diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 207fa084a..6ca29d7cc 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -69,40 +69,6 @@ jobs: - name: build with maven run: mvn -B formatter:validate verify --file pom.xml "-Djava17.home=${{env.JAVA_HOME_17_X64}}" "-Djava21.home=${{env.JAVA_HOME_21_X64}}" "-Djava25.home=${{env.JAVA_HOME_25_X64}}" - docs: - needs: [build] - if: github.event_name == 'push' && github.repository_owner == 'smallrye' - runs-on: ubuntu-latest - name: docs - - steps: - - uses: actions/checkout@v7 - name: checkout - - - uses: actions/setup-java@v6 - with: - distribution: 'temurin' - java-version: 25 - cache: 'maven' - cache-dependency-path: '**/pom.xml' - - - uses: actions/setup-python@v7 - with: - python-version: '3.12' - - - name: build docs - env: - GITHUB_TOKEN: ${{secrets.GITHUB_TOKEN}} - run: | - cd documentation - mvn package - pipx install pipenv - pipenv install --ignore-pipfile - git fetch origin gh-pages --depth=1 - git config --global user.name "SmallRye CI" - git config --global user.email "smallrye@googlegroups.com" - pipenv run mike deploy --config-file=mkdocs.yaml --push --update-aliases Main SNAPSHOT - quality: needs: [build] if: github.event_name == 'push' && github.repository_owner == 'smallrye' diff --git a/.github/workflows/docs.yml b/.github/workflows/docs.yml new file mode 100644 index 000000000..b31010d27 --- /dev/null +++ b/.github/workflows/docs.yml @@ -0,0 +1,16 @@ +name: Documentation + +# Renders the documentation with the smallrye.io site, as it will be published, and fails on a +# broken include or a page that does not render. smallrye.io publishes main nightly and each release. +on: + pull_request: + paths: + - 'documentation/**' + - '.github/workflows/docs.yml' + workflow_dispatch: + +jobs: + docs: + uses: smallrye/smallrye.github.io/.github/workflows/docs-check.yml@develop + with: + project: smallrye-config diff --git a/.github/workflows/publish-docs.yml b/.github/workflows/publish-docs.yml deleted file mode 100644 index fb5eecca2..000000000 --- a/.github/workflows/publish-docs.yml +++ /dev/null @@ -1,48 +0,0 @@ -name: Publish Docs - -on: - workflow_call: - inputs: - version: - required: true - description: Tag version to perform release - type: string - -permissions: - contents: write - -jobs: - publish-docs: - name: Publish Docs - runs-on: ubuntu-latest - - steps: - - uses: actions/checkout@v7 - name: checkout ${{inputs.version}} - with: - ref: ${{inputs.version}} - - - name: git author - run: | - git config --global user.name "SmallRye CI" - git config --global user.email "smallrye@googlegroups.com" - - - uses: actions/setup-python@v7 - with: - python-version: '3.12' - - - uses: actions/setup-java@v6 - with: - distribution: 'temurin' - java-version: 17 - - - name: docs release ${{inputs.version}} - run: | - cd documentation - mvn package - pipx install pipenv - pipenv install --ignore-pipfile - git fetch origin gh-pages --depth=1 - pipenv run mike deploy --config-file=mkdocs.yaml --push --update-aliases "${PROJECT_VERSION}" Latest - env: - PROJECT_VERSION: ${{inputs.version}} diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index dd0ce0c62..bd025dd0f 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -28,13 +28,6 @@ jobs: with: version: ${{github.event.inputs.tag || github.ref_name}} - publish-docs: - name: Publish Docs - uses: ./.github/workflows/publish-docs.yml - secrets: inherit - with: - version: ${{github.event.inputs.tag || github.ref_name}} - publish-tck: name: Publish TCK Report uses: ./.github/workflows/publish-tck.yml diff --git a/.gitignore b/.gitignore index 17eca2550..5166afb50 100644 --- a/.gitignore +++ b/.gitignore @@ -63,8 +63,5 @@ client/shade/dependency-reduced-pom.xml # Jenv .java-version -# MkDocs -site - # formatter cache directories .cache diff --git a/README.adoc b/README.adoc index 2a7d8bb8e..a8e0193b4 100644 --- a/README.adoc +++ b/README.adoc @@ -27,14 +27,9 @@ Compile and test the project: mvn verify ---- -Generate the documentation (from the `documentation` folder): - -[source,bash] ----- -mvn package -pipenv install -pipenv run mkdocs serve ----- +The documentation is AsciiDoc in `documentation/src/main/asciidoc`, published on +https://smallrye.io/docs/smallrye-config/latest/[smallrye.io]. See `documentation/README.adoc` to +write and preview it. === Project structure @@ -56,4 +51,4 @@ Please refer to our Wiki for the https://github.com/smallrye/smallrye/[Contribut * http://github.com/smallrye/smallrye-config/[Project Homepage] * {microprofile-config}[Eclipse MicroProfile Config] -* https://smallrye.io/smallrye-config[Documentation] +* https://smallrye.io/docs/smallrye-config/latest/[Documentation] diff --git a/documentation/Pipfile b/documentation/Pipfile deleted file mode 100644 index 351af8583..000000000 --- a/documentation/Pipfile +++ /dev/null @@ -1,15 +0,0 @@ -[[source]] -url = "https://pypi.org/simple" -verify_ssl = true -name = "pypi" - -[packages] -mkdocs = "*" -mkdocs-material = "*" -mkdocs-macros-plugin = "*" -mike = "*" - -[dev-packages] - -[requires] -python_version = "3" diff --git a/documentation/Pipfile.lock b/documentation/Pipfile.lock deleted file mode 100644 index 88edf2837..000000000 --- a/documentation/Pipfile.lock +++ /dev/null @@ -1,670 +0,0 @@ -{ - "_meta": { - "hash": { - "sha256": "2aa52cd35eb1c22baa080a96db79c3e339cc577e7010817186a402c478d97d14" - }, - "pipfile-spec": 6, - "requires": { - "python_version": "3" - }, - "sources": [ - { - "name": "pypi", - "url": "https://pypi.org/simple", - "verify_ssl": true - } - ] - }, - "default": { - "babel": { - "hashes": [ - "sha256:b80b99a14bd085fcacfa15c9165f651fbb3406e66cc603abf11c5750937c992d", - "sha256:e2b422b277c2b9a9630c1d7903c2a00d0830c409c59ac8cae9081c92f1aeba35" - ], - "markers": "python_version >= '3.8'", - "version": "==2.18.0" - }, - "backrefs": { - "hashes": [ - "sha256:4a627b817fd2dce43b79ab48da63613340509381cd8ce0897078a0bce79a2ab8", - "sha256:601ce68ca12385dbda06ce264406b4c4210cf5b79fd0fd627592365c92f29a88", - "sha256:87f0fae8c5f207fe9f4b2887efc71d42f4900ac78faa1af08d675ef303692dc5", - "sha256:9ec96efa080938be92323e8e730e57718c9c88eb15ad70bbef4e1766df591408", - "sha256:b556cd7d36c3a3a2f256b89590b176b8eddfb73bcfaee3a3ddd84ea66d21ce50", - "sha256:f0c35cf0102ba6b6070c12a492be3c1c1d3f5839529784b9a9565d6d04569a01" - ], - "markers": "python_version >= '3.10'", - "version": "==8.0" - }, - "certifi": { - "hashes": [ - "sha256:035c1e85572b141bf1c3a3eff0e33a8eb74917522f2559075ff8d2fea780a1ae", - "sha256:42d35340cc5b9ba78e818ddbff0c5b1c2b779de448a340fd1b989f5fa8670e1b" - ], - "index": "pypi", - "markers": "python_version >= '3.7'", - "version": "==2026.10.19" - }, - "charset-normalizer": { - "hashes": [ - "sha256:00668ebb0609751758682eb0b5857e7c35b9f00e84dfdef062e103244ec94d45", - "sha256:012a22b88a77ca2e59b98ac5889b0deb604147666032f45e6d6e217634d2550d", - "sha256:01e93745f7f219b703b60ba7afead36cfc4242782be5af484673fc500df12da5", - "sha256:04368edf83514385ffc3e1cfd4546e595f4f1272dd23ba437a93a9cc3741d47b", - "sha256:0722590aabf9dc6a6c0343d523c05458fa2b5047dbe6302fd526bb570600753f", - "sha256:07ffd07412fc5d5e84cd8952acf9ff7e4ed7a708e69d1bada19d8ba91711353f", - "sha256:09a7bba9f739468c8e78c36a75c33768e53cb1959fc638f510454c14683f00d5", - "sha256:0b2b1b3fa5670c127b246df1d0c059defd41f689a868a3b9d79df9b1cac42d22", - "sha256:0c6dfb5ca6723eeed15aa8e564a014d69fcb8812f94eef11fe3631e0508199f5", - "sha256:0d929fc574b4d6fd9e7c0f5c2ede8716a41911923aa7fa5fce38e0818aa4a1ac", - "sha256:13e3afe97712e8887cd516e960c63f0b93122971e5b5e4b2622fe7701771e838", - "sha256:15f024313246a4ed976c60f440bb8d257815513a681d212ff74fd46f7d715a90", - "sha256:195ce897c6153c0700078142cf8efe3e6454ca4cf4357499e4078dfd83396626", - "sha256:19a3dd5aa73cef1c99687c4fc57db016a9c17104ae1185da88ba566a5d3bebe4", - "sha256:1d1c7a53a6c2103925cdd6d7229f8c567379f211c869793df679f2e9f738c369", - "sha256:1f5883d77fd409a261abb5dc8ccbe335720d798b1de4abb3b1d47ccbbc76b53b", - "sha256:21b82d8082f6f5e7f456ef0bd16323d08de1266efbfeb476e64b2a91d1471a4e", - "sha256:252d099029bcbea642f2a06c4ed5046bdf8b5a8150b64afa5e027e88b106e5ee", - "sha256:256dd4d85d9e4dc595e2bc983c980e73f62ddeb3165c58b4c3dfe78c5c8548c1", - "sha256:26422d45fd13551cf564c58932f7d72b4f58b93b0fcf18c35ba6be12b46bb102", - "sha256:2679de311c7946dde5d3b6f44941844133ff5c7cb86099c0061ab1e8901c20a8", - "sha256:29880d17a8eb0b5cfdfd8944b468322928059aa35f1f5fa8ff22b149ec0b42f8", - "sha256:2bced4061f000f7187254a02ad3433ae17eaf991747ceea2f478422590a5bba9", - "sha256:2e9cf9253119d8e5d111f05d71626786fd3d6193817316eab1ca088cdb8593cf", - "sha256:2f06b7eae9dbe77fe1d644ca244dad508de8d302870a43f3c559b521270938a0", - "sha256:2f293479cce755c75f1697e87c409b7ae4c555c7dfecb6e988ad13abba943031", - "sha256:329fc3ccb63ad22d867d84c2adea759a64079a37ba4a343433b02c7a2816871e", - "sha256:343fb4f2821043bd87095f7b08a1a181febc8e36ac64212143bbfd0a0e1bc235", - "sha256:3588e376b3ea2eea84976f67273d679f229e24c66dce7b82ae45aef04ff6e072", - "sha256:35aea775dc2bd5f54cd84a1cd2696cc3207c479cb9cf0bd346f0d343e4300ddb", - "sha256:35fe081843b35aad20ffeccec3eeffbe637b15d14f3fb22cc1b59cd8ec17e93c", - "sha256:36047af20e17097c3bb9476c2b7655f2f7aa51322c0ba58c07695bedf755a950", - "sha256:3617ac3cfd8b9888f145ad89dd6e692285834b0201c6074a5eeaad3fd4d668c2", - "sha256:366ec70f5547c640d3ce1985722490f23faf4eb5216a7eeba78277490e78dacb", - "sha256:394fea06235c8543390050ed5f529187074b029fb027213f6c46ac11ab5d950e", - "sha256:3d27167433c0d5f18dc850f07d0b3816221984fecdc405d6c157a6f0b8f8e9e6", - "sha256:3e5e1224c0a6a90e05843e07adfec669edebec17801c67072f51e59561d63c0b", - "sha256:41876ee62a3dddf48ff1121ad8f0798032aa03f2fd35f21f34a4cab14f18d8d2", - "sha256:433c5a81eade63b47e522303bad236f59dba55ea6951746f5558355eeed8c75d", - "sha256:4582c27e8c889d64811987b5967fbd3ae0c823fe1fd933b543d55ac20bb475fa", - "sha256:485a0d363cafefcd2538a73c7c838daa2035f09b2c9f9b5e3133f80c6aeb84c2", - "sha256:494b70049a4d69aec6e8137c13af4cf8db8c9f9820a1392ac293b0dd2987a818", - "sha256:496846868fea80e479324862fa877f02411f2fd0f83b79ccee2607aa68b2a032", - "sha256:4abdc5f9ad448c1ecbfae2974b820535d6bc6e7eef63babbab3d81cf46968c71", - "sha256:4b599739b93b2cbeded49645ae3c8d1405c29ddfbceac1545c87a3f9580a9e96", - "sha256:4bea7f8ebe90bbd7f0e4a2de42ca6924ba23e3e76418c408ff82f1d46fabd687", - "sha256:4c4fb141a727957c93edfe5c32a26ceb6b5f6461d67146e2d39f51e16170bea8", - "sha256:4c9548dc78002099910abaebc0a72ac58b7d30931869e0351c09b507dff4ece3", - "sha256:4d26f14f041e83dd8edfd61f4cd4fa7285d31798b5bf1f28e70c367ba6c41d61", - "sha256:4f298bdadb8f0b9e5672877f647d1be9373ef5320c9e2f049795e26cad28b6a9", - "sha256:52ec005752a56ae79547a05c0139ca2501a0c866390b6115008456b9f0e7cde1", - "sha256:55261ac0d2941c42f196dd576f543d87a8ee03cd6f5e30dfb4d807b2e3b9121a", - "sha256:56490c595a28b1bb27dfc583e816152a9767721ef58b2c03b13f954d2f707420", - "sha256:58d3e12c88e0950bca850ae1f7c256055c097639c2edb9eb123af9807d8b15e4", - "sha256:58d4aa13a59c969dbfdf9e6a9560e242cbfd9e8a8f50c2747714df1a423adf65", - "sha256:59171c6e45bf07d0d5cab3b0bf81d945035530f6873398b3b531c31184d46663", - "sha256:5b6d1386bf0096d26d3a863dc0a487a5b4eb9aa93cf5ba69683d29dde6b9d60f", - "sha256:5c0ea61a470e070686aa30892fed79e297d2c8d0ab46b8bcdf027d38c51da591", - "sha256:5c84bec0ab5ae0c64bfe73a7d2adcb5ce73b467523fc27fd6a28ab2aa6cbe35a", - "sha256:5ca0555312ae2fe82715cada7fac375530c2f3349e1eaa1bcb33d0283ac79a18", - "sha256:5d8531a6569d025f68e2321e7638fb7978f23db58e5f69f56913837aae03816e", - "sha256:5e2d0e146dcb57034f8b97dc58d2d512cb90aba253960ce449f695fec6a82c6f", - "sha256:5fc45d653ea8c9a20479167e11d4a0f8cb2fa3470737ab6f9c827532313187b7", - "sha256:6117b84ea48435e5356dc737f5121485c30920ba43375fa7b434fd753df0eac3", - "sha256:6199d5606e2bbf2b096cf64d03f8b6790c91081d5ac866b8e7bb6422738cc60c", - "sha256:62b55f6722735a6c472f88361cde6640608773d9443cebdbb51abf436a1fcdd3", - "sha256:687c9ca3035544b113bea2055e180af96fb63c0c476e22a9180f51925186e7b7", - "sha256:6b7430cf5728e68f6c462254009a6ef4086e1bea43cf2f57aa9c55fb4f50ff96", - "sha256:6ba32c4d2abf1d2fe7cf27d280f4cca5664233b0f885549c7761719eb977f486", - "sha256:6c9cdde8becb25a7fde49924511aa2644d6f8081cc8df8e9452724303348d8e3", - "sha256:6df0ec430f9a831772c23ca5a224cba36517a58a84bb32c32bb59a9fa67c47f6", - "sha256:6e2912d4babbc65196ac13c2f53468dc57fb8b9c25ef913e8c59ddf7c6dc0e1b", - "sha256:6e5e4d73d588ca5ed09df1b7dcd1b203d1df3c542e3f50d126c947d432b10731", - "sha256:70055ff39b97c99e7ae40ea3e393fb62aa2e44dbd9b29f8d14f42fb0025c3959", - "sha256:706bfd38730a5ac7a365793269a00f4e988178cec121391f4248d84ad8c972e9", - "sha256:7235dc28fc6dd9d832ac7c7bce95367dedb85929f17368a0c2bee1e080b9acbf", - "sha256:774d157f112367ff4abd29019f38f023c24e00e56edc7829c20e358a5a913ad8", - "sha256:77efcff2b23071c349402ac1066667a3d011f62398d81408c9b88ad991747c9e", - "sha256:789b8982559ae28dad2356519f841655756cdcd96616410590ae0b17454ee64f", - "sha256:7ac76cf9afd34929d76eb7fcb63be476a4853d8a96f0dcf2d0db68a0cbdf9885", - "sha256:7c0c10730342b0c9b35dd1d619beb8214e520bd96a1f870f452680b238aab3e0", - "sha256:823f82903d189af463d7df250ef1f7f696f3cee08cc8d91deb565e8d425f6506", - "sha256:838648accb3a7fd9803fd45c87bce8509648eb0c11bc34e216141300977244f2", - "sha256:854066be00447fa8de2ccbbe893e2ffc4b123ef16d897af794c1e18bd4a714b0", - "sha256:85d5855daafc240cc045c026d7a15fd198a09b0fc8ff6f5ecbb5297b509cb11e", - "sha256:85de3134b5379856e323ba37c19c9256d39425f7b76a63af52b09fb4664c2e8f", - "sha256:87e4f41d375c0b9be2fb5251aee4b8a689169e134535aed81bf085c3b647451e", - "sha256:88ca277405c2d3b71c4e1c2ee0e7966e807bcba86a69d11e19ba199d18ae4491", - "sha256:88e85ab89cb822c1e635f51d6d32e488f94e002e70e2f492bdb8b945543f345a", - "sha256:8ac8c94b6539074e0f40899301273ac8402b9b3e01c7b7ba269ff30340aaaf20", - "sha256:8fe532b3c966d1fb794e0698e4589d0444017ae77fc0b31edea13c0e35bcc449", - "sha256:9085f87b0e38a2b92b8923059b4e8789fe40d9279712d15dcc670048d77079af", - "sha256:90b7481fb62fbe172c558bc6fd1c4c98d82004a54a7551f20e11ac9bf0b8708c", - "sha256:92caef967d287a407085d61176fce4012b1dd62daed4eb6d5ceb26d3d2538712", - "sha256:9362dd90aa7dab48c0054a21187791ccf05473f7dba5d92b8033ae62164675e7", - "sha256:94d78ecec2605a8d0398b0f365d5f12a63248438516f5dac536a5eff7337df4a", - "sha256:94fbf1c0c6cc0d3d5e50f9a9313a8cdca90dd696d34b381cd1704f8c9e939f20", - "sha256:950f23cb393f85543777b0433f082cddd25b51ab398eac7971146495679efe5f", - "sha256:96eefc178f8636b9c760c5829345307fd81cfae9ab1e80997dbddeb0f54ee9a3", - "sha256:96fef3e886d6a9874b14f27fc193fbdc69d5d8035783d86aa4e1cea594e695f9", - "sha256:977cdbd483a9cff38179bea4fd754289a6f2195c7abd414aba85410b3e66cc5e", - "sha256:978eab16f55b4ab2c2a745be9a0a840bf8f09a7f227d9c76eb30214d078865a5", - "sha256:994e883d17c559cdfd38c84003c8b27d25424a1077272a17e7cd27bfe0bf57b2", - "sha256:9ac4444d8d4fd4c4bd08bf451ed3167aa9e7ec6cdb41b648794f1d1103652e36", - "sha256:9b5db6052055d34d41230fb78d7c439c23dc536a9896f6cb039e8dd92cfc1263", - "sha256:9d9a0dc7cbe9bec24c3f767c9122c41fe5a1bc43f47cd099d00d393e09769de4", - "sha256:9dbdd9205662134957cf0c324f639bdc5031c0ca056e2369e238db75187c0f11", - "sha256:9eea3ab2597a5e65fe65296e2d6a84570845a6b55532d90333d740d48bbc850a", - "sha256:a2028475ba855475b8b4d3cfeb4994269c967aea8b9892dfba907f4263a863a3", - "sha256:a3a370082ce34d0612f421e15fe011c53bb1feff21a26d06ad4fb244dab5a375", - "sha256:a545775cfe815855ea32d7c27731d79da358ef2055b4a25830231b1622dd18aa", - "sha256:a5cbd90ecf0fc62e64726917ad083b73001f0563657a87ec3c0b504e277dc90d", - "sha256:a6d095662e73e74f0a49988e0593373e243e3a52e27bfeea0a859e88acf4a0f5", - "sha256:a6dac12ff6b846103483683f60c5f8fee205121adc58ffd87e90a90a3af69e99", - "sha256:a951ad59cad9145664a730d3036b40b844e74d2d3683da40111463cd3a83845d", - "sha256:aa1099b956fb795e686d073568f6dc002a0bb89765ea6d5b055dd7d9bf1b116c", - "sha256:aa2bb0b37202dca27175591f761108b5d34096ade1191ffe4808bdf6b1571488", - "sha256:aae2ee51122d3ae968a3837d97dc24a0aeebb0dea23694422cd172bd30017cd6", - "sha256:ab743e9bc90c1f73552ec33e10e3331315acd2c397b36065b591b0181de533cc", - "sha256:ac00177c4831ffa650f8609e4bdddd5fe09c03b1c0c47acece7e6ea20421598b", - "sha256:ac13b004224fb341e1e25a1ed5e19d32f57cdb2a403e01f003b46f051a550f6f", - "sha256:acaf604462bf330b0d07e7a07c1d6e4adac79e5fb13e9c5140590542cafacc00", - "sha256:ae31a1a1db2ee6cc2942fccaf695c934bc7f3db9f2133a3fef1f367cf1a4ab10", - "sha256:ae4a097991662cd4fff0ddc74e0fe7874f82e00042fa0ea00855645ed0c79598", - "sha256:aea996a6aba25260827c9ea511d1addfde2da9eb686ac961838509086188b7e6", - "sha256:b39b69b347e5e47a3b5b8cfc005c68c1ba347474e3960236c4944a8ecd174962", - "sha256:b54e7e13267d49ffbfe68e25b3cbd774dab38fa37238f71265e91b36146eb21c", - "sha256:b9af956078716df40d985fb0dfeb2c2120c5ca92ba4ff4b388acfd01cdc14d08", - "sha256:ba2f37ee79e6338845261a3c5b1784e5d1acdff2c0785b284f1b633033d136ab", - "sha256:ba501e667c17d8411f98e67a022d9604ef179aff0e459b7e292c796837c13573", - "sha256:baf3775a2635e5a11fbd5e4e64ee69c7e86875d224a5c72aca4c141064589a90", - "sha256:bb57753e36e4855b8ca375069482250a6246372331a3e4f3407eaebb007443f5", - "sha256:bd6c173f04743d483881bffa1478d5a4624475b8cd1d2194956a75548e191c18", - "sha256:be47f99644b208bff7766314013f9acf57b056b04191d570d68ad14022cf5b1d", - "sha256:c010f5581d9c612804cc59fcf7b524b707fbcb72828551237ab545bb5c7034af", - "sha256:c1dcc36dcb96abc02236e182d17e0f71430152a6c2c7447421da2d2dc144edea", - "sha256:c428c6c31eb5f4277d7f8eccaf767fbd548ddd5ce3c8b4f4cbbfab3d96b5904c", - "sha256:c658c50ac0c98cd755a2dd50b7977d3bca7df401dcc47fbdfa87db53ef7d4e8b", - "sha256:c71fb0d56c920c269cd3e2e3fe7c610e3f1fdb21a6ce60efa6430ff63676cea6", - "sha256:c7b742bf31c88566b4bb6335a7f393bb322e580b6bb98df7bd0c25e6e3519ce8", - "sha256:cc0329df4caaceb950d2f580b5ac716a377f7059624a0bafaeaf8a218c6ed774", - "sha256:cc5d36d96478aa9c60654bd932525bf32964c62a7281eafdf16d85003a8d6004", - "sha256:ce854f5f478050ade5a238731c4ca985a7d3b3cb53ff600a9b5c3b689b5f0a7a", - "sha256:ced3fdd71aaa83ce593746c2edb42b7a59cb4c19c8b5c407781c72e493aae55a", - "sha256:cee5dd7c6fb5dd52a0fe2a740f9bc6e3593f5f8b1788bde49de02086f30182b2", - "sha256:cfa1c0cc3a8f9f53f1243a5a99ac36fd003880199383b37672e86ddda9cb07e2", - "sha256:d1ee1e296209fdce05b81b663250eefa02213a2da7b41bf26f7829b8ba3545aa", - "sha256:d59b75732e9b6f27388e10c14b0259cc5f2e48c78627d185e6a177b58ad3cffe", - "sha256:d63600d620ad0064c3a748b950ac5ea38a80190e5498532efefa4b7b3f1da1f3", - "sha256:dd732602a7009217f658d5863d12d79d373a4de0eebc111094bcdd3bb8e0a6cc", - "sha256:e06efa066f7dbadbc84ebc126a97c452a6451dfcf589d89d788484949e1cf795", - "sha256:e199fb99720074809a7720f1c0b4d919eea8b87e88713e0f8f602f7bef543d9d", - "sha256:e4b018dc5a0eee4676e38fe84a47a427816c590b93b55d9025274ec4d6ffc2dc", - "sha256:e6621fb2a4988d6e53eedc455e5903e2679f3967b8acb3d639f1b63c14a2e893", - "sha256:e71c909f353863b2b89c83de2ebed71ea6d0df8a6ef65a128193c5e650766bef", - "sha256:e90251c0c7bdd54a100a0dce3c07b7e637278c93af29dbf78ebb89a58c4bac7d", - "sha256:e9fbdce1e47394b09bc9f26ab117dfc8d6491977a11d86f592bb42c779db2fda", - "sha256:eb12fb2ba69ffa05f8695f61c69e591dc4b4a12ac3757ac8af8adb259bf56d17", - "sha256:eda059b6bc8bc0812d626fd91a7ce01bf583df0a61296eff390fd94141a34e30", - "sha256:f03ac127268b43ef4fe9e6ab6794a6794b49485a0cc0c1db79876d2f33f75bc7", - "sha256:f298e218441525d3794428b4c8b8fb8662c6d3ea79925d4807ee6b9a96a3bca5", - "sha256:f5542f9b941279d82d41eb0aa9f98eba36fe4df5c7086c651df7944935b37182", - "sha256:f6f7deae3feb4edfa2efaf7c574fe88cbf055038a6abdb40188e4fff66d5699f", - "sha256:f9b1e28d0e8dbfa858abdba91d6b547beaf2df1a59bec6da6faae7b96a4991a9", - "sha256:f9f8405c2c758532c74fed975dbee57be1f31a6e865c031870c79a6ed3212ada", - "sha256:fa48b1b63d639f9483e0633e092f5851e2348c352f1f9bb6c8182f87884ef876", - "sha256:fb78f6e7fcd8ad785d28cd577168bc1aaee827b25bb8755638f694794ea98f0a", - "sha256:fbc597639158fd7c14d55e808718848319540f51b0e6746e3eefa59723a4a348", - "sha256:fce8cbd4997efeb450bd298b54f755dcdff18d496f7a5ddbb4867c6d7c88fdc3", - "sha256:fd0350afdc3aabd5576f60ea109228bd5538139713c7b094c5cd27c73a98bc6f", - "sha256:fd0a274c0e5f9a21565cd9d3dd749b61f96b7aa1e20a93aa1ba4029518f2e5c0", - "sha256:fdb8a068947befafba9952162645dc2fecaeb400e64584829ed5e9b2fbe21a7f" - ], - "markers": "python_version >= '3.7'", - "version": "==3.5.1" - }, - "click": { - "hashes": [ - "sha256:255bc9599cf7748b4b1a446ccc735421bd08a2ae529a8b88597d3de5664ee360", - "sha256:ba0d2089de75ea0310e2dde03160e6ca10009947fb95a182f9b54021bb272e34" - ], - "markers": "python_version >= '3.10'", - "version": "==8.5.0" - }, - "colorama": { - "hashes": [ - "sha256:08695f5cb7ed6e0531a20572697297273c47b8cae5a63ffc6d6ed5c201be6e44", - "sha256:4f1d9991f5acc0ca119f9d443620b77f9d6b33703e51011c16baf57afb285fc6" - ], - "markers": "python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2, 3.3, 3.4, 3.5, 3.6'", - "version": "==0.4.6" - }, - "ghp-import": { - "hashes": [ - "sha256:8337dd7b50877f163d4c0289bc1f1c7f127550241988d568c1db512c4324a619", - "sha256:9c535c4c61193c2df8871222567d7fd7e5014d835f97dc7b7439069e2413d343" - ], - "version": "==2.1.0" - }, - "hjson": { - "hashes": [ - "sha256:55af475a27cf83a7969c808399d7bccdec8fb836a07ddbd574587593b9cdcf75", - "sha256:65713cdcf13214fb554eb8b4ef803419733f4f5e551047c9b711098ab7186b89" - ], - "version": "==3.1.0" - }, - "idna": { - "hashes": [ - "sha256:5e0811a4383b21dc5838069f801c4fb62113b7447663d2530d2bd6e77b49bf15", - "sha256:815e7be7a7806d54abb586dc943addc79e8b2ee16915059658cbeff4b1b43bf4" - ], - "markers": "python_version >= '3.9'", - "version": "==3.19" - }, - "jinja2": { - "hashes": [ - "sha256:0137fb05990d35f1275a587e9aee6d56da821fc83491a0fb838183be43f66d6d", - "sha256:85ece4451f492d0c13c5dd7c13a64681a86afae63a5f347908daf103ce6d2f67" - ], - "markers": "python_version >= '3.7'", - "version": "==3.1.6" - }, - "markdown": { - "hashes": [ - "sha256:3589362618f743188b4d955b874402bc814f4f83f544dc207719f4baa7d9c45f", - "sha256:fa6c92a00a4a3c98b22728c64a935ae1928250ae65058a6ded814d2cc29a4cea" - ], - "markers": "python_version >= '3.10'", - "version": "==3.10.3" - }, - "markupsafe": { - "hashes": [ - "sha256:0303439a41979d9e74d18ff5e2dd8c43ed6c6001fd40e5bf2e43f7bd9bbc523f", - "sha256:068f375c472b3e7acbe2d5318dea141359e6900156b5b2ba06a30b169086b91a", - "sha256:0bf2a864d67e76e5c9a34dc26ec616a66b9888e25e7b9460e1c76d3293bd9dbf", - "sha256:0db14f5dafddbb6d9208827849fad01f1a2609380add406671a26386cdf15a19", - "sha256:0eb9ff8191e8498cca014656ae6b8d61f39da5f95b488805da4bb029cccbfbaf", - "sha256:0f4b68347f8c5eab4a13419215bdfd7f8c9b19f2b25520968adfad23eb0ce60c", - "sha256:1085e7fbddd3be5f89cc898938f42c0b3c711fdcb37d75221de2666af647c175", - "sha256:116bb52f642a37c115f517494ea5feb03889e04df47eeff5b130b1808ce7c219", - "sha256:12c63dfb4a98206f045aa9563db46507995f7ef6d83b2f68eda65c307c6829eb", - "sha256:133a43e73a802c5562be9bbcd03d090aa5a1fe899db609c29e8c8d815c5f6de6", - "sha256:1353ef0c1b138e1907ae78e2f6c63ff67501122006b0f9abad68fda5f4ffc6ab", - "sha256:15d939a21d546304880945ca1ecb8a039db6b4dc49b2c5a400387cdae6a62e26", - "sha256:177b5253b2834fe3678cb4a5f0059808258584c559193998be2601324fdeafb1", - "sha256:1872df69a4de6aead3491198eaf13810b565bdbeec3ae2dc8780f14458ec73ce", - "sha256:1b4b79e8ebf6b55351f0d91fe80f893b4743f104bff22e90697db1590e47a218", - "sha256:1b52b4fb9df4eb9ae465f8d0c228a00624de2334f216f178a995ccdcf82c4634", - "sha256:1ba88449deb3de88bd40044603fafffb7bc2b055d626a330323a9ed736661695", - "sha256:1cc7ea17a6824959616c525620e387f6dd30fec8cb44f649e31712db02123dad", - "sha256:218551f6df4868a8d527e3062d0fb968682fe92054e89978594c28e642c43a73", - "sha256:26a5784ded40c9e318cfc2bdb30fe164bdb8665ded9cd64d500a34fb42067b1c", - "sha256:2713baf880df847f2bece4230d4d094280f4e67b1e813eec43b4c0e144a34ffe", - "sha256:2a15a08b17dd94c53a1da0438822d70ebcd13f8c3a95abe3a9ef9f11a94830aa", - "sha256:2f981d352f04553a7171b8e44369f2af4055f888dfb147d55e42d29e29e74559", - "sha256:32001d6a8fc98c8cb5c947787c5d08b0a50663d139f1305bac5885d98d9b40fa", - "sha256:3524b778fe5cfb3452a09d31e7b5adefeea8c5be1d43c4f810ba09f2ceb29d37", - "sha256:3537e01efc9d4dccdf77221fb1cb3b8e1a38d5428920e0657ce299b20324d758", - "sha256:35add3b638a5d900e807944a078b51922212fb3dedb01633a8defc4b01a3c85f", - "sha256:38664109c14ffc9e7437e86b4dceb442b0096dfe3541d7864d9cbe1da4cf36c8", - "sha256:3a7e8ae81ae39e62a41ec302f972ba6ae23a5c5396c8e60113e9066ef893da0d", - "sha256:3b562dd9e9ea93f13d53989d23a7e775fdfd1066c33494ff43f5418bc8c58a5c", - "sha256:457a69a9577064c05a97c41f4e65148652db078a3a509039e64d3467b9e7ef97", - "sha256:4bd4cd07944443f5a265608cc6aab442e4f74dff8088b0dfc8238647b8f6ae9a", - "sha256:4e885a3d1efa2eadc93c894a21770e4bc67899e3543680313b09f139e149ab19", - "sha256:4faffd047e07c38848ce017e8725090413cd80cbc23d86e55c587bf979e579c9", - "sha256:509fa21c6deb7a7a273d629cf5ec029bc209d1a51178615ddf718f5918992ab9", - "sha256:5678211cb9333a6468fb8d8be0305520aa073f50d17f089b5b4b477ea6e67fdc", - "sha256:591ae9f2a647529ca990bc681daebdd52c8791ff06c2bfa05b65163e28102ef2", - "sha256:5a7d5dc5140555cf21a6fefbdbf8723f06fcd2f63ef108f2854de715e4422cb4", - "sha256:69c0b73548bc525c8cb9a251cddf1931d1db4d2258e9599c28c07ef3580ef354", - "sha256:6b5420a1d9450023228968e7e6a9ce57f65d148ab56d2313fcd589eee96a7a50", - "sha256:722695808f4b6457b320fdc131280796bdceb04ab50fe1795cd540799ebe1698", - "sha256:729586769a26dbceff69f7a7dbbf59ab6572b99d94576a5592625d5b411576b9", - "sha256:77f0643abe7495da77fb436f50f8dab76dbc6e5fd25d39589a0f1fe6548bfa2b", - "sha256:795e7751525cae078558e679d646ae45574b47ed6e7771863fcc079a6171a0fc", - "sha256:7be7b61bb172e1ed687f1754f8e7484f1c8019780f6f6b0786e76bb01c2ae115", - "sha256:7c3fb7d25180895632e5d3148dbdc29ea38ccb7fd210aa27acbd1201a1902c6e", - "sha256:7e68f88e5b8799aa49c85cd116c932a1ac15caaa3f5db09087854d218359e485", - "sha256:83891d0e9fb81a825d9a6d61e3f07550ca70a076484292a70fde82c4b807286f", - "sha256:8485f406a96febb5140bfeca44a73e3ce5116b2501ac54fe953e488fb1d03b12", - "sha256:8709b08f4a89aa7586de0aadc8da56180242ee0ada3999749b183aa23df95025", - "sha256:8f71bc33915be5186016f675cd83a1e08523649b0e33efdb898db577ef5bb009", - "sha256:915c04ba3851909ce68ccc2b8e2cd691618c4dc4c4232fb7982bca3f41fd8c3d", - "sha256:949b8d66bc381ee8b007cd945914c721d9aba8e27f71959d750a46f7c282b20b", - "sha256:94c6f0bb423f739146aec64595853541634bde58b2135f27f61c1ffd1cd4d16a", - "sha256:9a1abfdc021a164803f4d485104931fb8f8c1efd55bc6b748d2f5774e78b62c5", - "sha256:9b79b7a16f7fedff2495d684f2b59b0457c3b493778c9eed31111be64d58279f", - "sha256:a320721ab5a1aba0a233739394eb907f8c8da5c98c9181d1161e77a0c8e36f2d", - "sha256:a4afe79fb3de0b7097d81da19090f4df4f8d3a2b3adaa8764138aac2e44f3af1", - "sha256:ad2cf8aa28b8c020ab2fc8287b0f823d0a7d8630784c31e9ee5edea20f406287", - "sha256:b8512a91625c9b3da6f127803b166b629725e68af71f8184ae7e7d54686a56d6", - "sha256:bc51efed119bc9cfdf792cdeaa4d67e8f6fcccab66ed4bfdd6bde3e59bfcbb2f", - "sha256:bdc919ead48f234740ad807933cdf545180bfbe9342c2bb451556db2ed958581", - "sha256:bdd37121970bfd8be76c5fb069c7751683bdf373db1ed6c010162b2a130248ed", - "sha256:be8813b57049a7dc738189df53d69395eba14fb99345e0a5994914a3864c8a4b", - "sha256:c0c0b3ade1c0b13b936d7970b1d37a57acde9199dc2aecc4c336773e1d86049c", - "sha256:c47a551199eb8eb2121d4f0f15ae0f923d31350ab9280078d1e5f12b249e0026", - "sha256:c4ffb7ebf07cfe8931028e3e4c85f0357459a3f9f9490886198848f4fa002ec8", - "sha256:ccfcd093f13f0f0b7fdd0f198b90053bf7b2f02a3927a30e63f3ccc9df56b676", - "sha256:d2ee202e79d8ed691ceebae8e0486bd9a2cd4794cec4824e1c99b6f5009502f6", - "sha256:d53197da72cc091b024dd97249dfc7794d6a56530370992a5e1a08983ad9230e", - "sha256:d6dd0be5b5b189d31db7cda48b91d7e0a9795f31430b7f271219ab30f1d3ac9d", - "sha256:d88b440e37a16e651bda4c7c2b930eb586fd15ca7406cb39e211fcff3bf3017d", - "sha256:de8a88e63464af587c950061a5e6a67d3632e36df62b986892331d4620a35c01", - "sha256:df2449253ef108a379b8b5d6b43f4b1a8e81a061d6537becd5582fba5f9196d7", - "sha256:e1c1493fb6e50ab01d20a22826e57520f1284df32f2d8601fdd90b6304601419", - "sha256:e1cf1972137e83c5d4c136c43ced9ac51d0e124706ee1c8aa8532c1287fa8795", - "sha256:e2103a929dfa2fcaf9bb4e7c091983a49c9ac3b19c9061b6d5427dd7d14d81a1", - "sha256:e56b7d45a839a697b5eb268c82a71bd8c7f6c94d6fd50c3d577fa39a9f1409f5", - "sha256:e8afc3f2ccfa24215f8cb28dcf43f0113ac3c37c2f0f0806d8c70e4228c5cf4d", - "sha256:e8fc20152abba6b83724d7ff268c249fa196d8259ff481f3b1476383f8f24e42", - "sha256:eaa9599de571d72e2daf60164784109f19978b327a3910d3e9de8c97b5b70cfe", - "sha256:ec15a59cf5af7be74194f7ab02d0f59a62bdcf1a537677ce67a2537c9b87fcda", - "sha256:f190daf01f13c72eac4efd5c430a8de82489d9cff23c364c3ea822545032993e", - "sha256:f34c41761022dd093b4b6896d4810782ffbabe30f2d443ff5f083e0cbbb8c737", - "sha256:f3e98bb3798ead92273dc0e5fd0f31ade220f59a266ffd8a4f6065e0a3ce0523", - "sha256:f42d0984e947b8adf7dd6dde396e720934d12c506ce84eea8476409563607591", - "sha256:f71a396b3bf33ecaa1626c255855702aca4d3d9fea5e051b41ac59a9c1c41edc", - "sha256:f9e130248f4462aaa8e2552d547f36ddadbeaa573879158d721bbd33dfe4743a", - "sha256:fed51ac40f757d41b7c48425901843666a6677e3e8eb0abcff09e4ba6e664f50" - ], - "markers": "python_version >= '3.9'", - "version": "==3.0.3" - }, - "mergedeep": { - "hashes": [ - "sha256:0096d52e9dad9939c3d975a774666af186eda617e6ca84df4c94dec30004f2a8", - "sha256:70775750742b25c0d8f36c55aed03d24c3384d17c951b3175d898bd778ef0307" - ], - "markers": "python_version >= '3.6'", - "version": "==1.3.4" - }, - "mike": { - "hashes": [ - "sha256:39933e992e155dd70f2297e749a0ed78d8fd7942bc33a3666195d177758a280e", - "sha256:75d549420b134603805a65fc67f7dcd9fcd0ad1454fb2c893d9e844cba1aa6e4" - ], - "index": "pypi", - "version": "==2.1.4" - }, - "mkdocs": { - "hashes": [ - "sha256:7b432f01d928c084353ab39c57282f29f92136665bdd6abf7c1ec8d822ef86f2", - "sha256:db91759624d1647f3f34aa0c3f327dd2601beae39a366d6e064c03468d35c20e" - ], - "index": "pypi", - "markers": "python_version >= '3.8'", - "version": "==1.6.1" - }, - "mkdocs-get-deps": { - "hashes": [ - "sha256:8ee8d5f316cdbbb2834bc1df6e69c08fe769a83e040060de26d3c19fad3599a1", - "sha256:e7878cbeac04860b8b5e0ca31d3abad3df9411a75a32cde82f8e44b6c16ff650" - ], - "markers": "python_version >= '3.9'", - "version": "==0.2.2" - }, - "mkdocs-macros-plugin": { - "hashes": [ - "sha256:12aa45ce7ecb7a445c66b9f649f3dd05e9b92e8af6bc65e4acd91d26f878c01f", - "sha256:c10fabd812bf50f9170609d0ed518e54f1f0e12c334ac29141723a83c881dd6f" - ], - "index": "pypi", - "markers": "python_version >= '3.8'", - "version": "==1.5.0" - }, - "mkdocs-material": { - "hashes": [ - "sha256:8ea9bb1737a5b524a5f9dcf2e1b4ebda8274ae3008aa7845720a97083bef708f", - "sha256:c0649c065b1b0512d60aad8c10f947f8e455284475239b364b610f2deb4d0855" - ], - "index": "pypi", - "markers": "python_version >= '3.8'", - "version": "==9.7.7" - }, - "mkdocs-material-extensions": { - "hashes": [ - "sha256:10c9511cea88f568257f960358a467d12b970e1f7b2c0e5fb2bb48cab1928443", - "sha256:adff8b62700b25cb77b53358dad940f3ef973dd6db797907c49e3c2ef3ab4e31" - ], - "markers": "python_version >= '3.8'", - "version": "==1.3.1" - }, - "packaging": { - "hashes": [ - "sha256:94edc256424af38762eb31306eed28beb9f0efc50a8837492c9d6fd6004aed79", - "sha256:d7193f7c8e4e93f444fde0262bf90af30e16fa0ad0ad44cb553c87339b23cd1c" - ], - "markers": "python_version >= '3.9'", - "version": "==26.3" - }, - "paginate": { - "hashes": [ - "sha256:22bd083ab41e1a8b4f3690544afb2c60c25e5c9a63a30fa2f483f6c60c8e5945", - "sha256:b885e2af73abcf01d9559fd5216b57ef722f8c42affbb63942377668e35c7591" - ], - "version": "==0.5.7" - }, - "pathspec": { - "hashes": [ - "sha256:17db5ecd524104a120e173814c90367a96a98d07c45b2e10c2f3919fff91bf5a", - "sha256:a00ce642f577bf7f473932318056212bc4f8bfdf53128c78bbd5af0b9b20b189" - ], - "markers": "python_version >= '3.9'", - "version": "==1.1.1" - }, - "platformdirs": { - "hashes": [ - "sha256:4f41487eeeeeb07f3a6625e61d9bc0ae6809f92d3386dbd74392fbb76108104d", - "sha256:8a02cb259042c79d1cd0450facc2fe6dc9d303ae7901afbe33bf8ea0b188cef6" - ], - "markers": "python_version >= '3.10'", - "version": "==4.11.7" - }, - "pygments": { - "hashes": [ - "sha256:2363c69b61c4a97c838da3b130dcd6468f4848992b21a82f2a63ec34377137d9", - "sha256:610ca751c9bc2492b38eb9a38a7fbc93edbbb2d7182edaf34e66ae493dee5c8c" - ], - "markers": "python_version >= '3.9'", - "version": "==2.21.0" - }, - "pymdown-extensions": { - "hashes": [ - "sha256:259910762019732caa1dfd76f3faa62c59f191d46573e80bcb1d13c0f675bbe5", - "sha256:9506fcbe66fa355a775b768084334238dd6805020ac4b92bea0c0dda6f8f223d" - ], - "markers": "python_version >= '3.10'", - "version": "==11.0.2" - }, - "pyparsing": { - "hashes": [ - "sha256:850ba148bd908d7e2411587e247a1e4f0327839c40e2e5e6d05a007ecc69911d", - "sha256:c777f4d763f140633dcb6d8a3eda953bf7a214dc4eff598413c070bcdc117cbc" - ], - "markers": "python_version >= '3.9'", - "version": "==3.3.2" - }, - "python-dateutil": { - "hashes": [ - "sha256:37dd54208da7e1cd875388217d5e00ebd4179249f90fb72437e91a35459a0ad3", - "sha256:a8b2bc7bffae282281c8140a97d3aa9c14da0b136dfe83f850eea9a5f7470427" - ], - "markers": "python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2'", - "version": "==2.9.0.post0" - }, - "pyyaml": { - "hashes": [ - "sha256:00c4bdeba853cc34e7dd471f16b4114f4162dc03e6b7afcc2128711f0eca823c", - "sha256:0150219816b6a1fa26fb4699fb7daa9caf09eb1999f3b70fb6e786805e80375a", - "sha256:02893d100e99e03eda1c8fd5c441d8c60103fd175728e23e431db1b589cf5ab3", - "sha256:02ea2dfa234451bbb8772601d7b8e426c2bfa197136796224e50e35a78777956", - "sha256:0f29edc409a6392443abf94b9cf89ce99889a1dd5376d94316ae5145dfedd5d6", - "sha256:10892704fc220243f5305762e276552a0395f7beb4dbf9b14ec8fd43b57f126c", - "sha256:16249ee61e95f858e83976573de0f5b2893b3677ba71c9dd36b9cf8be9ac6d65", - "sha256:1d37d57ad971609cf3c53ba6a7e365e40660e3be0e5175fa9f2365a379d6095a", - "sha256:1ebe39cb5fc479422b83de611d14e2c0d3bb2a18bbcb01f229ab3cfbd8fee7a0", - "sha256:214ed4befebe12df36bcc8bc2b64b396ca31be9304b8f59e25c11cf94a4c033b", - "sha256:2283a07e2c21a2aa78d9c4442724ec1eb15f5e42a723b99cb3d822d48f5f7ad1", - "sha256:22ba7cfcad58ef3ecddc7ed1db3409af68d023b7f940da23c6c2a1890976eda6", - "sha256:27c0abcb4a5dac13684a37f76e701e054692a9b2d3064b70f5e4eb54810553d7", - "sha256:28c8d926f98f432f88adc23edf2e6d4921ac26fb084b028c733d01868d19007e", - "sha256:2e71d11abed7344e42a8849600193d15b6def118602c4c176f748e4583246007", - "sha256:34d5fcd24b8445fadc33f9cf348c1047101756fd760b4dacb5c3e99755703310", - "sha256:37503bfbfc9d2c40b344d06b2199cf0e96e97957ab1c1b546fd4f87e53e5d3e4", - "sha256:3c5677e12444c15717b902a5798264fa7909e41153cdf9ef7ad571b704a63dd9", - "sha256:3ff07ec89bae51176c0549bc4c63aa6202991da2d9a6129d7aef7f1407d3f295", - "sha256:41715c910c881bc081f1e8872880d3c650acf13dfa8214bad49ed4cede7c34ea", - "sha256:418cf3f2111bc80e0933b2cd8cd04f286338bb88bdc7bc8e6dd775ebde60b5e0", - "sha256:44edc647873928551a01e7a563d7452ccdebee747728c1080d881d68af7b997e", - "sha256:4a2e8cebe2ff6ab7d1050ecd59c25d4c8bd7e6f400f5f82b96557ac0abafd0ac", - "sha256:4ad1906908f2f5ae4e5a8ddfce73c320c2a1429ec52eafd27138b7f1cbe341c9", - "sha256:501a031947e3a9025ed4405a168e6ef5ae3126c59f90ce0cd6f2bfc477be31b7", - "sha256:5190d403f121660ce8d1d2c1bb2ef1bd05b5f68533fc5c2ea899bd15f4399b35", - "sha256:5498cd1645aa724a7c71c8f378eb29ebe23da2fc0d7a08071d89469bf1d2defb", - "sha256:5cf4e27da7e3fbed4d6c3d8e797387aaad68102272f8f9752883bc32d61cb87b", - "sha256:5e0b74767e5f8c593e8c9b5912019159ed0533c70051e9cce3e8b6aa699fcd69", - "sha256:5ed875a24292240029e4483f9d4a4b8a1ae08843b9c54f43fcc11e404532a8a5", - "sha256:5fcd34e47f6e0b794d17de1b4ff496c00986e1c83f7ab2fb8fcfe9616ff7477b", - "sha256:5fdec68f91a0c6739b380c83b951e2c72ac0197ace422360e6d5a959d8d97b2c", - "sha256:6344df0d5755a2c9a276d4473ae6b90647e216ab4757f8426893b5dd2ac3f369", - "sha256:64386e5e707d03a7e172c0701abfb7e10f0fb753ee1d773128192742712a98fd", - "sha256:652cb6edd41e718550aad172851962662ff2681490a8a711af6a4d288dd96824", - "sha256:66291b10affd76d76f54fad28e22e51719ef9ba22b29e1d7d03d6777a9174198", - "sha256:66e1674c3ef6f541c35191caae2d429b967b99e02040f5ba928632d9a7f0f065", - "sha256:6adc77889b628398debc7b65c073bcb99c4a0237b248cacaf3fe8a557563ef6c", - "sha256:79005a0d97d5ddabfeeea4cf676af11e647e41d81c9a7722a193022accdb6b7c", - "sha256:7c6610def4f163542a622a73fb39f534f8c101d690126992300bf3207eab9764", - "sha256:7f047e29dcae44602496db43be01ad42fc6f1cc0d8cd6c83d342306c32270196", - "sha256:8098f252adfa6c80ab48096053f512f2321f0b998f98150cea9bd23d83e1467b", - "sha256:850774a7879607d3a6f50d36d04f00ee69e7fc816450e5f7e58d7f17f1ae5c00", - "sha256:8d1fab6bb153a416f9aeb4b8763bc0f22a5586065f86f7664fc23339fc1c1fac", - "sha256:8da9669d359f02c0b91ccc01cac4a67f16afec0dac22c2ad09f46bee0697eba8", - "sha256:8dc52c23056b9ddd46818a57b78404882310fb473d63f17b07d5c40421e47f8e", - "sha256:9149cad251584d5fb4981be1ecde53a1ca46c891a79788c0df828d2f166bda28", - "sha256:93dda82c9c22deb0a405ea4dc5f2d0cda384168e466364dec6255b293923b2f3", - "sha256:96b533f0e99f6579b3d4d4995707cf36df9100d67e0c8303a0c55b27b5f99bc5", - "sha256:9c57bb8c96f6d1808c030b1687b9b5fb476abaa47f0db9c0101f5e9f394e97f4", - "sha256:9c7708761fccb9397fe64bbc0395abcae8c4bf7b0eac081e12b809bf47700d0b", - "sha256:9f3bfb4965eb874431221a3ff3fdcddc7e74e3b07799e0e84ca4a0f867d449bf", - "sha256:a33284e20b78bd4a18c8c2282d549d10bc8408a2a7ff57653c0cf0b9be0afce5", - "sha256:a80cb027f6b349846a3bf6d73b5e95e782175e52f22108cfa17876aaeff93702", - "sha256:b30236e45cf30d2b8e7b3e85881719e98507abed1011bf463a8fa23e9c3e98a8", - "sha256:b3bc83488de33889877a0f2543ade9f70c67d66d9ebb4ac959502e12de895788", - "sha256:b865addae83924361678b652338317d1bd7e79b1f4596f96b96c77a5a34b34da", - "sha256:b8bb0864c5a28024fac8a632c443c87c5aa6f215c0b126c449ae1a150412f31d", - "sha256:ba1cc08a7ccde2d2ec775841541641e4548226580ab850948cbfda66a1befcdc", - "sha256:bdb2c67c6c1390b63c6ff89f210c8fd09d9a1217a465701eac7316313c915e4c", - "sha256:c1ff362665ae507275af2853520967820d9124984e0f7466736aea23d8611fba", - "sha256:c2514fceb77bc5e7a2f7adfaa1feb2fb311607c9cb518dbc378688ec73d8292f", - "sha256:c3355370a2c156cffb25e876646f149d5d68f5e0a3ce86a5084dd0b64a994917", - "sha256:c458b6d084f9b935061bc36216e8a69a7e293a2f1e68bf956dcd9e6cbcd143f5", - "sha256:d0eae10f8159e8fdad514efdc92d74fd8d682c933a6dd088030f3834bc8e6b26", - "sha256:d76623373421df22fb4cf8817020cbb7ef15c725b9d5e45f17e189bfc384190f", - "sha256:ebc55a14a21cb14062aa4162f906cd962b28e2e9ea38f9b4391244cd8de4ae0b", - "sha256:eda16858a3cab07b80edaf74336ece1f986ba330fdb8ee0d6c0d68fe82bc96be", - "sha256:ee2922902c45ae8ccada2c5b501ab86c36525b883eff4255313a253a3160861c", - "sha256:efd7b85f94a6f21e4932043973a7ba2613b059c4a000551892ac9f1d11f5baf3", - "sha256:f7057c9a337546edc7973c0d3ba84ddcdf0daa14533c2065749c9075001090e6", - "sha256:fa160448684b4e94d80416c0fa4aac48967a969efe22931448d853ada8baf926", - "sha256:fc09d0aa354569bc501d4e787133afc08552722d3ab34836a80547331bb5d4a0" - ], - "markers": "python_version >= '3.8'", - "version": "==6.0.3" - }, - "pyyaml-env-tag": { - "hashes": [ - "sha256:17109e1a528561e32f026364712fee1264bc2ea6715120891174ed1b980d2e04", - "sha256:2eb38b75a2d21ee0475d6d97ec19c63287a7e140231e4214969d0eac923cd7ff" - ], - "markers": "python_version >= '3.9'", - "version": "==1.1" - }, - "requests": { - "hashes": [ - "sha256:2a0d60c172f83ac6ab31e4554906c0f3b3588d37b5cb939b1c061f4907e278e0", - "sha256:f288924cae4e29463698d6d60bc6a4da69c89185ad1e0bcc4104f584e960b9ed" - ], - "markers": "python_version >= '3.10'", - "version": "==2.34.2" - }, - "six": { - "hashes": [ - "sha256:4721f391ed90541fddacab5acf947aa0d3dc7d27b2e1e8eda2be8970586c3274", - "sha256:ff70335d468e7eb6ec65b95b99d3a2836546063f63acc5171de367e834932a81" - ], - "markers": "python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2'", - "version": "==1.17.0" - }, - "super-collections": { - "hashes": [ - "sha256:0c8d8abacd9fad2c7c1c715f036c29f5db213f8cac65f24d45ecba12b4da187a", - "sha256:291b74d26299e9051d69ad9d89e61b07b6646f86a57a2f5ab3063d206eee9c56" - ], - "markers": "python_version >= '3.8'", - "version": "==0.6.2" - }, - "termcolor": { - "hashes": [ - "sha256:348871ca648ec6a9a983a13ab626c0acce02f515b9e1983332b17af7979521c5", - "sha256:cf642efadaf0a8ebbbf4bc7a31cec2f9b5f21a9f726f4ccbb08192c9c26f43a5" - ], - "markers": "python_version >= '3.10'", - "version": "==3.3.0" - }, - "urllib3": { - "hashes": [ - "sha256:0cf3cae568d36aa9576b28dfb35f11328f1cb974ca7647d9475ebb86c75ac6e3", - "sha256:63bf2ead4c879426ebf22ef2a781eeb4aa3b4ae798a0435506f8687fd5bb9b63" - ], - "index": "pypi", - "markers": "python_version >= '3.10'", - "version": "==2.8.0" - }, - "verspec": { - "hashes": [ - "sha256:741877d5633cc9464c45a469ae2a31e801e6dbbaa85b9675d481cda100f11c31", - "sha256:c4504ca697b2056cdb4bfa7121461f5a0e81809255b41c03dda4ba823637c01e" - ], - "version": "==0.1.0" - }, - "watchdog": { - "hashes": [ - "sha256:07df1fdd701c5d4c8e55ef6cf55b8f0120fe1aef7ef39a1c6fc6bc2e606d517a", - "sha256:20ffe5b202af80ab4266dcd3e91aae72bf2da48c0d33bdb15c66658e685e94e2", - "sha256:212ac9b8bf1161dc91bd09c048048a95ca3a4c4f5e5d4a7d1b1a7d5752a7f96f", - "sha256:2cce7cfc2008eb51feb6aab51251fd79b85d9894e98ba847408f662b3395ca3c", - "sha256:490ab2ef84f11129844c23fb14ecf30ef3d8a6abafd3754a6f75ca1e6654136c", - "sha256:6eb11feb5a0d452ee41f824e271ca311a09e250441c262ca2fd7ebcf2461a06c", - "sha256:6f10cb2d5902447c7d0da897e2c6768bca89174d0c6e1e30abec5421af97a5b0", - "sha256:7607498efa04a3542ae3e05e64da8202e58159aa1fa4acddf7678d34a35d4f13", - "sha256:76aae96b00ae814b181bb25b1b98076d5fc84e8a53cd8885a318b42b6d3a5134", - "sha256:7a0e56874cfbc4b9b05c60c8a1926fedf56324bb08cfbc188969777940aef3aa", - "sha256:82dc3e3143c7e38ec49d61af98d6558288c415eac98486a5c581726e0737c00e", - "sha256:9041567ee8953024c83343288ccc458fd0a2d811d6a0fd68c4c22609e3490379", - "sha256:90c8e78f3b94014f7aaae121e6b909674df5b46ec24d6bebc45c44c56729af2a", - "sha256:9513f27a1a582d9808cf21a07dae516f0fab1cf2d7683a742c498b93eedabb11", - "sha256:9ddf7c82fda3ae8e24decda1338ede66e1c99883db93711d8fb941eaa2d8c282", - "sha256:a175f755fc2279e0b7312c0035d52e27211a5bc39719dd529625b1930917345b", - "sha256:a1914259fa9e1454315171103c6a30961236f508b9b623eae470268bbcc6a22f", - "sha256:afd0fe1b2270917c5e23c2a65ce50c2a4abb63daafb0d419fde368e272a76b7c", - "sha256:bc64ab3bdb6a04d69d4023b29422170b74681784ffb9463ed4870cf2f3e66112", - "sha256:bdd4e6f14b8b18c334febb9c4425a878a2ac20efd1e0b231978e7b150f92a948", - "sha256:c7ac31a19f4545dd92fc25d200694098f42c9a8e391bc00bdd362c5736dbf881", - "sha256:c7c15dda13c4eb00d6fb6fc508b3c0ed88b9d5d374056b239c4ad1611125c860", - "sha256:c897ac1b55c5a1461e16dae288d22bb2e412ba9807df8397a635d88f671d36c3", - "sha256:cbafb470cf848d93b5d013e2ecb245d4aa1c8fd0504e863ccefa32445359d680", - "sha256:d1cdb490583ebd691c012b3d6dae011000fe42edb7a82ece80965b42abd61f26", - "sha256:e3df4cbb9a450c6d49318f6d14f4bbc80d763fa587ba46ec86f99f9e6876bb26", - "sha256:e6439e374fc012255b4ec786ae3c4bc838cd7309a540e5fe0952d03687d8804e", - "sha256:e6f0e77c9417e7cd62af82529b10563db3423625c5fce018430b249bf977f9e8", - "sha256:e7631a77ffb1f7d2eefa4445ebbee491c720a5661ddf6df3498ebecae5ed375c", - "sha256:ef810fbf7b781a5a593894e4f439773830bdecb885e6880d957d5b9382a960d2" - ], - "markers": "python_version >= '3.9'", - "version": "==6.0.0" - } - }, - "develop": {} -} diff --git a/documentation/README.adoc b/documentation/README.adoc new file mode 100644 index 000000000..278640984 --- /dev/null +++ b/documentation/README.adoc @@ -0,0 +1,62 @@ += SmallRye Config documentation + +The documentation is AsciiDoc, laid out like the Quarkus guides, and published on +https://smallrye.io/docs/smallrye-config/latest/[smallrye.io]. The site pulls it from this +repository: the `main` branch every night, and each release once it is tagged. + +== Where things are + +[cols="1,2"] +|=== +|`src/main/asciidoc/**/*.adoc` |One page per file. The path is the page's address: `config/mappings.adoc` is published at `/docs/smallrye-config//config/mappings/`. +|`src/main/asciidoc/_nav.yml` |The sidebar: page order and sections. A new page must be added here. +|`src/main/asciidoc/_attributes.adoc` |Attributes every page includes (ids, paths, project values). +|=== + +== Writing a page + +[source,asciidoc] +------ += Page title +:version-root: ../ +include::{version-root}_attributes.adoc[] +:summary: One sentence for search engines and the page description. + +Text... + +== A section + +Link to another page with xref:config/profiles.adoc[Profiles], or to a section of it with +xref:config/profiles.adoc#parent-profile[]. Paths in xrefs start at `src/main/asciidoc`. + +[source,xml,subs="attributes+"] +---- +{project-version} +---- +------ + +* A page in a subdirectory sets `:version-root:` (`../` per level) before including + `_attributes.adoc`; a page at the top includes `_attributes.adoc` directly. +* Section ids are Quarkus-style: `== Parent Profile` gets the id `parent-profile`. +* `{project-version}` is the release the documentation belongs to (set by smallrye.io). +* Admonitions: `NOTE:`, `TIP:`, `IMPORTANT:`, `WARNING:`, `CAUTION:`. + +== Previewing + +Pull requests that change the documentation are rendered with the smallrye.io site by the +`Documentation` workflow, which fails on a broken include or a page that does not render. The +rendered site is attached to the workflow run as the `docs-smallrye-config` artifact. + +To see the documentation the way smallrye.io shows it while you write it, run from this repository: + +[source,bash] +---- +./mvnw -Pdocs-preview +---- + +and open http://localhost:8080/docs/smallrye-config/main/. Pages and included examples are published again +when you save them; refresh the page. Only Java is needed: the profile runs the +https://github.com/smallrye/smallrye.github.io/tree/develop/tools/docs[smallrye.io docs tools] +with https://www.jbang.dev[JBang]. Where JBang is installed, `jbang docs-preview@smallrye/smallrye.github.io` +does the same, and takes options such as `--port` or `--site ` +(see `--help`). diff --git a/documentation/mkdocs.yaml b/documentation/mkdocs.yaml deleted file mode 100644 index dd6f34959..000000000 --- a/documentation/mkdocs.yaml +++ /dev/null @@ -1,125 +0,0 @@ -site_name: SmallRye Config -site_url: https://smallrye.io/smallrye-config -repo_url: https://github.com/smallrye/smallrye-config -edit_uri: edit/main/documentation/src/main/docs - -docs_dir: src/main/docs - -nav: - - Home: index.md - - - Config: - - 'Getting Started': config/getting-started.md - - 'Expressions': config/expressions.md - - 'Profiles': config/profiles.md - - 'Environment Variables': config/environment-variables.md - - 'Indexed Properties': config/indexed-properties.md - - 'ConfigValue': config/config-value.md - - 'Mappings': config/mappings.md - - 'Instance Builder': config/instance-builder.md - - 'Map Support': config/map-support.md - - 'Secret Keys': config/secret-keys.md - - 'Customizer': config/customizer.md - - 'Configuration Reference': config/configuration.md - - Config Sources: - - 'Custom': config-sources/custom.md - - 'Factories': config-sources/factories.md - - 'Locations': config-sources/locations.md - - 'YAML': config-sources/yaml.md - - 'TOML': config-sources/toml.md - - 'JSON': config-sources/json.md - - 'FileSystem': config-sources/filesystem.md - - 'ZooKeeper': config-sources/zookeeper.md - - 'HOCON': config-sources/hocon.md - - 'KeyStore': config-sources/keystore.md - - Converters: - - 'Custom': converters/custom.md - - Extensions: - - 'Interceptors': extensions/interceptors.md - - 'Fallback': extensions/fallback.md - - 'Relocate': extensions/relocate.md - - 'Logging': extensions/logging.md - -plugins: - - search - - macros: - module_name: src/main/macros/docissimo - include_dir: src/main/macros - - mike: - version_selector: true - css_dir: css - javascript_dir: javascript - -copyright: >- - Sponsored by Red Hat
- CC by 3.0 | - Privacy Policy - -theme: - name: material - logo: assets/smallrye-icon.svg - font: - text: Roboto - code: JetBrains Mono - icon: - repo: fontawesome/brands/github - favicon: assets/favicon.ico - features: - - navigation.instant - - navigation.indexes - - navigation.sections - - navigation.tracking - - navigation.tabs - - navigation.tabs.sticky - palette: - - media: "(prefers-color-scheme: light)" - scheme: default - primary: blue-grey - accent: red - toggle: - icon: material/lightbulb-night - name: Switch to dark mode - - media: "(prefers-color-scheme: dark)" - scheme: slate - primary: black - accent: orange - toggle: - icon: material/lightbulb-on - name: Switch to light mode - -markdown_extensions: - - toc: - toc_depth: 3 - permalink: '#' - - admonition - - smarty - - attr_list - - md_in_html - - meta - - tables - - pymdownx.highlight: - anchor_linenums: true - - pymdownx.superfences: - custom_fences: - - name: mermaid - class: mermaid - format: !!python/name:pymdownx.superfences.fence_code_format - - pymdownx.snippets - - pymdownx.inlinehilite - - pymdownx.details - - pymdownx.smartsymbols - - pymdownx.betterem - - pymdownx.tabbed: - alternate_style: true - - pymdownx.emoji: - emoji_index: !!python/name:material.extensions.emoji.twemoji - emoji_generator: !!python/name:material.extensions.emoji.to_svg - -extra_css: - - assets/extra.css - -extra: - version: - provider: mike - snippet_dir: src/main/java - attributes_path: target/classes/attributes.yaml diff --git a/documentation/pom.xml b/documentation/pom.xml index fb45278ea..13d887345 100644 --- a/documentation/pom.xml +++ b/documentation/pom.xml @@ -15,32 +15,6 @@ - - org.apache.maven.plugins - maven-resources-plugin - - - update-attributes - initialize - - copy-resources - - - ${project.build.outputDirectory} - - - src/main/resources - true - - attributes.yaml - - - - - - - - org.apache.maven.plugins maven-install-plugin diff --git a/documentation/src/main/asciidoc/_attributes.adoc b/documentation/src/main/asciidoc/_attributes.adoc new file mode 100644 index 000000000..e6d5d6aba --- /dev/null +++ b/documentation/src/main/asciidoc/_attributes.adoc @@ -0,0 +1,10 @@ +// Attributes shared by every page. smallrye.io overrides the ones it needs when it publishes. +// Pages in subdirectories set :version-root: (../ per level) before including this file. +ifndef::version-root[:version-root:] +:idprefix: +:idseparator: - +:sectanchors: +:examples-dir: {version-root}../java +:partialsdir: {version-root}_partials +:project-name: SmallRye Config +:javadoc-version: latest diff --git a/documentation/src/main/asciidoc/_nav.yml b/documentation/src/main/asciidoc/_nav.yml new file mode 100644 index 000000000..6a14b50be --- /dev/null +++ b/documentation/src/main/asciidoc/_nav.yml @@ -0,0 +1,66 @@ +title: SmallRye Config +nav: +- title: Home + page: index +- title: Config + items: + - title: Getting Started + page: config/getting-started + - title: Expressions + page: config/expressions + - title: Profiles + page: config/profiles + - title: Environment Variables + page: config/environment-variables + - title: Indexed Properties + page: config/indexed-properties + - title: ConfigValue + page: config/config-value + - title: Mappings + page: config/mappings + - title: Instance Builder + page: config/instance-builder + - title: Map Support + page: config/map-support + - title: Secret Keys + page: config/secret-keys + - title: Customizer + page: config/customizer + - title: Configuration Reference + page: config/configuration +- title: Config Sources + items: + - title: Custom + page: config-sources/custom + - title: Factories + page: config-sources/factories + - title: Locations + page: config-sources/locations + - title: YAML + page: config-sources/yaml + - title: TOML + page: config-sources/toml + - title: JSON + page: config-sources/json + - title: FileSystem + page: config-sources/filesystem + - title: ZooKeeper + page: config-sources/zookeeper + - title: HOCON + page: config-sources/hocon + - title: KeyStore + page: config-sources/keystore +- title: Converters + items: + - title: Custom + page: converters/custom +- title: Extensions + items: + - title: Interceptors + page: extensions/interceptors + - title: Fallback + page: extensions/fallback + - title: Relocate + page: extensions/relocate + - title: Logging + page: extensions/logging diff --git a/documentation/src/main/docs/config-sources/custom.md b/documentation/src/main/asciidoc/config-sources/custom.adoc similarity index 61% rename from documentation/src/main/docs/config-sources/custom.md rename to documentation/src/main/asciidoc/config-sources/custom.adoc index 173d08a51..bd9cc1444 100644 --- a/documentation/src/main/docs/config-sources/custom.md +++ b/documentation/src/main/asciidoc/config-sources/custom.adoc @@ -1,21 +1,24 @@ -# Config Sources += Config Sources +:version-root: ../ +include::{version-root}_attributes.adoc[] -## Custom `ConfigSource` +== Custom `ConfigSource` -It’s possible to create a custom ConfigSource as specified in -[MicroProfile Config](https://github.com/eclipse/microprofile-config/). +It’s possible to create a custom ConfigSource as specified in +https://github.com/eclipse/microprofile-config/[MicroProfile Config]. -With a Custom `ConfigSource` it is possible to read additional configuration values and add them to the `Config` +With a Custom `ConfigSource` it is possible to read additional configuration values and add them to the `Config` instance in a defined ordinal. This allows overriding values from other sources or falling back to other values. -A custom `ConfigSource` requires an implementation of `org.eclipse.microprofile.config.spi.ConfigSource` or -`org.eclipse.microprofile.config.spi.ConfigSourceProvider`. Each implementation requires registration via the -`ServiceLoader` mechanism, either in `META-INF/services/org.eclipse.microprofile.config.spi.ConfigSource` or +A custom `ConfigSource` requires an implementation of `org.eclipse.microprofile.config.spi.ConfigSource` or +`org.eclipse.microprofile.config.spi.ConfigSourceProvider`. Each implementation requires registration via the +`ServiceLoader` mechanism, either in `META-INF/services/org.eclipse.microprofile.config.spi.ConfigSource` or `META-INF/services/org.eclipse.microprofile.config.spi.ConfigSourceProvider` files. Consider a simple in-memory ConfigSource: -```java +[source,java] +---- package org.acme.config; import org.eclipse.microprofile.config.spi.ConfigSource; @@ -51,31 +54,34 @@ public class InMemoryConfigSource implements ConfigSource { return InMemoryConfigSource.class.getSimpleName(); } } -``` +---- And registration in: -```properties title="META-INF/services/org.eclipse.microprofile.config.spi.ConfigSource" +.META-INF/services/org.eclipse.microprofile.config.spi.ConfigSource +[source,properties] +---- org.acme.config.InMemoryConfigSource -``` +---- -The `InMemoryConfigSource` will be ordered between the `System properties` config source, and the +The `InMemoryConfigSource` will be ordered between the `System properties` config source, and the `Environment variables` config source due to the `350` ordinal. -In this case, `my.prop` from `InMemoryConfigSource` will only be used if the `Config` instance is unable to find a +In this case, `my.prop` from `InMemoryConfigSource` will only be used if the `Config` instance is unable to find a value in `System Properties`, ignoring all the other lower ordinal config sources. -## `ConfigSourceFactory` +== `ConfigSourceFactory` -Another way to create a `ConfigSource` is via the SmallRye Config `io.smallrye.config.ConfigSourceFactory` API. The +Another way to create a `ConfigSource` is via the SmallRye Config `io.smallrye.config.ConfigSourceFactory` API. The difference between the SmallRye Config factory and the standard way to create a `ConfigSource` as specified in -[MicroProfile Config](https://github.com/eclipse/microprofile-config/), is the factory ability to provide a context +https://github.com/eclipse/microprofile-config/[MicroProfile Config], is the factory ability to provide a context with access to the current configuration. -Each implementation of `io.smallrye.config.ConfigSourceFactory` requires registration via the `ServiceLoader` mechanism +Each implementation of `io.smallrye.config.ConfigSourceFactory` requires registration via the `ServiceLoader` mechanism in the `META-INF/services/io.smallrye.config.ConfigSourceFactory` file. -```java +[source,java] +---- package org.acme.config; import java.util.Collections; @@ -108,48 +114,53 @@ public class URLConfigSourceFactory implements ConfigSourceFactory { return OptionalInt.of(290); } } -``` +---- And registration in: -```properties title="META-INF/services/io.smallrye.config.ConfigSourceFactory" +.META-INF/services/io.smallrye.config.ConfigSourceFactory +[source,properties] +---- org.acme.config.URLConfigSourceFactory -``` +---- -By implementing `io.smallrye.config.ConfigSourceFactory`, a list of `ConfigSource` may be provided via the -`Iterable getConfigSources(ConfigSourceContext context)` method. The `ConfigSourceFactory` may also -assign a priority by overriding the method `OptionalInt getPriority()`. The priority value is used to sort multiple +By implementing `io.smallrye.config.ConfigSourceFactory`, a list of `ConfigSource` may be provided via the +`Iterable++<++ConfigSource++>++ getConfigSources(ConfigSourceContext context)` method. The `ConfigSourceFactory` may also +assign a priority by overriding the method `OptionalInt getPriority()`. The priority value is used to sort multiple `io.smallrye.config.ConfigSourceFactory` (if found). Higher the value, higher the priority. -!!!warning +[WARNING] +==== - The `io.smallrye.config.ConfigSourceFactory` priority does not affect the `ConfigSource` ordinal. These are sorted - independently. +The `io.smallrye.config.ConfigSourceFactory` priority does not affect the `ConfigSource` ordinal. These are sorted +independently. -When the Factory is initializing, the provided `ConfigSourceContext` may call the method -`ConfigValue getValue(String name)`. This method looks up configuration names in all `ConfigSource`s that were already -initialized by the `Config` instance, including sources with lower ordinals than the ones defined in the -`ConfigSourceFactory`. This means that a `Config` instance is initialized in two steps: first all `ConfigSource` and +==== + +When the Factory is initializing, the provided `ConfigSourceContext` may call the method +`ConfigValue getValue(String name)`. This method looks up configuration names in all `ConfigSource`s that were already +initialized by the `Config` instance, including sources with lower ordinals than the ones defined in the +`ConfigSourceFactory`. This means that a `Config` instance is initialized in two steps: first all `ConfigSource` and `ConfigSourceProvider` and then the `ConfigSourceFactory`. Only configuation values found in the first step are avaible -to the `ConfigSourceFactory. +to the ++`++ConfigSourceFactory. -The `ConfigSource` list provided by a `ConfigSourceFactory` is not taken into consideration to +The `ConfigSource` list provided by a `ConfigSourceFactory` is not taken into consideration to configure other sources produced by a lower priority `ConfigSourceFactory`. -## Override `ConfigSource` ordinal +== Override `ConfigSource` ordinal -The special configuration property name `config_ordinal` can be set in any `ConfigSource` to override its default +The special configuration property name `config++_++ordinal` can be set in any `ConfigSource` to override its default ordinal. -For instance, setting the system property `-Dconfig_ordinal=200` will override the ordinal for the `System properties` +For instance, setting the system property `-Dconfig++_++ordinal=200` will override the ordinal for the `System properties` config source and move it to be looked up after the `Environment Variables` config source. -## Properties +== Properties -The [PropertiesConfigSource](https://github.com/smallrye/smallrye-config/blob/main/implementation/src/main/java/io/smallrye/config/PropertiesConfigSource.java) -creates a `ConfigSource` from Java `Properties`, `Map` objects or a `.properties` file (referenced by +The https://github.com/smallrye/smallrye-config/blob/main/implementation/src/main/java/io/smallrye/config/PropertiesConfigSource.java[PropertiesConfigSource] +creates a `ConfigSource` from Java `Properties`, `Map++<++String, String++>++` objects or a `.properties` file (referenced by its URL). -## `.env` +== `.env` -The [DotEnvConfigSourceProvider](https://github.com/smallrye/smallrye-config/blob/main/implementation/src/main/java/io/smallrye/config/DotEnvConfigSourceProvider.java) create a `ConfigSource` from a `.env` file. +The https://github.com/smallrye/smallrye-config/blob/main/implementation/src/main/java/io/smallrye/config/DotEnvConfigSourceProvider.java[DotEnvConfigSourceProvider] create a `ConfigSource` from a `.env` file. diff --git a/documentation/src/main/docs/config-sources/factories.md b/documentation/src/main/asciidoc/config-sources/factories.adoc similarity index 76% rename from documentation/src/main/docs/config-sources/factories.md rename to documentation/src/main/asciidoc/config-sources/factories.adoc index 973a3c4d2..a3c26281c 100644 --- a/documentation/src/main/docs/config-sources/factories.md +++ b/documentation/src/main/asciidoc/config-sources/factories.adoc @@ -1,34 +1,36 @@ -# Config Source Factory += Config Source Factory +:version-root: ../ +include::{version-root}_attributes.adoc[] -Another way to create a `ConfigSource` is via the `ConfigSourceFactory`. The difference between the SmallRye Config -Factory and the standard way to make a `ConfigSource` as specified in MicroProfile Config is the Factory's ability to -provide a context with access to the available configuration. With the `ConfigSourceFactory` it is possible to +Another way to create a `ConfigSource` is via the `ConfigSourceFactory`. The difference between the SmallRye Config +Factory and the standard way to make a `ConfigSource` as specified in MicroProfile Config is the Factory's ability to +provide a context with access to the available configuration. With the `ConfigSourceFactory` it is possible to bootstrap a `ConfigSource` that configures itself with previously initialized `ConfigSource's`. -By implementing -[ConfigSourceFactory](https://github.com/smallrye/smallrye-config/blob/main/implementation/src/main/java/io/smallrye/config/ConfigSourceFactory.java), -a list of `ConfigSource's` may be provided via the ` -Iterable getConfigSources(ConfigSourceContext context)` method. The `ConfigSourceFactory` may also -assign a priority by overriding the default method `OptionalInt getPriority()`. The priority only sorts the factories -during initialization. After initialization, the provided `ConfigSources` will use their own ordinal and sorted with +By implementing +https://github.com/smallrye/smallrye-config/blob/main/implementation/src/main/java/io/smallrye/config/ConfigSourceFactory.java[ConfigSourceFactory], +a list of `ConfigSource's` may be provided via the `Iterable++<++ConfigSource++>++ getConfigSources(ConfigSourceContext context)` method. The `ConfigSourceFactory` may also +assign a priority by overriding the default method `OptionalInt getPriority()`. The priority only sorts the factories +during initialization. After initialization, the provided `ConfigSources` will use their own ordinal and sorted with all `ConfigSources` available in the `Config` instance. -When the Factory initializes, the provided `ConfigSourceContext` may call the method -`ConfigValue getValue(String name)`. This method looks up configuration names in all `ConfigSource's` already -initialized by the `Config` instance, including sources with lower ordinals than the ones defined in the -`ConfigSourceFactory`. The `ConfigSourceFactory` does not consider `ConfigSources's` provided by other +When the Factory initializes, the provided `ConfigSourceContext` may call the method +`ConfigValue getValue(String name)`. This method looks up configuration names in all `ConfigSource's` already +initialized by the `Config` instance, including sources with lower ordinals than the ones defined in the +`ConfigSourceFactory`. The `ConfigSourceFactory` does not consider `ConfigSources's` provided by other `ConfigSourceFactory's` (the priority does not matter). Registration of a `ConfigSourceFactory` is done via the `ServiceLoader` mechanism by providing the implementation classes in a `META-INF/services/io.smallrye.config.ConfigSourceFactory` file. Alternatively, factories may be registered via the Programmatic API in `SmallRyeConfigBuilder#withSources`. -A `ConfigSourceFactory` requires an implementation of `io.smallrye.config.ConfigSourceFactory`. Each implementation -requires registration via the `ServiceLoader` mechanism in the -`META-INF/services/io.smallrye.config.ConfigSourceFactory` file. Alternatively, interceptors may be registered via the +A `ConfigSourceFactory` requires an implementation of `io.smallrye.config.ConfigSourceFactory`. Each implementation +requires registration via the `ServiceLoader` mechanism in the +`META-INF/services/io.smallrye.config.ConfigSourceFactory` file. Alternatively, interceptors may be registered via the Programmatic API in `SmallRyeConfigBuilder#withSources`. -```java +[source,java] +---- package org.acme.config import java.io.IOException; @@ -70,30 +72,34 @@ public class FileSystemConfigSourceFactory implements ConfigSourceFactory { } } } -``` +---- And registration in: -```properties title="META-INF/services/io.smallrye.config.ConfigSourceFactory" +.META-INF/services/io.smallrye.config.ConfigSourceFactory +[source,properties] +---- org.acme.config.FileSystemConfigSourceFactory -``` +---- The `FileSystemConfigSourceFactory` look ups the configuration value for `org.acme.config.file.locations`, and uses it to set up an additional `ConfigSource`. -## `ConfigurableConfigSourceFactory` +== `ConfigurableConfigSourceFactory` A `ConfigurableConfigSourceFactory` accepts a `@ConfigMapping` interface to configure the `ConfigSource`, removing the need to look up configuration values manually via `ConfigSourceContext`: -```java +[source,java] +---- @ConfigMapping(prefix = "org.acme.config.file") interface FileSystemConfig { List locations(); } -``` +---- -```java +[source,java] +---- public class FileSystemConfigurableConfigSourceFactory implements ConfigurableConfigSourceFactory { @Override public Iterable getConfigSources(ConfigSourceContext context, FileSystemConfig config) { @@ -108,16 +114,17 @@ public class FileSystemConfigurableConfigSourceFactory implements ConfigurableCo return sources; } } -``` +---- And registration in: -```properties title="META-INF/services/io.smallrye.config.ConfigSourceFactory" +.META-INF/services/io.smallrye.config.ConfigSourceFactory +[source,properties] +---- org.acme.config.FileSystemConfigurableConfigSourceFactory -``` +---- The `ConfigMapping` interface is automatically populated from all `ConfigSource`s already initialized at the time the factory runs. Values are resolved using the same two-step initialization as a regular `ConfigSourceFactory`: sources from `ConfigSource` / `ConfigSourceProvider` registrations are available, but sources from other `ConfigSourceFactory` implementations are not. - diff --git a/documentation/src/main/asciidoc/config-sources/filesystem.adoc b/documentation/src/main/asciidoc/config-sources/filesystem.adoc new file mode 100644 index 000000000..e34804cd5 --- /dev/null +++ b/documentation/src/main/asciidoc/config-sources/filesystem.adoc @@ -0,0 +1,51 @@ += FileSystem Config Source +:version-root: ../ +include::{version-root}_attributes.adoc[] + +This Config Source loads configuration values for each file found in a directory. Each file corresponds to a single +property, where the file name is the configuration property name and the file content the configuration value. + +For instance, if a directory structure looks like: + +.... +foo/ +|__num.max +|__num.size +.... + +The `FileSystem` Config Source will provide 2 properties: + +* num.max +* num.size + +[WARNING] +==== + +Nested directories are not supported. + +==== + +This Config Source can be used to read configuration from +https://kubernetes.io/docs/tasks/configure-pod-container/configure-pod-configmap[Kubernetes ConfigMap]. Check the +https://github.com/smallrye/smallrye-config/blob/main/examples/configmap/README.adoc[Kubernetes ConfigMap ConfigSource Example]. + +The same mapping rules as defined for environment variables are applied, so the `FileSystem` Config Source will search +for a given property name `num.max`: + +* Exact match (`num.max`) +* Replace each character that is neither alphanumeric nor ++_++ with ++_++ (`num++_++max`) +* Replace each character that is neither alphanumeric nor ++_++ with ++_++; then convert the name to upper case (`NUM++_++MAX`) + +The following dependency is required in the classpath to use the `FileSystem` Config Source: + +[source,xml,subs="attributes+"] +---- + + io.smallrye.config + smallrye-config-source-file-system + {project-version} + +---- + +The configuration property `smallrye.config.source.file.locations` sets the directory paths to look up the files. It +accepts multiple locations separated by a comma and each must represent a valid URI to a directory. diff --git a/documentation/src/main/asciidoc/config-sources/hocon.adoc b/documentation/src/main/asciidoc/config-sources/hocon.adoc new file mode 100644 index 000000000..dac54e13d --- /dev/null +++ b/documentation/src/main/asciidoc/config-sources/hocon.adoc @@ -0,0 +1,46 @@ += HOCON Config Source +:version-root: ../ +include::{version-root}_attributes.adoc[] + +This Config Source allows to use the https://github.com/lightbend/config/blob/main/HOCON.md[HOCON] file format to +load configuration values. The HOCON Config Source loads the +configuration from the file `META-INF/microprofile-config.conf`. It has a lower ordinal (`50`) than the +`microprofile-config.properties`. + +The following dependency is required in the classpath to use the HOCON Config Source: + +[source,xml,subs="attributes+"] +---- + + io.smallrye.config + smallrye-config-source-hocon + {project-version} + +---- + +Expressions defined as `$++{++value}` (unquoted) are resolved internally by the HOCON Config Source as described in the +https://github.com/lightbend/config/blob/main/HOCON.md#substitutions[HOCON Substitutions] documentation. Quoted +Expressions defined as `"$++{++value}"` are resolved by xref:config/expressions.adoc[SmallRye Config Property Expressions]. + +Consider: + +*hocon.conf* + +[source,conf] +---- +{ + foo: "bar", + hocon: ${foo}, + config: "${foo}" +} +---- + +*application.properties* + +[source,properties] +---- +config_ordinal=1000 +foo=baz +---- + +The value of `hocon` is `bar` and the value of `config` is `baz` (if the properties source has a higher ordinal). diff --git a/documentation/src/main/asciidoc/config-sources/json.adoc b/documentation/src/main/asciidoc/config-sources/json.adoc new file mode 100644 index 000000000..54fe1a808 --- /dev/null +++ b/documentation/src/main/asciidoc/config-sources/json.adoc @@ -0,0 +1,6 @@ += JSON Config Source +:version-root: ../ +include::{version-root}_attributes.adoc[] + +The xref:config-sources/yaml.adoc[YAML Config Source] also accepts the JSON format as its contents. The configuration file +`META-INF/microprofile-config.yaml`, still requires to use the `yaml` extension. diff --git a/documentation/src/main/asciidoc/config-sources/keystore.adoc b/documentation/src/main/asciidoc/config-sources/keystore.adoc new file mode 100644 index 000000000..c197905c7 --- /dev/null +++ b/documentation/src/main/asciidoc/config-sources/keystore.adoc @@ -0,0 +1,67 @@ += KeyStore Config Source +:version-root: ../ +include::{version-root}_attributes.adoc[] + +This Config Source allows to use a Java `KeyStore` to load configuration values. It uses an ordinal of `100`. + +The following dependency is required in the classpath to use the KeyStore Config Source: + +[source,xml,subs="attributes+"] +---- + + io.smallrye.config + smallrye-config-source-keystore + {project-version} + +---- + +== Create a KeyStore + +The following command creates a simple KeyStore + +[source,bash] +---- +keytool -importpass -alias my.secret -keystore keystore -storepass secret -storetype PKCS12 -v +---- + +The `-alias my.secret` stores the configuration property name `my.secret` in the KeyStore. The command will +interactively ask for the value to be stored in the KeyStore. + +== Read the KeyStore + +The KeyStore Config Source supports reading multiple keystore files: + +[source,properties] +---- +smallrye.config.source.keystore.one.path=keystore-one +smallrye.config.source.keystore.one.password=password + +smallrye.config.source.keystore.two.path=keystore-two +smallrye.config.source.keystore.two.password=password +---- + +The names are arbitrary and can be any name. The name `one` and `two` are used to distinguish both KeyStores. + +If a stored configuration property requires a xref:config/secret-keys.adoc[Secret Handler] to decode a value, set +the handler name with `smallrye.config.source.keystore."name".handler`. + +== Configuration + +[width="100%",cols="95%,2%,3%",options="header",] +|=== +|Configuration Property |Type |Default +|`smallrye.config.source.keystore."name".path` + +The KeyStore path. |String | +|`smallrye.config.source.keystore."name".password` + +The KeyStore password. |String | +|`smallrye.config.source.keystore."name".type` + +The KeyStore type. |String |`PKCS12` +|`smallrye.config.source.keystore."name".handler` + +An Optional secret keys handler. |String | +|`smallrye.config.source.keystore."name".aliases."key".name` + +An Optional aliases key name. |String | +|`smallrye.config.source.keystore."name".aliases."key".password` + +An Optional aliases key password. |String | +|`smallrye.config.source.keystore."name".aliases."key".handler` + +An Optional aliases key secret keys handler. |String | +|=== diff --git a/documentation/src/main/docs/config-sources/locations.md b/documentation/src/main/asciidoc/config-sources/locations.adoc similarity index 64% rename from documentation/src/main/docs/config-sources/locations.md rename to documentation/src/main/asciidoc/config-sources/locations.adoc index 684ee7323..84bdc6c76 100644 --- a/documentation/src/main/docs/config-sources/locations.md +++ b/documentation/src/main/asciidoc/config-sources/locations.adoc @@ -1,70 +1,82 @@ -# Locations += Locations +:version-root: ../ +include::{version-root}_attributes.adoc[] -Additionally, to the default config locations specified by the -[MicroProfile Config](https://github.com/eclipse/microprofile-config/) specification, SmallRye Config provides a way to +Additionally, to the default config locations specified by the +https://github.com/eclipse/microprofile-config/[MicroProfile Config] specification, SmallRye Config provides a way to scan additional locations for configuration properties files. -The `smallrye.config.locations` configuration property accepts multiple locations separated by a comma `,` and each +The `smallrye.config.locations` configuration property accepts multiple locations separated by a comma `,` and each ust represent a valid `URI`. The supported `URI` schemes are: -- file or directory (`file:`) -- classpath resource -- jar resource (`jar:`) -- http resource (`http:`) +* file or directory (`file:`) +* classpath resource +* jar resource (`jar:`) +* http resource (`http:`) -Each `URI` scheme loads all discovered resources in a `ConfigSource`. All loaded sources use the same ordinal of the -source that found the `smallrye.config.locations` configuration property. For instance, if `smallrye.config.locations` +Each `URI` scheme loads all discovered resources in a `ConfigSource`. All loaded sources use the same ordinal of the +source that found the `smallrye.config.locations` configuration property. For instance, if `smallrye.config.locations` is set as a system property, then all loaded sources have their ordinals set to `400` (system properties use `400` as -their ordinal). The ordinal may be overridden directly in the resource by setting the `config_ordinal` property. +their ordinal). The ordinal may be overridden directly in the resource by setting the `config++_++ordinal` property. Sources are sorted first by their ordinal, then by location order, and finally by loading order. -If a profile is active, and the `URI` represents a single resource (for instance a file), then resources that match -the active profile are also loaded. The profile resource name must follow the pattern: `{location}-{profile}`. A -profile resource is only loaded if the unprofiled resource is also available in the same location. This is to keep a +If a profile is active, and the `URI` represents a single resource (for instance a file), then resources that match +the active profile are also loaded. The profile resource name must follow the pattern: `++{++location}-++{++profile}`. A +profile resource is only loaded if the unprofiled resource is also available in the same location. This is to keep a consistent loading order and pair all the resources together. -Profile resources are not taken into account if the location is a directory since there is no reliable way to discover +Profile resources are not taken into account if the location is a directory since there is no reliable way to discover which file is the main resource. Properties that use the profile prefix syntax `%profile.` will work as expected. _All properties files from a directory_ -```properties +[source,properties] +---- # loads all files from a relative path smallrye.config.locations=./src/main/resources/ # loads all files from an absolute path smallrye.config.locations=/user/local/config -``` +---- For relative paths, the JVM `user.dir` property defines the current directory. _A specific file_ -```properties title="./src/main/resources/additional.properties" +../src/main/resources/additional.properties + +[source,properties] +---- smallrye.config.locations=./src/main/resources/additional.properties -``` +---- If a profile `dev` is active, and an `additional-dev.properties` file exists, this will also be loaded. _All `additional.properties` files from the classpath_ -```properties title="additional.properties" +.additional.properties +[source,properties] +---- smallrye.config.locations=additional.properties -``` +---- -If a profile `prod` is active, and an `additional-prod.properties` resources exists next to the `additional.properties` +If a profile `prod` is active, and an `additional-prod.properties` resources exists next to the `additional.properties` resource, this will also be loaded. _The `resources.properties` file from a specific jar_ -```properties title="jar:file:///user/local/app/lib/resources-.jar!/resources.properties" +.jar:file:///user/local/app/lib/resources-.jar!/resources.properties +[source,properties] +---- smallrye.config.locations=jar:file:///user/local/app/lib/resources-.jar!/resources.properties -``` +---- If a profile `test` is active, and an `additional-test.properties` resource exists, this will also be loaded. _The `config.properties` file from a web server_ -```properties title="http://localhost:8080/config/config.properties" +.http://localhost:8080/config/config.properties +[source,properties] +---- smallrye.config.locations=http://localhost:8080/config/config.properties -``` +---- diff --git a/documentation/src/main/asciidoc/config-sources/toml.adoc b/documentation/src/main/asciidoc/config-sources/toml.adoc new file mode 100644 index 000000000..1d6de423b --- /dev/null +++ b/documentation/src/main/asciidoc/config-sources/toml.adoc @@ -0,0 +1,22 @@ += TOML Config Source +:version-root: ../ +include::{version-root}_attributes.adoc[] + +This Config Source allows to use a https://toml.io[TOML] file to load configuration values. The TOML Config Source +loads the configuration from the following files: + +[arabic] +. (`265`) `application.toml` in `config` folder, located in the current working directory +. (`255`) `application.toml` in the classpath +. (`110`) MicroProfile Config configuration file `META-INF/microprofile-config.toml` in the classpath + +The following dependency is required in the classpath to use the TOML Config Source: + +[source,xml,subs="attributes+"] +---- + + io.smallrye.config + smallrye-config-source-toml + {project-version} + +---- diff --git a/documentation/src/main/asciidoc/config-sources/yaml.adoc b/documentation/src/main/asciidoc/config-sources/yaml.adoc new file mode 100644 index 000000000..faa4cb1fe --- /dev/null +++ b/documentation/src/main/asciidoc/config-sources/yaml.adoc @@ -0,0 +1,21 @@ += YAML Config Source +:version-root: ../ +include::{version-root}_attributes.adoc[] + +This Config Source allows to use a `yaml` file to load configuration values. The YAML Config Source loads the configuration from the following files: + +[arabic] +. (`265`) `application.yaml++|++yml` in `config` folder, located in the current working directory +. (`255`) `application.yaml++|++yml` in the classpath +. (`110`) MicroProfile Config configuration file `META-INF/microprofile-config.yaml++|++yml` in the classpath + +The following dependency is required in the classpath to use the YAML Config Source: + +[source,xml,subs="attributes+"] +---- + + io.smallrye.config + smallrye-config-source-yaml + {project-version} + +---- diff --git a/documentation/src/main/docs/config-sources/zookeeper.md b/documentation/src/main/asciidoc/config-sources/zookeeper.adoc similarity index 64% rename from documentation/src/main/docs/config-sources/zookeeper.md rename to documentation/src/main/asciidoc/config-sources/zookeeper.adoc index 406c0aab7..4d555f0c8 100644 --- a/documentation/src/main/docs/config-sources/zookeeper.md +++ b/documentation/src/main/asciidoc/config-sources/zookeeper.adoc @@ -1,26 +1,30 @@ -# ZooKeeper Config Source += ZooKeeper Config Source +:version-root: ../ +include::{version-root}_attributes.adoc[] -This Config Source allows using [Apache ZooKeeper](https://zookeeper.apache.org/index.html) to load configuration +This Config Source allows using https://zookeeper.apache.org/index.html[Apache ZooKeeper] to load configuration values. The following dependency is required in the classpath to use the ZooKeeper Config Source: -```xml +[source,xml,subs="attributes+"] +---- io.smallrye.config smallrye-config-source-zookeeper - {{attributes['version']}} + {project-version} -``` +---- It also requires to set up additional configuration properties to identify the ZooKeeper instance: -```properties +[source,properties] +---- io.smallrye.configsource.zookeeper.url=localhost:2181 io.smallrye.configsource.zookeeper.applicationId=applicationId -``` +---- -The ZooKeeper Config Source will look for configuration values in a ZooKeeper instance running in the url set in +The ZooKeeper Config Source will look for configuration values in a ZooKeeper instance running in the url set in `io.smallrye.configsource.zookeeper.url` and in the znodes available in `/applicationId/`. This Config Source has an ordinal of `150`. diff --git a/documentation/src/main/docs/config/config-value.md b/documentation/src/main/asciidoc/config/config-value.adoc similarity index 50% rename from documentation/src/main/docs/config/config-value.md rename to documentation/src/main/asciidoc/config/config-value.adoc index e402d49ee..63d58d715 100644 --- a/documentation/src/main/docs/config/config-value.md +++ b/documentation/src/main/asciidoc/config/config-value.adoc @@ -1,7 +1,8 @@ -# Config Value += Config Value +:version-root: ../ +include::{version-root}_attributes.adoc[] -The `io.smallrye.config.ConfigValue` is a metadata object that holds additional information after the lookup of a -configuration property. It is able to hold information of configuration property name, value, profile, the -`ConfigSource` from where the configuration was loaded, the ordinal of the `ConfigSource` and a line number from where +The `io.smallrye.config.ConfigValue` is a metadata object that holds additional information after the lookup of a +configuration property. It is able to hold information of configuration property name, value, profile, the +`ConfigSource` from where the configuration was loaded, the ordinal of the `ConfigSource` and a line number from where the configuration was loaded if exists. - diff --git a/documentation/src/main/asciidoc/config/configuration.adoc b/documentation/src/main/asciidoc/config/configuration.adoc new file mode 100644 index 000000000..cb7a1b582 --- /dev/null +++ b/documentation/src/main/asciidoc/config/configuration.adoc @@ -0,0 +1,20 @@ += Configuration Reference +:version-root: ../ +include::{version-root}_attributes.adoc[] + +[width="100%",cols="92%,4%,4%",options="header",] +|=== +|Configuration Property |Type |Default +|`smallrye.config.profile` + +The main xref:config/profiles.adoc[Profile] to activate. |String++[]++ | +|`smallrye.config.profile.parent` + +The parent xref:config/profiles.adoc#parent-profile[Profile] to activate. |String | +|`smallrye.config.locations` + +xref:config-sources/locations.adoc[Additional config locations] to be loaded with the Config. The configuration supports multiple locations separated by a comma and each must represent a valid `java.net.URI`. |URI++[]++ | +|`smallrye.config.mapping.validate-unknown` + +xref:config/mappings.adoc#retrieval[Validates] that a `@ConfigMapping` maps every available configuration name contained in the mapping prefix. |boolean |true +|`smallrye.config.secret-handlers` + +The names of the secret handlers to be loaded. A value of `all` loads all available secret handlers and a value of `none` skips the load. |String++[]++ |all +|`smallrye.config.log.values` + +Enable logging of configuration values lookup in DEBUG log level. |boolean |false +|=== diff --git a/documentation/src/main/docs/config/customizer.md b/documentation/src/main/asciidoc/config/customizer.adoc similarity index 73% rename from documentation/src/main/docs/config/customizer.md rename to documentation/src/main/asciidoc/config/customizer.adoc index 55fa78b36..e841a645b 100644 --- a/documentation/src/main/docs/config/customizer.md +++ b/documentation/src/main/asciidoc/config/customizer.adoc @@ -1,18 +1,22 @@ -# Customizer += Customizer +:version-root: ../ +include::{version-root}_attributes.adoc[] -A `SmallRyeConfigBuilderCustomizer` allows to customize a `SmallRyeConfigBuilder`, used to create the `SmallRyeConfig` +A `SmallRyeConfigBuilderCustomizer` allows to customize a `SmallRyeConfigBuilder`, used to create the `SmallRyeConfig` instance. Registration of a `SmallRyeConfigBuilderCustomizer` is done via the `ServiceLoader` mechanism by providing the -implementation classes in a `META-INF/services/io.smallrye.config.SmallRyeConfigBuilderCustomizer` file. Alternatively, +implementation classes in a `META-INF/services/io.smallrye.config.SmallRyeConfigBuilderCustomizer` file. Alternatively, customizers may be registered via the Programmatic API in `SmallRyeConfigBuilder#withCustomizers`. The `SmallRyeConfigBuilderCustomizer` may also -assign a priority by overriding the default method `int priority()`. Customizers are sorted by ascending priority and -executed in that order, meaning that higher numeric priorities will execute last, possible overriding values set by +assign a priority by overriding the default method `int priority()`. Customizers are sorted by ascending priority and +executed in that order, meaning that higher numeric priorities will execute last, possible overriding values set by previous customizers. -```java title="CustomConfigBuilder" +.CustomConfigBuilder +[source,java] +---- package org.acme.config; import io.smallrye.config.SmallRyeConfigBuilder; @@ -24,20 +28,22 @@ public class CustomConfigBuilder implements SmallRyeConfigBuilderCustomizer { builder.withDefaultValue("my.default", "1234"); } } -``` +---- And registration in: -```properties title="META-INF/services/io.smallrye.config.SmallRyeConfigBuilderCustomizer" +.META-INF/services/io.smallrye.config.SmallRyeConfigBuilderCustomizer +[source,properties] +---- org.acme.config.CustomConfigBuilder -``` +---- The `CustomConfigBuilder` will be executed when creating a new `SmallRyeConfig` from a `SmallRyeConfigBuilder`: -```java +[source,java] +---- SmallRyeConfig config = new SmallRyeConfigBuilder().build(); config.getValue("my.default", int.class); -``` +---- A look up to `my.default` returns the value `1234`, registered by the `CustomConfigBuilder`. - diff --git a/documentation/src/main/asciidoc/config/environment-variables.adoc b/documentation/src/main/asciidoc/config/environment-variables.adoc new file mode 100644 index 000000000..15579d8e6 --- /dev/null +++ b/documentation/src/main/asciidoc/config/environment-variables.adoc @@ -0,0 +1,80 @@ += Environment Variables +:version-root: ../ +include::{version-root}_attributes.adoc[] + +Environment Variable names follow the conversion rules specified by https://github.com/eclipse/microprofile-config/blob/master/spec/src/main/asciidoc/configsources.asciidoc#default-configsources[MicroProfile Config]. + +SmallRye Config specifies additional conversion rules: + +* A property with double quotes `foo."bar".baz` or `foo.bar."baz"`, replace each character that is neither alphanumeric +nor `++_++` with `++_++`: `FOO++__++BAR++__++BAZ` or `FOO++_++BAR++__++BAZ++_++` ; +* A property with dashes `foo.bar-baz`, replace each character that is neither alphanumeric nor `++_++` +with `++_++`: `FOO++_++BAR++_++BAZ` +* An indexed property `foo.bar++[++0++]++` or `foo.bar++[++0++]++.baz`, replace each character that is neither alphanumeric nor `++_++` +with `++_++`: `FOO++_++BAR++_++0++_++` or `FOO++_++BAR++_++0++__++BAZ`. + +[CAUTION] +==== + +Environment Variables format cannot represent the entire spectrum of common property names. + +==== + +The lookup of configuration values from Environment Variables will always use the dotted format name. For +instance, the lookup of the Environment Variable `FOO++_++BAR` value, requires the property name `foo.bar`: + +[source,java] +---- +Config config = Config.getOrCreate(); +String value = config.getValue("foo.bar", String.class); +---- + +When SmallRyeConfig performs the lookup on the Environment Variables Config Source, it applies the conversion rules to +find the matching property name and retrieve the value. + +In some situations, looking up the exact property name is impossible. For instance, when SmallRye Config has to look up +a configuration that is part of a `Map`, and the property name contains a dynamic segment (a `Map` key). In this case, +SmallRye Config relies upon each source's list of property names. These must be converted back to their most likely +dotted format for Environment Variables. + +By default, the underscore `++_++` of an Environment Variable name always maps to a dot `.`. If the property name +contains a dash or some other special character, that property name can be specified in another Config +Source, with the expected dotted format. It will provide additional information to SmallRye Config to perform a +two-way conversion and match the property names. + +Consider: + +..env + +[source,console] +---- +FOO_BAR_BAZ=VALUE +---- + +Will map to `foo.bar.baz` and value `value`. + +If `foo.bar-baz` is available in any source: + +..env + +[source,console] +---- +FOO_BAR_BAZ=VALUE +---- + +.application.properties +[source,properties] +---- +foo.bar-baz=default +---- + +Will map to `foo.bar-baz` and value `value`. + +[NOTE] +==== + +The property name in dotted format needs to exist somewhere to provide this additional information. It can be set in a +low ordinal source, even without value. The Environment Variables source will override the value and map the correct +configuration name. + +==== diff --git a/documentation/src/main/docs/config/expressions.md b/documentation/src/main/asciidoc/config/expressions.adoc similarity index 67% rename from documentation/src/main/docs/config/expressions.md rename to documentation/src/main/asciidoc/config/expressions.adoc index 04e9b7add..f76d0df5c 100644 --- a/documentation/src/main/docs/config/expressions.md +++ b/documentation/src/main/asciidoc/config/expressions.adoc @@ -1,67 +1,75 @@ -# Property Expressions += Property Expressions +:version-root: ../ +include::{version-root}_attributes.adoc[] SmallRye Config provides property expressions expansion on configuration values. An expression string is a mix of plain -strings and expression segments, which are wrapped by the sequence ${ ... }. +strings and expression segments, which are wrapped by the sequence $++{++ ... }. For instance, the following configuration properties file: -```properties +[source,properties] +---- remote.host=smallrye.io callable.url=https://${remote.host}/ -``` +---- The resolved value of the `callable.url` property is `https://smallrye.io/`. Additionally, the Expression Expansion engine supports the following segments: -- `${expression:value}` - Provides a default value after the `:` if the expansion doesn’t find a value. -- `${my.prop${compose}}` - Composed expressions. Inner expressions are resolved first. -- `${my.prop}${my.prop}` - Multiple expressions. +* `$++{++expression:value}` - Provides a default value after the `:` if the expansion doesn’t find a value. +* `$++{++my.prop$++{++compose}}` - Composed expressions. Inner expressions are resolved first. +* `$++{++my.prop}$++{++my.prop}` - Multiple expressions. If an expression cannot be expanded and no default is supplied a `NoSuchElementException` is thrown. -## Escaping +== Escaping A `$` that begins an expression segment can be escaped with a backslash to treat it as a literal character: -```properties +[source,properties] +---- # value is: ${my.prop} expression=\${my.prop} -``` +---- A backslash that immediately precedes a `$` can itself be escaped with another backslash: -```properties +[source,properties] +---- # my.prop=value # value is: \value expression=\\${my.prop} -``` +---- -Escaping only applies to values that contain an expression segment. In a value that has no `${ ... }` segment, +Escaping only applies to values that contain an expression segment. In a value that has no `$++{++ ... }` segment, every backslash is treated as a literal character and nothing needs escaping (for example, a Windows path such as -`C:\some\path` is used as-is). +`C:++\++some++\++path` is used as-is). As soon as a value contains an expression segment, the whole value is processed for escapes and backslash becomes an -escape character everywhere in it, not just before a `$`. Standard escape sequences are interpreted (`\n`, `\r`, `\t`, -`\b`, `\f`) and a backslash before any other character is dropped. To keep a literal backslash in such a value, double +escape character everywhere in it, not just before a `$`. Standard escape sequences are interpreted (`++\++n`, `++\++r`, `++\++t`, +`++\++b`, `++\++f`) and a backslash before any other character is dropped. To keep a literal backslash in such a value, double it: -```properties +[source,properties] +---- # value is: C:\some\path\value (my.prop=value) expression=C:\\some\\path\\${my.prop} -``` +---- -## Disabling Expansion +== Disabling Expansion Expression expansion may be selectively disabled for a block of code using `io.smallrye.config.Expressions.withoutExpansion()`. The raw (unexpanded) value is returned for any property looked up within the block: -```properties +[source,properties] +---- callable.url=https://${remote.host}/ -``` +---- -```java +[source,java] +---- Config config = Config.getOrCreate(); // returns "https://${remote.host}/" String url = Expressions.withoutExpansion(() -> config.getValue("callable.url", String.class)); -``` +---- diff --git a/documentation/src/main/docs/config/getting-started.md b/documentation/src/main/asciidoc/config/getting-started.adoc similarity index 59% rename from documentation/src/main/docs/config/getting-started.md rename to documentation/src/main/asciidoc/config/getting-started.adoc index 24bfc40f6..d2eb46c6d 100644 --- a/documentation/src/main/docs/config/getting-started.md +++ b/documentation/src/main/asciidoc/config/getting-started.adoc @@ -1,91 +1,99 @@ -# Getting Started += Getting Started +:version-root: ../ +include::{version-root}_attributes.adoc[] -## Config Sources +== Config Sources By default, SmallRye Config reads configuration properties from multiple configuration sources (by descending ordinal): -1. (`400`) System properties -2. (`300`) Environment variables -3. (`295`) `.env` file in the current working directory -4. (`260`) `application.properties` in `config` folder, located in the current working directory -5. (`250`) `application.properties` in the classpath -6. (`100`) MicroProfile Config configuration file `META-INF/microprofile-config.properties` in the classpath +[arabic] +. (`400`) System properties +. (`300`) Environment variables +. (`295`) `.env` file in the current working directory +. (`260`) `application.properties` in `config` folder, located in the current working directory +. (`250`) `application.properties` in the classpath +. (`100`) MicroProfile Config configuration file `META-INF/microprofile-config.properties` in the classpath A configuration source is handled by a `ConfigSource`. A `ConfigSource` provides configuration values from a specific -place. +place. -The final configuration is the aggregation of the properties defined by all these sources. A configuration property -lookup starts by the highest ordinal configuration source available and works it way down to other sources until a -match is found. This means that any configuration property may override a value just by setting a different value in a -higher ordinal config source. For example, a property configured using an Environment Variable overrides the value +The final configuration is the aggregation of the properties defined by all these sources. A configuration property +lookup starts by the highest ordinal configuration source available and works it way down to other sources until a +match is found. This means that any configuration property may override a value just by setting a different value in a +higher ordinal config source. For example, a property configured using an Environment Variable overrides the value provided using the `microprofile-config.properties` file. -### System Properties +=== System Properties -System properties can be handed to the application through the `-D` flag during startup. For instance, +System properties can be handed to the application through the `-D` flag during startup. For instance, `java -Dmy.prop -jar my.jar`. -### Environment Variables +=== Environment Variables -Environment variables are set directly in the host operating system. Environment variables names follow the conversion -rules detailed by [Environment Variables](environment-variables.md). - -### MicroProfile Config configuration file +Environment variables are set directly in the host operating system. Environment variables names follow the conversion +rules detailed by xref:config/environment-variables.adoc[Environment Variables]. -The MicroProfile Config configuration file `META-INF/microprofile-config.properties` in the classpath. It follows the +=== MicroProfile Config configuration file + +The MicroProfile Config configuration file `META-INF/microprofile-config.properties` in the classpath. It follows the standard convention for `properties` files. -```properties title="META-INF/microprofile-config.properties" +.META-INF/microprofile-config.properties +[source,properties] +---- greeting.message=hello goodbye.message=bye -``` +---- -### Additional Config Sources +=== Additional Config Sources SmallRye Config provides additional extensions which cover other configuration formats and stores: -- [YAML](../config-sources/yaml.md) -- [File System](../config-sources/filesystem.md) -- [ZooKeeper](../config-sources/zookeeper.md) -- [HOCON](../config-sources/hocon.md) +* xref:config-sources/yaml.adoc[YAML] +* xref:config-sources/filesystem.adoc[File System] +* xref:config-sources/zookeeper.adoc[ZooKeeper] +* xref:config-sources/hocon.adoc[HOCON] -It is also possible to create a [Custom ConfigSource](../config-sources/custom.md). +It is also possible to create a xref:config-sources/custom.adoc[Custom ConfigSource]. -## Retrieving the Configuration +== Retrieving the Configuration -### Programmatically +=== Programmatically -The `io.smallrye.config.Config#getOrCreate()` API allows to access the `io.smallrye.config.Config` API +The `io.smallrye.config.Config#getOrCreate()` API allows to access the `io.smallrye.config.Config` API programmatically: -```java +[source,java] +---- import io.smallrye.config.Config; Config config = Config.getOrCreate(); String message = config.getValue("greeting.message", String.class); -``` +---- -The `Config` instance will be created and registered to the current context class loader if no such configuration is -already created and registered. This means that subsequent calls to `Config.getOrCreate()` or +The `Config` instance will be created and registered to the current context class loader if no such configuration is +already created and registered. This means that subsequent calls to `Config.getOrCreate()` or `Config.get()` will return the same `Config` instance if the context class loader is the same. To obtain a detached instanced, use the `io.smallrye.config.SmallRyeConfigBuilder`: -```java +[source,java] +---- SmallRyeConfig config = new SmallRyeConfigBuilder() .addDefaultInterceptors() .addDefaultSources() .build(); String message = config.getValue("greeting.message", String.class); -``` +---- -### With CDI +=== With CDI -In a CDI environment, configuration can be injected in CDI aware beans with `@Inject` and +In a CDI environment, configuration can be injected in CDI aware beans with `@Inject` and the `org.eclipse.microprofile.config.inject.ConfigProperty` qualifier. -```java +[source,java] +---- @Inject @ConfigProperty(name = "greeting.message") String message; @@ -100,58 +108,60 @@ Optional name; @Inject SmallRyeConfig config; -``` +---- -- If a value if not provided for this `greeting.message`, the application startup fails with a -`jakarta.enterprise.inject.spi.DeploymentException: No config value of type [class java.lang.String] exists for: greeting.message`. -- The default value `!` is injected if the configuration does not provide a value for `greeting.suffix`. -- The property `greeting.name` is optional - an empty Optional is injected if the configuration does not provide a +* If a value if not provided for this `greeting.message`, the application startup fails with a +`jakarta.enterprise.inject.spi.DeploymentException: No config value of type ++[++class java.lang.String++]++ exists for: greeting.message`. +* The default value `!` is injected if the configuration does not provide a value for `greeting.suffix`. +* The property `greeting.name` is optional - an empty Optional is injected if the configuration does not provide a value for it. -## Override Config +== Override Config -It is possible to override `Config` default initialization `Config.getOrCreate()`, by extending -`io.smallrye.config.SmallRyeConfigFactory` and registering the implementation with the `ServiceLoader` mechanism. +It is possible to override `Config` default initialization `Config.getOrCreate()`, by extending +`io.smallrye.config.SmallRyeConfigFactory` and registering the implementation with the `ServiceLoader` mechanism. -## Config vs SmallRyeConfig +== Config vs SmallRyeConfig -The `io.smallrye.config.Config` is an extension of `org.eclipse.microprofile.config.Config` and provides -additional APIs and helper methods not available in `org.eclipse.microprofile.config.Config`. To obtain an instance of +The `io.smallrye.config.Config` is an extension of `org.eclipse.microprofile.config.Config` and provides +additional APIs and helper methods not available in `org.eclipse.microprofile.config.Config`. To obtain an instance of `io.smallrye.config.Config`, the original `org.eclipse.microprofile.config.Config` can be unwrapped: -```java +[source,java] +---- import io.smallrye.config.SmallRyeConfig; import org.eclipse.microprofile.config.Config; import org.eclipse.microprofile.config.ConfigProvider; Config config = ConfigProvider.getConfig(); SmallRyeConfig smallRyeConfig = config.unwrap(SmallRyeConfig.class); -``` +---- Or obtained directly: -```java +[source,java] +---- Config config = Config.getOrCreate(); -``` +---- A few notable APIs provided by `io.smallrye.config.Config` allow to: -- Retrieve multiple values into a specified `Collection` -- Retrieve [Indexed Values](indexed-properties.md) -- Retrieve [Config Mappings](mappings.md) instances -- Retrieve the raw value of a configuration -- Check if a property is present -- Retrieve a `Converter` -- Convert values +* Retrieve multiple values into a specified `Collection` +* Retrieve xref:config/indexed-properties.adoc[Indexed Values] +* Retrieve xref:config/mappings.adoc[Config Mappings] instances +* Retrieve the raw value of a configuration +* Check if a property is present +* Retrieve a `Converter` +* Convert values -## Converters +== Converters -The `ConfigSource` retrieves a configuration value as a `String`. Other data types require a conversion using the +The `ConfigSource` retrieves a configuration value as a `String`. Other data types require a conversion using the `org.eclipse.microprofile.config.spi.Converter` API. Most of the common `Converter` types are provided by default: -* `boolean` and `java.lang.Boolean`; the values "true", "1", "YES", "Y" "ON" represent `true`. Any other value will be +* `boolean` and `java.lang.Boolean`; the values "true", "1", "YES", "Y" "ON" represent `true`. Any other value will be interpreted as `false` * `byte` and `java.lang.Byte` * `short` and `java.lang.Short` @@ -167,6 +177,6 @@ interpreted as `false` * `java.util.regex.Pattern` * `java.nio.file.Path` * Any class with declared static methods `of`, `valueOf` or `parse` that take a `String` or a `CharSequence` -* Any class with declared constructors that takes a `String` or a `CharSequence` +* Any class with declared constructors that takes a `String` or a `CharSequence` All default converters have a priority of `1`. diff --git a/documentation/src/main/docs/config/indexed-properties.md b/documentation/src/main/asciidoc/config/indexed-properties.adoc similarity index 62% rename from documentation/src/main/docs/config/indexed-properties.md rename to documentation/src/main/asciidoc/config/indexed-properties.adoc index 70c20a995..78b32cc10 100644 --- a/documentation/src/main/docs/config/indexed-properties.md +++ b/documentation/src/main/asciidoc/config/indexed-properties.adoc @@ -1,12 +1,15 @@ -# Indexed Properties += Indexed Properties +:version-root: ../ +include::{version-root}_attributes.adoc[] -In [MicroProfile Config](https://github.com/eclipse/microprofile-config/), a config value with unescaped commas may be +In https://github.com/eclipse/microprofile-config/[MicroProfile Config], a config value with unescaped commas may be converted to `Collection`. It works for simple cases, but it becomes cumbersome and limited for more advanced use cases. -Indexed Properties provide a way to use indexes in config property names to map specific elements in a `Collection` +Indexed Properties provide a way to use indexes in config property names to map specific elements in a `Collection` type. Since the indexed element is part of the property name, it can also map complex object types. Consider: -```properties +[source,properties] +---- # MicroProfile Config - Collection Values my.collection=dog,cat,turtle @@ -14,16 +17,16 @@ my.collection=dog,cat,turtle my.indexed.collection[0]=dog my.indexed.collection[1]=cat my.indexed.collection[2]=turtle -``` +---- The indexed property syntax uses the property name and square brackets with an index in between. -A call to `Config#getValues("my.collection", String.class)`, will automatically create and convert a `List` -that contains the values `dog`, `cat` and `turtle`. A call to `Config#getValues("my.indexed.collection", String.class)` -returns the exact same result. The indexed property format is prioritized when both styles are found in the same -configuration source. When available in multiple sources, the higher ordinal source wins, like any other configuration +A call to `Config#getValues("my.collection", String.class)`, will automatically create and convert a `List++<++String++>++` +that contains the values `dog`, `cat` and `turtle`. A call to `Config#getValues("my.indexed.collection", String.class)` +returns the exact same result. The indexed property format is prioritized when both styles are found in the same +configuration source. When available in multiple sources, the higher ordinal source wins, like any other configuration lookup. -The indexed property is sorted by its index before being added to the target `Collection`. Any gaps in the indexes do -not resolve to the target `Collection`, which means that the `Collection` result will store all values without empty +The indexed property is sorted by its index before being added to the target `Collection`. Any gaps in the indexes do +not resolve to the target `Collection`, which means that the `Collection` result will store all values without empty elements. diff --git a/documentation/src/main/docs/config/instance-builder.md b/documentation/src/main/asciidoc/config/instance-builder.adoc similarity index 78% rename from documentation/src/main/docs/config/instance-builder.md rename to documentation/src/main/asciidoc/config/instance-builder.adoc index 751174037..1bd05231f 100644 --- a/documentation/src/main/docs/config/instance-builder.md +++ b/documentation/src/main/asciidoc/config/instance-builder.adoc @@ -1,14 +1,17 @@ -# Instance Builder += Instance Builder +:version-root: ../ +include::{version-root}_attributes.adoc[] -With the `io.smallrye.config.ConfigInstanceBuilder` API, it is possible to create instances of a configuration interface -programmatically, without requiring a `SmallRyeConfig` or any configuration source. This is useful for testing, default +With the `io.smallrye.config.ConfigInstanceBuilder` API, it is possible to create instances of a configuration interface +programmatically, without requiring a `SmallRyeConfig` or any configuration source. This is useful for testing, default configurations, or any scenario where configuration values are known at build time. -## Usage +== Usage A configuration interface instance is created with `ConfigInstanceBuilder.forInterface()`: -```java +[source,java] +---- interface Server { String host(); @@ -19,23 +22,27 @@ Server server = ConfigInstanceBuilder.forInterface(Server.class) .with(Server::host, "localhost") .with(Server::port, 8080) .build(); -``` +---- -The builder uses method references to identify which property to set, providing compile-time type safety without -string-based property names. The `with` method accepts a method reference to the configuration interface member and the +The builder uses method references to identify which property to set, providing compile-time type safety without +string-based property names. The `with` method accepts a method reference to the configuration interface member and the value to set. -!!! info +[NOTE] +==== - The configuration interface does not require the `@ConfigMapping` annotation to work with the builder. Any valid - configuration interface is accepted. +The configuration interface does not require the `@ConfigMapping` annotation to work with the builder. Any valid +configuration interface is accepted. -## Primitive Types +==== -The builder provides dedicated `with()` overloads for `int`, `long`, `double`, and `boolean` primitive types. Other +== Primitive Types + +The builder provides dedicated `with()` overloads for `int`, `long`, `double`, and `boolean` primitive types. Other primitive types (`byte`, `short`, `float`, `char`) are set via the generic `with()` method using their boxed types: -```java +[source,java] +---- @ConfigMapping interface Primitives { int intValue(); @@ -50,13 +57,14 @@ Primitives primitives = ConfigInstanceBuilder.forInterface(Primitives.class) .with(Primitives::booleanValue, true) .with(Primitives::byteValue, Byte.valueOf((byte) 1)) .build(); -``` +---- -## Optional Properties +== Optional Properties The `withOptional()` method sets optional properties. If an optional property is not set, it defaults to empty: -```java +[source,java] +---- interface AppConfig { Optional name(); @@ -67,17 +75,18 @@ AppConfig config = ConfigInstanceBuilder.forInterface(AppConfig.class) .withOptional(AppConfig::name, "MyApp") .withOptional(AppConfig::timeout, 30) .build(); -``` +---- -The `withOptional` method wraps the value in `Optional.of()`, `OptionalInt.of()`, `OptionalLong.of()`, or +The `withOptional` method wraps the value in `Optional.of()`, `OptionalInt.of()`, `OptionalLong.of()`, or `OptionalDouble.of()` depending on the property type. -## Defaults +== Defaults -Properties annotated with `io.smallrye.config.WithDefault` are automatically applied when no value is explicitly set +Properties annotated with `io.smallrye.config.WithDefault` are automatically applied when no value is explicitly set in the builder: -```java +[source,java] +---- interface ServerDefaults { @WithDefault("localhost") String host(); @@ -87,25 +96,27 @@ interface ServerDefaults { } ServerDefaults server = ConfigInstanceBuilder.forInterface(ServerDefaults.class).build(); -``` +---- The `ServerDefaults#host()` will return the value `localhost` and `ServerDefaults#port()` will return the value `8080`. Explicitly set values override the `@WithDefault` annotation: -```java +[source,java] +---- ServerDefaults server = ConfigInstanceBuilder.forInterface(ServerDefaults.class) .with(ServerDefaults::host, "0.0.0.0") .build(); -``` +---- The `ServerDefaults#host()` will return the value `0.0.0.0` and `ServerDefaults#port()` will return the value `8080`. -## Nested Groups +== Nested Groups Nested configuration groups are built separately and composed into the parent builder: -```java +[source,java] +---- interface AppConfig { String name(); @@ -125,16 +136,17 @@ AppConfig config = ConfigInstanceBuilder.forInterface(AppConfig.class) .with(DatabaseConfig::poolSize, 10) .build()) .build(); -``` +---- -If a nested group has `@WithDefault` values for all its members, the nested group instance is automatically built with +If a nested group has `@WithDefault` values for all its members, the nested group instance is automatically built with those defaults when not explicitly set in the builder. -## Collections and Maps +== Collections and Maps `List`, `Set`, and `Map` types are set directly with their values: -```java +[source,java] +---- interface AppConfig { List hosts(); @@ -145,23 +157,25 @@ AppConfig config = ConfigInstanceBuilder.forInterface(AppConfig.class) .with(AppConfig::hosts, List.of("host1", "host2")) .with(AppConfig::labels, Map.of("env", "prod", "region", "us-east")) .build(); -``` +---- Collections and Maps annotated with `@WithDefault` are automatically populated when not explicitly set. -## Converters +== Converters -The builder uses the same converter mechanism as `SmallRyeConfig`. Converters are discovered via the +The builder uses the same converter mechanism as `SmallRyeConfig`. Converters are discovered via the `java.util.ServiceLoader` mechanism, or can be registered explicitly with `ConfigInstanceBuilder.registerConverter()`: -```java +[source,java] +---- ConfigInstanceBuilder.registerConverter(Duration.class, new MyDurationConverter()); -``` +---- -Properties annotated with `io.smallrye.config.WithConverter` use the specified converter for both `@WithDefault` value +Properties annotated with `io.smallrye.config.WithConverter` use the specified converter for both `@WithDefault` value conversion and any value set via the builder: -```java +[source,java] +---- interface AppConfig { @WithDefault("30s") @WithConverter(DurationConverter.class) @@ -170,18 +184,22 @@ interface AppConfig { @WithConverter(MemorySizeConverter.class) MemorySize maxBodySize(); } -``` +---- + +[NOTE] +==== -!!! info +Converters registered with `registerConverter` are global and shared across all `ConfigInstanceBuilder` instances. - Converters registered with `registerConverter` are global and shared across all `ConfigInstanceBuilder` instances. +==== -## Required Properties +== Required Properties -Properties without a `@WithDefault` are considered required. Calling `build()` throws a `NoSuchElementException` if +Properties without a `@WithDefault` are considered required. Calling `build()` throws a `NoSuchElementException` if any required property is missing: -```java +[source,java] +---- interface Server { String host(); @@ -196,20 +214,21 @@ ConfigInstanceBuilder.forInterface(Server.class).build(); ConfigInstanceBuilder.forInterface(Server.class) .with(Server::host, "localhost") .build(); -``` +---- -## Builder Reuse +== Builder Reuse A builder can be used to produce multiple instances. Each `build()` call creates a new independent instance: -```java +[source,java] +---- ConfigInstanceBuilder builder = ConfigInstanceBuilder.forInterface(Server.class) .with(Server::host, "localhost") .with(Server::port, 8080); Server first = builder.build(); Server second = builder.build(); -``` +---- -The `first` and `second` instances are equal but not the same object. Values set after a `build()` call affect only +The `first` and `second` instances are equal but not the same object. Values set after a `build()` call affect only subsequent builds. diff --git a/documentation/src/main/docs/config/map-support.md b/documentation/src/main/asciidoc/config/map-support.adoc similarity index 57% rename from documentation/src/main/docs/config/map-support.md rename to documentation/src/main/asciidoc/config/map-support.adoc index 73b948209..72b42740c 100644 --- a/documentation/src/main/docs/config/map-support.md +++ b/documentation/src/main/asciidoc/config/map-support.adoc @@ -1,49 +1,60 @@ -# Map Support += Map Support +:version-root: ../ +include::{version-root}_attributes.adoc[] -SmallRye Config allows injecting multiple configuration parameters as a `Map`. The configuration value syntax is +SmallRye Config allows injecting multiple configuration parameters as a `Map`. The configuration value syntax is represented by `property.name.map-key=value` Consider: -```properties +[source,properties] +---- server.reasons.200=OK server.reasons.201=Created -``` +---- The previous configuration could be injected directly in a CDI Bean: With `@ConfigProperty` -```java +[source,java] +---- @ApplicationScoped public class ConfigBean { @Inject @ConfigProperty(name = "server.reasons") Map reasons; } -``` +---- With `@ConfigProperties` -```java +[source,java] +---- @ConfigProperties(prefix = "server") public class Config { Map reasons; } -``` +---- The `Map` will contains the keys `200` and `201`, which map to the values `OK` and `Created`. -!!!note +[NOTE] +==== - Only the direct sub properties will be converted into a `Map` and - injected into the target bean, the rest will be ignored. In other words, - in the previous example, a property whose name is `reasons.200.a` would - be ignored as not considered as a direct sub property. +Only the direct sub properties will be converted into a `Map` and +injected into the target bean, the rest will be ignored. In other words, +in the previous example, a property whose name is `reasons.200.a` would +be ignored as not considered as a direct sub property. -!!!note +==== - The property will be considered as missing if no direct sub properties - could be found. +[NOTE] +==== -It is also possible to retrieve the `Map` programmatically by calling the methods -`SmallRyeConfig#getValues("server.reasons", Integer.class, String.class)` or +The property will be considered as missing if no direct sub properties +could be found. + +==== + +It is also possible to retrieve the `Map` programmatically by calling the methods +`SmallRyeConfig#getValues("server.reasons", Integer.class, String.class)` or `SmallRyeConfig#getOptionalValues("server.reasons", Integer.class, String.class)`. diff --git a/documentation/src/main/docs/config/mappings.md b/documentation/src/main/asciidoc/config/mappings.adoc similarity index 62% rename from documentation/src/main/docs/config/mappings.md rename to documentation/src/main/asciidoc/config/mappings.adoc index ef8952c3e..b7454239f 100644 --- a/documentation/src/main/docs/config/mappings.md +++ b/documentation/src/main/asciidoc/config/mappings.adoc @@ -1,74 +1,85 @@ -# Mappings += Mappings +:version-root: ../ +include::{version-root}_attributes.adoc[] -With SmallRye Config Mappings, it is possible to group multiple configuration properties in a single interface that +With SmallRye Config Mappings, it is possible to group multiple configuration properties in a single interface that share the same prefix (or namespace). It supports the following set of features: -- Automatic conversion of the configuration type, including `List`, `Set`, `Map`, `Optional` and primitive types. -- Nested Config Mapping groups. -- Configuration Properties Naming Strategies -- Integration with Bean Validation +* Automatic conversion of the configuration type, including `List`, `Set`, `Map`, `Optional` and primitive types. +* Nested Config Mapping groups. +* Configuration Properties Naming Strategies +* Integration with Bean Validation -## Mapping Rules +== Mapping Rules A complex object type uses the following rules to map configuration values to their member values: -- A configuration path is built by taking the object type prefix (or namespace) and the mapping member name -- The member name is converted to its kebab-case format -- If the member name is represented as a getter, the member name is taken from its property name equivalent, and then - converted to its kebab-case format -- The configuration value is automatically converted to the member type -- The configuration path is required to exist with a valid configuration value or the mapping will fail +* A configuration path is built by taking the object type prefix (or namespace) and the mapping member name +* The member name is converted to its kebab-case format +* If the member name is represented as a getter, the member name is taken from its property name equivalent, and then +converted to its kebab-case format +* The configuration value is automatically converted to the member type +* The configuration path is required to exist with a valid configuration value or the mapping will fail -!!! info +[NOTE] +==== - Kebab-case - the method name is derived by replacing case changes with a dash to map the configuration property. +Kebab-case - the method name is derived by replacing case changes with a dash to map the configuration property. -A Config Mapping requires an interface with minimal metadata configuration annotated with +==== + +A Config Mapping requires an interface with minimal metadata configuration annotated with `io.smallrye.config.ConfigMapping`: -```java +[source,java] +---- @ConfigMapping(prefix = "server") interface Server { String host(); int port(); } -``` +---- -The `Server` interface is able to map configurations with the name `server.host` into the `Server#host()` method and -`server.port` into `Server#port()` method. The configuration property name to lookup is built from the prefix, and the +The `Server` interface is able to map configurations with the name `server.host` into the `Server#host()` method and +`server.port` into `Server#port()` method. The configuration property name to lookup is built from the prefix, and the method name with `.` (dot) as the separator. -!!! warning +[WARNING] +==== + +If a mapping fails to match a configuration property the config system throws a `NoSuchElementException`, unless +the mapped element is an `Optional`. - If a mapping fails to match a configuration property the config system throws a `NoSuchElementException`, unless - the mapped element is an `Optional`. +==== The `@ConfigMapping` interface must obey the following rules: -- A mapping method cannot accept parameters -- A mapping method return type cannot be void -- A mapping cannot use self-reference types -- `default` methods are allowed +* A mapping method cannot accept parameters +* A mapping method return type cannot be void +* A mapping cannot use self-reference types +* `default` methods are allowed -## Registration +== Registration -Registration of Config Mappings is automatic in CDI aware environments with the `@ConfigMapping` annotation. +Registration of Config Mappings is automatic in CDI aware environments with the `@ConfigMapping` annotation. -In non-CDI environments, the Config Mapping can be registered via `SmallRyeConfigBuilder#withMapping`. In this case, +In non-CDI environments, the Config Mapping can be registered via `SmallRyeConfigBuilder#withMapping`. In this case, the `@ConfigMapping` is completely optional (but recommendeded to set the prefix). -```java +[source,java] +---- SmallRyeConfig config = new SmallRyeConfigBuilder() .withMapping(Server.class) .build(); -``` +---- -## Retrieval +== Retrieval A config mapping interface can be injected into any CDI aware bean: -```java +[source,java] +---- @ApplicationScoped class BusinessBean { @Inject @@ -78,71 +89,81 @@ class BusinessBean { String host = server.host(); } } -``` +---- -In non-CDI environments, use the API `io.smallrye.config.SmallRyeConfig#getConfigMapping` to retrieve the config +In non-CDI environments, use the API `io.smallrye.config.SmallRyeConfig#getConfigMapping` to retrieve the config mapping instance: -```java +[source,java] +---- Config config = Config.getOrCreate(); Server server = config.getConfigMapping(Server.class); -``` +---- -!!! info +[NOTE] +==== - Config Mapping instances are cached. They are populated when the `SmallRyeConfig` instance is initialized and - their values are not updated on `ConfigSource` changes. +Config Mapping instances are cached. They are populated when the `SmallRyeConfig` instance is initialized and +their values are not updated on `ConfigSource` changes. + +==== For a Config Mapping to be valid, it needs to match every configuration property name contained in the `Config` under the specified prefix set in `@ConfigMapping`. This prevents unknown configuration properties in the `Config`. -### Disabling validation +=== Disabling validation Validation can be disabled entirely in two ways: Via configuration property: -```properties +[source,properties] +---- smallrye.config.mapping.validate-unknown=false -``` +---- Or programmatically via the builder: -```java +[source,java] +---- SmallRyeConfig config = new SmallRyeConfigBuilder() .withMapping(Server.class) .withValidateUnknown(false) .build(); -``` +---- -### Ignoring specific paths +=== Ignoring specific paths Rather than disabling validation entirely, specific paths can be ignored with `SmallRyeConfigBuilder#withMappingIgnore`. The path argument supports three patterns: -| Pattern | Meaning | -|-----------|--------------------------------------------------------| -| `foo.bar` | Ignores the exact configuration name `foo.bar` | -| `foo.*` | Ignores all direct child names under `foo` | -| `foo.**` | Ignores all names under `foo` at any level (recursive) | +[cols=",",options="header",] +|=== +|Pattern |Meaning +|`foo.bar` |Ignores the exact configuration name `foo.bar` +|`foo.++*++` |Ignores all direct child names under `foo` +|`foo.++**++` |Ignores all names under `foo` at any level (recursive) +|=== -```java +[source,java] +---- SmallRyeConfig config = new SmallRyeConfigBuilder() .withMapping(Server.class) .withMappingIgnore("server.foo") // ignore the exact name .withMappingIgnore("server.extras.*") // ignore direct children of server.extras .withMappingIgnore("server.legacy.**") // ignore everything under server.legacy .build(); -``` +---- Multiple calls to `withMappingIgnore` accumulate — each call adds to the set of ignored paths. -## Defaults +== Defaults The `io.smallrye.config.WithDefault` annotation allows to set a default property value into a mapping (and prevent errors if the configuration value is not available in any `ConfigSource`). -```java +[source,java] +---- public interface Defaults { @WithDefault("foo") String foo(); @@ -150,20 +171,21 @@ public interface Defaults { @WithDefault("bar") String bar(); } -``` +---- No configuration properties are required. The `Defaults#foo()` will return the value `foo` and `Defaults#bar()` will return the value `bar`. -## Nested Groups +== Nested Groups A nested mapping provides a way to map sub-groups of configuration properties. -- A nested type contributes with its name (converted to its kebab-case format) -- The configuration path is built by taking the root object type prefix (or namespace), the nested type name and the +* A nested type contributes with its name (converted to its kebab-case format) +* The configuration path is built by taking the root object type prefix (or namespace), the nested type name and the member name of the nested type -```java +[source,java] +---- @ConfigMapping(prefix = "server") public interface Server { String host(); @@ -180,24 +202,26 @@ public interface Server { boolean rotate(); } } -``` +---- -```properties +[source,properties] +---- server.host=localhost server.port=8080 server.log.enabled=true server.log.suffix=.log server.log.rotate=false -``` +---- The method name of a mapping group acts as a sub-prefix in the property name. In this case the matching property to `Server.Log#enabled` is `server.log.enabled`. -## Hierarchy +== Hierarchy A config mapping can extend another mapping and inherit all its super members: -```java +[source,java] +---- public interface Parent { String name(); } @@ -206,11 +230,12 @@ public interface Parent { public interface Child extends Parent { } -``` +---- And override members: -```java +[source,java] +---- public interface Parent { String name(); } @@ -220,16 +245,17 @@ public interface Child extends Parent { @WithName("child-name") String name(); } -``` +---- -## Overriding property names +== Overriding property names -### `@WithName` +=== `@WithName` -If a method name and a property name do not match, the `io.smallrye.config.WithName` annotation can +If a method name and a property name do not match, the `io.smallrye.config.WithName` annotation can override the method name mapping and use the name supplied in the annotation. -```java +[source,java] +---- @ConfigMapping(prefix = "server") interface Server { @WithName("name") @@ -237,19 +263,21 @@ interface Server { int port(); } -``` +---- -```properties +[source,properties] +---- server.name=localhost server.port=8080 -``` +---- -### `@WithParentName` +=== `@WithParentName` -The `io.smallrye.config.WithParentName` annotation allows configurations mappings to inherit its parent container name, +The `io.smallrye.config.WithParentName` annotation allows configurations mappings to inherit its parent container name, simplifying the configuration property name required to match the mapping. -```java +[source,java] +---- @ConfigMapping(prefix = "server") interface Server { @WithParentName @@ -268,65 +296,71 @@ interface ServerHostAndPort { interface ServerInfo { String name(); } -``` +---- -```properties +[source,properties] +---- server.host=localhost server.port=8080 server.name=konoha -``` +---- Without the `@WithParentName` the method `ServerInfo#name` maps the configuration property `server.info.name`. With -`@WithParentName`, the `Server#info` mapping will inherit the parent name from `Server` and `ServerInfo#name` maps to +`@WithParentName`, the `Server#info` mapping will inherit the parent name from `Server` and `ServerInfo#name` maps to the property `server.name` instead. -### NamingStrategy +=== NamingStrategy Method names in camelCase map to kebab-case configuration property names by default. -```java +[source,java] +---- @ConfigMapping(prefix = "server") interface Server { String theHost(); int thePort(); } -``` +---- -```properties +[source,properties] +---- server.the-host=localhost server.the-port=8080 -``` +---- The mapping strategy can be adjusted by setting `namingStrategy` value in the `@ConfigMapping` annotation. -```java +[source,java] +---- @ConfigMapping(prefix = "server", namingStrategy = ConfigMapping.NamingStrategy.VERBATIM) public interface ServerVerbatimNamingStrategy { String theHost(); int thePort(); } -``` +---- -```properties +[source,properties] +---- server.theHost=localhost server.thePort=8080 -``` +---- The `@ConfigMapping` annotation support the following naming stategies: -- KEBAB_CASE - The method name is derived by replacing case changes with a dash to map the configuration property. -- VERBATIM - The method name is used as is to map the configuration property. -- SNAKE_CASE - The method name is derived by replacing case changes with an underscore to map the configuration property. +* KEBAB++_++CASE - The method name is derived by replacing case changes with a dash to map the configuration property. +* VERBATIM - The method name is used as is to map the configuration property. +* SNAKE++_++CASE - The method name is derived by replacing case changes with an underscore to map the configuration property. -### `beanStyleGetters` +=== `beanStyleGetters` The `beanStyleGetters` attribute (default `false`) enables matching bean-style getter names (`get`/`is` prefixed) to their property name equivalent. For example, `getHost()` and `isEnabled()` map to the properties `host` and `enabled` respectively: -```java +[source,java] +---- @ConfigMapping(prefix = "server", beanStyleGetters = true) public interface Server { String getHost(); @@ -335,25 +369,30 @@ public interface Server { boolean isEnabled(); } -``` +---- -```properties +[source,properties] +---- server.host=localhost server.port=8080 server.enabled=true -``` +---- + +[WARNING] +==== -!!! warning +Bean-style getter matching allows multiple method names to match the same configuration name. For instance, +`getFoo` and `isFoo` both match `foo`, which may not be intended. Prefer simple method names that match +one-to-one with their configuration names. - Bean-style getter matching allows multiple method names to match the same configuration name. For instance, - `getFoo` and `isFoo` both match `foo`, which may not be intended. Prefer simple method names that match - one-to-one with their configuration names. +==== -## Conversion +== Conversion A config mapping interface support automatic conversions of all types available for conversion in `Config`. -```java +[source,java] +---- @ConfigMapping public interface SomeTypes { @WithName("int") @@ -392,20 +431,22 @@ public interface SomeTypes { @WithName("boolean") Boolean booleanWrapper(); } -``` +---- -```properties +[source,properties] +---- int=9 long=9999999999 float=99.9 double=99.99 char=c boolean=true -``` +---- This is also valid for `Optional` and friends. -```java +[source,java] +---- @ConfigMapping public interface Optionals { Optional server(); @@ -421,15 +462,16 @@ public interface Optionals { int port(); } } -``` +---- In this case, the mapping won’t fail if the configuraton properties values are missing. -### `@WithConverter` +=== `@WithConverter` The `io.smallrye.config.WithConverter` annotation provides a way to set a specific `Converter` in a mapping. -```java +[source,java] +---- @ConfigMapping public interface Converters { @WithConverter(FooBarConverter.class) @@ -442,27 +484,29 @@ public static class FooBarConverter implements Converter { return "bar"; } } -``` +---- -```properties +[source,properties] +---- foo=foo -``` +---- A call to `Converters.foo()` results in the value `bar`. -## Collections +== Collections A config mapping is also able to map the collections types `List` and `Set`. -- A member with a `Collection` type requires the configuration name to be in its indexed format -- Each configuration name, plus its index maps the configuration value to the corresponding `Collection` element in the +* A member with a `Collection` type requires the configuration name to be in its indexed format +* Each configuration name, plus its index maps the configuration value to the corresponding `Collection` element in the object type -- The index must be part of the configuration path, by appending the index between square brackets to the`Collection` +* The index must be part of the configuration path, by appending the index between square brackets to the`Collection` member -- The index specified in the configuration name is used to order the element in the `Collection` -- Missing elements or gaps are removed +* The index specified in the configuration name is used to order the element in the `Collection` +* Missing elements or gaps are removed -```java +[source,java] +---- @ConfigMapping(prefix = "server") public interface ServerCollections { Set environments(); @@ -481,34 +525,39 @@ public interface ServerCollections { } } } -``` +---- -```properties +[source,properties] +---- server.environments[0].name=dev server.environments[0].apps[0].name=rest server.environments[0].apps[0].services=bookstore,registration server.environments[0].apps[0].databases=pg,h2 server.environments[0].apps[1].name=batch server.environments[0].apps[1].services=stock,warehouse -``` +---- -The `List` and `Set` mappings can use [Indexed Properties](indexed-properties.md) to map configuration values in +The `List` and `Set` mappings can use xref:config/indexed-properties.adoc[Indexed Properties] to map configuration values in mapping groups. -!!! info +[NOTE] +==== - A `List` mapping is backed by an `ArrayList`, and a `Set` mapping is backed by a `HashSet`. +A `List` mapping is backed by an `ArrayList`, and a `Set` mapping is backed by a `HashSet`. -## Maps +==== + +== Maps A config mapping is also able to map a `Map`. -- A member with a `Map` type requires an additional configuration name added to the configuration path of the `Map` +* A member with a `Map` type requires an additional configuration name added to the configuration path of the `Map` member to act as a map key -- The additional configuration name maps a Map entry with the configuration name as the `Map` entry key and +* The additional configuration name maps a Map entry with the configuration name as the `Map` entry key and the configuration value as the Map entry value -```java +[source,java] +---- @ConfigMapping(prefix = "server") public interface Server { String host(); @@ -523,9 +572,10 @@ public interface Server { String name(); } } -``` +---- -```properties +[source,properties] +---- server.host=localhost server.port=8080 server.form.index=index.html @@ -534,68 +584,80 @@ server.form.error.page=error.html server.aliases.localhost[0].name=prod server.aliases.localhost[1].name=127.0.0.1 server.aliases.\"io.smallrye\"[0].name=smallrye -``` +---- -The configuration property name needs to specify an additional segment to act as the map key. The `server.form` matches -the `Server#form` `Map` and the segments `index`, `login.page` and `error.page` represent the `Map` +The configuration property name needs to specify an additional segment to act as the map key. The `server.form` matches +the `Server#form` `Map` and the segments `index`, `login.page` and `error.page` represent the `Map` keys. -!!! info +[NOTE] +==== + +A `Map` mapping is backed by an `HashMap`. - A `Map` mapping is backed by an `HashMap`. +==== -When populating a `Map`, `SmallRyeConfig` requires the configuration names listed in -`SmallRyeConfig#getPropertyNames` to find the `Map` keys. If a `ConfigSource` does not support -`getPropertyNames` (empty), the names must be provided by another `ConfigSource` that can do so. After retrieving the -map keys, `SmallRyeConfig` performs the lookup of the values with the regular `ConfigSource` ordinal ordering. Even if -a `ConfigSource` does not provide `getPropertyNames` it can provide the value by having the name listed in another +When populating a `Map`, `SmallRyeConfig` requires the configuration names listed in +`SmallRyeConfig#getPropertyNames` to find the `Map` keys. If a `ConfigSource` does not support +`getPropertyNames` (empty), the names must be provided by another `ConfigSource` that can do so. After retrieving the +map keys, `SmallRyeConfig` performs the lookup of the values with the regular `ConfigSource` ordinal ordering. Even if +a `ConfigSource` does not provide `getPropertyNames` it can provide the value by having the name listed in another capable `ConfigSource`. -For collection types, the key requires the indexed format. The configuration name `server.aliases.localhost[0].name` -maps to the `Map> aliases()` member, where `localhost` is the `Map` key, `[0]` is the index of the -`List` collection where the `Alias` element will be stored, containing the name `prod`. +For collection types, the key requires the indexed format. The configuration name `server.aliases.localhost++[++0++]++.name` +maps to the `Map++<++String, List++<++Alias++>>++ aliases()` member, where `localhost` is the `Map` key, `++[++0++]++` is the index of the +`List++<++Alias++>++` collection where the `Alias` element will be stored, containing the name `prod`. + +[TIP] +.Map quoted keys requirement +==== -!!! tip "Map quoted keys requirement" +The `Map` key part in the configuration property name may require quotes to delimit the key if the key contains +a dot, otherwise they are optional. If the key name is delimited by quotes, all configuration property names related +with the same name must use the quoted format across all sources, including Environment Variables. - The `Map` key part in the configuration property name may require quotes to delimit the key if the key contains - a dot, otherwise they are optional. If the key name is delimited by quotes, all configuration property names related - with the same name must use the quoted format across all sources, including Environment Variables. +==== -!!! warning "Do not mix quoted and unquoted keys" +[WARNING] +.Do not mix quoted and unquoted keys +==== - For a key that spans a single segment, the quoted and unquoted forms name the same `Map` key. Both - `server.aliases.localhost.name` and `server.aliases."localhost".name` refer to the key `localhost`, so writing both - makes the key ambiguous. +For a key that spans a single segment, the quoted and unquoted forms name the same `Map` key. Both +`server.aliases.localhost.name` and `server.aliases."localhost".name` refer to the key `localhost`, so writing both +makes the key ambiguous. - When `SmallRyeConfig` finds both forms, it resolves the entry with the quoted form and logs a warning: +When `SmallRyeConfig` finds both forms, it resolves the entry with the quoted form and logs a warning: - ``` - SRCFG01009: The Map path keys "server.aliases."localhost"" and "server.aliases.localhost" are ambiguous. These can - cause issues in the mapping. Please, do not mix quoted and unquoted in the same Map key. Using - server.aliases."localhost". - ``` +.... +SRCFG01009: The Map path keys "server.aliases."localhost"" and "server.aliases.localhost" are ambiguous. These can +cause issues in the mapping. Please, do not mix quoted and unquoted in the same Map key. Using +server.aliases."localhost". +.... - Because only the quoted form is used to look up the entry values, the property names written in the unquoted form - are left unmapped, and the mapping fails validation: +Because only the quoted form is used to look up the entry values, the property names written in the unquoted form +are left unmapped, and the mapping fails validation: - ``` - SRCFG00050: server.aliases.localhost.name does not map to any root - ``` +.... +SRCFG00050: server.aliases.localhost.name does not map to any root +.... - If the two forms also split the members of a nested group between them, the members that only exist in the - unquoted form are not found at all, and the mapping additionally fails with: +If the two forms also split the members of a nested group between them, the members that only exist in the +unquoted form are not found at all, and the mapping additionally fails with: - ``` - SRCFG00014: The config property server.aliases."localhost".name is required but it could not be found in any config source - ``` +.... +SRCFG00014: The config property server.aliases."localhost".name is required but it could not be found in any config source +.... - Either form works on its own, so pick one and use it consistently for a given key across all sources. +Either form works on its own, so pick one and use it consistently for a given key across all sources. -### `@WithUnnamedKey` +==== + +=== `@WithUnnamedKey` The `io.smallrye.config.WithUnnamedKey` annotation allows to omit a single map key in the configuration path: -```java +[source,java] +---- @ConfigMapping(prefix = "server") public interface Server { @WithUnnamedKey("localhost") @@ -605,31 +667,37 @@ public interface Server { String name(); } } -``` +---- -```properties +[source,properties] +---- server.aliases.name=localhost server.aliases.prod.name=prod -``` +---- -The `sever.aliases.name` is an unnamed `Map` property, because it does not contain the `Map` key to populate the `Map` -entry. Due to `@WithUnnamedKey("localhost")` the `Map` key is not required in the configuration path. The key used to +The `sever.aliases.name` is an unnamed `Map` property, because it does not contain the `Map` key to populate the `Map` +entry. Due to `@WithUnnamedKey("localhost")` the `Map` key is not required in the configuration path. The key used to look up the Map entry is given by `io.smallrye.config.WithUnnamedKey#value`: -```java +[source,java] +---- Server server = config.getConfigMapping(Server.class); Map localhost = server.aliases.get("localhost"); -``` +---- + +[WARNING] +==== -!!! warning +If the unnamed key (in this case `localhost`) is explicitly set in a property name, the explicit value takes precedence - If the unnamed key (in this case `localhost`) is explicitly set in a property name, the explicit value takes precedence +==== The `eager` attribute (default `true`) controls whether the unnamed key entry is included in the `Map` when its values come only from defaults. When `eager = false`, the unnamed key entry is excluded from the `Map` unless at least one of its values is explicitly set in a configuration source: -```java +[source,java] +---- @ConfigMapping(prefix = "server") public interface Server { @WithUnnamedKey(value = "localhost", eager = false) @@ -640,17 +708,18 @@ public interface Server { String name(); } } -``` +---- With `eager = false` and no properties set, `server.aliases` returns an empty `Map`. With `eager = true` (the default), it returns a `Map` with the key `localhost` populated from the `@WithDefault`. -### `@WithKeys` +=== `@WithKeys` -The `io.smallrye.config.WithKeys` annotation allows to define which `Map` keys must be loaded by -the configuration: +The `io.smallrye.config.WithKeys` annotation allows to define which `Map` keys must be loaded by +the configuration: -```java +[source,java] +---- @ConfigMapping(prefix = "server") public interface Server { @WithKeys(KeysProvider.class) @@ -667,28 +736,30 @@ public interface Server { } } } -``` +---- -In this case, `SmallRyeConfig` will look for the map keys `dev`, `test` and `prod` instead of discovering the keys +In this case, `SmallRyeConfig` will look for the map keys `dev`, `test` and `prod` instead of discovering the keys with `SmallRyeConfig#getPropertyNames`: -```properties +[source,properties] +---- servers.alias.dev.name=dev servers.alias.test.name=test servers.alias.prod.name=prod -``` +---- The provided list will effectively substitute the lookup in `SmallRyeConfig#getPropertyNames`, thus enabling a -`ConfigSource` that does not list its properties, to contribute configuration to the `Map`. Each key must exist in -the final configuration (relative to the `Map` path segment), or the mapping will fail with a +`ConfigSource` that does not list its properties, to contribute configuration to the `Map`. Each key must exist in +the final configuration (relative to the `Map` path segment), or the mapping will fail with a `ConfigValidationException`. -### `@WithDefaults` +=== `@WithDefaults` The `io.smallrye.config.WithDefaults` is a marker annotation to use only in a `Map` to return the default value for the value element on any key lookup: -```java +[source,java] +---- @ConfigMapping(prefix = "server") public interface Server { @WithDefaults @@ -699,11 +770,12 @@ public interface Server { String name(); } } -``` +---- -```properties +[source,properties] +---- server.aliases.prod.name=prod -``` +---- A look-up to the `aliases` `Map` with the key `localhost`, `any` or any other key, returns a `Alias` instance, where `Alias.name` is `localhost`, which is the default value. A look-up to `prod` returns a `Alias` instance, where @@ -712,55 +784,61 @@ A look-up to the `aliases` `Map` with the key `localhost`, `any` or any other ke The `Map` can only iterate and size the defined keys. In this case, the `aliases` `Map` only iterates the `prod` key, and the size is `1`. -```java +[source,java] +---- Server server = config.getConfigMapping(Server.class); Map localhost = server.aliases().get("localhost"); Map any = server.aliases().get("any"); Map prod = server.aliases().get("prod"); -``` +---- -## Optionals +== Optionals -- A mapping can wrap any complex type with an `Optional` -- `Optional` mappings do not require the configuration path and value to be present +* A mapping can wrap any complex type with an `Optional` +* `Optional` mappings do not require the configuration path and value to be present -## Secrets +== Secrets -- A mapping can mark a member type as a secret with `Secret`: +* A mapping can mark a member type as a secret with `Secret++<++T++>++`: -```java +[source,java] +---- @ConfigMapping(prefix = "credentials") public interface Credentials { String username(); Secret password(); } -``` +---- A `Secret` value modifies the behaviour of the config system by: -- Omitting the name of the secret in `SmallRyeConfig#getPropertyNames()` -- Omitting the name and value of the secret in the mapping `toString` method -- Throwing a `SecurityException` when trying to retrieve the value via `SmallRyeConfig` programmatic API +* Omitting the name of the secret in `SmallRyeConfig#getPropertyNames()` +* Omitting the name and value of the secret in the mapping `toString` method +* Throwing a `SecurityException` when trying to retrieve the value via `SmallRyeConfig` programmatic API -A Secret can be of any type that can be converted by a registered `org.eclipse.microprofile.config.spi.Converter` of +A Secret can be of any type that can be converted by a registered `org.eclipse.microprofile.config.spi.Converter` of the same type. -## toString, equals, hashcode +== toString, equals, hashcode If the config mapping contains a `toString` method declaration, the config mapping instance will include a proper implementation of the `toString` method. The `equals` and `hashcode` methods are included automatically. -!!! caution +[CAUTION] +==== + +Do not include a `toString` declaration in a config mapping with sensitive information. - Do not include a `toString` declaration in a config mapping with sensitive information. +==== -## Validation +== Validation -A config mapping may combine annotations from [Bean Validation](https://beanvalidation.org/) to validate configuration +A config mapping may combine annotations from https://beanvalidation.org/[Bean Validation] to validate configuration properties values. -```java +[source,java] +---- @ConfigMapping(prefix = "server") interface Server { @Size(min = 2, max = 20) @@ -769,11 +847,14 @@ interface Server { @Max(10000) int port(); } -``` +---- -The application startup fails with a `io.smallrye.config.ConfigValidationException` if the configuration properties -values do not follow the contraints defined in `Server`. +The application startup fails with a `io.smallrye.config.ConfigValidationException` if the configuration properties +values do not follow the contraints defined in `Server`. -!!! info - - For validation to work, the `smallrye-config-validator` dependency is required in the classpath. +[NOTE] +==== + +For validation to work, the `smallrye-config-validator` dependency is required in the classpath. + +==== diff --git a/documentation/src/main/docs/config/profiles.md b/documentation/src/main/asciidoc/config/profiles.adoc similarity index 53% rename from documentation/src/main/docs/config/profiles.md rename to documentation/src/main/asciidoc/config/profiles.adoc index 77277bd4f..ca2dd361e 100644 --- a/documentation/src/main/docs/config/profiles.md +++ b/documentation/src/main/asciidoc/config/profiles.adoc @@ -1,83 +1,105 @@ -# Profiles += Profiles +:version-root: ../ +include::{version-root}_attributes.adoc[] -Applications often require different configurations depending on the target environment. For example, the local -development environment may be different from the production environment. Profiles allow for multiple configurations +Applications often require different configurations depending on the target environment. For example, the local +development environment may be different from the production environment. Profiles allow for multiple configurations in the same file or separate files and select between them via a profile name. -## Profile aware properties +== Profile aware properties -To be able to set properties with the same name, each property needs to be prefixed with a percentage sign `%` followed -by the profile name and a dot `.` in the syntax `%{profile-name}.config.name`: +To be able to set properties with the same name, each property needs to be prefixed with a percentage sign `%` followed +by the profile name and a dot `.` in the syntax `%++{++profile-name}.config.name`: -```properties title="META-INF/microprofile-config.properties" +.META-INF/microprofile-config.properties +[source,properties] +---- http.port=8080 %dev.http.port=8181 -``` +---- -To activate the profile `dev`, the configuration `smallrye.config.profile=dev` has to be set into any valid +To activate the profile `dev`, the configuration `smallrye.config.profile=dev` has to be set into any valid `ConfigSource`. -Any lookup to the `http.port` property name will first search by the active profile name `%dev.http.port` and then -fallback to `http.port` if no value is present. In this case a lookup to the property `http.port` with the `dev` profile +Any lookup to the `http.port` property name will first search by the active profile name `%dev.http.port` and then +fallback to `http.port` if no value is present. In this case a lookup to the property `http.port` with the `dev` profile active, yields the value `8181`. -!!! attention +[WARNING] +==== - The profile must be set in one of the primary sources (system properties, environment variables, - `application.properties`, or any other source that does not require configuration) to determine the proper - configuration. +The profile must be set in one of the primary sources (system properties, environment variables, +`application.properties`, or any other source that does not require configuration) to determine the proper +configuration. -## Profile aware files +==== -Properties for a specific profile may reside in a `microprofile-config-{profile}.properties` named file. The previous +== Profile aware files + +Properties for a specific profile may reside in a `microprofile-config-++{++profile}.properties` named file. The previous example can be expressed as: -```properties title="META-INF/microprofile-config.properties" +.META-INF/microprofile-config.properties +[source,properties] +---- http.port=8080 -``` +---- -```properties title="META-INF/microprofile-config-dev.properties" +.META-INF/microprofile-config-dev.properties +[source,properties] +---- http.port=8181 -``` +---- In this style, the property names in the profile aware file do not need to be prefixed with the profile name. -!!! note +[NOTE] +==== + +Properties in the profile aware file have priority over profile aware properties defined in the main file. + +==== - Properties in the profile aware file have priority over profile aware properties defined in the main file. +[WARNING] +==== -!!! attention +Do not use Profile aware files to set `smallrye.config.profile`. This will not work because the +the profile is required in advance to load the profile aware files. - Do not use Profile aware files to set `smallrye.config.profile`. This will not work because the - the profile is required in advance to load the profile aware files. +==== -## Priority +== Priority -Profile lookups are only valid if the `ConfigSource` has a higher ordinal than a lookup to the regular configuration +Profile lookups are only valid if the `ConfigSource` has a higher ordinal than a lookup to the regular configuration name. Consider: -```properties title="main.properties" +.main.properties +[source,properties] +---- config_ordinal=1000 http.port=8080 -``` +---- -```properties title="profile.properties" +.profile.properties +[source,properties] +---- config_ordinal=100 %dev.http.port=8181 -``` +---- -Even with the profile `dev` active, the lookup value for `my.prop` is `1234`. This prevents lower ordinal sources to +Even with the profile `dev` active, the lookup value for `my.prop` is `1234`. This prevents lower ordinal sources to set a profile property value that cannot be overridden unless the profile property is also overridden. -## Multiple Profiles +== Multiple Profiles -Multiple Profiles may be active at the same time. The configuration `smallrye.config.profile` accepts a comma-separated +Multiple Profiles may be active at the same time. The configuration `smallrye.config.profile` accepts a comma-separated list of profile names: `smallrye.config.profile=common,dev`. Both `common` and `dev` are separate profiles. -When multiple profiles are active, the rules for profile configuration are the same. If two profiles define the same +When multiple profiles are active, the rules for profile configuration are the same. If two profiles define the same configuration, then the last listed profile has priority. Consider: -```properties +[source,properties] +---- smallrye.config.profile=common,dev my.prop=1234 @@ -87,44 +109,46 @@ my.prop=1234 %common.commom.prop=common %dev.dev.prop=dev %test.test.prop=test -``` +---- Then -- `common.prop` value is `common` -- `dev.prop` value is `dev` -- `my.prop` value is `5678` -- `test.prop` does not have a value +* `common.prop` value is `common` +* `dev.prop` value is `dev` +* `my.prop` value is `5678` +* `test.prop` does not have a value It is also possible to define multiple profile properties, with a comma-separated list of profile names: - -```properties +[source,properties] +---- %prod,dev.my.prop=1234 -``` +---- -The property name `common.prop` is active in both `dev` and `prod` profile. If the same property name exists in +The property name `common.prop` is active in both `dev` and `prod` profile. If the same property name exists in multiple profile properties then, the property name with the most specific profile wins: -```properties +[source,properties] +---- smallrye.config.profile=dev %prod,dev.my.prop=1234 %dev.my.prop=5678 -``` +---- Then `my.prop` value is `5678`. -## Parent Profile +== Parent Profile -A Parent Profile adds multiple levels of hierarchy to the current profile. The configuration +A Parent Profile adds multiple levels of hierarchy to the current profile. The configuration `smallrye.config.profile.parent` also acccepts a comma-separated list of profile names. -When the Parent Profile is active, if a property cannot be found in the current active Profile, the config lookup +When the Parent Profile is active, if a property cannot be found in the current active Profile, the config lookup fallbacks to the Parent Profile. Consider: -```properties +[source,properties] +---- smallrye.config.profile=dev smallrye.config.profile.parent=common @@ -135,31 +159,34 @@ my.prop=1234 %common.commom.prop=common %dev.dev.prop=dev %test.test.prop=test -``` +---- Then -- `common.prop` value is `common` -- `dev.prop` value is `dev` -- `my.prop` value is `0` -- `test.prop` does not have a value +* `common.prop` value is `common` +* `dev.prop` value is `dev` +* `my.prop` value is `0` +* `test.prop` does not have a value + +[WARNING] +==== -!!! attention +Do not use Profile aware files to set smallrye.config.profile.parent++`++. This will not work because the +the profile is required in advance to load the profile aware files. - Do not use Profile aware files to set smallrye.config.profile.parent`. This will not work because the - the profile is required in advance to load the profile aware files. +==== -### Multi-level Hierarchy +=== Multi-level Hierarchy The Parent Profile also supports multiple levels of hierarchies: -```properties +[source,properties] +---- smallrye.config.profile=child %child.smallrye.config.profile.parent=parent %parent.smallrye.config.profile.parent=grandparent %grandparent.smallrye.config.profile.parent=greatgrandparent %greatgrandparent.smallrye.config.profile.parent=end -``` - -Will load the following profiles in order: `child`, `parent`, `grandparent`, `greatgrandparent`, `end` +---- +Will load the following profiles in order: `child`, `parent`, `grandparent`, `greatgrandparent`, `end` diff --git a/documentation/src/main/docs/config/secret-handlers/encryptor.java b/documentation/src/main/asciidoc/config/secret-handlers/encryptor.java similarity index 100% rename from documentation/src/main/docs/config/secret-handlers/encryptor.java rename to documentation/src/main/asciidoc/config/secret-handlers/encryptor.java diff --git a/documentation/src/main/docs/config/secret-keys.md b/documentation/src/main/asciidoc/config/secret-keys.adoc similarity index 58% rename from documentation/src/main/docs/config/secret-keys.md rename to documentation/src/main/asciidoc/config/secret-keys.adoc index 6d33dec88..876d37281 100644 --- a/documentation/src/main/docs/config/secret-keys.md +++ b/documentation/src/main/asciidoc/config/secret-keys.adoc @@ -1,8 +1,10 @@ -# Secret Keys += Secret Keys +:version-root: ../ +include::{version-root}_attributes.adoc[] -## Secret Keys Expressions +== Secret Keys Expressions -In SmallRye Config, a secret configuration may be expressed as `${handler::value}`, where the `handler` is the name of +In SmallRye Config, a secret configuration may be expressed as `$++{++handler::value}`, where the `handler` is the name of a `io.smallrye.config.SecretKeysHandler` to decode or decrypt the `value` separated by a double colon `::`. It is possible to create a custom `SecretKeysHandler` and provide different ways to decode or decrypt configuration @@ -13,11 +15,12 @@ A custom `SecretKeysHandler` requires an implementation of `io.smallrye.config.S mechanism, either in `META-INF/services/io.smallrye.config.SecretKeysHandler` or `META-INF/services/io.smallrye.config.SecretKeysHandlerFactory` files. -### Custom `SecretKeysHandler` +=== Custom `SecretKeysHandler` A direct `SecretKeysHandler` implementation is suitable when the handler needs no configuration of its own: -```java +[source,java] +---- public class Base64SecretKeysHandler implements SecretKeysHandler { @Override public String decode(final String secret) { @@ -29,25 +32,29 @@ public class Base64SecretKeysHandler implements SecretKeysHandler { return "base64"; } } -``` +---- -```title="META-INF/services/io.smallrye.config.SecretKeysHandler" +.META-INF/services/io.smallrye.config.SecretKeysHandler + +.... org.acme.config.Base64SecretKeysHandler -``` +.... A secret value encoded with the `base64` handler can then be expressed as: -```properties +[source,properties] +---- my.secret=${base64::SGVsbG8gV29ybGQ=} -``` +---- -### `SecretKeysHandlerFactory` +=== `SecretKeysHandlerFactory` When a handler requires configuration from other config sources (for example, a key or a credential read from the config), use `SecretKeysHandlerFactory` instead. The factory receives a `ConfigSourceContext` that provides access to all config sources initialized before the factory runs: -```java +[source,java] +---- public class VaultSecretKeysHandlerFactory implements SecretKeysHandlerFactory { @Override public SecretKeysHandler getSecretKeysHandler(final ConfigSourceContext context) { @@ -60,24 +67,27 @@ public class VaultSecretKeysHandlerFactory implements SecretKeysHandlerFactory { return "vault"; } } -``` +---- -```properties title="META-INF/services/io.smallrye.config.SecretKeysHandlerFactory" +.META-INF/services/io.smallrye.config.SecretKeysHandlerFactory +[source,properties] +---- org.acme.config.VaultSecretKeysHandlerFactory -``` +---- -### `LazySecretKeysHandler` +=== `LazySecretKeysHandler` `SecretKeysHandlerFactory` initializes during the first phase of `SmallRyeConfig` bootstrap, alongside regular `ConfigSource` and `ConfigSourceProvider` registrations. This means that config values produced by a -`ConfigSourceFactory` are **not** yet available when the factory's `getSecretKeysHandler` is called. +`ConfigSourceFactory` are *not* yet available when the factory's `getSecretKeysHandler` is called. For handlers that depend on sources provided by a `ConfigSourceFactory`, wrap an inner `SecretKeysHandlerFactory` in a `SecretKeysHandlerFactory.LazySecretKeysHandler`. The inner factory's `getSecretKeysHandler` is only invoked the first time a value actually needs to be decoded, by which point all sources — including those from `ConfigSourceFactory` — are fully initialized: -```java +[source,java] +---- public class VaultSecretKeysHandlerFactory implements SecretKeysHandlerFactory { @Override public SecretKeysHandler getSecretKeysHandler(final ConfigSourceContext context) { @@ -101,100 +111,122 @@ public class VaultSecretKeysHandlerFactory implements SecretKeysHandlerFactory { return "vault"; } } -``` +---- + +[WARNING] +==== + +The inner factory wrapped by `LazySecretKeysHandler` is what defers initialization. Do not call +`context.getValue` in the outer `getSecretKeysHandler`; only the inner factory's `getSecretKeysHandler` (invoked lazily) may resolve configuration values. -!!! warning +==== - The inner factory wrapped by `LazySecretKeysHandler` is what defers initialization. Do not call - `context.getValue` in the outer `getSecretKeysHandler`; only the inner factory's `getSecretKeysHandler` (invoked lazily) may resolve configuration values. +[CAUTION] +==== -!!!danger +It is not possible to mix Secret Keys Expressions with Property Expressions. - It is not possible to mix Secret Keys Expressions with Property Expressions. +==== -### Crypto +=== Crypto -The `smallrye-config-crypto` artifact contains a few out-of-the-box `SecretKeysHandler`s ready for use. It requires +The `smallrye-config-crypto` artifact contains a few out-of-the-box `SecretKeysHandler`s ready for use. It requires the following dependency: -```xml +[source,xml,subs="attributes+"] +---- io.smallrye.config smallrye-config-crypto - {{attributes['version']}} + {project-version} -``` +---- + +==== AES/GCM/NoPadding `$++{++aes-gcm-nopadding::...}` + +* The encoding length is 128. +* The secret and the encryption key (without padding) must be base 64 encoded. -#### AES/GCM/NoPadding `${aes-gcm-nopadding::...}` +[NOTE] +==== -- The encoding length is 128. -- The secret and the encryption key (without padding) must be base 64 encoded. +.application.properties +[source,properties] +---- +smallrye.config.secret-handler.aes-gcm-nopadding.encryption-key=DDne5obnfH1RSeTg71xSZg -!!! example +my.secret=${aes-gcm-nopadding::DLTb_9zxThxeT5iAQqswEl5Dn1ju4FdM9hIyVip35t5V} +---- - ```properties title="application.properties" - smallrye.config.secret-handler.aes-gcm-nopadding.encryption-key=DDne5obnfH1RSeTg71xSZg +The `$++{++aes-gcm-nopadding::...}` `SecretKeyHandler` requires +`smallrye.config.secret-handler.aes-gcm-nopadding.encryption-key` configuration to state the encryption key to be +used by the `aes-gcm-nopaddin` handler. - my.secret=${aes-gcm-nopadding::DLTb_9zxThxeT5iAQqswEl5Dn1ju4FdM9hIyVip35t5V} - ``` +A lookup to `my.secret` will use the `SecretKeysHandler` name `aes-gcm-nopadding` to decode the value +`DJNrZ6LfpupFv6QbXyXhvzD8eVDnDa++_++kTliQBpuzTobDZxlg`. - The `${aes-gcm-nopadding::...}` `SecretKeyHandler` requires - `smallrye.config.secret-handler.aes-gcm-nopadding.encryption-key` configuration to state the encryption key to be - used by the `aes-gcm-nopaddin` handler. +==== - A lookup to `my.secret` will use the `SecretKeysHandler` name `aes-gcm-nopadding` to decode the value - `DJNrZ6LfpupFv6QbXyXhvzD8eVDnDa_kTliQBpuzTobDZxlg`. +[NOTE] +==== -!!! info +It is possible to generate the encrypted secret with the following http://jbang.dev/[JBang] script: - It is possible to generate the encrypted secret with the following [JBang](http://jbang.dev/) script: +[source,shell] +---- +jbang https://raw.githubusercontent.com/smallrye/smallrye-config/main/documentation/src/main/asciidoc/config/secret-handlers/encryptor.java -s= -k= +---- - ```shell - jbang https://raw.githubusercontent.com/smallrye/smallrye-config/main/documentation/src/main/docs/config/secret-handlers/encryptor.java -s= -k=` - ``` +==== -##### Configuration +===== Configuration -| Configuration Property | Type | Default | -|----------------------------------------------------------------------------------------------------------------------------------------------------------------------------|-----------|-----------| -| `smallrye.config.secret-handler.aes-gcm-nopadding.encryption-key`
The encryption key to use to decode secrets encoded by the `AES/GCM/NoPadding` algorithm. | String | | -| `"smallrye.config.secret-handler.aes-gcm-nopadding.encryption-key-decode"`
Decode the encryption key in Base64, if the plain text key was used to encrypt the secret. | boolean | false | +[width="100%",cols="90%,5%,5%",options="header",] +|=== +|Configuration Property |Type |Default +|`smallrye.config.secret-handler.aes-gcm-nopadding.encryption-key` + +The encryption key to use to decode secrets encoded by the `AES/GCM/NoPadding` algorithm. |String | +|`"smallrye.config.secret-handler.aes-gcm-nopadding.encryption-key-decode"` + +Decode the encryption key in Base64, if the plain text key was used to encrypt the secret. |boolean |false +|=== -## Secret Keys Names +== Secret Keys Names -When configuration properties contain passwords or other kinds of secrets, Smallrye Config can hide them to prevent +When configuration properties contain passwords or other kinds of secrets, Smallrye Config can hide them to prevent accidental exposure of such values. -**This is no way a replacement for securing secrets.** Proper security mechanisms must still be used to secure -secrets. However, there is still the fundamental problem that passwords and secrets are generally encoded simply as +*This is no way a replacement for securing secrets.* Proper security mechanisms must still be used to secure +secrets. However, there is still the fundamental problem that passwords and secrets are generally encoded simply as strings. Secret Keys provides a way to "lock" the configuration so that secrets do not appear unless explicitly enabled. -To mark specific keys as secrets, register an instance of `io.smallrye.config.SecretKeysConfigSourceInterceptor` by +To mark specific keys as secrets, register an instance of `io.smallrye.config.SecretKeysConfigSourceInterceptor` by using the interceptor factory as follows: -```java +[source,java] +---- public class SecretKeysConfigInterceptorFactory implements ConfigSourceInterceptorFactory { @Override public ConfigSourceInterceptor getInterceptor(ConfigSourceInterceptorContext context) { return new SecretKeysConfigSourceInterceptor(Set.of("secret")); } } -``` +---- -Register the factory so that it can be found at runtime by creating a -`META-INF/services/io.smallrye.config.ConfigSourceInterceptorFactory` file that contains the fully qualified name of +Register the factory so that it can be found at runtime by creating a +`META-INF/services/io.smallrye.config.ConfigSourceInterceptorFactory` file that contains the fully qualified name of this factory class. From this point forward, every lookup to the configuration name `secret` will throw a `SecurityException`. -Access the Secret Keys using the APIs `io.smallrye.config.SecretKeys#doUnlocked(java.lang.Runnable)` -and `io.smallrye.config.SecretKeys#doUnlocked(java.util.function.Supplier)`. +Access the Secret Keys using the APIs `io.smallrye.config.SecretKeys#doUnlocked(java.lang.Runnable)` +and `io.smallrye.config.SecretKeys#doUnlocked(java.util.function.Supplier++<++T++>++)`. -```java +[source,java] +---- String secretValue = SecretKeys.doUnlocked(() -> { config.getValue("secret", String.class); }); -``` +---- -Secret Keys are only unlocked in the context of `doUnlocked`. Once the execution completes, the secrets become locked +Secret Keys are only unlocked in the context of `doUnlocked`. Once the execution completes, the secrets become locked again. diff --git a/documentation/src/main/docs/converters/custom.md b/documentation/src/main/asciidoc/converters/custom.adoc similarity index 69% rename from documentation/src/main/docs/converters/custom.md rename to documentation/src/main/asciidoc/converters/custom.adoc index 70b78a4e1..e95f13ad9 100644 --- a/documentation/src/main/docs/converters/custom.md +++ b/documentation/src/main/asciidoc/converters/custom.adoc @@ -1,13 +1,16 @@ -# Custom `Converter` += Custom `Converter` +:version-root: ../ +include::{version-root}_attributes.adoc[] -It is possible to create a custom `Converter` type as specified in -[MicroProfile Config](https://github.com/eclipse/microprofile-config/). +It is possible to create a custom `Converter` type as specified in +https://github.com/eclipse/microprofile-config/[MicroProfile Config]. -A custom `Converter` requires an implementation of `org.eclipse.microprofile.config.spi.Converter`. Each implementation -requires registration via the `ServiceLoader` mechanism in the +A custom `Converter` requires an implementation of `org.eclipse.microprofile.config.spi.Converter`. Each implementation +requires registration via the `ServiceLoader` mechanism in the `META-INF/services/org.eclipse.microprofile.config.spi.Converter` file. Consider: -```java +[source,java] +---- package org.acme.config; public class CustomValue { @@ -22,11 +25,12 @@ public class CustomValue { return number; } } -``` +---- The corresponding converter can look like: -```java +[source,java] +---- package org.acme.config; import org.eclipse.microprofile.config.spi.Converter; @@ -38,31 +42,38 @@ public class CustomValueConverter implements Converter { return new CustomValue(Integer.parseInt(value)); } } -``` +---- And registration in: -```properties title="META-INF/services/org.eclipse.microprofile.config.spi.Converter" +.META-INF/services/org.eclipse.microprofile.config.spi.Converter +[source,properties] +---- org.acme.config.CustomValueConverter -``` +---- -!!! warning +[WARNING] +==== - The custom `Converter` class must be `public`, must have a `public` constructor with no arguments, and must not be - abstract. +The custom `Converter` class must be `public`, must have a `public` constructor with no arguments, and must not be +abstract. + +==== The `CustomValueConverter` converts the configuration value to the `CustomValue` type automatically. -```java +[source,java] +---- Config config = Config.getOrCreate(); CustomValue value = config.getValue("custom.value", CustomValue.class); -``` +---- -The `jakarta.annotation.Priority` annotation overrides the `Converter` priority and change converters precedence to fine -tune the execution order. By default, if no `@Priority` is specified by the `Converter`, the converter is registered +The `jakarta.annotation.Priority` annotation overrides the `Converter` priority and change converters precedence to fine +tune the execution order. By default, if no `@Priority` is specified by the `Converter`, the converter is registered with a priority of `100`. Consider: -```java +[source,java] +---- package org.acme.config; import jakarta.annotation.Priority; @@ -83,8 +94,8 @@ public class SecretConverter implements Converter { return new CustomValue(secretNumber); } } -``` +---- -Two `Converter`s, (`CustomValueConverter` and `SecretConverter`) can convert the same type `CustomValue`. Since -`SecretConverter` has a priority of `150`, it will be used instead of a `CustomValueConverter` which has a default +Two `Converter`s, (`CustomValueConverter` and `SecretConverter`) can convert the same type `CustomValue`. Since +`SecretConverter` has a priority of `150`, it will be used instead of a `CustomValueConverter` which has a default priority of `100` (no annotation). diff --git a/documentation/src/main/docs/extensions/fallback.md b/documentation/src/main/asciidoc/extensions/fallback.adoc similarity index 59% rename from documentation/src/main/docs/extensions/fallback.md rename to documentation/src/main/asciidoc/extensions/fallback.adoc index b5d35a652..05af7251d 100644 --- a/documentation/src/main/docs/extensions/fallback.md +++ b/documentation/src/main/asciidoc/extensions/fallback.adoc @@ -1,13 +1,16 @@ -# Fallback += Fallback +:version-root: ../ +include::{version-root}_attributes.adoc[] -The `io.smallrye.config.FallbackConfigSourceInterceptor` allows to fall back to another configuration name, by +The `io.smallrye.config.FallbackConfigSourceInterceptor` allows to fall back to another configuration name, by providing a transformation function or just a simple key value map. When a configuration name does not exist, there might be another configuration name that the config can fall back to provide the same expected behavior. The fallback function is only applied if the original resolved configuration name is not found and resolved to the fallback name. -```java +[source,java] +---- package org.acme.config; import io.smallrye.config.FallbackConfigSourceInterceptor; @@ -19,29 +22,38 @@ public class MicroProfileConfigFallbackInterceptor extends FallbackConfigSourceI name); } } -``` +---- And registration in: -```properties title="META-INF/services/io.smallrye.config.ConfigSourceInterceptor" +.META-INF/services/io.smallrye.config.ConfigSourceInterceptor +[source,properties] +---- org.acme.config.MicroProfileConfigFallbackInterceptor -``` +---- The `MicroProfileConfigFallbackInterceptor` can fallback configuration names in the `mp.config` namespace to the `smallrye.config` namespace. -!!! example +[NOTE] +==== - ```properties title="application.properties" - mp.config.profile=test - smallrye.config.profile=prod - ``` - - A lookup to `mp.config.profile` returns the value `test`. +.application.properties +[source,properties] +---- +mp.config.profile=test +smallrye.config.profile=prod +---- - ```properties title="application.properties" - smallrye.config.profile=prod - ``` +A lookup to `mp.config.profile` returns the value `test`. - A lookup to `mp.config.profile` returns the value `prod`. The config is not able to find a value for - `mp.config.profile`, so the interceptor fallbacks and lookups the value of `smallrye.config.profile`. +.application.properties +[source,properties] +---- +smallrye.config.profile=prod +---- + +A lookup to `mp.config.profile` returns the value `prod`. The config is not able to find a value for +`mp.config.profile`, so the interceptor fallbacks and lookups the value of `smallrye.config.profile`. + +==== diff --git a/documentation/src/main/docs/extensions/interceptors.md b/documentation/src/main/asciidoc/extensions/interceptors.adoc similarity index 73% rename from documentation/src/main/docs/extensions/interceptors.md rename to documentation/src/main/asciidoc/extensions/interceptors.adoc index 3e6aa8423..8811bf0dc 100644 --- a/documentation/src/main/docs/extensions/interceptors.md +++ b/documentation/src/main/asciidoc/extensions/interceptors.adoc @@ -1,35 +1,41 @@ -# Interceptors += Interceptors +:version-root: ../ +include::{version-root}_attributes.adoc[] -SmallRye Config provides an interceptor chain that hooks into the configuration values resolution. This is useful to -implement features like [Profiles](../config/profiles.md) , [Property Expressions](../config/expressions.md), or just +SmallRye Config provides an interceptor chain that hooks into the configuration values resolution. This is useful to +implement features like xref:config/profiles.adoc[Profiles] , xref:config/expressions.adoc[Property Expressions], or just logging to find out where the config value was loaded from. -An interceptor can be created by implementing the -[ConfigSourceInterceptor](https://github.com/smallrye/smallrye-config/blob/main/implementation/src/main/java/io/smallrye/config/ConfigSourceInterceptor.java) +An interceptor can be created by implementing the +https://github.com/smallrye/smallrye-config/blob/main/implementation/src/main/java/io/smallrye/config/ConfigSourceInterceptor.java[ConfigSourceInterceptor] interface. -An interceptor requires an implementation of `io.smallrye.config.ConfigSourceInterceptor`. Each implementation requires -registration via the `ServiceLoader` mechanism in the `META-INF/services/io.smallrye.config.ConfigSourceInterceptor` -file. Alternatively, interceptors may be registered via the Programmatic API in +An interceptor requires an implementation of `io.smallrye.config.ConfigSourceInterceptor`. Each implementation requires +registration via the `ServiceLoader` mechanism in the `META-INF/services/io.smallrye.config.ConfigSourceInterceptor` +file. Alternatively, interceptors may be registered via the Programmatic API in `SmallRyeConfigBuilder#withInterceptors`. `io.smallrye.config.ConfigSourceInterceptor` exposes two interception points: -- `ConfigValue getValue(ConfigSourceInterceptorContext context, String name)` — intercepts the resolution of a - configuration value by name. -- `Iterator iterateNames(ConfigSourceInterceptorContext context)` — intercepts the iteration of all known - configuration property names. +* `ConfigValue getValue(ConfigSourceInterceptorContext context, String name)` — intercepts the resolution of a +configuration value by name. +* `Iterator++<++String++>++ iterateNames(ConfigSourceInterceptorContext context)` — intercepts the iteration of all known +configuration property names. The `ConfigSourceInterceptorContext` is used to proceed with the interceptor chain. Calling `context.proceed(name)` continues to the next interceptor in the chain. The chain can be short-circuited by returning a custom instance of -`io.smallrye.config.ConfigValue` from `getValue`, or a custom `Iterator` from `iterateNames`. The `ConfigValue` +`io.smallrye.config.ConfigValue` from `getValue`, or a custom `Iterator++<++String++>++` from `iterateNames`. The `ConfigValue` objects hold information about the key name, value, config source origin and ordinal. -!!! info +[NOTE] +==== - The interceptor chain is applied before any conversion is performed on the configuration value. +The interceptor chain is applied before any conversion is performed on the configuration value. -```java +==== + +[source,java] +---- package org.acme.config; import jakarta.annotation.Priority; @@ -50,18 +56,20 @@ public class LoggingConfigSourceInterceptor implements ConfigSourceInterceptor { return configValue; } } -``` +---- And registration in: -```properties title="META-INF/services/io.smallrye.config.ConfigSourceInterceptor" +.META-INF/services/io.smallrye.config.ConfigSourceInterceptor +[source,properties] +---- org.acme.config.LoggingConfigSourceInterceptor -``` +---- The `LoggingConfigSourceInterceptor` logs each configuration name lookup. The logged information includes the config name and value, and (from the resolved `ConfigValue`) the config source origin and location if they exist. -## `iterateNames` +== `iterateNames` The `iterateNames` method intercepts the set of configuration property names visible to the rest of the chain. The default implementation simply delegates to `context.iterateNames()`. Override it to add, remove, or transform names. @@ -69,7 +77,8 @@ default implementation simply delegates to `context.iterateNames()`. Override it A common use case is hiding sensitive property names from enumeration while still allowing their values to be retrieved: -```java +[source,java] +---- package org.acme.config; import java.util.Iterator; @@ -105,27 +114,31 @@ public class HidingConfigSourceInterceptor implements ConfigSourceInterceptor { }; } } -``` +---- + +[NOTE] +==== -!!! info +`iterateNames` affects the results of `Config#getPropertyNames()` and is used by Config Mappings to discover +`Map` keys. Interceptors that hide names will also prevent those names from being mapped into `Map` entries. - `iterateNames` affects the results of `Config#getPropertyNames()` and is used by Config Mappings to discover - `Map` keys. Interceptors that hide names will also prevent those names from being mapped into `Map` entries. +==== -## `ConfigSourceInterceptorContext` +== `ConfigSourceInterceptorContext` `ConfigSourceInterceptorContext` provides two ways to continue the chain: -- `proceed(String name)` — passes the lookup to the **next** interceptor in the chain. This is the standard method - to use in most interceptors. -- `restart(String name)` — re-invokes the **first** interceptor in the chain from the beginning. This is intended for - relocating or compatibility interceptors that resolve a new name and need the full chain to re-evaluate it, including - profile expansion and expression resolution. Passing the original name to `restart` can cause an infinite loop, so - care must be taken. +* `proceed(String name)` — passes the lookup to the *next* interceptor in the chain. This is the standard method +to use in most interceptors. +* `restart(String name)` — re-invokes the *first* interceptor in the chain from the beginning. This is intended for +relocating or compatibility interceptors that resolve a new name and need the full chain to re-evaluate it, including +profile expansion and expression resolution. Passing the original name to `restart` can cause an infinite loop, so +care must be taken. Example — an interceptor that resolves an alias name and restarts the full chain for the resolved name: -```java +[source,java] +---- package org.acme.config; import jakarta.annotation.Priority; @@ -147,7 +160,7 @@ public class AliasConfigSourceInterceptor implements ConfigSourceInterceptor { return context.proceed(name); } } -``` +---- Interceptors may also be created with an implementation of `io.smallrye.config.ConfigSourceInterceptorFactory`. Each implementation requires registration via the `ServiceLoader` mechanism in the diff --git a/documentation/src/main/docs/extensions/logging.md b/documentation/src/main/asciidoc/extensions/logging.adoc similarity index 74% rename from documentation/src/main/docs/extensions/logging.md rename to documentation/src/main/asciidoc/extensions/logging.adoc index 0a606a236..3a42e6573 100644 --- a/documentation/src/main/docs/extensions/logging.md +++ b/documentation/src/main/asciidoc/extensions/logging.adoc @@ -1,11 +1,15 @@ -## LoggingConfigSourceInterceptor += Logging +:version-root: ../ +include::{version-root}_attributes.adoc[] -The `io.smallrye.config.LoggingConfigSourceInterceptor` logs lookups of configuration names in the provided logging +== LoggingConfigSourceInterceptor + +The `io.smallrye.config.LoggingConfigSourceInterceptor` logs lookups of configuration names in the provided logging platform. The log information includes config name and value, the config source origin and location if it exists. The log is done as `debug`, so the debug threshold must be set to `debug` for the `io.smallrye.config` appender to display the logs. This requires registration via the `ServiceLoader` mechanism in the -`META-INF/services/io.smallrye.config.ConfigSourceInterceptorFactory` file of the +`META-INF/services/io.smallrye.config.ConfigSourceInterceptorFactory` file of the `io.smallrye.config.LoggingConfigSourceInterceptor` interceptor. diff --git a/documentation/src/main/docs/extensions/relocate.md b/documentation/src/main/asciidoc/extensions/relocate.adoc similarity index 64% rename from documentation/src/main/docs/extensions/relocate.md rename to documentation/src/main/asciidoc/extensions/relocate.adoc index 085230e75..e33ee4f6a 100644 --- a/documentation/src/main/docs/extensions/relocate.md +++ b/documentation/src/main/asciidoc/extensions/relocate.adoc @@ -1,13 +1,16 @@ -# Relocate += Relocate +:version-root: ../ +include::{version-root}_attributes.adoc[] -The `io.smallrye.config.RelocateConfigSourceInterceptor` allows to relocate a configuration name to another name, by +The `io.smallrye.config.RelocateConfigSourceInterceptor` allows to relocate a configuration name to another name, by providing a transformation function or just a simple key value map. When a configuration key is renamed, lookup needs to happen on the new name, but also on the old name if the config sources are not updated yet. The relocation function gives priority to the new resolved configuration name or resolves to the old name if no value is found under the new relocation name. -```java +[source,java] +---- package org.acme.config; import io.smallrye.config.RelocateConfigSourceInterceptor; @@ -19,23 +22,30 @@ public class MicroProfileConfigRelocateInterceptor extends RelocateConfigSourceI name); } } -``` +---- And registration in: -```properties title="META-INF/services/io.smallrye.config.ConfigSourceInterceptor" +.META-INF/services/io.smallrye.config.ConfigSourceInterceptor +[source,properties] +---- org.acme.config.MicroProfileConfigRelocateInterceptor -``` +---- The `MicroProfileConfigRelocateInterceptor` can relocate configuration names in the `mp.config` namespace to the `smallrye.config` namespace. -!!! example +[NOTE] +==== - ```properties title="application.properties" - mp.config.profile=test - smallrye.config.profile=prod - ``` - - A lookup to `mp.config.profile` returns the value `prod`. The config finds a valid value in the relocated name - `smallrye.config.profile`, so the interceptor will use this value instead of the one in `mp.config.profile`. +.application.properties +[source,properties] +---- +mp.config.profile=test +smallrye.config.profile=prod +---- + +A lookup to `mp.config.profile` returns the value `prod`. The config finds a valid value in the relocated name +`smallrye.config.profile`, so the interceptor will use this value instead of the one in `mp.config.profile`. + +==== diff --git a/documentation/src/main/asciidoc/index.adoc b/documentation/src/main/asciidoc/index.adoc new file mode 100644 index 000000000..b5469fe5a --- /dev/null +++ b/documentation/src/main/asciidoc/index.adoc @@ -0,0 +1,97 @@ += SmallRye Config +include::_attributes.adoc[] + +*SmallRye Config* is a library that provides a way to configure applications, frameworks and containers. It is used +in applications servers like https://wildfly.org/[WildFly], https://openliberty.io[Open Liberty] and +https://tomee.apache.org[TomEE] or frameworks like https://quarkus.io[Quarkus]. It can also be used completely +standalone in any Java application, which makes it a very flexible library. + +It follows the https://github.com/eclipse/microprofile-config/[MicroProfile Config] specification to provide +the initial config foundations and expands with it own concepts to cover a wide range of use cases observed in the +configuration space. + +== Use SmallRye Config in a Java application + +Add the _dependency_ to your project using your preferred build tool: + +[.tabs] +==== + +Maven:: ++ +-- + +[source,xml,subs="attributes+"] +---- + + io.smallrye.config + smallrye-config + {project-version} + +---- + +-- + +Gradle (Groovy):: ++ +-- + +[source,groovy,subs="attributes+"] +---- +implementation 'io.smallrye.config:smallrye-config:{project-version}' +---- + +-- + +Gradle (Kotlin):: ++ +-- + +[source,kotlin,subs="attributes+"] +---- +implementation("io.smallrye.config:smallrye-config:{project-version}") +---- + +-- + +JBang:: ++ +-- + +[source,java,subs="attributes+"] +---- +//DEPS io.smallrye.config:smallrye-config:{project-version} +---- + +-- + +==== + +And retrieve a `SmallRyeConfig` instance with: + +[source,java] +---- +Config config = io.smallrye.config.Config.getOrCreate(); +---- + +[NOTE] +==== + +The `SmallRyeConfig` instance will be created and registered to the context class loader if no such configuration +is already created and registered. + +==== + +Or build your own: + +[source,java] +---- +SmallRyeConfig config = new SmallRyeConfigBuilder().build(); +---- + +[NOTE] +==== + +`io.smallrye.config.Config` is the entry point to all the config capabilities provided by SmallRye Config. + +==== diff --git a/documentation/src/main/docs/assets/extra.css b/documentation/src/main/docs/assets/extra.css deleted file mode 100644 index 9f8196c18..000000000 --- a/documentation/src/main/docs/assets/extra.css +++ /dev/null @@ -1,9 +0,0 @@ -/* Add stuff here if required */ - -.md-typeset__table { - min-width: 100%; -} - -.md-typeset table:not([class]) { - display: table; -} diff --git a/documentation/src/main/docs/assets/favicon.ico b/documentation/src/main/docs/assets/favicon.ico deleted file mode 100644 index c03e7b9ab..000000000 Binary files a/documentation/src/main/docs/assets/favicon.ico and /dev/null differ diff --git a/documentation/src/main/docs/assets/smallrye-icon.svg b/documentation/src/main/docs/assets/smallrye-icon.svg deleted file mode 100644 index c10b011e0..000000000 --- a/documentation/src/main/docs/assets/smallrye-icon.svg +++ /dev/null @@ -1,21 +0,0 @@ - - - - - SmallRye Icon - - - - - - - - - diff --git a/documentation/src/main/docs/config-sources/filesystem.md b/documentation/src/main/docs/config-sources/filesystem.md deleted file mode 100644 index 0332ccafe..000000000 --- a/documentation/src/main/docs/config-sources/filesystem.md +++ /dev/null @@ -1,43 +0,0 @@ -# FileSystem Config Source - -This Config Source loads configuration values for each file found in a directory. Each file corresponds to a single -property, where the file name is the configuration property name and the file content the configuration value. - -For instance, if a directory structure looks like: - - foo/ - |__num.max - |__num.size - -The `FileSystem` Config Source will provide 2 properties: - -- num.max -- num.size - -!!! warning - - Nested directories are not supported. - -This Config Source can be used to read configuration from -[Kubernetes ConfigMap](https://kubernetes.io/docs/tasks/configure-pod-container/configure-pod-configmap). Check the -[Kubernetes ConfigMap ConfigSource Example](https://github.com/smallrye/smallrye-config/blob/main/examples/configmap/README.adoc). - -The same mapping rules as defined for environment variables are applied, so the `FileSystem` Config Source will search -for a given property name `num.max`: - -- Exact match (`num.max`) -- Replace each character that is neither alphanumeric nor \_ with \_ (`num_max`) -- Replace each character that is neither alphanumeric nor \_ with \_; then convert the name to upper case (`NUM_MAX`) - -The following dependency is required in the classpath to use the `FileSystem` Config Source: - -```xml - - io.smallrye.config - smallrye-config-source-file-system - {{attributes['version']}} - -``` - -The configuration property `smallrye.config.source.file.locations` sets the directory paths to look up the files. It -accepts multiple locations separated by a comma and each must represent a valid URI to a directory. diff --git a/documentation/src/main/docs/config-sources/hocon.md b/documentation/src/main/docs/config-sources/hocon.md deleted file mode 100644 index d478e43e3..000000000 --- a/documentation/src/main/docs/config-sources/hocon.md +++ /dev/null @@ -1,39 +0,0 @@ -# HOCON Config Source - -This Config Source allows to use the [HOCON](https://github.com/lightbend/config/blob/main/HOCON.md) file format to -load configuration values. The HOCON Config Source loads the -configuration from the file `META-INF/microprofile-config.conf`. It has a lower ordinal (`50`) than the -`microprofile-config.properties`. - -The following dependency is required in the classpath to use the HOCON Config Source: - -```xml - - io.smallrye.config - smallrye-config-source-hocon - {{attributes['version']}} - -``` - -Expressions defined as `${value}` (unquoted) are resolved internally by the HOCON Config Source as described in the -[HOCON Substitutions](https://github.com/lightbend/config/blob/main/HOCON.md#substitutions) documentation. Quoted -Expressions defined as `"${value}"` are resolved by [SmallRye Config Property Expressions](../config/expressions.md). - -Consider: - -**hocon.conf** -```conf -{ - foo: "bar", - hocon: ${foo}, - config: "${foo}" -} -``` - -**application.properties** -```properties -config_ordinal=1000 -foo=baz -``` - -The value of `hocon` is `bar` and the value of `config` is `baz` (if the properties source has a higher ordinal). diff --git a/documentation/src/main/docs/config-sources/json.md b/documentation/src/main/docs/config-sources/json.md deleted file mode 100644 index 53a0e88e5..000000000 --- a/documentation/src/main/docs/config-sources/json.md +++ /dev/null @@ -1,4 +0,0 @@ -# JSON Config Source - -The [YAML Config Source](yaml.md) also accepts the JSON format as its contents. The configuration file -`META-INF/microprofile-config.yaml`, still requires to use the `yaml` extension. diff --git a/documentation/src/main/docs/config-sources/keystore.md b/documentation/src/main/docs/config-sources/keystore.md deleted file mode 100644 index 62c9f207e..000000000 --- a/documentation/src/main/docs/config-sources/keystore.md +++ /dev/null @@ -1,53 +0,0 @@ -# KeyStore Config Source - -This Config Source allows to use a Java `KeyStore` to load configuration values. It uses an ordinal of `100`. - -The following dependency is required in the classpath to use the KeyStore Config Source: - -```xml - - io.smallrye.config - smallrye-config-source-keystore - {{attributes['version']}} - -``` - -## Create a KeyStore - -The following command creates a simple KeyStore - -```bash -keytool -importpass -alias my.secret -keystore keystore -storepass secret -storetype PKCS12 -v -``` - -The `-alias my.secret` stores the configuration property name `my.secret` in the KeyStore. The command will -interactively ask for the value to be stored in the KeyStore. - -## Read the KeyStore - -The KeyStore Config Source supports reading multiple keystore files: - -```properties -smallrye.config.source.keystore.one.path=keystore-one -smallrye.config.source.keystore.one.password=password - -smallrye.config.source.keystore.two.path=keystore-two -smallrye.config.source.keystore.two.password=password -``` - -The names are arbitrary and can be any name. The name `one` and `two` are used to distinguish both KeyStores. - -If a stored configuration property requires a [Secret Handler](../config/secret-keys.md) to decode a value, set -the handler name with `smallrye.config.source.keystore."name".handler`. - -## Configuration - -| Configuration Property | Type | Default | -|---------------------------------------------------------------------------------------------------------------------|--- |----| -| `smallrye.config.source.keystore."name".path`
The KeyStore path. | String | | -| `smallrye.config.source.keystore."name".password`
The KeyStore password. | String | | -| `smallrye.config.source.keystore."name".type`
The KeyStore type. | String | `PKCS12` | -| `smallrye.config.source.keystore."name".handler`
An Optional secret keys handler. | String | | -| `smallrye.config.source.keystore."name".aliases."key".name`
An Optional aliases key name. | String | | -| `smallrye.config.source.keystore."name".aliases."key".password`
An Optional aliases key password. | String | | -| `smallrye.config.source.keystore."name".aliases."key".handler`
An Optional aliases key secret keys handler. | String | | diff --git a/documentation/src/main/docs/config-sources/toml.md b/documentation/src/main/docs/config-sources/toml.md deleted file mode 100644 index 7bf9b5a01..000000000 --- a/documentation/src/main/docs/config-sources/toml.md +++ /dev/null @@ -1,18 +0,0 @@ -# TOML Config Source - -This Config Source allows to use a [TOML](https://toml.io) file to load configuration values. The TOML Config Source -loads the configuration from the following files: - -1. (`265`) `application.toml` in `config` folder, located in the current working directory -2. (`255`) `application.toml` in the classpath -3. (`110`) MicroProfile Config configuration file `META-INF/microprofile-config.toml` in the classpath - -The following dependency is required in the classpath to use the TOML Config Source: - -```xml - - io.smallrye.config - smallrye-config-source-toml - {{attributes['version']}} - -``` diff --git a/documentation/src/main/docs/config-sources/yaml.md b/documentation/src/main/docs/config-sources/yaml.md deleted file mode 100644 index cc4db949f..000000000 --- a/documentation/src/main/docs/config-sources/yaml.md +++ /dev/null @@ -1,17 +0,0 @@ -# YAML Config Source - -This Config Source allows to use a `yaml` file to load configuration values. The YAML Config Source loads the configuration from the following files: - -1. (`265`) `application.yaml|yml` in `config` folder, located in the current working directory -2. (`255`) `application.yaml|yml` in the classpath -3. (`110`) MicroProfile Config configuration file `META-INF/microprofile-config.yaml|yml` in the classpath - -The following dependency is required in the classpath to use the YAML Config Source: - -```xml - - io.smallrye.config - smallrye-config-source-yaml - {{attributes['version']}} - -``` diff --git a/documentation/src/main/docs/config/configuration.md b/documentation/src/main/docs/config/configuration.md deleted file mode 100644 index d07026976..000000000 --- a/documentation/src/main/docs/config/configuration.md +++ /dev/null @@ -1,10 +0,0 @@ -# Configuration Reference - -| Configuration Property | Type | Default | -|------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|------------|-----------| -| `smallrye.config.profile`
The main [Profile](profiles.md) to activate. | String[] | | -| `smallrye.config.profile.parent`
The parent [Profile](profiles.md#parent-profile) to activate. | String | | -| `smallrye.config.locations`
[Additional config locations](../config-sources/locations.md) to be loaded with the Config. The configuration supports multiple locations separated by a comma and each must represent a valid `java.net.URI`. | URI[] | | -| `smallrye.config.mapping.validate-unknown`
[Validates](mappings.md#retrieval) that a `@ConfigMapping` maps every available configuration name contained in the mapping prefix. | boolean | true | -| `smallrye.config.secret-handlers`
The names of the secret handlers to be loaded. A value of `all` loads all available secret handlers and a value of `none` skips the load. | String[] | all | -| `smallrye.config.log.values`
Enable logging of configuration values lookup in DEBUG log level. | boolean | false | diff --git a/documentation/src/main/docs/config/environment-variables.md b/documentation/src/main/docs/config/environment-variables.md deleted file mode 100644 index 2cfc073b2..000000000 --- a/documentation/src/main/docs/config/environment-variables.md +++ /dev/null @@ -1,63 +0,0 @@ -# Environment Variables - -Environment Variable names follow the conversion rules specified by [MicroProfile Config](https://github.com/eclipse/microprofile-config/blob/master/spec/src/main/asciidoc/configsources.asciidoc#default-configsources). - -SmallRye Config specifies additional conversion rules: - -- A property with double quotes `foo."bar".baz` or `foo.bar."baz"`, replace each character that is neither alphanumeric -nor `_` with `_`: `FOO__BAR__BAZ` or `FOO_BAR__BAZ_` ; -- A property with dashes `foo.bar-baz`, replace each character that is neither alphanumeric nor `_` - with `_`: `FOO_BAR_BAZ` -- An indexed property `foo.bar[0]` or `foo.bar[0].baz`, replace each character that is neither alphanumeric nor `_` - with `_`: `FOO_BAR_0_` or `FOO_BAR_0__BAZ`. - -!!! danger - - Environment Variables format cannot represent the entire spectrum of common property names. - -The lookup of configuration values from Environment Variables will always use the dotted format name. For -instance, the lookup of the Environment Variable `FOO_BAR` value, requires the property name `foo.bar`: - -```java -Config config = Config.getOrCreate(); -String value = config.getValue("foo.bar", String.class); -``` - -When SmallRyeConfig performs the lookup on the Environment Variables Config Source, it applies the conversion rules to -find the matching property name and retrieve the value. - -In some situations, looking up the exact property name is impossible. For instance, when SmallRye Config has to look up -a configuration that is part of a `Map`, and the property name contains a dynamic segment (a `Map` key). In this case, -SmallRye Config relies upon each source's list of property names. These must be converted back to their most likely -dotted format for Environment Variables. - -By default, the underscore `_` of an Environment Variable name always maps to a dot `.`. If the property name -contains a dash or some other special character, that property name can be specified in another Config -Source, with the expected dotted format. It will provide additional information to SmallRye Config to perform a -two-way conversion and match the property names. - -Consider: - -```console title=".env" -FOO_BAR_BAZ=VALUE -``` - -Will map to `foo.bar.baz` and value `value`. - -If `foo.bar-baz` is available in any source: - -```console title=".env" -FOO_BAR_BAZ=VALUE -``` - -```properties title="application.properties" -foo.bar-baz=default -``` - -Will map to `foo.bar-baz` and value `value`. - -!!! note - - The property name in dotted format needs to exist somewhere to provide this additional information. It can be set in a - low ordinal source, even without value. The Environment Variables source will override the value and map the correct - configuration name. diff --git a/documentation/src/main/docs/index.md b/documentation/src/main/docs/index.md deleted file mode 100644 index cc92301b6..000000000 --- a/documentation/src/main/docs/index.md +++ /dev/null @@ -1,69 +0,0 @@ ---- -hide: -- navigation -- toc ---- - -# SmallRye Config - -**SmallRye Config** is a library that provides a way to configure applications, frameworks and containers. It is used -in applications servers like [WildFly](https://wildfly.org/), [Open Liberty](https://openliberty.io) and -[TomEE](https://tomee.apache.org) or frameworks like [Quarkus](https://quarkus.io). It can also be used completely -standalone in any Java application, which makes it a very flexible library. - -It follows the [MicroProfile Config](https://github.com/eclipse/microprofile-config/) specification to provide -the initial config foundations and expands with it own concepts to cover a wide range of use cases observed in the -configuration space. - -## Use SmallRye Config in a Java application - -Add the _dependency_ to your project using your preferred build tool: - -=== "Maven" - - ```xml - - io.smallrye.config - smallrye-config - {{attributes['version']}} - - ``` - -=== "Gradle (Groovy)" - - ```groovy - implementation 'io.smallrye.config:smallrye-config:{{attributes['version']}}' - ``` - -=== "Gradle (Kotlin)" - - ```kotlin - implementation("io.smallrye.config:smallrye-config:{{attributes['version']}}") - ``` - -=== "JBang" - - ```java - //DEPS io.smallrye.config:smallrye-config:{{attributes['version']}} - ``` - -And retrieve a `SmallRyeConfig` instance with: - -```java -Config config = io.smallrye.config.Config.getOrCreate(); -``` - -!!! info - - The `SmallRyeConfig` instance will be created and registered to the context class loader if no such configuration - is already created and registered. - -Or build your own: - -```java -SmallRyeConfig config = new SmallRyeConfigBuilder().build(); -``` - -!!! info - - `io.smallrye.config.Config` is the entry point to all the config capabilities provided by SmallRye Config. diff --git a/documentation/src/main/macros/docissimo.py b/documentation/src/main/macros/docissimo.py deleted file mode 100644 index 4186c705b..000000000 --- a/documentation/src/main/macros/docissimo.py +++ /dev/null @@ -1,155 +0,0 @@ -""" -Ease documentation writing with mkdocs - -- load the content of the 'variables.yaml' file -- provide the {{insert(file, tag)} macro - -## Loading attributes - -This feature loads a yaml file (default is `docs/attributes.yaml`), and import the content into the environment. -For example, if the imported file contains: - -``` -attributes: - versions: - camel: 3.13.0 - spec: 2.0.1 - mutiny: 1.1.2 - project-version: '3.14.0-SNAPSHOT' - smallrye-config-version: '2.7.0' -``` - -You can access values using `{{ attributes.versions.camel}}` or `{{ attributes['project-version'] }}`. - -The loaded file is `docs/variables.yaml` by default. The location can be configured in the `mkdocs.yml` file with: - -``` -extra: - attributes_path: docs/my-attributes.yaml -``` - -## Partial file include - -This feature allows including part of a file. -For example, include the code from the `Foo.java` located between `` and `` - -```java linenums="1" -{{ insert('src/test/Foo.java', 'example') }} -``` - -The `Foo.java` file contain something like: - -``` -package test; - -public class Foo { - - // this is my snippet - public static void main(String[]args){ - System.out.println("yoohoo"); - } - // - -} -``` - -The file path is relative to the `docs` directory. -You can change the location using the `snippet_dir` attributes in the `mkdocs.yaml` file: - -``` -extra: - snippet_dir: docs/snippets/src -``` - -Then, insert your snippet using: - -```java linenums="1" -{{ insert('test/Foo.java', 'example') }} -``` -""" - -import math -import yaml -import textwrap -import os.path - - -def loadAttributes(env): - path = env.conf['docs_dir'] + "/attributes.yaml" - if 'attributes_path' in env.variables: - path = env.variables['attributes_path'] - - if os.path.exists(path): - file = open(path) - var = yaml.load(file, Loader=yaml.FullLoader) - file.close() - if var is not None: - env.variables['attributes'] = var['attributes'] - else: - print("Unable to import attributes - " + path + " does not exists") - -def define_env(env): - - loadAttributes(env) - - @env.macro - def insert(file, tag = None): - root = env.conf['docs_dir'] - if 'snippet_dir' in env.variables: - root = env.variables['snippet_dir'] - - f = open(root + "/" + file) - - if tag is None: - text = f.read() - f.close() - return textwrap.dedent(text) - - inRecordingMode = False - c = "" - for line in f: - if not inRecordingMode: - if "<" + tag + ">" in line: - inRecordingMode = True - elif "" in line: - inRecordingMode = False - else: - c += line - - f.close() - if not c: - raise Exception(f"Unable to find tag '{tag}' in '{file}'") - - c = textwrap.dedent(c) - return c - - @env.macro - def image(path, title): - return f"""
- {title} -
{title}
-
""" - - @env.macro - def javadoc(clazz, full = False, artifact = None): - version = env.variables.attributes['project-version'] - if (artifact is None) : - artifact = env.variables['javadoc_artifact'] - - if not artifact: - raise Exception("Missing configuration: 'extra.javadoc_artifact'") - - if not version: - version = 'latest' - - path = clazz.replace(".", "/") + ".html" - if full : - name = clazz - else : - name = clazz.rsplit('.', 1)[1] - return f"""{name}""" - - @env.filter - def reverse(x): - "Reverse a string (and uppercase)" - return x.upper()[::-1] diff --git a/documentation/src/main/resources/attributes.yaml b/documentation/src/main/resources/attributes.yaml deleted file mode 100644 index 0aaa7a281..000000000 --- a/documentation/src/main/resources/attributes.yaml +++ /dev/null @@ -1,2 +0,0 @@ -attributes: - version: '${project.version}' diff --git a/pom.xml b/pom.xml index f69b5a790..7d5fd08a5 100644 --- a/pom.xml +++ b/pom.xml @@ -220,6 +220,40 @@ + + + docs-preview + + validate + + + dev.jbang + jbang-maven-plugin + 0.0.8 + false + + + docs-preview + validate + + run + + + + + --source=${project.basedir} + + + https://github.com/smallrye/smallrye.github.io/ + + ${user.home}/.m2/jbang + + + + + + + unpublished