About this task
Use the JavaCompute node to compress and decompress
message data using different formats, for example ZIP and GZIP.
Procedure
JavaCompute node functionality for Archive and
Unarchive activities:
- Compresses/decompresses the message content by using specified archive formats such as
ZIP or GZIP.
- Supports handling of multiple files in formats: ZIP or a single file in GZIP.
- Extracts the content and adds it to the message tree for further processing.
Supported archive formats:
- ZIP: Supports file names with directory structures.
- GZIP: Handles single files.
- TAR or TAR+GZIP: Requires third-party libraries like Apache Commons
Compress.
Input:
- fileName and fileContent - can be hardcoded or
dynamically retrieved from the environment, XML, or JSON.
Output:
- Archive - The compressed archive is Base64-encoded and added to the message tree before
propagation.
- Unarchive - The decompressed content is added to the message tree for propagation.
-
Implement the Archive logic by following this example:
Example: Archive in JavaCompute Node
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.util.Base64;
import java.util.zip.ZipEntry;
import java.util.zip.ZipOutputStream;
import java.util.zip.GZIPOutputStream;
import com.ibm.broker.javacompute.MbJavaComputeNode;
import com.ibm.broker.plugin.MbElement;
import com.ibm.broker.plugin.MbException;
import com.ibm.broker.plugin.MbMessage;
import com.ibm.broker.plugin.MbMessageAssembly;
import com.ibm.broker.plugin.MbOutputTerminal;
import com.ibm.broker.plugin.MbUserException;
public class Archive_JavaCompute extends MbJavaComputeNode {
public void evaluate(MbMessageAssembly inAssembly) throws MbException {
// Get the output terminal
MbOutputTerminal out = getOutputTerminal("out");
// Create the output message assembly by copying the input message
MbMessage inMessage = inAssembly.getMessage();
//If want to Retrieve from the Environment
//MbElement envRoot = inAssembly.getGlobalEnvironment().getRootElement();
//If want to Retrieve from the xml
//MbElement inRoot = inMessage.getRootElement();
//If want to Retrieve from the json
//MbElement jsonDataElement = inMessage.getRootElement().getFirstElementByPath("JSON/Data");
MbMessageAssembly outAssembly = new MbMessageAssembly(inAssembly, new MbMessage(inMessage));
// Inputs for the compression logic
String fileName = "folder/file.txt"; // File name (can include directory structure)
//If want to Retrieve from the Environment
// String fileName = envRoot.getFirstElementByPath("Variables/FileName").getValueAsString();
//If want to Retrieve from the xml
// String fileName = inRoot.getFirstElementByPath("XMLNSC/Root/FileName").getValueAsString();
//If want to Retrieve from the json
// byte[] fileContent = jsonDataElement.getFirstElementByPath("FileName").getValueAsString();
String archiveType = "zip"; // Archive type (e.g., zip, gzip)
byte[] fileContent = "abcdef".getBytes(); // File content as byte array
//If want to Retrieve from the Environment
// byte[] fileName = envRoot.getFirstElementByPath("Variables/Content").getValueAsString().getBytes();
//If want to Retrieve from the xml
// byte[] fileContent = inRoot.getFirstElementByPath("XMLNSC/Root/Content").getValueAsString().getBytes();
//If want to Retrieve from the json
// byte[] fileContent = jsonDataElement.getFirstElementByPath("content").getValueAsString();.getBytes();
byte[] archiveOutput;
try
// Archive based on the specified type
switch (archiveType.toLowerCase()) {
case "gzip":
archiveOutput = gzipArchive(fileContent);
break;
case "zip":
archiveOutput = zipArchive(fileName, fileContent);
break;
default:
throw new MbUserException(this.getClass().getName(), "evaluate", "Unsupported archive type", archiveType, "Supported types: gzip, zip", null);
}
} catch (IOException e) {
throw new MbUserException(this.getClass().getName(), "evaluate", "Archiving failed", e.getMessage(), "", null);
}
// Encode the compressed output as a Base64 string
String base64EncodedOutput = Base64.getEncoder().encodeToString(archiveOutput);
// Add the Base64-encoded archive output to the message tree
MbElement outRoot = outAssembly.getMessage().getRootElement();
MbElement outputStream = outRoot.createElementAsLastChild(MbElement.TYPE_NAME_VALUE, "OutputParameterStream", null);
outputStream.createElementAsLastChild(MbElement.TYPE_NAME_VALUE, "Archive", base64EncodedOutput);
// Propagate the message to the next node in the flo
out.propagate(outAssembly);
}
private byte[] gzipArchive(byte[] content) throws IOException {
ByteArrayOutputStream baos = new ByteArrayOutputStream();
try (GZIPOutputStream gos = new GZIPOutputStream(baos)) {
gos.write(content);
}
return baos.toByteArray();
}
private byte[] zipArchive(String fileName, byte[] content) throws IOException {
// Initialize a byte array output stream to hold the ZIP data
ByteArrayOutputStream baos = new ByteArrayOutputStream();
try (ZipOutputStream zos = new ZipOutputStream(baos)) {
// Check if the file name indicates a directory
boolean isDirectory = fileName.endsWith("/");
// Create a new ZIP entry with the provided file name
ZipEntry entry = new ZipEntry(fileName);
zos.putNextEntry(entry);
// Write content only if it's not a directory
if (!isDirectory) {
zos.write(contnt);
}
// Close the current ZIP entry
zos.closeEntry();
}
// Return the compressed data as a byte array
return baos.toByteArray();
}
}
- Implement the Unarchive logic by following this example:
Example Implementation: Unarchive in JavaCompute Node
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.util.Base64;
import java.util.zip.GZIPInputStream;
import java.util.zip.ZipEntry;
import java.util.zip.ZipInputStream;
import com.ibm.broker.javacompute.MbJavaComputeNode;
import com.ibm.broker.plugin.MbElement;
import com.ibm.broker.plugin.MbException;
import com.ibm.broker.plugin.MbMessage;
import com.ibm.broker.plugin.MbMessageAssembly;
import com.ibm.broker.plugin.MbOutputTerminal;
import com.ibm.broker.plugin.MbUserException;
public class Unarchive_JavaCompute extends MbJavaComputeNode {
public void evaluate(MbMessageAssembly inAssembly) throws MbException {
MbOutputTerminal out = getOutputTerminal("out");
MbMessage inMessage = inAssembly.getMessage();
MbMessageAssembly outAssembly = new MbMessageAssembly(inAssembly, new MbMessage(inMessage));
try {
// Retrieve the Base64-encoded archive content
MbElement inputRoot = inMessage.getRootElement();
String base64EncodedArchive = inputRoot.getFirstElementByPath("InputParameterStream/Archive").getValueAsString();
byte[] archiveContent = Base64.getDecoder().decode(base64EncodedArchive);
// Retrieve the archive type
String archiveType = inputRoot.getFirstElementByPath("InputParameterStream/ArchiveType").getValueAsString();
// Unarchive the content
String extractedContent = unarchiveContent(archiveContent, archiveType);
// Set the extracted content in the output message
MbElement outRoot = outAssembly.getMessage().getRootElement();
MbElement outputStream = outRoot.createElementAsLastChild(MbElement.TYPE_NAME_VALUE, "OutputParameterStream", null);
outputStream.createElementAsLastChild(MbElement.TYPE_NAME_VALUE, "UnarchivedContent", extractedContent);
out.propagate(outAssembly);
} catch (Exception e) {
throw new MbUserException(this.getClass().getName(), "evaluate", "Unarchiving failed", e.getMessage(), "", null);
}
}
private String unarchiveContent(byte[] archiveContent, String archiveType) throws IOException, MbUserException {
switch (archiveType.toLowerCase()) {
case "gzip":
return new String(unarchiveGZIP(archiveContent));
case "zip":
return unarchiveZIP(archiveContent);
default:
throw new MbUserException(this.getClass().getName(), "unarchiveContent", "Unsupported archive type", archiveType, "Supported types: gzip, zip", null);
}
}
private byte[] unarchiveGZIP(byte[] gzipContent) throws IOException {
ByteArrayInputStream bais = new ByteArrayInputStream(gzipContent);
try (GZIPInputStream gis = new GZIPInputStream(bais)) {
ByteArrayOutputStream baos = new ByteArrayOutputStream();
byte[] buffer = new byte[1024];
int len;
while ((len = gis.read(buffer)) > 0) {
baos.write(buffer, 0, len);
}
return baos.toByteArray();
}
}
private String unarchiveZIP(byte[] zipContent) throws IOException {
ByteArrayInputStream bais = new ByteArrayInputStream(zipContent);
StringBuilder extractedContent = new StringBuilder();
try (ZipInputStream zis = new ZipInputStream(bais)) {
ZipEntry entry;
while ((entry = zis.getNextEntry()) != null) {
if (!entry.isDirectory()) {
ByteArrayOutputStream baos = new ByteArrayOutputStream();
byte[] buffer = new byte[1024];
int len;
while ((len = zis.read(buffer)) > 0) {
baos.write(buffer, 0, len);
}
extractedContent.append("File: ").append(entry.getName()).append("\n");
extractedContent.append("Content: ").append(new String(baos.toByteArray())).append("\n");
}
}
}
return extractedContent.toString();
}
}