/** * Copyright (c) 2011-2014, OpenIoT * * This file is part of OpenIoT. * * OpenIoT is free software: you can redistribute it and/or modify it under the * terms of the GNU Lesser General Public License as published by the Free * Software Foundation, version 3 of the License. * * OpenIoT is distributed in the hope that it will be useful, but WITHOUT ANY * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR * A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more * details. * * You should have received a copy of the GNU Lesser General Public License * along with OpenIoT. If not, see <http://www.gnu.org/licenses/>. * * Contact: OpenIoT mailto: info@openiot.eu * * @author Jean-Paul Calbimonte * @author Hylke van der Schaaf */ package org.openiot.gsn.http.restapi; import com.typesafe.config.Config; import java.io.ByteArrayInputStream; import java.io.File; import java.io.FileWriter; import java.io.IOException; import java.io.InputStream; import java.io.Reader; import java.util.List; import javax.ws.rs.*; import javax.ws.rs.core.MediaType; import javax.ws.rs.core.Response; import org.apache.commons.io.IOUtils; import org.openiot.gsn.Main; import org.openiot.gsn.VSensorLoader; import org.openiot.gsn.metadata.LSM.LSMSensorMetaData; import org.openiot.gsn.metadata.LSM.SensorAnnotator; import org.openiot.gsn.metadata.rdf.SensorMetadata; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import com.typesafe.config.ConfigFactory; import com.typesafe.config.ConfigRenderOptions; import com.typesafe.config.ConfigValueFactory; import org.openiot.gsn.metadata.LSM.LSMRepository; @Path("/vsensor") public class VSManagerService { private static final transient Logger logger = LoggerFactory.getLogger(VSManagerService.class); private static final String KEY_DELETE_FROM_LSM = "deleteFromLSM"; private static final Config DEFAULT_DELETE_CONFIG = ConfigFactory.empty(); static { DEFAULT_DELETE_CONFIG.withValue(KEY_DELETE_FROM_LSM, ConfigValueFactory.fromAnyRef(false)); } //public VSManagerService() { super(VSManagerService.class); } @POST @Path("/{vsname}/create") public Response createVS(Reader vsconfig, @PathParam("vsname") String vsname) { VSensorLoader vsloader = VSensorLoader.getInstance(Main.DEFAULT_VIRTUAL_SENSOR_DIRECTORY); logger.info("Start loading vs config"); String xml; try { xml = IOUtils.toString(vsconfig); vsconfig.close(); } catch (IOException e) { logger.error("Errors detected!", e); throw new VSensorConfigException(e.getMessage(), e); } logger.debug("The xml vs config: {}", xml); try { logger.info("Now we start"); vsloader.loadVirtualSensor(xml, vsname); logger.info("The vs is loaded"); } catch (Exception e) { logger.error("Errors detected!", e); throw new VSensorConfigException(e.getMessage(), e); } logger.info("Finalized loading."); return Response.ok(vsname).build(); } @POST @Path("/{vsname}/registerRdf") public Response registerRdfVS(Reader metadata, @PathParam("vsname") String vsname) { SensorMetadata meta = new SensorMetadata(); String filePath = VSensorLoader.getVSConfigurationFilePath(vsname).replace(".xml", ".ttl"); try { List<String> lines = IOUtils.readLines(metadata); String concat = ""; for (String line : lines) { concat += line; } InputStream is = new ByteArrayInputStream(concat.getBytes()); meta.load(is); SensorAnnotator.addRdfMetadatatoLSM(meta); FileWriter fw = new FileWriter(filePath, true); IOUtils.writeLines(lines, "\n", fw); fw.close(); } catch (Exception e) { logger.error("Unable to load RDF metadata for sensor.", e); throw new VSensorConfigException("Unable to load RDF metadata for sensor.", e); } return Response.ok().build(); } @POST @Path("/{vsname}/register") public Response registerVS(InputStream metadata, @PathParam("vsname") String vsname) { String sensorId; String sensorIdOld = null; String filePath = VSensorLoader.getVSConfigurationFilePath(vsname).replace(".xml", ".metadata"); try { List<String> lines = IOUtils.readLines(metadata); FileWriter fw = new FileWriter(filePath, false); IOUtils.writeLines(lines, "\n", fw); fw.close(); LSMSensorMetaData lsmmd = new LSMSensorMetaData(); Config configData = ConfigFactory.parseFile(new File(filePath)); if (configData.hasPath(LSMSensorMetaData.KEY_SENSOR_ID)) { sensorIdOld = configData.getString(LSMSensorMetaData.KEY_SENSOR_ID); } lsmmd.init(configData, true); sensorId = SensorAnnotator.addSensorToLSM(lsmmd); if (sensorIdOld == null || sensorId.compareTo(sensorIdOld) != 0) { logger.info("SensorId has changed from {} to {}.", sensorIdOld, sensorId); lsmmd.setSensorID(sensorId); Config configDataNew = configData.withValue(LSMSensorMetaData.KEY_SENSOR_ID, ConfigValueFactory.fromAnyRef(sensorId)); configDataNew = configDataNew.withValue(LSMSensorMetaData.KEY_SENSOR_ID, ConfigValueFactory.fromAnyRef(sensorId)); String metadataNew = configDataNew.root().render(ConfigRenderOptions.defaults().setJson(false).setOriginComments(false)); fw = new FileWriter(filePath, false); IOUtils.write(metadataNew, fw); fw.close(); } } catch (Exception e) { logger.error("Unable to load metadata for sensor", e); throw new VSensorConfigException("Unable to load metadata for sensor.", e); } return Response.ok(sensorId).build(); } @POST @Path("/{vsname}/delete") public Response deleteVS(InputStream data, @PathParam("vsname") String vsname) { logger.info("Deleting sensor {}.", vsname); try { Config configData = ConfigFactory.parseString(IOUtils.toString(data, "UTF-8")); Config config = configData.withFallback(DEFAULT_DELETE_CONFIG); String vsFilePath = VSensorLoader.getVSConfigurationFilePath(vsname); File vsFile = new File(vsFilePath); if (config.getBoolean(KEY_DELETE_FROM_LSM)) { String vsMetaPath = vsFilePath.replace(".xml", ".metadata"); File vsMetaFile = new File(vsMetaPath); if (vsMetaFile.exists()) { Config sensorConfig = ConfigFactory.parseFile(vsMetaFile); if (!sensorConfig.hasPath(LSMSensorMetaData.KEY_SENSOR_ID)) { logger.info("Can not delete sensor {} from LSM, sensorId not found in metadata file.", vsname); } else { String sensorId = sensorConfig.getString(LSMSensorMetaData.KEY_SENSOR_ID); logger.info("Deleting sensor {} from LSM. SensorId: {}.", vsname, sensorId); SensorAnnotator.deleteSensorFromLSM(sensorId); if (!vsMetaFile.delete()) { logger.error("Failed to delete sensor metadata file."); } } } } if (!vsFile.delete()) { throw new VSensorConfigException("Failed to unload sensor."); } LSMRepository lsm=LSMRepository.getInstance(); lsm.unloadMetaData(vsname); } catch (IOException e) { logger.warn("Could not parse options.", e); throw new VSensorConfigException("Could not parse options.", e); } return Response.ok(vsname).build(); } } class VSensorConfigException extends WebApplicationException { private static final long serialVersionUID = -2199585164343127464L; public VSensorConfigException(String message) { super(Response.status(Response.Status.BAD_REQUEST) .entity(message).type(MediaType.TEXT_PLAIN).build()); } public VSensorConfigException(String message, Throwable cause) { super(cause, Response.status(Response.Status.BAD_REQUEST) .entity(message).type(MediaType.TEXT_PLAIN).build()); } }