From ad9ebea416dc5044978532c6ef8a58c74bc3229b Mon Sep 17 00:00:00 2001 From: supportontimize Date: Wed, 28 Jun 2023 12:09:02 +0000 Subject: [PATCH 01/23] =?UTF-8?q?New=20develop=20version=20=E2=86=92=201.4?= =?UTF-8?q?.0-SNAPSHOT?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- ontimize-jee-sdms-common/pom.xml | 4 ++-- ontimize-jee-sdms-engine/ontimize-jee-sdms-engine-s3/pom.xml | 4 ++-- ontimize-jee-sdms-engine/pom.xml | 4 ++-- ontimize-jee-sdms-event/pom.xml | 4 ++-- ontimize-jee-sdms-rest/pom.xml | 4 ++-- ontimize-jee-sdms-server/pom.xml | 4 ++-- pom.xml | 2 +- 7 files changed, 13 insertions(+), 13 deletions(-) diff --git a/ontimize-jee-sdms-common/pom.xml b/ontimize-jee-sdms-common/pom.xml index 6f61dcc..fbddfe1 100644 --- a/ontimize-jee-sdms-common/pom.xml +++ b/ontimize-jee-sdms-common/pom.xml @@ -5,7 +5,7 @@ 4.0.0 com.ontimize.jee.sdms ontimize-jee-sdms-common - 1.3.1 + 1.4.0-SNAPSHOT jar Ontimize EE SDMS (Common module) Ontimize EE Storage DMS (SDMS) - Common module @@ -14,7 +14,7 @@ com.ontimize.jee.sdms ontimize-jee-sdms - 1.3.1 + 1.4.0-SNAPSHOT diff --git a/ontimize-jee-sdms-engine/ontimize-jee-sdms-engine-s3/pom.xml b/ontimize-jee-sdms-engine/ontimize-jee-sdms-engine-s3/pom.xml index 9567e89..19d3c39 100644 --- a/ontimize-jee-sdms-engine/ontimize-jee-sdms-engine-s3/pom.xml +++ b/ontimize-jee-sdms-engine/ontimize-jee-sdms-engine-s3/pom.xml @@ -5,7 +5,7 @@ 4.0.0 com.ontimize.jee.sdms ontimize-jee-sdms-engine-s3 - 1.3.1 + 1.4.0-SNAPSHOT jar Ontimize EE SDMS (Engine S3 module) Ontimize EE Storage DMS (SDMS) - Engine S3 module @@ -14,7 +14,7 @@ com.ontimize.jee.sdms ontimize-jee-sdms-engine - 1.3.1 + 1.4.0-SNAPSHOT diff --git a/ontimize-jee-sdms-engine/pom.xml b/ontimize-jee-sdms-engine/pom.xml index bef7f08..aba6f9f 100644 --- a/ontimize-jee-sdms-engine/pom.xml +++ b/ontimize-jee-sdms-engine/pom.xml @@ -5,7 +5,7 @@ 4.0.0 com.ontimize.jee.sdms ontimize-jee-sdms-engine - 1.3.1 + 1.4.0-SNAPSHOT pom Ontimize EE SDMS (Engine module) Ontimize EE Storage DMS (SDMS) - Engine module @@ -17,7 +17,7 @@ com.ontimize.jee.sdms ontimize-jee-sdms - 1.3.1 + 1.4.0-SNAPSHOT diff --git a/ontimize-jee-sdms-event/pom.xml b/ontimize-jee-sdms-event/pom.xml index 1800a80..346c7a3 100644 --- a/ontimize-jee-sdms-event/pom.xml +++ b/ontimize-jee-sdms-event/pom.xml @@ -5,7 +5,7 @@ 4.0.0 com.ontimize.jee.sdms ontimize-jee-sdms-event - 1.3.1 + 1.4.0-SNAPSHOT jar Ontimize EE SDMS (Event module) Ontimize EE Storage DMS (SDMS) - Event module @@ -14,7 +14,7 @@ com.ontimize.jee.sdms ontimize-jee-sdms - 1.3.1 + 1.4.0-SNAPSHOT diff --git a/ontimize-jee-sdms-rest/pom.xml b/ontimize-jee-sdms-rest/pom.xml index 7cb8f9a..7e27a5b 100644 --- a/ontimize-jee-sdms-rest/pom.xml +++ b/ontimize-jee-sdms-rest/pom.xml @@ -5,7 +5,7 @@ 4.0.0 com.ontimize.jee.sdms ontimize-jee-sdms-rest - 1.3.1 + 1.4.0-SNAPSHOT jar Ontimize EE SDMS (Rest module) Ontimize EE Storage DMS (SDMS) - Rest module @@ -14,7 +14,7 @@ com.ontimize.jee.sdms ontimize-jee-sdms - 1.3.1 + 1.4.0-SNAPSHOT diff --git a/ontimize-jee-sdms-server/pom.xml b/ontimize-jee-sdms-server/pom.xml index f2f8c06..9322091 100644 --- a/ontimize-jee-sdms-server/pom.xml +++ b/ontimize-jee-sdms-server/pom.xml @@ -5,7 +5,7 @@ 4.0.0 com.ontimize.jee.sdms ontimize-jee-sdms-server - 1.3.1 + 1.4.0-SNAPSHOT jar Ontimize EE SDMS (Server module) Ontimize EE Storage DMS (SDMS) - Server module @@ -14,7 +14,7 @@ com.ontimize.jee.sdms ontimize-jee-sdms - 1.3.1 + 1.4.0-SNAPSHOT diff --git a/pom.xml b/pom.xml index b283f00..4e16a70 100644 --- a/pom.xml +++ b/pom.xml @@ -4,7 +4,7 @@ 4.0.0 com.ontimize.jee.sdms ontimize-jee-sdms - 1.3.1 + 1.4.0-SNAPSHOT pom Ontimize EE SDMS Ontimize EE Storage DMS (SDMS) is a system for storing and managing files by entity. From d05de1c3387db14ba60378a9ea2f570437bf3576 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Pablo=20Mart=C3=ADnez=20Kirsten?= Date: Fri, 29 Dec 2023 10:04:34 +0100 Subject: [PATCH 02/23] Git action add release on deploy --- .github/workflows/deploy-artifactory-release.yml | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/.github/workflows/deploy-artifactory-release.yml b/.github/workflows/deploy-artifactory-release.yml index d4c0ca9..962b6f1 100644 --- a/.github/workflows/deploy-artifactory-release.yml +++ b/.github/workflows/deploy-artifactory-release.yml @@ -68,4 +68,13 @@ jobs: - name: Create pull request run: | version=${{ steps.tag.outputs.version }} - gh pr create -B develop -H sync/$version --title "Backmerge from main into develop" --body "Created by a GitHub Action → Resync develop branch with main branch and increase project version" \ No newline at end of file + gh pr create -B develop -H sync/$version --title "Backmerge from main into develop" --body "Created by a GitHub Action → Resync develop branch with main branch and increase project version" + - name: Create release on Github + uses: ncipollo/release-action@2792aea87063cfd0d27953ac38e3ab45afacc154 + with: + commit: ${{ env.BRANCH }} + tag: ${{ steps.tag.outputs.version }} + name: ${{ steps.tag.outputs.version }} + token: ${{ secrets.GITHUB_TOKEN }} + body: | + Check out the [changelog](CHANGELOG.md) for version ${{ steps.tag.outputs.version }} From a034cd053422a96151f932515b72022d3e87dba2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Pablo=20Mart=C3=ADnez=20Kirsten?= Date: Fri, 29 Dec 2023 10:41:12 +0100 Subject: [PATCH 03/23] Rename deploy-artifactory-release.yml to deploy-mvn-central-release.yml --- ...loy-artifactory-release.yml => deploy-mvn-central-release.yml} | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename .github/workflows/{deploy-artifactory-release.yml => deploy-mvn-central-release.yml} (100%) diff --git a/.github/workflows/deploy-artifactory-release.yml b/.github/workflows/deploy-mvn-central-release.yml similarity index 100% rename from .github/workflows/deploy-artifactory-release.yml rename to .github/workflows/deploy-mvn-central-release.yml From 8618518dee6e63a1aeb2e8bddffe7b0a85efc27e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Pablo=20Mart=C3=ADnez=20Kirsten?= Date: Fri, 29 Dec 2023 13:11:51 +0100 Subject: [PATCH 04/23] Update documentation link --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 7b2e695..10da88d 100644 --- a/README.md +++ b/README.md @@ -4,7 +4,7 @@ Ontimize JEE Storage DMS is a module of the Ontimize framework that provides a d ## ✍ Use To use the module, you only need to import it into your project to be able to use it. On the entity that is required to have the DMS endpoints, you will have to extend the drivers and add the corresponding DMS methods to the entity services. For more information, see the [documentation](). ## 💼 Documentation -All documentation related to how to use it in a project, tutorials and details of its systems and usage can be found online by accessing the link about [Ontimize Boot documentation](https://ontimize.github.io/ontimize-boot/). +All documentation related to how to use it in a project, tutorials and details of its systems and usage can be found online by accessing the link about [Ontimize Boot documentation](https://ontimize.github.io/docs/). ## 👁️‍🗨️ Versions and dependencies All the versions and dependencies of the artifacts contained in this project can be downloaded from [Maven Central](https://central.sonatype.dev/namespace/com.ontimize.boot), as well as knowing each of its dependencies. ## :gear: Changelog From e9a8f6d97a0f76dfcfc9bf0e67edcfb443d462ba Mon Sep 17 00:00:00 2001 From: "angel.herce" Date: Thu, 24 Apr 2025 12:32:22 +0200 Subject: [PATCH 05/23] performance: S3 Connection has been optimized --- CHANGELOG.md | 3 ++ .../s3/repository/OSdmsS3Repository.java | 17 +++++++---- .../config/OSdmsS3RepositoryConfig.java | 28 ++++++++++++++++--- 3 files changed, 38 insertions(+), 10 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index b3807ab..86b9b7e 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -9,6 +9,9 @@ ## [Unreleased] +### Changed 🛠️ +* **S3 Connection:** The connection to S3 has been optimized. + ## [1.3.1] - 2023-06-28 ### Fixed 🐛 diff --git a/ontimize-jee-sdms-engine/ontimize-jee-sdms-engine-s3/src/main/java/com/ontimize/jee/sdms/engine/s3/repository/OSdmsS3Repository.java b/ontimize-jee-sdms-engine/ontimize-jee-sdms-engine-s3/src/main/java/com/ontimize/jee/sdms/engine/s3/repository/OSdmsS3Repository.java index a546f50..95b0611 100644 --- a/ontimize-jee-sdms-engine/ontimize-jee-sdms-engine-s3/src/main/java/com/ontimize/jee/sdms/engine/s3/repository/OSdmsS3Repository.java +++ b/ontimize-jee-sdms-engine/ontimize-jee-sdms-engine-s3/src/main/java/com/ontimize/jee/sdms/engine/s3/repository/OSdmsS3Repository.java @@ -15,6 +15,7 @@ import org.springframework.stereotype.Repository; import org.springframework.transaction.annotation.Transactional; +import java.io.IOException; import java.util.ArrayList; import java.util.HashSet; import java.util.List; @@ -143,12 +144,15 @@ public OSdmsS3RepositoryResponse download( final ListObjec final List findResponseData = findResponse.getData(); findResponseData.forEach( target -> { final GetObjectRequest getObjectRequest = new GetObjectRequest( target.getBucket(), target.getKey() ); - final S3Object s3Object = this.amazonS3.getObject( getObjectRequest ); - - if( s3Object != null ) { - final OSdmsS3RepositoryDto dto = new OSdmsS3RepositoryDto(); - dto.set( s3Object ); - data.add( dto ); + try( final S3Object s3Object = this.amazonS3.getObject( getObjectRequest )){ + if( s3Object != null ) { + final OSdmsS3RepositoryDto dto = new OSdmsS3RepositoryDto(); + dto.set( s3Object ); + data.add( dto ); + } + } + catch( final IOException e ){ + LOGGER.error("Error closing S3Object stream: {}", e.getMessage()); } } ); @@ -200,6 +204,7 @@ public OSdmsS3RepositoryResponse upload( final PutObjectRe try { final Upload upload = transferManager.upload( request ); upload.waitForCompletion(); + transferManager.shutdownNow(false); final ListObjectsRequest findRequest = new ListObjectsRequest() .withBucketName( request.getBucketName() ) diff --git a/ontimize-jee-sdms-engine/ontimize-jee-sdms-engine-s3/src/main/java/com/ontimize/jee/sdms/engine/s3/repository/config/OSdmsS3RepositoryConfig.java b/ontimize-jee-sdms-engine/ontimize-jee-sdms-engine-s3/src/main/java/com/ontimize/jee/sdms/engine/s3/repository/config/OSdmsS3RepositoryConfig.java index 65d7179..bdde0c0 100644 --- a/ontimize-jee-sdms-engine/ontimize-jee-sdms-engine-s3/src/main/java/com/ontimize/jee/sdms/engine/s3/repository/config/OSdmsS3RepositoryConfig.java +++ b/ontimize-jee-sdms-engine/ontimize-jee-sdms-engine-s3/src/main/java/com/ontimize/jee/sdms/engine/s3/repository/config/OSdmsS3RepositoryConfig.java @@ -1,5 +1,6 @@ package com.ontimize.jee.sdms.engine.s3.repository.config; +import com.amazonaws.ClientConfiguration; import com.amazonaws.auth.AWSStaticCredentialsProvider; import com.amazonaws.auth.BasicAWSCredentials; import com.amazonaws.client.builder.AwsClientBuilder; @@ -24,21 +25,30 @@ public class OSdmsS3RepositoryConfig { @Value( "${ontimize.sdms.s3.access-key}" ) private String accessKey; - /** The secret key from Amazon S3 */ @Value( "${ontimize.sdms.s3.secret-key}" ) private String secretKey; - /** The region of Amazon S3 */ @Value( "${ontimize.sdms.s3.region}" ) private String region; - /** The endpoing of Amazon S3 */ @Value( "${ontimize.sdms.s3.endpoint:}" ) private String endpoint; + @Value( "${ontimize.sdms.s3.max-connections:100}" ) + private int maxConnections; + + @Value( "${ontimize.sdms.s3.timeout.connection:5000}" ) + private int connectionTimeout; + + @Value( "${ontimize.sdms.s3.timeout.socket:10000}" ) + private int socketTimeout; + + @Value( "${ontimize.sdms.s3.ttl-connection:60000}" ) + private long ttlConnection; + // ------------------------------------------------------------------------------------------------------------------ \\ /** @@ -51,9 +61,19 @@ public AmazonS3 amazonS3() { //Initialise AWS credentials BasicAWSCredentials awsCreds = new BasicAWSCredentials( this.accessKey, this.secretKey ); + ClientConfiguration clientConfig = new ClientConfiguration() + .withMaxConnections(this.maxConnections) // Aumenta el número de conexiones simultáneas + .withConnectionTimeout(this.connectionTimeout) // Tiempo máximo para establecer la conexión (ms) + .withSocketTimeout(this.socketTimeout) // Tiempo máximo para leer datos del socket (ms) + .withTcpKeepAlive(true) // Mantiene las conexiones abiertas + .withUseExpectContinue(true) // Mejora rendimiento en PUTs grandes + .withConnectionTTL(this.ttlConnection) // TTL de conexión, útil para liberar sockets antiguos + .withMaxErrorRetry(3); + //Configure and return AmazonS3 bean final AmazonS3ClientBuilder builder = AmazonS3ClientBuilder.standard() - .withCredentials( new AWSStaticCredentialsProvider( awsCreds ) ); + .withClientConfiguration( clientConfig ) + .withCredentials( new AWSStaticCredentialsProvider( awsCreds )); if( this.endpoint != null && ! this.endpoint.isEmpty() ) { builder.withEndpointConfiguration( From 03abb88ba65c241f35b39b46d8f18c8e36291108 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Pablo=20Mart=C3=ADnez=20Kirsten?= Date: Thu, 24 Apr 2025 12:58:51 +0200 Subject: [PATCH 06/23] Update deploy-mvn-central-snapshot.yml --- .github/workflows/deploy-mvn-central-snapshot.yml | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/.github/workflows/deploy-mvn-central-snapshot.yml b/.github/workflows/deploy-mvn-central-snapshot.yml index fb5c88f..d9b330c 100644 --- a/.github/workflows/deploy-mvn-central-snapshot.yml +++ b/.github/workflows/deploy-mvn-central-snapshot.yml @@ -13,9 +13,9 @@ jobs: MAVEN_GPG_PASSPHRASE: ${{ secrets.MAVEN_GPG_PASSPHRASE }} steps: - name: Checkout repository code - uses: actions/checkout@v3 + uses: actions/checkout@v4 - name: Setup Java JDK and Maven - uses: ontimize/setup-java-maven-gitAction@v3 + uses: ontimize/setup-java-maven-gitAction@v4 with: distribution: 'temurin' java-version: '11' @@ -25,4 +25,4 @@ jobs: gpg-private-key: ${{ secrets.MAVEN_GPG_PRIVATE_KEY }} gpg-passphrase: MAVEN_GPG_PASSPHRASE - name: Publish to Apache Maven Central - run: mvn -B -U clean deploy -Pgenerate-version \ No newline at end of file + run: mvn -B -U clean deploy -Pgenerate-version From 041ff5ea5e1ef66dd232cc00053b35373d311ea7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Pablo=20Mart=C3=ADnez=20Kirsten?= Date: Thu, 24 Apr 2025 13:00:18 +0200 Subject: [PATCH 07/23] Update deploy-mvn-central-release.yml --- .github/workflows/deploy-mvn-central-release.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/deploy-mvn-central-release.yml b/.github/workflows/deploy-mvn-central-release.yml index 962b6f1..9eafd5d 100644 --- a/.github/workflows/deploy-mvn-central-release.yml +++ b/.github/workflows/deploy-mvn-central-release.yml @@ -28,12 +28,12 @@ jobs: run: | echo "BRANCH=${{ github.event.inputs.RELEASE_BRANCH || github.ref }}" >> $GITHUB_ENV - name: Checkout repository code - uses: actions/checkout@v3 + uses: actions/checkout@v4 with: ref: ${{ env.BRANCH }} fetch-depth: 0 - name: Setup Java JDK and Maven - uses: ontimize/setup-java-maven-gitAction@v3 + uses: ontimize/setup-java-maven-gitAction@v4 with: distribution: 'temurin' java-version: '11' From 84ad7dce0101eba8d3689333a7262dc1ecbab9c9 Mon Sep 17 00:00:00 2001 From: "angel.herce" Date: Fri, 25 Apr 2025 07:46:37 +0200 Subject: [PATCH 08/23] fix: properly close S3 input streams to prevent resource leaks --- CHANGELOG.md | 3 + .../sdms/common/zip/OSdmsZipCompressor.java | 58 ++++++++----------- .../jee/sdms/common/zip/OSdmsZipData.java | 15 +++-- .../s3/repository/OSdmsS3Repository.java | 2 +- .../repository/dto/OSdmsS3RepositoryDto.java | 16 +++-- .../dto/OSdmsS3RepositoryDtoTest.java | 28 +++++---- .../rest/controller/OSdmsRestController.java | 6 +- 7 files changed, 65 insertions(+), 63 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 86b9b7e..b234634 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -9,6 +9,9 @@ ## [Unreleased] +### Fixed 🐛 +- Closed `S3ObjectInputStream` instances properly to avoid `CLOSE_WAIT` socket issues and potential memory/resource leaks during file download operations. + ### Changed 🛠️ * **S3 Connection:** The connection to S3 has been optimized. diff --git a/ontimize-jee-sdms-common/src/main/java/com/ontimize/jee/sdms/common/zip/OSdmsZipCompressor.java b/ontimize-jee-sdms-common/src/main/java/com/ontimize/jee/sdms/common/zip/OSdmsZipCompressor.java index 177dc86..2d1ddd0 100644 --- a/ontimize-jee-sdms-common/src/main/java/com/ontimize/jee/sdms/common/zip/OSdmsZipCompressor.java +++ b/ontimize-jee-sdms-common/src/main/java/com/ontimize/jee/sdms/common/zip/OSdmsZipCompressor.java @@ -7,6 +7,7 @@ import java.io.ByteArrayInputStream; import java.io.ByteArrayOutputStream; import java.io.IOException; +import java.io.InputStream; import java.util.List; import java.util.Objects; import java.util.Set; @@ -35,48 +36,35 @@ public class OSdmsZipCompressor implements IOSdmsZipCompressor { @Override public OSdmsZipDto compress( final String zipName, final List dataToZip ) { final ByteArrayOutputStream baos = new ByteArrayOutputStream(); - final ZipOutputStream zos = new ZipOutputStream( baos ); - final Set data = dataToZip.stream() - .map( IOSdmsZippeable::getDataToZip ) - .filter( Objects::nonNull ) - .collect( Collectors.toSet() ); + try (ZipOutputStream zos = new ZipOutputStream(baos)) { + final Set data = dataToZip.stream() + .map(IOSdmsZippeable::getDataToZip) + .filter(Objects::nonNull) + .collect(Collectors.toSet()); - for( final OSdmsZipData zipData : data ) { - final ZipEntry entry = new ZipEntry( zipData.getFileName() ); - try { - zos.putNextEntry( entry ); - final byte[] bytes = new byte[ 1024 ]; - int length; - while( ( length = zipData.getInputStream().read( bytes ) ) >= 0 ) { - zos.write( bytes, 0, length ); - } - } - catch( final IOException e ) { - LOGGER.error( "Error compressing data to ZIP file: {}", e.getMessage() ); - } - finally { - try { + for (final OSdmsZipData zipData : data) { + final ZipEntry entry = new ZipEntry(zipData.getFileName()); + try ( InputStream inputStream = new ByteArrayInputStream( zipData.getFileContent() )) { + zos.putNextEntry(entry); + byte[] buffer = new byte[1024]; + int length; + while ((length = inputStream.read(buffer)) >= 0) { + zos.write(buffer, 0, length); + } zos.closeEntry(); - zipData.getInputStream().close(); - } - catch( final IOException e ) { - LOGGER.error( "Error closing Resoources: {}", e.getMessage() ); + } catch (IOException e) { + LOGGER.error("Error compressing entry {}: {}", zipData.getFileName(), e.getMessage()); } } + } catch (IOException e) { + LOGGER.error("Error creating ZIP output stream: {}", e.getMessage()); } - try { - zos.close(); - } - catch( final IOException e ) { - LOGGER.error( "Error closing ZIP file: {}", e.getMessage() ); - } - - final ByteArrayInputStream bais = new ByteArrayInputStream( baos.toByteArray() ); + final ByteArrayInputStream bais = new ByteArrayInputStream(baos.toByteArray()); final OSdmsZipDto zipDto = new OSdmsZipDto(); - zipDto.setFile( bais ); - zipDto.setName( zipName ); - zipDto.setSize( baos.size() ); + zipDto.setFile(bais); + zipDto.setName(zipName); + zipDto.setSize(baos.size()); return zipDto; } diff --git a/ontimize-jee-sdms-common/src/main/java/com/ontimize/jee/sdms/common/zip/OSdmsZipData.java b/ontimize-jee-sdms-common/src/main/java/com/ontimize/jee/sdms/common/zip/OSdmsZipData.java index dfe250a..b444962 100644 --- a/ontimize-jee-sdms-common/src/main/java/com/ontimize/jee/sdms/common/zip/OSdmsZipData.java +++ b/ontimize-jee-sdms-common/src/main/java/com/ontimize/jee/sdms/common/zip/OSdmsZipData.java @@ -1,6 +1,5 @@ package com.ontimize.jee.sdms.common.zip; -import java.io.InputStream; import java.util.Objects; @@ -17,16 +16,16 @@ public class OSdmsZipData { /** * The inputStream field represents the input stream to be zipped. */ - private InputStream inputStream; + private byte[] fileContent; // ------------------------------------------------------------------------------------------------------------------ \\ public OSdmsZipData() { } - public OSdmsZipData( final String fileName, final InputStream inputStream ) { + public OSdmsZipData( final String fileName, final byte[] fileContent ) { this.setFileName( fileName ); - this.setInputStream( inputStream ); + this.setFileContent( fileContent ); } // ------------------------------------------------------------------------------------------------------------------ \\ @@ -41,12 +40,12 @@ public void setFileName( final String fileName ) { this.fileName = fileName; } - public InputStream getInputStream() { - return this.inputStream; + public byte[] getFileContent() { + return this.fileContent; } - public void setInputStream( final InputStream inputStream ) { - this.inputStream = inputStream; + public void setFileContent( final byte[] content ) { + this.fileContent = content; } // ------------------------------------------------------------------------------------------------------------------ \\ diff --git a/ontimize-jee-sdms-engine/ontimize-jee-sdms-engine-s3/src/main/java/com/ontimize/jee/sdms/engine/s3/repository/OSdmsS3Repository.java b/ontimize-jee-sdms-engine/ontimize-jee-sdms-engine-s3/src/main/java/com/ontimize/jee/sdms/engine/s3/repository/OSdmsS3Repository.java index 95b0611..029391e 100644 --- a/ontimize-jee-sdms-engine/ontimize-jee-sdms-engine-s3/src/main/java/com/ontimize/jee/sdms/engine/s3/repository/OSdmsS3Repository.java +++ b/ontimize-jee-sdms-engine/ontimize-jee-sdms-engine-s3/src/main/java/com/ontimize/jee/sdms/engine/s3/repository/OSdmsS3Repository.java @@ -81,7 +81,7 @@ public OSdmsS3RepositoryResponse find( final ListObjectsRe dto.set( target ); dto.set( objectMetadata ); return dto; - } ).collect( Collectors.toList() ); + }).collect( Collectors.toList() ); data.addAll( files ); } diff --git a/ontimize-jee-sdms-engine/ontimize-jee-sdms-engine-s3/src/main/java/com/ontimize/jee/sdms/engine/s3/repository/dto/OSdmsS3RepositoryDto.java b/ontimize-jee-sdms-engine/ontimize-jee-sdms-engine-s3/src/main/java/com/ontimize/jee/sdms/engine/s3/repository/dto/OSdmsS3RepositoryDto.java index b0e7f09..90ab80e 100644 --- a/ontimize-jee-sdms-engine/ontimize-jee-sdms-engine-s3/src/main/java/com/ontimize/jee/sdms/engine/s3/repository/dto/OSdmsS3RepositoryDto.java +++ b/ontimize-jee-sdms-engine/ontimize-jee-sdms-engine-s3/src/main/java/com/ontimize/jee/sdms/engine/s3/repository/dto/OSdmsS3RepositoryDto.java @@ -8,6 +8,7 @@ import com.ontimize.jee.sdms.common.zip.IOSdmsZippeable; import com.ontimize.jee.sdms.common.zip.OSdmsZipData; +import java.io.IOException; import java.io.InputStream; import java.time.LocalDateTime; import java.time.ZoneId; @@ -66,7 +67,7 @@ public class OSdmsS3RepositoryDto implements IOSdmsMappeable, IOSdmsZippeable { private Map metadata; /** The bytes of S3 file */ - private InputStream file; + private byte[] file; // ------------------------------------------------------------------------------------------------------------------ \\ @@ -185,11 +186,11 @@ public void setMetadata( final Map metadata ) { this.metadata = metadata; } - public InputStream getFile() { + public byte[] getFile() { return this.file; } - public void setFile( final InputStream file ) { + public void setFile( final byte[] file ) { this.file = file; } @@ -207,7 +208,12 @@ public void setFile( final InputStream file ) { public void set( final S3Object s3Object ) { this.processKey( s3Object.getKey() ); this.bucket = s3Object.getBucketName(); - this.file = s3Object.getObjectContent(); + try (final InputStream is = s3Object.getObjectContent()) { + this.file = is.readAllBytes(); + if( this.file != null ) this.size = (long) this.file.length; + } catch ( IOException e) { + this.file = null; + } final ObjectMetadata objectMetadata = s3Object.getObjectMetadata(); this.set( objectMetadata ); } @@ -352,7 +358,7 @@ public OSdmsZipData getDataToZip() { String fileName = sanitizedKey.replace( "/", "_" ); if( fileName.endsWith( "_" ) ) fileName = fileName.substring( 0, fileName.length() - 1 ); result = new OSdmsZipData(); - result.setInputStream( this.file ); + result.setFileContent( this.file ); result.setFileName( fileName ); } return result; diff --git a/ontimize-jee-sdms-engine/ontimize-jee-sdms-engine-s3/src/test/java/com/ontimize/jee/sdms/engine/s3/repository/dto/OSdmsS3RepositoryDtoTest.java b/ontimize-jee-sdms-engine/ontimize-jee-sdms-engine-s3/src/test/java/com/ontimize/jee/sdms/engine/s3/repository/dto/OSdmsS3RepositoryDtoTest.java index 652c85c..cfb348a 100644 --- a/ontimize-jee-sdms-engine/ontimize-jee-sdms-engine-s3/src/test/java/com/ontimize/jee/sdms/engine/s3/repository/dto/OSdmsS3RepositoryDtoTest.java +++ b/ontimize-jee-sdms-engine/ontimize-jee-sdms-engine-s3/src/test/java/com/ontimize/jee/sdms/engine/s3/repository/dto/OSdmsS3RepositoryDtoTest.java @@ -3,12 +3,16 @@ import com.amazonaws.services.s3.model.*; import com.ontimize.jee.sdms.common.zip.OSdmsZipData; +import org.apache.http.client.methods.HttpRequestBase; import org.junit.jupiter.api.Test; import org.junit.jupiter.params.ParameterizedTest; import org.junit.jupiter.params.provider.CsvSource; import org.mockito.Mockito; +import java.io.ByteArrayInputStream; import java.io.InputStream; +import java.net.HttpURLConnection; +import java.nio.charset.StandardCharsets; import java.text.SimpleDateFormat; import java.util.*; @@ -37,7 +41,7 @@ void givenAValidS3Object_whenSetS3Object_thenDataIsSet( final String givenKey, f final String givenBucket = "bucket"; final Long givenSize = 1L; final String givenCreationDate = "27/06/2023-10:30:20"; - final S3ObjectInputStream givenFile = Mockito.mock( S3ObjectInputStream.class ); + final S3ObjectInputStream givenFile = new S3ObjectInputStream( new ByteArrayInputStream( "contenido de prueba".getBytes( StandardCharsets.UTF_8 )), Mockito.mock( HttpRequestBase.class )); final Map givenUserMetadata = Mockito.mock( Map.class ); when( givenUserMetadata.containsKey( "creation_date" ) ).thenReturn( true ); @@ -62,7 +66,7 @@ void givenAValidS3Object_whenSetS3Object_thenDataIsSet( final String givenKey, f final String key = dto.getKey(); final String prefix = dto.getPrefix(); final String name = dto.getName(); - final InputStream file = dto.getFile(); + final byte[] file = dto.getFile(); final Date creationDate = dto.getCreationDate(); final Long size = dto.getSize(); final Map metadata = dto.getMetadata(); @@ -415,14 +419,14 @@ void givenOSdmsS3RepositoryDto_whenCallGetDataToZip_thenOSdmsZipData() { final String givenKey = "/entity/1/proof.txt"; final String givenName = "proof.txt"; final boolean givenFolder = false; - final S3ObjectInputStream givenS3ObjectInputStream = Mockito.mock( S3ObjectInputStream.class ); + final byte[] givenFileBytes = "contenido de prueba".getBytes( StandardCharsets.UTF_8 ); //Set Data in DTO final OSdmsS3RepositoryDto dto = new OSdmsS3RepositoryDto(); dto.setKey( givenKey ); dto.setName( givenName ); dto.setFolder( givenFolder ); - dto.setFile( givenS3ObjectInputStream ); + dto.setFile( givenFileBytes ); //When final OSdmsZipData result = dto.getDataToZip(); @@ -430,8 +434,8 @@ void givenOSdmsS3RepositoryDto_whenCallGetDataToZip_thenOSdmsZipData() { //Then assertNotNull( result, () -> "The result should not be null" ); - final InputStream inputStream = result.getInputStream(); - assertNotNull( inputStream, () -> "The inputStream should not be null" ); + final byte[] fileContent = result.getFileContent(); + assertNotNull( fileContent, () -> "The File Content should not be null" ); final String fileName = result.getFileName(); assertEquals( expectedFileName, fileName, () -> "Unexpected fileName" ); @@ -699,16 +703,16 @@ void givenMetadadataAsMap_whenCallSetMetadata_thenCheckTheNewValueWithCallGetter //File @Test - void givenFileAsS3ObjectInputStream_whenCallSetFile_thenCheckTheNewValueWithCallGetter() { + void givenFileAsBytes_whenCallSetFile_thenCheckTheNewValueWithCallGetter() { //Given - final S3ObjectInputStream givenFile = Mockito.mock( S3ObjectInputStream.class ); + final byte[] givenFileBytes = "contenido de prueba".getBytes( StandardCharsets.UTF_8 ); final OSdmsS3RepositoryDto dto = new OSdmsS3RepositoryDto(); //When - dto.setFile( givenFile ); + dto.setFile( givenFileBytes ); //Then - final InputStream result = dto.getFile(); + final byte[] result = dto.getFile(); assertNotNull( result, () -> "The result should not be null" ); } @@ -722,14 +726,14 @@ void givenOSdmsS3RepositoryDto_whenCallToString_thenCorrectStringRepresentation( final String givenKey = "/entity/1/proof.txt"; final String givenName = "proof.txt"; final boolean givenFolder = false; - final S3ObjectInputStream givenS3ObjectInputStream = Mockito.mock( S3ObjectInputStream.class ); + final byte[] givenFileBytes = "contenido de prueba".getBytes( StandardCharsets.UTF_8 ); //Set Data in DTO final OSdmsS3RepositoryDto dto = new OSdmsS3RepositoryDto(); dto.setKey( givenKey ); dto.setName( givenName ); dto.setFolder( givenFolder ); - dto.setFile( givenS3ObjectInputStream ); + dto.setFile( givenFileBytes ); //When final String result = dto.toString(); diff --git a/ontimize-jee-sdms-rest/src/main/java/com/ontimize/jee/sdms/rest/controller/OSdmsRestController.java b/ontimize-jee-sdms-rest/src/main/java/com/ontimize/jee/sdms/rest/controller/OSdmsRestController.java index 376fbf4..7e4940d 100644 --- a/ontimize-jee-sdms-rest/src/main/java/com/ontimize/jee/sdms/rest/controller/OSdmsRestController.java +++ b/ontimize-jee-sdms-rest/src/main/java/com/ontimize/jee/sdms/rest/controller/OSdmsRestController.java @@ -16,6 +16,7 @@ import org.springframework.web.bind.annotation.*; import org.springframework.web.multipart.MultipartFile; +import java.io.ByteArrayInputStream; import java.io.InputStream; import java.io.Serializable; import java.util.Map; @@ -512,11 +513,12 @@ protected ResponseEntity createResponseEntityWithDocument( final EntityResult en final Map recordValues = entityResult.getRecordValues( 0 ); //Get Data - file = new InputStreamResource( ( InputStream ) recordValues.get( "file" ) ); + byte[] fileBytes = (byte[]) recordValues.get("file"); fileName = ( String ) recordValues.get( "name" ); fileSize = ( long ) recordValues.get( "size" ); - if( fileSize != 0 ) { + if( fileSize != 0 && fileBytes != null && fileBytes.length > 0 ) { + file = new InputStreamResource(new ByteArrayInputStream( fileBytes)); //Build the result result = ResponseEntity.ok() .contentType( MediaType.APPLICATION_OCTET_STREAM ) From 125ccf8ac4ef7fe083865a8323239f937eca7ec7 Mon Sep 17 00:00:00 2001 From: "angel.herce" Date: Fri, 25 Apr 2025 12:27:10 +0200 Subject: [PATCH 09/23] feat: add new method to OSdmsService --- CHANGELOG.md | 6 + ontimize-jee-sdms-common/pom.xml | 5 + .../jee/sdms/common/action/IOSdmsAction.java | 2 + .../file/DefaultTemporalFileManager.java | 56 ++++++ .../sdms/common/file/TemporalFileManager.java | 13 ++ .../sdms/common/zip/OSdmsZipCompressor.java | 20 ++- .../jee/sdms/common/zip/OSdmsZipData.java | 17 +- .../jee/sdms/engine/s3/OSdmsS3Engine.java | 6 + .../s3/command/OSdmsS3DownloadCommand.java | 2 +- .../OSdmsS3GetTemporalFilesCommand.java | 163 ++++++++++++++++++ .../s3/repository/OSdmsS3Repository.java | 8 +- .../repository/dto/OSdmsS3RepositoryDto.java | 24 ++- .../dto/OSdmsS3RepositoryDtoTest.java | 77 +++++---- .../jee/sdms/server/service/OSdmsService.java | 7 +- pom.xml | 6 + 15 files changed, 348 insertions(+), 64 deletions(-) create mode 100644 ontimize-jee-sdms-common/src/main/java/com/ontimize/jee/sdms/common/file/DefaultTemporalFileManager.java create mode 100644 ontimize-jee-sdms-common/src/main/java/com/ontimize/jee/sdms/common/file/TemporalFileManager.java create mode 100644 ontimize-jee-sdms-engine/ontimize-jee-sdms-engine-s3/src/main/java/com/ontimize/jee/sdms/engine/s3/command/OSdmsS3GetTemporalFilesCommand.java diff --git a/CHANGELOG.md b/CHANGELOG.md index b234634..72d64c5 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -9,6 +9,12 @@ ## [Unreleased] +### Added ✔️ +- The `TemporalFileManager` has been created to manage temporary files per request. + +* **OSdmsService:** Added `getTemporalFiles` method has been added to `OSdmsService`. + + ### Fixed 🐛 - Closed `S3ObjectInputStream` instances properly to avoid `CLOSE_WAIT` socket issues and potential memory/resource leaks during file download operations. diff --git a/ontimize-jee-sdms-common/pom.xml b/ontimize-jee-sdms-common/pom.xml index fbddfe1..f768e48 100644 --- a/ontimize-jee-sdms-common/pom.xml +++ b/ontimize-jee-sdms-common/pom.xml @@ -51,6 +51,11 @@ ontimize-jee-common + + jakarta.annotation + jakarta.annotation-api + + org.reflections diff --git a/ontimize-jee-sdms-common/src/main/java/com/ontimize/jee/sdms/common/action/IOSdmsAction.java b/ontimize-jee-sdms-common/src/main/java/com/ontimize/jee/sdms/common/action/IOSdmsAction.java index 7b84f12..648ef80 100644 --- a/ontimize-jee-sdms-common/src/main/java/com/ontimize/jee/sdms/common/action/IOSdmsAction.java +++ b/ontimize-jee-sdms-common/src/main/java/com/ontimize/jee/sdms/common/action/IOSdmsAction.java @@ -66,6 +66,8 @@ public interface IOSdmsAction { */ EntityResult download( OSdmsRestDataDto data ); + EntityResult getTemporalFiles( OSdmsRestDataDto data ); + // ------------------------------------------------------------------------------------------------------------------ \\ // -------| DMS - UPLOAD |------------------------------------------------------------------------------------------- \\ // ------------------------------------------------------------------------------------------------------------------ \\ diff --git a/ontimize-jee-sdms-common/src/main/java/com/ontimize/jee/sdms/common/file/DefaultTemporalFileManager.java b/ontimize-jee-sdms-common/src/main/java/com/ontimize/jee/sdms/common/file/DefaultTemporalFileManager.java new file mode 100644 index 0000000..4bd3c3a --- /dev/null +++ b/ontimize-jee-sdms-common/src/main/java/com/ontimize/jee/sdms/common/file/DefaultTemporalFileManager.java @@ -0,0 +1,56 @@ +package com.ontimize.jee.sdms.common.file; + +import jakarta.annotation.PreDestroy; +import org.springframework.beans.factory.annotation.Value; +import org.springframework.stereotype.Component; +import org.springframework.web.context.annotation.RequestScope; + +import java.io.*; +import java.nio.file.Files; +import java.util.ArrayList; +import java.util.List; +import java.util.UUID; + +@Component +@RequestScope +public class DefaultTemporalFileManager implements TemporalFileManager{ + + @Value( "${ontimize.sdms.file.temporal.directory}" ) + private String temporalDirectory; + + private final List files = new ArrayList<>(); + + @Override + public File create( final String name, final InputStream inputStream ) throws IOException { + final File directory = new File( this.temporalDirectory ); + final File file; + if( directory.exists() && directory.isDirectory() ) file = File.createTempFile( name, ".tmp", directory ); + else file = File.createTempFile( name, ".tmp" ); + try( FileOutputStream fos = new FileOutputStream( file)) { + inputStream.transferTo(fos); + } + this.files.add( file ); + return file; + } + + @Override + public File create( final InputStream inputStream ) throws IOException { + return this.create( UUID.randomUUID().toString(), inputStream ); + } + + @Override + public void delete( final File file ) { + this.files.stream().filter( target -> target.getAbsolutePath().equals( file.getAbsolutePath() ) ) + .findFirst() + .ifPresent( target -> { + this.files.remove( target ); + if( target.exists() ) target.delete(); + }); + } + + @PreDestroy + @Override + public void cleanUp() { + this.files.forEach( file -> { if( file.exists() ) file.delete(); }); + } +} diff --git a/ontimize-jee-sdms-common/src/main/java/com/ontimize/jee/sdms/common/file/TemporalFileManager.java b/ontimize-jee-sdms-common/src/main/java/com/ontimize/jee/sdms/common/file/TemporalFileManager.java new file mode 100644 index 0000000..d2d0239 --- /dev/null +++ b/ontimize-jee-sdms-common/src/main/java/com/ontimize/jee/sdms/common/file/TemporalFileManager.java @@ -0,0 +1,13 @@ +package com.ontimize.jee.sdms.common.file; + +import java.io.File; +import java.io.IOException; +import java.io.InputStream; + +public interface TemporalFileManager { + + File create( InputStream inputStream ) throws IOException; + File create( String name, InputStream inputStream ) throws IOException; + void delete( File file ); + void cleanUp(); +} diff --git a/ontimize-jee-sdms-common/src/main/java/com/ontimize/jee/sdms/common/zip/OSdmsZipCompressor.java b/ontimize-jee-sdms-common/src/main/java/com/ontimize/jee/sdms/common/zip/OSdmsZipCompressor.java index 2d1ddd0..c97af1d 100644 --- a/ontimize-jee-sdms-common/src/main/java/com/ontimize/jee/sdms/common/zip/OSdmsZipCompressor.java +++ b/ontimize-jee-sdms-common/src/main/java/com/ontimize/jee/sdms/common/zip/OSdmsZipCompressor.java @@ -4,10 +4,7 @@ import org.slf4j.LoggerFactory; import org.springframework.stereotype.Component; -import java.io.ByteArrayInputStream; -import java.io.ByteArrayOutputStream; -import java.io.IOException; -import java.io.InputStream; +import java.io.*; import java.util.List; import java.util.Objects; import java.util.Set; @@ -36,6 +33,7 @@ public class OSdmsZipCompressor implements IOSdmsZipCompressor { @Override public OSdmsZipDto compress( final String zipName, final List dataToZip ) { final ByteArrayOutputStream baos = new ByteArrayOutputStream(); + try (ZipOutputStream zos = new ZipOutputStream(baos)) { final Set data = dataToZip.stream() .map(IOSdmsZippeable::getDataToZip) @@ -44,22 +42,30 @@ public OSdmsZipDto compress( final String zipName, f for (final OSdmsZipData zipData : data) { final ZipEntry entry = new ZipEntry(zipData.getFileName()); - try ( InputStream inputStream = new ByteArrayInputStream( zipData.getFileContent() )) { + final File file = zipData.getFile(); + + if (file == null || !file.exists()) { + LOGGER.warn("File {} does not exist or is null, skipping", zipData.getFileName()); + continue; + } + + try (InputStream inputStream = new FileInputStream(file)) { zos.putNextEntry(entry); - byte[] buffer = new byte[1024]; + byte[] buffer = new byte[4096]; int length; while ((length = inputStream.read(buffer)) >= 0) { zos.write(buffer, 0, length); } zos.closeEntry(); } catch (IOException e) { - LOGGER.error("Error compressing entry {}: {}", zipData.getFileName(), e.getMessage()); + LOGGER.error("Error compressing file {}: {}", zipData.getFileName(), e.getMessage()); } } } catch (IOException e) { LOGGER.error("Error creating ZIP output stream: {}", e.getMessage()); } + // Construir el DTO con el contenido del zip en memoria final ByteArrayInputStream bais = new ByteArrayInputStream(baos.toByteArray()); final OSdmsZipDto zipDto = new OSdmsZipDto(); zipDto.setFile(bais); diff --git a/ontimize-jee-sdms-common/src/main/java/com/ontimize/jee/sdms/common/zip/OSdmsZipData.java b/ontimize-jee-sdms-common/src/main/java/com/ontimize/jee/sdms/common/zip/OSdmsZipData.java index b444962..f2402f2 100644 --- a/ontimize-jee-sdms-common/src/main/java/com/ontimize/jee/sdms/common/zip/OSdmsZipData.java +++ b/ontimize-jee-sdms-common/src/main/java/com/ontimize/jee/sdms/common/zip/OSdmsZipData.java @@ -1,5 +1,6 @@ package com.ontimize.jee.sdms.common.zip; +import java.io.File; import java.util.Objects; @@ -14,18 +15,18 @@ public class OSdmsZipData { private String fileName; /** - * The inputStream field represents the input stream to be zipped. + * The File field represents the file to be zipped. */ - private byte[] fileContent; + private File file; // ------------------------------------------------------------------------------------------------------------------ \\ public OSdmsZipData() { } - public OSdmsZipData( final String fileName, final byte[] fileContent ) { + public OSdmsZipData( final String fileName, final File file ) { this.setFileName( fileName ); - this.setFileContent( fileContent ); + this.setFile( file ); } // ------------------------------------------------------------------------------------------------------------------ \\ @@ -40,12 +41,12 @@ public void setFileName( final String fileName ) { this.fileName = fileName; } - public byte[] getFileContent() { - return this.fileContent; + public File getFile() { + return this.file; } - public void setFileContent( final byte[] content ) { - this.fileContent = content; + public void setFile( final File file ) { + this.file = file; } // ------------------------------------------------------------------------------------------------------------------ \\ diff --git a/ontimize-jee-sdms-engine/ontimize-jee-sdms-engine-s3/src/main/java/com/ontimize/jee/sdms/engine/s3/OSdmsS3Engine.java b/ontimize-jee-sdms-engine/ontimize-jee-sdms-engine-s3/src/main/java/com/ontimize/jee/sdms/engine/s3/OSdmsS3Engine.java index e266bf9..6bd23f2 100644 --- a/ontimize-jee-sdms-engine/ontimize-jee-sdms-engine-s3/src/main/java/com/ontimize/jee/sdms/engine/s3/OSdmsS3Engine.java +++ b/ontimize-jee-sdms-engine/ontimize-jee-sdms-engine-s3/src/main/java/com/ontimize/jee/sdms/engine/s3/OSdmsS3Engine.java @@ -69,6 +69,12 @@ public EntityResult download( final OSdmsRestDataDto data ) { return this.oSdmsCommandHandler.run( new OSdmsS3DownloadCommand( requestFilter ) ); } + @Override + public EntityResult getTemporalFiles( final OSdmsRestDataDto data ) { + final OSdmsS3InputFilter requestFilter = this.oSdmsS3InputFilterMapper.map( data ); + return this.oSdmsCommandHandler.run( new OSdmsS3GetTemporalFilesCommand( requestFilter ) ); + } + // ------------------------------------------------------------------------------------------------------------------ \\ // -------| DMS - UPLOAD |------------------------------------------------------------------------------------------- \\ // ------------------------------------------------------------------------------------------------------------------ \\ diff --git a/ontimize-jee-sdms-engine/ontimize-jee-sdms-engine-s3/src/main/java/com/ontimize/jee/sdms/engine/s3/command/OSdmsS3DownloadCommand.java b/ontimize-jee-sdms-engine/ontimize-jee-sdms-engine-s3/src/main/java/com/ontimize/jee/sdms/engine/s3/command/OSdmsS3DownloadCommand.java index c48e260..1ce1be1 100644 --- a/ontimize-jee-sdms-engine/ontimize-jee-sdms-engine-s3/src/main/java/com/ontimize/jee/sdms/engine/s3/command/OSdmsS3DownloadCommand.java +++ b/ontimize-jee-sdms-engine/ontimize-jee-sdms-engine-s3/src/main/java/com/ontimize/jee/sdms/engine/s3/command/OSdmsS3DownloadCommand.java @@ -27,7 +27,7 @@ /** * Command to download files from S3 */ -public class OSdmsS3DownloadCommand implements IOSdmsCommand { +public class OSdmsS3DownloadCommand implements IOSdmsCommand { //Constants private static final String ZIP_NAME = "data.zip"; diff --git a/ontimize-jee-sdms-engine/ontimize-jee-sdms-engine-s3/src/main/java/com/ontimize/jee/sdms/engine/s3/command/OSdmsS3GetTemporalFilesCommand.java b/ontimize-jee-sdms-engine/ontimize-jee-sdms-engine-s3/src/main/java/com/ontimize/jee/sdms/engine/s3/command/OSdmsS3GetTemporalFilesCommand.java new file mode 100644 index 0000000..f32bcf2 --- /dev/null +++ b/ontimize-jee-sdms-engine/ontimize-jee-sdms-engine-s3/src/main/java/com/ontimize/jee/sdms/engine/s3/command/OSdmsS3GetTemporalFilesCommand.java @@ -0,0 +1,163 @@ +package com.ontimize.jee.sdms.engine.s3.command; + +import com.amazonaws.services.s3.model.ListObjectsRequest; +import com.ontimize.jee.common.dto.EntityResult; +import com.ontimize.jee.sdms.common.command.IOSdmsCommand; +import com.ontimize.jee.sdms.common.inyector.IOSdmsInyector; +import com.ontimize.jee.sdms.common.response.builder.IOSdmsResponseBuilder; +import com.ontimize.jee.sdms.common.workspace.manager.IOSdmsWorkspaceManager; +import com.ontimize.jee.sdms.common.zip.IOSdmsZipCompressor; +import com.ontimize.jee.sdms.common.zip.OSdmsZipDto; +import com.ontimize.jee.sdms.engine.s3.repository.IOSdmsS3Repository; +import com.ontimize.jee.sdms.engine.s3.repository.OSdmsS3RepositoryProxy; +import com.ontimize.jee.sdms.engine.s3.repository.dto.OSdmsS3RepositoryDto; +import com.ontimize.jee.sdms.engine.s3.repository.response.OSdmsS3RepositoryResponse; +import com.ontimize.jee.sdms.engine.s3.repository.response.codes.OSdmsS3RepositoryResponseCodes; +import com.ontimize.jee.sdms.engine.s3.util.config.IOSdmsS3EngineConfig; +import com.ontimize.jee.sdms.engine.s3.util.input.filter.OSdmsS3InputFilter; +import com.ontimize.jee.sdms.engine.s3.util.input.filter.reader.IOSdmsS3FilterReader; +import com.ontimize.jee.sdms.engine.s3.util.normalize.IOSdmsS3KeyNormalize; +import com.ontimize.jee.sdms.engine.s3.util.response.mapper.IOSdmsS3ResponseMapper; + +import java.util.ArrayList; +import java.util.List; +import java.util.stream.Collectors; + + +/** + * Command to download files from S3 + */ +public class OSdmsS3GetTemporalFilesCommand implements IOSdmsCommand { + + + //Messages + private static final String MESSAGE_ERROR_NO_ACTIVE_WORKSPACE = "No active workspace found"; + private static final String MESSAGE_ERROR_NO_BUCKET = "No S3 bucket has been configured"; + private static final String MESSAGE_NO_CONTENT = "No file has been obtained from the query"; + + + // Dependencies + private IOSdmsS3Repository repository; + private IOSdmsResponseBuilder responseBuilder; + private IOSdmsS3ResponseMapper responseMapper; + private IOSdmsWorkspaceManager workspaceManager; + + + //Data + private String bucket; + private OSdmsS3InputFilter filter; + private List queries = new ArrayList<>(); + + + //Respone + private OSdmsS3RepositoryResponse response; + +// ------------------------------------------------------------------------------------------------------------------ \\ +// ------| ENTRYPOINT |---------------------------------------------------------------------------------------------- \\ +// ------------------------------------------------------------------------------------------------------------------ \\ + + public OSdmsS3GetTemporalFilesCommand( final OSdmsS3InputFilter filter ) { + this.filter = filter; + } + +// ------------------------------------------------------------------------------------------------------------------ \\ +// ------| INIT |--------------------------------------------------------------------------------------------------- \\ +// ------------------------------------------------------------------------------------------------------------------ \\ + + @Override + public void init( final IOSdmsInyector inyector ) { + //Inyect dependencies + this.repository = inyector.get( OSdmsS3RepositoryProxy.class ); + this.responseBuilder = inyector.get( IOSdmsResponseBuilder.class ); + this.responseMapper = inyector.get( IOSdmsS3ResponseMapper.class ); + this.workspaceManager = inyector.get( IOSdmsWorkspaceManager.class ); + final IOSdmsS3FilterReader filterParamReader = inyector.get( IOSdmsS3FilterReader.class ); + final IOSdmsS3EngineConfig s3EngineConfig = inyector.get( IOSdmsS3EngineConfig.class ); + final IOSdmsS3KeyNormalize keyNormalize = inyector.get( IOSdmsS3KeyNormalize.class ); + + //Get Data + this.workspaceManager.active( this.filter.getWorkspace(), this.filter.getData() ); + this.bucket = s3EngineConfig.getBucket(); + this.queries = filterParamReader.readAllKeys( this.filter ); + this.queries = this.queries.stream().map( keyNormalize::normalize ).collect( Collectors.toList() ); + } + +// ------------------------------------------------------------------------------------------------------------------ \\ +// ------| VALIDATE |------------------------------------------------------------------------------------------------ \\ +// ------------------------------------------------------------------------------------------------------------------ \\ + + @Override + public EntityResult validate() { + if( this.workspaceManager.getActive() == null ) { + return this.responseBuilder + .code( EntityResult.OPERATION_WRONG ) + .message( MESSAGE_ERROR_NO_ACTIVE_WORKSPACE ) + .build(); + } + + if( this.bucket == null ) { + return this.responseBuilder + .code( EntityResult.OPERATION_WRONG ) + .message( MESSAGE_ERROR_NO_BUCKET ) + .build(); + } + + return null; + } + +// ------------------------------------------------------------------------------------------------------------------ \\ +// ------| RUN |----------------------------------------------------------------------------------------------------- \\ +// ------------------------------------------------------------------------------------------------------------------ \\ + + @Override + public void run() { + final List requests = new ArrayList<>(); + + this.queries.forEach( prefix -> { + final ListObjectsRequest request = new ListObjectsRequest() + .withBucketName( this.bucket ) + .withPrefix( prefix ); + + if( this.filter.hasMaxKeys() ) request.withMaxKeys( this.filter.getMaxKeys() ); + if( this.filter.hasDelimiter() ) request.withDelimiter( this.filter.getDelimiter() ); + if( this.filter.hasMarker() ) request.withMarker( this.filter.getMarker() ); + + requests.add( request ); + } ); + + this.response = this.repository.download( requests ); + } + +// ------------------------------------------------------------------------------------------------------------------ \\ +// ------| RESPONSE |------------------------------------------------------------------------------------------------ \\ +// ------------------------------------------------------------------------------------------------------------------ \\ + + @Override + public EntityResult response() { + EntityResult result = null; + + if( this.response != null ) { + final OSdmsS3RepositoryResponseCodes code = this.response.getCode(); + if( code == OSdmsS3RepositoryResponseCodes.OK ) { + result = this.responseBuilder + .code( EntityResult.OPERATION_SUCCESSFUL ) + .message( MESSAGE_NO_CONTENT ) + .build(); + + List data = this.response.getData().stream() + .filter( target -> ! target.getName().equals( OSdmsS3RepositoryDto.FILE_NAME_MARK_FOLDER ) ) + .collect( Collectors.toList() ); + this.response.setData( data ); + + if( data != null && !data.isEmpty() ) result = this.responseMapper.map( this.response ); + } + } + + if( result == null ) result = this.responseMapper.map( this.response ); + + return result; + } + +// ------------------------------------------------------------------------------------------------------------------ \\ + +} diff --git a/ontimize-jee-sdms-engine/ontimize-jee-sdms-engine-s3/src/main/java/com/ontimize/jee/sdms/engine/s3/repository/OSdmsS3Repository.java b/ontimize-jee-sdms-engine/ontimize-jee-sdms-engine-s3/src/main/java/com/ontimize/jee/sdms/engine/s3/repository/OSdmsS3Repository.java index 029391e..91b95ce 100644 --- a/ontimize-jee-sdms-engine/ontimize-jee-sdms-engine-s3/src/main/java/com/ontimize/jee/sdms/engine/s3/repository/OSdmsS3Repository.java +++ b/ontimize-jee-sdms-engine/ontimize-jee-sdms-engine-s3/src/main/java/com/ontimize/jee/sdms/engine/s3/repository/OSdmsS3Repository.java @@ -5,6 +5,7 @@ import com.amazonaws.services.s3.transfer.TransferManager; import com.amazonaws.services.s3.transfer.TransferManagerBuilder; import com.amazonaws.services.s3.transfer.Upload; +import com.ontimize.jee.sdms.common.file.TemporalFileManager; import com.ontimize.jee.sdms.engine.s3.repository.dto.OSdmsS3RepositoryDto; import com.ontimize.jee.sdms.engine.s3.repository.response.OSdmsS3RepositoryResponse; import com.ontimize.jee.sdms.engine.s3.repository.response.builder.IOSdmsS3RepositoryResponseBuilder; @@ -54,6 +55,7 @@ public class OSdmsS3Repository implements IOSdmsS3Repository { /** The s3 repository response builder to build the response of each operation. */ private @Autowired IOSdmsS3RepositoryResponseBuilder oSdmsS3RepositoryResponseBuilder; + private @Autowired TemporalFileManager temporalFileManager; // ------------------------------------------------------------------------------------------------------------------ \\ // -------| FIND |--------------------------------------------------------------------------------------------------- \\ @@ -77,7 +79,7 @@ public OSdmsS3RepositoryResponse find( final ListObjectsRe final ObjectMetadata objectMetadata = this.amazonS3.getObjectMetadata( target.getBucketName(), target.getKey() ); - final OSdmsS3RepositoryDto dto = new OSdmsS3RepositoryDto(); + final OSdmsS3RepositoryDto dto = new OSdmsS3RepositoryDto( this.temporalFileManager ); dto.set( target ); dto.set( objectMetadata ); return dto; @@ -88,7 +90,7 @@ public OSdmsS3RepositoryResponse find( final ListObjectsRe final List commonPrefixes = requestResult.getCommonPrefixes(); if( commonPrefixes != null && ! commonPrefixes.isEmpty() ) { final List folders = commonPrefixes.stream().map( target -> { - final OSdmsS3RepositoryDto dto = new OSdmsS3RepositoryDto(); + final OSdmsS3RepositoryDto dto = new OSdmsS3RepositoryDto( this.temporalFileManager ); dto.setFolderData( request.getBucketName(), target ); return dto; } ).collect( Collectors.toList() ); @@ -146,7 +148,7 @@ public OSdmsS3RepositoryResponse download( final ListObjec final GetObjectRequest getObjectRequest = new GetObjectRequest( target.getBucket(), target.getKey() ); try( final S3Object s3Object = this.amazonS3.getObject( getObjectRequest )){ if( s3Object != null ) { - final OSdmsS3RepositoryDto dto = new OSdmsS3RepositoryDto(); + final OSdmsS3RepositoryDto dto = new OSdmsS3RepositoryDto( this.temporalFileManager ); dto.set( s3Object ); data.add( dto ); } diff --git a/ontimize-jee-sdms-engine/ontimize-jee-sdms-engine-s3/src/main/java/com/ontimize/jee/sdms/engine/s3/repository/dto/OSdmsS3RepositoryDto.java b/ontimize-jee-sdms-engine/ontimize-jee-sdms-engine-s3/src/main/java/com/ontimize/jee/sdms/engine/s3/repository/dto/OSdmsS3RepositoryDto.java index 90ab80e..bbd4326 100644 --- a/ontimize-jee-sdms-engine/ontimize-jee-sdms-engine-s3/src/main/java/com/ontimize/jee/sdms/engine/s3/repository/dto/OSdmsS3RepositoryDto.java +++ b/ontimize-jee-sdms-engine/ontimize-jee-sdms-engine-s3/src/main/java/com/ontimize/jee/sdms/engine/s3/repository/dto/OSdmsS3RepositoryDto.java @@ -4,10 +4,12 @@ import com.amazonaws.services.s3.model.Owner; import com.amazonaws.services.s3.model.S3Object; import com.amazonaws.services.s3.model.S3ObjectSummary; +import com.ontimize.jee.sdms.common.file.TemporalFileManager; import com.ontimize.jee.sdms.common.response.builder.IOSdmsMappeable; import com.ontimize.jee.sdms.common.zip.IOSdmsZippeable; import com.ontimize.jee.sdms.common.zip.OSdmsZipData; +import java.io.File; import java.io.IOException; import java.io.InputStream; import java.time.LocalDateTime; @@ -31,6 +33,8 @@ public class OSdmsS3RepositoryDto implements IOSdmsMappeable, IOSdmsZippeable { /** The name of the file that marks a folder in S3 */ public static final String FILE_NAME_MARK_FOLDER = ".ontimizeSdmsFolder"; + private final TemporalFileManager temporalFileManager; + /** The bucket name of S3 */ private String bucket; @@ -66,15 +70,17 @@ public class OSdmsS3RepositoryDto implements IOSdmsMappeable, IOSdmsZippeable { /** The metadata of S3 object */ private Map metadata; - /** The bytes of S3 file */ - private byte[] file; + /** The Temporal File of S3 file */ + private File file; // ------------------------------------------------------------------------------------------------------------------ \\ - public OSdmsS3RepositoryDto() { + public OSdmsS3RepositoryDto(final TemporalFileManager temporalFileManager ) { + this.temporalFileManager = temporalFileManager; } - public OSdmsS3RepositoryDto( final S3Object s3Object, final S3ObjectSummary s3ObjectSummary, final ObjectMetadata objectMetadata ) { + public OSdmsS3RepositoryDto( final TemporalFileManager temporalFileManager, final S3Object s3Object, final S3ObjectSummary s3ObjectSummary, final ObjectMetadata objectMetadata ) { + this.temporalFileManager = temporalFileManager; this.set( s3Object ); this.set( s3ObjectSummary ); this.set( objectMetadata ); @@ -186,11 +192,11 @@ public void setMetadata( final Map metadata ) { this.metadata = metadata; } - public byte[] getFile() { + public File getFile() { return this.file; } - public void setFile( final byte[] file ) { + public void setFile( final File file ) { this.file = file; } @@ -209,8 +215,8 @@ public void set( final S3Object s3Object ) { this.processKey( s3Object.getKey() ); this.bucket = s3Object.getBucketName(); try (final InputStream is = s3Object.getObjectContent()) { - this.file = is.readAllBytes(); - if( this.file != null ) this.size = (long) this.file.length; + this.file = this.temporalFileManager.create( this.key, is ); + if( this.file != null ) this.size = this.file.length(); } catch ( IOException e) { this.file = null; } @@ -358,7 +364,7 @@ public OSdmsZipData getDataToZip() { String fileName = sanitizedKey.replace( "/", "_" ); if( fileName.endsWith( "_" ) ) fileName = fileName.substring( 0, fileName.length() - 1 ); result = new OSdmsZipData(); - result.setFileContent( this.file ); + result.setFile( this.file ); result.setFileName( fileName ); } return result; diff --git a/ontimize-jee-sdms-engine/ontimize-jee-sdms-engine-s3/src/test/java/com/ontimize/jee/sdms/engine/s3/repository/dto/OSdmsS3RepositoryDtoTest.java b/ontimize-jee-sdms-engine/ontimize-jee-sdms-engine-s3/src/test/java/com/ontimize/jee/sdms/engine/s3/repository/dto/OSdmsS3RepositoryDtoTest.java index cfb348a..5d960eb 100644 --- a/ontimize-jee-sdms-engine/ontimize-jee-sdms-engine-s3/src/test/java/com/ontimize/jee/sdms/engine/s3/repository/dto/OSdmsS3RepositoryDtoTest.java +++ b/ontimize-jee-sdms-engine/ontimize-jee-sdms-engine-s3/src/test/java/com/ontimize/jee/sdms/engine/s3/repository/dto/OSdmsS3RepositoryDtoTest.java @@ -2,16 +2,19 @@ import com.amazonaws.services.s3.model.*; +import com.ontimize.jee.sdms.common.file.TemporalFileManager; import com.ontimize.jee.sdms.common.zip.OSdmsZipData; import org.apache.http.client.methods.HttpRequestBase; +import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; import org.junit.jupiter.params.ParameterizedTest; import org.junit.jupiter.params.provider.CsvSource; import org.mockito.Mockito; import java.io.ByteArrayInputStream; +import java.io.File; +import java.io.IOException; import java.io.InputStream; -import java.net.HttpURLConnection; import java.nio.charset.StandardCharsets; import java.text.SimpleDateFormat; import java.util.*; @@ -20,7 +23,14 @@ import static org.mockito.Mockito.*; class OSdmsS3RepositoryDtoTest { + private TemporalFileManager temporalFileManager; + @BeforeEach + void setUp() throws IOException { + this.temporalFileManager = mock( TemporalFileManager.class ); + when( this.temporalFileManager.create( any( InputStream.class )) ).thenReturn( new File( "temp.txt" ) ); + when( this.temporalFileManager.create( any( String.class ), any( InputStream.class )) ).thenReturn( new File( "temp.txt" ) ); + } // ------------------------------------------------------------------------------------------------------------------ \\ // --------| SET (S3Object) |---------------------------------------------------------------------------------------- \\ @@ -37,7 +47,7 @@ void givenAValidS3Object_whenSetS3Object_thenDataIsSet( final String givenKey, f final SimpleDateFormat formatDate = new SimpleDateFormat( "dd/MM/yyyy-HH:mm:ss" ); //Given - final OSdmsS3RepositoryDto dto = new OSdmsS3RepositoryDto(); + final OSdmsS3RepositoryDto dto = new OSdmsS3RepositoryDto( this.temporalFileManager ); final String givenBucket = "bucket"; final Long givenSize = 1L; final String givenCreationDate = "27/06/2023-10:30:20"; @@ -66,7 +76,7 @@ void givenAValidS3Object_whenSetS3Object_thenDataIsSet( final String givenKey, f final String key = dto.getKey(); final String prefix = dto.getPrefix(); final String name = dto.getName(); - final byte[] file = dto.getFile(); + final File file = dto.getFile(); final Date creationDate = dto.getCreationDate(); final Long size = dto.getSize(); final Map metadata = dto.getMetadata(); @@ -107,7 +117,7 @@ void givenAValidS3Object_whenSetS3Object_thenDataIsSet( final String givenKey, f }) void givenAValidS3ObjectSummary_whenSetS3ObjectSummary_thenDataIsSet( final String givenKey, final String expectedPrefix, final String expectedName ){ //Given - final OSdmsS3RepositoryDto dto = new OSdmsS3RepositoryDto(); + final OSdmsS3RepositoryDto dto = new OSdmsS3RepositoryDto( this.temporalFileManager ); final String givenBucket = "bucket"; final Long givenSize = 1L; final Date givenLastModified = new Date(); @@ -169,7 +179,7 @@ void givenAValidS3ObjectMetadata_whenSetS3ObjectMetadata_thenDataIsSet(){ final SimpleDateFormat formatDate = new SimpleDateFormat( "dd/MM/yyyy-HH:mm:ss" ); //Given - final OSdmsS3RepositoryDto dto = new OSdmsS3RepositoryDto(); + final OSdmsS3RepositoryDto dto = new OSdmsS3RepositoryDto( this.temporalFileManager ); final Long givenSize = 1L; final String givenCreationDate = "27/06/2023-10:30:20"; @@ -228,7 +238,7 @@ void givenAValidS3ObjectMetadata_whenSetS3ObjectMetadata_thenDataIsSet(){ void givenAValidFolderKey_whenSetFolderData_thenFolderDataIsSet( final String givenKey, final String expectedPrefix, final String expectedName ) { //Given final String givenBucket = "bucket"; - final OSdmsS3RepositoryDto dto = new OSdmsS3RepositoryDto(); + final OSdmsS3RepositoryDto dto = new OSdmsS3RepositoryDto( this.temporalFileManager ); //When dto.setFolderData( givenBucket, givenKey ); @@ -281,7 +291,7 @@ void givenAValidFolderKey_whenSetFolderData_thenFolderDataIsSet( final String gi void givenAValidKeyAndSpecificWorkspaces_whenSetRelativeKey_thenRelativeKeyIsSet( final String givenKey, final String expectedRelativeKey ) { //Given final List givenWorkspaces = Arrays.asList( "entity/1", "entity/5", "entity/10", "entity/50", "entity/images/top" ); - final OSdmsS3RepositoryDto dto = new OSdmsS3RepositoryDto(); + final OSdmsS3RepositoryDto dto = new OSdmsS3RepositoryDto( this.temporalFileManager ); dto.setKey( givenKey ); //When @@ -314,7 +324,7 @@ void givenAValidKeyAndSpecificWorkspaces_whenSetRelativeKey_thenRelativeKeyIsSet void givenAValidKeyAndSpecificWorkspaces_whenSetRelativePrefix_thenRelativePrefixIsSet( final String givenPrefix, final String expectedRelativePrefix ) { //Given final List givenWorkspaces = Arrays.asList( "entity/1", "entity/5", "entity/10", "entity/50", "entity/images/top" ); - final OSdmsS3RepositoryDto dto = new OSdmsS3RepositoryDto(); + final OSdmsS3RepositoryDto dto = new OSdmsS3RepositoryDto( this.temporalFileManager ); dto.setPrefix( givenPrefix ); //When @@ -380,7 +390,7 @@ void givenOSdmsS3RepositoryDto_whenCallToMap_thenBuildACorrectMap() { when( givenS3Object.getObjectMetadata() ).thenReturn( givenObjectMetadata ); //Set Data in DTO - final OSdmsS3RepositoryDto dto = new OSdmsS3RepositoryDto(); + final OSdmsS3RepositoryDto dto = new OSdmsS3RepositoryDto( this.temporalFileManager ); dto.set( givenS3ObjectSummary ); dto.set( givenS3Object ); dto.setRelativeKey( givenWorkspaces ); @@ -419,14 +429,13 @@ void givenOSdmsS3RepositoryDto_whenCallGetDataToZip_thenOSdmsZipData() { final String givenKey = "/entity/1/proof.txt"; final String givenName = "proof.txt"; final boolean givenFolder = false; - final byte[] givenFileBytes = "contenido de prueba".getBytes( StandardCharsets.UTF_8 ); //Set Data in DTO - final OSdmsS3RepositoryDto dto = new OSdmsS3RepositoryDto(); + final OSdmsS3RepositoryDto dto = new OSdmsS3RepositoryDto( this.temporalFileManager ); dto.setKey( givenKey ); dto.setName( givenName ); dto.setFolder( givenFolder ); - dto.setFile( givenFileBytes ); + dto.setFile( new File( givenName )); //When final OSdmsZipData result = dto.getDataToZip(); @@ -434,8 +443,8 @@ void givenOSdmsS3RepositoryDto_whenCallGetDataToZip_thenOSdmsZipData() { //Then assertNotNull( result, () -> "The result should not be null" ); - final byte[] fileContent = result.getFileContent(); - assertNotNull( fileContent, () -> "The File Content should not be null" ); + final File file = result.getFile(); + assertNotNull( file, () -> "The File should not be null" ); final String fileName = result.getFileName(); assertEquals( expectedFileName, fileName, () -> "Unexpected fileName" ); @@ -476,7 +485,7 @@ void givenS3Data_whenCallConstructor_thenCreateNewInstanceWithSameData(){ when( givenS3ObjectSummary.getOwner().getDisplayName() ).thenReturn( givenOwnerDisplayName ); //When - final OSdmsS3RepositoryDto result = new OSdmsS3RepositoryDto( givenS3Object, givenS3ObjectSummary, givenObjectMetadata ); + final OSdmsS3RepositoryDto result = new OSdmsS3RepositoryDto( this.temporalFileManager, givenS3Object, givenS3ObjectSummary, givenObjectMetadata ); //Then assertNotNull( result, () -> "The result should not be null" ); @@ -493,7 +502,7 @@ void givenS3Data_whenCallConstructor_thenCreateNewInstanceWithSameData(){ @Test void givenBucketNameAsString_whenCallSetBucket_thenCheckTheNewValueWithCallGetter(){ //Given - final OSdmsS3RepositoryDto dto = new OSdmsS3RepositoryDto(); + final OSdmsS3RepositoryDto dto = new OSdmsS3RepositoryDto( this.temporalFileManager ); final String givenBucketName = "bucket"; //When @@ -509,7 +518,7 @@ void givenBucketNameAsString_whenCallSetBucket_thenCheckTheNewValueWithCallGette @Test void givenKeyAsString_whenCallSetKey_thenCheckTheNewValueWithCallGetter(){ //Given - final OSdmsS3RepositoryDto dto = new OSdmsS3RepositoryDto(); + final OSdmsS3RepositoryDto dto = new OSdmsS3RepositoryDto( this.temporalFileManager ); final String givenKey = "key"; //When @@ -525,7 +534,7 @@ void givenKeyAsString_whenCallSetKey_thenCheckTheNewValueWithCallGetter(){ @Test void givenRelativeKeyAsString_whenCallSetRelativeKey_thenCheckTheNewValueWithCallGetter(){ //Given - final OSdmsS3RepositoryDto dto = new OSdmsS3RepositoryDto(); + final OSdmsS3RepositoryDto dto = new OSdmsS3RepositoryDto( this.temporalFileManager ); final String givenRelativeKey = "relativeKey"; //When @@ -541,7 +550,7 @@ void givenRelativeKeyAsString_whenCallSetRelativeKey_thenCheckTheNewValueWithCal @Test void givenRelativePrefixAsString_whenCallSetRelativePrefix_thenCheckTheNewValueWithCallGetter(){ //Given - final OSdmsS3RepositoryDto dto = new OSdmsS3RepositoryDto(); + final OSdmsS3RepositoryDto dto = new OSdmsS3RepositoryDto( this.temporalFileManager ); final String givenRelativePrefix = "relativePrefix"; //When @@ -557,7 +566,7 @@ void givenRelativePrefixAsString_whenCallSetRelativePrefix_thenCheckTheNewValueW @Test void givenPrefixAsString_whenCallSetPrefix_thenCheckTheNewValueWithCallGetter(){ //Given - final OSdmsS3RepositoryDto dto = new OSdmsS3RepositoryDto(); + final OSdmsS3RepositoryDto dto = new OSdmsS3RepositoryDto( this.temporalFileManager ); final String givenPrefix = "prefix"; //When @@ -573,7 +582,7 @@ void givenPrefixAsString_whenCallSetPrefix_thenCheckTheNewValueWithCallGetter(){ @Test void givenNameAsString_whenCallSetName_thenCheckTheNewValueWithCallGetter(){ //Given - final OSdmsS3RepositoryDto dto = new OSdmsS3RepositoryDto(); + final OSdmsS3RepositoryDto dto = new OSdmsS3RepositoryDto( this.temporalFileManager ); final String givenName = "name"; //When @@ -589,7 +598,7 @@ void givenNameAsString_whenCallSetName_thenCheckTheNewValueWithCallGetter(){ @Test void givenOwnerAsString_whenCallSetOwner_thenCheckTheNewValueWithCallGetter(){ //Given - final OSdmsS3RepositoryDto dto = new OSdmsS3RepositoryDto(); + final OSdmsS3RepositoryDto dto = new OSdmsS3RepositoryDto( this.temporalFileManager ); final String givenOwner = "owner"; //When @@ -605,7 +614,7 @@ void givenOwnerAsString_whenCallSetOwner_thenCheckTheNewValueWithCallGetter(){ @Test void givenSizeAsLong_whenCallSetSize_thenCheckTheNewValueWithCallGetter(){ //Given - final OSdmsS3RepositoryDto dto = new OSdmsS3RepositoryDto(); + final OSdmsS3RepositoryDto dto = new OSdmsS3RepositoryDto( this.temporalFileManager ); final Long givenSize = 1L; //When @@ -621,7 +630,7 @@ void givenSizeAsLong_whenCallSetSize_thenCheckTheNewValueWithCallGetter(){ @Test void givenFolderFlagAsBoolean_whenCallSetFolder_thenCheckTheNewValueWithCallGetter(){ //Given - final OSdmsS3RepositoryDto dto = new OSdmsS3RepositoryDto(); + final OSdmsS3RepositoryDto dto = new OSdmsS3RepositoryDto( this.temporalFileManager ); final boolean givenFolderFlag = true; //When @@ -637,7 +646,7 @@ void givenFolderFlagAsBoolean_whenCallSetFolder_thenCheckTheNewValueWithCallGett void givenCreationDateAsDate_whenCallSetCreationDate_thenCheckTheNewValueWithCallGetter() { //Given final Date givenCreationDate = new Date(); - final OSdmsS3RepositoryDto dto = new OSdmsS3RepositoryDto(); + final OSdmsS3RepositoryDto dto = new OSdmsS3RepositoryDto( this.temporalFileManager ); //When dto.setCreationDate( givenCreationDate ); @@ -654,7 +663,7 @@ void givenCreationDateAsString_whenCallSetCreationDate_thenCheckTheNewValueWithC //Given final String givenCreationDate = "27/06/2023-10:30:20"; - final OSdmsS3RepositoryDto dto = new OSdmsS3RepositoryDto(); + final OSdmsS3RepositoryDto dto = new OSdmsS3RepositoryDto( this.temporalFileManager ); //When dto.setCreationDate( givenCreationDate ); @@ -670,7 +679,7 @@ void givenCreationDateAsString_whenCallSetCreationDate_thenCheckTheNewValueWithC void givenLastModifiedAsDate_whenCallSetLastModified_thenCheckTheNewValueWithCallGetter() { //Given final Date givenLastModified = new Date(); - final OSdmsS3RepositoryDto dto = new OSdmsS3RepositoryDto(); + final OSdmsS3RepositoryDto dto = new OSdmsS3RepositoryDto( this.temporalFileManager ); //When dto.setLastModified( givenLastModified ); @@ -689,7 +698,7 @@ void givenMetadadataAsMap_whenCallSetMetadata_thenCheckTheNewValueWithCallGetter final Map givenMetadata = Mockito.mock( Map.class ); when( givenMetadata.size() ).thenReturn( expectedSize ); - final OSdmsS3RepositoryDto dto = new OSdmsS3RepositoryDto(); + final OSdmsS3RepositoryDto dto = new OSdmsS3RepositoryDto( this.temporalFileManager ); //When dto.setMetadata( givenMetadata ); @@ -705,14 +714,13 @@ void givenMetadadataAsMap_whenCallSetMetadata_thenCheckTheNewValueWithCallGetter @Test void givenFileAsBytes_whenCallSetFile_thenCheckTheNewValueWithCallGetter() { //Given - final byte[] givenFileBytes = "contenido de prueba".getBytes( StandardCharsets.UTF_8 ); - final OSdmsS3RepositoryDto dto = new OSdmsS3RepositoryDto(); + final OSdmsS3RepositoryDto dto = new OSdmsS3RepositoryDto(this.temporalFileManager ); //When - dto.setFile( givenFileBytes ); + dto.setFile( new File( "proof.tmp" ) ); //Then - final byte[] result = dto.getFile(); + final File result = dto.getFile(); assertNotNull( result, () -> "The result should not be null" ); } @@ -726,14 +734,13 @@ void givenOSdmsS3RepositoryDto_whenCallToString_thenCorrectStringRepresentation( final String givenKey = "/entity/1/proof.txt"; final String givenName = "proof.txt"; final boolean givenFolder = false; - final byte[] givenFileBytes = "contenido de prueba".getBytes( StandardCharsets.UTF_8 ); //Set Data in DTO - final OSdmsS3RepositoryDto dto = new OSdmsS3RepositoryDto(); + final OSdmsS3RepositoryDto dto = new OSdmsS3RepositoryDto( this.temporalFileManager ); dto.setKey( givenKey ); dto.setName( givenName ); dto.setFolder( givenFolder ); - dto.setFile( givenFileBytes ); + dto.setFile( new File( givenName )); //When final String result = dto.toString(); diff --git a/ontimize-jee-sdms-server/src/main/java/com/ontimize/jee/sdms/server/service/OSdmsService.java b/ontimize-jee-sdms-server/src/main/java/com/ontimize/jee/sdms/server/service/OSdmsService.java index 7a48e74..4524909 100644 --- a/ontimize-jee-sdms-server/src/main/java/com/ontimize/jee/sdms/server/service/OSdmsService.java +++ b/ontimize-jee-sdms-server/src/main/java/com/ontimize/jee/sdms/server/service/OSdmsService.java @@ -66,7 +66,12 @@ public EntityResult download( final OSdmsRestDataDto data ) { return this.engine.download( data ); } -// ------------------------------------------------------------------------------------------------------------------ \\ + @Override + public EntityResult getTemporalFiles( final OSdmsRestDataDto data ) { + return this.engine.getTemporalFiles( data ); + } + + // ------------------------------------------------------------------------------------------------------------------ \\ // -------| DMS - UPLOAD |------------------------------------------------------------------------------------------- \\ // ------------------------------------------------------------------------------------------------------------------ \\ diff --git a/pom.xml b/pom.xml index 4e16a70..dfa04c8 100644 --- a/pom.xml +++ b/pom.xml @@ -146,6 +146,12 @@ ${ontimize-jee.version} + + jakarta.annotation + jakarta.annotation-api + 2.1.1 + + org.reflections From a3ce7393a2efe1d8dd3079b390acf052bf47bb2b Mon Sep 17 00:00:00 2001 From: "angel.herce" Date: Fri, 25 Apr 2025 13:44:53 +0200 Subject: [PATCH 10/23] fix: TemporalFileManager fix cleanup and delete --- .../file/DefaultTemporalFileManager.java | 28 ++++++++++++------- .../sdms/common/file/TemporalFileManager.java | 4 +-- 2 files changed, 20 insertions(+), 12 deletions(-) diff --git a/ontimize-jee-sdms-common/src/main/java/com/ontimize/jee/sdms/common/file/DefaultTemporalFileManager.java b/ontimize-jee-sdms-common/src/main/java/com/ontimize/jee/sdms/common/file/DefaultTemporalFileManager.java index 4bd3c3a..8369457 100644 --- a/ontimize-jee-sdms-common/src/main/java/com/ontimize/jee/sdms/common/file/DefaultTemporalFileManager.java +++ b/ontimize-jee-sdms-common/src/main/java/com/ontimize/jee/sdms/common/file/DefaultTemporalFileManager.java @@ -5,10 +5,14 @@ import org.springframework.stereotype.Component; import org.springframework.web.context.annotation.RequestScope; -import java.io.*; +import java.io.File; +import java.io.FileOutputStream; +import java.io.IOException; +import java.io.InputStream; import java.nio.file.Files; import java.util.ArrayList; import java.util.List; +import java.util.Optional; import java.util.UUID; @Component @@ -39,18 +43,22 @@ public File create( final InputStream inputStream ) throws IOException { } @Override - public void delete( final File file ) { - this.files.stream().filter( target -> target.getAbsolutePath().equals( file.getAbsolutePath() ) ) - .findFirst() - .ifPresent( target -> { - this.files.remove( target ); - if( target.exists() ) target.delete(); - }); + public void delete( final File file ) throws IOException { + final Optional result = this.files.stream() + .filter( target -> target.getAbsolutePath().equals( file.getAbsolutePath() ) ) + .findFirst(); + if( result.isPresent() ){ + final File target = result.get(); + this.files.remove( target ); + if( target.exists() ) Files.delete( target.toPath() ); + } } @PreDestroy @Override - public void cleanUp() { - this.files.forEach( file -> { if( file.exists() ) file.delete(); }); + public void cleanUp() throws IOException { + for( final File file : this.files ){ + if( file.exists() ) Files.delete( file.toPath() ); + } } } diff --git a/ontimize-jee-sdms-common/src/main/java/com/ontimize/jee/sdms/common/file/TemporalFileManager.java b/ontimize-jee-sdms-common/src/main/java/com/ontimize/jee/sdms/common/file/TemporalFileManager.java index d2d0239..c52503f 100644 --- a/ontimize-jee-sdms-common/src/main/java/com/ontimize/jee/sdms/common/file/TemporalFileManager.java +++ b/ontimize-jee-sdms-common/src/main/java/com/ontimize/jee/sdms/common/file/TemporalFileManager.java @@ -8,6 +8,6 @@ public interface TemporalFileManager { File create( InputStream inputStream ) throws IOException; File create( String name, InputStream inputStream ) throws IOException; - void delete( File file ); - void cleanUp(); + void delete( File file ) throws IOException; + void cleanUp() throws IOException; } From b4cc36d9039c0fe491ad3c1e2e6e0222ea64a773 Mon Sep 17 00:00:00 2001 From: "angel.herce" Date: Mon, 28 Apr 2025 07:10:45 +0200 Subject: [PATCH 11/23] feat: Add component to auto remove temp files --- .../jee/sdms/common/file/DefaultTemporalFileManager.java | 4 +++- .../sdms/engine/s3/repository/dto/OSdmsS3RepositoryDto.java | 2 +- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/ontimize-jee-sdms-common/src/main/java/com/ontimize/jee/sdms/common/file/DefaultTemporalFileManager.java b/ontimize-jee-sdms-common/src/main/java/com/ontimize/jee/sdms/common/file/DefaultTemporalFileManager.java index 8369457..d82f8fb 100644 --- a/ontimize-jee-sdms-common/src/main/java/com/ontimize/jee/sdms/common/file/DefaultTemporalFileManager.java +++ b/ontimize-jee-sdms-common/src/main/java/com/ontimize/jee/sdms/common/file/DefaultTemporalFileManager.java @@ -2,6 +2,7 @@ import jakarta.annotation.PreDestroy; import org.springframework.beans.factory.annotation.Value; +import org.springframework.context.annotation.ScopedProxyMode; import org.springframework.stereotype.Component; import org.springframework.web.context.annotation.RequestScope; @@ -16,7 +17,7 @@ import java.util.UUID; @Component -@RequestScope +@RequestScope( proxyMode = ScopedProxyMode.TARGET_CLASS ) public class DefaultTemporalFileManager implements TemporalFileManager{ @Value( "${ontimize.sdms.file.temporal.directory}" ) @@ -60,5 +61,6 @@ public void cleanUp() throws IOException { for( final File file : this.files ){ if( file.exists() ) Files.delete( file.toPath() ); } + this.files.clear(); } } diff --git a/ontimize-jee-sdms-engine/ontimize-jee-sdms-engine-s3/src/main/java/com/ontimize/jee/sdms/engine/s3/repository/dto/OSdmsS3RepositoryDto.java b/ontimize-jee-sdms-engine/ontimize-jee-sdms-engine-s3/src/main/java/com/ontimize/jee/sdms/engine/s3/repository/dto/OSdmsS3RepositoryDto.java index bbd4326..0786fb6 100644 --- a/ontimize-jee-sdms-engine/ontimize-jee-sdms-engine-s3/src/main/java/com/ontimize/jee/sdms/engine/s3/repository/dto/OSdmsS3RepositoryDto.java +++ b/ontimize-jee-sdms-engine/ontimize-jee-sdms-engine-s3/src/main/java/com/ontimize/jee/sdms/engine/s3/repository/dto/OSdmsS3RepositoryDto.java @@ -215,7 +215,7 @@ public void set( final S3Object s3Object ) { this.processKey( s3Object.getKey() ); this.bucket = s3Object.getBucketName(); try (final InputStream is = s3Object.getObjectContent()) { - this.file = this.temporalFileManager.create( this.key, is ); + this.file = this.temporalFileManager.create( is ); if( this.file != null ) this.size = this.file.length(); } catch ( IOException e) { this.file = null; From ee03d9a49ad0e4349ad92e03bd86b1eaec9390b9 Mon Sep 17 00:00:00 2001 From: "angel.herce" Date: Mon, 28 Apr 2025 09:16:25 +0200 Subject: [PATCH 12/23] feat: Add filter to auto remove temp files --- .../file/DefaultTemporalFileManager.java | 5 --- .../sdms/rest/filter/TemporalFilesFilter.java | 31 +++++++++++++++++++ 2 files changed, 31 insertions(+), 5 deletions(-) create mode 100644 ontimize-jee-sdms-rest/src/main/java/com/ontimize/jee/sdms/rest/filter/TemporalFilesFilter.java diff --git a/ontimize-jee-sdms-common/src/main/java/com/ontimize/jee/sdms/common/file/DefaultTemporalFileManager.java b/ontimize-jee-sdms-common/src/main/java/com/ontimize/jee/sdms/common/file/DefaultTemporalFileManager.java index d82f8fb..1dbcc66 100644 --- a/ontimize-jee-sdms-common/src/main/java/com/ontimize/jee/sdms/common/file/DefaultTemporalFileManager.java +++ b/ontimize-jee-sdms-common/src/main/java/com/ontimize/jee/sdms/common/file/DefaultTemporalFileManager.java @@ -1,10 +1,7 @@ package com.ontimize.jee.sdms.common.file; -import jakarta.annotation.PreDestroy; import org.springframework.beans.factory.annotation.Value; -import org.springframework.context.annotation.ScopedProxyMode; import org.springframework.stereotype.Component; -import org.springframework.web.context.annotation.RequestScope; import java.io.File; import java.io.FileOutputStream; @@ -17,7 +14,6 @@ import java.util.UUID; @Component -@RequestScope( proxyMode = ScopedProxyMode.TARGET_CLASS ) public class DefaultTemporalFileManager implements TemporalFileManager{ @Value( "${ontimize.sdms.file.temporal.directory}" ) @@ -55,7 +51,6 @@ public void delete( final File file ) throws IOException { } } - @PreDestroy @Override public void cleanUp() throws IOException { for( final File file : this.files ){ diff --git a/ontimize-jee-sdms-rest/src/main/java/com/ontimize/jee/sdms/rest/filter/TemporalFilesFilter.java b/ontimize-jee-sdms-rest/src/main/java/com/ontimize/jee/sdms/rest/filter/TemporalFilesFilter.java new file mode 100644 index 0000000..8b9eb56 --- /dev/null +++ b/ontimize-jee-sdms-rest/src/main/java/com/ontimize/jee/sdms/rest/filter/TemporalFilesFilter.java @@ -0,0 +1,31 @@ +package com.ontimize.jee.sdms.rest.filter; + +import com.ontimize.jee.sdms.common.file.TemporalFileManager; +import jakarta.servlet.*; +import org.springframework.stereotype.Component; + +import java.io.IOException; + +@Component +public class TemporalFilesFilter implements Filter{ + + private final TemporalFileManager temporalFileManager; + + public TemporalFilesFilter( final TemporalFileManager temporalFileManager ) { + this.temporalFileManager = temporalFileManager; + } + + @Override + public void doFilter( + final ServletRequest servletRequest, + final ServletResponse servletResponse, + final FilterChain filterChain + ) throws IOException, ServletException { + try{ + filterChain.doFilter( servletRequest, servletResponse ); + } + finally { + this.temporalFileManager.cleanUp(); + } + } +} From 74f92344c6629c9d9b5661d436bb42e7e28d1543 Mon Sep 17 00:00:00 2001 From: "angel.herce" Date: Mon, 28 Apr 2025 09:20:58 +0200 Subject: [PATCH 13/23] fix: Add new dependency --- ontimize-jee-sdms-rest/pom.xml | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/ontimize-jee-sdms-rest/pom.xml b/ontimize-jee-sdms-rest/pom.xml index 7e27a5b..493f2c1 100644 --- a/ontimize-jee-sdms-rest/pom.xml +++ b/ontimize-jee-sdms-rest/pom.xml @@ -51,6 +51,12 @@ ontimize-jee-sdms-common + + jakarta.servlet + jakarta.servlet-api + 5.0.0 + + com.ontimize.jee From 57f65604bc12ceb21261ba88134c78c5f8dd59cf Mon Sep 17 00:00:00 2001 From: "angel.herce" Date: Mon, 28 Apr 2025 09:54:04 +0200 Subject: [PATCH 14/23] fix: Remove filter to remove temporal files --- ontimize-jee-sdms-rest/pom.xml | 6 ---- .../sdms/rest/filter/TemporalFilesFilter.java | 31 ------------------- 2 files changed, 37 deletions(-) delete mode 100644 ontimize-jee-sdms-rest/src/main/java/com/ontimize/jee/sdms/rest/filter/TemporalFilesFilter.java diff --git a/ontimize-jee-sdms-rest/pom.xml b/ontimize-jee-sdms-rest/pom.xml index 493f2c1..7e27a5b 100644 --- a/ontimize-jee-sdms-rest/pom.xml +++ b/ontimize-jee-sdms-rest/pom.xml @@ -51,12 +51,6 @@ ontimize-jee-sdms-common - - jakarta.servlet - jakarta.servlet-api - 5.0.0 - - com.ontimize.jee diff --git a/ontimize-jee-sdms-rest/src/main/java/com/ontimize/jee/sdms/rest/filter/TemporalFilesFilter.java b/ontimize-jee-sdms-rest/src/main/java/com/ontimize/jee/sdms/rest/filter/TemporalFilesFilter.java deleted file mode 100644 index 8b9eb56..0000000 --- a/ontimize-jee-sdms-rest/src/main/java/com/ontimize/jee/sdms/rest/filter/TemporalFilesFilter.java +++ /dev/null @@ -1,31 +0,0 @@ -package com.ontimize.jee.sdms.rest.filter; - -import com.ontimize.jee.sdms.common.file.TemporalFileManager; -import jakarta.servlet.*; -import org.springframework.stereotype.Component; - -import java.io.IOException; - -@Component -public class TemporalFilesFilter implements Filter{ - - private final TemporalFileManager temporalFileManager; - - public TemporalFilesFilter( final TemporalFileManager temporalFileManager ) { - this.temporalFileManager = temporalFileManager; - } - - @Override - public void doFilter( - final ServletRequest servletRequest, - final ServletResponse servletResponse, - final FilterChain filterChain - ) throws IOException, ServletException { - try{ - filterChain.doFilter( servletRequest, servletResponse ); - } - finally { - this.temporalFileManager.cleanUp(); - } - } -} From 211574cb2b24dc483503936bd63a789448a97f0f Mon Sep 17 00:00:00 2001 From: "angel.herce" Date: Mon, 28 Apr 2025 09:54:24 +0200 Subject: [PATCH 15/23] feat: Add method to remove temporal files --- .../common/file/DefaultTemporalFileManager.java | 14 ++++++++------ .../jee/sdms/server/service/IOSdmsService.java | 2 ++ .../jee/sdms/server/service/OSdmsService.java | 16 +++++++++++++++- 3 files changed, 25 insertions(+), 7 deletions(-) diff --git a/ontimize-jee-sdms-common/src/main/java/com/ontimize/jee/sdms/common/file/DefaultTemporalFileManager.java b/ontimize-jee-sdms-common/src/main/java/com/ontimize/jee/sdms/common/file/DefaultTemporalFileManager.java index 1dbcc66..b1aa400 100644 --- a/ontimize-jee-sdms-common/src/main/java/com/ontimize/jee/sdms/common/file/DefaultTemporalFileManager.java +++ b/ontimize-jee-sdms-common/src/main/java/com/ontimize/jee/sdms/common/file/DefaultTemporalFileManager.java @@ -19,7 +19,7 @@ public class DefaultTemporalFileManager implements TemporalFileManager{ @Value( "${ontimize.sdms.file.temporal.directory}" ) private String temporalDirectory; - private final List files = new ArrayList<>(); + private static final ThreadLocal> FILES = new ThreadLocal<>(); @Override public File create( final String name, final InputStream inputStream ) throws IOException { @@ -30,7 +30,8 @@ public File create( final String name, final InputStream inputStream ) throws IO try( FileOutputStream fos = new FileOutputStream( file)) { inputStream.transferTo(fos); } - this.files.add( file ); + if( FILES.get() == null ) FILES.set( new ArrayList<>() ); + FILES.get().add( file ); return file; } @@ -41,21 +42,22 @@ public File create( final InputStream inputStream ) throws IOException { @Override public void delete( final File file ) throws IOException { - final Optional result = this.files.stream() + if( FILES.get() == null ) return; + final Optional result = FILES.get().stream() .filter( target -> target.getAbsolutePath().equals( file.getAbsolutePath() ) ) .findFirst(); if( result.isPresent() ){ final File target = result.get(); - this.files.remove( target ); + FILES.get().remove( target ); if( target.exists() ) Files.delete( target.toPath() ); } } @Override public void cleanUp() throws IOException { - for( final File file : this.files ){ + for( final File file : FILES.get() ){ if( file.exists() ) Files.delete( file.toPath() ); } - this.files.clear(); + FILES.remove(); } } diff --git a/ontimize-jee-sdms-server/src/main/java/com/ontimize/jee/sdms/server/service/IOSdmsService.java b/ontimize-jee-sdms-server/src/main/java/com/ontimize/jee/sdms/server/service/IOSdmsService.java index 9980ecf..af5ac3c 100644 --- a/ontimize-jee-sdms-server/src/main/java/com/ontimize/jee/sdms/server/service/IOSdmsService.java +++ b/ontimize-jee-sdms-server/src/main/java/com/ontimize/jee/sdms/server/service/IOSdmsService.java @@ -24,4 +24,6 @@ public interface IOSdmsService extends IOSdmsAction { */ void setEngine( IOSdmsEngine engine ); + void removeTemporalFiles(); + } diff --git a/ontimize-jee-sdms-server/src/main/java/com/ontimize/jee/sdms/server/service/OSdmsService.java b/ontimize-jee-sdms-server/src/main/java/com/ontimize/jee/sdms/server/service/OSdmsService.java index 4524909..0f63252 100644 --- a/ontimize-jee-sdms-server/src/main/java/com/ontimize/jee/sdms/server/service/OSdmsService.java +++ b/ontimize-jee-sdms-server/src/main/java/com/ontimize/jee/sdms/server/service/OSdmsService.java @@ -4,12 +4,14 @@ import com.ontimize.jee.sdms.common.dto.OSdmsRestDataDto; import com.ontimize.jee.sdms.common.engine.IOSdmsEngine; import com.ontimize.jee.sdms.common.event.handler.IOSdmsEventHandler; +import com.ontimize.jee.sdms.common.file.TemporalFileManager; import com.ontimize.jee.sdms.server.service.event.*; import org.springframework.beans.factory.InitializingBean; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Component; import org.springframework.web.multipart.MultipartFile; +import java.io.IOException; import java.io.Serializable; @@ -27,6 +29,8 @@ public class OSdmsService implements IOSdmsService { private @Autowired IOSdmsEngine engine; + private @Autowired TemporalFileManager temporalFileManager; + // ------------------------------------------------------------------------------------------------------------------ \\ @Override @@ -34,7 +38,17 @@ public void setEngine( final IOSdmsEngine engine ) { this.engine = engine; } -// ------------------------------------------------------------------------------------------------------------------ \\ + @Override + public void removeTemporalFiles() { + try { + this.temporalFileManager.cleanUp(); + } + catch( final IOException e ) { + throw new RuntimeException( e ); + } + } + + // ------------------------------------------------------------------------------------------------------------------ \\ // -------| DMS - FIND |--------------------------------------------------------------------------------------------- \\ // ------------------------------------------------------------------------------------------------------------------ \\ From 11b45cb3f16dbd2bca94c36b866e7307b2bb5f53 Mon Sep 17 00:00:00 2001 From: "angel.herce" Date: Tue, 29 Apr 2025 12:05:40 +0200 Subject: [PATCH 16/23] fix: Correct NullPointerException --- .../sdms/common/file/DefaultTemporalFileManager.java | 11 +++++------ 1 file changed, 5 insertions(+), 6 deletions(-) diff --git a/ontimize-jee-sdms-common/src/main/java/com/ontimize/jee/sdms/common/file/DefaultTemporalFileManager.java b/ontimize-jee-sdms-common/src/main/java/com/ontimize/jee/sdms/common/file/DefaultTemporalFileManager.java index b1aa400..c66e217 100644 --- a/ontimize-jee-sdms-common/src/main/java/com/ontimize/jee/sdms/common/file/DefaultTemporalFileManager.java +++ b/ontimize-jee-sdms-common/src/main/java/com/ontimize/jee/sdms/common/file/DefaultTemporalFileManager.java @@ -27,8 +27,8 @@ public File create( final String name, final InputStream inputStream ) throws IO final File file; if( directory.exists() && directory.isDirectory() ) file = File.createTempFile( name, ".tmp", directory ); else file = File.createTempFile( name, ".tmp" ); - try( FileOutputStream fos = new FileOutputStream( file)) { - inputStream.transferTo(fos); + try( FileOutputStream fos = new FileOutputStream( file )) { + inputStream.transferTo( fos ); } if( FILES.get() == null ) FILES.set( new ArrayList<>() ); FILES.get().add( file ); @@ -44,7 +44,7 @@ public File create( final InputStream inputStream ) throws IOException { public void delete( final File file ) throws IOException { if( FILES.get() == null ) return; final Optional result = FILES.get().stream() - .filter( target -> target.getAbsolutePath().equals( file.getAbsolutePath() ) ) + .filter( target -> target.getAbsolutePath().equals( file.getAbsolutePath() )) .findFirst(); if( result.isPresent() ){ final File target = result.get(); @@ -55,9 +55,8 @@ public void delete( final File file ) throws IOException { @Override public void cleanUp() throws IOException { - for( final File file : FILES.get() ){ - if( file.exists() ) Files.delete( file.toPath() ); - } + if( FILES.get() == null ) return; + for( final File file : FILES.get() ) if( file.exists() ) Files.delete( file.toPath() ); FILES.remove(); } } From 9f6a1cc0de53c8c4acf96799124f803cc0dc4706 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Pablo=20Mart=C3=ADnez=20Kirsten?= Date: Mon, 12 May 2025 15:07:20 +0200 Subject: [PATCH 17/23] Update GitHub Actions and pom.xml for deploying with Maven Central Plugin instead of OSSRH --- .../workflows/deploy-mvn-central-release.yml | 4 +- .../workflows/deploy-mvn-central-snapshot.yml | 4 +- pom.xml | 38 +++++-------------- 3 files changed, 14 insertions(+), 32 deletions(-) diff --git a/.github/workflows/deploy-mvn-central-release.yml b/.github/workflows/deploy-mvn-central-release.yml index 9eafd5d..584216f 100644 --- a/.github/workflows/deploy-mvn-central-release.yml +++ b/.github/workflows/deploy-mvn-central-release.yml @@ -33,11 +33,11 @@ jobs: ref: ${{ env.BRANCH }} fetch-depth: 0 - name: Setup Java JDK and Maven - uses: ontimize/setup-java-maven-gitAction@v4 + uses: actions/setup-java@v4 with: distribution: 'temurin' java-version: '11' - server-id: ossrh + server-id: central server-username: MAVEN_USERNAME server-password: MAVEN_CENTRAL_TOKEN gpg-private-key: ${{ secrets.MAVEN_GPG_PRIVATE_KEY }} diff --git a/.github/workflows/deploy-mvn-central-snapshot.yml b/.github/workflows/deploy-mvn-central-snapshot.yml index d9b330c..737464b 100644 --- a/.github/workflows/deploy-mvn-central-snapshot.yml +++ b/.github/workflows/deploy-mvn-central-snapshot.yml @@ -15,11 +15,11 @@ jobs: - name: Checkout repository code uses: actions/checkout@v4 - name: Setup Java JDK and Maven - uses: ontimize/setup-java-maven-gitAction@v4 + uses: actions/setup-java@v4 with: distribution: 'temurin' java-version: '11' - server-id: ossrh + server-id: central server-username: MAVEN_USERNAME server-password: MAVEN_CENTRAL_TOKEN gpg-private-key: ${{ secrets.MAVEN_GPG_PRIVATE_KEY }} diff --git a/pom.xml b/pom.xml index dfa04c8..464a77e 100644 --- a/pom.xml +++ b/pom.xml @@ -43,17 +43,6 @@ https://github.com/ontimize/ontimize-jee-sdms.git/tree/main - - - ossrh - https://s01.oss.sonatype.org/service/local/staging/deploy/maven2/ - - - ossrh - https://s01.oss.sonatype.org/content/repositories/snapshots - - - ontimize-jee-sdms-common ontimize-jee-sdms-event @@ -81,17 +70,16 @@ 3.8.1 1.0 - 3.0.0-M1 2.8 3.0.1 3.0.2 3.2.0 - 1.6.7 3.2.0 3.2.1 2.4 3.0.0-M5 3.0.0-M5 + 0.7.0 @@ -192,11 +180,6 @@ - - org.apache.maven.plugins - maven-deploy-plugin - ${deploy.plugin.version} - org.apache.maven.plugins maven-source-plugin @@ -261,8 +244,8 @@ - sonatype-snapshot - https://s01.oss.sonatype.org/content/repositories/snapshots/ + central-portal-snapshots + https://central.sonatype.com/repository/maven-snapshots/ false @@ -276,8 +259,8 @@ generate-version - sonatype-snapshot - https://s01.oss.sonatype.org/content/repositories/snapshots/ + central-portal-snapshots + https://central.sonatype.com/repository/maven-snapshots/ false @@ -299,14 +282,13 @@ maven-javadoc-plugin - org.sonatype.plugins - nexus-staging-maven-plugin - ${nexus-staging-maven-plugin.version} + org.sonatype.central + central-publishing-maven-plugin + ${central-publishing-maven-plugin.version} true - ossrh - https://s01.oss.sonatype.org/ - true + central + true From 963de5183d79fddc869c15d8d6fd7b027b4f90ce Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Pablo=20Mart=C3=ADnez=20Kirsten?= Date: Mon, 12 May 2025 16:03:20 +0200 Subject: [PATCH 18/23] Update GitHub Actions and pom.xml for deploying with Maven Central Plugin instead of OSSRH --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index 464a77e..a83bacd 100644 --- a/pom.xml +++ b/pom.xml @@ -13,7 +13,7 @@ com.ontimize.jee ontimize-jee - 5.7.0 + 5.13.0-SNAPSHOT From 0c931564bc8faeccdde936bfe2d0aa0860329e7c Mon Sep 17 00:00:00 2001 From: "angel.herce" Date: Tue, 13 May 2025 08:19:43 +0200 Subject: [PATCH 19/23] fix: Update README.md --- README.md | 25 +++++++++++++++---------- 1 file changed, 15 insertions(+), 10 deletions(-) diff --git a/README.md b/README.md index 10da88d..45a4cfc 100644 --- a/README.md +++ b/README.md @@ -1,11 +1,16 @@ -# Ontimize JEE Storage DMS +# Ontimize JEE Storage SDMS + ## 📜 Introduction -Ontimize JEE Storage DMS is a module of the Ontimize framework that provides a document management solution for Java Enterprise Edition (JEE) based enterprise applications. This module enables organizations to store and manage documents within their enterprise applications. -## ✍ Use -To use the module, you only need to import it into your project to be able to use it. On the entity that is required to have the DMS endpoints, you will have to extend the drivers and add the corresponding DMS methods to the entity services. For more information, see the [documentation](). -## 💼 Documentation -All documentation related to how to use it in a project, tutorials and details of its systems and usage can be found online by accessing the link about [Ontimize Boot documentation](https://ontimize.github.io/docs/). -## 👁️‍🗨️ Versions and dependencies -All the versions and dependencies of the artifacts contained in this project can be downloaded from [Maven Central](https://central.sonatype.dev/namespace/com.ontimize.boot), as well as knowing each of its dependencies. -## :gear: Changelog -You can consult our changelog at the following [link](CHANGELOG.md) \ No newline at end of file +Ontimize JEE Storage SDMS es un módulo del framework Ontimize que proporciona una solución de gestión documental para aplicaciones empresariales basadas en Java Enterprise Edition (JEE). Este módulo permite a las organizaciones almacenar y gestionar documentos dentro de sus aplicaciones empresariales. + +## ✍ Uso +Para utilizar este módulo, solo necesitas importarlo en tu proyecto. En la entidad que requiera disponer de los endpoints SDMS, tendrás que extender los drivers y añadir los métodos SDMS correspondientes en los servicios de dicha entidad. Para más información, consulta la [documentación](https://ontimize.github.io/docs/v3/systems/sdms/). + +## 💼 Documentación +Toda la documentación relacionada con su uso en proyectos, tutoriales y detalles de sus sistemas y modos de uso puede encontrarse en línea, accediendo al siguiente enlace de la [documentación de Ontimize Boot](https://ontimize.github.io/docs/). + +## 👁️‍🗨️ Versiones y dependencias +Todas las versiones y dependencias de los artefactos contenidos en este proyecto pueden descargarse desde [Maven Central](https://central.sonatype.dev/namespace/com.ontimize.boot), así como conocer cada una de sus dependencias. + +## 📣 Registro de cambios +Puedes consultar nuestro registro de cambios en el siguiente [enlace](CHANGELOG.md) From 1f38db937f6e323a5cce2e6c379c90f212ae2135 Mon Sep 17 00:00:00 2001 From: supportontimize Date: Tue, 13 May 2025 07:42:46 +0000 Subject: [PATCH 20/23] =?UTF-8?q?New=20release=20=E2=86=92=201.4.0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- ontimize-jee-sdms-common/pom.xml | 4 ++-- ontimize-jee-sdms-engine/ontimize-jee-sdms-engine-s3/pom.xml | 4 ++-- ontimize-jee-sdms-engine/pom.xml | 4 ++-- ontimize-jee-sdms-event/pom.xml | 4 ++-- ontimize-jee-sdms-rest/pom.xml | 4 ++-- ontimize-jee-sdms-server/pom.xml | 4 ++-- pom.xml | 2 +- 7 files changed, 13 insertions(+), 13 deletions(-) diff --git a/ontimize-jee-sdms-common/pom.xml b/ontimize-jee-sdms-common/pom.xml index f768e48..3bc2fa7 100644 --- a/ontimize-jee-sdms-common/pom.xml +++ b/ontimize-jee-sdms-common/pom.xml @@ -5,7 +5,7 @@ 4.0.0 com.ontimize.jee.sdms ontimize-jee-sdms-common - 1.4.0-SNAPSHOT + 1.4.0 jar Ontimize EE SDMS (Common module) Ontimize EE Storage DMS (SDMS) - Common module @@ -14,7 +14,7 @@ com.ontimize.jee.sdms ontimize-jee-sdms - 1.4.0-SNAPSHOT + 1.4.0 diff --git a/ontimize-jee-sdms-engine/ontimize-jee-sdms-engine-s3/pom.xml b/ontimize-jee-sdms-engine/ontimize-jee-sdms-engine-s3/pom.xml index 19d3c39..c094050 100644 --- a/ontimize-jee-sdms-engine/ontimize-jee-sdms-engine-s3/pom.xml +++ b/ontimize-jee-sdms-engine/ontimize-jee-sdms-engine-s3/pom.xml @@ -5,7 +5,7 @@ 4.0.0 com.ontimize.jee.sdms ontimize-jee-sdms-engine-s3 - 1.4.0-SNAPSHOT + 1.4.0 jar Ontimize EE SDMS (Engine S3 module) Ontimize EE Storage DMS (SDMS) - Engine S3 module @@ -14,7 +14,7 @@ com.ontimize.jee.sdms ontimize-jee-sdms-engine - 1.4.0-SNAPSHOT + 1.4.0 diff --git a/ontimize-jee-sdms-engine/pom.xml b/ontimize-jee-sdms-engine/pom.xml index aba6f9f..60a162b 100644 --- a/ontimize-jee-sdms-engine/pom.xml +++ b/ontimize-jee-sdms-engine/pom.xml @@ -5,7 +5,7 @@ 4.0.0 com.ontimize.jee.sdms ontimize-jee-sdms-engine - 1.4.0-SNAPSHOT + 1.4.0 pom Ontimize EE SDMS (Engine module) Ontimize EE Storage DMS (SDMS) - Engine module @@ -17,7 +17,7 @@ com.ontimize.jee.sdms ontimize-jee-sdms - 1.4.0-SNAPSHOT + 1.4.0 diff --git a/ontimize-jee-sdms-event/pom.xml b/ontimize-jee-sdms-event/pom.xml index 346c7a3..8e6d2e7 100644 --- a/ontimize-jee-sdms-event/pom.xml +++ b/ontimize-jee-sdms-event/pom.xml @@ -5,7 +5,7 @@ 4.0.0 com.ontimize.jee.sdms ontimize-jee-sdms-event - 1.4.0-SNAPSHOT + 1.4.0 jar Ontimize EE SDMS (Event module) Ontimize EE Storage DMS (SDMS) - Event module @@ -14,7 +14,7 @@ com.ontimize.jee.sdms ontimize-jee-sdms - 1.4.0-SNAPSHOT + 1.4.0 diff --git a/ontimize-jee-sdms-rest/pom.xml b/ontimize-jee-sdms-rest/pom.xml index 7e27a5b..39b963d 100644 --- a/ontimize-jee-sdms-rest/pom.xml +++ b/ontimize-jee-sdms-rest/pom.xml @@ -5,7 +5,7 @@ 4.0.0 com.ontimize.jee.sdms ontimize-jee-sdms-rest - 1.4.0-SNAPSHOT + 1.4.0 jar Ontimize EE SDMS (Rest module) Ontimize EE Storage DMS (SDMS) - Rest module @@ -14,7 +14,7 @@ com.ontimize.jee.sdms ontimize-jee-sdms - 1.4.0-SNAPSHOT + 1.4.0 diff --git a/ontimize-jee-sdms-server/pom.xml b/ontimize-jee-sdms-server/pom.xml index 9322091..f105792 100644 --- a/ontimize-jee-sdms-server/pom.xml +++ b/ontimize-jee-sdms-server/pom.xml @@ -5,7 +5,7 @@ 4.0.0 com.ontimize.jee.sdms ontimize-jee-sdms-server - 1.4.0-SNAPSHOT + 1.4.0 jar Ontimize EE SDMS (Server module) Ontimize EE Storage DMS (SDMS) - Server module @@ -14,7 +14,7 @@ com.ontimize.jee.sdms ontimize-jee-sdms - 1.4.0-SNAPSHOT + 1.4.0 diff --git a/pom.xml b/pom.xml index a83bacd..d6d7b84 100644 --- a/pom.xml +++ b/pom.xml @@ -4,7 +4,7 @@ 4.0.0 com.ontimize.jee.sdms ontimize-jee-sdms - 1.4.0-SNAPSHOT + 1.4.0 pom Ontimize EE SDMS Ontimize EE Storage DMS (SDMS) is a system for storing and managing files by entity. From 147eaeb81d6a3d77a4c0d3e80fe3b82ffe5b8415 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C3=81ngel=20Herce=20Soto?= <97441532+angelherce@users.noreply.github.com> Date: Tue, 13 May 2025 09:47:01 +0200 Subject: [PATCH 21/23] Update CHANGELOG.md --- CHANGELOG.md | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 72d64c5..32cf47d 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -9,14 +9,15 @@ ## [Unreleased] +## [1.4.0] - 2025-05-13 + ### Added ✔️ -- The `TemporalFileManager` has been created to manage temporary files per request. +* The `TemporalFileManager` has been created to manage temporary files per request. * **OSdmsService:** Added `getTemporalFiles` method has been added to `OSdmsService`. - ### Fixed 🐛 -- Closed `S3ObjectInputStream` instances properly to avoid `CLOSE_WAIT` socket issues and potential memory/resource leaks during file download operations. +* Closed `S3ObjectInputStream` instances properly to avoid `CLOSE_WAIT` socket issues and potential memory/resource leaks during file download operations. ### Changed 🛠️ * **S3 Connection:** The connection to S3 has been optimized. @@ -77,9 +78,10 @@ * **OSdmsWorkspace Annotation:** Added an annotation to establish multiple query workspaces on the DMS system for an entity. -[unreleased]: https://github.com/ontimize/ontimize-jee-sdms/compare/1.3.1...HEAD +[unreleased]: https://github.com/ontimize/ontimize-jee-sdms/compare/1.4.0...HEAD +[1.4.0]: https://github.com/ontimize/ontimize-jee-sdms/compare/1.3.1...1.4.0 [1.3.1]: https://github.com/ontimize/ontimize-jee-sdms/compare/1.3.0...1.3.1 [1.3.0]: https://github.com/ontimize/ontimize-jee-sdms/compare/1.2.0...1.3.0 [1.2.0]: https://github.com/ontimize/ontimize-jee-sdms/compare/1.1.0...1.2.0 [1.1.0]: https://github.com/ontimize/ontimize-jee-sdms/compare/1.0.0...1.1.0 -[1.0.0]: https://github.com/ontimize/ontimize-jee-sdms/releases/tag/1.0.0 \ No newline at end of file +[1.0.0]: https://github.com/ontimize/ontimize-jee-sdms/releases/tag/1.0.0 From b73c7f808bfbc0b52a484a70a774d0d4d8a298f5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C3=81ngel=20Herce=20Soto?= <97441532+angelherce@users.noreply.github.com> Date: Tue, 13 May 2025 09:50:43 +0200 Subject: [PATCH 22/23] Update README.md --- README.md | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/README.md b/README.md index 45a4cfc..6d57b36 100644 --- a/README.md +++ b/README.md @@ -1,16 +1,16 @@ # Ontimize JEE Storage SDMS ## 📜 Introduction -Ontimize JEE Storage SDMS es un módulo del framework Ontimize que proporciona una solución de gestión documental para aplicaciones empresariales basadas en Java Enterprise Edition (JEE). Este módulo permite a las organizaciones almacenar y gestionar documentos dentro de sus aplicaciones empresariales. +Ontimize JEE Storage SDMS is a module of the Ontimize framework that provides a document management solution for Java Enterprise Edition (JEE) based enterprise applications. This module enables organizations to store and manage documents within their enterprise applications. -## ✍ Uso -Para utilizar este módulo, solo necesitas importarlo en tu proyecto. En la entidad que requiera disponer de los endpoints SDMS, tendrás que extender los drivers y añadir los métodos SDMS correspondientes en los servicios de dicha entidad. Para más información, consulta la [documentación](https://ontimize.github.io/docs/v3/systems/sdms/). +## ✍ Usage +To use this module, you only need to import it into your project. For entities requiring SDMS endpoints, you must extend the drivers and add the corresponding SDMS methods to the entity's services. For more information, please refer to the [documentation](https://ontimize.github.io/docs/v3/systems/sdms/). -## 💼 Documentación -Toda la documentación relacionada con su uso en proyectos, tutoriales y detalles de sus sistemas y modos de uso puede encontrarse en línea, accediendo al siguiente enlace de la [documentación de Ontimize Boot](https://ontimize.github.io/docs/). +## 💼 Documentation +All documentation related to project integration, tutorials, and details about its systems and usage can be found online via the following link to the [Ontimize Boot documentation](https://ontimize.github.io/docs/). -## 👁️‍🗨️ Versiones y dependencias -Todas las versiones y dependencias de los artefactos contenidos en este proyecto pueden descargarse desde [Maven Central](https://central.sonatype.dev/namespace/com.ontimize.boot), así como conocer cada una de sus dependencias. +## 👁️‍🗨️ Versions and Dependencies +All versions and dependencies of the artifacts included in this project can be downloaded from [Maven Central](https://central.sonatype.com/namespace/com.ontimize.jee.sdms), as well as viewing each of their dependencies. -## 📣 Registro de cambios -Puedes consultar nuestro registro de cambios en el siguiente [enlace](CHANGELOG.md) +## :gear: Changelog +You can consult our changelog at the following [link](CHANGELOG.md) From 898334aea73df744c285723535a7e7b4ef10a1e0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C3=81ngel=20Herce=20Soto?= <97441532+angelherce@users.noreply.github.com> Date: Tue, 13 May 2025 09:53:50 +0200 Subject: [PATCH 23/23] Update pom.xml --- pom.xml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/pom.xml b/pom.xml index d6d7b84..5387214 100644 --- a/pom.xml +++ b/pom.xml @@ -13,7 +13,7 @@ com.ontimize.jee ontimize-jee - 5.13.0-SNAPSHOT + 5.13.0 @@ -319,4 +319,4 @@ - \ No newline at end of file +