Skip to content
This repository has been archived by the owner on Jan 5, 2022. It is now read-only.

Commit

Permalink
Changed structure of organization handler return data as CloudFormati…
Browse files Browse the repository at this point in the history
…on seems to not support complex structures for custom resources.
  • Loading branch information
rafalwrzeszcz committed Mar 28, 2019
1 parent cddaf99 commit edfed31
Show file tree
Hide file tree
Showing 8 changed files with 110 additions and 81 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -103,5 +103,5 @@ object.
ServiceToken: !GetAtt "OrganizationUnitManager.Arn"
name: "internal services"
# assume Organization is a resource created by lambda-cform-organization handler
parentId: !GetAtt "Organization.Root.Id"
parentId: !GetAtt "Organization.rootId"
```
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@
import com.sunrun.cfnresponse.CfnRequest;
import pl.wrzasq.commons.aws.cloudformation.CustomResourceHandler;
import pl.wrzasq.lambda.cform.organization.model.OrganizationRequest;
import pl.wrzasq.lambda.cform.organization.model.OrganizationWithRoot;
import pl.wrzasq.lambda.cform.organization.model.OrganizationResponse;
import pl.wrzasq.lambda.cform.organization.service.OrganizationManager;

/**
Expand All @@ -26,7 +26,7 @@ public class Handler
/**
* CloudFormation response handler.
*/
private static CustomResourceHandler<OrganizationRequest, OrganizationWithRoot> handler;
private static CustomResourceHandler<OrganizationRequest, OrganizationResponse> handler;

static {
AWSOrganizations organizations = AWSOrganizationsClientBuilder.defaultClient();
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
/*
* This file is part of the pl.wrzasq.lambda.
*
* @license http://mit-license.org/ The MIT license
* @copyright 2019 © by Rafał Wrzeszcz - Wrzasq.pl.
*/

package pl.wrzasq.lambda.cform.organization.model;

import lombok.Data;

/**
* Organization data response model.
*/
@Data
public class OrganizationResponse
{
/**
* Organization ID.
*/
private String id;

/**
* Organization ARN.
*/
private String arn;

/**
* Root organizational unit ID.
*/
private String rootId;
}

This file was deleted.

Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@
import org.slf4j.LoggerFactory;
import pl.wrzasq.commons.aws.cloudformation.CustomResourceResponse;
import pl.wrzasq.lambda.cform.organization.model.OrganizationRequest;
import pl.wrzasq.lambda.cform.organization.model.OrganizationWithRoot;
import pl.wrzasq.lambda.cform.organization.model.OrganizationResponse;

/**
* Organizations API implementation.
Expand Down Expand Up @@ -59,7 +59,7 @@ public OrganizationManager(AWSOrganizations organizations)
* @param physicalResourceId Physical ID of existing resource (if present).
* @return Data about published version.
*/
public CustomResourceResponse<OrganizationWithRoot> sync(OrganizationRequest input, String physicalResourceId)
public CustomResourceResponse<OrganizationResponse> sync(OrganizationRequest input, String physicalResourceId)
{
Organization organization;
try {
Expand Down Expand Up @@ -94,7 +94,12 @@ public CustomResourceResponse<OrganizationWithRoot> sync(OrganizationRequest inp

Root root = this.organizations.listRoots(new ListRootsRequest()).getRoots().get(0);

return new CustomResourceResponse<>(new OrganizationWithRoot(organization, root), organization.getId());
OrganizationResponse organizationResponse = new OrganizationResponse();
organizationResponse.setId(organization.getId());
organizationResponse.setArn(organization.getArn());
organizationResponse.setRootId(root.getId());

return new CustomResourceResponse<>(organizationResponse, organization.getId());
}

/**
Expand All @@ -104,7 +109,7 @@ public CustomResourceResponse<OrganizationWithRoot> sync(OrganizationRequest inp
* @param physicalResourceId Physical ID of existing resource (if present).
* @return Empty response.
*/
public CustomResourceResponse<OrganizationWithRoot> delete(OrganizationRequest input, String physicalResourceId)
public CustomResourceResponse<OrganizationResponse> delete(OrganizationRequest input, String physicalResourceId)
{
Organization organization = this.organizations.describeOrganization(
new DescribeOrganizationRequest()
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -35,21 +35,19 @@ Specifies set of features enabled for accounts in organization. Can be either `C

# Output values

Deploy handler exposes structure with two elements:
Deploy handler exposes following data structure:

```json
{
"organization": object,
"root": object
"id": string,
"arn": string,
"rootId": stirng
}
```

- `organization`: entire
[Organization](https://docs.aws.amazon.com/AWSJavaSDK/latest/javadoc/com/amazonaws/services/iam/model/Organization.html)
object;
- `root`: entire
[Root](https://docs.aws.amazon.com/AWSJavaSDK/latest/javadoc/com/amazonaws/services/organizations/model/Root.html)
object.
- `id`: organization ID;
- `arn`: organization ARN;
- `rootId`: root organizational unit ID.

**Note:** Custom resource physical ID is set as created organization ID.

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,18 +21,18 @@
import pl.wrzasq.commons.aws.cloudformation.CustomResourceHandler;
import pl.wrzasq.lambda.cform.organization.Handler;
import pl.wrzasq.lambda.cform.organization.model.OrganizationRequest;
import pl.wrzasq.lambda.cform.organization.model.OrganizationWithRoot;
import pl.wrzasq.lambda.cform.organization.model.OrganizationResponse;

@ExtendWith(MockitoExtension.class)
public class HandlerTest
{
@Mock
private CustomResourceHandler<OrganizationRequest, OrganizationWithRoot> handler;
private CustomResourceHandler<OrganizationRequest, OrganizationResponse> handler;

@Mock
private Context context;

private CustomResourceHandler<OrganizationRequest, OrganizationWithRoot> originalHandler;
private CustomResourceHandler<OrganizationRequest, OrganizationResponse> originalHandler;

@BeforeEach
public void setUp() throws NoSuchFieldException, IllegalAccessException
Expand All @@ -58,14 +58,14 @@ public void handle()
Mockito.verify(this.handler).handle(request, this.context);
}

private CustomResourceHandler<OrganizationRequest, OrganizationWithRoot> setHandler(
CustomResourceHandler<OrganizationRequest, OrganizationWithRoot> sender
private CustomResourceHandler<OrganizationRequest, OrganizationResponse> setHandler(
CustomResourceHandler<OrganizationRequest, OrganizationResponse> sender
)
throws NoSuchFieldException, IllegalAccessException
{
Field hack = Handler.class.getDeclaredField("handler");
hack.setAccessible(true);
CustomResourceHandler<OrganizationRequest, OrganizationWithRoot> original
CustomResourceHandler<OrganizationRequest, OrganizationResponse> original
= CustomResourceHandler.class.cast(hack.get(null));
hack.set(null, sender);
return original;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@
import org.mockito.junit.jupiter.MockitoExtension;
import pl.wrzasq.commons.aws.cloudformation.CustomResourceResponse;
import pl.wrzasq.lambda.cform.organization.model.OrganizationRequest;
import pl.wrzasq.lambda.cform.organization.model.OrganizationWithRoot;
import pl.wrzasq.lambda.cform.organization.model.OrganizationResponse;
import pl.wrzasq.lambda.cform.organization.service.OrganizationManager;

@ExtendWith(MockitoExtension.class)
Expand All @@ -41,6 +41,10 @@ public class OrganizationManagerTest

private static final String PHYSICAL_ID_2 = "o-another";

private static final String ARN = "arn:aws:test";

private static final String ROOT_ID = "r-root";

@Mock
private AWSOrganizations organizations;

Expand All @@ -51,8 +55,10 @@ public class OrganizationManagerTest
public void sync()
{
Organization organization = new Organization()
.withId(OrganizationManagerTest.PHYSICAL_ID_1);
Root root = new Root();
.withId(OrganizationManagerTest.PHYSICAL_ID_1)
.withArn(OrganizationManagerTest.ARN);
Root root = new Root()
.withId(OrganizationManagerTest.ROOT_ID);

OrganizationManager manager = new OrganizationManager(this.organizations);

Expand All @@ -75,7 +81,7 @@ public void sync()
.withRoots(root)
);

CustomResourceResponse<OrganizationWithRoot> result = manager.sync(input, null);
CustomResourceResponse<OrganizationResponse> result = manager.sync(input, null);

Mockito.verify(this.organizations).describeOrganization(Mockito.any(DescribeOrganizationRequest.class));
Mockito.verify(this.organizations).createOrganization(Mockito.any(CreateOrganizationRequest.class));
Expand All @@ -85,15 +91,20 @@ public void sync()
this.createRequest.getValue().getFeatureSet(),
"OrganizationManager.sync() should pass specified feature set for created organization."
);
Assertions.assertEquals(
OrganizationManagerTest.PHYSICAL_ID_1,
result.getData().getId(),
"OrganizationManager.sync() should return ID of created organization."
);
Assertions.assertSame(
organization,
result.getData().getOrganization(),
"OrganizationManager.sync() should return organization data of created organization."
OrganizationManagerTest.ARN,
result.getData().getArn(),
"OrganizationManager.sync() should return ARN of created organization."
);
Assertions.assertSame(
root,
result.getData().getRoot(),
"OrganizationManager.sync() should return organization root of created organization."
OrganizationManagerTest.ROOT_ID,
result.getData().getRootId(),
"OrganizationManager.sync() should return ID of created organization root unit."
);
Assertions.assertEquals(
OrganizationManagerTest.PHYSICAL_ID_1,
Expand All @@ -106,8 +117,10 @@ public void sync()
public void syncAlreadyExists()
{
Organization organization = new Organization()
.withId(OrganizationManagerTest.PHYSICAL_ID_1);
Root root = new Root();
.withId(OrganizationManagerTest.PHYSICAL_ID_1)
.withArn(OrganizationManagerTest.ARN);
Root root = new Root()
.withId(OrganizationManagerTest.ROOT_ID);

OrganizationManager manager = new OrganizationManager(this.organizations);

Expand All @@ -126,23 +139,28 @@ public void syncAlreadyExists()
.withRoots(root)
);

CustomResourceResponse<OrganizationWithRoot> result = manager.sync(
CustomResourceResponse<OrganizationResponse> result = manager.sync(
input,
OrganizationManagerTest.PHYSICAL_ID_1
);

Mockito.verify(this.organizations).describeOrganization(Mockito.any(DescribeOrganizationRequest.class));
Mockito.verify(this.organizations, Mockito.never()).createOrganization(Mockito.any());

Assertions.assertEquals(
OrganizationManagerTest.PHYSICAL_ID_1,
result.getData().getId(),
"OrganizationManager.sync() should return ID of existing organization."
);
Assertions.assertSame(
organization,
result.getData().getOrganization(),
"OrganizationManager.sync() should return organization data of existing organization."
OrganizationManagerTest.ARN,
result.getData().getArn(),
"OrganizationManager.sync() should return ARN of existing organization."
);
Assertions.assertSame(
root,
result.getData().getRoot(),
"OrganizationManager.sync() should return organization root of existing organization."
OrganizationManagerTest.ROOT_ID,
result.getData().getRootId(),
"OrganizationManager.sync() should return ID of existing organization root unit."
);
Assertions.assertEquals(
OrganizationManagerTest.PHYSICAL_ID_1,
Expand All @@ -155,8 +173,10 @@ public void syncAlreadyExists()
public void syncAlreadyExistsOutOfSync()
{
Organization organization = new Organization()
.withId(OrganizationManagerTest.PHYSICAL_ID_1);
Root root = new Root();
.withId(OrganizationManagerTest.PHYSICAL_ID_1)
.withArn(OrganizationManagerTest.ARN);
Root root = new Root()
.withId(OrganizationManagerTest.ROOT_ID);

OrganizationManager manager = new OrganizationManager(this.organizations);

Expand All @@ -175,23 +195,28 @@ public void syncAlreadyExistsOutOfSync()
.withRoots(root)
);

CustomResourceResponse<OrganizationWithRoot> result = manager.sync(
CustomResourceResponse<OrganizationResponse> result = manager.sync(
input,
OrganizationManagerTest.PHYSICAL_ID_2
);

Mockito.verify(this.organizations).describeOrganization(Mockito.any(DescribeOrganizationRequest.class));
Mockito.verify(this.organizations, Mockito.never()).createOrganization(Mockito.any());

Assertions.assertEquals(
OrganizationManagerTest.PHYSICAL_ID_1,
result.getData().getId(),
"OrganizationManager.sync() should return ID of existing organization."
);
Assertions.assertSame(
organization,
result.getData().getOrganization(),
"OrganizationManager.sync() should return organization data of existing organization."
OrganizationManagerTest.ARN,
result.getData().getArn(),
"OrganizationManager.sync() should return ARN of existing organization."
);
Assertions.assertSame(
root,
result.getData().getRoot(),
"OrganizationManager.sync() should return organization root of existing organization."
OrganizationManagerTest.ROOT_ID,
result.getData().getRootId(),
"OrganizationManager.sync() should return ID of existing organization root unit."
);
Assertions.assertEquals(
OrganizationManagerTest.PHYSICAL_ID_1,
Expand Down

0 comments on commit edfed31

Please sign in to comment.