package cern.laser.business.pojo; import java.util.Collection; import java.util.Enumeration; import java.util.Iterator; import java.util.Properties; import java.util.logging.Logger; import javax.jms.JMSException; import javax.jms.Message; import javax.jms.ObjectMessage; import javax.jms.Session; import javax.jms.TextMessage; import javax.jms.Topic; import javax.jms.TopicConnection; import javax.jms.TopicConnectionFactory; import javax.jms.TopicPublisher; import javax.jms.TopicSession; import javax.naming.Context; import javax.naming.NamingException; import alma.acs.logging.AcsLogLevel; import alma.alarmsystem.alarmmessage.AlarmMessageConversion; import cern.laser.business.LaserCreateException; import cern.laser.business.LaserRuntimeException; import cern.laser.business.data.Alarm; import cern.laser.business.data.AlarmChange; import cern.laser.business.data.AlarmImpl; import cern.laser.business.data.Category; import cern.laser.business.data.Status; public class AlarmPublisherImpl { private static final String LASER_INIT_PROPERTY = "LASER_INIT"; private static final String LASER_SEARCH_PROPERTY = "LASER_SEARCH"; private static final String DEFAULT_CATEGORY_ROOT_TOPIC = "CMW.ALARM_SYSTEM.CATEGORIES"; private static final String BOOLEAN_SUFFIX = "_BOOL"; private static final String INTEGER_SUFFIX = "_INT"; private static final String FLOAT_SUFFIX = "_FLOAT"; private static final String DOUBLE_SUFFIX = "_DOUBLE"; private static final String SHORT_SUFFIX = "_SHORT"; private static final String LONG_SUFFIX = "_LONG"; private static final String STRING_SUFFIX = "_STRING"; private static final String BYTE_SUFFIX = "_BYTE"; private Context context = null; private TopicConnection connection = null; private TopicSession session = null; private TopicPublisher publisher = null; private TopicConnectionFactory topicConnectionFactory; private String categoryRootTopic = DEFAULT_CATEGORY_ROOT_TOPIC; /** * The logger */ private final Logger logger; /** * Construcotr * * @param logger The logger */ public AlarmPublisherImpl(Logger logger) { if (logger==null) { throw new IllegalArgumentException("Invalid NULL logger"); } this.logger=logger; } // // -- PUBLIC METHODS ---------------------------------------------- // public void setTopicConnectionFactory(TopicConnectionFactory topicConnectionFactory) { this.topicConnectionFactory = topicConnectionFactory; } public void setCategoryRootTopic(String categoryRootTopic) { this.categoryRootTopic = categoryRootTopic; } public void publish(AlarmChange alarmChange) { if (alarmChange == null) { logger.log(AcsLogLevel.WARNING,"alarm change is null"); return; } try { logger.log(AcsLogLevel.DEBUG,"publishing alarm change for " + alarmChange.getCurrent().getAlarmId() + ", active= " + alarmChange.getCurrent().getStatus().getActive()); Alarm alarm = alarmChange.getCurrent(); Alarm previous = alarmChange.getPrevious(); Iterator iterator = alarm.getCategories().iterator(); while (iterator.hasNext()) { Category category = (Category) iterator.next(); String destination = categoryRootTopic + "." + category.getPath(); Topic topic = getTopicSession().createTopic(destination); //ObjectMessage message = getTopicSession().createObjectMessage((AlarmImpl) alarm); TextMessage message = getTopicSession().createTextMessage(); setMessageProperties(message, alarm); Status previous_alarm_status = previous.getStatus(); Status current_alarm_status = alarm.getStatus(); message.setObjectProperty("REDUCED_MASKED_SET", Boolean.FALSE); /** * change belongs to the reduced set if and only if the transition is from whatever to (ACTIVE, NOT REDUCED, NOT * MASKED) or from (ACTIVE, NOT REDUCED, NOT MASKED) to whatever else or if there was not a transition but a * change of something NOT REDUCED and NOT MASKED */ if (current_alarm_status.getActive().booleanValue() && !(current_alarm_status.getMasked().booleanValue() || current_alarm_status.getReduced().booleanValue())) { // transition to (ACTIVE, NOT REDUCED, NOT MASKED) or change of // something NOT REDUCED and NOT MASKED message.setObjectProperty("REDUCED_MASKED_SET", Boolean.TRUE); } else { // transition from (ACTIVE, NOT REDUCED, NOT MASKED) to something // else if (previous_alarm_status.getActive().booleanValue() && !(previous_alarm_status.getMasked().booleanValue() || previous_alarm_status.getReduced() .booleanValue())) { message.setObjectProperty("REDUCED_MASKED_SET", Boolean.TRUE); } } message.setObjectProperty("NOT_REDUCED_MASKED_SET", Boolean.FALSE); /** * change belongs to the not reduced set if an only if the transition was from ACTIVE to NOT ACTIVE or from NOT * ACTIVE to ACTIVE or if it was not triggered by reduction or mask flags */ if (current_alarm_status.getActive().booleanValue() != previous_alarm_status.getActive().booleanValue()) { // transition from ACTIVE to NOT ACTIVE or from NOT ACTIVE to ACTIVE message.setObjectProperty("NOT_REDUCED_MASKED_SET", Boolean.TRUE); } else if (current_alarm_status.getActive().booleanValue() && (current_alarm_status.getMasked().booleanValue() == previous_alarm_status.getMasked().booleanValue()) && (current_alarm_status.getReduced().booleanValue() == previous_alarm_status.getReduced().booleanValue())) { // change not triggered by reduction or mask flags message.setObjectProperty("NOT_REDUCED_MASKED_SET", Boolean.TRUE); } // I insert the xml representation of this object // in the text field of the message String xml = AlarmMessageConversion.getXML((AlarmImpl)alarm); message.setText(xml); getTopicPublisher().publish(topic, message); logger.log(AcsLogLevel.DEBUG,"change published on : " + destination); } } catch (Exception e) { logger.log(AcsLogLevel.ERROR,"unable to publish", e); close(); } } public void sendInit(AlarmImpl alarm, String destination) { try { Topic topic = getTopicSession().createTopic(destination); TextMessage message = getTopicSession().createTextMessage(); message.setText(AlarmMessageConversion.getXML(alarm)); setMessageProperties(message, alarm); message.setObjectProperty("NOT_REDUCED_MASKED_SET", Boolean.TRUE); if (!(alarm.getStatus().getMasked().booleanValue() || alarm.getStatus().getReduced().booleanValue())) { message.setObjectProperty("REDUCED_MASKED_SET", Boolean.TRUE); } else { message.setObjectProperty("REDUCED_MASKED_SET", Boolean.FALSE); } getTopicPublisher().publish(topic, message); } catch (Exception e) { logger.log(AcsLogLevel.ERROR,"unable to send alarm " + alarm.getAlarmId() + " to destination " + destination, e); close(); //throw new EJBException("unable to send alarm " + alarm.getAlarmId() + " to destination " + destination, e); } } public void sendInit(Collection alarms, String destination) { try { logger.log(AcsLogLevel.DEBUG,"sending " + alarms.size() + " initial alarm(s) to " + destination + "..."); Topic topic = getTopicSession().createTopic(destination); TextMessage message = getTopicSession().createTextMessage(); Iterator iterator = alarms.iterator(); while (iterator.hasNext()) { AlarmImpl alarm = (AlarmImpl) iterator.next(); message.setText(AlarmMessageConversion.getXML(alarm)); message.clearProperties(); setMessageProperties(message, alarm); message.setObjectProperty("NOT_REDUCED_MASKED_SET", Boolean.TRUE); if (!(alarm.getStatus().getMasked().booleanValue() || alarm.getStatus().getReduced().booleanValue())) { message.setObjectProperty("REDUCED_MASKED_SET", Boolean.TRUE); } else { message.setObjectProperty("REDUCED_MASKED_SET", Boolean.FALSE); } getTopicPublisher().publish(topic, message); } logger.log(AcsLogLevel.DEBUG,"initial alarm(s) sent to " + destination); } catch (Exception e) { close(); throw new LaserRuntimeException("unable to send alarms to " + destination+" : "+e.getMessage()); } } public void publish(Collection alarmChanges) { Iterator iterator = alarmChanges.iterator(); while (iterator.hasNext()) { publish((AlarmChange) iterator.next()); } } public String getCategoryRootTopic() { return categoryRootTopic; } public void sendInitFinished(String destination) { try { logger.log(AcsLogLevel.DEBUG,"sending init finished message to " + destination + "..."); Topic topic = getTopicSession().createTopic(destination); Message message = getTopicSession().createMessage(); message.setObjectProperty(LASER_INIT_PROPERTY, Boolean.TRUE); getTopicPublisher().publish(topic, message); logger.log(AcsLogLevel.DEBUG,"init finished message sent to " + destination); } catch (Exception e) { close(); } } /** * @param init_alarms * @param destination */ public void sendSearch(Collection alarms, String destination) { try { logger.log(AcsLogLevel.DEBUG,"sending " + alarms.size() + " search alarm(s) to " + destination + "..."); Topic topic = getTopicSession().createTopic(destination); ObjectMessage message = getTopicSession().createObjectMessage(); Iterator iterator = alarms.iterator(); while (iterator.hasNext()) { AlarmImpl alarm = (AlarmImpl) iterator.next(); message.setObject(alarm); message.clearProperties(); setMessageProperties(message, alarm); getTopicPublisher().publish(topic, message); } logger.log(AcsLogLevel.DEBUG,"search alarm(s) sent to " + destination); } catch (Exception e) { close(); throw new LaserRuntimeException("unable to send search alarms to " + destination+" : "+e.getMessage()); } sendSearchFinished(destination); } // // -- PRIVATE METHODS -------------------------------------------- // private void sendSearchFinished(String destination) { try { logger.log(AcsLogLevel.DEBUG,"sending search finished message to " + destination + "..."); Topic topic = getTopicSession().createTopic(destination); Message message = getTopicSession().createMessage(); message.setObjectProperty(LASER_SEARCH_PROPERTY, Boolean.TRUE); getTopicPublisher().publish(topic, message); logger.log(AcsLogLevel.DEBUG,"search finished message sent to " + destination); } catch (Exception e) { close(); throw new LaserRuntimeException("unable to send search finished message to " + destination+" : "+ e.getMessage()); } } // private Context getInitialContext() throws NamingException { // if (context == null) { // context = new InitialContext(); // } // // return context; // } private TopicSession getTopicSession() throws JMSException, NamingException { if (session == null) { session = getTopicConnection().createTopicSession(false, Session.AUTO_ACKNOWLEDGE); } return session; } private TopicConnection getTopicConnection() throws JMSException, NamingException { if (connection == null) { // TopicConnectionFactory tcf = (TopicConnectionFactory) // getInitialContext().lookup("SonicJMS/TopicConnectionFactory"); connection = topicConnectionFactory.createTopicConnection(); } return connection; } private TopicPublisher getTopicPublisher() throws JMSException, NamingException { if (publisher == null) { publisher = getTopicSession().createPublisher(null); } return publisher; } private void close() { if (session != null) { try { session.close(); } catch (JMSException je) { logger.log(AcsLogLevel.ERROR,"unable to close JMS session", je); } } if (connection != null) { try { connection.close(); } catch (JMSException je) { logger.log(AcsLogLevel.ERROR,"unable to close JMS connection", je); } } publisher = null; session = null; connection = null; } private void setMessageProperties(Message message, Alarm alarm) throws JMSException { if (message==null || alarm==null) { throw new NullPointerException("setMessageProperties: message and/or alarm is null"); } // alarm id message.setObjectProperty("ALARM_ID", alarm.getAlarmId()); // triplet message.setObjectProperty("FAULT_FAMILY", alarm.getTriplet().getFaultFamily()); message.setObjectProperty("FAULT_MEMBER", alarm.getTriplet().getFaultMember()); message.setObjectProperty("FAULT_CODE", alarm.getTriplet().getFaultCode()); // problem description if (alarm.getProblemDescription() != null) { message.setObjectProperty("PROBLEM_DESCRIPTION", alarm.getProblemDescription()); } // location if (alarm.getLocation() != null) { if (alarm.getLocation().getBuilding() != null) { if (alarm.getLocation().getBuilding().getBuildingNumber() != null) { message.setObjectProperty("BUILDING", alarm.getLocation().getBuilding().getBuildingNumber()); } if (alarm.getLocation().getBuilding().getSite() != null) { message.setObjectProperty("SITE", alarm.getLocation().getBuilding().getSite()); } if (alarm.getLocation().getBuilding().getZone() != null) { message.setObjectProperty("SAFETY_ZONE", alarm.getLocation().getBuilding().getZone()); } } } // priority message.setObjectProperty("PRIORITY", alarm.getPriority()); // source message.setObjectProperty("SOURCE_NAME", alarm.getSource().getName()); // responsible person if (alarm.getResponsiblePerson() != null) { message.setObjectProperty("RESPONSIBLE_PERSON", alarm.getResponsiblePerson().getFirstName() + " " + alarm.getResponsiblePerson().getFamilyName()); } // system name message.setObjectProperty("SYSTEM_NAME", alarm.getSystemName()); // identifier message.setObjectProperty("IDENTIFIER", alarm.getIdentifier()); // status message.setObjectProperty("ACTIVE", alarm.getStatus().getActive()); message.setObjectProperty("REDUCED", alarm.getStatus().getReduced()); message.setObjectProperty("MASKED", alarm.getStatus().getMasked()); // user properties Properties user_properties = alarm.getStatus().getProperties(); if ((user_properties != null) && (user_properties.size() != 0)) { Enumeration keys = user_properties.propertyNames(); while (keys.hasMoreElements()) { String key = (String) keys.nextElement(); String value = user_properties.getProperty(key); if (key.toUpperCase().endsWith(BOOLEAN_SUFFIX)) { message.setObjectProperty(key, Boolean.valueOf(value)); } else if (key.toUpperCase().endsWith(INTEGER_SUFFIX)) { try { message.setObjectProperty(key, Integer.valueOf(value)); } catch (NumberFormatException nfe) { logger.log(AcsLogLevel.WARNING,"integer property was expected, found : " + value); } } else if (key.toUpperCase().endsWith(DOUBLE_SUFFIX)) { try { message.setObjectProperty(key, Double.valueOf(value)); } catch (NumberFormatException nfe) { logger.log(AcsLogLevel.WARNING,"double property was expected, found : " + value); } } else if (key.toUpperCase().endsWith(FLOAT_SUFFIX)) { try { message.setObjectProperty(key, Float.valueOf(value)); } catch (NumberFormatException nfe) { logger.log(AcsLogLevel.WARNING,"float property was expected, found : " + value); } } else if (key.toUpperCase().endsWith(SHORT_SUFFIX)) { try { message.setObjectProperty(key, Short.valueOf(value)); } catch (NumberFormatException nfe) { logger.log(AcsLogLevel.WARNING,"short property was expected, found : " + value); } } else if (key.toUpperCase().endsWith(BYTE_SUFFIX)) { try { message.setObjectProperty(key, Byte.valueOf(value)); } catch (NumberFormatException nfe) { logger.log(AcsLogLevel.WARNING,"byte property was expected, found : " + value); } } else { message.setStringProperty(key, value); } } } } }