/** * Copyright 2013 Technische Universitat Wien (TUW), Distributed SystemsGroup * E184. This work was partially supported by the European Commission in terms * of the CELAR FP7 project (FP7-ICT-2011-8 #317790). * * 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 at.ac.tuwien.dsg.rSybl.dataProcessingUnit.monitoringPlugins.melaPlugin; import java.io.BufferedReader; import java.io.File; import java.io.FileNotFoundException; import java.io.FileReader; import java.io.InputStream; import java.io.InputStreamReader; import java.io.OutputStream; import java.io.StringReader; import java.net.HttpURLConnection; import java.net.URL; import java.util.ArrayList; import java.util.List; import java.util.Map; import java.util.Timer; import java.util.TimerTask; import java.util.concurrent.atomic.AtomicBoolean; import java.util.logging.Level; import java.util.logging.Logger; import javax.xml.bind.JAXBContext; import javax.xml.bind.JAXBException; import javax.xml.bind.Unmarshaller; import at.ac.tuwien.dsg.csdg.DependencyGraph; import at.ac.tuwien.dsg.csdg.Node; import at.ac.tuwien.dsg.csdg.Node.NodeType; import at.ac.tuwien.dsg.csdg.Relationship.RelationshipType; import at.ac.tuwien.dsg.csdg.elasticityInformation.ElasticityRequirement; import at.ac.tuwien.dsg.csdg.elasticityInformation.elasticityRequirements.BinaryRestriction; import at.ac.tuwien.dsg.csdg.elasticityInformation.elasticityRequirements.BinaryRestrictionsConjunction; import at.ac.tuwien.dsg.csdg.elasticityInformation.elasticityRequirements.Constraint; import at.ac.tuwien.dsg.csdg.elasticityInformation.elasticityRequirements.SYBLSpecification; import at.ac.tuwien.dsg.csdg.inputProcessing.multiLevelModel.abstractModelXML.SYBLDirectiveMappingFromXML; import at.ac.tuwien.dsg.mela.common.configuration.metricComposition.CompositionRulesConfiguration; import at.ac.tuwien.dsg.mela.common.monitoringConcepts.Action; import at.ac.tuwien.dsg.mela.common.monitoringConcepts.Metric; import at.ac.tuwien.dsg.mela.common.monitoringConcepts.MetricValue; import at.ac.tuwien.dsg.mela.common.monitoringConcepts.MonitoredElement; import at.ac.tuwien.dsg.mela.common.monitoringConcepts.MonitoredElementMonitoringSnapshot; import at.ac.tuwien.dsg.mela.common.monitoringConcepts.MonitoredElementMonitoringSnapshots; import at.ac.tuwien.dsg.mela.common.requirements.Condition.Type; import at.ac.tuwien.dsg.mela.common.requirements.Requirement; import at.ac.tuwien.dsg.mela.common.requirements.Requirements; import at.ac.tuwien.dsg.rSybl.dataProcessingUnit.api.model.MonitoringSnapshot; import at.ac.tuwien.dsg.rSybl.dataProcessingUnit.api.model.ServicePartMonitor; import at.ac.tuwien.dsg.rSybl.dataProcessingUnit.monitoringPlugins.interfaces.MonitoringInterface; import at.ac.tuwien.dsg.rSybl.dataProcessingUnit.utils.Configuration; import at.ac.tuwien.dsg.rSybl.dataProcessingUnit.utils.RuntimeLogger; import java.io.StringWriter; import java.util.HashMap; import java.util.Map.Entry; public class MELA_API3 implements MonitoringInterface { private boolean existsStructureData = false; private boolean serviceSet = false; private static final String REST_API_URL = Configuration.getMonitoringServiceURL(); // private static final String REST_API_URL = "http://109.231.121.88:8080/MELA-DataService/REST_WS"; // private static final String REST_API_URL = "http://localhost:8480/MELA/REST_WS"; // private static final String REST_API_URL="http://localhost:8080/MELA-AnalysisService-1.0/REST_WS"; private static final int MONITORING_DATA_REFRESH_INTERVAL = 10; //in seconds private MonitoredElementMonitoringSnapshot latestMonitoringData; private AtomicBoolean monitoringDataUsed; private ArrayList<String> ongoingAction; private List<String> actionTargetEntity; private Node controlService; { latestMonitoringData = new MonitoredElementMonitoringSnapshot(); monitoringDataUsed = new AtomicBoolean(false); } public MELA_API3() { ongoingAction = new ArrayList<String>(); actionTargetEntity = new ArrayList<String>(); } //todo: Continuous refresh data with a semaphore like mechanism to synchronzie resource access { TimerTask task = new TimerTask() { @Override public void run() { if (serviceSet) { refreshMonitoringData(); } } }; Timer monitoringDataRefreshTimer = new Timer(); monitoringDataRefreshTimer.schedule(task, 0, MONITORING_DATA_REFRESH_INTERVAL * 1000); } // private List<MetricFilter> getMetricFilters() { // List<MetricFilter> filters = new ArrayList<MetricFilter>(); // MetricFilter metricFilter = new MetricFilter(); // metricFilter.setId("VMLevelCassandra"); // Metric m; // metricFilter.setLevel(ServiceElement.ServiceElementLevel.VM); // Collection<Metric> metrics = new ArrayList<Metric>(); // metrics.add(new Metric("cpu_usage")); // metrics.add(new Metric("mem_used")); // metrics.add(new Metric("pkts_total")); // // metricFilter.setMetrics(metrics); // filters.add(metricFilter); // // // metricFilter = new MetricFilter(); // // metricFilter.setId("SERVICE_UNITLevel"); // metricFilter.setLevel(ServiceElement.ServiceElementLevel.SERVICE_UNIT); // // metrics = new ArrayList<Metric>(); // m = new Metric("cpu_usage"); // metrics.add(m); // m = new Metric("read_latency"); // metrics.add(m); // m = new Metric("costPerHour"); // metrics.add(m); // m = new Metric("write_latency"); // metrics.add(m); // m = new Metric("responseTime"); // metrics.add(m); // m = new Metric("throughput"); // metrics.add(m); // m = new Metric("throughput_average"); // metrics.add(m); // m = new Metric("clientsNb"); // metrics.add(m); // metricFilter.setMetrics(metrics); // // // filters.add(metricFilter); // metricFilter = new MetricFilter(); // metricFilter.setId("SERVICE_TOPOLOGYLevel"); // metricFilter.setLevel(ServiceElement.ServiceElementLevel.SERVICE_TOPOLOGY); // // metrics = new ArrayList<Metric>(); // m = new Metric("costPerHour"); // metrics.add(m); // m = new Metric("responseTime"); // metrics.add(m); // m = new Metric("clientsNb"); // metrics.add(m); // metricFilter.setMetrics(metrics); // // filters.add(metricFilter); // metricFilter = new MetricFilter(); // metricFilter.setId("SERVICELevel"); // metricFilter.setLevel(ServiceElement.ServiceElementLevel.SERVICE); // metrics = new ArrayList<Metric>(); // metrics.add(new Metric("cpu_usage")); // m = new Metric("clientsNb"); // metrics.add(m); // m = new Metric("costPerHour"); // // metrics.add(m); // // // m = new Metric("costPerClientPerHour"); // metrics.add(m); // metricFilter.setMetrics(metrics); // // filters.add(metricFilter); // return filters; // // } public boolean isHealthy() { URL url = null; HttpURLConnection connection = null; boolean ishealthy = false; try { url = new URL(REST_API_URL + "/" + controlService.getId() + "/healthy"); connection = (HttpURLConnection) url.openConnection(); connection.setRequestMethod("GET"); // connection.setRequestProperty("Content-Type", "application/xml"); // connection.setRequestProperty("Accept", "application/xml"); InputStream errorStream = connection.getErrorStream(); if (errorStream != null) { BufferedReader reader = new BufferedReader(new InputStreamReader(errorStream)); String line; while ((line = reader.readLine()) != null) { Logger.getLogger(MELA_API3.class.getName()).log(Level.SEVERE, line); } } InputStream inputStream = connection.getInputStream(); if (inputStream != null) { BufferedReader reader = new BufferedReader(new InputStreamReader(inputStream)); String line; while ((line = reader.readLine()) != null) { Logger.getLogger(MELA_API3.class.getName()).log(Level.SEVERE, line); if (line.contains("true")) { ishealthy = true; } } } } catch (Exception e) { // Logger.getLogger(MELA_API.class.getName()).log(Level.SEVERE, e.getMessage(), e); Logger.getLogger(MELA_API3.class.getName()).log(Level.WARNING, "Trying to connect to MELA - failing ... . Retrying later"); RuntimeLogger.logger.error("Failing to connect to MELA"); } finally { if (connection != null) { connection.disconnect(); } } return ishealthy; } /** * pulls new monitoring data */ public void refreshMonitoringData() { URL url = null; HttpURLConnection connection = null; try { url = new URL(REST_API_URL + "/" + controlService.getId() + "/monitoringdata/xml"); connection = (HttpURLConnection) url.openConnection(); connection.setRequestMethod("GET"); connection.setRequestProperty("Content-Type", "application/xml"); connection.setRequestProperty("Accept", "application/xml"); InputStream errorStream = connection.getErrorStream(); if (errorStream != null) { BufferedReader reader = new BufferedReader(new InputStreamReader(errorStream)); String line; while ((line = reader.readLine()) != null) { Logger.getLogger(MELA_API3.class.getName()).log(Level.SEVERE, line); } } InputStream inputStream = connection.getInputStream(); JAXBContext jAXBContext = JAXBContext.newInstance(MonitoredElementMonitoringSnapshot.class); MonitoredElementMonitoringSnapshot retrievedData = (MonitoredElementMonitoringSnapshot) jAXBContext.createUnmarshaller().unmarshal(inputStream); if (retrievedData != null) { //P getLatestMonitoringDataLock(); latestMonitoringData = retrievedData; //V releaseLatestMonitoringDataLock(); } } catch (Exception e) { // Logger.getLogger(MELA_API.class.getName()).log(Level.SEVERE, e.getMessage(), e); Logger.getLogger(MELA_API3.class.getName()).log(Level.WARNING, "Trying to connect to MELA - failing ... . Retrying later"); RuntimeLogger.logger.error("Failing to connect to MELA"); } finally { if (connection != null) { connection.disconnect(); } } } //uses a semaphore like mechanism to synchronzie access to the latestMonitoringData to avoid data refresh when data is queried private void getLatestMonitoringDataLock() { while (monitoringDataUsed.get()) { try { Thread.sleep(1000); } catch (InterruptedException ex) { Logger.getLogger(MELA_API3.class.getName()).log(Level.SEVERE, null, ex); } }; monitoringDataUsed.set(true); } private void releaseLatestMonitoringDataLock() { monitoringDataUsed.set(false); } public void removeService(Node cloudService) { controlService = cloudService; MonitoredElement element = new MonitoredElement(); element.setId(cloudService.getId()); element.setLevel(MonitoredElement.MonitoredElementLevel.SERVICE); URL url = null; HttpURLConnection connection = null; boolean notConnected = true; while (notConnected) { try { RuntimeLogger.logger.info("Trying to connect to MELA ..."); url = new URL(REST_API_URL + "/" + controlService.getId()); connection = (HttpURLConnection) url.openConnection(); connection.setDoOutput(true); connection.setInstanceFollowRedirects(false); connection.setRequestMethod("DELETE"); connection.setRequestProperty("Content-Type", "application/xml"); connection.setRequestProperty("Accept", "application/json"); //write message body InputStream errorStream = connection.getErrorStream(); if (errorStream != null) { BufferedReader reader = new BufferedReader(new InputStreamReader(errorStream)); String line; while ((line = reader.readLine()) != null) { Logger.getLogger(MELA_API3.class.getName()).log(Level.SEVERE, line); } } InputStream inputStream = connection.getInputStream(); if (inputStream != null) { BufferedReader reader = new BufferedReader(new InputStreamReader(inputStream)); String line; while ((line = reader.readLine()) != null) { Logger.getLogger(MELA_API3.class.getName()).log(Level.SEVERE, line); } } serviceSet = false; notConnected = false; } catch (Exception e) { //Logger.getLogger(MELA_API.class.getName()).log(Level.WARNING, "Trying to connect to MELA - failing ... . Retrying later"); RuntimeLogger.logger.error("Failing to delete service" + e.getMessage()); try { Thread.sleep(MONITORING_DATA_REFRESH_INTERVAL * 1000); } catch (InterruptedException e1) { // TODO Auto-generated catch block e1.printStackTrace(); } } finally { if (connection != null) { connection.disconnect(); } } } } public void setCurrentCloudService (Node cloudService){ this.controlService=cloudService; } public void submitServiceConfiguration(Node cloudService) { controlService = cloudService; MonitoredElement element = new MonitoredElement(); element.setId(cloudService.getId()); element.setLevel(MonitoredElement.MonitoredElementLevel.SERVICE); MELA_ClientUtils.convertServiceTopology(element, cloudService); URL url = null; HttpURLConnection connection = null; boolean notConnected = true; while (notConnected) { try { RuntimeLogger.logger.info("Trying to connect to MELA ..."); url = new URL(REST_API_URL + "/service"); connection = (HttpURLConnection) url.openConnection(); connection.setDoOutput(true); connection.setInstanceFollowRedirects(false); connection.setRequestMethod("PUT"); connection.setRequestProperty("Content-Type", "application/xml"); connection.setRequestProperty("Accept", "application/json"); //write message body OutputStream os = connection.getOutputStream(); JAXBContext jaxbContext = JAXBContext.newInstance(MonitoredElement.class); jaxbContext.createMarshaller().marshal(element, os); StringWriter stringWriter = new StringWriter(); jaxbContext.createMarshaller().marshal(element, stringWriter); RuntimeLogger.logger.info("Sending to MELAAAA" + stringWriter.toString()); os.flush(); os.close(); InputStream errorStream = connection.getErrorStream(); if (errorStream != null) { BufferedReader reader = new BufferedReader(new InputStreamReader(errorStream)); String line; while ((line = reader.readLine()) != null) { Logger.getLogger(MELA_API3.class.getName()).log(Level.SEVERE, line); } } InputStream inputStream = connection.getInputStream(); if (inputStream != null) { BufferedReader reader = new BufferedReader(new InputStreamReader(inputStream)); String line; while ((line = reader.readLine()) != null) { Logger.getLogger(MELA_API3.class.getName()).log(Level.SEVERE, line); } } serviceSet = true; notConnected = false; } catch (Exception e) { //Logger.getLogger(MELA_API.class.getName()).log(Level.WARNING, "Trying to connect to MELA - failing ... . Retrying later"); RuntimeLogger.logger.error("Failing to connect to MELA" + e.getMessage()); try { Thread.sleep(MONITORING_DATA_REFRESH_INTERVAL * 1000); } catch (InterruptedException e1) { // TODO Auto-generated catch block e1.printStackTrace(); } } finally { if (connection != null) { connection.disconnect(); } } } } public void refreshServiceStructure(Node cloudService) { MonitoredElement element = new MonitoredElement(); element.setId(cloudService.getId()); element.setLevel(MonitoredElement.MonitoredElementLevel.SERVICE); MELA_ClientUtils.convertServiceTopology(element, cloudService); URL url = null; HttpURLConnection connection = null; try { url = new URL(REST_API_URL + "/" + controlService.getId() + "/structure"); connection = (HttpURLConnection) url.openConnection(); connection.setDoOutput(true); connection.setInstanceFollowRedirects(false); connection.setRequestMethod("POST"); connection.setRequestProperty("Content-Type", "application/xml"); connection.setRequestProperty("Accept", "application/json"); //write message body OutputStream os = connection.getOutputStream(); JAXBContext jaxbContext = JAXBContext.newInstance(MonitoredElement.class); jaxbContext.createMarshaller().marshal(element, os); os.flush(); os.close(); StringWriter writer = new StringWriter(); jaxbContext.createMarshaller().marshal(element, writer); Logger.getLogger(MELA_API3.class.getName()).log(Level.INFO, "Sending to MELA new structure " + writer.toString()); InputStream errorStream = connection.getErrorStream(); if (errorStream != null) { BufferedReader reader = new BufferedReader(new InputStreamReader(errorStream)); String line; while ((line = reader.readLine()) != null) { Logger.getLogger(MELA_API3.class.getName()).log(Level.SEVERE, line); } } InputStream inputStream = connection.getInputStream(); if (inputStream != null) { BufferedReader reader = new BufferedReader(new InputStreamReader(inputStream)); String line; while ((line = reader.readLine()) != null) { Logger.getLogger(MELA_API3.class.getName()).log(Level.SEVERE, line); } } } catch (Exception e) { Logger.getLogger(MELA_API3.class.getName()).log(Level.SEVERE, e.getMessage(), e); } finally { if (connection != null) { connection.disconnect(); } } //submitCompositionRules(); serviceSet = true; } public void submitMetricCompositionConfiguration(CompositionRulesConfiguration compositionRulesConfiguration) { URL url = null; HttpURLConnection connection = null; try { url = new URL(REST_API_URL + "/" + controlService.getId() + "/metricscompositionrules"); connection = (HttpURLConnection) url.openConnection(); connection.setDoOutput(true); connection.setInstanceFollowRedirects(false); connection.setRequestMethod("PUT"); connection.setRequestProperty("Content-Type", "application/xml"); connection.setRequestProperty("Accept", "application/json"); //write message body OutputStream os = connection.getOutputStream(); JAXBContext jaxbContext = JAXBContext.newInstance(CompositionRulesConfiguration.class); jaxbContext.createMarshaller().marshal(compositionRulesConfiguration, os); os.flush(); os.close(); InputStream errorStream = connection.getErrorStream(); if (errorStream != null) { BufferedReader reader = new BufferedReader(new InputStreamReader(errorStream)); String line; while ((line = reader.readLine()) != null) { Logger.getLogger(MELA_API3.class.getName()).log(Level.SEVERE, line); } } InputStream inputStream = connection.getInputStream(); if (inputStream != null) { BufferedReader reader = new BufferedReader(new InputStreamReader(inputStream)); String line; while ((line = reader.readLine()) != null) { Logger.getLogger(MELA_API3.class.getName()).log(Level.SEVERE, line); } } } catch (Exception e) { Logger.getLogger(MELA_API3.class.getName()).log(Level.SEVERE, e.getMessage(), e); } finally { if (connection != null) { connection.disconnect(); } } } // public Double getCpuUsage(Node entity) { // Metric metric = new Metric("cpu_usage"); // RuntimeLogger.logger.info("For entity " + entity.getId() + " Cpu usage is " + getMetricValue(metric, entity) + "cpu idle is" + getMetricValue(new Metric("cpu_idle"), entity)); // return getMetricValue(metric, entity); // } // // public Double getMemoryAvailable(Node entity) { // Metric metric = new Metric("mem_free_in_GB"); // return getMetricValue(metric, entity); // } // // public Double getMemorySize(Node entity) { // Metric metric = new Metric("mem_total_in_GB"); // return getMetricValue(metric, entity); // } // // public Double getMemoryUsage(Node entity) { // Metric metric = new Metric("mem_used"); // return getMetricValue(metric, entity); // } // // public Double getDiskSize(Node entity) { // Metric metric = new Metric("disk_total"); // return getMetricValue(metric, entity); // } // // public Double getDiskAvailable(Node entity) { // Metric metric = new Metric("disk_free"); // return getMetricValue(metric, entity); // } // // //TODO: define agg rule in procentaj // public Double getDiskUsage(Node entity) { // // return (getDiskSize(entity) - getDiskAvailable(entity)) / getDiskSize(entity) * 100; // } // // public Double getCPUSpeed(Node entity) { // // Metric metric = new Metric("cpu_speed"); // return getMetricValue(metric, entity); // } // // //TODO: define agg rule in TOTAL // public Double getPkts(Node entity) { // Metric metric = new Metric("pkts_total"); // return getMetricValue(metric, entity); // } // // public Double getPktsIn(Node entity) { // Metric metric = new Metric("pkts_in"); // return getMetricValue(metric, entity); // } // // public Double getPktsOut(Node entity) { // Metric metric = new Metric("pkts_out"); // return getMetricValue(metric, entity); // } // // public Double getReadLatency(Node entity) { // Metric metric = new Metric("read_latency"); // return getMetricValue(metric, entity); // } // // public Double getWriteLatency(Node entity) { // Metric metric = new Metric("write_latency"); // return getMetricValue(metric, entity); // } // // public Double getReadCount(Node entity) { // Metric metric = new Metric("read_count"); // return getMetricValue(metric, entity); // } // // public Double getCostPerHour(Node entity) { // Metric metric = new Metric("costPerHour"); // return getMetricValue(metric, entity); // } // // public Double getWriteCount(Node entity) { // Metric metric = new Metric("write_count"); // return getMetricValue(metric, entity); // } // // //TODO: can;t be done currentlu // public Double getTotalCostSoFar(Node entity) { // Metric metric = new Metric("costPerHour"); // return getMetricValue(metric, entity); // } // // /** // * @return currently, all metrics for the first VM that is monitored. While // * MELA can return metrics for different VMs belonging to different service // * units, it would require a Service_unit_id to be added as parameter to // * this call // */ // public List<String> getAvailableMetrics() { // ServiceMonitoringSnapshot monitoringSnapshot = systemControl.getRawMonitoringData(); // Map<ServiceElement, ServiceElementMonitoringSnapshot> monitoringData = monitoringSnapshot.getMonitoredData(ServiceElement.ServiceElementLevel.VM); // // Collection<Metric> metrics = monitoringData.values().iterator().next().getMonitoredData().keySet(); // List<String> strings = new ArrayList<String>(); // for (Metric metric : metrics) { // strings.add(metric.getName()); // } // return strings; // } // // //should at least have an action name in name public void notifyControlActionStarted(String actionName, Node actionTargetEntity) { URL url = null; HttpURLConnection connection = null; try { this.ongoingAction.add(actionName); this.actionTargetEntity.add(actionTargetEntity.getId()); url = new URL(REST_API_URL + "/" + controlService.getId() + "/" + actionTargetEntity.getId() + "/executingaction/" + actionName); connection = (HttpURLConnection) url.openConnection(); connection.setDoOutput(true); connection.setInstanceFollowRedirects(false); connection.setRequestMethod("PUT"); connection.setRequestProperty("Content-Type", "application/xml"); connection.setRequestProperty("Accept", "application/xml"); InputStream errorStream = connection.getErrorStream(); if (errorStream != null) { BufferedReader reader = new BufferedReader(new InputStreamReader(errorStream)); String line; while ((line = reader.readLine()) != null) { Logger.getLogger(MELA_API3.class.getName()).log(Level.SEVERE, line); } } InputStream inputStream = connection.getInputStream(); if (inputStream != null) { BufferedReader reader = new BufferedReader(new InputStreamReader(inputStream)); String line; while ((line = reader.readLine()) != null) { Logger.getLogger(MELA_API3.class.getName()).log(Level.SEVERE, line); } } } catch (Exception e) { Logger.getLogger(MELA_API3.class.getName()).log(Level.SEVERE, e.getMessage(), e); } finally { if (connection != null) { connection.disconnect(); } } } public void notifyControlActionEnded(String actionName, Node actionTargetEntity) { URL url = null; HttpURLConnection connection = null; try { url = new URL(REST_API_URL + "/" + controlService.getId() + "/" + actionTargetEntity.getId() + "/executingaction/" + actionName); connection = (HttpURLConnection) url.openConnection(); connection.setInstanceFollowRedirects(false); connection.setRequestMethod("DELETE"); connection.setRequestProperty("Content-Type", "application/xml"); connection.setRequestProperty("Accept", "application/xml"); InputStream errorStream = connection.getErrorStream(); if (errorStream != null) { BufferedReader reader = new BufferedReader(new InputStreamReader(errorStream)); String line; while ((line = reader.readLine()) != null) { Logger.getLogger(MELA_API3.class.getName()).log(Level.SEVERE, line); } } InputStream inputStream = connection.getInputStream(); if (inputStream != null) { BufferedReader reader = new BufferedReader(new InputStreamReader(inputStream)); String line; while ((line = reader.readLine()) != null) { Logger.getLogger(MELA_API3.class.getName()).log(Level.SEVERE, line); } } } catch (Exception e) { Logger.getLogger(MELA_API3.class.getName()).log(Level.SEVERE, e.getMessage(), e); } finally { this.ongoingAction.remove(actionName); actionName = ""; this.actionTargetEntity.remove(actionTargetEntity.getId()); if (connection != null) { connection.disconnect(); } } } public Double getMetricValue(Metric metric, Node entity) { if (entity.getId() == null) { Logger.getLogger(this.getClass().getName()).log(Level.WARNING, "Supplied entity has no ID. Can't get metric value"); return -1.0; } //get the Entity level so I can search it in the monitored snapshot easily (only in entity and its children) MonitoredElement.MonitoredElementLevel level = MELA_ClientUtils.getElementLevelFromEntity(entity); MonitoredElement element = new MonitoredElement(); element.setId(entity.getId()); element.setLevel(level); //search in the aggregated data over time for the target entity MonitoredElement elementSearchingFor = new MonitoredElement(entity.getId()); List<MonitoredElementMonitoringSnapshot> processing = new ArrayList<MonitoredElementMonitoringSnapshot>(); processing.add(latestMonitoringData); while (!processing.isEmpty()) { MonitoredElementMonitoringSnapshot currentlyUnderInspection = processing.remove(0); if (currentlyUnderInspection.getMonitoredElement().equals(elementSearchingFor)) { if (currentlyUnderInspection.containsMetric(metric)) { MetricValue value = currentlyUnderInspection.getMetricValue(metric); switch (value.getValueType()) { case NUMERIC: return Double.parseDouble(value.getValueRepresentation()); default: Logger.getLogger(this.getClass().getName()).log(Level.WARNING, "Value ''{0}''for metric {1} for Node {2} is not Numeric", new Object[]{value.getValueRepresentation(), metric.toString(), entity.getId()}); return -1.0; } } } else { processing.addAll(currentlyUnderInspection.getChildren()); } } //if we have reached this point, either the monitored element was not found, either the metric RuntimeLogger.logger.info("Metric " + metric.toString() + " OR Node " + entity.getId() + " not found"); return -1.0; } @Override public List<MonitoringSnapshot> getAllMonitoringInformation() { List<MonitoringSnapshot> snapshots = new ArrayList<>(); URL url = null; HttpURLConnection connection = null; while (snapshots.size()==0){ try { url = new URL(REST_API_URL + "/" + controlService.getId() + "/historicalmonitoringdata/all/xml"); connection = (HttpURLConnection) url.openConnection(); connection.setRequestMethod("GET"); connection.setRequestProperty("Content-Type", "application/xml"); connection.setRequestProperty("Accept", "application/xml"); InputStream errorStream = connection.getErrorStream(); if (errorStream != null) { BufferedReader reader = new BufferedReader(new InputStreamReader(errorStream)); String line; while ((line = reader.readLine()) != null) { Logger.getLogger(MELA_API3.class.getName()).log(Level.SEVERE, line); } } InputStream inputStream = connection.getInputStream(); JAXBContext jAXBContext = JAXBContext.newInstance(MonitoredElementMonitoringSnapshots.class); MonitoredElementMonitoringSnapshots retrievedData = (MonitoredElementMonitoringSnapshots) jAXBContext.createUnmarshaller().unmarshal(inputStream); if (retrievedData != null) { //P //getLatestMonitoringDataLock(); snapshots= recursivelyProcessMonitoringSnapshots(retrievedData); //V //releaseLatestMonitoringDataLock(); } } catch (Exception e) { // Logger.getLogger(MELA_API.class.getName()).log(Level.SEVERE, e.getMessage(), e); Logger.getLogger(MELA_API3.class.getName()).log(Level.WARNING, "Trying to connect to MELA - failing ... . Retrying later"); RuntimeLogger.logger.error("Failing to connect to MELA"); } finally { if (connection != null) { connection.disconnect(); } } } return snapshots; //throw new UnsupportedOperationException("Not supported yet."); } private List<MonitoringSnapshot> recursivelyProcessMonitoringSnapshots(MonitoredElementMonitoringSnapshots retrievedData) { List<MonitoringSnapshot> monitoringSnapshots = new ArrayList<>(); for (MonitoredElementMonitoringSnapshot elementMonitoringSnapshot : retrievedData.getChildren()) { List<MonitoredElementMonitoringSnapshot> processing = new ArrayList<MonitoredElementMonitoringSnapshot>(); MonitoringSnapshot monitoringSnapshot = new MonitoringSnapshot(); HashMap<String, ServicePartMonitor> monitors = new HashMap<>(); processing.add(elementMonitoringSnapshot); monitoringSnapshot.setTimestamp(Long.parseLong(elementMonitoringSnapshot.getTimestamp())); for (Action action:elementMonitoringSnapshot.getExecutingActions()){ monitoringSnapshot.addOngoingActions(action.getTargetEntityID(), action.getAction()); } while (!processing.isEmpty() && processing != null) { MonitoredElementMonitoringSnapshot currentlyUnderInspection = processing.remove(0); ServicePartMonitor monitor = new ServicePartMonitor(); monitor.setServicePart(currentlyUnderInspection.getMonitoredElement().getId()); HashMap<String, Double> metrics = new HashMap<>(); for (Entry<Metric, MetricValue> m : currentlyUnderInspection.getMonitoredData().entrySet()) { MetricValue value = currentlyUnderInspection.getMetricValue(m.getKey()); switch (value.getValueType()) { case NUMERIC: metrics.put(m.getKey().getName(), Double.parseDouble(m.getValue().getValueRepresentation())); break; default: //Logger.getLogger(this.getClass().getName()).log(Level.WARNING, "Value ''{0}''for metric {1} for Node {2} is not Numeric", new Object[]{value.getValueRepresentation(), m.getKey().getName().toString(), monitor.getServicePart()}); //; break; } } monitor.setMetrics(metrics); monitors.put(monitor.getServicePart(), monitor); monitoringSnapshot.addServicePart(monitor.getServicePart(),monitor); processing.addAll(currentlyUnderInspection.getChildren()); } monitoringSnapshots.add(monitoringSnapshot); } return monitoringSnapshots; } @Override public List<MonitoringSnapshot> getAllMonitoringInformationFromTimestamp( long timestamp) { List<MonitoringSnapshot> snapshots = new ArrayList<>(); URL url = null; HttpURLConnection connection = null; try { url = new URL(REST_API_URL + "/" + controlService.getId() + "/historicalmonitoringdata/fromtimestamp/xml?timestamp="+timestamp); connection = (HttpURLConnection) url.openConnection(); connection.setRequestMethod("GET"); connection.setRequestProperty("Content-Type", "application/xml"); connection.setRequestProperty("Accept", "application/xml"); InputStream errorStream = connection.getErrorStream(); if (errorStream != null) { BufferedReader reader = new BufferedReader(new InputStreamReader(errorStream)); String line; while ((line = reader.readLine()) != null) { Logger.getLogger(MELA_API3.class.getName()).log(Level.SEVERE, line); } } InputStream inputStream = connection.getInputStream(); JAXBContext jAXBContext = JAXBContext.newInstance(MonitoredElementMonitoringSnapshots.class); MonitoredElementMonitoringSnapshots retrievedData = (MonitoredElementMonitoringSnapshots) jAXBContext.createUnmarshaller().unmarshal(inputStream); if (retrievedData != null) { //P //getLatestMonitoringDataLock(); snapshots= recursivelyProcessMonitoringSnapshots(retrievedData); //V //releaseLatestMonitoringDataLock(); } } catch (Exception e) { // Logger.getLogger(MELA_API.class.getName()).log(Level.SEVERE, e.getMessage(), e); Logger.getLogger(MELA_API3.class.getName()).log(Level.WARNING, "Trying to connect to MELA - failing ... . Retrying later"); RuntimeLogger.logger.error("Failing to connect to MELA"); return snapshots; } finally { if (connection != null) { connection.disconnect(); } } return snapshots; } @Override public List<MonitoringSnapshot> getAllMonitoringInformationOnPeriod( long time) { List<MonitoringSnapshot> snapshots = new ArrayList<>(); URL url = null; HttpURLConnection connection = null; try { url = new URL(REST_API_URL + "/" + controlService.getId() + "/historicalmonitoringdata/lastX/xml?count="+time); connection = (HttpURLConnection) url.openConnection(); connection.setRequestMethod("GET"); connection.setRequestProperty("Content-Type", "application/xml"); connection.setRequestProperty("Accept", "application/xml"); InputStream errorStream = connection.getErrorStream(); if (errorStream != null) { BufferedReader reader = new BufferedReader(new InputStreamReader(errorStream)); String line; while ((line = reader.readLine()) != null) { Logger.getLogger(MELA_API3.class.getName()).log(Level.SEVERE, line); } } InputStream inputStream = connection.getInputStream(); JAXBContext jAXBContext = JAXBContext.newInstance(MonitoredElementMonitoringSnapshots.class); MonitoredElementMonitoringSnapshots retrievedData = (MonitoredElementMonitoringSnapshots) jAXBContext.createUnmarshaller().unmarshal(inputStream); if (retrievedData != null) { //P //getLatestMonitoringDataLock(); snapshots= recursivelyProcessMonitoringSnapshots(retrievedData); //V //releaseLatestMonitoringDataLock(); } } catch (Exception e) { // Logger.getLogger(MELA_API.class.getName()).log(Level.SEVERE, e.getMessage(), e); Logger.getLogger(MELA_API3.class.getName()).log(Level.WARNING, "Trying to connect to MELA - failing ... . Retrying later"); RuntimeLogger.logger.error("Failing to connect to MELA"); return snapshots; } finally { if (connection != null) { connection.disconnect(); } } return snapshots; } private static class MELA_ClientUtils { //works as side effect public static void convertServiceTopology(MonitoredElement serviceElement, Node cloudService) { //RuntimeLogger.logger.info("Related nodes for node "+ cloudService +" are "+ cloudService.getAllRelatedNodesOfType(RelationshipType.COMPOSITION_RELATIONSHIP)); List<Node> serviceTopologies = new ArrayList<Node>(); MonitoredElement mainServiceTopologyElement = null; if (cloudService.getAllRelatedNodesOfType(RelationshipType.COMPOSITION_RELATIONSHIP, NodeType.SERVICE_TOPOLOGY).size() == 1) { mainServiceTopologyElement = new MonitoredElement(); mainServiceTopologyElement = new MonitoredElement(); Node serviceTopology = cloudService.getAllRelatedNodesOfType(RelationshipType.COMPOSITION_RELATIONSHIP, NodeType.SERVICE_TOPOLOGY).get(0); mainServiceTopologyElement.setId(serviceTopology.getId()); mainServiceTopologyElement.setLevel(MonitoredElement.MonitoredElementLevel.SERVICE_TOPOLOGY); if ((serviceTopology.getAllRelatedNodesOfType(RelationshipType.COMPOSITION_RELATIONSHIP).size() > 0) && (serviceTopology.getAllRelatedNodesOfType(RelationshipType.COMPOSITION_RELATIONSHIP).get(0).getNodeType() == NodeType.SERVICE_TOPOLOGY)) { serviceTopologies.addAll(serviceTopology.getAllRelatedNodesOfType(RelationshipType.COMPOSITION_RELATIONSHIP)); } else { serviceTopologies.add(serviceTopology); mainServiceTopologyElement = null; } } else { serviceTopologies.addAll(cloudService.getAllRelatedNodesOfType(RelationshipType.COMPOSITION_RELATIONSHIP)); } while (!serviceTopologies.isEmpty()) { MonitoredElement serviceTopologyElement = new MonitoredElement(); Node serviceTopology = serviceTopologies.get(0); serviceTopologyElement.setId(serviceTopology.getId()); if (serviceTopology.getNodeType() == NodeType.SERVICE_TOPOLOGY) { serviceTopologyElement.setLevel(MonitoredElement.MonitoredElementLevel.SERVICE_TOPOLOGY); } else { serviceTopologyElement.setLevel(MonitoredElement.MonitoredElementLevel.SERVICE_UNIT); } if (serviceTopology.getAllRelatedNodesOfType(RelationshipType.COMPOSITION_RELATIONSHIP) != null) { for (Node serviceUnit : serviceTopology.getAllRelatedNodesOfType(RelationshipType.COMPOSITION_RELATIONSHIP)) { if (serviceUnit.getNodeType() == NodeType.SERVICE_UNIT) { MonitoredElement serviceUnitElement = new MonitoredElement(); serviceUnitElement.setId(serviceUnit.getId()); serviceUnitElement.setLevel(MonitoredElement.MonitoredElementLevel.SERVICE_UNIT); Node artifact = null; Node container = null; Node accessToVM = serviceUnit; if (serviceUnit.getAllRelatedNodesOfType(RelationshipType.HOSTED_ON_RELATIONSHIP, NodeType.ARTIFACT) != null && serviceUnit.getAllRelatedNodesOfType(RelationshipType.HOSTED_ON_RELATIONSHIP, NodeType.ARTIFACT).size() > 0) { artifact = serviceUnit.getAllRelatedNodesOfType(RelationshipType.HOSTED_ON_RELATIONSHIP, NodeType.ARTIFACT).get(0); if (artifact.getAllRelatedNodesOfType(RelationshipType.HOSTED_ON_RELATIONSHIP, NodeType.CONTAINER) != null && artifact.getAllRelatedNodesOfType(RelationshipType.HOSTED_ON_RELATIONSHIP, NodeType.CONTAINER).size() > 0) { container = artifact.getAllRelatedNodesOfType(RelationshipType.HOSTED_ON_RELATIONSHIP, NodeType.CONTAINER).get(0); } } if (artifact != null || container != null) { if (container == null) { accessToVM = artifact; } else { accessToVM = container; } } for (Node vm : accessToVM.getAllRelatedNodesOfType(RelationshipType.HOSTED_ON_RELATIONSHIP, NodeType.VIRTUAL_MACHINE)) { // RuntimeLogger.logger.info("Translating hosted on "+vm.getId()+" for node "+serviceUnitElement.getId()); MonitoredElement virtualMachine = new MonitoredElement(); virtualMachine.setId(vm.getId()); virtualMachine.setLevel(MonitoredElement.MonitoredElementLevel.VM); serviceUnitElement.addElement(virtualMachine); } for (Node vm : accessToVM.getAllRelatedNodesOfType(RelationshipType.ASSOCIATED_AT_RUNTIME_RELATIONSHIP, NodeType.VIRTUAL_MACHINE)) { MonitoredElement virtualMachine = new MonitoredElement(); virtualMachine.setId(vm.getId()); boolean alreadyContained = false; virtualMachine.setLevel(MonitoredElement.MonitoredElementLevel.VM); for (MonitoredElement el : serviceUnitElement.getContainedElements()) { if (el.getId().equalsIgnoreCase(vm.getId())) { alreadyContained = true; } } if (!alreadyContained) { serviceUnitElement.addElement(virtualMachine); } } serviceTopologyElement.addElement(serviceUnitElement); } if (serviceUnit.getNodeType() == NodeType.SERVICE_TOPOLOGY) { MonitoredElement serviceUnitElement = new MonitoredElement(); serviceTopologyElement.setId(serviceUnit.getId()); serviceTopologyElement.setLevel(MonitoredElement.MonitoredElementLevel.SERVICE_TOPOLOGY); serviceTopologyElement.addElement(serviceUnitElement); } } } if (mainServiceTopologyElement != null) { mainServiceTopologyElement.addElement(serviceTopologyElement); } else { serviceElement.addElement(serviceTopologyElement); } if (serviceTopology.getAllRelatedNodesOfType(RelationshipType.COMPOSITION_RELATIONSHIP) != null) { for (Node subTopology : serviceTopology.getAllRelatedNodesOfType(RelationshipType.COMPOSITION_RELATIONSHIP)) { if (subTopology.getNodeType() == NodeType.SERVICE_TOPOLOGY) { serviceTopologies.add(subTopology); } } } serviceTopologies.remove(0); } if (mainServiceTopologyElement != null) { serviceElement.addElement(mainServiceTopologyElement); } } public static MonitoredElement.MonitoredElementLevel getElementLevelFromEntity(Node entity) { if (entity.getNodeType() == NodeType.CLOUD_SERVICE) { return MonitoredElement.MonitoredElementLevel.SERVICE; } else if (entity.getNodeType() == NodeType.SERVICE_TOPOLOGY) { return MonitoredElement.MonitoredElementLevel.SERVICE_TOPOLOGY; } else if (entity.getNodeType() == NodeType.SERVICE_UNIT) { return MonitoredElement.MonitoredElementLevel.SERVICE_UNIT; } else { Logger.getLogger(MELA_API3.class.getName()).log(Level.SEVERE, "Error. Cannot determine the source class of entity " + entity); return null; } } } public static void main(String[] args) throws Exception { } @Override public void submitElasticityRequirements( ArrayList<ElasticityRequirement> description) { Requirements requirements = new Requirements(); ArrayList<Requirement> requirements2 = new ArrayList<Requirement>(); for (ElasticityRequirement elasticityRequirement : description) { // RuntimeLogger.logger.info("Setting elasticity requirement " + elasticityRequirement.getAnnotation().getConstraints()); SYBLSpecification specification = SYBLDirectiveMappingFromXML.mapFromSYBLAnnotation(elasticityRequirement.getAnnotation()); // !!!Set all info for (Constraint constraint : specification.getConstraint()) { RuntimeLogger.logger.info("Transformed constraint " + elasticityRequirement.getAnnotation().getConstraints()); for (BinaryRestrictionsConjunction binaryRestrictions : constraint.getToEnforce().getBinaryRestriction()) { for (BinaryRestriction binaryRestriction : binaryRestrictions.getBinaryRestrictions()) { Requirement req = new Requirement(); req.setId(specification.getComponentId()); ArrayList<String> targetedEls = new ArrayList<String>(); targetedEls.add(specification.getComponentId()); req.setTargetMonitoredElementIDs(targetedEls); List<at.ac.tuwien.dsg.mela.common.requirements.Condition> conditions = new ArrayList<at.ac.tuwien.dsg.mela.common.requirements.Condition>(); at.ac.tuwien.dsg.mela.common.requirements.Condition cond = new at.ac.tuwien.dsg.mela.common.requirements.Condition(); DependencyGraph dep = new DependencyGraph(); dep.setCloudService(controlService); req.setTargetMonitoredElementLevel(MELA_ClientUtils.getElementLevelFromEntity(dep.getNodeWithID(specification.getComponentId()))); if (binaryRestriction.getLeftHandSide().getMetric() != null) { String metric = binaryRestriction.getLeftHandSide().getMetric(); Metric m = new Metric(); m.setName(metric); m.setMeasurementUnit(null); req.setMetric(m); MetricValue metricValue = new MetricValue(); metricValue.setValue(Double.parseDouble(binaryRestriction.getRightHandSide().getNumber())); cond.addValue(metricValue); switch (binaryRestriction.getType()) { case "lessThan": cond.setType(Type.LESS_THAN); break; case "greaterThan": cond.setType(Type.GREATER_THAN); break; case "lessThanOrEqual": cond.setType(Type.LESS_EQUAL); break; case "greaterThanOrEqual": cond.setType(Type.GREATER_EQUAL); break; case "differentThan": //cond.setType(Type.) break; case "equals": cond.setType(Type.EQUAL); break; default: cond.setType(Type.LESS_THAN); break; } } else { if (binaryRestriction.getRightHandSide().getMetric() != null) { String metric = binaryRestriction.getRightHandSide().getMetric(); Metric m = new Metric(); m.setName(metric); m.setMeasurementUnit(null); req.setMetric(m); switch (binaryRestriction.getType()) { case "lessThan": cond.setType(Type.GREATER_THAN); break; case "greaterThan": cond.setType(Type.LESS_THAN); break; case "lessThanOrEqual": cond.setType(Type.GREATER_EQUAL); break; case "greaterThanOrEqual": cond.setType(Type.LESS_EQUAL); break; case "differentThan": //cond.setType(Type.) break; case "equals": cond.setType(Type.EQUAL); break; default: cond.setType(Type.LESS_THAN); break; } MetricValue metricValue = new MetricValue(); metricValue.setValue(Double.parseDouble(binaryRestriction.getRightHandSide().getNumber())); cond.addValue(metricValue); } } conditions.add(cond); req.setConditions(conditions); RuntimeLogger.logger.info("Requirements for MELA" + req.toString()); requirements2.add(req); } } } } requirements.setRequirements(requirements2); requirements.setTargetServiceID(controlService.getId()); URL url = null; HttpURLConnection connection = null; try { url = new URL(REST_API_URL + "/" + controlService.getId() + "/requirements"); connection = (HttpURLConnection) url.openConnection(); connection.setDoOutput(true); connection.setInstanceFollowRedirects(false); connection.setRequestMethod("PUT"); connection.setRequestProperty("Content-Type", "application/xml"); connection.setRequestProperty("Accept", "application/json"); //write message body OutputStream os = connection.getOutputStream(); JAXBContext jaxbContext = JAXBContext.newInstance(Requirements.class); jaxbContext.createMarshaller().marshal(requirements, os); os.flush(); os.close(); InputStream errorStream = connection.getErrorStream(); if (errorStream != null) { BufferedReader reader = new BufferedReader(new InputStreamReader(errorStream)); String line; while ((line = reader.readLine()) != null) { Logger.getLogger(MELA_API3.class.getName()).log(Level.SEVERE, line); } } InputStream inputStream = connection.getInputStream(); if (inputStream != null) { BufferedReader reader = new BufferedReader(new InputStreamReader(inputStream)); String line; while ((line = reader.readLine()) != null) { Logger.getLogger(MELA_API3.class.getName()).log(Level.SEVERE, line); } } } catch (Exception e) { Logger.getLogger(MELA_API3.class.getName()).log(Level.SEVERE, e.getMessage(), e); } finally { if (connection != null) { connection.disconnect(); } } } @Override public Double getNumberInstances(Node entity) { Metric metric = new Metric("vmCount"); return getMetricValue(metric, entity); } public Double getCpuUsage(Node entity) { Metric metric = new Metric("cpu_usage"); RuntimeLogger.logger.info("For entity " + entity.getId() + " Cpu usage is " + getMetricValue(metric, entity) + "cpu idle is" + getMetricValue(new Metric("cpu_idle"), entity)); return getMetricValue(metric, entity); } public Double getMemoryAvailable(Node entity) { Metric metric = new Metric("mem_free_in_GB"); return getMetricValue(metric, entity); } public Double getMemorySize(Node entity) { Metric metric = new Metric("mem_total_in_GB"); return getMetricValue(metric, entity); } public Double getMemoryUsage(Node entity) { Metric metric = new Metric("mem_used"); return getMetricValue(metric, entity); } public Double getDiskSize(Node entity) { Metric metric = new Metric("disk_total"); return getMetricValue(metric, entity); } public Double getDiskAvailable(Node entity) { Metric metric = new Metric("disk_free"); return getMetricValue(metric, entity); } //TODO: define agg rule in procentaj public Double getDiskUsage(Node entity) { return (getDiskSize(entity) - getDiskAvailable(entity)) / getDiskSize(entity) * 100; } public Double getCPUSpeed(Node entity) { Metric metric = new Metric("cpu_speed"); return getMetricValue(metric, entity); } //TODO: define agg rule in TOTAL public Double getPkts(Node entity) { Metric metric = new Metric("pkts_total"); return getMetricValue(metric, entity); } public Double getPktsIn(Node entity) { Metric metric = new Metric("pkts_in"); return getMetricValue(metric, entity); } public Double getPktsOut(Node entity) { Metric metric = new Metric("pkts_out"); return getMetricValue(metric, entity); } public Double getReadLatency(Node entity) { Metric metric = new Metric("read_latency"); return getMetricValue(metric, entity); } public Double getWriteLatency(Node entity) { Metric metric = new Metric("write_latency"); return getMetricValue(metric, entity); } public Double getReadCount(Node entity) { Metric metric = new Metric("read_count"); return getMetricValue(metric, entity); } public Double getCostPerHour(Node entity) { Metric metric = new Metric("costPerHour"); return getMetricValue(metric, entity); } public Double getWriteCount(Node entity) { Metric metric = new Metric("write_count"); return getMetricValue(metric, entity); } //TODO: can;t be done currentlu public Double getTotalCostSoFar(Node entity) { Metric metric = new Metric("costPerHour"); return getMetricValue(metric, entity); } /** * @return currently, all metrics for the first VM that is monitored. While * MELA can return metrics for different VMs belonging to different service * units, it would require a Service_unit_id to be added as parameter to * this call */ public List<String> getAvailableMetrics(Node node) { refreshMonitoringData(); List<MonitoredElementMonitoringSnapshot> processing = new ArrayList<MonitoredElementMonitoringSnapshot>(); List<String> metrics = new ArrayList<String>(); processing.add(latestMonitoringData); while (!processing.isEmpty() && processing != null) { MonitoredElementMonitoringSnapshot currentlyUnderInspection = processing.remove(0); if (currentlyUnderInspection.getMonitoredElement().getId().equalsIgnoreCase(node.getId())) { for (Metric m : currentlyUnderInspection.getMetrics()) { metrics.add(m.getName()); } } else { processing.addAll(currentlyUnderInspection.getChildren()); } } return metrics; } public List<String> getAvailableMetrics(String id) { refreshMonitoringData(); List<MonitoredElementMonitoringSnapshot> processing = new ArrayList<MonitoredElementMonitoringSnapshot>(); List<String> metrics = new ArrayList<String>(); processing.add(latestMonitoringData); while (!processing.isEmpty() && processing != null) { MonitoredElementMonitoringSnapshot currentlyUnderInspection = processing.remove(0); if (currentlyUnderInspection.getMonitoredElement().getId().equals(id)) { for (Metric m : currentlyUnderInspection.getMetrics()) { metrics.add(m.getName()); } } else { processing.addAll(currentlyUnderInspection.getChildren()); } } return metrics; } public void submitCompositionRules() { try { Unmarshaller unmarshaller = JAXBContext.newInstance(CompositionRulesConfiguration.class).createUnmarshaller(); CompositionRulesConfiguration compositionRulesConfiguration = (CompositionRulesConfiguration) unmarshaller.unmarshal(this.getClass().getClassLoader().getResourceAsStream(Configuration.getCompositionRulesPath())); submitMetricCompositionConfiguration(compositionRulesConfiguration); } catch (Exception e) { Unmarshaller unmarshaller; try { unmarshaller = JAXBContext.newInstance(CompositionRulesConfiguration.class).createUnmarshaller(); CompositionRulesConfiguration compositionRulesConfiguration = (CompositionRulesConfiguration) unmarshaller.unmarshal(new FileReader(new File(Configuration.getCompositionRulesPath()))); submitMetricCompositionConfiguration(compositionRulesConfiguration); } catch (JAXBException e1) { // TODO Auto-generated catch block e1.printStackTrace(); RuntimeLogger.logger.error("Submitting file composition rules. Error when submitting composition rules, in MELA_API" + e.getMessage()); } catch (FileNotFoundException e1) { // TODO Auto-generated catch block e1.printStackTrace(); } } } public void submitCompositionRules(String compositionRules) { try { RuntimeLogger.logger.info("In MELA_API: setting composition rules = " + compositionRules); Unmarshaller unmarshaller = JAXBContext.newInstance(CompositionRulesConfiguration.class).createUnmarshaller(); StringReader reader = new StringReader(compositionRules); CompositionRulesConfiguration compositionRulesConfiguration = (CompositionRulesConfiguration) unmarshaller.unmarshal(reader); submitMetricCompositionConfiguration(compositionRulesConfiguration); } catch (Exception e) { e.printStackTrace(); RuntimeLogger.logger.error("Error when submitting composition rules, in MELA_API " + e.getMessage()); } } public Double getMetricValue(String metricName, Node entity) { Metric metric = new Metric(metricName); return getMetricValue(metric, entity); } public boolean checkIfMetricsValid(Node node) { boolean validity = true; for (String metric : getAvailableMetrics(node)) { if (getMetricValue(metric, node) < 0) { validity = false; } } return validity; } @Override public List<String> getOngoingActionID() { return this.ongoingAction; } @Override public List<String> getOngoingActionNodeID() { return this.actionTargetEntity; } @Override public void sendMessageToAnalysisService(String message) { URL url = null; HttpURLConnection connection = null; boolean notConnected = true; while (notConnected) { try { RuntimeLogger.logger.info("Trying to connect to MELA ..."); url = new URL(REST_API_URL + "/" + controlService.getId() + "/events"); connection = (HttpURLConnection) url.openConnection(); connection.setDoOutput(true); connection.setInstanceFollowRedirects(false); connection.setRequestMethod("POST"); connection.setRequestProperty("Content-Type", "text/plain"); //write message body OutputStream os = connection.getOutputStream(); //JAXBContext jaxbContext = JAXBContext.newInstance(MonitoredElement.class); //jaxbContext.createMarshaller().marshal(message, os); os.write(message.getBytes()); os.flush(); os.close(); InputStream errorStream = connection.getErrorStream(); if (errorStream != null) { BufferedReader reader = new BufferedReader(new InputStreamReader(errorStream)); String line; while ((line = reader.readLine()) != null) { Logger.getLogger(MELA_API.class.getName()).log(Level.SEVERE, line); } } InputStream inputStream = connection.getInputStream(); if (inputStream != null) { BufferedReader reader = new BufferedReader(new InputStreamReader(inputStream)); String line; while ((line = reader.readLine()) != null) { Logger.getLogger(MELA_API.class.getName()).log(Level.SEVERE, line); } } serviceSet = true; notConnected = false; } catch (Exception e) { //Logger.getLogger(MELA_API.class.getName()).log(Level.WARNING, "Trying to connect to MELA - failing ... . Retrying later"); RuntimeLogger.logger.error("Failing to connect to MELA" + e.getMessage()); try { Thread.sleep(MONITORING_DATA_REFRESH_INTERVAL * 1000); } catch (InterruptedException e1) { // TODO Auto-generated catch block e1.printStackTrace(); } } finally { if (connection != null) { connection.disconnect(); } } } } @Override public void sendControlIncapacityMessage(String message, List<ElasticityRequirement> cause) { URL url = null; HttpURLConnection connection = null; boolean notConnected = true; while (notConnected) { try { RuntimeLogger.logger.info("Sending control incapacity message to MELA ..."); url = new URL(REST_API_URL + "/" + controlService.getId() + "/events"); connection = (HttpURLConnection) url.openConnection(); connection.setDoOutput(true); connection.setInstanceFollowRedirects(false); connection.setRequestMethod("POST"); connection.setRequestProperty("Content-Type", "text/plain"); connection.setRequestProperty("Accept", "text/plain"); //write message body OutputStream os = connection.getOutputStream(); //JAXBContext jaxbContext = JAXBContext.newInstance(MonitoredElement.class); //jaxbContext.createMarshaller().marshal(message, os); String myCause = ""; for (ElasticityRequirement req : cause) { myCause += req.getAnnotation().getConstraints() + "; "; } os.write((message + "Cause : " + myCause).getBytes()); os.flush(); os.close(); InputStream errorStream = connection.getErrorStream(); if (errorStream != null) { BufferedReader reader = new BufferedReader(new InputStreamReader(errorStream)); String line; while ((line = reader.readLine()) != null) { Logger.getLogger(MELA_API.class.getName()).log(Level.SEVERE, line); } } InputStream inputStream = connection.getInputStream(); if (inputStream != null) { BufferedReader reader = new BufferedReader(new InputStreamReader(inputStream)); String line; while ((line = reader.readLine()) != null) { Logger.getLogger(MELA_API.class.getName()).log(Level.SEVERE, line); } } serviceSet = true; notConnected = false; } catch (Exception e) { //Logger.getLogger(MELA_API.class.getName()).log(Level.WARNING, "Trying to connect to MELA - failing ... . Retrying later"); RuntimeLogger.logger.error("Failing to connect to MELA" + e.getMessage()); try { Thread.sleep(MONITORING_DATA_REFRESH_INTERVAL * 1000); } catch (InterruptedException e1) { // TODO Auto-generated catch block e1.printStackTrace(); } } finally { if (connection != null) { connection.disconnect(); } } } } }