我有一个 Java 17 项目,它具有 DynamoDB Local 依赖项,并在运行测试时配置和部署它:
这是一个测试示例:
@TestInstance(TestInstance.Lifecycle.PER_CLASS)
class TestClass1 {
private AmazonDynamoDB amazonDynamoDB;
@BeforeAll
void setUp() throws Exception {
var dynamoDBProxyServer = ServerRunner.createServerFromCommandLineArgs(
new String[]{"-inMemory"}
);
dynamoDBProxyServer.start();
createAmazonDynamoDBClient();
}
@BeforeEach
void setUpTable(){
createTables();
}
@AfterEach
void cleanUpTable() {
deleteTable();
}
private void createAmazonDynamoDBClient() {
this.amazonDynamoDB = AmazonDynamoDBClientBuilder.standard()
.withEndpointConfiguration(
new AwsClientBuilder.EndpointConfiguration("http://localhost:8000", "us-west-2"))
.build();
}
private void createTables() {
var mapper = new DynamoDBMapper(this.amazonDynamoDB);
var tableRequest = mapper.generateCreateTableRequest(DynamoTestModel.class);
tableRequest.setProvisionedThroughput(new ProvisionedThroughput(1L, 1L));
amazonDynamoDB.createTable(tableRequest);
}
private void deleteTable() {
var mapper = new DynamoDBMapper(this.amazonDynamoDB);
var tableRequest = mapper.generateDeleteTableRequest(DynamoTestModel.class);
amazonDynamoDB.deleteTable(tableRequest);
}
@Test
void givenSave_WhenItemIsPresentAndHasAutoGeneratedId_ThenShouldFinishWithoutErrorsReturningAnItemWithItsIdFilled() {
var mapper = new DynamoDBMapper(amazonDynamoDB);
var item = mapper.save(DynamoTestModel.builder().value("TEST").build());
Assertions.assertNotNull(item);
Assertions.assertNotNull(item.getId());
var queryResult = mapper.load(DynamoTestModel.class, item.getId());
Assertions.assertNotNull(queryResult);
Assertions.assertNotNull(queryResult.getId());
}
}
上面的代码有效。它提升了 DynamoDB 本地实例,我可以插入数据、加载、扫描而无需过滤器...
当我尝试使用过滤条件运行扫描时出现问题:
@TestInstance(TestInstance.Lifecycle.PER_CLASS)
class MyTestClass {
private AmazonDynamoDB amazonDynamoDB;
@BeforeAll
void setUp() throws Exception {
var dynamoDBProxyServer = ServerRunner.createServerFromCommandLineArgs(
new String[]{"-inMemory", "-port", "8000"}
);
dynamoDBProxyServer.start();
createAmazonDynamoDBClient();
}
@BeforeEach
void setUpTable(){
createTables();
}
@AfterEach
void cleanUpTable() {
deleteTable();
}
private void createAmazonDynamoDBClient() {
this.amazonDynamoDB = AmazonDynamoDBClientBuilder.standard()
.withEndpointConfiguration(
new AwsClientBuilder.EndpointConfiguration("http://localhost:8000", "us-west-2"))
.build();
}
private void createTables() {
var mapper = new DynamoDBMapper(this.amazonDynamoDB);
var tableRequest = mapper.generateCreateTableRequest(DynamoTestModel.class);
tableRequest.setProvisionedThroughput(new ProvisionedThroughput(1L, 1L));
amazonDynamoDB.createTable(tableRequest);
}
private void deleteTable() {
var mapper = new DynamoDBMapper(this.amazonDynamoDB);
var tableRequest = mapper.generateDeleteTableRequest(DynamoTestModel.class);
amazonDynamoDB.deleteTable(tableRequest);
}
@Test
void test() {
var mapper = new DynamoDBMapper(amazonDynamoDB);
Map<String, AttributeValue> attributes = new HashMap<>();
attributes.put(":test", new AttributeValue().withS("tomato"));
var query = " ( contains(value, :test)) ";
mapper.batchSave(Arrays.asList(
DynamoTestModel.builder().value("mango").build(),
DynamoTestModel.builder().value("avocado").build(),
DynamoTestModel.builder().value("other fruit").build(),
DynamoTestModel.builder().value("other other fruit").build(),
DynamoTestModel.builder().value("jack fruit").build(),
DynamoTestModel.builder().value("tomato").build()
));
var scanResult = mapperscanPage(DynamoTestModel.class, new DynamoDBScanExpression()
.withFilterExpression(query)
.withExpressionAttributeValues(attributes));
Assertions.assertEquals(1, scanResult.getCount());
Assertions.assertEquals("tomato", scanResult.getResults().get(0).getValue());
}
}
上述测试产生此错误:
Unable to unmarshall exception response with the unmarshallers provided (Service: AmazonDynamoDBv2; Status Code: 400; Error Code: ValidationException; Request ID: 0AS59VHPQ7IO0OIEQI4J9PEQIRVV4KQNSO5AEMVJF66Q9ASUAAJG; Proxy: null)
com.amazonaws.AmazonServiceException: Unable to unmarshall exception response with the unmarshallers provided (Service: AmazonDynamoDBv2; Status Code: 400; Error Code: ValidationException; Request ID: 0AS59VHPQ7IO0OIEQI4J9PEQIRVV4KQNSO5AEMVJF66Q9ASUAAJG; Proxy: null)
at app//com.amazonaws.http.AmazonHttpClient$RequestExecutor.handleErrorResponse(AmazonHttpClient.java:1879)
at app//com.amazonaws.http.AmazonHttpClient$RequestExecutor.handleServiceErrorResponse(AmazonHttpClient.java:1418)
at app//com.amazonaws.http.AmazonHttpClient$RequestExecutor.executeOneRequest(AmazonHttpClient.java:1387)
at app//com.amazonaws.http.AmazonHttpClient$RequestExecutor.executeHelper(AmazonHttpClient.java:1157)
at app//com.amazonaws.http.AmazonHttpClient$RequestExecutor.doExecute(AmazonHttpClient.java:814)
at app//com.amazonaws.http.AmazonHttpClient$RequestExecutor.executeWithTimer(AmazonHttpClient.java:781)
at app//com.amazonaws.http.AmazonHttpClient$RequestExecutor.execute(AmazonHttpClient.java:755)
at app//com.amazonaws.http.AmazonHttpClient$RequestExecutor.access$500(AmazonHttpClient.java:715)
at app//com.amazonaws.http.AmazonHttpClient$RequestExecutionBuilderImpl.execute(AmazonHttpClient.java:697)
at app//com.amazonaws.http.AmazonHttpClient.execute(AmazonHttpClient.java:561)
at app//com.amazonaws.http.AmazonHttpClient.execute(AmazonHttpClient.java:541)
at app//com.amazonaws.services.dynamodbv2.AmazonDynamoDBClient.doInvoke(AmazonDynamoDBClient.java:6903)
at app//com.amazonaws.services.dynamodbv2.AmazonDynamoDBClient.invoke(AmazonDynamoDBClient.java:6870)
at app//com.amazonaws.services.dynamodbv2.AmazonDynamoDBClient.executeScan(AmazonDynamoDBClient.java:4815)
at app//com.amazonaws.services.dynamodbv2.AmazonDynamoDBClient.scan(AmazonDynamoDBClient.java:4779)
at app//com.amazonaws.services.dynamodbv2.datamodeling.DynamoDBMapper.scanPage(DynamoDBMapper.java:1596)
at app//com.amazonaws.services.dynamodbv2.datamodeling.AbstractDynamoDBMapper.scanPage(AbstractDynamoDBMapper.java:263)
at app//data.dynamodb.repository.custom.MyTestClass.test2(MyTestClass.java:123)
at [email protected]/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at [email protected]/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:77)
at [email protected]/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at [email protected]/java.lang.reflect.Method.invoke(Method.java:568)
at app//org.junit.platform.commons.util.ReflectionUtils.invokeMethod(ReflectionUtils.java:727)
at app//org.junit.jupiter.engine.execution.MethodInvocation.proceed(MethodInvocation.java:60)
at app//org.junit.jupiter.engine.execution.InvocationInterceptorChain$ValidatingInvocation.proceed(InvocationInterceptorChain.java:131)
at app//org.junit.jupiter.engine.extension.TimeoutExtension.intercept(TimeoutExtension.java:156)
at app//org.junit.jupiter.engine.extension.TimeoutExtension.interceptTestableMethod(TimeoutExtension.java:147)
at app//org.junit.jupiter.engine.extension.TimeoutExtension.interceptTestMethod(TimeoutExtension.java:86)
at app//org.junit.jupiter.engine.execution.InterceptingExecutableInvoker$ReflectiveInterceptorCall.lambda$ofVoidMethod$0(InterceptingExecutableInvoker.java:103)
at app//org.junit.jupiter.engine.execution.InterceptingExecutableInvoker.lambda$invoke$0(InterceptingExecutableInvoker.java:93)
at app//org.junit.jupiter.engine.execution.InvocationInterceptorChain$InterceptedInvocation.proceed(InvocationInterceptorChain.java:106)
at app//org.junit.jupiter.engine.execution.InvocationInterceptorChain.proceed(InvocationInterceptorChain.java:64)
at app//org.junit.jupiter.engine.execution.InvocationInterceptorChain.chainAndInvoke(InvocationInterceptorChain.java:45)
at app//org.junit.jupiter.engine.execution.InvocationInterceptorChain.invoke(InvocationInterceptorChain.java:37)
at app//org.junit.jupiter.engine.execution.InterceptingExecutableInvoker.invoke(InterceptingExecutableInvoker.java:92)
at app//org.junit.jupiter.engine.execution.InterceptingExecutableInvoker.invoke(InterceptingExecutableInvoker.java:86)
at app//org.junit.jupiter.engine.descriptor.TestMethodTestDescriptor.lambda$invokeTestMethod$7(TestMethodTestDescriptor.java:217)
at app//org.junit.platform.engine.support.hierarchical.ThrowableCollector.execute(ThrowableCollector.java:73)
at app//org.junit.jupiter.engine.descriptor.TestMethodTestDescriptor.invokeTestMethod(TestMethodTestDescriptor.java:213)
at app//org.junit.jupiter.engine.descriptor.TestMethodTestDescriptor.execute(TestMethodTestDescriptor.java:138)
at app//org.junit.jupiter.engine.descriptor.TestMethodTestDescriptor.execute(TestMethodTestDescriptor.java:68)
at app//org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$6(NodeTestTask.java:151)
at app//org.junit.platform.engine.support.hierarchical.ThrowableCollector.execute(ThrowableCollector.java:73)
at app//org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$8(NodeTestTask.java:141)
at app//org.junit.platform.engine.support.hierarchical.Node.around(Node.java:137)
at app//org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$9(NodeTestTask.java:139)
at app//org.junit.platform.engine.support.hierarchical.ThrowableCollector.execute(ThrowableCollector.java:73)
at app//org.junit.platform.engine.support.hierarchical.NodeTestTask.executeRecursively(NodeTestTask.java:138)
at app//org.junit.platform.engine.support.hierarchical.NodeTestTask.execute(NodeTestTask.java:95)
at [email protected]/java.util.ArrayList.forEach(ArrayList.java:1511)
at app//org.junit.platform.engine.support.hierarchical.SameThreadHierarchicalTestExecutorService.invokeAll(SameThreadHierarchicalTestExecutorService.java:41)
at app//org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$6(NodeTestTask.java:155)
at app//org.junit.platform.engine.support.hierarchical.ThrowableCollector.execute(ThrowableCollector.java:73)
at app//org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$8(NodeTestTask.java:141)
at app//org.junit.platform.engine.support.hierarchical.Node.around(Node.java:137)
at app//org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$9(NodeTestTask.java:139)
at app//org.junit.platform.engine.support.hierarchical.ThrowableCollector.execute(ThrowableCollector.java:73)
at app//org.junit.platform.engine.support.hierarchical.NodeTestTask.executeRecursively(NodeTestTask.java:138)
at app//org.junit.platform.engine.support.hierarchical.NodeTestTask.execute(NodeTestTask.java:95)
at [email protected]/java.util.ArrayList.forEach(ArrayList.java:1511)
at app//org.junit.platform.engine.support.hierarchical.SameThreadHierarchicalTestExecutorService.invokeAll(SameThreadHierarchicalTestExecutorService.java:41)
at app//org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$6(NodeTestTask.java:155)
at app//org.junit.platform.engine.support.hierarchical.ThrowableCollector.execute(ThrowableCollector.java:73)
at app//org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$8(NodeTestTask.java:141)
at app//org.junit.platform.engine.support.hierarchical.Node.around(Node.java:137)
at app//org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$9(NodeTestTask.java:139)
at app//org.junit.platform.engine.support.hierarchical.ThrowableCollector.execute(ThrowableCollector.java:73)
at app//org.junit.platform.engine.support.hierarchical.NodeTestTask.executeRecursively(NodeTestTask.java:138)
at app//org.junit.platform.engine.support.hierarchical.NodeTestTask.execute(NodeTestTask.java:95)
at app//org.junit.platform.engine.support.hierarchical.SameThreadHierarchicalTestExecutorService.submit(SameThreadHierarchicalTestExecutorService.java:35)
at app//org.junit.platform.engine.support.hierarchical.HierarchicalTestExecutor.execute(HierarchicalTestExecutor.java:57)
at app//org.junit.platform.engine.support.hierarchical.HierarchicalTestEngine.execute(HierarchicalTestEngine.java:54)
at app//org.junit.platform.launcher.core.EngineExecutionOrchestrator.execute(EngineExecutionOrchestrator.java:107)
at app//org.junit.platform.launcher.core.EngineExecutionOrchestrator.execute(EngineExecutionOrchestrator.java:88)
at app//org.junit.platform.launcher.core.EngineExecutionOrchestrator.lambda$execute$0(EngineExecutionOrchestrator.java:54)
at app//org.junit.platform.launcher.core.EngineExecutionOrchestrator.withInterceptedStreams(EngineExecutionOrchestrator.java:67)
at app//org.junit.platform.launcher.core.EngineExecutionOrchestrator.execute(EngineExecutionOrchestrator.java:52)
at app//org.junit.platform.launcher.core.DefaultLauncher.execute(DefaultLauncher.java:114)
at app//org.junit.platform.launcher.core.DefaultLauncher.execute(DefaultLauncher.java:86)
at app//org.junit.platform.launcher.core.DefaultLauncherSession$DelegatingLauncher.execute(DefaultLauncherSession.java:86)
at org.gradle.api.internal.tasks.testing.junitplatform.JUnitPlatformTestClassProcessor$CollectAllTestClassesExecutor.processAllTestClasses(JUnitPlatformTestClassProcessor.java:118)
at org.gradle.api.internal.tasks.testing.junitplatform.JUnitPlatformTestClassProcessor$CollectAllTestClassesExecutor.access$000(JUnitPlatformTestClassProcessor.java:93)
at org.gradle.api.internal.tasks.testing.junitplatform.JUnitPlatformTestClassProcessor.stop(JUnitPlatformTestClassProcessor.java:88)
at org.gradle.api.internal.tasks.testing.SuiteTestClassProcessor.stop(SuiteTestClassProcessor.java:62)
at [email protected]/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at [email protected]/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:77)
at [email protected]/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at [email protected]/java.lang.reflect.Method.invoke(Method.java:568)
at org.gradle.internal.dispatch.ReflectionDispatch.dispatch(ReflectionDispatch.java:36)
at org.gradle.internal.dispatch.ReflectionDispatch.dispatch(ReflectionDispatch.java:24)
at org.gradle.internal.dispatch.ContextClassLoaderDispatch.dispatch(ContextClassLoaderDispatch.java:33)
at org.gradle.internal.dispatch.ProxyDispatchAdapter$DispatchingInvocationHandler.invoke(ProxyDispatchAdapter.java:94)
at jdk.proxy1/jdk.proxy1.$Proxy2.stop(Unknown Source)
at org.gradle.api.internal.tasks.testing.worker.TestWorker$3.run(TestWorker.java:193)
at org.gradle.api.internal.tasks.testing.worker.TestWorker.executeAndMaintainThreadName(TestWorker.java:129)
at org.gradle.api.internal.tasks.testing.worker.TestWorker.execute(TestWorker.java:100)
at org.gradle.api.internal.tasks.testing.worker.TestWorker.execute(TestWorker.java:60)
at org.gradle.process.internal.worker.child.ActionExecutionWorker.execute(ActionExecutionWorker.java:56)
at org.gradle.process.internal.worker.child.SystemApplicationClassLoaderWorker.call(SystemApplicationClassLoaderWorker.java:113)
at org.gradle.process.internal.worker.child.SystemApplicationClassLoaderWorker.call(SystemApplicationClassLoaderWorker.java:65)
at app//worker.org.gradle.process.internal.worker.GradleWorkerMain.run(GradleWorkerMain.java:69)
at app//worker.org.gradle.process.internal.worker.GradleWorkerMain.main(GradleWorkerMain.java:74)
123
的MyTestClass
行正是我使用过滤器运行scanPage的代码:
var scanResult = new DynamoDBMapper(amazonDynamoDB).scanPage(DynamoTestModel.class, new DynamoDBScanExpression()
.withFilterExpression(query)
.withExpressionAttributeValues(attributes));
我倾向于认为这是配置错误或 DynamoDB Local 的限制,因为此 scanPage 过滤器适用于真正的 DynamoDB。
你有什么建议吗?
这不是 DynamoDB Local 的问题。
无法使用提供的解组器解组异常响应
您的异常的第一部分只是您的设置问题,我在here详细解释了这一点。
错误代码:ValidationException
这才是真正的问题。
ValidationException
通常与不正确的语法有关。
var query = " ( contains(value, :test)) ";
这里的
value
是什么?它应该是一个属性名称。 value 是 DynamoDB 中的保留关键字,如果您的属性名称称为 value
那么您应该使用 ExpressionAttributeNames
。
如果您没有使用保留关键字并且
value
不是您的属性名称,您可以简单地这样做:
var query = "contains(myAttributeName, :test)";