I have developed Flex - Java - Spring Web Application that I have deployed into an Amazon EC2 image - all is looking great.
However, I need to auto scale and share User requests between multiple instances of the application that sit on different machines, i.e not within the same Tomcat Container. Amazon manages the load balancing and the application uses AMQ topics to communicate critical application level changes between each of the instances.
One of these notifications might be a property. I have several property files that I inject using the #Value annotation into the relevant Spring beans. These property files reside ina properties folder the class path root (classpath:properties/)
When operating on a single node, when I update a property, I update the in memory value using a setter and also write the change back to the relevant property file using FileInputStream and FileOutputStream. This is easy enough.
However, the obvious problem is now what happens when I autoscale and a new instance is started in a different container? This application will read the deployed (old) version of the property file and ultimately behave differently than the other parallel nodes.
I really would like to maintain file based configuration over a Database if I can - I know that the DB solution will be the most prevalent response here, but any suggestions would be appreciated.
Thanks
As far as you are already using JMS topics I'd suggest you to use durable subscription.
If a client needs to receive all the messages published on a topic, including the ones published while the subscriber is inactive, it uses a durable TopicSubscriber. The JMS provider retains a record of this durable subscription and insures that all messages from the topic's publishers are retained until they are acknowledged by this durable subscriber or they have expired.
Take a look on JMS API: http://docs.oracle.com/javaee/6/api/javax/jms/Session.html#createDurableSubscriber(javax.jms.Topic, java.lang.String)
Related
I am currently testing out JMS queue (first time using JMS) and message driven beans.
I have created a queue to provide other applications with state updates for one of our projects.
Logic is written in native JMS, deployed on a JBOSS7 using the ActiveMQ implementation.
It depends on a selector to deliver the messages to the right client, and while I can just place good faith in my colleagues, preferably I would like to enforce the use of the selector so the clients don't consume messages not meant for them.
So basically I would prefer that no messages are delivered to a client which has not specified a selector.
When I deploy a consumer without any selector it just consumes all messages available on the queue.
Otherwise everything works as expected.
I have looked and haven't been able to find anything I am looking for, maybe it's possible by configuring ActiveMQ itself but I am not really at home in that ecosystem.
So the problem is resolved by using a system I wasn't that aware about and I thought I'd share it here if someone need it:
The JMS clients are on different physical machines so originally the plan was to do manual JNDI remote lookup to access the queue but this caused some problems. Mainly having to write retry logic when the Queue is unavailable.
I threw that plan out the window to opt for a Bridge instead, following the guide found here: http://www.mastertheboss.com/howto/jboss-jms6/configuring-jms-bridge-with-wildfly-10
This has multiple advantages (both the producer system or the client can go down without causing too many problems) but most notably this solves my problem: I can define a selector on the bridge per Client. So the responsibility of choosing who receives which messages is back in my court.
I will have a crack at implementing this.
I would like to broadcast a message across microservices, whenever any database is updated.
Example:
Stock value keeps changing, how do i notify all to use the latest value everytime the stock value is updated.
Can anyone suggest any tools or plugins for the same which could be embedded with spring boot.
An example code would be very helpful
If you need something more complex, then you can find tons of examples with AMQP, Spring JMS, Redis pub-sub in this book.
One easy solution for basic state changes, would be instead spring-cloud-bus.
Spring Cloud Bus links nodes of a distributed system with a
lightweight message broker. This can then be used to broadcast state
changes (e.g. configuration changes) or other management instructions.
The only implementation currently is with an AMQP broker as the
transport, but the same basic feature set (and some more depending on
the transport) is on the roadmap for other transports.
A common use case is the change in the config server that needs to be updated in all the microservices. While normally we would change the value in the config server and then hit the refresh endpoint for each service, the config cloud bus updates them all making the process easier.
Currently I am developing module to display list of online user in my application. I am using comet streaming technology. When users log in I put data in map and then sending data in message queue. Now message queue is stored in servlet context.
Now problem I am facing is it is working in local environment but it is not working in production environment because in production environment i have set up tomcat cluster. so data set in servlet context for tomcat 1 is not accessible in tomcat 2.
I have already develop module but not getting any way to solve above issue. I google and found that tomcat doesn't support context replication.
I have one doubt that how many JVM instance will be created in tomcat cluster web application. e.g I have two tomcat cluster.
I would not use servlet context to store data for a cluster. The common pattern is to use a database for data that must be shared across different servers.
For your use case, it is no need persisting the values between different runs, so the database is not necessarily a nice solution, even if it is easy to setup. IMHO what you need it just a shared data cache or better a memory data grid. hazelcast should be easy to use for your requirements. If I correctly understand them, what you need is a distributed map, with a concatenation of node_id, session_id as key (or maybe simply session_id), and a user object as value.
In tomcat7 this requires writing a custom valve to force replication, the same is true in tomcat 6. Refer to Is there a useDirtyFlag option for Tomcat 6 cluster configuration? to see how to do this.
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.
I have a web service, that takes an input xml message, transforms it, and then forwards it to another web service.
The application is deployed to two web logic app servers for performance, and resilience reasons.
I would like a single website monitoring page that allows two things
ability to stop/ start forwarding of messages
ability to monitor throughput of number of messages in the last hour etc. Number of different senders into the webservice etc.
I was wondering what the best way to implement this was.
My current idea is to have an in memory database (eg Debry or HSQL) replicating data to share the information between the two (or more) instances of my application that are running in different instances of the app server. I imagine I would have to setup some sort of master/ slave configuration.
I would love a link to an article that discusses how to solve this problem.
(Note, this is a simple spring application using spring MVC)
thanks,
David.
This sounds like a good match for Java Management Extensions (JMX)
JMX allows you to expose certain operations (eg: start/stop forwarding messages)
JMX allows you to monitor certain performance indicators (eg: moving average of messages processed)
Spring has good support for exposing beans as JMX MBeans. See here for more information.
Then you could use an open-source web-based JMX console, such as jManage
Hope this helps.
Sounds like you are looking for a Message Queue, some MDBs and a configurable design would let you do all these. Spring has support for JMS Queues if I'm not wrong
I think you are looking for a message queue. If you need additional monitoring, using a web service as the end point may not suffice - with regards to stop/start or forwarding of messages; monitoring http requests to web service is more cumbersome than tracking messages to a queue (even though you can do it).
If you are exposing this service to third party, then the web service will sit on top of the message queue and delegate to to it.
In my experience, RabbitMQ is a fine messaging queue service with a relatively simple learning curve.