/**
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information regarding
* copyright ownership. The ASF licenses this file to you under
* the Apache License, Version 2.0 (the "License"); you may not
* use this file except in compliance with the License. You may
* obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND,
* either express or implied.
*
* See the License for the specific language governing permissions
* and limitations under the License.
*/
package siebog.interaction;
import java.util.ArrayList;
import java.util.List;
import java.util.UUID;
import javax.annotation.PostConstruct;
import javax.annotation.PreDestroy;
import javax.ejb.LocalBean;
import javax.ejb.Remote;
import javax.ejb.Stateless;
import javax.inject.Inject;
import javax.jms.JMSException;
import javax.jms.MessageProducer;
import javax.jms.ObjectMessage;
import javax.jms.Session;
import javax.ws.rs.Consumes;
import javax.ws.rs.FormParam;
import javax.ws.rs.GET;
import javax.ws.rs.POST;
import javax.ws.rs.Path;
import javax.ws.rs.Produces;
import javax.ws.rs.core.MediaType;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import siebog.agents.AID;
/**
* Default message manager implementation.
*
* @author <a href="mitrovic.dejan@gmail.com">Dejan Mitrovic</a>
* @author <a href="rade.milovanovic@hotmail.com">Rade Milovanovic</a>
*/
@Stateless
@Remote(MessageManager.class)
@LocalBean
@Path("/messages")
@Consumes(MediaType.APPLICATION_JSON)
@Produces(MediaType.APPLICATION_JSON)
public class MessageManagerBean implements MessageManager {
private static final Logger LOG = LoggerFactory.getLogger(MessageManagerBean.class);
@Inject
private JMSFactory factory;
private Session session;
private MessageProducer defaultProducer;
private MessageProducer testProducer;
@PostConstruct
public void postConstruct() {
session = factory.getSession();
defaultProducer = factory.getDefaultProducer(session);
}
@PreDestroy
public void preDestroy() {
try {
session.close();
} catch (JMSException e) {
}
}
@GET
@Path("/")
public List<String> getPerformatives() {
final Performative[] arr = Performative.values();
List<String> list = new ArrayList<>(arr.length);
for (Performative p : arr)
list.add(p.toString());
return list;
}
@POST
@Path("/")
@Consumes(MediaType.APPLICATION_FORM_URLENCODED)
@Override
public void post(@FormParam("acl") ACLMessage msg) {
post(msg, 0);
}
@Override
public void post(ACLMessage msg, long delayMillisec) {
// TODO : Check if the agent/subscriber exists
// http://hornetq.sourceforge.net/docs/hornetq-2.0.0.BETA5/user-manual/en/html/management.html#d0e5742
for (int i = 0; i < msg.receivers.size(); i++) {
if (msg.receivers.get(i) == null) {
throw new IllegalArgumentException("AID cannot be null.");
}
postToReceiver(msg, i, delayMillisec);
}
}
@Override
public String ping() {
return "Pong from " + System.getProperty("jboss.node.name");
}
private void postToReceiver(ACLMessage msg, int index, long delayMillisec) {
AID aid = msg.receivers.get(index);
try {
ObjectMessage jmsMsg = session.createObjectMessage(msg);
setupJmsMsg(jmsMsg, aid, index, delayMillisec);
getProducer(msg).send(jmsMsg);
} catch (Exception ex) {
LOG.warn(ex.getMessage());
}
}
private void setupJmsMsg(ObjectMessage jmsMsg, AID aid, int index, long delayMillisec)
throws JMSException {
// TODO See message grouping in a cluster
// http://docs.jboss.org/hornetq/2.2.5.Final/user-manual/en/html/message-grouping.html
jmsMsg.setStringProperty("JMSXGroupID", aid.getStr());
jmsMsg.setIntProperty("AIDIndex", index);
jmsMsg.setStringProperty("_HQ_DUPL_ID", UUID.randomUUID().toString());
if (delayMillisec > 0) {
jmsMsg.setLongProperty("_HQ_SCHED_DELIVERY", System.currentTimeMillis() + delayMillisec);
}
}
private MessageProducer getProducer(ACLMessage msg) {
if (MessageManager.REPLY_WITH_TEST.equals(msg.inReplyTo)) {
return getTestProducer();
}
return defaultProducer;
}
private MessageProducer getTestProducer() {
if (testProducer == null) {
testProducer = factory.getTestProducer(session);
}
return testProducer;
}
}