/* * Copyright 2008 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.rioproject.tools.cli; import groovy.lang.GroovyClassLoader; import net.jini.core.lookup.ServiceItem; import org.rioproject.deploy.DeployAdmin; import org.rioproject.impl.opstring.OAR; import org.rioproject.impl.opstring.OpStringLoader; import org.rioproject.opstring.*; import org.rioproject.resolver.Artifact; import org.rioproject.resolver.RemoteRepository; import org.rioproject.tools.webster.Webster; import java.io.*; import java.net.MalformedURLException; import java.net.URL; import java.util.*; /** * Utility for dealing with Monitor deploy, undeploy and redeploys * * @author Dennis Reedy */ public class MonitorControl { /** * Manages deployments */ public static class DeployHandler implements OptionHandler { public String process(final String input, final BufferedReader br, final PrintStream out) { if (out == null) throw new IllegalArgumentException("Must have an output PrintStream"); StringTokenizer tok = new StringTokenizer(input); String deployment = null; DeployOptions deployOptions = new DeployOptions(); deployOptions.deployTimeout = (Long) CLI.getInstance().settings.get(CLI.DEPLOY_WAIT); BufferedReader reader = br; boolean oarDeployment = false; if (tok.countTokens() > 1) { /* First token is "deploy" */ tok.nextToken(); /* Next token is the deploy-descriptor */ //deployment = tok.nextToken(); while (tok.hasMoreTokens()) { String value = tok.nextToken(); if (value.endsWith(".xml") || value.endsWith(".groovy")) { /* value is the deploy-descriptor */ deployment = value; } else if (value.endsWith("oar")) { /* value is the oar file */ deployment = value; oarDeployment = true; } else if (value.startsWith("-t")) { StringTokenizer tok1 = new StringTokenizer(value, " ="); if (tok1.countTokens() < 2) return (getUsage()); /* First token will be "delay" */ tok1.nextToken(); /* Next token must be the timeout value */ value = tok1.nextToken(); try { deployOptions.deployTimeout = Long.parseLong(value); } catch (NumberFormatException e) { return (getUsage()); } } else if (value.startsWith("-r")) { StringTokenizer tok1 = new StringTokenizer(value, " ="); if (tok1.countTokens() < 2) return (getUsage()); /* First token will be "-r" */ tok1.nextToken(); /* Next token must be the repositories value */ value = tok1.nextToken(); deployOptions.repositories = value; } else if (value.startsWith("-")) { /* strip the "-" off */ value = value.substring(1); while (value.length() > 0) { if (value.startsWith("i")) { deployOptions.noPrompt = true; } else if (value.startsWith("u")) { deployOptions.update = true; } else if (value.startsWith("v")) { deployOptions.verbose = true; }else { return (getUsage()); } value = value.substring(1); } } else { /* If its none of the above then we must have a * directory name to deploy */ deployment = value; oarDeployment = true; } } } else { return (getUsage()); } OperationalString deploy = null; if (!oarDeployment) { try { deploy = loadDeployment(deployment); if (deploy == null) { return (deployment + ": Cannot find file ["+deployment+"]\n"); } if(deployOptions.repositories!=null) { String[] parts = deployOptions.repositories.split(";"); List<RemoteRepository> remoteRepositories = new ArrayList<RemoteRepository>(); for(String part : parts) { RemoteRepository r = new RemoteRepository(); r.setUrl(part); remoteRepositories.add(r); } for(ServiceElement service : deploy.getServices()) { service.setRemoteRepositories(remoteRepositories); } } } catch (Exception e) { e.printStackTrace(); return ("Problem loading [" + deployment + "], Exception : " + e.getLocalizedMessage() + "\n"); } } ServiceItem[] items = CLI.getInstance().finder.findMonitors(null, null, deployOptions.verbose); if (items.length == 0) return ("No Provision Monitor instances discovered\n"); if (items.length == 1 || deployOptions.noPrompt()) { if (oarDeployment) { return (deploy(items[0], deployment, deployOptions, out)); } else { return (deploy(items[0], deploy, deployOptions, reader, out)); } } if (reader == null) reader = new BufferedReader(new InputStreamReader(System.in)); out.println(Formatter.asList(items) + "\n"); printRequest(out); while (true) { try { String response = reader.readLine(); if (response == null) { break; } if (response.equals("c")) break; try { int num = Integer.parseInt(response); if (num < 1 || num > (items.length + 1)) { printRequest(out); } else { if (oarDeployment) { deploy(items[0], deployment, deployOptions, out); } else { deploy(items[num - 1], deploy, deployOptions, reader, out); } break; } } catch (NumberFormatException e) { out.println("Invalid choice [" + response + "]"); printRequest(out); } } catch (IOException e) { e.printStackTrace(); } } return (""); } /** * Deploy an OperationalString using a selected monitor * * @param item The ServiceItem * @param deploy The OperationalString * @param deployOptions Deploy options * @param br A BufferedReader * @param out The printStream * * @return A String for the completed command */ String deploy(final ServiceItem item, final OperationalString deploy, final DeployOptions deployOptions, final BufferedReader br, final PrintStream out) { try { DeployAdmin deployAdmin = (DeployAdmin)CLI.getInstance().getServiceFinder().getPreparedAdmin(item.service); Boolean wait = (Boolean) CLI.getInstance().settings.get(CLI.DEPLOY_BLOCK); if (deployAdmin.hasDeployed(deploy.getName())) { if (deployOptions.update()) { try { out.print("The [" + deploy.getName() + "] is currently deployed, updating ...\n"); OperationalStringManager mgr = deployAdmin.getOperationalStringManager(deploy.getName()); mgr.update(deploy); } catch (Exception e) { e.printStackTrace(); return ("Exception "+e.getClass()+":"+e.getLocalizedMessage()+", check log for details"); } } else { if (deployOptions.noPrompt()) { return ("The [" + deploy.getName() + "] is currently deployed, interactive mode disabled, " + "returning"); } out.print("The ["+deploy.getName()+"] is currently deployed, update the deployment? [y/n] "); BufferedReader reader = br; try { if (reader == null) reader = new BufferedReader(new InputStreamReader(System.in)); String response = reader.readLine(); if (response == null) { return (""); } if (response.startsWith("y") || response.startsWith("Y")) { OperationalStringManager mgr = deployAdmin.getOperationalStringManager(deploy.getName()); mgr.update(deploy); return ("Updated"); } else { return ("Skipped"); } } catch (Exception e) { e.printStackTrace(); return ("Exception "+e.getClass()+":"+e.getLocalizedMessage()+", check log for details"); } } } else { if (deployOptions.getDeployTimeout() > 0 && wait) { ServiceProvisionNotification spn = CLI.getInstance().provisionNotifier; deployAdmin.deploy(deploy, spn.getServiceProvisionListener()); long t0 = System.currentTimeMillis(); out.println("Deploying [" + ServiceProvisionNotification.getDeploymentNames(deploy) + "], " + "total services ["+ServiceProvisionNotification.sumUpServices(deploy) + "] ..."); spn.notify( ServiceProvisionNotification.sumUpServices(deploy), deployOptions.getDeployTimeout()); long t1 = System.currentTimeMillis(); return ((deployOptions.verbose ? "Deployment notification time " +(t1 - t0) + " millis, Command completed" : "")); } else { deployAdmin.deploy(deploy, null); } } return ((deployOptions.verbose ? "Command completed" : "")); } catch (Exception e) { e.printStackTrace(); return ("Problem deploying [" + deploy.getName() + "], " + "Exception : " + e.getLocalizedMessage()); } } /** * Deploy an OAR using a selected monitor * * @param item The ServiceItem * @param deployName The OAR or artifact name * @param deployOptions Deploy options * @param out A printStream for output * @return A String for the completed command */ String deploy(final ServiceItem item, final String deployName, final DeployOptions deployOptions, final PrintStream out) { boolean isArtifact = false; try { new Artifact(deployName); isArtifact = true; } catch(Exception e) { /**/ } OperationalString toDeploy = null; Webster embeddedWebster = null; URL oarUrl = null; //String oarUrl = null; try { if(!isArtifact) { try { oarUrl = new URL(deployName); } catch(MalformedURLException e) { File oarFile = getDeploymentFile(deployName); OAR oar = new OAR(oarFile); embeddedWebster = new Webster(0, oarFile.getParentFile().getAbsolutePath()); toDeploy = oar.loadOperationalStrings()[0]; oarUrl = new URL("http://"+embeddedWebster.getAddress()+":"+embeddedWebster.getPort()+"/"+oarFile.getName()); } System.out.println("===> "+oarUrl); } } catch (Exception e) { e.printStackTrace(); return("Problem resolving ["+deployName+"], Exception : "+e.getLocalizedMessage()); } try { DeployAdmin deployAdmin = (DeployAdmin)CLI.getInstance().getServiceFinder().getPreparedAdmin(item.service); Boolean wait = (Boolean)CLI.getInstance().settings.get(CLI.DEPLOY_BLOCK); if(deployOptions.getDeployTimeout()>0 && wait) { ServiceProvisionNotification spn = CLI.getInstance().provisionNotifier; String label = "Artifact"; if(isArtifact) { deployAdmin.deploy(deployName, spn.getServiceProvisionListener()); } else { label = "OAR"; try{ //deployAdmin.deploy(toDeploy, spn.getServiceProvisionListener()); deployAdmin.deploy(oarUrl, spn.getServiceProvisionListener()); } finally { if(embeddedWebster!=null) embeddedWebster.terminate(); } } long t0 = System.currentTimeMillis(); out.println("Deploying "+label+" ["+deployName+"] ..."); spn.notify(1, deployOptions.getDeployTimeout()); long t1 = System.currentTimeMillis(); return((deployOptions.verbose? "Deployment notification time "+(t1-t0)+" millis, Command completed":"")); } else { if(isArtifact) deployAdmin.deploy(deployName, null); else deployAdmin.deploy(toDeploy, null); } return((deployOptions.verbose?"Command completed":"")); } catch (Exception e) { e.printStackTrace(); return("Problem deploying ["+deployName+"], Exception : "+e.getLocalizedMessage()); } } /* * Print the request to the operator */ void printRequest(final PrintStream out) { out.print("Choose a Provision Monitor for " + "deployment or \"c\" to cancel : "); } /** * @return Get the usage */ public String getUsage() { StringBuilder b = new StringBuilder(); b.append("\n"); b.append("usage: deploy opstring " + "[-t=deploy-timeout] " + "[-r=repository][;repository]]" + "[-iuv]"); b.append("\n"); b.append("\n"); b.append("-i\tTurns off interactive prompting"); b.append("\n"); b.append("-u\tAutomatically update deployments"); b.append("\n"); b.append("-v\tVerbose mode"); b.append("\n"); b.append("-t\tTime in milliseconds to wait for deployment status"); b.append("\n"); b.append("-r\tRepositories to use for the resolution of artifacts"); b.append("\n"); return (b.toString()); } } static class DeployOptions { boolean noPrompt; long deployTimeout; boolean verbose; boolean update; String repositories; long getDeployTimeout() { return (deployTimeout); } boolean noPrompt() { return (noPrompt); } boolean update() { return (update); } } /** * Manages undeployments */ public static class UndeployHandler implements OptionHandler { @SuppressWarnings ("unchecked") public String process(final String input, final BufferedReader br, final PrintStream out) { if (out == null) throw new IllegalArgumentException("Must have an output PrintStream"); StringTokenizer tok = new StringTokenizer(input); String deployment = null; boolean verbose = false; if (tok.countTokens() > 1) { /* First token is "undeploy" */ tok.nextToken(); /* Next token is the opstring */ deployment = tok.nextToken(); } ServiceItem[] items = CLI.getInstance().finder.findMonitors(null, null, verbose); if (items.length == 0) return ("No Provision Monitor instances discovered\n"); BufferedReader reader = br; if (deployment == null) { if (reader == null) reader = new BufferedReader(new InputStreamReader(System.in)); Map<String, DeployAdmin> map = getDeployedOpStrings(items); if (map.isEmpty()) { return "Nothing is currently deployed\n"; } int i = 1; Map.Entry<String, DeployAdmin>[] entries = map.entrySet().toArray(new Map.Entry[map.size()]); for (Map.Entry<String, DeployAdmin> entry : entries) { out.println("[" + (i++) + "] " + entry.getKey()); } out.println(); printRequest(out); while (true) { try { String response = reader.readLine(); if (response == null) { break; } if (response.equals("c")) break; try { int num = Integer.parseInt(response); if (num < 1 || num > (items.length + 1)) { printRequest(out); } else { try { String opStringName = entries[num - 1].getKey(); DeployAdmin dAdmin = entries[num - 1].getValue(); dAdmin.undeploy(opStringName); out.println("Command successful"); } catch (Exception e) { return ("Problem undeploying " + deployment + ", " + "Exception :" + e.getClass().getName() + ": " + e.getLocalizedMessage()); } } break; } catch (NumberFormatException e) { out.println("Invalid choice [" + response + "]"); printRequest(out); } } catch (IOException e) { e.printStackTrace(); } } return (""); } //OperationalString toUndeploy = null; String undeployName = null; try { new Artifact(deployment); undeployName = deployment; } catch(Exception e) { /* */ } if (deployment.endsWith("oar")) { try { File oarFile = getDeploymentFile(deployment); OAR oar = new OAR(oarFile); OperationalString toUndeploy = oar.loadOperationalStrings()[0]; undeployName = toUndeploy.getName(); } catch (Exception e) { return ("Problem loading [" + deployment + "], " + "Exception : " + e.getLocalizedMessage() + "\n"); } } if(undeployName==null) { try { OperationalString toUndeploy = loadDeployment(deployment); if (toUndeploy == null) { return (deployment + ": Cannot find file\n"); } undeployName = toUndeploy.getName(); } catch (Exception e) { return ("Problem loading [" + deployment + "], " + "Exception : " + e.getLocalizedMessage() + "\n"); } } try { DeployAdmin dAdmin = (DeployAdmin) CLI.getInstance().getServiceFinder().getPreparedAdmin(items[0].service); try { dAdmin.undeploy(undeployName); out.println("Command successful"); } catch(OperationalStringException e) { if(e.getMessage().startsWith("No deployment for")) { return ("Command failed, no active deployment for " + deployment); } else { return ("Problem undeploying " + deployment + ", " + "Exception :" + e.getClass().getName() + ": " + e.getLocalizedMessage()); } } catch (Exception e) { return ("Problem undeploying " + deployment + ", " + "Exception :" + e.getClass().getName() + ": " + e.getLocalizedMessage()); } } catch (Exception e) { return ("Problem undeploying " + deployment + ", " + "Exception :" + e.getClass().getName() + ": " + e.getLocalizedMessage()); } return (""); } /* * Print the request to the operator */ void printRequest(final PrintStream out) { out.print("Enter the OperationalString to undeploy " + "or \"c\" to cancel : "); } public String getUsage() { return ("usage: undeploy [opstring]\n"); } } static Map<String, DeployAdmin> getDeployedOpStrings(final ServiceItem[] items) { Map<String, DeployAdmin> map = new HashMap<String, DeployAdmin>(); for (ServiceItem item : items) { try { DeployAdmin deployAdmin = (DeployAdmin) CLI.getInstance().getServiceFinder(). getPreparedAdmin(item.service); OperationalStringManager[] opMgrs = deployAdmin.getOperationalStringManagers(); for (OperationalStringManager opMgr : opMgrs) { OperationalString opString = opMgr.getOperationalString(); if (opMgr.isManaging()) { map.put(opString.getName(), deployAdmin); } } } catch (Exception e) { e.printStackTrace(); } } return map; } /** * Manages redeployments */ public static class RedeployHandler implements OptionHandler { public String process(final String input, final BufferedReader br, final PrintStream out) { if (out == null) throw new IllegalArgumentException("Must have an output PrintStream"); StringTokenizer tok = new StringTokenizer(input); String deployment; boolean clean = false; long delay = 0; if (tok.countTokens() >= 2) { /* First token is "redeploy" */ tok.nextToken(); /* Next token must be the opstring */ deployment = tok.nextToken(); while (tok.hasMoreTokens()) { String value = tok.nextToken(); if (value.equals("clean")) { clean = true; } else if (value.startsWith("delay")) { StringTokenizer tok1 = new StringTokenizer(value, " ="); if (tok1.countTokens() < 2) return (getUsage()); /* First token will be "delay" */ tok1.nextToken(); /* Next token must be the timeout value */ value = tok1.nextToken(); try { delay = Long.parseLong(value); } catch (NumberFormatException e) { return (getUsage()); } } } } else { return (getUsage()); } if (deployment == null) { return (getUsage()); } OperationalString deploy; try { deploy = loadDeployment(deployment); if (deploy == null) { return (deployment + ": Cannot find file \n"); } } catch (Exception e) { return ("Problem loading [" + deployment + "], " + "Exception : " + e.getLocalizedMessage() + "\n"); } ServiceItem[] items = CLI.getInstance().finder.findMonitors(null, null); if (items.length == 0) return ("No Provision Monitor instances discovered\n"); OperationalStringManager primary = findOperationalStringManager(items, deploy); if (primary != null) { try { ServiceProvisionNotification spn = CLI.getInstance().provisionNotifier; primary.redeploy(null, null, clean, delay, spn.getServiceProvisionListener()); out.println("Command completed"); } catch (Exception e) { return ("Problem redeploying " + deployment + ", " + "Exception :" + e.getClass().getName() + ": " + e.getLocalizedMessage()); } } else { return ("Command failed, no active deployment for " +deployment); } return (""); } public String getUsage() { return ("usage: redeploy opstring [clean] [delay=millis-to-delay]\n"); } } /** * Load an OperationalString * * @param deployment The name of the file to load * @return An OperationalString * * @throws Exception If there are any errors */ static OperationalString loadDeployment(final String deployment) throws Exception { OperationalString deploy = null; File deployFile = getDeploymentFile(deployment); if (deployFile.exists()) { OpStringLoader opStringLoader = new OpStringLoader(new GroovyClassLoader(CLI.class.getClassLoader())); OperationalString[] opstrings = opStringLoader.parseOperationalString(deployFile); deploy = opstrings[0]; } return (deploy); } /** * Get the file to deploy from a file name * * @param deployment The name of the file to load * @return An OperationalString representing to loaded deployment * * @throws Exception If there are any errors */ static File getDeploymentFile(final String deployment) throws Exception { File deployFile; if (deployment.startsWith(File.separator)) { deployFile = new File(deployment); } else if (deployment.contains(":")) { deployFile = new File(deployment); } else if (deployment.startsWith("~/")) { String toDeploy = deployment.substring(2); deployFile = new File(System.getProperty("user.home")+File.separator + toDeploy); } else { deployFile = new File(CLI.getInstance().currentDir.getCanonicalPath()+File.separator+deployment); } return (deployFile); } /** * Find the primary OperationalStringManager for a loaded deployment * * @param items ServiceItems to iterate across * @param deploy The OperationalString * @return The primary OperationalStringManager */ static OperationalStringManager findOperationalStringManager(final ServiceItem[] items, final OperationalString deploy) { OperationalStringManager primary = null; for (ServiceItem item : items) { try { DeployAdmin deployAdmin = (DeployAdmin) CLI.getInstance().getServiceFinder().getPreparedAdmin(item.service); OperationalStringManager[] opMgrs = deployAdmin.getOperationalStringManagers(); for (OperationalStringManager opMgr : opMgrs) { OperationalString opString = opMgr.getOperationalString(); if (opString.getName().equals(deploy.getName()) && opMgr.isManaging()) { primary = opMgr; break; } } } catch (Exception e) { e.printStackTrace(); } } return (primary); } }