Vor ein paar Jahren wurde ich von einem unserer Kunden gebeten, ihm dabei zu helfen, seine Integrationsschicht besser zu nutzen. Seitdem haben mein Team und ich an einem Framework gearbeitet, das dies unterstützt. Dies ist der vierte in einer Reihe von Blogs über die Entwicklung unseres Frameworks und über die Funktionen, die es bietet. Der beim letzten Mal angekündigte Blog über Bausteine ist momentan verschoben. Bisher habe ich die Ziele und Herausforderungen im Zusammenhang mit den Entwicklungsaktivitäten erörtert, aber jetzt möchte ich mich mehr auf das Framework selbst konzentrieren und darauf, was es denjenigen bringt, die es nutzen. Sobald sich eine neue Partei (sei es ein Service-Konsument oder ein Service-Anbieter) mit unserem Framework verbindet, kann sie direkt von der Fülle an Funktionen profitieren, die wir out-of-the-box liefern. Diese 'generischen Funktionen' sind genau das, was man von einem (logischen) ESB erwarten würde, und basieren teilweise auf dem Expanded Enterprise Service Bus Pattern.
Da unser Projekt von Scrum gesteuert wurde, wurden Funktionen nur dann entwickelt, wenn sie benötigt wurden. Manchmal entdeckten wir während der Design- und Build-Phase einen besseren Weg, Dinge zu tun, und manchmal wurde das Problem, das eine Funktion lösen sollte, auf eine ganz andere Weise gelöst, die außerhalb unseres Aufgabenbereichs lag. Letztendlich haben wir es aber geschafft, etwa 20 Funktionen zu implementieren, die sich grob in fünf Typen unterteilen lassen: Routing, Robustheit, Sicherheit, Transformation und Datenspeicherung.
Routing
Eines unserer Hauptziele ist es, Nachrichten von A nach B zu übermitteln, ohne dass A wissen muss, wo sich B gerade aufhält. Um dies zu erreichen, machen wir ausgiebig Gebrauch vom WS-Addressing-Standard. Eine der Komponenten unseres Frameworks, der Routing-Dienst, verwendet die Informationen in den Kopfzeilen der Nachrichten, um zu entscheiden, was der nächste Hop sein wird (Hop ist in diesem Fall eine andere Framework-Komponente). In den meisten Fällen wird eine Nachricht an die Rückseite zugestellt, sobald sie die Integrationsschicht betritt, was wir als einfaches Routing bezeichnen.
Sobald jedoch eine spezielle Aktivität durchgeführt werden muss (wie z.B. die Transformation des Datenmodells), wird die Nachricht an eine der Komponenten des Frameworks weitergeleitet, die nicht mit der Außenwelt verbunden ist. Wir bezeichnen diese Dienste als
Robustheit
Natürlich ist es von eminenter Bedeutung, dass bei der Übermittlung der Nachricht nichts schief geht oder dass wir zumindest mit der Situation umgehen können(Ausnahmemanagement), wenn es doch passiert. Wenn wir eine Nachricht erhalten, prüfen wir als erstes, ob sie den von uns durchgesetzten Industrie- und Designstandards entspricht(technische Validierung). Manchmal möchte der Verbraucher/Verleger nicht auf die (funktionale) Antwort warten, aber dennoch informiert werden, ob seine Nachricht technisch gültig war. In diesem Fall senden wir ihm eine Antwort, die genau das bestätigt(technische Annahme). Zwei unserer Funktionen befassen sich mit Lastspitzen: Die Drosselung stellt sicher, dass die Integrationsschicht nur so viel aufnimmt, wie sie bewältigen kann, während die Pufferung gewährleistet, dass wir die Anwendungen, mit denen wir uns verbinden, nicht überfordern. Ähnlich wie die zweite Funktion ist die aufgeschobene Zustellung , die verwendet wird, wenn wir im Voraus wissen, dass die Rückseite nicht verfügbar ist. Aber die bei weitem wichtigste dieser Funktionen ist die garantierte Zustellung. Wir haben mit einer bidirektionalen Variante (unter Verwendung von WS-RM) herumgespielt, uns aber schließlich für eine unidirektionale Implementierung entschieden, was bedeutet, dass wir die Nachricht vor dem Versenden zunächst speichern und im Falle eines HTTP-Fehlercodes erneut versenden. Zuletzt (und eigentlich am wenigsten, da sie kaum genutzt wird) ist es auch möglich, eine syntaktische Validierung ausgehender Nachrichten durchzuführen. Da wir aber gerne dem Postel'schen Gesetz folgen (auch bekannt als das Robustheitsprinzip), sind wir der Meinung, dass es in der Verantwortung des Verbrauchers liegt, sich zu vergewissern, dass die Nachricht von Anfang an gültig war (Sie können sich vorstellen, dass wir dafür etwas verkaufen mussten). Die einzige Ausnahme ist, wenn die Nutzlast durch das Framework verändert wird.
Sicherheit
Jede Anwendung, die eine Verbindung zur Integrationsschicht herstellen möchte, muss sich mit dem WS-Security UsernameToken anmelden(Authentifizierung). Für die meisten Dienste, die wir anbieten, reicht das aus. In einigen wenigen Fällen muss eine solche Anwendung eine explizite Genehmigung(Autorisierung) haben. Intern nicht verwendet (nur wenn wir Anfragen von bestimmten externen Kunden erhalten) ist die Integrität, bei der wir verlangen, dass bestimmte Teile der Nachrichtenheader und der Nutzdaten signiert sind.
Transformation
In Anbetracht der Tatsache, dass nicht alle Anwendungen, die mit dem Framework verbunden sind, "dieselbe Sprache sprechen" (wie im vorigen Blog erwähnt), besteht ein offensichtlicher Bedarf an einer Datenmodelltransformation - eine unserer meistgenutzten Funktionen. Weit weniger beliebt ist die Split-Funktion , die es ermöglicht, eine große Nachricht in kleinere Teile aufzuteilen.
Datenspeicherung
Die letzten paar Funktionen spielen eine eher unterstützende Rolle zu den bereits erwähnten. Wir bieten
Fazit
Die meisten dieser Funktionen gibt es bereits seit der ersten Version unseres Frameworks und sie haben sich im Laufe der Zeit als generisch bewährt. In einigen wenigen Fällen mussten wir einige Änderungen vornehmen und auch jetzt gibt es noch ein oder zwei Funktionen, die wir in Zukunft vielleicht anders implementieren werden. Es gibt auch eine Liste zusätzlicher Funktionen, aber sie ist eher kurz, was ich als Zeichen dafür werte, dass das, was wir hier haben, ziemlich vollständig ist. Das ist Nummer vier; das nächste Mal werde ich ein wenig über die spezifischeren Ergebnisse sprechen, die wir unseren Projektteams liefern.
Verfasst von
Marit Fränkel
Unsere Ideen
Weitere Blogs
Contact



