Skip to content

News and noteworthy

Philip Helger edited this page Jul 24, 2026 · 64 revisions

Releases

v0.11.0 - work in progress

  • Implemented the MLS MLS_TO fallback for SMP lookup, following the Peppol Service Provider Operational Guideline on MLS (SPOG, sections 5.1 and 5.4). When acting as C3, an incoming MLS_TO is now only accepted if its SPID Main ID correlates to the sending C2's Main ID (from the AP certificate CN); a non-correlating MLS_TO is ignored (redirecting an MLS to a different Service Provider is not allowed) and the default SPID receiver is used. When a custom MLS_TO receiver cannot be resolved via SMP, the AP now fires the new IAPNotificationHandlerSPI.onSpecialMlsToNotReachable() notification and falls back to the default SPID receiver (0242:<Main ID>); if even the default SPID is not resolvable, the MLS is queued and retried (per PNP Rule MLS-4) instead of failing permanently. Retries reconstruct the same fallback automatically for mls_response transactions. The OpenTelemetry metrics handler exposes a new phoss.ap.outbound.mls.special_to_not_reachable counter. Regular business-document sending is unaffected (an unresolvable receiver remains a permanent failure). See #66 and the Message Level Status wiki page.
  • Enriched the IAPLifecycleEventSPI.onInboundMLSCorrelated() lifecycle callback so integrations get the full context when an MLS is received. It now additionally provides the correlated outbound transaction ID, the resolved EMlsReceptionStatus (RECEIVED_AP / RECEIVED_AB / RECEIVED_RE), the MLS document ID, and the AS4 reception timestamp. The OpenTelemetry metrics handler now also breaks the phoss.ap.inbound.mls.correlated counter and the phoss.ap.mls.roundtrip.duration histogram down by the new phoss.ap.mls.reception_status attribute. See #63.
  • Added three optional custom fields (custom1, custom2, custom3, max 255 characters each) to outbound transactions. They can be supplied on all outbound submit endpoints (/api/outbound/submit/..., /submit-sbd, /submit-auto/... as query parameters; /submit-s3 in the JSON body), are stored in the outbound_transaction table (and mirrored into outbound_transaction_archive), and are returned by the outbound status APIs when set. Values longer than 255 characters are rejected with HTTP 400. Existing database rows are filled with NULL via a new Flyway migration (V4). See #64.

v0.10.4 - 2026-07-21

  • The deprecation warning for a legacy .ms configuration key (in APCoreConfig and APDirSenderConfig) is now logged only once per key, instead of on every access.
  • Fixed outbound sending masking the real transport error with Phase4PeppolException: A Peppol Reporting item can only be created AFTER sending. OutboundOrchestrator called createPeppolReportingItemAfterSending(...) unconditionally right after the AS4 send — on a failed send (e.g. a TLS handshake failure) that call threw, and the resulting exception overwrote the actual transport exception (captured in aCaughtSendingEx) in the sending report, so the sending report and logs only showed the reporting error instead of the underlying PKIX path building failed / SSLHandshakeException. The Reporting item is now only created when sending actually succeeded, so failures surface the real transport exception and retry decisions are made on the real error. Affected both the PAYLOAD_ONLY and PREBUILT_SBD outbound paths. See #58 - thx @ajay2280
  • Added a startup check that the TLS trust store used for outbound HTTPS connections (SMP lookup and AS4 sending) actually contains trust anchors. Since phase4 4.5.0 the AP HTTP client uses the JVM default trust store (honoring the javax.net.ssl.trustStore system property); if that store is overridden with an empty or invalid file, every outbound SMP lookup and AS4 transmission fails with PKIX path building failed. The application now fails fast at startup with a clear message instead of failing silently on every transmission. See #58
  • Security fix: the API token check was skipped for every /api/** request when the AP is deployed under a non-root servlet context path (server.servlet.context-path), leaving all API endpoints (outbound submit, status queries, MLS SLA reports, inbound reporting) unauthenticated in such deployments. ApiTokenFilter matched the context-absolute request URI (getRequestURI(), e.g. /ap/api/...) against /api/; it now matches the context-relative servlet path (getServletPath()), so the token check applies regardless of the context path. Root-context deployments were unaffected. See #62 - thx @karelkryda
  • Added a runtime extension mechanism that lets you add custom SPI implementations (notification handlers, verifiers, document forwarders, …) and additional JDBC drivers to a deployment without rebuilding the application jar. The phoss-ap-webapp Spring Boot jar is now repackaged with the ZIP layout (using Spring Boot's PropertiesLauncher), and the Docker image sets LOADER_PATH=/ext and creates an /ext directory whose contents are appended to the runtime classpath on startup. Any thin jar dropped into /ext — bind-mounted from the host or baked into a derived image — is discovered via the standard java.util.ServiceLoader, with no further wiring. See the new Runtime Extensions wiki page. Addresses #60.
  • Added the new phoss-ap-extension-demo module — a minimal, logging-only example extension (implementing IAPLifecycleEventSPI and IAPNotificationHandlerSPI) with an example Dockerfile and assemble.sh / run-docker-ph.sh helper scripts, as a copy-paste starting point for writing your own extension.
  • Added experimental support for IBM DB2 (LUW) as a persistence backend, selected via phossap.jdbc.database-type=db2, including DB2 Flyway migration scripts. Because the IBM jcc driver is proprietary, it is not bundled: the driver and the flyway-database-db2 dialect are supplied at runtime via the new /ext extension mechanism (see Runtime Extensions), keeping the default distribution lean and Apache-licensed. Timestamp parameters are converted to java.sql.Timestamp only when running on DB2 (whose JDBC driver rejects OffsetDateTime via setObject()); PostgreSQL, MySQL and H2 continue to bind OffsetDateTime unchanged, so their behavior is unaffected. The Peppol Reporting SQL backend also supports DB2 (since peppol-reporting 4.2.0), so the reporting database may run on DB2 too. See #56 / #57 - thx @dmaus2018
  • Added a generic custom document storage backend extension point. Set storage.mode=spi and supply an IDocumentPayloadManagerProviderSPI implementation (selected by the storage.spi.id property, matched against the provider's getID()) to store document payloads in any backend — a relational database, an object store, a message queue, etc. The AP core makes no assumption about the storage technology; any technology-specific setup (schema, migrations, bucket provisioning) is the provider's own responsibility. The implementation is loaded via the /ext extension mechanism, exactly like the other provider SPIs (see Runtime Extensions). See #59 - thx @dmaus2018

v0.10.3 - 2026-07-05

  • Updated to ph-commons 12.3.2 - security improvements on XML processing and bug fixing in background cache eviction
  • Updated to peppol-reporting 4.1.5 - exclude MLS from EUSR

v0.10.2 - 2026-07-02

  • Added an outbound dev loopback mode for local/test environments. When outbound.dev-loopback.enabled=true and peppol.stage=test, outbound sending skips the SMP/SML lookup and sends the generated AS4 message back to this AP's own phase4.endpoint.address, using the AP's own AS4 certificate as the receiver certificate. Disabled by default, opt-in only, and ignored on the production stage — production behaviour is unchanged. See #49 - thx @fmarslan
  • HTTP forwarding now sends the SBDH Instance Identifier as the X-SBDH-Instance-ID request header, so the Receiver Backend can obtain it without deserializing the SBD stream (relevant e.g. for French PPF e-reporting). See #51 - thx @shetty-tejas
  • SFTP forwarding can now optionally write a JSON metadata sidecar next to each uploaded SBD, mirroring the filesystem forwarder's metadata. Enabled via the new forwarding.sftp.write-metadata property (default false). The sidecar is written with the same base name as the SBD ({name}.json) and contains the full inbound transaction metadata (the same JSON as the inbound transaction REST API).
  • S3 forwarding can now optionally write a JSON metadata sidecar object next to each uploaded SBD, mirroring the SFTP and filesystem forwarders' metadata. Enabled via the new forwarding.s3.write-metadata property (default false). The sidecar uses the same object key as the SBD but with a .json extension (<key-prefix><sbdhInstanceID>.json) and the same content.

v0.10.1 - 2026-06-25

  • Fixed Phorm call result handling to handle negative validations properly
  • MLS messages are no longer using status reason code FD but AB as we assume a temporary problem only
  • Filtering out Saxon "transformation warnings" when creating MLS errors
  • Fixed potential issues with S3 connection under load. See #47 - thx @gaboull

v0.10.0 - 2026-06-22

  • Added new IAPNotificationHandlerSPI.onInboundDuplicateRejected(...) callback that is invoked when an inbound AS4 message is rejected because it was detected as a duplicate before an inbound transaction could be persisted. Carries the Peppol sender ID (C1), receiver ID (C4), document type ID, process ID, sender provider ID (C2, derived from the signing certificate common name), AS4 Message ID, SBDH Instance Identifier, the bIsDuplicateAS4 / bIsDuplicateSBDH flags and the error detail sent back as the AS4 error. Declared as a default-method, so existing in-tree and external IAPNotificationHandlerSPI implementations remain source- and binary-compatible. See #42 - thx @fmarslan
  • BREAKING — IInboundDocumentVerifierSPI signature changed. verifyInboundDocument now returns @Nullable MlsOutcome instead of @NonNull ESuccess. null (or any non-REJECTION outcome) means the verifier passes; a non-null MlsOutcome with response code REJECTION rejects the document and its MlsOutcomeIssue entries flow into the outbound MLS line responses. External implementations of this SPI must be updated; the in-tree PhormDocumentVerifier has been migrated. See #38.
  • Added PhiveToMlsMapper in phoss-ap-validation that maps a phive ValidationResultList to a detailed MlsOutcome. Inbound rejections now carry one MLS line response per failed phive entry instead of a single generic BV/NA line: XSD validation failures become SV (Syntax Violation); Schematron and other failures become BV (Business Rule Violation, fatal) or BW (Business Rule Warning) based on phive severity; each issue's errorField carries the phive errorFieldName (typically the failed assertion's XPath context) with fallback to the formatted error location or NA; the issue description prefixes the rule ID where available (e.g. [BR-CO-15] Sum mismatch). Warnings are dropped when no errors are present (acceptance MLS responses do not carry line issues). See Message Level Status — Verifier-driven issue mapping.
  • Fixed Peppol Reporting outbound endUserID being set to the receiver participant ID instead of the sender participant ID — affected both the PEPPOL_SBDH and PREBUILT_SBD outbound paths in OutboundOrchestrator, so EUSR reports submitted by an AP that also sends documents contained the wrong end-user identifier. See #40 - thx @DmitriiKhudiakov
  • Added a machine-readable OpenAPI 3 specification of all REST endpoints, served by the running application at GET /openapi/v3/api-docs (JSON) and GET /openapi/v3/api-docs.yaml (YAML). Generated at runtime by springdoc-openapi from controller annotations — no Swagger UI is bundled (only the raw spec is exposed). Each endpoint carries an operation summary/description, parameter descriptions with examples, and the documented success / 4xx / 5xx response codes. The referenced request/response DTOs (OutboundS3SubmitRequest, InboundTransactionResponse, OutboundTransactionResponse, MlsSlaReportResponse, MlsSlaEntryResponse, ReportResponse) carry field-level descriptions, examples, required-vs-optional markers and allowed-value lists for enum-like fields (status, MLS response codes, …) so generated clients reflect the real contract. Declares the X-Token API-key security scheme on all /api/** endpoints so the auth requirement is visible to spec consumers and client generators; /management/** is unprotected. The base path is configurable via springdoc.api-docs.path (defaults to /openapi/v3/api-docs).
  • All sending reports, also in case of error, now at least contain the SBDH Instance Identifier and the country of C1 to make sure a later alignment is possible. See #44 - thx @Robcio35
  • Not sending MLS on MLR messages
  • Not placing MLS_TYPE and MLS_TO SBDH parameters on MLR or MLS messages

v0.9.1 - 2026-05-29

  • Replaced the in-tree tracing facade (APTrace, IAPSpan, EAPSpanKind, IAPTracerSPI in phoss-ap-api) with the new ph-telemetry submodule from ph-commons 12.2.6. phoss-ap-otel now provides the tracer via the ITelemetryTracerSPI service-loader contract instead of the in-tree SPI. Inbound / outbound / forwarding / MLS / scheduler / reporting code now uses com.helger.telemetry.Telemetry directly — no behavioural change, but consumers that only depended on the SPI now depend on ph-commons instead of phoss-ap-api.
  • Updated dependencies:
    • Parent POM 3.0.3 → 3.0.5
    • ph-commons 12.2.5 → 12.2.6 (new ph-telemetry submodule providing a vendor-neutral tracing facade; EErrorLevel.SUCCESS deprecated in favour of INFORMATION)
    • ph-web 11.4.0 → 11.4.1 (proxy configuration via http.proxy.host / http.proxy.port no longer requires http.proxy.enabled=true; http.proxy.enabled now only acts as an explicit kill-switch)
    • phase4 4.5.0 → 4.5.1 (improved backwards compatibility around the AP TLS truststore default change and clearer error messages on TLS / PKIX failures pointing at the migration guide)
    • ddd 0.8.7 → 0.8.8 (added value-provider entries for the French CTC Extended-CTC-FR profile on cii, ubl2-invoice and ubl2-creditnote; added support for the French CTC CDAR D22B syntax)
    • peppol-reporting 4.1.3 → 4.1.4
    • AWS SDK 2.44.4 → 2.45.0
    • Flyway 12.6.1 → 12.6.2
    • JAXB 4.0.8 → 4.0.9
    • OpenTelemetry Instrumentation 2.27.0 → 2.28.1
    • Sentry 8.41.0 → 8.43.0
    • Apache MINA sshd-sftp 2.17.1 → 2.18.0
    • Added OkHttp 5.3.2 as a centrally managed dependency for the OpenTelemetry OTLP exporter runtime

v0.9.0 - 2026-05-17

  • Added support for secondary forwarders — fire-and-forget fan-out of every successfully forwarded inbound document to any number of additional endpoints. Useful for duplicating from a TEST AP to both a Dev and a QA backend, or for adding a filesystem archive alongside an HTTP forward. Configured via indexed keys forwarding.secondary.{n}.mode / forwarding.secondary.{n}.* (up to 10 secondaries). Each secondary may use any supported mode (http_post_*, s3_link, sftp, filesystem) independently of the primary. Secondaries run only after the primary succeeded, have no retries, no SLA, no effect on the inbound transaction status, MLS response or circuit breaker; failures are logged only. Each dispatch is wrapped in a phoss.ap.inbound.forward.secondary OpenTelemetry span. See #23 and Forwarding Process — Secondary Forwarders.
  • Added optional OpenTelemetry integration in the new phoss-ap-otel module — emits metrics (failure counters, lifecycle counters and SLA histograms for forwarding / sending / MLS round-trip / scheduler cycles) and distributed traces across the inbound, outbound, MLS, SMP, verification, reporting, scheduler and archival flows. Disabled by default; enabled by setting otel.enabled=true and configuring the standard OTel environment variables (e.g. OTEL_EXPORTER_OTLP_ENDPOINT). Adds two new SPIs in phoss-ap-api: IAPLifecycleEventSPI (positive lifecycle events, complementing the existing failure-side IAPNotificationHandlerSPI) and IAPTracerSPI (tracing facade behind APTrace / IAPSpan / EAPSpanKind, so in-tree modules record spans without depending on the OpenTelemetry API jar). See #33
  • AS4 incoming duplicate detection is now backed by the configured database (PostgreSQL, MySQL, H2). Survives restarts and is shared across multiple AP instances. Adds Flyway V2 migration creating the as4_duplicate_item table. See #19
  • CRL downloads now use the dedicated Phase4PeppolCRLHttpClientSettings (pre-tuned timeouts) from phase4
  • Added new configuration property peppol.revocation.soft-fail (default false) to globally enable certificate revocation soft-fail mode — when set, certificate validation succeeds even if the CRL/OCSP status cannot be determined (e.g. responder unreachable due to a network error). Maps to CertificateRevocationCheckerDefaults.setAllowSoftFail(boolean).
  • /api/outbound/submit-sbd now also runs Phorm validation when verification.outbound.enabled=true, matching the behavior of /api/outbound/submit and /api/outbound/submit-auto. See #21 - thx @roiLeo
  • Added optional cleanup scheduler that periodically deletes archived inbound and outbound transactions (database row + document file) whose completed_dt is older than the configured retention. Operates only on archive tables; requires archival to be enabled. Configured via new properties cleanup.scheduler.enabled (default false), cleanup.scheduler.interval (default 24h), cleanup.scheduler.retention (default 90d, minimum 2d), and cleanup.scheduler.batch-size (default 100). Adds Flyway V3 migration creating indexes on completed_dt of the archive tables. See #20 - thx @thordw
  • Switched all time-related configuration properties to use the duration grammar (e.g. 5s, 1m 30s, 2d 12h). The legacy .ms / .millis keys continue to be honored for backwards compatibility (with a deprecation warning) and will be removed in v1.0.0. See Configuration Properties for the duration grammar. Affected properties:
    • retry.sending.initial-backoff(.ms)
    • retry.sending.max-backoff(.ms)
    • retry.forwarding.initial-backoff(.ms)
    • retry.forwarding.max-backoff(.ms)
    • retry.scheduler.interval(.ms)
    • circuit-breaker.open-duration(.ms)
    • archival.scheduler.interval(.ms)
    • dirsender.scan-interval(.ms)
    • dirsender.initial-delay(.ms)
    • shutdown.timeout(.ms)
    • phossap.jdbc.pooling.max-wait(.millis)
    • phossap.jdbc.pooling.between-evictions-runs(.millis)
    • phossap.jdbc.pooling.min-evictable-idle(.millis)
    • phossap.jdbc.pooling.remove-abandoned-timeout(.millis)
    • phossap.jdbc.execution-time-warning(.ms)
  • GET /api/outbound/status/{sbdhInstanceID} and GET /api/inbound/status/{sbdhInstanceID} now accept the optional query parameter includeArchive=true (default false). When set, the corresponding archive table is consulted if the transaction is no longer present in the active table. Adds the new DB API methods IOutboundTransactionManager.getBySbdhInstanceIDIncludingArchive(String) and IInboundTransactionManager.getBySbdhInstanceIDIncludingArchive(String). See #29 - thx @Robcio35
  • Removed the obsolete &serverTimezone=UTC parameter from the default MySQL JDBC URL in application.properties — the parameter has been a no-op since MySQL Connector/J 8.x and emits a deprecation warning. See #18
  • Fixed missing return statement in PeppolReportingController that caused the success response of the manual report trigger endpoint to be dropped, so a successful run was reported as an internal server error. See #25 - thx @gkoszegi
  • Updated dependencies:
    • PostgreSQL JDBC driver 42.7.10 → 42.7.11 (#26, #27)

v0.2.3 - 2026-04-19

  • Updated to BouncyCastle 1.84 (fixing CVE-2026-5588, CVE-2025-14813 and CVE-2026-5598)
  • Made sure all time related activities use UTC timezone only

v0.2.2 - 2026-04-12

  • Recommendation to use phorm 2.0.3+ as it support to extract payloads from SBDH payloads
  • Added support for custom S3 endpoints and path-style access across all three S3 integration points (storage, outbound, forwarding), enabling use of S3-compatible providers like MinIO or Garage. See #16
  • Added new configuration properties: storage.s3.endpoint, storage.s3.path-style-access, outbound.s3.endpoint, outbound.s3.path-style-access, forwarding.s3.endpoint, forwarding.s3.path-style-access
  • Added H2 support for integration tests, including a Flyway migration script for H2. See #17
  • Switched JAXB runtime from com.sun.xml.bind:jaxb-impl to org.glassfish.jaxb:jaxb-runtime (the maintained coordinates). Pinned jaxb-impl to 4.0.6 because 4.0.7 contains a regression.
  • Added new configuration property phossap.flyway.history-table for customizing the Flyway schema history table name (from ph-db 8.1.3)
  • Added new configuration properties phossap.flyway.debug-mode and phossap.flyway.repair-mode for Flyway diagnostics and history table repair (from ph-db 8.2.0)
  • Updated dependencies:
    • peppol-commons 12.4.0 → 12.4.1 (eDEC Code Lists v9.6; PeppolMLSBuilder now has a customizable identifier factory)
    • phive 12.0.1 → 12.0.3 (avoid NPE; avoid infinite ZIP size handling; avoid automatic owner document selection)
    • ph-db 8.1.2 → 8.2.0 (customizable Flyway history table name; customizable JDBC pooling parameters; Flyway debug and repair modes)
    • ddd 0.8.2 → 0.8.5 (support for new Peppol TDD formats; ability to capture inner element; wrappers in result details)
    • peppol-reporting 4.1.2 → 4.1.3
    • peppol-ap-support 2.1.2 → 2.1.3
    • AWS SDK 2.42.22 → 2.42.32
    • Flyway 12.2.0 → 12.3.0
    • Jackson 3.1.0 → 3.1.1
    • Log4j 2.25.3 → 2.25.4

v0.2.1 - 2026-04-01

  • Added MySQL 8.0+ as a supported database backend alongside PostgreSQL, including Flyway migration scripts for MySQL and MySQL JDBC driver dependency (#14)
  • Fixed phase4 and SMP Client not sharing the same configuration sources
  • Fixed missing MLS_TO and MLS_TYPE parameters when passing outbound transaction as params
  • Fixed using the correct MLS_TO value from the inbound transaction
  • Added field database.type to the status data

v0.2.0 - 2026-03-30

  • Added new REST endpoint POST /api/outbound/submit-auto/{senderID}/{receiverID}/{c1CountryCode} for submitting raw XML documents with automatic document type and process detection via the DDD (Document Details Determinator) library — no need to specify docTypeID or processID
  • Added DDDHelper utility in phoss-ap-core for DDD integration
  • Added new phoss-ap-dirsender module — optional directory-based batch sender that watches a directory for pre-built SBD XML files, submits them via the normal outbound pipeline, and moves processed files to success/ or error/ subdirectories with JSON result files. Includes crash-safe pending/ intermediate directory with startup recovery and periodic cleanup.
  • Added new configuration properties: dirsender.enabled, dirsender.directory, dirsender.scan-interval.ms, dirsender.initial-delay.ms
  • Added new forwarding mode filesystem — writes received SBDs to a local directory with a metadata JSON file alongside each document. Supports flat and per-transaction layout modes via forwarding.filesystem.layout. Atomic write pattern (.tmp → rename) prevents partial file reads.
  • Added support for custom HTTP headers on forwarding requests via forwarding.http.headers.{n}.name / .value indexed configuration — useful for Bearer tokens, API keys, or custom metadata headers
  • AS4 message dumps now include a metadata.json file with incoming message metadata (remote address, timestamps, unique ID, etc.) — applies to both direction and grouped dump modes
  • Changed default document storage paths from /var/phoss-ap/inbound and /var/phoss-ap/outbound to ${user.home}/phoss-ap/inbound and ${user.home}/phoss-ap/outbound
  • The management status endpoint now includes the DDD library version
  • Added ddd library dependency (v0.8.2) for document type auto-detection

v0.1.3 - 2026-03-29

  • Added configurable C4 country code determination modes via forwarding.c4countrycode.modes — supports receiver_pid (derive from receiver participant ID scheme) and business_card (look up from Peppol Directory Business Card via SMP). Multiple modes can be chained as a fallback sequence. The asynchronous reporting API always remains available as the final fallback.
  • Added new REST endpoint GET /api/inbound/missing-c4-country-code to list all forwarded transactions still missing a C4 country code
  • Added new REST endpoint GET /api/inbound/missing-c4-country-code/{sbdhInstanceID} to check if a specific transaction is missing a C4 country code (200 = missing, 204 = already set, 404 = not found)
  • Added c4CountryCode field to the InboundTransactionResponse DTO — previously omitted from the JSON response
  • Added management status endpoint GET /management/status returning non-sensitive configuration, version information, and runtime metadata as JSON (#13)
  • Added new configuration property peppol.receiver-check.mode with values none (default), smp, and sml to explicitly control receiver check behavior. The sml mode uses dynamic per-participant SMP resolution via the SML (#12, requires phase4 4.4.2+)
  • Added new configuration property peppol.dns.servers to specify custom DNS servers for Peppol NAPTR lookups
  • Added new configuration property management.status.enabled (default true) to disable the status endpoint
  • Changed default retry.sending.initial-backoff.ms from 60 seconds to 180 seconds (3 minutes)
  • Fixed HttpDocumentForwarder not applying configured HttpClientSettings (proxy, timeouts, TLS) — the settings were loaded from configuration but never passed to the HttpClientManager
  • Updated dependencies:
    • phase4 4.4.1 → 4.4.2

v0.1.2 - 2026-03-27

  • Added new configuration property mls.sending.enabled (default true) to globally disable all outbound MLS sending — useful for testing or during initial rollout
  • Added "retry": "none" support in http_post_sync forwarding responses — the Receiver Backend can now suppress retry attempts for permanently unprocessable documents
  • Added new configuration property archival.scheduler.batch-size (default 100) to control how many transactions are archived per scheduler cycle; values < 1 are rejected at startup
  • Added new configuration property retry.scheduler.batch-size (default 50) to control how many transactions are retried per scheduler cycle; values < 1 are rejected at startup
  • Added MLS correlation tracking: incoming MLS responses now record the inbound transaction ID (mls_inbound_transaction_id) for full audit trail
  • The peppol.receiving.enabled=false flag is now enforced — incoming AS4 messages are rejected immediately when receiving is disabled
  • Added logging configuration template in application.properties with commented-out options for file output, daily rotation and retention
  • Improved error diagnostics: AS4 private key loading failures now include the attempted key alias in the error message
  • Improved Phase4PeppolSendingReport to always include the AS4 sending result code, even on failure
  • Fixed NPE in OutboundOrchestrator when AS4 sending returns a negative result code without an accompanying exception
  • Fixed NPE in OutboundOrchestrator error message construction when exception is null
  • Fixed test backend to use configured country code for http_post_async forwarding responses instead of hardcoding AT (#10)
  • Moved all client-relevant REST API DTOs from phoss-ap-webapp to new com.helger.phoss.ap.api.dto package in phoss-ap-api, so that API clients can depend on phoss-ap-api alone without pulling in the webapp or Spring Boot
    • OutboundS3SubmitRequest — S3 submission request body
    • OutboundTransactionResponse — outbound transaction status (includes fromDomain())
    • InboundTransactionResponse — inbound transaction status (includes fromDomain())
    • ReportResponse — inbound reporting response
    • MlsSlaReportResponse (with nested MlsSlaEntryResponse) — MLS SLA compliance report
  • Updated dependencies:
    • Upgraded Jackson from 2.x to 3.1.0 (new tools.jackson.core groupId)
    • Spring Boot 4.0.3 → 4.0.5
    • phase4 4.3.2 → 4.4.1
    • peppol-commons 12.3.12 → 12.4.0
    • ph-web 11.2.4 → 11.2.5
    • Flyway 12.1.0 → 12.2.0
    • AWS SDK 2.42.13 → 2.42.22
    • Sentry 8.35.0 → 8.37.1
    • JAXB 4.0.6 → 4.0.7
    • commons-compress 1.28.0, commons-lang3 3.20.0
    • Imported parent POMs for ph-db, phase4 and peppol-reporting for centralized dependency management

v0.1.1 - 2026-03-18

  • Added S3 as an alternative document storage backend via storage.mode=s3 (new DocumentPayloadManagerS3 implementation of IDocumentPayloadManager)
  • Document paths in the database are now opaque strings — either absolute filesystem paths or s3://bucket/key URIs depending on the configured storage mode
  • Added new EStorageMode enum (FILE_SYSTEM, S3) for type-safe storage mode configuration
  • Added new REST endpoint POST /api/outbound/submit-s3 for submitting outbound documents by S3 reference instead of inlining the payload
  • Added new OutboundS3SubmitRequest JSON DTO for the S3 submission endpoint
  • Added configuration properties: storage.mode, storage.s3.* (bucket, region, access-key-id, secret-access-key), outbound.s3.* (enabled, bucket, region, access-key-id, secret-access-key)
  • Changed IDocumentPayloadManager.renameFile() return type from File to String to support non-filesystem storage backends
  • storage.inbound.path and storage.outbound.path are now used by all storage modes as base path components
  • Added AWS S3 SDK dependency to phoss-ap-basic module

v0.1.0 - 2026-03-17

  • Initial release as open-source
  • Requires Java 21 or later
  • Based on Spring Boot 4.x
  • Uses phase4 4.x for AS4 message exchange
  • Uses peppol-commons 12.x for Peppol identifiers, SMP client and MLS
  • Uses peppol-reporting 4.x for Peppol Reporting
  • PostgreSQL is the required backend database, schema managed via Flyway 12.x
  • Inbound AS4 document reception with duplicate detection on AS4 Message ID and SBDH Instance Identifier
  • Outbound document sending with automatic SMP lookup and SBDH creation
  • Configurable document forwarding to backend systems via HTTP POST, AWS S3 or SFTP
  • Retry with exponential backoff and per-endpoint circuit breaker (via Failsafe 3.x) for both sending and forwarding
  • Optional document validation via external phive Validation Service
  • MLS (Message Level Status) support with integrated SLA-1 and SLA-2 reporting
  • Peppol Reporting with scheduled EUSR and TSR submission
  • Automatic archival of completed transactions
  • REST API for outbound submission, status queries and inbound reporting
  • API token authentication
  • Multi-instance safe via PostgreSQL SKIP LOCKED for concurrent job processing
  • (Docker) Multi-stage Dockerfile with health check on /actuator/health
  • (Docker) Docker Compose setup with PostgreSQL included
  • Optional Sentry integration for error tracking

Clone this wiki locally