/* * Dog - Communication * * Copyright (c) 2013 Dario Bonino and Luigi De Russis * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License */ package it.polito.elite.dog.communication.rest.ruleengine; import java.io.StringReader; import java.io.StringWriter; import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors; import java.util.concurrent.atomic.AtomicReference; import javax.ws.rs.Path; import javax.xml.bind.JAXBContext; import javax.xml.bind.JAXBException; import javax.xml.bind.Unmarshaller; import it.polito.elite.dog.addons.rules.api.RuleEngineApi; import it.polito.elite.dog.addons.rules.schemalibrary.RuleList; import it.polito.elite.dog.communication.rest.ruleengine.api.RuleEngineRESTApi; import it.polito.elite.dog.core.library.util.LogHelper; import org.osgi.framework.BundleContext; import org.osgi.service.log.LogService; /** * @author <a href="mailto:dario.bonino@polito.it">Dario Bonino</a> * @author <a href="mailto:luigi.derussis@polito.it">Luigi De Russis</a> * @see <a href="http://elite.polito.it">http://elite.polito.it</a> * */ @Path("/api/v1/rules/") public class RuleEngineRESTEndpoint implements RuleEngineRESTApi { // the service logger private LogHelper logger; // the bundle context reference private BundleContext context; // the rule service for which this bundle offers a rest interface private AtomicReference<RuleEngineApi> ruleEngine; // the JAXB context private JAXBContext jaxbContext; // the JAXB unmarshaller private AtomicReference<Unmarshaller> unmarshaller; /** * Default constructor */ public RuleEngineRESTEndpoint() { // init this.ruleEngine = new AtomicReference<RuleEngineApi>(); this.unmarshaller = new AtomicReference<Unmarshaller>(); try { // int here JAXB objects (hoping to improve the performance of // the bundle) this.jaxbContext = JAXBContext.newInstance(RuleList.class.getPackage().getName()); this.unmarshaller.set(this.jaxbContext.createUnmarshaller()); } catch (JAXBException e) { System.out.println("[RuleEngineRESTEndpoint] Error creating the JAXB Context" + e); } } /** * Bundle activation, stores a reference to the context object passed by the * framework to get access to system data, e.g., installed bundles, etc. * * @param context */ public void activate(BundleContext context) { // store the bundle context this.context = context; // init the logger with a null logger this.logger = new LogHelper(this.context); // log the activation this.logger.log(LogService.LOG_INFO, "Activated...."); } /** * Prepare the bundle to be deactivated... */ public void deactivate() { // null the context this.context = null; // log deactivation this.logger.log(LogService.LOG_INFO, "Deactivated..."); // null the logger this.logger = null; } public void addedRuleEngine(RuleEngineApi ruleEngine) { // store a reference to the rule service this.ruleEngine.set(ruleEngine); // debug if (this.logger != null) this.logger.log(LogService.LOG_DEBUG, "Connected to the RuleEngineApi"); else System.out.println("[RuleEngineRESTEndpoint] Connected to the RuleEngineApi"); } public void removedRuleEngine(RuleEngineApi ruleEngine) { // remove the reference to the rule service this.ruleEngine = null; // debug this.logger.log(LogService.LOG_DEBUG, "Disconnected from the RuleEngineApi"); } /* * (non-Javadoc) * * @see * it.polito.elite.dog.communication.rest.ruleengine.api.RuleEngineRESTApi * #getDRLRules() */ @Override public String getDRLRules() { // no rules at the beginning String drlRules = ""; // extract the rule from the rule engine in the DRL format if (this.ruleEngine != null) drlRules = this.ruleEngine.get().getDRLRules(); // return existing rules return drlRules; } /* * (non-Javadoc) * * @see * it.polito.elite.dog.communication.rest.ruleengine.api.RuleEngineRESTApi * #getXMLRules() */ @Override public String getXMLRules() { // no rules at the beginning String xmlRules = ""; // extract the rule from the rule engine in the JAXB format if (this.ruleEngine != null) { xmlRules = this.generateXML(this.ruleEngine.get().getRules()); } // return existing rules return xmlRules; } /* * (non-Javadoc) * * @see * it.polito.elite.dog.communication.rest.ruleengine.api.RuleEngineRESTApi * #addRulesXML(it.polito.elite.dog.addons.rules.schemalibrary.RuleList) */ @Override public void addRulesXML(String xmlRules) { // check not null if (this.ruleEngine != null && this.unmarshaller != null) { try { // add the received rules final RuleList rules = (RuleList) this.unmarshaller.get().unmarshal(new StringReader(xmlRules)); // thread for asynchronous call ExecutorService executor = Executors.newSingleThreadExecutor(); executor.execute(new Runnable() { @Override public void run() { ruleEngine.get().addRule(rules); } }); } catch (JAXBException e) { this.logger.log(LogService.LOG_ERROR, "JAXB Error", e); } } else { this.logger.log(LogService.LOG_ERROR, "Error in adding a new rule"); } } @Override public void updateRuleXML(String ruleId, String ruleContent) { // check not null if (this.ruleEngine != null && this.unmarshaller != null) { try { // unmarshall the rule to update RuleList updatedRule = (RuleList) this.unmarshaller.get().unmarshal( new StringReader(ruleContent)); // update received rules this.ruleEngine.get().updateRule(ruleId, updatedRule); } catch (Exception e) { this.logger.log(LogService.LOG_ERROR, "JAXB Error", e); } } else { this.logger.log(LogService.LOG_ERROR, "Error in updating the rule " + ruleId); } } /* * (non-Javadoc) * * @see * it.polito.elite.dog.communication.rest.ruleengine.api.RuleEngineRESTApi * #removeRule(java.lang.String) */ @Override public void removeRule(String ruleId) { // check not null if (this.ruleEngine != null) { // add received rules this.ruleEngine.get().removeRule(ruleId); } } /** * Generate the XML to be sent * * @param rules * the {@link RuleList} object to marshall * @return the corresponding XML */ private String generateXML(RuleList rules) { String rulesXML = ""; try { StringWriter output = new StringWriter(); // marshall the RuleList... this.jaxbContext.createMarshaller().marshal(rules, output); rulesXML = output.getBuffer().toString(); } catch (Exception e) { // the exception can be throw by the JAXB.marshal method... this.logger.log(LogService.LOG_ERROR, "Exception in JAXB Marshalling...", e); } return rulesXML; } }