Skip to content

Commit

Permalink
Merge pull request #2160 from adobe/prepare-4-0-0
Browse files Browse the repository at this point in the history
Prepare 4.0.0
  • Loading branch information
afranken authored Dec 16, 2024
2 parents ec52cbd + 698721b commit 7cfbe26
Show file tree
Hide file tree
Showing 21 changed files with 163 additions and 151 deletions.
13 changes: 10 additions & 3 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@
* [PLANNED - 5.x - RELEASE TBD](#planned---5x---release-tbd)
* [Planned changes](#planned-changes)
* [CURRENT - 4.x - THIS VERSION IS UNDER ACTIVE DEVELOPMENT](#current---4x---this-version-is-under-active-development)
* [4.0.0 - PLANNED](#400---planned)
* [4.0.0](#400)
* [DEPRECATED - 3.x](#deprecated---3x)
* [3.12.0](#3120)
* [3.11.0](#3110)
Expand Down Expand Up @@ -133,14 +133,21 @@ Version 4.x is JDK17 LTS bytecode compatible, with Docker and JUnit / direct Jav

**The current major version 4 will receive new features, dependency updates and bug fixes on a continuous basis.**

### 4.0.0 - PLANNED
### 4.0.0

* Features and fixes
* Allow overriding headers in head object
* Implement If-(Un)modified-Since handling (fixes #829)
* Refactorings
* Use Tomcat instead of Jetty (fixes #2136)
* Use Tomcat instead of Jetty as the application container (fixes #2136)
* "FROM" in Dockerfile did not match "as"
* Version updates (deliverable dependencies)
* none
* Version updates (build dependencies)
* Bump github/codeql-action from 3.27.6 to 3.27.9
* Bump com.puppycrawl.tools:checkstyle from 10.20.2 to 10.21.0
* Jackson 2.18.2 to 2.17.2 (remove override, use Spring-Boot supplied version)


# DEPRECATED - 3.x
Version 3.x is JDK17 LTS bytecode compatible, with Docker and JUnit / direct Java integration.
Expand Down
2 changes: 1 addition & 1 deletion build-config/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@
<parent>
<groupId>com.adobe.testing</groupId>
<artifactId>s3mock-parent</artifactId>
<version>3.12.1-SNAPSHOT</version>
<version>4.0.0-SNAPSHOT</version>
</parent>

<artifactId>s3mock-build-config</artifactId>
Expand Down
2 changes: 1 addition & 1 deletion docker/Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@
# limitations under the License.
#

FROM alpine:3.21.0@sha256:21dc6063fd678b478f57c0e13f47560d0ea4eeba26dfc947b2a4f81f686b9f45 as staging_area
FROM alpine:3.21.0@sha256:21dc6063fd678b478f57c0e13f47560d0ea4eeba26dfc947b2a4f81f686b9f45 AS staging_area

RUN apk --no-cache add openjdk21-jdk openjdk21-jmods

Expand Down
2 changes: 1 addition & 1 deletion docker/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@
<parent>
<groupId>com.adobe.testing</groupId>
<artifactId>s3mock-parent</artifactId>
<version>3.12.1-SNAPSHOT</version>
<version>4.0.0-SNAPSHOT</version>
</parent>

<artifactId>s3mock-docker</artifactId>
Expand Down
8 changes: 4 additions & 4 deletions integration-tests/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@
<parent>
<groupId>com.adobe.testing</groupId>
<artifactId>s3mock-parent</artifactId>
<version>3.12.1-SNAPSHOT</version>
<version>4.0.0-SNAPSHOT</version>
</parent>

<artifactId>s3mock-integration-tests</artifactId>
Expand Down Expand Up @@ -161,8 +161,8 @@
<time>30000</time>
</wait>
<env>
<validKmsKeys>arn:aws:kms:us-east-1:1234567890:key/valid-test-key-id</validKmsKeys>
<initialBuckets>bucket-a, bucket-b</initialBuckets>
<COM_ADOBE_TESTING_S3MOCK_DOMAIN_VALID_KMS_KEYS>arn:aws:kms:us-east-1:1234567890:key/valid-test-key-id</COM_ADOBE_TESTING_S3MOCK_DOMAIN_VALID_KMS_KEYS>
<COM_ADOBE_TESTING_S3MOCK_DOMAIN_INITIAL_BUCKETS>bucket-a, bucket-b</COM_ADOBE_TESTING_S3MOCK_DOMAIN_INITIAL_BUCKETS>
<COM_ADOBE_TESTING_S3MOCK_REGION>eu-west-1</COM_ADOBE_TESTING_S3MOCK_REGION>
</env>
<memory>192000000</memory>
Expand Down Expand Up @@ -243,7 +243,7 @@
<it.s3mock.port_https>${it.s3mock.port_https}</it.s3mock.port_https>
<it.s3mock.port_http>${it.s3mock.port_http}</it.s3mock.port_http>
</systemPropertyVariables>
<runOrder>alphabetical</runOrder>
<runOrder>random</runOrder>
</configuration>
</execution>
</executions>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,6 @@ import org.junit.jupiter.api.Test
import org.junit.jupiter.api.TestInfo
import java.io.File
import java.io.FileInputStream
import java.io.InputStream
import java.util.UUID

/**
Expand Down Expand Up @@ -310,6 +309,7 @@ internal class CopyObjectV1IT : S3TestBase() {
s3Client.getObject(destinationBucketName, destinationKey).use {
val copiedDigest = DigestUtil.hexDigest(it.objectContent)
assertThat(copiedDigest).isEqualTo(putObjectResult.eTag)
assertThat(it.objectMetadata.contentLength).isEqualTo(uploadFile.length())
}
}

Expand All @@ -328,8 +328,8 @@ internal class CopyObjectV1IT : S3TestBase() {
val destinationKey = "copyOf/$sourceKey"
val putObjectResult = s3Client.putObject(PutObjectRequest(bucketName, sourceKey, uploadFile))
CopyObjectRequest(bucketName, sourceKey, destinationBucketName, destinationKey).also {
s3Client.copyObject(it)
}
s3Client.copyObject(it)
}

s3Client.getObject(destinationBucketName, destinationKey).use {
val copiedDigest = DigestUtil.hexDigest(it.objectContent)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -388,4 +388,42 @@ internal class CopyObjectV2IT : S3TestBase() {
assertThat(it.response().contentDisposition()).isEqualTo("attachment")
}
}

@Test
@S3VerifiedTodo
fun testCopyObject_encrypted(testInfo: TestInfo) {
val sourceKey = UPLOAD_FILE_NAME
val uploadFile = File(UPLOAD_FILE_NAME)
val bucketName = givenBucketV2(testInfo)

s3ClientV2.putObject(
PutObjectRequest.builder()
.bucket(bucketName)
.key(sourceKey)
.build(),
RequestBody.fromFile(uploadFile)
)

val destinationBucketName = givenRandomBucketV2()
val destinationKey = "copyOf/$sourceKey"

s3ClientV2.copyObject(CopyObjectRequest
.builder()
.sourceBucket(bucketName)
.sourceKey(sourceKey)
.destinationBucket(destinationBucketName)
.destinationKey(destinationKey)
.sseCustomerKey(TEST_ENC_KEY_ID)
.build()
)

s3ClientV2.headObject(HeadObjectRequest
.builder()
.bucket(destinationBucketName)
.key(destinationKey)
.build()
).also {
assertThat(it.contentLength()).isEqualTo(uploadFile.length())
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -17,14 +17,11 @@
package com.adobe.testing.s3mock.its

import com.adobe.testing.s3mock.util.DigestUtil
import org.apache.http.HttpHost
import org.apache.http.HttpStatus
import org.apache.http.client.methods.HttpOptions
import org.apache.http.client.methods.HttpPut
import org.apache.http.entity.ByteArrayEntity
import org.apache.http.impl.client.CloseableHttpClient
import org.apache.http.impl.client.HttpClientBuilder
import org.apache.http.impl.client.HttpClients
import org.apache.http.message.BasicHeader
import org.assertj.core.api.Assertions.assertThat
import org.junit.jupiter.api.Test
Expand All @@ -36,35 +33,28 @@ import java.util.UUID
* Test the application using the AmazonS3 SDK V2.
*/
internal class CorsV2IT : S3TestBase() {
private val httpClient: CloseableHttpClient = HttpClients.createDefault()
private val httpClient: CloseableHttpClient = createHttpClient()

@Test
@S3VerifiedFailure(year = 2024,
reason = "No credentials sent in plain HTTP request")
fun testPutObject_cors(testInfo: TestInfo) {
val bucketName = givenBucketV2(testInfo)
val httpclient = HttpClientBuilder.create().build()
val optionsRequest = HttpOptions("/${bucketName}/testObjectName").apply {
val optionsRequest = HttpOptions("$serviceEndpoint/${bucketName}/testObjectName").apply {
this.addHeader("Origin", "http://localhost/")
}
httpclient.execute(HttpHost(
host, httpPort
), optionsRequest).also {
httpClient.execute(optionsRequest).also {
assertThat(it.getFirstHeader("Allow").value).contains("PUT")
}

val byteArray = UUID.randomUUID().toString().toByteArray()
val expectedEtag = "\"${DigestUtil.hexDigest(byteArray)}\""
val putObject = HttpPut("/$bucketName/testObjectName").apply {
val putObject = HttpPut("$serviceEndpoint/$bucketName/testObjectName").apply {
this.entity = ByteArrayEntity(byteArray)
this.addHeader("Origin", "http://localhost/")
}

httpClient.execute(
HttpHost(
host, httpPort
), putObject
).use {
httpClient.execute(putObject).use {
assertThat(it.statusLine.statusCode).isEqualTo(HttpStatus.SC_OK)
assertThat(it.getFirstHeader("ETag").value).isEqualTo(expectedEtag)
assertThat(it.getFirstHeader("Access-Control-Allow-Origin").value).isEqualTo("*")
Expand All @@ -77,17 +67,13 @@ internal class CorsV2IT : S3TestBase() {
reason = "No credentials sent in plain HTTP request")
fun testGetBucket_cors(testInfo: TestInfo) {
val targetBucket = givenBucketV2(testInfo)
val httpOptions = HttpOptions("/$targetBucket").apply {
val httpOptions = HttpOptions("$serviceEndpoint/$targetBucket").apply {
this.addHeader(BasicHeader("Origin", "http://someurl.com"))
this.addHeader(BasicHeader("Access-Control-Request-Method", "GET"))
this.addHeader(BasicHeader("Access-Control-Request-Headers", "Content-Type, x-requested-with"))
}

httpClient.execute(
HttpHost(
host, httpPort
), httpOptions
).use {
httpClient.execute(httpOptions).use {
assertThat(it.getFirstHeader("Access-Control-Allow-Origin").value).isEqualTo("http://someurl.com")
assertThat(it.getFirstHeader("Access-Control-Allow-Methods").value).isEqualTo("GET")
assertThat(it.getFirstHeader("Access-Control-Allow-Headers").value)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -31,9 +31,8 @@ import com.amazonaws.services.s3.model.PutObjectRequest
import com.amazonaws.services.s3.model.ResponseHeaderOverrides
import com.amazonaws.services.s3.model.SSEAwsKeyManagementParams
import com.amazonaws.services.s3.transfer.TransferManager
import org.apache.http.HttpHost
import org.apache.http.client.methods.HttpGet
import org.apache.http.impl.client.HttpClients
import org.apache.http.impl.client.CloseableHttpClient
import org.assertj.core.api.Assertions.assertThat
import org.assertj.core.api.Assertions.assertThatThrownBy
import org.assertj.core.configuration.Configuration
Expand All @@ -47,14 +46,14 @@ import java.io.FileInputStream
import java.io.InputStream
import java.util.UUID
import java.util.stream.Collectors
import javax.net.ssl.HostnameVerifier
import kotlin.math.min

/**
* Test the application using the AmazonS3 SDK V1.
*/
internal class GetPutDeleteObjectV1IT : S3TestBase() {

private val httpClient: CloseableHttpClient = createHttpClient()
private val s3Client: AmazonS3 = createS3ClientV1()
private val transferManagerV1: TransferManager = createTransferManagerV1()

Expand Down Expand Up @@ -82,6 +81,7 @@ internal class GetPutDeleteObjectV1IT : S3TestBase() {
.build()
uploadClient.putObject(PutObjectRequest(bucketName, uploadFile.name, uploadFile))
s3Client.getObject(bucketName, uploadFile.name).also {
assertThat(it.objectMetadata.contentLength).isEqualTo(uploadFile.length())
verifyObjectContent(uploadFile, it)
}
}
Expand Down Expand Up @@ -459,12 +459,10 @@ internal class GetPutDeleteObjectV1IT : S3TestBase() {
)
this.method = HttpMethod.GET
}
val resourceUrl = createS3ClientV1(serviceEndpointHttp).generatePresignedUrl(presignedUrlRequest)
HttpClients.createDefault().use {
val resourceUrl = s3Client.generatePresignedUrl(presignedUrlRequest)
httpClient.use {
val getObject = HttpGet(resourceUrl.toString())
it.execute(
getObject
).also { response ->
it.execute(getObject).also { response ->
assertThat(response.getFirstHeader(Headers.CACHE_CONTROL).value).isEqualTo("cacheControl")
assertThat(response.getFirstHeader(Headers.CONTENT_DISPOSITION).value).isEqualTo("contentDisposition")
assertThat(response.getFirstHeader(Headers.CONTENT_ENCODING).value).isEqualTo("contentEncoding")
Expand Down
Loading

0 comments on commit 7cfbe26

Please sign in to comment.