@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;
  }
  /**
   * Get detailed informations for every instances of every node of the application on the PaaS.
   *
   * @param applicationId The id of the application to be deployed.
   * @return A {@link RestResponse} that contains detailed informations (See {@link
   *     InstanceInformation}) of the application on the PaaS it is deployed.
   */
  @ApiOperation(
      value =
          "Get detailed informations for every instances of every node of the application on the PaaS.",
      notes =
          "Application role required [ APPLICATION_MANAGER | APPLICATION_DEVOPS ] and Application environment role required [ APPLICATION_USER | DEPLOYMENT_MANAGER ]")
  @RequestMapping(
      value = "/{applicationId:.+}/environments/{applicationEnvironmentId}/deployment/informations",
      method = RequestMethod.GET,
      produces = MediaType.APPLICATION_JSON_VALUE)
  @PreAuthorize("isAuthenticated()")
  public DeferredResult<RestResponse<Map<String, Map<String, InstanceInformation>>>>
      getInstanceInformation(
          @PathVariable String applicationId, @PathVariable String applicationEnvironmentId) {
    Application application = applicationService.checkAndGetApplication(applicationId);
    ApplicationEnvironment environment =
        applicationEnvironmentService.getEnvironmentByIdOrDefault(
            application.getId(), applicationEnvironmentId);
    if (!AuthorizationUtil.hasAuthorizationForApplication(
        application, ApplicationRole.APPLICATION_MANAGER)) {
      AuthorizationUtil.checkAuthorizationForEnvironment(
          environment, ApplicationEnvironmentRole.values());
    }

    Deployment deployment = applicationEnvironmentService.getActiveDeployment(environment.getId());
    final DeferredResult<RestResponse<Map<String, Map<String, InstanceInformation>>>>
        instancesDeferredResult = new DeferredResult<>(5L * 60L * 1000L);
    if (deployment
        == null) { // if there is no topology associated with the version it could not have been
      // deployed.
      instancesDeferredResult.setResult(
          RestResponseBuilder.<Map<String, Map<String, InstanceInformation>>>builder().build());
    } else {
      try {
        deploymentRuntimeStateService.getInstancesInformation(
            deployment,
            new IPaaSCallback<Map<String, Map<String, InstanceInformation>>>() {
              @Override
              public void onSuccess(Map<String, Map<String, InstanceInformation>> data) {
                instancesDeferredResult.setResult(
                    RestResponseBuilder.<Map<String, Map<String, InstanceInformation>>>builder()
                        .data(data)
                        .build());
              }

              @Override
              public void onFailure(Throwable throwable) {
                instancesDeferredResult.setErrorResult(throwable);
              }
            });
      } catch (OrchestratorDisabledException e) {
        log.error("Cannot get instance informations as topology plugin cannot be found.", e);
        instancesDeferredResult.setResult(
            RestResponseBuilder.<Map<String, Map<String, InstanceInformation>>>builder().build());
      }
    }
    return instancesDeferredResult;
  }
  /**
   * 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;
  }
 /**
  * Get only the active deployment for the given application on the given cloud
  *
  * @param applicationId id of the topology
  * @return the active deployment
  */
 @ApiOperation(
     value = "Get active deployment for the given application on the given cloud.",
     notes =
         "Application role required [ APPLICATION_MANAGER | APPLICATION_DEVOPS ] and Application environment role required [ DEPLOYMENT_MANAGER ]")
 @RequestMapping(
     value = "/{applicationId:.+}/environments/{applicationEnvironmentId}/active-deployment",
     method = RequestMethod.GET,
     produces = MediaType.APPLICATION_JSON_VALUE)
 @PreAuthorize("isAuthenticated()")
 public RestResponse<Deployment> getActiveDeployment(
     @PathVariable String applicationId, @PathVariable String applicationEnvironmentId) {
   Application application = applicationService.checkAndGetApplication(applicationId);
   // get the topology from the version and the cloud from the environment
   ApplicationEnvironment environment =
       applicationEnvironmentService.getEnvironmentByIdOrDefault(
           application.getId(), applicationEnvironmentId);
   // when a user is application manager, he can manipulate environment
   if (!AuthorizationUtil.hasAuthorizationForApplication(
       application, ApplicationRole.APPLICATION_MANAGER)) {
     AuthorizationUtil.checkAuthorizationForEnvironment(
         environment,
         ApplicationEnvironmentRole.DEPLOYMENT_MANAGER,
         ApplicationEnvironmentRole.APPLICATION_USER);
   }
   Deployment deployment = deploymentService.getActiveDeployment(environment.getId());
   return RestResponseBuilder.<Deployment>builder().data(deployment).build();
 }
 @ApiOperation(
     value = "Update the name of an existing location.",
     authorizations = {@Authorization("ADMIN")})
 @RequestMapping(
     value = "/{id}",
     method = RequestMethod.PUT,
     consumes = MediaType.APPLICATION_JSON_VALUE)
 @PreAuthorize("hasAuthority('ADMIN')")
 @Audit
 public RestResponse<Void> update(
     @ApiParam(value = "Id of the orchestrator for which the location is defined.") @PathVariable
         String orchestratorId,
     @ApiParam(value = "Id of the location to update", required = true) @PathVariable String id,
     @ApiParam(
             value =
                 "Location update request, representing the fields to updates and their new values.",
             required = true)
         @Valid
         @NotEmpty
         @RequestBody
         UpdateLocationRequest updateRequest) {
   Location location = locationService.getOrFail(id);
   String currentName = location.getName();
   ReflectionUtil.mergeObject(updateRequest, location);
   locationService.ensureNameUnicityAndSave(location, currentName);
   return RestResponseBuilder.<Void>builder().build();
 }
  @RequestMapping(
      value = "/{topologyId}/workflows/{workflowName}",
      method = RequestMethod.POST,
      produces = MediaType.APPLICATION_JSON_VALUE)
  public RestResponse<Workflow> renameWorkflow(
      @PathVariable String topologyId,
      @PathVariable String workflowName,
      @RequestParam String newName) {

    Topology topology = topologyServiceCore.getMandatoryTopology(topologyId);
    topologyService.checkEditionAuthorizations(topology);
    topologyService.throwsErrorIfReleased(topology);

    if (topology.getWorkflows().containsKey(newName)) {
      throw new AlreadyExistException(
          String.format("The workflow named '%s' already exists", newName));
    }
    Workflow wf = topology.getWorkflows().remove(workflowName);
    if (wf.isStandard()) {
      throw new RuntimeException("standard wf can not be renamed");
    }
    wf.setName(newName);
    topology.getWorkflows().put(newName, wf);
    alienDAO.save(topology);
    return RestResponseBuilder.<Workflow>builder().data(wf).build();
  }
 @ApiOperation(value = "Get a location from it's id.")
 @RequestMapping(value = "/{id}", method = RequestMethod.GET)
 @PreAuthorize("isAuthenticated()")
 public RestResponse<LocationDTO> get(
     @ApiParam(value = "Id of the orchestrator for which the location is defined.") @PathVariable
         String orchestratorId,
     @ApiParam(value = "Id of the location to get", required = true) @PathVariable String id) {
   Location location = locationService.getOrFail(id);
   AuthorizationUtil.checkAuthorizationForLocation(location, DeployerRole.DEPLOYER);
   return RestResponseBuilder.<LocationDTO>builder().data(buildLocationDTO(location)).build();
 }
 @ApiOperation(
     value = "Delete an existing location.",
     authorizations = {@Authorization("ADMIN")})
 @RequestMapping(value = "/{id}", method = RequestMethod.DELETE)
 @PreAuthorize("hasAuthority('ADMIN')")
 @Audit
 public RestResponse<Boolean> delete(
     @ApiParam(value = "Id of the orchestrator for which the location is defined.") @PathVariable
         String orchestratorId,
     @ApiParam(value = "Id of the location to delete.", required = true) @PathVariable String id) {
   return RestResponseBuilder.<Boolean>builder().data(locationService.delete(id)).build();
 }
 @ApiOperation(value = "Get all locations for a given orchestrator.")
 @RequestMapping(method = RequestMethod.GET)
 @PreAuthorize("isAuthenticated()")
 public RestResponse<List<LocationDTO>> getAll(
     @ApiParam(value = "Id of the orchestrator for which to get all locations.") @PathVariable
         String orchestratorId) {
   List<Location> locations = locationService.getAll(orchestratorId);
   List<LocationDTO> locationDTOs = Lists.newArrayList();
   for (Location location : locations) {
     locationDTOs.add(buildLocationDTO(location));
   }
   return RestResponseBuilder.<List<LocationDTO>>builder().data(locationDTOs).build();
 }
  @RequestMapping(
      value = "/{topologyId}/workflows",
      method = RequestMethod.POST,
      produces = MediaType.APPLICATION_JSON_VALUE)
  public RestResponse<Workflow> createWorkflow(@PathVariable String topologyId) {

    Topology topology = topologyServiceCore.getMandatoryTopology(topologyId);
    topologyService.checkEditionAuthorizations(topology);
    topologyService.throwsErrorIfReleased(topology);

    Workflow wf = workflowBuilderService.ceateWorkflow(topology);
    alienDAO.save(topology);
    return RestResponseBuilder.<Workflow>builder().data(wf).build();
  }
  @RequestMapping(
      value = "/{topologyId}/workflows/{workflowName}/steps/{stepId}",
      method = RequestMethod.DELETE,
      produces = MediaType.APPLICATION_JSON_VALUE)
  public RestResponse<Workflow> removeStep(
      @PathVariable String topologyId,
      @PathVariable String workflowName,
      @PathVariable String stepId) {
    Topology topology = topologyServiceCore.getMandatoryTopology(topologyId);
    topologyService.checkEditionAuthorizations(topology);
    topologyService.throwsErrorIfReleased(topology);

    Workflow wf = workflowBuilderService.removeStep(topology, workflowName, stepId, false);
    alienDAO.save(topology);
    return RestResponseBuilder.<Workflow>builder().data(wf).build();
  }
 @RequestMapping(method = RequestMethod.POST, consumes = MediaType.APPLICATION_JSON_VALUE)
 @ApiOperation(
     value = "Create a new location.",
     authorizations = {@Authorization("ADMIN")})
 @ResponseStatus(value = HttpStatus.CREATED)
 @PreAuthorize("hasAuthority('ADMIN')")
 @Audit
 public RestResponse<String> create(
     @ApiParam(value = "Id of the orchestrator for which the location is defined.") @PathVariable
         String orchestratorId,
     @ApiParam(value = "Request for location creation", required = true) @Valid @RequestBody
         CreateLocationRequest locationRequest) {
   String id =
       locationService.create(
           orchestratorId, locationRequest.getName(), locationRequest.getInfrastructureType());
   return RestResponseBuilder.<String>builder().data(id).build();
 }
  @ApiOperation(
      value =
          "Get the deployment status for the environements that the current user is allowed to see for a given application.",
      notes =
          "Returns the current status of an application list from the PaaS it is deployed on for all environments.")
  @RequestMapping(
      value = "/statuses",
      method = RequestMethod.POST,
      produces = MediaType.APPLICATION_JSON_VALUE)
  @PreAuthorize("isAuthenticated()")
  public RestResponse<Map<String, Map<String, EnvironmentStatusDTO>>> getApplicationsStatuses(
      @RequestBody List<String> applicationIds) {
    Map<String, Map<String, EnvironmentStatusDTO>> statuses = Maps.newHashMap();

    for (String applicationId : applicationIds) {
      Map<String, EnvironmentStatusDTO> environmentStatuses = Maps.newHashMap();
      Application application = applicationService.checkAndGetApplication(applicationId);
      // get all environments status for the current application
      ApplicationEnvironment[] environments =
          applicationEnvironmentService.getByApplicationId(application.getId());
      for (ApplicationEnvironment env : environments) {
        if (AuthorizationUtil.hasAuthorizationForEnvironment(
            env, ApplicationEnvironmentRole.values())) {
          DeploymentStatus status = DeploymentStatus.UNKNOWN;
          try {
            status = applicationEnvironmentService.getStatus(env);
          } catch (Exception e) {
            log.debug(
                "Getting status for the environment <"
                    + env.getId()
                    + "> failed because the associated orchestrator seems disabled. Returned status is UNKNOWN.",
                e);
          }
          environmentStatuses.put(env.getId(), new EnvironmentStatusDTO(env.getName(), status));
        }
      }
      statuses.put(applicationId, environmentStatuses);
    }
    return RestResponseBuilder.<Map<String, Map<String, EnvironmentStatusDTO>>>builder()
        .data(statuses)
        .build();
  }
  /**
   * Delete a tag for the application.
   *
   * @param applicationId Id of the application for which to remove the tag.
   * @param tagId The key of the tag to remove.
   * @return An empty {@link RestResponse}.
   */
  @ApiOperation(
      value = "Delete a tag for the application.",
      notes =
          "The logged-in user must have the application manager role for this application. Application role required [ APPLICATION_MANAGER ]")
  @RequestMapping(
      value = "/{tagId}",
      method = RequestMethod.DELETE,
      produces = MediaType.APPLICATION_JSON_VALUE)
  @PreAuthorize("isAuthenticated()")
  @Audit
  public RestResponse<Void> deleteTag(
      @PathVariable String applicationId, @PathVariable String tagId) {
    Application application = applicationService.getOrFail(applicationId);
    AuthorizationUtil.checkAuthorizationForApplication(
        application, ApplicationRole.APPLICATION_MANAGER);

    tagService.removeTag(application, tagId);

    return RestResponseBuilder.<Void>builder().build();
  }
 /**
  * Get deployment properties for an orchestrator.
  *
  * @param orchestratorId Id of the orchestrator for which to get properties.
  */
 @ApiOperation(
     value = "Get deployment properties for an orchestrator.",
     notes =
         "Deployments properties are properties that can be set by the Application Deployer before deployment. They depends on the IPaaSProvider plugin associated with an orchestrator.",
     authorizations = {@Authorization("ADMIN")})
 @RequestMapping(
     value = "/deployment-property-definitions",
     method = RequestMethod.GET,
     produces = MediaType.APPLICATION_JSON_VALUE)
 @PreAuthorize("isAuthenticated()")
 public RestResponse<Map<String, PropertyDefinition>> getDeploymentPropertyDefinitions(
     @ApiParam(value = "Id of the cloud for which to get details.", required = true)
         @Valid
         @NotBlank
         @PathVariable
         String orchestratorId) {
   return RestResponseBuilder.<Map<String, PropertyDefinition>>builder()
       .data(orchestratorDeploymentService.getDeploymentPropertyDefinitions(orchestratorId))
       .build();
 }
  @RequestMapping(
      value = "/{topologyId}/workflows/{workflowName}/activities",
      method = RequestMethod.POST,
      produces = MediaType.APPLICATION_JSON_VALUE)
  public RestResponse<Workflow> addActivity(
      @PathVariable String topologyId,
      @PathVariable String workflowName,
      @RequestBody TopologyWorkflowAddActivityRequest activityRequest) {

    Topology topology = topologyServiceCore.getMandatoryTopology(topologyId);
    topologyService.checkEditionAuthorizations(topology);
    topologyService.throwsErrorIfReleased(topology);

    Workflow wf =
        workflowBuilderService.addActivity(
            topology,
            workflowName,
            activityRequest.getRelatedStepId(),
            activityRequest.isBefore(),
            activityRequest.getActivity());
    alienDAO.save(topology);
    return RestResponseBuilder.<Workflow>builder().data(wf).build();
  }
  /**
   * Update or create a tag for a given application
   *
   * @param applicationId The id of the application for which to update/create a tag.
   * @param updateApplicationTagRequest The object that contains the tag's key and value.
   * @return An empty rest response.
   */
  @ApiOperation(
      value = "Update/Create a tag for the application.",
      notes =
          "The logged-in user must have the application manager role for this application. Application role required [ APPLICATION_MANAGER ]")
  @RequestMapping(
      method = RequestMethod.POST,
      consumes = MediaType.APPLICATION_JSON_VALUE,
      produces = MediaType.APPLICATION_JSON_VALUE)
  @PreAuthorize("isAuthenticated()")
  @Audit
  public RestResponse<Void> upsertTag(
      @PathVariable String applicationId,
      @RequestBody UpdateTagRequest updateApplicationTagRequest) {
    Application application = applicationService.getOrFail(applicationId);
    AuthorizationUtil.checkAuthorizationForApplication(
        application, ApplicationRole.APPLICATION_MANAGER);

    tagService.upsertTag(
        application,
        updateApplicationTagRequest.getTagKey(),
        updateApplicationTagRequest.getTagValue());

    return RestResponseBuilder.<Void>builder().build();
  }
  @ApiIgnore
  @RequestMapping(
      value = "/deployment-prop-check",
      method = RequestMethod.POST,
      consumes = MediaType.APPLICATION_JSON_VALUE)
  @PreAuthorize("isAuthenticated()")
  public RestResponse<ConstraintUtil.ConstraintInformation> checkPluginDeploymentProperties(
      @ApiParam(
              value = "Id of the orchestrators for which to check deployment property.",
              required = true)
          @PathVariable
          @Valid
          @NotEmpty
          String orchestratorId,
      @ApiParam(value = "Value and id of the property to check.", required = true)
          @Valid
          @NotEmpty
          @RequestBody
          PropertyRequest deploymentPropertyValidationRequest) {
    Map<String, PropertyDefinition> deploymentPropertyDefinitions =
        orchestratorDeploymentService.getDeploymentPropertyDefinitions(orchestratorId);

    if (deploymentPropertyDefinitions != null) {
      PropertyDefinition propertyDefinition =
          deploymentPropertyDefinitions.get(deploymentPropertyValidationRequest.getDefinitionId());
      if (propertyDefinition != null && propertyDefinition.getConstraints() != null) {
        try {
          constraintPropertyService.checkSimplePropertyConstraint(
              deploymentPropertyValidationRequest.getDefinitionId(),
              deploymentPropertyValidationRequest.getValue(),
              propertyDefinition);
        } catch (ConstraintViolationException e) {
          log.error(
              "Constraint violation error for property <"
                  + deploymentPropertyValidationRequest.getDefinitionId()
                  + "> with value <"
                  + deploymentPropertyValidationRequest.getValue()
                  + ">",
              e);
          return RestResponseBuilder.<ConstraintUtil.ConstraintInformation>builder()
              .data(e.getConstraintInformation())
              .error(
                  RestErrorBuilder.builder(RestErrorCode.PROPERTY_CONSTRAINT_VIOLATION_ERROR)
                      .message(e.getMessage())
                      .build())
              .build();
        } catch (ConstraintValueDoNotMatchPropertyTypeException e) {
          log.error(
              "Constraint value violation error for property <"
                  + e.getConstraintInformation().getName()
                  + "> with value <"
                  + e.getConstraintInformation().getValue()
                  + "> and type <"
                  + e.getConstraintInformation().getType()
                  + ">",
              e);
          return RestResponseBuilder.<ConstraintUtil.ConstraintInformation>builder()
              .data(e.getConstraintInformation())
              .error(
                  RestErrorBuilder.builder(RestErrorCode.PROPERTY_TYPE_VIOLATION_ERROR)
                      .message(e.getMessage())
                      .build())
              .build();
        }
      }
    }
    return RestResponseBuilder.<ConstraintUtil.ConstraintInformation>builder().build();
  }
  /**
   * Trigger deployment of the application on the current configured PaaS.
   *
   * @param deployApplicationRequest application details for deployment (applicationId +
   *     deploymentProperties)
   * @return An empty rest response.
   */
  @ApiOperation(
      value = "Deploys the application on the configured Cloud.",
      notes =
          "Application role required [ APPLICATION_MANAGER | APPLICATION_DEVOPS ] and Application environment role required [ DEPLOYMENT_MANAGER ]")
  @RequestMapping(
      value = "/deployment",
      method = RequestMethod.POST,
      consumes = MediaType.APPLICATION_JSON_VALUE,
      produces = MediaType.APPLICATION_JSON_VALUE)
  @PreAuthorize("isAuthenticated()")
  @Audit
  public RestResponse<?> deploy(
      @Valid @RequestBody DeployApplicationRequest deployApplicationRequest) {
    String applicationId = deployApplicationRequest.getApplicationId();
    String environmentId = deployApplicationRequest.getApplicationEnvironmentId();
    Application application = applicationService.checkAndGetApplication(applicationId);
    ApplicationEnvironment environment =
        applicationEnvironmentService.getEnvironmentByIdOrDefault(applicationId, environmentId);
    if (!environment.getApplicationId().equals(applicationId)) {
      throw new NotFoundException(
          "Unable to find environment with id <"
              + environmentId
              + "> for application <"
              + applicationId
              + ">");
    }
    // Security check user must be authorized to deploy the environment (or be application manager)
    if (!AuthorizationUtil.hasAuthorizationForApplication(
        application, ApplicationRole.APPLICATION_MANAGER)) {
      AuthorizationUtil.checkAuthorizationForEnvironment(
          environment, ApplicationEnvironmentRole.DEPLOYMENT_MANAGER);
    }

    // check that the environment is not already deployed
    boolean isEnvironmentDeployed = applicationEnvironmentService.isDeployed(environment.getId());
    if (isEnvironmentDeployed) {
      throw new AlreadyExistException(
          "Environment with id <"
              + environmentId
              + "> for application <"
              + applicationId
              + "> is already deployed");
    }
    // Get the deployment configurations
    DeploymentConfiguration deploymentConfiguration =
        deploymentTopologyService.getDeploymentConfiguration(environment.getId());
    DeploymentTopology deploymentTopology = deploymentConfiguration.getDeploymentTopology();
    // Check authorization on the location
    // get the target locations of the deployment topology
    Map<String, Location> locationMap = deploymentTopologyService.getLocations(deploymentTopology);
    for (Location location : locationMap.values()) {
      AuthorizationUtil.checkAuthorizationForLocation(location, DeployerRole.DEPLOYER);
    }

    // prepare the deployment
    TopologyValidationResult validation = deployService.prepareForDeployment(deploymentTopology);

    // if not valid, then return validation errors
    if (!validation.isValid()) {
      return RestResponseBuilder.<TopologyValidationResult>builder()
          .error(
              new RestError(
                  RestErrorCode.INVALID_DEPLOYMENT_TOPOLOGY.getCode(),
                  "The deployment topology for the application <"
                      + application.getName()
                      + "> on the environment <"
                      + environment.getName()
                      + "> is not valid."))
          .data(validation)
          .build();
    }

    // process with the deployment
    deployService.deploy(deploymentTopology, application);
    // TODO OrchestratorDisabledException handling in the ExceptionHandler
    // return RestResponseBuilder.<Void> builder().error(
    // new RestError(RestErrorCode.CLOUD_DISABLED_ERROR.getCode(), "Cloud with id <" +
    // environment.getCloudId() + "> is disabled or not found"))
    // .build();

    return RestResponseBuilder.<Void>builder().build();
  }