org.apache.geode.management.internal.web.controllers.ShellCommandsController.java Source code

Java tutorial

Introduction

Here is the source code for org.apache.geode.management.internal.web.controllers.ShellCommandsController.java

Source

/*
 * 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.
 */
package org.apache.geode.management.internal.web.controllers;

import static org.apache.commons.io.IOUtils.toInputStream;
import static org.apache.geode.management.internal.web.util.UriUtils.decode;

import java.io.FileInputStream;
import java.io.IOException;
import java.nio.file.Path;
import java.util.Set;

import javax.management.AttributeNotFoundException;
import javax.management.InstanceNotFoundException;
import javax.management.MBeanException;
import javax.management.MBeanServer;
import javax.management.MalformedObjectNameException;
import javax.management.ObjectName;
import javax.management.ReflectionException;

import org.apache.commons.io.FileUtils;
import org.apache.commons.lang.ArrayUtils;
import org.springframework.core.io.InputStreamResource;
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpStatus;
import org.springframework.http.MediaType;
import org.springframework.http.ResponseEntity;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.multipart.MultipartFile;

import org.apache.geode.internal.GemFireVersion;
import org.apache.geode.internal.lang.ObjectUtils;
import org.apache.geode.internal.util.IOUtils;
import org.apache.geode.management.cli.Result;
import org.apache.geode.management.internal.cli.result.CommandResult;
import org.apache.geode.management.internal.cli.result.ResultBuilder;
import org.apache.geode.management.internal.web.domain.QueryParameterSource;
import org.apache.geode.management.internal.web.util.ConvertUtils;

/**
 * The ShellCommandsController class implements GemFire REST API calls for Gfsh Shell Commands.
 *
 * @see org.springframework.stereotype.Controller
 * @see org.springframework.web.bind.annotation.RequestBody
 * @see org.springframework.web.bind.annotation.RequestMapping
 * @see org.springframework.web.bind.annotation.RequestMethod
 * @see org.springframework.web.bind.annotation.RequestParam
 * @see org.springframework.web.bind.annotation.ResponseBody
 * @since GemFire 8.0
 */
@Controller("shellController")
@RequestMapping(AbstractCommandsController.REST_API_VERSION)
@SuppressWarnings("unused")
public class ShellCommandsController extends AbstractCommandsController {
    @RequestMapping(method = { RequestMethod.GET, RequestMethod.POST }, value = "/management/commands")
    public ResponseEntity<InputStreamResource> command(@RequestParam(value = "cmd") String command,
            @RequestParam(value = "resources", required = false) MultipartFile[] fileResource) throws IOException {
        String result = processCommand(decode(command), getEnvironment(), ConvertUtils.convert(fileResource));
        return getResponse(result);
    }

    @RequestMapping(method = RequestMethod.GET, value = "/mbean/attribute")
    public ResponseEntity<?> getAttribute(@RequestParam("resourceName") final String resourceName,
            @RequestParam("attributeName") final String attributeName)
            throws AttributeNotFoundException, MBeanException, ReflectionException, InstanceNotFoundException,
            IOException, MalformedObjectNameException {
        // Exceptions are caught by the @ExceptionHandler AbstractCommandsController.handleAppException
        MBeanServer mBeanServer = getMBeanServer();
        ObjectName objectName = ObjectName.getInstance(decode(resourceName));
        final Object attributeValue = mBeanServer.getAttribute(objectName, decode(attributeName));
        byte[] serializedResult = IOUtils.serializeObject(attributeValue);
        return new ResponseEntity<>(serializedResult, HttpStatus.OK);
    }

    @RequestMapping(method = RequestMethod.POST, value = "/mbean/operation")
    public ResponseEntity<?> invoke(@RequestParam("resourceName") final String resourceName,
            @RequestParam("operationName") final String operationName,
            @RequestParam(value = "signature", required = false) String[] signature,
            @RequestParam(value = "parameters", required = false) Object[] parameters)
            throws MalformedObjectNameException, MBeanException, InstanceNotFoundException, ReflectionException,
            IOException {
        // Exceptions are caught by the @ExceptionHandler AbstractCommandsController.handleAppException
        signature = (signature != null ? signature : ArrayUtils.EMPTY_STRING_ARRAY);
        parameters = (parameters != null ? parameters : ObjectUtils.EMPTY_OBJECT_ARRAY);
        MBeanServer mBeanServer = getMBeanServer();
        ObjectName objectName = ObjectName.getInstance(decode(resourceName));
        final Object result = mBeanServer.invoke(objectName, decode(operationName), parameters, signature);
        byte[] serializedResult = IOUtils.serializeObject(result);
        return new ResponseEntity<>(serializedResult, HttpStatus.OK);
    }

    @RequestMapping(method = RequestMethod.POST, value = "/mbean/query")
    public ResponseEntity<?> queryNames(@RequestBody final QueryParameterSource query) throws IOException {
        // Exceptions are caught by the @ExceptionHandler AbstractCommandsController.handleAppException
        final Set<ObjectName> objectNames = getMBeanServer().queryNames(query.getObjectName(),
                query.getQueryExpression());
        return new ResponseEntity<>(IOUtils.serializeObject(objectNames), HttpStatus.OK);
    }

    @RequestMapping(method = { RequestMethod.GET, RequestMethod.HEAD }, value = "/ping")
    public ResponseEntity<String> ping() {
        return new ResponseEntity<>("pong", HttpStatus.OK);
    }

    @RequestMapping(method = RequestMethod.GET, value = "/version")
    @ResponseBody
    public String version() {
        return GemFireVersion.getProductName().concat("/").concat(GemFireVersion.getGemFireVersion());
    }

    @RequestMapping(method = RequestMethod.GET, value = "/version/full")
    @ResponseBody
    public String fullVersion() {
        return GemFireVersion.asString();
    }

    private ResponseEntity<InputStreamResource> getResponse(String result) {
        CommandResult commandResult = ResultBuilder.fromJson(result);
        if (commandResult.getStatus().equals(Result.Status.OK) && commandResult.hasFileToDownload()) {
            return getFileDownloadResponse(commandResult);
        } else {
            return getJsonResponse(result);
        }
    }

    private ResponseEntity<InputStreamResource> getJsonResponse(String result) {
        HttpHeaders respHeaders = new HttpHeaders();
        try {
            InputStreamResource isr = new InputStreamResource(toInputStream(result, "UTF-8"));
            respHeaders.set(HttpHeaders.CONTENT_TYPE, MediaType.APPLICATION_JSON_VALUE);
            return new ResponseEntity<>(isr, respHeaders, HttpStatus.OK);
        } catch (Exception e) {
            throw new RuntimeException("IO Error writing file to output stream", e);
        }
    }

    private ResponseEntity<InputStreamResource> getFileDownloadResponse(CommandResult commandResult) {
        HttpHeaders respHeaders = new HttpHeaders();
        Path filePath = commandResult.getFileToDownload();
        try {
            InputStreamResource isr = new InputStreamResource(new FileInputStream(filePath.toFile()));
            respHeaders.set(HttpHeaders.CONTENT_TYPE, MediaType.APPLICATION_OCTET_STREAM_VALUE);
            return new ResponseEntity<>(isr, respHeaders, HttpStatus.OK);
        } catch (Exception e) {
            throw new RuntimeException("IO Error writing file to output stream", e);
        } finally {
            FileUtils.deleteQuietly(filePath.toFile());
        }
    }
}