AWS Control Tower exemples d'utilisation du SDK pour Java 2.x - AWS SDK for Java 2.x

Les traductions sont fournies par des outils de traduction automatique. En cas de conflit entre le contenu d'une traduction et celui de la version originale en anglais, la version anglaise prévaudra.

AWS Control Tower exemples d'utilisation du SDK pour Java 2.x

Les exemples de code suivants vous montrent comment effectuer des actions et implémenter des scénarios courants à l'aide du AWS SDK for Java 2.x with AWS Control Tower.

Les principes de base sont des exemples de code qui vous montrent comment effectuer les opérations essentielles au sein d’un service.

Les actions sont des extraits de code de programmes plus larges et doivent être exécutées dans leur contexte. Alors que les actions vous indiquent comment appeler des fonctions de service individuelles, vous pouvez les voir en contexte dans leurs scénarios associés.

Chaque exemple inclut un lien vers le code source complet, où vous trouverez des instructions sur la configuration et l’exécution du code en contexte.

Mise en route

L’exemple de code suivant montre comment démarrer avec AWS Control Tower.

SDK pour Java 2.x
Note

Il y en a plus à ce sujet GitHub. Trouvez l’exemple complet et découvrez comment le configurer et l’exécuter dans le référentiel d’exemples de code AWS.

public class HelloControlTower { public static void main(String[] args) { try { ControlTowerClient controlTowerClient = ControlTowerClient.builder() .build() ; helloControlTower(controlTowerClient); } catch (ControlTowerException e) { System.out.println("Control Tower error occurred: " + e.awsErrorDetails().errorMessage()); } } /** * Use the AWS SDK for Java (v2) to create an AWS Control Tower client * and list all available baselines. * This example uses the default settings specified in your shared credentials * and config files. * * @param controlTowerClient A ControlTowerClient object. This object wraps * the low-level AWS Control Tower service API. */ public static void helloControlTower(ControlTowerClient controlTowerClient) { System.out.println("Hello, AWS Control Tower! Let's list available baselines:\n"); ListBaselinesIterable paginator = controlTowerClient.listBaselinesPaginator( ListBaselinesRequest.builder().build()); List<String> baselineNames = new ArrayList<>(); try { paginator.stream() .flatMap(response -> response.baselines().stream()) .forEach(baseline -> baselineNames.add(baseline.name())); System.out.println(baselineNames.size() + " baseline(s) retrieved."); for (String baselineName : baselineNames) { System.out.println("\t" + baselineName); } } catch (ControlTowerException e) { if ("AccessDeniedException".equals(e.awsErrorDetails().errorCode())) { System.out.println("Access denied. Please ensure you have the necessary permissions."); } else { System.out.println("An error occurred: " + e.getMessage()); } } } }
  • Pour plus de détails sur l'API, reportez-vous ListBaselinesà la section Référence des AWS SDK for Java 2.x API.

Principes de base

L’exemple de code suivant illustre comment :

  • répertorier les zones de destination ;

  • répertorier, activer, obtenir, réinitialiser et désactiver les références ;

  • répertorier, activer, obtenir et désactiver les contrôles.

SDK pour Java 2.x
Note

Il y en a plus à ce sujet GitHub. Trouvez l’exemple complet et découvrez comment le configurer et l’exécuter dans le référentiel d’exemples de code AWS.

Exécutez un scénario interactif illustrant AWS Control Tower les fonctionnalités.

public class ControlTowerScenario { public static final String DASHES = new String(new char[80]).replace("\0", "-"); private static final Scanner scanner = new Scanner(in); private static OrganizationsClient orgClient; private static ControlCatalogClient catClient; private static String ouId = null; private static String ouArn = null; private static String landingZoneArn = null; private static boolean useLandingZone = false; private String stack = null; private String accountId = null; public static void main(String[] args) { System.out.println(DASHES); System.out.println("Welcome to the AWS Control Tower basics scenario!"); System.out.println(DASHES); try { runScenarioAsync(); } catch (Exception e) { e.printStackTrace(); } } // ----------------------------- // Utilities // ----------------------------- private static boolean askYesNo(String msg) { System.out.println(msg); return scanner.nextLine().trim().toLowerCase().startsWith("y"); } private static void runScenarioAsync() { try { ControlTowerActions actions = new ControlTowerActions(); // ----------------------------- // Step 1: Landing Zones // ----------------------------- System.out.println(DASHES); System.out.println(""" Some demo operations require the use of a landing zone. You can use an existing landing zone or opt out of these operations in the demo. For instructions on how to set up a landing zone, see https://docs.aws.amazon.com/controltower/latest/userguide/getting-started-from-console.html """); System.out.println("Step 1: Listing landing zones..."); waitForInputToContinue(scanner); List<LandingZoneSummary> landingZones = actions.listLandingZonesAsync().join(); if (landingZones.isEmpty()) { System.out.println("No landing zones found. Landing-zone-dependent steps will be skipped."); useLandingZone = false; waitForInputToContinue(scanner); } else { System.out.println("\nAvailable Landing Zones:"); for (int i = 0; i < landingZones.size(); i++) { System.out.printf("%d) %s%n", i + 1, landingZones.get(i).arn()); } if (askYesNo("Do you want to use the first landing zone in the list (" + landingZones.get(0).arn() + ")? (y/n): ")) { useLandingZone = true; landingZoneArn = landingZones.get(0).arn(); } else if (askYesNo("Do you want to use a different existing Landing Zone for this demo? (y/n): ")) { useLandingZone = true; System.out.println("Enter landing zone ARN: "); landingZoneArn = scanner.nextLine().trim(); } else { System.out.println("Proceeding without a landing zone."); useLandingZone = false; waitForInputToContinue(scanner); } } // ----------------------------- // Setup Organization + Sandbox OU // ----------------------------- if (useLandingZone) { System.out.println("Using landing zone ARN: " + landingZoneArn); ControlTowerActions.OrgSetupResult result = actions.setupOrganizationAsync().join(); ouArn = result.sandboxOuArn(); ouId = result.sandboxOuArn(); System.out.println("Organization ID: " + result.orgId()); System.out.println("Using Sandbox OU ARN: " + ouArn); } // ----------------------------- // Step 2: Baselines // ----------------------------- System.out.println(DASHES); System.out.println("Step 2: Listing available baselines..."); System.out.println(""" In this step, the program lists available AWS Control Tower baselines and may perform baseline-related operations (enable, disable, reset) if requested. NOTE: AWS Control Tower enforces governance through baselines and mandatory controls (guardrails). Mandatory controls are required for landing zone governance and may restrict certain operations depending on the account, region, or organizational policy. For more information, see: - Types of baselines in AWS Control Tower: https://docs.aws.amazon.com/controltower/latest/userguide/types-of-baselines.html - Mandatory controls (guardrails) in AWS Control Tower: https://docs.aws.amazon.com/controltower/latest/controlreference/mandatory-controls.html - Baseline API examples: https://docs.aws.amazon.com/controltower/latest/userguide/baseline-api-examples.html """); waitForInputToContinue(scanner); List<BaselineSummary> baselines = actions.listBaselinesAsync().join(); BaselineSummary controlTowerBaseline = null; for (BaselineSummary b : baselines) { System.out.println("Baseline: " + b.name()); System.out.println(" ARN: " + b.arn()); if ("AWSControlTowerBaseline".equals(b.name())) { controlTowerBaseline = b; } } waitForInputToContinue(scanner); if (useLandingZone && controlTowerBaseline != null) { System.out.println("\nListing enabled baselines:"); List<EnabledBaselineSummary> enabledBaselines = actions.listEnabledBaselinesAsync().join(); String enabledBaselineArn = null; for (EnabledBaselineSummary eb : enabledBaselines) { System.out.println("Checking enabled baseline ARN: " + eb.arn()); if (eb.baselineIdentifier().equals(controlTowerBaseline.arn())) { enabledBaselineArn = eb.arn(); // correct enabled ARN for this baseline break; // stop after finding the matching one } } if (enabledBaselineArn == null) { System.out.println("No enabled baseline found for " + controlTowerBaseline.arn()); } else { System.out.println("Selected enabled baseline ARN for reset/disable: " + enabledBaselineArn); } // Enable the Baseline if (askYesNo("Do you want to enable the Control Tower Baseline? (y/n): ")) { System.out.println("\nEnabling Control Tower Baseline..."); String baselineId = controlTowerBaseline.arn(); String enabledBaselineId = actions.enableBaselineAsync( ouArn, // targetIdentifier → the OU or account ARN baselineId, // baselineIdentifier → the Control Tower baseline ARN "5.0" // baselineVersion → version string ).join(); System.out.println("Enabled baseline operation ID: " + enabledBaselineId); if (enabledBaselineId == null) { enabledBaselineId = enabledBaselineArn; } // Reset the Baseline if (askYesNo("Do you want to reset the Control Tower Baseline? (y/n): ")) { String operationId = actions.resetEnabledBaselineAsync(enabledBaselineId).join(); System.out.println("Reset baseline operation ID: " + operationId); } if (askYesNo("Do you want to disable the Control Tower Baseline? (y/n): ")) { String operationId = actions.disableBaselineAsync(enabledBaselineId).join(); System.out.println("Disabled baseline operation ID: " + operationId); System.out.println("Now we will re‑enable the baseline and wait 1 minute before making the call..."); try { Thread.sleep(Duration.ofMinutes(1).toMillis()); } catch (InterruptedException e) { Thread.currentThread().interrupt(); System.out.println("Wait interrupted"); } String reEnabledBaselineId = actions.enableBaselineAsync( ouArn, baselineId, // reuse baseline definition ARN "5.0" ).join(); System.out.println("Re-enabled baseline operation ID: " + reEnabledBaselineId); } } } // ----------------------------- // Step 3: Controls // ----------------------------- System.out.println(DASHES); System.out.println("Step 3: Managing Controls:"); waitForInputToContinue(scanner); List<ControlSummary> controls = actions.listControlsAsync().join(); System.out.println("\nListing first 5 available Controls:"); for (int i = 0; i < Math.min(5, controls.size()); i++) { ControlSummary c = controls.get(i); System.out.println("%d. %s - %s".formatted(i + 1, c.name(), c.arn())); } if (useLandingZone) { waitForInputToContinue(scanner); List<EnabledControlSummary> enabledControls = actions.listEnabledControlsAsync(ouArn).join(); System.out.println("\nListing enabled controls:"); for (int i = 0; i < enabledControls.size(); i++) { System.out.println("%d. %s".formatted(i + 1, enabledControls.get(i).controlIdentifier())); } String controlArnToEnable = null; for (ControlSummary control : controls) { boolean enabled = enabledControls.stream() .anyMatch(ec -> ec.controlIdentifier().equals(control.arn())); if (!enabled) { controlArnToEnable = control.arn(); break; } } waitForInputToContinue(scanner); if (controlArnToEnable != null && askYesNo("Do you want to enable the control " + controlArnToEnable + "? (y/n): ")) { String operationId = actions.enableControlAsync(controlArnToEnable, ouArn).join(); System.out.println("Enabled control with operation ID: " + operationId); } waitForInputToContinue(scanner); if (controlArnToEnable != null && askYesNo("Do you want to disable the control? (y/n): ")) { String operationId = actions.disableControlAsync(controlArnToEnable, ouArn).join(); System.out.println("Disable operation ID: " + operationId); } } System.out.println("\nThis concludes the example scenario."); System.out.println("Thanks for watching!"); System.out.println(DASHES); } catch (CompletionException e) { Throwable cause = e.getCause() != null ? e.getCause() : e; System.out.println("Scenario failed: " + cause.getMessage()); throw e; // bubble up for tests / callers } catch (Exception e) { System.out.println("Unexpected error running scenario: " + e.getMessage()); throw new RuntimeException(e); } } private static void waitForInputToContinue(Scanner sc) { System.out.println("\nEnter 'c' then <ENTER> to continue:"); while (true) { String input = sc.nextLine(); if ("c".equalsIgnoreCase(input.trim())) { System.out.println("Continuing..."); break; } } } } public class ControlTowerActions { private static ControlCatalogAsyncClient controlCatalogAsyncClient; private static ControlTowerAsyncClient controlTowerAsyncClient; private static OrganizationsAsyncClient orgAsyncClient; private static OrganizationsAsyncClient getAsyncOrgClient() { if (orgAsyncClient == null) { SdkAsyncHttpClient httpClient = NettyNioAsyncHttpClient.builder() .maxConcurrency(50) .connectionTimeout(Duration.ofSeconds(60)) .readTimeout(Duration.ofSeconds(60)) .writeTimeout(Duration.ofSeconds(60)) .build(); ClientOverrideConfiguration overrideConfig = ClientOverrideConfiguration.builder() .apiCallTimeout(Duration.ofMinutes(2)) .apiCallAttemptTimeout(Duration.ofSeconds(90)) .build(); orgAsyncClient = OrganizationsAsyncClient.builder() .httpClient(httpClient) .overrideConfiguration(overrideConfig) .build(); } return orgAsyncClient; } private static ControlCatalogAsyncClient getAsyncCatClient() { if (controlCatalogAsyncClient == null) { SdkAsyncHttpClient httpClient = NettyNioAsyncHttpClient.builder() .maxConcurrency(100) .connectionTimeout(Duration.ofSeconds(60)) .readTimeout(Duration.ofSeconds(60)) .writeTimeout(Duration.ofSeconds(60)) .build(); ClientOverrideConfiguration overrideConfig = ClientOverrideConfiguration.builder() .apiCallTimeout(Duration.ofMinutes(2)) .apiCallAttemptTimeout(Duration.ofSeconds(90)) .retryStrategy(RetryMode.STANDARD) .build(); controlCatalogAsyncClient = ControlCatalogAsyncClient.builder() .httpClient(httpClient) .overrideConfiguration(overrideConfig) .build(); } return controlCatalogAsyncClient; } private static ControlTowerAsyncClient getAsyncClient() { if (controlTowerAsyncClient == null) { SdkAsyncHttpClient httpClient = AwsCrtAsyncHttpClient.builder() .maxConcurrency(100) .connectionTimeout(Duration.ofSeconds(60)) .build(); ClientOverrideConfiguration overrideConfig = ClientOverrideConfiguration.builder() .apiCallTimeout(Duration.ofMinutes(2)) .apiCallAttemptTimeout(Duration.ofSeconds(90)) .retryStrategy(RetryMode.STANDARD) .build(); controlTowerAsyncClient = ControlTowerAsyncClient.builder() .httpClient(httpClient) .overrideConfiguration(overrideConfig) .build(); } return controlTowerAsyncClient; } public record OrgSetupResult(String orgId, String sandboxOuArn) { } public CompletableFuture<OrgSetupResult> setupOrganizationAsync() { System.out.println("Starting organization setup…"); OrganizationsAsyncClient client = getAsyncOrgClient(); // Step 1: Describe or create organization CompletableFuture<Organization> orgFuture = client.describeOrganization() .thenApply(desc -> { System.out.println("Organization exists: " + desc.organization().id()); return desc.organization(); }) .exceptionallyCompose(ex -> { Throwable cause = ex.getCause() != null ? ex.getCause() : ex; if (cause instanceof AwsServiceException awsEx && "AWSOrganizationsNotInUseException".equals(awsEx.awsErrorDetails().errorCode())) { System.out.println("No organization found. Creating one…"); return client.createOrganization(CreateOrganizationRequest.builder() .featureSet(OrganizationFeatureSet.ALL) .build()) .thenApply(createResp -> { System.out.println("Created organization: {}" + createResp.organization().id()); return createResp.organization(); }); } return CompletableFuture.failedFuture( new CompletionException("Failed to describe or create organization", cause) ); }); // Step 2: Locate Sandbox OU return orgFuture.thenCompose(org -> { String orgId = org.id(); System.out.println("Organization ID: {}" + orgId); return client.listRoots() .thenCompose(rootsResp -> { if (rootsResp.roots().isEmpty()) { return CompletableFuture.failedFuture( new RuntimeException("No root found in organization") ); } String rootId = rootsResp.roots().get(0).id(); ListOrganizationalUnitsForParentRequest ouRequest = ListOrganizationalUnitsForParentRequest.builder() .parentId(rootId) .build(); ListOrganizationalUnitsForParentPublisher paginator = client.listOrganizationalUnitsForParentPaginator(ouRequest); AtomicReference<String> sandboxOuArnRef = new AtomicReference<>(); return paginator.subscribe(page -> { for (OrganizationalUnit ou : page.organizationalUnits()) { if ("Sandbox".equals(ou.name())) { sandboxOuArnRef.set(ou.arn()); System.out.println("Found Sandbox OU: " + ou.id()); break; } } }) .thenApply(v -> { String sandboxArn = sandboxOuArnRef.get(); if (sandboxArn == null) { System.out.println("Sandbox OU not found."); } return new OrgSetupResult(orgId, sandboxArn); }); }); }).exceptionally(ex -> { Throwable cause = ex.getCause() != null ? ex.getCause() : ex; System.out.println("Failed to setup organization: {}" + cause.getMessage()); throw new CompletionException(cause); }); } /** * Lists all landing zones using pagination to retrieve complete results. * * @return a list of all landing zones * @throws ControlTowerException if a service-specific error occurs * @throws SdkException if an SDK error occurs */ public CompletableFuture<List<LandingZoneSummary>> listLandingZonesAsync() { System.out.println("Starting list landing zones paginator…"); ListLandingZonesRequest request = ListLandingZonesRequest.builder().build(); ListLandingZonesPublisher paginator = getAsyncClient().listLandingZonesPaginator(request); List<LandingZoneSummary> landingZones = new ArrayList<>(); return paginator.subscribe(response -> { if (response.landingZones() != null && !response.landingZones().isEmpty()) { response.landingZones().forEach(lz -> { System.out.println("Landing zone ARN: " + lz.arn()); landingZones.add(lz); }); } else { System.out.println("Page contained no landing zones."); } }) .thenRun(() -> System.out.println("Successfully retrieved "+ landingZones.size() + " landing zones." )) .thenApply(v -> landingZones) .exceptionally(ex -> { Throwable cause = ex.getCause() != null ? ex.getCause() : ex; if (cause instanceof ControlTowerException e) { String errorCode = e.awsErrorDetails().errorCode(); switch (errorCode) { case "AccessDeniedException": throw new CompletionException( "Access denied when listing landing zones: " + e.getMessage(), e); default: throw new CompletionException( "Error listing landing zones: " + e.getMessage(), e); } } if (cause instanceof SdkException) { throw new CompletionException( "SDK error listing landing zones: " + cause.getMessage(), cause); } throw new CompletionException("Failed to list landing zones", cause); }); } /** * Lists all available baselines using pagination to retrieve complete results. * * @return a list of all baselines * @throws ControlTowerException if a service-specific error occurs * @throws SdkException if an SDK error occurs */ public CompletableFuture<List<BaselineSummary>> listBaselinesAsync() { System.out.println("Starting list baselines paginator…"); ListBaselinesRequest request = ListBaselinesRequest.builder().build(); ListBaselinesPublisher paginator = getAsyncClient().listBaselinesPaginator(request); List<BaselineSummary> baselines = new ArrayList<>(); return paginator.subscribe(response -> { if (response.baselines() != null && !response.baselines().isEmpty()) { response.baselines().forEach(baseline -> { baselines.add(baseline); }); } else { System.out.println("Page contained no baselines."); } }) .thenRun(() -> System.out.println("Successfully listed baselines. Total: " + baselines.size()) ) .thenApply(v -> baselines) .exceptionally(ex -> { Throwable cause = ex.getCause() != null ? ex.getCause() : ex; if (cause instanceof ControlTowerException e) { String errorCode = e.awsErrorDetails().errorCode(); if ("AccessDeniedException".equals(errorCode)) { throw new CompletionException( "Access denied when listing baselines: %s".formatted(e.getMessage()), e ); } throw new CompletionException( "Error listing baselines: %s".formatted(e.getMessage()), e ); } if (cause instanceof SdkException) { throw new CompletionException( "SDK error listing baselines: %s".formatted(cause.getMessage()), cause ); } throw new CompletionException("Failed to list baselines", cause); }); } /** * Lists all enabled baselines using pagination to retrieve complete results. * * @return a list of all enabled baselines * @throws ControlTowerException if a service-specific error occurs * @throws SdkException if an SDK error occurs */ public CompletableFuture<List<EnabledBaselineSummary>> listEnabledBaselinesAsync() { System.out.println("Starting list enabled baselines paginator…"); ListEnabledBaselinesRequest request = ListEnabledBaselinesRequest.builder().build(); ListEnabledBaselinesPublisher paginator = getAsyncClient().listEnabledBaselinesPaginator(request); List<EnabledBaselineSummary> enabledBaselines = new ArrayList<>(); return paginator.subscribe(response -> { if (response.enabledBaselines() != null && !response.enabledBaselines().isEmpty()) { response.enabledBaselines().forEach(baseline -> { enabledBaselines.add(baseline); }); } else { System.out.println("Page contained no enabled baselines."); } }) .thenRun(() -> System.out.println( "Successfully listed enabled baselines. Total: " + enabledBaselines.size() ) ) .thenApply(v -> enabledBaselines) .exceptionally(ex -> { Throwable cause = ex.getCause() != null ? ex.getCause() : ex; if (cause instanceof ControlTowerException e) { String errorCode = e.awsErrorDetails().errorCode(); if ("AccessDeniedException".equals(errorCode)) { throw new CompletionException( "Access denied when listing enabled baselines: %s".formatted(e.getMessage()), e); } throw new CompletionException( "Error listing enabled baselines: %s" .formatted(e.getMessage()), e ); } if (cause instanceof SdkException) { throw new CompletionException( "SDK error listing enabled baselines: %s" .formatted(cause.getMessage()), cause ); } throw new CompletionException( "Failed to list enabled baselines", cause ); }); } /** * Asynchronously enables a baseline for the specified target if not already enabled. * * @param targetIdentifier The ARN of the target (OU or account). * @param baselineIdentifier The baseline definition ARN to enable. * @param baselineVersion The baseline version to enable. * @return A CompletableFuture containing the enabled baseline ARN, or null if already enabled. */ public CompletableFuture<String> enableBaselineAsync( String targetIdentifier, String baselineIdentifier, String baselineVersion ) { EnableBaselineRequest request = EnableBaselineRequest.builder() .baselineIdentifier(baselineIdentifier) .baselineVersion(baselineVersion) .targetIdentifier(targetIdentifier) .build(); return getAsyncClient().enableBaseline(request) .handle((resp, exception) -> { if (exception != null) { Throwable cause = exception.getCause() != null ? exception.getCause() : exception; if (cause instanceof ControlTowerException e) { String code = e.awsErrorDetails() != null ? e.awsErrorDetails().errorCode() : "UNKNOWN"; String msg = e.awsErrorDetails() != null ? e.awsErrorDetails().errorMessage() : e.getMessage(); if ("ValidationException".equals(code) && msg.contains("already enabled")) { System.out.println("Baseline is already enabled for this target → fetching ARN..."); return fetchEnabledBaselineArn(targetIdentifier, baselineIdentifier) .join(); // fetch existing ARN synchronously } throw new RuntimeException("Error enabling baseline: " + code + " - " + msg, e); } throw new RuntimeException("Unexpected error enabling baseline: " + cause.getMessage(), cause); } return resp; }) .thenCompose(result -> { if (result instanceof EnableBaselineResponse resp) { String operationId = resp.operationIdentifier(); String enabledBaselineArn = resp.arn(); System.out.println("Baseline enable started. ARN: " + enabledBaselineArn + ", operation ID: " + operationId); // Inline polling return CompletableFuture.supplyAsync(() -> { while (true) { GetBaselineOperationRequest opReq = GetBaselineOperationRequest.builder() .operationIdentifier(operationId) .build(); GetBaselineOperationResponse opResp = getAsyncClient().getBaselineOperation(opReq).join(); BaselineOperation op = opResp.baselineOperation(); BaselineOperationStatus status = op.status(); System.out.println("Operation " + operationId + " status: " + status); if (status == BaselineOperationStatus.SUCCEEDED) { return enabledBaselineArn; } else if (status == BaselineOperationStatus.FAILED) { String opId = op.operationIdentifier(); String reason = op.statusMessage() != null ? op.statusMessage() : "No failure reason provided"; throw new RuntimeException("Baseline operation failed (ID: " + opId + "), status: " + status + ", reason: " + reason); } try { Thread.sleep(Duration.ofSeconds(15).toMillis()); } catch (InterruptedException e) { Thread.currentThread().interrupt(); throw new RuntimeException(e); } } }); } else if (result instanceof String existingArn) { // Already enabled branch return CompletableFuture.completedFuture(existingArn); } return CompletableFuture.completedFuture(null); }); } /** * Fetches the ARN of an already-enabled baseline for the target asynchronously. */ private CompletableFuture<String> fetchEnabledBaselineArn(String targetIdentifier, String baselineIdentifier) { return getAsyncClient().listEnabledBaselines(ListEnabledBaselinesRequest.builder().build()) .thenApply(listResp -> { for (EnabledBaselineSummary eb : listResp.enabledBaselines()) { if (baselineIdentifier.equals(eb.baselineIdentifier()) && targetIdentifier.equals(eb.targetIdentifier())) { return eb.arn(); } } return null; // not yet available }); } /** * Disables a baseline for a specified target. * * @param enabledBaselineIdentifier the identifier of the enabled baseline to disable * @return the operation identifier * @throws ControlTowerException if a service-specific error occurs * @throws SdkException if an SDK error occurs */ public CompletableFuture<String> disableBaselineAsync(String enabledBaselineIdentifier) { System.out.println("Starting disable of enabled baseline…"); System.out.println("This operation will check the status every 15 seconds until it completes (SUCCEEDED or FAILED)."); DisableBaselineRequest request = DisableBaselineRequest.builder() .enabledBaselineIdentifier(enabledBaselineIdentifier) .build(); return getAsyncClient().disableBaseline(request) .thenCompose(response -> { String operationId = response.operationIdentifier(); System.out.println("Disable baseline operation ID: " + operationId); // CompletableFuture that will be completed when operation finishes CompletableFuture<String> resultFuture = new CompletableFuture<>(); // Polling loop Runnable poller = new Runnable() { @Override public void run() { getBaselineOperationAsync(operationId) .thenAccept(statusObj -> { String status = statusObj.toString(); // Convert enum/status to string for printing System.out.println("Current disable operation status: " + status + " → waiting for SUCCEEDED or FAILED..."); if ("SUCCEEDED".equalsIgnoreCase(status) || "FAILED".equalsIgnoreCase(status)) { System.out.println("Disable operation finished with status: " + status); resultFuture.complete(operationId); } else { // Schedule next poll in 15 seconds CompletableFuture.delayedExecutor(15, TimeUnit.SECONDS) .execute(this); } }) .exceptionally(ex -> { System.out.println("Error checking baseline operation status: " + ex.getMessage()); resultFuture.completeExceptionally(ex); return null; }); } }; // Start first poll immediately poller.run(); return resultFuture; }) .exceptionally(ex -> { Throwable cause = ex.getCause() != null ? ex.getCause() : ex; if (cause instanceof ControlTowerException e) { String errorCode = e.awsErrorDetails() != null ? e.awsErrorDetails().errorCode() : "UNKNOWN"; String errorMessage = e.awsErrorDetails() != null ? e.awsErrorDetails().errorMessage() : e.getMessage(); System.out.println("ControlTowerException caught while disabling baseline: Code=" + errorCode + ", Message=" + errorMessage); return null; } if (cause instanceof SdkException sdkEx) { System.out.println("SDK exception caught while disabling baseline: " + sdkEx.getMessage()); return null; } System.out.println("Unexpected exception while disabling baseline: " + cause.getMessage()); return null; }); } /** * Gets the status of a baseline operation. * * @param operationIdentifier the identifier of the operation * @return the operation status * @throws ControlTowerException if a service-specific error occurs * @throws SdkException if an SDK error occurs */ public CompletableFuture<BaselineOperationStatus> getBaselineOperationAsync( String operationIdentifier) { GetBaselineOperationRequest request = GetBaselineOperationRequest.builder() .operationIdentifier(operationIdentifier) .build(); return getAsyncClient().getBaselineOperation(request) .whenComplete((response, exception) -> { if (exception != null) { Throwable cause = exception.getCause() != null ? exception.getCause() : exception; if (cause instanceof ControlTowerException e) { String errorCode = e.awsErrorDetails().errorCode(); if ("ResourceNotFoundException".equals(errorCode)) { throw new CompletionException( "Baseline operation not found: %s" .formatted(e.getMessage()), e ); } throw new CompletionException( "Error getting baseline operation status: %s" .formatted(e.getMessage()), e ); } if (cause instanceof SdkException) { throw new CompletionException( "SDK error getting baseline operation status: %s" .formatted(cause.getMessage()), cause ); } throw new CompletionException( "Failed to get baseline operation status", cause ); } }) .thenApply(response -> { BaselineOperationStatus status = response.baselineOperation().status(); return status; }); } /** * Lists all enabled controls for a specific target using pagination. * * @param targetIdentifier the identifier of the target (e.g., OU ARN) * @return a list of enabled controls * @throws ControlTowerException if a service-specific error occurs * @throws SdkException if an SDK error occurs */ public CompletableFuture<List<EnabledControlSummary>> listEnabledControlsAsync(String targetIdentifier) { System.out.println("Starting list enabled controls paginator for target " + targetIdentifier); ListEnabledControlsRequest request = ListEnabledControlsRequest.builder() .targetIdentifier(targetIdentifier) .build(); ListEnabledControlsPublisher paginator = getAsyncClient().listEnabledControlsPaginator(request); List<EnabledControlSummary> enabledControls = new ArrayList<>(); // Subscribe to the paginator asynchronously return paginator.subscribe(response -> { if (response.enabledControls() != null && !response.enabledControls().isEmpty()) { response.enabledControls().forEach(control -> { enabledControls.add(control); }); } else { System.out.println("Page contained no enabled controls."); } }) .thenRun(() -> System.out.println( "Successfully retrieved "+enabledControls.size() +" enabled controls for target "+targetIdentifier )) .thenApply(v -> enabledControls) .exceptionally(ex -> { Throwable cause = ex.getCause() != null ? ex.getCause() : ex; if (cause instanceof ControlTowerException e) { String errorCode = e.awsErrorDetails().errorCode(); switch (errorCode) { case "AccessDeniedException": throw new CompletionException( "Access denied when listing enabled controls: %s".formatted(e.getMessage()), e); case "ResourceNotFoundException": if (e.getMessage() != null && e.getMessage().contains("not registered with AWS Control Tower")) { throw new CompletionException( "Control Tower must be enabled to work with controls", e); } throw new CompletionException( "Target not found when listing enabled controls: %s".formatted(e.getMessage()), e); default: throw new CompletionException( "Error listing enabled controls: %s".formatted(e.getMessage()), e); } } if (cause instanceof SdkException) { throw new CompletionException( "SDK error listing enabled controls: %s".formatted(cause.getMessage()), cause); } throw new CompletionException("Failed to list enabled controls", cause); }); } /** * Enables a control for a specified target. * * @param controlIdentifier the identifier of the control to enable * @param targetIdentifier the identifier of the target (e.g., OU ARN) * @return the operation identifier * @throws ControlTowerException if a service-specific error occurs * @throws SdkException if an SDK error occurs */ public CompletableFuture<String> enableControlAsync( String controlIdentifier, String targetIdentifier) { EnableControlRequest request = EnableControlRequest.builder() .controlIdentifier(controlIdentifier) .targetIdentifier(targetIdentifier) .build(); return getAsyncClient().enableControl(request) .thenCompose(response -> { String operationId = response.operationIdentifier(); System.out.println("Enable control operation started. Operation ID: " + operationId); CompletableFuture<String> resultFuture = new CompletableFuture<>(); Runnable poller = new Runnable() { @Override public void run() { getControlOperationAsync(operationId) .thenAccept(status -> { System.out.println("Control operation status: " + status); if (status == ControlOperationStatus.SUCCEEDED || status == ControlOperationStatus.FAILED) { resultFuture.complete(operationId); } else { // Poll again after 30 seconds CompletableFuture.delayedExecutor(30, TimeUnit.SECONDS) .execute(this); } }) .exceptionally(ex -> { resultFuture.completeExceptionally(ex); return null; }); } }; // Start polling immediately poller.run(); return resultFuture; }) .exceptionally(ex -> { Throwable cause = ex.getCause() != null ? ex.getCause() : ex; if (cause instanceof ControlTowerException e) { String errorCode = e.awsErrorDetails().errorCode(); String message = e.getMessage() != null ? e.getMessage() : ""; if ("ValidationException".equals(errorCode) && message.contains("already enabled")) { System.out.println("Control is already enabled for this target"); return null; } if ("ResourceNotFoundException".equals(errorCode) && message.contains("not registered with AWS Control Tower")) { System.out.println( "Control Tower must be enabled to work with controls."); return null; } throw new CompletionException( "Couldn't enable control: %s".formatted(message), e ); } if (cause instanceof SdkException) { throw new CompletionException( "SDK error enabling control: %s" .formatted(cause.getMessage()), cause ); } throw new CompletionException( "Failed to enable control", cause ); }); } /** * Disables a control for a specified target. * * @param controlIdentifier the identifier of the control to disable * @param targetIdentifier the identifier of the target (e.g., OU ARN) * @return the operation identifier * @throws ControlTowerException if a service-specific error occurs * @throws SdkException if an SDK error occurs */ public CompletableFuture<String> disableControlAsync( String controlIdentifier, String targetIdentifier) { DisableControlRequest request = DisableControlRequest.builder() .controlIdentifier(controlIdentifier) .targetIdentifier(targetIdentifier) .build(); return getAsyncClient().disableControl(request) .thenCompose(response -> { String operationId = response.operationIdentifier(); System.out.println("Disable control operation started. Operation ID: " + operationId); CompletableFuture<String> resultFuture = new CompletableFuture<>(); Runnable poller = new Runnable() { @Override public void run() { getControlOperationAsync(operationId) .thenAccept(status -> { System.out.println("Control operation status: " + status); if (status == ControlOperationStatus.SUCCEEDED || status == ControlOperationStatus.FAILED) { resultFuture.complete(operationId); } else { // poll again after 30 seconds CompletableFuture.delayedExecutor(30, TimeUnit.SECONDS) .execute(this); } }) .exceptionally(ex -> { resultFuture.completeExceptionally(ex); return null; }); } }; // start polling immediately poller.run(); return resultFuture; }) .exceptionally(ex -> { Throwable cause = ex.getCause() != null ? ex.getCause() : ex; if (cause instanceof ControlTowerException e) { String errorCode = e.awsErrorDetails().errorCode(); if ("ResourceNotFoundException".equals(errorCode)) { // SPEC: notify user and continue System.out.println("Control not found for disabling: " + e.getMessage()); return null; } throw new CompletionException( "Error disabling control: " + e.getMessage(), e); } if (cause instanceof SdkException) { throw new CompletionException( "SDK error disabling control: " + cause.getMessage(), cause); } throw new CompletionException( "Failed to disable control", cause); }); } /** * Gets the status of a control operation. * * @param operationIdentifier the identifier of the operation * @return the operation status * @throws ControlTowerException if a service-specific error occurs * @throws SdkException if an SDK error occurs */ public CompletableFuture<ControlOperationStatus> getControlOperationAsync( String operationIdentifier) { GetControlOperationRequest request = GetControlOperationRequest.builder() .operationIdentifier(operationIdentifier) .build(); return getAsyncClient().getControlOperation(request) .whenComplete((response, exception) -> { if (exception != null) { Throwable cause = exception.getCause() != null ? exception.getCause() : exception; if (cause instanceof ControlTowerException e) { String errorCode = e.awsErrorDetails().errorCode(); if ("ResourceNotFoundException".equals(errorCode)) { throw new CompletionException( "Control operation not found: %s".formatted(e.getMessage()), e ); } throw new CompletionException( "Error getting control operation status: %s".formatted(e.getMessage()), e ); } if (cause instanceof SdkException) { throw new CompletionException( "SDK error getting control operation status: %s".formatted(cause.getMessage()), cause ); } throw new CompletionException("Failed to get control operation status", cause); } }) .thenApply(response -> response.controlOperation().status()); } /** * Lists all controls in the Control Tower control catalog. * * @return a list of controls * @throws SdkException if a service-specific error occurs */ public CompletableFuture<List<ControlSummary>> listControlsAsync() { System.out.println("Starting list controls paginator…"); ListControlsRequest request = ListControlsRequest.builder().build(); ListControlsPublisher paginator = getAsyncCatClient().listControlsPaginator(request); List<ControlSummary> controls = new ArrayList<>(); return paginator.subscribe(response -> { if (response.controls() != null && !response.controls().isEmpty()) { response.controls().forEach(control -> { controls.add(control); }); } else { System.out.println("Page contained no controls."); } }) .thenRun(() -> System.out.println("Successfully retrieved " + controls.size() +" controls.")) .thenApply(v -> controls) .exceptionally(ex -> { Throwable cause = ex.getCause() != null ? ex.getCause() : ex; if (cause instanceof SdkException sdkEx) { if (sdkEx.getMessage() != null && sdkEx.getMessage().contains("AccessDeniedException")) { throw new CompletionException( "Access denied when listing controls. Please ensure you have the necessary permissions.", sdkEx ); } else { throw new CompletionException( "SDK error listing controls: %s".formatted(sdkEx.getMessage()), sdkEx ); } } throw new CompletionException("Failed to list controls", cause); }); } /** * Resets an enabled baseline for a specific target. * * @param enabledBaselineIdentifier the identifier of the enabled baseline to reset * @return the operation identifier * @throws ControlTowerException if a service-specific error occurs * @throws SdkException if an SDK error occurs */ public CompletableFuture<String> resetEnabledBaselineAsync(String enabledBaselineIdentifier) { System.out.println("Starting reset of enabled baseline…"); System.out.println("This operation will check the status every 15 seconds until it completes (SUCCEEDED or FAILED)."); ResetEnabledBaselineRequest request = ResetEnabledBaselineRequest.builder() .enabledBaselineIdentifier(enabledBaselineIdentifier) .build(); return getAsyncClient().resetEnabledBaseline(request) .thenCompose(response -> { String operationId = response.operationIdentifier(); System.out.println("Reset enabled baseline operation ID: " + operationId); // Polling loop CompletableFuture<String> resultFuture = new CompletableFuture<>(); Runnable poller = new Runnable() { @Override public void run() { getBaselineOperationAsync(operationId) .thenAccept(statusObj -> { String status = statusObj.toString(); // Convert enum/status to string for printing System.out.println("Current baseline operation status: " + status + " → waiting for SUCCEEDED or FAILED..."); if ("SUCCEEDED".equalsIgnoreCase(status) || "FAILED".equalsIgnoreCase(status)) { System.out.println("Baseline operation finished with status: " + status); resultFuture.complete(operationId); } else { // Schedule next poll in 15 seconds CompletableFuture.delayedExecutor(15, TimeUnit.SECONDS) .execute(this); } }) .exceptionally(ex -> { System.out.println("Error checking baseline operation status: " + ex.getMessage()); resultFuture.completeExceptionally(ex); return null; }); } }; // Start first poll immediately poller.run(); return resultFuture; }) .exceptionally(ex -> { Throwable cause = ex.getCause() != null ? ex.getCause() : ex; if (cause instanceof ControlTowerException e) { String errorCode = e.awsErrorDetails() != null ? e.awsErrorDetails().errorCode() : "UNKNOWN"; String errorMessage = e.awsErrorDetails() != null ? e.awsErrorDetails().errorMessage() : e.getMessage(); System.out.println("ControlTowerException caught: Code=" + errorCode + ", Message=" + errorMessage); return null; } if (cause instanceof SdkException sdkEx) { System.out.println("SDK exception caught: " + sdkEx.getMessage()); return null; } System.out.println("Unexpected exception resetting baseline: " + cause.getMessage()); return null; }); } }

Actions

L'exemple de code suivant montre comment utiliserDisableBaseline.

SDK pour Java 2.x
Note

Il y en a plus à ce sujet GitHub. Trouvez l’exemple complet et découvrez comment le configurer et l’exécuter dans le référentiel d’exemples de code AWS.

/** * Disables a baseline for a specified target. * * @param enabledBaselineIdentifier the identifier of the enabled baseline to disable * @return the operation identifier * @throws ControlTowerException if a service-specific error occurs * @throws SdkException if an SDK error occurs */ public CompletableFuture<String> disableBaselineAsync(String enabledBaselineIdentifier) { System.out.println("Starting disable of enabled baseline…"); System.out.println("This operation will check the status every 15 seconds until it completes (SUCCEEDED or FAILED)."); DisableBaselineRequest request = DisableBaselineRequest.builder() .enabledBaselineIdentifier(enabledBaselineIdentifier) .build(); return getAsyncClient().disableBaseline(request) .thenCompose(response -> { String operationId = response.operationIdentifier(); System.out.println("Disable baseline operation ID: " + operationId); // CompletableFuture that will be completed when operation finishes CompletableFuture<String> resultFuture = new CompletableFuture<>(); // Polling loop Runnable poller = new Runnable() { @Override public void run() { getBaselineOperationAsync(operationId) .thenAccept(statusObj -> { String status = statusObj.toString(); // Convert enum/status to string for printing System.out.println("Current disable operation status: " + status + " → waiting for SUCCEEDED or FAILED..."); if ("SUCCEEDED".equalsIgnoreCase(status) || "FAILED".equalsIgnoreCase(status)) { System.out.println("Disable operation finished with status: " + status); resultFuture.complete(operationId); } else { // Schedule next poll in 15 seconds CompletableFuture.delayedExecutor(15, TimeUnit.SECONDS) .execute(this); } }) .exceptionally(ex -> { System.out.println("Error checking baseline operation status: " + ex.getMessage()); resultFuture.completeExceptionally(ex); return null; }); } }; // Start first poll immediately poller.run(); return resultFuture; }) .exceptionally(ex -> { Throwable cause = ex.getCause() != null ? ex.getCause() : ex; if (cause instanceof ControlTowerException e) { String errorCode = e.awsErrorDetails() != null ? e.awsErrorDetails().errorCode() : "UNKNOWN"; String errorMessage = e.awsErrorDetails() != null ? e.awsErrorDetails().errorMessage() : e.getMessage(); System.out.println("ControlTowerException caught while disabling baseline: Code=" + errorCode + ", Message=" + errorMessage); return null; } if (cause instanceof SdkException sdkEx) { System.out.println("SDK exception caught while disabling baseline: " + sdkEx.getMessage()); return null; } System.out.println("Unexpected exception while disabling baseline: " + cause.getMessage()); return null; }); }
  • Pour plus de détails sur l'API, reportez-vous DisableBaselineà la section Référence des AWS SDK for Java 2.x API.

L'exemple de code suivant montre comment utiliserDisableControl.

SDK pour Java 2.x
Note

Il y en a plus à ce sujet GitHub. Trouvez l’exemple complet et découvrez comment le configurer et l’exécuter dans le référentiel d’exemples de code AWS.

/** * Disables a control for a specified target. * * @param controlIdentifier the identifier of the control to disable * @param targetIdentifier the identifier of the target (e.g., OU ARN) * @return the operation identifier * @throws ControlTowerException if a service-specific error occurs * @throws SdkException if an SDK error occurs */ public CompletableFuture<String> disableControlAsync( String controlIdentifier, String targetIdentifier) { DisableControlRequest request = DisableControlRequest.builder() .controlIdentifier(controlIdentifier) .targetIdentifier(targetIdentifier) .build(); return getAsyncClient().disableControl(request) .thenCompose(response -> { String operationId = response.operationIdentifier(); System.out.println("Disable control operation started. Operation ID: " + operationId); CompletableFuture<String> resultFuture = new CompletableFuture<>(); Runnable poller = new Runnable() { @Override public void run() { getControlOperationAsync(operationId) .thenAccept(status -> { System.out.println("Control operation status: " + status); if (status == ControlOperationStatus.SUCCEEDED || status == ControlOperationStatus.FAILED) { resultFuture.complete(operationId); } else { // poll again after 30 seconds CompletableFuture.delayedExecutor(30, TimeUnit.SECONDS) .execute(this); } }) .exceptionally(ex -> { resultFuture.completeExceptionally(ex); return null; }); } }; // start polling immediately poller.run(); return resultFuture; }) .exceptionally(ex -> { Throwable cause = ex.getCause() != null ? ex.getCause() : ex; if (cause instanceof ControlTowerException e) { String errorCode = e.awsErrorDetails().errorCode(); if ("ResourceNotFoundException".equals(errorCode)) { // SPEC: notify user and continue System.out.println("Control not found for disabling: " + e.getMessage()); return null; } throw new CompletionException( "Error disabling control: " + e.getMessage(), e); } if (cause instanceof SdkException) { throw new CompletionException( "SDK error disabling control: " + cause.getMessage(), cause); } throw new CompletionException( "Failed to disable control", cause); }); }
  • Pour plus de détails sur l'API, reportez-vous DisableControlà la section Référence des AWS SDK for Java 2.x API.

L'exemple de code suivant montre comment utiliserEnableBaseline.

SDK pour Java 2.x
Note

Il y en a plus à ce sujet GitHub. Trouvez l’exemple complet et découvrez comment le configurer et l’exécuter dans le référentiel d’exemples de code AWS.

/** * Asynchronously enables a baseline for the specified target if not already enabled. * * @param targetIdentifier The ARN of the target (OU or account). * @param baselineIdentifier The baseline definition ARN to enable. * @param baselineVersion The baseline version to enable. * @return A CompletableFuture containing the enabled baseline ARN, or null if already enabled. */ public CompletableFuture<String> enableBaselineAsync( String targetIdentifier, String baselineIdentifier, String baselineVersion ) { EnableBaselineRequest request = EnableBaselineRequest.builder() .baselineIdentifier(baselineIdentifier) .baselineVersion(baselineVersion) .targetIdentifier(targetIdentifier) .build(); return getAsyncClient().enableBaseline(request) .handle((resp, exception) -> { if (exception != null) { Throwable cause = exception.getCause() != null ? exception.getCause() : exception; if (cause instanceof ControlTowerException e) { String code = e.awsErrorDetails() != null ? e.awsErrorDetails().errorCode() : "UNKNOWN"; String msg = e.awsErrorDetails() != null ? e.awsErrorDetails().errorMessage() : e.getMessage(); if ("ValidationException".equals(code) && msg.contains("already enabled")) { System.out.println("Baseline is already enabled for this target → fetching ARN..."); return fetchEnabledBaselineArn(targetIdentifier, baselineIdentifier) .join(); // fetch existing ARN synchronously } throw new RuntimeException("Error enabling baseline: " + code + " - " + msg, e); } throw new RuntimeException("Unexpected error enabling baseline: " + cause.getMessage(), cause); } return resp; }) .thenCompose(result -> { if (result instanceof EnableBaselineResponse resp) { String operationId = resp.operationIdentifier(); String enabledBaselineArn = resp.arn(); System.out.println("Baseline enable started. ARN: " + enabledBaselineArn + ", operation ID: " + operationId); // Inline polling return CompletableFuture.supplyAsync(() -> { while (true) { GetBaselineOperationRequest opReq = GetBaselineOperationRequest.builder() .operationIdentifier(operationId) .build(); GetBaselineOperationResponse opResp = getAsyncClient().getBaselineOperation(opReq).join(); BaselineOperation op = opResp.baselineOperation(); BaselineOperationStatus status = op.status(); System.out.println("Operation " + operationId + " status: " + status); if (status == BaselineOperationStatus.SUCCEEDED) { return enabledBaselineArn; } else if (status == BaselineOperationStatus.FAILED) { String opId = op.operationIdentifier(); String reason = op.statusMessage() != null ? op.statusMessage() : "No failure reason provided"; throw new RuntimeException("Baseline operation failed (ID: " + opId + "), status: " + status + ", reason: " + reason); } try { Thread.sleep(Duration.ofSeconds(15).toMillis()); } catch (InterruptedException e) { Thread.currentThread().interrupt(); throw new RuntimeException(e); } } }); } else if (result instanceof String existingArn) { // Already enabled branch return CompletableFuture.completedFuture(existingArn); } return CompletableFuture.completedFuture(null); }); } /** * Fetches the ARN of an already-enabled baseline for the target asynchronously. */ private CompletableFuture<String> fetchEnabledBaselineArn(String targetIdentifier, String baselineIdentifier) { return getAsyncClient().listEnabledBaselines(ListEnabledBaselinesRequest.builder().build()) .thenApply(listResp -> { for (EnabledBaselineSummary eb : listResp.enabledBaselines()) { if (baselineIdentifier.equals(eb.baselineIdentifier()) && targetIdentifier.equals(eb.targetIdentifier())) { return eb.arn(); } } return null; // not yet available }); }
  • Pour plus de détails sur l'API, reportez-vous EnableBaselineà la section Référence des AWS SDK for Java 2.x API.

L'exemple de code suivant montre comment utiliserEnableControl.

SDK pour Java 2.x
Note

Il y en a plus à ce sujet GitHub. Trouvez l’exemple complet et découvrez comment le configurer et l’exécuter dans le référentiel d’exemples de code AWS.

/** * Enables a control for a specified target. * * @param controlIdentifier the identifier of the control to enable * @param targetIdentifier the identifier of the target (e.g., OU ARN) * @return the operation identifier * @throws ControlTowerException if a service-specific error occurs * @throws SdkException if an SDK error occurs */ public CompletableFuture<String> enableControlAsync( String controlIdentifier, String targetIdentifier) { EnableControlRequest request = EnableControlRequest.builder() .controlIdentifier(controlIdentifier) .targetIdentifier(targetIdentifier) .build(); return getAsyncClient().enableControl(request) .thenCompose(response -> { String operationId = response.operationIdentifier(); System.out.println("Enable control operation started. Operation ID: " + operationId); CompletableFuture<String> resultFuture = new CompletableFuture<>(); Runnable poller = new Runnable() { @Override public void run() { getControlOperationAsync(operationId) .thenAccept(status -> { System.out.println("Control operation status: " + status); if (status == ControlOperationStatus.SUCCEEDED || status == ControlOperationStatus.FAILED) { resultFuture.complete(operationId); } else { // Poll again after 30 seconds CompletableFuture.delayedExecutor(30, TimeUnit.SECONDS) .execute(this); } }) .exceptionally(ex -> { resultFuture.completeExceptionally(ex); return null; }); } }; // Start polling immediately poller.run(); return resultFuture; }) .exceptionally(ex -> { Throwable cause = ex.getCause() != null ? ex.getCause() : ex; if (cause instanceof ControlTowerException e) { String errorCode = e.awsErrorDetails().errorCode(); String message = e.getMessage() != null ? e.getMessage() : ""; if ("ValidationException".equals(errorCode) && message.contains("already enabled")) { System.out.println("Control is already enabled for this target"); return null; } if ("ResourceNotFoundException".equals(errorCode) && message.contains("not registered with AWS Control Tower")) { System.out.println( "Control Tower must be enabled to work with controls."); return null; } throw new CompletionException( "Couldn't enable control: %s".formatted(message), e ); } if (cause instanceof SdkException) { throw new CompletionException( "SDK error enabling control: %s" .formatted(cause.getMessage()), cause ); } throw new CompletionException( "Failed to enable control", cause ); }); }
  • Pour plus de détails sur l'API, reportez-vous EnableControlà la section Référence des AWS SDK for Java 2.x API.

L'exemple de code suivant montre comment utiliserGetBaselineOperation.

SDK pour Java 2.x
Note

Il y en a plus à ce sujet GitHub. Trouvez l’exemple complet et découvrez comment le configurer et l’exécuter dans le référentiel d’exemples de code AWS.

/** * Gets the status of a baseline operation. * * @param operationIdentifier the identifier of the operation * @return the operation status * @throws ControlTowerException if a service-specific error occurs * @throws SdkException if an SDK error occurs */ public CompletableFuture<BaselineOperationStatus> getBaselineOperationAsync( String operationIdentifier) { GetBaselineOperationRequest request = GetBaselineOperationRequest.builder() .operationIdentifier(operationIdentifier) .build(); return getAsyncClient().getBaselineOperation(request) .whenComplete((response, exception) -> { if (exception != null) { Throwable cause = exception.getCause() != null ? exception.getCause() : exception; if (cause instanceof ControlTowerException e) { String errorCode = e.awsErrorDetails().errorCode(); if ("ResourceNotFoundException".equals(errorCode)) { throw new CompletionException( "Baseline operation not found: %s" .formatted(e.getMessage()), e ); } throw new CompletionException( "Error getting baseline operation status: %s" .formatted(e.getMessage()), e ); } if (cause instanceof SdkException) { throw new CompletionException( "SDK error getting baseline operation status: %s" .formatted(cause.getMessage()), cause ); } throw new CompletionException( "Failed to get baseline operation status", cause ); } }) .thenApply(response -> { BaselineOperationStatus status = response.baselineOperation().status(); return status; }); }
  • Pour plus de détails sur l'API, reportez-vous GetBaselineOperationà la section Référence des AWS SDK for Java 2.x API.

L'exemple de code suivant montre comment utiliserGetControlOperation.

SDK pour Java 2.x
Note

Il y en a plus à ce sujet GitHub. Trouvez l’exemple complet et découvrez comment le configurer et l’exécuter dans le référentiel d’exemples de code AWS.

/** * Gets the status of a control operation. * * @param operationIdentifier the identifier of the operation * @return the operation status * @throws ControlTowerException if a service-specific error occurs * @throws SdkException if an SDK error occurs */ public CompletableFuture<ControlOperationStatus> getControlOperationAsync( String operationIdentifier) { GetControlOperationRequest request = GetControlOperationRequest.builder() .operationIdentifier(operationIdentifier) .build(); return getAsyncClient().getControlOperation(request) .whenComplete((response, exception) -> { if (exception != null) { Throwable cause = exception.getCause() != null ? exception.getCause() : exception; if (cause instanceof ControlTowerException e) { String errorCode = e.awsErrorDetails().errorCode(); if ("ResourceNotFoundException".equals(errorCode)) { throw new CompletionException( "Control operation not found: %s".formatted(e.getMessage()), e ); } throw new CompletionException( "Error getting control operation status: %s".formatted(e.getMessage()), e ); } if (cause instanceof SdkException) { throw new CompletionException( "SDK error getting control operation status: %s".formatted(cause.getMessage()), cause ); } throw new CompletionException("Failed to get control operation status", cause); } }) .thenApply(response -> response.controlOperation().status()); }
  • Pour plus de détails sur l'API, reportez-vous GetControlOperationà la section Référence des AWS SDK for Java 2.x API.

L'exemple de code suivant montre comment utiliserListBaselines.

SDK pour Java 2.x
Note

Il y en a plus à ce sujet GitHub. Trouvez l’exemple complet et découvrez comment le configurer et l’exécuter dans le référentiel d’exemples de code AWS.

/** * Lists all available baselines using pagination to retrieve complete results. * * @return a list of all baselines * @throws ControlTowerException if a service-specific error occurs * @throws SdkException if an SDK error occurs */ public CompletableFuture<List<BaselineSummary>> listBaselinesAsync() { System.out.println("Starting list baselines paginator…"); ListBaselinesRequest request = ListBaselinesRequest.builder().build(); ListBaselinesPublisher paginator = getAsyncClient().listBaselinesPaginator(request); List<BaselineSummary> baselines = new ArrayList<>(); return paginator.subscribe(response -> { if (response.baselines() != null && !response.baselines().isEmpty()) { response.baselines().forEach(baseline -> { baselines.add(baseline); }); } else { System.out.println("Page contained no baselines."); } }) .thenRun(() -> System.out.println("Successfully listed baselines. Total: " + baselines.size()) ) .thenApply(v -> baselines) .exceptionally(ex -> { Throwable cause = ex.getCause() != null ? ex.getCause() : ex; if (cause instanceof ControlTowerException e) { String errorCode = e.awsErrorDetails().errorCode(); if ("AccessDeniedException".equals(errorCode)) { throw new CompletionException( "Access denied when listing baselines: %s".formatted(e.getMessage()), e ); } throw new CompletionException( "Error listing baselines: %s".formatted(e.getMessage()), e ); } if (cause instanceof SdkException) { throw new CompletionException( "SDK error listing baselines: %s".formatted(cause.getMessage()), cause ); } throw new CompletionException("Failed to list baselines", cause); }); }
  • Pour plus de détails sur l'API, reportez-vous ListBaselinesà la section Référence des AWS SDK for Java 2.x API.

L'exemple de code suivant montre comment utiliserListEnabledBaselines.

SDK pour Java 2.x
Note

Il y en a plus à ce sujet GitHub. Trouvez l’exemple complet et découvrez comment le configurer et l’exécuter dans le référentiel d’exemples de code AWS.

/** * Lists all enabled baselines using pagination to retrieve complete results. * * @return a list of all enabled baselines * @throws ControlTowerException if a service-specific error occurs * @throws SdkException if an SDK error occurs */ public CompletableFuture<List<EnabledBaselineSummary>> listEnabledBaselinesAsync() { System.out.println("Starting list enabled baselines paginator…"); ListEnabledBaselinesRequest request = ListEnabledBaselinesRequest.builder().build(); ListEnabledBaselinesPublisher paginator = getAsyncClient().listEnabledBaselinesPaginator(request); List<EnabledBaselineSummary> enabledBaselines = new ArrayList<>(); return paginator.subscribe(response -> { if (response.enabledBaselines() != null && !response.enabledBaselines().isEmpty()) { response.enabledBaselines().forEach(baseline -> { enabledBaselines.add(baseline); }); } else { System.out.println("Page contained no enabled baselines."); } }) .thenRun(() -> System.out.println( "Successfully listed enabled baselines. Total: " + enabledBaselines.size() ) ) .thenApply(v -> enabledBaselines) .exceptionally(ex -> { Throwable cause = ex.getCause() != null ? ex.getCause() : ex; if (cause instanceof ControlTowerException e) { String errorCode = e.awsErrorDetails().errorCode(); if ("AccessDeniedException".equals(errorCode)) { throw new CompletionException( "Access denied when listing enabled baselines: %s".formatted(e.getMessage()), e); } throw new CompletionException( "Error listing enabled baselines: %s" .formatted(e.getMessage()), e ); } if (cause instanceof SdkException) { throw new CompletionException( "SDK error listing enabled baselines: %s" .formatted(cause.getMessage()), cause ); } throw new CompletionException( "Failed to list enabled baselines", cause ); }); }
  • Pour plus de détails sur l'API, reportez-vous ListEnabledBaselinesà la section Référence des AWS SDK for Java 2.x API.

L'exemple de code suivant montre comment utiliserListEnabledControls.

SDK pour Java 2.x
Note

Il y en a plus à ce sujet GitHub. Trouvez l’exemple complet et découvrez comment le configurer et l’exécuter dans le référentiel d’exemples de code AWS.

/** * Lists all enabled controls for a specific target using pagination. * * @param targetIdentifier the identifier of the target (e.g., OU ARN) * @return a list of enabled controls * @throws ControlTowerException if a service-specific error occurs * @throws SdkException if an SDK error occurs */ public CompletableFuture<List<EnabledControlSummary>> listEnabledControlsAsync(String targetIdentifier) { System.out.println("Starting list enabled controls paginator for target " + targetIdentifier); ListEnabledControlsRequest request = ListEnabledControlsRequest.builder() .targetIdentifier(targetIdentifier) .build(); ListEnabledControlsPublisher paginator = getAsyncClient().listEnabledControlsPaginator(request); List<EnabledControlSummary> enabledControls = new ArrayList<>(); // Subscribe to the paginator asynchronously return paginator.subscribe(response -> { if (response.enabledControls() != null && !response.enabledControls().isEmpty()) { response.enabledControls().forEach(control -> { enabledControls.add(control); }); } else { System.out.println("Page contained no enabled controls."); } }) .thenRun(() -> System.out.println( "Successfully retrieved "+enabledControls.size() +" enabled controls for target "+targetIdentifier )) .thenApply(v -> enabledControls) .exceptionally(ex -> { Throwable cause = ex.getCause() != null ? ex.getCause() : ex; if (cause instanceof ControlTowerException e) { String errorCode = e.awsErrorDetails().errorCode(); switch (errorCode) { case "AccessDeniedException": throw new CompletionException( "Access denied when listing enabled controls: %s".formatted(e.getMessage()), e); case "ResourceNotFoundException": if (e.getMessage() != null && e.getMessage().contains("not registered with AWS Control Tower")) { throw new CompletionException( "Control Tower must be enabled to work with controls", e); } throw new CompletionException( "Target not found when listing enabled controls: %s".formatted(e.getMessage()), e); default: throw new CompletionException( "Error listing enabled controls: %s".formatted(e.getMessage()), e); } } if (cause instanceof SdkException) { throw new CompletionException( "SDK error listing enabled controls: %s".formatted(cause.getMessage()), cause); } throw new CompletionException("Failed to list enabled controls", cause); }); }
  • Pour plus de détails sur l'API, reportez-vous ListEnabledControlsà la section Référence des AWS SDK for Java 2.x API.

L'exemple de code suivant montre comment utiliserListLandingZones.

SDK pour Java 2.x
Note

Il y en a plus à ce sujet GitHub. Trouvez l’exemple complet et découvrez comment le configurer et l’exécuter dans le référentiel d’exemples de code AWS.

/** * Lists all landing zones using pagination to retrieve complete results. * * @return a list of all landing zones * @throws ControlTowerException if a service-specific error occurs * @throws SdkException if an SDK error occurs */ public CompletableFuture<List<LandingZoneSummary>> listLandingZonesAsync() { System.out.println("Starting list landing zones paginator…"); ListLandingZonesRequest request = ListLandingZonesRequest.builder().build(); ListLandingZonesPublisher paginator = getAsyncClient().listLandingZonesPaginator(request); List<LandingZoneSummary> landingZones = new ArrayList<>(); return paginator.subscribe(response -> { if (response.landingZones() != null && !response.landingZones().isEmpty()) { response.landingZones().forEach(lz -> { System.out.println("Landing zone ARN: " + lz.arn()); landingZones.add(lz); }); } else { System.out.println("Page contained no landing zones."); } }) .thenRun(() -> System.out.println("Successfully retrieved "+ landingZones.size() + " landing zones." )) .thenApply(v -> landingZones) .exceptionally(ex -> { Throwable cause = ex.getCause() != null ? ex.getCause() : ex; if (cause instanceof ControlTowerException e) { String errorCode = e.awsErrorDetails().errorCode(); switch (errorCode) { case "AccessDeniedException": throw new CompletionException( "Access denied when listing landing zones: " + e.getMessage(), e); default: throw new CompletionException( "Error listing landing zones: " + e.getMessage(), e); } } if (cause instanceof SdkException) { throw new CompletionException( "SDK error listing landing zones: " + cause.getMessage(), cause); } throw new CompletionException("Failed to list landing zones", cause); }); }
  • Pour plus de détails sur l'API, reportez-vous ListLandingZonesà la section Référence des AWS SDK for Java 2.x API.

L'exemple de code suivant montre comment utiliserResetEnabledBaseline.

SDK pour Java 2.x
Note

Il y en a plus à ce sujet GitHub. Trouvez l’exemple complet et découvrez comment le configurer et l’exécuter dans le référentiel d’exemples de code AWS.

/** * Resets an enabled baseline for a specific target. * * @param enabledBaselineIdentifier the identifier of the enabled baseline to reset * @return the operation identifier * @throws ControlTowerException if a service-specific error occurs * @throws SdkException if an SDK error occurs */ public CompletableFuture<String> resetEnabledBaselineAsync(String enabledBaselineIdentifier) { System.out.println("Starting reset of enabled baseline…"); System.out.println("This operation will check the status every 15 seconds until it completes (SUCCEEDED or FAILED)."); ResetEnabledBaselineRequest request = ResetEnabledBaselineRequest.builder() .enabledBaselineIdentifier(enabledBaselineIdentifier) .build(); return getAsyncClient().resetEnabledBaseline(request) .thenCompose(response -> { String operationId = response.operationIdentifier(); System.out.println("Reset enabled baseline operation ID: " + operationId); // Polling loop CompletableFuture<String> resultFuture = new CompletableFuture<>(); Runnable poller = new Runnable() { @Override public void run() { getBaselineOperationAsync(operationId) .thenAccept(statusObj -> { String status = statusObj.toString(); // Convert enum/status to string for printing System.out.println("Current baseline operation status: " + status + " → waiting for SUCCEEDED or FAILED..."); if ("SUCCEEDED".equalsIgnoreCase(status) || "FAILED".equalsIgnoreCase(status)) { System.out.println("Baseline operation finished with status: " + status); resultFuture.complete(operationId); } else { // Schedule next poll in 15 seconds CompletableFuture.delayedExecutor(15, TimeUnit.SECONDS) .execute(this); } }) .exceptionally(ex -> { System.out.println("Error checking baseline operation status: " + ex.getMessage()); resultFuture.completeExceptionally(ex); return null; }); } }; // Start first poll immediately poller.run(); return resultFuture; }) .exceptionally(ex -> { Throwable cause = ex.getCause() != null ? ex.getCause() : ex; if (cause instanceof ControlTowerException e) { String errorCode = e.awsErrorDetails() != null ? e.awsErrorDetails().errorCode() : "UNKNOWN"; String errorMessage = e.awsErrorDetails() != null ? e.awsErrorDetails().errorMessage() : e.getMessage(); System.out.println("ControlTowerException caught: Code=" + errorCode + ", Message=" + errorMessage); return null; } if (cause instanceof SdkException sdkEx) { System.out.println("SDK exception caught: " + sdkEx.getMessage()); return null; } System.out.println("Unexpected exception resetting baseline: " + cause.getMessage()); return null; }); }
  • Pour plus de détails sur l'API, reportez-vous ResetEnabledBaselineà la section Référence des AWS SDK for Java 2.x API.