/* * ProActive Parallel Suite(TM): * The Open Source library for parallel and distributed * Workflows & Scheduling, Orchestration, Cloud Automation * and Big Data Analysis on Enterprise Grids & Clouds. * * Copyright (c) 2007 - 2017 ActiveEon * Contact: contact@activeeon.com * * This library 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: version 3 of * the License. * * This program 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 this program. If not, see <http://www.gnu.org/licenses/>. * * If needed, contact us to obtain a release under GPL Version 2 or 3 * or a different license than the AGPL. */ package org.ow2.proactive.resourcemanager.updater; import java.io.File; import java.io.IOException; import java.io.RandomAccessFile; import java.lang.reflect.InvocationTargetException; import java.lang.reflect.Method; import java.net.URL; import java.net.URLConnection; import java.nio.channels.FileChannel; import java.nio.channels.FileLock; import java.util.Date; import org.apache.commons.io.FileUtils; /** * * A wrapper class to use with agents. * It either detects that node.jar must be updated, then downloads it start a node. * When an agent detects it and restart the node it just proxies the request to RMNodeStarer. * */ public class RMNodeUpdater { private static final String NODE_URL_PROPERTY = "node.jar.url"; private static final String NODE_JAR_PROPERTY = "node.jar.saveas"; private static final String TMP_DIR_PROPERTY = "java.io.tmpdir"; public static final String ONE_JAR_JAR_PATH = "one-jar.jar.path"; public static final String SCHEDULER_NODE_JAR = "scheduler-node.jar"; private static boolean isLocalJarUpToDate(String url, String filePath) { try { URLConnection urlConnection = new URL(url).openConnection(); File file = new File(filePath); System.out.println("Url date=" + new Date(urlConnection.getLastModified())); System.out.println("File date=" + new Date(file.lastModified())); if (file.lastModified() < urlConnection.getLastModified()) { System.out.println("Local jar " + file + " is obsolete"); } else { System.out.println("Local jar " + file + " is up to date"); return true; } } catch (IOException e) { e.printStackTrace(); } return false; } private static boolean makeNodeUpToDate() { if (System.getProperty(NODE_URL_PROPERTY) != null) { String jarUrl = System.getProperty(NODE_URL_PROPERTY); String jarFile = SCHEDULER_NODE_JAR; if (System.getProperty(NODE_JAR_PROPERTY) != null) { jarFile = System.getProperty(NODE_JAR_PROPERTY); } if (!isLocalJarUpToDate(jarUrl, jarFile)) { System.out.println("Downloading node.jar from " + jarUrl + " to " + jarFile); try { File destination = new File(jarFile); File lockFile = null; FileLock lock = null; if (destination.exists()) { lockFile = new File(System.getProperty(TMP_DIR_PROPERTY) + "/lock"); if (!lockFile.exists()) { lockFile.createNewFile(); } System.out.println("Getting the lock on " + lockFile.getAbsoluteFile()); FileChannel channel = new RandomAccessFile(lockFile, "rw").getChannel(); lock = channel.lock(); if (isLocalJarUpToDate(jarUrl, jarFile)) { System.out.println("Another process downloaded node.jar - don't do it anymore"); System.out.println("Releasing the lock on " + lockFile.getAbsoluteFile()); lock.release(); channel.close(); return false; } } FileUtils.copyURLToFile(new URL(jarUrl), destination); System.out.println("Download finished"); if (lock != null && lockFile != null) { System.out.println("Releasing the lock on " + lockFile.getAbsoluteFile()); lock.release(); } return true; } catch (Exception e) { System.err.println("Cannot download node.jar from " + jarUrl); e.printStackTrace(); } } } else { System.out.println("No java property " + NODE_URL_PROPERTY + " specified. Do not check for the new version."); } return false; } public static void main(String[] args) throws IOException, InterruptedException, ClassNotFoundException, NoSuchMethodException, InvocationTargetException, IllegalAccessException { makeNodeUpToDate(); if (System.getProperty(ONE_JAR_JAR_PATH) == null) { System.setProperty(ONE_JAR_JAR_PATH, SCHEDULER_NODE_JAR); } System.out.println("Launching a computing node"); Class<?> cls = Class.forName("OneJar"); Method meth = cls.getMethod("main", String[].class); meth.invoke(null, (Object) args); } }