diff --git a/.github/workflows/build-deploy-from-branch.yml b/.github/workflows/build-deploy-from-branch.yml
new file mode 100644
index 00000000..009fcfa3
--- /dev/null
+++ b/.github/workflows/build-deploy-from-branch.yml
@@ -0,0 +1,46 @@
+name: Build and deploy from branch.
+
+on:
+ pull_request:
+
+jobs:
+ build_deploy_branch:
+ runs-on: ubuntu-latest
+
+ environment: dev-cd
+
+ permissions:
+ id-token: write
+ packages: write
+ contents: write
+
+ steps:
+ - name: Checkout the source code
+ uses: actions/checkout@692973e3d937129bcbf40652eb9f2f61becf3332 # v4.1.7
+ with:
+ token: ${{ secrets.GIT_PAT }}
+ fetch-depth: 0
+
+ - name: Log in to the Container registry
+ uses: docker/login-action@9780b0c442fbb1117ed29e0efdff1e18412f7567 # v3.3.0
+ with:
+ registry: https://ghcr.io
+ username: ${{ github.actor }}
+ password: ${{ secrets.GITHUB_TOKEN }}
+
+ - name: Set up QEMU
+ uses: docker/setup-qemu-action@49b3bc8e6bdd4a60e6116a5414239cba5943d3cf # v3.2.0
+
+ - name: Set up Docker Buildx
+ uses: docker/setup-buildx-action@988b5a0280414f521da01fcc63a27aeeb4b104db # v3.6.1
+
+ - name: Build the app image
+ uses: docker/build-push-action@5cd11c3a4ced054e52742c5fd54dca954e0edd85 # v6.7.0
+ with:
+ push: true
+ context: .
+ file: src/main/docker/Dockerfile.multistage
+ platforms: linux/amd64
+ tags: ghcr.io/${{ github.repository }}:${{ github.head_ref || github.ref_name }}
+ secrets: |
+ "gh_token=${{ secrets.GIT_PAT }}"
diff --git a/.github/workflows/build-n-push-main.yml b/.github/workflows/build-n-push-main.yml
deleted file mode 100644
index c60f7cf1..00000000
--- a/.github/workflows/build-n-push-main.yml
+++ /dev/null
@@ -1,157 +0,0 @@
-name: Build, push and update
-
-on:
- workflow_dispatch:
- inputs:
- skip-unit-test:
- type: boolean
- required: true
- description: Skip unit-test
-
-jobs:
- build_push_update:
- runs-on: ubuntu-latest
-
- environment: dev-cd
-
- permissions:
- id-token: write
- packages: write
- contents: write
-
- steps:
- #
- # Checkout the source code.
- #
- - name: Checkout the source code
- uses: actions/checkout@8e5e7e5ab8b370d6c329ec480221332ada57f0ab
- with:
- token: ${{ secrets.GIT_PAT }}
- fetch-depth: 0
-
- #
- # Cache JDK.
- #
- - name: Cache JDK
- uses: actions/cache@88522ab9f39a2ea568f7027eddc7d8d8bc9d59c8
- id: cache-jdk
- with:
- key: OpenJDK21U-jdk_x64_linux_hotspot_21.0.2_13.tar.gz
- path: |
- ${{ runner.temp }}/jdk_setup.tar.gz
- ${{ runner.temp }}/jdk_setup.sha256
-
- #
- # Download JDK and verify its hash.
- #
- - name: Download JDK and verify its hash
- if: steps.cache-jdk.outputs.cache-hit != 'true'
- run: |
- echo "454bebb2c9fe48d981341461ffb6bf1017c7b7c6e15c6b0c29b959194ba3aaa5 ${{ runner.temp }}/jdk_setup.tar.gz" >> ${{ runner.temp }}/jdk_setup.sha256
- curl -L "https://github.com/adoptium/temurin21-binaries/releases/download/jdk-21.0.2%2B13/OpenJDK21U-jdk_x64_linux_hotspot_21.0.2_13.tar.gz" -o "${{ runner.temp }}/jdk_setup.tar.gz"
- sha256sum --check --status "${{ runner.temp }}/jdk_setup.sha256"
-
- #
- # Setup JDK.
- #
- - name: Setup JDK
- uses: actions/setup-java@5ffc13f4174014e2d4d4572b3d74c3fa61aeb2c2
- with:
- distribution: "jdkfile"
- jdkFile: "${{ runner.temp }}/jdk_setup.tar.gz"
- java-version: "21"
- cache: maven
-
- #
- # Cache Maven.
- #
- - name: Cache Maven
- uses: actions/cache@88522ab9f39a2ea568f7027eddc7d8d8bc9d59c8
- id: cache-maven
- with:
- key: apache-maven-3.9.6-bin.tar.gz
- path: |
- ${{ runner.temp }}/maven_setup.tar.gz
- ${{ runner.temp }}/maven_setup.sha256
-
- #
- # Download Maven and verify its hash.
- #
- - name: Download Maven and verify its hash
- if: steps.cache-maven.outputs.cache-hit != 'true'
- run: |
- echo "6eedd2cae3626d6ad3a5c9ee324bd265853d64297f07f033430755bd0e0c3a4b ${{ runner.temp }}/maven_setup.tar.gz" >> ${{ runner.temp }}/maven_setup.sha256
- curl -L "https://archive.apache.org/dist/maven/maven-3/3.9.6/binaries/apache-maven-3.9.6-bin.tar.gz" -o "${{ runner.temp }}/maven_setup.tar.gz"
- sha256sum --check --status "${{ runner.temp }}/maven_setup.sha256"
-
- #
- # Setup Maven.
- #
- - name: Setup Maven
- run: |
- mkdir ${{ runner.temp }}/maven
- tar -xvf ${{ runner.temp }}/maven_setup.tar.gz -C ${{ runner.temp }}/maven --strip-components=1
- echo "github${{ secrets.GIT_USER }}${{ secrets.GIT_PAT }}" >> ${{ runner.temp }}/settings.xml
-
- #
- # Build native executable.
- #
- - name: Build native executable
- run: |
- ${{ runner.temp }}/maven/bin/mvn clean package \
- -Pnative \
- -Dmaven.test.skip=${{ github.event.inputs.skip-unit-test }} \
- -Dquarkus.native.container-build=true \
- -Dquarkus.native.builder-image=quay.io/quarkus/ubi-quarkus-mandrel-builder-image@sha256:ce70e1a8016471ff0fc9c8f048cd9e37afddacd3de37ed0bca74201d102e45f5 \
- -s ${{ runner.temp }}/settings.xml \
- --no-transfer-progress
-
- #
- # Build Docker image.
- #
- - name: Build Docker image
- run: |
- BRANCH_NAME="${GITHUB_REF////_}"
- echo "branch_name=$BRANCH_NAME" >> $GITHUB_ENV
- docker build \
- -f src/main/docker/Dockerfile.native-micro \
- -t ghcr.io/${{ github.repository }}:$BRANCH_NAME \
- .
-
- #
- # Push Docker image.
- #
- - name: Push Docker image
- run: |
- echo "${{ secrets.GITHUB_TOKEN }}" | docker login ghcr.io -u ${{ github.actor }} --password-stdin
- docker push -a ghcr.io/${{ github.repository }}
-
- #
- # Get Docker image with sha256.
- #
- - name: Get Docker image with sha256
- run: echo "image_sha256=$(docker image inspect -f '{{index .RepoDigests 0}}' ghcr.io/${{ github.repository }}:${{ env.branch_name }})" >> "$GITHUB_ENV"
-
- #
- # Login to Azure.
- #
- - name: Login to Azure
- uses: azure/login@8c334a195cbb38e46038007b304988d888bf676a #v2.0.0
- with:
- client-id: ${{ secrets.AZURE_CLIENT_ID }}
- tenant-id: ${{ secrets.AZURE_TENANT_ID }}
- subscription-id: ${{ secrets.AZURE_SUBSCRIPTION_ID }}
-
- #
- # Update Container App.
- #
- - name: Update Container App
- uses: azure/CLI@fa0f960f00db49b95fdb54328a767aee31e80105
- with:
- inlineScript: |
- az config set extension.use_dynamic_install=yes_without_prompt
- az containerapp update \
- -n ${{ secrets.AZURE_CONTAINER_APP_NAME }} \
- -g ${{ secrets.AZURE_RESOURCE_GROUP_NAME }} \
- --subscription ${{ secrets.AZURE_SUBSCRIPTION_ID }} \
- -i ${{ env.image_sha256 }}
diff --git a/.github/workflows/post-merge.yml b/.github/workflows/post-merge.yml
index 5e1a70be..8bced8b0 100644
--- a/.github/workflows/post-merge.yml
+++ b/.github/workflows/post-merge.yml
@@ -31,9 +31,9 @@ jobs:
fetch-depth: 0
#
- # Calculate of the new version (dry-run).
+ # Calculation of the new version (again) with tagging + releasing + etc.
#
- - name: Calculate of the new version (dry-run)
+ - name: Calculation of the new version (w/o dry_run) and put tag
uses: cycjimmy/semantic-release-action@8e58d20d0f6c8773181f43eb74d6a05e3099571d
id: semantic
env:
@@ -44,194 +44,10 @@ jobs:
extra_plugins: |
@semantic-release/release-notes-generator@10.0.3
@semantic-release/git@10.0.1
- dry_run: true
-
- #
- # Cache JDK.
- #
- - name: Cache JDK
- if: steps.semantic.outputs.new_release_published == 'true'
- uses: actions/cache@88522ab9f39a2ea568f7027eddc7d8d8bc9d59c8
- id: cache-jdk
- with:
- key: OpenJDK21U-jdk_x64_linux_hotspot_21.0.2_13.tar.gz
- path: |
- ${{ runner.temp }}/jdk_setup.tar.gz
- ${{ runner.temp }}/jdk_setup.sha256
-
- #
- # Download JDK and verify its hash.
- #
- - name: Download JDK and verify its hash
- if: steps.semantic.outputs.new_release_published == 'true' && steps.cache-jdk.outputs.cache-hit != 'true'
- run: |
- echo "454bebb2c9fe48d981341461ffb6bf1017c7b7c6e15c6b0c29b959194ba3aaa5 ${{ runner.temp }}/jdk_setup.tar.gz" >> ${{ runner.temp }}/jdk_setup.sha256
- curl -L "https://github.com/adoptium/temurin21-binaries/releases/download/jdk-21.0.2%2B13/OpenJDK21U-jdk_x64_linux_hotspot_21.0.2_13.tar.gz" -o "${{ runner.temp }}/jdk_setup.tar.gz"
- sha256sum --check --status "${{ runner.temp }}/jdk_setup.sha256"
-
- #
- # Setup JDK.
- #
- - name: Setup JDK
- if: steps.semantic.outputs.new_release_published == 'true'
- uses: actions/setup-java@5ffc13f4174014e2d4d4572b3d74c3fa61aeb2c2
- with:
- distribution: "jdkfile"
- jdkFile: "${{ runner.temp }}/jdk_setup.tar.gz"
- java-version: "21"
- cache: maven
-
- #
- # Cache Maven.
- #
- - name: Cache Maven
- if: steps.semantic.outputs.new_release_published == 'true'
- uses: actions/cache@88522ab9f39a2ea568f7027eddc7d8d8bc9d59c8
- id: cache-maven
- with:
- key: apache-maven-3.9.6-bin.tar.gz
- path: |
- ${{ runner.temp }}/maven_setup.tar.gz
- ${{ runner.temp }}/maven_setup.sha256
-
- #
- # Download Maven and verify its hash.
- #
- - name: Download Maven and verify its hash
- if: steps.semantic.outputs.new_release_published == 'true' && steps.cache-maven.outputs.cache-hit != 'true'
- run: |
- echo "6eedd2cae3626d6ad3a5c9ee324bd265853d64297f07f033430755bd0e0c3a4b ${{ runner.temp }}/maven_setup.tar.gz" >> ${{ runner.temp }}/maven_setup.sha256
- curl -L "https://archive.apache.org/dist/maven/maven-3/3.9.6/binaries/apache-maven-3.9.6-bin.tar.gz" -o "${{ runner.temp }}/maven_setup.tar.gz"
- sha256sum --check --status "${{ runner.temp }}/maven_setup.sha256"
-
- #
- # Setup Maven.
- #
- - name: Setup Maven
- if: steps.semantic.outputs.new_release_published == 'true'
- run: |
- mkdir ${{ runner.temp }}/maven
- tar -xvf ${{ runner.temp }}/maven_setup.tar.gz -C ${{ runner.temp }}/maven --strip-components=1
- echo "github${{ secrets.GIT_USER }}${{ secrets.GIT_PAT }}" >> ${{ runner.temp }}/settings.xml
-
- #
- # RELEASE CANDIDATE - Update of pom.xml with the new version.
- #
- - name: RELEASE CANDIDATE - Update of pom.xml with the new version
- if: steps.semantic.outputs.new_release_published == 'true'
- run: ${{ runner.temp }}/maven/bin/mvn versions:set -DnewVersion=${{ steps.semantic.outputs.new_release_version }}-RC -s ${{ runner.temp }}/settings.xml --no-transfer-progress
-
- #
- # RELEASE CANDIDATE - Update of openapi.yaml with the new version.
- #
- - name: RELEASE CANDIDATE - Update of openapi.yaml with the new version.
- if: steps.semantic.outputs.new_release_published == 'true'
- run: yq -i ".info.version = \"${{ steps.semantic.outputs.new_release_version }}-RC\"" "src/main/resources/META-INF/openapi.yaml"
-
- #
- # RELEASE CANDIDATE - Execute unit-test + Calculate test coverage + SCA with Sonar.
- #
- - name: RELEASE CANDIDATE - Execute unit-test + Calculate test coverage + SCA with Sonar
- if: steps.semantic.outputs.new_release_published == 'true'
- env:
- SONAR_TOKEN: ${{ secrets.SONAR_TOKEN }}
- run: ${{ runner.temp }}/maven/bin/mvn verify -Pvalidate -s ${{ runner.temp }}/settings.xml --no-transfer-progress
-
- #
- # RELEASE CANDIDATE - Build native executable.
- #
- - name: RELEASE CANDIDATE - Build native executable
- if: steps.semantic.outputs.new_release_published == 'true'
- run: ${{ runner.temp }}/maven/bin/mvn clean package -Pnative -Dmaven.test.skip=true -Dquarkus.native.container-build=true -Dquarkus.native.builder-image=quay.io/quarkus/ubi-quarkus-mandrel-builder-image@sha256:ce70e1a8016471ff0fc9c8f048cd9e37afddacd3de37ed0bca74201d102e45f5 -s ${{ runner.temp }}/settings.xml --no-transfer-progress
-
- #
- # RELEASE CANDIDATE - Build Docker image.
- #
- - name: RELEASE CANDIDATE - Build Docker image
- if: steps.semantic.outputs.new_release_published == 'true'
- run: docker build -f src/main/docker/Dockerfile.native-micro -t ghcr.io/${{ github.repository }}:${{ steps.semantic.outputs.new_release_version }}-RC .
-
- #
- # RELEASE CANDIDATE - Push Docker image.
- #
- - name: RELEASE CANDIDATE - Push Docker image
- if: steps.semantic.outputs.new_release_published == 'true'
- run: |
- echo "${{ secrets.GITHUB_TOKEN }}" | docker login ghcr.io -u ${{ github.actor }} --password-stdin
- docker push -a ghcr.io/${{ github.repository }}
-
- #
- # RELEASE CANDICATE - Get Docker image with sha256.
- #
- - name: RELEASE CANDIDATE - Get Docker image with sha256
- if: steps.semantic.outputs.new_release_published == 'true'
- run: echo "image_sha256_rc=$(docker image inspect -f '{{index .RepoDigests 0}}' ghcr.io/${{ github.repository }}:${{ steps.semantic.outputs.new_release_version }}-RC)" >> "$GITHUB_ENV"
-
- #
- # Login to Azure.
- #
- - name: Login to Azure
- if: steps.semantic.outputs.new_release_published == 'true'
- uses: azure/login@92a5484dfaf04ca78a94597f4f19fea633851fa2
- with:
- client-id: ${{ secrets.AZURE_CLIENT_ID }}
- tenant-id: ${{ secrets.AZURE_TENANT_ID }}
- subscription-id: ${{ secrets.AZURE_SUBSCRIPTION_ID }}
-
- #
- # RELEASE CANDIDATE - Update Container App + OpenAPI descriptor on APIM
- #
- - name: RELEASE CANDIDATE - Update Container App + OpenAPI descriptor on APIM
- if: steps.semantic.outputs.new_release_published == 'true'
- uses: azure/CLI@fa0f960f00db49b95fdb54328a767aee31e80105
- with:
- inlineScript: |
- az config set extension.use_dynamic_install=yes_without_prompt
- az containerapp update -n ${{ secrets.AZURE_CONTAINER_APP_NAME }} -g ${{ secrets.AZURE_RESOURCE_GROUP_NAME }} --subscription ${{ secrets.AZURE_SUBSCRIPTION_ID }} -i ${{ env.image_sha256_rc }}
- API_DATA=$(az apim api show --resource-group ${{ secrets.AZURE_APIM_RESOURCE_GROUP }} --service-name ${{ secrets.AZURE_APIM_NAME }} --api-id ${{ secrets.AZURE_APIM_API_ID }} --subscription ${{ secrets.AZURE_SUBSCRIPTION_ID }} --query "{path:path, serviceUrl:serviceUrl}")
- API_PATH=$(echo $API_DATA | jq -r '.path')
- API_SERVICE_URL=$(echo $API_DATA | jq -r '.serviceUrl')
- az apim api import \
- --resource-group ${{ secrets.AZURE_APIM_RESOURCE_GROUP }} \
- --service-name ${{ secrets.AZURE_APIM_NAME }} \
- --api-id ${{ secrets.AZURE_APIM_API_ID }} \
- --specification-format OpenApi \
- --specification-path src/main/resources/META-INF/openapi.yaml \
- --path $API_PATH \
- --service-url $API_SERVICE_URL \
- --subscription ${{ secrets.AZURE_SUBSCRIPTION_ID }}
-
- #
- # Install Node.
- #
- - name: Install Node
- if: steps.semantic.outputs.new_release_published == 'true'
- uses: actions/setup-node@64ed1c7eab4cce3362f8c340dee64e5eaeef8f7c
- with:
- node-version: "18.16.0"
-
- #
- # Install Newman.
- #
- - name: Install Newman
- if: steps.semantic.outputs.new_release_published == 'true'
- run: npm install -g newman
-
- #
- # Run Postman collection.
- #
- - name: Run Postman collection
- if: steps.semantic.outputs.new_release_published == 'true'
- run: |
- newman run src/test/postman/mil-auth.postman_collection.json \
- -e src/test/postman/dev.postman_environment.json \
- --env-var "correctPassword=${{ secrets.NEWMAN_IT__CORRECTPASSWORD }}" \
- --env-var "correctClientSecret=${{ secrets.NEWMAN_IT__CORRECTCLIENTSECRET }}" \
- --env-var "correctClientSecretForVasLayer=${{ secrets.NEWMAN_IT__CORRECTCLIENTSECRETFORVASLAYER }}" \
- --env-var "clientSecretForMilDebtPosition=${{ secrets.NEWMAN_IT__CLIENTSECRETFORMILDEBTPOSITION }}"
+ dry_run: false
#
- # STABLE - Update of pom.xml and openapi.yaml with the new version.
+ # STABLE - Update of pom.xml with the new version.
#
- name: STABLE - Update of pom.xml and openapi.yaml with the new version
if: steps.semantic.outputs.new_release_published == 'true'
@@ -245,59 +61,28 @@ jobs:
git commit -m "Updated with new version ${{ steps.semantic.outputs.new_release_version }}"
git push origin main
- #
- # Calculation of the new version (again) with tagging + releasing + etc.
- #
- - name: Calculation of the new version (w/o dry_run) and put tag
- if: steps.semantic.outputs.new_release_published == 'true'
- uses: cycjimmy/semantic-release-action@8e58d20d0f6c8773181f43eb74d6a05e3099571d
- env:
- GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
+
+ - name: Log in to the Container registry
+ uses: docker/login-action@9780b0c442fbb1117ed29e0efdff1e18412f7567 # v3.3.0
with:
- semantic_version: 19
- branch: main
- extra_plugins: |
- @semantic-release/release-notes-generator@10.0.3
- @semantic-release/git@10.0.1
- dry_run: false
-
- #
- # STABLE - Build native executable.
- #
- - name: STABLE - Build native executable
- if: steps.semantic.outputs.new_release_published == 'true'
- run: ${{ runner.temp }}/maven/bin/mvn clean package -Pnative -Dmaven.test.skip=true -Dquarkus.native.container-build=true -Dquarkus.native.builder-image=quay.io/quarkus/ubi-quarkus-mandrel-builder-image@sha256:ce70e1a8016471ff0fc9c8f048cd9e37afddacd3de37ed0bca74201d102e45f5 -s ${{ runner.temp }}/settings.xml --no-transfer-progress
-
- #
- # STABLE - Build Docker image.
- #
- - name: STABLE - Build Docker image
- if: steps.semantic.outputs.new_release_published == 'true'
- run: docker build -f src/main/docker/Dockerfile.native-micro -t ghcr.io/${{ github.repository }}:latest -t ghcr.io/${{ github.repository }}:${{ steps.semantic.outputs.new_release_version }} .
-
- #
- # STABLE - Push Docker image.
- #
- - name: STABLE - Push Docker image
- if: steps.semantic.outputs.new_release_published == 'true'
- run: |
- echo "${{ secrets.GITHUB_TOKEN }}" | docker login ghcr.io -u ${{ github.actor }} --password-stdin
- docker push -a ghcr.io/${{ github.repository }}
-
- #
- # STABLE - Get Docker image with sha256.
- #
- - name: STABLE - Get Docker image with sha256
- if: steps.semantic.outputs.new_release_published == 'true'
- run: echo "image_sha256=$(docker image inspect -f '{{index .RepoDigests 0}}' ghcr.io/${{ github.repository }}:${{ steps.semantic.outputs.new_release_version }})" >> "$GITHUB_ENV"
-
- #
- # STABLE - Update Container App.
- #
- - name: STABLE - Update Container App
- if: steps.semantic.outputs.new_release_published == 'true'
- uses: azure/CLI@fa0f960f00db49b95fdb54328a767aee31e80105
+ registry: https://ghcr.io
+ username: ${{ github.actor }}
+ password: ${{ secrets.GITHUB_TOKEN }}
+
+ - name: Set up QEMU
+ uses: docker/setup-qemu-action@49b3bc8e6bdd4a60e6116a5414239cba5943d3cf # v3.2.0
+
+ - name: Set up Docker Buildx
+ uses: docker/setup-buildx-action@988b5a0280414f521da01fcc63a27aeeb4b104db # v3.6.1
+
+ - name: Build the app image
+ uses: docker/build-push-action@5cd11c3a4ced054e52742c5fd54dca954e0edd85 # v6.7.0
with:
- inlineScript: |
- az config set extension.use_dynamic_install=yes_without_prompt
- az containerapp update -n ${{ secrets.AZURE_CONTAINER_APP_NAME }} -g ${{ secrets.AZURE_RESOURCE_GROUP_NAME }} --subscription ${{ secrets.AZURE_SUBSCRIPTION_ID }} -i ${{ env.image_sha256 }}
\ No newline at end of file
+ push: true
+ context: .
+ file: src/main/docker/Dockerfile.multistage
+ platforms: linux/amd64
+ tags: ghcr.io/${{ github.repository }}:latest, ghcr.io/${{ github.repository }}:${{ steps.semantic.outputs.new_release_version }}
+ secrets: |
+ "gh_token=${{ secrets.GIT_PAT }}"
+
diff --git a/.github/workflows/pr-validation.yml b/.github/workflows/pr-validation.yml
index 80dc0e27..a564b830 100644
--- a/.github/workflows/pr-validation.yml
+++ b/.github/workflows/pr-validation.yml
@@ -12,7 +12,10 @@ on:
jobs:
pr-validation:
runs-on: ubuntu-latest
-
+ outputs:
+ CVE_CRITICAL: ${{env.CVE_CRITICAL}}
+ CVE_HIGH: ${{env.CVE_HIGH}}
+ CVE_MEDIUM: ${{env.CVE_MEDIUM}}
steps:
- name: PR title validation
uses: amannn/action-semantic-pull-request@c3cd5d1ea3580753008872425915e343e351ab54
@@ -84,9 +87,33 @@ jobs:
run: |
mkdir ${{ runner.temp }}/maven
tar -xvf ${{ runner.temp }}/maven_setup.tar.gz -C ${{ runner.temp }}/maven --strip-components=1
- echo "github${{ secrets.GIT_USER }}${{ secrets.GIT_PAT }}" >> ${{ runner.temp }}/settings.xml
+ echo "github${{ secrets.GIT_PAT }}" >> ${{ runner.temp }}/settings.xml
- name: Execute unit-test + Calculate test coverage + SCA with Sonar
env:
SONAR_TOKEN: ${{ secrets.SONAR_TOKEN }}
run: ${{ runner.temp }}/maven/bin/mvn verify -Pvalidate -s ${{ runner.temp }}/settings.xml --no-transfer-progress
+
+ - name: Run the Trivy scan action itself with GitHub Advanced Security code scanning integration enabled
+ id: scan
+ uses: aquasecurity/trivy-action@595be6a0f6560a0a8fc419ddf630567fc623531d # v0.22.0
+ with:
+ scan-type: 'fs'
+ format: 'sarif'
+ output: 'results.sarif'
+ - name: Upload Anchore Scan Report
+ uses: github/codeql-action/upload-sarif@9550da953dd3b29aedf76cd635101e48eae5eebd # CodeQL Bundle v2.17.4
+ with:
+ sarif_file: 'results.sarif'
+ - name: CVE Description escaped extraction and print
+ run: |
+ SCAN_RESULTS=$(jq -r 'try .runs[0].tool.driver.rules | map(.help.text) | join("\\n")' results.sarif)
+ echo "CVE_CRITICAL=$(echo $SCAN_RESULTS | grep -o CRITICAL | wc -l)" >> $GITHUB_ENV
+ echo "CVE_HIGH=$(echo $SCAN_RESULTS | grep -o HIGH | wc -l)" >> $GITHUB_ENV
+ echo "CVE_MEDIUM=$(echo $SCAN_RESULTS | grep -o MEDIUM | wc -l)" >> $GITHUB_ENV
+
+ echo $SCAN_RESULTS
+ - name: Fails if CVE HIGH or CRITICAL are detected
+ id: cve-threshold
+ if: env.CVE_HIGH > 0 || env.CVE_CRITICAL > 0
+ run: exit 1
diff --git a/.github/workflows/scan.yml b/.github/workflows/scan.yml
new file mode 100644
index 00000000..e5f248cf
--- /dev/null
+++ b/.github/workflows/scan.yml
@@ -0,0 +1,59 @@
+# This workflow uses actions that are not certified by GitHub.
+# They are provided by a third-party and are governed by
+# separate terms of service, privacy policy, and support
+# documentation.
+
+# This workflow checks out code, builds an image, performs a container image
+# vulnerability scan with Trivy tool, and integrates the results with GitHub Advanced Security
+# code scanning feature.
+name: Container Scan
+
+on:
+ push:
+ branches: [ "main" ]
+ schedule:
+ - cron: '00 07 * * *'
+
+permissions:
+ contents: read
+
+env:
+ DOCKERFILE: Dockerfile.multistage
+
+jobs:
+ BuildAndScan:
+ permissions:
+ contents: read # for actions/checkout to fetch code
+ security-events: write # for github/codeql-action/upload-sarif to upload SARIF results
+ actions: read # only required for a private repository by github/codeql-action/upload-sarif to get the Action run status
+ runs-on: ubuntu-latest
+ outputs:
+ CVE_CRITICAL: ${{env.CVE_CRITICAL}}
+ CVE_HIGH: ${{env.CVE_HIGH}}
+ CVE_MEDIUM: ${{env.CVE_MEDIUM}}
+ steps:
+ - name: Checkout the code
+ uses: actions/checkout@a5ac7e51b41094c92402da3b24376905380afc29 # v4.1.6
+ - name: Run the Trivy scan action itself with GitHub Advanced Security code scanning integration enabled
+ id: scan
+ uses: aquasecurity/trivy-action@595be6a0f6560a0a8fc419ddf630567fc623531d # v0.22.0
+ with:
+ image-ref: "ghcr.io/${{ github.repository }}:latest"
+ format: 'sarif'
+ output: 'results.sarif'
+ - name: Upload Anchore Scan Report
+ uses: github/codeql-action/upload-sarif@9550da953dd3b29aedf76cd635101e48eae5eebd # CodeQL Bundle v2.17.4
+ with:
+ sarif_file: 'results.sarif'
+ - name: CVE Description escaped extraction and print
+ run: |
+ SCAN_RESULTS=$(jq -r 'try .runs[0].tool.driver.rules | map(.help.text) | join("\\n")' results.sarif)
+ echo "CVE_CRITICAL=$(echo $SCAN_RESULTS | grep -o CRITICAL | wc -l)" >> $GITHUB_ENV
+ echo "CVE_HIGH=$(echo $SCAN_RESULTS | grep -o HIGH | wc -l)" >> $GITHUB_ENV
+ echo "CVE_MEDIUM=$(echo $SCAN_RESULTS | grep -o MEDIUM | wc -l)" >> $GITHUB_ENV
+
+ echo $SCAN_RESULTS
+ - name: Fails if CVE HIGH or CRITICAL are detected
+ id: cve-threshold
+ if: env.CVE_HIGH > 0 || env.CVE_CRITICAL > 0
+ run: exit 1
diff --git a/.github/workflows/sonar-cloud-coverage.yml b/.github/workflows/sonar-cloud-coverage.yml
new file mode 100644
index 00000000..2b85ede8
--- /dev/null
+++ b/.github/workflows/sonar-cloud-coverage.yml
@@ -0,0 +1,85 @@
+name: Sonarcloud coverage
+
+on:
+ pull_request:
+ types:
+ - closed
+ branches:
+ - main
+
+jobs:
+ post_merge:
+ if: github.event.pull_request.merged == true
+
+ runs-on: ubuntu-latest
+
+ environment: dev-cd
+
+ permissions:
+ id-token: write
+ packages: write
+ contents: write
+
+ steps:
+ #
+ # Checkout the source code.
+ #
+ - name: Checkout the source code
+ uses: actions/checkout@8e5e7e5ab8b370d6c329ec480221332ada57f0ab
+ with:
+ token: ${{ secrets.GIT_PAT }}
+ fetch-depth: 0
+
+ #
+ # Cache JDK.
+ #
+ - name: Cache JDK
+ uses: actions/cache@88522ab9f39a2ea568f7027eddc7d8d8bc9d59c8
+ id: cache-jdk
+ with:
+ key: OpenJDK21U-jdk_x64_linux_hotspot_21.0.2_13.tar.gz
+ path: |
+ ${{ runner.temp }}/jdk_setup.tar.gz
+ ${{ runner.temp }}/jdk_setup.sha256
+
+ #
+ # Setup JDK.
+ #
+ - name: Setup JDK
+ uses: actions/setup-java@5ffc13f4174014e2d4d4572b3d74c3fa61aeb2c2
+ with:
+ distribution: "jdkfile"
+ jdkFile: "${{ runner.temp }}/jdk_setup.tar.gz"
+ java-version: "21"
+ cache: maven
+
+ #
+ # Cache Maven.
+ #
+ - name: Cache Maven
+ uses: actions/cache@88522ab9f39a2ea568f7027eddc7d8d8bc9d59c8
+ id: cache-maven
+ with:
+ key: apache-maven-3.9.6-bin.tar.gz
+ path: |
+ ${{ runner.temp }}/maven_setup.tar.gz
+ ${{ runner.temp }}/maven_setup.sha256
+
+ #
+ # Setup Maven.
+ #
+ - name: Setup Maven
+ run: |
+ mkdir ${{ runner.temp }}/maven
+ tar -xvf ${{ runner.temp }}/maven_setup.tar.gz -C ${{ runner.temp }}/maven --strip-components=1
+ echo "github${{ secrets.GIT_PAT }}" >> ${{ runner.temp }}/settings.xml
+
+ #
+ # RELEASE CANDIDATE - Execute unit-test + Calculate test coverage + SCA with Sonar.
+ #
+ - name: RELEASE CANDIDATE - Execute unit-test + Calculate test coverage + SCA with Sonar
+ env:
+ SONAR_TOKEN: ${{ secrets.SONAR_TOKEN }}
+ run: ${{ runner.temp }}/maven/bin/mvn verify -Pvalidate -s ${{ runner.temp }}/settings.xml --no-transfer-progress
+
+
diff --git a/.mvn/wrapper/MavenWrapperDownloader.java b/.mvn/wrapper/MavenWrapperDownloader.java
deleted file mode 100644
index 05212d56..00000000
--- a/.mvn/wrapper/MavenWrapperDownloader.java
+++ /dev/null
@@ -1,121 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you 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
- *
- * http://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.
- */
-
-import java.net.*;
-import java.io.*;
-import java.nio.channels.*;
-import java.util.Properties;
-
-public class MavenWrapperDownloader {
- private static final String WRAPPER_VERSION = "3.1.1";
-
- /**
- * Default URL to download the maven-wrapper.jar from, if no 'downloadUrl' is provided.
- */
- private static final String DEFAULT_DOWNLOAD_URL =
- "https://repo.maven.apache.org/maven2/org/apache/maven/wrapper/maven-wrapper/" + WRAPPER_VERSION
- + "/maven-wrapper-" + WRAPPER_VERSION + ".jar";
-
- /**
- * Path to the maven-wrapper.properties file, which might contain a downloadUrl property to use instead of the
- * default one.
- */
- private static final String MAVEN_WRAPPER_PROPERTIES_PATH = ".mvn/wrapper/maven-wrapper.properties";
-
- /**
- * Path where the maven-wrapper.jar will be saved to.
- */
- private static final String MAVEN_WRAPPER_JAR_PATH = ".mvn/wrapper/maven-wrapper.jar";
-
- /**
- * Name of the property which should be used to override the default download url for the wrapper.
- */
- private static final String PROPERTY_NAME_WRAPPER_URL = "wrapperUrl";
-
- public static void main(String args[]) {
- System.out.println("- Downloader started");
- File baseDirectory = new File(args[0]);
- System.out.println("- Using base directory: " + baseDirectory.getAbsolutePath());
-
- // If the maven-wrapper.properties exists, read it and check if it contains a custom
- // wrapperUrl parameter.
- File mavenWrapperPropertyFile = new File(baseDirectory, MAVEN_WRAPPER_PROPERTIES_PATH);
- String url = DEFAULT_DOWNLOAD_URL;
- if (mavenWrapperPropertyFile.exists()) {
- FileInputStream mavenWrapperPropertyFileInputStream = null;
- try {
- mavenWrapperPropertyFileInputStream = new FileInputStream(mavenWrapperPropertyFile);
- Properties mavenWrapperProperties = new Properties();
- mavenWrapperProperties.load(mavenWrapperPropertyFileInputStream);
- url = mavenWrapperProperties.getProperty(PROPERTY_NAME_WRAPPER_URL, url);
- } catch (IOException e) {
- System.out.println("- ERROR loading '" + MAVEN_WRAPPER_PROPERTIES_PATH + "'");
- } finally {
- try {
- if (mavenWrapperPropertyFileInputStream != null) {
- mavenWrapperPropertyFileInputStream.close();
- }
- } catch (IOException e) {
- // Ignore ...
- }
- }
- }
- System.out.println("- Downloading from: " + url);
-
- File outputFile = new File(baseDirectory.getAbsolutePath(), MAVEN_WRAPPER_JAR_PATH);
- if (!outputFile.getParentFile().exists()) {
- if (!outputFile.getParentFile().mkdirs()) {
- System.out.println("- ERROR creating output directory '" + outputFile.getParentFile().getAbsolutePath()
- + "'");
- }
- }
- System.out.println("- Downloading to: " + outputFile.getAbsolutePath());
- try {
- downloadFileFromURL(url, outputFile);
- System.out.println("Done");
- System.exit(0);
- } catch (Throwable e) {
- System.out.println("- Error downloading");
- e.printStackTrace();
- System.exit(1);
- }
- }
-
- private static void downloadFileFromURL(String urlString, File destination)
- throws Exception {
- if (System.getenv("MVNW_USERNAME") != null && System.getenv("MVNW_PASSWORD") != null) {
- String username = System.getenv("MVNW_USERNAME");
- char[] password = System.getenv("MVNW_PASSWORD").toCharArray();
- Authenticator.setDefault(new Authenticator() {
- @Override
- protected PasswordAuthentication getPasswordAuthentication() {
- return new PasswordAuthentication(username, password);
- }
- });
- }
- URL website = new URL(urlString);
- ReadableByteChannel rbc;
- rbc = Channels.newChannel(website.openStream());
- FileOutputStream fos = new FileOutputStream(destination);
- fos.getChannel().transferFrom(rbc, 0, Long.MAX_VALUE);
- fos.close();
- rbc.close();
- }
-
-}
diff --git a/.mvn/wrapper/maven-wrapper.properties b/.mvn/wrapper/maven-wrapper.properties
index 61a2ef15..f95f1ee8 100644
--- a/.mvn/wrapper/maven-wrapper.properties
+++ b/.mvn/wrapper/maven-wrapper.properties
@@ -14,5 +14,6 @@
# KIND, either express or implied. See the License for the
# specific language governing permissions and limitations
# under the License.
-distributionUrl=https://repo.maven.apache.org/maven2/org/apache/maven/apache-maven/3.8.6/apache-maven-3.8.6-bin.zip
-wrapperUrl=https://repo.maven.apache.org/maven2/org/apache/maven/wrapper/maven-wrapper/3.1.1/maven-wrapper-3.1.1.jar
+wrapperVersion=3.3.2
+distributionType=only-script
+distributionUrl=https://repo.maven.apache.org/maven2/org/apache/maven/apache-maven/3.9.8/apache-maven-3.9.8-bin.zip
diff --git a/dep-sha256.json b/dep-sha256.json
index cf706d68..48c6e3d9 100644
--- a/dep-sha256.json
+++ b/dep-sha256.json
@@ -1162,6 +1162,48 @@
"version": "7.0.2.Final",
"sha256": "SO7eXzXFpmsE8nMEoro11MFjF3Ioy6etL48v5v_kdlI="
},
+ {
+ "id": "io.quarkus:quarkus-smallrye-health:jar:3.14.1",
+ "artifactId": "quarkus-smallrye-health",
+ "groupId": "io.quarkus",
+ "version": "3.14.1",
+ "sha256": "RONWCK748SPzeEXsz9goJsjMAtdNmqLq9IVuH7fwquc="
+ },
+ {
+ "id": "io.smallrye:smallrye-health:jar:4.1.0",
+ "artifactId": "smallrye-health",
+ "groupId": "io.smallrye",
+ "version": "4.1.0",
+ "sha256": "ahk1ZRigIsSj9FziM8mAPSQ11dGg4jhSYrEvPm5SWVw="
+ },
+ {
+ "id": "org.eclipse.microprofile.health:microprofile-health-api:jar:4.0.1",
+ "artifactId": "microprofile-health-api",
+ "groupId": "org.eclipse.microprofile.health",
+ "version": "4.0.1",
+ "sha256": "uJyktsT3oEQlDTHAZz9rwiHkD9Zp_Fhx261eWgdpykc="
+ },
+ {
+ "id": "io.smallrye:smallrye-health-api:jar:4.1.0",
+ "artifactId": "smallrye-health-api",
+ "groupId": "io.smallrye",
+ "version": "4.1.0",
+ "sha256": "gPcWfuQvorD1h9MIow5QJLWq8UtlFnNQrxhSz5_64Jw="
+ },
+ {
+ "id": "jakarta.json:jakarta.json-api:jar:2.1.3",
+ "artifactId": "jakarta.json-api",
+ "groupId": "jakarta.json",
+ "version": "2.1.3",
+ "sha256": "vJNBQoBeodeU8UQFY5ZaOGGiqft0FOzT_kTyZQBzRBQ="
+ },
+ {
+ "id": "io.smallrye:smallrye-health-provided-checks:jar:4.1.0",
+ "artifactId": "smallrye-health-provided-checks",
+ "groupId": "io.smallrye",
+ "version": "4.1.0",
+ "sha256": "B-W5cMNWebjKBSV7VOSb3-uKLiIKTSdTYcOgrN0TgIk="
+ },
{
"id": "io.quarkus:quarkus-junit5:jar:3.14.1",
"artifactId": "quarkus-junit5",
@@ -2282,13 +2324,6 @@
"version": "2.5.0",
"sha256": "tvsN7NYHFlazfa4Lg0ezI3OeyQwbfkBEiIuThNVKQhg="
},
- {
- "id": "jakarta.json:jakarta.json-api:jar:2.1.3",
- "artifactId": "jakarta.json-api",
- "groupId": "jakarta.json",
- "version": "2.1.3",
- "sha256": "vJNBQoBeodeU8UQFY5ZaOGGiqft0FOzT_kTyZQBzRBQ="
- },
{
"id": "io.quarkus:quarkus-opentelemetry:jar:3.14.1",
"artifactId": "quarkus-opentelemetry",
diff --git a/mvnw b/mvnw
index eaa3d308..19529ddf 100755
--- a/mvnw
+++ b/mvnw
@@ -8,7 +8,7 @@
# "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
+# http://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
@@ -19,298 +19,241 @@
# ----------------------------------------------------------------------------
# ----------------------------------------------------------------------------
-# Maven Start Up Batch script
-#
-# Required ENV vars:
-# ------------------
-# JAVA_HOME - location of a JDK home dir
+# Apache Maven Wrapper startup batch script, version 3.3.2
#
# Optional ENV vars
# -----------------
-# M2_HOME - location of maven2's installed home dir
-# MAVEN_OPTS - parameters passed to the Java VM when running Maven
-# e.g. to debug Maven itself, use
-# set MAVEN_OPTS=-Xdebug -Xrunjdwp:transport=dt_socket,server=y,suspend=y,address=8000
-# MAVEN_SKIP_RC - flag to disable loading of mavenrc files
+# JAVA_HOME - location of a JDK home dir, required when download maven via java source
+# MVNW_REPOURL - repo url base for downloading maven distribution
+# MVNW_USERNAME/MVNW_PASSWORD - user and password for downloading maven
+# MVNW_VERBOSE - true: enable verbose log; debug: trace the mvnw script; others: silence the output
# ----------------------------------------------------------------------------
-if [ -z "$MAVEN_SKIP_RC" ] ; then
-
- if [ -f /usr/local/etc/mavenrc ] ; then
- . /usr/local/etc/mavenrc
- fi
-
- if [ -f /etc/mavenrc ] ; then
- . /etc/mavenrc
- fi
+set -euf
+[ "${MVNW_VERBOSE-}" != debug ] || set -x
- if [ -f "$HOME/.mavenrc" ] ; then
- . "$HOME/.mavenrc"
- fi
+# OS specific support.
+native_path() { printf %s\\n "$1"; }
+case "$(uname)" in
+CYGWIN* | MINGW*)
+ [ -z "${JAVA_HOME-}" ] || JAVA_HOME="$(cygpath --unix "$JAVA_HOME")"
+ native_path() { cygpath --path --windows "$1"; }
+ ;;
+esac
-fi
+# set JAVACMD and JAVACCMD
+set_java_home() {
+ # For Cygwin and MinGW, ensure paths are in Unix format before anything is touched
+ 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"
+ JAVACCMD="$JAVA_HOME/jre/sh/javac"
+ else
+ JAVACMD="$JAVA_HOME/bin/java"
+ JAVACCMD="$JAVA_HOME/bin/javac"
-# OS specific support. $var _must_ be set to either true or false.
-cygwin=false;
-darwin=false;
-mingw=false
-case "`uname`" in
- CYGWIN*) cygwin=true ;;
- MINGW*) mingw=true;;
- Darwin*) darwin=true
- # Use /usr/libexec/java_home if available, otherwise fall back to /Library/Java/Home
- # See https://developer.apple.com/library/mac/qa/qa1170/_index.html
- if [ -z "$JAVA_HOME" ]; then
- if [ -x "/usr/libexec/java_home" ]; then
- export JAVA_HOME="`/usr/libexec/java_home`"
- else
- export JAVA_HOME="/Library/Java/Home"
+ if [ ! -x "$JAVACMD" ] || [ ! -x "$JAVACCMD" ]; then
+ echo "The JAVA_HOME environment variable is not defined correctly, so mvnw cannot run." >&2
+ echo "JAVA_HOME is set to \"$JAVA_HOME\", but \"\$JAVA_HOME/bin/java\" or \"\$JAVA_HOME/bin/javac\" does not exist." >&2
+ return 1
fi
fi
- ;;
-esac
-
-if [ -z "$JAVA_HOME" ] ; then
- if [ -r /etc/gentoo-release ] ; then
- JAVA_HOME=`java-config --jre-home`
+ else
+ JAVACMD="$(
+ 'set' +e
+ 'unset' -f command 2>/dev/null
+ 'command' -v java
+ )" || :
+ JAVACCMD="$(
+ 'set' +e
+ 'unset' -f command 2>/dev/null
+ 'command' -v javac
+ )" || :
+
+ if [ ! -x "${JAVACMD-}" ] || [ ! -x "${JAVACCMD-}" ]; then
+ echo "The java/javac command does not exist in PATH nor is JAVA_HOME set, so mvnw cannot run." >&2
+ return 1
+ fi
fi
-fi
-
-if [ -z "$M2_HOME" ] ; then
- ## resolve links - $0 may be a link to maven's home
- 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
+# hash string like Java String::hashCode
+hash_string() {
+ str="${1:-}" h=0
+ while [ -n "$str" ]; do
+ char="${str%"${str#?}"}"
+ h=$(((h * 31 + $(LC_CTYPE=C printf %d "'$char")) % 4294967296))
+ str="${str#?}"
done
+ printf %x\\n $h
+}
- saveddir=`pwd`
+verbose() { :; }
+[ "${MVNW_VERBOSE-}" != true ] || verbose() { printf %s\\n "${1-}"; }
- M2_HOME=`dirname "$PRG"`/..
+die() {
+ printf %s\\n "$1" >&2
+ exit 1
+}
- # make it fully qualified
- M2_HOME=`cd "$M2_HOME" && pwd`
+trim() {
+ # MWRAPPER-139:
+ # Trims trailing and leading whitespace, carriage returns, tabs, and linefeeds.
+ # Needed for removing poorly interpreted newline sequences when running in more
+ # exotic environments such as mingw bash on Windows.
+ printf "%s" "${1}" | tr -d '[:space:]'
+}
- cd "$saveddir"
- # echo Using m2 at $M2_HOME
-fi
+# parse distributionUrl and optional distributionSha256Sum, requires .mvn/wrapper/maven-wrapper.properties
+while IFS="=" read -r key value; do
+ case "${key-}" in
+ distributionUrl) distributionUrl=$(trim "${value-}") ;;
+ distributionSha256Sum) distributionSha256Sum=$(trim "${value-}") ;;
+ esac
+done <"${0%/*}/.mvn/wrapper/maven-wrapper.properties"
+[ -n "${distributionUrl-}" ] || die "cannot read distributionUrl property in ${0%/*}/.mvn/wrapper/maven-wrapper.properties"
+
+case "${distributionUrl##*/}" in
+maven-mvnd-*bin.*)
+ MVN_CMD=mvnd.sh _MVNW_REPO_PATTERN=/maven/mvnd/
+ case "${PROCESSOR_ARCHITECTURE-}${PROCESSOR_ARCHITEW6432-}:$(uname -a)" in
+ *AMD64:CYGWIN* | *AMD64:MINGW*) distributionPlatform=windows-amd64 ;;
+ :Darwin*x86_64) distributionPlatform=darwin-amd64 ;;
+ :Darwin*arm64) distributionPlatform=darwin-aarch64 ;;
+ :Linux*x86_64*) distributionPlatform=linux-amd64 ;;
+ *)
+ echo "Cannot detect native platform for mvnd on $(uname)-$(uname -m), use pure java version" >&2
+ distributionPlatform=linux-amd64
+ ;;
+ esac
+ distributionUrl="${distributionUrl%-bin.*}-$distributionPlatform.zip"
+ ;;
+maven-mvnd-*) MVN_CMD=mvnd.sh _MVNW_REPO_PATTERN=/maven/mvnd/ ;;
+*) MVN_CMD="mvn${0##*/mvnw}" _MVNW_REPO_PATTERN=/org/apache/maven/ ;;
+esac
-# For Cygwin, ensure paths are in UNIX format before anything is touched
-if $cygwin ; then
- [ -n "$M2_HOME" ] &&
- M2_HOME=`cygpath --unix "$M2_HOME"`
- [ -n "$JAVA_HOME" ] &&
- JAVA_HOME=`cygpath --unix "$JAVA_HOME"`
- [ -n "$CLASSPATH" ] &&
- CLASSPATH=`cygpath --path --unix "$CLASSPATH"`
-fi
+# apply MVNW_REPOURL and calculate MAVEN_HOME
+# maven home pattern: ~/.m2/wrapper/dists/{apache-maven-,maven-mvnd--}/
+[ -z "${MVNW_REPOURL-}" ] || distributionUrl="$MVNW_REPOURL$_MVNW_REPO_PATTERN${distributionUrl#*"$_MVNW_REPO_PATTERN"}"
+distributionUrlName="${distributionUrl##*/}"
+distributionUrlNameMain="${distributionUrlName%.*}"
+distributionUrlNameMain="${distributionUrlNameMain%-bin}"
+MAVEN_USER_HOME="${MAVEN_USER_HOME:-${HOME}/.m2}"
+MAVEN_HOME="${MAVEN_USER_HOME}/wrapper/dists/${distributionUrlNameMain-}/$(hash_string "$distributionUrl")"
+
+exec_maven() {
+ unset MVNW_VERBOSE MVNW_USERNAME MVNW_PASSWORD MVNW_REPOURL || :
+ exec "$MAVEN_HOME/bin/$MVN_CMD" "$@" || die "cannot exec $MAVEN_HOME/bin/$MVN_CMD"
+}
-# For Mingw, ensure paths are in UNIX format before anything is touched
-if $mingw ; then
- [ -n "$M2_HOME" ] &&
- M2_HOME="`(cd "$M2_HOME"; pwd)`"
- [ -n "$JAVA_HOME" ] &&
- JAVA_HOME="`(cd "$JAVA_HOME"; pwd)`"
+if [ -d "$MAVEN_HOME" ]; then
+ verbose "found existing MAVEN_HOME at $MAVEN_HOME"
+ exec_maven "$@"
fi
-if [ -z "$JAVA_HOME" ]; then
- javaExecutable="`which javac`"
- if [ -n "$javaExecutable" ] && ! [ "`expr \"$javaExecutable\" : '\([^ ]*\)'`" = "no" ]; then
- # readlink(1) is not available as standard on Solaris 10.
- readLink=`which readlink`
- if [ ! `expr "$readLink" : '\([^ ]*\)'` = "no" ]; then
- if $darwin ; then
- javaHome="`dirname \"$javaExecutable\"`"
- javaExecutable="`cd \"$javaHome\" && pwd -P`/javac"
- else
- javaExecutable="`readlink -f \"$javaExecutable\"`"
- fi
- javaHome="`dirname \"$javaExecutable\"`"
- javaHome=`expr "$javaHome" : '\(.*\)/bin'`
- JAVA_HOME="$javaHome"
- export JAVA_HOME
- fi
- fi
-fi
+case "${distributionUrl-}" in
+*?-bin.zip | *?maven-mvnd-?*-?*.zip) ;;
+*) die "distributionUrl is not valid, must match *-bin.zip or maven-mvnd-*.zip, but found '${distributionUrl-}'" ;;
+esac
-if [ -z "$JAVACMD" ] ; then
- 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
- else
- JAVACMD="`\\unset -f command; \\command -v java`"
- fi
+# prepare tmp dir
+if TMP_DOWNLOAD_DIR="$(mktemp -d)" && [ -d "$TMP_DOWNLOAD_DIR" ]; then
+ clean() { rm -rf -- "$TMP_DOWNLOAD_DIR"; }
+ trap clean HUP INT TERM EXIT
+else
+ die "cannot create temp dir"
fi
-if [ ! -x "$JAVACMD" ] ; then
- echo "Error: JAVA_HOME is not defined correctly." >&2
- echo " We cannot execute $JAVACMD" >&2
- exit 1
-fi
+mkdir -p -- "${MAVEN_HOME%/*}"
-if [ -z "$JAVA_HOME" ] ; then
- echo "Warning: JAVA_HOME environment variable is not set."
+# Download and Install Apache Maven
+verbose "Couldn't find MAVEN_HOME, downloading and installing it ..."
+verbose "Downloading from: $distributionUrl"
+verbose "Downloading to: $TMP_DOWNLOAD_DIR/$distributionUrlName"
+
+# select .zip or .tar.gz
+if ! command -v unzip >/dev/null; then
+ distributionUrl="${distributionUrl%.zip}.tar.gz"
+ distributionUrlName="${distributionUrl##*/}"
fi
-CLASSWORLDS_LAUNCHER=org.codehaus.plexus.classworlds.launcher.Launcher
+# verbose opt
+__MVNW_QUIET_WGET=--quiet __MVNW_QUIET_CURL=--silent __MVNW_QUIET_UNZIP=-q __MVNW_QUIET_TAR=''
+[ "${MVNW_VERBOSE-}" != true ] || __MVNW_QUIET_WGET='' __MVNW_QUIET_CURL='' __MVNW_QUIET_UNZIP='' __MVNW_QUIET_TAR=v
-# traverses directory structure from process work directory to filesystem root
-# first directory with .mvn subdirectory is considered project base directory
-find_maven_basedir() {
+# normalize http auth
+case "${MVNW_PASSWORD:+has-password}" in
+'') MVNW_USERNAME='' MVNW_PASSWORD='' ;;
+has-password) [ -n "${MVNW_USERNAME-}" ] || MVNW_USERNAME='' MVNW_PASSWORD='' ;;
+esac
- if [ -z "$1" ]
- then
- echo "Path not specified to find_maven_basedir"
- return 1
- fi
+if [ -z "${MVNW_USERNAME-}" ] && command -v wget >/dev/null; then
+ verbose "Found wget ... using wget"
+ wget ${__MVNW_QUIET_WGET:+"$__MVNW_QUIET_WGET"} "$distributionUrl" -O "$TMP_DOWNLOAD_DIR/$distributionUrlName" || die "wget: Failed to fetch $distributionUrl"
+elif [ -z "${MVNW_USERNAME-}" ] && command -v curl >/dev/null; then
+ verbose "Found curl ... using curl"
+ curl ${__MVNW_QUIET_CURL:+"$__MVNW_QUIET_CURL"} -f -L -o "$TMP_DOWNLOAD_DIR/$distributionUrlName" "$distributionUrl" || die "curl: Failed to fetch $distributionUrl"
+elif set_java_home; then
+ verbose "Falling back to use Java to download"
+ javaSource="$TMP_DOWNLOAD_DIR/Downloader.java"
+ targetZip="$TMP_DOWNLOAD_DIR/$distributionUrlName"
+ cat >"$javaSource" <<-END
+ public class Downloader extends java.net.Authenticator
+ {
+ protected java.net.PasswordAuthentication getPasswordAuthentication()
+ {
+ return new java.net.PasswordAuthentication( System.getenv( "MVNW_USERNAME" ), System.getenv( "MVNW_PASSWORD" ).toCharArray() );
+ }
+ public static void main( String[] args ) throws Exception
+ {
+ setDefault( new Downloader() );
+ java.nio.file.Files.copy( java.net.URI.create( args[0] ).toURL().openStream(), java.nio.file.Paths.get( args[1] ).toAbsolutePath().normalize() );
+ }
+ }
+ END
+ # For Cygwin/MinGW, switch paths to Windows format before running javac and java
+ verbose " - Compiling Downloader.java ..."
+ "$(native_path "$JAVACCMD")" "$(native_path "$javaSource")" || die "Failed to compile Downloader.java"
+ verbose " - Running Downloader.java ..."
+ "$(native_path "$JAVACMD")" -cp "$(native_path "$TMP_DOWNLOAD_DIR")" Downloader "$distributionUrl" "$(native_path "$targetZip")"
+fi
- basedir="$1"
- wdir="$1"
- while [ "$wdir" != '/' ] ; do
- if [ -d "$wdir"/.mvn ] ; then
- basedir=$wdir
- break
+# If specified, validate the SHA-256 sum of the Maven distribution zip file
+if [ -n "${distributionSha256Sum-}" ]; then
+ distributionSha256Result=false
+ if [ "$MVN_CMD" = mvnd.sh ]; then
+ echo "Checksum validation is not supported for maven-mvnd." >&2
+ echo "Please disable validation by removing 'distributionSha256Sum' from your maven-wrapper.properties." >&2
+ exit 1
+ elif command -v sha256sum >/dev/null; then
+ if echo "$distributionSha256Sum $TMP_DOWNLOAD_DIR/$distributionUrlName" | sha256sum -c >/dev/null 2>&1; then
+ distributionSha256Result=true
fi
- # workaround for JBEAP-8937 (on Solaris 10/Sparc)
- if [ -d "${wdir}" ]; then
- wdir=`cd "$wdir/.."; pwd`
+ elif command -v shasum >/dev/null; then
+ if echo "$distributionSha256Sum $TMP_DOWNLOAD_DIR/$distributionUrlName" | shasum -a 256 -c >/dev/null 2>&1; then
+ distributionSha256Result=true
fi
- # end of workaround
- done
- echo "${basedir}"
-}
-
-# concatenates all lines of a file
-concat_lines() {
- if [ -f "$1" ]; then
- echo "$(tr -s '\n' ' ' < "$1")"
+ else
+ echo "Checksum validation was requested but neither 'sha256sum' or 'shasum' are available." >&2
+ echo "Please install either command, or disable validation by removing 'distributionSha256Sum' from your maven-wrapper.properties." >&2
+ exit 1
+ fi
+ if [ $distributionSha256Result = false ]; then
+ echo "Error: Failed to validate Maven distribution SHA-256, your Maven distribution might be compromised." >&2
+ echo "If you updated your Maven version, you need to update the specified distributionSha256Sum property." >&2
+ exit 1
fi
-}
-
-BASE_DIR=`find_maven_basedir "$(pwd)"`
-if [ -z "$BASE_DIR" ]; then
- exit 1;
fi
-##########################################################################################
-# Extension to allow automatically downloading the maven-wrapper.jar from Maven-central
-# This allows using the maven wrapper in projects that prohibit checking in binary data.
-##########################################################################################
-if [ -r "$BASE_DIR/.mvn/wrapper/maven-wrapper.jar" ]; then
- if [ "$MVNW_VERBOSE" = true ]; then
- echo "Found .mvn/wrapper/maven-wrapper.jar"
- fi
+# unzip and move
+if command -v unzip >/dev/null; then
+ unzip ${__MVNW_QUIET_UNZIP:+"$__MVNW_QUIET_UNZIP"} "$TMP_DOWNLOAD_DIR/$distributionUrlName" -d "$TMP_DOWNLOAD_DIR" || die "failed to unzip"
else
- if [ "$MVNW_VERBOSE" = true ]; then
- echo "Couldn't find .mvn/wrapper/maven-wrapper.jar, downloading it ..."
- fi
- if [ -n "$MVNW_REPOURL" ]; then
- jarUrl="$MVNW_REPOURL/org/apache/maven/wrapper/maven-wrapper/3.1.1/maven-wrapper-3.1.1.jar"
- else
- jarUrl="https://repo.maven.apache.org/maven2/org/apache/maven/wrapper/maven-wrapper/3.1.1/maven-wrapper-3.1.1.jar"
- fi
- while IFS="=" read key value; do
- case "$key" in (wrapperUrl) jarUrl="$value"; break ;;
- esac
- done < "$BASE_DIR/.mvn/wrapper/maven-wrapper.properties"
- if [ "$MVNW_VERBOSE" = true ]; then
- echo "Downloading from: $jarUrl"
- fi
- wrapperJarPath="$BASE_DIR/.mvn/wrapper/maven-wrapper.jar"
- if $cygwin; then
- wrapperJarPath=`cygpath --path --windows "$wrapperJarPath"`
- fi
-
- if command -v wget > /dev/null; then
- if [ "$MVNW_VERBOSE" = true ]; then
- echo "Found wget ... using wget"
- fi
- if [ -z "$MVNW_USERNAME" ] || [ -z "$MVNW_PASSWORD" ]; then
- wget "$jarUrl" -O "$wrapperJarPath" || rm -f "$wrapperJarPath"
- else
- wget --http-user=$MVNW_USERNAME --http-password=$MVNW_PASSWORD "$jarUrl" -O "$wrapperJarPath" || rm -f "$wrapperJarPath"
- fi
- elif command -v curl > /dev/null; then
- if [ "$MVNW_VERBOSE" = true ]; then
- echo "Found curl ... using curl"
- fi
- if [ -z "$MVNW_USERNAME" ] || [ -z "$MVNW_PASSWORD" ]; then
- curl -o "$wrapperJarPath" "$jarUrl" -f
- else
- curl --user $MVNW_USERNAME:$MVNW_PASSWORD -o "$wrapperJarPath" "$jarUrl" -f
- fi
-
- else
- if [ "$MVNW_VERBOSE" = true ]; then
- echo "Falling back to using Java to download"
- fi
- javaClass="$BASE_DIR/.mvn/wrapper/MavenWrapperDownloader.java"
- # For Cygwin, switch paths to Windows format before running javac
- if $cygwin; then
- javaClass=`cygpath --path --windows "$javaClass"`
- fi
- if [ -e "$javaClass" ]; then
- if [ ! -e "$BASE_DIR/.mvn/wrapper/MavenWrapperDownloader.class" ]; then
- if [ "$MVNW_VERBOSE" = true ]; then
- echo " - Compiling MavenWrapperDownloader.java ..."
- fi
- # Compiling the Java class
- ("$JAVA_HOME/bin/javac" "$javaClass")
- fi
- if [ -e "$BASE_DIR/.mvn/wrapper/MavenWrapperDownloader.class" ]; then
- # Running the downloader
- if [ "$MVNW_VERBOSE" = true ]; then
- echo " - Running MavenWrapperDownloader.java ..."
- fi
- ("$JAVA_HOME/bin/java" -cp .mvn/wrapper MavenWrapperDownloader "$MAVEN_PROJECTBASEDIR")
- fi
- fi
- fi
-fi
-##########################################################################################
-# End of extension
-##########################################################################################
-
-export MAVEN_PROJECTBASEDIR=${MAVEN_BASEDIR:-"$BASE_DIR"}
-if [ "$MVNW_VERBOSE" = true ]; then
- echo $MAVEN_PROJECTBASEDIR
+ tar xzf${__MVNW_QUIET_TAR:+"$__MVNW_QUIET_TAR"} "$TMP_DOWNLOAD_DIR/$distributionUrlName" -C "$TMP_DOWNLOAD_DIR" || die "failed to untar"
fi
-MAVEN_OPTS="$(concat_lines "$MAVEN_PROJECTBASEDIR/.mvn/jvm.config") $MAVEN_OPTS"
-
-# For Cygwin, switch paths to Windows format before running java
-if $cygwin; then
- [ -n "$M2_HOME" ] &&
- M2_HOME=`cygpath --path --windows "$M2_HOME"`
- [ -n "$JAVA_HOME" ] &&
- JAVA_HOME=`cygpath --path --windows "$JAVA_HOME"`
- [ -n "$CLASSPATH" ] &&
- CLASSPATH=`cygpath --path --windows "$CLASSPATH"`
- [ -n "$MAVEN_PROJECTBASEDIR" ] &&
- MAVEN_PROJECTBASEDIR=`cygpath --path --windows "$MAVEN_PROJECTBASEDIR"`
-fi
-
-# Provide a "standardized" way to retrieve the CLI args that will
-# work with both Windows and non-Windows executions.
-MAVEN_CMD_LINE_ARGS="$MAVEN_CONFIG $@"
-export MAVEN_CMD_LINE_ARGS
-
-WRAPPER_LAUNCHER=org.apache.maven.wrapper.MavenWrapperMain
+printf %s\\n "$distributionUrl" >"$TMP_DOWNLOAD_DIR/$distributionUrlNameMain/mvnw.url"
+mv -- "$TMP_DOWNLOAD_DIR/$distributionUrlNameMain" "$MAVEN_HOME" || [ -d "$MAVEN_HOME" ] || die "fail to move MAVEN_HOME"
-exec "$JAVACMD" \
- $MAVEN_OPTS \
- $MAVEN_DEBUG_OPTS \
- -classpath "$MAVEN_PROJECTBASEDIR/.mvn/wrapper/maven-wrapper.jar" \
- "-Dmaven.home=${M2_HOME}" \
- "-Dmaven.multiModuleProjectDirectory=${MAVEN_PROJECTBASEDIR}" \
- ${WRAPPER_LAUNCHER} $MAVEN_CONFIG "$@"
+clean || :
+exec_maven "$@"
diff --git a/mvnw.cmd b/mvnw.cmd
index abb7c324..b150b91e 100644
--- a/mvnw.cmd
+++ b/mvnw.cmd
@@ -1,188 +1,149 @@
-@REM ----------------------------------------------------------------------------
-@REM Licensed to the Apache Software Foundation (ASF) under one
-@REM or more contributor license agreements. See the NOTICE file
-@REM distributed with this work for additional information
-@REM regarding copyright ownership. The ASF licenses this file
-@REM to you under the Apache License, Version 2.0 (the
-@REM "License"); you may not use this file except in compliance
-@REM with the License. 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,
-@REM software distributed under the License is distributed on an
-@REM "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-@REM KIND, either express or implied. See the License for the
-@REM specific language governing permissions and limitations
-@REM under the License.
-@REM ----------------------------------------------------------------------------
-
-@REM ----------------------------------------------------------------------------
-@REM Maven Start Up Batch script
-@REM
-@REM Required ENV vars:
-@REM JAVA_HOME - location of a JDK home dir
-@REM
-@REM Optional ENV vars
-@REM M2_HOME - location of maven2's installed home dir
-@REM MAVEN_BATCH_ECHO - set to 'on' to enable the echoing of the batch commands
-@REM MAVEN_BATCH_PAUSE - set to 'on' to wait for a keystroke before ending
-@REM MAVEN_OPTS - parameters passed to the Java VM when running Maven
-@REM e.g. to debug Maven itself, use
-@REM set MAVEN_OPTS=-Xdebug -Xrunjdwp:transport=dt_socket,server=y,suspend=y,address=8000
-@REM MAVEN_SKIP_RC - flag to disable loading of mavenrc files
-@REM ----------------------------------------------------------------------------
-
-@REM Begin all REM lines with '@' in case MAVEN_BATCH_ECHO is 'on'
-@echo off
-@REM set title of command window
-title %0
-@REM enable echoing by setting MAVEN_BATCH_ECHO to 'on'
-@if "%MAVEN_BATCH_ECHO%" == "on" echo %MAVEN_BATCH_ECHO%
-
-@REM set %HOME% to equivalent of $HOME
-if "%HOME%" == "" (set "HOME=%HOMEDRIVE%%HOMEPATH%")
-
-@REM Execute a user defined script before this one
-if not "%MAVEN_SKIP_RC%" == "" goto skipRcPre
-@REM check for pre script, once with legacy .bat ending and once with .cmd ending
-if exist "%USERPROFILE%\mavenrc_pre.bat" call "%USERPROFILE%\mavenrc_pre.bat" %*
-if exist "%USERPROFILE%\mavenrc_pre.cmd" call "%USERPROFILE%\mavenrc_pre.cmd" %*
-:skipRcPre
-
-@setlocal
-
-set ERROR_CODE=0
-
-@REM To isolate internal variables from possible post scripts, we use another setlocal
-@setlocal
-
-@REM ==== START VALIDATION ====
-if not "%JAVA_HOME%" == "" goto OkJHome
-
-echo.
-echo Error: JAVA_HOME not found in your environment. >&2
-echo Please set the JAVA_HOME variable in your environment to match the >&2
-echo location of your Java installation. >&2
-echo.
-goto error
-
-:OkJHome
-if exist "%JAVA_HOME%\bin\java.exe" goto init
-
-echo.
-echo Error: JAVA_HOME is set to an invalid directory. >&2
-echo JAVA_HOME = "%JAVA_HOME%" >&2
-echo Please set the JAVA_HOME variable in your environment to match the >&2
-echo location of your Java installation. >&2
-echo.
-goto error
-
-@REM ==== END VALIDATION ====
-
-:init
-
-@REM Find the project base dir, i.e. the directory that contains the folder ".mvn".
-@REM Fallback to current working directory if not found.
-
-set MAVEN_PROJECTBASEDIR=%MAVEN_BASEDIR%
-IF NOT "%MAVEN_PROJECTBASEDIR%"=="" goto endDetectBaseDir
-
-set EXEC_DIR=%CD%
-set WDIR=%EXEC_DIR%
-:findBaseDir
-IF EXIST "%WDIR%"\.mvn goto baseDirFound
-cd ..
-IF "%WDIR%"=="%CD%" goto baseDirNotFound
-set WDIR=%CD%
-goto findBaseDir
-
-:baseDirFound
-set MAVEN_PROJECTBASEDIR=%WDIR%
-cd "%EXEC_DIR%"
-goto endDetectBaseDir
-
-:baseDirNotFound
-set MAVEN_PROJECTBASEDIR=%EXEC_DIR%
-cd "%EXEC_DIR%"
-
-:endDetectBaseDir
-
-IF NOT EXIST "%MAVEN_PROJECTBASEDIR%\.mvn\jvm.config" goto endReadAdditionalConfig
-
-@setlocal EnableExtensions EnableDelayedExpansion
-for /F "usebackq delims=" %%a in ("%MAVEN_PROJECTBASEDIR%\.mvn\jvm.config") do set JVM_CONFIG_MAVEN_PROPS=!JVM_CONFIG_MAVEN_PROPS! %%a
-@endlocal & set JVM_CONFIG_MAVEN_PROPS=%JVM_CONFIG_MAVEN_PROPS%
-
-:endReadAdditionalConfig
-
-SET MAVEN_JAVA_EXE="%JAVA_HOME%\bin\java.exe"
-set WRAPPER_JAR="%MAVEN_PROJECTBASEDIR%\.mvn\wrapper\maven-wrapper.jar"
-set WRAPPER_LAUNCHER=org.apache.maven.wrapper.MavenWrapperMain
-
-set DOWNLOAD_URL="https://repo.maven.apache.org/maven2/org/apache/maven/wrapper/maven-wrapper/3.1.1/maven-wrapper-3.1.1.jar"
-
-FOR /F "usebackq tokens=1,2 delims==" %%A IN ("%MAVEN_PROJECTBASEDIR%\.mvn\wrapper\maven-wrapper.properties") DO (
- IF "%%A"=="wrapperUrl" SET DOWNLOAD_URL=%%B
-)
-
-@REM Extension to allow automatically downloading the maven-wrapper.jar from Maven-central
-@REM This allows using the maven wrapper in projects that prohibit checking in binary data.
-if exist %WRAPPER_JAR% (
- if "%MVNW_VERBOSE%" == "true" (
- echo Found %WRAPPER_JAR%
- )
-) else (
- if not "%MVNW_REPOURL%" == "" (
- SET DOWNLOAD_URL="%MVNW_REPOURL%/org/apache/maven/wrapper/maven-wrapper/3.1.1/maven-wrapper-3.1.1.jar"
- )
- if "%MVNW_VERBOSE%" == "true" (
- echo Couldn't find %WRAPPER_JAR%, downloading it ...
- echo Downloading from: %DOWNLOAD_URL%
- )
-
- powershell -Command "&{"^
- "$webclient = new-object System.Net.WebClient;"^
- "if (-not ([string]::IsNullOrEmpty('%MVNW_USERNAME%') -and [string]::IsNullOrEmpty('%MVNW_PASSWORD%'))) {"^
- "$webclient.Credentials = new-object System.Net.NetworkCredential('%MVNW_USERNAME%', '%MVNW_PASSWORD%');"^
- "}"^
- "[Net.ServicePointManager]::SecurityProtocol = [Net.SecurityProtocolType]::Tls12; $webclient.DownloadFile('%DOWNLOAD_URL%', '%WRAPPER_JAR%')"^
- "}"
- if "%MVNW_VERBOSE%" == "true" (
- echo Finished downloading %WRAPPER_JAR%
- )
-)
-@REM End of extension
-
-@REM Provide a "standardized" way to retrieve the CLI args that will
-@REM work with both Windows and non-Windows executions.
-set MAVEN_CMD_LINE_ARGS=%*
-
-%MAVEN_JAVA_EXE% ^
- %JVM_CONFIG_MAVEN_PROPS% ^
- %MAVEN_OPTS% ^
- %MAVEN_DEBUG_OPTS% ^
- -classpath %WRAPPER_JAR% ^
- "-Dmaven.multiModuleProjectDirectory=%MAVEN_PROJECTBASEDIR%" ^
- %WRAPPER_LAUNCHER% %MAVEN_CONFIG% %*
-if ERRORLEVEL 1 goto error
-goto end
-
-:error
-set ERROR_CODE=1
-
-:end
-@endlocal & set ERROR_CODE=%ERROR_CODE%
-
-if not "%MAVEN_SKIP_RC%"=="" goto skipRcPost
-@REM check for post script, once with legacy .bat ending and once with .cmd ending
-if exist "%USERPROFILE%\mavenrc_post.bat" call "%USERPROFILE%\mavenrc_post.bat"
-if exist "%USERPROFILE%\mavenrc_post.cmd" call "%USERPROFILE%\mavenrc_post.cmd"
-:skipRcPost
-
-@REM pause the script if MAVEN_BATCH_PAUSE is set to 'on'
-if "%MAVEN_BATCH_PAUSE%"=="on" pause
-
-if "%MAVEN_TERMINATE_CMD%"=="on" exit %ERROR_CODE%
-
-cmd /C exit /B %ERROR_CODE%
+<# : batch portion
+@REM ----------------------------------------------------------------------------
+@REM Licensed to the Apache Software Foundation (ASF) under one
+@REM or more contributor license agreements. See the NOTICE file
+@REM distributed with this work for additional information
+@REM regarding copyright ownership. The ASF licenses this file
+@REM to you under the Apache License, Version 2.0 (the
+@REM "License"); you may not use this file except in compliance
+@REM with the License. You may obtain a copy of the License at
+@REM
+@REM http://www.apache.org/licenses/LICENSE-2.0
+@REM
+@REM Unless required by applicable law or agreed to in writing,
+@REM software distributed under the License is distributed on an
+@REM "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+@REM KIND, either express or implied. See the License for the
+@REM specific language governing permissions and limitations
+@REM under the License.
+@REM ----------------------------------------------------------------------------
+
+@REM ----------------------------------------------------------------------------
+@REM Apache Maven Wrapper startup batch script, version 3.3.2
+@REM
+@REM Optional ENV vars
+@REM MVNW_REPOURL - repo url base for downloading maven distribution
+@REM MVNW_USERNAME/MVNW_PASSWORD - user and password for downloading maven
+@REM MVNW_VERBOSE - true: enable verbose log; others: silence the output
+@REM ----------------------------------------------------------------------------
+
+@IF "%__MVNW_ARG0_NAME__%"=="" (SET __MVNW_ARG0_NAME__=%~nx0)
+@SET __MVNW_CMD__=
+@SET __MVNW_ERROR__=
+@SET __MVNW_PSMODULEP_SAVE=%PSModulePath%
+@SET PSModulePath=
+@FOR /F "usebackq tokens=1* delims==" %%A IN (`powershell -noprofile "& {$scriptDir='%~dp0'; $script='%__MVNW_ARG0_NAME__%'; icm -ScriptBlock ([Scriptblock]::Create((Get-Content -Raw '%~f0'))) -NoNewScope}"`) DO @(
+ IF "%%A"=="MVN_CMD" (set __MVNW_CMD__=%%B) ELSE IF "%%B"=="" (echo %%A) ELSE (echo %%A=%%B)
+)
+@SET PSModulePath=%__MVNW_PSMODULEP_SAVE%
+@SET __MVNW_PSMODULEP_SAVE=
+@SET __MVNW_ARG0_NAME__=
+@SET MVNW_USERNAME=
+@SET MVNW_PASSWORD=
+@IF NOT "%__MVNW_CMD__%"=="" (%__MVNW_CMD__% %*)
+@echo Cannot start maven from wrapper >&2 && exit /b 1
+@GOTO :EOF
+: end batch / begin powershell #>
+
+$ErrorActionPreference = "Stop"
+if ($env:MVNW_VERBOSE -eq "true") {
+ $VerbosePreference = "Continue"
+}
+
+# calculate distributionUrl, requires .mvn/wrapper/maven-wrapper.properties
+$distributionUrl = (Get-Content -Raw "$scriptDir/.mvn/wrapper/maven-wrapper.properties" | ConvertFrom-StringData).distributionUrl
+if (!$distributionUrl) {
+ Write-Error "cannot read distributionUrl property in $scriptDir/.mvn/wrapper/maven-wrapper.properties"
+}
+
+switch -wildcard -casesensitive ( $($distributionUrl -replace '^.*/','') ) {
+ "maven-mvnd-*" {
+ $USE_MVND = $true
+ $distributionUrl = $distributionUrl -replace '-bin\.[^.]*$',"-windows-amd64.zip"
+ $MVN_CMD = "mvnd.cmd"
+ break
+ }
+ default {
+ $USE_MVND = $false
+ $MVN_CMD = $script -replace '^mvnw','mvn'
+ break
+ }
+}
+
+# apply MVNW_REPOURL and calculate MAVEN_HOME
+# maven home pattern: ~/.m2/wrapper/dists/{apache-maven-,maven-mvnd--}/
+if ($env:MVNW_REPOURL) {
+ $MVNW_REPO_PATTERN = if ($USE_MVND) { "/org/apache/maven/" } else { "/maven/mvnd/" }
+ $distributionUrl = "$env:MVNW_REPOURL$MVNW_REPO_PATTERN$($distributionUrl -replace '^.*'+$MVNW_REPO_PATTERN,'')"
+}
+$distributionUrlName = $distributionUrl -replace '^.*/',''
+$distributionUrlNameMain = $distributionUrlName -replace '\.[^.]*$','' -replace '-bin$',''
+$MAVEN_HOME_PARENT = "$HOME/.m2/wrapper/dists/$distributionUrlNameMain"
+if ($env:MAVEN_USER_HOME) {
+ $MAVEN_HOME_PARENT = "$env:MAVEN_USER_HOME/wrapper/dists/$distributionUrlNameMain"
+}
+$MAVEN_HOME_NAME = ([System.Security.Cryptography.MD5]::Create().ComputeHash([byte[]][char[]]$distributionUrl) | ForEach-Object {$_.ToString("x2")}) -join ''
+$MAVEN_HOME = "$MAVEN_HOME_PARENT/$MAVEN_HOME_NAME"
+
+if (Test-Path -Path "$MAVEN_HOME" -PathType Container) {
+ Write-Verbose "found existing MAVEN_HOME at $MAVEN_HOME"
+ Write-Output "MVN_CMD=$MAVEN_HOME/bin/$MVN_CMD"
+ exit $?
+}
+
+if (! $distributionUrlNameMain -or ($distributionUrlName -eq $distributionUrlNameMain)) {
+ Write-Error "distributionUrl is not valid, must end with *-bin.zip, but found $distributionUrl"
+}
+
+# prepare tmp dir
+$TMP_DOWNLOAD_DIR_HOLDER = New-TemporaryFile
+$TMP_DOWNLOAD_DIR = New-Item -Itemtype Directory -Path "$TMP_DOWNLOAD_DIR_HOLDER.dir"
+$TMP_DOWNLOAD_DIR_HOLDER.Delete() | Out-Null
+trap {
+ if ($TMP_DOWNLOAD_DIR.Exists) {
+ try { Remove-Item $TMP_DOWNLOAD_DIR -Recurse -Force | Out-Null }
+ catch { Write-Warning "Cannot remove $TMP_DOWNLOAD_DIR" }
+ }
+}
+
+New-Item -Itemtype Directory -Path "$MAVEN_HOME_PARENT" -Force | Out-Null
+
+# Download and Install Apache Maven
+Write-Verbose "Couldn't find MAVEN_HOME, downloading and installing it ..."
+Write-Verbose "Downloading from: $distributionUrl"
+Write-Verbose "Downloading to: $TMP_DOWNLOAD_DIR/$distributionUrlName"
+
+$webclient = New-Object System.Net.WebClient
+if ($env:MVNW_USERNAME -and $env:MVNW_PASSWORD) {
+ $webclient.Credentials = New-Object System.Net.NetworkCredential($env:MVNW_USERNAME, $env:MVNW_PASSWORD)
+}
+[Net.ServicePointManager]::SecurityProtocol = [Net.SecurityProtocolType]::Tls12
+$webclient.DownloadFile($distributionUrl, "$TMP_DOWNLOAD_DIR/$distributionUrlName") | Out-Null
+
+# If specified, validate the SHA-256 sum of the Maven distribution zip file
+$distributionSha256Sum = (Get-Content -Raw "$scriptDir/.mvn/wrapper/maven-wrapper.properties" | ConvertFrom-StringData).distributionSha256Sum
+if ($distributionSha256Sum) {
+ if ($USE_MVND) {
+ Write-Error "Checksum validation is not supported for maven-mvnd. `nPlease disable validation by removing 'distributionSha256Sum' from your maven-wrapper.properties."
+ }
+ Import-Module $PSHOME\Modules\Microsoft.PowerShell.Utility -Function Get-FileHash
+ if ((Get-FileHash "$TMP_DOWNLOAD_DIR/$distributionUrlName" -Algorithm SHA256).Hash.ToLower() -ne $distributionSha256Sum) {
+ Write-Error "Error: Failed to validate Maven distribution SHA-256, your Maven distribution might be compromised. If you updated your Maven version, you need to update the specified distributionSha256Sum property."
+ }
+}
+
+# unzip and move
+Expand-Archive "$TMP_DOWNLOAD_DIR/$distributionUrlName" -DestinationPath "$TMP_DOWNLOAD_DIR" | Out-Null
+Rename-Item -Path "$TMP_DOWNLOAD_DIR/$distributionUrlNameMain" -NewName $MAVEN_HOME_NAME | Out-Null
+try {
+ Move-Item -Path "$TMP_DOWNLOAD_DIR/$MAVEN_HOME_NAME" -Destination $MAVEN_HOME_PARENT | Out-Null
+} catch {
+ if (! (Test-Path -Path "$MAVEN_HOME" -PathType Container)) {
+ Write-Error "fail to move MAVEN_HOME"
+ }
+} finally {
+ try { Remove-Item $TMP_DOWNLOAD_DIR -Recurse -Force | Out-Null }
+ catch { Write-Warning "Cannot remove $TMP_DOWNLOAD_DIR" }
+}
+
+Write-Output "MVN_CMD=$MAVEN_HOME/bin/$MVN_CMD"
diff --git a/pom.xml b/pom.xml
index b4d11984..dfe947f8 100644
--- a/pom.xml
+++ b/pom.xml
@@ -1,8 +1,5 @@
-
-
+
+
4.0.0
@@ -148,6 +145,10 @@
quarkus-mongodb-panache
+
+ io.quarkus
+ quarkus-smallrye-health
+
io.quarkus
quarkus-junit5
@@ -168,12 +169,12 @@
assertj-core
${assertj-core.version}
test
+
io.quarkus
quarkus-junit5-mockito
test
-
org.mockito
@@ -186,24 +187,24 @@
quarkus-jacoco
test
+
+
com.atlassian.oai
swagger-request-validator-restassured
${swagger-request-validator.version}
test
-
-
+
io.quarkus
quarkus-logging-json
-
+
io.quarkus
quarkus-opentelemetry
-
io.quarkiverse.opentelemetry.exporter
quarkus-opentelemetry-exporter-azure
@@ -269,8 +270,7 @@
${surefire-plugin.version}
-
- org.jboss.logmanager.LogManager
+ org.jboss.logmanager.LogManager
${maven.home}
@@ -286,10 +286,8 @@
-
- ${project.build.directory}/${project.build.finalName}-runner
-
- org.jboss.logmanager.LogManager
+ ${project.build.directory}/${project.build.finalName}-runner
+ org.jboss.logmanager.LogManager
${maven.home}
@@ -327,8 +325,7 @@
test
-
- ${project.build.directory}/jacoco-quarkus.exec
+ ${project.build.directory}/jacoco-quarkus.exec
CLASS
diff --git a/src/main/docker/Dockerfile.multistage b/src/main/docker/Dockerfile.multistage
index e4079881..13d51176 100644
--- a/src/main/docker/Dockerfile.multistage
+++ b/src/main/docker/Dockerfile.multistage
@@ -13,24 +13,17 @@ USER quarkus
WORKDIR /code
RUN \
- --mount=type=secret,id=gh_user,uid=1001 \
- --mount=type=secret,id=gh_token,uid=1001 \
- export GH_USER=$(cat /run/secrets/gh_user) && \
- export GH_TOKEN=$(cat /run/secrets/gh_token) && \
- echo "github$GH_USER$GH_TOKENgithub-mil-azure-services$GH_USER$GH_TOKEN" >> settings.xml
+ --mount=type=secret,id=gh_token,uid=1001 \
+ export GH_TOKEN=$(cat /run/secrets/gh_token) && \
+ echo "github$GH_TOKEN" >> settings.xml
COPY src /code/src
-RUN ./mvnw package -Pnative -Dmaven.test.skip=true -s settings.xml
-
-
-
+RUN ./mvnw package -Dnative -Dmaven.test.skip=true -s settings.xml
## Stage 2 : create the docker final image
FROM quay.io/quarkus/quarkus-micro-image:2.0@sha256:ad4ebd25d024c6377d9497fb094a9acb22080f2b11396994e129f24e7d1b3b35
-
WORKDIR /work/
-
COPY --from=build /code/target/*-runner /work/application
# set up permissions for user `1001`
@@ -40,7 +33,6 @@ RUN chmod 775 /work /work/application \
&& chown -R 1001:root /work
EXPOSE 8080
-
USER 1001
CMD ["./application", "-Dquarkus.http.host=0.0.0.0"]
\ No newline at end of file
diff --git a/src/main/docker/Dockerfile.native-micro b/src/main/docker/Dockerfile.native-micro
deleted file mode 100644
index df1619cc..00000000
--- a/src/main/docker/Dockerfile.native-micro
+++ /dev/null
@@ -1,11 +0,0 @@
-FROM quay.io/quarkus/quarkus-micro-image@sha256:a9182e3618935ab7decb6ec0a7cdd2dd60288ea4a61e0c08c8c486fff42696e8
-WORKDIR /work/
-RUN chown 1001 /work \
- && chmod "g+rwX" /work \
- && chown 1001:root /work
-COPY --chown=1001:root target/*-runner /work/application
-
-EXPOSE 8080
-USER 1001
-
-CMD ["./application", "-Dquarkus.http.host=0.0.0.0"]
diff --git a/src/main/docker/README.md b/src/main/docker/README.md
index 8fc8ab73..d8a60a95 100644
--- a/src/main/docker/README.md
+++ b/src/main/docker/README.md
@@ -1,3 +1,5 @@
```shell
-sudo docker build --no-cache --progress=plain --secret id=gh_user,src=GH_USER.txt --secret id=gh_token,src=GH_TOKEN.txt -f src/main/docker/Dockerfile.multistage -t ghcr.io/pagopa/mil-auth:latest .
+export GH_USER=
+echo >> GH_TOKEN.txt
+sudo docker build --no-cache --progress=plain --build-arg GH_USER=$GH_USER --secret id=gh_token,src=GH_TOKEN.txt -f src/main/docker/Dockerfile.multistage -t ghcr.io/pagopa/mil-auth:latest .
```
\ No newline at end of file
diff --git a/src/main/resources/application.properties b/src/main/resources/application.properties
index 13b168eb..fbdb8e37 100644
--- a/src/main/resources/application.properties
+++ b/src/main/resources/application.properties
@@ -1,9 +1,11 @@
base-url=http://dummy
-%prod.base-url=${auth.base-url}
+%prod.base-url=${MIL_AUTH_URL}
# ------------------------------------------------------------------------------
# Logging configuration
# ------------------------------------------------------------------------------
+
+
quarkus.banner.enabled=false
quarkus.log.console.format=%d{yyyy-MM-dd HH:mm:ss.SSS} [%X{requestId}] [%p] [%c{2}] %m%n
quarkus.log.console.json=false
@@ -11,8 +13,8 @@ quarkus.rest-client.logging.body-limit=-1
quarkus.log.min-level=TRACE
quarkus.log.category."it.pagopa.swclient.mil".min-level=TRACE
quarkus.log.category."org.jboss.resteasy.reactive.client.logging".level=DEBUG
-quarkus.log.category."io.quarkus.smallrye.jwt.runtime.auth.MpJwtValidator".level=${auth.jwt-validator-log:ERROR}
-quarkus.log.category."io.quarkus.smallrye.jwt.runtime.auth.MpJwtValidator".min-level=${auth.jwt-validator-log:ERROR}
+quarkus.log.category."io.quarkus.smallrye.jwt.runtime.auth.MpJwtValidator".level=${JWT_VALIDATIOR_LOG:ERROR}
+quarkus.log.category."io.quarkus.smallrye.jwt.runtime.auth.MpJwtValidator".min-level=${JWT_VALIDATIOR_LOG:ERROR}
%dev.quarkus.log.level=INFO
%dev.quarkus.log.category."it.pagopa.swclient.mil".level=DEBUG
@@ -22,26 +24,33 @@ quarkus.log.category."io.quarkus.smallrye.jwt.runtime.auth.MpJwtValidator".min-l
%test.quarkus.log.category."it.pagopa.swclient.mil".level=TRACE
%test.quarkus.rest-client.logging.scope=none
-%prod.quarkus.log.console.json=${auth.json-log:true}
-%prod.quarkus.log.level=${auth.quarkus-log-level}
-%prod.quarkus.log.category."it.pagopa.swclient.mil".level=${auth.app-log-level}
-%prod.quarkus.rest-client.logging.scope=${auth.quarkus-rest-client-logging-scope}
+%test_wo_azure_access_tokens_cache.quarkus.log.level=ERROR
+%test_wo_azure_access_tokens_cache.quarkus.log.category."it.pagopa.swclient.mil.auth".level=DEBUG
+%test_wo_azure_access_tokens_cache.quarkus.rest-client.logging.scope=none
+
+%prod.quarkus.log.level=${QUARKUS_LOG_LEVEL}
+%prod.quarkus.rest-client.logging.scope=${QUARKUS_REST_CLIENT_LOGGING_SCOPE}
+%prod.quarkus.log.console.json=${QUARKUS_LOG_CONSOLE_JSON:true}
+
+%prod.quarkus.log.category."it.pagopa.swclient.mil".level=${APP_LOG_LEVEL}
+
# ------------------------------------------------------------------------------
# Cryptoperiod of RSA keys in seconds (86400s = 1d)
# ------------------------------------------------------------------------------
-cryptoperiod=${auth.cryptoperiod:43200}
+cryptoperiod=${CRYPTOPERIOD:43200}
# ------------------------------------------------------------------------------
# Key size (modulus) of RSA keys in bits
# ------------------------------------------------------------------------------
-keysize=${auth.keysize:2048}
+
+keysize=${KEYSIZE:2048}
# ------------------------------------------------------------------------------
# Token configuration
# ------------------------------------------------------------------------------
-access.duration=${auth.access.duration:300}
-refresh.duration=${auth.refresh.duration:3600}
+access.duration=${ACCESS_DURATION:300}
+refresh.duration=${REFRESH_DURATION:3600}
# ------------------------------------------------------------------------------
# Poynt integration
@@ -52,18 +61,18 @@ poynt-api.version=1.2
# ------------------------------------------------------------------------------
# Authorization data repository (users) : used by mil-azure-services
# ------------------------------------------------------------------------------
-azure-storage-blob.version=2019-07-07
-quarkus.rest-client.azure-storage-blob.url=https://mildconfst.blob.core.windows.net
-%prod.quarkus.rest-client.azure-storage-blob.url=${auth.data.url}
+quarkus.rest-client.auth-data-repository.url=https://mildconfst.blob.core.windows.net
+azure-storage-api.version=2019-07-07
+%prod.quarkus.rest-client.auth-data-repository.url=${DATA_URL}
# ------------------------------------------------------------------------------
# MongoDB client configuration (clients, roles)
# ------------------------------------------------------------------------------
-quarkus.mongodb.connect-timeout=${mongodb.connect-timeout:5}
-quarkus.mongodb.read-timeout=${mongodb.read-timeout:10}
-quarkus.mongodb.server-selection-timeout=${mongodb.server-selection-timeout:5}
+quarkus.mongodb.connect-timeout=${MONGO_CONNECT_TIMEOUT:5}
+quarkus.mongodb.read-timeout=${MONGO_READ_TIMEOUT:10}
+quarkus.mongodb.server-selection-timeout=${MONGO_SERVER_SELECTION_TIMEOUT:5}
quarkus.mongodb.connection-string = mongodb://localhost:27017
-%prod.quarkus.mongodb.connection-string=${mongodb.connection-string-1},${mongodb.connection-string-2}
+%prod.quarkus.mongodb.connection-string=${MONGODB_URI}
# ------------------------------------------------------------------------------
# TTL for the authorization data cache
@@ -75,18 +84,21 @@ quarkus.cache.caffeine.expire-after-write=1h
# Azure Key Vault API : used by mil-azure-services
# ------------------------------------------------------------------------------
azure-key-vault-keys.api-version=7.4
-azure-key-vault-keys.get-keys.maxresults=${auth.keyvault.maxresults:999}
-azure-key-vault-keys.get-key-version.maxresults=${auth.keyvault.maxresults:999}
-azure-key-vault-keys.backoff.initial-duration=${auth.keyvault.backoff.initial-duration:1}
-azure-key-vault-keys.backoff.jitter=${auth.keyvault.backoff.jitter:0.2}
-azure-key-vault-keys.backoff.number-of-attempts=${auth.keyvault.backoff.number-of-attempts:3}
+azure-key-vault-keys.get-keys.maxresults=${KV_MAXRESULT:999}
+azure-key-vault-keys.get-key-version.maxresults=${KV_MAXRESULT:999}
+azure-key-vault-keys.backoff.initial-duration=${KV_BACKOFF_INITIAL_DURATION:1}
+azure-key-vault-keys.backoff.jitter=${KV_BACKOFF_INITIAL_JITTER:0.2}
+azure-key-vault-keys.backoff.number-of-attempts=${KV_BACKOFF_INITIAL_NUMBER_OF_ATTEMPTS:3}
quarkus.rest-client.azure-key-vault-keys.url=http://dummy
-%prod.quarkus.rest-client.azure-key-vault-keys.url=${auth.keyvault.url}
+%prod.quarkus.rest-client.azure-key-vault-keys.url=${KV_URL}
# ------------------------------------------------------------------------------
# TTL for the key ID cache
# ------------------------------------------------------------------------------
+azure-key-vault-api.version=7.4
+quarkus.rest-client.azure-key-vault-api.url=http://dummy
+
keyid-cache.expire-after-write=3600
# ------------------------------------------------------------------------------
@@ -95,8 +107,8 @@ keyid-cache.expire-after-write=3600
quarkus.opentelemetry.tracer.exporter.azure.enabled=false
quarkus.otel.azure.applicationinsights.connection.string=InstrumentationKey=dummy;IngestionEndpoint=https://dummy/;LiveEndpoint=https://dummy/;ApplicationId=dummy
-%prod.quarkus.opentelemetry.tracer.exporter.azure.enabled=true
-%prod.quarkus.otel.azure.applicationinsights.connection.string=${application-insights.connection-string}
+%prod.quarkus.opentelemetry.tracer.exporter.azure.enabled=${OTEL_TRACER_EXPORTER_ENABLED:true}
+%prod.quarkus.otel.azure.applicationinsights.connection.string=${APPLICATIONINSIGHTS_CONNECTION_STRING}
# ------------------------------------------------------------------------------
# Location to retrieve public keys to verify access token when /token_info
@@ -104,4 +116,4 @@ quarkus.otel.azure.applicationinsights.connection.string=InstrumentationKey=dumm
# ------------------------------------------------------------------------------
quarkus.smallrye-jwt.blocking-authentication=true
%dev.mp.jwt.verify.publickey.location=http://dummy
-%prod.mp.jwt.verify.publickey.location=${jwt-publickey-location}
\ No newline at end of file
+%prod.mp.jwt.verify.publickey.location=${JWT_PUBLICKEY_LOCATION}