diff --git a/.circleci/config.yml b/.circleci/config.yml index c7a3b7bb..55ba4405 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -1,45 +1,18 @@ -version: 2 +version: 2.1 aliases: - - &google-sdk-container-config - docker: - - image: google/cloud-sdk:latest - auth: - username: $DOCKERHUB_LOGIN - password: $DOCKERHUB_PASSWORD - - &GCP-auth-docker - name: GCP authentication with docker - command: | - echo $DOCKER_PASSWORD > ${HOME}/account-auth.json - &jfrog-login name: Rename jfrog environment variable for maven setting.xml command: | echo "export JFROG_USER=$ARTIFACTORY_USER" >> $BASH_ENV echo "export JFROG_PASS=$ARTIFACTORY_PASSWORD" >> $BASH_ENV - - &tag-git-version - name: Tag git commit with build version and push to github + - &post_build + name: Trigger downstream builds command: | - git config --global user.email "circleci@entur.no" - git config --global user.name "circleci" - git tag $VERSION - git push origin $VERSION - - &create-image-version - name: Create new image version and store to env var and as file in workspace - command: | - echo "export VERSION=$CIRCLE_BRANCH-v$CIRCLE_BUILD_NUM-$(echo -n $CIRCLE_SHA1 | tail -c 8)" >> $BASH_ENV - echo "$CIRCLE_BRANCH-v$CIRCLE_BUILD_NUM-$(echo -n $CIRCLE_SHA1 | tail -c 8)" > version - - &read-image-version - name: Read new image version from workspace - command: | - echo "export VERSION=$(cat ./version)" >> $BASH_ENV - - &docker-build-and-push - name: Docker build and push - command: | - IMAGE="eu.gcr.io/entur-system-1287/${CIRCLE_PROJECT_REPONAME}" - echo "Image: ${IMAGE}" - docker build -t $IMAGE . - docker tag $IMAGE "${IMAGE}":"${VERSION}" - docker login -u _json_key --password-stdin https://eu.gcr.io < ${HOME}/account-auth.json - docker push "${IMAGE}":"${VERSION}" + wget https://raw.githubusercontent.com/entur/circleci-toolbox-image-java11/master/tools/trigger_build_v2.sh -O .circleci/trigger_build_v2.sh + chmod +x .circleci/trigger_build_v2.sh + echo 'export CIRCLE_SHA1="$CIRCLE_SHA1"' >> $BASH_ENV + echo 'export CIRCLE_PROJECT_REPONAME="$CIRCLE_PROJECT_REPONAME"' >> $BASH_ENV + .circleci/trigger_build_v2.sh "entur/uttu-deployment-config.git" "master" "$(git log -1 --pretty=%B)" - &sonar-scan name: Sonar scan command: | @@ -55,7 +28,7 @@ aliases: -Dsonar.host.url=https://sonarcloud.io \ -Dsonar.token=${ENTUR_SONAR_PASSWORD} jobs: - build: + test: machine: image: ubuntu-2204:2024.04.3 environment: @@ -94,36 +67,49 @@ jobs: path: ~/junit - store_artifacts: path: ~/junit - - run: *create-image-version - - run: *tag-git-version - persist_to_workspace: root: ~/project paths: - target - - Dockerfile - .circleci - - ./version - deploy-docker: - <<: *google-sdk-container-config + build: + docker: + - image: cimg/openjdk:21.0.2-node + auth: + username: $DOCKERHUB_LOGIN + password: $DOCKERHUB_PASSWORD + environment: + MAVEN_OPTS: -Xmx3G steps: - - setup_remote_docker: - version: default - docker_layer_caching: true - - attach_workspace: - at: ~/project - - run: *GCP-auth-docker - - run: *read-image-version - - run: *docker-build-and-push + - checkout + - restore_cache: + keys: + - dep-cache-v2-{{ checksum "pom.xml" }} + - dep-cache-v2- + - run: + name: Download Maven settings + command: wget https://raw.githubusercontent.com/entur/circleci-toolbox-image-java11/master/tools/m2/settings.xml -O .circleci/settings.xml + - run: *jfrog-login + - run: + name: Refresh cache + command: mvn org.apache.maven.plugins:maven-dependency-plugin:3.1.0:go-offline -s .circleci/settings.xml + - save_cache: + paths: + - ~/.m2 + key: dep-cache-v2-{{ checksum "pom.xml" }} + # Cannot use -o because of snapshot dependencies. + - run: mvn deploy -s .circleci/settings.xml -P prettierSkip -DskipTests + - run: *post_build workflows: - version: 2 - build_test_deploy: + release: jobs: - - build: + - test: context: global - - deploy-docker: + - build: context: global - requires: - - build filters: branches: - only: master + only: + - master + requires: + - test diff --git a/Dockerfile b/Dockerfile deleted file mode 100644 index 02e7a85e..00000000 --- a/Dockerfile +++ /dev/null @@ -1,8 +0,0 @@ -FROM bellsoft/liberica-openjdk-alpine:21.0.3-10 -RUN apk update && apk upgrade && apk add --no-cache \ - tini -WORKDIR /deployments -COPY target/uttu-*-SNAPSHOT.jar uttu.jar -RUN addgroup appuser && adduser --disabled-password appuser --ingroup appuser -USER appuser -CMD [ "/sbin/tini", "--", "java", "-jar", "uttu.jar" ] diff --git a/README.md b/README.md index 2d441bda..168f98df 100644 --- a/README.md +++ b/README.md @@ -30,10 +30,39 @@ provide a NeTEx file of organisations with uttu.organisations.netex-file-uri= -or provide your own implementation of the `OrganisationRegistry` interface +or provide your own implementation of the `OrganisationRegistry` interface –– see `src/main/java/no/entur/uttu/organisation/spi/OrganisationRegistry.java`. -See `src/test/resources/fixtures/organisations.xml` for an example of a NeTEx file with organisations. +Refer to `src/test/resources/fixtures/organisations.xml` for an example of a NeTEx file with organisations. + +## Stop place registry + +Uttu needs a stop place registry in order to allow lookup of stop places from quay refs, used when creating +journey patterns with fixed transit stops, and with hail-and-ride areas. + +You may provide a NeTEx file of stop places with + + uttu.stopplace.netex-file-uri= + +or provide your own implementation of the `StopPlaceRegistry` interface –– +see `src/main/java/no/entur/uttu/stopplace/spi/StopPlaceRegistry.java`. + +Refer to `src/test/resources/fixtures/stopplace.xml` for an example of a NeTEx file with stop places. + +## Optional export notification message + +If you want to notify an external system about a NeTEx file export, you can +provide an implementation of the `MessagingService` interface –– see +`src/main/java/no/entur/uttu/export/messaging/spi/MessagingService.java`. + +The default MessagingService implementation is a noop. + +## Disable Google PubSub autoconfiguration + +If you don't use Google PubSub, sett this property: + + # This property is needed to avoid pubsub autoconfiguration + spring.cloud.gcp.pubsub.enabled=false ## Running locally ### Build diff --git a/api/apiproxy/flexible-lines.xml b/api/apiproxy/flexible-lines.xml deleted file mode 100644 index a4d7daea..00000000 --- a/api/apiproxy/flexible-lines.xml +++ /dev/null @@ -1,36 +0,0 @@ - - - - - flexible-lines - flexible-lines - - assignMessage.addCors - flowCallout.getEnvironmentConfiguration - flowCallout.generalStackdriverLogging - flowCalloutreplaceTargetUrl - spikeArrest - - - flexible-lines-v1 - - - - - - flexible-lines-v1 - - diff --git a/api/apiproxy/policies/assignMessage.addCors.xml b/api/apiproxy/policies/assignMessage.addCors.xml deleted file mode 100644 index ac07e628..00000000 --- a/api/apiproxy/policies/assignMessage.addCors.xml +++ /dev/null @@ -1,31 +0,0 @@ - - - - - assignMessage.addCors - - - - -
*
-
*
-
3628800
-
GET, PUT, POST, DELETE
-
-
- true - -
diff --git a/api/apiproxy/policies/flowCallout.generalStackdriverLogging.xml b/api/apiproxy/policies/flowCallout.generalStackdriverLogging.xml deleted file mode 100644 index e1703aef..00000000 --- a/api/apiproxy/policies/flowCallout.generalStackdriverLogging.xml +++ /dev/null @@ -1,7 +0,0 @@ - - - flowCallout.generalStackdriverLogging - - - generalStackdriverLogging - \ No newline at end of file diff --git a/api/apiproxy/policies/flowCallout.getEnvironmentConfiguration.xml b/api/apiproxy/policies/flowCallout.getEnvironmentConfiguration.xml deleted file mode 100644 index e695faef..00000000 --- a/api/apiproxy/policies/flowCallout.getEnvironmentConfiguration.xml +++ /dev/null @@ -1,22 +0,0 @@ - - - - - flowCallout.getEnvironmentConfiguration - - - fetchEnvironmentConfiguration - diff --git a/api/apiproxy/policies/flowCallout.replaceTargetUrl.xml b/api/apiproxy/policies/flowCallout.replaceTargetUrl.xml deleted file mode 100644 index 9ad4dbef..00000000 --- a/api/apiproxy/policies/flowCallout.replaceTargetUrl.xml +++ /dev/null @@ -1,22 +0,0 @@ - - - - - flowCallout.replaceTargetUrl - - - replaceTargetUrl - diff --git a/api/apiproxy/policies/spikeArrest.xml b/api/apiproxy/policies/spikeArrest.xml deleted file mode 100644 index bce44598..00000000 --- a/api/apiproxy/policies/spikeArrest.xml +++ /dev/null @@ -1,23 +0,0 @@ - - - - - spikeArrest - - - 600pm - false - diff --git a/api/apiproxy/proxies/flexible-lines-v1.xml b/api/apiproxy/proxies/flexible-lines-v1.xml deleted file mode 100644 index e2b414a1..00000000 --- a/api/apiproxy/proxies/flexible-lines-v1.xml +++ /dev/null @@ -1,64 +0,0 @@ - - - - - - - - - - - - - assignMessage.addCors - - - request.verb == "OPTIONS" AND request.header.origin != null AND request.header.Access-Control-Request-Method != null - - - - - - - flowCallout.generalStackdriverLogging - - - - - - - - spikeArrest - - - - flowCallout.getEnvironmentConfiguration - - - - - - /timetable-admin/v1/flexible-lines - - entur - - - request.verb == "OPTIONS" AND request.header.origin != null AND request.header.Access-Control-Request-Method != null - - - flexible-lines-v1 - - diff --git a/api/apiproxy/targets/flexible-lines-v1.xml b/api/apiproxy/targets/flexible-lines-v1.xml deleted file mode 100644 index 9c7b624d..00000000 --- a/api/apiproxy/targets/flexible-lines-v1.xml +++ /dev/null @@ -1,47 +0,0 @@ - - - - - - - - - flowCallout.generalStackdriverLogging - - - - - - - - - - - flowCallout.replaceTargetUrl - - - - - - assignMessage.addCors - - - - - - https://timetable-admin-v1-flexible-lines-gcp2.INGRESS_ENVIRONMENT/services/flexible-lines - - \ No newline at end of file diff --git a/helm/uttu/Chart.lock b/helm/uttu/Chart.lock deleted file mode 100644 index d30894ea..00000000 --- a/helm/uttu/Chart.lock +++ /dev/null @@ -1,6 +0,0 @@ -dependencies: -- name: common - repository: https://entur.github.io/helm-charts - version: 1.17.5 -digest: sha256:548d4b1e40dd575cb2036735ec04bd469d8cea4c4f32e372cf3b9513ee621912 -generated: "2024-01-19T15:17:31.306013614+01:00" diff --git a/helm/uttu/Chart.yaml b/helm/uttu/Chart.yaml deleted file mode 100644 index c82c6888..00000000 --- a/helm/uttu/Chart.yaml +++ /dev/null @@ -1,17 +0,0 @@ -apiVersion: v2 -appVersion: "0.1.80" -description: Backend for flexible transport editor -name: uttu -version: 0.1.0 -keywords: - - uttu -sources: - - https://github.com/entur/uttu -maintainers: - - name: 'team-ror' - email: team.rutedata@entur.org -engine: gotpl -dependencies: - - name: common - version: 1.17.5 - repository: "https://entur.github.io/helm-charts" \ No newline at end of file diff --git a/helm/uttu/charts/common-1.17.5.tgz b/helm/uttu/charts/common-1.17.5.tgz deleted file mode 100644 index 7bf75b4e..00000000 Binary files a/helm/uttu/charts/common-1.17.5.tgz and /dev/null differ diff --git a/helm/uttu/env/values-kub-ent-dev.yaml b/helm/uttu/env/values-kub-ent-dev.yaml deleted file mode 100644 index 1a6f48ff..00000000 --- a/helm/uttu/env/values-kub-ent-dev.yaml +++ /dev/null @@ -1,33 +0,0 @@ -common: - env: dev - deployment: - replicas: 1 - -sql: - instance: ent-uttu-dev:europe-west1:uttu-db-pg13=tcp:5432 - -ingress: - domainName: -gcp2.dev.entur.io - - -configMap: - organisationRegistryUrl: https://api.dev.entur.io/organisations/v1/register/organisations - stopplaceRegistryUrl: https://api.dev.entur.io/stop-places/v1/read - auth0: - ror: - url: https://ror-entur-dev.eu.auth0.com/ - audience: https://ror.api.dev.entur.io - partner: - url: https://partner.dev.entur.org/ - client: - tokenUri: https://partner.dev.entur.org/oauth/token - clientId: 4a5zhKZaENqIl1u0m5blot8sYKVTUIec - orgRegister: - audience: https://api.dev.entur.io - pubsubProjectId: ent-marduk-dev - blobstoreProjectId: ent-marduk-dev - blobstoreContainerName: marduk-exchange-dev - logLevel: DEBUG - flywayTable: schema_version - exportQueueName: FlexibleLinesExportQueue - exportBlobFolder: inbound/uttu/ \ No newline at end of file diff --git a/helm/uttu/env/values-kub-ent-prd.yaml b/helm/uttu/env/values-kub-ent-prd.yaml deleted file mode 100644 index 89e2c0d1..00000000 --- a/helm/uttu/env/values-kub-ent-prd.yaml +++ /dev/null @@ -1,35 +0,0 @@ -common: - env: prd - deployment: - replicas: 2 - container: - forceReplicas: 2 - -sql: - instance: ent-uttu-prd:europe-west1:uttu-db-pg13=tcp:5432 - -ingress: - domainName: -gcp2.entur.io - - -configMap: - organisationRegistryUrl: https://api.entur.io/organisations/v1/register/organisations - stopplaceRegistryUrl: https://api.entur.io/stop-places/v1/read - auth0: - ror: - url: https://auth2.entur.org/ - audience: https://ror.api.entur.io - partner: - url: https://partner.entur.org/ - client: - tokenUri: https://partner.entur.org/oauth/token - clientId: 1ZZMds7c0urOXHAMuklhv2puDcdVUQIW - orgRegister: - audience: https://api.entur.io - pubsubProjectId: ent-marduk-prd - blobstoreProjectId: ent-marduk-prd - blobstoreContainerName: marduk-exchange-production - logLevel: INFO - flywayTable: flyway_schema_history - exportQueueName: FlexibleLinesExportQueue - exportBlobFolder: inbound/uttu/ diff --git a/helm/uttu/env/values-kub-ent-tst.yaml b/helm/uttu/env/values-kub-ent-tst.yaml deleted file mode 100644 index 944d9349..00000000 --- a/helm/uttu/env/values-kub-ent-tst.yaml +++ /dev/null @@ -1,32 +0,0 @@ -common: - env: tst - deployment: - replicas: 1 - -sql: - instance: ent-uttu-tst:europe-west1:uttu-db-pg13=tcp:5432 - -ingress: - domainName: -gcp2.staging.entur.io - -configMap: - organisationRegistryUrl: https://api.staging.entur.io/organisations/v1/register/organisations - stopplaceRegistryUrl: https://api.staging.entur.io/stop-places/v1/read - auth0: - ror: - url: https://ror-entur-staging.eu.auth0.com/ - audience: https://ror.api.staging.entur.io - partner: - url: https://partner.staging.entur.org/ - client: - tokenUri: https://partner.staging.entur.org/oauth/token - clientId: AXXN2zBqjVWKOp2uJGXv44ehaQwkHUJS - orgRegister: - audience: https://api.staging.entur.io - pubsubProjectId: ent-marduk-tst - blobstoreProjectId: ent-marduk-tst - blobstoreContainerName: marduk-exchange-test - logLevel: INFO - flywayTable: flyway_schema_history - exportQueueName: FlexibleLinesExportQueue - exportBlobFolder: inbound/uttu/ diff --git a/helm/uttu/templates/_helpers.tpl b/helm/uttu/templates/_helpers.tpl deleted file mode 100644 index d811ac18..00000000 --- a/helm/uttu/templates/_helpers.tpl +++ /dev/null @@ -1,37 +0,0 @@ -{{/* vim: set filetype=mustache: */}} -{{/* -Expand the name of the chart. -*/}} -{{- define "app.name" -}} -uttu -{{- end -}} - -{{/* -Create a default fully qualified app name. -We truncate at 63 chars because some Kubernetes name fields are limited to this (by the DNS naming spec). -If release name contains chart name it will be used as a full name. -*/}} -{{- define "app.fullname" -}} -{{- if .Values.fullnameOverride -}} -{{- .Values.fullnameOverride | trunc 63 | trimSuffix "-" -}} -{{- else -}} -{{- $name := default .Chart.Name .Values.nameOverride -}} -{{- if contains $name .Release.Name -}} -{{- .Release.Name | trunc 63 | trimSuffix "-" -}} -{{- else -}} -{{- printf "%s-%s" .Release.Name $name | trunc 63 | trimSuffix "-" -}} -{{- end -}} -{{- end -}} -{{- end -}} - - -{{/* Generate basic labels */}} -{{- define "uttu.common.labels" }} -app: {{ template "app.name" . }} -chart: {{ .Chart.Name }}-{{ .Chart.Version | replace "+" "_" }} -release: {{ .Release.Name }} -team: ror -slack: talk-ror -environment: {{ .Values.common.env }} -namespace: {{ .Release.Namespace }} -{{- end }} \ No newline at end of file diff --git a/helm/uttu/templates/configmap.yaml b/helm/uttu/templates/configmap.yaml deleted file mode 100644 index 17a5fa52..00000000 --- a/helm/uttu/templates/configmap.yaml +++ /dev/null @@ -1,75 +0,0 @@ -apiVersion: v1 -kind: ConfigMap -metadata: - name: {{ template "app.name" . }}-application - namespace: {{ .Release.Namespace }} - labels: - {{- include "uttu.common.labels" . | indent 4 }} -data: - application.properties: |- - organisation.registry.url={{ .Values.configMap.organisationRegistryUrl }} - stopplace.registry.url={{ .Values.configMap.stopplaceRegistryUrl }} - export.notify.enabled=true - export.notify.queue.name={{ .Values.configMap.exportQueueName }} - export.blob.folder={{ .Values.configMap.exportBlobFolder }} - export.blob.filenameSuffix=-flexible-lines - export.blob.commonFileFilenameSuffix=_flexible_shared_data - export.working.folder=/tmp/export - - # gcs - blobstore.gcs.project.id={{ .Values.configMap.blobstoreProjectId }} - blobstore.gcs.container.name={{ .Values.configMap.blobstoreContainerName }} - - # pubsub - spring.cloud.gcp.pubsub.project-id={{ .Values.configMap.pubsubProjectId }} - spring.cloud.gcp.pubsub.subscriber.parallel-pull-count=1 - spring.cloud.gcp.pubsub.subscriber.executor-threads=30 - spring.cloud.gcp.pubsub.subscriber.max-ack-extension-period=36000 - - # Database properties - spring.jpa.open-in-view=false - spring.jpa.properties.hibernate.temp.use_jdbc_metadata_defaults=false - spring.jpa.database=POSTGRESQL - spring.jpa.hibernate.ddl-auto=none - spring.database.driverClassName=org.postgresql.Driver - spring.datasource.url=jdbc:postgresql://localhost:5432/uttu - spring.datasource.platform=postgres - spring.datasource.username=uttu - spring.flyway.table={{ .Values.configMap.flywayTable }} - - #OAuth2 Resource Server - - # OAuth2 Resource Server - uttu.oauth2.resourceserver.auth0.ror.claim.namespace=https://ror.entur.io/ - - # OAuth2 Resource Server for Entur Partner tenant - uttu.oauth2.resourceserver.auth0.entur.partner.jwt.issuer-uri={{ .Values.configMap.auth0.partner.url }} - uttu.oauth2.resourceserver.auth0.entur.partner.jwt.audience={{ .Values.configMap.auth0.ror.audience }} - - # OAuth2 Resource Server for RoR tenant - uttu.oauth2.resourceserver.auth0.ror.jwt.issuer-uri={{ .Values.configMap.auth0.ror.url }} - uttu.oauth2.resourceserver.auth0.ror.jwt.audience={{ .Values.configMap.auth0.ror.audience }} - - - #Oauth2 Client - spring.security.oauth2.client.provider.orgregister.token-uri={{ .Values.configMap.auth0.client.tokenUri }} - spring.security.oauth2.client.registration.orgregister.client-id={{ .Values.configMap.auth0.client.clientId }} - spring.security.oauth2.client.registration.orgregister.authorization-grant-type=client_credentials - orgregister.oauth2.client.audience={{ .Values.configMap.orgRegister.audience }} - - # Spring Actuator - management.server.port= {{ .Values.common.service.internalPort }} - management.endpoints.enabled-by-default=false - management.endpoint.info.enabled=true - management.endpoint.health.enabled=true - management.endpoint.health.group.readiness.include=readinessState,db,pubSub - management.endpoint.prometheus.enabled=true - management.endpoints.web.exposure.include=info,health,prometheus - - # Logging - logging.level.no.entur.uttu={{ .Values.configMap.logLevel }} - logging.level.no.entur.uttu.health.rest.HealthResource=INFO - - # Profile - spring.profiles.active=gcs-blobstore,entur,entur-legacy-organisation-registry - spring.main.allow-bean-definition-overriding=true diff --git a/helm/uttu/templates/ingress.yaml b/helm/uttu/templates/ingress.yaml deleted file mode 100644 index 516bf334..00000000 --- a/helm/uttu/templates/ingress.yaml +++ /dev/null @@ -1,21 +0,0 @@ -apiVersion: networking.k8s.io/v1 -kind: Ingress -metadata: - labels: - traffic-type: api - {{- include "uttu.common.labels" . | indent 4 }} - annotations: - kubernetes.io/ingress.class: traefik - name: timetable-admin-v1-flexible-lines - namespace: {{ .Release.Namespace }} -spec: - rules: - - host: timetable-admin-v1-flexible-lines{{ .Values.ingress.domainName }} - http: - paths: - - pathType: ImplementationSpecific - backend: - service: - name: {{ template "app.name" . }} - port: - number: {{ .Values.common.service.externalPort }} \ No newline at end of file diff --git a/helm/uttu/templates/uttu-psql-configmap.yaml b/helm/uttu/templates/uttu-psql-configmap.yaml deleted file mode 100644 index dc04b2ad..00000000 --- a/helm/uttu/templates/uttu-psql-configmap.yaml +++ /dev/null @@ -1,9 +0,0 @@ -apiVersion: v1 -data: - INSTANCES: {{.Values.sql.instance}} -kind: ConfigMap -metadata: - name: uttu-psql-connection - namespace: {{ .Release.Namespace }} - labels: - {{- include "uttu.common.labels" . | indent 4 }} diff --git a/helm/uttu/values.yaml b/helm/uttu/values.yaml deleted file mode 100644 index 947c72df..00000000 --- a/helm/uttu/values.yaml +++ /dev/null @@ -1,48 +0,0 @@ -common: - app: uttu - shortname: uttu - team: ror - ingress: - enabled: false - service: - externalPort: 80 - internalPort: 8080 - container: - forceReplicas: 1 - image: <+artifacts.primary.image> - cpu: 1 - memory: 2000 - memoryLimit: 3000 - probes: - liveness: - path: /actuator/health/liveness - readiness: - path: /actuator/health/readiness - prometheus: - enabled: true - path: /actuator/prometheus - volumeMounts: - - mountPath: /etc/application-config - name: application-config - readOnly: true - volumes: - - configMap: - defaultMode: 420 - name: uttu-application - name: application-config - postgres: - enabled: true - memory: 40 - - configmap: - data: - JDK_JAVA_OPTIONS: -server -Xmx2048m -Xss1024m -Dspring.config.location=/etc/application-config/application.properties - -Dfile.encoding=UTF-8 - TZ: Europe/Oslo - enabled: true - toEnv: true - secrets: - psql-credentials: - - SPRING_DATASOURCE_PASSWORD - auth: - - SPRING_SECURITY_OAUTH2_CLIENT_REGISTRATION_ORGREGISTER_CLIENT_SECRET diff --git a/pom.xml b/pom.xml index 84a4b8ba..89cbdaf4 100644 --- a/pom.xml +++ b/pom.xml @@ -38,15 +38,15 @@ 21 - false + true - 2.20 + 2.21 ${entur.helpers.version} ${entur.helpers.version} 2023.1.0 - 31.0 + 31.1 0.18.1 2.16.1 @@ -63,6 +63,15 @@ 0.22 write + + + + snapshots + entur2-snapshots + https://entur2.jfrog.io/entur2/libs-snapshot-local + + + osgeo @@ -299,6 +308,15 @@ 1.19.8 test + + org.testcontainers + junit-jupiter + test + + + org.testcontainers + gcloud + org.assertj assertj-core @@ -419,7 +437,7 @@ org.codehaus.mojo build-helper-maven-plugin - 3.5.0 + 3.6.0 build-helper-generate-sources diff --git a/src/ext-test/java/no/entur/uttu/ext/entur/export/messaging/EnturPubSubMessagingServiceTest.java b/src/ext-test/java/no/entur/uttu/ext/entur/export/messaging/EnturPubSubMessagingServiceTest.java new file mode 100644 index 00000000..c4044066 --- /dev/null +++ b/src/ext-test/java/no/entur/uttu/ext/entur/export/messaging/EnturPubSubMessagingServiceTest.java @@ -0,0 +1,129 @@ +/* + * Licensed under the EUPL, Version 1.2 or – as soon they will be approved by + * the European Commission - subsequent versions of the EUPL (the "Licence"); + * You may not use this work except in compliance with the Licence. + * You may obtain a copy of the Licence at: + * + * https://joinup.ec.europa.eu/software/page/eupl + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the Licence is distributed on an "AS IS" basis, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the Licence for the specific language governing permissions and + * limitations under the Licence. + * + */ + +package no.entur.uttu.ext.entur.export.messaging; + +import com.google.api.gax.core.CredentialsProvider; +import com.google.api.gax.core.NoCredentialsProvider; +import com.google.cloud.spring.pubsub.core.PubSubTemplate; +import com.google.cloud.spring.pubsub.core.subscriber.PubSubSubscriberTemplate; +import com.google.pubsub.v1.PubsubMessage; +import java.nio.charset.StandardCharsets; +import java.util.List; +import no.entur.uttu.UttuIntegrationTest; +import no.entur.uttu.export.messaging.spi.MessagingService; +import org.entur.pubsub.base.EnturGooglePubSubAdmin; +import org.junit.*; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.beans.factory.annotation.Value; +import org.springframework.boot.test.context.TestConfiguration; +import org.springframework.context.annotation.Bean; +import org.springframework.test.context.ActiveProfiles; +import org.springframework.test.context.DynamicPropertyRegistry; +import org.springframework.test.context.DynamicPropertySource; +import org.testcontainers.containers.PubSubEmulatorContainer; +import org.testcontainers.junit.jupiter.Testcontainers; +import org.testcontainers.utility.DockerImageName; + +@Testcontainers +@ActiveProfiles({ "test", "entur-pubsub-messaging-service" }) +public class EnturPubSubMessagingServiceTest extends UttuIntegrationTest { + + public static final String TEST_CODESPACE = "rut"; + + public static final String TEST_EXPORT_FILE_NAME = "netex.zip"; + private static PubSubEmulatorContainer pubsubEmulator; + + @Autowired + private MessagingService messagingService; + + @Autowired + private PubSubTemplate pubSubTemplate; + + @Autowired + PubSubSubscriberTemplate subscriberTemplate; + + @Autowired + private EnturGooglePubSubAdmin enturGooglePubSubAdmin; + + @Value("${export.notify.queue.name:FlexibleLinesExportQueue}") + private String queueName; + + @DynamicPropertySource + static void emulatorProperties(DynamicPropertyRegistry registry) { + registry.add( + "spring.cloud.gcp.pubsub.emulator-host", + pubsubEmulator::getEmulatorEndpoint + ); + registry.add("spring.cloud.gcp.pubsub.enabled", () -> true); + registry.add("spring.cloud.gcp.project-id", () -> "uttu-gcp-test-project"); + registry.add("spring.cloud.gcp.pubsub.project-id", () -> "uttu-gcp-test-project"); + registry.add("export.notify.enabled", () -> true); + registry.add("export.notify.queue.name", () -> "FlexibleLinesExportQueue"); + } + + @BeforeClass + public static void init() { + pubsubEmulator = + new PubSubEmulatorContainer( + DockerImageName.parse("gcr.io/google.com/cloudsdktool/cloud-sdk:emulators") + ); + pubsubEmulator.start(); + } + + @AfterClass + public static void tearDown() { + pubsubEmulator.stop(); + } + + @Before + public void setup() { + enturGooglePubSubAdmin.createSubscriptionIfMissing(queueName); + } + + @After + public void teardown() { + enturGooglePubSubAdmin.deleteAllSubscriptions(); + } + + // By default, autoconfiguration will initialize application default credentials. + // For testing purposes, don't use any credentials. Bootstrap w/ NoCredentialsProvider. + @TestConfiguration + static class PubSubEmulatorConfiguration { + + @Bean + CredentialsProvider googleCredentials() { + return NoCredentialsProvider.create(); + } + } + + @Test + public void testNotifyExport() { + messagingService.notifyExport(TEST_CODESPACE, TEST_EXPORT_FILE_NAME); + + List messages = pubSubTemplate.pullAndAck(queueName, 1, false); + Assert.assertEquals(1, messages.size()); + PubsubMessage pubsubMessage = messages.get(0); + String codespace = pubsubMessage + .getAttributesMap() + .get(EnturPubSubMessagingService.HEADER_CHOUETTE_REFERENTIAL); + Assert.assertEquals("rb_" + TEST_CODESPACE, codespace); + Assert.assertEquals( + TEST_EXPORT_FILE_NAME, + pubsubMessage.getData().toString(StandardCharsets.UTF_8) + ); + } +} diff --git a/src/test/java/no/entur/uttu/config/NetexHttpMessageConverterTest.java b/src/ext-test/java/no/entur/uttu/ext/entur/stopplace/NetexHttpMessageConverterTest.java similarity index 71% rename from src/test/java/no/entur/uttu/config/NetexHttpMessageConverterTest.java rename to src/ext-test/java/no/entur/uttu/ext/entur/stopplace/NetexHttpMessageConverterTest.java index 2dc6e915..c7920961 100644 --- a/src/test/java/no/entur/uttu/config/NetexHttpMessageConverterTest.java +++ b/src/ext-test/java/no/entur/uttu/ext/entur/stopplace/NetexHttpMessageConverterTest.java @@ -1,6 +1,6 @@ -package no.entur.uttu.config; +package no.entur.uttu.ext.entur.stopplace; -import jakarta.xml.bind.JAXBException; +import no.entur.uttu.netex.NetexUnmarshallerUnmarshalFromSourceException; import org.junit.Test; import org.junit.jupiter.api.Assertions; import org.rutebanken.netex.model.StopPlace; @@ -11,7 +11,8 @@ public class NetexHttpMessageConverterTest { @Test - public void testConvertStopPlace() throws JAXBException { + public void testConvertStopPlace() + throws NetexUnmarshallerUnmarshalFromSourceException { NetexHttpMessageConverter converter = new NetexHttpMessageConverter(); Assertions.assertTrue(converter.supports(StopPlace.class)); @@ -23,7 +24,7 @@ public void testConvertStopPlace() throws JAXBException { StopPlace stopPlace = (StopPlace) converter.readFromSource( StopPlace.class, HttpHeaders.EMPTY, - Input.fromFile("src/test/resources/stopPlaceFixture.xml").build() + Input.fromFile("src/ext-test/resources/stopPlaceFixture.xml").build() ); Assertions.assertEquals("NSR:StopPlace:337", stopPlace.getId()); diff --git a/src/test/resources/stopPlaceFixture.xml b/src/ext-test/resources/stopPlaceFixture.xml similarity index 100% rename from src/test/resources/stopPlaceFixture.xml rename to src/ext-test/resources/stopPlaceFixture.xml diff --git a/src/ext/java/no/entur/uttu/ext/entur/config/EnturConfiguration.java b/src/ext/java/no/entur/uttu/ext/entur/config/EnturConfiguration.java new file mode 100644 index 00000000..029a386c --- /dev/null +++ b/src/ext/java/no/entur/uttu/ext/entur/config/EnturConfiguration.java @@ -0,0 +1,11 @@ +package no.entur.uttu.ext.entur.config; + +import org.entur.pubsub.base.config.GooglePubSubConfig; +import org.springframework.context.annotation.Configuration; +import org.springframework.context.annotation.Import; +import org.springframework.context.annotation.Profile; + +@Configuration +@Profile("entur-pubsub-messaging-service") +@Import(GooglePubSubConfig.class) +public class EnturConfiguration {} diff --git a/src/main/java/no/entur/uttu/export/messaging/PubSubMessagingService.java b/src/ext/java/no/entur/uttu/ext/entur/export/messaging/EnturPubSubMessagingService.java similarity index 84% rename from src/main/java/no/entur/uttu/export/messaging/PubSubMessagingService.java rename to src/ext/java/no/entur/uttu/ext/entur/export/messaging/EnturPubSubMessagingService.java index cb821d75..b2adc7e2 100644 --- a/src/main/java/no/entur/uttu/export/messaging/PubSubMessagingService.java +++ b/src/ext/java/no/entur/uttu/ext/entur/export/messaging/EnturPubSubMessagingService.java @@ -1,18 +1,21 @@ -package no.entur.uttu.export.messaging; +package no.entur.uttu.ext.entur.export.messaging; import com.google.cloud.spring.pubsub.core.PubSubTemplate; import java.util.HashMap; import java.util.Map; import java.util.UUID; import no.entur.uttu.config.Context; +import no.entur.uttu.export.messaging.spi.MessagingService; import no.entur.uttu.util.ExportUtil; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.beans.factory.annotation.Value; +import org.springframework.context.annotation.Profile; import org.springframework.stereotype.Component; @Component -public class PubSubMessagingService implements MessagingService { +@Profile("entur-pubsub-messaging-service") +public class EnturPubSubMessagingService implements MessagingService { public static final String HEADER_CHOUETTE_REFERENTIAL = "RutebankenChouetteReferential"; @@ -29,7 +32,7 @@ public class PubSubMessagingService implements MessagingService { @Value("${export.notify.queue.name:FlexibleLinesExportQueue}") private String queueName; - public PubSubMessagingService(PubSubTemplate pubSubTemplate) { + public EnturPubSubMessagingService(PubSubTemplate pubSubTemplate) { this.pubSubTemplate = pubSubTemplate; } diff --git a/src/main/java/no/entur/uttu/stopplace/DefaultStopPlaceRegistry.java b/src/ext/java/no/entur/uttu/ext/entur/stopplace/EnturMummuStopPlaceRegistry.java similarity index 92% rename from src/main/java/no/entur/uttu/stopplace/DefaultStopPlaceRegistry.java rename to src/ext/java/no/entur/uttu/ext/entur/stopplace/EnturMummuStopPlaceRegistry.java index 5fcce9c2..56dcc1ef 100644 --- a/src/main/java/no/entur/uttu/stopplace/DefaultStopPlaceRegistry.java +++ b/src/ext/java/no/entur/uttu/ext/entur/stopplace/EnturMummuStopPlaceRegistry.java @@ -13,7 +13,7 @@ * limitations under the Licence. */ -package no.entur.uttu.stopplace; +package no.entur.uttu.ext.entur.stopplace; import com.google.common.cache.CacheBuilder; import com.google.common.cache.CacheLoader; @@ -23,10 +23,11 @@ import java.util.concurrent.ExecutionException; import java.util.concurrent.TimeUnit; import javax.annotation.PostConstruct; -import no.entur.uttu.config.NetexHttpMessageConverter; +import no.entur.uttu.stopplace.spi.StopPlaceRegistry; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.beans.factory.annotation.Value; +import org.springframework.context.annotation.Profile; import org.springframework.http.HttpEntity; import org.springframework.http.HttpHeaders; import org.springframework.http.HttpMethod; @@ -39,10 +40,11 @@ * to retrieve a stop place given the ID of one of its quays. */ @Component -public class DefaultStopPlaceRegistry implements StopPlaceRegistry { +@Profile("entur-mummu-stop-place-registry") +public class EnturMummuStopPlaceRegistry implements StopPlaceRegistry { private static final Logger logger = LoggerFactory.getLogger( - DefaultStopPlaceRegistry.class + EnturMummuStopPlaceRegistry.class ); private RestTemplate restTemplate = new RestTemplate(); diff --git a/src/ext/java/no/entur/uttu/ext/entur/stopplace/NetexHttpMessageConverter.java b/src/ext/java/no/entur/uttu/ext/entur/stopplace/NetexHttpMessageConverter.java new file mode 100644 index 00000000..3cc68dd0 --- /dev/null +++ b/src/ext/java/no/entur/uttu/ext/entur/stopplace/NetexHttpMessageConverter.java @@ -0,0 +1,39 @@ +package no.entur.uttu.ext.entur.stopplace; + +import java.util.List; +import javax.xml.transform.Result; +import javax.xml.transform.Source; +import no.entur.uttu.netex.NetexUnmarshaller; +import no.entur.uttu.netex.NetexUnmarshallerUnmarshalFromSourceException; +import org.rutebanken.netex.model.StopPlace; +import org.springframework.http.HttpHeaders; +import org.springframework.http.MediaType; +import org.springframework.http.converter.xml.AbstractXmlHttpMessageConverter; + +public class NetexHttpMessageConverter extends AbstractXmlHttpMessageConverter { + + private final NetexUnmarshaller netexUnmarshaller = new NetexUnmarshaller( + StopPlace.class + ); + + @Override + protected Object readFromSource(Class clazz, HttpHeaders headers, Source source) + throws NetexUnmarshallerUnmarshalFromSourceException { + return netexUnmarshaller.unmarshalFromSource(source); + } + + @Override + protected void writeToResult(Object o, HttpHeaders headers, Result result) { + // This converter is intended for unmarshalling only + } + + @Override + protected boolean supports(Class clazz) { + return clazz.isAssignableFrom(StopPlace.class); + } + + @Override + public List getSupportedMediaTypes(Class clazz) { + return List.of(MediaType.APPLICATION_XML); + } +} diff --git a/src/main/java/no/entur/uttu/App.java b/src/main/java/no/entur/uttu/App.java index 129264a7..363e090d 100644 --- a/src/main/java/no/entur/uttu/App.java +++ b/src/main/java/no/entur/uttu/App.java @@ -17,18 +17,15 @@ import no.entur.uttu.model.Provider; import no.entur.uttu.repository.generic.ProviderEntityRepositoryImpl; -import org.entur.pubsub.base.config.GooglePubSubConfig; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; import org.springframework.boot.autoconfigure.domain.EntityScan; import org.springframework.boot.autoconfigure.security.servlet.UserDetailsServiceAutoConfiguration; import org.springframework.cache.annotation.EnableCaching; -import org.springframework.context.annotation.Import; import org.springframework.data.jpa.convert.threeten.Jsr310JpaConverters; import org.springframework.data.jpa.repository.config.EnableJpaRepositories; @SpringBootApplication(exclude = { UserDetailsServiceAutoConfiguration.class }) -@Import(GooglePubSubConfig.class) @EnableJpaRepositories( basePackages = { "no.entur.uttu.repository" }, repositoryBaseClass = ProviderEntityRepositoryImpl.class diff --git a/src/main/java/no/entur/uttu/config/NetexHttpMessageConverter.java b/src/main/java/no/entur/uttu/config/NetexHttpMessageConverter.java deleted file mode 100644 index 1eb64948..00000000 --- a/src/main/java/no/entur/uttu/config/NetexHttpMessageConverter.java +++ /dev/null @@ -1,70 +0,0 @@ -package no.entur.uttu.config; - -import static jakarta.xml.bind.JAXBContext.newInstance; - -import jakarta.xml.bind.JAXBContext; -import jakarta.xml.bind.JAXBElement; -import jakarta.xml.bind.JAXBException; -import jakarta.xml.bind.Unmarshaller; -import java.util.List; -import javax.xml.transform.Result; -import javax.xml.transform.Source; -import org.rutebanken.netex.model.PublicationDeliveryStructure; -import org.rutebanken.netex.model.StopPlace; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; -import org.springframework.http.HttpHeaders; -import org.springframework.http.MediaType; -import org.springframework.http.converter.xml.AbstractXmlHttpMessageConverter; - -public class NetexHttpMessageConverter extends AbstractXmlHttpMessageConverter { - - private static final Logger log = LoggerFactory.getLogger( - NetexHttpMessageConverter.class - ); - private static final JAXBContext publicationDeliveryContext = createContext( - PublicationDeliveryStructure.class, - StopPlace.class - ); - - @Override - protected Object readFromSource(Class clazz, HttpHeaders headers, Source source) - throws JAXBException { - JAXBElement element = (JAXBElement) getUnmarshaller().unmarshal(source); - return element.getValue(); - } - - @Override - protected void writeToResult(Object o, HttpHeaders headers, Result result) { - // This converter is intended for unmarshalling only - } - - @Override - protected boolean supports(Class clazz) { - return clazz.isAssignableFrom(StopPlace.class); - } - - @Override - public List getSupportedMediaTypes(Class clazz) { - return List.of(MediaType.APPLICATION_XML); - } - - private Unmarshaller getUnmarshaller() throws JAXBException { - return publicationDeliveryContext.createUnmarshaller(); - } - - private static JAXBContext createContext(Class... clazz) { - try { - JAXBContext jaxbContext = newInstance(clazz); - log.info("Created context {}", jaxbContext.getClass()); - return jaxbContext; - } catch (JAXBException e) { - String message = "Could not create instance of jaxb context for class " + clazz; - log.warn(message, e); - throw new RuntimeException( - "Could not create instance of jaxb context for class " + clazz, - e - ); - } - } -} diff --git a/src/main/java/no/entur/uttu/export/ExportService.java b/src/main/java/no/entur/uttu/export/ExportService.java index c9866b8c..6c66ac95 100644 --- a/src/main/java/no/entur/uttu/export/ExportService.java +++ b/src/main/java/no/entur/uttu/export/ExportService.java @@ -20,7 +20,7 @@ import java.util.List; import no.entur.uttu.error.codedexception.CodedIllegalArgumentException; import no.entur.uttu.export.linestatistics.ExportedLineStatisticsService; -import no.entur.uttu.export.messaging.MessagingService; +import no.entur.uttu.export.messaging.spi.MessagingService; import no.entur.uttu.export.netex.DataSetProducer; import no.entur.uttu.export.netex.NetexExporter; import no.entur.uttu.model.Line; diff --git a/src/main/java/no/entur/uttu/export/messaging/MessagingService.java b/src/main/java/no/entur/uttu/export/messaging/MessagingService.java deleted file mode 100644 index 686c25d0..00000000 --- a/src/main/java/no/entur/uttu/export/messaging/MessagingService.java +++ /dev/null @@ -1,5 +0,0 @@ -package no.entur.uttu.export.messaging; - -public interface MessagingService { - void notifyExport(String codespace, String filename); -} diff --git a/src/main/java/no/entur/uttu/export/messaging/NoopMessagingService.java b/src/main/java/no/entur/uttu/export/messaging/NoopMessagingService.java new file mode 100644 index 00000000..d4c8a4b0 --- /dev/null +++ b/src/main/java/no/entur/uttu/export/messaging/NoopMessagingService.java @@ -0,0 +1,21 @@ +package no.entur.uttu.export.messaging; + +import no.entur.uttu.export.messaging.spi.MessagingService; +import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean; +import org.springframework.stereotype.Component; + +/** + * The default implementation is a noop operation + */ +@Component +@ConditionalOnMissingBean( + value = MessagingService.class, + ignored = NoopMessagingService.class +) +public class NoopMessagingService implements MessagingService { + + @Override + public void notifyExport(String codespace, String filename) { + // intentionally empty + } +} diff --git a/src/main/java/no/entur/uttu/export/messaging/spi/MessagingService.java b/src/main/java/no/entur/uttu/export/messaging/spi/MessagingService.java new file mode 100644 index 00000000..35144e2c --- /dev/null +++ b/src/main/java/no/entur/uttu/export/messaging/spi/MessagingService.java @@ -0,0 +1,13 @@ +package no.entur.uttu.export.messaging.spi; + +/** + * Represents a service which can send a notification to an external system about an export + */ +public interface MessagingService { + /** + * Notify about export + * @param codespace The codespace of the provider + * @param filename The filename for this export + */ + void notifyExport(String codespace, String filename); +} diff --git a/src/main/java/no/entur/uttu/export/netex/producer/line/JourneyPatternProducer.java b/src/main/java/no/entur/uttu/export/netex/producer/line/JourneyPatternProducer.java index f6b9095d..82ec1188 100644 --- a/src/main/java/no/entur/uttu/export/netex/producer/line/JourneyPatternProducer.java +++ b/src/main/java/no/entur/uttu/export/netex/producer/line/JourneyPatternProducer.java @@ -29,7 +29,7 @@ import no.entur.uttu.model.Ref; import no.entur.uttu.model.StopPointInJourneyPattern; import no.entur.uttu.model.job.SeverityEnumeration; -import no.entur.uttu.stopplace.StopPlaceRegistry; +import no.entur.uttu.stopplace.spi.StopPlaceRegistry; import org.rutebanken.netex.model.BookingAccessEnumeration; import org.rutebanken.netex.model.BookingArrangementsStructure; import org.rutebanken.netex.model.BookingMethodEnumeration; diff --git a/src/main/java/no/entur/uttu/graphql/fetchers/QuayRefSearchFetcher.java b/src/main/java/no/entur/uttu/graphql/fetchers/QuayRefSearchFetcher.java index 9181124b..340d859f 100644 --- a/src/main/java/no/entur/uttu/graphql/fetchers/QuayRefSearchFetcher.java +++ b/src/main/java/no/entur/uttu/graphql/fetchers/QuayRefSearchFetcher.java @@ -6,7 +6,7 @@ import graphql.schema.DataFetchingEnvironment; import java.util.stream.Collectors; import no.entur.uttu.model.TimetabledPassingTime; -import no.entur.uttu.stopplace.StopPlaceRegistry; +import no.entur.uttu.stopplace.spi.StopPlaceRegistry; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; diff --git a/src/main/java/no/entur/uttu/graphql/mappers/FlexibleStopPlaceMapper.java b/src/main/java/no/entur/uttu/graphql/mappers/FlexibleStopPlaceMapper.java index ddfe9760..6aab70f6 100644 --- a/src/main/java/no/entur/uttu/graphql/mappers/FlexibleStopPlaceMapper.java +++ b/src/main/java/no/entur/uttu/graphql/mappers/FlexibleStopPlaceMapper.java @@ -36,7 +36,7 @@ import no.entur.uttu.model.Value; import no.entur.uttu.repository.ProviderRepository; import no.entur.uttu.repository.generic.ProviderEntityRepository; -import no.entur.uttu.stopplace.StopPlaceRegistry; +import no.entur.uttu.stopplace.spi.StopPlaceRegistry; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Component; diff --git a/src/main/java/no/entur/uttu/graphql/mappers/StopPointInJourneyPatternMapper.java b/src/main/java/no/entur/uttu/graphql/mappers/StopPointInJourneyPatternMapper.java index 8a7b06fc..8d5d4ada 100644 --- a/src/main/java/no/entur/uttu/graphql/mappers/StopPointInJourneyPatternMapper.java +++ b/src/main/java/no/entur/uttu/graphql/mappers/StopPointInJourneyPatternMapper.java @@ -28,7 +28,7 @@ import no.entur.uttu.repository.FlexibleStopPlaceRepository; import no.entur.uttu.repository.ProviderRepository; import no.entur.uttu.repository.generic.ProviderEntityRepository; -import no.entur.uttu.stopplace.StopPlaceRegistry; +import no.entur.uttu.stopplace.spi.StopPlaceRegistry; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Component; diff --git a/src/main/java/no/entur/uttu/netex/NetexUnmarshaller.java b/src/main/java/no/entur/uttu/netex/NetexUnmarshaller.java new file mode 100644 index 00000000..fc08e3df --- /dev/null +++ b/src/main/java/no/entur/uttu/netex/NetexUnmarshaller.java @@ -0,0 +1,51 @@ +package no.entur.uttu.netex; + +import static jakarta.xml.bind.JAXBContext.newInstance; + +import jakarta.xml.bind.JAXBContext; +import jakarta.xml.bind.JAXBElement; +import jakarta.xml.bind.JAXBException; +import jakarta.xml.bind.Unmarshaller; +import javax.xml.transform.Source; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +/** + * Thread safe NetexUnmarshaller service + */ +public class NetexUnmarshaller { + + private static final Logger logger = LoggerFactory.getLogger(NetexUnmarshaller.class); + + // JAXBContext is thread safe so can be shared + private final JAXBContext publicationDeliveryContext; + + public NetexUnmarshaller(Class... clazz) { + publicationDeliveryContext = createContext(clazz); + } + + public T unmarshalFromSource(Source source) + throws NetexUnmarshallerUnmarshalFromSourceException { + try { + // the Unmarshaller is not thread safe so must be created on every call + JAXBElement element = (JAXBElement) getUnmarshaller().unmarshal(source); + return element.getValue(); + } catch (JAXBException e) { + throw new NetexUnmarshallerUnmarshalFromSourceException(source, e); + } + } + + private Unmarshaller getUnmarshaller() throws JAXBException { + return publicationDeliveryContext.createUnmarshaller(); + } + + private static JAXBContext createContext(Class... clazz) { + try { + JAXBContext jaxbContext = newInstance(clazz); + logger.trace("Created context {}", jaxbContext.getClass()); + return jaxbContext; + } catch (JAXBException e) { + throw new NetexUnmarshallerCreateContextException(e, clazz); + } + } +} diff --git a/src/main/java/no/entur/uttu/netex/NetexUnmarshallerCreateContextException.java b/src/main/java/no/entur/uttu/netex/NetexUnmarshallerCreateContextException.java new file mode 100644 index 00000000..13a4610f --- /dev/null +++ b/src/main/java/no/entur/uttu/netex/NetexUnmarshallerCreateContextException.java @@ -0,0 +1,13 @@ +package no.entur.uttu.netex; + +import java.util.Arrays; + +public class NetexUnmarshallerCreateContextException extends RuntimeException { + + public NetexUnmarshallerCreateContextException(Throwable cause, Class... clazz) { + super( + "Could not create instance of jaxb context for class " + Arrays.toString(clazz), + cause + ); + } +} diff --git a/src/main/java/no/entur/uttu/netex/NetexUnmarshallerUnmarshalFromSourceException.java b/src/main/java/no/entur/uttu/netex/NetexUnmarshallerUnmarshalFromSourceException.java new file mode 100644 index 00000000..3168b507 --- /dev/null +++ b/src/main/java/no/entur/uttu/netex/NetexUnmarshallerUnmarshalFromSourceException.java @@ -0,0 +1,10 @@ +package no.entur.uttu.netex; + +import javax.xml.transform.Source; + +public class NetexUnmarshallerUnmarshalFromSourceException extends Exception { + + public NetexUnmarshallerUnmarshalFromSourceException(Source source, Throwable cause) { + super(String.format("Unable to unmarshal from source=%s", source), cause); + } +} diff --git a/src/main/java/no/entur/uttu/organisation/NetexPublicationDeliveryFileOrganisationRegistry.java b/src/main/java/no/entur/uttu/organisation/NetexPublicationDeliveryFileOrganisationRegistry.java index 297c2b86..61714be2 100644 --- a/src/main/java/no/entur/uttu/organisation/NetexPublicationDeliveryFileOrganisationRegistry.java +++ b/src/main/java/no/entur/uttu/organisation/NetexPublicationDeliveryFileOrganisationRegistry.java @@ -1,23 +1,17 @@ package no.entur.uttu.organisation; -import static jakarta.xml.bind.JAXBContext.newInstance; - -import jakarta.xml.bind.JAXBContext; -import jakarta.xml.bind.JAXBElement; -import jakarta.xml.bind.JAXBException; -import jakarta.xml.bind.Unmarshaller; import java.io.File; import java.util.List; import java.util.Optional; import javax.annotation.PostConstruct; -import javax.xml.transform.Source; import javax.xml.transform.stream.StreamSource; import no.entur.uttu.error.codederror.CodedError; import no.entur.uttu.error.codes.ErrorCodeEnumeration; +import no.entur.uttu.netex.NetexUnmarshaller; +import no.entur.uttu.netex.NetexUnmarshallerUnmarshalFromSourceException; import no.entur.uttu.organisation.spi.OrganisationRegistry; import no.entur.uttu.util.Preconditions; import org.rutebanken.netex.model.GeneralOrganisation; -import org.rutebanken.netex.model.Organisation; import org.rutebanken.netex.model.PublicationDeliveryStructure; import org.rutebanken.netex.model.ResourceFrame; import org.slf4j.Logger; @@ -34,28 +28,24 @@ public class NetexPublicationDeliveryFileOrganisationRegistry implements OrganisationRegistry { - private final Logger logger = LoggerFactory.getLogger(this.getClass()); - - private List organisations = List.of(); - - private static final Logger log = LoggerFactory.getLogger( + private final Logger logger = LoggerFactory.getLogger( NetexPublicationDeliveryFileOrganisationRegistry.class ); - private static final JAXBContext publicationDeliveryContext = createContext( - PublicationDeliveryStructure.class, - Organisation.class + private final NetexUnmarshaller netexUnmarshaller = new NetexUnmarshaller( + PublicationDeliveryStructure.class ); + private List organisations = List.of(); + @Value("${uttu.organisations.netex-file-uri}") String netexFileUri; @PostConstruct public void init() { try { - PublicationDeliveryStructure publicationDeliveryStructure = readFromSource( - new StreamSource(new File(netexFileUri)) - ); + PublicationDeliveryStructure publicationDeliveryStructure = + netexUnmarshaller.unmarshalFromSource(new StreamSource(new File(netexFileUri))); publicationDeliveryStructure .getDataObjects() .getCompositeFrameOrCommonFrame() @@ -71,7 +61,7 @@ public void init() { .toList(); } }); - } catch (JAXBException e) { + } catch (NetexUnmarshallerUnmarshalFromSourceException e) { logger.warn( "Unable to unmarshal organisations xml, organisation registry will be an empty list" ); @@ -117,28 +107,4 @@ public void validateAuthorityRef(String authorityRef) { authorityRef ); } - - private T readFromSource(Source source) throws JAXBException { - JAXBElement element = (JAXBElement) getUnmarshaller().unmarshal(source); - return element.getValue(); - } - - private Unmarshaller getUnmarshaller() throws JAXBException { - return publicationDeliveryContext.createUnmarshaller(); - } - - private static JAXBContext createContext(Class... clazz) { - try { - JAXBContext jaxbContext = newInstance(clazz); - log.info("Created context {}", jaxbContext.getClass()); - return jaxbContext; - } catch (JAXBException e) { - String message = "Could not create instance of jaxb context for class " + clazz; - log.warn(message, e); - throw new RuntimeException( - "Could not create instance of jaxb context for class " + clazz, - e - ); - } - } } diff --git a/src/main/java/no/entur/uttu/stopplace/NetexPublicationDeliveryFileStopPlaceRegistry.java b/src/main/java/no/entur/uttu/stopplace/NetexPublicationDeliveryFileStopPlaceRegistry.java new file mode 100644 index 00000000..d80a64fc --- /dev/null +++ b/src/main/java/no/entur/uttu/stopplace/NetexPublicationDeliveryFileStopPlaceRegistry.java @@ -0,0 +1,87 @@ +package no.entur.uttu.stopplace; + +import java.io.File; +import java.util.List; +import java.util.Map; +import java.util.Optional; +import java.util.concurrent.ConcurrentHashMap; +import javax.annotation.PostConstruct; +import javax.xml.transform.stream.StreamSource; +import no.entur.uttu.netex.NetexUnmarshaller; +import no.entur.uttu.netex.NetexUnmarshallerUnmarshalFromSourceException; +import no.entur.uttu.stopplace.spi.StopPlaceRegistry; +import org.rutebanken.netex.model.PublicationDeliveryStructure; +import org.rutebanken.netex.model.Quay; +import org.rutebanken.netex.model.SiteFrame; +import org.rutebanken.netex.model.StopPlace; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.beans.factory.annotation.Value; +import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean; +import org.springframework.stereotype.Component; + +@Component +@ConditionalOnMissingBean( + value = StopPlaceRegistry.class, + ignored = NetexPublicationDeliveryFileStopPlaceRegistry.class +) +public class NetexPublicationDeliveryFileStopPlaceRegistry implements StopPlaceRegistry { + + private final Logger logger = LoggerFactory.getLogger( + NetexPublicationDeliveryFileStopPlaceRegistry.class + ); + + private final NetexUnmarshaller netexUnmarshaller = new NetexUnmarshaller( + PublicationDeliveryStructure.class + ); + + private final Map stopPlaceByQuayRefIndex = + new ConcurrentHashMap<>(); + + @Value("${uttu.stopplace.netex-file-uri}") + String netexFileUri; + + @PostConstruct + public void init() { + try { + PublicationDeliveryStructure publicationDeliveryStructure = + netexUnmarshaller.unmarshalFromSource(new StreamSource(new File(netexFileUri))); + publicationDeliveryStructure + .getDataObjects() + .getCompositeFrameOrCommonFrame() + .forEach(frame -> { + var frameValue = frame.getValue(); + if (frameValue instanceof SiteFrame siteFrame) { + List stopPlaces = siteFrame + .getStopPlaces() + .getStopPlace_() + .stream() + .map(stopPlace -> (StopPlace) stopPlace.getValue()) + .toList(); + + stopPlaces.forEach(stopPlace -> + Optional + .ofNullable(stopPlace.getQuays()) + .ifPresent(quays -> + quays + .getQuayRefOrQuay() + .forEach(quayRefOrQuay -> { + Quay quay = (Quay) quayRefOrQuay.getValue(); + stopPlaceByQuayRefIndex.put(quay.getId(), stopPlace); + }) + ) + ); + } + }); + } catch (NetexUnmarshallerUnmarshalFromSourceException e) { + logger.warn( + "Unable to unmarshal stop places xml, stop place registry will be an empty list" + ); + } + } + + @Override + public Optional getStopPlaceByQuayRef(String quayRef) { + return Optional.ofNullable(stopPlaceByQuayRefIndex.get(quayRef)); + } +} diff --git a/src/main/java/no/entur/uttu/stopplace/StopPlaceRegistry.java b/src/main/java/no/entur/uttu/stopplace/spi/StopPlaceRegistry.java similarity index 74% rename from src/main/java/no/entur/uttu/stopplace/StopPlaceRegistry.java rename to src/main/java/no/entur/uttu/stopplace/spi/StopPlaceRegistry.java index a389e833..0c413c08 100644 --- a/src/main/java/no/entur/uttu/stopplace/StopPlaceRegistry.java +++ b/src/main/java/no/entur/uttu/stopplace/spi/StopPlaceRegistry.java @@ -13,10 +13,18 @@ * limitations under the Licence. */ -package no.entur.uttu.stopplace; +package no.entur.uttu.stopplace.spi; import java.util.Optional; +/** + * Represents a stop place registry used to lookup stop places from quay refs + */ public interface StopPlaceRegistry { + /** + * Lookup a stop place entity from a quay ref + * @param quayRef The id of a quay + * @return The stop place that the quay belongs to + */ Optional getStopPlaceByQuayRef(String quayRef); } diff --git a/src/test/groovy/no/entur/uttu/graphql/AbstractFixedLinesGraphQLIntegrationTest.groovy b/src/test/groovy/no/entur/uttu/graphql/AbstractFixedLinesGraphQLIntegrationTest.groovy index 804dca4a..57efdafa 100644 --- a/src/test/groovy/no/entur/uttu/graphql/AbstractFixedLinesGraphQLIntegrationTest.groovy +++ b/src/test/groovy/no/entur/uttu/graphql/AbstractFixedLinesGraphQLIntegrationTest.groovy @@ -117,13 +117,13 @@ abstract class AbstractFixedLinesGraphQLIntegrationTest extends AbstractGraphQLR { "pointsInSequence": [ { - "quayRef": "NSR:Quay:69", + "quayRef": "NSR:Quay:494", "destinationDisplay": { "frontText": "Første stopp" } }, { - "quayRef": "NSR:Quay:70" + "quayRef": "NSR:Quay:563" } ], "serviceJourneys": [ diff --git a/src/test/groovy/no/entur/uttu/graphql/AbstractFlexibleLinesGraphQLIntegrationTest.groovy b/src/test/groovy/no/entur/uttu/graphql/AbstractFlexibleLinesGraphQLIntegrationTest.groovy index ce1fe141..87508ea4 100644 --- a/src/test/groovy/no/entur/uttu/graphql/AbstractFlexibleLinesGraphQLIntegrationTest.groovy +++ b/src/test/groovy/no/entur/uttu/graphql/AbstractFlexibleLinesGraphQLIntegrationTest.groovy @@ -191,7 +191,7 @@ abstract class AbstractFlexibleLinesGraphQLIntegrationTest extends AbstractGraph "key": "foo", "values": ["bar", "baz"] }], - "hailAndRideArea": {"startQuayRef": "NSR:Quay:start","endQuayRef": "NSR:Quay:end"} + "hailAndRideArea": {"startQuayRef": "NSR:Quay:565","endQuayRef": "NSR:Quay:494"} } }""" @@ -268,7 +268,7 @@ abstract class AbstractFlexibleLinesGraphQLIntegrationTest extends AbstractGraph "flexibleStopPlaceRef": "$flexAreaStopPlaceId" }, { - "quayRef": "NSR:Quay:3513" + "quayRef": "NSR:Quay:563" } ], "serviceJourneys": [ @@ -306,7 +306,7 @@ abstract class AbstractFlexibleLinesGraphQLIntegrationTest extends AbstractGraph , { - "quayRef": "NSR:Quay:3513" + "quayRef": "NSR:Quay:494" } ], "serviceJourneys": [ diff --git a/src/test/groovy/no/entur/uttu/graphql/FixedLineGraphQLIntegrationTest.groovy b/src/test/groovy/no/entur/uttu/graphql/FixedLineGraphQLIntegrationTest.groovy index 9dfa763a..afa82664 100644 --- a/src/test/groovy/no/entur/uttu/graphql/FixedLineGraphQLIntegrationTest.groovy +++ b/src/test/groovy/no/entur/uttu/graphql/FixedLineGraphQLIntegrationTest.groovy @@ -29,7 +29,7 @@ class FixedLineGraphQLIntegrationTest extends AbstractFixedLinesGraphQLIntegrati createFixedLine(testFixedLineName) .body("data.mutateFixedLine.id", startsWith("TST:Line")) .body("data.mutateFixedLine.name", equalTo(testFixedLineName)) - .body("data.mutateFixedLine.journeyPatterns[0].pointsInSequence[0].quayRef", equalTo("NSR:Quay:69")) + .body("data.mutateFixedLine.journeyPatterns[0].pointsInSequence[0].quayRef", equalTo("NSR:Quay:494")) .body("data.mutateFixedLine.journeyPatterns[0].serviceJourneys[0].passingTimes[0].departureTime", equalTo("07:00:00")) } -} \ No newline at end of file +} diff --git a/src/test/groovy/no/entur/uttu/graphql/FlexibleStopPlaceGraphQLIntegrationTest.groovy b/src/test/groovy/no/entur/uttu/graphql/FlexibleStopPlaceGraphQLIntegrationTest.groovy index c9bb8e66..d89e6847 100644 --- a/src/test/groovy/no/entur/uttu/graphql/FlexibleStopPlaceGraphQLIntegrationTest.groovy +++ b/src/test/groovy/no/entur/uttu/graphql/FlexibleStopPlaceGraphQLIntegrationTest.groovy @@ -72,8 +72,8 @@ mutation deleteFlexibleStopPlace(\$id: ID!) { createFlexibleStopPlaceWithHailAndRideArea(hailAndRideTest) .body("data.mutateFlexibleStopPlace.id", startsWith("TST:FlexibleStopPlace")) .body("data.mutateFlexibleStopPlace.name", equalTo(hailAndRideTest)) - .body("data.mutateFlexibleStopPlace.hailAndRideArea.startQuayRef", equalTo("NSR:Quay:start")) - .body("data.mutateFlexibleStopPlace.hailAndRideArea.endQuayRef", equalTo("NSR:Quay:end")) + .body("data.mutateFlexibleStopPlace.hailAndRideArea.startQuayRef", equalTo("NSR:Quay:565")) + .body("data.mutateFlexibleStopPlace.hailAndRideArea.endQuayRef", equalTo("NSR:Quay:494")) } @Test diff --git a/src/test/groovy/no/entur/uttu/graphql/StopPlaceByQuayGraphQLIntegrationTest.groovy b/src/test/groovy/no/entur/uttu/graphql/StopPlaceByQuayGraphQLIntegrationTest.groovy index 08144e14..bd3b3add 100644 --- a/src/test/groovy/no/entur/uttu/graphql/StopPlaceByQuayGraphQLIntegrationTest.groovy +++ b/src/test/groovy/no/entur/uttu/graphql/StopPlaceByQuayGraphQLIntegrationTest.groovy @@ -9,13 +9,14 @@ class StopPlaceByQuayGraphQLIntegrationTest extends AbstractFlexibleLinesGraphQL @Test void getStopPlaceByQuayRefTest() { - String id = "NSR:StopPlace:337" - String query = """ { stopPlaceByQuayRef(id:"$id") { id, name { lang value }, quays { id publicCode }}}""" - assertResponse(executeGraphqQLQueryOnly(query), "stopPlaceByQuayRef") + String quayId = "NSR:Quay:494"; + String expectedStopPlaceId = "NSR:StopPlace:301" + String query = """ { stopPlaceByQuayRef(id:"$quayId") { id, name { lang value }, quays { id publicCode }}}""" + assertResponse(executeGraphqQLQueryOnly(query), "stopPlaceByQuayRef", expectedStopPlaceId) } - void assertResponse(ValidatableResponse rsp, String path) { - rsp.body("data. "+path+".id", equalTo("NSR:StopPlace:337")) + void assertResponse(ValidatableResponse rsp, String path, String expectedId) { + rsp.body("data. "+path+".id", equalTo(expectedId)) } } diff --git a/src/test/java/no/entur/uttu/UttuIntegrationTest.java b/src/test/java/no/entur/uttu/UttuIntegrationTest.java index eac0971c..39df8576 100644 --- a/src/test/java/no/entur/uttu/UttuIntegrationTest.java +++ b/src/test/java/no/entur/uttu/UttuIntegrationTest.java @@ -27,7 +27,7 @@ webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT, classes = UttuTestApp.class ) -@ActiveProfiles({ "google-pubsub-emulator", "test" }) +@ActiveProfiles({ "test" }) @EnableAspectJAutoProxy(proxyTargetClass = true) public abstract class UttuIntegrationTest { diff --git a/src/test/java/no/entur/uttu/UttuTestApp.java b/src/test/java/no/entur/uttu/UttuTestApp.java index 22f2873c..c49152d0 100644 --- a/src/test/java/no/entur/uttu/UttuTestApp.java +++ b/src/test/java/no/entur/uttu/UttuTestApp.java @@ -15,20 +15,15 @@ package no.entur.uttu; -import no.entur.uttu.ext.entur.organisation.EnturLegacyOrganisationRegistry; import no.entur.uttu.repository.generic.ProviderEntityRepositoryImpl; import no.entur.uttu.security.UttuSecurityConfiguration; -import no.entur.uttu.stopplace.DefaultStopPlaceRegistry; -import org.entur.pubsub.base.config.GooglePubSubConfig; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; import org.springframework.context.annotation.ComponentScan; import org.springframework.context.annotation.FilterType; -import org.springframework.context.annotation.Import; import org.springframework.data.jpa.repository.config.EnableJpaRepositories; @SpringBootApplication -@Import(GooglePubSubConfig.class) @EnableJpaRepositories( basePackages = { "no.entur.uttu.repository" }, repositoryBaseClass = ProviderEntityRepositoryImpl.class @@ -40,10 +35,6 @@ value = UttuSecurityConfiguration.class ), @ComponentScan.Filter(type = FilterType.ASSIGNABLE_TYPE, value = App.class), - @ComponentScan.Filter( - type = FilterType.ASSIGNABLE_TYPE, - value = DefaultStopPlaceRegistry.class - ), } ) public class UttuTestApp { diff --git a/src/test/java/no/entur/uttu/export/messaging/MessagingServiceTest.java b/src/test/java/no/entur/uttu/export/messaging/MessagingServiceTest.java deleted file mode 100644 index df1811d5..00000000 --- a/src/test/java/no/entur/uttu/export/messaging/MessagingServiceTest.java +++ /dev/null @@ -1,66 +0,0 @@ -/* - * Licensed under the EUPL, Version 1.2 or – as soon they will be approved by - * the European Commission - subsequent versions of the EUPL (the "Licence"); - * You may not use this work except in compliance with the Licence. - * You may obtain a copy of the Licence at: - * - * https://joinup.ec.europa.eu/software/page/eupl - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the Licence is distributed on an "AS IS" basis, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the Licence for the specific language governing permissions and - * limitations under the Licence. - * - */ - -package no.entur.uttu.export.messaging; - -import com.google.cloud.spring.pubsub.core.PubSubTemplate; -import com.google.pubsub.v1.PubsubMessage; -import java.nio.charset.StandardCharsets; -import java.util.List; -import no.entur.uttu.UttuIntegrationTest; -import org.entur.pubsub.base.EnturGooglePubSubAdmin; -import org.junit.Assert; -import org.junit.Test; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.beans.factory.annotation.Value; - -public class MessagingServiceTest extends UttuIntegrationTest { - - public static final String TEST_CODESPACE = "rut"; - - public static final String TEST_EXPORT_FILE_NAME = "netex.zip"; - - @Autowired - private MessagingService messagingService; - - @Autowired - private PubSubTemplate pubSubTemplate; - - @Autowired - private EnturGooglePubSubAdmin enturGooglePubSubAdmin; - - @Value("${export.notify.queue.name:FlexibleLinesExportQueue}") - private String queueName; - - @Test - public void testNotifyExport() { - enturGooglePubSubAdmin.createSubscriptionIfMissing(queueName); - - messagingService.notifyExport(TEST_CODESPACE, TEST_EXPORT_FILE_NAME); - - List messages = pubSubTemplate.pullAndAck(queueName, 1, false); - Assert.assertEquals(messages.size(), 1); - PubsubMessage pubsubMessage = messages.get(0); - String codespace = pubsubMessage - .getAttributesMap() - .get(PubSubMessagingService.HEADER_CHOUETTE_REFERENTIAL); - Assert.assertEquals("rb_" + TEST_CODESPACE, codespace); - Assert.assertEquals( - TEST_EXPORT_FILE_NAME, - pubsubMessage.getData().toString(StandardCharsets.UTF_8) - ); - } -} diff --git a/src/test/java/no/entur/uttu/stubs/StopPlaceRegistryStub.java b/src/test/java/no/entur/uttu/stubs/StopPlaceRegistryStub.java deleted file mode 100644 index a4bc1454..00000000 --- a/src/test/java/no/entur/uttu/stubs/StopPlaceRegistryStub.java +++ /dev/null @@ -1,58 +0,0 @@ -/* - * Licensed under the EUPL, Version 1.2 or – as soon they will be approved by - * the European Commission - subsequent versions of the EUPL (the "Licence"); - * You may not use this work except in compliance with the Licence. - * You may obtain a copy of the Licence at: - * - * https://joinup.ec.europa.eu/software/page/eupl - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the Licence is distributed on an "AS IS" basis, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the Licence for the specific language governing permissions and - * limitations under the Licence. - */ - -package no.entur.uttu.stubs; - -import java.io.FileInputStream; -import java.io.IOException; -import java.io.InputStream; -import java.util.Optional; -import no.entur.uttu.config.NetexHttpMessageConverter; -import no.entur.uttu.stopplace.StopPlaceRegistry; -import org.springframework.http.HttpHeaders; -import org.springframework.http.HttpInputMessage; -import org.springframework.stereotype.Component; - -@Component -public class StopPlaceRegistryStub implements StopPlaceRegistry { - - @Override - public Optional getStopPlaceByQuayRef( - String quayRef - ) { - NetexHttpMessageConverter converter = new NetexHttpMessageConverter(); - - try { - org.rutebanken.netex.model.StopPlace stopPlace = - (org.rutebanken.netex.model.StopPlace) converter.read( - org.rutebanken.netex.model.StopPlace.class, - new HttpInputMessage() { - @Override - public InputStream getBody() throws IOException { - return new FileInputStream("src/test/resources/stopPlaceFixture.xml"); - } - - @Override - public HttpHeaders getHeaders() { - return HttpHeaders.EMPTY; - } - } - ); - return Optional.of(stopPlace); - } catch (IOException e) { - return Optional.empty(); - } - } -} diff --git a/src/test/resources/application-test.properties b/src/test/resources/application-test.properties index b0707aee..4aee3026 100644 --- a/src/test/resources/application-test.properties +++ b/src/test/resources/application-test.properties @@ -13,54 +13,23 @@ # limitations under the Licence. # -server.port=11701 -server.host=localhost - - -blobstore.gcs.container.name=internal - +# Configure database test container spring.jpa.database=POSTGRESQL spring.sql.init.platform=postgres spring.datasource.url=jdbc:tc:postgis:13-3.3:///uttu -# Enable notifications to Marduk when a new NeTex export is uploaded -export.notify.enabled=true -export.notify.queue.name=FlexibleLinesExportQueue - -spring.cloud.gcp.project-id=test -spring.cloud.gcp.pubsub.project-id=test -# Path to credential for accessing the Google Cloud project, using the Spring resource syntax (prefixed with file:) -#spring.cloud.gcp.pubsub.credentials.location=file:/path/to/json/file -# if this property is present then the client library connects to the PubSub emulator instead of Google Cloud -spring.cloud.gcp.pubsub.emulatorHost=localhost:8088 -# number of parallel pullers for a given Subscriber. Constrained by the number of threads in the executor. -spring.cloud.gcp.pubsub.subscriber.parallel-pull-count=1 -# number of executor threads (shared by all subscribers) -spring.cloud.gcp.pubsub.subscriber.executor-threads=30 -# the client library will automatically extend the ack deadline up to this limit. -spring.cloud.gcp.pubsub.subscriber.max-ack-extension-period=36000 -# number of threads performing ack deadline extension (shared by all subscribers). The default value is 5 -#entur.pubsub.subscriber.system-threads=5 -# path to Google PubSub emulator -# default path if the property is not set (retrieved as a Maven dependency): -#entur.pubsub.emulator.path=target/pubsub-emulator/pubsub-emulator-0.1-SNAPSHOT.jar - - -#OAuth2 Resource Server -uttu.oauth2.resourceserver.auth0.ror.jwt.audience=https://notUsed -uttu.oauth2.resourceserver.auth0.ror.claim.namespace=https://notUsed - - -spring.security.oauth2.client.provider.orgregister.token-uri=https://notUsed -spring.security.oauth2.client.registration.orgregister.client-id=foo -spring.security.oauth2.client.registration.orgregister.client-secret=bar -spring.security.oauth2.client.registration.orgregister.authorization-grant-type=client_credentials -orgregister.oauth2.client.audience=https://notUsed - -# Monitoring +# Monitoring endpoints turned off in tests management.endpoints.enabled-by-default=false management.health.pubsub.enabled=false management.endpoints.web.exposure.exclude=* management.endpoints.jmx.exposure.exclude=* +# This property is needed, but should probably be renamed +blobstore.gcs.container.name=internal + +# Integrations with fixtures uttu.organisations.netex-file-uri=src/test/resources/fixtures/organisations.xml +uttu.stopplace.netex-file-uri=src/test/resources/fixtures/stopplaces.xml + +# This property is needed to avoid pubsub autoconfiguration +spring.cloud.gcp.pubsub.enabled=false diff --git a/src/test/resources/fixtures/stopplaces.xml b/src/test/resources/fixtures/stopplaces.xml new file mode 100644 index 00000000..dde2b32b --- /dev/null +++ b/src/test/resources/fixtures/stopplaces.xml @@ -0,0 +1,780 @@ + + + + + + + Oslo S + + + + 10.753276 + 59.910925 + + + + unknown + + + true + true + unknown + unknown + unknown + + + + + + + + both + + + + + true + true + + + + + true + 17 + + false + + + + + + rail + + + + + + + + + railStation + preferredInterchange + + + + + grails-platformId + 6170 + + + uicCode + 7600100 + + + imported-id + NSB:Quay:760010015,LIN:Quay:007600100 + + + tpsiId + 760010015 + + + 15 + + + 10.754734 + 59.910123 + + + + 15 + + + + + grails-platformId + 6157 + + + uicCode + 7600100 + + + imported-id + NSB:Quay:0076001002 + + + tpsiId + 760010002 + + + 2 + + + 10.755594 + 59.911022 + + + + 2 + + + + + grails-platformId + 6160 + + + uicCode + 7600100 + + + imported-id + NSB:Quay:0076001005 + + + tpsiId + 760010005 + + + 5 + + + 10.755399 + 59.910818 + + + + 5 + + + + + grails-platformId + 6162 + + + uicCode + 7600100 + + + imported-id + NSB:Quay:0076001007 + + + tpsiId + 760010007 + + + 7 + + + 10.755264 + 59.910677 + + + + 7 + + + + + grails-platformId + 6161 + + + uicCode + 7600100 + + + imported-id + NSB:Quay:0076001006 + + + tpsiId + 760010006 + + + 6 + + + 10.755326 + 59.910741 + + + + 6 + + + + + grails-platformId + 6166 + + + uicCode + 7600100 + + + imported-id + NSB:Quay:00760010011 + + + tpsiId + 760010011 + + + 11 + + + 10.754999 + 59.910400 + + + + 11 + + + + + grails-platformId + 6171 + + + uicCode + 7600100 + + + imported-id + NSB:Quay:00760010016 + + + tpsiId + 760010016 + + + 16 + + + 10.754663 + 59.910049 + + + + 16 + + + + + grails-platformId + 6168 + + + uicCode + 7600100 + + + imported-id + NSB:Quay:00760010013 + + + tpsiId + 760010013 + + + 13 + + + 10.754866 + 59.910261 + + + + 13 + + + + + grails-platformId + 6169 + + + uicCode + 7600100 + + + imported-id + NSB:Quay:00760010014 + + + tpsiId + 760010014 + + + 14 + + + 10.754798 + 59.910189 + + + + 14 + + + + + grails-platformId + 6164 + + + uicCode + 7600100 + + + imported-id + NSB:Quay:0076001009 + + + tpsiId + 760010009 + + + 9 + + + 10.755133 + 59.910540 + + + + 9 + + + + + grails-platformId + 6163 + + + uicCode + 7600100 + + + imported-id + NSB:Quay:0076001008 + + + tpsiId + 760010008 + + + 8 + + + 10.755195 + 59.910605 + + + + 8 + + + + + grails-platformId + 6159 + + + uicCode + 7600100 + + + imported-id + NSB:Quay:0076001004 + + + tpsiId + 760010004 + + + 4 + + + 10.755461 + 59.910882 + + + + 4 + + + + + grails-platformId + 6174 + + + uicCode + 7600100 + + + imported-id + NSB:Quay:00760010019 + + + tpsiId + 760010019 + + + 19 + + + 10.754467 + 59.909844 + + + + 19 + + + + + grails-platformId + 6172 + + + uicCode + 7600100 + + + imported-id + NSB:Quay:00760010017 + + + tpsiId + 760010017 + + + 17 + + + 10.754599 + 59.909982 + + + + 17 + + + + + grails-platformId + 6167 + + + uicCode + 7600100 + + + imported-id + NSB:Quay:00760010012 + + + tpsiId + 760010012 + + + 12 + + + 10.754926 + 59.910324 + + + + 12 + + + + + grails-platformId + 6158 + + + uicCode + 7600100 + + + imported-id + NSB:Quay:0076001003 + + + tpsiId + 760010003 + + + 3 + + + 10.755531 + 59.910956 + + + + 3 + + + + + grails-platformId + 6173 + + + uicCode + 7600100 + + + imported-id + NSB:Quay:00760010018 + + + tpsiId + 760010018 + + + 18 + + + 10.754527 + 59.909906 + + + + 18 + + + + + grails-platformId + 6165 + + + uicCode + 7600100 + + + imported-id + NSB:Quay:00760010010 + + + tpsiId + 760010010 + + + 10 + + + 10.755060 + 59.910464 + + + + 10 + + + + + grails-platformId + 6156 + + + uicCode + 7600100 + + + TPSI-Kode + 760010001 + + + imported-id + FLT:Quay:007600100,NSB:Quay:0076001001,NSB:Quay:076001001,NSB:Quay:007600100,FLT:Quay:7600100 + + + tpsiId + 760010001 + + + 1 + + + 10.755664 + 59.911095 + + + + 1 + + + + +