catalog-be servlets refactoring
[sdc.git] / catalog-be / src / main / java / org / openecomp / sdc / be / servlets / ComponentInstanceServlet.java
1 /*-
2  * ============LICENSE_START=======================================================
3  * SDC
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
10  * 
11  *      http://www.apache.org/licenses/LICENSE-2.0
12  * 
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=========================================================
19  */
20
21 package org.openecomp.sdc.be.servlets;
22
23 import com.fasterxml.jackson.databind.ObjectMapper;
24 import com.google.gson.Gson;
25 import com.google.gson.GsonBuilder;
26 import com.google.gson.reflect.TypeToken;
27 import com.jcabi.aspects.Loggable;
28 import fj.data.Either;
29 import io.swagger.annotations.*;
30 import javax.inject.Inject;
31 import org.apache.commons.io.IOUtils;
32 import org.apache.commons.lang.StringUtils;
33 import org.openecomp.sdc.be.components.impl.ComponentInstanceBusinessLogic;
34 import org.openecomp.sdc.be.components.impl.GroupBusinessLogic;
35 import org.openecomp.sdc.be.components.impl.ResourceImportManager;
36 import org.openecomp.sdc.be.components.impl.ServiceBusinessLogic;
37 import org.openecomp.sdc.be.components.impl.utils.DirectivesUtils;
38 import org.openecomp.sdc.be.config.BeEcompErrorManager;
39 import org.openecomp.sdc.be.dao.api.ActionStatus;
40 import org.openecomp.sdc.be.datamodel.ForwardingPaths;
41 import org.openecomp.sdc.be.datatypes.elements.CINodeFilterDataDefinition;
42 import org.openecomp.sdc.be.datatypes.enums.ComponentTypeEnum;
43 import org.openecomp.sdc.be.datatypes.enums.JsonPresentationFields;
44 import org.openecomp.sdc.be.impl.ComponentsUtils;
45 import org.openecomp.sdc.be.impl.ServletUtils;
46 import org.openecomp.sdc.be.info.CreateAndAssotiateInfo;
47 import org.openecomp.sdc.be.info.GroupDefinitionInfo;
48 import org.openecomp.sdc.be.model.*;
49 import org.openecomp.sdc.be.model.operations.impl.PropertyOperation.PropertyConstraintDeserialiser;
50 import org.openecomp.sdc.be.user.UserBusinessLogic;
51 import org.openecomp.sdc.common.api.Constants;
52 import org.openecomp.sdc.common.datastructure.Wrapper;
53 import org.openecomp.sdc.common.log.wrappers.Logger;
54 import org.openecomp.sdc.exception.ResponseFormat;
55
56 import javax.inject.Singleton;
57 import javax.servlet.ServletContext;
58 import javax.servlet.http.HttpServletRequest;
59 import javax.ws.rs.*;
60 import javax.ws.rs.core.Context;
61 import javax.ws.rs.core.MediaType;
62 import javax.ws.rs.core.Response;
63 import java.io.InputStream;
64 import java.lang.reflect.Type;
65 import java.util.ArrayList;
66 import java.util.Arrays;
67 import java.util.List;
68 import java.util.Set;
69 import java.util.Map;
70
71 /**
72  * Root resource (exposed at "/" path) .json
73  */
74 @Loggable(prepend = true, value = Loggable.DEBUG, trim = false)
75 @Path("/v1/catalog")
76 @Api(value = "Resource Instance Servlet")
77 @Singleton
78 public class ComponentInstanceServlet extends AbstractValidationsServlet {
79
80     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: {}";
81         private static final String GET_GROUP_ARTIFACT_BY_ID = "getGroupArtifactById";
82         private static final String GET_GROUP_ARTIFACT_BY_ID_UNEXPECTED_EXCEPTION = "getGroupArtifactById unexpected exception";
83         private static final String GET_START_HANDLE_REQUEST_OF = "(GET) Start handle request of {}";
84         private static final String START_HANDLE_REQUEST_OF_UPDATE_RESOURCE_INSTANCE_PROPERTY_RECEIVED_PROPERTY_IS = "Start handle request of updateResourceInstanceProperty. Received property is {}";
85         private static final String UPDATE_RESOURCE_INSTANCE = "Update Resource Instance";
86         private static final String RESOURCE_INSTANCE_UPDATE_RESOURCE_INSTANCE = "Resource Instance - updateResourceInstance";
87         private static final String UPDATE_RESOURCE_INSTANCE_WITH_EXCEPTION = "update resource instance with exception";
88         private static final String FAILED_TO_CONVERT_RECEIVED_DATA_TO_BE_FORMAT = "Failed to convert received data to BE format.";
89         private static final String EMPTY_BODY_WAS_SENT = "Empty body was sent.";
90         private static final String START_HANDLE_REQUEST_OF = "Start handle request of {}";
91         private static final String UNSUPPORTED_COMPONENT_TYPE = "Unsupported component type {}";
92         private static final Logger log = Logger.getLogger(ComponentInstanceServlet.class);
93     private static final Type PROPERTY_CONSTRAINT_TYPE = new TypeToken<PropertyConstraint>() {}.getType();
94     private static final Gson gsonDeserializer = new GsonBuilder().registerTypeAdapter(PROPERTY_CONSTRAINT_TYPE, new PropertyConstraintDeserialiser()).create();
95     private final GroupBusinessLogic groupBL;
96     private final ComponentInstanceBusinessLogic componentInstanceBusinessLogic;
97     private final ServiceBusinessLogic serviceBusinessLogic;
98
99
100     @Inject
101     public ComponentInstanceServlet(UserBusinessLogic userBusinessLogic,
102         GroupBusinessLogic groupBL, ComponentInstanceBusinessLogic componentInstanceBL,
103         ComponentsUtils componentsUtils, ServletUtils servletUtils,
104         ResourceImportManager resourceImportManager,
105         ServiceBusinessLogic serviceBusinessLogic) {
106         super(userBusinessLogic, componentInstanceBL, componentsUtils, servletUtils, resourceImportManager);
107         this.groupBL = groupBL;
108         this.componentInstanceBusinessLogic = componentInstanceBL;
109         this.serviceBusinessLogic = serviceBusinessLogic;
110     }
111
112     @POST
113     @Path("/{containerComponentType}/{componentId}/resourceInstance")
114     @Consumes(MediaType.APPLICATION_JSON)
115     @Produces(MediaType.APPLICATION_JSON)
116     @ApiOperation(value = "Create ComponentInstance", httpMethod = "POST", notes = "Returns created ComponentInstance", response = Response.class)
117     @ApiResponses(value = { @ApiResponse(code = 201, message = "Component created"), @ApiResponse(code = 403, message = "Restricted operation"), @ApiResponse(code = 400, message = "Invalid content / Missing content"),
118             @ApiResponse(code = 409, message = "Component instance already exist") })
119     public Response createComponentInstance(@ApiParam(value = "RI object to be created", required = true) String data, @PathParam("componentId") final String containerComponentId,
120             @ApiParam(value = "valid values: resources / services", allowableValues = ComponentTypeEnum.RESOURCE_PARAM_NAME + "," + ComponentTypeEnum.SERVICE_PARAM_NAME) @PathParam("containerComponentType") final String containerComponentType,
121             @HeaderParam(value = Constants.USER_ID_HEADER) @ApiParam(value = "USER_ID of modifier user", required = true) String userId, @Context final HttpServletRequest request) {
122         ServletContext context = request.getSession().getServletContext();
123
124         try {
125
126             ComponentInstance componentInstance = RepresentationUtils.fromRepresentation(data, ComponentInstance.class);
127             componentInstance.setInvariantName(null);
128             ComponentTypeEnum componentTypeEnum = ComponentTypeEnum.findByParamName(containerComponentType);
129             if (componentInstanceBusinessLogic == null) {
130                 log.debug(UNSUPPORTED_COMPONENT_TYPE, containerComponentType);
131                 return buildErrorResponse(getComponentsUtils().getResponseFormat(ActionStatus.UNSUPPORTED_ERROR, containerComponentType));
132             }
133             Either<ComponentInstance, ResponseFormat> actionResponse = componentInstanceBusinessLogic.createComponentInstance(containerComponentType, containerComponentId, userId, componentInstance);
134
135             if (actionResponse.isRight()) {
136                 return buildErrorResponse(actionResponse.right().value());
137             }
138             return buildOkResponse(getComponentsUtils().getResponseFormat(ActionStatus.CREATED), actionResponse.left().value());
139
140         } catch (Exception e) {
141             BeEcompErrorManager.getInstance().logBeRestApiGeneralError("Create Component Instance");
142             log.debug("create component instance failed with exception", e);
143             return buildErrorResponse(getComponentsUtils().getResponseFormat(ActionStatus.GENERAL_ERROR));
144         }
145     }
146
147     @POST
148     @Path("/{containerComponentType}/{componentId}/resourceInstance/{componentInstanceId}")
149     @Consumes(MediaType.APPLICATION_JSON)
150     @Produces(MediaType.APPLICATION_JSON)
151     @ApiOperation(value = "Update resource instance", httpMethod = "POST", notes = "Returns updated resource instance", response = Response.class)
152     @ApiResponses(value = { @ApiResponse(code = 200, message = "Resource instance updated"), @ApiResponse(code = 403, message = "Restricted operation"), @ApiResponse(code = 400, message = "Invalid content / Missing content") })
153     public Response updateComponentInstanceMetadata(@PathParam("componentId") final String componentId, @PathParam("componentInstanceId") final String componentInstanceId,
154             @ApiParam(value = "valid values: resources / services / products", allowableValues = ComponentTypeEnum.RESOURCE_PARAM_NAME + "," + ComponentTypeEnum.SERVICE_PARAM_NAME + ","
155                     + ComponentTypeEnum.PRODUCT_PARAM_NAME) @PathParam("containerComponentType") final String containerComponentType,
156             @Context final HttpServletRequest request) {
157
158         String url = request.getMethod() + " " + request.getRequestURI();
159         log.debug(START_HANDLE_REQUEST_OF, url);
160         try {
161
162             log.debug(START_HANDLE_REQUEST_OF, url);
163
164             InputStream inputStream = request.getInputStream();
165
166             byte[] bytes = IOUtils.toByteArray(inputStream);
167
168             if (bytes == null || bytes.length == 0) {
169                 log.info(EMPTY_BODY_WAS_SENT);
170                 return buildErrorResponse(getComponentsUtils().getResponseFormat(ActionStatus.INVALID_CONTENT));
171             }
172
173             String userId = request.getHeader(Constants.USER_ID_HEADER);
174
175             String data = new String(bytes);
176             ComponentTypeEnum componentTypeEnum = ComponentTypeEnum.findByParamName(containerComponentType);
177             if (componentInstanceBusinessLogic == null) {
178                 log.debug(UNSUPPORTED_COMPONENT_TYPE, containerComponentType);
179                 return buildErrorResponse(getComponentsUtils().getResponseFormat(ActionStatus.UNSUPPORTED_ERROR, containerComponentType));
180             }
181             Either<ComponentInstance, ResponseFormat> convertResponse = convertToResourceInstance(data);
182
183             if (convertResponse.isRight()) {
184                 BeEcompErrorManager.getInstance().logBeSystemError(RESOURCE_INSTANCE_UPDATE_RESOURCE_INSTANCE);
185                 log.debug(FAILED_TO_CONVERT_RECEIVED_DATA_TO_BE_FORMAT);
186                 return buildErrorResponse(convertResponse.right().value());
187             }
188
189             ComponentInstance resourceInstance = convertResponse.left().value();
190             Either<ComponentInstance, ResponseFormat> actionResponse = componentInstanceBusinessLogic.updateComponentInstanceMetadata(containerComponentType, componentId, componentInstanceId, userId, resourceInstance);
191
192             if (actionResponse.isRight()) {
193                 return buildErrorResponse(actionResponse.right().value());
194             }
195             ComponentInstance resultValue = actionResponse.left().value();
196             if (componentTypeEnum.equals(ComponentTypeEnum.SERVICE)){
197                 boolean shouldCreateServiceFilter = resourceInstance.getDirectives() != null && resourceInstance.getDirectives().contains(
198                         DirectivesUtils.SELECTABLE);
199
200                 if(shouldCreateServiceFilter) {
201                     Either<CINodeFilterDataDefinition, ResponseFormat> either =
202                             serviceBusinessLogic.createIfNotAlreadyExistServiceFilter(componentId, componentInstanceId, userId,
203                                     true);
204                     if (either.isRight()){
205                         BeEcompErrorManager.getInstance().logBeSystemError("Resource Instance - updateResourceInstance Failed to create service filter.");
206                         log.debug("Failed to create service filter.");
207                         return buildErrorResponse(convertResponse.right().value());
208                     }
209                     resultValue.setNodeFilter(either.left().value());
210                 } else {
211                     Either<String, ResponseFormat> either = serviceBusinessLogic.deleteIfNotAlreadyDeletedServiceFilter(componentId, componentInstanceId,  userId,true);
212                     if (either.isRight()){
213                         BeEcompErrorManager.getInstance().logBeSystemError("Resource Instance - updateResourceInstance Failed to delete service filter.");
214                         log.debug("Failed to delete service filter.");
215                         return buildErrorResponse(convertResponse.right().value());
216                     }
217                     resultValue.setNodeFilter(null);
218                 }
219             }
220
221             return buildOkResponse(getComponentsUtils().getResponseFormat(ActionStatus.OK), actionResponse.left().value());
222
223         } catch (Exception e) {
224             BeEcompErrorManager.getInstance().logBeRestApiGeneralError(UPDATE_RESOURCE_INSTANCE);
225             log.debug(UPDATE_RESOURCE_INSTANCE_WITH_EXCEPTION, e);
226             return buildErrorResponse(getComponentsUtils().getResponseFormat(ActionStatus.GENERAL_ERROR));
227         }
228
229     }
230
231     @POST
232     @Path("/{containerComponentType}/{componentId}/resourceInstance/multipleComponentInstance")
233     @Consumes(MediaType.APPLICATION_JSON)
234     @Produces(MediaType.APPLICATION_JSON)
235     @ApiOperation(value = "Update resource instance multiple component", httpMethod = "POST", notes = "Returns updated resource instance", response = Response.class)
236     @ApiResponses(value = { @ApiResponse(code = 200, message = "Resource instance updated"), @ApiResponse(code = 403, message = "Restricted operation"), @ApiResponse(code = 400, message = "Invalid content / Missing content") })
237     public Response updateMultipleComponentInstance(@PathParam("componentId") final String componentId,
238             @ApiParam(value = "valid values: resources / services / products", allowableValues = ComponentTypeEnum.RESOURCE_PARAM_NAME + "," + ComponentTypeEnum.SERVICE_PARAM_NAME + ","
239                     + ComponentTypeEnum.PRODUCT_PARAM_NAME) @PathParam("containerComponentType") final String containerComponentType,
240             @Context final HttpServletRequest request, @ApiParam(value = "Component Instance JSON Array", required = true) final String componentInstanceJsonArray) {
241
242         ServletContext context = request.getSession().getServletContext();
243         String url = request.getMethod() + " " + request.getRequestURI();
244         log.debug(START_HANDLE_REQUEST_OF, url);
245
246         try {
247             log.debug(START_HANDLE_REQUEST_OF, url);
248
249             if (componentInstanceJsonArray == null || componentInstanceJsonArray.length() == 0) {
250                 log.info("Empty JSON list was sent.");
251                 return buildErrorResponse(getComponentsUtils().getResponseFormat(ActionStatus.INVALID_CONTENT));
252             }
253
254             String userId = request.getHeader(Constants.USER_ID_HEADER);
255
256             ComponentTypeEnum componentTypeEnum = ComponentTypeEnum.findByParamName(containerComponentType);
257             if (componentInstanceBusinessLogic == null) {
258                 log.debug(UNSUPPORTED_COMPONENT_TYPE, containerComponentType);
259                 return buildErrorResponse(getComponentsUtils().getResponseFormat(ActionStatus.UNSUPPORTED_ERROR, containerComponentType));
260             }
261
262             Either<List<ComponentInstance>, ResponseFormat> convertResponse = convertToMultipleResourceInstance(componentInstanceJsonArray);
263
264             if (convertResponse.isRight()) {
265                 // Using both ECOMP error methods, show to Sofer
266                 BeEcompErrorManager.getInstance().logBeSystemError(RESOURCE_INSTANCE_UPDATE_RESOURCE_INSTANCE);
267                 log.debug(FAILED_TO_CONVERT_RECEIVED_DATA_TO_BE_FORMAT);
268                 return buildErrorResponse(convertResponse.right().value());
269             }
270
271             List<ComponentInstance> componentInstanceList = convertResponse.left().value();
272
273             Either<List<ComponentInstance>, ResponseFormat> actionResponse = componentInstanceBusinessLogic
274                 .updateComponentInstance(containerComponentType, componentId, userId, componentInstanceList, true);
275
276             if (actionResponse.isRight()) {
277                 return buildErrorResponse(actionResponse.right().value());
278             }
279
280             return buildOkResponse(getComponentsUtils().getResponseFormat(ActionStatus.OK), actionResponse.left().value());
281
282         } catch (Exception e) {
283             BeEcompErrorManager.getInstance().logBeRestApiGeneralError(UPDATE_RESOURCE_INSTANCE);
284             log.debug(UPDATE_RESOURCE_INSTANCE_WITH_EXCEPTION, e);
285             return buildErrorResponse(getComponentsUtils().getResponseFormat(ActionStatus.GENERAL_ERROR));
286         }
287
288     }
289
290     @DELETE
291     @Path("/{containerComponentType}/{componentId}/resourceInstance/{resourceInstanceId}")
292     @Consumes(MediaType.APPLICATION_JSON)
293     @Produces(MediaType.APPLICATION_JSON)
294     @ApiOperation(value = "Delete ResourceInstance", httpMethod = "DELETE", notes = "Returns delete resourceInstance", response = Response.class)
295     @ApiResponses(value = { @ApiResponse(code = 201, message = "ResourceInstance deleted"), @ApiResponse(code = 403, message = "Restricted operation"), @ApiResponse(code = 400, message = "Invalid content / Missing content") })
296     public Response deleteResourceInstance(@PathParam("componentId") final String componentId, @PathParam("resourceInstanceId") final String resourceInstanceId,
297             @ApiParam(value = "valid values: resources / services / products", allowableValues = ComponentTypeEnum.RESOURCE_PARAM_NAME + "," + ComponentTypeEnum.SERVICE_PARAM_NAME + ","
298                     + ComponentTypeEnum.PRODUCT_PARAM_NAME) @PathParam("containerComponentType") final String containerComponentType,
299             @Context final HttpServletRequest request) {
300         ServletContext context = request.getSession().getServletContext();
301         String url = request.getMethod() + " " + request.getRequestURI();
302         Response response = null;
303         try {
304             log.debug(START_HANDLE_REQUEST_OF, url);
305             ComponentTypeEnum componentTypeEnum = ComponentTypeEnum.findByParamName(containerComponentType);
306             if (componentInstanceBusinessLogic == null) {
307                 log.debug(UNSUPPORTED_COMPONENT_TYPE, containerComponentType);
308                 return buildErrorResponse(getComponentsUtils().getResponseFormat(ActionStatus.UNSUPPORTED_ERROR, containerComponentType));
309             }
310             String userId = request.getHeader(Constants.USER_ID_HEADER);
311             Either<ComponentInstance, ResponseFormat> actionResponse = componentInstanceBusinessLogic.deleteComponentInstance(containerComponentType, componentId, resourceInstanceId, userId);
312
313             if (actionResponse.isRight()) {
314                 response = buildErrorResponse(actionResponse.right().value());
315             } else {
316                 response = buildOkResponse(getComponentsUtils().getResponseFormat(ActionStatus.NO_CONTENT), null);
317             }
318             return response;
319         } catch (Exception e) {
320             BeEcompErrorManager.getInstance().logBeRestApiGeneralError("Delete Resource Instance");
321             log.debug("delete resource instance with exception", e);
322             return buildErrorResponse(getComponentsUtils().getResponseFormat(ActionStatus.GENERAL_ERROR));
323         }
324     }
325
326     @ApiParam(value = "allowed values are resources /services / products", allowableValues = ComponentTypeEnum.RESOURCE_PARAM_NAME + "," + ComponentTypeEnum.SERVICE_PARAM_NAME + "," + ComponentTypeEnum.PRODUCT_PARAM_NAME, required = true)
327     @POST
328     @Path("/{containerComponentType}/{componentId}/resourceInstance/associate")
329     @Consumes(MediaType.APPLICATION_JSON)
330     @Produces(MediaType.APPLICATION_JSON)
331     @ApiOperation(value = "Associate RI to RI", httpMethod = "POST", notes = "Returns created RelationshipInfo", response = Response.class)
332     @ApiResponses(value = { @ApiResponse(code = 201, message = "Relationship created"), @ApiResponse(code = 403, message = "Missing information"), @ApiResponse(code = 400, message = "Invalid content / Missing content"),
333             @ApiResponse(code = 409, message = "Relationship already exist") })
334     public Response associateRIToRI(@ApiParam(value = "unique id of the container component") @PathParam("componentId") final String componentId,
335             @ApiParam(value = "allowed values are resources /services / products", allowableValues = ComponentTypeEnum.RESOURCE_PARAM_NAME + "," + ComponentTypeEnum.SERVICE_PARAM_NAME + ","
336                     + ComponentTypeEnum.PRODUCT_PARAM_NAME, required = true) @PathParam("containerComponentType") final String containerComponentType,
337             @HeaderParam(value = Constants.USER_ID_HEADER) String userId, @ApiParam(value = "RelationshipInfo", required = true) String data, @Context final HttpServletRequest request) {
338
339         String url = request.getMethod() + " " + request.getRequestURI();
340         log.debug(START_HANDLE_REQUEST_OF, url);
341         Response response = null;
342
343         try {
344
345             log.debug(START_HANDLE_REQUEST_OF, url);
346
347             ComponentTypeEnum componentTypeEnum = ComponentTypeEnum.findByParamName(containerComponentType);
348             if (componentInstanceBusinessLogic == null) {
349                 log.debug(UNSUPPORTED_COMPONENT_TYPE, containerComponentType);
350                 return buildErrorResponse(getComponentsUtils().getResponseFormat(ActionStatus.UNSUPPORTED_ERROR, containerComponentType));
351             }
352
353             Either<RequirementCapabilityRelDef, ResponseFormat> regInfoW = convertToRequirementCapabilityRelDef(data);
354
355             Either<RequirementCapabilityRelDef, ResponseFormat> resultOp;
356             if (regInfoW.isRight()) {
357                 BeEcompErrorManager.getInstance().logBeSystemError("Resource Instance - associateRIToRI");
358                 log.debug(FAILED_TO_CONVERT_RECEIVED_DATA_TO_BE_FORMAT);
359                 resultOp = Either.right(regInfoW.right().value());
360             } else {
361                 RequirementCapabilityRelDef requirementDef = regInfoW.left().value();
362                 requirementDef.setOriginUI(true);
363                 resultOp = componentInstanceBusinessLogic.associateRIToRI(componentId, userId, requirementDef, componentTypeEnum);
364             }
365
366             Either<RequirementCapabilityRelDef, ResponseFormat> actionResponse = resultOp;
367
368             if (actionResponse.isRight()) {
369                 response = buildErrorResponse(actionResponse.right().value());
370             } else {
371                 response = buildOkResponse(getComponentsUtils().getResponseFormat(ActionStatus.OK), actionResponse.left().value());
372             }
373             return response;
374
375         } catch (Exception e) {
376             BeEcompErrorManager.getInstance().logBeRestApiGeneralError("Associate Resource Instance");
377             log.debug("associate resource instance to another RI with exception", e);
378             return buildErrorResponse(getComponentsUtils().getResponseFormat(ActionStatus.GENERAL_ERROR));
379         }
380     }
381
382     @PUT
383     @Path("/{containerComponentType}/{componentId}/resourceInstance/dissociate")
384     @Consumes(MediaType.APPLICATION_JSON)
385     @Produces(MediaType.APPLICATION_JSON)
386     @ApiOperation(value = "Dissociate RI from RI", httpMethod = "PUT", notes = "Returns deleted RelationshipInfo", response = Response.class)
387     @ApiResponses(value = { @ApiResponse(code = 201, message = "Relationship deleted"), @ApiResponse(code = 403, message = "Missing information"), @ApiResponse(code = 400, message = "Invalid content / Missing content") })
388     public Response dissociateRIFromRI(
389             @ApiParam(value = "allowed values are resources /services / products", allowableValues = ComponentTypeEnum.RESOURCE_PARAM_NAME + "," + ComponentTypeEnum.SERVICE_PARAM_NAME + ","
390                     + ComponentTypeEnum.PRODUCT_PARAM_NAME, required = true) @PathParam("containerComponentType") final String containerComponentType,
391             @ApiParam(value = "unique id of the container component") @PathParam("componentId") final String componentId, @HeaderParam(value = Constants.USER_ID_HEADER) String userId,
392             @ApiParam(value = "RelationshipInfo", required = true) String data, @Context final HttpServletRequest request) {
393         ServletContext context = request.getSession().getServletContext();
394
395         String url = request.getMethod() + " " + request.getRequestURI();
396         log.debug(START_HANDLE_REQUEST_OF, url);
397
398         try {
399
400             log.debug(START_HANDLE_REQUEST_OF, url);
401
402             ComponentTypeEnum componentTypeEnum = ComponentTypeEnum.findByParamName(containerComponentType);
403             if (componentInstanceBusinessLogic == null) {
404                 log.debug(UNSUPPORTED_COMPONENT_TYPE, containerComponentType);
405                 return buildErrorResponse(getComponentsUtils().getResponseFormat(ActionStatus.UNSUPPORTED_ERROR, containerComponentType));
406             }
407
408             Either<RequirementCapabilityRelDef, ResponseFormat> regInfoW = convertToRequirementCapabilityRelDef(data);
409             if (regInfoW.isRight()) {
410                 BeEcompErrorManager.getInstance().logBeSystemError("Resource Instance - dissociateRIFromRI");
411                 log.debug(FAILED_TO_CONVERT_RECEIVED_DATA_TO_BE_FORMAT);
412                 return buildErrorResponse(regInfoW.right().value());
413             }
414
415             RequirementCapabilityRelDef requirementDef = regInfoW.left().value();
416             Either<RequirementCapabilityRelDef, ResponseFormat> actionResponse = componentInstanceBusinessLogic.dissociateRIFromRI(componentId, userId, requirementDef, componentTypeEnum);
417
418             if (actionResponse.isRight()) {
419                 return buildErrorResponse(actionResponse.right().value());
420             }
421             return buildOkResponse(getComponentsUtils().getResponseFormat(ActionStatus.OK), actionResponse.left().value());
422
423         } catch (Exception e) {
424             BeEcompErrorManager.getInstance().logBeRestApiGeneralError("Dissociate Resource Instance");
425             log.debug("dissociate resource instance from service failed with exception", e);
426             return buildErrorResponse(getComponentsUtils().getResponseFormat(ActionStatus.GENERAL_ERROR));
427         }
428     }
429
430     @POST
431     @Path("/{containerComponentType}/{componentId}/resourceInstance/createAndAssociate")
432     @Consumes(MediaType.APPLICATION_JSON)
433     @Produces(MediaType.APPLICATION_JSON)
434     @ApiOperation(value = "Create RI and associate RI to RI", httpMethod = "POST", notes = "Returns created RI and RelationshipInfo", response = Response.class)
435     @ApiResponses(value = { @ApiResponse(code = 201, message = "RI created"), @ApiResponse(code = 403, message = "Restricted operation"), @ApiResponse(code = 400, message = "Invalid content / Missing content"),
436             @ApiResponse(code = 409, message = "Relationship already exist") })
437     public Response createAndAssociateRIToRI(@PathParam("componentId") final String componentId,
438             @ApiParam(value = "valid values: resources / services", allowableValues = ComponentTypeEnum.RESOURCE_PARAM_NAME + "," + ComponentTypeEnum.SERVICE_PARAM_NAME) @PathParam("containerComponentType") final String containerComponentType,
439             @Context final HttpServletRequest request) {
440         ServletContext context = request.getSession().getServletContext();
441
442         String url = request.getMethod() + " " + request.getRequestURI();
443         log.debug(START_HANDLE_REQUEST_OF, url);
444         try {
445
446             log.debug(START_HANDLE_REQUEST_OF, url);
447
448             InputStream inputStream = request.getInputStream();
449
450             byte[] bytes = IOUtils.toByteArray(inputStream);
451
452             if (bytes == null || bytes.length == 0) {
453                 log.info(EMPTY_BODY_WAS_SENT);
454                 return buildErrorResponse(getComponentsUtils().getResponseFormat(ActionStatus.INVALID_CONTENT));
455             }
456
457             String userId = request.getHeader(Constants.USER_ID_HEADER);
458
459             String data = new String(bytes);
460
461             ComponentTypeEnum componentTypeEnum = ComponentTypeEnum.findByParamName(containerComponentType);
462             if (componentInstanceBusinessLogic == null) {
463                 log.debug(UNSUPPORTED_COMPONENT_TYPE, containerComponentType);
464                 return buildErrorResponse(getComponentsUtils().getResponseFormat(ActionStatus.UNSUPPORTED_ERROR, containerComponentType));
465             }
466
467             Either<CreateAndAssotiateInfo, ActionStatus> convertStatus = convertJsonToObject(data, CreateAndAssotiateInfo.class);
468             if (convertStatus.isRight()) {
469                 BeEcompErrorManager.getInstance().logBeSystemError("Resource Instance - createAndAssociateRIToRI");
470                 log.debug(FAILED_TO_CONVERT_RECEIVED_DATA_TO_BE_FORMAT);
471                 Either<Object, ResponseFormat> formattedResponse = Either.right(getComponentsUtils().getResponseFormat(convertStatus.right().value()));
472                 return buildErrorResponse(formattedResponse.right().value());
473             }
474
475             CreateAndAssotiateInfo createAndAssotiateInfo = convertStatus.left().value();
476             RequirementCapabilityRelDef requirementDef = createAndAssotiateInfo.getAssociate();
477             requirementDef.setOriginUI(true);
478             Either<CreateAndAssotiateInfo, ResponseFormat> actionResponse = componentInstanceBusinessLogic.createAndAssociateRIToRI(containerComponentType, componentId, userId, createAndAssotiateInfo);
479
480             if (actionResponse.isRight()) {
481                 return buildErrorResponse(actionResponse.right().value());
482             }
483             return buildOkResponse(getComponentsUtils().getResponseFormat(ActionStatus.CREATED), actionResponse.left().value());
484         } catch (Exception e) {
485             BeEcompErrorManager.getInstance().logBeRestApiGeneralError("Create and Associate Resource Instance");
486             log.debug("create and associate RI failed with exception", e);
487             return buildErrorResponse(getComponentsUtils().getResponseFormat(ActionStatus.GENERAL_ERROR));
488         }
489     }
490
491     @POST
492     @Path("/{containerComponentType}/{componentId}/resourceInstance/{componentInstanceId}/properties")
493     @Consumes(MediaType.APPLICATION_JSON)
494     @Produces(MediaType.APPLICATION_JSON)
495     @ApiOperation(value = "Update resource instance property", httpMethod = "POST", notes = "Returns updated resource instance property", response = Response.class)
496     @ApiResponses(value = { @ApiResponse(code = 201, message = "Resource instance created"), @ApiResponse(code = 403, message = "Restricted operation"), @ApiResponse(code = 400, message = "Invalid content / Missing content") })
497     public Response updateResourceInstanceProperties(@ApiParam(value = "service id") @PathParam("componentId") final String componentId,
498             @ApiParam(value = "valid values: resources / services", allowableValues = ComponentTypeEnum.RESOURCE_PARAM_NAME + "," + ComponentTypeEnum.SERVICE_PARAM_NAME) @PathParam("containerComponentType") final String containerComponentType,
499             @ApiParam(value = "resource instance id") @PathParam("componentInstanceId") final String componentInstanceId, @ApiParam(value = "id of user initiating the operation") @HeaderParam(value = Constants.USER_ID_HEADER) String userId,
500             @Context final HttpServletRequest request, @ApiParam(value = "Component Instance Properties JSON Array", required = true) final String componentInstancePropertiesJsonArray) {
501
502         String url = request.getMethod() + " " + request.getRequestURI();
503         log.debug(START_HANDLE_REQUEST_OF, url);
504
505         try {
506             Wrapper<ResponseFormat> errorWrapper = new Wrapper<>();
507             List<ComponentInstanceProperty> propertiesToUpdate = new ArrayList<>();
508             if (errorWrapper.isEmpty()) {
509                 Either<List<ComponentInstanceProperty>, ResponseFormat> propertiesToUpdateEither = convertMultipleProperties(componentInstancePropertiesJsonArray);
510                 if (propertiesToUpdateEither.isRight()) {
511                     errorWrapper.setInnerElement(propertiesToUpdateEither.right().value());
512                 } else {
513                     propertiesToUpdate = propertiesToUpdateEither.left().value();
514                 }
515             }
516
517             if (!errorWrapper.isEmpty()) {
518                 return buildErrorResponse(errorWrapper.getInnerElement());
519             }
520
521             log.debug(START_HANDLE_REQUEST_OF_UPDATE_RESOURCE_INSTANCE_PROPERTY_RECEIVED_PROPERTY_IS, propertiesToUpdate);
522
523             ServletContext context = request.getSession().getServletContext();
524
525             ComponentTypeEnum componentTypeEnum = ComponentTypeEnum.findByParamName(containerComponentType);
526             if (componentInstanceBusinessLogic == null) {
527                 log.debug(UNSUPPORTED_COMPONENT_TYPE, containerComponentType);
528                 return buildErrorResponse(getComponentsUtils().getResponseFormat(ActionStatus.UNSUPPORTED_ERROR, containerComponentType));
529             }
530
531             Either<List<ComponentInstanceProperty>, ResponseFormat> actionResponse =
532                 componentInstanceBusinessLogic.createOrUpdatePropertiesValues(componentTypeEnum, componentId, componentInstanceId, propertiesToUpdate, userId);
533
534             if (actionResponse.isRight()) {
535                 return buildErrorResponse(actionResponse.right().value());
536             }
537
538             List<ComponentInstanceProperty> resourceInstanceProperties = actionResponse.left().value();
539             ObjectMapper mapper = new ObjectMapper();
540             String result = mapper.writeValueAsString(resourceInstanceProperties);
541             return buildOkResponse(getComponentsUtils().getResponseFormat(ActionStatus.OK), result);
542
543         } catch (Exception e) {
544             log.error("create and associate RI failed with exception: {}", e.getMessage(), e);
545             return buildErrorResponse(getComponentsUtils().getResponseFormat(ActionStatus.GENERAL_ERROR));
546         }
547
548     }
549
550     @POST
551     @Path("/{containerComponentType}/{componentId}/resourceInstance/{componentInstanceId}/inputs")
552     @Consumes(MediaType.APPLICATION_JSON)
553     @Produces(MediaType.APPLICATION_JSON)
554     @ApiOperation(value = "Update resource instance property", httpMethod = "POST", notes = "Returns updated resource instance property", response = Response.class)
555     @ApiResponses(value = { @ApiResponse(code = 201, message = "Resource instance created"), @ApiResponse(code = 403, message = "Restricted operation"), @ApiResponse(code = 400, message = "Invalid content / Missing content") })
556     public Response updateResourceInstanceInput(@ApiParam(value = "service id") @PathParam("componentId") final String componentId,
557             @ApiParam(value = "valid values: resources / services", allowableValues = ComponentTypeEnum.RESOURCE_PARAM_NAME + "," + ComponentTypeEnum.SERVICE_PARAM_NAME) @PathParam("containerComponentType") final String containerComponentType,
558             @ApiParam(value = "resource instance id") @PathParam("componentInstanceId") final String componentInstanceId, @ApiParam(value = "id of user initiating the operation") @HeaderParam(value = Constants.USER_ID_HEADER) String userId,
559             @Context final HttpServletRequest request, @ApiParam(value = "Component Instance Properties JSON Array", required = true) final String componentInstanceInputsJsonArray) {
560
561         String url = request.getMethod() + " " + request.getRequestURI();
562         log.debug(START_HANDLE_REQUEST_OF, url);
563
564         try {
565             Wrapper<ResponseFormat> errorWrapper = new Wrapper<>();
566             List<ComponentInstanceInput> inputsToUpdate = new ArrayList<>();
567             if (errorWrapper.isEmpty()) {
568                 Either<List<ComponentInstanceInput>, ResponseFormat> inputsToUpdateEither = convertMultipleInputs(componentInstanceInputsJsonArray);
569                 if (inputsToUpdateEither.isRight()) {
570                     errorWrapper.setInnerElement(inputsToUpdateEither.right().value());
571                 } else {
572                     inputsToUpdate = inputsToUpdateEither.left().value();
573                 }
574             }
575             if (!errorWrapper.isEmpty()) {
576                 return buildErrorResponse(errorWrapper.getInnerElement());
577             }
578
579             log.debug(START_HANDLE_REQUEST_OF_UPDATE_RESOURCE_INSTANCE_PROPERTY_RECEIVED_PROPERTY_IS, inputsToUpdate);
580
581             ServletContext context = request.getSession().getServletContext();
582
583             ComponentTypeEnum componentTypeEnum = ComponentTypeEnum.findByParamName(containerComponentType);
584             if (componentInstanceBusinessLogic == null) {
585                 log.debug(UNSUPPORTED_COMPONENT_TYPE, containerComponentType);
586                 return buildErrorResponse(getComponentsUtils().getResponseFormat(ActionStatus.UNSUPPORTED_ERROR, containerComponentType));
587             }
588
589             Either<List<ComponentInstanceInput>, ResponseFormat> actionResponse =
590                 componentInstanceBusinessLogic.createOrUpdateInstanceInputValues(componentTypeEnum, componentId, componentInstanceId, inputsToUpdate, userId);
591
592             if (actionResponse.isRight()) {
593                 return buildErrorResponse(actionResponse.right().value());
594             }
595
596             List<ComponentInstanceInput> resourceInstanceInput = actionResponse.left().value();
597             ObjectMapper mapper = new ObjectMapper();
598             String result = mapper.writeValueAsString(resourceInstanceInput);
599             return buildOkResponse(getComponentsUtils().getResponseFormat(ActionStatus.OK), result);
600
601         } catch (Exception e) {
602             log.error("create and associate RI failed with exception: {}", e.getMessage(), e);
603             return buildErrorResponse(getComponentsUtils().getResponseFormat(ActionStatus.GENERAL_ERROR));
604         }
605
606     }
607
608     /**
609      * Updates ResourceInstance Attribute
610      *
611      * @param componentId
612      * @param containerComponentType
613      * @param componentInstanceId
614      * @param userId
615      * @param request
616      * @return
617      */
618     @POST
619     @Path("/{containerComponentType}/{componentId}/resourceInstance/{componentInstanceId}/attribute")
620     @Consumes(MediaType.APPLICATION_JSON)
621     @Produces(MediaType.APPLICATION_JSON)
622     @ApiOperation(value = "Update resource instance attribute", httpMethod = "POST", notes = "Returns updated resource instance attribute", response = Response.class)
623     @ApiResponses(value = { @ApiResponse(code = 201, message = "Resource instance created"), @ApiResponse(code = 403, message = "Restricted operation"), @ApiResponse(code = 400, message = "Invalid content / Missing content") })
624     public Response updateResourceInstanceAttribute(@ApiParam(value = "service id") @PathParam("componentId") final String componentId,
625             @ApiParam(value = "valid values: resources / services", allowableValues = ComponentTypeEnum.RESOURCE_PARAM_NAME + "," + ComponentTypeEnum.SERVICE_PARAM_NAME) @PathParam("containerComponentType") final String containerComponentType,
626             @ApiParam(value = "resource instance id") @PathParam("componentInstanceId") final String componentInstanceId, @ApiParam(value = "id of user initiating the operation") @HeaderParam(value = Constants.USER_ID_HEADER) String userId,
627             @Context final HttpServletRequest request) {
628
629         String url = request.getMethod() + " " + request.getRequestURI();
630         log.debug(START_HANDLE_REQUEST_OF, url);
631
632         try {
633
634             Wrapper<ResponseFormat> errorWrapper = new Wrapper<>();
635             Wrapper<String> dataWrapper = new Wrapper<>();
636             Wrapper<ComponentInstanceProperty> attributeWrapper = new Wrapper<>();
637             Wrapper<ComponentInstanceBusinessLogic> blWrapper = new Wrapper<>();
638
639             validateInputStream(request, dataWrapper, errorWrapper);
640
641             if (errorWrapper.isEmpty()) {
642                 validateClassParse(dataWrapper.getInnerElement(), attributeWrapper, () -> ComponentInstanceProperty.class, errorWrapper);
643             }
644
645             if (errorWrapper.isEmpty()) {
646                 validateComponentInstanceBusinessLogic(request, containerComponentType, blWrapper, errorWrapper);
647             }
648
649             if (errorWrapper.isEmpty()) {
650                 ComponentInstanceBusinessLogic componentInstanceLogic = blWrapper.getInnerElement();
651                 ComponentTypeEnum componentTypeEnum = ComponentTypeEnum.findByParamName(containerComponentType);
652                 log.debug("Start handle request of ComponentInstanceAttribute. Received attribute is {}", attributeWrapper.getInnerElement());
653                 Either<ComponentInstanceProperty, ResponseFormat> eitherAttribute = componentInstanceLogic.createOrUpdateAttributeValue(componentTypeEnum, componentId, componentInstanceId, attributeWrapper.getInnerElement(), userId);
654                 if (eitherAttribute.isRight()) {
655                     errorWrapper.setInnerElement(eitherAttribute.right().value());
656                 } else {
657                     attributeWrapper.setInnerElement(eitherAttribute.left().value());
658                 }
659             }
660
661             return buildResponseFromElement(errorWrapper, attributeWrapper);
662
663         } catch (Exception e) {
664             log.error("create and associate RI failed with exception: {}", e.getMessage(), e);
665             return buildErrorResponse(getComponentsUtils().getResponseFormat(ActionStatus.GENERAL_ERROR));
666         }
667
668     }
669
670     @DELETE
671     @Path("/{containerComponentType}/{componentId}/resourceInstance/{componentInstanceId}/property/{propertyId}")
672     @Consumes(MediaType.APPLICATION_JSON)
673     @Produces(MediaType.APPLICATION_JSON)
674     @ApiOperation(value = "Update resource instance", httpMethod = "DELETE", notes = "Returns deleted resource instance property", response = Response.class)
675     @ApiResponses(value = { @ApiResponse(code = 201, message = "Resource instance created"), @ApiResponse(code = 403, message = "Restricted operation"), @ApiResponse(code = 400, message = "Invalid content / Missing content") })
676     public Response deleteResourceInstanceProperty(@ApiParam(value = "service id") @PathParam("componentId") final String componentId,
677             @ApiParam(value = "valid values: resources / services", allowableValues = ComponentTypeEnum.RESOURCE_PARAM_NAME + "," + ComponentTypeEnum.SERVICE_PARAM_NAME) @PathParam("containerComponentType") final String containerComponentType,
678             @ApiParam(value = "resource instance id") @PathParam("componentInstanceId") final String componentInstanceId, @ApiParam(value = "property id") @PathParam("propertyId") final String propertyId,
679             @ApiParam(value = "id of user initiating the operation") @HeaderParam(value = Constants.USER_ID_HEADER) String userId, @Context final HttpServletRequest request) {
680
681         String url = request.getMethod() + " " + request.getRequestURI();
682         log.debug(START_HANDLE_REQUEST_OF, url);
683         try {
684
685             ComponentTypeEnum componentTypeEnum = ComponentTypeEnum.findByParamName(containerComponentType);
686             if (componentInstanceBusinessLogic == null) {
687                 log.debug(UNSUPPORTED_COMPONENT_TYPE, containerComponentType);
688                 return buildErrorResponse(getComponentsUtils().getResponseFormat(ActionStatus.UNSUPPORTED_ERROR, containerComponentType));
689             }
690
691             Either<ComponentInstanceProperty, ResponseFormat> actionResponse = componentInstanceBusinessLogic.deletePropertyValue(componentTypeEnum, componentId, componentInstanceId, propertyId, userId);
692             if (actionResponse.isRight()) {
693                 return buildErrorResponse(actionResponse.right().value());
694             }
695             return buildOkResponse(getComponentsUtils().getResponseFormat(ActionStatus.NO_CONTENT), null);
696         } catch (Exception e) {
697             log.error("create and associate RI failed with exception: {}", e.getMessage(), e);
698             return buildErrorResponse(getComponentsUtils().getResponseFormat(ActionStatus.GENERAL_ERROR));
699         }
700
701     }
702
703     @POST
704     @Path("/{containerComponentType}/{componentId}/resourceInstance/{componentInstanceId}/changeVersion")
705     @Consumes(MediaType.APPLICATION_JSON)
706     @Produces(MediaType.APPLICATION_JSON)
707     @ApiOperation(value = "Update resource instance", httpMethod = "POST", notes = "Returns updated resource instance", response = Response.class)
708     @ApiResponses(value = { @ApiResponse(code = 201, message = "Resource instance created"), @ApiResponse(code = 403, message = "Restricted operation"), @ApiResponse(code = 400, message = "Invalid content / Missing content") })
709     public Response changeResourceInstanceVersion(@PathParam("componentId") final String componentId, @PathParam("componentInstanceId") final String componentInstanceId,
710             @ApiParam(value = "valid values: resources / services", allowableValues = ComponentTypeEnum.RESOURCE_PARAM_NAME + "," + ComponentTypeEnum.SERVICE_PARAM_NAME) @PathParam("containerComponentType") final String containerComponentType,
711             @Context final HttpServletRequest request) {
712         ServletContext context = request.getSession().getServletContext();
713
714         String url = request.getMethod() + " " + request.getRequestURI();
715         log.debug(START_HANDLE_REQUEST_OF, url);
716         try (    InputStream inputStream = request.getInputStream()) {
717
718             byte[] bytes = IOUtils.toByteArray(inputStream);
719
720             if (bytes == null || bytes.length == 0) {
721                 log.info(EMPTY_BODY_WAS_SENT);
722                 return buildErrorResponse(getComponentsUtils().getResponseFormat(ActionStatus.INVALID_CONTENT));
723             }
724
725             String userId = request.getHeader(Constants.USER_ID_HEADER);
726
727             String data = new String(bytes);
728
729             ComponentTypeEnum componentTypeEnum = ComponentTypeEnum.findByParamName(containerComponentType);
730             if (componentInstanceBusinessLogic == null) {
731                 log.debug(UNSUPPORTED_COMPONENT_TYPE, containerComponentType);
732                 return buildErrorResponse(getComponentsUtils().getResponseFormat(ActionStatus.UNSUPPORTED_ERROR, containerComponentType));
733             }
734
735             Either<ComponentInstance, ResponseFormat> convertResponse = convertToResourceInstance(data);
736
737             if (convertResponse.isRight()) {
738                 BeEcompErrorManager.getInstance().logBeSystemError(RESOURCE_INSTANCE_UPDATE_RESOURCE_INSTANCE);
739                 log.debug(FAILED_TO_CONVERT_RECEIVED_DATA_TO_BE_FORMAT);
740                 return buildErrorResponse(convertResponse.right().value());
741             }
742
743             ComponentInstance newResourceInstance = convertResponse.left().value();
744             Either<ComponentInstance, ResponseFormat> actionResponse = componentInstanceBusinessLogic.changeComponentInstanceVersion(containerComponentType, componentId, componentInstanceId, userId, newResourceInstance);
745
746             if (actionResponse.isRight()) {
747                 return buildErrorResponse(actionResponse.right().value());
748             }
749             return buildOkResponse(getComponentsUtils().getResponseFormat(ActionStatus.OK), actionResponse.left().value());
750
751         } catch (Exception e) {
752             BeEcompErrorManager.getInstance().logBeRestApiGeneralError(UPDATE_RESOURCE_INSTANCE);
753             log.debug(UPDATE_RESOURCE_INSTANCE_WITH_EXCEPTION, e);
754             return buildErrorResponse(getComponentsUtils().getResponseFormat(ActionStatus.GENERAL_ERROR));
755         }
756
757     }
758
759     @POST
760     @Path("/{containerComponentType}/{componentId}/resourceInstance/{componentInstanceId}/groupInstance/{groupInstanceId}/property")
761     @Consumes(MediaType.APPLICATION_JSON)
762     @Produces(MediaType.APPLICATION_JSON)
763     @ApiOperation(value = "Update resource instance property", httpMethod = "POST", notes = "Returns updated resource instance property", response = Response.class)
764     @ApiResponses(value = { @ApiResponse(code = 201, message = "Resource instance created"), @ApiResponse(code = 403, message = "Restricted operation"), @ApiResponse(code = 400, message = "Invalid content / Missing content") })
765     public Response updateGroupInstanceProperty(@ApiParam(value = "service id") @PathParam("componentId") final String componentId,
766             @ApiParam(value = "valid values: resources / services", allowableValues = ComponentTypeEnum.RESOURCE_PARAM_NAME + "," + ComponentTypeEnum.SERVICE_PARAM_NAME) @PathParam("containerComponentType") final String containerComponentType,
767             @ApiParam(value = "resource instance id") @PathParam("componentInstanceId") final String componentInstanceId, @ApiParam(value = "group instance id") @PathParam("groupInstanceId") final String groupInstanceId,
768             @ApiParam(value = "id of user initiating the operation") @HeaderParam(value = Constants.USER_ID_HEADER) String userId, @Context final HttpServletRequest request) {
769
770         String url = request.getMethod() + " " + request.getRequestURI();
771         log.debug(START_HANDLE_REQUEST_OF, url);
772
773         try {
774             Wrapper<String> dataWrapper = new Wrapper<>();
775             Wrapper<ResponseFormat> errorWrapper = new Wrapper<>();
776             Wrapper<ComponentInstanceProperty> propertyWrapper = new Wrapper<>();
777
778             validateInputStream(request, dataWrapper, errorWrapper);
779
780             if (errorWrapper.isEmpty()) {
781                 validateClassParse(dataWrapper.getInnerElement(), propertyWrapper, () -> ComponentInstanceProperty.class, errorWrapper);
782             }
783
784             if (!errorWrapper.isEmpty()) {
785                 return buildErrorResponse(errorWrapper.getInnerElement());
786             }
787
788             ComponentInstanceProperty property = propertyWrapper.getInnerElement();
789
790             log.debug(START_HANDLE_REQUEST_OF_UPDATE_RESOURCE_INSTANCE_PROPERTY_RECEIVED_PROPERTY_IS, property);
791
792             ServletContext context = request.getSession().getServletContext();
793
794             ComponentTypeEnum componentTypeEnum = ComponentTypeEnum.findByParamName(containerComponentType);
795             if (componentInstanceBusinessLogic == null) {
796                 log.debug(UNSUPPORTED_COMPONENT_TYPE, containerComponentType);
797                 return buildErrorResponse(getComponentsUtils().getResponseFormat(ActionStatus.UNSUPPORTED_ERROR, containerComponentType));
798             }
799
800             Either<ComponentInstanceProperty, ResponseFormat> actionResponse = componentInstanceBusinessLogic.createOrUpdateGroupInstancePropertyValue(componentTypeEnum, componentId, componentInstanceId, groupInstanceId, property, userId);
801
802             if (actionResponse.isRight()) {
803                 return buildErrorResponse(actionResponse.right().value());
804             }
805
806             ComponentInstanceProperty resourceInstanceProperty = actionResponse.left().value();
807             ObjectMapper mapper = new ObjectMapper();
808             String result = mapper.writeValueAsString(resourceInstanceProperty);
809             return buildOkResponse(getComponentsUtils().getResponseFormat(ActionStatus.OK), result);
810
811         } catch (Exception e) {
812             log.error("create and associate RI failed with exception: {}", e.getMessage(), e);
813             return buildErrorResponse(getComponentsUtils().getResponseFormat(ActionStatus.GENERAL_ERROR));
814         }
815
816     }
817
818     @GET
819     @Path("/{containerComponentType}/{componentId}/resourceInstance/{componentInstanceId}/groupInstance/{groupInstId}")
820     @Consumes(MediaType.APPLICATION_JSON)
821     @Produces(MediaType.APPLICATION_JSON)
822     @ApiOperation(value = "Get group artifacts ", httpMethod = "GET", notes = "Returns artifacts metadata according to groupInstId", response = Resource.class)
823     @ApiResponses(value = { @ApiResponse(code = 200, message = "group found"), @ApiResponse(code = 403, message = "Restricted operation"), @ApiResponse(code = 404, message = "Group not found") })
824     public Response getGroupArtifactById(@PathParam("containerComponentType") final String containerComponentType, @PathParam("componentId") final String componentId, @PathParam("componentInstanceId") final String componentInstanceId,
825             @PathParam("groupInstId") final String groupInstId, @Context final HttpServletRequest request, @HeaderParam(value = Constants.USER_ID_HEADER) String userId) {
826         String url = request.getMethod() + " " + request.getRequestURI();
827         log.debug(GET_START_HANDLE_REQUEST_OF, url);
828
829         try {
830
831             ComponentTypeEnum componentTypeEnum = ComponentTypeEnum.findByParamName(containerComponentType);
832             Either<GroupDefinitionInfo, ResponseFormat> actionResponse = groupBL
833                 .getGroupInstWithArtifactsById(componentTypeEnum, componentId, componentInstanceId,
834                     groupInstId, userId, false);
835
836             if (actionResponse.isRight()) {
837                 log.debug("failed to get all non abstract {}", containerComponentType);
838                 return buildErrorResponse(actionResponse.right().value());
839             }
840
841             return buildOkResponse(getComponentsUtils().getResponseFormat(ActionStatus.OK), actionResponse.left().value());
842
843         } catch (Exception e) {
844             BeEcompErrorManager.getInstance().logBeRestApiGeneralError(GET_GROUP_ARTIFACT_BY_ID);
845             log.debug(GET_GROUP_ARTIFACT_BY_ID_UNEXPECTED_EXCEPTION, e);
846             return buildErrorResponse(getComponentsUtils().getResponseFormat(ActionStatus.GENERAL_ERROR));
847         }
848
849     }
850
851     // US831698
852     @GET
853     @Path("/{containerComponentType}/{containerComponentId}/componentInstances/{componentInstanceUniqueId}/properties")
854     @Consumes(MediaType.APPLICATION_JSON)
855     @Produces(MediaType.APPLICATION_JSON)
856     @ApiOperation(value = "Get component instance properties", httpMethod = "GET", notes = "Returns component instance properties", response = Response.class)
857     @ApiResponses(value = { @ApiResponse(code = 200, message = "Properties found"), @ApiResponse(code = 403, message = "Restricted operation"), @ApiResponse(code = 404, message = "Component/Component Instance - not found") })
858     public Response getInstancePropertiesById(@PathParam("containerComponentType") final String containerComponentType, @PathParam("containerComponentId") final String containerComponentId,
859             @PathParam("componentInstanceUniqueId") final String componentInstanceUniqueId, @Context final HttpServletRequest request, @HeaderParam(value = Constants.USER_ID_HEADER) String userId) {
860
861         ServletContext context = request.getSession().getServletContext();
862         String url = request.getMethod() + " " + request.getRequestURI();
863         log.debug(GET_START_HANDLE_REQUEST_OF, url);
864
865         try {
866             ComponentTypeEnum componentTypeEnum = ComponentTypeEnum.findByParamName(containerComponentType);
867
868             Either<List<ComponentInstanceProperty>, ResponseFormat> componentInstancePropertiesById = componentInstanceBusinessLogic.getComponentInstancePropertiesById(containerComponentType, containerComponentId, componentInstanceUniqueId, userId);
869
870             if (componentInstancePropertiesById.isRight()) {
871                 log.debug(FAILED_TO_GET_PROPERTIES_OF_COMPONENT_INSTANCE_ID_IN_WITH_ID, componentInstanceUniqueId, containerComponentType, containerComponentId);
872                 return buildErrorResponse(componentInstancePropertiesById.right().value());
873             }
874
875             return buildOkResponse(getComponentsUtils().getResponseFormat(ActionStatus.OK), componentInstancePropertiesById.left().value());
876         } catch (Exception e) {
877             BeEcompErrorManager.getInstance().logBeRestApiGeneralError(GET_GROUP_ARTIFACT_BY_ID);
878             log.debug(GET_GROUP_ARTIFACT_BY_ID_UNEXPECTED_EXCEPTION, e);
879             return buildErrorResponse(getComponentsUtils().getResponseFormat(ActionStatus.GENERAL_ERROR));
880         }
881
882     }
883
884     // US330353
885     @GET
886     @Path("/{containerComponentType}/{containerComponentId}/componentInstances/{componentInstanceUniqueId}/capability/{capabilityType}/capabilityName/{capabilityName}/ownerId/{ownerId}/properties")
887     @Consumes(MediaType.APPLICATION_JSON)
888     @Produces(MediaType.APPLICATION_JSON)
889     @ApiOperation(value = "Get component instance capability properties", httpMethod = "GET", notes = "Returns component instance capability properties", response = Response.class)
890     @ApiResponses(value = { @ApiResponse(code = 200, message = "Properties found"), @ApiResponse(code = 403, message = "Restricted operation"), @ApiResponse(code = 404, message = "Component/Component Instance/Capability - not found") })
891     public Response getInstanceCapabilityPropertiesById(@PathParam("containerComponentType") final String containerComponentType, @PathParam("containerComponentId") final String containerComponentId,
892             @PathParam("componentInstanceUniqueId") final String componentInstanceUniqueId, @PathParam("capabilityType") final String capabilityType, @PathParam("capabilityName") final String capabilityName,  @PathParam("ownerId") final String ownerId, @Context final HttpServletRequest request,
893             @HeaderParam(value = Constants.USER_ID_HEADER) String userId) {
894
895         ServletContext context = request.getSession().getServletContext();
896         String url = request.getMethod() + " " + request.getRequestURI();
897         log.debug(GET_START_HANDLE_REQUEST_OF, url);
898
899         try {
900             ComponentTypeEnum componentTypeEnum = ComponentTypeEnum.findByParamName(containerComponentType);
901
902             Either<List<ComponentInstanceProperty>, ResponseFormat> componentInstancePropertiesById = componentInstanceBusinessLogic.getComponentInstanceCapabilityPropertiesById(containerComponentType, containerComponentId, componentInstanceUniqueId,
903                     capabilityType, capabilityName, ownerId, userId);
904
905             if (componentInstancePropertiesById.isRight()) {
906                 log.debug(FAILED_TO_GET_PROPERTIES_OF_COMPONENT_INSTANCE_ID_IN_WITH_ID, componentInstanceUniqueId, containerComponentType, containerComponentId);
907                 return buildErrorResponse(componentInstancePropertiesById.right().value());
908             }
909
910             return buildOkResponse(getComponentsUtils().getResponseFormat(ActionStatus.OK), componentInstancePropertiesById.left().value());
911         } catch (Exception e) {
912             BeEcompErrorManager.getInstance().logBeRestApiGeneralError(GET_GROUP_ARTIFACT_BY_ID);
913             log.debug(GET_GROUP_ARTIFACT_BY_ID_UNEXPECTED_EXCEPTION, e);
914             return buildErrorResponse(getComponentsUtils().getResponseFormat(ActionStatus.GENERAL_ERROR));
915         }
916
917     }
918
919     //US 331281
920     @PUT
921     @Path("/{containerComponentType}/{containerComponentId}/componentInstances/{componentInstanceUniqueId}/capability/{capabilityType}/capabilityName/{capabilityName}/ownerId/{ownerId}/properties")
922     @Consumes(MediaType.APPLICATION_JSON)
923     @Produces(MediaType.APPLICATION_JSON)
924     @ApiOperation(value = "Update Instance Capabilty  Property", httpMethod = "PUT", notes = "Returns updated property", response = Response.class)
925     @ApiResponses(value = { @ApiResponse(code = 200, message = "Resource instance capabilty property updated"), @ApiResponse(code = 403, message = "Restricted operation"), @ApiResponse(code = 400, message = "Invalid content / Missing content"),
926             @ApiResponse(code = 404, message = "Component/Component Instance/Capability - not found") })
927     public Response updateInstanceCapabilityProperty(@PathParam("containerComponentType") final String containerComponentType, @PathParam("containerComponentId") final String containerComponentId,
928             @PathParam("componentInstanceUniqueId") final String componentInstanceUniqueId, @PathParam("capabilityType") final String capabilityType, @PathParam("capabilityName") final String capabilityName, @PathParam("ownerId") final String ownerId,
929             @ApiParam(value = "Instance capabilty property to update", required = true) String data, @Context final HttpServletRequest request, @HeaderParam(value = Constants.USER_ID_HEADER) String userId) {
930         ServletContext context = request.getSession().getServletContext();
931         String url = request.getMethod() + " " + request.getRequestURI();
932         log.debug("(PUT) Start handle request of {}", url);
933         try {
934             Wrapper<ResponseFormat> errorWrapper = new Wrapper<>();
935             List<ComponentInstanceProperty> propertiesToUpdate = new ArrayList<>();
936             if (errorWrapper.isEmpty()) {
937                 Either<List<ComponentInstanceProperty>, ResponseFormat> propertiesToUpdateEither = convertMultipleProperties(data);
938                 if (propertiesToUpdateEither.isRight()) {
939                     errorWrapper.setInnerElement(propertiesToUpdateEither.right().value());
940                 } else {
941                     propertiesToUpdate = propertiesToUpdateEither.left().value();
942                 }
943             }
944
945             if (!errorWrapper.isEmpty()) {
946                 return buildErrorResponse(errorWrapper.getInnerElement());
947             }
948
949             ComponentTypeEnum componentTypeEnum = ComponentTypeEnum.findByParamName(containerComponentType);
950
951             Either<List<ComponentInstanceProperty>, ResponseFormat> updateCICapProperty = componentInstanceBusinessLogic.updateInstanceCapabilityProperties(componentTypeEnum, containerComponentId, componentInstanceUniqueId, capabilityType, capabilityName, propertiesToUpdate, userId);
952
953             if (updateCICapProperty.isRight()) {
954                 log.debug(FAILED_TO_GET_PROPERTIES_OF_COMPONENT_INSTANCE_ID_IN_WITH_ID, componentInstanceUniqueId, containerComponentType, containerComponentId);
955                 return buildErrorResponse(updateCICapProperty.right().value());
956             }
957
958             return buildOkResponse(getComponentsUtils().getResponseFormat(ActionStatus.OK), updateCICapProperty.left().value());
959         } catch (Exception e) {
960             BeEcompErrorManager.getInstance().logBeRestApiGeneralError(GET_GROUP_ARTIFACT_BY_ID);
961             log.debug(GET_GROUP_ARTIFACT_BY_ID_UNEXPECTED_EXCEPTION, e);
962             return buildErrorResponse(getComponentsUtils().getResponseFormat(ActionStatus.GENERAL_ERROR));
963         }
964     }
965
966     @POST
967     @Path("/{containerComponentType}/{containerComponentId}/serviceProxy")
968     @Consumes(MediaType.APPLICATION_JSON)
969     @Produces(MediaType.APPLICATION_JSON)
970     @ApiOperation(value = "Create service proxy", httpMethod = "POST", notes = "Returns created service proxy", response = Response.class)
971     @ApiResponses(value = { @ApiResponse(code = 201, message = "Service proxy created"), @ApiResponse(code = 403, message = "Restricted operation"), @ApiResponse(code = 400, message = "Invalid content / Missing content"),
972             @ApiResponse(code = 409, message = "Service proxy already exist") })
973     public Response createServiceProxy(@ApiParam(value = "RI object to be created", required = true) String data, @PathParam("containerComponentId") final String containerComponentId,
974             @ApiParam(value = "valid values: resources / services", allowableValues = ComponentTypeEnum.RESOURCE_PARAM_NAME + "," + ComponentTypeEnum.SERVICE_PARAM_NAME) @PathParam("containerComponentType") final String containerComponentType,
975             @HeaderParam(value = Constants.USER_ID_HEADER) @ApiParam(value = "USER_ID of modifier user", required = true) String userId, @Context final HttpServletRequest request) {
976         ServletContext context = request.getSession().getServletContext();
977
978         try {
979
980             ComponentInstance componentInstance = RepresentationUtils.fromRepresentation(data, ComponentInstance.class);
981             componentInstance.setInvariantName(null);
982             ComponentTypeEnum componentTypeEnum = ComponentTypeEnum.findByParamName(containerComponentType);
983             if (componentTypeEnum != ComponentTypeEnum.SERVICE) {
984                 log.debug("Unsupported container component type {}", containerComponentType);
985                 return buildErrorResponse(getComponentsUtils().getResponseFormat(ActionStatus.UNSUPPORTED_ERROR, containerComponentType));
986             }
987             if (componentInstanceBusinessLogic == null) {
988                 log.debug(UNSUPPORTED_COMPONENT_TYPE, containerComponentType);
989                 return buildErrorResponse(getComponentsUtils().getResponseFormat(ActionStatus.UNSUPPORTED_ERROR, containerComponentType));
990             }
991             Either<ComponentInstance, ResponseFormat> actionResponse = componentInstanceBusinessLogic.createServiceProxy();
992
993             if (actionResponse.isRight()) {
994                 return buildErrorResponse(actionResponse.right().value());
995             }
996             return buildOkResponse(getComponentsUtils().getResponseFormat(ActionStatus.CREATED), actionResponse.left().value());
997
998         } catch (Exception e) {
999             BeEcompErrorManager.getInstance().logBeRestApiGeneralError("Create service proxy");
1000             log.debug("Create service proxy failed with exception", e);
1001             return buildErrorResponse(getComponentsUtils().getResponseFormat(ActionStatus.GENERAL_ERROR));
1002         }
1003     }
1004
1005     @DELETE
1006     @Path("/{containerComponentType}/{containerComponentId}/serviceProxy/{serviceProxyId}")
1007     @Consumes(MediaType.APPLICATION_JSON)
1008     @Produces(MediaType.APPLICATION_JSON)
1009     @ApiOperation(value = "Delete service proxy", httpMethod = "DELETE", notes = "Returns delete service proxy", response = Response.class)
1010     @ApiResponses(value = { @ApiResponse(code = 201, message = "Service proxy deleted"), @ApiResponse(code = 403, message = "Restricted operation"), @ApiResponse(code = 400, message = "Invalid content / Missing content") })
1011     public Response deleteServiceProxy(@PathParam("containerComponentId") final String containerComponentId, @PathParam("serviceProxyId") final String serviceProxyId,
1012             @ApiParam(value = "valid values: resources / services / products", allowableValues = ComponentTypeEnum.RESOURCE_PARAM_NAME + "," + ComponentTypeEnum.SERVICE_PARAM_NAME + ","
1013                     + ComponentTypeEnum.PRODUCT_PARAM_NAME) @PathParam("containerComponentType") final String containerComponentType,
1014             @Context final HttpServletRequest request) {
1015         ServletContext context = request.getSession().getServletContext();
1016         String url = request.getMethod() + " " + request.getRequestURI();
1017         Response response = null;
1018         try {
1019             log.debug(START_HANDLE_REQUEST_OF, url);
1020             ComponentTypeEnum componentTypeEnum = ComponentTypeEnum.findByParamName(containerComponentType);
1021             if (componentInstanceBusinessLogic == null) {
1022                 log.debug(UNSUPPORTED_COMPONENT_TYPE, containerComponentType);
1023                 return buildErrorResponse(getComponentsUtils().getResponseFormat(ActionStatus.UNSUPPORTED_ERROR, containerComponentType));
1024             }
1025             String userId = request.getHeader(Constants.USER_ID_HEADER);
1026             Either<ComponentInstance, ResponseFormat> actionResponse = componentInstanceBusinessLogic.deleteServiceProxy();
1027
1028             if (actionResponse.isRight()) {
1029                 response = buildErrorResponse(actionResponse.right().value());
1030             } else {
1031                 response = buildOkResponse(getComponentsUtils().getResponseFormat(ActionStatus.NO_CONTENT), null);
1032             }
1033             return response;
1034         } catch (Exception e) {
1035             BeEcompErrorManager.getInstance().logBeRestApiGeneralError("Delete service proxy");
1036             log.debug("Delete service proxy failed with exception", e);
1037             return buildErrorResponse(getComponentsUtils().getResponseFormat(ActionStatus.GENERAL_ERROR));
1038         }
1039     }
1040
1041     @POST
1042     @Path("/{containerComponentType}/{containerComponentId}/serviceProxy/{serviceProxyId}/changeVersion/{newServiceId}")
1043     @Consumes(MediaType.APPLICATION_JSON)
1044     @Produces(MediaType.APPLICATION_JSON)
1045     @ApiOperation(value = "Update service proxy with new version", httpMethod = "POST", notes = "Returns updated service proxy", response = Response.class)
1046     @ApiResponses(value = { @ApiResponse(code = 201, message = "Service proxy created"), @ApiResponse(code = 403, message = "Restricted operation"), @ApiResponse(code = 400, message = "Invalid content / Missing content") })
1047     public Response changeServiceProxyVersion(@PathParam("containerComponentId") final String containerComponentId, @PathParam("serviceProxyId") final String serviceProxyId,
1048             @ApiParam(value = "valid values: resources / services", allowableValues = ComponentTypeEnum.RESOURCE_PARAM_NAME + "," + ComponentTypeEnum.SERVICE_PARAM_NAME) @PathParam("containerComponentType") final String containerComponentType,
1049             @Context final HttpServletRequest request) {
1050         ServletContext context = request.getSession().getServletContext();
1051
1052         String url = request.getMethod() + " " + request.getRequestURI();
1053         log.debug(START_HANDLE_REQUEST_OF, url);
1054         try {
1055
1056             String userId = request.getHeader(Constants.USER_ID_HEADER);
1057
1058             ComponentTypeEnum componentTypeEnum = ComponentTypeEnum.findByParamName(containerComponentType);
1059             if (componentInstanceBusinessLogic == null) {
1060                 log.debug(UNSUPPORTED_COMPONENT_TYPE, containerComponentType);
1061                 return buildErrorResponse(getComponentsUtils().getResponseFormat(ActionStatus.UNSUPPORTED_ERROR, containerComponentType));
1062             }
1063             Either<ComponentInstance, ResponseFormat> actionResponse = componentInstanceBusinessLogic.changeServiceProxyVersion();
1064
1065             if (actionResponse.isRight()) {
1066                 return buildErrorResponse(actionResponse.right().value());
1067             }
1068             return buildOkResponse(getComponentsUtils().getResponseFormat(ActionStatus.OK), actionResponse.left().value());
1069
1070         } catch (Exception e) {
1071             BeEcompErrorManager.getInstance().logBeRestApiGeneralError("Update service proxy with new version");
1072             log.debug("Update service proxy with new version failed with exception", e);
1073             return buildErrorResponse(getComponentsUtils().getResponseFormat(ActionStatus.GENERAL_ERROR));
1074         }
1075     }
1076     /**
1077      * REST API GET relation by Id
1078      * Allows to get relation contained in specified component according to received Id
1079      * @param containerComponentType
1080      * @param componentId
1081      * @param relationId
1082      * @param request
1083      * @param userId
1084      * @return Response
1085      */
1086     @GET
1087     @Path("/{containerComponentType}/{componentId}/relationId/{relationId}")
1088     @Consumes(MediaType.APPLICATION_JSON)
1089     @Produces(MediaType.APPLICATION_JSON)
1090     @ApiOperation(value = "Get relation", httpMethod = "GET", notes = "Returns relation metadata according to relationId", response = Resource.class)
1091     @ApiResponses(value = { @ApiResponse(code = 200, message = "relation found"), @ApiResponse(code = 403, message = "Restricted operation"), @ApiResponse(code = 404, message = "Relation not found") })
1092     public Response getRelationById(@PathParam("containerComponentType") final String containerComponentType, @PathParam("componentId") final String componentId,
1093             @PathParam("relationId") final String relationId, @Context final HttpServletRequest request, @HeaderParam(value = Constants.USER_ID_HEADER) String userId) {
1094
1095         ServletContext context = request.getSession().getServletContext();
1096         String url = request.getMethod() + " " + request.getRequestURI();
1097         log.debug(GET_START_HANDLE_REQUEST_OF, url);
1098         try {
1099             ComponentTypeEnum componentTypeEnum = ComponentTypeEnum.findByParamName(containerComponentType);
1100             if (componentTypeEnum == null) {
1101                 log.debug(UNSUPPORTED_COMPONENT_TYPE, containerComponentType);
1102                 return buildErrorResponse(getComponentsUtils().getResponseFormat(ActionStatus.UNSUPPORTED_ERROR, containerComponentType));
1103             }
1104
1105             Either<RequirementCapabilityRelDef, ResponseFormat> actionResponse = componentInstanceBusinessLogic.getRelationById(componentId, relationId, userId, componentTypeEnum);
1106             if (actionResponse.isRight()) {
1107                 return buildErrorResponse(actionResponse.right().value());
1108             }
1109             return buildOkResponse(getComponentsUtils().getResponseFormat(ActionStatus.OK), actionResponse.left().value());
1110         } catch (Exception e) {
1111             BeEcompErrorManager.getInstance().logBeRestApiGeneralError("getRelationById");
1112             log.debug("getRelationById unexpected exception", e);
1113             return buildErrorResponse(getComponentsUtils().getResponseFormat(ActionStatus.GENERAL_ERROR));
1114         }
1115     }
1116
1117     private Either<ComponentInstance, ResponseFormat> convertToResourceInstance(String data) {
1118
1119         Either<ComponentInstance, ResponseFormat> convertStatus = getComponentsUtils().convertJsonToObjectUsingObjectMapper(data, new User(), ComponentInstance.class, null, ComponentTypeEnum.RESOURCE_INSTANCE);
1120         if (convertStatus.isRight()) {
1121             return Either.right(convertStatus.right().value());
1122         }
1123         ComponentInstance resourceInstanceInfo = convertStatus.left().value();
1124
1125         return Either.left(resourceInstanceInfo);
1126     }
1127
1128     private Either<List<ComponentInstance>, ResponseFormat> convertToMultipleResourceInstance(String dataList) {
1129
1130         Either<ComponentInstance[], ResponseFormat> convertStatus = getComponentsUtils().convertJsonToObjectUsingObjectMapper(dataList, new User(), ComponentInstance[].class, null, ComponentTypeEnum.RESOURCE_INSTANCE);
1131         if (convertStatus.isRight()) {
1132             return Either.right(convertStatus.right().value());
1133         }
1134
1135         return Either.left(Arrays.asList(convertStatus.left().value()));
1136     }
1137
1138     private Either<List<ComponentInstanceProperty>, ResponseFormat> convertMultipleProperties(String dataList) {
1139         if (StringUtils.isEmpty(dataList)) {
1140             return Either.right(getComponentsUtils().getResponseFormat(ActionStatus.INVALID_CONTENT));
1141         }
1142         Either<ComponentInstanceProperty[], ResponseFormat> convertStatus = getComponentsUtils().convertJsonToObjectUsingObjectMapper(dataList, new User(), ComponentInstanceProperty[].class, null, ComponentTypeEnum.RESOURCE_INSTANCE);
1143         if (convertStatus.isRight()) {
1144             return Either.right(convertStatus.right().value());
1145         }
1146         return Either.left(Arrays.asList(convertStatus.left().value()));
1147     }
1148
1149     private Either<List<ComponentInstanceInput>, ResponseFormat> convertMultipleInputs(String dataList) {
1150         if (StringUtils.isEmpty(dataList)) {
1151             return Either.right(getComponentsUtils().getResponseFormat(ActionStatus.INVALID_CONTENT));
1152         }
1153         Either<ComponentInstanceInput[], ResponseFormat> convertStatus = getComponentsUtils().convertJsonToObjectUsingObjectMapper(dataList, new User(), ComponentInstanceInput[].class, null, ComponentTypeEnum.RESOURCE_INSTANCE);
1154         if (convertStatus.isRight()) {
1155             return Either.right(convertStatus.right().value());
1156         }
1157         return Either.left(Arrays.asList(convertStatus.left().value()));
1158     }
1159
1160
1161     private Either<RequirementCapabilityRelDef, ResponseFormat> convertToRequirementCapabilityRelDef(String data) {
1162
1163         Either<RequirementCapabilityRelDef, ActionStatus> convertStatus = convertJsonToObject(data, RequirementCapabilityRelDef.class);
1164         if (convertStatus.isRight()) {
1165             return Either.right(getComponentsUtils().getResponseFormat(convertStatus.right().value()));
1166         }
1167         RequirementCapabilityRelDef requirementCapabilityRelDef = convertStatus.left().value();
1168         return Either.left(requirementCapabilityRelDef);
1169     }
1170
1171     public  <T> Either<T, ActionStatus> convertJsonToObject(String data, Class<T> clazz) {
1172         try {
1173             log.trace("convert json to object. json=\n {}", data);
1174             T t;
1175             t = gsonDeserializer.fromJson(data, clazz);
1176             if (t == null) {
1177                 BeEcompErrorManager.getInstance().logBeInvalidJsonInput("convertJsonToObject");
1178                 log.debug("object is null after converting from json");
1179                 return Either.right(ActionStatus.INVALID_CONTENT);
1180             }
1181             return Either.left(t);
1182         } catch (Exception e) {
1183             // INVALID JSON
1184             BeEcompErrorManager.getInstance().logBeInvalidJsonInput("convertJsonToObject");
1185             log.debug("failed to convert from json", e);
1186             return Either.right(ActionStatus.INVALID_CONTENT);
1187         }
1188     }
1189
1190
1191     @GET
1192     @Path("/{containerComponentType}/{componentId}/paths-to-delete")
1193     @Produces(MediaType.APPLICATION_JSON)
1194     @ApiOperation(value = "Check if forwarding path to delete on version change", httpMethod = "GET", notes = "Returns forwarding paths to delete",
1195         response = Response.class)
1196     public Response changeResourceInstanceVersion( @PathParam("componentId") String componentId,
1197         @QueryParam("componentInstanceId") final String oldComponentInstanceId,
1198         @QueryParam("newComponentInstanceId") final String newComponentInstanceId,
1199         @ApiParam(value = "valid values: resources / services",
1200             allowableValues = ComponentTypeEnum.RESOURCE_PARAM_NAME + "," + ComponentTypeEnum.SERVICE_PARAM_NAME)
1201         @PathParam("containerComponentType") final String containerComponentType,
1202         @Context final HttpServletRequest request) {
1203         if (oldComponentInstanceId == null){
1204             return  buildErrorResponse(getComponentsUtils().getResponseFormat(ActionStatus.MISSING_OLD_COMPONENT_INSTANCE));
1205         }
1206         if (newComponentInstanceId == null){
1207             return  buildErrorResponse(getComponentsUtils().getResponseFormat(ActionStatus.MISSING_NEW_COMPONENT_INSTANCE));
1208         }
1209         ServletContext context = request.getSession().getServletContext();
1210
1211         String url = request.getMethod() + " " + request.getRequestURI();
1212         log.debug(START_HANDLE_REQUEST_OF, url);
1213         ComponentTypeEnum componentTypeEnum = ComponentTypeEnum.findByParamName(containerComponentType);
1214         if (componentInstanceBusinessLogic == null) {
1215             log.debug(UNSUPPORTED_COMPONENT_TYPE, containerComponentType);
1216             return buildErrorResponse(getComponentsUtils().getResponseFormat(ActionStatus.UNSUPPORTED_ERROR, containerComponentType));
1217         }
1218         ComponentInstance newComponentInstance;
1219         if(StringUtils.isNotEmpty(newComponentInstanceId)){
1220             newComponentInstance=new ComponentInstance();
1221             newComponentInstance.setToscaPresentationValue(JsonPresentationFields.CI_COMPONENT_UID,newComponentInstanceId);
1222         }else{
1223             log.error("missing component id");
1224             return buildErrorResponse(getComponentsUtils().getResponseFormat(ActionStatus.MISSING_DATA));
1225         }
1226         Either<Set<String>,ResponseFormat> actionResponse= componentInstanceBusinessLogic.forwardingPathOnVersionChange(
1227             containerComponentType,componentId,oldComponentInstanceId,newComponentInstance);
1228         if (actionResponse.isRight()) {
1229             return buildErrorResponse(actionResponse.right().value());
1230         }
1231         ForwardingPaths forwardingPaths=new ForwardingPaths();
1232         forwardingPaths.setForwardingPathToDelete(actionResponse.left().value());
1233         return buildOkResponse(getComponentsUtils().getResponseFormat(ActionStatus.OK), forwardingPaths);
1234
1235     }
1236
1237     @POST
1238     @Path("/services/{componentId}/copyComponentInstance/{componentInstanceId}")
1239     @Consumes(MediaType.APPLICATION_JSON)
1240     @Produces((MediaType.APPLICATION_JSON))
1241     @ApiOperation(value = "Copy Component Instance", httpMethod = "POST", notes = "Returns updated service information", response = Service.class)
1242     @ApiResponses(value = {
1243             @ApiResponse(code = 201, message = "Copy and Paste Success"),
1244             @ApiResponse(code = 403, message = "Restricted Operation"),
1245             @ApiResponse(code = 400, message = "Invalid Content / Missing content")})
1246     public Response copyComponentInstance(
1247             @ApiParam(value = "service unique id in pasted canvas") @PathParam("componentId") final String containerComponentId,
1248             @ApiParam(value = "Data for copying", required = true) String data, @PathParam("componentInstanceId") final String componentInstanceId,
1249             @Context final HttpServletRequest request) {
1250         log.info("Start to copy component instance");
1251         ServletContext context = request.getSession().getServletContext();
1252         String userId = request.getHeader(Constants.USER_ID_HEADER);
1253         final String CNTAINER_CMPT_TYPE = "services";
1254
1255         try {
1256             ComponentInstance inputComponentInstance = RepresentationUtils.fromRepresentation(data, ComponentInstance.class);
1257             inputComponentInstance.setInvariantName(null);
1258             ComponentTypeEnum componentTypeEnum = ComponentTypeEnum.findByParamName(CNTAINER_CMPT_TYPE);
1259             if (componentInstanceBusinessLogic == null) {
1260                 log.debug(UNSUPPORTED_COMPONENT_TYPE, componentTypeEnum);
1261                 return buildErrorResponse(getComponentsUtils().getResponseFormat(ActionStatus.UNSUPPORTED_ERROR, "services"));
1262             }
1263             Either<Map<String, ComponentInstance>, ResponseFormat> copyComponentInstance = componentInstanceBusinessLogic.copyComponentInstance(
1264                     inputComponentInstance, containerComponentId, componentInstanceId, userId);
1265
1266             if (copyComponentInstance.isRight()) {
1267                 log.error("Failed to copy ComponentInstance {}", copyComponentInstance.right().value());
1268                 return buildErrorResponse(copyComponentInstance.right().value());
1269             }
1270
1271             return buildOkResponse(getComponentsUtils().getResponseFormat(ActionStatus.OK),
1272                     copyComponentInstance.left().value());
1273         } catch (Exception e) {
1274             log.error("Failed to convert json to Map { }", data, e);
1275             return buildErrorResponse(getComponentsUtils().getResponseFormat(ActionStatus.USER_DEFINED,
1276                     "Failed to get the copied component instance information"));
1277         }
1278     }
1279
1280     @POST
1281     @Path("/{containerComponentType}/{componentId}/batchDeleteResourceInstances/")
1282     @Consumes(MediaType.APPLICATION_JSON)
1283     @Produces(MediaType.APPLICATION_JSON)
1284     @ApiOperation(value = "Batch Delete ResourceInstances", httpMethod = "POST")
1285     @ApiResponses(value = {
1286             @ApiResponse(code = 203, message = "ResourceInstances deleted"),
1287             @ApiResponse(code = 403, message = "Restricted Operation"),
1288             @ApiResponse(code = 400, message = "Invalid Content / Missing Content")
1289     })
1290     public Response batchDeleteResourceInstances(
1291             @ApiParam(value = "valid values: resources / services / products", allowableValues = ComponentTypeEnum.RESOURCE_PARAM_NAME + "," + ComponentTypeEnum.SERVICE_PARAM_NAME + "," +
1292                     ComponentTypeEnum.PRODUCT_PARAM_NAME)
1293             @PathParam("containerComponentType") final String containerComponentType,
1294             @PathParam("componentId") final String componentId,
1295             @Context final HttpServletRequest request,
1296             @ApiParam(value = "Component Instance Id List", required = true) final String componentInstanceIdLisStr) {
1297         try {
1298             if (componentInstanceIdLisStr == null || componentInstanceIdLisStr.isEmpty()) {
1299                 log.error("Empty JSON List was sent",componentInstanceIdLisStr);
1300                 return buildErrorResponse(getComponentsUtils().getResponseFormat(ActionStatus.INVALID_CONTENT));
1301             }
1302
1303
1304             if (componentInstanceBusinessLogic == null) {
1305                 log.error("Unsupported component type {}", containerComponentType);
1306                 return buildErrorResponse(getComponentsUtils().getResponseFormat(ActionStatus.UNSUPPORTED_ERROR, containerComponentType));
1307             }
1308
1309             Either<List<String>, ResponseFormat> convertResponse = convertToStringList(componentInstanceIdLisStr);
1310
1311             if (convertResponse.isRight()) {
1312                 BeEcompErrorManager.getInstance().logBeSystemError("Resource Instance - batchDeleteResourceInstances");
1313                 log.error("Failed to convert received data to BE format.");
1314                 return buildErrorResponse(convertResponse.right().value());
1315             }
1316
1317             String userId = request.getHeader(Constants.USER_ID_HEADER);
1318             List<String> componentInstanceIdList = convertResponse.left().value();
1319             log.debug("batchDeleteResourceInstances componentInstanceIdList is {}", componentInstanceIdList);
1320             Map<String, List<String>> deleteErrorMap = componentInstanceBusinessLogic.batchDeleteComponentInstance(containerComponentType,
1321                     componentId, componentInstanceIdList, userId);
1322
1323             return buildOkResponse(getComponentsUtils().getResponseFormat(ActionStatus.OK), deleteErrorMap);
1324         } catch (Exception e) {
1325             BeEcompErrorManager.getInstance().logBeRestApiGeneralError("Batch Delete ResourceInstances");
1326             log.error("batch delete resource instances with exception" , e);
1327             return buildErrorResponse(getComponentsUtils().getResponseFormat(ActionStatus.GENERAL_ERROR));
1328         }
1329
1330     }
1331
1332     @PUT
1333     @Path("/{containerComponentType}/{componentId}/resourceInstance/batchDissociate")
1334     @Consumes(MediaType.APPLICATION_JSON)
1335     @Produces(MediaType.APPLICATION_JSON)
1336     @ApiOperation(value = "Batch Dissociate RI from RI", httpMethod = "PUT", notes = "Returns deleted RelationShip Info", response = Response.class)
1337     @ApiResponses(value = {
1338             @ApiResponse(code = 201, message = "Relationship deleted"),
1339             @ApiResponse(code = 403, message = "Missing Information"),
1340             @ApiResponse(code = 400, message = "Invalid Content / Missing Content")
1341     })
1342     public Response batchDissociateRIFromRI(
1343             @ApiParam(value = "allowed values are resources/services/products", allowableValues = ComponentTypeEnum.RESOURCE_PARAM_NAME + "," + ComponentTypeEnum.SERVICE_PARAM_NAME + "," + ComponentTypeEnum.PRODUCT_PARAM_NAME, required = true)
1344             @PathParam("containerComponentType") final String containerComponentType,
1345             @ApiParam(value = "unique id of the container component")
1346             @PathParam("componentId") final String componentId,
1347             @HeaderParam(value = Constants.USER_ID_HEADER) String userId,
1348             @ApiParam(value = "RelationshipInfo", required = true) String data,
1349             @Context final HttpServletRequest request) {
1350
1351         try {
1352             if (data == null || data.length() == 0) {
1353                 log.info("Empty JSON list was sent");
1354                 return buildErrorResponse(getComponentsUtils().getResponseFormat(ActionStatus.INVALID_CONTENT));
1355             }
1356
1357             ComponentTypeEnum componentTypeEnum = ComponentTypeEnum.findByParamName(containerComponentType);
1358
1359             if (componentInstanceBusinessLogic == null) {
1360                 log.debug("Unsupported component type {}", containerComponentType);
1361                 return buildErrorResponse(getComponentsUtils().getResponseFormat(ActionStatus.UNSUPPORTED_ERROR, containerComponentType));
1362             }
1363
1364             Either<List<RequirementCapabilityRelDef>, ResponseFormat> regInfoWs = convertToRequirementCapabilityRelDefList(data);
1365
1366             if (regInfoWs.isRight()) {
1367                 BeEcompErrorManager.getInstance().logBeSystemError("Resource Instance - batch dissociateRIFromRI");
1368                 log.debug("Failed to convert received data to BE format");
1369                 return buildErrorResponse(regInfoWs.right().value());
1370             }
1371
1372             List<RequirementCapabilityRelDef> requirementDefList = regInfoWs.left().value();
1373             List<RequirementCapabilityRelDef> delOkResult = componentInstanceBusinessLogic.batchDissociateRIFromRI(
1374                     componentId, userId, requirementDefList, componentTypeEnum);
1375
1376             return buildOkResponse(getComponentsUtils().getResponseFormat(ActionStatus.OK), delOkResult);
1377         } catch (Exception e) {
1378             BeEcompErrorManager.getInstance().logBeRestApiGeneralError("Batch Dissociate Resource Instance");
1379             log.debug("batch dissociate resource instance from service failed with exception", e);
1380             return buildErrorResponse(getComponentsUtils().getResponseFormat(ActionStatus.GENERAL_ERROR));
1381         }
1382     }
1383
1384     private Either<List<String>, ResponseFormat> convertToStringList(String datalist) {
1385         Either<String[], ResponseFormat> convertStatus = getComponentsUtils().convertJsonToObjectUsingObjectMapper(datalist, new User(), String[].class, null, null);
1386
1387         if (convertStatus.isRight()) {
1388             return Either.right(convertStatus.right().value());
1389         }
1390
1391         return Either.left(Arrays.asList(convertStatus.left().value()));
1392     }
1393
1394     private Either<List<RequirementCapabilityRelDef>, ResponseFormat> convertToRequirementCapabilityRelDefList(String data) {
1395         Either<RequirementCapabilityRelDef[], ResponseFormat> convertStatus = getComponentsUtils().convertJsonToObjectUsingObjectMapper(data, new User(), RequirementCapabilityRelDef[].class, null, null);
1396
1397         if (convertStatus.isRight()) {
1398             return Either.right(convertStatus.right().value());
1399         }
1400
1401         return Either.left(Arrays.asList(convertStatus.left().value()));
1402     }
1403
1404 }