Enterprise Application Integration

Werbung
Enterprise Application Integration
Message oriented Middleware
Enterprise Application Integration
Björn Eilers
Prozessmanagement
Nachrichtenmanagement
Physisches Netzwerk
Enterprise Application Integration
2
Björn Eilers
Adapter
Adapter
Adapter
Adapter
Adapter
Adapter
Middleware
Metadatenbank für Zusatzdienste
Einordnung in funktionale Bestandteile einer EAI Infrastruktur
Kommunikation zwischen IS in Unternehmen
eng
Remote Procedure Calls
Kopplung
Interface-basierte Middleware
CORBA
EJB
DCOM+
Web Services
Nachrichten
lose
Enterprise Application Integration
3
Björn Eilers
Schnittstellen vs. Nachrichten
Schnittstellen
Für Intraprogramm- bis Intraserver-Kommunikation
Enge Kopplung der Systeme
Ermöglicht Typprüfung während Kompilierung und Laufzeit
I.d.R. schnelle Aufrufe
Anpassung umfangreicher Systeme aufwändig bis wirtschaftlich unmöglich
Schnittstellen alter und neuer Systeme oft inkompatibel
Schnittstelle
int addiere(int x, int y);
Implementierung
int addiere(int x, int y) {
return x+y; }
Enterprise Application Integration
4
Björn Eilers
17
25 Aufrufende Klasse
42 int result = schnittstelle.addiere(17, 25)
Schnittstellen vs. Nachrichten
Nachrichten
Für Intraserver bis Intersystem-Kommunikation
Lose Kopplung der Systeme
bietet Zustellungsgarantie (Nachricht bei Systemausfall später zugestellt)
keine Typprüfung
langsam (Overhead durch Ver- und Entpacken der Nachricht)
Einfache Anpassung auch bei größeren Systemen
Für Kompatibilität mit Altsystemen: alte Nachrichteninhalte beibehalten, neue
Ergänzen)
Sender
An: Empfänger
Dienst: addiere
x: 17
y: 25
Nachrichtenwarteschlange
Enterprise Application Integration
5
Björn Eilers
Empfänger
Kommunikationsmodelle
Synchrone Kommunikation
Sender und Empfänger in Ablauf aneinander gekoppelt
Sender blockiert, bis Empfänger antwortet
Sender
Empfänger
Asynchrone Kommunikation
Sender und Empfänger in Ablauf nicht gekoppelt
Während Empfänger Antwort berechnet, kann Sender weiterarbeiten
Sender
Enterprise Application Integration
6
Björn Eilers
Empfänger
Kommunikationsvarianten
Synchrone Einwegkommunikation
z.B. entfernter Methodenaufruf ohne Rückgabe
1. Sender sendet Anfrage an Empfänger und blockiert
2. Empfänger nimmt Nachricht entgegen, sendet Bestätigung
("Acknowledgement") und verarbeitet dann Nachricht
3. Sender erhält Bestätigung und kann direkt weiterarbeiten
Sender
Empfänger
Ack
Enterprise Application Integration
7
Björn Eilers
Kommunikationsvarianten
Synchrones Polling
1.
2.
3.
4.
5.
Sender fragt periodisch bei Empfänger an, ob Resultate vorliegen
Antwort entweder als Nachricht oder in gemeinsamem Speicher
Sender schickt Anfrage an Empfänger und arbeitet weiter
Empfänger startet Verarbeitung
Sender fragt regelmäßig nach Ergebnissen
Falls keine vorhanden, wird weitergearbeitet und später erneut nachgefragt
Ergebnis liegt vor: Ergebnis wird geliefert, Empfänger kann weiterarbeiten
Sender arbeitet mit Ergebnis weiter
Sender
Enterprise Application Integration
8
Björn Eilers
Empfänger
Kommunikationsvarianten
Asynchrones Broadcasting
Sender sendet Nachricht an mehrere Empfänger gleichzeitig, arbeitet weiter
Jeder Empfänger erhält Nachricht und kann reagieren
Empfänger 1
Sender
Empfänger 2
Empfänger 3
Enterprise Application Integration
9
Björn Eilers
Kommunikationsvarianten
Asynchrones Publish/Subscribe
Ähnlich zum Broadcast, aber Empfänger müssen bei "Zusteller" Themen
abonnieren
Nur registrierte Empfänger erhalten Nachricht
Empfänger 1
Sender
A
Zusteller
A Abonniere Thema A
Empfänger 2
Empfänger 3
Enterprise Application Integration
10
Björn Eilers
Message oriented Middleware
Middleware, die über die Weitergabe von Nachrichten kommuniziert
Dienste zentriert auf Nachrichten
Anlegen
Weitergabe
Auslieferung
Speicherung (Persistierung)
Transaktionssicherheit
MoM als Vermittler zwischen Sender und Empfänger
Message-Server / Message-Broker
Enterprise Application Integration
11
Björn Eilers
Message oriented Middleware
Vorteile
Asynchrone Kommunikation sehr allgemein, ermöglicht Emulation anderer
Modelle
Aufgrund allgemeinen Charakters hohes Maß an Interoperabilität zwischen
heterogenen Systemen
Für lose gekoppelte Systeme sehr gut geeignet; XML-Dokumente in
Nachrichten einbetten
Nachteile
Fehlende Typsicherheit
Overhead durch Ver-/Entpacken und Übermittlung der Nachrichten
Enterprise Application Integration
12
Björn Eilers
Message oriented Middleware
Entweder Standalone…
IBM MQSeries
Sun ONE Middleware
MS Message Queue Server
ObjectWeb JORAM
BEA MessageQ
EldoS MsgConnect
CSS NetZyme Enterprise
TIBCO ActiveEnterprise
…oder als Bestandteil anderer Middleware-Systeme
z. B. Java 2 Enterprise Edition (JMS und Message-Driven Beans)
Enterprise Application Integration
13
Björn Eilers
Java Message Service
Spezifikation, definiert Schnittstellen und Protokolle für
Kommunikation durch Nachrichtenaustausch
Kommunikationsvarianten
asynchrones Senden (normale asynchrone Kommunikation)
asynchrones Publish/Subscribe
asynchrones Request/Reply
synchrones Request/Reply (normale blockierende, synchrone
Kommunikation)
synchrone Einwegkommunikation
Ermöglicht bei entsprechender Programmierung auch weitere
Kommunikationsvarianten
Enterprise Application Integration
14
Björn Eilers
Java Message Service
Zwei Arten von Nachrichtenkanälen
Queues: Einfache Warteschlangen für n:1-Kommunikation
Topics: Publish/Subscribe-Kanäle für n:m-Kommunikation
Queues und Topics sind zueinander inkompatibel
Sender 1
Queue
Empfänger
Sender 2
Sender 1
Empfänger 1
Topic
Sender 2
Empfänger 2
Grundlegende Technologie für Message-Driven Beans
Enterprise Application Integration
15
Björn Eilers
Java Message Service
Nachrichten
Bestehen aus Header, Properties und Body
Header enthält Meta-Angaben (Empfänger, Lebensdauer, ...)
Properties enthalten zusätzliche, frei definierbare Angaben
(primitive Datentypen und Strings)
Body enthält den eigentlichen Inhalt
Header
Properties
Nachrichtenarten (implementieren javax.jms.Message)
TextMessage: Zum Übermitteln eines Strings
MapMessage: Für Namen-Werte-Paare primitiver Datentypen
ObjectMessage: Zum Übermitteln eines serialisierbaren Objektes
BytesMessage: Liefert einen beschreibbaren Byte-Stream
StreamMessage: Für einen Stream primitiver Datentypen
SpyMessage (JBoss-spezifisch): Nachricht ohne Inhalt ("Ping")
Enterprise Application Integration
16
Björn Eilers
Body
Java Message Service
Für Versand und Empfang existiert Interface-Hierarchie
javax.jms.ConnectionFactory: Baut Verbindungen zwischen JMS Client und
JMS Provider auf; wird von J2EE bereitgestellt
javax.jms.Connection: Kapselt Verbindungen
javax.jms.Session: Sitzung, innerhalb der Nachrichten gesendet und
empfangen werden können
javax.jms.Destination: Ziel einer Nachricht (z.B. Queue oder Topic), muss im
J2EE-Kontext bereitliegen
javax.jms.MessageProducer/MessageConsumer: Sender/Empfänger einer
Nachricht, kommunizieren mit Destination
Jeweils mit Subklassen für Queues und Topics (QueueConnectionFactory,
TopicConnectionFactory, etc.)
Destinations können auch temporär sein
Enterprise Application Integration
17
Björn Eilers
Java Message Service
ConnectionFactory
erzeugt
Connection
erzeugt
MessageProducer
erzeugt
Session
erzeugt
MessageConsumer
erzeugt
sendet an
Nachricht
Destination
Enterprise Application Integration
18
Björn Eilers
erhält von
Java Message Service
Grundsätzlicher Ablauf der Kommunikation
1.
2.
3.
4.
5.
6.
7.
8.
ConnectionFactory im JNDI-Kontext auffinden und referenzieren
Mithilfe der Factory Connection erzeugen
Destination auffinden
Session erzeugen
Verbindung starten
MessageProducer und/oder MessageConsumer erzeugen
Nachrichten austauschen
Verbindung schließen
Enterprise Application Integration
19
Björn Eilers
Java Message Service
Implementierung: Grundlegendes Gerüst für Clients
try {
Properties p = System.getProperties();
p.setProperty("java.naming.factory.initial",
"org.jnp.interfaces.NamingContextFactory");
p.setProperty("java.naming.factory.url.pkgs",
"org.jboss.naming:org.jnp.interfaces");
p.setProperty("java.naming.provider.url", "localhost");
InitialContext ctx = new InitialContext();
// ...
} catch (JMSException e) {
e.printStackTrace();
} catch (NamingException e) {
e.printStackTrace();
}
Enterprise Application Integration
20
Björn Eilers
Java Message Service
Nachricht an Queue senden
QueueConnectionFactory qcf = (QueueConnectionFactory) ctx
.lookup("ConnectionFactory");
QueueConnection qc = qcf.createQueueConnection();
QueueSession qs = qc.createQueueSession(false,
für TransaktionsSession.AUTO_ACKNOWLEDGE);
unterstützung: true
qc.start();
Queue queue = (Queue) ctx.lookup("queue/BeispielQueue");
QueueSender sender = qs.createSender(queue);
MapMessage exampleMessage = qs.createMapMessage();
// ...
sender.send(exampleMessage);
qc.close();
Enterprise Application Integration
21
Björn Eilers
Java Message Service
Nachricht an Topic senden
TopicConnectionFactory tcf = (TopicConnectionFactory) ctx
.lookup("ConnectionFactory");
TopicConnection tc = tcf.createTopicConnection();
TopicSession ts = tc.createTopicSession(false,
Session.AUTO_ACKNOWLEDGE);
tc.start();
Topic topic = (Topic) ctx.lookup("topic/BeispielTopic");
TopicPublisher publisher = ts.createPublisher(topic);
MapMessage message = ts.createMapMessage();
// ...
publisher.publish(message);
tc.close();
Enterprise Application Integration
22
Björn Eilers
Java Message Service
Asynchrones Empfangen einer Nachricht:
Implementieren des Interfaces javax.jms.MessageListener und der Methode
public void onMessage
Registrieren des MessageListeners an einem Receiver bzw. Subscriber
public class ExampleListener
implements javax.jms.MessageListener {
public void onMessage(Message message) {
// Verarbeitung: Gebe Empfangshinweis aus
System.out.println("Nachricht mit ID "+
message.getJMSMessageID()+" empfangen.");
}
}
Enterprise Application Integration
23
Björn Eilers
Java Message Service
Queue
// Properties setzen
...
// Verbindung zum Queue erzeugen
InitialContext ctx = new InitialContext();
QueueConnectionFactory qcf = (QueueConnectionFactory) ctx
.lookup("ConnectionFactory");
QueueConnection qc = qcf.createQueueConnection();
QueueSession qs = qc
.createQueueSession(false, Session.AUTO_ACKNOWLEDGE);
Queue queue = (Queue) ctx.lookup(QUEUE_NAME);
QueueReceiver receiver = qs.createReceiver(queue);
receiver.setMessageListener(new ExampleListener());
qc.start();
// warten
...
// wenn nicht mehr empfangen werden soll: Verbindung schließen
qc.close();
Enterprise Application Integration
24
Björn Eilers
Java Message Service
Topic
// Properties setzen
...
// Verbindung zum Topic erzeugen
InitialContext ctx = new InitialContext();
TopicConnectionFactory tcf = (TopicConnectionFactory) ctx
.lookup("ConnectionFactory");
TopicConnection tc = tcf.createTopicConnection();
TopicSession ts = tc
.createTopicSession(false, Session.AUTO_ACKNOWLEDGE);
Topic topic = (Topic) ctx.lookup(TOPIC_NAME);
TopicSubscriber subscriber = ts.createSubscriber(topic);
subscriber.setMessageListener(new ExampleListener());
tc.start();
// warten
...
// wenn nicht mehr empfangen werden soll: Verbindung schließen
tc.close();
Enterprise Application Integration
25
Björn Eilers
Java Message Service
Synchrones Empfangen einer Nachricht
Zwei Möglichkeiten:
QueueRequestor bzw. TopicRequestor-Objekt (Vorteil: einfach implementiert,
Nachteil: kein Timeout)
QueueReceiver bzw. TopicSubscriber (Vorteil: flexibler, Nachteil: höherer
Implementierungsaufwand)
tc.start();
Topic topic = (Topic) ctx.lookup(TOPIC_NAME);
TopicRequestor trq = new TopicRequestor(ts, topic);
ObjectMessage exampleMessage = ts.createObjectMessage();
// ... Nachricht mit Inhalten füllen ...
Message answer = trq.request(exampleMessage);
// Antwort auswerten
tc.close();
Enterprise Application Integration
26
Björn Eilers
Java Message Service
qc.start();
Queue queue = (Queue) ctx.lookup(QUEUE_NAME);
QueueRequestor qrq = new QueueRequestor(qs, queue);
ObjectMessage exampleMessage =
ts.createObjectMessage();
// Nachricht mit Inhalten füllen
...
Message answer = trq.request(exampleMessage);
// Antwort auswerten
qc.close();
Enterprise Application Integration
27
Björn Eilers
Java Message Service
Dienstenutzer:
tc.start();
Topic topic = (Topic) ctx.lookup("topic/TestTopic");
TopicPublisher publisher = ts.createPublisher(topic);
TemporaryTopic replyTopic = ts.createTemporaryTopic();
TopicSubscriber subscriber = ts.createSubscriber(replyTopic);
MapMessage exampleMessage = ts.createMapMessage();
// ... Nachricht füllen ...
// Rückgabekanal setzen
exampleMessage.setJMSReplyTo(replyTopic);
// Nachricht senden
publisher.publish(exampleMessage);
// Max. 15 sek. auf Antwort warten
Message answer = subscriber.receive(15000);
// ... Antwort verarbeiten ...
tc.close();
Enterprise Application Integration
28
Björn Eilers
Java Message Service
Diensteanbieter (hier MessageListener/MDB, auch receive/reply):
public void onMessage(Message message) {
try {
// Antwort auslesen
// TopicConnection tc und Session ts erstellen
tc.start();
Topic replyTopic = (Topic)message.getJMSReplyTo();
TopicPublisher publisher =
ts.createPublisher(replyTopic);
Message replyMessage = ts.createMessage();
// ... Nachricht mit Inhalt füllen ...
publisher.publish(replyMessage);
tc.close();
} catch (Exception e) {} }
Enterprise Application Integration
29
Björn Eilers
Java Message Service
Message Selektoren:
Nur für Topics
Nachrichten können anhand ihrer Properties selektiert werden
Beispiel: Wetterinformationen nur für eine bestimmte Stadt aus Topic
selektieren
Angabe eines Selektors bei Erzeugung eines TopicSubscribers:
topicSession.createSubscriber(topic, messageSelector, true);
Selektorstring: Bezeichner, Werte, Vergleichs- und logische Operatoren
"Stadt = 'Münster' AND Temperatur BETWEEN 15 AND 25 AND
Sicht NOT IN ('neblig', 'dunkel') AND Absender LIKE 'B%n
E%rs'"
Setzen der Properties in der Nachricht:
message.setStringProperty("Stadt", "Münster");
message.setIntProperty("Temperatur", 18);
Enterprise Application Integration
30
Björn Eilers
Java Message Service
Mehrere Nachrichten synchron empfangen
Voraussetzung: Maximale Anzahl an Empfängern bekannt
Ausgehende Nachricht senden
In Schleife mit queueReceiver.receive() bzw. topicSubscriber.subscribe()
Nachrichten empfangen, dabei
Timeout mit jeder Nachricht reduzieren
Schleife verlassen, wenn Timeout oder maximale Anzahl an Nachrichten erhalten
Enterprise Application Integration
31
Björn Eilers
Message-Driven Beans
Message-Driven Beans
Stellen JMS-Nachrichtenempfänger dar
Können Queues oder Topics abfragen
kapseln das Empfangen von Nachricht, nur Verarbeitung muss implementiert
werden
Interface MessageDrivenBean und MessageListener müssen implementiert
werden
Verarbeitung dann über onMessage()-Methode
Wichtig: ohne zusätzlichen Implementierungsaufwand kein Senden von
Nachrichten
Enterprise Application Integration
32
Björn Eilers
Message-Driven Beans
Definition der Eigenschaften einer Message-Driven Bean über
XDoclet
@ejb.bean
destination-type = "javax.jms.(Topic|Queue)": Setzt die Art der Destination
destination-jndi-name = "destinationJNDIName": Setzt den JNDI-Namen der
Destination
acknowledge-mode = "Auto-acknowledge": Nachrichten-Empfang automatisch
bestätigen
message-selector = "Selektorstring": Definieren eines Message Selektors für
Topics
@jboss.destination-jndi-name
name = "destinationJNDIName": JNDI-Namen der Destination im JBoss
bekanntgeben
Enterprise Application Integration
33
Björn Eilers
Message-Driven Beans
Beispiel:
/** @ejb.bean name="ExampleMDB"
*
display-name="Example Message Driven Bean"
*
destination-type="javax.jms.Topic"
*
destination-jndi-name = "topic/ExampleTopic"
*
acknowledge-mode="Auto-acknowledge"
*
message-selector="ExampleString = 'example'"
* @jboss.destination-jndi-name
*
name = "topic/ExampleTopic" */
public class TransferBean implements MessageDrivenBean,
MessageListener {
}
Enterprise Application Integration
34
Björn Eilers
Message-Driven Beans
public class TransferBean implements MessageDrivenBean,
MessageListener {
private MessageDrivenContext ctx;
public TransferBean() {
}
public void setMessageDrivenContext(MessageDrivenContext ctx)
throws EJBException {
this.ctx = ctx;
}
public void ejbCreate() {
}
public void ejbRemove() throws EJBException {
}
public void onMessage(Message message) {
// ... Nachrichten verarbeiten
}
}
Enterprise Application Integration
35
Björn Eilers
Beispiel
<<EntityBean>>
AccountBean
<<SessionBean>>
AccountManagem entBean
-unbenannt1 : AccountBean
+makeTransfer( sourceAccNo : String, destAccNo : String, amount : float )
-accountNumber : String
-balance : float
-name : String
-forename : String
<<MessageDrivenBean>>
TransferBean
TransferInform ation
#makeTransfer( transferInformation : TransferInformation )
+onMessage( message : Message )
-amount : float
-receiverName : String
-receiverAccount : String
-receiverInstituteID : String
-receiverInstituteName : String
-referenceText : String
-senderName : String
-senderAccount : String
<<Sw ing Component>>
TransferPanel
+getTransferInformation() : TransferInformation
1
-transferPanel
<<GUI>>
ClerkClient
<<GUI>>
AbstractClient
#makeTransfer( transferInformation : TransferInformation )
Enterprise Application Integration
36
Björn Eilers
<<Sw ing Component>>
TransferReplyDialog
1
-replyDialog
<<GUI>>
Custom erClient
Literatur
Keller, W.: Enterprise Application Integration, dpunkt-Verlag 2002.
Guter Überblick über sowohl technische als auch wirtschaftliche Aspekte der EAI
Roman, E., et. al.: Mastering Enterprise JavaBeans, Third Edition
http://www.theserverside.com/books/wiley/masteringEJB/index.tss
Java Message Service Specification 1.1
http://java.sun.com/products/jms/docs.html
Kurzdokumentationen zu J2EE und EAI
http://www.torsten-horn.de/techdocs/#JEE (einführende Beispiel in J2EE)
Enterprise Application Integration
37
Björn Eilers
Herunterladen