Skip to main content
Package: com.helger.phase4.dynamicdiscovery
Maven artifact: com.helger.phase4:phase4-dynamic-discovery
Endpoint detail providers decouple AS4 senders from how the receiver’s certificate and endpoint URL are resolved. This can be a live SMP lookup or a hard-coded test endpoint.

IAS4EndpointDetailProvider

Base interface. All providers implement these three methods:
// Called before getReceiverAPCertificate() and getReceiverAPEndpointURL().
// May be called multiple times; implementations should cache results.
void init(
    IDocumentTypeIdentifier aDocTypeID,
    IProcessIdentifier aProcID,
    IParticipantIdentifier aReceiverID
) throws Phase4Exception;

// The receiver's AS4 AP X.509 certificate. May be null.
@Nullable X509Certificate getReceiverAPCertificate() throws Phase4Exception;

// The receiver's AS4 endpoint URL. Never null or empty.
@NonNull String getReceiverAPEndpointURL() throws Phase4Exception;

// The technical contact from the SMP registration. May be null or empty. Since 3.2.0.
@Nullable String getReceiverTechnicalContact() throws Phase4Exception;

AS4EndpointDetailProviderConstant

Provides fixed (pre-known) endpoint details. Useful for testing or when endpoint information is obtained by means other than SMP.

Constructors

new AS4EndpointDetailProviderConstant(
    X509Certificate aReceiverCert,  // nullable
    String sDestURL                 // required, non-empty
)

new AS4EndpointDetailProviderConstant(
    X509Certificate aReceiverCert,  // nullable
    String sDestURL,                // required, non-empty
    String sTechnicalContact        // nullable
)
body.aReceiverCert
X509Certificate
The receiver’s AP certificate used for encryption. May be null if encryption is not required.
body.sDestURL
String
required
The AS4 endpoint URL of the receiver. Must be non-empty.
body.sTechnicalContact
String
Optional technical contact information.
init() is a no-op for this implementation.

Example

IAS4EndpointDetailProvider provider = new AS4EndpointDetailProviderConstant(
    receiverX509Cert,
    "https://receiver.example.com/as4"
);

AS4EndpointDetailProviderPeppol

Looks up endpoint details from a Peppol SMP using the SMP client API. Since 0.10.6.

Constructors

new AS4EndpointDetailProviderPeppol(
    ISMPServiceGroupProvider aServiceGroupProvider,
    ISMPExtendedServiceMetadataProvider aServiceMetadataProvider
)
// Convenience factory when both providers are the same SMPClientReadOnly instance
AS4EndpointDetailProviderPeppol.create(SMPClientReadOnly aSMPClient)
body.aServiceGroupProvider
ISMPServiceGroupProvider
required
Provides SMP service group information.
body.aServiceMetadataProvider
ISMPExtendedServiceMetadataProvider
required
Resolves SMP service metadata for a given participant and document type.

Configuration

body.setTransportProfile
ISMPTransportProfile
Override the transport profile used to select the endpoint from the SMP result. Default: ESMPTransportProfile.TRANSPORT_PROFILE_PEPPOL_AS4_V2.

Getters

ISMPServiceGroupProvider sgp = provider.getServiceGroupProvider();
ISMPServiceMetadataProvider smp = provider.getServiceMetadataProvider();
ISMPTransportProfile tp         = provider.getTransportProfile();
EndpointType endpoint           = provider.getEndpoint(); // non-null after init()

Example

import com.helger.phase4.dynamicdiscovery.AS4EndpointDetailProviderPeppol;
import com.helger.smpclient.peppol.SMPClientReadOnly;
import com.helger.smpclient.url.PeppolNaptrURLProvider;

SMPClientReadOnly smpClient = new SMPClientReadOnly(
    PeppolNaptrURLProvider.INSTANCE,
    receiverParticipantID,
    ESML.DIGIT_PRODUCTION
);

IAS4EndpointDetailProvider provider = AS4EndpointDetailProviderPeppol.create(smpClient);

AS4EndpointDetailProviderBDXR

Looks up endpoint details from an OASIS BDXR SMP v1 server. Since 0.10.6.

Constructor

new AS4EndpointDetailProviderBDXR(
    IBDXRExtendedServiceMetadataProvider aSMPClient // required
)
body.aSMPClient
IBDXRExtendedServiceMetadataProvider
required
OASIS BDXR SMP v1 client instance.

Configuration

body.setTransportProfile
ISMPTransportProfile
Transport profile for endpoint selection. Default: ESMPTransportProfile.TRANSPORT_PROFILE_BDXR_AS4.

Getters

IBDXRExtendedServiceMetadataProvider client = provider.getServiceMetadataProvider();
ISMPTransportProfile tp                     = provider.getTransportProfile();
EndpointType endpoint                       = provider.getEndpoint(); // non-null after init()

Example

import com.helger.phase4.dynamicdiscovery.AS4EndpointDetailProviderBDXR;
import com.helger.smpclient.bdxr1.BDXRClientReadOnly;

BDXRClientReadOnly smpClient = new BDXRClientReadOnly(smpBaseURI);
IAS4EndpointDetailProvider provider = new AS4EndpointDetailProviderBDXR(smpClient);

AS4EndpointDetailProviderBDXR2

Looks up endpoint details from an OASIS BDXR SMP v2 server. Since 0.10.6.

Constructor

new AS4EndpointDetailProviderBDXR2(
    IBDXR2ServiceMetadataProvider aSMPClient // required
)
body.aSMPClient
IBDXR2ServiceMetadataProvider
required
OASIS BDXR SMP v2 client instance.

Configuration

body.setTransportProfile
ISMPTransportProfile
Transport profile for endpoint selection. Default: ESMPTransportProfile.TRANSPORT_PROFILE_BDXR_AS4.

Getters

IBDXR2ServiceMetadataProvider client = provider.getServiceMetadataProvider();
ISMPTransportProfile tp              = provider.getTransportProfile();
EndpointType endpoint                = provider.getEndpoint(); // non-null after init()

Example

import com.helger.phase4.dynamicdiscovery.AS4EndpointDetailProviderBDXR2;
import com.helger.smpclient.bdxr2.BDXR2ClientReadOnly;

BDXR2ClientReadOnly smpClient = new BDXR2ClientReadOnly(smpBaseURI);
IAS4EndpointDetailProvider provider = new AS4EndpointDetailProviderBDXR2(smpClient);

Error handling

All init() implementations throw Phase4SMPException (a subtype of Phase4Exception) when SMP lookup fails. The isRetryFeasible() flag on the exception indicates whether the failure is transient:
try {
    provider.init(docTypeID, processID, receiverID);
} catch (Phase4SMPException ex) {
    if (ex.isRetryFeasible()) {
        // transient network error - retry may succeed
    } else {
        // non-transient error - do not retry
    }
}

Build docs developers (and LLMs) love