org.iipg.hurricane.jmx.client.JMXRequestHandler.java Source code

Java tutorial

Introduction

Here is the source code for org.iipg.hurricane.jmx.client.JMXRequestHandler.java

Source

package org.iipg.hurricane.jmx.client;

/*
 * Copyright 2009-2013 Roland Huss
 *
 * 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.
 */

import java.io.*;
import java.net.URI;
import java.net.URISyntaxException;
import java.nio.charset.Charset;
import java.util.List;
import java.util.Map;
import java.util.regex.Pattern;

import org.apache.http.*;
import org.apache.http.client.methods.*;
import org.apache.http.entity.StringEntity;
import org.json.simple.*;
import org.json.simple.parser.JSONParser;
import org.json.simple.parser.ParseException;

/**
 * Class doing the hard work of conversion between HTTP request/responses and
 * J4p request/responses.
 *
 * @author roland
 * @since Apr 25, 2010
 */
public abstract class JMXRequestHandler {

    // j4p agent URL for the agent server
    private URI serverUrl;

    // Optional default target configuration
    private JMXTargetConfig defaultTargetConfig;

    /**
     * Constructor
     *
     * @param pServerUrl URL to remote agent
     * @param pTargetConfig optional default target configuration for proxy requests
     */
    public JMXRequestHandler(String pServerUrl, JMXTargetConfig pTargetConfig) {
        try {
            serverUrl = new URI(pServerUrl);
            defaultTargetConfig = pTargetConfig;
        } catch (URISyntaxException e) {
            throw new IllegalArgumentException("Invalid URL " + pServerUrl, e);
        }
    }

    /**
     * Get the HttpRequest for executing the given single request
     *
     * @param pRequest request to convert
     * @param pPreferredMethod HTTP method preferred
     * @param pProcessingOptions optional map of processiong options
     * @return the request used with HttpClient to obtain the result.
     */
    public abstract HttpUriRequest getHttpRequest(JMXRequest pRequest, String pPreferredMethod,
            Map<JMXQueryParameter, String> pProcessingOptions)
            throws UnsupportedEncodingException, URISyntaxException;
    /*        String method = pPreferredMethod;
    if (method == null) {
        method = pRequest.getPreferredHttpMethod();
    }
    if (method == null) {
        method = doUseProxy(pRequest) ? HttpPost.METHOD_NAME : HttpGet.METHOD_NAME;
    }
    String queryParams = prepareQueryParameters(pProcessingOptions);
        
    // GET request
    if (method.equals(HttpGet.METHOD_NAME)) {
        if (doUseProxy(pRequest)) {
            throw new IllegalArgumentException("Proxy mode can only be used with POST requests");
        }
        List<String> parts = pRequest.getRequestParts();
        // If parts == null the request decides, that POST *must* be used
        if (parts != null) {
            String base = prepareBaseUrl(serverUrl);
            StringBuilder requestPath = new StringBuilder(base);
            for (String p : parts) {
                requestPath.append("/");
                requestPath.append(escape(p));
            }
            return new HttpGet(createRequestURI(requestPath.toString(),queryParams));
        }
    }
        
    // We are using a post method as fallback
    JSONObject requestContent = getJsonRequestContent(pRequest);
    HttpPost postReq = new HttpPost(createRequestURI(serverUrl.getPath(),queryParams));
    postReq.setEntity(new StringEntity(requestContent.toJSONString(),"utf-8"));
    return postReq;
        }*/

    protected boolean doUseProxy(JMXRequest pRequest) {
        return defaultTargetConfig != null || pRequest.getTargetConfig() != null;
    }

    protected String prepareBaseUrl(URI pUri) {
        String base = pUri.getPath();
        if (base == null) {
            return "/";
        } else if (!base.endsWith("/")) {
            return base + "/";
        } else {
            return base;
        }
    }

    /**
     * Get an HTTP Request for requesting multiples requests at once
     *
     * @param pRequests requests to put into a HTTP request
     * @return HTTP request to send to the server
     */
    public <T extends JMXRequest> HttpUriRequest getHttpRequest(List<T> pRequests,
            Map<JMXQueryParameter, String> pProcessingOptions)
            throws UnsupportedEncodingException, URISyntaxException {
        JSONArray bulkRequest = new JSONArray();
        String queryParams = prepareQueryParameters(pProcessingOptions);
        HttpPost postReq = new HttpPost(createRequestURI(serverUrl.getPath(), queryParams));
        for (T request : pRequests) {
            JSONObject requestContent = getJsonRequestContent(request);
            bulkRequest.add(requestContent);
        }
        postReq.setEntity(new StringEntity(bulkRequest.toJSONString(), "utf-8"));
        return postReq;
    }

    /**
     * Extract the complete JSON response out of a HTTP response
     *
     * @param pHttpResponse the resulting http response
     * @return JSON content of the answer
     */
    @SuppressWarnings("PMD.PreserveStackTrace")
    public JSONAware extractJsonResponse(HttpResponse pHttpResponse) throws IOException, ParseException {
        HttpEntity entity = pHttpResponse.getEntity();
        try {
            JSONParser parser = new JSONParser();
            Header contentEncoding = entity.getContentEncoding();
            if (contentEncoding != null) {
                return (JSONAware) parser.parse(
                        new InputStreamReader(entity.getContent(), Charset.forName(contentEncoding.getValue())));
            } else {
                return (JSONAware) parser.parse(new InputStreamReader(entity.getContent()));
            }
        } finally {
            if (entity != null) {
                entity.consumeContent();
            }
        }
    }

    /**
     * Get the J4p Server URL
     * @return the URL to the Jolokia agent on the server side
     */
    public URI getServerUrl() {
        return serverUrl;
    }

    // =============================================================================================================

    protected JSONObject getJsonRequestContent(JMXRequest pRequest) {
        JSONObject requestContent = pRequest.toJson();
        if (defaultTargetConfig != null && pRequest.getTargetConfig() == null) {
            requestContent.put("target", defaultTargetConfig.toJson());
        }
        return requestContent;
    }

    // Escape a part for usage as part of URI path: / -> \/, \ -> \\
    private static final String ESCAPE = "!";
    private static final Pattern ESCAPE_PATTERN = Pattern.compile(ESCAPE);
    private static final Pattern SLASH_PATTERN = Pattern.compile("/");

    protected String escape(String pPart) {
        String ret = ESCAPE_PATTERN.matcher(pPart).replaceAll(ESCAPE + ESCAPE);
        return SLASH_PATTERN.matcher(ret).replaceAll(ESCAPE + "/");
    }

    // Create the request URI to use
    protected URI createRequestURI(String path, String queryParams) throws URISyntaxException {
        return new URI(serverUrl.getScheme(), serverUrl.getUserInfo(), serverUrl.getHost(), serverUrl.getPort(),
                path, queryParams, null);
    }

    // prepare query parameters
    protected String prepareQueryParameters(Map<JMXQueryParameter, String> pProcessingOptions) {
        if (pProcessingOptions != null && pProcessingOptions.size() > 0) {
            StringBuilder queryParams = new StringBuilder();
            for (Map.Entry<JMXQueryParameter, String> entry : pProcessingOptions.entrySet()) {
                queryParams.append(entry.getKey().getParam()).append("=").append(entry.getValue()).append("&");
            }
            return queryParams.substring(0, queryParams.length() - 1);
        } else {
            return null;
        }
    }
}