uk.ac.soton.itinnovation.ecc.service.controllers.DataController.java Source code

Java tutorial

Introduction

Here is the source code for uk.ac.soton.itinnovation.ecc.service.controllers.DataController.java

Source

/////////////////////////////////////////////////////////////////////////
//
//  University of Southampton IT Innovation Centre, 2014
//
// 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 :         2014-04-22
//   Created for Project :           EXPERIMEDIA
//
/////////////////////////////////////////////////////////////////////////
package uk.ac.soton.itinnovation.ecc.service.controllers;

import java.io.BufferedWriter;
import java.io.IOException;
import java.io.OutputStreamWriter;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Date;
import java.util.Set;
import java.util.UUID;
import javax.servlet.http.HttpServletResponse;
import org.joda.time.format.ISODateTimeFormat;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.ResponseBody;
import uk.ac.soton.itinnovation.experimedia.arch.ecc.common.dataModel.experiment.Experiment;
import uk.ac.soton.itinnovation.experimedia.arch.ecc.common.dataModel.metrics.Attribute;
import uk.ac.soton.itinnovation.experimedia.arch.ecc.common.dataModel.metrics.Entity;
import uk.ac.soton.itinnovation.experimedia.arch.ecc.common.dataModel.metrics.MeasurementSet;
import uk.ac.soton.itinnovation.experimedia.arch.ecc.common.dataModel.monitor.EMClient;
import uk.ac.soton.itinnovation.ecc.service.domain.EccAttribute;
import uk.ac.soton.itinnovation.ecc.service.domain.EccEntity;
import uk.ac.soton.itinnovation.ecc.service.domain.EccGenericMeasurement;
import uk.ac.soton.itinnovation.ecc.service.domain.EccGenericMeasurementSet;
import uk.ac.soton.itinnovation.ecc.service.domain.EccMeasurement;
import uk.ac.soton.itinnovation.ecc.service.services.ConfigurationService;
import uk.ac.soton.itinnovation.ecc.service.services.DataService;
import uk.ac.soton.itinnovation.ecc.service.services.ExperimentService;
import uk.ac.soton.itinnovation.ecc.service.utils.Convert;
import uk.ac.soton.itinnovation.ecc.service.utils.EccAttributesComparator;

/**
 * Exposes experimental data.
 */
@Controller
@RequestMapping("/data")
public class DataController {

    private final Logger logger = LoggerFactory.getLogger(getClass());

    @Autowired
    ConfigurationService configurationService;

    @Autowired
    ExperimentService experimentService;

    @Autowired
    DataService dataService;

    @RequestMapping(method = RequestMethod.GET, value = "/entities/{experimentUuid}")
    @ResponseBody
    public ArrayList<EccEntity> getEntitiesForExperiment(@PathVariable String experimentUuid) {
        logger.debug("Returning entities for experiment [" + experimentUuid + "]");
        ArrayList<EccEntity> result = new ArrayList<EccEntity>();
        EccEntity tempEntity;
        ArrayList<EccAttribute> attributes;
        MeasurementSet ms;
        try {
            for (Entity e : dataService.getEntitiesForExperiment(UUID.fromString(experimentUuid))) {
                tempEntity = new EccEntity();
                attributes = new ArrayList<EccAttribute>();
                tempEntity.setName(e.getName());
                tempEntity.setDescription(e.getDescription());
                tempEntity.setUuid(e.getUUID());

                Set<Attribute> attrs = e.getAttributes();
                if (attrs != null) {
                    for (Attribute a : e.getAttributes()) {
                        ms = dataService.getAllEmptyMeasurementSetsForAttribute(UUID.fromString(experimentUuid), a)
                                .iterator().next();
                        attributes.add(
                                new EccAttribute(a.getName(), a.getDescription(), a.getUUID(), a.getEntityUUID(),
                                        ms.getMetric().getMetricType().name(), ms.getMetric().getUnit().getName()));
                    }
                }
                Collections.sort(attributes, new EccAttributesComparator());
                tempEntity.setAttributes(attributes);
                result.add(tempEntity);
            }
        } catch (Exception ex) {
            logger.error("Failed to return entities for experiment [" + experimentUuid + "]", ex);
        }
        return result;
    }

    /**
     * Returns 10 latest data points for an attribute from now.
     *
     * @param attributeId attribute to return data for.
     * @return
     */
    @RequestMapping(method = RequestMethod.GET, value = "/attribute/{attributeId}")
    @ResponseBody
    public EccGenericMeasurementSet getLatestDataForAttribute(@PathVariable String attributeId) {
        logger.debug("Returning 10 latest data entries for attribute [" + attributeId + "]");

        EccAttribute theAttribute = dataService.getEccAttribute(attributeId);
        EccGenericMeasurementSet result = new EccGenericMeasurementSet();

        if (theAttribute != null) {
            String theType = theAttribute.getType();
            logger.debug("Attribute [" + theAttribute.getUuid().toString() + "] is of type '" + theType + "'");

            if (theType.equals("NOMINAL")) {
                result = Convert.eccCounterMeasurementSetToEccGenericMeasurementSet(
                        dataService.getCounterMeasurementsForAttributeAfter(
                                experimentService.getActiveExperiment().getUUID().toString(), attributeId,
                                (new Date()).getTime(), 10));
            } else {
                result = Convert.eccMeasurementSetToEccGenericMeasurementSet(
                        dataService.getLatestMeasurementsForAttribute(attributeId, 10));
            }

            for (EccGenericMeasurement em : result.getData()) {
                logger.debug("Reporting: " + em.getKey() + ": " + em.getValue());
            }

        }
        return result;
    }

    /**
     * Returns 10 latest data points for an attribute since time.
     *
     * @param attributeId attribute to return data for.
     * @param timestampMsec
     * @return
     */
    @RequestMapping(method = RequestMethod.GET, value = "/attribute/{attributeId}/since/{timestampMsec}")
    @ResponseBody
    public EccGenericMeasurementSet getLatestDataForAttributeSince(@PathVariable String attributeId,
            @PathVariable Long timestampMsec) {
        logger.debug("Returning 10 latest data items for attribute '" + attributeId + "' since '" + timestampMsec
                + "' (" + new Date(timestampMsec) + ")");

        EccAttribute theAttribute = dataService.getEccAttribute(attributeId);
        EccGenericMeasurementSet result = new EccGenericMeasurementSet();

        if (theAttribute != null) {
            String theType = theAttribute.getType();
            logger.debug("Attribute [" + theAttribute.getUuid().toString() + "] is of type '" + theType + "'");

            if (theAttribute.getType().equals("NOMINAL")) {
                // TODO: this is bad, but no time to fix:
                if (dataService.getCounterMeasurementsForAttributeBeforeAndExcluding(
                        experimentService.getActiveExperiment().getUUID().toString(), attributeId, timestampMsec,
                        10).getData().size() > 0) { // only return 10 latest if there is new stuff
                    result = Convert.eccCounterMeasurementSetToEccGenericMeasurementSet(
                            dataService.getCounterMeasurementsForAttributeAfter(
                                    experimentService.getActiveExperiment().getUUID().toString(), attributeId,
                                    (new Date()).getTime(), 10));
                } else {
                    result.setData(new ArrayList<EccGenericMeasurement>());
                    result.setType(theType);
                    result.setUnit(theAttribute.getUnit());
                }
            } else {
                result = Convert.eccMeasurementSetToEccGenericMeasurementSet(
                        dataService.getLatestSinceMeasurementsForAttribute(attributeId, timestampMsec, 10));
            }

        } else {
            logger.error("Failed to find attribute [" + "] in current experiment");
        }

        return result;
    }

    /**
     * Returns attribute data as a download file.
     *
     * @param experimentId
     * @param attributeId attribute to return data for.
     * @param response
     */
    @RequestMapping(method = RequestMethod.GET, value = "/export/experiment/{experimentId}/attribute/{attributeId}")
    @ResponseBody
    public void exportDataForAttribute(@PathVariable String experimentId, @PathVariable String attributeId,
            HttpServletResponse response) {
        logger.debug("Exporting data for attribute [" + attributeId + "], experiment [" + experimentId + "]");

        // TODO: should be a database-level query
        EccAttribute attribute = null;
        for (EccAttribute eccAttribute : dataService.getAttributesForExperiment(experimentId)) {
            if (eccAttribute.getUuid().equals(UUID.fromString(attributeId))) {
                attribute = eccAttribute;
                break;
            }
        }

        if (attribute == null) {
            logger.error("Attribute [" + attributeId + "] was not found in experiment [" + experimentId + "]");
        } else {

            String fileName = attribute.getName() + " (attribute) - experiment " + experimentId + ".csv";
            response.setContentType("text/csv");
            response.setHeader("Content-disposition", "attachment; filename=\"" + fileName + "\"");

            try {
                BufferedWriter writer = new BufferedWriter(new OutputStreamWriter(response.getOutputStream()));
                writer.write("Timestamp, Value");

                for (EccMeasurement m : dataService.getAllMeasurementsForAttribute(experimentId, attributeId)
                        .getData()) {
                    writer.newLine();
                    writer.write(
                            ISODateTimeFormat.dateTime().print(m.getTimestamp().getTime()) + ", " + m.getValue());
                }

                writer.flush();
                writer.close();
                response.flushBuffer();
            } catch (IOException e) {
                logger.error("Failed to write data to output response stream for attribute [" + attributeId
                        + "], experiment [" + experimentId + "]", e);
            }
        }
    }

    /**
     * Returns entity data as a download file.
     *
     * @param experimentId
     * @param entityId
     * @param response
     */
    @RequestMapping(method = RequestMethod.GET, value = "/export/experiment/{experimentId}/entity/{entityId}")
    @ResponseBody
    public void exportDataForEntity(@PathVariable String experimentId, @PathVariable String entityId,
            HttpServletResponse response) {
        logger.debug("Exporting data for entity [" + entityId + "], experiment [" + experimentId + "]");

        // TODO: add error reporting
        EccEntity entity = null;

        for (EccEntity tempEntity : dataService.getEntitiesForExperiment(experimentId, true)) {
            if (tempEntity.getUuid().equals(UUID.fromString(entityId))) {
                entity = tempEntity;
                break;
            }
        }

        if (entity == null) {
            logger.error("Entity [" + entityId + "] was not found in experiment [" + experimentId + "]");
        } else {
            ArrayList<EccAttribute> attributes = entity.getAttributes();
            String fileName = entity.getName() + " (entity) - experiment " + experimentId + ".csv";
            response.setContentType("text/csv");
            response.setHeader("Content-disposition", "attachment; filename=\"" + fileName + "\"");

            try {
                BufferedWriter writer = new BufferedWriter(new OutputStreamWriter(response.getOutputStream()));
                writer.write("Attribute UUID, Attribute Name, Timestamp, Value, Metric type, Metric unit");
                for (EccAttribute a : attributes) {
                    logger.debug("Writing attribute [" + a.getUuid().toString() + "] " + a.getName());
                    for (EccMeasurement m : dataService
                            .getAllMeasurementsForAttribute(experimentId, a.getUuid().toString()).getData()) {
                        writer.newLine();
                        writer.write(a.getName() + ", " + a.getUuid().toString() + ", ");
                        writer.write(ISODateTimeFormat.dateTime().print(m.getTimestamp().getTime()) + ", "
                                + m.getValue() + ", ");
                        writer.write(a.getType() + ", " + a.getUnit());
                    }
                }

                writer.flush();
                writer.close();
                response.flushBuffer();
            } catch (IOException e) {
                logger.error("Failed to write data to output response stream for entity [" + entityId
                        + "], experiment [" + experimentId + "]", e);
            }
        }
    }

    /**
     * Returns client data as a download file.
     *
     * @param clientId
     * @param response
     */
    @RequestMapping(method = RequestMethod.GET, value = "/export/client/{clientId}")
    @ResponseBody
    public void exportDataForClient(@PathVariable String clientId, HttpServletResponse response) {
        logger.debug("Exporting data for client [" + clientId + "]");

        // TODO: add error reporting
        try {
            EMClient theClient = experimentService.getClientByID(UUID.fromString(clientId));
            Experiment currentExperiment = experimentService.getActiveExperiment();

            String experimentUuid;
            if (currentExperiment == null) {
                // should never happen
                experimentUuid = "unknown";
            } else {
                experimentUuid = currentExperiment.getUUID().toString();
            }

            if (theClient != null) {

                ArrayList<EccEntity> entities = dataService.getEntitiesForClient(clientId, true);
                ArrayList<EccAttribute> attributes;

                String fileName = theClient.getName() + " (client) - experiment " + experimentUuid + ".csv";
                response.setHeader("Content-disposition", "attachment; filename=\"" + fileName + "\"");
                response.setContentType("text/csv");

                BufferedWriter writer = new BufferedWriter(new OutputStreamWriter(response.getOutputStream()));
                writer.write(
                        "Entity Name, Entity UUID, Attribute Name, Attribute UUID, Timestamp, Value, Metric type, Metric unit");
                for (EccEntity e : entities) {
                    attributes = e.getAttributes();

                    for (EccAttribute a : attributes) {
                        for (EccMeasurement m : dataService.getAllMeasurementsForAttribute(a.getUuid().toString())
                                .getData()) {
                            writer.newLine();
                            writer.write(e.getName() + ", " + e.getUuid().toString() + ", ");
                            writer.write(a.getName() + ", " + a.getUuid().toString() + ", ");
                            writer.write(ISODateTimeFormat.dateTime().print(m.getTimestamp().getTime()) + ", "
                                    + m.getValue() + ", ");
                            writer.write(a.getType() + ", " + a.getUnit());

                        }
                    }
                }

                writer.flush();
                writer.close();
                response.flushBuffer();
            } else {
                String msg = "Failed to write data to output: could not find client for experiment: " + clientId;
                logger.error(msg);
            }
        } catch (Exception e) {
            logger.error("Failed to write data to output response stream for client [" + clientId + "]", e);
        }
    }

    /**
     * Returns experiment data as a download file.
     *
     * @param experimentId
     * @param response
     */
    @RequestMapping(method = RequestMethod.GET, value = "/export/experiment/{experimentId}")
    @ResponseBody
    public void exportDataForTheExperiment(@PathVariable String experimentId, HttpServletResponse response) {
        logger.debug("Exporting data for experiment '" + experimentId + "'");

        Experiment experiment = dataService.getExperiment(experimentId, false);

        // TODO: add error reporting
        if (experiment == null) {
            logger.error("Failed to get data for experiment [" + experimentId
                    + "], data service returned NULL experiment for that ID");
        } else {
            try {
                String fileName = experiment.getName() + " - UUID " + experimentId + ".csv";
                response.setHeader("Content-disposition", "attachment; filename=\"" + fileName + "\"");
                response.setContentType("text/csv");

                ArrayList<EccEntity> entities = dataService.getEntitiesForExperiment(experimentId, true);

                BufferedWriter writer = new BufferedWriter(new OutputStreamWriter(response.getOutputStream()));
                writer.write(
                        "Entity Name, Entity UUID, Attribute Name, Attribute UUID, Timestamp, Value, Metric type, Metric unit");
                ArrayList<EccAttribute> attributes;
                for (EccEntity e : entities) {
                    attributes = e.getAttributes();

                    if (attributes != null) {

                        for (EccAttribute a : attributes) {
                            ArrayList<EccMeasurement> emsData = dataService
                                    .getAllMeasurementsForAttribute(experimentId, a.getUuid().toString()).getData();

                            if (emsData != null)
                                for (EccMeasurement m : emsData) {
                                    writer.newLine();
                                    writer.write(e.getName() + ", " + e.getUuid().toString() + ", ");
                                    writer.write(a.getName() + ", " + a.getUuid().toString() + ", ");
                                    writer.write(ISODateTimeFormat.dateTime().print(m.getTimestamp().getTime())
                                            + ", " + m.getValue() + ", ");
                                    writer.write(a.getType() + ", " + a.getUnit());
                                }
                        }
                    }
                }

                writer.flush();
                writer.close();
                response.flushBuffer();
            } catch (IOException e) {
                logger.error("Failed to write data to output response stream for experiment [" + experimentId + "]",
                        e);
            }
        }
    }
}