Topics: |
Special registers are named fields of information carried through the system and available to all components and exits. Special registers are created by:
Special register values can be substituted into documents during transformations by use of the SREG() built-in function offered in the iWay Transformer and iWay Designer. Additionally, any configuration parameter can accept the SREG() specification. Special registers are also available as global variables to any process flow. The special service EvalWalk substitutes values in documents while processing in the channel (workflow).
If you use a special register in your own code, be careful that the register is available at the time you request it. For example, a document-specific register such as SREG(msgid) is not available until the document arrives to be processed; it would not be available to an exit init() method.
Although the specific special registers available can vary based upon protocols and situations, a complete list of these registers currently defined is displayed by the XDQAAgent(). This business agent displays the document and other information, and is available as a standard iWay Service Manager business agent when the server is installed.
Registers fall into several categories. You can reference registers in all categories, but normally should create registers only in HDR and USER categories.
Category |
Description |
---|---|
CFG |
Entered at the console. Should never be added or changed by an exit. |
DOC |
Applies to the document. Examples are source and protocol. |
HDR |
Applies to a document delivery header. For example, HTTP headers are carried as special registers; MQ Series RFH2 values are special registers. When a document is emitted, HDR registers are used to form the delivery header. |
SYS |
System information, such as listener name, configuration name, and so on. |
USER |
A variable that you might create to pass information from one part of the system to another. |
The register type can be referenced by the static constant XDSpecReg object, such as XDSpecReg.HDR.
Register names must be unique, regardless of the register type. Creating a register named "acklevel" at USER level replaces one at HDR level.
Register names must conform to the requirements for XML element names. The names are further restricted for HDR registers if the register will be used to form a message header for a protocol that itself has restricted character conventions. Use of the namespace designator '.' is supported for registers in which such namespaces are meaningful. In MQ Series, the namespace character is used to group RFH2 information. Otherwise, such characters are treated simply as part of the name for lookup purposes. Thus for MQ, the section of the RFH2 from which a value was extracted will appear as the namespace.
All non-SYS registers are reset for each document.
Registers are stored in a hierarchy of levels. The levels are, in order highest to lowest:
A process flow cannot set registers into the configuration or protocol levels, as this affects operations outside of the scope of the flow.
When searching for a register, the "nearest" special register repository is searched first, proceeding upward until the register is found. So in a flow, the Thread level is searched first, then upward through thread levels until the flow level is reached. Then upward until the register is found or the register is determined not to be stored anywhere; in this case the default is returned.
Emit operations defined in a flow inherit the existing registers as the emit object is encountered. Changes to registers subsequent to executing the emit object do not affect the emit.
Special Registers are classified into namespaces. Namespaces are simply groups of registers categorized by the first token of their name, which terminates in a dot. The namespace is considered part of the name and must be used for searches, etc. Many components can be configured to store their registers or take their registers from specific namespaces. For example, an nHTTP emit will attempt to make HDR registers into HTTP headers, and will store headers into the HDR portion of the registry hierarchy. Without a namespace the headers would become mixed with other headers in the system, and it would be impossible to separate those dealing with one nHTTP emit from another.
A special process flow agent, XDSregNamespaceAgent, provides namespace support services such as copying, renaming, and deleting.
Name |
Description |
---|---|
lookupSpecialRegister(name,default) |
Returns the value of the special register or the default if the register is not defined. |
lookupSpecialRegisterObject |
Special registers are actually stored as objects, which in turn can hold values of different types, such as Integer or Tree. You can use this method to retrieve the actual object, and then use the XDSpecReg object methods to extract specific information. |
storeSpecialRegister(name, value) |
Stores the value as a special register under the name key at the USER level. Storing null eliminates the register. |
storeSpecialRegister(name, value, type) |
Stores a special register of the specified type. For example, storeSpecialRegister ("john","121",XDSpecReg.HDR); Appears in an HTTP post as john=121. String x = lookupSpecialRegister("john","000"); logger.debug("john is "+x); Prints john is 121. |
deleteSpecialregister(name) |
Deletes the special register. |
getValue() |
Returns the value from the special register object. This is returned as a String and is the usual result of getting the value via lookupSpecialRegister(). |
getObject() |
Returns the object holding the value. This can be any object of meaning to an application. The object has to be set on a new special register or assigned to the register via the setObject() method. |
setObject() |
Sets the object stored in the register. The object reference is marked as volatile and can be locked by synchronization methods. For example, to set its own object, the application can lock on the register, get the current object, update that object, and set the object back. |
Although the list of special registers is updated as needs arise, you can count on at least the following special registers that can be accessed from any exit. All special register names are lowercase.
Name |
Description |
---|---|
<property name> |
Each property associated with a JMS queue is stored in a special register under the name of the property. This includes user properties. |
backoutcount |
Count of the number of times the message has previously been returned by an MQQueue.get() call as part of a unit of work, and subsequently backed out. MQ only. |
config |
For example, if you are running the base configuration, this is "base". |
correlid |
For queue-based listeners, this is the correlation ID. If the value is defined as allowing binary (for example, IBM MQ Series) it may be the base64(value) representation. |
destination |
Reply queue name. |
eos |
'1' if a streamer is running and has read end of stream, '0' if not at end of stream, and undefined if not streaming. |
expiry |
Message expiry in .1 seconds. MQ only. |
format |
Message format. MQ only. |
from |
Incoming email sender. |
groupid |
For queue-based listeners that support groups, this is the group ID. |
ip |
For TCP-based listeners, this is the dot-form IP address of the client. |
msgid |
For queue-based listeners, this is the message ID. If the msgid is defined as allowing binary (for example, IBM MQ Series) it may be the base64(value) representation. |
name |
Name of this server. Names are set by the –n startup parameter. |
outmsgid |
MQ Series only. Sets the outbound msgid to be emitted. |
persistence |
"queue", "persistent", or "non-persistent" to describe the message persistence. MQ, JMS, and SONIC only. |
priority |
Message priority. JMS, SONIC, and MQ only. |
putapplicationname |
Name of the writing application. MQ only. |
protocol |
Name of the protocol of the listener that received this document. |
source |
Origin of the document. For files, this is the file name, for TCP-based listeners, this is the host name of the client, for queue-based listeners, this is the queue name. |
subject |
Subject of incoming email. |
tid |
Transaction ID from this document. This is set to a unique value regardless of whether or not the document is operating in a controlled transaction. |
type |
Queue message type. For example, request, reply, or report. |
userid |
Identifier of the user that put this message. MQ only. |
The configuration console shows special registers appropriate to the listener type being configured.
You can learn which special registers are defined and their current values by executing the XDQAAgent or using the Debug service of a process flow. All special registers are dumped to the output location along with the current document.
Some registers may return values that are "expensive" in terms of system resource such as time or memory. It may be desirable to not actually load the value unless the register is actually checked by an _sreg() call or programmed lookup. An example is a reverse DNS lookup on a connected socket.
To accommodate this situation, register callbacks can be used. A register callback is simply a method that is called when the value of the register is looked up. So, in our example above, the callback method would make the reverse DNS call only if the user actually checks the value.
To establish a callback, first construct the special register. Then call the following:
void setCallback(com.ibi.common.IXSpecRegCallback callback, Object savedO)
This passes in the method reference and an arbitrary object that will be passed to the callback method when the callback is invoked. This will be the actual reference and not a clone; the application is responsible for protecting the value of the object.
When the register is looked up by the program, the callback is invoked. The callback is defined in the IXSpecregCallback interface. The method getSregValue is called. The method is passed to the register object, the name of the register (if known), the current value, and the object stored when the callback was established. The callback must return the value of the register to be returned by the original lookup.
public Object getSregValue(XDSpecReg sreg, String name, Object currentVal, Object savedO) { return "the answer" }