@RequestMapping(
     value =
         "/{applicationId:.+}/environments/{applicationEnvironmentId}/deployment/{nodeTemplateId}/{instanceId}/maintenance",
     method = RequestMethod.DELETE,
     produces = MediaType.APPLICATION_JSON_VALUE)
 @PreAuthorize("isAuthenticated()")
 @Audit
 public RestResponse<Void> switchInstanceMaintenanceModeOff(
     @PathVariable String applicationId,
     @PathVariable String applicationEnvironmentId,
     @PathVariable String nodeTemplateId,
     @PathVariable String instanceId) {
   ApplicationEnvironment environment =
       getAppEnvironmentAndCheckAuthorization(applicationId, applicationEnvironmentId);
   try {
     deploymentRuntimeService.switchInstanceMaintenanceMode(
         environment.getId(), nodeTemplateId, instanceId, false);
   } catch (OrchestratorDisabledException e) {
     return RestResponseBuilder.<Void>builder()
         .error(new RestError(RestErrorCode.CLOUD_DISABLED_ERROR.getCode(), e.getMessage()))
         .build();
   } catch (MaintenanceModeException e) {
     return RestResponseBuilder.<Void>builder()
         .error(new RestError(RestErrorCode.MAINTENANCE_MODE_ERROR.getCode(), e.getMessage()))
         .build();
   }
   return RestResponseBuilder.<Void>builder().build();
 }
 /**
  * Trigger un-deployment of the application for a given environment on the current configured
  * PaaS.
  *
  * @param applicationId The id of the application to undeploy.
  * @return An empty rest response.
  */
 @ApiOperation(
     value = "Un-Deploys the application on the configured PaaS.",
     notes =
         "The logged-in user must have the [ APPLICATION_MANAGER ] role for this application. Application environment role required [ DEPLOYMENT_MANAGER ]")
 @RequestMapping(
     value = "/{applicationId:.+}/environments/{applicationEnvironmentId}/deployment",
     method = RequestMethod.DELETE,
     produces = MediaType.APPLICATION_JSON_VALUE)
 @PreAuthorize("isAuthenticated()")
 @Audit
 public RestResponse<Void> undeploy(
     @PathVariable String applicationId, @PathVariable String applicationEnvironmentId) {
   ApplicationEnvironment environment =
       applicationEnvironmentService.getEnvironmentByIdOrDefault(
           applicationId, applicationEnvironmentId);
   Application application = applicationService.checkAndGetApplication(applicationId);
   if (!AuthorizationUtil.hasAuthorizationForApplication(
       application, ApplicationRole.APPLICATION_MANAGER)) {
     AuthorizationUtil.checkAuthorizationForEnvironment(
         environment, ApplicationEnvironmentRole.DEPLOYMENT_MANAGER);
   }
   try {
     undeployService.undeployEnvironment(applicationEnvironmentId);
   } catch (OrchestratorDisabledException e) {
     return RestResponseBuilder.<Void>builder()
         .error(new RestError(RestErrorCode.CLOUD_DISABLED_ERROR.getCode(), e.getMessage()))
         .build();
   }
   return RestResponseBuilder.<Void>builder().build();
 }
  @ApiOperation(
      value = "Launch a given workflow.",
      authorizations = {@Authorization("ADMIN"), @Authorization("APPLICATION_MANAGER")})
  @RequestMapping(
      value =
          "/{applicationId:.+}/environments/{applicationEnvironmentId}/workflows/{workflowName}",
      method = RequestMethod.POST,
      produces = MediaType.APPLICATION_JSON_VALUE)
  @PreAuthorize("isAuthenticated()")
  @Audit
  public DeferredResult<RestResponse<Void>> launchWorkflow(
      @ApiParam(value = "Application id.", required = true) @Valid @NotBlank @PathVariable
          String applicationId,
      @ApiParam(value = "Deployment id.", required = true) @Valid @NotBlank @PathVariable
          String applicationEnvironmentId,
      @ApiParam(value = "Workflow name.", required = true) @Valid @NotBlank @PathVariable
          String workflowName) {

    final DeferredResult<RestResponse<Void>> result = new DeferredResult<>(15L * 60L * 1000L);
    ApplicationEnvironment environment =
        getAppEnvironmentAndCheckAuthorization(applicationId, applicationEnvironmentId);

    // TODO merge with incoming params
    Map<String, Object> params = Maps.newHashMap();

    try {
      workflowExecutionService.launchWorkflow(
          environment.getId(),
          workflowName,
          params,
          new IPaaSCallback<Object>() {
            @Override
            public void onSuccess(Object data) {
              result.setResult(RestResponseBuilder.<Void>builder().build());
            }

            @Override
            public void onFailure(Throwable e) {
              result.setErrorResult(
                  RestResponseBuilder.<Void>builder()
                      .error(new RestError(RestErrorCode.SCALING_ERROR.getCode(), e.getMessage()))
                      .build());
            }
          });
    } catch (OrchestratorDisabledException e) {
      result.setErrorResult(
          RestResponseBuilder.<Void>builder()
              .error(new RestError(RestErrorCode.CLOUD_DISABLED_ERROR.getCode(), e.getMessage()))
              .build());
    } catch (PaaSDeploymentException e) {
      result.setErrorResult(
          RestResponseBuilder.<Void>builder()
              .error(new RestError(RestErrorCode.SCALING_ERROR.getCode(), e.getMessage()))
              .build());
    }

    return result;
  }
  /**
   * Scale an application on a particular node.
   *
   * @param applicationId The id of the application to be scaled.
   * @param nodeTemplateId The id of the node template to be scaled.
   * @param instances The instances number to be scaled up (if > 0)/ down (if < 0)
   * @return A {@link RestResponse} that contains the application's current {@link
   *     DeploymentStatus}.
   */
  @ApiOperation(
      value = "Scale the application on a particular node.",
      notes =
          "Returns the detailed informations of the application on the PaaS it is deployed."
              + " Application role required [ APPLICATION_MANAGER | APPLICATION_DEVOPS ] and Application environment role required [ DEPLOYMENT_MANAGER ]")
  @RequestMapping(
      value = "/{applicationId:.+}/environments/{applicationEnvironmentId}/scale/{nodeTemplateId}",
      method = RequestMethod.POST,
      produces = MediaType.APPLICATION_JSON_VALUE)
  @PreAuthorize("isAuthenticated()")
  @Audit
  public DeferredResult<RestResponse<Void>> scale(
      @PathVariable String applicationId,
      @PathVariable String applicationEnvironmentId,
      @PathVariable String nodeTemplateId,
      @RequestParam int instances) {
    final DeferredResult<RestResponse<Void>> result = new DeferredResult<>(15L * 60L * 1000L);
    ApplicationEnvironment environment =
        getAppEnvironmentAndCheckAuthorization(applicationId, applicationEnvironmentId);

    try {
      deploymentRuntimeService.scale(
          environment.getId(),
          nodeTemplateId,
          instances,
          new IPaaSCallback<Object>() {
            @Override
            public void onSuccess(Object data) {
              result.setResult(RestResponseBuilder.<Void>builder().build());
            }

            @Override
            public void onFailure(Throwable e) {
              result.setErrorResult(
                  RestResponseBuilder.<Void>builder()
                      .error(new RestError(RestErrorCode.SCALING_ERROR.getCode(), e.getMessage()))
                      .build());
            }
          });
    } catch (OrchestratorDisabledException e) {
      result.setErrorResult(
          RestResponseBuilder.<Void>builder()
              .error(new RestError(RestErrorCode.CLOUD_DISABLED_ERROR.getCode(), e.getMessage()))
              .build());
    } catch (PaaSDeploymentException e) {
      result.setErrorResult(
          RestResponseBuilder.<Void>builder()
              .error(new RestError(RestErrorCode.SCALING_ERROR.getCode(), e.getMessage()))
              .build());
    }

    return result;
  }