├── .github ├── dependabot.yml └── workflows │ ├── add-to-projects.yml │ ├── test.yml │ └── triggerConversion.yml ├── .gitignore ├── CONTRIBUTING.md ├── LICENSE ├── README.adoc ├── finish ├── .mvn │ └── wrapper │ │ ├── maven-wrapper.jar │ │ └── maven-wrapper.properties ├── mvnw ├── mvnw.cmd ├── pom.xml ├── resources │ └── CustomConfigSource.json └── src │ ├── main │ ├── java │ │ └── io │ │ │ └── openliberty │ │ │ └── guides │ │ │ ├── config │ │ │ ├── ConfigApplication.java │ │ │ ├── ConfigResource.java │ │ │ ├── CustomConfigSource.java │ │ │ ├── CustomEmailConverter.java │ │ │ └── Email.java │ │ │ ├── inventory │ │ │ ├── InventoryApplication.java │ │ │ ├── InventoryConfig.java │ │ │ ├── InventoryManager.java │ │ │ ├── InventoryResource.java │ │ │ ├── InventoryUtils.java │ │ │ ├── client │ │ │ │ ├── SystemClient.java │ │ │ │ ├── UnknownUrlException.java │ │ │ │ └── UnknownUrlExceptionMapper.java │ │ │ └── model │ │ │ │ ├── InventoryList.java │ │ │ │ └── SystemData.java │ │ │ └── system │ │ │ ├── SystemApplication.java │ │ │ ├── SystemConfig.java │ │ │ └── SystemResource.java │ ├── liberty │ │ └── config │ │ │ └── server.xml │ ├── resources │ │ └── META-INF │ │ │ ├── microprofile-config.properties │ │ │ └── services │ │ │ ├── org.eclipse.microprofile.config.spi.ConfigSource │ │ │ └── org.eclipse.microprofile.config.spi.Converter │ └── webapp │ │ ├── WEB-INF │ │ └── web.xml │ │ ├── favicon.ico │ │ └── index.html │ └── test │ └── java │ └── it │ └── io │ └── openliberty │ └── guides │ ├── config │ ├── ConfigITUtil.java │ ├── ConfigurationIT.java │ └── CustomConfig.java │ ├── inventory │ └── InventoryEndpointIT.java │ └── system │ └── SystemEndpointIT.java ├── scripts ├── dailyBuild.sh └── testApp.sh └── start ├── .mvn └── wrapper │ ├── maven-wrapper.jar │ └── maven-wrapper.properties ├── mvnw ├── mvnw.cmd ├── pom.xml ├── resources └── CustomConfigSource.json └── src ├── main ├── java │ └── io │ │ └── openliberty │ │ └── guides │ │ ├── config │ │ ├── ConfigApplication.java │ │ ├── ConfigResource.java │ │ └── Email.java │ │ ├── inventory │ │ ├── InventoryApplication.java │ │ ├── InventoryManager.java │ │ ├── InventoryResource.java │ │ ├── InventoryUtils.java │ │ ├── client │ │ │ ├── SystemClient.java │ │ │ ├── UnknownUrlException.java │ │ │ └── UnknownUrlExceptionMapper.java │ │ └── model │ │ │ ├── InventoryList.java │ │ │ └── SystemData.java │ │ └── system │ │ ├── SystemApplication.java │ │ ├── SystemConfig.java │ │ └── SystemResource.java ├── liberty │ └── config │ │ └── server.xml ├── resources │ └── META-INF │ │ ├── microprofile-config.properties │ │ └── services │ │ └── .gitkeep └── webapp │ ├── WEB-INF │ └── web.xml │ ├── favicon.ico │ └── index.html └── test └── java └── it └── io └── openliberty └── guides ├── config ├── ConfigITUtil.java └── CustomConfig.java ├── inventory └── InventoryEndpointIT.java └── system └── SystemEndpointIT.java /.github/dependabot.yml: -------------------------------------------------------------------------------- 1 | version: 2 2 | updates: 3 | - package-ecosystem: maven 4 | directory: "/finish" 5 | schedule: 6 | interval: monthly 7 | open-pull-requests-limit: 50 8 | - package-ecosystem: maven 9 | directory: "/start" 10 | schedule: 11 | interval: monthly 12 | open-pull-requests-limit: 50 13 | -------------------------------------------------------------------------------- /.github/workflows/add-to-projects.yml: -------------------------------------------------------------------------------- 1 | name: Add issues to Liberty guides backlog project 2 | 3 | on: 4 | issues: 5 | types: 6 | - opened 7 | - transferred 8 | 9 | jobs: 10 | add-to-project: 11 | name: Add issue to backlog 12 | runs-on: ubuntu-latest 13 | steps: 14 | - uses: actions/add-to-project@v0.4.0 15 | with: 16 | project-url: https://github.com/orgs/OpenLiberty/projects/11 17 | github-token: ${{ secrets.ADMIN_BACKLOG }} 18 | -------------------------------------------------------------------------------- /.github/workflows/test.yml: -------------------------------------------------------------------------------- 1 | name: Test application 2 | 3 | on: 4 | pull_request: 5 | branches: [ prod, staging ] 6 | 7 | jobs: 8 | check-files: 9 | if: ${{ github.event_name == 'pull_request' }} 10 | runs-on: ubuntu-latest 11 | outputs: 12 | canSkip: ${{ steps.Checker.outputs.canSkip }} 13 | steps: 14 | - name: Get files 15 | uses: actions/checkout@v4 16 | - name: Get tools 17 | uses: actions/checkout@v4 18 | with: 19 | path: tools/ 20 | repository: openliberty/guides-common 21 | - id: Checker 22 | shell: bash 23 | run: bash ./tools/pr-checker/checker.sh ${{ github.repository }} ${{ github.event.pull_request.number }} | tee checker.log 24 | - id: Lint-Code-Base 25 | if: "! github.event.pull_request.head.repo.fork" 26 | uses: github/super-linter@latest 27 | env: 28 | VALIDATE_ALL_CODEBASE: false 29 | GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} 30 | FILTER_REGEX_EXCLUDE: mvnw* 31 | LINTER_RULES_PATH: ./tools/pr-checker/linters/ 32 | DEFAULT_BRANCH: prod 33 | - name: Summary 34 | if: "! github.event.pull_request.head.repo.fork" 35 | run: | 36 | < ./checker.log tail -n +2; echo "====== Super Linter ======" 37 | < ./super-linter.log sed -n '/.*The script has completed.*/,$p' | tail -n +4 | sed 's/.*\(\[[A-Z]\+\]\)/\1/' 38 | echo "====== Examine logs in Checker and Super-Linter steps for more details ======" 39 | if [ '${{ steps.Checker.outcome }}' != 'success' ] || [ '${{ steps.Lint-Code-Base.outcome }}' != 'success' ]; then exit 1; fi 40 | test-app: 41 | runs-on: ubuntu-latest 42 | needs: [check-files] 43 | if: "!contains(needs.check-files.outputs.canSkip, 'true')" 44 | defaults: 45 | run: 46 | working-directory: finish 47 | steps: 48 | - uses: actions/checkout@v4 49 | - name: Set up JDK 11 50 | uses: actions/setup-java@v4 51 | with: 52 | distribution: 'semeru' 53 | java-version: 11 54 | - run: unset _JAVA_OPTIONS 55 | - name: Run tests 56 | run: | 57 | chmod +x ../scripts/testApp.sh 58 | sudo -E ../scripts/testApp.sh 59 | - name: Post tests 60 | if: always() 61 | run: | 62 | logsPath=$(sudo find . -name "console.log"); 63 | sudo cat "$logsPath" | sudo grep Launching 64 | - name: Archive server logs if failed 65 | if: failure() 66 | uses: actions/upload-artifact@v4 67 | with: 68 | name: server-logs 69 | path: finish/target/liberty/wlp/usr/servers/defaultServer/logs/ 70 | -------------------------------------------------------------------------------- /.github/workflows/triggerConversion.yml: -------------------------------------------------------------------------------- 1 | name: Rebuild cloud-hosted guide 2 | 3 | # Controls when the action will run. Triggers the workflow on push 4 | # events but only for the master branch 5 | on: 6 | push: 7 | branches: 8 | - 'main' 9 | - 'prod' 10 | - 'staging' 11 | 12 | # A workflow run is made up of one or more jobs that can run sequentially or in parallel 13 | jobs: 14 | # This workflow contains a single job called "post" 15 | post: 16 | # The type of runner that the job will run on 17 | runs-on: ubuntu-latest 18 | 19 | # Steps represent a sequence of tasks that will be executed as part of the job 20 | steps: 21 | # Checks-out your repository under $GITHUB_WORKSPACE, so your job can access it 22 | # Uses the secrets from the organisation for credentials 23 | - uses: actions/checkout@v2 24 | 25 | - name: Invoke workflow in another repo with inputs 26 | uses: benc-uk/workflow-dispatch@v1 27 | with: 28 | workflow: GuideConverter 29 | repo: OpenLiberty/cloud-hosted-guides 30 | token: ${{ secrets.GUIDECONVERSIONTOOL_PASSWORD }} 31 | inputs: '{ "branch": "${{ github.ref }}", "guide_name": "${{ github.event.repository.name }}" }' 32 | ref: "refs/heads/prod" 33 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | target/ 2 | .classpath 3 | .factorypath 4 | .project 5 | .settings/ 6 | finish/src/main/webapp/META-INF/ 7 | finish/.gitignore 8 | .apt_generated/ 9 | start/src/main/webapp/META-INF/ 10 | start/.gitignore 11 | temp/ 12 | WebContent/ 13 | -------------------------------------------------------------------------------- /CONTRIBUTING.md: -------------------------------------------------------------------------------- 1 | # Contributing to Open Liberty guides 2 | 3 | Anyone can contribute to the Open Liberty guides and we welcome your contributions! 4 | 5 | There are multiple ways to contribute: report bugs, fix bugs, contribute code, improve upon documentation, etc. 6 | 7 | ## Raising issues 8 | 9 | Please raise any bug reports in this [guide repository](../../issues). For new topics, large updates to existing guides, or general suggestions and ideas, report your issue in the [Open Liberty common guides repository](https://github.com/OpenLiberty/guides-common/issues). Be sure to search the list of open issues to see if your issue has already been raised. 10 | 11 | A good bug report makes it easy for everyone to understand what you were trying to do and what went wrong. Provide as much context as possible so we can try to recreate the issue. 12 | 13 | ## Contributions 14 | 15 | Contributing to an Open Liberty guide is simple. Each guide is maintained in its own GitHub repository. To contribute, just fork from the `prod` branch for your chosen guide. Then create a branch in your forked repository to include your contribution and open a pull request to the `staging` branch for the guide. 16 | Certify the originality of your work by following the [Developer Certificate of Origin (DCO)](https://developercertificate.org) approach and adding a line to the end of the Git commit message to sign your work: 17 | 18 | ```text 19 | Signed-off-by: Jane Williams 20 | ``` 21 | 22 | The sign-off is just a line at the end of the commit message that certifies that you wrote it or otherwise have the right to pass it on as an open source patch. 23 | 24 | Use your real name when you sign. We can't accept pseudonyms or anonymous contributions. 25 | 26 | Many Git UI tools have support for adding the `Signed-off-by` line to the end of your commit message. This line can be automatically added by the `git commit` command by using the `-s` option. 27 | 28 | The team is then notified and your contribution is reviewed according to the following process: 29 | 30 | 1. The team will review your change(s). 31 | - If there are further changes to be made, the team will request changes on the pull request. 32 | - If the team does not agree with the change, the PR will be closed with an explanation and suggestion for follow-up. 33 | 2. If the team approves, the team will merge your PR. A full Open Liberty staging site build will be run. 34 | 3. Based on the results of the build: 35 | - If further review is needed, we will let you know about a pending review from our team and discuss any necessary improvements that need to be made to your change(s). 36 | - If everything is successful, the team will publish your change(s) to the `prod` branch and update the Open Liberty production site, if necessary. 37 | 38 | ## Questions and concerns 39 | 40 | If you have any questions or concerns about the guides or about Open Liberty, you can visit [Gitter for Open Liberty](https://gitter.im/OpenLiberty/) and post your questions in the relevant rooms. You can also join the Open Liberty group on [Groups.io](https://groups.io/g/openliberty) to discuss any issues you have. 41 | -------------------------------------------------------------------------------- /README.adoc: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2017, 2025 IBM Corporation and others. 2 | // Licensed under Creative Commons Attribution-NoDerivatives 3 | // 4.0 International (CC BY-ND 4.0) 4 | // https://creativecommons.org/licenses/by-nd/4.0/ 5 | // 6 | // Contributors: 7 | // IBM Corporation 8 | :projectid: microprofile-config 9 | :page-layout: guide-multipane 10 | :page-duration: 20 minutes 11 | :page-releasedate: 2018-03-09 12 | :page-guide-category: microprofile 13 | :page-essential: false 14 | :page-description: Learn how to use the MicroProfile Config specification to externalize configuration data for an application. 15 | :page-tags: ['microprofile'] 16 | :page-permalink: /guides/{projectid} 17 | :page-related-guides: ['rest-intro', 'cdi-intro', 'microprofile-config-intro'] 18 | :common-includes: https://raw.githubusercontent.com/OpenLiberty/guides-common/prod 19 | :source-highlighter: prettify 20 | :page-seo-title: Externalizing configuration for Java microservices using Eclipse MicroProfile Config 21 | :page-seo-description: A tutorial and example on how to externalize and inject static and dynamic configuration properties for Java microservices through configuration sources using Eclipse MicroProfile Config. 22 | :guide-author: Open Liberty 23 | = Configuring microservices 24 | 25 | [.hidden] 26 | NOTE: This repository contains the guide documentation source. To view the guide in published form, view it on the https://openliberty.io/guides/{projectid}.html[Open Liberty website]. 27 | 28 | Learn how to provide external configuration to microservices using MicroProfile Config. 29 | 30 | // ================================================================================================= 31 | // What you'll learn 32 | // ================================================================================================= 33 | 34 | == What you'll learn 35 | 36 | You will learn how to externalize and inject both static and dynamic configuration properties for microservices using MicroProfile Config. 37 | 38 | You will learn to aggregate multiple configuration sources, assign prioritization values to these sources, merge configuration values, and create custom configuration sources. 39 | 40 | The application that you will be working with is an `inventory` service which stores the information about various JVMs running on different hosts. Whenever a request is made to the `inventory` service to retrieve the JVM system properties of a particular host, the `inventory` service will communicate with the `system` service on that host to get these system properties. You will add configuration properties to simulate if a service is down for maintenance. 41 | 42 | // ================================================================================================= 43 | // Getting Started 44 | // ================================================================================================= 45 | 46 | [role=command] 47 | include::{common-includes}/gitclone.adoc[] 48 | 49 | [role=command] 50 | include::{common-includes}/twyb-intro-mvnw.adoc[] 51 | 52 | // static guide instructions: 53 | ifndef::cloud-hosted[] 54 | You can access the following two microservices to test their availability: 55 | 56 | * http://localhost:9080/system/properties[http://localhost:9080/system/properties^] retrieves the information for a specific host 57 | 58 | * http://localhost:9080/inventory/systems[http://localhost:9080/inventory/systems^] retrieves the information for a list of all previously registered hosts 59 | 60 | In addition, you can access a third microservice, which retrieves and aggregates all of the configuration properties and sources that are added throughout this guide. This is available at: 61 | 62 | * http://localhost:9080/config[http://localhost:9080/config^] 63 | endif::[] 64 | 65 | // cloud-hosted guide instructions: 66 | ifdef::cloud-hosted[] 67 | Open another command-line session by selecting **Terminal** > **New Terminal** from the menu of the IDE. Run the following curl command to test the availability of the ***system*** microservice and retrieve the system information: 68 | ```bash 69 | curl -s http://localhost:9080/system/properties | jq 70 | ``` 71 | 72 | Run the following curl command to test the availability of the **inventory** microservice and retrieve the information for a list of all previously registered hosts: 73 | ```bash 74 | curl -s http://localhost:9080/inventory/systems | jq 75 | ``` 76 | 77 | In addition, you can run the following curl command to access a third microservice, which retrieves and aggregates all of the configuration properties and sources that are added throughout this guide. 78 | ```bash 79 | curl -s http://localhost:9080/config | jq 80 | ``` 81 | endif::[] 82 | 83 | [role=command] 84 | include::{common-includes}/twyb-end-mvnw.adoc[] 85 | 86 | // ================================================================================================= 87 | // Ordering multiple configuration sources 88 | // ================================================================================================= 89 | == Ordering multiple configuration sources 90 | 91 | // static guide instructions: 92 | ifndef::cloud-hosted[] 93 | Now, navigate to the `start` directory to begin. 94 | endif::[] 95 | 96 | // cloud-hosted guide instructions: 97 | ifdef::cloud-hosted[] 98 | To begin, run the following command to navigate to the **start** directory: 99 | ```bash 100 | cd /home/project/guide-microprofile-config/start 101 | ``` 102 | endif::[] 103 | 104 | 105 | [role=command] 106 | include::{common-includes}/devmode-mvnw-start.adoc[] 107 | 108 | MicroProfile Config combines configuration properties from multiple sources, each known as a ConfigSource. Each ConfigSource has a specified priority, defined by its `config_ordinal` value. 109 | 110 | A higher ordinal value means that the values taken from this ConfigSource will override values from ConfigSources with a lower ordinal value. 111 | 112 | The following four sources are the default configuration sources: 113 | 114 | * A `` element in the server.xml file has a default ordinal of 500. 115 | * System properties has a default ordinal of 400. (e.g. `bootstrap.properties` file) 116 | * Environment variables have a default ordinal of 300. (e.g. `server.env` file) 117 | * The [hotspot=ordinal]`META-INF/microprofile-config.properties` configuration property file on the classpath has a default ordinal of 100. 118 | 119 | Access the [hotspot]`src/main/resources/META-INF/microprofile-config.properties` local configuration file. This configuration file is the default configuration source for an application that uses MicroProfile Config. 120 | 121 | microprofile-config.properties 122 | [source, properties, linenums, role='code_column'] 123 | ---- 124 | include::finish/src/main/resources/META-INF/microprofile-config.properties[] 125 | ---- 126 | 127 | // ================================================================================================= 128 | // Injecting static configuration 129 | // ================================================================================================= 130 | == Injecting static configuration 131 | 132 | The MicroProfile Config API is included in the MicroProfile dependency that is specified in your [hotspot file=0]`pom.xml` file. Look for the dependency with the [hotspot=microprofile file=0]`microprofile` artifact ID. This dependency provides a library that allows you to use the MicroProfile Config API to externalize configurations for your microservices. The [hotspot=config file=1]`mpConfig` feature is also enabled in the [hotspot file=1]`src/main/liberty/config/server.xml` file. 133 | 134 | pom.xml 135 | [source,xml,linenums,role="code_column"] 136 | ---- 137 | include::finish/pom.xml[]] 138 | ---- 139 | 140 | server.xml 141 | [source,xml,linenums,role="code_column"] 142 | ---- 143 | include::finish/src/main/liberty/config/server.xml[] 144 | ---- 145 | 146 | Now navigate to the [hotspot file=2]`src/main/resources/META-INF/microprofile-config.properties` local configuration file to check some static configuration. This configuration file is the default configuration source for an application that uses MicroProfile Config. 147 | 148 | The [hotspot=inventory-port-number file=2]`io_openliberty_guides_port_number` property that has already been defined in this file, determines the port number of the REST service. 149 | 150 | microprofile-config.properties 151 | [source, properties, linenums, role='code_column'] 152 | ---- 153 | include::finish/src/main/resources/META-INF/microprofile-config.properties[] 154 | ---- 155 | 156 | To use this configuration property, 157 | [role="code_command hotspot file=3", subs="quotes"] 158 | ---- 159 | #Create the `InventoryConfig.java` class.# 160 | `src/main/java/io/openliberty/guides/inventory/InventoryConfig.java` 161 | ---- 162 | InventoryConfig.java 163 | [source, Java, linenums, role='code_column hide_tags=copyright,inject-inMaintenance,custom-converter,isInMaintenance,getEmail'] 164 | ---- 165 | include::finish/src/main/java/io/openliberty/guides/inventory/InventoryConfig.java[] 166 | ---- 167 | 168 | Inject the [hotspot=guides-port-number file=3]`io_openliberty_guides_port_number` property, and add the [hotspot=getPortNumber file=3]`getPortNumber()` class method to the [hotspot file=3]`InventoryConfig.java` file. 169 | 170 | The [hotspot=inject-port-number file=3]`@Inject` annotation injects the port number directly, the injection value is static and fixed on application starting. 171 | 172 | The [hotspot=getPortNumber file=3]`getPortNumber()` method directly returns the value of `portNumber` because it has been injected. 173 | 174 | // ================================================================================================= 175 | // Injecting dynamic configuration 176 | // ================================================================================================= 177 | == Injecting dynamic configuration 178 | 179 | Note that three default config sources mentioned above are static and fixed on application starting, so the properties within them cannot be modified while the Liberty is running. However, you can externalize configuration data out of the application package, through the creation of custom configuration sources, so that the service updates configuration changes dynamically. 180 | 181 | // ================================================================================================= 182 | // Creating custom configuration sources 183 | // ================================================================================================= 184 | === Creating custom configuration sources 185 | 186 | CustomConfigSource.json 187 | [source, Json, linenums, role='code_column'] 188 | ---- 189 | include::finish/resources/CustomConfigSource.json[] 190 | ---- 191 | 192 | Custom configuration sources can be created by implementing the `org.eclipse.microprofile.config.spi.ConfigSource` interface and using the `java.util.ServiceLoader` mechanism. 193 | 194 | A [hotspot file=0]`CustomConfigSource.json` JSON file has already been created in the `resources` directory. This JSON file simulates a remote configuration resource in real life. This file contains 4 custom config properties and has an ordinal of [hotspot=2 file=0]`150`. To use these properties in the application, the data object needs to be transformed from this JSON file to the configuration for your application. 195 | 196 | To link this JSON file to your application and to implement the `ConfigSource` interface, 197 | 198 | [role="code_command hotspot file=1", subs="quotes"] 199 | ---- 200 | #Create the `CustomConfigSource` class.# 201 | `src/main/java/io/openliberty/guides/config/CustomConfigSource.java` 202 | ---- 203 | CustomConfigSource.java 204 | [source, Java, linenums, role='code_column hide_tags=copyright'] 205 | ---- 206 | include::finish/src/main/java/io/openliberty/guides/config/CustomConfigSource.java[] 207 | ---- 208 | 209 | The [hotspot=getProperties file=1]`getProperties()` method reads the key value pairs from the [hotspot file=0]`resources/CustomConfigSource.json` JSON file and writes the information into a map. 210 | 211 | Finally, register the custom configuration source. 212 | 213 | [role="code_command hotspot file=2", subs="quotes"] 214 | ---- 215 | #Create the configuration file.# 216 | `src/main/resources/META-INF/services/org.eclipse.microprofile.config.spi.ConfigSource` 217 | ---- 218 | 219 | org.eclipse.microprofile.config.spi.ConfigSource 220 | [source, Java, linenums, role='code_column'] 221 | ---- 222 | include::finish/src/main/resources/META-INF/services/org.eclipse.microprofile.config.spi.ConfigSource[] 223 | ---- 224 | 225 | Add the fully qualified class name of the configuration source into it. 226 | 227 | 228 | // ================================================================================================= 229 | // Enabling dynamic configuration injection 230 | // ================================================================================================= 231 | === Enabling dynamic configuration injection 232 | 233 | Now that the custom configuration source has successfully been set up, you can enable dynamic configuration injection of the properties being set in this ConfigSource. To enable this dynamic injection, 234 | 235 | [role="code_command hotspot", subs="quotes"] 236 | ---- 237 | #Replace the `InventoryConfig.java` class.# 238 | `src/main/java/io/openliberty/guides/inventory/InventoryConfig.java` 239 | ---- 240 | InventoryConfig.java 241 | [source, Java, linenums, role='code_column hide_tags=copyright,custom-converter,getEmail'] 242 | ---- 243 | include::finish/src/main/java/io/openliberty/guides/inventory/InventoryConfig.java[] 244 | ---- 245 | Inject the [hotspot=inject-inMaintenance file=0]`io_openliberty_guides_inventory_inMaintenance` property, and add the [hotspot=isInMaintenance file=0]`isInMaintenance()` class method. 246 | 247 | The [hotspot=inject file=0]`@Inject` and [hotspot=configPropety file=0]`@ConfigProperty` annotations inject the [hotspot=4 file=1]`io_openliberty_guides_inventory_inMaintenance` configuration property from the [hotspot file=1]`CustomConfigSource.json` file. The `Provider<>` interface used, forces the service to retrieve the inMaintenance value just in time. This retrieval of the value just in time makes the config injection dynamic and able to change without having to restart the application. 248 | 249 | Every time that you invoke the [hotspot=inMaintenanceGet file=0]`inMaintenance.get()` method, the `Provider<>` interface picks up the latest value of the [hotspot=4 file=1]`io_openliberty_guides_inventory_inMaintenance` property from configuration sources. 250 | 251 | CustomConfigSource.json 252 | [source, Json, linenums, role='code_column'] 253 | ---- 254 | include::finish/resources/CustomConfigSource.json[] 255 | ---- 256 | 257 | // ================================================================================================= 258 | // Creating custom converters 259 | // ================================================================================================= 260 | == Creating custom converters 261 | 262 | Configuration values are purely Strings. MicroProfile Config API has built-in converters that automatically converts configured Strings into target types such as `int`, `Integer`, `boolean`, `Boolean`, `float`, `Float`, `double` and `Double`. Therefore, in the previous section, it is type-safe to directly set the variable type to `Provider`. 263 | 264 | To convert configured Strings to an arbitrary class type, such as the `Email` class type, 265 | [role="code_command hotspot", subs="quotes"] 266 | ---- 267 | #Replace the `Email` Class.# 268 | `src/main/java/io/openliberty/guides/config/Email.java` 269 | ---- 270 | Email.java 271 | [source, Java, linenums, role='code_column hide_tags=copyright'] 272 | ---- 273 | include::finish/src/main/java/io/openliberty/guides/config/Email.java[] 274 | ---- 275 | 276 | To use this [hotspot=email file=0]`Email` class type, add a custom converter by implementing the generic interface `org.eclipse.microprofile.config.spi.Converter`. The Type parameter of the interface is the target type the String is converted to. 277 | 278 | [role="code_command hotspot file=1", subs="quotes"] 279 | ---- 280 | #Create the `CustomEmailConverter` class.# 281 | `src/main/java/io/openliberty/guides/config/CustomEmailConverter.java` 282 | ---- 283 | CustomEmailConverter.java 284 | [source, Java, linenums, role='code_column hide_tags=copyright'] 285 | ---- 286 | include::finish/src/main/java/io/openliberty/guides/config/CustomEmailConverter.java[] 287 | ---- 288 | 289 | This implements the `Converter` interface. 290 | 291 | To register your implementation, 292 | [role="code_command hotspot file=2", subs="quotes"] 293 | ---- 294 | #Create the configuration file.# 295 | `src/main/resources/META-INF/services/org.eclipse.microprofile.config.spi.Converter` 296 | ---- 297 | org.eclipse.microprofile.config.spi.Converter 298 | [source, Java, linenums, role='code_column'] 299 | ---- 300 | include::finish/src/main/resources/META-INF/services/org.eclipse.microprofile.config.spi.Converter[] 301 | ---- 302 | Add the fully qualified class name of the custom converter into it. 303 | 304 | To use the custom [hotspot=customConfig file=2]`Email` converter, 305 | [role="code_command hotspot file=3", subs="quotes"] 306 | ---- 307 | #Replace the `InventoryConfig` class.# 308 | `src/main/java/io/openliberty/guides/inventory/InventoryConfig.java` 309 | ---- 310 | InventoryConfig.java 311 | [source, Java, linenums, role='code_column hide_tags=copyright'] 312 | ---- 313 | include::finish/src/main/java/io/openliberty/guides/inventory/InventoryConfig.java[] 314 | ---- 315 | Inject the [hotspot=custom-converter file=3]`io_openliberty_guides_email` property, and add the [hotspot=getEmail file=3]`getEmail()` method. 316 | 317 | // ================================================================================================= 318 | // Adding configuration to the service 319 | // ================================================================================================= 320 | == Adding configuration to the microservice 321 | 322 | To use externalized configuration in the `inventory` service, 323 | [role="code_command hotspot", subs="quotes"] 324 | ---- 325 | #Replace the `InventoryResource` class.# 326 | `src/main/java/io/openliberty/guides/inventory/InventoryResource.java` 327 | ---- 328 | InventoryResource.java 329 | [source, Java, linenums, role='code_column hide_tags=copyright'] 330 | ---- 331 | include::finish/src/main/java/io/openliberty/guides/inventory/InventoryResource.java[] 332 | ---- 333 | To add configuration to the `inventory` service, the [hotspot=config-injection file=0]`InventoryConfig` object is injected to the existing class. 334 | 335 | The port number from the configuration is retrieved by the [hotspot=config-port file=0]`inventoryConfig.getPortNumber()` method and passed to the [hotspot=config-port file=0]`manager.get()` method as a parameter. 336 | 337 | To determine whether the inventory service is in maintenance or not (according to the configuration value), [hotspot=isInMaintenance file=0]`inventoryConfig.isInMaintenance()` class method is used. If you set the [hotspot=4 file=1]`io_openliberty_guides_inventory_inMaintenance` property to `true` in the configuration, the inventory service returns the message, `ERROR: Service is currently in maintenance`, along with the contact email. The email configuration value can be obtained by calling [hotspot=getEmail file=0]`inventoryConfig.getEmail()` method. 338 | 339 | CustomConfigSource.json 340 | [source, Json, linenums, role='code_column'] 341 | ---- 342 | include::finish/resources/CustomConfigSource.json[] 343 | ---- 344 | 345 | 346 | // ================================================================================================= 347 | // Building and running the application 348 | // ================================================================================================= 349 | 350 | [role=command] 351 | include::{common-includes}/devmode-build.adoc[] 352 | 353 | // static guide instructions: 354 | ifndef::cloud-hosted[] 355 | While the Liberty is running, the following two microservices should be available to access: 356 | 357 | * http://localhost:9080/system/properties[http://localhost:9080/system/properties^] 358 | 359 | * http://localhost:9080/inventory/systems[http://localhost:9080/inventory/systems^] 360 | 361 | 362 | You can find the service that retrieves configuration information that is specific to this guide at the following location: 363 | 364 | * http://localhost:9080/config[http://localhost:9080/config^] 365 | endif::[] 366 | 367 | // cloud-hosted guide instructions: 368 | ifdef::cloud-hosted[] 369 | While the Liberty is running, run the following curl command to access the ***system*** microservice: 370 | ```bash 371 | curl -s http://localhost:9080/system/properties | jq 372 | ``` 373 | 374 | and run the following curl command to access the ***inventory*** microservice: 375 | ```bash 376 | curl -s http://localhost:9080/inventory/systems | jq 377 | ``` 378 | 379 | You can find the service that retrieves configuration information that is specific to this guide by running the following curl command: 380 | ```bash 381 | curl -s http://localhost:9080/config | jq 382 | ``` 383 | endif::[] 384 | 385 | The [hotspot=2 file=0]`config_ordinal` value of the custom configuration source is set to [hotspot=2 file=0]`150`. It overrides configuration values of the default [hotspot file=1]`microprofile-config.properties` source, which has a [hotspot=ordinal file=1]`config_ordinal` value of [hotspot=ordinal file=1]`100`. 386 | 387 | CustomConfigSource.json 388 | [source, Json, linenums, role='code_column'] 389 | ---- 390 | include::finish/resources/CustomConfigSource.json[] 391 | ---- 392 | 393 | microprofile-config.properties 394 | [source, properties, linenums, role='code_column'] 395 | ---- 396 | include::finish/src/main/resources/META-INF/microprofile-config.properties[] 397 | ---- 398 | 399 | // static guide instructions: 400 | ifndef::cloud-hosted[] 401 | Play with this application by changing configuration values for each property in the [hotspot file=0]`resources/CustomConfigSource.json` file. Your changes are added dynamically, and you do not need to restart the Liberty. Refresh http://localhost:9080/config[http://localhost:9080/config^] to see the dynamic changes. 402 | 403 | For example, change [hotspot=4 file=0]`io_openliberty_guides_inventory_inMaintenance` from `false` to `true`, then try to access http://localhost:9080/inventory/systems[http://localhost:9080/inventory/systems^] again. The following message displays: `ERROR: Service is currently in maintenance`. 404 | endif::[] 405 | 406 | // cloud-hosted guide instructions: 407 | ifdef::cloud-hosted[] 408 | Play with this application by changing configuration values for each property in the ***resources/CustomConfigSource.json*** file. Your changes are added dynamically, and you do not need to restart the Liberty. Rerun the following curl command to see the dynamic changes: 409 | ```bash 410 | curl -s http://localhost:9080/config | jq 411 | ``` 412 | 413 | For example, change ***io_openliberty_guides_inventory_inMaintenance*** from ***false*** to ***true***, then try to access http://localhost:9080/inventory/systems again by running the following curl command: 414 | ```bash 415 | curl -s http://localhost:9080/inventory/systems | jq 416 | ``` 417 | 418 | The following message displays: ***ERROR: Service is currently in maintenance***. 419 | endif::[] 420 | 421 | 422 | // ================================================================================================= 423 | // Testing the application 424 | // ================================================================================================= 425 | 426 | == Testing the application 427 | 428 | [role="code_command hotspot", subs="quotes"] 429 | ---- 430 | #Create the `ConfigurationIT` class.# 431 | `src/test/java/it/io/openliberty/guides/config/ConfigurationIT.java` 432 | ---- 433 | ConfigurationIT.java 434 | [source, Java, linenums, role='code_column hide_tags=copyright'] 435 | ---- 436 | include::finish/src/test/java/it/io/openliberty/guides/config/ConfigurationIT.java[] 437 | ---- 438 | 439 | microprofile-config.properties 440 | [source, properties, linenums, role='code_column'] 441 | ---- 442 | include::finish/src/main/resources/META-INF/microprofile-config.properties[] 443 | ---- 444 | 445 | 446 | The [hotspot=testInitialServiceStatus file=0]`testInitialServiceStatus()` test case reads the value of the [hotspot=inventory-in-maintenance file=1]`io_openliberty_guides_inventory_inMaintenance` configuration property in the [hotspot file=1]`META-INF/microprofile-config.properties` file and checks the HTTP response of the inventory service. If the configuration value is `false`, the service returns a valid response. Otherwise, the service returns the following message: `ERROR: Service is currently in maintenance`. 447 | 448 | Because the [hotspot=inventory-in-maintenance file=1]`io_openliberty_guides_inventory_inMaintenance` configuration property is set to `false` by default, the [hotspot=testPutServiceInMaintenance file=0]`testPutServiceInMaintenance()` test case first checks that the inventory service is not in maintenance in the beginning. Next, this test switches the value of the [hotspot=inventory-in-maintenance file=1]`io_openliberty_guides_inventory_inMaintenance` configuration property to `true`. In the end, the inventory service returns the following message: `ERROR: Service is currently in maintenance`. 449 | 450 | The [hotspot=testChangeEmail file=0]`testChangeEmail()` test case first puts the `inventory` service in maintenance, then it changes the email address in the configuration file. In the end, the `inventory` service should display the error message with the latest email address. 451 | 452 | In addition, a few endpoint tests have been provided for you to test the basic functionality of the `inventory` and `system` services. If a test failure occurs, then you must have introduced a bug into the code. Remember that you must register the custom configuration source and custom converter in the `src/main/resources/META-INF/services/` directory. If you don't complete these steps, the tests will fail. These tests run automatically as a part of the integration test suite. 453 | 454 | 455 | [role=command] 456 | include::{common-includes}/devmode-test.adoc[] 457 | 458 | You see the following output: 459 | 460 | [source, role="no_copy"] 461 | ---- 462 | ------------------------------------------------------- 463 | T E S T S 464 | ------------------------------------------------------- 465 | Running it.io.openliberty.guides.config.ConfigurationIT 466 | Tests run: 3, Failures: 0, Errors: 0, Skipped: 0, Time elapsed: 5.92 s - in it.io.openliberty.guides.config.ConfigurationIT 467 | Running it.io.openliberty.guides.system.SystemEndpointIT 468 | Tests run: 1, Failures: 0, Errors: 0, Skipped: 0, Time elapsed: 0.017 s - in it.io.openliberty.guides.system.SystemEndpointIT 469 | Running it.io.openliberty.guides.inventory.InventoryEndpointIT 470 | [WARNING ] Interceptor for {http://client.inventory.guides.openliberty.io/}SystemClient has thrown exception, unwinding now 471 | Could not send Message. 472 | [err] The specified host is unknown. 473 | Tests run: 3, Failures: 0, Errors: 0, Skipped: 0, Time elapsed: 0.077 s - in it.io.openliberty.guides.inventory.InventoryEndpointIT 474 | 475 | Results: 476 | 477 | Tests run: 7, Failures: 0, Errors: 0, Skipped: 0 478 | ---- 479 | 480 | The warning and error messages are expected and result from a request to a bad or an unknown hostname. This request is made in the `testUnknownHost()` test from the `InventoryEndpointIT` integration test. 481 | 482 | To see whether the tests detect a failure, remove the configuration resetting line in the [hotspot=setup file=0]`setup()` method of the [hotspot file=0]`ConfigurationIT.java` file. Then, manually change some configuration values in the `resources/CustomConfigSource.json` file. Rerun the tests. You will see a test failure occur. 483 | 484 | [role=command] 485 | include::{common-includes}/devmode-quit-ctrlc.adoc[] 486 | 487 | == Great work! You're done! 488 | 489 | You just built and tested a MicroProfile application with MicroProfile Config in Open Liberty. 490 | 491 | Feel free to try one of the related guides. They demonstrate new technologies that you can learn and expand on top what you built in this guide. 492 | 493 | include::{common-includes}/attribution.adoc[subs="attributes"] 494 | -------------------------------------------------------------------------------- /finish/.mvn/wrapper/maven-wrapper.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/OpenLiberty/guide-microprofile-config/8d870ed767a0ae27b2cbc35c40e157679bd40457/finish/.mvn/wrapper/maven-wrapper.jar -------------------------------------------------------------------------------- /finish/.mvn/wrapper/maven-wrapper.properties: -------------------------------------------------------------------------------- 1 | distributionUrl=https://repo.maven.apache.org/maven2/org/apache/maven/apache-maven/3.9.9/apache-maven-3.9.9-bin.zip 2 | wrapperUrl=https://repo.maven.apache.org/maven2/org/apache/maven/wrapper/maven-wrapper/3.3.2/maven-wrapper-3.3.2.jar 3 | -------------------------------------------------------------------------------- /finish/mvnw: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | # ---------------------------------------------------------------------------- 3 | # Licensed to the Apache Software Foundation (ASF) under one 4 | # or more contributor license agreements. See the NOTICE file 5 | # distributed with this work for additional information 6 | # regarding copyright ownership. The ASF licenses this file 7 | # to you under the Apache License, Version 2.0 (the 8 | # "License"); you may not use this file except in compliance 9 | # with the License. You may obtain a copy of the License at 10 | # 11 | # http://www.apache.org/licenses/LICENSE-2.0 12 | # 13 | # Unless required by applicable law or agreed to in writing, 14 | # software distributed under the License is distributed on an 15 | # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 16 | # KIND, either express or implied. See the License for the 17 | # specific language governing permissions and limitations 18 | # under the License. 19 | # ---------------------------------------------------------------------------- 20 | 21 | # ---------------------------------------------------------------------------- 22 | # Apache Maven Wrapper startup batch script, version 3.3.2 23 | # 24 | # Required ENV vars: 25 | # ------------------ 26 | # JAVA_HOME - location of a JDK home dir 27 | # 28 | # Optional ENV vars 29 | # ----------------- 30 | # MAVEN_OPTS - parameters passed to the Java VM when running Maven 31 | # e.g. to debug Maven itself, use 32 | # set MAVEN_OPTS=-Xdebug -Xrunjdwp:transport=dt_socket,server=y,suspend=y,address=8000 33 | # MAVEN_SKIP_RC - flag to disable loading of mavenrc files 34 | # ---------------------------------------------------------------------------- 35 | 36 | if [ -z "$MAVEN_SKIP_RC" ]; then 37 | 38 | if [ -f /usr/local/etc/mavenrc ]; then 39 | . /usr/local/etc/mavenrc 40 | fi 41 | 42 | if [ -f /etc/mavenrc ]; then 43 | . /etc/mavenrc 44 | fi 45 | 46 | if [ -f "$HOME/.mavenrc" ]; then 47 | . "$HOME/.mavenrc" 48 | fi 49 | 50 | fi 51 | 52 | # OS specific support. $var _must_ be set to either true or false. 53 | cygwin=false 54 | darwin=false 55 | mingw=false 56 | case "$(uname)" in 57 | CYGWIN*) cygwin=true ;; 58 | MINGW*) mingw=true ;; 59 | Darwin*) 60 | darwin=true 61 | # Use /usr/libexec/java_home if available, otherwise fall back to /Library/Java/Home 62 | # See https://developer.apple.com/library/mac/qa/qa1170/_index.html 63 | if [ -z "$JAVA_HOME" ]; then 64 | if [ -x "/usr/libexec/java_home" ]; then 65 | JAVA_HOME="$(/usr/libexec/java_home)" 66 | export JAVA_HOME 67 | else 68 | JAVA_HOME="/Library/Java/Home" 69 | export JAVA_HOME 70 | fi 71 | fi 72 | ;; 73 | esac 74 | 75 | if [ -z "$JAVA_HOME" ]; then 76 | if [ -r /etc/gentoo-release ]; then 77 | JAVA_HOME=$(java-config --jre-home) 78 | fi 79 | fi 80 | 81 | # For Cygwin, ensure paths are in UNIX format before anything is touched 82 | if $cygwin; then 83 | [ -n "$JAVA_HOME" ] \ 84 | && JAVA_HOME=$(cygpath --unix "$JAVA_HOME") 85 | [ -n "$CLASSPATH" ] \ 86 | && CLASSPATH=$(cygpath --path --unix "$CLASSPATH") 87 | fi 88 | 89 | # For Mingw, ensure paths are in UNIX format before anything is touched 90 | if $mingw; then 91 | [ -n "$JAVA_HOME" ] && [ -d "$JAVA_HOME" ] \ 92 | && JAVA_HOME="$( 93 | cd "$JAVA_HOME" || ( 94 | echo "cannot cd into $JAVA_HOME." >&2 95 | exit 1 96 | ) 97 | pwd 98 | )" 99 | fi 100 | 101 | if [ -z "$JAVA_HOME" ]; then 102 | javaExecutable="$(which javac)" 103 | if [ -n "$javaExecutable" ] && ! [ "$(expr "$javaExecutable" : '\([^ ]*\)')" = "no" ]; then 104 | # readlink(1) is not available as standard on Solaris 10. 105 | readLink=$(which readlink) 106 | if [ ! "$(expr "$readLink" : '\([^ ]*\)')" = "no" ]; then 107 | if $darwin; then 108 | javaHome="$(dirname "$javaExecutable")" 109 | javaExecutable="$(cd "$javaHome" && pwd -P)/javac" 110 | else 111 | javaExecutable="$(readlink -f "$javaExecutable")" 112 | fi 113 | javaHome="$(dirname "$javaExecutable")" 114 | javaHome=$(expr "$javaHome" : '\(.*\)/bin') 115 | JAVA_HOME="$javaHome" 116 | export JAVA_HOME 117 | fi 118 | fi 119 | fi 120 | 121 | if [ -z "$JAVACMD" ]; then 122 | if [ -n "$JAVA_HOME" ]; then 123 | if [ -x "$JAVA_HOME/jre/sh/java" ]; then 124 | # IBM's JDK on AIX uses strange locations for the executables 125 | JAVACMD="$JAVA_HOME/jre/sh/java" 126 | else 127 | JAVACMD="$JAVA_HOME/bin/java" 128 | fi 129 | else 130 | JAVACMD="$( 131 | \unset -f command 2>/dev/null 132 | \command -v java 133 | )" 134 | fi 135 | fi 136 | 137 | if [ ! -x "$JAVACMD" ]; then 138 | echo "Error: JAVA_HOME is not defined correctly." >&2 139 | echo " We cannot execute $JAVACMD" >&2 140 | exit 1 141 | fi 142 | 143 | if [ -z "$JAVA_HOME" ]; then 144 | echo "Warning: JAVA_HOME environment variable is not set." >&2 145 | fi 146 | 147 | # traverses directory structure from process work directory to filesystem root 148 | # first directory with .mvn subdirectory is considered project base directory 149 | find_maven_basedir() { 150 | if [ -z "$1" ]; then 151 | echo "Path not specified to find_maven_basedir" >&2 152 | return 1 153 | fi 154 | 155 | basedir="$1" 156 | wdir="$1" 157 | while [ "$wdir" != '/' ]; do 158 | if [ -d "$wdir"/.mvn ]; then 159 | basedir=$wdir 160 | break 161 | fi 162 | # workaround for JBEAP-8937 (on Solaris 10/Sparc) 163 | if [ -d "${wdir}" ]; then 164 | wdir=$( 165 | cd "$wdir/.." || exit 1 166 | pwd 167 | ) 168 | fi 169 | # end of workaround 170 | done 171 | printf '%s' "$( 172 | cd "$basedir" || exit 1 173 | pwd 174 | )" 175 | } 176 | 177 | # concatenates all lines of a file 178 | concat_lines() { 179 | if [ -f "$1" ]; then 180 | # Remove \r in case we run on Windows within Git Bash 181 | # and check out the repository with auto CRLF management 182 | # enabled. Otherwise, we may read lines that are delimited with 183 | # \r\n and produce $'-Xarg\r' rather than -Xarg due to word 184 | # splitting rules. 185 | tr -s '\r\n' ' ' <"$1" 186 | fi 187 | } 188 | 189 | log() { 190 | if [ "$MVNW_VERBOSE" = true ]; then 191 | printf '%s\n' "$1" 192 | fi 193 | } 194 | 195 | BASE_DIR=$(find_maven_basedir "$(dirname "$0")") 196 | if [ -z "$BASE_DIR" ]; then 197 | exit 1 198 | fi 199 | 200 | MAVEN_PROJECTBASEDIR=${MAVEN_BASEDIR:-"$BASE_DIR"} 201 | export MAVEN_PROJECTBASEDIR 202 | log "$MAVEN_PROJECTBASEDIR" 203 | 204 | ########################################################################################## 205 | # Extension to allow automatically downloading the maven-wrapper.jar from Maven-central 206 | # This allows using the maven wrapper in projects that prohibit checking in binary data. 207 | ########################################################################################## 208 | wrapperJarPath="$MAVEN_PROJECTBASEDIR/.mvn/wrapper/maven-wrapper.jar" 209 | if [ -r "$wrapperJarPath" ]; then 210 | log "Found $wrapperJarPath" 211 | else 212 | log "Couldn't find $wrapperJarPath, downloading it ..." 213 | 214 | if [ -n "$MVNW_REPOURL" ]; then 215 | wrapperUrl="$MVNW_REPOURL/org/apache/maven/wrapper/maven-wrapper/3.3.2/maven-wrapper-3.3.2.jar" 216 | else 217 | wrapperUrl="https://repo.maven.apache.org/maven2/org/apache/maven/wrapper/maven-wrapper/3.3.2/maven-wrapper-3.3.2.jar" 218 | fi 219 | while IFS="=" read -r key value; do 220 | # Remove '\r' from value to allow usage on windows as IFS does not consider '\r' as a separator ( considers space, tab, new line ('\n'), and custom '=' ) 221 | safeValue=$(echo "$value" | tr -d '\r') 222 | case "$key" in wrapperUrl) 223 | wrapperUrl="$safeValue" 224 | break 225 | ;; 226 | esac 227 | done <"$MAVEN_PROJECTBASEDIR/.mvn/wrapper/maven-wrapper.properties" 228 | log "Downloading from: $wrapperUrl" 229 | 230 | if $cygwin; then 231 | wrapperJarPath=$(cygpath --path --windows "$wrapperJarPath") 232 | fi 233 | 234 | if command -v wget >/dev/null; then 235 | log "Found wget ... using wget" 236 | [ "$MVNW_VERBOSE" = true ] && QUIET="" || QUIET="--quiet" 237 | if [ -z "$MVNW_USERNAME" ] || [ -z "$MVNW_PASSWORD" ]; then 238 | wget $QUIET "$wrapperUrl" -O "$wrapperJarPath" || rm -f "$wrapperJarPath" 239 | else 240 | wget $QUIET --http-user="$MVNW_USERNAME" --http-password="$MVNW_PASSWORD" "$wrapperUrl" -O "$wrapperJarPath" || rm -f "$wrapperJarPath" 241 | fi 242 | elif command -v curl >/dev/null; then 243 | log "Found curl ... using curl" 244 | [ "$MVNW_VERBOSE" = true ] && QUIET="" || QUIET="--silent" 245 | if [ -z "$MVNW_USERNAME" ] || [ -z "$MVNW_PASSWORD" ]; then 246 | curl $QUIET -o "$wrapperJarPath" "$wrapperUrl" -f -L || rm -f "$wrapperJarPath" 247 | else 248 | curl $QUIET --user "$MVNW_USERNAME:$MVNW_PASSWORD" -o "$wrapperJarPath" "$wrapperUrl" -f -L || rm -f "$wrapperJarPath" 249 | fi 250 | else 251 | log "Falling back to using Java to download" 252 | javaSource="$MAVEN_PROJECTBASEDIR/.mvn/wrapper/MavenWrapperDownloader.java" 253 | javaClass="$MAVEN_PROJECTBASEDIR/.mvn/wrapper/MavenWrapperDownloader.class" 254 | # For Cygwin, switch paths to Windows format before running javac 255 | if $cygwin; then 256 | javaSource=$(cygpath --path --windows "$javaSource") 257 | javaClass=$(cygpath --path --windows "$javaClass") 258 | fi 259 | if [ -e "$javaSource" ]; then 260 | if [ ! -e "$javaClass" ]; then 261 | log " - Compiling MavenWrapperDownloader.java ..." 262 | ("$JAVA_HOME/bin/javac" "$javaSource") 263 | fi 264 | if [ -e "$javaClass" ]; then 265 | log " - Running MavenWrapperDownloader.java ..." 266 | ("$JAVA_HOME/bin/java" -cp .mvn/wrapper MavenWrapperDownloader "$wrapperUrl" "$wrapperJarPath") || rm -f "$wrapperJarPath" 267 | fi 268 | fi 269 | fi 270 | fi 271 | ########################################################################################## 272 | # End of extension 273 | ########################################################################################## 274 | 275 | # If specified, validate the SHA-256 sum of the Maven wrapper jar file 276 | wrapperSha256Sum="" 277 | while IFS="=" read -r key value; do 278 | case "$key" in wrapperSha256Sum) 279 | wrapperSha256Sum=$value 280 | break 281 | ;; 282 | esac 283 | done <"$MAVEN_PROJECTBASEDIR/.mvn/wrapper/maven-wrapper.properties" 284 | if [ -n "$wrapperSha256Sum" ]; then 285 | wrapperSha256Result=false 286 | if command -v sha256sum >/dev/null; then 287 | if echo "$wrapperSha256Sum $wrapperJarPath" | sha256sum -c >/dev/null 2>&1; then 288 | wrapperSha256Result=true 289 | fi 290 | elif command -v shasum >/dev/null; then 291 | if echo "$wrapperSha256Sum $wrapperJarPath" | shasum -a 256 -c >/dev/null 2>&1; then 292 | wrapperSha256Result=true 293 | fi 294 | else 295 | echo "Checksum validation was requested but neither 'sha256sum' or 'shasum' are available." >&2 296 | echo "Please install either command, or disable validation by removing 'wrapperSha256Sum' from your maven-wrapper.properties." >&2 297 | exit 1 298 | fi 299 | if [ $wrapperSha256Result = false ]; then 300 | echo "Error: Failed to validate Maven wrapper SHA-256, your Maven wrapper might be compromised." >&2 301 | echo "Investigate or delete $wrapperJarPath to attempt a clean download." >&2 302 | echo "If you updated your Maven version, you need to update the specified wrapperSha256Sum property." >&2 303 | exit 1 304 | fi 305 | fi 306 | 307 | MAVEN_OPTS="$(concat_lines "$MAVEN_PROJECTBASEDIR/.mvn/jvm.config") $MAVEN_OPTS" 308 | 309 | # For Cygwin, switch paths to Windows format before running java 310 | if $cygwin; then 311 | [ -n "$JAVA_HOME" ] \ 312 | && JAVA_HOME=$(cygpath --path --windows "$JAVA_HOME") 313 | [ -n "$CLASSPATH" ] \ 314 | && CLASSPATH=$(cygpath --path --windows "$CLASSPATH") 315 | [ -n "$MAVEN_PROJECTBASEDIR" ] \ 316 | && MAVEN_PROJECTBASEDIR=$(cygpath --path --windows "$MAVEN_PROJECTBASEDIR") 317 | fi 318 | 319 | # Provide a "standardized" way to retrieve the CLI args that will 320 | # work with both Windows and non-Windows executions. 321 | MAVEN_CMD_LINE_ARGS="$MAVEN_CONFIG $*" 322 | export MAVEN_CMD_LINE_ARGS 323 | 324 | WRAPPER_LAUNCHER=org.apache.maven.wrapper.MavenWrapperMain 325 | 326 | # shellcheck disable=SC2086 # safe args 327 | exec "$JAVACMD" \ 328 | $MAVEN_OPTS \ 329 | $MAVEN_DEBUG_OPTS \ 330 | -classpath "$MAVEN_PROJECTBASEDIR/.mvn/wrapper/maven-wrapper.jar" \ 331 | "-Dmaven.multiModuleProjectDirectory=${MAVEN_PROJECTBASEDIR}" \ 332 | ${WRAPPER_LAUNCHER} $MAVEN_CONFIG "$@" 333 | -------------------------------------------------------------------------------- /finish/mvnw.cmd: -------------------------------------------------------------------------------- 1 | @REM ---------------------------------------------------------------------------- 2 | @REM Licensed to the Apache Software Foundation (ASF) under one 3 | @REM or more contributor license agreements. See the NOTICE file 4 | @REM distributed with this work for additional information 5 | @REM regarding copyright ownership. The ASF licenses this file 6 | @REM to you under the Apache License, Version 2.0 (the 7 | @REM "License"); you may not use this file except in compliance 8 | @REM with the License. You may obtain a copy of the License at 9 | @REM 10 | @REM http://www.apache.org/licenses/LICENSE-2.0 11 | @REM 12 | @REM Unless required by applicable law or agreed to in writing, 13 | @REM software distributed under the License is distributed on an 14 | @REM "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 15 | @REM KIND, either express or implied. See the License for the 16 | @REM specific language governing permissions and limitations 17 | @REM under the License. 18 | @REM ---------------------------------------------------------------------------- 19 | 20 | @REM ---------------------------------------------------------------------------- 21 | @REM Apache Maven Wrapper startup batch script, version 3.3.2 22 | @REM 23 | @REM Required ENV vars: 24 | @REM JAVA_HOME - location of a JDK home dir 25 | @REM 26 | @REM Optional ENV vars 27 | @REM MAVEN_BATCH_ECHO - set to 'on' to enable the echoing of the batch commands 28 | @REM MAVEN_BATCH_PAUSE - set to 'on' to wait for a keystroke before ending 29 | @REM MAVEN_OPTS - parameters passed to the Java VM when running Maven 30 | @REM e.g. to debug Maven itself, use 31 | @REM set MAVEN_OPTS=-Xdebug -Xrunjdwp:transport=dt_socket,server=y,suspend=y,address=8000 32 | @REM MAVEN_SKIP_RC - flag to disable loading of mavenrc files 33 | @REM ---------------------------------------------------------------------------- 34 | 35 | @REM Begin all REM lines with '@' in case MAVEN_BATCH_ECHO is 'on' 36 | @echo off 37 | @REM set title of command window 38 | title %0 39 | @REM enable echoing by setting MAVEN_BATCH_ECHO to 'on' 40 | @if "%MAVEN_BATCH_ECHO%" == "on" echo %MAVEN_BATCH_ECHO% 41 | 42 | @REM set %HOME% to equivalent of $HOME 43 | if "%HOME%" == "" (set "HOME=%HOMEDRIVE%%HOMEPATH%") 44 | 45 | @REM Execute a user defined script before this one 46 | if not "%MAVEN_SKIP_RC%" == "" goto skipRcPre 47 | @REM check for pre script, once with legacy .bat ending and once with .cmd ending 48 | if exist "%USERPROFILE%\mavenrc_pre.bat" call "%USERPROFILE%\mavenrc_pre.bat" %* 49 | if exist "%USERPROFILE%\mavenrc_pre.cmd" call "%USERPROFILE%\mavenrc_pre.cmd" %* 50 | :skipRcPre 51 | 52 | @setlocal 53 | 54 | set ERROR_CODE=0 55 | 56 | @REM To isolate internal variables from possible post scripts, we use another setlocal 57 | @setlocal 58 | 59 | @REM ==== START VALIDATION ==== 60 | if not "%JAVA_HOME%" == "" goto OkJHome 61 | 62 | echo. >&2 63 | echo Error: JAVA_HOME not found in your environment. >&2 64 | echo Please set the JAVA_HOME variable in your environment to match the >&2 65 | echo location of your Java installation. >&2 66 | echo. >&2 67 | goto error 68 | 69 | :OkJHome 70 | if exist "%JAVA_HOME%\bin\java.exe" goto init 71 | 72 | echo. >&2 73 | echo Error: JAVA_HOME is set to an invalid directory. >&2 74 | echo JAVA_HOME = "%JAVA_HOME%" >&2 75 | echo Please set the JAVA_HOME variable in your environment to match the >&2 76 | echo location of your Java installation. >&2 77 | echo. >&2 78 | goto error 79 | 80 | @REM ==== END VALIDATION ==== 81 | 82 | :init 83 | 84 | @REM Find the project base dir, i.e. the directory that contains the folder ".mvn". 85 | @REM Fallback to current working directory if not found. 86 | 87 | set MAVEN_PROJECTBASEDIR=%MAVEN_BASEDIR% 88 | IF NOT "%MAVEN_PROJECTBASEDIR%"=="" goto endDetectBaseDir 89 | 90 | set EXEC_DIR=%CD% 91 | set WDIR=%EXEC_DIR% 92 | :findBaseDir 93 | IF EXIST "%WDIR%"\.mvn goto baseDirFound 94 | cd .. 95 | IF "%WDIR%"=="%CD%" goto baseDirNotFound 96 | set WDIR=%CD% 97 | goto findBaseDir 98 | 99 | :baseDirFound 100 | set MAVEN_PROJECTBASEDIR=%WDIR% 101 | cd "%EXEC_DIR%" 102 | goto endDetectBaseDir 103 | 104 | :baseDirNotFound 105 | set MAVEN_PROJECTBASEDIR=%EXEC_DIR% 106 | cd "%EXEC_DIR%" 107 | 108 | :endDetectBaseDir 109 | 110 | IF NOT EXIST "%MAVEN_PROJECTBASEDIR%\.mvn\jvm.config" goto endReadAdditionalConfig 111 | 112 | @setlocal EnableExtensions EnableDelayedExpansion 113 | for /F "usebackq delims=" %%a in ("%MAVEN_PROJECTBASEDIR%\.mvn\jvm.config") do set JVM_CONFIG_MAVEN_PROPS=!JVM_CONFIG_MAVEN_PROPS! %%a 114 | @endlocal & set JVM_CONFIG_MAVEN_PROPS=%JVM_CONFIG_MAVEN_PROPS% 115 | 116 | :endReadAdditionalConfig 117 | 118 | SET MAVEN_JAVA_EXE="%JAVA_HOME%\bin\java.exe" 119 | set WRAPPER_JAR="%MAVEN_PROJECTBASEDIR%\.mvn\wrapper\maven-wrapper.jar" 120 | set WRAPPER_LAUNCHER=org.apache.maven.wrapper.MavenWrapperMain 121 | 122 | set WRAPPER_URL="https://repo.maven.apache.org/maven2/org/apache/maven/wrapper/maven-wrapper/3.3.2/maven-wrapper-3.3.2.jar" 123 | 124 | FOR /F "usebackq tokens=1,2 delims==" %%A IN ("%MAVEN_PROJECTBASEDIR%\.mvn\wrapper\maven-wrapper.properties") DO ( 125 | IF "%%A"=="wrapperUrl" SET WRAPPER_URL=%%B 126 | ) 127 | 128 | @REM Extension to allow automatically downloading the maven-wrapper.jar from Maven-central 129 | @REM This allows using the maven wrapper in projects that prohibit checking in binary data. 130 | if exist %WRAPPER_JAR% ( 131 | if "%MVNW_VERBOSE%" == "true" ( 132 | echo Found %WRAPPER_JAR% 133 | ) 134 | ) else ( 135 | if not "%MVNW_REPOURL%" == "" ( 136 | SET WRAPPER_URL="%MVNW_REPOURL%/org/apache/maven/wrapper/maven-wrapper/3.3.2/maven-wrapper-3.3.2.jar" 137 | ) 138 | if "%MVNW_VERBOSE%" == "true" ( 139 | echo Couldn't find %WRAPPER_JAR%, downloading it ... 140 | echo Downloading from: %WRAPPER_URL% 141 | ) 142 | 143 | powershell -Command "&{"^ 144 | "$webclient = new-object System.Net.WebClient;"^ 145 | "if (-not ([string]::IsNullOrEmpty('%MVNW_USERNAME%') -and [string]::IsNullOrEmpty('%MVNW_PASSWORD%'))) {"^ 146 | "$webclient.Credentials = new-object System.Net.NetworkCredential('%MVNW_USERNAME%', '%MVNW_PASSWORD%');"^ 147 | "}"^ 148 | "[Net.ServicePointManager]::SecurityProtocol = [Net.SecurityProtocolType]::Tls12; $webclient.DownloadFile('%WRAPPER_URL%', '%WRAPPER_JAR%')"^ 149 | "}" 150 | if "%MVNW_VERBOSE%" == "true" ( 151 | echo Finished downloading %WRAPPER_JAR% 152 | ) 153 | ) 154 | @REM End of extension 155 | 156 | @REM If specified, validate the SHA-256 sum of the Maven wrapper jar file 157 | SET WRAPPER_SHA_256_SUM="" 158 | FOR /F "usebackq tokens=1,2 delims==" %%A IN ("%MAVEN_PROJECTBASEDIR%\.mvn\wrapper\maven-wrapper.properties") DO ( 159 | IF "%%A"=="wrapperSha256Sum" SET WRAPPER_SHA_256_SUM=%%B 160 | ) 161 | IF NOT %WRAPPER_SHA_256_SUM%=="" ( 162 | powershell -Command "&{"^ 163 | "Import-Module $PSHOME\Modules\Microsoft.PowerShell.Utility -Function Get-FileHash;"^ 164 | "$hash = (Get-FileHash \"%WRAPPER_JAR%\" -Algorithm SHA256).Hash.ToLower();"^ 165 | "If('%WRAPPER_SHA_256_SUM%' -ne $hash){"^ 166 | " Write-Error 'Error: Failed to validate Maven wrapper SHA-256, your Maven wrapper might be compromised.';"^ 167 | " Write-Error 'Investigate or delete %WRAPPER_JAR% to attempt a clean download.';"^ 168 | " Write-Error 'If you updated your Maven version, you need to update the specified wrapperSha256Sum property.';"^ 169 | " exit 1;"^ 170 | "}"^ 171 | "}" 172 | if ERRORLEVEL 1 goto error 173 | ) 174 | 175 | @REM Provide a "standardized" way to retrieve the CLI args that will 176 | @REM work with both Windows and non-Windows executions. 177 | set MAVEN_CMD_LINE_ARGS=%* 178 | 179 | %MAVEN_JAVA_EXE% ^ 180 | %JVM_CONFIG_MAVEN_PROPS% ^ 181 | %MAVEN_OPTS% ^ 182 | %MAVEN_DEBUG_OPTS% ^ 183 | -classpath %WRAPPER_JAR% ^ 184 | "-Dmaven.multiModuleProjectDirectory=%MAVEN_PROJECTBASEDIR%" ^ 185 | %WRAPPER_LAUNCHER% %MAVEN_CONFIG% %* 186 | if ERRORLEVEL 1 goto error 187 | goto end 188 | 189 | :error 190 | set ERROR_CODE=1 191 | 192 | :end 193 | @endlocal & set ERROR_CODE=%ERROR_CODE% 194 | 195 | if not "%MAVEN_SKIP_RC%"=="" goto skipRcPost 196 | @REM check for post script, once with legacy .bat ending and once with .cmd ending 197 | if exist "%USERPROFILE%\mavenrc_post.bat" call "%USERPROFILE%\mavenrc_post.bat" 198 | if exist "%USERPROFILE%\mavenrc_post.cmd" call "%USERPROFILE%\mavenrc_post.cmd" 199 | :skipRcPost 200 | 201 | @REM pause the script if MAVEN_BATCH_PAUSE is set to 'on' 202 | if "%MAVEN_BATCH_PAUSE%"=="on" pause 203 | 204 | if "%MAVEN_TERMINATE_CMD%"=="on" exit %ERROR_CODE% 205 | 206 | cmd /C exit /B %ERROR_CODE% 207 | -------------------------------------------------------------------------------- /finish/pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 4.0.0 5 | 6 | io.openliberty.guides 7 | guide-microprofile-config 8 | 1.0-SNAPSHOT 9 | war 10 | 11 | 12 | UTF-8 13 | UTF-8 14 | 11 15 | 11 16 | 17 | 9080 18 | 9443 19 | 20 | 21 | 22 | 23 | 24 | jakarta.platform 25 | jakarta.jakartaee-api 26 | 10.0.0 27 | provided 28 | 29 | 30 | 31 | org.eclipse.microprofile 32 | microprofile 33 | 7.0 34 | pom 35 | provided 36 | 37 | 38 | 39 | 40 | org.junit.jupiter 41 | junit-jupiter 42 | 5.13.0 43 | test 44 | 45 | 46 | org.jboss.resteasy 47 | resteasy-client 48 | 6.2.12.Final 49 | test 50 | 51 | 52 | org.jboss.resteasy 53 | resteasy-json-binding-provider 54 | 6.2.12.Final 55 | test 56 | 57 | 58 | org.glassfish 59 | jakarta.json 60 | 2.0.1 61 | test 62 | 63 | 64 | 65 | 66 | ${project.artifactId} 67 | 68 | 69 | org.apache.maven.plugins 70 | maven-war-plugin 71 | 3.4.0 72 | 73 | 74 | 75 | org.apache.maven.plugins 76 | maven-surefire-plugin 77 | 3.5.3 78 | 79 | 80 | 81 | io.openliberty.tools 82 | liberty-maven-plugin 83 | 3.11.3 84 | 85 | 86 | 87 | org.apache.maven.plugins 88 | maven-failsafe-plugin 89 | 3.5.3 90 | 91 | 92 | ${liberty.var.http.port} 93 | ${liberty.var.https.port} 94 | 95 | 96 | 97 | 98 | 99 | 100 | -------------------------------------------------------------------------------- /finish/resources/CustomConfigSource.json: -------------------------------------------------------------------------------- 1 | { 2 | "config_ordinal": 150, 3 | "io_openliberty_guides_email": "admin@guides.openliberty.io", 4 | "io_openliberty_guides_inventory_inMaintenance": false, 5 | "io_openliberty_guides_system_inMaintenance": false, 6 | "io_openliberty_guides_testConfigOverwrite": "CustomSource" 7 | } -------------------------------------------------------------------------------- /finish/src/main/java/io/openliberty/guides/config/ConfigApplication.java: -------------------------------------------------------------------------------- 1 | // tag::copyright[] 2 | /******************************************************************************* 3 | * Copyright (c) 2017, 2022 IBM Corporation and others. 4 | * All rights reserved. This program and the accompanying materials 5 | * are made available under the terms of the Eclipse Public License 2.0 6 | * which accompanies this distribution, and is available at 7 | * http://www.eclipse.org/legal/epl-2.0/ 8 | * 9 | * SPDX-License-Identifier: EPL-2.0 10 | *******************************************************************************/ 11 | // end::copyright[] 12 | package io.openliberty.guides.config; 13 | 14 | // JAX-RS 15 | import jakarta.ws.rs.ApplicationPath; 16 | import jakarta.ws.rs.core.Application; 17 | 18 | @ApplicationPath("config") 19 | public class ConfigApplication extends Application { 20 | 21 | } 22 | -------------------------------------------------------------------------------- /finish/src/main/java/io/openliberty/guides/config/ConfigResource.java: -------------------------------------------------------------------------------- 1 | // tag::copyright[] 2 | /******************************************************************************* 3 | * Copyright (c) 2017, 2022 IBM Corporation and others. 4 | * All rights reserved. This program and the accompanying materials 5 | * are made available under the terms of the Eclipse Public License 2.0 6 | * which accompanies this distribution, and is available at 7 | * http://www.eclipse.org/legal/epl-2.0/ 8 | * 9 | * SPDX-License-Identifier: EPL-2.0 10 | *******************************************************************************/ 11 | // end::copyright[] 12 | package io.openliberty.guides.config; 13 | 14 | import jakarta.enterprise.context.RequestScoped; 15 | import jakarta.ws.rs.core.MediaType; 16 | 17 | import jakarta.json.JsonObject; 18 | import jakarta.json.JsonObjectBuilder; 19 | import jakarta.json.Json; 20 | import jakarta.inject.Inject; 21 | import jakarta.ws.rs.GET; 22 | import jakarta.ws.rs.Path; 23 | import jakarta.ws.rs.Produces; 24 | 25 | import org.eclipse.microprofile.config.Config; 26 | import org.eclipse.microprofile.config.spi.ConfigSource; 27 | 28 | @RequestScoped 29 | @Path("/") 30 | public class ConfigResource { 31 | 32 | // tag::config[] 33 | @Inject 34 | private Config config; 35 | // end::config[] 36 | 37 | @GET 38 | @Produces(MediaType.APPLICATION_JSON) 39 | public JsonObject getAllConfig() { 40 | JsonObjectBuilder builder = Json.createObjectBuilder(); 41 | return builder.add("ConfigSources", sourceJsonBuilder()) 42 | .add("ConfigProperties", propertyJsonBuilder()).build(); 43 | } 44 | 45 | public JsonObject sourceJsonBuilder() { 46 | JsonObjectBuilder sourcesBuilder = Json.createObjectBuilder(); 47 | for (ConfigSource source : config.getConfigSources()) { 48 | sourcesBuilder.add(source.getName(), source.getOrdinal()); 49 | } 50 | return sourcesBuilder.build(); 51 | } 52 | 53 | public JsonObject propertyJsonBuilder() { 54 | JsonObjectBuilder propertiesBuilder = Json.createObjectBuilder(); 55 | for (String name : config.getPropertyNames()) { 56 | if (name.contains("io_openliberty_guides")) { 57 | propertiesBuilder.add(name, config.getValue(name, String.class)); 58 | } 59 | } 60 | return propertiesBuilder.build(); 61 | } 62 | 63 | } 64 | -------------------------------------------------------------------------------- /finish/src/main/java/io/openliberty/guides/config/CustomConfigSource.java: -------------------------------------------------------------------------------- 1 | // tag::copyright[] 2 | /******************************************************************************* 3 | * Copyright (c) 2017, 2022 IBM Corporation and others. 4 | * All rights reserved. This program and the accompanying materials 5 | * are made available under the terms of the Eclipse Public License 2.0 6 | * which accompanies this distribution, and is available at 7 | * http://www.eclipse.org/legal/epl-2.0/ 8 | * 9 | * SPDX-License-Identifier: EPL-2.0 10 | *******************************************************************************/ 11 | // end::copyright[] 12 | // tag::customConfig[] 13 | package io.openliberty.guides.config; 14 | 15 | import jakarta.json.stream.JsonParser; 16 | import jakarta.json.stream.JsonParser.Event; 17 | import jakarta.json.Json; 18 | import java.math.BigDecimal; 19 | import java.io.StringReader; 20 | import java.util.HashMap; 21 | import java.util.Map; 22 | import java.util.Set; 23 | 24 | import java.io.BufferedReader; 25 | import java.io.FileReader; 26 | import org.eclipse.microprofile.config.spi.ConfigSource; 27 | 28 | /** 29 | * User-provided ConfigSources are dynamic. 30 | * The getProperties() method will be periodically invoked by the runtime 31 | * to retrieve up-to-date values. The frequency is controlled by 32 | * the microprofile.config.refresh.rate Java system property, 33 | * which is in milliseconds and can be customized. 34 | */ 35 | public class CustomConfigSource implements ConfigSource { 36 | 37 | String fileLocation = System.getProperty("user.dir").split("target")[0] 38 | + "resources/CustomConfigSource.json"; 39 | 40 | @Override 41 | public int getOrdinal() { 42 | return Integer.parseInt(getProperties().get("config_ordinal")); 43 | } 44 | 45 | @Override 46 | public Set getPropertyNames() { 47 | return getProperties().keySet(); 48 | } 49 | 50 | @Override 51 | public String getValue(String key) { 52 | return getProperties().get(key); 53 | } 54 | 55 | @Override 56 | public String getName() { 57 | return "Custom Config Source: file:" + this.fileLocation; 58 | } 59 | 60 | // tag::getProperties[] 61 | public Map getProperties() { 62 | Map m = new HashMap(); 63 | String jsonData = this.readFile(this.fileLocation); 64 | JsonParser parser = Json.createParser(new StringReader(jsonData)); 65 | String key = null; 66 | while (parser.hasNext()) { 67 | final Event event = parser.next(); 68 | switch (event) { 69 | case KEY_NAME: 70 | key = parser.getString(); 71 | break; 72 | case VALUE_STRING: 73 | String string = parser.getString(); 74 | m.put(key, string); 75 | break; 76 | case VALUE_NUMBER: 77 | BigDecimal number = parser.getBigDecimal(); 78 | m.put(key, number.toString()); 79 | break; 80 | case VALUE_TRUE: 81 | m.put(key, "true"); 82 | break; 83 | case VALUE_FALSE: 84 | m.put(key, "false"); 85 | break; 86 | default: 87 | break; 88 | } 89 | } 90 | parser.close(); 91 | return m; 92 | } 93 | // end::getProperties[] 94 | 95 | public String readFile(String fileName) { 96 | String result = ""; 97 | try { 98 | BufferedReader br = new BufferedReader(new FileReader(fileName)); 99 | StringBuilder sb = new StringBuilder(); 100 | String line = br.readLine(); 101 | while (line != null) { 102 | sb.append(line); 103 | line = br.readLine(); 104 | } 105 | result = sb.toString(); 106 | br.close(); 107 | } catch (Exception e) { 108 | e.printStackTrace(); 109 | } 110 | return result; 111 | } 112 | } 113 | // end::customConfig[] 114 | -------------------------------------------------------------------------------- /finish/src/main/java/io/openliberty/guides/config/CustomEmailConverter.java: -------------------------------------------------------------------------------- 1 | // tag::copyright[] 2 | /******************************************************************************* 3 | * Copyright (c) 2017, 2023 IBM Corporation and others. 4 | * All rights reserved. This program and the accompanying materials 5 | * are made available under the terms of the Eclipse Public License 2.0 6 | * which accompanies this distribution, and is available at 7 | * http://www.eclipse.org/legal/epl-2.0/ 8 | * 9 | * SPDX-License-Identifier: EPL-2.0 10 | *******************************************************************************/ 11 | // end::copyright[] 12 | package io.openliberty.guides.config; 13 | 14 | import org.eclipse.microprofile.config.spi.Converter; 15 | 16 | // tag::customConfig[] 17 | public class CustomEmailConverter implements Converter { 18 | 19 | @Override 20 | public Email convert(String value) { 21 | return new Email(value); 22 | } 23 | 24 | } 25 | // end::customConfig[] 26 | -------------------------------------------------------------------------------- /finish/src/main/java/io/openliberty/guides/config/Email.java: -------------------------------------------------------------------------------- 1 | // tag::copyright[] 2 | /******************************************************************************* 3 | * Copyright (c) 2017, 2019 IBM Corporation and others. 4 | * All rights reserved. This program and the accompanying materials 5 | * are made available under the terms of the Eclipse Public License 2.0 6 | * which accompanies this distribution, and is available at 7 | * http://www.eclipse.org/legal/epl-2.0/ 8 | * 9 | * SPDX-License-Identifier: EPL-2.0 10 | *******************************************************************************/ 11 | // end::copyright[] 12 | 13 | package io.openliberty.guides.config; 14 | 15 | // tag::email[] 16 | public class Email { 17 | private String name; 18 | private String domain; 19 | 20 | public Email(String value) { 21 | String[] components = value.split("@"); 22 | if (components.length == 2) { 23 | name = components[0]; 24 | domain = components[1]; 25 | } 26 | } 27 | 28 | public String getEmailName() { 29 | return name; 30 | } 31 | 32 | public String getEmailDomain() { 33 | return domain; 34 | } 35 | 36 | public String toString() { 37 | return name + "@" + domain; 38 | } 39 | } 40 | // end::email[] 41 | -------------------------------------------------------------------------------- /finish/src/main/java/io/openliberty/guides/inventory/InventoryApplication.java: -------------------------------------------------------------------------------- 1 | // tag::copyright[] 2 | /******************************************************************************* 3 | * Copyright (c) 2017, 2022 IBM Corporation and others. 4 | * All rights reserved. This program and the accompanying materials 5 | * are made available under the terms of the Eclipse Public License 2.0 6 | * which accompanies this distribution, and is available at 7 | * http://www.eclipse.org/legal/epl-2.0/ 8 | * 9 | * SPDX-License-Identifier: EPL-2.0 10 | *******************************************************************************/ 11 | // end::copyright[] 12 | package io.openliberty.guides.inventory; 13 | 14 | // JAX-RS 15 | import jakarta.ws.rs.ApplicationPath; 16 | import jakarta.ws.rs.core.Application; 17 | 18 | @ApplicationPath("inventory") 19 | public class InventoryApplication extends Application { 20 | 21 | } 22 | -------------------------------------------------------------------------------- /finish/src/main/java/io/openliberty/guides/inventory/InventoryConfig.java: -------------------------------------------------------------------------------- 1 | // tag::copyright[] 2 | /******************************************************************************* 3 | * Copyright (c) 2017, 2022 IBM Corporation and others. 4 | * All rights reserved. This program and the accompanying materials 5 | * are made available under the terms of the Eclipse Public License 2.0 6 | * which accompanies this distribution, and is available at 7 | * http://www.eclipse.org/legal/epl-2.0/ 8 | * 9 | * SPDX-License-Identifier: EPL-2.0 10 | *******************************************************************************/ 11 | // end::copyright[] 12 | // tag::config-class[] 13 | package io.openliberty.guides.inventory; 14 | 15 | import jakarta.enterprise.context.RequestScoped; 16 | import jakarta.inject.Inject; 17 | import jakarta.inject.Provider; 18 | import org.eclipse.microprofile.config.inject.ConfigProperty; 19 | import io.openliberty.guides.config.Email; 20 | 21 | @RequestScoped 22 | public class InventoryConfig { 23 | 24 | // tag::port-number[] 25 | // tag::inject-port-number[] 26 | @Inject 27 | // end::inject-port-number[] 28 | // tag::guides-port-number[] 29 | @ConfigProperty(name = "io_openliberty_guides_port_number") 30 | // end::guides-port-number[] 31 | private int portNumber; 32 | 33 | // end::port-number[] 34 | // tag::build-in-converter[] 35 | // tag::inject-inMaintenance[] 36 | // tag::inject[] 37 | @Inject 38 | // end::inject[] 39 | // tag::configPropety[] 40 | @ConfigProperty(name = "io_openliberty_guides_inventory_inMaintenance") 41 | // end::configPropety[] 42 | // end::inject-inMaintenance[] 43 | private Provider inMaintenance; 44 | 45 | // end::build-in-converter[] 46 | // tag::custom-converter[] 47 | @Inject 48 | @ConfigProperty(name = "io_openliberty_guides_email") 49 | private Provider email; 50 | // end::custom-converter[] 51 | 52 | // tag::getPortNumber[] 53 | public int getPortNumber() { 54 | return portNumber; 55 | } 56 | // end::getPortNumber[] 57 | 58 | // tag::isInMaintenance[] 59 | public boolean isInMaintenance() { 60 | // tag::inMaintenanceGet[] 61 | return inMaintenance.get(); 62 | // end::inMaintenanceGet[] 63 | } 64 | // end::isInMaintenance[] 65 | 66 | // tag::getEmail[] 67 | public Email getEmail() { 68 | return email.get(); 69 | } 70 | // end::getEmail[] 71 | } 72 | // end::config-class[] 73 | -------------------------------------------------------------------------------- /finish/src/main/java/io/openliberty/guides/inventory/InventoryManager.java: -------------------------------------------------------------------------------- 1 | // tag::copyright[] 2 | /******************************************************************************* 3 | * Copyright (c) 2017, 2022 IBM Corporation and others. 4 | * All rights reserved. This program and the accompanying materials 5 | * are made available under the terms of the Eclipse Public License 2.0 6 | * which accompanies this distribution, and is available at 7 | * http://www.eclipse.org/legal/epl-2.0/ 8 | * 9 | * SPDX-License-Identifier: EPL-2.0 10 | *******************************************************************************/ 11 | // end::copyright[] 12 | // tag::manager[] 13 | package io.openliberty.guides.inventory; 14 | 15 | import java.util.ArrayList; 16 | import java.util.Collections; 17 | import java.util.List; 18 | import java.util.Properties; 19 | import jakarta.enterprise.context.ApplicationScoped; 20 | import io.openliberty.guides.inventory.model.InventoryList; 21 | import io.openliberty.guides.inventory.model.SystemData; 22 | 23 | @ApplicationScoped 24 | public class InventoryManager { 25 | 26 | private List systems = Collections.synchronizedList(new ArrayList<>()); 27 | private InventoryUtils invUtils = new InventoryUtils(); 28 | 29 | public Properties get(String hostname, int portNumber) { 30 | return invUtils.getProperties(hostname, portNumber); 31 | } 32 | 33 | public void add(String hostname, Properties systemProps) { 34 | Properties props = new Properties(); 35 | props.setProperty("os.name", systemProps.getProperty("os.name")); 36 | props.setProperty("user.name", systemProps.getProperty("user.name")); 37 | 38 | SystemData system = new SystemData(hostname, props); 39 | if (!systems.contains(system)) { 40 | systems.add(system); 41 | } 42 | } 43 | 44 | public InventoryList list() { 45 | return new InventoryList(systems); 46 | } 47 | 48 | } 49 | // end::manager[] 50 | -------------------------------------------------------------------------------- /finish/src/main/java/io/openliberty/guides/inventory/InventoryResource.java: -------------------------------------------------------------------------------- 1 | // tag::copyright[] 2 | /******************************************************************************* 3 | * Copyright (c) 2017, 2022 IBM Corporation and others. 4 | * All rights reserved. This program and the accompanying materials 5 | * are made available under the terms of the Eclipse Public License 2.0 6 | * which accompanies this distribution, and is available at 7 | * http://www.eclipse.org/legal/epl-2.0/ 8 | * 9 | * SPDX-License-Identifier: EPL-2.0 10 | *******************************************************************************/ 11 | // end::copyright[] 12 | // tag::config-methods[] 13 | package io.openliberty.guides.inventory; 14 | 15 | import java.util.Properties; 16 | 17 | // CDI 18 | import jakarta.enterprise.context.RequestScoped; 19 | import jakarta.inject.Inject; 20 | import jakarta.ws.rs.GET; 21 | import jakarta.ws.rs.Path; 22 | import jakarta.ws.rs.PathParam; 23 | import jakarta.ws.rs.Produces; 24 | import jakarta.ws.rs.core.MediaType; 25 | import jakarta.ws.rs.core.Response; 26 | 27 | 28 | 29 | @RequestScoped 30 | @Path("systems") 31 | public class InventoryResource { 32 | 33 | @Inject 34 | InventoryManager manager; 35 | 36 | // tag::config-injection[] 37 | @Inject 38 | InventoryConfig inventoryConfig; 39 | // end::config-injection[] 40 | 41 | @GET 42 | @Path("{hostname}") 43 | @Produces(MediaType.APPLICATION_JSON) 44 | public Response getPropertiesForHost(@PathParam("hostname") String hostname) { 45 | 46 | if (!inventoryConfig.isInMaintenance()) { 47 | // tag::config-port[] 48 | Properties props = manager.get(hostname, inventoryConfig.getPortNumber()); 49 | // end::config-port[] 50 | if (props == null) { 51 | return Response.status(Response.Status.NOT_FOUND) 52 | .entity("{ \"error\" : \"Unknown hostname or the system service " 53 | + "may not be running on " + hostname + "\" }") 54 | .build(); 55 | } 56 | 57 | // Add to inventory 58 | manager.add(hostname, props); 59 | return Response.ok(props).build(); 60 | } else { 61 | // tag::email[] 62 | return Response.status(Response.Status.SERVICE_UNAVAILABLE) 63 | .entity("{ \"error\" : \"Service is currently in maintenance. " 64 | + "Contact: " + inventoryConfig.getEmail().toString() + "\" }") 65 | .build(); 66 | // end::email[] 67 | } 68 | } 69 | 70 | @GET 71 | @Produces(MediaType.APPLICATION_JSON) 72 | public Response listContents() { 73 | // tag::isInMaintenance[] 74 | if (!inventoryConfig.isInMaintenance()) { 75 | // end::isInMaintenance[] 76 | return Response.ok(manager.list()).build(); 77 | } else { 78 | // tag::email[] 79 | return Response.status(Response.Status.SERVICE_UNAVAILABLE) 80 | .entity("{ \"error\" : \"Service is currently in maintenance. " 81 | + "Contact: " + inventoryConfig.getEmail().toString() + "\" }") 82 | .build(); 83 | // end::getEmail[] 84 | } 85 | } 86 | 87 | } 88 | 89 | // end::config-methods[] 90 | -------------------------------------------------------------------------------- /finish/src/main/java/io/openliberty/guides/inventory/InventoryUtils.java: -------------------------------------------------------------------------------- 1 | // tag::copyright[] 2 | /******************************************************************************* 3 | * Copyright (c) 2017, 2022 IBM Corporation and others. 4 | * All rights reserved. This program and the accompanying materials 5 | * are made available under the terms of the Eclipse Public License 2.0 6 | * which accompanies this distribution, and is available at 7 | * http://www.eclipse.org/legal/epl-2.0/ 8 | * 9 | * SPDX-License-Identifier: EPL-2.0 10 | *******************************************************************************/ 11 | // end::copyright[] 12 | package io.openliberty.guides.inventory; 13 | 14 | import java.net.MalformedURLException; 15 | import java.net.URL; 16 | import java.net.UnknownHostException; 17 | import java.util.Properties; 18 | 19 | import org.eclipse.microprofile.rest.client.RestClientBuilder; 20 | 21 | import io.openliberty.guides.inventory.client.SystemClient; 22 | import io.openliberty.guides.inventory.client.UnknownUrlException; 23 | import jakarta.ws.rs.ProcessingException; 24 | 25 | public class InventoryUtils { 26 | 27 | // tag::builder[] 28 | public Properties getProperties(String hostname, int portNumber) { 29 | String customURLString = "http://" + hostname + ":" + portNumber + "/system"; 30 | URL customURL = null; 31 | try { 32 | customURL = new URL(customURLString); 33 | SystemClient customRestClient = RestClientBuilder.newBuilder() 34 | .baseUrl(customURL) 35 | .build(SystemClient.class); 36 | return customRestClient.getProperties(); 37 | } catch (ProcessingException ex) { 38 | handleProcessingException(ex); 39 | } catch (UnknownUrlException e) { 40 | System.err.println("The given URL is unreachable."); 41 | } catch (MalformedURLException e) { 42 | System.err.println("The given URL is not formatted correctly."); 43 | } 44 | return null; 45 | } 46 | // end::builder[] 47 | 48 | public void handleProcessingException(ProcessingException ex) { 49 | Throwable rootEx = ex; 50 | while (rootEx.getCause() != null) { 51 | rootEx = rootEx.getCause(); 52 | } 53 | if (rootEx != null && rootEx instanceof UnknownHostException) { 54 | System.err.println("The specified host is unknown."); 55 | } else { 56 | throw ex; 57 | } 58 | } 59 | 60 | } 61 | -------------------------------------------------------------------------------- /finish/src/main/java/io/openliberty/guides/inventory/client/SystemClient.java: -------------------------------------------------------------------------------- 1 | // tag::copyright[] 2 | /******************************************************************************* 3 | * Copyright (c) 2017, 2022 IBM Corporation and others. 4 | * All rights reserved. This program and the accompanying materials 5 | * are made available under the terms of the Eclipse Public License 2.0 6 | * which accompanies this distribution, and is available at 7 | * http://www.eclipse.org/legal/epl-2.0/ 8 | * 9 | * SPDX-License-Identifier: EPL-2.0 10 | *******************************************************************************/ 11 | // end::copyright[] 12 | // tag::client[] 13 | package io.openliberty.guides.inventory.client; 14 | 15 | import java.util.Properties; 16 | 17 | import jakarta.ws.rs.GET; 18 | import jakarta.ws.rs.Path; 19 | import jakarta.ws.rs.ProcessingException; 20 | import jakarta.ws.rs.Produces; 21 | import jakarta.ws.rs.core.MediaType; 22 | 23 | import org.eclipse.microprofile.rest.client.annotation.RegisterProvider; 24 | import org.eclipse.microprofile.rest.client.inject.RegisterRestClient; 25 | 26 | // tag::annotations[] 27 | 28 | @RegisterRestClient 29 | @RegisterProvider(UnknownUrlExceptionMapper.class) 30 | @Path("/properties") 31 | public interface SystemClient { 32 | // end::annotations[] 33 | @GET 34 | @Produces(MediaType.APPLICATION_JSON) 35 | Properties getProperties() throws UnknownUrlException, ProcessingException; 36 | } 37 | // end::client[] 38 | -------------------------------------------------------------------------------- /finish/src/main/java/io/openliberty/guides/inventory/client/UnknownUrlException.java: -------------------------------------------------------------------------------- 1 | // tag::copyright[] 2 | /******************************************************************************* 3 | * Copyright (c) 2017, 2018 IBM Corporation and others. 4 | * All rights reserved. This program and the accompanying materials 5 | * are made available under the terms of the Eclipse Public License 2.0 6 | * which accompanies this distribution, and is available at 7 | * http://www.eclipse.org/legal/epl-2.0/ 8 | * 9 | * SPDX-License-Identifier: EPL-2.0 10 | *******************************************************************************/ 11 | // end::copyright[] 12 | // tag::exception[] 13 | package io.openliberty.guides.inventory.client; 14 | 15 | public class UnknownUrlException extends Exception { 16 | 17 | private static final long serialVersionUID = 1L; 18 | 19 | public UnknownUrlException() { 20 | super(); 21 | } 22 | 23 | public UnknownUrlException(String message) { 24 | super(message); 25 | } 26 | } 27 | // end::exception[] 28 | -------------------------------------------------------------------------------- /finish/src/main/java/io/openliberty/guides/inventory/client/UnknownUrlExceptionMapper.java: -------------------------------------------------------------------------------- 1 | // tag::copyright[] 2 | /******************************************************************************* 3 | * Copyright (c) 2017, 2022 IBM Corporation and others. 4 | * All rights reserved. This program and the accompanying materials 5 | * are made available under the terms of the Eclipse Public License 2.0 6 | * which accompanies this distribution, and is available at 7 | * http://www.eclipse.org/legal/epl-2.0/ 8 | * 9 | * SPDX-License-Identifier: EPL-2.0 10 | *******************************************************************************/ 11 | // end::copyright[] 12 | // tag::mapper[] 13 | package io.openliberty.guides.inventory.client; 14 | 15 | import java.util.logging.Logger; 16 | import jakarta.ws.rs.core.MultivaluedMap; 17 | import jakarta.ws.rs.core.Response; 18 | import jakarta.ws.rs.ext.Provider; 19 | import org.eclipse.microprofile.rest.client.ext.ResponseExceptionMapper; 20 | 21 | @Provider 22 | public class UnknownUrlExceptionMapper 23 | implements ResponseExceptionMapper { 24 | Logger LOG = Logger.getLogger(UnknownUrlExceptionMapper.class.getName()); 25 | 26 | @Override 27 | public boolean handles(int status, MultivaluedMap headers) { 28 | LOG.info("status = " + status); 29 | return status == 404; 30 | } 31 | 32 | @Override 33 | public UnknownUrlException toThrowable(Response response) { 34 | return new UnknownUrlException(); 35 | } 36 | } 37 | // end::mapper[] 38 | -------------------------------------------------------------------------------- /finish/src/main/java/io/openliberty/guides/inventory/model/InventoryList.java: -------------------------------------------------------------------------------- 1 | // tag::copyright[] 2 | /******************************************************************************* 3 | * Copyright (c) 2017, 2018 IBM Corporation and others. 4 | * All rights reserved. This program and the accompanying materials 5 | * are made available under the terms of the Eclipse Public License 2.0 6 | * which accompanies this distribution, and is available at 7 | * http://www.eclipse.org/legal/epl-2.0/ 8 | * 9 | * SPDX-License-Identifier: EPL-2.0 10 | *******************************************************************************/ 11 | // end::copyright[] 12 | package io.openliberty.guides.inventory.model; 13 | 14 | import java.util.List; 15 | 16 | public class InventoryList { 17 | 18 | private List systems; 19 | 20 | public InventoryList(List systems) { 21 | this.systems = systems; 22 | } 23 | 24 | public List getSystems() { 25 | return systems; 26 | } 27 | 28 | public int getTotal() { 29 | return systems.size(); 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /finish/src/main/java/io/openliberty/guides/inventory/model/SystemData.java: -------------------------------------------------------------------------------- 1 | // tag::copyright[] 2 | /******************************************************************************* 3 | * Copyright (c) 2017, 2018 IBM Corporation and others. 4 | * All rights reserved. This program and the accompanying materials 5 | * are made available under the terms of the Eclipse Public License 2.0 6 | * which accompanies this distribution, and is available at 7 | * http://www.eclipse.org/legal/epl-2.0/ 8 | * 9 | * SPDX-License-Identifier: EPL-2.0 10 | *******************************************************************************/ 11 | // end::copyright[] 12 | package io.openliberty.guides.inventory.model; 13 | 14 | import java.util.Properties; 15 | 16 | public class SystemData { 17 | 18 | private final String hostname; 19 | private final Properties properties; 20 | 21 | public SystemData(String hostname, Properties properties) { 22 | this.hostname = hostname; 23 | this.properties = properties; 24 | } 25 | 26 | public String getHostname() { 27 | return hostname; 28 | } 29 | 30 | public Properties getProperties() { 31 | return properties; 32 | } 33 | 34 | @Override 35 | public boolean equals(Object host) { 36 | if (host instanceof SystemData) { 37 | return hostname.equals(((SystemData) host).getHostname()); 38 | } 39 | return false; 40 | } 41 | } 42 | -------------------------------------------------------------------------------- /finish/src/main/java/io/openliberty/guides/system/SystemApplication.java: -------------------------------------------------------------------------------- 1 | // tag::copyright[] 2 | /******************************************************************************* 3 | * Copyright (c) 2017, 2022 IBM Corporation and others. 4 | * All rights reserved. This program and the accompanying materials 5 | * are made available under the terms of the Eclipse Public License 2.0 6 | * which accompanies this distribution, and is available at 7 | * http://www.eclipse.org/legal/epl-2.0/ 8 | * 9 | * SPDX-License-Identifier: EPL-2.0 10 | *******************************************************************************/ 11 | // end::copyright[] 12 | package io.openliberty.guides.system; 13 | 14 | // JAX-RS 15 | import jakarta.ws.rs.core.Application; 16 | import jakarta.ws.rs.ApplicationPath; 17 | 18 | @ApplicationPath("system") 19 | public class SystemApplication extends Application { 20 | 21 | } 22 | -------------------------------------------------------------------------------- /finish/src/main/java/io/openliberty/guides/system/SystemConfig.java: -------------------------------------------------------------------------------- 1 | // tag::copyright[] 2 | /******************************************************************************* 3 | * Copyright (c) 2017, 2022 IBM Corporation and others. 4 | * All rights reserved. This program and the accompanying materials 5 | * are made available under the terms of the Eclipse Public License 2.0 6 | * which accompanies this distribution, and is available at 7 | * http://www.eclipse.org/legal/epl-2.0/ 8 | * 9 | * SPDX-License-Identifier: EPL-2.0 10 | *******************************************************************************/ 11 | // end::copyright[] 12 | package io.openliberty.guides.system; 13 | 14 | import jakarta.enterprise.context.RequestScoped; 15 | import jakarta.inject.Inject; 16 | 17 | import jakarta.inject.Provider; 18 | import org.eclipse.microprofile.config.inject.ConfigProperty; 19 | import io.openliberty.guides.config.Email; 20 | 21 | @RequestScoped 22 | public class SystemConfig { 23 | 24 | // tag::config[] 25 | @Inject 26 | @ConfigProperty(name = "io_openliberty_guides_system_inMaintenance") 27 | Provider inMaintenance; 28 | // end::config[] 29 | 30 | // tag::custom-converter[] 31 | @Inject 32 | @ConfigProperty(name = "io_openliberty_guides_email") 33 | private Provider email; 34 | // end::custom-converter[] 35 | 36 | public boolean isInMaintenance() { 37 | return inMaintenance.get(); 38 | } 39 | 40 | // tag::getEmail[] 41 | public Email getEmail() { 42 | return email.get(); 43 | } 44 | // end::getEmail[] 45 | 46 | } 47 | -------------------------------------------------------------------------------- /finish/src/main/java/io/openliberty/guides/system/SystemResource.java: -------------------------------------------------------------------------------- 1 | // tag::copyright[] 2 | /******************************************************************************* 3 | * Copyright (c) 2017, 2022 IBM Corporation and others. 4 | * All rights reserved. This program and the accompanying materials 5 | * are made available under the terms of the Eclipse Public License 2.0 6 | * which accompanies this distribution, and is available at 7 | * http://www.eclipse.org/legal/epl-2.0/ 8 | * 9 | * SPDX-License-Identifier: EPL-2.0 10 | *******************************************************************************/ 11 | // end::copyright[] 12 | package io.openliberty.guides.system; 13 | 14 | // CDI 15 | import jakarta.enterprise.context.RequestScoped; 16 | import jakarta.ws.rs.GET; 17 | import jakarta.inject.Inject; 18 | import jakarta.ws.rs.core.Response; 19 | 20 | // JAX-RS 21 | import jakarta.ws.rs.Path; 22 | import jakarta.ws.rs.Produces; 23 | import jakarta.ws.rs.core.MediaType; 24 | 25 | @RequestScoped 26 | @Path("properties") 27 | public class SystemResource { 28 | 29 | // tag::config-injection[] 30 | @Inject 31 | SystemConfig systemConfig; 32 | // end::config-injection[] 33 | 34 | @GET 35 | @Produces(MediaType.APPLICATION_JSON) 36 | public Response getProperties() { 37 | if (!systemConfig.isInMaintenance()) { 38 | return Response.ok(System.getProperties()).build(); 39 | } else { 40 | return Response.status(Response.Status.SERVICE_UNAVAILABLE) 41 | .entity("ERROR: Service is currently in maintenance. Contact: " 42 | + systemConfig.getEmail().toString()) 43 | .build(); 44 | } 45 | } 46 | 47 | } 48 | -------------------------------------------------------------------------------- /finish/src/main/liberty/config/server.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | jakartaee-10.0 5 | microprofile-7.0 6 | restfulWS 7 | jsonb 8 | jsonp 9 | cdi 10 | mpRestClient 11 | 12 | mpConfig 13 | 14 | 15 | 16 | 17 | 18 | 19 | 21 | 22 | 24 | 25 | -------------------------------------------------------------------------------- /finish/src/main/resources/META-INF/microprofile-config.properties: -------------------------------------------------------------------------------- 1 | # tag::all-props[] 2 | # tag::ordinal[] 3 | config_ordinal=100 4 | # end::ordinal[] 5 | # tag::inventory-port-number[] 6 | io_openliberty_guides_port_number=9080 7 | # end::inventory-port-number[] 8 | # tag::inventory-in-maintenance[] 9 | io_openliberty_guides_inventory_inMaintenance=false 10 | # end::inventory-in-maintenance[] 11 | # tag::system-in-maintenance[] 12 | io_openliberty_guides_system_inMaintenance=false 13 | # tag::system-in-maintenance[] 14 | # tag::test-config-overwrite[] 15 | io_openliberty_guides_testConfigOverwrite=DefaultSource 16 | # tag::test-config-overwrite[] 17 | # end::all-props[] 18 | -------------------------------------------------------------------------------- /finish/src/main/resources/META-INF/services/org.eclipse.microprofile.config.spi.ConfigSource: -------------------------------------------------------------------------------- 1 | io.openliberty.guides.config.CustomConfigSource 2 | -------------------------------------------------------------------------------- /finish/src/main/resources/META-INF/services/org.eclipse.microprofile.config.spi.Converter: -------------------------------------------------------------------------------- 1 | io.openliberty.guides.config.CustomEmailConverter 2 | -------------------------------------------------------------------------------- /finish/src/main/webapp/WEB-INF/web.xml: -------------------------------------------------------------------------------- 1 | 2 | 5 | Liberty Project 6 | 7 | 8 | index.html 9 | 10 | -------------------------------------------------------------------------------- /finish/src/main/webapp/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/OpenLiberty/guide-microprofile-config/8d870ed767a0ae27b2cbc35c40e157679bd40457/finish/src/main/webapp/favicon.ico -------------------------------------------------------------------------------- /finish/src/main/webapp/index.html: -------------------------------------------------------------------------------- 1 | 16 | 17 | 18 |

Welcome to your Open Liberty application

19 |

Open Liberty is a lightweight open framework for building fast and efficient cloud-native Java microservices. Find out more at openliberty.io.

20 |
21 |

Eclipse MicroProfile

22 |

23 | The Eclipse MicroProfile project is an open community with the aim of optimizing enterprise Java for a microservices architecture. 24 | MicroProfile evolves with guidance from the community. 25 |

26 |

27 | If you want to share your thoughts, you can post straight to the 28 | MicroProfile Google group. 29 |

30 |

31 | For more information about the features used in this application, see the Open Liberty documentation: 32 |

41 |

42 |
43 | 44 | -------------------------------------------------------------------------------- /finish/src/test/java/it/io/openliberty/guides/config/ConfigITUtil.java: -------------------------------------------------------------------------------- 1 | // tag::copyright[] 2 | /******************************************************************************* 3 | * Copyright (c) 2017, 2022 IBM Corporation and others. 4 | * All rights reserved. This program and the accompanying materials 5 | * are made available under the terms of the Eclipse Public License 2.0 6 | * which accompanies this distribution, and is available at 7 | * http://www.eclipse.org/legal/epl-2.0/ 8 | * 9 | * SPDX-License-Identifier: EPL-2.0 10 | *******************************************************************************/ 11 | // end::copyright[] 12 | package it.io.openliberty.guides.config; 13 | 14 | import java.io.BufferedReader; 15 | import java.io.File; 16 | import java.io.FileWriter; 17 | import java.io.FileReader; 18 | import java.io.IOException; 19 | import jakarta.json.bind.Jsonb; 20 | import jakarta.json.bind.JsonbBuilder; 21 | import jakarta.ws.rs.client.Client; 22 | import jakarta.ws.rs.core.Response; 23 | 24 | /* 25 | * =========================================================================== 26 | * HELPER METHODS 27 | * =========================================================================== 28 | * 29 | */ 30 | public class ConfigITUtil { 31 | private static final String EMAIL = "admin@guides.openliberty.io"; 32 | private static final String TEST_CONFIG = "CustomSource"; 33 | 34 | public static void setDefaultJsonFile(String source) { 35 | CustomConfig config = new CustomConfig(150, false, false, EMAIL, TEST_CONFIG); 36 | createJsonOverwrite(source, config); 37 | } 38 | 39 | /** 40 | * Change the inventory.inMaintenance value for the config source. 41 | */ 42 | public static void switchInventoryMaintenance(String source, boolean newValue) { 43 | CustomConfig config = new CustomConfig(150, newValue, false, EMAIL, TEST_CONFIG); 44 | createJsonOverwrite(source, config); 45 | } 46 | 47 | /** 48 | * Change the email for the config source. 49 | */ 50 | public static void changeEmail(String source, String newEmail) { 51 | CustomConfig config = new CustomConfig(150, true, false, newEmail, TEST_CONFIG); 52 | createJsonOverwrite(source, config); 53 | } 54 | 55 | public static void createJsonOverwrite(String source, CustomConfig config) { 56 | // Create Jsonb and serialize 57 | Jsonb jsonb = JsonbBuilder.create(); 58 | String result = jsonb.toJson(config); 59 | overwriteFile(source, result); 60 | } 61 | 62 | /** 63 | * Read the property values from a local file. 64 | */ 65 | public static String readPropertyValueInFile(String propName, String fileName) { 66 | String propValue = ""; 67 | String line = ""; 68 | try { 69 | File f = new File(fileName); 70 | if (f.exists()) { 71 | BufferedReader reader = new BufferedReader(new FileReader(f)); 72 | while ((line = reader.readLine()) != null) { 73 | if (line.contains(propName)) { 74 | propValue = line.split("=")[1]; 75 | } 76 | } 77 | reader.close(); 78 | return propValue; 79 | } else { 80 | System.out.println("File " + fileName + " does not exist..."); 81 | } 82 | } catch (IOException e) { 83 | e.printStackTrace(); 84 | } 85 | return propValue; 86 | } 87 | 88 | /** 89 | * Overwrite a local file. 90 | */ 91 | public static void overwriteFile(String fileName, String newContent) { 92 | try { 93 | File f = new File(fileName); 94 | if (f.exists()) { 95 | FileWriter fWriter = new FileWriter(f, false); // true to append 96 | // false to overwrite. 97 | fWriter.write(newContent); 98 | fWriter.close(); 99 | Thread.sleep(600); 100 | } else { 101 | System.out.println("File " + fileName + " does not exist"); 102 | } 103 | } catch (Exception e) { 104 | e.printStackTrace(); 105 | } 106 | } 107 | 108 | public static Response getResponse(Client client, String url) { 109 | Response response = client.target(url).request().get(); 110 | return response; 111 | } 112 | 113 | public static String getStringFromURL(Client client, String url) { 114 | Response response = client.target(url).request().get(); 115 | String result = response.readEntity(String.class); 116 | response.close(); 117 | return result; 118 | } 119 | 120 | } 121 | -------------------------------------------------------------------------------- /finish/src/test/java/it/io/openliberty/guides/config/ConfigurationIT.java: -------------------------------------------------------------------------------- 1 | // tag::copyright[] 2 | /******************************************************************************* 3 | * Copyright (c) 2017, 2024 IBM Corporation and others. 4 | * All rights reserved. This program and the accompanying materials 5 | * are made available under the terms of the Eclipse Public License 2.0 6 | * which accompanies this distribution, and is available at 7 | * http://www.eclipse.org/legal/epl-2.0/ 8 | * 9 | * SPDX-License-Identifier: EPL-2.0 10 | *******************************************************************************/ 11 | // end::copyright[] 12 | // tag::test[] 13 | package it.io.openliberty.guides.config; 14 | 15 | import static org.junit.jupiter.api.Assertions.assertEquals; 16 | 17 | import jakarta.ws.rs.client.Client; 18 | import jakarta.ws.rs.client.ClientBuilder; 19 | import jakarta.ws.rs.core.Response; 20 | 21 | import org.junit.jupiter.api.AfterEach; 22 | import org.junit.jupiter.api.BeforeEach; 23 | import org.junit.jupiter.api.MethodOrderer.OrderAnnotation; 24 | import org.junit.jupiter.api.Order; 25 | import org.junit.jupiter.api.Test; 26 | import org.junit.jupiter.api.TestMethodOrder; 27 | 28 | @TestMethodOrder(OrderAnnotation.class) 29 | public class ConfigurationIT { 30 | 31 | private String port; 32 | private String baseUrl; 33 | private Client client; 34 | 35 | private final String INVENTORY_HOSTS = "inventory/systems"; 36 | private final String USER_DIR = System.getProperty("user.dir"); 37 | private final String DEFAULT_CONFIG_FILE = USER_DIR 38 | + "/src/main/resources/META-INF/microprofile-config.properties"; 39 | private final String CUSTOM_CONFIG_FILE = USER_DIR.split("target")[0] 40 | + "/resources/CustomConfigSource.json"; 41 | private final String INV_MAINTENANCE_PROP = "io_openliberty_guides" 42 | + "_inventory_inMaintenance"; 43 | 44 | @BeforeEach 45 | // tag::setup[] 46 | public void setup() { 47 | port = System.getProperty("http.port"); 48 | baseUrl = "http://localhost:" + port + "/"; 49 | ConfigITUtil.setDefaultJsonFile(CUSTOM_CONFIG_FILE); 50 | 51 | client = ClientBuilder.newClient(); 52 | } 53 | // end::setup[] 54 | 55 | @AfterEach 56 | public void teardown() { 57 | ConfigITUtil.setDefaultJsonFile(CUSTOM_CONFIG_FILE); 58 | client.close(); 59 | } 60 | 61 | @Test 62 | @Order(1) 63 | // tag::testInitialServiceStatus[] 64 | public void testInitialServiceStatus() { 65 | boolean status = Boolean.valueOf(ConfigITUtil.readPropertyValueInFile( 66 | INV_MAINTENANCE_PROP, DEFAULT_CONFIG_FILE)); 67 | if (!status) { 68 | Response response = ConfigITUtil.getResponse(client, baseUrl + INVENTORY_HOSTS); 69 | 70 | int expected = Response.Status.OK.getStatusCode(); 71 | int actual = response.getStatus(); 72 | assertEquals(expected, actual); 73 | } else { 74 | assertEquals( 75 | "{ \"error\" : \"Service is currently in maintenance." 76 | + "Contact: admin@guides.openliberty.io\" }", 77 | ConfigITUtil.getStringFromURL(client, baseUrl + INVENTORY_HOSTS), 78 | "The Inventory Service should be in maintenance"); 79 | } 80 | } 81 | // end::testInitialServiceStatus[] 82 | 83 | @Test 84 | @Order(2) 85 | // tag::testPutServiceInMaintenance[] 86 | public void testPutServiceInMaintenance() { 87 | Response response = ConfigITUtil.getResponse(client, baseUrl + INVENTORY_HOSTS); 88 | 89 | int expected = Response.Status.OK.getStatusCode(); 90 | int actual = response.getStatus(); 91 | assertEquals(expected, actual); 92 | 93 | ConfigITUtil.switchInventoryMaintenance(CUSTOM_CONFIG_FILE, true); 94 | 95 | String error = ConfigITUtil.getStringFromURL(client, baseUrl + INVENTORY_HOSTS); 96 | 97 | assertEquals( 98 | "{ \"error\" : \"Service is currently in maintenance. " 99 | + "Contact: admin@guides.openliberty.io\" }", 100 | error, "The inventory service should be down in the end"); 101 | } 102 | // end::testPutServiceInMaintenance[] 103 | 104 | @Test 105 | @Order(3) 106 | // tag::testChangeEmail[] 107 | public void testChangeEmail() { 108 | ConfigITUtil.switchInventoryMaintenance(CUSTOM_CONFIG_FILE, true); 109 | 110 | String error = ConfigITUtil.getStringFromURL(client, baseUrl + INVENTORY_HOSTS); 111 | 112 | assertEquals( 113 | "{ \"error\" : \"Service is currently in maintenance. " 114 | + "Contact: admin@guides.openliberty.io\" }", 115 | error, "The email should be admin@guides.openliberty.io in the beginning"); 116 | 117 | ConfigITUtil.changeEmail(CUSTOM_CONFIG_FILE, "service@guides.openliberty.io"); 118 | 119 | error = ConfigITUtil.getStringFromURL(client, baseUrl + INVENTORY_HOSTS); 120 | 121 | assertEquals( 122 | "{ \"error\" : \"Service is currently in maintenance. " 123 | + "Contact: service@guides.openliberty.io\" }", 124 | error, "The email should be service@guides.openliberty.io in the beginning"); 125 | } 126 | // end::testChangeEmail[] 127 | 128 | } 129 | // end::test[] 130 | -------------------------------------------------------------------------------- /finish/src/test/java/it/io/openliberty/guides/config/CustomConfig.java: -------------------------------------------------------------------------------- 1 | // tag::copyright[] 2 | /******************************************************************************* 3 | * Copyright (c) 2017, 2023 IBM Corporation and others. 4 | * All rights reserved. This program and the accompanying materials 5 | * are made available under the terms of the Eclipse Public License 2.0 6 | * which accompanies this distribution, and is available at 7 | * http://www.eclipse.org/legal/epl-2.0/ 8 | * 9 | * SPDX-License-Identifier: EPL-2.0 10 | *******************************************************************************/ 11 | // end::copyright[] 12 | 13 | package it.io.openliberty.guides.config; 14 | 15 | import jakarta.json.bind.annotation.JsonbProperty; 16 | 17 | public class CustomConfig { 18 | private int config_ordinal; 19 | private boolean io_openliberty_guides_inventory_inMaintenance; 20 | private boolean io_openliberty_guides_system_inMaintenance; 21 | private String io_openliberty_guides_email; 22 | private String io_openliberty_guides_testConfigOverwrite; 23 | 24 | public CustomConfig(int ordinal, boolean inventory, boolean system, String email, 25 | String testConfig) { 26 | this.setConfigOrdinal(ordinal); 27 | this.setInventoryInMaintenance(inventory); 28 | this.setSystemInMaintenance(system); 29 | this.setEmail(email); 30 | this.setTestConfigOverwrite(testConfig); 31 | } 32 | 33 | @JsonbProperty("config_ordinal") 34 | public int getConfigOrdinal() { 35 | return config_ordinal; 36 | } 37 | 38 | public void setConfigOrdinal(int configOrdinal) { 39 | this.config_ordinal = configOrdinal; 40 | } 41 | 42 | @JsonbProperty("io_openliberty_guides_inventory_inMaintenance") 43 | public boolean isInventoryInMaintenance() { 44 | return io_openliberty_guides_inventory_inMaintenance; 45 | } 46 | 47 | public void setInventoryInMaintenance(boolean inventoryInMaintenance) { 48 | this.io_openliberty_guides_inventory_inMaintenance = 49 | inventoryInMaintenance; 50 | } 51 | 52 | @JsonbProperty("io_openliberty_guides_system_inMaintenance") 53 | public boolean isSystemInMaintenance() { 54 | return io_openliberty_guides_system_inMaintenance; 55 | } 56 | 57 | public void setSystemInMaintenance(boolean systemInMaintenance) { 58 | this.io_openliberty_guides_system_inMaintenance = 59 | systemInMaintenance; 60 | } 61 | 62 | @JsonbProperty("io_openliberty_guides_email") 63 | public String getEmail() { 64 | return io_openliberty_guides_email; 65 | } 66 | 67 | public void setEmail(String email) { 68 | this.io_openliberty_guides_email = email; 69 | } 70 | 71 | @JsonbProperty("io_openliberty_guides_testConfigOverwrite") 72 | public String getTestConfigOverwrite() { 73 | return io_openliberty_guides_testConfigOverwrite; 74 | } 75 | 76 | public void setTestConfigOverwrite(String testConfigOverwrite) { 77 | this.io_openliberty_guides_testConfigOverwrite = 78 | testConfigOverwrite; 79 | } 80 | 81 | } 82 | -------------------------------------------------------------------------------- /finish/src/test/java/it/io/openliberty/guides/inventory/InventoryEndpointIT.java: -------------------------------------------------------------------------------- 1 | // tag::copyright[] 2 | /******************************************************************************* 3 | * Copyright (c) 2017, 2024 IBM Corporation and others. 4 | * All rights reserved. This program and the accompanying materials 5 | * are made available under the terms of the Eclipse Public License 2.0 6 | * which accompanies this distribution, and is available at 7 | * http://www.eclipse.org/legal/epl-2.0/ 8 | * 9 | * SPDX-License-Identifier: EPL-2.0 10 | *******************************************************************************/ 11 | // end::copyright[] 12 | // tag::testClass[] 13 | package it.io.openliberty.guides.inventory; 14 | 15 | import static org.junit.jupiter.api.Assertions.assertEquals; 16 | import static org.junit.jupiter.api.Assertions.assertTrue; 17 | 18 | import jakarta.json.JsonArray; 19 | import jakarta.json.JsonObject; 20 | import jakarta.ws.rs.client.Client; 21 | import jakarta.ws.rs.client.ClientBuilder; 22 | import jakarta.ws.rs.core.MediaType; 23 | import jakarta.ws.rs.core.Response; 24 | 25 | import org.junit.jupiter.api.AfterEach; 26 | import org.junit.jupiter.api.BeforeAll; 27 | import org.junit.jupiter.api.BeforeEach; 28 | import org.junit.jupiter.api.MethodOrderer.OrderAnnotation; 29 | import org.junit.jupiter.api.Order; 30 | import org.junit.jupiter.api.Test; 31 | import org.junit.jupiter.api.TestMethodOrder; 32 | 33 | @TestMethodOrder(OrderAnnotation.class) 34 | public class InventoryEndpointIT { 35 | 36 | private static String port; 37 | private static String baseUrl; 38 | 39 | private Client client; 40 | 41 | private final String SYSTEM_PROPERTIES = "system/properties"; 42 | private final String INVENTORY_SYSTEMS = "inventory/systems"; 43 | 44 | @BeforeAll 45 | public static void oneTimeSetup() { 46 | port = System.getProperty("http.port"); 47 | baseUrl = "http://localhost:" + port + "/"; 48 | } 49 | 50 | @BeforeEach 51 | public void setup() { 52 | client = ClientBuilder.newClient(); 53 | } 54 | 55 | @AfterEach 56 | public void teardown() { 57 | client.close(); 58 | } 59 | 60 | // tag::tests[] 61 | @Test 62 | @Order(1) 63 | // tag::testHostRegistration[] 64 | public void testHostRegistration() { 65 | this.visitLocalhost(); 66 | 67 | Response response = this.getResponse(baseUrl + INVENTORY_SYSTEMS); 68 | this.assertResponse(baseUrl, response); 69 | 70 | JsonObject obj = response.readEntity(JsonObject.class); 71 | 72 | JsonArray systems = obj.getJsonArray("systems"); 73 | 74 | boolean localhostExists = false; 75 | for (int n = 0; n < systems.size(); n++) { 76 | localhostExists = systems.getJsonObject(n).get("hostname").toString() 77 | .contains("localhost"); 78 | if (localhostExists) { 79 | break; 80 | } 81 | } 82 | assertTrue(localhostExists, "A host was registered, but it was not localhost"); 83 | 84 | response.close(); 85 | } 86 | // end::testHostRegistration[] 87 | 88 | @Test 89 | @Order(2) 90 | // tag::testSystemPropertiesMatch[] 91 | public void testSystemPropertiesMatch() { 92 | Response invResponse = this.getResponse(baseUrl + INVENTORY_SYSTEMS); 93 | Response sysResponse = this.getResponse(baseUrl + SYSTEM_PROPERTIES); 94 | 95 | this.assertResponse(baseUrl, invResponse); 96 | this.assertResponse(baseUrl, sysResponse); 97 | 98 | JsonObject jsonFromInventory = (JsonObject) invResponse.readEntity(JsonObject.class) 99 | .getJsonArray("systems").getJsonObject(0).get("properties"); 100 | 101 | JsonObject jsonFromSystem = sysResponse.readEntity(JsonObject.class); 102 | 103 | String osNameFromInventory = jsonFromInventory.getString("os.name"); 104 | String osNameFromSystem = jsonFromSystem.getString("os.name"); 105 | this.assertProperty("os.name", "localhost", osNameFromSystem, osNameFromInventory); 106 | 107 | String userNameFromInventory = jsonFromInventory.getString("user.name"); 108 | String userNameFromSystem = jsonFromSystem.getString("user.name"); 109 | this.assertProperty("user.name", "localhost", userNameFromSystem, 110 | userNameFromInventory); 111 | 112 | invResponse.close(); 113 | sysResponse.close(); 114 | } 115 | // end::testSystemPropertiesMatch[] 116 | 117 | @Test 118 | @Order(3) 119 | // tag::testUnknownHost[] 120 | public void testUnknownHost() { 121 | Response response = this.getResponse(baseUrl + INVENTORY_SYSTEMS); 122 | this.assertResponse(baseUrl, response); 123 | 124 | Response badResponse = client 125 | .target(baseUrl + INVENTORY_SYSTEMS + "/" + "badhostname") 126 | .request(MediaType.APPLICATION_JSON).get(); 127 | 128 | assertEquals(404, badResponse.getStatus(), 129 | "BadResponse expected status: 404. Response code not as expected."); 130 | 131 | String stringObj = badResponse.readEntity(String.class); 132 | assertTrue(stringObj.contains("error"), 133 | "badhostname is not a valid host but it didn't raise an error"); 134 | 135 | response.close(); 136 | badResponse.close(); 137 | } 138 | // end::testUnknownHost[] 139 | // end::tests[] 140 | // tag::helpers[] 141 | // tag::javadoc[] 142 | 143 | /** 144 | *

145 | * Returns response information from the specified URL. 146 | *

147 | * 148 | * @param url - target URL. 149 | * @return Response object with the response from the specified URL. 150 | */ 151 | // end::javadoc[] 152 | private Response getResponse(String url) { 153 | return client.target(url).request().get(); 154 | } 155 | 156 | // tag::javadoc[] 157 | /** 158 | *

159 | * Asserts that the given URL has the correct response code of 200. 160 | *

161 | * 162 | * @param url - target URL. 163 | * @param response - response received from the target URL. 164 | */ 165 | // end::javadoc[] 166 | private void assertResponse(String url, Response response) { 167 | assertEquals(200, response.getStatus(), "Incorrect response code from " + url); 168 | } 169 | 170 | // tag::javadoc[] 171 | /** 172 | * Asserts that the specified JVM system property is equivalent in both the 173 | * system and inventory services. 174 | * 175 | * @param propertyName - name of the system property to check. 176 | * @param hostname - name of JVM's host. 177 | * @param expected - expected name. 178 | * @param actual - actual name. 179 | */ 180 | // end::javadoc[] 181 | private void assertProperty(String propertyName, String hostname, String expected, 182 | String actual) { 183 | assertEquals(expected, actual, 184 | "JVM system property [" + propertyName + "] " 185 | + "in the system service does not match the one stored in " 186 | + "the inventory service for " + hostname); 187 | } 188 | 189 | // tag::javadoc[] 190 | /** 191 | * Makes a simple GET request to inventory/localhost. 192 | */ 193 | // end::javadoc[] 194 | private void visitLocalhost() { 195 | Response response = this.getResponse(baseUrl + SYSTEM_PROPERTIES); 196 | this.assertResponse(baseUrl, response); 197 | response.close(); 198 | 199 | Response targetResponse = client.target(baseUrl + INVENTORY_SYSTEMS + "/localhost") 200 | .request().get(); 201 | targetResponse.close(); 202 | } 203 | // end::helpers[] 204 | } 205 | // end::testClass[] 206 | -------------------------------------------------------------------------------- /finish/src/test/java/it/io/openliberty/guides/system/SystemEndpointIT.java: -------------------------------------------------------------------------------- 1 | // tag::copyright[] 2 | /******************************************************************************* 3 | * Copyright (c) 2017, 2024 IBM Corporation and others. 4 | * All rights reserved. This program and the accompanying materials 5 | * are made available under the terms of the Eclipse Public License 2.0 6 | * which accompanies this distribution, and is available at 7 | * http://www.eclipse.org/legal/epl-2.0/ 8 | * 9 | * SPDX-License-Identifier: EPL-2.0 10 | *******************************************************************************/ 11 | // end::copyright[] 12 | package it.io.openliberty.guides.system; 13 | 14 | import static org.junit.jupiter.api.Assertions.assertEquals; 15 | import jakarta.json.JsonObject; 16 | import jakarta.ws.rs.client.Client; 17 | import jakarta.ws.rs.client.ClientBuilder; 18 | import jakarta.ws.rs.client.WebTarget; 19 | import jakarta.ws.rs.core.Response; 20 | 21 | import org.junit.jupiter.api.Test; 22 | 23 | public class SystemEndpointIT { 24 | 25 | @Test 26 | public void testGetProperties() { 27 | String port = System.getProperty("http.port"); 28 | String url = "http://localhost:" + port + "/"; 29 | 30 | Client client = ClientBuilder.newClient(); 31 | 32 | WebTarget target = client.target(url + "system/properties"); 33 | Response response = target.request().get(); 34 | 35 | assertEquals(200, response.getStatus(), "Incorrect response code from " + url); 36 | 37 | JsonObject obj = response.readEntity(JsonObject.class); 38 | 39 | assertEquals(System.getProperty("os.name"), obj.getString("os.name"), 40 | "The system property for the local and remote JVM should match"); 41 | 42 | response.close(); 43 | } 44 | } 45 | -------------------------------------------------------------------------------- /scripts/dailyBuild.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | while getopts t:d: flag; 3 | do 4 | case "${flag}" in 5 | t) DATE="${OPTARG}";; 6 | d) DRIVER="${OPTARG}";; 7 | *) echo "Invalid option";; 8 | esac 9 | done 10 | 11 | sed -i "\#liberty-maven-plugin#ahttps://public.dhe.ibm.com/ibmdl/export/pub/software/openliberty/runtime/nightly/$DATE/$DRIVER" pom.xml 12 | cat pom.xml 13 | 14 | ../scripts/testApp.sh 15 | -------------------------------------------------------------------------------- /scripts/testApp.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | set -euxo pipefail 3 | ./mvnw -version 4 | 5 | # LMP 3.0+ goals are listed here: https://github.com/OpenLiberty/ci.maven#goals 6 | 7 | ## Rebuild the application 8 | # package - Take the compiled code and package it in its distributable format. 9 | # liberty:create - Create a Liberty server. 10 | # liberty:install-feature - Install a feature packaged as a Subsystem Archive (esa) to the Liberty runtime. 11 | # liberty:deploy - Copy applications to the Liberty server's dropins or apps directory. 12 | ./mvnw -ntp -Dhttp.keepAlive=false \ 13 | -Dmaven.wagon.http.pool=false \ 14 | -Dmaven.wagon.httpconnectionManager.ttlSeconds=120 \ 15 | -q clean package liberty:create liberty:install-feature liberty:deploy 16 | 17 | 18 | ## Run the tests 19 | # These commands are separated because if one of the commands fail, the test script will fail and exit. 20 | # e.g if liberty:start fails, then there is no need to run the failsafe commands. 21 | # liberty:start - Start a Liberty server in the background. 22 | # failsafe:integration-test - Runs the integration tests of an application. 23 | # liberty:stop - Stop a Liberty server. 24 | # failsafe:verify - Verifies that the integration tests of an application passed. 25 | ./mvnw -ntp liberty:start 26 | ./mvnw -ntp -Dhttp.keepAlive=false \ 27 | -Dmaven.wagon.http.pool=false \ 28 | -Dmaven.wagon.httpconnectionManager.ttlSeconds=120 \ 29 | failsafe:integration-test liberty:stop 30 | ./mvnw -ntp failsafe:verify 31 | -------------------------------------------------------------------------------- /start/.mvn/wrapper/maven-wrapper.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/OpenLiberty/guide-microprofile-config/8d870ed767a0ae27b2cbc35c40e157679bd40457/start/.mvn/wrapper/maven-wrapper.jar -------------------------------------------------------------------------------- /start/.mvn/wrapper/maven-wrapper.properties: -------------------------------------------------------------------------------- 1 | distributionUrl=https://repo.maven.apache.org/maven2/org/apache/maven/apache-maven/3.9.9/apache-maven-3.9.9-bin.zip 2 | wrapperUrl=https://repo.maven.apache.org/maven2/org/apache/maven/wrapper/maven-wrapper/3.3.2/maven-wrapper-3.3.2.jar 3 | -------------------------------------------------------------------------------- /start/mvnw: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | # ---------------------------------------------------------------------------- 3 | # Licensed to the Apache Software Foundation (ASF) under one 4 | # or more contributor license agreements. See the NOTICE file 5 | # distributed with this work for additional information 6 | # regarding copyright ownership. The ASF licenses this file 7 | # to you under the Apache License, Version 2.0 (the 8 | # "License"); you may not use this file except in compliance 9 | # with the License. You may obtain a copy of the License at 10 | # 11 | # http://www.apache.org/licenses/LICENSE-2.0 12 | # 13 | # Unless required by applicable law or agreed to in writing, 14 | # software distributed under the License is distributed on an 15 | # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 16 | # KIND, either express or implied. See the License for the 17 | # specific language governing permissions and limitations 18 | # under the License. 19 | # ---------------------------------------------------------------------------- 20 | 21 | # ---------------------------------------------------------------------------- 22 | # Apache Maven Wrapper startup batch script, version 3.3.2 23 | # 24 | # Required ENV vars: 25 | # ------------------ 26 | # JAVA_HOME - location of a JDK home dir 27 | # 28 | # Optional ENV vars 29 | # ----------------- 30 | # MAVEN_OPTS - parameters passed to the Java VM when running Maven 31 | # e.g. to debug Maven itself, use 32 | # set MAVEN_OPTS=-Xdebug -Xrunjdwp:transport=dt_socket,server=y,suspend=y,address=8000 33 | # MAVEN_SKIP_RC - flag to disable loading of mavenrc files 34 | # ---------------------------------------------------------------------------- 35 | 36 | if [ -z "$MAVEN_SKIP_RC" ]; then 37 | 38 | if [ -f /usr/local/etc/mavenrc ]; then 39 | . /usr/local/etc/mavenrc 40 | fi 41 | 42 | if [ -f /etc/mavenrc ]; then 43 | . /etc/mavenrc 44 | fi 45 | 46 | if [ -f "$HOME/.mavenrc" ]; then 47 | . "$HOME/.mavenrc" 48 | fi 49 | 50 | fi 51 | 52 | # OS specific support. $var _must_ be set to either true or false. 53 | cygwin=false 54 | darwin=false 55 | mingw=false 56 | case "$(uname)" in 57 | CYGWIN*) cygwin=true ;; 58 | MINGW*) mingw=true ;; 59 | Darwin*) 60 | darwin=true 61 | # Use /usr/libexec/java_home if available, otherwise fall back to /Library/Java/Home 62 | # See https://developer.apple.com/library/mac/qa/qa1170/_index.html 63 | if [ -z "$JAVA_HOME" ]; then 64 | if [ -x "/usr/libexec/java_home" ]; then 65 | JAVA_HOME="$(/usr/libexec/java_home)" 66 | export JAVA_HOME 67 | else 68 | JAVA_HOME="/Library/Java/Home" 69 | export JAVA_HOME 70 | fi 71 | fi 72 | ;; 73 | esac 74 | 75 | if [ -z "$JAVA_HOME" ]; then 76 | if [ -r /etc/gentoo-release ]; then 77 | JAVA_HOME=$(java-config --jre-home) 78 | fi 79 | fi 80 | 81 | # For Cygwin, ensure paths are in UNIX format before anything is touched 82 | if $cygwin; then 83 | [ -n "$JAVA_HOME" ] \ 84 | && JAVA_HOME=$(cygpath --unix "$JAVA_HOME") 85 | [ -n "$CLASSPATH" ] \ 86 | && CLASSPATH=$(cygpath --path --unix "$CLASSPATH") 87 | fi 88 | 89 | # For Mingw, ensure paths are in UNIX format before anything is touched 90 | if $mingw; then 91 | [ -n "$JAVA_HOME" ] && [ -d "$JAVA_HOME" ] \ 92 | && JAVA_HOME="$( 93 | cd "$JAVA_HOME" || ( 94 | echo "cannot cd into $JAVA_HOME." >&2 95 | exit 1 96 | ) 97 | pwd 98 | )" 99 | fi 100 | 101 | if [ -z "$JAVA_HOME" ]; then 102 | javaExecutable="$(which javac)" 103 | if [ -n "$javaExecutable" ] && ! [ "$(expr "$javaExecutable" : '\([^ ]*\)')" = "no" ]; then 104 | # readlink(1) is not available as standard on Solaris 10. 105 | readLink=$(which readlink) 106 | if [ ! "$(expr "$readLink" : '\([^ ]*\)')" = "no" ]; then 107 | if $darwin; then 108 | javaHome="$(dirname "$javaExecutable")" 109 | javaExecutable="$(cd "$javaHome" && pwd -P)/javac" 110 | else 111 | javaExecutable="$(readlink -f "$javaExecutable")" 112 | fi 113 | javaHome="$(dirname "$javaExecutable")" 114 | javaHome=$(expr "$javaHome" : '\(.*\)/bin') 115 | JAVA_HOME="$javaHome" 116 | export JAVA_HOME 117 | fi 118 | fi 119 | fi 120 | 121 | if [ -z "$JAVACMD" ]; then 122 | if [ -n "$JAVA_HOME" ]; then 123 | if [ -x "$JAVA_HOME/jre/sh/java" ]; then 124 | # IBM's JDK on AIX uses strange locations for the executables 125 | JAVACMD="$JAVA_HOME/jre/sh/java" 126 | else 127 | JAVACMD="$JAVA_HOME/bin/java" 128 | fi 129 | else 130 | JAVACMD="$( 131 | \unset -f command 2>/dev/null 132 | \command -v java 133 | )" 134 | fi 135 | fi 136 | 137 | if [ ! -x "$JAVACMD" ]; then 138 | echo "Error: JAVA_HOME is not defined correctly." >&2 139 | echo " We cannot execute $JAVACMD" >&2 140 | exit 1 141 | fi 142 | 143 | if [ -z "$JAVA_HOME" ]; then 144 | echo "Warning: JAVA_HOME environment variable is not set." >&2 145 | fi 146 | 147 | # traverses directory structure from process work directory to filesystem root 148 | # first directory with .mvn subdirectory is considered project base directory 149 | find_maven_basedir() { 150 | if [ -z "$1" ]; then 151 | echo "Path not specified to find_maven_basedir" >&2 152 | return 1 153 | fi 154 | 155 | basedir="$1" 156 | wdir="$1" 157 | while [ "$wdir" != '/' ]; do 158 | if [ -d "$wdir"/.mvn ]; then 159 | basedir=$wdir 160 | break 161 | fi 162 | # workaround for JBEAP-8937 (on Solaris 10/Sparc) 163 | if [ -d "${wdir}" ]; then 164 | wdir=$( 165 | cd "$wdir/.." || exit 1 166 | pwd 167 | ) 168 | fi 169 | # end of workaround 170 | done 171 | printf '%s' "$( 172 | cd "$basedir" || exit 1 173 | pwd 174 | )" 175 | } 176 | 177 | # concatenates all lines of a file 178 | concat_lines() { 179 | if [ -f "$1" ]; then 180 | # Remove \r in case we run on Windows within Git Bash 181 | # and check out the repository with auto CRLF management 182 | # enabled. Otherwise, we may read lines that are delimited with 183 | # \r\n and produce $'-Xarg\r' rather than -Xarg due to word 184 | # splitting rules. 185 | tr -s '\r\n' ' ' <"$1" 186 | fi 187 | } 188 | 189 | log() { 190 | if [ "$MVNW_VERBOSE" = true ]; then 191 | printf '%s\n' "$1" 192 | fi 193 | } 194 | 195 | BASE_DIR=$(find_maven_basedir "$(dirname "$0")") 196 | if [ -z "$BASE_DIR" ]; then 197 | exit 1 198 | fi 199 | 200 | MAVEN_PROJECTBASEDIR=${MAVEN_BASEDIR:-"$BASE_DIR"} 201 | export MAVEN_PROJECTBASEDIR 202 | log "$MAVEN_PROJECTBASEDIR" 203 | 204 | ########################################################################################## 205 | # Extension to allow automatically downloading the maven-wrapper.jar from Maven-central 206 | # This allows using the maven wrapper in projects that prohibit checking in binary data. 207 | ########################################################################################## 208 | wrapperJarPath="$MAVEN_PROJECTBASEDIR/.mvn/wrapper/maven-wrapper.jar" 209 | if [ -r "$wrapperJarPath" ]; then 210 | log "Found $wrapperJarPath" 211 | else 212 | log "Couldn't find $wrapperJarPath, downloading it ..." 213 | 214 | if [ -n "$MVNW_REPOURL" ]; then 215 | wrapperUrl="$MVNW_REPOURL/org/apache/maven/wrapper/maven-wrapper/3.3.2/maven-wrapper-3.3.2.jar" 216 | else 217 | wrapperUrl="https://repo.maven.apache.org/maven2/org/apache/maven/wrapper/maven-wrapper/3.3.2/maven-wrapper-3.3.2.jar" 218 | fi 219 | while IFS="=" read -r key value; do 220 | # Remove '\r' from value to allow usage on windows as IFS does not consider '\r' as a separator ( considers space, tab, new line ('\n'), and custom '=' ) 221 | safeValue=$(echo "$value" | tr -d '\r') 222 | case "$key" in wrapperUrl) 223 | wrapperUrl="$safeValue" 224 | break 225 | ;; 226 | esac 227 | done <"$MAVEN_PROJECTBASEDIR/.mvn/wrapper/maven-wrapper.properties" 228 | log "Downloading from: $wrapperUrl" 229 | 230 | if $cygwin; then 231 | wrapperJarPath=$(cygpath --path --windows "$wrapperJarPath") 232 | fi 233 | 234 | if command -v wget >/dev/null; then 235 | log "Found wget ... using wget" 236 | [ "$MVNW_VERBOSE" = true ] && QUIET="" || QUIET="--quiet" 237 | if [ -z "$MVNW_USERNAME" ] || [ -z "$MVNW_PASSWORD" ]; then 238 | wget $QUIET "$wrapperUrl" -O "$wrapperJarPath" || rm -f "$wrapperJarPath" 239 | else 240 | wget $QUIET --http-user="$MVNW_USERNAME" --http-password="$MVNW_PASSWORD" "$wrapperUrl" -O "$wrapperJarPath" || rm -f "$wrapperJarPath" 241 | fi 242 | elif command -v curl >/dev/null; then 243 | log "Found curl ... using curl" 244 | [ "$MVNW_VERBOSE" = true ] && QUIET="" || QUIET="--silent" 245 | if [ -z "$MVNW_USERNAME" ] || [ -z "$MVNW_PASSWORD" ]; then 246 | curl $QUIET -o "$wrapperJarPath" "$wrapperUrl" -f -L || rm -f "$wrapperJarPath" 247 | else 248 | curl $QUIET --user "$MVNW_USERNAME:$MVNW_PASSWORD" -o "$wrapperJarPath" "$wrapperUrl" -f -L || rm -f "$wrapperJarPath" 249 | fi 250 | else 251 | log "Falling back to using Java to download" 252 | javaSource="$MAVEN_PROJECTBASEDIR/.mvn/wrapper/MavenWrapperDownloader.java" 253 | javaClass="$MAVEN_PROJECTBASEDIR/.mvn/wrapper/MavenWrapperDownloader.class" 254 | # For Cygwin, switch paths to Windows format before running javac 255 | if $cygwin; then 256 | javaSource=$(cygpath --path --windows "$javaSource") 257 | javaClass=$(cygpath --path --windows "$javaClass") 258 | fi 259 | if [ -e "$javaSource" ]; then 260 | if [ ! -e "$javaClass" ]; then 261 | log " - Compiling MavenWrapperDownloader.java ..." 262 | ("$JAVA_HOME/bin/javac" "$javaSource") 263 | fi 264 | if [ -e "$javaClass" ]; then 265 | log " - Running MavenWrapperDownloader.java ..." 266 | ("$JAVA_HOME/bin/java" -cp .mvn/wrapper MavenWrapperDownloader "$wrapperUrl" "$wrapperJarPath") || rm -f "$wrapperJarPath" 267 | fi 268 | fi 269 | fi 270 | fi 271 | ########################################################################################## 272 | # End of extension 273 | ########################################################################################## 274 | 275 | # If specified, validate the SHA-256 sum of the Maven wrapper jar file 276 | wrapperSha256Sum="" 277 | while IFS="=" read -r key value; do 278 | case "$key" in wrapperSha256Sum) 279 | wrapperSha256Sum=$value 280 | break 281 | ;; 282 | esac 283 | done <"$MAVEN_PROJECTBASEDIR/.mvn/wrapper/maven-wrapper.properties" 284 | if [ -n "$wrapperSha256Sum" ]; then 285 | wrapperSha256Result=false 286 | if command -v sha256sum >/dev/null; then 287 | if echo "$wrapperSha256Sum $wrapperJarPath" | sha256sum -c >/dev/null 2>&1; then 288 | wrapperSha256Result=true 289 | fi 290 | elif command -v shasum >/dev/null; then 291 | if echo "$wrapperSha256Sum $wrapperJarPath" | shasum -a 256 -c >/dev/null 2>&1; then 292 | wrapperSha256Result=true 293 | fi 294 | else 295 | echo "Checksum validation was requested but neither 'sha256sum' or 'shasum' are available." >&2 296 | echo "Please install either command, or disable validation by removing 'wrapperSha256Sum' from your maven-wrapper.properties." >&2 297 | exit 1 298 | fi 299 | if [ $wrapperSha256Result = false ]; then 300 | echo "Error: Failed to validate Maven wrapper SHA-256, your Maven wrapper might be compromised." >&2 301 | echo "Investigate or delete $wrapperJarPath to attempt a clean download." >&2 302 | echo "If you updated your Maven version, you need to update the specified wrapperSha256Sum property." >&2 303 | exit 1 304 | fi 305 | fi 306 | 307 | MAVEN_OPTS="$(concat_lines "$MAVEN_PROJECTBASEDIR/.mvn/jvm.config") $MAVEN_OPTS" 308 | 309 | # For Cygwin, switch paths to Windows format before running java 310 | if $cygwin; then 311 | [ -n "$JAVA_HOME" ] \ 312 | && JAVA_HOME=$(cygpath --path --windows "$JAVA_HOME") 313 | [ -n "$CLASSPATH" ] \ 314 | && CLASSPATH=$(cygpath --path --windows "$CLASSPATH") 315 | [ -n "$MAVEN_PROJECTBASEDIR" ] \ 316 | && MAVEN_PROJECTBASEDIR=$(cygpath --path --windows "$MAVEN_PROJECTBASEDIR") 317 | fi 318 | 319 | # Provide a "standardized" way to retrieve the CLI args that will 320 | # work with both Windows and non-Windows executions. 321 | MAVEN_CMD_LINE_ARGS="$MAVEN_CONFIG $*" 322 | export MAVEN_CMD_LINE_ARGS 323 | 324 | WRAPPER_LAUNCHER=org.apache.maven.wrapper.MavenWrapperMain 325 | 326 | # shellcheck disable=SC2086 # safe args 327 | exec "$JAVACMD" \ 328 | $MAVEN_OPTS \ 329 | $MAVEN_DEBUG_OPTS \ 330 | -classpath "$MAVEN_PROJECTBASEDIR/.mvn/wrapper/maven-wrapper.jar" \ 331 | "-Dmaven.multiModuleProjectDirectory=${MAVEN_PROJECTBASEDIR}" \ 332 | ${WRAPPER_LAUNCHER} $MAVEN_CONFIG "$@" 333 | -------------------------------------------------------------------------------- /start/mvnw.cmd: -------------------------------------------------------------------------------- 1 | @REM ---------------------------------------------------------------------------- 2 | @REM Licensed to the Apache Software Foundation (ASF) under one 3 | @REM or more contributor license agreements. See the NOTICE file 4 | @REM distributed with this work for additional information 5 | @REM regarding copyright ownership. The ASF licenses this file 6 | @REM to you under the Apache License, Version 2.0 (the 7 | @REM "License"); you may not use this file except in compliance 8 | @REM with the License. You may obtain a copy of the License at 9 | @REM 10 | @REM http://www.apache.org/licenses/LICENSE-2.0 11 | @REM 12 | @REM Unless required by applicable law or agreed to in writing, 13 | @REM software distributed under the License is distributed on an 14 | @REM "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 15 | @REM KIND, either express or implied. See the License for the 16 | @REM specific language governing permissions and limitations 17 | @REM under the License. 18 | @REM ---------------------------------------------------------------------------- 19 | 20 | @REM ---------------------------------------------------------------------------- 21 | @REM Apache Maven Wrapper startup batch script, version 3.3.2 22 | @REM 23 | @REM Required ENV vars: 24 | @REM JAVA_HOME - location of a JDK home dir 25 | @REM 26 | @REM Optional ENV vars 27 | @REM MAVEN_BATCH_ECHO - set to 'on' to enable the echoing of the batch commands 28 | @REM MAVEN_BATCH_PAUSE - set to 'on' to wait for a keystroke before ending 29 | @REM MAVEN_OPTS - parameters passed to the Java VM when running Maven 30 | @REM e.g. to debug Maven itself, use 31 | @REM set MAVEN_OPTS=-Xdebug -Xrunjdwp:transport=dt_socket,server=y,suspend=y,address=8000 32 | @REM MAVEN_SKIP_RC - flag to disable loading of mavenrc files 33 | @REM ---------------------------------------------------------------------------- 34 | 35 | @REM Begin all REM lines with '@' in case MAVEN_BATCH_ECHO is 'on' 36 | @echo off 37 | @REM set title of command window 38 | title %0 39 | @REM enable echoing by setting MAVEN_BATCH_ECHO to 'on' 40 | @if "%MAVEN_BATCH_ECHO%" == "on" echo %MAVEN_BATCH_ECHO% 41 | 42 | @REM set %HOME% to equivalent of $HOME 43 | if "%HOME%" == "" (set "HOME=%HOMEDRIVE%%HOMEPATH%") 44 | 45 | @REM Execute a user defined script before this one 46 | if not "%MAVEN_SKIP_RC%" == "" goto skipRcPre 47 | @REM check for pre script, once with legacy .bat ending and once with .cmd ending 48 | if exist "%USERPROFILE%\mavenrc_pre.bat" call "%USERPROFILE%\mavenrc_pre.bat" %* 49 | if exist "%USERPROFILE%\mavenrc_pre.cmd" call "%USERPROFILE%\mavenrc_pre.cmd" %* 50 | :skipRcPre 51 | 52 | @setlocal 53 | 54 | set ERROR_CODE=0 55 | 56 | @REM To isolate internal variables from possible post scripts, we use another setlocal 57 | @setlocal 58 | 59 | @REM ==== START VALIDATION ==== 60 | if not "%JAVA_HOME%" == "" goto OkJHome 61 | 62 | echo. >&2 63 | echo Error: JAVA_HOME not found in your environment. >&2 64 | echo Please set the JAVA_HOME variable in your environment to match the >&2 65 | echo location of your Java installation. >&2 66 | echo. >&2 67 | goto error 68 | 69 | :OkJHome 70 | if exist "%JAVA_HOME%\bin\java.exe" goto init 71 | 72 | echo. >&2 73 | echo Error: JAVA_HOME is set to an invalid directory. >&2 74 | echo JAVA_HOME = "%JAVA_HOME%" >&2 75 | echo Please set the JAVA_HOME variable in your environment to match the >&2 76 | echo location of your Java installation. >&2 77 | echo. >&2 78 | goto error 79 | 80 | @REM ==== END VALIDATION ==== 81 | 82 | :init 83 | 84 | @REM Find the project base dir, i.e. the directory that contains the folder ".mvn". 85 | @REM Fallback to current working directory if not found. 86 | 87 | set MAVEN_PROJECTBASEDIR=%MAVEN_BASEDIR% 88 | IF NOT "%MAVEN_PROJECTBASEDIR%"=="" goto endDetectBaseDir 89 | 90 | set EXEC_DIR=%CD% 91 | set WDIR=%EXEC_DIR% 92 | :findBaseDir 93 | IF EXIST "%WDIR%"\.mvn goto baseDirFound 94 | cd .. 95 | IF "%WDIR%"=="%CD%" goto baseDirNotFound 96 | set WDIR=%CD% 97 | goto findBaseDir 98 | 99 | :baseDirFound 100 | set MAVEN_PROJECTBASEDIR=%WDIR% 101 | cd "%EXEC_DIR%" 102 | goto endDetectBaseDir 103 | 104 | :baseDirNotFound 105 | set MAVEN_PROJECTBASEDIR=%EXEC_DIR% 106 | cd "%EXEC_DIR%" 107 | 108 | :endDetectBaseDir 109 | 110 | IF NOT EXIST "%MAVEN_PROJECTBASEDIR%\.mvn\jvm.config" goto endReadAdditionalConfig 111 | 112 | @setlocal EnableExtensions EnableDelayedExpansion 113 | for /F "usebackq delims=" %%a in ("%MAVEN_PROJECTBASEDIR%\.mvn\jvm.config") do set JVM_CONFIG_MAVEN_PROPS=!JVM_CONFIG_MAVEN_PROPS! %%a 114 | @endlocal & set JVM_CONFIG_MAVEN_PROPS=%JVM_CONFIG_MAVEN_PROPS% 115 | 116 | :endReadAdditionalConfig 117 | 118 | SET MAVEN_JAVA_EXE="%JAVA_HOME%\bin\java.exe" 119 | set WRAPPER_JAR="%MAVEN_PROJECTBASEDIR%\.mvn\wrapper\maven-wrapper.jar" 120 | set WRAPPER_LAUNCHER=org.apache.maven.wrapper.MavenWrapperMain 121 | 122 | set WRAPPER_URL="https://repo.maven.apache.org/maven2/org/apache/maven/wrapper/maven-wrapper/3.3.2/maven-wrapper-3.3.2.jar" 123 | 124 | FOR /F "usebackq tokens=1,2 delims==" %%A IN ("%MAVEN_PROJECTBASEDIR%\.mvn\wrapper\maven-wrapper.properties") DO ( 125 | IF "%%A"=="wrapperUrl" SET WRAPPER_URL=%%B 126 | ) 127 | 128 | @REM Extension to allow automatically downloading the maven-wrapper.jar from Maven-central 129 | @REM This allows using the maven wrapper in projects that prohibit checking in binary data. 130 | if exist %WRAPPER_JAR% ( 131 | if "%MVNW_VERBOSE%" == "true" ( 132 | echo Found %WRAPPER_JAR% 133 | ) 134 | ) else ( 135 | if not "%MVNW_REPOURL%" == "" ( 136 | SET WRAPPER_URL="%MVNW_REPOURL%/org/apache/maven/wrapper/maven-wrapper/3.3.2/maven-wrapper-3.3.2.jar" 137 | ) 138 | if "%MVNW_VERBOSE%" == "true" ( 139 | echo Couldn't find %WRAPPER_JAR%, downloading it ... 140 | echo Downloading from: %WRAPPER_URL% 141 | ) 142 | 143 | powershell -Command "&{"^ 144 | "$webclient = new-object System.Net.WebClient;"^ 145 | "if (-not ([string]::IsNullOrEmpty('%MVNW_USERNAME%') -and [string]::IsNullOrEmpty('%MVNW_PASSWORD%'))) {"^ 146 | "$webclient.Credentials = new-object System.Net.NetworkCredential('%MVNW_USERNAME%', '%MVNW_PASSWORD%');"^ 147 | "}"^ 148 | "[Net.ServicePointManager]::SecurityProtocol = [Net.SecurityProtocolType]::Tls12; $webclient.DownloadFile('%WRAPPER_URL%', '%WRAPPER_JAR%')"^ 149 | "}" 150 | if "%MVNW_VERBOSE%" == "true" ( 151 | echo Finished downloading %WRAPPER_JAR% 152 | ) 153 | ) 154 | @REM End of extension 155 | 156 | @REM If specified, validate the SHA-256 sum of the Maven wrapper jar file 157 | SET WRAPPER_SHA_256_SUM="" 158 | FOR /F "usebackq tokens=1,2 delims==" %%A IN ("%MAVEN_PROJECTBASEDIR%\.mvn\wrapper\maven-wrapper.properties") DO ( 159 | IF "%%A"=="wrapperSha256Sum" SET WRAPPER_SHA_256_SUM=%%B 160 | ) 161 | IF NOT %WRAPPER_SHA_256_SUM%=="" ( 162 | powershell -Command "&{"^ 163 | "Import-Module $PSHOME\Modules\Microsoft.PowerShell.Utility -Function Get-FileHash;"^ 164 | "$hash = (Get-FileHash \"%WRAPPER_JAR%\" -Algorithm SHA256).Hash.ToLower();"^ 165 | "If('%WRAPPER_SHA_256_SUM%' -ne $hash){"^ 166 | " Write-Error 'Error: Failed to validate Maven wrapper SHA-256, your Maven wrapper might be compromised.';"^ 167 | " Write-Error 'Investigate or delete %WRAPPER_JAR% to attempt a clean download.';"^ 168 | " Write-Error 'If you updated your Maven version, you need to update the specified wrapperSha256Sum property.';"^ 169 | " exit 1;"^ 170 | "}"^ 171 | "}" 172 | if ERRORLEVEL 1 goto error 173 | ) 174 | 175 | @REM Provide a "standardized" way to retrieve the CLI args that will 176 | @REM work with both Windows and non-Windows executions. 177 | set MAVEN_CMD_LINE_ARGS=%* 178 | 179 | %MAVEN_JAVA_EXE% ^ 180 | %JVM_CONFIG_MAVEN_PROPS% ^ 181 | %MAVEN_OPTS% ^ 182 | %MAVEN_DEBUG_OPTS% ^ 183 | -classpath %WRAPPER_JAR% ^ 184 | "-Dmaven.multiModuleProjectDirectory=%MAVEN_PROJECTBASEDIR%" ^ 185 | %WRAPPER_LAUNCHER% %MAVEN_CONFIG% %* 186 | if ERRORLEVEL 1 goto error 187 | goto end 188 | 189 | :error 190 | set ERROR_CODE=1 191 | 192 | :end 193 | @endlocal & set ERROR_CODE=%ERROR_CODE% 194 | 195 | if not "%MAVEN_SKIP_RC%"=="" goto skipRcPost 196 | @REM check for post script, once with legacy .bat ending and once with .cmd ending 197 | if exist "%USERPROFILE%\mavenrc_post.bat" call "%USERPROFILE%\mavenrc_post.bat" 198 | if exist "%USERPROFILE%\mavenrc_post.cmd" call "%USERPROFILE%\mavenrc_post.cmd" 199 | :skipRcPost 200 | 201 | @REM pause the script if MAVEN_BATCH_PAUSE is set to 'on' 202 | if "%MAVEN_BATCH_PAUSE%"=="on" pause 203 | 204 | if "%MAVEN_TERMINATE_CMD%"=="on" exit %ERROR_CODE% 205 | 206 | cmd /C exit /B %ERROR_CODE% 207 | -------------------------------------------------------------------------------- /start/pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 4.0.0 5 | 6 | io.openliberty.guides 7 | guide-microprofile-config 8 | 1.0-SNAPSHOT 9 | war 10 | 11 | 12 | UTF-8 13 | UTF-8 14 | 11 15 | 11 16 | 17 | 9080 18 | 9443 19 | 20 | 21 | 22 | 23 | 24 | jakarta.platform 25 | jakarta.jakartaee-api 26 | 10.0.0 27 | provided 28 | 29 | 30 | org.eclipse.microprofile 31 | microprofile 32 | 7.0 33 | pom 34 | provided 35 | 36 | 37 | 38 | org.junit.jupiter 39 | junit-jupiter 40 | 5.13.0 41 | test 42 | 43 | 44 | org.jboss.resteasy 45 | resteasy-client 46 | 6.2.12.Final 47 | test 48 | 49 | 50 | org.jboss.resteasy 51 | resteasy-json-binding-provider 52 | 6.2.12.Final 53 | test 54 | 55 | 56 | org.glassfish 57 | jakarta.json 58 | 2.0.1 59 | test 60 | 61 | 62 | 63 | 64 | ${project.artifactId} 65 | 66 | 67 | org.apache.maven.plugins 68 | maven-war-plugin 69 | 3.4.0 70 | 71 | 72 | 73 | org.apache.maven.plugins 74 | maven-surefire-plugin 75 | 3.5.3 76 | 77 | 78 | 79 | io.openliberty.tools 80 | liberty-maven-plugin 81 | 3.11.3 82 | 83 | 84 | 85 | org.apache.maven.plugins 86 | maven-failsafe-plugin 87 | 3.5.3 88 | 89 | 90 | ${liberty.var.http.port} 91 | ${liberty.var.https.port} 92 | 93 | 94 | 95 | 96 | 97 | 98 | -------------------------------------------------------------------------------- /start/resources/CustomConfigSource.json: -------------------------------------------------------------------------------- 1 | { 2 | "config_ordinal":150, 3 | "io_openliberty_guides_email":"admin@guides.openliberty.io", 4 | "io_openliberty_guides_inventory_inMaintenance":false, 5 | "io_openliberty_guides_system_inMaintenance":false, 6 | "io_openliberty_guides_testConfigOverwrite":"CustomSource" 7 | } 8 | -------------------------------------------------------------------------------- /start/src/main/java/io/openliberty/guides/config/ConfigApplication.java: -------------------------------------------------------------------------------- 1 | // tag::copyright[] 2 | /******************************************************************************* 3 | * Copyright (c) 2017, 2022 IBM Corporation and others. 4 | * All rights reserved. This program and the accompanying materials 5 | * are made available under the terms of the Eclipse Public License 2.0 6 | * which accompanies this distribution, and is available at 7 | * http://www.eclipse.org/legal/epl-2.0/ 8 | * 9 | * SPDX-License-Identifier: EPL-2.0 10 | *******************************************************************************/ 11 | // end::copyright[] 12 | package io.openliberty.guides.config; 13 | 14 | // JAX-RS 15 | import jakarta.ws.rs.ApplicationPath; 16 | import jakarta.ws.rs.core.Application; 17 | 18 | @ApplicationPath("config") 19 | public class ConfigApplication extends Application { 20 | 21 | } 22 | -------------------------------------------------------------------------------- /start/src/main/java/io/openliberty/guides/config/ConfigResource.java: -------------------------------------------------------------------------------- 1 | // tag::copyright[] 2 | /******************************************************************************* 3 | * Copyright (c) 2017, 2022 IBM Corporation and others. 4 | * All rights reserved. This program and the accompanying materials 5 | * are made available under the terms of the Eclipse Public License 2.0 6 | * which accompanies this distribution, and is available at 7 | * http://www.eclipse.org/legal/epl-2.0/ 8 | * 9 | * SPDX-License-Identifier: EPL-2.0 10 | *******************************************************************************/ 11 | // end::copyright[] 12 | package io.openliberty.guides.config; 13 | 14 | import jakarta.enterprise.context.RequestScoped; 15 | import jakarta.ws.rs.core.MediaType; 16 | 17 | import jakarta.json.JsonObject; 18 | import jakarta.json.JsonObjectBuilder; 19 | import jakarta.json.Json; 20 | import jakarta.inject.Inject; 21 | import jakarta.ws.rs.GET; 22 | import jakarta.ws.rs.Path; 23 | import jakarta.ws.rs.Produces; 24 | 25 | import org.eclipse.microprofile.config.Config; 26 | import org.eclipse.microprofile.config.spi.ConfigSource; 27 | 28 | @RequestScoped 29 | @Path("/") 30 | public class ConfigResource { 31 | 32 | // tag::config[] 33 | @Inject 34 | private Config config; 35 | // end::config[] 36 | 37 | @GET 38 | @Produces(MediaType.APPLICATION_JSON) 39 | public JsonObject getAllConfig() { 40 | JsonObjectBuilder builder = Json.createObjectBuilder(); 41 | return builder.add("ConfigSources", sourceJsonBuilder()) 42 | .add("ConfigProperties", propertyJsonBuilder()).build(); 43 | } 44 | 45 | public JsonObject sourceJsonBuilder() { 46 | JsonObjectBuilder sourcesBuilder = Json.createObjectBuilder(); 47 | for (ConfigSource source : config.getConfigSources()) { 48 | sourcesBuilder.add(source.getName(), source.getOrdinal()); 49 | } 50 | return sourcesBuilder.build(); 51 | } 52 | 53 | public JsonObject propertyJsonBuilder() { 54 | JsonObjectBuilder propertiesBuilder = Json.createObjectBuilder(); 55 | for (String name : config.getPropertyNames()) { 56 | if (name.contains("io_openliberty_guides")) { 57 | propertiesBuilder.add(name, config.getValue(name, String.class)); 58 | } 59 | } 60 | return propertiesBuilder.build(); 61 | } 62 | 63 | } 64 | -------------------------------------------------------------------------------- /start/src/main/java/io/openliberty/guides/config/Email.java: -------------------------------------------------------------------------------- 1 | // tag::copyright[] 2 | /******************************************************************************* 3 | * Copyright (c) 2019 IBM Corporation and others. 4 | * All rights reserved. This program and the accompanying materials 5 | * are made available under the terms of the Eclipse Public License 2.0 6 | * which accompanies this distribution, and is available at 7 | * http://www.eclipse.org/legal/epl-2.0/ 8 | * 9 | * SPDX-License-Identifier: EPL-2.0 10 | *******************************************************************************/ 11 | // end::copyright[] 12 | 13 | package io.openliberty.guides.config; 14 | 15 | // tag::email[] 16 | public class Email { 17 | 18 | } 19 | // end::email[] 20 | -------------------------------------------------------------------------------- /start/src/main/java/io/openliberty/guides/inventory/InventoryApplication.java: -------------------------------------------------------------------------------- 1 | // tag::copyright[] 2 | /******************************************************************************* 3 | * Copyright (c) 2017, 2022 IBM Corporation and others. 4 | * All rights reserved. This program and the accompanying materials 5 | * are made available under the terms of the Eclipse Public License 2.0 6 | * which accompanies this distribution, and is available at 7 | * http://www.eclipse.org/legal/epl-2.0/ 8 | * 9 | * SPDX-License-Identifier: EPL-2.0 10 | *******************************************************************************/ 11 | // end::copyright[] 12 | package io.openliberty.guides.inventory; 13 | 14 | // JAX-RS 15 | import jakarta.ws.rs.ApplicationPath; 16 | import jakarta.ws.rs.core.Application; 17 | 18 | @ApplicationPath("inventory") 19 | public class InventoryApplication extends Application { 20 | 21 | } 22 | -------------------------------------------------------------------------------- /start/src/main/java/io/openliberty/guides/inventory/InventoryManager.java: -------------------------------------------------------------------------------- 1 | // tag::copyright[] 2 | /******************************************************************************* 3 | * Copyright (c) 2017, 2022 IBM Corporation and others. 4 | * All rights reserved. This program and the accompanying materials 5 | * are made available under the terms of the Eclipse Public License 2.0 6 | * which accompanies this distribution, and is available at 7 | * http://www.eclipse.org/legal/epl-2.0/ 8 | * 9 | * SPDX-License-Identifier: EPL-2.0 10 | *******************************************************************************/ 11 | // end::copyright[] 12 | // tag::manager[] 13 | package io.openliberty.guides.inventory; 14 | 15 | import java.util.ArrayList; 16 | import java.util.Collections; 17 | import java.util.List; 18 | import java.util.Properties; 19 | import jakarta.enterprise.context.ApplicationScoped; 20 | import io.openliberty.guides.inventory.model.InventoryList; 21 | import io.openliberty.guides.inventory.model.SystemData; 22 | 23 | @ApplicationScoped 24 | public class InventoryManager { 25 | 26 | private List systems = Collections.synchronizedList(new ArrayList<>()); 27 | private InventoryUtils invUtils = new InventoryUtils(); 28 | 29 | public Properties get(String hostname, int portNumber) { 30 | return invUtils.getProperties(hostname, portNumber); 31 | } 32 | 33 | public void add(String hostname, Properties systemProps) { 34 | Properties props = new Properties(); 35 | props.setProperty("os.name", systemProps.getProperty("os.name")); 36 | props.setProperty("user.name", systemProps.getProperty("user.name")); 37 | 38 | SystemData system = new SystemData(hostname, props); 39 | if (!systems.contains(system)) { 40 | systems.add(system); 41 | } 42 | } 43 | 44 | public InventoryList list() { 45 | return new InventoryList(systems); 46 | } 47 | 48 | } 49 | // end::manager[] 50 | -------------------------------------------------------------------------------- /start/src/main/java/io/openliberty/guides/inventory/InventoryResource.java: -------------------------------------------------------------------------------- 1 | // tag::copyright[] 2 | /******************************************************************************* 3 | * Copyright (c) 2017, 2022 IBM Corporation and others. 4 | * All rights reserved. This program and the accompanying materials 5 | * are made available under the terms of the Eclipse Public License 2.0 6 | * which accompanies this distribution, and is available at 7 | * http://www.eclipse.org/legal/epl-2.0/ 8 | * 9 | * SPDX-License-Identifier: EPL-2.0 10 | *******************************************************************************/ 11 | // end::copyright[] 12 | package io.openliberty.guides.inventory; 13 | 14 | import java.util.Properties; 15 | 16 | // CDI 17 | import jakarta.enterprise.context.RequestScoped; 18 | import jakarta.inject.Inject; 19 | import jakarta.ws.rs.GET; 20 | import jakarta.ws.rs.Path; 21 | import jakarta.ws.rs.PathParam; 22 | import jakarta.ws.rs.Produces; 23 | import jakarta.ws.rs.core.MediaType; 24 | import jakarta.ws.rs.core.Response; 25 | 26 | import io.openliberty.guides.inventory.model.InventoryList; 27 | 28 | // tag::RequestScoped[] 29 | @RequestScoped 30 | // end::RequestScoped[] 31 | @Path("systems") 32 | public class InventoryResource { 33 | 34 | // tag::Inject[] 35 | @Inject InventoryManager manager; 36 | // end::Inject[] 37 | 38 | @GET 39 | @Path("{hostname}") 40 | @Produces(MediaType.APPLICATION_JSON) 41 | public Response getPropertiesForHost(@PathParam("hostname") String hostname) { 42 | // Get properties 43 | Properties props = manager.get(hostname, 9080); 44 | if (props == null) { 45 | return Response.status(Response.Status.NOT_FOUND) 46 | .entity("{ \"error\" : \"Unknown hostname or the system service " 47 | + "may not be running on " + hostname + "\" }") 48 | .build(); 49 | } 50 | 51 | // Add properties to inventory 52 | manager.add(hostname, props); 53 | return Response.ok(props).build(); 54 | } 55 | 56 | @GET 57 | @Produces(MediaType.APPLICATION_JSON) 58 | public InventoryList listContents() { 59 | return manager.list(); 60 | } 61 | } 62 | -------------------------------------------------------------------------------- /start/src/main/java/io/openliberty/guides/inventory/InventoryUtils.java: -------------------------------------------------------------------------------- 1 | // tag::copyright[] 2 | /******************************************************************************* 3 | * Copyright (c) 2017, 2023 IBM Corporation and others. 4 | * All rights reserved. This program and the accompanying materials 5 | * are made available under the terms of the Eclipse Public License 2.0 6 | * which accompanies this distribution, and is available at 7 | * http://www.eclipse.org/legal/epl-2.0/ 8 | * 9 | * SPDX-License-Identifier: EPL-2.0 10 | *******************************************************************************/ 11 | // end::copyright[] 12 | package io.openliberty.guides.inventory; 13 | 14 | import java.net.MalformedURLException; 15 | import java.net.URL; 16 | import java.net.UnknownHostException; 17 | import java.util.Properties; 18 | 19 | import org.eclipse.microprofile.rest.client.RestClientBuilder; 20 | import io.openliberty.guides.inventory.client.SystemClient; 21 | import io.openliberty.guides.inventory.client.UnknownUrlException; 22 | import jakarta.ws.rs.ProcessingException; 23 | 24 | public class InventoryUtils { 25 | 26 | // tag::builder[] 27 | public Properties getProperties(String hostname, int portNumber) { 28 | String customURLString = "http://" + hostname + ":" + portNumber + "/system"; 29 | URL customURL = null; 30 | try { 31 | customURL = new URL(customURLString); 32 | SystemClient customRestClient = RestClientBuilder.newBuilder() 33 | .baseUrl(customURL) 34 | .build(SystemClient.class); 35 | return customRestClient.getProperties(); 36 | } catch (ProcessingException ex) { 37 | handleProcessingException(ex); 38 | } catch (UnknownUrlException e) { 39 | System.err.println("The given URL is unreachable."); 40 | } catch (MalformedURLException e) { 41 | System.err.println("The given URL is not formatted correctly."); 42 | } 43 | return null; 44 | } 45 | // end::builder[] 46 | 47 | public void handleProcessingException(ProcessingException ex) { 48 | Throwable rootEx = ex; 49 | while (rootEx.getCause() != null) { 50 | rootEx = rootEx.getCause(); 51 | } 52 | if (rootEx != null && rootEx instanceof UnknownHostException) { 53 | System.err.println("The specified host is unknown."); 54 | } else { 55 | throw ex; 56 | } 57 | } 58 | 59 | } 60 | -------------------------------------------------------------------------------- /start/src/main/java/io/openliberty/guides/inventory/client/SystemClient.java: -------------------------------------------------------------------------------- 1 | // tag::copyright[] 2 | /******************************************************************************* 3 | * Copyright (c) 2017, 2022 IBM Corporation and others. 4 | * All rights reserved. This program and the accompanying materials 5 | * are made available under the terms of the Eclipse Public License 2.0 6 | * which accompanies this distribution, and is available at 7 | * http://www.eclipse.org/legal/epl-2.0/ 8 | * 9 | * SPDX-License-Identifier: EPL-2.0 10 | *******************************************************************************/ 11 | // end::copyright[] 12 | // tag::client[] 13 | package io.openliberty.guides.inventory.client; 14 | 15 | import java.util.Properties; 16 | 17 | import jakarta.ws.rs.GET; 18 | import jakarta.ws.rs.Path; 19 | import jakarta.ws.rs.ProcessingException; 20 | import jakarta.ws.rs.Produces; 21 | import jakarta.ws.rs.core.MediaType; 22 | 23 | import org.eclipse.microprofile.rest.client.annotation.RegisterProvider; 24 | import org.eclipse.microprofile.rest.client.inject.RegisterRestClient; 25 | 26 | // tag::annotations[] 27 | 28 | @RegisterRestClient 29 | @RegisterProvider(UnknownUrlExceptionMapper.class) 30 | @Path("/properties") 31 | public interface SystemClient { 32 | // end::annotations[] 33 | @GET 34 | @Produces(MediaType.APPLICATION_JSON) 35 | Properties getProperties() throws UnknownUrlException, ProcessingException; 36 | } 37 | // end::client[] 38 | -------------------------------------------------------------------------------- /start/src/main/java/io/openliberty/guides/inventory/client/UnknownUrlException.java: -------------------------------------------------------------------------------- 1 | // tag::copyright[] 2 | /******************************************************************************* 3 | * Copyright (c) 2017, 2018 IBM Corporation and others. 4 | * All rights reserved. This program and the accompanying materials 5 | * are made available under the terms of the Eclipse Public License 2.0 6 | * which accompanies this distribution, and is available at 7 | * http://www.eclipse.org/legal/epl-2.0/ 8 | * 9 | * SPDX-License-Identifier: EPL-2.0 10 | *******************************************************************************/ 11 | // end::copyright[] 12 | // tag::exception[] 13 | package io.openliberty.guides.inventory.client; 14 | 15 | public class UnknownUrlException extends Exception { 16 | 17 | private static final long serialVersionUID = 1L; 18 | 19 | public UnknownUrlException() { 20 | super(); 21 | } 22 | 23 | public UnknownUrlException(String message) { 24 | super(message); 25 | } 26 | } 27 | // end::exception[] 28 | -------------------------------------------------------------------------------- /start/src/main/java/io/openliberty/guides/inventory/client/UnknownUrlExceptionMapper.java: -------------------------------------------------------------------------------- 1 | // tag::copyright[] 2 | /******************************************************************************* 3 | * Copyright (c) 2017, 2022 IBM Corporation and others. 4 | * All rights reserved. This program and the accompanying materials 5 | * are made available under the terms of the Eclipse Public License 2.0 6 | * which accompanies this distribution, and is available at 7 | * http://www.eclipse.org/legal/epl-2.0/ 8 | * 9 | * SPDX-License-Identifier: EPL-2.0 10 | *******************************************************************************/ 11 | // end::copyright[] 12 | // tag::mapper[] 13 | package io.openliberty.guides.inventory.client; 14 | 15 | import java.util.logging.Logger; 16 | import jakarta.ws.rs.core.MultivaluedMap; 17 | import jakarta.ws.rs.core.Response; 18 | import jakarta.ws.rs.ext.Provider; 19 | import org.eclipse.microprofile.rest.client.ext.ResponseExceptionMapper; 20 | 21 | @Provider 22 | public class UnknownUrlExceptionMapper 23 | implements ResponseExceptionMapper { 24 | Logger LOG = Logger.getLogger(UnknownUrlExceptionMapper.class.getName()); 25 | 26 | @Override 27 | public boolean handles(int status, MultivaluedMap headers) { 28 | LOG.info("status = " + status); 29 | return status == 404; 30 | } 31 | 32 | @Override 33 | public UnknownUrlException toThrowable(Response response) { 34 | return new UnknownUrlException(); 35 | } 36 | } 37 | // end::mapper[] 38 | -------------------------------------------------------------------------------- /start/src/main/java/io/openliberty/guides/inventory/model/InventoryList.java: -------------------------------------------------------------------------------- 1 | // tag::copyright[] 2 | /******************************************************************************* 3 | * Copyright (c) 2017, 2018 IBM Corporation and others. 4 | * All rights reserved. This program and the accompanying materials 5 | * are made available under the terms of the Eclipse Public License 2.0 6 | * which accompanies this distribution, and is available at 7 | * http://www.eclipse.org/legal/epl-2.0/ 8 | * 9 | * SPDX-License-Identifier: EPL-2.0 10 | *******************************************************************************/ 11 | // end::copyright[] 12 | package io.openliberty.guides.inventory.model; 13 | 14 | import java.util.List; 15 | 16 | public class InventoryList { 17 | 18 | private List systems; 19 | 20 | public InventoryList(List systems) { 21 | this.systems = systems; 22 | } 23 | 24 | public List getSystems() { 25 | return systems; 26 | } 27 | 28 | public int getTotal() { 29 | return systems.size(); 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /start/src/main/java/io/openliberty/guides/inventory/model/SystemData.java: -------------------------------------------------------------------------------- 1 | // tag::copyright[] 2 | /******************************************************************************* 3 | * Copyright (c) 2017, 2018 IBM Corporation and others. 4 | * All rights reserved. This program and the accompanying materials 5 | * are made available under the terms of the Eclipse Public License 2.0 6 | * which accompanies this distribution, and is available at 7 | * http://www.eclipse.org/legal/epl-2.0/ 8 | * 9 | * SPDX-License-Identifier: EPL-2.0 10 | *******************************************************************************/ 11 | // end::copyright[] 12 | package io.openliberty.guides.inventory.model; 13 | 14 | import java.util.Properties; 15 | 16 | public class SystemData { 17 | 18 | private final String hostname; 19 | private final Properties properties; 20 | 21 | public SystemData(String hostname, Properties properties) { 22 | this.hostname = hostname; 23 | this.properties = properties; 24 | } 25 | 26 | public String getHostname() { 27 | return hostname; 28 | } 29 | 30 | public Properties getProperties() { 31 | return properties; 32 | } 33 | 34 | @Override 35 | public boolean equals(Object host) { 36 | if (host instanceof SystemData) { 37 | return hostname.equals(((SystemData) host).getHostname()); 38 | } 39 | return false; 40 | } 41 | } 42 | -------------------------------------------------------------------------------- /start/src/main/java/io/openliberty/guides/system/SystemApplication.java: -------------------------------------------------------------------------------- 1 | // tag::copyright[] 2 | /******************************************************************************* 3 | * Copyright (c) 2017, 2022 IBM Corporation and others. 4 | * All rights reserved. This program and the accompanying materials 5 | * are made available under the terms of the Eclipse Public License 2.0 6 | * which accompanies this distribution, and is available at 7 | * http://www.eclipse.org/legal/epl-2.0/ 8 | * 9 | * SPDX-License-Identifier: EPL-2.0 10 | *******************************************************************************/ 11 | // end::copyright[] 12 | package io.openliberty.guides.system; 13 | 14 | // JAX-RS 15 | import jakarta.ws.rs.core.Application; 16 | import jakarta.ws.rs.ApplicationPath; 17 | 18 | @ApplicationPath("system") 19 | public class SystemApplication extends Application { 20 | 21 | } 22 | -------------------------------------------------------------------------------- /start/src/main/java/io/openliberty/guides/system/SystemConfig.java: -------------------------------------------------------------------------------- 1 | // tag::copyright[] 2 | /******************************************************************************* 3 | * Copyright (c) 2017, 2022 IBM Corporation and others. 4 | * All rights reserved. This program and the accompanying materials 5 | * are made available under the terms of the Eclipse Public License 2.0 6 | * which accompanies this distribution, and is available at 7 | * http://www.eclipse.org/legal/epl-2.0/ 8 | * 9 | * SPDX-License-Identifier: EPL-2.0 10 | *******************************************************************************/ 11 | // end::copyright[] 12 | package io.openliberty.guides.system; 13 | 14 | import jakarta.enterprise.context.RequestScoped; 15 | import jakarta.inject.Inject; 16 | 17 | import jakarta.inject.Provider; 18 | import org.eclipse.microprofile.config.inject.ConfigProperty; 19 | import io.openliberty.guides.config.Email; 20 | 21 | @RequestScoped 22 | public class SystemConfig { 23 | 24 | // tag::config[] 25 | @Inject 26 | @ConfigProperty(name = "io_openliberty_guides_system_inMaintenance") 27 | Provider inMaintenance; 28 | // end::config[] 29 | 30 | // tag::custom-converter[] 31 | @Inject 32 | @ConfigProperty(name = "io_openliberty_guides_email") 33 | private Provider email; 34 | // end::custom-converter[] 35 | 36 | public boolean isInMaintenance() { 37 | return inMaintenance.get(); 38 | } 39 | 40 | // tag::getEmail[] 41 | public Email getEmail() { 42 | return email.get(); 43 | } 44 | // end::getEmail[] 45 | 46 | } 47 | -------------------------------------------------------------------------------- /start/src/main/java/io/openliberty/guides/system/SystemResource.java: -------------------------------------------------------------------------------- 1 | // tag::copyright[] 2 | /******************************************************************************* 3 | * Copyright (c) 2017, 2022 IBM Corporation and others. 4 | * All rights reserved. This program and the accompanying materials 5 | * are made available under the terms of the Eclipse Public License 2.0 6 | * which accompanies this distribution, and is available at 7 | * http://www.eclipse.org/legal/epl-2.0/ 8 | * 9 | * SPDX-License-Identifier: EPL-2.0 10 | *******************************************************************************/ 11 | // end::copyright[] 12 | package io.openliberty.guides.system; 13 | 14 | // CDI 15 | import jakarta.enterprise.context.RequestScoped; 16 | import jakarta.ws.rs.GET; 17 | import jakarta.inject.Inject; 18 | import jakarta.ws.rs.core.Response; 19 | 20 | // JAX-RS 21 | import jakarta.ws.rs.Path; 22 | import jakarta.ws.rs.Produces; 23 | import jakarta.ws.rs.core.MediaType; 24 | 25 | @RequestScoped 26 | @Path("properties") 27 | public class SystemResource { 28 | 29 | // tag::config-injection[] 30 | @Inject 31 | SystemConfig systemConfig; 32 | // end::config-injection[] 33 | 34 | @GET 35 | @Produces(MediaType.APPLICATION_JSON) 36 | public Response getProperties() { 37 | if (!systemConfig.isInMaintenance()) { 38 | return Response.ok(System.getProperties()).build(); 39 | } else { 40 | return Response.status(Response.Status.SERVICE_UNAVAILABLE) 41 | .entity("ERROR: Service is currently in maintenance. Contact: " 42 | + systemConfig.getEmail().toString()) 43 | .build(); 44 | } 45 | } 46 | 47 | } 48 | -------------------------------------------------------------------------------- /start/src/main/liberty/config/server.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | jakartaee-10.0 5 | microprofile-7.0 6 | restfulWS 7 | jsonb 8 | jsonp 9 | cdi 10 | mpRestClient 11 | 12 | mpConfig 13 | 14 | 15 | 16 | 17 | 18 | 19 | 21 | 22 | 24 | 25 | -------------------------------------------------------------------------------- /start/src/main/resources/META-INF/microprofile-config.properties: -------------------------------------------------------------------------------- 1 | config_ordinal=100 2 | io_openliberty_guides_port_number=9080 3 | io_openliberty_guides_inventory_inMaintenance=false 4 | io_openliberty_guides_system_inMaintenance=false 5 | io_openliberty_guides_testConfigOverwrite=DefaultSource 6 | -------------------------------------------------------------------------------- /start/src/main/resources/META-INF/services/.gitkeep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/OpenLiberty/guide-microprofile-config/8d870ed767a0ae27b2cbc35c40e157679bd40457/start/src/main/resources/META-INF/services/.gitkeep -------------------------------------------------------------------------------- /start/src/main/webapp/WEB-INF/web.xml: -------------------------------------------------------------------------------- 1 | 2 | 5 | Liberty Project 6 | 7 | 8 | index.html 9 | 10 | -------------------------------------------------------------------------------- /start/src/main/webapp/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/OpenLiberty/guide-microprofile-config/8d870ed767a0ae27b2cbc35c40e157679bd40457/start/src/main/webapp/favicon.ico -------------------------------------------------------------------------------- /start/src/main/webapp/index.html: -------------------------------------------------------------------------------- 1 | 16 | 17 | 18 |

Welcome to your Open Liberty application

19 |

Open Liberty is a lightweight open framework for building fast and efficient cloud-native Java microservices. Find out more at openliberty.io.

20 |
21 |

Eclipse MicroProfile

22 |

23 | The Eclipse MicroProfile project is an open community with the aim of optimizing enterprise Java for a microservices architecture. 24 | MicroProfile evolves with guidance from the community. 25 |

26 |

27 | If you want to share your thoughts, you can post straight to the 28 | MicroProfile Google group. 29 |

30 |

31 | For more information about the features used in this application, see the Open Liberty documentation: 32 |

41 |

42 |
43 | 44 | -------------------------------------------------------------------------------- /start/src/test/java/it/io/openliberty/guides/config/ConfigITUtil.java: -------------------------------------------------------------------------------- 1 | // tag::copyright[] 2 | /******************************************************************************* 3 | * Copyright (c) 2017, 2022 IBM Corporation and others. 4 | * All rights reserved. This program and the accompanying materials 5 | * are made available under the terms of the Eclipse Public License 2.0 6 | * which accompanies this distribution, and is available at 7 | * http://www.eclipse.org/legal/epl-2.0/ 8 | * 9 | * SPDX-License-Identifier: EPL-2.0 10 | *******************************************************************************/ 11 | // end::copyright[] 12 | package it.io.openliberty.guides.config; 13 | 14 | import java.io.BufferedReader; 15 | import java.io.File; 16 | import java.io.FileWriter; 17 | import java.io.FileReader; 18 | import java.io.IOException; 19 | import jakarta.json.bind.Jsonb; 20 | import jakarta.json.bind.JsonbBuilder; 21 | import jakarta.ws.rs.client.Client; 22 | import jakarta.ws.rs.core.Response; 23 | 24 | /* 25 | * =========================================================================== 26 | * HELPER METHODS 27 | * =========================================================================== 28 | * 29 | */ 30 | public class ConfigITUtil { 31 | private static final String EMAIL = "admin@guides.openliberty.io"; 32 | private static final String TEST_CONFIG = "CustomSource"; 33 | 34 | public static void setDefaultJsonFile(String source) { 35 | CustomConfig config = new CustomConfig(150, false, false, EMAIL, TEST_CONFIG); 36 | createJsonOverwrite(source, config); 37 | } 38 | 39 | /** 40 | * Change the inventory.inMaintenance value for the config source. 41 | */ 42 | public static void switchInventoryMaintenance(String source, boolean newValue) { 43 | CustomConfig config = new CustomConfig(150, newValue, false, EMAIL, TEST_CONFIG); 44 | createJsonOverwrite(source, config); 45 | } 46 | 47 | /** 48 | * Change the email for the config source. 49 | */ 50 | public static void changeEmail(String source, String newEmail) { 51 | CustomConfig config = new CustomConfig(150, true, false, newEmail, TEST_CONFIG); 52 | createJsonOverwrite(source, config); 53 | } 54 | 55 | public static void createJsonOverwrite(String source, CustomConfig config) { 56 | // Create Jsonb and serialize 57 | Jsonb jsonb = JsonbBuilder.create(); 58 | String result = jsonb.toJson(config); 59 | overwriteFile(source, result); 60 | } 61 | 62 | /** 63 | * Read the property values from a local file. 64 | */ 65 | public static String readPropertyValueInFile(String propName, String fileName) { 66 | String propValue = ""; 67 | String line = ""; 68 | try { 69 | File f = new File(fileName); 70 | if (f.exists()) { 71 | BufferedReader reader = new BufferedReader(new FileReader(f)); 72 | while ((line = reader.readLine()) != null) { 73 | if (line.contains(propName)) { 74 | propValue = line.split("=")[1]; 75 | } 76 | } 77 | reader.close(); 78 | return propValue; 79 | } else { 80 | System.out.println("File " + fileName + " does not exist..."); 81 | } 82 | } catch (IOException e) { 83 | e.printStackTrace(); 84 | } 85 | return propValue; 86 | } 87 | 88 | /** 89 | * Overwrite a local file. 90 | */ 91 | public static void overwriteFile(String fileName, String newContent) { 92 | try { 93 | File f = new File(fileName); 94 | if (f.exists()) { 95 | FileWriter fWriter = new FileWriter(f, false); // true to append 96 | // false to overwrite. 97 | fWriter.write(newContent); 98 | fWriter.close(); 99 | Thread.sleep(600); 100 | } else { 101 | System.out.println("File " + fileName + " does not exist"); 102 | } 103 | } catch (Exception e) { 104 | e.printStackTrace(); 105 | } 106 | } 107 | 108 | public static Response getResponse(Client client, String url) { 109 | Response response = client.target(url).request().get(); 110 | return response; 111 | } 112 | 113 | public static String getStringFromURL(Client client, String url) { 114 | Response response = client.target(url).request().get(); 115 | String result = response.readEntity(String.class); 116 | response.close(); 117 | return result; 118 | } 119 | 120 | } 121 | -------------------------------------------------------------------------------- /start/src/test/java/it/io/openliberty/guides/config/CustomConfig.java: -------------------------------------------------------------------------------- 1 | // tag::copyright[] 2 | /******************************************************************************* 3 | * Copyright (c) 2017, 2023 IBM Corporation and others. 4 | * All rights reserved. This program and the accompanying materials 5 | * are made available under the terms of the Eclipse Public License 2.0 6 | * which accompanies this distribution, and is available at 7 | * http://www.eclipse.org/legal/epl-2.0/ 8 | * 9 | * SPDX-License-Identifier: EPL-2.0 10 | *******************************************************************************/ 11 | // end::copyright[] 12 | 13 | package it.io.openliberty.guides.config; 14 | 15 | import jakarta.json.bind.annotation.JsonbProperty; 16 | 17 | public class CustomConfig { 18 | private int config_ordinal; 19 | private boolean io_openliberty_guides_inventory_inMaintenance; 20 | private boolean io_openliberty_guides_system_inMaintenance; 21 | private String io_openliberty_guides_email; 22 | private String io_openliberty_guides_testConfigOverwrite; 23 | 24 | public CustomConfig(int ordinal, boolean inventory, boolean system, String email, 25 | String testConfig) { 26 | this.setConfigOrdinal(ordinal); 27 | this.setInventoryInMaintenance(inventory); 28 | this.setSystemInMaintenance(system); 29 | this.setEmail(email); 30 | this.setTestConfigOverwrite(testConfig); 31 | } 32 | 33 | @JsonbProperty("config_ordinal") 34 | public int getConfigOrdinal() { 35 | return config_ordinal; 36 | } 37 | 38 | public void setConfigOrdinal(int configOrdinal) { 39 | this.config_ordinal = configOrdinal; 40 | } 41 | 42 | @JsonbProperty("io_openliberty_guides_inventory_inMaintenance") 43 | public boolean isInventoryInMaintenance() { 44 | return io_openliberty_guides_inventory_inMaintenance; 45 | } 46 | 47 | public void setInventoryInMaintenance(boolean inventoryInMaintenance) { 48 | this.io_openliberty_guides_inventory_inMaintenance = 49 | inventoryInMaintenance; 50 | } 51 | 52 | @JsonbProperty("io_openliberty_guides_system_inMaintenance") 53 | public boolean isSystemInMaintenance() { 54 | return io_openliberty_guides_system_inMaintenance; 55 | } 56 | 57 | public void setSystemInMaintenance(boolean systemInMaintenance) { 58 | this.io_openliberty_guides_system_inMaintenance = 59 | systemInMaintenance; 60 | } 61 | 62 | @JsonbProperty("io_openliberty_guides_email") 63 | public String getEmail() { 64 | return io_openliberty_guides_email; 65 | } 66 | 67 | public void setEmail(String email) { 68 | this.io_openliberty_guides_email = email; 69 | } 70 | 71 | @JsonbProperty("io_openliberty_guides_testConfigOverwrite") 72 | public String getTestConfigOverwrite() { 73 | return io_openliberty_guides_testConfigOverwrite; 74 | } 75 | 76 | public void setTestConfigOverwrite(String testConfigOverwrite) { 77 | this.io_openliberty_guides_testConfigOverwrite = 78 | testConfigOverwrite; 79 | } 80 | 81 | } 82 | -------------------------------------------------------------------------------- /start/src/test/java/it/io/openliberty/guides/inventory/InventoryEndpointIT.java: -------------------------------------------------------------------------------- 1 | // tag::copyright[] 2 | /******************************************************************************* 3 | * Copyright (c) 2017, 2024 IBM Corporation and others. 4 | * All rights reserved. This program and the accompanying materials 5 | * are made available under the terms of the Eclipse Public License 2.0 6 | * which accompanies this distribution, and is available at 7 | * http://www.eclipse.org/legal/epl-2.0/ 8 | * 9 | * SPDX-License-Identifier: EPL-2.0 10 | *******************************************************************************/ 11 | // end::copyright[] 12 | // tag::testClass[] 13 | package it.io.openliberty.guides.inventory; 14 | 15 | import static org.junit.jupiter.api.Assertions.assertEquals; 16 | import static org.junit.jupiter.api.Assertions.assertTrue; 17 | 18 | import jakarta.json.JsonArray; 19 | import jakarta.json.JsonObject; 20 | import jakarta.ws.rs.client.Client; 21 | import jakarta.ws.rs.client.ClientBuilder; 22 | import jakarta.ws.rs.core.MediaType; 23 | import jakarta.ws.rs.core.Response; 24 | 25 | import org.junit.jupiter.api.AfterEach; 26 | import org.junit.jupiter.api.BeforeAll; 27 | import org.junit.jupiter.api.BeforeEach; 28 | import org.junit.jupiter.api.MethodOrderer.OrderAnnotation; 29 | import org.junit.jupiter.api.Order; 30 | import org.junit.jupiter.api.Test; 31 | import org.junit.jupiter.api.TestMethodOrder; 32 | 33 | @TestMethodOrder(OrderAnnotation.class) 34 | public class InventoryEndpointIT { 35 | 36 | private static String port; 37 | private static String baseUrl; 38 | 39 | private Client client; 40 | 41 | private final String SYSTEM_PROPERTIES = "system/properties"; 42 | private final String INVENTORY_SYSTEMS = "inventory/systems"; 43 | 44 | @BeforeAll 45 | public static void oneTimeSetup() { 46 | port = System.getProperty("http.port"); 47 | baseUrl = "http://localhost:" + port + "/"; 48 | } 49 | 50 | @BeforeEach 51 | public void setup() { 52 | client = ClientBuilder.newClient(); 53 | } 54 | 55 | @AfterEach 56 | public void teardown() { 57 | client.close(); 58 | } 59 | 60 | // tag::tests[] 61 | @Test 62 | @Order(1) 63 | // tag::testHostRegistration[] 64 | public void testHostRegistration() { 65 | this.visitLocalhost(); 66 | 67 | Response response = this.getResponse(baseUrl + INVENTORY_SYSTEMS); 68 | this.assertResponse(baseUrl, response); 69 | 70 | JsonObject obj = response.readEntity(JsonObject.class); 71 | 72 | JsonArray systems = obj.getJsonArray("systems"); 73 | 74 | boolean localhostExists = false; 75 | for (int n = 0; n < systems.size(); n++) { 76 | localhostExists = systems.getJsonObject(n).get("hostname").toString() 77 | .contains("localhost"); 78 | if (localhostExists) { 79 | break; 80 | } 81 | } 82 | assertTrue(localhostExists, "A host was registered, but it was not localhost"); 83 | 84 | response.close(); 85 | } 86 | // end::testHostRegistration[] 87 | 88 | @Test 89 | @Order(2) 90 | // tag::testSystemPropertiesMatch[] 91 | public void testSystemPropertiesMatch() { 92 | Response invResponse = this.getResponse(baseUrl + INVENTORY_SYSTEMS); 93 | Response sysResponse = this.getResponse(baseUrl + SYSTEM_PROPERTIES); 94 | 95 | this.assertResponse(baseUrl, invResponse); 96 | this.assertResponse(baseUrl, sysResponse); 97 | 98 | JsonObject jsonFromInventory = (JsonObject) invResponse.readEntity(JsonObject.class) 99 | .getJsonArray("systems").getJsonObject(0).get("properties"); 100 | 101 | JsonObject jsonFromSystem = sysResponse.readEntity(JsonObject.class); 102 | 103 | String osNameFromInventory = jsonFromInventory.getString("os.name"); 104 | String osNameFromSystem = jsonFromSystem.getString("os.name"); 105 | this.assertProperty("os.name", "localhost", osNameFromSystem, osNameFromInventory); 106 | 107 | String userNameFromInventory = jsonFromInventory.getString("user.name"); 108 | String userNameFromSystem = jsonFromSystem.getString("user.name"); 109 | this.assertProperty("user.name", "localhost", userNameFromSystem, 110 | userNameFromInventory); 111 | 112 | invResponse.close(); 113 | sysResponse.close(); 114 | } 115 | // end::testSystemPropertiesMatch[] 116 | 117 | @Test 118 | @Order(3) 119 | // tag::testUnknownHost[] 120 | public void testUnknownHost() { 121 | Response response = this.getResponse(baseUrl + INVENTORY_SYSTEMS); 122 | this.assertResponse(baseUrl, response); 123 | 124 | Response badResponse = client 125 | .target(baseUrl + INVENTORY_SYSTEMS + "/" + "badhostname") 126 | .request(MediaType.APPLICATION_JSON).get(); 127 | 128 | assertEquals(404, badResponse.getStatus(), 129 | "BadResponse expected status: 404. Response code not as expected."); 130 | 131 | String stringObj = badResponse.readEntity(String.class); 132 | assertTrue(stringObj.contains("error"), 133 | "badhostname is not a valid host but it didn't raise an error"); 134 | 135 | response.close(); 136 | badResponse.close(); 137 | } 138 | // end::testUnknownHost[] 139 | // end::tests[] 140 | // tag::helpers[] 141 | // tag::javadoc[] 142 | 143 | /** 144 | *

145 | * Returns response information from the specified URL. 146 | *

147 | * 148 | * @param url - target URL. 149 | * @return Response object with the response from the specified URL. 150 | */ 151 | // end::javadoc[] 152 | private Response getResponse(String url) { 153 | return client.target(url).request().get(); 154 | } 155 | 156 | // tag::javadoc[] 157 | /** 158 | *

159 | * Asserts that the given URL has the correct response code of 200. 160 | *

161 | * 162 | * @param url - target URL. 163 | * @param response - response received from the target URL. 164 | */ 165 | // end::javadoc[] 166 | private void assertResponse(String url, Response response) { 167 | assertEquals(200, response.getStatus(), "Incorrect response code from " + url); 168 | } 169 | 170 | // tag::javadoc[] 171 | /** 172 | * Asserts that the specified JVM system property is equivalent in both the 173 | * system and inventory services. 174 | * 175 | * @param propertyName - name of the system property to check. 176 | * @param hostname - name of JVM's host. 177 | * @param expected - expected name. 178 | * @param actual - actual name. 179 | */ 180 | // end::javadoc[] 181 | private void assertProperty(String propertyName, String hostname, String expected, 182 | String actual) { 183 | assertEquals(expected, actual, 184 | "JVM system property [" + propertyName + "] " 185 | + "in the system service does not match the one stored in " 186 | + "the inventory service for " + hostname); 187 | } 188 | 189 | // tag::javadoc[] 190 | /** 191 | * Makes a simple GET request to inventory/localhost. 192 | */ 193 | // end::javadoc[] 194 | private void visitLocalhost() { 195 | Response response = this.getResponse(baseUrl + SYSTEM_PROPERTIES); 196 | this.assertResponse(baseUrl, response); 197 | response.close(); 198 | 199 | Response targetResponse = client.target(baseUrl + INVENTORY_SYSTEMS + "/localhost") 200 | .request().get(); 201 | targetResponse.close(); 202 | } 203 | // end::helpers[] 204 | } 205 | // end::testClass[] 206 | -------------------------------------------------------------------------------- /start/src/test/java/it/io/openliberty/guides/system/SystemEndpointIT.java: -------------------------------------------------------------------------------- 1 | // tag::copyright[] 2 | /******************************************************************************* 3 | * Copyright (c) 2017, 2024 IBM Corporation and others. 4 | * All rights reserved. This program and the accompanying materials 5 | * are made available under the terms of the Eclipse Public License 2.0 6 | * which accompanies this distribution, and is available at 7 | * http://www.eclipse.org/legal/epl-2.0/ 8 | * 9 | * SPDX-License-Identifier: EPL-2.0 10 | *******************************************************************************/ 11 | // end::copyright[] 12 | package it.io.openliberty.guides.system; 13 | 14 | import static org.junit.jupiter.api.Assertions.assertEquals; 15 | import jakarta.json.JsonObject; 16 | import jakarta.ws.rs.client.Client; 17 | import jakarta.ws.rs.client.ClientBuilder; 18 | import jakarta.ws.rs.client.WebTarget; 19 | import jakarta.ws.rs.core.Response; 20 | 21 | import org.junit.jupiter.api.Test; 22 | 23 | public class SystemEndpointIT { 24 | 25 | @Test 26 | public void testGetProperties() { 27 | String port = System.getProperty("http.port"); 28 | String url = "http://localhost:" + port + "/"; 29 | 30 | Client client = ClientBuilder.newClient(); 31 | 32 | WebTarget target = client.target(url + "system/properties"); 33 | Response response = target.request().get(); 34 | 35 | assertEquals(200, response.getStatus(), "Incorrect response code from " + url); 36 | 37 | JsonObject obj = response.readEntity(JsonObject.class); 38 | 39 | assertEquals(System.getProperty("os.name"), obj.getString("os.name"), 40 | "The system property for the local and remote JVM should match"); 41 | 42 | response.close(); 43 | } 44 | } 45 | --------------------------------------------------------------------------------