2 * ============LICENSE_START=======================================================
4 * ================================================================================
5 * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved.
6 * ================================================================================
7 * Licensed under the Apache License, Version 2.0 (the "License");
8 * you may not use this file except in compliance with the License.
9 * You may obtain a copy of the License at
11 * http://www.apache.org/licenses/LICENSE-2.0
13 * Unless required by applicable law or agreed to in writing, software
14 * distributed under the License is distributed on an "AS IS" BASIS,
15 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16 * See the License for the specific language governing permissions and
17 * limitations under the License.
18 * ============LICENSE_END=========================================================
21 package org.openecomp.sdc.be.externalapi.servlet;
23 import com.fasterxml.jackson.databind.ObjectMapper;
24 import com.jcabi.aspects.Loggable;
25 import fj.data.Either;
26 import io.swagger.annotations.*;
27 import javax.inject.Inject;
28 import org.apache.commons.lang3.StringUtils;
29 import org.elasticsearch.common.Strings;
30 import org.json.simple.JSONObject;
31 import org.json.simple.parser.JSONParser;
32 import org.json.simple.parser.ParseException;
33 import org.openecomp.sdc.be.components.impl.ComponentInstanceBusinessLogic;
34 import org.openecomp.sdc.be.components.impl.ElementBusinessLogic;
35 import org.openecomp.sdc.be.components.impl.GroupBusinessLogic;
36 import org.openecomp.sdc.be.components.impl.ResourceBusinessLogic;
37 import org.openecomp.sdc.be.components.impl.ResourceImportManager;
38 import org.openecomp.sdc.be.components.impl.exceptions.ComponentException;
39 import org.openecomp.sdc.be.components.lifecycle.LifecycleBusinessLogic;
40 import org.openecomp.sdc.be.components.lifecycle.LifecycleChangeInfoBase;
41 import org.openecomp.sdc.be.components.lifecycle.LifecycleChangeInfoWithAction;
42 import org.openecomp.sdc.be.config.BeEcompErrorManager;
43 import org.openecomp.sdc.be.dao.api.ActionStatus;
44 import org.openecomp.sdc.be.datamodel.api.CategoryTypeEnum;
45 import org.openecomp.sdc.be.datatypes.enums.AssetTypeEnum;
46 import org.openecomp.sdc.be.datatypes.enums.ComponentTypeEnum;
47 import org.openecomp.sdc.be.datatypes.enums.FilterKeyEnum;
48 import org.openecomp.sdc.be.datatypes.enums.ResourceTypeEnum;
49 import org.openecomp.sdc.be.ecomp.converters.AssetMetadataConverter;
50 import org.openecomp.sdc.be.externalapi.servlet.representation.AssetMetadata;
51 import org.openecomp.sdc.be.impl.ComponentsUtils;
52 import org.openecomp.sdc.be.impl.ServletUtils;
53 import org.openecomp.sdc.be.model.Component;
54 import org.openecomp.sdc.be.model.LifeCycleTransitionEnum;
55 import org.openecomp.sdc.be.model.Resource;
56 import org.openecomp.sdc.be.model.User;
57 import org.openecomp.sdc.be.model.category.CategoryDefinition;
58 import org.openecomp.sdc.be.model.category.SubCategoryDefinition;
59 import org.openecomp.sdc.be.resources.data.auditing.AuditingActionEnum;
60 import org.openecomp.sdc.be.resources.data.auditing.model.DistributionData;
61 import org.openecomp.sdc.be.resources.data.auditing.model.ResourceCommonInfo;
62 import org.openecomp.sdc.be.servlets.AbstractValidationsServlet;
63 import org.openecomp.sdc.be.servlets.RepresentationUtils;
64 import org.openecomp.sdc.be.user.UserBusinessLogic;
65 import org.openecomp.sdc.be.utils.CommonBeUtils;
66 import org.openecomp.sdc.common.api.Constants;
67 import org.openecomp.sdc.common.datastructure.Wrapper;
68 import org.openecomp.sdc.common.log.wrappers.Logger;
69 import org.openecomp.sdc.common.util.ValidationUtils;
70 import org.openecomp.sdc.exception.ResponseFormat;
72 import javax.inject.Singleton;
73 import javax.servlet.ServletContext;
74 import javax.servlet.http.HttpServletRequest;
76 import javax.ws.rs.core.Context;
77 import javax.ws.rs.core.MediaType;
78 import javax.ws.rs.core.Response;
79 import java.io.IOException;
80 import java.util.Arrays;
81 import java.util.List;
82 import java.util.Optional;
83 import java.util.stream.Collectors;
85 @Loggable(prepend = true, value = Loggable.DEBUG, trim = false)
87 @Api(value = "CRUD External Servlet", description = "This Servlet serves external users for creating assets and changing their lifecycle state")
89 public class CrudExternalServlet extends AbstractValidationsServlet {
92 private HttpServletRequest request;
94 private static final Logger log = Logger.getLogger(CrudExternalServlet.class);
95 private final ElementBusinessLogic elementBusinessLogic;
96 private final AssetMetadataConverter assetMetadataUtils;
97 private final LifecycleBusinessLogic lifecycleBusinessLogic;
98 private final ResourceBusinessLogic resourceBusinessLogic;
101 public CrudExternalServlet(UserBusinessLogic userBusinessLogic,
102 ComponentInstanceBusinessLogic componentInstanceBL,
103 ComponentsUtils componentsUtils, ServletUtils servletUtils,
104 ResourceImportManager resourceImportManager,
105 ElementBusinessLogic elementBusinessLogic,
106 AssetMetadataConverter assetMetadataUtils,
107 LifecycleBusinessLogic lifecycleBusinessLogic,
108 ResourceBusinessLogic resourceBusinessLogic) {
109 super(userBusinessLogic, componentInstanceBL, componentsUtils, servletUtils, resourceImportManager);
110 this.elementBusinessLogic = elementBusinessLogic;
111 this.assetMetadataUtils = assetMetadataUtils;
112 this.lifecycleBusinessLogic = lifecycleBusinessLogic;
113 this.resourceBusinessLogic = resourceBusinessLogic;
117 * Creates a new Resource
122 * @param instanceIdHeader
126 @Path("/{assetType}")
127 @Consumes(MediaType.APPLICATION_JSON)
128 @Produces(MediaType.APPLICATION_JSON)
129 @ApiOperation(value = "creates a resource", httpMethod = "POST", notes = "Creates a resource")
130 @ApiResponses(value = {
131 @ApiResponse(code = 200, message = "ECOMP component is authenticated and Asset created", response = Resource.class),
132 @ApiResponse(code = 400, message = "Missing X-ECOMP-InstanceID HTTP header - POL5001"),
133 @ApiResponse(code = 401, message = "ECOMP component should authenticate itself and to re-send again HTTP request with its Basic Authentication credentials - POL5002"),
134 @ApiResponse(code = 403, message = "ECOMP component is not authorized - POL5003"),
135 @ApiResponse(code = 404, message = "Error: Requested '%1' (uuid) resource was not found - SVC4063"),
136 @ApiResponse(code = 405, message = "Method Not Allowed : Invalid HTTP method type used ( PUT,DELETE,POST will be rejected) - POL4050"),
137 @ApiResponse(code = 500, message = "The GET request failed either due to internal SDC problem. ECOMP Component should continue the attempts to get the needed information - POL5000"),
138 @ApiResponse(code = 400, message = "The name provided for the newly created resource is already in use for another resource in SDC - SVC4050"),
139 @ApiResponse(code = 400, message = "Invalid field format. One of the provided fields does not comply with the field rules - SVC4126"),
140 @ApiResponse(code = 400, message = "Missing request body. The post request did not contain the expected body - SVC4500"),
141 @ApiResponse(code = 400, message = "The resource name is missing in the request body - SVC4062"),
142 @ApiResponse(code = 400, message = "Create VFCMT request: VFCMT description has wrong format - SVC4064"),
143 @ApiResponse(code = 400, message = "Create VFCMT request: VFCMT description has wrong format (exceeds limit) - SVC4065"),
144 @ApiResponse(code = 400, message = "Create VFCMT request: VFCMT tags exceeds character limit - SVC4066"),
145 @ApiResponse(code = 400, message = "Create VFCMT request: VFCMT vendor name exceeds character limit - SVC4067"),
146 @ApiResponse(code = 400, message = "Create VFCMT request: VFCMT vendor release exceeds character limit - SVC4068"),
147 @ApiResponse(code = 400, message = "Create VFCMT request: VFCMT ATT Contact has wrong format - SVC4069"),
148 @ApiResponse(code = 400, message = "Create VFCMT request: VFCMT name has wrong format - SVC4070"),
149 @ApiResponse(code = 400, message = "Create VFCMT request: VFCMT vendor name has wrong format - SVC4071"),
150 @ApiResponse(code = 400, message = "Create VFCMT request: VFCMT vendor release has wrong format - SVC4072"),
151 @ApiResponse(code = 400, message = "Create VFCMT request: VFCMT name exceeds character limit - SVC4073")})
152 @ApiImplicitParams({@ApiImplicitParam(required = true, dataType = "org.openecomp.sdc.be.model.Resource", paramType = "body", value = "json describe the created resource")})
153 public Response createResourceExternal(
154 @ApiParam(value = "Determines the format of the body of the request", required = true)@HeaderParam(value = Constants.CONTENT_TYPE_HEADER) String contentType,
155 @ApiParam(value = "The user id", required = true)@HeaderParam(value = Constants.USER_ID_HEADER) final String userId,
156 @ApiParam(value = "X-ECOMP-RequestID header", required = false)@HeaderParam(value = Constants.X_ECOMP_REQUEST_ID_HEADER) String requestId,
157 @ApiParam(value = "X-ECOMP-InstanceID header", required = true)@HeaderParam(value = Constants.X_ECOMP_INSTANCE_ID_HEADER) final String instanceIdHeader,
158 @ApiParam(value = "Determines the format of the body of the response", required = false)@HeaderParam(value = Constants.ACCEPT_HEADER) String accept,
159 @ApiParam(value = "The username and password", required = true)@HeaderParam(value = Constants.AUTHORIZATION_HEADER) String authorization,
160 @ApiParam(value = "The requested asset type", required = true, allowableValues = "resources, services")@PathParam("assetType") final String assetType,
161 @ApiParam( hidden = true) String data) {
165 Wrapper<ResponseFormat> responseWrapper = new Wrapper<>();
166 String requestURI = request.getRequestURI();
167 String url = request.getMethod() + " " + requestURI;
168 log.debug("Start handle request of {}", url);
169 Resource resource = null;
170 User modifier = null;
171 ResourceCommonInfo resourceCommonInfo = new ResourceCommonInfo(ComponentTypeEnum.RESOURCE.getValue());
173 ServletContext context = request.getSession().getServletContext();
175 // Validate X-ECOMP-InstanceID Header
176 if (responseWrapper.isEmpty()) {
177 validateXECOMPInstanceIDHeader(instanceIdHeader, responseWrapper);
179 // Validate USER_ID Header
180 if (responseWrapper.isEmpty()) {
181 validateHttpCspUserIdHeader(userId, responseWrapper);
183 // Validate assetType
184 if (responseWrapper.isEmpty()) {
185 if( !AssetTypeEnum.RESOURCES.getValue().equals(assetType) ){
186 responseWrapper.setInnerElement(getComponentsUtils().getResponseFormat(ActionStatus.RESTRICTED_OPERATION));
189 //Validate resource type
190 if(responseWrapper.isEmpty()){
191 JSONParser parser = new JSONParser();
192 JSONObject jsonObj = (JSONObject) parser.parse(data);
193 String resourceType = (String) jsonObj.get(FilterKeyEnum.RESOURCE_TYPE.getName());
194 if( StringUtils.isEmpty(resourceType) || !ResourceTypeEnum.containsName(resourceType) ){
195 resourceCommonInfo.setResourceName((String) jsonObj.get("name"));
196 responseWrapper.setInnerElement(getComponentsUtils().getResponseFormat(ActionStatus.INVALID_CONTENT));
199 // Convert the user json to a resource
200 if (responseWrapper.isEmpty()) {
201 modifier = new User();
202 modifier.setUserId(userId);
203 Either<Resource, ResponseFormat> eitherResource = getComponentsUtils()
204 .convertJsonToObjectUsingObjectMapper(data, modifier, Resource.class,
205 null, ComponentTypeEnum.RESOURCE);
206 if( eitherResource.isRight() ){
207 responseWrapper.setInnerElement(eitherResource.right().value());
210 resource = eitherResource.left().value();
214 //validate name exist
215 if(responseWrapper.isEmpty()){
216 if( Strings.isEmpty(resource.getName())){
217 responseWrapper.setInnerElement(getComponentsUtils().getResponseFormat(
218 ActionStatus.MISSING_COMPONENT_NAME, ComponentTypeEnum.RESOURCE.getValue()));
223 if(responseWrapper.isEmpty()){
224 resource.setDerivedFrom(Arrays.asList("tosca.nodes.Root"));
225 resource.setSystemName(ValidationUtils.convertToSystemName(resource.getName()));
226 resource.setToscaResourceName(CommonBeUtils.generateToscaResourceName(ResourceTypeEnum.VFCMT.name(),
227 resource.getSystemName()));
228 handleCategories(context, data, resource, responseWrapper);
230 // Create the resource in the dataModel
231 if (responseWrapper.isEmpty()) {
232 resource = resourceBusinessLogic.createResource(resource, null,
233 modifier, null, null);
234 return buildCreatedResourceResponse(resource, context, responseWrapper);
236 return buildErrorResponse(responseWrapper.getInnerElement());
238 } catch (IOException|ParseException e) {
239 final String message = "failed to create vfc monitoring template resource";
240 BeEcompErrorManager.getInstance().logBeRestApiGeneralError(message);
241 log.debug(message, e);
242 responseWrapper.setInnerElement(getComponentsUtils().getResponseFormat(ActionStatus.GENERAL_ERROR));
243 return buildErrorResponse(responseWrapper.getInnerElement());
244 } catch (ComponentException e){
245 ResponseFormat responseFormat = getComponentsUtils().getResponseFormat(e);
246 responseWrapper.setInnerElement(responseFormat);
247 return buildErrorResponse(responseFormat);
250 getComponentsUtils().auditCreateResourceExternalApi(responseWrapper.getInnerElement(), resourceCommonInfo, request, resource);
255 * Changing the lifecycle of an asset
256 * @param jsonChangeInfo The description - request body
257 * @param assetType The requested asset type.Valid values are: resources / services (for VFCMT – use "resources")
258 * @param uuid The uuid of the desired resource to be changed
259 * @param lifecycleTransition The lifecycle operation to be performed on the asset.Valid values are:Checkin / Checkout / CERTIFICATION_REQUEST
264 @Path("/{assetType}/{uuid}/lifecycleState/{lifecycleOperation}")
265 @Consumes(MediaType.APPLICATION_JSON)
266 @Produces(MediaType.APPLICATION_JSON)
267 @ApiOperation(value = "Change Resource lifecycle State", httpMethod = "POST")
268 @ApiResponses(value = {
269 @ApiResponse(code = 200, message = "Resource state changed", response = AssetMetadata.class),
270 @ApiResponse(code = 400, message = "Missing X-ECOMP-InstanceID HTTP header - POL5001"),
271 @ApiResponse(code = 401, message = "ECOMP component should authenticate itself and to re-send again HTTP request with its Basic Authentication credentials - POL5002"),
272 @ApiResponse(code = 403, message = "ECOMP component is not authorized - POL5003"),
273 @ApiResponse(code = 404, message = "Error: Requested '%1' (uuid) resource was not found - SVC4063"),
274 @ApiResponse(code = 405, message = "Method Not Allowed : Invalid HTTP method type used ( PUT,DELETE,POST will be rejected) - POL4050"),
275 @ApiResponse(code = 500, message = "The GET request failed either due to internal SDC problem. ECOMP Component should continue the attempts to get the needed information - POL5000"),
276 @ApiResponse(code = 403, message = "Asset is already checked-out by another user - SVC4085"),
277 @ApiResponse(code = 403, message = "Asset is being edited by different user. Only one user can checkout and edit an asset on given time. The asset will be available for checkout after the other user will checkin the asset - SVC4080")})
278 @ApiImplicitParams({@ApiImplicitParam(required = true, dataType = "org.openecomp.sdc.be.components.lifecycle.LifecycleChangeInfoWithAction", paramType = "body", value = "userRemarks - Short description (free text) about the asset version being changed")})
279 public Response changeResourceStateExternal(
280 @ApiParam(value = "Determines the format of the body of the request", required = true)@HeaderParam(value = Constants.CONTENT_TYPE_HEADER) String contentType,
281 @ApiParam(value = "The user id", required = true)@HeaderParam(value = Constants.USER_ID_HEADER) final String userId,
282 @ApiParam(value = "X-ECOMP-RequestID header", required = false)@HeaderParam(value = Constants.X_ECOMP_REQUEST_ID_HEADER) String requestId,
283 @ApiParam(value = "X-ECOMP-InstanceID header", required = true)@HeaderParam(value = Constants.X_ECOMP_INSTANCE_ID_HEADER) final String instanceIdHeader,
284 @ApiParam(value = "Determines the format of the body of the response", required = false)@HeaderParam(value = Constants.ACCEPT_HEADER) String accept,
285 @ApiParam(value = "The username and password", required = true)@HeaderParam(value = Constants.AUTHORIZATION_HEADER) String authorization,
286 @ApiParam(allowableValues = "checkout, checkin", required = true) @PathParam(value = "lifecycleOperation") final String lifecycleTransition,
287 @ApiParam(value = "id of component to be changed") @PathParam(value = "uuid") final String uuid,
288 @ApiParam(value = "validValues: resources / services ", allowableValues = ComponentTypeEnum.RESOURCE_PARAM_NAME + "," + ComponentTypeEnum.SERVICE_PARAM_NAME) @PathParam(value = "assetType") final String assetType,
289 @ApiParam( hidden = true) String jsonChangeInfo) {
291 Response response = null;
295 String requestURI = request.getRequestURI();
296 String url = request.getMethod() + " " + requestURI;
297 log.debug("Start handle request of {}", url);
299 //get the business logic
300 ServletContext context = request.getSession().getServletContext();
302 Wrapper<ResponseFormat> responseWrapper = runValidations(assetType);
303 ComponentTypeEnum componentType = ComponentTypeEnum.findByParamName(assetType);
304 Component component = null;
305 Component responseObject = null;
306 User modifier = null;
309 // Validate X-ECOMP-InstanceID Header
310 if (responseWrapper.isEmpty()) {
311 validateXECOMPInstanceIDHeader(instanceIdHeader, responseWrapper);
314 if (responseWrapper.isEmpty()) {
316 Either<User, ResponseFormat> eitherGetUser = getUser(request, userId);
317 if (eitherGetUser.isRight()) {
318 ResponseFormat responseFormat = eitherGetUser.right().value();
319 responseWrapper.setInnerElement(responseFormat);
320 return buildErrorResponse(responseFormat);
322 modifier = eitherGetUser.left().value();
324 //get the component id from the uuid
325 Either<Component, ResponseFormat> latestVersion = lifecycleBusinessLogic.getLatestComponentByUuid(componentType, uuid);
326 if (latestVersion.isRight()) {
327 ResponseFormat responseFormat = latestVersion.right().value();
328 responseWrapper.setInnerElement(responseFormat);
329 return buildErrorResponse(responseFormat);
331 component = latestVersion.left().value();
332 String componentId = component.getUniqueId();
334 //validate the transition is valid
335 Either<LifeCycleTransitionEnum, ResponseFormat> validateEnum = validateTransitionEnum(lifecycleTransition, modifier);
336 if (validateEnum.isRight()) {
337 ResponseFormat responseFormat = validateEnum.right().value();
338 responseWrapper.setInnerElement(responseFormat);
339 return buildErrorResponse(responseFormat);
341 LifeCycleTransitionEnum transitionEnum = validateEnum.left().value();
344 LifecycleChangeInfoWithAction changeInfo = new LifecycleChangeInfoWithAction();
346 if (jsonChangeInfo != null && !jsonChangeInfo.isEmpty()) {
347 ObjectMapper mapper = new ObjectMapper();
348 changeInfo = new LifecycleChangeInfoWithAction(mapper.readValue(jsonChangeInfo, LifecycleChangeInfoBase.class).getUserRemarks());
351 catch (IOException e) {
352 BeEcompErrorManager.getInstance().logBeInvalidJsonInput("convertJsonToObject");
353 log.debug("failed to convert from json {}", jsonChangeInfo, e);
354 ResponseFormat responseFormat = getComponentsUtils().getInvalidContentErrorAndAudit(modifier, componentId, AuditingActionEnum.CHECKOUT_RESOURCE);
355 responseWrapper.setInnerElement(responseFormat);
356 return buildErrorResponse(responseFormat);
359 //execute business logic
360 Either<? extends Component, ResponseFormat> actionResponse = lifecycleBusinessLogic
361 .changeComponentState(componentType, componentId, modifier, transitionEnum, changeInfo, false, true);
362 if (actionResponse.isRight()) {
363 log.info("failed to change resource state");
364 ResponseFormat responseFormat = actionResponse.right().value();
365 responseWrapper.setInnerElement(responseFormat);
366 return buildErrorResponse(responseFormat);
369 log.debug("change state successful !!!");
370 responseObject = actionResponse.left().value();
371 response = buildCreatedResourceResponse(responseObject, context, responseWrapper);
373 response = buildErrorResponse(responseWrapper.getInnerElement());
377 } catch (IOException e) {
378 BeEcompErrorManager.getInstance().logBeRestApiGeneralError("Change Lifecycle State");
379 log.debug("change lifecycle state failed with exception", e);
380 ResponseFormat responseFormat = getComponentsUtils().getResponseFormat(ActionStatus.GENERAL_ERROR);
381 responseWrapper.setInnerElement(responseFormat);
382 return buildErrorResponse(responseFormat);
383 } catch (ComponentException e){
384 ResponseFormat responseFormat = getComponentsUtils().getResponseFormat(e);
385 responseWrapper.setInnerElement(responseFormat);
386 return buildErrorResponse(responseFormat);
389 getComponentsUtils().auditChangeLifecycleAction(responseWrapper.getInnerElement(), componentType, requestId,
390 component, responseObject, new DistributionData(instanceIdHeader, requestURI), modifier);
394 private Response buildCreatedResourceResponse(Component resource, ServletContext context,
395 Wrapper<ResponseFormat> responseWrapper) throws IOException {
396 ResponseFormat responseFormat;
398 Either<? extends AssetMetadata, ResponseFormat> resMetadata = assetMetadataUtils
399 .convertToSingleAssetMetadata(resource, request.getRequestURL().toString(),
401 if (resMetadata.isRight()) {
402 log.debug("Asset conversion Failed");
403 responseFormat = resMetadata.right().value();
404 responseWrapper.setInnerElement(responseFormat);
405 response = buildErrorResponse(responseFormat);
407 final AssetMetadata assetData = resMetadata.left().value();
408 assetData.setToscaModelURL(null);
410 responseWrapper.setInnerElement(getComponentsUtils().getResponseFormat(ActionStatus.CREATED));
411 Object representation = RepresentationUtils.toRepresentation(assetData);
412 response = buildOkResponse(getComponentsUtils().getResponseFormat(ActionStatus.CREATED), representation);
417 private void handleCategories(ServletContext context, String data, Resource resource,
418 Wrapper<ResponseFormat> responseWrapper) {
420 JSONParser parser = new JSONParser();
421 JSONObject jsonObj = (JSONObject) parser.parse(data);
422 String category = (String) jsonObj.get(CategoryTypeEnum.CATEGORY.getValue());
423 String subcategory = (String) jsonObj.get(CategoryTypeEnum.SUBCATEGORY.getValue());
424 if (Strings.isEmpty(category)) {
425 responseWrapper.setInnerElement(getComponentsUtils().getResponseFormat(
426 ActionStatus.COMPONENT_MISSING_CATEGORY, ComponentTypeEnum.RESOURCE.getValue()));
428 else if (Strings.isEmpty(subcategory)) {
429 responseWrapper.setInnerElement(getComponentsUtils().getResponseFormat(
430 ActionStatus.COMPONENT_MISSING_SUBCATEGORY));
432 if (responseWrapper.isEmpty()) {
433 // get All Categories
434 Either<List<CategoryDefinition>, ActionStatus> allResourceCategories = elementBusinessLogic
435 .getAllResourceCategories();
436 // Error fetching categories
437 if (allResourceCategories.isRight()) {
438 responseWrapper.setInnerElement(
439 getComponentsUtils().getResponseFormat(allResourceCategories.right().value()));
441 addCategories(resource, category, subcategory, allResourceCategories, responseWrapper);
444 } catch (ParseException e) {
445 log.debug("Exception occured in addCategories: {}", e.getMessage(), e);
446 responseWrapper.setInnerElement(getComponentsUtils().getResponseFormat(ActionStatus.GENERAL_ERROR));
451 private void addCategories(Resource resource, String category, String subcategory,
452 Either<List<CategoryDefinition>, ActionStatus> allResourceCategories,
453 Wrapper<ResponseFormat> responseWrapper) {
454 Optional<CategoryDefinition> optionalCategory =
455 // Stream of all the categories
456 allResourceCategories.left().value().stream()
457 // filter in only relevant category
458 .filter(e -> e.getName().equals(category))
461 if (!optionalCategory.isPresent()) {
462 responseWrapper.setInnerElement(getComponentsUtils().getResponseFormat(
463 ActionStatus.COMPONENT_INVALID_CATEGORY, ComponentTypeEnum.RESOURCE.getValue()));
465 CategoryDefinition categoryDefinition = optionalCategory.get();
467 List<SubCategoryDefinition> subCaregories =
468 // Stream of all sub-categories of the relevant
470 categoryDefinition.getSubcategories().stream()
471 // filter in only relevant sub-category
472 .filter(e -> e.getName().equals(subcategory))
474 .collect(Collectors.toList());
476 if( subCaregories.isEmpty() ){
477 responseWrapper.setInnerElement(getComponentsUtils().getResponseFormat(
478 ActionStatus.COMPONENT_INVALID_SUBCATEGORY, ComponentTypeEnum.RESOURCE.getValue()));
481 categoryDefinition.setSubcategories(subCaregories);
482 resource.setCategories(Arrays.asList(categoryDefinition));
493 private Wrapper<ResponseFormat> runValidations(final String assetType) {
494 Wrapper<ResponseFormat> responseWrapper = new Wrapper<>();
496 // Validate X-ECOMP-InstanceID Header
497 if (responseWrapper.isEmpty()) {
498 String instanceId = request.getHeader(Constants.X_ECOMP_INSTANCE_ID_HEADER);
499 validateXECOMPInstanceIDHeader(instanceId,responseWrapper);
501 // Validate USER_ID Header
502 if (responseWrapper.isEmpty()) {
503 validateHttpCspUserIdHeader(request.getHeader(Constants.USER_ID_HEADER),responseWrapper);
505 // Validate assetType
506 if (responseWrapper.isEmpty()) {
507 if( !AssetTypeEnum.RESOURCES.getValue().equals(assetType) && !AssetTypeEnum.SERVICES.getValue().equals(assetType)){
508 responseWrapper.setInnerElement(getComponentsUtils().getResponseFormat(ActionStatus.RESTRICTED_OPERATION));
512 return responseWrapper;
515 private Either<LifeCycleTransitionEnum, ResponseFormat> validateTransitionEnum(final String lifecycleTransition, User user) {
516 LifeCycleTransitionEnum transitionEnum = LifeCycleTransitionEnum.CHECKOUT;
518 transitionEnum = LifeCycleTransitionEnum.getFromDisplayName(lifecycleTransition);
519 } catch (IllegalArgumentException e) {
520 log.info("state operation is not valid. operations allowed are: {}", LifeCycleTransitionEnum.valuesAsString(), e);
521 ResponseFormat error = getComponentsUtils().getInvalidContentErrorAndAudit(user, "", AuditingActionEnum.CHECKOUT_RESOURCE);
522 return Either.right(error);
524 return Either.left(transitionEnum);