diff --git a/pom.xml b/pom.xml
index f9e56ef5..69503782 100644
--- a/pom.xml
+++ b/pom.xml
@@ -89,7 +89,7 @@
2.2.3
5.4.1
3.0
-
+ 3.0.0
1.6
diff --git a/storage-aws-s3/src/main/java/org/rutebanken/helper/aws/repository/S3BlobStoreRepository.java b/storage-aws-s3/src/main/java/org/rutebanken/helper/aws/repository/S3BlobStoreRepository.java
index d13f5665..3395bad5 100644
--- a/storage-aws-s3/src/main/java/org/rutebanken/helper/aws/repository/S3BlobStoreRepository.java
+++ b/storage-aws-s3/src/main/java/org/rutebanken/helper/aws/repository/S3BlobStoreRepository.java
@@ -4,6 +4,8 @@
import org.rutebanken.helper.storage.BlobStoreException;
import org.rutebanken.helper.storage.model.BlobDescriptor;
import org.rutebanken.helper.storage.repository.BlobStoreRepository;
+import software.amazon.awssdk.awscore.exception.AwsServiceException;
+import software.amazon.awssdk.core.exception.SdkClientException;
import software.amazon.awssdk.core.sync.RequestBody;
import software.amazon.awssdk.core.sync.ResponseTransformer;
import software.amazon.awssdk.services.s3.S3Client;
@@ -49,10 +51,14 @@ public S3BlobStoreRepository(S3Client s3Client) {
@Override
public InputStream getBlob(String objectName) {
- return s3Client.getObject(
- GetObjectRequest.builder().bucket(containerName).key(objectName).build(),
- ResponseTransformer.toInputStream()
- );
+ try {
+ return s3Client.getObject(
+ GetObjectRequest.builder().bucket(containerName).key(objectName).build(),
+ ResponseTransformer.toInputStream()
+ );
+ } catch (NoSuchKeyException e) {
+ return null;
+ }
}
@Override
diff --git a/storage-gcp-gcs/src/main/java/org/rutebanken/helper/gcp/repository/GcsBlobStoreRepository.java b/storage-gcp-gcs/src/main/java/org/rutebanken/helper/gcp/repository/GcsBlobStoreRepository.java
index bce5cc08..5b6f0018 100644
--- a/storage-gcp-gcs/src/main/java/org/rutebanken/helper/gcp/repository/GcsBlobStoreRepository.java
+++ b/storage-gcp-gcs/src/main/java/org/rutebanken/helper/gcp/repository/GcsBlobStoreRepository.java
@@ -54,6 +54,11 @@ public void setContainerName(String containerName) {
this.containerName = containerName;
}
+ @Override
+ public boolean exist(String objectName) {
+ return BlobStoreHelper.existBlob(storage, containerName, objectName);
+ }
+
@Override
public InputStream getBlob(String name) {
return BlobStoreHelper.getBlob(storage, containerName, name);
diff --git a/storage/pom.xml b/storage/pom.xml
index 4f40f0d1..7f6d9511 100644
--- a/storage/pom.xml
+++ b/storage/pom.xml
@@ -50,6 +50,11 @@ Inspired by: https://github.com/fabric8io/ipaas-quickstarts/
commons-io
commons-io
+
+ jakarta.annotation
+ jakarta.annotation-api
+ ${jakarta.annotation-api.version}
+
diff --git a/storage/src/main/java/org/rutebanken/helper/storage/repository/BlobStoreRepository.java b/storage/src/main/java/org/rutebanken/helper/storage/repository/BlobStoreRepository.java
index dbe14e8f..4494198a 100644
--- a/storage/src/main/java/org/rutebanken/helper/storage/repository/BlobStoreRepository.java
+++ b/storage/src/main/java/org/rutebanken/helper/storage/repository/BlobStoreRepository.java
@@ -16,6 +16,7 @@
package org.rutebanken.helper.storage.repository;
+import jakarta.annotation.Nullable;
import org.rutebanken.helper.storage.BlobAlreadyExistsException;
import org.rutebanken.helper.storage.model.BlobDescriptor;
@@ -31,12 +32,22 @@
public interface BlobStoreRepository {
+ /**
+ * Return true if the given blob exists in the repository.
+ * The default implementation retrieves the object and test for nullity.
+ * Specific implementations can provide an optimized algorithm.
+ */
+ default boolean exist(String objectName) {
+ return getBlob(objectName) != null;
+ }
+
/**
* Download a blob from storage.
*
* @param objectName the name of the blob
- * @return an InputStream on the file content.
+ * @return an InputStream on the file content or null if the object does not exist.
*/
+ @Nullable
InputStream getBlob(String objectName);
/**
diff --git a/storage/src/test/java/org/rutebanken/helper/storage/repository/InMemoryBlobStoreRepositoryTest.java b/storage/src/test/java/org/rutebanken/helper/storage/repository/InMemoryBlobStoreRepositoryTest.java
new file mode 100644
index 00000000..bc0ee4fb
--- /dev/null
+++ b/storage/src/test/java/org/rutebanken/helper/storage/repository/InMemoryBlobStoreRepositoryTest.java
@@ -0,0 +1,26 @@
+package org.rutebanken.helper.storage.repository;
+
+import org.junit.jupiter.api.Test;
+
+import java.io.ByteArrayInputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.util.HashMap;
+
+import static org.junit.jupiter.api.Assertions.*;
+class InMemoryBlobStoreRepositoryTest {
+
+ public static final String BLOB_NAME = "blobName";
+ public static final byte[] BLOB_CONTENT = "content".getBytes();
+
+ @Test
+ void testUploadExistAndGet() throws IOException {
+ InMemoryBlobStoreRepository repository = new InMemoryBlobStoreRepository(new HashMap<>());
+ repository.uploadBlob(BLOB_NAME, new ByteArrayInputStream(BLOB_CONTENT));
+ assertTrue(repository.exist(BLOB_NAME));
+ InputStream blob = repository.getBlob(BLOB_NAME);
+ assertNotNull(blob);
+ assertArrayEquals(BLOB_CONTENT, blob.readAllBytes());
+ }
+
+}
\ No newline at end of file
diff --git a/storage/src/test/java/org/rutebanken/helper/storage/repository/LocalDiskBlobStoreRepositoryTest.java b/storage/src/test/java/org/rutebanken/helper/storage/repository/LocalDiskBlobStoreRepositoryTest.java
new file mode 100644
index 00000000..bd6f1fa0
--- /dev/null
+++ b/storage/src/test/java/org/rutebanken/helper/storage/repository/LocalDiskBlobStoreRepositoryTest.java
@@ -0,0 +1,31 @@
+package org.rutebanken.helper.storage.repository;
+
+import org.junit.jupiter.api.Test;
+import org.junit.jupiter.api.io.TempDir;
+
+import java.io.ByteArrayInputStream;
+import java.io.File;
+import java.io.IOException;
+import java.io.InputStream;
+
+import static org.junit.jupiter.api.Assertions.*;
+
+class LocalDiskBlobStoreRepositoryTest {
+
+ public static final String BLOB_NAME = "blobName";
+ public static final byte[] BLOB_CONTENT = "content".getBytes();
+
+ @TempDir
+ File tempDirectory;
+
+ @Test
+ void testUploadExistAndGet() throws IOException {
+ LocalDiskBlobStoreRepository repository = new LocalDiskBlobStoreRepository(tempDirectory.getAbsolutePath());
+ repository.uploadBlob(BLOB_NAME, new ByteArrayInputStream(BLOB_CONTENT));
+ assertTrue(repository.exist(BLOB_NAME));
+ InputStream blob = repository.getBlob(BLOB_NAME);
+ assertNotNull(blob);
+ assertArrayEquals(BLOB_CONTENT, blob.readAllBytes());
+ }
+
+}
\ No newline at end of file