public synchronized SubscribeParams createSubscription(final Agent agent, final QmfQuery query,
final String consoleHandle, final String options) throws QmfException
{
if (consoleHandle == null)
{
throw new QmfException("Called createSubscription() with null consoleHandle");
}
if (_subscriptionByHandle.get(consoleHandle) != null)
{
throw new QmfException("Called createSubscription() with a consoleHandle that is already in use");
}
if (agent == null)
{
throw new QmfException("Called createSubscription() with null agent");
}
if (!agent.isActive())
{
throw new QmfException("Called createSubscription() with inactive agent");
}
String agentName = agent.getName();
// Initialise optional values to defaults;
long lifetime = _subscriptionDuration;
long publishInterval = 10000;
long timeout = _replyTimeout;
String replyHandle = null;
if (options != null)
{ // We wrap the Map in a QmfData object to avoid potential class cast issues with the parsed options
QmfData optMap = new QmfData(new AddressParser(options).map());
if (optMap.hasValue("lifetime"))
{
lifetime = optMap.getLongValue("lifetime");
}
if (optMap.hasValue("publishInterval"))
{ // Multiply publishInterval by 1000 because the QMF2 protocol spec says interval is
// "The request time (in milliseconds) between periodic updates of data in this subscription"
publishInterval = 1000*optMap.getLongValue("publishInterval");
}
if (optMap.hasValue("timeout"))
{
timeout = optMap.getLongValue("timeout");
}
if (optMap.hasValue("replyHandle"))
{
replyHandle = optMap.getStringValue("replyHandle");
}
}
try
{
MapMessage request = _syncSession.createMapMessage();
request.setJMSReplyTo(_asyncReplyAddress); // Deliberately forcing all replies to the _asyncReplyAddress
request.setJMSCorrelationID(consoleHandle); // Deliberately using consoleHandle not replyHandle here
request.setStringProperty("x-amqp-0-10.app-id", "qmf2");
request.setStringProperty("method", "request");
request.setStringProperty("qmf.opcode", "_subscribe_request");
request.setStringProperty("qpid.subject", agentName);
request.setObject("_query", query.mapEncode());
request.setObject("_interval", publishInterval);
request.setObject("_duration", lifetime);
SubscriptionManager subscription =
new SubscriptionManager(agent, query, consoleHandle, replyHandle, publishInterval, lifetime);
_subscriptionByHandle.put(consoleHandle, subscription);
_timer.schedule(subscription, 0, publishInterval);
if (_subscriptionEmulationEnabled && agentName.equals(_brokerAgentName))
{ // If the Agent is the broker Agent we emulate the Subscription on the Console
String subscriptionId = UUID.randomUUID().toString();
_subscriptionById.put(subscriptionId, subscription);
subscription.setSubscriptionId(subscriptionId);
final SubscribeParams params = new SubscribeParams(consoleHandle, subscription.mapEncode());
if (replyHandle == null)
{
return params;
}
else
{
final String handle = replyHandle;
Thread thread = new Thread()
{
public void run()
{
_eventListener.onEvent(new SubscribeResponseWorkItem(new Handle(handle), params));
}
};
thread.start();
}
return null;
}
_requester.send(request);
if (replyHandle == null)
{ // If this is an synchronous request get the response
subscription.await(timeout*1000);
if (subscription.getSubscriptionId() == null)
{
_log.info("No response received in createSubscription()");
throw new QmfException("No response received for Console.createSubscription()");
}
return new SubscribeParams(consoleHandle, subscription.mapEncode());
}
// If this is an asynchronous request return without waiting for a response
return null;
}
catch (JMSException jmse)
{
_log.info("JMSException {} caught in createSubscription()", jmse.getMessage());
throw new QmfException(jmse.getMessage());
}
} // end of createSubscription()