Search in sources :

Example 1 with MPC

use of com.helger.phase4.model.mpc.MPC in project phase4 by phax.

the class AS4RequestHandler method _invokeSPIsForIncoming.

/**
 * Invoke custom SPI message processors
 *
 * @param aHttpHeaders
 *        The received HTTP headers. Never <code>null</code>.
 * @param aEbmsUserMessage
 *        Current user message. Either this OR signal message must be
 *        non-<code>null</code>.
 * @param aEbmsSignalMessage
 *        The signal message to use. Either this OR user message must be
 *        non-<code>null</code>.
 * @param aPayloadNode
 *        Optional SOAP body payload (only if direct SOAP msg, not for MIME).
 *        May be <code>null</code>.
 * @param aDecryptedAttachments
 *        Original attachments from source message. May be <code>null</code>.
 * @param aPMode
 *        PMode to be used - may be <code>null</code> for Receipt messages.
 * @param aState
 *        The current state. Never <code>null</<code></code>.
 * @param aErrorMessagesTarget
 *        The list of error messages to be filled if something goes wrong.
 *        Never <code>null</code>.
 * @param aResponseAttachmentsTarget
 *        The list of attachments to be added to the response. Never
 *        <code>null</code>.
 * @param aSPIResult
 *        The result object to be filled. May not be <code>null</code>.
 */
private void _invokeSPIsForIncoming(@Nonnull final HttpHeaderMap aHttpHeaders, @Nullable final Ebms3UserMessage aEbmsUserMessage, @Nullable final Ebms3SignalMessage aEbmsSignalMessage, @Nullable final Node aPayloadNode, @Nullable final ICommonsList<WSS4JAttachment> aDecryptedAttachments, @Nullable final IPMode aPMode, @Nonnull final IAS4MessageState aState, @Nonnull final ICommonsList<Ebms3Error> aErrorMessagesTarget, @Nonnull final ICommonsList<WSS4JAttachment> aResponseAttachmentsTarget, @Nonnull final SPIInvocationResult aSPIResult) {
    ValueEnforcer.isTrue(aEbmsUserMessage != null || aEbmsSignalMessage != null, "User OR Signal Message must be present");
    ValueEnforcer.isFalse(aEbmsUserMessage != null && aEbmsSignalMessage != null, "Only one of User OR Signal Message may be present");
    final boolean bIsUserMessage = aEbmsUserMessage != null;
    final String sMessageID = bIsUserMessage ? aEbmsUserMessage.getMessageInfo().getMessageId() : aEbmsSignalMessage.getMessageInfo().getMessageId();
    // Get all processors
    final ICommonsList<IAS4ServletMessageProcessorSPI> aAllProcessors = m_aProcessorSupplier.get();
    if (LOGGER.isDebugEnabled())
        LOGGER.debug("Trying to invoke the following " + aAllProcessors.size() + " SPIs on message ID '" + sMessageID + "': " + aAllProcessors);
    if (aAllProcessors.isEmpty())
        LOGGER.error("No IAS4ServletMessageProcessorSPI is available to process an incoming message");
    // Invoke ALL non-null SPIs
    for (final IAS4ServletMessageProcessorSPI aProcessor : aAllProcessors) if (aProcessor != null)
        try {
            if (LOGGER.isDebugEnabled())
                LOGGER.debug("Invoking AS4 message processor " + aProcessor + " for incoming message");
            // Main processing
            final AS4MessageProcessorResult aResult;
            final ICommonsList<Ebms3Error> aProcessingErrorMessages = new CommonsArrayList<>();
            if (bIsUserMessage) {
                aResult = aProcessor.processAS4UserMessage(m_aMessageMetadata, aHttpHeaders, aEbmsUserMessage, aPMode, aPayloadNode, aDecryptedAttachments, aState, aProcessingErrorMessages);
            } else {
                aResult = aProcessor.processAS4SignalMessage(m_aMessageMetadata, aHttpHeaders, aEbmsSignalMessage, aPMode, aState, aProcessingErrorMessages);
            }
            // Result returned?
            if (aResult == null)
                throw new IllegalStateException("No result object present from AS4 message processor " + aProcessor + " - this is a programming error");
            if (aProcessingErrorMessages.isNotEmpty() || aResult.isFailure()) {
                if (aProcessingErrorMessages.isNotEmpty()) {
                    if (LOGGER.isDebugEnabled())
                        LOGGER.debug("AS4 message processor " + aProcessor + " had processing errors - breaking. Details: " + aProcessingErrorMessages);
                    if (aResult.isSuccess())
                        LOGGER.warn("Processing errors are present but success was returned by a previous AS4 message processor " + aProcessor + " - considering the whole processing to be failed instead");
                    aErrorMessagesTarget.addAll(aProcessingErrorMessages);
                }
                if (aResult.isFailure() && aResult.hasErrorMessage()) {
                    aErrorMessagesTarget.add(EEbmsError.EBMS_OTHER.getAsEbms3Error(m_aLocale, sMessageID, "Invoked AS4 message processor SPI " + aProcessor + " on '" + sMessageID + "' returned a failure: " + aResult.getErrorMessage()));
                }
                // Stop processing
                return;
            }
            // SPI invocation returned success and no errors
            {
                final String sAsyncResultURL = aResult.getAsyncResponseURL();
                if (StringHelper.hasText(sAsyncResultURL)) {
                    // URL present
                    if (aSPIResult.hasAsyncResponseURL()) {
                        // A second processor returned a response URL - not allowed
                        final String sErrorMsg = "Invoked AS4 message processor SPI " + aProcessor + " on '" + sMessageID + "' failed: the previous processor already returned an async response URL; it is not possible to handle two URLs. Please check your SPI implementations.";
                        LOGGER.error(sErrorMsg);
                        aErrorMessagesTarget.add(EEbmsError.EBMS_VALUE_INCONSISTENT.getAsEbms3Error(m_aLocale, sMessageID, sErrorMsg));
                        // Stop processing
                        return;
                    }
                    aSPIResult.setAsyncResponseURL(sAsyncResultURL);
                    LOGGER.info("Using asynchronous response URL '" + sAsyncResultURL + "' for message ID '" + sMessageID + "'");
                }
            }
            if (bIsUserMessage) {
            // User message specific processing result handling
            // empty
            } else {
                // Signal message specific processing result handling
                assert aResult instanceof AS4SignalMessageProcessorResult;
                if (aEbmsSignalMessage.getReceipt() == null) {
                    final Ebms3UserMessage aPullReturnUserMsg = ((AS4SignalMessageProcessorResult) aResult).getPullReturnUserMessage();
                    if (aSPIResult.hasPullReturnUserMsg()) {
                        // to the pullrequest initiator
                        if (aPullReturnUserMsg != null) {
                            final String sErrorMsg = "Invoked AS4 message processor SPI " + aProcessor + " on '" + sMessageID + "' failed: the previous processor already returned a usermessage; it is not possible to return two usermessage. Please check your SPI implementations.";
                            LOGGER.warn(sErrorMsg);
                            aErrorMessagesTarget.add(EEbmsError.EBMS_VALUE_INCONSISTENT.getAsEbms3Error(m_aLocale, sMessageID, sErrorMsg));
                            // Stop processing
                            return;
                        }
                    } else {
                        // Initial return user msg
                        if (aPullReturnUserMsg == null) {
                            // No message contained in the MPC
                            final String sErrorMsg = "Invoked AS4 message processor SPI " + aProcessor + " on '" + sMessageID + "' returned a failure: no UserMessage contained in the MPC";
                            LOGGER.warn(sErrorMsg);
                            aErrorMessagesTarget.add(EEbmsError.EBMS_EMPTY_MESSAGE_PARTITION_CHANNEL.getAsEbms3Error(m_aLocale, sMessageID, sErrorMsg));
                            // Stop processing
                            return;
                        }
                        // We have something :)
                        aSPIResult.setPullReturnUserMsg(aPullReturnUserMsg);
                    }
                } else {
                    if (LOGGER.isDebugEnabled())
                        LOGGER.debug("The AS4 EbmsSignalMessage already has a Receipt");
                }
            }
            // Add response attachments, payloads
            aResult.addAllAttachmentsTo(aResponseAttachmentsTarget);
            if (LOGGER.isDebugEnabled())
                LOGGER.debug("Successfully invoked AS4 message processor " + aProcessor);
        } catch (final AS4DecompressException ex) {
            LOGGER.error("Failed to decompress AS4 payload", ex);
            // Hack for invalid GZip content from WSS4JAttachment.getSourceStream
            aErrorMessagesTarget.add(EEbmsError.EBMS_DECOMPRESSION_FAILURE.getAsEbms3Error(m_aLocale, sMessageID));
            return;
        } catch (final RuntimeException ex) {
            // Re-throw
            throw ex;
        } catch (final Exception ex) {
            throw new IllegalStateException("Error processing incoming AS4 message with processor " + aProcessor, ex);
        }
    // Remember success
    aSPIResult.setSuccess(true);
}
Also used : AS4DecompressException(com.helger.phase4.attachment.AS4DecompressException) IAS4ServletMessageProcessorSPI(com.helger.phase4.servlet.spi.IAS4ServletMessageProcessorSPI) Ebms3Error(com.helger.phase4.ebms3header.Ebms3Error) AS4DecompressException(com.helger.phase4.attachment.AS4DecompressException) MessagingException(javax.mail.MessagingException) WSSecurityException(org.apache.wss4j.common.ext.WSSecurityException) Phase4Exception(com.helger.phase4.util.Phase4Exception) IOException(java.io.IOException) AS4MessageProcessorResult(com.helger.phase4.servlet.spi.AS4MessageProcessorResult) Ebms3UserMessage(com.helger.phase4.ebms3header.Ebms3UserMessage) AS4SignalMessageProcessorResult(com.helger.phase4.servlet.spi.AS4SignalMessageProcessorResult) CommonsArrayList(com.helger.commons.collection.impl.CommonsArrayList)

Example 2 with MPC

use of com.helger.phase4.model.mpc.MPC in project phase4 by phax.

the class AS4BidirectionalClientHelper method sendAS4PullRequestAndReceiveAS4UserMessage.

public static void sendAS4PullRequestAndReceiveAS4UserMessage(@Nonnull final IAS4CryptoFactory aCryptoFactory, @Nonnull final IPModeResolver aPModeResolver, @Nonnull final IAS4IncomingAttachmentFactory aIAF, @Nonnull final IAS4IncomingProfileSelector aIncomingProfileSelector, @Nonnull final AS4ClientPullRequestMessage aClientPullRequest, @Nonnull final Locale aLocale, @Nonnull final String sURL, @Nullable final IAS4ClientBuildMessageCallback aBuildMessageCallback, @Nullable final IAS4OutgoingDumper aOutgoingDumper, @Nullable final IAS4IncomingDumper aIncomingDumper, @Nullable final IAS4RetryCallback aRetryCallback, @Nullable final IAS4RawResponseConsumer aResponseConsumer, @Nullable final IAS4UserMessageConsumer aUserMsgConsumer) throws IOException, Phase4Exception, WSSecurityException, MessagingException {
    if (LOGGER.isInfoEnabled())
        LOGGER.info("Sending AS4 PullRequest to '" + sURL + "' with max. " + aClientPullRequest.httpRetrySettings().getMaxRetries() + " retries");
    if (LOGGER.isDebugEnabled())
        LOGGER.debug("  MPC = '" + aClientPullRequest.getMPC() + "'");
    final Wrapper<HttpResponse> aWrappedResponse = new Wrapper<>();
    final ResponseHandler<byte[]> aResponseHdl = aHttpResponse -> {
        // May throw an ExtendedHttpResponseException
        final HttpEntity aEntity = ResponseHandlerHttpEntity.INSTANCE.handleResponse(aHttpResponse);
        if (aEntity == null)
            return null;
        aWrappedResponse.set(aHttpResponse);
        return EntityUtils.toByteArray(aEntity);
    };
    final AS4ClientSentMessage<byte[]> aResponseEntity = aClientPullRequest.sendMessageWithRetries(sURL, aResponseHdl, aBuildMessageCallback, aOutgoingDumper, aRetryCallback);
    if (LOGGER.isInfoEnabled())
        LOGGER.info("Successfully transmitted AS4 PullRequest with message ID '" + aResponseEntity.getMessageID() + "' to '" + sURL + "'");
    if (aResponseConsumer != null)
        aResponseConsumer.handleResponse(aResponseEntity);
    // Try interpret result as SignalMessage
    if (aResponseEntity.hasResponse() && aResponseEntity.getResponse().length > 0) {
        final IAS4IncomingMessageMetadata aMessageMetadata = new AS4IncomingMessageMetadata(EAS4MessageMode.RESPONSE).setRemoteAddr(sURL);
        // Read response as EBMS3 User Message
        // Read it in any case to ensure signature validation etc. happens
        final Ebms3UserMessage aUserMessage = AS4IncomingHandler.parseUserMessage(aCryptoFactory, aPModeResolver, aIAF, aIncomingProfileSelector, aClientPullRequest.getAS4ResourceHelper(), null, aLocale, aMessageMetadata, aWrappedResponse.get(), aResponseEntity.getResponse(), aIncomingDumper);
        if (aUserMessage != null && aUserMsgConsumer != null)
            aUserMsgConsumer.handleUserMessage(aUserMessage);
    } else
        LOGGER.info("AS4 ResponseEntity is empty");
}
Also used : Ebms3SignalMessage(com.helger.phase4.ebms3header.Ebms3SignalMessage) IAS4SignalMessageConsumer(com.helger.phase4.client.IAS4SignalMessageConsumer) IAS4RawResponseConsumer(com.helger.phase4.client.IAS4RawResponseConsumer) LoggerFactory(org.slf4j.LoggerFactory) MessagingException(javax.mail.MessagingException) IAS4CryptoFactory(com.helger.phase4.crypto.IAS4CryptoFactory) ResponseHandlerHttpEntity(com.helger.httpclient.response.ResponseHandlerHttpEntity) EntityUtils(org.apache.http.util.EntityUtils) IAS4IncomingProfileSelector(com.helger.phase4.servlet.IAS4IncomingProfileSelector) EAS4MessageMode(com.helger.phase4.messaging.EAS4MessageMode) WSSecurityException(org.apache.wss4j.common.ext.WSSecurityException) Locale(java.util.Locale) IAS4IncomingDumper(com.helger.phase4.dump.IAS4IncomingDumper) IAS4IncomingMessageMetadata(com.helger.phase4.messaging.IAS4IncomingMessageMetadata) IAS4RetryCallback(com.helger.phase4.client.IAS4RetryCallback) Nonnull(javax.annotation.Nonnull) IAS4IncomingAttachmentFactory(com.helger.phase4.attachment.IAS4IncomingAttachmentFactory) Phase4Exception(com.helger.phase4.util.Phase4Exception) Nullable(javax.annotation.Nullable) IAS4OutgoingDumper(com.helger.phase4.dump.IAS4OutgoingDumper) Ebms3Property(com.helger.phase4.ebms3header.Ebms3Property) AS4ClientPullRequestMessage(com.helger.phase4.client.AS4ClientPullRequestMessage) Ebms3UserMessage(com.helger.phase4.ebms3header.Ebms3UserMessage) Logger(org.slf4j.Logger) AS4IncomingMessageMetadata(com.helger.phase4.servlet.AS4IncomingMessageMetadata) IPModeResolver(com.helger.phase4.model.pmode.resolve.IPModeResolver) AS4ClientSentMessage(com.helger.phase4.client.AS4ClientSentMessage) HttpEntity(org.apache.http.HttpEntity) IOException(java.io.IOException) WSS4JAttachment(com.helger.phase4.attachment.WSS4JAttachment) IAS4ClientBuildMessageCallback(com.helger.phase4.client.IAS4ClientBuildMessageCallback) AS4IncomingHandler(com.helger.phase4.servlet.AS4IncomingHandler) Wrapper(com.helger.commons.wrapper.Wrapper) AS4ClientUserMessage(com.helger.phase4.client.AS4ClientUserMessage) HttpResponse(org.apache.http.HttpResponse) IAS4UserMessageConsumer(com.helger.phase4.client.IAS4UserMessageConsumer) ResponseHandler(org.apache.http.client.ResponseHandler) IAS4IncomingMessageMetadata(com.helger.phase4.messaging.IAS4IncomingMessageMetadata) Wrapper(com.helger.commons.wrapper.Wrapper) ResponseHandlerHttpEntity(com.helger.httpclient.response.ResponseHandlerHttpEntity) HttpEntity(org.apache.http.HttpEntity) IAS4IncomingMessageMetadata(com.helger.phase4.messaging.IAS4IncomingMessageMetadata) AS4IncomingMessageMetadata(com.helger.phase4.servlet.AS4IncomingMessageMetadata) Ebms3UserMessage(com.helger.phase4.ebms3header.Ebms3UserMessage) HttpResponse(org.apache.http.HttpResponse)

Example 3 with MPC

use of com.helger.phase4.model.mpc.MPC in project phase4 by phax.

the class SOAPHeaderElementProcessorExtractEbms3Messaging method processHeaderElement.

@Nonnull
public ESuccess processHeaderElement(@Nonnull final Document aSOAPDoc, @Nonnull final Element aElement, @Nonnull final ICommonsList<WSS4JAttachment> aAttachments, @Nonnull final AS4MessageState aState, @Nonnull final ErrorList aErrorList) {
    final IMPCManager aMPCMgr = MetaAS4Manager.getMPCMgr();
    IPMode aPMode = null;
    final ICommonsMap<String, EAS4CompressionMode> aCompressionAttachmentIDs = new CommonsHashMap<>();
    IMPC aEffectiveMPC = null;
    String sInitiatorID = null;
    String sResponderID = null;
    final Locale aLocale = aState.getLocale();
    // Parse EBMS3 Messaging object
    final CollectingValidationEventHandler aCVEH = new CollectingValidationEventHandler();
    final Ebms3Messaging aMessaging = Ebms3ReaderBuilder.ebms3Messaging().setValidationEventHandler(aCVEH).read(aElement);
    // wellformed
    if (aMessaging == null) {
        // Invalid Header == not wellformed/invalid xml
        for (final IError aError : aCVEH.getErrorList()) {
            LOGGER.error("Header error: " + aError.getAsString(aLocale));
            aErrorList.add(SingleError.builder(aError).errorID(EEbmsError.EBMS_INVALID_HEADER.getErrorCode()).build());
        }
        return ESuccess.FAILURE;
    }
    // Remember in state
    aState.setMessaging(aMessaging);
    // 0 or 1 are allowed
    final int nUserMessages = aMessaging.getUserMessageCount();
    if (nUserMessages > 1) {
        LOGGER.error("Too many UserMessage objects (" + nUserMessages + ") contained.");
        aErrorList.add(EEbmsError.EBMS_VALUE_INCONSISTENT.getAsError(aLocale));
        return ESuccess.FAILURE;
    }
    // 0 or 1 are allowed
    final int nSignalMessages = aMessaging.getSignalMessageCount();
    if (nSignalMessages > 1) {
        LOGGER.error("Too many SignalMessage objects (" + nSignalMessages + ") contained.");
        aErrorList.add(EEbmsError.EBMS_VALUE_INCONSISTENT.getAsError(aLocale));
        return ESuccess.FAILURE;
    }
    if (nUserMessages + nSignalMessages == 0) {
        // No Message was found
        LOGGER.error("Neither UserMessage nor SignalMessage object contained.");
        aErrorList.add(EEbmsError.EBMS_VALUE_INCONSISTENT.getAsError(aLocale));
        return ESuccess.FAILURE;
    }
    // Check if the usermessage has a PMode in the collaboration info
    final Ebms3UserMessage aUserMessage = CollectionHelper.getAtIndex(aMessaging.getUserMessage(), 0);
    if (aUserMessage != null) {
        final Ebms3MessageInfo aMsgInfo = aUserMessage.getMessageInfo();
        if (aMsgInfo != null) {
            // Set this is as early as possible, so that eventually occurring error
            // messages can use the "RefToMessageId" element properly
            aState.setMessageID(aMsgInfo.getMessageId());
            aState.setRefToMessageID(aMsgInfo.getRefToMessageId());
            aState.setMessageTimestamp(aMsgInfo.getTimestamp());
        }
        // PartyInfo is mandatory in UserMessage
        // From is mandatory in PartyInfo
        // To is mandatory in PartyInfo
        final List<Ebms3PartyId> aFromPartyIdList = aUserMessage.getPartyInfo().getFrom().getPartyId();
        final List<Ebms3PartyId> aToPartyIdList = aUserMessage.getPartyInfo().getTo().getPartyId();
        if (aFromPartyIdList.size() > 1 || aToPartyIdList.size() > 1) {
            LOGGER.error("More than one PartyId is containted in From or To Recipient please check the message.");
            aErrorList.add(EEbmsError.EBMS_VALUE_INCONSISTENT.getAsError(aLocale));
            return ESuccess.FAILURE;
        }
        // Setting Initiator and Responder id, Required values or else xsd will
        // throw an error
        sInitiatorID = aFromPartyIdList.get(0).getValue();
        sResponderID = aToPartyIdList.get(0).getValue();
        final Ebms3CollaborationInfo aCollaborationInfo = aUserMessage.getCollaborationInfo();
        if (aCollaborationInfo != null) {
            // Find PMode
            String sPModeID = null;
            String sAgreementRef = null;
            if (aCollaborationInfo.getAgreementRef() != null) {
                sPModeID = aCollaborationInfo.getAgreementRef().getPmode();
                sAgreementRef = aCollaborationInfo.getAgreementRef().getValue();
            }
            // Get responder address from properties file (may be null)
            final String sAddress = AS4Configuration.getThisEndpointAddress();
            aPMode = m_aPModeResolver.getPModeOfID(sPModeID, aCollaborationInfo.getService().getValue(), aCollaborationInfo.getAction(), sInitiatorID, sResponderID, sAgreementRef, sAddress);
            // Should be screened by the XSD conversion already
            if (aPMode == null) {
                LOGGER.error("Failed to resolve PMode '" + sPModeID + "' using resolver " + m_aPModeResolver);
                aErrorList.add(EEbmsError.EBMS_PROCESSING_MODE_MISMATCH.getAsError(aLocale));
                return ESuccess.FAILURE;
            }
        }
        // to use the configuration for leg2
        PModeLeg aPModeLeg1 = null;
        PModeLeg aPModeLeg2 = null;
        // Needed for the compression check: it is not allowed to have a
        // compressed attachment and a SOAPBodyPayload
        boolean bHasSoapBodyPayload = false;
        if (aPMode != null) {
            aPModeLeg1 = aPMode.getLeg1();
            aPModeLeg2 = aPMode.getLeg2();
            // both are present
            if (aPMode.getMEPBinding().getRequiredLegs() == 2 && aPModeLeg2 == null) {
                LOGGER.error("Error processing the UserMessage, PMode does not contain leg 2.");
                aErrorList.add(EEbmsError.EBMS_PROCESSING_MODE_MISMATCH.getAsError(aLocale));
                return ESuccess.FAILURE;
            }
            final boolean bUseLeg1 = _isUseLeg1(aUserMessage);
            final PModeLeg aEffectiveLeg = bUseLeg1 ? aPModeLeg1 : aPModeLeg2;
            final int nLegNum = bUseLeg1 ? 1 : 2;
            if (aEffectiveLeg == null) {
                LOGGER.error("Error processing the UserMessage, PMode does not contain effective leg " + nLegNum + ".");
                aErrorList.add(EEbmsError.EBMS_PROCESSING_MODE_MISMATCH.getAsError(aLocale));
                return ESuccess.FAILURE;
            }
            aState.setEffectivePModeLeg(nLegNum, aEffectiveLeg);
            if (_checkMPCOfPMode(aEffectiveLeg, aMPCMgr, aLocale, aErrorList).isFailure())
                return ESuccess.FAILURE;
            bHasSoapBodyPayload = _checkSOAPBodyHasPayload(aEffectiveLeg, aSOAPDoc);
            final String sEffectiveMPCID = _getMPCIDOfUserMsg(aUserMessage, aEffectiveLeg);
            // PMode is valid
            // Now Check if MPC valid
            aEffectiveMPC = aMPCMgr.getMPCOrDefaultOfID(sEffectiveMPCID);
            if (aEffectiveMPC == null) {
                LOGGER.error("Error processing the UserMessage, effective MPC ID '" + sEffectiveMPCID + "' is unknown!");
                aErrorList.add(EEbmsError.EBMS_VALUE_INCONSISTENT.getAsError(aLocale));
                return ESuccess.FAILURE;
            }
        }
        // Remember in state
        aState.setSoapBodyPayloadPresent(bHasSoapBodyPayload);
        final Ebms3PayloadInfo aEbms3PayloadInfo = aUserMessage.getPayloadInfo();
        if (aEbms3PayloadInfo == null || aEbms3PayloadInfo.getPartInfo().isEmpty()) {
            if (bHasSoapBodyPayload) {
                LOGGER.error("No PayloadInfo/PartInfo is specified, so no SOAP body payload is allowed.");
                aErrorList.add(EEbmsError.EBMS_VALUE_INCONSISTENT.getAsError(aLocale));
                return ESuccess.FAILURE;
            }
            // attachments in the message
            if (aAttachments.isNotEmpty()) {
                LOGGER.error("No PayloadInfo/PartInfo is specified, so no attachments are allowed.");
                aErrorList.add(EEbmsError.EBMS_EXTERNAL_PAYLOAD_ERROR.getAsError(aLocale));
                return ESuccess.FAILURE;
            }
        } else {
            // Check if there are more Attachments then specified
            if (aAttachments.size() > aEbms3PayloadInfo.getPartInfoCount()) {
                LOGGER.error("Error processing the UserMessage, the amount of specified attachments does not correlate with the actual attachments in the UserMessage. Expected " + aEbms3PayloadInfo.getPartInfoCount() + " but having " + aAttachments.size() + " attachments.");
                aErrorList.add(EEbmsError.EBMS_EXTERNAL_PAYLOAD_ERROR.getAsError(aLocale));
                return ESuccess.FAILURE;
            }
            int nSpecifiedAttachments = 0;
            for (final Ebms3PartInfo aPartInfo : aEbms3PayloadInfo.getPartInfo()) {
                // If href is null or empty there has to be a SOAP Payload
                if (StringHelper.hasNoText(aPartInfo.getHref())) {
                    // Check if there is a BodyPayload as specified in the UserMessage
                    if (!bHasSoapBodyPayload) {
                        LOGGER.error("Error processing the UserMessage. Expected a SOAPBody Payload but there is none present.");
                        aErrorList.add(EEbmsError.EBMS_VALUE_INCONSISTENT.getAsError(aLocale));
                        return ESuccess.FAILURE;
                    }
                } else {
                    // Attachment
                    // To check attachments which are specified in the usermessage and
                    // the real amount in the mime message
                    nSpecifiedAttachments++;
                    final String sAttachmentID = StringHelper.trimStart(aPartInfo.getHref(), MessageHelperMethods.PREFIX_CID);
                    final WSS4JAttachment aIncomingAttachment = aAttachments.findFirst(x -> EqualsHelper.equals(x.getId(), sAttachmentID));
                    if (aIncomingAttachment == null) {
                        LOGGER.warn("Failed to resolve MIME attachment '" + sAttachmentID + "' in list of " + aAttachments.getAllMapped(WSS4JAttachment::getId));
                    }
                    boolean bMimeTypePresent = false;
                    boolean bCompressionTypePresent = false;
                    if (aPartInfo.getPartProperties() != null)
                        for (final Ebms3Property aEbms3Property : aPartInfo.getPartProperties().getProperty()) {
                            final String sPropertyName = aEbms3Property.getName();
                            final String sPropertyValue = aEbms3Property.getValue();
                            if (sPropertyName.equalsIgnoreCase(MessageHelperMethods.PART_PROPERTY_MIME_TYPE)) {
                                bMimeTypePresent = StringHelper.hasText(sPropertyValue);
                            } else if (sPropertyName.equalsIgnoreCase(MessageHelperMethods.PART_PROPERTY_COMPRESSION_TYPE)) {
                                // Only needed check here since AS4 does not support another
                                // CompressionType
                                // http://wiki.ds.unipi.gr/display/ESENS/PR+-+AS4
                                final EAS4CompressionMode eCompressionMode = EAS4CompressionMode.getFromMimeTypeStringOrNull(sPropertyValue);
                                if (eCompressionMode == null) {
                                    LOGGER.error("Error processing the UserMessage, CompressionType '" + sPropertyValue + "' of attachment '" + sAttachmentID + "' is not supported.");
                                    aErrorList.add(EEbmsError.EBMS_VALUE_INCONSISTENT.getAsError(aLocale));
                                    return ESuccess.FAILURE;
                                }
                                aCompressionAttachmentIDs.put(sAttachmentID, eCompressionMode);
                                bCompressionTypePresent = true;
                            } else if (sPropertyName.equalsIgnoreCase(MessageHelperMethods.PART_PROPERTY_CHARACTER_SET)) {
                                if (StringHelper.hasText(sPropertyValue)) {
                                    final Charset aCharset = CharsetHelper.getCharsetFromNameOrNull(sPropertyValue);
                                    if (aCharset == null) {
                                        LOGGER.error("Value '" + sPropertyValue + "' of property '" + MessageHelperMethods.PART_PROPERTY_CHARACTER_SET + "' of attachment '" + sAttachmentID + "' is not supported");
                                        aErrorList.add(EEbmsError.EBMS_VALUE_INCONSISTENT.getAsError(aLocale));
                                        return ESuccess.FAILURE;
                                    } else if (aIncomingAttachment != null)
                                        aIncomingAttachment.setCharset(aCharset);
                                }
                            }
                        // else we don't care about the property
                        }
                    // got compressed
                    if (bCompressionTypePresent && !bMimeTypePresent) {
                        LOGGER.error("Error processing the UserMessage, MimeType for a compressed attachment ('" + sAttachmentID + "') is not present.");
                        aErrorList.add(EEbmsError.EBMS_VALUE_INCONSISTENT.getAsError(aLocale));
                        return ESuccess.FAILURE;
                    }
                }
            }
            // This may also be an indicator for "external payloads"
            if (nSpecifiedAttachments != aAttachments.size()) {
                LOGGER.error("Error processing the UserMessage: the amount of specified attachments does not correlate with the actual attachments in the UserMessage. Expected " + aEbms3PayloadInfo.getPartInfoCount() + " but having " + aAttachments.size() + " attachments. This is an indicator, that an external attached was provided.");
                aErrorList.add(EEbmsError.EBMS_EXTERNAL_PAYLOAD_ERROR.getAsError(aLocale));
                return ESuccess.FAILURE;
            }
        }
    } else {
        // Must be a SignalMessage
        // all vars stay null
        final Ebms3SignalMessage aSignalMessage = aMessaging.getSignalMessageAtIndex(0);
        final Ebms3MessageInfo aMsgInfo = aSignalMessage.getMessageInfo();
        if (aMsgInfo != null) {
            // Set this is as early as possible, so that eventually occurring error
            // messages can use the "RefToMessageId" element properly
            aState.setMessageID(aMsgInfo.getMessageId());
            aState.setRefToMessageID(aMsgInfo.getRefToMessageId());
            aState.setMessageTimestamp(aMsgInfo.getTimestamp());
        }
        final Ebms3PullRequest aEbms3PullRequest = aSignalMessage.getPullRequest();
        final Ebms3Receipt aEbms3Receipt = aSignalMessage.getReceipt();
        if (aEbms3PullRequest != null) {
            final String sMPC = aEbms3PullRequest.getMpc();
            final IMPC aMPC = aMPCMgr.getMPCOfID(sMPC);
            if (aMPC == null) {
                LOGGER.error("Failed to resolve the PullRequest MPC '" + sMPC + "'");
                // Return value not recognized when MPC is not currently saved
                aErrorList.add(EEbmsError.EBMS_VALUE_NOT_RECOGNIZED.getAsError(aLocale));
                return ESuccess.FAILURE;
            }
            // Create SPI which returns a PMode
            for (final IAS4ServletPullRequestProcessorSPI aProcessor : AS4ServletPullRequestProcessorManager.getAllProcessors()) {
                aPMode = aProcessor.findPMode(aSignalMessage);
                if (aPMode != null) {
                    LOGGER.info("Found PMode '" + aPMode.getID() + "' for MPC '" + sMPC + "' in SignalMessage " + aSignalMessage);
                    break;
                }
            }
            if (aPMode == null) {
                LOGGER.error("Failed to resolve PMode for PullRequest with MPC '" + sMPC + "'");
                aErrorList.add(EEbmsError.EBMS_VALUE_NOT_RECOGNIZED.getAsError(aLocale));
                return ESuccess.FAILURE;
            }
        } else if (aEbms3Receipt != null) {
            final String sRefToMessageID = aSignalMessage.getMessageInfo().getRefToMessageId();
            if (StringHelper.hasNoText(sRefToMessageID)) {
                LOGGER.error("The Receipt does not contain a RefToMessageId");
                aErrorList.add(EEbmsError.EBMS_INVALID_RECEIPT.getAsError(aLocale));
                return ESuccess.FAILURE;
            }
        } else {
            // Error Message
            if (!aSignalMessage.getError().isEmpty()) {
                for (final Ebms3Error aError : aSignalMessage.getError()) {
                    /*
               * Ebms 3 spec 6.2.6: This OPTIONAL attribute indicates the
               * MessageId of the message in error, for which this error is
               * raised.
               */
                    if (false)
                        if (StringHelper.hasNoText(aError.getRefToMessageInError())) {
                            aErrorList.add(EEbmsError.EBMS_VALUE_INCONSISTENT.getAsError(aLocale));
                            return ESuccess.FAILURE;
                        }
                }
            }
        }
    }
    // Remember in state
    aState.setPMode(aPMode);
    aState.setOriginalSoapDocument(aSOAPDoc);
    aState.setOriginalAttachments(aAttachments);
    aState.setCompressedAttachmentIDs(aCompressionAttachmentIDs);
    aState.setMPC(aEffectiveMPC);
    aState.setInitiatorID(sInitiatorID);
    aState.setResponderID(sResponderID);
    return ESuccess.SUCCESS;
}
Also used : Locale(java.util.Locale) Ebms3SignalMessage(com.helger.phase4.ebms3header.Ebms3SignalMessage) PModeLeg(com.helger.phase4.model.pmode.leg.PModeLeg) EAS4CompressionMode(com.helger.phase4.attachment.EAS4CompressionMode) Ebms3PartyId(com.helger.phase4.ebms3header.Ebms3PartyId) Ebms3PayloadInfo(com.helger.phase4.ebms3header.Ebms3PayloadInfo) Ebms3PullRequest(com.helger.phase4.ebms3header.Ebms3PullRequest) CommonsHashMap(com.helger.commons.collection.impl.CommonsHashMap) Ebms3MessageInfo(com.helger.phase4.ebms3header.Ebms3MessageInfo) Ebms3Property(com.helger.phase4.ebms3header.Ebms3Property) Ebms3Receipt(com.helger.phase4.ebms3header.Ebms3Receipt) CollectingValidationEventHandler(com.helger.jaxb.validation.CollectingValidationEventHandler) Charset(java.nio.charset.Charset) Ebms3PartInfo(com.helger.phase4.ebms3header.Ebms3PartInfo) Ebms3Error(com.helger.phase4.ebms3header.Ebms3Error) IError(com.helger.commons.error.IError) IAS4ServletPullRequestProcessorSPI(com.helger.phase4.servlet.spi.IAS4ServletPullRequestProcessorSPI) IMPC(com.helger.phase4.model.mpc.IMPC) Ebms3CollaborationInfo(com.helger.phase4.ebms3header.Ebms3CollaborationInfo) IMPCManager(com.helger.phase4.model.mpc.IMPCManager) IPMode(com.helger.phase4.model.pmode.IPMode) Ebms3UserMessage(com.helger.phase4.ebms3header.Ebms3UserMessage) Ebms3Messaging(com.helger.phase4.ebms3header.Ebms3Messaging) WSS4JAttachment(com.helger.phase4.attachment.WSS4JAttachment) Nonnull(javax.annotation.Nonnull)

Example 4 with MPC

use of com.helger.phase4.model.mpc.MPC in project phase4 by phax.

the class PullRequestTest method testSendPullRequestFailure.

@Test
public void testSendPullRequestFailure() throws Exception {
    // Special MPC name handled in MockMessageProcessorSPI
    final String sFailure = MockMessageProcessorSPI.MPC_FAILURE;
    final MPC aMPC = new MPC(sFailure);
    if (MetaAS4Manager.getMPCMgr().getMPCOfID(sFailure) == null)
        MetaAS4Manager.getMPCMgr().createMPC(aMPC);
    final Document aDoc = AS4PullRequestMessage.create(m_eSoapVersion, MessageHelperMethods.createEbms3MessageInfo(), sFailure, null).getAsSoapDocument();
    final HttpEntity aEntity = new HttpXMLEntity(aDoc, m_eSoapVersion.getMimeType());
    sendPlainMessageAndWait(aEntity, false, EEbmsError.EBMS_OTHER.getErrorCode());
}
Also used : MPC(com.helger.phase4.model.mpc.MPC) HttpEntity(org.apache.http.HttpEntity) HttpXMLEntity(com.helger.phase4.http.HttpXMLEntity) Document(org.w3c.dom.Document) Test(org.junit.Test)

Example 5 with MPC

use of com.helger.phase4.model.mpc.MPC in project phase4 by phax.

the class PullRequestTest method testSendPullRequestEmpty.

@Test
public void testSendPullRequestEmpty() throws Exception {
    // Special MPC name handled in MockMessageProcessorSPI
    final String sFailure = MockMessageProcessorSPI.MPC_EMPTY;
    final MPC aMPC = new MPC(sFailure);
    if (MetaAS4Manager.getMPCMgr().getMPCOfID(sFailure) == null)
        MetaAS4Manager.getMPCMgr().createMPC(aMPC);
    final Document aDoc = AS4PullRequestMessage.create(m_eSoapVersion, MessageHelperMethods.createEbms3MessageInfo(), sFailure, null).getAsSoapDocument();
    final HttpEntity aEntity = new HttpXMLEntity(aDoc, m_eSoapVersion.getMimeType());
    sendPlainMessageAndWait(aEntity, false, EEbmsError.EBMS_EMPTY_MESSAGE_PARTITION_CHANNEL.getErrorCode());
}
Also used : MPC(com.helger.phase4.model.mpc.MPC) HttpEntity(org.apache.http.HttpEntity) HttpXMLEntity(com.helger.phase4.http.HttpXMLEntity) Document(org.w3c.dom.Document) Test(org.junit.Test)

Aggregations

Ebms3UserMessage (com.helger.phase4.ebms3header.Ebms3UserMessage)4 HttpEntity (org.apache.http.HttpEntity)4 Ebms3Property (com.helger.phase4.ebms3header.Ebms3Property)3 HttpXMLEntity (com.helger.phase4.http.HttpXMLEntity)3 MPC (com.helger.phase4.model.mpc.MPC)3 Nonnull (javax.annotation.Nonnull)3 Test (org.junit.Test)3 Document (org.w3c.dom.Document)3 WSS4JAttachment (com.helger.phase4.attachment.WSS4JAttachment)2 Ebms3CollaborationInfo (com.helger.phase4.ebms3header.Ebms3CollaborationInfo)2 Ebms3Error (com.helger.phase4.ebms3header.Ebms3Error)2 Ebms3MessageInfo (com.helger.phase4.ebms3header.Ebms3MessageInfo)2 Ebms3PayloadInfo (com.helger.phase4.ebms3header.Ebms3PayloadInfo)2 Ebms3PullRequest (com.helger.phase4.ebms3header.Ebms3PullRequest)2 Ebms3SignalMessage (com.helger.phase4.ebms3header.Ebms3SignalMessage)2 Phase4Exception (com.helger.phase4.util.Phase4Exception)2 IOException (java.io.IOException)2 Locale (java.util.Locale)2 MessagingException (javax.mail.MessagingException)2 WSSecurityException (org.apache.wss4j.common.ext.WSSecurityException)2