Catalog alignment
[sdc.git] / catalog-be / src / main / java / org / openecomp / sdc / be / servlets / ResourcesServlet.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.jcabi.aspects.Loggable;
24 import fj.data.Either;
25 import io.swagger.v3.oas.annotations.OpenAPIDefinition;
26 import io.swagger.v3.oas.annotations.Operation;
27 import io.swagger.v3.oas.annotations.Parameter;
28 import io.swagger.v3.oas.annotations.info.Info;
29 import io.swagger.v3.oas.annotations.media.ArraySchema;
30 import io.swagger.v3.oas.annotations.media.Content;
31 import io.swagger.v3.oas.annotations.media.Schema;
32 import io.swagger.v3.oas.annotations.responses.ApiResponse;
33 import io.swagger.v3.oas.annotations.responses.ApiResponses;
34 import org.apache.http.HttpStatus;
35 import org.json.JSONException;
36 import org.json.JSONObject;
37 import org.openecomp.sdc.be.components.impl.ComponentInstanceBusinessLogic;
38 import org.openecomp.sdc.be.components.impl.CsarValidationUtils;
39 import org.openecomp.sdc.be.components.impl.ImportUtils;
40 import org.openecomp.sdc.be.components.impl.ResourceBusinessLogic;
41 import org.openecomp.sdc.be.components.impl.ResourceImportManager;
42 import org.openecomp.sdc.be.components.impl.aaf.AafPermission;
43 import org.openecomp.sdc.be.components.impl.aaf.PermissionAllowed;
44 import org.openecomp.sdc.be.config.BeEcompErrorManager;
45 import org.openecomp.sdc.be.dao.api.ActionStatus;
46 import org.openecomp.sdc.be.datamodel.api.HighestFilterEnum;
47 import org.openecomp.sdc.be.datatypes.enums.ComponentTypeEnum;
48 import org.openecomp.sdc.be.datatypes.enums.ResourceTypeEnum;
49 import org.openecomp.sdc.be.impl.ComponentsUtils;
50 import org.openecomp.sdc.be.impl.ServletUtils;
51 import org.openecomp.sdc.be.model.Resource;
52 import org.openecomp.sdc.be.model.UploadResourceInfo;
53 import org.openecomp.sdc.be.model.User;
54 import org.openecomp.sdc.be.resources.data.auditing.AuditingActionEnum;
55 import org.openecomp.sdc.be.servlets.ResourceUploadServlet.ResourceAuthorityTypeEnum;
56 import org.openecomp.sdc.be.user.UserBusinessLogic;
57 import org.openecomp.sdc.common.api.Constants;
58 import org.openecomp.sdc.common.datastructure.Wrapper;
59 import org.openecomp.sdc.common.log.elements.LoggerSupportability;
60 import org.openecomp.sdc.common.log.enums.LoggerSupportabilityActions;
61 import org.openecomp.sdc.common.log.enums.StatusCode;
62 import org.openecomp.sdc.common.log.wrappers.Logger;
63 import org.openecomp.sdc.common.zip.exception.ZipException;
64 import org.openecomp.sdc.exception.ResponseFormat;
65 import org.springframework.stereotype.Controller;
66
67 import javax.inject.Inject;
68 import javax.servlet.ServletContext;
69 import javax.servlet.http.HttpServletRequest;
70 import javax.ws.rs.Consumes;
71 import javax.ws.rs.DELETE;
72 import javax.ws.rs.GET;
73 import javax.ws.rs.HeaderParam;
74 import javax.ws.rs.POST;
75 import javax.ws.rs.PUT;
76 import javax.ws.rs.Path;
77 import javax.ws.rs.PathParam;
78 import javax.ws.rs.Produces;
79 import javax.ws.rs.QueryParam;
80 import javax.ws.rs.core.Context;
81 import javax.ws.rs.core.MediaType;
82 import javax.ws.rs.core.Response;
83 import java.io.IOException;
84 import java.util.List;
85 import java.util.Map;
86
87 @Loggable(prepend = true, value = Loggable.DEBUG, trim = false)
88 @Path("/v1/catalog")
89 @OpenAPIDefinition(info = @Info(title = "Resources Catalog", description = "Resources Servlet"))
90 @Controller
91 public class ResourcesServlet extends AbstractValidationsServlet {
92
93     private static final Logger log = Logger.getLogger(ResourcesServlet.class);
94     private static final LoggerSupportability loggerSupportability = LoggerSupportability.getLogger(ResourcesServlet.class.getName());
95     private static final String START_HANDLE_REQUEST_OF = "Start handle request of {}";
96     private static final String MODIFIER_ID_IS = "modifier id is {}";
97     private final ResourceBusinessLogic resourceBusinessLogic;
98
99     @Inject
100     public ResourcesServlet(UserBusinessLogic userBusinessLogic,
101         ComponentInstanceBusinessLogic componentInstanceBL,
102         ResourceBusinessLogic resourceBusinessLogic,
103         ComponentsUtils componentsUtils, ServletUtils servletUtils,
104         ResourceImportManager resourceImportManager) {
105         super(userBusinessLogic, componentInstanceBL, componentsUtils, servletUtils, resourceImportManager);
106         this.resourceBusinessLogic = resourceBusinessLogic;
107     }
108
109     @POST
110     @Path("/resources")
111     @Consumes(MediaType.APPLICATION_JSON)
112     @Produces(MediaType.APPLICATION_JSON)
113     @Operation(description = "Create Resource", method = "POST", summary = "Returns created resource",
114             responses = @ApiResponse(
115                     content = @Content(array = @ArraySchema(schema = @Schema(implementation = Resource.class)))))
116     @ApiResponses(value = {@ApiResponse(responseCode = "201", description = "Resource created"),
117             @ApiResponse(responseCode = "403", description = "Restricted operation"),
118             @ApiResponse(responseCode = "400", description = "Invalid content / Missing content"),
119             @ApiResponse(responseCode = "409", description = "Resource already exist")})
120     @PermissionAllowed(AafPermission.PermNames.INTERNAL_ALL_VALUE)
121     public Response createResource(@Parameter(description = "Resource object to be created", required = true) String data,
122             @Context final HttpServletRequest request, @HeaderParam(value = Constants.USER_ID_HEADER) String userId) throws IOException, ZipException {
123
124         userId = (userId != null) ? userId : request.getHeader(Constants.USER_ID_HEADER);
125         init();
126
127         String url = request.getMethod() + " " + request.getRequestURI();
128         log.debug(START_HANDLE_REQUEST_OF, url);
129         // get modifier id
130         User modifier = new User();
131         modifier.setUserId(userId);
132         log.debug(MODIFIER_ID_IS, userId);
133         loggerSupportability.log(LoggerSupportabilityActions.CREATE_RESOURCE, StatusCode.STARTED,"Starting to create Resource by user {}",userId);
134         Response response;
135         try {
136
137             Wrapper<Response> responseWrapper = new Wrapper<>();
138             // UI Import
139             if (isUIImport(data)) {
140                 performUIImport(responseWrapper, data, request, userId, null);
141             }
142             // UI Create
143             else {
144
145                 Either<Resource, ResponseFormat> convertResponse = parseToResource(data, modifier);
146                 if (convertResponse.isRight()) {
147                     log.debug("failed to parse resource");
148                     response = buildErrorResponse(convertResponse.right().value());
149                     return response;
150                 }
151
152                 Resource resource = convertResponse.left().value();
153                 Resource createdResource = resourceBusinessLogic.createResource(resource, AuditingActionEnum.CREATE_RESOURCE, modifier, null, null);
154                 Object representation = RepresentationUtils.toRepresentation(createdResource);
155                 response = buildOkResponse(getComponentsUtils().getResponseFormat(ActionStatus.CREATED), representation);
156                 responseWrapper.setInnerElement(response);
157                 loggerSupportability.log(LoggerSupportabilityActions.CREATE_RESOURCE,resource.getComponentMetadataForSupportLog() ,StatusCode.COMPLETE,"Resource successfully created user {}",userId);
158             }
159             return responseWrapper.getInnerElement();
160         } catch (final IOException | ZipException e) {
161             BeEcompErrorManager.getInstance().logBeRestApiGeneralError("Create Resource");
162             log.debug("create resource failed with exception", e);
163             throw e;
164         }
165     }
166
167     private boolean isUIImport(String data) {
168         boolean isUIImport;
169         try {
170             JSONObject json = new JSONObject(data);
171             String payloadName = json.getString(ImportUtils.Constants.UI_JSON_PAYLOAD_NAME);
172             isUIImport = payloadName != null && !payloadName.isEmpty();
173         } catch (JSONException e) {
174             log.debug("failed to parse json sent from client, json:{}", data, e);
175             isUIImport = false;
176         }
177         return isUIImport;
178     }
179
180     private void performUIImport(final Wrapper<Response> responseWrapper, final String data,
181                                  final HttpServletRequest request, final String userId,
182                                  final String resourceUniqueId) throws ZipException {
183         Wrapper<User> userWrapper = new Wrapper<>();
184         Wrapper<UploadResourceInfo> uploadResourceInfoWrapper = new Wrapper<>();
185         Wrapper<String> yamlStringWrapper = new Wrapper<>();
186
187         ResourceAuthorityTypeEnum resourceAuthorityEnum = ResourceAuthorityTypeEnum.USER_TYPE_UI;
188
189         commonGeneralValidations(responseWrapper, userWrapper, uploadResourceInfoWrapper, resourceAuthorityEnum, userId, data);
190
191         if (!CsarValidationUtils.isCsarPayloadName(uploadResourceInfoWrapper.getInnerElement().getPayloadName())) {
192             fillPayload(responseWrapper, uploadResourceInfoWrapper, yamlStringWrapper, userWrapper.getInnerElement(), data, resourceAuthorityEnum, null);
193
194             // PayLoad Validations
195             commonPayloadValidations(responseWrapper, yamlStringWrapper, userWrapper.getInnerElement(), uploadResourceInfoWrapper.getInnerElement());
196         }
197         specificResourceAuthorityValidations(responseWrapper, uploadResourceInfoWrapper, yamlStringWrapper, userWrapper.getInnerElement(), request, data, resourceAuthorityEnum);
198
199         if (responseWrapper.isEmpty()) {
200             handleImport(responseWrapper, userWrapper.getInnerElement(), uploadResourceInfoWrapper.getInnerElement(), yamlStringWrapper.getInnerElement(), resourceAuthorityEnum, true, resourceUniqueId);
201         }
202     }
203
204     private Either<Resource, ResponseFormat> parseToResource(String resourceJson, User user) {
205         return getComponentsUtils().convertJsonToObjectUsingObjectMapper(resourceJson, user, Resource.class, AuditingActionEnum.CREATE_RESOURCE, ComponentTypeEnum.RESOURCE);
206     }
207
208     private Either<Resource, ResponseFormat> parseToLightResource(String resourceJson, User user) {
209         Either<Resource, ResponseFormat> ret = getComponentsUtils().convertJsonToObjectUsingObjectMapper(resourceJson, user, Resource.class, AuditingActionEnum.UPDATE_RESOURCE_METADATA, ComponentTypeEnum.RESOURCE);
210         if (ret.isLeft()) {// drop unwanted data (sent from UI in update flow)
211             ret.left().value().setRequirements(null);
212             ret.left().value().setCapabilities(null);
213         }
214         return ret;
215     }
216
217     @DELETE
218     @Path("/resources/{resourceId}")
219     @PermissionAllowed(AafPermission.PermNames.INTERNAL_ALL_VALUE)
220     public Response deleteResource(@PathParam("resourceId") final String resourceId, @Context final HttpServletRequest request) {
221
222         String url = request.getMethod() + " " + request.getRequestURI();
223         log.debug(START_HANDLE_REQUEST_OF, url);
224         // get modifier id
225         String userId = request.getHeader(Constants.USER_ID_HEADER);
226         User modifier = new User();
227         modifier.setUserId(userId);
228         log.debug(MODIFIER_ID_IS, userId);
229         loggerSupportability.log(LoggerSupportabilityActions.DELETE_RESOURCE ,StatusCode.STARTED,"Starting to delete Resource by user {}",userId);
230         Response response;
231
232         try {
233             String resourceIdLower = resourceId.toLowerCase();
234             ResponseFormat actionResponse = resourceBusinessLogic.deleteResource(resourceIdLower, modifier);
235
236             if (actionResponse.getStatus() != HttpStatus.SC_NO_CONTENT) {
237                 log.debug("failed to delete resource");
238                 response = buildErrorResponse(actionResponse);
239                 return response;
240             }
241             response = buildOkResponse(getComponentsUtils().getResponseFormat(ActionStatus.NO_CONTENT), null);
242             loggerSupportability.log(LoggerSupportabilityActions.DELETE_RESOURCE ,StatusCode.COMPLETE,"Ended delete Resource by user {}",userId);
243             return response;
244
245         } catch (JSONException e) {
246             BeEcompErrorManager.getInstance().logBeRestApiGeneralError("Delete Resource");
247             log.debug("delete resource failed with exception", e);
248             throw e;
249         }
250     }
251
252     @DELETE
253     @Path("/resources/{resourceName}/{version}")
254     @Operation(description = "Delete Resource By Name And Version", method = "DELETE", summary = "Returns no content", responses = @ApiResponse(
255             content = @Content(array = @ArraySchema(schema = @Schema(implementation = Resource.class)))))
256     @ApiResponses(value = { @ApiResponse(responseCode = "204", description = "Resource deleted"),
257             @ApiResponse(responseCode = "403", description = "Restricted operation"),
258             @ApiResponse(responseCode = "400", description = "Invalid content / Missing content"),
259             @ApiResponse(responseCode = "404", description = "Resource not found") })
260     @PermissionAllowed(AafPermission.PermNames.INTERNAL_ALL_VALUE)
261     public Response deleteResourceByNameAndVersion(@PathParam("resourceName") final String resourceName, @PathParam("version") final String version, @Context final HttpServletRequest request) {
262
263         ServletContext context = request.getSession().getServletContext();
264
265         String url = request.getMethod() + " " + request.getRequestURI();
266         log.debug(START_HANDLE_REQUEST_OF, url);
267
268         // get modifier id
269         String userId = request.getHeader(Constants.USER_ID_HEADER);
270         User modifier = new User();
271         modifier.setUserId(userId);
272         log.debug(MODIFIER_ID_IS, userId);
273
274         Response response;
275         ResourceBusinessLogic businessLogic = getResourceBL(context);
276         ResponseFormat actionResponse = businessLogic.deleteResourceByNameAndVersion(resourceName, version, modifier);
277
278         if (actionResponse.getStatus() != HttpStatus.SC_NO_CONTENT) {
279             log.debug("failed to delete resource");
280             response = buildErrorResponse(actionResponse);
281             return response;
282         }
283         response = buildOkResponse(getComponentsUtils().getResponseFormat(ActionStatus.NO_CONTENT), null);
284         return response;
285     }
286
287     @GET
288     @Path("/resources/{resourceId}")
289     @Consumes(MediaType.APPLICATION_JSON)
290     @Produces(MediaType.APPLICATION_JSON)
291     @Operation(description = "Retrieve Resource", method = "GET", summary = "Returns resource according to resourceId",
292             responses = @ApiResponse(
293                     content = @Content(array = @ArraySchema(schema = @Schema(implementation = Resource.class)))))
294     @ApiResponses(value = {@ApiResponse(responseCode = "200", description = "Resource found"),
295             @ApiResponse(responseCode = "403", description = "Restricted operation"),
296             @ApiResponse(responseCode = "404", description = "Resource not found")})
297     @PermissionAllowed(AafPermission.PermNames.INTERNAL_ALL_VALUE)
298     public Response getResourceById(@PathParam("resourceId") final String resourceId,
299             @Context final HttpServletRequest request, @HeaderParam(value = Constants.USER_ID_HEADER) String userId) throws IOException {
300
301         ServletContext context = request.getSession().getServletContext();
302
303         String url = request.getMethod() + " " + request.getRequestURI();
304         log.debug(START_HANDLE_REQUEST_OF, url);
305
306         // get modifier id
307         User modifier = new User();
308         modifier.setUserId(userId);
309         log.debug(MODIFIER_ID_IS, userId);
310
311         Response response;
312
313         try {
314             String resourceIdLower = resourceId.toLowerCase();
315             log.trace("get resource with id {}", resourceId);
316             Either<Resource, ResponseFormat> actionResponse = resourceBusinessLogic.getResource(resourceIdLower, modifier);
317
318             if (actionResponse.isRight()) {
319                 log.debug("failed to get resource");
320                 response = buildErrorResponse(actionResponse.right().value());
321                 return response;
322             }
323             Object resource = RepresentationUtils.toRepresentation(actionResponse.left().value());
324             return buildOkResponse(getComponentsUtils().getResponseFormat(ActionStatus.OK), resource);
325
326         } catch (IOException e) {
327             BeEcompErrorManager.getInstance().logBeRestApiGeneralError("Get Resource");
328             log.debug("get resource failed with exception", e);
329             throw e;
330         }
331     }
332
333     @GET
334     @Path("/resources/resourceName/{resourceName}/resourceVersion/{resourceVersion}")
335     @Consumes(MediaType.APPLICATION_JSON)
336     @Produces(MediaType.APPLICATION_JSON)
337     @Operation(description = "Retrieve Resource by name and version", method = "GET",
338             summary = "Returns resource according to resourceId", responses = @ApiResponse(
339                     content = @Content(array = @ArraySchema(schema = @Schema(implementation = Resource.class)))))
340     @ApiResponses(value = {@ApiResponse(responseCode = "200", description = "Resource found"),
341             @ApiResponse(responseCode = "403", description = "Restricted operation"),
342             @ApiResponse(responseCode = "404", description = "Resource not found")})
343     @PermissionAllowed(AafPermission.PermNames.INTERNAL_ALL_VALUE)
344     public Response getResourceByNameAndVersion(@PathParam("resourceName") final String resourceName,
345                                                 @PathParam("resourceVersion") final String resourceVersion, @Context final HttpServletRequest request,
346                                                 @HeaderParam(value = Constants.USER_ID_HEADER) String userId) throws IOException {
347
348         // get modifier id
349         User modifier = new User();
350         modifier.setUserId(userId);
351         log.debug(MODIFIER_ID_IS, userId);
352         Response response;
353         try {
354             Either<Resource, ResponseFormat> actionResponse = resourceBusinessLogic.getResourceByNameAndVersion(resourceName, resourceVersion, userId);
355             if (actionResponse.isRight()) {
356                 response = buildErrorResponse(actionResponse.right().value());
357                 return response;
358             }
359             Object resource = RepresentationUtils.toRepresentation(actionResponse.left().value());
360             return buildOkResponse(getComponentsUtils().getResponseFormat(ActionStatus.OK), resource);
361
362         } catch (IOException e) {
363             BeEcompErrorManager.getInstance().logBeRestApiGeneralError("Get Resource by name and version");
364             log.debug("get resource failed with exception", e);
365             throw e;
366         }
367     }
368
369     @GET
370     @Path("/resources/validate-name/{resourceName}")
371     @Consumes(MediaType.APPLICATION_JSON)
372     @Produces(MediaType.APPLICATION_JSON)
373     @Operation(description = "validate resource name", method = "GET",
374             summary = "checks if the chosen resource name is available ", responses = @ApiResponse(
375                     content = @Content(array = @ArraySchema(schema = @Schema(implementation = Resource.class)))))
376     @ApiResponses(value = {@ApiResponse(responseCode = "200", description = "Resource found"),
377             @ApiResponse(responseCode = "403", description = "Restricted operation")})
378     @PermissionAllowed(AafPermission.PermNames.INTERNAL_ALL_VALUE)
379     public Response validateResourceName(@PathParam("resourceName") final String resourceName,
380             @QueryParam("subtype") String resourceType, @Context final HttpServletRequest request,
381             @HeaderParam(value = Constants.USER_ID_HEADER) String userId) {
382         String url = request.getMethod() + " " + request.getRequestURI();
383         log.debug(START_HANDLE_REQUEST_OF, url);
384
385         // get modifier id
386         User modifier = new User();
387         modifier.setUserId(userId);
388         log.debug(MODIFIER_ID_IS, userId);
389         Response response;
390
391         if (resourceType != null && !ResourceTypeEnum.containsName(resourceType)) {
392             log.debug("invalid resource type received");
393             response = buildErrorResponse(getComponentsUtils().getResponseFormat(ActionStatus.INVALID_CONTENT));
394             return response;
395
396         }
397         ResourceTypeEnum typeEnum = null;
398         if (resourceType != null) {
399             typeEnum = ResourceTypeEnum.valueOf(resourceType);
400         }
401         Either<Map<String, Boolean>, ResponseFormat> actionResponse = resourceBusinessLogic.validateResourceNameExists(resourceName, typeEnum, userId);
402
403         if (actionResponse.isRight()) {
404             log.debug("failed to validate resource name");
405             response = buildErrorResponse(actionResponse.right().value());
406             return response;
407         }
408         return buildOkResponse(getComponentsUtils().getResponseFormat(ActionStatus.OK), actionResponse.left().value());
409     }
410
411     @GET
412     @Path("/resources/certified/abstract")
413     @Consumes(MediaType.APPLICATION_JSON)
414     @Produces(MediaType.APPLICATION_JSON)
415     @PermissionAllowed(AafPermission.PermNames.INTERNAL_ALL_VALUE)
416     public Response getCertifiedAbstractResources(@Context final HttpServletRequest request, @HeaderParam(value = Constants.USER_ID_HEADER) String userId) throws IOException {
417         String url = request.getMethod() + " " + request.getRequestURI();
418         log.debug("(get) Start handle request of {}" , url);
419         try {
420             List<Resource> resources = resourceBusinessLogic
421                     .getAllCertifiedResources(true, HighestFilterEnum.HIGHEST_ONLY, userId);
422             return buildOkResponse(getComponentsUtils().getResponseFormat(ActionStatus.OK), RepresentationUtils.toRepresentation(resources));
423
424         } catch (IOException e) {
425             BeEcompErrorManager.getInstance().logBeRestApiGeneralError("Get Certified Abstract Resources");
426             log.debug("getCertifiedAbstractResources failed with exception", e);
427             throw e;
428         }
429     }
430
431     @GET
432     @Path("/resources/certified/notabstract")
433     @Consumes(MediaType.APPLICATION_JSON)
434     @Produces(MediaType.APPLICATION_JSON)
435     @PermissionAllowed(AafPermission.PermNames.INTERNAL_ALL_VALUE)
436     public Response getCertifiedNotAbstractResources(@Context final HttpServletRequest request, @HeaderParam(value = Constants.USER_ID_HEADER) String userId) throws IOException {
437         String url = request.getMethod() + " " + request.getRequestURI();
438         log.debug("(get) Start handle request of {}" , url);
439         try {
440             List<Resource> resouces = resourceBusinessLogic.getAllCertifiedResources(false, HighestFilterEnum.ALL, userId);
441             return buildOkResponse(getComponentsUtils().getResponseFormat(ActionStatus.OK), RepresentationUtils.toRepresentation(resouces));
442
443         } catch (IOException e) {
444             BeEcompErrorManager.getInstance().logBeRestApiGeneralError("Get Certified Non Abstract Resources");
445             log.debug("getCertifiedNotAbstractResources failed with exception", e);
446             throw e;
447         }
448
449     }
450
451     @PUT
452     @Path("/resources/{resourceId}/metadata")
453     @Consumes(MediaType.APPLICATION_JSON)
454     @Produces(MediaType.APPLICATION_JSON)
455     @Operation(description = "Update Resource Metadata", method = "PUT", summary = "Returns updated resource metadata",
456             responses = @ApiResponse(
457                     content = @Content(array = @ArraySchema(schema = @Schema(implementation = Resource.class)))))
458     @ApiResponses(value = {@ApiResponse(responseCode = "200", description = "Resource metadata updated"),
459             @ApiResponse(responseCode = "403", description = "Restricted operation"),
460             @ApiResponse(responseCode = "400", description = "Invalid content")})
461     @PermissionAllowed(AafPermission.PermNames.INTERNAL_ALL_VALUE)
462     public Response updateResourceMetadata(@PathParam("resourceId") final String resourceId,
463             @Parameter(description = "Resource metadata to be updated", required = true) String data,
464             @Context final HttpServletRequest request,       @HeaderParam(value = Constants.USER_ID_HEADER) String userId) throws IOException {
465
466         String url = request.getMethod() + " " + request.getRequestURI();
467         log.debug(START_HANDLE_REQUEST_OF, url);
468
469         // get modifier id
470         User modifier = new User();
471         modifier.setUserId(userId);
472         log.debug(MODIFIER_ID_IS, userId);
473         Response response;
474         try {
475             String resourceIdLower = resourceId.toLowerCase();
476             Either<Resource, ResponseFormat> updateInfoResource = getComponentsUtils().convertJsonToObjectUsingObjectMapper(data, modifier, Resource.class, AuditingActionEnum.UPDATE_RESOURCE_METADATA, ComponentTypeEnum.RESOURCE);
477             if (updateInfoResource.isRight()) {
478                 log.debug("failed to parse resource metadata");
479                 response = buildErrorResponse(updateInfoResource.right().value());
480                 return response;
481             }
482             Resource updatedResource = resourceBusinessLogic.updateResourceMetadata(resourceIdLower, updateInfoResource.left().value(), null, modifier, false);
483             Object resource = RepresentationUtils.toRepresentation(updatedResource);
484             return buildOkResponse(getComponentsUtils().getResponseFormat(ActionStatus.OK), resource);
485         } catch (IOException e) {
486             BeEcompErrorManager.getInstance().logBeRestApiGeneralError("Update Resource Metadata");
487             log.debug("Update Resource Metadata failed with exception", e);
488             throw e;
489         }
490     }
491
492     @PUT
493     @Path("/resources/{resourceId}")
494     @Consumes(MediaType.APPLICATION_JSON)
495     @Produces(MediaType.APPLICATION_JSON)
496     @Operation(description = "Update Resource", method = "PUT", summary = "Returns updated resource",
497             responses = @ApiResponse(
498                     content = @Content(array = @ArraySchema(schema = @Schema(implementation = Resource.class)))))
499     @ApiResponses(value = {@ApiResponse(responseCode = "200", description = "Resource updated"),
500             @ApiResponse(responseCode = "403", description = "Restricted operation"),
501             @ApiResponse(responseCode = "400", description = "Invalid content / Missing content"),
502             @ApiResponse(responseCode = "409", description = "Resource already exist")})
503     @PermissionAllowed(AafPermission.PermNames.INTERNAL_ALL_VALUE)
504     public Response updateResource(
505             @Parameter(description = "Resource object to be updated", required = true) String data,
506             @Context final HttpServletRequest request, @HeaderParam(value = Constants.USER_ID_HEADER) String userId,
507             @PathParam(value = "resourceId") String resourceId) throws IOException, ZipException {
508
509         userId = (userId != null) ? userId : request.getHeader(Constants.USER_ID_HEADER);
510         init();
511         String url = request.getMethod() + " " + request.getRequestURI();
512         log.debug(START_HANDLE_REQUEST_OF, url);
513         // get modifier id
514         User modifier = new User();
515         modifier.setUserId(userId);
516         log.debug(MODIFIER_ID_IS, userId);
517         loggerSupportability.log(LoggerSupportabilityActions.UPDATE_RESOURCE,StatusCode.STARTED,"Starting to update a resource by user {}",userId);
518         Response response;
519         try {
520             Wrapper<Response> responseWrapper = new Wrapper<>();
521             // UI Import
522             if (isUIImport(data)) {
523                 performUIImport(responseWrapper, data, request, userId, resourceId);
524             } else {
525                 Either<Resource, ResponseFormat> convertResponse = parseToLightResource(data, modifier);
526                 if (convertResponse.isRight()) {
527                     log.debug("failed to parse resource");
528                     response = buildErrorResponse(convertResponse.right().value());
529                     return response;
530                 }
531                 Resource updatedResource = resourceBusinessLogic.validateAndUpdateResourceFromCsar(convertResponse.left().value(), modifier, null, null, resourceId);
532                 Object representation = RepresentationUtils.toRepresentation(updatedResource);
533                 response = buildOkResponse(getComponentsUtils().getResponseFormat(ActionStatus.OK), representation);
534                 responseWrapper.setInnerElement(response);
535                 loggerSupportability.log(LoggerSupportabilityActions.UPDATE_RESOURCE,updatedResource.getComponentMetadataForSupportLog(),StatusCode.COMPLETE,"Ended update a resource by user {}",userId);
536
537             }
538             return responseWrapper.getInnerElement();
539         } catch (final IOException | ZipException e) {
540             BeEcompErrorManager.getInstance().logBeRestApiGeneralError("Update Resource");
541             log.debug("update resource failed with exception", e);
542             throw e;
543         }
544     }
545
546     @GET
547     @Path("/resources/csar/{csaruuid}")
548     @Consumes(MediaType.APPLICATION_JSON)
549     @Produces(MediaType.APPLICATION_JSON)
550     @Operation(description = "Create Resource", method = "POST", summary = "Returns resource created from csar uuid",
551             responses = @ApiResponse(
552                     content = @Content(array = @ArraySchema(schema = @Schema(implementation = Resource.class)))))
553     @ApiResponses(value = {@ApiResponse(responseCode = "201", description = "Resource retrieced"),
554             @ApiResponse(responseCode = "403", description = "Restricted operation"),
555             @ApiResponse(responseCode = "400", description = "Invalid content / Missing content")})
556     @PermissionAllowed(AafPermission.PermNames.INTERNAL_ALL_VALUE)
557     public Response getResourceFromCsar(@Context final HttpServletRequest request,
558             @HeaderParam(value = Constants.USER_ID_HEADER) String userId,
559             @PathParam(value = "csaruuid") String csarUUID) throws IOException {
560
561         init();
562
563         String url = request.getMethod() + " " + request.getRequestURI();
564         log.debug(START_HANDLE_REQUEST_OF, url);
565
566         // retrieve user details
567         userId = (userId != null) ? userId : request.getHeader(Constants.USER_ID_HEADER);
568         User user = new User();
569         user.setUserId(userId);
570
571         log.debug("user id is {}", userId);
572
573         Response response;
574
575         try {
576
577             Either<Resource, ResponseFormat> eitherResource =
578                     resourceBusinessLogic.getLatestResourceFromCsarUuid(csarUUID, user);
579
580             // validate response
581             if (eitherResource.isRight()) {
582                 log.debug("failed to get resource from csarUuid : {}", csarUUID);
583                 response = buildOkResponse(getComponentsUtils().getResponseFormat(ActionStatus.OK), eitherResource.right().value());
584             } else {
585                 Object representation = RepresentationUtils.toRepresentation(eitherResource.left().value());
586                 response = buildOkResponse(getComponentsUtils().getResponseFormat(ActionStatus.OK), representation);
587             }
588
589             return response;
590
591         } catch (IOException e) {
592             log.debug("get resource by csar failed with exception", e);
593             throw e;
594         }
595     }
596 }