You are viewing a plain text version of this content. The canonical link for it is here.
Posted to users@camel.apache.org by Reji Mathews <co...@gmail.com> on 2020/09/22 15:59:07 UTC

Rolling back transaction with custom error message using onException

Hello community

I have a requirement
-  Route needs to be transacted  :  If some failure happens, jdbc operation
should be rolled-back
- I need to send back a custom error message to API caller. (am trying to
do do that in onException)

But, I see the transaction rollback doesn't work if I use handled=true in
the onException block.
Alternatively, it works flawlessly if I flip it to false, but I get ugly
stack trace as an API response.

How can I achieve my requirement? following are my camel routes



public class TripBookingTransactedRoute extends RouteBuilder {

    @Override
    public void configure() throws Exception {
        getContext().addService(new
org.apache.camel.impl.saga.InMemorySagaService());
        //////////////////////////////////// ROLL BACK COORDINATOR
/////////////////////////////////////////////////////
        onException(Exception.class)
                .useOriginalMessage()
                .handled(true)
                .transform(constant("{\"status\" : \"trip booking
failed\"}"))  // this is the custom error response
                .end();
        //////////////////////////////////////////////// Original Business
Flow ////////////////////////////////////////
        // To kick off following route, POST :
http://localhost:8081/booktrip =>
{"name":"Reji","age":34,"origin":"YYZ","destination":"NYC"}
        from("jetty:http://0.0.0.0:8081/booktrip?httpMethodRestrict=POST")
                .log("Processing booking request ${body}")
.transacted() // transation scope begins here
.setProperty("booking_request", simple("${body}"))
.setProperty("trip_booking_id",
simple("${bean:UUIDGenerator.generateUUID()}"))
/////// LOGIC HERE TO BOOK A FLIGHT ////
.setHeader(Exchange.HTTP_METHOD, constant("POST"))
.setHeader(Exchange.HTTP_URI, constant("http://localhost:8000/flights"))
.setHeader(Exchange.CONTENT_TYPE, constant("application/json;
charset=utf-8"))
.to("http:dummyhost") // flight booking is performed here
.setProperty("flight_pnr", jsonpath("$.businessObject.flightPnr"))
.log("flight pnr : ${property.flight_pnr}")
.log("booked flight successfully..")


// following section needs to rollback when a failure occurs
.setBody(simple("INSERT into trip_details " +
                        "(trip_id, flight_pnr) VALUES
('${property.trip_booking_id}','${property.flight_pnr}')"))
.to("jdbc:dataSource?resetAutoCommit=false")

.throwException(new Exception("booking failed")) // simulating a failure

.setBody(simple("{\"trip_id\":\"${property.trip_booking_id}\",\"flight_pnr\":\"${property.flight_pnr}\",\"hotel_booking_id\":\"${property.hotel_booking_id}\",\"taxi_booking_id\":\"${property.taxi_booking_id}\"}"))
                .end();

Re: Rolling back transaction with custom error message using onException

Posted by Reji Mathews <co...@gmail.com>.
Thanks! I found it under section "12.3.6 Returning a custom response when a
transaction fails"

Cheers!

On Tue, Sep 22, 2020 at 12:15 PM Claus Ibsen <cl...@gmail.com> wrote:

> Hi
>
> I think that use case is covered in the CiA2 book in the transaction
> chapter.
>
> On Tue, Sep 22, 2020 at 6:01 PM Reji Mathews <co...@gmail.com>
> wrote:
> >
> > Hello community
> >
> > I have a requirement
> > -  Route needs to be transacted  :  If some failure happens, jdbc
> operation
> > should be rolled-back
> > - I need to send back a custom error message to API caller. (am trying to
> > do do that in onException)
> >
> > But, I see the transaction rollback doesn't work if I use handled=true in
> > the onException block.
> > Alternatively, it works flawlessly if I flip it to false, but I get ugly
> > stack trace as an API response.
> >
> > How can I achieve my requirement? following are my camel routes
> >
> >
> >
> > public class TripBookingTransactedRoute extends RouteBuilder {
> >
> >     @Override
> >     public void configure() throws Exception {
> >         getContext().addService(new
> > org.apache.camel.impl.saga.InMemorySagaService());
> >         //////////////////////////////////// ROLL BACK COORDINATOR
> > /////////////////////////////////////////////////////
> >         onException(Exception.class)
> >                 .useOriginalMessage()
> >                 .handled(true)
> >                 .transform(constant("{\"status\" : \"trip booking
> > failed\"}"))  // this is the custom error response
> >                 .end();
> >         //////////////////////////////////////////////// Original
> Business
> > Flow ////////////////////////////////////////
> >         // To kick off following route, POST :
> > http://localhost:8081/booktrip =>
> > {"name":"Reji","age":34,"origin":"YYZ","destination":"NYC"}
> >         from("jetty:http://0.0.0.0:8081/booktrip?httpMethodRestrict=POST
> ")
> >                 .log("Processing booking request ${body}")
> > .transacted() // transation scope begins here
> > .setProperty("booking_request", simple("${body}"))
> > .setProperty("trip_booking_id",
> > simple("${bean:UUIDGenerator.generateUUID()}"))
> > /////// LOGIC HERE TO BOOK A FLIGHT ////
> > .setHeader(Exchange.HTTP_METHOD, constant("POST"))
> > .setHeader(Exchange.HTTP_URI, constant("http://localhost:8000/flights"))
> > .setHeader(Exchange.CONTENT_TYPE, constant("application/json;
> > charset=utf-8"))
> > .to("http:dummyhost") // flight booking is performed here
> > .setProperty("flight_pnr", jsonpath("$.businessObject.flightPnr"))
> > .log("flight pnr : ${property.flight_pnr}")
> > .log("booked flight successfully..")
> >
> >
> > // following section needs to rollback when a failure occurs
> > .setBody(simple("INSERT into trip_details " +
> >                         "(trip_id, flight_pnr) VALUES
> > ('${property.trip_booking_id}','${property.flight_pnr}')"))
> > .to("jdbc:dataSource?resetAutoCommit=false")
> >
> > .throwException(new Exception("booking failed")) // simulating a failure
> >
> >
> .setBody(simple("{\"trip_id\":\"${property.trip_booking_id}\",\"flight_pnr\":\"${property.flight_pnr}\",\"hotel_booking_id\":\"${property.hotel_booking_id}\",\"taxi_booking_id\":\"${property.taxi_booking_id}\"}"))
> >                 .end();
>
>
>
> --
> Claus Ibsen
> -----------------
> http://davsclaus.com @davsclaus
> Camel in Action 2: https://www.manning.com/ibsen2
>

Re: Rolling back transaction with custom error message using onException

Posted by Claus Ibsen <cl...@gmail.com>.
Hi

I think that use case is covered in the CiA2 book in the transaction chapter.

On Tue, Sep 22, 2020 at 6:01 PM Reji Mathews <co...@gmail.com> wrote:
>
> Hello community
>
> I have a requirement
> -  Route needs to be transacted  :  If some failure happens, jdbc operation
> should be rolled-back
> - I need to send back a custom error message to API caller. (am trying to
> do do that in onException)
>
> But, I see the transaction rollback doesn't work if I use handled=true in
> the onException block.
> Alternatively, it works flawlessly if I flip it to false, but I get ugly
> stack trace as an API response.
>
> How can I achieve my requirement? following are my camel routes
>
>
>
> public class TripBookingTransactedRoute extends RouteBuilder {
>
>     @Override
>     public void configure() throws Exception {
>         getContext().addService(new
> org.apache.camel.impl.saga.InMemorySagaService());
>         //////////////////////////////////// ROLL BACK COORDINATOR
> /////////////////////////////////////////////////////
>         onException(Exception.class)
>                 .useOriginalMessage()
>                 .handled(true)
>                 .transform(constant("{\"status\" : \"trip booking
> failed\"}"))  // this is the custom error response
>                 .end();
>         //////////////////////////////////////////////// Original Business
> Flow ////////////////////////////////////////
>         // To kick off following route, POST :
> http://localhost:8081/booktrip =>
> {"name":"Reji","age":34,"origin":"YYZ","destination":"NYC"}
>         from("jetty:http://0.0.0.0:8081/booktrip?httpMethodRestrict=POST")
>                 .log("Processing booking request ${body}")
> .transacted() // transation scope begins here
> .setProperty("booking_request", simple("${body}"))
> .setProperty("trip_booking_id",
> simple("${bean:UUIDGenerator.generateUUID()}"))
> /////// LOGIC HERE TO BOOK A FLIGHT ////
> .setHeader(Exchange.HTTP_METHOD, constant("POST"))
> .setHeader(Exchange.HTTP_URI, constant("http://localhost:8000/flights"))
> .setHeader(Exchange.CONTENT_TYPE, constant("application/json;
> charset=utf-8"))
> .to("http:dummyhost") // flight booking is performed here
> .setProperty("flight_pnr", jsonpath("$.businessObject.flightPnr"))
> .log("flight pnr : ${property.flight_pnr}")
> .log("booked flight successfully..")
>
>
> // following section needs to rollback when a failure occurs
> .setBody(simple("INSERT into trip_details " +
>                         "(trip_id, flight_pnr) VALUES
> ('${property.trip_booking_id}','${property.flight_pnr}')"))
> .to("jdbc:dataSource?resetAutoCommit=false")
>
> .throwException(new Exception("booking failed")) // simulating a failure
>
> .setBody(simple("{\"trip_id\":\"${property.trip_booking_id}\",\"flight_pnr\":\"${property.flight_pnr}\",\"hotel_booking_id\":\"${property.hotel_booking_id}\",\"taxi_booking_id\":\"${property.taxi_booking_id}\"}"))
>                 .end();



-- 
Claus Ibsen
-----------------
http://davsclaus.com @davsclaus
Camel in Action 2: https://www.manning.com/ibsen2