Java tutorial
///////////////////////////////////////////////////////////////////////// // // University of Southampton IT Innovation Centre, 2013 // // Copyright in this library belongs to the University of Southampton // IT Innovation Centre of Gamma House, Enterprise Road, // Chilworth Science Park, Southampton, SO16 7NS, UK. // // This software may not be used, sold, licensed, transferred, copied // or reproduced in whole or in part in any manner or form or in or // on any media by any person other than in accordance with the terms // of the Licence Agreement supplied with the software, or otherwise // without the prior written consent of the copyright owners. // // This software is distributed WITHOUT ANY WARRANTY, without even the // implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR // PURPOSE, except where stated in the Licence Agreement supplied with // the software. // // Created By : Maxim Bashevoy // Created Date : 2013-03-21 // Created for Project : Experimedia // ///////////////////////////////////////////////////////////////////////// package uk.ac.soton.itinnovation.sad.service.adapters; import net.sf.json.JSONObject; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Qualifier; import org.springframework.stereotype.Service; import uk.ac.soton.itinnovation.experimedia.arch.ecc.amqpAPI.impl.amqp.AMQPBasicChannel; import uk.ac.soton.itinnovation.experimedia.arch.ecc.amqpAPI.impl.amqp.AMQPConnectionFactory; import uk.ac.soton.itinnovation.experimedia.arch.ecc.common.dataModel.experiment.Experiment; import uk.ac.soton.itinnovation.experimedia.arch.ecc.common.dataModel.metrics.*; import uk.ac.soton.itinnovation.experimedia.arch.ecc.common.dataModel.monitor.EMDataBatch; import uk.ac.soton.itinnovation.experimedia.arch.ecc.common.dataModel.monitor.EMPhase; import uk.ac.soton.itinnovation.experimedia.arch.ecc.common.dataModel.monitor.EMPostReportSummary; import uk.ac.soton.itinnovation.experimedia.arch.ecc.common.dataModel.provenance.*; import uk.ac.soton.itinnovation.experimedia.arch.ecc.samples.shared.*; import uk.ac.soton.itinnovation.sad.service.helpers.ProvVideo; import uk.ac.soton.itinnovation.sad.service.services.SchedulingService; import javax.annotation.PostConstruct; import java.util.*; import org.slf4j.Logger; import org.slf4j.LoggerFactory; /** * SAD EMClient, based on * uk.ac.soton.itinnovation.experimedia.arch.ecc.samples.headlessECCClient.ECCHeadlessClient */ @Service("ProvEMClient") public class ProvEMClient implements EMIAdapterListener { private final Logger logger = LoggerFactory.getLogger(getClass()); private static final String[] expectedEccProperties = new String[] { "enabled", "Rabbit_IP", "Rabbit_Port", "Monitor_ID", "Client_Name" }; private static final String[] expectedEdmProperties = new String[] { "enabled", "dbURL", "dbName", "dbUsername", "dbPassword", "dbType" }; // Connection to ECC private AMQPBasicChannel amqpChannel; private EMInterfaceAdapter emiAdapter; // Experiment and measurement information private HashMap<UUID, MetricGenerator> metricGenerators = new HashMap<>(); private Experiment theExperiment; private HashMap<UUID, MeasurementSet> measurementSetMap = new HashMap<>(); private HashSet<MeasurementTask> scheduledMeasurementTasks = new HashSet<>(); private HashMap<UUID, ITakeMeasurement> instantMeasurers = new HashMap<>(); private MetricGenerator theMetricGenerator; private UUID numPluginsRunMeasurementSetUuid; private UUID numPluginsFailedMeasurementSetUuid; private UUID numPluginsSuccessMeasurementSetUuid; private UUID actionsTakenUuid; private UUID videoQualityUuid; private ArrayList<UUID> pendingPushReports = new ArrayList<>(); private HashMap<UUID, Report> pendingPullReports = new HashMap<>(); private boolean emClientOK = false; private boolean measurementSchedulerOK = false; private boolean pushingEnabled = false; private boolean metricsModelSetup = false; // PROV private EDMProvFactory factory; // Client state private boolean deRegisteringFromEM = false; @Autowired @Qualifier("schedulingService") SchedulingService schedulingService; public ProvEMClient() { } @PostConstruct public void init() { } public boolean start() { // Connect to EM logger.debug("Creating new PROV EM Client ..."); Runtime.getRuntime().addShutdownHook(new ShutdownHook()); metricGenerators = new HashMap<>(); measurementSetMap = new HashMap<>(); scheduledMeasurementTasks = new HashSet<>(); instantMeasurers = new HashMap<>(); pendingPushReports = new ArrayList<>(); pendingPullReports = new HashMap<>(); emClientOK = false; measurementSchedulerOK = false; pushingEnabled = false; metricsModelSetup = false; // JSONObject eccProperties = propertiesService.getPropertyAsJSONObject("ecc"); JSONObject eccProperties = new JSONObject(); ensureAllEccPropertiesDefined(eccProperties); if (!eccProperties.getString("enabled").equals("y")) { logger.debug("ECC integration disabled in configuration. Stopped creating SAD EM client"); } else { logger.debug("Using ECC SAD configuration: " + eccProperties.toString(2)); String rabbitServerIP = eccProperties.getString("Rabbit_IP"); int rabbitServerPort = Integer.parseInt(eccProperties.getString("Rabbit_Port")); UUID expMonitorID = UUID.fromString(eccProperties.getString("Monitor_ID")); String clientName = "PROV ECC Client"; UUID clientID = UUID.randomUUID(); logger.debug("Created new client UUID: " + clientID.toString()); AMQPConnectionFactory amqpFactory = new AMQPConnectionFactory(); amqpFactory.setAMQPHostIPAddress(rabbitServerIP); amqpFactory.setAMQPHostPort(rabbitServerPort); try { amqpFactory.connectToAMQPHost(); amqpChannel = amqpFactory.createNewChannel(); } catch (Exception ex) { throw new RuntimeException( "Failed to connect to Rabbit server [" + rabbitServerIP + ":" + rabbitServerPort + "]", ex); } emiAdapter = new EMInterfaceAdapter(this); try { emiAdapter.registerWithEM(clientName, amqpChannel, expMonitorID, clientID); } catch (Exception ex) { throw new RuntimeException("Failed to register client [" + clientID + "] '" + clientName + "' with EM using experiment monitor ID [" + expMonitorID + "]", ex); } factory = EDMProvFactory.getInstance(); logger.debug("Successfully created new SAD EM Client"); emClientOK = true; } logger.debug("EM Client init results:"); logger.debug("\t- emClientOK: " + emClientOK); logger.debug("\t- measurementSchedulerOK: " + measurementSchedulerOK); return true; } /** * Returns true if EM Client was successfully created. */ public boolean isEmClientOK() { return emClientOK; } /** * Returns true if ECC measurement scheduler was successfully created. */ public boolean isMeasurementSchedulerOK() { return measurementSchedulerOK; } /** * Returns true if ECC enabled pushing. */ public boolean isPushingEnabled() { return pushingEnabled; } /** * Returns true if ECC metric model was created (UUIDs for measurement * reports have been set). */ public boolean isMetricModelSetup() { return metricsModelSetup; } /** * Converts JSON into Properties object. */ private Properties jsonToProperties(JSONObject propertiesAsJson) { Properties result = new Properties(); logger.debug("Converting JSON to Properties: " + propertiesAsJson.toString(2)); Iterator<String> it = propertiesAsJson.keys(); String propertyName, propertyValue; while (it.hasNext()) { propertyName = it.next(); propertyValue = propertiesAsJson.getString(propertyName); result.put(propertyName, propertyValue); } logger.debug("Convertion result: " + result.toString()); return result; } /** * Checks if all necessary ECC properties are present in the configuration * file. */ private void ensureAllEccPropertiesDefined(JSONObject eccProperties) { logger.debug("Checking if ECC SAD configuration has all required properties: "); for (String expectedProperty : expectedEccProperties) { if (!eccProperties.containsKey(expectedProperty)) { throw new RuntimeException("ECC configuration must have '" + expectedProperty + "' property. Your configuration: " + eccProperties.toString(2)); } else { logger.debug("\t- " + expectedProperty + " OK"); } } } /** * Checks if all necessary local EDM properties are present in the * configuration file. */ private void ensureAllEdmPropertiesDefined(JSONObject edmProperties) { logger.debug("Checking if EDM SAD configuration has all required properties: "); for (String expectedProperty : expectedEdmProperties) { if (!edmProperties.containsKey(expectedProperty)) { throw new RuntimeException("EDM configuration must have '" + expectedProperty + "' property. Your configuration: " + edmProperties.toString(2)); } else { logger.debug("\t- " + expectedProperty + " OK"); } } } @Override public void onEMConnectionResult(boolean connected, Experiment e) { if (connected) { if (e == null) { logger.error("Successfully connected to EM, but linked to experiment NULL. De-registering from EM"); deRegisterFromEM(); } else { logger.debug("Successfully connected to EM, linked to experiment [" + e.getExperimentID() + "] " + e.getName() + " (" + e.getDescription() + ")"); // Clone passed Experiment instance to save later in EDM Agent during discovery phase theExperiment = new Experiment(); theExperiment.setName(e.getName()); theExperiment.setDescription(e.getDescription()); theExperiment.setStartTime(e.getStartTime()); } } else { logger.error("Connection to EM was refused. De-registering from EM"); deRegisterFromEM(); } } /** * Attempts to disconnect (de-register) from EM */ public synchronized boolean deRegisterFromEM() { if (emiAdapter != null) { // run only when ECC not is disabled logger.debug("Attempting to deregister from EM, already deregistering: " + deRegisteringFromEM); // Don't repeatedly try to deregister if (!deRegisteringFromEM) { try { deRegisteringFromEM = true; emiAdapter.disconnectFromEM(); deRegisteringFromEM = false; return true; } catch (Throwable ex) { logger.error("Failed to de-register with the EM", ex); deRegisteringFromEM = false; return false; } } else { return false; } } else { return false; } } @Override public void onEMDeregistration(String reason) { logger.warn("Got DISCONNECTED because of: " + reason); deRegisterFromEM(); } @Override public void onDescribeSupportedPhases(EnumSet<EMPhase> phasesOUT) { logger.debug("Describing supported phases: Live monitoring and Post report only"); // Skipping Set-up and Tear-down phases: // phasesOUT.add(EMPhase.eEMSetUpMetricGenerators); phasesOUT.add(EMPhase.eEMLiveMonitoring); // phasesOUT.add(EMPhase.eEMPostMonitoringReport); // phasesOUT.add(EMPhase.eEMTearDown); } @Override public void onDescribePushPullBehaviours(Boolean[] pushPullOUT) { logger.debug("Describing push pull behaviours: only pushing supported"); pushPullOUT[0] = true; // Yes to pushing pushPullOUT[1] = false; // No to pulling } @Override public void onPopulateMetricGeneratorInfo() { logger.debug("Populating metric generator info"); // Time to start defining what metrics we can produce for this experiment if (theExperiment != null) { // Define all metric generators for this experiment createMetricModel(theExperiment); // Even if the EDMAgent isn't available, we can still send data, so // notify the adapter of our metrics emiAdapter.sendMetricGenerators(theExperiment.getMetricGenerators()); } else { // Things are bad if we can't describe our metric generators - so disconnect logger.error( "Trying to populate metric generator info - but current experiment is NULL. Disconnecting"); deRegisterFromEM(); } } /** * Defines SAD metric model */ private HashSet<MetricGenerator> createMetricModel(Experiment experiment) { measurementSetMap.clear(); // This map will be useful later for reporting measurement summaries // MetricHelper. theMetricGenerator = new MetricGenerator(); theMetricGenerator.setName("PROV Metric Generator"); theMetricGenerator.setDescription("Metric generator for AVCC Sim"); experiment.addMetricGenerator(theMetricGenerator); MetricGroup theMetricGroup = new MetricGroup(); theMetricGroup.setName("PROV Metric Group"); theMetricGroup.setDescription("Metric group for all AVCC Sim metircs"); theMetricGroup.setMetricGeneratorUUID(theMetricGenerator.getUUID()); theMetricGenerator.addMetricGroup(theMetricGroup); Entity theEntity = new Entity(); theEntity.setName("User actions"); theEntity.setDescription("Entity for PROV user actions metrics"); theMetricGenerator.addEntity(theEntity); Attribute actionsTaken = new Attribute(); actionsTaken.setName("Actions taken"); actionsTaken.setDescription("Names of actions by user at sample video page"); actionsTaken.setEntityUUID(theEntity.getUUID()); theEntity.addAttribute(actionsTaken); actionsTakenUuid = setupMeasurementForAttribute(actionsTaken, theMetricGroup, MetricType.NOMINAL, new Unit("")); Attribute videoQuality = new Attribute(); videoQuality.setName("Video Quality"); videoQuality.setDescription("Video resolution of the video player selected by user"); videoQuality.setEntityUUID(theEntity.getUUID()); theEntity.addAttribute(videoQuality); videoQualityUuid = setupMeasurementForAttribute(videoQuality, theMetricGroup, MetricType.NOMINAL, new Unit("")); metricGenerators.put(theMetricGenerator.getUUID(), theMetricGenerator); HashSet<MetricGenerator> mgSet = new HashSet<>(); mgSet.addAll(metricGenerators.values()); logger.debug("Reporting the following metric generator set to ECC: "); int counter = 0; for (MetricGenerator tempMg : mgSet) { printMetricGenerator(tempMg, counter); counter++; } metricsModelSetup = true; return mgSet; } public UUID getNumPluginsRunMeasurementSetUuid() { return numPluginsRunMeasurementSetUuid; } public UUID getNumPluginsFailedMeasurementSetUuid() { return numPluginsFailedMeasurementSetUuid; } public UUID getNumPluginsSuccessMeasurementSetUuid() { return numPluginsSuccessMeasurementSetUuid; } public UUID getActionsTakenMeasurementSetUuid() { return actionsTakenUuid; } /** * Pushes the new number of plugin runs measurement to ECC. * * @param newNumPluginsRun new number of plugin runs to report. */ public void pushNumPluginsRunMeasurementToEcc(int newNumPluginsRun) { if (emClientOK) { if (pushingEnabled) { logger.debug("Pushing total number of plugins run measurement update (" + newNumPluginsRun + ") to the ECC"); pushSingleMeasurementForMeasurementSetUuid(numPluginsRunMeasurementSetUuid, Integer.toString(newNumPluginsRun)); } else { logger.debug( "NOT pushing total number of plugins run measurement update to the ECC because pushing is DISABLED (wrong phase or was not told to start pushing by the ECC)"); } } else { logger.debug( "NOT pushing total number of plugins run measurement update to the ECC because EM client is NOT enabled"); } } /** * Pushes the new number of successful plugin runs measurement to ECC. * * @param newNumPluginsSucceeded new number of successful plugin runs to * report. */ public void pushNumPluginsSucceededMeasurementToEcc(int newNumPluginsSucceeded) { if (emClientOK) { if (pushingEnabled) { logger.debug("Pushing number of successful plugins measurement update (" + newNumPluginsSucceeded + ") to the ECC"); pushSingleMeasurementForMeasurementSetUuid(numPluginsSuccessMeasurementSetUuid, Integer.toString(newNumPluginsSucceeded)); } else { logger.debug( "NOT pushing number of successful plugins measurement update to the ECC because pushing is DISABLED (wrong phase or was not told to start pushing by the ECC)"); } } else { logger.debug( "NOT pushing number of successful plugins measurement update to the ECC because EM client is NOT enabled"); } } /** * Pushes the new number of failed plugins measurement to ECC. * * @param newNumPluginsFailed new number of failed plugins to report. */ public void pushNumPluginsFailedMeasurementToEcc(int newNumPluginsFailed) { if (emClientOK) { if (pushingEnabled) { logger.debug("Pushing number of failed plugins measurement update (" + newNumPluginsFailed + ") to the ECC"); pushSingleMeasurementForMeasurementSetUuid(numPluginsFailedMeasurementSetUuid, Integer.toString(newNumPluginsFailed)); } else { logger.debug( "NOT pushing number of failed plugins measurement update to the ECC because pushing is DISABLED (wrong phase or was not told to start pushing by the ECC)"); } } else { logger.debug( "NOT pushing number of failed plugins measurement update to the ECC because EM client is NOT enabled"); } } /** * Pushes the action to ECC. * * @param actionTaken taken to report. */ public void pushActionTakenMeasurementToEcc(String actionTaken) { if (emClientOK) { if (pushingEnabled) { logger.debug("Pushing new action taken measurement update (" + actionTaken + ") to the ECC"); pushSingleMeasurementForMeasurementSetUuid(actionsTakenUuid, actionTaken); } else { logger.debug( "NOT pushing new plugin name measurement update to the ECC because pushing is DISABLED (wrong phase or was not told to start pushing by the ECC)"); } } else { logger.debug( "NOT pushing new plugin name measurement update to the ECC because EM client is NOT enabled"); } } /** * Pushes the video quality to ECC. * * @param videoQuality taken to report. */ public void pushVideoQualityMeasurementToEcc(String videoQuality) { if (emClientOK) { if (pushingEnabled) { logger.debug("Pushing new action taken measurement update (" + videoQuality + ") to the ECC"); pushSingleMeasurementForMeasurementSetUuid(videoQualityUuid, videoQuality); } else { logger.debug( "NOT pushing new plugin name measurement update to the ECC because pushing is DISABLED (wrong phase or was not told to start pushing by the ECC)"); } } else { logger.debug( "NOT pushing new plugin name measurement update to the ECC because EM client is NOT enabled"); } } /** * Pushes single measurement to the ECC for a measurement set. * * @param uuid UUID of the measurement set. * @param measurementValueAsString measurement value as string. */ public boolean pushSingleMeasurementForMeasurementSetUuid(UUID uuid, String measurementValueAsString) { Report report = getReportForMeasurementSetUuid(uuid); report.setNumberOfMeasurements(1); if (report == null) { logger.error("Failed to push single measurement (" + measurementValueAsString + ") for measurement set [" + uuid.toString() + "] to the ECC because new report is NULL"); return false; } else { pushReportWithSingleMeasurement(report, measurementValueAsString); logger.debug("PUSHED single measurement report: [" + report.getUUID().toString() + "] " + "for measurement set [" + uuid.toString() + "] with measurement value '" + measurementValueAsString + "'"); return true; } } /** * Creates new report for a measurement set. * * @param uuid UUID of the measurement set. * @return ECC report object. */ private Report getReportForMeasurementSetUuid(UUID uuid) { MeasurementSet ms = MetricHelper.getMeasurementSet(theMetricGenerator, uuid); Report report = MetricHelper.createEmptyMeasurementReport(ms); report.setNumberOfMeasurements(1); Date now = new Date(); report.setReportDate(now); report.setFromDate(now); report.setToDate(now); return report; } /** * Pushes new report to the ECC with single measurement. * * @param reportToPush which report to push. * @param measurementValue which measurement to include with the report * before pushing. */ private void pushReportWithSingleMeasurement(Report reportToPush, String measurementValue) { Measurement sample = new Measurement(measurementValue); reportToPush.getMeasurementSet().addMeasurement(sample); // Push to ECC if (emClientOK) { emiAdapter.pushMetric(reportToPush); pendingPushReports.add(reportToPush.getUUID()); } else { logger.warn("Not pushing report to ECC as EM client DISABLED"); } } public void reportLoadPlayer(JSONObject event) { try { logger.debug("Creating prov report:\n" + event.toString(2)); String userName = event.getString("user_name"); String userId = event.getString("user_id"); String timestamp = event.getString("timestamp"); String url = event.getString("video_url"); factory = EDMProvFactory.getInstance(); // User EDMAgent userAsAgent = factory.createAgent("experimedia:" + userName + "_" + userId, userName); userAsAgent.addOwlClass("foaf:Person"); // Load page activity EDMActivity loadPageAsActivity = userAsAgent .doDiscreteActivity("experimedia:loadPage_" + userId + "_" + timestamp, timestamp); // Video EDMEntity videoAsEntity = factory.createEntity("experimedia:video_" + url, url); // Video player EDMEntity videoPlayerAsEntity = loadPageAsActivity.generateEntity("experimedia:videoPlayer_" + userId, userId); // videoPlayerAsEntity.addOwlClass("prov:Location"); // videoAsEntity.addProperty("prov:atLocation", videoPlayerAsEntity.getIri()); EDMProvReport report = factory.createProvReport(); pendingPushReports.add(report.getID()); emiAdapter.pushPROVStatement(report); } catch (Throwable ex) { logger.debug("Failed to report action by person as prov data", ex); } } public void reportActionByPerson(ProvVideo input_video) { try { logger.debug("Sending prov video data: " + input_video.toString()); factory = EDMProvFactory.getInstance(); EDMAgent user = factory.createAgent( "experimedia:" + input_video.getUserName() + "_" + input_video.getUserId(), input_video.getUserName()); user.addOwlClass("foaf:Person"); EDMActivity videoActivity = user.doDiscreteActivity("experimedia:" + input_video.getAction() + "_" + input_video.getUserId() + "_" + input_video.getTimestamp(), Long.toString(input_video.getTimestamp() / 1000)); EDMEntity videoPlayer = factory.createEntity("experimedia:videoPlayer_" + input_video.getUserId(), input_video.getUserId()); // videoActivity.addProperty("prov:used", videoPlayer.getIri()); EDMProvReport report = factory.createProvReport(); pendingPushReports.add(report.getID()); emiAdapter.pushPROVStatement(report); } catch (Throwable ex) { logger.debug("Failed to report action by person as prov data", ex); } } @Override public void onDiscoveryTimeOut() { logger.warn("Received DISCOVERY TIMEOUT message"); } @Override public void onSetupMetricGenerator(UUID uuid, Boolean[] resultOUT) { logger.debug("Reporting success setting up metric generator [" + uuid.toString() + "]"); resultOUT[0] = true; } @Override public void onSetupTimeOut(UUID uuid) { logger.warn("Received SETUP TIMEOUT message"); } @Override public void onLiveMonitoringStarted() { logger.debug("ECC has started live monitoring process"); // If we have an EDM Agent and scheduling, then start taking periodic measurements if (measurementSchedulerOK) { startMeasuring(); } } @Override public void onStartPushingMetricData() { logger.debug("ECC says: START pushing data, enabling pushing, pushing current data"); pushingEnabled = true; // pushNumPluginsRunMeasurementToEcc(leaderboardService.getAllLeaderboardContestants().size()); } @Override public void onPushReportReceived(UUID reportID) { if (pendingPushReports.contains(reportID)) { logger.debug("ECC says push report [" + reportID.toString() + "] RECEIVED, removing from pending"); pendingPushReports.remove(reportID); } else { logger.error("Unknown push report [" + reportID.toString() + "]"); } } @Override public void onStopPushingMetricData() { logger.debug("ECC says: STOP pushing data"); pushingEnabled = false; } @Override public void onPullReportReceived(UUID reportID) { logger.debug("ECC says pull report [" + reportID.toString() + "] RECEIVED"); if (pendingPullReports.containsKey(reportID)) { pendingPullReports.remove(reportID); } else { // logger.error("Unknown pull report [" + reportID.toString() + "]"); } } @Override public void onPullMetric(UUID measurementSetID, Report reportOUT) { // Otherwise, immediately generate the metric 'on-the-fly' ITakeMeasurement sampler = instantMeasurers.get(measurementSetID); MeasurementSet mSet = measurementSetMap.get(measurementSetID); if (sampler != null && mSet != null) { // Make an empty measurement set for this data first MeasurementSet emptySet = new MeasurementSet(mSet, false); reportOUT.setMeasurementSet(emptySet); sampler.takeMeasure(reportOUT); } else { logger.error("Could not find measurement sampler for measurement set with ID [" + measurementSetID.toString() + "]"); } } @Override public void onPullMetricTimeOut(UUID measurementSetID) { logger.warn( "Received PULL METRIC TIMEOUT message for Measurement Set [" + measurementSetID.toString() + "]"); } @Override public void onPullingStopped() { logger.debug("ECC has stopped pulling"); stopMeasuring(); } @Override public void onPopulateSummaryReport(EMPostReportSummary summaryOUT) { // summary statistics logger.debug("Populating summary report WITHOUT local EDM agent using instant measurers"); Iterator<UUID> msIDIt = instantMeasurers.keySet().iterator(); while (msIDIt.hasNext()) { // Get measurement and measurement set for sampler UUID msID = msIDIt.next(); ITakeMeasurement sampler = instantMeasurers.get(msID); MeasurementSet mset = measurementSetMap.get(msID); if (sampler != null && mset != null) { // Create a report for this measurement set + summary stats Report report = new Report(); report.setMeasurementSet(mset); report.setFromDate(sampler.getFirstMeasurementDate()); report.setToDate(sampler.getLastMeasurementDate()); report.setNumberOfMeasurements(sampler.getMeasurementCount()); summaryOUT.addReport(report); } } } @Override public void onPopulateDataBatch(EMDataBatch batchOUT) { logger.debug("Populating data batch"); // If we have been storing metrics using the EDM & Scheduler, get some // previously unsent data UUID msID = batchOUT.getExpectedMeasurementSetID(); if (msID == null) { logger.warn("Expected measurement set ID for this batch is NULL"); } else { logger.debug("Expected measurement set ID for this batch: " + msID.toString()); } } @Override public void onReportBatchTimeOut(UUID uuid) { logger.warn("Received REPORT BATCH TIMEOUT message"); } @Override public void onGetTearDownResult(Boolean[] resultOUT) { logger.debug("Reporting successfull tear down result"); resultOUT[0] = true; } @Override public void onTearDownTimeOut() { logger.warn("Received TEAR DOWN TIMEOUT message"); } /* * * USEFUL METHODS * */ /** * Run through all our measurement tasks and start them up. */ private void startMeasuring() { Iterator<MeasurementTask> taskIt = scheduledMeasurementTasks.iterator(); while (taskIt.hasNext()) { taskIt.next().startMeasuring(); } } /** * Run through all our measurement tasks and stop them. */ private void stopMeasuring() { Iterator<MeasurementTask> taskIt = scheduledMeasurementTasks.iterator(); while (taskIt.hasNext()) { taskIt.next().stopMeasuring(); } } /** * Correct way to setup measurements from ~ ECC version 1.1 */ // private void setupMeasurementForAttribute(Attribute attr, // MetricGroup parentGroup, // MetricType type, // Unit unit, // ITakeMeasurement listener, // long intervalMS) { // // // Define the measurement set // MeasurementSet ms = new MeasurementSet(); // parentGroup.addMeasurementSets(ms); // ms.setMetricGroupUUID(parentGroup.getUUID()); // ms.setAttributeUUID(attr.getUUID()); // ms.setMetric(new Metric(UUID.randomUUID(), type, unit)); // // // Map this measurement set for later // measurementSetMap.put( ms.getID(), ms ); // // // If available, create an automatic measurement task to periodically take measurements // if (localEdmOK && measurementSchedulerOK) { // try { // // Must keep hold of task reference to ensure continued sampling // MeasurementTask task = measurementScheduler.createMeasurementTask( // ms, // MeasurementSet // listener, // Listener that will take measurement // -1, // Monitor indefinitely... // intervalMS); // ... each 'X' milliseconds // // scheduledMeasurementTasks.add(task); // } catch (Throwable ex) { // logger.error("Could not define measurement task for attribute " + attr.getName(), ex); // } // } else { // // If we can't schedule & store measurements, just have the samplers handy // instantMeasurers.put(ms.getID(), listener); // } // } private UUID setupMeasurementForAttribute(Attribute attr, MetricGroup parentGroup, MetricType type, Unit unit) { // Define the measurement set MeasurementSet ms = new MeasurementSet(); parentGroup.addMeasurementSets(ms); ms.setMetricGroupUUID(parentGroup.getUUID()); ms.setAttributeUUID(attr.getUUID()); ms.setMetric(new Metric(UUID.randomUUID(), type, unit)); // Map this measurement set for later measurementSetMap.put(ms.getID(), ms); return ms.getID(); } /** * Simplifies the process of adding metrics to attributes and metric groups. */ @Deprecated private void addMetricToAttributeAndMetricGroup(MetricGroup metricGroup, Attribute attribute, MetricType metricType, Unit metricUnit) { MeasurementSet theMeasuringSet = new MeasurementSet(); theMeasuringSet.setMetricGroupUUID(metricGroup.getUUID()); theMeasuringSet.setAttributeUUID(attribute.getUUID()); metricGroup.addMeasurementSets(theMeasuringSet); // allMeasurementSets.add(theMeasuringSet); // measurementSetsAndAttributes.put(theMeasuringSet.getUUID(), attribute); Metric theMetric = new Metric(); theMetric.setMetricType(metricType); theMetric.setUnit(metricUnit); theMeasuringSet.setMetric(theMetric); } /** * Prints a metric generator into logs as a tree. */ private void printMetricGenerator(MetricGenerator mg, int numberInSet) { pr("[" + numberInSet + "] " + mg.getName() + " (" + mg.getDescription() + ") [" + mg.getUUID() + "]", 0); Set<MeasurementSet> allMeasurementSets = new HashSet<>(); for (MetricGroup mgroup : mg.getMetricGroups()) { allMeasurementSets.addAll(mgroup.getMeasurementSets()); } for (Entity e : mg.getEntities()) { pr("Entity: " + e.getName() + " (" + e.getDescription() + ") [" + e.getUUID() + "]", 1); for (Attribute a : e.getAttributes()) { pr("Attribute: " + a.getName() + " (" + a.getDescription() + ") [" + a.getUUID() + "]", 2); for (MeasurementSet ms : allMeasurementSets) { if (ms.getAttributeID().toString().equals(a.getUUID().toString())) { pr("Metric type: " + ms.getMetric().getMetricType() + ", unit: " + ms.getMetric().getUnit() + ", measurement set [" + ms.getID() + "]", 3); } } } } } /** * Prints an object into logs with indent. */ private void pr(Object o, int indent) { String indentString = ""; for (int i = 0; i < indent; i++) { indentString += "\t"; } if (indent > 0) { logger.debug(indentString + "- " + o); } else { logger.debug("" + o); } } /** * Private shut-down hook. */ private class ShutdownHook extends Thread { @Override public void run() { logger.debug("Executing clean shutdown"); deRegisterFromEM(); } } }