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.aaf.AafPermission;
73 import org.openecomp.sdc.be.components.impl.aaf.PermissionAllowed;
74 import org.openecomp.sdc.be.components.impl.exceptions.BusinessLogicException;
75 import org.openecomp.sdc.be.components.impl.exceptions.ByActionStatusComponentException;
76 import org.openecomp.sdc.be.components.impl.exceptions.ByResponseFormatComponentException;
77 import org.openecomp.sdc.be.components.impl.exceptions.ComponentException;
78 import org.openecomp.sdc.be.config.BeEcompErrorManager;
79 import org.openecomp.sdc.be.dao.api.ActionStatus;
80 import org.openecomp.sdc.be.datamodel.ForwardingPaths;
81 import org.openecomp.sdc.be.datatypes.elements.CINodeFilterDataDefinition;
82 import org.openecomp.sdc.be.datatypes.elements.GetInputValueDataDefinition;
83 import org.openecomp.sdc.be.datatypes.elements.ToscaGetFunctionDataDefinition;
84 import org.openecomp.sdc.be.datatypes.enums.ComponentTypeEnum;
85 import org.openecomp.sdc.be.datatypes.enums.CreatedFrom;
86 import org.openecomp.sdc.be.datatypes.enums.JsonPresentationFields;
87 import org.openecomp.sdc.be.datatypes.enums.PropertySource;
88 import org.openecomp.sdc.be.datatypes.tosca.ToscaGetFunctionType;
89 import org.openecomp.sdc.be.externalapi.servlet.representation.ReplaceVNFInfo;
90 import org.openecomp.sdc.be.impl.ComponentsUtils;
91 import org.openecomp.sdc.be.impl.ServletUtils;
92 import org.openecomp.sdc.be.info.CreateAndAssotiateInfo;
93 import org.openecomp.sdc.be.info.GroupDefinitionInfo;
94 import org.openecomp.sdc.be.model.ComponentInstance;
95 import org.openecomp.sdc.be.model.ComponentInstanceAttribute;
96 import org.openecomp.sdc.be.model.ComponentInstanceInput;
97 import org.openecomp.sdc.be.model.ComponentInstanceProperty;
98 import org.openecomp.sdc.be.model.PropertyConstraint;
99 import org.openecomp.sdc.be.model.RequirementCapabilityRelDef;
100 import org.openecomp.sdc.be.model.RequirementDefinition;
101 import org.openecomp.sdc.be.model.Service;
102 import org.openecomp.sdc.be.model.User;
103 import org.openecomp.sdc.be.model.operations.api.StorageOperationStatus;
104 import org.openecomp.sdc.be.model.operations.impl.PropertyOperation.PropertyConstraintDeserialiser;
105 import org.openecomp.sdc.be.resources.data.ComponentMetadataData;
106 import org.openecomp.sdc.be.resources.data.auditing.AuditingActionEnum;
107 import org.openecomp.sdc.common.api.Constants;
108 import org.openecomp.sdc.common.datastructure.Wrapper;
109 import org.openecomp.sdc.common.log.elements.LoggerSupportability;
110 import org.openecomp.sdc.common.log.enums.LoggerSupportabilityActions;
111 import org.openecomp.sdc.common.log.enums.StatusCode;
112 import org.openecomp.sdc.common.log.wrappers.Logger;
113 import org.openecomp.sdc.exception.ResponseFormat;
114 import org.springframework.stereotype.Controller;
117 * Root resource (exposed at "/" path) .json.
119 @Loggable(prepend = true, value = Loggable.DEBUG, trim = false)
121 @Tag(name = "SDCE-2 APIs")
122 @Server(url = "/sdc2/rest")
124 public class ComponentInstanceServlet extends AbstractValidationsServlet {
126 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: {}";
127 private static final String GET_GROUP_ARTIFACT_BY_ID = "getGroupArtifactById";
128 private static final String GET_GROUP_ARTIFACT_BY_ID_UNEXPECTED_EXCEPTION = "getGroupArtifactById unexpected exception";
129 private static final String GET_START_HANDLE_REQUEST_OF = "(GET) Start handle request of {}";
130 private static final String START_HANDLE_REQUEST_OF_UPDATE_RESOURCE_INSTANCE_PROPERTY_RECEIVED_PROPERTY_IS = "Start handle request of updateResourceInstanceProperty. Received property is {}";
131 private static final String START_HANDLE_REQUEST_OF_UPDATE_RESOURCE_INSTANCE_ATTRIBUTE_RECEIVED_ATTRIBUTE_IS = "Start handle request of updateResourceInstanceAttribute. Received attribute is {}";
132 private static final String UPDATE_RESOURCE_INSTANCE = "Update Resource Instance";
133 private static final String RESOURCE_INSTANCE_UPDATE_RESOURCE_INSTANCE = "Resource Instance - updateResourceInstance";
134 private static final String UPDATE_RESOURCE_INSTANCE_WITH_EXCEPTION = "update resource instance with exception";
135 private static final String FAILED_TO_CONVERT_RECEIVED_DATA_TO_BE_FORMAT = "Failed to convert received data to BE format.";
136 private static final String EMPTY_BODY_WAS_SENT = "Empty body was sent.";
137 private static final String START_HANDLE_REQUEST_OF = "Start handle request of {}";
138 private static final String UNSUPPORTED_COMPONENT_TYPE = "Unsupported component type {}";
139 private static final String CREATE_AND_ASSOCIATE_RI_FAILED_WITH_EXCEPTION = "create and associate RI failed with exception: {}";
140 private static final Logger log = Logger.getLogger(ComponentInstanceServlet.class);
141 private static final Type PROPERTY_CONSTRAINT_TYPE = new TypeToken<PropertyConstraint>() {
143 private static final Gson gsonDeserializer = new GsonBuilder().registerTypeAdapter(PROPERTY_CONSTRAINT_TYPE, new PropertyConstraintDeserialiser())
145 private static final LoggerSupportability loggerSupportability = LoggerSupportability.getLogger(ComponentInstanceServlet.class.getName());
146 private static final String SERVICES = "services";
147 private final GroupBusinessLogic groupBL;
148 private final ComponentNodeFilterBusinessLogic nodeFilterBusinessLogic;
149 private final ComponentBusinessLogicProvider componentBusinessLogicProvider;
152 public ComponentInstanceServlet(GroupBusinessLogic groupBL,
153 ComponentInstanceBusinessLogic componentInstanceBL, ComponentsUtils componentsUtils, ServletUtils servletUtils,
154 ResourceImportManager resourceImportManager, ComponentNodeFilterBusinessLogic nodeFilterBusinessLogic,
155 ComponentBusinessLogicProvider componentBusinessLogicProvider) {
156 super(componentInstanceBL, componentsUtils, servletUtils, resourceImportManager);
157 this.groupBL = groupBL;
158 this.nodeFilterBusinessLogic = nodeFilterBusinessLogic;
159 this.componentBusinessLogicProvider = componentBusinessLogicProvider;
163 @Path("/{containerComponentType}/{componentId}/resourceInstance")
164 @Consumes(MediaType.APPLICATION_JSON)
165 @Produces(MediaType.APPLICATION_JSON)
166 @Operation(description = "Create ComponentInstance", method = "POST", summary = "Returns created ComponentInstance", responses = {
167 @ApiResponse(content = @Content(array = @ArraySchema(schema = @Schema(implementation = Response.class)))),
168 @ApiResponse(responseCode = "201", description = "Component created"),
169 @ApiResponse(responseCode = "403", description = "Restricted operation"),
170 @ApiResponse(responseCode = "400", description = "Invalid content / Missing content"),
171 @ApiResponse(responseCode = "409", description = "Component instance already exist")})
172 @PermissionAllowed(AafPermission.PermNames.INTERNAL_ALL_VALUE)
173 public Response createComponentInstance(@Parameter(description = "RI object to be created", required = true) String data,
174 @PathParam("componentId") final String containerComponentId,
175 @Parameter(description = "valid values: resources / services", schema = @Schema(allowableValues = {
176 ComponentTypeEnum.RESOURCE_PARAM_NAME,
177 ComponentTypeEnum.SERVICE_PARAM_NAME})) @PathParam("containerComponentType") final String containerComponentType,
178 @HeaderParam(value = Constants.USER_ID_HEADER) @Parameter(description = "USER_ID of modifier user", required = true) String userId,
179 @Context final HttpServletRequest request) {
180 validateNotEmptyBody(data);
181 final ComponentInstance componentInstance;
183 componentInstance = RepresentationUtils.fromRepresentation(data, ComponentInstance.class);
184 componentInstance.setInvariantName(null);
185 componentInstance.setCreatedFrom(CreatedFrom.UI);
186 } catch (final Exception e) {
187 BeEcompErrorManager.getInstance().logBeRestApiGeneralError("Create Component Instance");
188 log.debug("create component instance failed with exception", e);
189 return buildErrorResponse(getComponentsUtils().getResponseFormat(ActionStatus.INVALID_CONTENT, containerComponentType));
192 .log(LoggerSupportabilityActions.CREATE_INSTANCE, StatusCode.STARTED, "Starting to create component instance by {}", userId);
193 if (componentInstanceBusinessLogic == null) {
194 log.debug(UNSUPPORTED_COMPONENT_TYPE, containerComponentType);
195 return buildErrorResponse(getComponentsUtils().getResponseFormat(ActionStatus.UNSUPPORTED_ERROR, containerComponentType));
197 final ComponentInstance actionResponse = componentInstanceBusinessLogic
198 .createComponentInstance(containerComponentType, containerComponentId, userId, componentInstance);
199 loggerSupportability.log(LoggerSupportabilityActions.CREATE_INSTANCE, actionResponse.getComponentMetadataForSupportLog(), StatusCode.COMPLETE,
200 "Ending to create component instance by user {}", userId);
201 return buildOkResponse(getComponentsUtils().getResponseFormat(ActionStatus.CREATED), actionResponse);
205 @Path("/{containerComponentType}/{componentId}/resourceInstance/{componentInstanceId}")
206 @Consumes(MediaType.APPLICATION_JSON)
207 @Produces(MediaType.APPLICATION_JSON)
208 @Operation(description = "Update resource instance", method = "POST", summary = "Returns updated resource instance", responses = {
209 @ApiResponse(content = @Content(array = @ArraySchema(schema = @Schema(implementation = Response.class)))),
210 @ApiResponse(responseCode = "200", description = "Resource instance updated"),
211 @ApiResponse(responseCode = "403", description = "Restricted operation"),
212 @ApiResponse(responseCode = "400", description = "Invalid content / Missing content")})
213 @PermissionAllowed(AafPermission.PermNames.INTERNAL_ALL_VALUE)
214 public Response updateComponentInstanceMetadata(@PathParam("componentId") final String componentId,
215 @PathParam("componentInstanceId") final String componentInstanceId,
216 @Parameter(description = "valid values: resources / services / products", schema = @Schema(allowableValues = {
217 ComponentTypeEnum.RESOURCE_PARAM_NAME, ComponentTypeEnum.SERVICE_PARAM_NAME,
218 ComponentTypeEnum.PRODUCT_PARAM_NAME})) @PathParam("containerComponentType") final String containerComponentType,
219 @Context final HttpServletRequest request) throws IOException, BusinessLogicException {
220 final String url = request.getMethod() + " " + request.getRequestURI();
221 log.debug(START_HANDLE_REQUEST_OF, url);
222 loggerSupportability.log(LoggerSupportabilityActions.UPDATE_COMPONENT_INSTANCE, StatusCode.STARTED, "update Component Instance Metadata");
223 final String userId = request.getHeader(Constants.USER_ID_HEADER);
225 if (componentInstanceBusinessLogic == null) {
226 log.debug(UNSUPPORTED_COMPONENT_TYPE, containerComponentType);
227 return buildErrorResponse(getComponentsUtils().getResponseFormat(ActionStatus.UNSUPPORTED_ERROR, containerComponentType));
229 componentInstanceBusinessLogic.validateUser(userId);
230 log.debug(START_HANDLE_REQUEST_OF, url);
231 final byte[] bytes = IOUtils.toByteArray(request.getInputStream());
232 if (bytes == null || bytes.length == 0) {
233 log.info(EMPTY_BODY_WAS_SENT);
234 return buildErrorResponse(getComponentsUtils().getResponseFormat(ActionStatus.INVALID_CONTENT));
236 final String data = new String(bytes);
237 final ComponentTypeEnum componentTypeEnum = ComponentTypeEnum.findByParamName(containerComponentType);
238 final Either<ComponentInstance, ResponseFormat> convertResponse = convertToResourceInstance(data);
239 if (convertResponse.isRight()) {
240 BeEcompErrorManager.getInstance().logBeSystemError(RESOURCE_INSTANCE_UPDATE_RESOURCE_INSTANCE);
241 log.debug(FAILED_TO_CONVERT_RECEIVED_DATA_TO_BE_FORMAT);
242 return buildErrorResponse(convertResponse.right().value());
244 final ComponentInstance componentInstance = convertResponse.left().value();
245 final Either<ComponentInstance, ResponseFormat> actionResponse = componentInstanceBusinessLogic
246 .updateComponentInstanceMetadata(containerComponentType, componentId, componentInstanceId, userId, componentInstance);
248 .log(LoggerSupportabilityActions.UPDATE_COMPONENT_INSTANCE, actionResponse.left().value().getComponentMetadataForSupportLog(),
249 StatusCode.COMPLETE, "update Component Instance Metadata by {}", userId);
250 if (actionResponse.isRight()) {
251 return buildErrorResponse(actionResponse.right().value());
253 final ComponentInstance resultValue = actionResponse.left().value();
254 if (ComponentTypeEnum.SERVICE.equals(componentTypeEnum) || ComponentTypeEnum.RESOURCE.equals(componentTypeEnum)) {
255 if (CollectionUtils.isNotEmpty(componentInstance.getDirectives())) {
256 final Optional<CINodeFilterDataDefinition> nodeFilterDataDefinition = nodeFilterBusinessLogic
257 .createNodeFilterIfNotExist(componentId, componentInstanceId, true, componentTypeEnum);
258 if (!nodeFilterDataDefinition.isPresent()) {
259 BeEcompErrorManager.getInstance().logBeSystemError("Failed to create node filter.");
260 log.error("Failed to create node filter.");
261 return buildErrorResponse(convertResponse.right().value());
263 resultValue.setNodeFilter(nodeFilterDataDefinition.get());
265 final Optional<String> result = nodeFilterBusinessLogic
266 .deleteNodeFilterIfExists(componentId, componentInstanceId, true, componentTypeEnum);
267 if (!result.isPresent()) {
268 BeEcompErrorManager.getInstance().logBeSystemError("Failed to delete node filter.");
269 log.error("Failed to delete node filter.");
270 return buildErrorResponse(convertResponse.right().value());
272 resultValue.setNodeFilter(null);
275 return buildOkResponse(getComponentsUtils().getResponseFormat(ActionStatus.OK), actionResponse.left().value());
276 } catch (final Exception e) {
277 BeEcompErrorManager.getInstance().logBeRestApiGeneralError(UPDATE_RESOURCE_INSTANCE);
278 log.debug(UPDATE_RESOURCE_INSTANCE_WITH_EXCEPTION, e);
284 @Path("/{containerComponentType}/{componentId}/resourceInstance/multipleComponentInstance")
285 @Consumes(MediaType.APPLICATION_JSON)
286 @Produces(MediaType.APPLICATION_JSON)
287 @Operation(description = "Update resource instance multiple component", method = "POST", summary = "Returns updated resource instance", responses = {
288 @ApiResponse(content = @Content(array = @ArraySchema(schema = @Schema(implementation = Response.class)))),
289 @ApiResponse(responseCode = "200", description = "Resource instance updated"),
290 @ApiResponse(responseCode = "403", description = "Restricted operation"),
291 @ApiResponse(responseCode = "400", description = "Invalid content / Missing content")})
292 @PermissionAllowed(AafPermission.PermNames.INTERNAL_ALL_VALUE)
293 public Response updateMultipleComponentInstance(@PathParam("componentId") final String componentId,
294 @Parameter(description = "valid values: resources / services / products", schema = @Schema(allowableValues = {
295 ComponentTypeEnum.RESOURCE_PARAM_NAME, ComponentTypeEnum.SERVICE_PARAM_NAME,
296 ComponentTypeEnum.PRODUCT_PARAM_NAME})) @PathParam("containerComponentType") final String containerComponentType,
297 @Context final HttpServletRequest request,
298 @Parameter(description = "Component Instance JSON Array", required = true) final String componentInstanceJsonArray) {
299 String url = request.getMethod() + " " + request.getRequestURI();
300 log.debug(START_HANDLE_REQUEST_OF, url);
302 log.debug(START_HANDLE_REQUEST_OF, url);
303 if (componentInstanceJsonArray == null || componentInstanceJsonArray.length() == 0) {
304 log.info("Empty JSON list was sent.");
305 return buildErrorResponse(getComponentsUtils().getResponseFormat(ActionStatus.INVALID_CONTENT));
307 String userId = request.getHeader(Constants.USER_ID_HEADER);
308 if (componentInstanceBusinessLogic == null) {
309 log.debug(UNSUPPORTED_COMPONENT_TYPE, containerComponentType);
310 return buildErrorResponse(getComponentsUtils().getResponseFormat(ActionStatus.UNSUPPORTED_ERROR, containerComponentType));
312 Either<List<ComponentInstance>, ResponseFormat> convertResponse = convertToMultipleResourceInstance(componentInstanceJsonArray);
313 if (convertResponse.isRight()) {
314 // Using both ECOMP error methods, show to Sofer
315 BeEcompErrorManager.getInstance().logBeSystemError(RESOURCE_INSTANCE_UPDATE_RESOURCE_INSTANCE);
316 log.debug(FAILED_TO_CONVERT_RECEIVED_DATA_TO_BE_FORMAT);
317 return buildErrorResponse(convertResponse.right().value());
319 List<ComponentInstance> componentInstanceList = convertResponse.left().value();
320 List<ComponentInstance> actionResponse = componentInstanceBusinessLogic
321 .updateComponentInstance(containerComponentType, null, componentId, userId, componentInstanceList, true);
322 return buildOkResponse(getComponentsUtils().getResponseFormat(ActionStatus.OK), actionResponse);
323 } catch (Exception e) {
324 BeEcompErrorManager.getInstance().logBeRestApiGeneralError(UPDATE_RESOURCE_INSTANCE);
325 log.debug(UPDATE_RESOURCE_INSTANCE_WITH_EXCEPTION, e);
331 @Path("/{containerComponentType}/{componentId}/resourceInstance/{resourceInstanceId}")
332 @Consumes(MediaType.APPLICATION_JSON)
333 @Produces(MediaType.APPLICATION_JSON)
334 @Operation(description = "Delete ResourceInstance", method = "DELETE", summary = "Returns delete resourceInstance", responses = {
335 @ApiResponse(content = @Content(array = @ArraySchema(schema = @Schema(implementation = Response.class)))),
336 @ApiResponse(responseCode = "201", description = "ResourceInstance deleted"),
337 @ApiResponse(responseCode = "403", description = "Restricted operation"),
338 @ApiResponse(responseCode = "400", description = "Invalid content / Missing content")})
339 @PermissionAllowed(AafPermission.PermNames.INTERNAL_ALL_VALUE)
340 public Response deleteResourceInstance(@PathParam("componentId") final String componentId,
341 @PathParam("resourceInstanceId") final String resourceInstanceId,
342 @Parameter(description = "valid values: resources / services / products", schema = @Schema(allowableValues = {
343 ComponentTypeEnum.RESOURCE_PARAM_NAME, ComponentTypeEnum.SERVICE_PARAM_NAME,
344 ComponentTypeEnum.PRODUCT_PARAM_NAME})) @PathParam("containerComponentType") final String containerComponentType,
345 @Context final HttpServletRequest request) {
346 String url = request.getMethod() + " " + request.getRequestURI();
348 log.debug(START_HANDLE_REQUEST_OF, url);
349 if (componentInstanceBusinessLogic == null) {
350 log.debug(UNSUPPORTED_COMPONENT_TYPE, containerComponentType);
351 return buildErrorResponse(getComponentsUtils().getResponseFormat(ActionStatus.UNSUPPORTED_ERROR, containerComponentType));
353 String userId = request.getHeader(Constants.USER_ID_HEADER);
354 ComponentInstance actionResponse = componentInstanceBusinessLogic
355 .deleteComponentInstance(containerComponentType, componentId, resourceInstanceId, userId);
357 .log(LoggerSupportabilityActions.DELETE_COMPONENT_INSTANCE, actionResponse.getComponentMetadataForSupportLog(), StatusCode.STARTED,
358 "DELETE_COMPONENT_INSTANCE by user {}", userId);
360 .log(LoggerSupportabilityActions.DELETE_COMPONENT_INSTANCE, actionResponse.getComponentMetadataForSupportLog(), StatusCode.COMPLETE,
361 "DELETE_COMPONENT_INSTANCE by user {}", userId);
362 return buildOkResponse(getComponentsUtils().getResponseFormat(ActionStatus.OK), actionResponse);
363 } catch (Exception e) {
364 BeEcompErrorManager.getInstance().logBeRestApiGeneralError("Delete Resource Instance");
365 log.debug("delete resource instance with exception", e);
366 return buildErrorResponse(getComponentsUtils().getResponseFormat(ActionStatus.GENERAL_ERROR));
370 @Parameter(description = "allowed values are resources /services / products", schema = @Schema(allowableValues = {
371 ComponentTypeEnum.RESOURCE_PARAM_NAME, ComponentTypeEnum.SERVICE_PARAM_NAME, ComponentTypeEnum.PRODUCT_PARAM_NAME}), required = true)
373 @Path("/{containerComponentType}/{componentId}/resourceInstance/associate")
374 @Consumes(MediaType.APPLICATION_JSON)
375 @Produces(MediaType.APPLICATION_JSON)
376 @Operation(description = "Associate RI to RI", method = "POST", summary = "Returns created RelationshipInfo", responses = {
377 @ApiResponse(content = @Content(array = @ArraySchema(schema = @Schema(implementation = Response.class)))),
378 @ApiResponse(responseCode = "201", description = "Relationship created"),
379 @ApiResponse(responseCode = "403", description = "Missing information"),
380 @ApiResponse(responseCode = "400", description = "Invalid content / Missing content"),
381 @ApiResponse(responseCode = "409", description = "Relationship already exist")})
382 @PermissionAllowed(AafPermission.PermNames.INTERNAL_ALL_VALUE)
383 public Response associateRIToRI(
384 @Parameter(description = "unique id of the container component") @PathParam("componentId") final String componentId,
385 @Parameter(description = "allowed values are resources /services / products", schema = @Schema(allowableValues = {
386 ComponentTypeEnum.RESOURCE_PARAM_NAME, ComponentTypeEnum.SERVICE_PARAM_NAME,
387 ComponentTypeEnum.PRODUCT_PARAM_NAME}), required = true) @PathParam("containerComponentType") final String containerComponentType,
388 @HeaderParam(value = Constants.USER_ID_HEADER) String userId, @Parameter(description = "RelationshipInfo", required = true) String data,
389 @Context final HttpServletRequest request) {
390 String url = request.getMethod() + " " + request.getRequestURI();
391 log.debug(START_HANDLE_REQUEST_OF, url);
393 .log(LoggerSupportabilityActions.ASSOCIATE_RI_TO_RI, StatusCode.STARTED, "Starting to associate RI To RI for component {} ",
394 componentId + " by " + userId);
396 log.debug(START_HANDLE_REQUEST_OF, url);
397 ComponentTypeEnum componentTypeEnum = ComponentTypeEnum.findByParamName(containerComponentType);
398 if (componentInstanceBusinessLogic == null) {
399 log.debug(UNSUPPORTED_COMPONENT_TYPE, containerComponentType);
400 return buildErrorResponse(getComponentsUtils().getResponseFormat(ActionStatus.UNSUPPORTED_ERROR, containerComponentType));
402 RequirementCapabilityRelDef requirementDef = convertToRequirementCapabilityRelDef(data);
403 requirementDef.setOriginUI(true);
404 RequirementCapabilityRelDef actionResponse = componentInstanceBusinessLogic
405 .associateRIToRI(componentId, userId, requirementDef, componentTypeEnum);
407 .log(LoggerSupportabilityActions.ASSOCIATE_RI_TO_RI, StatusCode.COMPLETE, "Ended associate RI To RI for component {} ",
408 componentId + " by " + userId);
409 return buildOkResponse(getComponentsUtils().getResponseFormat(ActionStatus.OK), actionResponse);
410 } catch (Exception e) {
411 if (!e.getClass().equals(ComponentException.class)) {
412 BeEcompErrorManager.getInstance().logBeRestApiGeneralError("Associate Resource Instance");
413 log.debug("associate resource instance to another RI with exception", e);
414 return buildErrorResponse(getComponentsUtils().getResponseFormat(ActionStatus.GENERAL_ERROR));
421 @Path("/{containerComponentType}/{componentId}/resourceInstance/dissociate")
422 @Consumes(MediaType.APPLICATION_JSON)
423 @Produces(MediaType.APPLICATION_JSON)
424 @Operation(description = "Dissociate RI from RI", method = "PUT", summary = "Returns deleted RelationshipInfo", responses = {
425 @ApiResponse(content = @Content(array = @ArraySchema(schema = @Schema(implementation = Response.class)))),
426 @ApiResponse(responseCode = "201", description = "Relationship deleted"),
427 @ApiResponse(responseCode = "403", description = "Missing information"),
428 @ApiResponse(responseCode = "400", description = "Invalid content / Missing content")})
429 @PermissionAllowed(AafPermission.PermNames.INTERNAL_ALL_VALUE)
430 public Response dissociateRIFromRI(
431 @Parameter(description = "allowed values are resources /services / products", schema = @Schema(allowableValues = {
432 ComponentTypeEnum.RESOURCE_PARAM_NAME, ComponentTypeEnum.SERVICE_PARAM_NAME,
433 ComponentTypeEnum.PRODUCT_PARAM_NAME}), required = true) @PathParam("containerComponentType") final String containerComponentType,
434 @Parameter(description = "unique id of the container component") @PathParam("componentId") final String componentId,
435 @HeaderParam(value = Constants.USER_ID_HEADER) String userId, @Parameter(description = "RelationshipInfo", required = true) String data,
436 @Context final HttpServletRequest request) {
437 String url = request.getMethod() + " " + request.getRequestURI();
438 log.debug(START_HANDLE_REQUEST_OF, url);
440 .log(LoggerSupportabilityActions.UN_ASSOCIATE_RI_TO_RI, StatusCode.STARTED, "Starting to undo associate RI To RI for component {} ",
441 componentId + " by " + userId);
443 log.debug(START_HANDLE_REQUEST_OF, url);
444 ComponentTypeEnum componentTypeEnum = ComponentTypeEnum.findByParamName(containerComponentType);
445 if (componentInstanceBusinessLogic == null) {
446 log.debug(UNSUPPORTED_COMPONENT_TYPE, containerComponentType);
447 return buildErrorResponse(getComponentsUtils().getResponseFormat(ActionStatus.UNSUPPORTED_ERROR, containerComponentType));
449 RequirementCapabilityRelDef requirementDef = convertToRequirementCapabilityRelDef(data);
450 RequirementCapabilityRelDef actionResponse = componentInstanceBusinessLogic
451 .dissociateRIFromRI(componentId, userId, requirementDef, componentTypeEnum);
453 .log(LoggerSupportabilityActions.UN_ASSOCIATE_RI_TO_RI, StatusCode.COMPLETE, "Ended undo associate RI To RI for component {} ",
454 componentId + " by " + userId);
455 return buildOkResponse(getComponentsUtils().getResponseFormat(ActionStatus.OK), actionResponse);
456 } catch (Exception e) {
457 BeEcompErrorManager.getInstance().logBeRestApiGeneralError("Dissociate Resource Instance");
458 log.debug("dissociate resource instance from service failed with exception", e);
464 @Path("/{containerComponentType}/{componentId}/resourceInstance/createAndAssociate")
465 @Consumes(MediaType.APPLICATION_JSON)
466 @Produces(MediaType.APPLICATION_JSON)
467 @Operation(description = "Create RI and associate RI to RI", method = "POST", summary = "Returns created RI and RelationshipInfo", responses = {
468 @ApiResponse(content = @Content(array = @ArraySchema(schema = @Schema(implementation = Response.class)))),
469 @ApiResponse(responseCode = "201", description = "RI created"), @ApiResponse(responseCode = "403", description = "Restricted operation"),
470 @ApiResponse(responseCode = "400", description = "Invalid content / Missing content"),
471 @ApiResponse(responseCode = "409", description = "Relationship already exist")})
472 @PermissionAllowed(AafPermission.PermNames.INTERNAL_ALL_VALUE)
473 public Response createAndAssociateRIToRI(@PathParam("componentId") final String componentId,
474 @Parameter(description = "valid values: resources / services", schema = @Schema(allowableValues = {
475 ComponentTypeEnum.RESOURCE_PARAM_NAME, ComponentTypeEnum.SERVICE_PARAM_NAME,
476 ComponentTypeEnum.PRODUCT_PARAM_NAME})) @PathParam("containerComponentType") final String containerComponentType,
477 @Context final HttpServletRequest request) throws IOException {
478 String url = request.getMethod() + " " + request.getRequestURI();
479 log.debug(START_HANDLE_REQUEST_OF, url);
481 log.debug(START_HANDLE_REQUEST_OF, url);
482 InputStream inputStream = request.getInputStream();
483 byte[] bytes = IOUtils.toByteArray(inputStream);
484 if (bytes == null || bytes.length == 0) {
485 log.info(EMPTY_BODY_WAS_SENT);
486 return buildErrorResponse(getComponentsUtils().getResponseFormat(ActionStatus.INVALID_CONTENT));
488 String userId = request.getHeader(Constants.USER_ID_HEADER);
489 String data = new String(bytes);
490 if (componentInstanceBusinessLogic == null) {
491 log.debug(UNSUPPORTED_COMPONENT_TYPE, containerComponentType);
492 return buildErrorResponse(getComponentsUtils().getResponseFormat(ActionStatus.UNSUPPORTED_ERROR, containerComponentType));
494 Either<CreateAndAssotiateInfo, ActionStatus> convertStatus = convertJsonToObject(data, CreateAndAssotiateInfo.class);
495 if (convertStatus.isRight()) {
496 BeEcompErrorManager.getInstance().logBeSystemError("Resource Instance - createAndAssociateRIToRI");
497 log.debug(FAILED_TO_CONVERT_RECEIVED_DATA_TO_BE_FORMAT);
498 Either<Object, ResponseFormat> formattedResponse = Either
499 .right(getComponentsUtils().getResponseFormat(convertStatus.right().value()));
500 return buildErrorResponse(formattedResponse.right().value());
502 CreateAndAssotiateInfo createAndAssotiateInfo = convertStatus.left().value();
503 RequirementCapabilityRelDef requirementDef = createAndAssotiateInfo.getAssociate();
504 requirementDef.setOriginUI(true);
505 Either<CreateAndAssotiateInfo, ResponseFormat> actionResponse = componentInstanceBusinessLogic
506 .createAndAssociateRIToRI(containerComponentType, componentId, userId, createAndAssotiateInfo);
507 if (actionResponse.isRight()) {
508 return buildErrorResponse(actionResponse.right().value());
510 return buildOkResponse(getComponentsUtils().getResponseFormat(ActionStatus.CREATED), actionResponse.left().value());
511 } catch (Exception e) {
512 BeEcompErrorManager.getInstance().logBeRestApiGeneralError("Create and Associate Resource Instance");
513 log.debug("create and associate RI failed with exception", e);
519 @Path("/{containerComponentType}/{componentId}/resourceInstance/{componentInstanceId}/properties")
520 @Consumes(MediaType.APPLICATION_JSON)
521 @Produces(MediaType.APPLICATION_JSON)
522 @Operation(description = "Update resource instance property", method = "POST", summary = "Returns updated resource instance property", responses = {
523 @ApiResponse(content = @Content(array = @ArraySchema(schema = @Schema(implementation = Response.class)))),
524 @ApiResponse(responseCode = "201", description = "Resource instance created"),
525 @ApiResponse(responseCode = "403", description = "Restricted operation"),
526 @ApiResponse(responseCode = "400", description = "Invalid content / Missing content")})
527 @PermissionAllowed(AafPermission.PermNames.INTERNAL_ALL_VALUE)
528 public Response updateResourceInstanceProperties(@Parameter(description = "service id") @PathParam("componentId") final String componentId,
529 @Parameter(description = "valid values: resources / services", schema = @Schema(allowableValues = {
530 ComponentTypeEnum.RESOURCE_PARAM_NAME,
531 ComponentTypeEnum.SERVICE_PARAM_NAME})) @PathParam("containerComponentType") final String containerComponentType,
532 @Parameter(description = "resource instance id") @PathParam("componentInstanceId") final String componentInstanceId,
533 @Parameter(description = "id of user initiating the operation") @HeaderParam(value = Constants.USER_ID_HEADER) String userId,
534 @Context final HttpServletRequest request,
535 @Parameter(description = "Component Instance Properties JSON Array", required = true) final String componentInstancePropertiesJsonArray) {
536 String url = request.getMethod() + " " + request.getRequestURI();
537 log.debug(START_HANDLE_REQUEST_OF, url);
538 loggerSupportability.log(LoggerSupportabilityActions.UPDATE_COMPONENT_INSTANCE, StatusCode.STARTED,
539 "Starting to update Resource Instance Properties for component {} ", componentId + " by " + userId);
540 Wrapper<ResponseFormat> errorWrapper = new Wrapper<>();
541 ComponentTypeEnum componentTypeEnum = ComponentTypeEnum.findByParamName(containerComponentType);
542 List<ComponentInstanceProperty> propertiesToUpdate = new ArrayList<>();
543 if (errorWrapper.isEmpty()) {
544 Either<List<ComponentInstanceProperty>, ResponseFormat> propertiesToUpdateEither = convertMultipleProperties(
545 componentInstancePropertiesJsonArray);
546 if (propertiesToUpdateEither.isRight()) {
547 errorWrapper.setInnerElement(propertiesToUpdateEither.right().value());
549 propertiesToUpdate = propertiesToUpdateEither.left().value();
550 handleDeprecatedComponentInstancePropertyStructure(propertiesToUpdate, componentTypeEnum);
553 if (!errorWrapper.isEmpty()) {
554 return buildErrorResponse(errorWrapper.getInnerElement());
556 log.debug(START_HANDLE_REQUEST_OF_UPDATE_RESOURCE_INSTANCE_PROPERTY_RECEIVED_PROPERTY_IS, propertiesToUpdate);
557 if (componentInstanceBusinessLogic == null) {
558 log.debug(UNSUPPORTED_COMPONENT_TYPE, containerComponentType);
559 return buildErrorResponse(getComponentsUtils().getResponseFormat(ActionStatus.UNSUPPORTED_ERROR, containerComponentType));
561 Either<List<ComponentInstanceProperty>, ResponseFormat> actionResponse = componentInstanceBusinessLogic
562 .createOrUpdatePropertiesValues(componentTypeEnum, componentId, componentInstanceId, propertiesToUpdate, userId);
563 if (actionResponse.isRight()) {
564 return buildErrorResponse(actionResponse.right().value());
566 List<ComponentInstanceProperty> resourceInstanceProperties = actionResponse.left().value();
567 ObjectMapper mapper = new ObjectMapper();
569 loggerSupportability.log(LoggerSupportabilityActions.UPDATE_COMPONENT_INSTANCE, StatusCode.COMPLETE,
570 "Ended update Resource Instance Properties for component {} ", componentId + " by " + userId);
572 result = mapper.writeValueAsString(resourceInstanceProperties);
573 } catch (JsonProcessingException e) {
574 log.error(UPDATE_RESOURCE_INSTANCE_WITH_EXCEPTION, e.getMessage(), e);
575 throw new ByActionStatusComponentException(ActionStatus.GENERAL_ERROR);
577 loggerSupportability.log(LoggerSupportabilityActions.UPDATE_COMPONENT_INSTANCE, StatusCode.COMPLETE,
578 "Ended update Resource Instance Properties for component {} ", componentId + " by user " + userId);
579 return buildOkResponse(getComponentsUtils().getResponseFormat(ActionStatus.OK), result);
582 private void handleDeprecatedComponentInstancePropertyStructure(final List<ComponentInstanceProperty> propertiesToUpdate,
583 final ComponentTypeEnum componentTypeEnum) {
584 propertiesToUpdate.stream().forEach(property -> {
585 if (property.getGetInputValues() != null) {
586 property.getGetInputValues().stream()
587 .forEach(getInputValue -> property.setToscaFunction(createToscaFunction(getInputValue, componentTypeEnum)));
592 private ToscaGetFunctionDataDefinition createToscaFunction(final GetInputValueDataDefinition getInput,
593 final ComponentTypeEnum componentTypeEnum) {
594 final String[] inputIdSplit = getInput.getInputId().split("\\.");
596 ToscaGetFunctionDataDefinition toscaFunction = new ToscaGetFunctionDataDefinition();
597 toscaFunction.setFunctionType(ToscaGetFunctionType.GET_INPUT);
598 toscaFunction.setPropertyUniqueId(getInput.getInputId());
599 toscaFunction.setPropertySource(PropertySource.SELF);
600 toscaFunction.setPropertyName(inputIdSplit[1]);
601 toscaFunction.setSourceName(getSourceName(inputIdSplit[0], componentTypeEnum));
602 toscaFunction.setSourceUniqueId(inputIdSplit[0]);
603 toscaFunction.setPropertyPathFromSource(Collections.singletonList(inputIdSplit[1]));
605 return toscaFunction;
608 private String getSourceName(final String componentId, final ComponentTypeEnum componentTypeEnum) {
609 ComponentBusinessLogic compBL = componentBusinessLogicProvider.getInstance(componentTypeEnum);
610 final Either<ComponentMetadataData, StorageOperationStatus> componentEither = compBL.getComponentMetadata(componentId);
611 if (componentEither.isLeft()) {
612 return componentEither.left().value().getMetadataDataDefinition().getName();
618 @Path("/{containerComponentType}/{componentId}/resourceInstance/{componentInstanceId}/inputs")
619 @Consumes(MediaType.APPLICATION_JSON)
620 @Produces(MediaType.APPLICATION_JSON)
621 @Operation(description = "Update resource instance property", method = "POST", summary = "Returns updated resource instance property", responses = {
622 @ApiResponse(content = @Content(array = @ArraySchema(schema = @Schema(implementation = Response.class)))),
623 @ApiResponse(responseCode = "201", description = "Resource instance created"),
624 @ApiResponse(responseCode = "403", description = "Restricted operation"),
625 @ApiResponse(responseCode = "400", description = "Invalid content / Missing content")})
626 @PermissionAllowed(AafPermission.PermNames.INTERNAL_ALL_VALUE)
627 public Response updateResourceInstanceInput(@Parameter(description = "service id") @PathParam("componentId") final String componentId,
628 @Parameter(description = "valid values: resources / services", schema = @Schema(allowableValues = {
629 ComponentTypeEnum.RESOURCE_PARAM_NAME,
630 ComponentTypeEnum.SERVICE_PARAM_NAME})) @PathParam("containerComponentType") final String containerComponentType,
631 @Parameter(description = "resource instance id") @PathParam("componentInstanceId") final String componentInstanceId,
632 @Parameter(description = "id of user initiating the operation") @HeaderParam(value = Constants.USER_ID_HEADER) String userId,
633 @Context final HttpServletRequest request,
634 @Parameter(description = "Component Instance Properties JSON Array", required = true) final String componentInstanceInputsJsonArray) {
635 String url = request.getMethod() + " " + request.getRequestURI();
636 log.debug(START_HANDLE_REQUEST_OF, url);
637 Wrapper<ResponseFormat> errorWrapper = new Wrapper<>();
638 List<ComponentInstanceInput> inputsToUpdate = new ArrayList<>();
639 if (errorWrapper.isEmpty()) {
640 Either<List<ComponentInstanceInput>, ResponseFormat> inputsToUpdateEither = convertMultipleInputs(componentInstanceInputsJsonArray);
641 if (inputsToUpdateEither.isRight()) {
642 errorWrapper.setInnerElement(inputsToUpdateEither.right().value());
644 inputsToUpdate = inputsToUpdateEither.left().value();
647 if (!errorWrapper.isEmpty()) {
648 return buildErrorResponse(errorWrapper.getInnerElement());
650 log.debug(START_HANDLE_REQUEST_OF_UPDATE_RESOURCE_INSTANCE_PROPERTY_RECEIVED_PROPERTY_IS, inputsToUpdate);
651 ComponentTypeEnum componentTypeEnum = ComponentTypeEnum.findByParamName(containerComponentType);
652 if (componentInstanceBusinessLogic == null) {
653 log.debug(UNSUPPORTED_COMPONENT_TYPE, containerComponentType);
654 return buildErrorResponse(getComponentsUtils().getResponseFormat(ActionStatus.UNSUPPORTED_ERROR, containerComponentType));
656 Either<List<ComponentInstanceInput>, ResponseFormat> actionResponse = componentInstanceBusinessLogic
657 .createOrUpdateInstanceInputValues(componentTypeEnum, componentId, componentInstanceId, inputsToUpdate, userId);
658 if (actionResponse.isRight()) {
659 return buildErrorResponse(actionResponse.right().value());
661 List<ComponentInstanceInput> resourceInstanceInput = actionResponse.left().value();
662 ObjectMapper mapper = new ObjectMapper();
663 mapper.configure(SerializationFeature.FAIL_ON_EMPTY_BEANS, false);
666 .log(LoggerSupportabilityActions.UPDATE_PROPERTIES, StatusCode.COMPLETE, "Ending update Resource Instance Input for component {} ",
667 componentId + " by " + userId);
669 result = mapper.writeValueAsString(resourceInstanceInput);
670 } catch (JsonProcessingException e) {
671 log.error(UPDATE_RESOURCE_INSTANCE_WITH_EXCEPTION, e.getMessage(), e);
672 return buildErrorResponse(getComponentsUtils().getResponseFormat(ActionStatus.GENERAL_ERROR));
675 .log(LoggerSupportabilityActions.UPDATE_PROPERTIES, StatusCode.COMPLETE, "Ending update Resource Instance Input for component {} ",
676 componentId + " by user " + userId);
677 return buildOkResponse(getComponentsUtils().getResponseFormat(ActionStatus.OK), result);
681 * Updates ResourceInstance Attribute
684 * @param containerComponentType
685 * @param componentInstanceId
691 @Path("/{containerComponentType}/{componentId}/resourceInstance/{componentInstanceId}/attributes")
692 @Consumes(MediaType.APPLICATION_JSON)
693 @Produces(MediaType.APPLICATION_JSON)
694 @Operation(description = "Update resource instance attribute", method = "POST", summary = "Returns updated resource instance property", responses = {
695 @ApiResponse(content = @Content(array = @ArraySchema(schema = @Schema(implementation = Response.class)))),
696 @ApiResponse(responseCode = "201", description = "Resource instance created"),
697 @ApiResponse(responseCode = "403", description = "Restricted operation"),
698 @ApiResponse(responseCode = "400", description = "Invalid content / Missing content")})
699 @PermissionAllowed(AafPermission.PermNames.INTERNAL_ALL_VALUE)
700 public Response updateResourceInstanceAttribute(@Parameter(description = "service id") @PathParam("componentId") final String componentId,
701 @Parameter(description = "valid values: resources / services", schema = @Schema(allowableValues = {
702 ComponentTypeEnum.RESOURCE_PARAM_NAME,
703 ComponentTypeEnum.SERVICE_PARAM_NAME})) @PathParam("containerComponentType") final String containerComponentType,
704 @Parameter(description = "resource instance id") @PathParam("componentInstanceId") final String componentInstanceId,
705 @Parameter(description = "id of user initiating the operation") @HeaderParam(value = Constants.USER_ID_HEADER) final String userId,
706 @Context final HttpServletRequest request,
707 @Parameter(description = "Component Instance Properties JSON Array", required = true) final String componentInstanceAttributesJsonArray) {
708 final String url = request.getMethod() + " " + request.getRequestURI();
709 log.debug(START_HANDLE_REQUEST_OF, url);
710 loggerSupportability.log(LoggerSupportabilityActions.UPDATE_COMPONENT_INSTANCE, StatusCode.STARTED,
711 "Starting to update Resource Instance Attributes for component {} ", componentId + " by " + userId);
712 final Wrapper<ResponseFormat> errorWrapper = new Wrapper<>();
713 List<ComponentInstanceAttribute> attributesToUpdate = new ArrayList<>();
714 if (errorWrapper.isEmpty()) {
715 final Either<List<ComponentInstanceAttribute>, ResponseFormat> attributesToUpdateEither = convertMultipleAttributes(
716 componentInstanceAttributesJsonArray);
717 if (attributesToUpdateEither.isRight()) {
718 errorWrapper.setInnerElement(attributesToUpdateEither.right().value());
720 attributesToUpdate = attributesToUpdateEither.left().value();
723 if (!errorWrapper.isEmpty()) {
724 return buildErrorResponse(errorWrapper.getInnerElement());
726 log.debug(START_HANDLE_REQUEST_OF_UPDATE_RESOURCE_INSTANCE_ATTRIBUTE_RECEIVED_ATTRIBUTE_IS, attributesToUpdate);
727 final ComponentTypeEnum componentTypeEnum = ComponentTypeEnum.findByParamName(containerComponentType);
728 if (componentInstanceBusinessLogic == null) {
729 log.debug(UNSUPPORTED_COMPONENT_TYPE, containerComponentType);
730 return buildErrorResponse(getComponentsUtils().getResponseFormat(ActionStatus.UNSUPPORTED_ERROR, containerComponentType));
732 final Either<List<ComponentInstanceAttribute>, ResponseFormat> actionResponse = componentInstanceBusinessLogic
733 .createOrUpdateAttributeValues(componentTypeEnum, componentId, componentInstanceId, attributesToUpdate, userId);
734 if (actionResponse.isRight()) {
735 return buildErrorResponse(actionResponse.right().value());
737 final List<ComponentInstanceAttribute> resourceInstanceAttributes = actionResponse.left().value();
738 final ObjectMapper mapper = new ObjectMapper();
740 loggerSupportability.log(LoggerSupportabilityActions.UPDATE_COMPONENT_INSTANCE, StatusCode.COMPLETE,
741 "Ended update Resource Instance Attributes for component {} ", componentId + " by " + userId);
743 result = mapper.writeValueAsString(resourceInstanceAttributes);
744 } catch (JsonProcessingException e) {
745 log.error(UPDATE_RESOURCE_INSTANCE_WITH_EXCEPTION, e.getMessage(), e);
746 throw new ByActionStatusComponentException(ActionStatus.GENERAL_ERROR);
748 loggerSupportability.log(LoggerSupportabilityActions.UPDATE_COMPONENT_INSTANCE, StatusCode.COMPLETE,
749 "Ended update Resource Instance Attributes for component {} ", componentId + " by user " + userId);
750 return buildOkResponse(getComponentsUtils().getResponseFormat(ActionStatus.OK), result);
754 @Path("/{containerComponentType}/{componentId}/resourceInstance/{componentInstanceId}/property/{propertyId}")
755 @Consumes(MediaType.APPLICATION_JSON)
756 @Produces(MediaType.APPLICATION_JSON)
757 @Operation(description = "Update resource instance", method = "DELETE", summary = "Returns deleted resource instance property", responses = {
758 @ApiResponse(content = @Content(array = @ArraySchema(schema = @Schema(implementation = Response.class)))),
759 @ApiResponse(responseCode = "201", description = "Resource instance created"),
760 @ApiResponse(responseCode = "403", description = "Restricted operation"),
761 @ApiResponse(responseCode = "400", description = "Invalid content / Missing content")})
762 @PermissionAllowed(AafPermission.PermNames.INTERNAL_ALL_VALUE)
763 public Response deleteResourceInstanceProperty(@Parameter(description = "service id") @PathParam("componentId") final String componentId,
764 @Parameter(description = "valid values: resources / services", schema = @Schema(allowableValues = {
765 ComponentTypeEnum.RESOURCE_PARAM_NAME,
766 ComponentTypeEnum.SERVICE_PARAM_NAME})) @PathParam("containerComponentType") final String containerComponentType,
767 @Parameter(description = "resource instance id") @PathParam("componentInstanceId") final String componentInstanceId,
768 @Parameter(description = "property id") @PathParam("propertyId") final String propertyId,
769 @Parameter(description = "id of user initiating the operation") @HeaderParam(value = Constants.USER_ID_HEADER) String userId,
770 @Context final HttpServletRequest request) {
772 .log(LoggerSupportabilityActions.UPDATE_PROPERTIES, StatusCode.STARTED, "Starting to delete Resource Instance Property for component {} ",
773 componentId + " by " + userId);
774 String url = request.getMethod() + " " + request.getRequestURI();
775 log.debug(START_HANDLE_REQUEST_OF, url);
777 ComponentTypeEnum componentTypeEnum = ComponentTypeEnum.findByParamName(containerComponentType);
779 .log(LoggerSupportabilityActions.UPDATE_PROPERTIES, StatusCode.COMPLETE, "Ended delete Resource Instance Property for component {} ",
780 componentId + " by " + userId);
781 if (componentInstanceBusinessLogic == null) {
782 log.debug(UNSUPPORTED_COMPONENT_TYPE, containerComponentType);
783 return buildErrorResponse(getComponentsUtils().getResponseFormat(ActionStatus.UNSUPPORTED_ERROR, containerComponentType));
785 Either<ComponentInstanceProperty, ResponseFormat> actionResponse = componentInstanceBusinessLogic
786 .deletePropertyValue(componentTypeEnum, componentId, componentInstanceId, propertyId, userId);
787 if (actionResponse.isRight()) {
788 return buildErrorResponse(actionResponse.right().value());
790 return buildOkResponse(getComponentsUtils().getResponseFormat(ActionStatus.NO_CONTENT), null);
791 } catch (Exception e) {
792 log.error(CREATE_AND_ASSOCIATE_RI_FAILED_WITH_EXCEPTION, e.getMessage(), e);
798 @Path("/{containerComponentType}/{componentId}/resourceInstance/{componentInstanceId}/changeVersion")
799 @Consumes(MediaType.APPLICATION_JSON)
800 @Produces(MediaType.APPLICATION_JSON)
801 @Operation(description = "Update resource instance", method = "POST", summary = "Returns updated resource instance", responses = {
802 @ApiResponse(content = @Content(array = @ArraySchema(schema = @Schema(implementation = Response.class)))),
803 @ApiResponse(responseCode = "201", description = "Resource instance created"),
804 @ApiResponse(responseCode = "403", description = "Restricted operation"),
805 @ApiResponse(responseCode = "400", description = "Invalid content / Missing content")})
806 @PermissionAllowed(AafPermission.PermNames.INTERNAL_ALL_VALUE)
807 public Response changeResourceInstanceVersion(@PathParam("componentId") final String componentId,
808 @PathParam("componentInstanceId") final String componentInstanceId,
809 @Parameter(description = "valid values: resources / services", schema = @Schema(allowableValues = {
810 ComponentTypeEnum.RESOURCE_PARAM_NAME,
811 ComponentTypeEnum.SERVICE_PARAM_NAME})) @PathParam("containerComponentType") final String containerComponentType,
812 @Context final HttpServletRequest request) throws IOException {
813 String url = request.getMethod() + " " + request.getRequestURI();
814 log.debug(START_HANDLE_REQUEST_OF, url);
815 try (InputStream inputStream = request.getInputStream()) {
816 byte[] bytes = IOUtils.toByteArray(inputStream);
817 if (bytes == null || bytes.length == 0) {
818 log.info(EMPTY_BODY_WAS_SENT);
819 return buildErrorResponse(getComponentsUtils().getResponseFormat(ActionStatus.INVALID_CONTENT));
821 String userId = request.getHeader(Constants.USER_ID_HEADER);
822 String data = new String(bytes);
823 if (componentInstanceBusinessLogic == null) {
824 log.debug(UNSUPPORTED_COMPONENT_TYPE, containerComponentType);
825 return buildErrorResponse(getComponentsUtils().getResponseFormat(ActionStatus.UNSUPPORTED_ERROR, containerComponentType));
827 Either<ComponentInstance, ResponseFormat> convertResponse = convertToResourceInstance(data);
828 if (convertResponse.isRight()) {
829 BeEcompErrorManager.getInstance().logBeSystemError(RESOURCE_INSTANCE_UPDATE_RESOURCE_INSTANCE);
830 log.debug(FAILED_TO_CONVERT_RECEIVED_DATA_TO_BE_FORMAT);
831 return buildErrorResponse(convertResponse.right().value());
833 ComponentInstance newResourceInstance = convertResponse.left().value();
834 ComponentInstance actionResponse = componentInstanceBusinessLogic
835 .changeComponentInstanceVersion(containerComponentType, componentId, componentInstanceId, userId, newResourceInstance);
836 return buildOkResponse(getComponentsUtils().getResponseFormat(ActionStatus.OK), actionResponse);
837 } catch (Exception e) {
838 BeEcompErrorManager.getInstance().logBeRestApiGeneralError(UPDATE_RESOURCE_INSTANCE);
839 log.debug(UPDATE_RESOURCE_INSTANCE_WITH_EXCEPTION, e);
845 @Path("/{containerComponentType}/{componentId}/resourceInstance/{componentInstanceId}/groupInstance/{groupInstanceId}/property")
846 @Consumes(MediaType.APPLICATION_JSON)
847 @Produces(MediaType.APPLICATION_JSON)
848 @Operation(description = "Update resource instance property", method = "POST", summary = "Returns updated resource instance property", responses = {
849 @ApiResponse(content = @Content(array = @ArraySchema(schema = @Schema(implementation = Response.class)))),
850 @ApiResponse(responseCode = "201", description = "Resource instance created"),
851 @ApiResponse(responseCode = "403", description = "Restricted operation"),
852 @ApiResponse(responseCode = "400", description = "Invalid content / Missing content")})
853 @PermissionAllowed(AafPermission.PermNames.INTERNAL_ALL_VALUE)
854 public Response updateGroupInstanceProperty(@Parameter(description = "service id") @PathParam("componentId") final String componentId,
855 @Parameter(description = "valid values: resources / services", schema = @Schema(allowableValues = {
856 ComponentTypeEnum.RESOURCE_PARAM_NAME,
857 ComponentTypeEnum.SERVICE_PARAM_NAME})) @PathParam("containerComponentType") final String containerComponentType,
858 @Parameter(description = "resource instance id") @PathParam("componentInstanceId") final String componentInstanceId,
859 @Parameter(description = "group instance id") @PathParam("groupInstanceId") final String groupInstanceId,
860 @Parameter(description = "id of user initiating the operation") @HeaderParam(value = Constants.USER_ID_HEADER) String userId,
861 @Context final HttpServletRequest request) throws IOException {
862 String url = request.getMethod() + " " + request.getRequestURI();
863 log.debug(START_HANDLE_REQUEST_OF, url);
866 .log(LoggerSupportabilityActions.UPDATE_PROPERTIES, StatusCode.STARTED, "Starting update Group Instance Property for component {} ",
867 componentId + " by " + userId);
868 Wrapper<String> dataWrapper = new Wrapper<>();
869 Wrapper<ResponseFormat> errorWrapper = new Wrapper<>();
870 Wrapper<ComponentInstanceProperty> propertyWrapper = new Wrapper<>();
871 validateInputStream(request, dataWrapper, errorWrapper);
872 if (errorWrapper.isEmpty()) {
873 validateClassParse(dataWrapper.getInnerElement(), propertyWrapper, () -> ComponentInstanceProperty.class, errorWrapper);
875 if (!errorWrapper.isEmpty()) {
876 return buildErrorResponse(errorWrapper.getInnerElement());
878 ComponentInstanceProperty property = propertyWrapper.getInnerElement();
879 log.debug(START_HANDLE_REQUEST_OF_UPDATE_RESOURCE_INSTANCE_PROPERTY_RECEIVED_PROPERTY_IS, property);
880 ComponentTypeEnum componentTypeEnum = ComponentTypeEnum.findByParamName(containerComponentType);
881 if (componentInstanceBusinessLogic == null) {
882 log.debug(UNSUPPORTED_COMPONENT_TYPE, containerComponentType);
883 return buildErrorResponse(getComponentsUtils().getResponseFormat(ActionStatus.UNSUPPORTED_ERROR, containerComponentType));
885 Either<ComponentInstanceProperty, ResponseFormat> actionResponse = componentInstanceBusinessLogic
886 .createOrUpdateGroupInstancePropertyValue(componentTypeEnum, componentId, componentInstanceId, groupInstanceId, property, userId);
887 if (actionResponse.isRight()) {
888 return buildErrorResponse(actionResponse.right().value());
890 ComponentInstanceProperty resourceInstanceProperty = actionResponse.left().value();
891 ObjectMapper mapper = new ObjectMapper();
892 String result = mapper.writeValueAsString(resourceInstanceProperty);
894 .log(LoggerSupportabilityActions.UPDATE_PROPERTIES, StatusCode.COMPLETE, "Ended update Group Instance Property for component {} ",
895 componentId + " by " + userId);
896 return buildOkResponse(getComponentsUtils().getResponseFormat(ActionStatus.OK), result);
897 } catch (Exception e) {
898 log.error(CREATE_AND_ASSOCIATE_RI_FAILED_WITH_EXCEPTION, e.getMessage(), e);
904 @Path("/{containerComponentType}/{componentId}/resourceInstance/{componentInstanceId}/groupInstance/{groupInstId}")
905 @Consumes(MediaType.APPLICATION_JSON)
906 @Produces(MediaType.APPLICATION_JSON)
907 @Operation(description = "Get group artifacts ", method = "GET", summary = "Returns artifacts metadata according to groupInstId", responses = {
908 @ApiResponse(content = @Content(array = @ArraySchema(schema = @Schema(implementation = Response.class)))),
909 @ApiResponse(responseCode = "200", description = "group found"), @ApiResponse(responseCode = "403", description = "Restricted operation"),
910 @ApiResponse(responseCode = "404", description = "Group not found")})
911 @PermissionAllowed(AafPermission.PermNames.INTERNAL_ALL_VALUE)
912 public Response getGroupArtifactById(@PathParam("containerComponentType") final String containerComponentType,
913 @PathParam("componentId") final String componentId,
914 @PathParam("componentInstanceId") final String componentInstanceId,
915 @PathParam("groupInstId") final String groupInstId, @Context final HttpServletRequest request,
916 @HeaderParam(value = Constants.USER_ID_HEADER) String userId) {
917 String url = request.getMethod() + " " + request.getRequestURI();
918 log.debug(GET_START_HANDLE_REQUEST_OF, url);
920 ComponentTypeEnum componentTypeEnum = ComponentTypeEnum.findByParamName(containerComponentType);
921 Either<GroupDefinitionInfo, ResponseFormat> actionResponse = groupBL
922 .getGroupInstWithArtifactsById(componentTypeEnum, componentId, componentInstanceId, groupInstId, userId, false);
923 if (actionResponse.isRight()) {
924 log.debug("failed to get all non abstract {}", containerComponentType);
925 return buildErrorResponse(actionResponse.right().value());
927 return buildOkResponse(getComponentsUtils().getResponseFormat(ActionStatus.OK), actionResponse.left().value());
928 } catch (Exception e) {
929 BeEcompErrorManager.getInstance().logBeRestApiGeneralError(GET_GROUP_ARTIFACT_BY_ID);
930 log.debug(GET_GROUP_ARTIFACT_BY_ID_UNEXPECTED_EXCEPTION, e);
937 @Path("/{containerComponentType}/{containerComponentId}/componentInstances/{componentInstanceUniqueId}/properties")
938 @Consumes(MediaType.APPLICATION_JSON)
939 @Produces(MediaType.APPLICATION_JSON)
940 @Operation(description = "Get component instance properties", method = "GET", summary = "Returns component instance properties", responses = {
941 @ApiResponse(content = @Content(array = @ArraySchema(schema = @Schema(implementation = Response.class)))),
942 @ApiResponse(responseCode = "200", description = "Properties found"),
943 @ApiResponse(responseCode = "403", description = "Restricted operation"),
944 @ApiResponse(responseCode = "404", description = "Component/Component Instance - not found")})
945 @PermissionAllowed(AafPermission.PermNames.INTERNAL_ALL_VALUE)
946 public Response getInstancePropertiesById(@PathParam("containerComponentType") final String containerComponentType,
947 @PathParam("containerComponentId") final String containerComponentId,
948 @PathParam("componentInstanceUniqueId") final String componentInstanceUniqueId,
949 @Context final HttpServletRequest request,
950 @HeaderParam(value = Constants.USER_ID_HEADER) String userId) {
951 String url = request.getMethod() + " " + request.getRequestURI();
952 log.debug(GET_START_HANDLE_REQUEST_OF, url);
953 List<ComponentInstanceProperty> componentInstancePropertiesById = componentInstanceBusinessLogic
954 .getComponentInstancePropertiesById(containerComponentType, containerComponentId, componentInstanceUniqueId, userId);
955 return buildOkResponse(getComponentsUtils().getResponseFormat(ActionStatus.OK), componentInstancePropertiesById);
959 @Path("/{containerComponentType}/{containerComponentId}/componentInstances/{componentInstanceUniqueId}/attributes")
960 @Consumes(MediaType.APPLICATION_JSON)
961 @Produces(MediaType.APPLICATION_JSON)
962 @Operation(description = "Get component instance attributes", method = "GET", summary = "Returns component instance attributes", responses = {
963 @ApiResponse(content = @Content(array = @ArraySchema(schema = @Schema(implementation = Response.class)))),
964 @ApiResponse(responseCode = "200", description = "Attributes found"),
965 @ApiResponse(responseCode = "403", description = "Restricted operation"),
966 @ApiResponse(responseCode = "404", description = "Component/Component Instance - not found")})
967 @PermissionAllowed(AafPermission.PermNames.INTERNAL_ALL_VALUE)
968 public Response getInstanceAttributesById(@PathParam("containerComponentType") final String containerComponentType,
969 @PathParam("containerComponentId") final String containerComponentId,
970 @PathParam("componentInstanceUniqueId") final String componentInstanceUniqueId,
971 @Context final HttpServletRequest request,
972 @HeaderParam(value = Constants.USER_ID_HEADER) final String userId) {
973 final String url = request.getMethod() + " " + request.getRequestURI();
974 log.debug(GET_START_HANDLE_REQUEST_OF, url);
975 final List<ComponentInstanceAttribute> componentInstanceAttributesById = componentInstanceBusinessLogic
976 .getComponentInstanceAttributesById(containerComponentType, containerComponentId, componentInstanceUniqueId, userId);
977 return buildOkResponse(getComponentsUtils().getResponseFormat(ActionStatus.OK), componentInstanceAttributesById);
982 @Path("/{containerComponentType}/{containerComponentId}/componentInstances/{componentInstanceUniqueId}/capability/{capabilityType}/capabilityName/{capabilityName}/ownerId/{ownerId}/properties")
983 @Consumes(MediaType.APPLICATION_JSON)
984 @Produces(MediaType.APPLICATION_JSON)
985 @Operation(description = "Get component instance capability properties", method = "GET", summary = "Returns component instance capability properties", responses = {
986 @ApiResponse(content = @Content(array = @ArraySchema(schema = @Schema(implementation = Response.class)))),
987 @ApiResponse(responseCode = "200", description = "Properties found"),
988 @ApiResponse(responseCode = "403", description = "Restricted operation"),
989 @ApiResponse(responseCode = "404", description = "Component/Component Instance/Capability - not found")})
990 @PermissionAllowed(AafPermission.PermNames.INTERNAL_ALL_VALUE)
991 public Response getInstanceCapabilityPropertiesById(@PathParam("containerComponentType") final String containerComponentType,
992 @PathParam("containerComponentId") final String containerComponentId,
993 @PathParam("componentInstanceUniqueId") final String componentInstanceUniqueId,
994 @PathParam("capabilityType") final String capabilityType,
995 @PathParam("capabilityName") final String capabilityName,
996 @PathParam("ownerId") final String ownerId, @Context final HttpServletRequest request,
997 @HeaderParam(value = Constants.USER_ID_HEADER) String userId) {
998 String url = request.getMethod() + " " + request.getRequestURI();
999 log.debug(GET_START_HANDLE_REQUEST_OF, url);
1001 List<ComponentInstanceProperty> componentInstancePropertiesById = componentInstanceBusinessLogic
1002 .getComponentInstanceCapabilityPropertiesById(containerComponentType, containerComponentId, componentInstanceUniqueId, capabilityType,
1003 capabilityName, ownerId, userId);
1004 return buildOkResponse(getComponentsUtils().getResponseFormat(ActionStatus.OK), componentInstancePropertiesById);
1005 } catch (Exception e) {
1006 BeEcompErrorManager.getInstance().logBeRestApiGeneralError(GET_GROUP_ARTIFACT_BY_ID);
1007 log.debug(GET_GROUP_ARTIFACT_BY_ID_UNEXPECTED_EXCEPTION, e);
1014 @Path("/{containerComponentType}/{containerComponentId}/componentInstances/{componentInstanceUniqueId}/capability/{capabilityType}/capabilityName/{capabilityName}/ownerId/{ownerId}/properties")
1015 @Consumes(MediaType.APPLICATION_JSON)
1016 @Produces(MediaType.APPLICATION_JSON)
1017 @Operation(description = "Update Instance Capabilty Property", method = "PUT", summary = "Returns updated property", responses = {
1018 @ApiResponse(content = @Content(array = @ArraySchema(schema = @Schema(implementation = Response.class)))),
1019 @ApiResponse(responseCode = "200", description = "Resource instance capabilty property updated"),
1020 @ApiResponse(responseCode = "403", description = "Restricted operation"),
1021 @ApiResponse(responseCode = "400", description = "Invalid content / Missing content"),
1022 @ApiResponse(responseCode = "404", description = "Component/Component Instance/Capability - not found")})
1023 @PermissionAllowed(AafPermission.PermNames.INTERNAL_ALL_VALUE)
1024 public Response updateInstanceCapabilityProperty(@PathParam("containerComponentType") final String containerComponentType,
1025 @PathParam("containerComponentId") final String containerComponentId,
1026 @PathParam("componentInstanceUniqueId") final String componentInstanceUniqueId,
1027 @PathParam("capabilityType") final String capabilityType,
1028 @PathParam("capabilityName") final String capabilityName,
1029 @PathParam("ownerId") final String ownerId,
1030 @Parameter(description = "Instance capabilty property to update", required = true) String data,
1031 @Context final HttpServletRequest request,
1032 @HeaderParam(value = Constants.USER_ID_HEADER) String userId) {
1033 String url = request.getMethod() + " " + request.getRequestURI();
1034 log.debug("(PUT) Start handle request of {}", url);
1035 loggerSupportability.log(LoggerSupportabilityActions.UPDATE_INSTANCE_CAPABILITY_PROPERTY, StatusCode.STARTED,
1036 " Starting to update Instance Capability Property for component instance {} ", componentInstanceUniqueId + " by " + userId);
1038 Wrapper<ResponseFormat> errorWrapper = new Wrapper<>();
1039 List<ComponentInstanceProperty> propertiesToUpdate = new ArrayList<>();
1040 if (errorWrapper.isEmpty()) {
1041 Either<List<ComponentInstanceProperty>, ResponseFormat> propertiesToUpdateEither = convertMultipleProperties(data);
1042 if (propertiesToUpdateEither.isRight()) {
1043 errorWrapper.setInnerElement(propertiesToUpdateEither.right().value());
1045 propertiesToUpdate = propertiesToUpdateEither.left().value();
1048 if (!errorWrapper.isEmpty()) {
1049 return buildErrorResponse(errorWrapper.getInnerElement());
1051 ComponentTypeEnum componentTypeEnum = ComponentTypeEnum.findByParamName(containerComponentType);
1052 Either<List<ComponentInstanceProperty>, ResponseFormat> updateCICapProperty = componentInstanceBusinessLogic
1053 .updateInstanceCapabilityProperties(componentTypeEnum, containerComponentId, componentInstanceUniqueId, capabilityType,
1054 capabilityName, propertiesToUpdate, userId);
1055 if (updateCICapProperty.isRight()) {
1056 log.debug(FAILED_TO_GET_PROPERTIES_OF_COMPONENT_INSTANCE_ID_IN_WITH_ID, componentInstanceUniqueId, containerComponentType,
1057 containerComponentId);
1058 return buildErrorResponse(updateCICapProperty.right().value());
1060 loggerSupportability.log(LoggerSupportabilityActions.UPDATE_INSTANCE_CAPABILITY_PROPERTY, StatusCode.COMPLETE,
1061 " Ended to update Instance Capability Property for component instance {} ", componentInstanceUniqueId + " by " + userId);
1062 return buildOkResponse(getComponentsUtils().getResponseFormat(ActionStatus.OK), updateCICapProperty.left().value());
1063 } catch (Exception e) {
1064 BeEcompErrorManager.getInstance().logBeRestApiGeneralError(GET_GROUP_ARTIFACT_BY_ID);
1065 log.debug(GET_GROUP_ARTIFACT_BY_ID_UNEXPECTED_EXCEPTION, e);
1071 @Path("/{containerComponentType}/{containerComponentId}/componentInstances/{componentInstanceUniqueId}/requirement/{capabilityType}/requirementName/{requirementName}")
1072 @Consumes(MediaType.APPLICATION_JSON)
1073 @Produces(MediaType.APPLICATION_JSON)
1074 @Operation(description = "Update Instance Requirement", method = "PUT", summary = "Returns updated requirement", responses = {
1075 @ApiResponse(content = @Content(array = @ArraySchema(schema = @Schema(implementation = Response.class)))),
1076 @ApiResponse(responseCode = "200", description = "Resource instance requirement updated"),
1077 @ApiResponse(responseCode = "403", description = "Restricted operation"),
1078 @ApiResponse(responseCode = "400", description = "Invalid content / Missing content"),
1079 @ApiResponse(responseCode = "404", description = "Component/Component Instance/Requirement - not found")})
1080 @PermissionAllowed(AafPermission.PermNames.INTERNAL_ALL_VALUE)
1081 public Response updateInstanceRequirement(@PathParam("containerComponentType") final String containerComponentType,
1082 @PathParam("containerComponentId") final String containerComponentId,
1083 @PathParam("componentInstanceUniqueId") final String componentInstanceUniqueId,
1084 @PathParam("capabilityType") final String capabilityType,
1085 @PathParam("requirementName") final String requirementName,
1086 @Parameter(description = "Instance capabilty requirement to update", required = true) String data,
1087 @Context final HttpServletRequest request,
1088 @HeaderParam(value = Constants.USER_ID_HEADER) String userId) {
1089 String url = request.getMethod() + " " + request.getRequestURI();
1090 log.debug(START_HANDLE_REQUEST_OF, url);
1091 loggerSupportability.log(LoggerSupportabilityActions.UPDATE_INSTANCE_REQUIREMENT, StatusCode.STARTED,
1092 "Starting to update requirement {} in component instance {} by {}", requirementName, componentInstanceUniqueId, userId);
1094 log.debug(START_HANDLE_REQUEST_OF, url);
1095 ComponentTypeEnum componentTypeEnum = ComponentTypeEnum.findByParamName(containerComponentType);
1096 if (componentTypeEnum == null) {
1097 log.debug(UNSUPPORTED_COMPONENT_TYPE, containerComponentType);
1098 return buildErrorResponse(getComponentsUtils().getResponseFormat(ActionStatus.UNSUPPORTED_ERROR, containerComponentType));
1100 Either<RequirementDefinition, ResponseFormat> mappedRequirementDataEither = getMappedRequirementData(data, new User(userId),
1102 if (mappedRequirementDataEither.isRight()) {
1103 log.debug("Failed to update requirements");
1104 return buildErrorResponse(mappedRequirementDataEither.right().value());
1106 RequirementDefinition requirementDef = mappedRequirementDataEither.left().value();
1107 Either<RequirementDefinition, ResponseFormat> response = componentInstanceBusinessLogic
1108 .updateInstanceRequirement(componentTypeEnum, containerComponentId, componentInstanceUniqueId, requirementDef, userId);
1109 if (response.isRight()) {
1110 return buildErrorResponse(response.right().value());
1112 return buildOkResponse(getComponentsUtils().getResponseFormat(ActionStatus.OK), response.left().value());
1113 } catch (ComponentException e) {
1115 } catch (Exception e) {
1116 BeEcompErrorManager.getInstance().logBeRestApiGeneralError("Update component instance requirement");
1117 log.debug("Update component instance requirement with exception", e);
1118 return buildErrorResponse(getComponentsUtils().getResponseFormat(ActionStatus.GENERAL_ERROR));
1122 private Either<RequirementDefinition, ResponseFormat> getMappedRequirementData(String inputJson, User user, ComponentTypeEnum componentTypeEnum) {
1123 return getComponentsUtils()
1124 .convertJsonToObjectUsingObjectMapper(inputJson, user, RequirementDefinition.class, AuditingActionEnum.GET_TOSCA_MODEL,
1129 @Path("/{containerComponentType}/{containerComponentId}/serviceProxy")
1130 @Consumes(MediaType.APPLICATION_JSON)
1131 @Produces(MediaType.APPLICATION_JSON)
1132 @Operation(description = "Create service proxy", method = "POST", summary = "Returns created service proxy", responses = {
1133 @ApiResponse(content = @Content(array = @ArraySchema(schema = @Schema(implementation = Response.class)))),
1134 @ApiResponse(responseCode = "201", description = "Service proxy created"),
1135 @ApiResponse(responseCode = "403", description = "Restricted operation"),
1136 @ApiResponse(responseCode = "400", description = "Invalid content / Missing content"),
1137 @ApiResponse(responseCode = "409", description = "Service proxy already exist")})
1138 @PermissionAllowed(AafPermission.PermNames.INTERNAL_ALL_VALUE)
1139 public Response createServiceProxy(@Parameter(description = "RI object to be created", required = true) String data,
1140 @PathParam("containerComponentId") final String containerComponentId,
1141 @Parameter(description = "valid values: resources / services", schema = @Schema(allowableValues = {
1142 ComponentTypeEnum.RESOURCE_PARAM_NAME,
1143 ComponentTypeEnum.SERVICE_PARAM_NAME})) @PathParam("containerComponentType") final String containerComponentType,
1144 @HeaderParam(value = Constants.USER_ID_HEADER) @Parameter(description = "USER_ID of modifier user", required = true) String userId,
1145 @Context final HttpServletRequest request) {
1147 ComponentInstance componentInstance = RepresentationUtils.fromRepresentation(data, ComponentInstance.class);
1148 componentInstance.setInvariantName(null);
1149 ComponentTypeEnum componentTypeEnum = ComponentTypeEnum.findByParamName(containerComponentType);
1150 if (componentTypeEnum != ComponentTypeEnum.SERVICE) {
1151 log.debug("Unsupported container component type {}", containerComponentType);
1152 return buildErrorResponse(getComponentsUtils().getResponseFormat(ActionStatus.UNSUPPORTED_ERROR, containerComponentType));
1154 if (componentInstanceBusinessLogic == null) {
1155 log.debug(UNSUPPORTED_COMPONENT_TYPE, containerComponentType);
1156 return buildErrorResponse(getComponentsUtils().getResponseFormat(ActionStatus.UNSUPPORTED_ERROR, containerComponentType));
1158 Either<ComponentInstance, ResponseFormat> actionResponse = componentInstanceBusinessLogic.createServiceProxy();
1159 if (actionResponse.isRight()) {
1160 return buildErrorResponse(actionResponse.right().value());
1162 return buildOkResponse(getComponentsUtils().getResponseFormat(ActionStatus.CREATED), actionResponse.left().value());
1163 } catch (Exception e) {
1164 BeEcompErrorManager.getInstance().logBeRestApiGeneralError("Create service proxy");
1165 log.debug("Create service proxy failed with exception", e);
1171 @Path("/{containerComponentType}/{containerComponentId}/serviceProxy/{serviceProxyId}")
1172 @Consumes(MediaType.APPLICATION_JSON)
1173 @Produces(MediaType.APPLICATION_JSON)
1174 @Operation(description = "Delete service proxy", method = "DELETE", summary = "Returns delete service proxy", responses = {
1175 @ApiResponse(content = @Content(array = @ArraySchema(schema = @Schema(implementation = Response.class)))),
1176 @ApiResponse(responseCode = "201", description = "Service proxy deleted"),
1177 @ApiResponse(responseCode = "403", description = "Restricted operation"),
1178 @ApiResponse(responseCode = "400", description = "Invalid content / Missing content")})
1179 @PermissionAllowed(AafPermission.PermNames.INTERNAL_ALL_VALUE)
1180 public Response deleteServiceProxy(@PathParam("containerComponentId") final String containerComponentId,
1181 @PathParam("serviceProxyId") final String serviceProxyId,
1182 @Parameter(description = "valid values: resources / services / products", schema = @Schema(allowableValues = {
1183 ComponentTypeEnum.RESOURCE_PARAM_NAME,
1184 ComponentTypeEnum.SERVICE_PARAM_NAME})) @PathParam("containerComponentType") final String containerComponentType,
1185 @Context final HttpServletRequest request) {
1186 String url = request.getMethod() + " " + request.getRequestURI();
1188 log.debug(START_HANDLE_REQUEST_OF, url);
1189 if (componentInstanceBusinessLogic == null) {
1190 log.debug(UNSUPPORTED_COMPONENT_TYPE, containerComponentType);
1191 return buildErrorResponse(getComponentsUtils().getResponseFormat(ActionStatus.UNSUPPORTED_ERROR, containerComponentType));
1193 Either<ComponentInstance, ResponseFormat> actionResponse = componentInstanceBusinessLogic.deleteServiceProxy();
1194 if (actionResponse.isRight()) {
1195 return buildErrorResponse(actionResponse.right().value());
1197 return buildOkResponse(getComponentsUtils().getResponseFormat(ActionStatus.NO_CONTENT), null);
1199 } catch (Exception e) {
1200 BeEcompErrorManager.getInstance().logBeRestApiGeneralError("Delete service proxy");
1201 log.debug("Delete service proxy failed with exception", e);
1207 @Path("/{containerComponentType}/{containerComponentId}/serviceProxy/{serviceProxyId}/changeVersion/{newServiceId}")
1208 @Consumes(MediaType.APPLICATION_JSON)
1209 @Produces(MediaType.APPLICATION_JSON)
1210 @Operation(description = "Update service proxy with new version", method = "POST", summary = "Returns updated service proxy", responses = {
1211 @ApiResponse(content = @Content(array = @ArraySchema(schema = @Schema(implementation = Response.class)))),
1212 @ApiResponse(responseCode = "201", description = "Service proxy created"),
1213 @ApiResponse(responseCode = "403", description = "Restricted operation"),
1214 @ApiResponse(responseCode = "400", description = "Invalid content / Missing content")})
1215 @PermissionAllowed(AafPermission.PermNames.INTERNAL_ALL_VALUE)
1216 public Response changeServiceProxyVersion(@PathParam("containerComponentId") final String containerComponentId,
1217 @PathParam("serviceProxyId") final String serviceProxyId,
1218 @Parameter(description = "valid values: resources / services", schema = @Schema(allowableValues = {
1219 ComponentTypeEnum.RESOURCE_PARAM_NAME,
1220 ComponentTypeEnum.SERVICE_PARAM_NAME})) @PathParam("containerComponentType") final String containerComponentType,
1221 @Context final HttpServletRequest request) {
1222 String url = request.getMethod() + " " + request.getRequestURI();
1223 log.debug(START_HANDLE_REQUEST_OF, url);
1225 if (componentInstanceBusinessLogic == null) {
1226 log.debug(UNSUPPORTED_COMPONENT_TYPE, containerComponentType);
1227 return buildErrorResponse(getComponentsUtils().getResponseFormat(ActionStatus.UNSUPPORTED_ERROR, containerComponentType));
1229 Either<ComponentInstance, ResponseFormat> actionResponse = componentInstanceBusinessLogic.changeServiceProxyVersion();
1230 if (actionResponse.isRight()) {
1231 return buildErrorResponse(actionResponse.right().value());
1233 return buildOkResponse(getComponentsUtils().getResponseFormat(ActionStatus.OK), actionResponse.left().value());
1234 } catch (Exception e) {
1235 BeEcompErrorManager.getInstance().logBeRestApiGeneralError("Update service proxy with new version");
1236 log.debug("Update service proxy with new version failed with exception", e);
1242 * REST API GET relation by Id Allows to get relation contained in specified component according to received Id
1244 * @param containerComponentType
1245 * @param componentId
1252 @Path("/{containerComponentType}/{componentId}/relationId/{relationId}")
1253 @Consumes(MediaType.APPLICATION_JSON)
1254 @Produces(MediaType.APPLICATION_JSON)
1255 @Operation(description = "Get relation", method = "GET", summary = "Returns relation metadata according to relationId", responses = {
1256 @ApiResponse(content = @Content(array = @ArraySchema(schema = @Schema(implementation = Response.class)))),
1257 @ApiResponse(responseCode = "200", description = "relation found"), @ApiResponse(responseCode = "403", description = "Restricted operation"),
1258 @ApiResponse(responseCode = "404", description = "Relation not found")})
1259 @PermissionAllowed(AafPermission.PermNames.INTERNAL_ALL_VALUE)
1260 public Response getRelationById(@PathParam("containerComponentType") final String containerComponentType,
1261 @PathParam("componentId") final String componentId, @PathParam("relationId") final String relationId,
1262 @Context final HttpServletRequest request, @HeaderParam(value = Constants.USER_ID_HEADER) String userId) {
1263 String url = request.getMethod() + " " + request.getRequestURI();
1264 log.debug(GET_START_HANDLE_REQUEST_OF, url);
1266 ComponentTypeEnum componentTypeEnum = ComponentTypeEnum.findByParamName(containerComponentType);
1267 if (componentTypeEnum == null) {
1268 log.debug(UNSUPPORTED_COMPONENT_TYPE, containerComponentType);
1269 return buildErrorResponse(getComponentsUtils().getResponseFormat(ActionStatus.UNSUPPORTED_ERROR, containerComponentType));
1271 Either<RequirementCapabilityRelDef, ResponseFormat> actionResponse = componentInstanceBusinessLogic
1272 .getRelationById(componentId, relationId, userId, componentTypeEnum);
1273 if (actionResponse.isRight()) {
1274 return buildErrorResponse(actionResponse.right().value());
1276 return buildOkResponse(getComponentsUtils().getResponseFormat(ActionStatus.OK), actionResponse.left().value());
1277 } catch (Exception e) {
1278 BeEcompErrorManager.getInstance().logBeRestApiGeneralError("getRelationById");
1279 log.debug("getRelationById unexpected exception", e);
1284 private Either<ComponentInstance, ResponseFormat> convertToResourceInstance(String data) {
1285 Either<ComponentInstance, ResponseFormat> convertStatus = getComponentsUtils()
1286 .convertJsonToObjectUsingObjectMapper(data, new User(), ComponentInstance.class, null, ComponentTypeEnum.RESOURCE_INSTANCE);
1287 if (convertStatus.isRight()) {
1288 return Either.right(convertStatus.right().value());
1290 ComponentInstance resourceInstanceInfo = convertStatus.left().value();
1291 return Either.left(resourceInstanceInfo);
1294 private Either<List<ComponentInstance>, ResponseFormat> convertToMultipleResourceInstance(String dataList) {
1295 Either<ComponentInstance[], ResponseFormat> convertStatus = getComponentsUtils()
1296 .convertJsonToObjectUsingObjectMapper(dataList, new User(), ComponentInstance[].class, null, ComponentTypeEnum.RESOURCE_INSTANCE);
1297 if (convertStatus.isRight()) {
1298 return Either.right(convertStatus.right().value());
1300 return Either.left(Arrays.asList(convertStatus.left().value()));
1303 private Either<List<ComponentInstanceProperty>, ResponseFormat> convertMultipleProperties(String dataList) {
1304 if (StringUtils.isEmpty(dataList)) {
1305 return Either.right(getComponentsUtils().getResponseFormat(ActionStatus.MISSING_BODY));
1307 Either<ComponentInstanceProperty[], ResponseFormat> convertStatus = getComponentsUtils()
1308 .convertJsonToObjectUsingObjectMapper(dataList, new User(), ComponentInstanceProperty[].class, null, ComponentTypeEnum.RESOURCE_INSTANCE);
1309 if (convertStatus.isRight()) {
1310 return Either.right(convertStatus.right().value());
1312 return Either.left(Arrays.asList(convertStatus.left().value()));
1315 private Either<List<ComponentInstanceAttribute>, ResponseFormat> convertMultipleAttributes(final String dataList) {
1316 if (StringUtils.isEmpty(dataList)) {
1317 return Either.right(getComponentsUtils().getResponseFormat(ActionStatus.MISSING_BODY));
1319 final Either<ComponentInstanceAttribute[], ResponseFormat> convertStatus = getComponentsUtils().
1320 convertJsonToObjectUsingObjectMapper(dataList, new User(), ComponentInstanceAttribute[].class, null, ComponentTypeEnum.RESOURCE_INSTANCE);
1321 if (convertStatus.isRight()) {
1322 return Either.right(convertStatus.right().value());
1324 return Either.left(Arrays.asList(convertStatus.left().value()));
1327 private Either<List<ComponentInstanceInput>, ResponseFormat> convertMultipleInputs(String dataList) {
1328 if (StringUtils.isEmpty(dataList)) {
1329 return Either.right(getComponentsUtils().getResponseFormat(ActionStatus.MISSING_BODY));
1331 Either<ComponentInstanceInput[], ResponseFormat> convertStatus = getComponentsUtils()
1332 .convertJsonToObjectUsingObjectMapper(dataList, new User(), ComponentInstanceInput[].class, null, ComponentTypeEnum.RESOURCE_INSTANCE);
1333 if (convertStatus.isRight()) {
1334 return Either.right(convertStatus.right().value());
1336 return Either.left(Arrays.asList(convertStatus.left().value()));
1339 private RequirementCapabilityRelDef convertToRequirementCapabilityRelDef(String data) {
1340 Either<RequirementCapabilityRelDef, ActionStatus> convertStatus = convertJsonToObject(data, RequirementCapabilityRelDef.class);
1341 if (convertStatus.isRight()) {
1342 throw new ByActionStatusComponentException(convertStatus.right().value());
1344 return convertStatus.left().value();
1348 public <T> Either<T, ActionStatus> convertJsonToObject(String data, Class<T> clazz) {
1350 log.trace("convert json to object. json=\n {}", data);
1352 t = gsonDeserializer.fromJson(data, clazz);
1354 BeEcompErrorManager.getInstance().logBeInvalidJsonInput("convertJsonToObject");
1355 log.debug("object is null after converting from json");
1356 return Either.right(ActionStatus.INVALID_CONTENT);
1358 return Either.left(t);
1359 } catch (Exception e) {
1361 BeEcompErrorManager.getInstance().logBeInvalidJsonInput("convertJsonToObject");
1362 log.debug("failed to convert from json", e);
1363 return Either.right(ActionStatus.INVALID_CONTENT);
1368 @Path("/{containerComponentType}/{componentId}/paths-to-delete")
1369 @Produces(MediaType.APPLICATION_JSON)
1370 @Operation(description = "Check if forwarding path to delete on version change", method = "GET", summary = "Returns forwarding paths to delete", responses = {
1371 @ApiResponse(content = @Content(array = @ArraySchema(schema = @Schema(implementation = Response.class))))})
1372 public Response changeResourceInstanceVersion(@PathParam("componentId") String componentId,
1373 @QueryParam("componentInstanceId") final String oldComponentInstanceId,
1374 @QueryParam("newComponentInstanceId") final String newComponentInstanceId,
1375 @Parameter(description = "valid values: resources / services", schema = @Schema(allowableValues = {
1376 ComponentTypeEnum.RESOURCE_PARAM_NAME,
1377 ComponentTypeEnum.SERVICE_PARAM_NAME})) @PathParam("containerComponentType") final String containerComponentType,
1378 @Context final HttpServletRequest request) {
1379 if (oldComponentInstanceId == null) {
1380 return buildErrorResponse(getComponentsUtils().getResponseFormat(ActionStatus.MISSING_OLD_COMPONENT_INSTANCE));
1382 if (newComponentInstanceId == null) {
1383 return buildErrorResponse(getComponentsUtils().getResponseFormat(ActionStatus.MISSING_NEW_COMPONENT_INSTANCE));
1385 String url = request.getMethod() + " " + request.getRequestURI();
1386 log.debug(START_HANDLE_REQUEST_OF, url);
1387 if (componentInstanceBusinessLogic == null) {
1388 log.debug(UNSUPPORTED_COMPONENT_TYPE, containerComponentType);
1389 return buildErrorResponse(getComponentsUtils().getResponseFormat(ActionStatus.UNSUPPORTED_ERROR, containerComponentType));
1391 ComponentInstance newComponentInstance;
1392 if (StringUtils.isNotEmpty(newComponentInstanceId)) {
1393 newComponentInstance = new ComponentInstance();
1394 newComponentInstance.setToscaPresentationValue(JsonPresentationFields.CI_COMPONENT_UID, newComponentInstanceId);
1396 log.error("missing component id");
1397 return buildErrorResponse(getComponentsUtils().getResponseFormat(ActionStatus.MISSING_DATA));
1399 Either<Set<String>, ResponseFormat> actionResponse = componentInstanceBusinessLogic
1400 .forwardingPathOnVersionChange(containerComponentType, componentId, oldComponentInstanceId, newComponentInstance);
1401 if (actionResponse.isRight()) {
1402 return buildErrorResponse(actionResponse.right().value());
1404 ForwardingPaths forwardingPaths = new ForwardingPaths();
1405 forwardingPaths.setForwardingPathToDelete(actionResponse.left().value());
1406 return buildOkResponse(getComponentsUtils().getResponseFormat(ActionStatus.OK), forwardingPaths);
1410 @Path("/services/{componentId}/copyComponentInstance/{componentInstanceId}")
1411 @Consumes(MediaType.APPLICATION_JSON)
1412 @Produces((MediaType.APPLICATION_JSON))
1413 @Operation(description = "Copy Component Instance", method = "POST", summary = "Returns updated service information", responses = {
1414 @ApiResponse(content = @Content(array = @ArraySchema(schema = @Schema(implementation = Service.class)))),
1415 @ApiResponse(responseCode = "201", description = "Copy and Paste Success"),
1416 @ApiResponse(responseCode = "403", description = "Restricted Operation"),
1417 @ApiResponse(responseCode = "400", description = "Invalid Content / Missing content")})
1418 public Response copyComponentInstance(
1419 @Parameter(description = "service unique id in pasted canvas") @PathParam("componentId") final String containerComponentId,
1420 @Parameter(description = "Data for copying", required = true) String data, @PathParam("componentInstanceId") final String componentInstanceId,
1421 @Context final HttpServletRequest request) {
1422 log.info("Start to copy component instance");
1423 String userId = request.getHeader(Constants.USER_ID_HEADER);
1424 final String CNTAINER_CMPT_TYPE = SERVICES;
1426 ComponentInstance inputComponentInstance = RepresentationUtils.fromRepresentation(data, ComponentInstance.class);
1427 inputComponentInstance.setInvariantName(null);
1428 ComponentTypeEnum componentTypeEnum = ComponentTypeEnum.findByParamName(CNTAINER_CMPT_TYPE);
1429 if (componentInstanceBusinessLogic == null) {
1430 log.debug(UNSUPPORTED_COMPONENT_TYPE, componentTypeEnum);
1431 return buildErrorResponse(getComponentsUtils().getResponseFormat(ActionStatus.UNSUPPORTED_ERROR, SERVICES));
1433 Either<Map<String, ComponentInstance>, ResponseFormat> copyComponentInstance = componentInstanceBusinessLogic
1434 .copyComponentInstance(inputComponentInstance, containerComponentId, componentInstanceId, userId);
1435 if (copyComponentInstance.isRight()) {
1436 log.error("Failed to copy ComponentInstance {}", copyComponentInstance.right().value());
1437 return buildErrorResponse(copyComponentInstance.right().value());
1439 return buildOkResponse(getComponentsUtils().getResponseFormat(ActionStatus.OK), copyComponentInstance.left().value());
1440 } catch (Exception e) {
1441 log.error("Failed to convert json to Map { }", data, e);
1442 return buildErrorResponse(
1443 getComponentsUtils().getResponseFormat(ActionStatus.USER_DEFINED, "Failed to get the copied component instance information"));
1448 @Path("/{containerComponentType}/{componentId}/batchDeleteResourceInstances/")
1449 @Consumes(MediaType.APPLICATION_JSON)
1450 @Produces(MediaType.APPLICATION_JSON)
1451 @Operation(description = "Batch Delete ResourceInstances", method = "POST", responses = {
1452 @ApiResponse(responseCode = "203", description = "ResourceInstances deleted"),
1453 @ApiResponse(responseCode = "403", description = "Restricted Operation"),
1454 @ApiResponse(responseCode = "400", description = "Invalid Content / Missing Content")})
1455 public Response batchDeleteResourceInstances(
1456 @Parameter(description = "valid values: resources / services / products", schema = @Schema(allowableValues = {
1457 ComponentTypeEnum.RESOURCE_PARAM_NAME, ComponentTypeEnum.SERVICE_PARAM_NAME,
1458 ComponentTypeEnum.PRODUCT_PARAM_NAME})) @PathParam("containerComponentType") final String containerComponentType,
1459 @PathParam("componentId") final String componentId, @Context final HttpServletRequest request,
1460 @Parameter(description = "Component Instance Id List", required = true) final String componentInstanceIdLisStr) {
1462 if (componentInstanceIdLisStr == null || componentInstanceIdLisStr.isEmpty()) {
1463 log.error("Empty JSON List was sent", componentInstanceIdLisStr);
1464 return buildErrorResponse(getComponentsUtils().getResponseFormat(ActionStatus.INVALID_CONTENT));
1466 if (componentInstanceBusinessLogic == null) {
1467 log.error(UNSUPPORTED_COMPONENT_TYPE, containerComponentType);
1468 return buildErrorResponse(getComponentsUtils().getResponseFormat(ActionStatus.UNSUPPORTED_ERROR, containerComponentType));
1470 Either<List<String>, ResponseFormat> convertResponse = convertToStringList(componentInstanceIdLisStr);
1471 if (convertResponse.isRight()) {
1472 BeEcompErrorManager.getInstance().logBeSystemError("Resource Instance - batchDeleteResourceInstances");
1473 log.error(FAILED_TO_CONVERT_RECEIVED_DATA_TO_BE_FORMAT);
1474 return buildErrorResponse(convertResponse.right().value());
1476 String userId = request.getHeader(Constants.USER_ID_HEADER);
1477 List<String> componentInstanceIdList = convertResponse.left().value();
1478 log.debug("batchDeleteResourceInstances componentInstanceIdList is {}", componentInstanceIdList);
1479 Map<String, List<String>> deleteErrorMap = componentInstanceBusinessLogic
1480 .batchDeleteComponentInstance(containerComponentType, componentId, componentInstanceIdList, userId);
1481 return buildOkResponse(getComponentsUtils().getResponseFormat(ActionStatus.OK), deleteErrorMap);
1482 } catch (Exception e) {
1483 BeEcompErrorManager.getInstance().logBeRestApiGeneralError("Batch Delete ResourceInstances");
1484 log.error("batch delete resource instances with exception", e);
1485 return buildErrorResponse(getComponentsUtils().getResponseFormat(ActionStatus.GENERAL_ERROR));
1490 @Path("/{containerComponentType}/{componentId}/resourceInstance/batchDissociate")
1491 @Consumes(MediaType.APPLICATION_JSON)
1492 @Produces(MediaType.APPLICATION_JSON)
1493 @Operation(description = "Batch Dissociate RI from RI", method = "PUT", summary = "Returns deleted RelationShip Info", responses = {
1494 @ApiResponse(content = @Content(array = @ArraySchema(schema = @Schema(implementation = Response.class)))),
1495 @ApiResponse(responseCode = "201", description = "Relationship deleted"),
1496 @ApiResponse(responseCode = "403", description = "Missing Information"),
1497 @ApiResponse(responseCode = "400", description = "Invalid Content / Missing Content")})
1498 public Response batchDissociateRIFromRI(
1499 @Parameter(description = "allowed values are resources/services/products", schema = @Schema(allowableValues = {
1500 ComponentTypeEnum.RESOURCE_PARAM_NAME, ComponentTypeEnum.SERVICE_PARAM_NAME,
1501 ComponentTypeEnum.PRODUCT_PARAM_NAME}), required = true) @PathParam("containerComponentType") final String containerComponentType,
1502 @Parameter(description = "unique id of the container component") @PathParam("componentId") final String componentId,
1503 @HeaderParam(value = Constants.USER_ID_HEADER) String userId, @Parameter(description = "RelationshipInfo", required = true) String data,
1504 @Context final HttpServletRequest request) {
1506 if (data == null || data.length() == 0) {
1507 log.info("Empty JSON list was sent");
1508 return buildErrorResponse(getComponentsUtils().getResponseFormat(ActionStatus.INVALID_CONTENT));
1510 ComponentTypeEnum componentTypeEnum = ComponentTypeEnum.findByParamName(containerComponentType);
1511 if (componentInstanceBusinessLogic == null) {
1512 log.debug(UNSUPPORTED_COMPONENT_TYPE, containerComponentType);
1513 return buildErrorResponse(getComponentsUtils().getResponseFormat(ActionStatus.UNSUPPORTED_ERROR, containerComponentType));
1515 Either<List<RequirementCapabilityRelDef>, ResponseFormat> regInfoWs = convertToRequirementCapabilityRelDefList(data);
1516 if (regInfoWs.isRight()) {
1517 BeEcompErrorManager.getInstance().logBeSystemError("Resource Instance - batch dissociateRIFromRI");
1518 log.debug("Failed to convert received data to BE format");
1519 return buildErrorResponse(regInfoWs.right().value());
1521 List<RequirementCapabilityRelDef> requirementDefList = regInfoWs.left().value();
1522 List<RequirementCapabilityRelDef> delOkResult = componentInstanceBusinessLogic
1523 .batchDissociateRIFromRI(componentId, userId, requirementDefList, componentTypeEnum);
1524 return buildOkResponse(getComponentsUtils().getResponseFormat(ActionStatus.OK), delOkResult);
1525 } catch (Exception e) {
1526 BeEcompErrorManager.getInstance().logBeRestApiGeneralError("Batch Dissociate Resource Instance");
1527 log.debug("batch dissociate resource instance from service failed with exception", e);
1528 return buildErrorResponse(getComponentsUtils().getResponseFormat(ActionStatus.GENERAL_ERROR));
1532 private Either<List<String>, ResponseFormat> convertToStringList(String datalist) {
1533 Either<String[], ResponseFormat> convertStatus = getComponentsUtils()
1534 .convertJsonToObjectUsingObjectMapper(datalist, new User(), String[].class, null, null);
1535 if (convertStatus.isRight()) {
1536 return Either.right(convertStatus.right().value());
1538 return Either.left(Arrays.asList(convertStatus.left().value()));
1541 private Either<List<RequirementCapabilityRelDef>, ResponseFormat> convertToRequirementCapabilityRelDefList(String data) {
1542 Either<RequirementCapabilityRelDef[], ResponseFormat> convertStatus = getComponentsUtils()
1543 .convertJsonToObjectUsingObjectMapper(data, new User(), RequirementCapabilityRelDef[].class, null, null);
1544 if (convertStatus.isRight()) {
1545 return Either.right(convertStatus.right().value());
1547 return Either.left(Arrays.asList(convertStatus.left().value()));
1551 @Path("/services/replaceVNF")
1552 @Operation(description = "Replace new VNF based on the existing VNF", method = "POST", summary = "Return whether the replace VNF is successful", responses = {
1553 @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)))),
1554 @ApiResponse(responseCode = "400", description = "Missing 'X-ECOMP-InstanceID' HTTP header - POL5001"),
1555 @ApiResponse(responseCode = "401", description = "ECOMP component should authenticate itself and to re-send again HTTP request with its Basic Authentication credentials - POL5002"),
1556 @ApiResponse(responseCode = "403", description = "ECOMP component is not authorized - POL5003"),
1557 @ApiResponse(responseCode = "404", description = "Error: Requested '%1' (uuid) resource was not found - SVC4063"),
1558 @ApiResponse(responseCode = "405", description = "Method Not Allowed : Invalid HTTP method type used ( PUT,DELETE,POST will be rejected) - POL4050"),
1559 @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"),
1560 @ApiResponse(responseCode = "409", description = "Service already exist")})
1561 @PermissionAllowed(AafPermission.PermNames.INTERNAL_ALL_VALUE)
1562 public Response replaceVNF(@Parameter(description = "The user id", required = true) @HeaderParam(value = Constants.USER_ID_HEADER) String userId,
1563 @Parameter(description = "X-ECOMP-RequestID header", required = false) @HeaderParam(value = Constants.X_ECOMP_REQUEST_ID_HEADER) String requestId,
1564 @Parameter(description = "X-ECOMP-InstanceID header", required = true) @HeaderParam(value = Constants.X_ECOMP_INSTANCE_ID_HEADER) final String instanceIdHeader,
1565 @Parameter(description = "Determines the format of the body of the response", required = false) @HeaderParam(value = Constants.ACCEPT_HEADER) String accept,
1566 @Parameter(description = "The username and password", required = true) @HeaderParam(value = Constants.AUTHORIZATION_HEADER) String authorization,
1567 @Context final HttpServletRequest request,
1568 @Parameter(description = "Resource object to be created", required = true) String data) {
1569 String url = request.getMethod() + " " + request.getRequestURI();
1570 log.debug("replaceVNF: Start handle request of {}", url);
1571 User modifier = new User();
1572 modifier.setUserId(userId);
1573 log.debug("replaceVNF:modifier id is {}", userId);
1574 validateNotEmptyBody(data);
1575 Either<ReplaceVNFInfo, ResponseFormat> convertResponse = parseToReplaceVNFInfo(data, modifier);
1576 if (convertResponse.isRight()) {
1577 throw new ByResponseFormatComponentException(convertResponse.right().value());
1579 log.debug("replaceVNF:get ReplaceVNFInfo success");
1580 String containerComponentType = SERVICES;
1581 ReplaceVNFInfo replaceVNFInfo = convertResponse.left().value();
1582 String serviceUniqueId = replaceVNFInfo.getServiceUniqueId();
1583 String abstractResourceUniqueId = replaceVNFInfo.getAbstractResourceUniqueId();
1584 ComponentInstance componentInstance = replaceVNFInfo.getRealVNFComponentInstance();
1585 log.debug("replaceVNF:get ReplaceVNFInfo,serviceUniqueId:{},abstractResourceUniqueId:{}", serviceUniqueId, abstractResourceUniqueId);
1590 if (componentInstanceBusinessLogic == null) {
1591 log.debug("replaceVNF:Unsupported component type {}", containerComponentType);
1592 return buildErrorResponse(getComponentsUtils().getResponseFormat(ActionStatus.UNSUPPORTED_ERROR, containerComponentType));
1594 Either<ComponentInstance, ResponseFormat> componentInstanceEither = componentInstanceBusinessLogic
1595 .deleteAbstractComponentInstance(containerComponentType, serviceUniqueId, abstractResourceUniqueId, userId);
1596 if (componentInstanceEither.isRight()) {
1597 log.debug("replaceVNF:delete Abstract ComponentInstance field");
1598 return buildErrorResponse(componentInstanceEither.right().value());
1603 log.debug("replaceVNF,start add vnf");
1604 componentInstance.setInvariantName(null);
1605 componentInstance.setCreatedFrom(CreatedFrom.UI);
1606 Either<ComponentInstance, ResponseFormat> realComponentInstance = componentInstanceBusinessLogic
1607 .createRealComponentInstance(containerComponentType, serviceUniqueId, userId, componentInstance);
1608 if (realComponentInstance.isRight()) {
1609 log.debug("replaceVNF:filed to add vnf");
1610 return buildErrorResponse(realComponentInstance.right().value());
1612 ComponentInstance newComponentInstance = realComponentInstance.left().value();
1613 log.debug("replaceVNF:success to add vnf");
1614 return buildOkResponse(getComponentsUtils().getResponseFormat(ActionStatus.OK), newComponentInstance);
1615 } catch (Exception e) {
1616 BeEcompErrorManager.getInstance().logBeRestApiGeneralError("replaceVNF");
1617 log.debug("replaceVNF with exception", e);
1622 private Either<ReplaceVNFInfo, ResponseFormat> parseToReplaceVNFInfo(String serviceJson, User user) {
1623 log.debug("enter parseToReplaceVNFInfo,get serviceJson:{}", serviceJson);
1624 return getComponentsUtils().convertJsonToObjectUsingObjectMapper(serviceJson, user, ReplaceVNFInfo.class, AuditingActionEnum.CREATE_RESOURCE,
1625 ComponentTypeEnum.SERVICE);