Neuer FTP Connector mit Atomic Write
This commit is contained in:
parent
1897377eb3
commit
7b421e0a37
2 changed files with 31 additions and 18 deletions
|
|
@ -76,7 +76,7 @@ public class CargosoftExportAdapter implements SignalAdapter {
|
||||||
@Override
|
@Override
|
||||||
public ItemCollection execute(ItemCollection document, ItemCollection event) throws AdapterException {
|
public ItemCollection execute(ItemCollection document, ItemCollection event) throws AdapterException {
|
||||||
|
|
||||||
logger.info("......starting export...");
|
logger.info("├── 📤 Cargosoft export...");
|
||||||
try {
|
try {
|
||||||
|
|
||||||
// read the cargosoft export options
|
// read the cargosoft export options
|
||||||
|
|
@ -84,14 +84,14 @@ public class CargosoftExportAdapter implements SignalAdapter {
|
||||||
|
|
||||||
if (evalItemCollection == null) {
|
if (evalItemCollection == null) {
|
||||||
throw new PluginException(CargosoftExportAdapter.class.getSimpleName(), CONFIG_ERROR,
|
throw new PluginException(CargosoftExportAdapter.class.getSimpleName(), CONFIG_ERROR,
|
||||||
"missign cargosoft configuration in model event - please check model configuration");
|
"missing cargosoft configuration in model event - please check model configuration");
|
||||||
}
|
}
|
||||||
String reportID = evalItemCollection.getItemValueString("report");
|
String reportID = evalItemCollection.getItemValueString("report");
|
||||||
ItemCollection report = reportService.findReport(reportID);
|
ItemCollection report = reportService.findReport(reportID);
|
||||||
|
|
||||||
if (report == null) {
|
if (report == null) {
|
||||||
throw new PluginException(CargosoftExportAdapter.class.getSimpleName(), CONFIG_ERROR,
|
throw new PluginException(CargosoftExportAdapter.class.getSimpleName(), CONFIG_ERROR,
|
||||||
"missign cargosoft report '" + reportID + "' - please check model configuration");
|
"missing cargosoft report '" + reportID + "' - please check model configuration");
|
||||||
}
|
}
|
||||||
|
|
||||||
List<ItemCollection> sourceData = new ArrayList<ItemCollection>();
|
List<ItemCollection> sourceData = new ArrayList<ItemCollection>();
|
||||||
|
|
@ -106,7 +106,6 @@ public class CargosoftExportAdapter implements SignalAdapter {
|
||||||
|
|
||||||
// transfer file via FTP...
|
// transfer file via FTP...
|
||||||
if (ftpServer.isPresent()) {
|
if (ftpServer.isPresent()) {
|
||||||
logger.info("ftp transfer...");
|
|
||||||
ftpConnector.put(exportFile);
|
ftpConnector.put(exportFile);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -115,7 +114,7 @@ public class CargosoftExportAdapter implements SignalAdapter {
|
||||||
|
|
||||||
} catch (PluginException | IOException | jakarta.xml.bind.JAXBException
|
} catch (PluginException | IOException | jakarta.xml.bind.JAXBException
|
||||||
| javax.xml.transform.TransformerException e) {
|
| javax.xml.transform.TransformerException e) {
|
||||||
logger.severe("cargosoft export failed: " + e.getMessage());
|
logger.severe("├── ⚠️ Cargosoft export failed: " + e.getMessage());
|
||||||
document.setItemValue("cargosoft.error", e.getMessage());
|
document.setItemValue("cargosoft.error", e.getMessage());
|
||||||
document.event(EVENT_FAILURE);
|
document.event(EVENT_FAILURE);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -82,10 +82,12 @@ public class FTPConnector {
|
||||||
Optional<String> ftpPassword;
|
Optional<String> ftpPassword;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* This method transfers a snapshot to a ftp server.
|
* This method transfers a file to a FTP server using atomic upload.
|
||||||
|
* The file is first uploaded with a temporary name and then renamed
|
||||||
|
* to avoid race conditions with the receiver.
|
||||||
*
|
*
|
||||||
* @param fileData object
|
* @param fileData object containing the file to upload
|
||||||
* @throws PluginException
|
* @throws PluginException if the upload fails
|
||||||
*/
|
*/
|
||||||
public void put(FileData fileData) throws PluginException {
|
public void put(FileData fileData) throws PluginException {
|
||||||
|
|
||||||
|
|
@ -95,6 +97,8 @@ public class FTPConnector {
|
||||||
}
|
}
|
||||||
|
|
||||||
String fileName = fileData.getName();
|
String fileName = fileData.getName();
|
||||||
|
// Create temporary filename to avoid race conditions
|
||||||
|
String tempFileName = fileName + ".part";
|
||||||
|
|
||||||
// Compute file path
|
// Compute file path
|
||||||
String ftpWorkingPath = ftpPath.get();
|
String ftpWorkingPath = ftpPath.get();
|
||||||
|
|
@ -108,7 +112,8 @@ public class FTPConnector {
|
||||||
|
|
||||||
FTPClient ftpClient = null;
|
FTPClient ftpClient = null;
|
||||||
try {
|
try {
|
||||||
logger.finest("......put " + fileName + " to FTP server: " + ftpServer + "...");
|
logger.info("├── 🔜 uploading " + fileName + " to FTP server: " + ftpServer + " ...");
|
||||||
|
logger.info("│ ├── working directory=" + ftpWorkingPath);
|
||||||
ftpClient = new FTPSClient("TLS", false);
|
ftpClient = new FTPSClient("TLS", false);
|
||||||
ftpClient.setBufferSize(8192);
|
ftpClient.setBufferSize(8192);
|
||||||
ftpClient.connect(ftpServer.get(), ftpPort.get().intValue());
|
ftpClient.connect(ftpServer.get(), ftpPort.get().intValue());
|
||||||
|
|
@ -120,38 +125,47 @@ public class FTPConnector {
|
||||||
ftpClient.setFileType(FTP.ASCII_FILE_TYPE);
|
ftpClient.setFileType(FTP.ASCII_FILE_TYPE);
|
||||||
ftpClient.setControlEncoding("UTF-8");
|
ftpClient.setControlEncoding("UTF-8");
|
||||||
|
|
||||||
// verify directories
|
// Verify directories
|
||||||
if (!ftpClient.changeWorkingDirectory(ftpWorkingPath)) {
|
if (!ftpClient.changeWorkingDirectory(ftpWorkingPath)) {
|
||||||
throw new PluginException(CargosoftExportAdapter.class.getSimpleName(), FTP_ERROR,
|
throw new PluginException(CargosoftExportAdapter.class.getSimpleName(), FTP_ERROR,
|
||||||
"FTP file transfer failed: missing working directory '" + ftpWorkingPath + "' : "
|
"FTP file transfer failed: missing working directory '" + ftpWorkingPath + "' : "
|
||||||
+ ftpClient.getReplyString());
|
+ ftpClient.getReplyString());
|
||||||
}
|
}
|
||||||
|
|
||||||
// upload file to FTP server.
|
// Upload file to FTP server with temporary name
|
||||||
writer = new ByteArrayInputStream(fileData.getContent());
|
writer = new ByteArrayInputStream(fileData.getContent());
|
||||||
|
|
||||||
if (!ftpClient.storeFile(fileName, writer)) {
|
if (!ftpClient.storeFile(tempFileName, writer)) {
|
||||||
throw new PluginException(CargosoftExportAdapter.class.getSimpleName(), FTP_ERROR,
|
throw new PluginException(CargosoftExportAdapter.class.getSimpleName(), FTP_ERROR,
|
||||||
"FTP file transfer failed: unable to write '" + ftpWorkingPath + fileName + "' : "
|
"FTP file transfer failed: unable to write '" + ftpWorkingPath + tempFileName + "' : "
|
||||||
+ ftpClient.getReplyString());
|
+ ftpClient.getReplyString());
|
||||||
}
|
}
|
||||||
|
|
||||||
logger.finest("...." + ftpWorkingPath + fileName + " transfered successfull to " + ftpServer);
|
// Rename to final name - this is an atomic operation
|
||||||
|
logger.info("│ ├── rename '" + tempFileName + "' to '" + fileName + " ...");
|
||||||
|
if (!ftpClient.rename(tempFileName, fileName)) {
|
||||||
|
throw new PluginException(CargosoftExportAdapter.class.getSimpleName(), FTP_ERROR,
|
||||||
|
"FTP file transfer failed: unable to rename '" + tempFileName + "' to '" + fileName + "' : "
|
||||||
|
+ ftpClient.getReplyString());
|
||||||
|
}
|
||||||
|
|
||||||
|
logger.info("│ └── ✓ ftp transfer completed.");
|
||||||
} catch (IOException e) {
|
} catch (IOException e) {
|
||||||
throw new PluginException(CargosoftExportAdapter.class.getSimpleName(), FTP_ERROR,
|
throw new PluginException(CargosoftExportAdapter.class.getSimpleName(), FTP_ERROR,
|
||||||
"FTP file transfer failed: " + e.getMessage(), e);
|
"FTP file transfer failed: " + e.getMessage(), e);
|
||||||
} finally {
|
} finally {
|
||||||
// do logout....
|
// Cleanup
|
||||||
try {
|
try {
|
||||||
if (writer != null) {
|
if (writer != null) {
|
||||||
writer.close();
|
writer.close();
|
||||||
}
|
}
|
||||||
ftpClient.logout();
|
if (ftpClient != null && ftpClient.isConnected()) {
|
||||||
ftpClient.disconnect();
|
ftpClient.logout();
|
||||||
|
ftpClient.disconnect();
|
||||||
|
}
|
||||||
} catch (IOException e) {
|
} catch (IOException e) {
|
||||||
throw new PluginException(CargosoftExportAdapter.class.getSimpleName(), FTP_ERROR,
|
throw new PluginException(CargosoftExportAdapter.class.getSimpleName(), FTP_ERROR,
|
||||||
"FTP file transfer failed: " + e.getMessage(), e);
|
"FTP file transfer failed during cleanup: " + e.getMessage(), e);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue