org.sentilo.samples.controller.SamplesController.java Source code

Java tutorial

Introduction

Here is the source code for org.sentilo.samples.controller.SamplesController.java

Source

/*
 * Sentilo
 *  
 * Original version 1.4 Copyright (C) 2013 Institut Municipal dInformtica, 
 * Ajuntament de Barcelona.
 * Modified by Opentrends adding support for multitenant deployments and SaaS. 
 * Modifications on version 1.5 Copyright (C) 2015 Opentrends Solucions i Sistemes, S.L.
 * 
 *   
 * This program is licensed and may be used, modified and redistributed under the
 * terms  of the European Public License (EUPL), either version 1.1 or (at your 
 * option) any later version as soon as they are approved by the European 
 * Commission.
 *   
 * Alternatively, you may redistribute and/or modify this program under the terms
 * of the GNU Lesser General Public License as published by the Free Software 
 * Foundation; either  version 3 of the License, or (at your option) any later 
 * version. 
 *   
 * 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 licenses for the specific language governing permissions, limitations 
 * and more details.
 *   
 * You should have received a copy of the EUPL1.1 and the LGPLv3 licenses along 
 * with this program; if not, you may find them at: 
 *   
 *   https://joinup.ec.europa.eu/software/page/eupl/licence-eupl
 *   http://www.gnu.org/licenses/ 
 *   and 
 *   https://www.gnu.org/licenses/lgpl.txt
 */
package org.sentilo.samples.controller;

import java.text.NumberFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Properties;

import javax.annotation.Resource;

import org.codehaus.jackson.map.ObjectMapper;
import org.sentilo.common.domain.AuthorizedProvider;
import org.sentilo.common.domain.CatalogComponent;
import org.sentilo.common.domain.CatalogSensor;
import org.sentilo.platform.client.core.PlatformTemplate;
import org.sentilo.platform.client.core.domain.CatalogInputMessage;
import org.sentilo.platform.client.core.domain.CatalogOutputMessage;
import org.sentilo.platform.client.core.domain.DataInputMessage;
import org.sentilo.platform.client.core.domain.Observation;
import org.sentilo.platform.client.core.domain.SensorObservations;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.RequestMapping;

/**
 * SamplesController
 * 
 * Executes a basic Sentilo Java Client Platform example that connects to the server and publishes some data to a sample sensor.
 * In this case we're getting info from the system with the runtime properties object
 * 
 */
@Controller
public class SamplesController {

    private final Logger logger = LoggerFactory.getLogger(SamplesController.class);

    private static final String VIEW_SAMPLES_RESPONSE = "samples";

    @Autowired
    private PlatformTemplate platformTemplate;

    @Resource
    private Properties samplesProperties;

    @RequestMapping(value = { "/", "/home" })
    public String runSamples(final Model model) {

        // All this data must be created in the Catalog Application before start this
        // sample execution. At least the application identity token id and the provider id must be
        // declared in system twice
        String restClientIdentityKey = samplesProperties.getProperty("rest.client.identityKey");
        String providerId = samplesProperties.getProperty("rest.client.provider");

        // For this example we have created a generic component with a status sensor that accepts text
        // type observations, only for test purpose
        String componentId = samplesProperties.getProperty("rest.client.component");
        String sensorId = samplesProperties.getProperty("rest.client.sensor");

        logger.info("Starting samples execution...");

        String observationsValue = null;
        String errorMessage = null;

        try {
            // Get some system data from runtime
            Runtime runtime = Runtime.getRuntime();
            NumberFormat format = NumberFormat.getInstance();
            StringBuilder sb = new StringBuilder();
            long maxMemory = runtime.maxMemory();
            long allocatedMemory = runtime.totalMemory();
            long freeMemory = runtime.freeMemory();

            sb.append("free memory: " + format.format(freeMemory / 1024) + "<br/>");
            sb.append("allocated memory: " + format.format(allocatedMemory / 1024) + "<br/>");
            sb.append("max memory: " + format.format(maxMemory / 1024) + "<br/>");
            sb.append("total free memory: " + format.format((freeMemory + (maxMemory - allocatedMemory)) / 1024)
                    + "<br/>");

            // In this case, we're getting CPU status in text mode
            observationsValue = sb.toString();

            logger.info("Observations values: " + observationsValue);

            // Create the sample sensor, only if it doesn't exists in the catalog
            createSensorIfNotExists(restClientIdentityKey, providerId, componentId, sensorId);

            // Publish observations to the sample sensor
            sendObservations(restClientIdentityKey, providerId, componentId, sensorId, observationsValue);
        } catch (Exception e) {
            logger.error("Error publishing sensor observations: " + e.getMessage(), e);
            errorMessage = e.getMessage();
        }

        logger.info("Samples execution ended!");

        model.addAttribute("restClientIdentityKey", restClientIdentityKey);
        model.addAttribute("providerId", providerId);
        model.addAttribute("componentId", componentId);
        model.addAttribute("sensorId", sensorId);
        model.addAttribute("observations", observationsValue);

        ObjectMapper mapper = new ObjectMapper();

        try {
            if (errorMessage != null && errorMessage.length() > 0) {
                Object json = mapper.readValue(errorMessage, Object.class);
                model.addAttribute("errorMsg", mapper.writerWithDefaultPrettyPrinter().writeValueAsString(json));
            } else {
                model.addAttribute("successMsg", "Observations sended successfully");
            }
        } catch (Exception e) {
            logger.error("Error parsing JSON: {}", e.getMessage(), e);
            errorMessage += (errorMessage.length() > 0) ? "<br/>" : "" + e.getMessage();
            model.addAttribute("errorMsg", errorMessage);
        }

        return VIEW_SAMPLES_RESPONSE;
    }

    /**
     * Retrieve catalog information about the sample provider. If the component and/or sensor doesn't
     * exists, then let create they
     * 
     * @param identityToken Samples Application identity token for manage the rest connections
     * @param providerId Samples provider id
     * @param componentId Samples component id
     * @param sensorId Samples sensor id
     * @return {@link CatalogOutputMessage} object with provider's catalog data
     */
    private CatalogOutputMessage createSensorIfNotExists(String identityToken, String providerId,
            String componentId, String sensorId) {
        List<String> sensorsIdList = new ArrayList<String>();
        sensorsIdList.add(sensorId);

        // Create a CatalogInputMessage object for retrieve server data
        CatalogInputMessage getSensorsInputMsg = new CatalogInputMessage();
        getSensorsInputMsg.setProviderId(providerId);
        getSensorsInputMsg.setIdentityToken(identityToken);
        getSensorsInputMsg.setComponents(createComponentsList(componentId));
        getSensorsInputMsg.setSensors(createSensorsList(providerId, componentId, sensorsIdList));

        // Obtain the sensors list from provider within a CatalogOutputMessage response object type
        CatalogOutputMessage getSensorsOutputMsg = platformTemplate.getCatalogOps().getSensors(getSensorsInputMsg);

        // Search for the sensor in the list
        boolean existsSensor = false;
        if (getSensorsOutputMsg.getProviders() != null && !getSensorsOutputMsg.getProviders().isEmpty()) {
            for (AuthorizedProvider provider : getSensorsOutputMsg.getProviders()) {
                if (provider.getSensors() != null && !provider.getSensors().isEmpty()) {
                    for (CatalogSensor sensor : provider.getSensors()) {
                        logger.debug("Retrieved sensor: " + sensor.getComponent() + " - " + sensor.getSensor());
                        existsSensor |= sensorId.equals(sensor.getSensor());
                        if (existsSensor) {
                            break;
                        }
                    }
                }
            }
        }

        // If the sensor doesn't exists in the retrieved list, we must create it before publish the
        // observations
        if (!existsSensor) {
            // Create a CatalogInputMessage object for retrieve server data
            CatalogInputMessage registerSensorsInputMsg = new CatalogInputMessage(providerId);
            registerSensorsInputMsg.setIdentityToken(identityToken);
            registerSensorsInputMsg.setComponents(createComponentsList(componentId));
            registerSensorsInputMsg.setSensors(createSensorsList(providerId, componentId, sensorsIdList));

            // Register the new sensor in the server
            platformTemplate.getCatalogOps().registerSensors(registerSensorsInputMsg);
        }

        return getSensorsOutputMsg;
    }

    /**
     * Publish some observations from a sensor
     * 
     * @param identityToken Samples Application identity token for manage the rest connections
     * @param providerId Samples provider id
     * @param componentId Samples component id
     * @param sensorId Samples sensor id
     * @param value Observations value, in our case, a String type
     */
    private void sendObservations(String identityToken, String providerId, String componentId, String sensorId,
            String value) {
        List<String> sensorsIdList = new ArrayList<String>();
        sensorsIdList.add(sensorId);
        createSensorsList(providerId, componentId, sensorsIdList);

        List<Observation> observations = new ArrayList<Observation>();
        Observation observation = new Observation(value, new Date());
        observations.add(observation);

        SensorObservations sensorObservations = new SensorObservations(sensorId);
        sensorObservations.setObservations(observations);

        DataInputMessage dataInputMessage = new DataInputMessage(providerId, sensorId);
        dataInputMessage.setIdentityToken(identityToken);
        dataInputMessage.setSensorObservations(sensorObservations);

        platformTemplate.getDataOps().sendObservations(dataInputMessage);
    }

    /**
     * Create a component list
     * 
     * @param componentId Component identifier
     * @return A {@link CatalogComponent} list
     */
    private List<CatalogComponent> createComponentsList(String componentId) {
        List<CatalogComponent> catalogComponentList = new ArrayList<CatalogComponent>();
        CatalogComponent catalogComponent = new CatalogComponent();
        catalogComponent.setComponent(componentId);
        catalogComponent.setComponentType(samplesProperties.getProperty("rest.client.component.type"));
        catalogComponent.setLocation(samplesProperties.getProperty("rest.client.component.location"));
        catalogComponentList.add(catalogComponent);
        return catalogComponentList;
    }

    /**
     * Create a sensor list
     * 
     * @param componentId The Sample Component Id
     * @param sensorsIdList A list with the sensor ids to create
     * @return A {@link CatalogSensor} list
     */
    private List<CatalogSensor> createSensorsList(String providerId, String componentId,
            List<String> sensorsIdList) {
        List<CatalogSensor> catalogSensorsList = new ArrayList<CatalogSensor>();
        for (String sensorId : sensorsIdList) {
            CatalogSensor catalogSensor = new CatalogSensor();
            catalogSensor.setComponent(componentId);
            catalogSensor.setSensor(sensorId);
            catalogSensor.setProvider(providerId);
            catalogSensor.setType(samplesProperties.getProperty("rest.client.sensor.type"));
            catalogSensor.setDataType(samplesProperties.getProperty("rest.client.sensor.dataType"));
            catalogSensor.setLocation(samplesProperties.getProperty("rest.client.sensor.location"));
            catalogSensorsList.add(catalogSensor);
        }
        return catalogSensorsList;
    }
}