/* * Copyright (c) 2014 Villu Ruusmann * * This file is part of Openscoring * * Openscoring is free software: you can redistribute it and/or modify * it under the terms of the GNU Affero General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * Openscoring 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 Affero General Public License for more details. * * You should have received a copy of the GNU Affero General Public License * along with Openscoring. If not, see <http://www.gnu.org/licenses/>. */ package org.openscoring.client; import java.io.File; import java.nio.file.DirectoryStream; import java.nio.file.FileSystem; import java.nio.file.Files; import java.nio.file.Path; import java.nio.file.StandardWatchEventKinds; import java.nio.file.WatchEvent; import java.nio.file.WatchKey; import java.nio.file.WatchService; import java.util.LinkedHashSet; import java.util.List; import java.util.Set; import com.beust.jcommander.Parameter; import org.slf4j.Logger; import org.slf4j.LoggerFactory; public class DirectoryDeployer extends Application { @Parameter ( names = {"--model-collection"}, description = "The URI of the model collection", required = true ) private String modelCollection = null; @Parameter ( names = {"--dir"}, description = "The directory to watch for PMML file additions and removals", required = true ) private File dir = null; /** * A set of "managed" model identifiers. */ private Set<String> identifiers = new LinkedHashSet<>(); static public void main(String... args) throws Exception { run(DirectoryDeployer.class, args); } @Override public void run() throws Exception { Path root = (getDir()).toPath(); try(DirectoryStream<Path> children = Files.newDirectoryStream(root)){ for(Path child : children){ process(StandardWatchEventKinds.ENTRY_CREATE, child); } } try(FileSystem fileSystem = root.getFileSystem()){ try(WatchService watcher = fileSystem.newWatchService()){ WatchKey key = root.register(watcher, StandardWatchEventKinds.ENTRY_CREATE, StandardWatchEventKinds.ENTRY_DELETE); if(key.isValid()){ processKey(key, root); } while(key.reset()){ try { key = watcher.take(); } catch(InterruptedException ie){ break; } if(key.isValid()){ processKey(key, root); } } } } } private void processKey(WatchKey key, Path root) throws Exception { List<WatchEvent<?>> events = key.pollEvents(); for(WatchEvent<?> event : events){ Path child = root.resolve((Path)event.context()); process((WatchEvent.Kind<Path>)event.kind(), child); } } private void process(WatchEvent.Kind<Path> kind, Path path) throws Exception { String id = (path.getFileName()).toString(); // Use the name part of the file name (ie. everything to the left of the first dot character) as the model identifier int dot = id.indexOf('.'); if(dot > -1){ id = id.substring(0, dot); } // End if if(("").equals(id)){ return; } // End if if((StandardWatchEventKinds.ENTRY_CREATE).equals(kind)){ if(!Files.isRegularFile(path)){ return; } logger.info("Deploying model {}", id); Deployer deployer = new Deployer(); deployer.setModel(getModelCollection() + "/" + id); deployer.setFile(path.toFile()); deployer.run(); this.identifiers.add(id); } else if((StandardWatchEventKinds.ENTRY_DELETE).equals(kind)){ boolean status = this.identifiers.remove(id); if(!status){ return; } logger.info("Undeploying model {}", id); Undeployer undeployer = new Undeployer(); undeployer.setModel(getModelCollection() + "/" + id); undeployer.run(); } } public String getModelCollection(){ return this.modelCollection; } public void setModelCollection(String modelCollection){ this.modelCollection = modelCollection; } public File getDir(){ return this.dir; } public void setDir(File dir){ this.dir = dir; } private static final Logger logger = LoggerFactory.getLogger(DirectoryDeployer.class); }