dynamisches Instanziieren von Beans

Lombardimuc

Mitglied
Hallo Community,

im Rahmen einer JEE Applikation komme ich gerade konzeptionell nicht ganz weiter.
Auch wenn ich bereits jahrelange plain Java-Erfahrung habe, bin ich nur ab und zu und nicht intensiv mit JEE in Berührung gekommen.

Ich möchte im Grundsatz ein einfaches Observer Pattern realisieren. Leider finde ich mit den verfügbaren Mitteln von CDI und EJB nicht zu dem Ziel das ich mir vorstelle.
Evtl. ist mein Denkansatz auch falsch :)

Ich möchte einen externen Service-Provider anbinden, der einen Datendienst anbietet.
Dies tut er über eine Art API Gateway, welches die eigentlich Schnittstellenkommunikation komplett kapselt und transparent für mich macht. Ich habe lediglich ein paar Java Klassen die ich direkt aufrufen kann.

Ich definiere über eine relativ komplexe Konfiguration, wofür ich mich interessiere, danach empfange ich ich (theoretisch unendlich lange) Daten, bis ich die entsprechende Konfiguration wieder deregistriere.
Ich kann beliebig viele Konfigurationen registrieren und empfange dann für jede Konfiguration eigene Daten.
Mit jedem "Datenstream" möchte ich danach verschiedene Dinge tun, aber das ist außerhalb meiner Problemstellung.

Um mein Problem besser zu schildern, habe ich ein schematisches Bild angefügt.
Bildschirmfoto 2017-03-07 um 17.31.38.png

Die folgenden Nummern, entsprechen den Nummerierungen im Bild.

1) In der JEE Applikation biete ich über eine Art Management Frontend die Möglichkeit an, eine Konfiguration zu erstellen und einen Datenservice dafür zu starten.
2) Diese Konfiguration inkl. Status wird dann in einer DB persistiert.
3) Wenn ein Service gestartet wird, wird die Konfiguration aus der DB gelesen
4) Um einen Service zu starten, erstelle ich zunächst einen internen Observer für diese Konfiguration, der die Daten empfangen und weiterverarbeiten soll.
5) Diesen Observer übergebe ich an den service api wrapper. Dieser erstellt einen api handler, der den observer erhält. Der API Handler ist das Interface zum Empfang von Daten, dass die API vorgibt. Dort implementiere ich quasi nach Vorgabe die "onMessage" Methoden.
6) Ab diesem Punkt empfängt der api handler Daten von der API und leitet sie ständig an den Observer weiter.
7) Der Observer soll die Daten nun auf verschiedenste Arten behandeln/ weiterleiten etc.

Mir ist nun nicht so recht klar, wie ich in Punkt 4 die Observer EJBs dynamisch im ServiceHandler erzeugen und halten kann. Mit den verfügbaren Annotationen bin ich nicht wirklich weiter gekommen, da ich für meinen Fall immer an Grenzen gestoßen bin, da die Annotationen im Code zu statisch sind und auch bei google habe ich für meinen Fall nichts entdecken können.
Folgende Laufzeitbedingungen sind wichtig:
-> der Service Handler soll die zentrale Anlaufstelle sein, die weiß, welche Observer aktiv sind, wie der Status ist, etc. pp.
-> ich möchte Dinge wie transaktionales Verhalten, Security, Messaging nicht neu erfinden, sondern gern von den JEE Fähigkeiten profitieren (ich denke hier aktuell an EJBs für die Observer, vll auch CDI Beans?)
-> die Observer müssen "unendlich" lange laufen, da die Objekte bei der service api registriert werden und dann "unendlich" lange Daten empfangen
-> Zur Laufzeit müssen dynamisch weitere Instanzen erstellt oder bestehende entfernt werden (Starten, Stoppen von Services)

Wie kann ich also zur Laufzeit dynamisch meine unendlich lange laufenden Beans (im service handler) erstellen? Ist das überhaupt möglich? Habe ich einen Denkfehler?

Danke im Voraus (insbesondere wer bis hier durchgehalten hat :) ) und Grüße
Christian
 

Lombardimuc

Mitglied
Hallo Andy,
danke für die rasche Antwort.
Der Service Handler ist tatsächlich bereits ein @Singleton. Er soll die Referenzen halten.

Ich hab die Asynchronous Method Invocation mal überflogen.
Meinst Du, das der Observer async Methoden anbieten soll?
Ich bin nicht sicher, ob es passt, da der Observer nicht eine lange Aufgabe ausführt, sondern einfach nur am Leben bleiben soll, um aufgerufen werden zu können. So tickt das integrierte API Gateway einfach.
Ich durchdenke das nochmal.

Mir ist nicht klar, wie ich die Observer Instanzen erstellen soll. Aktuell mache ich das mit "new". So geht das Ganze aber an der Ressourcenverwaltung vom JEE Server vorbei. Das ist nicht Sinn der Sache und man soll es vermeiden oder sehe ich das falsch?
@Stateless macht imho keinen Sinn, da jeder Observer sehr wohl einen langlebigen Zustand hat
@stateful hängt an einer Client Session, das ist auch nicht Sinn der Sache
@Singleton lebt dauerhaft, aber lässt nur eine Instanz zu (hätte ich exakt einen Datenstream, würde ich damit arbeiten)

Beim längeren Überlegen ist mit aufgefallen, das ich eigentlich gern eine Bean hätte, die die Eigenschaften einer Singleton Bean (oder ApplicationScoped in CDI) hat, mit der Ausnahme, dass es sie mehrfach geben kann.
Ich möchte eine Bean, die nicht "unkontrolliert" vom JEE Server zerstört wird, sondern nach einer eigens definierten Bedingung. Ist diese nicht erfüllt, lebt die Bean in der Anwendung.

In welche sinnvolle Art von Bean könnte ich die Observer verpacken? Oder macht das hier keinen Sinn?

Danke und Grüße

Christian
 

AndyJ

Bekanntes Mitglied
Howdy Christian,

Du scheinst ja long-running Services starten und stoppen zu wollen. Dafuer wuerde ich die Asynchronous Method nehmen. Wenn ich es richtig verstanden habe, feuern deine Services Events in unbestimmten Zeitabstaenden. Wenn du JEE-Mittel verwenden willst, wuerde ich diese Events an einen MessageQueue senden (evtl. erzeugst du auch den dynamisch per Service). Der Listener (Observer) waere dann eine MessageDriven Bean, die die Nachrichten bei Eintreffen verarbeitet.
Du musst nicht alle Resourcen vom Container verwalten lassen, selbstverstaendlich kann man Objekte auch mit new erzeugen. Aber man nutzt dann eigentlich nicht die Moeglichkeiten des Containers.
Prinzipiell versuche ich immer stateful Beans zu vermeiden, die machen alles nur kompliziert, besonders wenn mehrere Threads darauf zugreifen sollen.
Mir ist nur nicht klar, was die Events denn schlussendlich bewirken. Wir der Client benachrichtigt oder nur Daten gespeichert oder was?

Cheers,
Andy
 

Lombardimuc

Mitglied
Hallo Andy,

danke für den tollen Input.

Zunächst zu Deiner Frage:
Die Events werden für Analysen benötigt. Alle Events werden gespeichert, Langzeit-analysiert, sowie Echtzeit-analysiert (es wird eine Weiterleitung in ein Hadoop Cluster und eine Streaming Analytics App erfolgen, wo das passiert).
Warum benutze ich überhaupt JEE? Die JEE Applikation ist die "zentrale Steuerungseinheit", die eine Oberfläche zur Kontrolle und Beeinflussung der Gesamtapplikation bietet. Die JEE Toolbox finde ich dafür einfach interessant.
Später wird die externe API auch verwendet werden, um auf Basis der Analyseergebnisse, die aus dem Hadoop Cluster kommen, Befehle zurück zu senden. All das muss über die Management-Oberfläche angesehen, konfiguriert und gesteuert werden können.

Zum Problem zurück:
Zitat: "Wenn ich es richtig verstanden habe, feuern deine Services Events in unbestimmten Zeitabstaenden"
-> Da liegt der kleine, aber feine Unterschied :). Sie empfangen in unregelmäßigen Abständen "Events".
Der von mir geschriebene "Service API Wrapper" ist eine ApplicationScoped CDI Bean. Ein mal gestartet, läuft Sie nun also unendlich lange im Rahmen der Applikation und ich kann über sie immer die API ansteuern.
Wenn ich einen Datenstream subscriben möchte muss ich die Konfiguration und ein Objekt, dass das ApiHandler Interface implementiert, übergeben.
Die ApiHandler Objekte sind nun nicht per se Services, die die ganze Zeit etwas tun, sondern die Service Api ruft die ApiHandler Objekte jedes mal auf Ihren "onMessage" Methoden auf, wenn es etwas Neues gibt.
Das ist der Punkt an dem es wichtig ist, dass die empfangenden Objekte nie sterben und gerne auch Beans sind, um von den Container-Fähigkeiten profitieren zu können. Sie sind quasi passive, wartende Objekte.
Observer und ApiHandler habe ich nur getrennt, um die interne Implementierung("Observer") von der Service Api Implementierung zu entkoppeln. Sie machen eigentlich das Gleiche und die Api Handler sind nun nur zum Durchreichen da.

Bildschirmfoto 2017-03-09 um 11.58.11.png

Deine Idee mit den Message Queues verstehe ich, tatsächlich wollte ich zunächst vermeiden, für die JEE interne Verarbeitung auch noch Message Queues dazwischen schalten zu müssen (wg. Overhead).
Dennoch...damit würde Schritt 7 mit Queues entkoppelt werden. Aktuell ist es ein Observer Interface.
Wenn es keine Alternativen dazu gibt, werde ich das tun.

Habe ich Dich richtig verstanden, dass es keine Alternativen gibt?

Vielen Dank für Deine Zeit, Dein Interesse und Deine Hilfe!
Viele Grüße
Christian
 

AndyJ

Bekanntes Mitglied
Da sieht mir alles viel zu kompliziert aus. Wenn ich das also richtig verstanden habe, lauscht dein Service an einer externen Datenquelle und empfaengt von dort Daten. Dann lass den Service die Daten doch direkt verarbeiten.

Cheers,
Andy
 

Ähnliche Java Themen

Neue Themen


Oben