Monitoring adapter status

Status information is available between the correlator and an adapter. When developing an IAF adapter, the adapter author can provide the ability to make use of this status information. Basic information, such as whether an adapter is up or down, is available using a standard Apama monitor. Other information, such as the number of connections an adapter has, can be provided by using the getStatus() method in an adapter’s transport and codec. Optionally, adapter authors can also add code to the adapter’s service monitors to send and receive specific status information that application developers can then use when they write Apama applications that connect to the adapters.

Apama provides the following two mechanisms for handling IAF Adapter status information:

  • IAFStatusManager — The IAFStatusManager manages the connection status and other status information from the adapter to the correlator. In order to retrieve adapter status information, the IAFStatusManager needs to be injected into the correlator and the adapter author needs to add a small amount of code to the adapter. Application authors can then make use of status information available from the IAFStatusManager.

    Illustration of how the IAFStatusManager retrieves status information

    For information on using the IAFStatusManager, see IAFStatusManager

  • StatusSupport — StatusSupport is a generic interface (or contract) between an Apama application and an adapter’s service monitors. This interface provides a way to provide an application with a similar view of all the status information available from multiple adapters. In order to use the StatusSupport interface, an adapter author writes code in the adapter’s service monitors that send or receive specific StatusSupport events. In turn, the application author writes code to implement the desired behavior for handling the StatusSupport events.

    Illustration of how the StatusSupport interface retrieves status information

    Using the StatusSupport interface is optional. For more information on using this interface, see StatusSupport.

IAFStatusManager

The IAFStatusManager translates events from the adapter into simple status events for applications to consume. The monitor, IAFStatusManager.mon is found in the Apama installation’s adapters\monitors directory. In order to use the monitor:

  • The adapter author is required to return information about the adapter’s open connections in the adapter’s getStatus method, which is called every few seconds when the IAFStatusManager service monitor polls the IAF for status. Adapters written in Java must return an ExtendedTransportStatus or ExtendedCodecStatus object from getStatus(); adapters written in C++ must return AP_EventTransportStatus or AP_ExtendedCodecStatus.
  • The adapter may optionally also send notifications about a connection as soon as it is opened or closed, by sending a normalized event representation of the AdapterConnectionOpened or AdapterConnectionClosedevents to the correlator. This simply allows the correlator to find out about connectivity change more quickly than is the case if it needs to wait for the next status poll.

The IAFStatusManager has the following interfaces:

  • An application interface to communicate with the consumers of the adapter status information — usually adapter service monitors.
  • An IAF adapter interface is optional and can be used by adapter authors to issue connection notifications.

Application interface

The IAFStatusManager.mon file defines the event interface between it and a consumer of an adapter’s status information, which is usually an adapter’s service monitor. The application interface can be used to communicate status information to both the adapter’s service monitors as well as Apama applications.

The application interface events are either input events or output events. Input events are sent from a consumer of adapter status information to the IAFStatusManager. Output events are sent from the IAFStatusManager to a consumer of adapter status information.

Input events

The IAFStatusManager is a subscription-based interface. This means that a consumer of adapter status information (such as an application service monitor) needs to send the input events listed below to register or deregister as a consumer for adapter status information.

The IAFStatusManager defines the following input events:

  • The AdapterStatusRegister event is sent by a client that is interested in receiving status events from the specified codec and transport. The fields of this event uniquely identify a subscription.

    Once a subscription is made to the IAFStatusManager, the IAFStatusManager periodically receives information from the adapter and begins sending status information to the registered consumer in the form of output events (see below).

  • The AdapterStatusDeregister event is sent by a client that wants to remove its subscription for status events.

See the API reference for EPL (ApamaDoc) for more details on the IAFStatusManager and the above events.

Output events

Once a consumer of status information (such as an application service monitor) is registered with the IAFStatusManager, it begins to receive status information in the form of IAFStatusManager output events. Output events include connection information, adapter availability, and any custom information put into the dictionary by the transport or codec. For more information about adding custom information, see Connections and other custom properties.

The IAFStatusManager defines the following output events:

  • The AdapterUp event is used to notify registered clients that the specified adapter process is running.
  • The AdapterError event is used to notify registered clients that there is a problem with the subscription.
  • The ConnectionOpened event is used to notify registered clients that a connection between the adapter and the external system it communicates with has successfully been established.
  • The ConnectionClosed event is used to notify registered clients that a connection between the adapter and the external system it communicates with has been closed.

See the API reference for EPL (ApamaDoc) for more details on the IAFStatusManager and the above events.

Returning information from the getStatus method

The adapter’s transport and codec getStatus methods periodically update status information. The transport and codec send this information to the IAFStatusManager.

To take advantage of the IAFStatusManager for an adapter written in Java, the adapter author should implement the getStatus method so that it returns an ExtendedTransportStatus or ExtendedCodecStatus object. These objects include a Properties parameter, statusInfo, which contains custom information about the adapter. See the API reference for Java (Javadoc) for detailed information on the ExtendedTransportStatus and ExtendedCodecStatus classes.

For adapters written in C or C++, the adapter author should implement the getStatus function to include the statusDictionary in an AP_EventTransportStatus or AP_EventCodecStatus structure. See the API reference for C++ (Doxygen) for detailed information on the AP_EventTransportStatus and AP_EventCodecStatus structures.

The IAFStatusManager then forwards the information to registered consumers of that transport or codec’s status information in the form of a dictionary added to the AdapterUp event.

Example

In the following example, the custom status information for VERSION and CONNECTION is included in the information returned by the getStatus method:

public static final String TRANSPORT_VERSION="1";
        protected long connGeneration;
...
        public TransportStatus getStatus()
        {
           Properties properties=new Properties();
           properties.setProperty("VERSION", TRANSPORT_VERSION);
           if(market!=null)
           {
             properties.setProperty("CONNECTION",
             String.valueOf(connGeneration));
           }
           return new ExtendedTransportStatus("OK", numReceived, numSent,
             properties);
        }

For more information on specifying the CONNECTION property, see Asynchronously notifying IAFStatusManager of connection changes.

Connections and other custom properties

An adapter may deal with no connections, a single connection, or an arbitrary number of connections (for example, if it is a server socket that accepts clients connecting to it); an adapter may also deal with a set number of connections. In any case, an identifier needs to be assigned to each connection. A connection may be broken and then reconnected, with either the same or different identifier. It is useful to be able to detect a connection that has been dropped and then reconnected even if it has the same identifier. To facilitate this, a “generation” identifier can be associated with each connection identifier. While typically this generation identifier will be a number that is incremented, extra information may be contained in it.

Monitors can therefore detect when a connection has been reconnected; at this point any logon procedure needs to be repeated as the generation identifier has changed.

The state of all connections should be supplied in the statusDictionary field of the status struct in C/C++, or the statusInfo field of the ExtendedCodecStatus or ExtendedTransportStatus in Java.

Along with any other custom information, the adapter author can include connection information here. This will be passed to the correlator in event form and the IAFStatusManager will automatically attempt to pull out connection information from this data structure. If there is a single connection, a key should be supplied called CONNECTION. The value will be the generation identifier, typically a number. If the generation identifier changes, the IAFStatusManager will assume the connection has been dropped and reestablished, and will send appropriate events to the consumer of the status events.

If there are multiple connections, a key for each one should be supplied in the form CONNECTION_*<id>* to distinguish the different connections. Each one will also have a generation identifier associated with it. The same rules apply with the generation identifier as with a single connection.

In either case, if the connection is up, the property should be included, and if the connection is down, the property should not be included. This allows monitors to recover the state of what connections are made after losing connection to the IAF, and to determine when connections are opened or closed by polling.

The following Java example shows a simple adapter that reports the status of a single connection.

private long connectionGeneration = System.currentTimeMillis();
public TransportStatus getStatus()
{  Properties properties = new Properties();
  properties.setProperty("VERSION", "MyTransport_v1.0");
  properties.put("CONFIG_VERSION", "1");

  if (connected)
  {
    properties.setProperty("CONNECTION",
      String.valueOf(connectionGeneration));
  }
  return new ExtendedTransportStatus("OK", totalReceived,
      totalSent, properties);
}

The following Java example demonstrates usage with multiple connections, iterating through a collection of MyConnection objects.

public TransportStatus getStatus()
{  Properties properties = new Properties();
  properties.put("VERSION", "MyTransport_v1.0");
  properties.put("CONFIG_VERSION", "1");
  for (MyConnection con : connections.values())
  {
    if (!con.isClosed())
    {
      properties.put("CONNECTION_" + con.getId(), con.getGeneration());
    }
  }
  return new ExtendedTransportStatus(statusMessage, totalReceived,
      totalSent, properties);
}

Asynchronously notifying IAFStatusManager of connection changes

In addition to returning status information in response to a poll from the IAFStatusManager, an adapter may also send out events asynchronously when a connection is opened or closed.

This is done by creating and sending a NormalisedEvent object from the transport or codec to the semantic mapper. The NormalisedEvent object has special fields that allow for automatic mapping to an Apama event type — either AdapterConnectionOpened or AdapterConnectionClosed. The AdapterConnectionOpened and AdapterConnectionClosed events are then sent through the correlator to the IAFStatusManager.

The NormalisedEvent must have the following fields:

Field name Field value
AdapterConnectionOpenEvent or AdapterConnectionClosedEvent No value (empty string). This will either represent a connection opened or connection closed and be translated into AdapterConnectionOpened or AdapterConnectionClosed events respectively for the IAFStatusManager to consume.
codecName Name of codec.
transportName Name of transport.
connectionName No value (empty string) if there is only one connection. If there is more than one connection, this should contain CONNECTION_*<id>* and one event should be sent for every connection the adapter is concerned with.
connectionGeneration Connection generation identifier. This identifies a successful connection attempt with a connectionName. If the connection fails, then is successfully connected again, this should change. This is usually a number that is incremented.

This connection information should have a direct correlation to the connection information sent in the getStatus implementation. Note that if the transport deals with only a single connection at a time, the connectionName will be "" (the empty string) instead of CONNECTION, as it is in the getStatus implementation.

The following is an example in Java of sending a NormalisedEvent that provides status information.

protected void sendAdapterConnectionStatusChangeNotification(boolean open,
       String reason, TimestampSet tss)
{
  if(decoder==null) return;
  NormalisedEvent ne=new NormalisedEvent();
  ne.add("codecName", codecName);
  ne.add("transportName", transportName);
  if(reason==null)
  {
    reason="";
  }
  if(open)
  {
    ne.add("AdapterConnectionOpenEvent", reason);
  }
  else
  {
    ne.add("AdapterConnectionClosedEvent", reason);
  }
  ne.add("connectionGeneration", String.valueOf(connGeneration));
  ne.add("connectionName", "");
  try
  {
    decoder.sendTransportEvent(ne, tss);
  }
  catch (CodecException e)
  {
    logger.error("Could not send message due to Codec error: ", e);
  }
  catch (SemanticMapperException e)
  {
    logger.error("Could not send message due to Semantic Mapper
        error: ", e);
  }
}

Note: When using these events, the (J)NullCodec must be used, unless you write a codec that handles these and passes them on to the correlator. For example, the XMLCodec by default will not forward these events to the semantic mapper. If you want to use the XMLCodec, you need to use the (J)NullCodec as the codec to send these particular events.

For more information on the implicit rules that the semantic mapper uses to automatically map the objects to AdapterConnectionOpened and AdapterConnectionClosed events, see Mapping AdapterConnectionClosed and AdapterConnectionOpened events.

Mapping AdapterConnectionClosed and AdapterConnectionOpened events

As described in Asynchronously notifying IAFStatusManager of connection changes, the semantic mapper contains implicit rules to map NormalisedEvent objects that contain special fields to AdapterConnectionClosed and AdapterConnectionOpened events. This means you do not need to add mapping rules to your adapter’s configuration file. These implicit rules are:

<event name="AdapterConnectionClosed"
       package="com.apama.adapters"
       direction="downstream"
       breakDownstream="false">
  <id-rules>
    <downstream>
      <id fields="codecName,
                  transportName,
                  connectionName,
                  connectionGeneration"
          test="exists"/>
      <id fields="AdapterConnectionClosedEvent"
          test="exists"/>
    </downstream>
  </id-rules>
  <mapping-rules>
    <map apama="codecName"
         transport="codecName"
         type="string" default=""/>
    <map apama="transportName"
         transport="transportName"
         type="string" default=""/>
    <map apama="connectionName"
         transport="connectionName"
         type="string" default=""/>
    <map apama="connectionGeneration"
         transport="connectionGeneration"
         type="string" default=""/>
  </mapping-rules>
</event>
<event name="AdapterConnectionOpened"
       package="com.apama.adapters"
       direction="downstream"
       breakDownstream="false">
  <id-rules>
    <downstream>
      <id fields="codecName,
                  transportName,
                  connectionName,
                  connectionGeneration"
          test="exists"/>
      <id fields="AdapterConnectionOpenEvent"
          test="exists"/>
    </downstream>
  </id-rules>
  <mapping-rules>
    <map apama="codecName"
         transport="codecName"
         type="string" default=""/>
    <map apama="transportName"
         transport="transportName"
         type="string" default=""/>
    <map apama="connectionName"
         transport="connectionName"
         type="string" default=""/>
    <map apama="connectionGeneration"
         transport="connectionGeneration"
         type="string" default=""/>
  </mapping-rules>
</event>

StatusSupport

Consumers of the IAFStatusManager events are typically the adapter service monitors. In some cases it may desirable for an Apama application to have a more generic view of components and their status information so that getting status information will look the same across all components in a system, regardless of component type. For example, in addition to the information provided by the IAFStatusManager such as whether the adapter is up or connected, it may be useful to provide confirmation that the adapter has successfully logged in to an external system or a message that the external system is down.

Apama provides an interface called the StatusSupport event interface to help define this. It allows applications (EPL code) to see state from service monitors such as the adapter service monitors. In order to implement this behavior, adapter authors add code to the adapter service monitors to handle the various StatusSupport events. Developers of Apama applications can then add code to take appropriate actions for the StatusSupport events to their applications that use the adapters. In this way, an application can act as a “health monitor” and be notified when a component is down or what its status is at any given time.

The StatusSupport events are described in StatusSupport events.

The StatusSupport event interface is a subscription based interface, so consumers of this information will need to subscribe before receiving status information. The adapter service monitors need to reference count the status subscribers, so they do not stop sending status information if there are any interested consumers left. A subscription will only be removed when the call to remove the last one is made.

StatusSupport events

The StatusSupport event interface is defined in the StatusSupport.mon file, which is found in the monitors directory of the Apama installation (note, this is not the same directory as adapters\monitors).

All of the StatusSupport events contain the following fields:

  • serviceID — The service ID to subscribe to, a blank in this field targets all services
  • object — The object to request status of - this may include:
    • “Connection" - whether connected or not
    • “MarketState” - a market may be “Open”, “Closed”, or other states
  • subServiceID — The subService ID to subscribe to. Some services may expose several services. The interpretation of this string is adapter-specific.
  • connection — The connection to subscribe to. Some services may expose several services. The interpretation of this string is adapter-specific.

The StatusSupport interface defines the following events:

  • SubscribeStatus — This event is sent to the service monitor to subscribe to status.

        event SubscribeStatus {
          string serviceID;
          string object;
          string subServiceID;
          string connection;
        }
    
  • UnsubscribeStatus

        event UnsubscribeStatus {
          string serviceID;
          string object;
          string subServiceID;
          string connection;
        }
    
  • Status

        event Status {
          string serviceID;
          string object;
          string subServiceID;
          string connection;
          string description;
          sequence<string> summaries;
          boolean available;
          wildcard dictionary <string, string> extraParams;
        }
    

The additional fields for the Status event type are:

  • description — A free-form text string giving a description of the status.
  • summaries — The status of the object requested. This will be a well recognized sequence of words - for example, a financial market’s “MarketState” may be “Open”, “Closed”, “PreOpen”, etc. A Connection may be “Connected”, “Disconnected”, “Disconnected LoginFailed”, “Disconnected TimedOut”, etc. There should be at least one entry in the sequence.
  • availabletrue if the object is “available” - the exact meaning is adapter specific; for example, connected, open for general orders, etc.
  • extraParams — Extra parameters that do not map into any of the above. Convention is that keys are in title case, for example, “Username”, “CloseTime”, etc.

A Status event does not denote a change of state, merely what the current state is —  in particular, one will be sent out after every SubscribeStatus request.

Any adapter specific information that the application needs to supply or be supplied can be passed in the extraParams dictionary — these are free-form (though there are conventions on the keys, see below).

  • StatusError

        event StatusError {
          string serviceID;
          string object;
          string subServiceID;
          string connection;
          string description;
          boolean failed;
        }
    

The additional field for this event type is:

  • failed — Whether the subscription has been terminated. Any subscribers will need to send a new SubscribeStatus request after this.

Note that the purpose of the StatusError event is to report a problem in the delivery of status information, not to report an “error” status. A StatusError should be sent when the service is unable to deliver status for some reason. For example, reports on the status of an adapter transport’s connection to a downstream server cannot be sent if the correlator has lost its connection to the adapter — in this case the service would be justified in sending a StatusError event for the downstream connection status. However, in the same situation the service should continue to send normal Status events for the correlator-adapter connection status, as this status is known. The available flag in these Status events would of course be set to false to indicate that the connection is down.

If the failed flag in a StatusError event is true, this indicates that the failure in status reporting is permanent and any active status subscriptions will have been cancelled and receivers will need to re-subscribe if they wish to receive further status updates from the service. If the failed flag is false, the failure is temporary and receivers should assume that the flow of Status events will resume automatically at some point.

DataView support

The IAFStatusDataViewService provides support for publishing the status of an IAF adapter as a DataView item. It can be used to easily monitor the adapter status using Apama’s Scenario Browser or to visualize the adapter status using an Apama dashboard. The IAFStatusDataViewService.mon file, which can be found in the adapters/monitors directory of the Apama installation, needs to be injected to make use of the IAFStatusDataViewService. Note that the monitor is not included in any bundle in Apama Plugin for Eclipse. For more information on the DataViewService, see Making application data available to clients.

The status of every adapter is published as a DataView item of a single DataView definition (IAF_ADAPTER_STATUS). The IAFStatusDataViewService is dependent on the IAFStatusManager and can only publish the status of adapters which support the IAFStatusManager.

The IAFStatusDataViewService uses the following events:

  • The AdapterDataViewRegister event is used to register an adapter for publishing its status as a DataView item. You have to route the AdapterDataViewRegister event with the appropriate adapter name to start publishing its status.
  • The AdapterDataViewDeregister event is used to de-register an adapter from publishing its status as a DataView item. You have to route the AdapterDataViewDeregister event with the appropriate adapter name to stop publishing its status.
  • The AdapterDataViewResponse event is sent in response of the AdapterDataViewRegister and AdapterDataViewDeregister events to indicate the success or failure of the operation.

See the API reference for EPL (ApamaDoc) for more details about the IAFStatusDataViewService and the events.

Once an adapter is registered to publish its status information as a DataView item, the IAFStatusDataViewService starts consuming AdapterUp and AdapterError events from the IAFStatusManager. Each registered adapter has a corresponding DataView item for the status. This DataView item is periodically updated with the current status from the AdapterUp and AdapterError events.

After an adapter has been registered for publishing its status, the adapter status can be viewed in the Scenario Browser or visualized in a dashboard:

  • To view the adapter status in the Scenario Browser, open the Scenario Browser as described in Displaying the Scenario Browser, and then click or expand the IAF Adapter Status node to see the current status of the adapter.
  • To visualize the adapter status in a dashboard, use the IAF_ADAPTER_STATUS DataView as the data source. For more information, see Attaching dashboards to correlator data.