Insight

Maximo publish channels that survive a downstream outage

How to design Maximo publish channels, JMS queues and endpoints so a slow finance system does not leak into the Manage user experience.

6 min read By Milos Jakovljevic, Head of Architecture
Cover image for the insight: Maximo publish channels that survive a downstream outage
Maximo Best PracticesIntegration FrameworkPublish ChannelsJMSMaximo Manage

A supervisor closes a work order in Maximo Manage at 09:12 on a Tuesday. The status change fires the MXWO event, an active publish channel picks it up, transforms the payload through an XSL map, and posts it to the endpoint fronting the finance system. The endpoint returns HTTP 503. Ninety seconds later the same thing happens for the next work order. By 09:20 the sequential outbound queue is thirty messages deep, the JMSQSEQCONSUMER cron task is looping on the head message, and an integration inbox nobody owns has started to fill. This is the failure mode Maximo publish channels prevent under design and reproduce under drift.

The configuration and operating discipline that keep outbound integration quiet under a slow downstream have been part of the Maximo Integration Framework since Maximo 6 (~2008) and apply equally to Maximo 7.6.1 estates that have not yet upgraded to MAS.

What a Maximo publish channel actually is

A publish channel is the outbound half of the Maximo Integration Framework. It binds an object structure (the MBO tree that becomes the XML message), a processing class or automation script, an XSL mapping, and an endpoint that decides how the payload leaves the JVM. When event listening is enabled on the channel, an MBO create, update or delete triggers an outbound message; when it is off, the channel is called explicitly by an action, an escalation, or a bulk export.

Every message is written to a JMS queue on the way out. Maximo ships with two default outbound queues. SQOUT is the sequential outbound queue, processed by the SEQOUT instance of the JMSQSEQCONSUMER cron task in strict order. CQOUT is the continuous outbound queue, processed in parallel by MDBs, with an exception destination (cqouterrbd by default) so poison messages leave the primary queue. Four records have to be enabled for the payload to move: object structure, publish channel, external system and endpoint. Miss one and the message stays in the JVM.

09:12 to 09:20: what the estate is actually doing

Return to the supervisor. The MXWO status change fires the publish channel bound to the finance External System. The message is enqueued on SQOUT. The SEQOUT cron task takes the head message, calls the HTTP endpoint at the finance system, and receives a 503. Because the queue is sequential, the cron task will not process message two until message one succeeds or is moved out of the way. The HTTP handler’s retries and timeout are exhausted in seconds. The message stays at the head of SQOUT, retried on every cron cycle; Message Tracking records the RECEIVED status.

Every subsequent status change enqueues behind it. At 09:20, thirty work orders are stuck. At 10:00, a planner phones the service desk about missing settlement postings; the failure is invisible to the Manage user, so the call routes to the wrong team. A design decision on the External System record is doing exactly what it was configured to do.

Choose sequential or continuous per channel

Sequential and continuous queues serve different jobs. SQOUT preserves order and processes one message at a time; a failed message blocks the queue until it is corrected or reprocessed. CQOUT processes in parallel and routes poison messages to cqouterrbd, with best-effort ordering.

Only a subset of outbound flows genuinely needs strict order. A ledger posting where message N+1 depends on message N is one. A dimensional load into a data warehouse handles late-arriving updates downstream and can run on the continuous queue. The default of “every channel on SQOUT because the sample used SQOUT” is the pattern that produces the 09:20 scenario. Route order-sensitive channels to SQOUT and everything else to CQOUT, decide it per publish channel on the External System record, and record the reason in the design pack.

The endpoint owns the retry policy

The endpoint is where retry semantics live. The out-of-the-box HTTP endpoint accepts URL, HTTPHEADERS, and a small set of properties. Automation-script endpoint handlers let the integration author decide what “retry” means for a given downstream, including exponential backoff, a circuit breaker on repeated 5xx responses, or a route to a holding queue after N failures.

Two habits keep this honest. Endpoints that face flaky middleware carry a bounded retry with backoff and, when the bound is reached, move the message to an error destination that a named team monitors. Endpoints that face reliable middleware still time out; a downstream that hangs for ninety seconds on every message costs more than one that returns 503 quickly. Set connection and read timeouts on the endpoint in seconds, at values the middleware team has agreed. The queue makes the Manage user asynchronous; the endpoint timeout is what keeps that guarantee.

Message Reprocessing is the operating surface

The Message Reprocessing application surfaces errored messages from continuous queues (cqouterrbd via MAXINTERROR) with payload, exception, and actions to correct, retry or delete. Sequential queue errors show in the JMS queue view and Message Tracking, and route into Message Reprocessing when an error destination is configured on the SQOUTBD bus destination. This is the surface a middleware or integration team drives every morning; it is where the failure at 09:12 is either cleared or escalated.

Two operating rules follow. Every External System carries a named owner who monitors Message Reprocessing daily; the owner sits on the middleware or integration team, by default. Every error queue depth belongs on the operational dashboard alongside the integration success rate; a queue that quietly grows for three days is a change nobody agreed to.

Design patterns that hold up under load

The layout that keeps outbound integration boring:

  • One publish channel per business event; fan-out on the External System. Binding the channel to multiple External Systems, each with its own endpoint and queue, keeps the mapping single-purpose. A channel that serves three consumers with one XSL and three conditional branches becomes a maintenance liability inside a year.
  • XSL handles shape; scripts handle logic. XSL mappings rename, restructure and drop fields. Where the transformation needs to look up a value in another MBO or take a conditional decision, the work belongs in a processing class or automation script bound to the channel.
  • Message tracking on for anything auditable. MAXINTMSGTRK rows survive the queue and let a compliance team answer “did this message reach the finance system” without reading middleware logs. The storage cost is one row per message; on a settlement feed or a regulator-facing report, that cost is worth paying.
  • Run outbound integration on the MEA bundle. On MAS Manage, publish channels, endpoints and JMS cron tasks belong on the MEA server bundle rather than the UI bundle. It is a configuration change on the ManageWorkspace CR and it stops an integration burst from touching the interactive user experience.

What stays hard

Three limits stay in place after configuration. A downstream that returns 200 OK and silently drops the payload is invisible to queue and endpoint alike; the only defence is a reconciliation report comparing Manage-side counts to downstream counts on a cadence the business owns. Ordering that spans publish channels (settlement N must land before purchase order N+1) cannot be enforced by SQOUT alone and usually needs a small orchestration layer on the middleware side. Endpoint credentials rotate on a downstream calendar the Manage team does not control; a rotation missed on the endpoint record produces the same 503 pattern as an outage.

Those three points argue for treating outbound integration as an operated service under change control, on the same footing as the MIF integration surface as a whole.

The position

Publish channels in Maximo Manage hold up under a slow downstream when the queue type is chosen per channel, the endpoint carries a bounded retry with real timeouts, Message Reprocessing has a named owner, and the integration workload runs on the MEA bundle. Estates that leave every channel on SQOUT with a default HTTP endpoint and no queue owner rediscover the 09:12 scenario every time the finance system has a bad morning. The Integration Framework has not changed materially since Maximo 6; the operating discipline around it decides whether the outbound path is a service or a symptom queue.

Sources

Who stands behind this piece

Milos Jakovljevic

Head of Architecture

The argument above, including where it stops and what still has to be true on a live estate before it applies.

Talk to them directly →

Read next in the river

Neighbouring arguments and the delivery page

Where this leads

This piece takes a position. The delivery side of it sits on Maximo integrations, and the buyer guides work the same decisions end to end.

Disagree with it on your own estate before you circulate it as settled fact.

Disagree with this on your own estate

An insight argues one thing in general. Thirty minutes with a senior MaxIron engineer is where it gets tested against your version, your integrations and your operating model. Start with Maximo integrations if you would rather read first.

Useful to have to hand

  • Your current Maximo or MAS version, and the database behind it.
  • The part of this piece you think does not apply to you.
  • The decision this feeds, and who has to sign it off.