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
@@ -0,0 +1,59 @@
1
+ package org.embulk.input.dynamodb.operation
2
+
3
+ import java.util.Optional
4
+
5
+ import com.amazonaws.services.dynamodbv2.model.AttributeValue
6
+ import com.amazonaws.services.dynamodbv2.AmazonDynamoDB
7
+ import org.embulk.config.{
8
+ Config,
9
+ ConfigDefault,
10
+ ConfigException,
11
+ Task => EmbulkTask
12
+ }
13
+
14
+ object DynamodbOperationProxy {
15
+
16
+ trait Task extends EmbulkTask {
17
+
18
+ @Config("scan")
19
+ @ConfigDefault("null")
20
+ def getScan: Optional[DynamodbScanOperation.Task]
21
+
22
+ @Config("query")
23
+ @ConfigDefault("null")
24
+ def getQuery: Optional[DynamodbQueryOperation.Task]
25
+
26
+ @Config("table")
27
+ def getTable: String
28
+ }
29
+
30
+ def apply(task: Task): DynamodbOperationProxy = {
31
+ if (task.getScan.isPresent && task.getQuery.isPresent)
32
+ throw new ConfigException("You can use either \"scan\" or \"query\".")
33
+ if (!task.getScan.isPresent && !task.getQuery.isPresent)
34
+ throw new ConfigException("You must set either \"scan\" or \"query\".")
35
+ task.getScan.ifPresent(_.setTableName(task.getTable))
36
+ task.getQuery.ifPresent(_.setTableName(task.getTable))
37
+ new DynamodbOperationProxy(task)
38
+ }
39
+ }
40
+
41
+ case class DynamodbOperationProxy(task: DynamodbOperationProxy.Task)
42
+ extends EmbulkDynamodbOperation {
43
+
44
+ private def getOperation: EmbulkDynamodbOperation = {
45
+ task.getScan.ifPresent(t => return DynamodbScanOperation(t))
46
+ task.getQuery.ifPresent(t => return DynamodbQueryOperation(t))
47
+ throw new IllegalStateException()
48
+ }
49
+
50
+ private val operation: EmbulkDynamodbOperation = getOperation
51
+
52
+ override def getEmbulkTaskCount: Int = operation.getEmbulkTaskCount
53
+
54
+ override def run(
55
+ dynamodb: AmazonDynamoDB,
56
+ embulkTaskIndex: Int,
57
+ f: Seq[Map[String, AttributeValue]] => Unit
58
+ ): Unit = operation.run(dynamodb, embulkTaskIndex, f)
59
+ }
@@ -0,0 +1,72 @@
1
+ package org.embulk.input.dynamodb.operation
2
+
3
+ import com.amazonaws.services.dynamodbv2.model.{AttributeValue, QueryRequest}
4
+ import com.amazonaws.services.dynamodbv2.AmazonDynamoDB
5
+ import org.embulk.config.{Config, ConfigDefault}
6
+ import org.embulk.input.dynamodb.logger
7
+
8
+ import scala.jdk.CollectionConverters._
9
+ import scala.util.chaining._
10
+
11
+ object DynamodbQueryOperation {
12
+
13
+ trait Task extends AbstractDynamodbOperation.Task {
14
+
15
+ // ref. https://docs.aws.amazon.com/amazondynamodb/latest/developerguide/Query.html#Query.KeyConditionExpressions
16
+ @Config("key_condition_expression")
17
+ def getKeyConditionExpression: String
18
+
19
+ // TODO: Is it needed in the embulk context?
20
+ // ref. https://docs.aws.amazon.com/amazondynamodb/latest/developerguide/Query.html#Query.KeyConditionExpressions
21
+ @Config("scan_index_forward")
22
+ @ConfigDefault("true")
23
+ def getScanIndexForward: Boolean
24
+
25
+ }
26
+ }
27
+
28
+ case class DynamodbQueryOperation(task: DynamodbQueryOperation.Task)
29
+ extends AbstractDynamodbOperation(task) {
30
+
31
+ private def newRequest(
32
+ lastEvaluatedKey: Option[Map[String, AttributeValue]]
33
+ ): QueryRequest = {
34
+ new QueryRequest()
35
+ .tap(configureRequest(_, lastEvaluatedKey))
36
+ .tap(r => r.setKeyConditionExpression(task.getKeyConditionExpression))
37
+ .tap(r => r.setScanIndexForward(task.getScanIndexForward))
38
+ }
39
+
40
+ private def runInternal(
41
+ dynamodb: AmazonDynamoDB,
42
+ f: Seq[Map[String, AttributeValue]] => Unit,
43
+ lastEvaluatedKey: Option[Map[String, AttributeValue]] = None,
44
+ loadedRecords: Long = 0
45
+ ): Unit = {
46
+ val loadableRecords: Option[Long] = calculateLoadableRecords(loadedRecords)
47
+
48
+ val result = dynamodb.query(newRequest(lastEvaluatedKey).tap { req =>
49
+ logger.info(s"Call DynamodbQueryRequest: ${req.toString}")
50
+ })
51
+ loadableRecords match {
52
+ case Some(v) if (result.getCount > v) =>
53
+ f(result.getItems.asScala.take(v.toInt).map(_.asScala.toMap).toSeq)
54
+ case None =>
55
+ f(result.getItems.asScala.map(_.asScala.toMap).toSeq)
56
+ Option(result.getLastEvaluatedKey).foreach { lastEvaluatedKey =>
57
+ runInternal(
58
+ dynamodb,
59
+ f,
60
+ lastEvaluatedKey = Option(lastEvaluatedKey.asScala.toMap),
61
+ loadedRecords = loadedRecords + result.getCount
62
+ )
63
+ }
64
+ }
65
+ }
66
+
67
+ override def run(
68
+ dynamodb: AmazonDynamoDB,
69
+ embulkTaskIndex: Int,
70
+ f: Seq[Map[String, AttributeValue]] => Unit
71
+ ): Unit = runInternal(dynamodb, f)
72
+ }
@@ -0,0 +1,93 @@
1
+ package org.embulk.input.dynamodb.operation
2
+
3
+ import java.util.Optional
4
+
5
+ import com.amazonaws.services.dynamodbv2.model.{AttributeValue, ScanRequest}
6
+ import com.amazonaws.services.dynamodbv2.AmazonDynamoDB
7
+ import org.embulk.config.{Config, ConfigDefault, ConfigException}
8
+ import org.embulk.input.dynamodb.logger
9
+
10
+ import scala.jdk.CollectionConverters._
11
+ import scala.util.chaining._
12
+
13
+ object DynamodbScanOperation {
14
+
15
+ trait Task extends AbstractDynamodbOperation.Task {
16
+
17
+ // ref. https://docs.aws.amazon.com/amazondynamodb/latest/developerguide/Scan.html#Scan.ParallelScan
18
+ @Config("segment")
19
+ @ConfigDefault("null")
20
+ def getSegment: Optional[Int]
21
+
22
+ // ref. https://docs.aws.amazon.com/amazondynamodb/latest/developerguide/Scan.html#Scan.ParallelScan
23
+ @Config("total_segment")
24
+ @ConfigDefault("null")
25
+ def getTotalSegment: Optional[Int]
26
+
27
+ }
28
+ }
29
+
30
+ case class DynamodbScanOperation(task: DynamodbScanOperation.Task)
31
+ extends AbstractDynamodbOperation(task) {
32
+
33
+ override def getEmbulkTaskCount: Int = {
34
+ if (task.getTotalSegment.isPresent && task.getSegment.isPresent) 1
35
+ else if (task.getTotalSegment.isPresent && !task.getSegment.isPresent)
36
+ task.getTotalSegment.get()
37
+ else if (!task.getTotalSegment.isPresent && !task.getSegment.isPresent) 1
38
+ else // if (!task.getTotalSegment.isPresent && task.getSegment.isPresent)
39
+ throw new ConfigException(
40
+ "\"segment\" option must be set with \"total_segment\" option."
41
+ )
42
+ }
43
+
44
+ private def newRequest(
45
+ embulkTaskIndex: Int,
46
+ lastEvaluatedKey: Option[Map[String, AttributeValue]]
47
+ ): ScanRequest = {
48
+ new ScanRequest()
49
+ .tap(configureRequest(_, lastEvaluatedKey))
50
+ .tap { r =>
51
+ task.getTotalSegment.ifPresent { totalSegment =>
52
+ r.setTotalSegments(totalSegment)
53
+ r.setSegment(task.getSegment.orElse(embulkTaskIndex))
54
+ }
55
+ }
56
+ }
57
+
58
+ private def runInternal(
59
+ dynamodb: AmazonDynamoDB,
60
+ embulkTaskIndex: Int,
61
+ f: Seq[Map[String, AttributeValue]] => Unit,
62
+ lastEvaluatedKey: Option[Map[String, AttributeValue]] = None,
63
+ loadedRecords: Long = 0
64
+ ): Unit = {
65
+ val loadableRecords: Option[Long] = calculateLoadableRecords(loadedRecords)
66
+
67
+ val result =
68
+ dynamodb.scan(newRequest(embulkTaskIndex, lastEvaluatedKey).tap { req =>
69
+ logger.info(s"Call DynamodbQueryRequest: ${req.toString}")
70
+ })
71
+ loadableRecords match {
72
+ case Some(v) if (result.getCount > v) =>
73
+ f(result.getItems.asScala.take(v.toInt).map(_.asScala.toMap).toSeq)
74
+ case None =>
75
+ f(result.getItems.asScala.map(_.asScala.toMap).toSeq)
76
+ Option(result.getLastEvaluatedKey).foreach { lastEvaluatedKey =>
77
+ runInternal(
78
+ dynamodb,
79
+ embulkTaskIndex,
80
+ f,
81
+ lastEvaluatedKey = Option(lastEvaluatedKey.asScala.toMap),
82
+ loadedRecords = loadedRecords + result.getCount
83
+ )
84
+ }
85
+ }
86
+ }
87
+
88
+ override def run(
89
+ dynamodb: AmazonDynamoDB,
90
+ embulkTaskIndex: Int,
91
+ f: Seq[Map[String, AttributeValue]] => Unit
92
+ ): Unit = runInternal(dynamodb, embulkTaskIndex, f)
93
+ }
@@ -0,0 +1,15 @@
1
+ package org.embulk.input.dynamodb.operation
2
+
3
+ import com.amazonaws.services.dynamodbv2.AmazonDynamoDB
4
+ import com.amazonaws.services.dynamodbv2.model.AttributeValue
5
+
6
+ trait EmbulkDynamodbOperation {
7
+
8
+ def getEmbulkTaskCount: Int = 1
9
+
10
+ def run(
11
+ dynamodb: AmazonDynamoDB,
12
+ embulkTaskIndex: Int,
13
+ f: Seq[Map[String, AttributeValue]] => Unit
14
+ ): Unit
15
+ }
@@ -1,14 +1,9 @@
1
1
  package org.embulk.input
2
2
 
3
- import com.google.common.base.Optional
4
- import org.embulk.config.ConfigException
3
+ import org.slf4j.{Logger, LoggerFactory}
5
4
 
6
5
  package object dynamodb {
7
- def require[A](value: Optional[A], message: String): A = {
8
- if (value.isPresent) {
9
- value.get()
10
- } else {
11
- throw new ConfigException("Required option is not set: " + message)
12
- }
13
- }
6
+
7
+ val logger: Logger = LoggerFactory.getLogger(classOf[DynamodbInputPlugin])
8
+
14
9
  }
@@ -1,20 +1,21 @@
1
1
  package org.embulk.input.dynamodb
2
2
 
3
-
4
3
  import java.io.File
5
4
  import java.{util => JUtil}
6
5
 
7
6
  import com.amazonaws.services.dynamodbv2.model.AttributeValue
8
7
  import com.fasterxml.jackson.databind.ObjectMapper
9
- import org.embulk.input.dynamodb.AttributeValueHelper._
8
+ import org.embulk.input.dynamodb.deprecated.AttributeValueHelper._
10
9
  import org.hamcrest.CoreMatchers._
10
+ import org.hamcrest.MatcherAssert.assertThat
11
11
  import org.junit.Assert._
12
12
  import org.junit.Test
13
13
  import org.msgpack.value.ValueFactory
14
14
 
15
- import scala.collection.JavaConverters._
15
+ import scala.jdk.CollectionConverters._
16
16
 
17
17
  class AttributeValueHelperTest {
18
+
18
19
  @Test
19
20
  def decodeTest(): Unit = {
20
21
  val stringValue = decodeToValue(new AttributeValue().withS("STR"))
@@ -23,7 +24,9 @@ class AttributeValueHelperTest {
23
24
  val intValue = decodeToValue(new AttributeValue().withN("123456789"))
24
25
  assertEquals(intValue.asNumberValue().toInt, 123456789)
25
26
 
26
- val doubleValue = decodeToValue(new AttributeValue().withN("-98765432.00000001"))
27
+ val doubleValue = decodeToValue(
28
+ new AttributeValue().withN("-98765432.00000001")
29
+ )
27
30
  assertEquals(doubleValue.asNumberValue().toDouble, -98765432.00000001, 0.0)
28
31
 
29
32
  val trueValue = decodeToValue(new AttributeValue().withBOOL(true))
@@ -36,162 +39,303 @@ class AttributeValueHelperTest {
36
39
  assertEquals(nilValue.isNilValue, true)
37
40
  }
38
41
 
39
-
40
42
  @Test
41
43
  def listDecodeTest(): Unit = {
42
- val stringListValue = decodeToValue(new AttributeValue().withL(
43
- new AttributeValue().withS("ValueA"),
44
- new AttributeValue().withS("ValueB"),
45
- new AttributeValue().withS("ValueC")))
44
+ val stringListValue = decodeToValue(
45
+ new AttributeValue().withL(
46
+ new AttributeValue().withS("ValueA"),
47
+ new AttributeValue().withS("ValueB"),
48
+ new AttributeValue().withS("ValueC")
49
+ )
50
+ )
46
51
 
47
52
  assertTrue(stringListValue.isArrayValue)
48
53
  assertEquals(stringListValue.asArrayValue().size(), 3)
49
54
 
50
55
  assertTrue(stringListValue.asArrayValue().get(0).isStringValue)
51
- assertEquals(stringListValue.asArrayValue().get(0).asStringValue().asString(), "ValueA")
52
- assertEquals(stringListValue.asArrayValue().get(1).asStringValue().asString(), "ValueB")
53
- assertEquals(stringListValue.asArrayValue().get(2).asStringValue().asString(), "ValueC")
54
-
55
-
56
- val numberListValue = decodeToValue(new AttributeValue().withL(
57
- new AttributeValue().withN("123"),
58
- new AttributeValue().withN("-456"),
59
- new AttributeValue().withN("0.0000045679"),
60
- new AttributeValue().withN("-1234567890.123")))
56
+ assertEquals(
57
+ stringListValue.asArrayValue().get(0).asStringValue().asString(),
58
+ "ValueA"
59
+ )
60
+ assertEquals(
61
+ stringListValue.asArrayValue().get(1).asStringValue().asString(),
62
+ "ValueB"
63
+ )
64
+ assertEquals(
65
+ stringListValue.asArrayValue().get(2).asStringValue().asString(),
66
+ "ValueC"
67
+ )
68
+
69
+ val numberListValue = decodeToValue(
70
+ new AttributeValue().withL(
71
+ new AttributeValue().withN("123"),
72
+ new AttributeValue().withN("-456"),
73
+ new AttributeValue().withN("0.0000045679"),
74
+ new AttributeValue().withN("-1234567890.123")
75
+ )
76
+ )
61
77
 
62
78
  assertTrue(numberListValue.isArrayValue)
63
79
  assertEquals(numberListValue.asArrayValue().size(), 4)
64
80
 
65
81
  assertTrue(numberListValue.asArrayValue().get(0).isIntegerValue)
66
- assertEquals(numberListValue.asArrayValue().get(0).asNumberValue().toInt, 123)
67
- assertEquals(numberListValue.asArrayValue().get(1).asNumberValue().toInt, -456)
82
+ assertEquals(
83
+ numberListValue.asArrayValue().get(0).asNumberValue().toInt,
84
+ 123
85
+ )
86
+ assertEquals(
87
+ numberListValue.asArrayValue().get(1).asNumberValue().toInt,
88
+ -456
89
+ )
68
90
 
69
91
  assertTrue(numberListValue.asArrayValue().get(2).isFloatValue)
70
- assertEquals(numberListValue.asArrayValue().get(2).asNumberValue().toDouble, 0.0000045679, 0.0)
71
- assertEquals(numberListValue.asArrayValue().get(3).asNumberValue().toDouble, -1234567890.123, 0.0)
72
-
73
-
74
- val stringSetValue = decodeToValue(new AttributeValue().withSS(
75
- new JUtil.HashSet[String]() {
92
+ assertEquals(
93
+ numberListValue.asArrayValue().get(2).asNumberValue().toDouble,
94
+ 0.0000045679,
95
+ 0.0
96
+ )
97
+ assertEquals(
98
+ numberListValue.asArrayValue().get(3).asNumberValue().toDouble,
99
+ -1234567890.123,
100
+ 0.0
101
+ )
102
+
103
+ val stringSetValue = decodeToValue(
104
+ new AttributeValue().withSS(new JUtil.HashSet[String]() {
76
105
  add("ValueA")
77
106
  add("ValueB")
78
107
  add("ValueC")
79
- }))
108
+ })
109
+ )
80
110
 
81
111
  assertTrue(stringSetValue.isArrayValue)
82
112
  assertEquals(stringSetValue.asArrayValue().size(), 3)
83
113
 
84
- assertThat(List("ValueA", "ValueB", "ValueC").asJava,
114
+ assertThat(
115
+ List("ValueA", "ValueB", "ValueC").asJava,
85
116
  hasItems(
86
117
  equalTo(stringSetValue.asArrayValue().get(0).asStringValue().asString),
87
118
  equalTo(stringSetValue.asArrayValue().get(1).asStringValue().asString),
88
- equalTo(stringSetValue.asArrayValue().get(2).asStringValue().asString)))
89
-
119
+ equalTo(stringSetValue.asArrayValue().get(2).asStringValue().asString)
120
+ )
121
+ )
90
122
 
91
- val numberSetValue = decodeToValue(new AttributeValue().withNS(
92
- new JUtil.HashSet[String]() {
123
+ val numberSetValue = decodeToValue(
124
+ new AttributeValue().withNS(new JUtil.HashSet[String]() {
93
125
  add("123")
94
126
  add("-456")
95
127
  add("0.0000045679")
96
128
  add("-1234567890.123")
97
- }))
129
+ })
130
+ )
98
131
 
99
132
  assertTrue(numberSetValue.isArrayValue)
100
133
  assertEquals(numberSetValue.asArrayValue().size(), 4)
101
134
  }
102
135
 
103
-
104
136
  @Test
105
137
  def mapDecodeTest(): Unit = {
106
- val stringMap = decodeToValue(new AttributeValue().withM(
107
- new JUtil.HashMap[String, AttributeValue]() {
138
+ val stringMap = decodeToValue(
139
+ new AttributeValue().withM(new JUtil.HashMap[String, AttributeValue]() {
108
140
  put("KeyA", new AttributeValue().withS("ValueA"))
109
141
  put("KeyB", new AttributeValue().withS("ValueB"))
110
142
  put("KeyC", new AttributeValue().withS("ValueC"))
111
- }))
143
+ })
144
+ )
112
145
 
113
146
  assertTrue(stringMap.isMapValue)
114
147
  assertEquals(stringMap.asMapValue().size(), 3)
115
- assertEquals(stringMap.asMapValue().map().get(ValueFactory.newString("KeyA")).asStringValue().asString(), "ValueA")
116
- assertEquals(stringMap.asMapValue().map().get(ValueFactory.newString("KeyB")).asStringValue().asString(), "ValueB")
117
- assertEquals(stringMap.asMapValue().map().get(ValueFactory.newString("KeyC")).asStringValue().asString(), "ValueC")
118
-
119
-
120
- val numberMap = decodeToValue(new AttributeValue().withM(
121
- new JUtil.HashMap[String, AttributeValue]() {
148
+ assertEquals(
149
+ stringMap
150
+ .asMapValue()
151
+ .map()
152
+ .get(ValueFactory.newString("KeyA"))
153
+ .asStringValue()
154
+ .asString(),
155
+ "ValueA"
156
+ )
157
+ assertEquals(
158
+ stringMap
159
+ .asMapValue()
160
+ .map()
161
+ .get(ValueFactory.newString("KeyB"))
162
+ .asStringValue()
163
+ .asString(),
164
+ "ValueB"
165
+ )
166
+ assertEquals(
167
+ stringMap
168
+ .asMapValue()
169
+ .map()
170
+ .get(ValueFactory.newString("KeyC"))
171
+ .asStringValue()
172
+ .asString(),
173
+ "ValueC"
174
+ )
175
+
176
+ val numberMap = decodeToValue(
177
+ new AttributeValue().withM(new JUtil.HashMap[String, AttributeValue]() {
122
178
  put("KeyA", new AttributeValue().withN("123"))
123
179
  put("KeyB", new AttributeValue().withN("-456"))
124
180
  put("KeyC", new AttributeValue().withN("0.0000045679"))
125
181
  put("KeyD", new AttributeValue().withN("-1234567890.123"))
126
- }))
182
+ })
183
+ )
127
184
 
128
185
  assertTrue(numberMap.isMapValue)
129
186
  assertEquals(numberMap.asMapValue().size(), 4)
130
187
 
131
- assertTrue(numberMap.asMapValue().map().get(ValueFactory.newString("KeyA")).isIntegerValue)
132
- assertEquals(numberMap.asMapValue().map().get(ValueFactory.newString("KeyA")).asNumberValue().toInt, 123)
133
- assertEquals(numberMap.asMapValue().map().get(ValueFactory.newString("KeyB")).asNumberValue().toInt, -456)
134
-
135
- assertTrue(numberMap.asMapValue().map().get(ValueFactory.newString("KeyC")).isFloatValue)
136
- assertEquals(numberMap.asMapValue().map().get(ValueFactory.newString("KeyC")).asFloatValue().toDouble, 0.0000045679, 0.0)
137
- assertEquals(numberMap.asMapValue().map().get(ValueFactory.newString("KeyD")).asFloatValue().toDouble, -1234567890.123, 0.0)
188
+ assertTrue(
189
+ numberMap
190
+ .asMapValue()
191
+ .map()
192
+ .get(ValueFactory.newString("KeyA"))
193
+ .isIntegerValue
194
+ )
195
+ assertEquals(
196
+ numberMap
197
+ .asMapValue()
198
+ .map()
199
+ .get(ValueFactory.newString("KeyA"))
200
+ .asNumberValue()
201
+ .toInt,
202
+ 123
203
+ )
204
+ assertEquals(
205
+ numberMap
206
+ .asMapValue()
207
+ .map()
208
+ .get(ValueFactory.newString("KeyB"))
209
+ .asNumberValue()
210
+ .toInt,
211
+ -456
212
+ )
213
+
214
+ assertTrue(
215
+ numberMap
216
+ .asMapValue()
217
+ .map()
218
+ .get(ValueFactory.newString("KeyC"))
219
+ .isFloatValue
220
+ )
221
+ assertEquals(
222
+ numberMap
223
+ .asMapValue()
224
+ .map()
225
+ .get(ValueFactory.newString("KeyC"))
226
+ .asFloatValue()
227
+ .toDouble,
228
+ 0.0000045679,
229
+ 0.0
230
+ )
231
+ assertEquals(
232
+ numberMap
233
+ .asMapValue()
234
+ .map()
235
+ .get(ValueFactory.newString("KeyD"))
236
+ .asFloatValue()
237
+ .toDouble,
238
+ -1234567890.123,
239
+ 0.0
240
+ )
138
241
  }
139
242
 
140
- def attr[A](value: A)(implicit f: A=> AttributeValue): AttributeValue = f(value)
141
- implicit def StringAttributeValue(value: String): AttributeValue
142
- = new AttributeValue().withS(value)
143
- implicit def IntegerAttributeValue(value: Int): AttributeValue
144
- = new AttributeValue().withN(value.toString)
145
- implicit def LongAttributeValue(value: Long): AttributeValue
146
- = new AttributeValue().withN(value.toString)
147
- implicit def FloatAttributeValue(value: Float): AttributeValue
148
- = new AttributeValue().withN(value.toString)
149
- implicit def DoubleAttributeValue(value: Double): AttributeValue
150
- = new AttributeValue().withN(value.toString)
151
- implicit def BooleanAttributeValue(value: Boolean): AttributeValue
152
- = new AttributeValue().withBOOL(value)
153
- implicit def MapAttributeValue(value: Map[String, AttributeValue]): AttributeValue
154
- = new AttributeValue().withM(value.asJava)
155
- implicit def ListAttributeValue(value: List[AttributeValue]): AttributeValue
156
- = new AttributeValue().withL(value.asJava)
243
+ def attr[A](value: A)(implicit f: A => AttributeValue): AttributeValue =
244
+ f(value)
245
+
246
+ implicit def StringAttributeValue(value: String): AttributeValue =
247
+ new AttributeValue().withS(value)
248
+
249
+ implicit def IntegerAttributeValue(value: Int): AttributeValue =
250
+ new AttributeValue().withN(value.toString)
251
+
252
+ implicit def LongAttributeValue(value: Long): AttributeValue =
253
+ new AttributeValue().withN(value.toString)
254
+
255
+ implicit def FloatAttributeValue(value: Float): AttributeValue =
256
+ new AttributeValue().withN(value.toString)
257
+
258
+ implicit def DoubleAttributeValue(value: Double): AttributeValue =
259
+ new AttributeValue().withN(value.toString)
260
+
261
+ implicit def BooleanAttributeValue(value: Boolean): AttributeValue =
262
+ new AttributeValue().withBOOL(value)
263
+
264
+ implicit def MapAttributeValue(
265
+ value: Map[String, AttributeValue]
266
+ ): AttributeValue = new AttributeValue().withM(value.asJava)
267
+
268
+ implicit def ListAttributeValue(value: List[AttributeValue]): AttributeValue =
269
+ new AttributeValue().withL(value.asJava)
157
270
 
158
271
  @Test
159
272
  def nestedDecodeTest(): Unit = {
160
273
  // TODO: Json -> AttributeValue...
161
- val testData = decodeToValue(attr(Map(
162
- "_id" -> attr("56d8e1377a72374918f73bd2"),
163
- "index" -> attr(0),
164
- "guid" -> attr("5309640c-499a-43f6-801d-3076c810892b"),
165
- "isActive" -> attr(true),
166
- "age" -> attr(37),
167
- "name" -> attr("Battle Lancaster"),
168
- "email" -> attr("battlelancaster@zytrac.com"),
169
- "registered" -> attr("2014-07-16T04:40:58 -09:00"),
170
- "latitude" -> attr(45.574906),
171
- "longitude" -> attr(36.596302),
172
- "tags" -> attr(List(
173
- attr("veniam"),
174
- attr("exercitation"),
175
- attr("velit"),
176
- attr("pariatur"),
177
- attr("sit"),
178
- attr("non"),
179
- attr("dolore"))),
180
- "friends" -> attr(List(
181
- attr(Map("id" -> attr(0), "name" -> attr("Mejia Montgomery"),
182
- "tags" -> attr(List(attr("duis"), attr("proident"), attr("et"))))),
183
- attr(Map("id" -> attr(1), "name" -> attr("Carpenter Reed"),
184
- "tags" -> attr(List(attr("labore"), attr("nisi"), attr("ipsum"))))),
185
- attr(Map("id" -> attr(2), "name" -> attr("Gamble Watts"),
186
- "tags" -> attr(List(attr("occaecat"), attr("voluptate"), attr("eu")))))
187
- ))
274
+ val testData = decodeToValue(
275
+ attr(
276
+ Map(
277
+ "_id" -> attr("56d8e1377a72374918f73bd2"),
278
+ "index" -> attr(0),
279
+ "guid" -> attr("5309640c-499a-43f6-801d-3076c810892b"),
280
+ "isActive" -> attr(true),
281
+ "age" -> attr(37),
282
+ "name" -> attr("Battle Lancaster"),
283
+ "email" -> attr("battlelancaster@zytrac.com"),
284
+ "registered" -> attr("2014-07-16T04:40:58 -09:00"),
285
+ "latitude" -> attr(45.574906),
286
+ "longitude" -> attr(36.596302),
287
+ "tags" -> attr(
288
+ List(
289
+ attr("veniam"),
290
+ attr("exercitation"),
291
+ attr("velit"),
292
+ attr("pariatur"),
293
+ attr("sit"),
294
+ attr("non"),
295
+ attr("dolore")
296
+ )
297
+ ),
298
+ "friends" -> attr(
299
+ List(
300
+ attr(
301
+ Map(
302
+ "id" -> attr(0),
303
+ "name" -> attr("Mejia Montgomery"),
304
+ "tags" -> attr(
305
+ List(attr("duis"), attr("proident"), attr("et"))
306
+ )
307
+ )
308
+ ),
309
+ attr(
310
+ Map(
311
+ "id" -> attr(1),
312
+ "name" -> attr("Carpenter Reed"),
313
+ "tags" -> attr(
314
+ List(attr("labore"), attr("nisi"), attr("ipsum"))
315
+ )
316
+ )
317
+ ),
318
+ attr(
319
+ Map(
320
+ "id" -> attr(2),
321
+ "name" -> attr("Gamble Watts"),
322
+ "tags" -> attr(
323
+ List(attr("occaecat"), attr("voluptate"), attr("eu"))
324
+ )
325
+ )
326
+ )
327
+ )
328
+ )
329
+ )
188
330
  )
189
- ))
331
+ )
190
332
 
191
- val testA = new ObjectMapper().readValue(
192
- testData.toJson, classOf[JUtil.Map[String, Any]])
333
+ val testA = new ObjectMapper()
334
+ .readValue(testData.toJson, classOf[JUtil.Map[String, Any]])
193
335
  val testB = new ObjectMapper().readValue(
194
- new File("src/test/resources/json/test.json"), classOf[JUtil.Map[String, Any]])
336
+ new File("src/test/resources/json/test.json"),
337
+ classOf[JUtil.Map[String, Any]]
338
+ )
195
339
 
196
340
  assertThat(testA, is(testB))
197
341
  }