/* * Claudia Project * http://claudia.morfeo-project.org * * (C) Copyright 2010 Telefonica Investigacion y Desarrollo * S.A.Unipersonal (Telefonica I+D) * * See CREDITS file for info about members and contributors. * * This program is free software; you can redistribute it and/or modify * it under the terms of the Affero GNU General Public License (AGPL) as * published by the Free Software Foundation; either version 3 of the License, * or (at your option) any later version. * * This program 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 General Public License for more details. * * You should have received a copy of the Affero GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * * If you want to use this software an plan to distribute a * proprietary application in any way, and you are not licensing and * distributing your source code under AGPL, you probably need to * purchase a commercial license of the product. Please contact * claudia-support@lists.morfeo-project.org for more information. */ package com.telefonica.claudia.slm.rulesEngine; import javax.jms.Connection; import javax.jms.ConnectionFactory; import javax.jms.JMSException; import javax.jms.Message; import javax.jms.MessageConsumer; import javax.jms.ObjectMessage; import javax.jms.Session; import javax.jms.Topic; import javax.naming.Context; import javax.naming.InitialContext; import javax.naming.NamingException; import org.apache.log4j.ConsoleAppender; import org.apache.log4j.Level; import org.apache.log4j.Logger; import org.apache.log4j.PatternLayout; import org.drools.FactHandle; import org.drools.WorkingMemory; import com.telefonica.claudia.slm.common.SMConfiguration; import com.telefonica.claudia.slm.deployment.ServiceApplication; import com.telefonica.claudia.slm.eventsBus.BusListener; import com.telefonica.claudia.slm.eventsBus.events.Event; import com.telefonica.claudia.slm.eventsBus.events.Event.EventType; import com.telefonica.claudia.slm.lifecyclemanager.FSM; import com.telefonica.claudia.slm.lifecyclemanager.LifecycleController; public class EventsReceptor implements BusListener { @SuppressWarnings("unused") private FactHandle factHandle=null; private static Logger logger = Logger.getLogger("Monitoring"); private RulesEngine rulesEngine = null; private ServiceApplication sap; private LifecycleController lcc; private FSM fsm; static { Logger.getLogger("es.tid.reservoir.serviceManager.rulesEngine").addAppender( new ConsoleAppender(new PatternLayout("%-5p [%t] %c{2}: %m%n"), "System.out")); Logger.getLogger("es.tid.reservoir.serviceManager.rulesEngine").setLevel(Level.INFO); } public EventsReceptor(RulesEngine rulesEngine){ this.rulesEngine = rulesEngine; } public EventsReceptor(RulesEngine rulesEngine, FSM fsm, ServiceApplication sap, LifecycleController lcc) { this.rulesEngine = rulesEngine; this.lcc=lcc; this.sap=sap; this.fsm=fsm; Thread veehwMeasThread = new Thread(new EventListener(EventType.VEE_HW_MEASUREMENT, this), "Listener thread for " + EventType.VEE_HW_MEASUREMENT + " events"); Thread agentMeasThread = new Thread(new EventListener(EventType.AGENT_MEASUREMENT, this), "Listener thread for " + EventType.AGENT_MEASUREMENT + " events"); Thread probeMeasThread = new Thread(new EventListener(EventType.PROBE_MEASUREMENT, this), "Listener thread for " + EventType.PROBE_MEASUREMENT + " events"); veehwMeasThread.start(); agentMeasThread.start(); probeMeasThread.start(); } public void onEvent(final Event event) { logger.debug("Event reached Rules Engine: " + event.getEventType() + " " + fsm.getStateText()); if (!fsm.getStateText().equals("RUNNING")) { logger.warn("Measure got when the service is not already deployed"); return; } /** * Rococo engineering: the inline implementation of this interface seems to have one * and only purpose: code obfuscation. The interface itself it's not the most useful * software component... */ rulesEngine.executeRules( new WorkingEnvironmentCallback() { public void initEnvironment(WorkingMemory workingMemory) { // Load incoming event into the working memory Actions act=new Actions(lcc,sap,fsm); workingMemory.setGlobal("actions", act); factHandle=workingMemory.insert(event); }; } ); } } class EventListener implements Runnable { private static Logger logger = Logger.getLogger(EventListener.class); private Connection connection = null; private Session session = null; private EventType eventType = null; private EventsReceptor ere = null; private MessageConsumer messageConsumer = null; public EventListener(EventType eventType, EventsReceptor ere){ this.eventType = eventType; this.ere = ere; } public void finalize() { if(messageConsumer!=null) try { messageConsumer.close(); } catch (JMSException ex) { logger.warn("Exception caught when closing Message Consumer", ex); } } public void run() { try { listen(); } catch (NamingException ex) { logger.error("NamingException caught", ex); } catch (JMSException ex) { logger.error("JMSException caught", ex); } finally { try{ if(session != null){ logger.info("Clossing session"); session.close(); } if(connection != null){ logger.info("Clossing connection"); connection.close(); } } catch (JMSException ex) { logger.error("JMSException caucht when closing session and" + "connection", ex); } } } public void listen() throws NamingException, JMSException { logger.info("Getting initial JNDI context"); Context initialContext = new InitialContext(SMConfiguration.getInstance().getJNDIEnv()); logger.info("Creating Connection Factory"); ConnectionFactory connectionFactory = (ConnectionFactory) initialContext.lookup("ConnectionFactory"); logger.info("Getting Topic"); Topic topic = (Topic)initialContext.lookup(Event.busTopicForEventType(eventType)); logger.info("Creating Connection"); connection = connectionFactory.createConnection(); connection.start(); logger.info("Creating Session"); session = connection.createSession(false, Session.AUTO_ACKNOWLEDGE); logger.info("Registering message listener"); messageConsumer = session.createConsumer(topic); Message message = null; while(true){ message = messageConsumer.receive(); logger.debug("New message received, topic: " + ((Topic)message.getJMSDestination()).toString()); if(message instanceof ObjectMessage) { ObjectMessage objectMessage = (ObjectMessage)message; if(objectMessage.getObject() instanceof Event) { Event event = (Event)objectMessage.getObject(); ere.onEvent(event); logger.debug("Event info - " + event); } else { logger.error("Message does not contain an Event"); } } else { logger.error("Message is not instance of ObjectMessage"); } } } }