package org.openiot.gsn.dynamicSensorControl; import java.io.File; import java.io.IOException; import java.util.ArrayList; import java.util.Collection; import java.util.HashMap; import java.util.List; import java.util.TimerTask; import org.apache.commons.io.FileUtils; import org.apache.commons.io.filefilter.RegexFileFilter; import org.apache.log4j.Logger; import org.apache.log4j.PropertyConfigurator; import org.openiot.gsn.Main; import org.openiot.gsn.metadata.LSM.LSMRepository; import org.openiot.gsn.utils.PropertiesReader; import org.openrdf.repository.RepositoryException; /** * * @author Christos Georgoulis (cgeo) e-mail: cgeo@ait.edu.gr * */ public class DynamicControlTask extends TimerTask { // Variable Initialization private static final Logger logger = Logger .getLogger(DynamicControlTask.class); private static final String REGEX_ALL_XML = "^(.*?)\\.xml$"; private static final String METADATA_FILE_SUFFIX = ".metadata"; // Following query used for testing purposes private static final String TEST_QUERY = "select ?sensorId from <http://lsm.deri.ie/OpenIoT/demo/sensormeta#> " + "WHERE {?sensorId <http://lsm.deri.ie/ont/lsm.owl#hasSensorType> ?type. " + "?type <http://www.w3.org/2000/01/rdf-schema#label> 'gsn'. " + "FILTER EXISTS {?sensorId <http://www.loa-cnr.it/ontologies/DUL.owl#hasLocation> ?p. } " + "?p geo:geometry ?geo.filter (<bif:st_intersects>(?geo,<bif:st_point>(6.631622,46.520131),15)).}"; // Update the following constant with the query to be used private static final String QUERY = TEST_QUERY; private SparqlClient sparqlClient; // Singleton Setup private DynamicControlTask() { } private static class Holder { private static final DynamicControlTask INSTANCE = new DynamicControlTask(); } public static DynamicControlTask getInstance() { return Holder.INSTANCE; } // Class Methods @Override public void run() { PropertyConfigurator.configure(Main.DEFAULT_GSN_LOG4J_PROPERTIES); sparqlClient = loadSparqlClient(); if (sparqlClient != null) { ArrayList<String> sensorDefinitions = getSensorDefinitions(); HashMap<String, File> activeGSNSensors = getGSNSensors(PropertiesReader .readProperty(LSMRepository.LSM_CONFIG_PROPERTIES_FILE, "virtualSensorsDir")); HashMap<String, File> availableGSNSensors = getGSNSensors(PropertiesReader .readProperty(LSMRepository.LSM_CONFIG_PROPERTIES_FILE, "availableSensorsDir")); // Compare sensors and perform update updateActiveSensors(sensorDefinitions, activeGSNSensors, availableGSNSensors); } } /** * Activates - deactivates sensors according to SPARQL query results * * @param sensorDefinitions * @param activeGSNSensors * @param availableGSNSensors */ private void updateActiveSensors(List<String> sensorDefinitions, HashMap<String, File> activeGSNSensors, HashMap<String, File> availableGSNSensors) { for (String sensorID : activeGSNSensors.keySet()) { if (!sensorDefinitions.contains(sensorID)) deactivateSensor(activeGSNSensors.get(sensorID)); } ArrayList<String> sensorsToActivate = new ArrayList<String>( sensorDefinitions); sensorsToActivate.removeAll(activeGSNSensors.keySet()); for (String sensorName : sensorsToActivate) { File file = availableGSNSensors.get(sensorName); if (file != null) { activateSensor(file); } else { System.out.println(sensorName + " not available in LSM directory"); logger.error(sensorName + " not available in LSM directory"); } } } /** * Obtains sensors from directory and maps Sensor names to Sensor Files * * @return */ private HashMap<String, File> getGSNSensors(String dir) { HashMap<String, File> sensorsMap = new HashMap<String, File>(); File f = new File(dir); if (!f.getAbsoluteFile().exists()) { System.out.println("no such File/Dir"); logger.error(f.getName() + "no such File/Dir"); } else { Collection<File> files = FileUtils.listFiles(f, new RegexFileFilter(REGEX_ALL_XML), null); for (File file : files) { String path = file.getAbsolutePath() + METADATA_FILE_SUFFIX; String sensorID = PropertiesReader.readProperty(path, "sensorID"); sensorsMap.put(sensorID, file); } } return sensorsMap; } /** * Sends a SPARQL Query that retrieves sensors that are being defined as * used on the LSM * * @return */ private ArrayList<String> getSensorDefinitions() { Collection<String> col = sparqlClient.getQueryResults(QUERY, ParserFactory.SENSOR_PARSER); ArrayList<String> list = new ArrayList<String>(col); return list; } /** * deletes file from virtual-sensors directory * * @param file */ private void deactivateSensor(File file) { File metadata = new File(file.getAbsolutePath() + METADATA_FILE_SUFFIX); if (file.delete() && metadata.delete()) { logger.info(file.getName() + " successfully deleted from virtual-sensors directory"); System.out.println(file.getName() + " successfully deleted!"); } else { System.out.println("Delete operation failed for " + file.getName()); logger.info("Delete operation failed for " + file.getName()); } } /** * copies file from LSM directory to virtual-sensors directory * * @param xmlSource */ private void activateSensor(File xmlSource) { // metadata file destination String virtualSensorsDir = PropertiesReader.readProperty( LSMRepository.LSM_CONFIG_PROPERTIES_FILE, "virtualSensorsDir"); File xmlDest = new File(virtualSensorsDir + File.separator + xmlSource.getName()); // xmlFile destination File metaDataSource = new File(xmlSource.getAbsolutePath() + METADATA_FILE_SUFFIX); File metaDataDest = new File(virtualSensorsDir + File.separator + metaDataSource.getName()); try { FileUtils.copyFile(xmlSource, xmlDest); FileUtils.copyFile(metaDataSource, metaDataDest); } catch (IOException e) { e.printStackTrace(); } } /** Initializes SPARQL Connection */ private SparqlClient loadSparqlClient() { SparqlClient sc = null; try { sc = new SparqlClient(); logger.info("Sparql Repository loaded"); } catch (RepositoryException e) { logger.error("Sparql Repository not reached", e); } return sc; } // TODO Complete // private String createQuery() { // String query = "select distinct(?sensorid) from " // + Resources.LSM_FUNCTIONAL_GRAPH + "where {...}"; // // return query; // } }