Once you have connected to a server, much of the work of your application will be to send messages to that server and then handle the events you receive from it.
Genesys recommends that you use the Message Broker Application Block for most of your event handling needs. This article shows how to send and receive simple synchronous events without using Message Broker and then discusses how to use Message Broker for asynchronous event handling.
Note: It is important to determine whether your application
needs to use synchronous or asynchronous messages. In general, you will
probably use only one or the other type in your application. If you decide to
use synchronous messages, you must make sure that your code handles all of the
messages you receive from your servers. For example, if you send a
RequestReadObjects
message to Configuration Server, you will
receive several EventObjectsRead
messages, followed by an
EventObjectsSent
message. If your application does not handle all
of these messages, it will not work properly.
The messages you send to a server are in the form of requests. For example, you may send a request to log in an agent or to gather statistics. You might also send a request to update a configuration object, or to shut down an application.
In each of these cases, the server will respond with an event message, as shown in Figure 1.
Figure 1: Request and Response
Some of the requests you send may best be handled with a synchronous response, while others may best be handled asynchronously. Let’s talk about synchronous requests first.
Sometimes you might want a synchronous response to your request. For example, if you are using the Open Media Platform SDK, you may want to log in an agent. To do this, you need to let the server know that you want to log in. And then you need to wait for confirmation that your login was successful.
The first thing you need to do is to create a login request, as shown here:
[Java]
RequestAgentLogin requestAgentLogin =
RequestAgentLogin.create(
tenantId,
placeId,
reason);
This version of RequestAgentLogin.Create
specifies most of
the information you will need in order to perform the login, but there is one
more piece of data required. Here is how to add it:
[Java]
requestAgentLogin.setMediaList(mediaList);
Once you have created the request and set all required properties, you can
make a synchronous request by using the request
method of
your ProtocolManagementService
object, like this:
[Java]
Message response = null;
response = protocolManagementServiceImpl.getProtocol("Interaction_Server_App")
.request(requestAgentLogin);
Note: For information on how to use the
ProtocolManagementServiceImpl
class of the Protocol Manager
Block to communicate with a Genesys server, see the article on
Connecting to a Server.
There are two important things to understand when you use the
request
method:
RequestReadObjects
message to Configuration Server, as mentioned
at the beginning of this article.
The response from the server will come in the form of a Message
.
This is the interface implemented by all events in the Platform SDK. Some types
of requests will be answered by an event that is specific to the request, while
others may receive a more generic response of EventAck
, which
simply acknowledges that your request was successful. If a request fails,
the server will send an EventError
.
A successful RequestAgentLogin
will receive an
EventAck
, while an unsuccessful one will receive an
EventError
. You can use a switch statement to test which
response you received, as outlined here:
[Java]
switch(response.messageId())
{
case EventAck.ID:
OnEventAck(response);
case EventError.ID:
OnEventError(response);
...
}
There are times when you need to receive asynchronous responses from a server.
First of all, some requests to a server can result in multiple events. For
example, if you send a RequestReadObjects
message, which is used
to read objects from the Genesys Configuration Layer, Configuration Server may
send more than one EventObjectsRead
messages in response, depending
on whether there is too much data to be handled by a single
EventObjectsRead
.
In other cases, events may be unsolicited. To continue with our example, once
you have received all of the EventObjectsRead
messages,
Configuration Server will also send an EventObjectsSent
, which
confirms that it has completed your request.
To make an asynchronous request, you would use the send
method
of your ProtocolManagementServiceImpl
class. For example, you might
need to fetch information about some objects in the Genesys Configuration Layer.
Here is how to set up a RequestReadObjects
, followed by the
send
:
[Java]
KeyValueCollection filterKey = new KeyValueCollection();
filterKey.addObject("switch_dbid", 113);
filterKey.addObject("dn_type", ConfServerDNType.Extension.asInteger());
RequestReadObjects requestReadObjects = RequestReadObjects.create(
ConfServerObjectType.DN.asInteger(), filterKey);
protocolManagementServiceImpl.getProtocol("Config_Server_App")
.send(requestReadObjects);
This snippet is searching for all DNs that have a type of Extension
and are associated with the switch that has a database ID of 113.
There are several ways to handle the response from the server, but Genesys recommends that you use the Message Broker Application Block, which is included with the Platform SDK. Message Broker allows you to set up individual classes to handle specific events. It receives the events from the servers you are working with, and sends them to the appropriate handler class. Message Broker is a high-performance way to hide the complexity of event-driven programming — so you can focus on other areas of your application.
To use the Message Broker Application Block, add the following jar file to the classpath for your application:
This jar
file was precompiled using the default Application Block code, and can be located at:
<Platform SDK Folder>\applicationblocks\messagebroker\dist\lib
.
Note: You can also view or modify the Message Broker Application Block source code. To do this, open
the Message Broker Java source files that were installed with the Platform SDK. The Java source files for this project
are located at: <Platform SDK Folder>\applicationblocks\messagebroker\src\java
. If you
make any changes to the project, you will have to run Ant (or use the build.bat
file for this Application Block) to
rebuild the jar
archive listed above. After you run Ant, add the resulting jar
to your classpath.
Now you can add the appropriate import
statements to your source
code. For example:
[Java]
import com.genesyslab.platform.applicationblocks.commons.broker.*;
In order to use the Message Broker Application Block, you need to create an
EventBrokerService
object to handle the events your application
receives. Since you are using the Protocol Manager Application Block to connect
to your servers, as shown in the section on
Connecting to a Server, you should
specify the ProtocolManagementServiceImpl
object in the
EventBrokerService
constructor:
[Java]
EventBrokerService mEventBrokerService = new EventBrokerService(
(MessageReceiverSupport) protocolManagementServiceImpl
.getReceiver());
You also need to set up the appropriate filters for your event handlers and
register the handlers with the EventBrokerService
. This allows
that service to determine which classes will be used for event-handling. Note
that you should register these classes before you open the connection to the
server. Otherwise, the server might send events before you are ready to handle
them. The sample below shows how to filter on Message ID, which is an integer
associated with a particular message:
[Java]
mEventBrokerService.register(new ConfObjectsReadHandler(),
new MessageIdFilter(EventObjectsRead.ID));
mEventBrokerService.register(new ConfObjectsSentHandler(),
new MessageIdFilter(EventObjectsSent.ID));
mEventBrokerService.register(new StatPackageInfoHandler(),
new MessageIdFilter(EventPackageInfo.ID));
Once you have registered your event-handling classes, you can activate the
EventBrokerService
and open the connection to your server. In
the following snippet, connections are being opened to both Configuration
Server and Stat Server:
[Java]
mEventBrokerService.activate();
protocolManagementServiceImpl.getProtocol("Config_Server_App")
.open();
protocolManagementServiceImpl.getProtocol("Stat_Server_App").open();
At this point, you are ready to set up classes to handle the events you have
received from the server. Here is a simple class that handles the
EventObjectsRead
messages:
[Java] class ConfObjectsReadHandler implements Action{ public void handle(Message obj) { EventObjectsRead objectsRead = (EventObjectsRead) obj; // Add processing here... } }
As mentioned earlier, once Configuration Server has sent all of the information
you requested, it will let you know it has finished by sending an
EventObjectsSent
message. Note that this handler has a structure
that is similar to the one for EventObjectsRead
:
[Java] class ConfObjectsSentHandler implements Action{ public void handle(Message obj) { EventObjectsSent objectsSent = (EventObjectsSent) obj; // Add processing here... } }
Note: Message Broker only routes non-null messages of the type
you specify to your message handlers. For example, if you send a
RequestReadObjects
and no objects in the Configuration Layer meet
your filtering criteria, you will not receive an EventObjectsRead
.
In that case, you will only receive an EventObjectsSent
. Therefore,
you do not need to check for a null message in your
EventObjectsRead
handler.
The EventPackageInfo
handler also has a similar structure, but in
this case, we show how to print information about the statistics contained in
the requested package:
[Java] class StatPackageInfoHandler implements Action{ public void handle(Message obj) { EventPackageInfo eventPackageInfo = (EventPackageInfo) obj; if (eventPackageInfo != null) { int statisticsCount = eventPackageInfo.getStatistics().getCount(); StatisticsCollection statisticsCollection = eventPackageInfo.getStatistics(); for (int i = 0; i < statisticsCount; i++) { Statistic statistic = statisticsCollection.getStatistic(i); System.out.println("\nStatistic Metric is: " + statistic.getMetric().toString()); System.out.println("Statistic Object is: " + statistic.getObject()); System.out.println("Statistic IntValue is: " + statistic.getIntValue()); System.out.println("Statistic StringValue is: " + statistic.getStringValue()); System.out.println("Statistic ObjectValue is: " + statistic.getObjectValue()); System.out.println("Statistic ExtendedValue is: " + statistic.getExtendedValue()); System.out.println("Statistic Tenant is: " + statistic.getObject().getTenant()); System.out.println("Statistic Type is: " + statistic.getObject().getType()); System.out.println("Statistic Id is: " + statistic.getObject().getId()); System.out.println("Statistic TimeProfile is: " + statistic.getMetric().getTimeProfile()); System.out.println("Statistic StatisticType is: " + statistic.getMetric().getStatisticType()); System.out.println("Statistic TimeRange is: " + statistic.getMetric().getTimeRange()); } } } }
Each server in the Genesys environment makes use of a particular set of events
that corresponds to the tasks of that server. For example, Configuration Server
sends EventObjectsRead
and EventObjectsSent
messages, among others, while Stat Server's events include
EventPackageInfo
and EventPackageOpened
.
Although your applications can identify each of these events by name, it is
more efficient to use the ID field associated with an event, which you specify
as an int
. You can do this by using a MessageIdFilter
,
as shown here:
[Java]
mEventBrokerService.register(new ConfEventErrorHandler(),
new MessageIdFilter(EventError.ID));
However, the integer used for the Message ID of, say, a Configuration Server message,
could be same as the integer used for a completely different message on another
server. This could lead to problems if your application works with messages
from more than one server. For example, if a multi-server application includes
a handler that processes a specific type of message from the first server and
that message has an ID of 12, any messages from the other servers that also
have a Message ID of 12 will be sent by your MessageIdFilter
to
the same handler.
Fortunately, the Platform SDK allows you to filter messages on a
server-by-server basis in addition to filtering on MessageId
. Here
is how to set up a Protocol Description object that allows you to specify that
you want some of your handlers to work only with events that are coming from
Configuration Server:
[Java]
ConfServerProtocol confServerProtocol = (ConfServerProtocol)
protocolManagementServiceImpl.getProtocol("Config_Server_App");
ProtocolDescription configProtocolDescription = null;
if (confServerProtocol != null)
{
configProtocolDescription =
confServerProtocol.getProtocolDescription();
}
Once you have set up this Protocol Description, you can use it to indicate that you only want to process events associated with that server, in addition to specifying which event or events you want each handler to process:
[Java]
mEventBrokerService.register(new ConfEventErrorHandler(),
new MessageIdFilter(configProtocolDescription, EventError.ID));
You are now ready to open the connection to Configuration Server:
[Java]
protocolManagementServiceImpl.
getProtocol("Config_Server_App").open();
There may be times when you would like to use a single event handler for more
than one event. In that case, you can create the handler and then register the
appropriate events with it. For example, you might create a handler for both
EventObjectsRead
and EventObjectsSent
:
[Java] class ConfEventHandler implements Action{ ... }
You might use a case
statement inside the handler, in order to
process each event appropriately. In any case, once you have set up this
handler, all you need to do is register both events with it, as shown here:
[Java]
mEventBrokerService.register(new ConfEventHandler(),
new MessageIdFilter(configProtocolDescription, EventObjectsRead.ID));
mEventBrokerService.register(new ConfEventHandler(),
new MessageIdFilter(configProtocolDescription, EventObjectsSent.ID));
These are the basics of how to use the Message Broker Application Block. For more information, see the Message Broker Application Block Guide.
For information on the other application blocks included with the Platform SDK, see the section on application blocks in Introducing the Platform SDKs.
For more information about the Genesys SDKs, including the latest versions of all SDK documents, check out the Genesys Developer Zone, which also contains forums and other important sources of developer-related information. DevZone is available at http://www.genesyslab.com/developer.
Additional information on Genesys Telecommunications Laboratories, Inc. is available on our Technical Support website. The following documentation also contains information about this software. Please consult the Deployment Guide first.
The Platform SDK 7.6 Deployment Guide
The Platform SDK 7.6 Developer's Guide
Send comments on this topic to Techpubs.webadmin@genesyslab.com