package eu.aniketos.notification.client;
import eu.aniketos.serviceruntime.eventlistener.AlertMessage;
import eu.aniketos.serviceruntime.eventlistener.IEventListener;
import javax.jms.ExceptionListener;
import javax.jms.JMSException;
import javax.jms.Message;
import javax.jms.MessageConsumer;
import javax.jms.MessageListener;
import javax.jms.Session;
import javax.jms.Topic;
/**
* Receives an alert from some Aniketos component/service and allows any evaluation and reasoning to be done,
* before passing it on to the message broker where it is published to its subscribing entities.
*
* @version 1.0
* @author Erlend Andreas Gjære (SINTEF), erlendandreas.gjare@sintef.no
*/
public class Subscription implements MessageListener, ExceptionListener {
/** A name of the topic this subscription represents **/
private String topicName;
/** Alert type filter for the subscription (optional) **/
private String alertType;
/** Importance threshold for messages (optional) **/
private int threshold;
/** A JMS message consumer instance **/
private MessageConsumer consumer;
/** Indicates whether or not the subscription is active **/
private boolean isActive;
/** The JMS session instance **/
private Session session;
/** The listener to be informed on received messages */
private IEventListener eventListener;
/**
* Subscribe to only a specific notification type for a specific topic.
*
* @param serviceId Marketplace ID for the subscribed service
* @param alertType Choose from eu.aniketos.notification.Notification
* @param importanceThreshold Only subscribe to alerts with importance above given threshold
* @param jmsSession An already created JMS session
* @param eventListener The listener to be informed on a received alert
*/
public Subscription(String serviceId, String alertType,
int importanceThreshold, Session jmsSession,
IEventListener eventListener) {
this(serviceId, alertType, ">", importanceThreshold, jmsSession, eventListener);
}
/**
* Subscribe to only a specific notification type and description (e.g. a specific threat) for a specific topic.
*
* @param serviceId Service ID (URL) for the subscribed service
* @param alertType Choose from eu.aniketos.notification.Notification
* @param description Choose from eu.aniketos.notification.descriptions.*
* @param importanceThreshold Only subscribe to alerts with importance above given threshold
* @param jmsSession An already created JMS session
* @param eventListener The listener to be informed on a received alert
*/
public Subscription(String serviceId, String alertType, String description,
int importanceThreshold, Session jmsSession,
IEventListener eventListener) {
this.eventListener = eventListener;
this.topicName = serviceId;
this.alertType = alertType;
this.threshold = importanceThreshold;
this.session = jmsSession;
try {
String topicId = "pub." + serviceId + "." + alertType;
if (!alertType.equals(">"))
topicId += "." + description;
// Setting up the given topic - and the given types of alerts
Topic topic = session.createTopic(topicId);
// MessageConsumer is used for receiving (consuming) messages from the topic (above given threshold)
consumer = session.createConsumer(topic, "threshold>" + this.threshold);
// Durable subscribers will survive in the broker if the connection is closed
// consumer = session.createDurableSubscriber(topic, clientId, "alertThreshold>" + threshold, true);
consumer.setMessageListener(this);
isActive = true;
} catch (Exception e) {
isActive = false;
e.printStackTrace();
}
}
/**
* Implementation of the MessageListener interface
* @param message The message object received
*/
@Override
public void onMessage(Message message) {
//System.out.println("THIS IS WORKING RIGHT!");
try {
// Check if the Aniketos "proprietory" message property "alertType" is present in the message
if (message.propertyExists("alertType")) {
// Notification notif = new Notification(message.getJMSMessageID());
// notif.setServiceId(message.getStringProperty("serviceId"));
// notif.setAlertType(message.getStringProperty("alertType"));
// notif.setValue(message.getStringProperty("value"));
// notif.setDescription(message.getStringProperty("description"));
// notif.setThreatId(message.getStringProperty("threatId"));
// notif.setImportance(message.getIntProperty("importance"));
// notif.setServerTime(message.getStringProperty("serverTime"));
/**
* This is where the message is used for whatever it needs to be used for
*/
// For now, just print it to the console..
System.out.println("[Client : Message received] " + message.getStringProperty("serviceId") + " "
+ ": alertType=" + message.getStringProperty("alertType")
+ "; value=" + message.getStringProperty("value")
+ "; description='" + message.getStringProperty("description") + "'"
+ "; threatId=" + message.getStringProperty("threatId")
+ "; importance=" + message.getIntProperty("importance")
+ "; serverTime=" + message.getStringProperty("serverTime")
+ "; messageId=" + message.getJMSMessageID());
if (eventListener != null) {
System.out.println("Sending alert...");
String serviceId = message.getStringProperty("serviceId");
AlertMessage alertMessage = new AlertMessage();
alertMessage.setAlertType(message.getStringProperty("alertType"));
alertMessage.setDescription(message.getStringProperty("description"));
alertMessage.setServiceId(message.getStringProperty("serviceId"));
alertMessage.setThreatId(message.getStringProperty("threatId"));
alertMessage.setValue(message.getStringProperty("value"));
eventListener.onServiceEvent(serviceId, alertMessage);
}
else {
System.out.println("Event listener is null");
}
}
else
throw new JMSException("[Client : Unknown message] JMSMessageID=" + message.getJMSMessageID());
} catch (JMSException e) {
System.out.println(e.getMessage());
} catch (Throwable t) {
t.printStackTrace();
}
}
/**
* Unsubscribe from the current topic
*/
public void unsubscribe() {
try {
isActive = false;
session.unsubscribe(topicName + "." + alertType);
session.close();
System.out.println("[Client : Unsubscribe] Removed subscription: " + topicName + "." + alertType);
} catch(Exception e) {
System.out.println("[Client : Unsubscribe] No durable subscription exists for: " + topicName + "." + alertType);
} finally {
try {
consumer.close();
session.close();
} catch (Exception ignore) { }
}
}
/**
* Implementation of the ExceptionListener interface.
*/
@Override
public void onException(JMSException exception) {
System.out.println("[JMS Exception] " + exception.getMessage());
}
/**
* Check if the subscription is active and running.
* @return True if active, false if otherwise
*/
public boolean isActive() {
return isActive;
}
/**
* Get the name of the subscribed service.
* @return The JMS subscription string
*/
public String getService() {
return this.topicName;
}
/**
* Get the alert type.
* @return The alert type string constant set for the subscription
*/
public String getAlertType() {
return this.alertType;
}
}