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)

Reply via email to