raimund@716: Lada-Server raimund@716: =========== raimund@716: Die Software bietet Funktionalität zur Erfassung und Bearbeitung raimund@716: von Messdaten. Sowie der Planung der Messungen. raimund@716: raimund@716: Weitere Informationen finden sich auf der Projektwebseite unter raimund@716: der Adresse: https://wald.intevation.org/projects/lada/ raimund@716: raimund@716: Die Software entstand im Rahmen einer Software Entwicklung durch die raimund@716: Intevation GmbH im Auftrag des Bundesamt für Strahlenschutz in den Jahren 2013 raimund@716: bis 2015. raimund@716: raimund@716: Kontakt raimund@716: ------- raimund@716: Bundesamt für Strahlenschutz raimund@716: SW2 Notfallschutz, Zentralstelle des Bundes (ZdB) raimund@716: Willy-Brandt-Strasse 5 raimund@716: 38226 Salzgitter raimund@716: info@bfs.de raimund@716: raimund@716: Lizenz raimund@716: ------ raimund@716: Die Software ist unter der GNU GPL v>=3 Lizenz verfügbar. raimund@716: Details siehe die Datei `COPYING`. raimund@716: raimund@716: Quelltext raimund@716: --------- raimund@716: Die Quelldateien lassen sich wie folgt auschecken: raimund@716: ``` raimund@716: hg clone https://scm.wald.intevation.org/hg/lada/lada-server raimund@716: ``` raimund@716: raimund@716: Entwicklung raimund@716: ----------- raimund@716: Für die Entwicklung wird ein JDK7 und maven3 oder höher benötigt. Sämtliche raimund@716: Abhängigkeiten werden von dem maven build System aufgelöst. raimund@716: raimund@716: Installation raimund@716: ------------ tom@750: Die Installation des Lada-Servers erfolgt in einem Wildfly-Application-Server tom@750: (http://wildfly.org). Dazu müssen folgende Schritte unternommen werden: raimund@716: raimund@716: $ mvn clean compile package tom@750: $ mv target/lada-server-$VERSION.war $JBOSS_HOME/standalone/deployments tom@750: $ touch $JBOSS_HOME/standalone/deployments/lada-server-$VERSION.war.dodeploy raimund@716: tom@750: $JBOSS_HOME ist hierbei durch den Pfad zur Wildfly-Installation zu ersetzen, tom@750: $VERSION durch die aktuelle Versionsbezeichnung (entsprechend der Angabe in tom@750: pom.xml). raimund@716: tom@750: Zum Aktualisieren der Anwendung genügt es, das WAR-Archiv zu aktualisieren. tom@750: tom@750: Die Anwendung ist dann unter dem Pfad "/lada-server-$VERSION" erreichbar. raimund@716: tom@782: Um zu garantieren, dass die von den REST-Schnittstellen ausgelieferten tom@782: Zeitstempel sich korrekt auf UTC beziehen, muss die entsprechende System- tom@782: Property `user.timezone=UTC` vor dem Start des Application-Servers gesetzt tom@782: werden (siehe `wildfly/standalone.conf`). tom@782: tom@784: Das PostgreSQL-Datenbank-Backend des Lada-Servers kann als Nutzer `postgres` tom@784: (bzw. als PostgreSQL-Superuser) mit dem Skript `db_schema/setup-db.sh` tom@784: eingerichtet werden. tom@784: tom@784: Details zur Installation können den Dateien `Dockerfile` und tom@784: `db_schema/Dockerfile` entnommen werden. tom@784: tom@1210: Docker tom@1210: ------ tom@1210: Um schnell und automatisiert ein Entwicklungs-Setup für LADA aufsetzen zu tom@1210: können, werden Dockerfiles mitgeliefert. Voraussetzung für die Anwendung ist tom@1210: eine Docker-Installation. Folgendes Vorgehen führt zu einem tom@1210: Vollständigen Setup inklusive LADA-Client, in dem jeweils der auf dem Host tom@1210: vorhandene Quellcode in die Container gemounted wird, so dass auf dem Host tom@1210: durchgeführte Änderungen leicht innerhalb der Container getestet werden können. tom@1210: tom@1210: Bauen der Images: tom@1210: $ cd ./db_schema tom@1210: $ docker build -t koala/lada_db . tom@1210: $ cd .. tom@1210: $ docker build -t koala/lada_wildfly . tom@1210: $ cd your/repo/of/lada-client tom@1210: $ docker build -t koala/lada_client . tom@1210: tom@1210: Aufbau eines Netzwerks für die LADA-Komponenten: tom@1210: $ docker network create lada_network tom@1210: tom@1210: Starten der Container: tom@1210: $ cd db_schema tom@1210: $ docker run --name your_lada_db --net=lada_network -v $PWD:/opt/lada_sql/ \ tom@1210: -d koala/lada_db:latest tom@1210: $ cd .. tom@1210: $ docker run --name lada_wildfly --net=lada_network \ tom@1210: --link your_lada_db:lada_db -v $PWD:/usr/src/lada-server \ tom@1210: -d koala/lada_wildfly tom@1210: $ cd your/repo/of/lada-client tom@1210: $ docker run --name lada_client --net=lada_network \ tom@1210: -v $PWD:/var/www/html/ \ tom@1210: --link lada_wildfly:lada-server \ tom@1210: -p 8180-8184:80-84 -d koala/lada_client tom@1210: tom@1210: Die LADA-Anwendung kann dann unter den angegebenen Ports mit verschiedenen tom@1210: Rollen im Browser ausgeführt werden. tom@1210: raimund@716: Tests raimund@716: ----- raimund@716: Die auf Arquillian basierenden Tests erfordern einen vollständig konfigurierten raimund@716: und gestarteten Wildfly Application-Server, da für die Schnittstellentest eine raimund@716: Clientanwendung simuliert wird und HTTP-Requests ausgeführt werden. raimund@716: raimund@716: Das Ausführen der Tests erfolgt durch das Kommando raimund@716: raimund@716: $ mvn -Premote-test clean test raimund@716: tom@977: und benötigt eine leere Datenbank, die z.B. mit tom@977: tom@977: $ ./setup-db.sh -cn tom@977: tom@977: angelegt werden kann. tom@977: raimund@716: Dokumenation raimund@716: ------------ raimund@716: Die Entwicklerdokumentation (Javadoc) kann mit dem folgenden Befehl im raimund@716: Verzeichnis der Serveranwendung erzeugt werden: raimund@716: raimund@716: $ mvn javadoc:javadoc raimund@716: raimund@716: Der Ordner 'target' enthält dann die Dokumentation im HTML-Format in dem raimund@716: Verzeichnis 'site/apidocs'. raimund@985: tom@1093: Erstellen von Queries raimund@985: --------------------- tom@1093: Queries können als SQL-Statement in der Tabelle stammdaten.queries definiert tom@1093: werden. Eine Filterung kann über Variablen erfolgen, die in stammdaten.filter tom@1093: definiert werden müssen und mittels SQL-Interpolation im SQL-Statement tom@1093: verwendet werden können. tom@1093: Um neue Queries für die Suche von Proben, Messungen und Messprogrammen zu raimund@985: erstellen sind die folgenden Schritte erforderlich: raimund@985: raimund@985: 1. In der Tabelle 'stammdaten.query' einen neuen Eintrag erzeugen. raimund@985: * id: Primary-Key (wird generiert) tom@1093: * name: Der Name der Query raimund@985: * type: Der Datentyp der gefiltert werden soll. tom@1093: (mögliche Werte siehe Datenbank-Schema-Definition) raimund@985: * sql: Das auszuführende SQL-Statement (siehe #Regeln für die Syntax) raimund@985: * description: Ein beschreibender Text raimund@985: raimund@985: 2. In der Tabelle 'stammdaten.result' für die anzuzeigenden Felder je einen raimund@985: Eintrag erzeugen: raimund@985: * id: Primary-Key (wird generiert) raimund@985: * query_id: ID der zugehörigen und in Schritt 1. erzeugten Query raimund@985: * data_index: Name des Feldes zur Übertragung an den Client (in CamelCase) raimund@985: * header: Der Titel der Spalte für diesen Eintrag raimund@985: * width: Die Spaltenbreite (in Pixel) raimund@985: * flex: Dynamische Spaltenbreite (true/false) raimund@985: * index: Der Datenindex raimund@985: tom@1093: 3. In der Tabelle 'stammdaten.filter' für jeden Parameter in der 'WHERE'-Clause tom@1093: der Query einen Eintrag erzeugen: raimund@985: * id: Primary-Key (wird generiert) raimund@985: * query_id: ID der zugehörigen und in Schritt 1. erzeugten Query raimund@985: * data_index: Der Name der Variablen, die in dem 'WHERE'-Statement ersetzt raimund@985: werden soll raimund@985: * type: Datenbasis, die im Client als Eingabe genutzt werden soll tom@1093: (mögliche Werte siehe Datenbank-Schema-Definition) raimund@985: * label: Der angezeigte Name des Filters raimund@985: * multiselect: Mehrfachangabe von Werten für diesen Filter (true/false) raimund@985: raimund@985: ### Regeln raimund@985: raimund@985: * Bei Queries vom Typ `probe` muss das erste selektierte Feld `probe.id` sein. raimund@985: Dieses wird in der Oberfläche nicht angezeigt. tom@1093: * Bei Queries vom Typ `messung` muss das erste selektierte Feld `messung.id` tom@1093: und das zweite `probe.id` sein. Diese werden in der Oberfläche nicht tom@1093: angezeigt. Für `probe.id` muss in stammdaten.result ein Eintrag mit tom@1093: `data_index = 'probeId'` angelegt werden (obwohl diese Spalte nicht angezeigt tom@1093: wird). Um im Client die Funktionalität zu erhalten, sollten Messungsfilter tom@1093: die beiden Felder `probe.hauptproben_nr` und `messung.nebenproben_nr` tom@1093: enthalten. raimund@985: * Bei Queries vom Typ `messprogramm` muss das erste selektierte Feld raimund@985: `messprogramm.id` sein. Dieses wird in der Oberfläche nicht angezeigt. tom@1093: * Werden bei einem JOIN Spalten gleichen Namens aus verschiedenen Tabellen tom@1093: in der SELECT-Clause verwendet, so müssen diese mit einem expliziten Alias tom@1093: versehen werden, um eine tom@1093: org.hibernate.loader.custom.NonUniqueDiscoveredSqlAliasException zu tom@1093: vermeiden. raimund@985: * Im `WHERE`-Statement genutzte Variablen müssen in der Form `:variablenName` raimund@985: angegeben werden und dem Feld `data_index` im zugehörigen Filter entsprechen. tom@1093: * Wenn ein Filter mit `multiselect = true` angegeben wird, so wird in der tom@1093: `WHERE`-Clause ein `SIMILAR TO` erwartet. raimund@985: * Das Feld `index` in der Tabelle `stammdaten.result` dient zur Zuordnung des raimund@985: selektierten Datenfeldes zu dem Entsprechenden Eintrag in der Tabelle raimund@985: `stammdaten.result`. Beispiel: raimund@985: ``` raimund@985: 'SELECT probe.id, probe.mst_id AS mstId, probe.hauptproben_nr AS hpNr, ...' raimund@985: |----- index 1 -----| |--------- index 2 --------| raimund@985: Wird in der Tabelle 'stammdaten.result' zu: raimund@985: Result 1: raimund@985: ... raimund@985: data_index: mstId raimund@985: header: Messstelle raimund@985: width: 100 raimund@985: flex: false raimund@985: index: 1 raimund@985: ... raimund@985: Result 2: raimund@985: ... raimund@985: data_index: hpNr raimund@985: header: Hauptproben Nr raimund@985: width: 150 raimund@985: flex: false raimund@985: index: 2 raimund@985: .... raimund@985: ``` raimund@990: * Queries für Stammdaten werden gesondert behandelt und beinhalten keine raimund@985: SQL-Statements. Dementsprechend können auch keine Einträge für Ergebnisse in raimund@985: der Tabelle `stammdaten.result` gemacht werden. Filter können allerdings, raimund@990: unter der Bedingung, dass `data_index` auf einen in dem Datentyp vorhandenes raimund@990: und in CamelCase geschriebenes Datenfeld zeigt, angelegt werden. raimund@990: Momentan sind Queries für die folgenden Stammdaten möglich: raimund@985: * Orte raimund@985: * Probennehmer raimund@985: * Datensatzerzeuger raimund@985: * Messprogrammkategorien