I am experimenting with Camel and finding it a convenient tool for endpoint integration. I've set up the following experimental application:
The first endpoint is a simple http-get request (using curl on the command line). This interfaces with a central switch using Jetty (this is the Camel-based app). This does some elementary tinkering and passes the request to another endpoint (a Thrift server) which handles the request. Its reponse is then routed back to the command-line client. The set up is therefore a kind of tier-3 over-engineered Hello-world architecture.
My routes typically takes this form:
from("jetty:http://localhost:8080/hello").process(new DummyProcessor()).process(new HelloProcessor());
My question is as follows:
Given that the HelloProcessor sends a Thrift message to another endpoint to process, shouldn't this rather be a Component? Is it good (acceptable) practise to use a Processor for such a task? Furthermore, what are the advantages for writing a component if it is indeed acceptable.
There are not really any benefits in writing a component if you are going to use it in one or a few routes.
If you intend to use this processor in multiple routes in the future, and you need a way to configure it by some parameters - then you typically write your own component. It also perhaps makes the route more readable. A component is also an easy artifact to share between different Camel applications and projects.
from("file:///var/files/inbox").to("http://www.example.com/");
vs
from("file:///var/files/inbox").process(sendHttpToExampleDotComProcessor); // or whatever
If it's a one time use - don't overcomplicate.
Related
Is there a way to trace transactions end to end over distributed applications system using Spring AOP or AspectJ, without changing the existing codes? The web service interactions between applications may be RMI, SOAP or REST? I am looking for a general approach and just want to know if it possible using Spring AOP and AspectJ.
Yes, it is possible with AspectJ, but there is no easy "cooking recipe" or "template for dummies". You need a custom solution. In order to concretely answer your question I would have to see your code. Another guy from India lately asked me the same, maybe he works on the same project as you.
The general approach is to transfer state between client and server by injecting a unique parameter (something like a transaction ID) into the request and using it on the server. Both client and server should be aspect-enabled. This should be possible via RMI, SOAP and REST, provided you find a place where to inject an additional parameter. In RMI and SOAP this could be an existing general-purpose key-value dictionary for optional parameters, in REST it could be a header field or a request parameter.
There is a lot of information for using Camel with JMS, but I can’t find much on using Camel to request data from a web service. I am wondering if this is even possible to do this directly, or do I need to use some kind of JMS/queue?
Ideally, I want my service (using java DSL) to send out a request to another web service, retrieve the data, and then store this in a file locally. Is it possible to do this in Camel using a simple custom RouteBuilder and a camelContext? I’ve tried setting up my routes using
`from(“http:..”).to(“file:...");`
but this doesn’t seem to work, as it doesn’t seem to get the data from the web service. From what I've read, I was under the impression that the endpoint http: will build the request automatically and route this to a file.
I am now wondering what I could try next, and if this is even possible.
It is definitely possible. The best example to start with is the CXF-Proxy Example. This shows how to invoke a remote web-service from Camel. Feel free to ask specific questions if you run into issues and we can help.
Also you could use Spring Web Services Component
http://camel.apache.org/spring-web-services.html
In this case, your route would look like:
from("<some event to trigger the route>")
.to("spring-ws:<endpoint of the WS you want to use>")
.to("file:<write the WS result>")
If you don't mind trying things out at the SOAP level you could try out the approaches found here http://camel.apache.org/soap.html link. Its worth a look even if you end up using something a little more high level.
I currently work on a trading application that does not use camel.
It essentially takes in trades, does some processing and sends the details to an external system.
We now have a need to integrate with 3 new systems uusing FTP for 2 systems and JMS for 1 system.
I would like to use Camel in my application for these integrations. I have read a good chunk of camel in action but I was unclear on how we could kick off our camel routes
Essentially, we dont want to modify too drastically any part of the existing application as its working well in production.
In the existing application, we generate a Trade Value Object and its from this object that that I want to kick off our camel integration.
I dont have a database table or jms queue where I can kick off the route from.
I had a quick look at the Chapter on Bean routing and remoting in the Camel in Action book but I wanted to get peoples advise first before proceeding with any steps.
What would be the best approach for this integration?
Thanks
Damien
You can use Camel's POJO Producing feature that allows you to send a message to a camel endpoint from the java bean. If you have no need in JMS or DB you can use "direct:" or "seda:" or "vm:" endpoint as <from> part of your route.
Pojo producing as Konstantin V. Salikhov stated. However, you need to be sure you have a spring application and are scanning your beans with spring or wire them.
"If a bean is defined in Spring XML or scanned using the Spring component scanning mechanism and a is used or a CamelBeanPostProcessor then we process a number of Camel annotations to do various things such as injecting resources or producing, consuming or routing messages."
If this approach will add too much changes in your application, you could use a ProducerTemplate and just invoke a direct endpoint. (Or SEDA for that matter).
The choice of protocol here might be important. The direct protocol is a safe choice, since the overhead is simply a method call. Also, exceptions will propagate well through direct endpoints, as will transactions. As SEDA endpoints is asynchronous (like JMS) but does not feature persistence, there is a slight chance of loosing in flight data in case of a crash. This might or might not be an issue. However, with high load, the SEDA protocol stages better and give your application better resistance for load peaks.
I need to develop an IMAP poller which pings an email server every few seconds and fetches every new email which arrives.
I've done it once for another application, but there I used an inbound mail channel from Spring Integration.
I just started "playing" with Play, and am not sure what the best way to achieve this is. I know that JavaMail already offers the possibility to fetch mails, but I am not sure how to actually package this. Should this be a separate module, a separate plugin, a service, or sth?
Should the polling functionality be implemented as a job?
NOTE: It is a web application BTW, although the description above may suggest it is not.
There are a few options to solve this:
1) Use java in a Job to poll the IMAP server at regular intervals
documentation on creating a Job is available and is pretty straight forward, just setup the job to run every minute or 5 minutes and then add the code to actually check for new emails.
http://www.playframework.org/documentation/1.2.4/jobs
If you're looking for how to check for new emails on IMAP then have a look through stack exchange there. For example, to poll gmail check out this question: Getting mail from GMail into Java application using IMAP
2) Use camel module to poll IMAP server with a custom route/processor
This is a heavyweight solution and only recommended if you want to make use of other features of Apache Camel.
The module is available here: http://www.playframework.org/modules/camel
Using camel to poll for IMAP messages is fairly easy once you get your head around how to use camel, the specific info for the IMAP route is here: http://camel.apache.org/mail.html
In my opinion you shouldn't use Play at all for this — if I understand your requirements correctly. Play is a web framework intended to handle HTTP requests. Your requirements say nothing about HTTP at all, so a large part of Play! would be useless.
You could use Play's server runtime and Job (and cron) architecture to run this, but you would be misusing the facilities of the framework for something for which they were never intended. You may also be inheriting requirements from Play that you wouldn't ever actually need for an application/service like the one you want to build (for example the Python runtime).
I think you should not use Play for this, but rather create this as a simple, straight-forward Java application using Spring. With Spring's scheduling capabilities you can just as easily implement what you want.
Naturally, when you intend to build a web front-end on top of this in the future, that would make it a completely different story.
Background
I'm writing a medical record app for a friend who is a Doctor. I was told to write a listener in the app that awaits HL7 messages. That way a hospital can send out HL7 messages and my listener will catch them. So I came to the HAPI site and viewed this example. What I understand from it is that it's creating a server to listen for a message.
I'm developing this in Eclipse using JSF 2.0 on Tomcat 7.0. Where does one normally put this kind of listener in a project with JSF? I've tried searching online for this answer and found nothing!
My question
I know this code goes inside a class. When the class gets called the socket will be "turned on" and it's going to wait for a response. So I want to call this class as soon as the project is deployed. How is that done? How do I call that class only once (when the app is starting) in order to turn on the listener?
Any and all help is greatly appreciated! And if I'm not being clear on something let me know!
You don't normally get port listeners running inside an application hosted in Tomcat. You're usually best to keep the two things separated. In the main, web servers aren't meant to run separate threads of execution outside of their control.
You could consider using something like Spring Integration, JBossESB or Apache Camel to receive the messages and process them into a database, file folder (or whatever) that your Tomcat hosted web application then allowed you to manipulate. The ESB container could be hosted in the same JVM process as Tomcat but I wouldn't take that approach myself - I'd have a separate one doing the message processing and another running the webapp.
If you really wanted a "single application" you could consider creating a Java application that kicked off a listener as per the example you have, then started up an embedded version of Tomcat.
If you really really wanted to run it inside Tomcat, as part of web application itself, you could create a class which did the listening and get it loaded into the Application context of the web application. You can do this by adding an instance of it into the appl context within an autoloaded servlet - use <load-on-startup>1</load-on-startup> within the servlet definition. You'd code the servlet to check if there was already an instance in context before adding a new one (on the off-chance it was ever manually invoked), or go down the Spring container route to manage this object as a singleton.
* EDIT: 20120114T004300Z *
Apache Camel is an example of a routing engine that might be used by an Enterprise Service Bus (ESB) such as Apache ServiceMix which allows multiple applications to interoperate by exchanging messages. You'd only use a fraction of the functionality availability for this app by the sounds of it. For what you're doing you might just be able to use Camel capability embedded in Spring, for example.
In essence, the ESB runs "adapters" (or endpoints) - one types of which would by the socket "listener" you talk about here, or might be watching a folder for files to arrive, or polling a database table for rows to appear, or waiting on a JMS queue, etc. The transport (the means by which the "message" (in your case the HL7 file) arrives becomes abstracted away from the functionality of the application itself. The adapter puts the message onto a channel which can be configure to transform the message en-route. Camel actually ships with a HL7 component which can understand the HL7 file format and unmarshal it into a HL7 model. (It also gives you the listener/adapter you need). You'd then set up routing in the ESB to pass that model into a "consumer" Java class that does whatever you need to do with it.
If you're dealing with "standard" transports, protocols and message types most of the file receipt, parsing, and routing is just handled by declarative configuration of the ESB rather than coding.
Your Tomcat webapp can run completely autonomously to this message handling. As mentioned, there are various deployment options as to how exactly you'd do this - including loading Camel inside a Spring container hosted in Tomcat by your webapp if you want to.
Apologies if this is a bit woffley. Take some time to read around the subject on the web, given that HL7 is a standard you'll probably find a lot of code/components already out there that might save you a lot of time in re-implementing the basic file handling so you can concentrate on the value-add webapp for your friend.
A "Listener" is just a class which listens on an open port. In Java, this is mostly done through the Socket API, although you may find a library that better suits your purpose.
The Java Tutorial has some examples here:
http://docs.oracle.com/javase/tutorial/networking/sockets/index.html
In this case, you'd be writing a server (the listening half of a client-server arrangement), whereas the Hospital system sending the message would play the role of client.
Once you're listening on the port, then HL7 messages arrive as plain text onto that socket's inputstream. You can either hand-parse the message (viable if you're only interested in one or two details from a message) or if you're planning on handling dozens of types of messages you can look into one of the HL7 parsing libraries out there.
Keep in mind though, that different implementors of HL7 messages can sometimes send data in subtly different arrangements. (Many users treat HL7 as a 'recommendation' rather than a 'standard', unfortunately!) If you're planning on supporting lots of different feeds from lots of different providers, you'd be much better off using a middleware layer like MirthConnect to handle the parsing and translation of messages into something your application is designed to understand.
Over a year old so you probably figured it all out, but an Enterprise Service Bus (ESB) is a type of middleware (when you think of software, there is back-end i.e. Database/Analytics/Admin Tools and front-end i.e. App/WebApp/GUI displayed to and interacted with end-user), middleware sits in between and helps perform integration or separation/coordination of tasks. Apache ServiceMix (an ESB which contains Apache Camel routing engine) is probably what you want and can be used to implement a number of different Enterprise Integration Patterns such as "Message Routing" (the one you want).
Apache Camel has a built-in HL7 v2 Message parser (uses HAPI) which is the Tab-Separated variant of HL7: http://camel.apache.org/hl7.html
For HL7 v3 messages which are in XML format you can use the toolkits available here under v3 utilities:
http://www.hl7.org/participate/toolsandresources.cfm?ref=nav
There are both server (message listening and reading) and client (message creation and sending) examples.
"Listener" is usually an event listener in Java.
In the example you posted a link to, you have a server class, which handles the business of opening a network socket and waiting for messages to arrive.
The Application objects are the event listeners. These are added to an internal collection of the server class (in this case, with additional parameters that tell the server which listeners to route which classes of HL7 message to).
Each Application class must implement a particular interface - this constitutes the event listener. The SimpleServer class will call the methods of this interface ; processMessage() ; in order to perform actions based on message content, you write a class that implements this interface, and pass instances of it to the server class. In the processMessage() method, you perform all the required actions.
Since you can register multiple listeners, you can implement a number of actions, e.g. you could have two listeners for ADT A01 messages (admit patient) ; one that booked them in, and one that assigned them a bed.
I would suggest looking at Mirth Connect http://www.mirthcorp.com/community/mirth-connect as your HL7 message integration engine. Internally it makes use of HAPI.