Monday, June 15, 2026

PeopleSoft Integration Broker – Technical Interview Q&A

 

PeopleSoft Integration Broker – Technical Interview Q&A


Junior / Mid-Level (3–6 Years)


Q1. What is Integration Broker in PeopleSoft?

A: Integration Broker is PeopleSoft's middleware framework that enables synchronous and asynchronous messaging between PeopleSoft systems and third-party applications using service-oriented architecture. It handles message routing, transformation, queuing, and delivery through a gateway-based infrastructure.


Q2. What are the core components of Integration Broker?

A: Integration Gateway, Pub/Sub messaging system, Message Channel (Queue), Message Node, Service Operations, Handlers (OnRequest, OnNotify, OnError), Routing Definitions, and the Integration Engine running within the App Server.


Q3. What is the difference between Synchronous and Asynchronous service operations?

A: Synchronous operations require an immediate response from the target system within a single transaction - the caller waits. Asynchronous operations use a queue-based delivery where the message is published and the caller continues processing without waiting for a response. Asynchronous supports chunking, retry, and parallel delivery.


Q4. What is a Message Node and what does it represent?

A: A Message Node represents an external or internal system participating in integration. It defines the connection properties - connector type, URL, authentication - used by the gateway to route messages to that system. The local node represents the current PeopleSoft environment.


Q5. What is the purpose of a Message Channel?

A: A Message Channel (Queue) controls the order and parallelism of asynchronous message processing. Messages assigned to the same channel are processed sequentially. Multiple channels allow parallel processing across different business domains.


Q6. What is a Routing Definition and when is it required?

A: A Routing Definition maps a Service Operation to a sending node and receiving node. It controls direction (inbound/outbound), transforms, filters, and connector overrides. Without a valid active routing, messages will not be delivered.


Q7. What are the types of Handlers in Integration Broker?

A: OnRequest (handles synchronous inbound requests and must return a response), OnNotify (handles asynchronous inbound messages, no response expected), OnError (handles error conditions for a service operation), and OnAck (acknowledgment handling).


Q8. What is the Integration Gateway and what role does it play?

A: The Integration Gateway is a J2EE component deployed on the web server (PIA). It acts as the entry and exit point for all external messages. It manages connector loading, SSL termination, message serialization/deserialization, and routes messages to the Integration Engine inside the App Server via Jolt.


Q9. What connector is used for PeopleSoft-to-PeopleSoft integrations?

A: The PeopleSoft target connector (PSFTTARGET) for outbound and the PeopleSoft listening connector (PSFT) for inbound. These use the IB messaging protocol over HTTP/HTTPS.


Q10. What is the difference between a Rowset-based message and a non-rowset message?

A: Rowset-based messages have structure defined by PeopleSoft records and use the PeopleSoft XML schema with PSCAMA and data rows. Non-rowset (unstructured) messages carry arbitrary XML or any payload format and require manual parsing using XmlDoc or string manipulation in PeopleCode.


Q11. What is PSCAMA and what are its key fields?

A: PSCAMA is the audit header record embedded in every rowset-based message. Key fields: AUDIT_ACTN (A=Add, C=Change, D=Delete, K=Change with keys), LANGUAGE_CD, BASE_LANGUAGE_CD, MSG_NAME, MSG_VER, PUBLISH_RULE_ID, MSGNODENAME, and DESTNODENAME.


Q12. What is the purpose of the Publication Contractor and Subscription Contractor?

A: The Publication Contractor packages and queues outbound asynchronous messages from the App Server to the Integration Gateway. The Subscription Contractor picks up inbound messages from the queue and dispatches them to the appropriate handler.


Q13. How do you monitor Integration Broker messages?

A: Through Service Operations Monitor (PeopleTools > Integration Broker > Service Operations Monitor). It shows asynchronous publication queues, subscription queues, synchronous services, errors, and message instance details with payload inspection capability.


Q14. What happens when an asynchronous message fails?

A: The message goes to Error status in the Service Operations Monitor. Subsequent messages on the same channel are held if the channel is sequential. The message can be manually resubmitted after fixing the root cause, or the error handler OnError fires if configured.


Q15. What is a Transform Program in Integration Broker?

A: A Transform Program is an XSLT stylesheet or an Application Class-based PeopleCode program attached to a Routing Definition that transforms the message payload between the source format and the target format. Transforms run in the App Server during message routing.



🟡 Senior Level (6–10 Years)


Q16. Explain the end-to-end flow of an asynchronous outbound message.

A: PeopleCode or Component Interface triggers %IntBroker.Publish(). The Integration Engine packages the message, assigns it to the channel queue, and stores it in PSAPMSGPUBHDR/PSAPMSGPUBCON tables. The Publication Contractor picks it up and forwards it to the Integration Gateway. The Gateway selects the appropriate target connector, applies any transforms from the routing, and delivers it to the external endpoint. Status is written back to the monitoring tables.


Q17. What are the database tables that back Integration Broker queuing?

A: PSAPMSGPUBHDR and PSAPMSGPUBCON store publication (outbound) header and content. PSAPMSGSUBHDR and PSAPMSGSUBCON store subscription (inbound) header and content. PSAPMSGDOMVR stores domain versioning. PSAPMSGQUE holds the channel queue state.


Q18. How does Integration Broker handle large message payloads?

A: Through chunking - the message is split into multiple segments using the ChunkMessage method or automatically via chunk size settings on the message definition. Each chunk is published separately and reassembled on the target using chunk sequence information. Large payloads can also be streamed via GetLargeMessage API.


Q19. What is Domain Status and why does it matter for IB processing?

A: Domain Status represents the state of the App Server domain (Active, Inactive, Paused). The Publication and Subscription Contractors only process messages when the domain is Active. If a domain goes Inactive, outstanding messages queue up. The Dispatcher monitors domain heartbeat via PSAPMSGDOMVR to determine active processors.


Q20. How do you handle versioning of messages in Integration Broker?

A: By creating a new version of the Message definition (V2, V3, etc.) while keeping the original active for existing integrations. Routing Definitions are version-specific. Transform programs handle payload differences between versions. The MSG_VER field in PSCAMA carries the version identifier.


Q21. What is a REST-based Service Operation and how does it differ from a SOAP-based one?

A: REST service operations use HTTP methods (GET, POST, PUT, DELETE) with resource-based URIs, payload in JSON or XML, and no WSDL contract. SOAP operations use a strict WSDL contract, SOAP envelope wrapping, and the PeopleSoft HTTP target/listening connector with WS-Security headers. REST handlers parse the request via %IntBroker REST APIs; SOAP uses the standard Message object.


Q22. How do you implement WS-Security in Integration Broker?

A: By configuring the Node's Authentication Option (Password, Certificate, or Both), setting up the Digital Certificate store (PeopleTools > Security > Digital Certificates), and enabling WS-Security on the Routing Definition. Inbound WS-Security validation is handled by the Gateway. Outbound WS-Security signing/encryption is configured on the Node connector properties.


Q23. What is the GetMessage() / GetMessageInstance() pattern in handler PeopleCode?

A: Inside an OnNotify or OnRequest handler class, %IntBroker.GetMessage() retrieves the current inbound Message object. GetMessageInstance() is used to get a specific message version. The handler then accesses the message segments, rowsets, or XML content via the Message object API for processing.


Q24. How do you publish a message programmatically in PeopleCode?

A: Create a Message object using CreateMessage(OPERATION.OPERATION_NAME), populate the rowset or xmldoc content, set any overrides (target node, etc.) on the TransactionObject, then call %IntBroker.Publish(oMessage) for async or %IntBroker.SyncRequest(oMessage) for sync. Error handling checks the IB Status on the returned object.


Q25. What is the Integration Broker Tester and when do you use it?

A: The IB Tester (PeopleTools > Integration Broker > Service Utilities > Service Operation Tester) lets developers send test payloads to service operations without an external caller. It's used to validate handler logic, routing, transforms, and response generation in isolation during development and debugging.


Q26. How do you secure a REST service operation exposed from PeopleSoft?

A: By setting the Service Operation permission on the Permission List (Read, Write), assigning it to a Role, enforcing Authentication Token (oAuth/SSO Cookie or Basic Auth) on the service operation, and configuring SSL on the web server and gateway. API-level IP whitelisting can be added at the load balancer or gateway connector level.


Q27. What are Transformation Framework options in Integration Broker?

A: XSLT-based transforms (attached directly to routing, pure stylesheet processing), Application Class-based transforms (PeopleCode Transform class implementing ITransform interface with Execute method), and built-in PeopleCode transforms using XmlDoc for dynamic manipulation. App Class transforms are preferred when conditional logic is required.


Q28. How does Integration Broker support multi-target fan-out publishing?

A: By defining multiple Routing Definitions for the same Service Operation pointing to different target nodes. All active routings for the operation fire on publish. Each target receives an independent copy of the message and processes independently. Channel assignment per routing controls sequencing per target.


Q29. What is a Non-Repudiation Archive and how is it configured?

A: Non-Repudiation Archives store a tamper-proof copy of every message payload for audit and compliance. Enabled on the Service Operation definition (Archive Store option), it writes message content to PSAPMSGARCH tables. Retention and purging are managed by IB Archive processes.


Q30. How do you troubleshoot a stuck asynchronous publication queue?

A: Check Domain Status (all domains must be Active). Inspect the queue in Service Operations Monitor for error messages. Check the Publication Contractor process log in Process Monitor. Verify PSAPMSGDOMVR heartbeat is being updated by a live domain. Check App Server TUXEDO logs for dispatcher errors. If a poison message is blocking the channel, isolate and cancel it to unblock downstream messages.



🔴 Architect / Lead Level (10+ Years)


Q31. How would you design a high-volume PeopleSoft IB integration handling 500K+ messages per day?

A: Distribute load across multiple App Server domains using load balancing with separate Publication Dispatcher and Handler Server processes tuned for high throughput. Assign separate channels per business domain to maximize parallelism. Configure multiple Pub/Sub Handler processes per domain. Use chunking for large payloads. Implement asynchronous pattern exclusively - avoid synchronous at volume. Set up dedicated IB monitoring and alerting on PSAPMSGPUBHDR row counts and error thresholds. Archive processed messages on a rolling schedule to control table growth.


Q32. What are the architectural differences between Integration Broker running on a single domain versus clustered domains?

A: Single domain: one Publication Dispatcher, one set of Handler Servers - simple but single point of failure and throughput ceiling. Clustered: multiple domains each running Dispatchers and Handlers. Messages are distributed across domains using the Domain Versioning table (PSAPMSGDOMVR) for coordination. A domain claims message batches by updating heartbeat rows. Multiple domains can process different channels simultaneously, providing both redundancy and horizontal scalability.


Q33. How do you architect IB for zero message loss during App Server patching or maintenance?

A: Use a rolling domain restart pattern - bring down one domain at a time while others continue processing. All in-flight messages remain in the database queue and are picked up by surviving domains. For gateway maintenance, configure multiple gateway URLs on the Node definition with failover ordering. Use the IB Gateway Load Balancer property to distribute inbound traffic. Implement message-level acknowledgment (OnAck handlers) for end-to-end confirmation tracking.


Q34. How would you implement a canonical data model integration pattern using Integration Broker?

A: Define a set of canonical Message definitions in PeopleSoft that represent normalized business objects (Employee, Invoice, etc.). For each external system, define system-specific Routing Definitions with Transform Programs that map to/from the canonical format. All internal handlers work only with the canonical message. Adding a new external system requires only a new routing with a new transform - no changes to core handler logic.


Q35. What is the impact of XSLT vs Application Class transforms on performance at scale?

A: XSLT transforms load and execute in the Transformation Engine within the App Server - fast for simple mappings but limited in conditional and procedural logic. App Class transforms execute in PeopleCode runtime with full object model access - more flexible but carry PeopleCode session overhead. At scale, XSLT is faster for pure structural transforms. App Class is necessary for lookups, conditional branching, error logging, or calling Component Interfaces during transform. A hybrid - XSLT for structure + App Class wrapper for pre/post logic - is the optimal enterprise pattern.


Q36. How do you manage Integration Broker configuration across DEV, QST, UAT, and PROD environments?

A: Use ADS (Application Designer) Projects to migrate Service Operations, Messages, Routings, and Transform Programs through the lifecycle. Node definitions are environment-specific and maintained manually or via DataMover scripts. Gateway connector URLs are environment-specific configurations in integrationGateway.properties. Use Config Manager or scripted property file management for gateway-layer config. Document node URL matrices per environment and automate via PeopleSoft deployment automation tools.


Q37. What is the architectural significance of the Dispatch Contract process in IB?

A: The Dispatch Contract (Publication Dispatcher / Subscription Dispatcher) is the TUXEDO server process that orchestrates message distribution. It scans the queue tables, claims message batches, assigns them to Handler Servers, and writes back status. Its configuration (Min/Max Instances, Work Unit size) directly determines IB throughput. Undertuning it causes queue depth buildup; overtuning it causes TUXEDO memory exhaustion. It must be co-tuned with Handler Server instances and DB connection pool limits.


Q38. How would you design retry and dead-letter handling for critical outbound integrations?

A: Configure max retry count and retry interval on the Routing Definition. Implement the OnError handler to capture failed message context and write to a custom error log or trigger an alert workflow. For dead-letter, build a custom App Engine process that queries PSAPMSGPUBHDR for Error-status messages older than threshold, routes them to an exception queue or email notification, and generates a reprocessing ticket. Avoid manual resubmit dependency for production-critical flows.


Q39. How do you handle backward compatibility when a target system changes its API schema mid-integration?

A: Create a new Message version in PeopleSoft to represent the new schema. Build a new Routing Definition pointing to the updated node connector with a transform that maps from the existing internal canonical format to the new external schema. The old routing remains active for any systems still on the old schema. Version negotiation can be built into the transform using a routing filter on message version or node name. This isolates schema changes to the transform layer without touching handler or business logic.


Q40. What would you evaluate when deciding whether to use Integration Broker versus a third-party ESB (MuleSoft, TIBCO) for a PeopleSoft integration?

A: Use Integration Broker natively when: integrations are primarily PeopleSoft-to-PeopleSoft, volume is moderate, transformations are simple, and the team is PeopleSoft-skilled. Use a third-party ESB when: the integration landscape is heterogeneous (SAP, Salesforce, Workday, legacy), complex orchestration or saga patterns are needed, enterprise-wide API governance is required, or event streaming (Kafka-based) patterns are mandated. In hybrid architectures, IB handles the PeopleSoft boundary and publishes/subscribes to the ESB, which handles enterprise routing and orchestration. The ESB becomes the canonical integration hub; IB becomes a protocol adapter.


Q41. How do you enforce integration governance and observability in a large PeopleSoft IB landscape?

A: Establish a Service Operation naming standard and registry. Mandate that every service operation has an active routing log, a transform version, and an owner documented in the IB metadata comments. Build a custom monitoring dashboard using App Engine queries against PSAPMSGPUBHDR / PSAPMSGSUBHDR with SLA breach alerting. Implement centralized logging by extending OnError handlers to write to a custom IB_ERROR table with correlation IDs. Use Kibana or Splunk with App Server log ingestion for end-to-end message tracing across gateway, App Server, and handler layers.


PeopleSoft Integration Broker – Real-Time Troubleshooting & Setup Q&A

18+ Years / Principal Architect / Practice Lead Level


🔴 PRODUCTION TROUBLESHOOTING


Q1. A critical outbound async message pipeline suddenly stops processing in PROD with no code changes deployed. Where do you start and what is your systematic isolation approach?

A: First confirm Domain Status across all App Server domains via PSADMIN - a domain may have bounced and failed to restart cleanly. Check PSAPMSGDOMVR to confirm heartbeat timestamps are current for all registered domains; a stale heartbeat means the Dispatcher died silently. Check TUXEDO logs (TUXLOG, APPSRV.LOG) for BBL crashes or server process restarts. Confirm Publication Dispatcher (PSDISPATCH) and Handler Server (PSSUBHND) process counts match psappsrv.cfg configuration. Then check if the channel queue has a poison message in Error status blocking sequential processing - isolate and cancel it. Finally validate integrationGateway.properties has not been overwritten by a web server patch and that the gateway target connector URL is reachable.


Q2. You have 200,000 messages stuck in "New" status in PSAPMSGPUBHDR. Dispatcher is running. What caused this and how do you recover without message loss?

A: "New" status means messages were published to the DB queue but the Dispatcher never claimed them. Root causes: Dispatcher process count dropped to zero (check BBL), domain versioning conflict where two domains have the same node name causing claim collision in PSAPMSGDOMVR, or a DB lock on the queue table from a long-running transaction. Recovery: confirm Dispatcher is truly running via tmadmin and psr command. Clear stale domain rows from PSAPMSGDOMVR if duplicate node entries exist. Bounce the Dispatcher process cleanly - do not bounce the entire domain as that requeues in-flight Handler work. Messages in "New" status are safe; they will be picked up on Dispatcher restart. Never manually update status in PSAPMSGPUBHDR directly in production.


Q3. Synchronous service operation returns timeout to the caller but the handler executes successfully. How do you root-cause this?

A: This is a gateway-to-engine communication timeout, not a handler failure. Check the JOLT connection pool between Gateway and App Server - if all Jolt connections are saturated, the gateway queues the request past the synchronous timeout threshold. Check integrationGateway.properties for ig.ibtimeout and compare against App Server JOLT MAXPENDINGCONS. Check if the handler is doing long-running DB operations that exceed the gateway timeout but complete within TUXEDO timeout - the engine commits but the gateway already returned fault to the caller. Fix: increase ig.ibtimeout as interim, but the real fix is to offload the synchronous operation to async or optimize handler query performance. Also check if load balancer or reverse proxy has its own timeout shorter than IB gateway timeout - common in enterprise DMZ setups.


Q4. An inbound REST service operation returns HTTP 200 but the handler OnNotify never fires. What is the diagnostic path?

A: HTTP 200 from the gateway means the gateway accepted and queued the message - handler firing is a separate concern. Check the Subscription queue in Service Operations Monitor for the message instance - it may be in "New" or "Error" status. If "New", the Subscription Dispatcher is not processing - check PSSUBDSP process. If "Error", inspect the error detail - common causes are handler class not found (App Class path wrong), Permission List missing the service operation for the inbound node's user ID, or the inbound node not matching any active routing. Confirm the inbound node in the message header matches a Node definition in PeopleTools with an active inbound routing to the local node. Check gateway log (integration.log) for routing resolution failures.


Q5. Transform program is producing malformed XML in production only, works in QA. How do you isolate the data-specific failure?

A: Use the Service Operations Monitor to retrieve the raw inbound payload for the failing instance and compare it against a successful QA payload. The malformed output is almost always caused by a data character in production that QA data does not have - special characters (ampersand, angle brackets, accented characters) breaking XSLT processing, null field values causing XPath failures, or a field length exceeding Message schema definition. If XSLT-based, enable transform debug logging by temporarily redirecting the transform output to a custom log in an App Class wrapper. For App Class transforms, add defensive null checks around every XmlDoc node access. Never assume QA data covers production data variance - this is the most common transform production failure pattern.


Q6. Gateway is up, App Server is up, but all outbound messages are failing with "ConnectorException: Connection refused" to an external REST endpoint. Internal testing shows the endpoint is reachable. What do you investigate?

A: The gateway JVM makes the outbound HTTP call - not the App Server. So "reachable internally" means nothing if the gateway host has different network routing. Check if the gateway is deployed on the web server DMZ node which may have firewall rules blocking outbound to the target IP/port. Check integrationGateway.properties for proxy configuration (ig.proxyHost, ig.proxyPort) - the gateway may require a forward proxy for external calls that was not configured. Check SSL certificate trust - if the target endpoint recently renewed its certificate with a new CA, the gateway JVM truststore may not have the new CA certificate. Use keytool -list on the gateway JVM truststore to verify. Also confirm the connector timeout is not triggering before the endpoint responds - external endpoints with cold-start latency can appear as connection refused in gateway logs.


Q7. A PeopleSoft-to-PeopleSoft async integration between two environments stopped working after a PeopleTools upgrade on the target. Messages show "Error" with "Node authentication failed". What is the remediation?

A: PeopleTools upgrades often change the default node password hashing algorithm or reset the local node password. First confirm the source environment's Node definition for the target has the correct URL pointing to the upgraded target's gateway. Then confirm node-level authentication - if using Node password authentication, the password on both ends must match exactly. In the upgraded target, go to Node definition for the source node and re-enter/confirm the password. If using Digital Certificates for WS-Security, the upgrade may have reset the certificate store - re-import the source system's public certificate into the target's digital certificate store. Finally confirm the upgraded target's local node name has not changed - PeopleTools upgrades on cloned environments sometimes inherit the source node name.


Q8. Production IB performance degrades progressively over 72 hours, then recovers after a weekend. No code changes, no volume spikes. What is the systemic cause?

A: This pattern is classic IB queue table bloat combined with DB statistics staleness. PSAPMSGPUBHDR and PSAPMSGSUBCON accumulate processed message content rows that are not purged - over 72 hours the optimizer's table statistics become outdated and full table scans replace index scans on the Dispatcher's queue query. Monday recovery is because weekend batch purge runs or reduced load lets DB catch up. Permanent fix: implement IB Archive/Purge process on a 6-hourly schedule using the delivered IUARCH Application Engine. Rebuild statistics on PSAPMSGPUBHDR, PSAPMSGPUBCON, PSAPMSGSUBHDR, PSAPMSGSUBCON as part of the DBA weekly schedule. Add composite indexes on STATUS + CHNLNAME + PUBDTTM if not already present per Oracle/SQL Server IB tuning guides.


Q9. You inherit a production IB environment where messages randomly duplicate on the subscriber side. How do you architect a fix without changing the publisher?

A: Duplication root cause is either the publisher retrying due to false timeout (message delivered but acknowledgment lost) or the Subscription Dispatcher processing the same message twice due to a cluster coordination failure. Fix without touching publisher: implement idempotency in the OnNotify handler using a custom PROCESSED_MSG table keyed on MSGSEGID + PUBID - check before processing and skip if already recorded. This is the only safe fix because you cannot control whether a message arrives once or twice at the subscriber. Additionally audit PSAPMSGDOMVR for duplicate domain entries that could cause two Subscription Dispatchers to claim the same message batch - this is a setup defect in clustered environments.


Q10. An outbound SOAP integration to a third-party system starts failing with "SSL handshake exception" after their security team rotates certificates. Walk through the complete remediation.

A: The gateway JVM maintains its own truststore independent of the OS certificate store. Obtain the new certificate chain (root CA + intermediate) from the third-party team. Import each certificate into the gateway JVM truststore using keytool -importcert targeting the cacerts file of the JRE used by the gateway. Bounce the gateway web server to reload the JVM truststore - a hot reload is not supported. If the integration uses mutual TLS (client certificate), also confirm the client certificate presented by PeopleSoft has not expired - check the Node's digital certificate assignment in PeopleTools Security. After bounce, test using IB Tester before releasing to production traffic. Document the certificate expiry date and add a calendar alert 30 days prior to prevent recurrence.



🔴 ENVIRONMENT SETUP & CONFIGURATION


Q11. Walk through the complete Integration Gateway setup in a new PeopleSoft environment from scratch.

A: Deploy the gateway application (PSIGW.war) to the web server (WebLogic/Tomcat). Configure integrationGateway.properties: set ig.ISTPeopleSoftListeningConnector, local gateway URL, default App Server Jolt connect string, keystore path, and truststore path. Register the gateway URL in PeopleTools > Integration Broker > Configuration > Gateways - ping the gateway to confirm connectivity. Load connectors via the gateway administration page. Set the local node's gateway URL. Configure the gateway keystore with the local node's certificate if using WS-Security. Tune ig.threads, ig.maxConnections, and ig.ibtimeout based on expected load. Validate end-to-end by sending a test ping operation through the IB Tester.


Q12. How do you configure Integration Broker for a multi-domain clustered App Server setup to ensure no message duplication or loss?

A: Each domain must have a unique domain name but share the same local node name. All domains must point to the same database. Configure PSAPMSGDOMVR correctly - each domain registers its heartbeat independently. Ensure Publication Dispatcher on each domain is configured with non-overlapping work batch sizes to reduce contention. Set PUB_DISPATCHER_SLEEP and SUB_DISPATCHER_SLEEP parameters consistently across domains. Load-balance the gateway Jolt connection string across all App Server domains using the multi-server Jolt format. Validate by publishing a batch of test messages and confirming in PSAPMSGPUBHDR that different domains are processing different message batches with no duplicate MSGSEGID processing.


Q13. What is the complete checklist for setting up a new external Node for REST-based inbound integration?

A: Create Node definition with type "External", set Authentication Option (Basic/Certificate/None per security requirement). Define the Service Operation as REST with correct HTTP method and URI template. Create inbound Routing from the external node to the local node with the correct Service Operation version. Assign the Service Operation to the Permission List mapped to the node's authentication user ID. Configure SSL on the gateway if the endpoint uses HTTPS. Validate the gateway listening connector URL is accessible from the external caller's network. Test with IB Tester using a simulated inbound payload. Confirm message appears in Subscription Monitor and OnNotify handler fires successfully.


Q14. How do you configure Non-Repudiation and what are the operational consequences of enabling it?

A: Enable Archive Store on the Service Operation definition (both inbound and outbound as needed). This causes every message payload to be written to PSAPMSGARCH tables synchronously during processing. Operational consequence: increased DB write volume per message - at high volumes this becomes a throughput bottleneck. PSAPMSGARCH must be included in the purge/archive strategy with a separate retention window from operational queue tables. If regulatory compliance requires it, move PSAPMSGARCH to a separate tablespace with its own backup policy independent of the operational IB tablespace.


Q15. How do you set up a handler that must call an external system during processing of an inbound async message and handle the external system being unavailable?

A: In the OnNotify handler, wrap the external call in a try-catch with explicit error handling. On external system unavailability, do not allow the exception to propagate unhandled - that moves the IB message to Error and blocks the channel. Instead, write the failed payload to a custom retry staging table with a timestamp and retry count. Build a separate App Engine process on a scheduler that reads the staging table, retries the external call with exponential backoff, and marks complete on success or escalates to an alert after max retries. This decouples IB channel health from external system availability - a critical architectural discipline for async integrations.


Q16. How do you set up message-level encryption for sensitive payloads in Integration Broker beyond transport-layer SSL?

A: Use PeopleSoft's built-in WS-Security encryption at the message level. Configure Digital Certificates in PeopleTools Security - import the recipient's public certificate. On the Routing Definition, enable WS-Security with Encryption selected and assign the recipient's certificate for encryption. The gateway encrypts the SOAP body using the certificate before transmission. For non-SOAP REST payloads, message-level encryption is not natively supported in IB - implement payload encryption in the transform layer using a custom App Class that invokes Java crypto libraries available in the App Server JVM, encrypting the payload before the routing delivers it.


Q17. Walk through tuning the Publication Dispatcher and Handler Server processes for a high-throughput environment.

A: In psappsrv.cfg, increase MIN INSTANCES and MAX INSTANCES for PSDISPATCH and PSSUBHND based on CPU core count - a starting ratio is 2 Handler Servers per Dispatcher. Set WORKUNIT size on the Dispatcher to control how many messages are claimed per batch - larger batches reduce DB round trips but increase memory per process. Tune SLEEP interval on Dispatchers to balance responsiveness against DB polling load. Monitor TUXEDO server queue depth via tmadmin - if Handler queues are deep, add Handler instances. Monitor DB connection pool - each Handler consumes one connection, so Handler count is bounded by available DB connections. Coordinate with DBA to size the connection pool accordingly. Profile PSAPMSGPUBHDR index usage under load before declaring a tuning stable.


Q18. How do you migrate Integration Broker objects across environments and what are the common migration failure points?

A: Export via App Designer project: include Messages, Service Operations, Routings, Transform Programs, App Classes used by transforms, and Permission List assignments. Common failure points: Node definitions are environment-specific and must not be migrated - they must be configured manually per environment. Routing Definitions that reference environment-specific node names will be invalid after migration if node names differ. Transform XSLT files stored as Message Catalog entries must be included separately. Service Operation security (Permission List mapping) is often missed in projects and must be validated post-migration. Always run a Service Operations Monitor smoke test immediately after migration before releasing to integration partners.


Q19. How do you architect IB setup to support a blue-green deployment model for PeopleSoft upgrades?

A: Run two complete PeopleSoft environments (blue=current production, green=upgraded). Point the Integration Gateway to blue by default. During upgrade validation on green, configure a second gateway instance pointing to green with all Node connector URLs updated. External systems continue hitting blue gateway. On cutover, update the load balancer or DNS to route external traffic to the green gateway. IB queue tables are in the database - during transition, ensure the green environment's database has replayed all pending messages from blue's queue before blue is retired. For zero-loss cutover, drain the blue queue completely (confirm PSAPMSGPUBHDR row count for "New"/"Working" = 0) before switching traffic to green.


Q20. A regulatory audit requires a complete log of every message payload sent and received through Integration Broker for the past 3 years. How do you architect this retrospectively and going forward?

A: Retrospectively: if Non-Repudiation was not enabled, payload data in PSAPMSGPUBCON/PSAPMSGSUBCON may have been purged - this is a gap that must be disclosed to the audit. Going forward: enable Archive Store on all regulated Service Operations immediately. Extend the IB Archive purge retention to 7 years in the IUARCH process parameters. Move PSAPMSGARCH to a dedicated compliance tablespace with WORM (Write Once Read Many) storage if the regulatory standard requires tamper evidence. Build a compliance reporting App Engine that exports archived payloads to encrypted flat files on a monthly schedule with hash verification. Implement a search interface over PSAPMSGARCH keyed on date range, service operation, and node for auditor self-service queries.


Q21. How do you design the IB setup to handle a scenario where the same inbound message must trigger different processing logic based on message content - not message type?

A: Use a single OnNotify handler as the entry point and implement a content-based routing dispatcher inside the handler using a Strategy or Command pattern in App Class. Parse the message content field that differentiates the routing (document type, business unit, transaction code), then instantiate the appropriate processing class dynamically. Never create multiple service operations for content variants of the same logical message - that fragments your monitoring and security model. Alternatively, use a Routing Filter (PeopleCode-based filter on the Routing Definition) to route to different service operations based on content inspection before the handler fires - but this only works if handler logic separation is clean enough to justify separate operations.


Q22. What is your approach to designing IB integrations for a PeopleSoft HCM environment where PHI/PII data is transmitted to a benefits third-party vendor?

A: Enforce TLS 1.2 minimum on all gateway connectors. Enable WS-Security with message-level encryption using the vendor's public certificate. Implement field-level masking in the transform layer - SSN and date-of-birth fields are encrypted or tokenized in the transform before payload delivery. Configure Non-Repudiation Archive with access controls so only authorized DBA/Security roles can query PSAPMSGARCH. Implement outbound payload logging to a HIPAA-compliant audit store. Ensure the Node definition for the vendor system uses certificate-based authentication - never username/password for PHI transmissions. Conduct a data flow mapping exercise per HIPAA BAA requirements to document exactly which IB service operations carry PHI and ensure all are covered by the security controls.


PeopleSoft Integration Broker – Deep Dive Q&A

Channels · Queues · Services · Operations · REST · Monitoring Status Codes


🔴 CHANNELS & QUEUES


Q1. A channel shows "Paused" in Service Operations Monitor. What are the exact causes and remediation steps?

A: Caused by: a message in Error status blocking a sequential channel, manual pause via Monitor, or domain crash mid-processing. Check PSAPMSGPUBHDR for rows with STATUS=3 (Error) on that channel. Cancel or fix the blocking message, then resume the channel. If domain crashed, validate PSAPMSGDOMVR heartbeat before resuming.


Q2. What is the difference between Sequential and Any Order channel processing and when does choosing wrong cause production failure?

A: Sequential - messages processed in PUBID order, one at a time per channel. Any Order - parallel processing with no ordering guarantee. Choosing Sequential for high-volume channels creates a single-threaded bottleneck. Choosing Any Order for order-dependent transactions (header before detail) causes referential integrity failures on the subscriber side.


Q3. How does PeopleSoft determine which domain processes a message on a specific channel in a clustered setup?

A: The Publication Dispatcher queries PSAPMSGDOMVR for active domains, then claims a batch of messages by updating PSAPMSGPUBHDR with its domain ID atomically. First domain to commit the update owns that batch. Channel-level locking prevents two domains from claiming the same sequential channel simultaneously.


Q4. You have 15 channels all assigned to the same App Server domain. Three channels are high-volume. What is the architectural problem and fix?

A: All 15 channels compete for the same Handler Server pool. High-volume channels starve low-volume channels. Fix: deploy dedicated App Server domains per channel group, assign channel affinity using domain filtering, or increase Handler Server instances and set priority weights per channel in psappsrv.cfg.


Q5. What happens to messages in a channel when you change the channel from Sequential to Any Order in production?

A: Messages already queued in PSAPMSGPUBHDR retain their original processing rules until consumed. The change applies only to newly published messages. In-flight messages on the old sequential lock complete first. This creates a brief mixed-mode window - risky if ordering dependency exists across the transition boundary.


Q6. What are the exact PSAPMSGPUBHDR STATUS values and what does each mean operationally?

A:

  • 0 = New - published, not yet claimed by Dispatcher
  • 1 = Started - Dispatcher claimed, Handler processing
  • 2 = Done - successfully processed
  • 3 = Error - handler threw exception or delivery failed
  • 4 = Cancelled - manually cancelled via Monitor
  • 5 = Timeout - exceeded processing time threshold
  • 7 = Retry - scheduled for retry after transient failure
  • 8 = Edited - payload manually edited via Monitor before resubmit

Q7. How do you purge a channel queue safely in production without message loss for unprocessed messages?

A: Never delete directly from PSAPMSGPUBHDR. Use the delivered IUARCH App Engine with a date filter that only archives STATUS=2 (Done) and STATUS=4 (Cancelled) rows. STATUS=0 (New) and STATUS=3 (Error) rows must be resolved first. Run IUARCH during off-peak with DB transaction size limits to avoid log space exhaustion.


Q8. What is a Weighted Channel and how does it affect Dispatcher behavior?

A: Weighted Channels assign priority scores to channels so the Dispatcher claims higher-weight channel batches preferentially when Handler capacity is constrained. A channel with weight 10 gets approximately 10x more Handler assignments than a weight-1 channel under load. Used to guarantee SLA for critical business channels during peak load.



🔴 SERVICES & SERVICE OPERATIONS


Q9. What is the architectural distinction between a Service and a Service Operation in Integration Broker?

A: A Service is a logical grouping container - it represents a business capability (EmployeeService, InvoiceService). A Service Operation is the specific action within that service (GET_EMPLOYEE, CREATE_INVOICE) with its own handler, routing, versioning, and security. Multiple operations belong to one service. The WSDL is generated at the Service level, not the operation level.


Q10. A Service Operation is active, routing is active, but inbound messages return "Service Operation not found". What are the exact checks?

A: Verify the operation name in the inbound SOAP/REST header exactly matches - case-sensitive. Confirm the operation VERSION in the message header matches an active version on the definition. Check the inbound Node name in the message matches a Node definition registered in PeopleTools. Confirm the routing has the correct sender node - not just the operation being active. Verify Permission List assignment for the authenticating user includes this operation with at least Read access.


Q11. How do you version a Service Operation without breaking existing consumers?

A: Create VERSION 2 of the operation. Mark VERSION 1 as active (do not deactivate). Create a separate V2 routing. External consumers explicitly request V2 by including the version in the SOAP header or REST URI. V1 consumers continue unaffected. Deprecation notice goes to V1 consumers with a migration timeline. Never modify a live operation's message schema in place.


Q12. What is the Any-to-Local routing pattern and what are its security risks?

A: Any-to-Local routing accepts inbound messages from ANY external node without explicit node matching. Convenient for open APIs but a significant security risk - any caller that can reach the gateway can invoke the operation. In production, always replace Any-to-Local with explicit node-to-local routings with node-level authentication enforced.


Q13. How does the Service Operation security model interact with IB Node authentication?

A: Two independent security layers. Node authentication (password/certificate) validates that the calling system is who it claims to be - gateway layer. Permission List assignment on the Service Operation validates that the authenticated user ID associated with that node has rights to invoke the operation - App Server layer. Both must pass. Node auth passing but Permission List missing returns HTTP 403 equivalent at the IB layer.


Q14. What is the operational impact of setting a Service Operation to "Pause on Error" versus "Continue on Error"?

A: Pause on Error - first failed message stops all subsequent messages on the channel for that operation. Protects data integrity when messages are order-dependent. Continue on Error - failed message is marked Error and skipped, next message processes. Used for independent messages where one failure should not block others. Wrong choice here causes either cascading failures or silent data gaps in production.



🔴 REST API - SETUP, DESIGN & TROUBLESHOOTING


Q15. How does PeopleSoft implement REST service operations and what are the structural differences from SOAP operations?

A: REST operations define HTTP Method (GET/POST/PUT/DELETE), URI Template with path parameters, and use the RestRequest/RestResponse objects in handlers instead of Message rowsets. No WSDL - consumers use the URI pattern directly. Authentication via Basic Auth, OAuth token, or cookie-based SSO. Payload format is JSON or XML - no SOAP envelope wrapping. Handler accesses parameters via %IntBroker.GetRequestDocument() and %IntBroker.GetURITemplateValues().


Q16. What are the exact HTTP status codes returned by PeopleSoft REST service operations and what triggers each?

A:

  • 200 OK - Successful GET or sync operation response
  • 201 Created - Successful POST that created a resource
  • 400 Bad Request - Malformed URI, missing required parameter, schema validation failure
  • 401 Unauthorized - Authentication failed at gateway (bad credentials, expired token)
  • 403 Forbidden - Node authenticated but Permission List denies access to the operation
  • 404 Not Found - URI template does not match any active REST service operation
  • 405 Method Not Allowed - HTTP method not matching the defined operation method
  • 500 Internal Server Error - Handler PeopleCode threw unhandled exception
  • 503 Service Unavailable - App Server Jolt connection pool exhausted or domain down

Q17. How do you construct a URI Template for a REST GET operation that retrieves an employee by EmplID and as-of date?

A: URI Template: /employee/{EMPLID}/asofdate/{EFFDT}. In the OnRequest handler, retrieve values using %IntBroker.GetURITemplateValues() which returns a rowset with the path parameter name-value pairs. Validate parameter formats before DB access. The full external URL becomes: https://<gateway>/PSIGW/RESTListeningConnector/<node>/employee/E001/asofdate/2024-01-01.


Q18. A REST POST operation returns 400 Bad Request but the payload appears valid. What are the non-obvious causes?

A: Content-Type header missing or set to text/plain instead of application/json or application/xml - gateway rejects before reaching handler. URI template mismatch - extra trailing slash or case difference. Character encoding issue - BOM character in JSON payload from certain clients. Required URI template parameter missing even when body payload is present. Message schema validation failure on a field the caller thinks is optional but PeopleSoft schema marks required.


Q19. How do you implement OAuth 2.0 token validation for an inbound PeopleSoft REST API?

A: PeopleSoft does not natively validate OAuth tokens at the IB layer in older PeopleTools versions. Pattern: configure the REST operation with No Authentication at IB level, place a reverse proxy (API Gateway - Kong, Apigee) in front of the PeopleSoft gateway that validates the OAuth token and strips it before forwarding to PeopleSoft with a trusted internal header. In PeopleTools 8.59+, STS (Security Token Service) integration allows native OAuth token validation at the gateway. The handler receives a validated identity via the STS-resolved user context.


Q20. REST service operation works in IB Tester but fails when called by the external system with a 404. What is the diagnostic path?

A: IB Tester bypasses the gateway and calls the engine directly - so gateway routing is not tested. External 404 means the gateway cannot resolve the URI to an operation. Check the exact URI the external caller is using - node name segment in the URL must exactly match the local node name, case-sensitive. Confirm the REST service operation is published to the gateway (Services > Provide Web Service). Check if the gateway requires a context root prefix the external caller is omitting. Review gateway access log for the raw incoming URI to compare against the registered template.


Q21. How do you design pagination for a PeopleSoft REST GET operation returning large result sets?

A: Define URI template with query parameters: /employees?page={PAGE}&pagesize={PAGESIZE}. Retrieve via %IntBroker.GetRequestDocument() parsing the query string. In the handler, implement SQL-level pagination using ROWNUM (Oracle) or OFFSET/FETCH (SQL Server) against the query. Return a response JSON with totalCount, page, pageSize, and data array. Set appropriate response headers (X-Total-Count) via %IntBroker.SetResponseDocument(). Never return unbounded result sets from a REST GET - enforce a maximum pagesize cap in the handler.


Q22. How do you handle REST inbound payload validation before business logic executes in the OnRequest handler?

A: Implement a dedicated Validator App Class called first within OnRequest. Parse the incoming JSON/XML via %IntBroker.GetRequestDocument(). Validate required fields, data types, and business key existence. On validation failure, set HTTP response code to 400 using %IntBroker.SetHTTPResponseCode(400), populate a structured error response JSON with field-level error details, and return immediately without reaching business logic. This prevents partial processing and gives callers actionable error information.



🔴 MONITORING - STATUS CODES & OPERATIONAL PATTERNS


Q23. What are the complete Subscription Contract status codes in PSAPMSGSUBHDR and what does each indicate?

A:

  • 0 = New - received, awaiting Subscription Dispatcher pickup
  • 1 = Started - Dispatcher assigned to Handler
  • 2 = Done - OnNotify/OnRequest handler completed successfully
  • 3 = Error - handler threw exception, message in error queue
  • 4 = Cancelled - manually cancelled via Monitor
  • 5 = Timeout - handler exceeded timeout threshold
  • 6 = Held - manually held pending investigation
  • 7 = Retry - queued for automatic retry

Q24. What does a large volume of STATUS=7 (Retry) rows in PSAPMSGPUBHDR indicate architecturally?

A: Indicates systemic transient failures on the target endpoint - network instability, target system throttling, or SSL handshake intermittency. Retry rows consume Dispatcher cycles repeatedly without clearing. If retry exhaustion occurs, they move to STATUS=3 (Error). Architectural fix: implement circuit breaker pattern in the outbound connector configuration - detect repeated failures on a node and temporarily suspend delivery, alerting operations rather than endlessly retrying.


Q25. In Service Operations Monitor, what is the difference between Publication Contracts and Publication Details views and when do you use each?

A: Publication Contracts shows the outbound message delivery contract per target node - one row per target per message, showing delivery status to that specific node. Publication Details shows the raw message content and header metadata. Use Contracts view to diagnose multi-target fan-out failures where one node succeeded and another failed. Use Details view to inspect actual payload for content debugging or audit.


Q26. How do you correlate an IB message failure to a specific TUXEDO server process for root cause analysis?

A: PSAPMSGPUBHDR contains the HANDLRID column which stores the TUXEDO server instance ID that processed the message. Cross-reference with APPSRV.LOG filtering on that server instance and the message timestamp to get the exact PeopleCode stack trace. On UNIX, tmadmin command psr shows current server instances - match the instance ID to confirm if that Handler process is still running or crashed.


Q27. A business unit reports that messages are being processed but business data is not updating. Monitor shows STATUS=2 (Done). How do you investigate?

A: STATUS=2 means the handler completed without exception - not that business logic succeeded. The handler may be silently swallowing exceptions, committing a partial transaction, or routing to the wrong business logic branch. Check if the handler has a bare catch block that logs but does not re-throw. Inspect the Non-Repudiation Archive payload to confirm the received data matches expected values. Add explicit audit logging inside the handler at the business logic decision points. This is a handler design defect - Done status should only be set when business processing is fully confirmed.


Q28. How do you build a proactive IB health monitoring dashboard without using third-party tools?

A: Build a custom App Engine on a 15-minute scheduler that queries: PSAPMSGPUBHDR for STATUS=3 count by channel, STATUS=0 rows older than 10 minutes (Dispatcher lag indicator), STATUS=7 retry volume trend. PSAPMSGDOMVR for stale heartbeats (domain down indicator). Write results to a custom IB_HEALTH table. Build a PeopleSoft Pivot Grid or a simple IScript-based dashboard over IB_HEALTH with threshold-based color coding. Trigger email alerts via PeopleTools Notification Framework when thresholds breach. This gives operations a real-time view without PUM updates or third-party APM licensing.


Q29. What monitoring query would you write to identify channels that are at risk of blocking due to accumulated errors?

A: Query PSAPMSGPUBHDR grouping by CHNLNAME where STATUS=3, ordered by count descending, joined to PSAPMSGPUBHDR for the oldest error timestamp per channel. Channels with more than 1 error AND sequential processing type AND oldest error timestamp greater than 30 minutes are immediate intervention candidates. Schedule this as a monitor App Engine with auto-alert on breach - do not rely on manual Monitor checks in production.


Q30. During a production incident, operations manually edits and resubmits a message (STATUS=8 → resubmit). What are the risks and controls you enforce?

A: Risks: edited payload bypasses original validation, creates data inconsistency if partial processing already occurred, no audit trail by default of what was changed. Controls to enforce: restrict Monitor edit access to a dedicated IB-Operations role only. Mandate dual approval - editor and approver - before resubmit. Enable non-repudiation on all critical operations so both original and edited payload are archived. Log all manual edits to a custom IB_EDIT_AUDIT table capturing user ID, timestamp, original payload hash, and modified payload hash. Never allow business users direct access to the Service Operations Monitor in production.


PeopleSoft Integration Broker - SOAP vs REST, WADL vs WSDL, GET & POST Examples


SOAP vs REST API in PeopleSoft IB


Dimension

SOAP

REST

Protocol

Strictly HTTP/HTTPS with SOAP Envelope

HTTP/HTTPS - protocol-agnostic

Message Format

XML only - SOAP Envelope > Header > Body

JSON, XML, Plain Text

Contract

WSDL mandatory

WADL optional - URI template is the contract

Operation Type

Any (Sync/Async)

Primarily Sync - GET, POST, PUT, DELETE

PeopleSoft Handler Object

Message Rowset / XmlDoc

RestRequest / RestResponse via GetRequestDocument

Security

WS-Security, Username Token, Certificate

Basic Auth, OAuth, Cookie/SSO, API Key

Error Handling

SOAP Fault envelope returned

HTTP Status Codes (400, 401, 403, 500)

Versioning

Message Version in SOAP Header

URI path versioning (/v1/, /v2/)

WSDL/WADL Generation

Auto-generated from Service definition

WADL auto-generated - rarely used by consumers

Monitoring Status

Publication/Subscription Contract

Same monitor - REST ops appear under Synchronous tab

Payload Overhead

High - envelope wrapping adds size

Low - lean payload

PeopleSoft Connector

HTTPTARGET / PSFTTARGET

RESTListeningConnector / RESTTargetConnector

Transformation

XSLT on Message object

XSLT or App Class on RestDocument

PeopleTools Support From

PeopleTools 8.4x

PeopleTools 8.51+


WADL vs WSDL in PeopleSoft IB


Dimension

WSDL

WADL

Full Form

Web Services Description Language

Web Application Description Language

Applies To

SOAP Service Operations

REST Service Operations

Format

XML - strict schema

XML - lighter schema

Generated From

PeopleTools > Service > Provide Web Service

PeopleTools > Service > REST Service > Generate WADL

Describes

Operations, Messages, Bindings, Port Types, Types

Resources, Methods, URI Templates, Parameters, Representations

Consumer Usage

Required by SOAP clients to generate stubs

Rarely consumed - most REST clients use URI docs directly

Versioning

New WSDL per Message version

New WADL per URI template version

Endpoint Definition

WSDL contains exact endpoint URL

WADL contains base URI + resource paths

Industry Adoption

Mandatory for enterprise SOAP integrations

Largely replaced by OpenAPI/Swagger in modern REST

PeopleSoft Location

Automatically published via Provide Web Service wizard

Generated on demand - not auto-published

Schema Embedded

XSD types embedded in WSDL Types section

Representations defined inline or by reference

Tooling Support

Wide - SOAPUI, Postman, Java stubs

Limited - most teams skip WADL and use Postman collections


COMPLETE EXAMPLE 1 - REST GET METHOD

Scenario: PeopleSoft calls a Third-Party Employee Verification API to retrieve employee background check status by Employee ID


STEP 1 - Create Message Definition

PeopleTools > Integration Broker > Integration Setup > Messages

 

Message Name     : EMP_BGCHECK_RESPONSE

Message Type     : Nonrowset-based

Direction        : Inbound (response from third party)

Version          : VERSION_1


STEP 2 - Create Service and Service Operation

PeopleTools > Integration Broker > Integration Setup > Services

 

Service Name     : EMP_VERIFICATION_SVC

Service Type     : Provided (we are the consumer - use Consumed)

 

Service Operation Name   : GET_BGCHECK_STATUS

Operation Type           : REST - Synchronous

HTTP Method              : GET

URI Template             : /bgcheck/employee/{EMPLID}/status

Response Message         : EMP_BGCHECK_RESPONSE.VERSION_1


STEP 3 - Create External Node for Third-Party System

PeopleTools > Integration Broker > Integration Setup > Nodes

 

Node Name            : BGCHECK_VENDOR

Node Type            : External

Authentication Option: Basic Authentication

User Name            : api_svc_user

Password             : <encrypted>

Connector ID         : HTTPTARGET

Primary URL          : https://api.bgcheckvendor.com


STEP 4 - Create Routing Definition

PeopleTools > Integration Broker > Integration Setup > Routings

 

Routing Name         : GET_BGCHECK_RT_01

Service Operation    : GET_BGCHECK_STATUS.VERSION_1

Sender Node          : PSFT_LOCAL

Receiver Node        : BGCHECK_VENDOR

Direction            : Outbound

HTTP Method Override : GET

Connector Properties:

   Header : Authorization = Basic <Base64(user:pass)>

   Header : Accept = application/json

   Header : Content-Type = application/json

URL Property         : https://api.bgcheckvendor.com/bgcheck/employee/{EMPLID}/status

Status               : Active


STEP 5 - Handler App Class (OnRequest - Outbound Consumed GET)

peoplecode

import PS_PT:Integration:IRequestHandler;

 

class GetBgCheckHandler implements PS_PT:Integration:IRequestHandler

   method OnRequest(&_MSG As Message) Returns Message;

   method OnError(&_MSG As Message) Returns string;

end-class;

 

method OnRequest

   /+ &_MSG as Message +/

   /+ Returns Message +/

   /+ Extends/implements PS_PT:Integration:IRequestHandler.OnRequest +/

  

   Local Message  &requestMsg, &responseMsg;

   Local string   &sEmplID, &sStatus, &sResponseJSON;

   Local JsonObject &joResponse;

   Local integer  &iHttpStatus;

  

   /* Step 1: Build outbound REST GET request */

   &requestMsg = CreateMessage(Operation.GET_BGCHECK_STATUS, %IntBroker_Request);

  

   /* Step 2: Set EMPLID as URI template parameter */

   &sEmplID = GetSetProgramVariable(&_MSG, "EMPLID");

   &requestMsg.URIResourceIndex = 1;

   &requestMsg.SetURITemplateValue("EMPLID", &sEmplID);

  

   /* Step 3: Execute synchronous REST call */

   &responseMsg = %IntBroker.SyncRequest(&requestMsg);

  

   /* Step 4: Check HTTP response status */

   &iHttpStatus = &responseMsg.HTTPResponseCode;

  

   If &iHttpStatus = 200 Then

      /* Step 5: Parse JSON response */

      &sResponseJSON = &responseMsg.GetContentString();

      &joResponse    = CreateJsonObject();

      &joResponse.Parse(&sResponseJSON);

     

      &sStatus = &joResponse.GetProperty("bgCheckStatus").GetString();

     

      /* Step 6: Write result to staging table */

      Local SQL &sqlUpdate;

      &sqlUpdate = CreateSQL(

         "UPDATE PS_EMP_BGCHECK_STG SET STATUS = :1, " |

         "LAST_UPD_DTTM = %DateTimeIn(:2) " |

         "WHERE EMPLID = :3",

         &sStatus,

         %DateTime,

         &sEmplID);

     

   Else

      /* Step 7: Log failure with HTTP code */

      Local SQL &sqlError;

      &sqlError = CreateSQL(

         "INSERT INTO PS_IB_ERROR_LOG " |

         "(EMPLID, HTTP_STATUS, ERROR_DTTM, OPERATION) " |

         "VALUES(:1, :2, %DateTimeIn(:3), :4)",

         &sEmplID,

         String(&iHttpStatus),

         %DateTime,

         "GET_BGCHECK_STATUS");

   End-If;

  

   Return &responseMsg;

  

end-method;

 

method OnError

   /+ &_MSG as Message +/

   /+ Returns String +/

   Return "GET_BGCHECK_STATUS failed for node: " | &_MSG.NodeName;

end-method;


STEP 6 - Calling the Integration from Application PeopleCode

peoplecode

/* Called from SavePostChange or Application Engine */

 

Local Message  &reqMsg;

Local string   &sEmplID;

 

&sEmplID = DERIVED_HR.EMPLID;

 

/* Create request message */

&reqMsg = CreateMessage(Operation.GET_BGCHECK_STATUS, %IntBroker_Request);

 

/* Set URI path parameter */

&reqMsg.SetURITemplateValue("EMPLID", &sEmplID);

 

/* Set request headers */

&reqMsg.IBInfo.IBConnectorInfo.AddConnectorProperties(

   "Accept", "application/json", %ConnectorParam);

&reqMsg.IBInfo.IBConnectorInfo.AddConnectorProperties(

   "Authorization", "Basic " | IB_UTILS.GetBase64Creds(), %ConnectorParam);

 

/* Execute synchronous outbound REST GET */

Local Message &respMsg = %IntBroker.SyncRequest(&reqMsg);

 

/* Handle response */

If &respMsg.HTTPResponseCode = 200 Then

   /* Process success */

   MessageBox(0, "", 0, 0, "BG Check Status Retrieved Successfully");

Else

   /* Handle failure */

   MessageBox(0, "", 0, 0, "BG Check API Failed: HTTP " |

              String(&respMsg.HTTPResponseCode));

End-If;


STEP 7 - Monitoring in Service Operations Monitor

PeopleTools > Integration Broker > Service Operations Monitor

> Synchronous Services Tab

 

Field              Value

──────────────────────────────────────────

Operation          GET_BGCHECK_STATUS

Direction          Outbound

Status             Done / Error

HTTP Response Code 200 / 400 / 401 / 500

Node               BGCHECK_VENDOR

Timestamp          Runtime value

Payload View       Raw JSON response visible in Detail

Status Codes During Monitoring:

Code

Meaning in This Context

200

Vendor returned valid BG check status

400

EMPLID format invalid or missing in URI

401

Basic Auth credentials rejected by vendor

403

API key valid but insufficient scope

404

EMPLID not found in vendor system

500

Vendor API internal error

503

Vendor API unavailable - Jolt timeout on return



COMPLETE EXAMPLE 2 - REST POST METHOD

Scenario: Third-Party Payroll System POSTs a payroll confirmation payload into PeopleSoft - PeopleSoft receives, validates, and updates Job record


STEP 1 - Create Request Message

PeopleTools > Integration Broker > Integration Setup > Messages

 

Message Name     : PAYROLL_CONFIRM_REQ

Message Type     : Nonrowset-based

Direction        : Inbound

Schema           : JSON Schema defined inline

Version          : VERSION_1


STEP 2 - Create Service and Service Operation

Service Name         : PAYROLL_INTEGRATION_SVC

 

Service Operation    : POST_PAYROLL_CONFIRM

Operation Type       : REST - Synchronous

HTTP Method          : POST

URI Template         : /payroll/confirmation

Request Message      : PAYROLL_CONFIRM_REQ.VERSION_1

Response Message     : PAYROLL_CONFIRM_RESP.VERSION_1


STEP 3 - Create External Node for Payroll Vendor

Node Name            : PAYROLL_VENDOR_NODE

Node Type            : External

Authentication Option: Basic Authentication

Connector ID         : RESTListeningConnector

Default User         : PAYROLL_SVC_USER   ← mapped to Permission List


STEP 4 - Create Inbound Routing

Routing Name         : POST_PAYROLL_CONFIRM_RT

Service Operation    : POST_PAYROLL_CONFIRM.VERSION_1

Sender Node          : PAYROLL_VENDOR_NODE

Receiver Node        : PSFT_LOCAL (Local Node)

Direction            : Inbound

Status               : Active

 

Connector Override:

   Content-Type      : application/json

   Accept            : application/json


STEP 5 - Permission List Setup

PeopleTools > Security > Permissions & Roles > Permission Lists

 

Permission List      : PAYROLL_IB_PLIST

Service Operation    : POST_PAYROLL_CONFIRM

Access              : Full Access (Read + Write)

 

Assign to Role       : PAYROLL_VENDOR_ROLE

Assign Role to User  : PAYROLL_SVC_USER


STEP 6 - Handler App Class (OnRequest - Inbound POST)

peoplecode

import PS_PT:Integration:IRequestHandler;

 

class PostPayrollConfirmHandler implements PS_PT:Integration:IRequestHandler

   method OnRequest(&_MSG As Message) Returns Message;

   method OnError(&_MSG As Message) Returns string;

end-method;

 

method OnRequest

   /+ &_MSG as Message +/

   /+ Returns Message +/

  

   Local Message    &responseMsg;

   Local string     &sPayload, &sEmplID, &sPayPeriod;

   Local number     &nNetPay;

   Local JsonObject &joReq, &joResp;

   Local SQL        &sqlUpdate;

   Local integer    &iRespCode;

  

   /* Step 1: Read inbound JSON payload */

   &sPayload = &_MSG.GetContentString();

  

   /* Step 2: Parse JSON */

   &joReq    = CreateJsonObject();

   &joReq.Parse(&sPayload);

  

   /* Step 3: Extract fields */

   &sEmplID   = &joReq.GetProperty("employeeId").GetString();

   &sPayPeriod= &joReq.GetProperty("payPeriodEnd").GetString();

   &nNetPay   = &joReq.GetProperty("netPay").GetNumber();

  

   /* Step 4: Validate required fields */

   If None(&sEmplID) Or

      None(&sPayPeriod) Or

      &nNetPay <= 0 Then

     

      /* Return 400 Bad Request */

      &responseMsg = CreateMessage(Operation.POST_PAYROLL_CONFIRM,

                                   %IntBroker_Response);

      &responseMsg.HTTPResponseCode = 400;

     

      &joResp = CreateJsonObject();

      &joResp.AddProperty("status", "ERROR");

      &joResp.AddProperty("message", "Missing or invalid required fields");

      &responseMsg.SetContentString(&joResp.ToString());

      Return &responseMsg;

   End-If;

  

   /* Step 5: Validate EMPLID exists in PeopleSoft */

   Local string &sCheckEmpl;

   SQLExec("SELECT EMPLID FROM PS_PERSONAL_DATA WHERE EMPLID = :1",

           &sEmplID, &sCheckEmpl);

  

   If None(&sCheckEmpl) Then

      &responseMsg = CreateMessage(Operation.POST_PAYROLL_CONFIRM,

                                   %IntBroker_Response);

      &responseMsg.HTTPResponseCode = 404;

      &joResp = CreateJsonObject();

      &joResp.AddProperty("status", "ERROR");

      &joResp.AddProperty("message", "EMPLID not found: " | &sEmplID);

      &responseMsg.SetContentString(&joResp.ToString());

      Return &responseMsg;

   End-If;

  

   /* Step 6: Update Payroll Confirmation staging table */

   &sqlUpdate = CreateSQL(

      "INSERT INTO PS_PAYROLL_CONFIRM_STG " |

      "(EMPLID, PAY_PERIOD_END, NET_PAY, CONFIRM_DTTM, STATUS) " |

      "VALUES(:1, %DateIn(:2), :3, %DateTimeIn(:4), 'P')",

      &sEmplID,

      &sPayPeriod,

      &nNetPay,

      %DateTime);

  

   /* Step 7: Trigger downstream App Engine for Job update */

   Local ProcessRequest &oProcReq;

   &oProcReq = CreateProcessRequest("PAYROLL", "PAYUPDJOB");

   &oProcReq.RunControlID = "PAYROLL_" | &sEmplID;

   &oProcReq.Schedule();

  

   /* Step 8: Build success response */

   &responseMsg = CreateMessage(Operation.POST_PAYROLL_CONFIRM,

                                %IntBroker_Response);

   &responseMsg.HTTPResponseCode = 201;

  

   &joResp = CreateJsonObject();

   &joResp.AddProperty("status", "SUCCESS");

   &joResp.AddProperty("message", "Payroll confirmation accepted");

   &joResp.AddProperty("emplid", &sEmplID);

   &joResp.AddProperty("confirmedAt", String(%DateTime));

  

   &responseMsg.SetContentString(&joResp.ToString());

   Return &responseMsg;

  

end-method;

 

method OnError

   /+ &_MSG as Message +/

   /+ Returns String +/

   Return "POST_PAYROLL_CONFIRM handler error for node: " | &_MSG.NodeName;

end-method;


STEP 7 - Sample Inbound Payload from Payroll Vendor (POST Body)

json

{

  "employeeId"   : "E00123",

  "payPeriodEnd" : "2024-12-31",

  "netPay"       : 4500.00,

  "currency"     : "USD",

  "payGroup"     : "MONTHLY",

  "confirmedBy"  : "PAYROLL_SYS_01"

}


STEP 8 - Sample Success Response Returned to Vendor

json

{

  "status"      : "SUCCESS",

  "message"     : "Payroll confirmation accepted",

  "emplid"      : "E00123",

  "confirmedAt" : "2024-12-31 18:45:22.000000"

}


STEP 9 - Endpoint URL Published to Vendor

https://<psft-gateway-host>/PSIGW/RESTListeningConnector/PSFT_LOCAL/payroll/confirmation


STEP 10 - Monitoring in Service Operations Monitor

PeopleTools > Integration Broker > Service Operations Monitor

> Synchronous Services Tab

 

Field              Value

──────────────────────────────────────────

Operation          POST_PAYROLL_CONFIRM

Direction          Inbound

Node               PAYROLL_VENDOR_NODE

Status             Done / Error

HTTP Response Code 201 / 400 / 404 / 500

Payload (Request)  Raw JSON from vendor

Payload (Response) JSON success/error body

Status Codes During Monitoring:

Code

Meaning in This Context

201

Payroll confirmation successfully accepted and staged

400

Missing employeeId / payPeriodEnd / netPay in payload

401

Vendor not authenticated - Basic Auth failed

403

PAYROLL_SVC_USER missing Permission List assignment

404

EMPLID not found in PS_PERSONAL_DATA

500

Unhandled PeopleCode exception in OnRequest handler

503

App Server down - gateway cannot reach Jolt


End-to-End Flow Summary

VENDOR POST                PSFT GATEWAY              APP SERVER             DATABASE

────────────               ────────────              ──────────             ────────

POST /payroll/confirmation

       

       

  Auth Validation ──── 401 if failed

       

       

  Node Resolution ──── 404 if no routing

       

       

  Jolt Forward ────────────────────────►  OnRequest Handler

                                               

                                         JSON Parse & Validate ── 400 if invalid

                                               

                                         EMPLID Exists Check ──── 404 if not found

                                               

                                         INSERT staging table ──────────────────►

                                               

                                         Schedule App Engine

                                               

                                         Return 201 + JSON ◄──────────────────

       

        ◄────────────────────────────────────────

  Vendor receives

 

PeopleSoft Component Interface + REST Based Web Services

Interview Q&A with Real-Time Examples - 18+ Years Architect Level


SECTION 1 - CI-REST ARCHITECTURE & DESIGN Q&A


Q1. What is the architectural relationship between a Component Interface and a REST Service Operation in PeopleSoft?

A: CI encapsulates PeopleSoft business logic, validations, and component buffer processing. REST Service Operation is the transport layer. The OnRequest handler instantiates the CI, drives it programmatically, and returns the result as JSON via RestResponse. CI enforces all PeopleCode SaveEdit, SavePreChange, SavePostChange events - REST is purely the delivery mechanism. The CI is never bypassed; it remains the single source of truth for business rule enforcement regardless of the calling channel.


Q2. Why is CI preferred over direct SQL in a REST handler for write operations?

A: CI fires all component-level PeopleCode events - field defaults, cross-field validations, derived field calculations, workflow triggers, and audit logging - exactly as the online component does. Direct SQL bypasses all of this, creating data inconsistency. In an 18-year PeopleSoft landscape, every critical table has SaveEdit logic that must fire. CI enforces that contract programmatically.


Q3. What are the failure modes specific to CI usage inside a REST OnRequest handler?

A: CI instantiation failure if the CI definition is not deployed or marked inactive. Get() returning False when the key does not exist - must be handled before accessing properties. Save() returning False silently when validation fails - must check %IntBroker.IBException and CI error collection. Component buffer not being reset between calls in a long-running handler - causes data bleed between transactions. CI running in wrong mode (Find, Get, Add) for the operation type.


Q4. How does CI handle multi-level scroll data in a REST POST payload?

A: CI exposes scroll levels via GetLevel0(), GetLevel1(), GetLevel2() collection objects. In the handler, iterate the JSON array for each child level, instantiate the corresponding CI collection item, and set properties at each level independently. Parent key must be set at Level 0 before Level 1 items are added using InsertItem(). Commit sequence - Level 0 first, then child scrolls - is mandatory.


Q5. What is the difference between CI running in Interactive mode versus Non-Interactive mode in a REST context?

A: Interactive mode fires all component PeopleCode events including FieldChange and RowInit - identical to online user interaction. Non-Interactive mode skips FieldChange and RowInit events, runs faster, but risks missing field-level defaulting logic. REST handlers must use Interactive mode for write operations where field-level defaults are business-critical. Non-Interactive is acceptable for read-only GET operations where only data retrieval is needed.


Q6. How do you handle CI-level errors and return structured error responses to the REST caller?

A: After CI.Save(), check CI.PSMessages collection for error-level messages. Iterate the collection, extract MessageSetNumber, MessageNumber, and MessageText. Build a JSON error array with field-level detail. Set %IntBroker.SetHTTPResponseCode(400) and return the error JSON. Never return a generic 500 for CI validation failures - the caller needs field-level error detail to correct and resubmit.


Q7. How do you expose a CI-based REST API that supports both GET (read) and POST (create) on the same resource URI?

A: Create two separate Service Operations on the same Service - one with HTTP Method GET and one with HTTP Method POST - both using the same URI base path. PeopleSoft routes by HTTP method to the correct operation. GET operation handler uses CI.Get() mode and returns data. POST operation handler uses CI.Add() mode and calls CI.Save(). Both share the same URI template but have independent handlers, routings, and Permission List assignments.


Q8. What are the concurrency risks when a CI-based REST API receives parallel POST requests for the same EMPLID?

A: CI internally uses component buffer locking tied to the primary key. Parallel POSTs for the same EMPLID will cause the second request to hit a lock wait at CI.Get() or CI.Save(). In high-concurrency scenarios, implement an application-level optimistic locking pattern - include a version timestamp in the POST payload, validate it in the handler before CI.Save(), and return HTTP 409 Conflict if the record was modified between the GET and POST calls.


Q9. How do you design a CI-REST API that a third-party HRMS system uses to create and update employee personal data?

A: Expose two operations: POST /employee using PERSONAL_DATA CI in Add mode for creates, returning 201 with the new EMPLID. PUT /employee/{EMPLID} using Get mode for updates, returning 200. Both handlers validate payload schema first, then drive CI. EMPLID generation on create uses the PeopleSoft auto-numbering via CI - never generate EMPLID externally. CI enforces Name format validation, National ID uniqueness, and effective date logic automatically.


Q10. What is the impact of session isolation on CI-based REST handlers under high concurrency?

A: Each REST request runs in its own App Server TUXEDO service call with an isolated component buffer session. CI instantiation per request creates a fresh buffer context - no shared state between concurrent requests. The risk is DB connection pool exhaustion when concurrent CI operations hold connections open during long Save() operations. Tune Handler Server pool and DB connection pool in tandem - each concurrent CI-REST call holds one DB connection for the duration of the transaction.



 SECTION 2 - REAL-TIME EXAMPLE

Scenario: Third-Party Talent Acquisition System creates a New Hire in PeopleSoft HCM using CI-based REST POST API, then retrieves the created record via REST GET


EXAMPLE PART A - REST POST: Create New Hire via PERSONAL_DATA CI


STEP 1 - Identify CI Definition

PeopleTools > Application Designer > Component Interface

 

CI Name              : PERSONAL_DATA_CI

Based on Component   : PERSONAL_DATA

Exposed Collections  : Level 0 - PERSONAL_DATA

                       Level 1 - NAMES

                       Level 1 - ADDRESSES

                       Level 1 - NATIONAL_ID

Keys                 : EMPLID (Get Key), EFFDT (not applicable for add)

Methods Exposed      : Get, Create, Save, Cancel, Find


STEP 2 - Create Request and Response Message Definitions

Message Name     : NEWHIRE_CREATE_REQ

Type             : Nonrowset-based

Schema           : JSON

Version          : VERSION_1

 

Message Name     : NEWHIRE_CREATE_RESP

Type             : Nonrowset-based

Schema           : JSON

Version          : VERSION_1


STEP 3 - Create Service and POST Service Operation

Service Name         : NEWHIRE_ONBOARDING_SVC

 

Service Operation    : POST_NEWHIRE_CREATE

HTTP Method          : POST

URI Template         : /newhire/create

Request Message      : NEWHIRE_CREATE_REQ.VERSION_1

Response Message     : NEWHIRE_CREATE_RESP.VERSION_1

Operation Type       : REST Synchronous

Handler Class        : NEWHIRE_IB_HANDLER:PostNewHireHandler

Handler Method       : OnRequest


STEP 4 - Create Inbound Node and Routing

Node Name            : TALENT_ACQ_NODE

Node Type            : External

Authentication       : Basic Authentication

Default User         : TALENT_SVC_USR

 

Routing Name         : POST_NEWHIRE_RT

Sender Node          : TALENT_ACQ_NODE

Receiver Node        : PSFT_LOCAL

Operation            : POST_NEWHIRE_CREATE.VERSION_1

Direction            : Inbound

Status               : Active

Content-Type Header  : application/json


STEP 5 - Permission List Setup

Permission List      : TALENT_IB_PLIST

Operation            : POST_NEWHIRE_CREATE - Full Access

Role                 : TALENT_VENDOR_ROLE

User ID              : TALENT_SVC_USR


STEP 6 - Inbound JSON Payload from Talent Acquisition System

json

{

  "firstName"      : "Harish",

  "lastName"       : "Kumar",

  "dateOfBirth"    : "1985-06-15",

  "gender"         : "M",

  "nationalId"     : "XXX-XX-1234",

  "nationalIdType" : "PR",

  "country"        : "USA",

  "hireDate"       : "2024-01-15",

  "addressLine1"   : "123 Main Street",

  "city"           : "Dallas",

  "state"          : "TX",

  "postalCode"     : "75001",

  "email"          : "harish.kumar@company.com"

}


STEP 7 - Handler App Class: POST New Hire via CI

peoplecode

import PS_PT:Integration:IRequestHandler;

import PSXP_XMLGEN:RowSetCache;

 

class PostNewHireHandler implements PS_PT:Integration:IRequestHandler

   method OnRequest(&_MSG As Message) Returns Message;

   method OnError(&_MSG As Message) Returns string;

end-class;

 

method OnRequest

   /+ &_MSG as Message +/

   /+ Returns Message +/

 

   Local Message     &respMsg;

   Local JsonObject  &joReq, &joResp, &joError;

   Local JsonArray   &jaErrors;

   Local string      &sPayload, &sEmplID;

   Local boolean     &bSaveOK;

 

   /* ── Step 1: Read and parse inbound JSON ── */

   &sPayload = &_MSG.GetContentString();

   &joReq    = CreateJsonObject();

 

   try

      &joReq.Parse(&sPayload);

   catch Exception &exParse

      &respMsg = CreateMessage(Operation.POST_NEWHIRE_CREATE,

                               %IntBroker_Response);

      &respMsg.HTTPResponseCode = 400;

      &joResp = CreateJsonObject();

      &joResp.AddProperty("status", "ERROR");

      &joResp.AddProperty("message", "Invalid JSON payload");

      &respMsg.SetContentString(&joResp.ToString());

      Return &respMsg;

   end-try;

 

   /* ── Step 2: Validate required fields ── */

   Local string &sFirst, &sLast, &sDOB, &sGender;

   Local string &sNatID, &sNatIDType, &sCountry;

   Local string &sHireDate, &sAddr1, &sCity;

   Local string &sState, &sZip, &sEmail;

 

   &sFirst      = &joReq.GetProperty("firstName").GetString();

   &sLast       = &joReq.GetProperty("lastName").GetString();

   &sDOB        = &joReq.GetProperty("dateOfBirth").GetString();

   &sGender     = &joReq.GetProperty("gender").GetString();

   &sNatID      = &joReq.GetProperty("nationalId").GetString();

   &sNatIDType  = &joReq.GetProperty("nationalIdType").GetString();

   &sCountry    = &joReq.GetProperty("country").GetString();

   &sHireDate   = &joReq.GetProperty("hireDate").GetString();

   &sAddr1      = &joReq.GetProperty("addressLine1").GetString();

   &sCity       = &joReq.GetProperty("city").GetString();

   &sState      = &joReq.GetProperty("state").GetString();

   &sZip        = &joReq.GetProperty("postalCode").GetString();

   &sEmail      = &joReq.GetProperty("email").GetString();

 

   If None(&sFirst) Or None(&sLast) Or

      None(&sDOB)   Or None(&sNatID) Or

      None(&sHireDate) Then

 

      &respMsg = CreateMessage(Operation.POST_NEWHIRE_CREATE,

                               %IntBroker_Response);

      &respMsg.HTTPResponseCode = 400;

      &joResp = CreateJsonObject();

      &joResp.AddProperty("status", "ERROR");

      &joResp.AddProperty("message",

         "Required fields missing: firstName, lastName, " |

         "dateOfBirth, nationalId, hireDate");

      &respMsg.SetContentString(&joResp.ToString());

      Return &respMsg;

   End-If;

 

   /* ── Step 3: Generate next EMPLID from PeopleSoft sequence ── */

   SQLExec("SELECT LTRIM(TO_CHAR(PS_EMPLID_SEQ.NEXTVAL)) FROM DUAL",

           &sEmplID);

   /* Pad to 11 characters per PeopleSoft EMPLID format */

   &sEmplID = LPad(&sEmplID, 11, "0");

 

   /* ── Step 4: Instantiate PERSONAL_DATA CI in Add mode ── */

   Local ApiObject &oSession, &oCI;

   Local ApiObject &oLevel0, &oNames, &oAddresses, &oNatID;

 

   &oSession = %Session;

   &oSession.PSMessagesMode = 1; /* Collect all messages */

 

   &oCI = &oSession.GetCompIntfc(CompIntfc.PERSONAL_DATA_CI);

   &oCI.InteractiveMode = True;

   &oCI.GetHistoryItems = False;

   &oCI.EditHistoryItems = False;

 

   /* Set Add mode key */

   &oCI.EMPLID = &sEmplID;

 

   If Not &oCI.Create() Then

      &respMsg = CreateMessage(Operation.POST_NEWHIRE_CREATE,

                               %IntBroker_Response);

      &respMsg.HTTPResponseCode = 500;

      &joResp = CreateJsonObject();

      &joResp.AddProperty("status", "ERROR");

      &joResp.AddProperty("message", "CI Create() failed for EMPLID: "

                                     | &sEmplID);

      &respMsg.SetContentString(&joResp.ToString());

      Return &respMsg;

   End-If;

 

   /* ── Step 5: Set Level 0 - PERSONAL_DATA fields ── */

   &oLevel0 = &oCI.GetLevel0().Item(1);

   &oLevel0.EMPLID      = &sEmplID;

   &oLevel0.SEX         = &sGender;

   &oLevel0.BIRTHDATE   = Date3(

      Value(Substring(&sDOB, 1, 4)),

      Value(Substring(&sDOB, 6, 2)),

      Value(Substring(&sDOB, 9, 2)));

   &oLevel0.DT_OF_HIRE  = Date3(

      Value(Substring(&sHireDate, 1, 4)),

      Value(Substring(&sHireDate, 6, 2)),

      Value(Substring(&sHireDate, 9, 2)));

   &oLevel0.COUNTRY     = &sCountry;

   &oLevel0.EMAIL_ADDR  = &sEmail;

 

   /* ── Step 6: Set Level 1 - NAMES scroll ── */

   &oNames = &oCI.NAMES.Item(1);

   If &oNames = Null Then

      &oNames = &oCI.NAMES.InsertItem(1);

   End-If;

   &oNames.NAME_TYPE    = "PRI";

   &oNames.LAST_NAME    = &sLast;

   &oNames.FIRST_NAME   = &sFirst;

   &oNames.EFFDT        = %Date;

 

   /* ── Step 7: Set Level 1 - ADDRESSES scroll ── */

   &oAddresses = &oCI.ADDRESSES.Item(1);

   If &oAddresses = Null Then

      &oAddresses = &oCI.ADDRESSES.InsertItem(1);

   End-If;

   &oAddresses.ADDRESS_TYPE = "HOME";

   &oAddresses.EFFDT        = %Date;

   &oAddresses.ADDRESS1     = &sAddr1;

   &oAddresses.CITY         = &sCity;

   &oAddresses.STATE        = &sState;

   &oAddresses.POSTAL       = &sZip;

   &oAddresses.COUNTRY      = &sCountry;

 

   /* ── Step 8: Set Level 1 - NATIONAL_ID scroll ── */

   &oNatID = &oCI.NATIONAL_ID.Item(1);

   If &oNatID = Null Then

      &oNatID = &oCI.NATIONAL_ID.InsertItem(1);

   End-If;

   &oNatID.COUNTRY        = &sCountry;

   &oNatID.NATIONAL_ID_TYPE = &sNatIDType;

   &oNatID.NATIONAL_ID    = &sNatID;

   &oNatID.PRIMARY_NID    = "Y";

 

   /* ── Step 9: Save via CI ── */

   &bSaveOK = &oCI.Save();

 

   If Not &bSaveOK Then

      /* Collect CI error messages */

      &jaErrors = CreateJsonArray();

      Local integer &i;

      For &i = 1 To &oSession.PSMessages.Count

         Local PSMessage &oMsg = &oSession.PSMessages.Item(&i);

         If &oMsg.Type = %MsgTypeError Then

            Local JsonObject &joErrItem = CreateJsonObject();

            &joErrItem.AddProperty("msgSet",

                                   String(&oMsg.MessageSetNumber));

            &joErrItem.AddProperty("msgNum",

                                   String(&oMsg.MessageNumber));

            &joErrItem.AddProperty("text", &oMsg.Text);

            &jaErrors.Push(&joErrItem);

         End-If;

      End-For;

 

      &respMsg = CreateMessage(Operation.POST_NEWHIRE_CREATE,

                               %IntBroker_Response);

      &respMsg.HTTPResponseCode = 422;

      &joResp = CreateJsonObject();

      &joResp.AddProperty("status", "VALIDATION_ERROR");

      &joResp.AddProperty("emplid", &sEmplID);

      &joResp.AddJsonArray("errors", &jaErrors);

      &respMsg.SetContentString(&joResp.ToString());

      Return &respMsg;

   End-If;

 

   /* ── Step 10: Build 201 success response ── */

   &respMsg = CreateMessage(Operation.POST_NEWHIRE_CREATE,

                            %IntBroker_Response);

   &respMsg.HTTPResponseCode = 201;

 

   &joResp = CreateJsonObject();

   &joResp.AddProperty("status", "SUCCESS");

   &joResp.AddProperty("emplid", &sEmplID);

   &joResp.AddProperty("message", "New hire created successfully");

   &joResp.AddProperty("createdAt", String(%DateTime));

 

   &respMsg.SetContentString(&joResp.ToString());

   Return &respMsg;

 

end-method;

 

method OnError

   /+ &_MSG as Message +/

   /+ Returns String +/

   Return "POST_NEWHIRE_CREATE failed. Node: " | &_MSG.NodeName;

end-method;


STEP 8 - Success Response Returned to Talent System

json

{

  "status"    : "SUCCESS",

  "emplid"    : "00000001234",

  "message"   : "New hire created successfully",

  "createdAt" : "2024-01-15 10:32:45.000000"

}


STEP 9 - Validation Error Response (HTTP 422)

json

{

  "status" : "VALIDATION_ERROR",

  "emplid" : "00000001234",

  "errors" : [

    {

      "msgSet" : "1000",

      "msgNum" : "245",

      "text"   : "National ID already exists for another employee"

    },

    {

      "msgSet" : "1000",

      "msgNum" : "312",

      "text"   : "Date of Birth cannot be after Hire Date"

    }

  ]

}


STEP 10 - Monitoring Status Codes for POST_NEWHIRE_CREATE

HTTP Code

Trigger

201

CI.Save() succeeded - new hire created

400

Missing required JSON fields or parse failure

401

TALENT_SVC_USR Basic Auth failed at gateway

403

TALENT_IB_PLIST not assigned to TALENT_SVC_USR

422

CI.Save() returned False - PeopleSoft validation errors

500

CI.Create() failed or unhandled PeopleCode exception

503

App Server Jolt pool exhausted



EXAMPLE PART B - REST GET: Retrieve Created Employee via PERSONAL_DATA CI


STEP 1 - Create GET Service Operation

Service Name         : NEWHIRE_ONBOARDING_SVC  (same service)

 

Service Operation    : GET_EMPLOYEE_PROFILE

HTTP Method          : GET

URI Template         : /employee/{EMPLID}/profile

Response Message     : EMP_PROFILE_RESP.VERSION_1

Operation Type       : REST Synchronous

Handler Class        : NEWHIRE_IB_HANDLER:GetEmployeeHandler

Handler Method       : OnRequest


STEP 2 - Inbound Routing for GET

Routing Name         : GET_EMPLOYEE_PROFILE_RT

Sender Node          : TALENT_ACQ_NODE

Receiver Node        : PSFT_LOCAL

Operation            : GET_EMPLOYEE_PROFILE.VERSION_1

Direction            : Inbound

Status               : Active


STEP 3 - Handler App Class: GET Employee via CI

peoplecode

import PS_PT:Integration:IRequestHandler;

 

class GetEmployeeHandler implements PS_PT:Integration:IRequestHandler

   method OnRequest(&_MSG As Message) Returns Message;

   method OnError(&_MSG As Message) Returns string;

end-class;

 

method OnRequest

   /+ &_MSG as Message +/

   /+ Returns Message +/

 

   Local Message    &respMsg;

   Local JsonObject &joResp;

   Local string     &sEmplID;

 

   /* ── Step 1: Extract EMPLID from URI template ── */

   Local array of string &aKeys;

   &aKeys   = &_MSG.GetURITemplateValues();

   &sEmplID = &aKeys.Get(1); /* {EMPLID} is first template param */

 

   If None(&sEmplID) Then

      &respMsg = CreateMessage(Operation.GET_EMPLOYEE_PROFILE,

                               %IntBroker_Response);

      &respMsg.HTTPResponseCode = 400;

      &joResp = CreateJsonObject();

      &joResp.AddProperty("status", "ERROR");

      &joResp.AddProperty("message", "EMPLID is required in URI");

      &respMsg.SetContentString(&joResp.ToString());

      Return &respMsg;

   End-If;

 

   /* ── Step 2: Instantiate CI in Get mode ── */

   Local ApiObject &oSession, &oCI;

   Local ApiObject &oLevel0, &oNames, &oAddr, &oNatID;

 

   &oSession = %Session;

   &oCI = &oSession.GetCompIntfc(CompIntfc.PERSONAL_DATA_CI);

   &oCI.InteractiveMode  = False; /* Read-only - non-interactive OK */

   &oCI.GetHistoryItems  = False;

   &oCI.EMPLID = &sEmplID;

 

   /* ── Step 3: Attempt CI Get ── */

   If Not &oCI.Get() Then

      &respMsg = CreateMessage(Operation.GET_EMPLOYEE_PROFILE,

                               %IntBroker_Response);

      &respMsg.HTTPResponseCode = 404;

      &joResp = CreateJsonObject();

      &joResp.AddProperty("status", "NOT_FOUND");

      &joResp.AddProperty("message", "Employee not found: " | &sEmplID);

      &respMsg.SetContentString(&joResp.ToString());

      Return &respMsg;

   End-If;

 

   /* ── Step 4: Read Level 0 - PERSONAL_DATA ── */

   &oLevel0 = &oCI.GetLevel0().Item(1);

 

   Local string &sGender, &sEmail, &sCountry;

   Local date   &dDOB, &dHireDate;

 

   &sGender   = &oLevel0.SEX;

   &dDOB      = &oLevel0.BIRTHDATE;

   &dHireDate = &oLevel0.DT_OF_HIRE;

   &sCountry  = &oLevel0.COUNTRY;

   &sEmail    = &oLevel0.EMAIL_ADDR;

 

   /* ── Step 5: Read Level 1 - NAMES (Primary) ── */

   Local string &sFirst, &sLast;

   Local integer &n;

 

   For &n = 1 To &oCI.NAMES.Count

      Local ApiObject &oNameRow = &oCI.NAMES.Item(&n);

      If &oNameRow.NAME_TYPE = "PRI" Then

         &sFirst = &oNameRow.FIRST_NAME;

         &sLast  = &oNameRow.LAST_NAME;

         Break;

      End-If;

   End-For;

 

   /* ── Step 6: Read Level 1 - ADDRESSES (Home) ── */

   Local string &sAddr1, &sCity, &sState, &sZip;

 

   For &n = 1 To &oCI.ADDRESSES.Count

      Local ApiObject &oAddrRow = &oCI.ADDRESSES.Item(&n);

      If &oAddrRow.ADDRESS_TYPE = "HOME" Then

         &sAddr1 = &oAddrRow.ADDRESS1;

         &sCity  = &oAddrRow.CITY;

         &sState = &oAddrRow.STATE;

         &sZip   = &oAddrRow.POSTAL;

         Break;

      End-If;

   End-For;

 

   /* ── Step 7: Read Level 1 - NATIONAL_ID (Primary) ── */

   Local string &sNatID, &sNatIDType;

 

   For &n = 1 To &oCI.NATIONAL_ID.Count

      Local ApiObject &oNatRow = &oCI.NATIONAL_ID.Item(&n);

      If &oNatRow.PRIMARY_NID = "Y" Then

         &sNatID     = &oNatRow.NATIONAL_ID;

         &sNatIDType = &oNatRow.NATIONAL_ID_TYPE;

         Break;

      End-If;

   End-For;

 

   /* ── Step 8: Build response JSON ── */

   &joResp = CreateJsonObject();

   &joResp.AddProperty("status",    "SUCCESS");

   &joResp.AddProperty("emplid",    &sEmplID);

   &joResp.AddProperty("firstName", &sFirst);

   &joResp.AddProperty("lastName",  &sLast);

   &joResp.AddProperty("gender",    &sGender);

   &joResp.AddProperty("dateOfBirth",

                        DateTimeToLocalizedString(&dDOB, "YYYY-MM-DD"));

   &joResp.AddProperty("hireDate",

                        DateTimeToLocalizedString(&dHireDate, "YYYY-MM-DD"));

   &joResp.AddProperty("email",     &sEmail);

   &joResp.AddProperty("country",   &sCountry);

 

   /* Address nested object */

   Local JsonObject &joAddr = CreateJsonObject();

   &joAddr.AddProperty("addressLine1", &sAddr1);

   &joAddr.AddProperty("city",         &sCity);

   &joAddr.AddProperty("state",        &sState);

   &joAddr.AddProperty("postalCode",   &sZip);

   &joResp.AddJsonObject("address", &joAddr);

 

   /* National ID nested object */

   Local JsonObject &joNat = CreateJsonObject();

   &joNat.AddProperty("nationalId",     &sNatID);

   &joNat.AddProperty("nationalIdType", &sNatIDType);

   &joResp.AddJsonObject("nationalId", &joNat);

 

   /* ── Step 9: Return 200 response ── */

   &respMsg = CreateMessage(Operation.GET_EMPLOYEE_PROFILE,

                            %IntBroker_Response);

   &respMsg.HTTPResponseCode = 200;

   &respMsg.SetContentString(&joResp.ToString());

   Return &respMsg;

 

end-method;

 

method OnError

   /+ &_MSG as Message +/

   /+ Returns String +/

   Return "GET_EMPLOYEE_PROFILE failed. Node: " | &_MSG.NodeName;

end-method;


STEP 4 - GET Request from Talent System

GET https://<gateway>/PSIGW/RESTListeningConnector/PSFT_LOCAL/employee/00000001234/profile

Headers:

   Authorization: Basic <Base64(TALENT_SVC_USR:password)>

   Accept: application/json


STEP 5 - GET Success Response (HTTP 200)

json

{

  "status"      : "SUCCESS",

  "emplid"      : "00000001234",

  "firstName"   : "Harish",

  "lastName"    : "Kumar",

  "gender"      : "M",

  "dateOfBirth" : "1985-06-15",

  "hireDate"    : "2024-01-15",

  "email"       : "harish.kumar@company.com",

  "country"     : "USA",

  "address"     : {

    "addressLine1" : "123 Main Street",

    "city"         : "Dallas",

    "state"        : "TX",

    "postalCode"   : "75001"

  },

  "nationalId"  : {

    "nationalId"     : "XXX-XX-1234",

    "nationalIdType" : "PR"

  }

}


STEP 6 - Monitoring Status Codes for GET_EMPLOYEE_PROFILE

HTTP Code

Trigger

200

CI.Get() succeeded - profile returned

400

EMPLID missing from URI template

401

Basic Auth failed for TALENT_SVC_USR

403

Permission List missing GET operation access

404

CI.Get() returned False - EMPLID not in PeopleSoft

500

CI instantiation failure or unhandled exception

503

Jolt connection pool exhausted


End-to-End CI-REST Flow

TALENT SYSTEM          PSFT GATEWAY           APP SERVER CI LAYER        DATABASE

─────────────          ────────────           ──────────────────         ────────

 

POST /newhire/create ──►

                    Auth Check ── 401

                    Node Resolve

                    Jolt Forward ──────────► OnRequest Handler

                                             Parse JSON

                                             Validate Fields ── 400

                                             CI.Create() ──────────────► Component Buffer

                                             Set L0 Fields                   

                                             Set L1 NAMES                    

                                             Set L1 ADDRESSES                

                                             Set L1 NATIONAL_ID              

                                             CI.Save() ────────────────► SaveEdit Events

                                                                          SavePreChange

                                                                          SavePostChange

                                                                          COMMIT

                                             Return 201 ◄─────────────────────

◄─────────────────────────────────────────────────────

 

GET /employee/{EMPLID}/profile ──►

                    Auth Check ── 401

                    Jolt Forward ──────────► OnRequest Handler

                                             Parse URI Param

                                             CI.Get() ─────────────────► PS_PERSONAL_DATA

                                             Read L0                      PS_NAMES

                                             Read L1 NAMES                PS_ADDRESSES

                                             Read L1 ADDRESSES            PS_NATIONAL_ID

                                             Build JSON

                                             Return 200 ◄─────────────────────

◄─────────────────────────────────────────────────────

 

PeopleSoft IB - Scenario Based: Queue Stuck, Channels & High Priority Setup


SCENARIO 1 - QUEUE STUCK: DIAGNOSIS & RECOVERY


Q1. Monday morning, operations reports that no IB messages have processed since Friday night. Service Operations Monitor shows 50,000 messages in STATUS=0 (New). Dispatcher process shows running in PSADMIN. Walk through your exact diagnosis sequence.

A:

Layer 1 - Domain Verification:

PSADMIN > Domain Status

 

Check:

- Domain Status     = Active (not Inactive/Paused)

- Publication Dispatcher (PSDISPATCH) - Running

- Subscription Dispatcher (PSSUBDSP)  - Running

- Handler Servers (PSSUBHND)          - Min instances running

 

If Domain = Inactive:

   Boot domain → messages auto-picked up

If Domain = Active but Dispatcher count = 0:

   TUXEDO process crashed silently - bounce Dispatcher only

Layer 2 - PSAPMSGDOMVR Heartbeat Check:

sql

SELECT DOMAINNAME,

       LASTUPDTTM,

       SERVERSTATE

FROM   PSAPMSGDOMVR

ORDER  BY LASTUPDTTM DESC;

 

-- If LASTUPDTTM is older than 5 minutes → domain not updating heartbeat

-- Domain thinks it is active but TUXEDO is frozen

-- Resolution: Bounce the App Server domain cleanly

Layer 3 - Channel-Level Lock Check:

sql

SELECT CHNLNAME,

       COUNT(*)        AS STUCK_COUNT,

       MIN(PUBDTTM)    AS OLDEST_MSG,

       MAX(STATUS)     AS MAX_STATUS

FROM   PSAPMSGPUBHDR

WHERE  STATUS IN (0, 1, 3)

GROUP  BY CHNLNAME

ORDER  BY STUCK_COUNT DESC;

 

-- STATUS=1 rows older than 10 min = Handler Server died mid-processing

-- STATUS=3 on Sequential channel = blocking all STATUS=0 behind it

Layer 4 - Orphaned STATUS=1 (Started) Recovery:

sql

-- Messages stuck in Started = Handler died without completing

-- Safe to reset to New for reprocessing

 

UPDATE PSAPMSGPUBHDR

SET    STATUS   = 0,

       HANDLRID = ' '

WHERE  STATUS   = 1

AND    PUBDTTM  < (SYSDATE - 1/24) -- Older than 1 hour

AND    CHNLNAME = '<affected_channel>';

COMMIT;

 

-- Then bounce Dispatcher to re-claim

Layer 5 - TUXEDO Log Verification:

$PS_HOME/appserv/<domain>/LOGS/TUXLOG.<date>

$PS_HOME/appserv/<domain>/LOGS/APPSRV.LOG

 

Search for:

- "PSDISPATCH terminated"

- "BBL: process died"

- "Jolt: connection refused"

- "ORA-00020: maximum processes exceeded" ← DB connection limit hit


Q2. Queue has 10,000 messages stuck in STATUS=3 (Error) on a Sequential channel. Business says last 9,900 are valid and unprocessed. What is your recovery strategy?

A:

Step 1 - Identify the root blocking message:

sql

SELECT PUBID,

       MSGSEGID,

       CHNLNAME,

       PUBDTTM,

       DESTNODENAME,

       STATUS

FROM   PSAPMSGPUBHDR

WHERE  CHNLNAME  = '<channel_name>'

AND    STATUS     = 3

ORDER  BY PUBDTTM ASC

FETCH FIRST 1 ROWS ONLY;

-- Oldest Error is the channel blocker

Step 2 - Inspect error payload:

Service Operations Monitor >

Publication Contracts >

Filter: Channel = <channel>, Status = Error >

Open oldest record >

View Error Detail + Payload

Step 3 - Decision matrix:

Root Cause                    Action

─────────────────────────────────────────────────────

Data defect in message        Cancel via Monitor → Fix

                              source → re-publish

 

Handler code bug (fixed now)  Edit payload if needed →

                              Resubmit via Monitor

 

Target system was down        Target now up → Resubmit

 

All 100 are same error        Bulk resubmit via

                              IUIBRDFND App Engine

                              with filter criteria

Step 4 - Bulk resubmit via delivered process:

PeopleTools > Integration Broker >

Service Operations Monitor >

Asynchronous Services >

Select all Error rows on channel >

Action = Resubmit Selected

 

-- For bulk (> 500 records): use IUIBRDFND App Engine

-- Run Control: Channel = <name>, Status = Error,

--              Date From = <date>, Action = Resubmit

Step 5 - Prevent recurrence:

Change channel to "Continue on Error" temporarily

during mass reprocessing to prevent one bad message

blocking 9,900 good ones again.

Revert to sequential after queue is cleared.


Q3. A channel has STATUS=1 (Started) messages that are 6 hours old and not completing. Handler Server shows running. What is happening and how do you resolve?

A: STATUS=1 for 6 hours means the Handler Server claimed the message and started processing but never completed or errored. Root causes: Handler is stuck in an infinite loop in PeopleCode, waiting on an external synchronous call that never responded (deadlock on %IntBroker.SyncRequest()), or the Handler process is in a zombie state - TUXEDO reports it as running but it is not processing.

Diagnosis:

1. tmadmin > psr → confirm Handler instance is truly active

2. Check APPSRV.LOG for the Handler process ID → grep for

   "started processing PUBID=<id>" with no "completed" line

3. Check DB session for that Handler's OS PID:

sql

SELECT S.SID,

       S.SERIAL#,

       S.STATUS,

       S.WAIT_CLASS,

       S.EVENT,

       Q.SQL_TEXT

FROM   V$SESSION S

JOIN   V$SQL     Q ON S.SQL_ID = Q.SQL_ID

WHERE  S.PROGRAM LIKE '%PSSUBHND%'

AND    S.STATUS  = 'ACTIVE';

-- If WAIT_CLASS = 'Lock' → DB deadlock on Handler

-- Kill the DB session, reset STATUS=1 to STATUS=0

Resolution:

- Kill the zombie Handler OS process

- Reset stuck STATUS=1 message to STATUS=0

- Bounce Handler Server pool (not full domain)

- Fix the deadlock root cause in handler PeopleCode


Q4. Two different channels are stuck simultaneously. One is Sequential, one is Any Order. How does your diagnosis and recovery differ between them?

A:

Sequential Channel:

One Error row blocks ALL subsequent rows on this channel.

Single point of failure by design.

 

Diagnosis:

- Find oldest STATUS=3 row → that is the blocker

- All STATUS=0 rows behind it will not move until

  the blocker is resolved

- Fix/Cancel blocker → entire queue flows immediately

 

Recovery priority: HIGH - business impact is total

channel blockage

Any Order Channel:

Error rows do NOT block other messages.

Each message is independent.

 

Diagnosis:

- Error rows accumulate but do not stop new messages

- STATUS=0 rows continue processing in parallel

- Errors are isolated failures only

 

Recovery priority: MEDIUM - only failed messages

need attention, flow continues

 

Key difference:

Any Order errors can silently accumulate without

operations noticing - implement threshold alerting

on Error count even for Any Order channels


Q5. Publications are flowing but subscriptions are not processing on the same channel. How do you isolate this split failure?

A: Publication and Subscription contractors are completely independent processes. A publication queue flowing confirms PSDISPATCH and outbound Handlers are healthy. Subscription failure is isolated to PSSUBDSP (Subscription Dispatcher) or PSSUBHND (Subscription Handler) processes.

Step 1: Check PSAPMSGSUBHDR for STATUS distribution

sql

SELECT STATUS, COUNT(*)

FROM   PSAPMSGSUBHDR

WHERE  CHNLNAME = '<channel>'

GROUP  BY STATUS;

-- STATUS=0 accumulating = Subscription Dispatcher down

-- STATUS=3 accumulating = Handler throwing exceptions

Step 2: Verify PSSUBDSP process count in PSADMIN

   If 0 → Subscription Dispatcher crashed

   Bounce PSSUBDSP process only

 

Step 3: If Dispatcher running but messages stay STATUS=0

   Check PSAPMSGDOMVR - Subscription Dispatcher

   updates a separate heartbeat row from Publication

   Dispatcher - confirm it is current

 

Step 4: If STATUS=3 → open error detail in Monitor

   Check if OnNotify handler App Class path changed

   after a code migration - class not found error

   is the most common cause of sudden subscription failure


 SCENARIO 2 - CHANNEL SETUP & CONFIGURATION


Q6. What are all the configurable properties on a Channel definition and what is the production impact of each setting?

A:

PeopleTools > Integration Broker >

Integration Setup > Queues (Channels)

 

Property              Values          Production Impact

──────────────────────────────────────────────────────────────────

Queue Name            String          Unique identifier - used in

                                      routing assignment

 

Queue Type            Singleton       One message at a time globally

                      Standard        Normal parallel/sequential

 

Pause on Error        Yes / No        Yes = channel pauses on first

                                      error (Sequential behavior)

                     

Order Processing      Sequential      PUBID order enforced

                      Any Order       Parallel, no order guarantee

 

Priority              1–10            Higher = Dispatcher claims

                                      this channel's messages first

                                      under load contention

 

Status                Active          Messages flow normally

                      Inactive        New publishes rejected

                      Paused          Queue frozen - existing

                                      messages held

 

Description           Text            Documentation only


Q7. Walk through the complete setup of a High Priority channel from scratch for a Payroll integration that must process before all other channels.

A:

Step 1 - Create High Priority Channel:

PeopleTools > Integration Broker >

Integration Setup > Queues

 

Queue Name       : PAYROLL_HIGH_PRI_CHNL

Queue Type       : Standard

Order Processing : Sequential        ← Payroll must be ordered

Pause on Error   : Yes               ← Stop on any payroll error

Priority         : 10                ← Highest possible priority

Status           : Active

Description      : High Priority Payroll Processing Channel

Step 2 - Assign Channel to Service Operation:

PeopleTools > Integration Broker >

Integration Setup > Service Operations >

PAYROLL_CONFIRM_OP > General tab

 

Queue Name : PAYROLL_HIGH_PRI_CHNL

Step 3 - Assign Channel in Routing Definition:

Routing Definition > PAYROLL_OUTBOUND_RT >

Queue Name : PAYROLL_HIGH_PRI_CHNL

 

-- Routing-level channel assignment overrides

-- Operation-level assignment for that specific routing

Step 4 - Tune Dispatcher for Priority Channel:

$PS_CFG_HOME/appserv/<domain>/psappsrv.cfg

 

[PSSUBDSP]

Min Instances=2

Max Instances=2

 

[PSSUBHND]

Min Instances=5

Max Instances=10

 

; Priority channel gets dedicated Handler headroom

; Standard channels share remaining Handler capacity

Step 5 - Verify Priority in Monitor:

Service Operations Monitor >

Asynchronous Services >

Publication Contracts >

Filter: Queue = PAYROLL_HIGH_PRI_CHNL

 

Confirm messages process before lower-priority

channel messages under load - verify timestamps


Q8. You have 20 channels all with Priority=5 (default). Three channels handle payroll, benefits, and GL posting. How do you restructure channel priority without a maintenance window?

A:

Priority Assignment Strategy:

Channel                  New Priority   Rationale

────────────────────────────────────────────────────

PAYROLL_CHNL             10             Regulatory - must complete

GL_POSTING_CHNL          9              Financial close dependency

BENEFITS_CHNL            8              Employee-facing SLA

HR_AUDIT_CHNL            7              Compliance - near-real-time

WORKFLOW_NOTIF_CHNL      5              Standard - no hard SLA

REPORT_EXTRACT_CHNL      3              Batch - low urgency

ARCHIVE_CHNL             1              Background only

Live Priority Update (no maintenance window needed):

PeopleTools > Integration Broker >

Integration Setup > Queues >

Open each channel > Change Priority > Save

 

-- Priority change takes effect on the NEXT Dispatcher

-- polling cycle (within seconds)

-- No bounce required

-- In-flight messages on current cycle complete at old priority

-- New cycle picks up new priority immediately

Validation after change:

sql

SELECT QUEUENAME,

       PRIORITY,

       QUEUETYPE,

       ORDERINGTYPE

FROM   PSAPMSGCHNLDEFN

ORDER  BY PRIORITY DESC;

-- Confirm priority ladder is correct before declaring done


Q9. A channel with Priority=10 is not getting processed faster than a Priority=1 channel under load. What are the configuration gaps?

A: Priority is only meaningful when the Dispatcher has more channels to process than Handler capacity allows - it is a contention resolution mechanism, not a throughput accelerator. If Handler Servers have idle capacity, all channels process immediately regardless of priority.

Gap 1: Handler pool too large relative to load

   All channels process immediately → priority irrelevant

   Fix: Priority matters only under Handler saturation

 

Gap 2: Singleton Queue Type on high-priority channel

   Singleton processes one message globally at a time

   regardless of priority setting

   Fix: Change to Standard Queue Type

 

Gap 3: Dispatcher batch size equal across channels

   If WORKUNIT=10 for all channels, high-priority channel

   gets same batch claim size as low-priority

   Fix: No per-channel WORKUNIT setting exists natively -

   use dedicated domain per priority tier instead

 

Gap 4: Multiple domains with no channel affinity

   Low-priority domain claiming high-priority channel messages

   Fix: Configure domain-level channel filtering to restrict

   which domains process which channels

 

Gap 5: Priority=10 channel has Sequential + Pause on Error

   with a stuck Error message

   Channel paused = priority irrelevant - no messages flow

   Fix: Resolve the blocking error first


Q10. How do you configure channel affinity so that only a dedicated App Server domain processes a specific high-priority channel?

A:

Step 1 - Create Dedicated Domain for High Priority:

PSADMIN > Create New Domain > PSFT_HIGHPRI_DOM

 

Configure psappsrv.cfg:

[PSSUBDSP]

Min Instances=2

Max Instances=2

 

[PSSUBHND]

Min Instances=8

Max Instances=15

Step 2 - Configure Channel Filter on Dedicated Domain:

psappsrv.cfg of PSFT_HIGHPRI_DOM:

 

[PUBSUB]

; Include ONLY high-priority channels on this domain

ChannelList=PAYROLL_HIGH_PRI_CHNL,GL_POSTING_CHNL,BENEFITS_CHNL

ChannelListMode=INCLUDE

Step 3 - Configure Exclusion on Standard Domains:

psappsrv.cfg of PSFT_STD_DOM_01, PSFT_STD_DOM_02:

 

[PUBSUB]

; Exclude high-priority channels from standard domains

ChannelList=PAYROLL_HIGH_PRI_CHNL,GL_POSTING_CHNL,BENEFITS_CHNL

ChannelListMode=EXCLUDE

Step 4 - Verify Affinity in PSAPMSGDOMVR:

sql

SELECT DOMAINNAME,

       CHNLNAME,

       SERVERSTATE

FROM   PSAPMSGDOMVR

WHERE  CHNLNAME IN (

   'PAYROLL_HIGH_PRI_CHNL',

   'GL_POSTING_CHNL')

ORDER  BY DOMAINNAME;

-- Only PSFT_HIGHPRI_DOM rows should appear for these channels


Q11. During month-end close, GL posting channel needs to temporarily jump to highest priority while payroll channel must pause. How do you execute this without code changes?

A:

Step 1 - Pause Payroll Channel:

Service Operations Monitor >

Asynchronous Services >

Queue Status >

Select PAYROLL_HIGH_PRI_CHNL >

Action = Pause

 

-- Existing in-flight message completes

-- No new messages picked up from queue

-- STATUS=0 messages held safely in PSAPMSGPUBHDR

Step 2 - Elevate GL Channel Priority:

PeopleTools > Integration Broker >

Integration Setup > Queues >

GL_POSTING_CHNL >

Priority : Change from 9 to 10 >

Save

 

-- Effective on next Dispatcher polling cycle

-- No bounce required

Step 3 - Increase Handler Capacity for GL Channel:

PSADMIN > Domain Administration >

PSFT_HIGHPRI_DOM > Configure >

PSSUBHND Max Instances: 10 → 20

Bounce PSSUBHND pool only (not full domain)

Step 4 - Monitor GL Channel Throughput:

sql

SELECT COUNT(*),

       STATUS,

       TRUNC(PUBDTTM, 'MI') AS MINUTE_BUCKET

FROM   PSAPMSGPUBHDR

WHERE  CHNLNAME = 'GL_POSTING_CHNL'

GROUP  BY STATUS, TRUNC(PUBDTTM, 'MI')

ORDER  BY MINUTE_BUCKET DESC;

-- Confirm STATUS=2 (Done) rate increasing per minute

Step 5 - Restore after Month-End:

1. GL_POSTING_CHNL Priority → revert to 9

2. PAYROLL_HIGH_PRI_CHNL → Resume

3. PSSUBHND Max Instances → revert to 10

4. Confirm PAYROLL queue STATUS=0 messages resume processing


Q12. What is a Singleton Queue and when would you use it over a Standard Queue in an enterprise PeopleSoft setup?

A: Singleton Queue processes exactly one message at a time across all domains globally - not just within one domain, but system-wide. The Dispatcher enforces a global lock so no two domains or Handler threads ever process two messages from a Singleton channel concurrently.

Use Singleton When:

──────────────────────────────────────────────────────

Scenario                        Reason

──────────────────────────────────────────────────────

Master data sync where the      Parallel processing

target system cannot handle     causes duplicate key

concurrent inserts for same     or race condition on

business key                    the target

 

Integration that calls a        Third party has no

third-party API with a          concurrency support -

rate limit of 1 TPS             Singleton enforces 1 TPS

naturally

 

Balance update integrations     Credit + Debit for

where debit and credit for      same account must

same account must not           never process in parallel

run in parallel

 

Configuration data push         Order of config records

where sequence is absolute      matters absolutely

──────────────────────────────────────────────────────

 

Never use Singleton for:

- High-volume integrations (>100 msg/hour)

- Independent messages with no shared key

- Any channel where throughput SLA exists


Q13. How do you detect and prevent channel starvation where high-priority channels monopolize Handler Servers, starving low-priority channels indefinitely?

A:

Detection Query:

sql

SELECT H.CHNLNAME,

       D.PRIORITY,

       COUNT(H.PUBID)       AS STUCK_COUNT,

       MIN(H.PUBDTTM)       AS OLDEST_MESSAGE,

       ROUND((SYSDATE - MIN(H.PUBDTTM)) * 24, 2) AS HOURS_WAITING

FROM   PSAPMSGPUBHDR  H

JOIN   PSAPMSGCHNLDEFN D ON H.CHNLNAME = D.QUEUENAME

WHERE  H.STATUS = 0

GROUP  BY H.CHNLNAME, D.PRIORITY

HAVING MIN(H.PUBDTTM) < (SYSDATE - 1/24)

ORDER  BY HOURS_WAITING DESC;

-- Any low-priority channel waiting > 1 hour = starvation

Prevention Architecture:

Strategy 1 - Domain Segregation:

   Dedicated domain for Priority 8-10 channels

   Separate domain for Priority 1-7 channels

   Each domain has its own Handler pool

   High-priority channels cannot starve low-priority

   because they use separate Handler pools

 

Strategy 2 - Handler Reservation:

   Total Handler Servers = 20

   Reserve minimum 5 Handlers for low-priority channels

   via channel affinity configuration

   High-priority channels use remaining 15

 

Strategy 3 - Time-based Priority Aging:

   Build custom App Engine monitor:

   If STATUS=0 message on low-priority channel

   is older than 2 hours → temporarily elevate

   channel priority to 8 → reset after processing

   (requires custom monitoring - not delivered natively)

 

Strategy 4 - Alert Before Starvation:

   Schedule detection query every 30 minutes

   Alert operations if any channel has STATUS=0

   messages older than 60 minutes

   Intervene before business impact occurs


Q14. Design a complete channel architecture for a PeopleSoft HCM environment integrating with Payroll, Benefits, Talent, GL, and a Document Management System.

A:

Channel Name              Priority  Order       Pause    Type       Rationale

───────────────────────────────────────────────────────────────────────────────

PAYROLL_CRITICAL_CHNL     10        Sequential  Yes      Standard   Legal/regulatory

                                                                     Order mandatory

 

GL_CLOSE_CHNL             9         Sequential  Yes      Standard   Financial integrity

                                                                     Sequence critical

 

BENEFITS_ENROLLMENT_CHNL  8         Sequential  Yes      Standard   Employee SLA

                                                                     Ordered by eff date

 

TALENT_NEWHIRE_CHNL       7         Sequential  No       Standard   Ordered by hire date

                                                                     Continue on error

 

HR_AUDIT_CHNL             6         Any Order   No       Standard   Independent records

                                                                     No ordering needed

 

BENEFITS_NOTIFY_CHNL      5         Any Order   No       Standard   Notifications

                                                                     Independent

 

DOCSYS_ATTACH_CHNL        4         Any Order   No       Standard   File push

                                                                     Independent

 

REPORT_EXTRACT_CHNL       2         Any Order   No       Standard   Batch extracts

                                                                     Best effort

 

ARCHIVE_PURGE_CHNL        1         Any Order   No       Standard   Background only

───────────────────────────────────────────────────────────────────────────────

 

Domain Assignment:

PSFT_CRITICAL_DOM  → Channels Priority 8-10  (dedicated, 15 Handlers)

PSFT_STANDARD_DOM  → Channels Priority 4-7   (shared,    10 Handlers)

PSFT_BATCH_DOM     → Channels Priority 1-3   (batch,      5 Handlers)

 

Monitoring Alert Thresholds:

Priority 10 channel  → Alert if STATUS=0 older than 5 minutes

Priority 8-9 channel → Alert if STATUS=0 older than 15 minutes

Priority 5-7 channel → Alert if STATUS=0 older than 60 minutes

Priority 1-4 channel → Alert if STATUS=0 older than 4 hours


Q15. After a PROD database failover to DR, all IB channels show 0 messages processing despite the App Server connecting to DR DB successfully. What is the specific IB setup issue?

A: PSAPMSGDOMVR in the DR database has no active domain registrations - the DR database never had live domains writing heartbeat rows. The Dispatcher connects to DR DB, queries PSAPMSGDOMVR to register itself, but finds stale or missing rows from the primary that were not replicated in time, causing the Dispatcher to enter a wait state believing another domain is already active.

Step 1 - Check DR PSAPMSGDOMVR state:

sql

SELECT DOMAINNAME,

       LASTUPDTTM,

       SERVERSTATE

FROM   PSAPMSGDOMVR;

-- Stale rows from primary with SERVERSTATE=1 (Active)

-- DR Dispatcher sees them as live → waits for them to release

Step 2 - Clear stale domain registrations on DR:

sql

UPDATE PSAPMSGDOMVR

SET    SERVERSTATE = 0   -- Mark all domains Inactive

WHERE  SERVERSTATE = 1;

COMMIT;

-- DR Dispatcher will now register itself cleanly

-- on next heartbeat cycle (within 60 seconds)

Step 3 - Force Dispatcher re-registration:

   Bounce PSDISPATCH and PSSUBDSP processes on DR

   App Server domain (not full domain bounce needed)

   Dispatcher registers fresh rows in DR PSAPMSGDOMVR

   Begins claiming STATUS=0 messages within 60 seconds

 

Step 4 - Validate recovery:

sql

SELECT DOMAINNAME,

       LASTUPDTTM,

       SERVERSTATE

FROM   PSAPMSGDOMVR

WHERE  SERVERSTATE = 1;

-- Should show DR domain name with current timestamp

-- updating every 60 seconds confirming active processing

Step 5 - DR Runbook update:

   Add PSAPMSGDOMVR cleanup as a mandatory step

   in the DR activation runbook - this is the #1 missed

   step in every PeopleSoft DR failover that causes

   IB to appear broken while App Server is healthy

 

No comments:

Post a Comment

PEOPLESOFT FLUID — COMPREHENSIVE Q&A

 In-Depth Interview & Real-Time Reference Guide (2025-26) =================================================== TABLE OF CONTENTS: 1. FLUI...