Tiamat ist das Haltestellenregister. Es wird landesweit in Norwegen und an anderen Orten verwendet. Tiamat wird mit Technologien wie Spring Boot, Hibernate, Postgis, Jersey und Jackson erstellt.
Unterstützt den Export von Haltestellen und anderen Entitäten in das Format http://netex-cen.eu/. Für den Export gibt es viele Möglichkeiten:
Tiamat bietet eine umfangreiche GraphQL-API für Haltestellen, topografische Orte, Wegverbindungen, Tarifzonen usw. und unterstützt dieselben Parameter wie die NeTEx-Export-API. Es unterstützt auch Mutationen. So können Sie Entitäten aktualisieren oder erstellen. Es gibt auch Graphql-Prozesse (benannte Funktionen), die Funktionen wie das Zusammenführen von Kais oder Haltestellen ermöglichen.
Ein Frontend für Tiamat ist verfügbar. Sein Name ist Abzu. Siehe https://github.com/entur/abzu
Tiamat verwendet das Hazelcast-Speichergitter, um mit anderen Instanzen in Kubernetes zu kommunizieren. Das bedeutet, dass Sie mehrere Instanzen ausführen können.
Nach dem Importieren von Haltestellen und dem Zuweisen neuer IDs zu Haltestellen speichert Tiamat die alten IDs in einer Zuordnungstabelle. Die Zuordnungstabelle zwischen alten und neuen IDs ist über die GraphQL-API und einen REST-Endpunkt verfügbar.
Tiamat unterstützt das Nachschlagen und Ausfüllen von Referenzen zu Tarifgebieten und topografischen Orten aus Polygonübereinstimmungen beim Speichern eines Haltestellenorts.
Haltestellen und andere Entitäten werden versioniert. Das bedeutet, dass Sie den vollständigen Versionsverlauf der Haltestellen und die Person haben, die diese Änderungen vorgenommen hat. Tiamat enthält auch ein Diff-Tool. Dies wird verwendet, um den Unterschied zwischen zwei Versionen einer Haltestelle (oder einer anderen Entität) zu vergleichen und anzuzeigen.
mvn clean install
Sie benötigen das Verzeichnis /deployments/data
mit Rechten für den Benutzer, der den Build durchführt.
Tiamat verwendet Testcontainer, um Integrationstests mit einer echten Datenbank durchzuführen. Um Testcontainers-basierte Tests auszuführen, benötigen Sie eine Docker-API-kompatible Containerlaufzeit. Weitere Informationen finden Sie unter https://www.testcontainers.org/supported_docker_environment/
(Standardprofile werden in application.properties festgelegt)
Um Tiamat mit Docker Compose auszuführen, benötigen Sie eine docker-compose.yml-Datei. Im Docker-Compose-Ordner finden Sie eine compose.yml-Datei:
docker compose up
Dadurch wird Tiamat mit PostgreSQL und Hazelcast gestartet. und Sie können auf Tiamat unter http://localhost:1888 und auf die Datenbank unter http://localhost:5433 und auf graphiql unter http://localhost:8777/services/stop_places/graphql zugreifen. Beim Start kopiert Tiamat das leere Schema in das Datenbank. Federeigenschaften werden in application.properties festgelegt. Die Sicherheit ist in diesem Setup deaktiviert.
Zur Ausführung mit PostgreSQL benötigen Sie eine externe application.properties. Unten finden Sie ein Beispiel für application.properties:
spring.jpa.database=POSTGRESQL
spring.datasource.platform=postgres
spring.jpa.properties.hibernate.hbm2ddl.import_files_sql_extractor=org.hibernate.tool.hbm2ddl.MultipleLinesSqlCommandExtractor
spring.jpa.hibernate.hbm2ddl.import_files_sql_extractor=org.hibernate.tool.hbm2ddl.MultipleLinesSqlCommandExtractor
spring.jpa.hibernate.ddl-auto=none
spring.http.gzip.enabled=true
#spring.jpa.properties.hibernate.format_sql=true
spring.jpa.properties.hibernate.order_updates=true
spring.jpa.properties.hibernate.batch_versioned_data=true
spring.flyway.enabled=true
spring.flyway.table =schema_version
server.compression.mime-types=application/json,application/xml,text/html,text/xml,text/plain
spring.jpa.hibernate.id.new_generator_mappings=true
spring.jpa.hibernate.use-new-id-generator-mappings=true
spring.jpa.properties.hibernate.cache.use_second_level_cache=false
spring.jpa.properties.hibernate.cache.use_query_cache=false
spring.jpa.properties.hibernate.cache.use_minimal_puts=false
spring.jpa.properties.hibernate.cache.region.factory_class=org.rutebanken.tiamat.hazelcast.TiamatHazelcastCacheRegionFactory
netex.import.enabled.types=MERGE,INITIAL,ID_MATCH,MATCH
hazelcast.performance.monitoring.enabled=true
hazelcast.performance.monitoring.delay.seconds=2
management.endpoints.web.exposure.include=info,env,metrics
management.endpoints.prometheus.enabled=true
management.metrics.endpoint.export.prometheus.enabled=true
spring.jpa.properties.hibernate.jdbc.batch_size=20
spring.jpa.properties.hibernate.default_batch_fetch_size=16
spring.jpa.properties.hibernate.generate_statistics=false
changelog.publish.enabled=false
jettyMaxThreads=10
jettyMinThreads=1
spring.datasource.hikari.maximumPoolSize=40
spring.datasource.hikari.leakDetectionThreshold=30000
tiamat.locals.language.default=eng
tariffZoneLookupService.resetReferences=true
debug=true
# Disable feature detection by this undocumented parameter. Check the org.hibernate.engine.jdbc.internal.JdbcServiceImpl.configure method for more details.
spring.jpa.properties.hibernate.temp.use_jdbc_metadata_defaults = false
# Because detection is disabled you have to set correct dialect by hand.
spring.jpa.database-platform=org.hibernate.dialect.PostgreSQL9Dialect
tariffzoneLookupService.resetReferences=true
spring.jpa.properties.hibernate.dialect=org.hibernate.spatial.dialect.postgis.PostgisDialect
spring.database.driverClassName=org.postgresql.Driver
spring.datasource.url=jdbc:postgresql://localhost:5436/tiamat
spring.datasource.username=tiamat
spring.datasource.password=tiamat
#OAuth2 Resource Server
spring.security.oauth2.resourceserver.jwt.issuer-uri=https:http://localhost:8082/realms/entur
tiamat.oauth2.resourceserver.auth0.ror.jwt.audience=abzu
tiamat.oauth2.resourceserver.auth0.ror.claim.namespace=role_assignments
spring.cloud.gcp.pubsub.enabled=false
aspect.enabled=true
netex.id.valid.prefix.list={TopographicPlace:{'KVE','WOF','OSM','ENT','LAN'},TariffZone:{'*'},FareZone:{'*'},GroupOfTariffZones:{'*'}}
server.port=1888
blobstore.gcs.blob.path=exports
blobstore.gcs.bucket.name=tiamat-test
blobstore.gcs.credential.path=gcloud-storage.json
blobstore.gcs.project.id=carbon-1287
security.basic.enabled=false
management.security.enabled=false
authorization.enabled = true
rutebanken.kubernetes.enabled=false
async.export.path=/tmp
publicationDeliveryUnmarshaller.validateAgainstSchema=false
publicationDeliveryStreamingOutput.validateAgainstSchema=false
netex.validPrefix=NSR
netex.profile.version=1.12:NO-NeTEx-stops:1.4
blobstore.local.folder=/tmp/local-gcs-storage/tiamat/export
spring.profiles.active=local-blobstore,activemq
Um Tiamat mit dieser Konfiguration zu starten, geben Sie spring.config.location an:
java -jar -Dspring.config.location=/path/to/tiamat.properties --add-opens java.base/java.lang=ALL-UNNAMED -Denv=dev tiamat-0.0.2-SNAPSHOT.jar
Tiamat verwendet HikariCP. Die meisten Eigenschaften sollten in application.properties angegeben werden können, z. B. spring.datasource.initializationFailFast=false
. Weitere Informationen hier. https://github.com/brettwooldridge/HikariCP/wiki/Configuration Siehe auch http://stackoverflow.com/a/26514779
docker run -it -d -p 5435:5432 --name postgress-13 -e POSTGRES_USER=tiamat -e POSTGRES_PASSWORD="tiamat" -e POSTGRES_INITDB_ARGS="-d" postgis/postgis:13-master
Bei der Implementierung von Tiamat war es wünschenswert, NeTEx-IDs für Haltestellen mehr oder weniger lückenlos zu erstellen. Der Grund für diese Implementierung waren Altsysteme mit Einschränkungen hinsichtlich der maximalen Ziffernzahl.
Es kann gesteuert werden, ob IDs außerhalb von Tiamat generiert werden sollen oder nicht. Siehe die Klasse ValidPrefixList. Durch Festlegen der Eigenschaft netex.validPrefix
wird Tiamat angewiesen, IDs für neue Entitäten zu generieren. Bitte beachten Sie, dass ein mehrfacher Erstimport (siehe ImportType) mit denselben IDs nicht möglich ist.
Alles wird von einem mit PrePersist
annotierten Entity-Listener für die Klasse IdentifiedEntity
namens IdentifiedEntityListener
initiiert. NetexIdAssigner
bestimmt, ob die Entität bereits eine ID hat oder nicht. NetexIdProvider
gibt entweder eine neue ID zurück oder verarbeitet explizit beanspruchte IDs, wenn das konfigurierte Präfix übereinstimmt. Informationen zur Konfiguration gültiger Präfixe und Präfixe für an anderer Stelle generierte IDs finden Sie unter ValidPrefixList
. Der GaplessIdGeneratorService
verwendet Hazelcast, um den Status zwischen Instanzen zu synchronisieren und Konflikte zu vermeiden.
Sowohl Tiamat als auch Abzu sind für die Verwendung mit Keycloak oder Auth0 eingerichtet. Eine detaillierte Anleitung zur Einrichtung von Keycloak finden Sie hier.
Es ist möglich zu konfigurieren, ob Tiamat eingehende und ausgehende NeTEx-XML beim Unmarshalling oder Marshalling von Veröffentlichungslieferungen validieren soll. Standardwerte sind wahr. Kann deaktiviert werden, indem die Eigenschaften auf „false“ gesetzt werden.
publicationDeliveryStreamingOutput.validateAgainstSchema=false
publicationDeliveryUnmarshaller.validateAgainstSchema=true
Es ist möglich, Haltestellen und topografische Orte direkt in das NeTEx-Format zu exportieren. Dies ist der Endpunkt: https://api.dev.entur.io/stop-places/v1/netex
https://api.dev.entur.io/stop-places/v1/netex?q=Arne%20Garborgs%20vei
https://api.dev.entur.io/stop-places/v1/netex?q=3115
https://api.dev.entur.io/stop-places/v1/netex?stopPlaceType=RAIL_STATION
Es ist auch mit mehreren Typen möglich.
https://api.dev.entur.io/stop-places/v1/netex?municipalityReference=KVE:TopographicPlace:1003
https://api.dev.entur.io/stop-places/v1/netex?countyReference=KVE:TopographicPlace:11
https://api.dev.entur.io/stop-places/v1/netex?size=1000
https://api.dev.entur.io/stop-places/v1/netex?page=1
Sie können eine Liste der zurückzugebenden NSR-Haltestellen-IDs angeben
https://api.dev.entur.io/stop-places/v1/netex?idList=NSR:StopPlace:3378&idList=NSR:StopPlace:123
allVersions
. Akzeptable Werte sind wahr oder falsch. Wenn auf „true“ gesetzt, werden alle Versionen übereinstimmender Haltestellen zurückgegeben. Wenn auf „false“ gesetzt, wird für übereinstimmende Haltestellen die höchste Version nach Nummer zurückgegeben. Dieser Parameter ist nicht aktiviert, wenn der Versionsgültigkeitsparameter verwendet wird.
Nur Stopporte ohne Standort abgleichen. Verwenden Sie den Parameter: withoutLocationOnly=true
Der Parameter topographicPlaceExportMode
kann auf NONE , RELEVANT oder ALL gesetzt werden. Relevante topografische Orte werden aus der exportierten Liste der Haltestellen gefunden.
Der Parameter tariffZoneExportMode
kann auf NONE , RELEVANT oder ALL gesetzt werden. Relevante Tarifzonen werden aus der exportierten Liste der Haltestellen gefunden. Weil Haltestellen eine Liste von Tarifzonenreferenzen haben können.
Der Parameter groupOfStopPlacesExportMode
kann auf NONE , RELEVANT oder ALL gesetzt werden. Die relevante Gruppe von Haltestellen kann aus der exportierten Liste der Haltestellen gefunden werden.
Der Parameter versionValidity
steuert, welche Stopporte zurückgegeben werden sollen.
https://api.dev.entur.io/stop-places/v1/netex?tariffZoneExportMode=RELEVANT&topographicPlaceExportMode=RELEVANT&groupOfStopPlacesExportMode=NONE&q=Nesbru&versionValidity=CURRENT&municipalityReference=KVE:TopographicPlace:0220
Gibt Haltestellenorte mit aktueller Versionsgültigkeit zurück, die mit der Abfrage „Nesbru“ übereinstimmen und in der Gemeinde 0220 vorhanden sind. Ruft relevante Tarifzonen und topografische Orte ab.
Beim asynchronen Export werden exportierte Daten in den Google Cloud-Speicher hochgeladen. Bei der Initiierung erhalten Sie eine Job-ID zurück. Wenn der Auftrag abgeschlossen ist, können Sie die exportierten Daten herunterladen.
Die meisten Parameter des synchronen Exports funktionieren auch beim asynchronen Export!
curl https://api.dev.entur.io/stop-places/v1/netex/export/initiate
Profi-Tipp: Leiten Sie die Ausgabe von Curl an xmllint weiter, um die Ausgabe zu formatieren:
curl https://api.dev.entur.io/stop-places/v1/netex/export/initiate | xmllint --format -
curl https://api.dev.entur.io/stop-places/v1/netex/export
curl https://api.dev.entur.io/stop-places/v1/netex/export/130116/content | zcat | xmllint --format - > export.xml
Siehe auch https://rutebanken.atlassian.net/browse/NRP-924
Vorhandene Daten in Postgresql bereinigen (bei häufiger Verwendung optimieren):
TRUNCATE stop_place CASCADE;
TRUNCATE quay CASCADE;
TRUNCATE topographic_place CASCADE;
Wenn Sie dies über spring:run
ausführen, müssen Sie sicherstellen, dass genügend Speicher für den Java-Prozess verfügbar ist (bei großen Datensätzen). Ein weiteres Problem ist die Thread-Stack-Größe, die möglicherweise erhöht werden muss, wenn wirklich große NeTEx-Importe verarbeitet werden. Beispiel:
export MAVEN_OPTS='-Xms256m -Xmx1712m -Xss256m -XX:NewSize=64m -XX:MaxNewSize=128m -Dfile.encoding=UTF-8'
Diese NeTEx-Datei sollte keine NSR-ID enthalten. (Das NSR-Präfix ist in der Klasse ValidPrefixList konfigurierbar)
Tiamat gibt die geänderte NeTEx-Struktur mit seinen eigenen NSR-IDs zurück. Die Original-IDs sind in der Schlüsselwertliste jedes Objekts vorhanden.
curl -XPOST -H"Content-Type: application/xml" [email protected] http://localhost:1997/services/stop_places/netex
Beim Importieren mit importType=INITIAL wird ein paralleler Stream erstellt, der den ursprünglichen Prozess erzeugt. Beim Import werden Benutzerberechtigungen überprüft und somit auf SecurityContextHolder zugegriffen. Standardmäßig verwendet SecurityContextHolder DEFAULT_LOCAL_STRATEGY. Wenn Sie INITIAL importType verwenden, sollten Sie Spring anweisen, MODE_INHERITABLETHREADLOCAL für SecurityContextHolder zu verwenden, damit Spring den Sicherheitskontext in erzeugten Threads duplizieren kann. Dies kann durch Festlegen der Umgebungsvariablen erfolgen:
-Dspring.security.strategy=MODE_INHERITABLETHREADLOCAL
Wenn nicht, beschwert sich die Anwendung möglicherweise darüber, dass der Benutzer nicht authentifiziert wird, wenn Spring versucht, die Autorisierung in einem erzeugten Prozess zu überprüfen
Der GraphQL-Endpunkt ist verfügbar unter
https://api.dev.entur.io/stop-places/v1/graphql
Tipp: Die GraphiQL-Benutzeroberfläche ist unter https://api.dev.entur.io/graphql-explorer/stop-places mit GraphiQL verfügbar: https://github.com/graphql/graphiql (Verwenden Sie z. B. Modify Headers
for Chrome, um Träger hinzuzufügen. Token für Mutationen)
Um die Datenbank für Tiamat zu erstellen, laden Sie das Flyway-Befehlszeilentool herunter und verwenden Sie es: https://flywaydb.org/documentation/commandline/
Migrationen werden beim Start von tiamat ausgeführt.
Erstellen Sie eine neue Datei gemäß der Flyway-Dokumentation im Ordner resources/db/migrations
. Führen Sie die Migration zusammen mit den Codeänderungen durch, die diese Schemaänderung erfordern. Befolgen Sie die Namenskonvention.
Verschiedene Anfragen und Skripte im Zusammenhang mit Tiamat wurden hier gesammelt: https://github.com/entur/tiamat-scripts
Tiamat wird mit CircleCI erstellt. Siehe den .circleci-Ordner.