Tutorial
Diese Seite ist ein Teil der IsyFact-Standards. Alle Inhalte der Seite, insbesondere Texte und Grafiken, sind urheberrechtlich geschützt. Alle urheberrechtlichen Nutzungs- und Verwertungsrechte liegen beim Bundesverwaltungsamt.
Die Nutzung ist unter den Lizenzbedingungen der Creative Commons Namensnennung 4.0 International gestattet.
1. Einleitung
Dieses Dokument dient als Einstieg in die technischen Grundlagen der IsyFact. Es enthält in Kurzform die wesentlichen Designvorgaben und beschreibt, wie einzelne Aspekte in Anwendungen umzusetzen sind, die gemäß der Referenzarchitektur der IsyFact gebaut werden. Das Dokument unterstützt damit Entwickler und technische Chefdesigner bei der Konstruktion und Realisierung von Anwendungen einer zur IsyFact konformen Anwendungslandschaft. Im Sinne einer Referenz enthält es jedoch nicht alle Details der zugrunde liegenden Konzepte. Der Fokus liegt darauf, einen schnellen Überblick über die einzelnen Themen zu geben und die wichtigsten Realisierungsaufgaben zusammenfassend darzustellen.
Zunächst beschreibt das Kapitel Bezug IsyFact, wie sich die IsyFact in Entwicklungsprojekte einbinden lässt. Danach beleuchten die Kapitel Datenhaltung , Fachkomponenten der Anwendung und Anwendungsnutzung jeweils einzelne Kernthemen der Anwendungsentwicklung. Kapitel Querschnitt fasst alle Querschnittsthemen zusammen. Jedes Teilkapitel beginnt in der Regel mit der Auflistung der wichtigsten Designvorgaben und einem Klassendiagramm. Es folgt eine Realisierungsanleitung, die alle wesentlichen Schritte zur Umsetzung in Kurzform enthält.
2. Bezug und Nutzung der IsyFact
Alle Bibliotheken der IsyFact stehen über Maven Central zum Download bereit.
Zur Nutzung der Bibliotheken in der Anwendungsentwicklung steht ein zentrales BOM (Bill Of Materials) zur Verfügung, das Teil der Maven-Konfiguration (pom.xml
) wird:
<dependencyManagement>
<dependencies>
<dependency>
<groupId>de.bund.bva.isyfact</groupId>
<artifactId>isyfact-bom</artifactId>
<version>3.2.x</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>
Somit kann zentral eine zu nutzende Version der IsyFact festgelegt werden. Diese legt ebenfalls die Versionen aller Drittprodukte fest, die im Produktkatalog der IsyFact enthalten sind. Aktualisierungen geschehen ebenfalls zentral, durch die Erhöhung der Versionsnummer des IsyFact-BOM.
Durch die Nutzung des IsyFact-BOM ist es nicht mehr notwendig, die IsyFact-Bibliotheken mit einzelnen Versionsnummern einzubinden. Die Versionsnummer ermittelt Maven zentral über das BOM. Es reicht also folgender Abschnitt, um eine Bibliothek einzubinden:
<dependencies>
...
<dependency>
<groupId>de.bund.bva.isyfact</groupId>
<artifactId>isy-logging</artifactId>
</dependency>
...
</dependencies>
3. Datenhaltung
In diesem Kapitel wird die Implementierung der Datenhaltung einer Anwendung beschrieben. Die Datenhaltung besteht im Wesentlichen aus den Entitäten (Entity) und den zugehörigen Data Access Objects (DAOs). Alle Konzepte und Vorgaben zum Thema Persistenz und Datenzugriff stehen im Detailkonzept Komponente Datenzugriff sowie im Konzept JPA/Hibernate.
3.1. Designvorgaben
-
Der eigentliche Datenbankzugriff wird über die Java Persistence API (JPA) gekapselt. Als Implementierung für die JPA wird Hibernate verwendet.
-
Das Datenbank-Mapping wird über Annotation in den Klassen der Entitäten festgelegt.
-
Der Zugriff auf Entitäten erfolgt immer über DAOs oder durch die Traversierung des persistenten Datenmodells.
-
DAOs stellen Zugriffsmethoden (Suchen, Schreiben, Löschen…) für genau eine Entität bereit.
-
Datenbank-Queries werden im Normalfall aus den Methodennamen generiert. Sonst werden sie per
@Query
-Annotation an der Methode beschrieben. -
Entitäten werden entweder von genau einer fachlichen Komponente oder querschnittlich von der Komponente „Basisdaten“ verwaltet.
-
Der Datenzugriff erfolgt entweder über die Komponenten-Schnittstelle oder im Fall der Basisdaten direkt über die Basisdaten-DAOs.
-
Für persistente Entitäten, die über eine Komponentenschnittstelle angeboten werden, werden eigene Schnittstellenobjekte definiert, die per Deep-Copy gefüllt werden. Hierfür wird ein Bean-Mapper verwendet. Innerhalb einer Teilanwendung dürfen persistente Entitäten allerdings über Komponentengrenzen hinweg genutzt werden.
-
DAOs und Entitäten werden in einer festgelegten Paketstruktur abgelegt.
-
Die Transaktionssteuerung wird per AOP in der Service-Schicht durchgeführt (siehe Kapitel Anbieten von Service-Schnittstellen).
Aspect-Oriented Programming (AOP) ist ein Programmierparadigma, das anstrebt, verschiedene logische Aspekte eines Programmes getrennt voneinander zu entwerfen, zu entwickeln und zu testen. Die getrennt entwickelten Aspekte werden dann zur endgültigen Anwendung zusammengefügt. * Der Primärschlüssel einer Entität besteht aus genau einem Attribut. Besteht der fachliche Schlüssel der Entität aus genau einem Attribut, so wird er auch als Primärschlüssel verwendet. Ansonsten wird ein künstlicher technischer Primärschlüssel verwendet.
3.2. Klassendesign
AuskunftImpl |
AuskunftImpl ist die Implementierung der Komponente Auskunft (Anwendungskern). Die Komponente verwendet die DAOs zum Zugriff auf ihre Daten. Während die DAOs die eigentlichen Entitätstypen anbieten, liefert die Komponente Auskunft nur nicht persistente Schnittstellenobjekte auf ihre Daten. |
RegisterEintragDao |
DAOs kapseln den Datenbankzugriff für spezifische Entitätstypen. Sie stellen Methoden zum Suchen, Anlegen und Löschen dieser Typen zur Verfügung. Zur Durchführung der Datenbank-Queries benötigt das DAO den EntityManager. Dieser wird von Spring bereitgestellt. |
RegisterEintrag |
Implementierungsklasse für Entitäten vom Typ |
RegisterEintragDaten |
Nicht persistentes Schnittstellenobjekt, das die Daten des RegisterEintrags enthält. Wird als Deep-Copy durch Bean-Mapper erzeugt. |
Im Normalfall verwenden Komponenten die Daten anderer Komponenten über deren Schnittstelle. Der direkte Zugriff auf die DAOs ist verboten.
Entitäten, die von mehreren Anwendungskomponenten verwendet werden, bietet die Komponente Basisdaten an. Die Komponente Basisdaten ist keine vollständige Komponente, sie bietet keine Schnittstellen an. Ausnahmsweise verwenden Komponenten stattdessen direkt die zugehörigen DAOs der Basisdaten. Dieser Fall ist auch in Abbildung 1 dargestellt. Weitere Details können der IsyFact Referenzarchitektur entnommen werden.
3.3. Realisierung
Zur Realisierung der Datenhaltung müssen folgende Aktivitäten durchgeführt werden.
3.3.1. Anlegen des Datenbankschemas
Das Datenbankschema muss angelegt werden. Dazu werden die benötigten DDL-Anweisungen, wie in Versionierung von Datenbankschemas beschrieben, in einem Verzeichnis abgelegt.
Das initiale Datenmodell kann über das Tool hbm2ddl
erzeugt werden.
Dieses muss anschließend noch bearbeitet werden.
hbm2ddl ist Teil der von Hibernate bereitgestellten Werkzeuge.
Nutzungsdokumentation unter:
Hibernate Toolset Guide
|
3.3.2. Einbinden der Bibliotheken
Die benötigten Bibliotheken müssen als Abhängigkeiten in die Maven-Konfiguration (pom.xml
) aufgenommen werden:
<dependencies>
...
<dependency>
<groupId>de.bund.bva.isyfact</groupId>
<artifactId>isy-persistence</artifactId>
</dependency>
...
</dependencies>
3.3.3. Implementierung der Entitätsklassen und DAOs
Die Entitätsklassen und Schnittstellen-Klassen müssen implementiert werden. In den Entitätsklassen müssen die Mapping-Informationen für JPA als Annotationen eingetragen werden. Die Implementierung der DAOs wird automatisch generiert.
3.3.4. Implementierung von Schnittstellen-Klassen
Schnittstellen-Klassen dienen als eine nur Lese-Sicht auf persistente Entitäten. Dieses wird benötigt, wenn Komponenten persistente Entitäten über ihre Schnittstelle herausgeben, um zu verhindern, dass andere Komponenten diese Daten ändern.
Schnittstellen-Klassen enthalten alle Attribute, die auch ihre persistenten Gegenstücke besitzen. Zusätzlich besitzen sie Getter-/Settermethoden für alle Attribute.
Die Schnittstellen-Objekte werden per Deep-Copy mittels eines Bean-Mappers erzeugt und dem Aufrufer außerhalb der Teilanwendung zurückgeliefert. So stehen dem Aufrufer alle Informationen zur Verfügung, es ist ihm aber nicht möglich, Änderungen zu persistieren. Damit ist die Datenhoheit der Komponente gewahrt.
Im Folgenden ist ein beispielhaftes Mapping zu sehen:
/* Bean-Mapper */
protected MapperFacade mapper;
// Entität mappen
RegisterEintragDaten daten = mapper.map(registerEintrag, RegisterEintragDaten.class);
4. Fachkomponenten der Anwendung
In diesem Kapitel wird die Realisierung von Fachkomponenten beschrieben.
4.1. Designvorgaben
-
Alle Komponenten definieren ihre Schnittstelle über ein Java-Interface. Eine Ausnahme bildet die Komponente Basisdaten. Diese Komponente verwaltet gemeinsam genutzte Daten und bietet keine eigene Schnittstelle an. Der Zugriff erfolgt hier direkt über die DAOs (siehe Kapitel Klassendesign).
-
Komponenten bieten an ihrer Schnittstelle eine Nur-Lese-Sicht auf ihre Daten an. Für jeden Entitätstyp wird eine nicht-persistente Schnittstellenklasse erstellt. Die Komponentenschnittstelle wird von einer Java-Klasse implementiert. Diese Klasse kann die Anwendungsfälle im einfachen Fall direkt implementieren oder an Anwendungsfall-Klassen delegieren.
-
Die interne Strukturierung von Komponenten ist nicht im Detail vorgeben. Für fachliche Komponenten wird eine Basisimplementierung in IsyFact Referenzarchitektur beschrieben.
4.2. Klassendesign
Auskunft |
Interfaces zur Definition der Schnittstelle der Komponente "Auskunft". |
AuskunftImpl |
Implementierung der Komponente |
AwfLeseGesamtBestand |
Beispielklasse zur Implementierung eines Anwendungsfalls. Diese Klassen werden explizit instanziiert, also nicht als Spring-Bean konfiguriert. Falls ein Anwendungsfall weitere Komponenten (Konfiguration, Regelwerk) etc. benötigt, werden diese durch die instanziierende Impl-Klasse übergeben. |
RegisterEintrag |
Persistente Entität für Register-Einträge. |
RegisterEintragDaten |
Nur-Lese-Sicht auf Register-Einträge (siehe Kapitel Implementierung von Schnittstellen-Klassen). |
4.3. Package-Struktur
-
Die Realisierung der Komponenten-Schnittstelle erfolgt im Package
<organisation>.<domäne>.<system>.core.<komponente>
Für das Bundesverwaltungsamt ist dies z.B. de.bund.bva
-
Die Realisierung der Komponenten-Implementierung erfolgt im Package
<organisation>.<domäne>.<system>.core.<komponente>.impl.*
-
Die nicht-persistenten Schnittstellen-Klassen werden im Package
<organisation>.<domäne>.<system>.core.<komponente>.ausgabedaten.*
implementiert.
4.4. Realisierung
-
Die Implementierungsklassen und Interfaces der Komponente werden implementiert.
-
Die Komponente mit
@Component
bzw. mit einer passenden Spezialisierung annotiert, damit sie von Spring als Bean konfiguriert wird. -
Je nach Bedarf wird die Komponente anderen Komponenten per Dependency Injection bekannt gemacht.
5. Anwendungsnutzung
In diesem Kapitel wird die Realisierung von verschiedenen, technischen Zugangswegen zum Anwendungskern beschrieben, mit Ausnahme des GUI-Zugangs. Das Thema umfasst das Anbieten von internen Service-Schnittstellen per HTTP Invoker, das Nutzen derselben und die Nutzung des Anwendungskerns im Rahmen der Batch-Verarbeitung.
5.1. Anbieten von Service-Schnittstellen
Dieser Abschnitt beschreibt die Realisierung von HTTP Invoker Schnittstellen (siehe Spring). HTTP Invoker Schnittstellen sind interne Service-Schnittstellen, die innerhalb der Anwendungslandschaft durch andere Anwendungen genutzt werden dürfen.
Ab IsyFact 2.0 ist die Verwendung von REST-Schnittstellen erlaubt. HTTP Invoker wird in folgenden Releases (IsyFact 2.x) als Schnittstellenformat abgelöst. Die Verwendung von REST-Schnittstellen wird einem gesonderten Konzept erläutert. Ab IsyFact 3.0 wird die Verwendung von HTTPInvoker Schnittstellen nicht mehr empfohlen und wird in zukünftigen Versionen nicht mehr unterstützt werden. |
Extern verfügbare Services sind durch WebService-Schnittstellen anzubieten, über einen ServiceGateway.
5.1.1. Designvorgaben
-
Interne Services werden per Spring HTTP Invoker angeboten.
-
Es werden keine Komponenten des Anwendungskerns extern verfügbar gemacht: Es wird stets eine eigene Service-Schicht implementiert. Dazu gehört auch die Definition einer Service-Schnittstelle als Java-Interface (RemoteBean).
-
Jede Service-Methode erhält einen zusätzlichen Parameter
AufrufKontext
. Im Aufrufkontext werden Informationen zum Aufrufer (Name, Behördenkennzeichen, Rollen…) übermittelt. Die Implementierungen verschiedener Aufrufkontext-Transportobjekte sind in der Bibliothekisy-serviceapi-sst
enthalten. -
Die Implementierung der Service-Schnittstelle wird in eine Exception-Fassade und die eigentliche Service-Implementierung aufgeteilt.
-
In der Service-Schnittstelle werden nur Transport-Exceptions und Transportobjekte verwendet. Die Umwandlung der internen Exceptions und Entitäten auf Transport-Exceptions und -Objekte erfolgt in der Service-Schicht.
-
Listen von Objekten in Ein- und Ausgabeparametern werden als Arrays übertragen. Andere
Collection
-Typen sind nicht erlaubt. -
Beim Kompilieren der Schnittstellenprojekte muss auf die Java-Version geachtet werden. Die Java-Version darf nicht neuer sein, als diejenige des Nutzers. Gegebenenfalls muss die Schnittstelle auf eine ältere Version kompiliert werden.
5.1.2. Package-Struktur
-
Schnittstellen werden versioniert. Die Versionsnummer wird dreistellig im Package-Namen der Service-Schnittstelle angegeben. Beispiel: Die Version 1.0.0 einer generischen Schnittstelle einer generischen Anwendung, wird in den folgenden Packages implementiert:
de.bund.bva.<anwendung>.<schnittstelle>.httpinvoker.v1_0_0.*
-
Interfaces, Transport-Exceptions und Transportobjekte werden im Package
<organisation>.<domäne>.<system>.service.httpinvoker.vX_Y_Z
implementiertDas sind genau die Inhalte, die im eigenen Projekt <system>-httpinvoker-sst
implementiert werden. -
Die Implementierung der Service-Schnittstelle erfolgt im Package
<organisation>.<domäne>.<system>.service.httpinvoker.vX_Y_Z.impl
.
5.1.3. Klassendesign
AuskunftRemoteBean |
Externes Interface für den Zugriff auf die Auskunft-Komponente per HTTP Invoker.
Bei Nutzung einer Service-Schnittstelle generiert Spring auf Basis dieses Interfaces einen Proxy für den Remote-Zugriff. |
AuskunftToException |
Transport-Exception der Auskunft. Jede Komponente darf ausschließlich Transport-Exceptions an ihrer Service-Schnittstelle werfen. Details sind in Konzept Fehlerbehandlung nachzulesen. |
AufrufKontextTo |
|
RegisterEintragTo |
Transportobjekt für Register-Eintrag-Entitäten. |
AuskunftExceptionFassade |
Die Klasse |
AuskunftService |
Internes Interface für den Auskunft-Service. Diese Schnittstelle verwendet Transportobjekte aber noch die internen Exceptions. Diese werden erst von der Exception-Fassade auf die eigentlichen Exceptions der AuskunftRemoteBean umgewandelt. |
AuskunftServiceImpl |
Implementierung des
Das Mappen der Daten wird mit einem Bean Mapper durchgeführt. Dies geschieht automatisiert, ohne dass man Mapping-Informationen hinterlegen muss. Grund hierfür ist die strukturelle Gleichheit der Objekte des Anwendungskerns und der Service-Schicht. Dadurch ist der Bean Mapper in der Lage diese Objekte generisch zu übersetzen. In den Service-Implementierungen wird außerdem die Transaktionssteuerung durchgeführt. Diese wird per Spring-AOP über Annotations konfiguriert (siehe Kapitel Datenhaltung). |
5.1.4. Realisierung
Zur Realisierung einer Service-Schnittstelle müssen einige Aktivitäten ausgeführt werden. Diese werden im Folgenden beschrieben.
5.1.4.1. Anlegen des Schnittstellenprojekts
Das neue Projekt <system>-httpinvoker-sst
muss angelegt werden.
Dazu wird eine neue pom.xml
angelegt.
Wichtig ist, dass darin die Compiler-Version so festgelegt wird, wie es im Produktkatalog vorgegeben ist.
Das Projekt muss ein Jar erzeugen, das von anderen Systemen zur Nutzung der Service-Schnittstelle benötigt wird.
In der Pom-Datei muss konfiguriert werden, dass das Jar in das Verzeichnis repository-deploy
(Deployment-Repository) deployt wird.
Das Schnittstellen-Projekt erhält dieselbe Group-ID wie das eigentliche Anwendungsprojekt.
Die Artifact-ID ist <system>-httpinvoker-sst
.
5.1.4.2. Realisierung der „externen“ Service-Schnittstelle
Das RemoteBean-Interface, die Transportobjekte und -Exceptions müssen im Schnittstellen-Projekt angelegt werden.
5.1.4.3. Realisierung der Service-Implementierung
Im Projekt der eigentlichen Anwendung müssen die Exception-Fassade, das Service-Interface (z.B. AuskunftService
) und die Implementierung dieses Interfaces angelegt werden.
Im Rahmen der Implementierung muss ggf. die Bean-Mapping-Konfiguration für die Transformation der Transport- auf die Entitätsobjekte angelegt werden. Der Bean Mapper wird als Spring-Bean konfiguriert. Dabei werden die zuvor angelegten Mapping-Dateien im Mapper konfiguriert.
Die Exception-Fassade und die Service-Implementierung werden als Spring-Beans konfiguriert. Die Exception-Fassade erhält eine Referenz auf die Service-Implementierung per Dependency Injection. Genauso erhält die Service-Implementierung eine Referenz auf den Bean Mapper per Dependency Injection.
Vor der Exception-Fassade wird mithilfe der Annotation @StelltLoggingKontextBereit
die mit dem Aufrufkontext mitkommende Correlation-Id für das Logging registriert.
An den Methoden der Service-Implementierung werden die Annotationen @StelltAufrufKontextBereit
und @Gesichert
gemäß Nutzungsvorgaben Sicherheit verwendet, um den Zugriff auf die Service-Methode zu autorisieren.
5.1.4.4. Konfigurieren der Service-Schnittstelle
In der Konfigurationsklasse der Service-Schicht wird die HTTP Invoker Konfiguration der Service-Schnittstelle durchgeführt. Dazu werden das Remote-Bean-Interface und die zugehörige Implementierung in Form der Exception-Fassade als Service konfiguriert Listing 5. Der Bean-Name ist für die URL, unter welcher der Service erreichbar sein wird, wichtig.
@Configuration
public class ServiceConfiguration {
@Bean("/AuskunftBean_v1_0")
public IsyHttpInvokerServiceExporter auskunftService(AuskunftExceptionFassade auskunftFassade) {
IsyHttpInvokerServiceExporter exporter = new IsyHttpInvokerServiceExporter();
exporter.setService(auskunftFassade);
exporter.setServiceInterface(AuskunftRemoteBean.class);
return exporter;
}
}
IsyHttpInvokerServiceExporter
ist eine Erweiterung von HttpInvokerServiceExporter
und deaktiviert standardmäßig die Verwendung von Proxy-Klassen.
5.1.4.5. Einbinden der benötigten Bibliotheken
5.1.4.5.1. Bibliotheken für das Service-Schnittstellen-Projekt
Das Projekt der Service-Schnittstelle benötigt die in Listing 6 aufgelisteten Bibliotheken:
<dependencies>
...
<dependency>
<groupId>de.bund.bva.isyfact</groupId>
<artifactId>isy-exception-sst</artifactId>
</dependency>
<dependency>
<groupId>de.bund.bva.isyfact</groupId>
<artifactId>isy-serviceapi-sst</artifactId>
</dependency>
...
</dependencies>
5.1.4.5.2. Bibliotheken für die Implementierung der Service-Schnittstelle
In die Build-Konfiguration des Hauptprojekts des Anwendungssystems müssen folgende Bibliotheken aufgenommen werden:
<dependencies>
...
<dependency>
<groupId>{organisation}.{domäne}.{system}</groupId>
<artifactId>{systemname}-httpinvoker-sst</artifactId>
</dependency>
<dependency>
<groupId>de.bund.bva.isyfact</groupId>
<artifactId>isy-exception-core</artifactId>
</dependency>
<dependency>
<groupId>de.bund.bva.isyfact</groupId>
<artifactId>isy-serviceapi-core</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>ma.glasnost.orika</groupId>
<artifactId>orika-core</artifactId>
</dependency>
...
</dependencies>
Die verwendete Version von Orika ist dem Produktkatalog zu entnehmen. |
5.2. Nutzen von Service-Schnittstellen
Dieser Abschnitt beschreibt, wie Service-Schnittstellen genutzt, d.h. aufgerufen werden können.
5.2.1. Designvorgaben
Die genutzte Schnittstelle soll vom eigenen Anwendungskern entkoppelt werden. D.h. im eigenen Anwendungskern werden keine Exceptions oder Transportobjekte der genutzten Schnittstelle verwendet. Dazu wird ein Wrapper um die Schnittstelle implementiert.
5.2.2. Klassendesign
Zum Zugriff auf den Service wird im Normalfall ein Adapter im Client implementiert (AuskunftAdapter
). Dieser Adapter entkoppelt den Anwendungskern des Clients vom Service.
Im Adapter wird im Wesentlichen eine Wrapper-Klasse (AuskunftWrapper
) implementiert.
Diese führt das Mapping der Exceptions und der Daten durch.
Der Adapter implementiert im Beispiel ein eigenes Auskunft
-Interface für die Nutzung durch die Client-Anwendung.
Für die Remote Zugriffe wird der HttpInvokerProxy
benutzt.
Dieser wird automatisch von Spring erzeugt.
Er bietet das RemoteBean-Interface auf Client-Seite an und sorgt dafür, dass Aufrufe per HTTP Invoker an den Service weitergereicht werden.
5.2.3. Realisierung
5.2.3.1. Einbinden der Schnittstellen-Bibliothek
Zur Realisierung wird die Bibliothek mit der zu nutzenden Service-Schnittstelle benötigt. Dieses befindet sich im Deployment-Repository der zu nutzenden Anwendung. Das Jar wird in das eigene Projekt-Repository kopiert und via Maven eingebunden.
Zusätzlich müssen die HTTP Invoker Bibliotheken von Spring eingebunden werden. Eine vollständige Liste zeigt Listing 8.
<dependencies>
...
<dependency>
<groupId>{organisation}.{domäne}.{system}</groupId>
<artifactId>{systemname}-httpinvoker-sst</artifactId>
</dependency>
<dependency>
<groupId>de.bund.bva.isyfact</groupId>
<artifactId>isy-serviceapi-core</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
...
</dependencies>
|
5.2.3.2. Durchführen der Konfiguration
Spring erzeugt anhand des Service-Interfaces HTTP Invoker Proxies, die den eigentlichen Aufruf durchführen. Diese Proxies werden als Spring-Bean konfiguriert:
@Configuration
public class ServiceConfig {
@Bean
public HttpInvokerProxyFactoryBean invoker(ConfigProperties properties) {
HttpInvokerProxyFactoryBean invoker = new HttpInvokerProxyFactoryBean();
invoker.setServiceUrl(properties.getServiceUrl());
invoker.setServiceInterface(BeispielServiceRemoteBean.class);
return invoker;
}
}
Auf der Bean können alle Methoden des Interfaces serviceInterface
aufgerufen werden, der Aufruf erfolgt dann automatisch
per HTTP Invoker gegen das in serviceUrl
konfigurierte Ziel-System.
Die URL wird als betriebliche Konfiguration in application.properties ausgelagert und durch eine @ConfigurationProperties -Klasse von Spring Boot gesetzt.
|
5.2.3.3. Erweiterung um die Aufrufwiederholung mittels Service Utilities
Die in diesem Kapitel aufgeführte Konfiguration eines aufzurufenden Services kann durch die Verwendung einer Aufruf-Wiederholungsimplementierung erweitert werden, so dass Aufrufe bei Timeouts wiederholt werden. Dies ist nur notwendig, sofern eine Aufrufwiederholung eine Anforderung an die Anwendung ist. Für die Aufrufwiederholung ist lediglich die Spring-Konfiguration des Proxies anzupassen:
@Configuration
public class ServiceConfig {
@Bean
public HttpInvokerProxyFactoryBean invoker(ServiceConfigProperties properties, HttpInvokerRequestExecutor executor) {
HttpInvokerProxyFactoryBean invoker = new HttpInvokerProxyFactoryBean();
invoker.setServiceUrl(properties.getServiceUrl());
invoker.setServiceInterface(BeispielServiceRemoteBean.class);
return invoker;
}
@Bean
public TimeoutWiederholungHttpInvokerRequestExecutor executor(ServiceConfigProperties properties) {
TimeoutWiederholungHttpInvokerRequestExecutor executor = new TimeoutWiederholungHttpInvokerRequestExecutor();
executor.setAnzahlWiederholungen(properties.getWiederholungen());
executor.setTimeout(properties.getTimeout());
return executor;
}
Auf der Bean executor
sind die anzahlWiederholungen
und der timeout
konfiguriert.
Dieser RequestExecutor
erweitert den Standard-RequestExecutor
von Spring um die Möglichkeit Timeouts zu definieren und eine konfigurierte Anzahl an Aufruf-Wiederholungen durchzuführen.
Dieser RequestExecutor
ist der Spring-HttpInvokerProxyFactoryBean bekannt zu machen.
5.2.3.4. Implementierung des Wrappers
Zur Entkopplung des eigenen Anwendungskerns von der Schnittstelle wird ein Wrapper für die Schnittstelle implementiert. Der Wrapper führt das Mapping der internen Datenobjekte auf die Transportobjekte durch. Dieses kann bei Bedarf mit einem Bean Mapper gemacht werden.
Zusätzlich führt der Wrapper das Exception-Handling durch. Der Wrapper kann auftretende Exceptions in eigene Exceptions umwandeln (Exception-Chaining) oder explizit behandeln.
5.3. Batch-Verarbeitung
In diesem Kapitel wird die Implementierung von Batches zu einer Anwendung beschrieben.
5.3.1. Designvorgaben
-
Die Batch-Verarbeitung verwendet den Anwendungskern der zugehörigen Anwendung. Der Anwendungskern ist Teil des Batch-Deployments, d.h. der Code ist sowohl Teil der Server-Anwendung als auch der Batch-Anwendung in Bezug auf Deploymenteinheiten.
-
Zur Realisierung der Batchlogik wird eine Batch-Ausführungs-Bean implementiert.
-
Falls für die Verarbeitung im Batch eigene Fachlogik benötigt wird, ist diese trotzdem den entsprechenden Anwendungskomponenten der zugehörigen Geschäftsanwendung hinzuzufügen.
-
Im Rahmen der Initialisierung hat die Ausführungs-Bean unter anderem die Aufgabe, die Konsistenz und Korrektheit der Eingabedaten zu prüfen.
-
Falls die zu verarbeitenden Sätze eines Batches das Ergebnis einer Datenbank-Query sind, ist in der Initialisierung die Query über eine Anwendungskomponente der zugehörigen Geschäftsanwendung abzusetzen. Diese Query soll die (fachlichen) Schlüssel von Entitäten, nicht Entitäten selbst auslesen.
-
Die Batches sind möglichst robust zu konstruieren: Falls auf ein fachliches Problem in der Ausführungs-Bean reagiert werden kann, sollte dies getan werden.
-
Batches erzeugen ein Ausführungsprotokoll. Der Batchrahmen, die Steuerungsimplementierung, die jeden Batch und dessen Arbeitsschritte steuert, stellt die notwendige Implementierung bereit. Die Ausführungs-Bean übermittelt dem Batchrahmen Status-Informationen für das Protokoll.
-
Batches verwenden einen (konfigurierten) technischen Benutzer, um sich vor Start der fachlichen Verarbeitung am IAM-Service des Anwendungssystems oder der Anwendungslandschaft zu authentifizieren.
-
Alle Batches zu einer Anwendung werden als eigenständige Deployment-Einheit ausgeliefert.
5.3.2. Klassendesign
Abbildung 6 zeigt eine beispielhafte Implementierung eines Batches, der die Komponenten Auskunft
und Basisdaten
verwendet.
Im Normalfall erhält die Batch-Bean (AuskunftBatch
) eine Referenz auf die Komponenten des Anwendungskerns per Spring-Dependency.
Für die Komponente Basisdaten erfolgt der Zugriff wie immer mittels statischer Aufrufe der DAOs.
Der Batchrahmen definiert das Interface BatchAusfuehrungsBean
. Dieses dient der Steuerung des Batches durch den Batchrahmen.
Es muss von der Batch-Ausführungs-Bean implementiert werden.
Der Batchrahmen sorgt auch für die Initialisierung und Ausführung des Batches.
Der Batchrahmen übernimmt die Transaktionssteuerung. Die Transaktionssteuerung im Batch sieht vor, mehrere Arbeitsschritte in einer Transaktion abzuwickeln. Die Größe der Transaktion (Commit-Rate) wird über den Batchrahmen konfiguriert.
5.3.3. Realisierung
5.3.3.1. Einbinden der Bibliothek
Zur Realisierung von Batches muss die in Listing 11 aufgelistete Bibliothek eingebunden werden.
<dependencies>
...
<dependency>
<groupId>de.bund.bva.isyfact</groupId>
<artifactId>isy-batchrahmen</artifactId>
</dependency>
...
</dependencies>
5.3.3.2. Implementierung der Batch-Logik
Die Batch-Logik wird implementiert, in dem eine Batch-Bean im Package <organisation>.<domäne>.<anwendung>.batch
implementiert wird.
Für die Realisierung ist es notwendig, dass die Batch-Bean das Interface BatchAusfuehrungsBean
aus der Bibliothek isy-batchrahmen
implementiert.
Der Batchrahmen ruft als Erstes die Methode initialisieren
auf.
Dabei werden alle zur Initialisierung benötigten Informationen übergeben.
Details dazu werden im JavaDoc der Methode beschrieben.
Der Parameter BatchErgebnisProtokoll
enthält eine Referenz auf ein Protokollobjekt, welches der Batch verwendet, um Protokoll-Meldungen und Statistiken an den Batchrahmen zu übergeben.
5.3.3.3. Konfiguration des Batches und Batchrahmens
Für jeden Batch muss eine Property-Datei in /src/main/resources/resources/batch
angelegt werden.
In dieser statischen Konfiguration werden unter anderem die Batch-ID und die Transaktionssteuerung konfiguriert.
Eine Beschreibung der Parameter ist in Detailkonzept Komponente Batch enthalten.
Die betriebliche Konfiguration des Batches ist identisch zu derjenigen der zugehörigen Anwendung. Auch Parameter, die nur für den Batch benötigt werden, werden in die betriebliche Konfiguration der Geschäftsanwendung aufgenommen.
5.3.3.4. Spring-Konfiguration anlegen
Für den Batchrahmen werden in der Konfigurationsklasse der Batch-Schicht die Spring-Beans des Batchrahmens und für jeden existierenden Batch die Ausführungs-Bean als Spring-Bean definiert.
Zusätzlich müssen folgende Beans erstellt werden:
-
Eine Bean vom Typ
BatchRahmenMBean
zur Überwachung des Batchrahmens. Diese muss über den Spring MBeanExporter exportiert werden. -
Eine Bean für den
AufrufKontextVerwalter
, die nicht den Scopethread
hat. Ist in der Anwendungskonfiguration bereits eine Bean dieses Typs definiert, kann sie mit der Annotation@ExcludeFromBatchContext
ausschließen. -
Eine Bean für einen
JpaTransactionManager
. -
Die Konfigurationsklasse der Batch-Schicht muss mit der Annotation
@EntityScan("de.bund.bva.isyfact.batchrahmen.persistence.rahmen")
versehen werden, damit die Entitäten des Batchrahmens gefunden werden.
Die Spring-Konfiguration der Anwendung kann auch für den Batches verwendet werden.
Dazu müssen Beans, die nicht für Ausführung eines Batches instanziiert werden sollen, mit
@ExcludeFromBatchContext
annotiert werden.
5.3.3.5. Konfiguration des Batch-Deployments
Für das Deployment des Batches wird ein neues Maven-Projekt <system>-batch
angelegt.
Dieses hat die Aufgabe das Deployment-Paket für den Batch zusammenzustellen.
Dazu wird eine neue pom.xml angelegt, die als Ziel-Typ ein Jar mit allen Dateien des Batches erzeugt. Zusätzlich können in diesem Projekt Shell-Skripte und ähnliches für den Batch abgelegt werden.
Das Batch-Projekt enthält keinen Java-Code. Die Batch-Beans liegen im normalen Anwendungsprojekt.
6. Querschnitt
In diesem Kapitel wird die Umsetzung querschnittlicher Aspekte beschrieben.
6.1. Logging
In diesem Abschnitt wird beschrieben, wie das Logging umzusetzen und zu konfigurieren ist.
6.1.1. Designvorgaben
-
Für Logging wird die Bibliothek
isy-logging
verwendet. -
Es wird ein Debug-, Info- und ein Error-Log geführt. Die Zuordnung der Log-Levels auf diese Log-Arten wird im Dokument Konzept Logging definiert. Ebenso welche Informationen mit welchem Log-Level ausgeben werden sollen.
-
Für das Logging wird die im Rahmen der IsyFact erstellten Layouts für Entwicklung und Produktion verwendet.
-
In jeder Log-Meldung ist eine Correlation-ID mitzuloggen. Diese identifiziert den Aufruf über die Anwendungslandschaft hinweg.
6.1.2. Realisierung
6.1.2.1. Implementierung von Log-Ausgaben
Log-Ausgaben können an beliebigen Stellen im Code erzeugt werden. Dazu wird in jeder Klasse ein eigener Logger erzeugt (Listing 12).
public class MyClass {
...
private static final IsyLoggerStandard LOG = IsyLoggerFactory.getLogger(MyClass.class);
...
Der IsyLoggerStandard
ist dabei für technisches Logging gedacht.
Je nach Anwendungsszenario sind andere spezifische Logger (IsyLoggerFachdaten
, IsyLoggerTypisiert
) zu verwenden.
Wichtig ist, in der Exception-Fassade an der Service-Schnittstelle (siehe Kapitel Klassendesign) die Correlation-ID zu setzen:
public class ServiceSchnittstelleExceptionFassade {
@StelltLoggingKontextBereit
public Object serviceMethode(AufrufKontext kontext, Parameter serviceParameter) {
// ...
}
}
6.1.2.2. Einbinden der Bibliotheken
Um die Logging Funktionen in der eigenen Anwendung nutzen zu können müssen die in Listing 13 aufgelisteten Bibliotheken eingebunden werden.
<dependencies>
...
<dependency>
<groupId>de.bund.bva.isyfact</groupId>
<artifactId>isy-logging</artifactId>
</dependency>
...
</dependencies>
Dadurch wird die Bibliothek isy-logging
sowie Logback als verwendetes Produkt automatisch in die Anwendung integriert.
6.2. Konfiguration
In diesem Kapitel wird die Verarbeitung von Konfigurationen in Anwendungen beschrieben.
6.2.1. Designvorgaben
-
Für die Konfiguration werden betriebliche, statische und Benutzerkonfigurationen unterschieden. Eine Definition und Kriterien zur Typisierung können in Konzept Konfiguration nachgelesen werden.
-
Die betriebliche Konfiguration wird in
/src/main/resources/config/application.properties
abgelegt. -
Statische Konfigurationen werden als Datei in
/src/main/resources/resources
abgelegt. -
Benutzerkonfigurationen werden in der Datenbank abgelegt.
-
Betriebliche Konfigurationen können in Ausnahmefällen zur Laufzeit aktualisiert werden.
-
Für das Laden von betrieblichen Konfigurationen werden
@ConfigurationProperties
-Klassen verwendet.
6.2.2. Realisierung
6.2.2.1. Auslesen von Konfigurationsparametern in der Anwendung
Für den Zugriff auf Konfigurationsparameter in application.properties
werden Klassen erstellt, die beim Start
der Anwendung mit den Werten aus application.properties
befüllt werden.
Der Zugriff auf diese Klassen ist typsicher und die Werte können zusätzlich mit Bean Validierung überprüft werden.
Zur Verwendung in den Komponenten der Anwendung oder zur Konfiguration von Spring Beans werden diese Klassen per
Dependency Injection verfügbar gemacht.
Details zur Implementierung siehe Konzept Konfiguration.
6.3. Fehlerbehandlung
In diesem Kapitel wird beschrieben, wie die Fehlerbehandlung durchzuführen ist.
6.3.1. Designvorgaben
-
In jeder Anwendung bzw. Bibliothek wird eine eigene Exception-Hierarchie angelegt.
-
Für Anwendungs-Exceptions wird die oberste Exception dieser Hierarchie von den in der Bibliothek
isy-exception-core
enthaltenen Exception-Klassen abgeleitet. Diese Ober-Exceptions sind als abstrakt zu kennzeichnen. -
Für Exceptions in selbst entwickelten Bibliotheken werden nicht die Exception-Klassen aus
isy-exception-core
verwendet. Die zugrundeliegenden Designprinzipien sind jedoch identisch umzusetzen. So wird für jede Bibliothek eine abstrakte Ober-Exception angelegt. Diese sorgt für das Laden der Nachrichten, erbt aber direkt von einer derjava.lang.Exception
bzw.java.lang.RuntimeException
. -
Fehlertexte werden in Resource-Bundles ausgelagert und über eine Fehler-ID identifiziert. Die Schlüssel der Fehler-IDs werden in einer Konstantenklasse zusammengefasst.
-
Exceptions werden grundsätzlich nur zur Signalisierung abnormer Ergebnisse bzw. Situationen eingesetzt.
-
Exceptions sind in der Regel zu behandeln und zu loggen. Ist es nicht möglich die Exception zu behandeln, muss sie an den Aufrufer weitergegeben werden. Die Exception wird im Fall eines Weiterwerfens nicht geloggt.
-
Nur Exceptions in Methodensignaturen verwenden, die auch vorkommen können.
-
Bei der Behandlung von Fehlern ist ein geordneter Systemzustand herzustellen, z. B. das Schließen der Datenbankverbindung über einen
finally
-Block. -
Fehler sollten möglichst früh erkannt werden und zu entsprechenden Ausnahmen führen.
-
Interne Exceptions dürfen in der Service-Schnittstelle nicht vorkommen.
-
Catch-Blöcke dienen der Fehlerbehandlung und dürfen nicht als
else
-Zweige genutzt werden. -
Keine leeren Catch-Blöcke.
-
Das destruktive Wrappen einer Exception zerstört den StackTrace und ist nur für Exceptions an den Außen-Schnittstellen sinnvoll. Destruktiv gewrappte Exceptions sind in jedem Fall vor dem Wrappen zu loggen.
Weitere Hinweise für die richtige Behandlung von Fehlern sind in Konzept Fehlerbehandlung enthalten.
6.3.2. Paketstruktur
Exceptions die querschnittlich, also von mehreren Komponenten genutzt werden, werden im Paket:
<organisation>.<domäne>.<anwendung>.common.exception
<organisation> z.B. bva.bund.de
|
implementiert. Komponentenspezifische Exceptions, also solche die nur von einer einzigen Komponente genutzt werden, gehören in das Paket:
<organisation>.<domäne>.<anwendung>.core.<komponente>
6.3.3. Realisierung
Die Bibliothek ist in zwei Teile aufgeteilt: isy-exception-core
und isy-exception-sst
.
Das Core-Paket enthält anwendungsinterne Exception-Klassen und Hilfsklassen für das Exception-Mapping.
Im Schnittstellen-Projekt sind die Klassen für die Transport-Exceptions enthalten.
Wenn das Core-Paket eingebunden wird, wird über Maven automatisch das Schnittstellen-Projekt mit eingebunden.
Die explizite Einbindung von isy-exception-sst
sollte dann entfernt werden.
Die Core-Bibliothek wird im Wesentlichen im Anwendungskern bzw.
der Service-Schnittstellen-Implementierung benötigt
(siehe Bibliotheken für die Implementierung der Service-Schnittstelle). Für Service-Schnittstellen
werden lediglich die Transport-Exceptions aus isy-exception-sst
benötigt
(siehe Kapitel Bibliotheken für das Service-Schnittstellen-Projekt).
6.3.3.1. Einbinden der Bibliothek
Zur Realisierung der Fehlerbehandlung und Implementierung von Exceptions müssen die in Listing 14 aufgelisteten Bibliotheken eingebunden werden.
<dependencies>
...
<dependency>
<groupId>de.bund.bva.isyfact</groupId>
<artifactId>isy-exception-core</artifactId>
</dependency>
<dependency>
<groupId>de.bund.bva.isyfact</groupId>
<artifactId>isy-util</artifactId>
</dependency>
...
</dependencies>
isy-exception-core
enthält abstrakte Exception-Klassen die in Anwendungen zu verwenden sind.
isy-util
enthält Hilfsklassen zum Laden von Fehlertexten.
6.3.3.2. Anlegen der Exception-Klassen
In jeder Anwendung wird für jede Exception-Art (technisch, fachlich) eine eigene Oberklasse angelegt.
Diese erbt von der entsprechenden Klasse aus isy-exception-core
. Zum Laden der
Fehlertexte wird das Interface FehlertextProvider aus derselben Bibliothek verwendet.
In isy-util
ist die Implementierung MessageSourceFehlertextProvider
enthalten.
Diese unterstützt das Laden von Fehlertexten aus einer Spring-Message-Source.
6.3.3.3. Fehlerbehandlung an der Anwendungsschnittstelle
Fehler sind entweder zu behandeln und zu loggen oder weiterzuwerfen. Es muss jedoch sichergestellt werden, dass interne Fehler der Anwendung nicht über die System-Schnittstelle (siehe Anbieten von Service-Schnittstellen) geworfen werden. Dazu wird in der Exception-Fassade eine explizite Fehlerbehandlung mit einem Catch-Throwable-Block durchgeführt.
Alle Exceptions der Anwendungen werden hier in Transport-Exceptions umgewandelt. Dazu wird das im Folgenden beschrieben Muster verwendet.
Es wird ein Catch-Block für alle auftretenden eigenen Exceptions angelegt.
In jedem Catch-Block wird die Exception geloggt und über ExceptionMapper.mapException()
in eine passende Transport-Exception umgewandelt.
Als Letztes wird ein Catch-Throwable-Block eingefügt.
Hier wird für die aufgetretene Exception über ExceptionMapper.createToException()
eine neue Transport-Exception erzeugt.
Zur Ermittlung der Fehler-ID wird eine Klasse AusnahmeIdUtil angelegt.
Diese implementiert eine statische Methode getAusnahmeId
, die zu einer übergebenen Exception
eine passende Fehler-ID ermittelt.
Vor dem Werfen der so erzeugten Exception über die Schnittstelle wird ein Log-Eintrag erzeugt.
Beim Umwandeln der internen Exceptions in Transport-Exceptions wird der Stack-Trace der internen Exceptions verworfen.
6.4. Aufrufkontextverwaltung
Einige Komponenten der Anwendung, z.B. die Protokollierung oder die Autorisierung benötigen
Kontextinformationen über den Aufrufer.
Damit diese nicht durch die gesamte Anwendung gereicht werden müssen, kann in der Anwendung
ein AufrufKontextVerwalter
verwendet werden.
6.4.1. Designvorgaben
-
Die Komponente wird so implementiert, dass sie spezifische Informationen über den Aufrufkontext speichern kann (z.B. Name des aufrufenden Benutzers).
-
Die Komponente kann in einer Anwendung so erweitert werden, dass sie beliebige weitere Kontext-Informationen aufnehmen kann.
6.4.2. Realisierung
6.4.2.1. Einbinden der Bibliothek
Zur Realisierung des Aufrufkontextes müssen die in Listing 15 aufgelisteten Bibliotheken eingebunden werden.
Einbindung der Bibliotheken zur Nutzung des Aufrufkontextes
<dependencies>
...
<dependency>
<groupId>de.bund.bva.isyfact</groupId>
<artifactId>isy-aufrufkontext</artifactId>
</dependency>
...
</dependencies>
Die Bibliothek isy-aufrufkontext
enthält die Komponente AufrufKontextVerwalter
, welcher den benutzerspezifischen Aufrufkontext im Thread-Scope (alternativ Request-Scope) hält.
6.4.2.2. Konfiguration der Bibliothek
Die Komponente AufrufKontextVerwalter
wird als Spring-Bean konfiguriert.
Dabei wird festgelegt, dass Spring eine neue Instanz für jeden Thread (alternativ Request) anlegen soll:
@Bean
@Scope(value="request", proxyMode = ScopedProxyMode.TARGET_CLASS)
public AufrufKontextVerwalter aufrufKontextVerwalter(){
return new AufrufKontextVerwalterImpl();
}
Die Scopes thread und request werden mit dem Einbinden der Bibliothek isy-sicherheit registriert.
|
Der vom AufrufKontextVerwalter verwaltete AufrufKontext wird beim Aufruf der Anwendung in der Service-Schnittstelle oder im Controller der GUI gesetzt und steht fortan, während der Verarbeitung des Requests, in der gesamten Anwendung zur Verfügung.
Komponenten, die diese Informationen benötigen, erhalten dazu einfach eine Referenz auf den AufrufKontextVerwalter
per Dependency Injection.
Zur Entgegennahme des Aufrufkontextes an der Service-Schnittstelle wird die Annotation @StelltAufrufKontextBereit
verwendet.
Die Konfiguration ist im Dokument Nutzungsvorgaben Sicherheit beschrieben.
6.5. Authentifizierung und Autorisierung
Dieses Kapitel beschreibt die Realisierung der Authentifizierung und Autorisierung von Anfragen.
6.5.1. Designvorgaben
-
Die Authentifizierung von Anfragen wird im Servicegateway und im Portal mithilfe des IAM-Services durchgeführt.
-
Prozesse, die innerhalb des Anwendungssystems oder der Anwendungslandschaft starten (z.B. Timertasks, Batches) verwenden einen technischen Benutzer und authentifizieren diesen selbständig gegen den IAM-Service.
-
Die Berechtigungsprüfung ist in der Anwendung deklarativ zu definieren bzw. zu programmieren.
-
Eine erste Berechtigungsprüfung erfolgt in der Service-Schnittstelle oder im Web-GUI-Dialogcontroller jeder Anwendung. Es wird geprüft, ob der Aufrufer den Service oder den Dialog überhaupt verwenden darf.
-
In jeder Service-Methode wird ein Parameter
AufrufKontext
mit den Daten des aufrufenden Benutzers übermittelt. Dieser Parameter wird imAufrufKontextVerwalter
hinterlegt und beim Aufruf weiterer Nachbarsysteme durchgereicht. -
In der Web-GUI wird ein vom IAM-Service bereitgestellter HTTP-Header mit den Daten des aufrufenden Benutzers entgegengenommen und in einen
AufrufKontext
gewandelt. Dieser Parameter wird imAufrufKontextVerwalter
hinterlegt und beim Aufruf weiterer Nachbarsysteme durchgereicht.
6.5.2. Realisierung
6.5.2.1. Einbinden der Bibliothek
Zur Realisierung der Autorisierung müssen die in Listing 17 aufgelisteten Bibliotheken eingebunden werden.
<dependencies>
...
<dependency>
<groupId>de.bund.bva.isyfact</groupId>
<artifactId>isy-sicherheit</artifactId>
</dependency>
<dependency>
<groupId>de.bund.bva.isyfact</groupId>
<artifactId>isy-serviceapi-sst</artifactId>
</dependency>
...
</dependencies>
Die Bibliothek isy-sicherheit
enthält die Komponenten Sicherheit
und BerechtigungsManager
.
Die Bibliothek isy-serviceapi-sst
enthält das Transportobjekt AufrufKontextTo
, das zur Übermittlung der Authentifizierungsdaten über Schnittstellenaufrufe benutzt wird.
Zusätzlich wird als Abhängigkeit der AufrufKontextVerwalter
(siehe Aufrufkontextverwaltung) benötigt,
der die Informationen zum Aufrufer kennt.
6.5.2.2. Konfiguration der Sicherheitskomponente
Die Komponente Sicherheit wird als Spring-Bean in einer Konfigurationsklasse konfiguriert.
Die einer Rolle zugeordneten Rechte werden in der Datei /src/main/resources/resources/rollenrechte.xml
konfiguriert.
6.5.2.3. Prüfen der Berechtigung
Die Berechtigungsprüfung erfolgt in der Regel vor der fachlichen Verarbeitung in der Service-Schnittstelle oder im Dialog-Controller einer Anwendung. Dies erfolgt über Annotationen oder im Webflow (siehe Nutzungsvorgaben Sicherheit). Es kann auch jederzeit auf das Bean Sicherheit zugegriffen werden, um einen Berechtigungsmanager zu verwenden.
Berechtigungsmanager manager = sicherheit.getBerechtigungsManager();
manager.pruefeRecht(RechteSchluessel.RECHT_MELDEN);
Über die Methoden des Berechtigungsmanagers (z.B. hatRecht
, pruefeRecht
) kann die Anwendung
die Autorisierung durchführen.
6.6. Überwachung
In diesem Abschnitt wird beschrieben, wie die Überwachung einer Anwendung realisiert wird.
Detaillierte Informationen zur Überwachung sind im Dokument Konzept Überwachung und in Nutzungsvorgaben Überwachung enthalten. |
6.6.1. Designvorgaben
-
Die Erreichbarkeit des Systems wird über einen HealthCheck von Spring Boot Actuator realisiert.
-
Server-Metriken werden anbieterneutral mit Micrometer angeboten.
-
Einzelne Services können detailliert überwacht werden. Dazu stellen die Services Statistiken über ihre Nutzung als Metriken bereit.
-
Zur Steuerung des Loadbalancing ist ein Servlet enthalten, um die Anwendung innerhalb eines Clusters deaktivierbar zu machen.
6.6.2. Realisierung
6.6.2.1. Einbinden der Bibliothek
Zur Realisierung der Überwachung muss die in Listing 18 aufgelistete Bibliothek eingebunden werden.
<dependencies>
...
<dependency>
<groupId>de.bund.bva.isyfact</groupId>
<artifactId>isy-ueberwachung</artifactId>
</dependency>
...
</dependencies>
6.6.2.2. Konfiguration der Überwachungsschnittstelle
Der HealthCheck, die Server-Metriken und das Loadbalancing Servlet werden automatisch durch die Verwendung der Bibliothek in die Anwendung eingebunden und aktiviert. Für den HealthCheck muss explizit eine Konfiguration in den Application Properties erfolgen, damit der Health-Status automatisch aktualisiert wird.
Die im Detail zu überwachenden Services müssen explizit konfiguriert werden. Dazu werden die Service-Beans in Service-Statistik-Beans gekapselt, und jeder Service-Aufruf wird durch die Service-Statistik-Beans delegiert. Die Konfiguration besteht aus zwei Teilen:
-
Konfigurieren der Service-Statistik-Beans als Spring Beans.
-
Anbinden der Service-Statistik-Beans an die Service-Beans durch einen AOP-Advice. Dieser Advice wird so konfiguriert, dass bei jedem Aufruf einer Methode der Service-Bean die Statistik-Bean aufgerufen wird.