package argos.bangbang; import java.io.File; import java.io.IOException; import java.util.ArrayList; import java.util.List; import java.util.logging.Level; import java.util.logging.Logger; import javax.management.Notification; import org.mortbay.jetty.Server; import org.mortbay.jetty.deployer.WebAppDeployer; import org.mortbay.jetty.handler.ContextHandler; import org.mortbay.jetty.handler.ContextHandlerCollection; import org.mortbay.jetty.handler.DefaultHandler; import org.mortbay.jetty.handler.HandlerCollection; import org.mortbay.jetty.handler.HandlerList; import org.mortbay.jetty.webapp.WebAppContext; import argos.annotation.Description; import argos.annotation.Impact; import argos.annotation.Init; import argos.annotation.NotificationHandler; import argos.annotation.RemoveInstrumentation; import argos.annotation.Unload; import argos.config.Config; import argos.deploy.ComponentManager; import argos.deploy.JarClassloader; import argos.metadata.ServiceMetaInfo; import argos.naming.NamingService; import argos.util.Util; @Description("Adds web server and servlet/jsp support to Argos") public class Jetty { private static final Logger logger = Logger.getLogger(Jetty.class.getName()); private Server jettyServer; private int httpPort; private List currentDirs; ContextHandlerCollection col; @Init @Impact(Impact.ACTION) @Description("Starts the jetty web server") public void start() throws Exception { currentDirs = new ArrayList(); jettyServer = new Server(httpPort); col = new ContextHandlerCollection(); ContextHandler con = new WebAppContext(Config.get(Config.DEFAULT_DEPLOY_FOLDER) + "/.", "/"); con.setClassLoader(JarClassloader.getInstance()); col.addHandler(con); HandlerCollection handlers = new HandlerCollection(); handlers.addHandler(col); handlers.addHandler(new DefaultHandler()); jettyServer.addHandler(handlers); //Start jetty in its own thread JettyWorker worker = new JettyWorker(); worker.start(); } @Unload @Impact(Impact.ACTION) @Description("Stops the jetty web server") public void unload() { if(jettyServer != null) { try { jettyServer.stop(); } catch(Exception e) { logger.log(Level.SEVERE, "Exception while shutting down jetty 6: " + e.getMessage(), e); } } for(File file : currentDirs) { Util.cleanDir(file); file.delete(); logger.info("Removed directory " + file.getAbsolutePath()); } } @RemoveInstrumentation @NotificationHandler public void handler(Notification not) { if(handle(not)) { ServiceMetaInfo service = NamingService.getInstance().getService(not.getMessage()); if(service == null) { logger.severe("Unable to find service " + not.getMessage()); return; } String dir = Config.get(Config.DEFAULT_DEPLOY_FOLDER) + "/" + service.getName(); File tempDir = new File(dir); tempDir.mkdir(); if(not.getType().equals(ComponentManager.SERVICE_STARTED)) { try { int count = 0; List files = Util.extractFromJar(service.getFile(), "web", dir, true); count += files.size(); if(files.size() > 0) { logger.info("Web files exported to /" + service.getName()); addContext(service); } files = Util.extractFromJar(service.getFile(), "panels", dir, false); count += files.size(); if(files.size() > 0) { logger.info("Panel files exported to /" + service.getName() + "/panels"); } if(count == 0) { tempDir.delete(); } else { currentDirs.add(tempDir); } } catch (IOException e) { logger.log(Level.SEVERE, "Unable to extract web files: " + e.getMessage(), e); } } else if(not.getType().equals(ComponentManager.SERVICE_STOPPED)) { Util.cleanDir(new File(dir)); tempDir.delete(); currentDirs.remove(tempDir); logger.info("Removed directory " + dir); } } } private void addContext(ServiceMetaInfo service) { ContextHandler con = new WebAppContext(Config.get(Config.DEFAULT_DEPLOY_FOLDER) + "/" + service.getName() + "/.", "/" + service.getName()); con.setClassLoader(JarClassloader.getInstance()); col.addHandler(con); try { col.stop(); col.start(); } catch (Exception e) { // TODO Auto-generated catch block e.printStackTrace(); } } private boolean handle(Notification not) { return (not.getType().equals(ComponentManager.SERVICE_STARTED) || not.getType().equals(ComponentManager.SERVICE_STOPPED)) && not.getMessage() != null; } public Server getJettyServer() { return jettyServer; } public int getHttpPort() { return httpPort; } public void setHttpPort(int httpPort) { this.httpPort = httpPort; } class JettyWorker extends Thread { public JettyWorker() { super("JettyWorker"); } public void run() { try { jettyServer.start(); jettyServer.join(); } catch (Exception e) { logger.log(Level.SEVERE, "Unable to start jetty 6: " + e.getMessage(), e); unload(); } } } }