├── .github
└── workflows
│ ├── build-and-deploy-image.yml
│ ├── ci.yml
│ ├── cloud-config-versions.yml
│ ├── codeql.yml
│ ├── create-sha-docker-tag.yml
│ ├── deploy.yml
│ ├── generate-docker-tags.yml
│ ├── generate-jvm-tag.yml
│ └── release.yml
├── .gitignore
├── LICENSE
├── README.md
├── build.gradle.kts
├── examples
├── aws
│ ├── paramstore
│ │ ├── compose.yml
│ │ ├── config
│ │ │ └── application.yml
│ │ └── populate-paramstore.sh
│ ├── s3
│ │ ├── application.yml
│ │ ├── compose.yml
│ │ ├── config
│ │ │ ├── foo-db.yml
│ │ │ ├── foo-dev.yml
│ │ │ ├── foo-development-db.yml
│ │ │ ├── foo-development.yml
│ │ │ └── foo.yml
│ │ └── populate-s3.sh
│ └── secretsmanager
│ │ ├── application.yml
│ │ ├── compose.yml
│ │ └── populate-secretsmanager.sh
├── cloud-bus
│ ├── kafka
│ │ ├── compose.yml
│ │ └── config
│ │ │ └── application.yml
│ └── rabbit
│ │ ├── compose.yml
│ │ └── config
│ │ └── application.yml
├── git
│ ├── compose.yml
│ └── config
│ │ └── application.yml
├── healthcheck
│ └── compose.yml
├── jdbc
│ ├── mariadb
│ │ ├── compose.yml
│ │ ├── config
│ │ │ └── application.yml
│ │ └── init-db.sql
│ └── postgres
│ │ ├── compose.yml
│ │ ├── config
│ │ └── application.yml
│ │ └── init-db.sql
├── native
│ ├── compose.yml
│ ├── config
│ │ └── application.yml
│ └── native-files
│ │ ├── aggregating.yml
│ │ ├── application-dev.yml
│ │ ├── application.yaml
│ │ ├── application.yml
│ │ ├── bar.properties
│ │ ├── books.xml
│ │ ├── configserver.yml
│ │ ├── eureka.yml
│ │ ├── foo-db.properties
│ │ ├── foo-dev.yml
│ │ ├── foo-development-db.properties
│ │ ├── foo-development.properties
│ │ ├── foo.properties
│ │ ├── logtest.yml
│ │ ├── processor.yml
│ │ ├── samplebackendservice-development.properties
│ │ ├── samplebackendservice.properties
│ │ ├── samplefrontendservice.properties
│ │ ├── stores.yml
│ │ ├── subdir
│ │ └── test.txt
│ │ ├── test.json
│ │ ├── text-resource.txt
│ │ └── zuul.properties
├── prometheus
│ ├── compose.yml
│ └── config
│ │ └── application.yml
├── redis
│ ├── compose.yml
│ ├── config
│ │ └── application.yml
│ └── populate-redis.sh
├── security
│ ├── compose.yml
│ └── config
│ │ └── application.yml
└── vault
│ ├── compose.yml
│ ├── config
│ └── application.yml
│ └── populate-vault.sh
├── gradle.properties
├── gradle
├── libs.versions.toml
└── wrapper
│ ├── gradle-wrapper.jar
│ └── gradle-wrapper.properties
├── gradlew
├── gradlew.bat
├── project.toml
└── src
├── main
├── kotlin
│ └── org
│ │ └── freshlegacycode
│ │ └── cloud
│ │ └── config
│ │ └── server
│ │ └── ConfigServerApplication.kt
└── resources
│ └── application.yaml
└── test
├── kotlin
└── org
│ └── freshlegacycode
│ └── cloud
│ └── config
│ └── server
│ ├── AwsParamStoreBackendTest.kt
│ ├── AwsS3BackendTest.kt
│ ├── AwsSecretsManagerBackendTest.kt
│ ├── CloudBusKafkaRemoteGitBackendTest.kt
│ ├── CloudBusRabbitRemoteGitBackendTest.kt
│ ├── ConfigServerApplicationTests.kt
│ ├── FileSystemBackendTest.kt
│ ├── JdbcBackendMariaDbTest.kt
│ ├── JdbcBackendPostgresTest.kt
│ ├── JdbcBackendTest.kt
│ ├── PrometheusActuatorTest.kt
│ ├── RedisBackendTest.kt
│ ├── RemoteGitRepoBackendTest.kt
│ ├── SecurityEncryptTest.kt
│ └── VaultBackendTest.kt
└── resources
└── junit-platform.properties
/.github/workflows/build-and-deploy-image.yml:
--------------------------------------------------------------------------------
1 | name: Build and deploy OCI image to registry
2 |
3 | on:
4 | workflow_call:
5 | inputs:
6 | image-jvm-type:
7 | description: JVM type for output image
8 | type: string
9 | default: jre
10 | image-jvm-version:
11 | description: JVM version for output image
12 | type: string
13 | default: 17
14 | image-name:
15 | description: The output image name
16 | type: string
17 | required: true
18 | java-build-distribution:
19 | description: Java distribution to use for build
20 | type: string
21 | default: temurin
22 | java-build-version:
23 | description: Java version to build with
24 | type: string
25 | default: 17
26 | registry:
27 | description: The registry to deploy to
28 | type: string
29 | required: true
30 | tags:
31 | description: Comma separated list of docker tags to create
32 | type: string
33 |
34 | jobs:
35 | generate-jvm-tag:
36 | uses: ./.github/workflows/generate-jvm-tag.yml
37 | with:
38 | jvm-type: ${{ inputs.jvm-type }}
39 | jvm-version: ${{ inputs.jvm-version }}
40 |
41 | build-and-push:
42 | name: Build and deploy Java ${{ needs.generate-jvm-tag.outputs.jvm-tag }} OCI image to registry
43 | needs: generate-jvm-tag
44 | runs-on: ubuntu-latest
45 | steps:
46 | - name: Checkout
47 | uses: actions/checkout@v4
48 |
49 | - name: Set up JDK ${{ inputs.java-build-version }}
50 | uses: actions/setup-java@v4
51 | with:
52 | distribution: ${{ inputs.java-build-distribution }}
53 | java-version: ${{ inputs.java-build-version }}
54 |
55 | - name: Setup Gradle
56 | uses: gradle/actions/setup-gradle@v3
57 |
58 | - name: Add tags environment variable
59 | if: inputs.tags != ''
60 | run: echo "TAGS=-PdockerTags=${{ inputs.tags }}" >> $GITHUB_ENV
61 |
62 | - name: Setup Docker Hub credentials
63 | if: inputs.registry == 'docker.io'
64 | run: |
65 | echo "DOCKER_USERNAME=${{ secrets.DOCKERHUB_USERNAME }}" >> $GITHUB_ENV
66 | echo "DOCKER_PASSWORD=${{ secrets.DOCKERHUB_TOKEN }}" >> $GITHUB_ENV
67 |
68 | - name: Setup GitHub Container Registry credentials
69 | if: inputs.registry == 'ghcr.io'
70 | run: |
71 | echo "DOCKER_USERNAME=${{ github.actor }}" >> $GITHUB_ENV
72 | echo "DOCKER_PASSWORD=${{ secrets.GITHUB_TOKEN }}" >> $GITHUB_ENV
73 |
74 | - name: Build and deploy OCI image
75 | run: >
76 | ./gradlew bootBuildImage
77 | -PjvmType=${{ inputs.image-jvm-type }}
78 | -PjdkVersion=${{ inputs.image-jvm-version }}
79 | -PdockerUsername=${{ env.DOCKER_USERNAME }}
80 | -PdockerPassword=${{ env.DOCKER_PASSWORD }}
81 | $TAGS
82 | --imageName=${{ inputs.registry }}/${{ inputs.image-name }}
83 | --publishImage
84 |
--------------------------------------------------------------------------------
/.github/workflows/ci.yml:
--------------------------------------------------------------------------------
1 | name: Build and test
2 |
3 | on:
4 | pull_request:
5 | workflow_dispatch:
6 |
7 | env:
8 | DISTRIBUTION: temurin
9 | JVM_TYPE: jre
10 | JVM_VERSION: 17
11 | REGISTRY: ghcr.io
12 |
13 | jobs:
14 | build-vars:
15 | name: Create build variables
16 | runs-on: ubuntu-latest
17 | outputs:
18 | distribution: ${{ steps.build-vars.outputs.distribution }}
19 | jvm-type: ${{ steps.build-vars.outputs.jvm-type }}
20 | jvm-version: ${{ steps.build-vars.outputs.jvm-version }}
21 | registry: ${{ steps.build-vars.outputs.registry }}
22 | steps:
23 | - id: build-vars
24 | name: Create build variables
25 | run: |
26 | echo "distribution=$DISTRIBUTION" >> $GITHUB_OUTPUT
27 | echo "jvm-type=$JVM_TYPE" >> $GITHUB_OUTPUT
28 | echo "jvm-version=$JVM_VERSION" >> $GITHUB_OUTPUT
29 | echo "registry=$REGISTRY" >> $GITHUB_OUTPUT
30 |
31 | sha-tag:
32 | name: Create sha docker tag
33 | uses: ./.github/workflows/create-sha-docker-tag.yml
34 | needs: build-vars
35 | with:
36 | jvm-type: ${{ needs.build-vars.outputs.jvm-type }}
37 | jvm-version: ${{ needs.build-vars.outputs.jvm-version }}
38 |
39 | build-and-deploy:
40 | name: Build and deploy OCI image
41 | uses: ./.github/workflows/build-and-deploy-image.yml
42 | needs:
43 | - build-vars
44 | - sha-tag
45 | with:
46 | image-name: ${{ github.repository }}:${{ needs.sha-tag.outputs.tag }}
47 | registry: ${{ needs.build-vars.outputs.registry }}
48 |
49 | integration-test:
50 | name: Verify OCI image with ${{ matrix.backend }}
51 | needs:
52 | - build-vars
53 | - build-and-deploy
54 | - sha-tag
55 | runs-on: ubuntu-latest
56 | strategy:
57 | fail-fast: false
58 | matrix:
59 | backend: [
60 | aws-param-store,
61 | aws-s3,
62 | aws-secrets-manager,
63 | cloud-bus-kafka,
64 | cloud-bus-rabbitmq,
65 | git,
66 | mariadb,
67 | native,
68 | postgres,
69 | prometheus,
70 | redis,
71 | security,
72 | vault
73 | ]
74 | steps:
75 | - name: Checkout
76 | uses: actions/checkout@v4
77 |
78 | - name: Set up JDK ${{ needs.build-vars.outputs.jvm-version }}
79 | uses: actions/setup-java@v4
80 | with:
81 | distribution: ${{ needs.build-vars.outputs.distribution }}
82 | java-version: ${{ needs.build-vars.outputs.jvm-version }}
83 |
84 | - name: Setup Gradle
85 | uses: gradle/actions/setup-gradle@v3
86 |
87 | - name: Test with ${{ matrix.backend }}
88 | run: >
89 | ./gradlew test -i
90 | -PtestFilter=${{ matrix.backend }}
91 | -PimageRegistry=${{ needs.build-vars.outputs.registry }}
92 | -PjdkVersion=${{ needs.build-vars.outputs.jvm-version }}
93 | -PimageTag=${{ needs.sha-tag.outputs.tag }}
94 |
--------------------------------------------------------------------------------
/.github/workflows/cloud-config-versions.yml:
--------------------------------------------------------------------------------
1 | name: Find build and latest versions of cloud config
2 |
3 | on:
4 | workflow_call:
5 | inputs:
6 | distribution:
7 | description: JVM distribution to run
8 | type: string
9 | default: temurin
10 | java-version:
11 | description: JVM version to run
12 | type: string
13 | default: 17
14 | outputs:
15 | build:
16 | description: Current build version of cloud config
17 | value: ${{ jobs.cloud-config-versions.outputs.build }}
18 | latest:
19 | description: Latest version of cloud config
20 | value: ${{ jobs.cloud-config-versions.outputs.latest }}
21 |
22 | jobs:
23 | cloud-config-versions:
24 | name: Create Cloud Config Versions
25 | runs-on: ubuntu-latest
26 | outputs:
27 | build: ${{ steps.vars.outputs.build }}
28 | latest: ${{ steps.vars.outputs.latest }}
29 | steps:
30 | - name: Checkout
31 | uses: actions/checkout@v4
32 |
33 | - name: Set up JDK ${{ inputs.java-version }}
34 | uses: actions/setup-java@v4
35 | with:
36 | distribution: ${{ inputs.distribution }}
37 | java-version: ${{ inputs.java-version }}
38 |
39 | - name: Setup Gradle
40 | uses: gradle/actions/setup-gradle@v3
41 |
42 | - name: Set cloud config versions
43 | id: vars
44 | run: |
45 | echo "latest=`curl -s https://search.maven.org/solrsearch/select\?q\=g:%22org.springframework.cloud%22%20AND%20a:%22spring-cloud-config-server%22 | jq -r '.response.docs[0].latestVersion'`" >> $GITHUB_OUTPUT
46 | echo "build=`./gradlew dependencyInsight --dependency org.springframework.cloud:spring-cloud-config-server | grep 'org.springframework.cloud:spring-cloud-config-server:' | tail -1 | cut -d ':' -f 3-`" >> $GITHUB_OUTPUT
47 |
--------------------------------------------------------------------------------
/.github/workflows/codeql.yml:
--------------------------------------------------------------------------------
1 | # For most projects, this workflow file will not need changing; you simply need
2 | # to commit it to your repository.
3 | #
4 | # You may wish to alter this file to override the set of languages analyzed,
5 | # or to provide custom queries or build logic.
6 | #
7 | # ******** NOTE ********
8 | # We have attempted to detect the languages in your repository. Please check
9 | # the `language` matrix defined below to confirm you have the correct set of
10 | # supported CodeQL languages.
11 | #
12 | name: "CodeQL"
13 |
14 | on:
15 | push:
16 | branches: [ "main", "develop" ]
17 | pull_request:
18 | branches: [ "main", "develop" ]
19 | schedule:
20 | - cron: '25 22 * * 6'
21 |
22 | jobs:
23 | analyze:
24 | name: Analyze (${{ matrix.language }})
25 | # Runner size impacts CodeQL analysis time. To learn more, please see:
26 | # - https://gh.io/recommended-hardware-resources-for-running-codeql
27 | # - https://gh.io/supported-runners-and-hardware-resources
28 | # - https://gh.io/using-larger-runners (GitHub.com only)
29 | # Consider using larger runners or machines with greater resources for possible analysis time improvements.
30 | runs-on: ${{ (matrix.language == 'swift' && 'macos-latest') || 'ubuntu-latest' }}
31 | timeout-minutes: ${{ (matrix.language == 'swift' && 120) || 360 }}
32 | permissions:
33 | # required for all workflows
34 | security-events: write
35 |
36 | # only required for workflows in private repositories
37 | actions: read
38 | contents: read
39 |
40 | strategy:
41 | fail-fast: false
42 | matrix:
43 | include:
44 | - language: java-kotlin
45 | build-mode: autobuild
46 | # CodeQL supports the following values keywords for 'language': 'c-cpp', 'csharp', 'go', 'java-kotlin', 'javascript-typescript', 'python', 'ruby', 'swift'
47 | # Use `c-cpp` to analyze code written in C, C++ or both
48 | # Use 'java-kotlin' to analyze code written in Java, Kotlin or both
49 | # Use 'javascript-typescript' to analyze code written in JavaScript, TypeScript or both
50 | # To learn more about changing the languages that are analyzed or customizing the build mode for your analysis,
51 | # see https://docs.github.com/en/code-security/code-scanning/creating-an-advanced-setup-for-code-scanning/customizing-your-advanced-setup-for-code-scanning.
52 | # If you are analyzing a compiled language, you can modify the 'build-mode' for that language to customize how
53 | # your codebase is analyzed, see https://docs.github.com/en/code-security/code-scanning/creating-an-advanced-setup-for-code-scanning/codeql-code-scanning-for-compiled-languages
54 | steps:
55 | - name: Checkout repository
56 | uses: actions/checkout@v4
57 |
58 | - name: Set up JDK 17
59 | uses: actions/setup-java@v4
60 | with:
61 | distribution: temurin
62 | java-version: 17
63 |
64 | - name: Setup Gradle
65 | uses: gradle/actions/setup-gradle@v3
66 |
67 | # Initializes the CodeQL tools for scanning.
68 | - name: Initialize CodeQL
69 | uses: github/codeql-action/init@v3
70 | with:
71 | languages: ${{ matrix.language }}
72 | build-mode: ${{ matrix.build-mode }}
73 | # If you wish to specify custom queries, you can do so here or in a config file.
74 | # By default, queries listed here will override any specified in a config file.
75 | # Prefix the list here with "+" to use these queries and those in the config file.
76 |
77 | # For more details on CodeQL's query packs, refer to: https://docs.github.com/en/code-security/code-scanning/automatically-scanning-your-code-for-vulnerabilities-and-errors/configuring-code-scanning#using-queries-in-ql-packs
78 | # queries: security-extended,security-and-quality
79 |
80 | # If the analyze step fails for one of the languages you are analyzing with
81 | # "We were unable to automatically build your code", modify the matrix above
82 | # to set the build mode to "manual" for that language. Then modify this step
83 | # to build your code.
84 | # ℹ️ Command-line programs to run using the OS shell.
85 | # 📚 See https://docs.github.com/en/actions/using-workflows/workflow-syntax-for-github-actions#jobsjob_idstepsrun
86 | - if: matrix.build-mode == 'manual'
87 | run: |
88 | echo 'If you are using a "manual" build mode for one or more of the' \
89 | 'languages you are analyzing, replace this with the commands to build' \
90 | 'your code, for example:'
91 | echo ' make bootstrap'
92 | echo ' make release'
93 | exit 1
94 |
95 | - name: Perform CodeQL Analysis
96 | uses: github/codeql-action/analyze@v3
97 | with:
98 | category: "/language:${{matrix.language}}"
99 |
--------------------------------------------------------------------------------
/.github/workflows/create-sha-docker-tag.yml:
--------------------------------------------------------------------------------
1 | name: Create sha docker tag
2 |
3 | on:
4 | workflow_call:
5 | inputs:
6 | jvm-type:
7 | description: JVM type for output image
8 | type: string
9 | default: jre
10 | jvm-version:
11 | description: JVM version for output image
12 | type: string
13 | default: 17
14 | outputs:
15 | tag:
16 | description: Docker tag with sha of commit
17 | value: ${{ jobs.create-sha-docker-tag.outputs.tag }}
18 |
19 | jobs:
20 | jvm-tag:
21 | uses: ./.github/workflows/generate-jvm-tag.yml
22 | with:
23 | jvm-type: ${{ inputs.jvm-type }}
24 | jvm-version: ${{ inputs.jvm-version }}
25 |
26 | create-sha-docker-tag:
27 | name: Create sha docker tag
28 | needs: jvm-tag
29 | runs-on: ubuntu-latest
30 | outputs:
31 | tag: ${{ steps.vars.outputs.tag }}
32 | steps:
33 | - name: Build sha docker tag
34 | id: vars
35 | run: echo "tag=`echo $GITHUB_SHA | cut -c1-7`-${{ needs.jvm-tag.outputs.jvm-tag }}" >> $GITHUB_OUTPUT
36 |
--------------------------------------------------------------------------------
/.github/workflows/deploy.yml:
--------------------------------------------------------------------------------
1 | name: Build and deploy to registry
2 |
3 | on:
4 | release:
5 | types:
6 | - published
7 | workflow_dispatch:
8 | inputs:
9 | registry:
10 | description: Registry to deploy artifacts (docker.io, ghcr.io)
11 | required: true
12 |
13 | env:
14 | REGISTRY: docker.io
15 |
16 | jobs:
17 | build-vars:
18 | name: Create build variables
19 | runs-on: ubuntu-latest
20 | outputs:
21 | registry: ${{ inputs.registry || steps.build-vars.outputs.registry }}
22 | steps:
23 | - id: build-vars
24 | name: Create build variables
25 | run: echo "registry=$REGISTRY" >> $GITHUB_OUTPUT
26 |
27 | cloud-config-versions:
28 | name: Find build and latest versions of cloud config
29 | uses: ./.github/workflows/cloud-config-versions.yml
30 |
31 | build-and-deploy-to-registry:
32 | name: Create OCI images and deploy to ${{ inputs.registry }}
33 | uses: ./.github/workflows/release.yml
34 | needs:
35 | - build-vars
36 | - cloud-config-versions
37 | strategy:
38 | matrix:
39 | jvmType: [jre, jdk]
40 | jvmVersion: [17, 21]
41 | with:
42 | build-version: ${{ needs.cloud-config-versions.outputs.build }}
43 | latest-version: ${{ needs.cloud-config-versions.outputs.latest }}
44 | jvm-version: ${{ matrix.jvmVersion }}
45 | jvm-type: ${{ matrix.jvmType }}
46 | registry: ${{ needs.build-vars.outputs.registry }}
47 | secrets: inherit
48 |
49 | update-docker-hub-description:
50 | name: Update Docker Hub README
51 | needs:
52 | - build-vars
53 | - build-and-deploy-to-registry
54 | if: needs.build-vars.outputs.registry == 'docker.io'
55 | runs-on: ubuntu-latest
56 | steps:
57 | - name: Checkout
58 | uses: actions/checkout@v4
59 |
60 | - name: Docker Hub Description
61 | uses: peter-evans/dockerhub-description@v4
62 | with:
63 | username: ${{ secrets.DOCKERHUB_USERNAME }}
64 | password: ${{ secrets.DOCKERHUB_TOKEN }}
65 | repository: hyness/spring-cloud-config-server
66 |
--------------------------------------------------------------------------------
/.github/workflows/generate-docker-tags.yml:
--------------------------------------------------------------------------------
1 | name: Generate release build tags
2 |
3 | on:
4 | workflow_call:
5 | inputs:
6 | build-version:
7 | description: Version of docker image
8 | type: string
9 | required: true
10 | latest-version:
11 | description: Latest version of docker image
12 | type: string
13 | required: true
14 | image-name:
15 | description: The output image name
16 | type: string
17 | default: ${{ inputs.registry }}/${{ github.repository }}
18 | jvm-type:
19 | description: JVM type for output image
20 | type: string
21 | default: ${{ inputs.jvm-type-default }}
22 | jvm-type-default:
23 | description: Default JVM type for output image
24 | type: string
25 | default: jre
26 | jvm-version:
27 | description: JVM version for output image
28 | type: string
29 | default: ${{ inputs.jvm-version-default }}
30 | jvm-version-default:
31 | description: Default JVM version for output image
32 | type: string
33 | default: 17
34 | registry:
35 | description: Docker registry to deploy image
36 | type: string
37 | default: ghcr.io
38 | outputs:
39 | tags:
40 | description: A list of docker tags to create
41 | value: ${{ jobs.docker-tags.outputs.tags }}
42 |
43 | jobs:
44 | jvm-tag:
45 | uses: ./.github/workflows/generate-jvm-tag.yml
46 | with:
47 | jvm-type: ${{ inputs.jvm-type }}
48 | jvm-version: ${{ inputs.jvm-version }}
49 |
50 | jvm-tag-default:
51 | uses: ./.github/workflows/generate-jvm-tag.yml
52 | with:
53 | jvm-type: ${{ inputs.jvm-type-default }}
54 | jvm-version: ${{ inputs.jvm-version-default }}
55 |
56 | docker-tags:
57 | name: Generate release build tags
58 | needs:
59 | - jvm-tag
60 | - jvm-tag-default
61 | runs-on: ubuntu-latest
62 | outputs:
63 | tags: ${{ steps.write-tags.outputs.tags }}
64 | env:
65 | IS_JVM_DEFAULT: ${{ needs.jvm-tag.outputs.jvm-tag == needs.jvm-tag-default.outputs.jvm-tag }}
66 | steps:
67 | - name: Checkout
68 | uses: actions/checkout@v4
69 |
70 | - name: Remove prefix, if necessary
71 | run: |
72 | echo "BUILD_VERSION=`echo "${{ inputs.build-version }} | sed 's/.* -> //'`" >> $GITHUB_ENV
73 |
74 | - name: Determine if latest version
75 | run: |
76 | echo "IS_LATEST_VERSION=${{ env.BUILD_VERSION == inputs.latest-version }}" >> $GITHUB_ENV
77 |
78 | - name: Create docker tags
79 | uses: docker/metadata-action@v5
80 | with:
81 | images: ${{ inputs.image-name }}
82 | flavor: latest=false
83 | sep-tags: ','
84 | tags: |
85 | type=raw,value=latest,enable=${{ env.IS_LATEST_VERSION && env.IS_JVM_DEFAULT }}
86 | type=semver,pattern={{version}},value=${{ env.BUILD_VERSION }},enable=${{ env.IS_JVM_DEFAULT }}
87 | type=semver,pattern={{major}}.{{minor}},value=${{ env.BUILD_VERSION }},enable=${{ env.IS_JVM_DEFAULT }}
88 |
89 | type=raw,value=${{ needs.jvm-tag.outputs.jvm-tag }}
90 | type=semver,pattern={{major}}.{{minor}},suffix=-${{ needs.jvm-tag.outputs.jvm-tag }},value=${{ env.BUILD_VERSION }}
91 | type=semver,pattern={{version}},suffix=-{{sha}}-${{ needs.jvm-tag.outputs.jvm-tag }},value=${{ env.BUILD_VERSION }}
92 |
93 | - name: Write output
94 | id: write-tags
95 | run: echo "tags=$DOCKER_METADATA_OUTPUT_TAGS" >> $GITHUB_OUTPUT
96 |
--------------------------------------------------------------------------------
/.github/workflows/generate-jvm-tag.yml:
--------------------------------------------------------------------------------
1 | name: Generate a jvm tag
2 |
3 | on:
4 | workflow_call:
5 | inputs:
6 | jvm-type:
7 | description: JVM type for output image
8 | type: string
9 | required: true
10 | jvm-version:
11 | description: JVM version for output image
12 | type: string
13 | required: true
14 | outputs:
15 | jvm-tag:
16 | description: JVM tag used in docker tags
17 | value: ${{ jobs.generate-jvm-tag.outputs.jvm-tag }}
18 |
19 | jobs:
20 | generate-jvm-tag:
21 | name: Generate a jvm tag
22 | runs-on: ubuntu-latest
23 | outputs:
24 | jvm-tag: ${{ steps.write-tag.outputs.jvm-tag }}
25 | steps:
26 | - name: Write output
27 | id: write-tag
28 | run: echo "jvm-tag=${{ format('{0}{1}', inputs.jvm-type, inputs.jvm-version) }}" >> $GITHUB_OUTPUT
29 |
--------------------------------------------------------------------------------
/.github/workflows/release.yml:
--------------------------------------------------------------------------------
1 | name: Release build
2 |
3 | on:
4 | workflow_call:
5 | inputs:
6 | build-version:
7 | description: Version of docker image
8 | type: string
9 | required: true
10 | latest-version:
11 | description: Latest version of docker image
12 | type: string
13 | required: true
14 | jvm-type:
15 | description: JVM type for output image
16 | type: string
17 | default: jre
18 | jvm-version:
19 | description: JVM version for output image
20 | type: string
21 | default: 17
22 | image-name:
23 | description: The output image name
24 | type: string
25 | default: ${{ github.repository }}
26 | registry:
27 | description: The registry to deploy to
28 | type: string
29 | required: true
30 |
31 | jobs:
32 | docker-tags:
33 | uses: ./.github/workflows/generate-docker-tags.yml
34 | with:
35 | build-version: ${{ inputs.build-version }}
36 | latest-version: ${{ inputs.latest-version }}
37 | jvm-version: ${{ inputs.jvm-version }}
38 | jvm-type: ${{ inputs.jvm-type }}
39 |
40 | jvm-tag:
41 | uses: ./.github/workflows/generate-jvm-tag.yml
42 | with:
43 | jvm-type: ${{ inputs.jvm-type }}
44 | jvm-version: ${{ inputs.jvm-version }}
45 |
46 | sha-tag:
47 | uses: ./.github/workflows/create-sha-docker-tag.yml
48 | with:
49 | jvm-type: ${{ inputs.jvm-type }}
50 | jvm-version: ${{ inputs.jvm-version }}
51 |
52 | build-and-deploy:
53 | name: Build and deploy Java ${{ needs.jvm-tag.outputs.jvm-tag }} OCI image to registry
54 | uses: ./.github/workflows/build-and-deploy-image.yml
55 | needs:
56 | - docker-tags
57 | - jvm-tag
58 | - sha-tag
59 | with:
60 | image-name: ${{ inputs.image-name }}:${{ needs.sha-tag.outputs.tag }}
61 | image-jvm-version: ${{ inputs.jvm-version }}
62 | image-jvm-type: ${{ inputs.jvm-type }}
63 | registry: ${{ inputs.registry }}
64 | tags: ${{ needs.docker-tags.outputs.tags }}
65 | secrets: inherit
66 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | .*
2 | !.github
3 | !.travis-ci.yml
4 | build
5 | target
6 | out
7 |
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | Apache License
2 | Version 2.0, January 2004
3 | http://www.apache.org/licenses/
4 |
5 | TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
6 |
7 | 1. Definitions.
8 |
9 | "License" shall mean the terms and conditions for use, reproduction,
10 | and distribution as defined by Sections 1 through 9 of this document.
11 |
12 | "Licensor" shall mean the copyright owner or entity authorized by
13 | the copyright owner that is granting the License.
14 |
15 | "Legal Entity" shall mean the union of the acting entity and all
16 | other entities that control, are controlled by, or are under common
17 | control with that entity. For the purposes of this definition,
18 | "control" means (i) the power, direct or indirect, to cause the
19 | direction or management of such entity, whether by contract or
20 | otherwise, or (ii) ownership of fifty percent (50%) or more of the
21 | outstanding shares, or (iii) beneficial ownership of such entity.
22 |
23 | "You" (or "Your") shall mean an individual or Legal Entity
24 | exercising permissions granted by this License.
25 |
26 | "Source" form shall mean the preferred form for making modifications,
27 | including but not limited to software source code, documentation
28 | source, and configuration files.
29 |
30 | "Object" form shall mean any form resulting from mechanical
31 | transformation or translation of a Source form, including but
32 | not limited to compiled object code, generated documentation,
33 | and conversions to other media types.
34 |
35 | "Work" shall mean the work of authorship, whether in Source or
36 | Object form, made available under the License, as indicated by a
37 | copyright notice that is included in or attached to the work
38 | (an example is provided in the Appendix below).
39 |
40 | "Derivative Works" shall mean any work, whether in Source or Object
41 | form, that is based on (or derived from) the Work and for which the
42 | editorial revisions, annotations, elaborations, or other modifications
43 | represent, as a whole, an original work of authorship. For the purposes
44 | of this License, Derivative Works shall not include works that remain
45 | separable from, or merely link (or bind by name) to the interfaces of,
46 | the Work and Derivative Works thereof.
47 |
48 | "Contribution" shall mean any work of authorship, including
49 | the original version of the Work and any modifications or additions
50 | to that Work or Derivative Works thereof, that is intentionally
51 | submitted to Licensor for inclusion in the Work by the copyright owner
52 | or by an individual or Legal Entity authorized to submit on behalf of
53 | the copyright owner. For the purposes of this definition, "submitted"
54 | means any form of electronic, verbal, or written communication sent
55 | to the Licensor or its representatives, including but not limited to
56 | communication on electronic mailing lists, source code control systems,
57 | and issue tracking systems that are managed by, or on behalf of, the
58 | Licensor for the purpose of discussing and improving the Work, but
59 | excluding communication that is conspicuously marked or otherwise
60 | designated in writing by the copyright owner as "Not a Contribution."
61 |
62 | "Contributor" shall mean Licensor and any individual or Legal Entity
63 | on behalf of whom a Contribution has been received by Licensor and
64 | subsequently incorporated within the Work.
65 |
66 | 2. Grant of Copyright License. Subject to the terms and conditions of
67 | this License, each Contributor hereby grants to You a perpetual,
68 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable
69 | copyright license to reproduce, prepare Derivative Works of,
70 | publicly display, publicly perform, sublicense, and distribute the
71 | Work and such Derivative Works in Source or Object form.
72 |
73 | 3. Grant of Patent License. Subject to the terms and conditions of
74 | this License, each Contributor hereby grants to You a perpetual,
75 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable
76 | (except as stated in this section) patent license to make, have made,
77 | use, offer to sell, sell, import, and otherwise transfer the Work,
78 | where such license applies only to those patent claims licensable
79 | by such Contributor that are necessarily infringed by their
80 | Contribution(s) alone or by combination of their Contribution(s)
81 | with the Work to which such Contribution(s) was submitted. If You
82 | institute patent litigation against any entity (including a
83 | cross-claim or counterclaim in a lawsuit) alleging that the Work
84 | or a Contribution incorporated within the Work constitutes direct
85 | or contributory patent infringement, then any patent licenses
86 | granted to You under this License for that Work shall terminate
87 | as of the date such litigation is filed.
88 |
89 | 4. Redistribution. You may reproduce and distribute copies of the
90 | Work or Derivative Works thereof in any medium, with or without
91 | modifications, and in Source or Object form, provided that You
92 | meet the following conditions:
93 |
94 | (a) You must give any other recipients of the Work or
95 | Derivative Works a copy of this License; and
96 |
97 | (b) You must cause any modified files to carry prominent notices
98 | stating that You changed the files; and
99 |
100 | (c) You must retain, in the Source form of any Derivative Works
101 | that You distribute, all copyright, patent, trademark, and
102 | attribution notices from the Source form of the Work,
103 | excluding those notices that do not pertain to any part of
104 | the Derivative Works; and
105 |
106 | (d) If the Work includes a "NOTICE" text file as part of its
107 | distribution, then any Derivative Works that You distribute must
108 | include a readable copy of the attribution notices contained
109 | within such NOTICE file, excluding those notices that do not
110 | pertain to any part of the Derivative Works, in at least one
111 | of the following places: within a NOTICE text file distributed
112 | as part of the Derivative Works; within the Source form or
113 | documentation, if provided along with the Derivative Works; or,
114 | within a display generated by the Derivative Works, if and
115 | wherever such third-party notices normally appear. The contents
116 | of the NOTICE file are for informational purposes only and
117 | do not modify the License. You may add Your own attribution
118 | notices within Derivative Works that You distribute, alongside
119 | or as an addendum to the NOTICE text from the Work, provided
120 | that such additional attribution notices cannot be construed
121 | as modifying the License.
122 |
123 | You may add Your own copyright statement to Your modifications and
124 | may provide additional or different license terms and conditions
125 | for use, reproduction, or distribution of Your modifications, or
126 | for any such Derivative Works as a whole, provided Your use,
127 | reproduction, and distribution of the Work otherwise complies with
128 | the conditions stated in this License.
129 |
130 | 5. Submission of Contributions. Unless You explicitly state otherwise,
131 | any Contribution intentionally submitted for inclusion in the Work
132 | by You to the Licensor shall be under the terms and conditions of
133 | this License, without any additional terms or conditions.
134 | Notwithstanding the above, nothing herein shall supersede or modify
135 | the terms of any separate license agreement you may have executed
136 | with Licensor regarding such Contributions.
137 |
138 | 6. Trademarks. This License does not grant permission to use the trade
139 | names, trademarks, service marks, or product names of the Licensor,
140 | except as required for reasonable and customary use in describing the
141 | origin of the Work and reproducing the content of the NOTICE file.
142 |
143 | 7. Disclaimer of Warranty. Unless required by applicable law or
144 | agreed to in writing, Licensor provides the Work (and each
145 | Contributor provides its Contributions) on an "AS IS" BASIS,
146 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
147 | implied, including, without limitation, any warranties or conditions
148 | of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
149 | PARTICULAR PURPOSE. You are solely responsible for determining the
150 | appropriateness of using or redistributing the Work and assume any
151 | risks associated with Your exercise of permissions under this License.
152 |
153 | 8. Limitation of Liability. In no event and under no legal theory,
154 | whether in tort (including negligence), contract, or otherwise,
155 | unless required by applicable law (such as deliberate and grossly
156 | negligent acts) or agreed to in writing, shall any Contributor be
157 | liable to You for damages, including any direct, indirect, special,
158 | incidental, or consequential damages of any character arising as a
159 | result of this License or out of the use or inability to use the
160 | Work (including but not limited to damages for loss of goodwill,
161 | work stoppage, computer failure or malfunction, or any and all
162 | other commercial damages or losses), even if such Contributor
163 | has been advised of the possibility of such damages.
164 |
165 | 9. Accepting Warranty or Additional Liability. While redistributing
166 | the Work or Derivative Works thereof, You may choose to offer,
167 | and charge a fee for, acceptance of support, warranty, indemnity,
168 | or other liability obligations and/or rights consistent with this
169 | License. However, in accepting such obligations, You may act only
170 | on Your own behalf and on Your sole responsibility, not on behalf
171 | of any other Contributor, and only if You agree to indemnify,
172 | defend, and hold each Contributor harmless for any liability
173 | incurred by, or claims asserted against, such Contributor by reason
174 | of your accepting any such warranty or additional liability.
175 |
176 | END OF TERMS AND CONDITIONS
177 |
178 | APPENDIX: How to apply the Apache License to your work.
179 |
180 | To apply the Apache License to your work, attach the following
181 | boilerplate notice, with the fields enclosed by brackets "[]"
182 | replaced with your own identifying information. (Don't include
183 | the brackets!) The text should be enclosed in the appropriate
184 | comment syntax for the file format. We also recommend that a
185 | file or class name and description of purpose be included on the
186 | same "printed page" as the copyright notice for easier
187 | identification within third-party archives.
188 |
189 | Copyright [yyyy] [name of copyright owner]
190 |
191 | Licensed under the Apache License, Version 2.0 (the "License");
192 | you may not use this file except in compliance with the License.
193 | You may obtain a copy of the License at
194 |
195 | http://www.apache.org/licenses/LICENSE-2.0
196 |
197 | Unless required by applicable law or agreed to in writing, software
198 | distributed under the License is distributed on an "AS IS" BASIS,
199 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
200 | See the License for the specific language governing permissions and
201 | limitations under the License.
202 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # Spring Cloud Config Server
2 | A docker image of [Spring Cloud Config Server](https://docs.spring.io/spring-cloud-config/reference/).
3 |
4 | 
5 | 
6 | [](https://hub.docker.com/r/hyness/spring-cloud-config-server/)
7 | [](https://hub.docker.com/r/hyness/spring-cloud-config-server)
8 | [](https://hub.docker.com/r/hyness/spring-cloud-config-server)
9 | [](https://www.apache.org/licenses/LICENSE-2.0.html)
10 |
11 | ### Supported tags
12 | * `4.2.2-jre17`, `4.2-jre17`, `jre17`, `4.2.2`, `4.2`, `latest`
13 | * `4.2.2-jdk17`, `4.2-jdk17`, `jdk17`
14 | * `4.2.2-jre21`, `4.2-jre21`, `jre21`
15 | * `4.2.2-jdk21`, `4.2-jdk21`, `jdk21`
16 |
17 | ### Usage
18 | ```
19 | docker run -it --name=spring-cloud-config-server \
20 | -p 8888:8888 \
21 | -v :/config \
22 | hyness/spring-cloud-config-server
23 | ```
24 |
25 | #### Parameters
26 | * `-p 8888` Server port
27 | * `-v /config` Mounted configuration
28 |
29 | #### Environment Variables
30 | * `JAVA_OPTS` Specify VM Options or System Properties
31 |
32 | ### Configuring Spring Cloud Config Server
33 | Spring Cloud Config Server is a normal Spring Boot application, it can be configured through all the ways a
34 | Spring Boot application can be configured. You may use environment variables or you can mount configuration in
35 | the provided volume. The configuration file must be named **application** and may be a properties or yaml file.
36 | See the [Spring Boot documentation](http://docs.spring.io/spring-boot/docs/current/reference/htmlsingle/#boot-features-external-config)
37 | for further information on how to use and configure Spring Boot.
38 |
39 | #### Configuration examples
40 |
41 | #### Using a mounted config directory
42 | ```
43 | docker run -it -p 8888:8888 \
44 | -v /path/to/config/dir:/config \
45 | hyness/spring-cloud-config-server
46 | ```
47 |
48 | #### Using a mounted application.yml
49 | ```
50 | docker run -it -p 8888:8888 \
51 | -v /path/to/application.yml:/config/application.yml \
52 | hyness/spring-cloud-config-server
53 | ```
54 | #### Configure through environment variables without a configuration file
55 | ```
56 | docker run -it -p 8888:8888 \
57 | -e SPRING_CLOUD_CONFIG_SERVER_GIT_URI=https://github.com/spring-cloud-samples/config-repo \
58 | hyness/spring-cloud-config-server
59 | ```
60 | #### Configure through system properties without a configuration file
61 | ```
62 | docker run -it -p 8888:8888 \
63 | -e JAVA_OPTS=-Dspring.cloud.config.server.git.uri=https://github.com/spring-cloud-samples/config-repo \
64 | hyness/spring-cloud-config-server
65 | ```
66 | #### Configure through command line arguments without a configuration file
67 | ```
68 | docker run -it -p 8888:8888 \
69 | hyness/spring-cloud-config-server \
70 | --spring.cloud.config.server.git.uri=https://github.com/spring-cloud-samples/config-repo
71 | ```
72 | #### Verify Samples Above
73 | ```
74 | $ curl http://localhost:8888/foo/development
75 | ```
76 |
77 | ### Required Backend Configuration
78 | Spring Cloud Config Server **requires** that you configure a backend to serve your configuration files
79 |
80 | #### Git
81 | #### Remote https git repo example
82 | ```
83 | docker run -it -p 8888:8888 \
84 | -e SPRING_CLOUD_CONFIG_SERVER_GIT_URI=https://github.com/spring-cloud-samples/config-repo \
85 | hyness/spring-cloud-config-server
86 | ```
87 | #### Remote ssh git repo example
88 | ```
89 | docker run -it -p 8888:8888 \
90 | -v /path/to/home/dir/with/ssh/keys:/home/cnb/.ssh \
91 | -e SPRING_CLOUD_CONFIG_SERVER_GIT_URI=git@github.com:spring-cloud-samples/config-repo \
92 | hyness/spring-cloud-config-server
93 | ```
94 | #### Local git repo example
95 | ```
96 | docker run -it -p 8888:8888 \
97 | -v /path/to/config/files/dir:/config \
98 | -e SPRING_CLOUD_CONFIG_SERVER_GIT_URI=file:/config/my-local-git-repo \
99 | hyness/spring-cloud-config-server
100 | ```
101 | #### Filesystem
102 | ```
103 | docker run -it -p 8888:8888 \
104 | -v /path/to/config/files/dir:/config \
105 | -e SPRING_PROFILES_ACTIVE=native \
106 | hyness/spring-cloud-config-server
107 | ```
108 | #### Vault
109 | ```
110 | docker run -it -p 8888:8888 \
111 | -e SPRING_PROFILES_ACTIVE=vault \
112 | -e SPRING_CLOUD_CONFIG_SERVER_VAULT_HOST=localhost \
113 | -e SPRING_CLOUD_CONFIG_SERVER_VAULT_TOKEN=00000000-0000-0000-0000-000000000000 \
114 | hyness/spring-cloud-config-server
115 | ```
116 | #### AWS Parameter Store
117 | ```
118 | docker run -it -p 8888:8888 \
119 | -e SPRING_PROFILES_ACTIVE=awsparamstore \
120 | -e SPRING_CLOUD_CONFIG_SERVER_AWSPARAMSTORE_REGION=us-east-1 \
121 | hyness/spring-cloud-config-server
122 | ```
123 | #### AWS S3
124 | ```
125 | docker run -it -p 8888:8888 \
126 | -e SPRING_PROFILES_ACTIVE=awss3 \
127 | -e SPRING_CLOUD_CONFIG_SERVER_AWSS3_REGION=us-east-1 \
128 | -e SPRING_CLOUD_CONFIG_SERVER_AWSS3_BUCKET=sample-bucket \
129 | hyness/spring-cloud-config-server
130 | ```
131 | #### AWS Secrets Manager
132 | ```
133 | docker run -it -p 8888:8888 \
134 | -e SPRING_PROFILES_ACTIVE=awssecretsmanager \
135 | -e SPRING_CLOUD_CONFIG_SERVER_AWSSECRETSMANAGER_REGION=us-east-1 \
136 | hyness/spring-cloud-config-server
137 | ```
138 | #### Redis
139 | ```
140 | docker run -it -p 8888:8888 \
141 | -e SPRING_PROFILES_ACTIVE=redis \
142 | -e SPRING_DATA_REDIS_HOST=localhost
143 | -e SPRING_DATA_REDIS_PORT=6379
144 | hyness/spring-cloud-config-server
145 | ```
146 | #### JDBC
147 | ```
148 | docker run -it -p 8888:8888 \
149 | -e SPRING_PROFILES_ACTIVE=jdbc \
150 | -e SPRING_DATASOURCE_URL=jdbc:postgresql://localhost:5432/database_name \
151 | -e SPRING_DATASOURCE_USERNAME=myuser \
152 | -e SPRING_DATASOURCE_PASSWORD=mypassword \
153 | hyness/spring-cloud-config-server
154 | ```
155 | #### Supported Databases
156 | * Firebird
157 | * MariaDB
158 | * MS-SQL
159 | * Postgres
160 |
161 | [See the docker-compose examples](https://github.com/hyness/spring-cloud-config-server/tree/main/examples) for more details
162 |
163 | ### Additional Features
164 |
165 | #### Push notifications with Spring Cloud Bus
166 |
167 | Spring Cloud Bus links the nodes of a distributed system with a lightweight message broker. It allows clusters of
168 | applications configured with **RefreshScope** to automatically reload configuration without restarting.
169 |
170 | [See the Spring Cloud Conifg](https://docs.spring.io/spring-cloud-config/docs/2.2.6.RELEASE/reference/html/#_push_notifications_and_spring_cloud_bus) and
171 | [Spring Cloud Bus](https://cloud.spring.io/spring-cloud-bus/reference/html) documentation for more details
172 |
173 | #### Supported Message Brokers
174 | #### Kafka
175 | ```
176 | docker run -it -p 8888:8888 \
177 | -e SPRING_PROFILES_ACTIVE=cloud-bus-kafka \
178 | -e SPRING_CLOUD_CONFIG_SERVER_GIT_URI=https://github.com/spring-cloud-samples/config-repo \
179 | -e SPRING_KAFKA_BOOTSTRAP-SERVERS=localhost:9092 \
180 | hyness/spring-cloud-config-server
181 | ```
182 |
183 | #### RabbitMQ
184 | ```
185 | docker run -it -p 8888:8888 \
186 | -e SPRING_PROFILES_ACTIVE=cloud-bus-rabbit \
187 | -e SPRING_CLOUD_CONFIG_SERVER_GIT_URI=https://github.com/spring-cloud-samples/config-repo \
188 | -e SPRING_RABBITMQ_HOST=localhost \
189 | hyness/spring-cloud-config-server
190 | ```
191 |
192 | ### Actuator
193 | The [Spring Boot actuator](https://docs.spring.io/spring-boot/docs/current/reference/htmlsingle/#production-ready) is
194 | enabled by default. [See the Spring Boot documentation](https://docs.spring.io/spring-boot/docs/current/reference/htmlsingle/#actuator-properties)
195 | for configuration options. The actuator can be disabled entirely by including the `no-actuator` profile
196 |
197 | #### Prometheus Metrics
198 | To enable support for an additional prometheus metrics endpoint, enable the `prometheus` endpoint, as well as [ensuring the
199 | endpoint is exposed](https://docs.spring.io/spring-boot/docs/current/reference/htmlsingle/#actuator.endpoints.exposing).
200 | ````
201 | docker run -it -p 8888:8888 \
202 | -v /path/to/config/files/dir:/config \
203 | -e SPRING_CLOUD_CONFIG_SERVER_GIT_URI=file:/config/my-local-git-repo \
204 | -e MANAGEMENT_ENDPOINT_PROMETHEUS_ENABLED=true \
205 | -e MANAGEMENT_ENDPOINTS_WEB_EXPOSURE_INCLUDE=health,prometheus \
206 | hyness/spring-cloud-config-server
207 | ````
208 |
209 | ### Spring Security
210 | Spring Security can be enabled through the `security` profile for use with any backend of your choosing.
211 |
212 | #### Basic / Form Security (with remote git backend)
213 | ```
214 | docker run -it -p 8888:8888 \
215 | -e SPRING_PROFILES_ACTIVE=security \
216 | -e SPRING_SECURITY_USER_NAME=myuser \
217 | -e SPRING_SECURITY_USER_PASSWORD=mypassword \
218 | -e SPRING_CLOUD_CONFIG_SERVER_GIT_URI=https://github.com/spring-cloud-samples/config-repo \
219 | hyness/spring-cloud-config-server
220 | ```
221 |
222 | ### Docker Healthcheck
223 | Starting with 4.1.x, this docker image includes an internal health checker for use with docker or docker compose
224 | using [Tiny Health Checker](https://github.com/dmikusa/tiny-health-checker).
225 |
226 | #### Example configuration
227 | ```yaml
228 | healthcheck:
229 | test: ["CMD", "health-check"]
230 | start_interval: 30s
231 | interval: 5s
232 | retries: 10
233 | ```
234 |
235 | See [the full example](./examples/healthcheck/compose.yml) for more details
236 |
237 | ### Thank You
238 |
239 | #### Project Contributors
240 | Thank you to all the contributors who have helped make this project better through code contributions and bug reports.
241 |
--------------------------------------------------------------------------------
/build.gradle.kts:
--------------------------------------------------------------------------------
1 | import org.springframework.boot.gradle.plugin.SpringBootPlugin.BOM_COORDINATES as SPRING_BOOT_BOM
2 |
3 | plugins {
4 | alias(libs.plugins.spring.boot)
5 | alias(libs.plugins.kotlin.jvm)
6 | alias(libs.plugins.kotlin.plugin.spring)
7 | }
8 |
9 | val jdkVersion: String by project
10 | val jvmType: String by project
11 | val dockerUsername: String by project
12 | val dockerPassword: String by project
13 | val dockerTags: String? by project
14 | val imageRegistry: String? by project
15 | val imageName: String? by project
16 | val imageTag: String? by project
17 | val testFilter: String? by project
18 |
19 | tasks {
20 | version = versionCatalogs.firstNotNullOf {
21 | it.findVersion("spring.cloud.config").orElse(null)
22 | }
23 |
24 | compileKotlin {
25 | compilerOptions.freeCompilerArgs = listOf("-Xjsr305=strict")
26 | }
27 |
28 | test {
29 | systemProperties["registry"] = imageRegistry
30 | systemProperties["name"] = imageName
31 | systemProperties["tag"] = imageTag
32 | useJUnitPlatform {
33 | testFilter?.let { includeTags(it) }
34 | }
35 | }
36 |
37 | bootJar {
38 | manifest.attributes(
39 | "Implementation-Title" to project.name,
40 | "Implementation-Version" to project.version
41 | )
42 | }
43 |
44 | bootBuildImage {
45 | applicationDirectory = "/opt/spring-cloud-config-server"
46 | buildpacks = listOf(
47 | "paketo-buildpacks/ca-certificates",
48 | "paketo-buildpacks/bellsoft-liberica",
49 | "paketo-buildpacks/syft",
50 | "paketo-buildpacks/executable-jar",
51 | "paketo-buildpacks/dist-zip",
52 | "paketo-buildpacks/spring-boot",
53 | "paketo-buildpacks/environment-variables",
54 | "gcr.io/paketo-buildpacks/health-checker:1.17.0"
55 | )
56 | docker.publishRegistry {
57 | username = dockerUsername
58 | password = dockerPassword
59 | }
60 | environment = mapOf(
61 | "BP_JVM_TYPE" to jvmType,
62 | "BP_JVM_VERSION" to jdkVersion,
63 | "BPE_DELIM_JAVA_TOOL_OPTIONS" to " ",
64 | "BPE_APPEND_JAVA_TOOL_OPTIONS" to "-Dspring.config.additional-location=optional:file:/config/",
65 | "BP_HEALTH_CHECKER_ENABLED" to "true",
66 | "BPE_THC_PATH" to "/actuator/health",
67 | "BPE_THC_PORT" to "8888"
68 | )
69 | imageName = "hyness/spring-cloud-config-server"
70 | tags = dockerTags?.split(',')
71 | }
72 | }
73 |
74 | repositories {
75 | mavenCentral()
76 | }
77 |
78 | dependencies {
79 | implementation(platform(SPRING_BOOT_BOM))
80 | implementation(platform(libs.spring.cloud))
81 | implementation(libs.bundles.spring.cloud.config)
82 | implementation(libs.bundles.spring.cloud.bus)
83 | implementation(libs.spring.boot.actuator)
84 | implementation(libs.spring.data.redis)
85 | implementation(libs.spring.boot.security)
86 | implementation(libs.spring.jdbc)
87 | implementation(libs.spring.vault)
88 | implementation(libs.bundles.kotlin)
89 | implementation(libs.bundles.aws)
90 | runtimeOnly(libs.bundles.jdbc.drivers)
91 | runtimeOnly(libs.micrometer.prometheus)
92 | testImplementation(libs.spring.boot.test)
93 | testImplementation(libs.spring.boot.testcontainers)
94 | testImplementation(libs.testcontainers.junit5)
95 | testImplementation(libs.kotlin.logging)
96 | testImplementation(libs.awaitility.kotlin)
97 | }
98 |
99 | configurations.all {
100 | resolutionStrategy.eachDependency {
101 | if (requested.name.startsWith("spring-cloud-function-")) {
102 | useVersion("4.2.2")
103 | }
104 | }
105 | }
--------------------------------------------------------------------------------
/examples/aws/paramstore/compose.yml:
--------------------------------------------------------------------------------
1 | # Docker Compose example for testing AWS S3
2 |
3 | networks:
4 | aws:
5 |
6 | services:
7 | # Configured through environment variables
8 | config-server-env:
9 | depends_on:
10 | localstack:
11 | condition: service_healthy
12 | image: "${REGISTRY:-docker.io}/${IMAGE_NAME:-hyness/spring-cloud-config-server}:${TAG:-latest}"
13 | networks:
14 | - aws
15 | ports:
16 | - "8888"
17 | environment:
18 | AWS_ACCESS_KEY_ID: test
19 | AWS_SECRET_ACCESS_KEY: test
20 | SPRING_PROFILES_ACTIVE: awsparamstore
21 | SPRING_CLOUD_CONFIG_SERVER_AWSPARAMSTORE_ENDPOINT: http://localhost.localstack.cloud:4566
22 | SPRING_CLOUD_CONFIG_SERVER_AWSPARAMSTORE_REGION: us-east-1
23 |
24 | # Configured through mounted config file
25 | config-server-dir:
26 | depends_on:
27 | localstack:
28 | condition: service_healthy
29 | image: "${REGISTRY:-docker.io}/${IMAGE_NAME:-hyness/spring-cloud-config-server}:${TAG:-latest}"
30 | networks:
31 | - aws
32 | ports:
33 | - "8888"
34 | environment:
35 | AWS_ACCESS_KEY_ID: test
36 | AWS_SECRET_ACCESS_KEY: test
37 | volumes:
38 | - ./config:/config
39 |
40 | # Configured through system properties
41 | config-server-props:
42 | depends_on:
43 | localstack:
44 | condition: service_healthy
45 | image: "${REGISTRY:-docker.io}/${IMAGE_NAME:-hyness/spring-cloud-config-server}:${TAG:-latest}"
46 | networks:
47 | - aws
48 | ports:
49 | - "8888"
50 | environment:
51 | AWS_ACCESS_KEY_ID: test
52 | AWS_SECRET_ACCESS_KEY: test
53 | JAVA_OPTS: >
54 | -Dspring.profiles.active=awsparamstore
55 | -Dspring.cloud.config.server.awsparamstore.endpoint=http://localhost.localstack.cloud:4566
56 | -Dspring.cloud.config.server.awsparamstore.region=us-east-1
57 |
58 |
59 | # Configured through command line arguments
60 | config-server-args:
61 | depends_on:
62 | localstack:
63 | condition: service_healthy
64 | image: "${REGISTRY:-docker.io}/${IMAGE_NAME:-hyness/spring-cloud-config-server}:${TAG:-latest}"
65 | networks:
66 | - aws
67 | ports:
68 | - "8888"
69 | environment:
70 | AWS_ACCESS_KEY_ID: test
71 | AWS_SECRET_ACCESS_KEY: test
72 | command:
73 | - --spring.profiles.active=awsparamstore
74 | - --spring.cloud.config.server.awsparamstore.endpoint=http://localhost.localstack.cloud:4566
75 | - --spring.cloud.config.server.awsparamstore.region=us-east-1
76 |
77 | localstack:
78 | image: localstack/localstack:stable
79 | networks:
80 | aws:
81 | aliases:
82 | - localhost.localstack.cloud
83 | ports:
84 | - "4566:4566"
85 | - "4571:4571"
86 | environment:
87 | AWS_ACCESS_KEY_ID: test
88 | AWS_SECRET_ACCESS_KEY: test
89 | SERVICES: ssm
90 | DEBUG: 1
91 | USE_SINGLE_REGION: 1
92 | healthcheck:
93 | test: ["CMD-SHELL", "awslocal ssm list-documents"]
94 | volumes:
95 | - ./populate-paramstore.sh:/data/populate-paramstore.sh
96 |
--------------------------------------------------------------------------------
/examples/aws/paramstore/config/application.yml:
--------------------------------------------------------------------------------
1 | spring:
2 | cloud:
3 | config:
4 | server:
5 | awsparamstore:
6 | endpoint: http://localhost.localstack.cloud:4566
7 | region: us-east-1
8 | profiles:
9 | active: awsparamstore
--------------------------------------------------------------------------------
/examples/aws/paramstore/populate-paramstore.sh:
--------------------------------------------------------------------------------
1 | #!/bin/bash
2 | awslocal ssm put-parameter --name /config/application-default/foo --value "default" --type String
3 | awslocal ssm put-parameter --name /config/application-development/bar --value "default" --type String
4 | awslocal ssm put-parameter --name /config/foo-development/foo --value "bar" --type String
5 | awslocal ssm put-parameter --name /config/foo-development/bar --value "foo" --type String
6 |
--------------------------------------------------------------------------------
/examples/aws/s3/application.yml:
--------------------------------------------------------------------------------
1 | spring:
2 | cloud:
3 | config:
4 | server:
5 | awss3:
6 | endpoint: http://localhost.localstack.cloud:4566
7 | region: us-east-1
8 | bucket: sample-bucket
9 | profiles:
10 | active: awss3
--------------------------------------------------------------------------------
/examples/aws/s3/compose.yml:
--------------------------------------------------------------------------------
1 | # Docker Compose example for testing AWS S3
2 |
3 | networks:
4 | aws:
5 |
6 | services:
7 | # Configured through environment variables
8 | config-server-env:
9 | depends_on:
10 | localstack:
11 | condition: service_healthy
12 | image: "${REGISTRY:-docker.io}/${IMAGE_NAME:-hyness/spring-cloud-config-server}:${TAG:-latest}"
13 | networks:
14 | - aws
15 | ports:
16 | - "8888"
17 | environment:
18 | AWS_ACCESS_KEY_ID: test
19 | AWS_SECRET_ACCESS_KEY: test
20 | SPRING_PROFILES_ACTIVE: awss3
21 | SPRING_CLOUD_CONFIG_SERVER_AWSS3_ENDPOINT: http://localhost.localstack.cloud:4566
22 | SPRING_CLOUD_CONFIG_SERVER_AWSS3_REGION: us-east-1
23 | SPRING_CLOUD_CONFIG_SERVER_AWSS3_BUCKET: sample-bucket
24 |
25 | # Configured through mounted config file
26 | config-server-dir:
27 | depends_on:
28 | localstack:
29 | condition: service_healthy
30 | image: "${REGISTRY:-docker.io}/${IMAGE_NAME:-hyness/spring-cloud-config-server}:${TAG:-latest}"
31 | networks:
32 | - aws
33 | ports:
34 | - "8888"
35 | environment:
36 | AWS_ACCESS_KEY_ID: test
37 | AWS_SECRET_ACCESS_KEY: test
38 | volumes:
39 | - ./application.yml:/config/application.yml
40 |
41 | # Configured through system properties
42 | config-server-props:
43 | depends_on:
44 | localstack:
45 | condition: service_healthy
46 | image: "${REGISTRY:-docker.io}/${IMAGE_NAME:-hyness/spring-cloud-config-server}:${TAG:-latest}"
47 | networks:
48 | - aws
49 | ports:
50 | - "8888"
51 | environment:
52 | AWS_ACCESS_KEY_ID: test
53 | AWS_SECRET_ACCESS_KEY: test
54 | JAVA_OPTS: >
55 | -Dspring.profiles.active=awss3
56 | -Dspring.cloud.config.server.awss3.endpoint=http://localhost.localstack.cloud:4566
57 | -Dspring.cloud.config.server.awss3.region=us-east-1
58 | -Dspring.cloud.config.server.awss3.bucket=sample-bucket
59 |
60 | # Configured through command line arguments
61 | config-server-args:
62 | depends_on:
63 | localstack:
64 | condition: service_healthy
65 | image: "${REGISTRY:-docker.io}/${IMAGE_NAME:-hyness/spring-cloud-config-server}:${TAG:-latest}"
66 | networks:
67 | - aws
68 | ports:
69 | - "8888"
70 | environment:
71 | AWS_ACCESS_KEY_ID: test
72 | AWS_SECRET_ACCESS_KEY: test
73 | command:
74 | - --spring.profiles.active=awss3
75 | - --spring.cloud.config.server.awss3.endpoint=http://localhost.localstack.cloud:4566
76 | - --spring.cloud.config.server.awss3.region=us-east-1
77 | - --spring.cloud.config.server.awss3.bucket=sample-bucket
78 |
79 | localstack:
80 | image: localstack/localstack:stable
81 | networks:
82 | aws:
83 | aliases:
84 | - localhost.localstack.cloud
85 | - sample-bucket.localhost.localstack.cloud
86 | ports:
87 | - "4566:4566"
88 | - "4571:4571"
89 | environment:
90 | AWS_ACCESS_KEY_ID: test
91 | AWS_SECRET_ACCESS_KEY: test
92 | DEBUG: 1
93 | SERVICES: s3
94 | USE_SINGLE_REGION: 1
95 | healthcheck:
96 | test: ["CMD-SHELL", "awslocal s3api create-bucket --bucket test"]
97 | volumes:
98 | - ./config:/data/config
99 | - ./populate-s3.sh:/data/populate-s3.sh
100 |
--------------------------------------------------------------------------------
/examples/aws/s3/config/foo-db.yml:
--------------------------------------------------------------------------------
1 | foo.db: mycooldb
2 |
--------------------------------------------------------------------------------
/examples/aws/s3/config/foo-dev.yml:
--------------------------------------------------------------------------------
1 | bar: spam
2 | foo: from foo development
3 | democonfigclient.message: hello from dev profile
4 |
--------------------------------------------------------------------------------
/examples/aws/s3/config/foo-development-db.yml:
--------------------------------------------------------------------------------
1 | combined: true
2 |
--------------------------------------------------------------------------------
/examples/aws/s3/config/foo-development.yml:
--------------------------------------------------------------------------------
1 | bar: spam
2 | foo: from foo development
3 |
--------------------------------------------------------------------------------
/examples/aws/s3/config/foo.yml:
--------------------------------------------------------------------------------
1 | foo: from foo props
2 | democonfigclient.message: hello spring io
3 |
--------------------------------------------------------------------------------
/examples/aws/s3/populate-s3.sh:
--------------------------------------------------------------------------------
1 | #!/bin/bash
2 | awslocal s3api create-bucket --bucket sample-bucket --region us-east-1
3 | awslocal s3api put-bucket-acl --bucket sample-bucket --acl public-read
4 | awslocal s3api get-bucket-acl --bucket sample-bucket
5 | awslocal s3 cp /data/config/foo.yml s3://sample-bucket/
6 | awslocal s3 cp /data/config/foo-db.yml s3://sample-bucket/
7 | awslocal s3 cp /data/config/foo-dev.yml s3://sample-bucket/
8 | awslocal s3 cp /data/config/foo-development.yml s3://sample-bucket/
9 | awslocal s3 cp /data/config/foo-development-db.yml s3://sample-bucket/
10 | awslocal s3 ls s3://sample-bucket/
--------------------------------------------------------------------------------
/examples/aws/secretsmanager/application.yml:
--------------------------------------------------------------------------------
1 | spring:
2 | cloud:
3 | config:
4 | server:
5 | aws-secretsmanager:
6 | endpoint: http://localhost.localstack.cloud:4566
7 | region: us-east-1
8 | profiles:
9 | active: awssecretsmanager
--------------------------------------------------------------------------------
/examples/aws/secretsmanager/compose.yml:
--------------------------------------------------------------------------------
1 | # Docker Compose example for testing AWS S3
2 |
3 | networks:
4 | aws:
5 |
6 | services:
7 | # Configured through environment variables
8 | config-server-env:
9 | depends_on:
10 | localstack:
11 | condition: service_healthy
12 | image: "${REGISTRY:-docker.io}/${IMAGE_NAME:-hyness/spring-cloud-config-server}:${TAG:-latest}"
13 | networks:
14 | - aws
15 | ports:
16 | - "8888"
17 | environment:
18 | AWS_ACCESS_KEY_ID: test
19 | AWS_SECRET_ACCESS_KEY: test
20 | SPRING_PROFILES_ACTIVE: awssecretsmanager
21 | SPRING_CLOUD_CONFIG_SERVER_AWSSECRETSMANAGER_ENDPOINT: http://localhost.localstack.cloud:4566
22 | SPRING_CLOUD_CONFIG_SERVER_AWSSECRETSMANAGER_REGION: us-east-1
23 |
24 | # Configured through mounted config file
25 | config-server-dir:
26 | depends_on:
27 | localstack:
28 | condition: service_healthy
29 | image: "${REGISTRY:-docker.io}/${IMAGE_NAME:-hyness/spring-cloud-config-server}:${TAG:-latest}"
30 | networks:
31 | - aws
32 | ports:
33 | - "8888"
34 | environment:
35 | AWS_ACCESS_KEY_ID: test
36 | AWS_SECRET_ACCESS_KEY: test
37 | volumes:
38 | - ./application.yml:/config/application.yml
39 |
40 | # Configured through system properties
41 | config-server-props:
42 | depends_on:
43 | localstack:
44 | condition: service_healthy
45 | image: "${REGISTRY:-docker.io}/${IMAGE_NAME:-hyness/spring-cloud-config-server}:${TAG:-latest}"
46 | networks:
47 | - aws
48 | ports:
49 | - "8888"
50 | environment:
51 | AWS_ACCESS_KEY_ID: test
52 | AWS_SECRET_ACCESS_KEY: test
53 | JAVA_OPTS: >
54 | -Dspring.profiles.active=awssecretsmanager
55 | -Dspring.cloud.config.server.aws-secretsmanager.endpoint=http://localhost.localstack.cloud:4566
56 | -Dspring.cloud.config.server.aws-secretsmanager.region=us-east-1
57 |
58 |
59 | # Configured through command line arguments
60 | config-server-args:
61 | depends_on:
62 | localstack:
63 | condition: service_healthy
64 | image: "${REGISTRY:-docker.io}/${IMAGE_NAME:-hyness/spring-cloud-config-server}:${TAG:-latest}"
65 | networks:
66 | - aws
67 | ports:
68 | - "8888"
69 | environment:
70 | AWS_ACCESS_KEY_ID: test
71 | AWS_SECRET_ACCESS_KEY: test
72 | command:
73 | - --spring.profiles.active=awssecretsmanager
74 | - --spring.cloud.config.server.aws-secretsmanager.endpoint=http://localhost.localstack.cloud:4566
75 | - --spring.cloud.config.server.aws-secretsmanager.region=us-east-1
76 |
77 | localstack:
78 | image: localstack/localstack:stable
79 | networks:
80 | aws:
81 | aliases:
82 | - localhost.localstack.cloud
83 | ports:
84 | - "4566:4566"
85 | - "4571:4571"
86 | environment:
87 | AWS_ACCESS_KEY_ID: test
88 | AWS_SECRET_ACCESS_KEY: test
89 | DEBUG: 1
90 | SERVICES: secretsmanager
91 | USE_SINGLE_REGION: 1
92 | healthcheck:
93 | test: ["CMD-SHELL", "awslocal secretsmanager list-secrets"]
94 | volumes:
95 | - ./populate-secretsmanager.sh:/data/populate-secretsmanager.sh
96 |
--------------------------------------------------------------------------------
/examples/aws/secretsmanager/populate-secretsmanager.sh:
--------------------------------------------------------------------------------
1 | #!/bin/bash
2 | awslocal secretsmanager create-secret --name /secret/application-default/ --secret-string '{"foo": "default"}'
3 | awslocal secretsmanager create-secret --name /secret/application-development/ --secret-string '{"bar": "default"}'
4 | awslocal secretsmanager create-secret --name /secret/foo-development/ --secret-string '{"foo": "bar", "bar": "foo"}'
5 |
--------------------------------------------------------------------------------
/examples/cloud-bus/kafka/compose.yml:
--------------------------------------------------------------------------------
1 | # Docker Compose example for testing Spring Cloud Bus Kafka
2 |
3 | services:
4 | # Configured through environment variables
5 | config-server-env:
6 | depends_on:
7 | - kafka
8 | image: "${REGISTRY:-docker.io}/${IMAGE_NAME:-hyness/spring-cloud-config-server}:${TAG:-latest}"
9 | networks:
10 | - app-tier
11 | ports:
12 | - "8888"
13 | environment:
14 | MANAGEMENT_ENDPOINTS_WEB_EXPOSURE_INCLUDE: "*"
15 | SPRING_PROFILES_ACTIVE: cloud-bus-kafka
16 | SPRING_CLOUD_CONFIG_SERVER_GIT_URI: https://github.com/spring-cloud-samples/config-repo
17 | SPRING_KAFKA_BOOTSTRAP-SERVERS: kafka:9092
18 |
19 | # Configured through mounted config volume
20 | config-server-dir:
21 | depends_on:
22 | - kafka
23 | image: "${REGISTRY:-docker.io}/${IMAGE_NAME:-hyness/spring-cloud-config-server}:${TAG:-latest}"
24 | networks:
25 | - app-tier
26 | ports:
27 | - "8888"
28 | volumes:
29 | - ./config:/config
30 |
31 | # Configured through system properties
32 | config-server-props:
33 | depends_on:
34 | - kafka
35 | image: "${REGISTRY:-docker.io}/${IMAGE_NAME:-hyness/spring-cloud-config-server}:${TAG:-latest}"
36 | networks:
37 | - app-tier
38 | ports:
39 | - "8888"
40 | environment:
41 | JAVA_OPTS: >
42 | -Dmanagement.endpoints.web.exposure.include=*
43 | -Dspring.profiles.active=cloud-bus-kafka
44 | -Dspring.cloud.config.server.git.uri=https://github.com/spring-cloud-samples/config-repo
45 | -Dspring.kafka.bootstrap-servers=kafka:9092
46 |
47 | # Configured through command line arguments
48 | config-server-args:
49 | depends_on:
50 | - kafka
51 | image: "${REGISTRY:-docker.io}/${IMAGE_NAME:-hyness/spring-cloud-config-server}:${TAG:-latest}"
52 | networks:
53 | - app-tier
54 | command:
55 | - --management.endpoints.web.exposure.include=*
56 | - --spring.profiles.active=cloud-bus-kafka
57 | - --spring.cloud.config.server.git.uri=https://github.com/spring-cloud-samples/config-repo
58 | - --spring.kafka.bootstrap-servers=kafka:9092
59 | ports:
60 | - "8888"
61 |
62 | kafka:
63 | image: bitnami/kafka:3.6
64 | networks:
65 | - app-tier
66 | ports:
67 | - "9092"
68 | environment:
69 | KAFKA_CFG_NODE_ID: 0
70 | KAFKA_CFG_PROCESS_ROLES: controller,broker
71 | KAFKA_CFG_LISTENERS: PLAINTEXT://:9092,CONTROLLER://:9093
72 | KAFKA_CFG_LISTENER_SECURITY_PROTOCOL_MAP: CONTROLLER:PLAINTEXT,PLAINTEXT:PLAINTEXT
73 | KAFKA_CFG_CONTROLLER_QUORUM_VOTERS: 0@kafka:9093
74 | KAFKA_CFG_CONTROLLER_LISTENER_NAMES: CONTROLLER
75 |
76 | networks:
77 | app-tier:
78 | driver: bridge
--------------------------------------------------------------------------------
/examples/cloud-bus/kafka/config/application.yml:
--------------------------------------------------------------------------------
1 | management:
2 | endpoints:
3 | web:
4 | exposure:
5 | include: "*"
6 | spring:
7 | cloud:
8 | config:
9 | server:
10 | git:
11 | uri: https://github.com/spring-cloud-samples/config-repo
12 | kafka:
13 | bootstrap-servers: kafka:9092
14 | profiles:
15 | active: cloud-bus-kafka
16 |
--------------------------------------------------------------------------------
/examples/cloud-bus/rabbit/compose.yml:
--------------------------------------------------------------------------------
1 | # Docker Compose example for testing Spring Cloud Bus Kafka
2 |
3 | services:
4 | # Configured through environment variables
5 | config-server-env:
6 | depends_on:
7 | - rabbitmq
8 | image: "${REGISTRY:-docker.io}/${IMAGE_NAME:-hyness/spring-cloud-config-server}:${TAG:-latest}"
9 | ports:
10 | - "8888"
11 | environment:
12 | MANAGEMENT_ENDPOINTS_WEB_EXPOSURE_INCLUDE: "*"
13 | SPRING_PROFILES_ACTIVE: cloud-bus-rabbit
14 | SPRING_CLOUD_CONFIG_SERVER_GIT_URI: https://github.com/spring-cloud-samples/config-repo
15 | SPRING_RABBITMQ_HOST: rabbitmq
16 |
17 | # Configured through mounted config volume
18 | config-server-dir:
19 | depends_on:
20 | - rabbitmq
21 | image: "${REGISTRY:-docker.io}/${IMAGE_NAME:-hyness/spring-cloud-config-server}:${TAG:-latest}"
22 | ports:
23 | - "8888"
24 | volumes:
25 | - ./config:/config
26 |
27 | # Configured through system properties
28 | config-server-props:
29 | depends_on:
30 | - rabbitmq
31 | image: "${REGISTRY:-docker.io}/${IMAGE_NAME:-hyness/spring-cloud-config-server}:${TAG:-latest}"
32 | ports:
33 | - "8888"
34 | environment:
35 | JAVA_OPTS: >
36 | -Dmanagement.endpoints.web.exposure.include=*
37 | -Dspring.profiles.active=cloud-bus-rabbit
38 | -Dspring.cloud.config.server.git.uri=https://github.com/spring-cloud-samples/config-repo
39 | -Dspring.rabbitmq.host=rabbitmq
40 |
41 | # Configured through command line arguments
42 | config-server-args:
43 | depends_on:
44 | - rabbitmq
45 | image: "${REGISTRY:-docker.io}/${IMAGE_NAME:-hyness/spring-cloud-config-server}:${TAG:-latest}"
46 | command:
47 | - --management.endpoints.web.exposure.include=*
48 | - --spring.profiles.active=cloud-bus-rabbit
49 | - --spring.cloud.config.server.git.uri=https://github.com/spring-cloud-samples/config-repo
50 | - --spring.rabbitmq.host=rabbitmq
51 | ports:
52 | - "8888"
53 |
54 | rabbitmq:
55 | image: rabbitmq
56 | ports:
57 | - "5672"
--------------------------------------------------------------------------------
/examples/cloud-bus/rabbit/config/application.yml:
--------------------------------------------------------------------------------
1 | management:
2 | endpoints:
3 | web:
4 | exposure:
5 | include: "*"
6 | spring:
7 | cloud:
8 | config:
9 | server:
10 | git:
11 | uri: https://github.com/spring-cloud-samples/config-repo
12 | rabbitmq:
13 | host: rabbitmq
14 | profiles:
15 | active: cloud-bus-rabbit
16 |
--------------------------------------------------------------------------------
/examples/git/compose.yml:
--------------------------------------------------------------------------------
1 | # Docker Compose example for testing a remote git repo
2 |
3 | services:
4 | # Configured through environment variables
5 | config-server-env:
6 | image: "${REGISTRY:-docker.io}/${IMAGE_NAME:-hyness/spring-cloud-config-server}:${TAG:-latest}"
7 | ports:
8 | - "8888"
9 | environment:
10 | SPRING_CLOUD_CONFIG_SERVER_GIT_URI: https://github.com/spring-cloud-samples/config-repo
11 | volumes:
12 | - ./config:/config
13 |
14 | # Configured through mounted config volume
15 | config-server-dir:
16 | image: "${REGISTRY:-docker.io}/${IMAGE_NAME:-hyness/spring-cloud-config-server}:${TAG:-latest}"
17 | ports:
18 | - "8888"
19 | volumes:
20 | - ./config:/config
21 |
22 | # Configured through system properties
23 | config-server-props:
24 | image: "${REGISTRY:-docker.io}/${IMAGE_NAME:-hyness/spring-cloud-config-server}:${TAG:-latest}"
25 | ports:
26 | - "8888"
27 | environment:
28 | JAVA_OPTS: -Dspring.cloud.config.server.git.uri=https://github.com/spring-cloud-samples/config-repo
29 |
30 | # Configured through command line arguments
31 | config-server-args:
32 | image: "${REGISTRY:-docker.io}/${IMAGE_NAME:-hyness/spring-cloud-config-server}:${TAG:-latest}"
33 | command: --spring.cloud.config.server.git.uri=https://github.com/spring-cloud-samples/config-repo
34 | ports:
35 | - "8888"
36 |
--------------------------------------------------------------------------------
/examples/git/config/application.yml:
--------------------------------------------------------------------------------
1 | spring:
2 | cloud:
3 | config:
4 | server:
5 | git:
6 | uri: https://github.com/spring-cloud-samples/config-repo
--------------------------------------------------------------------------------
/examples/healthcheck/compose.yml:
--------------------------------------------------------------------------------
1 | # Docker Compose example for testing a remote git repo
2 |
3 | services:
4 | # Configured through environment variables
5 | config-server-env:
6 | image: "${REGISTRY:-docker.io}/${IMAGE_NAME:-hyness/spring-cloud-config-server}:${TAG:-latest}"
7 | ports:
8 | - "8888"
9 | environment:
10 | SPRING_CLOUD_CONFIG_SERVER_GIT_URI: https://github.com/spring-cloud-samples/config-repo
11 | volumes:
12 | - ./config:/config
13 | healthcheck:
14 | test: ["CMD", "health-check"]
15 | start_interval: 30s
16 | interval: 5s
17 | retries: 10
--------------------------------------------------------------------------------
/examples/jdbc/mariadb/compose.yml:
--------------------------------------------------------------------------------
1 | # Docker Compose example for testing MySQL
2 |
3 | services:
4 | # Configured through environment variables
5 | config-server-env:
6 | depends_on:
7 | - mariadb
8 | image: "${REGISTRY:-docker.io}/${IMAGE_NAME:-hyness/spring-cloud-config-server}:${TAG:-latest}"
9 | ports:
10 | - "8888"
11 | environment:
12 | SPRING_PROFILES_ACTIVE: jdbc
13 | SPRING_CLOUD_CONFIG_SERVER_JDBC_SQL: SELECT `KEY`, VALUE from PROPERTIES where APPLICATION=? and PROFILE=? and LABEL=?
14 | SPRING_DATASOURCE_URL: jdbc:mariadb://mariadb:3306/cloud_config
15 | SPRING_DATASOURCE_USERNAME: root
16 |
17 | # Configured through mounted config volume
18 | config-server-dir:
19 | depends_on:
20 | - mariadb
21 | image: "${REGISTRY:-docker.io}/${IMAGE_NAME:-hyness/spring-cloud-config-server}:${TAG:-latest}"
22 | ports:
23 | - "8888"
24 | volumes:
25 | - ./config:/config
26 |
27 | # Configured through system properties
28 | config-server-props:
29 | depends_on:
30 | - mariadb
31 | image: "${REGISTRY:-docker.io}/${IMAGE_NAME:-hyness/spring-cloud-config-server}:${TAG:-latest}"
32 | ports:
33 | - "8888"
34 | environment:
35 | JAVA_OPTS: >
36 | -Dspring.profiles.active=jdbc
37 | -Dspring.datasource.url=jdbc:mariadb://mariadb:3306/cloud_config
38 | -Dspring.datasource.username=root
39 | -Dspring.cloud.config.server.jdbc.sql="SELECT `KEY`, VALUE from PROPERTIES where APPLICATION=? and PROFILE=? and LABEL=?"
40 |
41 | # Configured through command line arguments
42 | config-server-args:
43 | depends_on:
44 | - mariadb
45 | image: "${REGISTRY:-docker.io}/${IMAGE_NAME:-hyness/spring-cloud-config-server}:${TAG:-latest}"
46 | command:
47 | - --spring.profiles.active=jdbc
48 | - --spring.cloud.config.server.jdbc.sql=SELECT `KEY`, VALUE from PROPERTIES where APPLICATION=? and PROFILE=? and LABEL=?
49 | - --spring.datasource.url=jdbc:mariadb://mariadb:3306/cloud_config
50 | - --spring.datasource.username=root
51 | ports:
52 | - "8888"
53 |
54 | mariadb:
55 | image: mariadb
56 | ports:
57 | - "3306:3306"
58 | environment:
59 | MYSQL_DATABASE: cloud_config
60 | MYSQL_ALLOW_EMPTY_PASSWORD: "yes"
61 | volumes:
62 | - ./init-db.sql:/docker-entrypoint-initdb.d/init-db.sql
--------------------------------------------------------------------------------
/examples/jdbc/mariadb/config/application.yml:
--------------------------------------------------------------------------------
1 | spring:
2 | cloud:
3 | config:
4 | server:
5 | jdbc:
6 | sql: SELECT `key`, value from PROPERTIES where application=? and profile=? and label=?
7 | datasource:
8 | url: jdbc:mariadb://mariadb:3306/cloud_config
9 | username: root
10 | profiles:
11 | active: jdbc
12 |
--------------------------------------------------------------------------------
/examples/jdbc/mariadb/init-db.sql:
--------------------------------------------------------------------------------
1 | create table PROPERTIES(
2 | application varchar(256),
3 | profile varchar(256),
4 | label varchar(256),
5 | `key` varchar(256),
6 | value varchar(256)
7 | );
8 |
9 | insert into PROPERTIES values ('jdbc-app', 'dev', 'latest', 'sample key', 'a value');
--------------------------------------------------------------------------------
/examples/jdbc/postgres/compose.yml:
--------------------------------------------------------------------------------
1 | # Docker Compose example for testing Postgres
2 |
3 | services:
4 | # Configured through environment variables
5 | config-server-env:
6 | depends_on:
7 | - postgres
8 | image: "${REGISTRY:-docker.io}/${IMAGE_NAME:-hyness/spring-cloud-config-server}:${TAG:-latest}"
9 | ports:
10 | - "8888"
11 | environment:
12 | SPRING_PROFILES_ACTIVE: jdbc
13 | SPRING_CLOUD_CONFIG_SERVER_JDBC_SQL: "SELECT key, value from PROPERTIES where application=? and profile=? and label=?"
14 | SPRING_DATASOURCE_URL: jdbc:postgresql://postgres:5432/cloud_config
15 | SPRING_DATASOURCE_USERNAME: root
16 | SPRING_DATASOURCE_PASSWORD: password
17 |
18 | # Configured through mounted config volume
19 | config-server-dir:
20 | depends_on:
21 | - postgres
22 | image: "${REGISTRY:-docker.io}/${IMAGE_NAME:-hyness/spring-cloud-config-server}:${TAG:-latest}"
23 | ports:
24 | - "8888"
25 | volumes:
26 | - ./config:/config
27 |
28 | # Configured through system properties
29 | config-server-props:
30 | depends_on:
31 | - postgres
32 | image: "${REGISTRY:-docker.io}/${IMAGE_NAME:-hyness/spring-cloud-config-server}:${TAG:-latest}"
33 | ports:
34 | - "8888"
35 | environment:
36 | JAVA_OPTS: >
37 | -Dspring.profiles.active=jdbc
38 | -Dspring.cloud.config.server.jdbc.sql="SELECT key, value from PROPERTIES where application=? and profile=? and label=?"
39 | -Dspring.datasource.url=jdbc:postgresql://postgres:5432/cloud_config
40 | -Dspring.datasource.username=root
41 | -Dspring.datasource.password=password
42 |
43 | # Configured through command line arguments
44 | config-server-args:
45 | depends_on:
46 | - postgres
47 | image: "${REGISTRY:-docker.io}/${IMAGE_NAME:-hyness/spring-cloud-config-server}:${TAG:-latest}"
48 | command:
49 | - --spring.profiles.active=jdbc
50 | - --spring.datasource.url=jdbc:postgresql://postgres:5432/cloud_config
51 | - --spring.datasource.username=root
52 | - --spring.datasource.password=password
53 | - --spring.cloud.config.server.jdbc.sql=SELECT key, value from PROPERTIES where application=? and profile=? and label=?
54 | ports:
55 | - "8888"
56 |
57 | postgres:
58 | image: postgres
59 | ports:
60 | - "5432:5432"
61 | environment:
62 | POSTGRES_USER: root
63 | POSTGRES_PASSWORD: password
64 | POSTGRES_DB: cloud_config
65 | volumes:
66 | - .:/docker-entrypoint-initdb.d
67 |
--------------------------------------------------------------------------------
/examples/jdbc/postgres/config/application.yml:
--------------------------------------------------------------------------------
1 | spring:
2 | cloud:
3 | config:
4 | server:
5 | jdbc:
6 | sql: SELECT key, value from PROPERTIES where application=? and profile=? and label=?
7 | datasource:
8 | url: jdbc:postgresql://postgres:5432/cloud_config
9 | username: root
10 | password: password
11 | profiles:
12 | active: jdbc
13 |
--------------------------------------------------------------------------------
/examples/jdbc/postgres/init-db.sql:
--------------------------------------------------------------------------------
1 | create table properties(
2 | application varchar(256),
3 | profile varchar(256),
4 | label varchar(256),
5 | key varchar(256),
6 | value varchar(256)
7 | );
8 |
9 | insert into PROPERTIES values ('jdbc-app', 'dev', 'latest', 'sample key', 'a value');
--------------------------------------------------------------------------------
/examples/native/compose.yml:
--------------------------------------------------------------------------------
1 | # Docker Compose example for testing a native file system
2 |
3 | services:
4 | # Configured through environment variables
5 | config-server-env:
6 | image: "${REGISTRY:-docker.io}/${IMAGE_NAME:-hyness/spring-cloud-config-server}:${TAG:-latest}"
7 | ports:
8 | - "8888"
9 | environment:
10 | SPRING_PROFILES_ACTIVE: native
11 | SPRING_CLOUD_CONFIG_SERVER_NATIVE_SEARCHLOCATIONS: /native-files
12 | volumes:
13 | - ./native-files:/native-files
14 |
15 | # Configured through mounted config file
16 | config-server-dir:
17 | image: "${REGISTRY:-docker.io}/${IMAGE_NAME:-hyness/spring-cloud-config-server}:${TAG:-latest}"
18 | ports:
19 | - "8888"
20 | volumes:
21 | - ./config:/config
22 | - ./native-files:/native-files
23 |
24 | # Configured through system properties
25 | config-server-props:
26 | image: "${REGISTRY:-docker.io}/${IMAGE_NAME:-hyness/spring-cloud-config-server}:${TAG:-latest}"
27 | ports:
28 | - "8888"
29 | environment:
30 | JAVA_OPTS: -Dspring.profiles.active=native -Dspring.cloud.config.server.native.searchLocations=/native-files
31 | volumes:
32 | - ./native-files:/native-files
33 |
34 | # Configured through command line arguments
35 | config-server-args:
36 | image: "${REGISTRY:-docker.io}/${IMAGE_NAME:-hyness/spring-cloud-config-server}:${TAG:-latest}"
37 | ports:
38 | - "8888"
39 | command: --spring.profiles.active=native --spring.cloud.config.server.native.searchLocations=/native-files
40 | volumes:
41 | - ./native-files:/native-files
42 |
--------------------------------------------------------------------------------
/examples/native/config/application.yml:
--------------------------------------------------------------------------------
1 | spring:
2 | cloud:
3 | config:
4 | server:
5 | native:
6 | searchLocations: /native-files
7 | profiles:
8 | active: native
--------------------------------------------------------------------------------
/examples/native/native-files/aggregating.yml:
--------------------------------------------------------------------------------
1 | ingredients.threshold: 1000
2 |
--------------------------------------------------------------------------------
/examples/native/native-files/application-dev.yml:
--------------------------------------------------------------------------------
1 | my.prop: from application-dev.yml
2 |
--------------------------------------------------------------------------------
/examples/native/native-files/application.yaml:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/hyness/spring-cloud-config-server/e06c625f71067b6ad2e9075645a540f30d9aeb11/examples/native/native-files/application.yaml
--------------------------------------------------------------------------------
/examples/native/native-files/application.yml:
--------------------------------------------------------------------------------
1 | info:
2 | description: Spring Cloud Samples
3 | url: https://github.com/spring-cloud-samples
4 | eureka:
5 | client:
6 | serviceUrl:
7 | defaultZone: http://localhost:8761/eureka/
8 |
9 | foo: baz
10 |
11 | ---
12 | spring:
13 | config:
14 | activate-on:
15 | profile: cloud
16 | cloud:
17 | config:
18 | uri: ${vcap.services.${PREFIX:}configserver.credentials.uri:http://user:password@${PREFIX:}configserver.${application.domain:cfapps.io}}
19 | oauth2:
20 | client:
21 | tokenUri: ${vcap.services.${PREFIX:}sso.credentials.tokenUri:}
22 | authorizationUri: ${vcap.services.${PREFIX:}sso.credentials.authorizationUri:}
23 | clientId: ${vcap.services.${PREFIX:}sso.credentials.clientId:}
24 | clientSecret: ${vcap.services.${PREFIX:}sso.credentials.clientSecret:}
25 | resource:
26 | tokenInfoUri: ${vcap.services.${OAUTH2_RESOURCE_SERVICEID:${oauth2.resource.serviceId:sso}}.credentials.tokenInfoUri:}
27 | serviceId: ${PREFIX:}resource
28 | application:
29 | domain: ${APPLICATION_DOMAIN:cfapps.io}
30 | endpoints:
31 | restart: enabled
32 | eureka:
33 | password: password
34 | instance:
35 | hostname: ${vcap.application.uris[0]:localhost}
36 | nonSecurePort: 80
37 | client:
38 | serviceUrl:
39 | defaultZone: ${vcap.services.${PREFIX:}eureka.credentials.uri:http://user:${eureka.password:}@${PREFIX:}eureka.${application.domain:cfapps.io}}/eureka/
40 | hystrix.command.default.execution.isolation.thread.timeoutInMilliseconds: 60000
41 | ribbon:
42 | ConnectTimeout: 3000
43 | ReadTimeout: 60000
44 |
45 | ---
46 | spring:
47 | config:
48 | activate-on:
49 | profile: docker
50 | cloud:
51 | config:
52 | uri: http://${CONFIGSERVER_1_PORT_8888_TCP_ADDR:localhost}:8888
53 | endpoints:
54 | restart: enabled
55 | eureka:
56 | instance:
57 | nonSecurePort: 80
58 | preferIpAddress: true
59 | client:
60 | serviceUrl:
61 | defaultZone: http://${EUREKA_1_PORT_8761_TCP_ADDR:localhost}:8761/eureka/
62 |
63 |
--------------------------------------------------------------------------------
/examples/native/native-files/bar.properties:
--------------------------------------------------------------------------------
1 | foo: bar2
2 |
--------------------------------------------------------------------------------
/examples/native/native-files/books.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | Gambardella, Matthew
5 | XML Developer's Guide
6 | Computer
7 | 44.95
8 | 2000-10-01
9 | An in-depth look at creating applications
10 | with XML.
11 |
12 |
13 | Ralls, Kim
14 | Midnight Rain
15 | Fantasy
16 | 5.95
17 | 2000-12-16
18 | A former architect battles corporate zombies,
19 | an evil sorceress, and her own childhood to become queen
20 | of the world.
21 |
22 |
23 | Corets, Eva
24 | Maeve Ascendant
25 | Fantasy
26 | 5.95
27 | 2000-11-17
28 | After the collapse of a nanotechnology
29 | society in England, the young survivors lay the
30 | foundation for a new society.
31 |
32 |
33 | Corets, Eva
34 | Oberon's Legacy
35 | Fantasy
36 | 5.95
37 | 2001-03-10
38 | In post-apocalypse England, the mysterious
39 | agent known only as Oberon helps to create a new life
40 | for the inhabitants of London. Sequel to Maeve
41 | Ascendant.
42 |
43 |
44 | Corets, Eva
45 | The Sundered Grail
46 | Fantasy
47 | 5.95
48 | 2001-09-10
49 | The two daughters of Maeve, half-sisters,
50 | battle one another for control of England. Sequel to
51 | Oberon's Legacy.
52 |
53 |
54 | Randall, Cynthia
55 | Lover Birds
56 | Romance
57 | 4.95
58 | 2000-09-02
59 | When Carla meets Paul at an ornithology
60 | conference, tempers fly as feathers get ruffled.
61 |
62 |
63 | Thurman, Paula
64 | Splish Splash
65 | Romance
66 | 4.95
67 | 2000-11-02
68 | A deep sea diver finds true love twenty
69 | thousand leagues beneath the sea.
70 |
71 |
72 | Knorr, Stefan
73 | Creepy Crawlies
74 | Horror
75 | 4.95
76 | 2000-12-06
77 | An anthology of horror stories about roaches,
78 | centipedes, scorpions and other insects.
79 |
80 |
81 | Kress, Peter
82 | Paradox Lost
83 | Science Fiction
84 | 6.95
85 | 2000-11-02
86 | After an inadvertant trip through a Heisenberg
87 | Uncertainty Device, James Salway discovers the problems
88 | of being quantum.
89 |
90 |
91 | O'Brien, Tim
92 | Microsoft .NET: The Programming Bible
93 | Computer
94 | 36.95
95 | 2000-12-09
96 | Microsoft's .NET initiative is explored in
97 | detail in this deep programmer's reference.
98 |
99 |
100 | O'Brien, Tim
101 | MSXML3: A Comprehensive Guide
102 | Computer
103 | 36.95
104 | 2000-12-01
105 | The Microsoft MSXML3 parser is covered in
106 | detail, with attention to XML DOM interfaces, XSLT processing,
107 | SAX and more.
108 |
109 |
110 | Galos, Mike
111 | Visual Studio 7: A Comprehensive Guide
112 | Computer
113 | 49.95
114 | 2001-04-16
115 | Microsoft Visual Studio 7 is explored in depth,
116 | looking at how Visual Basic, Visual C++, C#, and ASP+ are
117 | integrated into a comprehensive development
118 | environment.
119 |
120 |
121 |
--------------------------------------------------------------------------------
/examples/native/native-files/configserver.yml:
--------------------------------------------------------------------------------
1 | info.description: configserver
2 | ---
3 | spring:
4 | profiles: cloud
5 | service:
6 | definition:
7 | metadata:
8 | uri: http://${spring.application.name}.${application.domain:cfapps.io}
9 |
--------------------------------------------------------------------------------
/examples/native/native-files/eureka.yml:
--------------------------------------------------------------------------------
1 | ---
2 | spring:
3 | profiles: cloudpeers
4 | eureka:
5 | client:
6 | serviceUrl:
7 | defaultZone: ${vcap.services.${PREFIX:}othereureka.credentials.uri:http://${PREFIX:}othereureka.${application.domain:cfapps.io}}/eureka/
8 |
9 | ---
10 | spring:
11 | profiles: docker
12 | eureka:
13 | client:
14 | serviceUrl:
15 | defaultZone: http://localhost:8761/eureka/
16 |
--------------------------------------------------------------------------------
/examples/native/native-files/foo-db.properties:
--------------------------------------------------------------------------------
1 | foo.db: mycooldb
2 |
--------------------------------------------------------------------------------
/examples/native/native-files/foo-dev.yml:
--------------------------------------------------------------------------------
1 | bar: spam
2 | foo: from foo development
3 | democonfigclient.message: hello from dev profile
4 |
--------------------------------------------------------------------------------
/examples/native/native-files/foo-development-db.properties:
--------------------------------------------------------------------------------
1 | combined: true
2 |
--------------------------------------------------------------------------------
/examples/native/native-files/foo-development.properties:
--------------------------------------------------------------------------------
1 | bar: spam
2 | foo: from foo development
3 |
--------------------------------------------------------------------------------
/examples/native/native-files/foo.properties:
--------------------------------------------------------------------------------
1 | foo: from foo props
2 | democonfigclient.message: hello spring io
3 |
--------------------------------------------------------------------------------
/examples/native/native-files/logtest.yml:
--------------------------------------------------------------------------------
1 | logging:
2 | level:
3 | com.example:
4 | foo: DEBUG
5 | bar: DEBUG
6 |
--------------------------------------------------------------------------------
/examples/native/native-files/processor.yml:
--------------------------------------------------------------------------------
1 | ---
2 | spring:
3 | profiles: cloud
4 | data:
5 | mongodb:
6 | uri: ${vcap.services.${PREFIX:}mongodb.credentials.uri}
7 | demo:
8 | baseUri: http://${eureka.instance.hostname}
--------------------------------------------------------------------------------
/examples/native/native-files/samplebackendservice-development.properties:
--------------------------------------------------------------------------------
1 | bar: spam
--------------------------------------------------------------------------------
/examples/native/native-files/samplebackendservice.properties:
--------------------------------------------------------------------------------
1 | foo: live from phoenix again
2 |
--------------------------------------------------------------------------------
/examples/native/native-files/samplefrontendservice.properties:
--------------------------------------------------------------------------------
1 | foo: bar2
2 | logging.level.org.springframework.web: DEBUG
3 |
--------------------------------------------------------------------------------
/examples/native/native-files/stores.yml:
--------------------------------------------------------------------------------
1 | foo: '{cipher}{key:test}AQCST0WVyBi2M5w1KWyzV6DNGXKBgk5Yd9QnbVv4rSj+7HhgsJh5gQTI/CZvV/wHZqYtYrGxJJ3TCdXc/gBP4dbkBDdOEJOq+u7UUqNTOd2693FgOp5CeoMREUOmLp9r0CtF4TZLdjZfs4kxiBPVPd5fEaz9ULIgtgLSdS2oUEg6UXr3LA/M7P8YchkEPYUyf+VxGUDe587XPffHMU4zmvhmoTSen9BAc5BuGK+FZ3GFe12MDEPkNQ0uY002FitEfmgON65Xh3eJtNxCbUXJTj+oDc0icePqOgnG0gc17MymZdcJCIhP+cCiS6LzS57vhP+xGZvBBBHnw00ZVzHX73UfKkC9GLsnEVVQO5Xf2COR/rGZqvLJNKgvSHcbf03PrhQ='
2 | ---
3 | spring:
4 | profiles: cloud
5 | data:
6 | mongodb:
7 | uri: ${vcap.services.${PREFIX:}mongodb.credentials.uri}
8 |
--------------------------------------------------------------------------------
/examples/native/native-files/subdir/test.txt:
--------------------------------------------------------------------------------
1 | This is text served from a subdirectory
2 |
--------------------------------------------------------------------------------
/examples/native/native-files/test.json:
--------------------------------------------------------------------------------
1 | [
2 | {
3 | "_id": "56f051673a6f1037be9a3ccb",
4 | "index": 0,
5 | "guid": "2b403b4b-8b4f-4bf4-8fc0-c957e9c92596",
6 | "isActive": true,
7 | "balance": "$2,210.39",
8 | "picture": "http://placehold.it/32x32",
9 | "age": 25,
10 | "eyeColor": "blue",
11 | "name": {
12 | "first": "Audra",
13 | "last": "Mendez"
14 | },
15 | "company": "NEXGENE",
16 | "email": "audra.mendez@nexgene.io",
17 | "phone": "+1 (812) 461-2870",
18 | "address": "715 Ebony Court, Logan, New Hampshire, 9176",
19 | "about": "Sit deserunt nulla nulla incididunt et dolor anim eiusmod exercitation. Dolore dolor elit laborum aliquip esse amet id. Est ipsum sit voluptate duis cillum ut tempor ipsum pariatur adipisicing sunt. Consequat officia ut tempor id et reprehenderit et veniam ullamco anim qui sint aliquip tempor. Cillum laborum veniam ullamco enim consectetur veniam quis dolor nostrud officia.",
20 | "registered": "Tuesday, February 18, 2014 6:54 PM",
21 | "latitude": "-54.035224",
22 | "longitude": "-18.578621",
23 | "tags": [
24 | 7,
25 | "irure"
26 | ],
27 | "range": [
28 | 0,
29 | 1,
30 | 2,
31 | 3,
32 | 4,
33 | 5,
34 | 6,
35 | 7,
36 | 8,
37 | 9
38 | ],
39 | "friends": [
40 | 3,
41 | {
42 | "id": 1,
43 | "name": "Hillary Hutchinson"
44 | }
45 | ],
46 | "greeting": "Hello, Audra! You have 9 unread messages.",
47 | "favoriteFruit": "apple"
48 | },
49 | {
50 | "_id": "56f0516768d43b3ea3b7561f",
51 | "index": 1,
52 | "guid": "cbc8e72f-511b-406b-b3c8-d44a5ea78f2f",
53 | "isActive": true,
54 | "balance": "$3,096.58",
55 | "picture": "http://placehold.it/32x32",
56 | "age": 26,
57 | "eyeColor": "blue",
58 | "name": {
59 | "first": "Merle",
60 | "last": "Wooten"
61 | },
62 | "company": "EDECINE",
63 | "email": "merle.wooten@edecine.ca",
64 | "phone": "+1 (842) 447-2285",
65 | "address": "142 Hendrix Street, Bartley, Arizona, 5777",
66 | "about": "Ea sunt veniam labore qui ad. Sint nisi aliqua laborum dolor do voluptate cupidatat eu. Enim deserunt anim excepteur enim labore et nostrud elit consectetur excepteur nostrud aliquip dolor adipisicing. Irure aliquip incididunt proident culpa.",
67 | "registered": "Thursday, April 10, 2014 4:58 AM",
68 | "latitude": "-8.395754",
69 | "longitude": "75.771414",
70 | "tags": [
71 | 7,
72 | "irure"
73 | ],
74 | "range": [
75 | 0,
76 | 1,
77 | 2,
78 | 3,
79 | 4,
80 | 5,
81 | 6,
82 | 7,
83 | 8,
84 | 9
85 | ],
86 | "friends": [
87 | 3,
88 | {
89 | "id": 1,
90 | "name": "Hillary Hutchinson"
91 | }
92 | ],
93 | "greeting": "Hello, Merle! You have 5 unread messages.",
94 | "favoriteFruit": "strawberry"
95 | },
96 | {
97 | "_id": "56f05167d299eab579202f1e",
98 | "index": 2,
99 | "guid": "46f24b5b-f8e3-486b-8b3a-0b0784f513d9",
100 | "isActive": true,
101 | "balance": "$3,437.48",
102 | "picture": "http://placehold.it/32x32",
103 | "age": 39,
104 | "eyeColor": "green",
105 | "name": {
106 | "first": "Lupe",
107 | "last": "Lewis"
108 | },
109 | "company": "HOMELUX",
110 | "email": "lupe.lewis@homelux.me",
111 | "phone": "+1 (877) 548-3554",
112 | "address": "146 Terrace Place, Derwood, Pennsylvania, 2599",
113 | "about": "Aute sint id aliqua ipsum consectetur exercitation nisi. Minim ex laborum eu do. Sunt laborum enim deserunt culpa aliqua eu consectetur.",
114 | "registered": "Sunday, April 12, 2015 2:47 PM",
115 | "latitude": "-45.907896",
116 | "longitude": "-128.202572",
117 | "tags": [
118 | 7,
119 | "irure"
120 | ],
121 | "range": [
122 | 0,
123 | 1,
124 | 2,
125 | 3,
126 | 4,
127 | 5,
128 | 6,
129 | 7,
130 | 8,
131 | 9
132 | ],
133 | "friends": [
134 | 3,
135 | {
136 | "id": 1,
137 | "name": "Hillary Hutchinson"
138 | }
139 | ],
140 | "greeting": "Hello, Lupe! You have 5 unread messages.",
141 | "favoriteFruit": "strawberry"
142 | },
143 | {
144 | "_id": "56f05167aaf3df75213406b1",
145 | "index": 3,
146 | "guid": "c9f2570b-76c5-4326-809e-fb7797e0d1cc",
147 | "isActive": false,
148 | "balance": "$1,543.14",
149 | "picture": "http://placehold.it/32x32",
150 | "age": 34,
151 | "eyeColor": "blue",
152 | "name": {
153 | "first": "Swanson",
154 | "last": "Mccarthy"
155 | },
156 | "company": "MITROC",
157 | "email": "swanson.mccarthy@mitroc.co.uk",
158 | "phone": "+1 (954) 466-3219",
159 | "address": "420 Merit Court, Frystown, Oregon, 4940",
160 | "about": "Culpa incididunt adipisicing nostrud velit in veniam officia. Consequat voluptate mollit tempor eu velit aliqua commodo nulla nisi irure. Velit non incididunt amet proident deserunt officia velit cillum. Non exercitation veniam commodo deserunt Lorem velit incididunt ullamco dolor eu est consectetur. Commodo aliqua in minim minim eu. Labore sunt non aute tempor elit ut tempor deserunt.",
161 | "registered": "Thursday, November 19, 2015 5:44 PM",
162 | "latitude": "29.438056",
163 | "longitude": "-5.197729",
164 | "tags": [
165 | 7,
166 | "irure"
167 | ],
168 | "range": [
169 | 0,
170 | 1,
171 | 2,
172 | 3,
173 | 4,
174 | 5,
175 | 6,
176 | 7,
177 | 8,
178 | 9
179 | ],
180 | "friends": [
181 | 3,
182 | {
183 | "id": 1,
184 | "name": "Hillary Hutchinson"
185 | }
186 | ],
187 | "greeting": "Hello, Swanson! You have 10 unread messages.",
188 | "favoriteFruit": "banana"
189 | },
190 | {
191 | "_id": "56f051675b6417531450dd6f",
192 | "index": 4,
193 | "guid": "40b284d8-00a3-4778-8215-4781e3ed5df3",
194 | "isActive": true,
195 | "balance": "$2,520.39",
196 | "picture": "http://placehold.it/32x32",
197 | "age": 24,
198 | "eyeColor": "blue",
199 | "name": {
200 | "first": "Casey",
201 | "last": "Dotson"
202 | },
203 | "company": "IMKAN",
204 | "email": "casey.dotson@imkan.biz",
205 | "phone": "+1 (853) 506-2464",
206 | "address": "881 Sedgwick Street, Goodville, Hawaii, 7857",
207 | "about": "Officia exercitation aliqua anim deserunt sint. Elit incididunt laboris deserunt dolor sit veniam Lorem. Laboris anim non ad sint pariatur veniam cupidatat. Enim in quis reprehenderit ex amet laboris ea tempor. Labore laboris voluptate ipsum tempor sunt esse velit ex nisi. Minim sit pariatur Lorem elit occaecat.",
208 | "registered": "Saturday, August 15, 2015 8:30 PM",
209 | "latitude": "-58.150569",
210 | "longitude": "164.512045",
211 | "tags": [
212 | 7,
213 | "irure"
214 | ],
215 | "range": [
216 | 0,
217 | 1,
218 | 2,
219 | 3,
220 | 4,
221 | 5,
222 | 6,
223 | 7,
224 | 8,
225 | 9
226 | ],
227 | "friends": [
228 | 3,
229 | {
230 | "id": 1,
231 | "name": "Hillary Hutchinson"
232 | }
233 | ],
234 | "greeting": "Hello, Casey! You have 10 unread messages.",
235 | "favoriteFruit": "apple"
236 | }
237 | ]
238 |
--------------------------------------------------------------------------------
/examples/native/native-files/text-resource.txt:
--------------------------------------------------------------------------------
1 | Hello Toronto
2 |
--------------------------------------------------------------------------------
/examples/native/native-files/zuul.properties:
--------------------------------------------------------------------------------
1 | zuul.route.samplebackendservice=/hello
2 | zuul.route.samplefrontendservice=/
3 | zuul.route.hystrixdashboard=/hystrix-dashboard
4 |
--------------------------------------------------------------------------------
/examples/prometheus/compose.yml:
--------------------------------------------------------------------------------
1 | # Docker Compose example for testing a remote git repo
2 |
3 | services:
4 | # Configured through environment variables
5 | config-server-env:
6 | image: ${REGISTRY:-docker.io}/${IMAGE_NAME:-hyness/spring-cloud-config-server}:${TAG:-latest}
7 | ports:
8 | - "8888"
9 | environment:
10 | MANAGEMENT_ENDPOINT_PROMETHEUS_ENABLED: "true"
11 | MANAGEMENT_ENDPOINTS_WEB_EXPOSURE_INCLUDE: health,prometheus
12 | SPRING_CLOUD_CONFIG_SERVER_GIT_URI: https://github.com/spring-cloud-samples/config-repo
13 |
14 | # Configured through mounted config volume
15 | config-server-dir:
16 | image: ${REGISTRY:-docker.io}/${IMAGE_NAME:-hyness/spring-cloud-config-server}:${TAG:-latest}
17 | ports:
18 | - "8888"
19 | volumes:
20 | - ./config:/config
21 |
22 | # Configured through system properties
23 | config-server-props:
24 | image: ${REGISTRY:-docker.io}/${IMAGE_NAME:-hyness/spring-cloud-config-server}:${TAG:-latest}
25 | ports:
26 | - "8888"
27 | environment:
28 | JAVA_OPTS: >
29 | -Dmanagement.endpoint.prometheus.enabled=true
30 | -Dmanagement.endpoints.web.exposure.include=health,prometheus
31 | -Dspring.cloud.config.server.git.uri=https://github.com/spring-cloud-samples/config-repo
32 |
33 | # Configured through command line arguments
34 | config-server-args:
35 | image: ${REGISTRY:-docker.io}/${IMAGE_NAME:-hyness/spring-cloud-config-server}:${TAG:-latest}
36 | ports:
37 | - "8888"
38 | command:
39 | - --management.endpoint.prometheus.enabled=true
40 | - --management.endpoints.web.exposure.include=health,prometheus
41 | - --spring.cloud.config.server.git.uri=https://github.com/spring-cloud-samples/config-repo
42 |
--------------------------------------------------------------------------------
/examples/prometheus/config/application.yml:
--------------------------------------------------------------------------------
1 | management:
2 | endpoints:
3 | web:
4 | exposure:
5 | include: health,prometheus
6 | spring:
7 | cloud:
8 | config:
9 | server:
10 | git:
11 | default-label: main
12 | uri: https://github.com/spring-cloud-samples/config-repo
--------------------------------------------------------------------------------
/examples/redis/compose.yml:
--------------------------------------------------------------------------------
1 | # Docker Compose example for testing a redis backed repo
2 |
3 | services:
4 | # Configured through environment variables
5 | config-server-env:
6 | depends_on:
7 | - redis
8 | image: "${REGISTRY:-docker.io}/${IMAGE_NAME:-hyness/spring-cloud-config-server}:${TAG:-latest}"
9 | ports:
10 | - "8888"
11 | environment:
12 | SPRING_PROFILES_ACTIVE: redis
13 | SPRING_DATA_REDIS_HOST: redis
14 |
15 | # Configured through mounted config volume
16 | config-server-dir:
17 | depends_on:
18 | - redis
19 | image: "${REGISTRY:-docker.io}/${IMAGE_NAME:-hyness/spring-cloud-config-server}:${TAG:-latest}"
20 | ports:
21 | - "8888"
22 | volumes:
23 | - ./config:/config
24 |
25 | # Configured through system properties
26 | config-server-props:
27 | depends_on:
28 | - redis
29 | image: "${REGISTRY:-docker.io}/${IMAGE_NAME:-hyness/spring-cloud-config-server}:${TAG:-latest}"
30 | ports:
31 | - "8888"
32 | environment:
33 | JAVA_OPTS: >
34 | -Dspring.profiles.active=redis
35 | -Dspring.data.redis.host=redis
36 |
37 | # Configured through command line arguments
38 | config-server-args:
39 | depends_on:
40 | - redis
41 | image: "${REGISTRY:-docker.io}/${IMAGE_NAME:-hyness/spring-cloud-config-server}:${TAG:-latest}"
42 | ports:
43 | - "8888"
44 | command:
45 | - --spring.profiles.active=redis
46 | - --spring.data.redis.host=redis
47 |
48 | redis:
49 | image: redis:alpine
50 | ports:
51 | - "6379:6379"
52 | volumes:
53 | - ./populate-redis.sh:/data/populate-redis.sh
54 |
--------------------------------------------------------------------------------
/examples/redis/config/application.yml:
--------------------------------------------------------------------------------
1 | spring:
2 | data:
3 | redis:
4 | host: redis
5 | profiles:
6 | active: redis
7 |
--------------------------------------------------------------------------------
/examples/redis/populate-redis.sh:
--------------------------------------------------------------------------------
1 | #!/bin/bash
2 | echo 'HMSET redis-app-development server.port "8100" redis.topic.name "test" test.property1 "property1"' | redis-cli
3 |
--------------------------------------------------------------------------------
/examples/security/compose.yml:
--------------------------------------------------------------------------------
1 | # Docker Compose example for testing security with a remote git repo
2 |
3 | services:
4 | # Configured through environment variables
5 | config-server-env:
6 | image: "${REGISTRY:-docker.io}/${IMAGE_NAME:-hyness/spring-cloud-config-server}:${TAG:-latest}"
7 | ports:
8 | - "8888"
9 | environment:
10 | ENCRYPT_KEY: vprxxl5blpycu3kt8602
11 | SPRING_CLOUD_CONFIG_SERVER_GIT_URI: https://github.com/spring-cloud-samples/config-repo
12 | SPRING_PROFILES_ACTIVE: git,security
13 | SPRING_SECURITY_USER_NAME: user
14 | SPRING_SECURITY_USER_PASSWORD: password
15 | volumes:
16 | - ./config:/config
17 |
18 | # Configured through mounted config volume
19 | config-server-dir:
20 | image: "${REGISTRY:-docker.io}/${IMAGE_NAME:-hyness/spring-cloud-config-server}:${TAG:-latest}"
21 | ports:
22 | - "8888"
23 | volumes:
24 | - ./config:/config
25 |
26 | # Configured through system properties
27 | config-server-props:
28 | image: "${REGISTRY:-docker.io}/${IMAGE_NAME:-hyness/spring-cloud-config-server}:${TAG:-latest}"
29 | ports:
30 | - "8888"
31 | environment:
32 | JAVA_OPTS: >
33 | -Dencrypt.key=vprxxl5blpycu3kt8602
34 | -Dspring.cloud.config.server.git.uri=https://github.com/spring-cloud-samples/config-repo
35 | -Dspring.profiles.active=git,security
36 | -Dspring_security.user.name=user
37 | -Dspring.security.user.password=password
38 |
39 | # Configured through command line arguments
40 | config-server-args:
41 | image: "${REGISTRY:-docker.io}/${IMAGE_NAME:-hyness/spring-cloud-config-server}:${TAG:-latest}"
42 | ports:
43 | - "8888"
44 | command:
45 | - --encrypt.key=vprxxl5blpycu3kt8602
46 | - --spring.cloud.config.server.git.uri=https://github.com/spring-cloud-samples/config-repo
47 | - --spring.profiles.active=git,security
48 | - --spring_security.user.name=user
49 | - --spring.security.user.password=password
50 |
--------------------------------------------------------------------------------
/examples/security/config/application.yml:
--------------------------------------------------------------------------------
1 | encrypt:
2 | key: vprxxl5blpycu3kt8602
3 | spring:
4 | cloud:
5 | config:
6 | server:
7 | git:
8 | uri: https://github.com/spring-cloud-samples/config-repo
9 | profiles:
10 | active: git,security
11 | security:
12 | user:
13 | name: user
14 | password: password
--------------------------------------------------------------------------------
/examples/vault/compose.yml:
--------------------------------------------------------------------------------
1 | # Docker Compose example for testing Vault
2 |
3 | services:
4 | # Configured through environment variables
5 | config-server-env:
6 | depends_on:
7 | - vault
8 | image: "${REGISTRY:-docker.io}/${IMAGE_NAME:-hyness/spring-cloud-config-server}:${TAG:-latest}"
9 | ports:
10 | - "8888"
11 | environment:
12 | SPRING_PROFILES_ACTIVE: vault
13 | SPRING_CLOUD_CONFIG_SERVER_VAULT_TOKEN: 00000000-0000-0000-0000-000000000000
14 | SPRING_CLOUD_CONFIG_SERVER_VAULT_HOST: vault
15 | SPRING_CLOUD_CONFIG_SERVER_VAULT_KV_VERSION: 2
16 |
17 | # Configured through mounted config volume
18 | config-server-dir:
19 | depends_on:
20 | - vault
21 | image: "${REGISTRY:-docker.io}/${IMAGE_NAME:-hyness/spring-cloud-config-server}:${TAG:-latest}"
22 | ports:
23 | - "8888"
24 | volumes:
25 | - ./config:/config
26 |
27 | # Configured through system properties
28 | config-server-props:
29 | depends_on:
30 | - vault
31 | image: "${REGISTRY:-docker.io}/${IMAGE_NAME:-hyness/spring-cloud-config-server}:${TAG:-latest}"
32 | ports:
33 | - "8888"
34 | environment:
35 | JAVA_OPTS: >
36 | -Dspring.profiles.active=vault
37 | -Dspring.cloud.config.server.vault.token=00000000-0000-0000-0000-000000000000
38 | -Dspring.cloud.config.server.vault.host=vault
39 | -Dspring.cloud.config.server.vault.kv-version=2
40 |
41 | # Configured through command line arguments
42 | config-server-args:
43 | depends_on:
44 | - vault
45 | image: "${REGISTRY:-docker.io}/${IMAGE_NAME:-hyness/spring-cloud-config-server}:${TAG:-latest}"
46 | ports:
47 | - "8888"
48 | command:
49 | - --spring.profiles.active=vault
50 | - --spring.cloud.config.server.vault.token=00000000-0000-0000-0000-000000000000
51 | - --spring.cloud.config.server.vault.host=vault
52 | - --spring.cloud.config.server.vault.kv-version=2
53 |
54 | vault:
55 | privileged: true
56 | image: hashicorp/vault
57 | ports:
58 | - "8200:8200"
59 | environment:
60 | - VAULT_DEV_ROOT_TOKEN_ID=00000000-0000-0000-0000-000000000000
61 | - VAULT_TOKEN=00000000-0000-0000-0000-000000000000
62 | - VAULT_ADDR=http://127.0.0.1:8200
63 | volumes:
64 | - ./populate-vault.sh:/data/populate-vault.sh
65 |
--------------------------------------------------------------------------------
/examples/vault/config/application.yml:
--------------------------------------------------------------------------------
1 | spring:
2 | cloud:
3 | config:
4 | server:
5 | vault:
6 | token: 00000000-0000-0000-0000-000000000000
7 | host: vault
8 | kv-version: 2
9 | profiles:
10 | active: vault
11 |
--------------------------------------------------------------------------------
/examples/vault/populate-vault.sh:
--------------------------------------------------------------------------------
1 | #!/bin/bash
2 | vault kv put secret/application foo=bar baz=bam
3 | vault kv put secret/myapp foo=myappsbar
4 |
--------------------------------------------------------------------------------
/gradle.properties:
--------------------------------------------------------------------------------
1 | jdkVersion = 17
2 | jvmType = jre
3 | dockerUsername = user
4 | dockerPassword = password
5 |
--------------------------------------------------------------------------------
/gradle/libs.versions.toml:
--------------------------------------------------------------------------------
1 | [versions]
2 | aws = "2.17.195"
3 | aws-msk-iam-auth = "2.3.0"
4 | kotlin = "1.9.25"
5 | kotlin-logging = "7.0.4"
6 | spring-boot = "3.4.4"
7 | spring-cloud = "2024.0.1"
8 | spring-cloud-config = "4.2.2"
9 |
10 | [plugins]
11 | kotlin-jvm = { id = "org.jetbrains.kotlin.jvm", version.ref = "kotlin" }
12 | kotlin-plugin-spring = { id = "org.jetbrains.kotlin.plugin.spring", version.ref = "kotlin" }
13 | spring-boot = { id = "org.springframework.boot", version.ref = "spring-boot" }
14 |
15 | [bundles]
16 | aws = ["aws-msk-iam-auth", "aws-s3", "aws-secretsmanager", "aws-ssm", "aws-sts"]
17 | jdbc-drivers = ["jdbc-driver-firebird", "jdbc-driver-hikari", "jdbc-driver-mariadb", "jdbc-driver-mssql", "jdbc-driver-postgres"]
18 | kotlin = ["kotlin-reflect", "kotlin-stdlib"]
19 | spring-cloud-bus = ["spring-cloud-bus", "spring-cloud-bus-kafka", "spring-cloud-bus-amqp"]
20 | spring-cloud-config = ["spring-cloud-config-server", "spring-cloud-config-monitor"]
21 |
22 | [libraries]
23 | aws-msk-iam-auth = { module = "software.amazon.msk:aws-msk-iam-auth", version.ref = "aws-msk-iam-auth" }
24 | aws-s3 = { module = "software.amazon.awssdk:s3", version.ref = "aws" }
25 | aws-secretsmanager = { module = "software.amazon.awssdk:secretsmanager", version.ref = "aws" }
26 | aws-ssm = { module = "software.amazon.awssdk:ssm", version.ref = "aws" }
27 | aws-sts = { module = "software.amazon.awssdk:sts", version.ref = "aws" }
28 | awaitility-kotlin = { module = "org.awaitility:awaitility-kotlin" }
29 | jdbc-driver-firebird = { module = "org.firebirdsql.jdbc:jaybird" }
30 | jdbc-driver-hikari = { module = "com.zaxxer:HikariCP" }
31 | jdbc-driver-mariadb = { module = "org.mariadb.jdbc:mariadb-java-client" }
32 | jdbc-driver-mssql = { module = "com.microsoft.sqlserver:mssql-jdbc" }
33 | jdbc-driver-postgres = { module = "org.postgresql:postgresql" }
34 | kotlin-logging = { module = "io.github.oshai:kotlin-logging-jvm", version.ref = "kotlin-logging" }
35 | kotlin-reflect = { module = "org.jetbrains.kotlin:kotlin-reflect" }
36 | kotlin-stdlib = { module = "org.jetbrains.kotlin:kotlin-stdlib" }
37 | micrometer-prometheus = { module = "io.micrometer:micrometer-registry-prometheus" }
38 | spring-boot-actuator = { module = "org.springframework.boot:spring-boot-starter-actuator" }
39 | spring-boot-security = { module = "org.springframework.boot:spring-boot-starter-security" }
40 | spring-boot-test = { module = "org.springframework.boot:spring-boot-starter-test" }
41 | spring-boot-testcontainers = { module = "org.springframework.boot:spring-boot-testcontainers" }
42 | spring-data-redis = { module = "org.springframework.boot:spring-boot-starter-data-redis" }
43 | spring-cloud = { module = "org.springframework.cloud:spring-cloud-dependencies", version.ref = "spring-cloud" }
44 | spring-cloud-bus = { module = "org.springframework.cloud:spring-cloud-bus" }
45 | spring-cloud-bus-amqp = { module = "org.springframework.cloud:spring-cloud-starter-bus-amqp" }
46 | spring-cloud-bus-kafka = { module = "org.springframework.cloud:spring-cloud-starter-bus-kafka" }
47 | spring-cloud-config-monitor = { module = "org.springframework.cloud:spring-cloud-config-monitor", version.ref = "spring-cloud-config" }
48 | spring-cloud-config-server = { module = "org.springframework.cloud:spring-cloud-config-server", version.ref = "spring-cloud-config" }
49 | spring-jdbc = { module = "org.springframework:spring-jdbc" }
50 | spring-vault = { module = "org.springframework.vault:spring-vault-core" }
51 | testcontainers-junit5 = { module = "org.testcontainers:junit-jupiter" }
--------------------------------------------------------------------------------
/gradle/wrapper/gradle-wrapper.jar:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/hyness/spring-cloud-config-server/e06c625f71067b6ad2e9075645a540f30d9aeb11/gradle/wrapper/gradle-wrapper.jar
--------------------------------------------------------------------------------
/gradle/wrapper/gradle-wrapper.properties:
--------------------------------------------------------------------------------
1 | distributionBase=GRADLE_USER_HOME
2 | distributionPath=wrapper/dists
3 | distributionUrl=https\://services.gradle.org/distributions/gradle-8.13-bin.zip
4 | networkTimeout=10000
5 | validateDistributionUrl=true
6 | zipStoreBase=GRADLE_USER_HOME
7 | zipStorePath=wrapper/dists
8 |
--------------------------------------------------------------------------------
/gradlew:
--------------------------------------------------------------------------------
1 | #!/bin/sh
2 |
3 | #
4 | # Copyright © 2015-2021 the original authors.
5 | #
6 | # Licensed under the Apache License, Version 2.0 (the "License");
7 | # you may not use this file except in compliance with the License.
8 | # You may obtain a copy of the License at
9 | #
10 | # https://www.apache.org/licenses/LICENSE-2.0
11 | #
12 | # Unless required by applicable law or agreed to in writing, software
13 | # distributed under the License is distributed on an "AS IS" BASIS,
14 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15 | # See the License for the specific language governing permissions and
16 | # limitations under the License.
17 | #
18 | # SPDX-License-Identifier: Apache-2.0
19 | #
20 |
21 | ##############################################################################
22 | #
23 | # Gradle start up script for POSIX generated by Gradle.
24 | #
25 | # Important for running:
26 | #
27 | # (1) You need a POSIX-compliant shell to run this script. If your /bin/sh is
28 | # noncompliant, but you have some other compliant shell such as ksh or
29 | # bash, then to run this script, type that shell name before the whole
30 | # command line, like:
31 | #
32 | # ksh Gradle
33 | #
34 | # Busybox and similar reduced shells will NOT work, because this script
35 | # requires all of these POSIX shell features:
36 | # * functions;
37 | # * expansions «$var», «${var}», «${var:-default}», «${var+SET}»,
38 | # «${var#prefix}», «${var%suffix}», and «$( cmd )»;
39 | # * compound commands having a testable exit status, especially «case»;
40 | # * various built-in commands including «command», «set», and «ulimit».
41 | #
42 | # Important for patching:
43 | #
44 | # (2) This script targets any POSIX shell, so it avoids extensions provided
45 | # by Bash, Ksh, etc; in particular arrays are avoided.
46 | #
47 | # The "traditional" practice of packing multiple parameters into a
48 | # space-separated string is a well documented source of bugs and security
49 | # problems, so this is (mostly) avoided, by progressively accumulating
50 | # options in "$@", and eventually passing that to Java.
51 | #
52 | # Where the inherited environment variables (DEFAULT_JVM_OPTS, JAVA_OPTS,
53 | # and GRADLE_OPTS) rely on word-splitting, this is performed explicitly;
54 | # see the in-line comments for details.
55 | #
56 | # There are tweaks for specific operating systems such as AIX, CygWin,
57 | # Darwin, MinGW, and NonStop.
58 | #
59 | # (3) This script is generated from the Groovy template
60 | # https://github.com/gradle/gradle/blob/HEAD/platforms/jvm/plugins-application/src/main/resources/org/gradle/api/internal/plugins/unixStartScript.txt
61 | # within the Gradle project.
62 | #
63 | # You can find Gradle at https://github.com/gradle/gradle/.
64 | #
65 | ##############################################################################
66 |
67 | # Attempt to set APP_HOME
68 |
69 | # Resolve links: $0 may be a link
70 | app_path=$0
71 |
72 | # Need this for daisy-chained symlinks.
73 | while
74 | APP_HOME=${app_path%"${app_path##*/}"} # leaves a trailing /; empty if no leading path
75 | [ -h "$app_path" ]
76 | do
77 | ls=$( ls -ld "$app_path" )
78 | link=${ls#*' -> '}
79 | case $link in #(
80 | /*) app_path=$link ;; #(
81 | *) app_path=$APP_HOME$link ;;
82 | esac
83 | done
84 |
85 | # This is normally unused
86 | # shellcheck disable=SC2034
87 | APP_BASE_NAME=${0##*/}
88 | # Discard cd standard output in case $CDPATH is set (https://github.com/gradle/gradle/issues/25036)
89 | APP_HOME=$( cd -P "${APP_HOME:-./}" > /dev/null && printf '%s\n' "$PWD" ) || exit
90 |
91 | # Use the maximum available, or set MAX_FD != -1 to use that value.
92 | MAX_FD=maximum
93 |
94 | warn () {
95 | echo "$*"
96 | } >&2
97 |
98 | die () {
99 | echo
100 | echo "$*"
101 | echo
102 | exit 1
103 | } >&2
104 |
105 | # OS specific support (must be 'true' or 'false').
106 | cygwin=false
107 | msys=false
108 | darwin=false
109 | nonstop=false
110 | case "$( uname )" in #(
111 | CYGWIN* ) cygwin=true ;; #(
112 | Darwin* ) darwin=true ;; #(
113 | MSYS* | MINGW* ) msys=true ;; #(
114 | NONSTOP* ) nonstop=true ;;
115 | esac
116 |
117 | CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar
118 |
119 |
120 | # Determine the Java command to use to start the JVM.
121 | if [ -n "$JAVA_HOME" ] ; then
122 | if [ -x "$JAVA_HOME/jre/sh/java" ] ; then
123 | # IBM's JDK on AIX uses strange locations for the executables
124 | JAVACMD=$JAVA_HOME/jre/sh/java
125 | else
126 | JAVACMD=$JAVA_HOME/bin/java
127 | fi
128 | if [ ! -x "$JAVACMD" ] ; then
129 | die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME
130 |
131 | Please set the JAVA_HOME variable in your environment to match the
132 | location of your Java installation."
133 | fi
134 | else
135 | JAVACMD=java
136 | if ! command -v java >/dev/null 2>&1
137 | then
138 | die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
139 |
140 | Please set the JAVA_HOME variable in your environment to match the
141 | location of your Java installation."
142 | fi
143 | fi
144 |
145 | # Increase the maximum file descriptors if we can.
146 | if ! "$cygwin" && ! "$darwin" && ! "$nonstop" ; then
147 | case $MAX_FD in #(
148 | max*)
149 | # In POSIX sh, ulimit -H is undefined. That's why the result is checked to see if it worked.
150 | # shellcheck disable=SC2039,SC3045
151 | MAX_FD=$( ulimit -H -n ) ||
152 | warn "Could not query maximum file descriptor limit"
153 | esac
154 | case $MAX_FD in #(
155 | '' | soft) :;; #(
156 | *)
157 | # In POSIX sh, ulimit -n is undefined. That's why the result is checked to see if it worked.
158 | # shellcheck disable=SC2039,SC3045
159 | ulimit -n "$MAX_FD" ||
160 | warn "Could not set maximum file descriptor limit to $MAX_FD"
161 | esac
162 | fi
163 |
164 | # Collect all arguments for the java command, stacking in reverse order:
165 | # * args from the command line
166 | # * the main class name
167 | # * -classpath
168 | # * -D...appname settings
169 | # * --module-path (only if needed)
170 | # * DEFAULT_JVM_OPTS, JAVA_OPTS, and GRADLE_OPTS environment variables.
171 |
172 | # For Cygwin or MSYS, switch paths to Windows format before running java
173 | if "$cygwin" || "$msys" ; then
174 | APP_HOME=$( cygpath --path --mixed "$APP_HOME" )
175 | CLASSPATH=$( cygpath --path --mixed "$CLASSPATH" )
176 |
177 | JAVACMD=$( cygpath --unix "$JAVACMD" )
178 |
179 | # Now convert the arguments - kludge to limit ourselves to /bin/sh
180 | for arg do
181 | if
182 | case $arg in #(
183 | -*) false ;; # don't mess with options #(
184 | /?*) t=${arg#/} t=/${t%%/*} # looks like a POSIX filepath
185 | [ -e "$t" ] ;; #(
186 | *) false ;;
187 | esac
188 | then
189 | arg=$( cygpath --path --ignore --mixed "$arg" )
190 | fi
191 | # Roll the args list around exactly as many times as the number of
192 | # args, so each arg winds up back in the position where it started, but
193 | # possibly modified.
194 | #
195 | # NB: a `for` loop captures its iteration list before it begins, so
196 | # changing the positional parameters here affects neither the number of
197 | # iterations, nor the values presented in `arg`.
198 | shift # remove old arg
199 | set -- "$@" "$arg" # push replacement arg
200 | done
201 | fi
202 |
203 |
204 | # Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
205 | DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"'
206 |
207 | # Collect all arguments for the java command:
208 | # * DEFAULT_JVM_OPTS, JAVA_OPTS, and optsEnvironmentVar are not allowed to contain shell fragments,
209 | # and any embedded shellness will be escaped.
210 | # * For example: A user cannot expect ${Hostname} to be expanded, as it is an environment variable and will be
211 | # treated as '${Hostname}' itself on the command line.
212 |
213 | set -- \
214 | "-Dorg.gradle.appname=$APP_BASE_NAME" \
215 | -classpath "$CLASSPATH" \
216 | org.gradle.wrapper.GradleWrapperMain \
217 | "$@"
218 |
219 | # Stop when "xargs" is not available.
220 | if ! command -v xargs >/dev/null 2>&1
221 | then
222 | die "xargs is not available"
223 | fi
224 |
225 | # Use "xargs" to parse quoted args.
226 | #
227 | # With -n1 it outputs one arg per line, with the quotes and backslashes removed.
228 | #
229 | # In Bash we could simply go:
230 | #
231 | # readarray ARGS < <( xargs -n1 <<<"$var" ) &&
232 | # set -- "${ARGS[@]}" "$@"
233 | #
234 | # but POSIX shell has neither arrays nor command substitution, so instead we
235 | # post-process each arg (as a line of input to sed) to backslash-escape any
236 | # character that might be a shell metacharacter, then use eval to reverse
237 | # that process (while maintaining the separation between arguments), and wrap
238 | # the whole thing up as a single "set" statement.
239 | #
240 | # This will of course break if any of these variables contains a newline or
241 | # an unmatched quote.
242 | #
243 |
244 | eval "set -- $(
245 | printf '%s\n' "$DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS" |
246 | xargs -n1 |
247 | sed ' s~[^-[:alnum:]+,./:=@_]~\\&~g; ' |
248 | tr '\n' ' '
249 | )" '"$@"'
250 |
251 | exec "$JAVACMD" "$@"
252 |
--------------------------------------------------------------------------------
/gradlew.bat:
--------------------------------------------------------------------------------
1 | @rem
2 | @rem Copyright 2015 the original author or authors.
3 | @rem
4 | @rem Licensed under the Apache License, Version 2.0 (the "License");
5 | @rem you may not use this file except in compliance with the License.
6 | @rem You may obtain a copy of the License at
7 | @rem
8 | @rem https://www.apache.org/licenses/LICENSE-2.0
9 | @rem
10 | @rem Unless required by applicable law or agreed to in writing, software
11 | @rem distributed under the License is distributed on an "AS IS" BASIS,
12 | @rem WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | @rem See the License for the specific language governing permissions and
14 | @rem limitations under the License.
15 | @rem
16 | @rem SPDX-License-Identifier: Apache-2.0
17 | @rem
18 |
19 | @if "%DEBUG%"=="" @echo off
20 | @rem ##########################################################################
21 | @rem
22 | @rem Gradle startup script for Windows
23 | @rem
24 | @rem ##########################################################################
25 |
26 | @rem Set local scope for the variables with windows NT shell
27 | if "%OS%"=="Windows_NT" setlocal
28 |
29 | set DIRNAME=%~dp0
30 | if "%DIRNAME%"=="" set DIRNAME=.
31 | @rem This is normally unused
32 | set APP_BASE_NAME=%~n0
33 | set APP_HOME=%DIRNAME%
34 |
35 | @rem Resolve any "." and ".." in APP_HOME to make it shorter.
36 | for %%i in ("%APP_HOME%") do set APP_HOME=%%~fi
37 |
38 | @rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
39 | set DEFAULT_JVM_OPTS="-Xmx64m" "-Xms64m"
40 |
41 | @rem Find java.exe
42 | if defined JAVA_HOME goto findJavaFromJavaHome
43 |
44 | set JAVA_EXE=java.exe
45 | %JAVA_EXE% -version >NUL 2>&1
46 | if %ERRORLEVEL% equ 0 goto execute
47 |
48 | echo. 1>&2
49 | echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. 1>&2
50 | echo. 1>&2
51 | echo Please set the JAVA_HOME variable in your environment to match the 1>&2
52 | echo location of your Java installation. 1>&2
53 |
54 | goto fail
55 |
56 | :findJavaFromJavaHome
57 | set JAVA_HOME=%JAVA_HOME:"=%
58 | set JAVA_EXE=%JAVA_HOME%/bin/java.exe
59 |
60 | if exist "%JAVA_EXE%" goto execute
61 |
62 | echo. 1>&2
63 | echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME% 1>&2
64 | echo. 1>&2
65 | echo Please set the JAVA_HOME variable in your environment to match the 1>&2
66 | echo location of your Java installation. 1>&2
67 |
68 | goto fail
69 |
70 | :execute
71 | @rem Setup the command line
72 |
73 | set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar
74 |
75 |
76 | @rem Execute Gradle
77 | "%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %*
78 |
79 | :end
80 | @rem End local scope for the variables with windows NT shell
81 | if %ERRORLEVEL% equ 0 goto mainEnd
82 |
83 | :fail
84 | rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of
85 | rem the _cmd.exe /c_ return code!
86 | set EXIT_CODE=%ERRORLEVEL%
87 | if %EXIT_CODE% equ 0 set EXIT_CODE=1
88 | if not ""=="%GRADLE_EXIT_CONSOLE%" exit %EXIT_CODE%
89 | exit /b %EXIT_CODE%
90 |
91 | :mainEnd
92 | if "%OS%"=="Windows_NT" endlocal
93 |
94 | :omega
95 |
--------------------------------------------------------------------------------
/project.toml:
--------------------------------------------------------------------------------
1 | [[build.env]]
2 | NAME="BPE_DELIM_JAVA_TOOL_OPTIONS"
3 | VALUE=" "
4 |
5 | [[build.env]]
6 | NAME="BPE_PREPEND_JAVA_TOOL_OPTIONS"
7 | VALUE="-Dserver.port=8888 -Dspring.config.name=application -Dspring.config.additional-location=optional:file:/config/ -Dspring.cloud.config.server.native.searchLocations=classpath:/,classpath:/config,file:./,file:./config,file:/config"
8 |
--------------------------------------------------------------------------------
/src/main/kotlin/org/freshlegacycode/cloud/config/server/ConfigServerApplication.kt:
--------------------------------------------------------------------------------
1 | package org.freshlegacycode.cloud.config.server
2 |
3 | import org.springframework.boot.actuate.autoconfigure.security.servlet.EndpointRequest
4 | import org.springframework.boot.actuate.autoconfigure.security.servlet.ManagementWebSecurityAutoConfiguration
5 | import org.springframework.boot.actuate.autoconfigure.web.server.ManagementContextAutoConfiguration
6 | import org.springframework.boot.actuate.health.HealthEndpoint
7 | import org.springframework.boot.autoconfigure.SpringBootApplication
8 | import org.springframework.boot.autoconfigure.amqp.RabbitAutoConfiguration
9 | import org.springframework.boot.autoconfigure.data.redis.RedisAutoConfiguration
10 | import org.springframework.boot.autoconfigure.jdbc.DataSourceAutoConfiguration
11 | import org.springframework.boot.autoconfigure.kafka.KafkaAutoConfiguration
12 | import org.springframework.boot.autoconfigure.security.servlet.SecurityAutoConfiguration
13 | import org.springframework.boot.context.properties.ConfigurationProperties
14 | import org.springframework.boot.context.properties.EnableConfigurationProperties
15 | import org.springframework.boot.runApplication
16 | import org.springframework.cloud.bus.*
17 | import org.springframework.cloud.bus.jackson.BusJacksonAutoConfiguration
18 | import org.springframework.cloud.config.monitor.EnvironmentMonitorAutoConfiguration
19 | import org.springframework.cloud.config.server.EnableConfigServer
20 | import org.springframework.context.annotation.Bean
21 | import org.springframework.context.annotation.Configuration
22 | import org.springframework.context.annotation.Import
23 | import org.springframework.context.annotation.Profile
24 | import org.springframework.security.config.annotation.web.builders.HttpSecurity
25 | import org.springframework.security.config.annotation.web.invoke
26 | import org.springframework.security.web.SecurityFilterChain
27 | import org.springframework.cloud.stream.binder.kafka.config.ExtendedBindingHandlerMappingsProviderConfiguration as KafkaBinderAutoConfiguration
28 | import org.springframework.cloud.stream.binder.rabbit.config.ExtendedBindingHandlerMappingsProviderConfiguration as RabbitBinderAutoConfiguration
29 |
30 | @EnableConfigServer
31 | @SpringBootApplication(exclude = [
32 | DataSourceAutoConfiguration::class,
33 | RedisAutoConfiguration::class,
34 | ManagementContextAutoConfiguration::class,
35 | ManagementWebSecurityAutoConfiguration::class,
36 | SecurityAutoConfiguration::class,
37 | RabbitBinderAutoConfiguration::class,
38 | KafkaBinderAutoConfiguration::class,
39 | BusAutoConfiguration::class,
40 | PathServiceMatcherAutoConfiguration::class,
41 | BusAutoConfiguration::class,
42 | BusRefreshAutoConfiguration::class,
43 | BusShutdownAutoConfiguration::class,
44 | BusStreamAutoConfiguration::class,
45 | BusJacksonAutoConfiguration::class,
46 | EnvironmentMonitorAutoConfiguration::class,
47 | KafkaAutoConfiguration::class,
48 | RabbitAutoConfiguration::class,
49 | ])
50 | class ConfigServerApplication
51 |
52 | @Profile("!no-actuator")
53 | @Configuration
54 | @Import(ManagementContextAutoConfiguration::class)
55 | internal class ActuatorBackendConfiguration
56 |
57 | @Profile("jdbc")
58 | @Configuration
59 | @Import(DataSourceAutoConfiguration::class)
60 | internal class JdbcBackendConfiguration
61 |
62 | @Profile("cloud-bus-kafka")
63 | @Configuration
64 | @Import(KafkaAutoConfiguration::class, KafkaBinderAutoConfiguration::class)
65 | internal class CloudBusKafkaConfiguration : CloudBusConfiguration()
66 |
67 | @Profile("cloud-bus-rabbit")
68 | @Configuration
69 | @Import(RabbitAutoConfiguration::class, RabbitBinderAutoConfiguration::class)
70 | internal class CloudBusRabbitConfiguration : CloudBusConfiguration()
71 |
72 | @Import(BusAutoConfiguration::class,
73 | BusRefreshAutoConfiguration::class,
74 | BusShutdownAutoConfiguration::class,
75 | BusStreamAutoConfiguration::class,
76 | BusJacksonAutoConfiguration::class,
77 | PathServiceMatcherAutoConfiguration::class,
78 | EnvironmentMonitorAutoConfiguration::class)
79 | internal abstract class CloudBusConfiguration
80 |
81 | @Profile("redis")
82 | @Configuration
83 | @Import(RedisAutoConfiguration::class)
84 | internal class RedisBackendConfiguration
85 |
86 | @Profile("security")
87 | @Configuration
88 | @Import(SecurityAutoConfiguration::class, ManagementWebSecurityAutoConfiguration::class)
89 | internal class SecurityConfiguration
90 |
91 | @Profile("security")
92 | @Configuration
93 | @EnableConfigurationProperties(ConfigServerSecurityProperties::class)
94 | class ConfigServerSecurityConfiguration(val properties: ConfigServerSecurityProperties) {
95 | @Bean
96 | fun securityFilterChain(http: HttpSecurity): SecurityFilterChain {
97 | http {
98 | authorizeHttpRequests {
99 | authorize(EndpointRequest.to(HealthEndpoint::class.java), permitAll)
100 | properties.allowedPaths.forEach {
101 | authorize(it, permitAll)
102 | }
103 | authorize(anyRequest, authenticated)
104 | }
105 | formLogin {}
106 | httpBasic {}
107 | csrf {
108 | disable()
109 | }
110 | }
111 | return http.build()
112 | }
113 | }
114 |
115 | @ConfigurationProperties("spring.cloud.config.security")
116 | data class ConfigServerSecurityProperties(val allowedPaths: List = listOf())
117 |
118 | fun main(args: Array) {
119 | runApplication(*args)
120 | }
121 |
--------------------------------------------------------------------------------
/src/main/resources/application.yaml:
--------------------------------------------------------------------------------
1 | server:
2 | port: 8888
3 | ---
4 | spring:
5 | cloud:
6 | stream:
7 | defaultBinder: rabbit
8 | config:
9 | activate:
10 | on-profile: cloud-bus-rabbit
11 | ---
12 | spring:
13 | cloud:
14 | stream:
15 | defaultBinder: kafka
16 | config:
17 | activate:
18 | on-profile: cloud-bus-kafka
19 |
--------------------------------------------------------------------------------
/src/test/kotlin/org/freshlegacycode/cloud/config/server/AwsParamStoreBackendTest.kt:
--------------------------------------------------------------------------------
1 | package org.freshlegacycode.cloud.config.server
2 |
3 | import org.assertj.core.api.Assertions.assertThat
4 | import org.freshlegacycode.cloud.config.server.ConfigServerApplicationTests.Companion.containerTimeout
5 | import org.freshlegacycode.cloud.config.server.ConfigServerApplicationTests.Companion.logConsumer
6 | import org.freshlegacycode.cloud.config.server.ConfigServerApplicationTests.Companion.logger
7 | import org.junit.jupiter.api.BeforeAll
8 | import org.junit.jupiter.api.Tag
9 | import org.junit.jupiter.api.Tags
10 | import org.junit.jupiter.params.ParameterizedTest
11 | import org.junit.jupiter.params.provider.EnumSource
12 | import org.springframework.http.MediaType.APPLICATION_JSON
13 | import org.springframework.test.web.reactive.server.WebTestClient
14 | import org.testcontainers.containers.ComposeContainer
15 | import org.testcontainers.containers.wait.strategy.Wait
16 | import org.testcontainers.junit.jupiter.Container
17 | import org.testcontainers.junit.jupiter.Testcontainers
18 | import kotlin.jvm.optionals.getOrNull
19 |
20 | @Testcontainers
21 | @Tags(Tag("integration"), Tag("aws"), Tag("aws-param-store"))
22 | class AwsParamStoreBackendTest {
23 | @EnumSource
24 | @ParameterizedTest
25 | internal fun `given a config server, when configured with aws parameter store backend, is valid`(type: ContainerConfigurationType) {
26 | logger.info { "Verifying ${type.label}" }
27 | val webClient = WebTestClient.bindToServer()
28 | .baseUrl(cloudConfigContainer.getUrl(type))
29 | .responseTimeout(containerTimeout)
30 | .build()
31 |
32 | webClient.get()
33 | .uri("/foo/development")
34 | .accept(APPLICATION_JSON)
35 | .exchange()
36 | .expectStatus().isOk
37 | .expectHeader().contentType(APPLICATION_JSON)
38 | .expectBody()
39 | .jsonPath("$.name").isEqualTo("foo")
40 | .jsonPath("$.propertySources[0].name").isEqualTo("aws:ssm:parameter:/config/foo-development/")
41 | }
42 |
43 | companion object {
44 | @Container
45 | val cloudConfigContainer: ComposeContainer = "examples/aws/paramstore/compose.yml".toComposeContainer()
46 | .withExposedService("localstack", 4566, Wait.forHealthcheck())
47 | .withLogConsumer("localstack", logConsumer)
48 |
49 | @JvmStatic
50 | @BeforeAll
51 | internal fun populateData() {
52 | logger.info { "Populating test data" }
53 | val execResult = (cloudConfigContainer.getContainerByServiceName("localstack")
54 | .getOrNull()
55 | ?.execInContainer("sh", "/data/populate-paramstore.sh")
56 | ?: throw RuntimeException("Could not populate paramstore test data"))
57 |
58 | assertThat(execResult.exitCode).isZero()
59 | }
60 | }
61 | }
--------------------------------------------------------------------------------
/src/test/kotlin/org/freshlegacycode/cloud/config/server/AwsS3BackendTest.kt:
--------------------------------------------------------------------------------
1 | package org.freshlegacycode.cloud.config.server
2 |
3 | import org.assertj.core.api.Assertions.assertThat
4 | import org.freshlegacycode.cloud.config.server.ConfigServerApplicationTests.Companion.containerTimeout
5 | import org.freshlegacycode.cloud.config.server.ConfigServerApplicationTests.Companion.logConsumer
6 | import org.freshlegacycode.cloud.config.server.ConfigServerApplicationTests.Companion.logger
7 | import org.junit.jupiter.api.BeforeAll
8 | import org.junit.jupiter.api.Disabled
9 | import org.junit.jupiter.api.Tag
10 | import org.junit.jupiter.api.Tags
11 | import org.junit.jupiter.params.ParameterizedTest
12 | import org.junit.jupiter.params.provider.EnumSource
13 | import org.springframework.http.MediaType.APPLICATION_JSON
14 | import org.springframework.test.web.reactive.server.WebTestClient
15 | import org.testcontainers.containers.ComposeContainer
16 | import org.testcontainers.containers.wait.strategy.Wait
17 | import org.testcontainers.junit.jupiter.Container
18 | import org.testcontainers.junit.jupiter.Testcontainers
19 | import kotlin.jvm.optionals.getOrNull
20 |
21 | @Disabled("Test flakes in ci only")
22 | @Testcontainers
23 | @Tags(Tag("integration"), Tag("aws"), Tag("aws-s3"))
24 | class AwsS3BackendTest {
25 |
26 | @EnumSource
27 | @ParameterizedTest
28 | internal fun `given a config server, when configured with aws s3 backend, is valid`(type: ContainerConfigurationType) {
29 | logger.info { "Verifying ${type.label}" }
30 | val webClient = WebTestClient.bindToServer()
31 | .baseUrl(cloudConfigContainer.getUrl(type))
32 | .responseTimeout(containerTimeout)
33 | .build()
34 |
35 | webClient.get()
36 | .uri("/foo/development")
37 | .accept(APPLICATION_JSON)
38 | .exchange()
39 | .expectStatus().isOk
40 | .expectHeader().contentType(APPLICATION_JSON)
41 | .expectBody()
42 | .jsonPath("$.name").isEqualTo("foo")
43 | .jsonPath("$.propertySources[0].name").isEqualTo("s3:foo-development")
44 | }
45 |
46 | companion object {
47 | @Container
48 | val cloudConfigContainer: ComposeContainer = "examples/aws/s3/compose.yml".toComposeContainer()
49 | .withExposedService("localstack", 4566, Wait.forHealthcheck())
50 | .withLogConsumer("localstack", logConsumer)
51 |
52 | @JvmStatic
53 | @BeforeAll
54 | internal fun populateData() {
55 | logger.info { "Populating test data" }
56 | val execResult = (cloudConfigContainer.getContainerByServiceName("localstack")
57 | .getOrNull()
58 | ?.execInContainer("sh", "/data/populate-s3.sh")
59 | ?: throw RuntimeException("Could not populate s3 test data"))
60 |
61 | assertThat(execResult.exitCode).isZero()
62 | }
63 | }
64 | }
--------------------------------------------------------------------------------
/src/test/kotlin/org/freshlegacycode/cloud/config/server/AwsSecretsManagerBackendTest.kt:
--------------------------------------------------------------------------------
1 | package org.freshlegacycode.cloud.config.server
2 |
3 | import org.assertj.core.api.Assertions.assertThat
4 | import org.freshlegacycode.cloud.config.server.ConfigServerApplicationTests.Companion.containerTimeout
5 | import org.freshlegacycode.cloud.config.server.ConfigServerApplicationTests.Companion.logConsumer
6 | import org.freshlegacycode.cloud.config.server.ConfigServerApplicationTests.Companion.logger
7 | import org.junit.jupiter.api.BeforeAll
8 | import org.junit.jupiter.api.Tag
9 | import org.junit.jupiter.api.Tags
10 | import org.junit.jupiter.params.ParameterizedTest
11 | import org.junit.jupiter.params.provider.EnumSource
12 | import org.springframework.http.MediaType.APPLICATION_JSON
13 | import org.springframework.test.web.reactive.server.WebTestClient
14 | import org.testcontainers.containers.ComposeContainer
15 | import org.testcontainers.containers.wait.strategy.Wait
16 | import org.testcontainers.junit.jupiter.Container
17 | import org.testcontainers.junit.jupiter.Testcontainers
18 | import kotlin.jvm.optionals.getOrNull
19 |
20 | @Testcontainers
21 | @Tags(Tag("integration"), Tag("aws"), Tag("aws-secrets-manager"))
22 | class AwsSecretsManagerBackendTest {
23 |
24 | @EnumSource
25 | @ParameterizedTest
26 | internal fun `given a config server, when configured with aws secrets manager backend, is valid`(type: ContainerConfigurationType) {
27 | logger.info { "Verifying ${type.label}" }
28 | val webClient = WebTestClient.bindToServer()
29 | .baseUrl(cloudConfigContainer.getUrl(type))
30 | .responseTimeout(containerTimeout)
31 | .build()
32 |
33 | webClient.get()
34 | .uri("/foo/development")
35 | .accept(APPLICATION_JSON)
36 | .exchange()
37 | .expectStatus().isOk
38 | .expectHeader().contentType(APPLICATION_JSON)
39 | .expectBody()
40 | .jsonPath("$.name").isEqualTo("foo")
41 | .jsonPath("$.propertySources[0].name").isEqualTo("aws:secrets:/secret/foo-development/")
42 | }
43 |
44 | companion object {
45 | @Container
46 | val cloudConfigContainer: ComposeContainer = "examples/aws/secretsmanager/compose.yml".toComposeContainer()
47 | .withExposedService("localstack",4566, Wait.forHealthcheck())
48 | .withLogConsumer("localstack", logConsumer)
49 |
50 | @JvmStatic
51 | @BeforeAll
52 | internal fun populateData() {
53 | logger.info { "Populating test data" }
54 | val execResult = (cloudConfigContainer.getContainerByServiceName("localstack")
55 | .getOrNull()
56 | ?.execInContainer("sh", "/data/populate-secretsmanager.sh")
57 | ?: throw RuntimeException("Could not populate secretsmanager test data"))
58 |
59 | assertThat(execResult.exitCode).isZero()
60 | }
61 | }
62 | }
--------------------------------------------------------------------------------
/src/test/kotlin/org/freshlegacycode/cloud/config/server/CloudBusKafkaRemoteGitBackendTest.kt:
--------------------------------------------------------------------------------
1 | package org.freshlegacycode.cloud.config.server
2 |
3 | import org.freshlegacycode.cloud.config.server.ConfigServerApplicationTests.Companion.containerTimeout
4 | import org.freshlegacycode.cloud.config.server.ConfigServerApplicationTests.Companion.logger
5 | import org.junit.jupiter.api.Tag
6 | import org.junit.jupiter.api.Tags
7 | import org.junit.jupiter.params.ParameterizedTest
8 | import org.junit.jupiter.params.provider.EnumSource
9 | import org.springframework.http.MediaType.APPLICATION_JSON
10 | import org.springframework.test.web.reactive.server.WebTestClient
11 | import org.testcontainers.junit.jupiter.Container
12 | import org.testcontainers.junit.jupiter.Testcontainers
13 |
14 | @Testcontainers
15 | @Tags(Tag("integration"), Tag("cloud-bus"),Tag("kafka"), Tag("cloud-bus-kafka"))
16 | class CloudBusKafkaRemoteGitBackendTest {
17 | @EnumSource
18 | @ParameterizedTest
19 | internal fun `given a config server, when configured with cloud bus and remote git backend, is valid`(type: ContainerConfigurationType) {
20 | logger.info { "Verifying ${type.label}" }
21 | val webClient = WebTestClient.bindToServer()
22 | .baseUrl(cloudConfigContainer.getUrl(type))
23 | .responseTimeout(containerTimeout)
24 | .build()
25 |
26 | webClient.get()
27 | .uri("/foo/development")
28 | .accept(APPLICATION_JSON)
29 | .exchange()
30 | .expectStatus().isOk
31 | .expectHeader().contentType(APPLICATION_JSON)
32 | .expectBody()
33 | .consumeWith {
34 | println(it)
35 | }
36 | .jsonPath("$.name").isEqualTo("foo")
37 | .jsonPath("$.propertySources[0].name").isEqualTo("https://github.com/spring-cloud-samples/config-repo/foo-development.properties")
38 | }
39 |
40 | companion object {
41 | @Container
42 | val cloudConfigContainer = "examples/cloud-bus/kafka/compose.yml".toComposeContainer().apply {
43 | withExposedService("kafka", 9092)
44 | }
45 | }
46 | }
--------------------------------------------------------------------------------
/src/test/kotlin/org/freshlegacycode/cloud/config/server/CloudBusRabbitRemoteGitBackendTest.kt:
--------------------------------------------------------------------------------
1 | package org.freshlegacycode.cloud.config.server
2 |
3 | import org.freshlegacycode.cloud.config.server.ConfigServerApplicationTests.Companion.containerTimeout
4 | import org.freshlegacycode.cloud.config.server.ConfigServerApplicationTests.Companion.logger
5 | import org.junit.jupiter.api.Tag
6 | import org.junit.jupiter.api.Tags
7 | import org.junit.jupiter.params.ParameterizedTest
8 | import org.junit.jupiter.params.provider.EnumSource
9 | import org.springframework.http.MediaType.APPLICATION_JSON
10 | import org.springframework.test.web.reactive.server.WebTestClient
11 | import org.testcontainers.junit.jupiter.Container
12 | import org.testcontainers.junit.jupiter.Testcontainers
13 |
14 | @Testcontainers
15 | @Tags(Tag("integration"), Tag("cloud-bus"), Tag("rabbitmq"), Tag("cloud-bus-rabbitmq"))
16 | class CloudBusRabbitRemoteGitBackendTest {
17 | @EnumSource
18 | @ParameterizedTest
19 | internal fun `given a config server, when configured with cloud bus and remote git backend, is valid`(type: ContainerConfigurationType) {
20 | logger.info { "Verifying ${type.label}" }
21 | val webClient = WebTestClient.bindToServer()
22 | .baseUrl(cloudConfigContainer.getUrl(type))
23 | .responseTimeout(containerTimeout)
24 | .build()
25 |
26 | webClient.get()
27 | .uri("/foo/development")
28 | .accept(APPLICATION_JSON)
29 | .exchange()
30 | .expectStatus().isOk
31 | .expectHeader().contentType(APPLICATION_JSON)
32 | .expectBody()
33 | .consumeWith {
34 | println(it)
35 | }
36 | .jsonPath("$.name").isEqualTo("foo")
37 | .jsonPath("$.propertySources[0].name").isEqualTo("https://github.com/spring-cloud-samples/config-repo/foo-development.properties")
38 | }
39 |
40 | companion object {
41 | @Container
42 | val cloudConfigContainer = "examples/cloud-bus/rabbit/compose.yml".toComposeContainer().apply {
43 | withExposedService("rabbitmq", 5672)
44 | }
45 | }
46 | }
--------------------------------------------------------------------------------
/src/test/kotlin/org/freshlegacycode/cloud/config/server/ConfigServerApplicationTests.kt:
--------------------------------------------------------------------------------
1 | package org.freshlegacycode.cloud.config.server
2 |
3 | import io.github.oshai.kotlinlogging.KotlinLogging
4 | import org.freshlegacycode.cloud.config.server.ConfigServerApplicationTests.Companion.cloudConfigWait
5 | import org.freshlegacycode.cloud.config.server.ConfigServerApplicationTests.Companion.logConsumer
6 | import org.freshlegacycode.cloud.config.server.ConfigServerApplicationTests.Companion.logger
7 | import org.freshlegacycode.cloud.config.server.ContainerConfigurationType.*
8 | import org.junit.jupiter.api.Tag
9 | import org.junit.jupiter.api.Test
10 | import org.slf4j.LoggerFactory
11 | import org.springframework.boot.test.context.SpringBootTest
12 | import org.testcontainers.containers.ComposeContainer
13 | import org.testcontainers.containers.output.Slf4jLogConsumer
14 | import org.testcontainers.containers.wait.strategy.Wait
15 | import org.testcontainers.containers.wait.strategy.WaitStrategy
16 | import java.io.File
17 | import kotlin.time.Duration.Companion.seconds
18 | import kotlin.time.toJavaDuration
19 |
20 | @Tag("unit")
21 | @SpringBootTest(properties = ["spring.cloud.config.server.git.uri=https://github.com/spring-cloud-samples/config-repo"])
22 | class ConfigServerApplicationTests {
23 | @Test
24 | fun `context loads`() {}
25 |
26 | companion object {
27 | internal val logger = KotlinLogging.logger {}
28 | internal val logConsumer =
29 | ConfigServerApplicationTests::class.java.run(LoggerFactory::getLogger).run(::Slf4jLogConsumer)
30 | internal val cloudConfigWait: WaitStrategy = "/actuator/health".run(Wait::forHttp)
31 | internal val containerTimeout = 60.seconds.toJavaDuration()
32 | }
33 | }
34 |
35 | enum class ContainerConfigurationType(val container: String, val label: String) {
36 | CONFIG_DIR("config-server-dir", "Cloud config with config dir"),
37 | COMMAND_LINE("config-server-args", "Cloud config with command line arguments"),
38 | ENV_VARS("config-server-env", "Cloud config with environment variables"),
39 | SYS_PROPS("config-server-props", "Cloud config with system properties")
40 | }
41 |
42 | internal fun ComposeContainer.getUrl(type: ContainerConfigurationType) = getContainerByServiceName(type.container)
43 | .orElseThrow()
44 | .let { "http://localhost:${it.firstMappedPort}" }
45 |
46 | internal fun String.toComposeContainer(): ComposeContainer = ComposeContainer(run(::File))
47 | .withEnv(systemPropertiesToMap())
48 | .withExposedService(ENV_VARS.container, 8888, cloudConfigWait)
49 | .withExposedService(CONFIG_DIR.container, 8888, cloudConfigWait)
50 | .withExposedService(SYS_PROPS.container, 8888, cloudConfigWait)
51 | .withExposedService(COMMAND_LINE.container, 8888, cloudConfigWait)
52 | .withLogConsumer(ENV_VARS.container, logConsumer)
53 | .withLogConsumer(CONFIG_DIR.container, logConsumer)
54 | .withLogConsumer(SYS_PROPS.container, logConsumer)
55 | .withLogConsumer(COMMAND_LINE.container, logConsumer)
56 |
57 | internal fun systemPropertiesToMap() = mapOf("REGISTRY" to "registry", "IMAGE_NAME" to "name", "TAG" to "tag")
58 | .map { (key, value) -> key to value.run(System::getProperty) }
59 | .toMap()
60 | .also { logger.info { "Starting container using environment: $it" } }
61 |
--------------------------------------------------------------------------------
/src/test/kotlin/org/freshlegacycode/cloud/config/server/FileSystemBackendTest.kt:
--------------------------------------------------------------------------------
1 | package org.freshlegacycode.cloud.config.server
2 |
3 | import org.freshlegacycode.cloud.config.server.ConfigServerApplicationTests.Companion.containerTimeout
4 | import org.freshlegacycode.cloud.config.server.ConfigServerApplicationTests.Companion.logger
5 | import org.junit.jupiter.api.Tag
6 | import org.junit.jupiter.api.Tags
7 | import org.junit.jupiter.params.ParameterizedTest
8 | import org.junit.jupiter.params.provider.EnumSource
9 | import org.springframework.http.MediaType.APPLICATION_JSON
10 | import org.springframework.test.web.reactive.server.WebTestClient
11 | import org.testcontainers.junit.jupiter.Container
12 | import org.testcontainers.junit.jupiter.Testcontainers
13 |
14 | @Testcontainers
15 | @Tags(Tag("integration"), Tag("native"))
16 | class FileSystemBackendTest {
17 | @EnumSource
18 | @ParameterizedTest
19 | internal fun `given a config server, when configured with file system backend, is valid`(type: ContainerConfigurationType) {
20 | logger.info { "Verifying ${type.label}" }
21 | val webClient = WebTestClient.bindToServer()
22 | .baseUrl(cloudConfigContainer.getUrl(type))
23 | .responseTimeout(containerTimeout)
24 | .build()
25 |
26 | webClient.get()
27 | .uri("/foo/development")
28 | .accept(APPLICATION_JSON)
29 | .exchange()
30 | .expectStatus().isOk
31 | .expectHeader().contentType(APPLICATION_JSON)
32 | .expectBody()
33 | .jsonPath("$.name").isEqualTo("foo")
34 | .jsonPath("$.propertySources[0].name").isEqualTo("file:/native-files/foo-development.properties")
35 | }
36 |
37 | companion object {
38 | @Container
39 | val cloudConfigContainer = "examples/native/compose.yml".toComposeContainer()
40 | }
41 | }
--------------------------------------------------------------------------------
/src/test/kotlin/org/freshlegacycode/cloud/config/server/JdbcBackendMariaDbTest.kt:
--------------------------------------------------------------------------------
1 | package org.freshlegacycode.cloud.config.server
2 |
3 | import org.junit.jupiter.api.Tag
4 | import org.testcontainers.junit.jupiter.Container
5 | import org.testcontainers.junit.jupiter.Testcontainers
6 |
7 | @Testcontainers
8 | @Tag("mariadb")
9 | class JdbcBackendMariaDbTest : JdbcBackendTest() {
10 | override fun getContainer() = cloudConfigContainer
11 |
12 | companion object {
13 | @Container
14 | val cloudConfigContainer = "examples/jdbc/mariadb/compose.yml".toComposeContainer().apply {
15 | withExposedService("mariadb", 3306)
16 | }
17 | }
18 | }
--------------------------------------------------------------------------------
/src/test/kotlin/org/freshlegacycode/cloud/config/server/JdbcBackendPostgresTest.kt:
--------------------------------------------------------------------------------
1 | package org.freshlegacycode.cloud.config.server
2 |
3 | import org.junit.jupiter.api.Tag
4 | import org.testcontainers.junit.jupiter.Container
5 | import org.testcontainers.junit.jupiter.Testcontainers
6 |
7 | @Testcontainers
8 | @Tag("postgres")
9 | class JdbcBackendPostgresTest : JdbcBackendTest() {
10 | override fun getContainer() = cloudConfigContainer
11 |
12 | companion object {
13 | @Container
14 | val cloudConfigContainer = "examples/jdbc/postgres/compose.yml".toComposeContainer().apply {
15 | withExposedService("postgres", 5432)
16 | }
17 | }
18 | }
--------------------------------------------------------------------------------
/src/test/kotlin/org/freshlegacycode/cloud/config/server/JdbcBackendTest.kt:
--------------------------------------------------------------------------------
1 | package org.freshlegacycode.cloud.config.server
2 |
3 | import org.freshlegacycode.cloud.config.server.ConfigServerApplicationTests.Companion.containerTimeout
4 | import org.freshlegacycode.cloud.config.server.ConfigServerApplicationTests.Companion.logger
5 | import org.junit.jupiter.api.Tag
6 | import org.junit.jupiter.api.Tags
7 | import org.junit.jupiter.params.ParameterizedTest
8 | import org.junit.jupiter.params.provider.EnumSource
9 | import org.springframework.http.MediaType.APPLICATION_JSON
10 | import org.springframework.test.web.reactive.server.WebTestClient
11 | import org.testcontainers.containers.ComposeContainer
12 | import org.testcontainers.junit.jupiter.Testcontainers
13 |
14 | @Testcontainers
15 | @Tags(Tag("integration"), Tag("jdbc"))
16 | abstract class JdbcBackendTest {
17 | abstract fun getContainer(): ComposeContainer
18 |
19 | @EnumSource
20 | @ParameterizedTest
21 | internal fun `given a config server, when configured with jdbc backend, is valid`(type: ContainerConfigurationType) {
22 | logger.info{ "Verifying ${type.label}" }
23 | val webClient = WebTestClient.bindToServer()
24 | .baseUrl(getContainer().getUrl(type))
25 | .responseTimeout(containerTimeout)
26 | .build()
27 |
28 | webClient.get()
29 | .uri("/jdbc-app/dev/latest")
30 | .accept(APPLICATION_JSON)
31 | .exchange()
32 | .expectStatus().isOk
33 | .expectHeader().contentType(APPLICATION_JSON)
34 | .expectBody()
35 | .jsonPath("$.name").isEqualTo("jdbc-app")
36 | .jsonPath("$.propertySources[0].source.['sample key']").isEqualTo("a value")
37 | }
38 | }
--------------------------------------------------------------------------------
/src/test/kotlin/org/freshlegacycode/cloud/config/server/PrometheusActuatorTest.kt:
--------------------------------------------------------------------------------
1 | package org.freshlegacycode.cloud.config.server
2 |
3 | import org.assertj.core.api.Assertions.assertThat
4 | import org.freshlegacycode.cloud.config.server.ConfigServerApplicationTests.Companion.containerTimeout
5 | import org.freshlegacycode.cloud.config.server.ConfigServerApplicationTests.Companion.logger
6 | import org.junit.jupiter.api.Tag
7 | import org.junit.jupiter.api.Tags
8 | import org.junit.jupiter.params.ParameterizedTest
9 | import org.junit.jupiter.params.provider.EnumSource
10 | import org.springframework.http.MediaType.TEXT_PLAIN
11 | import org.springframework.test.web.reactive.server.WebTestClient
12 | import org.testcontainers.junit.jupiter.Container
13 | import org.testcontainers.junit.jupiter.Testcontainers
14 | import kotlin.text.Charsets.UTF_8
15 |
16 | @Testcontainers
17 | @Tags(Tag("integration"), Tag("prometheus"))
18 | class PrometheusActuatorTest {
19 | @EnumSource
20 | @ParameterizedTest
21 | internal fun `given a config server, when configured with remote git backend and prometheus actuator, is valid`(type: ContainerConfigurationType) {
22 | logger.info { "Verifying ${type.label}" }
23 | val webClient = WebTestClient.bindToServer()
24 | .baseUrl(cloudConfigContainer.getUrl(type))
25 | .responseTimeout(containerTimeout)
26 | .build()
27 |
28 | webClient.get()
29 | .uri("/actuator/prometheus")
30 | .exchange()
31 | .expectStatus().isOk
32 | .expectHeader().contentTypeCompatibleWith(TEXT_PLAIN)
33 | .expectBody()
34 | .consumeWith {
35 | assertThat(it.responseBodyContent?.toString(UTF_8))
36 | .contains("# TYPE system_cpu_usage gauge")
37 | }
38 | }
39 |
40 | companion object {
41 | @Container
42 | val cloudConfigContainer = "examples/prometheus/compose.yml".toComposeContainer()
43 | }
44 | }
--------------------------------------------------------------------------------
/src/test/kotlin/org/freshlegacycode/cloud/config/server/RedisBackendTest.kt:
--------------------------------------------------------------------------------
1 | package org.freshlegacycode.cloud.config.server
2 |
3 | import org.assertj.core.api.Assertions.assertThat
4 | import org.freshlegacycode.cloud.config.server.ConfigServerApplicationTests.Companion.containerTimeout
5 | import org.freshlegacycode.cloud.config.server.ConfigServerApplicationTests.Companion.logConsumer
6 | import org.freshlegacycode.cloud.config.server.ConfigServerApplicationTests.Companion.logger
7 | import org.junit.jupiter.api.BeforeAll
8 | import org.junit.jupiter.api.Tag
9 | import org.junit.jupiter.api.Tags
10 | import org.junit.jupiter.params.ParameterizedTest
11 | import org.junit.jupiter.params.provider.EnumSource
12 | import org.springframework.http.MediaType.APPLICATION_JSON
13 | import org.springframework.test.web.reactive.server.WebTestClient
14 | import org.testcontainers.containers.ComposeContainer
15 | import org.testcontainers.junit.jupiter.Container
16 | import org.testcontainers.junit.jupiter.Testcontainers
17 | import kotlin.jvm.optionals.getOrNull
18 |
19 | @Testcontainers
20 | @Tags(Tag("integration"), Tag("redis"))
21 | class RedisBackendTest {
22 | @EnumSource
23 | @ParameterizedTest
24 | internal fun `given a config server, when configured with redis backend, is valid`(type: ContainerConfigurationType) {
25 | logger.info { "Verifying ${type.label}" }
26 | val webClient = WebTestClient.bindToServer()
27 | .baseUrl(cloudConfigContainer.getUrl(type))
28 | .responseTimeout(containerTimeout)
29 | .build()
30 | webClient.get()
31 | .uri("/redis-app/development")
32 | .accept(APPLICATION_JSON)
33 | .exchange()
34 | .expectStatus().isOk
35 | .expectHeader().contentType(APPLICATION_JSON)
36 | .expectBody()
37 | .consumeWith { logger.info{ it } }
38 | .jsonPath("$.name").isEqualTo("redis-app")
39 | .jsonPath("$.propertySources[0].source.['server.port']").isEqualTo("8100")
40 | }
41 |
42 | companion object {
43 | @Container
44 | val cloudConfigContainer: ComposeContainer = "examples/redis/compose.yml".toComposeContainer()
45 | .withExposedService("redis", 6379)
46 | .withLogConsumer("redis", logConsumer)
47 |
48 | @JvmStatic
49 | @BeforeAll
50 | internal fun populateData() {
51 | logger.info { "Populating test data" }
52 | val execResult = (cloudConfigContainer.getContainerByServiceName("redis")
53 | .getOrNull()
54 | ?.execInContainer("sh", "/data/populate-redis.sh")
55 | ?: throw RuntimeException("Could not populate redis test data"))
56 |
57 | assertThat(execResult.exitCode).isZero()
58 | }
59 | }
60 | }
--------------------------------------------------------------------------------
/src/test/kotlin/org/freshlegacycode/cloud/config/server/RemoteGitRepoBackendTest.kt:
--------------------------------------------------------------------------------
1 | package org.freshlegacycode.cloud.config.server
2 |
3 | import org.freshlegacycode.cloud.config.server.ConfigServerApplicationTests.Companion.containerTimeout
4 | import org.freshlegacycode.cloud.config.server.ConfigServerApplicationTests.Companion.logger
5 | import org.junit.jupiter.api.Tag
6 | import org.junit.jupiter.api.Tags
7 | import org.junit.jupiter.params.ParameterizedTest
8 | import org.junit.jupiter.params.provider.EnumSource
9 | import org.springframework.http.MediaType.APPLICATION_JSON
10 | import org.springframework.test.web.reactive.server.WebTestClient
11 | import org.testcontainers.containers.ComposeContainer
12 | import org.testcontainers.junit.jupiter.Container
13 | import org.testcontainers.junit.jupiter.Testcontainers
14 |
15 | @Testcontainers
16 | @Tags(Tag("integration"), Tag("git"))
17 | class RemoteGitRepoBackendTest {
18 | @EnumSource
19 | @ParameterizedTest
20 | internal fun `given a config server, when configured with remote git backend, is valid`(type: ContainerConfigurationType) {
21 | logger.info { "Verifying ${type.label}" }
22 | val webClient = WebTestClient.bindToServer()
23 | .baseUrl(cloudConfigContainer.getUrl(type))
24 | .responseTimeout(containerTimeout)
25 | .build()
26 |
27 | webClient.get()
28 | .uri("/foo/development")
29 | .accept(APPLICATION_JSON)
30 | .exchange()
31 | .expectStatus().isOk
32 | .expectHeader().contentType(APPLICATION_JSON)
33 | .expectBody()
34 | .jsonPath("$.name").isEqualTo("foo")
35 | .jsonPath("$.propertySources[0].name").isEqualTo("https://github.com/spring-cloud-samples/config-repo/foo-development.properties")
36 | }
37 |
38 | companion object {
39 | @Container
40 | val cloudConfigContainer: ComposeContainer = "examples/git/compose.yml".toComposeContainer()
41 | }
42 | }
--------------------------------------------------------------------------------
/src/test/kotlin/org/freshlegacycode/cloud/config/server/SecurityEncryptTest.kt:
--------------------------------------------------------------------------------
1 | package org.freshlegacycode.cloud.config.server
2 |
3 | import org.assertj.core.api.Assertions.assertThat
4 | import org.freshlegacycode.cloud.config.server.ConfigServerApplicationTests.Companion.containerTimeout
5 | import org.freshlegacycode.cloud.config.server.ConfigServerApplicationTests.Companion.logger
6 | import org.junit.jupiter.api.Tag
7 | import org.junit.jupiter.api.Tags
8 | import org.junit.jupiter.params.ParameterizedTest
9 | import org.junit.jupiter.params.provider.EnumSource
10 | import org.springframework.http.HttpHeaders.AUTHORIZATION
11 | import org.springframework.http.MediaType.TEXT_PLAIN
12 | import org.springframework.test.web.reactive.server.WebTestClient
13 | import org.springframework.web.reactive.function.BodyInserters.fromValue
14 | import org.testcontainers.containers.ComposeContainer
15 | import org.testcontainers.junit.jupiter.Container
16 | import org.testcontainers.junit.jupiter.Testcontainers
17 | import org.testcontainers.shaded.org.apache.commons.lang3.RandomStringUtils.randomAlphanumeric
18 | import org.testcontainers.shaded.org.bouncycastle.util.encoders.Base64
19 |
20 | @Testcontainers
21 | @Tags(Tag("integration"), Tag("security"))
22 | class SecurityEncryptTest {
23 | @EnumSource
24 | @ParameterizedTest
25 | internal fun `given a config server, when configured with remote git backend, is valid`(type: ContainerConfigurationType) {
26 | logger.info { "Verifying ${type.label}" }
27 | val encodedCredentials = "Basic ${Base64.toBase64String("user:password".toByteArray())}"
28 | val value = randomAlphanumeric(20)
29 |
30 | val webClient = WebTestClient.bindToServer()
31 | .baseUrl(cloudConfigContainer.getUrl(type))
32 | .responseTimeout(containerTimeout)
33 | .build()
34 |
35 | val encrypted = webClient.post()
36 | .uri("/encrypt")
37 | .contentType(TEXT_PLAIN)
38 | .header(AUTHORIZATION, encodedCredentials)
39 | .body(fromValue(value))
40 | .exchange()
41 | .expectStatus().isOk
42 | .expectHeader().contentTypeCompatibleWith(TEXT_PLAIN)
43 | .returnResult(String::class.java)
44 | .responseBody
45 | .blockLast()
46 |
47 | assertThat(encrypted).isNotBlank().isNotEqualTo(value)
48 |
49 | val decrypted = webClient.post()
50 | .uri("/decrypt")
51 | .contentType(TEXT_PLAIN)
52 | .header(AUTHORIZATION, encodedCredentials)
53 | .body(fromValue(encrypted!!))
54 | .exchange()
55 | .expectStatus().isOk
56 | .expectHeader().contentTypeCompatibleWith(TEXT_PLAIN)
57 | .returnResult(String::class.java)
58 | .responseBody
59 | .blockLast()
60 |
61 | assertThat(decrypted).isEqualTo(value)
62 | }
63 |
64 | companion object {
65 | @Container
66 | val cloudConfigContainer: ComposeContainer = "examples/security/compose.yml".toComposeContainer()
67 | }
68 | }
--------------------------------------------------------------------------------
/src/test/kotlin/org/freshlegacycode/cloud/config/server/VaultBackendTest.kt:
--------------------------------------------------------------------------------
1 | package org.freshlegacycode.cloud.config.server
2 |
3 | import org.assertj.core.api.Assertions.assertThat
4 | import org.freshlegacycode.cloud.config.server.ConfigServerApplicationTests.Companion.containerTimeout
5 | import org.freshlegacycode.cloud.config.server.ConfigServerApplicationTests.Companion.logConsumer
6 | import org.freshlegacycode.cloud.config.server.ConfigServerApplicationTests.Companion.logger
7 | import org.junit.jupiter.api.BeforeAll
8 | import org.junit.jupiter.api.Tag
9 | import org.junit.jupiter.api.Tags
10 | import org.junit.jupiter.params.ParameterizedTest
11 | import org.junit.jupiter.params.provider.EnumSource
12 | import org.springframework.http.MediaType.APPLICATION_JSON
13 | import org.springframework.test.web.reactive.server.WebTestClient
14 | import org.testcontainers.containers.ComposeContainer
15 | import org.testcontainers.junit.jupiter.Container
16 | import org.testcontainers.junit.jupiter.Testcontainers
17 | import kotlin.jvm.optionals.getOrNull
18 |
19 | @Testcontainers
20 | @Tags(Tag("integration"), Tag("vault"))
21 | class VaultBackendTest {
22 | @EnumSource
23 | @ParameterizedTest
24 | internal fun `given a config server, when configured with vault backend, is valid`(type: ContainerConfigurationType) {
25 | logger.info { "Verifying ${type.label}" }
26 | val webClient = WebTestClient.bindToServer()
27 | .baseUrl(cloudConfigContainer.getUrl(type))
28 | .responseTimeout(containerTimeout)
29 | .build()
30 |
31 | webClient.get()
32 | .uri("/myapp/default")
33 | .accept(APPLICATION_JSON)
34 | .exchange()
35 | .expectStatus().isOk
36 | .expectHeader().contentType(APPLICATION_JSON)
37 | .expectBody()
38 | .jsonPath("$.name").isEqualTo("myapp")
39 | .jsonPath("$.propertySources[0].source.foo").isEqualTo("myappsbar")
40 | }
41 |
42 | companion object {
43 | @Container
44 | val cloudConfigContainer: ComposeContainer = "examples/vault/compose.yml".toComposeContainer()
45 | .withExposedService("vault", 8200)
46 | .withLogConsumer("vault", logConsumer)
47 |
48 | @JvmStatic
49 | @BeforeAll
50 | internal fun populateData() {
51 | logger.info { "Populating test data" }
52 | val execResult = (cloudConfigContainer.getContainerByServiceName("vault")
53 | .getOrNull()
54 | ?.execInContainer("sh", "/data/populate-vault.sh")
55 | ?: throw RuntimeException("Could not populate vault test data"))
56 |
57 | assertThat(execResult.exitCode).isZero()
58 | }
59 | }
60 | }
--------------------------------------------------------------------------------
/src/test/resources/junit-platform.properties:
--------------------------------------------------------------------------------
1 | #junit.jupiter.execution.parallel.enabled = true
2 | #junit.jupiter.execution.parallel.mode.default = concurrent
3 | #junit.jupiter.execution.parallel.mode.classes.default = same_thread
4 | junit.jupiter.execution.parallel.config.strategy = fixed
5 | junit.jupiter.execution.parallel.config.fixed.parallelism = 3
--------------------------------------------------------------------------------