├── .github └── workflows │ ├── codeql-analysis.yml │ ├── dependency-review.yml │ ├── deploy-docker.yml │ ├── dockerhub-release.yaml │ ├── maven-pulls.yml │ ├── maven.yml │ ├── prepare-release.yml │ └── release.yml ├── .gitignore ├── .whitesource ├── CI ├── docker-release.sh ├── ghApiClient.py ├── lastRelease.py ├── post-release.sh ├── pre-release.sh ├── prepare-release.sh ├── publishRelease.py ├── releaseNotes.py └── version.sh ├── Dockerfile ├── Dockerfile-telemetry ├── LICENSE ├── README.md ├── inflector.yaml ├── pom.xml └── src ├── gen └── java │ └── io │ └── swagger │ ├── controllers │ └── StringUtil.java │ └── handler │ └── StringUtil.java ├── main ├── java │ └── io │ │ └── swagger │ │ └── petstore │ │ ├── controller │ │ ├── OrderController.java │ │ ├── PetController.java │ │ └── UserController.java │ │ ├── data │ │ ├── OrderData.java │ │ ├── PetData.java │ │ └── UserData.java │ │ ├── exception │ │ ├── ApiException.java │ │ └── NotFoundException.java │ │ ├── model │ │ ├── ApiResponse.java │ │ ├── Category.java │ │ ├── Order.java │ │ ├── Pet.java │ │ ├── Tag.java │ │ └── User.java │ │ ├── notification │ │ ├── BugSnagNotifier.java │ │ ├── Notifier.java │ │ └── NullNotifier.java │ │ └── utils │ │ ├── HandleAuthUrlProcessor.java │ │ └── Util.java ├── resources │ └── openapi.yaml └── webapp │ ├── WEB-INF │ └── web.xml │ └── index.html └── test └── java └── ip └── swagger └── petstore └── PetStoreTest.java /.github/workflows/codeql-analysis.yml: -------------------------------------------------------------------------------- 1 | name: "Code scanning - action" 2 | 3 | on: 4 | push: 5 | branches: ["master"] 6 | pull_request: 7 | # The branches below must be a subset of the branches above 8 | branches: ["master"] 9 | schedule: 10 | - cron: '0 19 * * 1' 11 | 12 | jobs: 13 | CodeQL-Build: 14 | 15 | runs-on: ubuntu-latest 16 | 17 | steps: 18 | - name: Checkout repository 19 | uses: actions/checkout@v4 20 | with: 21 | # We must fetch at least the immediate parents so that if this is 22 | # a pull request then we can checkout the head. 23 | fetch-depth: 2 24 | 25 | # If this run was triggered by a pull request event, then checkout 26 | # the head of the pull request instead of the merge commit. 27 | - run: git checkout HEAD^2 28 | if: ${{ github.event_name == 'pull_request' }} 29 | 30 | # Initializes the CodeQL tools for scanning. 31 | - name: Initialize CodeQL 32 | uses: github/codeql-action/init@v3 33 | # Override language selection by uncommenting this and choosing your languages 34 | with: 35 | languages: java 36 | 37 | # Autobuild attempts to build any compiled languages (C/C++, C#, or Java). 38 | # If this step fails, then you should remove it and run the build manually (see below) 39 | - name: Autobuild 40 | uses: github/codeql-action/autobuild@v3 41 | 42 | # ℹ️ Command-line programs to run using the OS shell. 43 | # 📚 https://git.io/JvXDl 44 | 45 | # ✏️ If the Autobuild fails above, remove it and uncomment the following three lines 46 | # and modify them (or add more) to build your code if your project 47 | # uses a compiled language 48 | 49 | #- run: | 50 | # make bootstrap 51 | # make release 52 | 53 | - name: Perform CodeQL Analysis 54 | uses: github/codeql-action/analyze@v3 55 | -------------------------------------------------------------------------------- /.github/workflows/dependency-review.yml: -------------------------------------------------------------------------------- 1 | name: 'Dependency Review' 2 | on: [pull_request] 3 | 4 | permissions: 5 | contents: read 6 | 7 | jobs: 8 | dependency-review: 9 | runs-on: ubuntu-latest 10 | steps: 11 | - name: 'Checkout Repository' 12 | uses: actions/checkout@v4 13 | - name: Dependency Review 14 | uses: actions/dependency-review-action@v3 15 | with: 16 | fail-on-severity: high 17 | -------------------------------------------------------------------------------- /.github/workflows/deploy-docker.yml: -------------------------------------------------------------------------------- 1 | name: Deploy Docker 2 | 3 | on: 4 | workflow_dispatch: 5 | branches: ["master"] 6 | inputs: 7 | tag: 8 | description: tag/version to deploy 9 | required: true 10 | jobs: 11 | deploy: 12 | 13 | runs-on: ubuntu-latest 14 | 15 | steps: 16 | - name: deploy docker 17 | run: | 18 | SC_RELEASE_TAG="${{ env.TAG }}" 19 | echo "$SC_RELEASE_TAG" 20 | 21 | TOKEN="${{ secrets.RANCHER2_BEARER_TOKEN }}" 22 | BUGSNAG_API_KEY=${{ secrets.BUGSNAG_API_KEY }} 23 | RANCHER_HOST="rancher.tools.swagger.io" 24 | CLUSTER_ID="c-n8zp2" 25 | NAMESPACE_NAME="swagger-oss" 26 | K8S_OBJECT_TYPE="daemonsets" 27 | K8S_OBJECT_NAME="swagger-petstore-3" 28 | DEPLOY_IMAGE="swaggerapi/swagger-petstore3:$SC_RELEASE_TAG-telemetry" 29 | 30 | workloadStatus="" 31 | getStatus() { 32 | echo "Getting update status..." 33 | if ! workloadStatus="$(curl -s -X GET \ 34 | -H "Authorization: Bearer ${TOKEN}" \ 35 | -H 'Content-Type: application/json' \ 36 | "https://${RANCHER_HOST}/k8s/clusters/${CLUSTER_ID}/apis/apps/v1/namespaces/${NAMESPACE_NAME}/${K8S_OBJECT_TYPE}/${K8S_OBJECT_NAME}/status")" 37 | then 38 | echo 'ERROR - get status k8s API call failed!' 39 | echo "Exiting build"... 40 | exit 1 41 | fi 42 | } 43 | 44 | # $1 = image to deploy 45 | updateObject() { 46 | local image="${1}" 47 | echo "Updating image value..." 48 | 49 | if ! curl -s -X PATCH \ 50 | -H "Authorization: Bearer ${TOKEN}" \ 51 | -H 'Content-Type: application/json-patch+json' \ 52 | "https://${RANCHER_HOST}/k8s/clusters/${CLUSTER_ID}/apis/apps/v1/namespaces/${NAMESPACE_NAME}/${K8S_OBJECT_TYPE}/${K8S_OBJECT_NAME}" \ 53 | -d "[{\"op\": \"replace\", \"path\": \"/spec/template/spec/containers/0/image\", \"value\": \"${image}\"}, {\"op\":\"add\",\"path\":\"/spec/template/spec/containers/0/env\",\"value\":[{\"name\":\"BUGSNAG_API_KEY\",\"value\":\"${BUGSNAG_API_KEY}\"},{\"name\":\"notifierClass\",\"value\":\"io.swagger.petstore.notification.BugSnagNotifier\"}]}]" 54 | then 55 | echo 'ERROR - image update k8s API call failed!' 56 | echo "Exiting build..." 57 | exit 1 58 | fi 59 | } 60 | 61 | 62 | # Check that the TAG is valid 63 | if [[ $SC_RELEASE_TAG =~ ^[vV]?[0-9]*\.[0-9]*\.[0-9]*$ ]]; then 64 | echo "" 65 | echo "This is a Valid TAG..." 66 | 67 | # Get current image/tag in case we need to rollback 68 | getStatus 69 | ROLLBACK_IMAGE="$(echo "${workloadStatus}" | jq -r '.spec.template.spec.containers[0].image')" 70 | echo "" 71 | echo "Current image: ${ROLLBACK_IMAGE}" 72 | 73 | # Update image and validate response 74 | echo "" 75 | updateObject "${DEPLOY_IMAGE}" 76 | echo "" 77 | 78 | echo "" 79 | echo "Waiting for pods to start..." 80 | echo "" 81 | sleep 60s 82 | 83 | # Get state of the k8s object. If numberReady == desiredNumberScheduled, consider the upgrade successful. Else raise error 84 | getStatus 85 | status="$(echo "${workloadStatus}" | jq '.status')" 86 | echo "" 87 | echo "${status}" 88 | echo "" 89 | 90 | numberDesired="$(echo "${status}" | jq -r '.desiredNumberScheduled')" 91 | numberReady="$(echo "${status}" | jq -r '.numberReady')" 92 | 93 | if (( numberReady == numberDesired )); then 94 | echo "${K8S_OBJECT_NAME} has been upgraded to ${DEPLOY_IMAGE}" 95 | 96 | # If pods are not starting, rollback the upgrade and exit the build with error 97 | else 98 | echo "state = error...rolling back upgrade" 99 | updateObject "${ROLLBACK_IMAGE}" 100 | echo "" 101 | 102 | echo "" 103 | echo "Waiting for rollback pods to start..." 104 | echo "" 105 | sleep 60s 106 | 107 | getStatus 108 | status="$(echo "${workloadStatus}" | jq '.status')" 109 | echo "" 110 | echo "${status}" 111 | echo "" 112 | 113 | numberDesired="$(echo "${status}" | jq -r '.desiredNumberScheduled')" 114 | numberReady="$(echo "${status}" | jq -r '.numberReady')" 115 | 116 | if (( numberReady == numberDesired )); then 117 | echo "Rollback to ${ROLLBACK_IMAGE} completed." 118 | else 119 | echo "FATAL - rollback failed" 120 | fi 121 | echo "Exiting Build..." 122 | exit 1 123 | fi 124 | 125 | else 126 | echo "This TAG is not in a valid format..." 127 | echo "Exiting Build..." 128 | exit 0 129 | fi 130 | echo "Exiting Build..." 131 | exit 0 132 | env: 133 | ACTIONS_ALLOW_UNSECURE_COMMANDS: true 134 | GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} 135 | TAG: ${{ github.event.inputs.tag }} 136 | -------------------------------------------------------------------------------- /.github/workflows/dockerhub-release.yaml: -------------------------------------------------------------------------------- 1 | name: Docker Release 2 | 3 | on: 4 | workflow_dispatch: 5 | branches: ["master"] 6 | inputs: 7 | tag: 8 | description: tag/version to release 9 | required: true 10 | 11 | jobs: 12 | build: 13 | 14 | runs-on: ubuntu-latest 15 | 16 | steps: 17 | - uses: actions/checkout@v4 18 | - name: Set up Python 3.10 19 | uses: actions/setup-python@v4 20 | with: 21 | python-version: '3.10' 22 | - name: Set up Java 11 23 | uses: actions/setup-java@v4 24 | with: 25 | java-version: 11 26 | distribution: 'temurin' 27 | - name: Run pre release script 28 | id: preRelease 29 | run: | 30 | # export GPG_TTY=$(tty) 31 | export MY_POM_VERSION=`mvn -q -Dexec.executable="echo" -Dexec.args='${projects.version}' --non-recursive org.codehaus.mojo:exec-maven-plugin:1.3.1:exec` 32 | if [[ $MY_POM_VERSION =~ ^.*SNAPSHOT$ ]]; 33 | then 34 | echo "not releasing snapshot version: " ${MY_POM_VERSION} 35 | echo "RELEASE_OK=no" >> $GITHUB_ENV 36 | else 37 | . ./CI/pre-release.sh 38 | echo "RELEASE_OK=yes" >> $GITHUB_ENV 39 | fi 40 | echo "SC_VERSION=$SC_VERSION" >> $GITHUB_ENV 41 | echo "SC_NEXT_VERSION=$SC_NEXT_VERSION" >> $GITHUB_ENV 42 | echo "SC_LAST_RELEASE=$SC_LAST_RELEASE" >> $GITHUB_ENV 43 | - name: docker login 44 | run: | 45 | docker login --username=${{ secrets.DOCKERHUB_SB_USERNAME }} --password=${{ secrets.DOCKERHUB_SB_PASSWORD }} 46 | set -e 47 | - name: Build generator image and push 48 | if: env.RELEASE_OK == 'yes' 49 | uses: docker/build-push-action@v5 50 | with: 51 | context: . 52 | push: true 53 | platforms: linux/amd64 54 | provenance: false 55 | tags: swaggerapi/petstore3:${{ env.TAG }} 56 | - name: Build generator image and push 57 | if: env.RELEASE_OK == 'yes' 58 | uses: docker/build-push-action@v5 59 | with: 60 | file: Dockerfile-telemetry 61 | context: . 62 | push: true 63 | platforms: linux/amd64 64 | provenance: false 65 | tags: swaggerapi/petstore3:${{ env.TAG }}-telemetry 66 | env: 67 | ACTIONS_ALLOW_UNSECURE_COMMANDS: true 68 | GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} 69 | SC_VERSION: 70 | SC_NEXT_VERSION: 71 | TAG: ${{ github.event.inputs.tag }} 72 | 73 | -------------------------------------------------------------------------------- /.github/workflows/maven-pulls.yml: -------------------------------------------------------------------------------- 1 | name: Build Test PR 2 | 3 | on: 4 | pull_request: 5 | branches: [ "master" ] 6 | 7 | jobs: 8 | build: 9 | 10 | runs-on: ubuntu-latest 11 | strategy: 12 | matrix: 13 | java: [ 11 ] 14 | 15 | steps: 16 | - uses: actions/checkout@v4 17 | - name: Set up Java 18 | uses: actions/setup-java@v4 19 | with: 20 | java-version: ${{ matrix.java }} 21 | distribution: temurin 22 | server-id: central 23 | server-username: MAVEN_USERNAME 24 | server-password: MAVEN_PASSWORD 25 | - name: Cache local Maven repository 26 | uses: actions/cache@v4 27 | with: 28 | path: ~/.m2/repository 29 | key: ${{ runner.os }}-maven-${{ hashFiles('**/pom.xml') }} 30 | restore-keys: | 31 | ${{ runner.os }}-maven- 32 | - name: Build with Maven 33 | run: | 34 | mvn --no-transfer-progress -B install --file pom.xml 35 | env: 36 | MAVEN_USERNAME: ${{ secrets.MAVEN_CENTRAL_USERNAME }} 37 | MAVEN_PASSWORD: ${{ secrets.MAVEN_CENTRAL_PASSWORD }} -------------------------------------------------------------------------------- /.github/workflows/maven.yml: -------------------------------------------------------------------------------- 1 | name: Build Test master 2 | 3 | on: 4 | push: 5 | branches: [ "master" ] 6 | 7 | jobs: 8 | build: 9 | 10 | runs-on: ubuntu-latest 11 | strategy: 12 | matrix: 13 | java: [ 11 ] 14 | 15 | steps: 16 | - uses: actions/checkout@v4 17 | - name: Set up Java 18 | uses: actions/setup-java@v4 19 | with: 20 | java-version: ${{ matrix.java }} 21 | distribution: temurin 22 | server-id: central 23 | server-username: MAVEN_USERNAME 24 | server-password: MAVEN_PASSWORD 25 | - name: Cache local Maven repository 26 | uses: actions/cache@v4 27 | with: 28 | path: ~/.m2/repository 29 | key: ${{ runner.os }}-maven-${{ hashFiles('**/pom.xml') }} 30 | restore-keys: | 31 | ${{ runner.os }}-maven- 32 | - name: Build with Maven 33 | run: | 34 | mvn --no-transfer-progress -B install --file pom.xml 35 | env: 36 | MAVEN_USERNAME: ${{ secrets.MAVEN_CENTRAL_USERNAME }} 37 | MAVEN_PASSWORD: ${{ secrets.MAVEN_CENTRAL_PASSWORD }} -------------------------------------------------------------------------------- /.github/workflows/prepare-release.yml: -------------------------------------------------------------------------------- 1 | name: Prepare Release 2 | 3 | on: 4 | workflow_dispatch: 5 | branches: ["master"] 6 | 7 | jobs: 8 | build: 9 | 10 | runs-on: ubuntu-latest 11 | 12 | steps: 13 | - uses: actions/checkout@v4 14 | - uses: tibdex/github-app-token@v1 15 | id: generate-token 16 | with: 17 | app_id: ${{ secrets.APP_ID }} 18 | private_key: ${{ secrets.APP_PRIVATE_KEY }} 19 | - name: Set up Python 3.10 20 | uses: actions/setup-python@v4 21 | with: 22 | python-version: '3.10' 23 | - name: Set up Java 24 | uses: actions/setup-java@v4 25 | with: 26 | java-version: 11 27 | distribution: temurin 28 | server-id: central 29 | server-username: MAVEN_USERNAME 30 | server-password: MAVEN_PASSWORD 31 | - name: Cache local Maven repository 32 | uses: actions/cache@v4 33 | with: 34 | path: ~/.m2/repository 35 | key: ${{ runner.os }}-maven-${{ hashFiles('**/pom.xml') }} 36 | restore-keys: | 37 | ${{ runner.os }}-maven- 38 | - name: Run prepare release script 39 | id: prepare-release 40 | run: | 41 | export MY_POM_VERSION=`mvn -q -Dexec.executable="echo" -Dexec.args='${projects.version}' --non-recursive org.codehaus.mojo:exec-maven-plugin:1.3.1:exec` 42 | if [[ $MY_POM_VERSION =~ ^.*SNAPSHOT$ ]]; 43 | then 44 | . ./CI/prepare-release.sh 45 | echo "PREPARE_RELEASE_OK=yes" >> $GITHUB_ENV 46 | else 47 | echo "not preparing release for release version: " ${MY_POM_VERSION} 48 | echo "PREPARE_RELEASE_OK=no" >> $GITHUB_ENV 49 | fi 50 | echo "SC_VERSION=$SC_VERSION" >> $GITHUB_ENV 51 | echo "SC_NEXT_VERSION=$SC_NEXT_VERSION" >> $GITHUB_ENV 52 | - name: Create Prepare Release Pull Request 53 | uses: peter-evans/create-pull-request@v4 54 | if: env.PREPARE_RELEASE_OK == 'yes' 55 | with: 56 | token: ${{ steps.generate-token.outputs.token }} 57 | commit-message: prepare release ${{ env.SC_VERSION }} 58 | title: 'prepare release ${{ env.SC_VERSION }}' 59 | branch: prepare-release-${{ env.SC_VERSION }} 60 | env: 61 | ACTIONS_ALLOW_UNSECURE_COMMANDS: true 62 | GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} 63 | SC_VERSION: 64 | SC_NEXT_VERSION: 65 | MAVEN_USERNAME: ${{ secrets.MAVEN_CENTRAL_USERNAME }} 66 | MAVEN_PASSWORD: ${{ secrets.MAVEN_CENTRAL_PASSWORD }} 67 | -------------------------------------------------------------------------------- /.github/workflows/release.yml: -------------------------------------------------------------------------------- 1 | name: Release 2 | 3 | on: 4 | workflow_dispatch: 5 | branches: ["master"] 6 | 7 | jobs: 8 | build: 9 | 10 | runs-on: ubuntu-latest 11 | 12 | steps: 13 | - uses: actions/checkout@v4 14 | - uses: tibdex/github-app-token@v1 15 | id: generate-token 16 | with: 17 | app_id: ${{ secrets.APP_ID }} 18 | private_key: ${{ secrets.APP_PRIVATE_KEY }} 19 | - name: Set up Python 3.10 20 | uses: actions/setup-python@v4 21 | with: 22 | python-version: '3.10' 23 | - name: Set up Java 24 | uses: actions/setup-java@v4 25 | with: 26 | java-version: 11 27 | distribution: temurin 28 | server-id: central 29 | server-username: MAVEN_USERNAME 30 | server-password: MAVEN_PASSWORD 31 | - name: Cache local Maven repository 32 | uses: actions/cache@v4 33 | with: 34 | path: ~/.m2/repository 35 | key: ${{ runner.os }}-maven-${{ hashFiles('**/pom.xml') }} 36 | restore-keys: | 37 | ${{ runner.os }}-maven- 38 | - name: Run pre release script 39 | id: preRelease 40 | run: | 41 | # export GPG_TTY=$(tty) 42 | export MY_POM_VERSION=`mvn -q -Dexec.executable="echo" -Dexec.args='${projects.version}' --non-recursive org.codehaus.mojo:exec-maven-plugin:1.3.1:exec` 43 | if [[ $MY_POM_VERSION =~ ^.*SNAPSHOT$ ]]; 44 | then 45 | echo "not releasing snapshot version: " ${MY_POM_VERSION} 46 | echo "RELEASE_OK=no" >> $GITHUB_ENV 47 | else 48 | . ./CI/pre-release.sh 49 | echo "RELEASE_OK=yes" >> $GITHUB_ENV 50 | fi 51 | echo "SC_VERSION=$SC_VERSION" >> $GITHUB_ENV 52 | echo "SC_NEXT_VERSION=$SC_NEXT_VERSION" >> $GITHUB_ENV 53 | echo "SC_LAST_RELEASE=$SC_LAST_RELEASE" >> $GITHUB_ENV 54 | - name: configure git user email 55 | run: | 56 | git config --global user.email "action@github.com" 57 | git config --global user.name "GitHub Action" 58 | git config --global hub.protocol https 59 | git remote set-url origin https://\${{ secrets.GITHUB_TOKEN }}:x-oauth-basic@github.com/swagger-api/swagger-petstore.git 60 | - name: docker login 61 | run: | 62 | docker login --username=${{ secrets.DOCKERHUB_SB_USERNAME }} --password=${{ secrets.DOCKERHUB_SB_PASSWORD }} 63 | set -e 64 | - name: Docker build and push 65 | id: docker_build_push 66 | if: env.RELEASE_OK == 'yes' 67 | run: | 68 | . ./CI/docker-release.sh 69 | - name: Run post release script 70 | id: postRelease 71 | if: env.RELEASE_OK == 'yes' 72 | run: | 73 | . ./CI/post-release.sh 74 | - name: Create Next Snapshot Pull Request 75 | uses: peter-evans/create-pull-request@v4 76 | if: env.RELEASE_OK == 'yes' 77 | with: 78 | token: ${{ steps.generate-token.outputs.token }} 79 | commit-message: bump snapshot ${{ env.SC_NEXT_VERSION }}-SNAPSHOT 80 | title: 'bump snapshot ${{ env.SC_NEXT_VERSION }}-SNAPSHOT' 81 | branch: bump-snap-${{ env.SC_NEXT_VERSION }}-SNAPSHOT 82 | - name: deploy docker 83 | run: | 84 | SC_RELEASE_TAG="${{ env.SC_VERSION }}" 85 | echo "$SC_RELEASE_TAG" 86 | 87 | TOKEN="${{ secrets.RANCHER2_BEARER_TOKEN }}" 88 | BUGSNAG_API_KEY=${{ secrets.BUGSNAG_API_KEY }} 89 | RANCHER_HOST="rancher.tools.swagger.io" 90 | CLUSTER_ID="c-n8zp2" 91 | NAMESPACE_NAME="swagger-oss" 92 | K8S_OBJECT_TYPE="daemonsets" 93 | K8S_OBJECT_NAME="swagger-petstore-3" 94 | DEPLOY_IMAGE="swaggerapi/petstore3:$SC_RELEASE_TAG-telemetry" 95 | 96 | workloadStatus="" 97 | getStatus() { 98 | echo "Getting update status..." 99 | if ! workloadStatus="$(curl -s -X GET \ 100 | -H "Authorization: Bearer ${TOKEN}" \ 101 | -H 'Content-Type: application/json' \ 102 | "https://${RANCHER_HOST}/k8s/clusters/${CLUSTER_ID}/apis/apps/v1/namespaces/${NAMESPACE_NAME}/${K8S_OBJECT_TYPE}/${K8S_OBJECT_NAME}/status")" 103 | then 104 | echo 'ERROR - get status k8s API call failed!' 105 | echo "Exiting build"... 106 | exit 1 107 | fi 108 | } 109 | 110 | # $1 = image to deploy 111 | updateObject() { 112 | local image="${1}" 113 | echo "Updating image value..." 114 | 115 | if ! curl -s -X PATCH \ 116 | -H "Authorization: Bearer ${TOKEN}" \ 117 | -H 'Content-Type: application/json-patch+json' \ 118 | "https://${RANCHER_HOST}/k8s/clusters/${CLUSTER_ID}/apis/apps/v1/namespaces/${NAMESPACE_NAME}/${K8S_OBJECT_TYPE}/${K8S_OBJECT_NAME}" \ 119 | -d "[{\"op\": \"replace\", \"path\": \"/spec/template/spec/containers/0/image\", \"value\": \"${image}\"}, {\"op\":\"add\",\"path\":\"/spec/template/spec/containers/0/env\",\"value\":[{\"name\":\"BUGSNAG_API_KEY\",\"value\":\"${BUGSNAG_API_KEY}\"},{\"name\":\"notifierClass\",\"value\":\"io.swagger.petstore.notification.BugSnagNotifier\"}]}]" 120 | then 121 | echo 'ERROR - image update k8s API call failed!' 122 | echo "Exiting build..." 123 | exit 1 124 | fi 125 | } 126 | 127 | 128 | # Check that the TAG is valid 129 | if [[ $SC_RELEASE_TAG =~ ^[vV]?[0-9]*\.[0-9]*\.[0-9]*$ ]]; then 130 | echo "" 131 | echo "This is a Valid TAG..." 132 | 133 | # Get current image/tag in case we need to rollback 134 | getStatus 135 | ROLLBACK_IMAGE="$(echo "${workloadStatus}" | jq -r '.spec.template.spec.containers[0].image')" 136 | echo "" 137 | echo "Current image: ${ROLLBACK_IMAGE}" 138 | 139 | # Update image and validate response 140 | echo "" 141 | updateObject "${DEPLOY_IMAGE}" 142 | echo "" 143 | 144 | echo "" 145 | echo "Waiting for pods to start..." 146 | echo "" 147 | sleep 60s 148 | 149 | # Get state of the k8s object. If numberReady == desiredNumberScheduled, consider the upgrade successful. Else raise error 150 | getStatus 151 | status="$(echo "${workloadStatus}" | jq '.status')" 152 | echo "" 153 | echo "${status}" 154 | echo "" 155 | 156 | numberDesired="$(echo "${status}" | jq -r '.desiredNumberScheduled')" 157 | numberReady="$(echo "${status}" | jq -r '.numberReady')" 158 | 159 | if (( numberReady == numberDesired )); then 160 | echo "${K8S_OBJECT_NAME} has been upgraded to ${DEPLOY_IMAGE}" 161 | 162 | # If pods are not starting, rollback the upgrade and exit the build with error 163 | else 164 | echo "state = error...rolling back upgrade" 165 | updateObject "${ROLLBACK_IMAGE}" 166 | echo "" 167 | 168 | echo "" 169 | echo "Waiting for rollback pods to start..." 170 | echo "" 171 | sleep 60s 172 | 173 | getStatus 174 | status="$(echo "${workloadStatus}" | jq '.status')" 175 | echo "" 176 | echo "${status}" 177 | echo "" 178 | 179 | numberDesired="$(echo "${status}" | jq -r '.desiredNumberScheduled')" 180 | numberReady="$(echo "${status}" | jq -r '.numberReady')" 181 | 182 | if (( numberReady == numberDesired )); then 183 | echo "Rollback to ${ROLLBACK_IMAGE} completed." 184 | else 185 | echo "FATAL - rollback failed" 186 | fi 187 | echo "Exiting Build..." 188 | exit 1 189 | fi 190 | 191 | else 192 | echo "This TAG is not in a valid format..." 193 | echo "Exiting Build..." 194 | exit 0 195 | fi 196 | echo "Exiting Build..." 197 | exit 0 198 | env: 199 | ACTIONS_ALLOW_UNSECURE_COMMANDS: true 200 | GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} 201 | SC_VERSION: 202 | SC_NEXT_VERSION: 203 | MAVEN_USERNAME: ${{ secrets.MAVEN_CENTRAL_USERNAME }} 204 | MAVEN_PASSWORD: ${{ secrets.MAVEN_CENTRAL_PASSWORD }} -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | build/ 2 | lib/*.jar 3 | target 4 | .idea 5 | .idea_modules 6 | .settings 7 | .project 8 | .classpath 9 | .cache 10 | atlassian-ide-plugin.xml 11 | *.iml 12 | .java-version 13 | dependency-reduced-pom.xml 14 | *.pyc -------------------------------------------------------------------------------- /.whitesource: -------------------------------------------------------------------------------- 1 | { 2 | "settingsInheritedFrom": "swagger-api/whitesource-config@main", 3 | "scanSettings": { 4 | "baseBranches": ["master", "v2"] 5 | } 6 | } 7 | -------------------------------------------------------------------------------- /CI/docker-release.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | CUR=$(pwd) 4 | 5 | SC_RELEASE_TAG="$SC_VERSION" 6 | 7 | echo "docker tag:" 8 | echo "$SC_RELEASE_TAG" 9 | 10 | export DOCKER_PETSTORE_IMAGE_NAME=swaggerapi/petstore3 11 | docker build --rm=false -t $DOCKER_PETSTORE_IMAGE_NAME:$SC_RELEASE_TAG . 12 | docker tag $DOCKER_PETSTORE_IMAGE_NAME:$SC_RELEASE_TAG $DOCKER_PETSTORE_IMAGE_NAME:latest 13 | docker push $DOCKER_PETSTORE_IMAGE_NAME:$SC_RELEASE_TAG 14 | docker push $DOCKER_PETSTORE_IMAGE_NAME:latest 15 | docker build --rm=false -t $DOCKER_PETSTORE_IMAGE_NAME:$SC_RELEASE_TAG-telemetry -f Dockerfile-telemetry . 16 | docker tag $DOCKER_PETSTORE_IMAGE_NAME:$SC_RELEASE_TAG-telemetry $DOCKER_PETSTORE_IMAGE_NAME:latest-telemetry 17 | docker push $DOCKER_PETSTORE_IMAGE_NAME:$SC_RELEASE_TAG-telemetry 18 | docker push $DOCKER_PETSTORE_IMAGE_NAME:latest-telemetry 19 | echo "docker images:" 20 | docker images | grep -i petstore3 21 | -------------------------------------------------------------------------------- /CI/ghApiClient.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/python 2 | 3 | import os 4 | import time 5 | import urllib.request, urllib.error, urllib.parse 6 | import http.client 7 | import json 8 | 9 | GH_BASE_URL = "https://api.github.com/" 10 | 11 | GH_TOKEN = os.environ['GH_TOKEN'] 12 | GH_AUTH = "Bearer %s" % GH_TOKEN 13 | 14 | def readUrl(name): 15 | try: 16 | request = urllib.request.Request(GH_BASE_URL + name) 17 | request.add_header("Authorization", GH_AUTH) 18 | content = urllib.request.urlopen(request).read() 19 | jcont = json.loads(content) 20 | return jcont 21 | except urllib.error.HTTPError as e: 22 | print(('HTTPError = ' + str(e.code))) 23 | raise e 24 | except urllib.error.URLError as e: 25 | print(('URLError = ' + str(e.reason))) 26 | raise e 27 | except http.client.HTTPException as e: 28 | print(('HTTPException = ' + str(e))) 29 | raise e 30 | except Exception: 31 | import traceback 32 | print(('generic exception: ' + traceback.format_exc())) 33 | raise IOError 34 | 35 | def postUrl(name, body): 36 | global GH_BASE_URL 37 | try: 38 | time.sleep(0.05) 39 | request = urllib.request.Request(GH_BASE_URL + name) 40 | request.add_header("Authorization", GH_AUTH) 41 | request.add_header("Accept", "application/vnd.github.v3+json") 42 | data = body.encode('utf-8') 43 | content = urllib.request.urlopen(request, data).read() 44 | jcont = json.loads(content) 45 | return jcont 46 | except urllib.error.HTTPError as e: 47 | print(('HTTPError = ' + str(e.code))) 48 | print((str(e))) 49 | raise e 50 | except urllib.error.URLError as e: 51 | print(('URLError = ' + str(e.reason))) 52 | raise e 53 | except http.client.HTTPException as e: 54 | print(('HTTPException = ' + str(e))) 55 | raise e 56 | except Exception: 57 | import traceback 58 | print(('generic exception: ' + traceback.format_exc())) 59 | raise IOError 60 | -------------------------------------------------------------------------------- /CI/lastRelease.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/python 2 | 3 | import ghApiClient 4 | 5 | def getLastReleaseTag(): 6 | content = ghApiClient.readUrl('repos/swagger-api/swagger-petstore/releases') 7 | for l in content: 8 | draft = l["draft"] 9 | tag = l["tag_name"] 10 | if str(draft) != 'True' and tag.startswith("swagger-petstore-v3-"): 11 | return tag 12 | print ("NO RELEASE TAG FOUND, using default swagger-petstore-v3-1.0.17") 13 | return "swagger-petstore-v3-1.0.17" 14 | # main 15 | def main(): 16 | result = getLastReleaseTag() 17 | print (result) 18 | 19 | # here start main 20 | main() 21 | -------------------------------------------------------------------------------- /CI/post-release.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | CUR=$(pwd) 4 | TMPDIR="$(dirname -- "${0}")" 5 | 6 | SC_RELEASE_TAG="swagger-petstore-v3-$SC_VERSION" 7 | 8 | ##################### 9 | ### publish pre-prepared release (tag is created) 10 | ##################### 11 | python $CUR/CI/publishRelease.py "$SC_RELEASE_TAG" 12 | 13 | ##################### 14 | ### update the version to next snapshot in maven project with set version 15 | ##################### 16 | mvn versions:set -DnewVersion="${SC_NEXT_VERSION}-SNAPSHOT" 17 | mvn versions:commit 18 | 19 | ##################### 20 | ### update all other versions in files around to the next snapshot or new release, including readme and gradle ### 21 | ##################### 22 | 23 | sc_find="version\: $SC_VERSION" 24 | sc_replace="version: $SC_NEXT_VERSION-SNAPSHOT" 25 | sed -i -e "s/$sc_find/$sc_replace/g" $CUR/src/main/resources/openapi.yaml 26 | -------------------------------------------------------------------------------- /CI/pre-release.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | CUR=$(pwd) 4 | 5 | export SC_VERSION=`mvn -q -Dexec.executable="echo" -Dexec.args='${parsedVersion.majorVersion}.${parsedVersion.minorVersion}.${parsedVersion.incrementalVersion}' --non-recursive build-helper:parse-version org.codehaus.mojo:exec-maven-plugin:1.3.1:exec` 6 | export SC_NEXT_VERSION=`mvn -q -Dexec.executable="echo" -Dexec.args='${parsedVersion.majorVersion}.${parsedVersion.minorVersion}.${parsedVersion.nextIncrementalVersion}' --non-recursive build-helper:parse-version org.codehaus.mojo:exec-maven-plugin:1.3.1:exec` 7 | SC_QUALIFIER=`mvn -q -Dexec.executable="echo" -Dexec.args='${parsedVersion.qualifier}' --non-recursive build-helper:parse-version org.codehaus.mojo:exec-maven-plugin:1.3.1:exec` 8 | #SC_LAST_RELEASE=`mvn -q -Dexec.executable="echo" -Dexec.args='${releasedVersion.version}' --non-recursive org.codehaus.mojo:build-helper-maven-plugin:3.2.0:released-version org.codehaus.mojo:exec-maven-plugin:1.3.1:exec` 9 | SC_LAST_RELEASE=`python $CUR/CI/lastRelease.py` 10 | 11 | 12 | SC_RELEASE_TAG="$SC_VERSION" 13 | 14 | 15 | ##################### 16 | ### build and test maven ### 17 | ##################### 18 | mvn --no-transfer-progress -B install --file pom.xml 19 | -------------------------------------------------------------------------------- /CI/prepare-release.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | CUR=$(pwd) 4 | 5 | export SC_VERSION=`mvn -q -Dexec.executable="echo" -Dexec.args='${parsedVersion.majorVersion}.${parsedVersion.minorVersion}.${parsedVersion.incrementalVersion}' --non-recursive build-helper:parse-version org.codehaus.mojo:exec-maven-plugin:1.3.1:exec` 6 | export SC_NEXT_VERSION=`mvn -q -Dexec.executable="echo" -Dexec.args='${parsedVersion.majorVersion}.${parsedVersion.minorVersion}.${parsedVersion.nextIncrementalVersion}' --non-recursive build-helper:parse-version org.codehaus.mojo:exec-maven-plugin:1.3.1:exec` 7 | SC_QUALIFIER=`mvn -q -Dexec.executable="echo" -Dexec.args='${parsedVersion.qualifier}' --non-recursive build-helper:parse-version org.codehaus.mojo:exec-maven-plugin:1.3.1:exec` 8 | #SC_LAST_RELEASE=`mvn -q -Dexec.executable="echo" -Dexec.args='${releasedVersion.version}' --non-recursive org.codehaus.mojo:build-helper-maven-plugin:3.2.0:released-version org.codehaus.mojo:exec-maven-plugin:1.3.1:exec` 9 | SC_LAST_RELEASE=`python $CUR/CI/lastRelease.py` 10 | 11 | 12 | 13 | SC_RELEASE_TITLE="Swagger Petstore OpenAPI 3.0 release $SC_VERSION" 14 | SC_RELEASE_TAG="swagger-petstore-v3-$SC_VERSION" 15 | 16 | echo "SC_VERSION: $SC_VERSION" 17 | echo "SC_NEXT_VERSION: $SC_NEXT_VERSION" 18 | echo "SC_LAST_RELEASE: $SC_LAST_RELEASE" 19 | echo "SC_RELEASE_TITLE: $SC_RELEASE_TITLE" 20 | echo "SC_RELEASE_TAG: $SC_RELEASE_TAG" 21 | 22 | ##################### 23 | ### draft release Notes with next release after last release, with tag 24 | ##################### 25 | python $CUR/CI/releaseNotes.py "$SC_LAST_RELEASE" "$SC_RELEASE_TITLE" "$SC_RELEASE_TAG" 26 | 27 | ##################### 28 | ### update the version to release in maven project with set version 29 | ##################### 30 | mvn versions:set -DnewVersion=$SC_VERSION 31 | mvn versions:commit 32 | 33 | ##################### 34 | ### update version in openapi.yaml file ### 35 | ##################### 36 | sc_find="version\: $SC_VERSION\-SNAPSHOT" 37 | sc_replace="version: $SC_VERSION" 38 | sed -i -e "s/$sc_find/$sc_replace/g" $CUR/src/main/resources/openapi.yaml 39 | 40 | ##################### 41 | ### build and test maven ### 42 | ##################### 43 | mvn --no-transfer-progress -B install --file pom.xml 44 | 45 | -------------------------------------------------------------------------------- /CI/publishRelease.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/python 2 | 3 | import sys 4 | import ghApiClient 5 | 6 | def lastReleaseId(tag): 7 | content = ghApiClient.readUrl('repos/swagger-api/swagger-petstore/releases') 8 | for l in content: 9 | draft = l["draft"] 10 | draft_tag = l["tag_name"] 11 | if str(draft) == 'True' and tag == draft_tag: 12 | return l["id"] 13 | 14 | def publishRelease(tag): 15 | id = lastReleaseId(tag) 16 | payload = "{\"tag_name\":\"" + tag + "\", " 17 | payload += "\"draft\":" + "false" + ", " 18 | payload += "\"target_commitish\":\"" + "master" + "\"}" 19 | content = ghApiClient.postUrl('repos/swagger-api/swagger-petstore/releases/' + str(id), payload) 20 | return content 21 | 22 | # main 23 | def main(tag): 24 | publishRelease (tag) 25 | 26 | # here start main 27 | main(sys.argv[1]) 28 | -------------------------------------------------------------------------------- /CI/releaseNotes.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/python 2 | 3 | import sys 4 | import json 5 | from datetime import datetime 6 | import ghApiClient 7 | 8 | def allPulls(releaseDate): 9 | 10 | result = "" 11 | 12 | baseurl = "https://api.github.com/repos/swagger-api/swagger-petstore/pulls/" 13 | content = ghApiClient.readUrl('repos/swagger-api/swagger-petstore/pulls?state=closed&base=master&per_page=100') 14 | for l in content: 15 | stripped = l["url"][len(baseurl):] 16 | mergedAt = l["merged_at"] 17 | if mergedAt is not None: 18 | if datetime.strptime(mergedAt, '%Y-%m-%dT%H:%M:%SZ') > releaseDate: 19 | if not l['title'].startswith("bump snap"): 20 | result += '\n' 21 | result += "* " + l['title'] + " (#" + stripped + ")" 22 | return result 23 | 24 | 25 | def lastReleaseDate(tag): 26 | content = ghApiClient.readUrl('repos/swagger-api/swagger-petstore/releases/tags/' + tag) 27 | publishedAt = content["published_at"] 28 | return datetime.strptime(publishedAt, '%Y-%m-%dT%H:%M:%SZ') 29 | 30 | 31 | def addRelease(release_title, tag, content): 32 | payload = "{\"tag_name\":\"" + tag + "\", " 33 | payload += "\"name\":" + json.dumps(release_title) + ", " 34 | payload += "\"body\":" + json.dumps(content) + ", " 35 | payload += "\"draft\":" + "true" + ", " 36 | payload += "\"prerelease\":" + "false" + ", " 37 | payload += "\"target_commitish\":\"" + "master" + "\"}" 38 | content = ghApiClient.postUrl('repos/swagger-api/swagger-petstore/releases', payload) 39 | return content 40 | 41 | def getReleases(): 42 | content = ghApiClient.readUrl('repos/swagger-api/swagger-petstore/releases') 43 | return content 44 | 45 | # main 46 | def main(last_release, release_title, tag): 47 | result = allPulls(lastReleaseDate(last_release)) 48 | addRelease (release_title, tag, result) 49 | 50 | # here start main 51 | main(sys.argv[1], sys.argv[2], sys.argv[3]) 52 | 53 | -------------------------------------------------------------------------------- /CI/version.sh: -------------------------------------------------------------------------------- 1 | grep version pom.xml | grep -v -e '//g' | awk '{print $1}' -------------------------------------------------------------------------------- /Dockerfile: -------------------------------------------------------------------------------- 1 | FROM openjdk:8-jre-alpine 2 | 3 | WORKDIR /swagger-petstore 4 | 5 | COPY target/lib/jetty-runner.jar /swagger-petstore/jetty-runner.jar 6 | COPY target/*.war /swagger-petstore/server.war 7 | COPY src/main/resources/openapi.yaml /swagger-petstore/openapi.yaml 8 | COPY inflector.yaml /swagger-petstore/ 9 | 10 | EXPOSE 8080 11 | 12 | CMD ["java", "-jar", "-DswaggerUrl=openapi.yaml", "/swagger-petstore/jetty-runner.jar", "--log", "/var/log/yyyy_mm_dd-requests.log", "/swagger-petstore/server.war"] 13 | -------------------------------------------------------------------------------- /Dockerfile-telemetry: -------------------------------------------------------------------------------- 1 | FROM openjdk:11-jre-slim 2 | 3 | WORKDIR /swagger-petstore 4 | 5 | RUN apt-get update && apt-get install -y curl && rm -rf /var/lib/apt/lists/* 6 | 7 | RUN curl -Lo /swagger-petstore/otel-javaagent.jar \ 8 | "https://github.com/open-telemetry/opentelemetry-java-instrumentation/releases/latest/download/opentelemetry-javaagent.jar" 9 | 10 | COPY target/lib/jetty-runner.jar /swagger-petstore/jetty-runner.jar 11 | COPY target/*.war /swagger-petstore/server.war 12 | COPY src/main/resources/openapi.yaml /swagger-petstore/openapi.yaml 13 | COPY inflector.yaml /swagger-petstore/ 14 | 15 | EXPOSE 8080 16 | 17 | ENV JAVA_TOOL_OPTIONS="-javaagent:/swagger-petstore/otel-javaagent.jar" \ 18 | OTEL_JAVAAGENT_ENABLED=true \ 19 | OTEL_TRACES_EXPORTER=otlp \ 20 | OTEL_METRICS_EXPORTER=none \ 21 | OTEL_LOGS_EXPORTER=otlp \ 22 | OTEL_RESOURCE_ATTRIBUTES="service.name=swagger-petstore,deployment.environment=prod" \ 23 | OTEL_JAVAAGENT_LOGGING=simple \ 24 | OTEL_INSTRUMENTATION_HTTP_CAPTURE_HEADERS_SERVER_REQUEST=user-agent,authorization \ 25 | OTEL_INSTRUMENTATION_HTTP_CAPTURE_HEADERS_SERVER_RESPONSE=content-type \ 26 | OTEL_INSTRUMENTATION_HTTP_CAPTURE_PARAMETERS=true \ 27 | OTEL_INSTRUMENTATION_HTTP_SERVER_CAPTURE_REQUEST_PARAMETERS=true \ 28 | OTEL_INSTRUMENTATION_HTTP_SERVER_CAPTURE_ROUTE=true \ 29 | OTEL_ATTRIBUTE_VALUE_LENGTH_LIMIT=256 \ 30 | OTEL_SESSION_TRACKING_ENABLED=true \ 31 | OTEL_SESSION_TRACKING_INTERVAL=30s \ 32 | OTEL_EXPORTER_OTLP_TRACES_ENDPOINT="https://$BUGSNAG_API_KEY.otlp.bugsnag.com:4318" \ 33 | BUGSNAG_SESSIONS_ENABLED=true 34 | 35 | CMD ["sh", "-c", "export BUGSNAG_API_KEY=$BUGSNAG_API_KEY && \ 36 | export OTEL_EXPORTER_OTLP_ENDPOINT=https://$BUGSNAG_API_KEY.otlp.bugsnag.com && \ 37 | exec java $JAVA_TOOL_OPTIONS -Dorg.eclipse.jetty.server.RequestLog=DEBUG -Dorg.eclipse.jetty.server.HttpChannel=DEBUG \ 38 | -jar -DswaggerUrl=openapi.yaml /swagger-petstore/jetty-runner.jar --log /var/log/yyyy_mm_dd-requests.log /swagger-petstore/server.war"] 39 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | Apache License 2 | Version 2.0, January 2004 3 | http://www.apache.org/licenses/ 4 | 5 | TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION 6 | 7 | 1. Definitions. 8 | 9 | "License" shall mean the terms and conditions for use, reproduction, 10 | and distribution as defined by Sections 1 through 9 of this document. 11 | 12 | "Licensor" shall mean the copyright owner or entity authorized by 13 | the copyright owner that is granting the License. 14 | 15 | "Legal Entity" shall mean the union of the acting entity and all 16 | other entities that control, are controlled by, or are under common 17 | control with that entity. For the purposes of this definition, 18 | "control" means (i) the power, direct or indirect, to cause the 19 | direction or management of such entity, whether by contract or 20 | otherwise, or (ii) ownership of fifty percent (50%) or more of the 21 | outstanding shares, or (iii) beneficial ownership of such entity. 22 | 23 | "You" (or "Your") shall mean an individual or Legal Entity 24 | exercising permissions granted by this License. 25 | 26 | "Source" form shall mean the preferred form for making modifications, 27 | including but not limited to software source code, documentation 28 | source, and configuration files. 29 | 30 | "Object" form shall mean any form resulting from mechanical 31 | transformation or translation of a Source form, including but 32 | not limited to compiled object code, generated documentation, 33 | and conversions to other media types. 34 | 35 | "Work" shall mean the work of authorship, whether in Source or 36 | Object form, made available under the License, as indicated by a 37 | copyright notice that is included in or attached to the work 38 | (an example is provided in the Appendix below). 39 | 40 | "Derivative Works" shall mean any work, whether in Source or Object 41 | form, that is based on (or derived from) the Work and for which the 42 | editorial revisions, annotations, elaborations, or other modifications 43 | represent, as a whole, an original work of authorship. For the purposes 44 | of this License, Derivative Works shall not include works that remain 45 | separable from, or merely link (or bind by name) to the interfaces of, 46 | the Work and Derivative Works thereof. 47 | 48 | "Contribution" shall mean any work of authorship, including 49 | the original version of the Work and any modifications or additions 50 | to that Work or Derivative Works thereof, that is intentionally 51 | submitted to Licensor for inclusion in the Work by the copyright owner 52 | or by an individual or Legal Entity authorized to submit on behalf of 53 | the copyright owner. For the purposes of this definition, "submitted" 54 | means any form of electronic, verbal, or written communication sent 55 | to the Licensor or its representatives, including but not limited to 56 | communication on electronic mailing lists, source code control systems, 57 | and issue tracking systems that are managed by, or on behalf of, the 58 | Licensor for the purpose of discussing and improving the Work, but 59 | excluding communication that is conspicuously marked or otherwise 60 | designated in writing by the copyright owner as "Not a Contribution." 61 | 62 | "Contributor" shall mean Licensor and any individual or Legal Entity 63 | on behalf of whom a Contribution has been received by Licensor and 64 | subsequently incorporated within the Work. 65 | 66 | 2. Grant of Copyright License. Subject to the terms and conditions of 67 | this License, each Contributor hereby grants to You a perpetual, 68 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable 69 | copyright license to reproduce, prepare Derivative Works of, 70 | publicly display, publicly perform, sublicense, and distribute the 71 | Work and such Derivative Works in Source or Object form. 72 | 73 | 3. Grant of Patent License. Subject to the terms and conditions of 74 | this License, each Contributor hereby grants to You a perpetual, 75 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable 76 | (except as stated in this section) patent license to make, have made, 77 | use, offer to sell, sell, import, and otherwise transfer the Work, 78 | where such license applies only to those patent claims licensable 79 | by such Contributor that are necessarily infringed by their 80 | Contribution(s) alone or by combination of their Contribution(s) 81 | with the Work to which such Contribution(s) was submitted. If You 82 | institute patent litigation against any entity (including a 83 | cross-claim or counterclaim in a lawsuit) alleging that the Work 84 | or a Contribution incorporated within the Work constitutes direct 85 | or contributory patent infringement, then any patent licenses 86 | granted to You under this License for that Work shall terminate 87 | as of the date such litigation is filed. 88 | 89 | 4. Redistribution. You may reproduce and distribute copies of the 90 | Work or Derivative Works thereof in any medium, with or without 91 | modifications, and in Source or Object form, provided that You 92 | meet the following conditions: 93 | 94 | (a) You must give any other recipients of the Work or 95 | Derivative Works a copy of this License; and 96 | 97 | (b) You must cause any modified files to carry prominent notices 98 | stating that You changed the files; and 99 | 100 | (c) You must retain, in the Source form of any Derivative Works 101 | that You distribute, all copyright, patent, trademark, and 102 | attribution notices from the Source form of the Work, 103 | excluding those notices that do not pertain to any part of 104 | the Derivative Works; and 105 | 106 | (d) If the Work includes a "NOTICE" text file as part of its 107 | distribution, then any Derivative Works that You distribute must 108 | include a readable copy of the attribution notices contained 109 | within such NOTICE file, excluding those notices that do not 110 | pertain to any part of the Derivative Works, in at least one 111 | of the following places: within a NOTICE text file distributed 112 | as part of the Derivative Works; within the Source form or 113 | documentation, if provided along with the Derivative Works; or, 114 | within a display generated by the Derivative Works, if and 115 | wherever such third-party notices normally appear. The contents 116 | of the NOTICE file are for informational purposes only and 117 | do not modify the License. You may add Your own attribution 118 | notices within Derivative Works that You distribute, alongside 119 | or as an addendum to the NOTICE text from the Work, provided 120 | that such additional attribution notices cannot be construed 121 | as modifying the License. 122 | 123 | You may add Your own copyright statement to Your modifications and 124 | may provide additional or different license terms and conditions 125 | for use, reproduction, or distribution of Your modifications, or 126 | for any such Derivative Works as a whole, provided Your use, 127 | reproduction, and distribution of the Work otherwise complies with 128 | the conditions stated in this License. 129 | 130 | 5. Submission of Contributions. Unless You explicitly state otherwise, 131 | any Contribution intentionally submitted for inclusion in the Work 132 | by You to the Licensor shall be under the terms and conditions of 133 | this License, without any additional terms or conditions. 134 | Notwithstanding the above, nothing herein shall supersede or modify 135 | the terms of any separate license agreement you may have executed 136 | with Licensor regarding such Contributions. 137 | 138 | 6. Trademarks. This License does not grant permission to use the trade 139 | names, trademarks, service marks, or product names of the Licensor, 140 | except as required for reasonable and customary use in describing the 141 | origin of the Work and reproducing the content of the NOTICE file. 142 | 143 | 7. Disclaimer of Warranty. Unless required by applicable law or 144 | agreed to in writing, Licensor provides the Work (and each 145 | Contributor provides its Contributions) on an "AS IS" BASIS, 146 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or 147 | implied, including, without limitation, any warranties or conditions 148 | of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A 149 | PARTICULAR PURPOSE. You are solely responsible for determining the 150 | appropriateness of using or redistributing the Work and assume any 151 | risks associated with Your exercise of permissions under this License. 152 | 153 | 8. Limitation of Liability. In no event and under no legal theory, 154 | whether in tort (including negligence), contract, or otherwise, 155 | unless required by applicable law (such as deliberate and grossly 156 | negligent acts) or agreed to in writing, shall any Contributor be 157 | liable to You for damages, including any direct, indirect, special, 158 | incidental, or consequential damages of any character arising as a 159 | result of this License or out of the use or inability to use the 160 | Work (including but not limited to damages for loss of goodwill, 161 | work stoppage, computer failure or malfunction, or any and all 162 | other commercial damages or losses), even if such Contributor 163 | has been advised of the possibility of such damages. 164 | 165 | 9. Accepting Warranty or Additional Liability. While redistributing 166 | the Work or Derivative Works thereof, You may choose to offer, 167 | and charge a fee for, acceptance of support, warranty, indemnity, 168 | or other liability obligations and/or rights consistent with this 169 | License. However, in accepting such obligations, You may act only 170 | on Your own behalf and on Your sole responsibility, not on behalf 171 | of any other Contributor, and only if You agree to indemnify, 172 | defend, and hold each Contributor harmless for any liability 173 | incurred by, or claims asserted against, such Contributor by reason 174 | of your accepting any such warranty or additional liability. 175 | 176 | END OF TERMS AND CONDITIONS 177 | 178 | APPENDIX: How to apply the Apache License to your work. 179 | 180 | To apply the Apache License to your work, attach the following 181 | boilerplate notice, with the fields enclosed by brackets "{}" 182 | replaced with your own identifying information. (Don't include 183 | the brackets!) The text should be enclosed in the appropriate 184 | comment syntax for the file format. We also recommend that a 185 | file or class name and description of purpose be included on the 186 | same "printed page" as the copyright notice for easier 187 | identification within third-party archives. 188 | 189 | Copyright {yyyy} {name of copyright owner} 190 | 191 | Licensed under the Apache License, Version 2.0 (the "License"); 192 | you may not use this file except in compliance with the License. 193 | You may obtain a copy of the License at 194 | 195 | http://www.apache.org/licenses/LICENSE-2.0 196 | 197 | Unless required by applicable law or agreed to in writing, software 198 | distributed under the License is distributed on an "AS IS" BASIS, 199 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 200 | See the License for the specific language governing permissions and 201 | limitations under the License. 202 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Swagger Petstore Sample 2 | 3 | ## Overview 4 | This is the pet store sample hosted at https://petstore3.swagger.io. For other versions, check the branches. 5 | We welcome suggestion both the code and the API design. 6 | To make changes to the design itself, take a look at https://github.com/swagger-api/swagger-petstore/blob/master/src/main/resources/openapi.yaml. 7 | 8 | This is a java project to build a stand-alone server which implements the OpenAPI 3 Spec. You can find out 9 | more about both the spec and the framework at http://swagger.io. 10 | 11 | This sample is based on [swagger-inflector](https://github.com/swagger-api/swagger-inflector), and provides an example of swagger / OpenAPI 3 petstore. 12 | 13 | ### To run (with Maven) 14 | To run the server, run this task: 15 | 16 | ``` 17 | mvn package jetty:run 18 | ``` 19 | 20 | This will start Jetty embedded on port 8080. 21 | 22 | ### To run (via Docker) 23 | 24 | Expose port 8080 from the image and access petstore via the exposed port. You can then add and delete pets as you see fit. 25 | 26 | 27 | *Example*: 28 | 29 | ``` 30 | docker build -t swaggerapi/petstore3:unstable . 31 | ``` 32 | 33 | ``` 34 | docker pull swaggerapi/petstore3:unstable 35 | docker run --name swaggerapi-petstore3 -d -p 8080:8080 swaggerapi/petstore3:unstable 36 | ``` 37 | 38 | 39 | ### Testing the server 40 | Once started, you can navigate to http://localhost:8080/api/v3/openapi.json to view the Swagger Resource Listing. 41 | This tells you that the server is up and ready to demonstrate Swagger. 42 | 43 | ### Using the UI 44 | There is an HTML5-based API tool bundled in this sample--you can view it it at [http://localhost:8080](http://localhost:8080). This lets you inspect the API using an interactive UI. You can access the source of this code from [here](https://github.com/swagger-api/swagger-ui) 45 | -------------------------------------------------------------------------------- /inflector.yaml: -------------------------------------------------------------------------------- 1 | controllerPackage: io.swagger.petstore.controller 2 | modelPackage: io.swagger.petstore.model 3 | swaggerUrl: openapi.yaml 4 | 5 | exposedSpecOptions: 6 | useOriginalNotParsed: true 7 | 8 | entityProcessors: 9 | - json 10 | - yaml 11 | - xml 12 | 13 | swaggerProcessors: 14 | - io.swagger.petstore.utils.HandleAuthUrlProcessor 15 | 16 | rootPath: /api -------------------------------------------------------------------------------- /pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 4.0.0 3 | io.swagger 4 | swagger-petstore 5 | war 6 | swagger-petstore 7 | swagger-petstore 8 | https://github.com/swagger-api/swagger-petstore 9 | 1.0.27-SNAPSHOT 10 | 11 | scm:git:git@github.com:swagger-api/swagger-petstore.git 12 | scm:git:git@github.com:swagger-api/swagger-petstore.git 13 | https://github.com/swagger-api/swagger-petstore 14 | 15 | 16 | 17 | frantuma 18 | Francesco Tumanischvili 19 | frantuma@yahoo.com 20 | 21 | 22 | 23 | github 24 | https://github.com/swagger-api/swagger-petstore/issues 25 | 26 | 27 | 28 | Apache License 2.0 29 | http://www.apache.org/licenses/LICENSE-2.0.html 30 | repo 31 | 32 | 33 | 34 | 2.2.0 35 | 36 | 37 | 38 | install 39 | target 40 | ${project.artifactId}-${project.version} 41 | 42 | 43 | maven-compiler-plugin 44 | 3.11.0 45 | 46 | 1.8 47 | 1.8 48 | 49 | 50 | 51 | org.codehaus.mojo 52 | build-helper-maven-plugin 53 | 1.12 54 | 55 | 56 | add-source 57 | generate-sources 58 | 59 | add-source 60 | 61 | 62 | 63 | src/gen/java 64 | 65 | 66 | 67 | 68 | 69 | 70 | maven-dependency-plugin 71 | 72 | 73 | package 74 | 75 | copy-dependencies 76 | copy 77 | 78 | 79 | ${project.build.directory}/lib 80 | 81 | 82 | org.eclipse.jetty 83 | jetty-runner 84 | ${jetty-version} 85 | jetty-runner.jar 86 | 87 | 88 | 89 | 90 | 91 | 92 | 93 | org.apache.maven.plugins 94 | maven-jar-plugin 95 | 2.6 96 | 97 | 98 | **/logback.xml 99 | 100 | 101 | 102 | development 103 | ${project.url} 104 | ${project.version} 105 | io.swagger 106 | 107 | 108 | 109 | 110 | 111 | org.eclipse.jetty 112 | jetty-maven-plugin 113 | ${jetty-version} 114 | 115 | . 116 | 117 | inflector.yaml 118 | 119 | 1 120 | 121 | / 122 | 123 | target/${project.artifactId}-${project.version} 124 | 125 | 8080 126 | 60000 127 | 128 | 129 | 130 | 131 | com.googlecode.maven-download-plugin 132 | download-maven-plugin 133 | 1.6.8 134 | 135 | 136 | swagger-ui 137 | validate 138 | 139 | wget 140 | 141 | 142 | true 143 | https://github.com/swagger-api/swagger-ui/archive/master.tar.gz 144 | true 145 | ${project.build.directory} 146 | 147 | 148 | 149 | 150 | 151 | maven-resources-plugin 152 | 2.4.3 153 | 154 | 155 | copy-resources 156 | prepare-package 157 | 158 | copy-resources 159 | 160 | 161 | target/${project.artifactId}-${project.version} 162 | 163 | 164 | ${project.build.directory}/swagger-ui-master/dist 165 | true 166 | 167 | index.html 168 | 169 | 170 | 171 | 172 | 173 | 174 | 175 | 176 | 177 | 178 | 179 | 180 | com.fasterxml.jackson.core 181 | jackson-databind 182 | ${jackson-version} 183 | 184 | 185 | com.fasterxml.jackson.core 186 | jackson-annotations 187 | ${jackson-version} 188 | 189 | 190 | com.fasterxml.jackson.jaxrs 191 | jackson-jaxrs-yaml-provider 192 | ${jackson-version} 193 | 194 | 195 | com.fasterxml.jackson.jaxrs 196 | jackson-jaxrs-xml-provider 197 | ${jackson-version} 198 | 199 | 200 | com.fasterxml.jackson.datatype 201 | jackson-datatype-joda 202 | ${jackson-version} 203 | 204 | 205 | 206 | 207 | io.swagger.core.v3 208 | swagger-jaxrs2 209 | ${swagger-core-version} 210 | 211 | 212 | 213 | io.swagger 214 | swagger-inflector 215 | ${swagger-inflector-version} 216 | 217 | 218 | io.swagger.parser.v3 219 | swagger-parser 220 | ${swagger-parser-version} 221 | 222 | 223 | 224 | javax.xml.bind 225 | jaxb-api 226 | 2.3.1 227 | 228 | 229 | com.sun.xml.bind 230 | jaxb-core 231 | 2.3.0.1 232 | 233 | 234 | com.sun.xml.bind 235 | jaxb-impl 236 | 2.3.1 237 | 238 | 239 | com.bugsnag 240 | [3.0,4.0) 241 | bugsnag 242 | 243 | 244 | 245 | 246 | 1.0.0 247 | 2.1.21 248 | 2.2.17 249 | 2.16.1 250 | 2.0.11 251 | 9.4.53.v20231009 252 | 1.4.11 253 | 4.13.2 254 | 2.0.9 255 | UTF-8 256 | 257 | 258 | -------------------------------------------------------------------------------- /src/gen/java/io/swagger/controllers/StringUtil.java: -------------------------------------------------------------------------------- 1 | package io.swagger.controllers; 2 | 3 | @javax.annotation.Generated(value = "class io.swagger.codegen.languages.JavaInflectorServerCodegen", date = "2017-04-07T14:38:28.915Z") 4 | public class StringUtil { 5 | /** 6 | * Check if the given array contains the given value (with case-insensitive comparison). 7 | * 8 | * @param array The array 9 | * @param value The value to search 10 | * @return true if the array contains the value 11 | */ 12 | public static boolean containsIgnoreCase(String[] array, String value) { 13 | for (String str : array) { 14 | if (value == null && str == null) return true; 15 | if (value != null && value.equalsIgnoreCase(str)) return true; 16 | } 17 | return false; 18 | } 19 | 20 | /** 21 | * Join an array of strings with the given separator. 22 | *

23 | * Note: This might be replaced by utility method from commons-lang or guava someday 24 | * if one of those libraries is added as dependency. 25 | *

26 | * 27 | * @param array The array of strings 28 | * @param separator The separator 29 | * @return the resulting string 30 | */ 31 | public static String join(String[] array, String separator) { 32 | int len = array.length; 33 | if (len == 0) return ""; 34 | 35 | StringBuilder out = new StringBuilder(); 36 | out.append(array[0]); 37 | for (int i = 1; i < len; i++) { 38 | out.append(separator).append(array[i]); 39 | } 40 | return out.toString(); 41 | } 42 | } 43 | -------------------------------------------------------------------------------- /src/gen/java/io/swagger/handler/StringUtil.java: -------------------------------------------------------------------------------- 1 | package io.swagger.handler; 2 | 3 | @javax.annotation.Generated(value = "class io.swagger.codegen.languages.JavaInflectorServerCodegen", date = "2017-04-08T15:48:56.501Z") 4 | public class StringUtil { 5 | /** 6 | * Check if the given array contains the given value (with case-insensitive comparison). 7 | * 8 | * @param array The array 9 | * @param value The value to search 10 | * @return true if the array contains the value 11 | */ 12 | public static boolean containsIgnoreCase(String[] array, String value) { 13 | for (String str : array) { 14 | if (value == null && str == null) return true; 15 | if (value != null && value.equalsIgnoreCase(str)) return true; 16 | } 17 | return false; 18 | } 19 | 20 | /** 21 | * Join an array of strings with the given separator. 22 | *

23 | * Note: This might be replaced by utility method from commons-lang or guava someday 24 | * if one of those libraries is added as dependency. 25 | *

26 | * 27 | * @param array The array of strings 28 | * @param separator The separator 29 | * @return the resulting string 30 | */ 31 | public static String join(String[] array, String separator) { 32 | int len = array.length; 33 | if (len == 0) return ""; 34 | 35 | StringBuilder out = new StringBuilder(); 36 | out.append(array[0]); 37 | for (int i = 1; i < len; i++) { 38 | out.append(separator).append(array[i]); 39 | } 40 | return out.toString(); 41 | } 42 | } 43 | -------------------------------------------------------------------------------- /src/main/java/io/swagger/petstore/controller/OrderController.java: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright 2018 SmartBear Software 3 | *

4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | *

8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | *

10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package io.swagger.petstore.controller; 18 | 19 | import io.swagger.oas.inflector.models.RequestContext; 20 | import io.swagger.oas.inflector.models.ResponseContext; 21 | import io.swagger.petstore.data.OrderData; 22 | import io.swagger.petstore.model.Order; 23 | import io.swagger.petstore.utils.Util; 24 | import org.joda.time.DateTime; 25 | 26 | import javax.ws.rs.core.Response; 27 | import java.util.Date; 28 | 29 | @javax.annotation.Generated(value = "class io.swagger.codegen.languages.JavaInflectorServerCodegen", date = "2017-04-08T15:48:56.501Z") 30 | public class OrderController { 31 | 32 | private static OrderData orderData = new OrderData(); 33 | 34 | public ResponseContext getInventory(final RequestContext request) { 35 | return new ResponseContext() 36 | .contentType(Util.getMediaType(request)) 37 | .entity(orderData.getCountByStatus()); 38 | } 39 | 40 | public ResponseContext getOrderById(final RequestContext request, final Long orderId) { 41 | if (orderId == null) { 42 | return new ResponseContext() 43 | .status(Response.Status.BAD_REQUEST) 44 | .entity("No orderId provided. Try again?"); 45 | } 46 | 47 | final Order order = orderData.getOrderById(orderId); 48 | 49 | if (order != null) { 50 | return new ResponseContext() 51 | .contentType(Util.getMediaType(request)) 52 | .entity(order); 53 | } 54 | 55 | return new ResponseContext().status(Response.Status.NOT_FOUND).entity("Order not found"); 56 | } 57 | 58 | public ResponseContext placeOrder(final RequestContext request, final Order order) { 59 | if (order == null) { 60 | return new ResponseContext() 61 | .status(Response.Status.BAD_REQUEST) 62 | .entity("No Order provided. Try again?"); 63 | } 64 | 65 | orderData.addOrder(order); 66 | return new ResponseContext() 67 | .contentType(Util.getMediaType(request)) 68 | .entity(order); 69 | } 70 | 71 | public ResponseContext placeOrder(final RequestContext request, final Long id, final Long petId, final Integer quantity, final DateTime shipDate, 72 | final String status, final Boolean complete) { 73 | final Order order = OrderData.createOrder(id, petId, quantity, new Date(), status, complete); 74 | return placeOrder(request,order); 75 | } 76 | 77 | public ResponseContext deleteOrder(final RequestContext request, final Long orderId) { 78 | if (orderId == null) { 79 | return new ResponseContext() 80 | .status(Response.Status.BAD_REQUEST) 81 | .entity("No orderId provided. Try again?"); 82 | } 83 | 84 | orderData.deleteOrderById(orderId); 85 | 86 | final Order order = orderData.getOrderById(orderId); 87 | 88 | if (null == order) { 89 | return new ResponseContext() 90 | .contentType(Util.getMediaType(request)) 91 | .entity(order); 92 | } else { 93 | return new ResponseContext().status(Response.Status.NOT_MODIFIED).entity("Order couldn't be deleted."); 94 | } 95 | } 96 | } -------------------------------------------------------------------------------- /src/main/java/io/swagger/petstore/controller/PetController.java: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright 2018 SmartBear Software 3 | *

4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | *

8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | *

10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package io.swagger.petstore.controller; 18 | 19 | import io.swagger.oas.inflector.models.RequestContext; 20 | import io.swagger.oas.inflector.models.ResponseContext; 21 | import io.swagger.petstore.data.PetData; 22 | import io.swagger.petstore.model.Category; 23 | import io.swagger.petstore.model.Pet; 24 | import io.swagger.petstore.model.Tag; 25 | import io.swagger.petstore.notification.Notifier; 26 | import io.swagger.petstore.notification.NullNotifier; 27 | import io.swagger.petstore.utils.Util; 28 | 29 | import javax.ws.rs.core.MediaType; 30 | import javax.ws.rs.core.Response; 31 | import java.io.File; 32 | import java.util.List; 33 | 34 | @javax.annotation.Generated(value = "class io.swagger.codegen.languages.JavaInflectorServerCodegen", date = "2017-04-08T15:48:56.501Z") 35 | public class PetController { 36 | 37 | private static PetData petData = new PetData(); 38 | private Notifier notifier = new NullNotifier(); 39 | 40 | public PetController() { 41 | if (System.getenv("notifierClass") != null) { 42 | try { 43 | notifier = (Notifier) this.getClass().forName(System.getenv("notifierClass")).newInstance(); 44 | } catch (Exception e) { 45 | // 46 | } 47 | } 48 | } 49 | 50 | public ResponseContext findPetsByStatus(final RequestContext request, final String status) { 51 | if (status == null) { 52 | notifier.notify(new RuntimeException("No status provided")); 53 | return new ResponseContext() 54 | .status(Response.Status.BAD_REQUEST) 55 | .entity("No status provided. Try again?"); 56 | } 57 | 58 | final List petByStatus = petData.findPetByStatus(status); 59 | 60 | if (petByStatus == null) { 61 | notifier.notify(new RuntimeException("Pets not found")); 62 | return new ResponseContext().status(Response.Status.NOT_FOUND).entity("Pets not found"); 63 | } 64 | 65 | notifier.notify(new RuntimeException("Pets not found")); 66 | return new ResponseContext() 67 | .contentType(Util.getMediaType(request)) 68 | .entity(petByStatus); 69 | } 70 | 71 | public ResponseContext getPetById(final RequestContext request, final Long petId) { 72 | if (petId == null) { 73 | notifier.notify(new RuntimeException("No petId provided")); 74 | return new ResponseContext() 75 | .status(Response.Status.BAD_REQUEST) 76 | .entity("No petId provided. Try again?"); 77 | } 78 | 79 | final Pet pet = petData.getPetById(petId); 80 | 81 | if (pet != null) { 82 | return new ResponseContext() 83 | .contentType(Util.getMediaType(request)) 84 | .entity(pet); 85 | } 86 | 87 | notifier.notify(new RuntimeException("Pets not found")); 88 | return new ResponseContext().status(Response.Status.NOT_FOUND).entity("Pet not found"); 89 | } 90 | 91 | public ResponseContext updatePetWithForm(final RequestContext request, final Long petId, final String name, final String status) { 92 | if (petId == null) { 93 | notifier.notify(new RuntimeException("No petId provided")); 94 | return new ResponseContext() 95 | .status(Response.Status.BAD_REQUEST) 96 | .entity("No Pet provided. Try again?"); 97 | } 98 | 99 | if (name == null) { 100 | notifier.notify(new RuntimeException("No name provided")); 101 | return new ResponseContext() 102 | .status(Response.Status.BAD_REQUEST) 103 | .entity("No Name provided. Try again?"); 104 | } 105 | 106 | final MediaType outputType = Util.getMediaType(request); 107 | final Pet existingPet = petData.getPetById(petId); 108 | 109 | if (existingPet == null) { 110 | notifier.notify(new RuntimeException("No pet provided")); 111 | return new ResponseContext().status(Response.Status.NOT_FOUND).entity("Pet not found"); 112 | } 113 | 114 | petData.deletePetById(existingPet.getId()); 115 | existingPet.setName(name); 116 | existingPet.setStatus(status); 117 | petData.addPet(existingPet); 118 | 119 | return new ResponseContext() 120 | .contentType(outputType) 121 | .entity(existingPet); 122 | } 123 | 124 | public ResponseContext deletePet(final RequestContext request, final String apiKey, final Long petId) { 125 | if (petId == null) { 126 | notifier.notify(new RuntimeException("No petId provided")); 127 | return new ResponseContext() 128 | .status(Response.Status.BAD_REQUEST) 129 | .entity("No petId provided. Try again?"); 130 | } 131 | 132 | petData.deletePetById(petId); 133 | 134 | final MediaType outputType = Util.getMediaType(request); 135 | 136 | final Pet pet = petData.getPetById(petId); 137 | 138 | if (null == pet) { 139 | return new ResponseContext() 140 | .contentType(outputType) 141 | .entity("Pet deleted"); 142 | } else { 143 | notifier.notify(new RuntimeException("Pet couldn't be deleted")); 144 | return new ResponseContext().status(Response.Status.NOT_MODIFIED).entity("Pet couldn't be deleted."); 145 | } 146 | 147 | } 148 | 149 | public ResponseContext uploadFile(final RequestContext request, final Long petId, final String apiKey, final File file) { 150 | if (petId == null) { 151 | notifier.notify(new RuntimeException("No petId provided")); 152 | return new ResponseContext() 153 | .status(Response.Status.BAD_REQUEST) 154 | .entity("No petId provided. Try again?"); 155 | } 156 | 157 | if (file == null) { 158 | notifier.notify(new RuntimeException("No file provided")); 159 | return new ResponseContext().status(Response.Status.BAD_REQUEST).entity("No file uploaded"); 160 | } 161 | 162 | final Pet existingPet = petData.getPetById(petId); 163 | if (existingPet == null) { 164 | notifier.notify(new RuntimeException("No pet provided")); 165 | return new ResponseContext().status(Response.Status.NOT_FOUND).entity("Pet not found"); 166 | } 167 | 168 | existingPet.getPhotoUrls().add(file.getAbsolutePath()); 169 | petData.deletePetById(existingPet.getId()); 170 | petData.addPet(existingPet); 171 | 172 | final Pet pet = petData.getPetById(petId); 173 | 174 | if (null != pet) { 175 | return new ResponseContext() 176 | .contentType(Util.getMediaType(request)) 177 | .entity(pet); 178 | } else { 179 | notifier.notify(new RuntimeException("Pet couldn't be updated")); 180 | return new ResponseContext().status(Response.Status.NOT_MODIFIED).entity("Pet couldn't be updated."); 181 | } 182 | } 183 | 184 | public ResponseContext addPet(final RequestContext request, final Pet pet) { 185 | if (pet == null) { 186 | notifier.notify(new RuntimeException("No pet provided")); 187 | return new ResponseContext() 188 | .status(Response.Status.BAD_REQUEST) 189 | .entity("No Pet provided. Try again?"); 190 | } 191 | 192 | petData.addPet(pet); 193 | 194 | return new ResponseContext() 195 | .contentType(Util.getMediaType(request)) 196 | .entity(pet); 197 | } 198 | 199 | public ResponseContext addPet(final RequestContext request, final Long id, final String name, final Category category, 200 | final List urls, final List tags, final String status) { 201 | final Pet pet = PetData.createPet(id, category, name, urls, tags, status); 202 | return addPet(request, pet); 203 | } 204 | 205 | public ResponseContext updatePet(final RequestContext request, final Pet pet) { 206 | if (pet == null) { 207 | notifier.notify(new RuntimeException("No pet provided")); 208 | return new ResponseContext() 209 | .status(Response.Status.BAD_REQUEST) 210 | .entity("No Pet provided. Try again?"); 211 | } 212 | 213 | final Pet existingPet = petData.getPetById(pet.getId()); 214 | if (existingPet == null) { 215 | notifier.notify(new RuntimeException("No pet provided")); 216 | return new ResponseContext().status(Response.Status.NOT_FOUND).entity("Pet not found"); 217 | } 218 | 219 | petData.deletePetById(existingPet.getId()); 220 | petData.addPet(pet); 221 | 222 | return new ResponseContext() 223 | .contentType(Util.getMediaType(request)) 224 | .entity(pet); 225 | } 226 | 227 | public ResponseContext updatePet(final RequestContext request, final Long id, final String name, final Category category, 228 | final List urls, final List tags, final String status) { 229 | final Pet pet = PetData.createPet(id, category, name, urls, tags, status); 230 | return updatePet(request, pet); 231 | } 232 | 233 | public ResponseContext findPetsByTags(final RequestContext request, final List tags) { 234 | if (tags == null || tags.size() == 0) { 235 | notifier.notify(new RuntimeException("No tags provided")); 236 | return new ResponseContext() 237 | .status(Response.Status.BAD_REQUEST) 238 | .entity("No tags provided. Try again?"); 239 | } 240 | 241 | final List petByTags = petData.findPetByTags(tags); 242 | 243 | return new ResponseContext() 244 | .contentType(Util.getMediaType(request)) 245 | .entity(petByTags); 246 | } 247 | 248 | } 249 | 250 | -------------------------------------------------------------------------------- /src/main/java/io/swagger/petstore/controller/UserController.java: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright 2018 SmartBear Software 3 | *

4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | *

8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | *

10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package io.swagger.petstore.controller; 18 | 19 | import io.swagger.oas.inflector.models.RequestContext; 20 | import io.swagger.oas.inflector.models.ResponseContext; 21 | import io.swagger.petstore.data.UserData; 22 | import io.swagger.petstore.model.User; 23 | import io.swagger.petstore.utils.Util; 24 | import org.apache.commons.lang3.RandomUtils; 25 | 26 | import javax.ws.rs.core.Response; 27 | import java.util.Date; 28 | 29 | @javax.annotation.Generated(value = "class io.swagger.codegen.languages.JavaInflectorServerCodegen", date = "2017-04-08T15:48:56.501Z") 30 | public class UserController { 31 | 32 | private static UserData userData = new UserData(); 33 | 34 | public ResponseContext createUser(final RequestContext request, final User user) { 35 | if (user == null) { 36 | return new ResponseContext() 37 | .status(Response.Status.BAD_REQUEST) 38 | .entity("No User provided. Try again?"); 39 | } 40 | 41 | userData.addUser(user); 42 | return new ResponseContext() 43 | .contentType(Util.getMediaType(request)) 44 | .entity(user); 45 | } 46 | 47 | public ResponseContext createUser(final RequestContext request, final Long id, final String username, 48 | final String firstName, final String lastName, final String email, 49 | final String password, final String phone, final Integer userStatus) { 50 | final User user = UserData.createUser(id, username, firstName, lastName, email, phone, userStatus); 51 | return createUser(request, user); 52 | } 53 | 54 | public ResponseContext getUserByName(final RequestContext request, final String username) { 55 | if (username == null) { 56 | return new ResponseContext() 57 | .status(Response.Status.BAD_REQUEST) 58 | .entity("No username provided. Try again?"); 59 | } 60 | 61 | final User user = userData.findUserByName(username); 62 | if (user == null) { 63 | return new ResponseContext().status(Response.Status.NOT_FOUND).entity("User not found"); 64 | } 65 | 66 | return new ResponseContext() 67 | .contentType(Util.getMediaType(request)) 68 | .entity(user); 69 | } 70 | 71 | public ResponseContext createUsersWithArrayInput(final RequestContext request, final User[] users) { 72 | if (users == null || users.length == 0) { 73 | return new ResponseContext() 74 | .status(Response.Status.BAD_REQUEST) 75 | .entity("No User provided. Try again?"); 76 | } 77 | 78 | for (final User user : users) { 79 | userData.addUser(user); 80 | } 81 | 82 | return new ResponseContext() 83 | .contentType(Util.getMediaType(request)) 84 | .entity(users); 85 | } 86 | 87 | public ResponseContext createUsersWithListInput(final RequestContext request, final User[] users) { 88 | if (users == null || users.length == 0) { 89 | return new ResponseContext() 90 | .status(Response.Status.BAD_REQUEST) 91 | .entity("No User provided. Try again?"); 92 | } 93 | 94 | for (final User user : users) { 95 | userData.addUser(user); 96 | } 97 | 98 | return new ResponseContext() 99 | .contentType(Util.getMediaType(request)) 100 | .entity(users); 101 | } 102 | 103 | public ResponseContext loginUser(final RequestContext request, final String username, final String password) { 104 | Date date = new Date(System.currentTimeMillis() + 3600000); 105 | return new ResponseContext() 106 | .contentType(Util.getMediaType(request)) 107 | .header("X-Rate-Limit", String.valueOf(5000)) 108 | .header("X-Expires-After", date.toString()) 109 | .entity("Logged in user session: " + RandomUtils.nextLong()); 110 | } 111 | 112 | public ResponseContext logoutUser(final RequestContext request) { 113 | return new ResponseContext() 114 | .contentType(Util.getMediaType(request)) 115 | .entity("User logged out"); 116 | 117 | } 118 | 119 | public ResponseContext deleteUser(final RequestContext request, final String username) { 120 | if (username == null) { 121 | return new ResponseContext() 122 | .status(Response.Status.BAD_REQUEST) 123 | .entity("No username provided. Try again?"); 124 | } 125 | 126 | userData.deleteUser(username); 127 | 128 | final User user = userData.findUserByName(username); 129 | 130 | if (null == user) { 131 | return new ResponseContext() 132 | .contentType(Util.getMediaType(request)) 133 | .entity(user); 134 | } else { 135 | return new ResponseContext().status(Response.Status.NOT_MODIFIED).entity("User couldn't be deleted."); 136 | } 137 | } 138 | 139 | public ResponseContext updateUser(final RequestContext request, final String username, final User user) { 140 | if (username == null) { 141 | return new ResponseContext() 142 | .status(Response.Status.BAD_REQUEST) 143 | .entity("No Username provided. Try again?"); 144 | } 145 | 146 | if (user == null) { 147 | return new ResponseContext() 148 | .status(Response.Status.BAD_REQUEST) 149 | .entity("No User provided. Try again?"); 150 | } 151 | 152 | final User existingUser = userData.findUserByName(username); 153 | 154 | if (existingUser == null) { 155 | return new ResponseContext().status(Response.Status.NOT_FOUND).entity("User not found"); 156 | } 157 | 158 | userData.deleteUser(existingUser.getUsername()); 159 | userData.addUser(user); 160 | 161 | return new ResponseContext() 162 | .contentType(Util.getMediaType(request)) 163 | .entity(user); 164 | } 165 | 166 | public ResponseContext updateUser(final RequestContext request, final String updatedUser, final Long id, final String username, 167 | final String firstName, final String lastName, final String email, 168 | final String password, final String phone, final Integer userStatus) { 169 | final User user = UserData.createUser(id, username, firstName, lastName, email, phone, userStatus); 170 | return updateUser(request, updatedUser, user); 171 | } 172 | } 173 | 174 | -------------------------------------------------------------------------------- /src/main/java/io/swagger/petstore/data/OrderData.java: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright 2018 SmartBear Software 3 | *

4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | *

8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | *

10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package io.swagger.petstore.data; 18 | 19 | import io.swagger.petstore.model.Order; 20 | 21 | import java.util.*; 22 | 23 | public class OrderData { 24 | private static List orders = new ArrayList<>(); 25 | 26 | static { 27 | orders.add(createOrder(1, 1, 100, new Date(), "placed", true)); 28 | orders.add(createOrder(2, 1, 50, new Date(), "approved", true)); 29 | orders.add(createOrder(3, 1, 50, new Date(), "delivered", true)); 30 | } 31 | 32 | public Order getOrderById(final long orderId) { 33 | for (final Order order : orders) { 34 | if (order.getId() == orderId) { 35 | return order; 36 | } 37 | } 38 | return null; 39 | } 40 | 41 | public Map getCountByStatus() { 42 | 43 | final Map countByStatus = new HashMap<>(); 44 | 45 | for (final Order order : orders) { 46 | final String status = order.getStatus(); 47 | if (countByStatus.containsKey(status)) { 48 | countByStatus.put(status, countByStatus.get(status) + order.getQuantity()); 49 | } else { 50 | countByStatus.put(status, order.getQuantity()); 51 | } 52 | } 53 | 54 | return countByStatus; 55 | } 56 | 57 | public void addOrder(final Order order) { 58 | if (orders.size() > 0) { 59 | orders.removeIf(orderN -> orderN.getId() == order.getId()); 60 | } 61 | orders.add(order); 62 | } 63 | 64 | public void deleteOrderById(final Long orderId) { 65 | orders.removeIf(order -> order.getId() == orderId); 66 | } 67 | 68 | public static Order createOrder(final long id, final long petId, final int quantity, final Date shipDate, 69 | final String status, final boolean complete) { 70 | final Order order = new Order(); 71 | order.setId(id); 72 | order.setPetId(petId); 73 | order.setComplete(complete); 74 | order.setQuantity(quantity); 75 | order.setShipDate(shipDate); 76 | order.setStatus(status); 77 | return order; 78 | } 79 | } 80 | -------------------------------------------------------------------------------- /src/main/java/io/swagger/petstore/data/PetData.java: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright 2018 SmartBear Software 3 | *

4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | *

8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | *

10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package io.swagger.petstore.data; 18 | 19 | import io.swagger.petstore.model.Category; 20 | import io.swagger.petstore.model.Pet; 21 | import io.swagger.petstore.model.Tag; 22 | 23 | import java.util.ArrayList; 24 | import java.util.Arrays; 25 | import java.util.List; 26 | 27 | public class PetData { 28 | private static List pets = new ArrayList<>(); 29 | private static List categories = new ArrayList<>(); 30 | 31 | static { 32 | categories.add(createCategory(1, "Dogs")); 33 | categories.add(createCategory(2, "Cats")); 34 | categories.add(createCategory(3, "Rabbits")); 35 | categories.add(createCategory(4, "Lions")); 36 | 37 | pets.add(createPet(1, categories.get(1), "Cat 1", new String[]{ 38 | "url1", "url2"}, new String[]{"tag1", "tag2"}, "available")); 39 | pets.add(createPet(2, categories.get(1), "Cat 2", new String[]{ 40 | "url1", "url2"}, new String[]{"tag2", "tag3"}, "available")); 41 | pets.add(createPet(3, categories.get(1), "Cat 3", new String[]{ 42 | "url1", "url2"}, new String[]{"tag3", "tag4"}, "pending")); 43 | 44 | pets.add(createPet(4, categories.get(0), "Dog 1", new String[]{ 45 | "url1", "url2"}, new String[]{"tag1", "tag2"}, "available")); 46 | pets.add(createPet(5, categories.get(0), "Dog 2", new String[]{ 47 | "url1", "url2"}, new String[]{"tag2", "tag3"}, "sold")); 48 | pets.add(createPet(6, categories.get(0), "Dog 3", new String[]{ 49 | "url1", "url2"}, new String[]{"tag3", "tag4"}, "pending")); 50 | 51 | pets.add(createPet(7, categories.get(3), "Lion 1", new String[]{ 52 | "url1", "url2"}, new String[]{"tag1", "tag2"}, "available")); 53 | pets.add(createPet(8, categories.get(3), "Lion 2", new String[]{ 54 | "url1", "url2"}, new String[]{"tag2", "tag3"}, "available")); 55 | pets.add(createPet(9, categories.get(3), "Lion 3", new String[]{ 56 | "url1", "url2"}, new String[]{"tag3", "tag4"}, "available")); 57 | 58 | pets.add(createPet(10, categories.get(2), "Rabbit 1", new String[]{ 59 | "url1", "url2"}, new String[]{"tag3", "tag4"}, "available")); 60 | } 61 | 62 | public Pet getPetById(final long petId) { 63 | for (final Pet pet : pets) { 64 | if (pet.getId() == petId) { 65 | return pet; 66 | } 67 | } 68 | return null; 69 | } 70 | 71 | public List findPetByStatus(final String status) { 72 | final String[] statues = status.split(","); 73 | final List result = new ArrayList<>(); 74 | for (final Pet pet : pets) { 75 | for (final String s : statues) { 76 | if (s.equals(pet.getStatus())) { 77 | result.add(pet); 78 | } 79 | } 80 | } 81 | return result; 82 | } 83 | 84 | public List findPetByTags(final List tags) { 85 | final List result = new ArrayList<>(); 86 | for (final Pet pet : pets) { 87 | if (null != pet.getTags()) { 88 | for (final Tag tag : pet.getTags()) { 89 | for (final String tagListString : tags) { 90 | if (tagListString.equals(tag.getName())) { 91 | result.add(pet); 92 | } 93 | } 94 | } 95 | } 96 | } 97 | return result; 98 | } 99 | 100 | public void addPet(final Pet pet) { 101 | if (pets.size() > 0) { 102 | for (int i = pets.size() - 1; i >= 0; i--) { 103 | if (pets.get(i).getId() == pet.getId()) { 104 | pets.remove(i); 105 | } 106 | } 107 | } 108 | pets.add(pet); 109 | } 110 | 111 | public void deletePetById(final Long petId) { 112 | pets.removeIf(pet -> pet.getId() == petId); 113 | } 114 | 115 | public static Pet createPet(final Long id, final Category cat, final String name, 116 | final List urls, final List tags, final String status) { 117 | final Pet pet = new Pet(); 118 | pet.setId(id); 119 | pet.setCategory(cat); 120 | pet.setName(name); 121 | pet.setPhotoUrls(urls); 122 | pet.setTags(tags); 123 | pet.setStatus(status); 124 | return pet; 125 | } 126 | 127 | private static Pet createPet(final long id, final Category cat, final String name, final String[] urls, 128 | final String[] tags, final String status) { 129 | final Pet pet = new Pet(); 130 | pet.setId(id); 131 | pet.setCategory(cat); 132 | pet.setName(name); 133 | if (null != urls) { 134 | final List urlObjs = new ArrayList<>(Arrays.asList(urls)); 135 | pet.setPhotoUrls(urlObjs); 136 | } 137 | final List tagObjs = new ArrayList<>(); 138 | int i = 0; 139 | if (null != tags) { 140 | for (final String tagString : tags) { 141 | i = i + 1; 142 | final Tag tag = new Tag(); 143 | tag.setId(i); 144 | tag.setName(tagString); 145 | tagObjs.add(tag); 146 | } 147 | } 148 | pet.setTags(tagObjs); 149 | pet.setStatus(status); 150 | return pet; 151 | } 152 | 153 | private static Category createCategory(final long id, final String name) { 154 | final Category category = new Category(); 155 | category.setId(id); 156 | category.setName(name); 157 | return category; 158 | } 159 | } -------------------------------------------------------------------------------- /src/main/java/io/swagger/petstore/data/UserData.java: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright 2018 SmartBear Software 3 | *

4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | *

8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | *

10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package io.swagger.petstore.data; 18 | 19 | import io.swagger.petstore.model.User; 20 | 21 | import java.util.ArrayList; 22 | import java.util.List; 23 | 24 | public class UserData { 25 | private static List users = new ArrayList<>(); 26 | 27 | static { 28 | users.add(createUser(1, "user1", "first name 1", "last name 1", 29 | "email1@test.com", "123-456-7890", 1)); 30 | users.add(createUser(2, "user2", "first name 2", "last name 2", 31 | "email2@test.com", "123-456-7890", 2)); 32 | users.add(createUser(3, "user3", "first name 3", "last name 3", 33 | "email3@test.com", "123-456-7890", 3)); 34 | users.add(createUser(4, "user4", "first name 4", "last name 4", 35 | "email4@test.com", "123-456-7890", 1)); 36 | users.add(createUser(5, "user5", "first name 5", "last name 5", 37 | "email5@test.com", "123-456-7890", 2)); 38 | users.add(createUser(6, "user6", "first name 6", "last name 6", 39 | "email6@test.com", "123-456-7890", 3)); 40 | users.add(createUser(7, "user7", "first name 7", "last name 7", 41 | "email7@test.com", "123-456-7890", 1)); 42 | users.add(createUser(8, "user8", "first name 8", "last name 8", 43 | "email8@test.com", "123-456-7890", 2)); 44 | users.add(createUser(9, "user9", "first name 9", "last name 9", 45 | "email9@test.com", "123-456-7890", 3)); 46 | users.add(createUser(10, "user10", "first name 10", "last name 10", 47 | "email10@test.com", "123-456-7890", 1)); 48 | users.add(createUser(11, "user?10", "first name ?10", "last name ?10", 49 | "email101@test.com", "123-456-7890", 1)); 50 | 51 | } 52 | 53 | public User findUserByName(final String username) { 54 | for (final User user : users) { 55 | if (user.getUsername().equals(username)) { 56 | return user; 57 | } 58 | } 59 | return null; 60 | } 61 | 62 | public void addUser(final User user) { 63 | if (users.size() > 0) { 64 | for (int i = users.size() - 1; i >= 0; i--) { 65 | if (users.get(i).getUsername().equals(user.getUsername())) { 66 | users.remove(i); 67 | } 68 | } 69 | } 70 | users.add(user); 71 | } 72 | 73 | public void deleteUser(final String username) { 74 | users.removeIf(user -> user.getUsername().equals(username)); 75 | } 76 | 77 | public static User createUser(final long id, final String username, final String firstName, 78 | final String lastName, final String email, final String phone, final int userStatus) { 79 | final User user = new User(); 80 | user.setId(id); 81 | user.setUsername(username); 82 | user.setFirstName(firstName); 83 | user.setLastName(lastName); 84 | user.setEmail(email); 85 | user.setPassword("XXXXXXXXXXX"); 86 | user.setPhone(phone); 87 | user.setUserStatus(userStatus); 88 | return user; 89 | } 90 | } -------------------------------------------------------------------------------- /src/main/java/io/swagger/petstore/exception/ApiException.java: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright 2018 SmartBear Software 3 | *

4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | *

8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | *

10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package io.swagger.petstore.exception; 18 | 19 | public class ApiException extends Exception { 20 | private int code; 21 | 22 | public ApiException(final int code, final String msg) { 23 | super(msg); 24 | this.code = code; 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /src/main/java/io/swagger/petstore/exception/NotFoundException.java: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright 2018 SmartBear Software 3 | *

4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | *

8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | *

10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package io.swagger.petstore.exception; 18 | 19 | public class NotFoundException extends ApiException { 20 | private int code; 21 | 22 | public NotFoundException(int code, String msg) { 23 | super(code, msg); 24 | this.code = code; 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /src/main/java/io/swagger/petstore/model/ApiResponse.java: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright 2016 SmartBear Software 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package io.swagger.petstore.model; 18 | 19 | import javax.xml.bind.annotation.XmlTransient; 20 | 21 | @javax.xml.bind.annotation.XmlRootElement 22 | public class ApiResponse { 23 | public static final int ERROR = 1; 24 | public static final int WARNING = 2; 25 | public static final int INFO = 3; 26 | public static final int OK = 4; 27 | public static final int TOO_BUSY = 5; 28 | 29 | int code; 30 | String type; 31 | String message; 32 | 33 | public ApiResponse(){} 34 | 35 | public ApiResponse(int code, String message){ 36 | this.code = code; 37 | switch(code){ 38 | case ERROR: 39 | setType("error"); 40 | break; 41 | case WARNING: 42 | setType("warning"); 43 | break; 44 | case INFO: 45 | setType("info"); 46 | break; 47 | case OK: 48 | setType("ok"); 49 | break; 50 | case TOO_BUSY: 51 | setType("too busy"); 52 | break; 53 | default: 54 | setType("unknown"); 55 | break; 56 | } 57 | this.message = message; 58 | } 59 | 60 | @XmlTransient 61 | public int getCode() { 62 | return code; 63 | } 64 | 65 | public void setCode(int code) { 66 | this.code = code; 67 | } 68 | 69 | public String getType() { 70 | return type; 71 | } 72 | 73 | public void setType(String type) { 74 | this.type = type; 75 | } 76 | 77 | public String getMessage() { 78 | return message; 79 | } 80 | 81 | public void setMessage(String message) { 82 | this.message = message; 83 | } 84 | } 85 | -------------------------------------------------------------------------------- /src/main/java/io/swagger/petstore/model/Category.java: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright 2018 SmartBear Software 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package io.swagger.petstore.model; 18 | 19 | import javax.xml.bind.annotation.XmlElement; 20 | import javax.xml.bind.annotation.XmlRootElement; 21 | 22 | @XmlRootElement(name = "Category") 23 | public class Category { 24 | private long id; 25 | private String name; 26 | 27 | @XmlElement(name = "id") 28 | public long getId() { 29 | return id; 30 | } 31 | 32 | public void setId(long id) { 33 | this.id = id; 34 | } 35 | 36 | @XmlElement(name = "name") 37 | public String getName() { 38 | return name; 39 | } 40 | 41 | public void setName(String name) { 42 | this.name = name; 43 | } 44 | } -------------------------------------------------------------------------------- /src/main/java/io/swagger/petstore/model/Order.java: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright 2018 SmartBear Software 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package io.swagger.petstore.model; 18 | 19 | import io.swagger.v3.oas.annotations.media.Schema; 20 | 21 | import javax.xml.bind.annotation.XmlElement; 22 | import javax.xml.bind.annotation.XmlRootElement; 23 | import java.util.Date; 24 | 25 | @XmlRootElement(name = "Order") 26 | public class Order { 27 | private long id; 28 | private long petId; 29 | private int quantity; 30 | private Date shipDate; 31 | private String status; 32 | private boolean complete; 33 | 34 | @XmlElement(name = "id") 35 | public long getId() { 36 | return id; 37 | } 38 | 39 | public void setId(long id) { 40 | this.id = id; 41 | } 42 | 43 | public boolean isComplete() { 44 | return complete; 45 | } 46 | 47 | public void setComplete(boolean complete) { 48 | this.complete = complete; 49 | } 50 | 51 | 52 | @XmlElement(name = "petId") 53 | public long getPetId() { 54 | return petId; 55 | } 56 | 57 | public void setPetId(long petId) { 58 | this.petId = petId; 59 | } 60 | 61 | @XmlElement(name = "quantity") 62 | public int getQuantity() { 63 | return quantity; 64 | } 65 | 66 | public void setQuantity(int quantity) { 67 | this.quantity = quantity; 68 | } 69 | 70 | @XmlElement(name = "status") 71 | @Schema(description = "Order Status", allowableValues = "placed, approved, delivered") 72 | public String getStatus() { 73 | return status; 74 | } 75 | 76 | public void setStatus(String status) { 77 | this.status = status; 78 | } 79 | 80 | @XmlElement(name = "shipDate") 81 | public Date getShipDate() { 82 | return shipDate; 83 | } 84 | 85 | public void setShipDate(Date shipDate) { 86 | this.shipDate = shipDate; 87 | } 88 | } -------------------------------------------------------------------------------- /src/main/java/io/swagger/petstore/model/Pet.java: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright 2018 SmartBear Software 3 | *

4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | *

8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | *

10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package io.swagger.petstore.model; 18 | 19 | import io.swagger.v3.oas.annotations.media.Schema; 20 | 21 | import javax.xml.bind.annotation.XmlElement; 22 | import javax.xml.bind.annotation.XmlElementWrapper; 23 | import javax.xml.bind.annotation.XmlRootElement; 24 | import java.util.ArrayList; 25 | import java.util.List; 26 | 27 | @XmlRootElement(name = "Pet") 28 | public class Pet { 29 | private Long id; 30 | private Category category; 31 | private String name; 32 | private List photoUrls = new ArrayList<>(); 33 | private List tags = new ArrayList<>(); 34 | private String status; 35 | 36 | @XmlElement(name = "id") 37 | public long getId() { 38 | return id; 39 | } 40 | 41 | public void setId(final Long id) { 42 | this.id = id; 43 | } 44 | 45 | @XmlElement(name = "category") 46 | public Category getCategory() { 47 | return category; 48 | } 49 | 50 | public void setCategory(final Category category) { 51 | this.category = category; 52 | } 53 | 54 | @XmlElement(name = "name") 55 | public String getName() { 56 | return name; 57 | } 58 | 59 | public void setName(final String name) { 60 | this.name = name; 61 | } 62 | 63 | @XmlElementWrapper(name = "photoUrls") 64 | @XmlElement(name = "photoUrl") 65 | public List getPhotoUrls() { 66 | return photoUrls; 67 | } 68 | 69 | public void setPhotoUrls(final List photoUrls) { 70 | this.photoUrls = photoUrls; 71 | } 72 | 73 | @XmlElementWrapper(name = "tags") 74 | @XmlElement(name = "tag") 75 | public List getTags() { 76 | return tags; 77 | } 78 | 79 | public void setTags(final List tags) { 80 | this.tags = tags; 81 | } 82 | 83 | @XmlElement(name = "status") 84 | @Schema(description = "pet status in the store", allowableValues = "available,pending,sold") 85 | public String getStatus() { 86 | return status; 87 | } 88 | 89 | public void setStatus(final String status) { 90 | this.status = status; 91 | } 92 | } 93 | -------------------------------------------------------------------------------- /src/main/java/io/swagger/petstore/model/Tag.java: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright 2018 SmartBear Software 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package io.swagger.petstore.model; 18 | 19 | import javax.xml.bind.annotation.XmlElement; 20 | import javax.xml.bind.annotation.XmlRootElement; 21 | 22 | @XmlRootElement(name = "Tag") 23 | public class Tag { 24 | private long id; 25 | private String name; 26 | 27 | @XmlElement(name = "id") 28 | public long getId() { 29 | return id; 30 | } 31 | 32 | public void setId(long id) { 33 | this.id = id; 34 | } 35 | 36 | @XmlElement(name = "name") 37 | public String getName() { 38 | return name; 39 | } 40 | 41 | public void setName(String name) { 42 | this.name = name; 43 | } 44 | } -------------------------------------------------------------------------------- /src/main/java/io/swagger/petstore/model/User.java: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright 2018 SmartBear Software 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package io.swagger.petstore.model; 18 | 19 | import io.swagger.v3.oas.annotations.media.Schema; 20 | 21 | import javax.xml.bind.annotation.XmlElement; 22 | import javax.xml.bind.annotation.XmlRootElement; 23 | 24 | @XmlRootElement(name = "User") 25 | public class User { 26 | private long id; 27 | private String username; 28 | private String firstName; 29 | private String lastName; 30 | private String email; 31 | private String password; 32 | private String phone; 33 | private int userStatus; 34 | 35 | @XmlElement(name = "id") 36 | public long getId() { 37 | return id; 38 | } 39 | 40 | public void setId(long id) { 41 | this.id = id; 42 | } 43 | 44 | @XmlElement(name = "firstName") 45 | public String getFirstName() { 46 | return firstName; 47 | } 48 | 49 | public void setFirstName(String firstName) { 50 | this.firstName = firstName; 51 | } 52 | 53 | @XmlElement(name = "username") 54 | public String getUsername() { 55 | return username; 56 | } 57 | 58 | public void setUsername(String username) { 59 | this.username = username; 60 | } 61 | 62 | @XmlElement(name = "lastName") 63 | public String getLastName() { 64 | return lastName; 65 | } 66 | 67 | public void setLastName(String lastName) { 68 | this.lastName = lastName; 69 | } 70 | 71 | @XmlElement(name = "email") 72 | public String getEmail() { 73 | return email; 74 | } 75 | 76 | public void setEmail(String email) { 77 | this.email = email; 78 | } 79 | 80 | @XmlElement(name = "password") 81 | public String getPassword() { 82 | return password; 83 | } 84 | 85 | public void setPassword(String password) { 86 | this.password = password; 87 | } 88 | 89 | @XmlElement(name = "phone") 90 | public String getPhone() { 91 | return phone; 92 | } 93 | 94 | public void setPhone(String phone) { 95 | this.phone = phone; 96 | } 97 | 98 | @XmlElement(name = "userStatus") 99 | @Schema(description = "User Status", allowableValues = "1-registered,2-active,3-closed") 100 | public int getUserStatus() { 101 | return userStatus; 102 | } 103 | 104 | public void setUserStatus(int userStatus) { 105 | this.userStatus = userStatus; 106 | } 107 | } -------------------------------------------------------------------------------- /src/main/java/io/swagger/petstore/notification/BugSnagNotifier.java: -------------------------------------------------------------------------------- 1 | package io.swagger.petstore.notification; 2 | 3 | import com.bugsnag.Bugsnag; 4 | 5 | 6 | public class BugSnagNotifier implements Notifier { 7 | 8 | protected Bugsnag bugsnag; 9 | 10 | public void init() { 11 | String bugsnagApiKey = System.getenv("BUGSNAG_API_KEY"); 12 | if (bugsnagApiKey != null) { 13 | bugsnag = new Bugsnag(bugsnagApiKey); 14 | bugsnag.startSession(); 15 | } else { 16 | System.err.println("BUGSNAG_API_KEY environment variable is not set"); 17 | } 18 | } 19 | 20 | @Override 21 | public void notify(Throwable e) { 22 | if (bugsnag != null) { 23 | bugsnag.notify(e); 24 | } 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /src/main/java/io/swagger/petstore/notification/Notifier.java: -------------------------------------------------------------------------------- 1 | package io.swagger.petstore.notification; 2 | 3 | public interface Notifier { 4 | 5 | void notify(Throwable e); 6 | } 7 | -------------------------------------------------------------------------------- /src/main/java/io/swagger/petstore/notification/NullNotifier.java: -------------------------------------------------------------------------------- 1 | package io.swagger.petstore.notification; 2 | 3 | public class NullNotifier implements Notifier { 4 | 5 | @Override 6 | public void notify(Throwable e) { 7 | // 8 | } 9 | } 10 | -------------------------------------------------------------------------------- /src/main/java/io/swagger/petstore/utils/HandleAuthUrlProcessor.java: -------------------------------------------------------------------------------- 1 | package io.swagger.petstore.utils; 2 | 3 | import io.swagger.oas.inflector.config.OpenAPIProcessor; 4 | import io.swagger.v3.oas.models.OpenAPI; 5 | import org.apache.commons.lang3.StringUtils; 6 | 7 | public class HandleAuthUrlProcessor implements OpenAPIProcessor { 8 | 9 | @Override 10 | public void process(OpenAPI openAPI) { 11 | String oauthHost = System.getenv("SWAGGER_OAUTH_HOST"); 12 | if (StringUtils.isBlank(oauthHost)) { 13 | return; 14 | } 15 | openAPI.getComponents().getSecuritySchemes().get("petstore_auth").getFlows().getImplicit().setAuthorizationUrl(oauthHost + "/oauth/authorize"); 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /src/main/java/io/swagger/petstore/utils/Util.java: -------------------------------------------------------------------------------- 1 | package io.swagger.petstore.utils; 2 | 3 | import io.swagger.oas.inflector.models.RequestContext; 4 | 5 | import javax.ws.rs.core.MediaType; 6 | import java.util.List; 7 | 8 | public class Util { 9 | 10 | private static final String APPLICATION = "application"; 11 | private static final String YAML = "yaml"; 12 | 13 | public static MediaType getMediaType(final RequestContext request) { 14 | MediaType outputType = MediaType.APPLICATION_JSON_TYPE; 15 | 16 | final List accept = request.getHeaders().get("Accept"); 17 | String responseMediaType = ""; 18 | if (accept != null && accept.get(0) != null) { 19 | responseMediaType = accept.get(0); 20 | } 21 | if (MediaType.APPLICATION_XML.equals(responseMediaType)) { 22 | return MediaType.APPLICATION_XML_TYPE; 23 | } 24 | 25 | boolean isJsonOK = false; 26 | boolean isYamlOK = false; 27 | 28 | final MediaType yamlMediaType = new MediaType(APPLICATION, YAML); 29 | 30 | for (final MediaType mediaType : request.getAcceptableMediaTypes()) { 31 | if (mediaType.equals(MediaType.APPLICATION_JSON_TYPE)) { 32 | isJsonOK = true; 33 | } else if (mediaType.equals(yamlMediaType)) { 34 | isYamlOK = true; 35 | } 36 | } 37 | 38 | if (isYamlOK && !isJsonOK) { 39 | outputType = yamlMediaType; 40 | } 41 | 42 | return outputType; 43 | } 44 | } 45 | -------------------------------------------------------------------------------- /src/main/resources/openapi.yaml: -------------------------------------------------------------------------------- 1 | openapi: 3.0.4 2 | info: 3 | title: Swagger Petstore - OpenAPI 3.0 4 | description: |- 5 | This is a sample Pet Store Server based on the OpenAPI 3.0 specification. You can find out more about 6 | Swagger at [https://swagger.io](https://swagger.io). In the third iteration of the pet store, we've switched to the design first approach! 7 | You can now help us improve the API whether it's by making changes to the definition itself or to the code. 8 | That way, with time, we can improve the API in general, and expose some of the new features in OAS3. 9 | 10 | Some useful links: 11 | - [The Pet Store repository](https://github.com/swagger-api/swagger-petstore) 12 | - [The source API definition for the Pet Store](https://github.com/swagger-api/swagger-petstore/blob/master/src/main/resources/openapi.yaml) 13 | termsOfService: https://swagger.io/terms/ 14 | contact: 15 | email: apiteam@swagger.io 16 | license: 17 | name: Apache 2.0 18 | url: https://www.apache.org/licenses/LICENSE-2.0.html 19 | version: 1.0.27-SNAPSHOT 20 | externalDocs: 21 | description: Find out more about Swagger 22 | url: https://swagger.io 23 | servers: 24 | - url: https://petstore3.swagger.io/api/v3 25 | tags: 26 | - name: pet 27 | description: Everything about your Pets 28 | externalDocs: 29 | description: Find out more 30 | url: https://swagger.io 31 | - name: store 32 | description: Access to Petstore orders 33 | externalDocs: 34 | description: Find out more about our store 35 | url: https://swagger.io 36 | - name: user 37 | description: Operations about user 38 | paths: 39 | /pet: 40 | put: 41 | tags: 42 | - pet 43 | summary: Update an existing pet. 44 | description: Update an existing pet by Id. 45 | operationId: updatePet 46 | requestBody: 47 | description: Update an existent pet in the store 48 | content: 49 | application/json: 50 | schema: 51 | $ref: '#/components/schemas/Pet' 52 | application/xml: 53 | schema: 54 | $ref: '#/components/schemas/Pet' 55 | application/x-www-form-urlencoded: 56 | schema: 57 | $ref: '#/components/schemas/Pet' 58 | required: true 59 | responses: 60 | '200': 61 | description: Successful operation 62 | content: 63 | application/json: 64 | schema: 65 | $ref: '#/components/schemas/Pet' 66 | application/xml: 67 | schema: 68 | $ref: '#/components/schemas/Pet' 69 | '400': 70 | description: Invalid ID supplied 71 | '404': 72 | description: Pet not found 73 | '422': 74 | description: Validation exception 75 | default: 76 | description: Unexpected error 77 | security: 78 | - petstore_auth: 79 | - write:pets 80 | - read:pets 81 | post: 82 | tags: 83 | - pet 84 | summary: Add a new pet to the store. 85 | description: Add a new pet to the store. 86 | operationId: addPet 87 | requestBody: 88 | description: Create a new pet in the store 89 | content: 90 | application/json: 91 | schema: 92 | $ref: '#/components/schemas/Pet' 93 | application/xml: 94 | schema: 95 | $ref: '#/components/schemas/Pet' 96 | application/x-www-form-urlencoded: 97 | schema: 98 | $ref: '#/components/schemas/Pet' 99 | required: true 100 | responses: 101 | '200': 102 | description: Successful operation 103 | content: 104 | application/json: 105 | schema: 106 | $ref: '#/components/schemas/Pet' 107 | application/xml: 108 | schema: 109 | $ref: '#/components/schemas/Pet' 110 | '400': 111 | description: Invalid input 112 | '422': 113 | description: Validation exception 114 | default: 115 | description: Unexpected error 116 | security: 117 | - petstore_auth: 118 | - write:pets 119 | - read:pets 120 | /pet/findByStatus: 121 | get: 122 | tags: 123 | - pet 124 | summary: Finds Pets by status. 125 | description: Multiple status values can be provided with comma separated strings. 126 | operationId: findPetsByStatus 127 | parameters: 128 | - name: status 129 | in: query 130 | description: Status values that need to be considered for filter 131 | required: false 132 | explode: true 133 | schema: 134 | type: string 135 | default: available 136 | enum: 137 | - available 138 | - pending 139 | - sold 140 | responses: 141 | '200': 142 | description: successful operation 143 | content: 144 | application/json: 145 | schema: 146 | type: array 147 | items: 148 | $ref: '#/components/schemas/Pet' 149 | application/xml: 150 | schema: 151 | type: array 152 | items: 153 | $ref: '#/components/schemas/Pet' 154 | '400': 155 | description: Invalid status value 156 | default: 157 | description: Unexpected error 158 | security: 159 | - petstore_auth: 160 | - write:pets 161 | - read:pets 162 | /pet/findByTags: 163 | get: 164 | tags: 165 | - pet 166 | summary: Finds Pets by tags. 167 | description: Multiple tags can be provided with comma separated strings. Use tag1, tag2, tag3 for testing. 168 | operationId: findPetsByTags 169 | parameters: 170 | - name: tags 171 | in: query 172 | description: Tags to filter by 173 | required: false 174 | explode: true 175 | schema: 176 | type: array 177 | items: 178 | type: string 179 | responses: 180 | '200': 181 | description: successful operation 182 | content: 183 | application/json: 184 | schema: 185 | type: array 186 | items: 187 | $ref: '#/components/schemas/Pet' 188 | application/xml: 189 | schema: 190 | type: array 191 | items: 192 | $ref: '#/components/schemas/Pet' 193 | '400': 194 | description: Invalid tag value 195 | default: 196 | description: Unexpected error 197 | security: 198 | - petstore_auth: 199 | - write:pets 200 | - read:pets 201 | /pet/{petId}: 202 | get: 203 | tags: 204 | - pet 205 | summary: Find pet by ID. 206 | description: Returns a single pet. 207 | operationId: getPetById 208 | parameters: 209 | - name: petId 210 | in: path 211 | description: ID of pet to return 212 | required: true 213 | schema: 214 | type: integer 215 | format: int64 216 | responses: 217 | '200': 218 | description: successful operation 219 | content: 220 | application/json: 221 | schema: 222 | $ref: '#/components/schemas/Pet' 223 | application/xml: 224 | schema: 225 | $ref: '#/components/schemas/Pet' 226 | '400': 227 | description: Invalid ID supplied 228 | '404': 229 | description: Pet not found 230 | default: 231 | description: Unexpected error 232 | security: 233 | - api_key: [] 234 | - petstore_auth: 235 | - write:pets 236 | - read:pets 237 | post: 238 | tags: 239 | - pet 240 | summary: Updates a pet in the store with form data. 241 | description: Updates a pet resource based on the form data. 242 | operationId: updatePetWithForm 243 | parameters: 244 | - name: petId 245 | in: path 246 | description: ID of pet that needs to be updated 247 | required: true 248 | schema: 249 | type: integer 250 | format: int64 251 | - name: name 252 | in: query 253 | description: Name of pet that needs to be updated 254 | schema: 255 | type: string 256 | - name: status 257 | in: query 258 | description: Status of pet that needs to be updated 259 | schema: 260 | type: string 261 | responses: 262 | '200': 263 | description: successful operation 264 | content: 265 | application/json: 266 | schema: 267 | $ref: '#/components/schemas/Pet' 268 | application/xml: 269 | schema: 270 | $ref: '#/components/schemas/Pet' 271 | '400': 272 | description: Invalid input 273 | default: 274 | description: Unexpected error 275 | security: 276 | - petstore_auth: 277 | - write:pets 278 | - read:pets 279 | delete: 280 | tags: 281 | - pet 282 | summary: Deletes a pet. 283 | description: Delete a pet. 284 | operationId: deletePet 285 | parameters: 286 | - name: api_key 287 | in: header 288 | description: '' 289 | required: false 290 | schema: 291 | type: string 292 | - name: petId 293 | in: path 294 | description: Pet id to delete 295 | required: true 296 | schema: 297 | type: integer 298 | format: int64 299 | responses: 300 | '200': 301 | description: Pet deleted 302 | '400': 303 | description: Invalid pet value 304 | default: 305 | description: Unexpected error 306 | security: 307 | - petstore_auth: 308 | - write:pets 309 | - read:pets 310 | /pet/{petId}/uploadImage: 311 | post: 312 | tags: 313 | - pet 314 | summary: Uploads an image. 315 | description: Upload image of the pet. 316 | operationId: uploadFile 317 | parameters: 318 | - name: petId 319 | in: path 320 | description: ID of pet to update 321 | required: true 322 | schema: 323 | type: integer 324 | format: int64 325 | - name: additionalMetadata 326 | in: query 327 | description: Additional Metadata 328 | required: false 329 | schema: 330 | type: string 331 | requestBody: 332 | content: 333 | application/octet-stream: 334 | schema: 335 | type: string 336 | format: binary 337 | responses: 338 | '200': 339 | description: successful operation 340 | content: 341 | application/json: 342 | schema: 343 | $ref: '#/components/schemas/ApiResponse' 344 | '400': 345 | description: No file uploaded 346 | '404': 347 | description: Pet not found 348 | default: 349 | description: Unexpected error 350 | security: 351 | - petstore_auth: 352 | - write:pets 353 | - read:pets 354 | /store/inventory: 355 | get: 356 | tags: 357 | - store 358 | summary: Returns pet inventories by status. 359 | description: Returns a map of status codes to quantities. 360 | operationId: getInventory 361 | x-swagger-router-controller: OrderController 362 | responses: 363 | '200': 364 | description: successful operation 365 | content: 366 | application/json: 367 | schema: 368 | type: object 369 | additionalProperties: 370 | type: integer 371 | format: int32 372 | default: 373 | description: Unexpected error 374 | security: 375 | - api_key: [] 376 | /store/order: 377 | post: 378 | tags: 379 | - store 380 | summary: Place an order for a pet. 381 | description: Place a new order in the store. 382 | x-swagger-router-controller: OrderController 383 | operationId: placeOrder 384 | requestBody: 385 | content: 386 | application/json: 387 | schema: 388 | $ref: '#/components/schemas/Order' 389 | application/xml: 390 | schema: 391 | $ref: '#/components/schemas/Order' 392 | application/x-www-form-urlencoded: 393 | schema: 394 | $ref: '#/components/schemas/Order' 395 | responses: 396 | '200': 397 | description: successful operation 398 | content: 399 | application/json: 400 | schema: 401 | $ref: '#/components/schemas/Order' 402 | '400': 403 | description: Invalid input 404 | '422': 405 | description: Validation exception 406 | default: 407 | description: Unexpected error 408 | /store/order/{orderId}: 409 | get: 410 | tags: 411 | - store 412 | summary: Find purchase order by ID. 413 | x-swagger-router-controller: OrderController 414 | description: For valid response try integer IDs with value <= 5 or > 10. Other values will generate exceptions. 415 | operationId: getOrderById 416 | parameters: 417 | - name: orderId 418 | in: path 419 | description: ID of order that needs to be fetched 420 | required: true 421 | schema: 422 | type: integer 423 | format: int64 424 | responses: 425 | '200': 426 | description: successful operation 427 | content: 428 | application/json: 429 | schema: 430 | $ref: '#/components/schemas/Order' 431 | application/xml: 432 | schema: 433 | $ref: '#/components/schemas/Order' 434 | '400': 435 | description: Invalid ID supplied 436 | '404': 437 | description: Order not found 438 | default: 439 | description: Unexpected error 440 | delete: 441 | tags: 442 | - store 443 | summary: Delete purchase order by identifier. 444 | description: For valid response try integer IDs with value < 1000. Anything above 1000 or non-integers will generate API errors. 445 | x-swagger-router-controller: OrderController 446 | operationId: deleteOrder 447 | parameters: 448 | - name: orderId 449 | in: path 450 | description: ID of the order that needs to be deleted 451 | required: true 452 | schema: 453 | type: integer 454 | format: int64 455 | responses: 456 | '200': 457 | description: order deleted 458 | '400': 459 | description: Invalid ID supplied 460 | '404': 461 | description: Order not found 462 | default: 463 | description: Unexpected error 464 | /user: 465 | post: 466 | tags: 467 | - user 468 | summary: Create user. 469 | description: This can only be done by the logged in user. 470 | x-swagger-router-controller: UserController 471 | operationId: createUser 472 | requestBody: 473 | description: Created user object 474 | content: 475 | application/json: 476 | schema: 477 | $ref: '#/components/schemas/User' 478 | application/xml: 479 | schema: 480 | $ref: '#/components/schemas/User' 481 | application/x-www-form-urlencoded: 482 | schema: 483 | $ref: '#/components/schemas/User' 484 | responses: 485 | '200': 486 | description: successful operation 487 | content: 488 | application/json: 489 | schema: 490 | $ref: '#/components/schemas/User' 491 | application/xml: 492 | schema: 493 | $ref: '#/components/schemas/User' 494 | default: 495 | description: Unexpected error 496 | /user/createWithList: 497 | post: 498 | tags: 499 | - user 500 | summary: Creates list of users with given input array. 501 | description: Creates list of users with given input array. 502 | x-swagger-router-controller: UserController 503 | operationId: createUsersWithListInput 504 | requestBody: 505 | content: 506 | application/json: 507 | schema: 508 | type: array 509 | items: 510 | $ref: '#/components/schemas/User' 511 | responses: 512 | '200': 513 | description: Successful operation 514 | content: 515 | application/json: 516 | schema: 517 | $ref: '#/components/schemas/User' 518 | application/xml: 519 | schema: 520 | $ref: '#/components/schemas/User' 521 | default: 522 | description: Unexpected error 523 | /user/login: 524 | get: 525 | tags: 526 | - user 527 | summary: Logs user into the system. 528 | description: Log into the system. 529 | operationId: loginUser 530 | parameters: 531 | - name: username 532 | in: query 533 | description: The user name for login 534 | required: false 535 | schema: 536 | type: string 537 | - name: password 538 | in: query 539 | description: The password for login in clear text 540 | required: false 541 | schema: 542 | type: string 543 | responses: 544 | '200': 545 | description: successful operation 546 | headers: 547 | X-Rate-Limit: 548 | description: calls per hour allowed by the user 549 | schema: 550 | type: integer 551 | format: int32 552 | X-Expires-After: 553 | description: date in UTC when token expires 554 | schema: 555 | type: string 556 | format: date-time 557 | content: 558 | application/xml: 559 | schema: 560 | type: string 561 | application/json: 562 | schema: 563 | type: string 564 | '400': 565 | description: Invalid username/password supplied 566 | default: 567 | description: Unexpected error 568 | /user/logout: 569 | get: 570 | tags: 571 | - user 572 | summary: Logs out current logged in user session. 573 | description: Log user out of the system. 574 | operationId: logoutUser 575 | parameters: [] 576 | responses: 577 | '200': 578 | description: successful operation 579 | default: 580 | description: Unexpected error 581 | /user/{username}: 582 | get: 583 | tags: 584 | - user 585 | summary: Get user by user name. 586 | description: Get user detail based on username. 587 | operationId: getUserByName 588 | parameters: 589 | - name: username 590 | in: path 591 | description: The name that needs to be fetched. Use user1 for testing 592 | required: true 593 | schema: 594 | type: string 595 | responses: 596 | '200': 597 | description: successful operation 598 | content: 599 | application/json: 600 | schema: 601 | $ref: '#/components/schemas/User' 602 | application/xml: 603 | schema: 604 | $ref: '#/components/schemas/User' 605 | '400': 606 | description: Invalid username supplied 607 | '404': 608 | description: User not found 609 | default: 610 | description: Unexpected error 611 | put: 612 | tags: 613 | - user 614 | summary: Update user resource. 615 | description: This can only be done by the logged in user. 616 | x-swagger-router-controller: UserController 617 | operationId: updateUser 618 | parameters: 619 | - name: username 620 | in: path 621 | description: name that need to be deleted 622 | required: true 623 | schema: 624 | type: string 625 | requestBody: 626 | description: Update an existent user in the store 627 | content: 628 | application/json: 629 | schema: 630 | $ref: '#/components/schemas/User' 631 | application/xml: 632 | schema: 633 | $ref: '#/components/schemas/User' 634 | application/x-www-form-urlencoded: 635 | schema: 636 | $ref: '#/components/schemas/User' 637 | responses: 638 | '200': 639 | description: successful operation 640 | '400': 641 | description: bad request 642 | '404': 643 | description: user not found 644 | default: 645 | description: Unexpected error 646 | delete: 647 | tags: 648 | - user 649 | summary: Delete user resource. 650 | description: This can only be done by the logged in user. 651 | operationId: deleteUser 652 | parameters: 653 | - name: username 654 | in: path 655 | description: The name that needs to be deleted 656 | required: true 657 | schema: 658 | type: string 659 | responses: 660 | '200': 661 | description: User deleted 662 | '400': 663 | description: Invalid username supplied 664 | '404': 665 | description: User not found 666 | default: 667 | description: Unexpected error 668 | components: 669 | schemas: 670 | Order: 671 | x-swagger-router-model: io.swagger.petstore.model.Order 672 | type: object 673 | properties: 674 | id: 675 | type: integer 676 | format: int64 677 | example: 10 678 | petId: 679 | type: integer 680 | format: int64 681 | example: 198772 682 | quantity: 683 | type: integer 684 | format: int32 685 | example: 7 686 | shipDate: 687 | type: string 688 | format: date-time 689 | status: 690 | type: string 691 | description: Order Status 692 | example: approved 693 | enum: 694 | - placed 695 | - approved 696 | - delivered 697 | complete: 698 | type: boolean 699 | xml: 700 | name: order 701 | Category: 702 | x-swagger-router-model: io.swagger.petstore.model.Category 703 | type: object 704 | properties: 705 | id: 706 | type: integer 707 | format: int64 708 | example: 1 709 | name: 710 | type: string 711 | example: Dogs 712 | xml: 713 | name: category 714 | User: 715 | x-swagger-router-model: io.swagger.petstore.model.User 716 | type: object 717 | properties: 718 | id: 719 | type: integer 720 | format: int64 721 | example: 10 722 | username: 723 | type: string 724 | example: theUser 725 | firstName: 726 | type: string 727 | example: John 728 | lastName: 729 | type: string 730 | example: James 731 | email: 732 | type: string 733 | example: john@email.com 734 | password: 735 | type: string 736 | example: '12345' 737 | phone: 738 | type: string 739 | example: '12345' 740 | userStatus: 741 | type: integer 742 | description: User Status 743 | format: int32 744 | example: 1 745 | xml: 746 | name: user 747 | Tag: 748 | x-swagger-router-model: io.swagger.petstore.model.Tag 749 | type: object 750 | properties: 751 | id: 752 | type: integer 753 | format: int64 754 | name: 755 | type: string 756 | xml: 757 | name: tag 758 | Pet: 759 | x-swagger-router-model: io.swagger.petstore.model.Pet 760 | required: 761 | - name 762 | - photoUrls 763 | type: object 764 | properties: 765 | id: 766 | type: integer 767 | format: int64 768 | example: 10 769 | name: 770 | type: string 771 | example: doggie 772 | category: 773 | $ref: '#/components/schemas/Category' 774 | photoUrls: 775 | type: array 776 | xml: 777 | wrapped: true 778 | items: 779 | type: string 780 | xml: 781 | name: photoUrl 782 | tags: 783 | type: array 784 | xml: 785 | wrapped: true 786 | items: 787 | $ref: '#/components/schemas/Tag' 788 | status: 789 | type: string 790 | description: pet status in the store 791 | enum: 792 | - available 793 | - pending 794 | - sold 795 | xml: 796 | name: pet 797 | ApiResponse: 798 | type: object 799 | properties: 800 | code: 801 | type: integer 802 | format: int32 803 | type: 804 | type: string 805 | message: 806 | type: string 807 | xml: 808 | name: '##default' 809 | requestBodies: 810 | Pet: 811 | description: Pet object that needs to be added to the store 812 | content: 813 | application/json: 814 | schema: 815 | $ref: '#/components/schemas/Pet' 816 | application/xml: 817 | schema: 818 | $ref: '#/components/schemas/Pet' 819 | UserArray: 820 | description: List of user object 821 | content: 822 | application/json: 823 | schema: 824 | type: array 825 | items: 826 | $ref: '#/components/schemas/User' 827 | securitySchemes: 828 | petstore_auth: 829 | type: oauth2 830 | flows: 831 | implicit: 832 | authorizationUrl: https://petstore3.swagger.io/oauth/authorize 833 | scopes: 834 | "write:pets": modify pets in your account 835 | "read:pets": read your pets 836 | api_key: 837 | type: apiKey 838 | name: api_key 839 | in: header -------------------------------------------------------------------------------- /src/main/webapp/WEB-INF/web.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | swagger-inflector 5 | org.glassfish.jersey.servlet.ServletContainer 6 | 7 | javax.ws.rs.Application 8 | io.swagger.oas.inflector.OpenAPIInflector 9 | 10 | 11 | jersey.config.server.provider.packages 12 | 13 | com.fasterxml.jackson.jaxrs.yaml.JacksonYAMLProvider 14 | 15 | 16 | 1 17 | 18 | 19 | swagger-inflector 20 | /api/* 21 | 22 | 23 | CORSFilter 24 | io.swagger.oas.inflector.utils.CORSFilter 25 | 26 | 27 | CORSFilter 28 | /* 29 | 30 | -------------------------------------------------------------------------------- /src/main/webapp/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | Swagger UI 7 | 8 | 9 | 10 | 11 | 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 | 94 | 95 | 96 | -------------------------------------------------------------------------------- /src/test/java/ip/swagger/petstore/PetStoreTest.java: -------------------------------------------------------------------------------- 1 | package ip.swagger.petstore; 2 | 3 | public class PetStoreTest { 4 | 5 | } 6 | --------------------------------------------------------------------------------