package com.destinationradiodenver.mobileStreaming.messageDriven;
import java.io.Serializable;
import javax.annotation.Resource;
import javax.ejb.ActivationConfigProperty;
import javax.ejb.MessageDriven;
import javax.inject.Inject;
import javax.jms.JMSException;
import javax.jms.Message;
import javax.jms.MessageListener;
import javax.jms.ObjectMessage;
import javax.persistence.EntityManager;
import javax.persistence.NoResultException;
import javax.persistence.PersistenceContext;
import javax.persistence.TypedQuery;
import org.jboss.logging.Logger;
import com.destinationradiodenver.mobileStreaming.application.Servers;
import com.destinationradiodenver.mobileStreaming.application.Streams;
import com.destinationradiodenver.mobileStreaming.messages.StreamStatusMessage;
import com.destinationradiodenver.mobileStreaming.messages.StreamStatusMessage.Status;
import com.destinationradiodenver.mobileStreaming.web.entity.Red5Server;
import com.destinationradiodenver.mobileStreaming.web.entity.Stream;
@MessageDriven(name = "streamStatusConsumer", activationConfig = {
@ActivationConfigProperty(propertyName = "destinationType", propertyValue = "javax.jms.Topic"),
@ActivationConfigProperty(propertyName = "destination", propertyValue = "java:jboss/jms/topic/streamStatusTopic") })
public class StreamStatusConsumer implements Serializable, MessageListener {
/**
* @author cpenhale
*/
private static final long serialVersionUID = 1102064321674684886L;
private Logger log = Logger.getLogger(StreamStatusConsumer.class);
@Inject
private Servers servers;
@Inject
private Streams streams;
@PersistenceContext(unitName="mobileConsolePersistence")
EntityManager em;
public Stream generateStream(Red5Server server, String hostname, String scopeName, String publishedName){
Stream newStream = new Stream();
newStream.setServer(server);
String rtmpUri = "rtmp://";
rtmpUri += hostname;
rtmpUri += "/";
rtmpUri += scopeName;
rtmpUri += "/";
rtmpUri += publishedName;
log.infof("Constructed rtmpUri %s", rtmpUri);
newStream.setRtmpUri(rtmpUri);
newStream.setAutomaticallyStartEncoders(false);
newStream.setDescription("Automatically Generated Stream");
newStream.setFriendlyName(publishedName);
newStream.setRestartEncodersEveryMinutes(0);
return newStream;
}
public void onMessage(Message message) {
log.info("Recorder received a message");
try{
ObjectMessage objM = (ObjectMessage) message;
Object object = objM.getObject();
StreamStatusMessage statusMessage = (StreamStatusMessage) object;
log.infof("statusMessage received from JMS Message (%s). Checking for associated server...", objM.getJMSMessageID().toString());
String hostname = statusMessage.getServerHostname();
TypedQuery<Red5Server> tQ = em.createQuery("select red5server from Red5Server as red5server where red5server.hostname is :hostname", Red5Server.class).setParameter("hostname", hostname);
try{
Red5Server server = tQ.getSingleResult();
log.infof("Found a Red5 server for hostname %s", hostname);
if(server.getEnabled()){
log.infof("statusMessage recieved from active server %s", hostname);
Stream stream = generateStream(server, hostname, statusMessage.getScopeName(), statusMessage.getPublishedName());
try{
TypedQuery<Stream> tQToo = em.createQuery("select stream from Stream as stream where stream.rtmpUri is :rtmpUri", Stream.class).setParameter("rtmpUri", stream.getRtmpUri());
Stream persistedStream = tQToo.getSingleResult();
stream = persistedStream;
}catch (NoResultException ex){
log.info("Did not find stream, persisting");
em.persist(stream);
try{
TypedQuery<Stream> tQthree = em.createQuery("select stream from Stream as stream where stream.rtmpUri is :rtmpUri", Stream.class).setParameter("rtmpUri", stream.getRtmpUri());
Stream persistedStream = tQthree.getSingleResult();
stream = persistedStream;
log.info(stream.toString());
}catch (NoResultException extoo){
log.error("Unable to find persisted stream");
throw new RuntimeException("Unable to find persisted stream");
}
}
if(statusMessage.getStatus() == Status.ADDED){
streams.addStream(stream);
}else if(statusMessage.getStatus() == Status.REMOVED){
if(!streams.removeStream(stream))
log.errorf("attempted to remove non-existent stream from Streams singleton");
}else if(statusMessage.getStatus() == Status.SUBSCRIBER_ADDED){
streams.addListener(stream);
}else if(statusMessage.getStatus() == Status.SUBSCRIBER_REMOVED){
streams.removeListener(stream);
}else if(statusMessage.getStatus() == Status.STARTED_RECORDING){
streams.addStreamRecording(stream);
}else if(statusMessage.getStatus() == Status.STOPPED_RECORDING){
streams.removeStreamRecording(stream);
}else{
log.errorf("Received invalid status %s in JMS Message %s", statusMessage.getStatus().toString(), objM.getJMSMessageID().toString());
}
}else{
log.infof("statusMessage recieved from inactive server %s", hostname);
}
}catch (NoResultException ex){
log.infof("Received a JMS message from Red5 server %s that hasn't been added", hostname);
}
}catch (ClassCastException ccx){
log.info("Not an ObjectMessage, ignoring");
} catch (JMSException e) {
log.errorf("JMS Exception: \n %s", e.getMessage());
} catch (Exception ex){
log.error("CATCHALL: "+ex.getMessage());
}
}
}