private boolean stabilizeFirewallPolicyUpdate()

in aws-networkfirewall-firewall/src/main/java/software/amazon/networkfirewall/firewall/UpdateHandler.java [203:253]


    private boolean stabilizeFirewallPolicyUpdate(final AssociateFirewallPolicyRequest awsRequest,
            final AssociateFirewallPolicyResponse awsResponse, final ProxyClient<NetworkFirewallClient> client,
            final ResourceModel model, final CallbackContext callbackContext) {
        try {
            final DescribeFirewallResponse response = client.injectCredentialsAndInvokeV2(
                    Translator.translateToDescribeFirewallRequest(model),
                    client.client()::describeFirewall);

            // this can never be empty for active Firewall, but just in case of a bug, we should not mark the update
            // as success.
            if (response.firewallStatus().syncStates().isEmpty()) {
                return false;
            }
            // Its not enough just for the firewallStatus to be in `READY` and the ConfigurationSyncStateSummary to be
            // in `IN_SYNC` because firewall-policy association request is asynchronous. So, there is a
            // chance that when we call describe right after associateFirewallPolicy API, the work might not have
            // been started. So, the firewall status will be 'READY' and 'IN_SYNC' from the previous policy or
            // rule group updates. So, to confirm if the desired firewallPolicy got associated, we have to verify
            // the Config SyncStatus of this particular firewall policy ARN we are trying to associate here.

            // since same policy is associated to all subnets in a firewall, loop through all AZs under SyncStates key.
            for (final Map.Entry<String, SyncState> azSyncState : response.firewallStatus().syncStates().entrySet()) {
                final SyncState syncState = azSyncState.getValue();
                // check if the desired firewallPolicy ARN is part of the syncStates config Map.
                if (syncState.config().containsKey(desiredStateModel.getFirewallPolicyArn())) {
                    switch (syncState.config().get(desiredStateModel.getFirewallPolicyArn()).syncStatus()) {
                        case PENDING:
                            return false;
                        case IN_SYNC:
                            // continue to check the status in remaining AZs
                            continue;
                        default:
                            logger.log(String.format("Invalid/Unsupported syncState found while associating firewall"
                                    + "Policy:  %s", desiredStateModel.getFirewallPolicyArn()));
                            throw new CfnServiceInternalErrorException("FirewallPolicy failed to associate.");
                    }
                } else {
                    // desired firewallPolicy ARN is not yet added to SyncState, so still not stabilized
                    return false;
                }
            }

            // after confirming that firewallPolicy is associated to all subnets, check the firewallStatus and
            // configurationSyncStateSummary because this policy might have brought in new ruleGroups which also should
            // be in sync and that can be verified though the consolidated configurationSyncStateSummary.
            return response.firewallStatus().status() == FirewallStatusValue.READY &&
                    response.firewallStatus().configurationSyncStateSummary() == ConfigurationSyncState.IN_SYNC;
        } catch (final Exception e) {
            throw new CfnGeneralServiceException("FirewallPolicy failed to associate.");
        }
    }