ObjectQ - FAQ

...... Return to "Release Notes" page ......

Questions:

  1. What is the difference between ObjectQ and DSAP?
  2. How do I run the sample code?
  3. How do I make my code tolerant of queue manager failures?
  4. What is ObjectQ?
  5. Why do I need ObjectQ?
  6. How do I get ObjectQ?
  7. What platforms are supported?
  8. What is the most current version of ObjectQ?
  9. Are all versions of ObjectQ interoperable?
  10. Is ObjectQ thread safe?
  11. How do I convert my code to use version 6.x, from version 4.x?
  12. If a server sends multiple messages to a client, are they guaranteed to arrive in the same order as sent?
  13. Why is one of my attributes reported as unrecognized?
  14. Why do I get unresolved references from the linker?
  15. Shouldn't the HTTP transport accept IP addresses as well as host names?
  16. What is the maximum size message ObjectQ can handle?
  17. How can I tell if registerPrimary() has already been called?
  18. What vendor transports does ObjectQ support?
  19. Can I control the naming and characteristics of temporary queues?
  20. Can transports be changed on-the-fly?
  21. Can more than one transport be used in an application?
  22. Does ObjectQ support encryption?
  23. How do I use the new style callbacks?
  24. How does a client use a named queue?
  25. What are all those MIB files for?
  26. How do I make sense of a trace file?
  27. What is the point of using a “manager” instead of just sending messages?
  28. How do I run the sample code?

Answers

  1. What is the difference between ObjectQ and DSAP?

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

  2. How do I run the sample code?

    See here.

  3. 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.

  4. 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.

  5. 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.

  6. 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/

  7. What platforms are supported?

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

  8. What is the most current version of ObjectQ?

    There are two branches of 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.0.4a. For DmQ on Solaris, the functionally equivalent 6.0.2b may also be used (since changes between 6.0.2b and 6.0.4a relate to WMQ only).

  9. Are all versions of ObjectQ interoperable?

    Yes - the 6.x branch of ObjectQ is completely interoperable with the 4.x branch, as the wire protocol is the same.

  10. Is ObjectQ thread safe?

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

  11. 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.

  12. 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.

  13. 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.

  14. 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).

  15. 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.

  16. What is the maximum size message ObjectQ can handle?

    ObjectQ can handle any size of message - it's the underlying transport that is usually limited. ObjectQ will default to a maximum of 32000 bytes, unless you supply an environment variable, cpMAXMSGSIZE, containing a different value. The service name resolution (.snr) file can also limit the size of messages. Note that if you try to build a message that is larger than 32000 (or the value specified in cpMAXMSGSIZE), you will be advised, via a status return code, of an overflow condition; if you try to send a message larger than the transport supports, you will receive a vendor return code.

  17. 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.

  18. What vendor transports does ObjectQ support?

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

  19. 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 (see here).

  20. 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.

  21. 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.

  22. Does ObjectQ support encryption?

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

  23. 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.

  24. 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).

  25. 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.

  1. 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.

  1. 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.

...... Return to "Release Notes" page ......