Aws-sdk-java: com.amazonaws.SdkClientException: Unable to find a region via the region provider chain. Must provide an explicit region in the builder or setup environment to supply a region.

Created on 26 Jul 2019  路  2Comments  路  Source: aws/aws-sdk-java

I am trying to connect to AWS IoT. But it fails saying "com.amazonaws.SdkClientException: Unable to find a region via the region provider chain. Must provide an explicit region in the builder or setup environment to supply a region."
This error occurs on the following line in the code.

    public IotHelper() {
        this(AWSSecurityTokenServiceClientBuilder.defaultClient());
    }

```.
/*This function mainly creates a connection of the MtoH Service with the AWS IoT. It also publishes and subscribes to
the respective topics. */
public class IotHelper {

private static final Logger logger = LogManager.getLogger(IotHelper.class);

private final AWSSecurityTokenService stsClient;

private static final String CLIENT_ENDPOINT = "...";
private static final int STS_ASSUME_ROLE_DURATION_SECONDS = 3600;
// Note: this value must be <= 28 characters in order to satisfy STS session constraints
private static final String AIS_LAMBDA_MQTT_CLIENT_PREFIX = "...";
private static final String ASSUME_ROLE = "....";
private static final AWSIotQos AIS_LAMBDA_IOT_QOS = AWSIotQos.QOS1;

public static void main(String[] args) {
    IotHelper iotHelper = new IotHelper();
    iotHelper.generateIotClient(CLIENT_ENDPOINT,ASSUME_ROLE);
}
public IotHelper() {
    this(AWSSecurityTokenServiceClientBuilder.defaultClient());
}

@VisibleForTesting
public IotHelper(@NonNull final AWSSecurityTokenService stsClient) {
    this.stsClient = stsClient;
}

public AWSIotMqttClient generateIotClient(final String clientEndpoint, final String assumeRoleArn) {
    if (StringUtils.isAnyBlank(clientEndpoint, assumeRoleArn)) {
        logger.debug(String.format("Missing required param to generate IoT MQTT client: %s, %s", clientEndpoint,
                assumeRoleArn));
        throw new IllegalArgumentException("Missing required param to generate IoT MQTT client");
    }
    logger.info("Generating IoT client");
    logger.debug(String.format("Generating IoT client using IoT endpoint %s and assumeRoleArn %s", clientEndpoint,
            assumeRoleArn));
    final String clientId = AIS_LAMBDA_MQTT_CLIENT_PREFIX + "-" + UUID.randomUUID();
    final Credentials credentials = assumeRole(assumeRoleArn, clientId);
    final AWSIotMqttClient client = new AWSIotMqttClient(clientEndpoint, clientId, credentials.getAccessKeyId(),
            credentials.getSecretAccessKey(),
            credentials.getSessionToken());
    try {
        client.connect();
        System.out.println("Successfully created IoT client: " + client);
    } catch (AWSIotException ex) {
        throw new IotException(ex);
    }
    return client;
}

private Credentials assumeRole(final String assumeRoleArn, final String session) {
    logger.info("Assuming role using session " + session);
    logger.debug("Assuming role for " + assumeRoleArn);
    final AssumeRoleRequest assumeRoleRequest = new AssumeRoleRequest()
            .withRoleArn(assumeRoleArn)
            .withRoleSessionName(session)
            .withDurationSeconds(STS_ASSUME_ROLE_DURATION_SECONDS);
    final AssumeRoleResult assumeRoleResult = stsClient.assumeRole(assumeRoleRequest);
    logger.info("Successfully got AssumeRoleResult");
    logger.debug("Got this AssumeRoleResult: " + assumeRoleResult);
    return assumeRoleResult.getCredentials();
}

public void publishToIot(final AWSIotMqttClient iotClient, final String topic, final String message) {
    if (iotClient == null || StringUtils.isAnyBlank(topic, message)) {
        logger.debug(String.format("Missing required param to publish to IoT: %s, %s, %s", iotClient, topic,
                message));
        throw new IllegalArgumentException("Missing required param to publish to IoT");
    }

    logger.info("Attempting to publish to IoT using message: " + message);
    logger.debug("Attempting to publish to IoT using topic: " + topic);
    try {
        iotClient.publish(topic, AIS_LAMBDA_IOT_QOS, message);
        logger.info("Finished publishing message");
    } catch (AWSIotException ex) {
        throw new IotException(ex);
    }
}

public void subscribeToIot(final AWSIotMqttClient iotClient, final AWSIotTopic topic) {
    if (iotClient == null || topic == null) {
        logger.debug(String.format("Missing required param to subscribe to IoT using IoT client: %s, topic: %s",
                iotClient, topic));
        throw new IllegalArgumentException("Missing required param to subscribe to IoT");
    }

    logger.info("Attempting to subscribe to IoT using iotClient: " + iotClient);
    logger.debug("Attempting to publish to IoT using topic: " + topic);
    try {
        iotClient.subscribe(topic);
        logger.info("Finished subscription");
    } catch (AWSIotException ex) {
        throw new IotException(ex);
    }
}

}
```

Do I need to specify some region?

closing-soon guidance

Most helpful comment

Hi @abhigithub911, to connect programmatically to an AWS service, you need an endpoint and a region supported by that service. In the SDK, the region can be explicitly set in the client builder using a withRegion method:

 public IotHelper() {
        this(AWSSecurityTokenServiceClientBuilder.standard()
                .withRegion(Regions.US_WEST_2)
                .build());

or you can define it as an environment variable. Please see AWS Region Selection page for more info on region configuration, and AWS Service Endpoints page for a list of services and supported regions.

All 2 comments

Hi @abhigithub911, to connect programmatically to an AWS service, you need an endpoint and a region supported by that service. In the SDK, the region can be explicitly set in the client builder using a withRegion method:

 public IotHelper() {
        this(AWSSecurityTokenServiceClientBuilder.standard()
                .withRegion(Regions.US_WEST_2)
                .build());

or you can define it as an environment variable. Please see AWS Region Selection page for more info on region configuration, and AWS Service Endpoints page for a list of services and supported regions.

Closing, feel free to reopen if you have further questions.

Was this page helpful?
0 / 5 - 0 ratings