/** * Global Sensor Networks (GSN) Source Code * Copyright (c) 2006-2016, Ecole Polytechnique Federale de Lausanne (EPFL) * * This file is part of GSN. * * GSN is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * GSN 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 General Public License for more details. * * You should have received a copy of the GNU General Public License * along with GSN. If not, see <http://www.gnu.org/licenses/>. * * File: src/ch/epfl/gsn/http/rest/LocalDeliveryWrapper.java * * @author Ali Salehi * @author Mehdi Riahi * @author Timotee Maret * */ package ch.epfl.gsn.delivery; import java.io.IOException; import java.io.Serializable; import java.sql.SQLException; import java.util.Date; import javax.naming.OperationNotSupportedException; import org.slf4j.LoggerFactory; import ch.epfl.gsn.DataDistributer; import ch.epfl.gsn.Mappings; import ch.epfl.gsn.VirtualSensorInitializationFailedException; import ch.epfl.gsn.beans.AddressBean; import ch.epfl.gsn.beans.DataField; import ch.epfl.gsn.beans.StreamElement; import ch.epfl.gsn.beans.VSensorConfig; import ch.epfl.gsn.storage.SQLUtils; import ch.epfl.gsn.storage.SQLValidator; import ch.epfl.gsn.utils.Helpers; import ch.epfl.gsn.vsensor.AbstractVirtualSensor; import ch.epfl.gsn.wrappers.AbstractWrapper; import org.slf4j.Logger; import org.joda.time.format.ISODateTimeFormat; public class LocalDeliveryWrapper extends AbstractWrapper implements DeliverySystem{ private final String CURRENT_TIME = ISODateTimeFormat.dateTime().print(System.currentTimeMillis()); private static transient Logger logger = LoggerFactory.getLogger( LocalDeliveryWrapper.class ); private VSensorConfig vSensorConfig; public VSensorConfig getVSensorConfig() { return vSensorConfig; } private DataField[] structure; private DefaultDistributionRequest distributionRequest; public String getWrapperName() { return "Local-wrapper"; } public boolean initialize() { AddressBean params = getActiveAddressBean( ); String query = params.getPredicateValue("query"); String vsName = params.getPredicateValue( "name" ); String startTime = params.getPredicateValueWithDefault("start-time",CURRENT_TIME ); if (query==null && vsName == null) { logger.error("For using local-wrapper, either >query< or >name< parameters should be specified"); return false; } if (query == null) query = "select * from "+vsName; long lastVisited; try { lastVisited = Helpers.convertTimeFromIsoToLong(startTime); }catch (Exception e) { logger.error("Problem in parsing the start-time parameter, the provided value is:"+startTime+" while a valid input is:"+CURRENT_TIME); logger.error(e.getMessage(),e); return false; } try { vsName = SQLValidator.getInstance().validateQuery(query); if(vsName==null) //while the other instance is not loaded. return false; query = SQLUtils.newRewrite(query, vsName, vsName.toLowerCase()).toString(); logger.debug("Local wrapper request received for: "+vsName); vSensorConfig = Mappings.getConfig(vsName); distributionRequest = DefaultDistributionRequest.create(this, vSensorConfig, query, lastVisited); // This call MUST be executed before adding this listener to the data-distributer because distributer checks the isClose method before flushing. }catch (Exception e) { logger.error("Problem in the query parameter of the local-wrapper."); logger.error(e.getMessage(),e); return false; } return true; } public boolean sendToWrapper ( String action,String[] paramNames, Serializable[] paramValues ) throws OperationNotSupportedException { AbstractVirtualSensor vs; try { vs = Mappings.getVSensorInstanceByVSName( vSensorConfig.getName( ) ).borrowVS( ); } catch ( VirtualSensorInitializationFailedException e ) { logger.warn("Sending data back to the source virtual sensor failed !: "+e.getMessage( ),e); return false; } boolean toReturn = vs.dataFromWeb( action , paramNames , paramValues ); Mappings.getVSensorInstanceByVSName( vSensorConfig.getName( ) ).returnVS( vs ); return toReturn; } public String toString() { StringBuilder sb = new StringBuilder(); sb.append("LocalDistributionReq => [" ).append(distributionRequest.getQuery()).append(", Start-Time: ").append(new Date(distributionRequest.getStartTime())).append("]"); return sb.toString(); } public void run() { DataDistributer localDistributer = DataDistributer.getInstance(LocalDeliveryWrapper.class); localDistributer.addListener(this.distributionRequest); } public void writeStructure(DataField[] fields) throws IOException { this.structure=fields; } public DataField[] getOutputFormat() { return structure; } public void close() { logger.warn("Closing a local delivery."); try { releaseResources(); } catch (SQLException e) { logger.error(e.getMessage(),e); } } public boolean isClosed() { return !isActive(); } public boolean writeStreamElement(StreamElement se) { boolean isSucced = postStreamElement(se); logger.debug("wants to deliver stream element:"+ se.toString()+ "["+isSucced+"]"); return true; } public boolean writeKeepAliveStreamElement() { return true; } public void dispose() { } }