0

I've got the following example of using Camels Bindy, but eventually it raises assertion error because bindy transforms BigDecimal in wrong way (using comma instead of dot for number delimiter).

What is wrong with this code ?

public class PurchaseOrderBindyTest extends TestCase {

    @Test
    public void testBindy() throws Exception {
        CamelContext context = new DefaultCamelContext();
        context.addRoutes(createRoute());
        context.start();

        MockEndpoint mock = context.getEndpoint("mock:result", MockEndpoint.class);
        mock.expectedBodiesReceived("Camel in Action,39.95,1\n");

        PurchaseOrder order = new PurchaseOrder();
        order.setAmount(1);
        order.setPrice(new BigDecimal("39.95"));
        order.setName("Camel in Action");

        ProducerTemplate template = context.createProducerTemplate();
        template.sendBody("direct:toCsv", order);

        mock.assertIsSatisfied();
    }

    public RouteBuilder createRoute() {
        return new RouteBuilder() {
            public void configure() throws Exception {
                from("direct:toCsv")
                        .marshal().bindy(BindyType.Csv, "camelinaction.bindy")
                        .to("mock:result");
            }
        };
    }
}

Model

@CsvRecord(separator = ",", crlf = "UNIX")
public class PurchaseOrder {

    @DataField(pos = 1)
    private String name;

    @DataField(pos = 2, precision = 2)
    private BigDecimal price;

    @DataField(pos = 3)
    private int amount;

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public BigDecimal getPrice() {
        return price;
    }

    public void setPrice(BigDecimal price) {
        this.price = price;
    }

    public int getAmount() {
        return amount;
    }

    public void setAmount(int amount) {
        this.amount = amount;
    }
}

Assertion Error

java.lang.AssertionError: mock://result Body of message: 0. Expected: <Camel in Action,39.95,1
> but was: <Camel in Action.39,95.1
>
ashur
  • 4,177
  • 14
  • 53
  • 85
  • 1
    Do you have a locale set? There is this problem https://issues.apache.org/jira/browse/CAMEL-5326 but was fixed a while ago. – matt helliwell Nov 11 '14 at 16:15
  • 1
    My test passed without any problems. Funny that "." and "," seem to be reversed. The "," problem could be related to the local dependent `BigDecimal` String representation. But the "." problem is strange as you define the "," separator in the `@CsvRecord` annotation. Is this really the route you have tested? Which locale do you use? – Peter Keller Nov 11 '14 at 20:24
  • @Peter Yes, that was the route I tested. I'm not sure how to check/change the locale, could you give me an example ? – ashur Nov 13 '14 at 08:39
  • 1
    Get the default: `Locale.getDefault()`, set the default: `Locale.setDefault(new Locale ("en", "US"))` – Peter Keller Nov 13 '14 at 15:06
  • @Peter It's strange because calling `Locale.getDefault();` returned `en_US` and when I set default locale by calling `Locale.setDefault(new Locale ("en", "US"))` it started to work properly. I don't get it – ashur Nov 14 '14 at 08:38

1 Answers1

1

My test passed without any problems. It is funny that in your case the "." and "," seem to be reversed.

Camel uses the java.text.DecimalFormat class that determines the locale as follows:

Locale def = Locale.getDefault(Locale.Category.FORMAT);

You may reset the locale default as follows:

Locale.setDefault(new Locale ("en", "US"));

If you don't want to reset the default locale, you may set the locale as follows:

BindyCsvDataFormat bindy = new BindyCsvDataFormat(PurchaseOrder.class);
bindy.setLocale(Locale.US.getCountry());

from("direct:toCsv")
    .marshal(bindy)
    ...

In this case, Camel resets the decimal format symbols in AbstractNumberFormat as follows:

if (locale != null) {
    this.format.setDecimalFormatSymbols(DecimalFormatSymbols.getInstance(locale));
}
Peter Keller
  • 7,526
  • 2
  • 26
  • 29