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