ΕΝΟΤΗΤΑ 4 – INJECTING THE CAMELCONTEXT INTO A JAVA EE APPLICATION


Όπως έχουμε αναφέρει τόσες πολλές φορές, το CamelContext είναι αυτό που απλά συνθέτει όλα τα κομμάτια μαζί για να δημιουργήσει ένα ολοκληρωμένο route.  
 Το πιο κάτω σχεδιάγραμμα που προέρχεται από το site του Apache Camel (http://camel.apache.org/architecture.html) σας παρουσιάζει με γραφικό τρόπο το πως το CamelContext παίζει το ρόλο του οργανωτή στο Apache Camel.

 



Παρατηρούμε από το πιο πάνω σχεδιάγραμμα ότι υπάρχουν κάποιες καινούργιες ορολογίες όπως component και endpoint. Πριν εξηγήσουμε αυτούς τους όρους ας δείξουμε άλλη μια φορά τον κώδικα από το προηγούμενη ενότητα και κυρίως το κώδικα του route.

 


Χωρίς να ξέρουμε επίσημα τους όρους, τους έχουμε ήδη χρησιμοποιήσει. Components είναι τα διάφορα στοιχεία που είναι έτοιμα και άμεσα διαθέσιμα από το Apache Camel όπως ftp, http, file, jms, κτλ. Στον κώδικα μας χρησιμοποιήσαμε το file και το jms. Επειδή το file componentl, στο παράδειγμα μας, ήταν στην αρχή του route και μπορούσε να δεχτεί δεδομένα τότε αυτό ονομάζεται endpoint. Όπως επίσης endpoint θεωρείται και το σημείο στο οποίο καταλήγουν τα δεδομένα όπως το jms. Με άλλα λόγια έχουμε περίπου 80 components έτοιμα προς χρήση (και ετοιμάζονται και άλλα από την ομάδα του Apache Camel) και με αυτά μπορούμε να επικοινωνήσουμε με εξωτερικά συστήματα ανάλογα με την εκάστοτε υποδομή του πελάτη. Σε όσα από αυτά τα components είναι η αρχή ή το τέλος του route και μπορούν να δεχτούν ή να στείλουν μηνύματα τότε έχουν και την επιπλέον ονομασία του endpoint. Αν και ακόμα δεν το έχουμε δει αυτό, αλλά σαν processor ονομάζουμε το custom κώδικα που γράφουμε εμείς με τον οποίο μπορούμε να αλλάξουμε, να τροποποιήσουμε ή να ελέγξουμε την πληροφορία που περνάει από component σε component μέσα στο route. Φανταστείτε πχ. την περίπτωση όπου ένα εισερχόμενο μήνυμα σε XML μορφή πρέπει να μετατραπεί σε JSON ή μέσα από αυτό να διαβάσουμε συγκεκριμένες παραμέτρους πριν το μήνυμα συνεχίσει το route.

Τώρα γιατί ασχολούμαστε σε αυτή την ενότητα με το CamelContext αφού ήδη γνωρίζουμε το τι κάνει? Για παράδειγμα στο κώδικα μας βλέπουμε ότι δηλώσαμε με το getContext( ) το component jms στο CamelContext για να μπορεί να το διαχειριστεί μέσα στο κώδικα του route. Και αν θέλουμε να ανεβάσουμε λιγάκι την κλίμακα δυσκολίας, θα μπορούσαμε να ρωτήσουμε γιατί εγκαταστήσαμε το wildfly-camel πακέτο αφού μπορούμε απλά να φορτώσουμε τις βιβλιοθήκες του Apache Camel στο project μας και να δημιουργήσουμε routes.

Η απάντηση είναι απλή: επειδή μπορούμε να καλέσουμε το CamelContext αντικείμενο με injection μέσα στην Java EE εφαρμογή μας και να αλληλεπιδράσουμε με αυτό κάτι που δεν μπορούσαμε να κάνουμε μέχρι τώρα. Δηλαδή, θα ρωτήσει κάποιος, αντί το input να προέρχεται από ένα file endpoint θα μπορούσε να ερχόταν από την ίδια την εφαρμογή? Ακριβώς! Και ας δούμε πως…

Ας δημιουργήσουμε ένα καινούργιο project ή μπορείτε να συνεχίσετε να γράφετε κώδικα στο project που ήδη έχετε ξεκινήσει και γράφουμε το εξής κώδικα στην MyRouteBuilder κλάση:



 



Βασικά το μόνο που έχουμε αλλάξει είναι το αρχικό endpoint που από file το έχουμε αλλάξει σε direct:start. Το direct component προσφέρει επικοινωνία σαν endpoint μόνο μέσα από το ίδιο το Camel και όχι σε εξωτερικά συστήματα. Επειδή όμως το CamelContext μπορούμε να το κάνουμε inject μέσα στην Java EE εφαρμογή, άρα και ο κώδικας της εφαρμογής μας μπορεί να στείλει δεδομένα στο direct component. Συνήθως χρησιμοποιούμε το direct component όταν θέλουμε να ενώσουμε δύο routes. 

Για να δείξουμε πως μπορούμε να καλέσουμε το CamelContext ας δημιουργήσουμε ένα απλό Servlet και ας γράψουμε τον ακόλουθο κώδικα μέσα στην processRequest μέθοδο. Αν χρησιμοποιείτε άλλο IDE και όχι NetBeans τότε απλά γράψτε τον κώδικα μέσα στην doGet μέθοδο.

 
 


Πριν από την μέθοδο κάνουμε inject το camelcx αντικείμενο. Μέσα από αυτό μπορούμε να δημιουργήσουμε ένα ProducerTemplate αντικείμενο το οποίο έχει την δυνατότητα να στέλνει ένα οποιοδήποτε payload σε οποιοδήποτε destination του ορίσουμε. Στο παράδειγμά μας του ορίζουμε ότι θα στείλει στο direct:start το μήνυμα “This message is from the Servlet”. Εννοείται ότι μπορείτε να στείλετε μήνυμα σε οποιαδήποτε μορφή.

Οπότε τι έχουμε καταφέρει μέχρι τώρα? Έχουμε κάνει inject το CamelContext μέσα σε ένα Servlet. Αυτό μας δίνει την δυνατότητα να δημιουργήσουμε ένα αντικείμενο είδος ProducerTemplate που μα δίνει την ικανότητα να στείλουμε payloads σε οποιοδήποτε endpoint. Ορίζουμε λοιπόν να στείλουμε στο direct:start component ένα συγκεκριμένο string μήνυμα. Στο route που έχουμε ορίσει, ξεκινάμε το route με το ίδιο component. Αφού το μετατρέψουμε σε String το στέλνουμε σε ένα queue που ονομάζεται TestQueue. Αυτό το queue το έχουμε δημιουργήσει στην προηγούμενη ενότητα και είναι επάνω στον Wildfly application server. Το τελικό αποτέλεσμα είναι ότι το Servlet λογικά θα μας δείξει ένα απλό μήνυμα στο browser, στην κονσόλα θα δούμε ότι το μήνυμα έχει φτάσει στο queue, αλλά και μέσα στο queue θα μπορούμε να δούμε το αποθηκευμένο μήνυμα.

Message from the Servlet

 
Message from the Wildfly

 


The message in our queue

 


The Camel diagram of our route




Πείτε τώρα ότι θέλαμε το route μας να χρησιμοποιήσει πολλαπλά queues αλλά δεν θα επιθυμούσαμε να είναι όλα επάνω στον Wildfly application server γιατί πολύ απλά δεν θα θέλαμε να αποθηκεύσουμε τα μηνύματα αλλά να χρησιμοποιήσουμε το queue σαν ενδιάμεσο βήμα στο route. Αντί λοιπόν να ορίζουμε επάνω στον Application server queues μπορούμε να δημιουργήσουμε queues την ώρα που τρέχει το route και αυτά είναι εσωτερικά στο Apache Camel. Το component που χρησιμοποιούμε σε αυτή την περίπτωση είναι το vm και είναι πολύ συνηθισμένη η χρήση του κυρίως όταν θέλουμε να δοκιμάσουμε έναν καινούργιο κώδικα σε development επίπεδο. Στην παραγωγή, θα ήταν καλύτερα να χρησιμοποιήσουμε ένα πραγματικό queue επάνω σε ένα broker.

Οπότε, για να δοκιμάσουμε την λογική μας, μπορούμε απλά να αλλάξουμε τον κώδικα μας όπως δείχνει η πιο κάτω εικόνα:

 



Μιχάλης Κασάπογλου
Michail.Kassapoglou@gmail.com













Archive

Contact Form

Send