diff --git a/droid-api/pom.xml b/droid-api/pom.xml
index c273e58aa..a12ef0619 100644
--- a/droid-api/pom.xml
+++ b/droid-api/pom.xml
@@ -4,7 +4,7 @@
droid-parent
uk.gov.nationalarchives
- 6.9.7-SNAPSHOT
+ 6.9.8-SNAPSHOT
../droid-parent
diff --git a/droid-api/src/main/java/uk/gov/nationalarchives/droid/internal/api/DroidAPI.java b/droid-api/src/main/java/uk/gov/nationalarchives/droid/internal/api/DroidAPI.java
index bbaca30ab..17fb34471 100644
--- a/droid-api/src/main/java/uk/gov/nationalarchives/droid/internal/api/DroidAPI.java
+++ b/droid-api/src/main/java/uk/gov/nationalarchives/droid/internal/api/DroidAPI.java
@@ -92,6 +92,7 @@ public final class DroidAPI implements AutoCloseable {
private static final String S3_SCHEME = "s3";
private static final String GZIP_PUID = "x-fmt/266";
private static final long DEFAULT_MAX_BYTES_TO_SCAN = -1;
+ private static final int DEFAULT_WINDOW_SIZE = 4 * 1024 * 1024;
private static final AtomicLong ID_GENERATOR = new AtomicLong();
@@ -360,8 +361,8 @@ private List submitS3Identification(final URI uri, String extension)
Map hashResults = generateHashResults(s3Uri, this::getS3Hash);
final RequestIdentifier id = getRequestIdentifier(s3Uri.uri());
- RequestMetaData metaData = new RequestMetaData(s3Object.size(), s3Object.lastModified().getEpochSecond(), s3Uri.uri().toString());
- try (final S3IdentificationRequest request = new S3IdentificationRequest(metaData, id, s3Client)) {
+ RequestMetaData metaData = new RequestMetaData(s3Object.size(), s3Object.lastModified().toEpochMilli(), s3Uri.uri().toString());
+ try (final S3IdentificationRequest request = new S3IdentificationRequest(metaData, id, s3Client, DEFAULT_WINDOW_SIZE)) {
request.setExtension(extension);
request.open(s3Uri);
apiResults.add(new APIResult(getIdentificationResults(request), hashResults));
diff --git a/droid-api/src/test/java/uk/gov/nationalarchives/droid/internal/api/DroidAPITestUtils.java b/droid-api/src/test/java/uk/gov/nationalarchives/droid/internal/api/DroidAPITestUtils.java
index c64d15ba0..dbd08e5c9 100644
--- a/droid-api/src/test/java/uk/gov/nationalarchives/droid/internal/api/DroidAPITestUtils.java
+++ b/droid-api/src/test/java/uk/gov/nationalarchives/droid/internal/api/DroidAPITestUtils.java
@@ -169,16 +169,6 @@ static HttpServer createS3Server() throws IOException {
OutputStream responseBody = exchange.getResponseBody();
responseBody.write(response.getBytes());
responseBody.close();
- } else if (exchange.getRequestMethod().equals("HEAD")) {
- String fullPath = exchange.getRequestURI().getPath().substring(1);
- Path filePath = getFilePathFromUriPath(fullPath.substring(fullPath.indexOf("/")));
- long size = Files.size(filePath);
- exchange.getResponseHeaders().add("Content-Length", Long.toString(size));
- exchange.getResponseHeaders().add("Last-Modified", "Mon, 03 Mar 2025 17:29:48 GMT");
- exchange.sendResponseHeaders(200, -1);
- OutputStream responseBody = exchange.getResponseBody();
- responseBody.write("".getBytes());
- responseBody.close();
} else if (exchange.getRequestMethod().equals("GET")) {
String fullPath = exchange.getRequestURI().getPath().substring(1);
Path filePath = getFilePathFromUriPath(fullPath.substring(fullPath.indexOf("/")));
diff --git a/droid-binary/pom.xml b/droid-binary/pom.xml
index 35eaae08d..1cdb5b80e 100644
--- a/droid-binary/pom.xml
+++ b/droid-binary/pom.xml
@@ -4,7 +4,7 @@
droid-parent
uk.gov.nationalarchives
- 6.9.7-SNAPSHOT
+ 6.9.8-SNAPSHOT
../droid-parent
diff --git a/droid-build-tools/pom.xml b/droid-build-tools/pom.xml
index f0c7ff466..92b07bcf1 100644
--- a/droid-build-tools/pom.xml
+++ b/droid-build-tools/pom.xml
@@ -4,7 +4,7 @@
droid-parent
uk.gov.nationalarchives
- 6.9.7-SNAPSHOT
+ 6.9.8-SNAPSHOT
../droid-parent
diff --git a/droid-command-line/pom.xml b/droid-command-line/pom.xml
index 43abd9336..d5c9ba79a 100644
--- a/droid-command-line/pom.xml
+++ b/droid-command-line/pom.xml
@@ -4,7 +4,7 @@
droid-parent
uk.gov.nationalarchives
- 6.9.7-SNAPSHOT
+ 6.9.8-SNAPSHOT
../droid-parent
diff --git a/droid-container/pom.xml b/droid-container/pom.xml
index bc374114f..a55fd49b5 100644
--- a/droid-container/pom.xml
+++ b/droid-container/pom.xml
@@ -4,7 +4,7 @@
droid-parent
uk.gov.nationalarchives
- 6.9.7-SNAPSHOT
+ 6.9.8-SNAPSHOT
../droid-parent
diff --git a/droid-core-interfaces/pom.xml b/droid-core-interfaces/pom.xml
index 922268601..7d76f2c6b 100644
--- a/droid-core-interfaces/pom.xml
+++ b/droid-core-interfaces/pom.xml
@@ -4,7 +4,7 @@
droid-parent
uk.gov.nationalarchives
- 6.9.7-SNAPSHOT
+ 6.9.8-SNAPSHOT
../droid-parent
diff --git a/droid-core-interfaces/src/main/java/uk/gov/nationalarchives/droid/core/interfaces/http/S3ClientFactory.java b/droid-core-interfaces/src/main/java/uk/gov/nationalarchives/droid/core/interfaces/http/S3ClientFactory.java
index a6710705b..3564c4131 100644
--- a/droid-core-interfaces/src/main/java/uk/gov/nationalarchives/droid/core/interfaces/http/S3ClientFactory.java
+++ b/droid-core-interfaces/src/main/java/uk/gov/nationalarchives/droid/core/interfaces/http/S3ClientFactory.java
@@ -47,12 +47,15 @@ public class S3ClientFactory implements ProxySubscriber {
private S3Client s3Client;
- private final Region region;
+ private Region region;
- public S3ClientFactory(ProxySettings proxySettings) {
+ public S3ClientFactory() {
+ }
+
+ public void init(ProxySettings proxySettings) {
+ this.region = DefaultAwsRegionProviderChain.builder().build().getRegion();
proxySettings.addProxySubscriber(this);
setS3Client(proxySettings);
- this.region = DefaultAwsRegionProviderChain.builder().build().getRegion();
}
@Override
diff --git a/droid-core-interfaces/src/main/java/uk/gov/nationalarchives/droid/core/interfaces/resource/S3IdentificationRequest.java b/droid-core-interfaces/src/main/java/uk/gov/nationalarchives/droid/core/interfaces/resource/S3IdentificationRequest.java
index 5a41f856b..b80233e37 100644
--- a/droid-core-interfaces/src/main/java/uk/gov/nationalarchives/droid/core/interfaces/resource/S3IdentificationRequest.java
+++ b/droid-core-interfaces/src/main/java/uk/gov/nationalarchives/droid/core/interfaces/resource/S3IdentificationRequest.java
@@ -51,25 +51,27 @@ public class S3IdentificationRequest implements IdentificationRequest {
private WindowReader s3Reader;
private final RequestIdentifier identifier;
private final RequestMetaData requestMetaData;
+ private final int windowSize;
private final S3Client s3client;
private final S3Utils.S3ObjectMetadata s3ObjectMetadata;
private String extension;
- public S3IdentificationRequest(final RequestMetaData requestMetaData, final RequestIdentifier identifier, final S3Client s3Client) {
+ public S3IdentificationRequest(final RequestMetaData requestMetaData, final RequestIdentifier identifier, final S3Client s3Client, final int windowSize) {
this.identifier = identifier;
this.s3client = s3Client;
this.requestMetaData = requestMetaData;
+ this.windowSize = windowSize;
S3Utils s3Utils = new S3Utils(s3Client);
- this.s3ObjectMetadata = s3Utils.getS3ObjectMetadata(identifier.getUri());
+ this.s3ObjectMetadata = s3Utils.getS3ObjectMetadata(identifier.getUri(), requestMetaData);
this.s3Reader = buildWindowReader();
}
private WindowReader buildWindowReader() {
final WindowCache cache = new TopAndTailFixedLengthCache(this.s3ObjectMetadata.contentLength(), TOP_TAIL_BUFFER_CAPACITY);
- return new S3WindowReader(cache, s3ObjectMetadata, s3client);
+ return new S3WindowReader(cache, s3ObjectMetadata, s3client, windowSize);
}
/**
@@ -158,4 +160,12 @@ public byte getByte(long position) throws IOException {
public WindowReader getWindowReader() {
return this.s3Reader;
}
+
+ /**
+ * Gets the window size.
+ * @return the window size
+ */
+ public int getWindowSize() {
+ return windowSize;
+ }
}
diff --git a/droid-core-interfaces/src/main/java/uk/gov/nationalarchives/droid/core/interfaces/resource/S3Utils.java b/droid-core-interfaces/src/main/java/uk/gov/nationalarchives/droid/core/interfaces/resource/S3Utils.java
index 3c2414257..cada1fbae 100644
--- a/droid-core-interfaces/src/main/java/uk/gov/nationalarchives/droid/core/interfaces/resource/S3Utils.java
+++ b/droid-core-interfaces/src/main/java/uk/gov/nationalarchives/droid/core/interfaces/resource/S3Utils.java
@@ -63,26 +63,16 @@ public record S3ObjectMetadata(String bucket, Optional key, S3Uri uri, L
public record S3ObjectList(String bucket, Iterable contents) {}
- public S3ObjectMetadata getS3ObjectMetadata(final URI uri) {
+ public S3ObjectMetadata getS3ObjectMetadata(final URI uri, RequestMetaData requestMetaData) {
S3Uri s3Uri = S3Utilities.builder().region(region).build().parseUri(uri);
- return getS3ObjectMetadata(s3Uri);
+ return getS3ObjectMetadata(s3Uri, requestMetaData);
}
- public S3ObjectMetadata getS3ObjectMetadata(final S3Uri s3Uri) {
+ public S3ObjectMetadata getS3ObjectMetadata(final S3Uri s3Uri, RequestMetaData requestMetaData) {
String bucket = s3Uri.bucket().orElseThrow(() -> new RuntimeException(BUCKET_NOT_FOUND + s3Uri));
Optional key = s3Uri.key();
- long contentLength = 0L;
- long lastModified = 0L;
- if (key.isPresent()) {
- try {
- HeadObjectRequest headObjectRequest = HeadObjectRequest.builder().bucket(bucket).key(key.get()).build();
- HeadObjectResponse headObjectResponse = this.s3Client.headObject(headObjectRequest);
- contentLength = headObjectResponse.contentLength();
- lastModified = headObjectResponse.lastModified().getEpochSecond();
- } catch (NoSuchKeyException ignored) {}
- }
- return new S3ObjectMetadata(bucket, key, s3Uri, contentLength, lastModified);
+ return new S3ObjectMetadata(bucket, key, s3Uri, requestMetaData.getSize(), requestMetaData.getTime());
}
public S3ObjectList listObjects(final URI uri) {
diff --git a/droid-core-interfaces/src/main/java/uk/gov/nationalarchives/droid/core/interfaces/resource/S3WindowReader.java b/droid-core-interfaces/src/main/java/uk/gov/nationalarchives/droid/core/interfaces/resource/S3WindowReader.java
index b7f974e99..36bc44c0d 100644
--- a/droid-core-interfaces/src/main/java/uk/gov/nationalarchives/droid/core/interfaces/resource/S3WindowReader.java
+++ b/droid-core-interfaces/src/main/java/uk/gov/nationalarchives/droid/core/interfaces/resource/S3WindowReader.java
@@ -49,16 +49,14 @@ public class S3WindowReader extends AbstractReader implements SoftWindowRecovery
private static final int BUFFER_LENGTH = 8192;
- private static final int WINDOW_SIZE = 4 * 1024 * 1024;
-
private final S3Utils.S3ObjectMetadata s3ObjectMetadata;
private final S3Client s3Client;
private final Long length;
- public S3WindowReader(WindowCache cache, S3Utils.S3ObjectMetadata s3ObjectMetadata, S3Client s3Client) {
- super(WINDOW_SIZE, cache);
+ public S3WindowReader(WindowCache cache, S3Utils.S3ObjectMetadata s3ObjectMetadata, S3Client s3Client, int windowSize) {
+ super(windowSize, cache);
this.s3Client = s3Client;
this.length = s3ObjectMetadata.contentLength();
this.s3ObjectMetadata = s3ObjectMetadata;
diff --git a/droid-core-interfaces/src/test/java/uk/gov/nationalarchives/droid/core/interfaces/resource/S3IdentificationRequestTest.java b/droid-core-interfaces/src/test/java/uk/gov/nationalarchives/droid/core/interfaces/resource/S3IdentificationRequestTest.java
index 3a7dc5f9d..605195c4b 100644
--- a/droid-core-interfaces/src/test/java/uk/gov/nationalarchives/droid/core/interfaces/resource/S3IdentificationRequestTest.java
+++ b/droid-core-interfaces/src/test/java/uk/gov/nationalarchives/droid/core/interfaces/resource/S3IdentificationRequestTest.java
@@ -33,17 +33,12 @@
import org.junit.jupiter.api.Test;
import org.mockito.ArgumentCaptor;
-import software.amazon.awssdk.core.ResponseInputStream;
import software.amazon.awssdk.core.exception.SdkException;
import software.amazon.awssdk.services.s3.S3Client;
import software.amazon.awssdk.services.s3.S3Uri;
import software.amazon.awssdk.services.s3.model.GetObjectRequest;
-import software.amazon.awssdk.services.s3.model.GetObjectResponse;
-import software.amazon.awssdk.services.s3.model.HeadObjectRequest;
-import software.amazon.awssdk.services.s3.model.HeadObjectResponse;
import uk.gov.nationalarchives.droid.core.interfaces.RequestIdentifier;
-import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.net.URI;
@@ -63,11 +58,10 @@ public void testS3IdentificationRequestGetsFirstWindowOnCreation() throws IOExce
request.open(s3Uri);
ArgumentCaptor getObjectRequestCaptor = ArgumentCaptor.forClass(GetObjectRequest.class);
- verify(mockS3Client, times(1)).headObject(any(HeadObjectRequest.class));
verify(mockS3Client, times(1)).getObject(getObjectRequestCaptor.capture());
GetObjectRequest getRequestValue = getObjectRequestCaptor.getValue();
- assertEquals(getRequestValue.range(), "bytes=0-4194303");
+ assertEquals(getRequestValue.range(), "bytes=0-1023");
}
@Test
@@ -78,7 +72,7 @@ public void testS3IdentificationRequestHasCorrectAttributes() throws IOException
request.open(s3Uri);
- assertEquals(request.size(), 1);
+ assertEquals(request.size(), 2);
assertEquals(request.getFileName(), "entry.txt");
assertEquals(request.getExtension(), "txt");
}
@@ -126,18 +120,11 @@ public void testErrorIfS3GetObjectCallsFail() {
assertThrows(SdkException.class, () -> request.open(s3Uri));
}
- @Test
- public void testErrorIfS3HeadObjectCallsFail() {
- S3Client mockS3Client = mock(S3Client.class);
- when(mockS3Client.headObject(any(HeadObjectRequest.class))).thenThrow(SdkException.class);
- assertThrows(SdkException.class, () -> createRequest(mockS3Client));
- }
-
private S3IdentificationRequest createRequest(S3Client mockS3Client) {
RequestMetaData requestMetaData = new RequestMetaData(2L, 1L, "entry.txt");
URI uri = URI.create("s3://bucket/test");
RequestIdentifier requestIdentifier = new RequestIdentifier(uri);
- return new S3IdentificationRequest(requestMetaData, requestIdentifier, mockS3Client);
+ return new S3IdentificationRequest(requestMetaData, requestIdentifier, mockS3Client, 1024);
}
}
diff --git a/droid-core-interfaces/src/test/java/uk/gov/nationalarchives/droid/core/interfaces/resource/S3TestUtils.java b/droid-core-interfaces/src/test/java/uk/gov/nationalarchives/droid/core/interfaces/resource/S3TestUtils.java
index 94a3a1823..574d9d569 100644
--- a/droid-core-interfaces/src/test/java/uk/gov/nationalarchives/droid/core/interfaces/resource/S3TestUtils.java
+++ b/droid-core-interfaces/src/test/java/uk/gov/nationalarchives/droid/core/interfaces/resource/S3TestUtils.java
@@ -35,11 +35,8 @@
import software.amazon.awssdk.services.s3.S3Client;
import software.amazon.awssdk.services.s3.model.GetObjectRequest;
import software.amazon.awssdk.services.s3.model.GetObjectResponse;
-import software.amazon.awssdk.services.s3.model.HeadObjectRequest;
-import software.amazon.awssdk.services.s3.model.HeadObjectResponse;
import java.io.ByteArrayInputStream;
-import java.time.Instant;
import static org.mockito.ArgumentMatchers.any;
import static org.mockito.Mockito.mock;
@@ -49,10 +46,7 @@ public class S3TestUtils {
static S3Client mockS3Client() {
S3Client mockS3Client = mock(S3Client.class);
- HeadObjectResponse response = HeadObjectResponse.builder().contentLength(1L).lastModified(Instant.ofEpochSecond(1)).build();
GetObjectResponse getObjectResponse = GetObjectResponse.builder().build();
- ResponseInputStream responseInputStream = new ResponseInputStream<>(getObjectResponse, new ByteArrayInputStream("test".getBytes()));
- when(mockS3Client.headObject(any(HeadObjectRequest.class))).thenReturn(response);
when(mockS3Client.getObject(any(GetObjectRequest.class))).thenAnswer(invocation -> {
GetObjectRequest argument = invocation.getArgument(0, GetObjectRequest.class);
String range = argument.range();
diff --git a/droid-core-interfaces/src/test/java/uk/gov/nationalarchives/droid/core/interfaces/resource/S3UtilsTest.java b/droid-core-interfaces/src/test/java/uk/gov/nationalarchives/droid/core/interfaces/resource/S3UtilsTest.java
index 8442c7baf..3fd125536 100644
--- a/droid-core-interfaces/src/test/java/uk/gov/nationalarchives/droid/core/interfaces/resource/S3UtilsTest.java
+++ b/droid-core-interfaces/src/test/java/uk/gov/nationalarchives/droid/core/interfaces/resource/S3UtilsTest.java
@@ -57,9 +57,10 @@ public void getObjectMetadataReturnsCorrectMetadata() {
S3Client s3Client = mockS3Client();
S3Utils s3Utils = new S3Utils(s3Client, Region.EU_WEST_2);
URI uri = URI.create("s3://bucket/key");
- S3Utils.S3ObjectMetadata s3ObjectMetadataFromUri = s3Utils.getS3ObjectMetadata(uri);
+ RequestMetaData requestMetaData = new RequestMetaData(1L, 1L, "key");
+ S3Utils.S3ObjectMetadata s3ObjectMetadataFromUri = s3Utils.getS3ObjectMetadata(uri, requestMetaData);
S3Uri s3Uri = S3Uri.builder().uri(uri).bucket("bucket").key("key").build();
- S3Utils.S3ObjectMetadata s3ObjectMetadataFromS3Uri = s3Utils.getS3ObjectMetadata(s3Uri);
+ S3Utils.S3ObjectMetadata s3ObjectMetadataFromS3Uri = s3Utils.getS3ObjectMetadata(s3Uri, requestMetaData);
for (S3Utils.S3ObjectMetadata s3ObjectMetadata: List.of(s3ObjectMetadataFromUri, s3ObjectMetadataFromS3Uri)) {
assertTrue(s3ObjectMetadata.key().isPresent());
diff --git a/droid-core-interfaces/src/test/java/uk/gov/nationalarchives/droid/core/interfaces/resource/S3WindowReaderTest.java b/droid-core-interfaces/src/test/java/uk/gov/nationalarchives/droid/core/interfaces/resource/S3WindowReaderTest.java
index 6b10f3603..433b4dd7d 100644
--- a/droid-core-interfaces/src/test/java/uk/gov/nationalarchives/droid/core/interfaces/resource/S3WindowReaderTest.java
+++ b/droid-core-interfaces/src/test/java/uk/gov/nationalarchives/droid/core/interfaces/resource/S3WindowReaderTest.java
@@ -61,7 +61,7 @@ public void testWindowReaderReturnsExpectedWindow() throws Exception {
S3Client s3Client = mockS3Client();
S3Uri s3Uri = S3Uri.builder().uri(URI.create("s3://bucket/key")).build();
S3Utils.S3ObjectMetadata s3ObjectMetadata = new S3Utils.S3ObjectMetadata("bucket", Optional.of("key"), s3Uri, 4L, 1L);
- S3WindowReader s3WindowReader = new S3WindowReader(windowCache, s3ObjectMetadata, s3Client);
+ S3WindowReader s3WindowReader = new S3WindowReader(windowCache, s3ObjectMetadata, s3Client, 1);
byte[] testResponse = "test".getBytes();
for (int i = 0; i < testResponse.length; i++) {
@@ -79,12 +79,12 @@ public void testWindowReaderReturnsExpectedWindowForLargeFile() throws Exception
S3Client s3Client = mockS3Client();
S3Uri s3Uri = S3Uri.builder().uri(URI.create("s3://bucket/key")).build();
S3Utils.S3ObjectMetadata s3ObjectMetadata = new S3Utils.S3ObjectMetadata("bucket", Optional.of("key"), s3Uri, 4L, 1L);
- S3WindowReader s3WindowReader = new S3WindowReader(windowCache, s3ObjectMetadata, s3Client);
+ S3WindowReader s3WindowReader = new S3WindowReader(windowCache, s3ObjectMetadata, s3Client, 10);
s3WindowReader.createWindow(0);
Collection invocations = Mockito.mockingDetails(s3Client).getInvocations();
GetObjectRequest getObjectRequest = (GetObjectRequest)invocations.stream().toList().getFirst().getArguments()[0];
- assertEquals(getObjectRequest.range(), "bytes=0-" + ((4 * 1024 * 1024) - 1));
+ assertEquals(getObjectRequest.range(), "bytes=0-" + 9);
}
@Test
@@ -93,7 +93,7 @@ public void testWindowReaderReturnsNullIfPositionLessThanZero() throws Exception
S3Client s3Client = mock(S3Client.class);
S3Uri s3Uri = S3Uri.builder().uri(URI.create("s3://bucket/key")).build();
S3Utils.S3ObjectMetadata s3ObjectMetadata = new S3Utils.S3ObjectMetadata("bucket", Optional.of("key"), s3Uri, 1L, 1L);
- S3WindowReader s3WindowReader = new S3WindowReader(windowCache, s3ObjectMetadata, s3Client);
+ S3WindowReader s3WindowReader = new S3WindowReader(windowCache, s3ObjectMetadata, s3Client, 1);
assertNull(s3WindowReader.createWindow(-1));
}
@@ -104,7 +104,7 @@ public void testWindowReaderReturnsNullIfPositionGreaterOrEqualToLength() throws
S3Client s3Client = mockS3Client();
S3Uri s3Uri = S3Uri.builder().uri(URI.create("s3://bucket/key")).build();
S3Utils.S3ObjectMetadata s3ObjectMetadata = new S3Utils.S3ObjectMetadata("bucket", Optional.of("key"), s3Uri, 4L, 1L);
- S3WindowReader s3WindowReader = new S3WindowReader(windowCache, s3ObjectMetadata, s3Client);
+ S3WindowReader s3WindowReader = new S3WindowReader(windowCache, s3ObjectMetadata, s3Client, 1);
assertNotNull(s3WindowReader.createWindow(3));
assertNull(s3WindowReader.createWindow(4));
@@ -119,7 +119,7 @@ public void testWindowReaderReturnsErrorOnS3Failure() throws Exception {
when(s3Client.getObject(any(GetObjectRequest.class))).thenThrow(S3Exception.builder().message("Error contacting s3").build());
S3Uri s3Uri = S3Uri.builder().uri(URI.create("s3://bucket/key")).build();
S3Utils.S3ObjectMetadata s3ObjectMetadata = new S3Utils.S3ObjectMetadata("bucket", Optional.of("key"), s3Uri, 1L, 1L);
- S3WindowReader s3WindowReader = new S3WindowReader(windowCache, s3ObjectMetadata, s3Client);
+ S3WindowReader s3WindowReader = new S3WindowReader(windowCache, s3ObjectMetadata, s3Client, 1);
assertThrows(S3Exception.class, () -> s3WindowReader.createWindow(0));
}
diff --git a/droid-core/pom.xml b/droid-core/pom.xml
index ad0526997..4f1f8ad12 100644
--- a/droid-core/pom.xml
+++ b/droid-core/pom.xml
@@ -4,7 +4,7 @@
droid-parent
uk.gov.nationalarchives
- 6.9.7-SNAPSHOT
+ 6.9.8-SNAPSHOT
../droid-parent
@@ -114,12 +114,6 @@
${aws.version}
test
-
- software.amazon.awssdk
- aws-core
- ${aws.version}
- test
-
software.amazon.awssdk
regions
diff --git a/droid-core/src/main/java/uk/gov/nationalarchives/droid/core/signature/droid6/SubSequence.java b/droid-core/src/main/java/uk/gov/nationalarchives/droid/core/signature/droid6/SubSequence.java
index cd5f65718..bbf708d89 100644
--- a/droid-core/src/main/java/uk/gov/nationalarchives/droid/core/signature/droid6/SubSequence.java
+++ b/droid-core/src/main/java/uk/gov/nationalarchives/droid/core/signature/droid6/SubSequence.java
@@ -1406,12 +1406,17 @@ private long[] bytePosForRightFragments(final WindowReader bytes, final long lef
//Add the newly found fragment instance to the top of the stack and reset the loop
// position to resume checking for further fragments from that point.
tempEndPos[numEndPos] = tempFragEnd + searchDirection;
+ //CHECKSTYLE:OFF : Quite legitimate to modify control variables here, as we're
+ // reverting to an earlier fragment!
+ iFragPos = lastGoodFragRef.getFragmentSignaturePosition();
+ iAlt = lastGoodFragRef.getAlternativeFragmentNumber();
+ //CHECKSTYLE:ON
//Get the offset of this new instance of the current fragment from the previous
//fragment, or main sequence if this is the first fragment.
long newOffSetFoundFromPreviousMatch = tempEndPos[numEndPos]
- lastGoodFragRef.getPositionInFile() + lastGoodFragRef.getOffsetFound();
FragmentHit fragmentHit =
- new FragmentHit(lastGoodFragRef.getFragmentSignaturePosition(), lastGoodFragRef.getAlternativeFragmentNumber(), tempEndPos[numEndPos],
+ new FragmentHit(iFragPos, iAlt, tempEndPos[numEndPos],
newOffSetFoundFromPreviousMatch);
fragmentHits.push(fragmentHit);
numEndPos += 1;
diff --git a/droid-core/src/test/java/uk/gov/nationalarchives/droid/core/SkeletonSuiteTest.java b/droid-core/src/test/java/uk/gov/nationalarchives/droid/core/SkeletonSuiteTest.java
index df06f209a..6bbcd4d1c 100644
--- a/droid-core/src/test/java/uk/gov/nationalarchives/droid/core/SkeletonSuiteTest.java
+++ b/droid-core/src/test/java/uk/gov/nationalarchives/droid/core/SkeletonSuiteTest.java
@@ -195,7 +195,7 @@ public static Stream> identificationRequests() {
fileSystemIdentificationRequest.open(skeletonPath);
builder.add(fileSystemIdentificationRequest);
- S3IdentificationRequest s3IdentificationRequest = new S3IdentificationRequest(metaData, s3Identifier, new TestS3Client());
+ S3IdentificationRequest s3IdentificationRequest = new S3IdentificationRequest(metaData, s3Identifier, new TestS3Client(), 65536);
s3IdentificationRequest.open(s3Uri);
builder.add(s3IdentificationRequest);
diff --git a/droid-core/src/test/java/uk/gov/nationalarchives/droid/core/TestS3Client.java b/droid-core/src/test/java/uk/gov/nationalarchives/droid/core/TestS3Client.java
index 31137b776..4acdd9229 100644
--- a/droid-core/src/test/java/uk/gov/nationalarchives/droid/core/TestS3Client.java
+++ b/droid-core/src/test/java/uk/gov/nationalarchives/droid/core/TestS3Client.java
@@ -57,13 +57,6 @@ public ResponseInputStream getObject(GetObjectRequest getObje
}
}
- @Override
- public HeadObjectResponse headObject(HeadObjectRequest headObjectRequest) throws NoSuchKeyException, AwsServiceException,
- SdkClientException {
- long size = FileUtils.sizeOf(new File(headObjectRequest.key()));
- return HeadObjectResponse.builder().contentLength(size).lastModified(Instant.EPOCH).build();
- }
-
@Override
public void close() {}
diff --git a/droid-export-interfaces/pom.xml b/droid-export-interfaces/pom.xml
index 316497baf..265d057cd 100644
--- a/droid-export-interfaces/pom.xml
+++ b/droid-export-interfaces/pom.xml
@@ -4,7 +4,7 @@
droid-parent
uk.gov.nationalarchives
- 6.9.7-SNAPSHOT
+ 6.9.8-SNAPSHOT
../droid-parent
diff --git a/droid-export/pom.xml b/droid-export/pom.xml
index fc5d5efe2..db5aa5e67 100644
--- a/droid-export/pom.xml
+++ b/droid-export/pom.xml
@@ -4,7 +4,7 @@
droid-parent
uk.gov.nationalarchives
- 6.9.7-SNAPSHOT
+ 6.9.8-SNAPSHOT
../droid-parent
diff --git a/droid-help/pom.xml b/droid-help/pom.xml
index 66fd831f5..dcc9d2026 100644
--- a/droid-help/pom.xml
+++ b/droid-help/pom.xml
@@ -4,7 +4,7 @@
droid-parent
uk.gov.nationalarchives
- 6.9.7-SNAPSHOT
+ 6.9.8-SNAPSHOT
../droid-parent
diff --git a/droid-parent/pom.xml b/droid-parent/pom.xml
index 5d2922804..7a893bd3b 100644
--- a/droid-parent/pom.xml
+++ b/droid-parent/pom.xml
@@ -4,7 +4,7 @@
uk.gov.nationalarchives
droid-parent
- 6.9.7-SNAPSHOT
+ 6.9.8-SNAPSHOT
pom
droid-parent
@@ -108,7 +108,7 @@
2.0.17
2.25.2
10.21.2
- 2.34.8
+ 2.35.0
6.0.0
2.20.0
diff --git a/droid-report-interfaces/pom.xml b/droid-report-interfaces/pom.xml
index deb4295c3..b7cf10441 100644
--- a/droid-report-interfaces/pom.xml
+++ b/droid-report-interfaces/pom.xml
@@ -4,7 +4,7 @@
droid-parent
uk.gov.nationalarchives
- 6.9.7-SNAPSHOT
+ 6.9.8-SNAPSHOT
../droid-parent
diff --git a/droid-report/pom.xml b/droid-report/pom.xml
index d9f1e0593..88dd493a5 100644
--- a/droid-report/pom.xml
+++ b/droid-report/pom.xml
@@ -4,7 +4,7 @@
droid-parent
uk.gov.nationalarchives
- 6.9.7-SNAPSHOT
+ 6.9.8-SNAPSHOT
../droid-parent
diff --git a/droid-results/pom.xml b/droid-results/pom.xml
index 246ea7a95..4efb22330 100644
--- a/droid-results/pom.xml
+++ b/droid-results/pom.xml
@@ -4,7 +4,7 @@
droid-parent
uk.gov.nationalarchives
- 6.9.7-SNAPSHOT
+ 6.9.8-SNAPSHOT
../droid-parent
@@ -122,6 +122,7 @@
software.amazon.nio.s3:aws-java-nio-spi-for-s3:jar
org.apache.derby:derby
org.apache.httpcomponents:httpclient:jar
+ org.eclipse.angus:angus-mail:jar
org.slf4j:slf4j-api
@@ -203,6 +204,11 @@
jakarta.xml.bind-api
4.0.4
+
+ org.eclipse.angus
+ angus-mail
+ 2.0.3
+
jakarta.xml.ws
jakarta.xml.ws-api
diff --git a/droid-results/src/main/java/uk/gov/nationalarchives/droid/submitter/S3EventHandler.java b/droid-results/src/main/java/uk/gov/nationalarchives/droid/submitter/S3EventHandler.java
index 4da6cb7c4..26cbbf974 100644
--- a/droid-results/src/main/java/uk/gov/nationalarchives/droid/submitter/S3EventHandler.java
+++ b/droid-results/src/main/java/uk/gov/nationalarchives/droid/submitter/S3EventHandler.java
@@ -44,35 +44,43 @@
import uk.gov.nationalarchives.droid.core.interfaces.http.S3ClientFactory;
import uk.gov.nationalarchives.droid.core.interfaces.resource.RequestMetaData;
import uk.gov.nationalarchives.droid.core.interfaces.resource.S3IdentificationRequest;
-import uk.gov.nationalarchives.droid.core.interfaces.resource.S3Utils;
import uk.gov.nationalarchives.droid.profile.AbstractProfileResource;
import uk.gov.nationalarchives.droid.profile.throttle.SubmissionThrottle;
public class S3EventHandler {
+ private static final int DEFAULT_WINDOW_SIZE = 4 * 1024 * 1024;
+
private AsynchDroid droidCore;
private SubmissionThrottle submissionThrottle;
private ResultHandler resultHandler;
private DroidGlobalConfig config;
+ private S3ClientFactory s3ClientFactory;
- public S3EventHandler(final AsynchDroid droidCore, SubmissionThrottle submissionThrottle, ResultHandler resultHandler, DroidGlobalConfig config) {
+ public S3EventHandler(final AsynchDroid droidCore, SubmissionThrottle submissionThrottle, ResultHandler resultHandler, DroidGlobalConfig config, S3ClientFactory s3ClientFactory) {
this.droidCore = droidCore;
this.submissionThrottle = submissionThrottle;
this.resultHandler = resultHandler;
this.config = config;
+ this.s3ClientFactory = s3ClientFactory;
}
public void onS3Event(AbstractProfileResource resource, ResourceId parentResource) {
S3Client s3Client = getS3Client(resource);
- S3Utils s3Utils = new S3Utils(s3Client);
- S3Utils.S3ObjectMetadata s3ObjectMetadata = s3Utils.getS3ObjectMetadata(resource.getUri());
- RequestMetaData metaData = new RequestMetaData(s3ObjectMetadata.contentLength(), s3ObjectMetadata.lastModified(), resource.getName());
+ RequestMetaData metaData = new RequestMetaData(resource.getSize(), resource.getLastModifiedDate().getTime(), resource.getName());
// Prepare the identifier
RequestIdentifier identifier = new RequestIdentifier(resource.getUri());
identifier.setParentResourceId(parentResource);
// Prepare the request
- IdentificationRequest request = new S3IdentificationRequest(metaData, identifier, s3Client);
+ IdentificationRequest request;
+ long maxBytesToScan = config.getProperties().getLong("profile.maxBytesToScan", -1);
+ if (maxBytesToScan > -1 && maxBytesToScan < DEFAULT_WINDOW_SIZE) {
+ request = new S3IdentificationRequest(metaData, identifier, s3Client, (int) maxBytesToScan);
+ } else {
+ request = new S3IdentificationRequest(metaData, identifier, s3Client, DEFAULT_WINDOW_SIZE);
+ }
+
if (droidCore.passesIdentificationFilter(request)) {
try {
@@ -86,7 +94,7 @@ public void onS3Event(AbstractProfileResource resource, ResourceId parentResourc
public S3Client getS3Client(AbstractProfileResource resource) {
ProxyUtils proxyUtils = new ProxyUtils(config);
- S3ClientFactory s3ClientFactory = new S3ClientFactory(proxyUtils.getProxySettings(resource));
+ s3ClientFactory.init(proxyUtils.getProxySettings(resource));
return s3ClientFactory.getS3Client();
}
@@ -109,4 +117,8 @@ public DroidGlobalConfig getConfig() {
public void setConfig(DroidGlobalConfig config) {
this.config = config;
}
+
+ public void setS3ClientFactory(S3ClientFactory s3ClientFactory) {
+ this.s3ClientFactory = s3ClientFactory;
+ }
}
diff --git a/droid-results/src/main/java/uk/gov/nationalarchives/droid/submitter/S3Walker.java b/droid-results/src/main/java/uk/gov/nationalarchives/droid/submitter/S3Walker.java
index 2aeb9c00b..09c27be89 100644
--- a/droid-results/src/main/java/uk/gov/nationalarchives/droid/submitter/S3Walker.java
+++ b/droid-results/src/main/java/uk/gov/nationalarchives/droid/submitter/S3Walker.java
@@ -65,22 +65,25 @@ public S3Walker(final ProgressMonitor progressMonitor, final ResultHandler resul
public void walk(AbstractProfileResource resource) {
S3Result s3Result = getS3Result(resource);
progressMonitor.setTargetCount(s3Result.totalCount());
- ArrayList keysList = new ArrayList<>(s3Result.dirToFileMap().keySet());
+ ArrayList keysList = new ArrayList<>(s3Result.dirToObjectInfo().keySet());
Map pathToResourceId = new HashMap<>();
keysList.sort(Comparator.comparingInt(String::length));
for (int i=0; i < keysList.size(); i++) {
URI dirUri = URI.create(keysList.get(i));
Path dirPath = getPath(dirUri);
ResourceId fileParentNode = null;
- if (dirPath.getParent() != null) {
+ if (dirPath.getParent() != null && s3Result.totalCount() > 2) {
progressMonitor.startJob(dirUri);
ResourceId parent = dirPath.getParent() == null ? null : pathToResourceId.get(dirPath.getParent().toUri().toString());
fileParentNode = handleS3Directory(dirPath, parent, i+1);
pathToResourceId.put(dirUri + FORWARD_SLASH, fileParentNode);
}
- for (String objectUri: s3Result.dirToFileMap().get(keysList.get(i))) {
- progressMonitor.startJob(URI.create(objectUri.replaceAll(" ", "%20")));
- s3EventHandler.onS3Event(new S3ProfileResource(objectUri), fileParentNode);
+ for (S3ObjectInfo objectInfo: s3Result.dirToObjectInfo().get(keysList.get(i))) {
+ progressMonitor.startJob(URI.create(objectInfo.key().replaceAll(" ", "%20")));
+ S3ProfileResource fileProfileResource = new S3ProfileResource(objectInfo.key);
+ fileProfileResource.setLastModifiedDate(objectInfo.lastModified);
+ fileProfileResource.setSize(objectInfo.size);
+ s3EventHandler.onS3Event(fileProfileResource, fileParentNode);
}
}
}
@@ -106,7 +109,7 @@ private S3Result getS3Result(AbstractProfileResource resource) {
Iterable contents = objectList.contents();
String bucket = objectList.bucket();
- Map> dirToFileMap = new HashMap<>();
+ Map> dirToFileMap = new HashMap<>();
int totalCount = 0;
String uriWithBucket = S3_SCHEME + bucket + FORWARD_SLASH;
@@ -121,8 +124,8 @@ private S3Result getS3Result(AbstractProfileResource resource) {
}
if (!dirToFileMap.containsKey(parent)) {
- List existingKeys = new ArrayList<>();
- existingKeys.add(keyUri);
+ List existingKeys = new ArrayList<>();
+ existingKeys.add(new S3ObjectInfo(keyUri, new Date(s3Object.lastModified().toEpochMilli()), s3Object.size()));
dirToFileMap.put(parent, existingKeys);
if (FORWARD_SLASH.equals(URI.create(parent).getPath())) {
totalCount = totalCount + 1;
@@ -131,16 +134,16 @@ private S3Result getS3Result(AbstractProfileResource resource) {
}
} else {
- List existingKeys = dirToFileMap.get(parent);
- existingKeys.add(keyUri);
+ List existingKeys = dirToFileMap.get(parent);
+ existingKeys.add(new S3ObjectInfo(keyUri, new Date(s3Object.lastModified().toEpochMilli()), s3Object.size()));
dirToFileMap.put(parent, existingKeys);
totalCount++;
}
}
return new S3Result(dirToFileMap, totalCount);
}
-
- private record S3Result(Map> dirToFileMap, int totalCount) {
+ private record S3ObjectInfo(String key, Date lastModified, long size) {}
+ private record S3Result(Map> dirToObjectInfo, int totalCount) {
}
private Path getPath(URI uri) {
diff --git a/droid-results/src/main/resources/META-INF/spring-results.xml b/droid-results/src/main/resources/META-INF/spring-results.xml
index ef13ab80a..4b9908711 100644
--- a/droid-results/src/main/resources/META-INF/spring-results.xml
+++ b/droid-results/src/main/resources/META-INF/spring-results.xml
@@ -267,6 +267,8 @@ http://www.springframework.org/schema/context http://www.springframework.org/sch
+
+
@@ -313,6 +315,7 @@ http://www.springframework.org/schema/context http://www.springframework.org/sch
+
diff --git a/droid-results/src/test/java/uk/gov/nationalarchives/droid/submitter/S3EventHandlerTest.java b/droid-results/src/test/java/uk/gov/nationalarchives/droid/submitter/S3EventHandlerTest.java
new file mode 100644
index 000000000..55a077031
--- /dev/null
+++ b/droid-results/src/test/java/uk/gov/nationalarchives/droid/submitter/S3EventHandlerTest.java
@@ -0,0 +1,146 @@
+/*
+ * Copyright (c) 2016, The National Archives
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following
+ * conditions are met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * * Neither the name of the The National Archives nor the
+ * names of its contributors may be used to endorse or promote products
+ * derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+package uk.gov.nationalarchives.droid.submitter;
+
+import org.apache.commons.configuration2.PropertiesConfiguration;
+import org.apache.commons.configuration2.ex.ConfigurationException;
+import org.junit.Test;
+import org.mockito.ArgumentCaptor;
+import software.amazon.awssdk.services.s3.S3Client;
+import software.amazon.awssdk.services.s3.S3Uri;
+import uk.gov.nationalarchives.droid.core.interfaces.AsynchDroid;
+import uk.gov.nationalarchives.droid.core.interfaces.IdentificationRequest;
+import uk.gov.nationalarchives.droid.core.interfaces.ResultHandler;
+import uk.gov.nationalarchives.droid.core.interfaces.config.DroidGlobalConfig;
+import uk.gov.nationalarchives.droid.core.interfaces.http.S3ClientFactory;
+import uk.gov.nationalarchives.droid.core.interfaces.resource.RequestMetaData;
+import uk.gov.nationalarchives.droid.core.interfaces.resource.S3IdentificationRequest;
+import uk.gov.nationalarchives.droid.profile.S3ProfileResource;
+import uk.gov.nationalarchives.droid.profile.throttle.SubmissionThrottle;
+
+import java.io.IOException;
+import java.io.StringReader;
+import java.util.List;
+import java.util.concurrent.CompletableFuture;
+
+import static org.junit.Assert.assertEquals;
+import static org.mockito.ArgumentMatchers.any;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.when;
+
+public class S3EventHandlerTest {
+ @Test
+ public void testS3EventHandlerProvidesCorrectMetadata() {
+ ArgumentCaptor> droidCoreCaptor = ArgumentCaptor.forClass(IdentificationRequest.class);
+ S3EventHandler s3EventHandler = getS3EventHandler(droidCoreCaptor, 100, true);
+ S3ProfileResource s3ProfileResource = new S3ProfileResource("s3://bucket/object");
+
+ s3EventHandler.onS3Event(s3ProfileResource, null);
+ List> allValues = droidCoreCaptor.getAllValues();
+
+ RequestMetaData requestMetaData = allValues.getFirst().getRequestMetaData();
+ assertEquals(Long.valueOf(1), requestMetaData.getSize());
+ assertEquals(Long.valueOf(0), requestMetaData.getTime());
+ assertEquals("object", requestMetaData.getName());
+ }
+
+ @Test
+ public void testS3EventHandlerUsesCorrectWindowSizeForSmallMaxBytes() {
+ ArgumentCaptor> droidCoreCaptor = ArgumentCaptor.forClass(IdentificationRequest.class);
+ S3EventHandler s3EventHandler = getS3EventHandler(droidCoreCaptor, 100, true);
+ S3ProfileResource s3ProfileResource = new S3ProfileResource("s3://bucket/object");
+
+ s3EventHandler.onS3Event(s3ProfileResource, null);
+ List> allValues = droidCoreCaptor.getAllValues();
+
+ assertEquals(100, ((S3IdentificationRequest) allValues.getFirst()).getWindowSize());
+ }
+
+ @Test
+ public void testS3EventHandlerUsesCorrectWindowSizeForLargeMaxBytes() {
+ ArgumentCaptor> droidCoreCaptor = ArgumentCaptor.forClass(IdentificationRequest.class);
+ S3EventHandler s3EventHandler = getS3EventHandler(droidCoreCaptor, 100 * 1024 * 1024, true);
+ S3ProfileResource s3ProfileResource = new S3ProfileResource("s3://bucket/object");
+
+ s3EventHandler.onS3Event(s3ProfileResource, null);
+ List> allValues = droidCoreCaptor.getAllValues();
+
+ assertEquals(4 * 1024 * 1024, ((S3IdentificationRequest) allValues.getFirst()).getWindowSize());
+ }
+
+ @Test
+ public void testS3EventHandlerUsesCorrectWindowSizeForInfiniteBytes() {
+ ArgumentCaptor> droidCoreCaptor = ArgumentCaptor.forClass(IdentificationRequest.class);
+ S3EventHandler s3EventHandler = getS3EventHandler(droidCoreCaptor, 100 * 1024 * 1024, true);
+ S3ProfileResource s3ProfileResource = new S3ProfileResource("s3://bucket/object");
+
+ s3EventHandler.onS3Event(s3ProfileResource, null);
+ List> allValues = droidCoreCaptor.getAllValues();
+
+ assertEquals(4 * 1024 * 1024, ((S3IdentificationRequest) allValues.getFirst()).getWindowSize());
+ }
+
+ @Test
+ public void testS3EventHandlerDoesNotSubmitIfItDoesNotPassFilter() {
+ ArgumentCaptor> droidCoreCaptor = ArgumentCaptor.forClass(IdentificationRequest.class);
+ S3EventHandler s3EventHandler = getS3EventHandler(droidCoreCaptor, 100 * 1024 * 1024, false);
+ S3ProfileResource s3ProfileResource = new S3ProfileResource("s3://bucket/object");
+
+ s3EventHandler.onS3Event(s3ProfileResource, null);
+ List> allValues = droidCoreCaptor.getAllValues();
+
+ assertEquals(0, allValues.size());
+ }
+
+ private static S3EventHandler getS3EventHandler(ArgumentCaptor> droidCoreCaptor, int maxBytesToScan, boolean passesIdentification) {
+ AsynchDroid droidCore = mock(AsynchDroid.class);
+ SubmissionThrottle submissionThrottle = mock(SubmissionThrottle.class);
+ ResultHandler resultHandler = mock(ResultHandler.class);
+ DroidGlobalConfig droidGlobalConfig = mock(DroidGlobalConfig.class);
+ PropertiesConfiguration propertiesConfiguration = new PropertiesConfiguration();
+
+ when(droidCore.passesIdentificationFilter(any())).thenReturn(passesIdentification);
+
+ when(droidCore.submit(droidCoreCaptor.capture())).thenReturn(CompletableFuture.completedFuture(null));
+ try {
+ propertiesConfiguration.read(new StringReader("profile.maxBytesToScan=" + maxBytesToScan + "\nupdate.proxy=false"));
+ } catch (ConfigurationException | IOException e) {
+ throw new RuntimeException(e);
+ }
+ when(droidGlobalConfig.getProperties()).thenReturn(propertiesConfiguration);
+
+ S3ClientFactory s3ClientFactory = mock(S3ClientFactory.class);
+ S3Client s3Client = mock(S3Client.class);
+ when(s3ClientFactory.getS3Client()).thenReturn(s3Client);
+ return new S3EventHandler(droidCore, submissionThrottle, resultHandler, droidGlobalConfig, s3ClientFactory);
+ }
+}
diff --git a/droid-swing-ui/pom.xml b/droid-swing-ui/pom.xml
index e1d4aff2a..8d06e2d43 100644
--- a/droid-swing-ui/pom.xml
+++ b/droid-swing-ui/pom.xml
@@ -4,7 +4,7 @@
droid-parent
uk.gov.nationalarchives
- 6.9.7-SNAPSHOT
+ 6.9.8-SNAPSHOT
../droid-parent
diff --git a/droid-tools/pom.xml b/droid-tools/pom.xml
index 798453de6..2617d57fe 100644
--- a/droid-tools/pom.xml
+++ b/droid-tools/pom.xml
@@ -5,7 +5,7 @@
droid-parent
uk.gov.nationalarchives
- 6.9.7-SNAPSHOT
+ 6.9.8-SNAPSHOT
../droid-parent
diff --git a/pom.xml b/pom.xml
index 76626b216..64987ff79 100644
--- a/pom.xml
+++ b/pom.xml
@@ -4,7 +4,7 @@
droid-parent
uk.gov.nationalarchives
- 6.9.7-SNAPSHOT
+ 6.9.8-SNAPSHOT
droid-parent