Configure Route Recipients at run time

classic Classic list List threaded Threaded
4 messages Options
Reply | Threaded
Open this post in threaded view
|

Configure Route Recipients at run time

jpcook01
Hello,

I'm using camel 1.6.3 and would like to configure a route at runtime from a unit test something like looking the endpoint up in memory by name, and replacing the file:// by a mock:// ? I know I can override the createroutebuilder in the unit test but I don't want to do this and also I can't upgrade at the moment.

The route I'm actually trying to manipulate looks like this:
               Namespaces ns = new Namespaces("cps", "http://www.bbc.co.uk/schemas/CPS/CPS-API/");
                               
                from("seda:footballMatchCreateCPSAsset")
                        .setHeader(FileComponent.HEADER_FILE_NAME,
                                        header(FOOTBALL_MATCH_ROOT_PATH_HEADER)
                                        .append("/create_cps_match_asset.xml"))
                        .process(XsltBuilder.xslt(
                                        new File("xslt/football/match/xml/football_match_create_cps_asset.xml.xslt")))
                        .setBody(constant("payload=")
                        .append(body()))
                        .setHeader(HttpMethods.HTTP_METHOD, constant(HttpMethods.POST))
                        .setHeader("Content-Type", constant("application/x-www-form-urlencoded"))
                        .to(ConfigurationManager.getConfiguration().getString(
                                        "output.cpsapiWebService.createAssetUrl"))
                        .to("seda:footballMatchSaveCPSAssetId");

I want to remove the last two to statements and add a to(mock:test)

I've been playing around with getting the route definitions from the context but can't quite get it to work.

                List<RouteType> routeTypes = testSupport.getContext().getRouteDefinitions();
                RouteType rt = routeTypes.get(31); //this is the route for seda:footballMatchCreateCPSAsset
               
                List<ProcessorType<?>> outputs = rt.getOutputs();
               
                List<ProcessorType<?>> interceptorOutputs = outputs.get(0).getOutputs();
                interceptorOutputs.remove(5);
                interceptorOutputs.remove(5);
                //interceptor outputs actually look correct after the next line.
                outputs.get(0).addOutput(new ToType(new MockEndpoint("mock:test")));

                //but rt is still showing the to:file in the pipeline so I did this, I'm not sure what the difference between this and the above is but this adds another interceptor to rt but doesn't appear to have any affect
                outputs.add(new ToType(new MockEndpoint("mock:test")));
               
                rt.setOutputs(outputs);
                routeTypes.add(31, rt);

                MockEndpoint mock = testSupport.getContext().getEndpoint("mock:test", MockEndpoint.class);
                mock.expectedMessageCount(1);        

                testSupport.sendBody("seda:footballMatchCreateCPSAsset", FileUtils.readFileToString(
                new File("testxml/football/matches/footballmatch_3003485.xml")));
                mock.assertIsSatisfied();

I think I'm going along the right lines although it looks like I need to get at the recipient list for the route and modify that rather than the outputs?

Any help greatly appreciated.
Jon
Reply | Threaded
Open this post in threaded view
|

AW: Configure Route Recipients at run time

Schneider Christian
Hi Jon,

I would advise against changing the routes at runtime. How about introducing a direct endpoint and doing the last part of the route in a second method that can be changed for the test.

Like this:

from("seda:footballMatchCreateCPSAsset")
...
.to("direct:footballMatchEp")

Then in a separate method:

from("direct: footballMatchEp")
.to(ConfigurationManager.getConfiguration().getString(
                                        "output.cpsapiWebService.createAssetUrl"))
.to("seda:footballMatchSaveCPSAssetId");


Then in your test you can extend the routebuilder and replace the method with:

from("direct: footballMatchEp")
.to("mock:test")


An even better way than a separate method is using properties:
Add a property footballMatchEp to your route builder class and set this differently in the unit test (direct:footballMatchEpTest) and in the real app (direct:footballMatchEp). One for production use and one for tests.

Best regards

Christian


Christian Schneider
Informationsverarbeitung
Business Solutions
Handel und Dispatching

Tel : +49-(0)721-63-15482

EnBW Systeme Infrastruktur Support GmbH
Sitz der Gesellschaft: Karlsruhe
Handelsregister: Amtsgericht Mannheim ­ HRB 108550
Vorsitzender des Aufsichtsrats: Dr. Bernhard Beck
Geschäftsführer: Jochen Adenau, Hans-Günther Meier


-----Ursprüngliche Nachricht-----
Von: jpcook01 [mailto:[hidden email]]
Gesendet: Dienstag, 2. November 2010 11:04
An: [hidden email]
Betreff: Configure Route Recipients at run time


Hello,

I'm using camel 1.6.3 and would like to configure a route at runtime from a
unit test something like looking the endpoint up in memory by name, and
replacing the file:// by a mock:// ? I know I can override the
createroutebuilder in the unit test but I don't want to do this and also I
can't upgrade at the moment.

The route I'm actually trying to manipulate looks like this:
               Namespaces ns = new Namespaces("cps",
"http://www.bbc.co.uk/schemas/CPS/CPS-API/");
                               
                from("seda:footballMatchCreateCPSAsset")
                        .setHeader(FileComponent.HEADER_FILE_NAME,
                                        header(FOOTBALL_MATCH_ROOT_PATH_HEADER)
                                        .append("/create_cps_match_asset.xml"))
                        .process(XsltBuilder.xslt(
                                        new
File("xslt/football/match/xml/football_match_create_cps_asset.xml.xslt")))
                        .setBody(constant("payload=")
                        .append(body()))
                        .setHeader(HttpMethods.HTTP_METHOD, constant(HttpMethods.POST))
                        .setHeader("Content-Type", constant("application/x-www-form-urlencoded"))
                        .to(ConfigurationManager.getConfiguration().getString(
                                        "output.cpsapiWebService.createAssetUrl"))
                        .to("seda:footballMatchSaveCPSAssetId");

I want to remove the last two to statements and add a to(mock:test)

I've been playing around with getting the route definitions from the context
but can't quite get it to work.

                List<RouteType> routeTypes =
testSupport.getContext().getRouteDefinitions();
                RouteType rt = routeTypes.get(31); //this is the route for
seda:footballMatchCreateCPSAsset
               
                List<ProcessorType<?>> outputs = rt.getOutputs();
               
                List<ProcessorType<?>> interceptorOutputs = outputs.get(0).getOutputs();
                interceptorOutputs.remove(5);
                interceptorOutputs.remove(5);
                //interceptor outputs actually look correct after the next line.
                outputs.get(0).addOutput(new ToType(new
MockEndpoint("mock:test")));

                //but rt is still showing the to:file in the pipeline so I did this, I'm
not sure what the difference between this and the above is but this adds
another interceptor to rt but doesn't appear to have any affect
                outputs.add(new ToType(new MockEndpoint("mock:test")));
               
                rt.setOutputs(outputs);
                routeTypes.add(31, rt);

                MockEndpoint mock =
testSupport.getContext().getEndpoint("mock:test", MockEndpoint.class);
                mock.expectedMessageCount(1);        

                testSupport.sendBody("seda:footballMatchCreateCPSAsset",
FileUtils.readFileToString(
                new
File("testxml/football/matches/footballmatch_3003485.xml")));
                mock.assertIsSatisfied();

I think I'm going along the right lines although it looks like I need to get
at the recipient list for the route and modify that rather than the outputs?

Any help greatly appreciated.
Jon

--
View this message in context: http://camel.465427.n5.nabble.com/Configure-Route-Recipients-at-run-time-tp3246440p3246440.html
Sent from the Camel - Users mailing list archive at Nabble.com.
Reply | Threaded
Open this post in threaded view
|

Re: AW: Configure Route Recipients at run time

jpcook01
Thanks, I like the propery idea

When you say extend the routebuilder you mean the unit test will actually extend the routebuilder?

eg) FootballMatchRouteBuilderTest extends FootballMatchRouteBuilder

Thanks
Reply | Threaded
Open this post in threaded view
|

AW: AW: Configure Route Recipients at run time

Schneider Christian
yes.. you would extend the routbuilder class. So you could change the behaviour of the method that creates the route that starts with the direct endpoint.

The better way would probably be to have two direct endpoints and switch between them via a property.

Best regards

Christian
 




Christian Schneider
Informationsverarbeitung
Business Solutions
Handel und Dispatching

Tel : +49-(0)721-63-15482

EnBW Systeme Infrastruktur Support GmbH
Sitz der Gesellschaft: Karlsruhe
Handelsregister: Amtsgericht Mannheim ­ HRB 108550
Vorsitzender des Aufsichtsrats: Dr. Bernhard Beck
Geschäftsführer: Jochen Adenau, Hans-Günther Meier


-----Ursprüngliche Nachricht-----
Von: jpcook01 [mailto:[hidden email]]
Gesendet: Dienstag, 2. November 2010 13:11
An: [hidden email]
Betreff: Re: AW: Configure Route Recipients at run time


Thanks, I like the propery idea

When you say extend the routebuilder you mean the unit test will actually
extend the routebuilder?

eg) FootballMatchRouteBuilderTest extends FootballMatchRouteBuilder

Thanks
--
View this message in context: http://camel.465427.n5.nabble.com/Configure-Route-Recipients-at-run-time-tp3246440p3246619.html
Sent from the Camel - Users mailing list archive at Nabble.com.