1 package org.openecomp.sdc.be.servlets;
3 import com.jcabi.aspects.Loggable;
5 import io.swagger.annotations.*;
6 import org.apache.commons.lang3.StringUtils;
7 import org.openecomp.sdc.be.components.impl.PolicyBusinessLogic;
8 import org.openecomp.sdc.be.components.impl.ResourceImportManager;
9 import org.openecomp.sdc.be.config.BeEcompErrorManager;
10 import org.openecomp.sdc.be.dao.api.ActionStatus;
11 import org.openecomp.sdc.be.datatypes.elements.PolicyTargetType;
12 import org.openecomp.sdc.be.datatypes.elements.PropertyDataDefinition;
13 import org.openecomp.sdc.be.datatypes.enums.ComponentTypeEnum;
14 import org.openecomp.sdc.be.impl.ComponentsUtils;
15 import org.openecomp.sdc.be.impl.ServletUtils;
16 import org.openecomp.sdc.be.model.PolicyDefinition;
17 import org.openecomp.sdc.be.model.PolicyTargetDTO;
18 import org.openecomp.sdc.common.api.Constants;
19 import org.openecomp.sdc.common.datastructure.Wrapper;
20 import org.openecomp.sdc.common.log.wrappers.Logger;
21 import org.openecomp.sdc.exception.ResponseFormat;
22 import org.springframework.stereotype.Controller;
24 import javax.servlet.http.HttpServletRequest;
26 import javax.ws.rs.core.Context;
27 import javax.ws.rs.core.MediaType;
28 import javax.ws.rs.core.Response;
29 import java.util.HashMap;
30 import java.util.List;
32 import java.util.stream.Collectors;
35 * Provides REST API to create, retrieve, update, delete a policy
37 @Loggable(prepend = true, value = Loggable.DEBUG, trim = false)
39 @Api(value = "Policy Servlet")
41 @Consumes(MediaType.APPLICATION_JSON)
42 @Produces(MediaType.APPLICATION_JSON)
43 public class PolicyServlet extends AbstractValidationsServlet {
45 private static final Logger log = Logger.getLogger(PolicyServlet.class);
46 private final PolicyBusinessLogic policyBusinessLogic;
48 public PolicyServlet(PolicyBusinessLogic policyBusinessLogic, ServletUtils servletUtils, ResourceImportManager resourceImportManager, ComponentsUtils componentsUtils) {
49 this.policyBusinessLogic = policyBusinessLogic;
50 this.servletUtils = servletUtils;
51 this.resourceImportManager = resourceImportManager;
52 this.componentsUtils = componentsUtils;
56 @Path("/{containerComponentType}/{componentId}/policies/{policyTypeName}")
57 @ApiOperation(value = "Create Policy", httpMethod = "POST", notes = "Returns created Policy", response = Response.class)
58 @ApiResponses(value = {@ApiResponse(code = 201, message = "Policy created"), @ApiResponse(code = 403, message = "Restricted operation"), @ApiResponse(code = 400, message = "Invalid content / Missing content"),
59 @ApiResponse(code = 409, message = "Policy already exist"), @ApiResponse(code = 404, message = "Component not found")})
60 public Response createPolicy(@PathParam("componentId") final String containerComponentId,
61 @ApiParam(value = "valid values: resources / services", allowableValues = ComponentTypeEnum.RESOURCE_PARAM_NAME + "," + ComponentTypeEnum.SERVICE_PARAM_NAME) @PathParam("containerComponentType") final String containerComponentType,
62 @PathParam("policyTypeName") final String policyTypeName,
63 @HeaderParam(value = Constants.USER_ID_HEADER) @ApiParam(value = "USER_ID of modifier user", required = true) String userId,
64 @Context final HttpServletRequest request) {
67 Wrapper<Response> responseWrapper = new Wrapper<>();
69 Wrapper<ComponentTypeEnum> componentTypeWrapper = validateComponentTypeAndUserId(containerComponentType, userId, responseWrapper);
70 if (responseWrapper.isEmpty()) {
71 responseWrapper.setInnerElement(policyBusinessLogic.createPolicy(componentTypeWrapper.getInnerElement(), containerComponentId, policyTypeName, userId, true)
72 .either(l -> buildOkResponse(getComponentsUtils().getResponseFormat(ActionStatus.CREATED), l),
73 this::buildErrorResponse));
75 } catch (Exception e) {
76 BeEcompErrorManager.getInstance().logBeRestApiGeneralError("Create Policy");
77 log.error("Failed to create policy. The exception {} occurred. ", e);
78 responseWrapper.setInnerElement(buildErrorResponse(getComponentsUtils().getResponseFormat(ActionStatus.GENERAL_ERROR)));
80 return responseWrapper.getInnerElement();
84 @Path("/{containerComponentType}/{componentId}/policies/{policyId}")
85 @ApiOperation(value = "Update Policy metadata", httpMethod = "PUT", notes = "Returns updated Policy", response = Response.class)
86 @ApiResponses(value = {@ApiResponse(code = 200, message = "Policy updated"), @ApiResponse(code = 403, message = "Restricted operation"), @ApiResponse(code = 400, message = "Invalid content / Missing content"),
87 @ApiResponse(code = 404, message = "component / policy Not found")})
88 public Response updatePolicy(@PathParam("componentId") final String containerComponentId,
89 @ApiParam(value = "valid values: resources / services", allowableValues = ComponentTypeEnum.RESOURCE_PARAM_NAME + "," + ComponentTypeEnum.SERVICE_PARAM_NAME) @PathParam("containerComponentType") final String containerComponentType,
90 @PathParam("policyId") final String policyId, @HeaderParam(value = Constants.USER_ID_HEADER) @ApiParam(value = "USER_ID of modifier user", required = true) String userId,
91 @ApiParam(value = "PolicyDefinition", required = true) String policyData, @Context final HttpServletRequest request) {
94 Wrapper<Response> responseWrapper = new Wrapper<>();
96 Wrapper<ComponentTypeEnum> componentTypeWrapper = validateComponentTypeAndUserId(containerComponentType, userId, responseWrapper);
97 Wrapper<PolicyDefinition> policyWrapper = new Wrapper<>();
98 if (responseWrapper.isEmpty()) {
99 convertJsonToObjectOfClass(policyData, policyWrapper, PolicyDefinition.class, responseWrapper);
100 if (policyWrapper.isEmpty()) {
101 responseWrapper.setInnerElement(buildErrorResponse(getComponentsUtils().getResponseFormat(ActionStatus.INVALID_CONTENT)));
104 if (!policyWrapper.isEmpty()) {
105 policyWrapper.getInnerElement().setUniqueId(policyId);
106 responseWrapper.setInnerElement(policyBusinessLogic.updatePolicy(componentTypeWrapper.getInnerElement(), containerComponentId, policyWrapper.getInnerElement(), userId, true)
107 .either(this::buildOkResponse,
108 this::buildErrorResponse));
111 } catch (Exception e) {
112 BeEcompErrorManager.getInstance().logBeRestApiGeneralError("Update Policy");
113 log.error("Failed to update policy. The exception {} occurred. ", e);
114 responseWrapper.setInnerElement(buildErrorResponse(getComponentsUtils().getResponseFormat(ActionStatus.GENERAL_ERROR)));
116 return responseWrapper.getInnerElement();
120 @Path("/{containerComponentType}/{componentId}/policies/{policyId}")
121 @ApiOperation(value = "Get Policy", httpMethod = "GET", notes = "Returns Policy", response = Response.class)
122 @ApiResponses(value = {@ApiResponse(code = 200, message = "Policy was found"), @ApiResponse(code = 403, message = "Restricted operation"), @ApiResponse(code = 400, message = "Invalid content / Missing content"),
123 @ApiResponse(code = 404, message = "component / policy Not found")})
124 public Response getPolicy(@PathParam("componentId") final String containerComponentId,
125 @ApiParam(value = "valid values: resources / services", allowableValues = ComponentTypeEnum.RESOURCE_PARAM_NAME + "," + ComponentTypeEnum.SERVICE_PARAM_NAME) @PathParam("containerComponentType") final String containerComponentType,
126 @PathParam("policyId") final String policyId, @HeaderParam(value = Constants.USER_ID_HEADER) @ApiParam(value = "USER_ID of modifier user", required = true) String userId,
127 @Context final HttpServletRequest request) {
130 Wrapper<Response> responseWrapper = new Wrapper<>();
132 Wrapper<ComponentTypeEnum> componentTypeWrapper = validateComponentTypeAndUserId(containerComponentType, userId, responseWrapper);
133 if (responseWrapper.isEmpty()) {
134 responseWrapper.setInnerElement(policyBusinessLogic.getPolicy(componentTypeWrapper.getInnerElement(), containerComponentId, policyId, userId)
135 .either(this::buildOkResponse,
136 this::buildErrorResponse));
139 } catch (Exception e) {
140 BeEcompErrorManager.getInstance().logBeRestApiGeneralError("Get Policy");
141 log.error("Failed to retrieve policy. The exception {} occurred. ", e);
142 responseWrapper.setInnerElement(buildErrorResponse(getComponentsUtils().getResponseFormat(ActionStatus.GENERAL_ERROR)));
144 return responseWrapper.getInnerElement();
148 @Path("/{containerComponentType}/{componentId}/policies/{policyId}")
149 @ApiOperation(value = "Delete Policy", httpMethod = "DELETE", notes = "No body", response = Response.class)
150 @ApiResponses(value = {@ApiResponse(code = 204, message = "Policy was deleted"), @ApiResponse(code = 403, message = "Restricted operation"), @ApiResponse(code = 400, message = "Invalid content / Missing content"),
151 @ApiResponse(code = 404, message = "component / policy Not found")})
152 public Response deletePolicy(@PathParam("componentId") final String containerComponentId,
153 @ApiParam(value = "valid values: resources / services", allowableValues = ComponentTypeEnum.RESOURCE_PARAM_NAME + "," + ComponentTypeEnum.SERVICE_PARAM_NAME) @PathParam("containerComponentType") final String containerComponentType,
154 @PathParam("policyId") final String policyId, @HeaderParam(value = Constants.USER_ID_HEADER) @ApiParam(value = "USER_ID of modifier user", required = true) String userId,
155 @Context final HttpServletRequest request) {
158 Wrapper<Response> responseWrapper = new Wrapper<>();
160 Wrapper<ComponentTypeEnum> componentTypeWrapper = validateComponentTypeAndUserId(containerComponentType, userId, responseWrapper);
161 if (responseWrapper.isEmpty()) {
162 responseWrapper.setInnerElement(policyBusinessLogic.deletePolicy(componentTypeWrapper.getInnerElement(), containerComponentId, policyId, userId, true)
163 .either(l -> buildOkResponse(getComponentsUtils().getResponseFormat(ActionStatus.NO_CONTENT), null),
164 this::buildErrorResponse));
167 } catch (Exception e) {
168 BeEcompErrorManager.getInstance().logBeRestApiGeneralError("Delete Policy");
169 log.error("Failed to delete policy. The exception {} occurred. ", e);
170 responseWrapper.setInnerElement(buildErrorResponse(getComponentsUtils().getResponseFormat(ActionStatus.GENERAL_ERROR)));
172 return responseWrapper.getInnerElement();
176 @Path("/{containerComponentType}/{componentId}/policies/{policyId}/properties")
177 @ApiOperation(value = "Get component policy properties", httpMethod = "GET", notes = "Returns component policy properties", response = PropertyDataDefinition.class, responseContainer="List")
178 @ApiResponses(value = {@ApiResponse(code = 200, message = "Properties found"),@ApiResponse(code = 400, message = "invalid content - Error: containerComponentType is invalid"), @ApiResponse(code = 403, message = "Restricted operation"), @ApiResponse(code = 404, message = "Componentorpolicy not found"),
179 @ApiResponse(code = 500, message = "The GET request failed due to internal SDC problem.") })public Response getPolicyProperties(@ApiParam(value = "the id of the component which is the container of the policy") @PathParam("componentId") final String containerComponentId,
180 @ApiParam(value = "valid values: resources / services", allowableValues = ComponentTypeEnum.RESOURCE_PARAM_NAME + "," + ComponentTypeEnum.SERVICE_PARAM_NAME) @PathParam("containerComponentType") final String containerComponentType,
181 @ApiParam(value = "the id of the policy which its properties are to return") @PathParam("policyId") final String policyId,
182 @ApiParam(value = "the userid", required = true)@HeaderParam(value = Constants.USER_ID_HEADER) String userId,
183 @Context final HttpServletRequest request) {
186 return convertToComponentType(containerComponentType)
188 .bind(cmptType -> policyBusinessLogic.getPolicyProperties(cmptType, containerComponentId, policyId, userId))
189 .either(this::buildOkResponse,
190 this::buildErrorResponse);
191 } catch (Exception e) {
192 BeEcompErrorManager.getInstance().logBeRestApiGeneralError("get Policy properties");
193 log.debug("#getPolicyProperties - get Policy properties has failed.", e);
194 return buildErrorResponse(getComponentsUtils().getResponseFormat(ActionStatus.GENERAL_ERROR));
201 @Path("/{containerComponentType}/{componentId}/policies/{policyId}/properties")
202 @ApiOperation(value = "Update Policy properties", httpMethod = "PUT", notes = "Returns updated Policy", response = Response.class)
203 @ApiResponses(value = {@ApiResponse(code = 200, message = "Policy properties updated"), @ApiResponse(code = 403, message = "Restricted operation"), @ApiResponse(code = 400, message = "Invalid content / Missing content"),
204 @ApiResponse(code = 404, message = "component / policy Not found")})
205 public Response updatePolicyProperties(@PathParam("componentId") final String containerComponentId,
206 @ApiParam(value = "valid values: resources / services", allowableValues = ComponentTypeEnum.RESOURCE_PARAM_NAME + "," + ComponentTypeEnum.SERVICE_PARAM_NAME) @PathParam("containerComponentType") final String containerComponentType,
207 @PathParam("policyId") final String policyId, @HeaderParam(value = Constants.USER_ID_HEADER) @ApiParam(value = "USER_ID of modifier user", required = true) String userId,
208 @ApiParam(value = "PolicyDefinition", required = true) String policyData, @Context final HttpServletRequest request) {
210 Wrapper<Response> responseWrapper = new Wrapper<>();
212 Wrapper<ComponentTypeEnum> componentTypeWrapper = validateComponentTypeAndUserId(containerComponentType, userId, responseWrapper);
213 Wrapper<PropertyDataDefinition[]> propertiesWrapper = new Wrapper<>();
214 if (responseWrapper.isEmpty()) {
215 convertJsonToObjectOfClass(policyData, propertiesWrapper, PropertyDataDefinition[].class, responseWrapper);
216 if (propertiesWrapper.isEmpty()) {
217 responseWrapper.setInnerElement(buildErrorResponse(getComponentsUtils().getResponseFormat(ActionStatus.INVALID_CONTENT)));
220 if (!propertiesWrapper.isEmpty()) {
221 responseWrapper.setInnerElement(
222 policyBusinessLogic.updatePolicyProperties(componentTypeWrapper.getInnerElement(), containerComponentId, policyId, propertiesWrapper.getInnerElement(), userId, true)
223 .either(this::buildOkResponse, this::buildErrorResponse));
225 } catch (Exception e) {
226 BeEcompErrorManager.getInstance().logBeRestApiGeneralError("Update Policy");
227 log.error("Failed to update policy. The exception {} occurred. ", e);
228 responseWrapper.setInnerElement(buildErrorResponse(getComponentsUtils().getResponseFormat(ActionStatus.GENERAL_ERROR)));
230 return responseWrapper.getInnerElement();
233 private Wrapper<ComponentTypeEnum> validateComponentTypeAndUserId(final String containerComponentType, String userId, Wrapper<Response> responseWrapper) {
234 Wrapper<ComponentTypeEnum> componentTypeWrapper = new Wrapper<>();
235 if (StringUtils.isEmpty(userId)) {
236 log.error("Missing userId HTTP header. ");
237 responseWrapper.setInnerElement(buildErrorResponse(getComponentsUtils().getResponseFormat(ActionStatus.MISSING_USER_ID)));
239 if (responseWrapper.isEmpty()) {
240 validateComponentType(responseWrapper, componentTypeWrapper, containerComponentType);
242 return componentTypeWrapper;
246 @Path("/{containerComponentType}/{componentId}/policies/{policyId}/targets")
247 @Consumes(MediaType.APPLICATION_JSON)
248 @Produces(MediaType.APPLICATION_JSON)
249 @ApiOperation(value = "update policy targets", httpMethod = "POST", notes = "Returns updated Policy", response = Response.class)
250 @ApiResponses(value = {@ApiResponse(code = 201, message = "Policy target updated"), @ApiResponse(code = 403, message = "Restricted operation"), @ApiResponse(code = 400, message = "Invalid content / Missing content")})
251 public Response updatePolicyTargets(@PathParam("componentId") final String containerComponentId,
252 @ApiParam(value = "valid values: resources / services", allowableValues = ComponentTypeEnum.RESOURCE_PARAM_NAME + "," + ComponentTypeEnum.SERVICE_PARAM_NAME) @PathParam("containerComponentType") final String containerComponentType,
253 @PathParam("policyId") final String policyId,
254 @HeaderParam(value = Constants.USER_ID_HEADER) @ApiParam(value = "USER_ID of modifier user", required = true) String userId,
255 @Context final HttpServletRequest request,
256 List<PolicyTargetDTO> requestJson) {
259 return updatePolicyTargetsFromDTO(requestJson)
261 .bind(policyTarget -> updatePolicyTargetsFromMap(policyTarget, containerComponentType, containerComponentId, policyId, userId))
262 .either(this::buildOkResponse, this::buildErrorResponse);
264 } catch (Exception e) {
265 BeEcompErrorManager.getInstance().logBeRestApiGeneralError("Create Policy");
266 log.debug("Policy target update has been failed with the exception{}. ", e);
267 return buildErrorResponse(getComponentsUtils().getResponseFormat(ActionStatus.GENERAL_ERROR));
271 private Either<PolicyDefinition, ResponseFormat> updatePolicyTargetsFromMap(Map<PolicyTargetType, List<String>> policyTarget, String containerComponentType, String containerComponentId, String policyId, String userId) {
272 return convertToComponentType(containerComponentType)
274 .bind(cmptType -> policyBusinessLogic.updatePolicyTargets(cmptType, containerComponentId, policyId, policyTarget, userId));
277 private Either<Map<PolicyTargetType, List<String>>, ResponseFormat> updatePolicyTargetsFromDTO(List<PolicyTargetDTO> targetDTOList) {
278 Map<PolicyTargetType, List<String>> policyTarget = new HashMap<>();
279 for (PolicyTargetDTO currentTarget : targetDTOList) {
280 if(!addTargetsByType(policyTarget, currentTarget.getType(), currentTarget.getUniqueIds())){
281 return Either.right(componentsUtils.getResponseFormat(ActionStatus.POLICY_TARGET_TYPE_DOES_NOT_EXIST, currentTarget.getType()));
284 return Either.left(policyTarget);
288 public boolean addTargetsByType(Map<PolicyTargetType, List<String>> policyTarget, String type, List<String> uniqueIds) {
289 PolicyTargetType targetTypeEnum = PolicyTargetType.getByNameIgnoreCase(type);
290 if(targetTypeEnum != null){
291 policyTarget.put(targetTypeEnum, validateUniquenessOfIds(uniqueIds));
299 private List<String> validateUniquenessOfIds(List<String> uniqueIds) {
300 return uniqueIds.stream().distinct().collect(Collectors.toList());