Skip to content

Commit

Permalink
Resend file cleanup error (#394)
Browse files Browse the repository at this point in the history
* Use string statics for the pending file storage identifiers.

* Add setter with storage for boolean indicating if message is in resend
mode.

* Fix formatting and reference pending file directory using string static
  • Loading branch information
uhurusurfa authored Oct 2, 2024
1 parent 35844db commit aa62228
Show file tree
Hide file tree
Showing 8 changed files with 68 additions and 39 deletions.
8 changes: 7 additions & 1 deletion Server/src/main/java/org/openas2/message/BaseMessage.java
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,7 @@ public abstract class BaseMessage implements Message {
private String compressionType = ICryptoHelper.COMPRESSION_NONE;
private boolean rxdMsgWasSigned = false;
private boolean rxdMsgWasEncrypted = false;
private boolean isResending = false;
private boolean fileCleanupCompleted = false;
private Map<String, Object> options = new HashMap<String, Object>();
private String calculatedMIC = null;
Expand Down Expand Up @@ -104,7 +105,12 @@ public void setStatus(String status) {

public boolean isResend() {
// Determines if message is currently in resend phase
return Message.MSG_STATUS_MSG_RESEND.equals(getStatus());
return isResending;
}

public void setIsResend(boolean resending) {
// Sets resend phase
this.isResending = resending;
}

public Map<String, String> getCustomOuterMimeHeaders() {
Expand Down
1 change: 1 addition & 0 deletions Server/src/main/java/org/openas2/message/Message.java
Original file line number Diff line number Diff line change
Expand Up @@ -167,6 +167,7 @@ public interface Message extends Serializable {

void setFileCleanupCompleted(boolean cleanupDone);

void setIsResend(boolean resending);
boolean isResend();

String getSubject();
Expand Down
3 changes: 3 additions & 0 deletions Server/src/main/java/org/openas2/processor/Processor.java
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,9 @@
public interface Processor extends Component {
String COMPID_PROCESSOR = "processor";

String PENDING_MDN_INFO_DIRECTORY_IDENTIFIER = "pendingmdninfo";
String PENDING_MDN_MSG_DIRECTORY_IDENTIFIER = "pendingmdn";

void handle(String action, Message msg, Map<String, Object> options) throws OpenAS2Exception;

List<ProcessorModule> getModules();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
import org.openas2.Session;
import org.openas2.message.Message;
import org.openas2.params.InvalidParameterException;
import org.openas2.processor.Processor;
import org.openas2.util.IOUtil;

import java.io.File;
Expand Down Expand Up @@ -63,9 +64,9 @@ public void init(Session session, Map<String, String> options) throws OpenAS2Exc
executorService = Executors.newFixedThreadPool(maxProcessingThreads);
}

String pendingInfoFolder = getSession().getProcessor().getParameters().get("pendingmdninfo");
String pendingInfoFolder = getSession().getProcessor().getParameters().get(Processor.PENDING_MDN_INFO_DIRECTORY_IDENTIFIER);
IOUtil.getDirectoryFile(pendingInfoFolder);
String pendingFolder = getSession().getProcessor().getParameters().get("pendingmdn");
String pendingFolder = getSession().getProcessor().getParameters().get(Processor.PENDING_MDN_MSG_DIRECTORY_IDENTIFIER);
IOUtil.getDirectoryFile(pendingFolder);


Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@
import org.openas2.params.ParameterParser;
import org.openas2.params.RandomParameters;
import org.openas2.partner.Partnership;
import org.openas2.processor.Processor;
import org.openas2.processor.resender.ResenderModule;
import org.openas2.processor.sender.SenderModule;
import org.openas2.util.AS2Util;
Expand Down Expand Up @@ -233,6 +234,9 @@ protected Message processDocument(File pendingFile, Message msg) throws OpenAS2E
getSession().getProcessor().handle(SenderModule.DO_SEND, msg, options);
// Cleanup files only if sending was successful and an MDN was already received
if (!msg.isResend() && !msg.isConfiguredForAsynchMDN()) {
if (logger.isDebugEnabled()) {
logger.debug("Calling AS2Util.cleanupFiles from processDocument method.");
}
AS2Util.cleanupFiles(msg, false);
}
} catch (Exception e) {
Expand Down Expand Up @@ -291,7 +295,7 @@ public void addMessageMetadata(Message msg, String filename) throws OpenAS2Excep
msg.setHeader("AS2-From", msg.getPartnership().getSenderID(Partnership.PID_AS2));
// Now build the filename since it is by default dependent on having sender and
// receiver ID
String pendingFile = AS2Util.buildPendingFileName(msg, getSession().getProcessor(), "pendingmdn");
String pendingFile = AS2Util.buildPendingFileName(msg, getSession().getProcessor(), Processor.PENDING_MDN_MSG_DIRECTORY_IDENTIFIER);
msg.setAttribute(FileAttribute.MA_PENDINGFILE, pendingFile);
CompositeParameters parser = new CompositeParameters(false).add("date", new DateParameters()).add("msg", new MessageParameters(msg)).add("rand", new RandomParameters());
msg.setAttribute(FileAttribute.MA_ERROR_DIR, ParameterParser.parse(getParameter(PARAM_ERROR_DIRECTORY, true), parser));
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -46,13 +46,13 @@ public class DirectoryResenderModule extends BaseResenderModule {
/** TODO: Remove this when module config enforces setting the action so that the super method does all the work
*
*/
public String getModuleAction() {
String action = super.getModuleAction();
if (action == null) {
return ResenderModule.DO_RESEND;
}
return action;
}
public String getModuleAction() {
String action = super.getModuleAction();
if (action == null) {
return ResenderModule.DO_RESEND;
}
return action;
}

public void handle(String action, Message msg, Map<String, Object> options) throws OpenAS2Exception {
ObjectOutputStream oos = null;
Expand All @@ -67,12 +67,21 @@ public void handle(String action, Message msg, Map<String, Object> options) thro
int retries = Integer.parseInt((String)options.get(ResenderModule.OPTION_RETRIES));
oos.writeObject(method);
oos.writeObject("" + retries);
// Set the resend flag to avoid unwanted processing of the message by the builder module
msg.setIsResend(true);
oos.writeObject(msg);

logger.info("Message put in resend queue" + msg.getLogMsgID());
if (logger.isTraceEnabled()) {
try {
logger.trace("Message object in resender module for storage. Content-Disposition: " + msg.getContentDisposition() + "\n Content-Type : " + msg.getContentType() + "\n Retries : " + retries + "\n HEADERS : " + AS2Util.printHeaders(msg.getData().getAllHeaders()) + "\n Content-Disposition in MSG getData() MIMEPART: " + msg.getData().getContentType() + "\n Attributes: " + msg.getAttributes() + msg.getLogMsgID());
logger.trace("Message object in resender module for storage. Content-Disposition: " +
msg.getContentDisposition() +
"\n Content-Type : " + msg.getContentType() +
"\n Retries : " + retries +
"\n HEADERS : " + AS2Util.printHeaders(msg.getData().getAllHeaders()) +
"\n Content-Disposition in MSG getData() MIMEPART: " + msg.getData().getContentType() +
"\n Attributes: " + msg.getAttributes() + msg.getLogMsgID()
);
} catch (Exception e) {
}
}
Expand Down Expand Up @@ -174,7 +183,7 @@ protected void processFile(File file) throws OpenAS2Exception {

// Transmit the message
if (logger.isInfoEnabled()) {
logger.info("loaded message for resend." + msg.getLogMsgID());
logger.info("Loaded message for resend: " + file.getAbsolutePath() + msg.getLogMsgID());
}
if (logger.isTraceEnabled()) {
try {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@
import org.openas2.params.MessageParameters;
import org.openas2.params.ParameterParser;
import org.openas2.partner.Partnership;
import org.openas2.processor.Processor;
import org.openas2.processor.msgtracking.BaseMsgTrackingModule.FIELDS;
import org.openas2.processor.resender.ResenderModule;
import org.openas2.schedule.HasSchedule;
Expand Down Expand Up @@ -538,7 +539,7 @@ protected void storePendingInfo(AS2Message msg, boolean isResend) throws Excepti
ObjectOutputStream oos = null;

try {
String pendingInfoFile = AS2Util.buildPendingFileName(msg, getSession().getProcessor(), "pendingmdninfo");
String pendingInfoFile = AS2Util.buildPendingFileName(msg, getSession().getProcessor(), Processor.PENDING_MDN_INFO_DIRECTORY_IDENTIFIER);
String pendingFile = msg.getAttribute(FileAttribute.MA_PENDINGFILE);
msg.setAttribute(FileAttribute.MA_PENDINGFILE, pendingFile);
msg.setAttribute(FileAttribute.MA_PENDINGINFO, pendingInfoFile);
Expand Down Expand Up @@ -617,7 +618,7 @@ protected void calcAndStoreMic(Message msg, MimeBodyPart mbp, boolean includeHea
protected void detectFailedSentMessages() {
String dir;
try {
dir = getSession().getProcessor().getParameters().get("pendingmdninfo");
dir = getSession().getProcessor().getParameters().get(Processor.PENDING_MDN_INFO_DIRECTORY_IDENTIFIER);
} catch (ComponentNotFoundException e) {
logger.warn("Failed to retrieve the name of the pending info folder for sent messages in trying to run the failed message detection method.", e);
return;
Expand Down
52 changes: 28 additions & 24 deletions Server/src/main/java/org/openas2/util/AS2Util.java
Original file line number Diff line number Diff line change
Expand Up @@ -22,10 +22,8 @@
import org.openas2.processor.sender.SenderModule;
import org.openas2.processor.storage.StorageModule;

import jakarta.mail.BodyPart;
import jakarta.mail.Header;
import jakarta.mail.MessagingException;
import jakarta.mail.Multipart;
import jakarta.mail.internet.ContentType;
import jakarta.mail.internet.InternetHeaders;
import jakarta.mail.internet.MimeBodyPart;
Expand Down Expand Up @@ -321,7 +319,7 @@ public static boolean resend(Session session, Class<?> sourceClass, String how,
int retries = Integer.parseInt((String)msg.getOption(ResenderModule.OPTION_RETRIES));
int maxRetryCount = getMaxResendCount(session, msg);
if (logger.isDebugEnabled()) {
logger.debug("RESEND requested. Retries: " + retries + "Max retries: " + maxRetryCount + "\n Message file from passed in object: " + msg.getAttribute(FileAttribute.MA_PENDINGFILE) + msg.getLogMsgID());
logger.debug("RESEND requested. Retries: " + retries + " Max retries: " + maxRetryCount + "\n Message file from passed in object: " + msg.getAttribute(FileAttribute.MA_PENDINGFILE) + msg.getLogMsgID());
}
if (maxRetryCount > -1) {
// Have to resend some fixed number of times so check if we are done
Expand All @@ -333,6 +331,9 @@ public static boolean resend(Session session, Class<?> sourceClass, String how,
msg.setOption("STATE", Message.MSG_STATE_SEND_FAIL);
msg.trackMsgState(session);
// Cleanup the files associated with this failed message
if (logger.isDebugEnabled()) {
logger.debug("Calling AS2Util.cleanupFiles from resend abort on max retries.");
}
AS2Util.cleanupFiles(msg, true);
// Signal sending retry has been abandoned
return false;
Expand Down Expand Up @@ -392,9 +393,10 @@ public static boolean resend(Session session, Class<?> sourceClass, String how,
if (requiresNewMessageId) {
/**
* Per https://tools.ietf.org/html/rfc4130#section-9.3 resend should have same
* Message-Id ... BUT Because it was implemented in the beginning to vreate a
* Message-Id ... BUT Because it was implemented in the beginning to create a
* new one for each resend, for backwards compatibility the default is the
* reverse Systems like Mendelson require a new Message-Id
* reverse.
* Systems like Mendelson require a new Message-Id
*/
// Resend requires a new Message-Id and we need to update the pendinginfo file
// name to match....
Expand All @@ -407,7 +409,7 @@ public static boolean resend(Session session, Class<?> sourceClass, String how,
// Set new Id in Message object so we can generate new file name
msg.setMessageID(newMsgId);
// msg.setHeader("Original-Message-Id", oldMsgId); // Not sure about this so leave out for now
String newPendingInfoFileName = buildPendingFileName(msg, session.getProcessor(), "pendingmdninfo");
String newPendingInfoFileName = buildPendingFileName(msg, session.getProcessor(), Processor.PENDING_MDN_INFO_DIRECTORY_IDENTIFIER);
if (logger.isDebugEnabled()) {
logger.debug("" + "\n Old Msg Id: " + oldMsgId + "\n Old Info File: " + oldPendingInfoFileName + "\n New Info File: " + newPendingInfoFileName + msg.getLogMsgID());
}
Expand Down Expand Up @@ -605,7 +607,7 @@ public static void getMetaData(AS2Message msg, Session session) throws OpenAS2Ex
String originalMsgId = msg.getMDN().getAttribute(AS2MessageMDN.MDNA_ORIG_MESSAGEID);

msg.setMessageID(originalMsgId);
String pendinginfofile = buildPendingFileName(msg, session.getProcessor(), "pendingmdninfo");
String pendinginfofile = buildPendingFileName(msg, session.getProcessor(), Processor.PENDING_MDN_INFO_DIRECTORY_IDENTIFIER);

if (logger.isDebugEnabled()) {
logger.debug("Pending info file to retrieve data from in MDN receiver: " + pendinginfofile);
Expand All @@ -620,7 +622,7 @@ public static void getMetaData(AS2Message msg, Session session) throws OpenAS2Ex
throw new OpenAS2Exception("Pending info file missing: " + pendinginfofile);
}
msg.setMessageID(oMsgIdStripped);
pendinginfofile = buildPendingFileName(msg, session.getProcessor(), "pendingmdninfo");
pendinginfofile = buildPendingFileName(msg, session.getProcessor(), Processor.PENDING_MDN_INFO_DIRECTORY_IDENTIFIER);
iFile = new File(pendinginfofile);
if (!iFile.exists()) {
throw new OpenAS2Exception("Pending info file missing: " + pendinginfofile);
Expand Down Expand Up @@ -685,9 +687,9 @@ public static void cleanupFiles(Message msg, boolean isError) {
}
return;
}
String pendingInfoFileName = msg.getAttribute(FileAttribute.MA_PENDINGINFO);
if (pendingInfoFileName != null) {
File fPendingInfoFile = new File(pendingInfoFileName);
String pendingMessageMetadata = msg.getAttribute(FileAttribute.MA_PENDINGINFO);
if (pendingMessageMetadata != null) {
File fPendingInfoFile = new File(pendingMessageMetadata);
if (fPendingInfoFile.exists()) {
if (logger.isTraceEnabled()) {
logger.trace("Deleting pendinginfo file : " + fPendingInfoFile.getAbsolutePath() + msg.getLogMsgID());
Expand All @@ -696,14 +698,14 @@ public static void cleanupFiles(Message msg, boolean isError) {
try {
IOUtil.deleteFile(fPendingInfoFile);
if (logger.isTraceEnabled()) {
logger.trace("deleted " + pendingInfoFileName + msg.getLogMsgID());
logger.trace("Pending MDN INFO file deleted: " + pendingMessageMetadata + msg.getLogMsgID());
}
} catch (Exception e) {
msg.setLogMsg("File was successfully sent but info file not deleted: " + pendingInfoFileName);
msg.setLogMsg("File was successfully sent but info file not deleted: " + pendingMessageMetadata);
logger.warn(msg, e);
}
} else {
msg.setLogMsg("Cleanup could not find pendinginfo file: " + pendingInfoFileName);
msg.setLogMsg("Cleanup could not find pendinginfo file: " + pendingMessageMetadata);
logger.warn(msg);
}
}
Expand All @@ -714,14 +716,14 @@ public static void cleanupFiles(Message msg, boolean isError) {
try {
IOUtil.deleteFile(new File(pendingFileName + ".object"));
if (logger.isTraceEnabled()) {
logger.trace("deleted " + pendingFileName + ".object" + msg.getLogMsgID());
logger.trace("The RETRY message object file deleted: " + pendingFileName + ".object" + msg.getLogMsgID());
}
} catch (Exception e) {
msg.setLogMsg("File was successfully sent but message object file not deleted: " + org.openas2.logging.Log.getExceptionMsg(e));
msg.setLogMsg("The RETRY message object file NOT deleted: " + org.openas2.logging.Log.getExceptionMsg(e));
logger.warn(msg, e);
}
if (logger.isTraceEnabled()) {
logger.trace("Cleaning up pending file : " + fPendingFile.getName() + " from pending folder : " + fPendingFile.getParent() + msg.getLogMsgID());
logger.trace("Cleaning up pending file : " + fPendingFile.getName() + " ::: From pending folder : " + fPendingFile.getParent() + msg.getLogMsgID());
}
try {
// Move file to error or sent directory if the error or sent saving functionality is enabled
Expand Down Expand Up @@ -750,8 +752,8 @@ public static void cleanupFiles(Message msg, boolean isError) {
tgtFile = IOUtil.moveFile(fPendingFile, tgtFile, false);
isMoved = true;

if (logger.isInfoEnabled()) {
logger.info("Pending file " + fPendingFile.getAbsolutePath() + " moved to " + tgtFile.getAbsolutePath() + msg.getLogMsgID());
if (logger.isDebugEnabled()) {
logger.debug("Pending MDN MSG FILE file " + fPendingFile.getAbsolutePath() + " moved to " + tgtFile.getAbsolutePath() + msg.getLogMsgID());
}

} catch (IOException iose) {
Expand All @@ -761,14 +763,16 @@ public static void cleanupFiles(Message msg, boolean isError) {
}

if (!isMoved) {
// Could not find somewhere to move it to so delete it
IOUtil.deleteFile(fPendingFile);
if (logger.isInfoEnabled()) {
logger.info("deleted " + fPendingFile.getAbsolutePath() + msg.getLogMsgID());
// Could not find somewhere to move it to so delete it if it still exists
if (fPendingFile.exists()) {
IOUtil.deleteFile(fPendingFile);
if (logger.isInfoEnabled()) {
logger.info("Pending MDN MSG FILE deleted: " + fPendingFile.getAbsolutePath() + msg.getLogMsgID());
}
}
}
} catch (Exception e) {
msg.setLogMsg("File was successfully sent but not deleted: " + fPendingFile.getAbsolutePath());
msg.setLogMsg("File cleanup unable to delete the locally stored version of the pending MSG file: " + fPendingFile.getAbsolutePath());
logger.error(msg, e);
}
}
Expand Down

0 comments on commit aa62228

Please sign in to comment.