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