All Downloads are FREE. Search and download functionalities are using the official Maven repository.

io.airlift.jmx.http.rpc.MBeanServerServlet Maven / Gradle / Ivy

/*
 * Copyright 2010 Proofpoint, Inc.
 *
 * 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 io.airlift.jmx.http.rpc;

import com.google.inject.Inject;
import jakarta.servlet.ServletException;
import jakarta.servlet.http.HttpServlet;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;

import javax.management.Attribute;
import javax.management.AttributeList;
import javax.management.MBeanServer;
import javax.management.ObjectName;
import javax.management.QueryExp;
import javax.management.remote.JMXServerErrorException;

import java.io.IOException;
import java.io.ObjectInputStream;

import static io.airlift.jmx.http.rpc.HttpMBeanServerRpc.createExceptionResponse;
import static io.airlift.jmx.http.rpc.HttpMBeanServerRpc.createSuccessResponse;
import static jakarta.servlet.http.HttpServletResponse.SC_BAD_REQUEST;
import static jakarta.servlet.http.HttpServletResponse.SC_INTERNAL_SERVER_ERROR;
import static jakarta.servlet.http.HttpServletResponse.SC_UNAUTHORIZED;

public class MBeanServerServlet
        extends HttpServlet
{
    private static final String BASE_PATH = "/v1/jmx/mbeanServer/";
    private final MBeanServer mbeanServer;
    private final HttpMBeanServerCredentials credentials;

    @Inject
    public MBeanServerServlet(MBeanServer mbeanServer, HttpMBeanServerCredentials credentials)
    {
        this.mbeanServer = mbeanServer;
        this.credentials = credentials;
    }

    @Override
    protected void doPost(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException
    {
        if (credentials != null) {
            if (!credentials.authenticate(HttpMBeanServerCredentials.fromBasicAuthHeader(request.getHeader("Authorization")))) {
                sendErrorResponse(response, SC_UNAUTHORIZED, new SecurityException("Invalid credentials"));
                return;
            }
        }

        String method = extractJmxMethodFromPath(request);
        if (method == null) {
            sendErrorResponse(response, SC_BAD_REQUEST, new NullPointerException("method is null"));
            return;
        }

        Object[] args;
        try {
            args = (Object[]) new ObjectInputStream(request.getInputStream()).readObject();
        }
        catch (Exception e) {
            sendErrorResponse(response, SC_BAD_REQUEST, new IllegalArgumentException("Request does not contain a serialized Object[]"));
            return;
        }

        try {
            Object result = null;
            if ("getMBeanInfo".equals(method)) {
                result = mbeanServer.getMBeanInfo((ObjectName) args[0]);
            }
            else if ("queryMBeans".equals(method)) {
                result = mbeanServer.queryMBeans((ObjectName) args[0], (QueryExp) args[1]);
            }
            else if ("queryNames".equals(method)) {
                result = mbeanServer.queryNames((ObjectName) args[0], (QueryExp) args[1]);
            }
            else if ("getAttribute".equals(method)) {
                result = mbeanServer.getAttribute((ObjectName) args[0], (String) args[1]);
            }
            else if ("getAttributes".equals(method)) {
                result = mbeanServer.getAttributes((ObjectName) args[0], (String[]) args[1]);
            }
            else if ("setAttribute".equals(method)) {
                mbeanServer.setAttribute((ObjectName) args[0], (Attribute) args[1]);
            }
            else if ("setAttributes".equals(method)) {
                result = mbeanServer.setAttributes((ObjectName) args[0], (AttributeList) args[1]);
            }
            else if ("invoke".equals(method)) {
                result = mbeanServer.invoke((ObjectName) args[0], (String) args[1], (Object[]) args[2], (String[]) args[3]);
            }
            else if ("getMBeanCount".equals(method)) {
                result = mbeanServer.getMBeanCount();
            }
            else if ("isRegistered".equals(method)) {
                result = mbeanServer.isRegistered((ObjectName) args[0]);
            }
            else if ("getObjectInstance".equals(method)) {
                result = mbeanServer.getObjectInstance((ObjectName) args[0]);
            }
            else if ("getDefaultDomain".equals(method)) {
                result = mbeanServer.getDefaultDomain();
            }
            else if ("getDomains".equals(method)) {
                result = mbeanServer.getDomains();
            }
            else if ("isInstanceOf".equals(method)) {
                result = mbeanServer.isInstanceOf((ObjectName) args[0], (String) args[1]);
            }
            else {
                sendErrorResponse(response, SC_BAD_REQUEST, new IllegalArgumentException("Unknown method " + method));
                return;
            }

            response.getOutputStream().write(createSuccessResponse(result));
        }
        catch (Exception e) {
            sendErrorResponse(response, SC_INTERNAL_SERVER_ERROR, e);
        }
        catch (Error e) {
            sendErrorResponse(response, SC_INTERNAL_SERVER_ERROR, new JMXServerErrorException("Internal error", e));
        }
    }

    private String extractJmxMethodFromPath(HttpServletRequest request)
    {
        String path = request.getRequestURI();
        if (!path.startsWith(BASE_PATH)) {
            return null;
        }
        path = path.substring("/v1/jmx/mbeanServer/".length());
        if (path.contains("/")) {
            return null;
        }
        return path;
    }

    private void sendErrorResponse(HttpServletResponse response, int status, Exception exception)
            throws IOException
    {
        response.setStatus(status);
        response.getOutputStream().write(createExceptionResponse(exception));
    }
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy