Java tutorial
package org.codehaus.mojo.tomcat; /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you 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. */ import org.apache.commons.codec.binary.Base64; import java.io.BufferedOutputStream; import java.io.IOException; import java.io.InputStream; import java.io.InputStreamReader; import java.io.OutputStream; import java.net.HttpURLConnection; import java.net.URL; import java.net.URLEncoder; /** * A Tomcat manager webapp invocation wrapper. * * @author Mark Hobson <markhobson@gmail.com> * @version $Id$ */ public class TomcatManager { // ---------------------------------------------------------------------- // Constants // ---------------------------------------------------------------------- /** * The charset to use when decoding Tomcat manager responses. */ private static final String MANAGER_CHARSET = "UTF-8"; // ---------------------------------------------------------------------- // Fields // ---------------------------------------------------------------------- /** * The full URL of the Tomcat manager instance to use. */ private URL url; /** * The username to use when authenticating with Tomcat manager. */ private String username; /** * The password to use when authenticating with Tomcat manager. */ private String password; /** * The URL encoding charset to use when communicating with Tomcat manager. */ private String charset; /** * The user agent name to use when communicating with Tomcat manager. */ private String userAgent; // ---------------------------------------------------------------------- // Constructors // ---------------------------------------------------------------------- /** * Creates a Tomcat manager wrapper for the specified URL that uses a username of <code>admin</code>, an empty * password and ISO-8859-1 URL encoding. * * @param url the full URL of the Tomcat manager instance to use */ public TomcatManager(URL url) { this(url, "admin"); } /** * Creates a Tomcat manager wrapper for the specified URL and username that uses an empty password and ISO-8859-1 * URL encoding. * * @param url the full URL of the Tomcat manager instance to use * @param username the username to use when authenticating with Tomcat manager */ public TomcatManager(URL url, String username) { this(url, username, ""); } /** * Creates a Tomcat manager wrapper for the specified URL, username and password that uses ISO-8859-1 URL encoding. * * @param url the full URL of the Tomcat manager instance to use * @param username the username to use when authenticating with Tomcat manager * @param password the password to use when authenticating with Tomcat manager */ public TomcatManager(URL url, String username, String password) { this(url, username, password, "ISO-8859-1"); } /** * Creates a Tomcat manager wrapper for the specified URL, username, password and URL encoding. * * @param url the full URL of the Tomcat manager instance to use * @param username the username to use when authenticating with Tomcat manager * @param password the password to use when authenticating with Tomcat manager * @param charset the URL encoding charset to use when communicating with Tomcat manager */ public TomcatManager(URL url, String username, String password, String charset) { this.url = url; this.username = username; this.password = password; this.charset = charset; } // ---------------------------------------------------------------------- // Public Methods // ---------------------------------------------------------------------- /** * Gets the full URL of the Tomcat manager instance. * * @return the full URL of the Tomcat manager instance */ public URL getURL() { return url; } /** * Gets the username to use when authenticating with Tomcat manager. * * @return the username to use when authenticating with Tomcat manager */ public String getUserName() { return username; } /** * Gets the password to use when authenticating with Tomcat manager. * * @return the password to use when authenticating with Tomcat manager */ public String getPassword() { return password; } /** * Gets the URL encoding charset to use when communicating with Tomcat manager. * * @return the URL encoding charset to use when communicating with Tomcat manager */ public String getCharset() { return charset; } /** * Gets the user agent name to use when communicating with Tomcat manager. * * @return the user agent name to use when communicating with Tomcat manager */ public String getUserAgent() { return userAgent; } /** * Sets the user agent name to use when communicating with Tomcat manager. * * @param userAgent the user agent name to use when communicating with Tomcat manager */ public void setUserAgent(String userAgent) { this.userAgent = userAgent; } /** * Deploys the specified WAR as a URL to the specified context path. * * @param path the webapp context path to deploy to * @param war the URL of the WAR to deploy * @return the Tomcat manager response * @throws TomcatManagerException if the Tomcat manager request fails * @throws IOException if an i/o error occurs */ public String deploy(String path, URL war) throws TomcatManagerException, IOException { return deploy(path, war, false); } /** * Deploys the specified WAR as a URL to the specified context path, optionally undeploying the webapp if it already * exists. * * @param path the webapp context path to deploy to * @param war the URL of the WAR to deploy * @param update whether to first undeploy the webapp if it already exists * @return the Tomcat manager response * @throws TomcatManagerException if the Tomcat manager request fails * @throws IOException if an i/o error occurs */ public String deploy(String path, URL war, boolean update) throws TomcatManagerException, IOException { return deploy(path, war, update, null); } /** * Deploys the specified WAR as a URL to the specified context path, optionally undeploying the webapp if it already * exists and using the specified tag name. * * @param path the webapp context path to deploy to * @param war the URL of the WAR to deploy * @param update whether to first undeploy the webapp if it already exists * @param tag the tag name to use * @return the Tomcat manager response * @throws TomcatManagerException if the Tomcat manager request fails * @throws IOException if an i/o error occurs */ public String deploy(String path, URL war, boolean update, String tag) throws TomcatManagerException, IOException { return deployImpl(path, null, war, null, update, tag); } /** * Deploys the specified WAR as a HTTP PUT to the specified context path. * * @param path the webapp context path to deploy to * @param war an input stream to the WAR to deploy * @return the Tomcat manager response * @throws TomcatManagerException if the Tomcat manager request fails * @throws IOException if an i/o error occurs */ public String deploy(String path, InputStream war) throws TomcatManagerException, IOException { return deploy(path, war, false); } /** * Deploys the specified WAR as a HTTP PUT to the specified context path, optionally undeploying the webapp if it * already exists. * * @param path the webapp context path to deploy to * @param war an input stream to the WAR to deploy * @param update whether to first undeploy the webapp if it already exists * @return the Tomcat manager response * @throws TomcatManagerException if the Tomcat manager request fails * @throws IOException if an i/o error occurs */ public String deploy(String path, InputStream war, boolean update) throws TomcatManagerException, IOException { return deploy(path, war, update, null); } /** * Deploys the specified WAR as a HTTP PUT to the specified context path, optionally undeploying the webapp if it * already exists and using the specified tag name. * * @param path the webapp context path to deploy to * @param war an input stream to the WAR to deploy * @param update whether to first undeploy the webapp if it already exists * @param tag the tag name to use * @return the Tomcat manager response * @throws TomcatManagerException if the Tomcat manager request fails * @throws IOException if an i/o error occurs */ public String deploy(String path, InputStream war, boolean update, String tag) throws TomcatManagerException, IOException { return deployImpl(path, null, null, war, update, tag); } /** * Deploys the specified context XML configuration to the specified context path. * * @param path the webapp context path to deploy to * @param config the URL of the context XML configuration to deploy * @return the Tomcat manager response * @throws TomcatManagerException if the Tomcat manager request fails * @throws IOException if an i/o error occurs */ public String deployContext(String path, URL config) throws TomcatManagerException, IOException { return deployContext(path, config, false); } /** * Deploys the specified context XML configuration to the specified context path, optionally undeploying the webapp * if it already exists. * * @param path the webapp context path to deploy to * @param config the URL of the context XML configuration to deploy * @param update whether to first undeploy the webapp if it already exists * @return the Tomcat manager response * @throws TomcatManagerException if the Tomcat manager request fails * @throws IOException if an i/o error occurs */ public String deployContext(String path, URL config, boolean update) throws TomcatManagerException, IOException { return deployContext(path, config, update, null); } /** * Deploys the specified context XML configuration to the specified context path, optionally undeploying the webapp * if it already exists and using the specified tag name. * * @param path the webapp context path to deploy to * @param config the URL of the context XML configuration to deploy * @param update whether to first undeploy the webapp if it already exists * @param tag the tag name to use * @return the Tomcat manager response * @throws TomcatManagerException if the Tomcat manager request fails * @throws IOException if an i/o error occurs */ public String deployContext(String path, URL config, boolean update, String tag) throws TomcatManagerException, IOException { return deployContext(path, config, null, update, tag); } /** * Deploys the specified context XML configuration and WAR as a URL to the specified context path. * * @param path the webapp context path to deploy to * @param config the URL of the context XML configuration to deploy * @param war the URL of the WAR to deploy * @return the Tomcat manager response * @throws TomcatManagerException if the Tomcat manager request fails * @throws IOException if an i/o error occurs */ public String deployContext(String path, URL config, URL war) throws TomcatManagerException, IOException { return deployContext(path, config, war, false); } /** * Deploys the specified context XML configuration and WAR as a URL to the specified context path, optionally * undeploying the webapp if it already exists. * * @param path the webapp context path to deploy to * @param config the URL of the context XML configuration to deploy * @param war the URL of the WAR to deploy * @param update whether to first undeploy the webapp if it already exists * @return the Tomcat manager response * @throws TomcatManagerException if the Tomcat manager request fails * @throws IOException if an i/o error occurs */ public String deployContext(String path, URL config, URL war, boolean update) throws TomcatManagerException, IOException { return deployContext(path, config, war, update, null); } /** * Deploys the specified context XML configuration and WAR as a URL to the specified context path, optionally * undeploying the webapp if it already exists and using the specified tag name. * * @param path the webapp context path to deploy to * @param config the URL of the context XML configuration to deploy * @param war the URL of the WAR to deploy * @param update whether to first undeploy the webapp if it already exists * @param tag the tag name to use * @return the Tomcat manager response * @throws TomcatManagerException if the Tomcat manager request fails * @throws IOException if an i/o error occurs */ public String deployContext(String path, URL config, URL war, boolean update, String tag) throws TomcatManagerException, IOException { return deployImpl(path, config, war, null, update, tag); } /** * Undeploys the webapp at the specified context path. * * @param path the webapp context path to undeploy * @return the Tomcat manager response * @throws TomcatManagerException if the Tomcat manager request fails * @throws IOException if an i/o error occurs */ public String undeploy(String path) throws TomcatManagerException, IOException { return invoke("/undeploy?path=" + URLEncoder.encode(path, charset)); } /** * Reloads the webapp at the specified context path. * * @param path the webapp context path to reload * @return the Tomcat manager response * @throws TomcatManagerException if the Tomcat manager request fails * @throws IOException if an i/o error occurs */ public String reload(String path) throws TomcatManagerException, IOException { return invoke("/reload?path=" + URLEncoder.encode(path, charset)); } /** * Starts the webapp at the specified context path. * * @param path the webapp context path to start * @return the Tomcat manager response * @throws TomcatManagerException if the Tomcat manager request fails * @throws IOException if an i/o error occurs */ public String start(String path) throws TomcatManagerException, IOException { return invoke("/start?path=" + URLEncoder.encode(path, charset)); } /** * Stops the webapp at the specified context path. * * @param path the webapp context path to stop * @return the Tomcat manager response * @throws TomcatManagerException if the Tomcat manager request fails * @throws IOException if an i/o error occurs */ public String stop(String path) throws TomcatManagerException, IOException { return invoke("/stop?path=" + URLEncoder.encode(path, charset)); } /** * Lists all the currently deployed web applications. * * @return the list of currently deployed applications * @throws TomcatManagerException if the Tomcat manager request fails * @throws IOException if an i/o error occurs */ public String list() throws TomcatManagerException, IOException { return invoke("/list"); } /** * Lists information about the Tomcat version, OS, and JVM properties. * * @return the server information * @throws TomcatManagerException if the Tomcat manager request fails * @throws IOException if an i/o error occurs */ public String getServerInfo() throws TomcatManagerException, IOException { return invoke("/serverinfo"); } /** * Lists all of the global JNDI resources. * * @return the list of all global JNDI resources * @throws TomcatManagerException if the Tomcat manager request fails * @throws IOException if an i/o error occurs */ public String getResources() throws TomcatManagerException, IOException { return getResources(null); } /** * Lists the global JNDI resources of the given type. * * @param type the class name of the resources to list, or <code>null</code> for all * @return the list of global JNDI resources of the given type * @throws TomcatManagerException if the Tomcat manager request fails * @throws IOException if an i/o error occurs */ public String getResources(String type) throws TomcatManagerException, IOException { StringBuffer buffer = new StringBuffer(); buffer.append("/resources"); if (type != null) { buffer.append("?type=" + URLEncoder.encode(type, charset)); } return invoke(buffer.toString()); } /** * Lists the security role names and corresponding descriptions that are available. * * @return the list of security role names and corresponding descriptions * @throws TomcatManagerException if the Tomcat manager request fails * @throws IOException if an i/o error occurs */ public String getRoles() throws TomcatManagerException, IOException { return invoke("/roles"); } /** * Lists the default session timeout and the number of currently active sessions for the given context path. * * @param path the context path to list session information for * @return the default session timeout and the number of currently active sessions * @throws TomcatManagerException if the Tomcat manager request fails * @throws IOException if an i/o error occurs */ public String getSessions(String path) throws TomcatManagerException, IOException { return invoke("/sessions?path=" + URLEncoder.encode(path, charset)); } // ---------------------------------------------------------------------- // Protected Methods // ---------------------------------------------------------------------- /** * Invokes Tomcat manager with the specified command. * * @param path the Tomcat manager command to invoke * @return the Tomcat manager response * @throws TomcatManagerException if the Tomcat manager request fails * @throws IOException if an i/o error occurs */ protected String invoke(String path) throws TomcatManagerException, IOException { return invoke(path, null); } /** * Invokes Tomcat manager with the specified command and content data. * * @param path the Tomcat manager command to invoke * @param data an input stream to the content data * @return the Tomcat manager response * @throws TomcatManagerException if the Tomcat manager request fails * @throws IOException if an i/o error occurs */ protected String invoke(String path, InputStream data) throws TomcatManagerException, IOException { HttpURLConnection connection = (HttpURLConnection) new URL(url + path).openConnection(); connection.setAllowUserInteraction(false); connection.setDoInput(true); connection.setUseCaches(false); if (data == null) { connection.setDoOutput(false); connection.setRequestMethod("GET"); } else { connection.setDoOutput(true); connection.setRequestMethod("PUT"); connection.setRequestProperty("Content-Type", "application/octet-stream"); } if (userAgent != null) { connection.setRequestProperty("User-Agent", userAgent); } connection.setRequestProperty("Authorization", toAuthorization(username, password)); connection.connect(); if (data != null) { pipe(data, connection.getOutputStream()); } String response = toString(connection.getInputStream(), MANAGER_CHARSET); if (!response.startsWith("OK -")) { throw new TomcatManagerException(response); } return response; } // ---------------------------------------------------------------------- // Private Methods // ---------------------------------------------------------------------- /** * Deploys the specified WAR. * * @param path the webapp context path to deploy to * @param config the URL of the context XML configuration to deploy, or null for none * @param war the URL of the WAR to deploy, or null to use <code>data</code> * @param data an input stream to the WAR to deploy, or null to use <code>war</code> * @param update whether to first undeploy the webapp if it already exists * @param tag the tag name to use * @return the Tomcat manager response * @throws TomcatManagerException if the Tomcat manager request fails * @throws IOException if an i/o error occurs */ private String deployImpl(String path, URL config, URL war, InputStream data, boolean update, String tag) throws TomcatManagerException, IOException { StringBuffer buffer = new StringBuffer("/deploy"); buffer.append("?path=").append(URLEncoder.encode(path, charset)); if (config != null) { buffer.append("&config=").append(URLEncoder.encode(config.toString(), charset)); } if (war != null) { buffer.append("&war=").append(URLEncoder.encode(war.toString(), charset)); } else { // for Tomcat 5.0.27 buffer.append("&war="); } if (update) { buffer.append("&update=true"); } if (tag != null) { buffer.append("&tag=").append(URLEncoder.encode(tag, charset)); } return invoke(buffer.toString(), data); } /** * Gets the HTTP Basic Authorization header value for the supplied username and password. * * @param username the username to use for authentication * @param password the password to use for authentication * @return the HTTP Basic Authorization header value */ private String toAuthorization(String username, String password) { StringBuffer buffer = new StringBuffer(); buffer.append(username).append(':'); if (password != null) { buffer.append(password); } return "Basic " + new String(Base64.encodeBase64(buffer.toString().getBytes())); } /** * Reads all the data from the specified input stream and writes it to the specified output stream. Both streams are * also closed. * * @param in the input stream to read from * @param out the output stream to write to * @throws IOException if an i/o error occurs */ private void pipe(InputStream in, OutputStream out) throws IOException { out = new BufferedOutputStream(out); int n; byte[] bytes = new byte[1024 * 4]; while ((n = in.read(bytes)) != -1) { out.write(bytes, 0, n); } out.flush(); out.close(); in.close(); } /** * Gets the data from the specified input stream as a string using the specified charset. * * @param in the input stream to read from * @param charset the charset to use when constructing the string * @return a string representation of the data read from the input stream * @throws IOException if an i/o error occurs */ private String toString(InputStream in, String charset) throws IOException { InputStreamReader reader = new InputStreamReader(in, charset); StringBuffer buffer = new StringBuffer(); char[] chars = new char[1024]; int n; while ((n = reader.read(chars, 0, chars.length)) != -1) { buffer.append(chars, 0, n); } return buffer.toString(); } }