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