├── .ci-orchestrator └── sample-liberty-build.yml ├── .github ├── dependabot.yml └── workflows │ └── add-to-projects.yml ├── .gitignore ├── .mvn └── wrapper │ ├── maven-wrapper.jar │ └── maven-wrapper.properties ├── .one-pipeline.yaml ├── .secrets.baseline ├── .whitesource ├── CONTRIBUTING.md ├── Dockerfile ├── LICENSE ├── Makefile ├── README.md ├── ebcDockerBuilderLGS.jenkinsfile ├── mvnw ├── mvnw.cmd ├── pom.xml ├── scripts ├── build-app.sh ├── build-manifest.sh └── pipeline │ ├── await-ciorchestrator.sh │ ├── check-build.sh │ ├── ci_to_secure_pipeline_scan.sh │ └── request-ciorchestrator.sh └── src ├── main ├── java │ └── io │ │ └── openliberty │ │ └── sample │ │ ├── SampleApplication.java │ │ ├── config │ │ ├── ConfigResource.java │ │ └── CustomConfigSource.java │ │ └── system │ │ ├── SystemConfig.java │ │ ├── SystemHealth.java │ │ ├── SystemResource.java │ │ └── SystemRuntime.java ├── liberty │ └── config │ │ └── server.xml ├── resources │ └── META-INF │ │ ├── CustomConfigSource.json │ │ ├── microprofile-config.properties │ │ └── services │ │ └── org.eclipse.microprofile.config.spi.ConfigSource └── webapp │ ├── WEB-INF │ └── web.xml │ ├── css │ └── main.css │ ├── fonts │ ├── BunueloCleanPro-Light.otf │ └── BunueloCleanPro-SemiBold.otf │ ├── img │ ├── carets │ │ ├── caret_down_blue.svg │ │ ├── caret_down_green.svg │ │ ├── caret_down_orange.svg │ │ ├── caret_up_blue.svg │ │ ├── caret_up_green.svg │ │ └── caret_up_orange.svg │ ├── config.svg │ ├── favicon.ico │ ├── footer_main.png │ ├── github_logo.png │ ├── gitter_logo.png │ ├── groups_io_logo.jpeg │ ├── header_ufo.png │ ├── health.svg │ ├── metrics.svg │ ├── open_liberty_logo.png │ ├── stack_overflow_logo.png │ ├── sysProps.svg │ ├── systemDown.svg │ ├── systemUp.svg │ └── twitter_logo.png │ ├── index.html │ └── js │ └── mpData.js └── test └── java └── it └── io └── openliberty └── sample └── health ├── HealthIT.java └── HealthUtilIT.java /.ci-orchestrator/sample-liberty-build.yml: -------------------------------------------------------------------------------- 1 | type: pipeline_definition 2 | product: Liberty 3 | name: Liberty Getting Started Build 4 | description: To build to Liberty Getting started sample in a container 5 | triggers: 6 | - type: manual 7 | triggerName: "sample-liberty" 8 | propertyDefinitions: 9 | - name: BRANCH 10 | defaultValue: "main" 11 | - name: command 12 | defaultValue: "make build-app-pipeline IMAGE=${IMAGE}" 13 | - name: IMAGE 14 | defaultValue: "stg.icr.io/cp/olc-sample/open-liberty/samples/getting-started:latest" 15 | 16 | steps: 17 | - stepName: Z Build 18 | workType: Jenkins 19 | projectName: ebcDockerBuilderLGS 20 | timeoutInMinutes: 1440 21 | # Need properties for Makefile or build script for WLO 22 | properties: 23 | ebcPlan: svl-dockerJenkins-ubuntu20_s390x.yml 24 | 25 | 26 | - stepName: P Build 27 | workType: Jenkins 28 | projectName: ebcDockerBuilderLGS 29 | timeoutInMinutes: 1440 30 | # Need properties for Makefile or build script for WLO 31 | properties: 32 | ebcPlan: svl-dockerJenkins-ubuntu20_ppcle.yml -------------------------------------------------------------------------------- /.github/dependabot.yml: -------------------------------------------------------------------------------- 1 | # To get started with Dependabot version updates, you'll need to specify which 2 | # package ecosystems to update and where the package manifests are located. 3 | # Please see the documentation for all configuration options: 4 | # https://help.github.com/github/administering-a-repository/configuration-options-for-dependency-updates 5 | 6 | version: 2 7 | updates: 8 | - package-ecosystem: "" # See documentation for possible values 9 | directory: "/" # Location of package manifests 10 | schedule: 11 | interval: "daily" 12 | -------------------------------------------------------------------------------- /.github/workflows/add-to-projects.yml: -------------------------------------------------------------------------------- 1 | name: Add GitHub Issues and Pull Requests to GitHub Project 2 | 3 | on: 4 | issues: 5 | types: 6 | - opened 7 | - transferred 8 | pull_request: 9 | types: 10 | - opened 11 | 12 | jobs: 13 | add-to-project: 14 | name: Add issue or pull request to project 15 | runs-on: ubuntu-latest 16 | steps: 17 | - uses: actions/add-to-project@v0.4.0 18 | with: 19 | project-url: https://github.com/orgs/OpenLiberty/projects/10 20 | github-token: ${{ secrets.ADD_TO_PROJECT_PAT }} 21 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # Maven generated 2 | target/ 3 | 4 | # Eclipse generated 5 | .apt_generated/ 6 | .settings/ 7 | .project 8 | .classpath 9 | .factorypath 10 | MANIFEST.MF 11 | 12 | # VS Code 13 | .vscode/ 14 | 15 | # MacOS system files 16 | .DS_Store 17 | 18 | # Zip files 19 | *.zip 20 | -------------------------------------------------------------------------------- /.mvn/wrapper/maven-wrapper.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/OpenLiberty/sample-getting-started/00406970c9264f594b1ecf223816d769c7b8a685/.mvn/wrapper/maven-wrapper.jar -------------------------------------------------------------------------------- /.mvn/wrapper/maven-wrapper.properties: -------------------------------------------------------------------------------- 1 | # Licensed to the Apache Software Foundation (ASF) under one 2 | # or more contributor license agreements. See the NOTICE file 3 | # distributed with this work for additional information 4 | # regarding copyright ownership. The ASF licenses this file 5 | # to you under the Apache License, Version 2.0 (the 6 | # "License"); you may not use this file except in compliance 7 | # with the License. You may obtain a copy of the License at 8 | # 9 | # http://www.apache.org/licenses/LICENSE-2.0 10 | # 11 | # Unless required by applicable law or agreed to in writing, 12 | # software distributed under the License is distributed on an 13 | # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 14 | # KIND, either express or implied. See the License for the 15 | # specific language governing permissions and limitations 16 | # under the License. 17 | distributionUrl=https://repo.maven.apache.org/maven2/org/apache/maven/apache-maven/3.9.3/apache-maven-3.9.3-bin.zip 18 | wrapperUrl=https://repo.maven.apache.org/maven2/org/apache/maven/wrapper/maven-wrapper/3.1.0/maven-wrapper-3.1.0.jar 19 | -------------------------------------------------------------------------------- /.one-pipeline.yaml: -------------------------------------------------------------------------------- 1 | version: '1' 2 | 3 | setup: 4 | image: icr.io/continuous-delivery/pipeline/pipeline-base-ubi:3.12 5 | script: | 6 | #!/usr/bin/env bash 7 | 8 | SKIP_SETUP=$(get_env SKIP_SETUP) 9 | if [[ "$SKIP_SETUP" != 1 ]]; then 10 | GHE_TOKEN=$(cat "$WORKSPACE/git-token") 11 | GHE_TOKEN=$(get_env git-token) 12 | GH_TOKEN=$(get_env git-token-GH) 13 | OWNER=$(jq -r '.services[] | select(.toolchain_binding.name=="app-repo") | .parameters.owner_id' /toolchain/toolchain.json) 14 | REPO=$(jq -r '.services[] | select(.toolchain_binding.name=="app-repo") | .parameters.repo_name' /toolchain/toolchain.json) 15 | REPO=${REPO%.git} 16 | REPO=sample-getting-started 17 | BRANCH=$(get_env branch) 18 | # The 'owner' is really the org, not the user with admin access to repo 19 | OWNER=OpenLiberty 20 | echo "Owner: $OWNER" 21 | echo "REPO: $REPO" 22 | echo "BRANCH: $BRANCH" 23 | 24 | curl -u :$GH_TOKEN https://api.github.com/repos/$OWNER/$REPO/branches/$BRANCH/protection -H "Accept: application/vnd.github.v3+json" -X PUT -d '{"required_pull_request_reviews":{"dismiss_stale_reviews":true,"required_approving_review_count":1},"enforce_admins":null,"restrictions":null,"required_status_checks":null}' 25 | 26 | // Update repo with Whitesource enabled 27 | WHITESOURCE_GHE_REPO=$(get_env WHITESOURCE_GHE_REPO) 28 | WHITESOURCE_GHE_DOMAIN=$(get_env WHITESOURCE_GHE_DOMAIN) 29 | echo "git push --prune https://$GHE_TOKEN@$WHITESOURCE_GHE_DOMAIN/$WHITESOURCE_GHE_REPO +refs/remotes/origin/$BRANCH:refs/heads/$BRANCH +refs/tags/*:refs/tags/*" 30 | git push --prune https://$GHE_TOKEN@$WHITESOURCE_GHE_DOMAIN/$WHITESOURCE_GHE_REPO +refs/remotes/origin/$BRANCH:refs/heads/$BRANCH +refs/tags/*:refs/tags/* 31 | fi 32 | 33 | test: 34 | abort_on_failure: true 35 | image: icr.io/continuous-delivery/pipeline/pipeline-base-ubi:3.12 36 | script: | 37 | #!/usr/bin/env bash 38 | SKIP_UNIT_TESTS=$(get_env SKIP_UNIT_TESTS) 39 | if [[ "$SKIP_UNIT_TESTS" != 1 ]]; then 40 | cd ../"$(load_repo app-repo path)" 41 | mvn clean package liberty:create liberty:install-feature liberty:test-start liberty:deploy failsafe:integration-test failsafe:verify liberty:test-stop 42 | fi 43 | 44 | static-scan: 45 | abort_on_failure: false 46 | dind: true 47 | image: icr.io/continuous-delivery/pipeline/pipeline-base-ubi:3.12 48 | script: | 49 | #!/usr/bin/env bash 50 | SKIP_STATIC_SCAN=$(get_env SKIP_STATIC_SCAN) 51 | if [[ "$SKIP_STATIC_SCAN" != 1 ]]; then 52 | read -r SONAR_HOST_URL <<< "$(get_env sonarqube | jq -r '.parameters.dashboard_url' | sed 's:/*$::')" 53 | read -r SONAR_USER <<< "$(get_env sonarqube | jq -r '.parameters.user_login')" 54 | SONARQUBE_INSTANCE_ID=$(get_env sonarqube | jq -r '.instance_id') 55 | read -r SONAR_PASS <<< "$(jq -r --arg sonar_instance "$SONARQUBE_INSTANCE_ID" '[.services[] | select(."service_id"=="sonarqube")][] | select(."instance_id"==$sonar_instance) | .parameters.user_password' /toolchain/toolchain.json)" 56 | touch "$WORKSPACE"/liberty-getting-started/sonar-project.properties 57 | cat << EOF > "$WORKSPACE"/liberty-getting-started/sonar-project.properties 58 | sonar.projectKey=liberty-getting-started 59 | sonar.host.url=$SONAR_HOST_URL 60 | sonar.sources=. 61 | sonar.login=$SONAR_USER 62 | sonar.password=$SONAR_PASS 63 | sonar.c.file.suffixes=- 64 | sonar.cpp.file.suffixes=- 65 | sonar.objc.file.suffixes=- 66 | EOF 67 | chmod -x "$WORKSPACE"/liberty-getting-started/sonar-project.properties 68 | #echo "$SONAR_PASS" >> /tmp/sonarqube-token 69 | "${ONE_PIPELINE_PATH}"/internal/sonarqube/sonarqube_run 70 | fi 71 | 72 | containerize: 73 | abort_on_failure: true 74 | dind: true 75 | image: icr.io/continuous-delivery/pipeline/pipeline-base-ubi:3.12 76 | script: | 77 | #!/usr/bin/env bash 78 | 79 | if [[ "$PIPELINE_DEBUG" == 1 ]]; then 80 | trap env EXIT 81 | env 82 | set -x 83 | fi 84 | 85 | yum -y -q update 86 | 87 | # Check skopeo version 88 | echo "skopeo version" 89 | skopeo --version || exit 1 90 | 91 | # Build images 92 | export PIPELINE_USERNAME=$(get_env ibmcloud-api-user) 93 | export PIPELINE_PASSWORD=$(get_env ibmcloud-api-key-staging) 94 | export CONTAINER_REGISTRY=$(get_env CONTAINER_REGISTRY "stg.icr.io") 95 | REGISTRY_REPO=$(get_env REGISTRY_REPO) 96 | IMAGE_TAG=$(get_env IMAGE_TAG) 97 | IMAGE=$CONTAINER_REGISTRY/$REGISTRY_REPO:$IMAGE_TAG 98 | BRANCH=$(get_env branch) 99 | 100 | W3_USERNAME=$(get_env w3_username) 101 | W3_PASSWORD=$(get_env w3_password) 102 | 103 | export arch=$(get_env architecture) 104 | 105 | # build P and Z 106 | if [[ "$arch" == "ZXP" ]]; then 107 | echo " Sending request to build P and Z" 108 | ./scripts/pipeline/request-ciorchestrator.sh --command "make build-app-pipeline IMAGE=${IMAGE}" --user "$W3_USERNAME" --password "$W3_PASSWORD" --branch "$BRANCH" --repository "sample-getting-started" --org "OpenLiberty" --trigger "sample-liberty" --configFile ".ci-orchestrator/sample-liberty-build.yml" 109 | pipelineid=$(cat ciorchestrator-submit.id) 110 | fi 111 | 112 | # Build X 113 | make build-app-pipeline IMAGE=${IMAGE} 114 | 115 | #wait on build for P and Z 116 | if [[ "$arch" == "ZXP" ]]; then 117 | # wait for build ppc64le and s390x images 118 | echo " waiting on request to build P and Z" 119 | ./scripts/pipeline/await-ciorchestrator.sh --user "$W3_USERNAME" --password "$W3_PASSWORD" --pipelineId "$pipelineid" 120 | fi 121 | 122 | # Build manifest 123 | make build-manifest-pipeline IMAGE=${IMAGE} 124 | 125 | # Save artifacts 126 | echo "**** Saving Artifacts ****" 127 | if [[ "$arch" == "ZXP" ]]; then 128 | declare -a tags=("${IMAGE_TAG}" "${IMAGE_TAG}-amd64" "${IMAGE_TAG}-ppc64le" "${IMAGE_TAG}-s390x") 129 | else 130 | declare -a tags=("${IMAGE_TAG}" "${IMAGE_TAG}-amd64") 131 | fi 132 | 133 | for i in "${tags[@]}" 134 | do 135 | IMAGE=$CONTAINER_REGISTRY/$REGISTRY_REPO:$i 136 | DIGEST="$(skopeo inspect docker://$IMAGE | grep Digest | grep -o 'sha[^\"]*')" 137 | { ARCH="$(echo $i | grep -o '\(amd64\|s390x\|ppc64le\)$')" && TYPE="image"; } || { TYPE="manifest"; } 138 | if [[ "$TYPE" == "manifest" ]]; then 139 | echo "Saving artifact $i type=$TYPE name=$IMAGE digest=$DIGEST" 140 | save_artifact $i type=$TYPE name="$IMAGE" "digest=$DIGEST" 141 | else 142 | echo "Saving artifact $i type=$TYPE name=$IMAGE digest=$DIGEST arch=$ARCH" 143 | save_artifact $i type=$TYPE name="$IMAGE" "digest=$DIGEST" "arch=$ARCH" 144 | fi 145 | done 146 | 147 | sign-artifact: 148 | abort_on_failure: false 149 | image: icr.io/continuous-delivery/pipeline/pipeline-base-ubi:3.12 150 | script: | 151 | #!/usr/bin/env bash 152 | echo "Skipping step because it doesn't make sense to sign an image at this step in the flow" 153 | 154 | deploy: 155 | image: icr.io/continuous-delivery/pipeline/pipeline-base-ubi:3.12 156 | script: | 157 | #!/usr/bin/env bash 158 | 159 | if [[ "$PIPELINE_DEBUG" == 1 ]]; then 160 | trap env EXIT 161 | env 162 | set -x 163 | fi 164 | 165 | echo "Skipping Deploy" 166 | 167 | dynamic-scan: 168 | abort_on_failure: false 169 | image: icr.io/continuous-delivery/pipeline/pipeline-base-ubi:3.12 170 | script: | 171 | #!/usr/bin/env bash 172 | 173 | echo "Skipping dynamic-scan" 174 | 175 | acceptance-test: 176 | abort_on_failure: true 177 | dind: true 178 | image: icr.io/continuous-delivery/pipeline/pipeline-base-ubi:3.12 179 | script: | 180 | #!/usr/bin/env bash 181 | 182 | if [[ "$PIPELINE_DEBUG" == 1 ]]; then 183 | trap env EXIT 184 | env 185 | set -x 186 | fi 187 | 188 | export PIPELINE_USERNAME=$(get_env ibmcloud-api-user) 189 | export PIPELINE_PASSWORD=$(get_env ibmcloud-api-key-staging) 190 | export CONTAINER_REGISTRY=$(get_env CONTAINER_REGISTRY "stg.icr.io") 191 | REGISTRY_REPO=$(get_env REGISTRY_REPO) 192 | IMAGE_TAG=$(get_env IMAGE_TAG) 193 | IMAGE=$CONTAINER_REGISTRY/$REGISTRY_REPO:$IMAGE_TAG 194 | BRANCH=$(get_env branch) 195 | 196 | W3_USERNAME=$(get_env w3_username) 197 | W3_PASSWORD=$(get_env w3_password) 198 | 199 | export arch=$(get_env architecture) 200 | 201 | # check P and Z 202 | if [[ "$arch" == "ZXP" ]]; then 203 | echo " Sending request to build P and Z" 204 | ./scripts/pipeline/request-ciorchestrator.sh --command "make check-build IMAGE=${IMAGE}" --user "$W3_USERNAME" --password "$W3_PASSWORD" --branch "$BRANCH" --repository "sample-getting-started" --org "OpenLiberty" --trigger "sample-liberty" --configFile ".ci-orchestrator/sample-liberty-build.yml" 205 | pipelineid=$(cat ciorchestrator-submit.id) 206 | fi 207 | 208 | # Check X 209 | make check-build IMAGE=${IMAGE} 210 | 211 | #wait on build for P and Z 212 | if [[ "$arch" == "ZXP" ]]; then 213 | # wait for build ppc64le and s390x images 214 | echo " waiting on request to build P and Z" 215 | ./scripts/pipeline/await-ciorchestrator.sh --user "$W3_USERNAME" --password "$W3_PASSWORD" --pipelineId "$pipelineid" 216 | fi 217 | 218 | 219 | scan-artifact: 220 | abort_on_failure: true 221 | image: icr.io/continuous-delivery/pipeline/pipeline-base-ubi:3.12 222 | script: | 223 | #!/usr/bin/env bash 224 | 225 | echo $STAGE 226 | 227 | # ========== Security Scanner ========== 228 | ./scripts/pipeline/ci_to_secure_pipeline_scan.sh 229 | 230 | release: 231 | abort_on_failure: false 232 | dind: true 233 | image: icr.io/continuous-delivery/pipeline/pipeline-base-ubi:3.12 234 | script: | 235 | #!/usr/bin/env bash 236 | 237 | if [[ "$PIPELINE_DEBUG" == 1 ]]; then 238 | trap env EXIT 239 | env 240 | set -x 241 | fi 242 | 243 | PUBLISH_IMAGES=$(get_env PUBLISH_IMAGES) 244 | if [[ "$PUBLISH_IMAGES" == 1 ]]; then 245 | skopeo --version 246 | 247 | IMAGE_TAG=$(get_env IMAGE_TAG) 248 | 249 | export PIPELINE_USERNAME=$(get_env ibmcloud-api-user) 250 | PIPELINE_STAGING_PASSWORD=$(get_env ibmcloud-api-key-staging) 251 | CONTAINER_REGISTRY=$(get_env CONTAINER_REGISTRY "stg.icr.io") 252 | REGISTRY_REPO=$(get_env REGISTRY_REPO) 253 | STAGING_IMAGE=$CONTAINER_REGISTRY/$REGISTRY_REPO:$IMAGE_TAG 254 | 255 | PIPELINE_PROD_PASSWORD=$(get_env ibmcloud-api-key) 256 | PROD_CONTAINER_REGISTRY=$(get_env PROD_CONTAINER_REGISTRY) 257 | PROD_REGISTRY_REPO=$(get_env PROD_REGISTRY_REPO) 258 | PROD_IMAGE=$PROD_CONTAINER_REGISTRY/$PROD_REGISTRY_REPO:$IMAGE_TAG 259 | 260 | # Copy image digests and manifest list to prod 261 | echo $PIPELINE_STAGING_PASSWORD | docker login $CONTAINER_REGISTRY -u "$PIPELINE_USERNAME" --password-stdin 262 | echo $PIPELINE_PROD_PASSWORD | docker login $PROD_CONTAINER_REGISTRY -u "$PIPELINE_USERNAME" --password-stdin 263 | 264 | echo "Copying staged image $STAGING_IMAGE to prod at $PROD_IMAGE as user $PIPELINE_USERNAME" 265 | skopeo copy --src-creds $PIPELINE_USERNAME:$PIPELINE_STAGING_PASSWORD --dest-creds $PIPELINE_USERNAME:$PIPELINE_PROD_PASSWORD --all docker://$STAGING_IMAGE docker://$PROD_IMAGE 266 | 267 | echo "Manifest list of $PROD_IMAGE" 268 | docker manifest inspect "$PROD_IMAGE" 269 | digest="$(skopeo inspect docker://$PROD_IMAGE | grep Digest | grep -o 'sha[^\"]*')" 270 | echo "$digest" 271 | 272 | export CONTAINER_REGISTRY=$PROD_CONTAINER_REGISTRY 273 | export PIPELINE_PASSWORD=$PIPELINE_PROD_PASSWORD 274 | 275 | # Check X image from prod registry 276 | make check-build IMAGE=${PROD_IMAGE} 277 | fi 278 | 279 | owasp-zap-api: 280 | dind: true 281 | abort_on_failure: false 282 | image: icr.io/continuous-delivery/pipeline/pipeline-base-ubi:3.12 283 | script: | 284 | #!/usr/bin/env bash 285 | if [[ "$PIPELINE_DEBUG" == 1 ]]; then 286 | trap env EXIT 287 | env 288 | set -x 289 | fi 290 | 291 | echo "Skipping OWASP ZAP API" 292 | -------------------------------------------------------------------------------- /.secrets.baseline: -------------------------------------------------------------------------------- 1 | { 2 | "exclude": { 3 | "files": "^.secrets.baseline$", 4 | "lines": null 5 | }, 6 | "generated_at": "2023-08-25T19:53:53Z", 7 | "plugins_used": [ 8 | { 9 | "name": "AWSKeyDetector" 10 | }, 11 | { 12 | "name": "ArtifactoryDetector" 13 | }, 14 | { 15 | "name": "AzureStorageKeyDetector" 16 | }, 17 | { 18 | "base64_limit": 4.5, 19 | "name": "Base64HighEntropyString" 20 | }, 21 | { 22 | "name": "BasicAuthDetector" 23 | }, 24 | { 25 | "name": "BoxDetector" 26 | }, 27 | { 28 | "name": "CloudantDetector" 29 | }, 30 | { 31 | "ghe_instance": "github.ibm.com", 32 | "name": "GheDetector" 33 | }, 34 | { 35 | "name": "GitHubTokenDetector" 36 | }, 37 | { 38 | "hex_limit": 3, 39 | "name": "HexHighEntropyString" 40 | }, 41 | { 42 | "name": "IbmCloudIamDetector" 43 | }, 44 | { 45 | "name": "IbmCosHmacDetector" 46 | }, 47 | { 48 | "name": "JwtTokenDetector" 49 | }, 50 | { 51 | "keyword_exclude": null, 52 | "name": "KeywordDetector" 53 | }, 54 | { 55 | "name": "MailchimpDetector" 56 | }, 57 | { 58 | "name": "NpmDetector" 59 | }, 60 | { 61 | "name": "PrivateKeyDetector" 62 | }, 63 | { 64 | "name": "SlackDetector" 65 | }, 66 | { 67 | "name": "SoftlayerDetector" 68 | }, 69 | { 70 | "name": "SquareOAuthDetector" 71 | }, 72 | { 73 | "name": "StripeDetector" 74 | }, 75 | { 76 | "name": "TwilioKeyDetector" 77 | } 78 | ], 79 | "results": { 80 | "mvnw.cmd": [ 81 | { 82 | "hashed_secret": "4e455935905a45080257f4d3c67115e4131b05af", 83 | "is_secret": false, 84 | "is_verified": false, 85 | "line_number": 147, 86 | "type": "Secret Keyword", 87 | "verified_result": null 88 | } 89 | ] 90 | }, 91 | "version": "0.13.1+ibm.61.dss", 92 | "word_list": { 93 | "file": null, 94 | "hash": null 95 | } 96 | } 97 | -------------------------------------------------------------------------------- /.whitesource: -------------------------------------------------------------------------------- 1 | { 2 | "settingsInheritedFrom": "whitesource-config/whitesource-config@master" 3 | } 4 | -------------------------------------------------------------------------------- /CONTRIBUTING.md: -------------------------------------------------------------------------------- 1 | # Contributing to Open Liberty Sample Getting Started 2 | 3 | Anyone can contribute to the Sample Getting Started project and we welcome your contributions! 4 | 5 | ## Contributor License Agreement 6 | 7 | In order for us to accept pull requests, you must declare that you wrote the code or, at least, have the right to contribute it to the repo under the open source licence of the project in the repo. It's dead easy... 8 | 9 | 1. Read this (from [developercertificate.org](http://developercertificate.org/)): 10 | 11 | ``` 12 | Developer Certificate of Origin 13 | Version 1.1 14 | 15 | Copyright (C) 2004, 2006 The Linux Foundation and its contributors. 16 | 660 York Street, Suite 102, 17 | San Francisco, CA 94110 USA 18 | 19 | Everyone is permitted to copy and distribute verbatim copies of this 20 | license document, but changing it is not allowed. 21 | 22 | 23 | Developer's Certificate of Origin 1.1 24 | 25 | By making a contribution to this project, I certify that: 26 | 27 | (a) The contribution was created in whole or in part by me and I 28 | have the right to submit it under the open source license 29 | indicated in the file; or 30 | 31 | (b) The contribution is based upon previous work that, to the best 32 | of my knowledge, is covered under an appropriate open source 33 | license and I have the right under that license to submit that 34 | work with modifications, whether created in whole or in part 35 | by me, under the same open source license (unless I am 36 | permitted to submit under a different license), as indicated 37 | in the file; or 38 | 39 | (c) The contribution was provided directly to me by some other 40 | person who certified (a), (b) or (c) and I have not modified 41 | it. 42 | 43 | (d) I understand and agree that this project and the contribution 44 | are public and that a record of the contribution (including all 45 | personal information I submit with it, including my sign-off) is 46 | maintained indefinitely and may be redistributed consistent with 47 | this project or the open source license(s) involved. 48 | ``` 49 | 50 | 2. If you can certify that it is true, sign off your `git commit` with a message like this: 51 | ``` 52 | Signed-off-by: Laura Cowen 53 | ``` 54 | You must use your real name (no pseudonyms or anonymous contributions, sorry). 55 | 56 | Instead of typing that in every git commit message, your Git tools might let you automatically add the details for you. If you configure them to do that, when you issue the `git commit` command, just add the `-s` option. 57 | 58 | If you are an IBMer, please contact us directly as the contribution process is 59 | slightly different. 60 | -------------------------------------------------------------------------------- /Dockerfile: -------------------------------------------------------------------------------- 1 | FROM icr.io/appcafe/open-liberty:kernel-slim-java11-openj9-ubi 2 | ARG VERSION=1.0 3 | ARG REVISION=SNAPSHOT 4 | 5 | LABEL \ 6 | org.opencontainers.image.authors="Alasdair Nottingham" \ 7 | org.opencontainers.image.vendor="IBM" \ 8 | org.opencontainers.image.url="local" \ 9 | org.opencontainers.image.source="https://github.com/OpenLiberty/sample-getting-started" \ 10 | org.opencontainers.image.version="$VERSION" \ 11 | org.opencontainers.image.revision="$REVISION" \ 12 | vendor="Open Liberty" \ 13 | name="system" \ 14 | version="$VERSION-$REVISION" \ 15 | summary="Sample app running on Open Liberty that uses Eclipse MicroProfile" \ 16 | description="This image contains a sample application that displays the Java system properties and demonstrates MicroProfile Config, Health and Metrics." 17 | 18 | COPY --chown=1001:0 src/main/liberty/config/ /config/ 19 | 20 | RUN features.sh 21 | 22 | COPY --chown=1001:0 target/*.war /config/apps/ 23 | 24 | RUN configure.sh && rm -rf /output/resources/security/ 25 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | Code and build scripts are licensed under the Eclipse Public License v2 2 | 3 | Documentation and Website files (e.g. files with an adoc file extension) are 4 | licensed under Creative Commons Attribution-NoDerivatives 4.0 International 5 | (CC BY-ND 4.0) 6 | 7 | Eclipse Public License - v 2.0 8 | 9 | THE ACCOMPANYING PROGRAM IS PROVIDED UNDER THE TERMS OF THIS ECLIPSE 10 | PUBLIC LICENSE ("AGREEMENT"). ANY USE, REPRODUCTION OR DISTRIBUTION 11 | OF THE PROGRAM CONSTITUTES RECIPIENT'S ACCEPTANCE OF THIS AGREEMENT. 12 | 13 | 1. DEFINITIONS 14 | 15 | "Contribution" means: 16 | 17 | a) in the case of the initial Contributor, the initial content 18 | Distributed under this Agreement, and 19 | 20 | b) in the case of each subsequent Contributor: 21 | i) changes to the Program, and 22 | ii) additions to the Program; 23 | where such changes and/or additions to the Program originate from 24 | and are Distributed by that particular Contributor. A Contribution 25 | "originates" from a Contributor if it was added to the Program by 26 | such Contributor itself or anyone acting on such Contributor's behalf. 27 | Contributions do not include changes or additions to the Program that 28 | are not Modified Works. 29 | 30 | "Contributor" means any person or entity that Distributes the Program. 31 | 32 | "Licensed Patents" mean patent claims licensable by a Contributor which 33 | are necessarily infringed by the use or sale of its Contribution alone 34 | or when combined with the Program. 35 | 36 | "Program" means the Contributions Distributed in accordance with this 37 | Agreement. 38 | 39 | "Recipient" means anyone who receives the Program under this Agreement 40 | or any Secondary License (as applicable), including Contributors. 41 | 42 | "Derivative Works" shall mean any work, whether in Source Code or other 43 | form, that is based on (or derived from) the Program and for which the 44 | editorial revisions, annotations, elaborations, or other modifications 45 | represent, as a whole, an original work of authorship. 46 | 47 | "Modified Works" shall mean any work in Source Code or other form that 48 | results from an addition to, deletion from, or modification of the 49 | contents of the Program, including, for purposes of clarity any new file 50 | in Source Code form that contains any contents of the Program. Modified 51 | Works shall not include works that contain only declarations, 52 | interfaces, types, classes, structures, or files of the Program solely 53 | in each case in order to link to, bind by name, or subclass the Program 54 | or Modified Works thereof. 55 | 56 | "Distribute" means the acts of a) distributing or b) making available 57 | in any manner that enables the transfer of a copy. 58 | 59 | "Source Code" means the form of a Program preferred for making 60 | modifications, including but not limited to software source code, 61 | documentation source, and configuration files. 62 | 63 | "Secondary License" means either the GNU General Public License, 64 | Version 2.0, or any later versions of that license, including any 65 | exceptions or additional permissions as identified by the initial 66 | Contributor. 67 | 68 | 2. GRANT OF RIGHTS 69 | 70 | a) Subject to the terms of this Agreement, each Contributor hereby 71 | grants Recipient a non-exclusive, worldwide, royalty-free copyright 72 | license to reproduce, prepare Derivative Works of, publicly display, 73 | publicly perform, Distribute and sublicense the Contribution of such 74 | Contributor, if any, and such Derivative Works. 75 | 76 | b) Subject to the terms of this Agreement, each Contributor hereby 77 | grants Recipient a non-exclusive, worldwide, royalty-free patent 78 | license under Licensed Patents to make, use, sell, offer to sell, 79 | import and otherwise transfer the Contribution of such Contributor, 80 | if any, in Source Code or other form. This patent license shall 81 | apply to the combination of the Contribution and the Program if, at 82 | the time the Contribution is added by the Contributor, such addition 83 | of the Contribution causes such combination to be covered by the 84 | Licensed Patents. The patent license shall not apply to any other 85 | combinations which include the Contribution. No hardware per se is 86 | licensed hereunder. 87 | 88 | c) Recipient understands that although each Contributor grants the 89 | licenses to its Contributions set forth herein, no assurances are 90 | provided by any Contributor that the Program does not infringe the 91 | patent or other intellectual property rights of any other entity. 92 | Each Contributor disclaims any liability to Recipient for claims 93 | brought by any other entity based on infringement of intellectual 94 | property rights or otherwise. As a condition to exercising the 95 | rights and licenses granted hereunder, each Recipient hereby 96 | assumes sole responsibility to secure any other intellectual 97 | property rights needed, if any. For example, if a third party 98 | patent license is required to allow Recipient to Distribute the 99 | Program, it is Recipient's responsibility to acquire that license 100 | before distributing the Program. 101 | 102 | d) Each Contributor represents that to its knowledge it has 103 | sufficient copyright rights in its Contribution, if any, to grant 104 | the copyright license set forth in this Agreement. 105 | 106 | e) Notwithstanding the terms of any Secondary License, no 107 | Contributor makes additional grants to any Recipient (other than 108 | those set forth in this Agreement) as a result of such Recipient's 109 | receipt of the Program under the terms of a Secondary License 110 | (if permitted under the terms of Section 3). 111 | 112 | 3. REQUIREMENTS 113 | 114 | 3.1 If a Contributor Distributes the Program in any form, then: 115 | 116 | a) the Program must also be made available as Source Code, in 117 | accordance with section 3.2, and the Contributor must accompany 118 | the Program with a statement that the Source Code for the Program 119 | is available under this Agreement, and informs Recipients how to 120 | obtain it in a reasonable manner on or through a medium customarily 121 | used for software exchange; and 122 | 123 | b) the Contributor may Distribute the Program under a license 124 | different than this Agreement, provided that such license: 125 | i) effectively disclaims on behalf of all other Contributors all 126 | warranties and conditions, express and implied, including 127 | warranties or conditions of title and non-infringement, and 128 | implied warranties or conditions of merchantability and fitness 129 | for a particular purpose; 130 | 131 | ii) effectively excludes on behalf of all other Contributors all 132 | liability for damages, including direct, indirect, special, 133 | incidental and consequential damages, such as lost profits; 134 | 135 | iii) does not attempt to limit or alter the recipients' rights 136 | in the Source Code under section 3.2; and 137 | 138 | iv) requires any subsequent distribution of the Program by any 139 | party to be under a license that satisfies the requirements 140 | of this section 3. 141 | 142 | 3.2 When the Program is Distributed as Source Code: 143 | 144 | a) it must be made available under this Agreement, or if the 145 | Program (i) is combined with other material in a separate file or 146 | files made available under a Secondary License, and (ii) the initial 147 | Contributor attached to the Source Code the notice described in 148 | Exhibit A of this Agreement, then the Program may be made available 149 | under the terms of such Secondary Licenses, and 150 | 151 | b) a copy of this Agreement must be included with each copy of 152 | the Program. 153 | 154 | 3.3 Contributors may not remove or alter any copyright, patent, 155 | trademark, attribution notices, disclaimers of warranty, or limitations 156 | of liability ("notices") contained within the Program from any copy of 157 | the Program which they Distribute, provided that Contributors may add 158 | their own appropriate notices. 159 | 160 | 4. COMMERCIAL DISTRIBUTION 161 | 162 | Commercial distributors of software may accept certain responsibilities 163 | with respect to end users, business partners and the like. While this 164 | license is intended to facilitate the commercial use of the Program, 165 | the Contributor who includes the Program in a commercial product 166 | offering should do so in a manner which does not create potential 167 | liability for other Contributors. Therefore, if a Contributor includes 168 | the Program in a commercial product offering, such Contributor 169 | ("Commercial Contributor") hereby agrees to defend and indemnify every 170 | other Contributor ("Indemnified Contributor") against any losses, 171 | damages and costs (collectively "Losses") arising from claims, lawsuits 172 | and other legal actions brought by a third party against the Indemnified 173 | Contributor to the extent caused by the acts or omissions of such 174 | Commercial Contributor in connection with its distribution of the Program 175 | in a commercial product offering. The obligations in this section do not 176 | apply to any claims or Losses relating to any actual or alleged 177 | intellectual property infringement. In order to qualify, an Indemnified 178 | Contributor must: a) promptly notify the Commercial Contributor in 179 | writing of such claim, and b) allow the Commercial Contributor to control, 180 | and cooperate with the Commercial Contributor in, the defense and any 181 | related settlement negotiations. The Indemnified Contributor may 182 | participate in any such claim at its own expense. 183 | 184 | For example, a Contributor might include the Program in a commercial 185 | product offering, Product X. That Contributor is then a Commercial 186 | Contributor. If that Commercial Contributor then makes performance 187 | claims, or offers warranties related to Product X, those performance 188 | claims and warranties are such Commercial Contributor's responsibility 189 | alone. Under this section, the Commercial Contributor would have to 190 | defend claims against the other Contributors related to those performance 191 | claims and warranties, and if a court requires any other Contributor to 192 | pay any damages as a result, the Commercial Contributor must pay 193 | those damages. 194 | 195 | 5. NO WARRANTY 196 | 197 | EXCEPT AS EXPRESSLY SET FORTH IN THIS AGREEMENT, AND TO THE EXTENT 198 | PERMITTED BY APPLICABLE LAW, THE PROGRAM IS PROVIDED ON AN "AS IS" 199 | BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, EITHER EXPRESS OR 200 | IMPLIED INCLUDING, WITHOUT LIMITATION, ANY WARRANTIES OR CONDITIONS OF 201 | TITLE, NON-INFRINGEMENT, MERCHANTABILITY OR FITNESS FOR A PARTICULAR 202 | PURPOSE. Each Recipient is solely responsible for determining the 203 | appropriateness of using and distributing the Program and assumes all 204 | risks associated with its exercise of rights under this Agreement, 205 | including but not limited to the risks and costs of program errors, 206 | compliance with applicable laws, damage to or loss of data, programs 207 | or equipment, and unavailability or interruption of operations. 208 | 209 | 6. DISCLAIMER OF LIABILITY 210 | 211 | EXCEPT AS EXPRESSLY SET FORTH IN THIS AGREEMENT, AND TO THE EXTENT 212 | PERMITTED BY APPLICABLE LAW, NEITHER RECIPIENT NOR ANY CONTRIBUTORS 213 | SHALL HAVE ANY LIABILITY FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 214 | EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING WITHOUT LIMITATION LOST 215 | PROFITS), HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 216 | CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 217 | ARISING IN ANY WAY OUT OF THE USE OR DISTRIBUTION OF THE PROGRAM OR THE 218 | EXERCISE OF ANY RIGHTS GRANTED HEREUNDER, EVEN IF ADVISED OF THE 219 | POSSIBILITY OF SUCH DAMAGES. 220 | 221 | 7. GENERAL 222 | 223 | If any provision of this Agreement is invalid or unenforceable under 224 | applicable law, it shall not affect the validity or enforceability of 225 | the remainder of the terms of this Agreement, and without further 226 | action by the parties hereto, such provision shall be reformed to the 227 | minimum extent necessary to make such provision valid and enforceable. 228 | 229 | If Recipient institutes patent litigation against any entity 230 | (including a cross-claim or counterclaim in a lawsuit) alleging that the 231 | Program itself (excluding combinations of the Program with other software 232 | or hardware) infringes such Recipient's patent(s), then such Recipient's 233 | rights granted under Section 2(b) shall terminate as of the date such 234 | litigation is filed. 235 | 236 | All Recipient's rights under this Agreement shall terminate if it 237 | fails to comply with any of the material terms or conditions of this 238 | Agreement and does not cure such failure in a reasonable period of 239 | time after becoming aware of such noncompliance. If all Recipient's 240 | rights under this Agreement terminate, Recipient agrees to cease use 241 | and distribution of the Program as soon as reasonably practicable. 242 | However, Recipient's obligations under this Agreement and any licenses 243 | granted by Recipient relating to the Program shall continue and survive. 244 | 245 | Everyone is permitted to copy and distribute copies of this Agreement, 246 | but in order to avoid inconsistency the Agreement is copyrighted and 247 | may only be modified in the following manner. The Agreement Steward 248 | reserves the right to publish new versions (including revisions) of 249 | this Agreement from time to time. No one other than the Agreement 250 | Steward has the right to modify this Agreement. The Eclipse Foundation 251 | is the initial Agreement Steward. The Eclipse Foundation may assign the 252 | responsibility to serve as the Agreement Steward to a suitable separate 253 | entity. Each new version of the Agreement will be given a distinguishing 254 | version number. The Program (including Contributions) may always be 255 | Distributed subject to the version of the Agreement under which it was 256 | received. In addition, after a new version of the Agreement is published, 257 | Contributor may elect to Distribute the Program (including its 258 | Contributions) under the new version. 259 | 260 | Except as expressly stated in Sections 2(a) and 2(b) above, Recipient 261 | receives no rights or licenses to the intellectual property of any 262 | Contributor under this Agreement, whether expressly, by implication, 263 | estoppel or otherwise. All rights in the Program not expressly granted 264 | under this Agreement are reserved. Nothing in this Agreement is intended 265 | to be enforceable by any entity that is not a Contributor or Recipient. 266 | No third-party beneficiary rights are created under this Agreement. 267 | 268 | Exhibit A - Form of Secondary Licenses Notice 269 | 270 | "This Source Code may also be made available under the following 271 | Secondary Licenses when the conditions for such availability set forth 272 | in the Eclipse Public License, v. 2.0 are satisfied: {name license(s), 273 | version(s), and exceptions or additional permissions here}." 274 | 275 | Simply including a copy of this Agreement, including this Exhibit A 276 | is not sufficient to license the Source Code under Secondary Licenses. 277 | 278 | If it is not possible or desirable to put the notice in a particular 279 | file, then You may include the notice in a location (such as a LICENSE 280 | file in a relevant directory) where a recipient would be likely to 281 | look for such a notice. 282 | 283 | You may add additional accurate notices of copyright ownership. 284 | 285 | -------------------------------------------------------------------------------- 286 | 287 | Attribution-NoDerivatives 4.0 International 288 | 289 | ======================================================================= 290 | 291 | Creative Commons Corporation ("Creative Commons") is not a law firm and 292 | does not provide legal services or legal advice. Distribution of 293 | Creative Commons public licenses does not create a lawyer-client or 294 | other relationship. Creative Commons makes its licenses and related 295 | information available on an "as-is" basis. Creative Commons gives no 296 | warranties regarding its licenses, any material licensed under their 297 | terms and conditions, or any related information. Creative Commons 298 | disclaims all liability for damages resulting from their use to the 299 | fullest extent possible. 300 | 301 | Using Creative Commons Public Licenses 302 | 303 | Creative Commons public licenses provide a standard set of terms and 304 | conditions that creators and other rights holders may use to share 305 | original works of authorship and other material subject to copyright 306 | and certain other rights specified in the public license below. The 307 | following considerations are for informational purposes only, are not 308 | exhaustive, and do not form part of our licenses. 309 | 310 | Considerations for licensors: Our public licenses are 311 | intended for use by those authorized to give the public 312 | permission to use material in ways otherwise restricted by 313 | copyright and certain other rights. Our licenses are 314 | irrevocable. Licensors should read and understand the terms 315 | and conditions of the license they choose before applying it. 316 | Licensors should also secure all rights necessary before 317 | applying our licenses so that the public can reuse the 318 | material as expected. Licensors should clearly mark any 319 | material not subject to the license. This includes other CC- 320 | licensed material, or material used under an exception or 321 | limitation to copyright. More considerations for licensors: 322 | wiki.creativecommons.org/Considerations_for_licensors 323 | 324 | Considerations for the public: By using one of our public 325 | licenses, a licensor grants the public permission to use the 326 | licensed material under specified terms and conditions. If 327 | the licensor's permission is not necessary for any reason--for 328 | example, because of any applicable exception or limitation to 329 | copyright--then that use is not regulated by the license. Our 330 | licenses grant only permissions under copyright and certain 331 | other rights that a licensor has authority to grant. Use of 332 | the licensed material may still be restricted for other 333 | reasons, including because others have copyright or other 334 | rights in the material. A licensor may make special requests, 335 | such as asking that all changes be marked or described. 336 | Although not required by our licenses, you are encouraged to 337 | respect those requests where reasonable. More_considerations 338 | for the public: 339 | wiki.creativecommons.org/Considerations_for_licensees 340 | 341 | 342 | ======================================================================= 343 | 344 | Creative Commons Attribution-NoDerivatives 4.0 International Public 345 | License 346 | 347 | By exercising the Licensed Rights (defined below), You accept and agree 348 | to be bound by the terms and conditions of this Creative Commons 349 | Attribution-NoDerivatives 4.0 International Public License ("Public 350 | License"). To the extent this Public License may be interpreted as a 351 | contract, You are granted the Licensed Rights in consideration of Your 352 | acceptance of these terms and conditions, and the Licensor grants You 353 | such rights in consideration of benefits the Licensor receives from 354 | making the Licensed Material available under these terms and 355 | conditions. 356 | 357 | 358 | Section 1 -- Definitions. 359 | 360 | a. Adapted Material means material subject to Copyright and Similar 361 | Rights that is derived from or based upon the Licensed Material 362 | and in which the Licensed Material is translated, altered, 363 | arranged, transformed, or otherwise modified in a manner requiring 364 | permission under the Copyright and Similar Rights held by the 365 | Licensor. For purposes of this Public License, where the Licensed 366 | Material is a musical work, performance, or sound recording, 367 | Adapted Material is always produced where the Licensed Material is 368 | synched in timed relation with a moving image. 369 | 370 | b. Copyright and Similar Rights means copyright and/or similar rights 371 | closely related to copyright including, without limitation, 372 | performance, broadcast, sound recording, and Sui Generis Database 373 | Rights, without regard to how the rights are labeled or 374 | categorized. For purposes of this Public License, the rights 375 | specified in Section 2(b)(1)-(2) are not Copyright and Similar 376 | Rights. 377 | 378 | c. Effective Technological Measures means those measures that, in the 379 | absence of proper authority, may not be circumvented under laws 380 | fulfilling obligations under Article 11 of the WIPO Copyright 381 | Treaty adopted on December 20, 1996, and/or similar international 382 | agreements. 383 | 384 | d. Exceptions and Limitations means fair use, fair dealing, and/or 385 | any other exception or limitation to Copyright and Similar Rights 386 | that applies to Your use of the Licensed Material. 387 | 388 | e. Licensed Material means the artistic or literary work, database, 389 | or other material to which the Licensor applied this Public 390 | License. 391 | 392 | f. Licensed Rights means the rights granted to You subject to the 393 | terms and conditions of this Public License, which are limited to 394 | all Copyright and Similar Rights that apply to Your use of the 395 | Licensed Material and that the Licensor has authority to license. 396 | 397 | g. Licensor means the individual(s) or entity(ies) granting rights 398 | under this Public License. 399 | 400 | h. Share means to provide material to the public by any means or 401 | process that requires permission under the Licensed Rights, such 402 | as reproduction, public display, public performance, distribution, 403 | dissemination, communication, or importation, and to make material 404 | available to the public including in ways that members of the 405 | public may access the material from a place and at a time 406 | individually chosen by them. 407 | 408 | i. Sui Generis Database Rights means rights other than copyright 409 | resulting from Directive 96/9/EC of the European Parliament and of 410 | the Council of 11 March 1996 on the legal protection of databases, 411 | as amended and/or succeeded, as well as other essentially 412 | equivalent rights anywhere in the world. 413 | 414 | j. You means the individual or entity exercising the Licensed Rights 415 | under this Public License. Your has a corresponding meaning. 416 | 417 | 418 | Section 2 -- Scope. 419 | 420 | a. License grant. 421 | 422 | 1. Subject to the terms and conditions of this Public License, 423 | the Licensor hereby grants You a worldwide, royalty-free, 424 | non-sublicensable, non-exclusive, irrevocable license to 425 | exercise the Licensed Rights in the Licensed Material to: 426 | 427 | a. reproduce and Share the Licensed Material, in whole or 428 | in part; and 429 | 430 | b. produce and reproduce, but not Share, Adapted Material. 431 | 432 | 2. Exceptions and Limitations. For the avoidance of doubt, where 433 | Exceptions and Limitations apply to Your use, this Public 434 | License does not apply, and You do not need to comply with 435 | its terms and conditions. 436 | 437 | 3. Term. The term of this Public License is specified in Section 438 | 6(a). 439 | 440 | 4. Media and formats; technical modifications allowed. The 441 | Licensor authorizes You to exercise the Licensed Rights in 442 | all media and formats whether now known or hereafter created, 443 | and to make technical modifications necessary to do so. The 444 | Licensor waives and/or agrees not to assert any right or 445 | authority to forbid You from making technical modifications 446 | necessary to exercise the Licensed Rights, including 447 | technical modifications necessary to circumvent Effective 448 | Technological Measures. For purposes of this Public License, 449 | simply making modifications authorized by this Section 2(a) 450 | (4) never produces Adapted Material. 451 | 452 | 5. Downstream recipients. 453 | 454 | a. Offer from the Licensor -- Licensed Material. Every 455 | recipient of the Licensed Material automatically 456 | receives an offer from the Licensor to exercise the 457 | Licensed Rights under the terms and conditions of this 458 | Public License. 459 | 460 | b. No downstream restrictions. You may not offer or impose 461 | any additional or different terms or conditions on, or 462 | apply any Effective Technological Measures to, the 463 | Licensed Material if doing so restricts exercise of the 464 | Licensed Rights by any recipient of the Licensed 465 | Material. 466 | 467 | 6. No endorsement. Nothing in this Public License constitutes or 468 | may be construed as permission to assert or imply that You 469 | are, or that Your use of the Licensed Material is, connected 470 | with, or sponsored, endorsed, or granted official status by, 471 | the Licensor or others designated to receive attribution as 472 | provided in Section 3(a)(1)(A)(i). 473 | 474 | b. Other rights. 475 | 476 | 1. Moral rights, such as the right of integrity, are not 477 | licensed under this Public License, nor are publicity, 478 | privacy, and/or other similar personality rights; however, to 479 | the extent possible, the Licensor waives and/or agrees not to 480 | assert any such rights held by the Licensor to the limited 481 | extent necessary to allow You to exercise the Licensed 482 | Rights, but not otherwise. 483 | 484 | 2. Patent and trademark rights are not licensed under this 485 | Public License. 486 | 487 | 3. To the extent possible, the Licensor waives any right to 488 | collect royalties from You for the exercise of the Licensed 489 | Rights, whether directly or through a collecting society 490 | under any voluntary or waivable statutory or compulsory 491 | licensing scheme. In all other cases the Licensor expressly 492 | reserves any right to collect such royalties. 493 | 494 | 495 | Section 3 -- License Conditions. 496 | 497 | Your exercise of the Licensed Rights is expressly made subject to the 498 | following conditions. 499 | 500 | a. Attribution. 501 | 502 | 1. If You Share the Licensed Material, You must: 503 | 504 | a. retain the following if it is supplied by the Licensor 505 | with the Licensed Material: 506 | 507 | i. identification of the creator(s) of the Licensed 508 | Material and any others designated to receive 509 | attribution, in any reasonable manner requested by 510 | the Licensor (including by pseudonym if 511 | designated); 512 | 513 | ii. a copyright notice; 514 | 515 | iii. a notice that refers to this Public License; 516 | 517 | iv. a notice that refers to the disclaimer of 518 | warranties; 519 | 520 | v. a URI or hyperlink to the Licensed Material to the 521 | extent reasonably practicable; 522 | 523 | b. indicate if You modified the Licensed Material and 524 | retain an indication of any previous modifications; and 525 | 526 | c. indicate the Licensed Material is licensed under this 527 | Public License, and include the text of, or the URI or 528 | hyperlink to, this Public License. 529 | 530 | For the avoidance of doubt, You do not have permission under 531 | this Public License to Share Adapted Material. 532 | 533 | 2. You may satisfy the conditions in Section 3(a)(1) in any 534 | reasonable manner based on the medium, means, and context in 535 | which You Share the Licensed Material. For example, it may be 536 | reasonable to satisfy the conditions by providing a URI or 537 | hyperlink to a resource that includes the required 538 | information. 539 | 540 | 3. If requested by the Licensor, You must remove any of the 541 | information required by Section 3(a)(1)(A) to the extent 542 | reasonably practicable. 543 | 544 | 545 | Section 4 -- Sui Generis Database Rights. 546 | 547 | Where the Licensed Rights include Sui Generis Database Rights that 548 | apply to Your use of the Licensed Material: 549 | 550 | a. for the avoidance of doubt, Section 2(a)(1) grants You the right 551 | to extract, reuse, reproduce, and Share all or a substantial 552 | portion of the contents of the database, provided You do not Share 553 | Adapted Material; 554 | b. if You include all or a substantial portion of the database 555 | contents in a database in which You have Sui Generis Database 556 | Rights, then the database in which You have Sui Generis Database 557 | Rights (but not its individual contents) is Adapted Material; and 558 | c. You must comply with the conditions in Section 3(a) if You Share 559 | all or a substantial portion of the contents of the database. 560 | 561 | For the avoidance of doubt, this Section 4 supplements and does not 562 | replace Your obligations under this Public License where the Licensed 563 | Rights include other Copyright and Similar Rights. 564 | 565 | 566 | Section 5 -- Disclaimer of Warranties and Limitation of Liability. 567 | 568 | a. UNLESS OTHERWISE SEPARATELY UNDERTAKEN BY THE LICENSOR, TO THE 569 | EXTENT POSSIBLE, THE LICENSOR OFFERS THE LICENSED MATERIAL AS-IS 570 | AND AS-AVAILABLE, AND MAKES NO REPRESENTATIONS OR WARRANTIES OF 571 | ANY KIND CONCERNING THE LICENSED MATERIAL, WHETHER EXPRESS, 572 | IMPLIED, STATUTORY, OR OTHER. THIS INCLUDES, WITHOUT LIMITATION, 573 | WARRANTIES OF TITLE, MERCHANTABILITY, FITNESS FOR A PARTICULAR 574 | PURPOSE, NON-INFRINGEMENT, ABSENCE OF LATENT OR OTHER DEFECTS, 575 | ACCURACY, OR THE PRESENCE OR ABSENCE OF ERRORS, WHETHER OR NOT 576 | KNOWN OR DISCOVERABLE. WHERE DISCLAIMERS OF WARRANTIES ARE NOT 577 | ALLOWED IN FULL OR IN PART, THIS DISCLAIMER MAY NOT APPLY TO YOU. 578 | 579 | b. TO THE EXTENT POSSIBLE, IN NO EVENT WILL THE LICENSOR BE LIABLE 580 | TO YOU ON ANY LEGAL THEORY (INCLUDING, WITHOUT LIMITATION, 581 | NEGLIGENCE) OR OTHERWISE FOR ANY DIRECT, SPECIAL, INDIRECT, 582 | INCIDENTAL, CONSEQUENTIAL, PUNITIVE, EXEMPLARY, OR OTHER LOSSES, 583 | COSTS, EXPENSES, OR DAMAGES ARISING OUT OF THIS PUBLIC LICENSE OR 584 | USE OF THE LICENSED MATERIAL, EVEN IF THE LICENSOR HAS BEEN 585 | ADVISED OF THE POSSIBILITY OF SUCH LOSSES, COSTS, EXPENSES, OR 586 | DAMAGES. WHERE A LIMITATION OF LIABILITY IS NOT ALLOWED IN FULL OR 587 | IN PART, THIS LIMITATION MAY NOT APPLY TO YOU. 588 | 589 | c. The disclaimer of warranties and limitation of liability provided 590 | above shall be interpreted in a manner that, to the extent 591 | possible, most closely approximates an absolute disclaimer and 592 | waiver of all liability. 593 | 594 | 595 | Section 6 -- Term and Termination. 596 | 597 | a. This Public License applies for the term of the Copyright and 598 | Similar Rights licensed here. However, if You fail to comply with 599 | this Public License, then Your rights under this Public License 600 | terminate automatically. 601 | 602 | b. Where Your right to use the Licensed Material has terminated under 603 | Section 6(a), it reinstates: 604 | 605 | 1. automatically as of the date the violation is cured, provided 606 | it is cured within 30 days of Your discovery of the 607 | violation; or 608 | 609 | 2. upon express reinstatement by the Licensor. 610 | 611 | For the avoidance of doubt, this Section 6(b) does not affect any 612 | right the Licensor may have to seek remedies for Your violations 613 | of this Public License. 614 | 615 | c. For the avoidance of doubt, the Licensor may also offer the 616 | Licensed Material under separate terms or conditions or stop 617 | distributing the Licensed Material at any time; however, doing so 618 | will not terminate this Public License. 619 | 620 | d. Sections 1, 5, 6, 7, and 8 survive termination of this Public 621 | License. 622 | 623 | 624 | Section 7 -- Other Terms and Conditions. 625 | 626 | a. The Licensor shall not be bound by any additional or different 627 | terms or conditions communicated by You unless expressly agreed. 628 | 629 | b. Any arrangements, understandings, or agreements regarding the 630 | Licensed Material not stated herein are separate from and 631 | independent of the terms and conditions of this Public License. 632 | 633 | 634 | Section 8 -- Interpretation. 635 | 636 | a. For the avoidance of doubt, this Public License does not, and 637 | shall not be interpreted to, reduce, limit, restrict, or impose 638 | conditions on any use of the Licensed Material that could lawfully 639 | be made without permission under this Public License. 640 | 641 | b. To the extent possible, if any provision of this Public License is 642 | deemed unenforceable, it shall be automatically reformed to the 643 | minimum extent necessary to make it enforceable. If the provision 644 | cannot be reformed, it shall be severed from this Public License 645 | without affecting the enforceability of the remaining terms and 646 | conditions. 647 | 648 | c. No term or condition of this Public License will be waived and no 649 | failure to comply consented to unless expressly agreed to by the 650 | Licensor. 651 | 652 | d. Nothing in this Public License constitutes or may be interpreted 653 | as a limitation upon, or waiver of, any privileges and immunities 654 | that apply to the Licensor or You, including from the legal 655 | processes of any jurisdiction or authority. 656 | 657 | ======================================================================= 658 | 659 | Creative Commons is not a party to its public 660 | licenses. Notwithstanding, Creative Commons may elect to apply one of 661 | its public licenses to material it publishes and in those instances 662 | will be considered the “Licensor.” The text of the Creative Commons 663 | public licenses is dedicated to the public domain under the CC0 Public 664 | Domain Dedication. Except for the limited purpose of indicating that 665 | material is shared under a Creative Commons public license or as 666 | otherwise permitted by the Creative Commons policies published at 667 | creativecommons.org/policies, Creative Commons does not authorize the 668 | use of the trademark "Creative Commons" or any other trademark or logo 669 | of Creative Commons without its prior written consent including, 670 | without limitation, in connection with any unauthorized modifications 671 | to any of its public licenses or any other arrangements, 672 | understandings, or agreements concerning use of licensed material. For 673 | the avoidance of doubt, this paragraph does not form part of the 674 | public licenses. 675 | 676 | Creative Commons may be contacted at creativecommons.org. 677 | -------------------------------------------------------------------------------- /Makefile: -------------------------------------------------------------------------------- 1 | # Default values if not set 2 | CONTAINER_REGISTRY ?= icr.io 3 | REGISTRY_REPO ?= appcafe/open-liberty/samples/getting-started 4 | IMAGE_TAG ?= latest 5 | IMAGE ?= ${CONTAINER_REGISTRY}/${REGISTRY_REPO}:${IMAGE_TAG} 6 | 7 | docker-login: 8 | echo ${PIPELINE_PASSWORD} | docker login ${CONTAINER_REGISTRY} -u "${PIPELINE_USERNAME}" --password-stdin 9 | 10 | build-app-pipeline: docker-login 11 | ./scripts/build-app.sh --image "${IMAGE}" 12 | 13 | build-manifest-pipeline: 14 | ./scripts/build-manifest.sh --image "${IMAGE}" 15 | 16 | check-build: docker-login 17 | ./scripts/pipeline/check-build.sh --image "${IMAGE}" 18 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | ![Open Liberty logo](https://github.com/OpenLiberty/logos/blob/main/combomark/png/OL_logo_green_on_white.png) 2 | 3 | # Open Liberty Getting Started sample 4 | 5 | ## Overview 6 | The sample application provides a simple example of how to get started with Open Liberty. It provides a REST API that retrieves the system properties in the JVM and a web based UI for viewing them. It also uses MicroProfile Config, MicroProfile Health and MicroProfile Metrics to demonstrate how to use these specifications in an application that maybe deployed to kubernetes. 7 | 8 | ## Project structure 9 | 10 | - `src/main/java` - the Java code for the Project 11 | - `io/openliberty/sample` 12 | - `config` 13 | - `ConfigResource.java` - A REST Resource that exposes MicroProfile Config via a /rest/config GET request 14 | - `CustomConfigSource.java` - A MicroProfile Config ConfigSource that reads a json file. 15 | - `system` 16 | - `SystemConfig.java` - A CDI bean that will report if the application is in maintenance. This supports the config variable changing dynamically via an update to a json file. 17 | - `SystemHealth.java` - A MicroProfile Health check that reports DOWN if the application is in maintenance and UP otherwise. 18 | - `SystemResource.java` - A REST Resource that exposes the System properties via a /rest/properties GET request. Calls to this GET method have MicroProfile Timer and Count metrics applied. 19 | - `SystemRuntime.java` - A REST Resource that exposes the version of the Open Liberty runtime via a /rest/runtime GET request. 20 | - `SystemApplication.java` - The Jakarta RESTful Web Services Application class 21 | - `liberty/config/server.xml` - The server configuration for the liberty runtime 22 | - `META-INF` - Contains the metadata files for MicroProfile Config including how to load CustomConfigSource.java 23 | - `webapp` - Contains the Web UI for the application. 24 | - `test/java/it/io/openliberty/sample/health` 25 | - `HealthIT.java` - Test cases for a sample application running on `localhost` 26 | - `HealthUtilIT.java` - Utility methods for functional tests 27 | - `resources/CustomConfigSource.json` - Contains the data that is read by the MicroProfile Config ConfigSource. 28 | - `Dockerfile` - The Dockerfile for building the sample 29 | - `pom.xml` - The Maven POM file 30 | 31 | ## Build and Run the Sample locally 32 | 33 | Clone the project 34 | 35 | ``` 36 | git clone https://github.com/OpenLiberty/sample-getting-started.git 37 | ``` 38 | 39 | then build and run it using Liberty dev mode: 40 | 41 | ``` 42 | mvnw liberty:dev 43 | ``` 44 | 45 | if you just want to build it run: 46 | 47 | ``` 48 | mvnw package 49 | ``` 50 | 51 | ## Build container image from Dockerfile and run locally 52 | To build the container image from Dockerfile and run locally using docker: 53 | 54 | ``` 55 | docker build --platform=linux/amd64 -t openliberty-gettingstarted: . 56 | docker images --filter reference=openliberty-gettingstarted 57 | sudo docker run --platform=linux/amd64 -t -i -p 127.0.0.1:9080:9080 openliberty-gettingstarted: 58 | ``` 59 | 60 | To build the container image from Dockerfile and run locally using podman: 61 | 62 | ``` 63 | podman build --platform=linux/amd64 -t openliberty-gettingstarted: . 64 | podman images --filter reference=openliberty-gettingstarted 65 | sudo podman run --platform=linux/amd64 -t -i -p 127.0.0.1:9080:9080 openliberty-gettingstarted: 66 | ``` 67 | 68 | ### Access the application 69 | Open a browser to http://localhost:9080 70 | 71 | ## Run the Sample in a container 72 | 73 | To run the sample using docker run: 74 | 75 | ``` 76 | docker run -p 9080:9080 icr.io/appcafe/open-liberty/samples/getting-started 77 | ``` 78 | 79 | To run the sample using podman run: 80 | 81 | ``` 82 | podman run -p 9080:9080 icr.io/appcafe/open-liberty/samples/getting-started 83 | ``` 84 | 85 | 86 | ### Access the application 87 | Open a browser to http://localhost:9080 88 | 89 | ![image](https://user-images.githubusercontent.com/3076261/117993383-4f34c980-b305-11eb-94b5-fa7319bc2850.png) 90 | 91 | ## Run the functional tests 92 | 93 | The test cases uses [JUnit 5](https://junit.org/junit5/) and 94 | [Maven Failsafe Plugin](https://maven.apache.org/surefire/maven-failsafe-plugin/index.html) defined 95 | in [`pom.xml`](pom.xml). 96 | 97 | > Note: Sample appplication must be running on `http://localhost` before running the test cases. 98 | >
99 | > See [`HealthUtilIT.java`](src/test/java/it/io/openliberty/sample/health/HealthUtilIT.java) to change 100 | > the change the sample application target URL. 101 | 102 | To run the test cases against a running sample application, use the following command 103 | ``` 104 | mvnw failsafe:integration-test 105 | ``` 106 | 107 | To view the test results, look at the console output or look under 108 | directory `target/failsafe-reports` 109 | -------------------------------------------------------------------------------- /ebcDockerBuilderLGS.jenkinsfile: -------------------------------------------------------------------------------- 1 | properties([ 2 | parameters([ 3 | // EBC relevant properties 4 | string(name: 'executionId', defaultValue: UUID.randomUUID().toString(), description: 'Unique execution id'), 5 | string(name: 'ebcPriority', defaultValue: '200', description: 'EBC Priority'), 6 | string(name: 'ebcPlan', defaultValue: 'svl-dockerJenkins-ubuntu20_ppcle.yml', description: 'EBC plan to use when provisioning a Jenkins node'), 7 | string(name: 'ebcBranch', defaultValue: "${env.ecosystem_branch}", description: 'Git branch used for ebc code'), 8 | string(name: 'scriptOrg', defaultValue: "OpenLiberty", description: 'Git org containing docker build scripts'), 9 | string(name: 'command', defaultValue: "make build-app-pipeline IMAGE=stg.icr.io/cp/olc-sample/open-liberty/samples/getting-started", description: 'Build command to execute on target arch machine, e.g. make build-pipeline-releases'), 10 | string(name: 'BRANCH', defaultValue: "main", description: 'release branch to use'), 11 | string(name: 'CONTAINER_REGISTRY', defaultValue: "stg.icr.io", description: 'staging registry to push images to') 12 | ]) 13 | ]) 14 | timestamps { 15 | // Identify if the job was kicked off by the seed job. 16 | def causes = currentBuild.getBuildCauses() 17 | for(cause in causes) { 18 | if ("seed".equalsIgnoreCase(cause.upstreamProject)) { 19 | // As the seed job kicked off this build, bail early returning success. 20 | // This allows the jenkinsfile's properties to be populated. 21 | currentBuild.result = 'SUCCESS' 22 | println "Returning success as upstream job is the seed job; this is therefore a dummy run to populate job parameters." 23 | return 24 | } 25 | } 26 | 27 | def ebcPriority = "${params.ebcPriority}" 28 | def executionId = "${params.executionId}" 29 | def ebcPlan = "${params.ebcPlan}" 30 | 31 | try { 32 | node (label: 'built-in') { 33 | ws("workspace/${env.JOB_NAME}-${env.BUILD_NUMBER}") { 34 | stage ("EBC Demand"){ 35 | //This is executing on Jenkins Server 36 | ebcDemand() 37 | gitCloneAndStash(); 38 | } 39 | } 40 | } 41 | 42 | node(label: "ebc_${executionId}"){ 43 | stage("Running Job"){ 44 | withCredentials([usernamePassword(credentialsId: 'operator_icrId', usernameVariable: 'PIPELINE_USERNAME', passwordVariable: 'PIPELINE_PASSWORD'), 45 | usernamePassword(credentialsId: 'dockerId', usernameVariable: 'DOCKER_USERNAME', passwordVariable: 'DOCKER_PASSWORD')]) { 46 | //This is executing on ebc dynamic machine 47 | doWork(); 48 | } // withCredentials() end 49 | } 50 | } 51 | } finally { 52 | node (label: 'built-in') { 53 | ws("workspace/${env.JOB_NAME}-${env.BUILD_NUMBER}") { 54 | stage ("EBC Cleanup"){ 55 | //This is executing on Jenkins Server 56 | ebcCleanup(); 57 | // Clean up the workspace 58 | cleanWs(cleanWhenAborted: true, 59 | cleanWhenFailure: true, 60 | cleanWhenNotBuilt: false, 61 | cleanWhenSuccess: true, 62 | cleanWhenUnstable: true, 63 | deleteDirs: true, 64 | disableDeferredWipeout: false, 65 | notFailBuild: true) 66 | } 67 | } 68 | } 69 | } 70 | } 71 | // Functions Only Below here 72 | 73 | // Clone the git repo and stash it, so that the jenkins agent machine can grab it later 74 | def gitCloneAndStash() { 75 | git branch: BRANCH, url: "git@github.com:${scriptOrg}/sample-getting-started.git" 76 | stash(name: 'sample-getting-started') 77 | } 78 | 79 | // Job Specific Functions 80 | def void doWork(){ 81 | // Setup global variables 82 | 83 | // Unstash the git repo 84 | unstash(name: 'sample-getting-started') 85 | 86 | withMaven(maven: '3.6.3') { 87 | sh "${COMMAND}" 88 | } 89 | 90 | } 91 | 92 | 93 | // EBC Functions 94 | def void ebcDemand(){ 95 | buildName executionId 96 | //cleanWs() 97 | git branch: ebcBranch, url:'git@github.ibm.com:elastic-build-cloud/ebc-gateway-http' 98 | withCredentials([usernamePassword(credentialsId: 'intranetId', usernameVariable: 'intranetId_USR', passwordVariable: 'intranetId_PSW')]) { 99 | withEnv([ 100 | "demandId=${executionId}", 101 | "ebcEnvironment=${ebcBranch}", 102 | "ebc_plan=${ebcPlan}", 103 | "ebc_priority=${ebcPriority}", 104 | "ebc_autoCompleteAfterXHours=24", 105 | "ebc_reasonForEnvironment=${env.BUILD_URL}", 106 | "ebc_jenkins_agent_label=ebc_${executionId}", 107 | "ebc_jenkins_server_instance_name=${env.jenkins_server_instance_name}", 108 | "ebc_jenkins_service_name=${env.jenkins_service_name}" 109 | ]){ 110 | sh "./ebc_demand.sh" 111 | } 112 | } 113 | stash(name: 'ebc-gateway-http') 114 | } 115 | 116 | def void ebcCleanup(){ 117 | //cleanWs() 118 | unstash(name: 'ebc-gateway-http') 119 | withCredentials([usernamePassword(credentialsId: 'intranetId', usernameVariable: 'intranetId_USR', passwordVariable: 'intranetId_PSW')]) { 120 | withEnv([ 121 | "demandId=${executionId}", 122 | "ebcEnvironment=${ebcBranch}" 123 | ]){ 124 | sh "./ebc_complete.sh" 125 | } 126 | } 127 | } -------------------------------------------------------------------------------- /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 | # Maven Start Up Batch script 23 | # 24 | # Required ENV vars: 25 | # ------------------ 26 | # JAVA_HOME - location of a JDK home dir 27 | # 28 | # Optional ENV vars 29 | # ----------------- 30 | # M2_HOME - location of maven2's installed home dir 31 | # MAVEN_OPTS - parameters passed to the Java VM when running Maven 32 | # e.g. to debug Maven itself, use 33 | # set MAVEN_OPTS=-Xdebug -Xrunjdwp:transport=dt_socket,server=y,suspend=y,address=8000 34 | # MAVEN_SKIP_RC - flag to disable loading of mavenrc files 35 | # ---------------------------------------------------------------------------- 36 | 37 | if [ -z "$MAVEN_SKIP_RC" ] ; then 38 | 39 | if [ -f /usr/local/etc/mavenrc ] ; then 40 | . /usr/local/etc/mavenrc 41 | fi 42 | 43 | if [ -f /etc/mavenrc ] ; then 44 | . /etc/mavenrc 45 | fi 46 | 47 | if [ -f "$HOME/.mavenrc" ] ; then 48 | . "$HOME/.mavenrc" 49 | fi 50 | 51 | fi 52 | 53 | # OS specific support. $var _must_ be set to either true or false. 54 | cygwin=false; 55 | darwin=false; 56 | mingw=false 57 | case "`uname`" in 58 | CYGWIN*) cygwin=true ;; 59 | MINGW*) mingw=true;; 60 | Darwin*) 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 | export JAVA_HOME="`/usr/libexec/java_home`" 66 | else 67 | export JAVA_HOME="/Library/Java/Home" 68 | fi 69 | fi 70 | ;; 71 | esac 72 | 73 | if [ -z "$JAVA_HOME" ] ; then 74 | if [ -r /etc/gentoo-release ] ; then 75 | JAVA_HOME=`java-config --jre-home` 76 | fi 77 | fi 78 | 79 | if [ -z "$M2_HOME" ] ; then 80 | ## resolve links - $0 may be a link to maven's home 81 | PRG="$0" 82 | 83 | # need this for relative symlinks 84 | while [ -h "$PRG" ] ; do 85 | ls=`ls -ld "$PRG"` 86 | link=`expr "$ls" : '.*-> \(.*\)$'` 87 | if expr "$link" : '/.*' > /dev/null; then 88 | PRG="$link" 89 | else 90 | PRG="`dirname "$PRG"`/$link" 91 | fi 92 | done 93 | 94 | saveddir=`pwd` 95 | 96 | M2_HOME=`dirname "$PRG"`/.. 97 | 98 | # make it fully qualified 99 | M2_HOME=`cd "$M2_HOME" && pwd` 100 | 101 | cd "$saveddir" 102 | # echo Using m2 at $M2_HOME 103 | fi 104 | 105 | # For Cygwin, ensure paths are in UNIX format before anything is touched 106 | if $cygwin ; then 107 | [ -n "$M2_HOME" ] && 108 | M2_HOME=`cygpath --unix "$M2_HOME"` 109 | [ -n "$JAVA_HOME" ] && 110 | JAVA_HOME=`cygpath --unix "$JAVA_HOME"` 111 | [ -n "$CLASSPATH" ] && 112 | CLASSPATH=`cygpath --path --unix "$CLASSPATH"` 113 | fi 114 | 115 | # For Mingw, ensure paths are in UNIX format before anything is touched 116 | if $mingw ; then 117 | [ -n "$M2_HOME" ] && 118 | M2_HOME="`(cd "$M2_HOME"; pwd)`" 119 | [ -n "$JAVA_HOME" ] && 120 | JAVA_HOME="`(cd "$JAVA_HOME"; pwd)`" 121 | fi 122 | 123 | if [ -z "$JAVA_HOME" ]; then 124 | javaExecutable="`which javac`" 125 | if [ -n "$javaExecutable" ] && ! [ "`expr \"$javaExecutable\" : '\([^ ]*\)'`" = "no" ]; then 126 | # readlink(1) is not available as standard on Solaris 10. 127 | readLink=`which readlink` 128 | if [ ! `expr "$readLink" : '\([^ ]*\)'` = "no" ]; then 129 | if $darwin ; then 130 | javaHome="`dirname \"$javaExecutable\"`" 131 | javaExecutable="`cd \"$javaHome\" && pwd -P`/javac" 132 | else 133 | javaExecutable="`readlink -f \"$javaExecutable\"`" 134 | fi 135 | javaHome="`dirname \"$javaExecutable\"`" 136 | javaHome=`expr "$javaHome" : '\(.*\)/bin'` 137 | JAVA_HOME="$javaHome" 138 | export JAVA_HOME 139 | fi 140 | fi 141 | fi 142 | 143 | if [ -z "$JAVACMD" ] ; then 144 | if [ -n "$JAVA_HOME" ] ; then 145 | if [ -x "$JAVA_HOME/jre/sh/java" ] ; then 146 | # IBM's JDK on AIX uses strange locations for the executables 147 | JAVACMD="$JAVA_HOME/jre/sh/java" 148 | else 149 | JAVACMD="$JAVA_HOME/bin/java" 150 | fi 151 | else 152 | JAVACMD="`\\unset -f command; \\command -v java`" 153 | fi 154 | fi 155 | 156 | if [ ! -x "$JAVACMD" ] ; then 157 | echo "Error: JAVA_HOME is not defined correctly." >&2 158 | echo " We cannot execute $JAVACMD" >&2 159 | exit 1 160 | fi 161 | 162 | if [ -z "$JAVA_HOME" ] ; then 163 | echo "Warning: JAVA_HOME environment variable is not set." 164 | fi 165 | 166 | CLASSWORLDS_LAUNCHER=org.codehaus.plexus.classworlds.launcher.Launcher 167 | 168 | # traverses directory structure from process work directory to filesystem root 169 | # first directory with .mvn subdirectory is considered project base directory 170 | find_maven_basedir() { 171 | 172 | if [ -z "$1" ] 173 | then 174 | echo "Path not specified to find_maven_basedir" 175 | return 1 176 | fi 177 | 178 | basedir="$1" 179 | wdir="$1" 180 | while [ "$wdir" != '/' ] ; do 181 | if [ -d "$wdir"/.mvn ] ; then 182 | basedir=$wdir 183 | break 184 | fi 185 | # workaround for JBEAP-8937 (on Solaris 10/Sparc) 186 | if [ -d "${wdir}" ]; then 187 | wdir=`cd "$wdir/.."; pwd` 188 | fi 189 | # end of workaround 190 | done 191 | echo "${basedir}" 192 | } 193 | 194 | # concatenates all lines of a file 195 | concat_lines() { 196 | if [ -f "$1" ]; then 197 | echo "$(tr -s '\n' ' ' < "$1")" 198 | fi 199 | } 200 | 201 | BASE_DIR=`find_maven_basedir "$(pwd)"` 202 | if [ -z "$BASE_DIR" ]; then 203 | exit 1; 204 | fi 205 | 206 | ########################################################################################## 207 | # Extension to allow automatically downloading the maven-wrapper.jar from Maven-central 208 | # This allows using the maven wrapper in projects that prohibit checking in binary data. 209 | ########################################################################################## 210 | if [ -r "$BASE_DIR/.mvn/wrapper/maven-wrapper.jar" ]; then 211 | if [ "$MVNW_VERBOSE" = true ]; then 212 | echo "Found .mvn/wrapper/maven-wrapper.jar" 213 | fi 214 | else 215 | if [ "$MVNW_VERBOSE" = true ]; then 216 | echo "Couldn't find .mvn/wrapper/maven-wrapper.jar, downloading it ..." 217 | fi 218 | if [ -n "$MVNW_REPOURL" ]; then 219 | jarUrl="$MVNW_REPOURL/org/apache/maven/wrapper/maven-wrapper/3.1.0/maven-wrapper-3.1.0.jar" 220 | else 221 | jarUrl="https://repo.maven.apache.org/maven2/org/apache/maven/wrapper/maven-wrapper/3.1.0/maven-wrapper-3.1.0.jar" 222 | fi 223 | while IFS="=" read key value; do 224 | case "$key" in (wrapperUrl) jarUrl="$value"; break ;; 225 | esac 226 | done < "$BASE_DIR/.mvn/wrapper/maven-wrapper.properties" 227 | if [ "$MVNW_VERBOSE" = true ]; then 228 | echo "Downloading from: $jarUrl" 229 | fi 230 | wrapperJarPath="$BASE_DIR/.mvn/wrapper/maven-wrapper.jar" 231 | if $cygwin; then 232 | wrapperJarPath=`cygpath --path --windows "$wrapperJarPath"` 233 | fi 234 | 235 | if command -v wget > /dev/null; then 236 | if [ "$MVNW_VERBOSE" = true ]; then 237 | echo "Found wget ... using wget" 238 | fi 239 | if [ -z "$MVNW_USERNAME" ] || [ -z "$MVNW_PASSWORD" ]; then 240 | wget "$jarUrl" -O "$wrapperJarPath" || rm -f "$wrapperJarPath" 241 | else 242 | wget --http-user=$MVNW_USERNAME --http-password=$MVNW_PASSWORD "$jarUrl" -O "$wrapperJarPath" || rm -f "$wrapperJarPath" 243 | fi 244 | elif command -v curl > /dev/null; then 245 | if [ "$MVNW_VERBOSE" = true ]; then 246 | echo "Found curl ... using curl" 247 | fi 248 | if [ -z "$MVNW_USERNAME" ] || [ -z "$MVNW_PASSWORD" ]; then 249 | curl -o "$wrapperJarPath" "$jarUrl" -f 250 | else 251 | curl --user $MVNW_USERNAME:$MVNW_PASSWORD -o "$wrapperJarPath" "$jarUrl" -f 252 | fi 253 | 254 | else 255 | if [ "$MVNW_VERBOSE" = true ]; then 256 | echo "Falling back to using Java to download" 257 | fi 258 | javaClass="$BASE_DIR/.mvn/wrapper/MavenWrapperDownloader.java" 259 | # For Cygwin, switch paths to Windows format before running javac 260 | if $cygwin; then 261 | javaClass=`cygpath --path --windows "$javaClass"` 262 | fi 263 | if [ -e "$javaClass" ]; then 264 | if [ ! -e "$BASE_DIR/.mvn/wrapper/MavenWrapperDownloader.class" ]; then 265 | if [ "$MVNW_VERBOSE" = true ]; then 266 | echo " - Compiling MavenWrapperDownloader.java ..." 267 | fi 268 | # Compiling the Java class 269 | ("$JAVA_HOME/bin/javac" "$javaClass") 270 | fi 271 | if [ -e "$BASE_DIR/.mvn/wrapper/MavenWrapperDownloader.class" ]; then 272 | # Running the downloader 273 | if [ "$MVNW_VERBOSE" = true ]; then 274 | echo " - Running MavenWrapperDownloader.java ..." 275 | fi 276 | ("$JAVA_HOME/bin/java" -cp .mvn/wrapper MavenWrapperDownloader "$MAVEN_PROJECTBASEDIR") 277 | fi 278 | fi 279 | fi 280 | fi 281 | ########################################################################################## 282 | # End of extension 283 | ########################################################################################## 284 | 285 | export MAVEN_PROJECTBASEDIR=${MAVEN_BASEDIR:-"$BASE_DIR"} 286 | if [ "$MVNW_VERBOSE" = true ]; then 287 | echo $MAVEN_PROJECTBASEDIR 288 | fi 289 | MAVEN_OPTS="$(concat_lines "$MAVEN_PROJECTBASEDIR/.mvn/jvm.config") $MAVEN_OPTS" 290 | 291 | # For Cygwin, switch paths to Windows format before running java 292 | if $cygwin; then 293 | [ -n "$M2_HOME" ] && 294 | M2_HOME=`cygpath --path --windows "$M2_HOME"` 295 | [ -n "$JAVA_HOME" ] && 296 | JAVA_HOME=`cygpath --path --windows "$JAVA_HOME"` 297 | [ -n "$CLASSPATH" ] && 298 | CLASSPATH=`cygpath --path --windows "$CLASSPATH"` 299 | [ -n "$MAVEN_PROJECTBASEDIR" ] && 300 | MAVEN_PROJECTBASEDIR=`cygpath --path --windows "$MAVEN_PROJECTBASEDIR"` 301 | fi 302 | 303 | # Provide a "standardized" way to retrieve the CLI args that will 304 | # work with both Windows and non-Windows executions. 305 | MAVEN_CMD_LINE_ARGS="$MAVEN_CONFIG $@" 306 | export MAVEN_CMD_LINE_ARGS 307 | 308 | WRAPPER_LAUNCHER=org.apache.maven.wrapper.MavenWrapperMain 309 | 310 | exec "$JAVACMD" \ 311 | $MAVEN_OPTS \ 312 | $MAVEN_DEBUG_OPTS \ 313 | -classpath "$MAVEN_PROJECTBASEDIR/.mvn/wrapper/maven-wrapper.jar" \ 314 | "-Dmaven.home=${M2_HOME}" \ 315 | "-Dmaven.multiModuleProjectDirectory=${MAVEN_PROJECTBASEDIR}" \ 316 | ${WRAPPER_LAUNCHER} $MAVEN_CONFIG "$@" 317 | -------------------------------------------------------------------------------- /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 Maven Start Up Batch script 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 M2_HOME - location of maven2's installed home dir 28 | @REM MAVEN_BATCH_ECHO - set to 'on' to enable the echoing of the batch commands 29 | @REM MAVEN_BATCH_PAUSE - set to 'on' to wait for a keystroke before ending 30 | @REM MAVEN_OPTS - parameters passed to the Java VM when running Maven 31 | @REM e.g. to debug Maven itself, use 32 | @REM set MAVEN_OPTS=-Xdebug -Xrunjdwp:transport=dt_socket,server=y,suspend=y,address=8000 33 | @REM MAVEN_SKIP_RC - flag to disable loading of mavenrc files 34 | @REM ---------------------------------------------------------------------------- 35 | 36 | @REM Begin all REM lines with '@' in case MAVEN_BATCH_ECHO is 'on' 37 | @echo off 38 | @REM set title of command window 39 | title %0 40 | @REM enable echoing by setting MAVEN_BATCH_ECHO to 'on' 41 | @if "%MAVEN_BATCH_ECHO%" == "on" echo %MAVEN_BATCH_ECHO% 42 | 43 | @REM set %HOME% to equivalent of $HOME 44 | if "%HOME%" == "" (set "HOME=%HOMEDRIVE%%HOMEPATH%") 45 | 46 | @REM Execute a user defined script before this one 47 | if not "%MAVEN_SKIP_RC%" == "" goto skipRcPre 48 | @REM check for pre script, once with legacy .bat ending and once with .cmd ending 49 | if exist "%USERPROFILE%\mavenrc_pre.bat" call "%USERPROFILE%\mavenrc_pre.bat" %* 50 | if exist "%USERPROFILE%\mavenrc_pre.cmd" call "%USERPROFILE%\mavenrc_pre.cmd" %* 51 | :skipRcPre 52 | 53 | @setlocal 54 | 55 | set ERROR_CODE=0 56 | 57 | @REM To isolate internal variables from possible post scripts, we use another setlocal 58 | @setlocal 59 | 60 | @REM ==== START VALIDATION ==== 61 | if not "%JAVA_HOME%" == "" goto OkJHome 62 | 63 | echo. 64 | echo Error: JAVA_HOME not found in your environment. >&2 65 | echo Please set the JAVA_HOME variable in your environment to match the >&2 66 | echo location of your Java installation. >&2 67 | echo. 68 | goto error 69 | 70 | :OkJHome 71 | if exist "%JAVA_HOME%\bin\java.exe" goto init 72 | 73 | echo. 74 | echo Error: JAVA_HOME is set to an invalid directory. >&2 75 | echo JAVA_HOME = "%JAVA_HOME%" >&2 76 | echo Please set the JAVA_HOME variable in your environment to match the >&2 77 | echo location of your Java installation. >&2 78 | echo. 79 | goto error 80 | 81 | @REM ==== END VALIDATION ==== 82 | 83 | :init 84 | 85 | @REM Find the project base dir, i.e. the directory that contains the folder ".mvn". 86 | @REM Fallback to current working directory if not found. 87 | 88 | set MAVEN_PROJECTBASEDIR=%MAVEN_BASEDIR% 89 | IF NOT "%MAVEN_PROJECTBASEDIR%"=="" goto endDetectBaseDir 90 | 91 | set EXEC_DIR=%CD% 92 | set WDIR=%EXEC_DIR% 93 | :findBaseDir 94 | IF EXIST "%WDIR%"\.mvn goto baseDirFound 95 | cd .. 96 | IF "%WDIR%"=="%CD%" goto baseDirNotFound 97 | set WDIR=%CD% 98 | goto findBaseDir 99 | 100 | :baseDirFound 101 | set MAVEN_PROJECTBASEDIR=%WDIR% 102 | cd "%EXEC_DIR%" 103 | goto endDetectBaseDir 104 | 105 | :baseDirNotFound 106 | set MAVEN_PROJECTBASEDIR=%EXEC_DIR% 107 | cd "%EXEC_DIR%" 108 | 109 | :endDetectBaseDir 110 | 111 | IF NOT EXIST "%MAVEN_PROJECTBASEDIR%\.mvn\jvm.config" goto endReadAdditionalConfig 112 | 113 | @setlocal EnableExtensions EnableDelayedExpansion 114 | for /F "usebackq delims=" %%a in ("%MAVEN_PROJECTBASEDIR%\.mvn\jvm.config") do set JVM_CONFIG_MAVEN_PROPS=!JVM_CONFIG_MAVEN_PROPS! %%a 115 | @endlocal & set JVM_CONFIG_MAVEN_PROPS=%JVM_CONFIG_MAVEN_PROPS% 116 | 117 | :endReadAdditionalConfig 118 | 119 | SET MAVEN_JAVA_EXE="%JAVA_HOME%\bin\java.exe" 120 | set WRAPPER_JAR="%MAVEN_PROJECTBASEDIR%\.mvn\wrapper\maven-wrapper.jar" 121 | set WRAPPER_LAUNCHER=org.apache.maven.wrapper.MavenWrapperMain 122 | 123 | set DOWNLOAD_URL="https://repo.maven.apache.org/maven2/org/apache/maven/wrapper/maven-wrapper/3.1.0/maven-wrapper-3.1.0.jar" 124 | 125 | FOR /F "usebackq tokens=1,2 delims==" %%A IN ("%MAVEN_PROJECTBASEDIR%\.mvn\wrapper\maven-wrapper.properties") DO ( 126 | IF "%%A"=="wrapperUrl" SET DOWNLOAD_URL=%%B 127 | ) 128 | 129 | @REM Extension to allow automatically downloading the maven-wrapper.jar from Maven-central 130 | @REM This allows using the maven wrapper in projects that prohibit checking in binary data. 131 | if exist %WRAPPER_JAR% ( 132 | if "%MVNW_VERBOSE%" == "true" ( 133 | echo Found %WRAPPER_JAR% 134 | ) 135 | ) else ( 136 | if not "%MVNW_REPOURL%" == "" ( 137 | SET DOWNLOAD_URL="%MVNW_REPOURL%/org/apache/maven/wrapper/maven-wrapper/3.1.0/maven-wrapper-3.1.0.jar" 138 | ) 139 | if "%MVNW_VERBOSE%" == "true" ( 140 | echo Couldn't find %WRAPPER_JAR%, downloading it ... 141 | echo Downloading from: %DOWNLOAD_URL% 142 | ) 143 | 144 | powershell -Command "&{"^ 145 | "$webclient = new-object System.Net.WebClient;"^ 146 | "if (-not ([string]::IsNullOrEmpty('%MVNW_USERNAME%') -and [string]::IsNullOrEmpty('%MVNW_PASSWORD%'))) {"^ 147 | "$webclient.Credentials = new-object System.Net.NetworkCredential('%MVNW_USERNAME%', '%MVNW_PASSWORD%');"^ 148 | "}"^ 149 | "[Net.ServicePointManager]::SecurityProtocol = [Net.SecurityProtocolType]::Tls12; $webclient.DownloadFile('%DOWNLOAD_URL%', '%WRAPPER_JAR%')"^ 150 | "}" 151 | if "%MVNW_VERBOSE%" == "true" ( 152 | echo Finished downloading %WRAPPER_JAR% 153 | ) 154 | ) 155 | @REM End of extension 156 | 157 | @REM Provide a "standardized" way to retrieve the CLI args that will 158 | @REM work with both Windows and non-Windows executions. 159 | set MAVEN_CMD_LINE_ARGS=%* 160 | 161 | %MAVEN_JAVA_EXE% ^ 162 | %JVM_CONFIG_MAVEN_PROPS% ^ 163 | %MAVEN_OPTS% ^ 164 | %MAVEN_DEBUG_OPTS% ^ 165 | -classpath %WRAPPER_JAR% ^ 166 | "-Dmaven.multiModuleProjectDirectory=%MAVEN_PROJECTBASEDIR%" ^ 167 | %WRAPPER_LAUNCHER% %MAVEN_CONFIG% %* 168 | if ERRORLEVEL 1 goto error 169 | goto end 170 | 171 | :error 172 | set ERROR_CODE=1 173 | 174 | :end 175 | @endlocal & set ERROR_CODE=%ERROR_CODE% 176 | 177 | if not "%MAVEN_SKIP_RC%"=="" goto skipRcPost 178 | @REM check for post script, once with legacy .bat ending and once with .cmd ending 179 | if exist "%USERPROFILE%\mavenrc_post.bat" call "%USERPROFILE%\mavenrc_post.bat" 180 | if exist "%USERPROFILE%\mavenrc_post.cmd" call "%USERPROFILE%\mavenrc_post.cmd" 181 | :skipRcPost 182 | 183 | @REM pause the script if MAVEN_BATCH_PAUSE is set to 'on' 184 | if "%MAVEN_BATCH_PAUSE%"=="on" pause 185 | 186 | if "%MAVEN_TERMINATE_CMD%"=="on" exit %ERROR_CODE% 187 | 188 | cmd /C exit /B %ERROR_CODE% 189 | -------------------------------------------------------------------------------- /pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 4 | 5 | 4.0.0 6 | 7 | io.openliberty.samples 8 | io.openliberty.sample.getting.started 9 | 1.0-SNAPSHOT 10 | war 11 | 12 | 13 | 14 | UTF-8 15 | UTF-8 16 | 11 17 | 11 18 | 19 | 3.7.1 20 | 3.0.0 21 | 3.0.0 22 | 23 | 9080 24 | 9443 25 | / 26 | 27 | 28 | 29 | 30 | 31 | org.eclipse.microprofile 32 | microprofile 33 | 6.0 34 | pom 35 | provided 36 | 37 | 38 | 39 | org.junit.jupiter 40 | junit-jupiter-engine 41 | 5.9.2 42 | test 43 | 44 | 45 | org.jboss.resteasy 46 | resteasy-client 47 | 6.2.12.Final 48 | test 49 | 50 | 51 | org.jboss.resteasy 52 | resteasy-json-binding-provider 53 | 6.2.12.Final 54 | test 55 | 56 | 57 | org.glassfish 58 | jakarta.json 59 | 2.0.1 60 | test 61 | 62 | 63 | 64 | jakarta.xml.bind 65 | jakarta.xml.bind-api 66 | 4.0.0 67 | test 68 | 69 | 70 | 71 | 72 | ${project.artifactId} 73 | 74 | 75 | 76 | io.openliberty.tools 77 | liberty-maven-plugin 78 | ${version.liberty-maven-plugin} 79 | 80 | sampleAppServer 81 | 82 | 83 | 84 | 85 | org.apache.maven.plugins 86 | maven-failsafe-plugin 87 | ${version.maven-failsafe-plugin} 88 | 89 | ${project.basedir}/src/main/resources 90 | 91 | ${liberty.var.default.http.port} 92 | ${liberty.var.default.https.port} 93 | ${liberty.var.app.context.root} 94 | 95 | 96 | **/*IT.java 97 | 98 | 99 | 100 | 101 | org.apache.maven.plugins 102 | maven-war-plugin 103 | 3.4.0 104 | 105 | 106 | 107 | -------------------------------------------------------------------------------- /scripts/build-app.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | ######################################################################################### 4 | # 5 | # Script to build the multi arch images for sample app 6 | # 7 | ######################################################################################### 8 | 9 | set -Eeo pipefail 10 | 11 | readonly usage="Usage: $0 --image " 12 | 13 | main() { 14 | parse_args "$@" 15 | check_args 16 | 17 | # Define current arch variable 18 | case "$(uname -p)" in 19 | "ppc64le") 20 | readonly arch="ppc64le" 21 | ;; 22 | "s390x") 23 | readonly arch="s390x" 24 | ;; 25 | *) 26 | readonly arch="amd64" 27 | ;; 28 | esac 29 | 30 | # Package and download base image 31 | mvn clean package 32 | docker pull icr.io/appcafe/open-liberty:kernel-slim-java11-openj9-ubi 33 | 34 | # Build and push the app image 35 | ARCH_IMAGE="${IMAGE}-${arch}" 36 | echo "****** Building image: ${ARCH_IMAGE}" 37 | docker build -t "${ARCH_IMAGE}" . 38 | if [ "$?" != "0" ]; then 39 | echo "Error building app image: ${ARCH_IMAGE}" 40 | exit 1 41 | fi 42 | 43 | echo "****** Pushing image: ${ARCH_IMAGE}" 44 | docker push "${ARCH_IMAGE}" 45 | if [ "$?" != "0" ]; then 46 | echo "Error pushing app image: ${ARCH_IMAGE}" 47 | exit 1 48 | fi 49 | } 50 | 51 | check_args() { 52 | if [[ -z "${IMAGE}" ]]; then 53 | echo "****** Missing target image for app build, see usage" 54 | echo "${usage}" 55 | exit 1 56 | fi 57 | } 58 | 59 | parse_args() { 60 | while [ $# -gt 0 ]; do 61 | case "$1" in 62 | --image) 63 | shift 64 | readonly IMAGE="${1}" 65 | ;; 66 | *) 67 | echo "Error: Invalid argument - $1" 68 | echo "$usage" 69 | exit 1 70 | ;; 71 | esac 72 | shift 73 | done 74 | } 75 | 76 | main "$@" -------------------------------------------------------------------------------- /scripts/build-manifest.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | ######################################################################################### 4 | # 5 | # Script to build manifest list for sample app 6 | # 7 | ######################################################################################### 8 | 9 | set -Eeo pipefail 10 | 11 | readonly usage="Usage: $0 --image " 12 | readonly script_dir="$(dirname "$0")" 13 | 14 | main() { 15 | parse_args "$@" 16 | check_args 17 | 18 | build_manifest "${IMAGE}" 19 | } 20 | 21 | build_manifest() { 22 | local target=$1 23 | export DOCKER_CLI_EXPERIMENTAL=enabled 24 | 25 | echo "Creating manifest list with $target-amd64" 26 | docker manifest create "$target" "$target-amd64" 27 | if [ "$?" != "0" ]; then 28 | echo "Error creating manifest list with $target-amd64" 29 | exit 1 30 | fi 31 | docker manifest annotate "$target" "$target-amd64" --os linux --arch amd64 32 | if [ "$?" != "0" ]; then 33 | echo "Error adding annotations for $target-amd64 to manifest list" 34 | exit 1 35 | fi 36 | 37 | if [[ "$arch" == "ZXP" ]]; then 38 | echo "Adding $target-s390x to manifest list" 39 | docker manifest create --amend "$target" "$target-s390x" 40 | if [ "$?" != "0" ]; then 41 | echo "Error adding $target-s390x to manifest list" 42 | exit 1 43 | fi 44 | docker manifest annotate "$target" "$target-s390x" --os linux --arch s390x 45 | if [ "$?" != "0" ]; then 46 | echo "Error adding annotations for $target-s390x to manifest list" 47 | exit 1 48 | fi 49 | 50 | echo "Adding $target-ppc64le to manifest list" 51 | docker manifest create --amend "$target" "$target-ppc64le" 52 | if [ "$?" != "0" ]; then 53 | echo "Error adding $target-ppc64le to manifest list" 54 | exit 1 55 | fi 56 | docker manifest annotate "$target" "$target-ppc64le" --os linux --arch ppc64le 57 | if [ "$?" != "0" ]; then 58 | echo "Error adding annotations for $target-ppc64le to manifest list" 59 | exit 1 60 | fi 61 | fi 62 | 63 | docker manifest inspect "$target" 64 | docker manifest push "$target" --purge 65 | if [ "$?" = "0" ]; then 66 | echo "Successfully pushed $target" 67 | else 68 | echo "Error pushing $target" 69 | exit 1 70 | fi 71 | } 72 | 73 | check_args() { 74 | if [[ -z "${IMAGE}" ]]; then 75 | echo "****** Missing target image for manifest lists, see usage" 76 | echo "${usage}" 77 | exit 1 78 | fi 79 | } 80 | 81 | parse_args() { 82 | while [ $# -gt 0 ]; do 83 | case "$1" in 84 | --image) 85 | shift 86 | readonly IMAGE="${1}" 87 | ;; 88 | *) 89 | echo "Error: Invalid argument - $1" 90 | echo "$usage" 91 | exit 1 92 | ;; 93 | esac 94 | shift 95 | done 96 | } 97 | 98 | main "$@" -------------------------------------------------------------------------------- /scripts/pipeline/await-ciorchestrator.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | function main() { 4 | parse_arguments "$@" 5 | await_ciorchestrator 6 | } 7 | 8 | function print_usage() { 9 | script_name=`basename ${0}` 10 | echo "Usage: ${script_name} [OPTIONS]" 11 | echo "" 12 | echo "Await Completion of CI Orchestrator job" 13 | echo "" 14 | echo "Options:" 15 | echo " -u, --user string IntranetId to use to authenticate to CI Orchestrator" 16 | echo " --password string Intranet Password to use to authenticate to CI Orchestrator" 17 | echo " --pipelineId string pipelineId of the request that should be awaited" 18 | echo " -h, --help Print usage information" 19 | echo "" 20 | } 21 | 22 | 23 | function parse_arguments() { 24 | if [[ "$#" == 0 ]]; then 25 | print_usage 26 | exit 1 27 | fi 28 | 29 | # process options 30 | while [[ "$1" != "" ]]; do 31 | case "$1" in 32 | -u | --user) 33 | shift 34 | USER=$1 35 | ;; 36 | --password) 37 | shift 38 | PASSWORD=$1 39 | ;; 40 | --pipelineId) 41 | shift 42 | pipelineId=$1 43 | ;; 44 | -h | --help) 45 | print_usage 46 | exit 1 47 | ;; 48 | esac 49 | shift 50 | done 51 | } 52 | 53 | function await_ciorchestrator() { 54 | echo "Checking Pipeline Request in CI Orchestrator as ${USER}, pipelineId: ${pipelineId}" 55 | 56 | cat >ciorchestrator-query.json </dev/null 78 | rc=$? 79 | if [ $rc -eq 0 ]; then 80 | echo "CIOrchestrator Pipeline finished" 81 | cat ciorchestrator-query-output.csv | grep -E "OK" >/dev/null 82 | ok=$? 83 | echo "Exiting $ok" 84 | exit $ok 85 | else 86 | sleep 1m 87 | fi 88 | done 89 | } 90 | 91 | function check_request(){ 92 | curl -s -X POST \ 93 | --insecure \ 94 | -H "Content-Type: application/json" \ 95 | -d @ciorchestrator-query.json \ 96 | -u "${USER}:${PASSWORD}" \ 97 | -o ciorchestrator-query-output.csv \ 98 | https://libh-proxy1.fyre.ibm.com/ci-pipeline-work-views-stateStore/query 99 | 100 | cat ciorchestrator-query-output.csv 101 | 102 | } 103 | 104 | 105 | # --- Run --- 106 | 107 | main $* -------------------------------------------------------------------------------- /scripts/pipeline/check-build.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | ######################################################################################### 4 | # 5 | # Script to check the image for sample app 6 | # 7 | ######################################################################################### 8 | 9 | set -Eeo pipefail 10 | 11 | readonly usage="Usage: $0 --image " 12 | 13 | main() { 14 | parse_args "$@" 15 | check_args 16 | 17 | docker pull $IMAGE 18 | docker images 19 | 20 | docker run -d --name getting-started-sample -p 9080:9080 $IMAGE 21 | docker ps 22 | 23 | # Wait for starter planet 24 | maxWait=30 25 | count=0 26 | while [ "$count" != "$maxWait" ] && ! docker logs getting-started-sample | grep -q "CWWKF0011I"; 27 | do 28 | count=$(( $count + 1 )) 29 | echo "Waiting for CWWKF0011I (Smarter Planet msg) in log. $count / $maxWait seconds." 30 | sleep 1 31 | done 32 | 33 | if [[ "$count" == "$maxWait" ]]; then 34 | echo "Did not find CWWKF0011I (Smarter Planet msg) in log within $maxWait seconds." 35 | exit 1; 36 | fi 37 | 38 | docker logs getting-started-sample | grep "^Launching" 39 | 40 | # Test the endpoints for 200 response code 41 | curl -f -s -I "0.0.0.0:9080" &>/dev/null && echo "OK: Landing page did return 200" || { echo 'FAIL: Sample App landing page did not return 200' ; exit 1; } 42 | curl -f -s "0.0.0.0:9080" | grep -q 'Open Liberty - Getting Started Sample' && echo "OK: Sample App landing page contained 'Open Liberty - Getting Started Sample'" || { echo 'FAIL: Did not find "Open Liberty - Getting Started Sample" in response' ; exit 1; } 43 | curl -f -s -I "0.0.0.0:9080/system/properties" &>/dev/null && echo "OK: /system/properties did return 200" || { echo 'FAIL: /system/properties did not return 200' ; exit 1; } 44 | curl -f -s -I "0.0.0.0:9080/system/config" &>/dev/null && echo "OK: /system/config did return 200" || { echo 'FAIL: /system/config did not return 200' ; exit 1; } 45 | curl -f -s -I "0.0.0.0:9080/system/runtime" &>/dev/null && echo "OK: /system/runtime did return 200" || { echo 'FAIL: /system/runtime did not return 200' ; exit 1; } 46 | curl -f -s -I "0.0.0.0:9080/health" &>/dev/null && echo "OK: /health did return 200" || { echo 'FAIL: /health did not return 200' ; exit 1; } 47 | curl -f -s "0.0.0.0:9080/metrics" &>/dev/null && echo "OK: /metrics did return 200" || { echo 'FAIL: /metrics did not return 200' ; exit 1; } 48 | } 49 | 50 | check_args() { 51 | if [[ -z "${IMAGE}" ]]; then 52 | echo "****** Missing target image for app image check, see usage" 53 | echo "${usage}" 54 | exit 1 55 | fi 56 | } 57 | 58 | parse_args() { 59 | while [ $# -gt 0 ]; do 60 | case "$1" in 61 | --image) 62 | shift 63 | readonly IMAGE="${1}" 64 | ;; 65 | *) 66 | echo "Error: Invalid argument - $1" 67 | echo "$usage" 68 | exit 1 69 | ;; 70 | esac 71 | shift 72 | done 73 | } 74 | 75 | main "$@" -------------------------------------------------------------------------------- /scripts/pipeline/ci_to_secure_pipeline_scan.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | echo "Connecting to the Security Scan Toolchain" 4 | 5 | # IMAGES_TO_SCAN is delimited by "\n" 6 | IMAGES_TO_SCAN="" 7 | if which list_artifacts >/dev/null; then 8 | for ARTIFACT_IMAGE in $(list_artifacts); do 9 | IMAGE_NAME="$(load_artifact "$ARTIFACT_IMAGE" "name" 2>/dev/null)" 10 | IMAGE_TYPE="$(load_artifact "$ARTIFACT_IMAGE" "type" 2>/dev/null)" 11 | 12 | if [[ -z "${IMAGE_NAME}" || "$(echo "$IMAGE_TYPE" | tr '[:upper:]' '[:lower:]')" != "image" ]]; then 13 | continue 14 | else 15 | IMAGES_TO_SCAN+="$IMAGE_NAME" 16 | IMAGES_TO_SCAN+=$"\n" 17 | fi 18 | done 19 | fi 20 | 21 | echo -e "IMAGES_TO_SCAN:\n$IMAGES_TO_SCAN" 22 | 23 | # This must be an IBM Cloud API key that has permission to run the toolchain 24 | IBMCLOUD_API_KEY="$(get_env ibmcloud-api-key)" # pragma: allowlist secret 25 | 26 | # The IBM Cloud region that is hosting the security scanning pipeline 27 | SECSCAN_TOOLCHAIN_REGION=$(get_env sescan-toolchain-region) 28 | if [[ -z "${SECSCAN_TOOLCHAIN_REGION}" ]]; then 29 | SECSCAN_TOOLCHAIN_REGION="us-south" 30 | fi 31 | 32 | # Ensure ibmcloud is updated before logging in 33 | ibmcloud --version 34 | ibmcloud update -f 35 | ibmcloud login --apikey "$IBMCLOUD_API_KEY" -r "$SECSCAN_TOOLCHAIN_REGION" -a "https://cloud.ibm.com" 36 | 37 | SCANNING_PIPELINE_ID=$(get_env security-scanning-pipeline-id) 38 | 39 | TRIGGER_NAME=$(get_env security-scanning-pipeline-trigger) 40 | if [[ -z "${TRIGGER_NAME}" ]]; then 41 | TRIGGER_NAME="Security Scan Manual Trigger Multiscan" 42 | fi 43 | 44 | #AGGREGATE_IMAGE_SCAN_ISSUES=(get_env aggregate-image-scan-issues) 45 | #if [[ -z "${AGGREGATE_IMAGE_SCAN_ISSUES}" ]]; then 46 | AGGREGATE_IMAGE_SCAN_ISSUES="squad" 47 | #fi 48 | 49 | EVIDENCE_REPO=$(get_env evidence-repo) 50 | INCIDENT_REPO=$(get_env incident-repo) 51 | if [[ -z $EVIDENCE_REPO || -z $INCIDENT_REPO ]]; then 52 | TRIGGER_PROPERTIES_JSON="{\"images-to-scan\": \"$(echo ${IMAGES_TO_SCAN})\"}" 53 | else 54 | TRIGGER_PROPERTIES_JSON="{ 55 | \"aggregate-image-scan-issues\": \"$(echo ${AGGREGATE_IMAGE_SCAN_ISSUES})\", 56 | \"images-to-scan\": \"$(echo ${IMAGES_TO_SCAN})\", 57 | \"evidence-repo\": \"${EVIDENCE_REPO}\", 58 | \"incident-repo\": \"${INCIDENT_REPO}\" 59 | }" 60 | fi 61 | 62 | echo "RUN_DATA=(ibmcloud dev tekton-trigger "$SCANNING_PIPELINE_ID" --trigger-name "$TRIGGER_NAME" --trigger-properties "$TRIGGER_PROPERTIES_JSON" --output json)" 63 | RUN_DATA=$(ibmcloud dev tekton-trigger "$SCANNING_PIPELINE_ID" --trigger-name "$TRIGGER_NAME" --trigger-properties "$TRIGGER_PROPERTIES_JSON" --output json) 64 | 65 | RUN_ID=$(echo $RUN_DATA | jq -r '.id') 66 | echo "Security Scanning Pipeline Run ID=$RUN_ID" 67 | 68 | MAX_TRIES=600 69 | COMPLETE=0 70 | for (( TRIES=0; TRIES<=$MAX_TRIES; TRIES++ )) 71 | do 72 | RESULT=$(ibmcloud dev tekton-pipelinerun $SCANNING_PIPELINE_ID --run-id ${RUN_ID} --output json | jq -r '.status.state') 73 | if [[ $RESULT != "passed" && $RESULT != "failed" && $RESULT != "cancelled" && $RESULT != "succeeded" ]];then 74 | sleep 10 75 | else 76 | COMPLETE=1 77 | break 78 | fi 79 | done 80 | echo "Security Scanning Pipeline returned $RESULT" 81 | echo "Security Scanning Pipeline URL: https://cloud.ibm.com/devops/pipelines/tekton/${SCANNING_PIPELINE_ID}/runs/${RUN_ID}/build-scan-artifact/run-stage?env_id=ibm:yp:us-south" 82 | 83 | # TODO: Add code to fail the pipeline run if the Security Scanning Pipeline returns "failed" 84 | -------------------------------------------------------------------------------- /scripts/pipeline/request-ciorchestrator.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | GH_API_ROOT="https://api.github.com" 4 | GH_BRANCH="main" 5 | GH_REPOSITORY="sample-getting-started" 6 | GH_ORG="OpenLiberty" 7 | CI_TRIGGER="lgsdocker" 8 | CI_CONFIG_FILE=".ci-orchestrator/sample-liberty-build.yml" 9 | pipelineName="Liberty Getting Started Build" 10 | command="make build-app-pipeline" 11 | 12 | 13 | function main() { 14 | parse_arguments "$@" 15 | request_ciorchestrator 16 | } 17 | 18 | function print_usage() { 19 | script_name=`basename ${0}` 20 | echo "Usage: ${script_name} [OPTIONS]" 21 | echo "" 22 | echo "Kick off of CI Orchestrator job" 23 | echo "" 24 | echo "Options:" 25 | echo " -u, --user string IntranetId to use to authenticate to CI Orchestrator" 26 | echo " --password string Intranet Password to use to authenticate to CI Orchestrator" 27 | echo " -b, --branch string Github Repository branch" 28 | echo " -r, --repository string GitHub Repository to use" 29 | echo " --org string Github Organisation containing repository" 30 | echo " --trigger string Name of trigger within CI Orchestrator config file" 31 | echo " --configFile string Location of CI Orchestrator config file" 32 | echo " --command string Command to execute on remote machine" 33 | echo " -h, --help Print usage information" 34 | echo "" 35 | } 36 | 37 | 38 | function parse_arguments() { 39 | if [[ "$#" == 0 ]]; then 40 | print_usage 41 | exit 1 42 | fi 43 | 44 | # process options 45 | while [[ "$1" != "" ]]; do 46 | case "$1" in 47 | -u | --user) 48 | shift 49 | USER=$1 50 | ;; 51 | --password) 52 | shift 53 | PASSWORD=$1 54 | ;; 55 | -b | --branch) 56 | shift 57 | GH_BRANCH=$1 58 | ;; 59 | -r | --repository) 60 | shift 61 | GH_REPOSITORY=$1 62 | ;; 63 | --org) 64 | shift 65 | GH_ORG=$1 66 | ;; 67 | --trigger) 68 | shift 69 | CI_TRIGGER=$1 70 | ;; 71 | --configFile) 72 | shift 73 | CI_CONFIG_FILE=$1 74 | ;; 75 | --command) 76 | shift 77 | COMMAND=$1 78 | ;; 79 | -h | --help) 80 | print_usage 81 | exit 1 82 | ;; 83 | esac 84 | shift 85 | done 86 | } 87 | 88 | 89 | function request_ciorchestrator() { 90 | pipelineId=OnePipeline_${PIPELINE_RUN_ID}_${RANDOM} 91 | cat >ciorchestrator-submit.json <ciorchestrator-submit.id 116 | # add retry logic for Fyre networking issues 117 | echo "Sending Pipeline Request to CI Orchestrator pipelineId: ${pipelineId} as ${USER}" 118 | echo "command to run: $COMMAND" 119 | count=0 120 | tryAgain=true 121 | while $tryAgain; do 122 | curl --fail --insecure -v -X POST \ 123 | -H "Content-Type: application/json" \ 124 | -d @ciorchestrator-submit.json \ 125 | -u "${USER}:${PASSWORD}" \ 126 | https://libh-proxy1.fyre.ibm.com/eventPublish/rawCIData/${pipelineId} 127 | rc=$? 128 | if [[ $rc -eq 0 ]]; then 129 | echo "Successfully sent CI orchestrator Request" 130 | tryAgain=false 131 | elif [[ $count -gt 600 ]]; then 132 | #Bail after 10 mins 133 | echo "Problem sending CI orchestrator Request after 10 mins of trying, giving up. Curl returned $rc" 134 | exit 1; 135 | else 136 | sleep 10 137 | count=$((count+10)) 138 | fi 139 | done 140 | } 141 | 142 | 143 | # --- Run --- 144 | 145 | main "$@" -------------------------------------------------------------------------------- /src/main/java/io/openliberty/sample/SampleApplication.java: -------------------------------------------------------------------------------- 1 | /******************************************************************************* 2 | * Copyright (c) 2017 IBM Corporation and others. 3 | * All rights reserved. This program and the accompanying materials 4 | * are made available under the terms of the Eclipse Public License v1.0 5 | * which accompanies this distribution, and is available at 6 | * http://www.eclipse.org/legal/epl-v10.html 7 | * 8 | * Contributors: 9 | * IBM Corporation - Initial implementation 10 | *******************************************************************************/ 11 | 12 | package io.openliberty.sample; 13 | 14 | import jakarta.ws.rs.ApplicationPath; 15 | import jakarta.ws.rs.core.Application; 16 | 17 | @ApplicationPath("system") 18 | public class SampleApplication extends Application { 19 | } 20 | -------------------------------------------------------------------------------- /src/main/java/io/openliberty/sample/config/ConfigResource.java: -------------------------------------------------------------------------------- 1 | /******************************************************************************* 2 | * Copyright (c) 2017 IBM Corporation and others. 3 | * All rights reserved. This program and the accompanying materials 4 | * are made available under the terms of the Eclipse Public License v1.0 5 | * which accompanies this distribution, and is available at 6 | * http://www.eclipse.org/legal/epl-v10.html 7 | * 8 | * Contributors: 9 | * IBM Corporation - Initial implementation 10 | *******************************************************************************/ 11 | 12 | package io.openliberty.sample.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("/config") 30 | public class ConfigResource { 31 | 32 | @Inject 33 | private Config config; 34 | 35 | @GET 36 | @Produces(MediaType.APPLICATION_JSON) 37 | public JsonObject getAllConfig() { 38 | JsonObjectBuilder builder = Json.createObjectBuilder(); 39 | return builder.add("ConfigSources", sourceJsonBuilder()) 40 | .add("ConfigProperties", propertyJsonBuilder()).build(); 41 | } 42 | 43 | public JsonObject sourceJsonBuilder() { 44 | JsonObjectBuilder sourcesBuilder = Json.createObjectBuilder(); 45 | for (ConfigSource source : config.getConfigSources()) { 46 | sourcesBuilder.add(source.getName(), source.getOrdinal()); 47 | } 48 | return sourcesBuilder.build(); 49 | } 50 | 51 | public JsonObject propertyJsonBuilder() { 52 | JsonObjectBuilder propertiesBuilder = Json.createObjectBuilder(); 53 | for (String name : config.getPropertyNames()) { 54 | if (name.contains("io_openliberty_sample")) { 55 | propertiesBuilder.add(name, config.getValue(name, String.class)); 56 | } 57 | } 58 | return propertiesBuilder.build(); 59 | } 60 | 61 | } 62 | -------------------------------------------------------------------------------- /src/main/java/io/openliberty/sample/config/CustomConfigSource.java: -------------------------------------------------------------------------------- 1 | /******************************************************************************* 2 | * Copyright (c) 2017 IBM Corporation and others. 3 | * All rights reserved. This program and the accompanying materials 4 | * are made available under the terms of the Eclipse Public License v1.0 5 | * which accompanies this distribution, and is available at 6 | * http://www.eclipse.org/legal/epl-v10.html 7 | * 8 | * Contributors: 9 | * IBM Corporation - Initial implementation 10 | *******************************************************************************/ 11 | 12 | package io.openliberty.sample.config; 13 | 14 | import jakarta.json.stream.JsonParser; 15 | import jakarta.json.stream.JsonParser.Event; 16 | import jakarta.json.Json; 17 | import java.math.BigDecimal; 18 | import java.util.*; 19 | import java.io.StringReader; 20 | 21 | import java.io.BufferedReader; 22 | import java.io.InputStream; 23 | import java.io.InputStreamReader; 24 | 25 | import org.eclipse.microprofile.config.spi.ConfigSource; 26 | 27 | public class CustomConfigSource implements ConfigSource { 28 | 29 | String fileLocation = "META-INF/CustomConfigSource.json"; 30 | 31 | @Override 32 | public int getOrdinal() { 33 | return Integer.parseInt(getProperties().get("config_ordinal")); 34 | } 35 | 36 | @Override 37 | public Set getPropertyNames() { 38 | return getProperties().keySet(); 39 | } 40 | 41 | @Override 42 | public String getValue(String key) { 43 | return getProperties().get(key); 44 | } 45 | 46 | @Override 47 | public String getName() { 48 | return "Custom Config Source: file:" + this.fileLocation; 49 | } 50 | 51 | public Map getProperties() { 52 | Map m = new HashMap(); 53 | String jsonData = this.readFile(this.fileLocation); 54 | JsonParser parser = Json.createParser(new StringReader(jsonData)); 55 | String key = null; 56 | while (parser.hasNext()) { 57 | final Event event = parser.next(); 58 | switch (event) { 59 | case KEY_NAME: 60 | key = parser.getString(); 61 | break; 62 | case VALUE_STRING: 63 | String string = parser.getString(); 64 | m.put(key, string); 65 | break; 66 | case VALUE_NUMBER: 67 | BigDecimal number = parser.getBigDecimal(); 68 | m.put(key, number.toString()); 69 | break; 70 | case VALUE_TRUE: 71 | m.put(key, "true"); 72 | break; 73 | case VALUE_FALSE: 74 | m.put(key, "false"); 75 | break; 76 | default: 77 | break; 78 | } 79 | } 80 | parser.close(); 81 | return m; 82 | } 83 | 84 | public String readFile(String fileName) { 85 | String result = ""; 86 | try { 87 | InputStream is = this.getClass().getClassLoader().getResourceAsStream(fileName); 88 | BufferedReader br = new BufferedReader(new InputStreamReader(is, "UTF-8")); 89 | StringBuilder sb = new StringBuilder(); 90 | String line = br.readLine(); 91 | while (line != null) { 92 | sb.append(line); 93 | line = br.readLine(); 94 | } 95 | result = sb.toString(); 96 | br.close(); 97 | } catch (Exception e) { 98 | e.printStackTrace(); 99 | } 100 | return result; 101 | } 102 | } 103 | -------------------------------------------------------------------------------- /src/main/java/io/openliberty/sample/system/SystemConfig.java: -------------------------------------------------------------------------------- 1 | /******************************************************************************* 2 | * Copyright (c) 2017, 2020 IBM Corporation and others. 3 | * All rights reserved. This program and the accompanying materials 4 | * are made available under the terms of the Eclipse Public License v1.0 5 | * which accompanies this distribution, and is available at 6 | * http://www.eclipse.org/legal/epl-v10.html 7 | * 8 | * Contributors: 9 | * IBM Corporation - Initial implementation 10 | *******************************************************************************/ 11 | 12 | package io.openliberty.sample.system; 13 | 14 | import jakarta.enterprise.context.ApplicationScoped; 15 | import jakarta.inject.Inject; 16 | import jakarta.inject.Provider; 17 | 18 | import org.eclipse.microprofile.config.inject.ConfigProperty; 19 | 20 | @ApplicationScoped 21 | public class SystemConfig { 22 | 23 | @Inject 24 | @ConfigProperty(name = "io_openliberty_sample_system_inMaintenance") 25 | Provider inMaintenance; 26 | 27 | 28 | public boolean isInMaintenance() { 29 | return inMaintenance.get(); 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /src/main/java/io/openliberty/sample/system/SystemHealth.java: -------------------------------------------------------------------------------- 1 | /******************************************************************************* 2 | * Copyright (c) 2018, 2020 IBM Corporation and others. 3 | * All rights reserved. This program and the accompanying materials 4 | * are made available under the terms of the Eclipse Public License v1.0 5 | * which accompanies this distribution, and is available at 6 | * http://www.eclipse.org/legal/epl-v10.html 7 | * 8 | * Contributors: 9 | * IBM Corporation - Initial implementation 10 | *******************************************************************************/ 11 | package io.openliberty.sample.system; 12 | 13 | import jakarta.enterprise.context.ApplicationScoped; 14 | import jakarta.inject.Inject; 15 | 16 | import org.eclipse.microprofile.health.HealthCheck; 17 | import org.eclipse.microprofile.health.HealthCheckResponse; 18 | import org.eclipse.microprofile.health.Readiness; 19 | 20 | @Readiness 21 | @ApplicationScoped 22 | public class SystemHealth implements HealthCheck { 23 | 24 | @Inject 25 | SystemConfig systemConfig; 26 | 27 | public boolean isHealthy() { 28 | if (systemConfig.isInMaintenance()) { 29 | return false; 30 | } 31 | return true; 32 | } 33 | 34 | @Override 35 | public HealthCheckResponse call() { 36 | if (!isHealthy()) { 37 | return HealthCheckResponse.named(SystemResource.class.getSimpleName()) 38 | .withData("services","not available").down().build(); 39 | } 40 | return HealthCheckResponse.named(SystemResource.class.getSimpleName()) 41 | .withData("services","available").up().build(); 42 | } 43 | } 44 | -------------------------------------------------------------------------------- /src/main/java/io/openliberty/sample/system/SystemResource.java: -------------------------------------------------------------------------------- 1 | /******************************************************************************* 2 | * Copyright (c) 2017, 2020 IBM Corporation and others. 3 | * All rights reserved. This program and the accompanying materials 4 | * are made available under the terms of the Eclipse Public License v1.0 5 | * which accompanies this distribution, and is available at 6 | * http://www.eclipse.org/legal/epl-v10.html 7 | * 8 | * Contributors: 9 | * IBM Corporation - Initial implementation 10 | *******************************************************************************/ 11 | 12 | package io.openliberty.sample.system; 13 | 14 | import jakarta.enterprise.context.RequestScoped; 15 | import jakarta.inject.Inject; 16 | 17 | import org.eclipse.microprofile.metrics.annotation.Counted; 18 | import org.eclipse.microprofile.metrics.annotation.Timed; 19 | 20 | import jakarta.ws.rs.GET; 21 | import jakarta.ws.rs.core.Response; 22 | import jakarta.ws.rs.core.MediaType; 23 | import jakarta.ws.rs.Path; 24 | import jakarta.ws.rs.Produces; 25 | 26 | @RequestScoped 27 | @Path("/properties") 28 | public class SystemResource { 29 | 30 | @Inject 31 | SystemConfig systemConfig; 32 | 33 | @GET 34 | @Produces(MediaType.APPLICATION_JSON) 35 | @Timed(name = "getPropertiesTime", description = "Time needed to get the properties of a system") 36 | @Counted(absolute = true, description = "Number of times the properties of a systems is requested") 37 | public Response getProperties() { 38 | if (!systemConfig.isInMaintenance()) { 39 | return Response.ok(System.getProperties()).build(); 40 | } else { 41 | return Response.status(Response.Status.SERVICE_UNAVAILABLE).entity("ERROR: Service is currently in maintenance.") 42 | .build(); 43 | } 44 | } 45 | } 46 | -------------------------------------------------------------------------------- /src/main/java/io/openliberty/sample/system/SystemRuntime.java: -------------------------------------------------------------------------------- 1 | /******************************************************************************* 2 | * Copyright (c) 2022 IBM Corporation and others. 3 | * All rights reserved. This program and the accompanying materials 4 | * are made available under the terms of the Eclipse Public License v1.0 5 | * which accompanies this distribution, and is available at 6 | * http://www.eclipse.org/legal/epl-v10.html 7 | * 8 | * Contributors: 9 | * IBM Corporation - Initial implementation 10 | *******************************************************************************/ 11 | 12 | package io.openliberty.sample.system; 13 | 14 | import java.lang.management.ManagementFactory; 15 | 16 | import jakarta.enterprise.context.RequestScoped; 17 | 18 | import jakarta.ws.rs.GET; 19 | import jakarta.ws.rs.core.Response; 20 | import jakarta.ws.rs.core.MediaType; 21 | import jakarta.ws.rs.Path; 22 | import jakarta.ws.rs.Produces; 23 | 24 | import javax.management.ObjectName; 25 | import javax.management.MBeanInfo; 26 | import javax.management.MBeanAttributeInfo; 27 | import javax.management.MBeanServer; 28 | 29 | @RequestScoped 30 | @Path("/runtime") 31 | public class SystemRuntime { 32 | @GET 33 | @Produces(MediaType.TEXT_PLAIN) 34 | public Response getRuntime() { 35 | String libertyVersion = getServerVersion(); 36 | return Response.ok(libertyVersion).build(); 37 | } 38 | 39 | String getServerVersion() { 40 | String version = null; 41 | try { 42 | MBeanServer mbs = ManagementFactory.getPlatformMBeanServer(); 43 | ObjectName objName = new ObjectName("WebSphere:feature=kernel,name=ServerInfo"); 44 | MBeanInfo beanInfo = mbs.getMBeanInfo(objName); 45 | 46 | for (MBeanAttributeInfo attr : beanInfo.getAttributes()) { 47 | if (attr.getName().equals("LibertyVersion")) { 48 | version = String.valueOf(mbs.getAttribute(objName, attr.getName())); 49 | break; 50 | } 51 | } 52 | } catch (Exception ex) { 53 | System.out.println("Unable to retrieve server version."); 54 | } 55 | return version; 56 | } 57 | } 58 | -------------------------------------------------------------------------------- /src/main/liberty/config/server.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | restfulWS-3.1 5 | jsonb-3.0 6 | mpMetrics-5.1 7 | mpHealth-4.0 8 | mpConfig-3.1 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | -------------------------------------------------------------------------------- /src/main/resources/META-INF/CustomConfigSource.json: -------------------------------------------------------------------------------- 1 | {"config_ordinal":550,"io_openliberty_sample_system_inMaintenance":false,"io_openliberty_sample_testConfigOverwrite":"CustomSource"} 2 | -------------------------------------------------------------------------------- /src/main/resources/META-INF/microprofile-config.properties: -------------------------------------------------------------------------------- 1 | config_ordinal=100 2 | io_openliberty_sample_port_number=9080 3 | io_openliberty_sample_system_inMaintenance=false 4 | io_openliberty_sample_testConfigOverwrite=DefaultSource 5 | 6 | -------------------------------------------------------------------------------- /src/main/resources/META-INF/services/org.eclipse.microprofile.config.spi.ConfigSource: -------------------------------------------------------------------------------- 1 | io.openliberty.sample.config.CustomConfigSource -------------------------------------------------------------------------------- /src/main/webapp/WEB-INF/web.xml: -------------------------------------------------------------------------------- 1 | 2 | 5 | Liberty Project 6 | 7 | 8 | index.html 9 | 10 | -------------------------------------------------------------------------------- /src/main/webapp/css/main.css: -------------------------------------------------------------------------------- 1 | /******************************************************************************* 2 | * Copyright (c) 2018, 2022 IBM Corporation and others. 3 | * All rights reserved. This program and the accompanying materials 4 | * are made available under the terms of the Eclipse Public License v1.0 5 | * which accompanies this distribution, and is available at 6 | * http://www.eclipse.org/legal/epl-v10.html 7 | * 8 | * Contributors: 9 | * IBM Corporation - initial API and implementation 10 | *******************************************************************************/ 11 | @import url("https://fonts.googleapis.com/css?family=Asap:300,400,500"); 12 | 13 | @font-face { 14 | font-family: BunueloLight; 15 | src: url("/fonts/BunueloCleanPro-Light.otf"); 16 | } 17 | 18 | @font-face { 19 | font-family: BunueloSemiBold; 20 | src: url("/fonts/BunueloCleanPro-SemiBold.otf"); 21 | } 22 | 23 | body{ 24 | font-family:Asap; 25 | font-size: 16px; 26 | color:#24243b; 27 | background-color: white; 28 | margin: 0px; 29 | } 30 | 31 | section { 32 | padding-top: 55px; 33 | padding-left: 8%; 34 | padding-right: 8%; 35 | /* font-weight: 400; */ 36 | letter-spacing:0; 37 | text-align:left; 38 | } 39 | 40 | .line { 41 | margin-right: 200px; 42 | height: 1px; 43 | background-color: #C8D3D3; 44 | } 45 | 46 | .headerImage { 47 | background-image: url(/img/header_ufo.png); 48 | background-repeat: no-repeat; 49 | background-position: top 20px right 15px; 50 | height: 103px; 51 | margin-top: -94px; 52 | } 53 | 54 | #whereTo { 55 | padding-bottom: 80px; 56 | width: 50%; 57 | } 58 | 59 | p { 60 | line-height: 22px; 61 | margin-top: 0px; 62 | } 63 | h1 { 64 | font-family:BunueloSemiBold; 65 | font-size: 40px; 66 | font-weight: 400; 67 | letter-spacing:0; 68 | text-align:left; 69 | } 70 | h2 { 71 | font-size: 24px; 72 | font-weight: 400; 73 | } 74 | h4 { 75 | margin-top: 52px; 76 | } 77 | a { 78 | text-decoration: none; 79 | } 80 | 81 | #appIntro { 82 | background-image:linear-gradient(#141427 0%, #2c2e50 100%); 83 | background-size: 100% calc(100% - 70px); 84 | background-repeat: no-repeat; 85 | } 86 | 87 | #titleSection { 88 | color: white; 89 | margin-bottom: 80px; 90 | } 91 | 92 | #appTitle { 93 | font-family:BunueloLight; 94 | font-size:55px; 95 | } 96 | 97 | .headerRow { 98 | height: 100px; 99 | position:relative; 100 | z-index:2; 101 | box-shadow: 0 2px 4px 0 rgba(0,0,0,0.50); 102 | } 103 | .headerRow > div { 104 | display: inline-block; 105 | } 106 | 107 | .collapsibleRow { 108 | transition: border 400ms ease-out, box-shadow 200ms linear; 109 | cursor: pointer; 110 | } 111 | .collapsibleRow:hover .headerTitle { 112 | background-color: #f4f4f4; 113 | transition: background-color 0.1s; 114 | } 115 | .collapsed .collapsibleRow { 116 | box-shadow: none; 117 | border-bottom: 4px solid; 118 | } 119 | .collapsed#healthSection > .headerRow { 120 | border-bottom-color: #D6D9E4; 121 | } 122 | .collapsed#configSection > .headerRow { 123 | border-bottom-color: #F8D7C1; 124 | } 125 | .collapsed#metricsSection > .headerRow { 126 | border-bottom-color: #EEF3C3; 127 | } 128 | 129 | .collapsed .collapsibleContent { /* collapsing animation */ 130 | transition: all 400ms ease-out, opacity 300ms ease-in; 131 | } 132 | .expanded .collapsibleContent { /* expanding animation */ 133 | transition: all 400ms ease-out, opacity 450ms ease-out; 134 | } 135 | .collapsed .collapsibleContent { 136 | opacity: 0; 137 | max-height: 0; 138 | visibility: hidden; 139 | } 140 | .expanded .collapsibleContent { 141 | opacity: 1; 142 | max-height: 1000px; 143 | visibility: visible; 144 | } 145 | 146 | .headerIcon { 147 | width: 160px; 148 | height: 100%; 149 | float: left; 150 | background-color: #E8EAEF; 151 | } 152 | .headerIcon img { 153 | display:block; 154 | margin:auto; 155 | margin-top: 20px; 156 | } 157 | 158 | #healthSection .headerIcon { 159 | background-color: #E8EAEF; 160 | } 161 | #configSection .headerIcon { 162 | background-color: #FDE4D1; 163 | } 164 | #metricsSection .headerIcon { 165 | background-color: #F5F8DA; 166 | } 167 | 168 | .headerTitle { 169 | background-color: white; 170 | color:#5d6a8e; 171 | letter-spacing:0; 172 | text-align:left; 173 | padding-left: 40px; 174 | padding-top: 10px; 175 | width: calc(100% - 200px); /* 160 from icon, 40 from padding */ 176 | } 177 | #healthSection h2 { 178 | color: #5D6A8E; 179 | } 180 | #configSection h2 { 181 | color: #E57000; 182 | } 183 | #metricsSection h2 { 184 | color: #4F6700; 185 | } 186 | 187 | #sysPropTitle { 188 | padding-top: 28px; 189 | } 190 | 191 | .headerTitle > h2 { 192 | font-family: BunueloLight; 193 | font-size:40px; 194 | margin: 0; 195 | } 196 | 197 | .caret { 198 | position: absolute; 199 | right: 45px; 200 | top: 45px; 201 | } 202 | 203 | .collapsed#configSection .caret { 204 | background-image: url("../img/carets/caret_down_orange.svg") 205 | } 206 | .expanded#configSection .caret { 207 | background-image: url("../img/carets/caret_up_orange.svg") 208 | } 209 | 210 | .msSection { 211 | background: white; 212 | box-shadow: 0 2px 4px 0 rgba(63,70,89,0.31); 213 | } 214 | 215 | .sectionContent { 216 | margin-left: 160px; 217 | } 218 | 219 | #systemPropertiesTable { 220 | padding-left: 160px; 221 | background: white; 222 | } 223 | 224 | button { 225 | border-radius:100px; 226 | min-height:44px; 227 | color:#24253a; 228 | text-align:center; 229 | font-family: Asap; 230 | margin-top: 25px; 231 | margin-bottom: 25px; 232 | cursor: pointer; 233 | border: none; 234 | } 235 | 236 | button a { 237 | text-decoration: none; 238 | color:#F4914D; 239 | } 240 | 241 | #guidesButton { 242 | background-color:#abd155; 243 | width:269px; 244 | font-weight: 500; 245 | font-size:16px; 246 | transition: background-color .2s; 247 | } 248 | #guidesButton:hover { 249 | background-color: #C7EE63; 250 | } 251 | .checkOutGuidesButton { 252 | border:2px solid #f4914d8c; 253 | border-radius:100px; 254 | font-size:20px; 255 | letter-spacing:0; 256 | padding-left: 30px; 257 | padding-right: 30px; 258 | margin-right: 20px; 259 | background-color: white; 260 | transition: background-color .2s, color .2s; 261 | } 262 | .checkOutGuidesButton:hover { 263 | background-color: #f4914d; 264 | color: white; 265 | } 266 | 267 | section#openLibertyAndMp { 268 | background:#f4f4f5; 269 | background-size: 100% calc(100% - 70px); 270 | background-repeat: no-repeat; 271 | } 272 | 273 | #healthBox { 274 | text-align: left; 275 | display: table-cell; 276 | vertical-align: middle; 277 | width: 47%; 278 | } 279 | 280 | #healthBox > div { 281 | display: table-cell; 282 | vertical-align: middle; 283 | } 284 | 285 | #healthIcon { 286 | padding-left: 73px; 287 | padding-top: 56px; 288 | padding-bottom: 56px; 289 | } 290 | #healthStatusIcon { 291 | width: 104px; 292 | height: 104px; 293 | } 294 | 295 | #healthText { 296 | padding: 50px; 297 | } 298 | 299 | #serviceStatus { 300 | font-size: 50px; 301 | font-family:BunueloLight; 302 | margin-top: 30px; 303 | } 304 | 305 | #healthNote { 306 | text-align: left; 307 | display: table-cell; 308 | vertical-align: middle; 309 | padding-left: 43px; 310 | line-height: 26px; 311 | width: 53%; 312 | } 313 | 314 | table { 315 | width: 100%; 316 | font-size: 14px; 317 | text-align: left; 318 | border-collapse: collapse; 319 | } 320 | 321 | th { 322 | height: 63px; 323 | padding-left: 41px; 324 | font-size: 16px; 325 | } 326 | tr { 327 | height: 45px; 328 | } 329 | td { 330 | padding-left: 41px; 331 | } 332 | #systemPropertiesTable tr:first-child { 333 | background: #D6D9E4; 334 | } 335 | #configTable tr:first-child { 336 | background: #F8D7C1;; 337 | } 338 | #metricsTable tr:first-child { 339 | background: #EEF3C3; 340 | } 341 | 342 | #systemPropertiesTable tr:nth-child(2n+3) { 343 | background: #EEEFF3; 344 | } 345 | #configTable tr:nth-child(2n+2) { 346 | background: #FEF8F4; 347 | } 348 | #metricsTable tr:nth-child(2n+2) { 349 | background: #FBFCEE; 350 | } 351 | 352 | #systemPropertiesTable .sourceRow, 353 | #healthTable .sourceRow { 354 | border-top: 4px solid #D6D9E4; 355 | } 356 | #systemPropertiesTable .sourceRow a, 357 | #healthTable .sourceRow a { 358 | color: #5D6A8E; 359 | } 360 | #configTable .sourceRow { 361 | border-top: 4px solid #F8D7C1; 362 | } 363 | #configTable .sourceRow a { 364 | color: #E57000; 365 | } 366 | #metricsTable .sourceRow { 367 | border-top: 4px solid #EEF3C3; 368 | } 369 | #metricsTable .sourceRow a { 370 | color: #4F6700; 371 | } 372 | .sourceRow a { 373 | font-weight: 500; 374 | } 375 | 376 | #learnMore { 377 | margin-top: 120px; 378 | padding: 0px 200px 100px; 379 | } 380 | 381 | #learnMore > h2 { 382 | color:#5e6b8d; 383 | } 384 | 385 | @media (max-width:991px) { 386 | #learnMore { 387 | margin-top: 100px; 388 | padding: 0px 100px 50px; 389 | } 390 | } 391 | 392 | .resourcesRow { 393 | padding: 0px 40px; 394 | width: 100%; 395 | max-width: 1150px; 396 | margin: 0 auto; 397 | display: -webkit-box; 398 | display: -moz-box; 399 | display: -webkit-flex; 400 | display: -ms-flexbox; 401 | display: flex; 402 | -webkit-flex-wrap: wrap; 403 | -ms-flex-wrap: wrap; 404 | flex-wrap: wrap; 405 | } 406 | 407 | .column { 408 | flex: 100%; 409 | } 410 | 411 | @media (min-width: 767px) { 412 | .resourcesRow { 413 | -webkit-flex-wrap: nowrap; 414 | -ms-flex-wrap: none; 415 | flex-wrap: nowrap; 416 | } 417 | 418 | .column { 419 | flex: 50%; 420 | max-width: 50%; 421 | } 422 | } 423 | 424 | .resources { 425 | padding: 25px 20px 0px 20px; 426 | } 427 | 428 | .resources .row { 429 | width: 100%; 430 | max-width: 1150px; 431 | margin: 0 auto; 432 | display: -webkit-box; 433 | display: -moz-box; 434 | display: -webkit-flex; 435 | display: -ms-flexbox; 436 | display: flex; 437 | -webkit-flex-wrap: wrap; 438 | -ms-flex-wrap: wrap; 439 | flex-wrap: wrap; 440 | -webkit-box-direction: normal; 441 | -webkit-box-orient: vertical; 442 | -moz-box-direction: normal; 443 | -moz-box-orient: vertical; 444 | -webkit-flex-direction: column; 445 | -ms-flex-direction: column; 446 | flex-direction: column; 447 | padding: 0px 20px; 448 | } 449 | 450 | .resource { 451 | width: 90px; 452 | text-align: center; 453 | padding-top: 15px; 454 | padding-bottom: 0px; 455 | cursor: pointer; 456 | margin: 0 auto; 457 | } 458 | 459 | .resource:hover { 460 | background-color: #f4f4f4; 461 | } 462 | 463 | .resource p { 464 | margin-top: 10px; 465 | margin-bottom: 10px; 466 | } 467 | 468 | .resource__logo { 469 | height: 40px; 470 | } 471 | 472 | .circle { 473 | border-radius: 50%; 474 | border: 1px solid #C8D2D2; 475 | background-color: #ffffff; 476 | } 477 | 478 | #gitter_logo { 479 | border-radius: 50%; 480 | } 481 | 482 | #first_row { 483 | padding-top: 20px; 484 | } 485 | 486 | @media (min-width: 320px) { 487 | .resources .row { 488 | -webkit-box-direction: normal; 489 | -webkit-box-orient: horizontal; 490 | -moz-box-direction: normal; 491 | -moz-box-orient: horizontal; 492 | -webkit-flex-direction: row; 493 | -ms-flex-direction: row; 494 | flex-direction: row; 495 | padding: 0px; 496 | } 497 | } 498 | 499 | @media (min-width: 400px) { 500 | .resource { 501 | width: 100px; 502 | } 503 | 504 | .resource__logo { 505 | height: 50px; 506 | } 507 | } 508 | 509 | @media (min-width: 500px) { 510 | .resource { 511 | width: 120px; 512 | } 513 | 514 | .resource__logo { 515 | height: 70px; 516 | } 517 | 518 | .resource p { 519 | margin-top: 15px; 520 | margin-bottom: 15px; 521 | } 522 | } 523 | 524 | @media (min-width: 767px) { 525 | .resources .row { 526 | -webkit-flex-wrap: nowrap; 527 | -ms-flex-wrap: none; 528 | flex-wrap: nowrap; 529 | } 530 | 531 | .resource { 532 | width: 140px; 533 | } 534 | 535 | .resource__logo { 536 | height: 80px; 537 | } 538 | } 539 | 540 | @media (min-width: 992px) { 541 | 542 | #first_row { 543 | float: left; 544 | width: 50%; 545 | padding-top: 0px; 546 | } 547 | 548 | #second_row { 549 | float: right; 550 | width: 50%; 551 | } 552 | 553 | .resources { 554 | height: 150px; 555 | padding-left: 80px; 556 | padding-right: 80px; 557 | } 558 | 559 | .resource { 560 | padding-top: 30px; 561 | padding-bottom: 10px; 562 | } 563 | } 564 | 565 | .bodyFooter { 566 | padding: 5px 8%; 567 | background-image: url(/img/footer_main.png); 568 | background-repeat: no-repeat; 569 | background-position: top 20px right 110px; 570 | margin-bottom: 40px; 571 | margin-top: 50px; 572 | color: #3F4659; 573 | } 574 | 575 | .bodyFooterLink { 576 | font-family: Asap; 577 | font-weight: 300; 578 | font-size: 14px; 579 | letter-spacing: 0; 580 | border-bottom: solid 1px #C8D3D3; 581 | margin-top: 30px; 582 | margin-right: 130px; 583 | padding-bottom: 5px; 584 | padding-right: 50px; 585 | text-align: right; 586 | } 587 | 588 | .bodyFooterLink > a { 589 | text-decoration: none; 590 | padding: 10px; 591 | color: #96bc32; 592 | } 593 | 594 | #footer_text { 595 | margin-top: 4px; 596 | margin-bottom: 4px; 597 | font-size: 16px; 598 | } 599 | 600 | #footer_copyright { 601 | font-size: 11px; 602 | } 603 | -------------------------------------------------------------------------------- /src/main/webapp/fonts/BunueloCleanPro-Light.otf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/OpenLiberty/sample-getting-started/00406970c9264f594b1ecf223816d769c7b8a685/src/main/webapp/fonts/BunueloCleanPro-Light.otf -------------------------------------------------------------------------------- /src/main/webapp/fonts/BunueloCleanPro-SemiBold.otf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/OpenLiberty/sample-getting-started/00406970c9264f594b1ecf223816d769c7b8a685/src/main/webapp/fonts/BunueloCleanPro-SemiBold.otf -------------------------------------------------------------------------------- /src/main/webapp/img/carets/caret_down_blue.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 5 | 8 | 10 | 11 | -------------------------------------------------------------------------------- /src/main/webapp/img/carets/caret_down_green.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 5 | 8 | 10 | 11 | -------------------------------------------------------------------------------- /src/main/webapp/img/carets/caret_down_orange.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 5 | 8 | 10 | 11 | -------------------------------------------------------------------------------- /src/main/webapp/img/carets/caret_up_blue.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 5 | 8 | 10 | 11 | -------------------------------------------------------------------------------- /src/main/webapp/img/carets/caret_up_green.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 5 | 8 | 10 | 11 | -------------------------------------------------------------------------------- /src/main/webapp/img/carets/caret_up_orange.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 5 | 8 | 10 | 11 | -------------------------------------------------------------------------------- /src/main/webapp/img/config.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 6 | 9 | 10 | 13 | 16 | 19 | 20 | 21 | -------------------------------------------------------------------------------- /src/main/webapp/img/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/OpenLiberty/sample-getting-started/00406970c9264f594b1ecf223816d769c7b8a685/src/main/webapp/img/favicon.ico -------------------------------------------------------------------------------- /src/main/webapp/img/footer_main.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/OpenLiberty/sample-getting-started/00406970c9264f594b1ecf223816d769c7b8a685/src/main/webapp/img/footer_main.png -------------------------------------------------------------------------------- /src/main/webapp/img/github_logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/OpenLiberty/sample-getting-started/00406970c9264f594b1ecf223816d769c7b8a685/src/main/webapp/img/github_logo.png -------------------------------------------------------------------------------- /src/main/webapp/img/gitter_logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/OpenLiberty/sample-getting-started/00406970c9264f594b1ecf223816d769c7b8a685/src/main/webapp/img/gitter_logo.png -------------------------------------------------------------------------------- /src/main/webapp/img/groups_io_logo.jpeg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/OpenLiberty/sample-getting-started/00406970c9264f594b1ecf223816d769c7b8a685/src/main/webapp/img/groups_io_logo.jpeg -------------------------------------------------------------------------------- /src/main/webapp/img/header_ufo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/OpenLiberty/sample-getting-started/00406970c9264f594b1ecf223816d769c7b8a685/src/main/webapp/img/header_ufo.png -------------------------------------------------------------------------------- /src/main/webapp/img/health.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 5 | 8 | 9 | 10 | 11 | 12 | 13 | 15 | 16 | 17 | -------------------------------------------------------------------------------- /src/main/webapp/img/metrics.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 6 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | -------------------------------------------------------------------------------- /src/main/webapp/img/open_liberty_logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/OpenLiberty/sample-getting-started/00406970c9264f594b1ecf223816d769c7b8a685/src/main/webapp/img/open_liberty_logo.png -------------------------------------------------------------------------------- /src/main/webapp/img/stack_overflow_logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/OpenLiberty/sample-getting-started/00406970c9264f594b1ecf223816d769c7b8a685/src/main/webapp/img/stack_overflow_logo.png -------------------------------------------------------------------------------- /src/main/webapp/img/sysProps.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 5 | 8 | 12 | 16 | 20 | 21 | -------------------------------------------------------------------------------- /src/main/webapp/img/systemDown.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 5 | 9 | 10 | 11 | 13 | 15 | 16 | 17 | -------------------------------------------------------------------------------- /src/main/webapp/img/systemUp.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 6 | 10 | 11 | 12 | 13 | 15 | 16 | 17 | -------------------------------------------------------------------------------- /src/main/webapp/img/twitter_logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/OpenLiberty/sample-getting-started/00406970c9264f594b1ecf223816d769c7b8a685/src/main/webapp/img/twitter_logo.png -------------------------------------------------------------------------------- /src/main/webapp/index.html: -------------------------------------------------------------------------------- 1 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | Open Liberty - Getting Started Sample 24 | 25 | 26 |
27 |
28 |

Open Liberty System Properties Sample

29 |
30 |
31 |

Congrats on your shiny, new Open Liberty sample app!

32 |

This sample app uses a System Properties microservice to return the properties of the system that you're running.

33 |
34 | 35 |
36 |
37 |
38 |

System Properties

39 |
40 |
41 | 42 | 43 | 44 | 45 |
PropertiesValue
46 |
47 |
48 | 49 |
50 | 51 |
52 |

Where to next, captain?

53 |

Set course for the Open Liberty guides!

54 |

All of the info you need to continue your journey is here, laid out in easy to follow steps and examples. Searching our current selection makes it easy to find the guide that will help make your next project a reality.

55 | 56 | 57 |

Learn more about this sample app and a sweet Eclipse MicroProfile® bonus!

58 |

Some things just go together, like Earth and gravity or lasers and spaceships.
Another dynamic pair, Open Liberty and MicroProfile, provide the latest capabilities for building microservices by working together.

Your sample app utilizes MicroProfile health, config, and metrics, while running on Open Liberty. Scroll down to learn more.

59 |
60 | 61 |
62 |

System properties sample Insights

63 |

Built with MicroProfile on Open Liberty

64 | 90 | 91 | 110 | 111 | 139 |
140 | 141 |
142 |
143 | 149 | 155 | 161 |
162 |
163 | 169 | 175 | 181 |
182 |
183 | 184 | 190 | 191 | 192 |
193 | 197 | 198 | 199 |
200 | 201 | -------------------------------------------------------------------------------- /src/main/webapp/js/mpData.js: -------------------------------------------------------------------------------- 1 | /******************************************************************************* 2 | * Copyright (c) 2018, 2022 IBM Corporation and others. 3 | * All rights reserved. This program and the accompanying materials 4 | * are made available under the terms of the Eclipse Public License v1.0 5 | * which accompanies this distribution, and is available at 6 | * http://www.eclipse.org/legal/epl-v10.html 7 | * 8 | * Contributors: 9 | * IBM Corporation - initial API and implementation 10 | *******************************************************************************/ 11 | function displayLibertyVersion() { 12 | getRuntimeRequest(); 13 | } 14 | 15 | function getRuntimeRequest() { 16 | var url = location.origin + "/system/runtime"; 17 | var req = new XMLHttpRequest(); 18 | var table = document.getElementById("systemPropertiesTable"); 19 | 20 | req.onreadystatechange = function () { 21 | if (req.status === 200) { 22 | var version = req.responseText; 23 | if (version != "") { 24 | var appTitle = document.getElementById("appTitle"); 25 | appTitle.innerText = "Open Liberty " + version + " System Properties Sample"; 26 | } 27 | } 28 | }; 29 | req.open("GET", url, true); 30 | req.send(); 31 | } 32 | 33 | function displayMetrics() { 34 | getSystemMetrics(); 35 | } 36 | 37 | function getSystemMetrics() { 38 | var url = location.origin + "/metrics"; 39 | var req = new XMLHttpRequest(); 40 | 41 | var metricToDisplay = {}; 42 | var SRgetPropertiesTime = "io_openliberty_sample_system_SystemResource_getPropertiesTime"; 43 | metricToDisplay["getProperties_total{mp_scope=\"application\",}"] = "Request Count"; 44 | metricToDisplay[SRgetPropertiesTime + "_seconds{mp_scope=\"application\",quantile=\"0.999\",}"] = "Request Time (ms) at Quantile 0.999"; 45 | metricToDisplay[SRgetPropertiesTime + "_seconds{mp_scope=\"application\",quantile=\"0.5\",}"] = "Request Time (ms) at Quantile 0.5"; 46 | metricToDisplay[SRgetPropertiesTime + "_seconds_max{mp_scope=\"application\",}"] = "Max Request Time (ms)"; 47 | metricToDisplay["cpu_processCpuLoad_percent{mp_scope=\"base\",}"] = "System CPU Usage (%)"; 48 | metricToDisplay["memory_usedHeap_bytes{mp_scope=\"base\",}"] = "System Heap Usage (MB)"; 49 | 50 | var metricToMatch = "^("; 51 | for (var metricKey in metricToDisplay) { 52 | metricToMatch += metricKey + "|" 53 | } 54 | // remove the last | 55 | metricToMatch = metricToMatch.substring(0, metricToMatch.length - 1); 56 | metricToMatch += ")\\s*(\\S*)$" 57 | 58 | req.onreadystatechange = function () { 59 | if (req.readyState != 4) return; // Not there yet 60 | if (req.status != 200) { 61 | document.getElementById("metricsText").innerHTML = req.statusText; 62 | return; 63 | } 64 | 65 | var resp = req.responseText; 66 | var regexpToMatch = new RegExp(metricToMatch, "gm"); 67 | var matchMetrics = resp.match(regexpToMatch); 68 | 69 | var keyValPairs = {}; 70 | for (var metricKey in metricToDisplay) { 71 | matchMetrics.forEach(function (line) { 72 | var keyToMatch = metricKey + " (.*)"; 73 | var keyVal = line.match(new RegExp(keyToMatch)); 74 | if (keyVal) { 75 | var val = keyVal[1]; 76 | if (metricKey.indexOf(SRgetPropertiesTime) === 0) { 77 | val = val * 1000; 78 | } else if (metricKey.indexOf("base_memory_usedHeap_bytes") === 0) { 79 | val = val / 1000000; 80 | } 81 | keyValPairs[metricToDisplay[metricKey]] = val; 82 | } 83 | }) 84 | } 85 | 86 | var table = document.getElementById("metricsTableBody"); 87 | for (key in keyValPairs) { 88 | var row = document.createElement("tr"); 89 | var keyData = document.createElement("td"); 90 | keyData.innerText = key; 91 | var valueData = document.createElement("td"); 92 | valueData.innerText = keyValPairs[key]; 93 | row.appendChild(keyData); 94 | row.appendChild(valueData); 95 | table.appendChild(row); 96 | } 97 | 98 | addSourceRow(table, location.origin + "/metrics"); 99 | }; 100 | 101 | req.open("GET", url, true); 102 | req.send(); 103 | } 104 | 105 | function displaySystemProperties() { 106 | getSystemPropertiesRequest(); 107 | } 108 | 109 | function getSystemPropertiesRequest() { 110 | var propToDisplay = ["java.vendor", "java.version", "user.name", "os.name", "wlp.install.dir", "wlp.server.name"]; 111 | var url = location.origin + "/system/properties"; 112 | var req = new XMLHttpRequest(); 113 | var table = document.getElementById("systemPropertiesTable"); 114 | // Create the callback: 115 | req.onreadystatechange = function () { 116 | if (req.readyState != 4) return; // Not there yet 117 | displayMetrics(); 118 | if (req.status != 200) { 119 | table.innerHTML = ""; 120 | var row = document.createElement("tr"); 121 | var th = document.createElement("th"); 122 | th.innerText = req.statusText; 123 | row.appendChild(th); 124 | table.appendChild(row); 125 | 126 | addSourceRow(table, url); 127 | return; 128 | } 129 | // Request successful, read the response 130 | var resp = JSON.parse(req.responseText); 131 | for (var i = 0; i < propToDisplay.length; i++) { 132 | var key = propToDisplay[i]; 133 | if (resp.hasOwnProperty(key)) { 134 | var row = document.createElement("tr"); 135 | var keyData = document.createElement("td"); 136 | keyData.innerText = key; 137 | var valueData = document.createElement("td"); 138 | valueData.innerText = resp[key]; 139 | row.appendChild(keyData); 140 | row.appendChild(valueData); 141 | table.appendChild(row); 142 | } 143 | } 144 | 145 | addSourceRow(table, url); 146 | }; 147 | req.open("GET", url, true); 148 | req.send(); 149 | } 150 | 151 | function displayHealth() { 152 | getHealth(); 153 | } 154 | 155 | function getHealth() { 156 | var url = location.origin + "/health"; 157 | var req = new XMLHttpRequest(); 158 | 159 | var healthBox = document.getElementById("healthBox"); 160 | var serviceName = document.getElementById("serviceName"); 161 | var healthStatus = document.getElementById("serviceStatus"); 162 | var healthIcon = document.getElementById("healthStatusIconImage"); 163 | 164 | req.onreadystatechange = function () { 165 | if (req.readyState != 4) return; // Not there yet 166 | 167 | // Request successful, read the response 168 | if (req.responseText) { 169 | var resp = JSON.parse(req.responseText); 170 | var service = resp.checks[0]; //TODO: use for loop for multiple services 171 | 172 | resp.checks.forEach(function (service) { 173 | serviceName.innerText = service.name; 174 | healthStatus.innerText = service.status; 175 | 176 | if (service.status === "UP") { 177 | healthBox.style.backgroundColor = "#f0f7e1"; 178 | healthIcon.setAttribute("src", "img/systemUp.svg"); 179 | } else { 180 | healthBox.style.backgroundColor = "#fef7f2"; 181 | healthIcon.setAttribute("src", "img/systemDown.svg"); 182 | } 183 | }); 184 | } 185 | var table = document.getElementById("healthTable"); 186 | 187 | addSourceRow(table, url); 188 | }; 189 | req.open("GET", url, true); 190 | req.send(); 191 | } 192 | 193 | function displayConfigProperties() { 194 | getConfigPropertiesRequest(); 195 | } 196 | 197 | function getConfigPropertiesRequest() { 198 | var url = location.origin + "/system/config"; 199 | var req = new XMLHttpRequest(); 200 | 201 | var configToDisplay = {}; 202 | configToDisplay["io_openliberty_sample_system_inMaintenance"] = "System In Maintenance"; 203 | configToDisplay["io_openliberty_sample_testConfigOverwrite"] = "Test Config Overwrite"; 204 | configToDisplay["io_openliberty_sample_port_number"] = "Port Number"; 205 | // Create the callback: 206 | req.onreadystatechange = function () { 207 | if (req.readyState != 4) return; // Not there yet 208 | if (req.status != 200) { 209 | return; 210 | } 211 | 212 | // Request successful, read the response 213 | var resp = JSON.parse(req.responseText); 214 | var configProps = resp["ConfigProperties"]; 215 | var table = document.getElementById("configTableBody"); 216 | for (key in configProps) { 217 | var row = document.createElement("tr"); 218 | var keyData = document.createElement("td"); 219 | keyData.innerText = configToDisplay[key]; 220 | var valueData = document.createElement("td"); 221 | valueData.innerText = configProps[key]; 222 | row.appendChild(keyData); 223 | row.appendChild(valueData); 224 | table.appendChild(row); 225 | } 226 | 227 | addSourceRow(table, url); 228 | } 229 | req.open("GET", url, true); 230 | req.send(); 231 | } 232 | 233 | function toggle(e) { 234 | var callerElement; 235 | if (!e) { 236 | if (window.event) { 237 | e = window.event; 238 | callerElement = e.currentTarget; 239 | } else { 240 | callerElement = window.toggle.caller.arguments[0].currentTarget; // for firefox 241 | } 242 | } 243 | 244 | var classes = callerElement.parentElement.classList; 245 | var collapsed = classes.contains("collapsed"); 246 | var caretImg = callerElement.getElementsByClassName("caret")[0]; 247 | var caretImgSrc = caretImg.getAttribute("src"); 248 | if (collapsed) { // expand the section 249 | classes.replace("collapsed", "expanded"); 250 | caretImg.setAttribute("src", caretImgSrc.replace("down", "up")); 251 | } else { // collapse the section 252 | classes.replace("expanded", "collapsed"); 253 | caretImg.setAttribute("src", caretImgSrc.replace("up", "down")); 254 | } 255 | } 256 | 257 | function addSourceRow(table, url) { 258 | var sourceRow = document.createElement("tr"); 259 | sourceRow.classList.add("sourceRow"); 260 | var sourceText = document.createElement("td"); 261 | sourceText.setAttribute("colspan", "100%"); 262 | sourceText.innerHTML = "API Source\: " + url + ""; 263 | sourceRow.appendChild(sourceText); 264 | table.appendChild(sourceRow); 265 | } -------------------------------------------------------------------------------- /src/test/java/it/io/openliberty/sample/health/HealthIT.java: -------------------------------------------------------------------------------- 1 | /******************************************************************************* 2 | * Copyright (c) 2018, 2020 IBM Corporation and others. 3 | * All rights reserved. This program and the accompanying materials 4 | * are made available under the terms of the Eclipse Public License v1.0 5 | * which accompanies this distribution, and is available at 6 | * http://www.eclipse.org/legal/epl-v10.html 7 | * 8 | * Contributors: 9 | * IBM Corporation - Initial implementation 10 | *******************************************************************************/ 11 | 12 | package it.io.openliberty.sample.health; 13 | 14 | import java.util.HashMap; 15 | import jakarta.json.JsonArray; 16 | 17 | import static org.junit.jupiter.api.Assertions.assertEquals; 18 | 19 | import org.junit.jupiter.api.AfterEach; 20 | import org.junit.jupiter.api.Test; 21 | 22 | public class HealthIT { 23 | 24 | private JsonArray servicesstatus; 25 | private static HashMap dataWhenServicesUP, dataWhenServicesDown; 26 | 27 | static { 28 | dataWhenServicesUP = new HashMap(); 29 | dataWhenServicesDown = new HashMap(); 30 | dataWhenServicesUP.put("SystemResource", "UP"); 31 | dataWhenServicesDown.put("SystemResource", "DOWN"); 32 | } 33 | 34 | @Test 35 | public void testIfServicesAreUp() { 36 | servicesstatus = HealthUtilIT.connectToHealthEnpoint(200); 37 | checkServicesstatus(dataWhenServicesUP, servicesstatus); 38 | } 39 | 40 | @Test 41 | public void testIfServicesAreDown() { 42 | servicesstatus = HealthUtilIT.connectToHealthEnpoint(200); 43 | checkServicesstatus(dataWhenServicesUP, servicesstatus); 44 | HealthUtilIT.changeProperty(HealthUtilIT.INV_MAINTENANCE_FALSE, HealthUtilIT.INV_MAINTENANCE_TRUE); 45 | servicesstatus = HealthUtilIT.connectToHealthEnpoint(503); 46 | checkServicesstatus(dataWhenServicesDown, servicesstatus); 47 | } 48 | 49 | private void checkServicesstatus(HashMap testData, JsonArray servicesstatus) { 50 | testData.forEach((service, expectedState) -> { 51 | assertEquals(expectedState, HealthUtilIT.getActualState(service, servicesstatus), 52 | "The state of " + service + " service is not matching the "); 53 | }); 54 | 55 | } 56 | 57 | @AfterEach 58 | public void teardown() { 59 | HealthUtilIT.cleanUp(); 60 | } 61 | 62 | } 63 | -------------------------------------------------------------------------------- /src/test/java/it/io/openliberty/sample/health/HealthUtilIT.java: -------------------------------------------------------------------------------- 1 | /******************************************************************************* 2 | * Copyright (c) 2018, 2020 IBM Corporation and others. 3 | * All rights reserved. This program and the accompanying materials 4 | * are made available under the terms of the Eclipse Public License v1.0 5 | * which accompanies this distribution, and is available at 6 | * http://www.eclipse.org/legal/epl-v10.html 7 | * 8 | * Contributors: 9 | * IBM Corporation - Initial implementation 10 | *******************************************************************************/ 11 | 12 | package it.io.openliberty.sample.health; 13 | 14 | import static org.junit.jupiter.api.Assertions.assertEquals; 15 | 16 | import java.io.BufferedReader; 17 | import java.io.File; 18 | import java.io.FileReader; 19 | import java.io.FileWriter; 20 | 21 | import jakarta.json.JsonArray; 22 | import jakarta.json.JsonObject; 23 | import jakarta.ws.rs.client.Client; 24 | import jakarta.ws.rs.client.ClientBuilder; 25 | import jakarta.ws.rs.core.Response; 26 | 27 | public class HealthUtilIT { 28 | 29 | private static String port; 30 | private static String contextRoot; 31 | private static String baseUrl; 32 | private final static String HEALTH_ENDPOINT = "health"; 33 | public static final String INV_MAINTENANCE_FALSE = "io_openliberty_sample_system_inMaintenance\":false"; 34 | public static final String INV_MAINTENANCE_TRUE = "io_openliberty_sample_system_inMaintenance\":true"; 35 | 36 | static { 37 | port = System.getProperty("http.port"); 38 | contextRoot = System.getProperty("app.context.root"); 39 | baseUrl = "http://localhost:" + port + contextRoot; 40 | } 41 | 42 | public static JsonArray connectToHealthEnpoint(int expectedResponseCode) { 43 | String healthURL = baseUrl + HEALTH_ENDPOINT; 44 | Client client = ClientBuilder.newClient(); 45 | Response response = client.target(healthURL).request().get(); 46 | assertEquals(expectedResponseCode, response.getStatus(), "Response code is not matching " + healthURL); 47 | JsonArray servicesstatus = response.readEntity(JsonObject.class).getJsonArray("checks"); 48 | response.close(); 49 | client.close(); 50 | return servicesstatus; 51 | } 52 | 53 | public static String getActualState(String service, JsonArray servicesstatus) { 54 | String state = ""; 55 | for (Object obj : servicesstatus) { 56 | if (obj instanceof JsonObject) { 57 | if (service.equals(((JsonObject) obj).getString("name"))) { 58 | state = ((JsonObject) obj).getString("status"); 59 | } 60 | } 61 | } 62 | return state; 63 | } 64 | 65 | public static void changeProperty(String oldValue, String newValue) { 66 | try { 67 | String fileName = System.getProperty("user.dir").split("src")[0] + "/target/classes/META-INF/CustomConfigSource.json"; 68 | BufferedReader reader = new BufferedReader(new FileReader(new File(fileName))); 69 | String line = ""; 70 | String oldContent = "", newContent = ""; 71 | while ((line = reader.readLine()) != null) { 72 | oldContent += line + "\r\n"; 73 | } 74 | reader.close(); 75 | newContent = oldContent.replaceAll(oldValue, newValue); 76 | FileWriter writer = new FileWriter(fileName); 77 | writer.write(newContent); 78 | writer.close(); 79 | Thread.sleep(3500); 80 | } catch (Exception e) { 81 | e.printStackTrace(); 82 | } 83 | } 84 | 85 | public static void cleanUp() { 86 | changeProperty(INV_MAINTENANCE_TRUE, INV_MAINTENANCE_FALSE); 87 | } 88 | 89 | } 90 | --------------------------------------------------------------------------------