/* * Copyright 2015 herd contributors * * 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.finra.herd.rest; import io.swagger.annotations.Api; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.security.access.annotation.Secured; import org.springframework.web.bind.annotation.PathVariable; 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.RestController; import org.finra.herd.model.api.xml.EmrCluster; import org.finra.herd.model.api.xml.EmrClusterCreateRequest; import org.finra.herd.model.api.xml.EmrHadoopJarStep; import org.finra.herd.model.api.xml.EmrHadoopJarStepAddRequest; import org.finra.herd.model.api.xml.EmrHiveStep; import org.finra.herd.model.api.xml.EmrHiveStepAddRequest; import org.finra.herd.model.api.xml.EmrMasterSecurityGroup; import org.finra.herd.model.api.xml.EmrMasterSecurityGroupAddRequest; import org.finra.herd.model.api.xml.EmrPigStep; import org.finra.herd.model.api.xml.EmrPigStepAddRequest; import org.finra.herd.model.api.xml.EmrShellStep; import org.finra.herd.model.api.xml.EmrShellStepAddRequest; import org.finra.herd.model.dto.EmrClusterAlternateKeyDto; import org.finra.herd.model.dto.SecurityFunctions; import org.finra.herd.service.EmrService; import org.finra.herd.ui.constants.UiConstants; /** * The REST controller that handles EMR REST requests. */ @RestController @RequestMapping(value = UiConstants.REST_URL_BASE, produces = {"application/xml", "application/json"}) @Api(tags = "EMR") public class EmrRestController extends HerdBaseController { @Autowired private EmrService emrService; /** * Adds security groups to the master node of an existing cluster <p>Requires WRITE permission on namespace</p> * * @param request the information needed to add security groups to master node of the EMR cluster. * * @return the created EMR master groups. */ @RequestMapping(value = "/emrMasterSecurityGroups", method = RequestMethod.POST, consumes = {"application/xml", "application/json"}) @Secured(SecurityFunctions.FN_EMR_MASTER_SECURITY_GROUPS_POST) public EmrMasterSecurityGroup addGroupsToEmrClusterMaster(@RequestBody EmrMasterSecurityGroupAddRequest request) throws Exception { return emrService.addSecurityGroupsToClusterMaster(request); } /** * Adds a Hadoop Jar step to the existing cluster <p>Requires EXECUTE permission on namespace</p> * * @param request the information needed to add Hadoop Jar step to the EMR cluster. * * @return the created EMR Hadoop Jar step. */ @RequestMapping(value = "/emrHadoopJarSteps", method = RequestMethod.POST, consumes = {"application/xml", "application/json"}) @Secured(SecurityFunctions.FN_EMR_HADOOP_JAR_STEPS_POST) public EmrHadoopJarStep addHadoopJarStepToEmrCluster(@RequestBody EmrHadoopJarStepAddRequest request) throws Exception { return (EmrHadoopJarStep) emrService.addStepToCluster(request); } /** * Adds a hive step to the existing cluster <p>Requires EXECUTE permission on namespace</p> * * @param request the information needed to add hive step to the EMR cluster. * * @return the created EMR hive step. */ @RequestMapping(value = "/emrHiveSteps", method = RequestMethod.POST, consumes = {"application/xml", "application/json"}) @Secured(SecurityFunctions.FN_EMR_HIVE_STEPS_POST) public EmrHiveStep addHiveStepToEmrCluster(@RequestBody EmrHiveStepAddRequest request) throws Exception { return (EmrHiveStep) emrService.addStepToCluster(request); } /** * Adds a Pig step to the existing cluster <p>Requires EXECUTE permission on namespace</p> * * @param request the information needed to add Pig step to the EMR cluster. * * @return the created EMR Pig step. */ @RequestMapping(value = "/emrPigSteps", method = RequestMethod.POST, consumes = {"application/xml", "application/json"}) @Secured(SecurityFunctions.FN_EMR_PIG_STEPS_POST) public EmrPigStep addPigStepToEmrCluster(@RequestBody EmrPigStepAddRequest request) throws Exception { return (EmrPigStep) emrService.addStepToCluster(request); } /** * Adds a shell step to the existing cluster <p>Requires EXECUTE permission on namespace</p> * * @param request the information needed to add shell step to the EMR cluster. * * @return the created EMR shell step. * @throws Exception if a shell step couldn't be added to the EMR cluster. */ @RequestMapping(value = "/emrShellSteps", method = RequestMethod.POST, consumes = {"application/xml", "application/json"}) @Secured(SecurityFunctions.FN_EMR_SHELL_STEPS_POST) public EmrShellStep addShellStepToEmrCluster(@RequestBody EmrShellStepAddRequest request) throws Exception { return (EmrShellStep) emrService.addStepToCluster(request); } /** * Creates a new EMR cluster. <p>Requires EXECUTE permission on namespace</p> * * @param request the information needed to create the EMR cluster. * * @return the created EMR cluster. */ @RequestMapping(value = "/emrClusters", method = RequestMethod.POST, consumes = {"application/xml", "application/json"}) @Secured(SecurityFunctions.FN_EMR_CLUSTERS_POST) public EmrCluster createEmrCluster(@RequestBody EmrClusterCreateRequest request) throws Exception { return emrService.createCluster(request); } /** * Gets an existing EMR cluster details. <p>Requires READ permission on namespace</p> * * @param namespace the namespace * @param emrClusterDefinitionName the EMR cluster definition name * @param emrClusterName the EMR cluster name * @param emrClusterId the cluster id of the cluster to get details * @param emrStepId the step id of the step to get details * @param verbose parameter for whether to return detailed information * @param accountId the account Id * @param retrieveInstanceFleets parameter for whether to retrieve instance fleets * * @return the EMR Cluster object with details. * @throws Exception if there was an error getting the EMR cluster. */ @RequestMapping(value = "/emrClusters/namespaces/{namespace}/emrClusterDefinitionNames/{emrClusterDefinitionName}/emrClusterNames/{emrClusterName}", method = RequestMethod.GET) @Secured(SecurityFunctions.FN_EMR_CLUSTERS_GET) public EmrCluster getEmrCluster(@PathVariable("namespace") String namespace, @PathVariable("emrClusterDefinitionName") String emrClusterDefinitionName, @PathVariable("emrClusterName") String emrClusterName, @RequestParam(value = "emrClusterId", required = false) String emrClusterId, @RequestParam(value = "emrStepId", required = false) String emrStepId, @RequestParam(value = "verbose", required = false, defaultValue = "false") Boolean verbose, @RequestParam(value = "accountId", required = false) String accountId, @RequestParam(value = "retrieveInstanceFleets", required = false, defaultValue = "false") Boolean retrieveInstanceFleets ) throws Exception { EmrClusterAlternateKeyDto alternateKey = EmrClusterAlternateKeyDto.builder().namespace(namespace).emrClusterDefinitionName(emrClusterDefinitionName).emrClusterName(emrClusterName).build(); return emrService.getCluster(alternateKey, emrClusterId, emrStepId, verbose, accountId, retrieveInstanceFleets); } /** * Terminates an existing EMR cluster. <p>Requires EXECUTE permission on namespace</p> * * @param namespace the namespace * @param emrClusterDefinitionName the EMR cluster definition name * @param emrClusterName the EMR cluster name * @param overrideTerminationProtection parameter for whether to override termination protection * @param emrClusterId EMR cluster ID * @param accountId account Id * * @return the EMR cluster that was terminated * @throws Exception if there was an error terminating the EMR cluster. */ @RequestMapping(value = "/emrClusters/namespaces/{namespace}/emrClusterDefinitionNames/{emrClusterDefinitionName}/emrClusterNames/{emrClusterName}", method = RequestMethod.DELETE) @Secured(SecurityFunctions.FN_EMR_CLUSTERS_DELETE) public EmrCluster terminateEmrCluster(@PathVariable("namespace") String namespace, @PathVariable("emrClusterDefinitionName") String emrClusterDefinitionName, @PathVariable("emrClusterName") String emrClusterName, @RequestParam(value = "overrideTerminationProtection", required = false, defaultValue = "false") Boolean overrideTerminationProtection, @RequestParam(value = "emrClusterId", required = false) String emrClusterId, @RequestParam(value = "accountId", required = false) String accountId) throws Exception { EmrClusterAlternateKeyDto alternateKey = EmrClusterAlternateKeyDto.builder().namespace(namespace).emrClusterDefinitionName(emrClusterDefinitionName).emrClusterName(emrClusterName).build(); return emrService.terminateCluster(alternateKey, overrideTerminationProtection, emrClusterId, accountId); } }