How to create MasterEndpoint programmatically - apache-camel

I need to create an MasterEndpoint from a given (as Endpoint instance in Java) FileEndpoint.
Normally i create an class extending the desired endpoint and call all needed setter (e.g. to set context) from with in constructor or in an init method.
Sometimes i create a method that uses getContext().getEndpoint("name", ClazzOfEndpoint.class) within the route builder.
But how to do this with MasterEndpoint (preferable without using string literals/constants)?
The problem with extending MasterEndpoint is the unusual constructor it uses. The problem with using getEndpoint is: how to connect the returned master endpoint to the FileEndpoint?

You cannot really do this as that master component is not designed for being build programmatically. You get the endpoint via configuring it using a string uri. This is also the recommended way in Camel to setup and define endpoints. Don't program them manually.

I found a way that suits my needs:
First create the master endpoint together with it's child:
masterEndpoint = context.getEndpoint("master:fileLock:file:" + rootFolder, MasterEndpoint.class);
To programmatically configure the child endpoint (in my case FileEndpoint) obtain it from master and configure it:
fileEndpoint = (FileEndpoint) masterEndpoint.getEndpoint();
fileEndpoint.setAutoCreate(false);
fileEndpoint.setAntInclude(ANT_INCLUDE);
fileEndpoint.setMove(doneFolder);
fileEndpoint.setMoveFailed(errorFolder);
It would be extreme cumbersome (and error prone) to configure it with strings.

Related

toD() - Dynamic URI formation in camel 2.23 scheduled via Quartz

I'm newbie to Apache camel and wanted to Implement the toD() which is to dynamically frame the URI and add request params values from Beans..
Code snippet below -
from("quartz2://timer?cron=0+0/1+++*+?")
.noAutoStartup().routeId(ROUTE_ID).log("Route Started")
.toD(http://localhost:3420/contextpath?from=${bean:bean.from} "+ "&size=${bean:bean.size}")
.process(processor)
Seems like, on every hit via Quartz the same URL is being triggered and hence I see duplicate values saved to DB.
Please suggest why Dynamic uri is not working as expected.
Am calling the processor, computing and setting the Bean values which i get from Response of Endpoint. But when the next time Quartz hits the url, the bean values are not updated and takes the default value
. Bean definition is usual getter setter, and registration is I have used Simple registry
SimpleRegistry simpleRegistry = new SimpleRegistry ();
// create CamelContext
context = new DefaultCamelContext (simpleRegistry);
simpleRegistry.put("bean", bean);
Thanks in Advance
In order to use dynamic URI on a camel-route you must include your variable inside a Simple expression.
Since Camel 2.16.0 release endpoint implementation toD() supports the Simple expression language so you can define a dynamic-URI as message-endpoint:
from("quartz2://timer?cron=0+0/1+++*+?")
.noAutoStartup()
.routeId(ROUTE_ID)
.log("Route Started")
.toD( "http://localhost:3420/contextpath?from=${bean:bean.from}&size=${bean:bean.size}" );
So the expressions ${bean:bean.from} and ${bean:bean.size} should get directly interpolated by using Bean language inside your URI-string. This bean-component bean: tells Camel to get the bean registered with your specified name bean and call the specified methods from and size.
Apache Camel: Rest DSL, section Using Dynamic to() has also a note:
Note: we need to use .endRest() to tell Camel where the route ends, so we can go back to the Rest DSL and continue defining REST services.
Otherwise you could implement that dynamic endpoint using simple inside your regular to(). See Apache Camel: How to use a dynamic URI in to().

Camel Apns component readtimeout and connectiontimeout have no access to set

I am using camel apns component in order to push send notifications but I did not find any timeout setter for both reading and connection.
As I have seen:
There is this class , ApnsConnection, and it includes that parameters. But ApnsServiceFactory uses ApnsBuilder class as default. In its getService() method, setting of these two timeouts is not implemented.
So the question is, am I missing something or are the timeout settings really missing?
Thanks
The timeout settings are missing but that doesn't mean you can't do this, looking in the source code for ApnsServiceFactory you can see a protected method called configureServiceBuilder(ApnsServiceBuilder serviceBuilder) which is used in the testing of the class (which gives a good example usage) and means you can add extra configuration to the builder.
Subclass the ApnsServiceFactory and override configureServiceBuilder. In the body of that override add your withConnectionTimeout() and withReadTimeout() to the passed in serviceBuilder and return it.

Custom IdempotentConsumer/Processor in Apache Camel

I want to perform custom logic in an IdempotentConsumer. I've extended the class and implemented the logic. How can I add this to my route?
Do I have to make my own Definition class? Do I add it as a Processor? How do I get the parameters passed to the constructor?
Well, custom consumer/producer could be little overkill. I think for some kind of custom logic is enough to do it trough processor or custom bean.
1.Bean
Look at bean binding you can use simple language to pass arguments to your method. It will looks like this:
.bean(OrderService.class, "doSomething(${body}, true)")
.to("bean:orderService?method=doSomething(null, true)")
2.Processor
You have to realize your classes should be stateless because of concurrent matter of camel framework. Your constructor should be empty and your variables final otherwise whole bunch of magic could happen. Everything you want to pass to your logic component/processor should be passed via Exchange object. You can store your variables in getin() or getOut() messages as headers or body or Exchange properties and pass it to next endpoint. The exchange will change dynamically as it flows trough you camel routes. It should be your one and only one mutable object.

Modify Endpoint Address of a WCF Client Proxy

When I'm making web service calls from Silverlight using a service reference, is there any way to have the (generated) SoapClient objects modify the address that they call the service on?
Specifically, I'd like to tack on a QueryString value onto each call that the service makes. So if I have
DataService.SilverlightServiceSoapClient C = new DataService.SilverlightServiceSoapClient();
Is there any way to do something like:
C.Address += "?Foo=Bar";
Which would allow me to, from my WebMethod, say:
HttpContext.Current.Request.QueryString["foo"];
Obviously I can modify my WebMethods to take this value in as a parameter, but I'd like to avoid doing that if possible.
Since you are already using service references, you can simply use the overload of the proxy class constructor that accepts an EndpointAddress as a parameter. Alternatively, you can create multiple endpoint configuration and have the code simply use the chosen configuration - which may include URL changes.
See Understanding Generated Client Code on MSDN.
It looks like the best way to do this is to just use one of the overloaded constructors and supply the uri yourself
C = new DataService.SilverlightServiceSoapClient(new BasicHttpBinding(), new System.ServiceModel.EndpointAddress("http://blah/blah/blah/SilverlightService.asmx?Foo=Bar"));

Problem in sharing Cache between main domain and subdomain

As I have posted before also,I am developing a site in two languages done in CakePHP.
Now the latest problem I am facing in my application is that the application is not sharing the Cache values between the Main Domain and the Subdomain.Please help me out of this mess...!!!
Thanks in advance.
There are 3 problems connected to this.
Data you're caching manually by using Cache::read() and Cache::write()
Just use a prefix for each subdomain when using the methods.
Element caching
you can solve this "almost" elegantly by following these steps:
Create my_view.php (or whatever) in app/views
Content:
class MyView extends View {
}
Search for view.php in the Cake Core and copy the element() method to your newly created class. Add your subdomain prefix in the part where the caching happens
In your AppController::beforeFilter() write
$this->view = 'MyView';
Now you have control over the CakePHP view layer. You have just overridden the element method.
Alternatively to this approach (if your codebase isn't already using elements extensively) you could just create a helper with a method, that takes the same arguments as the View::element() method, add the subdomain key to the cache options and call the orginal element() method.
Full Page Caching
This is a tricky one. The full page caching happens in the dispatch() method before you have any possibility to modify the behavior. The second problem is, that CakePHP uses the relative URL of the page to cache it. The relative URLs are most likely identical under your different subdomains.
I think the simplest approach here is to create a Dispatcher class, which extends the original dispatcher. Override the cached() method and implement your desired behavior, like the prefixes. Then in your app/webroot/index.php you need to change this line
$Dispatcher = new Dispatcher();
...to your new class name.

Resources