org.glite.authz.common.http.JettyAdminServiceCLI.java Source code

Java tutorial

Introduction

Here is the source code for org.glite.authz.common.http.JettyAdminServiceCLI.java

Source

/*
 * Copyright (c) Members of the EGEE Collaboration. 2006-2010.
 * See http://www.eu-egee.org/partners/ for details on the copyright holders.
 *
 * 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.glite.authz.common.http;

import java.io.IOException;
import java.net.ConnectException;
import java.net.InetAddress;
import java.net.UnknownHostException;

import org.apache.commons.httpclient.HttpClient;
import org.apache.commons.httpclient.HttpStatus;
import org.apache.commons.httpclient.NameValuePair;
import org.apache.commons.httpclient.methods.GetMethod;
import org.glite.authz.common.util.Strings;
import org.opensaml.ws.soap.client.http.HttpClientBuilder;
import org.slf4j.LoggerFactory;

import ch.qos.logback.classic.Level;
import ch.qos.logback.classic.Logger;
import ch.qos.logback.classic.LoggerContext;

/**
 * A command line tool used to communicate with {@link JettyAdminService}.
 * 
 * Command line arguments are, in order:
 * <ul>
 * <li><em>hostname</em> - hostname to which to connect</li>
 * <li><em>port</em> - port to which to connect</li>
 * <li><em>command</em> - admin command to execute</li>
 * <li><em>password</em> - admin command password</li>
 * </ul>
 */
public class JettyAdminServiceCLI {

    /** Successful return code: {@value} . */
    public static final int RC_SUCCESS = 0;

    /** Bad command line arguments return code: {@value} . */
    public static final int RC_BAD_ARGUMENTS = 1;

    /** HTTP connection error return code: {@value} . */
    public static final int RC_CTX = 2;

    /** Invalid command return code: {@value} . */
    public static final int RC_INVALID_COMMAND = 3;

    /** Unauthorized return code: {@value} . */
    public static final int RC_UNAUTHORIZED = 4;

    /** Unknown error return code: {@value} . */
    public static final int RC_UNKNOWN = 100;

    /**
     * Run the admin client.
     * 
     * @param args command line arguments
     */
    public static void main(String[] args) {
        if (args.length < 3) {
            exit("Invalid command line arguments", RC_BAD_ARGUMENTS);
        }

        disableLibraryLogging();

        String host = parseHost(args[0]);
        int port = parsePort(args[1]);
        String command = parseCommand(args[2]);
        String password = null;

        if (args.length == 4) {
            password = Strings.safeTrimOrNullString(args[3]);
        }

        executeCommand(host, port, command, password);
        exit(null, RC_SUCCESS);
    }

    /** Disables logging messages from all dependent libraries. */
    private static void disableLibraryLogging() {
        LoggerContext lc = (LoggerContext) LoggerFactory.getILoggerFactory();
        Logger rootLogger = lc.getLogger(org.slf4j.Logger.ROOT_LOGGER_NAME);
        rootLogger.setLevel(Level.OFF);
    }

    /**
     * Parses the hostname command line argument. Checks that the argument is a valid hostname.
     * 
     * @param hostArgument the command line hostname argument
     * 
     * @return the hostname
     */
    private static String parseHost(String hostArgument) {
        try {
            InetAddress[] addresses = InetAddress.getAllByName(hostArgument);
            return addresses[0].getHostName();
        } catch (UnknownHostException e) {
            exit("The host argument is not a valid hostname or IP address", RC_BAD_ARGUMENTS);
        }

        return null;
    }

    /**
     * Parses the port command line argument. Checks that the port command line argument is a valid integer and between
     * 1 and 65535 (valid port numbers).
     * 
     * @param portArgument the command line port argument
     * 
     * @return the port
     */
    private static int parsePort(String portArgument) {
        try {
            int port = Integer.parseInt(portArgument);
            if (port < 1 || port > 65535) {
                exit("Port number is not valid", RC_BAD_ARGUMENTS);
            }
            return port;
        } catch (NumberFormatException e) {
            exit("Port number is not valid", RC_BAD_ARGUMENTS);
        }

        return 0;
    }

    /**
     * Parses the command command line argument. Checks that the argument is not null.
     * 
     * @param commandArgument the command line command argument
     * 
     * @return the command
     */
    private static String parseCommand(String commandArgument) {
        String argument = Strings.safeTrimOrNullString(commandArgument);
        if (argument == null) {
            exit("Command argument is not valid", RC_BAD_ARGUMENTS);
        }

        return argument;
    }

    /**
     * Executes the service command. Also checks to ensure the HTTP return code was 200.
     * 
     * @param host host to which to connect
     * @param port port to which to connect
     * @param command command sent to the admin service
     * @param password admin command password, may be null
     */
    private static void executeCommand(String host, int port, String command, String password) {
        HttpClientBuilder clientBuilder = new HttpClientBuilder();
        HttpClient httpClient = clientBuilder.buildClient();

        GetMethod getMethod = new GetMethod("http://" + host + ":" + port + "/" + command);
        if (password != null) {
            getMethod.setQueryString(new NameValuePair[] {
                    new NameValuePair(PasswordProtectFilter.PASSWORD_PARAM_NAME, password), });
        }

        try {
            httpClient.executeMethod(getMethod);
            String response = Strings.safeTrimOrNullString(getMethod.getResponseBodyAsString());
            if (response != null) {
                System.out.println(response);
            }
        } catch (ConnectException e) {
            exit("Unable to connect to " + host + ":" + port + ", perhaps the service is not running", RC_CTX);
        } catch (IOException e) {
            exit("Error executing service command:\n" + e.getMessage(), RC_CTX);
        }

        int statusCode = getMethod.getStatusCode();
        if (statusCode == HttpStatus.SC_OK) {
            return;
        } else if (statusCode == HttpStatus.SC_UNAUTHORIZED) {
            exit("you are not authorized to execute admin commands; invalid password", RC_UNAUTHORIZED);
        } else {
            exit("Service returned unexpected HTTP status code; " + statusCode, RC_UNKNOWN);
        }
    }

    /**
     * Prints the given message to STDERR and exits with the given status code.
     * 
     * @param message the message to output, may be null if nothing is to be printed
     * @param returnCode the return code to be given for the application
     */
    private static void exit(String message, int returnCode) {
        if (message != null) {
            System.err.println(message);
        }
        System.exit(returnCode);
    }
}