From 8018c6bab71831171f2e99e41d3adde95f19a567 Mon Sep 17 00:00:00 2001 From: Philip Helger Date: Thu, 24 Oct 2024 21:49:20 +0200 Subject: [PATCH] Improved IncomingProfileSelector handling --- .../com/helger/phase4/dump/AS4DumpReader.java | 2 + .../AS4IncomingProfileSelectorConstant.java | 68 +++++++++++++++++++ .../AS4IncomingProfileSelectorFromGlobal.java | 36 ++++++++-- .../phase4/incoming/AS4RequestHandler.java | 6 +- .../incoming/IAS4IncomingProfileSelector.java | 6 +- .../sender/AbstractAS4MessageBuilder.java | 13 ++-- .../phase4/servlet/AS4XServletHandler.java | 8 ++- .../springboot/servlet/ServletConfig.java | 18 ++--- 8 files changed, 128 insertions(+), 29 deletions(-) create mode 100644 phase4-lib/src/main/java/com/helger/phase4/incoming/AS4IncomingProfileSelectorConstant.java diff --git a/phase4-lib/src/main/java/com/helger/phase4/dump/AS4DumpReader.java b/phase4-lib/src/main/java/com/helger/phase4/dump/AS4DumpReader.java index 8e9fb2fcf..499010dfa 100644 --- a/phase4-lib/src/main/java/com/helger/phase4/dump/AS4DumpReader.java +++ b/phase4-lib/src/main/java/com/helger/phase4/dump/AS4DumpReader.java @@ -49,6 +49,7 @@ import com.helger.phase4.ebms3header.Ebms3SignalMessage; import com.helger.phase4.ebms3header.Ebms3UserMessage; import com.helger.phase4.incoming.AS4IncomingMessageMetadata; +import com.helger.phase4.incoming.AS4IncomingProfileSelectorConstant; import com.helger.phase4.incoming.AS4IncomingReceiverConfiguration; import com.helger.phase4.incoming.AS4RequestHandler; import com.helger.phase4.incoming.IAS4IncomingMessageMetadata; @@ -235,6 +236,7 @@ public static void decryptAS4In (@Nonnull @Nonempty final String sAS4ProfileID, aHandler.setCryptoFactorySign (aCryptoFactorySign); aHandler.setCryptoFactoryCrypt (aCryptoFactoryCrypt); aHandler.setPModeResolver (new AS4DefaultPModeResolver (sAS4ProfileID)); + aHandler.setIncomingProfileSelector (new AS4IncomingProfileSelectorConstant (sAS4ProfileID)); aHandler.setIncomingAttachmentFactory (IAS4IncomingAttachmentFactory.DEFAULT_INSTANCE); aHandler.setIncomingSecurityConfiguration (AS4IncomingSecurityConfiguration.createDefaultInstance ()); aHandler.setIncomingReceiverConfiguration (new AS4IncomingReceiverConfiguration ()); diff --git a/phase4-lib/src/main/java/com/helger/phase4/incoming/AS4IncomingProfileSelectorConstant.java b/phase4-lib/src/main/java/com/helger/phase4/incoming/AS4IncomingProfileSelectorConstant.java new file mode 100644 index 000000000..7ffef673f --- /dev/null +++ b/phase4-lib/src/main/java/com/helger/phase4/incoming/AS4IncomingProfileSelectorConstant.java @@ -0,0 +1,68 @@ +/* + * Copyright (C) 2015-2024 Philip Helger (www.helger.com) + * philip[at]helger[dot]com + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.helger.phase4.incoming; + +import javax.annotation.Nonnull; +import javax.annotation.Nullable; +import javax.annotation.concurrent.Immutable; + +import com.helger.commons.string.ToStringGenerator; + +/** + * Implementation of {@link IAS4IncomingProfileSelector} taking a constant AS4 + * profile ID. + * + * @author Philip Helger + * @since 3.0.0 + */ +@Immutable +public class AS4IncomingProfileSelectorConstant implements IAS4IncomingProfileSelector +{ + private final String m_sAS4ProfileID; + private final boolean m_bValidateAgainstProfile; + + public AS4IncomingProfileSelectorConstant (@Nullable final String sAS4ProfileID) + { + this (sAS4ProfileID, DEFAULT_VALIDATE_AGAINST_PROFILE); + } + + public AS4IncomingProfileSelectorConstant (@Nullable final String sAS4ProfileID, + final boolean bValidateAgainstProfile) + { + m_sAS4ProfileID = sAS4ProfileID; + m_bValidateAgainstProfile = bValidateAgainstProfile; + } + + @Nullable + public String getAS4ProfileID (@Nonnull final IAS4IncomingMessageState aIncomingState) + { + return m_sAS4ProfileID; + } + + public boolean validateAgainstProfile () + { + return m_bValidateAgainstProfile; + } + + @Override + public String toString () + { + return new ToStringGenerator (null).append ("AS4ProfileID", m_sAS4ProfileID) + .append ("ValidateAgainstProfile", m_bValidateAgainstProfile) + .getToString (); + } +} diff --git a/phase4-lib/src/main/java/com/helger/phase4/incoming/AS4IncomingProfileSelectorFromGlobal.java b/phase4-lib/src/main/java/com/helger/phase4/incoming/AS4IncomingProfileSelectorFromGlobal.java index 28629854a..e3f99a933 100644 --- a/phase4-lib/src/main/java/com/helger/phase4/incoming/AS4IncomingProfileSelectorFromGlobal.java +++ b/phase4-lib/src/main/java/com/helger/phase4/incoming/AS4IncomingProfileSelectorFromGlobal.java @@ -19,21 +19,43 @@ import javax.annotation.Nonnull; import javax.annotation.Nullable; +import com.helger.commons.string.ToStringGenerator; import com.helger.phase4.incoming.mgr.AS4ProfileSelector; -import com.helger.phase4.v3.ChangePhase4V3; /** * Default implementation of {@link IAS4IncomingProfileSelector} taking the AS4 - * profile ID from {@link AS4ProfileSelector}. + * profile ID from the global {@link AS4ProfileSelector}. * * @author Philip Helger * @since 0.13.0 */ -@ChangePhase4V3 ("Find a better solution for this") public class AS4IncomingProfileSelectorFromGlobal implements IAS4IncomingProfileSelector { public static final AS4IncomingProfileSelectorFromGlobal INSTANCE = new AS4IncomingProfileSelectorFromGlobal (); + private final boolean m_bValidateAgainstProfile; + + /** + * Default constructor with validation enabled + */ + public AS4IncomingProfileSelectorFromGlobal () + { + this (DEFAULT_VALIDATE_AGAINST_PROFILE); + } + + /** + * Constructor + * + * @param bValidateAgainstProfile + * true to enable validation, false to + * disable validation against the profile + * @since 3.0.0 + */ + public AS4IncomingProfileSelectorFromGlobal (final boolean bValidateAgainstProfile) + { + m_bValidateAgainstProfile = bValidateAgainstProfile; + } + @Nullable public String getAS4ProfileID (@Nonnull final IAS4IncomingMessageState aIncomingState) { @@ -42,6 +64,12 @@ public String getAS4ProfileID (@Nonnull final IAS4IncomingMessageState aIncoming public boolean validateAgainstProfile () { - return true; + return m_bValidateAgainstProfile; + } + + @Override + public String toString () + { + return new ToStringGenerator (this).append ("ValidateAgainstProfile", m_bValidateAgainstProfile).getToString (); } } diff --git a/phase4-lib/src/main/java/com/helger/phase4/incoming/AS4RequestHandler.java b/phase4-lib/src/main/java/com/helger/phase4/incoming/AS4RequestHandler.java index 290887efe..10b8fa2cd 100644 --- a/phase4-lib/src/main/java/com/helger/phase4/incoming/AS4RequestHandler.java +++ b/phase4-lib/src/main/java/com/helger/phase4/incoming/AS4RequestHandler.java @@ -355,7 +355,7 @@ public boolean hasAsyncResponseURL () private IAS4IncomingAttachmentFactory m_aIncomingAttachmentFactory; private IAS4IncomingSecurityConfiguration m_aIncomingSecurityConfig; private IAS4IncomingReceiverConfiguration m_aIncomingReceiverConfig; - private IAS4IncomingProfileSelector m_aIncomingProfileSelector = AS4IncomingProfileSelectorFromGlobal.INSTANCE; + private IAS4IncomingProfileSelector m_aIncomingProfileSelector; private Locale m_aLocale = Locale.US; private IAS4IncomingDumper m_aIncomingDumper; private IAS4OutgoingDumper m_aOutgoingDumper; @@ -469,8 +469,8 @@ public final AS4RequestHandler setCryptoFactory (@Nonnull final IAS4CryptoFactor } /** - * @return The {@link IAS4PModeResolver} to be used. May be null if - * not initialized. + * @return The {@link IAS4PModeResolver} to be used. May be null + * if not initialized. * @since 3.0.0 */ @Nullable diff --git a/phase4-lib/src/main/java/com/helger/phase4/incoming/IAS4IncomingProfileSelector.java b/phase4-lib/src/main/java/com/helger/phase4/incoming/IAS4IncomingProfileSelector.java index fd1ee64da..01a5b9078 100644 --- a/phase4-lib/src/main/java/com/helger/phase4/incoming/IAS4IncomingProfileSelector.java +++ b/phase4-lib/src/main/java/com/helger/phase4/incoming/IAS4IncomingProfileSelector.java @@ -19,17 +19,16 @@ import javax.annotation.Nonnull; import javax.annotation.Nullable; -import com.helger.phase4.v3.ChangePhase4V3; - /** * Callback interface to determine the used AS4 profile of an incoming message. * * @author Philip Helger * @since 0.13.0 */ -@ChangePhase4V3 ("As the AS4 profile ID is part of the sending process, reuse it for receiving") public interface IAS4IncomingProfileSelector { + boolean DEFAULT_VALIDATE_AGAINST_PROFILE = true; + /** * Try to determine the AS4 profile to be used for an incoming message. This * method is only called after the SOAP headers were processed successfully. @@ -38,7 +37,6 @@ public interface IAS4IncomingProfileSelector * The message state of processing. Never null. * @return The AS4 profile ID or null if none was found. */ - // TODO remove? @Nullable String getAS4ProfileID (@Nonnull IAS4IncomingMessageState aIncomingState); diff --git a/phase4-lib/src/main/java/com/helger/phase4/sender/AbstractAS4MessageBuilder.java b/phase4-lib/src/main/java/com/helger/phase4/sender/AbstractAS4MessageBuilder.java index f80456d71..1147fd540 100644 --- a/phase4-lib/src/main/java/com/helger/phase4/sender/AbstractAS4MessageBuilder.java +++ b/phase4-lib/src/main/java/com/helger/phase4/sender/AbstractAS4MessageBuilder.java @@ -46,7 +46,7 @@ import com.helger.phase4.crypto.IAS4DecryptParameterModifier; import com.helger.phase4.dump.IAS4IncomingDumper; import com.helger.phase4.dump.IAS4OutgoingDumper; -import com.helger.phase4.incoming.AS4IncomingProfileSelectorFromGlobal; +import com.helger.phase4.incoming.AS4IncomingProfileSelectorConstant; import com.helger.phase4.incoming.IAS4IncomingProfileSelector; import com.helger.phase4.messaging.http.HttpRetrySettings; import com.helger.phase4.messaging.http.IHttpPoster; @@ -104,7 +104,6 @@ public abstract class AbstractAS4MessageBuilder * {@link #soapVersion(ESoapVersion)} * {@link #incomingAttachmentFactory(IAS4IncomingAttachmentFactory)}
- * {@link #incomingProfileSelector(IAS4IncomingProfileSelector)}
*/ protected AbstractAS4MessageBuilder () { @@ -116,7 +115,6 @@ protected AbstractAS4MessageBuilder () cryptoFactory (AS4CryptoFactoryConfiguration.getDefaultInstance ()); soapVersion (ESoapVersion.SOAP_12); incomingAttachmentFactory (IAS4IncomingAttachmentFactory.DEFAULT_INSTANCE); - incomingProfileSelector (AS4IncomingProfileSelectorFromGlobal.INSTANCE); } catch (final Exception ex) { @@ -841,8 +839,13 @@ public final IMPLTYPE rawResponseConsumer (@Nullable final IAS4RawResponseConsum @OverridingMethodsMustInvokeSuper protected ESuccess finishFields () throws Phase4Exception { - if (m_aPModeResolver == null && StringHelper.hasText (m_sAS4ProfileID)) - pmodeResolver (new AS4DefaultPModeResolver (m_sAS4ProfileID)); + if (StringHelper.hasText (m_sAS4ProfileID)) + { + if (m_aPModeResolver == null) + pmodeResolver (new AS4DefaultPModeResolver (m_sAS4ProfileID)); + if (m_aIncomingProfileSelector == null) + incomingProfileSelector (new AS4IncomingProfileSelectorConstant (m_sAS4ProfileID)); + } return ESuccess.SUCCESS; } diff --git a/phase4-lib/src/main/java/com/helger/phase4/servlet/AS4XServletHandler.java b/phase4-lib/src/main/java/com/helger/phase4/servlet/AS4XServletHandler.java index 83fb3484d..b6030b505 100644 --- a/phase4-lib/src/main/java/com/helger/phase4/servlet/AS4XServletHandler.java +++ b/phase4-lib/src/main/java/com/helger/phase4/servlet/AS4XServletHandler.java @@ -35,6 +35,7 @@ import com.helger.phase4.attachment.IAS4IncomingAttachmentFactory; import com.helger.phase4.crypto.AS4CryptoFactoryConfiguration; import com.helger.phase4.incoming.AS4IncomingMessageMetadata; +import com.helger.phase4.incoming.AS4IncomingProfileSelectorConstant; import com.helger.phase4.incoming.AS4IncomingReceiverConfiguration; import com.helger.phase4.incoming.AS4RequestHandler; import com.helger.phase4.incoming.IAS4IncomingMessageMetadata; @@ -205,10 +206,13 @@ protected void handleRequest (@Nonnull final IRequestWebScopeWithoutResponse aRe try (final AS4RequestHandler aHandler = new AS4RequestHandler (aMessageMetadata)) { + // No specific AS4 profile is available here + final String sAS4ProfileID = AS4ProfileSelector.getDefaultAS4ProfileID (); + // Set default values in handler aHandler.setCryptoFactory (AS4CryptoFactoryConfiguration.getDefaultInstance ()); - // No specific AS4 profile is available here - aHandler.setPModeResolver (new AS4DefaultPModeResolver (AS4ProfileSelector.getDefaultAS4ProfileID ())); + aHandler.setPModeResolver (new AS4DefaultPModeResolver (sAS4ProfileID)); + aHandler.setIncomingProfileSelector (new AS4IncomingProfileSelectorConstant (sAS4ProfileID, true)); aHandler.setIncomingAttachmentFactory (IAS4IncomingAttachmentFactory.DEFAULT_INSTANCE); aHandler.setIncomingSecurityConfiguration (AS4IncomingSecurityConfiguration.createDefaultInstance ()); aHandler.setIncomingReceiverConfiguration (new AS4IncomingReceiverConfiguration ()); diff --git a/phase4-spring-boot-demo/src/main/java/com/helger/phase4/springboot/servlet/ServletConfig.java b/phase4-spring-boot-demo/src/main/java/com/helger/phase4/springboot/servlet/ServletConfig.java index 286be15b8..c50a362f7 100644 --- a/phase4-spring-boot-demo/src/main/java/com/helger/phase4/springboot/servlet/ServletConfig.java +++ b/phase4-spring-boot-demo/src/main/java/com/helger/phase4/springboot/servlet/ServletConfig.java @@ -42,7 +42,7 @@ import com.helger.phase4.config.AS4Configuration; import com.helger.phase4.crypto.AS4CryptoFactoryConfiguration; import com.helger.phase4.crypto.IAS4CryptoFactory; -import com.helger.phase4.incoming.AS4IncomingProfileSelectorFromGlobal; +import com.helger.phase4.incoming.AS4IncomingProfileSelectorConstant; import com.helger.phase4.incoming.AS4RequestHandler; import com.helger.phase4.incoming.AS4ServerInitializer; import com.helger.phase4.incoming.mgr.AS4ProfileSelector; @@ -106,15 +106,9 @@ public void customizeBeforeHandling (@Nonnull final IRequestWebScopeWithoutRespo // Example code to disable PMode validation if (false) { - aRequestHandler.setIncomingProfileSelector (new AS4IncomingProfileSelectorFromGlobal () - { - @Override - public boolean validateAgainstProfile () - { - // override; - return false; - } - }); + // Note: API is for 3.0.0 only + aRequestHandler.setIncomingProfileSelector (new AS4IncomingProfileSelectorConstant (AS4PeppolProfileRegistarSPI.AS4_PROFILE_ID, + false)); } // Example for changing the Peppol receiver data based on the source @@ -156,7 +150,9 @@ public boolean validateAgainstProfile () public void customizeAfterHandling (@Nonnull final IRequestWebScopeWithoutResponse aRequestScope, @Nonnull final AS4UnifiedResponse aUnifiedResponse, @Nonnull final AS4RequestHandler aRequestHandler) - {} + { + // empty + } }); // HTTP POST only