use of com.helger.phase4.util.Phase4Exception in project phase4 by phax.
the class AS4IncomingHandler method parseSignalMessage.
@Nullable
public static Ebms3SignalMessage parseSignalMessage(@Nonnull final IAS4CryptoFactory aCryptoFactory, @Nonnull final IPModeResolver aPModeResolver, @Nonnull final IAS4IncomingAttachmentFactory aIAF, @Nonnull final IAS4IncomingProfileSelector aAS4ProfileSelector, @Nonnull @WillNotClose final AS4ResourceHelper aResHelper, @Nullable final IPMode aSendingPMode, @Nonnull final Locale aLocale, @Nonnull final IAS4IncomingMessageMetadata aMessageMetadata, @Nonnull final HttpResponse aHttpResponse, @Nonnull final byte[] aResponsePayload, @Nullable final IAS4IncomingDumper aIncomingDumper) throws Phase4Exception {
final IAS4MessageState aState = _parseMessage(aCryptoFactory, aPModeResolver, aIAF, aAS4ProfileSelector, aResHelper, aSendingPMode, aLocale, aMessageMetadata, aHttpResponse, aResponsePayload, aIncomingDumper);
if (aState == null) {
// Error message was already logged
return null;
}
final Ebms3SignalMessage ret = aState.getEbmsSignalMessage();
if (ret == null) {
if (aState.getEbmsUserMessage() != null)
LOGGER.warn("A Message state is present, but it contains a UserMessage instead of a SignalMessage.");
else
LOGGER.warn("A Message state is present, but it contains neither a UserMessage nor a SignalMessage.");
}
return ret;
}
use of com.helger.phase4.util.Phase4Exception 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");
}
use of com.helger.phase4.util.Phase4Exception in project phase4 by phax.
the class AS4BidirectionalClientHelper method sendAS4UserMessageAndReceiveAS4SignalMessage.
public static void sendAS4UserMessageAndReceiveAS4SignalMessage(@Nonnull final IAS4CryptoFactory aCryptoFactory, @Nonnull final IPModeResolver aPModeResolver, @Nonnull final IAS4IncomingAttachmentFactory aIAF, @Nonnull final IAS4IncomingProfileSelector aIncomingProfileSelector, @Nonnull final AS4ClientUserMessage aClientUserMsg, @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 IAS4SignalMessageConsumer aSignalMsgConsumer) throws IOException, Phase4Exception, WSSecurityException, MessagingException {
if (LOGGER.isInfoEnabled())
LOGGER.info("Sending AS4 UserMessage to '" + sURL + "' with max. " + aClientUserMsg.httpRetrySettings().getMaxRetries() + " retries");
if (LOGGER.isDebugEnabled()) {
LOGGER.debug(" ServiceType = '" + aClientUserMsg.getServiceType() + "'");
LOGGER.debug(" Service = '" + aClientUserMsg.getServiceValue() + "'");
LOGGER.debug(" Action = '" + aClientUserMsg.getAction() + "'");
LOGGER.debug(" ConversationId = '" + aClientUserMsg.getConversationID() + "'");
LOGGER.debug(" MessageProperties:");
for (final Ebms3Property p : aClientUserMsg.ebms3Properties()) LOGGER.debug(" [" + p.getName() + "] = [" + p.getValue() + "]");
LOGGER.debug(" Attachments (" + aClientUserMsg.attachments().size() + "):");
for (final WSS4JAttachment a : aClientUserMsg.attachments()) {
LOGGER.debug(" [" + a.getId() + "] with [" + a.getMimeType() + "] and [" + a.getCharsetOrDefault(null) + "] and [" + a.getCompressionMode() + "] and [" + a.getContentTransferEncoding() + "]");
}
}
final Wrapper<HttpResponse> aWrappedResponse = new Wrapper<>();
final ResponseHandler<byte[]> aResponseHdl = aHttpResponse -> {
// throws an ExtendedHttpResponseException on exception
final HttpEntity aEntity = ResponseHandlerHttpEntity.INSTANCE.handleResponse(aHttpResponse);
if (aEntity == null)
return null;
aWrappedResponse.set(aHttpResponse);
return EntityUtils.toByteArray(aEntity);
};
final AS4ClientSentMessage<byte[]> aResponseEntity = aClientUserMsg.sendMessageWithRetries(sURL, aResponseHdl, aBuildMessageCallback, aOutgoingDumper, aRetryCallback);
if (LOGGER.isInfoEnabled())
LOGGER.info("Successfully transmitted AS4 UserMessage 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 Signal Message
// Read it in any case to ensure signature validation etc. happens
final Ebms3SignalMessage aSignalMessage = AS4IncomingHandler.parseSignalMessage(aCryptoFactory, aPModeResolver, aIAF, aIncomingProfileSelector, aClientUserMsg.getAS4ResourceHelper(), aClientUserMsg.getPMode(), aLocale, aMessageMetadata, aWrappedResponse.get(), aResponseEntity.getResponse(), aIncomingDumper);
if (aSignalMessage != null && aSignalMsgConsumer != null)
aSignalMsgConsumer.handleSignalMessage(aSignalMessage);
} else
LOGGER.info("AS4 ResponseEntity is empty");
}
use of com.helger.phase4.util.Phase4Exception in project phase4 by phax.
the class AS4DumpReader method decryptAS4In.
/**
* Utility method to decrypt dumped .as4in message late.<br>
* Note: this method was mainly created for internal use and does not win the
* prize for the most sexy piece of software in the world ;-)
*
* @param aAS4InData
* The byte array with the dumped data.
* @param aCF
* The Crypto factory to be used. This crypto factory must use use the
* private key that can be used to decrypt this particular message. May
* not be <code>null</code>.
* @param aHttpHeaderConsumer
* An optional HTTP Header map consumer. May be <code>null</code>.
* @param aDecryptedConsumer
* The consumer for the decrypted payload - whatever that is :). May
* not be <code>null</code>.
* @throws WSSecurityException
* In case of error
* @throws Phase4Exception
* In case of error
* @throws IOException
* In case of error
* @throws MessagingException
* In case of error
*/
public static void decryptAS4In(@Nonnull final byte[] aAS4InData, final IAS4CryptoFactory aCF, @Nullable final Consumer<HttpHeaderMap> aHttpHeaderConsumer, @Nonnull final Consumer<byte[]> aDecryptedConsumer) throws WSSecurityException, Phase4Exception, IOException, MessagingException {
final HttpHeaderMap hm = new HttpHeaderMap();
int nHttpStart = 0;
int nHttpEnd = -1;
boolean bLastWasCR = false;
for (int i = 0; i < aAS4InData.length; ++i) {
final byte b = aAS4InData[i];
if (b == '\n') {
if (bLastWasCR) {
nHttpEnd = i;
break;
}
bLastWasCR = true;
final String sLine = new String(aAS4InData, nHttpStart, i - nHttpStart, StandardCharsets.ISO_8859_1);
final String[] aParts = StringHelper.getExplodedArray(':', sLine, 2);
hm.addHeader(aParts[0].trim(), aParts[1].trim());
nHttpStart = i + 1;
} else {
if (b != '\r')
bLastWasCR = false;
}
}
if (aHttpHeaderConsumer != null)
aHttpHeaderConsumer.accept(hm);
LOGGER.info("Now at byte " + nHttpEnd + " having " + hm.getCount() + " HTTP headers");
WebScopeManager.onGlobalBegin(MockServletContext.create());
try (final WebScoped w = new WebScoped();
final AS4RequestHandler rh = new AS4RequestHandler(aCF, DefaultPModeResolver.DEFAULT_PMODE_RESOLVER, IAS4IncomingAttachmentFactory.DEFAULT_INSTANCE, new AS4IncomingMessageMetadata(EAS4MessageMode.REQUEST))) {
final IAS4ServletMessageProcessorSPI aSPI = new IAS4ServletMessageProcessorSPI() {
public AS4MessageProcessorResult processAS4UserMessage(final IAS4IncomingMessageMetadata aMessageMetadata, final HttpHeaderMap aHttpHeaders, final Ebms3UserMessage aUserMessage, final IPMode aPMode, final Node aPayload, final ICommonsList<WSS4JAttachment> aIncomingAttachments, final IAS4MessageState aState, final ICommonsList<Ebms3Error> aProcessingErrorMessages) {
try {
final byte[] aDecryptedBytes = StreamHelper.getAllBytes(aIncomingAttachments.getFirst().getInputStreamProvider());
aDecryptedConsumer.accept(aDecryptedBytes);
LOGGER.info("Handled decrypted payload with " + aDecryptedBytes.length + " bytes");
return AS4MessageProcessorResult.createSuccess();
} catch (final Exception ex) {
throw new IllegalStateException(ex);
}
}
public AS4SignalMessageProcessorResult processAS4SignalMessage(final IAS4IncomingMessageMetadata aMessageMetadata, final HttpHeaderMap aHttpHeaders, final Ebms3SignalMessage aSignalMessage, final IPMode aPMode, final IAS4MessageState aState, final ICommonsList<Ebms3Error> aProcessingErrorMessages) {
LOGGER.error("Unexpected signal msg");
return AS4SignalMessageProcessorResult.createSuccess();
}
};
rh.setProcessorSupplier(() -> new CommonsArrayList<>(aSPI));
rh.handleRequest(new NonBlockingByteArrayInputStream(aAS4InData, nHttpEnd, aAS4InData.length - nHttpEnd), hm, new IAS4ResponseAbstraction() {
public void setStatus(final int nStatusCode) {
}
public void setMimeType(final IMimeType aMimeType) {
}
public void setContent(final HttpHeaderMap aHeaderMap, final IHasInputStream aHasIS) {
}
public void setContent(final byte[] aResultBytes, final Charset aCharset) {
}
});
} finally {
WebScopeManager.onGlobalEnd();
}
}
use of com.helger.phase4.util.Phase4Exception in project phase4 by phax.
the class AS4RawResponseConsumerWriteToFile method handleResponse.
public void handleResponse(@Nonnull final AS4ClientSentMessage<byte[]> aResponseEntity) throws Phase4Exception {
final boolean bUseStatusLine = isHandleStatusLine() && aResponseEntity.hasResponseStatusLine();
final boolean bUseHttpHeaders = isHandleHttpHeaders() && aResponseEntity.getResponseHeaders().isNotEmpty();
final boolean bUseBody = aResponseEntity.hasResponse() && aResponseEntity.getResponse().length > 0;
if (bUseStatusLine || bUseHttpHeaders || bUseBody) {
final String sSentMessageID = aResponseEntity.getMessageID();
// Use the configured data path as the base
final File aResponseFile = m_aFileProvider.createFile(sSentMessageID);
if (LOGGER.isInfoEnabled())
LOGGER.info("Logging AS4 response to '" + aResponseFile.getAbsolutePath() + "'");
try (final OutputStream aOS = FileHelper.getBufferedOutputStream(aResponseFile)) {
if (bUseStatusLine) {
// Write the status line
aOS.write(aResponseEntity.getResponseStatusLine().toString().getBytes(CHttp.HTTP_CHARSET));
}
if (bUseHttpHeaders) {
// Write the response headers
for (final Map.Entry<String, ICommonsList<String>> aEntry : aResponseEntity.getResponseHeaders()) {
final String sHeader = aEntry.getKey();
for (final String sValue : aEntry.getValue()) {
// By default quoting is disabled
final boolean bQuoteIfNecessary = false;
final String sUnifiedValue = HttpHeaderMap.getUnifiedValue(sValue, bQuoteIfNecessary);
aOS.write((sHeader + HttpHeaderMap.SEPARATOR_KEY_VALUE + sUnifiedValue + CHttp.EOL).getBytes(CHttp.HTTP_CHARSET));
}
}
}
if ((bUseStatusLine || bUseHttpHeaders) && bUseBody) {
// Separator line
aOS.write(CHttp.EOL.getBytes(CHttp.HTTP_CHARSET));
}
if (bUseBody) {
// Write the main content
aOS.write(aResponseEntity.getResponse());
}
} catch (final IOException ex) {
throw new Phase4Exception("Error writing AS4 response file to '" + aResponseFile.getAbsolutePath() + "'", ex);
}
}
}
Aggregations