Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Lets AsyncSignedRequest and SignedRequest implement CopyableBuilder #4607

Merged
merged 4 commits into from
Nov 1, 2023
Merged
Show file tree
Hide file tree
Changes from 3 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 6 additions & 0 deletions .changes/next-release/feature-AWSSDKforJavav2-5d2de6d.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
{
"type": "feature",
"category": "AWS SDK for Java v2",
"contributor": "",
"description": "Makes SignedRequest and AsyncSignedRequest implement CopyableBuilder to allow modifications"
}
Original file line number Diff line number Diff line change
Expand Up @@ -430,7 +430,11 @@ private void validateBuilderViaMethods(String buildableClassName, JavaClass buil
if (builders.containsKey(concreteClass)) {
// We're invoking these methods on a known builder. Assume the method name matches the field name and validate
// based on that.
Set<String> builderFieldsForBuilder = new HashSet<>(builderFields.get(concreteClass));
List<String> concreteClassBuilderFields = builderFields.get(concreteClass);
if (concreteClassBuilderFields == null) {
concreteClassBuilderFields = new ArrayList<>();
}
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

getOrDefault?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

That'd be nice(r)

Set<String> builderFieldsForBuilder = new HashSet<>(concreteClassBuilderFields);
invokedMethods.forEach(builderFieldsForBuilder::remove);
ignoredFields.getOrDefault(buildableClassName, emptyList()).forEach(builderFieldsForBuilder::remove);

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -29,18 +29,30 @@ private DefaultAsyncSignedRequest(BuilderImpl builder) {
super(builder);
}

public static BuilderImpl builder() {
return new BuilderImpl();
}

@Override
public String toString() {
return ToString.builder("AsyncSignedRequest")
.add("request", request)
.build();
}

@Override
public AsyncSignedRequest.Builder toBuilder() {
return AsyncSignedRequest.builder().request(request).payload(payload);
}

@SdkInternalApi
public static final class BuilderImpl
extends DefaultBaseSignedRequest.BuilderImpl<AsyncSignedRequest.Builder, Publisher<ByteBuffer>>
implements AsyncSignedRequest.Builder {

private BuilderImpl() {
}

@Override
public AsyncSignedRequest build() {
return new DefaultAsyncSignedRequest(this);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -28,18 +28,30 @@ private DefaultSignedRequest(BuilderImpl builder) {
super(builder);
}

public static BuilderImpl builder() {
return new BuilderImpl();
}

@Override
public String toString() {
return ToString.builder("SyncSignedRequest")
.add("request", request)
.build();
}

@Override
public SignedRequest.Builder toBuilder() {
return SignedRequest.builder().request(request).payload(payload);
}

@SdkInternalApi
public static final class BuilderImpl
extends DefaultBaseSignedRequest.BuilderImpl<SignedRequest.Builder, ContentStreamProvider>
implements SignedRequest.Builder {

private BuilderImpl() {
}

@Override
public SignedRequest build() {
return new DefaultSignedRequest(this);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,27 +21,29 @@
import software.amazon.awssdk.annotations.SdkPublicApi;
import software.amazon.awssdk.annotations.ThreadSafe;
import software.amazon.awssdk.http.auth.spi.internal.signer.DefaultAsyncSignedRequest;
import software.amazon.awssdk.utils.builder.SdkBuilder;
import software.amazon.awssdk.utils.builder.CopyableBuilder;
import software.amazon.awssdk.utils.builder.ToCopyableBuilder;

/**
* Represents a request with async payload that has been signed by {@link HttpSigner}.
*/
@SdkPublicApi
@Immutable
@ThreadSafe
public interface AsyncSignedRequest extends BaseSignedRequest<Publisher<ByteBuffer>> {
public interface AsyncSignedRequest extends BaseSignedRequest<Publisher<ByteBuffer>>,
ToCopyableBuilder<AsyncSignedRequest.Builder, AsyncSignedRequest> {

/**
* Get a new builder for creating a {@link AsyncSignedRequest}.
*/
static Builder builder() {
return new DefaultAsyncSignedRequest.BuilderImpl();
return DefaultAsyncSignedRequest.builder();
}

/**
* A builder for a {@link AsyncSignedRequest}.
*/
interface Builder extends BaseSignedRequest.Builder<Builder, Publisher<ByteBuffer>>,
SdkBuilder<Builder, AsyncSignedRequest> {
CopyableBuilder<AsyncSignedRequest.Builder, AsyncSignedRequest> {
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -20,27 +20,28 @@
import software.amazon.awssdk.annotations.ThreadSafe;
import software.amazon.awssdk.http.ContentStreamProvider;
import software.amazon.awssdk.http.auth.spi.internal.signer.DefaultSignedRequest;
import software.amazon.awssdk.utils.builder.SdkBuilder;
import software.amazon.awssdk.utils.builder.CopyableBuilder;
import software.amazon.awssdk.utils.builder.ToCopyableBuilder;

/**
* Represents a request with sync payload that has been signed by {@link HttpSigner}.
*/
@SdkPublicApi
@Immutable
@ThreadSafe
public interface SignedRequest extends BaseSignedRequest<ContentStreamProvider> {
public interface SignedRequest extends BaseSignedRequest<ContentStreamProvider>,
ToCopyableBuilder<SignedRequest.Builder, SignedRequest> {

/**
* Get a new builder for creating a {@link SignedRequest}.
*/
static Builder builder() {
return new DefaultSignedRequest.BuilderImpl();
return DefaultSignedRequest.builder();
}

/**
* A builder for a {@link SignedRequest}.
*/
interface Builder extends BaseSignedRequest.Builder<Builder, ContentStreamProvider>,
SdkBuilder<Builder, SignedRequest> {
interface Builder extends BaseSignedRequest.Builder<Builder, ContentStreamProvider>, CopyableBuilder<Builder, SignedRequest> {
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,105 @@
/*
* Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License").
* You may not use this file except in compliance with the License.
* A copy of the License is located at
*
* http://aws.amazon.com/apache2.0
*
* or in the "license" file accompanying this file. This file is distributed
* on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
* express or implied. See the License for the specific language governing
* permissions and limitations under the License.
*/

package software.amazon.awssdk.http.auth.spi.signer;

import static org.assertj.core.api.Assertions.assertThat;
import static org.assertj.core.api.Assertions.assertThatThrownBy;
import static org.junit.jupiter.api.Assertions.assertNotNull;
import static org.mockito.Mockito.mock;

import org.junit.jupiter.api.Test;
import software.amazon.awssdk.http.SdkHttpRequest;

public class AsyncSignedRequestTest {

@Test
public void createSignedRequest_missingRequest_throwsException() {
assertThatThrownBy(() -> AsyncSignedRequest.builder().build())
.isInstanceOf(NullPointerException.class)
.hasMessageContaining("request must not be null");
}

@Test
public void createSignedRequest_minimalBuild_works() {
SdkHttpRequest request = mock(SdkHttpRequest.class);
AsyncSignedRequest signedRequest = AsyncSignedRequest.builder()
.request(request)
.build();

assertNotNull(signedRequest);
assertThat(signedRequest.request()).isEqualTo(request);
}

@Test
public void createSignedRequest_maximalBuild_works() {
SdkHttpRequest request = mock(SdkHttpRequest.class);
AsyncSignedRequest signedRequest = AsyncSignedRequest.builder()
.request(request)
.payload(subscriber -> {})
.build();

assertNotNull(signedRequest);
assertThat(signedRequest.request()).isEqualTo(request);
assertThat(signedRequest.payload()).isPresent();
}

@Test
public void createSignedRequest_toBuilder_works() {
SdkHttpRequest request = mock(SdkHttpRequest.class);
AsyncSignedRequest signedRequest = AsyncSignedRequest.builder()
.request(request)
.payload(subscriber -> {})
.build();

AsyncSignedRequest.Builder builder = signedRequest.toBuilder();
AsyncSignedRequest copy = builder.build();

assertNotNull(copy);
assertThat(copy.request()).isEqualTo(request);
assertThat(copy.payload()).isPresent();
}

@Test
public void createSignedRequest_copyNoChange_works() {
SdkHttpRequest request = mock(SdkHttpRequest.class);
AsyncSignedRequest signedRequest = AsyncSignedRequest.builder()
.request(request)
.payload(subscriber -> {})
.build();

AsyncSignedRequest copy = signedRequest.copy(r -> {});

assertNotNull(copy);
assertThat(copy.request()).isEqualTo(request);
assertThat(copy.payload()).isPresent();
}

@Test
public void createSignedRequest_copyWithChange_works() {
SdkHttpRequest firstRequest = mock(SdkHttpRequest.class);
SdkHttpRequest secondRequest = mock(SdkHttpRequest.class);
AsyncSignedRequest signedRequest = AsyncSignedRequest.builder()
.request(firstRequest)
.payload(subscriber -> {})
.build();

AsyncSignedRequest copy = signedRequest.copy(r -> r.request(secondRequest));

assertNotNull(copy);
assertThat(copy.request()).isEqualTo(secondRequest);
assertThat(copy.payload()).isPresent();
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,105 @@
/*
* Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License").
* You may not use this file except in compliance with the License.
* A copy of the License is located at
*
* http://aws.amazon.com/apache2.0
*
* or in the "license" file accompanying this file. This file is distributed
* on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
* express or implied. See the License for the specific language governing
* permissions and limitations under the License.
*/

package software.amazon.awssdk.http.auth.spi.signer;

import static org.assertj.core.api.Assertions.assertThat;
import static org.assertj.core.api.Assertions.assertThatThrownBy;
import static org.junit.jupiter.api.Assertions.assertNotNull;
import static org.mockito.Mockito.mock;

import org.junit.jupiter.api.Test;
import software.amazon.awssdk.http.SdkHttpRequest;
import software.amazon.awssdk.utils.StringInputStream;

public class SignedRequestTest {

@Test
public void createSignedRequest_missingRequest_throwsException() {
assertThatThrownBy(() -> SignedRequest.builder().build())
.isInstanceOf(NullPointerException.class)
.hasMessageContaining("request must not be null");
}

@Test
public void createSignedRequest_minimalBuild_works() {
SdkHttpRequest request = mock(SdkHttpRequest.class);
SignedRequest signedRequest = SignedRequest.builder()
.request(request)
.build();

assertNotNull(signedRequest);
assertThat(signedRequest.request()).isEqualTo(request);
}

@Test
public void createSignedRequest_maximalBuild_works() {
SdkHttpRequest request = mock(SdkHttpRequest.class);
SignedRequest signedRequest = SignedRequest.builder()
.request(request)
.payload(() -> new StringInputStream("test"))
.build();

assertNotNull(signedRequest);
assertThat(signedRequest.request()).isEqualTo(request);
assertThat(signedRequest.payload()).isPresent();
}

@Test
public void createSignedRequest_toBuilder_works() {
SdkHttpRequest request = mock(SdkHttpRequest.class);
SignedRequest signedRequest = SignedRequest.builder()
.request(request)
.payload(() -> new StringInputStream("test"))
.build();

SignedRequest copy = signedRequest.toBuilder().build();

assertNotNull(copy);
assertThat(copy.request()).isEqualTo(request);
assertThat(copy.payload()).isPresent();
}

@Test
public void createSignedRequest_copyNoChange_works() {
SdkHttpRequest request = mock(SdkHttpRequest.class);
SignedRequest signedRequest = SignedRequest.builder()
.request(request)
.payload(() -> new StringInputStream("test"))
.build();

SignedRequest copy = signedRequest.copy(r -> {});

assertNotNull(copy);
assertThat(copy.request()).isEqualTo(request);
assertThat(copy.payload()).isPresent();
}

@Test
public void createSignedRequest_copyWithChange_works() {
SdkHttpRequest firstRequest = mock(SdkHttpRequest.class);
SdkHttpRequest secondRequest = mock(SdkHttpRequest.class);
SignedRequest signedRequest = SignedRequest.builder()
.request(firstRequest)
.payload(() -> new StringInputStream("test"))
.build();

SignedRequest copy = signedRequest.copy(r -> r.request(secondRequest));

assertNotNull(copy);
assertThat(copy.request()).isEqualTo(secondRequest);
assertThat(copy.payload()).isPresent();
}
}
Loading
Loading