├── .allstar └── binary_artifacts.yaml ├── .github ├── pull_request_template.md └── workflows │ └── security-considerations.yml ├── .gitignore ├── CODEOWNERS ├── CONTRIBUTING.md ├── LICENSE.md ├── README.md ├── SECURITY.md ├── build-java-see.yml ├── cf-cron ├── LICENSE ├── Makefile ├── README.md ├── crontab └── manifest.yml ├── cron-task ├── README.md ├── index.js ├── manifest.yml ├── package-lock.json └── package.json ├── deno ├── Makefile ├── main.ts └── manifest.yml ├── dotnet-core ├── .gitignore ├── LICENSE ├── Program.cs ├── Startup.cs ├── dotnet-core-hello-world.csproj └── manifest.yml ├── go-hello ├── .gitignore ├── go.mod ├── main.go └── manifest.yml ├── java-see ├── .gitignore ├── .mvn │ └── wrapper │ │ ├── MavenWrapperDownloader.java │ │ ├── maven-wrapper.jar │ │ └── maven-wrapper.properties ├── INSTRUCTIONS.md ├── README.md ├── build-java-see.sh ├── build-java-see.yml ├── hello-world.iml ├── manifest.yml ├── mvnw ├── mvnw.cmd ├── pom.xml └── src │ ├── main │ ├── java │ │ └── gov │ │ │ └── cloud │ │ │ └── eng │ │ │ └── helloworld │ │ │ ├── HelloController.java │ │ │ └── HelloWorldApplication.java │ └── resources │ │ └── application.properties │ └── test │ └── java │ └── gov │ └── cloud │ └── eng │ └── helloworld │ └── HelloWorldApplicationTests.java ├── java-spring-actuator ├── .mvn │ └── wrapper │ │ ├── MavenWrapperDownloader.java │ │ ├── maven-wrapper.jar │ │ └── maven-wrapper.properties ├── README.md ├── manifest.yml ├── mvnw ├── mvnw.cmd ├── pom.xml ├── set-route-custom-port.sh └── src │ ├── main │ ├── java │ │ └── gov │ │ │ └── cloud │ │ │ └── eng │ │ │ └── spring_actuator_demo │ │ │ ├── HelloController.java │ │ │ └── HelloWorldApplication.java │ └── resources │ │ └── application.properties │ └── test │ └── java │ └── gov │ └── cloud │ └── eng │ └── spring_actuator_demo │ └── HelloWorldApplicationTests.java ├── nodejs ├── manifest-cnb.yml ├── manifest.yml ├── package-lock.json ├── package.json └── server.js ├── php ├── composer.json ├── index.php └── manifest.yml ├── pipeline.yml ├── python-flask-socketio ├── Procfile ├── README.md ├── client.js ├── hello.py ├── manifest.yml ├── package-lock.json ├── package.json └── requirements.txt ├── python-flask ├── Procfile ├── README.md ├── hello.py ├── manifest.yml └── requirements.txt ├── ruby-sinatra ├── .ruby-version ├── Gemfile ├── Gemfile.lock ├── config.ru ├── manifest.yml └── server.rb └── static ├── Staticfile ├── manifest.yml └── src └── index.html /.allstar/binary_artifacts.yaml: -------------------------------------------------------------------------------- 1 | # Ignore reason: These files are used for the Maven wrapper, which is useful 2 | ignorePaths: 3 | - java-see/.mvn/wrapper/maven-wrapper.jar 4 | - java-spring-actuator/.mvn/wrapper/maven-wrapper.jar 5 | -------------------------------------------------------------------------------- /.github/pull_request_template.md: -------------------------------------------------------------------------------- 1 | ## Changes proposed in this pull request: 2 | - 3 | - 4 | - 5 | 6 | ## security considerations 7 | [Note the any security considerations here, or make note of why there are none] 8 | -------------------------------------------------------------------------------- /.github/workflows/security-considerations.yml: -------------------------------------------------------------------------------- 1 | name: Security Considerations 2 | 3 | on: 4 | pull_request: 5 | types: [opened, edited, reopened] 6 | branches: [main, master, develop] 7 | 8 | jobs: 9 | security-considerations: 10 | runs-on: ubuntu-latest 11 | steps: 12 | - uses: cloud-gov/security-considerations-action@main 13 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | .*.cache 2 | .bundle/ 3 | vendor/ 4 | *.droplet 5 | local.yml 6 | .idea/ 7 | .DS_Store 8 | .vscode 9 | bin 10 | obj 11 | java-*/target 12 | node_modules 13 | -------------------------------------------------------------------------------- /CODEOWNERS: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cloud-gov/cf-hello-worlds/108bcd5031e01312243001254d6d1ddbdb8d8608/CODEOWNERS -------------------------------------------------------------------------------- /CONTRIBUTING.md: -------------------------------------------------------------------------------- 1 | **Contribution Policy** 2 | 3 | Cloud.gov is an open source project operated by the U.S. General Services Administration (GSA) to support federal agency missions. While we value transparency and collaboration, we must balance openness with the responsibilities of operating a secure, compliant, and trusted federal platform. 4 | 5 | ✅ **Who can contribute** 6 | We welcome contributions from: 7 | 8 | - Employees of U.S. federal agencies 9 | - Contractors working under a current agreement with a U.S. government entity 10 | - GSA-approved contributors as part of official interagency collaboration 11 | 12 | ❌ **Who we cannot accept contributions from** 13 | To avoid the appearance of government endorsement, manage supply chain risk, and maintain the integrity of our compliance posture, we do **not** accept unsolicited contributions from: 14 | 15 | - Individuals unaffiliated with the U.S. government 16 | - International contributors or organizations 17 | - Unvetted accounts or first-time contributors submitting minor changes 18 | 19 | If you're unsure whether your contribution fits, feel free to open an issue first so we can discuss it. 20 | -------------------------------------------------------------------------------- /LICENSE.md: -------------------------------------------------------------------------------- 1 | As a work of the United States Government, this project is in the 2 | public domain within the United States. 3 | 4 | Additionally, we waive copyright and related rights in the work 5 | worldwide through the CC0 1.0 Universal public domain dedication. 6 | 7 | ## CC0 1.0 Universal Summary 8 | 9 | This is a human-readable summary of the [Legal Code (read the full text)](https://creativecommons.org/publicdomain/zero/1.0/legalcode). 10 | 11 | ### No Copyright 12 | 13 | The person who associated a work with this deed has dedicated the work to 14 | the public domain by waiving all of his or her rights to the work worldwide 15 | under copyright law, including all related and neighboring rights, to the 16 | extent allowed by law. 17 | 18 | You can copy, modify, distribute and perform the work, even for commercial 19 | purposes, all without asking permission. 20 | 21 | ### Other Information 22 | 23 | In no way are the patent or trademark rights of any person affected by CC0, 24 | nor are the rights that other persons may have in the work or in how the 25 | work is used, such as publicity or privacy rights. 26 | 27 | Unless expressly stated otherwise, the person who associated a work with 28 | this deed makes no warranties about the work, and disclaims liability for 29 | all uses of the work, to the fullest extent permitted by applicable law. 30 | When using or citing the work, you should not imply endorsement by the 31 | author or the affirmer. 32 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Hello World apps for cloud.gov 2 | 3 | This repository contains minimal "Hello World" applications for a handful of different languages/frameworks for testing deployment to [cloud.gov](https://www.cloud.gov/), in particular, and other instances of [Cloud Foundry](https://www.cloudfoundry.org) ("CF") in general. 4 | 5 | For [cloud.gov](https://cloud.gov), follow the [quickstart guide](https://cloud.gov/docs/getting-started/your-first-deploy/) for a guided tour, or follow the USAGE below. 6 | 7 | ## Usage 8 | 9 | All of these examples, except Java, have the same usage. For Java, see its [INSTRUCTIONS.md](./java-see-instructions/INSTRUCTIONS.md). 10 | 11 | 1. Follow the [Cloud Foundry command-line (CLI) setup instructions](https://docs.cloudfoundry.org/cf-cli/install-go-cli.html). 12 | 1. Log into your Cloud Foundry account. (For example, if you use cloud.gov, follow [the "Set up the command line" instructions](https://cloud.gov/docs/getting-started/setup/#set-up-the-command-line) to log in.) 13 | 1. Clone or download this repository, and `cd` into the directory `cf-hello-worlds`. 14 | 1. `cd` into the subdirectory for whatever language/framework you feel most comfortable with. 15 | 1. Deploy the application with `cf push`. Look for `urls` value when the push completes. 16 | ```bash{9} 17 | cf push --random-route 18 | ... 19 | Creating app APP in org / space 20 | OK 21 | ...[snip]... 22 | requested state: started 23 | instances: 1/1 24 | usage: 512M x 1 instances 25 | urls: php-random-words.app.cloud.gov 26 | last uploaded: Fri Nov 3 17:50:30 UTC 2017 27 | stack: cflinuxfs2 28 | ``` 29 | 1. Visit your app with your browser at the URL assigned to your app. In the example above, that would be: e.g. https://php-random-words.app.cloud.gov 30 | 31 | All of examples produce web applications that respond "Hello World from <framework>" on their index page. 32 | 33 | ## See also 34 | 35 | * [Cloud Foundry community collection of sample applications](https://github.com/cloudfoundry-samples) 36 | * [cloud.gov Java Spring Boot example](https://github.com/18F/cf-sample-app-spring): This doesn't require `gradle` or any other dependencies. 37 | * [cloud.gov Drupal 8 example](https://github.com/18F/cf-ex-drupal8) 38 | * [cloud.gov Drupal 7 example](https://github.com/18F/cf-ex-drupal) 39 | * [cloud.gov Wordpress example](https://github.com/18F/cf-ex-wordpress) 40 | 41 | ## Public domain 42 | 43 | This project is in the worldwide [public domain](LICENSE.md). As stated in [CONTRIBUTING](CONTRIBUTING.md): 44 | 45 | >This project is in the public domain within the United States, and copyright and related rights in the work worldwide are waived through the [CC0 1.0 Universal public domain dedication](https://creativecommons.org/publicdomain/zero/1.0/). 46 | > 47 | >All contributions to this project will be released under the CC0 48 | >dedication. By submitting a pull request, you are agreeing to comply 49 | >with this waiver of copyright interest. 50 | -------------------------------------------------------------------------------- /SECURITY.md: -------------------------------------------------------------------------------- 1 | 2 | **Reporting Security Issues** 3 | 4 | Please refrain from reporting security vulnerabilities through public GitHub issues. 5 | 6 | Instead, kindly report them via the information provided in [cloud.gov's security.txt](https://cloud.gov/.well-known/security.txt). 7 | 8 | When reporting, include the following details (as much as possible) to help us understand the nature and extent of the potential issue: 9 | 10 | - Type of issue (e.g., buffer overflow, SQL injection, cross-site scripting, etc.) 11 | - Full paths of related source file(s) 12 | - Location of affected source code (tag/branch/commit or direct URL) 13 | - Any special configuration required to reproduce the issue 14 | - Step-by-step instructions to reproduce the issue 15 | - Proof-of-concept or exploit code (if available) 16 | - Impact of the issue, including potential exploitation by attackers 17 | 18 | Providing this information will facilitate a quicker triage of your report. 19 | -------------------------------------------------------------------------------- /build-java-see.yml: -------------------------------------------------------------------------------- 1 | --- 2 | platform: linux 3 | 4 | image_resource: 5 | type: docker-image 6 | source: 7 | repository: openjdk 8 | 9 | inputs: 10 | - name: cf-hello-worlds 11 | outputs: 12 | - name: cf-hello-worlds-build 13 | 14 | run: 15 | path: cf-hello-worlds/build-java-see.sh 16 | -------------------------------------------------------------------------------- /cf-cron/LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2018 Meshcloud 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /cf-cron/Makefile: -------------------------------------------------------------------------------- 1 | SUPERCRONIC_URL = https://github.com/aptible/supercronic/releases/download/v0.2.33/supercronic-linux-amd64 2 | SUPERCRONIC_SHA1SUM = 71b0d58cc53f6bd72cf2f293e09e294b79c666d8 3 | 4 | supercronic: 5 | curl --fail --silent --location --show-error -o $@ ${SUPERCRONIC_URL} 6 | echo "${SUPERCRONIC_SHA1SUM} $@" | sha1sum -c - || rm $@ 7 | chmod +x $@ 8 | 9 | -------------------------------------------------------------------------------- /cf-cron/README.md: -------------------------------------------------------------------------------- 1 | # Running Cron Jobs on Cloud Foundry 2 | 3 | ## Note: originally from https://github.com/meshcloud/cf-cron, 4 | 5 | ## Quickstart 6 | 7 | * Edit the `crontab` to do what you want, 8 | * Download, checksum, and chmod the `supercronic` binary: 9 | `make` 10 | * Push the app: 11 | `cf push` 12 | 13 | ## Notes 14 | 15 | This repository demonstrates how to run scheduled tasks on Cloud Foundry with a very small footprint (8 to 16 MB RAM) using a traditional crontab. This means you can run it for a few cents of monthly cost. 16 | 17 | Traditional cron daemons need to run as root and have opinionated defaults for logging and error notifications. This makes them unsuitable for running in a containerized environment like Cloud Foundry. Instead of a system cron daemon we're thus using [supercronic](https://github.com/aptible/supercronic) to run our cron tab. 18 | 19 | ## How it works 20 | 21 | This application is built using the binary buildpack and executes `supercronic` on the `crontab` file. The `crontab`file specifies all your cron jobs. To add additional jobs, simply add a new line which specifies a schedule and command to the `crontab`. 22 | 23 | > Note: By default, `supercronic` will log [all output to stderr](https://github.com/aptible/supercronic/issues/16) so we redirect that to stdout in our cf manifest. 24 | 25 | You can also include additional scripts and binaries to execute more complex actions. 26 | 27 | After `cf push`ing this sample app to Cloud Foundry, you can see that it happily executes the jobs from the `crontab` in the log output: 28 | 29 | ```text 30 | Apr 18, 2025 @ 13:51:29.911 {"level":"info","msg":"read crontab: ./crontab","time":"2025-04-18T17:51:29Z"} 31 | Apr 18, 2025 @ 14:00:00.099 {"iteration":0,"job.command":"curl -s https://logs-workshop.app.cloud.gov/ 1\u003e/dev/null 2\u003e/dev/null","job.position":0,"job.schedule":"*/10 00-19,30-49 * * * * *","level":"info","msg":"starting","time":"2025-04-18T18:00:00Z"} 32 | Apr 18, 2025 @ 14:00:00.237 {"iteration":0,"job.command":"curl -s https://logs-workshop.app.cloud.gov/ 1\u003e/dev/null 2\u003e/dev/null","job.position":0,"job.schedule":"*/10 00-19,30-49 * * * * *","level":"info","msg":"job succeeded","time":"2025-04-18T18:00:00Z"} 33 | ``` 34 | 35 | ## Maintaining Supercronic 36 | 37 | The binary for Supercronic comes from https://github.com/aptible/supercronic/releases, and you should check the periodically for updates. 38 | 39 | ## Running Scheduled Tasks on Cloud Foundry 40 | 41 | While the cron container here is designed to be small and lightweight, you may want to use it to trigger more resource intensive tasks and processes. When a simple `curl` to an http endpoint is not enough to kick off such a task on your existing app, [Cloud Foundry Tasks](https://docs.cloudfoundry.org/devguide/using-tasks.html) are a great solution to run these processes. 42 | 43 | -------------------------------------------------------------------------------- /cf-cron/crontab: -------------------------------------------------------------------------------- 1 | 2 | # Run every 10 seconds, for a sample app 3 | */10 * * * * * * curl -s https://sample-app.app.cloud.gov/ 1>/dev/null 2>/dev/null 4 | 5 | -------------------------------------------------------------------------------- /cf-cron/manifest.yml: -------------------------------------------------------------------------------- 1 | --- 2 | applications: 3 | - name: cf-cron 4 | memory: 256M 5 | no-route: true 6 | health-check-type: process 7 | buildpacks: 8 | - binary_buildpack 9 | command: ./supercronic -passthrough-logs -json ./crontab 2>&1 10 | 11 | -------------------------------------------------------------------------------- /cron-task/README.md: -------------------------------------------------------------------------------- 1 | # Running one-off tasks on cloud.gov 2 | 3 | This is an example of a one-off task that can be run on cloud.gov. More on how to do this can be [found in the docs](https://cloud.gov/docs/management/one-off-tasks/). Note, this example uses node.js, but you can use any language that has a cron-like library to do something similar. 4 | 5 | ## Usage 6 | 7 | To run this app locally, use `npm start`. To deploy to cloud.gov, use the instructions below: 8 | 9 | ```bash 10 | ~$ cf push -f manifest.yml --health-check-type none --no-route 11 | ``` 12 | 13 | You can also add the `health-check-type` and `no-route` parameters to your manifest if it's easier: 14 | 15 | ```yaml 16 | health-check-type: none 17 | no-route: true 18 | ``` 19 | 20 | When done, wait a few minutes for some log messages to show up, then check the logs: 21 | 22 | ```bash 23 | ~$ cf logs --recent task-runner 24 | ``` 25 | 26 | You can also check the status of tasks that have run: 27 | 28 | ```bash 29 | ~$ cf tasks task-runner 30 | ``` 31 | 32 | ## Clean up 33 | 34 | Note, when done with the example, make sure you delete your app: 35 | 36 | ```bash 37 | ~$ cf delete task-runner 38 | ``` 39 | 40 | -------------------------------------------------------------------------------- /cron-task/index.js: -------------------------------------------------------------------------------- 1 | // Require cron module. 2 | const CronJob = require('cron').CronJob; 3 | 4 | // Set timing parameters. 5 | const schedule = '*/30 * * * * *'; 6 | const timezone = 'America/New_York'; 7 | 8 | // Declare a function with a job to be run. 9 | let runJob = () => console.log('*** Hello world every 30 seconds ***'); 10 | 11 | // Set up the job and run it. 12 | console.log("Starting one-off task"); 13 | let job = new CronJob(schedule, () => runJob(), null, true, timezone); 14 | job.start(); -------------------------------------------------------------------------------- /cron-task/manifest.yml: -------------------------------------------------------------------------------- 1 | applications: 2 | - name: task-runner 3 | buildpacks: 4 | - nodejs_buildpack 5 | disk_quota: 1G 6 | instances: 1 7 | memory: 256M 8 | stack: cflinuxfs3 9 | command: (npm start && echo SUCCESS || echo FAIL) && sleep infinity 10 | 11 | -------------------------------------------------------------------------------- /cron-task/package-lock.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "cg-task-example", 3 | "version": "1.0.0", 4 | "lockfileVersion": 1, 5 | "requires": true, 6 | "dependencies": { 7 | "cron": { 8 | "version": "1.8.2", 9 | "resolved": "https://registry.npmjs.org/cron/-/cron-1.8.2.tgz", 10 | "integrity": "sha512-Gk2c4y6xKEO8FSAUTklqtfSr7oTq0CiPQeLBG5Fl0qoXpZyMcj1SG59YL+hqq04bu6/IuEA7lMkYDAplQNKkyg==", 11 | "requires": { 12 | "moment-timezone": "^0.5.x" 13 | } 14 | }, 15 | "moment-timezone": { 16 | "version": "0.5.45", 17 | "resolved": "https://registry.npmjs.org/moment-timezone/-/moment-timezone-0.5.45.tgz", 18 | "integrity": "sha512-HIWmqA86KcmCAhnMAN0wuDOARV/525R2+lOLotuGFzn4HO+FH+/645z2wx0Dt3iDv6/p61SIvKnDstISainhLQ==", 19 | "requires": { 20 | "moment": "^2.29.4" 21 | }, 22 | "dependencies": { 23 | "moment": { 24 | "version": "2.30.1", 25 | "resolved": "https://registry.npmjs.org/moment/-/moment-2.30.1.tgz", 26 | "integrity": "sha512-uEmtNhbDOrWPFS+hdjFCBfy9f2YoyzRpwcl+DqpC6taX21FzsTLQVbMV/W7PzNSX6x/bhC1zA3c2UQ5NzH6how==" 27 | } 28 | } 29 | } 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /cron-task/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "cg-task-example", 3 | "version": "1.0.0", 4 | "description": "", 5 | "main": "index.js", 6 | "scripts": { 7 | "start": "node index.js" 8 | }, 9 | "keywords": ["cron", "cloud"], 10 | "author": "Mark Headd (mark.headd@gsa.gov)", 11 | "license": "ISC", 12 | "dependencies": { 13 | "cron": "^1.8.2" 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /deno/Makefile: -------------------------------------------------------------------------------- 1 | # A Makefile to `make` life easier 2 | # Run `make` or `make help` to see all options 3 | 4 | SHELL := /bin/bash 5 | 6 | .PHONY: help 7 | help: ## Show this help 8 | @egrep -h '\s##\s' $(MAKEFILE_LIST) | sort | awk 'BEGIN {FS = ":.*?## "}; {printf "\033[36m%-30s\033[0m %s\n", $$1, $$2}' 9 | 10 | watch: ## Run the app and restart on changes 11 | docker run -it --init -p 8080:8080 -v $(PWD):/app -e PORT=8080 denoland/deno:alpine run --allow-net=0.0.0.0 --allow-env=PORT --watch /app/main.ts 12 | 13 | compile: ## Compile the app to a single executable 14 | docker run -it --init -v $(PWD):/app denoland/deno:alpine compile --allow-net=0.0.0.0 --allow-env=PORT -o /app/bin/main /app/main.ts 15 | 16 | deploy: compile ## Compile and deploy the app to Cloud Foundry 17 | cf push test-deno -------------------------------------------------------------------------------- /deno/main.ts: -------------------------------------------------------------------------------- 1 | const port = Number.parseInt(Deno.env.get('PORT') ?? '8080'); 2 | 3 | const server = Deno.listen({ port }); 4 | console.log(`http://localhost:${port}/`); 5 | 6 | for await (const conn of server) { 7 | handleConn(conn); 8 | } 9 | 10 | async function handleConn(conn: Deno.Conn) { 11 | const requests = Deno.serveHttp(conn); 12 | for await (const request of requests) { 13 | request.respondWith(new Response('Hello World from Deno')); 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /deno/manifest.yml: -------------------------------------------------------------------------------- 1 | --- 2 | applications: 3 | - name: test-deno 4 | random-route: true 5 | buildpacks: 6 | - binary_buildpack 7 | memory: 128M 8 | command: ./bin/main -------------------------------------------------------------------------------- /dotnet-core/.gitignore: -------------------------------------------------------------------------------- 1 | .vscode 2 | appsettings.Development.json 3 | appsettings.json 4 | [Bb]in/ 5 | [Oo]bj/ -------------------------------------------------------------------------------- /dotnet-core/LICENSE: -------------------------------------------------------------------------------- 1 | Apache License 2 | Version 2.0, January 2004 3 | http://www.apache.org/licenses/ 4 | 5 | TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION 6 | 7 | 1. Definitions. 8 | 9 | "License" shall mean the terms and conditions for use, reproduction, 10 | and distribution as defined by Sections 1 through 9 of this document. 11 | 12 | "Licensor" shall mean the copyright owner or entity authorized by 13 | the copyright owner that is granting the License. 14 | 15 | "Legal Entity" shall mean the union of the acting entity and all 16 | other entities that control, are controlled by, or are under common 17 | control with that entity. For the purposes of this definition, 18 | "control" means (i) the power, direct or indirect, to cause the 19 | direction or management of such entity, whether by contract or 20 | otherwise, or (ii) ownership of fifty percent (50%) or more of the 21 | outstanding shares, or (iii) beneficial ownership of such entity. 22 | 23 | "You" (or "Your") shall mean an individual or Legal Entity 24 | exercising permissions granted by this License. 25 | 26 | "Source" form shall mean the preferred form for making modifications, 27 | including but not limited to software source code, documentation 28 | source, and configuration files. 29 | 30 | "Object" form shall mean any form resulting from mechanical 31 | transformation or translation of a Source form, including but 32 | not limited to compiled object code, generated documentation, 33 | and conversions to other media types. 34 | 35 | "Work" shall mean the work of authorship, whether in Source or 36 | Object form, made available under the License, as indicated by a 37 | copyright notice that is included in or attached to the work 38 | (an example is provided in the Appendix below). 39 | 40 | "Derivative Works" shall mean any work, whether in Source or Object 41 | form, that is based on (or derived from) the Work and for which the 42 | editorial revisions, annotations, elaborations, or other modifications 43 | represent, as a whole, an original work of authorship. For the purposes 44 | of this License, Derivative Works shall not include works that remain 45 | separable from, or merely link (or bind by name) to the interfaces of, 46 | the Work and Derivative Works thereof. 47 | 48 | "Contribution" shall mean any work of authorship, including 49 | the original version of the Work and any modifications or additions 50 | to that Work or Derivative Works thereof, that is intentionally 51 | submitted to Licensor for inclusion in the Work by the copyright owner 52 | or by an individual or Legal Entity authorized to submit on behalf of 53 | the copyright owner. For the purposes of this definition, "submitted" 54 | means any form of electronic, verbal, or written communication sent 55 | to the Licensor or its representatives, including but not limited to 56 | communication on electronic mailing lists, source code control systems, 57 | and issue tracking systems that are managed by, or on behalf of, the 58 | Licensor for the purpose of discussing and improving the Work, but 59 | excluding communication that is conspicuously marked or otherwise 60 | designated in writing by the copyright owner as "Not a Contribution." 61 | 62 | "Contributor" shall mean Licensor and any individual or Legal Entity 63 | on behalf of whom a Contribution has been received by Licensor and 64 | subsequently incorporated within the Work. 65 | 66 | 2. Grant of Copyright License. Subject to the terms and conditions of 67 | this License, each Contributor hereby grants to You a perpetual, 68 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable 69 | copyright license to reproduce, prepare Derivative Works of, 70 | publicly display, publicly perform, sublicense, and distribute the 71 | Work and such Derivative Works in Source or Object form. 72 | 73 | 3. Grant of Patent License. Subject to the terms and conditions of 74 | this License, each Contributor hereby grants to You a perpetual, 75 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable 76 | (except as stated in this section) patent license to make, have made, 77 | use, offer to sell, sell, import, and otherwise transfer the Work, 78 | where such license applies only to those patent claims licensable 79 | by such Contributor that are necessarily infringed by their 80 | Contribution(s) alone or by combination of their Contribution(s) 81 | with the Work to which such Contribution(s) was submitted. If You 82 | institute patent litigation against any entity (including a 83 | cross-claim or counterclaim in a lawsuit) alleging that the Work 84 | or a Contribution incorporated within the Work constitutes direct 85 | or contributory patent infringement, then any patent licenses 86 | granted to You under this License for that Work shall terminate 87 | as of the date such litigation is filed. 88 | 89 | 4. Redistribution. You may reproduce and distribute copies of the 90 | Work or Derivative Works thereof in any medium, with or without 91 | modifications, and in Source or Object form, provided that You 92 | meet the following conditions: 93 | 94 | (a) You must give any other recipients of the Work or 95 | Derivative Works a copy of this License; and 96 | 97 | (b) You must cause any modified files to carry prominent notices 98 | stating that You changed the files; and 99 | 100 | (c) You must retain, in the Source form of any Derivative Works 101 | that You distribute, all copyright, patent, trademark, and 102 | attribution notices from the Source form of the Work, 103 | excluding those notices that do not pertain to any part of 104 | the Derivative Works; and 105 | 106 | (d) If the Work includes a "NOTICE" text file as part of its 107 | distribution, then any Derivative Works that You distribute must 108 | include a readable copy of the attribution notices contained 109 | within such NOTICE file, excluding those notices that do not 110 | pertain to any part of the Derivative Works, in at least one 111 | of the following places: within a NOTICE text file distributed 112 | as part of the Derivative Works; within the Source form or 113 | documentation, if provided along with the Derivative Works; or, 114 | within a display generated by the Derivative Works, if and 115 | wherever such third-party notices normally appear. The contents 116 | of the NOTICE file are for informational purposes only and 117 | do not modify the License. You may add Your own attribution 118 | notices within Derivative Works that You distribute, alongside 119 | or as an addendum to the NOTICE text from the Work, provided 120 | that such additional attribution notices cannot be construed 121 | as modifying the License. 122 | 123 | You may add Your own copyright statement to Your modifications and 124 | may provide additional or different license terms and conditions 125 | for use, reproduction, or distribution of Your modifications, or 126 | for any such Derivative Works as a whole, provided Your use, 127 | reproduction, and distribution of the Work otherwise complies with 128 | the conditions stated in this License. 129 | 130 | 5. Submission of Contributions. Unless You explicitly state otherwise, 131 | any Contribution intentionally submitted for inclusion in the Work 132 | by You to the Licensor shall be under the terms and conditions of 133 | this License, without any additional terms or conditions. 134 | Notwithstanding the above, nothing herein shall supersede or modify 135 | the terms of any separate license agreement you may have executed 136 | with Licensor regarding such Contributions. 137 | 138 | 6. Trademarks. This License does not grant permission to use the trade 139 | names, trademarks, service marks, or product names of the Licensor, 140 | except as required for reasonable and customary use in describing the 141 | origin of the Work and reproducing the content of the NOTICE file. 142 | 143 | 7. Disclaimer of Warranty. Unless required by applicable law or 144 | agreed to in writing, Licensor provides the Work (and each 145 | Contributor provides its Contributions) on an "AS IS" BASIS, 146 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or 147 | implied, including, without limitation, any warranties or conditions 148 | of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A 149 | PARTICULAR PURPOSE. You are solely responsible for determining the 150 | appropriateness of using or redistributing the Work and assume any 151 | risks associated with Your exercise of permissions under this License. 152 | 153 | 8. Limitation of Liability. In no event and under no legal theory, 154 | whether in tort (including negligence), contract, or otherwise, 155 | unless required by applicable law (such as deliberate and grossly 156 | negligent acts) or agreed to in writing, shall any Contributor be 157 | liable to You for damages, including any direct, indirect, special, 158 | incidental, or consequential damages of any character arising as a 159 | result of this License or out of the use or inability to use the 160 | Work (including but not limited to damages for loss of goodwill, 161 | work stoppage, computer failure or malfunction, or any and all 162 | other commercial damages or losses), even if such Contributor 163 | has been advised of the possibility of such damages. 164 | 165 | 9. Accepting Warranty or Additional Liability. While redistributing 166 | the Work or Derivative Works thereof, You may choose to offer, 167 | and charge a fee for, acceptance of support, warranty, indemnity, 168 | or other liability obligations and/or rights consistent with this 169 | License. However, in accepting such obligations, You may act only 170 | on Your own behalf and on Your sole responsibility, not on behalf 171 | of any other Contributor, and only if You agree to indemnify, 172 | defend, and hold each Contributor harmless for any liability 173 | incurred by, or claims asserted against, such Contributor by reason 174 | of your accepting any such warranty or additional liability. 175 | 176 | END OF TERMS AND CONDITIONS 177 | 178 | APPENDIX: How to apply the Apache License to your work. 179 | 180 | To apply the Apache License to your work, attach the following 181 | boilerplate notice, with the fields enclosed by brackets "[]" 182 | replaced with your own identifying information. (Don't include 183 | the brackets!) The text should be enclosed in the appropriate 184 | comment syntax for the file format. We also recommend that a 185 | file or class name and description of purpose be included on the 186 | same "printed page" as the copyright notice for easier 187 | identification within third-party archives. 188 | 189 | Copyright [yyyy] [name of copyright owner] 190 | 191 | Licensed under the Apache License, Version 2.0 (the "License"); 192 | you may not use this file except in compliance with the License. 193 | You may obtain a copy of the License at 194 | 195 | http://www.apache.org/licenses/LICENSE-2.0 196 | 197 | Unless required by applicable law or agreed to in writing, software 198 | distributed under the License is distributed on an "AS IS" BASIS, 199 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 200 | See the License for the specific language governing permissions and 201 | limitations under the License. 202 | -------------------------------------------------------------------------------- /dotnet-core/Program.cs: -------------------------------------------------------------------------------- 1 | using Microsoft.AspNetCore.Hosting; 2 | using Microsoft.Extensions.Hosting; 3 | 4 | namespace dot_net_gov 5 | { 6 | public class Program 7 | { 8 | public static void Main(string[] args) 9 | { 10 | CreateHostBuilder(args).Build().Run(); 11 | } 12 | 13 | public static IHostBuilder CreateHostBuilder(string[] args) => 14 | Host.CreateDefaultBuilder(args) 15 | .ConfigureWebHostDefaults(webBuilder => 16 | { 17 | webBuilder.UseStartup(); 18 | }); 19 | } 20 | } -------------------------------------------------------------------------------- /dotnet-core/Startup.cs: -------------------------------------------------------------------------------- 1 | using Microsoft.AspNetCore.Builder; 2 | using Microsoft.AspNetCore.Hosting; 3 | using Microsoft.AspNetCore.Http; 4 | using Microsoft.Extensions.DependencyInjection; 5 | using Microsoft.Extensions.Hosting; 6 | 7 | namespace dot_net_gov 8 | { 9 | public class Startup 10 | { 11 | // This method gets called by the runtime. Use this method to add services to the container. 12 | // For more information on how to configure your application, visit https://go.microsoft.com/fwlink/?LinkID=398940 13 | public void ConfigureServices(IServiceCollection services) 14 | { 15 | } 16 | 17 | // This method gets called by the runtime. Use this method to configure the HTTP request pipeline. 18 | public void Configure(IApplicationBuilder app, IWebHostEnvironment env) 19 | { 20 | if (env.IsDevelopment()) 21 | { 22 | app.UseDeveloperExceptionPage(); 23 | } 24 | 25 | app.UseRouting(); 26 | 27 | app.UseEndpoints(endpoints => 28 | { 29 | endpoints.MapGet("/", async context => 30 | { 31 | await context.Response.WriteAsync("Hello World from .Net Core 8.0!"); 32 | }); 33 | }); 34 | } 35 | } 36 | } 37 | -------------------------------------------------------------------------------- /dotnet-core/dotnet-core-hello-world.csproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | netcoreapp8.0 5 | dot_net_gov 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /dotnet-core/manifest.yml: -------------------------------------------------------------------------------- 1 | --- 2 | applications: 3 | - name: test-dotnet-core 4 | random-route: true 5 | buildpacks: 6 | - dotnet_core_buildpack 7 | memory: 256M 8 | stack: cflinuxfs4 9 | env: 10 | CACHE_NUGET_PACKAGES: false 11 | -------------------------------------------------------------------------------- /go-hello/.gitignore: -------------------------------------------------------------------------------- 1 | go-hello 2 | -------------------------------------------------------------------------------- /go-hello/go.mod: -------------------------------------------------------------------------------- 1 | module github.com/cloud-gov/cf-hello-worlds/go-hello 2 | 3 | go 1.20 4 | -------------------------------------------------------------------------------- /go-hello/main.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "fmt" 5 | "net/http" 6 | "os" 7 | ) 8 | 9 | func main() { 10 | http.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) { 11 | fmt.Fprintf(w, "

Hello, World from Go!

\n") 12 | }) 13 | 14 | http.ListenAndServe(":"+os.Getenv("PORT"), nil) 15 | } 16 | -------------------------------------------------------------------------------- /go-hello/manifest.yml: -------------------------------------------------------------------------------- 1 | --- 2 | applications: 3 | - name: go-hello 4 | buildpacks: 5 | - go_buildpack 6 | env: 7 | GOVERSION: "1.20" 8 | random-route: true 9 | stack: cflinuxfs4 10 | -------------------------------------------------------------------------------- /java-see/.gitignore: -------------------------------------------------------------------------------- 1 | /bin/ 2 | .classpath 3 | .project 4 | .settings/ 5 | build/ 6 | .gradle/ 7 | target/ 8 | -------------------------------------------------------------------------------- /java-see/.mvn/wrapper/MavenWrapperDownloader.java: -------------------------------------------------------------------------------- 1 | /* 2 | Licensed to the Apache Software Foundation (ASF) under one 3 | or more contributor license agreements. See the NOTICE file 4 | distributed with this work for additional information 5 | regarding copyright ownership. The ASF licenses this file 6 | to you under the Apache License, Version 2.0 (the 7 | "License"); you may not use this file except in compliance 8 | with the License. You may obtain a copy of the License at 9 | 10 | https://www.apache.org/licenses/LICENSE-2.0 11 | 12 | Unless required by applicable law or agreed to in writing, 13 | software distributed under the License is distributed on an 14 | "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 15 | KIND, either express or implied. See the License for the 16 | specific language governing permissions and limitations 17 | under the License. 18 | */ 19 | 20 | import java.io.File; 21 | import java.io.FileInputStream; 22 | import java.io.FileOutputStream; 23 | import java.io.IOException; 24 | import java.net.URL; 25 | import java.nio.channels.Channels; 26 | import java.nio.channels.ReadableByteChannel; 27 | import java.util.Properties; 28 | 29 | public class MavenWrapperDownloader { 30 | 31 | /** 32 | * Default URL to download the maven-wrapper.jar from, if no 'downloadUrl' is provided. 33 | */ 34 | private static final String DEFAULT_DOWNLOAD_URL = 35 | "https://repo.maven.apache.org/maven2/io/takari/maven-wrapper/0.4.2/maven-wrapper-0.4.2.jar"; 36 | 37 | /** 38 | * Path to the maven-wrapper.properties file, which might contain a downloadUrl property to 39 | * use instead of the default one. 40 | */ 41 | private static final String MAVEN_WRAPPER_PROPERTIES_PATH = 42 | ".mvn/wrapper/maven-wrapper.properties"; 43 | 44 | /** 45 | * Path where the maven-wrapper.jar will be saved to. 46 | */ 47 | private static final String MAVEN_WRAPPER_JAR_PATH = 48 | ".mvn/wrapper/maven-wrapper.jar"; 49 | 50 | /** 51 | * Name of the property which should be used to override the default download url for the wrapper. 52 | */ 53 | private static final String PROPERTY_NAME_WRAPPER_URL = "wrapperUrl"; 54 | 55 | public static void main(String args[]) { 56 | System.out.println("- Downloader started"); 57 | File baseDirectory = new File(args[0]); 58 | System.out.println("- Using base directory: " + baseDirectory.getAbsolutePath()); 59 | 60 | // If the maven-wrapper.properties exists, read it and check if it contains a custom 61 | // wrapperUrl parameter. 62 | File mavenWrapperPropertyFile = new File(baseDirectory, MAVEN_WRAPPER_PROPERTIES_PATH); 63 | String url = DEFAULT_DOWNLOAD_URL; 64 | if(mavenWrapperPropertyFile.exists()) { 65 | FileInputStream mavenWrapperPropertyFileInputStream = null; 66 | try { 67 | mavenWrapperPropertyFileInputStream = new FileInputStream(mavenWrapperPropertyFile); 68 | Properties mavenWrapperProperties = new Properties(); 69 | mavenWrapperProperties.load(mavenWrapperPropertyFileInputStream); 70 | url = mavenWrapperProperties.getProperty(PROPERTY_NAME_WRAPPER_URL, url); 71 | } catch (IOException e) { 72 | System.out.println("- ERROR loading '" + MAVEN_WRAPPER_PROPERTIES_PATH + "'"); 73 | } finally { 74 | try { 75 | if(mavenWrapperPropertyFileInputStream != null) { 76 | mavenWrapperPropertyFileInputStream.close(); 77 | } 78 | } catch (IOException e) { 79 | // Ignore ... 80 | } 81 | } 82 | } 83 | System.out.println("- Downloading from: : " + url); 84 | 85 | File outputFile = new File(baseDirectory.getAbsolutePath(), MAVEN_WRAPPER_JAR_PATH); 86 | if(!outputFile.getParentFile().exists()) { 87 | if(!outputFile.getParentFile().mkdirs()) { 88 | System.out.println( 89 | "- ERROR creating output direcrory '" + outputFile.getParentFile().getAbsolutePath() + "'"); 90 | } 91 | } 92 | System.out.println("- Downloading to: " + outputFile.getAbsolutePath()); 93 | try { 94 | downloadFileFromURL(url, outputFile); 95 | System.out.println("Done"); 96 | System.exit(0); 97 | } catch (Throwable e) { 98 | System.out.println("- Error downloading"); 99 | e.printStackTrace(); 100 | System.exit(1); 101 | } 102 | } 103 | 104 | private static void downloadFileFromURL(String urlString, File destination) throws Exception { 105 | URL website = new URL(urlString); 106 | ReadableByteChannel rbc; 107 | rbc = Channels.newChannel(website.openStream()); 108 | FileOutputStream fos = new FileOutputStream(destination); 109 | fos.getChannel().transferFrom(rbc, 0, Long.MAX_VALUE); 110 | fos.close(); 111 | rbc.close(); 112 | } 113 | 114 | } 115 | -------------------------------------------------------------------------------- /java-see/.mvn/wrapper/maven-wrapper.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cloud-gov/cf-hello-worlds/108bcd5031e01312243001254d6d1ddbdb8d8608/java-see/.mvn/wrapper/maven-wrapper.jar -------------------------------------------------------------------------------- /java-see/.mvn/wrapper/maven-wrapper.properties: -------------------------------------------------------------------------------- 1 | distributionUrl=https://repo.maven.apache.org/maven2/org/apache/maven/apache-maven/3.6.0/apache-maven-3.6.0-bin.zip 2 | -------------------------------------------------------------------------------- /java-see/INSTRUCTIONS.md: -------------------------------------------------------------------------------- 1 | # How to deploy the Hello World Java app 2 | 3 | ## Build the application 4 | 5 | First, use the following command to download all of the dependencies and create the application for deploying. 6 | 7 | ### Mac OS X, Unix, or Linux 8 | 9 | ```bash 10 | ./mvnw compile 11 | ./mvnw package 12 | 13 | ``` 14 | 15 | ## Windows 16 | 17 | ```powershell 18 | .\mvnw.bat compile 19 | .\mvnw.bat package 20 | 21 | ``` 22 | 23 | ## Deploy the application 24 | 25 | Then follow the usual process for deploying 26 | 27 | ```bash 28 | cf push 29 | ``` 30 | -------------------------------------------------------------------------------- /java-see/README.md: -------------------------------------------------------------------------------- 1 | INSTRUCTIONS.md -------------------------------------------------------------------------------- /java-see/build-java-see.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | set -ex 4 | 5 | export TERM=${TERM:-dumb} 6 | 7 | wget https://download.oracle.com/java/21/latest/jdk-21_linux-x64_bin.tar.gz 8 | tar -xvf jdk-21_linux-x64_bin.tar.gz 9 | VERSION=$(find . -maxdepth 1 -mindepth 1 -name "jdk-21.*" | sed 's/^..//') 10 | mv $VERSION /opt/ 11 | 12 | JAVA_HOME="/opt/${VERSION}" 13 | export JAVA_HOME 14 | PATH="JAVA_HOME/bin:$PATH" 15 | export PATH 16 | 17 | pushd cf-hello-worlds/java-see 18 | ./mvnw compile 19 | ./mvnw package 20 | popd 21 | 22 | cp -r cf-hello-worlds/* cf-hello-worlds-build/ 23 | -------------------------------------------------------------------------------- /java-see/build-java-see.yml: -------------------------------------------------------------------------------- 1 | --- 2 | platform: linux 3 | 4 | image_resource: 5 | type: registry-image 6 | source: 7 | aws_access_key_id: ((ecr_aws_key)) 8 | aws_secret_access_key: ((ecr_aws_secret)) 9 | repository: general-task 10 | aws_region: us-gov-west-1 11 | tag: latest 12 | 13 | inputs: 14 | - name: cf-hello-worlds 15 | outputs: 16 | - name: cf-hello-worlds-build 17 | 18 | run: 19 | path: cf-hello-worlds/java-see/build-java-see.sh 20 | -------------------------------------------------------------------------------- /java-see/hello-world.iml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | 74 | 75 | 76 | 77 | 78 | 79 | 80 | 81 | 82 | 83 | 84 | 85 | 86 | 87 | 88 | 89 | 90 | 91 | 92 | 93 | 94 | 95 | 96 | -------------------------------------------------------------------------------- /java-see/manifest.yml: -------------------------------------------------------------------------------- 1 | --- 2 | applications: 3 | - name: test-java 4 | random-route: true 5 | memory: 768M 6 | path: target/hello-world-0.0.1-SNAPSHOT.jar 7 | env: 8 | JBP_CONFIG_OPEN_JDK_JRE: '{ jre: { version: 11.+ }}' 9 | -------------------------------------------------------------------------------- /java-see/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 | # https://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 | # Maven2 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 /etc/mavenrc ] ; then 40 | . /etc/mavenrc 41 | fi 42 | 43 | if [ -f "$HOME/.mavenrc" ] ; then 44 | . "$HOME/.mavenrc" 45 | fi 46 | 47 | fi 48 | 49 | # OS specific support. $var _must_ be set to either true or false. 50 | cygwin=false; 51 | darwin=false; 52 | mingw=false 53 | case "`uname`" in 54 | CYGWIN*) cygwin=true ;; 55 | MINGW*) mingw=true;; 56 | Darwin*) darwin=true 57 | # Use /usr/libexec/java_home if available, otherwise fall back to /Library/Java/Home 58 | # See https://developer.apple.com/library/mac/qa/qa1170/_index.html 59 | if [ -z "$JAVA_HOME" ]; then 60 | if [ -x "/usr/libexec/java_home" ]; then 61 | export JAVA_HOME="`/usr/libexec/java_home`" 62 | else 63 | export JAVA_HOME="/Library/Java/Home" 64 | fi 65 | fi 66 | ;; 67 | esac 68 | 69 | if [ -z "$JAVA_HOME" ] ; then 70 | if [ -r /etc/gentoo-release ] ; then 71 | JAVA_HOME=`java-config --jre-home` 72 | fi 73 | fi 74 | 75 | if [ -z "$M2_HOME" ] ; then 76 | ## resolve links - $0 may be a link to maven's home 77 | PRG="$0" 78 | 79 | # need this for relative symlinks 80 | while [ -h "$PRG" ] ; do 81 | ls=`ls -ld "$PRG"` 82 | link=`expr "$ls" : '.*-> \(.*\)$'` 83 | if expr "$link" : '/.*' > /dev/null; then 84 | PRG="$link" 85 | else 86 | PRG="`dirname "$PRG"`/$link" 87 | fi 88 | done 89 | 90 | saveddir=`pwd` 91 | 92 | M2_HOME=`dirname "$PRG"`/.. 93 | 94 | # make it fully qualified 95 | M2_HOME=`cd "$M2_HOME" && pwd` 96 | 97 | cd "$saveddir" 98 | # echo Using m2 at $M2_HOME 99 | fi 100 | 101 | # For Cygwin, ensure paths are in UNIX format before anything is touched 102 | if $cygwin ; then 103 | [ -n "$M2_HOME" ] && 104 | M2_HOME=`cygpath --unix "$M2_HOME"` 105 | [ -n "$JAVA_HOME" ] && 106 | JAVA_HOME=`cygpath --unix "$JAVA_HOME"` 107 | [ -n "$CLASSPATH" ] && 108 | CLASSPATH=`cygpath --path --unix "$CLASSPATH"` 109 | fi 110 | 111 | # For Mingw, ensure paths are in UNIX format before anything is touched 112 | if $mingw ; then 113 | [ -n "$M2_HOME" ] && 114 | M2_HOME="`(cd "$M2_HOME"; pwd)`" 115 | [ -n "$JAVA_HOME" ] && 116 | JAVA_HOME="`(cd "$JAVA_HOME"; pwd)`" 117 | # TODO classpath? 118 | fi 119 | 120 | if [ -z "$JAVA_HOME" ]; then 121 | javaExecutable="`which javac`" 122 | if [ -n "$javaExecutable" ] && ! [ "`expr \"$javaExecutable\" : '\([^ ]*\)'`" = "no" ]; then 123 | # readlink(1) is not available as standard on Solaris 10. 124 | readLink=`which readlink` 125 | if [ ! `expr "$readLink" : '\([^ ]*\)'` = "no" ]; then 126 | if $darwin ; then 127 | javaHome="`dirname \"$javaExecutable\"`" 128 | javaExecutable="`cd \"$javaHome\" && pwd -P`/javac" 129 | else 130 | javaExecutable="`readlink -f \"$javaExecutable\"`" 131 | fi 132 | javaHome="`dirname \"$javaExecutable\"`" 133 | javaHome=`expr "$javaHome" : '\(.*\)/bin'` 134 | JAVA_HOME="$javaHome" 135 | export JAVA_HOME 136 | fi 137 | fi 138 | fi 139 | 140 | if [ -z "$JAVACMD" ] ; then 141 | if [ -n "$JAVA_HOME" ] ; then 142 | if [ -x "$JAVA_HOME/jre/sh/java" ] ; then 143 | # IBM's JDK on AIX uses strange locations for the executables 144 | JAVACMD="$JAVA_HOME/jre/sh/java" 145 | else 146 | JAVACMD="$JAVA_HOME/bin/java" 147 | fi 148 | else 149 | JAVACMD="`which java`" 150 | fi 151 | fi 152 | 153 | if [ ! -x "$JAVACMD" ] ; then 154 | echo "Error: JAVA_HOME is not defined correctly." >&2 155 | echo " We cannot execute $JAVACMD" >&2 156 | exit 1 157 | fi 158 | 159 | if [ -z "$JAVA_HOME" ] ; then 160 | echo "Warning: JAVA_HOME environment variable is not set." 161 | fi 162 | 163 | CLASSWORLDS_LAUNCHER=org.codehaus.plexus.classworlds.launcher.Launcher 164 | 165 | # traverses directory structure from process work directory to filesystem root 166 | # first directory with .mvn subdirectory is considered project base directory 167 | find_maven_basedir() { 168 | 169 | if [ -z "$1" ] 170 | then 171 | echo "Path not specified to find_maven_basedir" 172 | return 1 173 | fi 174 | 175 | basedir="$1" 176 | wdir="$1" 177 | while [ "$wdir" != '/' ] ; do 178 | if [ -d "$wdir"/.mvn ] ; then 179 | basedir=$wdir 180 | break 181 | fi 182 | # workaround for JBEAP-8937 (on Solaris 10/Sparc) 183 | if [ -d "${wdir}" ]; then 184 | wdir=`cd "$wdir/.."; pwd` 185 | fi 186 | # end of workaround 187 | done 188 | echo "${basedir}" 189 | } 190 | 191 | # concatenates all lines of a file 192 | concat_lines() { 193 | if [ -f "$1" ]; then 194 | echo "$(tr -s '\n' ' ' < "$1")" 195 | fi 196 | } 197 | 198 | BASE_DIR=`find_maven_basedir "$(pwd)"` 199 | if [ -z "$BASE_DIR" ]; then 200 | exit 1; 201 | fi 202 | 203 | ########################################################################################## 204 | # Extension to allow automatically downloading the maven-wrapper.jar from Maven-central 205 | # This allows using the maven wrapper in projects that prohibit checking in binary data. 206 | ########################################################################################## 207 | if [ -r "$BASE_DIR/.mvn/wrapper/maven-wrapper.jar" ]; then 208 | if [ "$MVNW_VERBOSE" = true ]; then 209 | echo "Found .mvn/wrapper/maven-wrapper.jar" 210 | fi 211 | else 212 | if [ "$MVNW_VERBOSE" = true ]; then 213 | echo "Couldn't find .mvn/wrapper/maven-wrapper.jar, downloading it ..." 214 | fi 215 | jarUrl="https://repo.maven.apache.org/maven2/io/takari/maven-wrapper/0.4.2/maven-wrapper-0.4.2.jar" 216 | while IFS="=" read key value; do 217 | case "$key" in (wrapperUrl) jarUrl="$value"; break ;; 218 | esac 219 | done < "$BASE_DIR/.mvn/wrapper/maven-wrapper.properties" 220 | if [ "$MVNW_VERBOSE" = true ]; then 221 | echo "Downloading from: $jarUrl" 222 | fi 223 | wrapperJarPath="$BASE_DIR/.mvn/wrapper/maven-wrapper.jar" 224 | 225 | if command -v wget > /dev/null; then 226 | if [ "$MVNW_VERBOSE" = true ]; then 227 | echo "Found wget ... using wget" 228 | fi 229 | wget "$jarUrl" -O "$wrapperJarPath" 230 | elif command -v curl > /dev/null; then 231 | if [ "$MVNW_VERBOSE" = true ]; then 232 | echo "Found curl ... using curl" 233 | fi 234 | curl -o "$wrapperJarPath" "$jarUrl" 235 | else 236 | if [ "$MVNW_VERBOSE" = true ]; then 237 | echo "Falling back to using Java to download" 238 | fi 239 | javaClass="$BASE_DIR/.mvn/wrapper/MavenWrapperDownloader.java" 240 | if [ -e "$javaClass" ]; then 241 | if [ ! -e "$BASE_DIR/.mvn/wrapper/MavenWrapperDownloader.class" ]; then 242 | if [ "$MVNW_VERBOSE" = true ]; then 243 | echo " - Compiling MavenWrapperDownloader.java ..." 244 | fi 245 | # Compiling the Java class 246 | ("$JAVA_HOME/bin/javac" "$javaClass") 247 | fi 248 | if [ -e "$BASE_DIR/.mvn/wrapper/MavenWrapperDownloader.class" ]; then 249 | # Running the downloader 250 | if [ "$MVNW_VERBOSE" = true ]; then 251 | echo " - Running MavenWrapperDownloader.java ..." 252 | fi 253 | ("$JAVA_HOME/bin/java" -cp .mvn/wrapper MavenWrapperDownloader "$MAVEN_PROJECTBASEDIR") 254 | fi 255 | fi 256 | fi 257 | fi 258 | ########################################################################################## 259 | # End of extension 260 | ########################################################################################## 261 | 262 | export MAVEN_PROJECTBASEDIR=${MAVEN_BASEDIR:-"$BASE_DIR"} 263 | if [ "$MVNW_VERBOSE" = true ]; then 264 | echo $MAVEN_PROJECTBASEDIR 265 | fi 266 | MAVEN_OPTS="$(concat_lines "$MAVEN_PROJECTBASEDIR/.mvn/jvm.config") $MAVEN_OPTS" 267 | 268 | # For Cygwin, switch paths to Windows format before running java 269 | if $cygwin; then 270 | [ -n "$M2_HOME" ] && 271 | M2_HOME=`cygpath --path --windows "$M2_HOME"` 272 | [ -n "$JAVA_HOME" ] && 273 | JAVA_HOME=`cygpath --path --windows "$JAVA_HOME"` 274 | [ -n "$CLASSPATH" ] && 275 | CLASSPATH=`cygpath --path --windows "$CLASSPATH"` 276 | [ -n "$MAVEN_PROJECTBASEDIR" ] && 277 | MAVEN_PROJECTBASEDIR=`cygpath --path --windows "$MAVEN_PROJECTBASEDIR"` 278 | fi 279 | 280 | WRAPPER_LAUNCHER=org.apache.maven.wrapper.MavenWrapperMain 281 | 282 | exec "$JAVACMD" \ 283 | $MAVEN_OPTS \ 284 | -classpath "$MAVEN_PROJECTBASEDIR/.mvn/wrapper/maven-wrapper.jar" \ 285 | "-Dmaven.home=${M2_HOME}" "-Dmaven.multiModuleProjectDirectory=${MAVEN_PROJECTBASEDIR}" \ 286 | ${WRAPPER_LAUNCHER} $MAVEN_CONFIG "$@" 287 | -------------------------------------------------------------------------------- /java-see/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 https://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 Maven2 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 key stroke 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 my 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 "%HOME%\mavenrc_pre.bat" call "%HOME%\mavenrc_pre.bat" 50 | if exist "%HOME%\mavenrc_pre.cmd" call "%HOME%\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/io/takari/maven-wrapper/0.4.2/maven-wrapper-0.4.2.jar" 124 | FOR /F "tokens=1,2 delims==" %%A IN (%MAVEN_PROJECTBASEDIR%\.mvn\wrapper\maven-wrapper.properties) DO ( 125 | IF "%%A"=="wrapperUrl" SET DOWNLOAD_URL=%%B 126 | ) 127 | 128 | @REM Extension to allow automatically downloading the maven-wrapper.jar from Maven-central 129 | @REM This allows using the maven wrapper in projects that prohibit checking in binary data. 130 | if exist %WRAPPER_JAR% ( 131 | echo Found %WRAPPER_JAR% 132 | ) else ( 133 | echo Couldn't find %WRAPPER_JAR%, downloading it ... 134 | echo Downloading from: %DOWNLOAD_URL% 135 | powershell -Command "(New-Object Net.WebClient).DownloadFile('%DOWNLOAD_URL%', '%WRAPPER_JAR%')" 136 | echo Finished downloading %WRAPPER_JAR% 137 | ) 138 | @REM End of extension 139 | 140 | %MAVEN_JAVA_EXE% %JVM_CONFIG_MAVEN_PROPS% %MAVEN_OPTS% %MAVEN_DEBUG_OPTS% -classpath %WRAPPER_JAR% "-Dmaven.multiModuleProjectDirectory=%MAVEN_PROJECTBASEDIR%" %WRAPPER_LAUNCHER% %MAVEN_CONFIG% %* 141 | if ERRORLEVEL 1 goto error 142 | goto end 143 | 144 | :error 145 | set ERROR_CODE=1 146 | 147 | :end 148 | @endlocal & set ERROR_CODE=%ERROR_CODE% 149 | 150 | if not "%MAVEN_SKIP_RC%" == "" goto skipRcPost 151 | @REM check for post script, once with legacy .bat ending and once with .cmd ending 152 | if exist "%HOME%\mavenrc_post.bat" call "%HOME%\mavenrc_post.bat" 153 | if exist "%HOME%\mavenrc_post.cmd" call "%HOME%\mavenrc_post.cmd" 154 | :skipRcPost 155 | 156 | @REM pause the script if MAVEN_BATCH_PAUSE is set to 'on' 157 | if "%MAVEN_BATCH_PAUSE%" == "on" pause 158 | 159 | if "%MAVEN_TERMINATE_CMD%" == "on" exit %ERROR_CODE% 160 | 161 | exit /B %ERROR_CODE% 162 | -------------------------------------------------------------------------------- /java-see/pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 4 | 4.0.0 5 | 6 | org.springframework.boot 7 | spring-boot-starter-parent 8 | 2.2.0.M3 9 | 10 | 11 | gov.cloud.eng 12 | hello-world 13 | 0.0.1-SNAPSHOT 14 | hello-world 15 | Demo project for Spring Boot 16 | 17 | 18 | 11 19 | 20 | 21 | 22 | 23 | org.springframework.boot 24 | spring-boot-starter 25 | 26 | 27 | 28 | org.springframework.boot 29 | spring-boot-starter-test 30 | test 31 | 32 | 33 | org.junit.vintage 34 | junit-vintage-engine 35 | 36 | 37 | junit 38 | junit 39 | 40 | 41 | 42 | 43 | 44 | org.springframework.boot 45 | spring-boot-starter-web 46 | 47 | 48 | 49 | 50 | 51 | 52 | org.springframework.boot 53 | spring-boot-maven-plugin 54 | 55 | 56 | 57 | 58 | 59 | 60 | spring-snapshots 61 | Spring Snapshots 62 | https://repo.spring.io/snapshot 63 | 64 | true 65 | 66 | 67 | 68 | spring-milestones 69 | Spring Milestones 70 | https://repo.spring.io/milestone 71 | 72 | 73 | 74 | 75 | spring-snapshots 76 | Spring Snapshots 77 | https://repo.spring.io/snapshot 78 | 79 | true 80 | 81 | 82 | 83 | spring-milestones 84 | Spring Milestones 85 | https://repo.spring.io/milestone 86 | 87 | 88 | 89 | 90 | -------------------------------------------------------------------------------- /java-see/src/main/java/gov/cloud/eng/helloworld/HelloController.java: -------------------------------------------------------------------------------- 1 | package gov.cloud.eng.helloworld; 2 | 3 | import org.springframework.web.bind.annotation.RestController; 4 | import org.springframework.web.bind.annotation.RequestMapping; 5 | 6 | @RestController 7 | public class HelloController { 8 | 9 | @RequestMapping("/") 10 | public String index() { 11 | return "Greetings from cloud.gov!"; 12 | } 13 | 14 | } -------------------------------------------------------------------------------- /java-see/src/main/java/gov/cloud/eng/helloworld/HelloWorldApplication.java: -------------------------------------------------------------------------------- 1 | package gov.cloud.eng.helloworld; 2 | 3 | import org.springframework.boot.SpringApplication; 4 | import org.springframework.boot.autoconfigure.SpringBootApplication; 5 | 6 | @SpringBootApplication 7 | public class HelloWorldApplication { 8 | 9 | public static void main(String[] args) { 10 | SpringApplication.run(HelloWorldApplication.class, args); 11 | } 12 | 13 | } 14 | -------------------------------------------------------------------------------- /java-see/src/main/resources/application.properties: -------------------------------------------------------------------------------- 1 | 2 | -------------------------------------------------------------------------------- /java-see/src/test/java/gov/cloud/eng/helloworld/HelloWorldApplicationTests.java: -------------------------------------------------------------------------------- 1 | package gov.cloud.eng.helloworld; 2 | 3 | import org.junit.jupiter.api.Test; 4 | import org.springframework.boot.test.context.SpringBootTest; 5 | 6 | @SpringBootTest 7 | class HelloWorldApplicationTests { 8 | 9 | @Test 10 | void contextLoads() { 11 | } 12 | 13 | } 14 | -------------------------------------------------------------------------------- /java-spring-actuator/.mvn/wrapper/MavenWrapperDownloader.java: -------------------------------------------------------------------------------- 1 | /* 2 | Licensed to the Apache Software Foundation (ASF) under one 3 | or more contributor license agreements. See the NOTICE file 4 | distributed with this work for additional information 5 | regarding copyright ownership. The ASF licenses this file 6 | to you under the Apache License, Version 2.0 (the 7 | "License"); you may not use this file except in compliance 8 | with the License. You may obtain a copy of the License at 9 | 10 | https://www.apache.org/licenses/LICENSE-2.0 11 | 12 | Unless required by applicable law or agreed to in writing, 13 | software distributed under the License is distributed on an 14 | "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 15 | KIND, either express or implied. See the License for the 16 | specific language governing permissions and limitations 17 | under the License. 18 | */ 19 | 20 | import java.io.File; 21 | import java.io.FileInputStream; 22 | import java.io.FileOutputStream; 23 | import java.io.IOException; 24 | import java.net.URL; 25 | import java.nio.channels.Channels; 26 | import java.nio.channels.ReadableByteChannel; 27 | import java.util.Properties; 28 | 29 | public class MavenWrapperDownloader { 30 | 31 | /** 32 | * Default URL to download the maven-wrapper.jar from, if no 'downloadUrl' is provided. 33 | */ 34 | private static final String DEFAULT_DOWNLOAD_URL = 35 | "https://repo.maven.apache.org/maven2/io/takari/maven-wrapper/0.4.2/maven-wrapper-0.4.2.jar"; 36 | 37 | /** 38 | * Path to the maven-wrapper.properties file, which might contain a downloadUrl property to 39 | * use instead of the default one. 40 | */ 41 | private static final String MAVEN_WRAPPER_PROPERTIES_PATH = 42 | ".mvn/wrapper/maven-wrapper.properties"; 43 | 44 | /** 45 | * Path where the maven-wrapper.jar will be saved to. 46 | */ 47 | private static final String MAVEN_WRAPPER_JAR_PATH = 48 | ".mvn/wrapper/maven-wrapper.jar"; 49 | 50 | /** 51 | * Name of the property which should be used to override the default download url for the wrapper. 52 | */ 53 | private static final String PROPERTY_NAME_WRAPPER_URL = "wrapperUrl"; 54 | 55 | public static void main(String args[]) { 56 | System.out.println("- Downloader started"); 57 | File baseDirectory = new File(args[0]); 58 | System.out.println("- Using base directory: " + baseDirectory.getAbsolutePath()); 59 | 60 | // If the maven-wrapper.properties exists, read it and check if it contains a custom 61 | // wrapperUrl parameter. 62 | File mavenWrapperPropertyFile = new File(baseDirectory, MAVEN_WRAPPER_PROPERTIES_PATH); 63 | String url = DEFAULT_DOWNLOAD_URL; 64 | if(mavenWrapperPropertyFile.exists()) { 65 | FileInputStream mavenWrapperPropertyFileInputStream = null; 66 | try { 67 | mavenWrapperPropertyFileInputStream = new FileInputStream(mavenWrapperPropertyFile); 68 | Properties mavenWrapperProperties = new Properties(); 69 | mavenWrapperProperties.load(mavenWrapperPropertyFileInputStream); 70 | url = mavenWrapperProperties.getProperty(PROPERTY_NAME_WRAPPER_URL, url); 71 | } catch (IOException e) { 72 | System.out.println("- ERROR loading '" + MAVEN_WRAPPER_PROPERTIES_PATH + "'"); 73 | } finally { 74 | try { 75 | if(mavenWrapperPropertyFileInputStream != null) { 76 | mavenWrapperPropertyFileInputStream.close(); 77 | } 78 | } catch (IOException e) { 79 | // Ignore ... 80 | } 81 | } 82 | } 83 | System.out.println("- Downloading from: : " + url); 84 | 85 | File outputFile = new File(baseDirectory.getAbsolutePath(), MAVEN_WRAPPER_JAR_PATH); 86 | if(!outputFile.getParentFile().exists()) { 87 | if(!outputFile.getParentFile().mkdirs()) { 88 | System.out.println( 89 | "- ERROR creating output direcrory '" + outputFile.getParentFile().getAbsolutePath() + "'"); 90 | } 91 | } 92 | System.out.println("- Downloading to: " + outputFile.getAbsolutePath()); 93 | try { 94 | downloadFileFromURL(url, outputFile); 95 | System.out.println("Done"); 96 | System.exit(0); 97 | } catch (Throwable e) { 98 | System.out.println("- Error downloading"); 99 | e.printStackTrace(); 100 | System.exit(1); 101 | } 102 | } 103 | 104 | private static void downloadFileFromURL(String urlString, File destination) throws Exception { 105 | URL website = new URL(urlString); 106 | ReadableByteChannel rbc; 107 | rbc = Channels.newChannel(website.openStream()); 108 | FileOutputStream fos = new FileOutputStream(destination); 109 | fos.getChannel().transferFrom(rbc, 0, Long.MAX_VALUE); 110 | fos.close(); 111 | rbc.close(); 112 | } 113 | 114 | } 115 | -------------------------------------------------------------------------------- /java-spring-actuator/.mvn/wrapper/maven-wrapper.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cloud-gov/cf-hello-worlds/108bcd5031e01312243001254d6d1ddbdb8d8608/java-spring-actuator/.mvn/wrapper/maven-wrapper.jar -------------------------------------------------------------------------------- /java-spring-actuator/.mvn/wrapper/maven-wrapper.properties: -------------------------------------------------------------------------------- 1 | distributionUrl=https://repo.maven.apache.org/maven2/org/apache/maven/apache-maven/3.6.0/apache-maven-3.6.0-bin.zip 2 | -------------------------------------------------------------------------------- /java-spring-actuator/README.md: -------------------------------------------------------------------------------- 1 | # How to deploy the Java Spring Actuator example app 2 | 3 | This example application demonstrates the ability to: 4 | 5 | - [route traffic to a custom port on a CloudFoundry application][custom-ports] 6 | - [use multiple routes to connect to multiple ports opened by an application][custom-ports] 7 | - [connect to an application using an internal route](https://docs.cloudfoundry.org/devguide/deploy-apps/routes-domains.html#internal-routes) 8 | - [use secure container-to-container networking with TLS][secure-c2c-with-tls] 9 | 10 | ## Build the application 11 | 12 | First, use the following command to download all of the dependencies and create the application for deploying. 13 | 14 | ### Mac OS X, Unix, or Linux 15 | 16 | ```bash 17 | ./mvnw compile 18 | ./mvnw package 19 | ``` 20 | 21 | ## Windows 22 | 23 | ```powershell 24 | .\mvnw.cmd compile 25 | .\mvnw.cmd package 26 | ``` 27 | 28 | ## Deploy the application and configure the networking 29 | 30 | 1. After building the application, follow the usual process for deploying: 31 | 32 | ```bash 33 | cf push --var app-domain=app.cloud.gov 34 | ``` 35 | 36 | 2. Use the provided shell script to update the route for the Spring Boot process to listen on port `8081` (configured in [`manifest.yml`](./manifest.yml)): 37 | 38 | ```shell 39 | ./set-route-custom-port.sh test-java-spring-actuator test-java-spring-boot 8081 40 | ``` 41 | 42 | 3. Restart the app so the route is properly handled: 43 | 44 | ```shell 45 | cf restart test-java-spring-actuator 46 | ``` 47 | 48 | 4. Add a network policy allowing a separate app to reach the internal route for the Actuator process: 49 | 50 | ```shell 51 | cf add-network-policy SOURCE_APP test-java-spring-actuator --protocol tcp --port 61443 52 | ``` 53 | 54 | You should be able to successfully make a request to the route for the Spring Boot process: 55 | 56 | ```shell 57 | $ curl https://test-java-spring-boot.app.cloud.gov/ 58 | Greetings from cloud.gov! 59 | ``` 60 | 61 | And if you `cf ssh SOURCE_APP`, you should be able to successfully make a request to the health check endpoint for the Acutator component: 62 | 63 | ```shell 64 | $ curl https://actuator.apps.internal:61443/actuator/health 65 | {"status":"UP"} 66 | ``` 67 | 68 | ## How it works 69 | 70 | ```mermaid 71 | flowchart LR 72 | spring-boot-url(test-java-spring.app.cloud.gov) 73 | user[User] --> spring-boot-url:::traffic 74 | spring-boot-url --> gorouter[Gorouter] 75 | gorouter --> spring-boot-port:::traffic 76 | internal-app-route --> spring-actuator-port:::traffic 77 | 78 | subgraph overlay-network[overlay network] 79 | internal-app-route(actuator.apps.internal:61443) 80 | end 81 | subgraph diego-cell[diego-cell VM] 82 | source-app[source app] 83 | source-app:::app --> internal-app-route:::traffic 84 | 85 | subgraph test-java-spring-actuator[test-java-spring-actuator app] 86 | spring-boot-port(:8081) --> spring-boot-process[Spring Boot] 87 | spring-actuator-port(:8080) --> spring-actuator-process[Actuator] 88 | end 89 | end 90 | ``` 91 | 92 | There are two processes running in the `test-java-spring-actuator` app: 93 | 94 | - Spring Boot on port `8081` (configured in [`manifest.yml`](./manifest.yml)) 95 | - Actuator on port `8080` (configured in [`src/main/resources/application.properties`](./src/main/resources/application.properties)) 96 | 97 | Traffic is routed to the processes as follows: 98 | 99 | - Requests to the route `test-java-spring.app.cloud.gov` go over the public internet and hit the Gorouter, which directs the request to port `8081` on the `test-java-spring-actuator` app. By default, a route would usually go to port `8080` on the app, but we updated the route to use port `8081` using the [`set-route-custom-port.sh`](./set-route-custom-port.sh) script. 100 | - Requests to the route `actuator.apps.internal:61443` from a separate application go through a container overlay network to the `test-java-spring-actuator` app. These requests **do not go out to the public internet**. By default, [requests to port `61443` for secure container-to-container networking are proxied to port `8080`](secure-c2c-with-tls), so the request hits port `8080` in the container and thus the Actuator process. 101 | 102 | ## Helpful resources 103 | 104 | - [Configuring Cloud Foundry to route traffic to apps on custom ports][custom-ports] 105 | - [Building a RESTful Web Service with Spring Boot Actuator](https://spring.io/guides/gs/actuator-service/) 106 | - [Container to container networking in CloudFoundry](https://docs.cloudfoundry.org/concepts/understand-cf-networking.html) 107 | - [Securing Container-to-Container Networking with TLS][secure-c2c-with-tls] 108 | 109 | [custom-ports]: https://docs.cloudfoundry.org/devguide/custom-ports.html 110 | [secure-c2c-with-tls]: https://www.cloudfoundry.org/blog/secure-container-networking-with-tls/ 111 | -------------------------------------------------------------------------------- /java-spring-actuator/manifest.yml: -------------------------------------------------------------------------------- 1 | --- 2 | applications: 3 | - name: test-java-spring-actuator 4 | random-route: true 5 | buildpacks: 6 | - java_buildpack 7 | memory: 1G 8 | path: target/java-spring-actuator-0.0.1-SNAPSHOT.jar 9 | routes: 10 | - route: test-java-spring-boot.((app-domain)) 11 | - route: actuator.apps.internal 12 | env: 13 | JBP_CONFIG_OPEN_JDK_JRE: '{ jre: { version: 17.+ }}' 14 | JBP_CONFIG_SPRING_AUTO_RECONFIGURATION: '{enabled: false}' 15 | # Required to override SERVER_PORT env var set by buildpack and load 16 | # default Spring application on port 8081 17 | SPRING_APPLICATION_JSON: '{"server.port":8081}' 18 | 19 | -------------------------------------------------------------------------------- /java-spring-actuator/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 | # https://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 | # Maven2 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 /etc/mavenrc ] ; then 40 | . /etc/mavenrc 41 | fi 42 | 43 | if [ -f "$HOME/.mavenrc" ] ; then 44 | . "$HOME/.mavenrc" 45 | fi 46 | 47 | fi 48 | 49 | # OS specific support. $var _must_ be set to either true or false. 50 | cygwin=false; 51 | darwin=false; 52 | mingw=false 53 | case "`uname`" in 54 | CYGWIN*) cygwin=true ;; 55 | MINGW*) mingw=true;; 56 | Darwin*) darwin=true 57 | # Use /usr/libexec/java_home if available, otherwise fall back to /Library/Java/Home 58 | # See https://developer.apple.com/library/mac/qa/qa1170/_index.html 59 | if [ -z "$JAVA_HOME" ]; then 60 | if [ -x "/usr/libexec/java_home" ]; then 61 | export JAVA_HOME="`/usr/libexec/java_home`" 62 | else 63 | export JAVA_HOME="/Library/Java/Home" 64 | fi 65 | fi 66 | ;; 67 | esac 68 | 69 | if [ -z "$JAVA_HOME" ] ; then 70 | if [ -r /etc/gentoo-release ] ; then 71 | JAVA_HOME=`java-config --jre-home` 72 | fi 73 | fi 74 | 75 | if [ -z "$M2_HOME" ] ; then 76 | ## resolve links - $0 may be a link to maven's home 77 | PRG="$0" 78 | 79 | # need this for relative symlinks 80 | while [ -h "$PRG" ] ; do 81 | ls=`ls -ld "$PRG"` 82 | link=`expr "$ls" : '.*-> \(.*\)$'` 83 | if expr "$link" : '/.*' > /dev/null; then 84 | PRG="$link" 85 | else 86 | PRG="`dirname "$PRG"`/$link" 87 | fi 88 | done 89 | 90 | saveddir=`pwd` 91 | 92 | M2_HOME=`dirname "$PRG"`/.. 93 | 94 | # make it fully qualified 95 | M2_HOME=`cd "$M2_HOME" && pwd` 96 | 97 | cd "$saveddir" 98 | # echo Using m2 at $M2_HOME 99 | fi 100 | 101 | # For Cygwin, ensure paths are in UNIX format before anything is touched 102 | if $cygwin ; then 103 | [ -n "$M2_HOME" ] && 104 | M2_HOME=`cygpath --unix "$M2_HOME"` 105 | [ -n "$JAVA_HOME" ] && 106 | JAVA_HOME=`cygpath --unix "$JAVA_HOME"` 107 | [ -n "$CLASSPATH" ] && 108 | CLASSPATH=`cygpath --path --unix "$CLASSPATH"` 109 | fi 110 | 111 | # For Mingw, ensure paths are in UNIX format before anything is touched 112 | if $mingw ; then 113 | [ -n "$M2_HOME" ] && 114 | M2_HOME="`(cd "$M2_HOME"; pwd)`" 115 | [ -n "$JAVA_HOME" ] && 116 | JAVA_HOME="`(cd "$JAVA_HOME"; pwd)`" 117 | # TODO classpath? 118 | fi 119 | 120 | if [ -z "$JAVA_HOME" ]; then 121 | javaExecutable="`which javac`" 122 | if [ -n "$javaExecutable" ] && ! [ "`expr \"$javaExecutable\" : '\([^ ]*\)'`" = "no" ]; then 123 | # readlink(1) is not available as standard on Solaris 10. 124 | readLink=`which readlink` 125 | if [ ! `expr "$readLink" : '\([^ ]*\)'` = "no" ]; then 126 | if $darwin ; then 127 | javaHome="`dirname \"$javaExecutable\"`" 128 | javaExecutable="`cd \"$javaHome\" && pwd -P`/javac" 129 | else 130 | javaExecutable="`readlink -f \"$javaExecutable\"`" 131 | fi 132 | javaHome="`dirname \"$javaExecutable\"`" 133 | javaHome=`expr "$javaHome" : '\(.*\)/bin'` 134 | JAVA_HOME="$javaHome" 135 | export JAVA_HOME 136 | fi 137 | fi 138 | fi 139 | 140 | if [ -z "$JAVACMD" ] ; then 141 | if [ -n "$JAVA_HOME" ] ; then 142 | if [ -x "$JAVA_HOME/jre/sh/java" ] ; then 143 | # IBM's JDK on AIX uses strange locations for the executables 144 | JAVACMD="$JAVA_HOME/jre/sh/java" 145 | else 146 | JAVACMD="$JAVA_HOME/bin/java" 147 | fi 148 | else 149 | JAVACMD="`which java`" 150 | fi 151 | fi 152 | 153 | if [ ! -x "$JAVACMD" ] ; then 154 | echo "Error: JAVA_HOME is not defined correctly." >&2 155 | echo " We cannot execute $JAVACMD" >&2 156 | exit 1 157 | fi 158 | 159 | if [ -z "$JAVA_HOME" ] ; then 160 | echo "Warning: JAVA_HOME environment variable is not set." 161 | fi 162 | 163 | CLASSWORLDS_LAUNCHER=org.codehaus.plexus.classworlds.launcher.Launcher 164 | 165 | # traverses directory structure from process work directory to filesystem root 166 | # first directory with .mvn subdirectory is considered project base directory 167 | find_maven_basedir() { 168 | 169 | if [ -z "$1" ] 170 | then 171 | echo "Path not specified to find_maven_basedir" 172 | return 1 173 | fi 174 | 175 | basedir="$1" 176 | wdir="$1" 177 | while [ "$wdir" != '/' ] ; do 178 | if [ -d "$wdir"/.mvn ] ; then 179 | basedir=$wdir 180 | break 181 | fi 182 | # workaround for JBEAP-8937 (on Solaris 10/Sparc) 183 | if [ -d "${wdir}" ]; then 184 | wdir=`cd "$wdir/.."; pwd` 185 | fi 186 | # end of workaround 187 | done 188 | echo "${basedir}" 189 | } 190 | 191 | # concatenates all lines of a file 192 | concat_lines() { 193 | if [ -f "$1" ]; then 194 | echo "$(tr -s '\n' ' ' < "$1")" 195 | fi 196 | } 197 | 198 | BASE_DIR=`find_maven_basedir "$(pwd)"` 199 | if [ -z "$BASE_DIR" ]; then 200 | exit 1; 201 | fi 202 | 203 | ########################################################################################## 204 | # Extension to allow automatically downloading the maven-wrapper.jar from Maven-central 205 | # This allows using the maven wrapper in projects that prohibit checking in binary data. 206 | ########################################################################################## 207 | if [ -r "$BASE_DIR/.mvn/wrapper/maven-wrapper.jar" ]; then 208 | if [ "$MVNW_VERBOSE" = true ]; then 209 | echo "Found .mvn/wrapper/maven-wrapper.jar" 210 | fi 211 | else 212 | if [ "$MVNW_VERBOSE" = true ]; then 213 | echo "Couldn't find .mvn/wrapper/maven-wrapper.jar, downloading it ..." 214 | fi 215 | jarUrl="https://repo.maven.apache.org/maven2/io/takari/maven-wrapper/0.4.2/maven-wrapper-0.4.2.jar" 216 | while IFS="=" read key value; do 217 | case "$key" in (wrapperUrl) jarUrl="$value"; break ;; 218 | esac 219 | done < "$BASE_DIR/.mvn/wrapper/maven-wrapper.properties" 220 | if [ "$MVNW_VERBOSE" = true ]; then 221 | echo "Downloading from: $jarUrl" 222 | fi 223 | wrapperJarPath="$BASE_DIR/.mvn/wrapper/maven-wrapper.jar" 224 | 225 | if command -v wget > /dev/null; then 226 | if [ "$MVNW_VERBOSE" = true ]; then 227 | echo "Found wget ... using wget" 228 | fi 229 | wget "$jarUrl" -O "$wrapperJarPath" 230 | elif command -v curl > /dev/null; then 231 | if [ "$MVNW_VERBOSE" = true ]; then 232 | echo "Found curl ... using curl" 233 | fi 234 | curl -o "$wrapperJarPath" "$jarUrl" 235 | else 236 | if [ "$MVNW_VERBOSE" = true ]; then 237 | echo "Falling back to using Java to download" 238 | fi 239 | javaClass="$BASE_DIR/.mvn/wrapper/MavenWrapperDownloader.java" 240 | if [ -e "$javaClass" ]; then 241 | if [ ! -e "$BASE_DIR/.mvn/wrapper/MavenWrapperDownloader.class" ]; then 242 | if [ "$MVNW_VERBOSE" = true ]; then 243 | echo " - Compiling MavenWrapperDownloader.java ..." 244 | fi 245 | # Compiling the Java class 246 | ("$JAVA_HOME/bin/javac" "$javaClass") 247 | fi 248 | if [ -e "$BASE_DIR/.mvn/wrapper/MavenWrapperDownloader.class" ]; then 249 | # Running the downloader 250 | if [ "$MVNW_VERBOSE" = true ]; then 251 | echo " - Running MavenWrapperDownloader.java ..." 252 | fi 253 | ("$JAVA_HOME/bin/java" -cp .mvn/wrapper MavenWrapperDownloader "$MAVEN_PROJECTBASEDIR") 254 | fi 255 | fi 256 | fi 257 | fi 258 | ########################################################################################## 259 | # End of extension 260 | ########################################################################################## 261 | 262 | export MAVEN_PROJECTBASEDIR=${MAVEN_BASEDIR:-"$BASE_DIR"} 263 | if [ "$MVNW_VERBOSE" = true ]; then 264 | echo $MAVEN_PROJECTBASEDIR 265 | fi 266 | MAVEN_OPTS="$(concat_lines "$MAVEN_PROJECTBASEDIR/.mvn/jvm.config") $MAVEN_OPTS" 267 | 268 | # For Cygwin, switch paths to Windows format before running java 269 | if $cygwin; then 270 | [ -n "$M2_HOME" ] && 271 | M2_HOME=`cygpath --path --windows "$M2_HOME"` 272 | [ -n "$JAVA_HOME" ] && 273 | JAVA_HOME=`cygpath --path --windows "$JAVA_HOME"` 274 | [ -n "$CLASSPATH" ] && 275 | CLASSPATH=`cygpath --path --windows "$CLASSPATH"` 276 | [ -n "$MAVEN_PROJECTBASEDIR" ] && 277 | MAVEN_PROJECTBASEDIR=`cygpath --path --windows "$MAVEN_PROJECTBASEDIR"` 278 | fi 279 | 280 | WRAPPER_LAUNCHER=org.apache.maven.wrapper.MavenWrapperMain 281 | 282 | exec "$JAVACMD" \ 283 | $MAVEN_OPTS \ 284 | -classpath "$MAVEN_PROJECTBASEDIR/.mvn/wrapper/maven-wrapper.jar" \ 285 | "-Dmaven.home=${M2_HOME}" "-Dmaven.multiModuleProjectDirectory=${MAVEN_PROJECTBASEDIR}" \ 286 | ${WRAPPER_LAUNCHER} $MAVEN_CONFIG "$@" 287 | -------------------------------------------------------------------------------- /java-spring-actuator/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 https://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 Maven2 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 key stroke 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 my 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 "%HOME%\mavenrc_pre.bat" call "%HOME%\mavenrc_pre.bat" 50 | if exist "%HOME%\mavenrc_pre.cmd" call "%HOME%\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/io/takari/maven-wrapper/0.4.2/maven-wrapper-0.4.2.jar" 124 | FOR /F "tokens=1,2 delims==" %%A IN (%MAVEN_PROJECTBASEDIR%\.mvn\wrapper\maven-wrapper.properties) DO ( 125 | IF "%%A"=="wrapperUrl" SET DOWNLOAD_URL=%%B 126 | ) 127 | 128 | @REM Extension to allow automatically downloading the maven-wrapper.jar from Maven-central 129 | @REM This allows using the maven wrapper in projects that prohibit checking in binary data. 130 | if exist %WRAPPER_JAR% ( 131 | echo Found %WRAPPER_JAR% 132 | ) else ( 133 | echo Couldn't find %WRAPPER_JAR%, downloading it ... 134 | echo Downloading from: %DOWNLOAD_URL% 135 | powershell -Command "(New-Object Net.WebClient).DownloadFile('%DOWNLOAD_URL%', '%WRAPPER_JAR%')" 136 | echo Finished downloading %WRAPPER_JAR% 137 | ) 138 | @REM End of extension 139 | 140 | %MAVEN_JAVA_EXE% %JVM_CONFIG_MAVEN_PROPS% %MAVEN_OPTS% %MAVEN_DEBUG_OPTS% -classpath %WRAPPER_JAR% "-Dmaven.multiModuleProjectDirectory=%MAVEN_PROJECTBASEDIR%" %WRAPPER_LAUNCHER% %MAVEN_CONFIG% %* 141 | if ERRORLEVEL 1 goto error 142 | goto end 143 | 144 | :error 145 | set ERROR_CODE=1 146 | 147 | :end 148 | @endlocal & set ERROR_CODE=%ERROR_CODE% 149 | 150 | if not "%MAVEN_SKIP_RC%" == "" goto skipRcPost 151 | @REM check for post script, once with legacy .bat ending and once with .cmd ending 152 | if exist "%HOME%\mavenrc_post.bat" call "%HOME%\mavenrc_post.bat" 153 | if exist "%HOME%\mavenrc_post.cmd" call "%HOME%\mavenrc_post.cmd" 154 | :skipRcPost 155 | 156 | @REM pause the script if MAVEN_BATCH_PAUSE is set to 'on' 157 | if "%MAVEN_BATCH_PAUSE%" == "on" pause 158 | 159 | if "%MAVEN_TERMINATE_CMD%" == "on" exit %ERROR_CODE% 160 | 161 | exit /B %ERROR_CODE% 162 | -------------------------------------------------------------------------------- /java-spring-actuator/pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 4 | 4.0.0 5 | 6 | org.springframework.boot 7 | spring-boot-starter-parent 8 | 3.1.0 9 | 10 | 11 | gov.cloud.eng 12 | java-spring-actuator 13 | 0.0.1-SNAPSHOT 14 | java-spring-actuator 15 | Demo project for Spring Boot + Actuator 16 | 17 | 18 | 17 19 | 20 | 21 | 22 | 23 | org.springframework.boot 24 | spring-boot-starter-actuator 25 | 26 | 27 | 28 | org.springframework.boot 29 | spring-boot-starter 30 | 31 | 32 | 33 | org.springframework.boot 34 | spring-boot-starter-test 35 | test 36 | 37 | 38 | org.junit.vintage 39 | junit-vintage-engine 40 | 41 | 42 | junit 43 | junit 44 | 45 | 46 | 47 | 48 | 49 | org.springframework.boot 50 | spring-boot-starter-web 51 | 52 | 53 | 54 | 55 | 56 | 57 | org.springframework.boot 58 | spring-boot-maven-plugin 59 | 60 | 61 | 62 | 63 | -------------------------------------------------------------------------------- /java-spring-actuator/set-route-custom-port.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | ORG="$1" 4 | SPACE="$2" 5 | APP_NAME="$3" 6 | HOSTNAME="$4" 7 | PORT=$5 8 | 9 | ORG_GUID=$(cf org "$ORG" --guid) 10 | SPACE_GUID=$(cf space "$SPACE" --guid) 11 | APP_GUID=$(cf app "$APP_NAME" --guid) 12 | 13 | ROUTE_GUID=$(cf curl "/v3/routes?organization_guids=$ORG_GUID&space_guids=$SPACE_GUID" \ 14 | | jq -r --arg host "$HOSTNAME" '.resources[] | select(.host==$host) | .guid') 15 | 16 | cf curl -X PATCH "/v3/routes/$ROUTE_GUID/destinations" \ 17 | -d "{ 18 | \"destinations\": [ 19 | { 20 | \"app\": { 21 | \"guid\": \"$APP_GUID\", 22 | \"process\": { 23 | \"type\": \"web\" 24 | } 25 | }, 26 | \"port\": $PORT, 27 | \"protocol\": \"http1\" 28 | } 29 | ] 30 | }" 31 | -------------------------------------------------------------------------------- /java-spring-actuator/src/main/java/gov/cloud/eng/spring_actuator_demo/HelloController.java: -------------------------------------------------------------------------------- 1 | package gov.cloud.eng.spring_actuator_demo; 2 | 3 | import org.springframework.web.bind.annotation.RestController; 4 | import org.springframework.web.bind.annotation.RequestMapping; 5 | 6 | @RestController 7 | public class HelloController { 8 | 9 | @RequestMapping("/") 10 | public String index() { 11 | return "Greetings from cloud.gov!"; 12 | } 13 | 14 | } 15 | -------------------------------------------------------------------------------- /java-spring-actuator/src/main/java/gov/cloud/eng/spring_actuator_demo/HelloWorldApplication.java: -------------------------------------------------------------------------------- 1 | package gov.cloud.eng.spring_actuator_demo; 2 | 3 | import org.springframework.boot.SpringApplication; 4 | import org.springframework.boot.autoconfigure.SpringBootApplication; 5 | 6 | @SpringBootApplication 7 | public class HelloWorldApplication { 8 | 9 | public static void main(String[] args) { 10 | SpringApplication.run(HelloWorldApplication.class, args); 11 | } 12 | 13 | } 14 | -------------------------------------------------------------------------------- /java-spring-actuator/src/main/resources/application.properties: -------------------------------------------------------------------------------- 1 | management.server.port: 8080 2 | management.server.address: 0.0.0.0 3 | -------------------------------------------------------------------------------- /java-spring-actuator/src/test/java/gov/cloud/eng/spring_actuator_demo/HelloWorldApplicationTests.java: -------------------------------------------------------------------------------- 1 | package gov.cloud.eng.spring_actuator_demo; 2 | 3 | import org.junit.jupiter.api.Test; 4 | import org.springframework.boot.test.context.SpringBootTest; 5 | 6 | @SpringBootTest 7 | class HelloWorldApplicationTests { 8 | 9 | @Test 10 | void contextLoads() { 11 | } 12 | 13 | } 14 | -------------------------------------------------------------------------------- /nodejs/manifest-cnb.yml: -------------------------------------------------------------------------------- 1 | --- 2 | applications: 3 | - name: test-nodejs-cnb 4 | random-route: true 5 | lifecycle: cnb 6 | buildpacks: 7 | - docker://docker.io/paketobuildpacks/nodejs 8 | memory: 256M 9 | stack: cflinuxfs4 10 | env: 11 | LIFECYCLE: "CNB_V3" 12 | -------------------------------------------------------------------------------- /nodejs/manifest.yml: -------------------------------------------------------------------------------- 1 | --- 2 | applications: 3 | - name: test-nodejs 4 | random-route: true 5 | buildpacks: 6 | - nodejs_buildpack 7 | memory: 256M 8 | stack: cflinuxfs4 9 | env: 10 | LIFECYCLE: "CLASSIC_V2" 11 | -------------------------------------------------------------------------------- /nodejs/package-lock.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "sample", 3 | "version": "0.0.0", 4 | "lockfileVersion": 3, 5 | "requires": true, 6 | "packages": { 7 | "": { 8 | "name": "sample", 9 | "version": "0.0.0", 10 | "license": "Apache-2.0", 11 | "dependencies": { 12 | "express": "^4.19.2" 13 | } 14 | }, 15 | "node_modules/accepts": { 16 | "version": "1.3.8", 17 | "resolved": "https://registry.npmjs.org/accepts/-/accepts-1.3.8.tgz", 18 | "integrity": "sha512-PYAthTa2m2VKxuvSD3DPC/Gy+U+sOA1LAuT8mkmRuvw+NACSaeXEQ+NHcVF7rONl6qcaxV3Uuemwawk+7+SJLw==", 19 | "license": "MIT", 20 | "dependencies": { 21 | "mime-types": "~2.1.34", 22 | "negotiator": "0.6.3" 23 | }, 24 | "engines": { 25 | "node": ">= 0.6" 26 | } 27 | }, 28 | "node_modules/array-flatten": { 29 | "version": "1.1.1", 30 | "resolved": "https://registry.npmjs.org/array-flatten/-/array-flatten-1.1.1.tgz", 31 | "integrity": "sha512-PCVAQswWemu6UdxsDFFX/+gVeYqKAod3D3UVm91jHwynguOwAvYPhx8nNlM++NqRcK6CxxpUafjmhIdKiHibqg==", 32 | "license": "MIT" 33 | }, 34 | "node_modules/body-parser": { 35 | "version": "1.20.3", 36 | "resolved": "https://registry.npmjs.org/body-parser/-/body-parser-1.20.3.tgz", 37 | "integrity": "sha512-7rAxByjUMqQ3/bHJy7D6OGXvx/MMc4IqBn/X0fcM1QUcAItpZrBEYhWGem+tzXH90c+G01ypMcYJBO9Y30203g==", 38 | "license": "MIT", 39 | "dependencies": { 40 | "bytes": "3.1.2", 41 | "content-type": "~1.0.5", 42 | "debug": "2.6.9", 43 | "depd": "2.0.0", 44 | "destroy": "1.2.0", 45 | "http-errors": "2.0.0", 46 | "iconv-lite": "0.4.24", 47 | "on-finished": "2.4.1", 48 | "qs": "6.13.0", 49 | "raw-body": "2.5.2", 50 | "type-is": "~1.6.18", 51 | "unpipe": "1.0.0" 52 | }, 53 | "engines": { 54 | "node": ">= 0.8", 55 | "npm": "1.2.8000 || >= 1.4.16" 56 | } 57 | }, 58 | "node_modules/bytes": { 59 | "version": "3.1.2", 60 | "resolved": "https://registry.npmjs.org/bytes/-/bytes-3.1.2.tgz", 61 | "integrity": "sha512-/Nf7TyzTx6S3yRJObOAV7956r8cr2+Oj8AC5dt8wSP3BQAoeX58NoHyCU8P8zGkNXStjTSi6fzO6F0pBdcYbEg==", 62 | "license": "MIT", 63 | "engines": { 64 | "node": ">= 0.8" 65 | } 66 | }, 67 | "node_modules/call-bind-apply-helpers": { 68 | "version": "1.0.2", 69 | "resolved": "https://registry.npmjs.org/call-bind-apply-helpers/-/call-bind-apply-helpers-1.0.2.tgz", 70 | "integrity": "sha512-Sp1ablJ0ivDkSzjcaJdxEunN5/XvksFJ2sMBFfq6x0ryhQV/2b/KwFe21cMpmHtPOSij8K99/wSfoEuTObmuMQ==", 71 | "license": "MIT", 72 | "dependencies": { 73 | "es-errors": "^1.3.0", 74 | "function-bind": "^1.1.2" 75 | }, 76 | "engines": { 77 | "node": ">= 0.4" 78 | } 79 | }, 80 | "node_modules/call-bound": { 81 | "version": "1.0.4", 82 | "resolved": "https://registry.npmjs.org/call-bound/-/call-bound-1.0.4.tgz", 83 | "integrity": "sha512-+ys997U96po4Kx/ABpBCqhA9EuxJaQWDQg7295H4hBphv3IZg0boBKuwYpt4YXp6MZ5AmZQnU/tyMTlRpaSejg==", 84 | "license": "MIT", 85 | "dependencies": { 86 | "call-bind-apply-helpers": "^1.0.2", 87 | "get-intrinsic": "^1.3.0" 88 | }, 89 | "engines": { 90 | "node": ">= 0.4" 91 | }, 92 | "funding": { 93 | "url": "https://github.com/sponsors/ljharb" 94 | } 95 | }, 96 | "node_modules/content-disposition": { 97 | "version": "0.5.4", 98 | "resolved": "https://registry.npmjs.org/content-disposition/-/content-disposition-0.5.4.tgz", 99 | "integrity": "sha512-FveZTNuGw04cxlAiWbzi6zTAL/lhehaWbTtgluJh4/E95DqMwTmha3KZN1aAWA8cFIhHzMZUvLevkw5Rqk+tSQ==", 100 | "license": "MIT", 101 | "dependencies": { 102 | "safe-buffer": "5.2.1" 103 | }, 104 | "engines": { 105 | "node": ">= 0.6" 106 | } 107 | }, 108 | "node_modules/content-type": { 109 | "version": "1.0.5", 110 | "resolved": "https://registry.npmjs.org/content-type/-/content-type-1.0.5.tgz", 111 | "integrity": "sha512-nTjqfcBFEipKdXCv4YDQWCfmcLZKm81ldF0pAopTvyrFGVbcR6P/VAAd5G7N+0tTr8QqiU0tFadD6FK4NtJwOA==", 112 | "license": "MIT", 113 | "engines": { 114 | "node": ">= 0.6" 115 | } 116 | }, 117 | "node_modules/cookie": { 118 | "version": "0.7.1", 119 | "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.7.1.tgz", 120 | "integrity": "sha512-6DnInpx7SJ2AK3+CTUE/ZM0vWTUboZCegxhC2xiIydHR9jNuTAASBrfEpHhiGOZw/nX51bHt6YQl8jsGo4y/0w==", 121 | "license": "MIT", 122 | "engines": { 123 | "node": ">= 0.6" 124 | } 125 | }, 126 | "node_modules/cookie-signature": { 127 | "version": "1.0.6", 128 | "resolved": "https://registry.npmjs.org/cookie-signature/-/cookie-signature-1.0.6.tgz", 129 | "integrity": "sha512-QADzlaHc8icV8I7vbaJXJwod9HWYp8uCqf1xa4OfNu1T7JVxQIrUgOWtHdNDtPiywmFbiS12VjotIXLrKM3orQ==", 130 | "license": "MIT" 131 | }, 132 | "node_modules/debug": { 133 | "version": "2.6.9", 134 | "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", 135 | "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", 136 | "license": "MIT", 137 | "dependencies": { 138 | "ms": "2.0.0" 139 | } 140 | }, 141 | "node_modules/depd": { 142 | "version": "2.0.0", 143 | "resolved": "https://registry.npmjs.org/depd/-/depd-2.0.0.tgz", 144 | "integrity": "sha512-g7nH6P6dyDioJogAAGprGpCtVImJhpPk/roCzdb3fIh61/s/nPsfR6onyMwkCAR/OlC3yBC0lESvUoQEAssIrw==", 145 | "license": "MIT", 146 | "engines": { 147 | "node": ">= 0.8" 148 | } 149 | }, 150 | "node_modules/destroy": { 151 | "version": "1.2.0", 152 | "resolved": "https://registry.npmjs.org/destroy/-/destroy-1.2.0.tgz", 153 | "integrity": "sha512-2sJGJTaXIIaR1w4iJSNoN0hnMY7Gpc/n8D4qSCJw8QqFWXf7cuAgnEHxBpweaVcPevC2l3KpjYCx3NypQQgaJg==", 154 | "license": "MIT", 155 | "engines": { 156 | "node": ">= 0.8", 157 | "npm": "1.2.8000 || >= 1.4.16" 158 | } 159 | }, 160 | "node_modules/dunder-proto": { 161 | "version": "1.0.1", 162 | "resolved": "https://registry.npmjs.org/dunder-proto/-/dunder-proto-1.0.1.tgz", 163 | "integrity": "sha512-KIN/nDJBQRcXw0MLVhZE9iQHmG68qAVIBg9CqmUYjmQIhgij9U5MFvrqkUL5FbtyyzZuOeOt0zdeRe4UY7ct+A==", 164 | "license": "MIT", 165 | "dependencies": { 166 | "call-bind-apply-helpers": "^1.0.1", 167 | "es-errors": "^1.3.0", 168 | "gopd": "^1.2.0" 169 | }, 170 | "engines": { 171 | "node": ">= 0.4" 172 | } 173 | }, 174 | "node_modules/ee-first": { 175 | "version": "1.1.1", 176 | "resolved": "https://registry.npmjs.org/ee-first/-/ee-first-1.1.1.tgz", 177 | "integrity": "sha512-WMwm9LhRUo+WUaRN+vRuETqG89IgZphVSNkdFgeb6sS/E4OrDIN7t48CAewSHXc6C8lefD8KKfr5vY61brQlow==", 178 | "license": "MIT" 179 | }, 180 | "node_modules/encodeurl": { 181 | "version": "2.0.0", 182 | "resolved": "https://registry.npmjs.org/encodeurl/-/encodeurl-2.0.0.tgz", 183 | "integrity": "sha512-Q0n9HRi4m6JuGIV1eFlmvJB7ZEVxu93IrMyiMsGC0lrMJMWzRgx6WGquyfQgZVb31vhGgXnfmPNNXmxnOkRBrg==", 184 | "license": "MIT", 185 | "engines": { 186 | "node": ">= 0.8" 187 | } 188 | }, 189 | "node_modules/es-define-property": { 190 | "version": "1.0.1", 191 | "resolved": "https://registry.npmjs.org/es-define-property/-/es-define-property-1.0.1.tgz", 192 | "integrity": "sha512-e3nRfgfUZ4rNGL232gUgX06QNyyez04KdjFrF+LTRoOXmrOgFKDg4BCdsjW8EnT69eqdYGmRpJwiPVYNrCaW3g==", 193 | "license": "MIT", 194 | "engines": { 195 | "node": ">= 0.4" 196 | } 197 | }, 198 | "node_modules/es-errors": { 199 | "version": "1.3.0", 200 | "resolved": "https://registry.npmjs.org/es-errors/-/es-errors-1.3.0.tgz", 201 | "integrity": "sha512-Zf5H2Kxt2xjTvbJvP2ZWLEICxA6j+hAmMzIlypy4xcBg1vKVnx89Wy0GbS+kf5cwCVFFzdCFh2XSCFNULS6csw==", 202 | "license": "MIT", 203 | "engines": { 204 | "node": ">= 0.4" 205 | } 206 | }, 207 | "node_modules/es-object-atoms": { 208 | "version": "1.1.1", 209 | "resolved": "https://registry.npmjs.org/es-object-atoms/-/es-object-atoms-1.1.1.tgz", 210 | "integrity": "sha512-FGgH2h8zKNim9ljj7dankFPcICIK9Cp5bm+c2gQSYePhpaG5+esrLODihIorn+Pe6FGJzWhXQotPv73jTaldXA==", 211 | "license": "MIT", 212 | "dependencies": { 213 | "es-errors": "^1.3.0" 214 | }, 215 | "engines": { 216 | "node": ">= 0.4" 217 | } 218 | }, 219 | "node_modules/escape-html": { 220 | "version": "1.0.3", 221 | "resolved": "https://registry.npmjs.org/escape-html/-/escape-html-1.0.3.tgz", 222 | "integrity": "sha512-NiSupZ4OeuGwr68lGIeym/ksIZMJodUGOSCZ/FSnTxcrekbvqrgdUxlJOMpijaKZVjAJrWrGs/6Jy8OMuyj9ow==", 223 | "license": "MIT" 224 | }, 225 | "node_modules/etag": { 226 | "version": "1.8.1", 227 | "resolved": "https://registry.npmjs.org/etag/-/etag-1.8.1.tgz", 228 | "integrity": "sha512-aIL5Fx7mawVa300al2BnEE4iNvo1qETxLrPI/o05L7z6go7fCw1J6EQmbK4FmJ2AS7kgVF/KEZWufBfdClMcPg==", 229 | "license": "MIT", 230 | "engines": { 231 | "node": ">= 0.6" 232 | } 233 | }, 234 | "node_modules/express": { 235 | "version": "4.21.2", 236 | "resolved": "https://registry.npmjs.org/express/-/express-4.21.2.tgz", 237 | "integrity": "sha512-28HqgMZAmih1Czt9ny7qr6ek2qddF4FclbMzwhCREB6OFfH+rXAnuNCwo1/wFvrtbgsQDb4kSbX9de9lFbrXnA==", 238 | "license": "MIT", 239 | "dependencies": { 240 | "accepts": "~1.3.8", 241 | "array-flatten": "1.1.1", 242 | "body-parser": "1.20.3", 243 | "content-disposition": "0.5.4", 244 | "content-type": "~1.0.4", 245 | "cookie": "0.7.1", 246 | "cookie-signature": "1.0.6", 247 | "debug": "2.6.9", 248 | "depd": "2.0.0", 249 | "encodeurl": "~2.0.0", 250 | "escape-html": "~1.0.3", 251 | "etag": "~1.8.1", 252 | "finalhandler": "1.3.1", 253 | "fresh": "0.5.2", 254 | "http-errors": "2.0.0", 255 | "merge-descriptors": "1.0.3", 256 | "methods": "~1.1.2", 257 | "on-finished": "2.4.1", 258 | "parseurl": "~1.3.3", 259 | "path-to-regexp": "0.1.12", 260 | "proxy-addr": "~2.0.7", 261 | "qs": "6.13.0", 262 | "range-parser": "~1.2.1", 263 | "safe-buffer": "5.2.1", 264 | "send": "0.19.0", 265 | "serve-static": "1.16.2", 266 | "setprototypeof": "1.2.0", 267 | "statuses": "2.0.1", 268 | "type-is": "~1.6.18", 269 | "utils-merge": "1.0.1", 270 | "vary": "~1.1.2" 271 | }, 272 | "engines": { 273 | "node": ">= 0.10.0" 274 | }, 275 | "funding": { 276 | "type": "opencollective", 277 | "url": "https://opencollective.com/express" 278 | } 279 | }, 280 | "node_modules/finalhandler": { 281 | "version": "1.3.1", 282 | "resolved": "https://registry.npmjs.org/finalhandler/-/finalhandler-1.3.1.tgz", 283 | "integrity": "sha512-6BN9trH7bp3qvnrRyzsBz+g3lZxTNZTbVO2EV1CS0WIcDbawYVdYvGflME/9QP0h0pYlCDBCTjYa9nZzMDpyxQ==", 284 | "license": "MIT", 285 | "dependencies": { 286 | "debug": "2.6.9", 287 | "encodeurl": "~2.0.0", 288 | "escape-html": "~1.0.3", 289 | "on-finished": "2.4.1", 290 | "parseurl": "~1.3.3", 291 | "statuses": "2.0.1", 292 | "unpipe": "~1.0.0" 293 | }, 294 | "engines": { 295 | "node": ">= 0.8" 296 | } 297 | }, 298 | "node_modules/forwarded": { 299 | "version": "0.2.0", 300 | "resolved": "https://registry.npmjs.org/forwarded/-/forwarded-0.2.0.tgz", 301 | "integrity": "sha512-buRG0fpBtRHSTCOASe6hD258tEubFoRLb4ZNA6NxMVHNw2gOcwHo9wyablzMzOA5z9xA9L1KNjk/Nt6MT9aYow==", 302 | "license": "MIT", 303 | "engines": { 304 | "node": ">= 0.6" 305 | } 306 | }, 307 | "node_modules/fresh": { 308 | "version": "0.5.2", 309 | "resolved": "https://registry.npmjs.org/fresh/-/fresh-0.5.2.tgz", 310 | "integrity": "sha512-zJ2mQYM18rEFOudeV4GShTGIQ7RbzA7ozbU9I/XBpm7kqgMywgmylMwXHxZJmkVoYkna9d2pVXVXPdYTP9ej8Q==", 311 | "license": "MIT", 312 | "engines": { 313 | "node": ">= 0.6" 314 | } 315 | }, 316 | "node_modules/function-bind": { 317 | "version": "1.1.2", 318 | "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.2.tgz", 319 | "integrity": "sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA==", 320 | "license": "MIT", 321 | "funding": { 322 | "url": "https://github.com/sponsors/ljharb" 323 | } 324 | }, 325 | "node_modules/get-intrinsic": { 326 | "version": "1.3.0", 327 | "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.3.0.tgz", 328 | "integrity": "sha512-9fSjSaos/fRIVIp+xSJlE6lfwhES7LNtKaCBIamHsjr2na1BiABJPo0mOjjz8GJDURarmCPGqaiVg5mfjb98CQ==", 329 | "license": "MIT", 330 | "dependencies": { 331 | "call-bind-apply-helpers": "^1.0.2", 332 | "es-define-property": "^1.0.1", 333 | "es-errors": "^1.3.0", 334 | "es-object-atoms": "^1.1.1", 335 | "function-bind": "^1.1.2", 336 | "get-proto": "^1.0.1", 337 | "gopd": "^1.2.0", 338 | "has-symbols": "^1.1.0", 339 | "hasown": "^2.0.2", 340 | "math-intrinsics": "^1.1.0" 341 | }, 342 | "engines": { 343 | "node": ">= 0.4" 344 | }, 345 | "funding": { 346 | "url": "https://github.com/sponsors/ljharb" 347 | } 348 | }, 349 | "node_modules/get-proto": { 350 | "version": "1.0.1", 351 | "resolved": "https://registry.npmjs.org/get-proto/-/get-proto-1.0.1.tgz", 352 | "integrity": "sha512-sTSfBjoXBp89JvIKIefqw7U2CCebsc74kiY6awiGogKtoSGbgjYE/G/+l9sF3MWFPNc9IcoOC4ODfKHfxFmp0g==", 353 | "license": "MIT", 354 | "dependencies": { 355 | "dunder-proto": "^1.0.1", 356 | "es-object-atoms": "^1.0.0" 357 | }, 358 | "engines": { 359 | "node": ">= 0.4" 360 | } 361 | }, 362 | "node_modules/gopd": { 363 | "version": "1.2.0", 364 | "resolved": "https://registry.npmjs.org/gopd/-/gopd-1.2.0.tgz", 365 | "integrity": "sha512-ZUKRh6/kUFoAiTAtTYPZJ3hw9wNxx+BIBOijnlG9PnrJsCcSjs1wyyD6vJpaYtgnzDrKYRSqf3OO6Rfa93xsRg==", 366 | "license": "MIT", 367 | "engines": { 368 | "node": ">= 0.4" 369 | }, 370 | "funding": { 371 | "url": "https://github.com/sponsors/ljharb" 372 | } 373 | }, 374 | "node_modules/has-symbols": { 375 | "version": "1.1.0", 376 | "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.1.0.tgz", 377 | "integrity": "sha512-1cDNdwJ2Jaohmb3sg4OmKaMBwuC48sYni5HUw2DvsC8LjGTLK9h+eb1X6RyuOHe4hT0ULCW68iomhjUoKUqlPQ==", 378 | "license": "MIT", 379 | "engines": { 380 | "node": ">= 0.4" 381 | }, 382 | "funding": { 383 | "url": "https://github.com/sponsors/ljharb" 384 | } 385 | }, 386 | "node_modules/hasown": { 387 | "version": "2.0.2", 388 | "resolved": "https://registry.npmjs.org/hasown/-/hasown-2.0.2.tgz", 389 | "integrity": "sha512-0hJU9SCPvmMzIBdZFqNPXWa6dqh7WdH0cII9y+CyS8rG3nL48Bclra9HmKhVVUHyPWNH5Y7xDwAB7bfgSjkUMQ==", 390 | "license": "MIT", 391 | "dependencies": { 392 | "function-bind": "^1.1.2" 393 | }, 394 | "engines": { 395 | "node": ">= 0.4" 396 | } 397 | }, 398 | "node_modules/http-errors": { 399 | "version": "2.0.0", 400 | "resolved": "https://registry.npmjs.org/http-errors/-/http-errors-2.0.0.tgz", 401 | "integrity": "sha512-FtwrG/euBzaEjYeRqOgly7G0qviiXoJWnvEH2Z1plBdXgbyjv34pHTSb9zoeHMyDy33+DWy5Wt9Wo+TURtOYSQ==", 402 | "license": "MIT", 403 | "dependencies": { 404 | "depd": "2.0.0", 405 | "inherits": "2.0.4", 406 | "setprototypeof": "1.2.0", 407 | "statuses": "2.0.1", 408 | "toidentifier": "1.0.1" 409 | }, 410 | "engines": { 411 | "node": ">= 0.8" 412 | } 413 | }, 414 | "node_modules/iconv-lite": { 415 | "version": "0.4.24", 416 | "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.24.tgz", 417 | "integrity": "sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA==", 418 | "license": "MIT", 419 | "dependencies": { 420 | "safer-buffer": ">= 2.1.2 < 3" 421 | }, 422 | "engines": { 423 | "node": ">=0.10.0" 424 | } 425 | }, 426 | "node_modules/inherits": { 427 | "version": "2.0.4", 428 | "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", 429 | "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==", 430 | "license": "ISC" 431 | }, 432 | "node_modules/ipaddr.js": { 433 | "version": "1.9.1", 434 | "resolved": "https://registry.npmjs.org/ipaddr.js/-/ipaddr.js-1.9.1.tgz", 435 | "integrity": "sha512-0KI/607xoxSToH7GjN1FfSbLoU0+btTicjsQSWQlh/hZykN8KpmMf7uYwPW3R+akZ6R/w18ZlXSHBYXiYUPO3g==", 436 | "license": "MIT", 437 | "engines": { 438 | "node": ">= 0.10" 439 | } 440 | }, 441 | "node_modules/math-intrinsics": { 442 | "version": "1.1.0", 443 | "resolved": "https://registry.npmjs.org/math-intrinsics/-/math-intrinsics-1.1.0.tgz", 444 | "integrity": "sha512-/IXtbwEk5HTPyEwyKX6hGkYXxM9nbj64B+ilVJnC/R6B0pH5G4V3b0pVbL7DBj4tkhBAppbQUlf6F6Xl9LHu1g==", 445 | "license": "MIT", 446 | "engines": { 447 | "node": ">= 0.4" 448 | } 449 | }, 450 | "node_modules/media-typer": { 451 | "version": "0.3.0", 452 | "resolved": "https://registry.npmjs.org/media-typer/-/media-typer-0.3.0.tgz", 453 | "integrity": "sha512-dq+qelQ9akHpcOl/gUVRTxVIOkAJ1wR3QAvb4RsVjS8oVoFjDGTc679wJYmUmknUF5HwMLOgb5O+a3KxfWapPQ==", 454 | "license": "MIT", 455 | "engines": { 456 | "node": ">= 0.6" 457 | } 458 | }, 459 | "node_modules/merge-descriptors": { 460 | "version": "1.0.3", 461 | "resolved": "https://registry.npmjs.org/merge-descriptors/-/merge-descriptors-1.0.3.tgz", 462 | "integrity": "sha512-gaNvAS7TZ897/rVaZ0nMtAyxNyi/pdbjbAwUpFQpN70GqnVfOiXpeUUMKRBmzXaSQ8DdTX4/0ms62r2K+hE6mQ==", 463 | "license": "MIT", 464 | "funding": { 465 | "url": "https://github.com/sponsors/sindresorhus" 466 | } 467 | }, 468 | "node_modules/methods": { 469 | "version": "1.1.2", 470 | "resolved": "https://registry.npmjs.org/methods/-/methods-1.1.2.tgz", 471 | "integrity": "sha512-iclAHeNqNm68zFtnZ0e+1L2yUIdvzNoauKU4WBA3VvH/vPFieF7qfRlwUZU+DA9P9bPXIS90ulxoUoCH23sV2w==", 472 | "license": "MIT", 473 | "engines": { 474 | "node": ">= 0.6" 475 | } 476 | }, 477 | "node_modules/mime": { 478 | "version": "1.6.0", 479 | "resolved": "https://registry.npmjs.org/mime/-/mime-1.6.0.tgz", 480 | "integrity": "sha512-x0Vn8spI+wuJ1O6S7gnbaQg8Pxh4NNHb7KSINmEWKiPE4RKOplvijn+NkmYmmRgP68mc70j2EbeTFRsrswaQeg==", 481 | "license": "MIT", 482 | "bin": { 483 | "mime": "cli.js" 484 | }, 485 | "engines": { 486 | "node": ">=4" 487 | } 488 | }, 489 | "node_modules/mime-db": { 490 | "version": "1.52.0", 491 | "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.52.0.tgz", 492 | "integrity": "sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==", 493 | "license": "MIT", 494 | "engines": { 495 | "node": ">= 0.6" 496 | } 497 | }, 498 | "node_modules/mime-types": { 499 | "version": "2.1.35", 500 | "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.35.tgz", 501 | "integrity": "sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==", 502 | "license": "MIT", 503 | "dependencies": { 504 | "mime-db": "1.52.0" 505 | }, 506 | "engines": { 507 | "node": ">= 0.6" 508 | } 509 | }, 510 | "node_modules/ms": { 511 | "version": "2.0.0", 512 | "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", 513 | "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==", 514 | "license": "MIT" 515 | }, 516 | "node_modules/negotiator": { 517 | "version": "0.6.3", 518 | "resolved": "https://registry.npmjs.org/negotiator/-/negotiator-0.6.3.tgz", 519 | "integrity": "sha512-+EUsqGPLsM+j/zdChZjsnX51g4XrHFOIXwfnCVPGlQk/k5giakcKsuxCObBRu6DSm9opw/O6slWbJdghQM4bBg==", 520 | "license": "MIT", 521 | "engines": { 522 | "node": ">= 0.6" 523 | } 524 | }, 525 | "node_modules/object-inspect": { 526 | "version": "1.13.4", 527 | "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.13.4.tgz", 528 | "integrity": "sha512-W67iLl4J2EXEGTbfeHCffrjDfitvLANg0UlX3wFUUSTx92KXRFegMHUVgSqE+wvhAbi4WqjGg9czysTV2Epbew==", 529 | "license": "MIT", 530 | "engines": { 531 | "node": ">= 0.4" 532 | }, 533 | "funding": { 534 | "url": "https://github.com/sponsors/ljharb" 535 | } 536 | }, 537 | "node_modules/on-finished": { 538 | "version": "2.4.1", 539 | "resolved": "https://registry.npmjs.org/on-finished/-/on-finished-2.4.1.tgz", 540 | "integrity": "sha512-oVlzkg3ENAhCk2zdv7IJwd/QUD4z2RxRwpkcGY8psCVcCYZNq4wYnVWALHM+brtuJjePWiYF/ClmuDr8Ch5+kg==", 541 | "license": "MIT", 542 | "dependencies": { 543 | "ee-first": "1.1.1" 544 | }, 545 | "engines": { 546 | "node": ">= 0.8" 547 | } 548 | }, 549 | "node_modules/parseurl": { 550 | "version": "1.3.3", 551 | "resolved": "https://registry.npmjs.org/parseurl/-/parseurl-1.3.3.tgz", 552 | "integrity": "sha512-CiyeOxFT/JZyN5m0z9PfXw4SCBJ6Sygz1Dpl0wqjlhDEGGBP1GnsUVEL0p63hoG1fcj3fHynXi9NYO4nWOL+qQ==", 553 | "license": "MIT", 554 | "engines": { 555 | "node": ">= 0.8" 556 | } 557 | }, 558 | "node_modules/path-to-regexp": { 559 | "version": "0.1.12", 560 | "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-0.1.12.tgz", 561 | "integrity": "sha512-RA1GjUVMnvYFxuqovrEqZoxxW5NUZqbwKtYz/Tt7nXerk0LbLblQmrsgdeOxV5SFHf0UDggjS/bSeOZwt1pmEQ==", 562 | "license": "MIT" 563 | }, 564 | "node_modules/proxy-addr": { 565 | "version": "2.0.7", 566 | "resolved": "https://registry.npmjs.org/proxy-addr/-/proxy-addr-2.0.7.tgz", 567 | "integrity": "sha512-llQsMLSUDUPT44jdrU/O37qlnifitDP+ZwrmmZcoSKyLKvtZxpyV0n2/bD/N4tBAAZ/gJEdZU7KMraoK1+XYAg==", 568 | "license": "MIT", 569 | "dependencies": { 570 | "forwarded": "0.2.0", 571 | "ipaddr.js": "1.9.1" 572 | }, 573 | "engines": { 574 | "node": ">= 0.10" 575 | } 576 | }, 577 | "node_modules/qs": { 578 | "version": "6.13.0", 579 | "resolved": "https://registry.npmjs.org/qs/-/qs-6.13.0.tgz", 580 | "integrity": "sha512-+38qI9SOr8tfZ4QmJNplMUxqjbe7LKvvZgWdExBOmd+egZTtjLB67Gu0HRX3u/XOq7UU2Nx6nsjvS16Z9uwfpg==", 581 | "license": "BSD-3-Clause", 582 | "dependencies": { 583 | "side-channel": "^1.0.6" 584 | }, 585 | "engines": { 586 | "node": ">=0.6" 587 | }, 588 | "funding": { 589 | "url": "https://github.com/sponsors/ljharb" 590 | } 591 | }, 592 | "node_modules/range-parser": { 593 | "version": "1.2.1", 594 | "resolved": "https://registry.npmjs.org/range-parser/-/range-parser-1.2.1.tgz", 595 | "integrity": "sha512-Hrgsx+orqoygnmhFbKaHE6c296J+HTAQXoxEF6gNupROmmGJRoyzfG3ccAveqCBrwr/2yxQ5BVd/GTl5agOwSg==", 596 | "license": "MIT", 597 | "engines": { 598 | "node": ">= 0.6" 599 | } 600 | }, 601 | "node_modules/raw-body": { 602 | "version": "2.5.2", 603 | "resolved": "https://registry.npmjs.org/raw-body/-/raw-body-2.5.2.tgz", 604 | "integrity": "sha512-8zGqypfENjCIqGhgXToC8aB2r7YrBX+AQAfIPs/Mlk+BtPTztOvTS01NRW/3Eh60J+a48lt8qsCzirQ6loCVfA==", 605 | "license": "MIT", 606 | "dependencies": { 607 | "bytes": "3.1.2", 608 | "http-errors": "2.0.0", 609 | "iconv-lite": "0.4.24", 610 | "unpipe": "1.0.0" 611 | }, 612 | "engines": { 613 | "node": ">= 0.8" 614 | } 615 | }, 616 | "node_modules/safe-buffer": { 617 | "version": "5.2.1", 618 | "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz", 619 | "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==", 620 | "funding": [ 621 | { 622 | "type": "github", 623 | "url": "https://github.com/sponsors/feross" 624 | }, 625 | { 626 | "type": "patreon", 627 | "url": "https://www.patreon.com/feross" 628 | }, 629 | { 630 | "type": "consulting", 631 | "url": "https://feross.org/support" 632 | } 633 | ], 634 | "license": "MIT" 635 | }, 636 | "node_modules/safer-buffer": { 637 | "version": "2.1.2", 638 | "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz", 639 | "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==", 640 | "license": "MIT" 641 | }, 642 | "node_modules/send": { 643 | "version": "0.19.0", 644 | "resolved": "https://registry.npmjs.org/send/-/send-0.19.0.tgz", 645 | "integrity": "sha512-dW41u5VfLXu8SJh5bwRmyYUbAoSB3c9uQh6L8h/KtsFREPWpbX1lrljJo186Jc4nmci/sGUZ9a0a0J2zgfq2hw==", 646 | "license": "MIT", 647 | "dependencies": { 648 | "debug": "2.6.9", 649 | "depd": "2.0.0", 650 | "destroy": "1.2.0", 651 | "encodeurl": "~1.0.2", 652 | "escape-html": "~1.0.3", 653 | "etag": "~1.8.1", 654 | "fresh": "0.5.2", 655 | "http-errors": "2.0.0", 656 | "mime": "1.6.0", 657 | "ms": "2.1.3", 658 | "on-finished": "2.4.1", 659 | "range-parser": "~1.2.1", 660 | "statuses": "2.0.1" 661 | }, 662 | "engines": { 663 | "node": ">= 0.8.0" 664 | } 665 | }, 666 | "node_modules/send/node_modules/encodeurl": { 667 | "version": "1.0.2", 668 | "resolved": "https://registry.npmjs.org/encodeurl/-/encodeurl-1.0.2.tgz", 669 | "integrity": "sha512-TPJXq8JqFaVYm2CWmPvnP2Iyo4ZSM7/QKcSmuMLDObfpH5fi7RUGmd/rTDf+rut/saiDiQEeVTNgAmJEdAOx0w==", 670 | "license": "MIT", 671 | "engines": { 672 | "node": ">= 0.8" 673 | } 674 | }, 675 | "node_modules/send/node_modules/ms": { 676 | "version": "2.1.3", 677 | "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", 678 | "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==", 679 | "license": "MIT" 680 | }, 681 | "node_modules/serve-static": { 682 | "version": "1.16.2", 683 | "resolved": "https://registry.npmjs.org/serve-static/-/serve-static-1.16.2.tgz", 684 | "integrity": "sha512-VqpjJZKadQB/PEbEwvFdO43Ax5dFBZ2UECszz8bQ7pi7wt//PWe1P6MN7eCnjsatYtBT6EuiClbjSWP2WrIoTw==", 685 | "license": "MIT", 686 | "dependencies": { 687 | "encodeurl": "~2.0.0", 688 | "escape-html": "~1.0.3", 689 | "parseurl": "~1.3.3", 690 | "send": "0.19.0" 691 | }, 692 | "engines": { 693 | "node": ">= 0.8.0" 694 | } 695 | }, 696 | "node_modules/setprototypeof": { 697 | "version": "1.2.0", 698 | "resolved": "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.2.0.tgz", 699 | "integrity": "sha512-E5LDX7Wrp85Kil5bhZv46j8jOeboKq5JMmYM3gVGdGH8xFpPWXUMsNrlODCrkoxMEeNi/XZIwuRvY4XNwYMJpw==", 700 | "license": "ISC" 701 | }, 702 | "node_modules/side-channel": { 703 | "version": "1.1.0", 704 | "resolved": "https://registry.npmjs.org/side-channel/-/side-channel-1.1.0.tgz", 705 | "integrity": "sha512-ZX99e6tRweoUXqR+VBrslhda51Nh5MTQwou5tnUDgbtyM0dBgmhEDtWGP/xbKn6hqfPRHujUNwz5fy/wbbhnpw==", 706 | "license": "MIT", 707 | "dependencies": { 708 | "es-errors": "^1.3.0", 709 | "object-inspect": "^1.13.3", 710 | "side-channel-list": "^1.0.0", 711 | "side-channel-map": "^1.0.1", 712 | "side-channel-weakmap": "^1.0.2" 713 | }, 714 | "engines": { 715 | "node": ">= 0.4" 716 | }, 717 | "funding": { 718 | "url": "https://github.com/sponsors/ljharb" 719 | } 720 | }, 721 | "node_modules/side-channel-list": { 722 | "version": "1.0.0", 723 | "resolved": "https://registry.npmjs.org/side-channel-list/-/side-channel-list-1.0.0.tgz", 724 | "integrity": "sha512-FCLHtRD/gnpCiCHEiJLOwdmFP+wzCmDEkc9y7NsYxeF4u7Btsn1ZuwgwJGxImImHicJArLP4R0yX4c2KCrMrTA==", 725 | "license": "MIT", 726 | "dependencies": { 727 | "es-errors": "^1.3.0", 728 | "object-inspect": "^1.13.3" 729 | }, 730 | "engines": { 731 | "node": ">= 0.4" 732 | }, 733 | "funding": { 734 | "url": "https://github.com/sponsors/ljharb" 735 | } 736 | }, 737 | "node_modules/side-channel-map": { 738 | "version": "1.0.1", 739 | "resolved": "https://registry.npmjs.org/side-channel-map/-/side-channel-map-1.0.1.tgz", 740 | "integrity": "sha512-VCjCNfgMsby3tTdo02nbjtM/ewra6jPHmpThenkTYh8pG9ucZ/1P8So4u4FGBek/BjpOVsDCMoLA/iuBKIFXRA==", 741 | "license": "MIT", 742 | "dependencies": { 743 | "call-bound": "^1.0.2", 744 | "es-errors": "^1.3.0", 745 | "get-intrinsic": "^1.2.5", 746 | "object-inspect": "^1.13.3" 747 | }, 748 | "engines": { 749 | "node": ">= 0.4" 750 | }, 751 | "funding": { 752 | "url": "https://github.com/sponsors/ljharb" 753 | } 754 | }, 755 | "node_modules/side-channel-weakmap": { 756 | "version": "1.0.2", 757 | "resolved": "https://registry.npmjs.org/side-channel-weakmap/-/side-channel-weakmap-1.0.2.tgz", 758 | "integrity": "sha512-WPS/HvHQTYnHisLo9McqBHOJk2FkHO/tlpvldyrnem4aeQp4hai3gythswg6p01oSoTl58rcpiFAjF2br2Ak2A==", 759 | "license": "MIT", 760 | "dependencies": { 761 | "call-bound": "^1.0.2", 762 | "es-errors": "^1.3.0", 763 | "get-intrinsic": "^1.2.5", 764 | "object-inspect": "^1.13.3", 765 | "side-channel-map": "^1.0.1" 766 | }, 767 | "engines": { 768 | "node": ">= 0.4" 769 | }, 770 | "funding": { 771 | "url": "https://github.com/sponsors/ljharb" 772 | } 773 | }, 774 | "node_modules/statuses": { 775 | "version": "2.0.1", 776 | "resolved": "https://registry.npmjs.org/statuses/-/statuses-2.0.1.tgz", 777 | "integrity": "sha512-RwNA9Z/7PrK06rYLIzFMlaF+l73iwpzsqRIFgbMLbTcLD6cOao82TaWefPXQvB2fOC4AjuYSEndS7N/mTCbkdQ==", 778 | "license": "MIT", 779 | "engines": { 780 | "node": ">= 0.8" 781 | } 782 | }, 783 | "node_modules/toidentifier": { 784 | "version": "1.0.1", 785 | "resolved": "https://registry.npmjs.org/toidentifier/-/toidentifier-1.0.1.tgz", 786 | "integrity": "sha512-o5sSPKEkg/DIQNmH43V0/uerLrpzVedkUh8tGNvaeXpfpuwjKenlSox/2O/BTlZUtEe+JG7s5YhEz608PlAHRA==", 787 | "license": "MIT", 788 | "engines": { 789 | "node": ">=0.6" 790 | } 791 | }, 792 | "node_modules/type-is": { 793 | "version": "1.6.18", 794 | "resolved": "https://registry.npmjs.org/type-is/-/type-is-1.6.18.tgz", 795 | "integrity": "sha512-TkRKr9sUTxEH8MdfuCSP7VizJyzRNMjj2J2do2Jr3Kym598JVdEksuzPQCnlFPW4ky9Q+iA+ma9BGm06XQBy8g==", 796 | "license": "MIT", 797 | "dependencies": { 798 | "media-typer": "0.3.0", 799 | "mime-types": "~2.1.24" 800 | }, 801 | "engines": { 802 | "node": ">= 0.6" 803 | } 804 | }, 805 | "node_modules/unpipe": { 806 | "version": "1.0.0", 807 | "resolved": "https://registry.npmjs.org/unpipe/-/unpipe-1.0.0.tgz", 808 | "integrity": "sha512-pjy2bYhSsufwWlKwPc+l3cN7+wuJlK6uz0YdJEOlQDbl6jo/YlPi4mb8agUkVC8BF7V8NuzeyPNqRksA3hztKQ==", 809 | "license": "MIT", 810 | "engines": { 811 | "node": ">= 0.8" 812 | } 813 | }, 814 | "node_modules/utils-merge": { 815 | "version": "1.0.1", 816 | "resolved": "https://registry.npmjs.org/utils-merge/-/utils-merge-1.0.1.tgz", 817 | "integrity": "sha512-pMZTvIkT1d+TFGvDOqodOclx0QWkkgi6Tdoa8gC8ffGAAqz9pzPTZWAybbsHHoED/ztMtkv/VoYTYyShUn81hA==", 818 | "license": "MIT", 819 | "engines": { 820 | "node": ">= 0.4.0" 821 | } 822 | }, 823 | "node_modules/vary": { 824 | "version": "1.1.2", 825 | "resolved": "https://registry.npmjs.org/vary/-/vary-1.1.2.tgz", 826 | "integrity": "sha512-BNGbWLfd0eUPabhkXUVm0j8uuvREyTh5ovRa/dyow/BqAbZJyC+5fU+IzQOzmAKzYqYRAISoRhdQr3eIZ/PXqg==", 827 | "license": "MIT", 828 | "engines": { 829 | "node": ">= 0.8" 830 | } 831 | } 832 | } 833 | } 834 | -------------------------------------------------------------------------------- /nodejs/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "author": "Paketo Buildpacks", 3 | "dependencies": { 4 | "express": "^4.19.2" 5 | }, 6 | "description": "Sample Node.js Application using NPM", 7 | "license": "Apache-2.0", 8 | "name": "sample", 9 | "repository": { 10 | "type": "git", 11 | "url": "https://github.com/paketo-buildpacks/samples" 12 | }, 13 | "scripts": { 14 | "start": "echo \"start\" && node server.js" 15 | }, 16 | "version": "0.0.0" 17 | } 18 | -------------------------------------------------------------------------------- /nodejs/server.js: -------------------------------------------------------------------------------- 1 | const express = require('express'); 2 | const port = process.env.PORT || 8080; 3 | const os = require('os'); 4 | const lifecycle = process.env.LIFECYCLE || 'not_set' 5 | 6 | const app = express(); 7 | 8 | app.use((request, _, next) => { 9 | const requestTime = new Date(Date.now()).toString(); 10 | console.log(request.method, request.hostname, request.path, requestTime); 11 | next(); 12 | }); 13 | 14 | app.get('/', (request, response) => { 15 | response.send(` 16 | 17 | 18 | Powered By ${lifecycle} Buildpacks 19 | 20 | 21 |

Hello World from NodeJS on port ${port} from container ${os.hostname()} with ${lifecycle} buildpacks

22 | 23 | `); 24 | }); 25 | 26 | app.get("/actuator/health", (request, response) => { 27 | response.json({ status: "UP" }); 28 | }); 29 | 30 | app.listen(port, () => { 31 | console.log(`App listening on port ${port}`); 32 | }); 33 | -------------------------------------------------------------------------------- /php/composer.json: -------------------------------------------------------------------------------- 1 | {} 2 | -------------------------------------------------------------------------------- /php/index.php: -------------------------------------------------------------------------------- 1 | 2 | -------------------------------------------------------------------------------- /php/manifest.yml: -------------------------------------------------------------------------------- 1 | --- 2 | applications: 3 | - name: test-php 4 | random-route: true 5 | memory: 256M 6 | buildpacks: 7 | - php_buildpack 8 | stack: cflinuxfs4 9 | -------------------------------------------------------------------------------- /pipeline.yml: -------------------------------------------------------------------------------- 1 | jobs: 2 | - name: set-self 3 | plan: 4 | - get: cf-hello-worlds 5 | trigger: true 6 | - set_pipeline: self 7 | file: cf-hello-worlds/pipeline.yml 8 | 9 | - name: deploy-python-flask 10 | serial_groups: [apps] 11 | plan: 12 | - in_parallel: &plan-gets 13 | - get: cf-hello-worlds 14 | trigger: true 15 | passed: [set-self] 16 | - get: timer 17 | trigger: true 18 | - put: deploy-python-flask-staging 19 | params: 20 | config: 21 | platform: linux 22 | image_resource: 23 | type: registry-image 24 | source: &general-task 25 | aws_access_key_id: ((ecr_aws_key)) 26 | aws_secret_access_key: ((ecr_aws_secret)) 27 | repository: general-task 28 | aws_region: us-gov-west-1 29 | tag: latest 30 | path: cf-hello-worlds/python-flask 31 | manifest: cf-hello-worlds/python-flask/manifest.yml 32 | - put: deploy-python-flask-production 33 | params: 34 | config: 35 | platform: linux 36 | image_resource: 37 | type: registry-image 38 | source: *general-task 39 | path: cf-hello-worlds/python-flask 40 | manifest: cf-hello-worlds/python-flask/manifest.yml 41 | on_failure: 42 | put: slack 43 | params: &slack-params 44 | text: | 45 | :x: Failed to deploy python-flask sample app 46 | <$ATC_EXTERNAL_URL/teams/$BUILD_TEAM_NAME/pipelines/$BUILD_PIPELINE_NAME/jobs/$BUILD_JOB_NAME/builds/$BUILD_NAME|View build details> 47 | channel: ((slack-failure-channel)) 48 | username: ((slack-username)) 49 | icon_url: ((slack-icon-url)) 50 | 51 | - name: deploy-ruby-sinatra 52 | serial_groups: [apps] 53 | plan: 54 | - in_parallel: *plan-gets 55 | - put: deploy-ruby-sinatra-staging 56 | params: 57 | config: 58 | platform: linux 59 | image_resource: 60 | type: registry-image 61 | source: *general-task 62 | path: cf-hello-worlds/ruby-sinatra 63 | manifest: cf-hello-worlds/ruby-sinatra/manifest.yml 64 | - put: deploy-ruby-sinatra-production 65 | params: 66 | config: 67 | platform: linux 68 | image_resource: 69 | type: registry-image 70 | source: *general-task 71 | path: cf-hello-worlds/ruby-sinatra 72 | manifest: cf-hello-worlds/ruby-sinatra/manifest.yml 73 | on_failure: 74 | put: slack 75 | params: 76 | <<: *slack-params 77 | text: | 78 | :x: Failed to deploy ruby-sinatra sample app 79 | <$ATC_EXTERNAL_URL/teams/$BUILD_TEAM_NAME/pipelines/$BUILD_PIPELINE_NAME/jobs/$BUILD_JOB_NAME/builds/$BUILD_NAME|View build details> 80 | 81 | - name: deploy-nodejs 82 | serial_groups: [apps] 83 | plan: 84 | - in_parallel: *plan-gets 85 | - put: deploy-nodejs-staging 86 | params: 87 | config: 88 | platform: linux 89 | image_resource: 90 | type: registry-image 91 | source: *general-task 92 | path: cf-hello-worlds/nodejs 93 | manifest: cf-hello-worlds/nodejs/manifest.yml 94 | - put: deploy-nodejs-production 95 | params: 96 | config: 97 | platform: linux 98 | image_resource: 99 | type: registry-image 100 | source: *general-task 101 | path: cf-hello-worlds/nodejs 102 | manifest: cf-hello-worlds/nodejs/manifest.yml 103 | on_failure: 104 | put: slack 105 | params: 106 | <<: *slack-params 107 | text: | 108 | :x: Failed to deploy nodejs sample app 109 | <$ATC_EXTERNAL_URL/teams/$BUILD_TEAM_NAME/pipelines/$BUILD_PIPELINE_NAME/jobs/$BUILD_JOB_NAME/builds/$BUILD_NAME|View build details> 110 | 111 | - name: deploy-nodejs-cnb 112 | serial_groups: [apps] 113 | plan: 114 | - in_parallel: *plan-gets 115 | - put: deploy-nodejs-cnb-staging 116 | params: 117 | config: 118 | platform: linux 119 | image_resource: 120 | type: registry-image 121 | source: *general-task 122 | path: cf-hello-worlds/nodejs 123 | manifest: cf-hello-worlds/nodejs/manifest-cnb.yml 124 | - put: deploy-nodejs-cnb-production 125 | params: 126 | config: 127 | platform: linux 128 | image_resource: 129 | type: registry-image 130 | source: *general-task 131 | path: cf-hello-worlds/nodejs 132 | manifest: cf-hello-worlds/nodejs/manifest-cnb.yml 133 | on_failure: 134 | put: slack 135 | params: 136 | <<: *slack-params 137 | text: | 138 | :x: Failed to deploy nodejs CNB sample app 139 | <$ATC_EXTERNAL_URL/teams/$BUILD_TEAM_NAME/pipelines/$BUILD_PIPELINE_NAME/jobs/$BUILD_JOB_NAME/builds/$BUILD_NAME|View build details> 140 | 141 | - name: deploy-php 142 | serial_groups: [apps] 143 | plan: 144 | - in_parallel: *plan-gets 145 | - put: deploy-php-staging 146 | params: 147 | config: 148 | platform: linux 149 | image_resource: 150 | type: registry-image 151 | source: *general-task 152 | path: cf-hello-worlds/php 153 | manifest: cf-hello-worlds/php/manifest.yml 154 | - put: deploy-php-production 155 | params: 156 | config: 157 | platform: linux 158 | image_resource: 159 | type: registry-image 160 | source: *general-task 161 | path: cf-hello-worlds/php 162 | manifest: cf-hello-worlds/php/manifest.yml 163 | on_failure: 164 | put: slack 165 | params: 166 | <<: *slack-params 167 | text: | 168 | :x: Failed to deploy php sample app 169 | <$ATC_EXTERNAL_URL/teams/$BUILD_TEAM_NAME/pipelines/$BUILD_PIPELINE_NAME/jobs/$BUILD_JOB_NAME/builds/$BUILD_NAME|View build details> 170 | 171 | - name: deploy-java 172 | serial_groups: [apps] 173 | plan: 174 | - in_parallel: *plan-gets 175 | - task: build 176 | file: cf-hello-worlds/java-see/build-java-see.yml 177 | - put: deploy-java-staging 178 | params: 179 | config: 180 | platform: linux 181 | image_resource: 182 | type: registry-image 183 | source: *general-task 184 | path: cf-hello-worlds-build/java-see/target/hello-world-0.0.1-SNAPSHOT.jar 185 | manifest: cf-hello-worlds-build/java-see/manifest.yml 186 | - put: deploy-java-production 187 | params: 188 | config: 189 | platform: linux 190 | image_resource: 191 | type: registry-image 192 | source: *general-task 193 | path: cf-hello-worlds-build/java-see/target/hello-world-0.0.1-SNAPSHOT.jar 194 | manifest: cf-hello-worlds-build/java-see/manifest.yml 195 | on_failure: 196 | put: slack 197 | params: 198 | <<: *slack-params 199 | text: | 200 | :x: Failed to deploy java sample app 201 | <$ATC_EXTERNAL_URL/teams/$BUILD_TEAM_NAME/pipelines/$BUILD_PIPELINE_NAME/jobs/$BUILD_JOB_NAME/builds/$BUILD_NAME|View build details> 202 | 203 | - name: deploy-dotnet-core 204 | serial_groups: [apps] 205 | plan: 206 | - in_parallel: *plan-gets 207 | - put: deploy-dotnet-core-staging 208 | params: 209 | config: 210 | platform: linux 211 | image_resource: 212 | type: registry-image 213 | source: *general-task 214 | path: cf-hello-worlds/dotnet-core 215 | manifest: cf-hello-worlds/dotnet-core/manifest.yml 216 | - put: deploy-dotnet-core-production 217 | params: 218 | config: 219 | platform: linux 220 | image_resource: 221 | type: registry-image 222 | source: *general-task 223 | path: cf-hello-worlds/dotnet-core 224 | manifest: cf-hello-worlds/dotnet-core/manifest.yml 225 | on_failure: 226 | put: slack 227 | params: 228 | <<: *slack-params 229 | text: | 230 | :x: Failed to deploy dotnet-core sample app 231 | <$ATC_EXTERNAL_URL/teams/$BUILD_TEAM_NAME/pipelines/$BUILD_PIPELINE_NAME/jobs/$BUILD_JOB_NAME/builds/$BUILD_NAME|View build details> 232 | 233 | resources: 234 | - name: cf-hello-worlds 235 | type: git 236 | source: 237 | uri: https://github.com/cloud-gov/cf-hello-worlds 238 | branch: main 239 | commit_verification_keys: ((cloud-gov-pgp-keys)) 240 | 241 | - name: timer 242 | type: time 243 | source: 244 | interval: 24h 245 | 246 | - name: deploy-python-flask-staging 247 | type: cf 248 | source: &cf-source-staging 249 | api: ((staging-cf-api-url)) 250 | username: ((cf-username-staging)) 251 | password: ((cf-password-staging)) 252 | organization: ((cf-organization-staging)) 253 | space: ((cf-space-staging)) 254 | 255 | - name: deploy-ruby-sinatra-staging 256 | type: cf 257 | source: *cf-source-staging 258 | 259 | - name: deploy-nodejs-staging 260 | type: cf 261 | source: *cf-source-staging 262 | 263 | - name: deploy-nodejs-cnb-staging 264 | type: cf 265 | source: *cf-source-staging 266 | 267 | - name: deploy-php-staging 268 | type: cf 269 | source: *cf-source-staging 270 | 271 | - name: deploy-java-staging 272 | type: cf 273 | source: *cf-source-staging 274 | 275 | - name: deploy-dotnet-core-staging 276 | type: cf 277 | source: *cf-source-staging 278 | 279 | - name: deploy-python-flask-production 280 | type: cf 281 | source: &cf-source-production 282 | api: ((prod-cf-api-url)) 283 | username: ((cf-username-production)) 284 | password: ((cf-password-production)) 285 | organization: ((cf-organization-production)) 286 | space: ((cf-space-production)) 287 | 288 | - name: deploy-ruby-sinatra-production 289 | type: cf 290 | source: *cf-source-production 291 | 292 | - name: deploy-nodejs-production 293 | type: cf 294 | source: *cf-source-production 295 | 296 | - name: deploy-nodejs-cnb-production 297 | type: cf 298 | source: *cf-source-production 299 | 300 | - name: deploy-php-production 301 | type: cf 302 | source: *cf-source-production 303 | 304 | - name: deploy-java-production 305 | type: cf 306 | source: *cf-source-production 307 | 308 | - name: deploy-dotnet-core-production 309 | type: cf 310 | source: *cf-source-production 311 | 312 | - name: slack 313 | type: slack-notification 314 | source: 315 | url: ((slack-webhook-url)) 316 | 317 | resource_types: 318 | - name: slack-notification 319 | type: registry-image 320 | source: 321 | aws_access_key_id: ((ecr_aws_key)) 322 | aws_secret_access_key: ((ecr_aws_secret)) 323 | repository: slack-notification-resource 324 | aws_region: us-gov-west-1 325 | tag: latest 326 | 327 | - name: git 328 | type: registry-image 329 | source: 330 | aws_access_key_id: ((ecr_aws_key)) 331 | aws_secret_access_key: ((ecr_aws_secret)) 332 | repository: git-resource 333 | aws_region: us-gov-west-1 334 | tag: latest 335 | 336 | - name: cf 337 | type: registry-image 338 | source: 339 | aws_access_key_id: ((ecr_aws_key)) 340 | aws_secret_access_key: ((ecr_aws_secret)) 341 | repository: cf-resource 342 | aws_region: us-gov-west-1 343 | tag: latest 344 | 345 | - name: registry-image 346 | type: registry-image 347 | source: 348 | aws_access_key_id: ((ecr_aws_key)) 349 | aws_secret_access_key: ((ecr_aws_secret)) 350 | repository: registry-image-resource 351 | aws_region: us-gov-west-1 352 | tag: latest 353 | 354 | - name: time 355 | type: registry-image 356 | source: 357 | aws_access_key_id: ((ecr_aws_key)) 358 | aws_secret_access_key: ((ecr_aws_secret)) 359 | repository: time-resource 360 | aws_region: us-gov-west-1 361 | tag: latest 362 | -------------------------------------------------------------------------------- /python-flask-socketio/Procfile: -------------------------------------------------------------------------------- 1 | web: python hello.py -------------------------------------------------------------------------------- /python-flask-socketio/README.md: -------------------------------------------------------------------------------- 1 | # Python Flask + Socket IO example 2 | 3 | This example application shows how to integrate Python Flask with [Socket IO](https://socket.io/) to handle websocket traffic in your Python Flask application. 4 | 5 | ## Deploying 6 | 7 | Deploy the example application: 8 | 9 | ```shell 10 | cf push 11 | ``` 12 | 13 | Assuming you are in the correct cf org and space, the above command is all you 14 | need. See also: [Cloud.gov Quickstart](https://cloud.gov/docs/getting-started/your-first-deploy/). 15 | 16 | ## Testing the websocket connection 17 | 18 | > You must have `node`/`npm` installed on your machine to use the `client.js` script for testing the websocket connection 19 | 20 | 1. Install the Node.js dependencies for the `client.js` script: 21 | 22 | ```shell 23 | npm install 24 | ``` 25 | 26 | 1. Update this line in `client.js` with the URL of your application: 27 | 28 | ```javascript 29 | const socket = io("wss://.app.cloud.gov"); 30 | ``` 31 | 32 | 1. Run the `client.js` file: 33 | 34 | ```shell 35 | node client.js 36 | ``` 37 | 38 | If you see output like: 39 | 40 | ```shell 41 | received message: Hello from the server! 42 | Sent message: Hi there! 43 | ``` 44 | 45 | Then everything is working correctly. If the `client.js` script seems to produce no output, then: 46 | 47 | - Double-check that you updated the URL in `client.js` correctly 48 | - Inspect the logs from the example application for errors: 49 | 50 | ```shell 51 | cf logs test-python-flask-socketio --recent 52 | ``` 53 | -------------------------------------------------------------------------------- /python-flask-socketio/client.js: -------------------------------------------------------------------------------- 1 | const { io } = require("socket.io-client"); 2 | 3 | const socket = io("wss://.app.cloud.gov"); 4 | 5 | socket.on("connect", () => { 6 | const message = 'Hi there!' 7 | socket.send(message); 8 | console.log('Sent message: ' + message) 9 | }); 10 | 11 | socket.on("message", (msg) => { 12 | console.log(`received message: ${msg}`) 13 | }) 14 | -------------------------------------------------------------------------------- /python-flask-socketio/hello.py: -------------------------------------------------------------------------------- 1 | import os 2 | from flask import Flask, current_app, request 3 | from flask_socketio import SocketIO, send 4 | 5 | port = os.getenv("PORT", "5000") 6 | app = Flask(__name__) 7 | app.debug = True 8 | socketio = SocketIO(app, logger=True, engineio_logger=True) 9 | 10 | 11 | @socketio.on("connect") 12 | def on_connect(): 13 | send("Hello from the server!") 14 | current_app.logger.info( 15 | f"Socket {request.sid} connected from {request.environ.get('HTTP_ORIGIN')}" 16 | ) 17 | return True 18 | 19 | 20 | @socketio.on("disconnect") 21 | def on_disconnect(): 22 | current_app.logger.info(f"Socket {request.sid} disconnected") 23 | 24 | 25 | @socketio.on("message") 26 | def handle_message(data): 27 | print("received message: " + data) 28 | 29 | 30 | @socketio.on_error_default 31 | def default_error_handler(e): 32 | print(e) 33 | print(request.event["message"]) 34 | print(request.event["args"]) 35 | 36 | 37 | @socketio.on_error 38 | def default_error_handler(e): 39 | print("Error: {}".format(e)) 40 | 41 | 42 | @app.route("/") 43 | def hello(): 44 | return "Hello World from Flask!" 45 | 46 | 47 | if __name__ == "__main__": 48 | socketio.run(app, host="0.0.0.0", port=int(port), debug=True) 49 | -------------------------------------------------------------------------------- /python-flask-socketio/manifest.yml: -------------------------------------------------------------------------------- 1 | --- 2 | applications: 3 | - name: test-python-flask-socketio 4 | random-route: true 5 | buildpacks: 6 | - python_buildpack 7 | memory: 256M 8 | stack: cflinuxfs4 9 | 10 | -------------------------------------------------------------------------------- /python-flask-socketio/package-lock.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "python-flask-socketio", 3 | "lockfileVersion": 3, 4 | "requires": true, 5 | "packages": { 6 | "": { 7 | "dependencies": { 8 | "socket.io-client": "^4.8.1" 9 | } 10 | }, 11 | "node_modules/@socket.io/component-emitter": { 12 | "version": "3.1.2", 13 | "resolved": "https://registry.npmjs.org/@socket.io/component-emitter/-/component-emitter-3.1.2.tgz", 14 | "integrity": "sha512-9BCxFwvbGg/RsZK9tjXd8s4UcwR0MWeFQ1XEKIQVVvAGJyINdrqKMcTRyLoK8Rse1GjzLV9cwjWV1olXRWEXVA==", 15 | "license": "MIT" 16 | }, 17 | "node_modules/debug": { 18 | "version": "4.3.7", 19 | "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.7.tgz", 20 | "integrity": "sha512-Er2nc/H7RrMXZBFCEim6TCmMk02Z8vLC2Rbi1KEBggpo0fS6l0S1nnapwmIi3yW/+GOJap1Krg4w0Hg80oCqgQ==", 21 | "license": "MIT", 22 | "dependencies": { 23 | "ms": "^2.1.3" 24 | }, 25 | "engines": { 26 | "node": ">=6.0" 27 | }, 28 | "peerDependenciesMeta": { 29 | "supports-color": { 30 | "optional": true 31 | } 32 | } 33 | }, 34 | "node_modules/engine.io-client": { 35 | "version": "6.6.3", 36 | "resolved": "https://registry.npmjs.org/engine.io-client/-/engine.io-client-6.6.3.tgz", 37 | "integrity": "sha512-T0iLjnyNWahNyv/lcjS2y4oE358tVS/SYQNxYXGAJ9/GLgH4VCvOQ/mhTjqU88mLZCQgiG8RIegFHYCdVC+j5w==", 38 | "license": "MIT", 39 | "dependencies": { 40 | "@socket.io/component-emitter": "~3.1.0", 41 | "debug": "~4.3.1", 42 | "engine.io-parser": "~5.2.1", 43 | "ws": "~8.17.1", 44 | "xmlhttprequest-ssl": "~2.1.1" 45 | } 46 | }, 47 | "node_modules/engine.io-parser": { 48 | "version": "5.2.3", 49 | "resolved": "https://registry.npmjs.org/engine.io-parser/-/engine.io-parser-5.2.3.tgz", 50 | "integrity": "sha512-HqD3yTBfnBxIrbnM1DoD6Pcq8NECnh8d4As1Qgh0z5Gg3jRRIqijury0CL3ghu/edArpUYiYqQiDUQBIs4np3Q==", 51 | "license": "MIT", 52 | "engines": { 53 | "node": ">=10.0.0" 54 | } 55 | }, 56 | "node_modules/ms": { 57 | "version": "2.1.3", 58 | "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", 59 | "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==", 60 | "license": "MIT" 61 | }, 62 | "node_modules/socket.io-client": { 63 | "version": "4.8.1", 64 | "resolved": "https://registry.npmjs.org/socket.io-client/-/socket.io-client-4.8.1.tgz", 65 | "integrity": "sha512-hJVXfu3E28NmzGk8o1sHhN3om52tRvwYeidbj7xKy2eIIse5IoKX3USlS6Tqt3BHAtflLIkCQBkzVrEEfWUyYQ==", 66 | "license": "MIT", 67 | "dependencies": { 68 | "@socket.io/component-emitter": "~3.1.0", 69 | "debug": "~4.3.2", 70 | "engine.io-client": "~6.6.1", 71 | "socket.io-parser": "~4.2.4" 72 | }, 73 | "engines": { 74 | "node": ">=10.0.0" 75 | } 76 | }, 77 | "node_modules/socket.io-parser": { 78 | "version": "4.2.4", 79 | "resolved": "https://registry.npmjs.org/socket.io-parser/-/socket.io-parser-4.2.4.tgz", 80 | "integrity": "sha512-/GbIKmo8ioc+NIWIhwdecY0ge+qVBSMdgxGygevmdHj24bsfgtCmcUUcQ5ZzcylGFHsN3k4HB4Cgkl96KVnuew==", 81 | "license": "MIT", 82 | "dependencies": { 83 | "@socket.io/component-emitter": "~3.1.0", 84 | "debug": "~4.3.1" 85 | }, 86 | "engines": { 87 | "node": ">=10.0.0" 88 | } 89 | }, 90 | "node_modules/ws": { 91 | "version": "8.17.1", 92 | "resolved": "https://registry.npmjs.org/ws/-/ws-8.17.1.tgz", 93 | "integrity": "sha512-6XQFvXTkbfUOZOKKILFG1PDK2NDQs4azKQl26T0YS5CxqWLgXajbPZ+h4gZekJyRqFU8pvnbAbbs/3TgRPy+GQ==", 94 | "license": "MIT", 95 | "engines": { 96 | "node": ">=10.0.0" 97 | }, 98 | "peerDependencies": { 99 | "bufferutil": "^4.0.1", 100 | "utf-8-validate": ">=5.0.2" 101 | }, 102 | "peerDependenciesMeta": { 103 | "bufferutil": { 104 | "optional": true 105 | }, 106 | "utf-8-validate": { 107 | "optional": true 108 | } 109 | } 110 | }, 111 | "node_modules/xmlhttprequest-ssl": { 112 | "version": "2.1.2", 113 | "resolved": "https://registry.npmjs.org/xmlhttprequest-ssl/-/xmlhttprequest-ssl-2.1.2.tgz", 114 | "integrity": "sha512-TEU+nJVUUnA4CYJFLvK5X9AOeH4KvDvhIfm0vV1GaQRtchnG0hgK5p8hw/xjv8cunWYCsiPCSDzObPyhEwq3KQ==", 115 | "engines": { 116 | "node": ">=0.4.0" 117 | } 118 | } 119 | } 120 | } 121 | -------------------------------------------------------------------------------- /python-flask-socketio/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "dependencies": { 3 | "socket.io-client": "^4.8.1" 4 | } 5 | } 6 | -------------------------------------------------------------------------------- /python-flask-socketio/requirements.txt: -------------------------------------------------------------------------------- 1 | click==8.1.7 2 | flask==2.2.5 3 | itsdangerous==2.2.0 4 | jinja2==3.1.5 5 | markupsafe==2.1.5 6 | werkzeug==3.0.6 7 | flask-socketio==5.5.1 8 | eventlet==0.40.0 9 | -------------------------------------------------------------------------------- /python-flask/Procfile: -------------------------------------------------------------------------------- 1 | web: python hello.py -------------------------------------------------------------------------------- /python-flask/README.md: -------------------------------------------------------------------------------- 1 | # How to push the example Python Flask app to your space 2 | 3 | ```shell 4 | cf push 5 | ``` 6 | 7 | Assuming you are in the correct cf org and space, the above command is all you 8 | need. See also: [Cloud.gov Quickstart](https://cloud.gov/docs/getting-started/your-first-deploy/). 9 | -------------------------------------------------------------------------------- /python-flask/hello.py: -------------------------------------------------------------------------------- 1 | import os 2 | from flask import Flask 3 | 4 | app = Flask(__name__) 5 | 6 | 7 | @app.route('/') 8 | def hello(): 9 | return 'Hello World from Flask!' 10 | 11 | 12 | port = os.getenv('PORT', '5000') 13 | if __name__ == "__main__": 14 | app.run(host='0.0.0.0', port=int(port)) 15 | -------------------------------------------------------------------------------- /python-flask/manifest.yml: -------------------------------------------------------------------------------- 1 | --- 2 | applications: 3 | - name: test-python-flask 4 | random-route: true 5 | buildpacks: 6 | - python_buildpack 7 | memory: 256M 8 | stack: cflinuxfs4 9 | 10 | -------------------------------------------------------------------------------- /python-flask/requirements.txt: -------------------------------------------------------------------------------- 1 | click==8.1.7 2 | flask==2.2.5 3 | itsdangerous==2.2.0 4 | jinja2==3.1.5 5 | markupsafe==2.1.5 6 | werkzeug==3.0.6 7 | -------------------------------------------------------------------------------- /ruby-sinatra/.ruby-version: -------------------------------------------------------------------------------- 1 | 3.3.3 2 | -------------------------------------------------------------------------------- /ruby-sinatra/Gemfile: -------------------------------------------------------------------------------- 1 | source 'https://rubygems.org' 2 | 3 | gem 'sinatra' 4 | gem 'rackup' 5 | gem 'puma' 6 | -------------------------------------------------------------------------------- /ruby-sinatra/Gemfile.lock: -------------------------------------------------------------------------------- 1 | GEM 2 | remote: https://rubygems.org/ 3 | specs: 4 | base64 (0.2.0) 5 | logger (1.7.0) 6 | mustermann (3.0.3) 7 | ruby2_keywords (~> 0.0.1) 8 | nio4r (2.7.3) 9 | puma (6.4.3) 10 | nio4r (~> 2.0) 11 | rack (3.1.14) 12 | rack-protection (4.1.1) 13 | base64 (>= 0.1.0) 14 | logger (>= 1.6.0) 15 | rack (>= 3.0.0, < 4) 16 | rack-session (2.1.1) 17 | base64 (>= 0.1.0) 18 | rack (>= 3.0.0) 19 | rackup (2.1.0) 20 | rack (>= 3) 21 | webrick (~> 1.8) 22 | ruby2_keywords (0.0.5) 23 | sinatra (4.1.1) 24 | logger (>= 1.6.0) 25 | mustermann (~> 3.0) 26 | rack (>= 3.0.0, < 4) 27 | rack-protection (= 4.1.1) 28 | rack-session (>= 2.0.0, < 3) 29 | tilt (~> 2.0) 30 | tilt (2.6.0) 31 | webrick (1.9.1) 32 | 33 | PLATFORMS 34 | ruby 35 | 36 | DEPENDENCIES 37 | puma 38 | rackup 39 | sinatra 40 | 41 | BUNDLED WITH 42 | 2.3.26 43 | -------------------------------------------------------------------------------- /ruby-sinatra/config.ru: -------------------------------------------------------------------------------- 1 | require './server' 2 | run Sinatra::Application 3 | -------------------------------------------------------------------------------- /ruby-sinatra/manifest.yml: -------------------------------------------------------------------------------- 1 | --- 2 | applications: 3 | - name: test-ruby-sinatra 4 | random-route: true 5 | buildpacks: 6 | - ruby_buildpack 7 | memory: 256M 8 | stack: cflinuxfs4 9 | -------------------------------------------------------------------------------- /ruby-sinatra/server.rb: -------------------------------------------------------------------------------- 1 | require 'sinatra' 2 | 3 | get '/' do 4 | "Hello World from Sinatra!" 5 | end 6 | -------------------------------------------------------------------------------- /static/Staticfile: -------------------------------------------------------------------------------- 1 | root: src 2 | -------------------------------------------------------------------------------- /static/manifest.yml: -------------------------------------------------------------------------------- 1 | applications: 2 | - name: test-static 3 | buildpack: staticfile_buildpack 4 | random-route: true 5 | -------------------------------------------------------------------------------- /static/src/index.html: -------------------------------------------------------------------------------- 1 | Hello from cloud.gov! 2 | --------------------------------------------------------------------------------