Controller extends AbstractComponent { public ApplicationController applications() { return applicationController; } @Inject  Controller(CuratorDb curator, RotationsConfig rotationsConfig, AccessControl accessControl, FlagSource flagSource,
                      MavenRepository mavenRepository, ServiceRegistry serviceRegistry, Metric metric, SecretStore secretStore,
                      ControllerConfig controllerConfig);  Controller(CuratorDb curator, RotationsConfig rotationsConfig, AccessControl accessControl,
                      Supplier<String> hostnameSupplier, FlagSource flagSource, MavenRepository mavenRepository,
                      ServiceRegistry serviceRegistry, Metric metric, SecretStore secretStore, ControllerConfig controllerConfig); TenantController tenants(); ApplicationController applications(); JobController jobController(); RoutingController routing(); ServiceRegistry serviceRegistry(); FlagSource flagSource(); Clock clock(); ZoneRegistry zoneRegistry(); NameServiceForwarder nameServiceForwarder(); MavenRepository mavenRepository(); ControllerConfig controllerConfig(); ApplicationView getApplicationView(String tenantName, String applicationName, String instanceName,
                                              String environment, String region); void updateVersionStatus(VersionStatus newStatus); VersionStatus versionStatus(); void removeConfidenceOverride(Predicate<Version> filter); Version systemVersion(); Optional<OsVersionTarget> osVersionTarget(CloudName cloud); Set<OsVersionTarget> osVersionTargets(); void upgradeOsIn(CloudName cloudName, Version version, Optional<Duration> upgradeBudget, boolean force); OsVersionStatus osVersionStatus(); void updateOsVersionStatus(OsVersionStatus newStatus); HostName hostname(); ConfigServerMetrics metrics(); SystemName system(); CuratorDb curator(); AuditLogger auditLogger(); Metric metric(); JobControl jobControl();  }
@Test public void testChangeEndpointCluster() { var context = tester.newDeploymentContext(); var west = ZoneId.from("prod", "us-west-1"); var east = ZoneId.from("prod", "us-east-3"); var applicationPackage = new ApplicationPackageBuilder() .environment(Environment.prod) .endpoint("default", "foo") .region(west.region().value()) .region(east.region().value()) .build(); context.submit(applicationPackage).deploy(); assertEquals(ClusterSpec.Id.from("foo"), tester.applications().requireInstance(context.instanceId()) .rotations().get(0).clusterId()); applicationPackage = new ApplicationPackageBuilder() .environment(Environment.prod) .endpoint("default", "bar") .region(west.region().value()) .region(east.region().value()) .build(); try { context.submit(applicationPackage).deploy(); fail("Expected exception"); } catch (IllegalArgumentException e) { assertEquals("global-endpoint-change: application 'tenant.application' has endpoints [endpoint " + "'default' (cluster foo) -> us-east-3, us-west-1], but does not include all of these in " + "deployment.xml. Deploying given deployment.xml will remove " + "[endpoint 'default' (cluster foo) -> us-east-3, us-west-1] and add " + "[endpoint 'default' (cluster bar) -> us-east-3, us-west-1]. To allow this add " + "<allow until='yyyy-mm-dd'>global-endpoint-change</allow> to validation-overrides.xml, see " + "https: } applicationPackage = new ApplicationPackageBuilder() .environment(Environment.prod) .endpoint("default", "bar") .region(west.region().value()) .region(east.region().value()) .allow(ValidationId.globalEndpointChange) .build(); context.submit(applicationPackage).deploy(); assertEquals(ClusterSpec.Id.from("bar"), tester.applications().requireInstance(context.instanceId()) .rotations().get(0).clusterId()); }