Mapping Pipeline¶
The three-namespace problem¶
IBM MQ uses multiple naming conventions depending on the interface:
- MQSC names (e.g.
CURDEPTH,DEFPSIST) - Short, uppercase tokens used in MQSC commands and the REST API's
runCommandJSONendpoint. - PCF names (e.g.
CurrentQDepth,DefPersistence) - CamelCase names from the Programmable Command Formats. Not used directly by mq-rest-admin, but they form the intermediate namespace in the mapping pipeline.
- Developer names (e.g.
current_queue_depth,default_persistence) - Human-readable
snake_casenames for use in application code.
The mapping pipeline translates between MQSC and developer names. PCF names were used as an intermediate reference during the original extraction process that bootstrapped the mapping tables but do not appear at runtime.
In Java, developer-friendly names use snake_case (e.g. current_queue_depth,
default_persistence), matching the convention across the mq-rest-admin library
family. The mapping tables are loaded from a JSON resource file and are identical
across language implementations.
// With mapping enabled (default) — developer-friendly names
var queues = session.displayQueue("MY.QUEUE",
Map.of("response_parameters", List.of("current_queue_depth", "max_queue_depth")));
// Returns: [{"queue_name": "MY.QUEUE", "current_queue_depth": 0, "max_queue_depth": 5000}]
// With mapping disabled — native MQSC names
var queues = session.displayQueue("MY.QUEUE",
Map.of("response_parameters", List.of("CURDEPTH", "MAXDEPTH")),
Map.of("mapAttributes", false));
// Returns: [{"queue": "MY.QUEUE", "curdepth": 0, "maxdepth": 5000}]
Qualifier-based mapping¶
Mappings are organized by qualifier (e.g. queue, channel, qmgr),
not by command. A single qualifier's mapping tables serve all commands
that operate on that object type. For example, the queue qualifier
covers DISPLAY QUEUE, DEFINE QLOCAL, DELETE QALIAS, and all other
queue-related commands.
This design avoids duplicating mapping data across commands and reflects how MQSC attributes are shared across command verbs.
See the Qualifier Mapping Reference for the complete per-qualifier documentation, including every key map, value map, and key-value map entry.
Request mapping flow¶
When mapping is enabled, request attributes are translated before sending to the MQ REST API:
-
Key mapping: Each
snake_caseattribute name is looked up in the qualifier'srequest_key_map. If found, the key is replaced with the MQSC parameter name. -
Value mapping: For attributes with enumerated values, the qualifier's
request_value_maptranslates developer values to MQSC values (e.g."yes"→"YES"). -
Key-value mapping: Some attributes require both key and value to change simultaneously. The
request_key_value_maphandles cases where a single developer attribute expands to a different MQSC key+value pair (e.g.channel_type="server_connection"→CHLTYPE("SVRCONN")).
Java example¶
// Developer-friendly request parameters
session.defineQlocal("MY.QUEUE", Map.of(
"max_queue_depth", 50000,
"default_persistence", "yes",
"description", "Application queue"
));
// After request mapping, the JSON payload sent to MQ contains:
// { "MAXDEPTH": 50000, "DEFPSIST": "YES", "DESCR": "Application queue" }
Response mapping flow¶
Response attributes are translated after receiving the MQ REST response:
-
Key mapping: Each MQSC parameter name from the response is looked up in the qualifier's
response_key_map. If found, the key is replaced with thesnake_casename. -
Value mapping: Enumerated MQSC values are translated to developer-friendly values via the
response_value_map(e.g."YES"→"yes").
Java example¶
// Request specific response attributes using developer-friendly names
var queues = session.displayQueue("MY.QUEUE",
Map.of("response_parameters", List.of("current_queue_depth", "max_queue_depth")));
// MQ returns MQSC names in the response:
// { "queue": "MY.QUEUE", "curdepth": 0, "maxdepth": 5000 }
// After response mapping, the caller receives developer-friendly names:
// { "queue_name": "MY.QUEUE", "current_queue_depth": 0, "max_queue_depth": 5000 }
Response parameter mapping¶
When the caller specifies response_parameters (the list of attributes
to return), those names are also mapped from snake_case to MQSC before
being sent in the request. This allows callers to request specific
attributes using developer-friendly names.
Response parameter macros (like CFCONLOS for channel status) are
recognized and passed through without mapping.
WHERE keyword mapping¶
The where parameter on DISPLAY methods accepts a filter expression
like "current_queue_depth GT 100". The first token (the keyword) is mapped
from snake_case to the MQSC name. The rest of the expression is
passed through unchanged.
Qualifier resolution¶
When a command is executed, the mapping qualifier is resolved by:
- Looking up the command key (e.g.
"DISPLAY QUEUE") inMAPPING_DATA["commands"]for an explicit qualifier. - Falling back to a hardcoded default map (e.g.
QLOCAL→queue,CHANNEL→channel). - As a last resort, lowercasing the MQSC qualifier.
This means DEFINE QLOCAL, DEFINE QREMOTE, and DISPLAY QUEUE all
resolve to the queue qualifier and share the same mapping tables.
Strict vs lenient mode¶
Strict mode (default): Any attribute name or value that cannot be
mapped raises a MappingException. This catches typos and unsupported
attributes early.
Lenient mode (mappingStrict(false)): Unknown attribute names and
values pass through unchanged. This is useful when working with
attributes not yet covered by the mapping tables.
The mode is set at session construction and applies to all mapping operations. It cannot be overridden per-call.
In Java, the mode is set via the builder:
// Strict mode (default) — throws MappingException on unknown attributes
var session = MqRestSession.builder()
.host("localhost")
.port(9443)
.queueManager("QM1")
.credentials(new LtpaAuth("admin", "passw0rd"))
.mappingStrict(true) // default
.build();
// Lenient mode — unknown attributes pass through unchanged
var session = MqRestSession.builder()
.host("localhost")
.port(9443)
.queueManager("QM1")
.credentials(new LtpaAuth("admin", "passw0rd"))
.mappingStrict(false)
.build();
Custom mapping overrides¶
The built-in mapping tables cover all standard MQSC attributes, but sites may
use different snake_case conventions. The mappingOverrides parameter on
MqRestSession lets you layer sparse changes on top of the built-in data
without replacing it.
How merging works¶
Overrides are merged at the key level within each sub-map. You only specify the entries you want to change — all other mappings remain intact:
var overrides = Map.of(
"qualifiers", Map.of(
"queue", Map.of(
"response_key_map", Map.of(
"CURDEPTH", "queue_depth", // override built-in mapping
"MAXDEPTH", "queue_max_depth" // override built-in mapping
)
)
)
);
var session = MqRestSession.builder()
.host("localhost")
.port(9443)
.queueManager("QM1")
.credentials(new LtpaAuth("admin", "passw0rd"))
.mappingOverrides(overrides)
.build();
var queues = session.displayQueue("MY.QUEUE");
// Returns: [{"queue_depth": 0, "queue_max_depth": 5000, ...}]
// All other queue attributes keep their default names
When this override is applied:
- The built-in
MAPPING_DATAis deep-copied (the original is never mutated). - The
queuequalifier'sresponse_key_mapis updated: the entry forCURDEPTHchanges from"current_queue_depth"to"queue_depth". - All other entries in
response_key_map(and all other sub-maps) remain unchanged.
Supported override keys¶
The top level of mappingOverrides accepts two keys:
commands: Override command-level metadata (e.g. which qualifier a command resolves to). Each command entry is shallow-merged.qualifiers: Override qualifier mapping tables. Each qualifier supports five sub-maps:request_key_map—snake_case→ MQSC key mapping for requestsrequest_value_map— value translations for request attributesrequest_key_value_map— combined key+value translations for requestsresponse_key_map— MQSC →snake_casekey mapping for responsesresponse_value_map— value translations for response attributes
Adding new qualifiers¶
You can add mappings for qualifiers not yet covered by the built-in data:
var overrides = Map.of(
"qualifiers", Map.of(
"custom_object", Map.of(
"request_key_map", Map.of("my_attr", "MYATTR"),
"response_key_map", Map.of("MYATTR", "my_attr"),
"request_value_map", Map.of(),
"response_value_map", Map.of()
)
)
);
Validation¶
The override structure is validated at session construction time. Invalid shapes raise exceptions immediately, so errors are caught before any commands are sent.
Per-call opt-out¶
Mapping can be disabled for a single command invocation without changing the session-level setting:
// Session has mapping enabled (default)
var session = MqRestSession.builder()
.host("localhost").port(9443).queueManager("QM1")
.credentials(new LtpaAuth("admin", "passw0rd"))
.build();
// This call uses native MQSC names
var queues = session.displayQueue("MY.QUEUE",
Map.of("response_parameters", List.of("CURDEPTH", "MAXDEPTH")),
Map.of("mapAttributes", false));
// Returns native MQSC names: [{"queue": "MY.QUEUE", "curdepth": 0, ...}]
Mapping can also be disabled entirely at the session level: