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=========================================================
20 package org.openecomp.sdc.be.servlets;
22 import com.fasterxml.jackson.core.JsonProcessingException;
23 import com.fasterxml.jackson.databind.ObjectMapper;
24 import com.fasterxml.jackson.databind.SerializationFeature;
25 import com.google.gson.Gson;
26 import com.google.gson.GsonBuilder;
27 import com.google.gson.reflect.TypeToken;
28 import com.jcabi.aspects.Loggable;
29 import fj.data.Either;
30 import io.swagger.v3.oas.annotations.Operation;
31 import io.swagger.v3.oas.annotations.Parameter;
32 import io.swagger.v3.oas.annotations.media.ArraySchema;
33 import io.swagger.v3.oas.annotations.media.Content;
34 import io.swagger.v3.oas.annotations.media.Schema;
35 import io.swagger.v3.oas.annotations.responses.ApiResponse;
36 import io.swagger.v3.oas.annotations.servers.Server;
37 import io.swagger.v3.oas.annotations.tags.Tag;
38 import java.io.IOException;
39 import java.io.InputStream;
40 import java.lang.reflect.Type;
41 import java.util.ArrayList;
42 import java.util.Arrays;
43 import java.util.Collections;
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.lang3.StringUtils;
66 import org.openecomp.sdc.be.components.impl.ComponentBusinessLogic;
67 import org.openecomp.sdc.be.components.impl.ComponentBusinessLogicProvider;
68 import org.openecomp.sdc.be.components.impl.ComponentInstanceBusinessLogic;
69 import org.openecomp.sdc.be.components.impl.ComponentNodeFilterBusinessLogic;
70 import org.openecomp.sdc.be.components.impl.GroupBusinessLogic;
71 import org.openecomp.sdc.be.components.impl.ResourceImportManager;
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.ByResponseFormatComponentException;
75 import org.openecomp.sdc.be.components.impl.exceptions.ComponentException;
76 import org.openecomp.sdc.be.config.BeEcompErrorManager;
77 import org.openecomp.sdc.be.dao.api.ActionStatus;
78 import org.openecomp.sdc.be.datamodel.ForwardingPaths;
79 import org.openecomp.sdc.be.datatypes.elements.CINodeFilterDataDefinition;
80 import org.openecomp.sdc.be.datatypes.elements.GetInputValueDataDefinition;
81 import org.openecomp.sdc.be.datatypes.elements.ToscaGetFunctionDataDefinition;
82 import org.openecomp.sdc.be.datatypes.enums.ComponentTypeEnum;
83 import org.openecomp.sdc.be.datatypes.enums.CreatedFrom;
84 import org.openecomp.sdc.be.datatypes.enums.JsonPresentationFields;
85 import org.openecomp.sdc.be.datatypes.enums.PropertySource;
86 import org.openecomp.sdc.be.datatypes.tosca.ToscaGetFunctionType;
87 import org.openecomp.sdc.be.externalapi.servlet.representation.ReplaceVNFInfo;
88 import org.openecomp.sdc.be.impl.ComponentsUtils;
89 import org.openecomp.sdc.be.impl.ServletUtils;
90 import org.openecomp.sdc.be.info.CreateAndAssotiateInfo;
91 import org.openecomp.sdc.be.info.GroupDefinitionInfo;
92 import org.openecomp.sdc.be.model.ComponentInstance;
93 import org.openecomp.sdc.be.model.ComponentInstanceAttribute;
94 import org.openecomp.sdc.be.model.ComponentInstanceInput;
95 import org.openecomp.sdc.be.model.ComponentInstanceProperty;
96 import org.openecomp.sdc.be.model.PropertyConstraint;
97 import org.openecomp.sdc.be.model.RequirementCapabilityRelDef;
98 import org.openecomp.sdc.be.model.RequirementDefinition;
99 import org.openecomp.sdc.be.model.Service;
100 import org.openecomp.sdc.be.model.User;
101 import org.openecomp.sdc.be.model.operations.api.StorageOperationStatus;
102 import org.openecomp.sdc.be.model.operations.impl.PropertyOperation.PropertyConstraintDeserialiser;
103 import org.openecomp.sdc.be.resources.data.ComponentMetadataData;
104 import org.openecomp.sdc.be.resources.data.auditing.AuditingActionEnum;
105 import org.openecomp.sdc.common.api.Constants;
106 import org.openecomp.sdc.common.datastructure.Wrapper;
107 import org.openecomp.sdc.common.log.elements.LoggerSupportability;
108 import org.openecomp.sdc.common.log.enums.LoggerSupportabilityActions;
109 import org.openecomp.sdc.common.log.enums.StatusCode;
110 import org.openecomp.sdc.common.log.wrappers.Logger;
111 import org.openecomp.sdc.exception.ResponseFormat;
112 import org.springframework.stereotype.Controller;
115 * Root resource (exposed at "/" path) .json.
117 @Loggable(prepend = true, value = Loggable.DEBUG, trim = false)
119 @Tag(name = "SDCE-2 APIs")
120 @Server(url = "/sdc2/rest")
122 public class ComponentInstanceServlet extends AbstractValidationsServlet {
124 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: {}";
125 private static final String GET_GROUP_ARTIFACT_BY_ID = "getGroupArtifactById";
126 private static final String GET_GROUP_ARTIFACT_BY_ID_UNEXPECTED_EXCEPTION = "getGroupArtifactById unexpected exception";
127 private static final String GET_START_HANDLE_REQUEST_OF = "(GET) Start handle request of {}";
128 private static final String START_HANDLE_REQUEST_OF_UPDATE_RESOURCE_INSTANCE_PROPERTY_RECEIVED_PROPERTY_IS = "Start handle request of updateResourceInstanceProperty. Received property is {}";
129 private static final String START_HANDLE_REQUEST_OF_UPDATE_RESOURCE_INSTANCE_ATTRIBUTE_RECEIVED_ATTRIBUTE_IS = "Start handle request of updateResourceInstanceAttribute. Received attribute is {}";
130 private static final String UPDATE_RESOURCE_INSTANCE = "Update Resource Instance";
131 private static final String RESOURCE_INSTANCE_UPDATE_RESOURCE_INSTANCE = "Resource Instance - updateResourceInstance";
132 private static final String UPDATE_RESOURCE_INSTANCE_WITH_EXCEPTION = "update resource instance with exception";
133 private static final String FAILED_TO_CONVERT_RECEIVED_DATA_TO_BE_FORMAT = "Failed to convert received data to BE format.";
134 private static final String EMPTY_BODY_WAS_SENT = "Empty body was sent.";
135 private static final String START_HANDLE_REQUEST_OF = "Start handle request of {}";
136 private static final String UNSUPPORTED_COMPONENT_TYPE = "Unsupported component type {}";
137 private static final String CREATE_AND_ASSOCIATE_RI_FAILED_WITH_EXCEPTION = "create and associate RI failed with exception: {}";
138 private static final Logger log = Logger.getLogger(ComponentInstanceServlet.class);
139 private static final Type PROPERTY_CONSTRAINT_TYPE = new TypeToken<PropertyConstraint>() {
141 private static final Gson gsonDeserializer = new GsonBuilder().registerTypeAdapter(PROPERTY_CONSTRAINT_TYPE, new PropertyConstraintDeserialiser())
143 private static final LoggerSupportability loggerSupportability = LoggerSupportability.getLogger(ComponentInstanceServlet.class.getName());
144 private static final String SERVICES = "services";
145 private final GroupBusinessLogic groupBL;
146 private final ComponentNodeFilterBusinessLogic nodeFilterBusinessLogic;
147 private final ComponentBusinessLogicProvider componentBusinessLogicProvider;
150 public ComponentInstanceServlet(GroupBusinessLogic groupBL,
151 ComponentInstanceBusinessLogic componentInstanceBL, ComponentsUtils componentsUtils, ServletUtils servletUtils,
152 ResourceImportManager resourceImportManager, ComponentNodeFilterBusinessLogic nodeFilterBusinessLogic,
153 ComponentBusinessLogicProvider componentBusinessLogicProvider) {
154 super(componentInstanceBL, componentsUtils, servletUtils, resourceImportManager);
155 this.groupBL = groupBL;
156 this.nodeFilterBusinessLogic = nodeFilterBusinessLogic;
157 this.componentBusinessLogicProvider = componentBusinessLogicProvider;
161 @Path("/{containerComponentType}/{componentId}/resourceInstance")
162 @Consumes(MediaType.APPLICATION_JSON)
163 @Produces(MediaType.APPLICATION_JSON)
164 @Operation(description = "Create ComponentInstance", method = "POST", summary = "Returns created ComponentInstance", responses = {
165 @ApiResponse(content = @Content(array = @ArraySchema(schema = @Schema(implementation = Response.class)))),
166 @ApiResponse(responseCode = "201", description = "Component created"),
167 @ApiResponse(responseCode = "403", description = "Restricted operation"),
168 @ApiResponse(responseCode = "400", description = "Invalid content / Missing content"),
169 @ApiResponse(responseCode = "409", description = "Component instance already exist")})
170 public Response createComponentInstance(@Parameter(description = "RI object to be created", required = true) String data,
171 @PathParam("componentId") final String containerComponentId,
172 @Parameter(description = "valid values: resources / services", schema = @Schema(allowableValues = {
173 ComponentTypeEnum.RESOURCE_PARAM_NAME,
174 ComponentTypeEnum.SERVICE_PARAM_NAME})) @PathParam("containerComponentType") final String containerComponentType,
175 @HeaderParam(value = Constants.USER_ID_HEADER) @Parameter(description = "USER_ID of modifier user", required = true) String userId,
176 @Context final HttpServletRequest request) {
177 validateNotEmptyBody(data);
178 final ComponentInstance componentInstance;
180 componentInstance = RepresentationUtils.fromRepresentation(data, ComponentInstance.class);
181 componentInstance.setInvariantName(null);
182 componentInstance.setCreatedFrom(CreatedFrom.UI);
183 } catch (final Exception e) {
184 BeEcompErrorManager.getInstance().logBeRestApiGeneralError("Create Component Instance");
185 log.debug("create component instance failed with exception", e);
186 return buildErrorResponse(getComponentsUtils().getResponseFormat(ActionStatus.INVALID_CONTENT, containerComponentType));
189 .log(LoggerSupportabilityActions.CREATE_INSTANCE, StatusCode.STARTED, "Starting to create component instance by {}", userId);
190 if (componentInstanceBusinessLogic == null) {
191 log.debug(UNSUPPORTED_COMPONENT_TYPE, containerComponentType);
192 return buildErrorResponse(getComponentsUtils().getResponseFormat(ActionStatus.UNSUPPORTED_ERROR, containerComponentType));
194 final ComponentInstance actionResponse = componentInstanceBusinessLogic
195 .createComponentInstance(containerComponentType, containerComponentId, userId, componentInstance);
196 loggerSupportability.log(LoggerSupportabilityActions.CREATE_INSTANCE, actionResponse.getComponentMetadataForSupportLog(), StatusCode.COMPLETE,
197 "Ending to create component instance by user {}", userId);
198 return buildOkResponse(getComponentsUtils().getResponseFormat(ActionStatus.CREATED), actionResponse);
202 @Path("/{containerComponentType}/{componentId}/resourceInstance/{componentInstanceId}")
203 @Consumes(MediaType.APPLICATION_JSON)
204 @Produces(MediaType.APPLICATION_JSON)
205 @Operation(description = "Update resource instance", method = "POST", summary = "Returns updated resource instance", responses = {
206 @ApiResponse(content = @Content(array = @ArraySchema(schema = @Schema(implementation = Response.class)))),
207 @ApiResponse(responseCode = "200", description = "Resource instance updated"),
208 @ApiResponse(responseCode = "403", description = "Restricted operation"),
209 @ApiResponse(responseCode = "400", description = "Invalid content / Missing content")})
210 public Response updateComponentInstanceMetadata(@PathParam("componentId") final String componentId,
211 @PathParam("componentInstanceId") final String componentInstanceId,
212 @Parameter(description = "valid values: resources / services / products", schema = @Schema(allowableValues = {
213 ComponentTypeEnum.RESOURCE_PARAM_NAME, ComponentTypeEnum.SERVICE_PARAM_NAME,
214 ComponentTypeEnum.PRODUCT_PARAM_NAME})) @PathParam("containerComponentType") final String containerComponentType,
215 @Context final HttpServletRequest request) throws IOException, BusinessLogicException {
216 final String url = request.getMethod() + " " + request.getRequestURI();
217 log.debug(START_HANDLE_REQUEST_OF, url);
218 loggerSupportability.log(LoggerSupportabilityActions.UPDATE_COMPONENT_INSTANCE, StatusCode.STARTED, "update Component Instance Metadata");
219 final String userId = request.getHeader(Constants.USER_ID_HEADER);
221 if (componentInstanceBusinessLogic == null) {
222 log.debug(UNSUPPORTED_COMPONENT_TYPE, containerComponentType);
223 return buildErrorResponse(getComponentsUtils().getResponseFormat(ActionStatus.UNSUPPORTED_ERROR, containerComponentType));
225 componentInstanceBusinessLogic.validateUser(userId);
226 log.debug(START_HANDLE_REQUEST_OF, url);
227 final byte[] bytes = IOUtils.toByteArray(request.getInputStream());
228 if (bytes == null || bytes.length == 0) {
229 log.info(EMPTY_BODY_WAS_SENT);
230 return buildErrorResponse(getComponentsUtils().getResponseFormat(ActionStatus.INVALID_CONTENT));
232 final String data = new String(bytes);
233 final ComponentTypeEnum componentTypeEnum = ComponentTypeEnum.findByParamName(containerComponentType);
234 final Either<ComponentInstance, ResponseFormat> convertResponse = convertToResourceInstance(data);
235 if (convertResponse.isRight()) {
236 BeEcompErrorManager.getInstance().logBeSystemError(RESOURCE_INSTANCE_UPDATE_RESOURCE_INSTANCE);
237 log.debug(FAILED_TO_CONVERT_RECEIVED_DATA_TO_BE_FORMAT);
238 return buildErrorResponse(convertResponse.right().value());
240 final ComponentInstance componentInstance = convertResponse.left().value();
241 final Either<ComponentInstance, ResponseFormat> actionResponse = componentInstanceBusinessLogic
242 .updateComponentInstanceMetadata(containerComponentType, componentId, componentInstanceId, userId, componentInstance);
244 .log(LoggerSupportabilityActions.UPDATE_COMPONENT_INSTANCE, actionResponse.left().value().getComponentMetadataForSupportLog(),
245 StatusCode.COMPLETE, "update Component Instance Metadata by {}", userId);
246 if (actionResponse.isRight()) {
247 return buildErrorResponse(actionResponse.right().value());
249 final ComponentInstance resultValue = actionResponse.left().value();
250 if (ComponentTypeEnum.SERVICE.equals(componentTypeEnum) || ComponentTypeEnum.RESOURCE.equals(componentTypeEnum)) {
251 if (CollectionUtils.isNotEmpty(componentInstance.getDirectives())) {
252 final Optional<CINodeFilterDataDefinition> nodeFilterDataDefinition = nodeFilterBusinessLogic
253 .createNodeFilterIfNotExist(componentId, componentInstanceId, true, componentTypeEnum);
254 if (!nodeFilterDataDefinition.isPresent()) {
255 BeEcompErrorManager.getInstance().logBeSystemError("Failed to create node filter.");
256 log.error("Failed to create node filter.");
257 return buildErrorResponse(convertResponse.right().value());
259 resultValue.setNodeFilter(nodeFilterDataDefinition.get());
261 final Optional<String> result = nodeFilterBusinessLogic
262 .deleteNodeFilterIfExists(componentId, componentInstanceId, true, componentTypeEnum);
263 if (!result.isPresent()) {
264 BeEcompErrorManager.getInstance().logBeSystemError("Failed to delete node filter.");
265 log.error("Failed to delete node filter.");
266 return buildErrorResponse(convertResponse.right().value());
268 resultValue.setNodeFilter(null);
271 return buildOkResponse(getComponentsUtils().getResponseFormat(ActionStatus.OK), actionResponse.left().value());
272 } catch (final Exception e) {
273 BeEcompErrorManager.getInstance().logBeRestApiGeneralError(UPDATE_RESOURCE_INSTANCE);
274 log.debug(UPDATE_RESOURCE_INSTANCE_WITH_EXCEPTION, e);
280 @Path("/{containerComponentType}/{componentId}/resourceInstance/multipleComponentInstance")
281 @Consumes(MediaType.APPLICATION_JSON)
282 @Produces(MediaType.APPLICATION_JSON)
283 @Operation(description = "Update resource instance multiple component", method = "POST", summary = "Returns updated resource instance", responses = {
284 @ApiResponse(content = @Content(array = @ArraySchema(schema = @Schema(implementation = Response.class)))),
285 @ApiResponse(responseCode = "200", description = "Resource instance updated"),
286 @ApiResponse(responseCode = "403", description = "Restricted operation"),
287 @ApiResponse(responseCode = "400", description = "Invalid content / Missing content")})
288 public Response updateMultipleComponentInstance(@PathParam("componentId") final String componentId,
289 @Parameter(description = "valid values: resources / services / products", schema = @Schema(allowableValues = {
290 ComponentTypeEnum.RESOURCE_PARAM_NAME, ComponentTypeEnum.SERVICE_PARAM_NAME,
291 ComponentTypeEnum.PRODUCT_PARAM_NAME})) @PathParam("containerComponentType") final String containerComponentType,
292 @Context final HttpServletRequest request,
293 @Parameter(description = "Component Instance JSON Array", required = true) final String componentInstanceJsonArray) {
294 String url = request.getMethod() + " " + request.getRequestURI();
295 log.debug(START_HANDLE_REQUEST_OF, url);
297 log.debug(START_HANDLE_REQUEST_OF, url);
298 if (componentInstanceJsonArray == null || componentInstanceJsonArray.length() == 0) {
299 log.info("Empty JSON list was sent.");
300 return buildErrorResponse(getComponentsUtils().getResponseFormat(ActionStatus.INVALID_CONTENT));
302 String userId = request.getHeader(Constants.USER_ID_HEADER);
303 if (componentInstanceBusinessLogic == null) {
304 log.debug(UNSUPPORTED_COMPONENT_TYPE, containerComponentType);
305 return buildErrorResponse(getComponentsUtils().getResponseFormat(ActionStatus.UNSUPPORTED_ERROR, containerComponentType));
307 Either<List<ComponentInstance>, ResponseFormat> convertResponse = convertToMultipleResourceInstance(componentInstanceJsonArray);
308 if (convertResponse.isRight()) {
309 // Using both ECOMP error methods, show to Sofer
310 BeEcompErrorManager.getInstance().logBeSystemError(RESOURCE_INSTANCE_UPDATE_RESOURCE_INSTANCE);
311 log.debug(FAILED_TO_CONVERT_RECEIVED_DATA_TO_BE_FORMAT);
312 return buildErrorResponse(convertResponse.right().value());
314 List<ComponentInstance> componentInstanceList = convertResponse.left().value();
315 List<ComponentInstance> actionResponse = componentInstanceBusinessLogic
316 .updateComponentInstance(containerComponentType, null, componentId, userId, componentInstanceList, true);
317 return buildOkResponse(getComponentsUtils().getResponseFormat(ActionStatus.OK), actionResponse);
318 } catch (Exception e) {
319 BeEcompErrorManager.getInstance().logBeRestApiGeneralError(UPDATE_RESOURCE_INSTANCE);
320 log.debug(UPDATE_RESOURCE_INSTANCE_WITH_EXCEPTION, e);
326 @Path("/{containerComponentType}/{componentId}/resourceInstance/{resourceInstanceId}")
327 @Consumes(MediaType.APPLICATION_JSON)
328 @Produces(MediaType.APPLICATION_JSON)
329 @Operation(description = "Delete ResourceInstance", method = "DELETE", summary = "Returns delete resourceInstance", responses = {
330 @ApiResponse(content = @Content(array = @ArraySchema(schema = @Schema(implementation = Response.class)))),
331 @ApiResponse(responseCode = "201", description = "ResourceInstance deleted"),
332 @ApiResponse(responseCode = "403", description = "Restricted operation"),
333 @ApiResponse(responseCode = "400", description = "Invalid content / Missing content")})
334 public Response deleteResourceInstance(@PathParam("componentId") final String componentId,
335 @PathParam("resourceInstanceId") final String resourceInstanceId,
336 @Parameter(description = "valid values: resources / services / products", schema = @Schema(allowableValues = {
337 ComponentTypeEnum.RESOURCE_PARAM_NAME, ComponentTypeEnum.SERVICE_PARAM_NAME,
338 ComponentTypeEnum.PRODUCT_PARAM_NAME})) @PathParam("containerComponentType") final String containerComponentType,
339 @Context final HttpServletRequest request) {
340 String url = request.getMethod() + " " + request.getRequestURI();
342 log.debug(START_HANDLE_REQUEST_OF, url);
343 if (componentInstanceBusinessLogic == null) {
344 log.debug(UNSUPPORTED_COMPONENT_TYPE, containerComponentType);
345 return buildErrorResponse(getComponentsUtils().getResponseFormat(ActionStatus.UNSUPPORTED_ERROR, containerComponentType));
347 String userId = request.getHeader(Constants.USER_ID_HEADER);
348 ComponentInstance actionResponse = componentInstanceBusinessLogic
349 .deleteComponentInstance(containerComponentType, componentId, resourceInstanceId, userId);
351 .log(LoggerSupportabilityActions.DELETE_COMPONENT_INSTANCE, actionResponse.getComponentMetadataForSupportLog(), StatusCode.STARTED,
352 "DELETE_COMPONENT_INSTANCE by user {}", userId);
354 .log(LoggerSupportabilityActions.DELETE_COMPONENT_INSTANCE, actionResponse.getComponentMetadataForSupportLog(), StatusCode.COMPLETE,
355 "DELETE_COMPONENT_INSTANCE by user {}", userId);
356 return buildOkResponse(getComponentsUtils().getResponseFormat(ActionStatus.OK), actionResponse);
357 } catch (Exception e) {
358 BeEcompErrorManager.getInstance().logBeRestApiGeneralError("Delete Resource Instance");
359 log.debug("delete resource instance with exception", e);
360 return buildErrorResponse(getComponentsUtils().getResponseFormat(ActionStatus.GENERAL_ERROR));
364 @Parameter(description = "allowed values are resources /services / products", schema = @Schema(allowableValues = {
365 ComponentTypeEnum.RESOURCE_PARAM_NAME, ComponentTypeEnum.SERVICE_PARAM_NAME, ComponentTypeEnum.PRODUCT_PARAM_NAME}), required = true)
367 @Path("/{containerComponentType}/{componentId}/resourceInstance/associate")
368 @Consumes(MediaType.APPLICATION_JSON)
369 @Produces(MediaType.APPLICATION_JSON)
370 @Operation(description = "Associate RI to RI", method = "POST", summary = "Returns created RelationshipInfo", responses = {
371 @ApiResponse(content = @Content(array = @ArraySchema(schema = @Schema(implementation = Response.class)))),
372 @ApiResponse(responseCode = "201", description = "Relationship created"),
373 @ApiResponse(responseCode = "403", description = "Missing information"),
374 @ApiResponse(responseCode = "400", description = "Invalid content / Missing content"),
375 @ApiResponse(responseCode = "409", description = "Relationship already exist")})
376 public Response associateRIToRI(
377 @Parameter(description = "unique id of the container component") @PathParam("componentId") final String componentId,
378 @Parameter(description = "allowed values are resources /services / products", schema = @Schema(allowableValues = {
379 ComponentTypeEnum.RESOURCE_PARAM_NAME, ComponentTypeEnum.SERVICE_PARAM_NAME,
380 ComponentTypeEnum.PRODUCT_PARAM_NAME}), required = true) @PathParam("containerComponentType") final String containerComponentType,
381 @HeaderParam(value = Constants.USER_ID_HEADER) String userId, @Parameter(description = "RelationshipInfo", required = true) String data,
382 @Context final HttpServletRequest request) {
383 String url = request.getMethod() + " " + request.getRequestURI();
384 log.debug(START_HANDLE_REQUEST_OF, url);
386 .log(LoggerSupportabilityActions.ASSOCIATE_RI_TO_RI, StatusCode.STARTED, "Starting to associate RI To RI for component {} ",
387 componentId + " by " + userId);
389 log.debug(START_HANDLE_REQUEST_OF, url);
390 ComponentTypeEnum componentTypeEnum = ComponentTypeEnum.findByParamName(containerComponentType);
391 if (componentInstanceBusinessLogic == null) {
392 log.debug(UNSUPPORTED_COMPONENT_TYPE, containerComponentType);
393 return buildErrorResponse(getComponentsUtils().getResponseFormat(ActionStatus.UNSUPPORTED_ERROR, containerComponentType));
395 RequirementCapabilityRelDef requirementDef = convertToRequirementCapabilityRelDef(data);
396 requirementDef.setOriginUI(true);
397 RequirementCapabilityRelDef actionResponse = componentInstanceBusinessLogic
398 .associateRIToRI(componentId, userId, requirementDef, componentTypeEnum);
400 .log(LoggerSupportabilityActions.ASSOCIATE_RI_TO_RI, StatusCode.COMPLETE, "Ended associate RI To RI for component {} ",
401 componentId + " by " + userId);
402 return buildOkResponse(getComponentsUtils().getResponseFormat(ActionStatus.OK), actionResponse);
403 } catch (Exception e) {
404 if (!e.getClass().equals(ComponentException.class)) {
405 BeEcompErrorManager.getInstance().logBeRestApiGeneralError("Associate Resource Instance");
406 log.debug("associate resource instance to another RI with exception", e);
407 return buildErrorResponse(getComponentsUtils().getResponseFormat(ActionStatus.GENERAL_ERROR));
414 @Path("/{containerComponentType}/{componentId}/resourceInstance/dissociate")
415 @Consumes(MediaType.APPLICATION_JSON)
416 @Produces(MediaType.APPLICATION_JSON)
417 @Operation(description = "Dissociate RI from RI", method = "PUT", summary = "Returns deleted RelationshipInfo", responses = {
418 @ApiResponse(content = @Content(array = @ArraySchema(schema = @Schema(implementation = Response.class)))),
419 @ApiResponse(responseCode = "201", description = "Relationship deleted"),
420 @ApiResponse(responseCode = "403", description = "Missing information"),
421 @ApiResponse(responseCode = "400", description = "Invalid content / Missing content")})
422 public Response dissociateRIFromRI(
423 @Parameter(description = "allowed values are resources /services / products", schema = @Schema(allowableValues = {
424 ComponentTypeEnum.RESOURCE_PARAM_NAME, ComponentTypeEnum.SERVICE_PARAM_NAME,
425 ComponentTypeEnum.PRODUCT_PARAM_NAME}), required = true) @PathParam("containerComponentType") final String containerComponentType,
426 @Parameter(description = "unique id of the container component") @PathParam("componentId") final String componentId,
427 @HeaderParam(value = Constants.USER_ID_HEADER) String userId, @Parameter(description = "RelationshipInfo", required = true) String data,
428 @Context final HttpServletRequest request) {
429 String url = request.getMethod() + " " + request.getRequestURI();
430 log.debug(START_HANDLE_REQUEST_OF, url);
432 .log(LoggerSupportabilityActions.UN_ASSOCIATE_RI_TO_RI, StatusCode.STARTED, "Starting to undo associate RI To RI for component {} ",
433 componentId + " by " + userId);
435 log.debug(START_HANDLE_REQUEST_OF, url);
436 ComponentTypeEnum componentTypeEnum = ComponentTypeEnum.findByParamName(containerComponentType);
437 if (componentInstanceBusinessLogic == null) {
438 log.debug(UNSUPPORTED_COMPONENT_TYPE, containerComponentType);
439 return buildErrorResponse(getComponentsUtils().getResponseFormat(ActionStatus.UNSUPPORTED_ERROR, containerComponentType));
441 RequirementCapabilityRelDef requirementDef = convertToRequirementCapabilityRelDef(data);
442 RequirementCapabilityRelDef actionResponse = componentInstanceBusinessLogic
443 .dissociateRIFromRI(componentId, userId, requirementDef, componentTypeEnum);
445 .log(LoggerSupportabilityActions.UN_ASSOCIATE_RI_TO_RI, StatusCode.COMPLETE, "Ended undo associate RI To RI for component {} ",
446 componentId + " by " + userId);
447 return buildOkResponse(getComponentsUtils().getResponseFormat(ActionStatus.OK), actionResponse);
448 } catch (Exception e) {
449 BeEcompErrorManager.getInstance().logBeRestApiGeneralError("Dissociate Resource Instance");
450 log.debug("dissociate resource instance from service failed with exception", e);
456 @Path("/{containerComponentType}/{componentId}/resourceInstance/createAndAssociate")
457 @Consumes(MediaType.APPLICATION_JSON)
458 @Produces(MediaType.APPLICATION_JSON)
459 @Operation(description = "Create RI and associate RI to RI", method = "POST", summary = "Returns created RI and RelationshipInfo", responses = {
460 @ApiResponse(content = @Content(array = @ArraySchema(schema = @Schema(implementation = Response.class)))),
461 @ApiResponse(responseCode = "201", description = "RI created"), @ApiResponse(responseCode = "403", description = "Restricted operation"),
462 @ApiResponse(responseCode = "400", description = "Invalid content / Missing content"),
463 @ApiResponse(responseCode = "409", description = "Relationship already exist")})
464 public Response createAndAssociateRIToRI(@PathParam("componentId") final String componentId,
465 @Parameter(description = "valid values: resources / services", schema = @Schema(allowableValues = {
466 ComponentTypeEnum.RESOURCE_PARAM_NAME, ComponentTypeEnum.SERVICE_PARAM_NAME,
467 ComponentTypeEnum.PRODUCT_PARAM_NAME})) @PathParam("containerComponentType") final String containerComponentType,
468 @Context final HttpServletRequest request) throws IOException {
469 String url = request.getMethod() + " " + request.getRequestURI();
470 log.debug(START_HANDLE_REQUEST_OF, url);
472 log.debug(START_HANDLE_REQUEST_OF, url);
473 InputStream inputStream = request.getInputStream();
474 byte[] bytes = IOUtils.toByteArray(inputStream);
475 if (bytes == null || bytes.length == 0) {
476 log.info(EMPTY_BODY_WAS_SENT);
477 return buildErrorResponse(getComponentsUtils().getResponseFormat(ActionStatus.INVALID_CONTENT));
479 String userId = request.getHeader(Constants.USER_ID_HEADER);
480 String data = new String(bytes);
481 if (componentInstanceBusinessLogic == null) {
482 log.debug(UNSUPPORTED_COMPONENT_TYPE, containerComponentType);
483 return buildErrorResponse(getComponentsUtils().getResponseFormat(ActionStatus.UNSUPPORTED_ERROR, containerComponentType));
485 Either<CreateAndAssotiateInfo, ActionStatus> convertStatus = convertJsonToObject(data, CreateAndAssotiateInfo.class);
486 if (convertStatus.isRight()) {
487 BeEcompErrorManager.getInstance().logBeSystemError("Resource Instance - createAndAssociateRIToRI");
488 log.debug(FAILED_TO_CONVERT_RECEIVED_DATA_TO_BE_FORMAT);
489 Either<Object, ResponseFormat> formattedResponse = Either
490 .right(getComponentsUtils().getResponseFormat(convertStatus.right().value()));
491 return buildErrorResponse(formattedResponse.right().value());
493 CreateAndAssotiateInfo createAndAssotiateInfo = convertStatus.left().value();
494 RequirementCapabilityRelDef requirementDef = createAndAssotiateInfo.getAssociate();
495 requirementDef.setOriginUI(true);
496 Either<CreateAndAssotiateInfo, ResponseFormat> actionResponse = componentInstanceBusinessLogic
497 .createAndAssociateRIToRI(containerComponentType, componentId, userId, createAndAssotiateInfo);
498 if (actionResponse.isRight()) {
499 return buildErrorResponse(actionResponse.right().value());
501 return buildOkResponse(getComponentsUtils().getResponseFormat(ActionStatus.CREATED), actionResponse.left().value());
502 } catch (Exception e) {
503 BeEcompErrorManager.getInstance().logBeRestApiGeneralError("Create and Associate Resource Instance");
504 log.debug("create and associate RI failed with exception", e);
510 @Path("/{containerComponentType}/{componentId}/resourceInstance/{componentInstanceId}/properties")
511 @Consumes(MediaType.APPLICATION_JSON)
512 @Produces(MediaType.APPLICATION_JSON)
513 @Operation(description = "Update resource instance property", method = "POST", summary = "Returns updated resource instance property", responses = {
514 @ApiResponse(content = @Content(array = @ArraySchema(schema = @Schema(implementation = Response.class)))),
515 @ApiResponse(responseCode = "201", description = "Resource instance created"),
516 @ApiResponse(responseCode = "403", description = "Restricted operation"),
517 @ApiResponse(responseCode = "400", description = "Invalid content / Missing content")})
518 public Response updateResourceInstanceProperties(@Parameter(description = "service id") @PathParam("componentId") final String componentId,
519 @Parameter(description = "valid values: resources / services", schema = @Schema(allowableValues = {
520 ComponentTypeEnum.RESOURCE_PARAM_NAME,
521 ComponentTypeEnum.SERVICE_PARAM_NAME})) @PathParam("containerComponentType") final String containerComponentType,
522 @Parameter(description = "resource instance id") @PathParam("componentInstanceId") final String componentInstanceId,
523 @Parameter(description = "id of user initiating the operation") @HeaderParam(value = Constants.USER_ID_HEADER) String userId,
524 @Context final HttpServletRequest request,
525 @Parameter(description = "Component Instance Properties JSON Array", required = true) final String componentInstancePropertiesJsonArray) {
526 String url = request.getMethod() + " " + request.getRequestURI();
527 log.debug(START_HANDLE_REQUEST_OF, url);
528 loggerSupportability.log(LoggerSupportabilityActions.UPDATE_COMPONENT_INSTANCE, StatusCode.STARTED,
529 "Starting to update Resource Instance Properties for component {} ", componentId + " by " + userId);
530 Wrapper<ResponseFormat> errorWrapper = new Wrapper<>();
531 ComponentTypeEnum componentTypeEnum = ComponentTypeEnum.findByParamName(containerComponentType);
532 List<ComponentInstanceProperty> propertiesToUpdate = new ArrayList<>();
533 if (errorWrapper.isEmpty()) {
534 Either<List<ComponentInstanceProperty>, ResponseFormat> propertiesToUpdateEither = convertMultipleProperties(
535 componentInstancePropertiesJsonArray);
536 if (propertiesToUpdateEither.isRight()) {
537 errorWrapper.setInnerElement(propertiesToUpdateEither.right().value());
539 propertiesToUpdate = propertiesToUpdateEither.left().value();
540 handleDeprecatedComponentInstancePropertyStructure(propertiesToUpdate, componentTypeEnum);
543 if (!errorWrapper.isEmpty()) {
544 return buildErrorResponse(errorWrapper.getInnerElement());
546 log.debug(START_HANDLE_REQUEST_OF_UPDATE_RESOURCE_INSTANCE_PROPERTY_RECEIVED_PROPERTY_IS, propertiesToUpdate);
547 if (componentInstanceBusinessLogic == null) {
548 log.debug(UNSUPPORTED_COMPONENT_TYPE, containerComponentType);
549 return buildErrorResponse(getComponentsUtils().getResponseFormat(ActionStatus.UNSUPPORTED_ERROR, containerComponentType));
551 Either<List<ComponentInstanceProperty>, ResponseFormat> actionResponse = componentInstanceBusinessLogic
552 .createOrUpdatePropertiesValues(componentTypeEnum, componentId, componentInstanceId, propertiesToUpdate, userId);
553 if (actionResponse.isRight()) {
554 return buildErrorResponse(actionResponse.right().value());
556 List<ComponentInstanceProperty> resourceInstanceProperties = actionResponse.left().value();
557 ObjectMapper mapper = new ObjectMapper();
559 loggerSupportability.log(LoggerSupportabilityActions.UPDATE_COMPONENT_INSTANCE, StatusCode.COMPLETE,
560 "Ended update Resource Instance Properties for component {} ", componentId + " by " + userId);
562 result = mapper.writeValueAsString(resourceInstanceProperties);
563 } catch (JsonProcessingException e) {
564 log.error(UPDATE_RESOURCE_INSTANCE_WITH_EXCEPTION, e.getMessage(), e);
565 throw new ByActionStatusComponentException(ActionStatus.GENERAL_ERROR);
567 loggerSupportability.log(LoggerSupportabilityActions.UPDATE_COMPONENT_INSTANCE, StatusCode.COMPLETE,
568 "Ended update Resource Instance Properties for component {} ", componentId + " by user " + userId);
569 return buildOkResponse(getComponentsUtils().getResponseFormat(ActionStatus.OK), result);
572 private void handleDeprecatedComponentInstancePropertyStructure(final List<ComponentInstanceProperty> propertiesToUpdate,
573 final ComponentTypeEnum componentTypeEnum) {
574 propertiesToUpdate.stream().forEach(property -> {
575 if (property.getGetInputValues() != null) {
576 property.getGetInputValues().stream()
577 .forEach(getInputValue -> property.setToscaFunction(createToscaFunction(getInputValue, componentTypeEnum)));
582 private ToscaGetFunctionDataDefinition createToscaFunction(final GetInputValueDataDefinition getInput,
583 final ComponentTypeEnum componentTypeEnum) {
584 final String[] inputIdSplit = getInput.getInputId().split("\\.");
586 ToscaGetFunctionDataDefinition toscaFunction = new ToscaGetFunctionDataDefinition();
587 toscaFunction.setFunctionType(ToscaGetFunctionType.GET_INPUT);
588 toscaFunction.setPropertyUniqueId(getInput.getInputId());
589 toscaFunction.setPropertySource(PropertySource.SELF);
590 toscaFunction.setPropertyName(inputIdSplit[1]);
591 toscaFunction.setSourceName(getSourceName(inputIdSplit[0], componentTypeEnum));
592 toscaFunction.setSourceUniqueId(inputIdSplit[0]);
593 toscaFunction.setPropertyPathFromSource(Collections.singletonList(inputIdSplit[1]));
595 return toscaFunction;
598 private String getSourceName(final String componentId, final ComponentTypeEnum componentTypeEnum) {
599 ComponentBusinessLogic compBL = componentBusinessLogicProvider.getInstance(componentTypeEnum);
600 final Either<ComponentMetadataData, StorageOperationStatus> componentEither = compBL.getComponentMetadata(componentId);
601 if (componentEither.isLeft()) {
602 return componentEither.left().value().getMetadataDataDefinition().getName();
608 @Path("/{containerComponentType}/{componentId}/resourceInstance/{componentInstanceId}/inputs")
609 @Consumes(MediaType.APPLICATION_JSON)
610 @Produces(MediaType.APPLICATION_JSON)
611 @Operation(description = "Update resource instance property", method = "POST", summary = "Returns updated resource instance property", responses = {
612 @ApiResponse(content = @Content(array = @ArraySchema(schema = @Schema(implementation = Response.class)))),
613 @ApiResponse(responseCode = "201", description = "Resource instance created"),
614 @ApiResponse(responseCode = "403", description = "Restricted operation"),
615 @ApiResponse(responseCode = "400", description = "Invalid content / Missing content")})
616 public Response updateResourceInstanceInput(@Parameter(description = "service id") @PathParam("componentId") final String componentId,
617 @Parameter(description = "valid values: resources / services", schema = @Schema(allowableValues = {
618 ComponentTypeEnum.RESOURCE_PARAM_NAME,
619 ComponentTypeEnum.SERVICE_PARAM_NAME})) @PathParam("containerComponentType") final String containerComponentType,
620 @Parameter(description = "resource instance id") @PathParam("componentInstanceId") final String componentInstanceId,
621 @Parameter(description = "id of user initiating the operation") @HeaderParam(value = Constants.USER_ID_HEADER) String userId,
622 @Context final HttpServletRequest request,
623 @Parameter(description = "Component Instance Properties JSON Array", required = true) final String componentInstanceInputsJsonArray) {
624 String url = request.getMethod() + " " + request.getRequestURI();
625 log.debug(START_HANDLE_REQUEST_OF, url);
626 Wrapper<ResponseFormat> errorWrapper = new Wrapper<>();
627 List<ComponentInstanceInput> inputsToUpdate = new ArrayList<>();
628 if (errorWrapper.isEmpty()) {
629 Either<List<ComponentInstanceInput>, ResponseFormat> inputsToUpdateEither = convertMultipleInputs(componentInstanceInputsJsonArray);
630 if (inputsToUpdateEither.isRight()) {
631 errorWrapper.setInnerElement(inputsToUpdateEither.right().value());
633 inputsToUpdate = inputsToUpdateEither.left().value();
636 if (!errorWrapper.isEmpty()) {
637 return buildErrorResponse(errorWrapper.getInnerElement());
639 log.debug(START_HANDLE_REQUEST_OF_UPDATE_RESOURCE_INSTANCE_PROPERTY_RECEIVED_PROPERTY_IS, inputsToUpdate);
640 ComponentTypeEnum componentTypeEnum = ComponentTypeEnum.findByParamName(containerComponentType);
641 if (componentInstanceBusinessLogic == null) {
642 log.debug(UNSUPPORTED_COMPONENT_TYPE, containerComponentType);
643 return buildErrorResponse(getComponentsUtils().getResponseFormat(ActionStatus.UNSUPPORTED_ERROR, containerComponentType));
645 Either<List<ComponentInstanceInput>, ResponseFormat> actionResponse = componentInstanceBusinessLogic
646 .createOrUpdateInstanceInputValues(componentTypeEnum, componentId, componentInstanceId, inputsToUpdate, userId);
647 if (actionResponse.isRight()) {
648 return buildErrorResponse(actionResponse.right().value());
650 List<ComponentInstanceInput> resourceInstanceInput = actionResponse.left().value();
651 ObjectMapper mapper = new ObjectMapper();
652 mapper.configure(SerializationFeature.FAIL_ON_EMPTY_BEANS, false);
655 .log(LoggerSupportabilityActions.UPDATE_PROPERTIES, StatusCode.COMPLETE, "Ending update Resource Instance Input for component {} ",
656 componentId + " by " + userId);
658 result = mapper.writeValueAsString(resourceInstanceInput);
659 } catch (JsonProcessingException e) {
660 log.error(UPDATE_RESOURCE_INSTANCE_WITH_EXCEPTION, e.getMessage(), e);
661 return buildErrorResponse(getComponentsUtils().getResponseFormat(ActionStatus.GENERAL_ERROR));
664 .log(LoggerSupportabilityActions.UPDATE_PROPERTIES, StatusCode.COMPLETE, "Ending update Resource Instance Input for component {} ",
665 componentId + " by user " + userId);
666 return buildOkResponse(getComponentsUtils().getResponseFormat(ActionStatus.OK), result);
670 * Updates ResourceInstance Attribute
673 * @param containerComponentType
674 * @param componentInstanceId
680 @Path("/{containerComponentType}/{componentId}/resourceInstance/{componentInstanceId}/attributes")
681 @Consumes(MediaType.APPLICATION_JSON)
682 @Produces(MediaType.APPLICATION_JSON)
683 @Operation(description = "Update resource instance attribute", method = "POST", summary = "Returns updated resource instance property", responses = {
684 @ApiResponse(content = @Content(array = @ArraySchema(schema = @Schema(implementation = Response.class)))),
685 @ApiResponse(responseCode = "201", description = "Resource instance created"),
686 @ApiResponse(responseCode = "403", description = "Restricted operation"),
687 @ApiResponse(responseCode = "400", description = "Invalid content / Missing content")})
688 public Response updateResourceInstanceAttribute(@Parameter(description = "service id") @PathParam("componentId") final String componentId,
689 @Parameter(description = "valid values: resources / services", schema = @Schema(allowableValues = {
690 ComponentTypeEnum.RESOURCE_PARAM_NAME,
691 ComponentTypeEnum.SERVICE_PARAM_NAME})) @PathParam("containerComponentType") final String containerComponentType,
692 @Parameter(description = "resource instance id") @PathParam("componentInstanceId") final String componentInstanceId,
693 @Parameter(description = "id of user initiating the operation") @HeaderParam(value = Constants.USER_ID_HEADER) final String userId,
694 @Context final HttpServletRequest request,
695 @Parameter(description = "Component Instance Properties JSON Array", required = true) final String componentInstanceAttributesJsonArray) {
696 final String url = request.getMethod() + " " + request.getRequestURI();
697 log.debug(START_HANDLE_REQUEST_OF, url);
698 loggerSupportability.log(LoggerSupportabilityActions.UPDATE_COMPONENT_INSTANCE, StatusCode.STARTED,
699 "Starting to update Resource Instance Attributes for component {} ", componentId + " by " + userId);
700 final Wrapper<ResponseFormat> errorWrapper = new Wrapper<>();
701 List<ComponentInstanceAttribute> attributesToUpdate = new ArrayList<>();
702 if (errorWrapper.isEmpty()) {
703 final Either<List<ComponentInstanceAttribute>, ResponseFormat> attributesToUpdateEither = convertMultipleAttributes(
704 componentInstanceAttributesJsonArray);
705 if (attributesToUpdateEither.isRight()) {
706 errorWrapper.setInnerElement(attributesToUpdateEither.right().value());
708 attributesToUpdate = attributesToUpdateEither.left().value();
711 if (!errorWrapper.isEmpty()) {
712 return buildErrorResponse(errorWrapper.getInnerElement());
714 log.debug(START_HANDLE_REQUEST_OF_UPDATE_RESOURCE_INSTANCE_ATTRIBUTE_RECEIVED_ATTRIBUTE_IS, attributesToUpdate);
715 final ComponentTypeEnum componentTypeEnum = ComponentTypeEnum.findByParamName(containerComponentType);
716 if (componentInstanceBusinessLogic == null) {
717 log.debug(UNSUPPORTED_COMPONENT_TYPE, containerComponentType);
718 return buildErrorResponse(getComponentsUtils().getResponseFormat(ActionStatus.UNSUPPORTED_ERROR, containerComponentType));
720 final Either<List<ComponentInstanceAttribute>, ResponseFormat> actionResponse = componentInstanceBusinessLogic
721 .createOrUpdateAttributeValues(componentTypeEnum, componentId, componentInstanceId, attributesToUpdate, userId);
722 if (actionResponse.isRight()) {
723 return buildErrorResponse(actionResponse.right().value());
725 final List<ComponentInstanceAttribute> resourceInstanceAttributes = actionResponse.left().value();
726 final ObjectMapper mapper = new ObjectMapper();
728 loggerSupportability.log(LoggerSupportabilityActions.UPDATE_COMPONENT_INSTANCE, StatusCode.COMPLETE,
729 "Ended update Resource Instance Attributes for component {} ", componentId + " by " + userId);
731 result = mapper.writeValueAsString(resourceInstanceAttributes);
732 } catch (JsonProcessingException e) {
733 log.error(UPDATE_RESOURCE_INSTANCE_WITH_EXCEPTION, e.getMessage(), e);
734 throw new ByActionStatusComponentException(ActionStatus.GENERAL_ERROR);
736 loggerSupportability.log(LoggerSupportabilityActions.UPDATE_COMPONENT_INSTANCE, StatusCode.COMPLETE,
737 "Ended update Resource Instance Attributes for component {} ", componentId + " by user " + userId);
738 return buildOkResponse(getComponentsUtils().getResponseFormat(ActionStatus.OK), result);
742 @Path("/{containerComponentType}/{componentId}/resourceInstance/{componentInstanceId}/property/{propertyId}")
743 @Consumes(MediaType.APPLICATION_JSON)
744 @Produces(MediaType.APPLICATION_JSON)
745 @Operation(description = "Update resource instance", method = "DELETE", summary = "Returns deleted resource instance property", responses = {
746 @ApiResponse(content = @Content(array = @ArraySchema(schema = @Schema(implementation = Response.class)))),
747 @ApiResponse(responseCode = "201", description = "Resource instance created"),
748 @ApiResponse(responseCode = "403", description = "Restricted operation"),
749 @ApiResponse(responseCode = "400", description = "Invalid content / Missing content")})
750 public Response deleteResourceInstanceProperty(@Parameter(description = "service id") @PathParam("componentId") final String componentId,
751 @Parameter(description = "valid values: resources / services", schema = @Schema(allowableValues = {
752 ComponentTypeEnum.RESOURCE_PARAM_NAME,
753 ComponentTypeEnum.SERVICE_PARAM_NAME})) @PathParam("containerComponentType") final String containerComponentType,
754 @Parameter(description = "resource instance id") @PathParam("componentInstanceId") final String componentInstanceId,
755 @Parameter(description = "property id") @PathParam("propertyId") final String propertyId,
756 @Parameter(description = "id of user initiating the operation") @HeaderParam(value = Constants.USER_ID_HEADER) String userId,
757 @Context final HttpServletRequest request) {
759 .log(LoggerSupportabilityActions.UPDATE_PROPERTIES, StatusCode.STARTED, "Starting to delete Resource Instance Property for component {} ",
760 componentId + " by " + userId);
761 String url = request.getMethod() + " " + request.getRequestURI();
762 log.debug(START_HANDLE_REQUEST_OF, url);
764 ComponentTypeEnum componentTypeEnum = ComponentTypeEnum.findByParamName(containerComponentType);
766 .log(LoggerSupportabilityActions.UPDATE_PROPERTIES, StatusCode.COMPLETE, "Ended delete Resource Instance Property for component {} ",
767 componentId + " by " + userId);
768 if (componentInstanceBusinessLogic == null) {
769 log.debug(UNSUPPORTED_COMPONENT_TYPE, containerComponentType);
770 return buildErrorResponse(getComponentsUtils().getResponseFormat(ActionStatus.UNSUPPORTED_ERROR, containerComponentType));
772 Either<ComponentInstanceProperty, ResponseFormat> actionResponse = componentInstanceBusinessLogic
773 .deletePropertyValue(componentTypeEnum, componentId, componentInstanceId, propertyId, userId);
774 if (actionResponse.isRight()) {
775 return buildErrorResponse(actionResponse.right().value());
777 return buildOkResponse(getComponentsUtils().getResponseFormat(ActionStatus.NO_CONTENT), null);
778 } catch (Exception e) {
779 log.error(CREATE_AND_ASSOCIATE_RI_FAILED_WITH_EXCEPTION, e.getMessage(), e);
785 @Path("/{containerComponentType}/{componentId}/resourceInstance/{componentInstanceId}/changeVersion")
786 @Consumes(MediaType.APPLICATION_JSON)
787 @Produces(MediaType.APPLICATION_JSON)
788 @Operation(description = "Update resource instance", method = "POST", summary = "Returns updated resource instance", responses = {
789 @ApiResponse(content = @Content(array = @ArraySchema(schema = @Schema(implementation = Response.class)))),
790 @ApiResponse(responseCode = "201", description = "Resource instance created"),
791 @ApiResponse(responseCode = "403", description = "Restricted operation"),
792 @ApiResponse(responseCode = "400", description = "Invalid content / Missing content")})
793 public Response changeResourceInstanceVersion(@PathParam("componentId") final String componentId,
794 @PathParam("componentInstanceId") final String componentInstanceId,
795 @Parameter(description = "valid values: resources / services", schema = @Schema(allowableValues = {
796 ComponentTypeEnum.RESOURCE_PARAM_NAME,
797 ComponentTypeEnum.SERVICE_PARAM_NAME})) @PathParam("containerComponentType") final String containerComponentType,
798 @Context final HttpServletRequest request) throws IOException {
799 String url = request.getMethod() + " " + request.getRequestURI();
800 log.debug(START_HANDLE_REQUEST_OF, url);
801 try (InputStream inputStream = request.getInputStream()) {
802 byte[] bytes = IOUtils.toByteArray(inputStream);
803 if (bytes == null || bytes.length == 0) {
804 log.info(EMPTY_BODY_WAS_SENT);
805 return buildErrorResponse(getComponentsUtils().getResponseFormat(ActionStatus.INVALID_CONTENT));
807 String userId = request.getHeader(Constants.USER_ID_HEADER);
808 String data = new String(bytes);
809 if (componentInstanceBusinessLogic == null) {
810 log.debug(UNSUPPORTED_COMPONENT_TYPE, containerComponentType);
811 return buildErrorResponse(getComponentsUtils().getResponseFormat(ActionStatus.UNSUPPORTED_ERROR, containerComponentType));
813 Either<ComponentInstance, ResponseFormat> convertResponse = convertToResourceInstance(data);
814 if (convertResponse.isRight()) {
815 BeEcompErrorManager.getInstance().logBeSystemError(RESOURCE_INSTANCE_UPDATE_RESOURCE_INSTANCE);
816 log.debug(FAILED_TO_CONVERT_RECEIVED_DATA_TO_BE_FORMAT);
817 return buildErrorResponse(convertResponse.right().value());
819 ComponentInstance newResourceInstance = convertResponse.left().value();
820 ComponentInstance actionResponse = componentInstanceBusinessLogic
821 .changeComponentInstanceVersion(containerComponentType, componentId, componentInstanceId, userId, newResourceInstance);
822 return buildOkResponse(getComponentsUtils().getResponseFormat(ActionStatus.OK), actionResponse);
823 } catch (Exception e) {
824 BeEcompErrorManager.getInstance().logBeRestApiGeneralError(UPDATE_RESOURCE_INSTANCE);
825 log.debug(UPDATE_RESOURCE_INSTANCE_WITH_EXCEPTION, e);
831 @Path("/{containerComponentType}/{componentId}/resourceInstance/{componentInstanceId}/groupInstance/{groupInstanceId}/property")
832 @Consumes(MediaType.APPLICATION_JSON)
833 @Produces(MediaType.APPLICATION_JSON)
834 @Operation(description = "Update resource instance property", method = "POST", summary = "Returns updated resource instance property", responses = {
835 @ApiResponse(content = @Content(array = @ArraySchema(schema = @Schema(implementation = Response.class)))),
836 @ApiResponse(responseCode = "201", description = "Resource instance created"),
837 @ApiResponse(responseCode = "403", description = "Restricted operation"),
838 @ApiResponse(responseCode = "400", description = "Invalid content / Missing content")})
839 public Response updateGroupInstanceProperty(@Parameter(description = "service id") @PathParam("componentId") final String componentId,
840 @Parameter(description = "valid values: resources / services", schema = @Schema(allowableValues = {
841 ComponentTypeEnum.RESOURCE_PARAM_NAME,
842 ComponentTypeEnum.SERVICE_PARAM_NAME})) @PathParam("containerComponentType") final String containerComponentType,
843 @Parameter(description = "resource instance id") @PathParam("componentInstanceId") final String componentInstanceId,
844 @Parameter(description = "group instance id") @PathParam("groupInstanceId") final String groupInstanceId,
845 @Parameter(description = "id of user initiating the operation") @HeaderParam(value = Constants.USER_ID_HEADER) String userId,
846 @Context final HttpServletRequest request) throws IOException {
847 String url = request.getMethod() + " " + request.getRequestURI();
848 log.debug(START_HANDLE_REQUEST_OF, url);
851 .log(LoggerSupportabilityActions.UPDATE_PROPERTIES, StatusCode.STARTED, "Starting update Group Instance Property for component {} ",
852 componentId + " by " + userId);
853 Wrapper<String> dataWrapper = new Wrapper<>();
854 Wrapper<ResponseFormat> errorWrapper = new Wrapper<>();
855 Wrapper<ComponentInstanceProperty> propertyWrapper = new Wrapper<>();
856 validateInputStream(request, dataWrapper, errorWrapper);
857 if (errorWrapper.isEmpty()) {
858 validateClassParse(dataWrapper.getInnerElement(), propertyWrapper, () -> ComponentInstanceProperty.class, errorWrapper);
860 if (!errorWrapper.isEmpty()) {
861 return buildErrorResponse(errorWrapper.getInnerElement());
863 ComponentInstanceProperty property = propertyWrapper.getInnerElement();
864 log.debug(START_HANDLE_REQUEST_OF_UPDATE_RESOURCE_INSTANCE_PROPERTY_RECEIVED_PROPERTY_IS, property);
865 ComponentTypeEnum componentTypeEnum = ComponentTypeEnum.findByParamName(containerComponentType);
866 if (componentInstanceBusinessLogic == null) {
867 log.debug(UNSUPPORTED_COMPONENT_TYPE, containerComponentType);
868 return buildErrorResponse(getComponentsUtils().getResponseFormat(ActionStatus.UNSUPPORTED_ERROR, containerComponentType));
870 Either<ComponentInstanceProperty, ResponseFormat> actionResponse = componentInstanceBusinessLogic
871 .createOrUpdateGroupInstancePropertyValue(componentTypeEnum, componentId, componentInstanceId, groupInstanceId, property, userId);
872 if (actionResponse.isRight()) {
873 return buildErrorResponse(actionResponse.right().value());
875 ComponentInstanceProperty resourceInstanceProperty = actionResponse.left().value();
876 ObjectMapper mapper = new ObjectMapper();
877 String result = mapper.writeValueAsString(resourceInstanceProperty);
879 .log(LoggerSupportabilityActions.UPDATE_PROPERTIES, StatusCode.COMPLETE, "Ended update Group Instance Property for component {} ",
880 componentId + " by " + userId);
881 return buildOkResponse(getComponentsUtils().getResponseFormat(ActionStatus.OK), result);
882 } catch (Exception e) {
883 log.error(CREATE_AND_ASSOCIATE_RI_FAILED_WITH_EXCEPTION, e.getMessage(), e);
889 @Path("/{containerComponentType}/{componentId}/resourceInstance/{componentInstanceId}/groupInstance/{groupInstId}")
890 @Consumes(MediaType.APPLICATION_JSON)
891 @Produces(MediaType.APPLICATION_JSON)
892 @Operation(description = "Get group artifacts ", method = "GET", summary = "Returns artifacts metadata according to groupInstId", responses = {
893 @ApiResponse(content = @Content(array = @ArraySchema(schema = @Schema(implementation = Response.class)))),
894 @ApiResponse(responseCode = "200", description = "group found"), @ApiResponse(responseCode = "403", description = "Restricted operation"),
895 @ApiResponse(responseCode = "404", description = "Group not found")})
896 public Response getGroupArtifactById(@PathParam("containerComponentType") final String containerComponentType,
897 @PathParam("componentId") final String componentId,
898 @PathParam("componentInstanceId") final String componentInstanceId,
899 @PathParam("groupInstId") final String groupInstId, @Context final HttpServletRequest request,
900 @HeaderParam(value = Constants.USER_ID_HEADER) String userId) {
901 String url = request.getMethod() + " " + request.getRequestURI();
902 log.debug(GET_START_HANDLE_REQUEST_OF, url);
904 ComponentTypeEnum componentTypeEnum = ComponentTypeEnum.findByParamName(containerComponentType);
905 Either<GroupDefinitionInfo, ResponseFormat> actionResponse = groupBL
906 .getGroupInstWithArtifactsById(componentTypeEnum, componentId, componentInstanceId, groupInstId, userId, false);
907 if (actionResponse.isRight()) {
908 log.debug("failed to get all non abstract {}", containerComponentType);
909 return buildErrorResponse(actionResponse.right().value());
911 return buildOkResponse(getComponentsUtils().getResponseFormat(ActionStatus.OK), actionResponse.left().value());
912 } catch (Exception e) {
913 BeEcompErrorManager.getInstance().logBeRestApiGeneralError(GET_GROUP_ARTIFACT_BY_ID);
914 log.debug(GET_GROUP_ARTIFACT_BY_ID_UNEXPECTED_EXCEPTION, e);
921 @Path("/{containerComponentType}/{containerComponentId}/componentInstances/{componentInstanceUniqueId}/properties")
922 @Consumes(MediaType.APPLICATION_JSON)
923 @Produces(MediaType.APPLICATION_JSON)
924 @Operation(description = "Get component instance properties", method = "GET", summary = "Returns component instance properties", responses = {
925 @ApiResponse(content = @Content(array = @ArraySchema(schema = @Schema(implementation = Response.class)))),
926 @ApiResponse(responseCode = "200", description = "Properties found"),
927 @ApiResponse(responseCode = "403", description = "Restricted operation"),
928 @ApiResponse(responseCode = "404", description = "Component/Component Instance - not found")})
929 public Response getInstancePropertiesById(@PathParam("containerComponentType") final String containerComponentType,
930 @PathParam("containerComponentId") final String containerComponentId,
931 @PathParam("componentInstanceUniqueId") final String componentInstanceUniqueId,
932 @Context final HttpServletRequest request,
933 @HeaderParam(value = Constants.USER_ID_HEADER) String userId) {
934 String url = request.getMethod() + " " + request.getRequestURI();
935 log.debug(GET_START_HANDLE_REQUEST_OF, url);
936 List<ComponentInstanceProperty> componentInstancePropertiesById = componentInstanceBusinessLogic
937 .getComponentInstancePropertiesById(containerComponentType, containerComponentId, componentInstanceUniqueId, userId);
938 return buildOkResponse(getComponentsUtils().getResponseFormat(ActionStatus.OK), componentInstancePropertiesById);
942 @Path("/{containerComponentType}/{containerComponentId}/componentInstances/{componentInstanceUniqueId}/attributes")
943 @Consumes(MediaType.APPLICATION_JSON)
944 @Produces(MediaType.APPLICATION_JSON)
945 @Operation(description = "Get component instance attributes", method = "GET", summary = "Returns component instance attributes", responses = {
946 @ApiResponse(content = @Content(array = @ArraySchema(schema = @Schema(implementation = Response.class)))),
947 @ApiResponse(responseCode = "200", description = "Attributes found"),
948 @ApiResponse(responseCode = "403", description = "Restricted operation"),
949 @ApiResponse(responseCode = "404", description = "Component/Component Instance - not found")})
950 public Response getInstanceAttributesById(@PathParam("containerComponentType") final String containerComponentType,
951 @PathParam("containerComponentId") final String containerComponentId,
952 @PathParam("componentInstanceUniqueId") final String componentInstanceUniqueId,
953 @Context final HttpServletRequest request,
954 @HeaderParam(value = Constants.USER_ID_HEADER) final String userId) {
955 final String url = request.getMethod() + " " + request.getRequestURI();
956 log.debug(GET_START_HANDLE_REQUEST_OF, url);
957 final List<ComponentInstanceAttribute> componentInstanceAttributesById = componentInstanceBusinessLogic
958 .getComponentInstanceAttributesById(containerComponentType, containerComponentId, componentInstanceUniqueId, userId);
959 return buildOkResponse(getComponentsUtils().getResponseFormat(ActionStatus.OK), componentInstanceAttributesById);
964 @Path("/{containerComponentType}/{containerComponentId}/componentInstances/{componentInstanceUniqueId}/capability/{capabilityType}/capabilityName/{capabilityName}/ownerId/{ownerId}/properties")
965 @Consumes(MediaType.APPLICATION_JSON)
966 @Produces(MediaType.APPLICATION_JSON)
967 @Operation(description = "Get component instance capability properties", method = "GET", summary = "Returns component instance capability properties", responses = {
968 @ApiResponse(content = @Content(array = @ArraySchema(schema = @Schema(implementation = Response.class)))),
969 @ApiResponse(responseCode = "200", description = "Properties found"),
970 @ApiResponse(responseCode = "403", description = "Restricted operation"),
971 @ApiResponse(responseCode = "404", description = "Component/Component Instance/Capability - not found")})
972 public Response getInstanceCapabilityPropertiesById(@PathParam("containerComponentType") final String containerComponentType,
973 @PathParam("containerComponentId") final String containerComponentId,
974 @PathParam("componentInstanceUniqueId") final String componentInstanceUniqueId,
975 @PathParam("capabilityType") final String capabilityType,
976 @PathParam("capabilityName") final String capabilityName,
977 @PathParam("ownerId") final String ownerId, @Context final HttpServletRequest request,
978 @HeaderParam(value = Constants.USER_ID_HEADER) String userId) {
979 String url = request.getMethod() + " " + request.getRequestURI();
980 log.debug(GET_START_HANDLE_REQUEST_OF, url);
982 List<ComponentInstanceProperty> componentInstancePropertiesById = componentInstanceBusinessLogic
983 .getComponentInstanceCapabilityPropertiesById(containerComponentType, containerComponentId, componentInstanceUniqueId, capabilityType,
984 capabilityName, ownerId, userId);
985 return buildOkResponse(getComponentsUtils().getResponseFormat(ActionStatus.OK), componentInstancePropertiesById);
986 } catch (Exception e) {
987 BeEcompErrorManager.getInstance().logBeRestApiGeneralError(GET_GROUP_ARTIFACT_BY_ID);
988 log.debug(GET_GROUP_ARTIFACT_BY_ID_UNEXPECTED_EXCEPTION, e);
995 @Path("/{containerComponentType}/{containerComponentId}/componentInstances/{componentInstanceUniqueId}/capability/{capabilityType}/capabilityName/{capabilityName}/ownerId/{ownerId}/properties")
996 @Consumes(MediaType.APPLICATION_JSON)
997 @Produces(MediaType.APPLICATION_JSON)
998 @Operation(description = "Update Instance Capabilty Property", method = "PUT", summary = "Returns updated property", responses = {
999 @ApiResponse(content = @Content(array = @ArraySchema(schema = @Schema(implementation = Response.class)))),
1000 @ApiResponse(responseCode = "200", description = "Resource instance capabilty property updated"),
1001 @ApiResponse(responseCode = "403", description = "Restricted operation"),
1002 @ApiResponse(responseCode = "400", description = "Invalid content / Missing content"),
1003 @ApiResponse(responseCode = "404", description = "Component/Component Instance/Capability - not found")})
1004 public Response updateInstanceCapabilityProperty(@PathParam("containerComponentType") final String containerComponentType,
1005 @PathParam("containerComponentId") final String containerComponentId,
1006 @PathParam("componentInstanceUniqueId") final String componentInstanceUniqueId,
1007 @PathParam("capabilityType") final String capabilityType,
1008 @PathParam("capabilityName") final String capabilityName,
1009 @PathParam("ownerId") final String ownerId,
1010 @Parameter(description = "Instance capabilty property to update", required = true) String data,
1011 @Context final HttpServletRequest request,
1012 @HeaderParam(value = Constants.USER_ID_HEADER) String userId) {
1013 String url = request.getMethod() + " " + request.getRequestURI();
1014 log.debug("(PUT) Start handle request of {}", url);
1015 loggerSupportability.log(LoggerSupportabilityActions.UPDATE_INSTANCE_CAPABILITY_PROPERTY, StatusCode.STARTED,
1016 " Starting to update Instance Capability Property for component instance {} ", componentInstanceUniqueId + " by " + userId);
1018 Wrapper<ResponseFormat> errorWrapper = new Wrapper<>();
1019 List<ComponentInstanceProperty> propertiesToUpdate = new ArrayList<>();
1020 if (errorWrapper.isEmpty()) {
1021 Either<List<ComponentInstanceProperty>, ResponseFormat> propertiesToUpdateEither = convertMultipleProperties(data);
1022 if (propertiesToUpdateEither.isRight()) {
1023 errorWrapper.setInnerElement(propertiesToUpdateEither.right().value());
1025 propertiesToUpdate = propertiesToUpdateEither.left().value();
1028 if (!errorWrapper.isEmpty()) {
1029 return buildErrorResponse(errorWrapper.getInnerElement());
1031 ComponentTypeEnum componentTypeEnum = ComponentTypeEnum.findByParamName(containerComponentType);
1032 Either<List<ComponentInstanceProperty>, ResponseFormat> updateCICapProperty = componentInstanceBusinessLogic
1033 .updateInstanceCapabilityProperties(componentTypeEnum, containerComponentId, componentInstanceUniqueId, capabilityType,
1034 capabilityName, propertiesToUpdate, userId);
1035 if (updateCICapProperty.isRight()) {
1036 log.debug(FAILED_TO_GET_PROPERTIES_OF_COMPONENT_INSTANCE_ID_IN_WITH_ID, componentInstanceUniqueId, containerComponentType,
1037 containerComponentId);
1038 return buildErrorResponse(updateCICapProperty.right().value());
1040 loggerSupportability.log(LoggerSupportabilityActions.UPDATE_INSTANCE_CAPABILITY_PROPERTY, StatusCode.COMPLETE,
1041 " Ended to update Instance Capability Property for component instance {} ", componentInstanceUniqueId + " by " + userId);
1042 return buildOkResponse(getComponentsUtils().getResponseFormat(ActionStatus.OK), updateCICapProperty.left().value());
1043 } catch (Exception e) {
1044 BeEcompErrorManager.getInstance().logBeRestApiGeneralError(GET_GROUP_ARTIFACT_BY_ID);
1045 log.debug(GET_GROUP_ARTIFACT_BY_ID_UNEXPECTED_EXCEPTION, e);
1051 @Path("/{containerComponentType}/{containerComponentId}/componentInstances/{componentInstanceUniqueId}/requirement/{capabilityType}/requirementName/{requirementName}")
1052 @Consumes(MediaType.APPLICATION_JSON)
1053 @Produces(MediaType.APPLICATION_JSON)
1054 @Operation(description = "Update Instance Requirement", method = "PUT", summary = "Returns updated requirement", responses = {
1055 @ApiResponse(content = @Content(array = @ArraySchema(schema = @Schema(implementation = Response.class)))),
1056 @ApiResponse(responseCode = "200", description = "Resource instance requirement updated"),
1057 @ApiResponse(responseCode = "403", description = "Restricted operation"),
1058 @ApiResponse(responseCode = "400", description = "Invalid content / Missing content"),
1059 @ApiResponse(responseCode = "404", description = "Component/Component Instance/Requirement - not found")})
1060 public Response updateInstanceRequirement(@PathParam("containerComponentType") final String containerComponentType,
1061 @PathParam("containerComponentId") final String containerComponentId,
1062 @PathParam("componentInstanceUniqueId") final String componentInstanceUniqueId,
1063 @PathParam("capabilityType") final String capabilityType,
1064 @PathParam("requirementName") final String requirementName,
1065 @Parameter(description = "Instance capabilty requirement to update", required = true) String data,
1066 @Context final HttpServletRequest request,
1067 @HeaderParam(value = Constants.USER_ID_HEADER) String userId) {
1068 String url = request.getMethod() + " " + request.getRequestURI();
1069 log.debug(START_HANDLE_REQUEST_OF, url);
1070 loggerSupportability.log(LoggerSupportabilityActions.UPDATE_INSTANCE_REQUIREMENT, StatusCode.STARTED,
1071 "Starting to update requirement {} in component instance {} by {}", requirementName, componentInstanceUniqueId, userId);
1073 log.debug(START_HANDLE_REQUEST_OF, url);
1074 ComponentTypeEnum componentTypeEnum = ComponentTypeEnum.findByParamName(containerComponentType);
1075 if (componentTypeEnum == null) {
1076 log.debug(UNSUPPORTED_COMPONENT_TYPE, containerComponentType);
1077 return buildErrorResponse(getComponentsUtils().getResponseFormat(ActionStatus.UNSUPPORTED_ERROR, containerComponentType));
1079 Either<RequirementDefinition, ResponseFormat> mappedRequirementDataEither = getMappedRequirementData(data, new User(userId),
1081 if (mappedRequirementDataEither.isRight()) {
1082 log.debug("Failed to update requirements");
1083 return buildErrorResponse(mappedRequirementDataEither.right().value());
1085 RequirementDefinition requirementDef = mappedRequirementDataEither.left().value();
1086 Either<RequirementDefinition, ResponseFormat> response = componentInstanceBusinessLogic
1087 .updateInstanceRequirement(componentTypeEnum, containerComponentId, componentInstanceUniqueId, requirementDef, userId);
1088 if (response.isRight()) {
1089 return buildErrorResponse(response.right().value());
1091 return buildOkResponse(getComponentsUtils().getResponseFormat(ActionStatus.OK), response.left().value());
1092 } catch (ComponentException e) {
1094 } catch (Exception e) {
1095 BeEcompErrorManager.getInstance().logBeRestApiGeneralError("Update component instance requirement");
1096 log.debug("Update component instance requirement with exception", e);
1097 return buildErrorResponse(getComponentsUtils().getResponseFormat(ActionStatus.GENERAL_ERROR));
1101 private Either<RequirementDefinition, ResponseFormat> getMappedRequirementData(String inputJson, User user, ComponentTypeEnum componentTypeEnum) {
1102 return getComponentsUtils()
1103 .convertJsonToObjectUsingObjectMapper(inputJson, user, RequirementDefinition.class, AuditingActionEnum.GET_TOSCA_MODEL,
1108 @Path("/{containerComponentType}/{containerComponentId}/serviceProxy")
1109 @Consumes(MediaType.APPLICATION_JSON)
1110 @Produces(MediaType.APPLICATION_JSON)
1111 @Operation(description = "Create service proxy", method = "POST", summary = "Returns created service proxy", responses = {
1112 @ApiResponse(content = @Content(array = @ArraySchema(schema = @Schema(implementation = Response.class)))),
1113 @ApiResponse(responseCode = "201", description = "Service proxy created"),
1114 @ApiResponse(responseCode = "403", description = "Restricted operation"),
1115 @ApiResponse(responseCode = "400", description = "Invalid content / Missing content"),
1116 @ApiResponse(responseCode = "409", description = "Service proxy already exist")})
1117 public Response createServiceProxy(@Parameter(description = "RI object to be created", required = true) String data,
1118 @PathParam("containerComponentId") final String containerComponentId,
1119 @Parameter(description = "valid values: resources / services", schema = @Schema(allowableValues = {
1120 ComponentTypeEnum.RESOURCE_PARAM_NAME,
1121 ComponentTypeEnum.SERVICE_PARAM_NAME})) @PathParam("containerComponentType") final String containerComponentType,
1122 @HeaderParam(value = Constants.USER_ID_HEADER) @Parameter(description = "USER_ID of modifier user", required = true) String userId,
1123 @Context final HttpServletRequest request) {
1125 ComponentInstance componentInstance = RepresentationUtils.fromRepresentation(data, ComponentInstance.class);
1126 componentInstance.setInvariantName(null);
1127 ComponentTypeEnum componentTypeEnum = ComponentTypeEnum.findByParamName(containerComponentType);
1128 if (componentTypeEnum != ComponentTypeEnum.SERVICE) {
1129 log.debug("Unsupported container component type {}", containerComponentType);
1130 return buildErrorResponse(getComponentsUtils().getResponseFormat(ActionStatus.UNSUPPORTED_ERROR, containerComponentType));
1132 if (componentInstanceBusinessLogic == null) {
1133 log.debug(UNSUPPORTED_COMPONENT_TYPE, containerComponentType);
1134 return buildErrorResponse(getComponentsUtils().getResponseFormat(ActionStatus.UNSUPPORTED_ERROR, containerComponentType));
1136 Either<ComponentInstance, ResponseFormat> actionResponse = componentInstanceBusinessLogic.createServiceProxy();
1137 if (actionResponse.isRight()) {
1138 return buildErrorResponse(actionResponse.right().value());
1140 return buildOkResponse(getComponentsUtils().getResponseFormat(ActionStatus.CREATED), actionResponse.left().value());
1141 } catch (Exception e) {
1142 BeEcompErrorManager.getInstance().logBeRestApiGeneralError("Create service proxy");
1143 log.debug("Create service proxy failed with exception", e);
1149 @Path("/{containerComponentType}/{containerComponentId}/serviceProxy/{serviceProxyId}")
1150 @Consumes(MediaType.APPLICATION_JSON)
1151 @Produces(MediaType.APPLICATION_JSON)
1152 @Operation(description = "Delete service proxy", method = "DELETE", summary = "Returns delete service proxy", responses = {
1153 @ApiResponse(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 public Response deleteServiceProxy(@PathParam("containerComponentId") final String containerComponentId,
1158 @PathParam("serviceProxyId") final String serviceProxyId,
1159 @Parameter(description = "valid values: resources / services / products", schema = @Schema(allowableValues = {
1160 ComponentTypeEnum.RESOURCE_PARAM_NAME,
1161 ComponentTypeEnum.SERVICE_PARAM_NAME})) @PathParam("containerComponentType") final String containerComponentType,
1162 @Context final HttpServletRequest request) {
1163 String url = request.getMethod() + " " + request.getRequestURI();
1165 log.debug(START_HANDLE_REQUEST_OF, url);
1166 if (componentInstanceBusinessLogic == null) {
1167 log.debug(UNSUPPORTED_COMPONENT_TYPE, containerComponentType);
1168 return buildErrorResponse(getComponentsUtils().getResponseFormat(ActionStatus.UNSUPPORTED_ERROR, containerComponentType));
1170 Either<ComponentInstance, ResponseFormat> actionResponse = componentInstanceBusinessLogic.deleteServiceProxy();
1171 if (actionResponse.isRight()) {
1172 return buildErrorResponse(actionResponse.right().value());
1174 return buildOkResponse(getComponentsUtils().getResponseFormat(ActionStatus.NO_CONTENT), null);
1176 } catch (Exception e) {
1177 BeEcompErrorManager.getInstance().logBeRestApiGeneralError("Delete service proxy");
1178 log.debug("Delete service proxy failed with exception", e);
1184 @Path("/{containerComponentType}/{containerComponentId}/serviceProxy/{serviceProxyId}/changeVersion/{newServiceId}")
1185 @Consumes(MediaType.APPLICATION_JSON)
1186 @Produces(MediaType.APPLICATION_JSON)
1187 @Operation(description = "Update service proxy with new version", method = "POST", summary = "Returns updated service proxy", responses = {
1188 @ApiResponse(content = @Content(array = @ArraySchema(schema = @Schema(implementation = Response.class)))),
1189 @ApiResponse(responseCode = "201", description = "Service proxy created"),
1190 @ApiResponse(responseCode = "403", description = "Restricted operation"),
1191 @ApiResponse(responseCode = "400", description = "Invalid content / Missing content")})
1192 public Response changeServiceProxyVersion(@PathParam("containerComponentId") final String containerComponentId,
1193 @PathParam("serviceProxyId") final String serviceProxyId,
1194 @Parameter(description = "valid values: resources / services", schema = @Schema(allowableValues = {
1195 ComponentTypeEnum.RESOURCE_PARAM_NAME,
1196 ComponentTypeEnum.SERVICE_PARAM_NAME})) @PathParam("containerComponentType") final String containerComponentType,
1197 @Context final HttpServletRequest request) {
1198 String url = request.getMethod() + " " + request.getRequestURI();
1199 log.debug(START_HANDLE_REQUEST_OF, url);
1201 if (componentInstanceBusinessLogic == null) {
1202 log.debug(UNSUPPORTED_COMPONENT_TYPE, containerComponentType);
1203 return buildErrorResponse(getComponentsUtils().getResponseFormat(ActionStatus.UNSUPPORTED_ERROR, containerComponentType));
1205 Either<ComponentInstance, ResponseFormat> actionResponse = componentInstanceBusinessLogic.changeServiceProxyVersion();
1206 if (actionResponse.isRight()) {
1207 return buildErrorResponse(actionResponse.right().value());
1209 return buildOkResponse(getComponentsUtils().getResponseFormat(ActionStatus.OK), actionResponse.left().value());
1210 } catch (Exception e) {
1211 BeEcompErrorManager.getInstance().logBeRestApiGeneralError("Update service proxy with new version");
1212 log.debug("Update service proxy with new version failed with exception", e);
1218 * REST API GET relation by Id Allows to get relation contained in specified component according to received Id
1220 * @param containerComponentType
1221 * @param componentId
1228 @Path("/{containerComponentType}/{componentId}/relationId/{relationId}")
1229 @Consumes(MediaType.APPLICATION_JSON)
1230 @Produces(MediaType.APPLICATION_JSON)
1231 @Operation(description = "Get relation", method = "GET", summary = "Returns relation metadata according to relationId", responses = {
1232 @ApiResponse(content = @Content(array = @ArraySchema(schema = @Schema(implementation = Response.class)))),
1233 @ApiResponse(responseCode = "200", description = "relation found"), @ApiResponse(responseCode = "403", description = "Restricted operation"),
1234 @ApiResponse(responseCode = "404", description = "Relation not found")})
1235 public Response getRelationById(@PathParam("containerComponentType") final String containerComponentType,
1236 @PathParam("componentId") final String componentId, @PathParam("relationId") final String relationId,
1237 @Context final HttpServletRequest request, @HeaderParam(value = Constants.USER_ID_HEADER) String userId) {
1238 String url = request.getMethod() + " " + request.getRequestURI();
1239 log.debug(GET_START_HANDLE_REQUEST_OF, url);
1241 ComponentTypeEnum componentTypeEnum = ComponentTypeEnum.findByParamName(containerComponentType);
1242 if (componentTypeEnum == null) {
1243 log.debug(UNSUPPORTED_COMPONENT_TYPE, containerComponentType);
1244 return buildErrorResponse(getComponentsUtils().getResponseFormat(ActionStatus.UNSUPPORTED_ERROR, containerComponentType));
1246 Either<RequirementCapabilityRelDef, ResponseFormat> actionResponse = componentInstanceBusinessLogic
1247 .getRelationById(componentId, relationId, userId, componentTypeEnum);
1248 if (actionResponse.isRight()) {
1249 return buildErrorResponse(actionResponse.right().value());
1251 return buildOkResponse(getComponentsUtils().getResponseFormat(ActionStatus.OK), actionResponse.left().value());
1252 } catch (Exception e) {
1253 BeEcompErrorManager.getInstance().logBeRestApiGeneralError("getRelationById");
1254 log.debug("getRelationById unexpected exception", e);
1259 private Either<ComponentInstance, ResponseFormat> convertToResourceInstance(String data) {
1260 Either<ComponentInstance, ResponseFormat> convertStatus = getComponentsUtils()
1261 .convertJsonToObjectUsingObjectMapper(data, new User(), ComponentInstance.class, null, ComponentTypeEnum.RESOURCE_INSTANCE);
1262 if (convertStatus.isRight()) {
1263 return Either.right(convertStatus.right().value());
1265 ComponentInstance resourceInstanceInfo = convertStatus.left().value();
1266 return Either.left(resourceInstanceInfo);
1269 private Either<List<ComponentInstance>, ResponseFormat> convertToMultipleResourceInstance(String dataList) {
1270 Either<ComponentInstance[], ResponseFormat> convertStatus = getComponentsUtils()
1271 .convertJsonToObjectUsingObjectMapper(dataList, new User(), ComponentInstance[].class, null, ComponentTypeEnum.RESOURCE_INSTANCE);
1272 if (convertStatus.isRight()) {
1273 return Either.right(convertStatus.right().value());
1275 return Either.left(Arrays.asList(convertStatus.left().value()));
1278 private Either<List<ComponentInstanceProperty>, ResponseFormat> convertMultipleProperties(String dataList) {
1279 if (StringUtils.isEmpty(dataList)) {
1280 return Either.right(getComponentsUtils().getResponseFormat(ActionStatus.MISSING_BODY));
1282 Either<ComponentInstanceProperty[], ResponseFormat> convertStatus = getComponentsUtils()
1283 .convertJsonToObjectUsingObjectMapper(dataList, new User(), ComponentInstanceProperty[].class, null, ComponentTypeEnum.RESOURCE_INSTANCE);
1284 if (convertStatus.isRight()) {
1285 return Either.right(convertStatus.right().value());
1287 return Either.left(Arrays.asList(convertStatus.left().value()));
1290 private Either<List<ComponentInstanceAttribute>, ResponseFormat> convertMultipleAttributes(final String dataList) {
1291 if (StringUtils.isEmpty(dataList)) {
1292 return Either.right(getComponentsUtils().getResponseFormat(ActionStatus.MISSING_BODY));
1294 final Either<ComponentInstanceAttribute[], ResponseFormat> convertStatus = getComponentsUtils().
1295 convertJsonToObjectUsingObjectMapper(dataList, new User(), ComponentInstanceAttribute[].class, null, ComponentTypeEnum.RESOURCE_INSTANCE);
1296 if (convertStatus.isRight()) {
1297 return Either.right(convertStatus.right().value());
1299 return Either.left(Arrays.asList(convertStatus.left().value()));
1302 private Either<List<ComponentInstanceInput>, ResponseFormat> convertMultipleInputs(String dataList) {
1303 if (StringUtils.isEmpty(dataList)) {
1304 return Either.right(getComponentsUtils().getResponseFormat(ActionStatus.MISSING_BODY));
1306 Either<ComponentInstanceInput[], ResponseFormat> convertStatus = getComponentsUtils()
1307 .convertJsonToObjectUsingObjectMapper(dataList, new User(), ComponentInstanceInput[].class, null, ComponentTypeEnum.RESOURCE_INSTANCE);
1308 if (convertStatus.isRight()) {
1309 return Either.right(convertStatus.right().value());
1311 return Either.left(Arrays.asList(convertStatus.left().value()));
1314 private RequirementCapabilityRelDef convertToRequirementCapabilityRelDef(String data) {
1315 Either<RequirementCapabilityRelDef, ActionStatus> convertStatus = convertJsonToObject(data, RequirementCapabilityRelDef.class);
1316 if (convertStatus.isRight()) {
1317 throw new ByActionStatusComponentException(convertStatus.right().value());
1319 return convertStatus.left().value();
1323 public <T> Either<T, ActionStatus> convertJsonToObject(String data, Class<T> clazz) {
1325 log.trace("convert json to object. json=\n {}", data);
1327 t = gsonDeserializer.fromJson(data, clazz);
1329 BeEcompErrorManager.getInstance().logBeInvalidJsonInput("convertJsonToObject");
1330 log.debug("object is null after converting from json");
1331 return Either.right(ActionStatus.INVALID_CONTENT);
1333 return Either.left(t);
1334 } catch (Exception e) {
1336 BeEcompErrorManager.getInstance().logBeInvalidJsonInput("convertJsonToObject");
1337 log.debug("failed to convert from json", e);
1338 return Either.right(ActionStatus.INVALID_CONTENT);
1343 @Path("/{containerComponentType}/{componentId}/paths-to-delete")
1344 @Produces(MediaType.APPLICATION_JSON)
1345 @Operation(description = "Check if forwarding path to delete on version change", method = "GET", summary = "Returns forwarding paths to delete", responses = {
1346 @ApiResponse(content = @Content(array = @ArraySchema(schema = @Schema(implementation = Response.class))))})
1347 public Response changeResourceInstanceVersion(@PathParam("componentId") String componentId,
1348 @QueryParam("componentInstanceId") final String oldComponentInstanceId,
1349 @QueryParam("newComponentInstanceId") final String newComponentInstanceId,
1350 @Parameter(description = "valid values: resources / services", schema = @Schema(allowableValues = {
1351 ComponentTypeEnum.RESOURCE_PARAM_NAME,
1352 ComponentTypeEnum.SERVICE_PARAM_NAME})) @PathParam("containerComponentType") final String containerComponentType,
1353 @Context final HttpServletRequest request) {
1354 if (oldComponentInstanceId == null) {
1355 return buildErrorResponse(getComponentsUtils().getResponseFormat(ActionStatus.MISSING_OLD_COMPONENT_INSTANCE));
1357 if (newComponentInstanceId == null) {
1358 return buildErrorResponse(getComponentsUtils().getResponseFormat(ActionStatus.MISSING_NEW_COMPONENT_INSTANCE));
1360 String url = request.getMethod() + " " + request.getRequestURI();
1361 log.debug(START_HANDLE_REQUEST_OF, url);
1362 if (componentInstanceBusinessLogic == null) {
1363 log.debug(UNSUPPORTED_COMPONENT_TYPE, containerComponentType);
1364 return buildErrorResponse(getComponentsUtils().getResponseFormat(ActionStatus.UNSUPPORTED_ERROR, containerComponentType));
1366 ComponentInstance newComponentInstance;
1367 if (StringUtils.isNotEmpty(newComponentInstanceId)) {
1368 newComponentInstance = new ComponentInstance();
1369 newComponentInstance.setToscaPresentationValue(JsonPresentationFields.CI_COMPONENT_UID, newComponentInstanceId);
1371 log.error("missing component id");
1372 return buildErrorResponse(getComponentsUtils().getResponseFormat(ActionStatus.MISSING_DATA));
1374 Either<Set<String>, ResponseFormat> actionResponse = componentInstanceBusinessLogic
1375 .forwardingPathOnVersionChange(containerComponentType, componentId, oldComponentInstanceId, newComponentInstance);
1376 if (actionResponse.isRight()) {
1377 return buildErrorResponse(actionResponse.right().value());
1379 ForwardingPaths forwardingPaths = new ForwardingPaths();
1380 forwardingPaths.setForwardingPathToDelete(actionResponse.left().value());
1381 return buildOkResponse(getComponentsUtils().getResponseFormat(ActionStatus.OK), forwardingPaths);
1385 @Path("/services/{componentId}/copyComponentInstance/{componentInstanceId}")
1386 @Consumes(MediaType.APPLICATION_JSON)
1387 @Produces((MediaType.APPLICATION_JSON))
1388 @Operation(description = "Copy Component Instance", method = "POST", summary = "Returns updated service information", responses = {
1389 @ApiResponse(content = @Content(array = @ArraySchema(schema = @Schema(implementation = Service.class)))),
1390 @ApiResponse(responseCode = "201", description = "Copy and Paste Success"),
1391 @ApiResponse(responseCode = "403", description = "Restricted Operation"),
1392 @ApiResponse(responseCode = "400", description = "Invalid Content / Missing content")})
1393 public Response copyComponentInstance(
1394 @Parameter(description = "service unique id in pasted canvas") @PathParam("componentId") final String containerComponentId,
1395 @Parameter(description = "Data for copying", required = true) String data, @PathParam("componentInstanceId") final String componentInstanceId,
1396 @Context final HttpServletRequest request) {
1397 log.info("Start to copy component instance");
1398 String userId = request.getHeader(Constants.USER_ID_HEADER);
1399 final String CNTAINER_CMPT_TYPE = SERVICES;
1401 ComponentInstance inputComponentInstance = RepresentationUtils.fromRepresentation(data, ComponentInstance.class);
1402 inputComponentInstance.setInvariantName(null);
1403 ComponentTypeEnum componentTypeEnum = ComponentTypeEnum.findByParamName(CNTAINER_CMPT_TYPE);
1404 if (componentInstanceBusinessLogic == null) {
1405 log.debug(UNSUPPORTED_COMPONENT_TYPE, componentTypeEnum);
1406 return buildErrorResponse(getComponentsUtils().getResponseFormat(ActionStatus.UNSUPPORTED_ERROR, SERVICES));
1408 Either<Map<String, ComponentInstance>, ResponseFormat> copyComponentInstance = componentInstanceBusinessLogic
1409 .copyComponentInstance(inputComponentInstance, containerComponentId, componentInstanceId, userId);
1410 if (copyComponentInstance.isRight()) {
1411 log.error("Failed to copy ComponentInstance {}", copyComponentInstance.right().value());
1412 return buildErrorResponse(copyComponentInstance.right().value());
1414 return buildOkResponse(getComponentsUtils().getResponseFormat(ActionStatus.OK), copyComponentInstance.left().value());
1415 } catch (Exception e) {
1416 log.error("Failed to convert json to Map { }", data, e);
1417 return buildErrorResponse(
1418 getComponentsUtils().getResponseFormat(ActionStatus.USER_DEFINED, "Failed to get the copied component instance information"));
1423 @Path("/{containerComponentType}/{componentId}/batchDeleteResourceInstances/")
1424 @Consumes(MediaType.APPLICATION_JSON)
1425 @Produces(MediaType.APPLICATION_JSON)
1426 @Operation(description = "Batch Delete ResourceInstances", method = "POST", responses = {
1427 @ApiResponse(responseCode = "203", description = "ResourceInstances deleted"),
1428 @ApiResponse(responseCode = "403", description = "Restricted Operation"),
1429 @ApiResponse(responseCode = "400", description = "Invalid Content / Missing Content")})
1430 public Response batchDeleteResourceInstances(
1431 @Parameter(description = "valid values: resources / services / products", schema = @Schema(allowableValues = {
1432 ComponentTypeEnum.RESOURCE_PARAM_NAME, ComponentTypeEnum.SERVICE_PARAM_NAME,
1433 ComponentTypeEnum.PRODUCT_PARAM_NAME})) @PathParam("containerComponentType") final String containerComponentType,
1434 @PathParam("componentId") final String componentId, @Context final HttpServletRequest request,
1435 @Parameter(description = "Component Instance Id List", required = true) final String componentInstanceIdLisStr) {
1437 if (componentInstanceIdLisStr == null || componentInstanceIdLisStr.isEmpty()) {
1438 log.error("Empty JSON List was sent", componentInstanceIdLisStr);
1439 return buildErrorResponse(getComponentsUtils().getResponseFormat(ActionStatus.INVALID_CONTENT));
1441 if (componentInstanceBusinessLogic == null) {
1442 log.error(UNSUPPORTED_COMPONENT_TYPE, containerComponentType);
1443 return buildErrorResponse(getComponentsUtils().getResponseFormat(ActionStatus.UNSUPPORTED_ERROR, containerComponentType));
1445 Either<List<String>, ResponseFormat> convertResponse = convertToStringList(componentInstanceIdLisStr);
1446 if (convertResponse.isRight()) {
1447 BeEcompErrorManager.getInstance().logBeSystemError("Resource Instance - batchDeleteResourceInstances");
1448 log.error(FAILED_TO_CONVERT_RECEIVED_DATA_TO_BE_FORMAT);
1449 return buildErrorResponse(convertResponse.right().value());
1451 String userId = request.getHeader(Constants.USER_ID_HEADER);
1452 List<String> componentInstanceIdList = convertResponse.left().value();
1453 log.debug("batchDeleteResourceInstances componentInstanceIdList is {}", componentInstanceIdList);
1454 Map<String, List<String>> deleteErrorMap = componentInstanceBusinessLogic
1455 .batchDeleteComponentInstance(containerComponentType, componentId, componentInstanceIdList, userId);
1456 return buildOkResponse(getComponentsUtils().getResponseFormat(ActionStatus.OK), deleteErrorMap);
1457 } catch (Exception e) {
1458 BeEcompErrorManager.getInstance().logBeRestApiGeneralError("Batch Delete ResourceInstances");
1459 log.error("batch delete resource instances with exception", e);
1460 return buildErrorResponse(getComponentsUtils().getResponseFormat(ActionStatus.GENERAL_ERROR));
1465 @Path("/{containerComponentType}/{componentId}/resourceInstance/batchDissociate")
1466 @Consumes(MediaType.APPLICATION_JSON)
1467 @Produces(MediaType.APPLICATION_JSON)
1468 @Operation(description = "Batch Dissociate RI from RI", method = "PUT", summary = "Returns deleted RelationShip Info", responses = {
1469 @ApiResponse(content = @Content(array = @ArraySchema(schema = @Schema(implementation = Response.class)))),
1470 @ApiResponse(responseCode = "201", description = "Relationship deleted"),
1471 @ApiResponse(responseCode = "403", description = "Missing Information"),
1472 @ApiResponse(responseCode = "400", description = "Invalid Content / Missing Content")})
1473 public Response batchDissociateRIFromRI(
1474 @Parameter(description = "allowed values are resources/services/products", schema = @Schema(allowableValues = {
1475 ComponentTypeEnum.RESOURCE_PARAM_NAME, ComponentTypeEnum.SERVICE_PARAM_NAME,
1476 ComponentTypeEnum.PRODUCT_PARAM_NAME}), required = true) @PathParam("containerComponentType") final String containerComponentType,
1477 @Parameter(description = "unique id of the container component") @PathParam("componentId") final String componentId,
1478 @HeaderParam(value = Constants.USER_ID_HEADER) String userId, @Parameter(description = "RelationshipInfo", required = true) String data,
1479 @Context final HttpServletRequest request) {
1481 if (data == null || data.length() == 0) {
1482 log.info("Empty JSON list was sent");
1483 return buildErrorResponse(getComponentsUtils().getResponseFormat(ActionStatus.INVALID_CONTENT));
1485 ComponentTypeEnum componentTypeEnum = ComponentTypeEnum.findByParamName(containerComponentType);
1486 if (componentInstanceBusinessLogic == null) {
1487 log.debug(UNSUPPORTED_COMPONENT_TYPE, containerComponentType);
1488 return buildErrorResponse(getComponentsUtils().getResponseFormat(ActionStatus.UNSUPPORTED_ERROR, containerComponentType));
1490 Either<List<RequirementCapabilityRelDef>, ResponseFormat> regInfoWs = convertToRequirementCapabilityRelDefList(data);
1491 if (regInfoWs.isRight()) {
1492 BeEcompErrorManager.getInstance().logBeSystemError("Resource Instance - batch dissociateRIFromRI");
1493 log.debug("Failed to convert received data to BE format");
1494 return buildErrorResponse(regInfoWs.right().value());
1496 List<RequirementCapabilityRelDef> requirementDefList = regInfoWs.left().value();
1497 List<RequirementCapabilityRelDef> delOkResult = componentInstanceBusinessLogic
1498 .batchDissociateRIFromRI(componentId, userId, requirementDefList, componentTypeEnum);
1499 return buildOkResponse(getComponentsUtils().getResponseFormat(ActionStatus.OK), delOkResult);
1500 } catch (Exception e) {
1501 BeEcompErrorManager.getInstance().logBeRestApiGeneralError("Batch Dissociate Resource Instance");
1502 log.debug("batch dissociate resource instance from service failed with exception", e);
1503 return buildErrorResponse(getComponentsUtils().getResponseFormat(ActionStatus.GENERAL_ERROR));
1507 private Either<List<String>, ResponseFormat> convertToStringList(String datalist) {
1508 Either<String[], ResponseFormat> convertStatus = getComponentsUtils()
1509 .convertJsonToObjectUsingObjectMapper(datalist, new User(), String[].class, null, null);
1510 if (convertStatus.isRight()) {
1511 return Either.right(convertStatus.right().value());
1513 return Either.left(Arrays.asList(convertStatus.left().value()));
1516 private Either<List<RequirementCapabilityRelDef>, ResponseFormat> convertToRequirementCapabilityRelDefList(String data) {
1517 Either<RequirementCapabilityRelDef[], ResponseFormat> convertStatus = getComponentsUtils()
1518 .convertJsonToObjectUsingObjectMapper(data, new User(), RequirementCapabilityRelDef[].class, null, null);
1519 if (convertStatus.isRight()) {
1520 return Either.right(convertStatus.right().value());
1522 return Either.left(Arrays.asList(convertStatus.left().value()));
1526 @Path("/services/replaceVNF")
1527 @Operation(description = "Replace new VNF based on the existing VNF", method = "POST", summary = "Return whether the replace VNF is successful", responses = {
1528 @ApiResponse(responseCode = "200", description = "ECOMP component is authenticated and list of Catalog Assets Metadata is returned", content = @Content(array = @ArraySchema(schema = @Schema(implementation = ReplaceVNFInfo.class)))),
1529 @ApiResponse(responseCode = "400", description = "Missing 'X-ECOMP-InstanceID' HTTP header - POL5001"),
1530 @ApiResponse(responseCode = "401", description = "ECOMP component should authenticate itself and to re-send again HTTP request with its Basic Authentication credentials - POL5002"),
1531 @ApiResponse(responseCode = "403", description = "ECOMP component is not authorized - POL5003"),
1532 @ApiResponse(responseCode = "404", description = "Error: Requested '%1' (uuid) resource was not found - SVC4063"),
1533 @ApiResponse(responseCode = "405", description = "Method Not Allowed : Invalid HTTP method type used ( PUT,DELETE,POST will be rejected) - POL4050"),
1534 @ApiResponse(responseCode = "500", description = "The GET request failed either due to internal SDC problem. ECOMP Component should continue the attempts to get the needed information - POL5000"),
1535 @ApiResponse(responseCode = "409", description = "Service already exist")})
1536 public Response replaceVNF(@Parameter(description = "The user id", required = true) @HeaderParam(value = Constants.USER_ID_HEADER) String userId,
1537 @Parameter(description = "X-ECOMP-RequestID header", required = false) @HeaderParam(value = Constants.X_ECOMP_REQUEST_ID_HEADER) String requestId,
1538 @Parameter(description = "X-ECOMP-InstanceID header", required = true) @HeaderParam(value = Constants.X_ECOMP_INSTANCE_ID_HEADER) final String instanceIdHeader,
1539 @Parameter(description = "Determines the format of the body of the response", required = false) @HeaderParam(value = Constants.ACCEPT_HEADER) String accept,
1540 @Parameter(description = "The username and password", required = true) @HeaderParam(value = Constants.AUTHORIZATION_HEADER) String authorization,
1541 @Context final HttpServletRequest request,
1542 @Parameter(description = "Resource object to be created", required = true) String data) {
1543 String url = request.getMethod() + " " + request.getRequestURI();
1544 log.debug("replaceVNF: Start handle request of {}", url);
1545 User modifier = new User();
1546 modifier.setUserId(userId);
1547 log.debug("replaceVNF:modifier id is {}", userId);
1548 validateNotEmptyBody(data);
1549 Either<ReplaceVNFInfo, ResponseFormat> convertResponse = parseToReplaceVNFInfo(data, modifier);
1550 if (convertResponse.isRight()) {
1551 throw new ByResponseFormatComponentException(convertResponse.right().value());
1553 log.debug("replaceVNF:get ReplaceVNFInfo success");
1554 String containerComponentType = SERVICES;
1555 ReplaceVNFInfo replaceVNFInfo = convertResponse.left().value();
1556 String serviceUniqueId = replaceVNFInfo.getServiceUniqueId();
1557 String abstractResourceUniqueId = replaceVNFInfo.getAbstractResourceUniqueId();
1558 ComponentInstance componentInstance = replaceVNFInfo.getRealVNFComponentInstance();
1559 log.debug("replaceVNF:get ReplaceVNFInfo,serviceUniqueId:{},abstractResourceUniqueId:{}", serviceUniqueId, abstractResourceUniqueId);
1564 if (componentInstanceBusinessLogic == null) {
1565 log.debug("replaceVNF:Unsupported component type {}", containerComponentType);
1566 return buildErrorResponse(getComponentsUtils().getResponseFormat(ActionStatus.UNSUPPORTED_ERROR, containerComponentType));
1568 Either<ComponentInstance, ResponseFormat> componentInstanceEither = componentInstanceBusinessLogic
1569 .deleteAbstractComponentInstance(containerComponentType, serviceUniqueId, abstractResourceUniqueId, userId);
1570 if (componentInstanceEither.isRight()) {
1571 log.debug("replaceVNF:delete Abstract ComponentInstance field");
1572 return buildErrorResponse(componentInstanceEither.right().value());
1577 log.debug("replaceVNF,start add vnf");
1578 componentInstance.setInvariantName(null);
1579 componentInstance.setCreatedFrom(CreatedFrom.UI);
1580 Either<ComponentInstance, ResponseFormat> realComponentInstance = componentInstanceBusinessLogic
1581 .createRealComponentInstance(containerComponentType, serviceUniqueId, userId, componentInstance);
1582 if (realComponentInstance.isRight()) {
1583 log.debug("replaceVNF:filed to add vnf");
1584 return buildErrorResponse(realComponentInstance.right().value());
1586 ComponentInstance newComponentInstance = realComponentInstance.left().value();
1587 log.debug("replaceVNF:success to add vnf");
1588 return buildOkResponse(getComponentsUtils().getResponseFormat(ActionStatus.OK), newComponentInstance);
1589 } catch (Exception e) {
1590 BeEcompErrorManager.getInstance().logBeRestApiGeneralError("replaceVNF");
1591 log.debug("replaceVNF with exception", e);
1596 private Either<ReplaceVNFInfo, ResponseFormat> parseToReplaceVNFInfo(String serviceJson, User user) {
1597 log.debug("enter parseToReplaceVNFInfo,get serviceJson:{}", serviceJson);
1598 return getComponentsUtils().convertJsonToObjectUsingObjectMapper(serviceJson, user, ReplaceVNFInfo.class, AuditingActionEnum.CREATE_RESOURCE,
1599 ComponentTypeEnum.SERVICE);