Skip to content

Instantly share code, notes, and snippets.

Show Gist options
  • Select an option

  • Save sasharevzin/a55adeee9731a3d0c10920479b4573a9 to your computer and use it in GitHub Desktop.

Select an option

Save sasharevzin/a55adeee9731a3d0c10920479b4573a9 to your computer and use it in GitHub Desktop.
psaTitan: Direct HLR API activation — replace IFS bulk CSV with Summa HSS REST (plan)
name Direct HLR API Activation
overview Replace the file-drop-and-callback bulk activation flow with direct REST API calls to the Summa HSS, reusing Titan's existing HLR vendor module pattern and the same data already gathered by getActivationFileInfo.
todos
id content status
vendor-interface
Add createSubscriber method to HlrVendorModule interface + SubscriberActivationData VO
pending
id content status
rest-client
Create SummaRestClient (JSON HTTP client for HSS REST API, parallel to SummaSoapClient)
pending
id content status
vendor-impl
Implement createSubscriber in HlrSummaVendor using SummaRestClient + SubscriptionDto mapping
pending
id content status
structured-query
Add getActivationRows() to IMSIUtilities returning List<SubscriberActivationData> instead of CSV strings
pending
id content status
endpoint
New endpoint or mode flag on bulkactivation to call HSS REST directly instead of file drop
pending
id content status
async-handler
Async batch command handler (hlr_direct_activate) for large subscriber sets
pending
id content status
hlr-settings
Add hss_rest_api_ip and hss_operator_name HLR setting types + admin UI / SQL migration
pending
id content status
status-update
Per-subscriber status update logic (adapt updateStatusAfterActivate for incremental use)
pending
isProject false

Direct HLR API Activation — Replace File Drop with REST Calls

Current flow (what we are replacing)

sequenceDiagram
    participant Client
    participant Titan as Titan API
    participant iSeries as iSeries IFS
    participant Provisioner as External Provisioner
    Client->>Titan: POST /imsi/bulkactivation
    Titan->>Titan: getActivationFileInfo (DB query)
    Titan->>iSeries: Write CSV via JT400
    Titan-->>Client: 200 + batch id
    Note over iSeries,Provisioner: External job polls IFS,<br/>provisions HLR, writes result zips
    Provisioner->>iSeries: Write SUCCESS.txt / ERROR.txt zips
    Client->>Titan: POST /imsi/bulkactivationcomplete
    Titan->>iSeries: Read result zips
    Titan->>Titan: Parse results, update SIM/IMSI status
Loading

Pain points: latency waiting for external job, FTP/JT400 dependency, opaque error handling, no per-subscriber feedback.

Target flow

sequenceDiagram
    participant Client
    participant Titan as Titan API
    participant HSS as Summa HSS REST
    Client->>Titan: POST /imsi/bulkactivation (or new endpoint)
    Titan->>Titan: getActivationFileInfo (same DB query)
    loop Each subscriber row
        Titan->>HSS: POST /v1/SubscriberManagement/createSubscriber/{operator}
        HSS-->>Titan: 201 or 4xx/5xx
        Titan->>Titan: Update SIM/IMSI status per result
    end
    Titan-->>Client: 200 + per-subscriber results
Loading

What already exists and can be reused

  • HlrVendorModule interface (HlrVendorModule.java) — extensible vendor abstraction
  • HlrSummaVendor (HlrSummaVendor.java) — already makes SOAP calls via SummaSoapClient and raw HTTP via httpPostXml; pattern for adding REST calls
  • HlrDispatcher (HlrDispatcher.java) — resolves which HLR record + account + vendor module to use for a given IMSI/MSISDN
  • HlrUrlResolver (HlrUrlResolver.java) — resolves {{ip}} placeholders in HLR URL settings
  • HlrService (HlrService.java) — existing JAX-RS /hlr/* endpoints follow the exact resolve-dispatch-vendor pattern
  • getActivationFileInfo (IMSIUtilities.java:1345) — already pulls all fields needed for HSS subscriber creation (IMSI, ICCID, MSISDN, ki, opc, hlrTemplate, lteTemplate, roamingProfile, smsRouteProfile, ssTemplate, imsProfile)
  • updateStatusAfterActivate (IMSIUtilities.java:1864) — status update logic (9 vs 10)
  • Commented prototype in ImsiService.java:3893-3934 — old ActivateHLRSubscribersRequest sketch showing the intended subscriber/IMSI/MSISDN structure

HSS REST API (from the spec PDF)

  • Create: POST /v1/SubscriberManagement/createSubscriber/{operatorName} — body is SubscriptionDto
  • Activate: PUT /v1/SubscriberManagement/activateSubscriber/{subscriberId}/{operatorName} — no body
  • No bulk endpoint — one subscriber per call; parallelism is our responsibility
  • Key fields in SubscriptionDto:
    • subscriber.subscriberId (e.g. "SUB_" + iccid)
    • subscriber.roamingTemplate
    • imsiSubscriptionList[].imsi, .roamingProfile (required), .hlrTemplate, .lteTemplate, .imsTemplate
    • msisdnInfoList[].msisdn, .smsRouteProfile, .ssTemplate, .imsiRelationshipList[].imsi, .defaultMsisdn
    • isim.iccId

Implementation tasks

1. Add createSubscriber to HlrVendorModule interface

Add a new method to the interface:

void createSubscriber(BigInteger account, SubscriberActivationData data, HLRValue hlr) throws Exception;

Where SubscriberActivationData is a new VO holding the parsed CSV row fields (iccid, imsi, msisdn, ki, opc, hlrTemplate, lteTemplate, roamingProfile, smsRouteProfile, ssTemplate, imsProfile, alg, operator).

2. Create SummaRestClient for the HSS REST API

New class in com.psasoft.titan.hlr (parallel to SummaSoapClient):

  • JSON POST/PUT using HttpURLConnection (same pattern as httpPostXml in HlrSummaVendor)
  • Jackson ObjectMapper for request/response serialization
  • Builds SubscriptionDto JSON from SubscriberActivationData
  • Uses a new HLR setting key (e.g. hss_rest_api_ip) resolved via HlrUrlResolver for the HSS REST base URL
  • Handles 200/201 as success, 400/500 as errors with message extraction

3. Implement createSubscriber in HlrSummaVendor

  • Resolve HSS REST URL from HLR settings via HlrUrlResolver.resolve(hlr, "hss_rest_api_ip", ...)
  • Resolve operator name from HLR settings (new key hss_operator_name or reuse existing hlr_default_activation_operator from profile settings)
  • Build the SubscriptionDto JSON mapping CSV fields to HSS fields:
    • subscriberId = "SUB_" + iccid
    • imsiSubscriptionList[0] = imsi + roamingProfile + hlrTemplate + lteTemplate + imsTemplate
    • msisdnInfoList[0] = msisdn + smsRouteProfile + ssTemplate + imsiRelationship to the imsi
    • isim.iccId = iccid
  • POST to {baseUrl}/v1/SubscriberManagement/createSubscriber/{operator}
  • Optionally follow with PUT .../activateSubscriber/{subscriberId}/{operator} if create does not auto-activate

4. Refactor getActivationFileInfo to return structured data

Currently returns List<String> (CSV rows). Either:

  • (a) Add a parallel method getActivationRows(...) returning List<SubscriberActivationData> (cleaner, avoids re-parsing CSV), or
  • (b) Parse the existing CSV strings back into fields (quick-and-dirty, fragile)

Option (a) is recommended — reuse the same SQL but map ResultSet columns to the new VO instead of CONCAT_WS.

5. New endpoint or mode flag on existing endpoint

Two options:

  • (a) Add a "mode": "direct" flag to BulkActivationRequest — when present, skip CSV/file and call HSS REST directly
  • (b) New endpoint POST /imsi/activatehlr that takes same ICCID list / IMSI range

Either way, the handler:

  1. Calls getActivationRows(...) for structured data
  2. Loops each row, calling HlrSummaVendor.createSubscriber(...) via HlrDispatcher
  3. On success per row: updates that SIM/IMSI status (reuse updateStatusAfterActivate logic or per-row variant)
  4. Collects per-subscriber success/failure results
  5. Returns batch-style response with per-subscriber detail

6. Async dispatch for large batches

For >50 subscribers, dispatch via DbQueueAsyncDispatchService (same pattern as current bulk activate) with a new command handler (e.g. hlr_direct_activate). The handler loops through rows calling the HSS REST API and updates batch progress. This avoids HTTP timeout on the initial request.

7. HLR settings configuration

Add new HLR setting types to module_hlr.hlrs_settings for each HLR definition:

  • hss_rest_api_ip — base URL of the HSS REST API (e.g. https://hss.example.com)
  • hss_operator_name — operator name for the path parameter (e.g. ChoiceWireless)
  • Optionally hss_auth_* keys if the HSS requires HTTP auth (Basic, bearer, mTLS cert path)

8. Keep the old flow as fallback

Do not remove the CSV/iSeries path. The mode flag or endpoint choice determines which path runs. This allows gradual migration and rollback.

Key decisions needed before implementation

  1. Auth to HSS REST — The PDF does not document HTTP auth. Need to confirm: is it IP-allowlisted? Basic auth? mTLS? This determines SummaRestClient auth config.
  2. Create vs Create+Activate — Does createSubscriber auto-activate, or do we need a separate activateSubscriber PUT call after each create?
  3. Operator name source — Hard-coded per HLR definition in DB, or derived from account settings?
  4. Sync vs async threshold — At what batch size should we switch from synchronous (wait for all results) to async (dispatch to queue worker)?
  5. New endpoint vs mode flag — Preference on API surface?
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment