| package com.scraper.agents.dataextract;
|
|
|
| import com.highradius.cpacommon.model.CPADataExtractConfig;
|
| import com.scraper.fs.cpa.FSClient;
|
| import org.slf4j.Logger;
|
| import org.slf4j.LoggerFactory;
|
|
|
| import java.util.List;
|
| import java.util.regex.Pattern;
|
|
|
| /**
|
| * Uses framework DataExtractTransporter to establish SFTP connection (via FSClient),
|
| * lists files in remote directory and validates name & size.
|
| * Retry logic is encapsulated here (configurable).
|
| */
|
| public class SftpValidationService {
|
|
|
| private static final Logger LOGGER = LoggerFactory.getLogger(SftpValidationService.class);
|
| private static final Pattern FILE_PATTERN =
|
| Pattern.compile("^Deductions-\\d{8}T\\d{6}Z-\\d+\\.zip$", Pattern.CASE_INSENSITIVE);
|
|
|
| private final DataExtractTransporter transporter; // existing framework transporter
|
| private final int retryCount;
|
| private final long retryDelayMs;
|
|
|
| public SftpValidationService(DataExtractTransporter transporter, int retryCount, long retryDelayMs) {
|
| this.transporter = transporter;
|
| this.retryCount = retryCount;
|
| this.retryDelayMs = retryDelayMs;
|
| }
|
|
|
| public SftpValidationSummary validate(CPADataExtractConfig config, String remotePath) {
|
| int attempt = 0;
|
| Exception lastEx = null;
|
| while (attempt < retryCount) {
|
| attempt++;
|
| try {
|
| LOGGER.info("SFTP validation attempt {}/{} for path: {}", attempt, retryCount, remotePath);
|
| return performValidation(config, remotePath);
|
| } catch (Exception e) {
|
| lastEx = e;
|
| LOGGER.error("Attempt {}/{} failed: {}", attempt, retryCount, e.getMessage(), e);
|
| sleepQuietly();
|
| }
|
| }
|
| SftpValidationSummary summary = new SftpValidationSummary();
|
| summary.setFailed(true);
|
| summary.setFailureReason("SFTP validation failed after " + retryCount + " attempts: " +
|
| (lastEx != null ? lastEx.getMessage() : "unknown"));
|
| return summary;
|
| }
|
|
|
| private SftpValidationSummary performValidation(CPADataExtractConfig config, String remotePath) throws Exception {
|
| SftpValidationSummary summary = new SftpValidationSummary();
|
|
|
| // DataExtractTransporter exposes connectToSFTP(...) in your framework (see your transporter).
|
| FSClient fsClient = transporter.connectToSFTP(config, true);
|
| if (fsClient == null) {
|
| throw new Exception("FSClient is null after connectToSFTP.");
|
| }
|
|
|
| List<String> files = fsClient.listNames(remotePath);
|
| if (files == null || files.isEmpty()) {
|
| summary.setFailed(true);
|
| summary.setFailureReason("No files found in remote path: " + remotePath);
|
| try { fsClient.closeConnection(); } catch (Exception ignored) {}
|
| return summary;
|
| }
|
|
|
| for (String f : files) {
|
| SftpValidationResult r = new SftpValidationResult(f);
|
| r.setValidName(FILE_PATTERN.matcher(f).matches());
|
| long sizeBytes = fsClient.getFileSize(remotePath + (remotePath.endsWith("/") ? "" : "/") + f);
|
| r.setFileSizeBytes(sizeBytes);
|
| r.setValidSize(sizeBytes > 0);
|
| r.setRemarks(
|
| !r.isValidName() && !r.isValidSize() ? "Invalid name & 0KB" :
|
| !r.isValidName() ? "Invalid name" :
|
| !r.isValidSize() ? "0KB file" : "Valid file"
|
| );
|
| summary.addResult(r);
|
| }
|
|
|
| fsClient.closeConnection();
|
| summary.computeMessage();
|
| return summary;
|
| }
|
|
|
| private void sleepQuietly() {
|
| try { Thread.sleep(retryDelayMs); } catch (InterruptedException ie) { Thread.currentThread().interrupt(); }
|
| }
|
| }
|