GSB 7.0 Standardlösung

Mandantenentwicklung

Dieses Dokument beschreibt die Einrichtung einer Entwicklungsumgebung für die Entwicklung eines Mandantenprojektes und skizziert den Aufbau eines Mandantenprojektes am Beispiel der Standardlösung.

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 und adminportal 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 Ordner build/distributions
  • Der Task installDist erstellt das Release in entpackter Form im Ordner build/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());

    }

  }

}

1Kennzeichnung als Spring-Bean
2Erweiterung des Basis-Performers
3Setzen des Mandantennamens
4Methode 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;

  }

}
1Kennzeichnung als Spring-Configuration
2REST-basierte Konfiguration des Newsletters
3Referenz auf Bean newsletterPoster - Klasse die den Versand an die Schnittstelle ausführt
4Im Maildistributor vorhandene Newsletter-Liste
5Templates für die Erzeugung der HTML- und Plain-Varianten des Newsletters
6Im MailDistributor konfiguriertes Attribut für das Mailformat
7Attributwerte für die Formate HTML und TEXT/PLAIN
8Im MailDistributor konfiguriertes Attribut für das Thema
9Konfiguration der Versandprüfung. Es wird nur dann der Versand ausgelöst, wenn im vorliegenden Dokument der Schalter (cl2Categories-EMail) auf "Ja" gestellt worden ist.
10Name der Property 'cl2Categories' und es LinkClassifiers 'EMail'
11Name der Property im referenzierten Dokument, die für die Prüfung (Ja/Nein) verwendet wird
12Property-Wert der den Newsletterversand auslöst
13Konfiguration des rest-basierten Newsletter-Performers
14Name des Mandanten
15Liste mit Events, bei denen der Performer aufgerufen werden soll
16Angabe des Pfads unter dem Dokumente für den Versand berücksichtigt werden sollen
17Angabe welche Dokumenttypen für den Versand berücksichtigt werden sollen
18Name der Benutzer/Gruppen, die für den Versand autorisiert sein sollen
19Konfiguration des E-Mail-Betreffs
20Konfiguation 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 Datei conf 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)

1Variable 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>

1Definition des Macros mit dem Namen <CUSTOMER_NAME>MeinErstesMacro. Das Macro erwartet ein Argument und speichert es in die Variable %(customer).
2Exemplarischer Aufruf eines zweiten Macros mit den Parametern %(customer) und ${VAR1}.
3Standard-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>

1VHost-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
2Setzen der Direktiven ServerName und ServerAlias. Die hier verwendeten Variablen werden im Mandanten in standardlsg_variables.conf gesetzt
3Aufruf des Macros activateStdLogging mit dem Parameter standardlsg. Das Macro beinhaltet die Access-Log Konfiguration des Apaches für den übergebenen Mandanten
4Aufruf des Macros disableRequestMethodsPreview. Das Macro deaktiviert bestimmte HTTP-Methoden, die in der Preview nicht benötigt werden
5Aufruf des Macros enableDeflate. Das Macro konfiguriert das Apache-Modul mod_deflate, das eine Kompression der Server-Antwort ermöglicht
6Aufruf des Macros enableStaticContent mit dem Parameter standardlsg. Das Macro setzt Regeln, die einen Zugriff auf den static-Bereich im Apache ermöglichen
7Aufruf des Macros httpsSupport. Das Macro ermöglicht, durch Setzen bestimmter Regeln, die Auslieferung mittels https
8Aufruf 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)

  }

}

1Erweiterung des Basis-Mappers
2Wird bei der Indizierung von Dokumenten aufgerufen
3Wird 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;

  }

}

1Erweiterung des Basis-Indexers
2Wird 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;

  }

1Kennzeichnung als Spring-Configuration
2Referenz auf die Basis-Properties
3Instanziierung des Indexers
4Aktivierung des Indexers
5Setzen der Url zum Solr-Core
6Setzen der Referenz auf den ContentMapper
7Setzen der Solr-Property 'source'
8Setzen der zu berücksichtigenden Verzeichnisse
9Angabe ob Ordner indiziert werden sollen
10Angabe ob Rechte indiziert werden sollen
11Angabe ob Rechte auf geschützte Bereiche indiziert werden sollen
12Setzen des Mandanten
13Angabe welche Dokumenttypen zu einer Reindizierung der Referrer-Dokumente führen.
14Angabe welche Dokumenttypen bei der Indizierung berücksichtigt werden sollen
15Instanziierung des ContentMappers
16Angabe welche cl2-Properties indiziert werden sollen
17Angabe 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)

1Setzt den ContentType und den Zeichensatz einer JSP-Datei auf text/html und utf-8
2Bindet die Datei startTemplate.jinc ein, die einige initiale Schritte durchführt und Objekte, die im Kontext des Templates genutzt werden können, bereitstellt
3Darstellung der Daten des Dokuments in HTML-Form
4Bindet 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.