ObjectQ Help Center

  • What is the difference between ObjectQ and DSAP?

    There is no difference. DSAP is the old name for the same product.

  • How do I run the sample code?

  • How do I make my code tolerant of queue manager failures?

    When a queue manager fails, and is brought back up, the application's "handle" is invalid. The application must disconnect, and reconnect to obtain a new handle. It is unusual for a queue manager to fail, but the scenario would be common in the case of failover. This code, adapted from the sample code's server.c, will accomplish recovery.

  • How does my application access the MIB files?

  • How is encryption implemented?

    The server has a pair of private and public keys. It puts its public key into the Service Name Resolution file (*.snr) that is distributed to all clients.


    Each client also has its own pair of private and public keys, although there are default ones built into DSAP in case a client doesn't have them - this is obviously not very secure, although it's better than nothing.


    The keys are made known to the app (both client and server) via environment variables (cpPRIVATEKEY and cpPUBLICKEY) that specify the file names in the same way that the MIB files are specified - that is, they can be either a file name (if locally stored) or a URL (for example, sftp://ec2-user@localhost/home/ec2-user/rsa_key.pub) if they are centrally stored.


    When a client requests encryption via the cpResource object:

    • The client generates a random symmetric key, using AES-256 with a 128 byte initialization vector, and uses this to encrypt the payload. This key is used only once, and another key is generated for the next message.
    • The symmetric key is encrypted using the server's public RSA key, obtained from the .snr file, and the encrypted key is passed in the message as an attribute, along with the client's public RSA key.
    • The request message is sent to the server.

    The server receives the request, and sends a response:

    • The server uses its private RSA key to decrypt the symmetric key passed as an attribute, and the symmetric key is used to decrypt the payload.
    • A response is constructed, and another single-use AES-256 symmetric key is generated and used to encrypt the payload.
    • The symmetric key is encrypted using the client's public RSA key, which was passed as an attribute in the request message, and the response is sent with the encrypted key stored in an attribute of the message.

    The client receives the response:

    • The client uses its private RSA key to decrypt the symmetric key, and this is used to decrypt the payload.
  • What environment variables are used by ObjectQ?

    MQS_QUEUE_MANAGER: The queue manager that an application attaches to, or that is a message destination, may be specified in one of two ways. Either the environment variable MQS_QUEUE_MANAGER should be set to the queue manager's name, or it should be prefixed to the queue name, using a colon separator, in the code or in the Service Name Resolution file. Thus, a message could be sent to the queue TEST on the queue manager QM in any of the following ways:

    • With environment variable MQS_QUEUE_MANAGER set to "QM" and destination queue set to "TEST";
    • With environment variable MQS_QUEUE_MANAGER either not set or set to anything, and destination queue set to "QM:TEST";
    • With environment variable MQS_QUEUE_MANAGER either not set or set to anything, and destination service resolving, via the destName field of the Service Name Resolution file, to "QM:TEST";
    • With environment variable MQS_QUEUE_MANAGER set to "QM" and destination service resolving, via the destName field of the Service Name Resolution file, to "TEST".

    MQS_MODEL_QUEUE: If MQS_MODEL_QUEUE is defined, it represents the name of the model queue that is used instead of the default SYSTEM.DEFAULT.MODEL.QUEUE for creating dynamic queues. If MQS_DYNAMIC_QUEUE_NAME is defined, it serves to specify the name of the dynamic queue. This may include the wildcard "*". More information can be found in the IBM Knowledge Center.


    MQS_MAX_OPEN_QUEUES: When queues are opened in order to send a message, they are kept open, for efficiency reasons. Under certain circumstances, this can result in enough queues being held open that MQ resources are exhausted. Specifying the maximum number of simultaneously open queues allows the oldest of these queues to be closed before a new one is opened. If no environment variable is defined, the default value is 10.


    REGDOMAIN: If this environment variable is set, it specifies a filename from which the Domain Table is populated; if it is not set, the domain data is loaded from a file named regdomain in the current directory. The environment variable may also specify a URL from which the domain information is obtained. For example, it could be set to sftp://oq-user@example.com/home/oq-user/MIBs/regdomain or file://localhost/MIBdata/regdomain.


    cpMAXMSGSIZE: The default maximum message size can be specified at instantiation time, but, if not, will default to the value contained in this environment variable, or 32000 if the environment variable is unset.


    cpTRACEDIR: The log file will be located in the directory named in this environment variable. If this environment variable is not set, the log file will be written in the current directory.


    cpENCRYPT: To enable encryption, set this environment variable. If the content is empty, messages to all services are encrypted. To encrypt messages to a subset of services, provide a list of those services, thus:

     export cpENCRYPT=Demo.Sales,Demo.Accounts

  • What are the support requirements and interoperability characteristics of ObjectQ?

    The support requirements and interoperability for the available versions of ObjectQ are tabulated here.

  • What is ObjectQ?

    ObjectQ is an umbrella middleware product that provides a uniform application programming interface (API) to all the major message queuing products, allowing applications to switch transparently from one to another.


    ObjectQ also supports a methodology for developing end-to-end client/server solutions that are loosely coupled, such that either side can change without requiring simultaneous changes on the other side.


    The server side interface of an ObjectQ architecture is defined via a management information base (MIB) that completely specifies the services it provides, allowing development of clients without server-side personnel intervention.

  • Why do I need ObjectQ?

    ObjectQ simplifies system design by supplying a consistent framework for architecture development, and then providing a ready-made infrastructure that can be used to implement it.


    ObjectQ systems typically scale well, are simpler to maintain and upgrade, and provide the independence from the underlying transport vendor that allows applications to take advantage of advances in technology without costly rewriting of code.

  • How do I get ObjectQ?

    ObjectQ is available from Information Design, Inc., a leader in middleware training,testing and consulting. Call us at 203-245-0772, or visit our web site at http://www.idi-middleware.com/



  • What platforms are supported?

    The main platform supported is RHEL 7.x. Earlier versions Linux, as well as Solaris, HP/UX, AIX and Windows are also supported - contact us for details.



  • What is the most current version of ObjectQ?

    There are two branches of C++ ObjectQ. The older branch is based on the Lucent C++ Standard Components library, and is supported only on platforms for which Lucent SCL is available. The latest revision of this branch is 4.2.6.


    The newer ObjectQ branch is based on the Standard Template Library, which is available with most C++ compilers. This removes the requirement for the Lucent C++ Standard Components Library, which Lucent no longer supports actively. The latest release in this branch is ObjectQ 6.1.


    The latest version for Java ObjectQ is 6.2.

  • Are all versions of ObjectQ interoperable?

    Yes - the 6.0.x branch of ObjectQ is completely interoperable with the 4.x branch, as the wire protocol is the same. Interoperability between version 6.1/6.2 and earlier versions is subject to some restrictions - see the Release Notes.

  • Is ObjectQ thread safe?

    No. Part of the reason for this is that underlying transports may not be thread safe.

  • How do I convert my code to use version 6.x, from version 4.x?

    Here's a summary of the changes that are required to application programs to convert from using SC (Standard Components) to STL (Standard Templates Library):


    • STL has no equivalent of the Time class in SC. There are no interfaces to ObjectQ that require this, but application programs will need to provide their own equivalent, or use the standard Unix time functions if they require it.
    • The String class is replaced by std::string. This is widely used. The functionality is largely the same, but method names are different - for example, strchr() in SC is replaced by find() in STL, and chunk() is replaced by substr(). Because it�s so heavily used, the changes are tedious, but not difficult.
    • The Map class is replaced by std::map. Once again, there are no interfaces to ObjectQ that require this, but applications that use it themselves will need to change. Although the functionality is essentially the same, the syntax is sufficiently different to make the changes a manual, rather than automated, task.
    • The List class is replaced by std::list. This is used in a number of ObjectQ interfaces. Like std::map, the functionality is essentially the same, but the syntax is sufficiently different to make the changes a manual, rather than automated, task.

    The sample code that comes with the distribution provides a good illustration of these changes.

  • If a server sends multiple messages to a client, are they guaranteed to arrive in the same order as sent?

    Yes, as long as the same delivery mode (no assurance, partial assurance, or full assurance)is used for each message, and selectors are not used to read the messages in an orderother than FIFO.



  • Why is one of my attributes reported as unrecognized?

    Within an application, attributes are referred to by name (e.g., myService.date); within messages, they are referred to by registered name (e.g., 136.28.2.3).The mapping between these two is contained within the MIB, which is loaded by both sides at run time. Attributes specified on one side, and not on the other, will be unrecognized on the other side. This will do no harm, as unrecognized attributes are simply ignored - but this is often an indication of a typographical error.


    Similarly, if attribute names are mistyped within an application (and trailing or leading spaces constitute mistyping), they will also be unrecognized.



  • Why do I get unresolved references from the linker?

    In order to be run-time-switchable between different transport vendors, the ObjectQ library must obviously know how to interface with each. When you link your applications, you must provide libraries for each of the transports you want to use; for those that you don't use,we provide "stub" or "fake" libraries that you should also link against - if you don't, you will see unresolved references to, for example, functions like tpsend (Tuxedo), or MQ_PUT (WebSphere MQ), or pams_put_msg (BEA messageQ).

  • Shouldn't the HTTP transport accept IP addresses as well as host names?

    Yes, it should - but there is currently a bug in the software that handles the service name resolution (.snr) file that prevents IP addresses from being recognized as such.



  • How can I tell if registerPrimary() has already been called?

    The transport manager has a function transport() that takes either a service name or a vendor type as argument, and returns a pointer to a transport object - if it returns 0, registerPrimary has not been previously called for this service/vendor.

  • What vendor transports does ObjectQ support?

    ObjectQ supports: BEA's messageQ, IBM's Websphere MQ, BEA's Tuxedo, AMQP, and raw TCP/IP.



  • Can I control the naming and characteristics of temporary queues?

    Yes, but only for WebSphere MQ. There are two environment variables that separately or together control naming.

    The environment variable MQS_MODEL_QUEUE defines the name of a model queue to use instead of the default SYSTEM.DEFAULT.MODEL.QUEUE. This can have any characteristics that are allowable for a model queue.

    The environment variable MQS_DYNAMIC_QUEUE_NAME defines the format of the generated name of the dynamic queue, and may include the wildcard character "*", according to the usual MQ rules.

  • Can transports be changed on-the-fly?

    The type of vendor to be used is specified at run time via the service name resolution (.snr) file. Changing from one vendor to another is simply a matter of changing a parameter in this file, and restarting the application. Of course, not all features of the API are supported by all vendors - so, for example, Tuxedo does not support message selection, so that selectors used on a Tuxedo transport will be ignored. The manual pages identify the features supported by each transport.

  • Can more than one transport be used in an application?

    Yes - as many as needed can co-exist. In fact, it is common for a client to use one transport vendor for a particular service, and a different transport vendor for another. If more than one of the services accessed use the same transport vendor, a single transport object will be created to handle both.



  • Does ObjectQ support encryption?

    Yes, using the BSAFE library from RSA Technology. Public key encryption is used.



  • How do I use the new style callbacks?

    The traditional method of using callbacks relies on functions having well-known names,so that, for example, a manager is expected to have functions named responseHandler,eventHandler and timeoutHandler, an agent is expected to have a function namedrequestHandler, and an application requester object is expected to have functions named notifyComplete, notifyPartial and notifyEvent.


    Release 4.1 and beyond allow the callback functions to have names of your own choosing,and provide registration mechanisms in support of this.


    If you are:


    - subclassing the generic manager - there are 6 protected variables which correspond to pointers to callback functions, which, if non-zero, will be called in preference to the well-known named functions; they are:

    • _completeCallBack - the address of a function taking a pointer to a manager as its argument; this function will be called instead of notifyComplete.
    • _partialCallBack - the address of a function taking a pointer to a manager as its argument; this function will be called instead of notifyPartial.
    • _eventCallBack - the address of a function taking a pointer to a manager as its argument; this function will be called instead of notifyEvent.
    • _dispatchCallBack - the address of a function taking a pointer to an envelope as its argument; this function will be called instead of responseHandler.
    • _eventHdlrCallBack - the address of a function taking a pointer to an envelope as its argument; this function will be called instead of eventHandler.
    • _timeoutCallBack - the address of a function taking no arguments; this function will be called instead of timeoutHandler.

    - developing an agent - the registerServer and unregisterServer functions of the Dispatcher are overloaded to take the address of a function taking a pointer to an envelope as its argument, in place of the agent's address.


    - developing application code - both the dispatcher and the manager have overloaded functions to allow registration of the callback functions:

    • registerMessage (dispatcher) - the callback function should take a pointer to an envelope as its argument; this function will be called instead of responseHandler.
    • registerEventHandler (dispatcher) - the callback function should take a pointer to an envelope as its argument; this function will be called instead of eventHandler.
    • registerAdminHandler (dispatcher) - the callback function should take a pointer to an envelope as its argument; this function will be called instead of adminHandler.
    • registerCompleteCallBack (manager) - the callback function should take a pointer to a manager as its argument; this function will be called instead of notifyComplete.
    • registerPartialCallBack (manager) - the callback function should take a pointer to a manager as its argument; this function will be called instead of notifyPartial.
    • registerEventCallBack (manager) - the callback function should take a pointer to a manager as its argument; this function will be called instead of notifyEvent.
  • How does a client use a named queue?

    There are three versions of the registerPrimary() call: the first, with vendor and cpHandle parameters registers an unnamed (or temporary queue); the second specifies a queue or service name as its first parameter, and a cpHandle as the second parameter; the third version specifies a vendor, a queue, a cpHandle, and a parameter that indicates how the queue is specified.


    The first version is used by a client to register an unnamed queue, the second by a server registering a named queue, and the third can be used by a client wishing to register a named queue. In this last case, the fourth parameter should be specified either as cpQUEUE_ALIAS (the first parameter is the alias for a queue, such as "MYQUEUE") or cpQUEUE_NAME (the first parameter is the name of a queue in native transport format, such as "145.51" for BEA MessageQ).

  • What are all those MIB files for?

    The MIB is the Management Information Base. It constitutes a contract between a client and a service, defining the details of the service provided. It exists in two forms: a human-readable document, and machine-readable files that are derived from the document. Some of the information in the document is not represented in the files – an example would be containment trees – and thus cannot be enforced by ObjectQ. However, since this information is part of the contract, it almost certainly will be enforced by the service – ObjectQ’s only responsibility is to transport the data. If a client sends data to a service that the service is not contractually bound to handle, an error response will usually result. It is always the service-provider that generates the MIB. So, what are all the files? Most of the information can be found in the “MIB Files” section of the Reference Guide, but here’s a brief summary:


    regdomain: Every piece of data transported by ObjectQ has 3 major components: its type (string or integer, for example), its value, and its registered name. The application programmer will normally never see the registered name – in code, each data element is represented as a string “domain.name”. The domain prevents name clashes between different service-providers; within a domain, names can be allocated as desired, with the single proviso that they should be unique within the domain. To conserve bandwidth, ObjectQ transports the string “domain.name” in a form resembling an IP address: “a.b.c.d”, where each component is in the range 0 to 255. The first part, “a.b” corresponds to the domain, and the regdomain file contains the mapping between the string used by the application programmer and its ObjectQ representation.


    .cdf: The attributes, or data elements, transported by ObjectQ are grouped according to the class they belong to (where a single attribute can belong to more than one class). The human-readable MIB will explain the relationships between the classes; the Class Definition Files contain the mapping between the string used by the application programmer and its ObjectQ representation. Thus, in the domain “FOO”, represented internally by, say, “5.1”, the class “BAR” might be represented internally by “6.3”. The application programmer uses “FOO.BAR” to refer to the class, whereas ObjectQ uses “5.1.6.3”.


    .sdf: The Service Definition File contains the mapping between the string representation of the service name and its ObjectQ representation.


    .edf: Every potential error that could be returned by a service provider is defined in the human-readable MIB. The machine-readable Error Definition File contains the mapping between the string representation of the error and its ObjectQ representation.


    .adf: The Attribute Definition File contains a complete list of all attributes within the domain, along with their type and registered name. Each of these attributes will belong to one or more of the classes defined in the Class Definition File.


    .mdf: The Administrative Command Definition file contains the mapping between administrative commands (of which the most common is “echo”) and their registered names.


    .snr: The Service Name Resolution file is the mechanism that ObjectQ uses to map a service to a specific transport provider, and to particular objects (queues, for example) within the transport. See the man page for the SNR Data File for details of its format.

  • How do I make sense of a trace file?

    One of the parameters to the cpInit() method is an integer value that specifies a trace level. The default value is 0, meaning that no trace is generated. A value greater than 0 will cause a trace file (named cpTRACEFILE.<pid>) to be generated either in the directory from which the application was started, or in a directory specified by the environment variable cpTRACEDIR. The most useful value for the parameter is 4; less than that tends to provide too little information, while 5 (the maximum value) generates too much.


    The first thing you'll see in the trace file is the MIB files being read in - each file's full path name is traced, so that you can see where the MIB files are stored. The first file to be read is regdomain, populating the domain table; once it is read in, the complete domain table is dumped to the trace file. Then come the class files (.cdf), the attribute definition files (.adf), the service definition files (.sdf) and the error definition files (.edf). These are followed by the service name resolution files (.snr), after which initialization is complete.


    Any application usually starts (after initialization) with an invocation of registerPrimary(), and this is a good place to start looking at what�s going on in the application. Whenever an underlying vendor API is called (like pams_attach_q() for BEA messageQ), the parameters passed in and out are traced � this will give a good indication of whether there are problems related to the transport itself. A good understanding of how the application is behaving can be obtained by merely looking at the results of each API call.


    The complete contents of every envelope, and every message within an envelope, are traced out before sending and after receipt. Some of the contents will be intelligible to an application programmer, but mostly this is of use to ObjectQ support personnel.

  • What is the point of using a manager instead of just sending messages?

    ObjectQ is a service-oriented architecture (SOA) that pre-dates many of the currently available SOAs. There are many definitions of SOA, but the over-riding principles are the following:


    • The service-provider is responsible for providing a complete definition of the capabilities and limitations of the service. The client-server interface is non-negotiable (except that the client may request additional functionality from the service-provider, which may or may not be honored).
    • The interface is loosely-coupled, so that a change on either client- or server-side does not need to be mutually coordinated.
    • The underlying implementation of the service is completely transparent to the client.

    The last bullet is crucial. It means not only that the client should not be aware of whether the server is using Oracle or Sybase, Java or C++, or Solaris or Windows, but ideally that the communications infrastructure is also transparent. This transparency is more difficult to achieve: how do you make a client unaware of whether it is using a web services interface, or WebSphere MQSeries, or BEA MessageQ, or CORBA?


    The answer, of course, is to make use of ObjectQ's concept of a manager. The manager is a �proxy� for the service, and should be developed and supported by the service provider. ObjectQ itself provides a cpManager class that supports all the basic functionality of a manager; in addition, it provides a cpGenericMgr class that illustrates how the basic paradigms of, for example, the synchronous and asynchronous model (in addition to many others) can be supported.


    The vision of ObjectQ was never that the cpGenericMgr be widely used in its raw form, but rather that it be sub-classed to provide service-specific interfaces for clients that reflect their view of the service more closely.


    So, for example, a Trouble Ticket service manager might provide a function EscalateSeverity which would:


    • Send a message to the service requesting that the severity be incremented.
    • If the severity escalation was to a critical level, send a pager notification to the duty manager.
    • Provide email verification to the client of the escalation.

    There is an inherent problem with service-providers supporting the vision; whatever software they provide must be capable of running on a variety of platforms, with a variety of language interfaces. Far too often they abdicate their responsibility and fall back on the capabilities of the Generic Manager.


    A manager is a lightweight object. As such, it is designed to handle a single request and associated response(s). Ideally, for each request (synchronous or asynchronous), a manager should be created, and subsequently deleted. It is certainly possible to re-use a manager for multiple requests, but, in order to do so, it needs to be reset to an initial blank slate between requests. The generic manager provides a method reset to do this.

Share by: