From c26541cc2e4a6f02520ddb1488c648ecf6869b66 Mon Sep 17 00:00:00 2001 From: Keynan Pratt Date: Tue, 5 Nov 2024 06:46:04 +0000 Subject: [PATCH] Factoring out describe calls and reducing the over engineered api version selection behavior. Note the V12 API code paths are marked for removal. --- .../client/ApiVersionDispatcher.java | 2 + .../amazon/rds/dbinstance/common/Fetch.java | 32 ++++ .../common/create/FreshInstance.java | 159 ++++++++---------- .../common/create/FromSnapshot.java | 66 ++------ 4 files changed, 119 insertions(+), 140 deletions(-) create mode 100644 aws-rds-dbinstance/src/main/java/software/amazon/rds/dbinstance/common/Fetch.java diff --git a/aws-rds-dbinstance/src/main/java/software/amazon/rds/dbinstance/client/ApiVersionDispatcher.java b/aws-rds-dbinstance/src/main/java/software/amazon/rds/dbinstance/client/ApiVersionDispatcher.java index 8f567b7ac..87a9616e3 100644 --- a/aws-rds-dbinstance/src/main/java/software/amazon/rds/dbinstance/client/ApiVersionDispatcher.java +++ b/aws-rds-dbinstance/src/main/java/software/amazon/rds/dbinstance/client/ApiVersionDispatcher.java @@ -1,5 +1,6 @@ package software.amazon.rds.dbinstance.client; +import javax.annotation.Nonnull; import java.util.Comparator; import java.util.Map; import java.util.TreeMap; @@ -24,6 +25,7 @@ public ApiVersionDispatcher register(final ApiVersion version, final BiPre * @param context An instance of Context. * @return Returns the highest {@code ApiVersion} matching the input model and context. If no matchers triggered, DEFAULT version is returned (hence no need to register a match-all tester for DEFAULT version). */ + @Nonnull public ApiVersion dispatch(final M model, final C context) { for (final Map.Entry> entry : versionTesters.entrySet()) { if (entry.getValue().test(model, context)) { diff --git a/aws-rds-dbinstance/src/main/java/software/amazon/rds/dbinstance/common/Fetch.java b/aws-rds-dbinstance/src/main/java/software/amazon/rds/dbinstance/common/Fetch.java new file mode 100644 index 000000000..d477b2433 --- /dev/null +++ b/aws-rds-dbinstance/src/main/java/software/amazon/rds/dbinstance/common/Fetch.java @@ -0,0 +1,32 @@ +package software.amazon.rds.dbinstance.common; + +import lombok.AllArgsConstructor; +import software.amazon.awssdk.services.rds.RdsClient; +import software.amazon.awssdk.services.rds.model.DBInstance; +import software.amazon.awssdk.services.rds.model.DBSnapshot; +import software.amazon.awssdk.services.rds.model.DescribeDbInstancesResponse; +import software.amazon.awssdk.services.rds.model.DescribeDbSnapshotsResponse; +import software.amazon.cloudformation.proxy.ProxyClient; +import software.amazon.rds.dbinstance.ResourceModel; +import software.amazon.rds.dbinstance.Translator; + +@AllArgsConstructor +public class Fetch { + private final ProxyClient rdsProxyClient; + + public DBInstance dbInstance(final ResourceModel model) { + final DescribeDbInstancesResponse response = rdsProxyClient.injectCredentialsAndInvokeV2( + Translator.describeDbInstancesRequest(model), + rdsProxyClient.client()::describeDBInstances + ); + return response.dbInstances().get(0); + } + + public DBSnapshot dbSnapshot(final ResourceModel model) { + final DescribeDbSnapshotsResponse response = rdsProxyClient.injectCredentialsAndInvokeV2( + Translator.describeDbSnapshotsRequest(model), + rdsProxyClient.client()::describeDBSnapshots + ); + return response.dbSnapshots().get(0); + } +} diff --git a/aws-rds-dbinstance/src/main/java/software/amazon/rds/dbinstance/common/create/FreshInstance.java b/aws-rds-dbinstance/src/main/java/software/amazon/rds/dbinstance/common/create/FreshInstance.java index 659a88774..51d76f1a6 100644 --- a/aws-rds-dbinstance/src/main/java/software/amazon/rds/dbinstance/common/create/FreshInstance.java +++ b/aws-rds-dbinstance/src/main/java/software/amazon/rds/dbinstance/common/create/FreshInstance.java @@ -3,8 +3,6 @@ import lombok.AllArgsConstructor; import software.amazon.awssdk.services.rds.RdsClient; import software.amazon.awssdk.services.rds.model.DBInstance; -import software.amazon.awssdk.services.rds.model.DescribeDbInstancesResponse; -import software.amazon.awssdk.utils.ImmutableMap; import software.amazon.cloudformation.proxy.AmazonWebServicesClientProxy; import software.amazon.cloudformation.proxy.ProgressEvent; import software.amazon.cloudformation.proxy.ProxyClient; @@ -21,8 +19,7 @@ import software.amazon.rds.dbinstance.client.ApiVersionDispatcher; import software.amazon.rds.dbinstance.client.VersionedProxyClient; import software.amazon.rds.dbinstance.common.Errors; - -import java.util.Map; +import software.amazon.rds.dbinstance.common.Fetch; @AllArgsConstructor public class FreshInstance implements DBInstanceFactory { @@ -35,111 +32,89 @@ public class FreshInstance implements DBInstanceFactory { private final ApiVersionDispatcher apiVersionDispatcher; public ProgressEvent create(ProgressEvent progress) { - return versioned(proxy, rdsProxyClient, progress, allTags, ImmutableMap.of( - ApiVersion.V12, this::createDbInstanceV12, - ApiVersion.DEFAULT, safeAddTags(this::createDbInstance) - )); + final ResourceModel model = progress.getResourceModel(); + final CallbackContext callbackContext = progress.getCallbackContext(); + final ApiVersion apiVersion = selectVersion(model, callbackContext); + + if (apiVersion == ApiVersion.V12) { + return createDbInstanceV12(proxy, rdsProxyClient.forVersion(apiVersion), progress, allTags); + } + + return safeAddTags(this::createDbInstance).invoke(proxy, rdsProxyClient.forVersion(apiVersion), progress, allTags); } private ProgressEvent createDbInstance( - final AmazonWebServicesClientProxy proxy, - final ProxyClient rdsProxyClient, - final ProgressEvent progress, - final Tagging.TagSet tagSet + final AmazonWebServicesClientProxy proxy, + final ProxyClient rdsProxyClient, + final ProgressEvent progress, + final Tagging.TagSet tagSet ) { + final Fetch fetch = new Fetch(rdsProxyClient); return proxy.initiate( - "rds::create-db-instance", - rdsProxyClient, - progress.getResourceModel(), - progress.getCallbackContext() - ).translateToServiceRequest(model -> Translator.createDbInstanceRequest(model, tagSet)) - .backoffDelay(config.getBackoff()) - .makeServiceCall((createRequest, proxyInvocation) -> proxyInvocation.injectCredentialsAndInvokeV2( - createRequest, - proxyInvocation.client()::createDBInstance - )) - .stabilize((request, response, proxyInvocation, model, context) -> - { - final DBInstance dbInstance = fetchDBInstance(rdsProxyClient, model); - return DBInstancePredicates.isDBInstanceStabilizedAfterMutate(dbInstance, model, context, requestLogger) ; - }) - .handleError((request, exception, client, model, context) -> Commons.handleException( - ProgressEvent.progress(model, context), - exception, - Errors.CREATE_DB_INSTANCE_ERROR_RULE_SET, - requestLogger - )) - .progress(); - } - - private DBInstance fetchDBInstance( - final ProxyClient rdsProxyClient, - final ResourceModel model - ) { - final DescribeDbInstancesResponse response = rdsProxyClient.injectCredentialsAndInvokeV2( - Translator.describeDbInstancesRequest(model), - rdsProxyClient.client()::describeDBInstances - ); - return response.dbInstances().get(0); + "rds::create-db-instance", + rdsProxyClient, + progress.getResourceModel(), + progress.getCallbackContext() + ).translateToServiceRequest(model -> Translator.createDbInstanceRequest(model, tagSet)) + .backoffDelay(config.getBackoff()) + .makeServiceCall((createRequest, proxyInvocation) -> proxyInvocation.injectCredentialsAndInvokeV2( + createRequest, + proxyInvocation.client()::createDBInstance + )) + .stabilize((request, response, proxyInvocation, model, context) -> + { + final DBInstance dbInstance = fetch.dbInstance(model); + return DBInstancePredicates.isDBInstanceStabilizedAfterMutate(dbInstance, model, context, requestLogger); + }) + .handleError((request, exception, client, model, context) -> Commons.handleException( + ProgressEvent.progress(model, context), + exception, + Errors.CREATE_DB_INSTANCE_ERROR_RULE_SET, + requestLogger + )) + .progress(); } private ProgressEvent createDbInstanceV12( - final AmazonWebServicesClientProxy proxy, - final ProxyClient rdsProxyClient, - final ProgressEvent progress, - final Tagging.TagSet tagSet + final AmazonWebServicesClientProxy proxy, + final ProxyClient rdsProxyClient, + final ProgressEvent progress, + final Tagging.TagSet tagSet ) { requestLogger.log("CreateDbInstanceAPIv12Invoked"); requestLogger.log("API version 12 create detected", - "This indicates that the customer is using DBSecurityGroup, which may result in certain features not" + - " functioning properly. Please refer to the API model for supported parameters"); + "This indicates that the customer is using DBSecurityGroup, which may result in certain features not" + + " functioning properly. Please refer to the API model for supported parameters"); + final Fetch fetch = new Fetch(rdsProxyClient); return proxy.initiate( - "rds::create-db-instance-v12", - rdsProxyClient, - progress.getResourceModel(), - progress.getCallbackContext() - ).translateToServiceRequest(Translator::createDbInstanceRequestV12) - .backoffDelay(config.getBackoff()) - .makeServiceCall((createRequest, proxyInvocation) -> proxyInvocation.injectCredentialsAndInvokeV2( - createRequest, - proxyInvocation.client()::createDBInstance - )) - .stabilize((request, response, proxyInvocation, model, context) -> { - final DBInstance dbInstance = fetchDBInstance(rdsProxyClient, model); - return DBInstancePredicates.isDBInstanceStabilizedAfterMutate(dbInstance, model, context, requestLogger) ; - }) - .handleError((request, exception, client, model, context) -> Commons.handleException( - ProgressEvent.progress(model, context), - exception, - Errors.CREATE_DB_INSTANCE_ERROR_RULE_SET, - requestLogger - )) - .progress(); + "rds::create-db-instance-v12", + rdsProxyClient, + progress.getResourceModel(), + progress.getCallbackContext() + ).translateToServiceRequest(Translator::createDbInstanceRequestV12) + .backoffDelay(config.getBackoff()) + .makeServiceCall((createRequest, proxyInvocation) -> proxyInvocation.injectCredentialsAndInvokeV2( + createRequest, + proxyInvocation.client()::createDBInstance + )) + .stabilize((request, response, proxyInvocation, model, context) -> { + final DBInstance dbInstance = fetch.dbInstance(model); + return DBInstancePredicates.isDBInstanceStabilizedAfterMutate(dbInstance, model, context, requestLogger); + }) + .handleError((request, exception, client, model, context) -> Commons.handleException( + ProgressEvent.progress(model, context), + exception, + Errors.CREATE_DB_INSTANCE_ERROR_RULE_SET, + requestLogger + )) + .progress(); } - protected ProgressEvent versioned( - final AmazonWebServicesClientProxy proxy, - final VersionedProxyClient rdsProxyClient, - final ProgressEvent progress, - final Tagging.TagSet allTags, - final Map> methodVersions - ) { - final ResourceModel model = progress.getResourceModel(); - final CallbackContext callbackContext = progress.getCallbackContext(); - final ApiVersion apiVersion = getApiVersionDispatcher().dispatch(model, callbackContext); - if (!methodVersions.containsKey(apiVersion)) { - throw new RuntimeException("Missing method version"); - } - return methodVersions.get(apiVersion).invoke(proxy, rdsProxyClient.forVersion(apiVersion), progress, allTags); - } - - protected ApiVersionDispatcher getApiVersionDispatcher() { - return apiVersionDispatcher; + private ApiVersion selectVersion(ResourceModel model, CallbackContext callbackContext) { + return apiVersionDispatcher.dispatch(model, callbackContext); } private HandlerMethod safeAddTags(final HandlerMethod handlerMethod) { return (proxy, rdsProxyClient, progress, tagSet) -> progress.then(p -> Tagging.createWithTaggingFallback(proxy, rdsProxyClient, handlerMethod, progress, tagSet)); } - - } diff --git a/aws-rds-dbinstance/src/main/java/software/amazon/rds/dbinstance/common/create/FromSnapshot.java b/aws-rds-dbinstance/src/main/java/software/amazon/rds/dbinstance/common/create/FromSnapshot.java index 6a3598e44..acdec97d3 100644 --- a/aws-rds-dbinstance/src/main/java/software/amazon/rds/dbinstance/common/create/FromSnapshot.java +++ b/aws-rds-dbinstance/src/main/java/software/amazon/rds/dbinstance/common/create/FromSnapshot.java @@ -25,6 +25,7 @@ import software.amazon.rds.dbinstance.client.ApiVersionDispatcher; import software.amazon.rds.dbinstance.client.VersionedProxyClient; import software.amazon.rds.dbinstance.common.Errors; +import software.amazon.rds.dbinstance.common.Fetch; import software.amazon.rds.dbinstance.util.ResourceModelHelper; import java.util.Map; @@ -42,10 +43,14 @@ public class FromSnapshot implements DBInstanceFactory { @Override public ProgressEvent create(ProgressEvent progress) { final ResourceModel model = progress.getResourceModel(); + final CallbackContext callbackContext = progress.getCallbackContext(); + final ApiVersion apiVersion = selectVersion(model, callbackContext); + + final Fetch fetch = new Fetch(rdsProxyClient.defaultClient()); final boolean isMultiAZ = BooleanUtils.isTrue(model.getMultiAZ()); if (ResourceModelHelper.isRestoreFromSnapshot(model) && !isMultiAZ) { try { - final DBSnapshot snapshot = fetchDBSnapshot(rdsProxyClient.defaultClient(), model); + final DBSnapshot snapshot = fetch.dbSnapshot(model); final String engine = snapshot.engine(); if (StringUtils.isNullOrEmpty(model.getEngine())) { model.setEngine(engine); @@ -57,10 +62,12 @@ public ProgressEvent create(ProgressEvent restoreDbInstanceFromSnapshotV12( @@ -73,6 +80,7 @@ private ProgressEvent restoreDbInstanceFromSnaps requestLogger.log("API version 12 restore detected", "This indicates that the customer is using DBSecurityGroup, which may result in certain features not" + " functioning properly. Please refer to the API model for supported parameters"); + final Fetch fetch = new Fetch(rdsProxyClient); return proxy.initiate( "rds::restore-db-instance-from-snapshot-v12", rdsProxyClient, @@ -85,7 +93,7 @@ private ProgressEvent restoreDbInstanceFromSnaps proxyInvocation.client()::restoreDBInstanceFromDBSnapshot )) .stabilize((request, response, proxyInvocation, model, context) -> { - final DBInstance dbInstance = fetchDBInstance(rdsProxyClient, model); + final DBInstance dbInstance = fetch.dbInstance(model); return DBInstancePredicates.isDBInstanceStabilizedAfterMutate(dbInstance, model, context, requestLogger); }) .handleError((request, exception, client, model, context) -> Commons.handleException( @@ -103,6 +111,7 @@ private ProgressEvent restoreDbInstanceFromSnaps final ProgressEvent progress, final Tagging.TagSet tagSet ) { + final Fetch fetch = new Fetch(rdsProxyClient); return proxy.initiate( "rds::restore-db-instance-from-snapshot", rdsProxyClient, @@ -115,7 +124,7 @@ private ProgressEvent restoreDbInstanceFromSnaps proxyInvocation.client()::restoreDBInstanceFromDBSnapshot )) .stabilize((request, response, proxyInvocation, model, context) -> { - final DBInstance dbInstance = fetchDBInstance(rdsProxyClient, model); + final DBInstance dbInstance = fetch.dbInstance(model); return DBInstancePredicates.isDBInstanceStabilizedAfterMutate(dbInstance, model, context, requestLogger); }) .handleError((request, exception, client, model, context) -> Commons.handleException( @@ -127,50 +136,11 @@ private ProgressEvent restoreDbInstanceFromSnaps .progress(); } - private DBInstance fetchDBInstance( - final ProxyClient rdsProxyClient, - final ResourceModel model - ) { - final DescribeDbInstancesResponse response = rdsProxyClient.injectCredentialsAndInvokeV2( - Translator.describeDbInstancesRequest(model), - rdsProxyClient.client()::describeDBInstances - ); - return response.dbInstances().get(0); - } - - protected ProgressEvent versioned( - final AmazonWebServicesClientProxy proxy, - final VersionedProxyClient rdsProxyClient, - final ProgressEvent progress, - final Tagging.TagSet allTags, - final Map> methodVersions - ) { - final ResourceModel model = progress.getResourceModel(); - final CallbackContext callbackContext = progress.getCallbackContext(); - final ApiVersion apiVersion = getApiVersionDispatcher().dispatch(model, callbackContext); - if (!methodVersions.containsKey(apiVersion)) { - throw new RuntimeException("Missing method version"); - } - return methodVersions.get(apiVersion).invoke(proxy, rdsProxyClient.forVersion(apiVersion), progress, allTags); - } - - protected ApiVersionDispatcher getApiVersionDispatcher() { - return apiVersionDispatcher; + private ApiVersion selectVersion(ResourceModel model, CallbackContext callbackContext) { + return apiVersionDispatcher.dispatch(model, callbackContext); } private HandlerMethod safeAddTags(final HandlerMethod handlerMethod) { return (proxy, rdsProxyClient, progress, tagSet) -> progress.then(p -> Tagging.createWithTaggingFallback(proxy, rdsProxyClient, handlerMethod, progress, tagSet)); } - - protected DBSnapshot fetchDBSnapshot( - final ProxyClient rdsProxyClient, - final ResourceModel model - ) { - final DescribeDbSnapshotsResponse response = rdsProxyClient.injectCredentialsAndInvokeV2( - Translator.describeDbSnapshotsRequest(model), - rdsProxyClient.client()::describeDBSnapshots - ); - return response.dbSnapshots().get(0); - } - }