private Optional clientEndpointFromServiceMetadata()

in core/aws-core/src/main/java/software/amazon/awssdk/awscore/endpoint/AwsClientEndpointProvider.java [183:258]


    private Optional<ClientEndpoint> clientEndpointFromServiceMetadata(Builder builder) {
        // This value is generally overridden after endpoints 2.0. It seems to exist for backwards-compatibility
        // with older client versions or interceptors.

        if (builder.serviceEndpointPrefix == null ||
            builder.region == null ||
            builder.protocol == null) {
            // Make sure that people didn't set just one value and expect it to be used.
            Validate.isTrue(builder.serviceEndpointPrefix == null &&
                            builder.region == null &&
                            builder.protocol == null,
                            "If any of the service endpoint prefix, region or protocol are configured, they must all "
                            + "be configured.");
            log.trace(() -> "Service metadata was not checked for client endpoint.");
            return Optional.empty();
        }

        Validate.paramNotNull(builder.serviceEndpointPrefix, "serviceName");
        Validate.paramNotNull(builder.region, "region");
        Validate.paramNotNull(builder.protocol, "protocol");

        initializeProfileFileDefaults(builder);

        if (builder.dualstackEnabled == null) {
            builder.dualstackEnabled = DualstackEnabledProvider.builder()
                                                               .profileFile(builder.profileFile)
                                                               .profileName(builder.profileName)
                                                               .build()
                                                               .isDualstackEnabled()
                                                               .orElse(false);
        }

        if (builder.fipsEnabled == null) {
            builder.fipsEnabled = FipsEnabledProvider.builder()
                                                     .profileFile(builder.profileFile)
                                                     .profileName(builder.profileName)
                                                     .build()
                                                     .isFipsEnabled()
                                                     .orElse(false);
        }

        List<EndpointTag> endpointTags = new ArrayList<>();
        if (builder.dualstackEnabled) {
            endpointTags.add(EndpointTag.DUALSTACK);
        }
        if (builder.fipsEnabled) {
            endpointTags.add(EndpointTag.FIPS);
        }

        ServiceMetadata serviceMetadata = ServiceMetadata.of(builder.serviceEndpointPrefix)
                                                         .reconfigure(c -> c.profileFile(builder.profileFile)
                                                                            .profileName(builder.profileName)
                                                                            .advancedOptions(builder.advancedOptions));
        URI endpointWithoutProtocol =
            serviceMetadata.endpointFor(ServiceEndpointKey.builder()
                                                          .region(builder.region)
                                                          .tags(endpointTags)
                                                          .build());
        URI endpoint = URI.create(builder.protocol + "://" + endpointWithoutProtocol);
        if (endpoint.getHost() == null) {
            String error = "Configured region (" + builder.region + ") and tags (" + endpointTags + ") resulted in "
                           + "an invalid URI: " + endpoint + ". This is usually caused by an invalid region "
                           + "configuration.";

            List<Region> exampleRegions = serviceMetadata.regions();
            if (!exampleRegions.isEmpty()) {
                error += " Valid regions: " + exampleRegions;
            }

            throw SdkClientException.create(error);
        }

        log.trace(() -> "Client endpoint was loaded from service metadata, but this endpoint will likely be overridden "
                        + "at the request-level by the endpoint resolver: " + endpoint);
        return Optional.of(new ClientEndpoint(endpoint, false));
    }