I am using AWS DynamoDB for the first time and having some problems with it running on an EC2 instance. I reviewed the AWS examples and found a simple Java CRUD example. I got it working very quickly using Eclipse Java Spring Boot and AWS DynamoDB running in the cloud. I ran it on my desktop using static access credentials. I had to include in the applications.properties page, "cloud.aws.region.static = us-west-2". It accessed the AWS Cloud-based DynamoDB service with no problems. I then commented out the "cloud.aws.region.static = us-west-2" and ran the exact same Java Spring-Boot microservice on an EC2 instance. I got a number of errors but all seem to point to an inability to access DynamoDB credential provider chain. I know static credentials are not the recommended approach for security reasons but I don't understand why this is not working. Any ideas?
Application Code:
package com.belcan;
import java.util.HashMap;
import java.util.Map;
import com.amazonaws.AmazonClientException;
import com.amazonaws.AmazonServiceException;
import com.amazonaws.auth.AWSStaticCredentialsProvider;
import com.amazonaws.auth.BasicAWSCredentials;
import com.amazonaws.services.dynamodbv2.AmazonDynamoDB;
import com.amazonaws.services.dynamodbv2.AmazonDynamoDBClientBuilder;
import com.amazonaws.services.dynamodbv2.model.AttributeDefinition;
import com.amazonaws.services.dynamodbv2.model.AttributeValue;
import com.amazonaws.services.dynamodbv2.model.ComparisonOperator;
import com.amazonaws.services.dynamodbv2.model.Condition;
import com.amazonaws.services.dynamodbv2.model.CreateTableRequest;
import com.amazonaws.services.dynamodbv2.model.DescribeTableRequest;
import com.amazonaws.services.dynamodbv2.model.KeySchemaElement;
import com.amazonaws.services.dynamodbv2.model.KeyType;
import com.amazonaws.services.dynamodbv2.model.ProvisionedThroughput;
import com.amazonaws.services.dynamodbv2.model.PutItemRequest;
import com.amazonaws.services.dynamodbv2.model.PutItemResult;
import com.amazonaws.services.dynamodbv2.model.ScalarAttributeType;
import com.amazonaws.services.dynamodbv2.model.ScanRequest;
import com.amazonaws.services.dynamodbv2.model.ScanResult;
import com.amazonaws.services.dynamodbv2.model.TableDescription;
import com.amazonaws.services.dynamodbv2.util.TableUtils;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
@SpringBootApplication
public class DynamoDbExampleWarApplication {
static String awsaccesskeyid = "bla-bla-bal";
static String awssecretkey = "yadi-yadi-yada";
static AmazonDynamoDB dynamoDB;
public static void init() {
try {
BasicAWSCredentials myCredentials = new BasicAWSCredentials(awsaccesskeyid, awssecretkey);
dynamoDB = AmazonDynamoDBClientBuilder.standard()
.withCredentials(new AWSStaticCredentialsProvider(myCredentials))
.withRegion("us-west-2")
.build();
} catch (Exception e) {
throw new AmazonClientException(
"Init1(): Cannot load the credentials from the credential profiles file. " + toString.e);
}
}
public static void main(String[] args) {
SpringApplication.run(DynamoDbExampleWarApplication.class, args);
// Get Amazon DynamoDB Client
init();
try {
String tableName = "my-favorite-movies-table";
// Create a table with a primary hash key named 'name', which holds a string
CreateTableRequest createTableRequest = new CreateTableRequest().withTableName(tableName)
.withKeySchema(new KeySchemaElement().withAttributeName("name").withKeyType(KeyType.HASH))
.withAttributeDefinitions(new AttributeDefinition().withAttributeName("name").withAttributeType(ScalarAttributeType.S))
.withProvisionedThroughput(new ProvisionedThroughput().withReadCapacityUnits(1L).withWriteCapacityUnits(1L));
// Create table if it does not exist yet
TableUtils.createTableIfNotExists(dynamoDB, createTableRequest);
// wait for the table to move into ACTIVE state
try {
TableUtils.waitUntilActive(dynamoDB, tableName);
} catch (Exception e) {
System.out.println("Table Error");
}
// Describe our new table
DescribeTableRequest describeTableRequest = new DescribeTableRequest().withTableName(tableName);
TableDescription tableDescription = dynamoDB.describeTable(describeTableRequest).getTable();
System.out.println("Table Description: " + tableDescription);
// Add an item
Map<String, AttributeValue> item = newItem("Bill & Ted's Excellent Adventure", 1989, "****", "James", "Sara");
PutItemRequest putItemRequest = new PutItemRequest(tableName, item);
PutItemResult putItemResult = dynamoDB.putItem(putItemRequest);
System.out.println("Result: " + putItemResult);
// Add another item
item = newItem("Airplane", 1980, "*****", "James", "Billy Bob");
putItemRequest = new PutItemRequest(tableName, item);
putItemResult = dynamoDB.putItem(putItemRequest);
System.out.println("Result: " + putItemResult);
// Scan items for movies with a year attribute greater than 1985
HashMap<String, Condition> scanFilter = new HashMap<String, Condition>();
Condition condition = new Condition()
.withComparisonOperator(ComparisonOperator.GT.toString())
.withAttributeValueList(new AttributeValue().withN("1985"));
scanFilter.put("year", condition);
ScanRequest scanRequest = new ScanRequest(tableName).withScanFilter(scanFilter);
ScanResult scanResult = dynamoDB.scan(scanRequest);
System.out.println("Result: " + scanResult);
} catch (AmazonServiceException ase) {
System.out.println("Caught an AmazonServiceException, which means your request made it "
+ "to AWS, but was rejected with an error response for some reason.");
System.out.println("Error Message: " + ase.getMessage());
System.out.println("HTTP Status Code: " + ase.getStatusCode());
System.out.println("AWS Error Code: " + ase.getErrorCode());
System.out.println("Error Type: " + ase.getErrorType());
System.out.println("Request ID: " + ase.getRequestId());
} catch (AmazonClientException ace) {
System.out.println("Caught an AmazonClientException, which means the client encountered "
+ "a serious internal problem while trying to communicate with AWS, "
+ "such as not being able to access the network.");
System.out.println("Error Message: " + ace.getMessage());
}
}
public static Map<String, AttributeValue> newItem(String name, int year, String rating, String... fans) {
Map<String, AttributeValue> item = new HashMap<String, AttributeValue>();
item.put("name", new AttributeValue(name));
item.put("year", new AttributeValue().withN(Integer.toString(year)));
item.put("rating", new AttributeValue(rating));
item.put("fans", new AttributeValue().withSS(fans));
return item;
}
}
Here is the EC2 Linux Error String,
[ec2-user@ip-10-0-0-244 server]$ java -jar DynamoDBExample-war-v001.war
. ____ _ __ _ _
/\\ / ___'_ __ _ _(_)_ __ __ _ \ \ \ \
( ( )\___ | '_ | '_| | '_ \/ _` | \ \ \ \
\\/ ___)| |_)| | | | | || (_| | ) ) ) )
' |____| .__|_| |_|_| |_\__, | / / / /
=========|_|==============|___/=/_/_/_/
:: Spring Boot :: (v1.5.9.RELEASE)
....Deleted a lot of messages to try to keep the message length as short as possible.
2017-12-20 15:03:32.187 INFO 7372 --- [ main] c.belcan.DynamoDbExampleWarApplication : Starting DynamoDbExampleWarApplication on ip-10-0-0-244 with PID 7372 (/home/ec2-user/server/DynamoDBExample-war-v001.war started by ec2-user in /home/ec2-user/server)
2017-12-20 15:03:32.190 INFO 7372 --- [ main] c.belcan.DynamoDbExampleWarApplication : No active profile set, falling back to default profiles: default
2017-12-20 15:03:32.243 INFO 7372 --- [ main] ationConfigEmbeddedWebApplicationContext : Refreshing org.springframework.boot.context.embedded.AnnotationConfigEmbeddedWebApplicationContext@30946e09: startup date [Wed Dec 20 15:03:32 UTC 2017]; root of context hierarchy
2017-12-20 15:03:34.568 INFO 7372 --- [ main] o.s.aop.framework.CglibAopProxy : Final method [protected final com.amazonaws.services.s3.model.InitiateMultipartUploadRequest com.amazonaws.services.s3.AmazonS3Client.newInitiateMultipartUploadRequest(com.amazonaws.services.s3.model.UploadObjectRequest)] cannot get proxied via CGLIB: Calls to this method will NOT be routed to the target instance and might lead to
2017-12-20 15:03:36.530 INFO 7372 --- [ main] s.w.s.m.m.a.RequestMappingHandlerAdapter : Looking for @ControllerAdvice: org.springframework.boot.context.embedded.AnnotationConfigEmbeddedWebApplicationContext@30946e09: startup date [Wed Dec 20 15:03:32 UTC 2017]; root of context hierarchy
2017-12-20 15:03:36.616 INFO 7372 --- [ main] s.w.s.m.m.a.RequestMappingHandlerMapping : Mapped "{[/error],produces=[text/html]}" onto public org.springframework.web.servlet.ModelAndView org.springframework.boot.autoconfigure.web.BasicErrorController.errorHtml(javax.servlet.http.HttpServletRequest,javax.servlet.http.HttpServletResponse)
2017-12-20 15:03:36.618 INFO 7372 --- [ main] s.w.s.m.m.a.RequestMappingHandlerMapping : Mapped "{[/error]}" onto public org.springframework.http.ResponseEntity<java.util.Map<java.lang.String, java.lang.Object>> org.springframework.boot.autoconfigure.web.BasicErrorController.error(javax.servlet.http.HttpServletRequest)
2017-12-20 15:03:36.657 INFO 7372 --- [ main] o.s.w.s.handler.SimpleUrlHandlerMapping : Mapped URL path [/webjars/**] onto handler of type [class org.springframework.web.servlet.resource.ResourceHttpRequestHandler]
2017-12-20 15:03:36.657 INFO 7372 --- [ main] o.s.w.s.handler.SimpleUrlHandlerMapping : Mapped URL path [/**] onto handler of type [class org.springframework.web.servlet.resource.ResourceHttpRequestHandler]
2017-12-20 15:03:36.707 INFO 7372 --- [ main] o.s.w.s.handler.SimpleUrlHandlerMapping : Mapped URL path [/**/favicon.ico] onto handler of type [class org.springframework.web.servlet.resource.ResourceHttpRequestHandler]
2017-12-20 15:03:36.951 INFO 7372 --- [ main] b.a.s.AuthenticationManagerConfiguration :
Using default security password: 1cadad8f-e5f6-44ed-a2fd-6df59c36010a
2017-12-20 15:03:37.008 INFO 7372 --- [ main] o.s.s.web.DefaultSecurityFilterChain : Creating filter chain: OrRequestMatcher [requestMatchers=[Ant [pattern='/css/**'], Ant [pattern='/js/**'], Ant [pattern='/images/**'], Ant [pattern='/webjars/**'], Ant [pattern='/**/favicon.ico'], Ant [pattern='/error']]], []
2017-12-20 15:03:37.287 INFO 7372 --- [ main] o.s.b.a.e.mvc.EndpointHandlerMapping : Mapped "{[/dump || /dump.json],methods=[GET],produces=[application/vnd.spring-boot.actuator.v1+json || application/json]}" onto public java.lang.Object org.springframework.boot.actuate.endpoint.mvc.EndpointMvcAdapter.invoke()
2017-12-20 15:03:37.289 INFO 7372 --- [ main] o.s.b.a.e.mvc.EndpointHandlerMapping : Mapped "{[/metrics/{name:.*}],methods=[GET],produces=[application/vnd.spring-boot.actuator.v1+json || application/json]}" onto public java.lang.Object org.springframework.boot.actuate.endpoint.mvc.MetricsMvcEndpoint.value(java.lang.String)
2017-12-20 15:03:37.290 INFO 7372 --- [ main] o.s.b.a.e.mvc.EndpointHandlerMapping : Mapped "{[/metrics || /metrics.json],methods=[GET],produces=[application/vnd.spring-boot.actuator.v1+json || application/json]}" onto public java.lang.Object org.springframework.boot.actuate.endpoint.mvc.EndpointMvcAdapter.invoke()
2017-12-20 15:03:37.290 INFO 7372 --- [ main] o.s.b.a.e.mvc.EndpointHandlerMapping : Mapped "{[/configprops || /configprops.json],methods=[GET],produces=[application/vnd.spring-boot.actuator.v1+json || application/json]}" onto public java.lang.Object org.springframework.boot.actuate.endpoint.mvc.EndpointMvcAdapter.invoke()
2017-12-20 15:03:37.291 INFO 7372 --- [ main] o.s.b.a.e.mvc.EndpointHandlerMapping : Mapped "{[/health || /health.json],methods=[GET],produces=[application/vnd.spring-boot.actuator.v1+json || application/json]}" onto public java.lang.Object org.springframework.boot.actuate.endpoint.mvc.HealthMvcEndpoint.invoke(javax.servlet.http.HttpServletRequest,java.security.Principal)
2017-12-20 15:03:37.292 INFO 7372 --- [ main] o.s.b.a.e.mvc.EndpointHandlerMapping : Mapped "{[/beans || /beans.json],methods=[GET],produces=[application/vnd.spring-boot.actuator.v1+json || application/json]}" onto public java.lang.Object org.springframework.boot.actuate.endpoint.mvc.EndpointMvcAdapter.invoke()
2017-12-20 15:03:37.294 INFO 7372 --- [ main] o.s.b.a.e.mvc.EndpointHandlerMapping : Mapped "{[/auditevents || /auditevents.json],methods=[GET],produces=[application/vnd.spring-boot.actuator.v1+json || application/json]}" onto public org.springframework.http.ResponseEntity<?> org.springframework.boot.actuate.endpoint.mvc.AuditEventsMvcEndpoint.findByPrincipalAndAfterAndType(java.lang.String,java.util.Date,java.lang.String)
2017-12-20 15:03:37.297 INFO 7372 --- [ main] o.s.b.a.e.mvc.EndpointHandlerMapping : Mapped "{[/autoconfig || /autoconfig.json],methods=[GET],produces=[application/vnd.spring-boot.actuator.v1+json || application/json]}" onto public java.lang.Object org.springframework.boot.actuate.endpoint.mvc.EndpointMvcAdapter.invoke()
2017-12-20 15:03:37.300 INFO 7372 --- [ main] o.s.b.a.e.mvc.EndpointHandlerMapping : Mapped "{[/loggers/{name:.*}],methods=[GET],produces=[application/vnd.spring-boot.actuator.v1+json || application/json]}" onto public java.lang.Object org.springframework.boot.actuate.endpoint.mvc.LoggersMvcEndpoint.get(java.lang.String)
2017-12-20 15:03:37.300 INFO 7372 --- [ main] o.s.b.a.e.mvc.EndpointHandlerMapping : Mapped "{[/loggers/{name:.*}],methods=[POST],consumes=[application/vnd.spring-boot.actuator.v1+json || application/json],produces=[application/vnd.spring-boot.actuator.v1+json || application/json]}" onto public java.lang.Object org.springframework.boot.actuate.endpoint.mvc.LoggersMvcEndpoint.set(java.lang.String,java.util.Map<java.lang.String, java.lang.String>)
2017-12-20 15:03:37.301 INFO 7372 --- [ main] o.s.b.a.e.mvc.EndpointHandlerMapping : Mapped "{[/loggers || /loggers.json],methods=[GET],produces=[application/vnd.spring-boot.actuator.v1+json || application/json]}" onto public java.lang.Object org.springframework.boot.actuate.endpoint.mvc.EndpointMvcAdapter.invoke()
2017-12-20 15:03:37.301 INFO 7372 --- [ main] o.s.b.a.e.mvc.EndpointHandlerMapping : Mapped "{[/heapdump || /heapdump.json],methods=[GET],produces=[application/octet-stream]}" onto public void org.springframework.boot.actuate.endpoint.mvc.HeapdumpMvcEndpoint.invoke(boolean,javax.servlet.http.HttpServletRequest,javax.servlet.http.HttpServletResponse) throws java.io.IOException,javax.servlet.ServletException
2017-12-20 15:03:37.302 INFO 7372 --- [ main] o.s.b.a.e.mvc.EndpointHandlerMapping : Mapped "{[/trace || /trace.json],methods=[GET],produces=[application/vnd.spring-boot.actuator.v1+json || application/json]}" onto public java.lang.Object org.springframework.boot.actuate.endpoint.mvc.EndpointMvcAdapter.invoke()
2017-12-20 15:03:37.303 INFO 7372 --- [ main] o.s.b.a.e.mvc.EndpointHandlerMapping : Mapped "{[/mappings || /mappings.json],methods=[GET],produces=[application/vnd.spring-boot.actuator.v1+json || application/json]}" onto public java.lang.Object org.springframework.boot.actuate.endpoint.mvc.EndpointMvcAdapter.invoke()
2017-12-20 15:03:37.310 INFO 7372 --- [ main] o.s.b.a.e.mvc.EndpointHandlerMapping : Mapped "{[/info || /info.json],methods=[GET],produces=[application/vnd.spring-boot.actuator.v1+json || application/json]}" onto public java.lang.Object org.springframework.boot.actuate.endpoint.mvc.EndpointMvcAdapter.invoke()
2017-12-20 15:03:37.313 INFO 7372 --- [ main] o.s.b.a.e.mvc.EndpointHandlerMapping : Mapped "{[/env/{name:.*}],methods=[GET],produces=[application/vnd.spring-boot.actuator.v1+json || application/json]}" onto public java.lang.Object org.springframework.boot.actuate.endpoint.mvc.EnvironmentMvcEndpoint.value(java.lang.String)
2017-12-20 15:03:37.313 INFO 7372 --- [ main] o.s.b.a.e.mvc.EndpointHandlerMapping : Mapped "{[/env || /env.json],methods=[GET],produces=[application/vnd.spring-boot.actuator.v1+json || application/json]}" onto public java.lang.Object org.springframework.boot.actuate.endpoint.mvc.EndpointMvcAdapter.invoke()
2017-12-20 15:03:37.314 INFO 7372 --- [ main] o.s.s.web.DefaultSecurityFilterChain : Creating filter chain: org.springframework.boot.actuate.autoconfigure.ManagementWebSecurityAutoConfiguration$LazyEndpointPathRequestMatcher@5b94b04d, [org.springframework.security.web.context.request.async.WebAsyncManagerIntegrationFilter@8c3b9d, org.springframework.security.web.context.SecurityContextPersistenceFilter@682b2fa, org.springframework.security.web.header.HeaderWriterFilter@3fc2959f, org.springframework.web.filter.CorsFilter@4c39bec8, org.springframework.security.web.authentication.logout.LogoutFilter@477b4cdf, org.springframework.security.web.authentication.www.BasicAuthenticationFilter@3c9754d8, org.springframework.security.web.savedrequest.RequestCacheAwareFilter@7dcf94f8, org.springframework.security.web.servletapi.SecurityContextHolderAwareRequestFilter@662ac478, org.springframework.security.web.authentication.AnonymousAuthenticationFilter@f79e, org.springframework.security.web.session.SessionManagementFilter@6989da5e, org.springframework.security.web.access.ExceptionTranslationFilter@6a78afa0, org.springframework.security.web.access.intercept.FilterSecurityInterceptor@6ed3ccb2]
2017-12-20 15:03:37.317 INFO 7372 --- [ main] o.s.s.web.DefaultSecurityFilterChain : Creating filter chain: OrRequestMatcher [requestMatchers=[Ant [pattern='/**']]], [org.springframework.security.web.context.request.async.WebAsyncManagerIntegrationFilter@3af9c5b7, org.springframework.security.web.context.SecurityContextPersistenceFilter@445b295b, org.springframework.security.web.header.HeaderWriterFilter@2e377400, org.springframework.security.web.authentication.logout.LogoutFilter@757277dc, org.springframework.security.web.authentication.www.BasicAuthenticationFilter@687e99d8, org.springframework.security.web.savedrequest.RequestCacheAwareFilter@49e5f737, org.springframework.security.web.servletapi.SecurityContextHolderAwareRequestFilter@5c671d7f, org.springframework.security.web.authentication.AnonymousAuthenticationFilter@37271612, org.springframework.security.web.session.SessionManagementFilter@1757cd72, org.springframework.security.web.access.ExceptionTranslationFilter@561b6512, org.springframework.security.web.access.intercept.FilterSecurityInterceptor@10aa41f2]
2017-12-20 15:03:37.555 WARN 7372 --- [ main] ationConfigEmbeddedWebApplicationContext : Exception encountered during context initialization - cancelling refresh attempt: org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'org.springframework.cloud.aws.core.env.ResourceIdResolver.BEAN_NAME': Invocation of init method failed; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'stackResourceRegistryFactoryBean' defined in class path resource [org/springframework/cloud/aws/autoconfigure/context/ContextStackAutoConfiguration$StackAutoDetectConfiguration.class]: Bean instantiation via factory method failed; nested exception is org.springframework.beans.BeanInstantiationException: Failed to instantiate [org.springframework.cloud.aws.core.env.stack.config.StackResourceRegistryFactoryBean]: Factory method 'stackResourceRegistryFactoryBean' threw exception; nested exception is com.amazonaws.SdkClientException: Unable to load AWS credentials from any provider in the chain
2017-12-20 15:03:37.556 INFO 7372 --- [ main] o.s.j.e.a.AnnotationMBeanExporter : Unregistering JMX-exposed beans on shutdown
2017-12-20 15:03:37.560 INFO 7372 --- [ main] o.apache.catalina.core.StandardService : Stopping service [Tomcat]
2017-12-20 15:03:38.079 INFO 7372 --- [ main] utoConfigurationReportLoggingInitializer :
Error starting ApplicationContext. To display the auto-configuration report re-run your application with 'debug' enabled.
2017-12-20 15:03:38.086 ERROR 7372 --- [ main] o.s.boot.SpringApplication : Application startup failed
org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'org.springframework.cloud.aws.core.env.ResourceIdResolver.BEAN_NAME': Invocation of init method failed; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'stackResourceRegistryFactoryBean' defined in class path resource [org/springframework/cloud/aws/autoconfigure/context/ContextStackAutoConfiguration$StackAutoDetectConfiguration.class]: Bean instantiation via factory method failed; nested exception is org.springframework.beans.BeanInstantiationException: Failed to instantiate [org.springframework.cloud.aws.core.env.stack.config.StackResourceRegistryFactoryBean]: Factory method 'stackResourceRegistryFactoryBean' threw exception; nested exception is com.amazonaws.SdkClientException: Unable to load AWS credentials from any provider in the chain
...Lot more lines of error messages but I think you get the picture...
[ec2-user@ip-10-0-0-244 server]$
It doesn't look like the Dynamo call is failing. it looks like Spring Cloud AWS is failing.
Here is the last portion of the stack trace you provided:
Failed to instantiate [org.springframework.cloud.aws.core.env.stack.config.StackResourceRegistryFactoryBean]: Factory method 'stackResourceRegistryFactoryBean' threw exception; nested exception is com.amazonaws.SdkClientException: Unable to load AWS credentials from any provider in the chain
It looks like Spring Cloud AWS wants credentials, and providing them for only DynamoDB isn't enough.
Try removing Spring Cloud from your dependencies if you don't need it.
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.