Kumar Gaurav created CAMEL-22038:
------------------------------------
Summary: aws-ddb: float/doubles are being set as ddb attribute
type=S while using transformer - Ddb2JsonDataTypeTransformer
Key: CAMEL-22038
URL: https://issues.apache.org/jira/browse/CAMEL-22038
Project: Camel
Issue Type: Bug
Components: camel-aws, camel-aws2
Affects Versions: 4.4.5
Reporter: Kumar Gaurav
We are using Ddb2JsonDataTypeTransformer to serialize the json input to
DynamoDB AttributeValue Map for all the attributes before sending the paylaod
to dynamodb put operation.
My input payload :
Route endpoint:
Issue:
We are seeing the floating point value in above json being saved to dynamodb as
type=S instead of N.
*Why this problem?*
When I debugged this class
{*}org.apache.camel.component.aws2.ddb.transform.Ddb2JsonDataTypeTransformer{*},
I found that there is no condition in method (which checks and matches data
types to attribute value types) for float/double data type. Hence, all
float/default values are getting defaulted back to type=S.
{quote} private static AttributeValue getAttributeValue(Object value) {
if (value == null) {
return AttributeValue.builder().nul(true).build();
}
if (value instanceof String) {
return AttributeValue.builder().s(value.toString()).build();
}
if (value instanceof Integer) {
return AttributeValue.builder().n(value.toString()).build();
}
if (value instanceof Boolean) {
return AttributeValue.builder().bool((Boolean) value).build();
}
if (value instanceof String[]) {
return AttributeValue.builder().ss((String[]) value).build();
}
if (value instanceof int[]) {
return AttributeValue.builder().ns(Stream.of((int[])
value).map(Object::toString).collect(Collectors.toList()))
.build();
}
if (value instanceof List) {
List<?> values = (List<?>) value;
if (values.isEmpty()) {
return AttributeValue.builder().ss().build();
} else if (values.get(0) instanceof Integer) {
return
AttributeValue.builder().ns(values.stream().map(Object::toString).collect(Collectors.toList())).build();
} else {
return
AttributeValue.builder().ss(values.stream().map(Object::toString).collect(Collectors.toList())).build();
}
}
if (value instanceof Map) {
Map<String, AttributeValue> nestedAttributes = new
LinkedHashMap<>();
for (Map.Entry<?, ?> nested : ((Map<?, ?>) value).entrySet()) {
nestedAttributes.put(nested.getKey().toString(),
getAttributeValue(nested.getValue()));
}
return AttributeValue.builder().m(nestedAttributes).build();
}
*return AttributeValue.builder().s(value.toString()).build();*
}
{quote}
So - the current code in this class as below should have an if condition to
match the data type to float/double and set the attribute type for such values
as N:
*if (value instanceof Double) {*
*return AttributeValue.builder().n(value.toString()).build();*
*}*
The fix should be included is as follows:
{quote} private static AttributeValue getAttributeValue(Object value) {
if (value == null) {
return AttributeValue.builder().nul(true).build();
}
if (value instanceof String) {
return AttributeValue.builder().s(value.toString()).build();
}
if (value instanceof Integer) {
return AttributeValue.builder().n(value.toString()).build();
}
*if (value instanceof Double) {*
*return AttributeValue.builder().n(value.toString()).build();*
*}*
if (value instanceof Boolean) {
return AttributeValue.builder().n((Boolean) value).build();
}
if (value instanceof String[]) {
return AttributeValue.builder().ss((String[]) value).build();
}
if (value instanceof int[]) {
return AttributeValue.builder().ns(Stream.of((int[])
value).map(Object::toString).collect(Collectors.toList()))
.build();
}
if (value instanceof List) {
List<?> values = (List<?>) value;
if (values.isEmpty()) {
return AttributeValue.builder().ss().build();
} else if (values.get(0) instanceof Integer) {
return
AttributeValue.builder().ns(values.stream().map(Object::toString).collect(Collectors.toList())).build();
} else {
return
AttributeValue.builder().ss(values.stream().map(Object::toString).collect(Collectors.toList())).build();
}
}
if (value instanceof Map) {
Map<String, AttributeValue> nestedAttributes = new
LinkedHashMap<>();
for (Map.Entry<?, ?> nested : ((Map<?, ?>) value).entrySet()) {
nestedAttributes.put(nested.getKey().toString(),
getAttributeValue(nested.getValue()));
}
return AttributeValue.builder().m(nestedAttributes).build();
}
return AttributeValue.builder().s(value.toString()).build();
}
{quote}
--
This message was sent by Atlassian Jira
(v8.20.10#820010)