[
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)