// to the same Console instance at the same time.
synchronized(this)
{
if (_connection != null)
{
throw new QmfException("Multiple connections per Console is not supported");
}
_connection = conn;
}
try
{
String syncReplyAddressOptions = addressOptions;
String asyncReplyAddressOptions = addressOptions;
String eventAddressOptions = addressOptions;
if (!addressOptions.equals(""))
{ // If there are address options supplied we need to check if a name parameter is present.
String[] split = addressOptions.split("name");
if (split.length == 2)
{ // If options contains a name parameter we extract it and create variants for async and event queues.
split = split[1].split("[,}]"); // Look for the end of the key/value block
String nameValue = split[0].replaceAll("[ :'\"]", ""); // Remove initial colon, space any any quotes.
// Hopefully at this point nameValue is actually the value of the name parameter.
asyncReplyAddressOptions = asyncReplyAddressOptions.replace(nameValue, nameValue + "-async");
eventAddressOptions = eventAddressOptions.replace(nameValue, nameValue + "-event");
}
}
String topicBase = "qmf." + _domain + ".topic";
_syncSession = _connection.createSession(false, Session.AUTO_ACKNOWLEDGE);
// Create a MessageProducer for the QMF topic address used to broadcast requests
Destination topicAddress = _syncSession.createQueue(topicBase);
_broadcaster = _syncSession.createProducer(topicAddress);
// If Asynchronous Behaviour is enabled we create the Queues used to receive async responses
// Data Indications, QMF Events, Heartbeats etc. from the broker (or other Agents).
if (!_disableEvents)
{
// TODO it should be possible to bind _eventConsumer and _asyncResponder to the same queue
// if I can figure out the correct AddressString to use, probably not a big deal though.
_asyncSession = _connection.createSession(false, Session.AUTO_ACKNOWLEDGE);
// Set up MessageListener on the Event Address
Destination eventAddress = _asyncSession.createQueue(topicBase + "/agent.ind.#" + eventAddressOptions);
_eventConsumer = _asyncSession.createConsumer(eventAddress);
_eventConsumer.setMessageListener(this);
// Create the asynchronous JMSReplyTo _replyAddress and MessageConsumer
_asyncReplyAddress = _asyncSession.createQueue(_address + ".async" + asyncReplyAddressOptions);
_asyncResponder = _asyncSession.createConsumer(_asyncReplyAddress);
_asyncResponder.setMessageListener(this);
}
// I've extended the synchronized block to include creating the _requester and _responder. I don't believe
// that this is strictly necessary, but it stops findbugs moaning about inconsistent synchronization
// so makes sense if only to get that warm and fuzzy feeling of keeping findbugs happy :-)
synchronized(this)
{
// Create a MessageProducer for the QMF direct address, mainly used for request/response
Destination directAddress = _syncSession.createQueue("qmf." + _domain + ".direct");
_requester = _syncSession.createProducer(directAddress);
// Create the JMSReplyTo _replyAddress and MessageConsumer
_replyAddress = _syncSession.createQueue(_address + syncReplyAddressOptions);
_responder = _syncSession.createConsumer(_replyAddress);
_connection.start();
// If Asynchronous Behaviour is disabled we create an Agent instance to represent the broker
// ManagementAgent the only info that needs to be populated is the _name and we can use the
// "broker" synonym. We populate this fake Agent so getObjects() behaviour is consistent whether
// we've any received *real* Agent updates or not.
if (_disableEvents)
{
_brokerAgentName = "broker";
Map<String, String> map = new HashMap<String, String>();
map.put("_name", _brokerAgentName);
Agent agent = new Agent(map, this);
_agents.put(_brokerAgentName, agent);
_agentAvailable = true;
}
else
{
// If Asynchronous Behaviour is enabled Broadcast an Agent Locate message to get Agent info quickly.
broadcastAgentLocate();
}
// Wait until the Broker Agent has been located (this should generally be pretty quick)
while (!_agentAvailable)
{
long startTime = System.currentTimeMillis();
try
{
wait(_replyTimeout*1000);
}
catch (InterruptedException ie)
{
continue;
}
// Measure elapsed time to test against spurious wakeups and ensure we really have timed out
long elapsedTime = (System.currentTimeMillis() - startTime)/1000;
if (!_agentAvailable && elapsedTime >= _replyTimeout)
{
_log.info("Broker Agent not found");
throw new QmfException("Broker Agent not found");
}
}
// Timer used for tidying up Subscriptions.
_timer = new Timer(true);
}
}
catch (JMSException jmse)
{
// If we can't create the QMF Destinations there's not much else we can do
_log.info("JMSException {} caught in addConnection()", jmse.getMessage());
throw new QmfException("Failed to create sessions or destinations " + jmse.getMessage());
}
}