Zielgruppe EntwicklungVersion: GSB10.1Mandantenentwicklung
Dieses Dokument beschreibt die Einrichtung einer Entwicklungsumgebung für die Entwicklung eines Mandantenprojektes und skizziert den Aufbau eines Mandantenprojektes am Beispiel der Standardlösung.
- Vorbereitung
- Versionierung und Release Erstellung
- Deployment in Testumgebung / Produktivumgebung
- Lokales Deployment
- Subprojekte
Grundlage und Ausgangspunkt der Entwicklung bilden die Sourcen eines GSB Mandanten. Hierfür bietet sich der im GSB Release enthaltene Mandant standardlsg
an. Die Sourcen des Mandanten werden als ZIP-Archiv standardlsg-<VERSIONSNR>-git.zip
bereitgestellt, welches das komplette Projekt des Mandanten standardlsg
enthält und damit die ideale Voraussetzung für die Umsetzung eines individuellen Mandanten ist.
Das Mandanten-Projekt ist ein Multi-Module Gradle Projekt.
Das Haupt-Projekt repräsentiert den Mandanten als Ganzes und die einzelnen Sub-Projekte enthalten die mandantenspezifischen Anpassungen für die verschiedenen GSB Komponenten. Die genauen Funktionen der verschiedenen Module wird im Kapitel Subprojekte erläutert.
Vorbereitung
Bevor mit der Entwicklung gestartet werden kann sind einige vorbereitende Schritte notwendig. Diese werden in diesem Kapitel beschrieben.
Benötigte Software
Die folgende Software ist für die Entwicklung eines GSB Mandanten erforderlich und sollte daher als erstes Installiert werden:
- Ein JDK (Version s.a. Systemvoraussetzungen)
- Git
Installation der benötigten Software exemplarisch für CentOS 7
sudo yum install -y git java-11-openjdk
Falls der Mandant lokal gestartet und getestet werden soll, muss zusätzlich noch Folgendes installiert werden:
- Für die Komponente
site
undadminportal
muss ein Tomcat im Verzeichnis/opt/software/tomcat/default
vorliegen. - Apache-Webserver
- Solr (Version s.a. Systemvoraussetzungen)
- Datenbank-Treiber (s.a. Systemvoraussetzungen)
Detaillierte Informationen zur Installation dieser Beistellungen, können der Installationsanleitung entnommen werden.
Einrichtung der Git-Versionierung
Im ersten Schritt, sollte im Projektverzeichnis die Git-Versionierung aktiviert werden:
git initgit checkout -b developgit commit -m "Initialer commit"
Maven-Repository
Standard- und GSB spezifische Bibliotheken werden in einem Maven-Repository benötigt.
Die vom GSB eingesetzten Open-Source Bibliotheken können aus den öffentlichen Maven Repositories unter https://repo1.maven.org/maven2/
oder https://jcenter.bintray.com/
abgerufen werden. Für die GSB-spezifischen Bibliotheken wird ein Maven-Repository in der Datei gsbos-full-<VERSIONSNR>-maven.zip
im Release mit geliefert.
Die öffentlichen Maven Repositories sind bereits im Mandanten-Projekt eingebunden und bedürften keiner weiterer Einrichtung. Das GSB Maven Repository muss allerdings noch für das Projekt verfügbar gemacht werden. Hierfür bieten sich zwei Optionen an:
- Ein lokales Maven Repository auf dem Computer des Entwicklers.
- Ein zentrales Maven Repository auf einem firmeninternen Server.
Beide Optionen werden im Folgenden beschrieben.
Unabhängig von der gewählten Option, muss das GSB Maven Repository in der Datei build.gradle
in die beiden repositories { … }
-Blöcke eingetragen werden.
Lokales Maven Repository
Diese Option bietet sich für Tests oder kleine Projekte bzw. -teams an.
Hierbei muss die gsbos-full-<VERSIONSNR>-maven.zip
einfach nur in einen beliebigen Ordner entpackt werden, welcher dann wiederum im Mandanten-Projekt eingetragen wird. Der Einfachheit halber bietet es sich an, hierfür den Ordner ~/.m2/repository
zu nutzen, da dies der Standardpfad für das lokale Maven Repository ist. Dieser Ordner kann im Projekt dann über die Kurzform mavenLocal()
eingebunden werden:
Einbindung des lokalen Maven Repositories in das Mandanten-Projekt
repositories { // ggf. weitere Maven Repositories mavenLocal()}
Falls das Repository an einem anderen Ort abgelegt wurde kann es über die folgende Syntax eingebunden werden:
Einbindung eines lokalen Maven Repositories mit einem beliebigen Ordnerpfad
repositories { // ggf. weitere Maven Repositories maven { url '/pfad/zum/entpackten/maven/repository' }}
Hinweis: | Weitere Informationen zur Deklaration von Maven-Repositories können der offiziellen Gradle-Dokumentation entnommen werden: https://docs.gradle.org/5.5.1/userguide/declaring_repositories.html |
Zentrales Maven Repository
Diese Option bietet sich für größere Projekte an, an denen mehrere Entwickler arbeiten werden.
Idealerweise ist bereits ein zentraler, firmeninterner Repository-Server auf Basis von bspw. Nexus oder Artifactory vorhanden, in welchen das GSB Maven Repository importiert werden kann.
Für ein Aritfactory ist dieser Import-Vorgang z.B. hier beschrieben: https://www.jfrog.com/confluence/display/RTF/Importing+and+Exporting#ImportingandExporting-Import
Sobald das GSB Maven Repository auf einem zentralen Server zur Verfügung steht, kann dessen URL im Projekt eingetragen werden:
Einbindung eines zentralen Maven Repositories über eine URL
repositories { // ggf. weitere Maven Repositories maven { url 'https://repo.example.com/gsb-libs' }}
Hinweis: | Weitere Informationen zur Deklaration von Maven-Repositories können der offiziellen Gradle-Dokumentation entnommen werden: https://docs.gradle.org/5.5.1/userguide/declaring_repositories.html |
Umbenennung des Mandanten
Im nächsten Schritt muss der Mandant von standardlsg
in seinen tatsächlichen Namen umbenannt werden.
Dazu muss in der Datei settings.gradle
unter rootProject.name
standardlsg
durch den Namen des Mandanten ersetzt werden.
Festschreiben der Änderungen
Im letzten Schritt sollten die gemachten Änderungen mit einem git commit
festgeschrieben werden:
git commit -m "Initiale Einrichtung des Mandanten xyz"
Einrichtung der IDE
Nach der initialen Einrichtung des Projektes, kann dieses nun in der IDE geöffnet werden.
IntelliJ IDEA
Hinweis: | Im Folgenden wird - wenn nicht anders erwähnt - davon ausgegangen, dass die IDE IntelliJ IDEA 2019.1 genutzt wird. Für die Entwicklung des GSB empfiehlt sich die Verwendung von IntelliJ IDEA Ultimate, da der Support für JSP-Templates durch die IDE sehr gut ist und diese üblicherweise auch von externen Dienstleistern oder Selbsthostern eingesetzt wird. |
Das Projekt sollte in IntelliJ als Gradle Projekt importiert werden. Dazu muss einfach die build.gradle
im Hauptordner des Projektes geöffnet werden. IntelliJ sollte diese als Projekt-Datei erkennen und ggf. vorschlagen das Projekt zu importieren.
Hinweis: | Dieses Vorgehen ist auch in der IntellIJ Dokumentation beschrieben: https://www.jetbrains.com/help/idea/2019.1/gradle.html#gradle_import_project_start |
Für eine optimale Integration sollten die IntelliJ Optionen
- "Create separate module per source set"
- "Delegate IDE build/run actions to Gradle"
- "Run tests using" = Gradle
aktiviert, bzw. gesetzt sein.
IntellJ Plugins
Nach dem Import des Projektes wird IntelliJ vorschlagen, weitere Plugins zu installieren bzw. zu aktivieren. Die Liste dieser Plugins stammt aus der Datei .idea/externalDependencies.xml
. Alle entsprechenden Plugins sollten installiert werden.
Andere IDE’s
Da der komplette Build-Prozess in Gradle abgebildet ist, ist es auch möglich eine andere IDE zu benutzen.
Auf der offiziellen Gradle Homepage wird beschrieben, wie Gradle-basierte Projekte in andern IDE’s genutzt werden können.
Da die GSB Projekte intern auf Spring und Lombok basieren, empfiehlt es sich - soweit möglich - die entsprechenden IDE-Unterstützungen zu aktivieren:
- Spring Tools
- Lombok für Eclipse Basierte IDE’s
Versionierung und Release Erstellung
Um die volle Unterstützung des Gradle Builds nutzen zu können, sollte das Projekt mit Git versioniert werden und dabei dem gitflow Workflow folgen.
Insbesondere sollte die Haupt-Entwicklung auf dem develop
-Branch bzw. in feature/*
-Branches erfolgen. Der master
-Branch sollte nur für Releases genutzt werden.
Versionsnummer
Der Gradle Build bestimmt die Versionsnummer automatisch Anhand der in der gradle.properties
festgelegten Version und des Namens des Git-Branches. Dazu ist es notwendig, dass die in oben beschriebenen Branch-Namen genutzt werden (insbesondere master
, develop
und release-*
).
In der Datei gradle.properties
sollte dabei immer die Version eingetragen sein, welche aktuell entwickelt wird.
Erstellung Mandantenrelease
Nach Abschluss der Entwicklungstätigkeiten wird ein Mandantenrelease erstellt, welches dann im Rahmen der Installation auf Test-/Produktivsystemen verwendet wird. Dieses Kapitel beschreibt den Prozess der Erstellung eines Mandantenrelease.
Bei Nutzung des Gitflow-Workflow wird empfohlen, dass aus dem develop-Branch ein release-Branch erstellt wird, in dem nur noch Bugfixes und für das Release wichtige Änderungen committed werden. Nach Fertigstellung des Releases sollte der Release-Stand in den develop- und master-Branch gemerged werden.
In GSB Projekten wird dieser Prozess mit Hilfe von zwei Gradle-Tasks unterstützt.
prepareRelease
Dieser Task erstellt - ausgehend vom develop
-Branch - einen neuen release-*
-Branch. Die Versionen für das Release und die weitere Entwicklung können dabei über Parameter angegeben werden.
prepareRelease
für einen Release Candidate
./gradlew prepareRelease --release-version=42-rc1 --next-version=42
In diesem Beispiel wird während der Entwicklung der Version 42
ein release-*
-Branch für den Release Candidate 42-rc1
erzeugt. Die Version für die weitere Entwicklung bleibt in diesem Fall 42
.
prepareRelease
für ein finales Release
./gradlew prepareRelease --release-version=42 --next-version=42.1
In diesem Beispiel wird am Ende der Entwicklung der Version 42
ein release-*
-Branch für die Version 42
erzeugt. Die Version für die weitere Entwicklung wird auf 42.1
erhöht.
performRelease
Dieser Task finalisiert das mit prepareRelease
vorbereitete Release, in dem es den release-*
-Branch in den master
-Branch merged, die Version mit einem entsprechenden tag versieht, und das Ganze dann wieder in den develop
-Branch merged.
Der Task muss auf dem zu finalisierenden release-*
-Branch gestartet werden.
./gradlew performRelease
Danach kann auf dem master
-Branch das Release - wie im nächsten Kapitel beschrieben - gebaut werden.
Bau des Releases
Der Bau des Mandanten-Releases ist komplett über Gradle automatisiert:
- Der Task
distZip
erstellt das Release als Zip-Datei im Ordnerbuild/distributions
- Der Task
installDist
erstellt das Release in entpackter Form im Ordnerbuild/install
Bei Nutzung des maven-publish
Gradle-Plugins werden zudem automatisch zwei entsprechende Publications mit den Namen gsb
und gsbReports
erstellt. Diese erlauben es das Release über entsprechende publish*
Tasks in einem Maven-Repository abzulegen.
Deployment in Testumgebung / Produktivumgebung
Das Deployment in einer zentralen Test- bzw. Produktivumgebung wird auf Basis der Installationsskripte im GSB 10 Release beschrieben.
Informationen zur Installation und Konfiguration der Komponenten finden sich in der Installationsanleitung.
Lokales Deployment
Die Konfigurationen und Schritte für ein lokales Deployment von GSB Komponenten auf dem Entwicklerarbeitsplatz werden hier beschrieben. Darüber hinaus wird ein dediziertes Unterkapitel für die JSP-Templateentwicklung erstellt, in dem das Vorgehen zur Templateentwicklung erläutert wird.
Nachdem die Projekte in IntelliJ eingerichtet wurden, kann die Software mit Hilfe des folgenden Aufrufs installiert werden:
./gradlew installAll
Die Installation legt Standard-Runtime-Properties unter /opt/gsbos/software/runtime
ab. Anpassungen an den Properties, z.B. das Ändern der Repository-URL, sollten im Verzeichnis /opt/gsbos/runtime
durchgeführt werden. Die Ablagestruktur sollte dabei von den Standard-Runtime-Properties übernommen werden. Desweiteren erstellt die Installationsroutine einmalig systemd-Dateien unter /etc/systemd/system
, die zum Starten der einzelnen Services benötigt werden und installiert die beiden Services 'httpd' und 'site'.
Weitere Hinweise zu den Runtime-Properties finden sich in der Installationsanleitung.
Achtung: | Nach der erstmaligen Installation ist zu prüfen, ob die Datei /opt/gsbos/software/runtime/httpd/conf.d/gsbos.conf korrekt in den Apache eingebunden wurde. Im CentOS wird hierfür ein Link im Verzeichnis /etc/httpd/conf.d erstellt. |
In der Standardlösung sind standardmäßig die Service-Instanzen site und httpd aktiviert. Für das lokale Deployment stehen hier die folgenden Gradle-Tasks zur Verfügung
- installAll - Installiert alle Service-Typen nach '/opt/gsbos/software'
- installSiteService - Installiert den Service-Typ 'site' nach '/opt/gsbos/software/site'
- installHttpdService - Installiert den Service-Typ 'httpd' nach '/opt/gsbos/software/httpd'
- startAll - Startet alle Instanzen der Service-Typen 'httpd' und 'site'
- startSiteServices - Startet alle Instanzen des Service-Typs 'site'
- startHttpdServices - Startet alle Instanzen des Service-Typs 'httpd'
- stopAll - Stoppt alle Instanzen der Service-Typen 'httpd' und 'site'
- stopSiteServices - Stoppt alle Instanzen des Service-Typs 'site'
- stopHttpdServices - Stoppt alle Instanzen des Service-Typs 'httpd'
Bei Änderungen an den Projekten httpd oder site können die Gradle-Tasks installHttpdService, bzw. startSiteServices verwendet werden, um die Komponenten mit dem aktuellen Stand zu installieren.
JSP Template-Entwicklung
Die Installation der Site führt eine Verlinkung der JSP-Templates durch. Dadurch ist ein Rebuild/Restart der Komponente site nach Template-Anpassungen nicht notwendig. Anpassungen an Templates sind direkt nach Neuladen des Browsers sichtbar.
Aktivierung der Service-Typen EventDispatcher und Indexer
In der Datei /standardlsg/build.gradle
können weitere Service-Typen aktiviert werden.
Um bspw. den EventDispatcher lokal zu installieren, muss der folgende Eintrag im Block serviceInstances eingefügt werden:
"eventdispatcher"
{
serviceType = ServiceType.EVENTDISPATCHER
}
Um den Indexer lokal zu installieren, muss der folgende Eintrag im Block serviceInstances eingefügt werden:
"indexer"
{
serviceType = ServiceType.INDEXER
}
Nach Aktivierung der Services werden die zur Verfügung stehenden Tasks automatisch um die Tasks installEventdispatcherService
und installIndexerService
ergänzt.
Subprojekte
Die Sourcen des GSB Mandanten verteilen sich auf verschiedene Subprojekte im Mandanten. Die einzelnen Subprojekte werden vorgestellt sowie die Arbeit mit den Subprojekten wird verdeutlicht. An dieser Stelle werden auch (Internet-) Links zu vorhandenen Dokumentationen der Standardkomponenten (bspw. solr, httpd) im Web aufgeführt, die dann für weiterführende Recherchen genutzt werden können. Das Ziel dieses Kapitels ist es eine fachliche Darstellung eines Subprojektes zu erstellen (bspw. Aufbau/Ablage der httpd-Konfiguration des Mandanten VirtualHost, ggf. Macros).
content
Beinhaltet den Content des Mandanten (in diesem Fall der Standardlösung). Der Content eines Entwicklungssystems kann mit dem Gradle Task downloadContentExport
exportiert und im content Subprojekt abgelegt werden. Der exportierte Content kann bei Bedarf für eine Versionierung im Git-Repository des Mandanten verwendet werden.
Hinweis: | In der Datei content/.gitignore können Pfade und Dateien definiert werden, die durch git ignoriert werden sollen. Hiermit können Testinhalte oder Ordner mit großen Download-Dokumenten o.ä. ausgeschlossen werden. |
static-content
Hier können statische Inhalte wie Schriften oder Bilder hinterlegt werden.
documentation-internal
Das Projekt documentation_internal enthält Dokumentationen zu den einzelnen Komponenten im Format AsciiDoc. An dieser Stelle können projektinterne Dokumentationen erstellt und versioniert werden.
eventdispatcher
Beinhaltet die Erweiterung des EventDispatchers. Es können neue Performer in Form von Spring-Beans implementiert werden, die der EventDispatcher automatisch in das System integriert (s.a. EventDispatcher).
Um einen neuen Performer zu definieren, muss lediglich die Basis-Klasse de.bund.gsb.eventdispatcher.performer.Performer
erweitert und die Methode perform
überschrieben werden. Desweiteren muss bei der Instanziierung, der Name des Mandanten im Konstruktor oder mit Hilfe der Spring-Annotationen preConstruct/postConstruct gesetzt werden.
Im Projekt enthalten ist die Beispiel-Performer-Implementierung StandardlsgPerformer
, die als Basis für eigene Performer verwendet werden kann.
@Component
(1)
public
class
StandardlsgPerformer
extends Performer { (2)
public StandardlsgPerformer() {
setCustomer(
"standardlsg"); (3)
}
private
Logger log = LoggerFactory.getLogger(getClass());
@Override
public
void perform(ContentEvent event) { (4)
if (shouldEventBePerformed(event)) {
log.info(
"Fuehre die Action fuer Mandant '{}' im StandardlsgPerformer aus.", event.getCustomer());
}
else {
log.debug(
"Fuehre die Action fuer Mandant '{}' im StandardlsgPerformer nicht aus.", event.getCustomer());
}
}
}
1 | Kennzeichnung als Spring-Bean |
2 | Erweiterung des Basis-Performers |
3 | Setzen des Mandantennamens |
4 | Methode perform, wird bei jedem Event aufgerufen. Das publizierte Event wird als Argument übergeben |
Die Aktivierung des Standard-Performers de.bund.gsb.eventdispatcher.performer.newsletter.RESTNewsletterPerformer
kann mittels Java-basierter Konfiguration erfolgen. Auch hier wird die Verwendung von Spring-Mitteln empfohlen. Mittels der Annotation @Configuration wird eine Klasse als Quelle für Spring-Beans markiert. In der Klasse können Methoden mit @Bean annotiert werden, um den Methoden-Rückgabewert als Spring-Bean zu instanziieren (s.a. allgemeine Beschreibung Konfiguration).
Im Standardlsg-Projekt eventdispatcher befindet sich eine Spring-Konfiguration, die den Newsletter-Performer aktiviert.
Achtung: | Die nachfolgend beschriebene Java-basierte Konfiguration entspricht der bisherigen Konfiguration des EventDispatchers über XML-Dateien. |
@Configuration
(1)
public
class
StandardlsgConfiguration {
@Autowired
private NewsletterPoster newsletterPoster;
@Bean (2)
public RESTConfigProperties standardlsgRestConfig() {
RESTConfigProperties restConfigProperties =
new RESTConfigProperties();
restConfigProperties.setNewsletterPoster(newsletterPoster); (3)
restConfigProperties.setListName(
"standardlsg_newsletter"); (4)
restConfigProperties.setHtmlTemplateName(
"renderNewsletterHtml"); (5)
restConfigProperties.setPlainTemplateName(
"renderNewsletterPlain"); (5)
restConfigProperties.setFormatAttributeName(
"Format"); (6)
restConfigProperties.setHtmlAttributeValueName(
"HTML"); (7)
restConfigProperties.setPlainAttributeValueName(
"Text"); (7)
restConfigProperties.setTopicAttributeName(
"Themen"); (8)
return restConfigProperties;
}
@Bean (9)
public CL2PropertyCheck standardlsgCheckEmail() {
CL2PropertyCheck standardlsgCheckEmail =
new CL2PropertyCheck();
standardlsgCheckEmail.setFieldName(
"cl2Categories"); (10)
standardlsgCheckEmail.setLinkClassifierTitle(
"EMail"); (10)
standardlsgCheckEmail.setPropertyNameInReferredDoc(
"title"); (11)
standardlsgCheckEmail.setRequiredValue(
"Ja"); (12)
return standardlsgCheckEmail;
}
@Bean (13)
public RESTNewsletterPerformer standardlsgNewsletterPerformer() {
RESTNewsletterPerformer standardlsgNewsletterPerformer =
new RESTNewsletterPerformer();
standardlsgNewsletterPerformer.setCustomer(
"standardlsg"); (14)
standardlsgNewsletterPerformer.setEventsToHandle(
Collections.singleton(
"DocumentPublishedEvent")); (15)
standardlsgNewsletterPerformer.setIncludedPathsRegex(
"/standardlsg/SharedDocs/Newsletter/.*"); (16)
standardlsgNewsletterPerformer.setIncludedDocumentTypes(
Collections.singleton(
"Newsletter")); (17)
standardlsgNewsletterPerformer.setAllowedGroups(
Collections.singleton(
"mandant_standardlsg@standardlsg")); (18)
standardlsgNewsletterPerformer.setAllowedUsers(
Collections.singleton(
"workflow@standardlsg")); (18)
standardlsgNewsletterPerformer.setSubjectsForDocumentTypes(
Collections.singletonMap(
"Newsletter",
"[standardlsg] Newsletter: {title}")); (19)
standardlsgNewsletterPerformer.setCl2ClassifierTitleForTopicValues(
"Themen"); (20)
standardlsgNewsletterPerformer.setCl2PropertyForTopicValues(
"cl2Categories"); (20)
standardlsgNewsletterPerformer.setLinkedDocumentPropertyForTopicValue(
"title"); (20)
standardlsgNewsletterPerformer.setRestConfiguration(standardlsgRestConfig());
return standardlsgNewsletterPerformer;
}
}
1 | Kennzeichnung als Spring-Configuration |
2 | REST-basierte Konfiguration des Newsletters |
3 | Referenz auf Bean newsletterPoster - Klasse die den Versand an die Schnittstelle ausführt |
4 | Im Maildistributor vorhandene Newsletter-Liste |
5 | Templates für die Erzeugung der HTML- und Plain-Varianten des Newsletters |
6 | Im MailDistributor konfiguriertes Attribut für das Mailformat |
7 | Attributwerte für die Formate HTML und TEXT/PLAIN |
8 | Im MailDistributor konfiguriertes Attribut für das Thema |
9 | Konfiguration der Versandprüfung. Es wird nur dann der Versand ausgelöst, wenn im vorliegenden Dokument der Schalter (cl2Categories-EMail) auf "Ja" gestellt worden ist. |
10 | Name der Property 'cl2Categories' und es LinkClassifiers 'EMail' |
11 | Name der Property im referenzierten Dokument, die für die Prüfung (Ja/Nein) verwendet wird |
12 | Property-Wert der den Newsletterversand auslöst |
13 | Konfiguration des rest-basierten Newsletter-Performers |
14 | Name des Mandanten |
15 | Liste mit Events, bei denen der Performer aufgerufen werden soll |
16 | Angabe des Pfads unter dem Dokumente für den Versand berücksichtigt werden sollen |
17 | Angabe welche Dokumenttypen für den Versand berücksichtigt werden sollen |
18 | Name der Benutzer/Gruppen, die für den Versand autorisiert sein sollen |
19 | Konfiguration des E-Mail-Betreffs |
20 | Konfiguation der Property 'Themen' - Mittels der Eingrenzung nach Themen, erhalten die Abonnenten nur E-Mails die zu den bei der Registrierung angegebenen Themen passen (Siehe auch Punkt 8) |
httpd
Das Projekt httpd beinhaltet die VHost-Konfigurationen des Mandanten für die beiden Zonen preview und live. Desweiteren sind hier Variablen für den Mandanten standardlsg definiert, die im Apache-Kontext verwendet werden. Um Konfigurationen zu vereinfachen wird die Makro-Funktion unterstützt, sodass wiederkehrende Konfigurationen in Form von Makros ausgelagert und parametrisiert werden können.
Die Struktur des httpd-Projektes sieht wie folgt aus:
src/main/dist/conf/variables
: Definition der Variablen. Die Dateiconf
beinhaltet die Standard-Variablen für den Mandanten und kann durch weitere Variablen ergänzt werden. Die Variablen sind in den VHost-Konfigurationen und Macros referenzierbar.src/main/dist/conf/vhosts
: VHost-Konfiguration des Mandanten für die Zonen preview und live. Die Zone preview besteht aus den VHost-Konfigurationen für die Standard-Preview, Editor-Preview und die zur Beispielzwecken angelegte Subsite.src/main/dist/conf/macro
: Diese Ablage kann für die eigens definierten Macros dienen. Pro Datei können beliebig viele Macros definiert werden. Die Standardlösung beinhaltet keine eigenen Macros, sodass der Ordner 'macro' im Auslieferungszustand nicht existiert. Der Buildprozess berücksichtigt das Vorhandensein des Ordners und kopiert die Macro-Dateien an die entsprechende Stelle im Installationsverzeichnis.
Eine Variable kann grundsätzlich im Basis-, Mandanten-Kontext oder in der Runtime-Konfiguration definiert werden. Gleichzeitig ist es möglich in gleicher Reihenfolge Variablen zu überschreiben. Eine Variable wird mittels 'Define' definiert.
Define VAR1 VALUE1 (1)
1 | Variable mit dem Namen 'VAR1' und dem Wert 'VALUE1' definiert. |
Macros sind mit Funktionen vergleichbar, an deren Aufruf Argumente übergeben werden können. Der Aufruf des Macros erfolgt mit der vorgesetzten Anweisung 'use' (Beispiel: 'use meinErstesMacro standardlsg').
Die Denition eines Macros kann wie folgt aussehen:
<Macro <CUSTOMER_NAME>_MeinErstesMacro %(customer)> (1)
use <CUSTOMER_NAME>_MeinZweitesMacro %(customer) ${VAR1} (2)
RewriteRule ^(.+) $1?param1=test (3)
</Macro>
1 | Definition des Macros mit dem Namen <CUSTOMER_NAME>MeinErstesMacro. Das Macro erwartet ein Argument und speichert es in die Variable %(customer). |
2 | Exemplarischer Aufruf eines zweiten Macros mit den Parametern %(customer) und ${VAR1}. |
3 | Standard-Regel |
Hinweis: | Um die eindeutige Benennung von Macros sicherzustellen, wird die Nutzung der Mandantenkennung als Präfix für den Macronamen empfohlen |
Für weiterführende Dokumentation zum httpd Macro-Modul wird an dieser Stelle auf die vorhandene Apache httpd-Dokumenation verwiesen (im Beispiel https://httpd.apache.org/docs/2.4/mod/mod_macro.html).
Nachfolgend soll das Zusammenspiel beispielhaft an der VHost-Konfiguration für die Deployment-Location 'preview' verdeutlicht werden:
<VirtualHost *:${HttpPort}> (1)
ServerName ${standardlsg-preview-servername} (2)
ServerAlias ${standardlsg-preview-serveralias} (2)
use activateStdLogging standardlsg (3)
use disableRequestMethodsPreview (4)
use enableDeflate (5)
use enableStaticContent standardlsg (6)
use httpsSupport (7)
use gsbRewritePreview standardlsg (8)
</VirtualHost>
1 | VHost-Konfiguration für die auf Port 80 ankommenden Anfragen. Die Variable ${HttpPort} wird in der Basis definiert, lässt sich genau wie die anderen Variablen im Mandanten überschreiben |
2 | Setzen der Direktiven ServerName und ServerAlias. Die hier verwendeten Variablen werden im Mandanten in standardlsg_variables.conf gesetzt |
3 | Aufruf des Macros activateStdLogging mit dem Parameter standardlsg. Das Macro beinhaltet die Access-Log Konfiguration des Apaches für den übergebenen Mandanten |
4 | Aufruf des Macros disableRequestMethodsPreview. Das Macro deaktiviert bestimmte HTTP-Methoden, die in der Preview nicht benötigt werden |
5 | Aufruf des Macros enableDeflate. Das Macro konfiguriert das Apache-Modul mod_deflate, das eine Kompression der Server-Antwort ermöglicht |
6 | Aufruf des Macros enableStaticContent mit dem Parameter standardlsg. Das Macro setzt Regeln, die einen Zugriff auf den static-Bereich im Apache ermöglichen |
7 | Aufruf des Macros httpsSupport. Das Macro ermöglicht, durch Setzen bestimmter Regeln, die Auslieferung mittels https |
8 | Aufruf der gsbRewritePreview mit dem Parameter standardlsg. Das Macro fügt für die Preview benötigten Standardregeln ein |
indexer
Beinhaltet die Erweiterung des Indexers. Es können u.a. Mandanten-Mapper und Mandanten-Indexer in Form von Spring-Beans implementiert und in das System integriert werden.
Um einen neuen Mapper zu definieren, muss lediglich die Basis-Klasse de.bund.gsb.indexer.mapper.ContentMapper
erweitert und eine der Hook-Methoden, z.B. mapAdditionalProperties
oder mapAdditionalFolderProperties
überschrieben werden.
public
class
ExampleMapper
extends ContentMapper { (1)
@Override
public
void mapAdditionalProperties(
Map<
String,
Object> mapProperties,
Document document) { (2)
}
@Override
public
void mapAdditionalFolderProperties(
Map<
String,
Object> mapProperties, Folder folder) { (3)
}
}
1 | Erweiterung des Basis-Mappers |
2 | Wird bei der Indizierung von Dokumenten aufgerufen |
3 | Wird bei der Indizierung von Ordnern aufgerufen |
Analog dazu kann ein Mandanten-Indexer durch das Erweitern der Basis-Klasse de.bund.gsb.indexer.writer.SolrIndexer
implementiert werden.
public
class
ExampleIndexer
extends SolrIndexer { (1)
@Override
public
boolean shouldIndexDocument(
Document document) { (2)
return
true;
}
}
1 | Erweiterung des Basis-Indexers |
2 | Wird bei der Indizierung von Dokumenten aufgerufen. Entscheidet, ob das Dokument indiziert werden soll |
Im Projekt enthalten ist die Java-basierte Spring-Konfiguration für den Mandanten standardlsg. Neben dem Standard-Mapper/Indexer werden auch die CMIS- und Editor-Varianten instanziiert und abhängig der Runtime-Konfiguration aktiviert.
Achtung: | Die nachfolgend beschriebene Java-basierte Konfiguration entspricht der bisherigen Konfiguration des Indexers über XML-Dateien. |
@Configuration
(1)
public
class
StandardlsgConfiguration {
@Autowired
private IndexerProperties indexerProperties; (2)
@Bean
(3)
public SolrIndexer standardlsgIndexer() {
SolrIndexer indexer =
new SolrIndexer();
indexer.setActive(indexerProperties.isActive()); (4)
indexer.setServerAddress(indexerProperties.getSolr().getUrl() +
"/solr/standardlsg"); (5)
indexer.setContentMapper(standardlsgContentMapper()); (6)
indexer.setSource(
"repository"); (7)
indexer.setIncludedDirectories(
"/standardlsg/.*"); (8)
indexer.setExcludedDirectories(
"/standardlsg/_config/Editor/.*|/standardlsg/__EditorConfig/.*"); (8)
indexer.setIndexingFolder(
false); (9)
indexer.setIndexingRights(
false); (10)
indexer.setIndexingCugRights(
true); (11)
indexer.setCustomer(
"standardlsg"); (12)
indexer.setReindexingDocTypes(indexerProperties.getReindexingDocTypes()); (13)
indexer.setIncludedDocTypes(indexerProperties.getIncludedBaseDocTypes()); (14)
return indexer;
}
@Bean (15)
public ContentMapper standardlsgContentMapper() {
ContentMapper mapper =
new ContentMapper();
mapper.setCl2VirtualProperties(indexerProperties.getCl2VirtualProperties()); (16)
mapper.setBlobPropertiesToIndex(indexerProperties.getBlobPropertiesToIndex()); (17)
return mapper;
}
1 | Kennzeichnung als Spring-Configuration |
2 | Referenz auf die Basis-Properties |
3 | Instanziierung des Indexers |
4 | Aktivierung des Indexers |
5 | Setzen der Url zum Solr-Core |
6 | Setzen der Referenz auf den ContentMapper |
7 | Setzen der Solr-Property 'source' |
8 | Setzen der zu berücksichtigenden Verzeichnisse |
9 | Angabe ob Ordner indiziert werden sollen |
10 | Angabe ob Rechte indiziert werden sollen |
11 | Angabe ob Rechte auf geschützte Bereiche indiziert werden sollen |
12 | Setzen des Mandanten |
13 | Angabe welche Dokumenttypen zu einer Reindizierung der Referrer-Dokumente führen. |
14 | Angabe welche Dokumenttypen bei der Indizierung berücksichtigt werden sollen |
15 | Instanziierung des ContentMappers |
16 | Angabe welche cl2-Properties indiziert werden sollen |
17 | Angabe welche Blob-Proprties indiziert werden sollen |
infrastructure
Hier sind diverse Vorlagen abgelegt, die im Mandanten-Kontext versioniert werden sollten. Dazu zählen die folgenden Definition und Konfigurationen:
*.gsbshell
exemplarische Beispieldateien für die Nutzung der Gsbshell, um z.B. einen Contentimport des Mandanten durchzuführen.etc
Liste der mandantenspezifischen Hostnamen die ggf. in der lokalen Host-Datei eingetragen werden müssen.runtime
Zusammenstellung mandantenspezifischer Runtime-Konfigurationen.security
Gruppen- und Rechtedefinitionen für das Redaktionssystem.
site
In diesem Projekt ist es möglich die site des Mandanten zu erweitern. Denkbar sind Template-Anpassungen, Implementierung von Java-Klassen oder Modifikationen der Spring-Konfiguration.
Templates
Die site ermöglicht die Einbindung von eigenen JSP-Templates, die im folgenden Verzeichnis abgelegt sind src/main/webapp/WEB-INF/templates/customers/<CUSTOMER_NAME>
. Templates für Subsites werden im Verzeichnis src/main/webapp/WEB-INF/templates/customers/<CUSTOMER_NAME>/site/<SUBSITE_NAME>
abgelegt.
Grundsätzlich wird zwischen Basis- und Mandanten-Templates unterschieden, wobei in einem Mandantenprojekt nur die JSP-Templates des Mandanten entwickelt oder angepasst werden.
JSP-Templates kommen in den folgenden Bereichen zum Einsatz
- Navigations-Templates: Darstellung der unterschiedlichen Navigationen (Top, Left, Service)
- Content-Templates: Darstellung der einzelnen Dokumente
- Funktions-Templates: Ausführen von Funktionen, z.B. mittels des Dokumenttyps GenericJSP
Die Templates können für konkrete (z.B. Basepage) oder abstrakte Dokumenttypen (z.B. DocumentEnt) entwickelt werden. Letzteres ermöglicht die Bereitstellung von Templates für mehrere konkrete oder abstrakte Dokumenttypen.
Für die Darstellung eines Dokuments mittels eines Templates, durchsucht das GSB-Framework zunächst den Mandanten-Bereich und geht hier ggf. die Dokumenttyphierarchie hoch. Wenn kein passendes Template gefunden wurde, werden die Basis-Templates durchsucht.
Der Rahmen eines Templates sieht wie folgt aus:
<%@ page contentType="text/html;charset=utf-8" (1)
%><%@ include file="/WEB-INF/templates/startTemplate.jinc" (2)
%>
<%--….. Der Inhalt des Templates …..--%> (3)
<%@ include file="/WEB-INF/templates/endTemplate.jinc"%> (4)
1 | Setzt den ContentType und den Zeichensatz einer JSP-Datei auf text/html und utf-8 |
2 | Bindet die Datei startTemplate.jinc ein, die einige initiale Schritte durchführt und Objekte, die im Kontext des Templates genutzt werden können, bereitstellt |
3 | Darstellung der Daten des Dokuments in HTML-Form |
4 | Bindet die Datei endTemplate.jinc ein, die einige abschliessende Schritte durchführt |
Bei der Entwicklung von JSP-Templates ist es wichtig, dass einige Programmierrichtlinien eingehalten werden.
- Trennung von Darstellungslogik und Businesslogik
- Keine Nutzung von Java Scriptlets
- Zugriff auf GSB Repository immer über Contentbeans
- Zugriff auf Properties und Hilfsobjekte mittels JSP Expression-Language oder Taglibs
Java-Implementierung
Im Verzeichnis src/main/java
ist es möglich die Java-Backend-Implementierung der site zu erweitern.
Unter anderem können die folgenden Bereiche der site erweitert werden
- Content- und PluginBeans
- Data-Klassen für GenericJSPEnt/GenericResultSet
- FormularActions, Validatoren, Formfiller
- RichtextEnhancer durch Implementierung eines RichtextEnhancerPlugins
- Controller durch Implementierung eines ControllerPlugins
- Link-Schema durch Implementierung des LinkSchemeCustomerPlugins
- Datenbankschema-Erweiterung, Anbindung eines weiteren Schemas, Datenbankzugriff
Das Projekt site beinhaltet die Implementierung einer Formular-Action, die als Vorlage für eigene Actions verwendet werden kann. Eine FormularAction muss die Oberklasse de.bund.gsb.site.forms.action.AbstractAction
oder einer der abgeleiteten Basis-Action-Klassen erweitern. Eine Action wird in Dokumenten vom Typ 'HTML-Formular Action' im Feld 'Java-Klasse' referenziert und nach Abschicken des Formulars vom GSB-Framework aufgerufen.
Die im Projekt enthaltene Beispiel-Action ist eine SuchAction, die von der SolrQueryAction abgeleitet ist:
public
class
TestAction
extends SolrQueryAction { (1)
}
Spring-Konfiguration Das Projekt site ermöglicht das Einbinden eigener XML-basierter Spring-Konfiguration. Die Konfiguration wird im Verzeichnis src/main/resources/spring/customers
abgelegt und atutomatisch vom GSB in den Spring-ApplicationContext integriert.
Im Projekt befinden sich aktuell vier Spring-XML-Dateien, die nachfolgend näher erleutert werden sollen.
- standardlsg-cachewarmup.xml - Konfiguration des Cache-Warmups, das Dokumente in den Cache der site lädt, damit sie initial schneller aufrufbar sind
- standardlsg-configuration.xml - Diverse Konfigurationen, wie z.B. die Konfiguration des Pfads zur Standard-Login-Seite
- standardlsg-contentbeans.xml - ContentBean-Erweiterungen können hier registriert werden
- standardlsg-searchbean.xml - Konfiguration der Suche
solr
Hier ist die mandantenspezifische Solr-Konfiguration für die einzelnen Solr-Cores des Mandanten standardlsg abgelegt.
Für weiterführende Informationen wird auf den "Apache Solr Reference Guide" unter https://lucene.apache.org/solr/guide/ verwiesen.
Clonen eines Mandanten
Wenn ein neuer GSB 10 Mandant erstellt wird, dann kann dieser auf Grundlage der Standardlösung angelegt werden. Die Schritte zur Erstellung des neuen Mandanten werden in der Anleitung zum Clonen eines Mandanten beschrieben.
Mandanten-Migration
Die Schritte zur Migration eines GSB 7 Mandanten in einen GSB 10 Mandanten sind in der Migrationsanleitung beschrieben.