From de4773c7a86f062ffbde92c5a576cf3674dedb6d Mon Sep 17 00:00:00 2001 From: Cato Olsen Date: Wed, 27 Nov 2024 14:15:23 +0100 Subject: [PATCH 01/14] Endrer loglevel fra INFO til TRACE for "Setter opp proxy host". (#3680) --- .../testnorge/profil/consumer/AzureAdProfileConsumer.java | 2 +- .../testnorge/profil/service/AzureAdTokenService.java | 2 +- .../testnav/libs/reactivesecurity/decoder/JwtDecoder.java | 2 +- .../exchange/azuread/AzureAdTokenService.java | 2 +- .../exchange/azuread/NavAzureAdTokenService.java | 2 +- .../exchange/azuread/TrygdeetatenAzureAdTokenService.java | 2 +- .../servletsecurity/exchange/AzureAdTokenService.java | 2 +- .../libs/servletsecurity/exchange/AzureAdTokenService.java | 2 +- .../no/nav/testnav/libs/slack/consumer/SlackConsumer.java | 6 +++--- 9 files changed, 11 insertions(+), 11 deletions(-) diff --git a/apps/profil-api/src/main/java/no/nav/registre/testnorge/profil/consumer/AzureAdProfileConsumer.java b/apps/profil-api/src/main/java/no/nav/registre/testnorge/profil/consumer/AzureAdProfileConsumer.java index c04d1c7b48d..7f5a0341fc3 100644 --- a/apps/profil-api/src/main/java/no/nav/registre/testnorge/profil/consumer/AzureAdProfileConsumer.java +++ b/apps/profil-api/src/main/java/no/nav/registre/testnorge/profil/consumer/AzureAdProfileConsumer.java @@ -41,7 +41,7 @@ public AzureAdProfileConsumer( .build()); if (proxyHost != null) { - log.info("Setter opp proxy host {} for Azure Ad", proxyHost); + log.trace("Setter opp proxy host {} for Azure Ad", proxyHost); var uri = URI.create(proxyHost); builder.clientConnector(new ReactorClientHttpConnector( HttpClient diff --git a/apps/profil-api/src/main/java/no/nav/registre/testnorge/profil/service/AzureAdTokenService.java b/apps/profil-api/src/main/java/no/nav/registre/testnorge/profil/service/AzureAdTokenService.java index 05437f60338..07cbc158beb 100644 --- a/apps/profil-api/src/main/java/no/nav/registre/testnorge/profil/service/AzureAdTokenService.java +++ b/apps/profil-api/src/main/java/no/nav/registre/testnorge/profil/service/AzureAdTokenService.java @@ -40,7 +40,7 @@ public AzureAdTokenService( .defaultHeader(HttpHeaders.CONTENT_TYPE, MediaType.APPLICATION_FORM_URLENCODED_VALUE); if (proxyHost != null) { - log.info("Setter opp proxy host {} for Client Credentials", proxyHost); + log.trace("Setter opp proxy host {} for Client Credentials", proxyHost); var uri = URI.create(proxyHost); builder.clientConnector(new ReactorClientHttpConnector( HttpClient diff --git a/libs/reactive-security/src/main/java/no/nav/testnav/libs/reactivesecurity/decoder/JwtDecoder.java b/libs/reactive-security/src/main/java/no/nav/testnav/libs/reactivesecurity/decoder/JwtDecoder.java index 335f81e629d..061985f9b41 100644 --- a/libs/reactive-security/src/main/java/no/nav/testnav/libs/reactivesecurity/decoder/JwtDecoder.java +++ b/libs/reactive-security/src/main/java/no/nav/testnav/libs/reactivesecurity/decoder/JwtDecoder.java @@ -46,7 +46,7 @@ public ReactiveJwtDecoder jwtDecoder() { private WebClient buildProxyWebClient(String proxyHost) { var builder = WebClient.builder(); if (proxyHost != null) { - log.info("Setter opp proxy host {} for jwt decoder.", proxyHost); + log.trace("Setter opp proxy host {} for jwt decoder.", proxyHost); var uri = URI.create(proxyHost); builder.clientConnector(new ReactorClientHttpConnector( HttpClient diff --git a/libs/reactive-security/src/main/java/no/nav/testnav/libs/reactivesecurity/exchange/azuread/AzureAdTokenService.java b/libs/reactive-security/src/main/java/no/nav/testnav/libs/reactivesecurity/exchange/azuread/AzureAdTokenService.java index 7568c51cf61..e65534dcfde 100644 --- a/libs/reactive-security/src/main/java/no/nav/testnav/libs/reactivesecurity/exchange/azuread/AzureAdTokenService.java +++ b/libs/reactive-security/src/main/java/no/nav/testnav/libs/reactivesecurity/exchange/azuread/AzureAdTokenService.java @@ -50,7 +50,7 @@ public AzureAdTokenService( .defaultHeader(HttpHeaders.CONTENT_TYPE, MediaType.APPLICATION_FORM_URLENCODED_VALUE); if (proxyHost != null) { - log.info("Setter opp proxy host {} for Client Credentials", proxyHost); + log.trace("Setter opp proxy host {} for Client Credentials", proxyHost); var uri = URI.create(proxyHost); builder.clientConnector(new ReactorClientHttpConnector( HttpClient diff --git a/libs/reactive-security/src/main/java/no/nav/testnav/libs/reactivesecurity/exchange/azuread/NavAzureAdTokenService.java b/libs/reactive-security/src/main/java/no/nav/testnav/libs/reactivesecurity/exchange/azuread/NavAzureAdTokenService.java index fbc95f64d17..2800db0654c 100644 --- a/libs/reactive-security/src/main/java/no/nav/testnav/libs/reactivesecurity/exchange/azuread/NavAzureAdTokenService.java +++ b/libs/reactive-security/src/main/java/no/nav/testnav/libs/reactivesecurity/exchange/azuread/NavAzureAdTokenService.java @@ -39,7 +39,7 @@ public NavAzureAdTokenService( .defaultHeader(HttpHeaders.CONTENT_TYPE, MediaType.APPLICATION_FORM_URLENCODED_VALUE); if (proxyHost != null) { - log.info("Setter opp proxy host {} for Client Credentials", proxyHost); + log.trace("Setter opp proxy host {} for Client Credentials", proxyHost); var uri = URI.create(proxyHost); HttpClient httpClient = HttpClient .create() diff --git a/libs/reactive-security/src/main/java/no/nav/testnav/libs/reactivesecurity/exchange/azuread/TrygdeetatenAzureAdTokenService.java b/libs/reactive-security/src/main/java/no/nav/testnav/libs/reactivesecurity/exchange/azuread/TrygdeetatenAzureAdTokenService.java index 4fbaf171d02..c1a8adb73b2 100644 --- a/libs/reactive-security/src/main/java/no/nav/testnav/libs/reactivesecurity/exchange/azuread/TrygdeetatenAzureAdTokenService.java +++ b/libs/reactive-security/src/main/java/no/nav/testnav/libs/reactivesecurity/exchange/azuread/TrygdeetatenAzureAdTokenService.java @@ -56,7 +56,7 @@ public TrygdeetatenAzureAdTokenService( .defaultHeader(HttpHeaders.CONTENT_TYPE, MediaType.APPLICATION_FORM_URLENCODED_VALUE); if (nonNull(proxyHost)) { - log.info("Setter opp proxy host {} for Client Credentials", proxyHost); + log.trace("Setter opp proxy host {} for Client Credentials", proxyHost); var uri = URI.create(proxyHost); builder.clientConnector(new ReactorClientHttpConnector( HttpClient diff --git a/libs/servlet-insecure-security/src/main/java/no/nav/testnav/libs/standalone/servletsecurity/exchange/AzureAdTokenService.java b/libs/servlet-insecure-security/src/main/java/no/nav/testnav/libs/standalone/servletsecurity/exchange/AzureAdTokenService.java index adc99f711f6..00696ba6667 100644 --- a/libs/servlet-insecure-security/src/main/java/no/nav/testnav/libs/standalone/servletsecurity/exchange/AzureAdTokenService.java +++ b/libs/servlet-insecure-security/src/main/java/no/nav/testnav/libs/standalone/servletsecurity/exchange/AzureAdTokenService.java @@ -37,7 +37,7 @@ public AzureAdTokenService( .defaultHeader(HttpHeaders.CONTENT_TYPE, MediaType.APPLICATION_FORM_URLENCODED_VALUE); if (proxyHost != null) { - log.info("Setter opp proxy host {} for Client Credentials", proxyHost); + log.trace("Setter opp proxy host {} for Client Credentials", proxyHost); var uri = URI.create(proxyHost); builder.clientConnector(new ReactorClientHttpConnector( HttpClient diff --git a/libs/servlet-security/src/main/java/no/nav/testnav/libs/servletsecurity/exchange/AzureAdTokenService.java b/libs/servlet-security/src/main/java/no/nav/testnav/libs/servletsecurity/exchange/AzureAdTokenService.java index 1c2924e99ae..f6323dcb5fc 100644 --- a/libs/servlet-security/src/main/java/no/nav/testnav/libs/servletsecurity/exchange/AzureAdTokenService.java +++ b/libs/servlet-security/src/main/java/no/nav/testnav/libs/servletsecurity/exchange/AzureAdTokenService.java @@ -45,7 +45,7 @@ public AzureAdTokenService( .defaultHeader(HttpHeaders.CONTENT_TYPE, MediaType.APPLICATION_FORM_URLENCODED_VALUE); if (proxyHost != null) { - log.info("Setter opp proxy host {} for Client Credentials", proxyHost); + log.trace("Setter opp proxy host {} for Client Credentials", proxyHost); var uri = URI.create(proxyHost); builder.clientConnector(new ReactorClientHttpConnector( HttpClient diff --git a/libs/slack/src/main/java/no/nav/testnav/libs/slack/consumer/SlackConsumer.java b/libs/slack/src/main/java/no/nav/testnav/libs/slack/consumer/SlackConsumer.java index 33766e4735e..6f15c0edbfa 100644 --- a/libs/slack/src/main/java/no/nav/testnav/libs/slack/consumer/SlackConsumer.java +++ b/libs/slack/src/main/java/no/nav/testnav/libs/slack/consumer/SlackConsumer.java @@ -28,7 +28,7 @@ public SlackConsumer( this.token = token; this.applicationName = applicationName; if (proxyHost != null) { - log.info("Setter opp proxy host {} for Slack api", proxyHost); + log.trace("Setter opp proxy host {} for Slack api", proxyHost); var uri = URI.create(proxyHost); webClientBuilder.clientConnector(new ReactorClientHttpConnector( HttpClient @@ -47,7 +47,7 @@ public SlackConsumer( public void publish(Message message) { log.info("Publiserer melding til slack."); SlackResponse response = new PublishMessageCommand(webClient, token, message).call(); - if (!response.getOk()) { + if (!Boolean.TRUE.equals(response.getOk())) { throw new SlackConsumerException("Klarer ikke aa opprette slack melding", response); } } @@ -55,7 +55,7 @@ public void publish(Message message) { public void uploadFile(byte[] file, String fileName, String channel) { log.info("Publiserer fil til slack."); SlackResponse response = new UploadFileCommand(webClient, token, file, fileName, channel, applicationName).call(); - if (!response.getOk()) { + if (!Boolean.TRUE.equals(response.getOk())) { throw new SlackConsumerException("Klarer ikke aa opprette slack melding", response); } } From de9bc7ede5017e003db9843b1a4b5cf86b70da83 Mon Sep 17 00:00:00 2001 From: Stian Gustavsson Date: Wed, 27 Nov 2024 15:01:36 +0100 Subject: [PATCH 02/14] Ny sykemelding proxy (#3679) - Lagt til sykemelding-proxy --- .github/workflows/proxy.sykemelding-proxy.yml | 23 +++ proxies/sykemelding-proxy/Dockerfile | 8 + proxies/sykemelding-proxy/build.gradle | 18 ++ proxies/sykemelding-proxy/config.yml | 74 +++++++ .../gradle/wrapper/gradle-wrapper.jar | Bin 0 -> 59203 bytes .../gradle/wrapper/gradle-wrapper.properties | 5 + proxies/sykemelding-proxy/gradlew | 185 ++++++++++++++++++ proxies/sykemelding-proxy/gradlew.bat | 89 +++++++++ proxies/sykemelding-proxy/settings.gradle | 19 ++ .../proxies/sykemeldingproxy/Consumers.java | 22 +++ .../sykemeldingproxy/RouteLocatorConfig.java | 48 +++++ .../sykemeldingproxy/StatusController.java | 64 ++++++ .../SykemeldingProxyApplicationStarter.java | 15 ++ .../src/main/resources/application.yml | 37 ++++ .../src/main/resources/logback-spring.xml | 41 ++++ .../RouteLocatorConfigTest.java | 68 +++++++ .../src/test/resources/application-test.yml | 4 + 17 files changed, 720 insertions(+) create mode 100644 .github/workflows/proxy.sykemelding-proxy.yml create mode 100644 proxies/sykemelding-proxy/Dockerfile create mode 100644 proxies/sykemelding-proxy/build.gradle create mode 100644 proxies/sykemelding-proxy/config.yml create mode 100644 proxies/sykemelding-proxy/gradle/wrapper/gradle-wrapper.jar create mode 100644 proxies/sykemelding-proxy/gradle/wrapper/gradle-wrapper.properties create mode 100755 proxies/sykemelding-proxy/gradlew create mode 100644 proxies/sykemelding-proxy/gradlew.bat create mode 100644 proxies/sykemelding-proxy/settings.gradle create mode 100644 proxies/sykemelding-proxy/src/main/java/no/nav/testnav/proxies/sykemeldingproxy/Consumers.java create mode 100644 proxies/sykemelding-proxy/src/main/java/no/nav/testnav/proxies/sykemeldingproxy/RouteLocatorConfig.java create mode 100644 proxies/sykemelding-proxy/src/main/java/no/nav/testnav/proxies/sykemeldingproxy/StatusController.java create mode 100644 proxies/sykemelding-proxy/src/main/java/no/nav/testnav/proxies/sykemeldingproxy/SykemeldingProxyApplicationStarter.java create mode 100644 proxies/sykemelding-proxy/src/main/resources/application.yml create mode 100644 proxies/sykemelding-proxy/src/main/resources/logback-spring.xml create mode 100644 proxies/sykemelding-proxy/src/test/java/no/nav/testnav/proxies/sykemeldingproxy/RouteLocatorConfigTest.java create mode 100644 proxies/sykemelding-proxy/src/test/resources/application-test.yml diff --git a/.github/workflows/proxy.sykemelding-proxy.yml b/.github/workflows/proxy.sykemelding-proxy.yml new file mode 100644 index 00000000000..52ddc6f062c --- /dev/null +++ b/.github/workflows/proxy.sykemelding-proxy.yml @@ -0,0 +1,23 @@ +name: sykemelding-proxy + +on: + push: + paths: + - "plugins/**" + - "libs/reactive-core/**" + - "libs/reactive-proxy/**" + - "libs/security-token-service/**" + - "proxies/sykemelding-proxy/**" + - ".github/workflows/proxy.sykemelding-proxy.yml" + +jobs: + workflow: + uses: ./.github/workflows/common.workflow.backend.yml + with: + cluster: "dev-gcp" + working-directory: "proxies/sykemelding-proxy" + deploy-tag: "#deploy-proxy-sykemelding" + permissions: + contents: read + id-token: write + secrets: inherit diff --git a/proxies/sykemelding-proxy/Dockerfile b/proxies/sykemelding-proxy/Dockerfile new file mode 100644 index 00000000000..4a36f93546f --- /dev/null +++ b/proxies/sykemelding-proxy/Dockerfile @@ -0,0 +1,8 @@ +FROM ghcr.io/navikt/baseimages/temurin:21 +LABEL maintainer="Team Dolly" + +ENV JAVA_OPTS="-Dspring.profiles.active=prod" + +ADD /build/libs/app.jar /app/app.jar + +EXPOSE 8080 diff --git a/proxies/sykemelding-proxy/build.gradle b/proxies/sykemelding-proxy/build.gradle new file mode 100644 index 00000000000..748b5a264f1 --- /dev/null +++ b/proxies/sykemelding-proxy/build.gradle @@ -0,0 +1,18 @@ +plugins { + id "dolly-proxies" +} + +sonarqube { + properties { + property "sonar.projectKey", "testnav-sykemelding-proxy" + property "sonar.projectName", "testnav-sykemelding-proxy" + } +} + +dependencies { + implementation 'no.nav.testnav.libs:security-core' + implementation 'no.nav.testnav.libs:reactive-security' + implementation 'no.nav.testnav.libs:data-transfer-objects' + + testImplementation 'org.springframework.security:spring-security-test' +} diff --git a/proxies/sykemelding-proxy/config.yml b/proxies/sykemelding-proxy/config.yml new file mode 100644 index 00000000000..24dedf2a3d7 --- /dev/null +++ b/proxies/sykemelding-proxy/config.yml @@ -0,0 +1,74 @@ +--- +apiVersion: nais.io/v1 +kind: AzureAdApplication +metadata: + name: testnav-sykemelding-proxy-trygdeetaten + namespace: dolly + labels: + team: dolly +spec: + secretName: azure-trygdeetaten-testnav-sykemelding-proxy-trygdeetaten + secretKeyPrefix: "AZURE_TRYGDEETATEN" + tenant: trygdeetaten.no +--- +apiVersion: nais.io/v1alpha1 +kind: Application +metadata: + name: testnav-sykemelding-proxy + namespace: dolly + labels: + team: dolly +spec: + image: {{image}} + port: 8080 + tokenx: + enabled: true + azure: + application: + allowAllUsers: true + enabled: true + tenant: nav.no + accessPolicy: + inbound: + rules: + - application: team-dolly-lokal-app + - application: dolly-frontend + - application: dolly-idporten + - application: dolly-frontend-dev + - application: dolly-backend + - application: dolly-backend-dev + - application: testnav-oversikt-frontend + outbound: + rules: + - application: syfosmregler + namespace: teamsykmelding + liveness: + path: /internal/isAlive + initialDelay: 4 + periodSeconds: 5 + failureThreshold: 500 + observability: + logging: + destinations: + - id: elastic + autoInstrumentation: + enabled: true + runtime: java + readiness: + path: /internal/isReady + initialDelay: 4 + periodSeconds: 5 + failureThreshold: 500 + replicas: + min: 1 + max: 1 + resources: + requests: + cpu: 200m + memory: 1024Mi + limits: + memory: 2048Mi + envFrom: + - secret: azure-trygdeetaten-testnav-sykemelding-proxy-trygdeetaten + ingresses: + - "https://testnav-sykemelding-proxy.intern.dev.nav.no" \ No newline at end of file diff --git a/proxies/sykemelding-proxy/gradle/wrapper/gradle-wrapper.jar b/proxies/sykemelding-proxy/gradle/wrapper/gradle-wrapper.jar new file mode 100644 index 0000000000000000000000000000000000000000..e708b1c023ec8b20f512888fe07c5bd3ff77bb8f GIT binary patch literal 59203 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

K7UpUK$>l@ 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 E2O(~oYXATM literal 0 HcmV?d00001 diff --git a/proxies/sykemelding-proxy/gradle/wrapper/gradle-wrapper.properties b/proxies/sykemelding-proxy/gradle/wrapper/gradle-wrapper.properties new file mode 100644 index 00000000000..48c0a02ca41 --- /dev/null +++ b/proxies/sykemelding-proxy/gradle/wrapper/gradle-wrapper.properties @@ -0,0 +1,5 @@ +distributionBase=GRADLE_USER_HOME +distributionPath=wrapper/dists +distributionUrl=https\://services.gradle.org/distributions/gradle-8.7-bin.zip +zipStoreBase=GRADLE_USER_HOME +zipStorePath=wrapper/dists diff --git a/proxies/sykemelding-proxy/gradlew b/proxies/sykemelding-proxy/gradlew new file mode 100755 index 00000000000..4f906e0c811 --- /dev/null +++ b/proxies/sykemelding-proxy/gradlew @@ -0,0 +1,185 @@ +#!/usr/bin/env sh + +# +# Copyright 2015 the original author or authors. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# https://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# + +############################################################################## +## +## Gradle start up script for UN*X +## +############################################################################## + +# Attempt to set APP_HOME +# Resolve links: $0 may be a link +PRG="$0" +# Need this for relative symlinks. +while [ -h "$PRG" ] ; do + ls=`ls -ld "$PRG"` + link=`expr "$ls" : '.*-> \(.*\)$'` + if expr "$link" : '/.*' > /dev/null; then + PRG="$link" + else + PRG=`dirname "$PRG"`"/$link" + fi +done +SAVED="`pwd`" +cd "`dirname \"$PRG\"`/" >/dev/null +APP_HOME="`pwd -P`" +cd "$SAVED" >/dev/null + +APP_NAME="Gradle" +APP_BASE_NAME=`basename "$0"` + +# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. +DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"' + +# Use the maximum available, or set MAX_FD != -1 to use that value. +MAX_FD="maximum" + +warn () { + echo "$*" +} + +die () { + echo + echo "$*" + echo + exit 1 +} + +# OS specific support (must be 'true' or 'false'). +cygwin=false +msys=false +darwin=false +nonstop=false +case "`uname`" in + CYGWIN* ) + cygwin=true + ;; + Darwin* ) + darwin=true + ;; + MINGW* ) + msys=true + ;; + NONSTOP* ) + nonstop=true + ;; +esac + +CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar + + +# Determine the Java command to use to start the JVM. +if [ -n "$JAVA_HOME" ] ; then + if [ -x "$JAVA_HOME/jre/sh/java" ] ; then + # IBM's JDK on AIX uses strange locations for the executables + JAVACMD="$JAVA_HOME/jre/sh/java" + else + JAVACMD="$JAVA_HOME/bin/java" + fi + if [ ! -x "$JAVACMD" ] ; then + die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME + +Please set the JAVA_HOME variable in your environment to match the +location of your Java installation." + fi +else + JAVACMD="java" + which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. + +Please set the JAVA_HOME variable in your environment to match the +location of your Java installation." +fi + +# Increase the maximum file descriptors if we can. +if [ "$cygwin" = "false" -a "$darwin" = "false" -a "$nonstop" = "false" ] ; then + MAX_FD_LIMIT=`ulimit -H -n` + if [ $? -eq 0 ] ; then + if [ "$MAX_FD" = "maximum" -o "$MAX_FD" = "max" ] ; then + MAX_FD="$MAX_FD_LIMIT" + fi + ulimit -n $MAX_FD + if [ $? -ne 0 ] ; then + warn "Could not set maximum file descriptor limit: $MAX_FD" + fi + else + warn "Could not query maximum file descriptor limit: $MAX_FD_LIMIT" + fi +fi + +# For Darwin, add options to specify how the application appears in the dock +if $darwin; then + GRADLE_OPTS="$GRADLE_OPTS \"-Xdock:name=$APP_NAME\" \"-Xdock:icon=$APP_HOME/media/gradle.icns\"" +fi + +# For Cygwin or MSYS, switch paths to Windows format before running java +if [ "$cygwin" = "true" -o "$msys" = "true" ] ; then + APP_HOME=`cygpath --path --mixed "$APP_HOME"` + CLASSPATH=`cygpath --path --mixed "$CLASSPATH"` + + JAVACMD=`cygpath --unix "$JAVACMD"` + + # We build the pattern for arguments to be converted via cygpath + ROOTDIRSRAW=`find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null` + SEP="" + for dir in $ROOTDIRSRAW ; do + ROOTDIRS="$ROOTDIRS$SEP$dir" + SEP="|" + done + OURCYGPATTERN="(^($ROOTDIRS))" + # Add a user-defined pattern to the cygpath arguments + if [ "$GRADLE_CYGPATTERN" != "" ] ; then + OURCYGPATTERN="$OURCYGPATTERN|($GRADLE_CYGPATTERN)" + fi + # Now convert the arguments - kludge to limit ourselves to /bin/sh + i=0 + for arg in "$@" ; do + CHECK=`echo "$arg"|egrep -c "$OURCYGPATTERN" -` + CHECK2=`echo "$arg"|egrep -c "^-"` ### Determine if an option + + if [ $CHECK -ne 0 ] && [ $CHECK2 -eq 0 ] ; then ### Added a condition + eval `echo args$i`=`cygpath --path --ignore --mixed "$arg"` + else + eval `echo args$i`="\"$arg\"" + fi + i=`expr $i + 1` + done + case $i in + 0) set -- ;; + 1) set -- "$args0" ;; + 2) set -- "$args0" "$args1" ;; + 3) set -- "$args0" "$args1" "$args2" ;; + 4) set -- "$args0" "$args1" "$args2" "$args3" ;; + 5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;; + 6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;; + 7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;; + 8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;; + 9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;; + esac +fi + +# Escape application args +save () { + for i do printf %s\\n "$i" | sed "s/'/'\\\\''/g;1s/^/'/;\$s/\$/' \\\\/" ; done + echo " " +} +APP_ARGS=`save "$@"` + +# Collect all arguments for the java command, following the shell quoting and substitution rules +eval set -- $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS "\"-Dorg.gradle.appname=$APP_BASE_NAME\"" -classpath "\"$CLASSPATH\"" org.gradle.wrapper.GradleWrapperMain "$APP_ARGS" + +exec "$JAVACMD" "$@" diff --git a/proxies/sykemelding-proxy/gradlew.bat b/proxies/sykemelding-proxy/gradlew.bat new file mode 100644 index 00000000000..107acd32c4e --- /dev/null +++ b/proxies/sykemelding-proxy/gradlew.bat @@ -0,0 +1,89 @@ +@rem +@rem Copyright 2015 the original author or authors. +@rem +@rem Licensed under the Apache License, Version 2.0 (the "License"); +@rem you may not use this file except in compliance with the License. +@rem You may obtain a copy of the License at +@rem +@rem https://www.apache.org/licenses/LICENSE-2.0 +@rem +@rem Unless required by applicable law or agreed to in writing, software +@rem distributed under the License is distributed on an "AS IS" BASIS, +@rem WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +@rem See the License for the specific language governing permissions and +@rem limitations under the License. +@rem + +@if "%DEBUG%" == "" @echo off +@rem ########################################################################## +@rem +@rem Gradle startup script for Windows +@rem +@rem ########################################################################## + +@rem Set local scope for the variables with windows NT shell +if "%OS%"=="Windows_NT" setlocal + +set DIRNAME=%~dp0 +if "%DIRNAME%" == "" set DIRNAME=. +set APP_BASE_NAME=%~n0 +set APP_HOME=%DIRNAME% + +@rem Resolve any "." and ".." in APP_HOME to make it shorter. +for %%i in ("%APP_HOME%") do set APP_HOME=%%~fi + +@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. +set DEFAULT_JVM_OPTS="-Xmx64m" "-Xms64m" + +@rem Find java.exe +if defined JAVA_HOME goto findJavaFromJavaHome + +set JAVA_EXE=java.exe +%JAVA_EXE% -version >NUL 2>&1 +if "%ERRORLEVEL%" == "0" goto execute + +echo. +echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. +echo. +echo Please set the JAVA_HOME variable in your environment to match the +echo location of your Java installation. + +goto fail + +:findJavaFromJavaHome +set JAVA_HOME=%JAVA_HOME:"=% +set JAVA_EXE=%JAVA_HOME%/bin/java.exe + +if exist "%JAVA_EXE%" goto execute + +echo. +echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME% +echo. +echo Please set the JAVA_HOME variable in your environment to match the +echo location of your Java installation. + +goto fail + +:execute +@rem Setup the command line + +set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar + + +@rem Execute Gradle +"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %* + +:end +@rem End local scope for the variables with windows NT shell +if "%ERRORLEVEL%"=="0" goto mainEnd + +:fail +rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of +rem the _cmd.exe /c_ return code! +if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1 +exit /b 1 + +:mainEnd +if "%OS%"=="Windows_NT" endlocal + +:omega diff --git a/proxies/sykemelding-proxy/settings.gradle b/proxies/sykemelding-proxy/settings.gradle new file mode 100644 index 00000000000..18362b8a55b --- /dev/null +++ b/proxies/sykemelding-proxy/settings.gradle @@ -0,0 +1,19 @@ +plugins { + id "com.gradle.develocity" version "3.17.4" +} + +rootProject.name = 'sykemelding-proxy' + +includeBuild "../../plugins/java" + +includeBuild '../../libs/data-transfer-objects' +includeBuild '../../libs/reactive-core' +includeBuild '../../libs/reactive-proxy' +includeBuild '../../libs/security-token-service' + +develocity { + buildScan { + termsOfUseUrl = "https://gradle.com/terms-of-service" + termsOfUseAgree = "yes" + } +} diff --git a/proxies/sykemelding-proxy/src/main/java/no/nav/testnav/proxies/sykemeldingproxy/Consumers.java b/proxies/sykemelding-proxy/src/main/java/no/nav/testnav/proxies/sykemeldingproxy/Consumers.java new file mode 100644 index 00000000000..ebbf535055a --- /dev/null +++ b/proxies/sykemelding-proxy/src/main/java/no/nav/testnav/proxies/sykemeldingproxy/Consumers.java @@ -0,0 +1,22 @@ +package no.nav.testnav.proxies.sykemeldingproxy; + +import lombok.Getter; +import lombok.NoArgsConstructor; +import lombok.Setter; +import org.springframework.boot.context.properties.ConfigurationProperties; +import org.springframework.context.annotation.Configuration; + +import no.nav.testnav.libs.securitycore.domain.ServerProperties; + +import static lombok.AccessLevel.PACKAGE; + +@Configuration +@ConfigurationProperties(prefix = "consumers") +@NoArgsConstructor(access = PACKAGE) +@Getter +@Setter(PACKAGE) +public class Consumers { + + private ServerProperties sykemelding; + +} diff --git a/proxies/sykemelding-proxy/src/main/java/no/nav/testnav/proxies/sykemeldingproxy/RouteLocatorConfig.java b/proxies/sykemelding-proxy/src/main/java/no/nav/testnav/proxies/sykemeldingproxy/RouteLocatorConfig.java new file mode 100644 index 00000000000..fa2c69e5228 --- /dev/null +++ b/proxies/sykemelding-proxy/src/main/java/no/nav/testnav/proxies/sykemeldingproxy/RouteLocatorConfig.java @@ -0,0 +1,48 @@ +package no.nav.testnav.proxies.sykemeldingproxy; + +import no.nav.testnav.libs.reactiveproxy.config.SecurityConfig; +import no.nav.testnav.libs.reactiveproxy.filter.AddAuthenticationRequestGatewayFilterFactory; +import no.nav.testnav.libs.reactivesecurity.config.SecureOAuth2ServerToServerConfiguration; +import no.nav.testnav.libs.reactivesecurity.exchange.azuread.TrygdeetatenAzureAdTokenService; +import no.nav.testnav.libs.securitycore.domain.AccessToken; +import org.springframework.cloud.gateway.filter.GatewayFilter; +import org.springframework.cloud.gateway.route.RouteLocator; +import org.springframework.cloud.gateway.route.builder.RouteLocatorBuilder; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import org.springframework.context.annotation.Import; + +@Import({ + SecureOAuth2ServerToServerConfiguration.class, + SecurityConfig.class +}) +@Configuration +public class RouteLocatorConfig { + + @Bean + public RouteLocator customRouteLocator( + RouteLocatorBuilder builder, + Consumers consumers, + GatewayFilter authenticationFilter + ) { + return builder + .routes() + .route(spec -> spec + .path("/**") + .filters(f -> f.filter(authenticationFilter)) + .uri(consumers.getSykemelding().getUrl())) + .build(); + } + + @Bean + GatewayFilter getAuthenticationFilter( + TrygdeetatenAzureAdTokenService tokenService, + Consumers consumers + ) { + return AddAuthenticationRequestGatewayFilterFactory + .bearerAuthenticationHeaderFilter(() -> tokenService + .exchange(consumers.getSykemelding()) + .map(AccessToken::getTokenValue)); + } + +} diff --git a/proxies/sykemelding-proxy/src/main/java/no/nav/testnav/proxies/sykemeldingproxy/StatusController.java b/proxies/sykemelding-proxy/src/main/java/no/nav/testnav/proxies/sykemeldingproxy/StatusController.java new file mode 100644 index 00000000000..c0a87c7abb4 --- /dev/null +++ b/proxies/sykemelding-proxy/src/main/java/no/nav/testnav/proxies/sykemeldingproxy/StatusController.java @@ -0,0 +1,64 @@ +package no.nav.testnav.proxies.sykemeldingproxy; + +import no.nav.testnav.libs.dto.status.v1.TestnavStatusResponse; +import org.springframework.http.MediaType; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.RestController; +import org.springframework.web.reactive.function.client.WebClient; +import reactor.core.publisher.Mono; + +import java.util.Map; + +@RestController +public class StatusController { + private static final String TEAM = "Team sykmelding"; + + @GetMapping(value = "/internal/status", produces = MediaType.APPLICATION_JSON_VALUE) + public Map getStatus() { + var statusWebClient = WebClient.builder().build(); + + var status = checkConsumerStatus( + "http://syfosmregler.teamsykmelding" + "/internal/is_alive", + "http://syfosmregler.teamsykmelding" + "/internal/is_ready", + statusWebClient); + + return Map.of( + "syfosmregler", status + ); + } + + public TestnavStatusResponse checkConsumerStatus(String aliveUrl, String readyUrl, WebClient webClient) { + TestnavStatusResponse status = TestnavStatusResponse.builder().team(TEAM).build(); + + Thread blockingThread = new Thread(() -> { + status.setAlive( + checkStatus(webClient, aliveUrl) + .blockOptional() + .orElse("Error: Empty response") + ); + status.setReady( + checkStatus(webClient, readyUrl) + .blockOptional() + .orElse("Error: Empty response") + ); + }); + blockingThread.start(); + try { + blockingThread.join(); + } catch (InterruptedException e) { + Thread.currentThread().interrupt(); + } + + return status; + } + + private Mono checkStatus(WebClient webClient, String url) { + return webClient.get().uri(url) + .retrieve() + .bodyToMono(String.class) + .defaultIfEmpty("OK") + .onErrorResume(Exception.class, error -> Mono.just("Error: " + error.getMessage())) + .doOnSuccess(result -> Mono.just("OK")) + .map(result -> result.startsWith("Error:") ? result : "OK"); + } +} \ No newline at end of file diff --git a/proxies/sykemelding-proxy/src/main/java/no/nav/testnav/proxies/sykemeldingproxy/SykemeldingProxyApplicationStarter.java b/proxies/sykemelding-proxy/src/main/java/no/nav/testnav/proxies/sykemeldingproxy/SykemeldingProxyApplicationStarter.java new file mode 100644 index 00000000000..0b482c50274 --- /dev/null +++ b/proxies/sykemelding-proxy/src/main/java/no/nav/testnav/proxies/sykemeldingproxy/SykemeldingProxyApplicationStarter.java @@ -0,0 +1,15 @@ +package no.nav.testnav.proxies.sykemeldingproxy; + +import no.nav.testnav.libs.reactivecore.config.CoreConfig; +import org.springframework.boot.SpringApplication; +import org.springframework.boot.autoconfigure.SpringBootApplication; +import org.springframework.context.annotation.Import; + +@SpringBootApplication +@Import(CoreConfig.class) +public class SykemeldingProxyApplicationStarter { + + public static void main(String[] args) { + SpringApplication.run(SykemeldingProxyApplicationStarter.class, args); + } +} diff --git a/proxies/sykemelding-proxy/src/main/resources/application.yml b/proxies/sykemelding-proxy/src/main/resources/application.yml new file mode 100644 index 00000000000..e6753ab77f1 --- /dev/null +++ b/proxies/sykemelding-proxy/src/main/resources/application.yml @@ -0,0 +1,37 @@ +AAD_ISSUER_URI: https://login.microsoftonline.com/62366534-1ec3-4962-8869-9b5535279d0b + +spring: + application: + name: testnav-sykemelding-proxy + description: Proxy for sykemelding. + security: + oauth2: + resourceserver: + aad: + issuer-uri: ${AAD_ISSUER_URI}/v2.0 + jwk-set-uri: ${AAD_ISSUER_URI}/discovery/v2.0/keys + accepted-audience: ${azure.app.client.id}, api://${azure.app.client.id} + tokenx: + issuer-uri: ${TOKEN_X_ISSUER} + jwk-set-uri: ${TOKEN_X_JWKS_URI} + accepted-audience: ${TOKEN_X_CLIENT_ID} + cloud: + vault: + enabled: false + gateway: + httpclient: + response-timeout: 30s + +server: + servlet: + encoding: + charset: UTF-8 + error: + include-message: always + +consumers: + sykemelding: + name: syfosmregler + namespace: teamsykmelding + url: http://syfosmregler.teamsykmelding.svc.cluster.local + cluster: dev-gcp diff --git a/proxies/sykemelding-proxy/src/main/resources/logback-spring.xml b/proxies/sykemelding-proxy/src/main/resources/logback-spring.xml new file mode 100644 index 00000000000..2b55a41c62f --- /dev/null +++ b/proxies/sykemelding-proxy/src/main/resources/logback-spring.xml @@ -0,0 +1,41 @@ + + + + + + + true + + 10280 + 20 + ^sun\.reflect\..*\.invoke + ^net\.sf\.cglib\.proxy\.MethodProxy\.invoke + java\.util\.concurrent\..* + org\.apache\.catalina\..* + org\.apache\.coyote\..* + org\.apache\.tomcat\..* + + + + + + + + + + + + + %d{HH:mm:ss.SSS} | %5p | %logger{25} | %m%n + + utf8 + + + + + + + + + + \ No newline at end of file diff --git a/proxies/sykemelding-proxy/src/test/java/no/nav/testnav/proxies/sykemeldingproxy/RouteLocatorConfigTest.java b/proxies/sykemelding-proxy/src/test/java/no/nav/testnav/proxies/sykemeldingproxy/RouteLocatorConfigTest.java new file mode 100644 index 00000000000..a66ef3eb492 --- /dev/null +++ b/proxies/sykemelding-proxy/src/test/java/no/nav/testnav/proxies/sykemeldingproxy/RouteLocatorConfigTest.java @@ -0,0 +1,68 @@ +package no.nav.testnav.proxies.sykemeldingproxy; + +import org.junit.jupiter.api.Test; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.test.autoconfigure.web.reactive.AutoConfigureWebTestClient; +import org.springframework.boot.test.context.SpringBootTest; +import org.springframework.boot.test.context.TestConfiguration; +import org.springframework.cloud.contract.wiremock.AutoConfigureWireMock; +import org.springframework.cloud.gateway.filter.GatewayFilter; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Primary; +import org.springframework.http.HttpHeaders; +import org.springframework.http.HttpStatus; +import org.springframework.http.MediaType; +import org.springframework.test.context.ActiveProfiles; +import org.springframework.test.web.reactive.server.WebTestClient; + +import static com.github.tomakehurst.wiremock.client.WireMock.*; +import static org.springframework.security.test.web.reactive.server.SecurityMockServerConfigurers.mockOAuth2Login; + +@SpringBootTest( + webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT, + properties = "consumers.sykemelding.url=http://localhost:${wiremock.server.port}" +) +@AutoConfigureWireMock(port = 0) +@AutoConfigureWebTestClient +@ActiveProfiles("test") +class RouteLocatorConfigTest { + + @Autowired + private WebTestClient webClient; + + @TestConfiguration + static class TestAuthenticationConfig { + + @Primary + @Bean + GatewayFilter getNoopAuthenticationFilter() { + return (exchange, chain) -> chain.filter(exchange); + + } + + } + + @Test + void shouldRouteToStub() { + + stubFor( + get(urlEqualTo("/testing/route")) + .willReturn( + aResponse() + .withStatus(HttpStatus.OK.value()) + .withHeader(HttpHeaders.CONTENT_TYPE, MediaType.TEXT_PLAIN_VALUE) + .withBody("Some content") + ) + ); + + webClient + .mutateWith(mockOAuth2Login()) + .get().uri("/testing/route") + .exchange() + .expectStatus().isOk() + .expectHeader().contentType(MediaType.TEXT_PLAIN_VALUE) + .expectBody(String.class).isEqualTo("Some content"); + + } + +} diff --git a/proxies/sykemelding-proxy/src/test/resources/application-test.yml b/proxies/sykemelding-proxy/src/test/resources/application-test.yml new file mode 100644 index 00000000000..f77593af929 --- /dev/null +++ b/proxies/sykemelding-proxy/src/test/resources/application-test.yml @@ -0,0 +1,4 @@ +TOKEN_X_ISSUER: dummy +proxy.url: http://localhost +STS_TOKEN_PROVIDER_USERNAME: dummy +STS_TOKEN_PROVIDER_PASSWORD: dummy \ No newline at end of file From ea26d4c8d75a8518064276174d1a37c343fd6ddc Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Kristen=20H=C3=A6rum?= Date: Thu, 28 Nov 2024 15:04:30 +0100 Subject: [PATCH 03/14] Feature/sykemelding forbedre status tilbakemelding (#3681) * Refactor exception handling and update sykemelding responses Replaced custom exceptions with ResponseStatusException for better HTTP response handling. Updated service and controller methods to return SykemeldningResponseDTO for more informative responses. Added SykemeldningResponseDTO class in the DTO library. * Refactor exception handling in SykemeldingConsumer Replaced custom exceptions with ResponseStatusException to standardize error handling across the application. Modified relevant unit tests and command logic to align with this change. * Add test and prod configurations for sykemelding API #deploy-test-sykemelding-api Created a new `config-test.yml` for the development environment and a new `application-prod.yml` for the production environment. Updated the Dockerfile and workflow to support these configurations, including enabling TokenX for production. * Rename config-test.yml to config.test.yml #deploy-test-sykemelding-api This change standardizes the naming convention for configuration files. It ensures consistency across the project and simplifies future maintenance. * Add SPRING_PROFILES_ACTIVE env variable to configs #deploy-test-sykemelding-api This commit introduces the SPRING_PROFILES_ACTIVE environment variable to the test and production configuration files. It sets the value to 'dev' for the test environment and 'prod' for the production environment to ensure appropriate profile activation. * Change profile annotation for LocalVaultConfig #deploy-test-sykemelding-api Updated the @Profile annotation from "dev" to "local" in LocalVaultConfig class. This change ensures that the configuration is applied only when the "local" profile is active. * Refactor profiles and update URLs for local and dev environments #deploy-test-synt-sykemelding-api #deploy-test-sykemelding-api Updated the configuration to differentiate between 'local' and 'dev' profiles, ensuring appropriate URL endpoints for each environment. This includes changes in the OAuth2 setup, Spring profiles, and Dockerfile adjustments. Added new configuration files to support "prod" and "local" environments. * Add new application to proxy config #deploy-pdl-proxy Included the testnav-synt-sykemelding-api-dev application under the dev-gcp cluster in the proxy configuration file. This change ensures proper routing and access for the new development environment. * Add test environment configs for synt-sykemelding-api-dev #deploy-test-dolly-backend #deploy-arbeidsforhold-service Added new application entries for 'testnav-synt-sykemelding-api-dev' in both arbeidsforhold-service and dolly-backend configuration files. This change ensures the new environment is recognized and integrated into the existing test setup. * Add testnav-synt-sykemelding-api-dev to config file #deploy-organisasjon-service Updated the configurational dependencies to include the new application testnav-synt-sykemelding-api-dev. This change is necessary for the development environment setup and ensures that all relevant services are listed for proper integration. * Update logging config for dev and local profiles #deploy-test-sykemelding-api #deploy-test-synt-sykemelding-api Expanded the "prod" profile to include "dev" for consistent logging and changed "dev" to "local" to better differentiate environments. This will improve clarity and maintainability of the logging configuration. * Update application-local.yaml with sykemelding API dev config Renamed 'testnav-synt-sykemelding-api' to 'testnav-synt-sykemelding-api-dev' and added 'testnav-pdl-forvalter-dev' name. This ensures proper configuration for the development environment. * Refactor sykemelding classes and fix DTO typo #deploy-test-dolly-backend #deploy-test-sykemelding-api #deploy-test-synt-sykemelding-api Refactored the Sykemelding classes to use a new response DTO and improved logging for better traceability. Also corrected the typo in SykemeldingResponseDTO across the codebase, ensuring consistent naming conventions. Updated application URLs in the configuration files. * Remove unused logging and add new API configuration. #deploy-test-dolly-backend Eliminated unused logging of sykemelding response status for clarity and simplicity. Added configuration entries for testnav-sykemelding-api and testnav-synt-sykemelding-api to support new integrations. * Deploy #deploy-arbeidsforhold-service #deploy-helsepersonell-service * Update dependencies and API URLs for dev environment #deploy-test-sykemelding-api Changed SpringDoc dependency from webflux to webmvc in build.gradle to match project requirements. Also corrected the URL for the testnav-synt-sykemelding-api in the local configuration file. * Remove Avro schema dependencies #deploy-test-sykemelding-api Removed the inclusion of 'avro-schema' from both `settings.gradle` and `build.gradle`. The change involved eliminating related dependencies including Kafka clients and Avro serializers that are no longer required. * Add testnav-sykemelding-api-dev to config.test.yml #deploy-test-dolly-backend This commit updates the configuration file to include the testnav-sykemelding-api-dev application. This ensures that the application is recognized and properly configured during testing environments. * Add sykemeldingId for tracking submissions. #deploy-test-frontend Incorporated 'sykemeldingId' to enable tracking of sykemelding submissions in the components `SyntSykemelding.tsx` and `DetaljertSykemelding.tsx`. This enhancement allows for improved data traceability and management. Additionally, code formatting was refined for uniformity and clarity. * Reorder error message checks and fix sykemelding config #deploy-test-dolly-backend Reordered error message checks in ErrorStatusDecoder for more logical processing, checking for a 'message' before 'error'. Also corrected the configuration name for testnav-synt-sykemelding-api in application-local.yaml to ensure proper service references. * Refactor variable name for clarity in KodeverkGetCommand #deploy-test-dolly-backend Renamed the variable "kodeverk" to "kodeverket" to improve code clarity and consistency with naming conventions. This change ensures better understanding and readability of the code, reducing potential confusion during future developments or reviews. --- .github/workflows/app.sykemelding-api.yml | 1 + .../workflows/app.synt-sykemelding-api.yml | 1 + apps/arbeidsforhold-service/config.yml | 2 + .../ArbeidsforholdApiApplicationStarter.java | 2 +- apps/dolly-backend/config.test.yml | 2 + .../dolly/DollyBackendApplicationStarter.java | 2 +- .../sykemelding/SykemeldingClient.java | 1 + .../command/SykemeldingPostCommand.java | 10 +- .../command/SyntSykemeldingPostCommand.java | 8 +- .../sykemelding/dto/SykemeldingResponse.java | 2 + .../kodeverk/command/KodeverkGetCommand.java | 5 + .../errorhandling/ErrorStatusDecoder.java | 6 +- .../src/main/resources/application-dev.yaml | 6 + .../src/main/resources/application-local.yaml | 6 +- .../fagsystem/sykdom/visning/Visning.tsx | 210 +++++++++--------- .../visning/partials/DetaljertSykemelding.tsx | 205 +++++++++-------- .../visning/partials/SyntSykemelding.tsx | 4 + ...lsepersonellServiceApplicationStarter.java | 2 +- apps/organisasjon-service/config.yml | 1 + apps/sykemelding-api/Dockerfile | 2 - apps/sykemelding-api/build.gradle | 7 +- apps/sykemelding-api/config.test.yml | 74 ++++++ apps/sykemelding-api/config.yml | 3 + apps/sykemelding-api/settings.gradle | 1 - .../sykemelding/config/LocalVaultConfig.java | 2 +- .../sykemelding/consumer/SyfoConsumer.java | 12 +- .../provider/SykemeldingController.java | 18 +- .../service/SykemeldingService.java | 5 +- .../src/main/resources/application-prod.yml | 8 + .../src/main/resources/application.yml | 4 - .../src/main/resources/logback-spring.xml | 4 +- apps/synt-sykemelding-api/Dockerfile | 4 +- apps/synt-sykemelding-api/config.test.yml | 73 ++++++ apps/synt-sykemelding-api/config.yml | 3 + .../config/LocalVaultConfig.java | 2 +- .../consumer/HelsepersonellConsumer.java | 5 +- .../consumer/PdlProxyConsumer.java | 7 +- .../consumer/SykemeldingConsumer.java | 7 +- .../consumer/SyntElsamConsumer.java | 5 +- .../command/PostSykemeldingCommand.java | 18 +- .../command/PostSyntSykemeldingCommand.java | 5 +- .../GenererSykemeldingerException.java | 8 - .../HelsepersonellNotFoundException.java | 8 - .../exception/LagreSykemeldingException.java | 7 - .../exception/PdlPersonException.java | 8 - .../provider/SyntSykemeldingController.java | 28 +-- .../service/SykemeldingService.java | 7 +- .../src/main/resources/application-dev.yml | 20 +- .../src/main/resources/application-local.yml | 13 ++ .../src/main/resources/application-prod.yml | 8 + .../src/main/resources/application.yml | 4 - .../src/main/resources/logback-spring.xml | 4 +- .../consumer/SykemeldingConsumerTest.java | 16 +- .../v1/SykemeldingResponseDTO.java | 17 ++ libs/reactive-proxy/package-lock.json | 6 + proxies/pdl-proxy/config.yml | 2 + 56 files changed, 563 insertions(+), 338 deletions(-) create mode 100644 apps/sykemelding-api/config.test.yml create mode 100644 apps/sykemelding-api/src/main/resources/application-prod.yml create mode 100644 apps/synt-sykemelding-api/config.test.yml delete mode 100644 apps/synt-sykemelding-api/src/main/java/no/nav/testnav/apps/syntsykemeldingapi/exception/GenererSykemeldingerException.java delete mode 100644 apps/synt-sykemelding-api/src/main/java/no/nav/testnav/apps/syntsykemeldingapi/exception/HelsepersonellNotFoundException.java delete mode 100644 apps/synt-sykemelding-api/src/main/java/no/nav/testnav/apps/syntsykemeldingapi/exception/LagreSykemeldingException.java delete mode 100644 apps/synt-sykemelding-api/src/main/java/no/nav/testnav/apps/syntsykemeldingapi/exception/PdlPersonException.java create mode 100644 apps/synt-sykemelding-api/src/main/resources/application-local.yml create mode 100644 apps/synt-sykemelding-api/src/main/resources/application-prod.yml create mode 100644 libs/data-transfer-objects/src/main/java/no/nav/testnav/libs/dto/sykemelding/v1/SykemeldingResponseDTO.java create mode 100644 libs/reactive-proxy/package-lock.json diff --git a/.github/workflows/app.sykemelding-api.yml b/.github/workflows/app.sykemelding-api.yml index 13b32b61caa..10a312277dc 100644 --- a/.github/workflows/app.sykemelding-api.yml +++ b/.github/workflows/app.sykemelding-api.yml @@ -17,6 +17,7 @@ jobs: cluster: "dev-gcp" working-directory: "apps/sykemelding-api" deploy-tag: "#deploy-sykemelding-api" + deploy-tag-test: "#deploy-test-sykemelding-api" permissions: contents: read id-token: write diff --git a/.github/workflows/app.synt-sykemelding-api.yml b/.github/workflows/app.synt-sykemelding-api.yml index a9dd896a2d1..fa1c0105f66 100644 --- a/.github/workflows/app.synt-sykemelding-api.yml +++ b/.github/workflows/app.synt-sykemelding-api.yml @@ -19,6 +19,7 @@ jobs: with: working-directory: "apps/synt-sykemelding-api" deploy-tag: "#deploy-synt-sykemelding-api" + deploy-tag-test: "#deploy-test-synt-sykemelding-api" permissions: contents: read id-token: write diff --git a/apps/arbeidsforhold-service/config.yml b/apps/arbeidsforhold-service/config.yml index 553ffc6f0b4..f5ead086d9d 100644 --- a/apps/arbeidsforhold-service/config.yml +++ b/apps/arbeidsforhold-service/config.yml @@ -28,6 +28,8 @@ spec: cluster: dev-gcp - application: testnav-synt-sykemelding-api cluster: dev-gcp + - application: testnav-synt-sykemelding-api-dev + cluster: dev-gcp outbound: external: - host: testnav-aareg-proxy.dev-fss-pub.nais.io diff --git a/apps/arbeidsforhold-service/src/main/java/no/nav/registre/testnorge/arbeidsforholdservice/ArbeidsforholdApiApplicationStarter.java b/apps/arbeidsforhold-service/src/main/java/no/nav/registre/testnorge/arbeidsforholdservice/ArbeidsforholdApiApplicationStarter.java index 5afc9f4e4fa..575e1cf149b 100644 --- a/apps/arbeidsforhold-service/src/main/java/no/nav/registre/testnorge/arbeidsforholdservice/ArbeidsforholdApiApplicationStarter.java +++ b/apps/arbeidsforhold-service/src/main/java/no/nav/registre/testnorge/arbeidsforholdservice/ArbeidsforholdApiApplicationStarter.java @@ -9,4 +9,4 @@ public class ArbeidsforholdApiApplicationStarter { public static void main(String[] args) { SpringApplication.run(ArbeidsforholdApiApplicationStarter.class, args); } -} \ No newline at end of file +} diff --git a/apps/dolly-backend/config.test.yml b/apps/dolly-backend/config.test.yml index c99e52ac2e3..ed956306f6d 100644 --- a/apps/dolly-backend/config.test.yml +++ b/apps/dolly-backend/config.test.yml @@ -39,7 +39,9 @@ spec: - application: testnav-person-service - application: testnav-skattekort-service - application: testnav-sykemelding-api + - application: testnav-sykemelding-api-dev - application: testnav-synt-sykemelding-api + - application: testnav-synt-sykemelding-api-dev - application: testnav-tps-messaging-service - application: testnav-yrkesskade-proxy - application: testnorge-profil-api-dev diff --git a/apps/dolly-backend/src/main/java/no/nav/dolly/DollyBackendApplicationStarter.java b/apps/dolly-backend/src/main/java/no/nav/dolly/DollyBackendApplicationStarter.java index 6af8668f777..f0ef428e58d 100644 --- a/apps/dolly-backend/src/main/java/no/nav/dolly/DollyBackendApplicationStarter.java +++ b/apps/dolly-backend/src/main/java/no/nav/dolly/DollyBackendApplicationStarter.java @@ -10,4 +10,4 @@ public static void main(String[] args) { SpringApplication.run(DollyBackendApplicationStarter.class, args); } -} \ No newline at end of file +} diff --git a/apps/dolly-backend/src/main/java/no/nav/dolly/bestilling/sykemelding/SykemeldingClient.java b/apps/dolly-backend/src/main/java/no/nav/dolly/bestilling/sykemelding/SykemeldingClient.java index c7714481e7c..07980a32425 100644 --- a/apps/dolly-backend/src/main/java/no/nav/dolly/bestilling/sykemelding/SykemeldingClient.java +++ b/apps/dolly-backend/src/main/java/no/nav/dolly/bestilling/sykemelding/SykemeldingClient.java @@ -188,6 +188,7 @@ private void saveTransaksjonId(SykemeldingResponse sykemelding, Long bestillingI log.info("Lagrer transaksjon for {} i q1 ", sykemelding.getIdent()); + sykemelding.getSykemeldingRequest().setSykemeldingId(sykemelding.getMsgId()); transaksjonMappingService.save(TransaksjonMapping.builder() .ident(sykemelding.getIdent()) .bestillingId(bestillingId) diff --git a/apps/dolly-backend/src/main/java/no/nav/dolly/bestilling/sykemelding/command/SykemeldingPostCommand.java b/apps/dolly-backend/src/main/java/no/nav/dolly/bestilling/sykemelding/command/SykemeldingPostCommand.java index 06549e69549..14877f9a865 100644 --- a/apps/dolly-backend/src/main/java/no/nav/dolly/bestilling/sykemelding/command/SykemeldingPostCommand.java +++ b/apps/dolly-backend/src/main/java/no/nav/dolly/bestilling/sykemelding/command/SykemeldingPostCommand.java @@ -1,12 +1,13 @@ package no.nav.dolly.bestilling.sykemelding.command; import lombok.RequiredArgsConstructor; +import lombok.extern.slf4j.Slf4j; import no.nav.dolly.bestilling.sykemelding.domain.DetaljertSykemeldingRequest; import no.nav.dolly.bestilling.sykemelding.dto.SykemeldingResponse; +import no.nav.testnav.libs.dto.sykemelding.v1.SykemeldingResponseDTO; import no.nav.testnav.libs.reactivecore.utils.WebClientFilter; import no.nav.testnav.libs.securitycore.config.UserConstant; import org.springframework.http.HttpHeaders; -import org.springframework.http.HttpStatus; import org.springframework.web.reactive.function.client.WebClient; import reactor.core.publisher.Mono; import reactor.util.retry.Retry; @@ -16,6 +17,7 @@ import static no.nav.dolly.util.TokenXUtil.getUserJwt; +@Slf4j @RequiredArgsConstructor public class SykemeldingPostCommand implements Callable> { @@ -35,10 +37,10 @@ public Mono call() { .header(UserConstant.USER_HEADER_JWT, getUserJwt()) .bodyValue(request) .retrieve() - .toBodilessEntity() - .timeout(Duration.ofMinutes(4)) + .bodyToMono(SykemeldingResponseDTO.class) .map(response -> SykemeldingResponse.builder() - .status(HttpStatus.valueOf(response.getStatusCode().value())) + .status(response.getStatus()) + .msgId(response.getSykemeldingId()) .ident(request.getPasient().getIdent()) .sykemeldingRequest(SykemeldingResponse.SykemeldingRequest.builder() .detaljertSykemeldingRequest(request) diff --git a/apps/dolly-backend/src/main/java/no/nav/dolly/bestilling/sykemelding/command/SyntSykemeldingPostCommand.java b/apps/dolly-backend/src/main/java/no/nav/dolly/bestilling/sykemelding/command/SyntSykemeldingPostCommand.java index 2b781fa2dc8..fcbfd4b5dac 100644 --- a/apps/dolly-backend/src/main/java/no/nav/dolly/bestilling/sykemelding/command/SyntSykemeldingPostCommand.java +++ b/apps/dolly-backend/src/main/java/no/nav/dolly/bestilling/sykemelding/command/SyntSykemeldingPostCommand.java @@ -3,10 +3,10 @@ import lombok.RequiredArgsConstructor; import no.nav.dolly.bestilling.sykemelding.domain.SyntSykemeldingRequest; import no.nav.dolly.bestilling.sykemelding.dto.SykemeldingResponse; +import no.nav.testnav.libs.dto.sykemelding.v1.SykemeldingResponseDTO; import no.nav.testnav.libs.reactivecore.utils.WebClientFilter; import no.nav.testnav.libs.securitycore.config.UserConstant; import org.springframework.http.HttpHeaders; -import org.springframework.http.HttpStatus; import org.springframework.web.reactive.function.client.WebClient; import reactor.core.publisher.Mono; import reactor.util.retry.Retry; @@ -34,10 +34,10 @@ public Mono call() { .header(UserConstant.USER_HEADER_JWT, getUserJwt()) .bodyValue(sykemeldingRequest) .retrieve() - .toBodilessEntity() - .timeout(Duration.ofMinutes(4)) + .bodyToMono(SykemeldingResponseDTO.class) .map(response -> SykemeldingResponse.builder() - .status(HttpStatus.valueOf(response.getStatusCode().value())) + .status(response.getStatus()) + .msgId(response.getSykemeldingId()) .ident(sykemeldingRequest.getIdent()) .sykemeldingRequest(SykemeldingResponse.SykemeldingRequest.builder() .syntSykemeldingRequest(sykemeldingRequest) diff --git a/apps/dolly-backend/src/main/java/no/nav/dolly/bestilling/sykemelding/dto/SykemeldingResponse.java b/apps/dolly-backend/src/main/java/no/nav/dolly/bestilling/sykemelding/dto/SykemeldingResponse.java index 9126e4bff3c..2575ecc536c 100644 --- a/apps/dolly-backend/src/main/java/no/nav/dolly/bestilling/sykemelding/dto/SykemeldingResponse.java +++ b/apps/dolly-backend/src/main/java/no/nav/dolly/bestilling/sykemelding/dto/SykemeldingResponse.java @@ -18,6 +18,7 @@ public class SykemeldingResponse { private HttpStatus status; private String avvik; private SykemeldingRequest sykemeldingRequest; + private String msgId; private String ident; @Data @@ -27,6 +28,7 @@ public class SykemeldingResponse { @JsonInclude(JsonInclude.Include.NON_EMPTY) public static class SykemeldingRequest { + private String sykemeldingId; private SyntSykemeldingRequest syntSykemeldingRequest; private DetaljertSykemeldingRequest detaljertSykemeldingRequest; } diff --git a/apps/dolly-backend/src/main/java/no/nav/dolly/consumer/kodeverk/command/KodeverkGetCommand.java b/apps/dolly-backend/src/main/java/no/nav/dolly/consumer/kodeverk/command/KodeverkGetCommand.java index 91b2382e5cb..d2466162e2e 100644 --- a/apps/dolly-backend/src/main/java/no/nav/dolly/consumer/kodeverk/command/KodeverkGetCommand.java +++ b/apps/dolly-backend/src/main/java/no/nav/dolly/consumer/kodeverk/command/KodeverkGetCommand.java @@ -4,6 +4,7 @@ import no.nav.testnav.libs.dto.kodeverkservice.v1.KodeverkDTO; import no.nav.testnav.libs.reactivecore.utils.WebClientFilter; import org.springframework.http.HttpHeaders; +import org.springframework.http.HttpStatus; import org.springframework.web.reactive.function.client.WebClient; import reactor.core.publisher.Mono; import reactor.util.retry.Retry; @@ -31,6 +32,10 @@ public Mono call() { .header(HttpHeaders.AUTHORIZATION, "Bearer " + token) .retrieve() .bodyToMono(KodeverkDTO.class) + .map(kodeverket -> { + kodeverket.setStatus(HttpStatus.OK); + return kodeverket; + }) .doOnError(WebClientFilter::logErrorMessage) .onErrorResume(error -> Mono.just(KodeverkDTO.builder() .kodeverknavn(kodeverk) diff --git a/apps/dolly-backend/src/main/java/no/nav/dolly/errorhandling/ErrorStatusDecoder.java b/apps/dolly-backend/src/main/java/no/nav/dolly/errorhandling/ErrorStatusDecoder.java index 893a8f55d12..466a74505e3 100644 --- a/apps/dolly-backend/src/main/java/no/nav/dolly/errorhandling/ErrorStatusDecoder.java +++ b/apps/dolly-backend/src/main/java/no/nav/dolly/errorhandling/ErrorStatusDecoder.java @@ -102,10 +102,10 @@ public String getStatusMessage(String json) { if (json.contains("{")) { try { Map status = objectMapper.readValue(json, Map.class); - if (status.containsKey(ERROR) && isNotBlank((String) status.get(ERROR))) { - builder.append("error=").append(status.get(ERROR)).append("; "); - } else if (status.containsKey(MESSAGE) && isNotBlank((String) status.get(MESSAGE))) { + if (status.containsKey(MESSAGE) && isNotBlank((String) status.get(MESSAGE))) { builder.append("message=").append(encodeStatus((String) status.get(MESSAGE))).append("; "); + } else if (status.containsKey(ERROR) && isNotBlank((String) status.get(ERROR))) { + builder.append("error=").append(status.get(ERROR)).append("; "); } else if (status.containsKey(MELDING) && isNotBlank((String) status.get(MELDING))) { builder.append(encodeStatus((String) status.get(MELDING))); } else if (status.containsKey(DETAILS) && status.get(DETAILS) instanceof List) { diff --git a/apps/dolly-backend/src/main/resources/application-dev.yaml b/apps/dolly-backend/src/main/resources/application-dev.yaml index 6bef737e63a..a64b00aaada 100644 --- a/apps/dolly-backend/src/main/resources/application-dev.yaml +++ b/apps/dolly-backend/src/main/resources/application-dev.yaml @@ -22,3 +22,9 @@ consumers: testnav-pdl-forvalter: name: testnav-pdl-forvalter-dev url: http://testnav-pdl-forvalter-dev.dolly.svc.cluster.local + testnav-sykemelding-api: + name: testnav-sykemelding-api-dev + url: http://testnav-sykemelding-api-dev.dolly.svc.cluster.local + testnav-synt-sykemelding-api: + name: testnav-synt-sykemelding-api-dev + url: http://testnav-synt-sykemelding-api-dev.dolly.svc.cluster.local \ No newline at end of file diff --git a/apps/dolly-backend/src/main/resources/application-local.yaml b/apps/dolly-backend/src/main/resources/application-local.yaml index e4ec31e8b75..72fb6260486 100644 --- a/apps/dolly-backend/src/main/resources/application-local.yaml +++ b/apps/dolly-backend/src/main/resources/application-local.yaml @@ -54,9 +54,11 @@ consumers: testnav-organisasjon-service: url: https://testnav-organisasjon-service.intern.dev.nav.no testnav-synt-sykemelding-api: - url: https://testnav-synt-sykemelding-api.intern.dev.nav.no + name: testnav-synt-sykemelding-api-dev + url: https://testnav-synt-sykemelding-api-dev.intern.dev.nav.no testnav-sykemelding-api: - url: http://testnav-sykemelding-api.intern.dev.nav.no + name: testnav-sykemelding-api-dev + url: https://testnav-sykemelding-api-dev.intern.dev.nav.no testnav-miljoer-service: url: https://testnav-miljoer-service.intern.dev.nav.no testnav-arbeidsplassencv-proxy: diff --git a/apps/dolly-frontend/src/main/js/src/components/fagsystem/sykdom/visning/Visning.tsx b/apps/dolly-frontend/src/main/js/src/components/fagsystem/sykdom/visning/Visning.tsx index f21dc60938e..660ab7fe61f 100644 --- a/apps/dolly-frontend/src/main/js/src/components/fagsystem/sykdom/visning/Visning.tsx +++ b/apps/dolly-frontend/src/main/js/src/components/fagsystem/sykdom/visning/Visning.tsx @@ -1,119 +1,131 @@ import _ from 'lodash' import SubOverskrift from '@/components/ui/subOverskrift/SubOverskrift' -import { SyntSykemelding } from './partials/SyntSykemelding' -import { DetaljertSykemelding } from './partials/DetaljertSykemelding' -import { Sykemelding, SykemeldingDetaljert, SykemeldingSynt } from '../SykemeldingTypes' -import { erGyldig } from '@/components/transaksjonid/GyldigeBestillinger' -import { Alert } from '@navikt/ds-react' +import {SyntSykemelding} from './partials/SyntSykemelding' +import {DetaljertSykemelding} from './partials/DetaljertSykemelding' +import { + Sykemelding, + SykemeldingDetaljert, + SykemeldingSynt +} from '../SykemeldingTypes' +import {erGyldig} from '@/components/transaksjonid/GyldigeBestillinger' +import {Alert} from '@navikt/ds-react' import React from 'react' -import { MiljoTabs } from '@/components/ui/miljoTabs/MiljoTabs' -import { useBestilteMiljoer } from '@/utils/hooks/useBestilling' +import {MiljoTabs} from '@/components/ui/miljoTabs/MiljoTabs' +import {useBestilteMiljoer} from '@/utils/hooks/useBestilling' import Loading from '@/components/ui/loading/Loading' export const sjekkManglerSykemeldingData = (sykemeldingData) => { - return ( - !sykemeldingData || - sykemeldingData?.length < 1 || - sykemeldingData?.every((miljoData) => !miljoData.data) - ) + return ( + !sykemeldingData || + sykemeldingData?.length < 1 || + sykemeldingData?.every((miljoData) => !miljoData.data) + ) } export const sjekkManglerSykemeldingBestilling = (sykemeldingBestilling) => { - return !sykemeldingBestilling || sykemeldingBestilling?.length < 1 + return !sykemeldingBestilling || sykemeldingBestilling?.length < 1 } -const VisningAvBestilling = ({ bestillinger }) => { - if (!bestillinger) { - return null - } - - return bestillinger?.map((bestilling: SykemeldingSynt | SykemeldingDetaljert, idx: number) => { - if (!bestilling.erGjenopprettet) { - const syntSykemelding = _.get(bestilling, 'data.sykemelding.syntSykemelding') - const detaljertSykemelding = _.get(bestilling, 'data.sykemelding.detaljertSykemelding') - - return syntSykemelding ? ( - - ) : detaljertSykemelding ? ( - - ) : null - } - }) +const VisningAvBestilling = ({bestillinger}) => { + if (!bestillinger) { + return null + } + + return bestillinger?.map((bestilling: SykemeldingSynt | SykemeldingDetaljert, idx: number) => { + if (!bestilling.erGjenopprettet) { + const syntSykemelding = _.get(bestilling, 'data.sykemelding.syntSykemelding') + const detaljertSykemelding = _.get(bestilling, 'data.sykemelding.detaljertSykemelding') + + return syntSykemelding ? ( + + ) : detaljertSykemelding ? ( + + ) : null + } + }) } -const VisningAvTransaksjonsId = ({ data }) => { - if (!data) { - return null - } - - const syntSykemelding = _.get(data, 'syntSykemeldingRequest') - const detaljertSykemelding = _.get(data, 'detaljertSykemeldingRequest') - - return syntSykemelding ? ( - - ) : detaljertSykemelding ? ( - - ) : null +const VisningAvTransaksjonsId = ({data}) => { + if (!data) { + return null + } + + const syntSykemelding = _.get(data, 'syntSykemeldingRequest') + const detaljertSykemelding = _.get(data, 'detaljertSykemeldingRequest') + const sykemeldingId = _.get(data, 'sykemeldingId') + + if (syntSykemelding) { + syntSykemelding['sykemeldingId'] = sykemeldingId + return + } + if (detaljertSykemelding) { + detaljertSykemelding['sykemeldingId'] = sykemeldingId + return < DetaljertSykemelding sykemelding={detaljertSykemelding}/> + } } export const SykemeldingVisning = ({ - data, - loading, - bestillingIdListe, - tilgjengeligMiljoe, - bestillinger, -}: Sykemelding) => { - const { bestilteMiljoer } = useBestilteMiljoer(bestillingIdListe, 'SYKEMELDING') - - if (loading) { - return - } - - if (!data && !bestillinger) { - return null - } - - const manglerFagsystemData = - sjekkManglerSykemeldingData(data) && sjekkManglerSykemeldingBestilling(bestillinger) - - const miljoerMedData = data?.map((miljoData) => miljoData.data && miljoData.miljo) - const errorMiljoer = bestilteMiljoer?.filter((miljo) => !miljoerMedData?.includes(miljo)) - - const forsteMiljo = data?.find((miljoData) => miljoData?.data)?.miljo - - const filteredData = - tilgjengeligMiljoe && data?.filter((item) => tilgjengeligMiljoe.includes(item.miljo)) - - return ( -

- - {manglerFagsystemData ? ( - - Fant ikke sykemelding-data på person - - ) : sjekkManglerSykemeldingData(data) ? ( - - ) : ( - - - - )} -
- ) + data, + loading, + bestillingIdListe, + tilgjengeligMiljoe, + bestillinger, + }: Sykemelding) => { + const {bestilteMiljoer} = useBestilteMiljoer(bestillingIdListe, 'SYKEMELDING') + + if (loading) { + return + } + + if (!data && !bestillinger) { + return null + } + + const manglerFagsystemData = + sjekkManglerSykemeldingData(data) && sjekkManglerSykemeldingBestilling(bestillinger) + + const miljoerMedData = data?.map((miljoData) => miljoData.data && miljoData.miljo) + const errorMiljoer = bestilteMiljoer?.filter((miljo) => !miljoerMedData?.includes(miljo)) + + const forsteMiljo = data?.find((miljoData) => miljoData?.data)?.miljo + + const filteredData = + tilgjengeligMiljoe && data?.filter((item) => tilgjengeligMiljoe.includes(item.miljo)) + + return ( +
+ + {manglerFagsystemData ? ( + + Fant ikke sykemelding-data på person + + ) : sjekkManglerSykemeldingData(data) ? ( + + ) : ( + + + + )} +
+ ) } SykemeldingVisning.filterValues = (bestillinger: Array, ident: string) => { - if (!bestillinger) { - return null - } - - return bestillinger.filter( - (bestilling: any) => - bestilling.data?.sykemelding && erGyldig(bestilling.id, 'SYKEMELDING', ident), - ) + if (!bestillinger) { + return null + } + + return bestillinger.filter( + (bestilling: any) => + bestilling.data?.sykemelding && erGyldig(bestilling.id, 'SYKEMELDING', ident), + ) } diff --git a/apps/dolly-frontend/src/main/js/src/components/fagsystem/sykdom/visning/partials/DetaljertSykemelding.tsx b/apps/dolly-frontend/src/main/js/src/components/fagsystem/sykdom/visning/partials/DetaljertSykemelding.tsx index 68b98a77b40..4fe1c7172eb 100644 --- a/apps/dolly-frontend/src/main/js/src/components/fagsystem/sykdom/visning/partials/DetaljertSykemelding.tsx +++ b/apps/dolly-frontend/src/main/js/src/components/fagsystem/sykdom/visning/partials/DetaljertSykemelding.tsx @@ -1,100 +1,119 @@ import * as React from 'react' -import { formatStringDates, oversettBoolean } from '@/utils/DataFormatter' -import { TitleValue } from '@/components/ui/titleValue/TitleValue' -import { Bidiagnoser } from './Bidiagnoser' -import { Perioder } from './Perioder' -import { ArbeidKodeverk } from '@/config/kodeverk' -import { SykemeldingDetaljert } from '@/components/fagsystem/sykdom/SykemeldingTypes' +import {formatStringDates, oversettBoolean} from '@/utils/DataFormatter' +import {TitleValue} from '@/components/ui/titleValue/TitleValue' +import {Bidiagnoser} from './Bidiagnoser' +import {Perioder} from './Perioder' +import {ArbeidKodeverk} from '@/config/kodeverk' +import { + SykemeldingDetaljert +} from '@/components/fagsystem/sykdom/SykemeldingTypes' import styled from 'styled-components' export const SykemeldingKategori = styled.div` - width: 100%; - h4 { - margin-top: 5px; - margin-bottom: 15px; - } + width: 100%; + + h4 { + margin-top: 5px; + margin-bottom: 15px; + } ` -export const DetaljertSykemelding = ({ sykemelding, idx }: SykemeldingDetaljert) => { - return ( -
- -
- - - -
- <> - -

Diagnose

-
-
- - -
- - - <> - -

Helsepersonell

-
-
- - - - -
- - <> - -

Arbeidsgiver

-
-
- - - -
- - - <> - -

Detaljer

-
-
- - - - -
- -
-
- ) +export const DetaljertSykemelding = ({ + sykemelding, + idx + }: SykemeldingDetaljert) => { + console.log('sykemelding', sykemelding) + return ( +
+ +
+ + + +
+ <> + +

Diagnose

+
+
+ + +
+ + + <> + +

Helsepersonell

+
+
+ + + + +
+ + <> + +

Arbeidsgiver

+
+
+ + + +
+ + + <> + +

Detaljer

+
+
+ + + + + +
+ +
+
+ ) } diff --git a/apps/dolly-frontend/src/main/js/src/components/fagsystem/sykdom/visning/partials/SyntSykemelding.tsx b/apps/dolly-frontend/src/main/js/src/components/fagsystem/sykdom/visning/partials/SyntSykemelding.tsx index f67334cee4c..2c19e33f8b8 100644 --- a/apps/dolly-frontend/src/main/js/src/components/fagsystem/sykdom/visning/partials/SyntSykemelding.tsx +++ b/apps/dolly-frontend/src/main/js/src/components/fagsystem/sykdom/visning/partials/SyntSykemelding.tsx @@ -8,5 +8,9 @@ export const SyntSykemelding = ({ sykemelding, idx }: SykemeldingSynt) => ( + ) diff --git a/apps/helsepersonell-service/src/main/java/no/nav/registre/testnorge/helsepersonellservice/HelsepersonellServiceApplicationStarter.java b/apps/helsepersonell-service/src/main/java/no/nav/registre/testnorge/helsepersonellservice/HelsepersonellServiceApplicationStarter.java index aa032265a42..1a3041608b2 100644 --- a/apps/helsepersonell-service/src/main/java/no/nav/registre/testnorge/helsepersonellservice/HelsepersonellServiceApplicationStarter.java +++ b/apps/helsepersonell-service/src/main/java/no/nav/registre/testnorge/helsepersonellservice/HelsepersonellServiceApplicationStarter.java @@ -9,4 +9,4 @@ public class HelsepersonellServiceApplicationStarter { public static void main(String[] args) { SpringApplication.run(HelsepersonellServiceApplicationStarter.class, args); } -} \ No newline at end of file +} diff --git a/apps/organisasjon-service/config.yml b/apps/organisasjon-service/config.yml index 5fd5cef84b2..322487c6a0b 100644 --- a/apps/organisasjon-service/config.yml +++ b/apps/organisasjon-service/config.yml @@ -31,6 +31,7 @@ spec: - application: testnav-orgnummer-service - application: testnav-oversikt-frontend - application: testnav-synt-sykemelding-api + - application: testnav-synt-sykemelding-api-dev - application: testnorge-statisk-data-forvalter cluster: dev-fss outbound: diff --git a/apps/sykemelding-api/Dockerfile b/apps/sykemelding-api/Dockerfile index 4a36f93546f..89a589699dd 100644 --- a/apps/sykemelding-api/Dockerfile +++ b/apps/sykemelding-api/Dockerfile @@ -1,8 +1,6 @@ FROM ghcr.io/navikt/baseimages/temurin:21 LABEL maintainer="Team Dolly" -ENV JAVA_OPTS="-Dspring.profiles.active=prod" - ADD /build/libs/app.jar /app/app.jar EXPOSE 8080 diff --git a/apps/sykemelding-api/build.gradle b/apps/sykemelding-api/build.gradle index e7893d2c807..a41d620d9c0 100644 --- a/apps/sykemelding-api/build.gradle +++ b/apps/sykemelding-api/build.gradle @@ -10,7 +10,6 @@ sonarqube { } dependencies { - implementation "no.nav.testnav.libs:avro-schema" implementation "no.nav.testnav.libs:commands" implementation "no.nav.testnav.libs:data-transfer-objects" implementation "no.nav.testnav.libs:reactive-core" @@ -22,19 +21,15 @@ dependencies { implementation "org.springframework.boot:spring-boot-starter-web" implementation "org.springframework.boot:spring-boot-starter-security" - implementation "org.springdoc:springdoc-openapi-starter-webflux-ui:$versions.springdoc" + implementation "org.springdoc:springdoc-openapi-starter-webmvc-ui:$versions.springdoc" implementation "io.swagger.core.v3:swagger-annotations-jakarta:$versions.swagger" implementation "com.ibm.mq:mq-jms-spring-boot-starter:$versions.mq" - implementation "org.springframework.kafka:spring-kafka" implementation "jakarta.xml.bind:jakarta.xml.bind-api:$versions.jakartaXmlBindApi" implementation "jakarta.activation:jakarta.activation-api:$versions.jakartaActivation" implementation "org.glassfish.jaxb:jaxb-runtime:$versions.jaxb" implementation "com.fasterxml.jackson.dataformat:jackson-dataformat-xml" - implementation "org.apache.kafka:kafka-clients:$versions.apacheKafka" - implementation "io.confluent:kafka-avro-serializer:$versions.avro" - testImplementation "no.nav.testnav.libs:testing" testImplementation "org.springframework.security:spring-security-test" testImplementation "org.springframework.cloud:spring-cloud-contract-wiremock" diff --git a/apps/sykemelding-api/config.test.yml b/apps/sykemelding-api/config.test.yml new file mode 100644 index 00000000000..c22417b88ff --- /dev/null +++ b/apps/sykemelding-api/config.test.yml @@ -0,0 +1,74 @@ +apiVersion: "nais.io/v1alpha1" +kind: "Application" +metadata: + name: testnav-sykemelding-api-dev + namespace: dolly + labels: + team: dolly + annotations: + nginx.ingress.kubernetes.io/proxy-read-timeout: "600" + nginx.ingress.kubernetes.io/proxy-send-timeout: "600" + nginx.ingress.kubernetes.io/proxy-body-size: "512m" +spec: + webproxy: true + tokenx: + enabled: true + azure: + application: + allowAllUsers: true + enabled: true + tenant: nav.no + image: "{{image}}" + port: 8080 + liveness: + path: /internal/isAlive + initialDelay: 4 + periodSeconds: 5 + failureThreshold: 500 + observability: + logging: + destinations: + - id: elastic + autoInstrumentation: + enabled: true + runtime: java + readiness: + path: /internal/isReady + initialDelay: 4 + periodSeconds: 5 + failureThreshold: 500 + prometheus: + enabled: true + path: /internal/metrics + replicas: + min: 1 + max: 1 + envFrom: + - secret: dolly-sykemelding-mq + env: + - name: SPRING_PROFILES_ACTIVE + value: dev + resources: + requests: + cpu: 200m + memory: 4000Mi + limits: + memory: 5000Mi + accessPolicy: + inbound: + rules: + - application: dolly-backend + - application: dolly-backend-dev + - application: dolly-frontend + - application: dolly-frontend-dev + - application: dolly-idporten + - application: team-dolly-lokal-app + - application: testnav-oversikt-frontend + - application: testnav-synt-sykemelding-api-dev + outbound: + external: + - host: mqls04.preprod.local + ports: + - port: 1413 + ingresses: + - "https://testnav-sykemelding-api-dev.intern.dev.nav.no" \ No newline at end of file diff --git a/apps/sykemelding-api/config.yml b/apps/sykemelding-api/config.yml index bb498bac7a2..38ec28ef58a 100644 --- a/apps/sykemelding-api/config.yml +++ b/apps/sykemelding-api/config.yml @@ -45,6 +45,9 @@ spec: max: 1 envFrom: - secret: dolly-sykemelding-mq + env: + - name: SPRING_PROFILES_ACTIVE + value: prod resources: requests: cpu: 200m diff --git a/apps/sykemelding-api/settings.gradle b/apps/sykemelding-api/settings.gradle index 8caaf392e5b..4c0a23fa254 100644 --- a/apps/sykemelding-api/settings.gradle +++ b/apps/sykemelding-api/settings.gradle @@ -6,7 +6,6 @@ rootProject.name = 'sykemelding-api' includeBuild "../../plugins/java" -includeBuild '../../libs/avro-schema' includeBuild '../../libs/commands' includeBuild '../../libs/data-transfer-objects' includeBuild '../../libs/reactive-core' diff --git a/apps/sykemelding-api/src/main/java/no/nav/registre/testnorge/sykemelding/config/LocalVaultConfig.java b/apps/sykemelding-api/src/main/java/no/nav/registre/testnorge/sykemelding/config/LocalVaultConfig.java index c35a141e2f2..480a0aaedf3 100644 --- a/apps/sykemelding-api/src/main/java/no/nav/registre/testnorge/sykemelding/config/LocalVaultConfig.java +++ b/apps/sykemelding-api/src/main/java/no/nav/registre/testnorge/sykemelding/config/LocalVaultConfig.java @@ -5,6 +5,6 @@ import org.springframework.context.annotation.Profile; @Configuration -@Profile("dev") +@Profile("local") public class LocalVaultConfig extends AbstractLocalVaultConfiguration { } \ No newline at end of file diff --git a/apps/sykemelding-api/src/main/java/no/nav/registre/testnorge/sykemelding/consumer/SyfoConsumer.java b/apps/sykemelding-api/src/main/java/no/nav/registre/testnorge/sykemelding/consumer/SyfoConsumer.java index f9ad67d4ced..d121155f9df 100644 --- a/apps/sykemelding-api/src/main/java/no/nav/registre/testnorge/sykemelding/consumer/SyfoConsumer.java +++ b/apps/sykemelding-api/src/main/java/no/nav/registre/testnorge/sykemelding/consumer/SyfoConsumer.java @@ -2,7 +2,9 @@ import lombok.extern.slf4j.Slf4j; import no.nav.registre.testnorge.sykemelding.domain.Sykemelding; +import no.nav.testnav.libs.dto.sykemelding.v1.SykemeldingResponseDTO; import org.springframework.beans.factory.annotation.Value; +import org.springframework.http.HttpStatus; import org.springframework.jms.core.JmsTemplate; import org.springframework.stereotype.Component; @@ -17,10 +19,16 @@ public SyfoConsumer(JmsTemplate jmsTemplate, @Value("${syfo.queue.name}") String this.queueName = queueName; } - public void send(Sykemelding sykemelding) { - String xml = sykemelding.toXml(); + public SykemeldingResponseDTO send(Sykemelding sykemelding) { + + var xml = sykemelding.toXml(); log.info("Legger sykemelding på kø med MsgId {}\n{}", sykemelding.getMsgId(), sykemelding); jmsTemplate.send(queueName, session -> session.createTextMessage(xml)); log.trace(xml); + + return SykemeldingResponseDTO.builder() + .sykemeldingId(sykemelding.getMsgId()) + .status(HttpStatus.OK) + .build(); } } \ No newline at end of file diff --git a/apps/sykemelding-api/src/main/java/no/nav/registre/testnorge/sykemelding/provider/SykemeldingController.java b/apps/sykemelding-api/src/main/java/no/nav/registre/testnorge/sykemelding/provider/SykemeldingController.java index 7279719f55b..54a10649acc 100644 --- a/apps/sykemelding-api/src/main/java/no/nav/registre/testnorge/sykemelding/provider/SykemeldingController.java +++ b/apps/sykemelding-api/src/main/java/no/nav/registre/testnorge/sykemelding/provider/SykemeldingController.java @@ -1,18 +1,16 @@ package no.nav.registre.testnorge.sykemelding.provider; import lombok.RequiredArgsConstructor; -import org.springframework.http.HttpStatus; -import org.springframework.http.ResponseEntity; +import no.nav.registre.testnorge.sykemelding.domain.ApplicationInfo; +import no.nav.registre.testnorge.sykemelding.domain.Sykemelding; +import no.nav.registre.testnorge.sykemelding.service.SykemeldingService; +import no.nav.testnav.libs.dto.sykemelding.v1.SykemeldingDTO; +import no.nav.testnav.libs.dto.sykemelding.v1.SykemeldingResponseDTO; import org.springframework.web.bind.annotation.PostMapping; import org.springframework.web.bind.annotation.RequestBody; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RestController; -import no.nav.testnav.libs.dto.sykemelding.v1.SykemeldingDTO; -import no.nav.registre.testnorge.sykemelding.domain.ApplicationInfo; -import no.nav.registre.testnorge.sykemelding.domain.Sykemelding; -import no.nav.registre.testnorge.sykemelding.service.SykemeldingService; - @RestController @RequestMapping("/api/v1/sykemeldinger") @RequiredArgsConstructor @@ -22,8 +20,8 @@ public class SykemeldingController { private final ApplicationInfo applicationInfo; @PostMapping - public ResponseEntity create(@RequestBody SykemeldingDTO dto) { - service.send(new Sykemelding(dto, applicationInfo)); - return ResponseEntity.ok().build(); + public SykemeldingResponseDTO create(@RequestBody SykemeldingDTO dto) { + + return service.send(new Sykemelding(dto, applicationInfo)); } } diff --git a/apps/sykemelding-api/src/main/java/no/nav/registre/testnorge/sykemelding/service/SykemeldingService.java b/apps/sykemelding-api/src/main/java/no/nav/registre/testnorge/sykemelding/service/SykemeldingService.java index 0009eb98a9e..e8a9e4f2302 100644 --- a/apps/sykemelding-api/src/main/java/no/nav/registre/testnorge/sykemelding/service/SykemeldingService.java +++ b/apps/sykemelding-api/src/main/java/no/nav/registre/testnorge/sykemelding/service/SykemeldingService.java @@ -3,6 +3,7 @@ import lombok.RequiredArgsConstructor; import no.nav.registre.testnorge.sykemelding.consumer.SyfoConsumer; import no.nav.registre.testnorge.sykemelding.domain.Sykemelding; +import no.nav.testnav.libs.dto.sykemelding.v1.SykemeldingResponseDTO; import org.springframework.stereotype.Service; @Service @@ -10,8 +11,8 @@ public class SykemeldingService { private final SyfoConsumer syfoConsumer; - public void send(Sykemelding sykemelding) { + public SykemeldingResponseDTO send(Sykemelding sykemelding) { - syfoConsumer.send(sykemelding); + return syfoConsumer.send(sykemelding); } } \ No newline at end of file diff --git a/apps/sykemelding-api/src/main/resources/application-prod.yml b/apps/sykemelding-api/src/main/resources/application-prod.yml new file mode 100644 index 00000000000..0311ce578e3 --- /dev/null +++ b/apps/sykemelding-api/src/main/resources/application-prod.yml @@ -0,0 +1,8 @@ +spring: + security: + oauth2: + resourceserver: + tokenx: + issuer-uri: ${TOKEN_X_ISSUER} + jwk-set-uri: ${TOKEN_X_JWKS_URI} + accepted-audience: ${TOKEN_X_CLIENT_ID} \ No newline at end of file diff --git a/apps/sykemelding-api/src/main/resources/application.yml b/apps/sykemelding-api/src/main/resources/application.yml index 341ca3b64f1..357f2b5c5f6 100644 --- a/apps/sykemelding-api/src/main/resources/application.yml +++ b/apps/sykemelding-api/src/main/resources/application.yml @@ -16,10 +16,6 @@ spring: issuer-uri: ${AAD_ISSUER_URI}/v2.0 jwk-set-uri: ${AAD_ISSUER_URI}/discovery/v2.0/keys accepted-audience: ${azure.app.client.id}, api://${azure.app.client.id} - tokenx: - issuer-uri: ${TOKEN_X_ISSUER} - jwk-set-uri: ${TOKEN_X_JWKS_URI} - accepted-audience: ${TOKEN_X_CLIENT_ID} cloud: vault: enabled: false diff --git a/apps/sykemelding-api/src/main/resources/logback-spring.xml b/apps/sykemelding-api/src/main/resources/logback-spring.xml index 87916258c05..2523e5d41b7 100644 --- a/apps/sykemelding-api/src/main/resources/logback-spring.xml +++ b/apps/sykemelding-api/src/main/resources/logback-spring.xml @@ -1,6 +1,6 @@ - + @@ -22,7 +22,7 @@ - + diff --git a/apps/synt-sykemelding-api/Dockerfile b/apps/synt-sykemelding-api/Dockerfile index 4a36f93546f..8fcd643d0ff 100644 --- a/apps/synt-sykemelding-api/Dockerfile +++ b/apps/synt-sykemelding-api/Dockerfile @@ -1,8 +1,6 @@ FROM ghcr.io/navikt/baseimages/temurin:21 LABEL maintainer="Team Dolly" -ENV JAVA_OPTS="-Dspring.profiles.active=prod" - -ADD /build/libs/app.jar /app/app.jar +COPY /build/libs/app.jar /app/app.jar EXPOSE 8080 diff --git a/apps/synt-sykemelding-api/config.test.yml b/apps/synt-sykemelding-api/config.test.yml new file mode 100644 index 00000000000..7ec70c4d0cd --- /dev/null +++ b/apps/synt-sykemelding-api/config.test.yml @@ -0,0 +1,73 @@ +apiVersion: "nais.io/v1alpha1" +kind: "Application" +metadata: + name: testnav-synt-sykemelding-api-dev + namespace: dolly + annotations: + nginx.ingress.kubernetes.io/proxy-read-timeout: "3600" + nginx.ingress.kubernetes.io/proxy-send-timeout: "3600" + labels: + team: dolly +spec: + image: "{{image}}" + port: 8080 + webproxy: true + tokenx: + enabled: true + azure: + application: + allowAllUsers: true + enabled: true + tenant: nav.no + liveness: + path: /internal/isAlive + initialDelay: 4 + periodSeconds: 5 + failureThreshold: 500 + observability: + logging: + destinations: + - id: elastic + autoInstrumentation: + enabled: true + runtime: java + readiness: + path: /internal/isReady + initialDelay: 4 + periodSeconds: 5 + failureThreshold: 500 + prometheus: + enabled: true + path: /internal/metrics + replicas: + min: 1 + max: 1 + vault: + enabled: true + resources: + requests: + cpu: 200m + memory: 4000Mi + limits: + memory: 5000Mi + accessPolicy: + inbound: + rules: + - application: dolly-backend + - application: dolly-backend-dev + - application: team-dolly-lokal-app + - application: testnav-oversikt-frontend + outbound: + rules: + - application: synthdata-elsam-gcp + - application: testnav-organisasjon-service + - application: testnav-arbeidsforhold-service + - application: testnav-helsepersonell-service + - application: testnav-sykemelding-api-dev + external: + - host: testnav-pdl-proxy.dev-fss-pub.nais.io + ingresses: + - "https://testnav-synt-sykemelding-api-dev.intern.dev.nav.no" + env: + - name: SPRING_PROFILES_ACTIVE + value: dev \ No newline at end of file diff --git a/apps/synt-sykemelding-api/config.yml b/apps/synt-sykemelding-api/config.yml index 2493281b221..d1622f0bba1 100644 --- a/apps/synt-sykemelding-api/config.yml +++ b/apps/synt-sykemelding-api/config.yml @@ -68,3 +68,6 @@ spec: - host: testnav-pdl-proxy.dev-fss-pub.nais.io ingresses: - "https://testnav-synt-sykemelding-api.intern.dev.nav.no" + env: + - name: SPRING_PROFILES_ACTIVE + value: prod \ No newline at end of file diff --git a/apps/synt-sykemelding-api/src/main/java/no/nav/testnav/apps/syntsykemeldingapi/config/LocalVaultConfig.java b/apps/synt-sykemelding-api/src/main/java/no/nav/testnav/apps/syntsykemeldingapi/config/LocalVaultConfig.java index be09110b7fa..c7ec9427324 100644 --- a/apps/synt-sykemelding-api/src/main/java/no/nav/testnav/apps/syntsykemeldingapi/config/LocalVaultConfig.java +++ b/apps/synt-sykemelding-api/src/main/java/no/nav/testnav/apps/syntsykemeldingapi/config/LocalVaultConfig.java @@ -5,6 +5,6 @@ import org.springframework.context.annotation.Profile; @Configuration -@Profile("dev") +@Profile("local") public class LocalVaultConfig extends AbstractLocalVaultConfiguration { } \ No newline at end of file diff --git a/apps/synt-sykemelding-api/src/main/java/no/nav/testnav/apps/syntsykemeldingapi/consumer/HelsepersonellConsumer.java b/apps/synt-sykemelding-api/src/main/java/no/nav/testnav/apps/syntsykemeldingapi/consumer/HelsepersonellConsumer.java index 8cd27ace590..814acafdccf 100644 --- a/apps/synt-sykemelding-api/src/main/java/no/nav/testnav/apps/syntsykemeldingapi/consumer/HelsepersonellConsumer.java +++ b/apps/synt-sykemelding-api/src/main/java/no/nav/testnav/apps/syntsykemeldingapi/consumer/HelsepersonellConsumer.java @@ -5,11 +5,12 @@ import no.nav.testnav.apps.syntsykemeldingapi.config.Consumers; import no.nav.testnav.apps.syntsykemeldingapi.consumer.command.GetHelsepersonellCommand; import no.nav.testnav.apps.syntsykemeldingapi.domain.HelsepersonellListe; -import no.nav.testnav.apps.syntsykemeldingapi.exception.HelsepersonellNotFoundException; import no.nav.testnav.libs.securitycore.domain.ServerProperties; import no.nav.testnav.libs.servletsecurity.exchange.TokenExchange; +import org.springframework.http.HttpStatus; import org.springframework.stereotype.Component; import org.springframework.web.reactive.function.client.WebClient; +import org.springframework.web.server.ResponseStatusException; import static java.util.Objects.nonNull; @@ -44,7 +45,7 @@ public HelsepersonellListe hentHelsepersonell() { return new HelsepersonellListe(response); } else { log.warn("Feil oppsto i henting av helsepersonell"); - throw new HelsepersonellNotFoundException("Feil i henting av helsepersonell"); + throw new ResponseStatusException(HttpStatus.INTERNAL_SERVER_ERROR, "Feil i henting av helsepersonell"); } } } \ No newline at end of file diff --git a/apps/synt-sykemelding-api/src/main/java/no/nav/testnav/apps/syntsykemeldingapi/consumer/PdlProxyConsumer.java b/apps/synt-sykemelding-api/src/main/java/no/nav/testnav/apps/syntsykemeldingapi/consumer/PdlProxyConsumer.java index 52d2327642a..0e916558c72 100644 --- a/apps/synt-sykemelding-api/src/main/java/no/nav/testnav/apps/syntsykemeldingapi/consumer/PdlProxyConsumer.java +++ b/apps/synt-sykemelding-api/src/main/java/no/nav/testnav/apps/syntsykemeldingapi/consumer/PdlProxyConsumer.java @@ -4,13 +4,14 @@ import no.nav.testnav.apps.syntsykemeldingapi.config.Consumers; import no.nav.testnav.apps.syntsykemeldingapi.consumer.command.GetPdlPersonCommand; import no.nav.testnav.apps.syntsykemeldingapi.domain.pdl.PdlPerson; -import no.nav.testnav.apps.syntsykemeldingapi.exception.PdlPersonException; import no.nav.testnav.apps.syntsykemeldingapi.util.FilLaster; import no.nav.testnav.libs.securitycore.domain.ServerProperties; import no.nav.testnav.libs.servletsecurity.exchange.TokenExchange; +import org.springframework.http.HttpStatus; import org.springframework.stereotype.Component; import org.springframework.web.reactive.function.client.ExchangeStrategies; import org.springframework.web.reactive.function.client.WebClient; +import org.springframework.web.server.ResponseStatusException; import java.io.BufferedReader; import java.io.IOException; @@ -60,12 +61,12 @@ public PdlPerson getPdlPerson(String ident) { if (nonNull(response) && !response.getErrors().isEmpty()) { var melding = response.getErrors().get(0).getMessage(); log.error("Klarte ikke hente pdlperson: " + melding); - throw new PdlPersonException("Feil i henting av person fra pdl" + melding); + throw new ResponseStatusException(HttpStatus.INTERNAL_SERVER_ERROR, "Feil i henting av person fra pdl" + melding); } return response; } catch (Exception e) { log.error("Klarte ikke hente pdlperson.", e); - throw new PdlPersonException("Feil i henting av person fra pdl"); + throw new ResponseStatusException(HttpStatus.INTERNAL_SERVER_ERROR, "Feil i henting av person fra pdl"); } } diff --git a/apps/synt-sykemelding-api/src/main/java/no/nav/testnav/apps/syntsykemeldingapi/consumer/SykemeldingConsumer.java b/apps/synt-sykemelding-api/src/main/java/no/nav/testnav/apps/syntsykemeldingapi/consumer/SykemeldingConsumer.java index 60acfddd441..87b327b5899 100644 --- a/apps/synt-sykemelding-api/src/main/java/no/nav/testnav/apps/syntsykemeldingapi/consumer/SykemeldingConsumer.java +++ b/apps/synt-sykemelding-api/src/main/java/no/nav/testnav/apps/syntsykemeldingapi/consumer/SykemeldingConsumer.java @@ -4,6 +4,7 @@ import no.nav.testnav.apps.syntsykemeldingapi.config.Consumers; import no.nav.testnav.apps.syntsykemeldingapi.consumer.command.PostSykemeldingCommand; import no.nav.testnav.libs.dto.sykemelding.v1.SykemeldingDTO; +import no.nav.testnav.libs.dto.sykemelding.v1.SykemeldingResponseDTO; import no.nav.testnav.libs.securitycore.domain.ServerProperties; import no.nav.testnav.libs.servletsecurity.exchange.TokenExchange; import org.springframework.stereotype.Component; @@ -29,8 +30,10 @@ public SykemeldingConsumer( .build(); } - public void opprettSykemelding(SykemeldingDTO sykemelding) { - tokenExchange.exchange(serverProperties).flatMap(accessToken -> + public SykemeldingResponseDTO opprettSykemelding(SykemeldingDTO sykemelding) { + + return tokenExchange.exchange(serverProperties) + .flatMap(accessToken -> new PostSykemeldingCommand(webClient, accessToken.getTokenValue(), sykemelding).call()) .block(); } diff --git a/apps/synt-sykemelding-api/src/main/java/no/nav/testnav/apps/syntsykemeldingapi/consumer/SyntElsamConsumer.java b/apps/synt-sykemelding-api/src/main/java/no/nav/testnav/apps/syntsykemeldingapi/consumer/SyntElsamConsumer.java index 1a754f8a8e1..85e1b91820f 100644 --- a/apps/synt-sykemelding-api/src/main/java/no/nav/testnav/apps/syntsykemeldingapi/consumer/SyntElsamConsumer.java +++ b/apps/synt-sykemelding-api/src/main/java/no/nav/testnav/apps/syntsykemeldingapi/consumer/SyntElsamConsumer.java @@ -5,12 +5,13 @@ import no.nav.testnav.apps.syntsykemeldingapi.config.Consumers; import no.nav.testnav.apps.syntsykemeldingapi.consumer.command.PostSyntSykemeldingCommand; import no.nav.testnav.apps.syntsykemeldingapi.consumer.dto.SyntSykemeldingHistorikkDTO; -import no.nav.testnav.apps.syntsykemeldingapi.exception.GenererSykemeldingerException; import no.nav.testnav.libs.securitycore.domain.ServerProperties; import no.nav.testnav.libs.servletsecurity.exchange.TokenExchange; +import org.springframework.http.HttpStatus; import org.springframework.stereotype.Component; import org.springframework.web.reactive.function.client.ExchangeStrategies; import org.springframework.web.reactive.function.client.WebClient; +import org.springframework.web.server.ResponseStatusException; import java.time.LocalDate; import java.util.Map; @@ -54,7 +55,7 @@ public SyntSykemeldingHistorikkDTO genererSykemeldinger(String ident, LocalDate .block(); if (isNull(response)) { - throw new GenererSykemeldingerException("Klarte ikke å generere sykemeldinger."); + throw new ResponseStatusException(HttpStatus.INTERNAL_SERVER_ERROR, "Klarte ikke å generere sykemeldinger."); } log.info("Sykemelding generert."); return response.get(ident); diff --git a/apps/synt-sykemelding-api/src/main/java/no/nav/testnav/apps/syntsykemeldingapi/consumer/command/PostSykemeldingCommand.java b/apps/synt-sykemelding-api/src/main/java/no/nav/testnav/apps/syntsykemeldingapi/consumer/command/PostSykemeldingCommand.java index f0137a236cb..3570ec16745 100644 --- a/apps/synt-sykemelding-api/src/main/java/no/nav/testnav/apps/syntsykemeldingapi/consumer/command/PostSykemeldingCommand.java +++ b/apps/synt-sykemelding-api/src/main/java/no/nav/testnav/apps/syntsykemeldingapi/consumer/command/PostSykemeldingCommand.java @@ -3,9 +3,12 @@ import lombok.RequiredArgsConstructor; import lombok.SneakyThrows; import lombok.extern.slf4j.Slf4j; -import no.nav.testnav.apps.syntsykemeldingapi.exception.LagreSykemeldingException; import no.nav.testnav.libs.dto.sykemelding.v1.SykemeldingDTO; +import no.nav.testnav.libs.dto.sykemelding.v1.SykemeldingResponseDTO; +import no.nav.testnav.libs.reactivecore.utils.WebClientFilter; +import org.springframework.http.HttpStatus; import org.springframework.web.reactive.function.client.WebClient; +import org.springframework.web.server.ResponseStatusException; import reactor.core.publisher.Mono; import java.util.concurrent.Callable; @@ -14,7 +17,7 @@ @Slf4j @RequiredArgsConstructor -public class PostSykemeldingCommand implements Callable> { +public class PostSykemeldingCommand implements Callable> { private final WebClient webClient; private final String token; @@ -22,7 +25,7 @@ public class PostSykemeldingCommand implements Callable> { @SneakyThrows @Override - public Mono call() { + public Mono call() { return webClient.post() .uri(builder -> builder.path("/api/v1/sykemeldinger").build() @@ -30,10 +33,9 @@ public Mono call() { .header(AUTHORIZATION, "Bearer " + token) .bodyValue(sykemelding) .retrieve() - .bodyToMono(String.class) - .onErrorResume(throwable -> { - log.error("Feil oppsto i innsending av sykemelding", throwable); - throw new LagreSykemeldingException("Feil oppsto i innsending av sykemelding"); - }); + .bodyToMono(SykemeldingResponseDTO.class) + .doOnError(WebClientFilter::logErrorMessage) + .onErrorResume(throwable -> + Mono.error(new ResponseStatusException(HttpStatus.INTERNAL_SERVER_ERROR, "Feil oppsto i innsending av sykemelding"))); } } diff --git a/apps/synt-sykemelding-api/src/main/java/no/nav/testnav/apps/syntsykemeldingapi/consumer/command/PostSyntSykemeldingCommand.java b/apps/synt-sykemelding-api/src/main/java/no/nav/testnav/apps/syntsykemeldingapi/consumer/command/PostSyntSykemeldingCommand.java index 9b359589dd0..0a6c70719e0 100644 --- a/apps/synt-sykemelding-api/src/main/java/no/nav/testnav/apps/syntsykemeldingapi/consumer/command/PostSyntSykemeldingCommand.java +++ b/apps/synt-sykemelding-api/src/main/java/no/nav/testnav/apps/syntsykemeldingapi/consumer/command/PostSyntSykemeldingCommand.java @@ -3,10 +3,11 @@ import lombok.AllArgsConstructor; import lombok.extern.slf4j.Slf4j; import no.nav.testnav.apps.syntsykemeldingapi.consumer.dto.SyntSykemeldingHistorikkDTO; -import no.nav.testnav.apps.syntsykemeldingapi.exception.GenererSykemeldingerException; import no.nav.testnav.libs.commands.utils.WebClientFilter; import org.springframework.core.ParameterizedTypeReference; +import org.springframework.http.HttpStatus; import org.springframework.web.reactive.function.client.WebClient; +import org.springframework.web.server.ResponseStatusException; import reactor.core.publisher.Mono; import reactor.util.retry.Retry; @@ -39,7 +40,7 @@ public Mono> call() { .filter(WebClientFilter::is5xxException)) .onErrorResume(throwable -> { log.error("Klarte ikke å hente data fra synthdata-elsam", throwable); - throw new GenererSykemeldingerException("Klarte ikke å generere sykemeldinger."); + throw new ResponseStatusException(HttpStatus.INTERNAL_SERVER_ERROR, "Klarte ikke å generere sykemeldinger."); }); } } diff --git a/apps/synt-sykemelding-api/src/main/java/no/nav/testnav/apps/syntsykemeldingapi/exception/GenererSykemeldingerException.java b/apps/synt-sykemelding-api/src/main/java/no/nav/testnav/apps/syntsykemeldingapi/exception/GenererSykemeldingerException.java deleted file mode 100644 index 82c222ce5e6..00000000000 --- a/apps/synt-sykemelding-api/src/main/java/no/nav/testnav/apps/syntsykemeldingapi/exception/GenererSykemeldingerException.java +++ /dev/null @@ -1,8 +0,0 @@ -package no.nav.testnav.apps.syntsykemeldingapi.exception; - -public class GenererSykemeldingerException extends RuntimeException { - - public GenererSykemeldingerException(String message) { - super(message); - } -} diff --git a/apps/synt-sykemelding-api/src/main/java/no/nav/testnav/apps/syntsykemeldingapi/exception/HelsepersonellNotFoundException.java b/apps/synt-sykemelding-api/src/main/java/no/nav/testnav/apps/syntsykemeldingapi/exception/HelsepersonellNotFoundException.java deleted file mode 100644 index 5af4175bc7b..00000000000 --- a/apps/synt-sykemelding-api/src/main/java/no/nav/testnav/apps/syntsykemeldingapi/exception/HelsepersonellNotFoundException.java +++ /dev/null @@ -1,8 +0,0 @@ -package no.nav.testnav.apps.syntsykemeldingapi.exception; - -public class HelsepersonellNotFoundException extends RuntimeException { - - public HelsepersonellNotFoundException(String message) { - super(message); - } -} diff --git a/apps/synt-sykemelding-api/src/main/java/no/nav/testnav/apps/syntsykemeldingapi/exception/LagreSykemeldingException.java b/apps/synt-sykemelding-api/src/main/java/no/nav/testnav/apps/syntsykemeldingapi/exception/LagreSykemeldingException.java deleted file mode 100644 index bec944dc7b5..00000000000 --- a/apps/synt-sykemelding-api/src/main/java/no/nav/testnav/apps/syntsykemeldingapi/exception/LagreSykemeldingException.java +++ /dev/null @@ -1,7 +0,0 @@ -package no.nav.testnav.apps.syntsykemeldingapi.exception; - -public class LagreSykemeldingException extends RuntimeException { - public LagreSykemeldingException(String message) { - super(message); - } -} diff --git a/apps/synt-sykemelding-api/src/main/java/no/nav/testnav/apps/syntsykemeldingapi/exception/PdlPersonException.java b/apps/synt-sykemelding-api/src/main/java/no/nav/testnav/apps/syntsykemeldingapi/exception/PdlPersonException.java deleted file mode 100644 index f071a9a967f..00000000000 --- a/apps/synt-sykemelding-api/src/main/java/no/nav/testnav/apps/syntsykemeldingapi/exception/PdlPersonException.java +++ /dev/null @@ -1,8 +0,0 @@ -package no.nav.testnav.apps.syntsykemeldingapi.exception; - -public class PdlPersonException extends RuntimeException { - - public PdlPersonException(String message) { - super(message); - } -} diff --git a/apps/synt-sykemelding-api/src/main/java/no/nav/testnav/apps/syntsykemeldingapi/provider/SyntSykemeldingController.java b/apps/synt-sykemelding-api/src/main/java/no/nav/testnav/apps/syntsykemeldingapi/provider/SyntSykemeldingController.java index f3c24a063dc..7659c7d3723 100644 --- a/apps/synt-sykemelding-api/src/main/java/no/nav/testnav/apps/syntsykemeldingapi/provider/SyntSykemeldingController.java +++ b/apps/synt-sykemelding-api/src/main/java/no/nav/testnav/apps/syntsykemeldingapi/provider/SyntSykemeldingController.java @@ -2,42 +2,24 @@ import lombok.RequiredArgsConstructor; import lombok.extern.slf4j.Slf4j; - import no.nav.testnav.apps.syntsykemeldingapi.service.SykemeldingService; +import no.nav.testnav.libs.dto.sykemelding.v1.SykemeldingResponseDTO; import no.nav.testnav.libs.dto.synt.sykemelding.v1.SyntSykemeldingDTO; - -import org.springframework.http.HttpStatus; -import org.springframework.http.ResponseEntity; -import org.springframework.web.bind.annotation.ControllerAdvice; -import org.springframework.web.bind.annotation.ExceptionHandler; import org.springframework.web.bind.annotation.PostMapping; import org.springframework.web.bind.annotation.RequestBody; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RestController; -import org.springframework.web.client.HttpClientErrorException; @RestController @Slf4j @RequestMapping("/api/v1/synt-sykemelding") @RequiredArgsConstructor public class SyntSykemeldingController { - private final SykemeldingService service; + private final SykemeldingService sykemeldingService; @PostMapping - public ResponseEntity opprett(@RequestBody SyntSykemeldingDTO sykemelding) { - service.opprettSykemelding(sykemelding); - return ResponseEntity.ok().build(); - } - - @ControllerAdvice - public static class ExceptionHandlerAdvice { - - @ExceptionHandler(HttpClientErrorException.class) - public ResponseEntity handleException(HttpClientErrorException e) { - log.error("Klarte ikke å finne arbeidsforhold", e); - return ResponseEntity - .status(HttpStatus.NOT_FOUND) - .body("Klarte ikke å finne aktivt arbeidsforhold for personen"); - } + public SykemeldingResponseDTO opprett(@RequestBody SyntSykemeldingDTO sykemelding) { + + return sykemeldingService.opprettSykemelding(sykemelding); } } \ No newline at end of file diff --git a/apps/synt-sykemelding-api/src/main/java/no/nav/testnav/apps/syntsykemeldingapi/service/SykemeldingService.java b/apps/synt-sykemelding-api/src/main/java/no/nav/testnav/apps/syntsykemeldingapi/service/SykemeldingService.java index 6bef1a391dd..dea8c92f9a8 100644 --- a/apps/synt-sykemelding-api/src/main/java/no/nav/testnav/apps/syntsykemeldingapi/service/SykemeldingService.java +++ b/apps/synt-sykemelding-api/src/main/java/no/nav/testnav/apps/syntsykemeldingapi/service/SykemeldingService.java @@ -9,11 +9,10 @@ import no.nav.testnav.apps.syntsykemeldingapi.consumer.SyntElsamConsumer; import no.nav.testnav.apps.syntsykemeldingapi.domain.Person; import no.nav.testnav.apps.syntsykemeldingapi.domain.Sykemelding; +import no.nav.testnav.libs.dto.sykemelding.v1.SykemeldingResponseDTO; import no.nav.testnav.libs.dto.synt.sykemelding.v1.SyntSykemeldingDTO; import org.springframework.stereotype.Service; -import java.util.Objects; - import static java.util.Objects.nonNull; @Slf4j @@ -26,7 +25,7 @@ public class SykemeldingService { private final ArbeidsforholdAdapter arbeidsforholdAdapter; private final PdlProxyConsumer pdlProxyConsumer; - public void opprettSykemelding(SyntSykemeldingDTO syntSykemelding) { + public SykemeldingResponseDTO opprettSykemelding(SyntSykemeldingDTO syntSykemelding) { var pdlData = pdlProxyConsumer.getPdlPerson(syntSykemelding.getIdent()); var pasient = new Person(pdlData); @@ -44,7 +43,7 @@ public void opprettSykemelding(SyntSykemeldingDTO syntSykemelding) { ); var helsepersonellListe = helsepersonellConsumer.hentHelsepersonell(); - sykemeldingConsumer.opprettSykemelding( + return sykemeldingConsumer.opprettSykemelding( new Sykemelding(pasient, historikk, syntSykemelding, helsepersonellListe.getRandomLege(), arbeidsforhold).toDTO() ); } diff --git a/apps/synt-sykemelding-api/src/main/resources/application-dev.yml b/apps/synt-sykemelding-api/src/main/resources/application-dev.yml index d2bdd15fc8a..e0dc5a65e3c 100644 --- a/apps/synt-sykemelding-api/src/main/resources/application-dev.yml +++ b/apps/synt-sykemelding-api/src/main/resources/application-dev.yml @@ -1,12 +1,22 @@ -TOKEN_X_CLIENT_ID: dev-gcp:dolly:testnav-synt-sykemelding-api +spring: + security: + oauth2: + resourceserver: + tokenx: + issuer-uri: ${TOKEN_X_ISSUER} + jwk-set-uri: ${TOKEN_X_JWKS_URI} + accepted-audience: ${TOKEN_X_CLIENT_ID} consumers: synt-sykemelding: - url: https://synthdata-elsam-gcp.intern.dev.nav.no + url: http://synthdata-elsam-gcp.intern.dolly.svc.cluster.local testnav-organisasjon-service: - url: https://testnav-organisasjon-service.intern.dev.nav.no + url: http://testnav-organisasjon-service.dolly.svc.cluster.local testnav-arbeidsforhold-service: - url: https://testnav-arbeidsforhold-service.intern.dev.nav.no + url: http://testnav-arbeidsforhold-service.dolly.svc.cluster.local testnav-helsepersonell-service: - url: https://testnav-helsepersonell-service.intern.dev.nav.no + url: http://testnav-helsepersonell-service.dolly.svc.cluster.local + sykemelding-api: + url: http://testnav-sykemelding-api-dev.dolly.svc.cluster.local + name: testnav-sykemelding-api-dev diff --git a/apps/synt-sykemelding-api/src/main/resources/application-local.yml b/apps/synt-sykemelding-api/src/main/resources/application-local.yml new file mode 100644 index 00000000000..e77e1c2c6af --- /dev/null +++ b/apps/synt-sykemelding-api/src/main/resources/application-local.yml @@ -0,0 +1,13 @@ + +consumers: + synt-sykemelding: + url: https://synthdata-elsam-gcp.intern.dev.nav.no + testnav-organisasjon-service: + url: https://testnav-organisasjon-service.intern.dev.nav.no + testnav-arbeidsforhold-service: + url: https://testnav-arbeidsforhold-service.intern.dev.nav.no + testnav-helsepersonell-service: + url: https://testnav-helsepersonell-service.intern.dev.nav.no + sykemelding-api: + url: https://testnav-sykemelding-api-dev.intern.dev.nav.no + name: testnav-sykemelding-api-dev \ No newline at end of file diff --git a/apps/synt-sykemelding-api/src/main/resources/application-prod.yml b/apps/synt-sykemelding-api/src/main/resources/application-prod.yml new file mode 100644 index 00000000000..0311ce578e3 --- /dev/null +++ b/apps/synt-sykemelding-api/src/main/resources/application-prod.yml @@ -0,0 +1,8 @@ +spring: + security: + oauth2: + resourceserver: + tokenx: + issuer-uri: ${TOKEN_X_ISSUER} + jwk-set-uri: ${TOKEN_X_JWKS_URI} + accepted-audience: ${TOKEN_X_CLIENT_ID} \ No newline at end of file diff --git a/apps/synt-sykemelding-api/src/main/resources/application.yml b/apps/synt-sykemelding-api/src/main/resources/application.yml index 11992aca432..424f21bfb59 100644 --- a/apps/synt-sykemelding-api/src/main/resources/application.yml +++ b/apps/synt-sykemelding-api/src/main/resources/application.yml @@ -12,10 +12,6 @@ spring: issuer-uri: ${AAD_ISSUER_URI}/v2.0 jwk-set-uri: ${AAD_ISSUER_URI}/discovery/v2.0/keys accepted-audience: ${azure.app.client.id}, api://${azure.app.client.id} - tokenx: - issuer-uri: ${TOKEN_X_ISSUER} - jwk-set-uri: ${TOKEN_X_JWKS_URI} - accepted-audience: ${TOKEN_X_CLIENT_ID} cloud: vault: enabled: false diff --git a/apps/synt-sykemelding-api/src/main/resources/logback-spring.xml b/apps/synt-sykemelding-api/src/main/resources/logback-spring.xml index 7309420d4fd..75c5be52d1c 100644 --- a/apps/synt-sykemelding-api/src/main/resources/logback-spring.xml +++ b/apps/synt-sykemelding-api/src/main/resources/logback-spring.xml @@ -1,6 +1,6 @@ - + @@ -22,7 +22,7 @@ - + diff --git a/apps/synt-sykemelding-api/src/test/java/no/nav/testnav/apps/syntsykemeldingapi/consumer/SykemeldingConsumerTest.java b/apps/synt-sykemelding-api/src/test/java/no/nav/testnav/apps/syntsykemeldingapi/consumer/SykemeldingConsumerTest.java index 79c2b3dea2a..9ba6c0c1b47 100644 --- a/apps/synt-sykemelding-api/src/test/java/no/nav/testnav/apps/syntsykemeldingapi/consumer/SykemeldingConsumerTest.java +++ b/apps/synt-sykemelding-api/src/test/java/no/nav/testnav/apps/syntsykemeldingapi/consumer/SykemeldingConsumerTest.java @@ -8,7 +8,6 @@ import no.nav.testnav.apps.syntsykemeldingapi.domain.Person; import no.nav.testnav.apps.syntsykemeldingapi.domain.Sykemelding; import no.nav.testnav.apps.syntsykemeldingapi.domain.pdl.PdlPerson; -import no.nav.testnav.apps.syntsykemeldingapi.exception.LagreSykemeldingException; import no.nav.testnav.libs.dto.helsepersonell.v1.HelsepersonellListeDTO; import no.nav.testnav.libs.dto.oppsummeringsdokumentservice.v1.ArbeidsforholdDTO; import no.nav.testnav.libs.dto.organisasjon.v1.OrganisasjonDTO; @@ -30,24 +29,25 @@ import org.springframework.test.context.ActiveProfiles; import org.springframework.test.context.TestPropertySource; import org.springframework.test.context.junit4.SpringRunner; +import org.springframework.web.server.ResponseStatusException; import reactor.core.publisher.Mono; import java.time.LocalDate; import java.util.Map; -import static com.github.tomakehurst.wiremock.client.WireMock.stubFor; +import static com.github.tomakehurst.wiremock.client.WireMock.aResponse; +import static com.github.tomakehurst.wiremock.client.WireMock.ok; import static com.github.tomakehurst.wiremock.client.WireMock.post; +import static com.github.tomakehurst.wiremock.client.WireMock.stubFor; import static com.github.tomakehurst.wiremock.client.WireMock.urlPathMatching; -import static com.github.tomakehurst.wiremock.client.WireMock.ok; -import static com.github.tomakehurst.wiremock.client.WireMock.aResponse; -import static no.nav.testnav.apps.syntsykemeldingapi.util.TestUtil.getTestPdlPerson; -import static no.nav.testnav.apps.syntsykemeldingapi.util.TestUtil.getTestHistorikk; import static no.nav.testnav.apps.syntsykemeldingapi.util.TestUtil.getTestArbeidsforholdDTO; +import static no.nav.testnav.apps.syntsykemeldingapi.util.TestUtil.getTestHistorikk; import static no.nav.testnav.apps.syntsykemeldingapi.util.TestUtil.getTestLegeListeDTO; import static no.nav.testnav.apps.syntsykemeldingapi.util.TestUtil.getTestOrganisasjonDTO; +import static no.nav.testnav.apps.syntsykemeldingapi.util.TestUtil.getTestPdlPerson; +import static org.junit.jupiter.api.Assertions.assertDoesNotThrow; import static org.junit.jupiter.api.Assertions.assertThrows; import static org.mockito.Mockito.when; -import static org.junit.jupiter.api.Assertions.assertDoesNotThrow; @ActiveProfiles("test") @RunWith(SpringRunner.class) @@ -126,7 +126,7 @@ public void shouldPostSykemeldingUtenFeil() { @Test public void shouldGetFeil() { stubSykemeldingError(); - assertThrows(LagreSykemeldingException.class, () -> sykemeldingConsumer.opprettSykemelding(sykemeldingRequest)); + assertThrows(ResponseStatusException.class, () -> sykemeldingConsumer.opprettSykemelding(sykemeldingRequest)); } private void stubSykemelding() { diff --git a/libs/data-transfer-objects/src/main/java/no/nav/testnav/libs/dto/sykemelding/v1/SykemeldingResponseDTO.java b/libs/data-transfer-objects/src/main/java/no/nav/testnav/libs/dto/sykemelding/v1/SykemeldingResponseDTO.java new file mode 100644 index 00000000000..e299b10962a --- /dev/null +++ b/libs/data-transfer-objects/src/main/java/no/nav/testnav/libs/dto/sykemelding/v1/SykemeldingResponseDTO.java @@ -0,0 +1,17 @@ +package no.nav.testnav.libs.dto.sykemelding.v1; + +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.Data; +import lombok.NoArgsConstructor; +import org.springframework.http.HttpStatus; + +@Data +@Builder +@NoArgsConstructor +@AllArgsConstructor +public class SykemeldingResponseDTO { + + private HttpStatus status; + private String sykemeldingId; +} diff --git a/libs/reactive-proxy/package-lock.json b/libs/reactive-proxy/package-lock.json new file mode 100644 index 00000000000..34301f6bd76 --- /dev/null +++ b/libs/reactive-proxy/package-lock.json @@ -0,0 +1,6 @@ +{ + "name": "reactive-proxy", + "lockfileVersion": 3, + "requires": true, + "packages": {} +} diff --git a/proxies/pdl-proxy/config.yml b/proxies/pdl-proxy/config.yml index b5a88f48086..a685d4fd29e 100644 --- a/proxies/pdl-proxy/config.yml +++ b/proxies/pdl-proxy/config.yml @@ -57,6 +57,8 @@ spec: cluster: dev-gcp - application: testnav-synt-sykemelding-api cluster: dev-gcp + - application: testnav-synt-sykemelding-api-dev + cluster: dev-gcp - application: testnav-helsepersonell-service cluster: dev-gcp - application: testnav-tenor-search-service From 1fe5c0f2684750924d20328d80b5807f097f91bd Mon Sep 17 00:00:00 2001 From: Stian Gustavsson Date: Fri, 29 Nov 2024 11:04:18 +0100 Subject: [PATCH 04/14] Update config.yml Lagt til inbound rules for sykemelding api og dev versjon av denne i sykemelding-proxy --- proxies/sykemelding-proxy/config.yml | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/proxies/sykemelding-proxy/config.yml b/proxies/sykemelding-proxy/config.yml index 24dedf2a3d7..e1b061e8484 100644 --- a/proxies/sykemelding-proxy/config.yml +++ b/proxies/sykemelding-proxy/config.yml @@ -37,6 +37,8 @@ spec: - application: dolly-frontend-dev - application: dolly-backend - application: dolly-backend-dev + - application: testnav-sykemelding-api + - application: testnav-sykemelding-api-dev - application: testnav-oversikt-frontend outbound: rules: @@ -71,4 +73,4 @@ spec: envFrom: - secret: azure-trygdeetaten-testnav-sykemelding-proxy-trygdeetaten ingresses: - - "https://testnav-sykemelding-proxy.intern.dev.nav.no" \ No newline at end of file + - "https://testnav-sykemelding-proxy.intern.dev.nav.no" From 0840efbbee3a29bd8861b8b904fbdf1f72256c72 Mon Sep 17 00:00:00 2001 From: Stian Gustavsson Date: Fri, 29 Nov 2024 15:20:57 +0100 Subject: [PATCH 05/14] Feature/better trigger handling (#3676) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - Bedre handling av react-hook-forms trigger sjekking - Fikset date fra norsk bankkonto på ugyldig format - Gir rød input boks i tillegg til errormelding dersom feltet ikke validerer - Større trigger endringer, lagt til bedre støtte for manuelle feil satt fra koden utenom yup-valideringen - Noe mindre bugfixing av diverse elementer funnet under testing --- .../src/main/js/package-lock.json | 252 +++++++++--------- apps/dolly-frontend/src/main/js/package.json | 2 +- .../stegVelger/StegVelger.tsx | 6 +- .../form/partials/arbeidsforholdToggle.tsx | 6 +- .../aareg/form/partials/arbeidsgiverIdent.tsx | 4 +- .../form/partials/EgneOrganisasjoner.tsx | 2 +- .../form/partials/orgnummerToggle.tsx | 13 +- .../pensjon/form/GenerertInntektForm.tsx | 7 +- .../form/PensjonsgivendeInntektForm.tsx | 4 +- .../inntektStub/validerInntekt/index.tsx | 2 + .../ui/form/inputs/datepicker/Datepicker.tsx | 73 +++-- .../components/ui/form/inputs/label/Label.tsx | 5 +- .../ui/form/inputs/select/Select.tsx | 8 +- .../ui/form/inputs/textInput/TextInput.tsx | 5 +- .../src/main/js/src/utils/DataFormatter.tsx | 3 + .../src/utils/GenererGyldigNorskBankkonto.tsx | 2 +- 16 files changed, 212 insertions(+), 182 deletions(-) diff --git a/apps/dolly-frontend/src/main/js/package-lock.json b/apps/dolly-frontend/src/main/js/package-lock.json index 573f54271c3..80940c5d35d 100644 --- a/apps/dolly-frontend/src/main/js/package-lock.json +++ b/apps/dolly-frontend/src/main/js/package-lock.json @@ -1,12 +1,12 @@ { "name": "dolly", - "version": "3.0.46", + "version": "3.0.47", "lockfileVersion": 3, "requires": true, "packages": { "": { "name": "dolly", - "version": "3.0.46", + "version": "3.0.47", "license": "ISC", "dependencies": { "@grafana/faro-react": "^1.11.0", @@ -3269,9 +3269,9 @@ } }, "node_modules/@rollup/rollup-android-arm-eabi": { - "version": "4.27.3", - "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm-eabi/-/rollup-android-arm-eabi-4.27.3.tgz", - "integrity": "sha512-EzxVSkIvCFxUd4Mgm4xR9YXrcp976qVaHnqom/Tgm+vU79k4vV4eYTjmRvGfeoW8m9LVcsAy/lGjcgVegKEhLQ==", + "version": "4.27.4", + "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm-eabi/-/rollup-android-arm-eabi-4.27.4.tgz", + "integrity": "sha512-2Y3JT6f5MrQkICUyRVCw4oa0sutfAsgaSsb0Lmmy1Wi2y7X5vT9Euqw4gOsCyy0YfKURBg35nhUKZS4mDcfULw==", "cpu": [ "arm" ], @@ -3283,9 +3283,9 @@ ] }, "node_modules/@rollup/rollup-android-arm64": { - "version": "4.27.3", - "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm64/-/rollup-android-arm64-4.27.3.tgz", - "integrity": "sha512-LJc5pDf1wjlt9o/Giaw9Ofl+k/vLUaYsE2zeQGH85giX2F+wn/Cg8b3c5CDP3qmVmeO5NzwVUzQQxwZvC2eQKw==", + "version": "4.27.4", + "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm64/-/rollup-android-arm64-4.27.4.tgz", + "integrity": "sha512-wzKRQXISyi9UdCVRqEd0H4cMpzvHYt1f/C3CoIjES6cG++RHKhrBj2+29nPF0IB5kpy9MS71vs07fvrNGAl/iA==", "cpu": [ "arm64" ], @@ -3297,9 +3297,9 @@ ] }, "node_modules/@rollup/rollup-darwin-arm64": { - "version": "4.27.3", - "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-arm64/-/rollup-darwin-arm64-4.27.3.tgz", - "integrity": "sha512-OuRysZ1Mt7wpWJ+aYKblVbJWtVn3Cy52h8nLuNSzTqSesYw1EuN6wKp5NW/4eSre3mp12gqFRXOKTcN3AI3LqA==", + "version": "4.27.4", + "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-arm64/-/rollup-darwin-arm64-4.27.4.tgz", + "integrity": "sha512-PlNiRQapift4LNS8DPUHuDX/IdXiLjf8mc5vdEmUR0fF/pyy2qWwzdLjB+iZquGr8LuN4LnUoSEvKRwjSVYz3Q==", "cpu": [ "arm64" ], @@ -3311,9 +3311,9 @@ ] }, "node_modules/@rollup/rollup-darwin-x64": { - "version": "4.27.3", - "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-x64/-/rollup-darwin-x64-4.27.3.tgz", - "integrity": "sha512-xW//zjJMlJs2sOrCmXdB4d0uiilZsOdlGQIC/jjmMWT47lkLLoB1nsNhPUcnoqyi5YR6I4h+FjBpILxbEy8JRg==", + "version": "4.27.4", + "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-x64/-/rollup-darwin-x64-4.27.4.tgz", + "integrity": "sha512-o9bH2dbdgBDJaXWJCDTNDYa171ACUdzpxSZt+u/AAeQ20Nk5x+IhA+zsGmrQtpkLiumRJEYef68gcpn2ooXhSQ==", "cpu": [ "x64" ], @@ -3325,9 +3325,9 @@ ] }, "node_modules/@rollup/rollup-freebsd-arm64": { - "version": "4.27.3", - "resolved": "https://registry.npmjs.org/@rollup/rollup-freebsd-arm64/-/rollup-freebsd-arm64-4.27.3.tgz", - "integrity": "sha512-58E0tIcwZ+12nK1WiLzHOD8I0d0kdrY/+o7yFVPRHuVGY3twBwzwDdTIBGRxLmyjciMYl1B/U515GJy+yn46qw==", + "version": "4.27.4", + "resolved": "https://registry.npmjs.org/@rollup/rollup-freebsd-arm64/-/rollup-freebsd-arm64-4.27.4.tgz", + "integrity": "sha512-NBI2/i2hT9Q+HySSHTBh52da7isru4aAAo6qC3I7QFVsuhxi2gM8t/EI9EVcILiHLj1vfi+VGGPaLOUENn7pmw==", "cpu": [ "arm64" ], @@ -3339,9 +3339,9 @@ ] }, "node_modules/@rollup/rollup-freebsd-x64": { - "version": "4.27.3", - "resolved": "https://registry.npmjs.org/@rollup/rollup-freebsd-x64/-/rollup-freebsd-x64-4.27.3.tgz", - "integrity": "sha512-78fohrpcVwTLxg1ZzBMlwEimoAJmY6B+5TsyAZ3Vok7YabRBUvjYTsRXPTjGEvv/mfgVBepbW28OlMEz4w8wGA==", + "version": "4.27.4", + "resolved": "https://registry.npmjs.org/@rollup/rollup-freebsd-x64/-/rollup-freebsd-x64-4.27.4.tgz", + "integrity": "sha512-wYcC5ycW2zvqtDYrE7deary2P2UFmSh85PUpAx+dwTCO9uw3sgzD6Gv9n5X4vLaQKsrfTSZZ7Z7uynQozPVvWA==", "cpu": [ "x64" ], @@ -3353,9 +3353,9 @@ ] }, "node_modules/@rollup/rollup-linux-arm-gnueabihf": { - "version": "4.27.3", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-gnueabihf/-/rollup-linux-arm-gnueabihf-4.27.3.tgz", - "integrity": "sha512-h2Ay79YFXyQi+QZKo3ISZDyKaVD7uUvukEHTOft7kh00WF9mxAaxZsNs3o/eukbeKuH35jBvQqrT61fzKfAB/Q==", + "version": "4.27.4", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-gnueabihf/-/rollup-linux-arm-gnueabihf-4.27.4.tgz", + "integrity": "sha512-9OwUnK/xKw6DyRlgx8UizeqRFOfi9mf5TYCw1uolDaJSbUmBxP85DE6T4ouCMoN6pXw8ZoTeZCSEfSaYo+/s1w==", "cpu": [ "arm" ], @@ -3367,9 +3367,9 @@ ] }, "node_modules/@rollup/rollup-linux-arm-musleabihf": { - "version": "4.27.3", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-musleabihf/-/rollup-linux-arm-musleabihf-4.27.3.tgz", - "integrity": "sha512-Sv2GWmrJfRY57urktVLQ0VKZjNZGogVtASAgosDZ1aUB+ykPxSi3X1nWORL5Jk0sTIIwQiPH7iE3BMi9zGWfkg==", + "version": "4.27.4", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-musleabihf/-/rollup-linux-arm-musleabihf-4.27.4.tgz", + "integrity": "sha512-Vgdo4fpuphS9V24WOV+KwkCVJ72u7idTgQaBoLRD0UxBAWTF9GWurJO9YD9yh00BzbkhpeXtm6na+MvJU7Z73A==", "cpu": [ "arm" ], @@ -3381,9 +3381,9 @@ ] }, "node_modules/@rollup/rollup-linux-arm64-gnu": { - "version": "4.27.3", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-gnu/-/rollup-linux-arm64-gnu-4.27.3.tgz", - "integrity": "sha512-FPoJBLsPW2bDNWjSrwNuTPUt30VnfM8GPGRoLCYKZpPx0xiIEdFip3dH6CqgoT0RnoGXptaNziM0WlKgBc+OWQ==", + "version": "4.27.4", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-gnu/-/rollup-linux-arm64-gnu-4.27.4.tgz", + "integrity": "sha512-pleyNgyd1kkBkw2kOqlBx+0atfIIkkExOTiifoODo6qKDSpnc6WzUY5RhHdmTdIJXBdSnh6JknnYTtmQyobrVg==", "cpu": [ "arm64" ], @@ -3395,9 +3395,9 @@ ] }, "node_modules/@rollup/rollup-linux-arm64-musl": { - "version": "4.27.3", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-musl/-/rollup-linux-arm64-musl-4.27.3.tgz", - "integrity": "sha512-TKxiOvBorYq4sUpA0JT+Fkh+l+G9DScnG5Dqx7wiiqVMiRSkzTclP35pE6eQQYjP4Gc8yEkJGea6rz4qyWhp3g==", + "version": "4.27.4", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-musl/-/rollup-linux-arm64-musl-4.27.4.tgz", + "integrity": "sha512-caluiUXvUuVyCHr5DxL8ohaaFFzPGmgmMvwmqAITMpV/Q+tPoaHZ/PWa3t8B2WyoRcIIuu1hkaW5KkeTDNSnMA==", "cpu": [ "arm64" ], @@ -3409,9 +3409,9 @@ ] }, "node_modules/@rollup/rollup-linux-powerpc64le-gnu": { - "version": "4.27.3", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-powerpc64le-gnu/-/rollup-linux-powerpc64le-gnu-4.27.3.tgz", - "integrity": "sha512-v2M/mPvVUKVOKITa0oCFksnQQ/TqGrT+yD0184/cWHIu0LoIuYHwox0Pm3ccXEz8cEQDLk6FPKd1CCm+PlsISw==", + "version": "4.27.4", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-powerpc64le-gnu/-/rollup-linux-powerpc64le-gnu-4.27.4.tgz", + "integrity": "sha512-FScrpHrO60hARyHh7s1zHE97u0KlT/RECzCKAdmI+LEoC1eDh/RDji9JgFqyO+wPDb86Oa/sXkily1+oi4FzJQ==", "cpu": [ "ppc64" ], @@ -3423,9 +3423,9 @@ ] }, "node_modules/@rollup/rollup-linux-riscv64-gnu": { - "version": "4.27.3", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-riscv64-gnu/-/rollup-linux-riscv64-gnu-4.27.3.tgz", - "integrity": "sha512-LdrI4Yocb1a/tFVkzmOE5WyYRgEBOyEhWYJe4gsDWDiwnjYKjNs7PS6SGlTDB7maOHF4kxevsuNBl2iOcj3b4A==", + "version": "4.27.4", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-riscv64-gnu/-/rollup-linux-riscv64-gnu-4.27.4.tgz", + "integrity": "sha512-qyyprhyGb7+RBfMPeww9FlHwKkCXdKHeGgSqmIXw9VSUtvyFZ6WZRtnxgbuz76FK7LyoN8t/eINRbPUcvXB5fw==", "cpu": [ "riscv64" ], @@ -3437,9 +3437,9 @@ ] }, "node_modules/@rollup/rollup-linux-s390x-gnu": { - "version": "4.27.3", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-s390x-gnu/-/rollup-linux-s390x-gnu-4.27.3.tgz", - "integrity": "sha512-d4wVu6SXij/jyiwPvI6C4KxdGzuZOvJ6y9VfrcleHTwo68fl8vZC5ZYHsCVPUi4tndCfMlFniWgwonQ5CUpQcA==", + "version": "4.27.4", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-s390x-gnu/-/rollup-linux-s390x-gnu-4.27.4.tgz", + "integrity": "sha512-PFz+y2kb6tbh7m3A7nA9++eInGcDVZUACulf/KzDtovvdTizHpZaJty7Gp0lFwSQcrnebHOqxF1MaKZd7psVRg==", "cpu": [ "s390x" ], @@ -3451,9 +3451,9 @@ ] }, "node_modules/@rollup/rollup-linux-x64-gnu": { - "version": "4.27.3", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-gnu/-/rollup-linux-x64-gnu-4.27.3.tgz", - "integrity": "sha512-/6bn6pp1fsCGEY5n3yajmzZQAh+mW4QPItbiWxs69zskBzJuheb3tNynEjL+mKOsUSFK11X4LYF2BwwXnzWleA==", + "version": "4.27.4", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-gnu/-/rollup-linux-x64-gnu-4.27.4.tgz", + "integrity": "sha512-Ni8mMtfo+o/G7DVtweXXV/Ol2TFf63KYjTtoZ5f078AUgJTmaIJnj4JFU7TK/9SVWTaSJGxPi5zMDgK4w+Ez7Q==", "cpu": [ "x64" ], @@ -3465,9 +3465,9 @@ ] }, "node_modules/@rollup/rollup-linux-x64-musl": { - "version": "4.27.3", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-musl/-/rollup-linux-x64-musl-4.27.3.tgz", - "integrity": "sha512-nBXOfJds8OzUT1qUreT/en3eyOXd2EH5b0wr2bVB5999qHdGKkzGzIyKYaKj02lXk6wpN71ltLIaQpu58YFBoQ==", + "version": "4.27.4", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-musl/-/rollup-linux-x64-musl-4.27.4.tgz", + "integrity": "sha512-5AeeAF1PB9TUzD+3cROzFTnAJAcVUGLuR8ng0E0WXGkYhp6RD6L+6szYVX+64Rs0r72019KHZS1ka1q+zU/wUw==", "cpu": [ "x64" ], @@ -3479,9 +3479,9 @@ ] }, "node_modules/@rollup/rollup-win32-arm64-msvc": { - "version": "4.27.3", - "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-arm64-msvc/-/rollup-win32-arm64-msvc-4.27.3.tgz", - "integrity": "sha512-ogfbEVQgIZOz5WPWXF2HVb6En+kWzScuxJo/WdQTqEgeyGkaa2ui5sQav9Zkr7bnNCLK48uxmmK0TySm22eiuw==", + "version": "4.27.4", + "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-arm64-msvc/-/rollup-win32-arm64-msvc-4.27.4.tgz", + "integrity": "sha512-yOpVsA4K5qVwu2CaS3hHxluWIK5HQTjNV4tWjQXluMiiiu4pJj4BN98CvxohNCpcjMeTXk/ZMJBRbgRg8HBB6A==", "cpu": [ "arm64" ], @@ -3493,9 +3493,9 @@ ] }, "node_modules/@rollup/rollup-win32-ia32-msvc": { - "version": "4.27.3", - "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-ia32-msvc/-/rollup-win32-ia32-msvc-4.27.3.tgz", - "integrity": "sha512-ecE36ZBMLINqiTtSNQ1vzWc5pXLQHlf/oqGp/bSbi7iedcjcNb6QbCBNG73Euyy2C+l/fn8qKWEwxr+0SSfs3w==", + "version": "4.27.4", + "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-ia32-msvc/-/rollup-win32-ia32-msvc-4.27.4.tgz", + "integrity": "sha512-KtwEJOaHAVJlxV92rNYiG9JQwQAdhBlrjNRp7P9L8Cb4Rer3in+0A+IPhJC9y68WAi9H0sX4AiG2NTsVlmqJeQ==", "cpu": [ "ia32" ], @@ -3507,9 +3507,9 @@ ] }, "node_modules/@rollup/rollup-win32-x64-msvc": { - "version": "4.27.3", - "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-x64-msvc/-/rollup-win32-x64-msvc-4.27.3.tgz", - "integrity": "sha512-vliZLrDmYKyaUoMzEbMTg2JkerfBjn03KmAw9CykO0Zzkzoyd7o3iZNam/TpyWNjNT+Cz2iO3P9Smv2wgrR+Eg==", + "version": "4.27.4", + "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-x64-msvc/-/rollup-win32-x64-msvc-4.27.4.tgz", + "integrity": "sha512-3j4jx1TppORdTAoBJRd+/wJRGCPC0ETWkXOecJ6PPZLj6SptXkrXcNqdj0oclbKML6FkQltdz7bBA3rUSirZug==", "cpu": [ "x64" ], @@ -3712,9 +3712,9 @@ "license": "MIT" }, "node_modules/@types/node": { - "version": "22.9.1", - "resolved": "https://registry.npmjs.org/@types/node/-/node-22.9.1.tgz", - "integrity": "sha512-p8Yy/8sw1caA8CdRIQBG5tiLHmxtQKObCijiAa9Ez+d4+PRffM4054xbju0msf+cvhJpnFEeNjxmVT/0ipktrg==", + "version": "22.9.3", + "resolved": "https://registry.npmjs.org/@types/node/-/node-22.9.3.tgz", + "integrity": "sha512-F3u1fs/fce3FFk+DAxbxc78DF8x0cY09RRL8GnXLmkJ1jvx3TtPdWoTT5/NiYfI5ASqXBmfqJi9dZ3gxMx4lzw==", "license": "MIT", "dependencies": { "undici-types": "~6.19.8" @@ -4850,9 +4850,9 @@ } }, "node_modules/caniuse-lite": { - "version": "1.0.30001683", - "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001683.tgz", - "integrity": "sha512-iqmNnThZ0n70mNwvxpEC2nBJ037ZHZUoBI5Gorh1Mw6IlEAZujEoU1tXA628iZfzm7R9FvFzxbfdgml82a3k8Q==", + "version": "1.0.30001684", + "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001684.tgz", + "integrity": "sha512-G1LRwLIQjBQoyq0ZJGqGIJUXzJ8irpbjHLpVRXDvBEScFJ9b17sgK6vlx0GAJFE21okD7zXl08rRRUfq6HdoEQ==", "dev": true, "funding": [ { @@ -6287,9 +6287,9 @@ } }, "node_modules/file-selector": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/file-selector/-/file-selector-2.1.0.tgz", - "integrity": "sha512-ZuXAqGePcSPz4JuerOY06Dzzq0hrmQ6VGoXVzGyFI1npeOfBgqGIKKpznfYWRkSLJlXutkqVC5WvGZtkFVhu9Q==", + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/file-selector/-/file-selector-2.1.1.tgz", + "integrity": "sha512-pJVY80PuSiHbnYEZ0gZYQf15x0z/lkeIF1yn95yRC/Usb43343ewXtMClQ9GLPvPm4/SscX4zvQz9QhCAyLqlg==", "dev": true, "license": "MIT", "dependencies": { @@ -7253,13 +7253,16 @@ } }, "node_modules/is-finalizationregistry": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/is-finalizationregistry/-/is-finalizationregistry-1.0.2.tgz", - "integrity": "sha512-0by5vtUJs8iFQb5TYUHHPudOR+qXYIMKtiUzvLIZITZUjknFmziyBJuLhVRc+Ds0dREFlskDNJKYIdIzu/9pfw==", + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/is-finalizationregistry/-/is-finalizationregistry-1.1.0.tgz", + "integrity": "sha512-qfMdqbAQEwBw78ZyReKnlA8ezmPdb9BemzIIip/JkjaZUhitfXDkkr+3QTboW0JrSXT1QWyYShpvnNHGZ4c4yA==", "dev": true, "license": "MIT", "dependencies": { - "call-bind": "^1.0.2" + "call-bind": "^1.0.7" + }, + "engines": { + "node": ">= 0.4" }, "funding": { "url": "https://github.com/sponsors/ljharb" @@ -8291,9 +8294,9 @@ "license": "MIT" }, "node_modules/msw": { - "version": "2.6.5", - "resolved": "https://registry.npmjs.org/msw/-/msw-2.6.5.tgz", - "integrity": "sha512-PnlnTpUlOrj441kYQzzFhzMzMCGFT6a2jKUBG7zSpLkYS5oh8Arrbc0dL8/rNAtxaoBy0EVs2mFqj2qdmWK7lQ==", + "version": "2.6.6", + "resolved": "https://registry.npmjs.org/msw/-/msw-2.6.6.tgz", + "integrity": "sha512-npfIIVRHKQX3Lw4aLWX4wBh+lQwpqdZNyJYB5K/+ktK8NhtkdsTxGK7WDrgknozcVyRI7TOqY6yBS9j2FTR+YQ==", "dev": true, "hasInstallScript": true, "license": "MIT", @@ -9763,19 +9766,19 @@ } }, "node_modules/reflect.getprototypeof": { - "version": "1.0.6", - "resolved": "https://registry.npmjs.org/reflect.getprototypeof/-/reflect.getprototypeof-1.0.6.tgz", - "integrity": "sha512-fmfw4XgoDke3kdI6h4xcUz1dG8uaiv5q9gcEwLS4Pnth2kxT+GZ7YehS1JTMGBQmtV7Y4GFGbs2re2NqhdozUg==", + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/reflect.getprototypeof/-/reflect.getprototypeof-1.0.7.tgz", + "integrity": "sha512-bMvFGIUKlc/eSfXNX+aZ+EL95/EgZzuwA0OBPTbZZDEJw/0AkentjMuM1oiRfwHrshqk4RzdgiTg5CcDalXN5g==", "dev": true, "license": "MIT", "dependencies": { "call-bind": "^1.0.7", "define-properties": "^1.2.1", - "es-abstract": "^1.23.1", + "es-abstract": "^1.23.5", "es-errors": "^1.3.0", "get-intrinsic": "^1.2.4", - "globalthis": "^1.0.3", - "which-builtin-type": "^1.1.3" + "gopd": "^1.0.1", + "which-builtin-type": "^1.1.4" }, "engines": { "node": ">= 0.4" @@ -9950,9 +9953,9 @@ } }, "node_modules/rollup": { - "version": "4.27.3", - "resolved": "https://registry.npmjs.org/rollup/-/rollup-4.27.3.tgz", - "integrity": "sha512-SLsCOnlmGt9VoZ9Ek8yBK8tAdmPHeppkw+Xa7yDlCEhDTvwYei03JlWo1fdc7YTfLZ4tD8riJCUyAgTbszk1fQ==", + "version": "4.27.4", + "resolved": "https://registry.npmjs.org/rollup/-/rollup-4.27.4.tgz", + "integrity": "sha512-RLKxqHEMjh/RGLsDxAEsaLO3mWgyoU6x9w6n1ikAzet4B3gI2/3yP6PWY2p9QzRTh6MfEIXB3MwsOY0Iv3vNrw==", "dev": true, "license": "MIT", "dependencies": { @@ -9966,24 +9969,24 @@ "npm": ">=8.0.0" }, "optionalDependencies": { - "@rollup/rollup-android-arm-eabi": "4.27.3", - "@rollup/rollup-android-arm64": "4.27.3", - "@rollup/rollup-darwin-arm64": "4.27.3", - "@rollup/rollup-darwin-x64": "4.27.3", - "@rollup/rollup-freebsd-arm64": "4.27.3", - "@rollup/rollup-freebsd-x64": "4.27.3", - "@rollup/rollup-linux-arm-gnueabihf": "4.27.3", - "@rollup/rollup-linux-arm-musleabihf": "4.27.3", - "@rollup/rollup-linux-arm64-gnu": "4.27.3", - "@rollup/rollup-linux-arm64-musl": "4.27.3", - "@rollup/rollup-linux-powerpc64le-gnu": "4.27.3", - "@rollup/rollup-linux-riscv64-gnu": "4.27.3", - "@rollup/rollup-linux-s390x-gnu": "4.27.3", - "@rollup/rollup-linux-x64-gnu": "4.27.3", - "@rollup/rollup-linux-x64-musl": "4.27.3", - "@rollup/rollup-win32-arm64-msvc": "4.27.3", - "@rollup/rollup-win32-ia32-msvc": "4.27.3", - "@rollup/rollup-win32-x64-msvc": "4.27.3", + "@rollup/rollup-android-arm-eabi": "4.27.4", + "@rollup/rollup-android-arm64": "4.27.4", + "@rollup/rollup-darwin-arm64": "4.27.4", + "@rollup/rollup-darwin-x64": "4.27.4", + "@rollup/rollup-freebsd-arm64": "4.27.4", + "@rollup/rollup-freebsd-x64": "4.27.4", + "@rollup/rollup-linux-arm-gnueabihf": "4.27.4", + "@rollup/rollup-linux-arm-musleabihf": "4.27.4", + "@rollup/rollup-linux-arm64-gnu": "4.27.4", + "@rollup/rollup-linux-arm64-musl": "4.27.4", + "@rollup/rollup-linux-powerpc64le-gnu": "4.27.4", + "@rollup/rollup-linux-riscv64-gnu": "4.27.4", + "@rollup/rollup-linux-s390x-gnu": "4.27.4", + "@rollup/rollup-linux-x64-gnu": "4.27.4", + "@rollup/rollup-linux-x64-musl": "4.27.4", + "@rollup/rollup-win32-arm64-msvc": "4.27.4", + "@rollup/rollup-win32-ia32-msvc": "4.27.4", + "@rollup/rollup-win32-x64-msvc": "4.27.4", "fsevents": "~2.3.2" } }, @@ -10890,22 +10893,22 @@ } }, "node_modules/tldts": { - "version": "6.1.63", - "resolved": "https://registry.npmjs.org/tldts/-/tldts-6.1.63.tgz", - "integrity": "sha512-YWwhsjyn9sB/1rOkSRYxvkN/wl5LFM1QDv6F2pVR+pb/jFne4EOBxHfkKVWvDIBEAw9iGOwwubHtQTm0WRT5sQ==", + "version": "6.1.64", + "resolved": "https://registry.npmjs.org/tldts/-/tldts-6.1.64.tgz", + "integrity": "sha512-ph4AE5BXWIOsSy9stpoeo7bYe/Cy7VfpciIH4RhVZUPItCJmhqWCN0EVzxd8BOHiyNb42vuJc6NWTjJkg91Tuw==", "dev": true, "license": "MIT", "dependencies": { - "tldts-core": "^6.1.63" + "tldts-core": "^6.1.64" }, "bin": { "tldts": "bin/cli.js" } }, "node_modules/tldts-core": { - "version": "6.1.63", - "resolved": "https://registry.npmjs.org/tldts-core/-/tldts-core-6.1.63.tgz", - "integrity": "sha512-H1XCt54xY+QPbwhTgmxLkepX0MVHu3USfMmejiCOdkMbRcP22Pn2FVF127r/GWXVDmXTRezyF3Ckvhn4Fs6j7Q==", + "version": "6.1.64", + "resolved": "https://registry.npmjs.org/tldts-core/-/tldts-core-6.1.64.tgz", + "integrity": "sha512-uqnl8vGV16KsyflHOzqrYjjArjfXaU6rMPXYy2/ZWoRKCkXtghgB4VwTDXUG+t0OTGeSewNAG31/x1gCTfLt+Q==", "dev": true, "license": "MIT" }, @@ -10971,9 +10974,9 @@ } }, "node_modules/ts-api-utils": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/ts-api-utils/-/ts-api-utils-1.4.0.tgz", - "integrity": "sha512-032cPxaEKwM+GT3vA5JXNzIaizx388rhsSW79vGRNGXfRRAdEAn2mvk36PvK5HnOchyWZ7afLEXqYCvPCrzuzQ==", + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/ts-api-utils/-/ts-api-utils-1.4.1.tgz", + "integrity": "sha512-5RU2/lxTA3YUZxju61HO2U6EoZLvBLtmV2mbTvqyu4a/7s7RmJPT+1YekhMVsQhznRWk/czIwDUg+V8Q9ZuG4w==", "dev": true, "license": "MIT", "engines": { @@ -11074,9 +11077,9 @@ } }, "node_modules/type-fest": { - "version": "4.27.0", - "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-4.27.0.tgz", - "integrity": "sha512-3IMSWgP7C5KSQqmo1wjhKrwsvXAtF33jO3QY+Uy++ia7hqvgSK6iXbbg5PbDBc1P2ZbNEDgejOrN4YooXvhwCw==", + "version": "4.28.0", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-4.28.0.tgz", + "integrity": "sha512-jXMwges/FVbFRe5lTMJZVEZCrO9kI9c8k0PA/z7nF3bo0JSCCLysvokFjNPIUK/itEMas10MQM+AiHoHt/T/XA==", "dev": true, "license": "(MIT OR CC0-1.0)", "engines": { @@ -11144,18 +11147,18 @@ } }, "node_modules/typed-array-length": { - "version": "1.0.6", - "resolved": "https://registry.npmjs.org/typed-array-length/-/typed-array-length-1.0.6.tgz", - "integrity": "sha512-/OxDN6OtAk5KBpGb28T+HZc2M+ADtvRxXrKKbUwtsLgdoxgX13hyy7ek6bFRl5+aBs2yZzB0c4CnQfAtVypW/g==", + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/typed-array-length/-/typed-array-length-1.0.7.tgz", + "integrity": "sha512-3KS2b+kL7fsuk/eJZ7EQdnEmQoaho/r6KUef7hxvltNA5DR8NAUM+8wJMbJyZ4G9/7i3v5zPBIMN5aybAh2/Jg==", "dev": true, "license": "MIT", "dependencies": { "call-bind": "^1.0.7", "for-each": "^0.3.3", "gopd": "^1.0.1", - "has-proto": "^1.0.3", "is-typed-array": "^1.1.13", - "possible-typed-array-names": "^1.0.0" + "possible-typed-array-names": "^1.0.0", + "reflect.getprototypeof": "^1.0.6" }, "engines": { "node": ">= 0.4" @@ -11165,9 +11168,9 @@ } }, "node_modules/typescript": { - "version": "5.6.3", - "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.6.3.tgz", - "integrity": "sha512-hjcS1mhfuyi4WW8IWtjP7brDrG2cuDZukyrYrSauoXGNgx0S7zceP07adYkJycEr56BOUTNPzbInooiN3fn1qw==", + "version": "5.7.2", + "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.7.2.tgz", + "integrity": "sha512-i5t66RHxDvVN40HfDd1PsEThGNnlMCMT3jMUuoh9/0TaqWevNontacunWyN02LA9/fIbEWlcHZcgTKb9QoaLfg==", "dev": true, "license": "Apache-2.0", "bin": { @@ -11689,17 +11692,18 @@ } }, "node_modules/which-builtin-type": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/which-builtin-type/-/which-builtin-type-1.1.4.tgz", - "integrity": "sha512-bppkmBSsHFmIMSl8BO9TbsyzsvGjVoppt8xUiGzwiu/bhDCGxnpOKCxgqj6GuyHE0mINMDecBFPlOm2hzY084w==", + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/which-builtin-type/-/which-builtin-type-1.2.0.tgz", + "integrity": "sha512-I+qLGQ/vucCby4tf5HsLmGueEla4ZhwTBSqaooS+Y0BuxN4Cp+okmGuV+8mXZ84KDI9BA+oklo+RzKg0ONdSUA==", "dev": true, "license": "MIT", "dependencies": { + "call-bind": "^1.0.7", "function.prototype.name": "^1.1.6", "has-tostringtag": "^1.0.2", "is-async-function": "^2.0.0", "is-date-object": "^1.0.5", - "is-finalizationregistry": "^1.0.2", + "is-finalizationregistry": "^1.1.0", "is-generator-function": "^1.0.10", "is-regex": "^1.1.4", "is-weakref": "^1.0.2", diff --git a/apps/dolly-frontend/src/main/js/package.json b/apps/dolly-frontend/src/main/js/package.json index 41ca4f91f38..846ac1e1cc0 100644 --- a/apps/dolly-frontend/src/main/js/package.json +++ b/apps/dolly-frontend/src/main/js/package.json @@ -1,6 +1,6 @@ { "name": "dolly", - "version": "3.0.46", + "version": "3.0.47", "type": "module", "description": "", "main": "index.js", diff --git a/apps/dolly-frontend/src/main/js/src/components/bestillingsveileder/stegVelger/StegVelger.tsx b/apps/dolly-frontend/src/main/js/src/components/bestillingsveileder/stegVelger/StegVelger.tsx index 5454eb33afd..9adb83942f8 100644 --- a/apps/dolly-frontend/src/main/js/src/components/bestillingsveileder/stegVelger/StegVelger.tsx +++ b/apps/dolly-frontend/src/main/js/src/components/bestillingsveileder/stegVelger/StegVelger.tsx @@ -47,13 +47,15 @@ export const StegVelger = ({ initialValues, onSubmit }) => { const mutate = useMatchMutate() + const validationPaths = Object.keys(DollyValidation?.fields) + const isLastStep = () => step === STEPS.length - 1 const handleNext = () => { - formMethods.trigger().then((valid) => { + formMethods.trigger(validationPaths).then(() => { const errorFelter = Object.keys(formMethods.formState.errors) const kunEnvironmentError = errorFelter.length === 1 && errorFelter[0] === 'environments' const kunGruppeIdError = errorFelter.length === 1 && errorFelter[0] === 'gruppeId' - if (!valid && step === 1 && !kunEnvironmentError && !kunGruppeIdError) { + if (errorFelter.length > 0 && step === 1 && !kunEnvironmentError && !kunGruppeIdError) { console.warn('Feil i form, stopper navigering videre') console.error(formMethods.formState.errors) errorContext?.setShowError(true) diff --git a/apps/dolly-frontend/src/main/js/src/components/fagsystem/aareg/form/partials/arbeidsforholdToggle.tsx b/apps/dolly-frontend/src/main/js/src/components/fagsystem/aareg/form/partials/arbeidsforholdToggle.tsx index 0be7e3722ab..2fa15a4bd42 100644 --- a/apps/dolly-frontend/src/main/js/src/components/fagsystem/aareg/form/partials/arbeidsforholdToggle.tsx +++ b/apps/dolly-frontend/src/main/js/src/components/fagsystem/aareg/form/partials/arbeidsforholdToggle.tsx @@ -21,17 +21,21 @@ const ToggleArbeidsgiver = styled(ToggleGroup)` const DisabledToggleArbeidsgiver = styled(ToggleGroup)` display: grid; grid-template-columns: repeat(auto-fit, minmax(180px, 1fr)); + :hover { background-color: white; cursor: default; } + &&& { button { color: #aab0ba; } + .navds-toggle-group__button[aria-checked='true'] { background-color: #aab0ba; color: white; + :hover { background-color: #aab0ba; cursor: default; @@ -140,7 +144,7 @@ export const ArbeidsforholdToggle = ({ ) .filter((arbeidsforhold: any) => !_.isEmpty(arbeidsforhold)) if (!_.isEmpty(dupliserteAktiveArbeidsforhold)) { - formMethods.setError(`${path}.arbeidsgiver.orgnummer`, { + formMethods.setError(`manual.${path}.arbeidsgiver.orgnummer`, { message: `Identen har allerede pågående arbeidsforhold i org: ${dupliserteAktiveArbeidsforhold.toString()}`, }) } diff --git a/apps/dolly-frontend/src/main/js/src/components/fagsystem/aareg/form/partials/arbeidsgiverIdent.tsx b/apps/dolly-frontend/src/main/js/src/components/fagsystem/aareg/form/partials/arbeidsgiverIdent.tsx index 4abda6260cc..8bee26dad1d 100644 --- a/apps/dolly-frontend/src/main/js/src/components/fagsystem/aareg/form/partials/arbeidsgiverIdent.tsx +++ b/apps/dolly-frontend/src/main/js/src/components/fagsystem/aareg/form/partials/arbeidsgiverIdent.tsx @@ -27,10 +27,11 @@ export const ArbeidsgiverIdent = ({ if (result?.identNavigerTil) { formMethods.setValue(path, personnummer, { shouldTouch: true }) formMethods.trigger(path) + formMethods.clearErrors(`manual.${path}`) formMethods.clearErrors(path) setSuccess(true) } else { - formMethods.setError(path, { message: 'Fant ikke arbeidsgiver-ident' }) + formMethods.setError(`manual.${path}`, { message: 'Fant ikke arbeidsgiver-ident' }) } } }, [result, errorNaviger]) @@ -39,6 +40,7 @@ export const ArbeidsgiverIdent = ({ setSuccess(false) const personnr = event.target.value formMethods.setValue(path, '123', { shouldTouch: true }) + formMethods.clearErrors(`manual.${path}`) formMethods.trigger(path) setPersonnummer(personnr) } diff --git a/apps/dolly-frontend/src/main/js/src/components/fagsystem/brregstub/form/partials/EgneOrganisasjoner.tsx b/apps/dolly-frontend/src/main/js/src/components/fagsystem/brregstub/form/partials/EgneOrganisasjoner.tsx index d3184eb6425..4dea462cc8c 100644 --- a/apps/dolly-frontend/src/main/js/src/components/fagsystem/brregstub/form/partials/EgneOrganisasjoner.tsx +++ b/apps/dolly-frontend/src/main/js/src/components/fagsystem/brregstub/form/partials/EgneOrganisasjoner.tsx @@ -145,7 +145,7 @@ export const EgneOrganisasjoner = ({ const sjekkOrganisasjoner = () => { if (formMethods.watch(path) === '') { if (!_.has(formMethods.formState.errors, path)) { - formMethods.setError(path, { message: 'Feltet er påkrevd' }) + formMethods.setError(`manual.${path}`, { message: 'Feltet er påkrevd' }) } return { feilmelding: 'Feltet er påkrevd' } } diff --git a/apps/dolly-frontend/src/main/js/src/components/fagsystem/inntektstub/form/partials/orgnummerToggle.tsx b/apps/dolly-frontend/src/main/js/src/components/fagsystem/inntektstub/form/partials/orgnummerToggle.tsx index 09d673c01a5..9530bde71cd 100644 --- a/apps/dolly-frontend/src/main/js/src/components/fagsystem/inntektstub/form/partials/orgnummerToggle.tsx +++ b/apps/dolly-frontend/src/main/js/src/components/fagsystem/inntektstub/form/partials/orgnummerToggle.tsx @@ -39,6 +39,7 @@ export const OrgnummerToggle = ({ formMethods, opplysningspliktigPath, path }: P setInputType(value) sessionStorage.setItem(ORGANISASJONSTYPE_TOGGLE, value) formMethods.setValue(path, '') + formMethods.clearErrors(`manual.${path}`) formMethods.clearErrors(path) } @@ -50,8 +51,10 @@ export const OrgnummerToggle = ({ formMethods, opplysningspliktigPath, path }: P const handleManualOrgChange = (org: string, miljo: string) => { if (!org || !miljo) { + formMethods.setError(`manual.${path}`, { message: !org ? 'Skriv inn org' : 'Velg miljø' }) return } + formMethods.clearErrors(`manual.${path}`) formMethods.clearErrors(path) setLoading(true) setSuccess(false) @@ -59,7 +62,9 @@ export const OrgnummerToggle = ({ formMethods, opplysningspliktigPath, path }: P .then((response: { data: { enhetType: string; juridiskEnhet: any; orgnummer: any } }) => { setLoading(false) if (!validEnhetstyper.includes(response.data.enhetType)) { - formMethods.setError(path, { message: 'Organisasjonen må være av type BEDR eller AAFY' }) + formMethods.setError(`manual.${path}`, { + message: 'Organisasjonen må være av type BEDR eller AAFY', + }) return } if (!response.data.juridiskEnhet) { @@ -67,7 +72,9 @@ export const OrgnummerToggle = ({ formMethods, opplysningspliktigPath, path }: P opplysningspliktigPath && formMethods.setValue(`${opplysningspliktigPath}`, organisasjon.overenhet) } else { - formMethods.setError(path, { message: 'Organisasjonen mangler juridisk enhet' }) + formMethods.setError(`manual.${path}`, { + message: 'Organisasjonen mangler juridisk enhet', + }) return } } @@ -79,7 +86,7 @@ export const OrgnummerToggle = ({ formMethods, opplysningspliktigPath, path }: P }) .catch(() => { setLoading(false) - formMethods.setError(path, { message: 'Fant ikke organisasjonen i ' + miljo }) + formMethods.setError(`manual.${path}`, { message: 'Fant ikke organisasjonen i ' + miljo }) }) } diff --git a/apps/dolly-frontend/src/main/js/src/components/fagsystem/pensjon/form/GenerertInntektForm.tsx b/apps/dolly-frontend/src/main/js/src/components/fagsystem/pensjon/form/GenerertInntektForm.tsx index b2e24847831..e036e62a877 100644 --- a/apps/dolly-frontend/src/main/js/src/components/fagsystem/pensjon/form/GenerertInntektForm.tsx +++ b/apps/dolly-frontend/src/main/js/src/components/fagsystem/pensjon/form/GenerertInntektForm.tsx @@ -36,18 +36,19 @@ export const GenerertInntektForm = ({ gyldigFraOgMedAar, formMethods }) => { ) const handleGenerer = () => { - formMethods.clearErrors(pensjonGenererPath) + formMethods.clearErrors(`manual.${pensjonGenererPath}`) + formMethods.clearErrors(`${pensjonGenererPath}`) trigger(pensjonGenererPath) .then((values) => { if (!values) { - formMethods.setError(`${pensjonGenererPath}.generer.tomAar`, { + formMethods.setError(`manual.${pensjonGenererPath}.generer.tomAar`, { message: 'Velg et gyldig år', }) } formMethods.setValue(`${pensjonGenererPath}.inntekter`, values?.data?.arInntektGList) }) .catch(() => { - formMethods.setError(`${pensjonGenererPath}.generer.tomAar`, { + formMethods.setError(`manual.${pensjonGenererPath}.generer.tomAar`, { message: 'Velg et gyldig år', }) }) diff --git a/apps/dolly-frontend/src/main/js/src/components/fagsystem/sigrunstubPensjonsgivende/form/PensjonsgivendeInntektForm.tsx b/apps/dolly-frontend/src/main/js/src/components/fagsystem/sigrunstubPensjonsgivende/form/PensjonsgivendeInntektForm.tsx index 93db703bbc6..fc86b544780 100644 --- a/apps/dolly-frontend/src/main/js/src/components/fagsystem/sigrunstubPensjonsgivende/form/PensjonsgivendeInntektForm.tsx +++ b/apps/dolly-frontend/src/main/js/src/components/fagsystem/sigrunstubPensjonsgivende/form/PensjonsgivendeInntektForm.tsx @@ -61,7 +61,9 @@ const createInntektForm = (kodeverk, skatteordning, path, formMethods) => { export const PensjonsgivendeInntektForm = ({ path, formMethods, kodeverk, skatteordning }) => { const newEntry = getInitialInntekt(kodeverk, skatteordning) - const inntektError = _.get(formMethods.formState.errors, path)?.message + const inntektError = + _.get(formMethods.formState.errors, path)?.message || + _.get(formMethods.formState.errors, `manual${path}`)?.message return ( { formMethods.getValues(`${inntektPath}.${name}`) !== undefined ) { formMethods.setValue(`${inntektPath}.${name}`, undefined) + formMethods.clearErrors(`manual.${inntektPath}.${name}`) formMethods.clearErrors(`${inntektPath}.${name}`) } } @@ -107,6 +108,7 @@ const InntektStub = ({ inntektPath }) => { if (isObjectEmptyDeep(tilleggsinformasjon)) { formMethods.setValue(`${inntektPath}.tilleggsinformasjon`, undefined) + formMethods.clearErrors(`manual.${inntektPath}.tilleggsinformasjon`) formMethods.clearErrors(`${inntektPath}.tilleggsinformasjon`) } } diff --git a/apps/dolly-frontend/src/main/js/src/components/ui/form/inputs/datepicker/Datepicker.tsx b/apps/dolly-frontend/src/main/js/src/components/ui/form/inputs/datepicker/Datepicker.tsx index d91b1881cff..be2062d8add 100644 --- a/apps/dolly-frontend/src/main/js/src/components/ui/form/inputs/datepicker/Datepicker.tsx +++ b/apps/dolly-frontend/src/main/js/src/components/ui/form/inputs/datepicker/Datepicker.tsx @@ -17,55 +17,51 @@ import { convertInputToDate } from '@/components/ui/form/DateFormatUtils' registerLocale('nb', locale_nb) export const DollyDatepicker = (props: any) => { - const format = props.format || 'DD.MM.YYYY' + const { + excludeDates, + disabled, + onChange, + minDate = subYears(new Date(), 125), + name, + label, + maxDate = addYears(new Date(), 5), + format, + } = props + const dateFormat = format || 'DD.MM.YYYY' const formMethods = useFormContext() - const existingValue = formMethods.watch(props.name) + const existingValue = formMethods.watch(name) const [showDatepicker, setShowDatepicker] = useState(false) - const [input, setInput] = useState(existingValue ? formatDate(existingValue, format) : '') - const [errorMessage, setErrorMessage] = useState('') + const [input, setInput] = useState(existingValue ? formatDate(existingValue, dateFormat) : '') const getDatepickerProps = useCallback(() => { return useDatepicker({ - fromDate: props.minDate || subYears(new Date(), 125), - toDate: props.maxDate || addYears(new Date(), 5), - disabled: props.excludeDates, + fromDate: minDate, + toDate: maxDate, + disabled: excludeDates, }) - }, [props.minDate, props.maxDate, props.excludeDates, input]) + }, [minDate, maxDate, excludeDates, input]) const { datepickerProps, setSelected } = getDatepickerProps() useEffect(() => { const date = convertInputToDate(existingValue) - setInput(date?.isValid?.() ? formatDate(date, format) : existingValue) - formMethods.trigger(props.name).then(() => { + setInput(date?.isValid?.() ? formatDate(date, dateFormat) : existingValue) + formMethods.trigger(`manual.${name}`).then(() => { validateDate(date) }) }, []) - useEffect(() => { - if (errorMessage) { - formMethods.setError(props.name, { - type: 'invalid-date', - message: errorMessage, - }) - } else { - formMethods.clearErrors(props.name) - } - }, [errorMessage]) - const validateDate = (date) => { - if (!date || date.isValid?.()) { - setErrorMessage(null) - formMethods.clearErrors(props.name) - } else if (date.isAfter?.(props.maxDate) || date.isBefore?.(props.minDate)) { - setErrorMessage('Dato utenfor gyldig periode') - formMethods.setError(props.name, { + if (date?.isAfter?.(maxDate) || date?.isBefore?.(minDate)) { + formMethods.setError(`manual.${name}`, { type: 'invalid-date', message: 'Dato utenfor gyldig periode', }) + } else if (!date || date.isValid?.()) { + formMethods.clearErrors(`manual.${name}`) + formMethods.clearErrors(name) } else { - setErrorMessage('Ugyldig dato-format') - formMethods.setError(props.name, { + formMethods.setError(`manual.${name}`, { type: 'invalid-date-format', message: 'Ugyldig dato-format', }) @@ -74,12 +70,12 @@ export const DollyDatepicker = (props: any) => { const setFormDate = (date) => { const formDate = date.isValid?.() ? date.toDate() : date - props.onChange?.(formDate) + onChange?.(formDate) const dateStr = formDate?.toISOString?.().substring?.(0, 19) - formMethods.setValue(props.name, dateStr || date, { + formMethods.setValue(name, dateStr || date, { shouldTouch: true, }) - formMethods.trigger(props.name).then(() => { + formMethods.trigger(`manual.${name}`).then(() => { validateDate(date) }) } @@ -94,7 +90,8 @@ export const DollyDatepicker = (props: any) => { } setFormDate(date) - setInput(formatDate(date, format)) + setInput(formatDate(date, dateFormat)) + validateDate(date) } const DateInput = ( @@ -108,11 +105,11 @@ export const DollyDatepicker = (props: any) => { setInput(value) }} onBlur={handleInputBlur} - isDisabled={props.disabled} + isDisabled={disabled} input={input} icon={'calendar'} datepickerOnclick={() => { - if (!props.disabled) { + if (!disabled) { setShowDatepicker((prev) => !prev) } }} @@ -121,7 +118,7 @@ export const DollyDatepicker = (props: any) => { return ( - - + diff --git a/proxies/fullmakt-proxy/src/test/java/no/nav/testnav/proxies/fullmaktproxy/ApplicationContextTest.java b/proxies/fullmakt-proxy/src/test/java/no/nav/testnav/proxies/fullmaktproxy/ApplicationContextTest.java index 2cfbe3605db..9e39e82faac 100644 --- a/proxies/fullmakt-proxy/src/test/java/no/nav/testnav/proxies/fullmaktproxy/ApplicationContextTest.java +++ b/proxies/fullmakt-proxy/src/test/java/no/nav/testnav/proxies/fullmaktproxy/ApplicationContextTest.java @@ -6,15 +6,19 @@ import org.springframework.security.oauth2.jwt.ReactiveJwtDecoder; import org.springframework.test.context.ActiveProfiles; +import static org.assertj.core.api.AssertionsForClassTypes.assertThat; + @SpringBootTest @ActiveProfiles("test") class ApplicationContextTest { @MockBean - public ReactiveJwtDecoder reactiveJwtDecoder; + @SuppressWarnings("unused") + private ReactiveJwtDecoder reactiveJwtDecoder; @Test - @SuppressWarnings("java:S2699") void load_app_context() { + assertThat(true).isTrue(); } + } diff --git a/proxies/histark-proxy/README.md b/proxies/histark-proxy/README.md new file mode 100644 index 00000000000..674eee89b18 --- /dev/null +++ b/proxies/histark-proxy/README.md @@ -0,0 +1,3 @@ +## Lokal kjøring +* [Generelt.](../../docs/local_general.md) +* [Secret Manager.](../../docs/local_secretmanager.md) \ No newline at end of file diff --git a/proxies/histark-proxy/build.gradle b/proxies/histark-proxy/build.gradle index 5b7ad95f9f4..e77cab21cd2 100644 --- a/proxies/histark-proxy/build.gradle +++ b/proxies/histark-proxy/build.gradle @@ -11,5 +11,4 @@ sonarqube { dependencies { implementation "no.nav.testnav.libs:data-transfer-objects" - implementation "no.nav.testnav.libs:vault" } diff --git a/proxies/histark-proxy/settings.gradle b/proxies/histark-proxy/settings.gradle index 3664ec0c0d4..d42d8b80ebd 100644 --- a/proxies/histark-proxy/settings.gradle +++ b/proxies/histark-proxy/settings.gradle @@ -9,7 +9,6 @@ includeBuild "../../plugins/java" includeBuild "../../libs/data-transfer-objects" includeBuild "../../libs/reactive-core" includeBuild "../../libs/reactive-proxy" -includeBuild "../../libs/vault" develocity { buildScan { diff --git a/proxies/histark-proxy/src/main/java/no/nav/testnav/proxies/histarkproxy/LocalVaultConfig.java b/proxies/histark-proxy/src/main/java/no/nav/testnav/proxies/histarkproxy/LocalVaultConfig.java deleted file mode 100644 index 2e825162de7..00000000000 --- a/proxies/histark-proxy/src/main/java/no/nav/testnav/proxies/histarkproxy/LocalVaultConfig.java +++ /dev/null @@ -1,12 +0,0 @@ -package no.nav.testnav.proxies.histarkproxy; - -import no.nav.testnav.libs.vault.AbstractLocalVaultConfiguration; -import org.springframework.context.annotation.Configuration; -import org.springframework.context.annotation.Profile; -import org.springframework.vault.annotation.VaultPropertySource; - -@Configuration -@Profile("dev") -@VaultPropertySource(value = "azuread/prod/creds/team-dolly-lokal-app", ignoreSecretNotFound = false) -public class LocalVaultConfig extends AbstractLocalVaultConfiguration { -} diff --git a/proxies/histark-proxy/src/main/resources/application-dev.yml b/proxies/histark-proxy/src/main/resources/application-dev.yml new file mode 100644 index 00000000000..0f24d85a8e2 --- /dev/null +++ b/proxies/histark-proxy/src/main/resources/application-dev.yml @@ -0,0 +1,14 @@ +TOKEN_X_ISSUER: dummy + +spring: + cloud: + gcp: + secretmanager: + enabled: true + config: + import: "sm://" + security: + oauth2: + resourceserver: + aad: + accepted-audience: ${sm://azure-app-client-id}, api://${sm://azure-app-client-id} \ No newline at end of file diff --git a/proxies/histark-proxy/src/main/resources/application.yml b/proxies/histark-proxy/src/main/resources/application.yml index c57132d143a..a7fe5e1b935 100644 --- a/proxies/histark-proxy/src/main/resources/application.yml +++ b/proxies/histark-proxy/src/main/resources/application.yml @@ -10,7 +10,7 @@ spring: aad: issuer-uri: ${AAD_ISSUER_URI}/v2.0 jwk-set-uri: ${AAD_ISSUER_URI}/discovery/v2.0/keys - accepted-audience: ${azure.app.client.id}, api://${azure.app.client.id} + accepted-audience: ${AZURE_APP_CLIENT_ID}, api:// ${AZURE_APP_CLIENT_ID} tokenx: issuer-uri: ${TOKEN_X_ISSUER} jwk-set-uri: ${TOKEN_X_JWKS_URI} @@ -19,8 +19,9 @@ spring: gateway: httpclient: response-timeout: 600s - vault: - enabled: false + gcp: + secretmanager: + enabled: false server: servlet: diff --git a/proxies/histark-proxy/src/test/java/no/nav/testnav/proxies/histarkproxy/ApplicationContextTest.java b/proxies/histark-proxy/src/test/java/no/nav/testnav/proxies/histarkproxy/ApplicationContextTest.java index 28f402e674a..c8263cb22d3 100644 --- a/proxies/histark-proxy/src/test/java/no/nav/testnav/proxies/histarkproxy/ApplicationContextTest.java +++ b/proxies/histark-proxy/src/test/java/no/nav/testnav/proxies/histarkproxy/ApplicationContextTest.java @@ -6,15 +6,19 @@ import org.springframework.security.oauth2.jwt.ReactiveJwtDecoder; import org.springframework.test.context.ActiveProfiles; +import static org.assertj.core.api.AssertionsForClassTypes.assertThat; + @SpringBootTest @ActiveProfiles("test") class ApplicationContextTest { @MockBean - public ReactiveJwtDecoder reactiveJwtDecoder; + @SuppressWarnings("unused") + private ReactiveJwtDecoder reactiveJwtDecoder; @Test - @SuppressWarnings("java:S2699") void load_app_context() { + assertThat(true).isTrue(); } + } diff --git a/proxies/histark-proxy/src/test/resources/application-test.yml b/proxies/histark-proxy/src/test/resources/application-test.yml index 6c4ae555764..f05debbd219 100644 --- a/proxies/histark-proxy/src/test/resources/application-test.yml +++ b/proxies/histark-proxy/src/test/resources/application-test.yml @@ -1 +1 @@ -TOKEN_X_ISSUER: dummy +TOKEN_X_ISSUER: dummy \ No newline at end of file diff --git a/proxies/inntektstub-proxy/README.md b/proxies/inntektstub-proxy/README.md new file mode 100644 index 00000000000..674eee89b18 --- /dev/null +++ b/proxies/inntektstub-proxy/README.md @@ -0,0 +1,3 @@ +## Lokal kjøring +* [Generelt.](../../docs/local_general.md) +* [Secret Manager.](../../docs/local_secretmanager.md) \ No newline at end of file diff --git a/proxies/inntektstub-proxy/build.gradle b/proxies/inntektstub-proxy/build.gradle index d197c1556b0..2b0947f58d0 100644 --- a/proxies/inntektstub-proxy/build.gradle +++ b/proxies/inntektstub-proxy/build.gradle @@ -11,5 +11,4 @@ sonarqube { dependencies { implementation "no.nav.testnav.libs:data-transfer-objects" - implementation "no.nav.testnav.libs:vault" } diff --git a/proxies/inntektstub-proxy/settings.gradle b/proxies/inntektstub-proxy/settings.gradle index 631909031d6..e0e8654b062 100644 --- a/proxies/inntektstub-proxy/settings.gradle +++ b/proxies/inntektstub-proxy/settings.gradle @@ -9,7 +9,6 @@ includeBuild "../../plugins/java" includeBuild "../../libs/data-transfer-objects" includeBuild "../../libs/reactive-core" includeBuild "../../libs/reactive-proxy" -includeBuild "../../libs/vault" develocity { buildScan { diff --git a/proxies/inntektstub-proxy/src/main/java/no/nav/testnav/proxies/inntektstubproxy/LocalVaultConfig.java b/proxies/inntektstub-proxy/src/main/java/no/nav/testnav/proxies/inntektstubproxy/LocalVaultConfig.java deleted file mode 100644 index 8d619b3ab12..00000000000 --- a/proxies/inntektstub-proxy/src/main/java/no/nav/testnav/proxies/inntektstubproxy/LocalVaultConfig.java +++ /dev/null @@ -1,12 +0,0 @@ -package no.nav.testnav.proxies.inntektstubproxy; - -import no.nav.testnav.libs.vault.AbstractLocalVaultConfiguration; -import org.springframework.context.annotation.Configuration; -import org.springframework.context.annotation.Profile; -import org.springframework.vault.annotation.VaultPropertySource; - -@Configuration -@Profile("dev") -@VaultPropertySource(value = "azuread/prod/creds/team-dolly-lokal-app", ignoreSecretNotFound = false) -public class LocalVaultConfig extends AbstractLocalVaultConfiguration { -} diff --git a/proxies/inntektstub-proxy/src/main/resources/application-dev.yml b/proxies/inntektstub-proxy/src/main/resources/application-dev.yml new file mode 100644 index 00000000000..0f24d85a8e2 --- /dev/null +++ b/proxies/inntektstub-proxy/src/main/resources/application-dev.yml @@ -0,0 +1,14 @@ +TOKEN_X_ISSUER: dummy + +spring: + cloud: + gcp: + secretmanager: + enabled: true + config: + import: "sm://" + security: + oauth2: + resourceserver: + aad: + accepted-audience: ${sm://azure-app-client-id}, api://${sm://azure-app-client-id} \ No newline at end of file diff --git a/proxies/inntektstub-proxy/src/main/resources/application.yml b/proxies/inntektstub-proxy/src/main/resources/application.yml index d887142145a..b7851322180 100644 --- a/proxies/inntektstub-proxy/src/main/resources/application.yml +++ b/proxies/inntektstub-proxy/src/main/resources/application.yml @@ -10,7 +10,7 @@ spring: aad: issuer-uri: ${AAD_ISSUER_URI}/v2.0 jwk-set-uri: ${AAD_ISSUER_URI}/discovery/v2.0/keys - accepted-audience: ${azure.app.client.id}, api://${azure.app.client.id} + accepted-audience: ${AZURE_APP_CLIENT_ID}, api:// ${AZURE_APP_CLIENT_ID} tokenx: issuer-uri: ${TOKEN_X_ISSUER} jwk-set-uri: ${TOKEN_X_JWKS_URI} @@ -19,8 +19,9 @@ spring: gateway: httpclient: response-timeout: 600s - vault: - enabled: false + gcp: + secretmanager: + enabled: false server: servlet: diff --git a/proxies/inntektstub-proxy/src/test/java/no/nav/testnav/proxies/inntektstubproxy/ApplicationContextTest.java b/proxies/inntektstub-proxy/src/test/java/no/nav/testnav/proxies/inntektstubproxy/ApplicationContextTest.java index e4dfcea39ef..9409541e8e2 100644 --- a/proxies/inntektstub-proxy/src/test/java/no/nav/testnav/proxies/inntektstubproxy/ApplicationContextTest.java +++ b/proxies/inntektstub-proxy/src/test/java/no/nav/testnav/proxies/inntektstubproxy/ApplicationContextTest.java @@ -6,15 +6,19 @@ import org.springframework.security.oauth2.jwt.ReactiveJwtDecoder; import org.springframework.test.context.ActiveProfiles; +import static org.assertj.core.api.AssertionsForClassTypes.assertThat; + @SpringBootTest @ActiveProfiles("test") class ApplicationContextTest { @MockBean - public ReactiveJwtDecoder reactiveJwtDecoder; + @SuppressWarnings("unused") + private ReactiveJwtDecoder reactiveJwtDecoder; @Test - @SuppressWarnings("java:S2699") void load_app_context() { + assertThat(true).isTrue(); } + } diff --git a/proxies/inst-proxy/README.md b/proxies/inst-proxy/README.md new file mode 100644 index 00000000000..674eee89b18 --- /dev/null +++ b/proxies/inst-proxy/README.md @@ -0,0 +1,3 @@ +## Lokal kjøring +* [Generelt.](../../docs/local_general.md) +* [Secret Manager.](../../docs/local_secretmanager.md) \ No newline at end of file diff --git a/proxies/inst-proxy/build.gradle b/proxies/inst-proxy/build.gradle index ea42b084e65..001bbf62428 100644 --- a/proxies/inst-proxy/build.gradle +++ b/proxies/inst-proxy/build.gradle @@ -13,5 +13,4 @@ dependencies { implementation "no.nav.testnav.libs:data-transfer-objects" implementation "no.nav.testnav.libs:reactive-security" implementation "no.nav.testnav.libs:security-core" - implementation "no.nav.testnav.libs:vault" } \ No newline at end of file diff --git a/proxies/inst-proxy/settings.gradle b/proxies/inst-proxy/settings.gradle index 1118b88f555..7bd65178af0 100644 --- a/proxies/inst-proxy/settings.gradle +++ b/proxies/inst-proxy/settings.gradle @@ -11,7 +11,6 @@ includeBuild "../../libs/reactive-core" includeBuild "../../libs/reactive-proxy" includeBuild "../../libs/reactive-security" includeBuild "../../libs/security-core" -includeBuild "../../libs/vault" develocity { buildScan { diff --git a/proxies/inst-proxy/src/main/java/no/nav/testnav/proxies/instproxy/LocalVaultConfig.java b/proxies/inst-proxy/src/main/java/no/nav/testnav/proxies/instproxy/LocalVaultConfig.java deleted file mode 100644 index 2b85871801d..00000000000 --- a/proxies/inst-proxy/src/main/java/no/nav/testnav/proxies/instproxy/LocalVaultConfig.java +++ /dev/null @@ -1,12 +0,0 @@ -package no.nav.testnav.proxies.instproxy; - -import no.nav.testnav.libs.vault.AbstractLocalVaultConfiguration; -import org.springframework.context.annotation.Configuration; -import org.springframework.context.annotation.Profile; -import org.springframework.vault.annotation.VaultPropertySource; - -@Configuration -@Profile("dev") -@VaultPropertySource(value = "azuread/prod/creds/team-dolly-lokal-app", ignoreSecretNotFound = false) -public class LocalVaultConfig extends AbstractLocalVaultConfiguration { -} diff --git a/proxies/inst-proxy/src/main/resources/application-dev.yml b/proxies/inst-proxy/src/main/resources/application-dev.yml new file mode 100644 index 00000000000..0f24d85a8e2 --- /dev/null +++ b/proxies/inst-proxy/src/main/resources/application-dev.yml @@ -0,0 +1,14 @@ +TOKEN_X_ISSUER: dummy + +spring: + cloud: + gcp: + secretmanager: + enabled: true + config: + import: "sm://" + security: + oauth2: + resourceserver: + aad: + accepted-audience: ${sm://azure-app-client-id}, api://${sm://azure-app-client-id} \ No newline at end of file diff --git a/proxies/inst-proxy/src/main/resources/application.yml b/proxies/inst-proxy/src/main/resources/application.yml index 01dd5bd794a..59199e982f5 100644 --- a/proxies/inst-proxy/src/main/resources/application.yml +++ b/proxies/inst-proxy/src/main/resources/application.yml @@ -10,17 +10,18 @@ spring: aad: issuer-uri: ${AAD_ISSUER_URI}/v2.0 jwk-set-uri: ${AAD_ISSUER_URI}/discovery/v2.0/keys - accepted-audience: ${azure.app.client.id}, api://${azure.app.client.id} + accepted-audience: ${AZURE_APP_CLIENT_ID}, api:// ${AZURE_APP_CLIENT_ID} tokenx: issuer-uri: ${TOKEN_X_ISSUER} jwk-set-uri: ${TOKEN_X_JWKS_URI} accepted-audience: ${TOKEN_X_CLIENT_ID} cloud: - vault: - enabled: false gateway: httpclient: response-timeout: 180s + gcp: + secretmanager: + enabled: false server: servlet: diff --git a/proxies/inst-proxy/src/test/java/no/nav/testnav/proxies/instproxy/ApplicationContextTest.java b/proxies/inst-proxy/src/test/java/no/nav/testnav/proxies/instproxy/ApplicationContextTest.java index a306f7e9271..2fc7061fa85 100644 --- a/proxies/inst-proxy/src/test/java/no/nav/testnav/proxies/instproxy/ApplicationContextTest.java +++ b/proxies/inst-proxy/src/test/java/no/nav/testnav/proxies/instproxy/ApplicationContextTest.java @@ -6,15 +6,19 @@ import org.springframework.security.oauth2.jwt.ReactiveJwtDecoder; import org.springframework.test.context.ActiveProfiles; +import static org.assertj.core.api.AssertionsForClassTypes.assertThat; + @SpringBootTest @ActiveProfiles("test") class ApplicationContextTest { @MockBean - public ReactiveJwtDecoder reactiveJwtDecoder; + @SuppressWarnings("unused") + private ReactiveJwtDecoder reactiveJwtDecoder; @Test - @SuppressWarnings("java:S2699") void load_app_context() { + assertThat(true).isTrue(); } + } diff --git a/proxies/inst-proxy/src/test/resources/application-test.properties b/proxies/inst-proxy/src/test/resources/application-test.properties deleted file mode 100644 index e5e55886152..00000000000 --- a/proxies/inst-proxy/src/test/resources/application-test.properties +++ /dev/null @@ -1 +0,0 @@ -TOKEN_X_ISSUER=dummy \ No newline at end of file diff --git a/proxies/inst-proxy/src/test/resources/application-test.yml b/proxies/inst-proxy/src/test/resources/application-test.yml new file mode 100644 index 00000000000..f05debbd219 --- /dev/null +++ b/proxies/inst-proxy/src/test/resources/application-test.yml @@ -0,0 +1 @@ +TOKEN_X_ISSUER: dummy \ No newline at end of file diff --git a/proxies/kontoregister-person-proxy/README.md b/proxies/kontoregister-person-proxy/README.md new file mode 100644 index 00000000000..674eee89b18 --- /dev/null +++ b/proxies/kontoregister-person-proxy/README.md @@ -0,0 +1,3 @@ +## Lokal kjøring +* [Generelt.](../../docs/local_general.md) +* [Secret Manager.](../../docs/local_secretmanager.md) \ No newline at end of file diff --git a/proxies/kontoregister-person-proxy/build.gradle b/proxies/kontoregister-person-proxy/build.gradle index d0d9049d4ad..516d518b93a 100644 --- a/proxies/kontoregister-person-proxy/build.gradle +++ b/proxies/kontoregister-person-proxy/build.gradle @@ -13,8 +13,6 @@ dependencies { implementation "no.nav.testnav.libs:data-transfer-objects" implementation "no.nav.testnav.libs:reactive-security" implementation "no.nav.testnav.libs:security-core" - implementation "no.nav.testnav.libs:vault" implementation "org.springframework.boot:spring-boot-starter-webflux" - implementation "org.springframework.cloud:spring-cloud-starter-vault-config" } diff --git a/proxies/kontoregister-person-proxy/settings.gradle b/proxies/kontoregister-person-proxy/settings.gradle index 371a5277aa5..308e11806f5 100644 --- a/proxies/kontoregister-person-proxy/settings.gradle +++ b/proxies/kontoregister-person-proxy/settings.gradle @@ -11,7 +11,6 @@ includeBuild '../../libs/reactive-core' includeBuild '../../libs/reactive-proxy' includeBuild '../../libs/reactive-security' includeBuild '../../libs/security-core' -includeBuild '../../libs/vault' develocity { buildScan { diff --git a/proxies/kontoregister-person-proxy/src/main/java/no/nav/testnav/proxies/kontoregisterperson/KontoregisterProxyApplicationStarter.java b/proxies/kontoregister-person-proxy/src/main/java/no/nav/testnav/proxies/kontoregisterperson/KontoregisterProxyApplicationStarter.java index 2c06bde3093..db2525486aa 100644 --- a/proxies/kontoregister-person-proxy/src/main/java/no/nav/testnav/proxies/kontoregisterperson/KontoregisterProxyApplicationStarter.java +++ b/proxies/kontoregister-person-proxy/src/main/java/no/nav/testnav/proxies/kontoregisterperson/KontoregisterProxyApplicationStarter.java @@ -7,7 +7,6 @@ import no.nav.testnav.libs.reactivesecurity.exchange.azuread.TrygdeetatenAzureAdTokenService; import no.nav.testnav.libs.securitycore.domain.AccessToken; import no.nav.testnav.proxies.kontoregisterperson.config.Consumers; -import no.nav.testnav.proxies.kontoregisterperson.config.LocalVaultConfig; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; import org.springframework.cloud.gateway.route.RouteLocator; @@ -17,7 +16,6 @@ @Import({ CoreConfig.class, - LocalVaultConfig.class, SecurityConfig.class, SecureOAuth2ServerToServerConfiguration.class }) diff --git a/proxies/kontoregister-person-proxy/src/main/java/no/nav/testnav/proxies/kontoregisterperson/config/LocalVaultConfig.java b/proxies/kontoregister-person-proxy/src/main/java/no/nav/testnav/proxies/kontoregisterperson/config/LocalVaultConfig.java deleted file mode 100644 index b456766d674..00000000000 --- a/proxies/kontoregister-person-proxy/src/main/java/no/nav/testnav/proxies/kontoregisterperson/config/LocalVaultConfig.java +++ /dev/null @@ -1,12 +0,0 @@ -package no.nav.testnav.proxies.kontoregisterperson.config; - -import no.nav.testnav.libs.vault.AbstractLocalVaultConfiguration; -import org.springframework.context.annotation.Configuration; -import org.springframework.context.annotation.Profile; -import org.springframework.vault.annotation.VaultPropertySource; - -@Configuration -@Profile("dev") -@VaultPropertySource(value = "azuread/prod/creds/team-dolly-lokal-app", ignoreSecretNotFound = false) -public class LocalVaultConfig extends AbstractLocalVaultConfiguration { -} diff --git a/proxies/kontoregister-person-proxy/src/main/resources/application-dev.yml b/proxies/kontoregister-person-proxy/src/main/resources/application-dev.yml new file mode 100644 index 00000000000..0f24d85a8e2 --- /dev/null +++ b/proxies/kontoregister-person-proxy/src/main/resources/application-dev.yml @@ -0,0 +1,14 @@ +TOKEN_X_ISSUER: dummy + +spring: + cloud: + gcp: + secretmanager: + enabled: true + config: + import: "sm://" + security: + oauth2: + resourceserver: + aad: + accepted-audience: ${sm://azure-app-client-id}, api://${sm://azure-app-client-id} \ No newline at end of file diff --git a/proxies/kontoregister-person-proxy/src/main/resources/application.yml b/proxies/kontoregister-person-proxy/src/main/resources/application.yml index 9e6cd97e0d9..6c00b3b7101 100644 --- a/proxies/kontoregister-person-proxy/src/main/resources/application.yml +++ b/proxies/kontoregister-person-proxy/src/main/resources/application.yml @@ -10,7 +10,7 @@ spring: aad: issuer-uri: ${AAD_ISSUER_URI}/v2.0 jwk-set-uri: ${AAD_ISSUER_URI}/discovery/v2.0/keys - accepted-audience: ${azure.app.client.id}, api://${azure.app.client.id} + accepted-audience: ${AZURE_APP_CLIENT_ID}, api:// ${AZURE_APP_CLIENT_ID} tokenx: issuer-uri: ${TOKEN_X_ISSUER} jwk-set-uri: ${TOKEN_X_JWKS_URI} @@ -19,8 +19,9 @@ spring: gateway: httpclient: response-timeout: 600s - vault: - enabled: false + gcp: + secretmanager: + enabled: false server: servlet: diff --git a/proxies/kontoregister-person-proxy/src/test/java/no/nav/testnav/proxies/kontoregisterperson/ApplicationContextTest.java b/proxies/kontoregister-person-proxy/src/test/java/no/nav/testnav/proxies/kontoregisterperson/ApplicationContextTest.java index 11008df6b6b..0480187bda0 100644 --- a/proxies/kontoregister-person-proxy/src/test/java/no/nav/testnav/proxies/kontoregisterperson/ApplicationContextTest.java +++ b/proxies/kontoregister-person-proxy/src/test/java/no/nav/testnav/proxies/kontoregisterperson/ApplicationContextTest.java @@ -6,15 +6,19 @@ import org.springframework.security.oauth2.jwt.ReactiveJwtDecoder; import org.springframework.test.context.ActiveProfiles; +import static org.assertj.core.api.AssertionsForClassTypes.assertThat; + @SpringBootTest @ActiveProfiles("test") class ApplicationContextTest { @MockBean - public ReactiveJwtDecoder reactiveJwtDecoder; + @SuppressWarnings("unused") + private ReactiveJwtDecoder reactiveJwtDecoder; @Test - @SuppressWarnings("java:S2699") void load_app_context() { + assertThat(true).isTrue(); } + } diff --git a/proxies/kontoregister-person-proxy/src/test/resources/application-test.yml b/proxies/kontoregister-person-proxy/src/test/resources/application-test.yml index 6c4ae555764..f05debbd219 100644 --- a/proxies/kontoregister-person-proxy/src/test/resources/application-test.yml +++ b/proxies/kontoregister-person-proxy/src/test/resources/application-test.yml @@ -1 +1 @@ -TOKEN_X_ISSUER: dummy +TOKEN_X_ISSUER: dummy \ No newline at end of file diff --git a/proxies/krrstub-proxy/README.md b/proxies/krrstub-proxy/README.md new file mode 100644 index 00000000000..674eee89b18 --- /dev/null +++ b/proxies/krrstub-proxy/README.md @@ -0,0 +1,3 @@ +## Lokal kjøring +* [Generelt.](../../docs/local_general.md) +* [Secret Manager.](../../docs/local_secretmanager.md) \ No newline at end of file diff --git a/proxies/krrstub-proxy/build.gradle b/proxies/krrstub-proxy/build.gradle index 33757b2cc3c..c1e2ce31706 100644 --- a/proxies/krrstub-proxy/build.gradle +++ b/proxies/krrstub-proxy/build.gradle @@ -12,8 +12,6 @@ sonarqube { dependencies { implementation "no.nav.testnav.libs:reactive-security" implementation "no.nav.testnav.libs:security-core" - implementation "no.nav.testnav.libs:vault" implementation "org.springframework.boot:spring-boot-starter-webflux" - implementation "org.springframework.cloud:spring-cloud-starter-vault-config" } diff --git a/proxies/krrstub-proxy/settings.gradle b/proxies/krrstub-proxy/settings.gradle index 5625c1721a9..c78c01fb986 100644 --- a/proxies/krrstub-proxy/settings.gradle +++ b/proxies/krrstub-proxy/settings.gradle @@ -10,7 +10,6 @@ includeBuild '../../libs/reactive-core' includeBuild '../../libs/reactive-proxy' includeBuild '../../libs/reactive-security' includeBuild '../../libs/security-core' -includeBuild '../../libs/vault' develocity { buildScan { diff --git a/proxies/krrstub-proxy/src/main/java/no/nav/testnav/proxies/krrstubproxy/KrrstubProxyApplicationStarter.java b/proxies/krrstub-proxy/src/main/java/no/nav/testnav/proxies/krrstubproxy/KrrstubProxyApplicationStarter.java index eeb404fbaf4..84463fa8cdc 100644 --- a/proxies/krrstub-proxy/src/main/java/no/nav/testnav/proxies/krrstubproxy/KrrstubProxyApplicationStarter.java +++ b/proxies/krrstub-proxy/src/main/java/no/nav/testnav/proxies/krrstubproxy/KrrstubProxyApplicationStarter.java @@ -7,7 +7,6 @@ import no.nav.testnav.libs.reactivesecurity.exchange.azuread.TrygdeetatenAzureAdTokenService; import no.nav.testnav.libs.securitycore.domain.AccessToken; import no.nav.testnav.proxies.krrstubproxy.config.Consumers; -import no.nav.testnav.proxies.krrstubproxy.config.LocalVaultConfig; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; import org.springframework.cloud.gateway.route.RouteLocator; @@ -17,7 +16,6 @@ @Import({ CoreConfig.class, - LocalVaultConfig.class, SecurityConfig.class, SecureOAuth2ServerToServerConfiguration.class }) diff --git a/proxies/krrstub-proxy/src/main/java/no/nav/testnav/proxies/krrstubproxy/config/LocalVaultConfig.java b/proxies/krrstub-proxy/src/main/java/no/nav/testnav/proxies/krrstubproxy/config/LocalVaultConfig.java deleted file mode 100644 index 5a880c9c35f..00000000000 --- a/proxies/krrstub-proxy/src/main/java/no/nav/testnav/proxies/krrstubproxy/config/LocalVaultConfig.java +++ /dev/null @@ -1,13 +0,0 @@ -package no.nav.testnav.proxies.krrstubproxy.config; - -import no.nav.testnav.libs.vault.AbstractLocalVaultConfiguration; -import org.springframework.context.annotation.Configuration; -import org.springframework.context.annotation.Profile; -import org.springframework.vault.annotation.VaultPropertySource; - -@Configuration -@Profile("dev") -@VaultPropertySource(value = "azuread/prod/creds/team-dolly-lokal-app", ignoreSecretNotFound = false) -@VaultPropertySource(value = "kv/preprod/fss/testnav-krrstub-proxy/dev", ignoreSecretNotFound = false) -public class LocalVaultConfig extends AbstractLocalVaultConfiguration { -} \ No newline at end of file diff --git a/proxies/krrstub-proxy/src/main/resources/application-dev.yml b/proxies/krrstub-proxy/src/main/resources/application-dev.yml new file mode 100644 index 00000000000..0f24d85a8e2 --- /dev/null +++ b/proxies/krrstub-proxy/src/main/resources/application-dev.yml @@ -0,0 +1,14 @@ +TOKEN_X_ISSUER: dummy + +spring: + cloud: + gcp: + secretmanager: + enabled: true + config: + import: "sm://" + security: + oauth2: + resourceserver: + aad: + accepted-audience: ${sm://azure-app-client-id}, api://${sm://azure-app-client-id} \ No newline at end of file diff --git a/proxies/krrstub-proxy/src/main/resources/application.yml b/proxies/krrstub-proxy/src/main/resources/application.yml index 8a784650e62..f3100af5d9e 100644 --- a/proxies/krrstub-proxy/src/main/resources/application.yml +++ b/proxies/krrstub-proxy/src/main/resources/application.yml @@ -10,7 +10,7 @@ spring: aad: issuer-uri: ${AAD_ISSUER_URI}/v2.0 jwk-set-uri: ${AAD_ISSUER_URI}/discovery/v2.0/keys - accepted-audience: ${azure.app.client.id}, api://${azure.app.client.id} + accepted-audience: ${AZURE_APP_CLIENT_ID}, api:// ${AZURE_APP_CLIENT_ID} tokenx: issuer-uri: ${TOKEN_X_ISSUER} jwk-set-uri: ${TOKEN_X_JWKS_URI} @@ -19,8 +19,9 @@ spring: gateway: httpclient: response-timeout: 600s - vault: - enabled: false + gcp: + secretmanager: + enabled: false server: servlet: diff --git a/proxies/krrstub-proxy/src/test/java/no/nav/testnav/proxies/krrstubproxy/ApplicationContextTest.java b/proxies/krrstub-proxy/src/test/java/no/nav/testnav/proxies/krrstubproxy/ApplicationContextTest.java index 0a432023ceb..ad0124eba2b 100644 --- a/proxies/krrstub-proxy/src/test/java/no/nav/testnav/proxies/krrstubproxy/ApplicationContextTest.java +++ b/proxies/krrstub-proxy/src/test/java/no/nav/testnav/proxies/krrstubproxy/ApplicationContextTest.java @@ -6,15 +6,19 @@ import org.springframework.security.oauth2.jwt.ReactiveJwtDecoder; import org.springframework.test.context.ActiveProfiles; +import static org.assertj.core.api.AssertionsForClassTypes.assertThat; + @SpringBootTest @ActiveProfiles("test") class ApplicationContextTest { @MockBean - public ReactiveJwtDecoder reactiveJwtDecoder; + @SuppressWarnings("unused") + private ReactiveJwtDecoder reactiveJwtDecoder; @Test - @SuppressWarnings("java:S2699") void load_app_context() { + assertThat(true).isTrue(); } + } diff --git a/proxies/medl-proxy/README.md b/proxies/medl-proxy/README.md new file mode 100644 index 00000000000..674eee89b18 --- /dev/null +++ b/proxies/medl-proxy/README.md @@ -0,0 +1,3 @@ +## Lokal kjøring +* [Generelt.](../../docs/local_general.md) +* [Secret Manager.](../../docs/local_secretmanager.md) \ No newline at end of file diff --git a/proxies/medl-proxy/build.gradle b/proxies/medl-proxy/build.gradle index c2ae7901926..88115d2aa7b 100644 --- a/proxies/medl-proxy/build.gradle +++ b/proxies/medl-proxy/build.gradle @@ -12,8 +12,6 @@ sonarqube { dependencies { implementation "no.nav.testnav.libs:reactive-security" implementation "no.nav.testnav.libs:security-core" - implementation "no.nav.testnav.libs:vault" implementation "org.springframework.boot:spring-boot-starter-webflux" - implementation "org.springframework.cloud:spring-cloud-starter-vault-config" } diff --git a/proxies/medl-proxy/settings.gradle b/proxies/medl-proxy/settings.gradle index 7a74e821866..e59a1fa89e2 100644 --- a/proxies/medl-proxy/settings.gradle +++ b/proxies/medl-proxy/settings.gradle @@ -10,7 +10,6 @@ includeBuild '../../libs/reactive-core' includeBuild '../../libs/reactive-proxy' includeBuild '../../libs/reactive-security' includeBuild '../../libs/security-core' -includeBuild '../../libs/vault' develocity { buildScan { diff --git a/proxies/medl-proxy/src/main/java/no/nav/testnav/proxies/medlproxy/MedlProxyApplicationStarter.java b/proxies/medl-proxy/src/main/java/no/nav/testnav/proxies/medlproxy/MedlProxyApplicationStarter.java index fdcc8f93b25..52146c6cf38 100644 --- a/proxies/medl-proxy/src/main/java/no/nav/testnav/proxies/medlproxy/MedlProxyApplicationStarter.java +++ b/proxies/medl-proxy/src/main/java/no/nav/testnav/proxies/medlproxy/MedlProxyApplicationStarter.java @@ -7,7 +7,6 @@ import no.nav.testnav.libs.reactivesecurity.exchange.azuread.TrygdeetatenAzureAdTokenService; import no.nav.testnav.libs.securitycore.domain.AccessToken; import no.nav.testnav.proxies.medlproxy.config.Consumers; -import no.nav.testnav.proxies.medlproxy.config.LocalVaultConfig; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; import org.springframework.cloud.gateway.route.RouteLocator; @@ -17,7 +16,6 @@ @Import({ CoreConfig.class, - LocalVaultConfig.class, SecurityConfig.class, SecureOAuth2ServerToServerConfiguration.class }) diff --git a/proxies/medl-proxy/src/main/java/no/nav/testnav/proxies/medlproxy/config/LocalVaultConfig.java b/proxies/medl-proxy/src/main/java/no/nav/testnav/proxies/medlproxy/config/LocalVaultConfig.java deleted file mode 100644 index 56664cbbdee..00000000000 --- a/proxies/medl-proxy/src/main/java/no/nav/testnav/proxies/medlproxy/config/LocalVaultConfig.java +++ /dev/null @@ -1,12 +0,0 @@ -package no.nav.testnav.proxies.medlproxy.config; - -import no.nav.testnav.libs.vault.AbstractLocalVaultConfiguration; -import org.springframework.context.annotation.Configuration; -import org.springframework.context.annotation.Profile; -import org.springframework.vault.annotation.VaultPropertySource; - -@Configuration -@Profile("dev") -@VaultPropertySource(value = "azuread/prod/creds/team-dolly-lokal-app", ignoreSecretNotFound = false) -public class LocalVaultConfig extends AbstractLocalVaultConfiguration { -} \ No newline at end of file diff --git a/proxies/medl-proxy/src/main/resources/application-dev.yml b/proxies/medl-proxy/src/main/resources/application-dev.yml new file mode 100644 index 00000000000..0f24d85a8e2 --- /dev/null +++ b/proxies/medl-proxy/src/main/resources/application-dev.yml @@ -0,0 +1,14 @@ +TOKEN_X_ISSUER: dummy + +spring: + cloud: + gcp: + secretmanager: + enabled: true + config: + import: "sm://" + security: + oauth2: + resourceserver: + aad: + accepted-audience: ${sm://azure-app-client-id}, api://${sm://azure-app-client-id} \ No newline at end of file diff --git a/proxies/medl-proxy/src/main/resources/application.yml b/proxies/medl-proxy/src/main/resources/application.yml index fdbf0b0c264..d4b194e21fa 100644 --- a/proxies/medl-proxy/src/main/resources/application.yml +++ b/proxies/medl-proxy/src/main/resources/application.yml @@ -10,7 +10,7 @@ spring: aad: issuer-uri: ${AAD_ISSUER_URI}/v2.0 jwk-set-uri: ${AAD_ISSUER_URI}/discovery/v2.0/keys - accepted-audience: ${azure.app.client.id}, api://${azure.app.client.id} + accepted-audience: ${AZURE_APP_CLIENT_ID}, api:// ${AZURE_APP_CLIENT_ID} tokenx: issuer-uri: ${TOKEN_X_ISSUER} jwk-set-uri: ${TOKEN_X_JWKS_URI} @@ -19,8 +19,9 @@ spring: gateway: httpclient: response-timeout: 600s - vault: - enabled: false + gcp: + secretmanager: + enabled: false server: servlet: diff --git a/proxies/medl-proxy/src/test/java/no/nav/testnav/proxies/medlproxy/ApplicationContextTest.java b/proxies/medl-proxy/src/test/java/no/nav/testnav/proxies/medlproxy/ApplicationContextTest.java index 5b5208ebcd7..82e8113faaa 100644 --- a/proxies/medl-proxy/src/test/java/no/nav/testnav/proxies/medlproxy/ApplicationContextTest.java +++ b/proxies/medl-proxy/src/test/java/no/nav/testnav/proxies/medlproxy/ApplicationContextTest.java @@ -6,15 +6,19 @@ import org.springframework.security.oauth2.jwt.ReactiveJwtDecoder; import org.springframework.test.context.ActiveProfiles; +import static org.assertj.core.api.AssertionsForClassTypes.assertThat; + @SpringBootTest @ActiveProfiles("test") class ApplicationContextTest { @MockBean - public ReactiveJwtDecoder reactiveJwtDecoder; + @SuppressWarnings("unused") + private ReactiveJwtDecoder reactiveJwtDecoder; @Test - @SuppressWarnings("java:S2699") void load_app_context() { + assertThat(true).isTrue(); } + } diff --git a/proxies/medl-proxy/src/test/resources/application-test.yml b/proxies/medl-proxy/src/test/resources/application-test.yml index 5f3a2a2c0c8..f05debbd219 100644 --- a/proxies/medl-proxy/src/test/resources/application-test.yml +++ b/proxies/medl-proxy/src/test/resources/application-test.yml @@ -1,2 +1 @@ -azure.app.client.id: dummy TOKEN_X_ISSUER: dummy \ No newline at end of file diff --git a/proxies/norg2-proxy/README.md b/proxies/norg2-proxy/README.md new file mode 100644 index 00000000000..674eee89b18 --- /dev/null +++ b/proxies/norg2-proxy/README.md @@ -0,0 +1,3 @@ +## Lokal kjøring +* [Generelt.](../../docs/local_general.md) +* [Secret Manager.](../../docs/local_secretmanager.md) \ No newline at end of file diff --git a/proxies/norg2-proxy/build.gradle b/proxies/norg2-proxy/build.gradle index b7e51012270..414d34ac1e3 100644 --- a/proxies/norg2-proxy/build.gradle +++ b/proxies/norg2-proxy/build.gradle @@ -11,7 +11,4 @@ sonarqube { dependencies { implementation "no.nav.testnav.libs:data-transfer-objects" - implementation "no.nav.testnav.libs:vault" - - implementation "org.springframework.cloud:spring-cloud-starter-bootstrap" // TODO remove legacy bootstrap config } diff --git a/proxies/norg2-proxy/config.yml b/proxies/norg2-proxy/config.yml index 4ac00671cab..4dca79a69d0 100644 --- a/proxies/norg2-proxy/config.yml +++ b/proxies/norg2-proxy/config.yml @@ -53,8 +53,6 @@ spec: replicas: min: 1 max: 1 - vault: - enabled: false resources: requests: cpu: 200m diff --git a/proxies/norg2-proxy/settings.gradle b/proxies/norg2-proxy/settings.gradle index c5316e6e5bc..be380d614f9 100644 --- a/proxies/norg2-proxy/settings.gradle +++ b/proxies/norg2-proxy/settings.gradle @@ -9,7 +9,6 @@ includeBuild "../../plugins/java" includeBuild "../../libs/data-transfer-objects" includeBuild "../../libs/reactive-core" includeBuild "../../libs/reactive-proxy" -includeBuild "../../libs/vault" develocity { buildScan { diff --git a/proxies/norg2-proxy/src/main/java/no/nav/testnav/proxies/norg2proxy/LocalVaultConfig.java b/proxies/norg2-proxy/src/main/java/no/nav/testnav/proxies/norg2proxy/LocalVaultConfig.java deleted file mode 100644 index a5e41233db4..00000000000 --- a/proxies/norg2-proxy/src/main/java/no/nav/testnav/proxies/norg2proxy/LocalVaultConfig.java +++ /dev/null @@ -1,12 +0,0 @@ -package no.nav.testnav.proxies.norg2proxy; - -import no.nav.testnav.libs.vault.AbstractLocalVaultConfiguration; -import org.springframework.context.annotation.Configuration; -import org.springframework.context.annotation.Profile; -import org.springframework.vault.annotation.VaultPropertySource; - -@Configuration -@Profile("dev") -@VaultPropertySource(value = "azuread/prod/creds/team-dolly-lokal-app", ignoreSecretNotFound = false) -public class LocalVaultConfig extends AbstractLocalVaultConfiguration { -} diff --git a/proxies/norg2-proxy/src/main/resources/application-dev.yml b/proxies/norg2-proxy/src/main/resources/application-dev.yml new file mode 100644 index 00000000000..0f24d85a8e2 --- /dev/null +++ b/proxies/norg2-proxy/src/main/resources/application-dev.yml @@ -0,0 +1,14 @@ +TOKEN_X_ISSUER: dummy + +spring: + cloud: + gcp: + secretmanager: + enabled: true + config: + import: "sm://" + security: + oauth2: + resourceserver: + aad: + accepted-audience: ${sm://azure-app-client-id}, api://${sm://azure-app-client-id} \ No newline at end of file diff --git a/proxies/norg2-proxy/src/main/resources/application.yml b/proxies/norg2-proxy/src/main/resources/application.yml index 824d19c8596..7d580bc2045 100644 --- a/proxies/norg2-proxy/src/main/resources/application.yml +++ b/proxies/norg2-proxy/src/main/resources/application.yml @@ -10,7 +10,7 @@ spring: aad: issuer-uri: ${AAD_ISSUER_URI}/v2.0 jwk-set-uri: ${AAD_ISSUER_URI}/discovery/v2.0/keys - accepted-audience: ${azure.app.client.id}, api://${azure.app.client.id} + accepted-audience: ${AZURE_APP_CLIENT_ID}, api:// ${AZURE_APP_CLIENT_ID} tokenx: issuer-uri: ${TOKEN_X_ISSUER} jwk-set-uri: ${TOKEN_X_JWKS_URI} @@ -19,6 +19,9 @@ spring: gateway: httpclient: response-timeout: 600s + gcp: + secretmanager: + enabled: false server: servlet: diff --git a/proxies/norg2-proxy/src/main/resources/bootstrap.yml b/proxies/norg2-proxy/src/main/resources/bootstrap.yml deleted file mode 100644 index 0451449ca23..00000000000 --- a/proxies/norg2-proxy/src/main/resources/bootstrap.yml +++ /dev/null @@ -1,4 +0,0 @@ -spring: - cloud: - vault: - enabled: false \ No newline at end of file diff --git a/proxies/norg2-proxy/src/test/java/no/nav/testnav/proxies/norg2proxy/ApplicationContextTest.java b/proxies/norg2-proxy/src/test/java/no/nav/testnav/proxies/norg2proxy/ApplicationContextTest.java index ad2d5ff7389..7a125b93143 100644 --- a/proxies/norg2-proxy/src/test/java/no/nav/testnav/proxies/norg2proxy/ApplicationContextTest.java +++ b/proxies/norg2-proxy/src/test/java/no/nav/testnav/proxies/norg2proxy/ApplicationContextTest.java @@ -6,15 +6,19 @@ import org.springframework.security.oauth2.jwt.ReactiveJwtDecoder; import org.springframework.test.context.ActiveProfiles; +import static org.assertj.core.api.AssertionsForClassTypes.assertThat; + @SpringBootTest @ActiveProfiles("test") class ApplicationContextTest { @MockBean - public ReactiveJwtDecoder reactiveJwtDecoder; + @SuppressWarnings("unused") + private ReactiveJwtDecoder reactiveJwtDecoder; @Test - @SuppressWarnings("java:S2699") void load_app_context() { + assertThat(true).isTrue(); } + } diff --git a/proxies/pdl-proxy/README.md b/proxies/pdl-proxy/README.md new file mode 100644 index 00000000000..674eee89b18 --- /dev/null +++ b/proxies/pdl-proxy/README.md @@ -0,0 +1,3 @@ +## Lokal kjøring +* [Generelt.](../../docs/local_general.md) +* [Secret Manager.](../../docs/local_secretmanager.md) \ No newline at end of file diff --git a/proxies/pdl-proxy/build.gradle b/proxies/pdl-proxy/build.gradle index 8e425e34727..b88f07def05 100644 --- a/proxies/pdl-proxy/build.gradle +++ b/proxies/pdl-proxy/build.gradle @@ -13,9 +13,6 @@ dependencies { implementation "no.nav.testnav.libs:data-transfer-objects" implementation "no.nav.testnav.libs:reactive-security" implementation "no.nav.testnav.libs:security-core" - implementation "no.nav.testnav.libs:vault" implementation "org.springframework.boot:spring-boot-starter-webflux" - implementation "org.springframework.cloud:spring-cloud-starter-bootstrap" // TODO remove legacy bootstrap config. - implementation "org.springframework.cloud:spring-cloud-starter-vault-config" } diff --git a/proxies/pdl-proxy/config.yml b/proxies/pdl-proxy/config.yml index a685d4fd29e..64a77463673 100644 --- a/proxies/pdl-proxy/config.yml +++ b/proxies/pdl-proxy/config.yml @@ -90,8 +90,6 @@ spec: replicas: min: 1 max: 1 - vault: - enabled: true resources: requests: cpu: 200m @@ -100,5 +98,6 @@ spec: memory: 2048Mi envFrom: - secret: azure-trygdeetaten-testnav-pdl-proxy-trygdeetaten + - secret: testnav-pdl-proxy ingresses: - "https://testnav-pdl-proxy.dev-fss-pub.nais.io" diff --git a/proxies/pdl-proxy/settings.gradle b/proxies/pdl-proxy/settings.gradle index 56e4e14bc5a..bb575df7d4a 100644 --- a/proxies/pdl-proxy/settings.gradle +++ b/proxies/pdl-proxy/settings.gradle @@ -11,7 +11,6 @@ includeBuild "../../libs/reactive-core" includeBuild "../../libs/reactive-proxy" includeBuild "../../libs/reactive-security" includeBuild "../../libs/security-core" -includeBuild "../../libs/vault" develocity { buildScan { diff --git a/proxies/pdl-proxy/src/main/java/no/nav/testnav/proxies/pdlproxy/dto/CredentialsHolder.java b/proxies/pdl-proxy/src/main/java/no/nav/testnav/proxies/pdlproxy/CredentialsHolder.java similarity index 83% rename from proxies/pdl-proxy/src/main/java/no/nav/testnav/proxies/pdlproxy/dto/CredentialsHolder.java rename to proxies/pdl-proxy/src/main/java/no/nav/testnav/proxies/pdlproxy/CredentialsHolder.java index 97dc09c8bc4..c43b5cb96c3 100644 --- a/proxies/pdl-proxy/src/main/java/no/nav/testnav/proxies/pdlproxy/dto/CredentialsHolder.java +++ b/proxies/pdl-proxy/src/main/java/no/nav/testnav/proxies/pdlproxy/CredentialsHolder.java @@ -1,4 +1,4 @@ -package no.nav.testnav.proxies.pdlproxy.dto; +package no.nav.testnav.proxies.pdlproxy; public record CredentialsHolder(String hendelselagerApiKey, String aktoerAdminApiKey, diff --git a/proxies/pdl-proxy/src/main/java/no/nav/testnav/proxies/pdlproxy/PdlProxyApplicationStarter.java b/proxies/pdl-proxy/src/main/java/no/nav/testnav/proxies/pdlproxy/PdlProxyApplicationStarter.java index 30ef0028151..28d743293c1 100644 --- a/proxies/pdl-proxy/src/main/java/no/nav/testnav/proxies/pdlproxy/PdlProxyApplicationStarter.java +++ b/proxies/pdl-proxy/src/main/java/no/nav/testnav/proxies/pdlproxy/PdlProxyApplicationStarter.java @@ -8,8 +8,6 @@ import no.nav.testnav.libs.securitycore.domain.AccessToken; import no.nav.testnav.libs.securitycore.domain.ServerProperties; import no.nav.testnav.proxies.pdlproxy.config.Consumers; -import no.nav.testnav.proxies.pdlproxy.dto.CredentialsHolder; -import org.springframework.beans.factory.annotation.Value; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; import org.springframework.cloud.gateway.filter.GatewayFilter; @@ -35,16 +33,6 @@ public static void main(String[] args) { SpringApplication.run(PdlProxyApplicationStarter.class, args); } - @Bean - public CredentialsHolder credentialsHolder( - @Value("${hendelse.lager.api.key}") String hendelselagerApiKey, - @Value("${person.aktor.admin.api}") String aktoerAdminApiKey, - @Value("${elastic.username}") String elasticUsername, - @Value("${elastic.password}") String elasticPassword) { - - return new CredentialsHolder(hendelselagerApiKey, aktoerAdminApiKey, elasticUsername, elasticPassword); - } - @Bean public RouteLocator customRouteLocator(RouteLocatorBuilder builder, CredentialsHolder credentialsHolder, diff --git a/proxies/pdl-proxy/src/main/java/no/nav/testnav/proxies/pdlproxy/config/CredentialsConfig.java b/proxies/pdl-proxy/src/main/java/no/nav/testnav/proxies/pdlproxy/config/CredentialsConfig.java new file mode 100644 index 00000000000..ea1bd2eda70 --- /dev/null +++ b/proxies/pdl-proxy/src/main/java/no/nav/testnav/proxies/pdlproxy/config/CredentialsConfig.java @@ -0,0 +1,28 @@ +package no.nav.testnav.proxies.pdlproxy.config; + +import no.nav.testnav.proxies.pdlproxy.CredentialsHolder; +import org.springframework.beans.factory.annotation.Value; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; + +@Configuration +public class CredentialsConfig { + + @Value("${app.hendelse.lager.api.key}") + private String hendelselagerApiKey; + + @Value("${app.person.aktor.api.key}") + private String aktoerAdminApiKey; + + @Value("${app.elastic.username}") + private String elasticUsername; + + @Value("${app.elastic.password}") + private String elasticPassword; + + @Bean + CredentialsHolder credentialsHolder() { + return new CredentialsHolder(hendelselagerApiKey, aktoerAdminApiKey, elasticUsername, elasticPassword); + } + +} diff --git a/proxies/pdl-proxy/src/main/java/no/nav/testnav/proxies/pdlproxy/config/LocalVaultConfig.java b/proxies/pdl-proxy/src/main/java/no/nav/testnav/proxies/pdlproxy/config/LocalVaultConfig.java deleted file mode 100644 index c8ff2443b61..00000000000 --- a/proxies/pdl-proxy/src/main/java/no/nav/testnav/proxies/pdlproxy/config/LocalVaultConfig.java +++ /dev/null @@ -1,13 +0,0 @@ -package no.nav.testnav.proxies.pdlproxy.config; - -import no.nav.testnav.libs.vault.AbstractLocalVaultConfiguration; -import org.springframework.context.annotation.Configuration; -import org.springframework.context.annotation.Profile; -import org.springframework.vault.annotation.VaultPropertySource; - -@Profile("dev") -@Configuration -@VaultPropertySource(value = "azuread/prod/creds/team-dolly-lokal-app", ignoreSecretNotFound = false) -@VaultPropertySource(value = "kv/preprod/fss/testnav-pdl-proxy/dev", ignoreSecretNotFound = false) -public class LocalVaultConfig extends AbstractLocalVaultConfiguration { -} \ No newline at end of file diff --git a/proxies/pdl-proxy/src/main/resources/META-INF/additional-spring-configuration-metadata.json b/proxies/pdl-proxy/src/main/resources/META-INF/additional-spring-configuration-metadata.json new file mode 100644 index 00000000000..822e874f5ef --- /dev/null +++ b/proxies/pdl-proxy/src/main/resources/META-INF/additional-spring-configuration-metadata.json @@ -0,0 +1,23 @@ +{ + "properties": [ + { + "name": "app.hendelse.lager.api.key", + "type": "java.lang.String", + "description": "API key for hendelse-lager-api? Assigned by ?." + }, + { + "name": "app.person.aktor.api.key", + "type": "java.lang.String", + "description": "API key for person-aktor-api? Assigned by ?." + }, + { + "name": "app.elastic.username", + "type": "java.lang.String", + "description": "Elastic username." + }, + { + "name": "app.elastic.password", + "type": "java.lang.String", + "description": "Elastic password." + } + ] } \ No newline at end of file diff --git a/proxies/pdl-proxy/src/main/resources/application-dev.yml b/proxies/pdl-proxy/src/main/resources/application-dev.yml new file mode 100644 index 00000000000..946f65f4c53 --- /dev/null +++ b/proxies/pdl-proxy/src/main/resources/application-dev.yml @@ -0,0 +1,16 @@ +TOKEN_X_ISSUER: dummy + +spring: + cloud: + gcp: + secretmanager: + enabled: true + config: + import: "sm://" + +app: + elastic: + username: ${sm://elastic-username} + password: ${sm://elastic-password} + hendelse.lager.api.key: ${sm://hendelse-lager-api-key} + person.aktor.api.key: ${sm://person-aktor-api-key} \ No newline at end of file diff --git a/proxies/pdl-proxy/src/main/resources/application.yml b/proxies/pdl-proxy/src/main/resources/application.yml index e26237f80f4..0a8d4157349 100644 --- a/proxies/pdl-proxy/src/main/resources/application.yml +++ b/proxies/pdl-proxy/src/main/resources/application.yml @@ -10,7 +10,7 @@ spring: aad: issuer-uri: ${AAD_ISSUER_URI}/v2.0 jwk-set-uri: ${AAD_ISSUER_URI}/discovery/v2.0/keys - accepted-audience: ${azure.app.client.id}, api://${azure.app.client.id} + accepted-audience: ${AZURE_APP_CLIENT_ID}, api:// ${AZURE_APP_CLIENT_ID} tokenx: issuer-uri: ${TOKEN_X_ISSUER} jwk-set-uri: ${TOKEN_X_JWKS_URI} @@ -19,6 +19,16 @@ spring: gateway: httpclient: response-timeout: 1200s + gcp: + secretmanager: + enabled: false + +app: + elastic: + username: ${ELASTIC_USERNAME} + password: ${ELASTIC_PASSWORD} + hendelse.lager.api.key: ${HENDELSE_LAGER_API_KEY} + person.aktor.api.key: ${PERSON_AKTOR_API_KEY} sts: token: diff --git a/proxies/pdl-proxy/src/main/resources/bootstrap.yml b/proxies/pdl-proxy/src/main/resources/bootstrap.yml deleted file mode 100644 index 0451449ca23..00000000000 --- a/proxies/pdl-proxy/src/main/resources/bootstrap.yml +++ /dev/null @@ -1,4 +0,0 @@ -spring: - cloud: - vault: - enabled: false \ No newline at end of file diff --git a/proxies/pdl-proxy/src/test/java/no/nav/testnav/proxies/pdlproxy/ApplicationContextTest.java b/proxies/pdl-proxy/src/test/java/no/nav/testnav/proxies/pdlproxy/ApplicationContextTest.java index e7c3a307cba..105c63bc51e 100644 --- a/proxies/pdl-proxy/src/test/java/no/nav/testnav/proxies/pdlproxy/ApplicationContextTest.java +++ b/proxies/pdl-proxy/src/test/java/no/nav/testnav/proxies/pdlproxy/ApplicationContextTest.java @@ -6,15 +6,19 @@ import org.springframework.security.oauth2.jwt.ReactiveJwtDecoder; import org.springframework.test.context.ActiveProfiles; +import static org.assertj.core.api.AssertionsForClassTypes.assertThat; + @SpringBootTest @ActiveProfiles("test") class ApplicationContextTest { @MockBean + @SuppressWarnings("unused") private ReactiveJwtDecoder jwtDecoder; @Test - @SuppressWarnings("java:S2699") void load_app_context() { + assertThat(true).isTrue(); } + } diff --git a/proxies/pdl-proxy/src/test/resources/application-test.properties b/proxies/pdl-proxy/src/test/resources/application-test.properties deleted file mode 100644 index aa18dbf1e43..00000000000 --- a/proxies/pdl-proxy/src/test/resources/application-test.properties +++ /dev/null @@ -1,8 +0,0 @@ -TOKEN_X_ISSUER=dummy - -sts.token.provider.username=dummy -sts.token.provider.password=dummy -hendelse.lager.api.key=dummy -person.aktor.admin.api=dummy -elastic.username=dummy -elastic.password=dummy \ No newline at end of file diff --git a/proxies/pdl-proxy/src/test/resources/application-test.yml b/proxies/pdl-proxy/src/test/resources/application-test.yml new file mode 100644 index 00000000000..d77faa43b11 --- /dev/null +++ b/proxies/pdl-proxy/src/test/resources/application-test.yml @@ -0,0 +1,14 @@ +TOKEN_X_ISSUER: dummy + +sts: + token: + provider: + username: dummy + password: dummy + +app: + elastic: + username: dummy + password: dummy + hendelse.lager.api.key: dummy + person.aktor.api.key: dummy \ No newline at end of file diff --git a/proxies/pensjon-testdata-facade-proxy/README.md b/proxies/pensjon-testdata-facade-proxy/README.md new file mode 100644 index 00000000000..674eee89b18 --- /dev/null +++ b/proxies/pensjon-testdata-facade-proxy/README.md @@ -0,0 +1,3 @@ +## Lokal kjøring +* [Generelt.](../../docs/local_general.md) +* [Secret Manager.](../../docs/local_secretmanager.md) \ No newline at end of file diff --git a/proxies/pensjon-testdata-facade-proxy/build.gradle b/proxies/pensjon-testdata-facade-proxy/build.gradle index 5ed37360f08..c4710ef518d 100644 --- a/proxies/pensjon-testdata-facade-proxy/build.gradle +++ b/proxies/pensjon-testdata-facade-proxy/build.gradle @@ -13,8 +13,6 @@ dependencies { implementation "no.nav.testnav.libs:data-transfer-objects" implementation "no.nav.testnav.libs:reactive-security" implementation "no.nav.testnav.libs:security-core" - implementation "no.nav.testnav.libs:vault" implementation "org.springframework.boot:spring-boot-starter-webflux" - implementation "org.springframework.cloud:spring-cloud-starter-vault-config" } diff --git a/proxies/pensjon-testdata-facade-proxy/settings.gradle b/proxies/pensjon-testdata-facade-proxy/settings.gradle index 6936a160745..70f802c3a29 100644 --- a/proxies/pensjon-testdata-facade-proxy/settings.gradle +++ b/proxies/pensjon-testdata-facade-proxy/settings.gradle @@ -11,7 +11,6 @@ includeBuild "../../libs/reactive-core" includeBuild "../../libs/reactive-proxy" includeBuild "../../libs/reactive-security" includeBuild "../../libs/security-core" -includeBuild "../../libs/vault" develocity { buildScan { diff --git a/proxies/pensjon-testdata-facade-proxy/src/main/java/no/nav/testnav/proxies/pensjontestdatafacadeproxy/config/LocalVaultConfig.java b/proxies/pensjon-testdata-facade-proxy/src/main/java/no/nav/testnav/proxies/pensjontestdatafacadeproxy/config/LocalVaultConfig.java deleted file mode 100644 index b914fcf66f1..00000000000 --- a/proxies/pensjon-testdata-facade-proxy/src/main/java/no/nav/testnav/proxies/pensjontestdatafacadeproxy/config/LocalVaultConfig.java +++ /dev/null @@ -1,10 +0,0 @@ -package no.nav.testnav.proxies.pensjontestdatafacadeproxy.config; - -import no.nav.testnav.libs.vault.AbstractLocalVaultConfiguration; -import org.springframework.context.annotation.Configuration; -import org.springframework.context.annotation.Profile; - -@Configuration -@Profile("dev") -public class LocalVaultConfig extends AbstractLocalVaultConfiguration { -} diff --git a/proxies/pensjon-testdata-facade-proxy/src/main/resources/application-dev.yml b/proxies/pensjon-testdata-facade-proxy/src/main/resources/application-dev.yml index 70af6cc16b1..50f5dcfd4c1 100644 --- a/proxies/pensjon-testdata-facade-proxy/src/main/resources/application-dev.yml +++ b/proxies/pensjon-testdata-facade-proxy/src/main/resources/application-dev.yml @@ -1,3 +1,15 @@ +spring: + cloud: + gcp: + secretmanager: + enabled: true + config: + import: "sm://" + security: + oauth2: + resourceserver: + aad: + accepted-audience: ${sm://azure-app-client-id}, api://${sm://azure-app-client-id} consumers: pensjon-testdata-facade: diff --git a/proxies/pensjon-testdata-facade-proxy/src/main/resources/application.yml b/proxies/pensjon-testdata-facade-proxy/src/main/resources/application.yml index 6c15990c604..c614ed41395 100644 --- a/proxies/pensjon-testdata-facade-proxy/src/main/resources/application.yml +++ b/proxies/pensjon-testdata-facade-proxy/src/main/resources/application.yml @@ -10,7 +10,7 @@ spring: aad: issuer-uri: ${AAD_ISSUER_URI}/v2.0 jwk-set-uri: ${AAD_ISSUER_URI}/discovery/v2.0/keys - accepted-audience: ${azure.app.client.id}, api://${azure.app.client.id} + accepted-audience: ${AZURE_APP_CLIENT_ID}, api:// ${AZURE_APP_CLIENT_ID} cloud: gateway: httpclient: @@ -18,8 +18,9 @@ spring: wiretap: true httpserver: wiretap: true - vault: - enabled: false + gcp: + secretmanager: + enabled: false logging: level: diff --git a/proxies/pensjon-testdata-facade-proxy/src/test/java/no/nav/testnav/proxies/pensjontestdatafacadeproxy/ApplicationContextTest.java b/proxies/pensjon-testdata-facade-proxy/src/test/java/no/nav/testnav/proxies/pensjontestdatafacadeproxy/ApplicationContextTest.java index ec19c494775..eab4ba77905 100644 --- a/proxies/pensjon-testdata-facade-proxy/src/test/java/no/nav/testnav/proxies/pensjontestdatafacadeproxy/ApplicationContextTest.java +++ b/proxies/pensjon-testdata-facade-proxy/src/test/java/no/nav/testnav/proxies/pensjontestdatafacadeproxy/ApplicationContextTest.java @@ -6,15 +6,19 @@ import org.springframework.security.oauth2.jwt.ReactiveJwtDecoder; import org.springframework.test.context.ActiveProfiles; +import static org.assertj.core.api.AssertionsForClassTypes.assertThat; + @SpringBootTest @ActiveProfiles("test") class ApplicationContextTest { @MockBean - public ReactiveJwtDecoder reactiveJwtDecoder; + @SuppressWarnings("unused") + private ReactiveJwtDecoder reactiveJwtDecoder; @Test - @SuppressWarnings("java:S2699") void load_app_context() { + assertThat(true).isTrue(); } + } diff --git a/proxies/pensjon-testdata-facade-proxy/src/test/resources/application-test.yml b/proxies/pensjon-testdata-facade-proxy/src/test/resources/application-test.yml index 9b722c3bc51..2deeda02e69 100644 --- a/proxies/pensjon-testdata-facade-proxy/src/test/resources/application-test.yml +++ b/proxies/pensjon-testdata-facade-proxy/src/test/resources/application-test.yml @@ -1,4 +1,3 @@ - consumers: samboer-testdata: name: pensjon-dummy diff --git a/proxies/saf-proxy/README.md b/proxies/saf-proxy/README.md new file mode 100644 index 00000000000..674eee89b18 --- /dev/null +++ b/proxies/saf-proxy/README.md @@ -0,0 +1,3 @@ +## Lokal kjøring +* [Generelt.](../../docs/local_general.md) +* [Secret Manager.](../../docs/local_secretmanager.md) \ No newline at end of file diff --git a/proxies/saf-proxy/build.gradle b/proxies/saf-proxy/build.gradle index a6e2b4b82a6..ceba6e612a2 100644 --- a/proxies/saf-proxy/build.gradle +++ b/proxies/saf-proxy/build.gradle @@ -13,5 +13,4 @@ dependencies { implementation "no.nav.testnav.libs:data-transfer-objects" implementation "no.nav.testnav.libs:reactive-security" implementation "no.nav.testnav.libs:security-core" - implementation "no.nav.testnav.libs:vault" } diff --git a/proxies/saf-proxy/settings.gradle b/proxies/saf-proxy/settings.gradle index f6ae9850df9..f20834874e2 100644 --- a/proxies/saf-proxy/settings.gradle +++ b/proxies/saf-proxy/settings.gradle @@ -11,7 +11,6 @@ includeBuild "../../libs/reactive-core" includeBuild "../../libs/reactive-proxy" includeBuild "../../libs/reactive-security" includeBuild "../../libs/security-core" -includeBuild "../../libs/vault" develocity { buildScan { diff --git a/proxies/saf-proxy/src/main/java/no/nav/testnav/proxies/safproxy/LocalVaultConfig.java b/proxies/saf-proxy/src/main/java/no/nav/testnav/proxies/safproxy/LocalVaultConfig.java deleted file mode 100644 index ca70a76d15b..00000000000 --- a/proxies/saf-proxy/src/main/java/no/nav/testnav/proxies/safproxy/LocalVaultConfig.java +++ /dev/null @@ -1,12 +0,0 @@ -package no.nav.testnav.proxies.safproxy; - -import no.nav.testnav.libs.vault.AbstractLocalVaultConfiguration; -import org.springframework.context.annotation.Configuration; -import org.springframework.context.annotation.Profile; -import org.springframework.vault.annotation.VaultPropertySource; - -@Configuration -@Profile("dev") -@VaultPropertySource(value = "azuread/prod/creds/team-dolly-lokal-app", ignoreSecretNotFound = false) -public class LocalVaultConfig extends AbstractLocalVaultConfiguration { -} diff --git a/proxies/saf-proxy/src/main/resources/application-dev.yml b/proxies/saf-proxy/src/main/resources/application-dev.yml new file mode 100644 index 00000000000..0f24d85a8e2 --- /dev/null +++ b/proxies/saf-proxy/src/main/resources/application-dev.yml @@ -0,0 +1,14 @@ +TOKEN_X_ISSUER: dummy + +spring: + cloud: + gcp: + secretmanager: + enabled: true + config: + import: "sm://" + security: + oauth2: + resourceserver: + aad: + accepted-audience: ${sm://azure-app-client-id}, api://${sm://azure-app-client-id} \ No newline at end of file diff --git a/proxies/saf-proxy/src/main/resources/application.yml b/proxies/saf-proxy/src/main/resources/application.yml index 5ad17d622f3..0efb4d0b49b 100644 --- a/proxies/saf-proxy/src/main/resources/application.yml +++ b/proxies/saf-proxy/src/main/resources/application.yml @@ -10,7 +10,7 @@ spring: aad: issuer-uri: ${AAD_ISSUER_URI}/v2.0 jwk-set-uri: ${AAD_ISSUER_URI}/discovery/v2.0/keys - accepted-audience: ${azure.app.client.id}, api://${azure.app.client.id} + accepted-audience: ${AZURE_APP_CLIENT_ID}, api:// ${AZURE_APP_CLIENT_ID} tokenx: issuer-uri: ${TOKEN_X_ISSUER} jwk-set-uri: ${TOKEN_X_JWKS_URI} @@ -19,8 +19,9 @@ spring: gateway: httpclient: response-timeout: 1200s - vault: - enabled: false + gcp: + secretmanager: + enabled: false server: servlet: diff --git a/proxies/saf-proxy/src/test/java/no/nav/testnav/proxies/safproxy/ApplicationContextTest.java b/proxies/saf-proxy/src/test/java/no/nav/testnav/proxies/safproxy/ApplicationContextTest.java index b589621f621..410a0ab0c4e 100644 --- a/proxies/saf-proxy/src/test/java/no/nav/testnav/proxies/safproxy/ApplicationContextTest.java +++ b/proxies/saf-proxy/src/test/java/no/nav/testnav/proxies/safproxy/ApplicationContextTest.java @@ -6,15 +6,19 @@ import org.springframework.security.oauth2.jwt.ReactiveJwtDecoder; import org.springframework.test.context.ActiveProfiles; +import static org.assertj.core.api.AssertionsForClassTypes.assertThat; + @SpringBootTest @ActiveProfiles("test") class ApplicationContextTest { @MockBean + @SuppressWarnings("unused") public ReactiveJwtDecoder reactiveJwtDecoder; @Test - @SuppressWarnings("java:S2699") void load_app_context() { + assertThat(true).isTrue(); } + } diff --git a/proxies/saf-proxy/src/test/resources/application-test.yml b/proxies/saf-proxy/src/test/resources/application-test.yml index 3a0b87cb27e..d9e6fdf44ba 100644 --- a/proxies/saf-proxy/src/test/resources/application-test.yml +++ b/proxies/saf-proxy/src/test/resources/application-test.yml @@ -1,11 +1,9 @@ TOKEN_X_ISSUER: dummy + consumers: saf: url: http://saf-dummy.dummy.no cluster: dev-fss name: saf-dummy namespace: dummy -spring: - cloud: - vault: - enabled: false + diff --git a/proxies/sigrunstub-proxy/README.md b/proxies/sigrunstub-proxy/README.md new file mode 100644 index 00000000000..674eee89b18 --- /dev/null +++ b/proxies/sigrunstub-proxy/README.md @@ -0,0 +1,3 @@ +## Lokal kjøring +* [Generelt.](../../docs/local_general.md) +* [Secret Manager.](../../docs/local_secretmanager.md) \ No newline at end of file diff --git a/proxies/sigrunstub-proxy/build.gradle b/proxies/sigrunstub-proxy/build.gradle index 2eeeaa62ff6..b6c1e5e936a 100644 --- a/proxies/sigrunstub-proxy/build.gradle +++ b/proxies/sigrunstub-proxy/build.gradle @@ -11,5 +11,4 @@ sonarqube { dependencies { implementation "no.nav.testnav.libs:data-transfer-objects" - implementation "no.nav.testnav.libs:vault" } diff --git a/proxies/sigrunstub-proxy/settings.gradle b/proxies/sigrunstub-proxy/settings.gradle index b0883859278..fa1ab721eca 100644 --- a/proxies/sigrunstub-proxy/settings.gradle +++ b/proxies/sigrunstub-proxy/settings.gradle @@ -9,7 +9,6 @@ includeBuild "../../plugins/java" includeBuild "../../libs/data-transfer-objects" includeBuild "../../libs/reactive-core" includeBuild "../../libs/reactive-proxy" -includeBuild "../../libs/vault" develocity { buildScan { diff --git a/proxies/sigrunstub-proxy/src/main/java/no/nav/testnav/proxies/sigrunstubproxy/LocalVaultConfig.java b/proxies/sigrunstub-proxy/src/main/java/no/nav/testnav/proxies/sigrunstubproxy/LocalVaultConfig.java deleted file mode 100644 index 037351b909c..00000000000 --- a/proxies/sigrunstub-proxy/src/main/java/no/nav/testnav/proxies/sigrunstubproxy/LocalVaultConfig.java +++ /dev/null @@ -1,12 +0,0 @@ -package no.nav.testnav.proxies.sigrunstubproxy; - -import no.nav.testnav.libs.vault.AbstractLocalVaultConfiguration; -import org.springframework.context.annotation.Configuration; -import org.springframework.context.annotation.Profile; -import org.springframework.vault.annotation.VaultPropertySource; - -@Configuration -@Profile("dev") -@VaultPropertySource(value = "azuread/prod/creds/team-dolly-lokal-app", ignoreSecretNotFound = false) -public class LocalVaultConfig extends AbstractLocalVaultConfiguration { -} diff --git a/proxies/sigrunstub-proxy/src/main/resources/application-dev.yml b/proxies/sigrunstub-proxy/src/main/resources/application-dev.yml new file mode 100644 index 00000000000..0f24d85a8e2 --- /dev/null +++ b/proxies/sigrunstub-proxy/src/main/resources/application-dev.yml @@ -0,0 +1,14 @@ +TOKEN_X_ISSUER: dummy + +spring: + cloud: + gcp: + secretmanager: + enabled: true + config: + import: "sm://" + security: + oauth2: + resourceserver: + aad: + accepted-audience: ${sm://azure-app-client-id}, api://${sm://azure-app-client-id} \ No newline at end of file diff --git a/proxies/sigrunstub-proxy/src/main/resources/application.yml b/proxies/sigrunstub-proxy/src/main/resources/application.yml index 7276fd556ff..4e14eb4e948 100644 --- a/proxies/sigrunstub-proxy/src/main/resources/application.yml +++ b/proxies/sigrunstub-proxy/src/main/resources/application.yml @@ -10,7 +10,7 @@ spring: aad: issuer-uri: ${AAD_ISSUER_URI}/v2.0 jwk-set-uri: ${AAD_ISSUER_URI}/discovery/v2.0/keys - accepted-audience: ${azure.app.client.id}, api://${azure.app.client.id} + accepted-audience: ${AZURE_APP_CLIENT_ID}, api:// ${AZURE_APP_CLIENT_ID} tokenx: issuer-uri: ${TOKEN_X_ISSUER} jwk-set-uri: ${TOKEN_X_JWKS_URI} @@ -19,8 +19,9 @@ spring: gateway: httpclient: response-timeout: 600s - vault: - enabled: false + gcp: + secretmanager: + enabled: false server: servlet: diff --git a/proxies/sigrunstub-proxy/src/test/java/no/nav/testnav/proxies/sigrunstubproxy/ApplicationContextTest.java b/proxies/sigrunstub-proxy/src/test/java/no/nav/testnav/proxies/sigrunstubproxy/ApplicationContextTest.java index 2199cc1f682..47bf9ceff2e 100644 --- a/proxies/sigrunstub-proxy/src/test/java/no/nav/testnav/proxies/sigrunstubproxy/ApplicationContextTest.java +++ b/proxies/sigrunstub-proxy/src/test/java/no/nav/testnav/proxies/sigrunstubproxy/ApplicationContextTest.java @@ -6,15 +6,19 @@ import org.springframework.security.oauth2.jwt.ReactiveJwtDecoder; import org.springframework.test.context.ActiveProfiles; +import static org.assertj.core.api.AssertionsForClassTypes.assertThat; + @SpringBootTest @ActiveProfiles("test") class ApplicationContextTest { @MockBean - public ReactiveJwtDecoder reactiveJwtDecoder; + @SuppressWarnings("unused") + private ReactiveJwtDecoder reactiveJwtDecoder; @Test - @SuppressWarnings("java:S2699") void load_app_context() { + assertThat(true).isTrue(); } + } diff --git a/proxies/sigrunstub-proxy/src/test/resources/application-test.properties b/proxies/sigrunstub-proxy/src/test/resources/application-test.properties deleted file mode 100644 index e5e55886152..00000000000 --- a/proxies/sigrunstub-proxy/src/test/resources/application-test.properties +++ /dev/null @@ -1 +0,0 @@ -TOKEN_X_ISSUER=dummy \ No newline at end of file diff --git a/proxies/sigrunstub-proxy/src/test/resources/application-test.yml b/proxies/sigrunstub-proxy/src/test/resources/application-test.yml new file mode 100644 index 00000000000..f05debbd219 --- /dev/null +++ b/proxies/sigrunstub-proxy/src/test/resources/application-test.yml @@ -0,0 +1 @@ +TOKEN_X_ISSUER: dummy \ No newline at end of file diff --git a/proxies/skjermingsregister-proxy/README.md b/proxies/skjermingsregister-proxy/README.md new file mode 100644 index 00000000000..674eee89b18 --- /dev/null +++ b/proxies/skjermingsregister-proxy/README.md @@ -0,0 +1,3 @@ +## Lokal kjøring +* [Generelt.](../../docs/local_general.md) +* [Secret Manager.](../../docs/local_secretmanager.md) \ No newline at end of file diff --git a/proxies/skjermingsregister-proxy/src/main/resources/META-INF/additional-spring-configuration-metadata.json b/proxies/skjermingsregister-proxy/src/main/resources/META-INF/additional-spring-configuration-metadata.json new file mode 100644 index 00000000000..2a704be2f85 --- /dev/null +++ b/proxies/skjermingsregister-proxy/src/main/resources/META-INF/additional-spring-configuration-metadata.json @@ -0,0 +1,8 @@ +{ + "properties": [ + { + "name": "consumers.skjermingsregister.url", + "type": "java.net.URL", + "description": "URL to service skjermede-personer." + } +] } \ No newline at end of file diff --git a/proxies/skjermingsregister-proxy/src/main/resources/application-local.yml b/proxies/skjermingsregister-proxy/src/main/resources/application-local.yml new file mode 100644 index 00000000000..0f24d85a8e2 --- /dev/null +++ b/proxies/skjermingsregister-proxy/src/main/resources/application-local.yml @@ -0,0 +1,14 @@ +TOKEN_X_ISSUER: dummy + +spring: + cloud: + gcp: + secretmanager: + enabled: true + config: + import: "sm://" + security: + oauth2: + resourceserver: + aad: + accepted-audience: ${sm://azure-app-client-id}, api://${sm://azure-app-client-id} \ No newline at end of file diff --git a/proxies/skjermingsregister-proxy/src/main/resources/application.yml b/proxies/skjermingsregister-proxy/src/main/resources/application.yml index 675b5454381..4db5b00c8b2 100644 --- a/proxies/skjermingsregister-proxy/src/main/resources/application.yml +++ b/proxies/skjermingsregister-proxy/src/main/resources/application.yml @@ -10,17 +10,18 @@ spring: aad: issuer-uri: ${AAD_ISSUER_URI}/v2.0 jwk-set-uri: ${AAD_ISSUER_URI}/discovery/v2.0/keys - accepted-audience: ${azure.app.client.id}, api://${azure.app.client.id} + accepted-audience: ${AZURE_APP_CLIENT_ID}, api:// ${AZURE_APP_CLIENT_ID} tokenx: issuer-uri: ${TOKEN_X_ISSUER} jwk-set-uri: ${TOKEN_X_JWKS_URI} accepted-audience: ${TOKEN_X_CLIENT_ID} cloud: - vault: - enabled: false gateway: httpclient: response-timeout: 30s + gcp: + secretmanager: + enabled: false server: servlet: diff --git a/proxies/skjermingsregister-proxy/src/test/resources/application-test.yml b/proxies/skjermingsregister-proxy/src/test/resources/application-test.yml index f77593af929..3a43869267f 100644 --- a/proxies/skjermingsregister-proxy/src/test/resources/application-test.yml +++ b/proxies/skjermingsregister-proxy/src/test/resources/application-test.yml @@ -1,4 +1,5 @@ TOKEN_X_ISSUER: dummy -proxy.url: http://localhost STS_TOKEN_PROVIDER_USERNAME: dummy -STS_TOKEN_PROVIDER_PASSWORD: dummy \ No newline at end of file +STS_TOKEN_PROVIDER_PASSWORD: dummy + +proxy.url: http://localhost \ No newline at end of file diff --git a/proxies/sykemelding-proxy/src/main/resources/application.yml b/proxies/sykemelding-proxy/src/main/resources/application.yml index e6753ab77f1..1d29c30041d 100644 --- a/proxies/sykemelding-proxy/src/main/resources/application.yml +++ b/proxies/sykemelding-proxy/src/main/resources/application.yml @@ -16,8 +16,9 @@ spring: jwk-set-uri: ${TOKEN_X_JWKS_URI} accepted-audience: ${TOKEN_X_CLIENT_ID} cloud: - vault: - enabled: false + gcp: + secretmanager: + enabled: false gateway: httpclient: response-timeout: 30s diff --git a/proxies/synthdata-meldekort-proxy/README.md b/proxies/synthdata-meldekort-proxy/README.md index 7384301da9a..dfa8479ddd6 100644 --- a/proxies/synthdata-meldekort-proxy/README.md +++ b/proxies/synthdata-meldekort-proxy/README.md @@ -5,12 +5,9 @@ nå synt-applikasjonen. ## Lokal kjøring -Start `SynthdataMeldekortProxyApplicationStarter` med følgende props: - -``` --Dspring.profiles.active=dev --Dspring.cloud.vault.token=<> -``` +## Lokal kjøring +* [Generelt.](../../docs/local_general.md) +* [Secret Manager.](../../docs/local_secretmanager.md) ## Access token Siden proxy-en kjører med trygdeetaten tenant kan man ikke bruke oversikt-frontend for å hente access token når man diff --git a/proxies/synthdata-meldekort-proxy/build.gradle b/proxies/synthdata-meldekort-proxy/build.gradle index ce19804eec5..66ce73cf9ae 100644 --- a/proxies/synthdata-meldekort-proxy/build.gradle +++ b/proxies/synthdata-meldekort-proxy/build.gradle @@ -19,8 +19,6 @@ dependencies { implementation "no.nav.testnav.libs:data-transfer-objects" implementation "no.nav.testnav.libs:reactive-security" implementation "no.nav.testnav.libs:security-core" - implementation "no.nav.testnav.libs:vault" implementation "org.springframework.boot:spring-boot-starter-webflux" - implementation "org.springframework.cloud:spring-cloud-starter-vault-config" } \ No newline at end of file diff --git a/proxies/synthdata-meldekort-proxy/config.yml b/proxies/synthdata-meldekort-proxy/config.yml index 5d6498ba0b8..c20fb8d97da 100644 --- a/proxies/synthdata-meldekort-proxy/config.yml +++ b/proxies/synthdata-meldekort-proxy/config.yml @@ -72,8 +72,6 @@ spec: replicas: min: 1 max: 2 - vault: - enabled: true resources: requests: cpu: 200m diff --git a/proxies/synthdata-meldekort-proxy/settings.gradle b/proxies/synthdata-meldekort-proxy/settings.gradle index 52df408b35e..51a14287d37 100644 --- a/proxies/synthdata-meldekort-proxy/settings.gradle +++ b/proxies/synthdata-meldekort-proxy/settings.gradle @@ -11,7 +11,6 @@ includeBuild '../../libs/reactive-core' includeBuild '../../libs/reactive-proxy' includeBuild '../../libs/reactive-security' includeBuild '../../libs/security-core' -includeBuild '../../libs/vault' develocity { buildScan { diff --git a/proxies/synthdata-meldekort-proxy/src/main/java/no/nav/testnav/proxies/synthdatameldekortproxy/SynthdataMeldekortProxyApplicationStarter.java b/proxies/synthdata-meldekort-proxy/src/main/java/no/nav/testnav/proxies/synthdatameldekortproxy/SynthdataMeldekortProxyApplicationStarter.java index 62e69799ba8..88a92c6bedc 100644 --- a/proxies/synthdata-meldekort-proxy/src/main/java/no/nav/testnav/proxies/synthdatameldekortproxy/SynthdataMeldekortProxyApplicationStarter.java +++ b/proxies/synthdata-meldekort-proxy/src/main/java/no/nav/testnav/proxies/synthdatameldekortproxy/SynthdataMeldekortProxyApplicationStarter.java @@ -7,7 +7,6 @@ import no.nav.testnav.libs.reactivesecurity.exchange.azuread.NavAzureAdTokenService; import no.nav.testnav.libs.securitycore.domain.AccessToken; import no.nav.testnav.proxies.synthdatameldekortproxy.config.Consumers; -import no.nav.testnav.proxies.synthdatameldekortproxy.config.LocalVaultConfig; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; import org.springframework.cloud.gateway.route.RouteLocator; @@ -17,7 +16,6 @@ @Import({ CoreConfig.class, - LocalVaultConfig.class, SecurityConfig.class, SecureOAuth2ServerToServerConfiguration.class }) diff --git a/proxies/synthdata-meldekort-proxy/src/main/java/no/nav/testnav/proxies/synthdatameldekortproxy/config/LocalVaultConfig.java b/proxies/synthdata-meldekort-proxy/src/main/java/no/nav/testnav/proxies/synthdatameldekortproxy/config/LocalVaultConfig.java deleted file mode 100644 index 9d20b9bf7ab..00000000000 --- a/proxies/synthdata-meldekort-proxy/src/main/java/no/nav/testnav/proxies/synthdatameldekortproxy/config/LocalVaultConfig.java +++ /dev/null @@ -1,12 +0,0 @@ -package no.nav.testnav.proxies.synthdatameldekortproxy.config; - -import no.nav.testnav.libs.vault.AbstractLocalVaultConfiguration; -import org.springframework.context.annotation.Configuration; -import org.springframework.context.annotation.Profile; -import org.springframework.vault.annotation.VaultPropertySource; - -@Configuration -@Profile("dev") -@VaultPropertySource(value = "azuread/prod/creds/team-dolly-lokal-app", ignoreSecretNotFound = false) -public class LocalVaultConfig extends AbstractLocalVaultConfiguration { -} \ No newline at end of file diff --git a/proxies/synthdata-meldekort-proxy/src/main/resources/application-dev.yml b/proxies/synthdata-meldekort-proxy/src/main/resources/application-dev.yml index 813a39364c9..0931b73834a 100644 --- a/proxies/synthdata-meldekort-proxy/src/main/resources/application-dev.yml +++ b/proxies/synthdata-meldekort-proxy/src/main/resources/application-dev.yml @@ -1,9 +1,20 @@ +spring: + cloud: + gcp: + secretmanager: + enabled: true + config: + import: "sm://" + azure: nav: app: client: - id: ${client_id} - secret: ${client_secret} + id: ${sm://azure-app-client-id} + secret: ${sm://azure-app-client-secret} + openid: + config: + issuer: https://login.microsoftonline.com/62366534-1ec3-4962-8869-9b5535279d0b consumers: synt-meldekort: diff --git a/proxies/synthdata-meldekort-proxy/src/main/resources/application.yml b/proxies/synthdata-meldekort-proxy/src/main/resources/application.yml index 9e4e5fcdf42..72804a26497 100644 --- a/proxies/synthdata-meldekort-proxy/src/main/resources/application.yml +++ b/proxies/synthdata-meldekort-proxy/src/main/resources/application.yml @@ -8,12 +8,13 @@ spring: trygdeetaten: issuer-uri: ${azure.openid.config.issuer} jwk-set-uri: ${azure.openid.config.jwks.uri} - accepted-audience: ${azure.app.client.id}, api://${azure.app.client.id} + accepted-audience: ${AZURE_APP_CLIENT_ID}, api:// ${AZURE_APP_CLIENT_ID} codec: max-in-memory-size: 15MB cloud: - vault: - enabled: false + gcp: + secretmanager: + enabled: false server: servlet: diff --git a/proxies/synthdata-meldekort-proxy/src/test/java/no/nav/testnav/proxies/synthdatameldekortproxy/ApplicationContextTest.java b/proxies/synthdata-meldekort-proxy/src/test/java/no/nav/testnav/proxies/synthdatameldekortproxy/ApplicationContextTest.java index 02588100eb7..2c897ad945b 100644 --- a/proxies/synthdata-meldekort-proxy/src/test/java/no/nav/testnav/proxies/synthdatameldekortproxy/ApplicationContextTest.java +++ b/proxies/synthdata-meldekort-proxy/src/test/java/no/nav/testnav/proxies/synthdatameldekortproxy/ApplicationContextTest.java @@ -6,15 +6,19 @@ import org.springframework.security.oauth2.jwt.ReactiveJwtDecoder; import org.springframework.test.context.ActiveProfiles; +import static org.assertj.core.api.AssertionsForClassTypes.assertThat; + @SpringBootTest @ActiveProfiles("test") class ApplicationContextTest { @MockBean - public ReactiveJwtDecoder reactiveJwtDecoder; + @SuppressWarnings("unused") + private ReactiveJwtDecoder reactiveJwtDecoder; @Test - @SuppressWarnings("java:S2699") void load_app_context() { + assertThat(true).isTrue(); } + } \ No newline at end of file diff --git a/proxies/synthdata-meldekort-proxy/src/test/resources/application-test.yml b/proxies/synthdata-meldekort-proxy/src/test/resources/application-test.yml index e82d8cc835d..0664d10716c 100644 --- a/proxies/synthdata-meldekort-proxy/src/test/resources/application-test.yml +++ b/proxies/synthdata-meldekort-proxy/src/test/resources/application-test.yml @@ -1,10 +1,4 @@ azure: - app: - client: - id: dummy - secret: dummy openid: config: - issuer: dummy - jwks: - uri: dummy \ No newline at end of file + issuer: dummy \ No newline at end of file diff --git a/proxies/udistub-proxy/README.md b/proxies/udistub-proxy/README.md new file mode 100644 index 00000000000..674eee89b18 --- /dev/null +++ b/proxies/udistub-proxy/README.md @@ -0,0 +1,3 @@ +## Lokal kjøring +* [Generelt.](../../docs/local_general.md) +* [Secret Manager.](../../docs/local_secretmanager.md) \ No newline at end of file diff --git a/proxies/udistub-proxy/build.gradle b/proxies/udistub-proxy/build.gradle index 0dc2e8ae2c3..e309c212e92 100644 --- a/proxies/udistub-proxy/build.gradle +++ b/proxies/udistub-proxy/build.gradle @@ -13,7 +13,4 @@ dependencies { implementation "no.nav.testnav.libs:security-core" implementation "no.nav.testnav.libs:reactive-security" implementation "no.nav.testnav.libs:data-transfer-objects" - implementation "no.nav.testnav.libs:vault" - - implementation "org.springframework.cloud:spring-cloud-starter-bootstrap" // TODO remove legacy bootstrap config } diff --git a/proxies/udistub-proxy/settings.gradle b/proxies/udistub-proxy/settings.gradle index 94a117cb7a1..b0cb53466d3 100644 --- a/proxies/udistub-proxy/settings.gradle +++ b/proxies/udistub-proxy/settings.gradle @@ -11,7 +11,6 @@ includeBuild "../../libs/reactive-core" includeBuild "../../libs/reactive-proxy" includeBuild "../../libs/reactive-security" includeBuild "../../libs/security-core" -includeBuild "../../libs/vault" develocity { buildScan { diff --git a/proxies/udistub-proxy/src/main/java/no/nav/testnav/proxies/udistubproxy/LocalVaultConfig.java b/proxies/udistub-proxy/src/main/java/no/nav/testnav/proxies/udistubproxy/LocalVaultConfig.java deleted file mode 100644 index b1739871236..00000000000 --- a/proxies/udistub-proxy/src/main/java/no/nav/testnav/proxies/udistubproxy/LocalVaultConfig.java +++ /dev/null @@ -1,12 +0,0 @@ -package no.nav.testnav.proxies.udistubproxy; - -import no.nav.testnav.libs.vault.AbstractLocalVaultConfiguration; -import org.springframework.context.annotation.Configuration; -import org.springframework.context.annotation.Profile; -import org.springframework.vault.annotation.VaultPropertySource; - -@Configuration -@Profile("dev") -@VaultPropertySource(value = "azuread/prod/creds/team-dolly-lokal-app", ignoreSecretNotFound = false) -public class LocalVaultConfig extends AbstractLocalVaultConfiguration { -} diff --git a/proxies/udistub-proxy/src/main/resources/application-dev.yml b/proxies/udistub-proxy/src/main/resources/application-dev.yml new file mode 100644 index 00000000000..0f24d85a8e2 --- /dev/null +++ b/proxies/udistub-proxy/src/main/resources/application-dev.yml @@ -0,0 +1,14 @@ +TOKEN_X_ISSUER: dummy + +spring: + cloud: + gcp: + secretmanager: + enabled: true + config: + import: "sm://" + security: + oauth2: + resourceserver: + aad: + accepted-audience: ${sm://azure-app-client-id}, api://${sm://azure-app-client-id} \ No newline at end of file diff --git a/proxies/udistub-proxy/src/main/resources/application.yml b/proxies/udistub-proxy/src/main/resources/application.yml index c3d6f395292..04caa6c4b90 100644 --- a/proxies/udistub-proxy/src/main/resources/application.yml +++ b/proxies/udistub-proxy/src/main/resources/application.yml @@ -10,7 +10,7 @@ spring: aad: issuer-uri: ${AAD_ISSUER_URI}/v2.0 jwk-set-uri: ${AAD_ISSUER_URI}/discovery/v2.0/keys - accepted-audience: ${azure.app.client.id}, api://${azure.app.client.id} + accepted-audience: ${AZURE_APP_CLIENT_ID}, api:// ${AZURE_APP_CLIENT_ID} tokenx: issuer-uri: ${TOKEN_X_ISSUER} jwk-set-uri: ${TOKEN_X_JWKS_URI} @@ -19,6 +19,9 @@ spring: gateway: httpclient: response-timeout: 1200s + gcp: + secretmanager: + enabled: false server: servlet: diff --git a/proxies/udistub-proxy/src/main/resources/bootstrap.yml b/proxies/udistub-proxy/src/main/resources/bootstrap.yml deleted file mode 100644 index 0451449ca23..00000000000 --- a/proxies/udistub-proxy/src/main/resources/bootstrap.yml +++ /dev/null @@ -1,4 +0,0 @@ -spring: - cloud: - vault: - enabled: false \ No newline at end of file diff --git a/proxies/udistub-proxy/src/test/java/no/nav/testnav/proxies/udistubproxy/ApplicationContextTest.java b/proxies/udistub-proxy/src/test/java/no/nav/testnav/proxies/udistubproxy/ApplicationContextTest.java index 312111e0f7a..48f8ffb9897 100644 --- a/proxies/udistub-proxy/src/test/java/no/nav/testnav/proxies/udistubproxy/ApplicationContextTest.java +++ b/proxies/udistub-proxy/src/test/java/no/nav/testnav/proxies/udistubproxy/ApplicationContextTest.java @@ -6,15 +6,19 @@ import org.springframework.security.oauth2.jwt.ReactiveJwtDecoder; import org.springframework.test.context.ActiveProfiles; +import static org.assertj.core.api.AssertionsForClassTypes.assertThat; + @SpringBootTest @ActiveProfiles("test") class ApplicationContextTest { @MockBean - public ReactiveJwtDecoder reactiveJwtDecoder; + @SuppressWarnings("unused") + private ReactiveJwtDecoder reactiveJwtDecoder; @Test - @SuppressWarnings("java:S2699") void load_app_context() { + assertThat(true).isTrue(); } + } diff --git a/proxies/udistub-proxy/src/test/resources/application-test.properties b/proxies/udistub-proxy/src/test/resources/application-test.properties deleted file mode 100644 index 483fe127f1f..00000000000 --- a/proxies/udistub-proxy/src/test/resources/application-test.properties +++ /dev/null @@ -1 +0,0 @@ -TOKEN_X_ISSUER= dummy \ No newline at end of file diff --git a/proxies/udistub-proxy/src/test/resources/application-test.yml b/proxies/udistub-proxy/src/test/resources/application-test.yml new file mode 100644 index 00000000000..f05debbd219 --- /dev/null +++ b/proxies/udistub-proxy/src/test/resources/application-test.yml @@ -0,0 +1 @@ +TOKEN_X_ISSUER: dummy \ No newline at end of file diff --git a/proxies/yrkesskade-proxy/README.md b/proxies/yrkesskade-proxy/README.md new file mode 100644 index 00000000000..674eee89b18 --- /dev/null +++ b/proxies/yrkesskade-proxy/README.md @@ -0,0 +1,3 @@ +## Lokal kjøring +* [Generelt.](../../docs/local_general.md) +* [Secret Manager.](../../docs/local_secretmanager.md) \ No newline at end of file diff --git a/proxies/yrkesskade-proxy/build.gradle b/proxies/yrkesskade-proxy/build.gradle index de7cfad39dd..8ed97fe8337 100644 --- a/proxies/yrkesskade-proxy/build.gradle +++ b/proxies/yrkesskade-proxy/build.gradle @@ -12,5 +12,4 @@ sonarqube { dependencies { implementation "no.nav.testnav.libs:reactive-security" implementation "no.nav.testnav.libs:security-core" - implementation "no.nav.testnav.libs:vault" } diff --git a/proxies/yrkesskade-proxy/config.yml b/proxies/yrkesskade-proxy/config.yml index 1fd5540ddfa..a62e067635c 100644 --- a/proxies/yrkesskade-proxy/config.yml +++ b/proxies/yrkesskade-proxy/config.yml @@ -49,8 +49,6 @@ spec: replicas: min: 1 max: 1 - vault: - enabled: true resources: requests: cpu: 200m diff --git a/proxies/yrkesskade-proxy/settings.gradle b/proxies/yrkesskade-proxy/settings.gradle index aba37aba8c1..8a5bb23f0ff 100644 --- a/proxies/yrkesskade-proxy/settings.gradle +++ b/proxies/yrkesskade-proxy/settings.gradle @@ -10,7 +10,6 @@ includeBuild "../../libs/reactive-core" includeBuild "../../libs/reactive-proxy" includeBuild "../../libs/reactive-security" includeBuild "../../libs/security-core" -includeBuild "../../libs/vault" develocity { buildScan { diff --git a/proxies/yrkesskade-proxy/src/main/java/no/nav/testnav/proxies/yrkesskadeproxy/config/LocalVaultConfig.java b/proxies/yrkesskade-proxy/src/main/java/no/nav/testnav/proxies/yrkesskadeproxy/config/LocalVaultConfig.java deleted file mode 100644 index defca83410b..00000000000 --- a/proxies/yrkesskade-proxy/src/main/java/no/nav/testnav/proxies/yrkesskadeproxy/config/LocalVaultConfig.java +++ /dev/null @@ -1,10 +0,0 @@ -package no.nav.testnav.proxies.yrkesskadeproxy.config; - -import no.nav.testnav.libs.vault.AbstractLocalVaultConfiguration; -import org.springframework.context.annotation.Configuration; -import org.springframework.context.annotation.Profile; - -@Profile("dev") -@Configuration -public class LocalVaultConfig extends AbstractLocalVaultConfiguration { -} \ No newline at end of file diff --git a/proxies/yrkesskade-proxy/src/main/resources/application-dev.yaml b/proxies/yrkesskade-proxy/src/main/resources/application-dev.yaml index 4c4c40f29b0..4fcf0345fde 100644 --- a/proxies/yrkesskade-proxy/src/main/resources/application-dev.yaml +++ b/proxies/yrkesskade-proxy/src/main/resources/application-dev.yaml @@ -1,3 +1,17 @@ +spring: + cloud: + gcp: + secretmanager: + enabled: true + config: + import: "sm://" + security: + oauth2: + resourceserver: + aad: + accepted-audience: ${sm://azure-app-client-id}, api://${sm://azure-app-client-id} + tokenx: + issuer-uri: dummy consumers: yrkesskade: diff --git a/proxies/yrkesskade-proxy/src/main/resources/application.yml b/proxies/yrkesskade-proxy/src/main/resources/application.yml index 6969d7203e1..d184bab8be3 100644 --- a/proxies/yrkesskade-proxy/src/main/resources/application.yml +++ b/proxies/yrkesskade-proxy/src/main/resources/application.yml @@ -10,14 +10,15 @@ spring: aad: issuer-uri: ${AAD_ISSUER_URI}/v2.0 jwk-set-uri: ${AAD_ISSUER_URI}/discovery/v2.0/keys - accepted-audience: ${azure.app.client.id}, api://${azure.app.client.id} + accepted-audience: ${AZURE_APP_CLIENT_ID}, api:// ${AZURE_APP_CLIENT_ID} cloud: gateway: httpclient: response-timeout: 30s wiretap: true - vault: - enabled: false + gcp: + secretmanager: + enabled: false server: servlet: From 885db08ad0c041a3c04c3898111a0cd6f11f7a1c Mon Sep 17 00:00:00 2001 From: Stian Gustavsson Date: Wed, 4 Dec 2024 11:10:17 +0100 Subject: [PATCH 09/14] Bugfix/pdl sivilstand fix (#3684) * Fix for sivilstand ImmutableCollections exception i PDL forvalter og fix for tomDato som var tidligere enn fomDato i PensonSamboerMapping * Lagt til ny test for dette --- .../PensjonforvalterConsumer.java | 35 ++++++------ .../mapper/PensjonSamboerMappingStrategy.java | 11 ++-- .../PensjonSamboerMappingStrategyTest.java | 54 +++++++++++++++++++ .../PdlForvalterApplicationStarter.java | 2 +- .../forvalter/service/SivilstandService.java | 7 +++ 5 files changed, 85 insertions(+), 24 deletions(-) diff --git a/apps/dolly-backend/src/main/java/no/nav/dolly/bestilling/pensjonforvalter/PensjonforvalterConsumer.java b/apps/dolly-backend/src/main/java/no/nav/dolly/bestilling/pensjonforvalter/PensjonforvalterConsumer.java index af14b85f811..9dadced34e2 100644 --- a/apps/dolly-backend/src/main/java/no/nav/dolly/bestilling/pensjonforvalter/PensjonforvalterConsumer.java +++ b/apps/dolly-backend/src/main/java/no/nav/dolly/bestilling/pensjonforvalter/PensjonforvalterConsumer.java @@ -69,14 +69,14 @@ public PensjonforvalterConsumer( .build(); } - @Timed(name = "providers", tags = {"operation", "pen_getMiljoer"}) + @Timed(name = "providers", tags = { "operation", "pen_getMiljoer" }) public Mono> getMiljoer() { return tokenService.exchange(serverProperties) .flatMap(token -> new HentMiljoerCommand(webClient, token.getTokenValue()).call()); } - @Timed(name = "providers", tags = {"operation", "popp_lagreInntekt"}) + @Timed(name = "providers", tags = { "operation", "popp_lagreInntekt" }) public Flux lagreInntekter(PensjonPoppInntektRequest pensjonPoppInntektRequest) { return tokenService.exchange(serverProperties) @@ -84,7 +84,7 @@ public Flux lagreInntekter(PensjonPoppInntektRequest p pensjonPoppInntektRequest).call()); } - @Timed(name = "providers", tags = {"operation", "popp_lagreGenerertInntekt"}) + @Timed(name = "providers", tags = { "operation", "popp_lagreGenerertInntekt" }) public Flux lagreGenererteInntekter(PensjonPoppGenerertInntektRequest pensjonPoppGenerertInntektRequest) { return tokenService.exchange(serverProperties) @@ -92,7 +92,7 @@ public Flux lagreGenererteInntekter(PensjonPoppGenerer pensjonPoppGenerertInntektRequest).call()); } - @Timed(name = "providers", tags = {"operation", "pen_opprettPerson"}) + @Timed(name = "providers", tags = { "operation", "pen_opprettPerson" }) public Flux opprettPerson(PensjonPersonRequest pensjonPersonRequest, Set miljoer) { @@ -102,7 +102,7 @@ public Flux opprettPerson(PensjonPersonRequest pensjon .doOnNext(response -> log.info("Opprettet person for {}: {}", pensjonPersonRequest.getFnr(), response)); } - @Timed(name = "providers", tags = {"operation", "pen_hentSamboer"}) + @Timed(name = "providers", tags = { "operation", "pen_hentSamboer" }) public Flux hentSamboer(String ident, String miljoe) { return tokenService.exchange(serverProperties) @@ -110,22 +110,23 @@ public Flux hentSamboer(String ident, String miljoe) { .doOnNext(response -> log.info("Pensjon samboer for {} i {} hentet {}", ident, miljoe, response)); } - @Timed(name = "providers", tags = {"operation", "pen_opprettSamboer"}) + @Timed(name = "providers", tags = { "operation", "pen_opprettSamboer" }) public Flux lagreSamboer(PensjonSamboerRequest pensjonSamboerRequest, String miljoe) { + log.info("Oppretter samboerskap i pensjon: {}", pensjonSamboerRequest); return tokenService.exchange(serverProperties) .flatMapMany(token -> new LagreSamboerCommand(webClient, pensjonSamboerRequest, miljoe, token.getTokenValue()).call()); } - @Timed(name = "providers", tags = {"operation", "pen_opprettSamboer"}) + @Timed(name = "providers", tags = { "operation", "pen_opprettSamboer" }) public Flux annullerSamboer(String periodeId, String miljoe) { return tokenService.exchange(serverProperties) .flatMapMany(token -> new AnnullerSamboerCommand(webClient, periodeId, miljoe, token.getTokenValue()).call()); } - @Timed(name = "providers", tags = {"operation", "pen_lagreAlderspensjon"}) + @Timed(name = "providers", tags = { "operation", "pen_lagreAlderspensjon" }) public Flux lagreAlderspensjon(AlderspensjonRequest request) { return tokenService.exchange(serverProperties) @@ -133,21 +134,21 @@ public Flux lagreAlderspensjon(AlderspensjonRequest re new LagreAlderspensjonCommand(webClient, token.getTokenValue(), request).call()); } - @Timed(name = "providers", tags = {"operation", "pen_lagreUforetrygd"}) + @Timed(name = "providers", tags = { "operation", "pen_lagreUforetrygd" }) public Flux lagreUforetrygd(PensjonUforetrygdRequest request) { return tokenService.exchange(serverProperties) .flatMapMany(token -> new LagreUforetrygdCommand(webClient, token.getTokenValue(), request).call()); } - @Timed(name = "providers", tags = {"operation", "pen_lagreTpForhold"}) + @Timed(name = "providers", tags = { "operation", "pen_lagreTpForhold" }) public Flux lagreTpForhold(PensjonTpForholdRequest pensjonTpForholdRequest) { return tokenService.exchange(serverProperties) .flatMapMany(token -> new LagreTpForholdCommand(webClient, token.getTokenValue(), pensjonTpForholdRequest).call()); } - @Timed(name = "providers", tags = {"operation", "pen_sletteTpForhold"}) + @Timed(name = "providers", tags = { "operation", "pen_sletteTpForhold" }) public void sletteTpForhold(List identer) { tokenService.exchange(serverProperties) @@ -159,21 +160,21 @@ public void sletteTpForhold(List identer) { .subscribe(response -> log.info("Slettet mot PESYS (tp) i alle miljoer")); } - @Timed(name = "providers", tags = {"operation", "pen_lagreTpYtelse"}) + @Timed(name = "providers", tags = { "operation", "pen_lagreTpYtelse" }) public Flux lagreTpYtelse(PensjonTpYtelseRequest pensjonTpYtelseRequest) { return tokenService.exchange(serverProperties) .flatMapMany(token -> new LagreTpYtelseCommand(webClient, token.getTokenValue(), pensjonTpYtelseRequest).call()); } - @Timed(name = "providers", tags = {"operation", "pen_lagrePensjpnsavtale"}) + @Timed(name = "providers", tags = { "operation", "pen_lagrePensjpnsavtale" }) public Flux lagrePensjonsavtale(PensjonsavtaleRequest pensjonsavtaleRequest) { return tokenService.exchange(serverProperties) .flatMapMany(token -> new LagrePensjonsavtaleCommand(webClient, pensjonsavtaleRequest, token.getTokenValue()).call()); } - @Timed(name = "providers", tags = {"operation", "pen_slettePensjpnsavtale"}) + @Timed(name = "providers", tags = { "operation", "pen_slettePensjpnsavtale" }) public void slettePensjonsavtale(List identer) { tokenService.exchange(serverProperties) @@ -183,7 +184,7 @@ public void slettePensjonsavtale(List identer) { .subscribe(resultat -> log.info("Slettet pensjonsavtaler (PEN), alle miljøer")); } - @Timed(name = "providers", tags = {"operation", "pen_hentVedtak"}) + @Timed(name = "providers", tags = { "operation", "pen_hentVedtak" }) public Flux hentVedtak(String ident, String miljoe) { return tokenService.exchange(serverProperties) @@ -192,14 +193,14 @@ public Flux hentVedtak(String ident, String miljoe) { ident, miljoe, response)); } - @Timed(name = "providers", tags = {"operation", "pen_lagreAfpOffentlig"}) + @Timed(name = "providers", tags = { "operation", "pen_lagreAfpOffentlig" }) public Flux lagreAfpOffentlig(AfpOffentligRequest afpOffentligRequest, String ident, String miljoe) { return tokenService.exchange(serverProperties) .flatMapMany(token -> new LagreAfpOffentligCommand(webClient, afpOffentligRequest, ident, miljoe, token.getTokenValue()).call()); } - @Timed(name = "providers", tags = {"operation", "pen_sletteAfpOffentlig"}) + @Timed(name = "providers", tags = { "operation", "pen_sletteAfpOffentlig" }) public void sletteAfpOffentlig(List identer) { tokenService.exchange(serverProperties) diff --git a/apps/dolly-backend/src/main/java/no/nav/dolly/bestilling/pensjonforvalter/mapper/PensjonSamboerMappingStrategy.java b/apps/dolly-backend/src/main/java/no/nav/dolly/bestilling/pensjonforvalter/mapper/PensjonSamboerMappingStrategy.java index 4ee87c5f634..2347e2ff256 100644 --- a/apps/dolly-backend/src/main/java/no/nav/dolly/bestilling/pensjonforvalter/mapper/PensjonSamboerMappingStrategy.java +++ b/apps/dolly-backend/src/main/java/no/nav/dolly/bestilling/pensjonforvalter/mapper/PensjonSamboerMappingStrategy.java @@ -13,7 +13,6 @@ import java.time.LocalDateTime; import java.util.Comparator; import java.util.List; -import java.util.Objects; import static java.util.Objects.nonNull; import static no.nav.dolly.domain.CommonKeysAndUtils.CONSUMER; @@ -35,12 +34,13 @@ public void mapAtoB(PensjonSivilstandWrapper sivilstander, List list, MappingCon .findFirst() .ifPresent(sivilstandSamboer -> { + var datoTom = nonNull(sivilstandSamboer.getSivilstandsdato()) ? + toLocalDate(sivilstandSamboer.getSivilstandsdato()) : + LocalDate.now(); var hovedperson = PensjonSamboerRequest.builder() .pidBruker(ident) .pidSamboer(sivilstandSamboer.getRelatertVedSivilstand()) - .datoFom(nonNull(sivilstandSamboer.getSivilstandsdato()) ? - toLocalDate(sivilstandSamboer.getSivilstandsdato()) : - LocalDate.now()) + .datoFom(datoTom) .datoTom(sivilstander.getSivilstander().stream() .sorted(Comparator.comparing(SivilstandDTO::getId).reversed()) .filter(sivilstand -> sivilstand.isGift() && @@ -49,7 +49,7 @@ public void mapAtoB(PensjonSivilstandWrapper sivilstander, List list, MappingCon sivilstand2.getId() < sivilstand.getId())) .map(sivilstand -> toLocalDate(nonNull(sivilstand.getSivilstandsdato()) ? sivilstand.getSivilstandsdato() : sivilstand.getBekreftelsesdato())) - .filter(Objects::nonNull) + .filter(localDate -> nonNull(localDate) && localDate.isAfter(datoTom)) .map(dato -> dato.minusDays(1)) .findFirst() .orElse(null)) @@ -68,7 +68,6 @@ public void mapAtoB(PensjonSivilstandWrapper sivilstander, List list, MappingCon } private static LocalDate toLocalDate(LocalDateTime localDateTime) { - return nonNull(localDateTime) ? localDateTime.toLocalDate() : null; } } diff --git a/apps/dolly-backend/src/test/java/no/nav/dolly/bestilling/pensjonforvalter/mapper/PensjonSamboerMappingStrategyTest.java b/apps/dolly-backend/src/test/java/no/nav/dolly/bestilling/pensjonforvalter/mapper/PensjonSamboerMappingStrategyTest.java index ea8246abfcb..87c07825032 100644 --- a/apps/dolly-backend/src/test/java/no/nav/dolly/bestilling/pensjonforvalter/mapper/PensjonSamboerMappingStrategyTest.java +++ b/apps/dolly-backend/src/test/java/no/nav/dolly/bestilling/pensjonforvalter/mapper/PensjonSamboerMappingStrategyTest.java @@ -21,6 +21,7 @@ import static org.hamcrest.MatcherAssert.assertThat; import static org.hamcrest.Matchers.containsInAnyOrder; import static org.hamcrest.Matchers.hasProperty; +import static org.hamcrest.Matchers.nullValue; @ExtendWith(MockitoExtension.class) @SuppressWarnings("unchecked") @@ -28,7 +29,13 @@ class PensjonSamboerMappingStrategyTest { private static final String IDENT_1 = "11111111111"; private static final String IDENT_2 = "22222222222"; + private static final String IDENT_3 = "33333333333"; + private static final String IDENT_4 = "44444444444"; private static final LocalDateTime SIVILSTAND_DATO = LocalDateTime.now(); + private static final LocalDateTime SIVILSTAND_DATO_EARLIEST = LocalDateTime.of(2000, 10, 10, 0, 0); + private static final LocalDateTime SIVILSTAND_DATO_MIDDLE = LocalDateTime.of(2010, 10, 10, 0, 0); + private static final LocalDateTime SIVILSTAND_DATO_LATEST = LocalDateTime.of(2020, 10, 10, 0, 0); + private MapperFacade mapperFacade; @@ -42,6 +49,30 @@ private static SivilstandDTO buildSivilstand() { .build(); } + private static List buildMultipleSivilstand() { + + var sivilstandOne = SivilstandDTO.builder() + .id(1) + .type(SivilstandDTO.Sivilstand.SAMBOER) + .relatertVedSivilstand(IDENT_2) + .sivilstandsdato(SIVILSTAND_DATO_EARLIEST) + .build(); + var sivilstandTwo = SivilstandDTO.builder() + .id(2) + .type(SivilstandDTO.Sivilstand.GIFT) + .relatertVedSivilstand(IDENT_3) + .sivilstandsdato(SIVILSTAND_DATO_MIDDLE) + .build(); + var sivilstandThree = SivilstandDTO.builder() + .id(3) + .type(SivilstandDTO.Sivilstand.SAMBOER) + .relatertVedSivilstand(IDENT_4) + .sivilstandsdato(SIVILSTAND_DATO_LATEST) + .build(); + + return List.of(sivilstandOne, sivilstandTwo, sivilstandThree); + } + @BeforeEach void setup() { mapperFacade = MapperTestUtils.createMapperFacadeForMappingStrategy(new LocalDateCustomMapping(), @@ -142,4 +173,27 @@ void mapSamboerOgSenereGift_OK() { hasProperty("datoTom", is(equalTo(SIVILSTAND_DATO.toLocalDate().plusYears(1).minusDays(1)))), hasProperty("registrertAv", is(equalTo("Dolly")))))); } + + + @Test + void mapMultipleSivilstand_OK() { + + var context = new MappingContext.Factory().getContext(); + context.setProperty("ident", IDENT_1); + var resultat = (List) mapperFacade.map(PensjonSivilstandWrapper.builder() + .sivilstander(buildMultipleSivilstand()) + .build(), List.class, context); + + assertThat(resultat, containsInAnyOrder( + allOf(hasProperty("pidBruker", is(equalTo(IDENT_1))), + hasProperty("pidSamboer", is(equalTo(IDENT_4))), + hasProperty("datoFom", is(equalTo(SIVILSTAND_DATO_LATEST.toLocalDate()))), + hasProperty("datoTom", nullValue()), + hasProperty("registrertAv", is(equalTo("Dolly")))), + allOf(hasProperty("pidBruker", is(equalTo(IDENT_4))), + hasProperty("pidSamboer", is(equalTo(IDENT_1))), + hasProperty("datoFom", is(equalTo(SIVILSTAND_DATO_LATEST.toLocalDate()))), + hasProperty("datoTom", nullValue()), + hasProperty("registrertAv", is(equalTo("Dolly")))))); + } } \ No newline at end of file diff --git a/apps/pdl-forvalter/src/main/java/no/nav/pdl/forvalter/PdlForvalterApplicationStarter.java b/apps/pdl-forvalter/src/main/java/no/nav/pdl/forvalter/PdlForvalterApplicationStarter.java index 45f34416ff3..d4f60c563e8 100644 --- a/apps/pdl-forvalter/src/main/java/no/nav/pdl/forvalter/PdlForvalterApplicationStarter.java +++ b/apps/pdl-forvalter/src/main/java/no/nav/pdl/forvalter/PdlForvalterApplicationStarter.java @@ -10,4 +10,4 @@ public static void main(String[] args) { SpringApplication.run(PdlForvalterApplicationStarter.class, args); } -} +} \ No newline at end of file diff --git a/apps/pdl-forvalter/src/main/java/no/nav/pdl/forvalter/service/SivilstandService.java b/apps/pdl-forvalter/src/main/java/no/nav/pdl/forvalter/service/SivilstandService.java index c998c7794aa..51eee8015eb 100644 --- a/apps/pdl-forvalter/src/main/java/no/nav/pdl/forvalter/service/SivilstandService.java +++ b/apps/pdl-forvalter/src/main/java/no/nav/pdl/forvalter/service/SivilstandService.java @@ -19,6 +19,7 @@ import java.time.LocalDateTime; import java.util.Comparator; +import java.util.LinkedList; import java.util.List; import java.util.Objects; import java.util.concurrent.atomic.AtomicReference; @@ -168,6 +169,12 @@ private void createRelatertSivilstand(SivilstandDTO sivilstand, String hovedpers .max(Comparator.comparing(SivilstandDTO::getId)) .map(SivilstandDTO::getId) .orElse(0) + 1); + + // Ensure the list is modifiable + if (!(relatertPerson.get().getPerson().getSivilstand() instanceof LinkedList)) { + relatertPerson.get().getPerson().setSivilstand(new LinkedList<>(relatertPerson.get().getPerson().getSivilstand())); + } + relatertPerson.get().getPerson().getSivilstand().addFirst(relatertSivilstand); relatertPerson.get().getPerson().setSivilstand(enforceIntegrity(relatertPerson.get().getPerson())); From fe549e01e891b535ff47daae6c52b769073985f0 Mon Sep 17 00:00:00 2001 From: Cato Olsen Date: Wed, 4 Dec 2024 11:50:21 +0100 Subject: [PATCH 10/14] Fjerner org.springframework.cloud:spring-cloud-starter-vault-config som dependency gjennom reactive-frontend. --- apps/dolly-frontend/src/main/resources/application.yml | 3 --- .../src/main/resources/application.yml | 3 --- .../oversikt-frontend/src/main/resources/application-dev.yml | 2 ++ apps/oversikt-frontend/src/main/resources/application.yml | 3 --- libs/reactive-frontend/build.gradle | 5 ++--- 5 files changed, 4 insertions(+), 12 deletions(-) diff --git a/apps/dolly-frontend/src/main/resources/application.yml b/apps/dolly-frontend/src/main/resources/application.yml index 5e50e1267ab..476b3bd834e 100644 --- a/apps/dolly-frontend/src/main/resources/application.yml +++ b/apps/dolly-frontend/src/main/resources/application.yml @@ -8,9 +8,6 @@ spring: main: banner-mode: off allow-circular-references: true - cloud: - vault: - enabled: false data: redis: host: ${REDIS_HOST} diff --git a/apps/endringsmelding-frontend/src/main/resources/application.yml b/apps/endringsmelding-frontend/src/main/resources/application.yml index 74f8ec0f202..38f3e2e9a89 100644 --- a/apps/endringsmelding-frontend/src/main/resources/application.yml +++ b/apps/endringsmelding-frontend/src/main/resources/application.yml @@ -4,9 +4,6 @@ spring: application: name: endringsmelding-frontend description: App for å sende inn endringsmeldinger til tps - cloud: - vault: - enabled: false main: banner-mode: off security: diff --git a/apps/oversikt-frontend/src/main/resources/application-dev.yml b/apps/oversikt-frontend/src/main/resources/application-dev.yml index 3c102fb42f4..86865e8d705 100644 --- a/apps/oversikt-frontend/src/main/resources/application-dev.yml +++ b/apps/oversikt-frontend/src/main/resources/application-dev.yml @@ -1,3 +1,5 @@ +TOKEN_X_ISSUER: dummy + server: port: 8080 diff --git a/apps/oversikt-frontend/src/main/resources/application.yml b/apps/oversikt-frontend/src/main/resources/application.yml index fe0df0c08ce..cab26a3240a 100644 --- a/apps/oversikt-frontend/src/main/resources/application.yml +++ b/apps/oversikt-frontend/src/main/resources/application.yml @@ -1,9 +1,6 @@ AAD_ISSUER_URI: https://login.microsoftonline.com/62366534-1ec3-4962-8869-9b5535279d0b spring: - cloud: - vault: - enabled: false security: oauth2: resourceserver: diff --git a/libs/reactive-frontend/build.gradle b/libs/reactive-frontend/build.gradle index b337a0fb293..57fad612684 100644 --- a/libs/reactive-frontend/build.gradle +++ b/libs/reactive-frontend/build.gradle @@ -45,11 +45,10 @@ publishing { dependencies { implementation 'no.nav.testnav.libs:security-core' + implementation 'org.hibernate.validator:hibernate-validator' + implementation 'org.springframework.boot:spring-boot-starter-oauth2-resource-server' implementation 'org.springframework.boot:spring-boot-starter-webflux' - implementation 'org.springframework.cloud:spring-cloud-starter-vault-config' implementation 'org.springframework.cloud:spring-cloud-starter-gateway' - - implementation 'org.hibernate.validator:hibernate-validator' } \ No newline at end of file From ecc0ce3d2308b6a3321125be4dee0fc97d44f787 Mon Sep 17 00:00:00 2001 From: Cato Olsen Date: Wed, 4 Dec 2024 12:01:40 +0100 Subject: [PATCH 11/14] =?UTF-8?q?Lagt=20til=20dependency=20p=C3=A5=20io.gr?= =?UTF-8?q?pc:grpc-netty,=20ref.=20https://github.com/GoogleCloudPlatform/?= =?UTF-8?q?spring-cloud-gcp/issues/1314.?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- apps/oversikt-frontend/build.gradle | 2 ++ 1 file changed, 2 insertions(+) diff --git a/apps/oversikt-frontend/build.gradle b/apps/oversikt-frontend/build.gradle index 45a292fb976..b2e13e3acfa 100644 --- a/apps/oversikt-frontend/build.gradle +++ b/apps/oversikt-frontend/build.gradle @@ -11,6 +11,8 @@ sonarqube { } dependencies { + implementation "io.grpc:grpc-netty:$versions.grpc" + implementation "no.nav.testnav.libs:reactive-core" implementation "no.nav.testnav.libs:reactive-frontend" implementation "no.nav.testnav.libs:reactive-security" From 1995e2344ebff73bdc97657a54d8d38b8a8addef Mon Sep 17 00:00:00 2001 From: Cato Olsen Date: Wed, 4 Dec 2024 12:14:09 +0100 Subject: [PATCH 12/14] =?UTF-8?q?Fjerner=20ubrukt=20dependency=20p=C3=A5?= =?UTF-8?q?=20no.nav.testnav.libs:database=20som=20dro=20med=20seg=20Vault?= =?UTF-8?q?=20og=20fikk=20health=20check=20til=20=C3=A5=20feile.?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- apps/pdl-forvalter/build.gradle | 1 - apps/pdl-forvalter/settings.gradle | 1 - 2 files changed, 2 deletions(-) diff --git a/apps/pdl-forvalter/build.gradle b/apps/pdl-forvalter/build.gradle index 160fb17c31a..db127052d46 100644 --- a/apps/pdl-forvalter/build.gradle +++ b/apps/pdl-forvalter/build.gradle @@ -14,7 +14,6 @@ properties { } dependencies { - implementation "no.nav.testnav.libs:database" implementation "no.nav.testnav.libs:data-transfer-objects" implementation "no.nav.testnav.libs:data-transfer-search-objects" implementation "no.nav.testnav.libs:servlet-core" diff --git a/apps/pdl-forvalter/settings.gradle b/apps/pdl-forvalter/settings.gradle index c5eee4e5ef0..b47890f670b 100644 --- a/apps/pdl-forvalter/settings.gradle +++ b/apps/pdl-forvalter/settings.gradle @@ -8,7 +8,6 @@ includeBuild "../../plugins/java" includeBuild '../../libs/data-transfer-objects' includeBuild '../../libs/data-transfer-search-objects' -includeBuild '../../libs/database' includeBuild '../../libs/reactive-core' includeBuild '../../libs/security-core' includeBuild '../../libs/servlet-core' From d99611dd5a4557591158569f5281b90193e4bd41 Mon Sep 17 00:00:00 2001 From: Cato Olsen Date: Wed, 4 Dec 2024 12:30:22 +0100 Subject: [PATCH 13/14] =?UTF-8?q?Setter=20spring.cloud.gcp.secretmanager.e?= =?UTF-8?q?nabled=3Dfalse=20for=20applikasjoner=20som=20kj=C3=B8rer=20i=20?= =?UTF-8?q?dev-fss.?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- apps/brreg-stub/src/main/resources/application-prod.yaml | 3 +++ apps/udi-stub/src/main/resources/application-prod.yml | 3 +++ 2 files changed, 6 insertions(+) diff --git a/apps/brreg-stub/src/main/resources/application-prod.yaml b/apps/brreg-stub/src/main/resources/application-prod.yaml index 1ba9cd7cef9..f0277592973 100644 --- a/apps/brreg-stub/src/main/resources/application-prod.yaml +++ b/apps/brreg-stub/src/main/resources/application-prod.yaml @@ -17,6 +17,9 @@ spring: hibernate: dialect: org.hibernate.dialect.PostgreSQLDialect cloud: + gcp: + secretmanager: + enabled: false # Running in dev-fss. vault: host: vault.adeo.no port: 443 diff --git a/apps/udi-stub/src/main/resources/application-prod.yml b/apps/udi-stub/src/main/resources/application-prod.yml index 8241cfe5bde..5f2ac6157da 100644 --- a/apps/udi-stub/src/main/resources/application-prod.yml +++ b/apps/udi-stub/src/main/resources/application-prod.yml @@ -8,6 +8,9 @@ spring: initialization-fail-timeout: 10000 jdbc-url: jdbc:postgresql://b27dbvl032.preprod.local:5432/testnav-udistub?autoReconnect=true&useSSL=false cloud: + gcp: + secretmanager: + enabled: false # Running in dev-fss. vault: kv: enabled: false From 2464b3fcca4b15a718c6127889aacbf3a5a84761 Mon Sep 17 00:00:00 2001 From: Cato Olsen Date: Thu, 5 Dec 2024 10:39:21 +0100 Subject: [PATCH 14/14] =?UTF-8?q?-=20Spring=20profile=20"dev"=20var=20satt?= =?UTF-8?q?=20opp=20for=20lokal=20kj=C3=B8ring.=20Rettet.=20-=20Lagt=20til?= =?UTF-8?q?=20config=20for=20Spring=20profile=20"local".=20-=20Fjernet=20d?= =?UTF-8?q?uplisert=20config=20i=20Spring=20profile=20"prod".=20-=20Behold?= =?UTF-8?q?er=20tomme=20config-filer=20for=20Spring=20profile=20"dev"=20og?= =?UTF-8?q?=20"prod"=20for=20=C3=A5=20tydeliggj=C3=B8re=20at=20disse=20pro?= =?UTF-8?q?filene=20er=20i=20bruk.?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../src/main/resources/application-dev.yml | 8 -------- .../src/main/resources/application-local.yml | 8 ++++++++ .../src/main/resources/application-prod.yml | 8 -------- 3 files changed, 8 insertions(+), 16 deletions(-) create mode 100644 apps/sykemelding-api/src/main/resources/application-local.yml diff --git a/apps/sykemelding-api/src/main/resources/application-dev.yml b/apps/sykemelding-api/src/main/resources/application-dev.yml index bea43da510a..e69de29bb2d 100644 --- a/apps/sykemelding-api/src/main/resources/application-dev.yml +++ b/apps/sykemelding-api/src/main/resources/application-dev.yml @@ -1,8 +0,0 @@ -spring: - config: - import: "sm://" - security: - oauth2: - resourceserver: - aad: - accepted-audience: ${sm://azure-app-client-id}, api://${sm://azure-app-client-id} \ No newline at end of file diff --git a/apps/sykemelding-api/src/main/resources/application-local.yml b/apps/sykemelding-api/src/main/resources/application-local.yml new file mode 100644 index 00000000000..bea43da510a --- /dev/null +++ b/apps/sykemelding-api/src/main/resources/application-local.yml @@ -0,0 +1,8 @@ +spring: + config: + import: "sm://" + security: + oauth2: + resourceserver: + aad: + accepted-audience: ${sm://azure-app-client-id}, api://${sm://azure-app-client-id} \ No newline at end of file diff --git a/apps/sykemelding-api/src/main/resources/application-prod.yml b/apps/sykemelding-api/src/main/resources/application-prod.yml index 0311ce578e3..e69de29bb2d 100644 --- a/apps/sykemelding-api/src/main/resources/application-prod.yml +++ b/apps/sykemelding-api/src/main/resources/application-prod.yml @@ -1,8 +0,0 @@ -spring: - security: - oauth2: - resourceserver: - tokenx: - issuer-uri: ${TOKEN_X_ISSUER} - jwk-set-uri: ${TOKEN_X_JWKS_URI} - accepted-audience: ${TOKEN_X_CLIENT_ID} \ No newline at end of file