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