diff --git a/Server/src/main/java/org/openas2/message/BaseMessage.java b/Server/src/main/java/org/openas2/message/BaseMessage.java index 4948682b..e81c8db9 100644 --- a/Server/src/main/java/org/openas2/message/BaseMessage.java +++ b/Server/src/main/java/org/openas2/message/BaseMessage.java @@ -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 options = new HashMap(); private String calculatedMIC = null; @@ -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 getCustomOuterMimeHeaders() { diff --git a/Server/src/main/java/org/openas2/message/Message.java b/Server/src/main/java/org/openas2/message/Message.java index df820d20..c660303a 100644 --- a/Server/src/main/java/org/openas2/message/Message.java +++ b/Server/src/main/java/org/openas2/message/Message.java @@ -167,6 +167,7 @@ public interface Message extends Serializable { void setFileCleanupCompleted(boolean cleanupDone); + void setIsResend(boolean resending); boolean isResend(); String getSubject(); diff --git a/Server/src/main/java/org/openas2/processor/Processor.java b/Server/src/main/java/org/openas2/processor/Processor.java index 7fa0bbda..487c3240 100644 --- a/Server/src/main/java/org/openas2/processor/Processor.java +++ b/Server/src/main/java/org/openas2/processor/Processor.java @@ -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 options) throws OpenAS2Exception; List getModules(); diff --git a/Server/src/main/java/org/openas2/processor/receiver/DirectoryPollingModule.java b/Server/src/main/java/org/openas2/processor/receiver/DirectoryPollingModule.java index e7e6bbb3..98d632d0 100644 --- a/Server/src/main/java/org/openas2/processor/receiver/DirectoryPollingModule.java +++ b/Server/src/main/java/org/openas2/processor/receiver/DirectoryPollingModule.java @@ -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; @@ -63,9 +64,9 @@ public void init(Session session, Map 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); diff --git a/Server/src/main/java/org/openas2/processor/receiver/MessageBuilderModule.java b/Server/src/main/java/org/openas2/processor/receiver/MessageBuilderModule.java index 83d77a48..6611cb27 100644 --- a/Server/src/main/java/org/openas2/processor/receiver/MessageBuilderModule.java +++ b/Server/src/main/java/org/openas2/processor/receiver/MessageBuilderModule.java @@ -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; @@ -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) { @@ -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)); diff --git a/Server/src/main/java/org/openas2/processor/resender/DirectoryResenderModule.java b/Server/src/main/java/org/openas2/processor/resender/DirectoryResenderModule.java index f73f5125..ed24bd18 100644 --- a/Server/src/main/java/org/openas2/processor/resender/DirectoryResenderModule.java +++ b/Server/src/main/java/org/openas2/processor/resender/DirectoryResenderModule.java @@ -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 options) throws OpenAS2Exception { ObjectOutputStream oos = null; @@ -67,12 +67,21 @@ public void handle(String action, Message msg, Map 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) { } } @@ -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 { diff --git a/Server/src/main/java/org/openas2/processor/sender/AS2SenderModule.java b/Server/src/main/java/org/openas2/processor/sender/AS2SenderModule.java index 9512f121..8b7d87be 100644 --- a/Server/src/main/java/org/openas2/processor/sender/AS2SenderModule.java +++ b/Server/src/main/java/org/openas2/processor/sender/AS2SenderModule.java @@ -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; @@ -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); @@ -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; diff --git a/Server/src/main/java/org/openas2/util/AS2Util.java b/Server/src/main/java/org/openas2/util/AS2Util.java index 18252818..cf6cf05c 100644 --- a/Server/src/main/java/org/openas2/util/AS2Util.java +++ b/Server/src/main/java/org/openas2/util/AS2Util.java @@ -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; @@ -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 @@ -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; @@ -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.... @@ -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()); } @@ -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); @@ -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); @@ -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()); @@ -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); } } @@ -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 @@ -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) { @@ -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); } }