From e8b17db10adb43fd7ba991d818f60efbbb426119 Mon Sep 17 00:00:00 2001 From: Amine Mouhoub Date: Mon, 15 Jan 2024 03:02:58 +0100 Subject: [PATCH] Add import package feature --- .../resources/archives/package.zip | Bin 0 -> 6583 bytes .../controller/CatalogObjectController.java | 184 +++++++++++------- .../catalog/service/CatalogObjectService.java | 48 ++++- .../catalog/util/ArchiveManagerHelper.java | 29 ++- .../util/PackageMetadataJSONParser.java | 19 +- .../util/ArchiveManagerHelperTest.java | 25 --- 6 files changed, 200 insertions(+), 105 deletions(-) create mode 100644 src/integration-test/resources/archives/package.zip diff --git a/src/integration-test/resources/archives/package.zip b/src/integration-test/resources/archives/package.zip new file mode 100644 index 0000000000000000000000000000000000000000..5c9cbbf887d0c1861780fd90f253b3fb55f3ed70 GIT binary patch literal 6583 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 list( @Parameter(description = "Include only objects whose last commit belong to the given user.") @RequestParam(value = "lastCommitBy", required = false) Optional lastCommitBy, @Parameter(description = "Include only objects whose last commit time is greater than the given EPOCH time.") @RequestParam(value = "lastCommitTimeGreater", required = false) Optional lastCommitTimeGreater, @Parameter(description = "Include only objects whose last commit time is less than the given EPOCH time.") @RequestParam(value = "lastCommitTimeLessThan", required = false) Optional lastCommitTimeLessThan, - @Parameter(description = "Give a list of name separated by comma to get them in an archive", array = @ArraySchema(schema = @Schema())) @RequestParam(value = "listObjectNamesForArchive", required = false) Optional> names, @Parameter(description = "Page number", required = false) @RequestParam(defaultValue = "0", value = "pageNo") int pageNo, @Parameter(description = "Page size", required = false) @RequestParam(defaultValue = MAXVALUE + "", value = "pageSize") int pageSize, @@ -428,74 +427,69 @@ public ResponseEntity> list( objectTagFilter = objectTagFilter.filter(s -> !s.isEmpty()); projectNameFilter = projectNameFilter.filter(s -> !s.isEmpty()); lastCommitBy = lastCommitBy.filter(s -> !s.isEmpty()); - if (names.isPresent()) { - ZipArchiveContent content = catalogObjectService.getCatalogObjectsAsZipArchive(bucketName, names.get()); - return getResponseAsArchive(content, response); - } else { - List metadataList = catalogObjectService.listCatalogObjects(Collections.singletonList(bucketName), - kind, - contentType, - objectNameFilter, - objectTagFilter, - projectNameFilter, - lastCommitBy, - lastCommitTimeGreater, - lastCommitTimeLessThan, - pageNo, - pageSize); - - if (sessionIdRequired && !isPublicBucket.get()) { - // remove all objects that the user shouldn't have access according to the grants specification. - GrantRightsService.removeInaccessibleObjectsInBucket(metadataList, bucketGrants, catalogObjectsGrants); - } + List metadataList = catalogObjectService.listCatalogObjects(Collections.singletonList(bucketName), + kind, + contentType, + objectNameFilter, + objectTagFilter, + projectNameFilter, + lastCommitBy, + lastCommitTimeGreater, + lastCommitTimeLessThan, + pageNo, + pageSize); + + if (sessionIdRequired && !isPublicBucket.get()) { + // remove all objects that the user shouldn't have access according to the grants specification. + GrantRightsService.removeInaccessibleObjectsInBucket(metadataList, bucketGrants, catalogObjectsGrants); + } - Optional userSpecificBucketRights = GrantHelper.filterFirstUserSpecificGrant(bucketGrants) - .map(BucketGrantMetadata::getAccessType); - for (CatalogObjectMetadata catalogObject : metadataList) { - catalogObject.add(LinkUtil.createLink(bucketName, catalogObject.getName())); - catalogObject.add(LinkUtil.createRelativeLink(bucketName, catalogObject.getName())); - if (sessionIdRequired) { - List objectsGrants = GrantHelper.filterObjectGrants(catalogObjectsGrants, - catalogObject.getName()); - catalogObject.setRights(GrantRightsService.getCatalogObjectRights(isPublicBucket.get(), - bucketRights.toString(), - userSpecificBucketRights, - objectsGrants)); - } - } - Optional associatedObjectsByBucketOptional = Optional.empty(); + Optional userSpecificBucketRights = GrantHelper.filterFirstUserSpecificGrant(bucketGrants) + .map(BucketGrantMetadata::getAccessType); + for (CatalogObjectMetadata catalogObject : metadataList) { + catalogObject.add(LinkUtil.createLink(bucketName, catalogObject.getName())); + catalogObject.add(LinkUtil.createRelativeLink(bucketName, catalogObject.getName())); if (sessionIdRequired) { - List associatedObjectsByBucketList = jobPlannerService.getAssociatedObjects(sessionId); - associatedObjectsByBucketOptional = associatedObjectsByBucketList.stream() - .filter(object -> bucketName.equals(object.getBucketName())) - .findFirst(); - if (associatedObjectsByBucketOptional.isPresent()) { - AssociatedObjectsByBucket associatedObjects = associatedObjectsByBucketOptional.get(); - for (CatalogObjectMetadata catalogObject : metadataList) { - AssociatedObject associatedObject = associatedObjects.findAssociatedObject(catalogObject.getName()); - addAssociationStatus(catalogObject, associatedObject); - } + List objectsGrants = GrantHelper.filterObjectGrants(catalogObjectsGrants, + catalogObject.getName()); + catalogObject.setRights(GrantRightsService.getCatalogObjectRights(isPublicBucket.get(), + bucketRights.toString(), + userSpecificBucketRights, + objectsGrants)); + } + } + Optional associatedObjectsByBucketOptional = Optional.empty(); + if (sessionIdRequired) { + List associatedObjectsByBucketList = jobPlannerService.getAssociatedObjects(sessionId); + associatedObjectsByBucketOptional = associatedObjectsByBucketList.stream() + .filter(object -> bucketName.equals(object.getBucketName())) + .findFirst(); + if (associatedObjectsByBucketOptional.isPresent()) { + AssociatedObjectsByBucket associatedObjects = associatedObjectsByBucketOptional.get(); + for (CatalogObjectMetadata catalogObject : metadataList) { + AssociatedObject associatedObject = associatedObjects.findAssociatedObject(catalogObject.getName()); + addAssociationStatus(catalogObject, associatedObject); } } - if (sessionIdRequired && associationStatusFilter.isPresent()) { - if (!associatedObjectsByBucketOptional.isPresent()) { - if (!UNPLANNED.equalsIgnoreCase(associationStatusFilter.get())) { - return ResponseEntity.ok(Collections.emptyList()); - } - // if UNPLANNED and no objects are associated, we return the full list - } else { - AssociatedObjectsByBucket associatedObjectsByBucket = associatedObjectsByBucketOptional.get(); - - metadataList = metadataList.stream() - .filter(metadata -> isAssociatedInJobPlanner(metadata, - associationStatusFilter.get(), - associatedObjectsByBucket)) - .collect(Collectors.toList()); + } + if (sessionIdRequired && associationStatusFilter.isPresent()) { + if (!associatedObjectsByBucketOptional.isPresent()) { + if (!UNPLANNED.equalsIgnoreCase(associationStatusFilter.get())) { + return ResponseEntity.ok(Collections.emptyList()); } + // if UNPLANNED and no objects are associated, we return the full list + } else { + AssociatedObjectsByBucket associatedObjectsByBucket = associatedObjectsByBucketOptional.get(); + + metadataList = metadataList.stream() + .filter(metadata -> isAssociatedInJobPlanner(metadata, + associationStatusFilter.get(), + associatedObjectsByBucket)) + .collect(Collectors.toList()); } - Collections.sort(metadataList); - return ResponseEntity.ok(metadataList); } + Collections.sort(metadataList); + return ResponseEntity.ok(metadataList); } @Operation(summary = "Export catalog objects as a ProActive Package", description = "Export catalog objects as a ProActive Package containing the selected objects or contents of the selected bucket along with a METADATA.json describing the exported objects.
Note: Returns catalog objects metadata associated to the latest revision.") @@ -504,9 +498,10 @@ public ResponseEntity> list( @ApiResponse(responseCode = "401", description = "User not authenticated"), @ApiResponse(responseCode = "403", description = "Permission denied") }) @RequestMapping(value = REQUEST_API_QUERY + "/export", method = GET) - public ResponseEntity> exportAsPackage( + public ResponseEntity> exportCatalogObjects( @Parameter(description = "sessionID") @RequestHeader(value = "sessionID", required = false) String sessionId, @PathVariable String bucketName, + @Parameter(description = "Plain zip instead of a Proactive package") @RequestParam(value = "isPlainZip", required = false, defaultValue = "false") boolean isPlainZip, @Parameter(description = "Give a list of name separated by comma to get them in an archive", array = @ArraySchema(schema = @Schema())) @RequestParam(value = "objectNamesList", required = false) Optional> names, HttpServletResponse response) throws NotAuthenticatedException, AccessDeniedException { @@ -518,7 +513,11 @@ public ResponseEntity> exportAsPackage( ZipArchiveContent content; if (names.isPresent()) { - content = catalogObjectService.getCatalogObjectsAsPackageZipArchive(bucketName, names.get()); + if (isPlainZip) { + content = catalogObjectService.getCatalogObjectsAsZipArchive(bucketName, names.get()); + } else { + content = catalogObjectService.getCatalogObjectsAsPackageZipArchive(bucketName, names.get()); + } } else { List metadataList = catalogObjectService.listCatalogObjects(Collections.singletonList(bucketName), Optional.empty(), @@ -539,11 +538,66 @@ public ResponseEntity> exportAsPackage( List objectNames = metadataList.stream() .map(CatalogObjectMetadata::getName) .collect(Collectors.toList()); - content = catalogObjectService.getCatalogObjectsAsPackageZipArchive(bucketName, objectNames); + if (isPlainZip) { + content = catalogObjectService.getCatalogObjectsAsZipArchive(bucketName, objectNames); + } else { + content = catalogObjectService.getCatalogObjectsAsPackageZipArchive(bucketName, objectNames); + } } return getResponseAsArchive(content, response); } + @Operation(summary = "Import a ProActive package") + @ApiResponses(value = { @ApiResponse(responseCode = "404", description = "Bucket not found"), + @ApiResponse(responseCode = "422", description = "Invalid file content supplied") }) + @RequestMapping(value = REQUEST_API_QUERY + + "/import", consumes = { MediaType.MULTIPART_FORM_DATA_VALUE }, method = POST) + @ResponseStatus(HttpStatus.CREATED) + public CatalogObjectMetadataList importAsPackage( + @Parameter(description = "sessionID", required = true) @RequestHeader(value = "sessionID") String sessionId, + @Parameter(description = "The name of the existing Bucket", required = true, schema = @Schema(pattern = BucketNameValidator.VALID_BUCKET_NAME_PATTERN)) @PathVariable String bucketName, + @Parameter(description = "Project of the package objects") @RequestParam(value = "projectName", required = false, defaultValue = "") Optional projectName, + @Parameter(description = "List of comma separated tags of the objects", schema = @Schema(pattern = TagsValidator.TAGS_PATTERN)) @RequestParam(value = "tags", required = false, defaultValue = "") Optional tags, + @Parameter(description = "The ProActive package zip file", required = true) @RequestPart(value = "file") MultipartFile file) + throws IOException, NotAuthenticatedException, AccessDeniedException { + + // Check Grants + AuthenticatedUser user = null; + String initiator = ANONYMOUS; + if (sessionIdRequired) { + // Check session validation + if (!restApiAccessService.isSessionActive(sessionId)) { + throw new AccessDeniedException("Session id is not active. Please login."); + } + user = restApiAccessService.getUserFromSessionId(sessionId); + if (!AccessTypeHelper.satisfy(grantRightsService.getBucketRights(user, bucketName), write)) { + throw new BucketGrantAccessException(bucketName); + } + } + + String userName = ""; + if (user != null) { + userName = user.getName(); + initiator = userName; + } + CatalogObjectMetadataList catalogObjectMetadataList; + + List catalogObjects = catalogObjectService.createCatalogObjectsFromPackage(bucketName, + userName, + projectName.orElse(""), + tags.orElse(""), + file.getBytes()); + + for (CatalogObjectMetadata catalogObject : catalogObjects) { + catalogObject.add(LinkUtil.createLink(bucketName, catalogObject.getName())); + catalogObject.add(LinkUtil.createRelativeLink(bucketName, catalogObject.getName())); + } + + catalogObjectMetadataList = new CatalogObjectMetadataList(catalogObjects); + log.info(ACTION + initiator + " created new catalog objects from archive inside bucket " + bucketName); + return catalogObjectMetadataList; + } + private void checkBucketGrants(String sessionId, String bucketName, List catalogObjectsGrants, List bucketGrants, StringBuilder bucketRights, AtomicBoolean isPublicBucket) { diff --git a/src/main/java/org/ow2/proactive/catalog/service/CatalogObjectService.java b/src/main/java/org/ow2/proactive/catalog/service/CatalogObjectService.java index a88a923b02..9eac6d587f 100644 --- a/src/main/java/org/ow2/proactive/catalog/service/CatalogObjectService.java +++ b/src/main/java/org/ow2/proactive/catalog/service/CatalogObjectService.java @@ -58,6 +58,7 @@ import org.ow2.proactive.catalog.util.ArchiveManagerHelper; import org.ow2.proactive.catalog.util.ArchiveManagerHelper.FileNameAndContent; import org.ow2.proactive.catalog.util.ArchiveManagerHelper.ZipArchiveContent; +import org.ow2.proactive.catalog.util.PackageMetadataJSONParser; import org.ow2.proactive.catalog.util.RevisionCommitMessageBuilder; import org.ow2.proactive.catalog.util.SeparatorUtility; import org.ow2.proactive.catalog.util.name.validator.KindAndContentTypeValidator; @@ -202,6 +203,47 @@ public List createCatalogObjects(String bucketName, Strin }).collect(Collectors.toList()); } + @Transactional + public List createCatalogObjectsFromPackage(String bucketName, String username, + String projectName, String tags, byte[] zipArchive) { + + PackageMetadataJSONParser.PackageData metadata = ArchiveManagerHelper.extractMetadataObject(bucketName, + zipArchive); + + List objectsList = new ArrayList<>(); + BucketEntity bucketEntity = findBucketByNameAndCheck(bucketName); + + metadata.getCatalog().getObjects().forEach(object -> { + byte[] objectFile = ArchiveManagerHelper.extractObjectByPath(zipArchive, object.getFile()); + CatalogObjectEntity catalogObject = catalogObjectRepository.findOne(new CatalogObjectEntity.CatalogObjectEntityKey(bucketEntity.getId(), + object.getName())); + CatalogObjectMetadata objectMetadata; + if (catalogObject == null) { + objectMetadata = this.createCatalogObject(bucketName, + object.getName(), + projectName, + tags, + object.getMetadata().getKind(), + object.getMetadata().getCommitMessage(), + username, + object.getMetadata().getContentType(), + Collections.emptyList(), + objectFile, + FilenameUtils.getExtension(object.getFile())); + } else { + objectMetadata = this.createCatalogObjectRevision(bucketName, + object.getName(), + projectName, + tags, + object.getMetadata().getCommitMessage(), + username, + objectFile); + } + objectsList.add(objectMetadata); + }); + return objectsList; + } + @Transactional public CatalogObjectMetadata createCatalogObject(String bucketName, String name, String projectName, String tags, String kind, String commitMessage, String username, String contentType, List metadataList, @@ -795,8 +837,7 @@ public List listCatalogObjectRevisions(String bucketName, } @Transactional(readOnly = true) - public CatalogObjectMetadata getCatalogObjectRevision(String bucketName, String name, long commitTime) - throws UnsupportedEncodingException { + public CatalogObjectMetadata getCatalogObjectRevision(String bucketName, String name, long commitTime) { CatalogObjectRevisionEntity revisionEntity = getCatalogObjectRevisionEntityByCommitTime(bucketName, name, commitTime); @@ -805,8 +846,7 @@ public CatalogObjectMetadata getCatalogObjectRevision(String bucketName, String } @Transactional(readOnly = true) - public CatalogRawObject getCatalogObjectRevisionRaw(String bucketName, String name, long commitTime) - throws UnsupportedEncodingException { + public CatalogRawObject getCatalogObjectRevisionRaw(String bucketName, String name, long commitTime) { CatalogObjectRevisionEntity revisionEntity = getCatalogObjectRevisionEntityByCommitTime(bucketName, name, commitTime); diff --git a/src/main/java/org/ow2/proactive/catalog/util/ArchiveManagerHelper.java b/src/main/java/org/ow2/proactive/catalog/util/ArchiveManagerHelper.java index 5a6b3ce285..c33d89ddab 100644 --- a/src/main/java/org/ow2/proactive/catalog/util/ArchiveManagerHelper.java +++ b/src/main/java/org/ow2/proactive/catalog/util/ArchiveManagerHelper.java @@ -25,6 +25,7 @@ */ package org.ow2.proactive.catalog.util; +import static org.ow2.proactive.catalog.util.PackageMetadataJSONParser.readJSONFile; import static org.ow2.proactive.catalog.util.PackageMetadataJSONParser.writeJSONFile; import java.io.ByteArrayInputStream; @@ -38,6 +39,7 @@ import java.util.zip.ZipEntry; import org.apache.commons.io.FilenameUtils; +import org.apache.logging.log4j.Level; import org.ow2.proactive.catalog.repository.entity.CatalogObjectEntity; import org.ow2.proactive.catalog.repository.entity.CatalogObjectRevisionEntity; import org.springframework.beans.factory.annotation.Autowired; @@ -172,7 +174,7 @@ public ByteSource generateMetadataForPackage(String bucketName, .getName(), catalogObjectEntity.getExtension(), catalogObjectEntity.getKind()); - fileNameWithExtension = bucketName + "/resources/catalog/" + fileNameWithExtension; + fileNameWithExtension = "resources/catalog/" + fileNameWithExtension; PackageMetadataJSONParser.CatalogObjectData objectData = new PackageMetadataJSONParser.CatalogObjectData(catalogObjectEntity.getId() .getName(), catalogObjectEntity.getKind(), @@ -184,7 +186,7 @@ public ByteSource generateMetadataForPackage(String bucketName, packageData.getCatalog().getObjects().add(objectData); } try { - return new ByteSource(bucketName + "/METADATA.json", writeJSONFile(packageData)); + return new ByteSource("METADATA.json", writeJSONFile(packageData)); } catch (IOException ioe) { log.error("Could not create a METADATA.json file for the demanded package"); throw new RuntimeException(ioe); @@ -215,8 +217,7 @@ public ZipArchiveContent compressPackageZIP(boolean isPartial, List extractZIP(byte[] byteArrayArchive) { */ private void checkAndAddFileFromZip(List filesList, InputStream in, ZipEntry entry) { String nameZipEntry = FilenameUtils.getName(entry.getName()); - if (!nameZipEntry.isEmpty()) { + if (!nameZipEntry.isEmpty() && !nameZipEntry.equals("METADATA.json")) { filesList.add(process(in, entry)); } } + public static PackageMetadataJSONParser.PackageData extractMetadataObject(String bucketName, + byte[] byteArrayArchive) { + try (ByteArrayInputStream byteArrayInputStream = new ByteArrayInputStream(byteArrayArchive)) { + byte[] bytes = ZipUtil.unpackEntry(byteArrayInputStream, "METADATA.json"); + return readJSONFile(bytes); + } catch (IOException ioe) { + throw new RuntimeException(ioe); + } + } + + public static byte[] extractObjectByPath(byte[] byteArrayArchive, String objectName) { + try (ByteArrayInputStream byteArrayInputStream = new ByteArrayInputStream(byteArrayArchive)) { + return ZipUtil.unpackEntry(byteArrayInputStream, objectName); + } catch (IOException ioe) { + throw new RuntimeException(ioe); + } + } + /** * Extract ZIP entry into a byte array * @param in entry content diff --git a/src/main/java/org/ow2/proactive/catalog/util/PackageMetadataJSONParser.java b/src/main/java/org/ow2/proactive/catalog/util/PackageMetadataJSONParser.java index a7a0006923..c02048b905 100644 --- a/src/main/java/org/ow2/proactive/catalog/util/PackageMetadataJSONParser.java +++ b/src/main/java/org/ow2/proactive/catalog/util/PackageMetadataJSONParser.java @@ -58,9 +58,14 @@ protected static PackageData createPackageMetadata(String bucketName, String use return new PackageData(bucketName, userGroup); } + protected static PackageData readJSONFile(byte[] jsonFileAsByteArray) throws IOException { + return MAPPER.readValue(jsonFileAsByteArray, PackageMetadataJSONParser.PackageData.class); + } + @Getter @Setter - protected static class PackageData { + @AllArgsConstructor(access = AccessLevel.PUBLIC) + public static class PackageData { private PackageMetaData metadata; @@ -69,13 +74,14 @@ protected static class PackageData { public PackageData(String bucketName, String userGroup) { this.metadata = new PackageMetaData(bucketName); - this.catalog = new BucketData(bucketName, userGroup, new ArrayList()); + this.catalog = new BucketData(bucketName, userGroup, new ArrayList<>()); } } @Getter @Setter + @AllArgsConstructor(access = AccessLevel.PUBLIC) private static class PackageMetaData { private String name; @@ -101,7 +107,7 @@ public PackageMetaData(String name) { @Getter @Setter @AllArgsConstructor(access = AccessLevel.PUBLIC) - protected static class BucketData { + public static class BucketData { private String bucket; @@ -113,7 +119,8 @@ protected static class BucketData { @Getter @Setter - protected static class CatalogObjectData { + @AllArgsConstructor(access = AccessLevel.PUBLIC) + public static class CatalogObjectData { private String name; @@ -131,8 +138,8 @@ public CatalogObjectData(String name, String kind, String commitMessage, String @Getter @Setter - @AllArgsConstructor(access = AccessLevel.PROTECTED) - private static class CatalogObjectMetaData { + @AllArgsConstructor(access = AccessLevel.PUBLIC) + public static class CatalogObjectMetaData { private String kind; diff --git a/src/test/java/org/ow2/proactive/catalog/util/ArchiveManagerHelperTest.java b/src/test/java/org/ow2/proactive/catalog/util/ArchiveManagerHelperTest.java index a85da773e1..9c88cd2ada 100644 --- a/src/test/java/org/ow2/proactive/catalog/util/ArchiveManagerHelperTest.java +++ b/src/test/java/org/ow2/proactive/catalog/util/ArchiveManagerHelperTest.java @@ -148,31 +148,6 @@ public void testCompressZip() throws IOException { assertEquals("workflow_1.xml", actualFiles.get(1).getFileNameWithExtension()); } - @Test - public void testCompressPackageZip() throws IOException { - - assertNull(archiveManager.compressPackageZIP(false, null, "test-empty-bucket")); - - byte[] workflowByteArray0 = convertFromURIToByteArray(XML_FILE_0); - byte[] workflowByteArray1 = convertFromURIToByteArray(XML_FILE_1); - List expectedFiles = new ArrayList<>(); - expectedFiles.add(getCatalogObjectRevisionEntity("workflow_0", workflowByteArray0, "xml")); - expectedFiles.add(getCatalogObjectRevisionEntity("workflow_1", workflowByteArray1, "xml")); - when(rawObjectResponseCreator.getNameWithFileExtension("workflow_0", "xml", null)).thenReturn("workflow_0.xml"); - when(rawObjectResponseCreator.getNameWithFileExtension("workflow_1", "xml", null)).thenReturn("workflow_1.xml"); - //Compress - ZipArchiveContent archive = archiveManager.compressPackageZIP(false, expectedFiles, "test-bucket"); - //Then extract - List actualFiles = archiveManager.extractZIP(archive.getContent()); - assertEquals(3, actualFiles.size()); - - compare(workflowByteArray0, actualFiles.get(1).getContent()); - compare(workflowByteArray1, actualFiles.get(2).getContent()); - assertEquals("METADATA.json", actualFiles.get(0).getFileNameWithExtension()); - assertEquals("workflow_0.xml", actualFiles.get(1).getFileNameWithExtension()); - assertEquals("workflow_1.xml", actualFiles.get(2).getFileNameWithExtension()); - } - @Test public void testExtractZip() throws IOException { assertTrue(archiveManager.extractZIP(null).isEmpty());