/* * 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.deployment; import javax.persistence.Basic; import javax.persistence.CascadeType; import javax.persistence.Entity; import javax.persistence.GeneratedValue; import javax.persistence.Id; import javax.persistence.ManyToOne; import javax.persistence.OneToOne; import com.telefonica.claudia.slm.naming.DirectoryEntry; import com.telefonica.claudia.slm.naming.FQN; import com.telefonica.claudia.slm.naming.ReservoirDirectory; /** * Class representing old style rules * @author tid * */ @Entity public class Rule implements DirectoryEntry { @Id @GeneratedValue public long internalId; private String KPIName=""; private String KPIType=""; private String name=""; private String eventType=""; @ManyToOne private ServiceApplication serviceApplication = null; @OneToOne(cascade={CascadeType.REFRESH, CascadeType.MERGE, CascadeType.PERSIST}) private FQN ruleFQN = null; // Y1 style elements @Basic private String checkPeriod=""; private String condition=""; private String action=""; // Y2 elements private String associatedVee=""; /** * Buffer of measure values. The buffer will have a fixed capacity, and all * the reads and writes will be made on the head position. */ private double[] buffer; /** * Reading head for the buffer. */ private int bufferHead = 0; private double window = 0.0; private double frequency = 0.0; private double quota = 0.0; private double tolerance = 0.0; @ManyToOne private ServiceKPI kpi; public Rule() {} public Rule(ServiceApplication serviceApplication, String checkPeriod, String condition, String action){ this.action=action; this.checkPeriod=checkPeriod; this.condition=condition; this.serviceApplication=serviceApplication; } public Rule(ServiceApplication serviceApplication){ this.serviceApplication=serviceApplication; } public void setAction(String action){this.action=action;} public String getAction(){return action;} public void setCheckPeriod(String checkPeriod){this.checkPeriod=checkPeriod;} public String getCheckPeriod(){return checkPeriod;} public void setCondition(String condition){this.condition=condition;} public String getCondition(){return condition;} /** * This method has to be invoked by the parser before actually considering * the KPI object is usable * * @param window * @param frequency * @param quota * @param associatedVee */ public void configure(double window, double frequency, double quota, String associatedVee, ServiceKPI kpi, double tolerance) { this.window = window; this.frequency = frequency; this.quota=quota; this.associatedVee=associatedVee; this.kpi=kpi; this.tolerance=tolerance; buffer = new double[(int) window]; } /** * * Configure the rule for the the given KPI. This method * should be called once all the other parameters have been fullfilled with * its appropiate setters. * * @param kpi */ public void configure(ServiceKPI kpi) { this.kpi=kpi; System.out.println ("configure " + kpi.getKPIName()); buffer = new double[(int) window]; } public double getTolerance() { return tolerance; } public void setTolerance(double tolerance) { this.tolerance = tolerance; } public String buildRule(boolean up){ String bodyUp, bodyDown, rule; System.out.println ("building rule" ); String actionUp= "actions.createReplica(\""+associatedVee+"\")"; System.out.println (actionUp); String actionDown="actions.removeReplica(\""+associatedVee+"\")"; System.out.println (actionDown); String header="package com.telefonica.claudia.slm.rulesEngine;"+"\n"+"// Imports for all types of events should be here..."+"\n"+"import com.telefonica.claudia.slm.eventsBus.events.VeeHwMeasureEvent;"+"\n"+"import com.telefonica.claudia.slm.eventsBus.events.AgentMeasureEvent;"+"\n"+"import com.telefonica.claudia.slm.eventsBus.events.ProbeMeasureEvent;"+"\n"+"global com.telefonica.claudia.slm.rulesEngine.Actions actions; \n"; System.out.println (header); System.out.println ("kpi" + kpi); if (up){ // add rule name bodyUp="rule"+" \""+ruleFQN.toString(); // add other headers bodyUp=bodyUp+"\""+"\n"+"lock-on-active true"+"\n"+"salience 100"+"\n"+"when"+"\n"; // add then part of the rule bodyUp=bodyUp+" event : "+eventType.toString()+" (measure == \""+kpi.getFQN().toString()+"\" , "+"eval(actions.getAverage(\""+kpi.getFQN().toString()+"\",value)/(actions.getAmount(\""+ associatedVee+"\"))> "+Double.toString(quota+(quota*tolerance)/100) +" )); \n"+"then \n"; bodyUp=bodyUp+actionUp+";\n"+"end"; rule=header+bodyUp; System.out.println(header+bodyUp); }else{ // add rule name bodyDown="rule"+" \""+ruleFQN.toString() + "b"; // add other headers bodyDown=bodyDown+"\""+"\n"+"lock-on-active true"+"\n"+"salience 100"+"\n"+"when"+"\n"; // add then part of the rule bodyDown=bodyDown+" event : "+eventType.toString()+" (measure == \""+kpi.getFQN().toString()+"\" , "+"eval(actions.getAverage(\""+kpi.getFQN().toString()+"\",value)/(actions.getAmount(\""+ associatedVee+"\"))< "+Double.toString(quota-(quota*tolerance)/100)+" )); \n"+"then \n"; bodyDown=bodyDown+actionDown+";\n"+"end"; rule=header+bodyDown; System.out.println(header+bodyDown); } return rule; } public String getAssociatedVee() { return associatedVee; } public void setAssociatedVee(String associatedVee) { this.associatedVee = associatedVee; } /** * Put the received measure inside the buffer, in the head position. * * @param receivedKpi * Measure value to store */ public void put(double receivedKpi) { bufferHead = (++bufferHead)%buffer.length; buffer[bufferHead] =receivedKpi; } public double getAverage() { double average = 0.0; for (int i = 0; i < buffer.length; i++) { average += buffer[i]; } return (average / buffer.length); } public double[] getBuffer() { return buffer; } public void setBuffer(double[] buffer) { this.buffer = buffer; } public double getWindow() { return window; } public void setWindow(double window) { this.window = window; } public double getFrequency() { return frequency; } public void setFrequency(double frequency) { this.frequency = frequency; } public double getQuota() { return quota; } public void setQuota(double quota) { this.quota = quota; } public void setKpi(ServiceKPI kpi) { System.out.println (" new set kpi " + "" + " " + kpi.getKPIName() + " " + this.getName()); this.kpi = kpi; } public ServiceKPI getKpi() { return kpi; } public String getKPIName() { return KPIName; } public void setKPIName(String kPIName) { KPIName = kPIName; } public String getKPIType() { return KPIType; } public void setKPIType(String kPIType) { KPIType = kPIType; } public void setName(String name){this.name=name;} public String getName(){return name;} public void setEventType(String eventType){this.eventType=eventType;} public String getEventType(){return eventType;} public ServiceApplication getServiceApplication() { return serviceApplication; } public FQN getFQN() { if(ruleFQN == null) ruleFQN = ReservoirDirectory.getInstance().buildFQN(this); return ruleFQN; } @Override public int hashCode() { return getFQN().hashCode(); } @Override public boolean equals(Object object) { if(object == null) return false; if(!(object instanceof Rule)) return false; return ((Rule)object).getFQN().equals(getFQN()); } }