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