Java tutorial
/** * Copyright (C) 2011 Pedro Mauricio Costa <pm.costa [at] imperial [dot] ac [dot] uk> * * This file is part of Cloud2Bubble <http://www.cloud2bubble.com>. * * Cloud2Bubble is free software: you can redistribute it and/or modify * it under the terms of the GNU Lesser Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * Cloud2Bubble 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 Public License for more details. * * You should have received a copy of the GNU Lesser Public License * along with Cloud2Bubble. If not, see <http://www.gnu.org/licenses/>. */ package com.cloud2bubble.services; import java.util.HashMap; import java.util.Map; import net.ponder2.managedobject.Bubble; import net.ponder2.managedobject.Cloudlet; import net.ponder2.managedobject.MessagingQueue.Producer; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import org.drools.KnowledgeBase; import org.drools.KnowledgeBaseConfiguration; import org.drools.KnowledgeBaseFactory; import org.drools.builder.KnowledgeBuilder; import org.drools.builder.KnowledgeBuilderError; import org.drools.builder.KnowledgeBuilderErrors; import org.drools.builder.KnowledgeBuilderFactory; import org.drools.builder.ResourceType; import org.drools.conf.EventProcessingOption; import org.drools.io.ResourceFactory; import org.drools.logger.KnowledgeRuntimeLogger; import org.drools.logger.KnowledgeRuntimeLoggerFactory; import org.drools.runtime.StatefulKnowledgeSession; import org.drools.runtime.rule.FactHandle; import org.drools.runtime.rule.WorkingMemoryEntryPoint; import com.cloud2bubble.Cloud2Bubble; /** * Provides the functionality of a Rule Engine including temporal event reasoning. * * @author Pedro Mauricio Costa <pm.costa@imperial.ac.uk> * */ public class RuleEngine { private static final Log log = LogFactory.getLog(RuleEngine.class); public static final String EVENT_LISTENER = "EventListener"; public static final String MESSAGE_LISTENER = "MessageListener"; public static final String GLOBAL_LOG = "$log"; public static final String GLOBAL_PRODUCER = "$producer"; public static final String ENGINE_LOGGER = "rule-engine"; private static RuleEngine instance = null; private Map<Object, FactHandle> facts; private KnowledgeBase kbase; private StatefulKnowledgeSession ksession; private KnowledgeRuntimeLogger engineLogger; private WorkingMemoryEntryPoint eventListenerEntryPoint; private WorkingMemoryEntryPoint messageListenerEntryPoint; private Producer producer; private RuleEngine() { try { kbase = createKnowledgeBase(); ksession = kbase.newStatefulKnowledgeSession(); engineLogger = KnowledgeRuntimeLoggerFactory.newFileLogger(ksession, ENGINE_LOGGER); ksession.setGlobal(GLOBAL_LOG, log); eventListenerEntryPoint = ksession.getWorkingMemoryEntryPoint(EVENT_LISTENER); messageListenerEntryPoint = ksession.getWorkingMemoryEntryPoint(MESSAGE_LISTENER); new Thread(new Runnable() { public void run() { ksession.fireUntilHalt(); } }).start(); } catch (Exception e) { log.fatal("Couldn't initiate the Rule Engine", e); } facts = new HashMap<Object, FactHandle>(); } /** * Returns the singleton instance of the Rule Engine. * * @return */ public static RuleEngine getInstace() { if (instance == null) { instance = new RuleEngine(); } return instance; } public void setProducer(Producer p) { ksession.setGlobal(GLOBAL_PRODUCER, p); } /** * Inserts any object into the Rule Engine. * * @param o a fact */ public void insertInSession(Object o) { FactHandle fh = ksession.insert(o); facts.put(o.hashCode(), fh); } /** * Updates an existing object in the Rule Engine. * * @param o a fact */ public void updateInSession(String o) { ksession.update(facts.get(o), o.hashCode()); } /** * Inserts any object into the Rule Engine through the Event Listener Entry Point. * * @param o an event */ public void insertInEventListener(Object o) { eventListenerEntryPoint.insert(o); } public void insertInMessageListener(Object o) { messageListenerEntryPoint.insert(o); } /** * Stops the Rule Engine. */ public void stop() { ksession.halt(); engineLogger.close(); } /** * Handles the heavy process of loading rules into a knowledge base. * * @return knowledge base ready to generate sessions * @throws Exception */ private static KnowledgeBase createKnowledgeBase() throws Exception { KnowledgeBuilder kbuilder = KnowledgeBuilderFactory.newKnowledgeBuilder(); kbuilder.add(ResourceFactory.newClassPathResource(Cloud2Bubble.getRuleFile()), ResourceType.DRL); KnowledgeBuilderErrors errors = kbuilder.getErrors(); if (errors.size() > 0) { for (KnowledgeBuilderError error : errors) { log.error(error); } throw new IllegalArgumentException("Could not parse knowledge."); } // activates event time-based processing KnowledgeBaseConfiguration config = KnowledgeBaseFactory.newKnowledgeBaseConfiguration(); config.setOption(EventProcessingOption.STREAM); KnowledgeBase kbase = KnowledgeBaseFactory.newKnowledgeBase(config); kbase.addKnowledgePackages(kbuilder.getKnowledgePackages()); return kbase; } public void sendQoeEvent(Cloudlet c, Bubble b) { this.producer.sendQoEEvent(b.getId(), c.getId()); } }