[ 
https://issues.apache.org/jira/browse/CAMEL-22038?page=com.atlassian.jira.plugin.system.issuetabpanels:all-tabpanel
 ]

Kumar Gaurav updated CAMEL-22038:
---------------------------------
    Description: 
We are using Ddb2JsonDataTypeTransformer   to serialize the json input to 
DynamoDB AttributeValue Map for all the attributes before sending the payload 
(to create an item in dynamodb table) to DynamoDB put operation. 

My input payload: 
{quote}{
  "operation": "PutItem",
  "item": {
    "Id": "1340",
    "FirstName": "ChrisFloat",
    "LastName": "Kotner",
        "FloatTest": 45.25
  }
}
{quote}
 

Route sink endpoint: 
{quote}.to(aws2Ddb("tablename"))
{quote}
 

+*Issue:*+ 

We are seeing the floating-point value in above Json which are 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)
Unknown macro: \{             return 
AttributeValue.builder().nul(true).build();         }
        if (value instanceof String)
Unknown macro: \{             return 
AttributeValue.builder().s(value.toString()).build();         }
        if (value instanceof Integer)
Unknown macro: \{             return 
AttributeValue.builder().n(value.toString()).build();         }
        if (value instanceof Boolean)
Unknown macro: \{             return AttributeValue.builder().bool((Boolean) 
value).build();         }
        if (value instanceof String[])
Unknown macro: \{             return AttributeValue.builder().ss((String[]) 
value).build();         }
        if (value instanceof int[])
Unknown macro: \{             return 
AttributeValue.builder().ns(Stream.of((int[]) value).map(Object}
        if (value instanceof List) {
            List<?> values = (List<?>) value;

            if (values.isEmpty())
Unknown macro: \{                 return AttributeValue.builder().ss().build(); 
            }
else if (values.get(0) instanceof Integer)
Unknown macro: \{                 return 
AttributeValue.builder().ns(values.stream().map(Object}
else
Unknown macro: \{                 return 
AttributeValue.builder().ss(values.stream().map(Object}
        }

        if (value instanceof Map) {
            Map<String, AttributeValue> nestedAttributes = new 
LinkedHashMap<>();

            for (Map.Entry<?, ?> nested : ((Map<?, ?>) value).entrySet())
Unknown macro: \{                 
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)
Unknown macro: \{             return 
AttributeValue.builder().nul(true).build();         }
        if (value instanceof String)
Unknown macro: \{             return 
AttributeValue.builder().s(value.toString()).build();         }
        if (value instanceof Integer)
Unknown macro: \{             return 
AttributeValue.builder().n(value.toString()).build();         }
        *if (value instanceof Double) {*
           *return AttributeValue.builder().n(value.toString()).build();*
        *}*

        if (value instanceof Boolean)
Unknown macro: \{             return AttributeValue.builder().n((Boolean) 
value).build();         }
        if (value instanceof String[])
Unknown macro: \{             return AttributeValue.builder().ss((String[]) 
value).build();         }
        if (value instanceof int[])
Unknown macro: \{             return 
AttributeValue.builder().ns(Stream.of((int[]) value).map(Object}
        if (value instanceof List) {
            List<?> values = (List<?>) value;

            if (values.isEmpty())
Unknown macro: \{                 return AttributeValue.builder().ss().build(); 
            }
else if (values.get(0) instanceof Integer)
Unknown macro: \{                 return 
AttributeValue.builder().ns(values.stream().map(Object}
else
Unknown macro: \{                 return 
AttributeValue.builder().ss(values.stream().map(Object}
        }

        if (value instanceof Map) {
            Map<String, AttributeValue> nestedAttributes = new 
LinkedHashMap<>();

            for (Map.Entry<?, ?> nested : ((Map<?, ?>) value).entrySet())
Unknown macro: \{                 
nestedAttributes.put(nested.getKey().toString(), 
getAttributeValue(nested.getValue()));             }
            return AttributeValue.builder().m(nestedAttributes).build();
        }

        return AttributeValue.builder().s(value.toString()).build();
    }
{quote}
 

 

 

 

  was:
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}
 

 

 

 


> 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
>            Priority: Major
>
> We are using Ddb2JsonDataTypeTransformer   to serialize the json input to 
> DynamoDB AttributeValue Map for all the attributes before sending the payload 
> (to create an item in dynamodb table) to DynamoDB put operation. 
> My input payload: 
> {quote}{
>   "operation": "PutItem",
>   "item": {
>     "Id": "1340",
>     "FirstName": "ChrisFloat",
>     "LastName": "Kotner",
>         "FloatTest": 45.25
>   }
> }
> {quote}
>  
> Route sink endpoint: 
> {quote}.to(aws2Ddb("tablename"))
> {quote}
>  
> +*Issue:*+ 
> We are seeing the floating-point value in above Json which are 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)
> Unknown macro: \{             return 
> AttributeValue.builder().nul(true).build();         }
>         if (value instanceof String)
> Unknown macro: \{             return 
> AttributeValue.builder().s(value.toString()).build();         }
>         if (value instanceof Integer)
> Unknown macro: \{             return 
> AttributeValue.builder().n(value.toString()).build();         }
>         if (value instanceof Boolean)
> Unknown macro: \{             return AttributeValue.builder().bool((Boolean) 
> value).build();         }
>         if (value instanceof String[])
> Unknown macro: \{             return AttributeValue.builder().ss((String[]) 
> value).build();         }
>         if (value instanceof int[])
> Unknown macro: \{             return 
> AttributeValue.builder().ns(Stream.of((int[]) value).map(Object}
>         if (value instanceof List) {
>             List<?> values = (List<?>) value;
>             if (values.isEmpty())
> Unknown macro: \{                 return 
> AttributeValue.builder().ss().build();             }
> else if (values.get(0) instanceof Integer)
> Unknown macro: \{                 return 
> AttributeValue.builder().ns(values.stream().map(Object}
> else
> Unknown macro: \{                 return 
> AttributeValue.builder().ss(values.stream().map(Object}
>         }
>         if (value instanceof Map) {
>             Map<String, AttributeValue> nestedAttributes = new 
> LinkedHashMap<>();
>             for (Map.Entry<?, ?> nested : ((Map<?, ?>) value).entrySet())
> Unknown macro: \{                 
> 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)
> Unknown macro: \{             return 
> AttributeValue.builder().nul(true).build();         }
>         if (value instanceof String)
> Unknown macro: \{             return 
> AttributeValue.builder().s(value.toString()).build();         }
>         if (value instanceof Integer)
> Unknown macro: \{             return 
> AttributeValue.builder().n(value.toString()).build();         }
>         *if (value instanceof Double) {*
>            *return AttributeValue.builder().n(value.toString()).build();*
>         *}*
>         if (value instanceof Boolean)
> Unknown macro: \{             return AttributeValue.builder().n((Boolean) 
> value).build();         }
>         if (value instanceof String[])
> Unknown macro: \{             return AttributeValue.builder().ss((String[]) 
> value).build();         }
>         if (value instanceof int[])
> Unknown macro: \{             return 
> AttributeValue.builder().ns(Stream.of((int[]) value).map(Object}
>         if (value instanceof List) {
>             List<?> values = (List<?>) value;
>             if (values.isEmpty())
> Unknown macro: \{                 return 
> AttributeValue.builder().ss().build();             }
> else if (values.get(0) instanceof Integer)
> Unknown macro: \{                 return 
> AttributeValue.builder().ns(values.stream().map(Object}
> else
> Unknown macro: \{                 return 
> AttributeValue.builder().ss(values.stream().map(Object}
>         }
>         if (value instanceof Map) {
>             Map<String, AttributeValue> nestedAttributes = new 
> LinkedHashMap<>();
>             for (Map.Entry<?, ?> nested : ((Map<?, ?>) value).entrySet())
> Unknown macro: \{                 
> 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