use of com.helger.phase4.ebms3header.Ebms3Error in project phase4 by phax.
the class MockMessages method createErrorMessageSigned.
@Nonnull
public static Document createErrorMessageSigned(@Nonnull final ESoapVersion eSOAPVersion, @Nullable final ICommonsList<WSS4JAttachment> aAttachments, @Nonnull final AS4ResourceHelper aResMgr) throws WSSecurityException {
final ICommonsList<Ebms3Error> aEbms3ErrorList = new CommonsArrayList<>(EEbmsError.EBMS_INVALID_HEADER.getAsEbms3Error(Locale.US, null));
final AS4ErrorMessage aErrorMsg = AS4ErrorMessage.create(eSOAPVersion, "srcmsgid", aEbms3ErrorList).setMustUnderstand(true);
return AS4Signer.createSignedMessage(AS4CryptoFactoryProperties.getDefaultInstance(), aErrorMsg.getAsSoapDocument(), eSOAPVersion, aErrorMsg.getMessagingID(), aAttachments, aResMgr, false, AS4SigningParams.createDefault());
}
use of com.helger.phase4.ebms3header.Ebms3Error in project phase4 by phax.
the class AS4RequestHandler method handleRequest.
/**
* This is the main handling routine when called from an abstract
* (non-Servlet) API
*
* @param aServletRequestIS
* The input stream with the request data. May not be
* <code>null</code>.
* @param aRequestHttpHeaders
* The HTTP headers of the request. May not be <code>null</code>.
* @param aHttpResponse
* The HTTP response to be filled. May not be <code>null</code>.
* @throws Phase4Exception
* in case the request is missing certain prerequisites. Since 0.9.11
* @throws IOException
* In case of IO errors
* @throws MessagingException
* MIME related errors
* @throws WSSecurityException
* In case of WSS4J errors
* @see #handleRequest(InputStream, HttpHeaderMap, IAS4ResponseAbstraction)
* for a more generic API
*/
public void handleRequest(@Nonnull @WillClose final InputStream aServletRequestIS, @Nonnull final HttpHeaderMap aRequestHttpHeaders, @Nonnull final IAS4ResponseAbstraction aHttpResponse) throws Phase4Exception, IOException, MessagingException, WSSecurityException {
final IAS4ParsedMessageCallback aCallback = (aHttpHeaders, aSoapDocument, eSoapVersion, aIncomingAttachments) -> {
// SOAP document and SOAP version are determined
// Collect all runtime errors
final ICommonsList<Ebms3Error> aErrorMessages = new CommonsArrayList<>();
final IAS4ResponseFactory aResponder = _handleSoapMessage(aHttpHeaders, aSoapDocument, eSoapVersion, aIncomingAttachments, aErrorMessages);
if (aResponder != null) {
// Response present -> send back
final IAS4OutgoingDumper aRealOutgoingDumper = m_aOutgoingDumper != null ? m_aOutgoingDumper : AS4DumpManager.getOutgoingDumper();
aResponder.applyToResponse(aHttpResponse, aRealOutgoingDumper);
} else {
// Success, HTTP No Content
aHttpResponse.setStatus(CHttp.HTTP_NO_CONTENT);
}
AS4HttpDebug.debug(() -> "RECEIVE-END with " + (aResponder != null ? "EBMS message" : "no content"));
};
AS4IncomingHandler.parseAS4Message(m_aIAF, m_aResHelper, m_aMessageMetadata, aServletRequestIS, aRequestHttpHeaders, aCallback, m_aIncomingDumper);
}
use of com.helger.phase4.ebms3header.Ebms3Error 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);
}
use of com.helger.phase4.ebms3header.Ebms3Error in project phase4 by phax.
the class AS4RequestHandler method _handleSoapMessage.
@Nullable
private IAS4ResponseFactory _handleSoapMessage(@Nonnull final HttpHeaderMap aHttpHeaders, @Nonnull final Document aSoapDocument, @Nonnull final ESoapVersion eSoapVersion, @Nonnull final ICommonsList<WSS4JAttachment> aIncomingAttachments, @Nonnull final ICommonsList<Ebms3Error> aErrorMessagesTarget) throws WSSecurityException, MessagingException, Phase4Exception {
final SOAPHeaderElementProcessorRegistry aRegistry = SOAPHeaderElementProcessorRegistry.createDefault(m_aPModeResolver, m_aCryptoFactory, (IPMode) null);
final IAS4MessageState aState = AS4IncomingHandler.processEbmsMessage(m_aResHelper, m_aLocale, aRegistry, aHttpHeaders, aSoapDocument, eSoapVersion, aIncomingAttachments, m_aIncomingProfileSelector, aErrorMessagesTarget);
final IPMode aPMode = aState.getPMode();
final PModeLeg aEffectiveLeg = aState.getEffectivePModeLeg();
final String sMessageID = aState.getMessageID();
final ICommonsList<WSS4JAttachment> aDecryptedAttachments = aState.hasDecryptedAttachments() ? aState.getDecryptedAttachments() : aState.getOriginalAttachments();
final Node aPayloadNode = aState.getSoapBodyPayloadNode();
final Ebms3UserMessage aEbmsUserMessage = aState.getEbmsUserMessage();
final Ebms3SignalMessage aEbmsSignalMessage = aState.getEbmsSignalMessage();
if (aState.isSoapHeaderElementProcessingSuccessful()) {
final String sProfileID = aState.getProfileID();
if (LOGGER.isDebugEnabled())
LOGGER.debug("No checking for duplicate message with message ID '" + sMessageID + "' and profile ID '" + sProfileID + "'");
final boolean bIsDuplicate = MetaAS4Manager.getIncomingDuplicateMgr().registerAndCheck(sMessageID, sProfileID, aPMode == null ? null : aPMode.getID()).isBreak();
if (bIsDuplicate) {
LOGGER.error("Not invoking SPIs, because message with Message ID '" + sMessageID + "' was already handled!");
aErrorMessagesTarget.add(EEbmsError.EBMS_OTHER.getAsEbms3Error(m_aLocale, sMessageID, "Another message with the same Message ID '" + sMessageID + "' was already received!"));
} else {
if (LOGGER.isDebugEnabled())
LOGGER.debug("Message is not a duplicate");
}
}
final SPIInvocationResult aSPIResult = new SPIInvocationResult();
// Storing for two-way response messages
final ICommonsList<WSS4JAttachment> aResponseAttachments = new CommonsArrayList<>();
// Invoke SPIs if
// * No errors so far (sign, encrypt, ...)
// * Valid PMode
// * Exactly one UserMessage or SignalMessage
// * No ping/test message
// * No Duplicate message ID
final boolean bCanInvokeSPIs = aErrorMessagesTarget.isEmpty() && !aState.isPingMessage();
if (bCanInvokeSPIs) {
// PMode may be null for receipts
if (aPMode == null || aPMode.getMEPBinding().isSynchronous() || aPMode.getMEPBinding().isAsynchronousInitiator() || aState.getEffectivePModeLegNumber() != 1) {
// Call synchronous
// Might add to aErrorMessages
// Might add to aResponseAttachments
// Might add to m_aPullReturnUserMsg
_invokeSPIsForIncoming(aHttpHeaders, aEbmsUserMessage, aEbmsSignalMessage, aPayloadNode, aDecryptedAttachments, aPMode, aState, aErrorMessagesTarget, aResponseAttachments, aSPIResult);
if (aSPIResult.isFailure())
LOGGER.warn("Error invoking synchronous SPIs");
else if (LOGGER.isDebugEnabled())
LOGGER.debug("Successfully invoked synchronous SPIs");
if (m_aSoapProcessingFinalizedCB != null)
m_aSoapProcessingFinalizedCB.onProcessingFinalized(true);
} else {
// Call asynchronous
// Only leg1 can be async!
final IThrowingRunnable<Exception> r = () -> {
// Start async
final ICommonsList<Ebms3Error> aLocalErrorMessages = new CommonsArrayList<>();
final ICommonsList<WSS4JAttachment> aLocalResponseAttachments = new CommonsArrayList<>();
final SPIInvocationResult aAsyncSPIResult = new SPIInvocationResult();
_invokeSPIsForIncoming(aHttpHeaders, aEbmsUserMessage, aEbmsSignalMessage, aPayloadNode, aDecryptedAttachments, aPMode, aState, aLocalErrorMessages, aLocalResponseAttachments, aAsyncSPIResult);
final IAS4ResponseFactory aAsyncResponseFactory;
final String sResponseMessageID;
if (aAsyncSPIResult.isSuccess()) {
// SPI processing succeeded
assert aLocalErrorMessages.isEmpty();
// The response user message has no explicit payload. All data of
// the response user message is in the local attachments
sResponseMessageID = MessageHelperMethods.createRandomMessageID();
final AS4UserMessage aResponseUserMsg = _createReversedUserMessage(eSoapVersion, sResponseMessageID, aEbmsUserMessage, aLocalResponseAttachments);
// Send UserMessage
final AS4SigningParams aSigningParams = new AS4SigningParams().setFromPMode(aEffectiveLeg.getSecurity());
// Use the original receiver ID as the alias into the keystore for
// encrypting the response message
final String sEncryptionAlias = aEbmsUserMessage.getPartyInfo().getTo().getPartyIdAtIndex(0).getValue();
final AS4CryptParams aCryptParams = new AS4CryptParams().setFromPMode(aEffectiveLeg.getSecurity()).setAlias(sEncryptionAlias);
aAsyncResponseFactory = _createResponseUserMessage(aState, aEffectiveLeg.getProtocol().getSoapVersion(), aResponseUserMsg, aResponseAttachments, aSigningParams, aCryptParams);
} else {
// SPI processing failed
// Send ErrorMessage Undefined - see
// https://github.com/phax/phase4/issues/4
final AS4ErrorMessage aResponseErrorMsg = AS4ErrorMessage.create(eSoapVersion, aState.getMessageID(), aLocalErrorMessages);
sResponseMessageID = aResponseErrorMsg.getEbms3SignalMessage().getMessageInfo().getMessageId();
// Pass error messages to the outside
if (m_aErrorConsumer != null && aLocalErrorMessages.isNotEmpty())
m_aErrorConsumer.onAS4ErrorMessage(aState, aLocalErrorMessages, aResponseErrorMsg);
aAsyncResponseFactory = new AS4ResponseFactoryXML(m_aMessageMetadata, aState, sResponseMessageID, aResponseErrorMsg.getAsSoapDocument(), eSoapVersion.getMimeType());
}
// where to send it back (must be determined by SPI!)
final String sAsyncResponseURL = aAsyncSPIResult.getAsyncResponseURL();
if (StringHelper.hasNoText(sAsyncResponseURL))
throw new IllegalStateException("No asynchronous response URL present - please check your SPI implementation");
if (LOGGER.isDebugEnabled())
LOGGER.debug("Responding asynchronous to: " + sAsyncResponseURL);
// Ensure HttpEntity is repeatable
HttpEntity aHttpEntity = aAsyncResponseFactory.getHttpEntityForSending(eSoapVersion.getMimeType());
aHttpEntity = m_aResHelper.createRepeatableHttpEntity(aHttpEntity);
// Use the prebuilt entity for dumping
_invokeSPIsForResponse(aState, aAsyncResponseFactory, aHttpEntity, eSoapVersion.getMimeType(), sResponseMessageID);
// invoke client with new document
final BasicHttpPoster aSender = new BasicHttpPoster();
final Document aAsyncResponse;
if (true) {
final HttpHeaderMap aResponseHttpHeaders = null;
// TODO make async send parameters customizable
final HttpRetrySettings aRetrySettings = new HttpRetrySettings();
aAsyncResponse = aSender.sendGenericMessageWithRetries(sAsyncResponseURL, aResponseHttpHeaders, aHttpEntity, sMessageID, aRetrySettings, new ResponseHandlerXml(), m_aOutgoingDumper, m_aRetryCallback);
} else {
aAsyncResponse = aSender.sendGenericMessage(sAsyncResponseURL, null, aHttpEntity, new ResponseHandlerXml());
}
AS4HttpDebug.debug(() -> "SEND-RESPONSE [async sent] received: " + XMLWriter.getNodeAsString(aAsyncResponse, AS4HttpDebug.getDebugXMLWriterSettings()));
};
final CompletableFuture<Void> aFuture = PhotonWorkerPool.getInstance().runThrowing(CAS4.LIB_NAME + " async processing", r);
if (m_aSoapProcessingFinalizedCB != null) {
// Give the outside world the possibility to get notified when the
// processing is done
aFuture.thenRun(() -> m_aSoapProcessingFinalizedCB.onProcessingFinalized(false));
}
}
}
// Try building error message
final String sResponseMessageID;
final IAS4ResponseFactory ret;
if (!aState.isSoapHeaderElementProcessingSuccessful() || aState.getEbmsError() == null) {
// Not an incoming Ebms Error Message
if (aErrorMessagesTarget.isNotEmpty()) {
if (LOGGER.isDebugEnabled())
LOGGER.debug("Creating AS4 error message with these " + aErrorMessagesTarget.size() + " errors: " + aErrorMessagesTarget.getAllMapped(Ebms3Error::getDescriptionValue));
final AS4ErrorMessage aResponseErrorMsg = AS4ErrorMessage.create(eSoapVersion, aState.getMessageID(), aErrorMessagesTarget);
// Call optional consumer
if (m_aErrorConsumer != null)
m_aErrorConsumer.onAS4ErrorMessage(aState, aErrorMessagesTarget, aResponseErrorMsg);
// When aLeg == null, the response is true
if (_isSendErrorAsResponse(aEffectiveLeg)) {
sResponseMessageID = aResponseErrorMsg.getEbms3SignalMessage().getMessageInfo().getMessageId();
ret = new AS4ResponseFactoryXML(m_aMessageMetadata, aState, sResponseMessageID, aResponseErrorMsg.getAsSoapDocument(), eSoapVersion.getMimeType());
} else {
LOGGER.warn("Not sending back the error, because sending error response is prohibited in PMode");
sResponseMessageID = null;
ret = null;
}
} else {
// Do not respond to receipt (except with error message - see above)
if (aEbmsSignalMessage == null || aEbmsSignalMessage.getReceipt() == null) {
// So now the incoming message is a user message or a pull request
if (aPMode.getMEP().isOneWay() || aPMode.getMEPBinding().isAsynchronous()) {
// the pull phase
if (aPMode.getMEPBinding().equals(EMEPBinding.PULL) || (aPMode.getMEPBinding().equals(EMEPBinding.PULL_PUSH) && aSPIResult.hasPullReturnUserMsg()) || (aPMode.getMEPBinding().equals(EMEPBinding.PUSH_PULL) && aSPIResult.hasPullReturnUserMsg())) {
// TODO would be nice to have attachments here I guess
final AS4UserMessage aResponseUserMsg = new AS4UserMessage(eSoapVersion, aSPIResult.getPullReturnUserMsg());
sResponseMessageID = aResponseUserMsg.getEbms3UserMessage().getMessageInfo().getMessageId();
ret = new AS4ResponseFactoryXML(m_aMessageMetadata, aState, sResponseMessageID, aResponseUserMsg.getAsSoapDocument(), eSoapVersion.getMimeType());
} else if (aEbmsUserMessage != null) {
// We received an incoming user message and no errors occurred
final boolean bSendReceiptAsResponse = _isSendReceiptAsResponse(aEffectiveLeg);
if (bSendReceiptAsResponse) {
sResponseMessageID = MessageHelperMethods.createRandomMessageID();
ret = _createResponseReceiptMessage(aState, aSoapDocument, eSoapVersion, sResponseMessageID, aEffectiveLeg, aEbmsUserMessage, aResponseAttachments);
} else {
// TODO what shall we send back here?
LOGGER.info("Not sending back the Receipt response, because sending Receipt response is prohibited in PMode");
sResponseMessageID = null;
ret = null;
}
} else {
sResponseMessageID = null;
ret = null;
}
} else {
// synchronous TWO - WAY (= "SYNC")
final PModeLeg aLeg2 = aPMode.getLeg2();
if (aLeg2 == null)
throw new Phase4Exception("PMode has no leg2!");
if (MEPHelper.isValidResponseTypeLeg2(aPMode.getMEP(), aPMode.getMEPBinding(), EAS4MessageType.USER_MESSAGE)) {
sResponseMessageID = MessageHelperMethods.createRandomMessageID();
final AS4UserMessage aResponseUserMsg = _createReversedUserMessage(eSoapVersion, sResponseMessageID, aEbmsUserMessage, aResponseAttachments);
final AS4SigningParams aSigningParams = new AS4SigningParams().setFromPMode(aLeg2.getSecurity());
final String sEncryptionAlias = aEbmsUserMessage.getPartyInfo().getTo().getPartyIdAtIndex(0).getValue();
final AS4CryptParams aCryptParams = new AS4CryptParams().setFromPMode(aLeg2.getSecurity()).setAlias(sEncryptionAlias);
ret = _createResponseUserMessage(aState, aLeg2.getProtocol().getSoapVersion(), aResponseUserMsg, aResponseAttachments, aSigningParams, aCryptParams);
} else {
sResponseMessageID = null;
ret = null;
}
}
} else {
sResponseMessageID = null;
ret = null;
}
}
} else {
sResponseMessageID = null;
ret = null;
}
// Create the HttpEntity on demand
_invokeSPIsForResponse(aState, ret, null, eSoapVersion.getMimeType(), sResponseMessageID);
return ret;
}
use of com.helger.phase4.ebms3header.Ebms3Error in project phase4 by phax.
the class AS4IncomingHandler method _processSoapHeaderElements.
private static void _processSoapHeaderElements(@Nonnull final SOAPHeaderElementProcessorRegistry aRegistry, @Nonnull final Document aSoapDocument, @Nonnull final ICommonsList<WSS4JAttachment> aIncomingAttachments, @Nonnull final AS4MessageState aState, @Nonnull final ICommonsList<Ebms3Error> aErrorMessages) throws Phase4Exception {
final ESoapVersion eSoapVersion = aState.getSoapVersion();
final ICommonsList<AS4SingleSOAPHeader> aHeaders = new CommonsArrayList<>();
{
// Find SOAP header
final Node aHeaderNode = XMLHelper.getFirstChildElementOfName(aSoapDocument.getDocumentElement(), eSoapVersion.getNamespaceURI(), eSoapVersion.getHeaderElementName());
if (aHeaderNode == null)
throw new Phase4Exception("SOAP document is missing a Header element {" + eSoapVersion.getNamespaceURI() + "}" + eSoapVersion.getHeaderElementName());
// Extract all header elements including their "mustUnderstand" value
for (final Element aHeaderChild : new ChildElementIterator(aHeaderNode)) {
final QName aQName = XMLHelper.getQName(aHeaderChild);
final String sMustUnderstand = aHeaderChild.getAttributeNS(eSoapVersion.getNamespaceURI(), "mustUnderstand");
final boolean bIsMustUnderstand = eSoapVersion.getMustUnderstandValue(true).equals(sMustUnderstand);
aHeaders.add(new AS4SingleSOAPHeader(aHeaderChild, aQName, bIsMustUnderstand));
}
}
final ICommonsOrderedMap<QName, ISOAPHeaderElementProcessor> aAllProcessors = aRegistry.getAllElementProcessors();
if (aAllProcessors.isEmpty())
LOGGER.error("No SOAP Header element processor is registered");
// handle all headers in the order of the registered handlers!
for (final Map.Entry<QName, ISOAPHeaderElementProcessor> aEntry : aAllProcessors.entrySet()) {
final QName aQName = aEntry.getKey();
// Check if this message contains a header for the current handler
final AS4SingleSOAPHeader aHeader = aHeaders.findFirst(x -> aQName.equals(x.getQName()));
if (aHeader == null) {
// no header element for current processor
if (LOGGER.isDebugEnabled())
LOGGER.debug("Message contains no SOAP header element with QName " + aQName.toString());
continue;
}
final ISOAPHeaderElementProcessor aProcessor = aEntry.getValue();
if (LOGGER.isDebugEnabled())
LOGGER.debug("Processing SOAP header element " + aQName.toString() + " with processor " + aProcessor);
// Error list for this processor
final ErrorList aErrorList = new ErrorList();
try {
// Process element
if (aProcessor.processHeaderElement(aSoapDocument, aHeader.getNode(), aIncomingAttachments, aState, aErrorList).isSuccess()) {
// Mark header as processed (for mustUnderstand check)
aHeader.setProcessed(true);
} else {
// upon failure, the element stays unprocessed and sends back a signal
// message with the errors
LOGGER.error("Failed to process SOAP header element " + aQName.toString() + " with processor " + aProcessor + "; error details: " + aErrorList);
final String sRefToMessageID = aState.getMessageID();
final Locale aLocale = aState.getLocale();
for (final IError aError : aErrorList) {
final EEbmsError ePredefinedError = EEbmsError.getFromErrorCodeOrNull(aError.getErrorID());
if (ePredefinedError != null)
aErrorMessages.add(ePredefinedError.getAsEbms3Error(aLocale, sRefToMessageID));
else {
final Ebms3Error aEbms3Error = new Ebms3Error();
aEbms3Error.setErrorDetail(aError.getErrorText(aLocale));
aEbms3Error.setErrorCode(aError.getErrorID());
aEbms3Error.setSeverity(aError.getErrorLevel().getID());
aEbms3Error.setOrigin(aError.getErrorFieldName());
aEbms3Error.setRefToMessageInError(sRefToMessageID);
aErrorMessages.add(aEbms3Error);
}
}
// Stop processing of other headers
break;
}
} catch (final Exception ex) {
// upon failure, the element stays unprocessed and sends back a signal
// message with the errors
LOGGER.error("Error processing SOAP header element " + aQName.toString() + " with processor " + aProcessor, ex);
aErrorMessages.add(EEbmsError.EBMS_OTHER.getAsEbms3Error(aState.getLocale(), aState.getMessageID(), "Error processing SOAP header element " + aQName.toString()));
// Stop processing of other headers
break;
}
}
// If an error message is present, send it back gracefully
if (aErrorMessages.isEmpty()) {
// Are all must-understand headers processed?
for (final AS4SingleSOAPHeader aHeader : aHeaders) if (aHeader.isMustUnderstand() && !aHeader.isProcessed())
throw new Phase4Exception("Required SOAP header element " + aHeader.getQName().toString() + " could not be handled");
}
}
Aggregations