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

Commit 9450f2b

Browse files
authored
Pre-setting primaryResourceIdentifier. (#46)
* Pre-setting primaryResourceIdentifier. * Removing silly log statement. * Adding unit test.
1 parent ccae423 commit 9450f2b

File tree

5 files changed

+137
-9
lines changed

5 files changed

+137
-9
lines changed

aws-codeartifact-repository/src/main/java/software/amazon/codeartifact/repository/ArnUtils.java

Lines changed: 16 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,8 @@
11
package software.amazon.codeartifact.repository;
22

33
public class ArnUtils {
4-
4+
public static final String SERVICE_NAME = "codeartifact";
5+
public static final String REPO_RESOURCE_TYPE = "repository";
56
public static RepositoryArn fromArn(String arn) {
67

78
// TODO (jonjara) move ArnUtils to a common module
@@ -31,4 +32,18 @@ public static RepositoryArn fromArn(String arn) {
3132
.build();
3233
}
3334

35+
public static RepositoryArn repoArn(
36+
String partition, String region, String domainOwner, String domainName, String repoName
37+
) {
38+
return RepositoryArn.builder()
39+
.partition(partition)
40+
.region(region)
41+
.service(SERVICE_NAME)
42+
.owner(domainOwner)
43+
.type(REPO_RESOURCE_TYPE)
44+
.domainName(domainName)
45+
.repoName(repoName)
46+
.build();
47+
}
48+
3449
}

aws-codeartifact-repository/src/main/java/software/amazon/codeartifact/repository/BaseHandlerStd.java

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,8 @@
33
import java.util.Set;
44

55
import com.amazonaws.util.CollectionUtils;
6+
import com.fasterxml.jackson.databind.JsonNode;
7+
import com.fasterxml.jackson.databind.ObjectMapper;
68

79
import software.amazon.awssdk.awscore.exception.AwsServiceException;
810
import software.amazon.awssdk.services.codeartifact.CodeartifactClient;
@@ -15,9 +17,6 @@
1517
import software.amazon.cloudformation.proxy.ProxyClient;
1618
import software.amazon.cloudformation.proxy.ResourceHandlerRequest;
1719

18-
import com.fasterxml.jackson.databind.JsonNode;
19-
import com.fasterxml.jackson.databind.ObjectMapper;
20-
2120
public abstract class BaseHandlerStd extends BaseHandler<CallbackContext> {
2221
public static final ObjectMapper MAPPER = new ObjectMapper();
2322

aws-codeartifact-repository/src/main/java/software/amazon/codeartifact/repository/CreateHandler.java

Lines changed: 18 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,6 @@
44
import software.amazon.awssdk.awscore.AwsResponse;
55
import software.amazon.awssdk.awscore.exception.AwsServiceException;
66
import software.amazon.awssdk.services.codeartifact.CodeartifactClient;
7-
import software.amazon.awssdk.services.codeartifact.model.DescribeRepositoryResponse;
87
import software.amazon.awssdk.services.codeartifact.model.ResourceNotFoundException;
98
import software.amazon.cloudformation.exceptions.CfnInvalidRequestException;
109
import software.amazon.cloudformation.proxy.AmazonWebServicesClientProxy;
@@ -33,13 +32,30 @@ protected ProgressEvent<ResourceModel, CallbackContext> handleRequest(
3332
throw new CfnInvalidRequestException("Attempting to set a ReadOnly Property.");
3433
}
3534

35+
// Setting primaryId first in case rollback occurs, we need the Id to be able to rollback
36+
setPrimaryIdentifier(request, model);
37+
3638
return ProgressEvent.progress(request.getDesiredResourceState(), callbackContext)
3739
.then(progress -> createRepository(proxy, progress, proxyClient))
3840
.then(progress -> putRepositoryPermissionsPolicy(proxy, progress, callbackContext, request, proxyClient, logger))
3941
.then(progress -> associateExternalConnections(progress, callbackContext, request, proxyClient, externalConnectionsToAdd, logger))
4042
.then(progress -> new ReadHandler().handleRequest(proxy, request, callbackContext, proxyClient, logger));
4143
}
4244

45+
private void setPrimaryIdentifier(ResourceHandlerRequest<ResourceModel> request, ResourceModel model) {
46+
String domainOwner = model.getDomainOwner() == null ? request.getAwsAccountId() : model.getDomainOwner();
47+
48+
RepositoryArn repoArn = ArnUtils.repoArn(
49+
request.getAwsPartition(),
50+
request.getRegion(),
51+
domainOwner,
52+
model.getDomainName(),
53+
model.getRepositoryName()
54+
);
55+
56+
model.setArn(repoArn.arn());
57+
}
58+
4359
private ProgressEvent<ResourceModel, CallbackContext> createRepository(
4460
AmazonWebServicesClientProxy proxy,
4561
ProgressEvent<ResourceModel, CallbackContext> progress,
@@ -71,9 +87,8 @@ private boolean isStabilized(
7187
final ProxyClient<CodeartifactClient> proxyClient
7288
) {
7389
try {
74-
DescribeRepositoryResponse response = proxyClient.injectCredentialsAndInvokeV2(
90+
proxyClient.injectCredentialsAndInvokeV2(
7591
Translator.translateToReadRequest(model), proxyClient.client()::describeRepository);
76-
model.setArn(response.repository().arn());
7792
return true;
7893
} catch (ResourceNotFoundException e) {
7994
return false;

aws-codeartifact-repository/src/test/java/software/amazon/codeartifact/repository/AbstractTestBase.java

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -27,11 +27,13 @@
2727
public class AbstractTestBase {
2828
public static final ObjectMapper MAPPER = new ObjectMapper();
2929
protected static final String DOMAIN_NAME = "test-domain-name";
30+
protected static final String PARTITION = "aws";
31+
protected static final String REGION = "us-west-2";
3032
protected static final String DOMAIN_OWNER = "12345";
3133
protected static final String ADMIN_ACCOUNT = "54321";
3234
protected static final String REPO_NAME = "test-repo-name";
33-
protected static final String REPO_ARN = String.format("arn:aws:codeartifact:region:%s:repository/%s/%s",
34-
DOMAIN_OWNER, DOMAIN_NAME, REPO_NAME);
35+
protected static final String REPO_ARN = String.format("arn:aws:codeartifact:%s:%s:repository/%s/%s",
36+
REGION, DOMAIN_OWNER, DOMAIN_NAME, REPO_NAME);
3537
protected static final Map<String, Object> TEST_POLICY_DOC_0 = Collections.singletonMap("key0", "value0");
3638
protected static final Map<String, Object> TEST_POLICY_DOC_1 = Collections.singletonMap("key1", "value1");
3739

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

Lines changed: 97 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -100,6 +100,9 @@ public void handleRequest_SimpleSuccess() {
100100

101101
final ResourceHandlerRequest<ResourceModel> request = ResourceHandlerRequest.<ResourceModel>builder()
102102
.desiredResourceState(model)
103+
.region(REGION)
104+
.awsPartition(PARTITION)
105+
.awsAccountId(DOMAIN_OWNER)
103106
.build();
104107

105108
final RepositoryDescription repositoryDescription = RepositoryDescription.builder()
@@ -132,6 +135,64 @@ public void handleRequest_SimpleSuccess() {
132135
verify(codeartifactClient, atLeastOnce()).serviceName();
133136
}
134137

138+
@Test
139+
public void handleRequest_SimpleSuccess_withoutDomainOwner() {
140+
final CreateHandler handler = new CreateHandler();
141+
142+
final ResourceModel model = ResourceModel.builder()
143+
.domainName(DOMAIN_NAME)
144+
.repositoryName(REPO_NAME)
145+
.description(DESCRIPTION)
146+
.build();
147+
148+
final ResourceModel desiredOutputModel = ResourceModel.builder()
149+
.domainName(DOMAIN_NAME)
150+
.domainOwner(DOMAIN_OWNER)
151+
.name(REPO_NAME)
152+
.repositoryName(REPO_NAME)
153+
.arn(REPO_ARN)
154+
.description(DESCRIPTION)
155+
.administratorAccount(ADMIN_ACCOUNT)
156+
.build();
157+
158+
final ResourceHandlerRequest<ResourceModel> request = ResourceHandlerRequest.<ResourceModel>builder()
159+
.desiredResourceState(model)
160+
.region(REGION)
161+
.awsPartition(PARTITION)
162+
.awsAccountId(DOMAIN_OWNER)
163+
.build();
164+
165+
final RepositoryDescription repositoryDescription = RepositoryDescription.builder()
166+
.name(REPO_NAME)
167+
.administratorAccount(ADMIN_ACCOUNT)
168+
.arn(REPO_ARN)
169+
.description(DESCRIPTION)
170+
.domainOwner(DOMAIN_OWNER)
171+
.domainName(DOMAIN_NAME)
172+
.build();
173+
174+
CreateRepositoryResponse createRepositoryResponse = CreateRepositoryResponse.builder()
175+
.repository(repositoryDescription)
176+
.build();
177+
178+
when(proxyClient.client().createRepository(any(CreateRepositoryRequest.class))).thenReturn(createRepositoryResponse);
179+
180+
DescribeRepositoryResponse describeRepositoryResponse = DescribeRepositoryResponse.builder()
181+
.repository(repositoryDescription)
182+
.build();
183+
184+
when(proxyClient.client().describeRepository(any(DescribeRepositoryRequest.class))).thenReturn(describeRepositoryResponse);
185+
186+
final ProgressEvent<ResourceModel, CallbackContext> response = handler.handleRequest(proxy, request, new CallbackContext(), proxyClient, logger);
187+
188+
assertSuccess(response, desiredOutputModel);
189+
190+
verify(codeartifactClient).createRepository(any(CreateRepositoryRequest.class));
191+
verify(codeartifactClient, times(2)).describeRepository(any(DescribeRepositoryRequest.class));
192+
verify(codeartifactClient, atLeastOnce()).serviceName();
193+
}
194+
195+
135196
@Test
136197
public void handleRequest_withUpstreams() {
137198
final CreateHandler handler = new CreateHandler();
@@ -170,6 +231,9 @@ public void handleRequest_withUpstreams() {
170231

171232
final ResourceHandlerRequest<ResourceModel> request = ResourceHandlerRequest.<ResourceModel>builder()
172233
.desiredResourceState(model)
234+
.region(REGION)
235+
.awsPartition(PARTITION)
236+
.awsAccountId(DOMAIN_OWNER)
173237
.build();
174238

175239
CreateRepositoryResponse createRepositoryResponse = CreateRepositoryResponse.builder()
@@ -227,6 +291,9 @@ public void handleRequest_withRepoPolicy() throws JsonProcessingException {
227291

228292
final ResourceHandlerRequest<ResourceModel> request = ResourceHandlerRequest.<ResourceModel>builder()
229293
.desiredResourceState(model)
294+
.region(REGION)
295+
.awsPartition(PARTITION)
296+
.awsAccountId(DOMAIN_OWNER)
230297
.build();
231298

232299
CreateRepositoryResponse createRepositoryResponse = CreateRepositoryResponse.builder()
@@ -295,6 +362,9 @@ public void handleRequest_withExternalConnections_happycase() {
295362

296363
final ResourceHandlerRequest<ResourceModel> request = ResourceHandlerRequest.<ResourceModel>builder()
297364
.desiredResourceState(model)
365+
.region(REGION)
366+
.awsPartition(PARTITION)
367+
.awsAccountId(DOMAIN_OWNER)
298368
.build();
299369

300370
CreateRepositoryResponse createRepositoryResponse = CreateRepositoryResponse.builder()
@@ -342,6 +412,9 @@ public void handleRequest_withExternalConnections_moreThanOneExternalConnection(
342412

343413
final ResourceHandlerRequest<ResourceModel> request = ResourceHandlerRequest.<ResourceModel>builder()
344414
.desiredResourceState(model)
415+
.region(REGION)
416+
.awsPartition(PARTITION)
417+
.awsAccountId(DOMAIN_OWNER)
345418
.build();
346419

347420
CreateRepositoryResponse createRepositoryResponse = CreateRepositoryResponse.builder()
@@ -383,6 +456,9 @@ public void handleRequest_conflictException() {
383456

384457
final ResourceHandlerRequest<ResourceModel> request = ResourceHandlerRequest.<ResourceModel>builder()
385458
.desiredResourceState(model)
459+
.region(REGION)
460+
.awsPartition(PARTITION)
461+
.awsAccountId(DOMAIN_OWNER)
386462
.build();
387463

388464
assertThrows(CfnAlreadyExistsException.class, () -> handler.handleRequest(proxy, request, new CallbackContext(), proxyClient, logger));
@@ -408,6 +484,9 @@ public void handleRequest_serviceQuotaExceededException() {
408484

409485
final ResourceHandlerRequest<ResourceModel> request = ResourceHandlerRequest.<ResourceModel>builder()
410486
.desiredResourceState(model)
487+
.region(REGION)
488+
.awsPartition(PARTITION)
489+
.awsAccountId(DOMAIN_OWNER)
411490
.build();
412491

413492
assertThrows(CfnServiceLimitExceededException.class, () -> handler.handleRequest(proxy, request, new CallbackContext(), proxyClient, logger));
@@ -432,6 +511,9 @@ public void handleRequest_validationException() {
432511

433512
final ResourceHandlerRequest<ResourceModel> request = ResourceHandlerRequest.<ResourceModel>builder()
434513
.desiredResourceState(model)
514+
.region(REGION)
515+
.awsPartition(PARTITION)
516+
.awsAccountId(DOMAIN_OWNER)
435517
.build();
436518

437519
assertThrows(CfnInvalidRequestException.class, () -> handler.handleRequest(proxy, request, new CallbackContext(), proxyClient, logger));
@@ -457,6 +539,9 @@ public void handleRequest_internalServerException() {
457539

458540
final ResourceHandlerRequest<ResourceModel> request = ResourceHandlerRequest.<ResourceModel>builder()
459541
.desiredResourceState(model)
542+
.region(REGION)
543+
.awsPartition(PARTITION)
544+
.awsAccountId(DOMAIN_OWNER)
460545
.build();
461546

462547
assertThrows(CfnServiceInternalErrorException.class, () -> handler.handleRequest(proxy, request, new CallbackContext(), proxyClient, logger));
@@ -481,6 +566,9 @@ public void handleRequest_accessDeniedException() {
481566

482567
final ResourceHandlerRequest<ResourceModel> request = ResourceHandlerRequest.<ResourceModel>builder()
483568
.desiredResourceState(model)
569+
.region(REGION)
570+
.awsPartition(PARTITION)
571+
.awsAccountId(DOMAIN_OWNER)
484572
.build();
485573

486574
assertThrows(CfnAccessDeniedException.class, () -> handler.handleRequest(proxy, request, new CallbackContext(), proxyClient, logger));
@@ -505,6 +593,9 @@ public void handleRequest_notFoundException() {
505593

506594
final ResourceHandlerRequest<ResourceModel> request = ResourceHandlerRequest.<ResourceModel>builder()
507595
.desiredResourceState(model)
596+
.region(REGION)
597+
.awsPartition(PARTITION)
598+
.awsAccountId(DOMAIN_OWNER)
508599
.build();
509600

510601
assertThrows(CfnNotFoundException.class, () -> handler.handleRequest(proxy, request, new CallbackContext(), proxyClient, logger));
@@ -529,6 +620,9 @@ public void handleRequest_generalException() {
529620

530621
final ResourceHandlerRequest<ResourceModel> request = ResourceHandlerRequest.<ResourceModel>builder()
531622
.desiredResourceState(model)
623+
.region(REGION)
624+
.awsPartition(PARTITION)
625+
.awsAccountId(DOMAIN_OWNER)
532626
.build();
533627

534628
assertThrows(CfnGeneralServiceException.class, () -> handler.handleRequest(proxy, request, new CallbackContext(), proxyClient, logger));
@@ -550,6 +644,9 @@ public void handleRequest_invalidRequest_readOnlyProperties() {
550644

551645
final ResourceHandlerRequest<ResourceModel> request = ResourceHandlerRequest.<ResourceModel>builder()
552646
.desiredResourceState(model)
647+
.region(REGION)
648+
.awsPartition(PARTITION)
649+
.awsAccountId(DOMAIN_OWNER)
553650
.build();
554651

555652
assertThrows(CfnInvalidRequestException.class, () -> handler.handleRequest(proxy, request, new CallbackContext(), proxyClient, logger));

0 commit comments

Comments
 (0)