From 556100629c6c60635e7dc1c6deded864cb0025f9 Mon Sep 17 00:00:00 2001 From: Omkar Hegde Date: Wed, 19 Aug 2020 16:44:36 -0700 Subject: [PATCH 1/6] Issue #, if available: #292 Description of changes: This change adds getPreviousResourceTags method which returns previous tags that were applied to a resource. The tags come from previousStackTags and previousResourceDefinedTags By submitting this pull request, I confirm that my contribution is made under the terms of the Apache 2.0 license. --- .../templates/generate/HandlerWrapper.java | 1 + .../amazon/cloudformation/LambdaWrapper.java | 25 ++++++++++- .../cloudformation/proxy/RequestData.java | 1 + .../proxy/ResourceHandlerRequest.java | 1 + .../cloudformation/LambdaWrapperTest.java | 43 +++++++++++++++++++ 5 files changed, 70 insertions(+), 1 deletion(-) mode change 100644 => 100755 src/test/java/software/amazon/cloudformation/LambdaWrapperTest.java diff --git a/python/rpdk/java/templates/generate/HandlerWrapper.java b/python/rpdk/java/templates/generate/HandlerWrapper.java index 3873d9ba..48821e7a 100644 --- a/python/rpdk/java/templates/generate/HandlerWrapper.java +++ b/python/rpdk/java/templates/generate/HandlerWrapper.java @@ -132,6 +132,7 @@ public Map provideResourceDefinedTags(final {{ pojo_name}} resou .desiredResourceState(requestData.getResourceProperties()) .previousResourceState(requestData.getPreviousResourceProperties()) .desiredResourceTags(getDesiredResourceTags(request)) + .previousResourceTags(getPreviousResourceTags(request)) .systemTags(request.getRequestData().getSystemTags()) .awsAccountId(request.getAwsAccountId()) .logicalResourceIdentifier(request.getRequestData().getLogicalResourceId()) diff --git a/src/main/java/software/amazon/cloudformation/LambdaWrapper.java b/src/main/java/software/amazon/cloudformation/LambdaWrapper.java index 1d6b4a23..ebddae86 100644 --- a/src/main/java/software/amazon/cloudformation/LambdaWrapper.java +++ b/src/main/java/software/amazon/cloudformation/LambdaWrapper.java @@ -502,7 +502,7 @@ protected void scrubFiles() { /** * Combines the tags supplied by the caller (e.g; CloudFormation) into a single * Map which represents the desired final set of tags to be applied to this - * resource. User-defined tags + * resource. * * @param request The request object contains the new set of tags to be applied * at a Stack level. These will be overridden with any resource-level @@ -521,6 +521,29 @@ protected Map getDesiredResourceTags(final HandlerRequest getPreviousResourceTags(final HandlerRequest request) { + Map previousResourceTags = new HashMap<>(); + + if (request != null && request.getRequestData() != null) { + replaceInMap(previousResourceTags, request.getRequestData().getPreviousStackTags()); + replaceInMap(previousResourceTags, + provideResourceDefinedTags(request.getRequestData().getPreviousResourceProperties())); + } + + return previousResourceTags; + } + private void replaceInMap(final Map targetMap, final Map sourceMap) { if (targetMap == null) { return; diff --git a/src/main/java/software/amazon/cloudformation/proxy/RequestData.java b/src/main/java/software/amazon/cloudformation/proxy/RequestData.java index d6b1cbc1..10f9bbdc 100644 --- a/src/main/java/software/amazon/cloudformation/proxy/RequestData.java +++ b/src/main/java/software/amazon/cloudformation/proxy/RequestData.java @@ -29,4 +29,5 @@ public class RequestData { private ResourceT previousResourceProperties; private Map systemTags; private Map stackTags; + private Map previousStackTags; } diff --git a/src/main/java/software/amazon/cloudformation/proxy/ResourceHandlerRequest.java b/src/main/java/software/amazon/cloudformation/proxy/ResourceHandlerRequest.java index 5cceff69..6c5b5abe 100644 --- a/src/main/java/software/amazon/cloudformation/proxy/ResourceHandlerRequest.java +++ b/src/main/java/software/amazon/cloudformation/proxy/ResourceHandlerRequest.java @@ -36,6 +36,7 @@ public class ResourceHandlerRequest { private T desiredResourceState; private T previousResourceState; private Map desiredResourceTags; + private Map previousResourceTags; private Map systemTags; private String awsAccountId; private String awsPartition; diff --git a/src/test/java/software/amazon/cloudformation/LambdaWrapperTest.java b/src/test/java/software/amazon/cloudformation/LambdaWrapperTest.java old mode 100644 new mode 100755 index 344691f3..53d53605 --- a/src/test/java/software/amazon/cloudformation/LambdaWrapperTest.java +++ b/src/test/java/software/amazon/cloudformation/LambdaWrapperTest.java @@ -956,4 +956,47 @@ public void getDesiredResourceTags_resourceTagOverridesStackTag() { assertThat(tags.size()).isEqualTo(1); assertThat(tags.get("Tag1")).isEqualTo("Value2"); } + + @Test + public void getPreviousResourceTags_oneStackTagAndOneResourceTag() { + final Map stackTags = new HashMap<>(); + stackTags.put("Tag1", "Value1"); + + final Map resourceTags = new HashMap<>(); + resourceTags.put("Tag2", "Value2"); + final TestModel model = TestModel.builder().tags(resourceTags).build(); + + final HandlerRequest request = new HandlerRequest<>(); + final RequestData requestData = new RequestData<>(); + requestData.setPreviousResourceProperties(model); + requestData.setPreviousStackTags(stackTags); + request.setRequestData(requestData); + + final Map tags = wrapper.getPreviousResourceTags(request); + assertThat(tags).isNotNull(); + assertThat(tags.size()).isEqualTo(2); + assertThat(tags.get("Tag1")).isEqualTo("Value1"); + assertThat(tags.get("Tag2")).isEqualTo("Value2"); + } + + @Test + public void getPreviousResourceTags_resourceTagOverridesStackTag() { + final Map stackTags = new HashMap<>(); + stackTags.put("Tag1", "Value1"); + + final Map resourceTags = new HashMap<>(); + resourceTags.put("Tag1", "Value2"); + final TestModel model = TestModel.builder().tags(resourceTags).build(); + + final HandlerRequest request = new HandlerRequest<>(); + final RequestData requestData = new RequestData<>(); + requestData.setPreviousResourceProperties(model); + requestData.setPreviousStackTags(stackTags); + request.setRequestData(requestData); + + final Map tags = wrapper.getPreviousResourceTags(request); + assertThat(tags).isNotNull(); + assertThat(tags.size()).isEqualTo(1); + assertThat(tags.get("Tag1")).isEqualTo("Value2"); + } } From 4b038c3eca912b79b1b64b009a34d4e473546c83 Mon Sep 17 00:00:00 2001 From: Omkar Hegde Date: Wed, 19 Aug 2020 16:52:48 -0700 Subject: [PATCH 2/6] Fix comments --- .../java/software/amazon/cloudformation/LambdaWrapper.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/main/java/software/amazon/cloudformation/LambdaWrapper.java b/src/main/java/software/amazon/cloudformation/LambdaWrapper.java index ebddae86..a6b61373 100644 --- a/src/main/java/software/amazon/cloudformation/LambdaWrapper.java +++ b/src/main/java/software/amazon/cloudformation/LambdaWrapper.java @@ -502,7 +502,7 @@ protected void scrubFiles() { /** * Combines the tags supplied by the caller (e.g; CloudFormation) into a single * Map which represents the desired final set of tags to be applied to this - * resource. + * resource. User-defined tags * * @param request The request object contains the new set of tags to be applied * at a Stack level. These will be overridden with any resource-level @@ -524,7 +524,7 @@ protected Map getDesiredResourceTags(final HandlerRequest Date: Wed, 19 Aug 2020 23:18:51 -0700 Subject: [PATCH 3/6] Add null check for getPreviousResourceProperties --- .../java/software/amazon/cloudformation/LambdaWrapper.java | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/src/main/java/software/amazon/cloudformation/LambdaWrapper.java b/src/main/java/software/amazon/cloudformation/LambdaWrapper.java index a6b61373..0428b510 100644 --- a/src/main/java/software/amazon/cloudformation/LambdaWrapper.java +++ b/src/main/java/software/amazon/cloudformation/LambdaWrapper.java @@ -537,8 +537,10 @@ protected Map getPreviousResourceTags(final HandlerRequest Date: Thu, 20 Aug 2020 09:14:20 -0700 Subject: [PATCH 4/6] Handle backward compatability --- python/rpdk/java/templates/generate/HandlerWrapper.java | 1 - src/main/java/software/amazon/cloudformation/LambdaWrapper.java | 2 ++ 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/python/rpdk/java/templates/generate/HandlerWrapper.java b/python/rpdk/java/templates/generate/HandlerWrapper.java index 48821e7a..3873d9ba 100644 --- a/python/rpdk/java/templates/generate/HandlerWrapper.java +++ b/python/rpdk/java/templates/generate/HandlerWrapper.java @@ -132,7 +132,6 @@ public Map provideResourceDefinedTags(final {{ pojo_name}} resou .desiredResourceState(requestData.getResourceProperties()) .previousResourceState(requestData.getPreviousResourceProperties()) .desiredResourceTags(getDesiredResourceTags(request)) - .previousResourceTags(getPreviousResourceTags(request)) .systemTags(request.getRequestData().getSystemTags()) .awsAccountId(request.getAwsAccountId()) .logicalResourceIdentifier(request.getRequestData().getLogicalResourceId()) diff --git a/src/main/java/software/amazon/cloudformation/LambdaWrapper.java b/src/main/java/software/amazon/cloudformation/LambdaWrapper.java index 0428b510..0a667ca6 100644 --- a/src/main/java/software/amazon/cloudformation/LambdaWrapper.java +++ b/src/main/java/software/amazon/cloudformation/LambdaWrapper.java @@ -259,6 +259,8 @@ public void handleRequest(final InputStream inputStream, final OutputStream outp // transform the request object to pass to caller ResourceHandlerRequest resourceHandlerRequest = transform(request); + resourceHandlerRequest.setPreviousResourceTags(getPreviousResourceTags(request)); + this.metricsPublisherProxy.publishInvocationMetric(Instant.now(), request.getAction()); // for CUD actions, validate incoming model - any error is a terminal failure on From 3639046a0c99c6dc1dc26667574172a2b7707c38 Mon Sep 17 00:00:00 2001 From: Omkar Hegde Date: Thu, 20 Aug 2020 13:27:04 -0700 Subject: [PATCH 5/6] Add null check --- .../java/software/amazon/cloudformation/LambdaWrapper.java | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/main/java/software/amazon/cloudformation/LambdaWrapper.java b/src/main/java/software/amazon/cloudformation/LambdaWrapper.java index 0a667ca6..c28fdb02 100644 --- a/src/main/java/software/amazon/cloudformation/LambdaWrapper.java +++ b/src/main/java/software/amazon/cloudformation/LambdaWrapper.java @@ -259,7 +259,9 @@ public void handleRequest(final InputStream inputStream, final OutputStream outp // transform the request object to pass to caller ResourceHandlerRequest resourceHandlerRequest = transform(request); - resourceHandlerRequest.setPreviousResourceTags(getPreviousResourceTags(request)); + if(resourceHandlerRequest != null) { + resourceHandlerRequest.setPreviousResourceTags(getPreviousResourceTags(request)); + } this.metricsPublisherProxy.publishInvocationMetric(Instant.now(), request.getAction()); From f714c68c2da6e28a35d795813b4d5ed3bebbcf0f Mon Sep 17 00:00:00 2001 From: Omkar Hegde Date: Thu, 20 Aug 2020 13:44:17 -0700 Subject: [PATCH 6/6] Fix indent --- .../software/amazon/cloudformation/LambdaWrapper.java | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/main/java/software/amazon/cloudformation/LambdaWrapper.java b/src/main/java/software/amazon/cloudformation/LambdaWrapper.java index c28fdb02..e810cb53 100644 --- a/src/main/java/software/amazon/cloudformation/LambdaWrapper.java +++ b/src/main/java/software/amazon/cloudformation/LambdaWrapper.java @@ -259,7 +259,7 @@ public void handleRequest(final InputStream inputStream, final OutputStream outp // transform the request object to pass to caller ResourceHandlerRequest resourceHandlerRequest = transform(request); - if(resourceHandlerRequest != null) { + if (resourceHandlerRequest != null) { resourceHandlerRequest.setPreviousResourceTags(getPreviousResourceTags(request)); } @@ -526,9 +526,9 @@ protected Map getDesiredResourceTags(final HandlerRequest