<commit_before>/*
 * 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.stratos.rest.endpoint.api;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.apache.stratos.autoscaler.stub.*;
import org.apache.stratos.cloud.controller.stub.*;
import org.apache.stratos.common.beans.ResponseMessageBean;
import org.apache.stratos.common.beans.TenantInfoBean;
import org.apache.stratos.common.beans.UserInfoBean;
import org.apache.stratos.common.beans.application.ApplicationBean;
import org.apache.stratos.common.beans.application.ApplicationNetworkPartitionIdListBean;
import org.apache.stratos.common.beans.application.domain.mapping.ApplicationDomainMappingsBean;
import org.apache.stratos.common.beans.application.domain.mapping.DomainMappingBean;
import org.apache.stratos.common.beans.application.signup.ApplicationSignUpBean;
import org.apache.stratos.common.beans.artifact.repository.GitNotificationPayloadBean;
import org.apache.stratos.common.beans.cartridge.CartridgeBean;
import org.apache.stratos.common.beans.cartridge.CartridgeGroupBean;
import org.apache.stratos.common.beans.kubernetes.KubernetesClusterBean;
import org.apache.stratos.common.beans.kubernetes.KubernetesHostBean;
import org.apache.stratos.common.beans.kubernetes.KubernetesMasterBean;
import org.apache.stratos.common.beans.partition.NetworkPartitionBean;
import org.apache.stratos.common.beans.policy.autoscale.AutoscalePolicyBean;
import org.apache.stratos.common.beans.policy.deployment.ApplicationPolicyBean;
import org.apache.stratos.common.beans.policy.deployment.DeploymentPolicyBean;
import org.apache.stratos.common.beans.topology.ApplicationInfoBean;
import org.apache.stratos.common.beans.topology.ClusterBean;
import org.apache.stratos.common.exception.InvalidEmailException;
import org.apache.stratos.manager.service.stub.StratosManagerServiceApplicationSignUpExceptionException;
import org.apache.stratos.manager.service.stub.StratosManagerServiceDomainMappingExceptionException;
import org.apache.stratos.rest.endpoint.Utils;
import org.apache.stratos.rest.endpoint.annotation.AuthorizationAction;
import org.apache.stratos.rest.endpoint.annotation.SuperTenantService;
import org.apache.stratos.rest.endpoint.exception.*;
import org.wso2.carbon.context.PrivilegedCarbonContext;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpSession;
import javax.ws.rs.*;
import javax.ws.rs.core.Context;
import javax.ws.rs.core.MediaType;
import javax.ws.rs.core.Response;
import javax.ws.rs.core.UriInfo;
import java.net.URI;
import java.rmi.RemoteException;
import java.util.ArrayList;
import java.util.List;

/**
 * Stratos API v4.1 for Stratos 4.1.0 release.
 */
@Path("/")
public class StratosApiV41 extends AbstractApi {
    private static final Log log = LogFactory.getLog(StratosApiV41.class);

    @Context
    HttpServletRequest httpServletRequest;
    @Context
    UriInfo uriInfo;

    /**
     * This method is used by clients such as the CLI to verify the Stratos manager URL.
     *
     * @return the response
     * @throws RestAPIException the rest api exception
     */
    @GET
    @Path("/init")
    @AuthorizationAction("/permission/admin/login")
    public Response initialize()
            throws RestAPIException {
        ResponseMessageBean response = new ResponseMessageBean(ResponseMessageBean.SUCCESS,
                "Successfully authenticated");
        return Response.ok(response).build();
    }

    /**
     * This method gets called by the client who are interested in using session mechanism to authenticate
     * themselves in subsequent calls. This method call get authenticated by the basic authenticator.
     * Once the authenticated call received, the method creates a session and returns the session id.
     *
     * @return The session id related with the session
     */
    @GET
    @Path("/session")
    @Produces("application/json")
    @Consumes("application/json")
    @AuthorizationAction("/permission/admin/login")
    public Response getSession() {
        HttpSession httpSession = httpServletRequest.getSession(true);//create session if not found
        PrivilegedCarbonContext carbonContext = PrivilegedCarbonContext.getThreadLocalCarbonContext();
        httpSession.setAttribute("userName", carbonContext.getUsername());
        httpSession.setAttribute("tenantDomain", carbonContext.getTenantDomain());
        httpSession.setAttribute("tenantId", carbonContext.getTenantId());

        String sessionId = httpSession.getId();
        return Response.ok().header("WWW-Authenticate", "Basic").type(MediaType.APPLICATION_JSON).
                entity(Utils.buildAuthenticationSuccessMessage(sessionId)).build();
    }

    /**
     * Creates the Deployment Policy Definition.
     *
     * @param deploymentPolicyDefinitionBean the deployment policy bean
     * @return 201 if deployment policy is successfully added
     * @throws RestAPIException the rest api exception
     */
    @POST
    @Path("/deploymentPolicies")
    @Produces("application/json")
    @Consumes("application/json")
    @AuthorizationAction("/permission/stratos/deploymentPolicies/manage")
    public Response addDeploymentPolicy(
            DeploymentPolicyBean deploymentPolicyDefinitionBean) throws RestAPIException {

        String deploymentPolicyID = deploymentPolicyDefinitionBean.getId();
        try {
            StratosApiV41Utils.addDeploymentPolicy(deploymentPolicyDefinitionBean);
        } catch (AutoscalerServiceInvalidDeploymentPolicyExceptionException e) {
            String backendErrorMessage = e.getFaultMessage().getInvalidDeploymentPolicyException().getMessage();
            return Response.status(Response.Status.BAD_REQUEST).entity(new ResponseMessageBean(
                    ResponseMessageBean.ERROR, backendErrorMessage)).build();
        } catch (AutoscalerServiceDeploymentPolicyAlreadyExistsExceptionException e) {
            return Response.status(Response.Status.CONFLICT).entity(new ResponseMessageBean(
                    ResponseMessageBean.ERROR, "Deployment policy already exists")).build();
        }
        URI url = uriInfo.getAbsolutePathBuilder().path(deploymentPolicyID).build();
        return Response.created(url).entity(new ResponseMessageBean(ResponseMessageBean.SUCCESS,
                String.format("Deployment policy added successfully: " + "[deployment-policy-id] %s",
                        deploymentPolicyID))).build();
    }

    /**
     * Get deployment policy by deployment policy id
     *
     * @return 200 if deployment policy is found, 404 if not
     * @throws RestAPIException
     */
    @GET
    @Path("/deploymentPolicies/{deploymentPolicyId}")
    @Produces("application/json")
    @Consumes("application/json")
    @AuthorizationAction("/permission/stratos/deploymentPolicies/view")
    public Response getDeploymentPolicy(
            @PathParam("deploymentPolicyId") String deploymentPolicyId) throws RestAPIException {
        DeploymentPolicyBean deploymentPolicyBean = StratosApiV41Utils.getDeployementPolicy(deploymentPolicyId);
        if (deploymentPolicyBean == null) {
            return Response.status(Response.Status.NOT_FOUND).entity(new ResponseMessageBean(
                    ResponseMessageBean.ERROR, "Deployment policy not found")).build();
        }
        return Response.ok(deploymentPolicyBean).build();
    }

    /**
     * Get deployment policies
     *
     * @return 200 with the list of deployment policies
     * @throws RestAPIException
     */
    @GET
    @Path("/deploymentPolicies")
    @Produces("application/json")
    @Consumes("application/json")
    @AuthorizationAction("/permission/stratos/deploymentPolicies/view")
    public Response getDeploymentPolicies()
            throws RestAPIException {
        DeploymentPolicyBean[] deploymentPolicies = StratosApiV41Utils.getDeployementPolicies();
        if (deploymentPolicies == null || deploymentPolicies.length == 0) {
            return Response.status(Response.Status.NOT_FOUND).entity(new ResponseMessageBean(
                    ResponseMessageBean.ERROR, "No deployment policies found")).build();
        }

        return Response.ok(deploymentPolicies).build();
    }

    /**
     * Updates the Deployment Policy Definition.
     *
     * @param deploymentPolicyDefinitionBean the deployment policy bean
     * @return 200 if deployment policy is successfully updated
     * @throws RestAPIException the rest api exception
     */
    @PUT
    @Path("/deploymentPolicies")
    @Produces("application/json")
    @Consumes("application/json")
    @AuthorizationAction("/permission/stratos/deploymentPolicies/manage")
    public Response updateDeploymentPolicy(
            DeploymentPolicyBean deploymentPolicyDefinitionBean) throws RestAPIException {

        String deploymentPolicyID = deploymentPolicyDefinitionBean.getId();
        // TODO :: Deployment policy validation

        try {

            StratosApiV41Utils.updateDeploymentPolicy(deploymentPolicyDefinitionBean);

        } catch (AutoscalerServiceInvalidPolicyExceptionException e) {
            String backendErrorMessage = e.getFaultMessage().getInvalidPolicyException().getMessage();
            return Response.status(Response.Status.BAD_REQUEST).entity(new ResponseMessageBean(
                    ResponseMessageBean.ERROR, backendErrorMessage)).build();
        } catch (AutoscalerServiceInvalidDeploymentPolicyExceptionException e) {
            String backendErrorMessage = e.getFaultMessage().getInvalidDeploymentPolicyException().getMessage();
            return Response.status(Response.Status.BAD_REQUEST).entity(new ResponseMessageBean(
                    ResponseMessageBean.ERROR, backendErrorMessage)).build();
        } catch (AutoscalerServiceDeploymentPolicyNotExistsExceptionException e) {
            return Response.status(Response.Status.NOT_FOUND).entity(new ResponseMessageBean(
                    ResponseMessageBean.ERROR, "Deployment policy not found")).build();
        }
        URI url = uriInfo.getAbsolutePathBuilder().path(deploymentPolicyID).build();
        return Response.ok(url).entity(new ResponseMessageBean(ResponseMessageBean.SUCCESS,
                String.format("Deployment policy updated successfully: " + "[deployment-policy-id] %s",
                        deploymentPolicyID))).build();
    }

    /**
     * Updates the Deployment Policy Definition.
     *
     * @param deploymentPolicyId the deployment policy id
     * @return 200 if deployment policy is successfully removed
     * @throws RestAPIException the rest api exception
     */
    @DELETE
    @Path("/deploymentPolicies/{deploymentPolicyId}")
    @Produces("application/json")
    @Consumes("application/json")
    @AuthorizationAction("/permission/stratos/deploymentPolicies/manage")
    public Response removeDeploymentPolicy(
            @PathParam("deploymentPolicyId") String deploymentPolicyId) throws RestAPIException {
        try {
            StratosApiV41Utils.removeDeploymentPolicy(deploymentPolicyId);
        } catch (AutoscalerServiceDeploymentPolicyNotExistsExceptionException e) {
            return Response.status(Response.Status.NOT_FOUND).entity(new ResponseMessageBean(
                    ResponseMessageBean.ERROR, "Deployment policy not found")).build();
        } catch (AutoscalerServiceUnremovablePolicyExceptionException e) {
            return Response.status(Response.Status.BAD_REQUEST).entity(new ResponseMessageBean(
                    ResponseMessageBean.ERROR, "Deployment policy is in use")).build();
        }
        URI url = uriInfo.getAbsolutePathBuilder().path(deploymentPolicyId).build();
        return Response.ok(url).entity(new ResponseMessageBean(ResponseMessageBean.SUCCESS,
                String.format("Deployment policy removed successfully: " + "[deployment-policy-id] %s",
                        deploymentPolicyId))).build();
    }

    /**
     * Creates the cartridge definition.
     *
     * @param cartridgeDefinitionBean the cartridge definition bean
     * @return 201 if cartridge is successfully created, 409 if cartridge already exists.
     * @throws RestAPIException the rest api exception
     */
    @POST
    @Path("/cartridges")
    @Produces("application/json")
    @Consumes("application/json")
    @AuthorizationAction("/permission/stratos/cartridges/manage")
    public Response addCartridge(
            CartridgeBean cartridgeDefinitionBean) throws RestAPIException {

        String cartridgeType = cartridgeDefinitionBean.getType();
        CartridgeBean cartridgeBean = StratosApiV41Utils.getCartridgeForValidate(cartridgeType);
        if (cartridgeBean != null) {
            String msg = String.format("Cartridge already exists: [cartridge-type] %s", cartridgeType);
            log.warn(msg);
            return Response.status(Response.Status.CONFLICT)
                    .entity(new ResponseMessageBean(ResponseMessageBean.ERROR, msg)).build();
        }

        StratosApiV41Utils.addCartridge(cartridgeDefinitionBean);
        URI url = uriInfo.getAbsolutePathBuilder().path(cartridgeType).build();
        return Response.created(url).entity(new ResponseMessageBean(ResponseMessageBean.SUCCESS,
                String.format("Cartridge added successfully: [cartridge-type] %s", cartridgeType))).build();
    }

    /**
     * Updates the cartridge definition.
     *
     * @param cartridgeDefinitionBean the cartridge definition bean
     * @return 201 if cartridge successfully updated
     * @throws RestAPIException the rest api exception
     */
    @PUT
    @Path("/cartridges")
    @Produces("application/json")
    @Consumes("application/json")
    @AuthorizationAction("/permission/stratos/cartridges/manage")
    public Response updateCartridge(
            CartridgeBean cartridgeDefinitionBean) throws RestAPIException {
        StratosApiV41Utils.updateCartridge(cartridgeDefinitionBean);
        URI url = uriInfo.getAbsolutePathBuilder().path(cartridgeDefinitionBean.getType()).build();
        return Response.ok(url)
                .entity(new ResponseMessageBean(ResponseMessageBean.SUCCESS, "Cartridge updated successfully"))
                .build();

    }

    /**
     * Gets all available cartridges.
     *
     * @return 200 if cartridges exists, 404 if no cartridges found
     * @throws RestAPIException the rest api exception
     */
    @GET
    @Path("/cartridges")
    @Produces("application/json")
    @Consumes("application/json")
    @AuthorizationAction("/permission/stratos/cartridges/view")
    public Response getCartridges()
            throws RestAPIException {

        //We pass null to searching string and multi-tenant parameter since we do not need to do any filtering
        List<CartridgeBean> cartridges = StratosApiV41Utils.getAvailableCartridges(null, null, getConfigContext());
        if (cartridges == null || cartridges.isEmpty()) {
            return Response.status(Response.Status.NOT_FOUND).entity(new ResponseMessageBean(
                    ResponseMessageBean.ERROR, "No cartridges found")).build();
        }
        CartridgeBean[] cartridgeArray = cartridges.toArray(new CartridgeBean[cartridges.size()]);
        return Response.ok().entity(cartridgeArray).build();
    }

    /**
     * Gets a single cartridge by type
     *
     * @param cartridgeType Cartridge type
     * @return 200 if specified cartridge exists, 404 if not
     * @throws RestAPIException
     */
    @GET
    @Path("/cartridges/{cartridgeType}")
    @Produces("application/json")
    @Consumes("application/json")
    @AuthorizationAction("/permission/stratos/cartridges/view")
    public Response getCartridge(
            @PathParam("cartridgeType") String cartridgeType) throws RestAPIException {
        CartridgeBean cartridge;
        try {
            cartridge = StratosApiV41Utils.getCartridge(cartridgeType);
            return Response.ok().entity(cartridge).build();
        } catch (RestAPIException e) {
            return Response.status(Response.Status.NOT_FOUND).entity(new ResponseMessageBean(
                    ResponseMessageBean.ERROR, "Cartridge not found")).build();
        }
    }

    /**
     * Returns cartridges by category.
     *
     * @param filter   Filter
     * @param criteria Criteria
     * @return 200 if cartridges are found for specified filter, 404 if none found
     * @throws RestAPIException
     */
    @GET
    @Path("/cartridges/filter/{filter}")
    @Produces("application/json")
    @Consumes("application/json")
    @AuthorizationAction("/permission/stratos/cartridges/view")
    public Response getCartridgesByFilter(
            @DefaultValue("") @PathParam("filter") String filter, @QueryParam("criteria") String criteria)
            throws RestAPIException {
        List<CartridgeBean> cartridges = StratosApiV41Utils.
                getCartridgesByFilter(filter, criteria, getConfigContext());
        if (cartridges == null || cartridges.isEmpty()) {
            return Response.status(Response.Status.NOT_FOUND).entity(new ResponseMessageBean(
                    ResponseMessageBean.ERROR, "No cartridges found")).build();
        }

        CartridgeBean[] cartridgeArray = cartridges.toArray(new CartridgeBean[cartridges.size()]);
        return Response.ok().entity(cartridgeArray).build();
    }

    /**
     * Returns a specific cartridge by category.
     *
     * @param filter        Filter
     * @param cartridgeType Cartridge Type
     * @return 200 if a cartridge is found for specified filter, 404 if none found
     * @throws RestAPIException
     */
    @GET
    @Path("/cartridges/{cartridgeType}/filter/{filter}")
    @Produces("application/json")
    @Consumes("application/json")
    @AuthorizationAction("/permission/stratos/cartridges/view")
    public Response getCartridgeByFilter(
            @PathParam("cartridgeType") String cartridgeType, @DefaultValue("") @PathParam("filter") String filter)
            throws RestAPIException {
        CartridgeBean cartridge;

        cartridge = StratosApiV41Utils.getCartridgeByFilter(filter, cartridgeType, getConfigContext());
        if (cartridge == null) {
            return Response.status(Response.Status.NOT_FOUND).entity(new ResponseMessageBean(
                    ResponseMessageBean.ERROR, "No cartridges found for this filter")).build();
        }
        return Response.ok().entity(cartridge).build();

    }

    /**
     * Deletes a cartridge definition.
     *
     * @param cartridgeType the cartridge type
     * @return 200 if cartridge is successfully removed
     * @throws RestAPIException the rest api exception
     */
    @DELETE
    @Path("/cartridges/{cartridgeType}")
    @Produces("application/json")
    @Consumes("application/json")
    @AuthorizationAction("/permission/stratos/cartridges/manage")
    public Response removeCartridge(
            @PathParam("cartridgeType") String cartridgeType) throws RestAPIException {
        try {
            StratosApiV41Utils.removeCartridge(cartridgeType);
            return Response.ok().entity(new ResponseMessageBean(ResponseMessageBean.SUCCESS,
                    String.format("Cartridge deleted successfully: [cartridge-type] %s", cartridgeType))).build();
        } catch (RemoteException e) {
            return Response.status(Response.Status.BAD_REQUEST).entity(new ResponseMessageBean(
                    ResponseMessageBean.ERROR, e.getMessage())).build();
        } catch (CloudControllerServiceInvalidCartridgeTypeExceptionException e) {
            return Response.status(Response.Status.BAD_REQUEST).entity(new ResponseMessageBean(
                    ResponseMessageBean.ERROR, e.getFaultMessage().getInvalidCartridgeTypeException().getMessage()))
                    .build();<commit_msg>handling RemoteException<commit_after>/*
 * 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.stratos.rest.endpoint.api;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.apache.stratos.autoscaler.stub.*;
import org.apache.stratos.cloud.controller.stub.*;
import org.apache.stratos.common.beans.ResponseMessageBean;
import org.apache.stratos.common.beans.TenantInfoBean;
import org.apache.stratos.common.beans.UserInfoBean;
import org.apache.stratos.common.beans.application.ApplicationBean;
import org.apache.stratos.common.beans.application.ApplicationNetworkPartitionIdListBean;
import org.apache.stratos.common.beans.application.domain.mapping.ApplicationDomainMappingsBean;
import org.apache.stratos.common.beans.application.domain.mapping.DomainMappingBean;
import org.apache.stratos.common.beans.application.signup.ApplicationSignUpBean;
import org.apache.stratos.common.beans.artifact.repository.GitNotificationPayloadBean;
import org.apache.stratos.common.beans.cartridge.CartridgeBean;
import org.apache.stratos.common.beans.cartridge.CartridgeGroupBean;
import org.apache.stratos.common.beans.kubernetes.KubernetesClusterBean;
import org.apache.stratos.common.beans.kubernetes.KubernetesHostBean;
import org.apache.stratos.common.beans.kubernetes.KubernetesMasterBean;
import org.apache.stratos.common.beans.partition.NetworkPartitionBean;
import org.apache.stratos.common.beans.policy.autoscale.AutoscalePolicyBean;
import org.apache.stratos.common.beans.policy.deployment.ApplicationPolicyBean;
import org.apache.stratos.common.beans.policy.deployment.DeploymentPolicyBean;
import org.apache.stratos.common.beans.topology.ApplicationInfoBean;
import org.apache.stratos.common.beans.topology.ClusterBean;
import org.apache.stratos.common.exception.InvalidEmailException;
import org.apache.stratos.manager.service.stub.StratosManagerServiceApplicationSignUpExceptionException;
import org.apache.stratos.manager.service.stub.StratosManagerServiceDomainMappingExceptionException;
import org.apache.stratos.rest.endpoint.Utils;
import org.apache.stratos.rest.endpoint.annotation.AuthorizationAction;
import org.apache.stratos.rest.endpoint.annotation.SuperTenantService;
import org.apache.stratos.rest.endpoint.exception.*;
import org.wso2.carbon.context.PrivilegedCarbonContext;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpSession;
import javax.ws.rs.*;
import javax.ws.rs.core.Context;
import javax.ws.rs.core.MediaType;
import javax.ws.rs.core.Response;
import javax.ws.rs.core.UriInfo;
import java.net.URI;
import java.rmi.RemoteException;
import java.util.ArrayList;
import java.util.List;

/**
 * Stratos API v4.1 for Stratos 4.1.0 release.
 */
@Path("/")
public class StratosApiV41 extends AbstractApi {
    private static final Log log = LogFactory.getLog(StratosApiV41.class);

    @Context
    HttpServletRequest httpServletRequest;
    @Context
    UriInfo uriInfo;

    /**
     * This method is used by clients such as the CLI to verify the Stratos manager URL.
     *
     * @return the response
     * @throws RestAPIException the rest api exception
     */
    @GET
    @Path("/init")
    @AuthorizationAction("/permission/admin/login")
    public Response initialize()
            throws RestAPIException {
        ResponseMessageBean response = new ResponseMessageBean(ResponseMessageBean.SUCCESS,
                "Successfully authenticated");
        return Response.ok(response).build();
    }

    /**
     * This method gets called by the client who are interested in using session mechanism to authenticate
     * themselves in subsequent calls. This method call get authenticated by the basic authenticator.
     * Once the authenticated call received, the method creates a session and returns the session id.
     *
     * @return The session id related with the session
     */
    @GET
    @Path("/session")
    @Produces("application/json")
    @Consumes("application/json")
    @AuthorizationAction("/permission/admin/login")
    public Response getSession() {
        HttpSession httpSession = httpServletRequest.getSession(true);//create session if not found
        PrivilegedCarbonContext carbonContext = PrivilegedCarbonContext.getThreadLocalCarbonContext();
        httpSession.setAttribute("userName", carbonContext.getUsername());
        httpSession.setAttribute("tenantDomain", carbonContext.getTenantDomain());
        httpSession.setAttribute("tenantId", carbonContext.getTenantId());

        String sessionId = httpSession.getId();
        return Response.ok().header("WWW-Authenticate", "Basic").type(MediaType.APPLICATION_JSON).
                entity(Utils.buildAuthenticationSuccessMessage(sessionId)).build();
    }

    /**
     * Creates the Deployment Policy Definition.
     *
     * @param deploymentPolicyDefinitionBean the deployment policy bean
     * @return 201 if deployment policy is successfully added
     * @throws RestAPIException the rest api exception
     */
    @POST
    @Path("/deploymentPolicies")
    @Produces("application/json")
    @Consumes("application/json")
    @AuthorizationAction("/permission/stratos/deploymentPolicies/manage")
    public Response addDeploymentPolicy(
            DeploymentPolicyBean deploymentPolicyDefinitionBean) throws RestAPIException {

        String deploymentPolicyID = deploymentPolicyDefinitionBean.getId();
        try {
            StratosApiV41Utils.addDeploymentPolicy(deploymentPolicyDefinitionBean);
        } catch (AutoscalerServiceInvalidDeploymentPolicyExceptionException e) {
            String backendErrorMessage = e.getFaultMessage().getInvalidDeploymentPolicyException().getMessage();
            return Response.status(Response.Status.BAD_REQUEST).entity(new ResponseMessageBean(
                    ResponseMessageBean.ERROR, backendErrorMessage)).build();
        } catch (AutoscalerServiceDeploymentPolicyAlreadyExistsExceptionException e) {
            return Response.status(Response.Status.CONFLICT).entity(new ResponseMessageBean(
                    ResponseMessageBean.ERROR, "Deployment policy already exists")).build();
        }
        URI url = uriInfo.getAbsolutePathBuilder().path(deploymentPolicyID).build();
        return Response.created(url).entity(new ResponseMessageBean(ResponseMessageBean.SUCCESS,
                String.format("Deployment policy added successfully: " + "[deployment-policy-id] %s",
                        deploymentPolicyID))).build();
    }

    /**
     * Get deployment policy by deployment policy id
     *
     * @return 200 if deployment policy is found, 404 if not
     * @throws RestAPIException
     */
    @GET
    @Path("/deploymentPolicies/{deploymentPolicyId}")
    @Produces("application/json")
    @Consumes("application/json")
    @AuthorizationAction("/permission/stratos/deploymentPolicies/view")
    public Response getDeploymentPolicy(
            @PathParam("deploymentPolicyId") String deploymentPolicyId) throws RestAPIException {
        DeploymentPolicyBean deploymentPolicyBean = StratosApiV41Utils.getDeployementPolicy(deploymentPolicyId);
        if (deploymentPolicyBean == null) {
            return Response.status(Response.Status.NOT_FOUND).entity(new ResponseMessageBean(
                    ResponseMessageBean.ERROR, "Deployment policy not found")).build();
        }
        return Response.ok(deploymentPolicyBean).build();
    }

    /**
     * Get deployment policies
     *
     * @return 200 with the list of deployment policies
     * @throws RestAPIException
     */
    @GET
    @Path("/deploymentPolicies")
    @Produces("application/json")
    @Consumes("application/json")
    @AuthorizationAction("/permission/stratos/deploymentPolicies/view")
    public Response getDeploymentPolicies()
            throws RestAPIException {
        DeploymentPolicyBean[] deploymentPolicies = StratosApiV41Utils.getDeployementPolicies();
        if (deploymentPolicies == null || deploymentPolicies.length == 0) {
            return Response.status(Response.Status.NOT_FOUND).entity(new ResponseMessageBean(
                    ResponseMessageBean.ERROR, "No deployment policies found")).build();
        }

        return Response.ok(deploymentPolicies).build();
    }

    /**
     * Updates the Deployment Policy Definition.
     *
     * @param deploymentPolicyDefinitionBean the deployment policy bean
     * @return 200 if deployment policy is successfully updated
     * @throws RestAPIException the rest api exception
     */
    @PUT
    @Path("/deploymentPolicies")
    @Produces("application/json")
    @Consumes("application/json")
    @AuthorizationAction("/permission/stratos/deploymentPolicies/manage")
    public Response updateDeploymentPolicy(
            DeploymentPolicyBean deploymentPolicyDefinitionBean) throws RestAPIException {

        String deploymentPolicyID = deploymentPolicyDefinitionBean.getId();
        // TODO :: Deployment policy validation

        try {

            StratosApiV41Utils.updateDeploymentPolicy(deploymentPolicyDefinitionBean);

        } catch (AutoscalerServiceInvalidPolicyExceptionException e) {
            String backendErrorMessage = e.getFaultMessage().getInvalidPolicyException().getMessage();
            return Response.status(Response.Status.BAD_REQUEST).entity(new ResponseMessageBean(
                    ResponseMessageBean.ERROR, backendErrorMessage)).build();
        } catch (AutoscalerServiceInvalidDeploymentPolicyExceptionException e) {
            String backendErrorMessage = e.getFaultMessage().getInvalidDeploymentPolicyException().getMessage();
            return Response.status(Response.Status.BAD_REQUEST).entity(new ResponseMessageBean(
                    ResponseMessageBean.ERROR, backendErrorMessage)).build();
        } catch (AutoscalerServiceDeploymentPolicyNotExistsExceptionException e) {
            return Response.status(Response.Status.NOT_FOUND).entity(new ResponseMessageBean(
                    ResponseMessageBean.ERROR, "Deployment policy not found")).build();
        }
        URI url = uriInfo.getAbsolutePathBuilder().path(deploymentPolicyID).build();
        return Response.ok(url).entity(new ResponseMessageBean(ResponseMessageBean.SUCCESS,
                String.format("Deployment policy updated successfully: " + "[deployment-policy-id] %s",
                        deploymentPolicyID))).build();
    }

    /**
     * Updates the Deployment Policy Definition.
     *
     * @param deploymentPolicyId the deployment policy id
     * @return 200 if deployment policy is successfully removed
     * @throws RestAPIException the rest api exception
     */
    @DELETE
    @Path("/deploymentPolicies/{deploymentPolicyId}")
    @Produces("application/json")
    @Consumes("application/json")
    @AuthorizationAction("/permission/stratos/deploymentPolicies/manage")
    public Response removeDeploymentPolicy(
            @PathParam("deploymentPolicyId") String deploymentPolicyId) throws RestAPIException {
        try {
            StratosApiV41Utils.removeDeploymentPolicy(deploymentPolicyId);
        } catch (AutoscalerServiceDeploymentPolicyNotExistsExceptionException e) {
            return Response.status(Response.Status.NOT_FOUND).entity(new ResponseMessageBean(
                    ResponseMessageBean.ERROR, "Deployment policy not found")).build();
        } catch (AutoscalerServiceUnremovablePolicyExceptionException e) {
            return Response.status(Response.Status.BAD_REQUEST).entity(new ResponseMessageBean(
                    ResponseMessageBean.ERROR, "Deployment policy is in use")).build();
        }
        URI url = uriInfo.getAbsolutePathBuilder().path(deploymentPolicyId).build();
        return Response.ok(url).entity(new ResponseMessageBean(ResponseMessageBean.SUCCESS,
                String.format("Deployment policy removed successfully: " + "[deployment-policy-id] %s",
                        deploymentPolicyId))).build();
    }

    /**
     * Creates the cartridge definition.
     *
     * @param cartridgeDefinitionBean the cartridge definition bean
     * @return 201 if cartridge is successfully created, 409 if cartridge already exists.
     * @throws RestAPIException the rest api exception
     */
    @POST
    @Path("/cartridges")
    @Produces("application/json")
    @Consumes("application/json")
    @AuthorizationAction("/permission/stratos/cartridges/manage")
    public Response addCartridge(
            CartridgeBean cartridgeDefinitionBean) throws RestAPIException {

        String cartridgeType = cartridgeDefinitionBean.getType();
        CartridgeBean cartridgeBean = StratosApiV41Utils.getCartridgeForValidate(cartridgeType);
        if (cartridgeBean != null) {
            String msg = String.format("Cartridge already exists: [cartridge-type] %s", cartridgeType);
            log.warn(msg);
            return Response.status(Response.Status.CONFLICT)
                    .entity(new ResponseMessageBean(ResponseMessageBean.ERROR, msg)).build();
        }

        StratosApiV41Utils.addCartridge(cartridgeDefinitionBean);
        URI url = uriInfo.getAbsolutePathBuilder().path(cartridgeType).build();
        return Response.created(url).entity(new ResponseMessageBean(ResponseMessageBean.SUCCESS,
                String.format("Cartridge added successfully: [cartridge-type] %s", cartridgeType))).build();
    }

    /**
     * Updates the cartridge definition.
     *
     * @param cartridgeDefinitionBean the cartridge definition bean
     * @return 201 if cartridge successfully updated
     * @throws RestAPIException the rest api exception
     */
    @PUT
    @Path("/cartridges")
    @Produces("application/json")
    @Consumes("application/json")
    @AuthorizationAction("/permission/stratos/cartridges/manage")
    public Response updateCartridge(
            CartridgeBean cartridgeDefinitionBean) throws RestAPIException {
        StratosApiV41Utils.updateCartridge(cartridgeDefinitionBean);
        URI url = uriInfo.getAbsolutePathBuilder().path(cartridgeDefinitionBean.getType()).build();
        return Response.ok(url)
                .entity(new ResponseMessageBean(ResponseMessageBean.SUCCESS, "Cartridge updated successfully"))
                .build();

    }

    /**
     * Gets all available cartridges.
     *
     * @return 200 if cartridges exists, 404 if no cartridges found
     * @throws RestAPIException the rest api exception
     */
    @GET
    @Path("/cartridges")
    @Produces("application/json")
    @Consumes("application/json")
    @AuthorizationAction("/permission/stratos/cartridges/view")
    public Response getCartridges()
            throws RestAPIException {

        //We pass null to searching string and multi-tenant parameter since we do not need to do any filtering
        List<CartridgeBean> cartridges = StratosApiV41Utils.getAvailableCartridges(null, null, getConfigContext());
        if (cartridges == null || cartridges.isEmpty()) {
            return Response.status(Response.Status.NOT_FOUND).entity(new ResponseMessageBean(
                    ResponseMessageBean.ERROR, "No cartridges found")).build();
        }
        CartridgeBean[] cartridgeArray = cartridges.toArray(new CartridgeBean[cartridges.size()]);
        return Response.ok().entity(cartridgeArray).build();
    }

    /**
     * Gets a single cartridge by type
     *
     * @param cartridgeType Cartridge type
     * @return 200 if specified cartridge exists, 404 if not
     * @throws RestAPIException
     */
    @GET
    @Path("/cartridges/{cartridgeType}")
    @Produces("application/json")
    @Consumes("application/json")
    @AuthorizationAction("/permission/stratos/cartridges/view")
    public Response getCartridge(
            @PathParam("cartridgeType") String cartridgeType) throws RestAPIException {
        CartridgeBean cartridge;
        try {
            cartridge = StratosApiV41Utils.getCartridge(cartridgeType);
            return Response.ok().entity(cartridge).build();
        } catch (RestAPIException e) {
            return Response.status(Response.Status.NOT_FOUND).entity(new ResponseMessageBean(
                    ResponseMessageBean.ERROR, "Cartridge not found")).build();
        }
    }

    /**
     * Returns cartridges by category.
     *
     * @param filter   Filter
     * @param criteria Criteria
     * @return 200 if cartridges are found for specified filter, 404 if none found
     * @throws RestAPIException
     */
    @GET
    @Path("/cartridges/filter/{filter}")
    @Produces("application/json")
    @Consumes("application/json")
    @AuthorizationAction("/permission/stratos/cartridges/view")
    public Response getCartridgesByFilter(
            @DefaultValue("") @PathParam("filter") String filter, @QueryParam("criteria") String criteria)
            throws RestAPIException {
        List<CartridgeBean> cartridges = StratosApiV41Utils.
                getCartridgesByFilter(filter, criteria, getConfigContext());
        if (cartridges == null || cartridges.isEmpty()) {
            return Response.status(Response.Status.NOT_FOUND).entity(new ResponseMessageBean(
                    ResponseMessageBean.ERROR, "No cartridges found")).build();
        }

        CartridgeBean[] cartridgeArray = cartridges.toArray(new CartridgeBean[cartridges.size()]);
        return Response.ok().entity(cartridgeArray).build();
    }

    /**
     * Returns a specific cartridge by category.
     *
     * @param filter        Filter
     * @param cartridgeType Cartridge Type
     * @return 200 if a cartridge is found for specified filter, 404 if none found
     * @throws RestAPIException
     */
    @GET
    @Path("/cartridges/{cartridgeType}/filter/{filter}")
    @Produces("application/json")
    @Consumes("application/json")
    @AuthorizationAction("/permission/stratos/cartridges/view")
    public Response getCartridgeByFilter(
            @PathParam("cartridgeType") String cartridgeType, @DefaultValue("") @PathParam("filter") String filter)
            throws RestAPIException {
        CartridgeBean cartridge;

        cartridge = StratosApiV41Utils.getCartridgeByFilter(filter, cartridgeType, getConfigContext());
        if (cartridge == null) {
            return Response.status(Response.Status.NOT_FOUND).entity(new ResponseMessageBean(
                    ResponseMessageBean.ERROR, "No cartridges found for this filter")).build();
        }
        return Response.ok().entity(cartridge).build();

    }

    /**
     * Deletes a cartridge definition.
     *
     * @param cartridgeType the cartridge type
     * @return 200 if cartridge is successfully removed
     * @throws RestAPIException the rest api exception
     */
    @DELETE
    @Path("/cartridges/{cartridgeType}")
    @Produces("application/json")
    @Consumes("application/json")
    @AuthorizationAction("/permission/stratos/cartridges/manage")
    public Response removeCartridge(
            @PathParam("cartridgeType") String cartridgeType) throws RestAPIException {
        try {
            StratosApiV41Utils.removeCartridge(cartridgeType);
            return Response.ok().entity(new ResponseMessageBean(ResponseMessageBean.SUCCESS,
                    String.format("Cartridge deleted successfully: [cartridge-type] %s", cartridgeType))).build();
        } catch (RemoteException e) {
            throw new RestAPIException(e.getMessage());
        } catch (CloudControllerServiceInvalidCartridgeTypeExceptionException e) {
            return Response.status(Response.Status.BAD_REQUEST).entity(new ResponseMessageBean(
                    ResponseMessageBean.ERROR, e.getFaultMessage().getInvalidCartridgeTypeException().getMessage()))
                    .build();
{'fraction_non_alphanumeric': 0.09579803291459733, 'fraction_numerical': 0.0046255721102346865, 'mean_word_length': 3.5001095530236634, 'pattern_counts': {'":': 0, '<': 7, '<?xml version=': 0, '>': 7, 'https://': 0, 'lorem ipsum': 0, 'www.': 2, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '6039505', 'n_tokens_mistral': 10708, 'n_tokens_neox': 10185, 'n_words': 2242}