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 the library at runtime, but they formed the intermediate namespace during the original extraction process that bootstrapped the mapping tables.
- Developer-friendly names (e.g.
current_depth,default_persistence) - Human-readable names for use in application code.
The mapping pipeline translates between MQSC and developer-friendly names. PCF names were used as an intermediate reference during the original extraction process but do not appear at runtime.
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.
Request mapping flow¶
When mapping is enabled, request attributes are translated before sending to the MQ REST API:
-
Key mapping: Each developer-friendly attribute name is looked up in the qualifier's request 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 map translates developer-friendly 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 map handles cases where a single attribute expands to a different MQSC key+value pair (e.g.
channel_type="server_connection"→CHLTYPE("SVRCONN")).
In Ruby, request mapping happens inside the private mqsc_command method
before the payload is sent. The Mapping.map_request_attributes module
method handles the translation:
# Internal flow (simplified)
mapped = Mapping.map_request_attributes(
qualifier, attributes,
strict: @mapping_strict, mapping_data: @mapping_data
)
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 the developer-friendly name.
-
Value mapping: Enumerated MQSC values are translated to developer-friendly values via the response value map (e.g.
"YES"→"yes").
Response parameter mapping¶
When the caller specifies response parameters (the list of attributes to return), those names are also mapped from developer-friendly names to MQSC before being sent in the request. This allows callers to request specific attributes using their preferred naming convention.
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_depth GT 100". The first token (the keyword) is mapped from the
developer-friendly name to the MQSC name. The rest of the expression is passed
through unchanged.
Response mapping happens after the HTTP response is parsed. The
Mapping.map_response_list module method handles batch translation:
# Internal flow (simplified)
mapped = Mapping.map_response_list(
qualifier, parameter_objects,
strict: @mapping_strict, mapping_data: @mapping_data
)
Custom mapping overrides¶
The built-in mapping tables cover all standard MQSC attributes, but sites may use different naming conventions. The mapping overrides mechanism 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. A single override entry doesn't affect the hundreds of other mappings.
When an override is applied:
- The built-in mapping data is deep-copied (the original is never mutated).
- The specified qualifier's sub-map is updated: the entry for the overridden key changes to the new value.
- All other entries in that sub-map (and all other sub-maps) remain unchanged.
Supported override keys¶
The top level of overrides 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 — developer-friendly → MQSC key mapping for requests
- request value map — value translations for request attributes
- request key-value map — combined key+value translations for requests
- response key map — MQSC → developer-friendly key mapping for responses
- response value map — value translations for response attributes
Adding new qualifiers¶
You can add mappings for qualifiers not yet covered by the built-in data by providing a complete qualifier entry in the overrides.
Validation¶
The override structure is validated at session construction time. Invalid shapes raise errors immediately, so problems are caught before any commands are sent.
Opting out¶
Mapping can be disabled entirely or selectively:
- Session-level: Disable mapping when creating the session.
- Per-call: Disable mapping for a single command invocation.
When mapping is disabled, attributes pass through in their native MQSC form.
In Ruby, overrides are passed when creating the session:
overrides = {
'qualifiers' => {
'queue' => {
'response_key_map' => {
'CURDEPTH' => 'queue_depth'
}
}
}
}
session = MQ::REST::Admin::Session.new(
'https://localhost:9443/ibmmq/rest/v2', 'QM1',
credentials: MQ::REST::Admin::BasicAuth.new(username: 'admin', password: 'admin'),
mapping_overrides: overrides,
mapping_overrides_mode: :merge # or :replace
)
Strict vs lenient mode¶
Strict mode (default): Any attribute name or value that cannot be mapped raises an error. This catches typos and unsupported attributes early.
Lenient mode: 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 creation and applies to all mapping operations.
Qualifier resolution¶
When a command is executed, the mapping qualifier is resolved by:
- Looking up the command key (e.g.
"DISPLAY QUEUE") in the command metadata for an explicit qualifier. - Falling back to a 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.
In Ruby, strict mode raises MappingError with an issues attribute
containing an array of MappingIssue objects: