Ceci est une ancienne révision du document !
1
Some time ago, I began a new job in a big corporation. My first task was to reimplement / reimport their C# tcp client to Java. Existing convertors sucked, so I did it manually. After a week or so, the new Java tcp client and server simulator were written and waiting for further use. Having met the client’s requirements, we found that Java’s implementation lacked important features such as failover and auto-reconnection. Adding such functionality required us to add some untested code, which might be unable to handle the business logic. One of our guys said, Aha, what if…? We can replace the Java implementation with another one, for instance - Spring Integration. The rest of us smiled, thinking what the heck? Anyway, he is a good chap, trying to use the best technologies available. We got the green light to do research and learn something exciting. To simplify our requirements, I am going to discuss a simulator (aka server) and a client. Before delving deeper, let me explain what Spring Integration is intended for. As their site suggests: “it provides an extension of the Spring programming model to support the well-known Enterprise Integration Patterns”. Rephrasing, to design good enterprise applications one could use messaging (more precisely asynchronous messaging) that enables diverse applications to be integrated with each other – without nightmares or pain. A wise guy named Martin Fowler has written a famous book: “Enterprise Integration Patterns”. Folks from Spring probably one day decided to materialize a theory into practice. Very pragmatic approach, isn’t it? Later, you will see how wonderful it is for regular tasks. The main concept of SI is: Endpoint, Channel and Message.
Il y a quelque temps, j'ai commencé un nouveau boulot dans une grande société. Ma première tâche était de réimplémenter/porter leur client tcp de C# en Java. Les convertisseurs existants fonctionnant mal, je l'ai fait manuellement. Après environ une semaine, le nouveau client tcp et le nouveau simulateur de serveur étaient écrits en Java et prêts à être utilisés. Après avoir répondu aux exigences du client, nous avons constaté que l'implémentation en Java manquait de caractéristiques importantes telles que la gestion de panne et l'auto- reconnexion. Ajouter ces fonctionnalités nécessitait que l'on ajoute du code non testé, qui risquait de ne pas gérer la logique métier. Un de nos collègues a dit : Ah ah, et si… ? Nous pourrions remplacer l'implémentation en Java avec une autre, par exemple - Spring Integration. Nous avons rigolé en pensant : mais qu'est-ce qu'il raconte ? Quoi qu'il en soit, c'est un bon garçon, qui essaie d'utiliser les meilleures technologies disponibles. Nous avons eu le feu vert pour faire des recherches et apprendre quelque chose d'excitant. Pour simplifier nos besoins, je vais parler d'un simulateur (c'est-à-dire un serveur) et d'un client. Avant de plonger plus profondément, laissez-moi vous expliquer pour quoi Spring Integration est conçu. Comme leur site l'indique : « cela fournit une extension du modèle de programmation Spring qui supporte les modèles bien connus d'intégration de l'entreprise (Enterprise Integration Patterns) ». Pour reformuler, cela permet de concevoir de bonnes applications d'entreprise en utilisant des messages (plus précisément une messagerie asynchrone) qui permet à diverses applications de s'intégrées les unes aux autres - sans peine ni douleur. Un gars sage du nom de Martin Fowler a écrit un livre célèbre : « Enterprise Integration Patterns ». Les gens de Spring ont sans doute décidé un jour de matérialiser une théorie en pratique. Approche très pragmatique, n'est-ce pas ? Plus tard, vous verrez combien c'est merveilleux pour des tâches récurrentes. Les concept principaux du SI sont : Endpoint, Channel et Message (destination, canal et message).
2
Endpoint is a component which actually does something with a message. A message is a container consisting of header and payload. The header contains data that’s relevant to the messaging system where the payload contains the actual data. Channel connects two or more endpoints, it’s similar to Unix pipes. Two endpoints can exchange messages if they’re connected through a channel. Pretty easy, isn’t it? The following diagram shows this.
The next step to our crash course will be defining the requirements. I would say, we need a server (tcp) and tcp client. We will write a simple application that will exchange a couple of messages with each other.
An important thing with SI is a configuration file which contains all the necessary components we’re going to use. Here is the “server” part of the configuration. Simplifying a model and SI lifecycle, Spring creates objects that are defined in the configuration xml. More generally, such a concept is called declarative programming. You define a business object in the xml, and a framework generates appropriate classes for you, and injects and initializes dependencies. The mantra says: you should be concentrated only on the business and not on the implementation.
3
Let’s define a part of the configuration xml (next page, top left), the server part: http://pastebin.com/6AHQWPse
Important things are: A factory (tcp-connection-factory) - creates tcp server using a byte array length serializer. A Serializer is needed for “packaging” our message in some way or to encode it in order to transmit it over a wire. On the other hand, a Deserializer is needed for “unpackaging” our message or to decode it. Spring Integration has two factories – one for the client and another for the server. The difference is the Type [server or client]. A Port listens for incoming messages. An IP address is not mentioned here because a server runs as a localhost.
We also defined two channels: serverIn (for incoming messages) and serverOut (for outgoing messages). So that our server can send and receive messages, we define inbound and outbound adapters which are associated with the factory and channels. In our case they define the endpoints. So, when a message arrives, something should take care of it. This responsibility requires a service, i.e. file sender service. If it accepts a message, then it will send a file in the background, line by line, to the client. Basically, when a server starts, it listens for incoming messages. However, only specific messages will be accepted, and, when accepted, than the server sends a file line-by-line. If an error occurs, it’s routed to the error channel. It’s done using interceptor.
4
I would say a couple of words about the SI lifecycle. Spring framework has two “main” packages: org.springframework.beans and org.springframework.context that build up the core utility of the dependency injection of the component. The org.springframework.beans.factory.BeanFactory interface provides basic lifecycle methods (start and stop) for bean initialization/destruction. The org.springframework.context.ApplicationContext offers AOP integration, message resource handling, and even more.
Our server is ready… I mean, completely ready. To run the example, follow the below steps:
cd /tcpserver
mvn clean install
mvn dependency:copy-dependencies
mvn exec:java -Dexec.mainClass=“org.example.tcpserver.ServerRunner” -Dexec.args=“–file=”/file_to_be_sent.txt“”
5
Our main class expresses as shown in the box below.
The source code can be found here http://pastebin.com/6PMpWTfX
Also we define a file-send service. This is shown on the next page, top left. The code is at: http://pastebin.com/icHRdQS3
Next, denote a business runner. That code is shown on the next page, bottom left. The code can be seen at: http://pastebin.com/LZRdZ3Tg
Finally, for the server, write an error handler which logs the errors which is shown above. Code is at: http://pastebin.com/2EQvbVR8
At this point, we’re done with our server.
6
Now, let’s define a tcp client which connects to the server, sends an accept message, and gets a file sent from the server.
Our configuration file looks as follows: http://pastebin.com/egquzq5q
Here’s how to run a client: Open a new terminal:
cd /tcpclient
mvn clean install
mvn dependency:copy-dependencies
mvn exec:java -Dexec.mainClass=“org.example.tcpclient.ClientTcp”
Almost the same logic applies here. Have a look. A main class has the lines shown in the code on the next page, top left.
7
In addition, define a client service:
void send(String txt);
Next, a message handler:
public void handle(byte[] s) {
String ss = new String(s); LOG.info("r:" + ss);
}
And the last one is an interceptor, which will inform your application about: i. Message sent; ii. A connection closed; iii. A new connection added.
That’s it!
To play with the code, see here: http://www.4shared.com/zip/eF4q7l0k/spring_integration_example.html.
8
Prerequisites: • Java 1.6 or above; • Maven 3 or above; • Desire to learn something new and thrilling;
Pros: • A lot of features • Tested • Good and friendly community • If you have questions, the people reply really quickly • There are tons of examples • API is easy and comprehensive
Cons: • Takes time to learn and understand how to work with it. • If you get problems, sometime it is difficult to debug it.