embulk-input-dynamodb 0.2.0 → 0.3.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (70) hide show
  1. checksums.yaml +4 -4
  2. data/.github/workflows/master.yml +34 -0
  3. data/.github/workflows/test.yml +30 -0
  4. data/.scalafmt.conf +5 -0
  5. data/CHANGELOG.md +49 -0
  6. data/README.md +204 -54
  7. data/build.gradle +53 -44
  8. data/example/config-deprecated.yml +20 -0
  9. data/example/config-query-as-json.yml +18 -0
  10. data/example/config-query.yml +22 -0
  11. data/example/config-scan.yml +18 -0
  12. data/example/prepare_dynamodb_table.sh +67 -0
  13. data/gradle/wrapper/gradle-wrapper.jar +0 -0
  14. data/gradle/wrapper/gradle-wrapper.properties +1 -2
  15. data/gradlew +67 -48
  16. data/gradlew.bat +20 -10
  17. data/{test/run_dynamodb_local.sh → run_dynamodb_local.sh} +2 -1
  18. data/settings.gradle +1 -0
  19. data/src/main/scala/org/embulk/input/dynamodb/DeprecatedDynamodbInputPlugin.scala +73 -0
  20. data/src/main/scala/org/embulk/input/dynamodb/DynamodbInputPlugin.scala +76 -25
  21. data/src/main/scala/org/embulk/input/dynamodb/PluginTask.scala +132 -32
  22. data/src/main/scala/org/embulk/input/dynamodb/aws/Aws.scala +44 -0
  23. data/src/main/scala/org/embulk/input/dynamodb/aws/AwsClientConfiguration.scala +37 -0
  24. data/src/main/scala/org/embulk/input/dynamodb/aws/AwsCredentials.scala +240 -0
  25. data/src/main/scala/org/embulk/input/dynamodb/aws/AwsDynamodbConfiguration.scala +35 -0
  26. data/src/main/scala/org/embulk/input/dynamodb/aws/AwsEndpointConfiguration.scala +79 -0
  27. data/src/main/scala/org/embulk/input/dynamodb/aws/HttpProxy.scala +61 -0
  28. data/src/main/scala/org/embulk/input/dynamodb/deprecated/AttributeValueHelper.scala +72 -0
  29. data/src/main/scala/org/embulk/input/dynamodb/{Filter.scala → deprecated/Filter.scala} +3 -3
  30. data/src/main/scala/org/embulk/input/dynamodb/{FilterConfig.scala → deprecated/FilterConfig.scala} +13 -13
  31. data/src/main/scala/org/embulk/input/dynamodb/{ope → deprecated/ope}/AbstractOperation.scala +36 -18
  32. data/src/main/scala/org/embulk/input/dynamodb/{ope → deprecated/ope}/QueryOperation.scala +21 -13
  33. data/src/main/scala/org/embulk/input/dynamodb/{ope → deprecated/ope}/ScanOperation.scala +20 -13
  34. data/src/main/scala/org/embulk/input/dynamodb/item/DynamodbAttributeValue.scala +154 -0
  35. data/src/main/scala/org/embulk/input/dynamodb/item/DynamodbAttributeValueEmbulkTypeTransformable.scala +245 -0
  36. data/src/main/scala/org/embulk/input/dynamodb/item/DynamodbAttributeValueType.scala +33 -0
  37. data/src/main/scala/org/embulk/input/dynamodb/item/DynamodbItemColumnVisitor.scala +50 -0
  38. data/src/main/scala/org/embulk/input/dynamodb/item/DynamodbItemConsumer.scala +40 -0
  39. data/src/main/scala/org/embulk/input/dynamodb/item/DynamodbItemIterator.scala +19 -0
  40. data/src/main/scala/org/embulk/input/dynamodb/item/DynamodbItemReader.scala +64 -0
  41. data/src/main/scala/org/embulk/input/dynamodb/item/DynamodbItemSchema.scala +135 -0
  42. data/src/main/scala/org/embulk/input/dynamodb/operation/AbstractDynamodbOperation.scala +169 -0
  43. data/src/main/scala/org/embulk/input/dynamodb/operation/DynamodbOperationProxy.scala +59 -0
  44. data/src/main/scala/org/embulk/input/dynamodb/operation/DynamodbQueryOperation.scala +72 -0
  45. data/src/main/scala/org/embulk/input/dynamodb/operation/DynamodbScanOperation.scala +93 -0
  46. data/src/main/scala/org/embulk/input/dynamodb/operation/EmbulkDynamodbOperation.scala +15 -0
  47. data/src/main/scala/org/embulk/input/dynamodb/package.scala +4 -9
  48. data/src/test/scala/org/embulk/input/dynamodb/AttributeValueHelperTest.scala +245 -101
  49. data/src/test/scala/org/embulk/input/dynamodb/AwsCredentialsTest.scala +150 -97
  50. data/src/test/scala/org/embulk/input/dynamodb/DynamodbQueryOperationTest.scala +188 -0
  51. data/src/test/scala/org/embulk/input/dynamodb/DynamodbScanOperationTest.scala +181 -0
  52. data/src/test/scala/org/embulk/input/dynamodb/testutil/EmbulkTestBase.scala +85 -0
  53. metadata +73 -49
  54. data/circle.yml +0 -16
  55. data/config/checkstyle/checkstyle.xml +0 -128
  56. data/config/checkstyle/default.xml +0 -108
  57. data/src/main/scala/org/embulk/input/dynamodb/AttributeValueHelper.scala +0 -41
  58. data/src/main/scala/org/embulk/input/dynamodb/AwsCredentials.scala +0 -63
  59. data/src/main/scala/org/embulk/input/dynamodb/DynamoDBClient.scala +0 -23
  60. data/src/test/resources/yaml/authMethodBasic.yml +0 -21
  61. data/src/test/resources/yaml/authMethodBasic_Error.yml +0 -19
  62. data/src/test/resources/yaml/authMethodEnv.yml +0 -19
  63. data/src/test/resources/yaml/authMethodProfile.yml +0 -20
  64. data/src/test/resources/yaml/dynamodb-local-query.yml +0 -25
  65. data/src/test/resources/yaml/dynamodb-local-scan.yml +0 -23
  66. data/src/test/resources/yaml/notSetAuthMethod.yml +0 -20
  67. data/src/test/scala/org/embulk/input/dynamodb/ope/QueryOperationTest.scala +0 -83
  68. data/src/test/scala/org/embulk/input/dynamodb/ope/ScanOperationTest.scala +0 -83
  69. data/test/create_table.sh +0 -16
  70. data/test/put_items.sh +0 -25
@@ -1,135 +1,188 @@
1
1
  package org.embulk.input.dynamodb
2
2
 
3
- import java.io.File
4
- import java.nio.charset.Charset
5
- import java.nio.file.{FileSystems, Files}
6
-
7
- import com.google.inject.{Binder, Module}
8
- import org.embulk.config.ConfigSource
9
- import org.embulk.exec.PartialExecutionException
10
- import org.embulk.plugin.InjectedPluginSource
11
- import org.embulk.spi.InputPlugin
12
- import org.embulk.{EmbulkEmbed, EmbulkTestRuntime}
13
- import org.junit.Assert.assertEquals
14
- import org.junit.{Before, Rule, Test}
15
-
16
- class AwsCredentialsTest {
17
- private var EMBULK_DYNAMODB_TEST_REGION: String = null
18
- private var EMBULK_DYNAMODB_TEST_TABLE: String = null
19
- private var EMBULK_DYNAMODB_TEST_ACCESS_KEY: String = null
20
- private var EMBULK_DYNAMODB_TEST_SECRET_KEY: String = null
21
- private var EMBULK_DYNAMODB_TEST_PROFILE_NAME: String = null
22
-
23
- private var embulk: EmbulkEmbed = null
24
-
25
- @Rule
26
- def runtime: EmbulkTestRuntime = new EmbulkTestRuntime
27
-
28
- @Before
29
- def createResources() {
30
- // Get Environments
31
- EMBULK_DYNAMODB_TEST_REGION = System.getenv("EMBULK_DYNAMODB_TEST_REGION")
32
- EMBULK_DYNAMODB_TEST_TABLE = System.getenv("EMBULK_DYNAMODB_TEST_TABLE")
33
- EMBULK_DYNAMODB_TEST_ACCESS_KEY = System.getenv("EMBULK_DYNAMODB_TEST_ACCESS_KEY")
34
- EMBULK_DYNAMODB_TEST_SECRET_KEY = System.getenv("EMBULK_DYNAMODB_TEST_SECRET_KEY")
35
- EMBULK_DYNAMODB_TEST_PROFILE_NAME = System.getenv("EMBULK_DYNAMODB_TEST_PROFILE_NAME")
36
-
37
- val bootstrap = new EmbulkEmbed.Bootstrap()
38
- bootstrap.addModules(new Module {
39
- def configure(binder: Binder): Unit = {
40
- InjectedPluginSource.registerPluginTo(binder,
41
- classOf[InputPlugin],
42
- "dynamodb",
43
- classOf[DynamodbInputPlugin])
44
- }
45
- })
46
-
47
- embulk = bootstrap.initializeCloseable()
3
+ import com.amazonaws.services.securitytoken.model.AWSSecurityTokenServiceException
4
+ import org.embulk.config.{ConfigException, ConfigSource}
5
+ import org.embulk.input.dynamodb.aws.AwsCredentials
6
+ import org.embulk.input.dynamodb.testutil.EmbulkTestBase
7
+ import org.hamcrest.CoreMatchers._
8
+ import org.hamcrest.MatcherAssert.assertThat
9
+ import org.junit.{Assume, Test}
10
+
11
+ class AwsCredentialsTest extends EmbulkTestBase {
12
+
13
+ private val runAwsCredentialsTest: Boolean = Option(
14
+ System.getenv("RUN_AWS_CREDENTIALS_TEST")
15
+ ) match {
16
+ case Some(x) =>
17
+ if (x == "false") false
18
+ else true
19
+ case None => true
48
20
  }
49
21
 
50
- def doTest(config: ConfigSource) {
51
- embulk.run(config)
22
+ private lazy val EMBULK_DYNAMODB_TEST_ACCESS_KEY =
23
+ getEnvironmentVariableOrShowErrorMessage("EMBULK_DYNAMODB_TEST_ACCESS_KEY")
52
24
 
53
- val fs = FileSystems.getDefault
54
- val lines = Files.readAllLines(fs.getPath("result000.00.tsv"), Charset.forName("UTF-8"))
55
- assertEquals("KEY-1\t1\tHogeHoge", lines.get(0))
25
+ private lazy val EMBULK_DYNAMODB_TEST_SECRET_KEY =
26
+ getEnvironmentVariableOrShowErrorMessage("EMBULK_DYNAMODB_TEST_SECRET_KEY")
27
+
28
+ private lazy val EMBULK_DYNAMODB_TEST_PROFILE_NAME =
29
+ getEnvironmentVariableOrShowErrorMessage(
30
+ "EMBULK_DYNAMODB_TEST_PROFILE_NAME"
31
+ )
32
+
33
+ private lazy val EMBULK_DYNAMODB_TEST_ASSUME_ROLE_ROLE_ARN =
34
+ getEnvironmentVariableOrShowErrorMessage(
35
+ "EMBULK_DYNAMODB_TEST_ASSUME_ROLE_ROLE_ARN"
36
+ )
37
+
38
+ def doTest(inConfig: ConfigSource): Unit = {
39
+ val task: PluginTask = inConfig.loadConfig(classOf[PluginTask])
40
+ val provider = AwsCredentials(task).createAwsCredentialsProvider
41
+ val cred = provider.getCredentials
42
+ assertThat(cred.getAWSAccessKeyId, notNullValue())
43
+ assertThat(cred.getAWSSecretKey, notNullValue())
56
44
  }
57
45
 
58
- @Test
59
- def notSetAuthMethod_SetCredentials() {
60
- val config = embulk.newConfigLoader().fromYamlFile(
61
- new File("src/test/resources/yaml/notSetAuthMethod.yml"))
46
+ def defaultInConfig: ConfigSource = {
47
+ embulk.configLoader().fromYamlString(s"""
48
+ |type: dynamodb
49
+ |region: us-east-1
50
+ |table: hoge
51
+ |operation: scan
52
+ |columns:
53
+ | - {name: key1, type: string}
54
+ | - {name: key2, type: long}
55
+ | - {name: value1, type: string}
56
+ |""".stripMargin)
57
+ }
62
58
 
63
- config.getNested("in")
64
- .set("region", EMBULK_DYNAMODB_TEST_REGION)
65
- .set("table", EMBULK_DYNAMODB_TEST_TABLE)
59
+ @deprecated(since = "0.3.0")
60
+ @Test
61
+ def notSetAuthMethod_SetCredentials_deprecated(): Unit = {
62
+ Assume.assumeTrue(runAwsCredentialsTest)
63
+ val inConfig: ConfigSource = defaultInConfig
66
64
  .set("access_key", EMBULK_DYNAMODB_TEST_ACCESS_KEY)
67
65
  .set("secret_key", EMBULK_DYNAMODB_TEST_SECRET_KEY)
68
66
 
69
- doTest(config)
67
+ doTest(inConfig)
70
68
  }
71
69
 
72
70
  @Test
73
- def setAuthMethod_Basic() {
74
- val config = embulk.newConfigLoader().fromYamlFile(
75
- new File("src/test/resources/yaml/authMethodBasic.yml"))
71
+ def notSetAuthMethod_SetCredentials(): Unit = {
72
+ Assume.assumeTrue(runAwsCredentialsTest)
73
+ val inConfig: ConfigSource = defaultInConfig
74
+ .set("access_key_id", EMBULK_DYNAMODB_TEST_ACCESS_KEY)
75
+ .set("secret_access_key", EMBULK_DYNAMODB_TEST_SECRET_KEY)
76
76
 
77
- config.getNested("in")
78
- .set("region", EMBULK_DYNAMODB_TEST_REGION)
79
- .set("table", EMBULK_DYNAMODB_TEST_TABLE)
77
+ doTest(inConfig)
78
+ }
79
+
80
+ @deprecated(since = "0.3.0")
81
+ @Test
82
+ def setAuthMethod_Basic_deprecated(): Unit = {
83
+ Assume.assumeTrue(runAwsCredentialsTest)
84
+ val inConfig: ConfigSource = defaultInConfig
85
+ .set("auth_method", "basic")
80
86
  .set("access_key", EMBULK_DYNAMODB_TEST_ACCESS_KEY)
81
87
  .set("secret_key", EMBULK_DYNAMODB_TEST_SECRET_KEY)
82
88
 
83
- doTest(config)
89
+ doTest(inConfig)
84
90
  }
85
91
 
86
- @Test(expected = classOf[PartialExecutionException])
87
- def setAuthMethod_Basic_NotSet() {
88
- val config = embulk.newConfigLoader().fromYamlFile(
89
- new File("src/test/resources/yaml/authMethodBasic_Error.yml"))
92
+ @Test
93
+ def setAuthMethod_Basic(): Unit = {
94
+ Assume.assumeTrue(runAwsCredentialsTest)
95
+ val inConfig: ConfigSource = defaultInConfig
96
+ .set("auth_method", "basic")
97
+ .set("access_key_id", EMBULK_DYNAMODB_TEST_ACCESS_KEY)
98
+ .set("secret_access_key", EMBULK_DYNAMODB_TEST_SECRET_KEY)
99
+
100
+ doTest(inConfig)
101
+ }
90
102
 
91
- config.getNested("in")
92
- .set("region", EMBULK_DYNAMODB_TEST_REGION)
93
- .set("table", EMBULK_DYNAMODB_TEST_TABLE)
103
+ @deprecated(since = "0.3.0")
104
+ @Test(expected = classOf[ConfigException])
105
+ def throwIfSetAccessKeyAndAccessKeyId(): Unit = {
106
+ Assume.assumeTrue(runAwsCredentialsTest)
107
+ val inConfig: ConfigSource = defaultInConfig
108
+ .set("auth_method", "basic")
109
+ .set("access_key", EMBULK_DYNAMODB_TEST_ACCESS_KEY)
110
+ .set("access_key_id", EMBULK_DYNAMODB_TEST_ACCESS_KEY)
111
+ .set("secret_key", EMBULK_DYNAMODB_TEST_SECRET_KEY)
94
112
 
95
- doTest(config)
113
+ doTest(inConfig)
96
114
  }
97
115
 
98
- @Test
99
- def setAuthMethod_Env() {
100
- val config = embulk.newConfigLoader().fromYamlFile(
101
- new File("src/test/resources/yaml/authMethodEnv.yml"))
116
+ @deprecated(since = "0.3.0")
117
+ @Test(expected = classOf[ConfigException])
118
+ def throwIfSetSecretKeyAndSecretAccessKeyId(): Unit = {
119
+ Assume.assumeTrue(runAwsCredentialsTest)
120
+ val inConfig: ConfigSource = defaultInConfig
121
+ .set("auth_method", "basic")
122
+ .set("access_key", EMBULK_DYNAMODB_TEST_ACCESS_KEY)
123
+ .set("secret_key", EMBULK_DYNAMODB_TEST_SECRET_KEY)
124
+ .set("secret_access_key", EMBULK_DYNAMODB_TEST_SECRET_KEY)
102
125
 
103
- config.getNested("in")
104
- .set("region", EMBULK_DYNAMODB_TEST_REGION)
105
- .set("table", EMBULK_DYNAMODB_TEST_TABLE)
126
+ doTest(inConfig)
127
+ }
106
128
 
107
- doTest(config)
129
+ @Test(expected = classOf[ConfigException])
130
+ def setAuthMethod_Basic_NotSet(): Unit = {
131
+ val inConfig: ConfigSource = defaultInConfig
132
+ .set("auth_method", "basic")
133
+
134
+ doTest(inConfig)
108
135
  }
109
136
 
110
137
  @Test
111
- def setAuthMethod_Profile() {
112
- val config = embulk.newConfigLoader().fromYamlFile(
113
- new File("src/test/resources/yaml/authMethodProfile.yml"))
138
+ def setAuthMethod_Env(): Unit = {
139
+ Assume.assumeTrue(runAwsCredentialsTest)
140
+ // NOTE: Requires to set the env vars like 'AWS_ACCESS_KEY_ID' and so on when testing.
141
+ val inConfig: ConfigSource = defaultInConfig
142
+ .set("auth_method", "env")
143
+
144
+ doTest(inConfig)
145
+ }
114
146
 
115
- config.getNested("in")
116
- .set("region", EMBULK_DYNAMODB_TEST_REGION)
117
- .set("table", EMBULK_DYNAMODB_TEST_TABLE)
147
+ @Test
148
+ def setAuthMethod_Profile(): Unit = {
149
+ Assume.assumeTrue(runAwsCredentialsTest)
150
+ // NOTE: Requires to set credentials to '~/.aws' when testing.
151
+ val inConfig: ConfigSource = defaultInConfig
152
+ .set("auth_method", "profile")
118
153
  .set("profile_name", EMBULK_DYNAMODB_TEST_PROFILE_NAME)
119
154
 
120
- doTest(config)
155
+ doTest(inConfig)
156
+ }
157
+
158
+ @Test(expected = classOf[IllegalArgumentException])
159
+ def setAuthMethod_Profile_NotExistProfileName(): Unit = {
160
+ val inConfig: ConfigSource = defaultInConfig
161
+ .set("auth_method", "profile")
162
+ .set("profile_name", "DO_NOT_EXIST")
163
+
164
+ doTest(inConfig)
121
165
  }
122
166
 
123
- @Test(expected = classOf[PartialExecutionException])
124
- def setAuthMethod_Profile_NotExistProfileName() {
125
- val config = embulk.newConfigLoader().fromYamlFile(
126
- new File("src/test/resources/yaml/authMethodProfile.yml"))
167
+ @Test
168
+ def setAuthMethod_assume_role(): Unit = {
169
+ Assume.assumeTrue(runAwsCredentialsTest)
170
+ val inConfig: ConfigSource = defaultInConfig
171
+ .set("auth_method", "assume_role")
172
+ .set("role_arn", EMBULK_DYNAMODB_TEST_ASSUME_ROLE_ROLE_ARN)
173
+ .set("role_session_name", "dummy")
174
+
175
+ doTest(inConfig)
176
+ }
127
177
 
128
- config.getNested("in")
129
- .set("region", EMBULK_DYNAMODB_TEST_REGION)
130
- .set("table", EMBULK_DYNAMODB_TEST_TABLE)
131
- .set("profile_name", "NotExistName")
178
+ @Test(expected = classOf[AWSSecurityTokenServiceException])
179
+ def setAuthMethod_assume_role_NotExistRoleArn(): Unit = {
180
+ Assume.assumeTrue(runAwsCredentialsTest)
181
+ val inConfig: ConfigSource = defaultInConfig
182
+ .set("auth_method", "assume_role")
183
+ .set("role_arn", "DO_NOT_EXIST")
184
+ .set("role_session_name", "dummy")
132
185
 
133
- doTest(config)
186
+ doTest(inConfig)
134
187
  }
135
188
  }
@@ -0,0 +1,188 @@
1
+ package org.embulk.input.dynamodb
2
+
3
+ import com.amazonaws.services.dynamodbv2.model.{
4
+ AttributeDefinition,
5
+ AttributeValue,
6
+ CreateTableRequest,
7
+ KeySchemaElement,
8
+ KeyType,
9
+ ProvisionedThroughput,
10
+ PutItemRequest,
11
+ ScalarAttributeType
12
+ }
13
+ import org.embulk.config.ConfigSource
14
+ import org.embulk.input.dynamodb.testutil.EmbulkTestBase
15
+ import org.embulk.spi.util.Pages
16
+ import org.hamcrest.CoreMatchers._
17
+ import org.hamcrest.MatcherAssert.assertThat
18
+ import org.junit.Test
19
+ import org.msgpack.value.Value
20
+
21
+ import scala.jdk.CollectionConverters._
22
+
23
+ class DynamodbQueryOperationTest extends EmbulkTestBase {
24
+
25
+ private def testBackwardCompatibility(embulkInConfig: ConfigSource): Unit = {
26
+ cleanupTable("EMBULK_DYNAMODB_TEST_TABLE")
27
+ withDynamodb { dynamodb =>
28
+ dynamodb.createTable(
29
+ new CreateTableRequest()
30
+ .withTableName("EMBULK_DYNAMODB_TEST_TABLE")
31
+ .withAttributeDefinitions(
32
+ new AttributeDefinition()
33
+ .withAttributeName("pri-key")
34
+ .withAttributeType(ScalarAttributeType.S),
35
+ new AttributeDefinition()
36
+ .withAttributeName("sort-key")
37
+ .withAttributeType(ScalarAttributeType.N)
38
+ )
39
+ .withKeySchema(
40
+ new KeySchemaElement()
41
+ .withAttributeName("pri-key")
42
+ .withKeyType(KeyType.HASH),
43
+ new KeySchemaElement()
44
+ .withAttributeName("sort-key")
45
+ .withKeyType(KeyType.RANGE)
46
+ )
47
+ .withProvisionedThroughput(
48
+ new ProvisionedThroughput()
49
+ .withReadCapacityUnits(5L)
50
+ .withWriteCapacityUnits(5L)
51
+ )
52
+ )
53
+
54
+ dynamodb.putItem(
55
+ new PutItemRequest()
56
+ .withTableName("EMBULK_DYNAMODB_TEST_TABLE")
57
+ .withItem(
58
+ Map
59
+ .newBuilder[String, AttributeValue]
60
+ .addOne("pri-key", new AttributeValue().withS("key-1"))
61
+ .addOne("sort-key", new AttributeValue().withN("0"))
62
+ .addOne("doubleValue", new AttributeValue().withN("42.195"))
63
+ .addOne("boolValue", new AttributeValue().withBOOL(true))
64
+ .addOne(
65
+ "listValue",
66
+ new AttributeValue().withL(
67
+ new AttributeValue().withS("list-value"),
68
+ new AttributeValue().withN("123")
69
+ )
70
+ )
71
+ .addOne(
72
+ "mapValue",
73
+ new AttributeValue().withM(
74
+ Map
75
+ .newBuilder[String, AttributeValue]
76
+ .addOne(
77
+ "map-key-1",
78
+ new AttributeValue().withS("map-value-1")
79
+ )
80
+ .addOne("map-key-2", new AttributeValue().withN("456"))
81
+ .result()
82
+ .asJava
83
+ )
84
+ )
85
+ .result()
86
+ .asJava
87
+ )
88
+ )
89
+
90
+ val path = embulk.createTempFile("csv")
91
+ val result = embulk
92
+ .inputBuilder()
93
+ .in(embulkInConfig)
94
+ .outputPath(path)
95
+ .preview()
96
+
97
+ val pages = result.getPages
98
+ val head = Pages.toObjects(result.getSchema, pages.get(0)).get(0)
99
+
100
+ assertThat(head(0).toString, is("key-1"))
101
+ assertThat(head(1).asInstanceOf[Long], is(0L))
102
+ assertThat(head(2).asInstanceOf[Double], is(42.195))
103
+ assertThat(head(3).asInstanceOf[Boolean], is(true))
104
+
105
+ val arrayValue = head(4).asInstanceOf[Value].asArrayValue()
106
+ assertThat(arrayValue.size(), is(2))
107
+ assertThat(arrayValue.get(0).asStringValue().toString, is("list-value"))
108
+ assertThat(arrayValue.get(1).asIntegerValue().asLong(), is(123L))
109
+
110
+ val mapValue = head(5).asInstanceOf[Value].asMapValue()
111
+ assert(mapValue.keySet().asScala.map(_.toString).contains("map-key-1"))
112
+ assertThat(
113
+ mapValue
114
+ .entrySet()
115
+ .asScala
116
+ .filter(_.getKey.toString.equals("map-key-1"))
117
+ .head
118
+ .getValue
119
+ .toString,
120
+ is("map-value-1")
121
+ )
122
+ assert(mapValue.keySet().asScala.map(_.toString).contains("map-key-2"))
123
+ assertThat(
124
+ mapValue
125
+ .entrySet()
126
+ .asScala
127
+ .filter(_.getKey.toString.equals("map-key-2"))
128
+ .head
129
+ .getValue
130
+ .asIntegerValue()
131
+ .asLong(),
132
+ is(456L)
133
+ )
134
+
135
+ }
136
+ }
137
+
138
+ @Test
139
+ def deprecatedQueryOperationTest(): Unit = {
140
+ val inConfig: ConfigSource = embulk.configLoader().fromYamlString(s"""
141
+ |type: dynamodb
142
+ |end_point: http://${dynamoDBHost}:${dynamoDBPort}/
143
+ |table: EMBULK_DYNAMODB_TEST_TABLE
144
+ |auth_method: basic
145
+ |access_key: dummy
146
+ |secret_key: dummy
147
+ |operation: query
148
+ |filters:
149
+ | - {name: pri-key, type: string, condition: EQ, value: key-1}
150
+ |columns:
151
+ | - {name: pri-key, type: string}
152
+ | - {name: sort-key, type: long}
153
+ | - {name: doubleValue, type: double}
154
+ | - {name: boolValue, type: boolean}
155
+ | - {name: listValue, type: json}
156
+ | - {name: mapValue, type: json}
157
+ |""".stripMargin)
158
+
159
+ testBackwardCompatibility(inConfig)
160
+ }
161
+
162
+ @Test
163
+ def keepTheSameBehaviourAsDeprecatedQueryOperationTest(): Unit = {
164
+ val inConfig: ConfigSource = embulk.configLoader().fromYamlString(s"""
165
+ |type: dynamodb
166
+ |endpoint: http://${dynamoDBHost}:${dynamoDBPort}/
167
+ |table: EMBULK_DYNAMODB_TEST_TABLE
168
+ |auth_method: basic
169
+ |access_key: dummy
170
+ |secret_key: dummy
171
+ |query:
172
+ | key_condition_expression: "#x = :v"
173
+ | expression_attribute_names:
174
+ | "#x": pri-key
175
+ | expression_attribute_values:
176
+ | ":v": {S: key-1}
177
+ |columns:
178
+ | - {name: pri-key, type: string}
179
+ | - {name: sort-key, type: long}
180
+ | - {name: doubleValue, type: double}
181
+ | - {name: boolValue, type: boolean}
182
+ | - {name: listValue, type: json}
183
+ | - {name: mapValue, type: json}
184
+ |""".stripMargin)
185
+
186
+ testBackwardCompatibility(inConfig)
187
+ }
188
+ }