/* * ALMA - Atacama Large Millimiter Array (c) European Southern Observatory, 2007 * * This library is free software; you can redistribute it and/or modify it under * the terms of the GNU Lesser General Public License as published by the Free * Software Foundation; either version 2.1 of the License, or (at your option) * any later version. * * This library is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS * FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more * details. * * You should have received a copy of the GNU Lesser General Public License * along with this library; if not, write to the Free Software Foundation, Inc., * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * */ /** * @author acaproni * @version $Id: CategorySubscriber.java,v 1.6 2011/03/25 13:57:08 acaproni Exp $ * @since */ package alma.acs.lasercore.test.stress.category; import alma.acs.container.ContainerServices; import alma.acs.logging.AcsLogLevel; import alma.acs.lasercore.test.stress.CategoryClient; import java.io.StringReader; import javax.jms.JMSException; import javax.jms.Message; import javax.jms.MessageListener; import javax.jms.Topic; import javax.xml.parsers.DocumentBuilder; import javax.xml.parsers.DocumentBuilderFactory; import org.w3c.dom.Document; import org.w3c.dom.Node; import org.w3c.dom.NodeList; import org.xml.sax.InputSource; import com.cosylab.acs.jms.ACSJMSSession; import com.cosylab.acs.jms.ACSJMSTextMessage; import com.cosylab.acs.jms.ACSJMSTopicSubscriber; public class CategorySubscriber implements MessageListener { public static final String NOT_AVAILABLE = "N/A"; // Container services private final ContainerServices acsCS; // Root and path names private final String rootName; private final String pathName; // The variables for JMS private ACSJMSTopicSubscriber consumer; private ACSJMSSession session; private Topic topic; // The DOM parser private DocumentBuilder builder = null; // The listener of alarms private final CategoryClient categoryClient; // Remember if the Subscriber has been closed private volatile boolean closed=false; /** * Constructor * * @param contSvc ACS container services * @param rootName The root name * @param pathName The path name */ public CategorySubscriber(ContainerServices contSvc, String rootName, String pathName, CategoryClient categoryClient) throws Exception { if (contSvc==null) { throw new IllegalArgumentException("Invalid null ContainerServices in constructor"); } if (rootName==null || rootName.length()==0) { throw new IllegalArgumentException("Invalid root name in constructor"); } if (pathName==null || pathName.length()==0) { throw new IllegalArgumentException("Invalid path name in constructor"); } if (categoryClient==null) { throw new IllegalArgumentException("Invalid null CategoryClient in constructor"); } this.categoryClient=categoryClient; acsCS=contSvc; this.rootName=rootName; this.pathName=pathName; initParser(); connectSubscriber(); } /** * Close the subscriber * * Should be called when done. */ public void close() { if (closed) { return; } closed=true; try { consumer.close(); } catch (Exception e) { System.err.println("Error closing the consumer "+e.getMessage()); e.printStackTrace(); } } /** * @see Object.<code>finalize</code> */ public void finalize() { close(); try { super.finalize(); } catch (Throwable t) { System.err.println("Error finalizing "+t.getMessage()); t.printStackTrace(); } } /** * Initialize the parser * */ private void initParser() throws Exception { DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance(); builder = factory.newDocumentBuilder(); } /** * Connect the JMS consumer settting this class as listener * for incoming messages * * @throws JMSException */ private void connectSubscriber() throws JMSException { acsCS.getLogger().log(AcsLogLevel.INFO,"Connecting subscriber to "+rootName+"."+pathName); session = new ACSJMSSession(acsCS); topic = session.createTopic(rootName+"."+pathName); consumer = (ACSJMSTopicSubscriber)session.createConsumer(topic); if (consumer!=null) { acsCS.getLogger().log(AcsLogLevel.INFO,"Consumer connected to "+rootName+"."+pathName); consumer.setMessageListener(this); } } /** * Executed when a message has been received * * @param msg */ public void onMessage(Message msg) { if (closed) { return; } acsCS.getLogger().log(AcsLogLevel.DEBUG,"Message received from "+rootName+"."+pathName); if (msg instanceof ACSJMSTextMessage) { ACSJMSTextMessage textMsg = (ACSJMSTextMessage)msg; String content=null; try { content=textMsg.getText(); } catch (JMSException e) { acsCS.getLogger().log(AcsLogLevel.WARNING,"Exception caught while getting a message "+e.getMessage()); return; } if (content==null || content.length()==0) { return; } adddAlarmView(content); } else { System.out.println("Not a text msg"); } } /** * Get the fields of the alarm to show in the table and * add the alarm to the model * * @param s */ private void adddAlarmView(String xmlString) { String alarmID=""; // Triplet String priority = ""; // Priority String sourceTimestamp=null; // Source timestamp (ISO 8601 string) String description=NOT_AVAILABLE; // Problem description String cause=NOT_AVAILABLE; // The cause of the alarm String active=NOT_AVAILABLE; // Active String hostName=NOT_AVAILABLE; String nodeParent=NOT_AVAILABLE; String nodeChild=NOT_AVAILABLE; String multiplicityParent=NOT_AVAILABLE; String multiplicityChild=NOT_AVAILABLE; String reduced=NOT_AVAILABLE; String masked=NOT_AVAILABLE; Document document = null; try { document = builder.parse(new InputSource(new StringReader(xmlString))); } catch (Exception e) { acsCS.getLogger().log(AcsLogLevel.ERROR, "Error parsing an alarm"); e.printStackTrace(System.err); return; } Node node = document.getFirstChild(); NodeList list=node.getChildNodes(); for (int t=0; t<list.getLength(); t++) { Node childNode = list.item(t); if (childNode.getNodeName().equals(("alarmId"))) { Node idNode = childNode.getLastChild(); alarmID=idNode.getNodeValue(); } if (childNode.getNodeName().equals(("priority"))) { Node priNode = childNode.getLastChild(); priority=priNode.getNodeValue(); } if (childNode.getNodeName().equals(("cause"))) { Node priNode = childNode.getLastChild(); cause=priNode.getNodeValue(); } if (childNode.getNodeName().equals(("nodeParent"))) { Node priNode = childNode.getLastChild(); nodeParent=priNode.getNodeValue(); } if (childNode.getNodeName().equals(("nodeChild"))) { Node priNode = childNode.getLastChild(); nodeChild=priNode.getNodeValue(); } if (childNode.getNodeName().equals(("multiplicityParent"))) { Node priNode = childNode.getLastChild(); multiplicityParent=priNode.getNodeValue(); } if (childNode.getNodeName().equals(("multiplicityChild"))) { Node priNode = childNode.getLastChild(); multiplicityChild=priNode.getNodeValue(); } // This tag sometimes appear inside visualFields (see below) if (childNode.getNodeName().equals("problemDescription")) { Node dateNode=childNode.getLastChild(); if (dateNode!=null) { description=dateNode.getNodeValue(); } else { description=NOT_AVAILABLE; } } if (childNode.getNodeName().equals(("status"))) { NodeList statusNodeList=childNode.getChildNodes(); for (int j=0; j<statusNodeList.getLength(); j++) { Node statusNode=statusNodeList.item(j); if (statusNode.getNodeName().equals("active")) { Node activeNode=statusNode.getLastChild(); active=activeNode.getNodeValue(); } if (statusNode.getNodeName().equals("reduced")) { Node activeNode=statusNode.getLastChild(); reduced=activeNode.getNodeValue(); } if (statusNode.getNodeName().equals("masked")) { Node activeNode=statusNode.getLastChild(); masked=activeNode.getNodeValue(); } if (statusNode.getNodeName().equals("sourceTimestamp")) { Node srcTstampNode = statusNode.getLastChild(); sourceTimestamp=srcTstampNode.getNodeValue(); } } } // Get the host name if (childNode.getNodeName().equals("source")) { NodeList sourceNodeList=childNode.getChildNodes(); for (int m=0; m<sourceNodeList.getLength(); m++) { Node hostNameNode=sourceNodeList.item(m); if (hostNameNode.getNodeName().equals("hostName")) { Node hNameNode=hostNameNode.getLastChild(); if (hNameNode!=null) { hostName=hNameNode.getNodeValue(); } else { hostName=NOT_AVAILABLE; } break; } } } // Sometimes problemDescription appeared into visualFields if (childNode.getNodeName().equals("visualFields")) { NodeList visualFieldsNodeList=childNode.getChildNodes(); for (int m=0; m<visualFieldsNodeList.getLength(); m++) { Node descNode=visualFieldsNodeList.item(m); if (descNode.getNodeName().equals("problemDescription")) { Node dateNode=descNode.getLastChild(); if (dateNode!=null) { description=dateNode.getNodeValue(); } else { description=NOT_AVAILABLE; } break; } } } } try { categoryClient.dispatchAlarm( new AlarmView( alarmID, priority, sourceTimestamp, description, cause, active, hostName, nodeParent, nodeChild, multiplicityParent, multiplicityChild, reduced, masked)); } catch (Throwable t) { System.err.println("Error building alarm "+t.getMessage()); t.printStackTrace(System.err); } } }