Overview
pn-address-manager provides address normalisation and deduplication services. Paper Channel calls Address Manager during the prepare phase whenever it needs to compare two addresses (e.g., a first-attempt postman address versus a second-attempt National Registry address) and obtain a normalised canonical form. The core operation isdeduplicates, which takes two addresses, determines whether they are equivalent, and returns a normalised version of the target address.
When Paper Channel calls Address Manager
Address Manager is invoked fromSecondAttemptFlowService.handleSecondAttempt(...) — the abstract base class for all second-attempt prepare flows. Concrete subclasses include the postman flow and the National Registry flow.
The call sequence is:
Client interface
Implementation — AddressManagerClientImpl
- Calls
DeduplicatesAddressServiceApi.deduplicateswithcxIdandapiKeyheaders. - Retries up to 2 times with 500 ms backoff on transient
TimeoutExceptionorConnectException. - Maps both addresses via
AddressMapper.toAnalogAddressManager(...)before sending.
Request fields — DeduplicatesRequestDto
Correlation identifier for tracing the request across services.
The reference address (first-attempt address). Mapped from
Address via AddressMapper.toAnalogAddressManager.The candidate address to normalise and compare (second-attempt address).
Response fields — DeduplicatesResponseDto
The normalised canonical form of the target address.
null if Address Manager could not normalise the address.true if the base and target addresses are considered equivalent after normalisation.An error code string if normalisation failed. Known codes are defined in
DeduplicateErrorConst.Error codes — DeduplicateErrorConst
| Code | Meaning | continueFlow flag |
|---|---|---|
PNADDR001 | Address differs after normalisation — variant 1 | Controlled by pn.paper-channel.pnaddr001continue-flow (default: true) |
PNADDR002 | Address differs after normalisation — variant 2 | Controlled by pn.paper-channel.pnaddr002continue-flow (default: false) |
PNADDR003 | Address differs after normalisation — variant 3 | Always stops the flow (continueFlow = false) |
PNADDR999 | Unrecoverable Address Manager error | Throws PnAddressFlowException(ADDRESS_MANAGER_ERROR) |
continueFlow is true for an error code, the prepare flow continues using the original first-attempt address (via throwExceptionToContinueFlowAfterError). When false, the flow stops and a StopFlowSecondAttemptException is thrown with the error code and geokey.
If
normalizedAddress is null in the response, Paper Channel throws RESPONSE_NULL_FROM_DEDUPLICATION. This is treated as a fatal error — the prepare flow cannot continue without a valid normalised address.Configuration
| Property | Description | Example |
|---|---|---|
pn.paper-channel.client-address-manager-basepath | Base URL of the Address Manager service | http://localhost:1080 |
pn.paper-channel.address-manager-cx-id | Client identity header (x-pagopa-pn-cx-id) | pn-paper-channel |
pn.paper-channel.address-manager-api-key | API key header for Address Manager | _ |
pn.paper-channel.attempt-queue-address-manager | Max SQS consumer retry attempts | 3 |
pn.paper-channel.pnaddr001continue-flow | Whether PNADDR001 allows the flow to continue | true |
pn.paper-channel.pnaddr002continue-flow | Whether PNADDR002 allows the flow to continue | false |
Error handling
| Exception | Cause | Behaviour |
|---|---|---|
ADDRESS_MANAGER_ERROR (via PnAddressFlowException) | PNADDR999 error code in response, or any unrecoverable exception from deduplicates | Propagated upstream; prepare flow fails |
RESPONSE_NULL_FROM_DEDUPLICATION | normalizedAddress is null in response | Fatal — prepare flow terminates |
RESPONSE_ERROR_NOT_HANDLED_FROM_DEDUPLICATION | error code is not PNADDR001/002/003/999 | PnGenericException thrown |
StopFlowSecondAttemptException | PNADDR002 or PNADDR003 with continueFlow = false | Flow stops; outcome reported to Delivery Push |
TimeoutException / ConnectException | Transient connectivity issue | Retried 2 times with 500 ms backoff; PnAddressFlowException thrown if all fail |