Skip to content

Commit

Permalink
impl completed
Browse files Browse the repository at this point in the history
Issue #177
  • Loading branch information
rsoika committed Jun 11, 2023
1 parent 3892eac commit 16d71d3
Show file tree
Hide file tree
Showing 7 changed files with 186 additions and 87 deletions.
7 changes: 4 additions & 3 deletions docker-compose-test.yml
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ services:
ports:
- "8080:8080"
- "8787:8787"
- "9990:9990"
- "9990:9990"

##################
# Exporter Service
Expand All @@ -53,9 +53,10 @@ services:
#EXPORT_FTP_PORT: "21"
#EXPORT_FTP_USER: ""
#EXPORT_FTP_PASSWORD: ""
EXPORT_PATH: "/opt/jboss/wildfly/test-export"
ports:
- "8081:8080"
- "8788:8787"
- "8788:8787"
- "9991:9990"
volumes:
- ./imixs-archive-exporter/docker/deployments:/opt/jboss/wildfly/standalone/deployments/
Expand Down Expand Up @@ -85,7 +86,7 @@ services:
HEALTH_ENDPOINT: "http://localhost:9992/health"
ports:
- "8082:8080"
- "8789:8787"
- "8789:8787"
- "9992:9990"
volumes:
- ./imixs-archive-backup/docker/deployments:/opt/jboss/wildfly/standalone/deployments/
Expand Down
7 changes: 5 additions & 2 deletions imixs-archive-exporter/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -13,15 +13,18 @@ The Exporter Service can be run in a container environment. To connect the expor
WORKFLOW_SERVICE_PASSWORD: [PASSWORD]
WORKFLOW_SERVICE_AUTHMETHOD: [AUTHMETHOD]

EXPORT_PATH: [DIRECTORY]
EXPORT_FTP_HOST: [FTP-SERVER-ADDRESS]
EXPORT_FTP_PATH: [DIRECTORY]
EXPORT_FTP_PORT: "21"
EXPORT_FTP_USER: [USER]
EXPORT_FTP_PASSWORD: [PASSWORD]

EVENTLOG_TOPIC : "file.export" (default topic)
EVENTLOG_DEADLOCK: 10000 (default timeout)

**Note:** The EXPORT-USER must have manager access.

The following envrionent variables are optional and depend on the Jakarta EE Runtime:
The following environment variables are optional and depend on the Jakarta EE Runtime:

- METRICS_ENDPOINT = endpoint for metrics API (default = http://localhost:9990/metrics)
- HEALTH_ENDPOINT = endpoint for health API (default = http://localhost:9990/health)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,8 +17,8 @@ public class ExportApi extends Application {
public static final String WORKFLOW_SYNC_INITIALDELAY = "workflow.sync.initialdelay";
public static final String WORKFLOW_SYNC_DEADLOCK = "workflow.sync.deadlock";

public static final String EVENTLOG_TOPIC = "file.export";
public static final String EVENTLOG_DEADLOCK = "export.sync.deadlock";
public static final String EVENTLOG_TOPIC = "eventlog.topic";
public static final String EVENTLOG_DEADLOCK = "eventlog.deadlock";

public static final String EXPORT_PATH = "export.path";

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -162,7 +162,7 @@ public long getCounterByName(String name) {
return entry.getValue().getCount();
}
}
logger.warning("Metric Counter : " + name + " not found!");
logger.fine("Metric Counter : " + name + " not found!");
return 0;
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -96,16 +96,27 @@ public class FileService {
*
* @param fileData - the File Data object
* @param path - optional sub directory
* @throws ExportException
*/
public void writeFileData(FileData fileData, String path) {
public void writeFileData(FileData fileData, String path) throws ExportException {

String workingPath = "";
if (fileData == null) {
throw new ExportException("EXPORT_EXCEPTION", "FileData object is null!");
}
if (path == null) {
path = "";
}
workingPath = fileData.getName();
// verify checksum if file exists
try {

String newChecksum = fileData.generateMD5();
FileData oldFile = readFileData(fileData.getName(), path);
if (oldFile != null && oldFile.generateMD5().equals(newChecksum)) {
// content hast not changed.
// no operation needed.
logger.info("file content unchanged: " + workingPath);
return;
}

Expand All @@ -116,15 +127,16 @@ public void writeFileData(FileData fileData, String path) {

} else {
// write file to local file storage
String ftpWorkingPath = computeWorkingDirectory(path);
ftpWorkingPath = ftpWorkingPath + fileData.getName();
logger.info("---> write file to: " + ftpWorkingPath);
Path nioPath = Paths.get(ftpWorkingPath);
Files.write(nioPath, fileData.getContent());
workingPath = computeWorkingDirectory(path);
// create sub directories if not exits
Files.createDirectories(Paths.get(workingPath));
workingPath = workingPath + fileData.getName();
logger.info("write file content: " + workingPath);
Files.write(Paths.get(workingPath), fileData.getContent());
}

} catch (NoSuchAlgorithmException | ExportException | IOException e) {
e.printStackTrace();
} catch (NoSuchAlgorithmException | IOException e) {
throw new ExportException("EXPORT_EXCEPTION", "Unable to write file: " + workingPath, e);
}

}
Expand All @@ -133,12 +145,35 @@ public void writeFileData(FileData fileData, String path) {
* Reads a fileData from a given export path (optional on a FTP Server)..
*
* @param path
* @throws ExportException
*/
public FileData readFileData(String fileName, String path) {

return null;
public FileData readFileData(String fileName, String path) throws ExportException {

FileData fileData = null;
// do we have a ftp server?
if (ftpServer.isPresent()) {
// FTPSClient ftpClient = getFTPClient();
fileData = ftpGet(fileName, path);

} else {
// write file to local file storage
String workingPath = computeWorkingDirectory(path);
workingPath = workingPath + fileName;
logger.fine("...read file from: " + workingPath);
Path nioPath = Paths.get(workingPath);

try {
if (Files.exists(nioPath)) {
byte[] data = Files.readAllBytes(nioPath);
fileData = new FileData(fileName, data, null, null);
}

} catch (IOException e) {
throw new ExportException("EXPORT_EXCEPTION", "Unable to read file: " + workingPath, e);
}
}

return fileData;

}

Expand Down Expand Up @@ -178,17 +213,44 @@ private void changeWorkingDirectory(FTPClient ftpClient, String subDirectory) th
try {
if (!ftpClient.changeWorkingDirectory(subDirectory)) {
// try to create it....
if (!ftpClient.makeDirectory(subDirectory)) {
throw new ExportException(FTP_ERROR, "FTP Error: unable to create sub-directory '" + subDirectory
+ "' : " + ftpClient.getReplyString());
}
makeDirectoryPath(ftpClient, subDirectory);
ftpClient.changeWorkingDirectory(subDirectory);
}
} catch (IOException e) {
throw new ExportException(FTP_ERROR, "FTP file transfer failed: " + e.getMessage(), e);
}
}

/**
* Helper method to create a sub directory path
*
* @param ftpClient
* @param dirPath
* @return
* @throws IOException
* @throws ExportException
*/
private static void makeDirectoryPath(FTPClient ftpClient, String dirPath) throws IOException, ExportException {
String[] pathElements = dirPath.split("/");
if (pathElements != null && pathElements.length > 0) {
for (String singleDir : pathElements) {
if (singleDir.isEmpty()) {
continue;
}
boolean existed = ftpClient.changeWorkingDirectory(singleDir);
if (!existed) {
boolean created = ftpClient.makeDirectory(singleDir);
if (created) {
ftpClient.changeWorkingDirectory(singleDir);
} else {
throw new ExportException(FTP_ERROR,
"FTP file transfer failed - COULD NOT create directory: " + singleDir);
}
}
}
}
}

/**
* This method transfers a single byte to a ftp server.
*
Expand All @@ -205,19 +267,16 @@ private void ftpPut(FileData fileData, String path) throws ExportException {
InputStream writer = null;
FTPClient ftpClient = null;
try {
logger.finest("......put " + fileData.getName() + " to FTP server: " + ftpServer + "...");
logger.info("put file content: " + fileData.getName() + " on FTP server...");
ftpClient = getFTPClient();

// verify directories
changeWorkingDirectory(ftpClient, ftpWorkingPath);
// upload file to FTP server.
writer = new ByteArrayInputStream(fileData.getContent());

if (!ftpClient.storeFile(fileData.getName(), writer)) {
throw new ExportException(FTP_ERROR, "FTP file transfer failed: unable to write '" + ftpWorkingPath
+ fileData.getName() + "' : " + ftpClient.getReplyString());
}

logger.finest("...." + ftpWorkingPath + fileData.getName() + " transferred successful to " + ftpServer);

} catch (IOException e) {
Expand All @@ -238,40 +297,30 @@ private void ftpPut(FileData fileData, String path) throws ExportException {
}
}

/**
* Helper method computes the full target file path
*/
private String computeWorkingDirectory(String path) {
// Compute file path
String ftpWorkingPath = filePath.orElse("");
if (!ftpWorkingPath.startsWith("/")) {
ftpWorkingPath = "/" + ftpWorkingPath;
}
if (path != null && !path.isEmpty()) {
if (path.startsWith("/")) {
path = path.substring(1);
}
ftpWorkingPath = ftpWorkingPath + path;
}
if (!ftpWorkingPath.endsWith("/")) {
ftpWorkingPath = ftpWorkingPath + "/";
}
return ftpWorkingPath;
}

/**
* This method reads a snapshot form the current working directory
*
* @param snapshot
* @throws ExportException
* @return snapshot
*/
private FileData ftpGet(FTPClient ftpClient, String fileName) throws ExportException {
private FileData ftpGet(String fileName, String path) throws ExportException {

long l = System.currentTimeMillis();
ByteArrayOutputStream bos = null;

if (!ftpServer.isPresent() || !filePath.isPresent()) {
throw new ExportException(FTP_ERROR,
"FTP file transfer failed: no ftp host provided (" + ExportApi.EXPORT_FTP_HOST + ")!");
}

String ftpWorkingPath = computeWorkingDirectory(path);

ByteArrayOutputStream bos = null;
FTPClient ftpClient = null;
try {
ftpClient = getFTPClient();
changeWorkingDirectory(ftpClient, ftpWorkingPath);

logger.finest("......get " + fileName + "...");
bos = new ByteArrayOutputStream();
ftpClient.retrieveFile(fileName, bos);
Expand All @@ -287,4 +336,24 @@ private FileData ftpGet(FTPClient ftpClient, String fileName) throws ExportExcep
}
}

/**
* Helper method computes the full target file path
*/
private String computeWorkingDirectory(String path) {
// Compute file path
String ftpWorkingPath = filePath.orElse("");
if (!ftpWorkingPath.startsWith("/")) {
ftpWorkingPath = "/" + ftpWorkingPath;
}
if (path != null && !path.isEmpty()) {
if (!path.startsWith("/")) {
path = "/" + path;
}
ftpWorkingPath = ftpWorkingPath + path;
}
if (!ftpWorkingPath.endsWith("/")) {
ftpWorkingPath = ftpWorkingPath + "/";
}
return ftpWorkingPath;
}
}
Loading

0 comments on commit 16d71d3

Please sign in to comment.