ΕΝΟΤΗΤΑ 4 – INJECTING THE CAMELCONTEXT INTO A JAVA EE APPLICATION
Όπως έχουμε αναφέρει
τόσες πολλές φορές, το CamelContext
είναι αυτό που
απλά συνθέτει όλα τα κομμάτια μαζί για
να δημιουργήσει ένα ολοκληρωμένο route.
Παρατηρούμε από το πιο
πάνω σχεδιάγραμμα ότι υπάρχουν κάποιες
καινούργιες ορολογίες όπως 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