Skip to content
This repository was archived by the owner on Aug 27, 2025. It is now read-only.

Commit b513b18

Browse files
authored
Fixing contract tests for version 1.0.11 (#51)
* Fixing contract tests for version 1.0.11 * Changing ReadHandler so that it actually reads the live state of the resource.
1 parent 6001f07 commit b513b18

File tree

20 files changed

+582
-75
lines changed

20 files changed

+582
-75
lines changed
Lines changed: 2 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
{
2+
"DomainName": "create-contract-domain",
23
"PermissionsPolicyDocument": {
34
"Version": "2012-10-17",
45
"Statement": [
@@ -9,11 +10,5 @@
910
"Resource": "*"
1011
}
1112
]
12-
},
13-
"Upstreams": null,
14-
"ExternalConnections": [
15-
"public:npmjs"
16-
],
17-
"DomainName": "create-contract-domain",
18-
"Description": "test description"
13+
}
1914
}

aws-codeartifact-domain/inputs/inputs_1_update.json

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -10,8 +10,5 @@
1010
}
1111
]
1212
},
13-
"Upstreams": null,
14-
"ExternalConnections": null,
15-
"DomainName": "create-contract-domain",
16-
"Description": "test description"
13+
"DomainName": "create-contract-domain"
1714
}

aws-codeartifact-domain/pom.xml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,7 @@
2323
<dependency>
2424
<groupId>software.amazon.cloudformation</groupId>
2525
<artifactId>aws-cloudformation-rpdk-java-plugin</artifactId>
26-
<version>2.0.0</version>
26+
<version>2.0.2</version>
2727
</dependency>
2828
<!-- https://mvnrepository.com/artifact/org.projectlombok/lombok -->
2929
<dependency>

aws-codeartifact-domain/src/main/java/software/amazon/codeartifact/domain/Constants.java

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ public class Constants {
66
public static final String LIST_DOMAINS = "codeartifact:ListDomains";
77
public static final String PUT_DOMAIN_POLICY = "codeartifact:PutDomainPermissionsPolicy";
88
public static final String DELETE_DOMAIN_PERMISSION_POLICY = "codeartifact:DeleteDomainPermissionsPolicy";
9+
public static final String GET_DOMAIN_PERMISSION_POLICY = "codeartifact:GetDomainPermissionsPolicy";
910
public static final String DELETE_DOMAIN = "codeartifact:DeleteDomain";
1011
public static final String DESCRIBE_DOMAIN = "codeartifact:DescribeDomain";
1112
public static final String ACTIVE_STATUS = "Active";

aws-codeartifact-domain/src/main/java/software/amazon/codeartifact/domain/ReadHandler.java

Lines changed: 54 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -3,13 +3,16 @@
33
import software.amazon.awssdk.awscore.exception.AwsServiceException;
44
import software.amazon.awssdk.services.codeartifact.CodeartifactClient;
55
import software.amazon.awssdk.services.codeartifact.model.DescribeDomainResponse;
6+
import software.amazon.awssdk.services.codeartifact.model.GetDomainPermissionsPolicyResponse;
7+
import software.amazon.awssdk.services.codeartifact.model.ResourceNotFoundException;
68
import software.amazon.cloudformation.proxy.AmazonWebServicesClientProxy;
79
import software.amazon.cloudformation.proxy.Logger;
810
import software.amazon.cloudformation.proxy.ProgressEvent;
911
import software.amazon.cloudformation.proxy.ProxyClient;
1012
import software.amazon.cloudformation.proxy.ResourceHandlerRequest;
1113

1214
public class ReadHandler extends BaseHandlerStd {
15+
1316
private Logger logger;
1417

1518
protected ProgressEvent<ResourceModel, CallbackContext> handleRequest(
@@ -21,15 +24,58 @@ protected ProgressEvent<ResourceModel, CallbackContext> handleRequest(
2124

2225
this.logger = logger;
2326

24-
// STEP 1 [initialize a proxy context]
25-
return proxy.initiate("AWS-CodeArtifact-Domain::Read", proxyClient, request.getDesiredResourceState(), callbackContext)
27+
logger.log(String.format("%s read handler is being invoked", ResourceModel.TYPE_NAME));
28+
return ProgressEvent.progress(request.getDesiredResourceState(), callbackContext)
29+
.then(progress -> describeDomain(proxy, progress, request, proxyClient))
30+
.then(progress -> getDomainPolicy(proxy, progress, request, proxyClient))
31+
.then(progress -> {
32+
final ResourceModel model = progress.getResourceModel();
33+
return ProgressEvent.defaultSuccessHandler(model);
34+
});
35+
}
2636

27-
// STEP 2 [construct a body of a request]
28-
.translateToServiceRequest(Translator::translateToReadRequest)
29-
// STEP 3 [make an api call]
37+
private ProgressEvent<ResourceModel, CallbackContext> getDomainPolicy(
38+
AmazonWebServicesClientProxy proxy,
39+
ProgressEvent<ResourceModel, CallbackContext> progress,
40+
ResourceHandlerRequest<ResourceModel> request,
41+
ProxyClient<CodeartifactClient> proxyClient
42+
) {
43+
return proxy.initiate("AWS-CodeArtifact-Domain::GetDomainPolicy", proxyClient, progress.getResourceModel(), progress.getCallbackContext())
44+
.translateToServiceRequest(Translator::translateGetDomainPermissionsPolicyRequest)
3045
.makeServiceCall((awsRequest, client) -> {
31-
logger.log(String.format("%s read handler is being invoked", ResourceModel.TYPE_NAME));
46+
logger.log(String.format("%s getDomainPolicy is being invoked", ResourceModel.TYPE_NAME));
3247

48+
GetDomainPermissionsPolicyResponse getDomainPermissionsPolicyResponse = null;
49+
try {
50+
getDomainPermissionsPolicyResponse = client.injectCredentialsAndInvokeV2(awsRequest, proxyClient.client()::getDomainPermissionsPolicy);
51+
} catch (final ResourceNotFoundException e) {
52+
// Do nothing since there is no policy
53+
} catch (final AwsServiceException e) {
54+
String domainName = request.getDesiredResourceState().getDomainName();
55+
Translator.throwCfnException(e, Constants.GET_DOMAIN_PERMISSION_POLICY, domainName);
56+
}
57+
logger.log(String.format("Domain policy of %s has successfully been read.", ResourceModel.TYPE_NAME));
58+
return getDomainPermissionsPolicyResponse;
59+
})
60+
.done((getDomainPermissionsPolicyRequest, getDomainPermissionsPolicyResponse, proxyInvocation, resourceModel, context) -> {
61+
if (getDomainPermissionsPolicyResponse != null) {
62+
String domainPolicy = getDomainPermissionsPolicyResponse.policy().document();
63+
resourceModel.setPermissionsPolicyDocument(Translator.deserializePolicy(domainPolicy));
64+
}
65+
return ProgressEvent.progress(resourceModel, context);
66+
});
67+
}
68+
69+
private ProgressEvent<ResourceModel, CallbackContext> describeDomain(
70+
AmazonWebServicesClientProxy proxy,
71+
ProgressEvent<ResourceModel, CallbackContext> progress,
72+
ResourceHandlerRequest<ResourceModel> request,
73+
ProxyClient<CodeartifactClient> proxyClient
74+
) {
75+
return proxy.initiate("AWS-CodeArtifact-Domain::Read", proxyClient, progress.getResourceModel(), progress.getCallbackContext())
76+
.translateToServiceRequest(Translator::translateToReadRequest)
77+
.makeServiceCall((awsRequest, client) -> {
78+
logger.log(String.format("%s describeDomain is being invoked", ResourceModel.TYPE_NAME));
3379
DescribeDomainResponse awsResponse = null;
3480
try {
3581
awsResponse = client.injectCredentialsAndInvokeV2(awsRequest, proxyClient.client()::describeDomain);
@@ -40,14 +86,7 @@ protected ProgressEvent<ResourceModel, CallbackContext> handleRequest(
4086
logger.log(String.format("%s has successfully been read.", ResourceModel.TYPE_NAME));
4187
return awsResponse;
4288
})
43-
// STEP 4 [gather all properties of the resource]
44-
.done(this::constructResourceModelFromResponse);
45-
}
46-
47-
private ProgressEvent<ResourceModel, CallbackContext> constructResourceModelFromResponse(
48-
final DescribeDomainResponse awsResponse
49-
) {
50-
ResourceModel model = Translator.translateFromReadResponse(awsResponse);
51-
return ProgressEvent.defaultSuccessHandler(model);
89+
.done((describeDomainRequest, describeDomainResponse, proxyInvocation, resourceModel, context) ->
90+
ProgressEvent.progress(Translator.translateFromReadResponse(describeDomainResponse), context));
5291
}
5392
}

aws-codeartifact-domain/src/main/java/software/amazon/codeartifact/domain/Translator.java

Lines changed: 45 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,17 @@
11
package software.amazon.codeartifact.domain;
22

3+
import java.io.IOException;
34
import java.util.Collection;
5+
import java.util.HashMap;
46
import java.util.List;
7+
import java.util.Map;
58
import java.util.Optional;
69
import java.util.stream.Collectors;
710
import java.util.stream.Stream;
811

12+
import com.amazonaws.util.StringUtils;
913
import com.fasterxml.jackson.core.JsonProcessingException;
14+
import com.fasterxml.jackson.core.type.TypeReference;
1015
import com.fasterxml.jackson.databind.ObjectMapper;
1116

1217
import software.amazon.awssdk.awscore.exception.AwsServiceException;
@@ -18,6 +23,7 @@
1823
import software.amazon.awssdk.services.codeartifact.model.DescribeDomainRequest;
1924
import software.amazon.awssdk.services.codeartifact.model.DescribeDomainResponse;
2025
import software.amazon.awssdk.services.codeartifact.model.DomainDescription;
26+
import software.amazon.awssdk.services.codeartifact.model.GetDomainPermissionsPolicyRequest;
2127
import software.amazon.awssdk.services.codeartifact.model.InternalServerException;
2228
import software.amazon.awssdk.services.codeartifact.model.ListDomainsRequest;
2329
import software.amazon.awssdk.services.codeartifact.model.ListDomainsResponse;
@@ -28,6 +34,7 @@
2834
import software.amazon.cloudformation.exceptions.CfnAccessDeniedException;
2935
import software.amazon.cloudformation.exceptions.CfnAlreadyExistsException;
3036
import software.amazon.cloudformation.exceptions.CfnGeneralServiceException;
37+
import software.amazon.cloudformation.exceptions.CfnInternalFailureException;
3138
import software.amazon.cloudformation.exceptions.CfnInvalidRequestException;
3239
import software.amazon.cloudformation.exceptions.CfnNotFoundException;
3340
import software.amazon.cloudformation.exceptions.CfnServiceLimitExceededException;
@@ -77,12 +84,49 @@ static DescribeDomainRequest translateToReadRequest(final ResourceModel model) {
7784
.build();
7885
}
7986

87+
/**
88+
* Request to get permissionsPolicy of the domain resource
89+
* @param model resource model
90+
* @return awsRequest the aws service request to describe a resource
91+
*/
92+
static GetDomainPermissionsPolicyRequest translateGetDomainPermissionsPolicyRequest(final ResourceModel model) {
93+
String domainName = model.getDomainName();
94+
String domainOwner = model.getOwner();
95+
96+
if (model.getArn() != null && domainName == null && domainOwner == null) {
97+
// This is the case GetAtt or Ref is called on the resource
98+
Arn domainArn = ArnUtils.fromArn(model.getArn());
99+
100+
domainName = domainArn.shortId();
101+
domainOwner = domainArn.owner();
102+
}
103+
return GetDomainPermissionsPolicyRequest.builder()
104+
.domain(domainName)
105+
.domainOwner(domainOwner)
106+
.build();
107+
}
108+
109+
public static Map<String, Object> deserializePolicy(final String policy) {
110+
if (StringUtils.isNullOrEmpty(policy)) {
111+
return null;
112+
}
113+
114+
try {
115+
return MAPPER.readValue(policy, new TypeReference<HashMap<String,Object>>() {});
116+
} catch (final IOException e) {
117+
throw new CfnInternalFailureException(e);
118+
}
119+
}
120+
80121
/**
81122
* Translates resource object from sdk into a resource model
82123
* @param awsResponse the aws service describe resource response
83124
* @return model resource model
84125
*/
85-
static ResourceModel translateFromReadResponse(final DescribeDomainResponse awsResponse) {
126+
static ResourceModel translateFromReadResponse(
127+
final DescribeDomainResponse awsResponse
128+
) {
129+
86130
DomainDescription domain = awsResponse.domain();
87131
return ResourceModel.builder()
88132
.encryptionKey(domain.encryptionKey())

aws-codeartifact-domain/src/test/java/software/amazon/codeartifact/domain/CreateHandlerTest.java

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,9 +30,13 @@
3030
import software.amazon.awssdk.services.codeartifact.model.DescribeDomainRequest;
3131
import software.amazon.awssdk.services.codeartifact.model.DescribeDomainResponse;
3232
import software.amazon.awssdk.services.codeartifact.model.DomainDescription;
33+
import software.amazon.awssdk.services.codeartifact.model.GetDomainPermissionsPolicyRequest;
34+
import software.amazon.awssdk.services.codeartifact.model.GetDomainPermissionsPolicyResponse;
3335
import software.amazon.awssdk.services.codeartifact.model.InternalServerException;
3436
import software.amazon.awssdk.services.codeartifact.model.PutDomainPermissionsPolicyRequest;
3537
import software.amazon.awssdk.services.codeartifact.model.PutDomainPermissionsPolicyResponse;
38+
import software.amazon.awssdk.services.codeartifact.model.ResourceNotFoundException;
39+
import software.amazon.awssdk.services.codeartifact.model.ResourcePolicy;
3640
import software.amazon.awssdk.services.codeartifact.model.ServiceQuotaExceededException;
3741
import software.amazon.awssdk.services.codeartifact.model.ValidationException;
3842
import software.amazon.cloudformation.exceptions.CfnAccessDeniedException;
@@ -108,6 +112,7 @@ public void handleRequest_simpleSuccess() {
108112
.domain(domainDescription)
109113
.build();
110114

115+
when(proxyClient.client().getDomainPermissionsPolicy(any(GetDomainPermissionsPolicyRequest.class))).thenThrow(ResourceNotFoundException.class);
111116
when(proxyClient.client().describeDomain(any(DescribeDomainRequest.class))).thenReturn(describeDomainResponse);
112117

113118
final ResourceHandlerRequest<ResourceModel> request = ResourceHandlerRequest.<ResourceModel>builder()
@@ -125,6 +130,7 @@ public void handleRequest_simpleSuccess() {
125130
assertThat(response.getErrorCode()).isNull();
126131

127132
verify(codeartifactClient).createDomain(any(CreateDomainRequest.class));
133+
verify(codeartifactClient).getDomainPermissionsPolicy(any(GetDomainPermissionsPolicyRequest.class));
128134
verify(codeartifactClient, times(2)).describeDomain(any(DescribeDomainRequest.class));
129135
verify(codeartifactClient, never()).putDomainPermissionsPolicy(any(PutDomainPermissionsPolicyRequest.class));
130136

@@ -149,6 +155,7 @@ public void handleRequest_simpleSuccess_withEncryptionKey() {
149155
.domain(domainDescription)
150156
.build();
151157

158+
when(proxyClient.client().getDomainPermissionsPolicy(any(GetDomainPermissionsPolicyRequest.class))).thenThrow(ResourceNotFoundException.class);
152159
when(proxyClient.client().describeDomain(any(DescribeDomainRequest.class))).thenReturn(describeDomainResponse);
153160

154161
final ResourceHandlerRequest<ResourceModel> request = ResourceHandlerRequest.<ResourceModel>builder()
@@ -170,6 +177,7 @@ public void handleRequest_simpleSuccess_withEncryptionKey() {
170177
verify(codeartifactClient).createDomain(createDomainRequestArgumentCaptor.capture());
171178
verify(codeartifactClient, times(2)).describeDomain(any(DescribeDomainRequest.class));
172179
verify(codeartifactClient, never()).putDomainPermissionsPolicy(any(PutDomainPermissionsPolicyRequest.class));
180+
verify(codeartifactClient).getDomainPermissionsPolicy(any(GetDomainPermissionsPolicyRequest.class));
173181

174182
CreateDomainRequest createDomainRequestValue = createDomainRequestArgumentCaptor.getValue();
175183

@@ -199,6 +207,16 @@ public void handleRequest_withDomainPolicy() throws JsonProcessingException {
199207
.domain(domainDescription)
200208
.build();
201209

210+
211+
GetDomainPermissionsPolicyResponse getDomainPermissionsPolicyResponse = GetDomainPermissionsPolicyResponse.builder()
212+
.policy(
213+
ResourcePolicy.builder()
214+
.document(MAPPER.writeValueAsString(TEST_POLICY_DOC))
215+
.build()
216+
)
217+
.build();
218+
219+
when(proxyClient.client().getDomainPermissionsPolicy(any(GetDomainPermissionsPolicyRequest.class))).thenReturn(getDomainPermissionsPolicyResponse);
202220
when(proxyClient.client().describeDomain(any(DescribeDomainRequest.class))).thenReturn(describeDomainResponse);
203221

204222
final ResourceHandlerRequest<ResourceModel> request = ResourceHandlerRequest.<ResourceModel>builder()
@@ -210,6 +228,16 @@ public void handleRequest_withDomainPolicy() throws JsonProcessingException {
210228
assertThat(response).isNotNull();
211229
assertThat(response.getStatus()).isEqualTo(OperationStatus.SUCCESS);
212230
assertThat(response.getCallbackDelaySeconds()).isEqualTo(0);
231+
232+
final ResourceModel desiredOutputModel = ResourceModel.builder()
233+
.domainName(DOMAIN_NAME)
234+
.name(DOMAIN_NAME)
235+
.owner(DOMAIN_OWNER)
236+
.permissionsPolicyDocument(TEST_POLICY_DOC)
237+
.arn(DOMAIN_ARN)
238+
.encryptionKey(ENCRYPTION_KEY_ARN)
239+
.build();
240+
213241
assertThat(response.getResourceModel()).isEqualTo(desiredOutputModel);
214242
assertThat(response.getResourceModels()).isNull();
215243
assertThat(response.getMessage()).isNull();

0 commit comments

Comments
 (0)