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.servlets;
23 import com.fasterxml.jackson.core.JsonProcessingException;
24 import com.fasterxml.jackson.databind.ObjectMapper;
25 import com.fasterxml.jackson.databind.SerializationFeature;
26 import com.google.gson.Gson;
27 import com.google.gson.GsonBuilder;
28 import com.google.gson.reflect.TypeToken;
29 import com.jcabi.aspects.Loggable;
30 import fj.data.Either;
31 import io.swagger.v3.oas.annotations.Operation;
32 import io.swagger.v3.oas.annotations.Parameter;
33 import io.swagger.v3.oas.annotations.media.ArraySchema;
34 import io.swagger.v3.oas.annotations.media.Content;
35 import io.swagger.v3.oas.annotations.media.Schema;
36 import io.swagger.v3.oas.annotations.responses.ApiResponse;
37 import io.swagger.v3.oas.annotations.servers.Server;
38 import io.swagger.v3.oas.annotations.tags.Tag;
39 import java.io.IOException;
40 import java.io.InputStream;
41 import java.lang.reflect.Type;
42 import java.util.ArrayList;
43 import java.util.Arrays;
44 import java.util.List;
46 import java.util.Optional;
48 import javax.inject.Inject;
49 import javax.servlet.http.HttpServletRequest;
50 import javax.ws.rs.Consumes;
51 import javax.ws.rs.DELETE;
52 import javax.ws.rs.GET;
53 import javax.ws.rs.HeaderParam;
54 import javax.ws.rs.POST;
55 import javax.ws.rs.PUT;
56 import javax.ws.rs.Path;
57 import javax.ws.rs.PathParam;
58 import javax.ws.rs.Produces;
59 import javax.ws.rs.QueryParam;
60 import javax.ws.rs.core.Context;
61 import javax.ws.rs.core.MediaType;
62 import javax.ws.rs.core.Response;
63 import org.apache.commons.collections.CollectionUtils;
64 import org.apache.commons.io.IOUtils;
65 import org.apache.commons.lang.StringUtils;
66 import org.openecomp.sdc.be.components.impl.ComponentInstanceBusinessLogic;
67 import org.openecomp.sdc.be.components.impl.ComponentNodeFilterBusinessLogic;
68 import org.openecomp.sdc.be.components.impl.GroupBusinessLogic;
69 import org.openecomp.sdc.be.components.impl.ResourceImportManager;
70 import org.openecomp.sdc.be.components.impl.aaf.AafPermission;
71 import org.openecomp.sdc.be.components.impl.aaf.PermissionAllowed;
72 import org.openecomp.sdc.be.components.impl.exceptions.BusinessLogicException;
73 import org.openecomp.sdc.be.components.impl.exceptions.ByActionStatusComponentException;
74 import org.openecomp.sdc.be.components.impl.exceptions.ComponentException;
75 import org.openecomp.sdc.be.config.BeEcompErrorManager;
76 import org.openecomp.sdc.be.dao.api.ActionStatus;
77 import org.openecomp.sdc.be.datamodel.ForwardingPaths;
78 import org.openecomp.sdc.be.datatypes.elements.CINodeFilterDataDefinition;
79 import org.openecomp.sdc.be.datatypes.enums.ComponentTypeEnum;
80 import org.openecomp.sdc.be.datatypes.enums.CreatedFrom;
81 import org.openecomp.sdc.be.datatypes.enums.JsonPresentationFields;
82 import org.openecomp.sdc.be.impl.ComponentsUtils;
83 import org.openecomp.sdc.be.impl.ServletUtils;
84 import org.openecomp.sdc.be.info.CreateAndAssotiateInfo;
85 import org.openecomp.sdc.be.info.GroupDefinitionInfo;
86 import org.openecomp.sdc.be.model.ComponentInstance;
87 import org.openecomp.sdc.be.model.ComponentInstanceInput;
88 import org.openecomp.sdc.be.model.ComponentInstanceProperty;
89 import org.openecomp.sdc.be.model.PropertyConstraint;
90 import org.openecomp.sdc.be.model.RequirementCapabilityRelDef;
91 import org.openecomp.sdc.be.model.Service;
92 import org.openecomp.sdc.be.model.User;
93 import org.openecomp.sdc.be.model.operations.impl.PropertyOperation.PropertyConstraintDeserialiser;
94 import org.openecomp.sdc.be.user.UserBusinessLogic;
95 import org.openecomp.sdc.common.api.Constants;
96 import org.openecomp.sdc.common.datastructure.Wrapper;
97 import org.openecomp.sdc.common.log.elements.LoggerSupportability;
98 import org.openecomp.sdc.common.log.enums.LoggerSupportabilityActions;
99 import org.openecomp.sdc.common.log.enums.StatusCode;
100 import org.openecomp.sdc.common.log.wrappers.Logger;
101 import org.openecomp.sdc.exception.ResponseFormat;
102 import org.springframework.stereotype.Controller;
105 * Root resource (exposed at "/" path) .json.
107 @Loggable(prepend = true, value = Loggable.DEBUG, trim = false)
109 @Tag(name = "SDC Internal APIs")
110 @Server(url = "/sdc2/rest")
112 public class ComponentInstanceServlet extends AbstractValidationsServlet {
114 private static final String FAILED_TO_GET_PROPERTIES_OF_COMPONENT_INSTANCE_ID_IN_WITH_ID = "Failed to get properties of component instance ID: {} in {} with ID: {}";
115 private static final String GET_GROUP_ARTIFACT_BY_ID = "getGroupArtifactById";
116 private static final String GET_GROUP_ARTIFACT_BY_ID_UNEXPECTED_EXCEPTION = "getGroupArtifactById unexpected exception";
117 private static final String GET_START_HANDLE_REQUEST_OF = "(GET) Start handle request of {}";
118 private static final String START_HANDLE_REQUEST_OF_UPDATE_RESOURCE_INSTANCE_PROPERTY_RECEIVED_PROPERTY_IS = "Start handle request of updateResourceInstanceProperty. Received property is {}";
119 private static final String UPDATE_RESOURCE_INSTANCE = "Update Resource Instance";
120 private static final String RESOURCE_INSTANCE_UPDATE_RESOURCE_INSTANCE = "Resource Instance - updateResourceInstance";
121 private static final String UPDATE_RESOURCE_INSTANCE_WITH_EXCEPTION = "update resource instance with exception";
122 private static final String FAILED_TO_CONVERT_RECEIVED_DATA_TO_BE_FORMAT = "Failed to convert received data to BE format.";
123 private static final String EMPTY_BODY_WAS_SENT = "Empty body was sent.";
124 private static final String START_HANDLE_REQUEST_OF = "Start handle request of {}";
125 private static final String UNSUPPORTED_COMPONENT_TYPE = "Unsupported component type {}";
126 private static final String CREATE_AND_ASSOCIATE_RI_FAILED_WITH_EXCEPTION = "create and associate RI failed with exception: {}";
127 private static final Logger log = Logger.getLogger(ComponentInstanceServlet.class);
128 private static final Type PROPERTY_CONSTRAINT_TYPE = new TypeToken<PropertyConstraint>() {}.getType();
129 private static final Gson gsonDeserializer = new GsonBuilder().registerTypeAdapter(PROPERTY_CONSTRAINT_TYPE, new PropertyConstraintDeserialiser()).create();
130 private static final LoggerSupportability loggerSupportability = LoggerSupportability.getLogger(ComponentInstanceServlet.class.getName());
132 private final GroupBusinessLogic groupBL;
133 private final ComponentNodeFilterBusinessLogic nodeFilterBusinessLogic;
137 public ComponentInstanceServlet(UserBusinessLogic userBusinessLogic,
138 GroupBusinessLogic groupBL, ComponentInstanceBusinessLogic componentInstanceBL,
139 ComponentsUtils componentsUtils, ServletUtils servletUtils,
140 ResourceImportManager resourceImportManager,
141 ComponentNodeFilterBusinessLogic nodeFilterBusinessLogic) {
142 super(userBusinessLogic, componentInstanceBL, componentsUtils, servletUtils, resourceImportManager);
143 this.groupBL = groupBL;
144 this.nodeFilterBusinessLogic = nodeFilterBusinessLogic;
148 @Path("/{containerComponentType}/{componentId}/resourceInstance")
149 @Consumes(MediaType.APPLICATION_JSON)
150 @Produces(MediaType.APPLICATION_JSON)
151 @Operation(description = "Create ComponentInstance", method = "POST", summary = "Returns created ComponentInstance",
152 responses = {@ApiResponse(
153 content = @Content(array = @ArraySchema(schema = @Schema(implementation = Response.class)))),
154 @ApiResponse(responseCode = "201", description = "Component created"),
155 @ApiResponse(responseCode = "403", description = "Restricted operation"),
156 @ApiResponse(responseCode = "400", description = "Invalid content / Missing content"),
157 @ApiResponse(responseCode = "409", description = "Component instance already exist")})
158 @PermissionAllowed(AafPermission.PermNames.INTERNAL_ALL_VALUE)
159 public Response createComponentInstance(@Parameter(description = "RI object to be created", required = true) String data,
160 @PathParam("componentId") final String containerComponentId,
161 @Parameter(description = "valid values: resources / services",
162 schema = @Schema(allowableValues = {ComponentTypeEnum.RESOURCE_PARAM_NAME ,
163 ComponentTypeEnum.SERVICE_PARAM_NAME})) @PathParam("containerComponentType") final String containerComponentType,
164 @HeaderParam(value = Constants.USER_ID_HEADER) @Parameter(description = "USER_ID of modifier user",
165 required = true) String userId,
166 @Context final HttpServletRequest request) {
168 validateNotEmptyBody(data);
169 final ComponentInstance componentInstance;
171 componentInstance = RepresentationUtils.fromRepresentation(data, ComponentInstance.class);
172 componentInstance.setInvariantName(null);
173 componentInstance.setCreatedFrom(CreatedFrom.UI);
174 } catch (final Exception e) {
175 BeEcompErrorManager.getInstance().logBeRestApiGeneralError("Create Component Instance");
176 log.debug("create component instance failed with exception", e);
177 throw new ByActionStatusComponentException(ActionStatus.INVALID_CONTENT);
180 loggerSupportability.log(LoggerSupportabilityActions.CREATE_INSTANCE, StatusCode.STARTED,
181 "Starting to create component instance by {}", userId);
182 if (componentInstanceBusinessLogic == null) {
183 log.debug(UNSUPPORTED_COMPONENT_TYPE, containerComponentType);
184 return buildErrorResponse(
185 getComponentsUtils().getResponseFormat(ActionStatus.UNSUPPORTED_ERROR, containerComponentType));
187 final ComponentInstance actionResponse = componentInstanceBusinessLogic.
188 createComponentInstance(containerComponentType, containerComponentId, userId, componentInstance);
190 .log(LoggerSupportabilityActions.CREATE_INSTANCE, actionResponse.getComponentMetadataForSupportLog(),
191 StatusCode.COMPLETE, "Ending to create component instance by user {}", userId);
192 return buildOkResponse(getComponentsUtils().getResponseFormat(ActionStatus.CREATED), actionResponse);
197 @Path("/{containerComponentType}/{componentId}/resourceInstance/{componentInstanceId}")
198 @Consumes(MediaType.APPLICATION_JSON)
199 @Produces(MediaType.APPLICATION_JSON)
200 @Operation(description = "Update resource instance", method = "POST", summary = "Returns updated resource instance",
201 responses = {@ApiResponse(
202 content = @Content(array = @ArraySchema(schema = @Schema(implementation = Response.class)))),
203 @ApiResponse(responseCode = "200", description = "Resource instance updated"),
204 @ApiResponse(responseCode = "403", description = "Restricted operation"),
205 @ApiResponse(responseCode = "400", description = "Invalid content / Missing content")})
206 @PermissionAllowed(AafPermission.PermNames.INTERNAL_ALL_VALUE)
207 public Response updateComponentInstanceMetadata(@PathParam("componentId") final String componentId,
208 @PathParam("componentInstanceId") final String componentInstanceId,
209 @Parameter(description = "valid values: resources / services / products",
210 schema = @Schema(allowableValues = {ComponentTypeEnum.RESOURCE_PARAM_NAME,
211 ComponentTypeEnum.SERVICE_PARAM_NAME,
212 ComponentTypeEnum.PRODUCT_PARAM_NAME})) @PathParam("containerComponentType") final String containerComponentType,
213 @Context final HttpServletRequest request) throws IOException, BusinessLogicException {
215 final String url = request.getMethod() + " " + request.getRequestURI();
216 log.debug(START_HANDLE_REQUEST_OF, url);
217 loggerSupportability.log(LoggerSupportabilityActions.UPDATE_COMPONENT_INSTANCE,StatusCode.STARTED,"update Component Instance Metadata");
218 final String userId = request.getHeader(Constants.USER_ID_HEADER);
220 if (componentInstanceBusinessLogic == null) {
221 log.debug(UNSUPPORTED_COMPONENT_TYPE, containerComponentType);
222 return buildErrorResponse(getComponentsUtils().getResponseFormat(ActionStatus.UNSUPPORTED_ERROR,
223 containerComponentType));
225 componentInstanceBusinessLogic.validateUser(userId);
226 log.debug(START_HANDLE_REQUEST_OF, url);
227 final byte[] bytes = IOUtils.toByteArray(request.getInputStream());
229 if (bytes == null || bytes.length == 0) {
230 log.info(EMPTY_BODY_WAS_SENT);
231 return buildErrorResponse(getComponentsUtils().getResponseFormat(ActionStatus.INVALID_CONTENT));
234 final String data = new String(bytes);
235 final ComponentTypeEnum componentTypeEnum = ComponentTypeEnum.findByParamName(containerComponentType);
236 final Either<ComponentInstance, ResponseFormat> convertResponse = convertToResourceInstance(data);
237 if (convertResponse.isRight()) {
238 BeEcompErrorManager.getInstance().logBeSystemError(RESOURCE_INSTANCE_UPDATE_RESOURCE_INSTANCE);
239 log.debug(FAILED_TO_CONVERT_RECEIVED_DATA_TO_BE_FORMAT);
240 return buildErrorResponse(convertResponse.right().value());
244 final ComponentInstance componentInstance = convertResponse.left().value();
245 final Either<ComponentInstance, ResponseFormat> actionResponse = componentInstanceBusinessLogic
246 .updateComponentInstanceMetadata(containerComponentType, componentId, componentInstanceId, userId, componentInstance);
247 loggerSupportability.log(LoggerSupportabilityActions.UPDATE_COMPONENT_INSTANCE,actionResponse.left().value()
248 .getComponentMetadataForSupportLog(),StatusCode.COMPLETE,"update Component Instance Metadata by {}", userId);
249 if (actionResponse.isRight()) {
250 return buildErrorResponse(actionResponse.right().value());
253 final ComponentInstance resultValue = actionResponse.left().value();
254 if (ComponentTypeEnum.SERVICE.equals(componentTypeEnum) ||
255 ComponentTypeEnum.RESOURCE.equals(componentTypeEnum) &&
256 componentInstanceBusinessLogic.isVFC(componentInstance.getOriginType())) {
258 if(CollectionUtils.isNotEmpty(componentInstance.getDirectives())) {
259 final Optional<CINodeFilterDataDefinition> nodeFilterDataDefinition =
260 nodeFilterBusinessLogic.createNodeFilterIfNotExist(componentId, componentInstanceId,
261 true, componentTypeEnum);
262 if (!nodeFilterDataDefinition.isPresent()){
263 BeEcompErrorManager.getInstance().logBeSystemError("Failed to create node filter.");
264 log.error("Failed to create node filter.");
265 return buildErrorResponse(convertResponse.right().value());
267 resultValue.setNodeFilter(nodeFilterDataDefinition.get());
269 final Optional<String> result = nodeFilterBusinessLogic
270 .deleteNodeFilterIfExists(componentId, componentInstanceId, true, componentTypeEnum);
271 if (!result.isPresent()){
272 BeEcompErrorManager.getInstance().logBeSystemError("Failed to delete node filter.");
273 log.error("Failed to delete node filter.");
274 return buildErrorResponse(convertResponse.right().value());
276 resultValue.setNodeFilter(null);
280 return buildOkResponse(getComponentsUtils().getResponseFormat(ActionStatus.OK), actionResponse.left().value());
282 } catch (final Exception e) {
283 BeEcompErrorManager.getInstance().logBeRestApiGeneralError(UPDATE_RESOURCE_INSTANCE);
284 log.debug(UPDATE_RESOURCE_INSTANCE_WITH_EXCEPTION, e);
291 @Path("/{containerComponentType}/{componentId}/resourceInstance/multipleComponentInstance")
292 @Consumes(MediaType.APPLICATION_JSON)
293 @Produces(MediaType.APPLICATION_JSON)
294 @Operation(description = "Update resource instance multiple component", method = "POST",
295 summary = "Returns updated resource instance", responses = {
296 @ApiResponse(content = @Content(array = @ArraySchema(schema = @Schema(implementation = Response.class)))),
297 @ApiResponse(responseCode = "200", description = "Resource instance updated"),
298 @ApiResponse(responseCode = "403", description = "Restricted operation"),
299 @ApiResponse(responseCode = "400", description = "Invalid content / Missing content")})
300 @PermissionAllowed(AafPermission.PermNames.INTERNAL_ALL_VALUE)
301 public Response updateMultipleComponentInstance(@PathParam("componentId") final String componentId, @Parameter(
302 description = "valid values: resources / services / products",
303 schema = @Schema(allowableValues = {ComponentTypeEnum.RESOURCE_PARAM_NAME,
304 ComponentTypeEnum.SERVICE_PARAM_NAME,
305 ComponentTypeEnum.PRODUCT_PARAM_NAME})) @PathParam("containerComponentType") final String containerComponentType,
306 @Context final HttpServletRequest request, @Parameter(description = "Component Instance JSON Array",
307 required = true) final String componentInstanceJsonArray) {
309 String url = request.getMethod() + " " + request.getRequestURI();
310 log.debug(START_HANDLE_REQUEST_OF, url);
313 log.debug(START_HANDLE_REQUEST_OF, url);
315 if (componentInstanceJsonArray == null || componentInstanceJsonArray.length() == 0) {
316 log.info("Empty JSON list was sent.");
317 return buildErrorResponse(getComponentsUtils().getResponseFormat(ActionStatus.INVALID_CONTENT));
320 String userId = request.getHeader(Constants.USER_ID_HEADER);
322 if (componentInstanceBusinessLogic == null) {
323 log.debug(UNSUPPORTED_COMPONENT_TYPE, containerComponentType);
324 return buildErrorResponse(getComponentsUtils().getResponseFormat(ActionStatus.UNSUPPORTED_ERROR, containerComponentType));
327 Either<List<ComponentInstance>, ResponseFormat> convertResponse = convertToMultipleResourceInstance(componentInstanceJsonArray);
329 if (convertResponse.isRight()) {
330 // Using both ECOMP error methods, show to Sofer
331 BeEcompErrorManager.getInstance().logBeSystemError(RESOURCE_INSTANCE_UPDATE_RESOURCE_INSTANCE);
332 log.debug(FAILED_TO_CONVERT_RECEIVED_DATA_TO_BE_FORMAT);
333 return buildErrorResponse(convertResponse.right().value());
336 List<ComponentInstance> componentInstanceList = convertResponse.left().value();
338 List<ComponentInstance> actionResponse = componentInstanceBusinessLogic.updateComponentInstance(containerComponentType, null, componentId, userId, componentInstanceList, true);
339 return buildOkResponse(getComponentsUtils().getResponseFormat(ActionStatus.OK), actionResponse);
341 } catch (Exception e) {
342 BeEcompErrorManager.getInstance().logBeRestApiGeneralError(UPDATE_RESOURCE_INSTANCE);
343 log.debug(UPDATE_RESOURCE_INSTANCE_WITH_EXCEPTION, e);
350 @Path("/{containerComponentType}/{componentId}/resourceInstance/{resourceInstanceId}")
351 @Consumes(MediaType.APPLICATION_JSON)
352 @Produces(MediaType.APPLICATION_JSON)
353 @Operation(description = "Delete ResourceInstance", method = "DELETE", summary = "Returns delete resourceInstance",
354 responses = {@ApiResponse(
355 content = @Content(array = @ArraySchema(schema = @Schema(implementation = Response.class)))),
356 @ApiResponse(responseCode = "201", description = "ResourceInstance deleted"),
357 @ApiResponse(responseCode = "403", description = "Restricted operation"),
358 @ApiResponse(responseCode = "400", description = "Invalid content / Missing content")})
359 @PermissionAllowed(AafPermission.PermNames.INTERNAL_ALL_VALUE)
360 public Response deleteResourceInstance(@PathParam("componentId") final String componentId,
361 @PathParam("resourceInstanceId") final String resourceInstanceId,
362 @Parameter(description = "valid values: resources / services / products",
363 schema = @Schema(allowableValues = {ComponentTypeEnum.RESOURCE_PARAM_NAME,
364 ComponentTypeEnum.SERVICE_PARAM_NAME,
365 ComponentTypeEnum.PRODUCT_PARAM_NAME})) @PathParam("containerComponentType") final String containerComponentType,
366 @Context final HttpServletRequest request) {
368 String url = request.getMethod() + " " + request.getRequestURI();
371 log.debug(START_HANDLE_REQUEST_OF, url);
372 if (componentInstanceBusinessLogic == null) {
373 log.debug(UNSUPPORTED_COMPONENT_TYPE, containerComponentType);
374 return buildErrorResponse(getComponentsUtils().getResponseFormat(ActionStatus.UNSUPPORTED_ERROR, containerComponentType));
376 String userId = request.getHeader(Constants.USER_ID_HEADER);
377 ComponentInstance actionResponse = componentInstanceBusinessLogic.deleteComponentInstance(containerComponentType, componentId, resourceInstanceId, userId);
378 loggerSupportability.log(LoggerSupportabilityActions.DELETE_COMPONENT_INSTANCE,actionResponse.getComponentMetadataForSupportLog(),StatusCode.STARTED,"DELETE_COMPONENT_INSTANCE by user {}", userId);
379 loggerSupportability.log(LoggerSupportabilityActions.DELETE_COMPONENT_INSTANCE,actionResponse.getComponentMetadataForSupportLog(),StatusCode.COMPLETE,"DELETE_COMPONENT_INSTANCE by user {}", userId);
380 return buildOkResponse(getComponentsUtils().getResponseFormat(ActionStatus.OK), actionResponse);
381 } catch (Exception e) {
382 BeEcompErrorManager.getInstance().logBeRestApiGeneralError("Delete Resource Instance");
383 log.debug("delete resource instance with exception", e);
384 return buildErrorResponse(getComponentsUtils().getResponseFormat(ActionStatus.GENERAL_ERROR));
388 @Parameter(description = "allowed values are resources /services / products",
389 schema = @Schema(allowableValues = {ComponentTypeEnum.RESOURCE_PARAM_NAME,
390 ComponentTypeEnum.SERVICE_PARAM_NAME,
391 ComponentTypeEnum.PRODUCT_PARAM_NAME}),
394 @Path("/{containerComponentType}/{componentId}/resourceInstance/associate")
395 @Consumes(MediaType.APPLICATION_JSON)
396 @Produces(MediaType.APPLICATION_JSON)
397 @Operation(description = "Associate RI to RI", method = "POST", summary = "Returns created RelationshipInfo",
398 responses = {@ApiResponse(
399 content = @Content(array = @ArraySchema(schema = @Schema(implementation = Response.class)))),
400 @ApiResponse(responseCode = "201", description = "Relationship created"),
401 @ApiResponse(responseCode = "403", description = "Missing information"),
402 @ApiResponse(responseCode = "400", description = "Invalid content / Missing content"),
403 @ApiResponse(responseCode = "409", description = "Relationship already exist")})
404 @PermissionAllowed(AafPermission.PermNames.INTERNAL_ALL_VALUE)
405 public Response associateRIToRI(@Parameter(
406 description = "unique id of the container component") @PathParam("componentId") final String componentId,
407 @Parameter(description = "allowed values are resources /services / products",
408 schema = @Schema(allowableValues = {ComponentTypeEnum.RESOURCE_PARAM_NAME,
409 ComponentTypeEnum.SERVICE_PARAM_NAME, ComponentTypeEnum.PRODUCT_PARAM_NAME}),
410 required = true) @PathParam("containerComponentType") final String containerComponentType,
411 @HeaderParam(value = Constants.USER_ID_HEADER) String userId,
412 @Parameter(description = "RelationshipInfo", required = true) String data,
413 @Context final HttpServletRequest request) {
415 String url = request.getMethod() + " " + request.getRequestURI();
416 log.debug(START_HANDLE_REQUEST_OF, url);
417 loggerSupportability.log(LoggerSupportabilityActions.ASSOCIATE_RI_TO_RI, StatusCode.STARTED,"Starting to associate RI To RI for component {} ",componentId + " by " + userId );
420 log.debug(START_HANDLE_REQUEST_OF, url);
422 ComponentTypeEnum componentTypeEnum = ComponentTypeEnum.findByParamName(containerComponentType);
423 if (componentInstanceBusinessLogic == null) {
424 log.debug(UNSUPPORTED_COMPONENT_TYPE, containerComponentType);
425 return buildErrorResponse(getComponentsUtils().getResponseFormat(ActionStatus.UNSUPPORTED_ERROR, containerComponentType));
428 RequirementCapabilityRelDef requirementDef = convertToRequirementCapabilityRelDef(data);
429 requirementDef.setOriginUI(true);
431 RequirementCapabilityRelDef actionResponse = componentInstanceBusinessLogic.associateRIToRI(componentId, userId, requirementDef, componentTypeEnum);
432 loggerSupportability.log(LoggerSupportabilityActions.ASSOCIATE_RI_TO_RI, StatusCode.COMPLETE,"Ended associate RI To RI for component {} ",componentId + " by " + userId );
433 return buildOkResponse(getComponentsUtils().getResponseFormat(ActionStatus.OK), actionResponse);
435 } catch (Exception e) {
436 if(!e.getClass().equals(ComponentException.class)) {
437 BeEcompErrorManager.getInstance().logBeRestApiGeneralError("Associate Resource Instance");
438 log.debug("associate resource instance to another RI with exception", e);
439 return buildErrorResponse(getComponentsUtils().getResponseFormat(ActionStatus.GENERAL_ERROR));
446 @Path("/{containerComponentType}/{componentId}/resourceInstance/dissociate")
447 @Consumes(MediaType.APPLICATION_JSON)
448 @Produces(MediaType.APPLICATION_JSON)
449 @Operation(description = "Dissociate RI from RI", method = "PUT", summary = "Returns deleted RelationshipInfo",
450 responses = {@ApiResponse(
451 content = @Content(array = @ArraySchema(schema = @Schema(implementation = Response.class)))),
452 @ApiResponse(responseCode = "201", description = "Relationship deleted"),
453 @ApiResponse(responseCode = "403", description = "Missing information"),
454 @ApiResponse(responseCode = "400", description = "Invalid content / Missing content")})
455 @PermissionAllowed(AafPermission.PermNames.INTERNAL_ALL_VALUE)
456 public Response dissociateRIFromRI(
457 @Parameter(description = "allowed values are resources /services / products",
458 schema = @Schema(allowableValues = {ComponentTypeEnum.RESOURCE_PARAM_NAME,
459 ComponentTypeEnum.SERVICE_PARAM_NAME, ComponentTypeEnum.PRODUCT_PARAM_NAME}),
460 required = true) @PathParam("containerComponentType") final String containerComponentType,
462 description = "unique id of the container component") @PathParam("componentId") final String componentId,
463 @HeaderParam(value = Constants.USER_ID_HEADER) String userId,
464 @Parameter(description = "RelationshipInfo", required = true) String data,
465 @Context final HttpServletRequest request) {
467 String url = request.getMethod() + " " + request.getRequestURI();
468 log.debug(START_HANDLE_REQUEST_OF, url);
469 loggerSupportability.log(LoggerSupportabilityActions.UN_ASSOCIATE_RI_TO_RI, StatusCode.STARTED,"Starting to undo associate RI To RI for component {} ",componentId + " by " + userId );
472 log.debug(START_HANDLE_REQUEST_OF, url);
474 ComponentTypeEnum componentTypeEnum = ComponentTypeEnum.findByParamName(containerComponentType);
475 if (componentInstanceBusinessLogic == null) {
476 log.debug(UNSUPPORTED_COMPONENT_TYPE, containerComponentType);
477 return buildErrorResponse(getComponentsUtils().getResponseFormat(ActionStatus.UNSUPPORTED_ERROR, containerComponentType));
480 RequirementCapabilityRelDef requirementDef = convertToRequirementCapabilityRelDef(data);
481 RequirementCapabilityRelDef actionResponse = componentInstanceBusinessLogic.dissociateRIFromRI(componentId, userId, requirementDef, componentTypeEnum);
482 loggerSupportability.log(LoggerSupportabilityActions.UN_ASSOCIATE_RI_TO_RI, StatusCode.COMPLETE,"Ended undo associate RI To RI for component {} ",componentId + " by " + userId );
483 return buildOkResponse(getComponentsUtils().getResponseFormat(ActionStatus.OK), actionResponse);
485 } catch (Exception e) {
486 BeEcompErrorManager.getInstance().logBeRestApiGeneralError("Dissociate Resource Instance");
487 log.debug("dissociate resource instance from service failed with exception", e);
493 @Path("/{containerComponentType}/{componentId}/resourceInstance/createAndAssociate")
494 @Consumes(MediaType.APPLICATION_JSON)
495 @Produces(MediaType.APPLICATION_JSON)
496 @Operation(description = "Create RI and associate RI to RI", method = "POST",
497 summary = "Returns created RI and RelationshipInfo", responses = {
498 @ApiResponse(content = @Content(array = @ArraySchema(schema = @Schema(implementation = Response.class)))),
499 @ApiResponse(responseCode = "201", description = "RI created"),
500 @ApiResponse(responseCode = "403", description = "Restricted operation"),
501 @ApiResponse(responseCode = "400", description = "Invalid content / Missing content"),
502 @ApiResponse(responseCode = "409", description = "Relationship already exist")})
503 @PermissionAllowed(AafPermission.PermNames.INTERNAL_ALL_VALUE)
504 public Response createAndAssociateRIToRI(@PathParam("componentId") final String componentId, @Parameter(
505 description = "valid values: resources / services",
506 schema = @Schema(allowableValues = {ComponentTypeEnum.RESOURCE_PARAM_NAME,
507 ComponentTypeEnum.SERVICE_PARAM_NAME, ComponentTypeEnum.PRODUCT_PARAM_NAME})) @PathParam("containerComponentType") final String containerComponentType,
508 @Context final HttpServletRequest request) throws IOException {
510 String url = request.getMethod() + " " + request.getRequestURI();
511 log.debug(START_HANDLE_REQUEST_OF, url);
514 log.debug(START_HANDLE_REQUEST_OF, url);
516 InputStream inputStream = request.getInputStream();
518 byte[] bytes = IOUtils.toByteArray(inputStream);
520 if (bytes == null || bytes.length == 0) {
521 log.info(EMPTY_BODY_WAS_SENT);
522 return buildErrorResponse(getComponentsUtils().getResponseFormat(ActionStatus.INVALID_CONTENT));
525 String userId = request.getHeader(Constants.USER_ID_HEADER);
526 String data = new String(bytes);
528 if (componentInstanceBusinessLogic == null) {
529 log.debug(UNSUPPORTED_COMPONENT_TYPE, containerComponentType);
530 return buildErrorResponse(getComponentsUtils().getResponseFormat(ActionStatus.UNSUPPORTED_ERROR, containerComponentType));
533 Either<CreateAndAssotiateInfo, ActionStatus> convertStatus = convertJsonToObject(data, CreateAndAssotiateInfo.class);
534 if (convertStatus.isRight()) {
535 BeEcompErrorManager.getInstance().logBeSystemError("Resource Instance - createAndAssociateRIToRI");
536 log.debug(FAILED_TO_CONVERT_RECEIVED_DATA_TO_BE_FORMAT);
537 Either<Object, ResponseFormat> formattedResponse = Either.right(getComponentsUtils().getResponseFormat(convertStatus.right().value()));
538 return buildErrorResponse(formattedResponse.right().value());
541 CreateAndAssotiateInfo createAndAssotiateInfo = convertStatus.left().value();
542 RequirementCapabilityRelDef requirementDef = createAndAssotiateInfo.getAssociate();
543 requirementDef.setOriginUI(true);
544 Either<CreateAndAssotiateInfo, ResponseFormat> actionResponse = componentInstanceBusinessLogic.createAndAssociateRIToRI(containerComponentType, componentId, userId, createAndAssotiateInfo);
546 if (actionResponse.isRight()) {
547 return buildErrorResponse(actionResponse.right().value());
549 return buildOkResponse(getComponentsUtils().getResponseFormat(ActionStatus.CREATED), actionResponse.left().value());
550 } catch (Exception e) {
551 BeEcompErrorManager.getInstance().logBeRestApiGeneralError("Create and Associate Resource Instance");
552 log.debug("create and associate RI failed with exception", e);
558 @Path("/{containerComponentType}/{componentId}/resourceInstance/{componentInstanceId}/properties")
559 @Consumes(MediaType.APPLICATION_JSON)
560 @Produces(MediaType.APPLICATION_JSON)
561 @Operation(description = "Update resource instance property", method = "POST",
562 summary = "Returns updated resource instance property", responses = {
563 @ApiResponse(content = @Content(array = @ArraySchema(schema = @Schema(implementation = Response.class)))),
564 @ApiResponse(responseCode = "201", description = "Resource instance created"),
565 @ApiResponse(responseCode = "403", description = "Restricted operation"),
566 @ApiResponse(responseCode = "400", description = "Invalid content / Missing content")})
567 @PermissionAllowed(AafPermission.PermNames.INTERNAL_ALL_VALUE)
568 public Response updateResourceInstanceProperties(
569 @Parameter(description = "service id") @PathParam("componentId") final String componentId,
570 @Parameter(description = "valid values: resources / services",
571 schema = @Schema(allowableValues = {ComponentTypeEnum.RESOURCE_PARAM_NAME,
572 ComponentTypeEnum.SERVICE_PARAM_NAME})) @PathParam("containerComponentType") final String containerComponentType,
574 description = "resource instance id") @PathParam("componentInstanceId") final String componentInstanceId,
575 @Parameter(description = "id of user initiating the operation") @HeaderParam(
576 value = Constants.USER_ID_HEADER) String userId,
577 @Context final HttpServletRequest request,
578 @Parameter(description = "Component Instance Properties JSON Array",
579 required = true) final String componentInstancePropertiesJsonArray) {
581 String url = request.getMethod() + " " + request.getRequestURI();
582 log.debug(START_HANDLE_REQUEST_OF, url);
583 loggerSupportability.log(LoggerSupportabilityActions.UPDATE_COMPONENT_INSTANCE, StatusCode.STARTED,"Starting to update Resource Instance Properties for component {} ",componentId + " by " + userId );
585 Wrapper<ResponseFormat> errorWrapper = new Wrapper<>();
586 List<ComponentInstanceProperty> propertiesToUpdate = new ArrayList<>();
587 if (errorWrapper.isEmpty()) {
588 Either<List<ComponentInstanceProperty>, ResponseFormat> propertiesToUpdateEither = convertMultipleProperties(componentInstancePropertiesJsonArray);
589 if (propertiesToUpdateEither.isRight()) {
590 errorWrapper.setInnerElement(propertiesToUpdateEither.right().value());
592 propertiesToUpdate = propertiesToUpdateEither.left().value();
595 if (!errorWrapper.isEmpty()) {
596 return buildErrorResponse(errorWrapper.getInnerElement());
598 log.debug(START_HANDLE_REQUEST_OF_UPDATE_RESOURCE_INSTANCE_PROPERTY_RECEIVED_PROPERTY_IS, propertiesToUpdate);
600 ComponentTypeEnum componentTypeEnum = ComponentTypeEnum.findByParamName(containerComponentType);
601 if (componentInstanceBusinessLogic == null) {
602 log.debug(UNSUPPORTED_COMPONENT_TYPE, containerComponentType);
603 return buildErrorResponse(getComponentsUtils().getResponseFormat(ActionStatus.UNSUPPORTED_ERROR, containerComponentType));
605 Either<List<ComponentInstanceProperty>, ResponseFormat> actionResponse = componentInstanceBusinessLogic.createOrUpdatePropertiesValues(componentTypeEnum, componentId, componentInstanceId, propertiesToUpdate, userId);
606 if (actionResponse.isRight()) {
607 return buildErrorResponse(actionResponse.right().value());
609 List<ComponentInstanceProperty> resourceInstanceProperties = actionResponse.left().value();
610 ObjectMapper mapper = new ObjectMapper();
612 loggerSupportability.log(LoggerSupportabilityActions.UPDATE_COMPONENT_INSTANCE, StatusCode.COMPLETE,"Ended update Resource Instance Properties for component {} ",componentId + " by " + userId );
614 result = mapper.writeValueAsString(resourceInstanceProperties);
615 } catch (JsonProcessingException e) {
616 log.error(UPDATE_RESOURCE_INSTANCE_WITH_EXCEPTION, e.getMessage(), e);
617 throw new ByActionStatusComponentException(ActionStatus.GENERAL_ERROR);
619 loggerSupportability.log(LoggerSupportabilityActions.UPDATE_COMPONENT_INSTANCE, StatusCode.COMPLETE,"Ended update Resource Instance Properties for component {} ",componentId + " by user " + userId );
620 return buildOkResponse(getComponentsUtils().getResponseFormat(ActionStatus.OK), result);
624 @Path("/{containerComponentType}/{componentId}/resourceInstance/{componentInstanceId}/inputs")
625 @Consumes(MediaType.APPLICATION_JSON)
626 @Produces(MediaType.APPLICATION_JSON)
627 @Operation(description = "Update resource instance property", method = "POST",
628 summary = "Returns updated resource instance property", responses = {
629 @ApiResponse(content = @Content(array = @ArraySchema(schema = @Schema(implementation = Response.class)))),
630 @ApiResponse(responseCode = "201", description = "Resource instance created"),
631 @ApiResponse(responseCode = "403", description = "Restricted operation"),
632 @ApiResponse(responseCode = "400", description = "Invalid content / Missing content")})
633 @PermissionAllowed(AafPermission.PermNames.INTERNAL_ALL_VALUE)
634 public Response updateResourceInstanceInput(
635 @Parameter(description = "service id") @PathParam("componentId") final String componentId,
636 @Parameter(description = "valid values: resources / services",
637 schema = @Schema(allowableValues = {ComponentTypeEnum.RESOURCE_PARAM_NAME,
638 ComponentTypeEnum.SERVICE_PARAM_NAME})) @PathParam("containerComponentType") final String containerComponentType,
640 description = "resource instance id") @PathParam("componentInstanceId") final String componentInstanceId,
641 @Parameter(description = "id of user initiating the operation") @HeaderParam(
642 value = Constants.USER_ID_HEADER) String userId,
643 @Context final HttpServletRequest request,
644 @Parameter(description = "Component Instance Properties JSON Array",
645 required = true) final String componentInstanceInputsJsonArray) {
647 String url = request.getMethod() + " " + request.getRequestURI();
648 log.debug(START_HANDLE_REQUEST_OF, url);
650 Wrapper<ResponseFormat> errorWrapper = new Wrapper<>();
651 List<ComponentInstanceInput> inputsToUpdate = new ArrayList<>();
652 if (errorWrapper.isEmpty()) {
653 Either<List<ComponentInstanceInput>, ResponseFormat> inputsToUpdateEither = convertMultipleInputs(componentInstanceInputsJsonArray);
654 if (inputsToUpdateEither.isRight()) {
655 errorWrapper.setInnerElement(inputsToUpdateEither.right().value());
657 inputsToUpdate = inputsToUpdateEither.left().value();
660 if (!errorWrapper.isEmpty()) {
661 return buildErrorResponse(errorWrapper.getInnerElement());
663 log.debug(START_HANDLE_REQUEST_OF_UPDATE_RESOURCE_INSTANCE_PROPERTY_RECEIVED_PROPERTY_IS, inputsToUpdate);
665 ComponentTypeEnum componentTypeEnum = ComponentTypeEnum.findByParamName(containerComponentType);
666 if (componentInstanceBusinessLogic == null) {
667 log.debug(UNSUPPORTED_COMPONENT_TYPE, containerComponentType);
668 return buildErrorResponse(getComponentsUtils().getResponseFormat(ActionStatus.UNSUPPORTED_ERROR, containerComponentType));
670 Either<List<ComponentInstanceInput>, ResponseFormat> actionResponse =
671 componentInstanceBusinessLogic.createOrUpdateInstanceInputValues(componentTypeEnum, componentId, componentInstanceId, inputsToUpdate, userId);
672 if (actionResponse.isRight()) {
673 return buildErrorResponse(actionResponse.right().value());
675 List<ComponentInstanceInput> resourceInstanceInput = actionResponse.left().value();
676 ObjectMapper mapper = new ObjectMapper();
677 mapper.configure(SerializationFeature.FAIL_ON_EMPTY_BEANS, false);
679 loggerSupportability.log(LoggerSupportabilityActions.UPDATE_PROPERTIES, StatusCode.COMPLETE,"Ending update Resource Instance Input for component {} ",componentId + " by " + userId );
681 result = mapper.writeValueAsString(resourceInstanceInput);
682 } catch (JsonProcessingException e) {
683 log.error(UPDATE_RESOURCE_INSTANCE_WITH_EXCEPTION, e.getMessage(), e);
684 return buildErrorResponse(getComponentsUtils().getResponseFormat(ActionStatus.GENERAL_ERROR));
686 loggerSupportability.log(LoggerSupportabilityActions.UPDATE_PROPERTIES, StatusCode.COMPLETE, "Ending update Resource Instance Input for component {} ", componentId + " by user " + userId);
687 return buildOkResponse(getComponentsUtils().getResponseFormat(ActionStatus.OK), result);
691 * Updates ResourceInstance Attribute
694 * @param containerComponentType
695 * @param componentInstanceId
701 @Path("/{containerComponentType}/{componentId}/resourceInstance/{componentInstanceId}/attribute")
702 @Consumes(MediaType.APPLICATION_JSON)
703 @Produces(MediaType.APPLICATION_JSON)
704 @Operation(description = "Update resource instance attribute", method = "POST",
705 summary = "Returns updated resource instance attribute", responses = {
706 @ApiResponse(content = @Content(array = @ArraySchema(schema = @Schema(implementation = Response.class)))),
707 @ApiResponse(responseCode = "201", description = "Resource instance created"),
708 @ApiResponse(responseCode = "403", description = "Restricted operation"),
709 @ApiResponse(responseCode = "400", description = "Invalid content / Missing content")})
710 @PermissionAllowed(AafPermission.PermNames.INTERNAL_ALL_VALUE)
711 public Response updateResourceInstanceAttribute(
712 @Parameter(description = "service id") @PathParam("componentId") final String componentId,
713 @Parameter(description = "valid values: resources / services",
714 schema = @Schema(allowableValues = {ComponentTypeEnum.RESOURCE_PARAM_NAME,
715 ComponentTypeEnum.SERVICE_PARAM_NAME})) @PathParam("containerComponentType") final String containerComponentType,
717 description = "resource instance id") @PathParam("componentInstanceId") final String componentInstanceId,
718 @Parameter(description = "id of user initiating the operation") @HeaderParam(
719 value = Constants.USER_ID_HEADER) String userId,
720 @Context final HttpServletRequest request) throws IOException {
722 String url = request.getMethod() + " " + request.getRequestURI();
723 log.debug(START_HANDLE_REQUEST_OF, url);
724 loggerSupportability.log(LoggerSupportabilityActions.UPDATE_RESOURCE, StatusCode.STARTED,"Starting to update Resource Instance Attribute for component {} ",componentId + " by " + userId );
727 Wrapper<ResponseFormat> errorWrapper = new Wrapper<>();
728 Wrapper<String> dataWrapper = new Wrapper<>();
729 Wrapper<ComponentInstanceProperty> attributeWrapper = new Wrapper<>();
730 Wrapper<ComponentInstanceBusinessLogic> blWrapper = new Wrapper<>();
732 validateInputStream(request, dataWrapper, errorWrapper);
734 if (errorWrapper.isEmpty()) {
735 validateClassParse(dataWrapper.getInnerElement(), attributeWrapper, () -> ComponentInstanceProperty.class, errorWrapper);
738 if (errorWrapper.isEmpty()) {
739 validateComponentInstanceBusinessLogic(request, containerComponentType, blWrapper, errorWrapper);
742 if (errorWrapper.isEmpty()) {
743 ComponentInstanceBusinessLogic componentInstanceLogic = blWrapper.getInnerElement();
744 ComponentTypeEnum componentTypeEnum = ComponentTypeEnum.findByParamName(containerComponentType);
745 log.debug("Start handle request of ComponentInstanceAttribute. Received attribute is {}", attributeWrapper.getInnerElement());
746 Either<ComponentInstanceProperty, ResponseFormat> eitherAttribute = componentInstanceLogic.createOrUpdateAttributeValue(componentTypeEnum, componentId, componentInstanceId, attributeWrapper.getInnerElement(), userId);
747 if (eitherAttribute.isRight()) {
748 errorWrapper.setInnerElement(eitherAttribute.right().value());
750 attributeWrapper.setInnerElement(eitherAttribute.left().value());
753 loggerSupportability.log(LoggerSupportabilityActions.UPDATE_RESOURCE, StatusCode.COMPLETE,"Ended update Resource Instance Attribute for component {} ",componentId + " by " + userId );
754 return buildResponseFromElement(errorWrapper, attributeWrapper);
756 } catch (Exception e) {
757 log.error(CREATE_AND_ASSOCIATE_RI_FAILED_WITH_EXCEPTION, e.getMessage(), e);
764 @Path("/{containerComponentType}/{componentId}/resourceInstance/{componentInstanceId}/property/{propertyId}")
765 @Consumes(MediaType.APPLICATION_JSON)
766 @Produces(MediaType.APPLICATION_JSON)
767 @Operation(description = "Update resource instance", method = "DELETE",
768 summary = "Returns deleted resource instance property", responses = {
769 @ApiResponse(content = @Content(array = @ArraySchema(schema = @Schema(implementation = Response.class)))),
770 @ApiResponse(responseCode = "201", description = "Resource instance created"),
771 @ApiResponse(responseCode = "403", description = "Restricted operation"),
772 @ApiResponse(responseCode = "400", description = "Invalid content / Missing content")})
773 @PermissionAllowed(AafPermission.PermNames.INTERNAL_ALL_VALUE)
774 public Response deleteResourceInstanceProperty(
775 @Parameter(description = "service id") @PathParam("componentId") final String componentId,
776 @Parameter(description = "valid values: resources / services",
777 schema = @Schema(allowableValues = {ComponentTypeEnum.RESOURCE_PARAM_NAME,
778 ComponentTypeEnum.SERVICE_PARAM_NAME})) @PathParam("containerComponentType") final String containerComponentType,
780 description = "resource instance id") @PathParam("componentInstanceId") final String componentInstanceId,
781 @Parameter(description = "property id") @PathParam("propertyId") final String propertyId,
782 @Parameter(description = "id of user initiating the operation") @HeaderParam(
783 value = Constants.USER_ID_HEADER) String userId,
784 @Context final HttpServletRequest request) {
787 loggerSupportability.log(LoggerSupportabilityActions.UPDATE_PROPERTIES, StatusCode.STARTED,"Starting to delete Resource Instance Property for component {} ",componentId + " by " + userId );
788 String url = request.getMethod() + " " + request.getRequestURI();
789 log.debug(START_HANDLE_REQUEST_OF, url);
792 ComponentTypeEnum componentTypeEnum = ComponentTypeEnum.findByParamName(containerComponentType);
793 loggerSupportability.log(LoggerSupportabilityActions.UPDATE_PROPERTIES, StatusCode.COMPLETE,"Ended delete Resource Instance Property for component {} ",componentId + " by " + userId );
794 if (componentInstanceBusinessLogic == null) {
795 log.debug(UNSUPPORTED_COMPONENT_TYPE, containerComponentType);
796 return buildErrorResponse(getComponentsUtils().getResponseFormat(ActionStatus.UNSUPPORTED_ERROR, containerComponentType));
799 Either<ComponentInstanceProperty, ResponseFormat> actionResponse = componentInstanceBusinessLogic.deletePropertyValue(componentTypeEnum, componentId, componentInstanceId, propertyId, userId);
800 if (actionResponse.isRight()) {
801 return buildErrorResponse(actionResponse.right().value());
803 return buildOkResponse(getComponentsUtils().getResponseFormat(ActionStatus.NO_CONTENT), null);
804 } catch (Exception e) {
805 log.error(CREATE_AND_ASSOCIATE_RI_FAILED_WITH_EXCEPTION, e.getMessage(), e);
812 @Path("/{containerComponentType}/{componentId}/resourceInstance/{componentInstanceId}/changeVersion")
813 @Consumes(MediaType.APPLICATION_JSON)
814 @Produces(MediaType.APPLICATION_JSON)
815 @Operation(description = "Update resource instance", method = "POST", summary = "Returns updated resource instance",
816 responses = {@ApiResponse(
817 content = @Content(array = @ArraySchema(schema = @Schema(implementation = Response.class)))),
818 @ApiResponse(responseCode = "201", description = "Resource instance created"),
819 @ApiResponse(responseCode = "403", description = "Restricted operation"),
820 @ApiResponse(responseCode = "400", description = "Invalid content / Missing content")})
821 @PermissionAllowed(AafPermission.PermNames.INTERNAL_ALL_VALUE)
822 public Response changeResourceInstanceVersion(@PathParam("componentId") final String componentId,
823 @PathParam("componentInstanceId") final String componentInstanceId,
824 @Parameter(description = "valid values: resources / services",
825 schema = @Schema(allowableValues = {ComponentTypeEnum.RESOURCE_PARAM_NAME,
826 ComponentTypeEnum.SERVICE_PARAM_NAME})) @PathParam("containerComponentType") final String containerComponentType,
827 @Context final HttpServletRequest request) throws IOException {
829 String url = request.getMethod() + " " + request.getRequestURI();
830 log.debug(START_HANDLE_REQUEST_OF, url);
832 InputStream inputStream = request.getInputStream()) {
834 byte[] bytes = IOUtils.toByteArray(inputStream);
836 if (bytes == null || bytes.length == 0) {
837 log.info(EMPTY_BODY_WAS_SENT);
838 return buildErrorResponse(getComponentsUtils().getResponseFormat(ActionStatus.INVALID_CONTENT));
841 String userId = request.getHeader(Constants.USER_ID_HEADER);
842 String data = new String(bytes);
844 if (componentInstanceBusinessLogic == null) {
845 log.debug(UNSUPPORTED_COMPONENT_TYPE, containerComponentType);
846 return buildErrorResponse(getComponentsUtils().getResponseFormat(ActionStatus.UNSUPPORTED_ERROR, containerComponentType));
849 Either<ComponentInstance, ResponseFormat> convertResponse = convertToResourceInstance(data);
851 if (convertResponse.isRight()) {
852 BeEcompErrorManager.getInstance().logBeSystemError(RESOURCE_INSTANCE_UPDATE_RESOURCE_INSTANCE);
853 log.debug(FAILED_TO_CONVERT_RECEIVED_DATA_TO_BE_FORMAT);
854 return buildErrorResponse(convertResponse.right().value());
857 ComponentInstance newResourceInstance = convertResponse.left().value();
858 ComponentInstance actionResponse = componentInstanceBusinessLogic.changeComponentInstanceVersion(containerComponentType, componentId, componentInstanceId, userId, newResourceInstance);
860 return buildOkResponse(getComponentsUtils().getResponseFormat(ActionStatus.OK), actionResponse);
862 } catch (Exception e) {
863 BeEcompErrorManager.getInstance().logBeRestApiGeneralError(UPDATE_RESOURCE_INSTANCE);
864 log.debug(UPDATE_RESOURCE_INSTANCE_WITH_EXCEPTION, e);
871 @Path("/{containerComponentType}/{componentId}/resourceInstance/{componentInstanceId}/groupInstance/{groupInstanceId}/property")
872 @Consumes(MediaType.APPLICATION_JSON)
873 @Produces(MediaType.APPLICATION_JSON)
874 @Operation(description = "Update resource instance property", method = "POST",
875 summary = "Returns updated resource instance property", responses = {
876 @ApiResponse(content = @Content(array = @ArraySchema(schema = @Schema(implementation = Response.class)))),
877 @ApiResponse(responseCode = "201", description = "Resource instance created"),
878 @ApiResponse(responseCode = "403", description = "Restricted operation"),
879 @ApiResponse(responseCode = "400", description = "Invalid content / Missing content")})
880 @PermissionAllowed(AafPermission.PermNames.INTERNAL_ALL_VALUE)
881 public Response updateGroupInstanceProperty(
882 @Parameter(description = "service id") @PathParam("componentId") final String componentId,
883 @Parameter(description = "valid values: resources / services",
884 schema = @Schema(allowableValues = {ComponentTypeEnum.RESOURCE_PARAM_NAME,
885 ComponentTypeEnum.SERVICE_PARAM_NAME})) @PathParam("containerComponentType") final String containerComponentType,
887 description = "resource instance id") @PathParam("componentInstanceId") final String componentInstanceId,
888 @Parameter(description = "group instance id") @PathParam("groupInstanceId") final String groupInstanceId,
889 @Parameter(description = "id of user initiating the operation") @HeaderParam(
890 value = Constants.USER_ID_HEADER) String userId,
891 @Context final HttpServletRequest request) throws IOException {
893 String url = request.getMethod() + " " + request.getRequestURI();
894 log.debug(START_HANDLE_REQUEST_OF, url);
897 loggerSupportability.log(LoggerSupportabilityActions.UPDATE_PROPERTIES, StatusCode.STARTED,"Starting update Group Instance Property for component {} ",componentId + " by " + userId );
898 Wrapper<String> dataWrapper = new Wrapper<>();
899 Wrapper<ResponseFormat> errorWrapper = new Wrapper<>();
900 Wrapper<ComponentInstanceProperty> propertyWrapper = new Wrapper<>();
902 validateInputStream(request, dataWrapper, errorWrapper);
904 if (errorWrapper.isEmpty()) {
905 validateClassParse(dataWrapper.getInnerElement(), propertyWrapper, () -> ComponentInstanceProperty.class, errorWrapper);
908 if (!errorWrapper.isEmpty()) {
909 return buildErrorResponse(errorWrapper.getInnerElement());
912 ComponentInstanceProperty property = propertyWrapper.getInnerElement();
914 log.debug(START_HANDLE_REQUEST_OF_UPDATE_RESOURCE_INSTANCE_PROPERTY_RECEIVED_PROPERTY_IS, property);
918 ComponentTypeEnum componentTypeEnum = ComponentTypeEnum.findByParamName(containerComponentType);
919 if (componentInstanceBusinessLogic == null) {
920 log.debug(UNSUPPORTED_COMPONENT_TYPE, containerComponentType);
921 return buildErrorResponse(getComponentsUtils().getResponseFormat(ActionStatus.UNSUPPORTED_ERROR, containerComponentType));
924 Either<ComponentInstanceProperty, ResponseFormat> actionResponse = componentInstanceBusinessLogic.createOrUpdateGroupInstancePropertyValue(componentTypeEnum, componentId, componentInstanceId, groupInstanceId, property, userId);
925 if (actionResponse.isRight()) {
926 return buildErrorResponse(actionResponse.right().value());
929 ComponentInstanceProperty resourceInstanceProperty = actionResponse.left().value();
930 ObjectMapper mapper = new ObjectMapper();
931 String result = mapper.writeValueAsString(resourceInstanceProperty);
932 loggerSupportability.log(LoggerSupportabilityActions.UPDATE_PROPERTIES, StatusCode.COMPLETE,"Ended update Group Instance Property for component {} ",componentId + " by " + userId );
933 return buildOkResponse(getComponentsUtils().getResponseFormat(ActionStatus.OK), result);
935 } catch (Exception e) {
936 log.error(CREATE_AND_ASSOCIATE_RI_FAILED_WITH_EXCEPTION, e.getMessage(), e);
942 @Path("/{containerComponentType}/{componentId}/resourceInstance/{componentInstanceId}/groupInstance/{groupInstId}")
943 @Consumes(MediaType.APPLICATION_JSON)
944 @Produces(MediaType.APPLICATION_JSON)
945 @Operation(description = "Get group artifacts ", method = "GET",
946 summary = "Returns artifacts metadata according to groupInstId", responses = {
947 @ApiResponse(content = @Content(array = @ArraySchema(schema = @Schema(implementation = Response.class)))),
948 @ApiResponse(responseCode = "200", description = "group found"),
949 @ApiResponse(responseCode = "403", description = "Restricted operation"),
950 @ApiResponse(responseCode = "404", description = "Group not found")})
951 @PermissionAllowed(AafPermission.PermNames.INTERNAL_ALL_VALUE)
952 public Response getGroupArtifactById(@PathParam("containerComponentType") final String containerComponentType,
953 @PathParam("componentId") final String componentId,
954 @PathParam("componentInstanceId") final String componentInstanceId,
955 @PathParam("groupInstId") final String groupInstId, @Context final HttpServletRequest request,
956 @HeaderParam(value = Constants.USER_ID_HEADER) String userId) {
957 String url = request.getMethod() + " " + request.getRequestURI();
958 log.debug(GET_START_HANDLE_REQUEST_OF, url);
962 ComponentTypeEnum componentTypeEnum = ComponentTypeEnum.findByParamName(containerComponentType);
963 Either<GroupDefinitionInfo, ResponseFormat> actionResponse = groupBL.getGroupInstWithArtifactsById(componentTypeEnum, componentId, componentInstanceId, groupInstId, userId, false);
965 if (actionResponse.isRight()) {
966 log.debug("failed to get all non abstract {}", containerComponentType);
967 return buildErrorResponse(actionResponse.right().value());
970 return buildOkResponse(getComponentsUtils().getResponseFormat(ActionStatus.OK), actionResponse.left().value());
972 } catch (Exception e) {
973 BeEcompErrorManager.getInstance().logBeRestApiGeneralError(GET_GROUP_ARTIFACT_BY_ID);
974 log.debug(GET_GROUP_ARTIFACT_BY_ID_UNEXPECTED_EXCEPTION, e);
982 @Path("/{containerComponentType}/{containerComponentId}/componentInstances/{componentInstanceUniqueId}/properties")
983 @Consumes(MediaType.APPLICATION_JSON)
984 @Produces(MediaType.APPLICATION_JSON)
985 @Operation(description = "Get component instance properties", method = "GET",
986 summary = "Returns component instance properties", responses = {
987 @ApiResponse(content = @Content(array = @ArraySchema(schema = @Schema(implementation = Response.class)))),
988 @ApiResponse(responseCode = "200", description = "Properties found"),
989 @ApiResponse(responseCode = "403", description = "Restricted operation"),
990 @ApiResponse(responseCode = "404", description = "Component/Component Instance - not found")})
991 @PermissionAllowed(AafPermission.PermNames.INTERNAL_ALL_VALUE)
992 public Response getInstancePropertiesById(@PathParam("containerComponentType") final String containerComponentType,
993 @PathParam("containerComponentId") final String containerComponentId,
994 @PathParam("componentInstanceUniqueId") final String componentInstanceUniqueId,
995 @Context final HttpServletRequest request, @HeaderParam(value = Constants.USER_ID_HEADER) String userId) {
998 String url = request.getMethod() + " " + request.getRequestURI();
999 log.debug(GET_START_HANDLE_REQUEST_OF, url);
1001 List<ComponentInstanceProperty> componentInstancePropertiesById = componentInstanceBusinessLogic.getComponentInstancePropertiesById(containerComponentType, containerComponentId, componentInstanceUniqueId, userId);
1002 return buildOkResponse(getComponentsUtils().getResponseFormat(ActionStatus.OK), componentInstancePropertiesById);
1007 @Path("/{containerComponentType}/{containerComponentId}/componentInstances/{componentInstanceUniqueId}/capability/{capabilityType}/capabilityName/{capabilityName}/ownerId/{ownerId}/properties")
1008 @Consumes(MediaType.APPLICATION_JSON)
1009 @Produces(MediaType.APPLICATION_JSON)
1010 @Operation(description = "Get component instance capability properties", method = "GET",
1011 summary = "Returns component instance capability properties", responses = {
1012 @ApiResponse(content = @Content(array = @ArraySchema(schema = @Schema(implementation = Response.class)))),
1013 @ApiResponse(responseCode = "200", description = "Properties found"),
1014 @ApiResponse(responseCode = "403", description = "Restricted operation"),
1015 @ApiResponse(responseCode = "404", description = "Component/Component Instance/Capability - not found")})
1016 @PermissionAllowed(AafPermission.PermNames.INTERNAL_ALL_VALUE)
1017 public Response getInstanceCapabilityPropertiesById(
1018 @PathParam("containerComponentType") final String containerComponentType,
1019 @PathParam("containerComponentId") final String containerComponentId,
1020 @PathParam("componentInstanceUniqueId") final String componentInstanceUniqueId,
1021 @PathParam("capabilityType") final String capabilityType,
1022 @PathParam("capabilityName") final String capabilityName, @PathParam("ownerId") final String ownerId,
1023 @Context final HttpServletRequest request, @HeaderParam(value = Constants.USER_ID_HEADER) String userId) {
1026 String url = request.getMethod() + " " + request.getRequestURI();
1027 log.debug(GET_START_HANDLE_REQUEST_OF, url);
1030 List<ComponentInstanceProperty> componentInstancePropertiesById = componentInstanceBusinessLogic.getComponentInstanceCapabilityPropertiesById(containerComponentType, containerComponentId, componentInstanceUniqueId,
1031 capabilityType, capabilityName, ownerId, userId);
1033 return buildOkResponse(getComponentsUtils().getResponseFormat(ActionStatus.OK), componentInstancePropertiesById);
1034 } catch (Exception e) {
1035 BeEcompErrorManager.getInstance().logBeRestApiGeneralError(GET_GROUP_ARTIFACT_BY_ID);
1036 log.debug(GET_GROUP_ARTIFACT_BY_ID_UNEXPECTED_EXCEPTION, e);
1044 @Path("/{containerComponentType}/{containerComponentId}/componentInstances/{componentInstanceUniqueId}/capability/{capabilityType}/capabilityName/{capabilityName}/ownerId/{ownerId}/properties")
1045 @Consumes(MediaType.APPLICATION_JSON)
1046 @Produces(MediaType.APPLICATION_JSON)
1047 @Operation(description = "Update Instance Capabilty Property", method = "PUT",
1048 summary = "Returns updated property", responses = {
1049 @ApiResponse(content = @Content(array = @ArraySchema(schema = @Schema(implementation = Response.class)))),
1050 @ApiResponse(responseCode = "200", description = "Resource instance capabilty property updated"),
1051 @ApiResponse(responseCode = "403", description = "Restricted operation"),
1052 @ApiResponse(responseCode = "400", description = "Invalid content / Missing content"),
1053 @ApiResponse(responseCode = "404", description = "Component/Component Instance/Capability - not found")})
1054 @PermissionAllowed(AafPermission.PermNames.INTERNAL_ALL_VALUE)
1055 public Response updateInstanceCapabilityProperty(
1056 @PathParam("containerComponentType") final String containerComponentType,
1057 @PathParam("containerComponentId") final String containerComponentId,
1058 @PathParam("componentInstanceUniqueId") final String componentInstanceUniqueId,
1059 @PathParam("capabilityType") final String capabilityType,
1060 @PathParam("capabilityName") final String capabilityName, @PathParam("ownerId") final String ownerId,
1061 @Parameter(description = "Instance capabilty property to update", required = true) String data,
1062 @Context final HttpServletRequest request, @HeaderParam(value = Constants.USER_ID_HEADER) String userId) {
1063 String url = request.getMethod() + " " + request.getRequestURI();
1064 log.debug("(PUT) Start handle request of {}", url);
1065 loggerSupportability.log(LoggerSupportabilityActions.UPDATE_INSTANCE_CAPABILITY_PROPERTY, StatusCode.STARTED," Starting to update Instance Capability Property for component instance {} " , componentInstanceUniqueId + " by " + userId);
1067 Wrapper<ResponseFormat> errorWrapper = new Wrapper<>();
1068 List<ComponentInstanceProperty> propertiesToUpdate = new ArrayList<>();
1069 if (errorWrapper.isEmpty()) {
1070 Either<List<ComponentInstanceProperty>, ResponseFormat> propertiesToUpdateEither = convertMultipleProperties(data);
1071 if (propertiesToUpdateEither.isRight()) {
1072 errorWrapper.setInnerElement(propertiesToUpdateEither.right().value());
1074 propertiesToUpdate = propertiesToUpdateEither.left().value();
1078 if (!errorWrapper.isEmpty()) {
1079 return buildErrorResponse(errorWrapper.getInnerElement());
1082 ComponentTypeEnum componentTypeEnum = ComponentTypeEnum.findByParamName(containerComponentType);
1084 Either<List<ComponentInstanceProperty>, ResponseFormat> updateCICapProperty = componentInstanceBusinessLogic.updateInstanceCapabilityProperties(componentTypeEnum, containerComponentId, componentInstanceUniqueId, capabilityType, capabilityName, propertiesToUpdate, userId);
1086 if (updateCICapProperty.isRight()) {
1087 log.debug(FAILED_TO_GET_PROPERTIES_OF_COMPONENT_INSTANCE_ID_IN_WITH_ID, componentInstanceUniqueId, containerComponentType, containerComponentId);
1088 return buildErrorResponse(updateCICapProperty.right().value());
1090 loggerSupportability.log(LoggerSupportabilityActions.UPDATE_INSTANCE_CAPABILITY_PROPERTY, StatusCode.COMPLETE," Ended to update Instance Capability Property for component instance {} " , componentInstanceUniqueId + " by " + userId);
1091 return buildOkResponse(getComponentsUtils().getResponseFormat(ActionStatus.OK), updateCICapProperty.left().value());
1092 } catch (Exception e) {
1093 BeEcompErrorManager.getInstance().logBeRestApiGeneralError(GET_GROUP_ARTIFACT_BY_ID);
1094 log.debug(GET_GROUP_ARTIFACT_BY_ID_UNEXPECTED_EXCEPTION, e);
1100 @Path("/{containerComponentType}/{containerComponentId}/serviceProxy")
1101 @Consumes(MediaType.APPLICATION_JSON)
1102 @Produces(MediaType.APPLICATION_JSON)
1103 @Operation(description = "Create service proxy", method = "POST", summary = "Returns created service proxy",
1104 responses = {@ApiResponse(
1105 content = @Content(array = @ArraySchema(schema = @Schema(implementation = Response.class)))),
1106 @ApiResponse(responseCode = "201", description = "Service proxy created"),
1107 @ApiResponse(responseCode = "403", description = "Restricted operation"),
1108 @ApiResponse(responseCode = "400", description = "Invalid content / Missing content"),
1109 @ApiResponse(responseCode = "409", description = "Service proxy already exist")})
1110 @PermissionAllowed(AafPermission.PermNames.INTERNAL_ALL_VALUE)
1111 public Response createServiceProxy(@Parameter(description = "RI object to be created", required = true) String data,
1112 @PathParam("containerComponentId") final String containerComponentId,
1113 @Parameter(description = "valid values: resources / services",
1114 schema = @Schema(allowableValues = {ComponentTypeEnum.RESOURCE_PARAM_NAME,
1115 ComponentTypeEnum.SERVICE_PARAM_NAME})) @PathParam("containerComponentType") final String containerComponentType,
1116 @HeaderParam(value = Constants.USER_ID_HEADER) @Parameter(description = "USER_ID of modifier user",
1117 required = true) String userId,
1118 @Context final HttpServletRequest request) {
1122 ComponentInstance componentInstance = RepresentationUtils.fromRepresentation(data, ComponentInstance.class);
1123 componentInstance.setInvariantName(null);
1124 ComponentTypeEnum componentTypeEnum = ComponentTypeEnum.findByParamName(containerComponentType);
1125 if (componentTypeEnum != ComponentTypeEnum.SERVICE) {
1126 log.debug("Unsupported container component type {}", containerComponentType);
1127 return buildErrorResponse(getComponentsUtils().getResponseFormat(ActionStatus.UNSUPPORTED_ERROR, containerComponentType));
1129 if (componentInstanceBusinessLogic == null) {
1130 log.debug(UNSUPPORTED_COMPONENT_TYPE, containerComponentType);
1131 return buildErrorResponse(getComponentsUtils().getResponseFormat(ActionStatus.UNSUPPORTED_ERROR, containerComponentType));
1133 Either<ComponentInstance, ResponseFormat> actionResponse = componentInstanceBusinessLogic.createServiceProxy();
1135 if (actionResponse.isRight()) {
1136 return buildErrorResponse(actionResponse.right().value());
1138 return buildOkResponse(getComponentsUtils().getResponseFormat(ActionStatus.CREATED), actionResponse.left().value());
1140 } catch (Exception e) {
1141 BeEcompErrorManager.getInstance().logBeRestApiGeneralError("Create service proxy");
1142 log.debug("Create service proxy failed with exception", e);
1148 @Path("/{containerComponentType}/{containerComponentId}/serviceProxy/{serviceProxyId}")
1149 @Consumes(MediaType.APPLICATION_JSON)
1150 @Produces(MediaType.APPLICATION_JSON)
1151 @Operation(description = "Delete service proxy", method = "DELETE", summary = "Returns delete service proxy",
1152 responses = {@ApiResponse(
1153 content = @Content(array = @ArraySchema(schema = @Schema(implementation = Response.class)))),
1154 @ApiResponse(responseCode = "201", description = "Service proxy deleted"),
1155 @ApiResponse(responseCode = "403", description = "Restricted operation"),
1156 @ApiResponse(responseCode = "400", description = "Invalid content / Missing content")})
1157 @PermissionAllowed(AafPermission.PermNames.INTERNAL_ALL_VALUE)
1158 public Response deleteServiceProxy(@PathParam("containerComponentId") final String containerComponentId,
1159 @PathParam("serviceProxyId") final String serviceProxyId,
1160 @Parameter(description = "valid values: resources / services / products",
1161 schema = @Schema(allowableValues = {ComponentTypeEnum.RESOURCE_PARAM_NAME,
1162 ComponentTypeEnum.SERVICE_PARAM_NAME})) @PathParam("containerComponentType") final String containerComponentType,
1163 @Context final HttpServletRequest request) {
1165 String url = request.getMethod() + " " + request.getRequestURI();
1167 log.debug(START_HANDLE_REQUEST_OF, url);
1168 if (componentInstanceBusinessLogic == null) {
1169 log.debug(UNSUPPORTED_COMPONENT_TYPE, containerComponentType);
1170 return buildErrorResponse(getComponentsUtils().getResponseFormat(ActionStatus.UNSUPPORTED_ERROR, containerComponentType));
1172 Either<ComponentInstance, ResponseFormat> actionResponse = componentInstanceBusinessLogic.deleteServiceProxy();
1174 if (actionResponse.isRight()) {
1175 return buildErrorResponse(actionResponse.right().value());
1177 return buildOkResponse(getComponentsUtils().getResponseFormat(ActionStatus.NO_CONTENT), null);
1179 } catch (Exception e) {
1180 BeEcompErrorManager.getInstance().logBeRestApiGeneralError("Delete service proxy");
1181 log.debug("Delete service proxy failed with exception", e);
1187 @Path("/{containerComponentType}/{containerComponentId}/serviceProxy/{serviceProxyId}/changeVersion/{newServiceId}")
1188 @Consumes(MediaType.APPLICATION_JSON)
1189 @Produces(MediaType.APPLICATION_JSON)
1190 @Operation(description = "Update service proxy with new version", method = "POST",
1191 summary = "Returns updated service proxy", responses = {
1192 @ApiResponse(content = @Content(array = @ArraySchema(schema = @Schema(implementation = Response.class)))),
1193 @ApiResponse(responseCode = "201", description = "Service proxy created"),
1194 @ApiResponse(responseCode = "403", description = "Restricted operation"),
1195 @ApiResponse(responseCode = "400", description = "Invalid content / Missing content")})
1196 @PermissionAllowed(AafPermission.PermNames.INTERNAL_ALL_VALUE)
1197 public Response changeServiceProxyVersion(@PathParam("containerComponentId") final String containerComponentId,
1198 @PathParam("serviceProxyId") final String serviceProxyId,
1199 @Parameter(description = "valid values: resources / services",
1200 schema = @Schema(allowableValues = {ComponentTypeEnum.RESOURCE_PARAM_NAME,
1201 ComponentTypeEnum.SERVICE_PARAM_NAME})) @PathParam("containerComponentType") final String containerComponentType,
1202 @Context final HttpServletRequest request) {
1205 String url = request.getMethod() + " " + request.getRequestURI();
1206 log.debug(START_HANDLE_REQUEST_OF, url);
1208 if (componentInstanceBusinessLogic == null) {
1209 log.debug(UNSUPPORTED_COMPONENT_TYPE, containerComponentType);
1210 return buildErrorResponse(getComponentsUtils().getResponseFormat(ActionStatus.UNSUPPORTED_ERROR, containerComponentType));
1212 Either<ComponentInstance, ResponseFormat> actionResponse = componentInstanceBusinessLogic.changeServiceProxyVersion();
1214 if (actionResponse.isRight()) {
1215 return buildErrorResponse(actionResponse.right().value());
1217 return buildOkResponse(getComponentsUtils().getResponseFormat(ActionStatus.OK), actionResponse.left().value());
1219 } catch (Exception e) {
1220 BeEcompErrorManager.getInstance().logBeRestApiGeneralError("Update service proxy with new version");
1221 log.debug("Update service proxy with new version failed with exception", e);
1226 * REST API GET relation by Id
1227 * Allows to get relation contained in specified component according to received Id
1228 * @param containerComponentType
1229 * @param componentId
1236 @Path("/{containerComponentType}/{componentId}/relationId/{relationId}")
1237 @Consumes(MediaType.APPLICATION_JSON)
1238 @Produces(MediaType.APPLICATION_JSON)
1239 @Operation(description = "Get relation", method = "GET",
1240 summary = "Returns relation metadata according to relationId", responses = {
1241 @ApiResponse(content = @Content(array = @ArraySchema(schema = @Schema(implementation = Response.class)))),
1242 @ApiResponse(responseCode = "200", description = "relation found"),
1243 @ApiResponse(responseCode = "403", description = "Restricted operation"),
1244 @ApiResponse(responseCode = "404", description = "Relation not found")})
1245 @PermissionAllowed(AafPermission.PermNames.INTERNAL_ALL_VALUE)
1246 public Response getRelationById(@PathParam("containerComponentType") final String containerComponentType,
1247 @PathParam("componentId") final String componentId, @PathParam("relationId") final String relationId,
1248 @Context final HttpServletRequest request, @HeaderParam(value = Constants.USER_ID_HEADER) String userId) {
1251 String url = request.getMethod() + " " + request.getRequestURI();
1252 log.debug(GET_START_HANDLE_REQUEST_OF, url);
1254 ComponentTypeEnum componentTypeEnum = ComponentTypeEnum.findByParamName(containerComponentType);
1255 if (componentTypeEnum == null) {
1256 log.debug(UNSUPPORTED_COMPONENT_TYPE, containerComponentType);
1257 return buildErrorResponse(getComponentsUtils().getResponseFormat(ActionStatus.UNSUPPORTED_ERROR, containerComponentType));
1260 Either<RequirementCapabilityRelDef, ResponseFormat> actionResponse = componentInstanceBusinessLogic.getRelationById(componentId, relationId, userId, componentTypeEnum);
1261 if (actionResponse.isRight()) {
1262 return buildErrorResponse(actionResponse.right().value());
1264 return buildOkResponse(getComponentsUtils().getResponseFormat(ActionStatus.OK), actionResponse.left().value());
1265 } catch (Exception e) {
1266 BeEcompErrorManager.getInstance().logBeRestApiGeneralError("getRelationById");
1267 log.debug("getRelationById unexpected exception", e);
1272 private Either<ComponentInstance, ResponseFormat> convertToResourceInstance(String data) {
1274 Either<ComponentInstance, ResponseFormat> convertStatus = getComponentsUtils().convertJsonToObjectUsingObjectMapper(data, new User(), ComponentInstance.class, null, ComponentTypeEnum.RESOURCE_INSTANCE);
1275 if (convertStatus.isRight()) {
1276 return Either.right(convertStatus.right().value());
1278 ComponentInstance resourceInstanceInfo = convertStatus.left().value();
1280 return Either.left(resourceInstanceInfo);
1283 private Either<List<ComponentInstance>, ResponseFormat> convertToMultipleResourceInstance(String dataList) {
1285 Either<ComponentInstance[], ResponseFormat> convertStatus = getComponentsUtils().convertJsonToObjectUsingObjectMapper(dataList, new User(), ComponentInstance[].class, null, ComponentTypeEnum.RESOURCE_INSTANCE);
1286 if (convertStatus.isRight()) {
1287 return Either.right(convertStatus.right().value());
1290 return Either.left(Arrays.asList(convertStatus.left().value()));
1293 private Either<List<ComponentInstanceProperty>, ResponseFormat> convertMultipleProperties(String dataList) {
1294 if (StringUtils.isEmpty(dataList)) {
1295 return Either.right(getComponentsUtils().getResponseFormat(ActionStatus.MISSING_BODY));
1297 Either<ComponentInstanceProperty[], ResponseFormat> convertStatus = getComponentsUtils().convertJsonToObjectUsingObjectMapper(dataList, new User(), ComponentInstanceProperty[].class, null, ComponentTypeEnum.RESOURCE_INSTANCE);
1298 if (convertStatus.isRight()) {
1299 return Either.right(convertStatus.right().value());
1301 return Either.left(Arrays.asList(convertStatus.left().value()));
1304 private Either<List<ComponentInstanceInput>, ResponseFormat> convertMultipleInputs(String dataList) {
1305 if (StringUtils.isEmpty(dataList)) {
1306 return Either.right(getComponentsUtils().getResponseFormat(ActionStatus.MISSING_BODY));
1308 Either<ComponentInstanceInput[], ResponseFormat> convertStatus = getComponentsUtils().convertJsonToObjectUsingObjectMapper(dataList, new User(), ComponentInstanceInput[].class, null, ComponentTypeEnum.RESOURCE_INSTANCE);
1309 if (convertStatus.isRight()) {
1310 return Either.right(convertStatus.right().value());
1312 return Either.left(Arrays.asList(convertStatus.left().value()));
1316 private RequirementCapabilityRelDef convertToRequirementCapabilityRelDef(String data) {
1318 Either<RequirementCapabilityRelDef, ActionStatus> convertStatus = convertJsonToObject(data, RequirementCapabilityRelDef.class);
1319 if (convertStatus.isRight()) {
1320 throw new ByActionStatusComponentException(convertStatus.right().value());
1322 return convertStatus.left().value();
1325 public <T> Either<T, ActionStatus> convertJsonToObject(String data, Class<T> clazz) {
1327 log.trace("convert json to object. json=\n {}", data);
1329 t = gsonDeserializer.fromJson(data, clazz);
1331 BeEcompErrorManager.getInstance().logBeInvalidJsonInput("convertJsonToObject");
1332 log.debug("object is null after converting from json");
1333 return Either.right(ActionStatus.INVALID_CONTENT);
1335 return Either.left(t);
1336 } catch (Exception e) {
1338 BeEcompErrorManager.getInstance().logBeInvalidJsonInput("convertJsonToObject");
1339 log.debug("failed to convert from json", e);
1340 return Either.right(ActionStatus.INVALID_CONTENT);
1346 @Path("/{containerComponentType}/{componentId}/paths-to-delete")
1347 @Produces(MediaType.APPLICATION_JSON)
1348 @Operation(description = "Check if forwarding path to delete on version change", method = "GET",
1349 summary = "Returns forwarding paths to delete", responses = {
1350 @ApiResponse(content = @Content(array = @ArraySchema(schema = @Schema(implementation = Response.class))))})
1351 public Response changeResourceInstanceVersion( @PathParam("componentId") String componentId,
1352 @QueryParam("componentInstanceId") final String oldComponentInstanceId,
1353 @QueryParam("newComponentInstanceId") final String newComponentInstanceId,
1354 @Parameter(description = "valid values: resources / services",
1355 schema = @Schema(allowableValues = {ComponentTypeEnum.RESOURCE_PARAM_NAME,
1356 ComponentTypeEnum.SERVICE_PARAM_NAME}))
1357 @PathParam("containerComponentType") final String containerComponentType,
1358 @Context final HttpServletRequest request) {
1359 if (oldComponentInstanceId == null){
1360 return buildErrorResponse(getComponentsUtils().getResponseFormat(ActionStatus.MISSING_OLD_COMPONENT_INSTANCE));
1362 if (newComponentInstanceId == null){
1363 return buildErrorResponse(getComponentsUtils().getResponseFormat(ActionStatus.MISSING_NEW_COMPONENT_INSTANCE));
1367 String url = request.getMethod() + " " + request.getRequestURI();
1368 log.debug(START_HANDLE_REQUEST_OF, url);
1369 if (componentInstanceBusinessLogic == null) {
1370 log.debug(UNSUPPORTED_COMPONENT_TYPE, containerComponentType);
1371 return buildErrorResponse(getComponentsUtils().getResponseFormat(ActionStatus.UNSUPPORTED_ERROR, containerComponentType));
1373 ComponentInstance newComponentInstance;
1374 if(StringUtils.isNotEmpty(newComponentInstanceId)){
1375 newComponentInstance=new ComponentInstance();
1376 newComponentInstance.setToscaPresentationValue(JsonPresentationFields.CI_COMPONENT_UID,newComponentInstanceId);
1378 log.error("missing component id");
1379 return buildErrorResponse(getComponentsUtils().getResponseFormat(ActionStatus.MISSING_DATA));
1381 Either<Set<String>,ResponseFormat> actionResponse= componentInstanceBusinessLogic.forwardingPathOnVersionChange(
1382 containerComponentType,componentId,oldComponentInstanceId,newComponentInstance);
1383 if (actionResponse.isRight()) {
1384 return buildErrorResponse(actionResponse.right().value());
1386 ForwardingPaths forwardingPaths=new ForwardingPaths();
1387 forwardingPaths.setForwardingPathToDelete(actionResponse.left().value());
1388 return buildOkResponse(getComponentsUtils().getResponseFormat(ActionStatus.OK), forwardingPaths);
1393 @Path("/services/{componentId}/copyComponentInstance/{componentInstanceId}")
1394 @Consumes(MediaType.APPLICATION_JSON)
1395 @Produces((MediaType.APPLICATION_JSON))
1396 @Operation(description = "Copy Component Instance", method = "POST",
1397 summary = "Returns updated service information", responses = {
1398 @ApiResponse(content = @Content(array = @ArraySchema(schema = @Schema(implementation = Service.class)))),
1399 @ApiResponse(responseCode = "201", description = "Copy and Paste Success"),
1400 @ApiResponse(responseCode = "403", description = "Restricted Operation"),
1401 @ApiResponse(responseCode = "400", description = "Invalid Content / Missing content")})
1402 public Response copyComponentInstance(
1403 @Parameter(description = "service unique id in pasted canvas") @PathParam("componentId") final String containerComponentId,
1404 @Parameter(description = "Data for copying", required = true) String data, @PathParam("componentInstanceId") final String componentInstanceId,
1405 @Context final HttpServletRequest request) {
1406 log.info("Start to copy component instance");
1408 String userId = request.getHeader(Constants.USER_ID_HEADER);
1409 final String CNTAINER_CMPT_TYPE = "services";
1412 ComponentInstance inputComponentInstance = RepresentationUtils.fromRepresentation(data, ComponentInstance.class);
1413 inputComponentInstance.setInvariantName(null);
1414 ComponentTypeEnum componentTypeEnum = ComponentTypeEnum.findByParamName(CNTAINER_CMPT_TYPE);
1415 if (componentInstanceBusinessLogic == null) {
1416 log.debug(UNSUPPORTED_COMPONENT_TYPE, componentTypeEnum);
1417 return buildErrorResponse(getComponentsUtils().getResponseFormat(ActionStatus.UNSUPPORTED_ERROR, "services"));
1419 Either<Map<String, ComponentInstance>, ResponseFormat> copyComponentInstance = componentInstanceBusinessLogic.copyComponentInstance(
1420 inputComponentInstance, containerComponentId, componentInstanceId, userId);
1422 if (copyComponentInstance.isRight()) {
1423 log.error("Failed to copy ComponentInstance {}", copyComponentInstance.right().value());
1424 return buildErrorResponse(copyComponentInstance.right().value());
1427 return buildOkResponse(getComponentsUtils().getResponseFormat(ActionStatus.OK),
1428 copyComponentInstance.left().value());
1429 } catch (Exception e) {
1430 log.error("Failed to convert json to Map { }", data, e);
1431 return buildErrorResponse(getComponentsUtils().getResponseFormat(ActionStatus.USER_DEFINED,
1432 "Failed to get the copied component instance information"));
1437 @Path("/{containerComponentType}/{componentId}/batchDeleteResourceInstances/")
1438 @Consumes(MediaType.APPLICATION_JSON)
1439 @Produces(MediaType.APPLICATION_JSON)
1440 @Operation(description = "Batch Delete ResourceInstances", method = "POST",
1441 responses = {@ApiResponse(responseCode = "203", description = "ResourceInstances deleted"),
1442 @ApiResponse(responseCode = "403", description = "Restricted Operation"),
1443 @ApiResponse(responseCode = "400", description = "Invalid Content / Missing Content")})
1444 public Response batchDeleteResourceInstances(
1445 @Parameter(description = "valid values: resources / services / products", schema = @Schema(allowableValues = {ComponentTypeEnum.RESOURCE_PARAM_NAME,
1446 ComponentTypeEnum.SERVICE_PARAM_NAME,
1447 ComponentTypeEnum.PRODUCT_PARAM_NAME}))
1448 @PathParam("containerComponentType") final String containerComponentType,
1449 @PathParam("componentId") final String componentId,
1450 @Context final HttpServletRequest request,
1451 @Parameter(description = "Component Instance Id List", required = true) final String componentInstanceIdLisStr) {
1453 if (componentInstanceIdLisStr == null || componentInstanceIdLisStr.isEmpty()) {
1454 log.error("Empty JSON List was sent",componentInstanceIdLisStr);
1455 return buildErrorResponse(getComponentsUtils().getResponseFormat(ActionStatus.INVALID_CONTENT));
1459 if (componentInstanceBusinessLogic == null) {
1460 log.error(UNSUPPORTED_COMPONENT_TYPE, containerComponentType);
1461 return buildErrorResponse(getComponentsUtils().getResponseFormat(ActionStatus.UNSUPPORTED_ERROR, containerComponentType));
1464 Either<List<String>, ResponseFormat> convertResponse = convertToStringList(componentInstanceIdLisStr);
1466 if (convertResponse.isRight()) {
1467 BeEcompErrorManager.getInstance().logBeSystemError("Resource Instance - batchDeleteResourceInstances");
1468 log.error(FAILED_TO_CONVERT_RECEIVED_DATA_TO_BE_FORMAT);
1469 return buildErrorResponse(convertResponse.right().value());
1472 String userId = request.getHeader(Constants.USER_ID_HEADER);
1473 List<String> componentInstanceIdList = convertResponse.left().value();
1474 log.debug("batchDeleteResourceInstances componentInstanceIdList is {}", componentInstanceIdList);
1475 Map<String, List<String>> deleteErrorMap = componentInstanceBusinessLogic.batchDeleteComponentInstance(containerComponentType,
1476 componentId, componentInstanceIdList, userId);
1478 return buildOkResponse(getComponentsUtils().getResponseFormat(ActionStatus.OK), deleteErrorMap);
1479 } catch (Exception e) {
1480 BeEcompErrorManager.getInstance().logBeRestApiGeneralError("Batch Delete ResourceInstances");
1481 log.error("batch delete resource instances with exception" , e);
1482 return buildErrorResponse(getComponentsUtils().getResponseFormat(ActionStatus.GENERAL_ERROR));
1488 @Path("/{containerComponentType}/{componentId}/resourceInstance/batchDissociate")
1489 @Consumes(MediaType.APPLICATION_JSON)
1490 @Produces(MediaType.APPLICATION_JSON)
1491 @Operation(description = "Batch Dissociate RI from RI", method = "PUT",
1492 summary = "Returns deleted RelationShip Info", responses = {
1493 @ApiResponse(content = @Content(array = @ArraySchema(schema = @Schema(implementation = Response.class)))),
1494 @ApiResponse(responseCode = "201", description = "Relationship deleted"),
1495 @ApiResponse(responseCode = "403", description = "Missing Information"),
1496 @ApiResponse(responseCode = "400", description = "Invalid Content / Missing Content")})
1497 public Response batchDissociateRIFromRI(
1498 @Parameter(description = "allowed values are resources/services/products",
1499 schema = @Schema(allowableValues = {ComponentTypeEnum.RESOURCE_PARAM_NAME,
1500 ComponentTypeEnum.SERVICE_PARAM_NAME,
1501 ComponentTypeEnum.PRODUCT_PARAM_NAME}),
1502 required = true) @PathParam("containerComponentType") final String containerComponentType,
1504 description = "unique id of the container component") @PathParam("componentId") final String componentId,
1505 @HeaderParam(value = Constants.USER_ID_HEADER) String userId,
1506 @Parameter(description = "RelationshipInfo", required = true) String data,
1507 @Context final HttpServletRequest request) {
1511 if (data == null || data.length() == 0) {
1512 log.info("Empty JSON list was sent");
1513 return buildErrorResponse(getComponentsUtils().getResponseFormat(ActionStatus.INVALID_CONTENT));
1516 ComponentTypeEnum componentTypeEnum = ComponentTypeEnum.findByParamName(containerComponentType);
1518 if (componentInstanceBusinessLogic == null) {
1519 log.debug(UNSUPPORTED_COMPONENT_TYPE, containerComponentType);
1520 return buildErrorResponse(getComponentsUtils().getResponseFormat(ActionStatus.UNSUPPORTED_ERROR, containerComponentType));
1523 Either<List<RequirementCapabilityRelDef>, ResponseFormat> regInfoWs = convertToRequirementCapabilityRelDefList(data);
1525 if (regInfoWs.isRight()) {
1526 BeEcompErrorManager.getInstance().logBeSystemError("Resource Instance - batch dissociateRIFromRI");
1527 log.debug("Failed to convert received data to BE format");
1528 return buildErrorResponse(regInfoWs.right().value());
1531 List<RequirementCapabilityRelDef> requirementDefList = regInfoWs.left().value();
1532 List<RequirementCapabilityRelDef> delOkResult = componentInstanceBusinessLogic.batchDissociateRIFromRI(
1533 componentId, userId, requirementDefList, componentTypeEnum);
1535 return buildOkResponse(getComponentsUtils().getResponseFormat(ActionStatus.OK), delOkResult);
1536 } catch (Exception e) {
1537 BeEcompErrorManager.getInstance().logBeRestApiGeneralError("Batch Dissociate Resource Instance");
1538 log.debug("batch dissociate resource instance from service failed with exception", e);
1539 return buildErrorResponse(getComponentsUtils().getResponseFormat(ActionStatus.GENERAL_ERROR));
1543 private Either<List<String>, ResponseFormat> convertToStringList(String datalist) {
1544 Either<String[], ResponseFormat> convertStatus = getComponentsUtils().convertJsonToObjectUsingObjectMapper(datalist, new User(), String[].class, null, null);
1546 if (convertStatus.isRight()) {
1547 return Either.right(convertStatus.right().value());
1550 return Either.left(Arrays.asList(convertStatus.left().value()));
1553 private Either<List<RequirementCapabilityRelDef>, ResponseFormat> convertToRequirementCapabilityRelDefList(String data) {
1554 Either<RequirementCapabilityRelDef[], ResponseFormat> convertStatus = getComponentsUtils().convertJsonToObjectUsingObjectMapper(data, new User(), RequirementCapabilityRelDef[].class, null, null);
1556 if (convertStatus.isRight()) {
1557 return Either.right(convertStatus.right().value());
1560 return Either.left(Arrays.asList(convertStatus.left().value()));