Тиамат — это регистр остановок. Он используется на национальном уровне в Норвегии и других местах. Tiamat создан с использованием таких технологий, как Spring Boot, Hibernate, Postgis, Jersey и Jackson.
Поддерживает экспорт мест остановок и других объектов в формат http://netex-cen.eu/. Вариантов экспорта много:
Tiamat предоставляет богатый API GraphQL для остановочных мест, топографических мест, ссылок на пути, тарифных зон и т. д., поддерживает те же параметры, что и API экспорта NeTEx. Он также поддерживает мутации. Таким образом, вы можете обновлять или создавать сущности. Существуют также процессы Graphql (именованные функции), которые позволяют выполнять такие функции, как объединение причалов или остановок.
Доступен интерфейс для Тиамат. Его зовут Абзу. См. https://github.com/entur/abzu.
Tiamat использует сетку памяти Hazelcast для взаимодействия с другими экземплярами в Kubernetes. Это означает, что вы можете запускать несколько экземпляров.
После импорта остановочных мест и назначения новых идентификаторов остановкам Tiamat сохраняет старые идентификаторы в таблице сопоставления. Таблица сопоставления старых и новых идентификаторов доступна через GraphQL API и конечную точку REST.
Тиамат поддерживает поиск и заполнение ссылок на тарифные зоны и топографические места из совпадений полигонов при сохранении места остановки.
Остановочные места и другие объекты имеют версии. Это означает, что у вас есть полная история версий остановочных мест и того, кто внес эти изменения. Tiamat также включает в себя инструмент сравнения. Это используется для сравнения и отображения разницы между двумя версиями места остановки (или другого объекта).
mvn clean install
Вам нужен каталог /deployments/data
с правами пользователя, выполняющего сборку.
Tiamat использует тест-контейнеры для запуска интеграционных тестов с реальной базой данных. Для запуска тестов на основе Testcontainers вам потребуется среда выполнения контейнера, совместимая с Docker-API. Более подробную информацию см. на странице https://www.testcontainers.org/supported_docker_environment/.
(профили по умолчанию установлены в application.properties)
Чтобы запустить Tiamat с помощью Docker Compose, вам понадобится файл docker-compose.yml. В папке docker-compose вы найдете файл compose.yml:
docker compose up
Это запустит Tiamat с PostgreSQL и Hazelcast. и вы можете получить доступ к Tiamat по адресу http://localhost:1888, к базе данных по адресу http://localhost:5433 и графическому файлу по адресу http://localhost:8777/services/stop_places/graphql. При запуске Tiamat скопируйте пустую схему в база данных. Свойства Spring устанавливаются в application.properties. В этой настройке безопасность отключена.
Для работы с PostgreSQL вам нужен внешний файл application.properties. Ниже приведен пример 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
Чтобы запустить Tiamat с этой конфигурацией, укажите 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
Тиамат использует HikariCP. Большинство свойств должно быть возможным указать в application.properties, например spring.datasource.initializationFailFast=false
. Дополнительная информация здесь. https://github.com/brettwooldridge/HikariCP/wiki/Configuration См. также 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
При внедрении Тиамата было желательно производить NeTEx ID для мест остановок с большим или меньшим зазором. Причиной такой реализации стали устаревшие системы с ограничениями на максимальное количество цифр.
Можно контролировать, должны ли идентификаторы генерироваться вне Тиамата или нет. См. класс ValidPrefixList. Установка свойства netex.validPrefix
сообщает Tiamat генерировать идентификаторы для новых объектов. Обратите внимание, что невозможно выполнить первоначальный импорт (см. ImportType) несколько раз с одними и теми же идентификаторами.
Все это инициируется прослушивателем сущностей, аннотированным PrePersist
в классе IdentifiedEntity
называемом IdentifiedEntityListener
. NetexIdAssigner
определяет, есть ли у объекта идентификатор или нет. NetexIdProvider
либо возвращает новый идентификатор, либо обрабатывает явно заявленные идентификаторы, если настроенный префикс соответствует. См. ValidPrefixList
для настройки допустимых префиксов и префиксов для идентификаторов, созданных где-либо еще. GaplessIdGeneratorService
использует Hazelcast для синхронизации состояния между экземплярами и предотвращения конфликтов.
И Тиамат, и Абзу настроены для использования с Keycloak или Auth0. Подробное руководство по настройке Keycloak можно найти здесь.
Можно настроить, должен ли Tiamat проверять входящий и исходящий XML-файл NeTEx при демаршаллинге или маршаллинге доставки публикаций. Значения по умолчанию верны. Можно деактивировать, установив для свойств значение false.
publicationDeliveryStreamingOutput.validateAgainstSchema=false
publicationDeliveryUnmarshaller.validateAgainstSchema=true
Остановочные и топографические места можно экспортировать непосредственно в формат NeTEX. Это конечная точка: 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
Это также возможно с несколькими типами.
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
Вы можете указать список идентификаторов остановок NSR для возврата.
https://api.dev.entur.io/stop-places/v1/netex?idList=NSR:StopPlace:3378&idList=NSR:StopPlace:123
allVersions
. Приемлемые значения: истина или ложь. Если установлено значение true, будут возвращены все версии совпадающих мест остановки. Если установлено значение false, для соответствующих мест остановки будет возвращена самая высокая версия по номеру. Этот параметр неактивен при использовании параметра действительности версии.
Сопоставлять только остановки без местоположения. Используйте параметр: withoutLocationOnly=true
Параметру topographicPlaceExportMode
можно задать значение NONE , RELEVANT или ALL. Соответствующие топографические места будут найдены из экспортированного списка мест остановок.
Для параметра tariffZoneExportMode
можно установить значение NONE , RELEVANT или ALL. Соответствующие тарифные зоны можно найти из экспортированного списка мест остановок. Потому что остановки могут иметь список рефов тарифных зон.
Для параметра groupOfStopPlacesExportMode
можно установить значение NONE , RELEVANT или ALL. Соответствующую группу остановочных мест можно найти из экспортированного списка остановочных мест.
Параметр versionValidity
управляет местами остановки для возврата.
https://api.dev.entur.io/stop-places/v1/netex?tariffZoneExportMode=RELEVANT&topographicPlaceExportMode=RELEVANT&groupOfStopPlacesExportMode=NONE&q=Nesbru&versionValidity=CURRENT&municipalityReference=KVE:TopographicPlace:0220
Возвращает остановки мест с актуальной текущей версией, соответствующих запросу «Несбру» и существующих в муниципалитете 0220. Выбирает соответствующие тарифные зоны и топографические места.
Асинхронный экспорт загружает экспортированные данные в облачное хранилище Google. После запуска вы получите обратно идентификатор задания. Когда задание будет завершено, вы сможете загрузить экспортированные данные.
Большинство параметров синхронного экспорта работают и при асинхронном экспорте!
curl https://api.dev.entur.io/stop-places/v1/netex/export/initiate
Совет для профессионалов: перенаправьте выходные данные из Curl в xmllint, чтобы отформатировать выходные данные:
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
См. также https://rutebanken.atlassian.net/browse/NRP-924.
Очистите существующие данные в postgresql (упростите, если часто используете):
TRUNCATE stop_place CASCADE;
TRUNCATE quay CASCADE;
TRUNCATE topographic_place CASCADE;
Если вы запускаете это из spring:run
, вам необходимо убедиться, что у вас достаточно памяти для процесса Java (в случае больших наборов данных). Другая проблема — размер стека потоков, который, возможно, придется увеличить при работе с действительно большими импортами NeTEX. Пример:
export MAVEN_OPTS='-Xms256m -Xmx1712m -Xss256m -XX:NewSize=64m -XX:MaxNewSize=128m -Dfile.encoding=UTF-8'
Этот файл NeTEX не должен содержать идентификатор NSR. (Префикс NSR настраивается в классе ValidPrefixList)
Tiamat вернет измененную структуру NeTEx со своими собственными идентификаторами NSR. Исходные идентификаторы будут присутствовать в списке значений ключей для каждого объекта.
curl -XPOST -H"Content-Type: application/xml" [email protected] http://localhost:1997/services/stop_places/netex
При импорте с помощью importType=INITIAL будет создан параллельный поток, порождающий исходный процесс. Во время импорта проверяются авторизации пользователей, таким образом осуществляется доступ к SecurityContextHolder. По умолчанию SecurityContextHolder использует DEFAULT_LOCAL_STRATEGY. При использовании INITIAL importType вы должны указать Spring использовать MODE_INHERITABLETHREADLOCAL для SecurityContextHolder, позволяя Spring дублировать контекст безопасности в создаваемых потоках. Это можно сделать, установив переменную env:
-Dspring.security.strategy=MODE_INHERITABLETHREADLOCAL
В противном случае приложение может жаловаться на то, что пользователь не прошел аутентификацию, если Spring попытается проверить авторизацию в порожденном процессе.
Конечная точка GraphQL доступна на
https://api.dev.entur.io/stop-places/v1/graphql
Совет: пользовательский интерфейс GraphiQL доступен по адресу https://api.dev.entur.io/graphql-explorer/stop-places с использованием GraphiQL : https://github.com/graphql/graphiql (используйте, например, Modify Headers
для Chrome», чтобы добавить токен для мутаций)
Чтобы создать базу данных для тиамата, загрузите и используйте инструмент командной строки Flyway: https://flywaydb.org/documentation/commandline/
Миграции выполняются при запуске tiamat.
Создайте новый файл в соответствии с документацией Flyway в папке resources/db/migrations
. Зафиксируйте миграцию вместе с изменениями кода, требующими этого изменения схемы. Следуйте соглашению об именах.
Различные запросы и скрипты, связанные с тиаматом, собраны здесь: https://github.com/entur/tiamat-scripts
Тиамат построен с использованием CircleCI. См. папку .circleci.