From e6e709c20f8af0d301052204eeb4447d9c068406 Mon Sep 17 00:00:00 2001 From: "p.zahnen" Date: Tue, 6 Jan 2026 17:50:52 +0100 Subject: [PATCH 1/3] refactor S3 drivers with helper classes for operations --- .../ii/xtraplatform/s3/app/BlobSourceS3.java | 201 ++++++------------ .../s3/app/BlobStoreDriverS3.java | 25 +-- .../s3/app/CacheOperationsHelper.java | 54 +++++ .../xtraplatform/s3/app/CfgStoreDriverS3.java | 14 +- .../s3/app/EventStoreDriverS3.java | 5 +- .../de/ii/xtraplatform/s3/app/PathHelper.java | 33 +++ .../s3/app/S3OperationsHelper.java | 72 +++++++ 7 files changed, 246 insertions(+), 158 deletions(-) create mode 100644 xtraplatform-s3/src/main/java/de/ii/xtraplatform/s3/app/CacheOperationsHelper.java create mode 100644 xtraplatform-s3/src/main/java/de/ii/xtraplatform/s3/app/PathHelper.java create mode 100644 xtraplatform-s3/src/main/java/de/ii/xtraplatform/s3/app/S3OperationsHelper.java diff --git a/xtraplatform-s3/src/main/java/de/ii/xtraplatform/s3/app/BlobSourceS3.java b/xtraplatform-s3/src/main/java/de/ii/xtraplatform/s3/app/BlobSourceS3.java index b7d740eb..821626c6 100644 --- a/xtraplatform-s3/src/main/java/de/ii/xtraplatform/s3/app/BlobSourceS3.java +++ b/xtraplatform-s3/src/main/java/de/ii/xtraplatform/s3/app/BlobSourceS3.java @@ -16,17 +16,15 @@ import de.ii.xtraplatform.blobs.domain.BlobSource; import de.ii.xtraplatform.blobs.domain.BlobWriter; import de.ii.xtraplatform.blobs.domain.ImmutableBlob; -import io.minio.GetObjectArgs; -import io.minio.GetObjectArgs.Builder; import io.minio.ListObjectsArgs; import io.minio.MinioClient; import io.minio.PutObjectArgs; import io.minio.RemoveObjectArgs; import io.minio.Result; -import io.minio.StatObjectArgs; import io.minio.StatObjectResponse; import io.minio.messages.Item; import java.io.ByteArrayInputStream; +import java.io.Closeable; import java.io.IOException; import java.io.InputStream; import java.nio.file.Path; @@ -39,20 +37,29 @@ import java.util.stream.IntStream; import java.util.stream.Stream; import java.util.stream.StreamSupport; -import javax.annotation.Nullable; import javax.ws.rs.core.EntityTag; import org.slf4j.Logger; import org.slf4j.LoggerFactory; -public class BlobSourceS3 implements BlobSource, BlobWriter, BlobLocals { - +public class BlobSourceS3 implements BlobSource, BlobWriter, BlobLocals, Closeable { private static final Logger LOGGER = LoggerFactory.getLogger(BlobSourceS3.class); private final MinioClient minioClient; private final String bucket; - private final Path root; - @Nullable private final Path prefix; - private final BlobCache cache; + private final S3OperationsHelper s3Operations; + private final CacheOperationsHelper cacheOperations; + private final PathHelper pathHelper; + + @Override + public void close() throws IOException { + if (minioClient != null) { + try { + minioClient.close(); + } catch (Exception e) { + throw new IOException("Failed to close MinioClient", e); + } + } + } public BlobSourceS3(MinioClient minioClient, String bucket, Path root, BlobCache cache) { this(minioClient, bucket, root, cache, null); @@ -62,61 +69,31 @@ public BlobSourceS3( MinioClient minioClient, String bucket, Path root, BlobCache cache, Path prefix) { this.minioClient = minioClient; this.bucket = bucket; - this.root = root; - this.cache = cache; - this.prefix = prefix; + this.s3Operations = new S3OperationsHelper(minioClient, bucket); + this.cacheOperations = new CacheOperationsHelper(cache); + this.pathHelper = new PathHelper(root, prefix); } @Override public boolean canHandle(Path path) { - return Objects.isNull(prefix) || path.startsWith(prefix); + return pathHelper.canHandle(path); } @Override public boolean has(Path path) throws IOException { - return getStat(path).isPresent(); + return s3Operations.getStat(pathHelper.full(path)).isPresent(); } @Override public Optional content(Path path) throws IOException { - return getCurrent(path); - } - - @Override - public Optional get(Path path) throws IOException { - return getStat(path) - .map( - stat -> - ImmutableBlob.of( - path, - stat.size(), - stat.lastModified().toInstant().toEpochMilli(), - Optional.of(new EntityTag(stat.etag())), - Optional.ofNullable(stat.contentType()), - supplierMayThrow( - () -> - content(path) - .orElseThrow( - () -> - new IOException( - "Unexpected error, could not get " + path))))); - } - - @Override - public long size(Path path) throws IOException { - return getStat(path).map(StatObjectResponse::size).orElse(-1L); - } - - @Override - public long lastModified(Path path) throws IOException { - return getStat(path).map(stat -> stat.lastModified().toInstant().toEpochMilli()).orElse(-1L); + return s3Operations.getCurrent(pathHelper.full(path)); } // TODO: walkInfo @Override public Stream walk(Path path, int maxDepth, BiPredicate matcher) throws IOException { - if (!canHandle(path) || maxDepth <= 0) { + if (!pathHelper.canHandle(path) || maxDepth <= 0) { return Stream.empty(); } @@ -124,7 +101,7 @@ public Stream walk(Path path, int maxDepth, BiPredicate paths = new HashSet<>(); @@ -195,7 +172,7 @@ public boolean isHidden() { @Override public void put(Path path, InputStream content) throws IOException { - if (!canHandle(path)) { + if (!pathHelper.canHandle(path)) { return; } @@ -205,7 +182,7 @@ public void put(Path path, InputStream content) throws IOException { } minioClient.putObject( - PutObjectArgs.builder().bucket(bucket).object(full(path)).stream( + PutObjectArgs.builder().bucket(bucket).object(pathHelper.full(path)).stream( buffer, buffer.available(), -1) .build()); } catch (Throwable e) { @@ -215,7 +192,7 @@ public void put(Path path, InputStream content) throws IOException { @Override public void delete(Path path) throws IOException { - if (!canHandle(path)) { + if (!pathHelper.canHandle(path)) { return; } @@ -225,105 +202,61 @@ public void delete(Path path) throws IOException { } minioClient.removeObject( - RemoveObjectArgs.builder().bucket(bucket).object(full(path)).build()); + RemoveObjectArgs.builder().bucket(bucket).object(pathHelper.full(path)).build()); } catch (Throwable e) { throw new IOException("S3 Driver", e); } } @Override - public Optional asLocalPath(Path path, boolean writable) throws IOException { - if (writable) { - throw new IOException("Local resources from S3 cannot be written to"); - } - - Optional stat = getStat(path); - - if (stat.isPresent()) { - String eTag = stat.get().etag(); - Optional cachePath = cache.get(path, eTag); - - if (cachePath.isPresent()) { - if (LOGGER.isDebugEnabled(MARKER.S3)) { - LOGGER.debug(MARKER.S3, "S3 using local cache {}", cachePath.get()); - } - return cachePath; - } - - Optional content = content(path); - - if (content.isPresent()) { - if (LOGGER.isDebugEnabled(MARKER.S3)) { - LOGGER.debug(MARKER.S3, "S3 updating local cache for {}", path); - } - - return Optional.of(cache.put(path, eTag, content.get())) - .map( - p -> { - if (LOGGER.isDebugEnabled(MARKER.S3)) { - LOGGER.debug(MARKER.S3, "S3 updated local cache {}", p); - } - - return p; - }); - } - } - - return Optional.empty(); + public Optional get(Path path) throws IOException { + return s3Operations + .getStat(pathHelper.full(path)) + .map( + stat -> + ImmutableBlob.of( + path, + stat.size(), + stat.lastModified().toInstant().toEpochMilli(), + Optional.of(new EntityTag(stat.etag())), + Optional.ofNullable(stat.contentType()), + supplierMayThrow( + () -> + content(path) + .orElseThrow( + () -> + new IOException( + "Unexpected error, could not get " + path))))); } - private Optional getStat(Path path) { - if (!canHandle(path)) { - return Optional.empty(); - } - - if (LOGGER.isDebugEnabled(MARKER.S3)) { - LOGGER.debug(MARKER.S3, "S3 get stat {}", path); - } - - try { - return Optional.of( - minioClient.statObject( - StatObjectArgs.builder().bucket(bucket).object(full(path)).build())); - } catch (Throwable e) { - return Optional.empty(); - } + @Override + public long size(Path path) throws IOException { + return s3Operations.getStat(pathHelper.full(path)).map(StatObjectResponse::size).orElse(-1L); } - public Optional getCurrent(Path path) throws IOException { - return getByETag(path, null); + @Override + public long lastModified(Path path) throws IOException { + return s3Operations + .getStat(pathHelper.full(path)) + .map(stat -> stat.lastModified().toInstant().toEpochMilli()) + .orElse(-1L); } - public Optional getByETag(Path path, String eTag) { - if (!canHandle(path)) { - return Optional.empty(); - } - - if (LOGGER.isDebugEnabled(MARKER.S3)) { - LOGGER.debug( - MARKER.S3, - "S3 get content {} {}", - path, - Objects.nonNull(eTag) ? "if-none-match " + eTag : ""); - } - - Builder builder = GetObjectArgs.builder().bucket(bucket).object(full(path)); - - if (Objects.nonNull(eTag)) { - builder.notMatchETag(eTag); + @Override + public Optional asLocalPath(Path path, boolean writable) throws IOException { + if (writable) { + throw new IOException("Local resources from S3 cannot be written to"); } - try { - return Optional.of(minioClient.getObject(builder.build())); - } catch (Throwable e) { + Optional stat = s3Operations.getStat(pathHelper.full(path)); + if (stat.isEmpty()) { return Optional.empty(); - // throw new IOException("S3 Driver", e); } - } - - private String full(Path path) { - return Objects.isNull(prefix) - ? root.resolve(path).toString() - : root.resolve(prefix.relativize(path)).toString(); + String eTag = stat.get().etag(); + Optional cachePath = cacheOperations.getCachedPath(path, eTag); + if (cachePath.isPresent()) { + return cachePath; + } + return cacheOperations.updateCacheAndReturnPath(path, eTag, content(path)); } } diff --git a/xtraplatform-s3/src/main/java/de/ii/xtraplatform/s3/app/BlobStoreDriverS3.java b/xtraplatform-s3/src/main/java/de/ii/xtraplatform/s3/app/BlobStoreDriverS3.java index d505050c..51af989f 100644 --- a/xtraplatform-s3/src/main/java/de/ii/xtraplatform/s3/app/BlobStoreDriverS3.java +++ b/xtraplatform-s3/src/main/java/de/ii/xtraplatform/s3/app/BlobStoreDriverS3.java @@ -49,9 +49,10 @@ public boolean isAvailable(StoreSource storeSource) { if (storeSource instanceof StoreSourceS3) { try { Tuple client = getClient((StoreSourceS3) storeSource); - String bucket = client.second(); - - return client.first().bucketExists(BucketExistsArgs.builder().bucket(bucket).build()); + try (MinioClient minioClient = client.first()) { + String bucket = client.second(); + return minioClient.bucketExists(BucketExistsArgs.builder().bucket(bucket).build()); + } } catch (Throwable e) { LogContext.error(LOGGER, e, "S3 Driver"); return false; @@ -63,6 +64,7 @@ public boolean isAvailable(StoreSource storeSource) { @Override public BlobSource init(StoreSource storeSource, Content contentType) throws IOException { Tuple client = getClient((StoreSourceS3) storeSource); + MinioClient minioClient = client.first(); String bucket = client.second(); Path root = Path.of(""); @@ -70,13 +72,11 @@ public BlobSource init(StoreSource storeSource, Content contentType) throws IOEx root = root.resolve(contentType.getPrefix()); } - BlobSource blobSource = - storeSource.isSingleContent() && storeSource.getPrefix().isPresent() - ? new BlobSourceS3( - client.first(), bucket, root, cache, Path.of(storeSource.getPrefix().get())) - : new BlobSourceS3(client.first(), bucket, root, cache); - - return blobSource; + if (storeSource.isSingleContent() && storeSource.getPrefix().isPresent()) { + return new BlobSourceS3( + minioClient, bucket, root, cache, Path.of(storeSource.getPrefix().get())); + } + return new BlobSourceS3(minioClient, bucket, root, cache); } private Tuple getClient(StoreSourceS3 storeSource) { @@ -86,8 +86,6 @@ private Tuple getClient(StoreSourceS3 storeSource) { hasScheme ? storeSource.getSrc().replaceFirst("[a-zA-Z0-9]+://", "") : storeSource.getSrc(); URI uri = URI.create(scheme + source); - String host = uri.getHost(); - int port = uri.getPort() == -1 ? (storeSource.getInsecure() ? 80 : 443) : uri.getPort(); String bucket = uri.getPath().replaceFirst("^/", "").replaceFirst("/$", ""); if (bucket.isEmpty()) { @@ -95,6 +93,9 @@ private Tuple getClient(StoreSourceS3 storeSource) { "Bucket name cannot be empty (" + storeSource.getSrc() + ")"); } + String host = uri.getHost(); + int port = uri.getPort() == -1 ? storeSource.getInsecure() ? 80 : 443 : uri.getPort(); + MinioClient minioClient = MinioClient.builder() .endpoint(host, port, !storeSource.getInsecure()) diff --git a/xtraplatform-s3/src/main/java/de/ii/xtraplatform/s3/app/CacheOperationsHelper.java b/xtraplatform-s3/src/main/java/de/ii/xtraplatform/s3/app/CacheOperationsHelper.java new file mode 100644 index 00000000..78ec6868 --- /dev/null +++ b/xtraplatform-s3/src/main/java/de/ii/xtraplatform/s3/app/CacheOperationsHelper.java @@ -0,0 +1,54 @@ +/* + * Copyright 2024 interactive instruments GmbH + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + */ +package de.ii.xtraplatform.s3.app; + +import de.ii.xtraplatform.base.domain.LogContext.MARKER; +import de.ii.xtraplatform.blobs.domain.BlobCache; +import java.io.IOException; +import java.io.InputStream; +import java.nio.file.Path; +import java.util.Optional; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +class CacheOperationsHelper { + + private static final Logger LOGGER = LoggerFactory.getLogger(CacheOperationsHelper.class); + + private final BlobCache cache; + + CacheOperationsHelper(BlobCache cache) { + this.cache = cache; + } + + Optional getCachedPath(Path path, String eTag) throws IOException { + Optional cachePath = cache.get(path, eTag); + if (cachePath.isPresent()) { + if (LOGGER.isDebugEnabled(MARKER.S3)) { + LOGGER.debug(MARKER.S3, "S3 using local cache {}", cachePath.get()); + } + return cachePath; + } + return Optional.empty(); + } + + Optional updateCacheAndReturnPath(Path path, String eTag, Optional content) + throws IOException { + if (content.isEmpty()) { + return Optional.empty(); + } + if (LOGGER.isDebugEnabled(MARKER.S3)) { + LOGGER.debug(MARKER.S3, "S3 updating local cache for {}", path); + } + Path p = cache.put(path, eTag, content.get()); + if (LOGGER.isDebugEnabled(MARKER.S3)) { + LOGGER.debug(MARKER.S3, "S3 updated local cache {}", p); + } + return Optional.of(p); + } +} diff --git a/xtraplatform-s3/src/main/java/de/ii/xtraplatform/s3/app/CfgStoreDriverS3.java b/xtraplatform-s3/src/main/java/de/ii/xtraplatform/s3/app/CfgStoreDriverS3.java index ee8936f6..7cd75668 100644 --- a/xtraplatform-s3/src/main/java/de/ii/xtraplatform/s3/app/CfgStoreDriverS3.java +++ b/xtraplatform-s3/src/main/java/de/ii/xtraplatform/s3/app/CfgStoreDriverS3.java @@ -27,8 +27,6 @@ public class CfgStoreDriverS3 implements CfgStoreDriver { private static final Logger LOGGER = LoggerFactory.getLogger(CfgStoreDriverS3.class); static final Path CFG_YML = Path.of("cfg.yml"); - public CfgStoreDriverS3() {} - @Override public String getType() { return "S3"; @@ -39,9 +37,8 @@ public boolean isAvailable(StoreSource storeSource) { if (storeSource instanceof StoreSourceS3) { Tuple client = getClient((StoreSourceS3) storeSource); String bucket = client.second(); - - try { - return client.first().bucketExists(BucketExistsArgs.builder().bucket(bucket).build()); + try (MinioClient minioClient = client.first()) { + return minioClient.bucketExists(BucketExistsArgs.builder().bucket(bucket).build()); } catch (Throwable e) { LogContext.error(LOGGER, e, "S3 Driver"); return false; @@ -60,11 +57,10 @@ public Optional load(StoreSource storeSource) throws IOException { Path root = Path.of(""); Path cfg = storeSource.isSingleContent() ? root : root.resolve(CFG_YML); - try { + try (MinioClient minioClient = client.first()) { return Optional.of( - client - .first() - .getObject(GetObjectArgs.builder().bucket(bucket).object(cfg.toString()).build())); + minioClient.getObject( + GetObjectArgs.builder().bucket(bucket).object(cfg.toString()).build())); } catch (Throwable e) { LogContext.error(LOGGER, e, "S3 Driver"); return Optional.empty(); diff --git a/xtraplatform-s3/src/main/java/de/ii/xtraplatform/s3/app/EventStoreDriverS3.java b/xtraplatform-s3/src/main/java/de/ii/xtraplatform/s3/app/EventStoreDriverS3.java index b8d642bc..06239164 100644 --- a/xtraplatform-s3/src/main/java/de/ii/xtraplatform/s3/app/EventStoreDriverS3.java +++ b/xtraplatform-s3/src/main/java/de/ii/xtraplatform/s3/app/EventStoreDriverS3.java @@ -45,9 +45,8 @@ public boolean isAvailable(StoreSource storeSource) { if (storeSource instanceof StoreSourceS3) { Tuple client = getClient((StoreSourceS3) storeSource); String bucket = client.second(); - - try { - return client.first().bucketExists(BucketExistsArgs.builder().bucket(bucket).build()); + try (MinioClient minioClient = client.first()) { + return minioClient.bucketExists(BucketExistsArgs.builder().bucket(bucket).build()); } catch (Throwable e) { LogContext.error(LOGGER, e, "S3 Driver"); return false; diff --git a/xtraplatform-s3/src/main/java/de/ii/xtraplatform/s3/app/PathHelper.java b/xtraplatform-s3/src/main/java/de/ii/xtraplatform/s3/app/PathHelper.java new file mode 100644 index 00000000..17f1c3cf --- /dev/null +++ b/xtraplatform-s3/src/main/java/de/ii/xtraplatform/s3/app/PathHelper.java @@ -0,0 +1,33 @@ +/* + * Copyright 2024 interactive instruments GmbH + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + */ +package de.ii.xtraplatform.s3.app; + +import java.nio.file.Path; +import java.util.Objects; +import javax.annotation.Nullable; + +class PathHelper { + + private final Path root; + @Nullable private final Path prefix; + + PathHelper(Path root, @Nullable Path prefix) { + this.root = root; + this.prefix = prefix; + } + + String full(Path path) { + return Objects.isNull(prefix) + ? root.resolve(path).toString() + : root.resolve(prefix.relativize(path)).toString(); + } + + boolean canHandle(Path path) { + return Objects.isNull(prefix) || path.startsWith(prefix); + } +} diff --git a/xtraplatform-s3/src/main/java/de/ii/xtraplatform/s3/app/S3OperationsHelper.java b/xtraplatform-s3/src/main/java/de/ii/xtraplatform/s3/app/S3OperationsHelper.java new file mode 100644 index 00000000..184fd15c --- /dev/null +++ b/xtraplatform-s3/src/main/java/de/ii/xtraplatform/s3/app/S3OperationsHelper.java @@ -0,0 +1,72 @@ +/* + * Copyright 2024 interactive instruments GmbH + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + */ +package de.ii.xtraplatform.s3.app; + +import de.ii.xtraplatform.base.domain.LogContext.MARKER; +import io.minio.GetObjectArgs; +import io.minio.MinioClient; +import io.minio.StatObjectArgs; +import io.minio.StatObjectResponse; +import java.io.IOException; +import java.io.InputStream; +import java.util.Objects; +import java.util.Optional; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +class S3OperationsHelper { + + private static final Logger LOGGER = LoggerFactory.getLogger(S3OperationsHelper.class); + + private final MinioClient minioClient; + private final String bucket; + + S3OperationsHelper(MinioClient minioClient, String bucket) { + this.minioClient = minioClient; + this.bucket = bucket; + } + + Optional getStat(String fullPath) { + if (LOGGER.isDebugEnabled(MARKER.S3)) { + LOGGER.debug(MARKER.S3, "S3 get stat {}", fullPath); + } + + try { + return Optional.of( + minioClient.statObject(StatObjectArgs.builder().bucket(bucket).object(fullPath).build())); + } catch (Throwable e) { + return Optional.empty(); + } + } + + Optional getCurrent(String fullPath) throws IOException { + return getByETag(fullPath, null); + } + + Optional getByETag(String fullPath, String eTag) { + if (LOGGER.isDebugEnabled(MARKER.S3)) { + LOGGER.debug( + MARKER.S3, + "S3 get content {} {}", + fullPath, + Objects.nonNull(eTag) ? "if-none-match " + eTag : ""); + } + + GetObjectArgs.Builder builder = GetObjectArgs.builder().bucket(bucket).object(fullPath); + + if (Objects.nonNull(eTag)) { + builder.notMatchETag(eTag); + } + + try { + return Optional.of(minioClient.getObject(builder.build())); + } catch (Throwable e) { + return Optional.empty(); + } + } +} From 2ab15f8082eddc713d9559b071be9fe1d2427785 Mon Sep 17 00:00:00 2001 From: "p.zahnen" Date: Fri, 9 Jan 2026 10:53:17 +0100 Subject: [PATCH 2/3] surpressed warnings --- .../src/main/java/de/ii/xtraplatform/s3/app/BlobSourceS3.java | 1 + .../main/java/de/ii/xtraplatform/s3/app/BlobStoreDriverS3.java | 1 + .../main/java/de/ii/xtraplatform/s3/app/CfgStoreDriverS3.java | 1 + .../main/java/de/ii/xtraplatform/s3/app/EventStoreDriverS3.java | 1 + 4 files changed, 4 insertions(+) diff --git a/xtraplatform-s3/src/main/java/de/ii/xtraplatform/s3/app/BlobSourceS3.java b/xtraplatform-s3/src/main/java/de/ii/xtraplatform/s3/app/BlobSourceS3.java index 821626c6..1decf33c 100644 --- a/xtraplatform-s3/src/main/java/de/ii/xtraplatform/s3/app/BlobSourceS3.java +++ b/xtraplatform-s3/src/main/java/de/ii/xtraplatform/s3/app/BlobSourceS3.java @@ -41,6 +41,7 @@ import org.slf4j.Logger; import org.slf4j.LoggerFactory; +@SuppressWarnings({"PMD.CommentContent"}) public class BlobSourceS3 implements BlobSource, BlobWriter, BlobLocals, Closeable { private static final Logger LOGGER = LoggerFactory.getLogger(BlobSourceS3.class); diff --git a/xtraplatform-s3/src/main/java/de/ii/xtraplatform/s3/app/BlobStoreDriverS3.java b/xtraplatform-s3/src/main/java/de/ii/xtraplatform/s3/app/BlobStoreDriverS3.java index 51af989f..65975f33 100644 --- a/xtraplatform-s3/src/main/java/de/ii/xtraplatform/s3/app/BlobStoreDriverS3.java +++ b/xtraplatform-s3/src/main/java/de/ii/xtraplatform/s3/app/BlobStoreDriverS3.java @@ -79,6 +79,7 @@ public BlobSource init(StoreSource storeSource, Content contentType) throws IOEx return new BlobSourceS3(minioClient, bucket, root, cache); } + @SuppressWarnings("PMD.CloseResource") private Tuple getClient(StoreSourceS3 storeSource) { boolean hasScheme = storeSource.getSrc().matches("^[a-zA-Z0-9]+://.*"); String scheme = storeSource.getInsecure() ? "http://" : "https://"; diff --git a/xtraplatform-s3/src/main/java/de/ii/xtraplatform/s3/app/CfgStoreDriverS3.java b/xtraplatform-s3/src/main/java/de/ii/xtraplatform/s3/app/CfgStoreDriverS3.java index 7cd75668..1a4d6cd1 100644 --- a/xtraplatform-s3/src/main/java/de/ii/xtraplatform/s3/app/CfgStoreDriverS3.java +++ b/xtraplatform-s3/src/main/java/de/ii/xtraplatform/s3/app/CfgStoreDriverS3.java @@ -22,6 +22,7 @@ import org.slf4j.Logger; import org.slf4j.LoggerFactory; +@SuppressWarnings({"PMD.CommentContent", "PMD.CloseResource"}) public class CfgStoreDriverS3 implements CfgStoreDriver { private static final Logger LOGGER = LoggerFactory.getLogger(CfgStoreDriverS3.class); diff --git a/xtraplatform-s3/src/main/java/de/ii/xtraplatform/s3/app/EventStoreDriverS3.java b/xtraplatform-s3/src/main/java/de/ii/xtraplatform/s3/app/EventStoreDriverS3.java index 06239164..1f85ffc7 100644 --- a/xtraplatform-s3/src/main/java/de/ii/xtraplatform/s3/app/EventStoreDriverS3.java +++ b/xtraplatform-s3/src/main/java/de/ii/xtraplatform/s3/app/EventStoreDriverS3.java @@ -28,6 +28,7 @@ @Singleton @AutoBind +@SuppressWarnings({"PMD.CloseResource"}) public class EventStoreDriverS3 implements EventStoreDriver { private static final Logger LOGGER = LoggerFactory.getLogger(EventStoreDriverS3.class); From 39d4e21e7d5ca7dcabd10f26a696aaa6a72716bf Mon Sep 17 00:00:00 2001 From: "p.zahnen" Date: Fri, 9 Jan 2026 10:56:20 +0100 Subject: [PATCH 3/3] removed todos --- .../src/main/java/de/ii/xtraplatform/s3/app/BlobSourceS3.java | 3 --- .../main/java/de/ii/xtraplatform/s3/app/CfgStoreDriverS3.java | 3 +-- 2 files changed, 1 insertion(+), 5 deletions(-) diff --git a/xtraplatform-s3/src/main/java/de/ii/xtraplatform/s3/app/BlobSourceS3.java b/xtraplatform-s3/src/main/java/de/ii/xtraplatform/s3/app/BlobSourceS3.java index 1decf33c..99b7e4ef 100644 --- a/xtraplatform-s3/src/main/java/de/ii/xtraplatform/s3/app/BlobSourceS3.java +++ b/xtraplatform-s3/src/main/java/de/ii/xtraplatform/s3/app/BlobSourceS3.java @@ -41,7 +41,6 @@ import org.slf4j.Logger; import org.slf4j.LoggerFactory; -@SuppressWarnings({"PMD.CommentContent"}) public class BlobSourceS3 implements BlobSource, BlobWriter, BlobLocals, Closeable { private static final Logger LOGGER = LoggerFactory.getLogger(BlobSourceS3.class); @@ -90,7 +89,6 @@ public Optional content(Path path) throws IOException { return s3Operations.getCurrent(pathHelper.full(path)); } - // TODO: walkInfo @Override public Stream walk(Path path, int maxDepth, BiPredicate matcher) throws IOException { @@ -116,7 +114,6 @@ public Stream walk(Path path, int maxDepth, BiPredicate { diff --git a/xtraplatform-s3/src/main/java/de/ii/xtraplatform/s3/app/CfgStoreDriverS3.java b/xtraplatform-s3/src/main/java/de/ii/xtraplatform/s3/app/CfgStoreDriverS3.java index 1a4d6cd1..c4cee16d 100644 --- a/xtraplatform-s3/src/main/java/de/ii/xtraplatform/s3/app/CfgStoreDriverS3.java +++ b/xtraplatform-s3/src/main/java/de/ii/xtraplatform/s3/app/CfgStoreDriverS3.java @@ -22,7 +22,7 @@ import org.slf4j.Logger; import org.slf4j.LoggerFactory; -@SuppressWarnings({"PMD.CommentContent", "PMD.CloseResource"}) +@SuppressWarnings({"PMD.CloseResource"}) public class CfgStoreDriverS3 implements CfgStoreDriver { private static final Logger LOGGER = LoggerFactory.getLogger(CfgStoreDriverS3.class); @@ -48,7 +48,6 @@ public boolean isAvailable(StoreSource storeSource) { return false; } - // TODO: single content? @Override public Optional load(StoreSource storeSource) throws IOException { if (storeSource instanceof StoreSourceS3) {