/* * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER. * * Copyright (c) 2004-2013 Oracle and/or its affiliates. All rights reserved. * * The contents of this file are subject to the terms of either the GNU * General Public License Version 2 only ("GPL") or the Common Development * and Distribution License("CDDL") (collectively, the "License"). You * may not use this file except in compliance with the License. You can * obtain a copy of the License at * http://glassfish.java.net/public/CDDL+GPL_1_1.html * or packager/legal/LICENSE.txt. See the License for the specific * language governing permissions and limitations under the License. * * When distributing the software, include this License Header Notice in each * file and include the License file at packager/legal/LICENSE.txt. * * GPL Classpath Exception: * Oracle designates this particular file as subject to the "Classpath" * exception as provided by Oracle in the GPL Version 2 section of the License * file that accompanied this code. * * Modifications: * If applicable, add the following below the License Header, with the fields * enclosed by brackets [] replaced by your own identifying information: * "Portions Copyright [year] [name of copyright owner]" * * Contributor(s): * If you wish your version of this file to be governed by only the CDDL or * only the GPL Version 2, indicate your decision by adding "[Contributor] * elects to include this software in this distribution under the [CDDL or GPL * Version 2] license." If you don't indicate a single choice of license, a * recipient has the option to distribute your version of this file under * either the CDDL, the GPL Version 2 or to extend the choice of license to * its licensees as provided above. However, if you add GPL Version 2 code * and therefore, elected the GPL Version 2 license, then the option applies * only if the new code is made subject to such option by the copyright * holder. */ package testutil; import com.sun.net.httpserver.HttpContext; import com.sun.net.httpserver.HttpExchange; import com.sun.net.httpserver.HttpHandler; import com.sun.net.httpserver.HttpServer; import com.sun.xml.ws.api.server.WSEndpoint; import com.sun.xml.ws.transport.http.DeploymentDescriptorParser; import com.sun.xml.ws.transport.http.DeploymentDescriptorParser.AdapterFactory; import com.sun.xml.ws.transport.http.HttpAdapter; import com.sun.xml.ws.transport.http.HttpAdapterList; import com.sun.xml.ws.transport.http.server.EndpointImpl; import com.sun.xml.ws.transport.local.FileSystemResourceLoader; import org.apache.tools.ant.Project; import org.apache.tools.ant.taskdefs.Copy; import org.apache.tools.ant.taskdefs.Expand; import org.apache.tools.ant.types.FileSet; import javax.xml.ws.Endpoint; import java.io.File; import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; import java.io.PrintWriter; import java.net.InetSocketAddress; import java.util.HashMap; import java.util.List; import java.util.Map; import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors; public class JaxwsHttpServer { private HttpServer appServer; private ExecutorService appExecutorService; private HttpServer adminServer; private ExecutorService adminExecutorService; private String sepChar; private File webappsDir; private File classesDir; private Map<String, WarInfo> deployedWARs; private boolean stopped; public JaxwsHttpServer() throws Exception { //String homeDir = System.getProperty ("user.dir"); String j2seServerDir = System.getProperty ("j2se.server.home"); System.out.println("Server dir="+j2seServerDir); sepChar = System.getProperty ("file.separator"); webappsDir = new File(j2seServerDir+sepChar+"webapps"); classesDir = new File(webappsDir, "classes"); System.out.println("webapps dir="+webappsDir.getAbsolutePath()); deployedWARs = new HashMap<String, WarInfo>(); start(); } public static void main(String[] args) throws Exception { new JaxwsHttpServer(); } public void createDeployThread() { new Thread(new DeployWAR()).start(); } public class WarInfo { } public synchronized boolean isStopped() { return stopped; } public synchronized void stopped() { stopped = true; } public class DeployWAR implements Runnable { public void run() { System.out.println("Starting DeployWAR thread"); while(!isStopped()) { try { File[] fileList = webappsDir.listFiles(); if (fileList != null) { for(File file : fileList) { if (file.isFile()) { deployWAR(file.getName()); } } } Thread.sleep(10000); } catch(Exception e) { e.printStackTrace(); } } System.out.println("Stopping DeployWAR thread"); } } public void deployWAR(String warName) throws Exception { try { if (deployedWARs.get(warName) == null) { try { System.out.println("Deploying "+warName); File warDirFile = expandWAR(warName); for(Adapter adapter : parseSunJaxws(warDirFile)) { createEndpoint(adapter, warDirFile); } } finally { // So that we don't try the same failed endpoint deployedWARs.put(warName, new WarInfo()); } } } catch(Throwable e) { e.printStackTrace(); } } public void deployWAR(HttpExchange msg, String war) throws Exception { deployWAR(war); writeStatus(msg, 200, "DEPLOY OK "+war); } private File expandWAR(String war) throws IOException { String warDirName = war.substring(0, war.length()-4); File warDirFile = new File(webappsDir, warDirName); if (warDirFile.exists()) { System.out.println("Already expanded "+war); return warDirFile; } System.out.println("Expanding war "+war); File src = new File(webappsDir, war); System.out.println("WAR path="+src.getAbsolutePath()); System.out.println("WAR dest path="+warDirFile.getAbsolutePath()); Expand e = new Expand(); e.setProject(new Project()); e.setDest(warDirFile); e.setSrc(src); e.setTaskType("unzip"); e.execute(); System.out.println("Copying classes for "+war); FileSet srcSet = new FileSet(); srcSet.setDir(new File(warDirFile, "WEB-INF/classes")); srcSet.setIncludes("**"); Copy copy = new Copy(); copy.setProject(new Project()); copy.setTodir(classesDir); copy.addFileset(srcSet); copy.setTaskType("copy"); copy.execute(); return warDirFile; } static final class Adapter extends HttpAdapter { final String urlPattern; public Adapter(WSEndpoint endpoint, String urlPattern, AdapterList owner ) { super(endpoint,owner); this.urlPattern = urlPattern; } } static final class AdapterList extends HttpAdapterList<Adapter> implements AdapterFactory<Adapter> { protected Adapter createHttpAdapter(String name, String urlPattern, WSEndpoint<?> endpoint) { return new Adapter(endpoint,urlPattern,this); } } private List<Adapter> parseSunJaxws(File warDirFile) throws Exception { File ddFile = new File(warDirFile, "WEB-INF"+sepChar+"sun-jaxws.xml"); System.out.println("dd file="+ddFile.getName()); /* String classesDir = userDir+sepChar+"webapps"+sepChar+warDir+sepChar+ "WEB-INF"+sepChar+"classes"; System.out.println("classes dir="+classesDir); URL url = new File(classesDir).toURL(); ClassLoader urlc = new URLClassLoader(new URL[] { url }, this.getClass().getClassLoader()); */ DeploymentDescriptorParser<Adapter> parser = new DeploymentDescriptorParser<Adapter>( this.getClass().getClassLoader(), new FileSystemResourceLoader(warDirFile), null, new AdapterList() ); return parser.parse(ddFile); } private void createEndpoint(Adapter adapter, File warDirFile) throws Exception { /* String url = "http://localhost:8080/"+warDir+endpointInfo.getUrlPattern(); EndpointFactory.newInstance ().publish (url, endpointInfo.getImplementor()); */ String urlPattern = adapter.urlPattern; if (urlPattern.endsWith("/*")) { urlPattern = urlPattern.substring(0, urlPattern.length() - 2); } String warDirName = warDirFile.getName(); String contextRoot = "/"+warDirName+urlPattern; System.out.println("Context Root="+contextRoot); HttpContext context = appServer.createContext (contextRoot); // Creating endpoint from backdoor (and this publishes it, too) Endpoint endpoint = new EndpointImpl(adapter.getEndpoint(),context); //// set MTOM //if (binding instanceof SOAPBinding) { // ((SOAPBinding)endpoint.getBinding()).setMTOMEnabled(((SOAPBinding)binding).isMTOMEnabled()); // ((SOAPBinding)endpoint.getBinding()).setRoles(((SOAPBinding)binding).getRoles()); //} } public void collectMetadata(File wsdlDirFile, List<File> metadataFile) { File[] files = wsdlDirFile.listFiles(); if (files == null) { return; } for(File file : files) { if (file.isDirectory()) { collectMetadata(file, metadataFile); continue; } metadataFile.add(file); } } public void undeployWAR(HttpExchange msg, String war) throws IOException { System.out.println("Undeploy war="+war); writeStatus(msg, 200, "UNDEPLOY OK "+war); } public void stop(HttpExchange msg) throws IOException { System.out.println("Stop "); stopped(); appServer.stop(2); appExecutorService.shutdown(); System.out.println("AppServer Stopped "); writeStatus(msg, 200, "STOP OK "); adminServer.stop(2); adminExecutorService.shutdown(); System.out.println("AdminServer Stopped "); } private void startAppServer() throws Exception { appServer = HttpServer.create(new InetSocketAddress(8080), 5); appExecutorService = Executors.newFixedThreadPool(5); appServer.setExecutor(appExecutorService); appServer.start(); System.out.println("AppServer started"); } private void start() throws Exception { // Create App Server startAppServer(); // Create Admin Server startAdminServer(); // Create deploy Thread createDeployThread(); } public void startAdminServer() throws Exception { // Create admin server InetSocketAddress inetAddress = new InetSocketAddress(9999); adminServer = HttpServer.create(inetAddress, 5); adminExecutorService = Executors.newFixedThreadPool(5); adminServer.setExecutor(adminExecutorService); HttpContext context = adminServer.createContext("/admin"); context.setHandler(new HttpHandler() { public void handle(HttpExchange msg) { try { System.out.println("Received HTTP request:"+msg.getRequestURI()); String method = msg.getRequestMethod(); if (method.equals("GET")) { InputStream is = msg.getRequestBody(); readFully(is); is.close(); writeGetReply(msg); } else { System.out.println("****** METHOD not handled ***** "+method); } } catch(Exception e) { e.printStackTrace(); } finally { msg.close(); } } }); adminServer.start(); System.out.println("AdminServer started"); } protected void writeGetReply(HttpExchange msg) throws Exception { String queryString = msg.getRequestURI().getQuery(); System.out.println("queryString="+queryString); if (queryString.startsWith("deploy=")) { int index = queryString.indexOf("="); String warName = null; if (index != -1) { warName = queryString.substring(index+1); deployWAR(msg, warName); } else { writeStatus(msg, 200, "Don't know "+queryString); } } else if (queryString.startsWith("undeploy=")) { int index = queryString.indexOf("="); String warName = null; if (index != -1) { warName = queryString.substring(index+1); undeployWAR(msg, warName); } else { writeStatus(msg, 200, "Don't know "+queryString); } } else if (queryString.startsWith("stop")) { stop(msg); } else { writeStatus(msg, 200, "Don't know "+queryString); } } /* * writes 404 Not found error html page */ private void writeStatus(HttpExchange msg, int code, String message) throws IOException { msg.getResponseHeaders().add("Content-Type", "text/html"); msg.sendResponseHeaders(code, 0); OutputStream outputStream = msg.getResponseBody(); PrintWriter out = new PrintWriter(outputStream); out.println("<html><head><title>"); out.println("JaxwsHttpServer Status"); out.println("</title></head><body>"); out.println(message); out.println("</body></html>"); out.close(); } /* * Consumes the entire input stream */ private static void readFully(InputStream is) throws IOException { byte[] buf = new byte[1024]; if (is != null) { while (is.read(buf) != -1); } } }