/*************************************************************************** * * * ShutdownNodes.java * * ------------------- * * date : 09.09.2004, 18:08 * * copyright : (C) 2004-2008 Distributed and * * Mobile Systems Group * * Lehrstuhl fuer Praktische Informatik * * Universitaet Bamberg * * http://www.uni-bamberg.de/pi/ * * email : sven.kaffille@uni-bamberg.de * * karsten.loesing@uni-bamberg.de * * * * * ***************************************************************************/ /*************************************************************************** * * * This program 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 2 of the License, or * * (at your option) any later version. * * * * A copy of the license can be found in the license.txt file supplied * * with this software or at: http://www.gnu.org/copyleft/gpl.html * * * ***************************************************************************/ package de.uniba.wiai.lspi.chord.console.command; import java.net.MalformedURLException; import java.util.LinkedList; import java.util.List; import java.util.Random; import java.util.Set; import de.uniba.wiai.lspi.chord.com.local.ChordImplAccess; import de.uniba.wiai.lspi.chord.com.local.Registry; import de.uniba.wiai.lspi.chord.com.local.ThreadEndpoint; import de.uniba.wiai.lspi.chord.data.URL; import de.uniba.wiai.lspi.util.console.Command; import de.uniba.wiai.lspi.util.console.ConsoleException; /** * <p> * {@link Command} to shutdown a number of nodes. * </p> * * To get a description of this command type <code>shutdown -help</code> into * the {@link de.uniba.wiai.lspi.chord.console.Main console}. * * @author sven * @version 1.0.5 */ public class ShutdownNodes extends Command { /** * Name of this {@link Command}. */ public static final String COMMAND_NAME = "shutdown"; /** * The name of the parameter, that defines the list of the nodes to * shutdown. */ public static final String NAMES_PARAM = "names"; /** * The parameter to define that all nodes should be shutdown. */ protected static final String ALL_PARAM = "all"; /** * Creates a new instance of shutdownNodes * * @param toCommand1 * @param out1 */ public ShutdownNodes(Object[] toCommand1, java.io.PrintStream out1) { super(toCommand1, out1); } public void exec() throws de.uniba.wiai.lspi.util.console.ConsoleException { if ((!this.parameters.containsKey(NAMES_PARAM)) && (!this.parameters.containsKey(ALL_PARAM))) { throw new ConsoleException("Not enough parameters. Provide at " + "least one node name with help of " + NAMES_PARAM + " parameter."); } String namesString = this.parameters.get(NAMES_PARAM); List<URL> names = new LinkedList<URL>(); if (namesString != null) { ListParameter namesParam = new ListParameter(NAMES_PARAM, namesString, false); for (String name : namesParam.getList()) { try { names.add(new URL(URL.KNOWN_PROTOCOLS .get(URL.LOCAL_PROTOCOL) + "://" + name + "/")); } catch (MalformedURLException e) { throw new ConsoleException(e.getMessage()); } } } else if (this.parameters.containsKey(ALL_PARAM)) { Registry reg = (Registry) this.toCommand[0]; Set<URL> all = reg.lookupAll().keySet(); names.addAll(all); if (names.size() == 0) { this.out.println("No nodes running."); } } if (names.size() == 1) { this.shutdown(names.get(0)); return; } /* random to calculate random sleep time */ Random r = new Random(); Thread[] threads = new Thread[names.size()]; for (int i = 0; i < names.size(); i++) { /* Create thread for each node to crash */ long s = r.nextLong() % 501; if (s < 0) { s *= -1; } final long sleep = s; final URL name = names.get(i); threads[i] = new Thread(new Runnable() { public void run() { try { Thread.sleep(sleep); } catch (InterruptedException e) { /* * nothing to do here. */ } shutdown(name); } }); threads[i].start(); } for (int i = 0; i < threads.length; i++) { try { threads[i].join(); } catch (InterruptedException e) { /* * nothing to do here. */ } } } /** * @param name */ void shutdown(URL name) { Registry reg = (Registry) this.toCommand[0]; ThreadEndpoint ep = reg.lookup(name); if (ep != null) { try { ChordImplAccess.fetchChordImplOfNode(ep.getNode()).leave(); this.out.println("Node with name " + name + " left."); } catch (Throwable t) { this.out.println("Could not shut down node with name " + name); this.out.println(t.getMessage()); t.printStackTrace(this.out); } } else { this.out.println("Could not find node with name " + name); } } public String getCommandName() { return COMMAND_NAME; } public void printOutHelp() { this.out.println("Shuts down all nodes provided by '" + NAMES_PARAM + "' parameter."); this.out .println("The names of the node must be separated by '_' \n as for the create command."); this.out.println("In order to shutdown all nodes provide parameter '" + ALL_PARAM + "' with no value."); } }