Tiamat est le registre des lieux d'arrêt. Il est utilisé à l’échelle nationale en Norvège et ailleurs. Tiamat est créé avec des technologies comme Spring Boot, Hibernate, Postgis, Jersey et Jackson.
Prend en charge l'exportation des lieux d'arrêt et d'autres entités au format http://netex-cen.eu/. Il existe de nombreuses options pour les exportations :
Tiamat fournit une riche API GraphQL pour les arrêts, les lieux topographiques, les liens de chemin, les zones tarifaires, etc., prend en charge les mêmes paramètres que l'API d'exportation NeTEx. Il prend également en charge les mutations. Vous pouvez donc mettre à jour ou créer des entités. Il existe également des processus graphql (fonctions nommées) qui permettent des fonctionnalités telles que la fusion de quais ou de lieux d'arrêt.
Une interface pour Tiamat est disponible. Son nom est Abzu. Voir https://github.com/entur/abzu
Tiamat utilise la grille mémoire Hazelcast pour communiquer avec d'autres instances dans Kubernetes. Cela signifie que vous pouvez exécuter plusieurs instances.
Après avoir importé des lieux d'arrêt et attribué de nouveaux identifiants aux lieux d'arrêt, tiamat conserve les anciens identifiants dans une table de mappage. La table de mappage entre les anciens et les nouveaux ID est disponible via l'API GraphQL et un point de terminaison REST.
Tiamat prend en charge la recherche et le remplissage des références aux zones tarifaires et aux lieux topographiques à partir des correspondances de polygones lors de l'enregistrement d'un lieu d'arrêt.
Les lieux d'arrêt et autres entités sont versionnés. Cela signifie que vous disposez d'un historique complet des versions des lieux d'arrêt et de la personne qui a effectué ces modifications. Tiamat comprend également un outil de comparaison. Ceci est utilisé pour comparer et montrer la différence entre deux versions d'un lieu d'arrêt (ou d'une autre entité).
mvn clean install
Vous avez besoin du répertoire /deployments/data
avec les droits de l'utilisateur qui effectue la build.
Tiamat utilise des conteneurs de tests pour exécuter des tests d'intégration sur une base de données réelle. Pour exécuter des tests basés sur Testcontainers, vous avez besoin d'un environnement d'exécution de conteneur compatible Docker-API. Pour plus de détails, voir https://www.testcontainers.org/supported_docker_environment/
(les profils par défaut sont définis dans application.properties)
Pour exécuter Tiamat avec Docker compose, vous devez disposer d'un fichier docker-compose.yml. Dans le dossier docker-compose, vous trouverez un fichier compose.yml :
docker compose up
Cela démarrera Tiamat avec PostgreSQL et Hazelcast. et vous pouvez accéder à Tiamat sur http://localhost:1888 et à la base de données sur http://localhost:5433 et graphiql sur http://localhost:8777/services/stop_places/graphql. Au démarrage, tiamat copie le schéma vide dans le base de données. Les propriétés Spring sont définies dans application.properties. La sécurité est désactivée dans cette configuration.
Pour exécuter avec PostgreSQL, vous avez besoin d'un fichier application.properties externe. Vous trouverez ci-dessous un exemple de 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
Pour démarrer Tiamat avec cette configuration, spécifiez spring.config.location :
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 utilise HikariCP. La plupart des propriétés devraient pouvoir être spécifiées dans application.properties, comme spring.datasource.initializationFailFast=false
. Plus d'informations ici. https://github.com/brettwooldridge/HikariCP/wiki/Configuration Voir aussi 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
Lors de la mise en œuvre de Tiamat, il était souhaitable de produire des identifiants NeTEx pour les arrêts avec plus ou moins d'espace. La raison de cette implémentation était les systèmes existants avec des restrictions sur le nombre maximum de chiffres.
Il est possible de contrôler si les identifiants doivent être générés en dehors de Tiamat ou non. Voir la classe ValidPrefixList. La définition de la propriété netex.validPrefix
indique à Tiamat de générer des identifiants pour les nouvelles entités. Veuillez noter qu'il n'est pas possible d'effectuer une importation initiale (voir ImportType) plusieurs fois avec les mêmes identifiants.
Tout est initié par un écouteur d'entité annoté avec PrePersist
sur la classe IdentifiedEntity
appelée IdentifiedEntityListener
. NetexIdAssigner
détermine si l'entité possède déjà un identifiant ou non. NetexIdProvider
renvoie un nouvel identifiant ou gère les identifiants explicitement revendiqués si le préfixe configuré correspond. Voir ValidPrefixList
pour la configuration des préfixes valides et des préfixes pour les ID générés ailleurs. Le GaplessIdGeneratorService
utilise Hazelcast pour synchroniser l'état entre les instances et éviter les conflits.
Tiamat et Abzu sont tous deux configurés pour être utilisés avec Keycloak ou Auth0. Un guide détaillé sur la façon de configurer Keycloak peut être trouvé ici.
Il est possible de configurer si tiamat doit valider le XML NeTEx entrant et sortant lors du déclassement ou du rassemblement des livraisons de publications. Les valeurs par défaut sont vraies. Peut être désactivé en définissant les propriétés sur false.
publicationDeliveryStreamingOutput.validateAgainstSchema=false
publicationDeliveryUnmarshaller.validateAgainstSchema=true
Il est possible d'exporter des haltes et des lieux topographiques directement au format NeTEx. Il s'agit du point de terminaison : 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
C’est également possible avec plusieurs types.
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
Vous pouvez spécifier une liste d'ID de lieu d'arrêt NSR à renvoyer
https://api.dev.entur.io/stop-places/v1/netex?idList=NSR:StopPlace:3378&idList=NSR:StopPlace:123
allVersions
. Les valeurs acceptables sont vraies ou fausses. Si la valeur est true, toutes les versions des lieux d'arrêt correspondants seront renvoyées. Si la valeur est false, la version la plus élevée en nombre sera renvoyée pour les lieux d'arrêt correspondants. Ce paramètre n'est pas activé lors de l'utilisation du paramètre de valeur de version.
Ne faire correspondre que les arrêts sans emplacement Utiliser le paramètre : withoutLocationOnly=true
Le paramètre topographicPlaceExportMode
peut être défini sur NONE , RELEVANT ou ALL. Les lieux topographiques pertinents seront trouvés dans la liste exportée des lieux d'arrêt.
Le paramètre tariffZoneExportMode
peut être réglé sur NONE , RELEVANT ou ALL Les zones tarifaires pertinentes peuvent être trouvées dans la liste exportée des points d'arrêt. Parce que les lieux d'arrêt peuvent avoir une liste de références de zones tarifaires.
Le paramètre groupOfStopPlacesExportMode
peut être défini sur NONE , RELEVANT ou ALL. Le groupe de places d'arrêt pertinent peut être trouvé dans la liste des places d'arrêt exportée.
Le paramètre versionValidity
contrôle les endroits d'arrêt à retourner.
https://api.dev.entur.io/stop-places/v1/netex?tariffZoneExportMode=RELEVANT&topographicPlaceExportMode=RELEVANT&groupOfStopPlacesExportMode=NONE&q=Nesbru&versionValidity=CURRENT&municipalityReference=KVE:TopographicPlace:0220
Renvoie les lieux d'arrêt avec la version actuelle valide maintenant, correspondant à la requête « Nesbru » et existant dans la municipalité 0220. Récupère les zones tarifaires et les lieux topographiques pertinents.
L'exportation asynchrone télécharge les données exportées vers le stockage cloud de Google. Une fois lancé, vous recevrez un identifiant de travail. Une fois le travail terminé, vous pouvez télécharger les données exportées.
La plupart des paramètres de l’export synchrone fonctionnent également avec l’export asynchrone !
curl https://api.dev.entur.io/stop-places/v1/netex/export/initiate
Conseil de pro : dirigez la sortie de curl vers xmllint pour formater la sortie :
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
Voir également https://rutebanken.atlassian.net/browse/NRP-924
Nettoyer les données existantes dans postgresql (rationaliser si elles sont fréquemment utilisées) :
TRUNCATE stop_place CASCADE;
TRUNCATE quay CASCADE;
TRUNCATE topographic_place CASCADE;
Si vous l'exécutez à partir de spring:run
, vous devez vous assurer que vous disposez de suffisamment de mémoire disponible pour le processus Java (en cas d'ensembles de données volumineux). Un autre problème est la taille de la pile de threads, qui devra peut-être être augmentée lors de la gestion d'importations NeTEx très volumineuses. Exemple:
export MAVEN_OPTS='-Xms256m -Xmx1712m -Xss256m -XX:NewSize=64m -XX:MaxNewSize=128m -Dfile.encoding=UTF-8'
Ce fichier NeTEx ne doit pas contenir d'ID NSR. (Le préfixe NSR est configurable dans la classe ValidPrefixList)
Tiamat renverra la structure NeTEx modifiée avec ses propres identifiants NSR. Les identifiants d'origine seront présents dans la liste de valeurs clés sur chaque objet.
curl -XPOST -H"Content-Type: application/xml" [email protected] http://localhost:1997/services/stop_places/netex
Lors de l'importation avec importType=INITIAL , un flux parallèle sera créé, générant le processus d'origine. Lors de l'importation, les autorisations des utilisateurs sont vérifiées, accédant ainsi à SecurityContextHolder. Par défaut, SecurityContextHolder utilise DEFAULT_LOCAL_STRATEGY. Lorsque vous utilisez INITIAL importType, vous devez indiquer à Spring d'utiliser MODE_INHERITABLETHREADLOCAL pour SecurityContextHolder, permettant à Spring de dupliquer le contexte de sécurité dans les threads générés. Cela peut être fait en définissant la variable env :
-Dspring.security.strategy=MODE_INHERITABLETHREADLOCAL
Sinon, l'application peut se plaindre du fait que l'utilisateur n'est pas authentifié si Spring tente de vérifier l'autorisation dans un processus généré.
Le point de terminaison GraphQL est disponible sur
https://api.dev.entur.io/stop-places/v1/graphql
Astuce : interface utilisateur GraphiQL disponible sur https://api.dev.entur.io/graphql-explorer/stop-places en utilisant GraphiQL : https://github.com/graphql/graphiql (utilisez par exemple Modify Headers
pour Chrome pour ajouter un support jeton pour les mutations)
Pour créer la base de données pour tiamat, téléchargez et utilisez l'outil de ligne de commande flyway : https://flywaydb.org/documentation/commandline/
Les migrations sont exécutées au démarrage de tiamat.
Créez un nouveau fichier conformément à la documentation de la voie de migration dans le dossier resources/db/migrations
. Validez la migration avec les modifications de code qui nécessitent cette modification de schéma. Suivez la convention de dénomination.
Diverses requêtes et scripts liés à tiamat ont été collectés ici : https://github.com/entur/tiamat-scripts
Tiamat est construit en utilisant CircleCI. Voir le dossier .circleci.