├── .ci.settings.xml ├── .github └── workflows │ └── ci.yml ├── .gitignore ├── .pre-commit-config.yaml ├── CI ├── RELEASE.md └── release.sh ├── LICENSE ├── README.md ├── pom.xml └── src ├── main └── webapp │ ├── WEB-INF │ └── web.xml │ ├── changelogs │ ├── auth-5.2-6.0.json │ ├── core-5.1-5.2.json │ ├── core-5.2-6.0.json │ ├── discovery-5.2-6.0.json │ ├── search-5.2-6.0.json │ ├── workflow-5.1-5.2.json │ └── workflow-5.2-6.0.json │ ├── css │ └── alfresco.css │ ├── definitions │ ├── alfresco-auth.yaml │ ├── alfresco-core.yaml │ ├── alfresco-discovery.yaml │ ├── alfresco-model.yaml │ ├── alfresco-search-sql.yaml │ ├── alfresco-search.yaml │ ├── alfresco-workflow.yaml │ └── index.jsp │ ├── images │ └── logo.svg │ ├── index.html │ └── version.jsp └── test └── java └── org └── alfresco ├── api └── YamlToJson.java └── test └── APIExplorerIntegrationTest.java /.ci.settings.xml: -------------------------------------------------------------------------------- 1 | 2 | 4 | 5 | 6 | alfresco-public 7 | ${env.MAVEN_USERNAME} 8 | ${env.MAVEN_PASSWORD} 9 | 10 | 11 | alfresco-public-snapshots 12 | ${env.MAVEN_USERNAME} 13 | ${env.MAVEN_PASSWORD} 14 | 15 | 16 | 17 | -------------------------------------------------------------------------------- /.github/workflows/ci.yml: -------------------------------------------------------------------------------- 1 | name: Alfresco REST API Explorer CI 2 | 3 | on: 4 | pull_request: 5 | branches: 6 | - master 7 | - fix/** 8 | - feature/** 9 | push: 10 | branches: 11 | - master 12 | - fix/** 13 | - feature/** 14 | workflow_dispatch: 15 | schedule: 16 | - cron: '0 5 * * 3' 17 | 18 | env: 19 | MAVEN_USERNAME: ${{ secrets.NEXUS_USERNAME }} 20 | MAVEN_PASSWORD: ${{ secrets.NEXUS_PASSWORD }} 21 | GIT_USERNAME: ${{ secrets.BOT_GITHUB_USERNAME }} 22 | GIT_PASSWORD: ${{ secrets.BOT_GITHUB_TOKEN }} 23 | RELEASE_VERSION: "25.1.0" 24 | DEVELOPMENT_VERSION: "25.2.0-A.1-SNAPSHOT" 25 | MAVEN_CLI_OPTS: "-B -q -e -fae -V -DinstallAtEnd=true -U" 26 | GITHUB_ACTIONS_DEPLOY_TIMEOUT: 30 27 | 28 | jobs: 29 | pre_commit: 30 | runs-on: ubuntu-latest 31 | steps: 32 | - uses: Alfresco/alfresco-build-tools/.github/actions/pre-commit@v8.16.0 33 | 34 | build: 35 | name: "Build" 36 | runs-on: ubuntu-latest 37 | needs: [pre_commit] 38 | steps: 39 | - uses: actions/checkout@v4 40 | - uses: Alfresco/alfresco-build-tools/.github/actions/get-build-info@v8.16.0 41 | - uses: Alfresco/alfresco-build-tools/.github/actions/setup-java-build@v8.16.0 42 | - name: "Build" 43 | run: mvn install -DskipTests=true -Dmaven.javadoc.skip=true -B -V 44 | - name: "Verify" 45 | timeout-minutes: ${{ fromJSON(env.GITHUB_ACTIONS_DEPLOY_TIMEOUT) }} 46 | run: mvn ${MAVEN_CLI_OPTS} verify -Dlogging.root.level=off -Dspring.main.banner-mode=off 47 | 48 | tests: 49 | name: "Integration tests" 50 | runs-on: ubuntu-latest 51 | needs: [build] 52 | if: "!contains(github.event.head_commit.message, '[skip tests]')" 53 | steps: 54 | - uses: actions/checkout@v4 55 | - uses: Alfresco/alfresco-build-tools/.github/actions/get-build-info@v8.16.0 56 | - uses: Alfresco/alfresco-build-tools/.github/actions/setup-java-build@v8.16.0 57 | - name: "Run tests" 58 | run: mvn verify 59 | 60 | publish: 61 | name: "Publish artifacts" 62 | runs-on: ubuntu-latest 63 | needs: [tests] 64 | if: "!(failure() || cancelled()) && github.event_name != 'pull_request'" 65 | steps: 66 | - uses: actions/checkout@v4 67 | - uses: Alfresco/alfresco-build-tools/.github/actions/get-build-info@v8.16.0 68 | - uses: Alfresco/alfresco-build-tools/.github/actions/setup-java-build@v8.16.0 69 | - name: "Publish" 70 | timeout-minutes: ${{ fromJSON(env.GITHUB_ACTIONS_DEPLOY_TIMEOUT) }} 71 | run: mvn ${MAVEN_CLI_OPTS} deploy -DskipTests 72 | 73 | release: 74 | name: "Release" 75 | runs-on: ubuntu-latest 76 | needs: [publish] 77 | if: > 78 | !(failure() || cancelled()) && contains(github.event.head_commit.message, '[release]') && 79 | github.ref_name == 'master' && github.event_name != 'pull_request' 80 | steps: 81 | - uses: actions/checkout@v4 82 | with: 83 | persist-credentials: false 84 | - uses: Alfresco/alfresco-build-tools/.github/actions/get-build-info@v8.16.0 85 | - uses: Alfresco/alfresco-build-tools/.github/actions/setup-java-build@v8.16.0 86 | - uses: Alfresco/alfresco-build-tools/.github/actions/configure-git-author@v8.16.0 87 | with: 88 | username: ${{ secrets.BOT_GITHUB_USERNAME }} 89 | email: ${{ secrets.BOT_GITHUB_EMAIL }} 90 | global: true 91 | - name: "Release" 92 | run: bash CI/release.sh 93 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | /src/main/swagger 2 | 3 | #Maven 4 | target/ 5 | pom.xml.tag 6 | pom.xml.releaseBackup 7 | pom.xml.versionsBackup 8 | pom.xml.next 9 | release.properties 10 | dependency-reduced-pom.xml 11 | buildNumber.properties 12 | .mvn/timing.properties 13 | 14 | # Eclipse 15 | .settings 16 | .project 17 | .classpath 18 | 19 | # IntelliJ 20 | .idea 21 | *.iml -------------------------------------------------------------------------------- /.pre-commit-config.yaml: -------------------------------------------------------------------------------- 1 | default_language_version: 2 | # force all unspecified python hooks to run python3 3 | python: python3 4 | 5 | repos: 6 | - repo: https://github.com/pre-commit/pre-commit-hooks 7 | rev: v3.4.0 8 | hooks: 9 | - id: check-yaml 10 | args: [--allow-multiple-documents] 11 | - id: check-json 12 | 13 | - repo: https://github.com/APIDevTools/swagger-cli 14 | rev: v4.0.4 15 | hooks: 16 | - id: swagger-validation 17 | name: Check Alfresco OpenAPI 2.0 definition 18 | files: (alfresco).*\.(json|ya?ml)$ 19 | args: ["validate"] 20 | -------------------------------------------------------------------------------- /CI/RELEASE.md: -------------------------------------------------------------------------------- 1 | # RELEASE 2 | 3 | The Release Process of REST API Explorer is now managed through GitHub Actions. 4 | 5 | Only someone with Admin access to the project can create a new Release. 6 | 7 | The documentation is on [this internal Confluence page](https://alfresco.atlassian.net/wiki/spaces/APO/pages/109904136/REST+API+Explorer). 8 | 9 | The GitHub CI builds, however, are visible to everyone at the following address: https://github.com/Alfresco/rest-api-explorer/actions. 10 | -------------------------------------------------------------------------------- /CI/release.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | # EXAMPLE: "7.0.0-A1" 4 | echo "RELEASE VERSION: ${RELEASE_VERSION}" 5 | 6 | # EXAMPLE: "7.0.0-SNAPSHOT" 7 | echo "DEVELOPMENT VERSION: ${DEVELOPMENT_VERSION}" 8 | 9 | if [ -z "${RELEASE_VERSION}" ] || [ -z "${DEVELOPMENT_VERSION}" ]; then 10 | echo "Please provide a Release and Development version in the format - (7.0.0-EA or 7.0.0-SNAPSHOT)" 11 | exit 1 12 | fi 13 | 14 | # Use full history for release 15 | git checkout -B master 16 | 17 | mvn release:clean release:prepare release:perform \ 18 | -B \ 19 | -DskipTests \ 20 | -Dbuild-number="${BUILD_NUMBER}" \ 21 | -DreleaseVersion="${RELEASE_VERSION}" \ 22 | -DignoreSnapshots \ 23 | -DdevelopmentVersion="${DEVELOPMENT_VERSION}" \ 24 | -DscmCommentPrefix="[maven-release-plugin][skip ci] " \ 25 | -Dusername="${GIT_USERNAME}" \ 26 | -Dpassword="${GIT_PASSWORD}" 27 | -------------------------------------------------------------------------------- /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 | # Welcome to the Alfresco REST API Explorer 2 | 3 | [![Build Status](https://github.com/Alfresco/rest-api-explorer/actions/workflows/ci.yml/badge.svg?branch=master)](https://github.com/Alfresco/rest-api-explorer/actions/workflows/ci.yml) 4 | [![pre-commit](https://img.shields.io/badge/pre--commit-enabled-brightgreen?logo=pre-commit&logoColor=white)](https://github.com/pre-commit/pre-commit) 5 | ![GitHub](https://img.shields.io/github/license/Alfresco/rest-api-explorer?color=brightgreen) 6 | 7 | The API Explorer allows you to browse and experiment with the REST APIs available in the Alfresco platform. 8 | 9 | #### Building and deploying the war 10 | - `mvn install` 11 | 12 | You now have a `target/api-explorer.war`, drop this into your Application server that is running alfresco.war 13 | 14 | #### For development only 15 | You can run the project as a packaged web application using an embedded Jetty server. 16 | This is useful for changing documentation and endpoint descriptions but it means that the "Try it Out!" button will not work. 17 | 18 | - `mvn jetty:run-war` 19 | 20 | Now the application is running at [http://localhost:8085/api-explorer](http://localhost:8085/api-explorer/) 21 | 22 | ### License 23 | Copyright (C) 2016-2021 Alfresco Software Limited 24 | 25 | This file is part of an unsupported extension to Alfresco. 26 | 27 | Alfresco Software Limited licenses this file 28 | to you under the Apache License, Version 2.0 (the 29 | "License"); you may not use this file except in compliance 30 | with the License. You may obtain a copy of the License at 31 | 32 | http://www.apache.org/licenses/LICENSE-2.0 33 | 34 | Unless required by applicable law or agreed to in writing, 35 | software distributed under the License is distributed on an 36 | "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 37 | KIND, either express or implied. See the License for the 38 | specific language governing permissions and limitations 39 | under the License. 40 | -------------------------------------------------------------------------------- /pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 4.0.0 3 | org.alfresco 4 | api-explorer 5 | 25.2.0-A.1-SNAPSHOT 6 | war 7 | Alfresco REST API Explorer 8 | Produces the API Explorer for all API definitions 9 | 10 | 11 | 4.1.3 12 | 17 13 | 17 14 | 17 15 | 17 16 | 17 17 | UTF-8 18 | UTF-8 19 | 20 | 8085 21 | 22 | 23 | 24 | scm:git:https://github.com/Alfresco/rest-api-explorer.git 25 | scm:git:https://github.com/Alfresco/rest-api-explorer.git 26 | https://github.com/Alfresco/rest-api-explorer 27 | HEAD 28 | 29 | 30 | 31 | 32 | Apache License 2.0 33 | http://www.apache.org/licenses/LICENSE-2.0 34 | 35 | 36 | 37 | 38 | 39 | org.webjars 40 | swagger-ui 41 | ${swagger-ui.version} 42 | provided 43 | 44 | 45 | junit 46 | junit 47 | 4.13.1 48 | test 49 | 50 | 51 | org.apache.httpcomponents 52 | httpclient 53 | 4.5.13 54 | test 55 | 56 | 57 | commons-io 58 | commons-io 59 | 2.14.0 60 | test 61 | 62 | 63 | io.swagger 64 | swagger-parser 65 | 1.0.52 66 | test 67 | 68 | 69 | org.slf4j 70 | slf4j-api 71 | 1.7.30 72 | test 73 | 74 | 75 | org.slf4j 76 | slf4j-simple 77 | 1.7.30 78 | test 79 | 80 | 81 | 82 | api-explorer 83 | 84 | 85 | org.apache.maven.plugins 86 | maven-release-plugin 87 | 2.5.3 88 | 89 | @{project.version} 90 | 91 | 92 | 93 | 94 | org.apache.maven.plugins 95 | maven-surefire-plugin 96 | 2.22.2 97 | 98 | true 99 | 100 | 101 | 102 | org.apache.maven.plugins 103 | maven-dependency-plugin 104 | 3.1.2 105 | 106 | 107 | unpack-dependencies 108 | validate 109 | 110 | unpack-dependencies 111 | 112 | 113 | META-INF/resources/webjars/swagger-ui/${swagger-ui.version}/**/*.* 114 | **/index.html,**/*.gz,**/*.map 115 | ${basedir}/src/main/swagger 116 | 117 | 118 | 119 | 120 | 121 | org.codehaus.mojo 122 | exec-maven-plugin 123 | 3.0.0 124 | 125 | 126 | generate-json 127 | prepare-package 128 | 129 | java 130 | 131 | 132 | 133 | 134 | org.alfresco.api.YamlToJson 135 | 136 | ${basedir} 137 | 138 | test 139 | 140 | 141 | 142 | maven-clean-plugin 143 | 3.1.0 144 | 145 | 146 | 147 | ${basedir}/src/main/swagger 148 | 149 | 150 | 151 | 152 | 153 | org.apache.maven.plugins 154 | maven-war-plugin 155 | 3.3.1 156 | 157 | 158 | 159 | 160 | src/main/swagger/META-INF/resources/webjars/swagger-ui/${swagger-ui.version} 161 | 162 | 163 | 164 | 165 | 166 | ${project.version} 167 | ${maven.build.timestamp} 168 | 169 | 170 | 171 | Libraries 172 | 173 | ${swagger-ui.version} 174 | 175 | 176 | 177 | 178 | true 179 | true 180 | 181 | 182 | 183 | 184 | 185 | 186 | org.eclipse.jetty 187 | jetty-maven-plugin 188 | 11.0.0 189 | 190 | 0 191 | 192 | /api-explorer 193 | 194 | 195 | 196 | 8085 197 | 198 | 199 | 200 | 201 | start-ephemeral-jetty 202 | pre-integration-test 203 | 204 | start-war 205 | 206 | 207 | 208 | 209 | 210 | 211 | org.apache.maven.plugins 212 | maven-failsafe-plugin 213 | 2.22.2 214 | 215 | 216 | integration-tests 217 | 218 | integration-test 219 | verify 220 | 221 | 222 | 223 | **/*IntegrationTest.java 224 | 225 | 226 | 227 | 228 | 229 | 230 | 231 | 232 | 233 | alfresco-public-snapshots 234 | https://artifacts.alfresco.com/nexus/content/repositories/snapshots 235 | 236 | 237 | alfresco-public 238 | https://artifacts.alfresco.com/nexus/content/repositories/releases 239 | 240 | 241 | 242 | -------------------------------------------------------------------------------- /src/main/webapp/WEB-INF/web.xml: -------------------------------------------------------------------------------- 1 | 6 | 7 | versionjsp 8 | /version.jsp 9 | 10 | 11 | versionjsp 12 | /version/* 13 | 14 | -------------------------------------------------------------------------------- /src/main/webapp/changelogs/auth-5.2-6.0.json: -------------------------------------------------------------------------------- 1 | {"errors":[],"warnings":[],"infos":[],"unmatchDiffs":[]} 2 | -------------------------------------------------------------------------------- /src/main/webapp/changelogs/core-5.2-6.0.json: -------------------------------------------------------------------------------- 1 | {"errors":[],"warnings":[],"infos":[],"unmatchDiffs":[]} 2 | -------------------------------------------------------------------------------- /src/main/webapp/changelogs/discovery-5.2-6.0.json: -------------------------------------------------------------------------------- 1 | {"errors":[],"warnings":[],"infos":[],"unmatchDiffs":[]} 2 | -------------------------------------------------------------------------------- /src/main/webapp/changelogs/search-5.2-6.0.json: -------------------------------------------------------------------------------- 1 | {"errors":[],"warnings":[],"infos":[],"unmatchDiffs":[]} 2 | -------------------------------------------------------------------------------- /src/main/webapp/changelogs/workflow-5.2-6.0.json: -------------------------------------------------------------------------------- 1 | {"errors":[],"warnings":[],"infos":[],"unmatchDiffs":[]} 2 | -------------------------------------------------------------------------------- /src/main/webapp/css/alfresco.css: -------------------------------------------------------------------------------- 1 | body { 2 | padding: 10px; 3 | } 4 | 5 | #select-wrapper { 6 | padding-top: 3px; 7 | } 8 | 9 | .swagger-section #header #alflogo { 10 | background: transparent; 11 | } 12 | 13 | .swagger-section #header { 14 | padding: 14px; 15 | border-bottom: 1px solid #e6e6ec; 16 | background: linear-gradient(to bottom,white 0%,#f9fafa 47%,#f4f4f4 100%); 17 | height: auto; 18 | } 19 | 20 | .swagger-section #api_selector .input { 21 | padding: 3px 10px 0 10px; 22 | margin: 0 0 0 0; 23 | } 24 | 25 | .swagger-section .swagger-ui-wrap p { 26 | padding: 0 0 3px 0; 27 | } 28 | 29 | .swagger-section #api_selector .input input { 30 | padding-top: 0; 31 | } 32 | 33 | -------------------------------------------------------------------------------- /src/main/webapp/definitions/alfresco-auth.yaml: -------------------------------------------------------------------------------- 1 | swagger: '2.0' 2 | info: 3 | description: | 4 | **Authentication API** 5 | 6 | Provides access to the authentication features of Alfresco Content Services. 7 | version: '1' 8 | title: Alfresco Content Services REST API 9 | basePath: /alfresco/api/-default-/public/authentication/versions/1 10 | securityDefinitions: 11 | basicAuth: 12 | type: basic 13 | description: HTTP Basic Authentication 14 | security: 15 | - basicAuth: [] 16 | consumes: 17 | - application/json 18 | produces: 19 | - application/json 20 | paths: 21 | '/tickets': 22 | post: 23 | x-alfresco-since: "5.2" 24 | tags: 25 | - authentication 26 | summary: Create ticket (login) 27 | description: | 28 | **Note:** this endpoint is available in Alfresco 5.2 and newer versions. 29 | 30 | Logs in and returns the new authentication ticket. 31 | 32 | The userId and password properties are mandatory in the request body. For example: 33 | ```JSON 34 | { 35 | "userId": "jbloggs", 36 | "password": "password" 37 | } 38 | ``` 39 | To use the ticket in future requests you should pass it in the request header. 40 | For example using Javascript: 41 | ```Javascript 42 | request.setRequestHeader ("Authorization", "Basic " + btoa(ticket)); 43 | ``` 44 | operationId: createTicket 45 | parameters: 46 | - in: body 47 | name: ticketBodyCreate 48 | description: The user credential. 49 | required: true 50 | schema: 51 | $ref: '#/definitions/TicketBody' 52 | consumes: 53 | - application/json 54 | produces: 55 | - application/json 56 | responses: 57 | '201': 58 | description: Successful response 59 | schema: 60 | $ref: '#/definitions/TicketEntry' 61 | '400': 62 | description: | 63 | **userId** or **password** is not provided 64 | '403': 65 | description: Login failed 66 | '501': 67 | description: SAML is enabled and enforced 68 | default: 69 | description: Unexpected error 70 | schema: 71 | $ref: '#/definitions/Error' 72 | '/tickets/-me-': 73 | get: 74 | x-alfresco-since: "5.2" 75 | tags: 76 | - authentication 77 | summary: Validate ticket 78 | description: | 79 | **Note:** this endpoint is available in Alfresco 5.2 and newer versions. 80 | 81 | Validates the specified ticket (derived from Authorization header) is still valid. 82 | 83 | For example, you can pass the Authorization request header using Javascript: 84 | ```Javascript 85 | request.setRequestHeader ("Authorization", "Basic " + btoa(ticket)); 86 | ``` 87 | operationId: validateTicket 88 | produces: 89 | - application/json 90 | responses: 91 | '200': 92 | description: Successful response 93 | schema: 94 | $ref: '#/definitions/ValidTicketEntry' 95 | '400': 96 | description: URL path does not include **-me-** or the ticket is not provided by the Authorization header 97 | '401': 98 | description: Authentication failed 99 | '404': 100 | description: The request is authorized correctly but the status of the user (of the supplied ticket) has 101 | changed (for example, the user is locked or the account is disabled) or the ticket has expired 102 | default: 103 | description: Unexpected error 104 | schema: 105 | $ref: '#/definitions/Error' 106 | delete: 107 | x-alfresco-since: "5.2" 108 | tags: 109 | - authentication 110 | summary: Delete ticket (logout) 111 | description: | 112 | **Note:** this endpoint is available in Alfresco 5.2 and newer versions. 113 | 114 | Deletes logged in ticket (logout). 115 | operationId: deleteTicket 116 | responses: 117 | '204': 118 | description: Successful response 119 | '400': 120 | description: URL path does not include **-me-** or the ticket is not provided by the Authorization header 121 | '404': 122 | description: Status of the user has changed (for example, the user is locked or the account is disabled) or the ticket has expired 123 | default: 124 | description: Unexpected error 125 | schema: 126 | $ref: '#/definitions/Error' 127 | definitions: 128 | Error: 129 | type: object 130 | required: 131 | - error 132 | properties: 133 | error: 134 | type: object 135 | required: 136 | - statusCode 137 | - briefSummary 138 | - stackTrace 139 | - descriptionURL 140 | properties: 141 | errorKey: 142 | type: string 143 | statusCode: 144 | type: integer 145 | format: int32 146 | briefSummary: 147 | type: string 148 | stackTrace: 149 | type: string 150 | descriptionURL: 151 | type: string 152 | logId: 153 | type: string 154 | TicketBody: 155 | type: object 156 | properties: 157 | userId: 158 | type: string 159 | password: 160 | type: string 161 | TicketEntry: 162 | type: object 163 | required: 164 | - entry 165 | properties: 166 | entry: 167 | $ref: '#/definitions/Ticket' 168 | Ticket: 169 | type: object 170 | properties: 171 | id: 172 | type: string 173 | userId: 174 | type: string 175 | ValidTicketEntry: 176 | type: object 177 | required: 178 | - entry 179 | properties: 180 | entry: 181 | $ref: '#/definitions/ValidTicket' 182 | ValidTicket: 183 | type: object 184 | properties: 185 | id: 186 | type: string -------------------------------------------------------------------------------- /src/main/webapp/definitions/alfresco-discovery.yaml: -------------------------------------------------------------------------------- 1 | swagger: '2.0' 2 | info: 3 | description: | 4 | **Discovery API** 5 | 6 | Provides access to information about Alfresco Content Services. 7 | version: '1' 8 | title: Alfresco Content Services REST API 9 | basePath: /alfresco/api 10 | securityDefinitions: 11 | basicAuth: 12 | type: basic 13 | description: HTTP Basic Authentication 14 | security: 15 | - basicAuth: [] 16 | produces: 17 | - application/json 18 | paths: 19 | '/discovery': 20 | get: 21 | x-alfresco-since: "5.2" 22 | tags: 23 | - discovery 24 | summary: Get repository information 25 | description: | 26 | **Note:** this endpoint is available in Alfresco 5.2 and newer versions. 27 | 28 | Retrieves the capabilities and detailed version information from the repository. 29 | operationId: getRepositoryInformation 30 | produces: 31 | - application/json 32 | responses: 33 | '200': 34 | description: Successful response 35 | schema: 36 | $ref: '#/definitions/DiscoveryEntry' 37 | '501': 38 | description: Discovery is disabled for the system 39 | default: 40 | description: Unexpected error 41 | schema: 42 | $ref: '#/definitions/Error' 43 | definitions: 44 | Error: 45 | type: object 46 | required: 47 | - error 48 | properties: 49 | error: 50 | type: object 51 | required: 52 | - statusCode 53 | - briefSummary 54 | - stackTrace 55 | - descriptionURL 56 | properties: 57 | errorKey: 58 | type: string 59 | statusCode: 60 | type: integer 61 | format: int32 62 | briefSummary: 63 | type: string 64 | stackTrace: 65 | type: string 66 | descriptionURL: 67 | type: string 68 | logId: 69 | type: string 70 | VersionInfo: 71 | type: object 72 | required: 73 | - major 74 | - minor 75 | - patch 76 | - hotfix 77 | - schema 78 | - label 79 | - display 80 | properties: 81 | major: 82 | type: string 83 | minor: 84 | type: string 85 | patch: 86 | type: string 87 | hotfix: 88 | type: string 89 | schema: 90 | type: integer 91 | label: 92 | type: string 93 | display: 94 | type: string 95 | StatusInfo: 96 | type: object 97 | required: 98 | - isReadOnly 99 | - isAuditEnabled 100 | - isQuickShareEnabled 101 | - isThumbnailGenerationEnabled 102 | - isDirectAccessUrlEnabled 103 | properties: 104 | isReadOnly: 105 | type: boolean 106 | default: false 107 | isAuditEnabled: 108 | type: boolean 109 | isQuickShareEnabled: 110 | type: boolean 111 | isThumbnailGenerationEnabled: 112 | type: boolean 113 | isDirectAccessUrlEnabled: 114 | type: boolean 115 | EntitlementsInfo: 116 | type: object 117 | properties: 118 | maxUsers: 119 | type: integer 120 | format: int64 121 | maxDocs: 122 | type: integer 123 | format: int64 124 | isClusterEnabled: 125 | type: boolean 126 | default: false 127 | isCryptodocEnabled: 128 | type: boolean 129 | default: false 130 | isCustomEmbeddedWorkflowEnabled: 131 | type: boolean 132 | default: false 133 | LicenseInfo: 134 | type: object 135 | required: 136 | - issuedAt 137 | - expiresAt 138 | - remainingDays 139 | - holder 140 | - mode 141 | properties: 142 | issuedAt: 143 | type: string 144 | format: date-time 145 | expiresAt: 146 | type: string 147 | format: date-time 148 | remainingDays: 149 | type: integer 150 | holder: 151 | type: string 152 | mode: 153 | type: string 154 | entitlements: 155 | $ref: '#/definitions/EntitlementsInfo' 156 | ModuleInfo: 157 | type: object 158 | properties: 159 | id: 160 | type: string 161 | title: 162 | type: string 163 | description: 164 | type: string 165 | version: 166 | type: string 167 | installDate: 168 | type: string 169 | format: date-time 170 | installState: 171 | type: string 172 | versionMin: 173 | type: string 174 | versionMax: 175 | type: string 176 | RepositoryInfo: 177 | type: object 178 | required: 179 | - id 180 | - edition 181 | - version 182 | - status 183 | properties: 184 | id: 185 | type: string 186 | edition: 187 | type: string 188 | version: 189 | $ref: '#/definitions/VersionInfo' 190 | status: 191 | $ref: '#/definitions/StatusInfo' 192 | license: 193 | $ref: '#/definitions/LicenseInfo' 194 | modules: 195 | type: array 196 | items: 197 | $ref: '#/definitions/ModuleInfo' 198 | RepositoryEntry: 199 | type: object 200 | required: 201 | - repository 202 | properties: 203 | repository: 204 | $ref: '#/definitions/RepositoryInfo' 205 | DiscoveryEntry: 206 | type: object 207 | required: 208 | - entry 209 | properties: 210 | entry: 211 | $ref: '#/definitions/RepositoryEntry' -------------------------------------------------------------------------------- /src/main/webapp/definitions/alfresco-model.yaml: -------------------------------------------------------------------------------- 1 | swagger: '2.0' 2 | info: 3 | description: | 4 | **Model API** 5 | 6 | Provides access to the model features of Alfresco Content Services. 7 | version: '1' 8 | title: Alfresco Content Services REST API 9 | basePath: /alfresco/api/-default-/public/alfresco/versions/1 10 | securityDefinitions: 11 | basicAuth: 12 | type: basic 13 | description: HTTP Basic Authentication 14 | security: 15 | - basicAuth: [] 16 | consumes: 17 | - application/json 18 | produces: 19 | - application/json 20 | tags: 21 | - name: aspects 22 | description: Retrieve and manage aspects 23 | - name: types 24 | description: Retrieve and manage types 25 | 26 | parameters: 27 | skipCountParam: 28 | name: skipCount 29 | in: query 30 | description: | 31 | The number of entities that exist in the collection before those included in this list. 32 | If not supplied then the default value is 0. 33 | required: false 34 | type: integer 35 | minimum: 0 36 | default: 0 37 | maxItemsParam: 38 | name: maxItems 39 | in: query 40 | description: | 41 | The maximum number of items to return in the list. 42 | If not supplied then the default value is 100. 43 | required: false 44 | type: integer 45 | minimum: 1 46 | default: 100 47 | 48 | paths: 49 | '/aspects': 50 | get: 51 | x-alfresco-since: "7.0.0" 52 | tags: 53 | - aspects 54 | summary: List aspects 55 | description: | 56 | **Note:** This is available in Alfresco 7.0.0 and newer versions. 57 | 58 | Gets a list of aspects from the data dictionary. The System aspects will be ignored by default. 59 | ```JSON 60 | { 61 | "list": { 62 | "pagination": { 63 | "count": 0, 64 | "hasMoreItems": true, 65 | "totalItems": 0, 66 | "skipCount": 0, 67 | "maxItems": 0 68 | }, 69 | "entries": [ 70 | { 71 | "entry": { 72 | "associations": [], 73 | "mandatoryAspects": [], 74 | "includedInSupertypeQuery": true, 75 | "description": "Titled", 76 | "isContainer": false, 77 | "model": { 78 | "id": "cm:contentmodel", 79 | "author": "Alfresco", 80 | "description": "Alfresco Content Domain Model", 81 | "namespaceUri": "http://www.alfresco.org/model/content/1.0", 82 | "namespacePrefix": "cm" 83 | }, 84 | "id": "cm:titled", 85 | "title": "Titled", 86 | "properties": [ 87 | { 88 | "id": "cm:title", 89 | "title": "Title", 90 | "description": "Content Title", 91 | "dataType": "d:mltext", 92 | "isMultiValued": false, 93 | "isMandatory": false, 94 | "isMandatoryEnforced": false, 95 | "isProtected": false 96 | }, 97 | { 98 | ... 99 | } 100 | ] 101 | } 102 | }, 103 | { 104 | "entry": { 105 | ... 106 | } 107 | }, 108 | { 109 | "entry": { 110 | ... 111 | } 112 | }, 113 | ] 114 | } 115 | } 116 | ``` 117 | operationId: listAspects 118 | parameters: 119 | - name: where 120 | in: query 121 | description: | 122 | Optionally filter the list. Here are some examples: 123 | 124 | An aspect should represented in the following format(`prefix:name`). e.g 'cm:title'. 125 | 126 | The following where clause will only return aspects from the `namespace1:model` and `namespace2:model`. 127 | ``` 128 | where=(modelId in ('namespace1:model','namespace2:model')) 129 | where=(modelId in ('namespace1:model INCLUDESUBASPECTS','namespace2:model')) 130 | ``` 131 | 132 | The following where clause will only return sub aspects for the given parents. 133 | ``` 134 | where=(parentId in ('namespace1:parent','namespace2:parent')) 135 | ``` 136 | 137 | The following where clause will only return aspects that match the pattern. 138 | ``` 139 | where=(namespaceUri matches('http://www.alfresco.*')) 140 | ``` 141 | 142 | The following where clause will only return aspects that don't match the pattern. 143 | ``` 144 | where=(not namespaceUri matches('http://www.alfresco.*')) 145 | ``` 146 | required: false 147 | type: string 148 | - $ref: '#/parameters/skipCountParam' 149 | - $ref: '#/parameters/maxItemsParam' 150 | - name: include 151 | in: query 152 | description: | 153 | Returns additional information about the aspect. The following optional fields can be requested: 154 | * properties 155 | * mandatoryAspects 156 | * associations 157 | required: false 158 | type: array 159 | items: 160 | type: string 161 | collectionFormat: csv 162 | produces: 163 | - application/json 164 | responses: 165 | '200': 166 | description: Successful response 167 | schema: 168 | $ref: '#/definitions/AspectPaging' 169 | '401': 170 | description: Authentication failed 171 | default: 172 | description: Unexpected error 173 | schema: 174 | $ref: '#/definitions/Error' 175 | '/aspects/{aspectId}': 176 | get: 177 | x-alfresco-since: "7.0.0" 178 | tags: 179 | - aspects 180 | summary: Get an aspect 181 | description: | 182 | **Note:** This is available in Alfresco 7.0.0 and newer versions. 183 | Get information for aspect **aspectId**. 184 | parameters: 185 | - name: aspectId 186 | in: path 187 | description: The Qname of an aspect(`prefix:name`) e.g 'cm:title' 188 | required: true 189 | type: string 190 | produces: 191 | - application/json 192 | operationId: getAspect 193 | responses: 194 | '200': 195 | description: Successful response 196 | schema: 197 | $ref: '#/definitions/AspectEntry' 198 | '400': 199 | description: | 200 | Invalid parameter: unknown aspectId scheme specified 201 | '401': 202 | description: Authentication failed 203 | '404': 204 | description: | 205 | **aspectId** does not exist 206 | default: 207 | description: Unexpected error 208 | schema: 209 | $ref: '#/definitions/Error' 210 | '/types': 211 | get: 212 | x-alfresco-since: "7.0.0" 213 | tags: 214 | - types 215 | summary: List types 216 | description: | 217 | **Note:** This is available in Alfresco 7.0.0 and newer versions. 218 | 219 | Gets a list of types from the data dictionary. The System types will be ignored by default. 220 | ```JSON 221 | { 222 | "list": { 223 | "pagination": { 224 | "count": 0, 225 | "hasMoreItems": true, 226 | "totalItems": 0, 227 | "skipCount": 0, 228 | "maxItems": 0 229 | }, 230 | "entries": [ 231 | { 232 | "entry": { 233 | "associations": [], 234 | "isArchive": true, 235 | "mandatoryAspects": [ 236 | "cm:auditable", 237 | "sys:referenceable", 238 | "sys:localized" 239 | ], 240 | "includedInSupertypeQuery": true, 241 | "description": "Base Content Object", 242 | "isContainer": false, 243 | "model": { 244 | "id": "cm:contentmodel", 245 | "author": "Alfresco", 246 | "description": "Alfresco Content Domain Model", 247 | "namespaceUri": "http://www.alfresco.org/model/content/1.0", 248 | "namespacePrefix": "cm" 249 | }, 250 | "id": "cm:content", 251 | "title": "Content", 252 | "parentId": "cm:cmobject" 253 | "properties": [ 254 | { 255 | "id": "cm:name", 256 | "title": "Name", 257 | "description": "Name", 258 | "dataType": "d:text", 259 | "isMultiValued": false, 260 | "isMandatory": true, 261 | "isMandatoryEnforced": true 262 | "isProtected": false 263 | ... 264 | }, 265 | { 266 | ... 267 | } 268 | ] 269 | } 270 | }, 271 | { 272 | "entry": { 273 | ... 274 | } 275 | }, 276 | { 277 | "entry": { 278 | ... 279 | } 280 | }, 281 | ] 282 | } 283 | } 284 | ``` 285 | operationId: listTypes 286 | parameters: 287 | - name: where 288 | in: query 289 | description: | 290 | Optionally filter the list. Here are some examples: 291 | 292 | A type should represented in the following format(`prefix:name`). e.g 'cm:content'. 293 | 294 | The following where clause will only return types from the `namespace1:model` and `namespace2:model`. 295 | ``` 296 | where=(modelId in ('namespace1:model','namespace2:model')) 297 | where=(modelId in ('namespace1:model INCLUDESUBTYPES','namespace2:model')) 298 | ``` 299 | 300 | The following where clause will only return sub types for the given parents. 301 | ``` 302 | where=(parentId in ('namespace1:parent','namespace2:parent')) 303 | ``` 304 | 305 | The following where clause will only return types that match the pattern. 306 | ``` 307 | where=(namespaceUri matches('http://www.alfresco.*')) 308 | ``` 309 | 310 | The following where clause will only return types that don't match the pattern. 311 | ``` 312 | where=(not namespaceUri matches('http://www.alfresco.*')) 313 | ``` 314 | required: false 315 | type: string 316 | - $ref: '#/parameters/skipCountParam' 317 | - $ref: '#/parameters/maxItemsParam' 318 | - name: include 319 | in: query 320 | description: | 321 | Returns additional information about the type. The following optional fields can be requested: 322 | * properties 323 | * mandatoryAspects 324 | * associations 325 | required: false 326 | type: array 327 | items: 328 | type: string 329 | collectionFormat: csv 330 | produces: 331 | - application/json 332 | responses: 333 | '200': 334 | description: Successful response 335 | schema: 336 | $ref: '#/definitions/TypePaging' 337 | '401': 338 | description: Authentication failed 339 | default: 340 | description: Unexpected error 341 | schema: 342 | $ref: '#/definitions/Error' 343 | '/types/{typeId}': 344 | get: 345 | x-alfresco-since: "7.0.0" 346 | tags: 347 | - types 348 | summary: Get a type 349 | description: | 350 | **Note:** This is available in Alfresco 7.0.0 and newer versions. 351 | Get information for type **typeId**. 352 | parameters: 353 | - name: typeId 354 | in: path 355 | description: The Qname of a type(`prefix:name`) e.g 'cm:content' 356 | required: true 357 | type: string 358 | 359 | produces: 360 | - application/json 361 | operationId: getType 362 | responses: 363 | '200': 364 | description: Successful response 365 | schema: 366 | $ref: '#/definitions/TypeEntry' 367 | '400': 368 | description: | 369 | Invalid parameter: unknown typeId scheme specified 370 | '401': 371 | description: Authentication failed 372 | '404': 373 | description: | 374 | **typeId** does not exist 375 | default: 376 | description: Unexpected error 377 | schema: 378 | $ref: '#/definitions/Error' 379 | definitions: 380 | Error: 381 | type: object 382 | required: 383 | - error 384 | properties: 385 | error: 386 | type: object 387 | required: 388 | - statusCode 389 | - briefSummary 390 | - stackTrace 391 | - descriptionURL 392 | properties: 393 | errorKey: 394 | type: string 395 | statusCode: 396 | type: integer 397 | format: int32 398 | briefSummary: 399 | type: string 400 | stackTrace: 401 | type: string 402 | descriptionURL: 403 | type: string 404 | logId: 405 | type: string 406 | Pagination: 407 | type: object 408 | properties: 409 | count: 410 | type: integer 411 | format: int64 412 | description: | 413 | The number of objects in the entries array. 414 | hasMoreItems: 415 | type: boolean 416 | description: | 417 | A boolean value which is **true** if there are more entities in the collection 418 | beyond those in this response. A true value means a request with a larger value 419 | for the **skipCount** or the **maxItems** parameter will return more entities. 420 | totalItems: 421 | type: integer 422 | format: int64 423 | description: | 424 | An integer describing the total number of entities in the collection. 425 | The API might not be able to determine this value, 426 | in which case this property will not be present. 427 | skipCount: 428 | type: integer 429 | format: int64 430 | description: | 431 | An integer describing how many entities exist in the collection before 432 | those included in this list. If there was no **skipCount** parameter then the 433 | default value is 0. 434 | maxItems: 435 | type: integer 436 | format: int64 437 | description: | 438 | The value of the **maxItems** parameter used to generate this list. 439 | If there was no **maxItems** parameter then the default value is 100. 440 | AspectPaging: 441 | type: object 442 | properties: 443 | list: 444 | type: object 445 | properties: 446 | pagination: 447 | $ref: '#/definitions/Pagination' 448 | entries: 449 | type: array 450 | items: 451 | $ref: '#/definitions/AspectEntry' 452 | AspectEntry: 453 | type: object 454 | required: 455 | - entry 456 | properties: 457 | entry: 458 | $ref: '#/definitions/Aspect' 459 | Aspect: 460 | $ref: '#/definitions/AbstractClass' 461 | TypePaging: 462 | type: object 463 | properties: 464 | list: 465 | type: object 466 | properties: 467 | pagination: 468 | $ref: '#/definitions/Pagination' 469 | entries: 470 | type: array 471 | items: 472 | $ref: '#/definitions/TypeEntry' 473 | TypeEntry: 474 | type: object 475 | required: 476 | - entry 477 | properties: 478 | entry: 479 | $ref: '#/definitions/Type' 480 | Type: 481 | $ref: '#/definitions/AbstractClass' 482 | AbstractClass: 483 | type: object 484 | required: 485 | - id 486 | - title 487 | properties: 488 | id: 489 | type: string 490 | title: 491 | type: string 492 | description: 493 | type: string 494 | parentId: 495 | type: string 496 | properties: 497 | type: array 498 | items: 499 | $ref: '#/definitions/Property' 500 | isContainer: 501 | type: boolean 502 | isArchive: 503 | type: boolean 504 | includedInSupertypeQuery: 505 | type: boolean 506 | mandatoryAspects: 507 | type: array 508 | items: 509 | type: string 510 | associations: 511 | type: array 512 | items: 513 | $ref: '#/definitions/AbstractClassAssociation' 514 | model: 515 | $ref: '#/definitions/Model' 516 | Property: 517 | type: object 518 | required: 519 | - id 520 | properties: 521 | id: 522 | type: string 523 | title: 524 | description: the human-readable title 525 | type: string 526 | description: 527 | description: the human-readable description 528 | type: string 529 | defaultValue: 530 | description: the default value 531 | type: string 532 | dataType: 533 | description: the name of the property type (e.g. d:text) 534 | type: string 535 | isMultiValued: 536 | description: define if the property is multi-valued 537 | type: boolean 538 | isMandatory: 539 | description: define if the property is mandatory 540 | type: boolean 541 | isMandatoryEnforced: 542 | description: define if the presence of mandatory properties is enforced 543 | type: boolean 544 | isProtected: 545 | description: define if the property is system maintained 546 | type: boolean 547 | constraints: 548 | description: list of constraints defined for the property 549 | type: array 550 | items: 551 | $ref: '#/definitions/Constraint' 552 | Constraint: 553 | type: object 554 | required: 555 | - id 556 | properties: 557 | id: 558 | type: string 559 | type: 560 | description: the type of the constraint 561 | type: string 562 | title: 563 | description: the human-readable constraint title 564 | type: string 565 | description: 566 | description: the human-readable constraint description 567 | type: string 568 | parameters: 569 | type: object 570 | additionalProperties: 571 | type: object 572 | Model: 573 | type: object 574 | required: 575 | - id 576 | properties: 577 | id: 578 | type: string 579 | author: 580 | type: string 581 | description: 582 | type: string 583 | namespaceUri: 584 | type: string 585 | namespacePrefix: 586 | type: string 587 | AbstractClassAssociation: 588 | type: object 589 | required: 590 | - id 591 | properties: 592 | id: 593 | type: string 594 | title: 595 | type: string 596 | description: 597 | type: string 598 | isChild: 599 | type: boolean 600 | isProtected: 601 | type: boolean 602 | source: 603 | $ref: '#/definitions/AbstractClassAssociationSource' 604 | target: 605 | $ref: '#/definitions/AbstractClassAssociationSource' 606 | AbstractClassAssociationSource: 607 | type: object 608 | properties: 609 | role: 610 | type: string 611 | cls: 612 | type: string 613 | isMandatory: 614 | type: boolean 615 | isMany: 616 | type: boolean 617 | isMandatoryEnforced: 618 | type: boolean 619 | -------------------------------------------------------------------------------- /src/main/webapp/definitions/alfresco-search-sql.yaml: -------------------------------------------------------------------------------- 1 | swagger: '2.0' 2 | info: 3 | description: | 4 | **Search SQL API** 5 | A Solr SQL passthrough, this feature provides the ability to use SQL to query Solr. 6 | version: '1' 7 | title: Alfresco Insight Engine REST API 8 | basePath: /alfresco/api/-default-/public/search/versions/1 9 | securityDefinitions: 10 | basicAuth: 11 | type: basic 12 | description: HTTP Basic Authentication 13 | security: 14 | - basicAuth: [] 15 | consumes: 16 | - application/json 17 | produces: 18 | - application/json 19 | paths: 20 | '/sql': 21 | post: 22 | x-alfresco-since: "6.0" 23 | tags: 24 | - sql 25 | summary: Alfresco Insight Engine SQL Passthrough 26 | description: | 27 | **Note**: this endpoint is available in Alfresco 6.0 and newer versions. 28 | This will require Insight Engine and will not work with Alfresco Search Services. 29 | 30 | **You specify all the parameters in this API in a JSON body**, 31 | A basic query looks like this: 32 | 33 | ```JSON 34 | { 35 | "stmt": "select * from alfresco", 36 | "locales": ["en_UK"], 37 | "timezone": "Europe/London", 38 | "includeMetadata":true 39 | } 40 | ``` 41 | 42 | **Note:** the minimum possible query parameter required. 43 | ```JSON 44 | { 45 | "stmt": 46 | } 47 | ``` 48 | The expected reponse will appear in the Alfresco format as seen below. 49 | ```JSON 50 | { 51 | "list": { 52 | "pagination": { 53 | "count": 1, 54 | "hasMoreItems": false, 55 | "totalItems": 1, 56 | "skipCount": 0, 57 | "maxItems": 100 58 | }, 59 | "entries": [{ 60 | "entry": [ 61 | { 62 | "label": "aliases", 63 | "value": "{\"SITE\":\"site\"}" 64 | }, 65 | { 66 | "label": "isMetadata", 67 | "value": "true" 68 | }, 69 | { 70 | "label": "fields", 71 | "value": "[\"SITE\"]" 72 | } 73 | ] 74 | }]}} 75 | ``` 76 | To override the default format set the format to solr. 77 | ```JSON 78 | { 79 | "stmt": "select * from alfresco", 80 | "format": "solr" 81 | } 82 | ``` 83 | This will return Solr's output response. 84 | ```JSON 85 | { 86 | "result-set": { 87 | "docs": [ 88 | { 89 | "aliases": { 90 | "SITE": "site" 91 | }, 92 | "isMetadata": true, 93 | "fields": [ "SITE"] 94 | }, 95 | { 96 | "RESPONSE_TIME": 23, 97 | "EOF": true 98 | } 99 | ]} 100 | } 101 | ``` 102 | 103 | 104 | You can use the **locales parameter** to filter results based on locale. 105 | ```JSON 106 | "locales": ["en_UK", "en_US"] 107 | ``` 108 | 109 | To include timezone in the query add the **timezone parameter**. 110 | ```JSON 111 | "timezone": "Japan" 112 | ``` 113 | 114 | To include custom filter queries add the **filterQueries parameter**. 115 | ```JSON 116 | "filterQueries": ["-SITE:swsdp"] 117 | ``` 118 | 119 | You can use the **includeMetadata parameter** to include addtional information, this is by default set to false. 120 | 121 | ```JSON 122 | "includeMetadata": "false" 123 | ``` 124 | Please note that if its set to true the first entry will represent the metdata requested 125 | 126 | ```JSON 127 | { 128 | "stmt": "select site from alfresco limit 2", 129 | "includeMetadata":true 130 | } 131 | ``` 132 | The expected response: 133 | ```JSON 134 | "entries": [ 135 | { 136 | #First entry holds the Metadata infromation as set by {includeMetadata:true} 137 | "entry": [ 138 | { 139 | "label": "aliases", 140 | "value": "{\"SITE\":\"site\"}" 141 | 142 | }, 143 | { 144 | "label": "isMetadata", 145 | "value": "true" 146 | }, 147 | { 148 | "label": "fields", 149 | "value": "[\"SITE\"]" 150 | } 151 | ] 152 | #end of Metadata 153 | }, 154 | { 155 | #Query result entry value. 156 | "entry": [ 157 | { 158 | "label": "site", 159 | "value": "[\"test\"]" 160 | } 161 | ] 162 | }, 163 | { 164 | "entry": [ 165 | { 166 | "label": "site", 167 | "value": "[\"test\"]" 168 | } 169 | ] 170 | } 171 | ] 172 | ``` 173 | 174 | parameters: 175 | - in: body 176 | name: queryBody 177 | description: | 178 | Generic query API 179 | required: true 180 | schema: 181 | $ref: '#/definitions/SQLSearchRequest' 182 | operationId: search 183 | produces: 184 | - application/json 185 | 186 | responses: 187 | '200': 188 | description: Successful response 189 | schema: 190 | $ref: '#/definitions/SQLResultSetPaging' 191 | default: 192 | description: Unexpected error 193 | schema: 194 | $ref: '#/definitions/Error' 195 | 196 | 197 | definitions: 198 | 199 | ## Standard definition 200 | Error: 201 | type: object 202 | required: 203 | - error 204 | properties: 205 | error: 206 | type: object 207 | required: 208 | - statusCode 209 | - briefSummary 210 | - stackTrace 211 | - descriptionURL 212 | properties: 213 | errorKey: 214 | type: string 215 | statusCode: 216 | type: integer 217 | format: int32 218 | briefSummary: 219 | type: string 220 | stackTrace: 221 | type: string 222 | descriptionURL: 223 | type: string 224 | logId: 225 | type: string 226 | 227 | SQLSearchRequest: 228 | type: object 229 | properties: 230 | stmt: 231 | type: string 232 | format: 233 | type: string 234 | locales: 235 | type: array 236 | items: 237 | type: string 238 | timezone: 239 | type: string 240 | filterQueries: 241 | type: array 242 | items: 243 | type: string 244 | includeMetadata: 245 | type: boolean 246 | 247 | 248 | # ReponseQuery 249 | 250 | SQLResultSetPaging: 251 | description: Query results 252 | type: object 253 | properties: 254 | list: 255 | type: object 256 | properties: 257 | pagination: 258 | $ref: '#/definitions/Pagination' 259 | entries: 260 | type: array 261 | items: 262 | $ref: '#/definitions/SQLResultSetRowEntry' 263 | Pagination: 264 | type: object 265 | required: 266 | - count 267 | - hasMoreItems 268 | - skipCount 269 | - maxItems 270 | properties: 271 | count: 272 | type: integer 273 | format: int64 274 | description: | 275 | The number of objects in the entries array. 276 | hasMoreItems: 277 | type: boolean 278 | description: | 279 | A boolean value which is **true** if there are more entities in the collection 280 | beyond those in this response. A true value means a request with a larger value 281 | for the **skipCount** or the **maxItems** parameter will return more entities. 282 | totalItems: 283 | type: integer 284 | format: int64 285 | description: | 286 | An integer describing the total number of entities in the collection. 287 | The API might not be able to determine this value, 288 | in which case this property will not be present. 289 | skipCount: 290 | type: integer 291 | format: int64 292 | description: | 293 | An integer describing how many entities exist in the collection before 294 | those included in this list. 295 | maxItems: 296 | type: integer 297 | format: int64 298 | description: | 299 | The value of the **maxItems** parameter used to generate this list, 300 | or if there was no **maxItems** parameter the default value is 100 301 | 302 | SQLResultSetRowEntry: 303 | type: object 304 | properties: 305 | label: 306 | type: string 307 | value: 308 | type: string 309 | 310 | SolrResultSet: 311 | description: SQL results in Solr formatting 312 | type: object 313 | properties: 314 | result-set: 315 | type: object 316 | $ref: '#/definitions/docs' 317 | docs: 318 | description: Array of documents returned by the query, note that this is a Solr convention. 319 | type: array 320 | items: 321 | type: object 322 | properties: 323 | label: 324 | type: string 325 | value: 326 | type: string 327 | -------------------------------------------------------------------------------- /src/main/webapp/definitions/alfresco-search.yaml: -------------------------------------------------------------------------------- 1 | swagger: '2.0' 2 | info: 3 | description: | 4 | **Search API** 5 | 6 | Provides access to the search features of Alfresco Content Services. 7 | version: '1' 8 | title: Alfresco Content Services REST API 9 | basePath: /alfresco/api/-default-/public/search/versions/1 10 | securityDefinitions: 11 | basicAuth: 12 | type: basic 13 | description: HTTP Basic Authentication 14 | security: 15 | - basicAuth: [] 16 | consumes: 17 | - application/json 18 | produces: 19 | - application/json 20 | paths: 21 | '/search': 22 | post: 23 | x-alfresco-since: "5.2" 24 | tags: 25 | - search 26 | summary: Searches Alfresco 27 | description: | 28 | **Note**: this endpoint is available in Alfresco 5.2 and newer versions. 29 | 30 | **You specify all the parameters in this API in a JSON body**, URL parameters are not supported. 31 | A basic query looks like this: 32 | 33 | ```JSON 34 | { 35 | "query": { 36 | "query": "foo" 37 | } 38 | } 39 | ``` 40 | 41 | **Note:** These are the minimum possible query parameters. 42 | 43 | The default search language is **afts** ([Alfresco Full Text Search](http://docs.alfresco.com/5.1/concepts/rm-searchsyntax-intro.html)), but you can also specify **cmis**, and **lucene**. 44 | 45 | A basic CMIS query looks like this: 46 | 47 | ```JSON 48 | { 49 | "query": { 50 | "query": "select * from cmis:folder", 51 | "language": "cmis" 52 | } 53 | } 54 | ``` 55 | 56 | By default, **results are limited to the first 100.** 57 | Results can be restricted using "paging". For example: 58 | ```JSON 59 | "paging": { 60 | "maxItems": "50", 61 | "skipCount": "28" 62 | } 63 | ``` 64 | This example would ensure that results are **limited by Final Size**, skipping the first 28 results and returning the next 50. 65 | 66 | Alternatively, you can limit the results by using the **limits JSON body parameter**. For example, 67 | ```JSON 68 | "limits": { 69 | "permissionEvaluationTime": 20000, 70 | "permissionEvaluationCount": 2000 71 | } 72 | ``` 73 | 74 | You can use the **include JSON body parameter** to return additional information. 75 | This works in the same way as in the /nodes/{nodeId}/children method in the core API. For example: 76 | ```JSON 77 | "include": ["aspectNames", "properties", "isLink"] 78 | ``` 79 | 80 | You can use the **fields JSON body parameter** to restrict the fields returned within a response if, for example, you want to save on overall bandwidth. 81 | This works in the same way as in the /nodes/{nodeId}/children method in the core API. For example: 82 | ```JSON 83 | "fields": ["id", "name", "search"] 84 | ``` 85 | 86 | You can sort the results using the **sort JSON body parameter**, for example: 87 | ```JSON 88 | "sort": [{"type":"FIELD", "field":"cm:description", "ascending":"true"}] 89 | ``` 90 | **Note:** the **sort** parameter is not supported for CMIS queries. 91 | 92 | By default, search uses the **"nodes" location**, which is the **content store known as workspace://SpacesStore**. 93 | To change the scope to another location you can use the **locations JSON body parameter**. 94 | You can specify either **nodes** (the default), **versions** or **deleted-nodes**. For example: 95 | ```JSON 96 | "scope": { 97 | "locations": ["deleted-nodes"] 98 | } 99 | ``` 100 | You can specify templates using the **templates JSON body parameter**, for example: 101 | ```JSON 102 | "templates": [{"name": "_PERSON","template": "|%firstName OR |%lastName OR |%userName"}, 103 | {"name": "mytemplate","template": "%cm:content"}] 104 | ``` 105 | 106 | **Note: Spell checking only works on Search Services (Solr 6) if you have already enabled suggestions.** 107 | 108 | For **spell checking** you can use a query like this: 109 | ```JSON 110 | { 111 | "query": { 112 | "query": "cm:title:alfrezco" 113 | }, 114 | "spellcheck": {"query": "alfrezco"} 115 | } 116 | ``` 117 | 118 | If you are already specifying "userQuery" then the following may be easier and produces the same result : 119 | ```JSON 120 | { 121 | "query": { 122 | "query": "cm:title:alfrezco", 123 | "userQuery": "alfrezco" 124 | }, 125 | "spellcheck": {} 126 | } 127 | ``` 128 | 129 | The spellcheck response includes a spellCheck context like this: 130 | ```JSON 131 | "context": { 132 | "spellCheck": { 133 | "type": "searchInsteadFor", 134 | "suggestions": ["alfresco"] 135 | } 136 | }, 137 | ``` 138 | 139 | To specify defaults, you use a **defaults JSON body parameter**, for example: 140 | ```JSON 141 | "defaults": { 142 | "textAttributes": [ 143 | "cm:content", "cm:name" 144 | ], 145 | "defaultFTSOperator": "AND", 146 | "defaultFTSFieldOperator": "OR", 147 | "namespace": "cm", 148 | "defaultFieldName": "PATH" 149 | } 150 | ``` 151 | 152 | You can specify several filter queries using the **filterQueries JSON body parameter**, for example: 153 | ```JSON 154 | "filterQueries": [{"query": "TYPE:'cm:folder'"},{"query": "cm:creator:mjackson"}] 155 | ``` 156 | 157 | You can specify several facet queries using the **facetQueries JSON body parameter**, for example: 158 | ```JSON 159 | "facetQueries": [{"query": "created:2016","label": "CreatedThisYear"}] 160 | ``` 161 | The response will contain a matching "context" section, the "label" will match the facet query. 162 | ```JSON 163 | "context": { 164 | "facetQueries": [ 165 | {"label": "CreatedThisYear","count": 3} 166 | ] 167 | }, 168 | ``` 169 | 170 | A complete query for facetting via the content.size field looks this: 171 | ```JSON 172 | { 173 | "query": { 174 | "query": "presentation", 175 | "language": "afts" 176 | }, 177 | "facetQueries": [ 178 | {"query": "content.size:[0 TO 10240]", "label": "xtra small"}, 179 | {"query": "content.size:[10240 TO 102400]", "label": "small"}, 180 | {"query": "content.size:[102400 TO 1048576]", "label": "medium"}, 181 | {"query": "content.size:[1048576 TO 16777216]", "label": "large"}, 182 | {"query": "content.size:[16777216 TO 134217728]", "label": "xtra large"}, 183 | {"query": "content.size:[134217728 TO MAX]", "label": "XX large"} 184 | ], 185 | "facetFields": {"facets": [{"field": "'content.size'"}]} 186 | } 187 | ``` 188 | 189 | The response will contain a matching "context" section, the "label" will match the facet query. 190 | ```JSON 191 | "context": { 192 | "facetQueries": [ 193 | { "label": "small","count": 2 }, 194 | { "label": "large","count": 0 }, 195 | { "label": "xtra small","count": 5 }, 196 | { "label": "xtra large","count": 56}, 197 | { "label": "medium","count": 4 }, 198 | { "label": "XX large", "count": 1 } 199 | ] 200 | }, 201 | ``` 202 | 203 | You can specify several facet fields using the **facetFields JSON body parameter**, for example: 204 | ```JSON 205 | "facetFields": {"facets": [{"field": "creator", "mincount": 1}, {"field": "modifier", "mincount": 1}]} 206 | ``` 207 | The response will contain a matching "context" section, the "label" will match the facet field. 208 | ```JSON 209 | "context": { 210 | "facetsFields": [ 211 | { "label": "creator", 212 | "buckets": [ 213 | { "label": "System", "count": 75 }, 214 | { "label": "mjackson", "count": 5 } 215 | ]}, 216 | { "label": "modifier", 217 | "buckets": [ 218 | { "label": "System", "count": 72 }, 219 | { "label": "mjackson", "count": 5 }, 220 | { "label": "admin", "count": 3 } 221 | ]} 222 | ] 223 | }, 224 | ``` 225 | 226 | Grouping facet queries that go together can be done by specifying the group label in the fact queries as follow: 227 | ```JSON 228 | { 229 | "query": { 230 | "query": "presentation" 231 | }, 232 | "facetQueries": [ 233 | {"query": "content.size:[0 TO 102400]", "label": "small", "group":"foo"}, 234 | {"query": "content.size:[102400 TO 1048576]", "label": "medium","group":"foo"}, 235 | {"query": "content.size:[1048576 TO 16777216]", "label": "large","group":"foo"} 236 | ] 237 | } 238 | ``` 239 | The above query returns the results a faceted field grouped under the label foo: 240 | ```JSON 241 | { 242 | "context": {"facetsFields": [{ 243 | "label": "foo", 244 | "buckets": [ 245 | { 246 | "count": 109, 247 | "label": "small", 248 | "filterQuery": "content.size:[0 TO 102400]" 249 | }, 250 | { 251 | "count": 0, 252 | "label": "large", 253 | "filterQuery": "content.size:[1048576 TO 16777216]" 254 | }, 255 | { 256 | "count": 0, 257 | "label": "medium", 258 | "filterQuery": "content.size:[102400 TO 1048576]" 259 | } 260 | ] 261 | }] 262 | } 263 | ``` 264 | Range Faceting is supported by the **ranges JSON body parameter**, for example: 265 | ```JSON 266 | { 267 | "query": { 268 | "query": "presentation" 269 | }, 270 | "ranges": [ 271 | { 272 | "field": "content.size", 273 | "start": "0", 274 | "end": "100", 275 | "gap": "20", 276 | "hardend": true 277 | }, 278 | { 279 | "field": "created", 280 | "start": "2015-09-29T10:45:15.729Z", 281 | "end": "2016-09-29T10:45:15.729Z", 282 | "gap": "+100DAY" 283 | }] 284 | } 285 | ``` 286 | An example query for **search highlighting** could look like this: 287 | ```JSON 288 | { 289 | "query": { 290 | "query": "description:workflow", 291 | "userQuery":"workflow" 292 | }, 293 | "highlight": { 294 | "prefix": "¿", 295 | "postfix": "?", 296 | "mergeContiguous": true, 297 | "fields": [ 298 | { 299 | "field": "cm:title" 300 | }, 301 | { 302 | "field": "description", 303 | "prefix": "(", 304 | "postfix": ")" 305 | } 306 | 307 | ] 308 | } 309 | } 310 | ``` 311 | The example above changes the highlighting prefix and postfix from the default `` for all fields to ¿? and just for the "description" field to (). 312 | The hightlight information is added in each node entry response; here is an example partial response: 313 | ``` 314 | "entry": { 315 | "createdAt": "2016-10-12T15:24:31.202+0000", 316 | "isFolder": true, 317 | "search": { 318 | "score": 1, 319 | "highlight": [ 320 | { 321 | "field": "cm:title", 322 | "snippets": [ 323 | "Customized ¿Workflow? Process Definitions" 324 | ] 325 | }, 326 | { 327 | "field": "description", 328 | "snippets": [ 329 | "Customized (Workflow) Process Definitions" 330 | ] 331 | } 332 | ] 333 | }, 334 | ``` 335 | **Note**: after the migration to Swagger UI 3, this API definition was triggering some warnings, more info in [this StackOverflow Q&A](https://stackoverflow.com/q/65584131/1654265). 336 | 337 | parameters: 338 | - in: body 339 | name: queryBody 340 | description: | 341 | Generic query API 342 | required: true 343 | schema: 344 | $ref: '#/definitions/SearchRequest' 345 | operationId: search 346 | produces: 347 | - application/json 348 | 349 | responses: 350 | '200': 351 | description: Successful response 352 | schema: 353 | $ref: '#/definitions/ResultSetPaging' 354 | default: 355 | description: Unexpected error 356 | schema: 357 | $ref: '#/definitions/Error' 358 | 359 | 360 | definitions: 361 | 362 | ## Standard definition 363 | Error: 364 | type: object 365 | required: 366 | - error 367 | properties: 368 | error: 369 | type: object 370 | required: 371 | - statusCode 372 | - briefSummary 373 | - stackTrace 374 | - descriptionURL 375 | properties: 376 | errorKey: 377 | type: string 378 | statusCode: 379 | type: integer 380 | format: int32 381 | briefSummary: 382 | type: string 383 | stackTrace: 384 | type: string 385 | descriptionURL: 386 | type: string 387 | logId: 388 | type: string 389 | SearchRequest: 390 | type: object 391 | required: 392 | - query 393 | properties: 394 | query: 395 | $ref: '#/definitions/RequestQuery' 396 | paging: 397 | $ref: '#/definitions/RequestPagination' 398 | include: 399 | $ref: '#/definitions/RequestInclude' 400 | includeRequest: 401 | description: "When true, include the original request in the response" 402 | type: boolean 403 | default: false 404 | fields: 405 | $ref: '#/definitions/RequestFields' 406 | sort: 407 | $ref: '#/definitions/RequestSortDefinition' 408 | templates: 409 | $ref: '#/definitions/RequestTemplates' 410 | defaults: 411 | $ref: '#/definitions/RequestDefaults' 412 | localization: 413 | $ref: '#/definitions/RequestLocalization' 414 | filterQueries: 415 | $ref: '#/definitions/RequestFilterQueries' 416 | facetQueries: 417 | $ref: '#/definitions/RequestFacetQueries' 418 | facetFields: 419 | $ref: '#/definitions/RequestFacetFields' 420 | facetIntervals: 421 | $ref: '#/definitions/RequestFacetIntervals' 422 | pivots: 423 | type: array 424 | items: 425 | $ref: '#/definitions/RequestPivot' 426 | stats: 427 | type: array 428 | items: 429 | $ref: '#/definitions/RequestStats' 430 | spellcheck: 431 | $ref: '#/definitions/RequestSpellcheck' 432 | scope: 433 | $ref: '#/definitions/RequestScope' 434 | limits: 435 | $ref: '#/definitions/RequestLimits' 436 | highlight: 437 | $ref: '#/definitions/RequestHighlight' 438 | ranges: 439 | type: array 440 | items: 441 | $ref: '#/definitions/RequestRange' 442 | 443 | RequestInclude: 444 | description: | 445 | Returns additional information about the node. The following optional fields can be requested: 446 | * properties 447 | * aspectNames 448 | * path 449 | * isLink 450 | * allowableOperations 451 | * association 452 | * isFavorite 453 | type: array 454 | items: 455 | type: string 456 | enum: 457 | - allowableOperations 458 | - aspectNames 459 | - isLink 460 | - isLocked 461 | - path 462 | - properties 463 | - isFavorite 464 | 465 | RequestFields: 466 | description: A list of field names. 467 | 468 | You can use this parameter to restrict the fields 469 | returned within a response if, for example, you want to save on overall bandwidth. 470 | 471 | The list applies to a returned individual 472 | entity or entries within a collection. 473 | 474 | If the **include** parameter is used aswell then the fields specified in the **include** 475 | parameter are returned in addition to those specified in the **fields** parameter. 476 | type: array 477 | items: 478 | type: string 479 | RequestPivot: 480 | description: A list of pivots. 481 | type: object 482 | properties: 483 | key: 484 | description: A key corresponding to a matching field facet label or stats. 485 | type: string 486 | pivots: 487 | type: array 488 | items: 489 | $ref: '#/definitions/RequestPivot' 490 | example: # <--- Custom example 491 | key: MyKey 492 | pivots: 493 | - key: AnotherKey 494 | pivots: [ ] 495 | RequestLocalization: 496 | description: Localization settings 497 | type: object 498 | properties: 499 | timezone: 500 | description: A valid timezone id supported by @see java.time.ZoneId 501 | type: string 502 | locales: 503 | description: A list of Locales definied by IETF BCP 47. The ordering is 504 | significant. The first locale (leftmost) is used for sort and query 505 | localization, whereas the remaining locales are used for query only. 506 | type: array 507 | items: 508 | type: string 509 | RequestStats: 510 | description: A list of stats request. 511 | type: object 512 | properties: 513 | field: 514 | description: The stats field 515 | type: string 516 | label: 517 | description: A label to include for reference the stats field 518 | type: string 519 | min: 520 | description: The minimum value of the field 521 | type: boolean 522 | default: true 523 | max: 524 | description: The maximum value of the field 525 | type: boolean 526 | default: true 527 | sum: 528 | description: The sum of all values of the field 529 | type: boolean 530 | default: true 531 | countValues: 532 | description: The number which have a value for this field 533 | type: boolean 534 | default: true 535 | missing: 536 | description: The number which do not have a value for this field 537 | type: boolean 538 | default: true 539 | mean: 540 | description: The average 541 | type: boolean 542 | default: true 543 | stddev: 544 | description: Standard deviation 545 | type: boolean 546 | default: true 547 | sumOfSquares: 548 | description: Sum of all values squared 549 | type: boolean 550 | default: true 551 | distinctValues: 552 | description: The set of all distinct values for the field (This can be very 553 | expensive to calculate) 554 | type: boolean 555 | default: false 556 | countDistinct: 557 | description: The number of distinct values (This can be very expensive to 558 | calculate) 559 | type: boolean 560 | default: false 561 | cardinality: 562 | description: A statistical approximation of the number of distinct values 563 | type: boolean 564 | default: false 565 | cardinalityAccuracy: 566 | description: Number between 0.0 and 1.0 indicating how aggressively the algorithm 567 | should try to be accurate. Used with boolean cardinality flag. 568 | type: number 569 | format: float 570 | default: 0.3 571 | excludeFilters: 572 | description: A list of filters to exclude 573 | type: array 574 | items: 575 | type: string 576 | percentiles: 577 | description: A list of percentile values, e.g. "1,99,99.9" 578 | type: array 579 | items: 580 | type: number 581 | format: float 582 | RequestQuery: 583 | description: Query. 584 | type: object 585 | required: 586 | - query 587 | properties: 588 | language: 589 | description: The query language in which the query is written. 590 | type: string 591 | default: afts 592 | enum: 593 | - afts 594 | - lucene 595 | - cmis 596 | userQuery: 597 | description: The exact search request typed in by the user 598 | type: string 599 | query: 600 | description: The query which may have been generated in some way from the userQuery 601 | type: string 602 | 603 | # ResponseQuery 604 | 605 | ResultSetPaging: 606 | description: Query results 607 | type: object 608 | properties: 609 | list: 610 | type: object 611 | properties: 612 | pagination: 613 | $ref: '#/definitions/Pagination' 614 | context: 615 | $ref: '#/definitions/ResultSetContext' 616 | entries: 617 | type: array 618 | items: 619 | $ref: '#/definitions/ResultSetRowEntry' 620 | 621 | ResultSetContext: 622 | description: Context that applies to the whole result set 623 | type: object 624 | properties: 625 | consistency: 626 | $ref: '#/definitions/ResponseConsistency' 627 | request: 628 | $ref: '#/definitions/SearchRequest' 629 | facetQueries: 630 | description: The counts from facet queries 631 | type: array 632 | items: 633 | type: object 634 | properties: 635 | label: 636 | type: string 637 | filterQuery: 638 | description: The filter query you can use to apply this facet 639 | type: string 640 | count: 641 | type: integer 642 | facetsFields: 643 | description: The counts from field facets 644 | type: array 645 | items: 646 | $ref: '#/definitions/ResultBuckets' 647 | facets: 648 | description: The faceted response 649 | type: array 650 | items: 651 | $ref: '#/definitions/GenericFacetResponse' 652 | spellcheck: 653 | description: | 654 | Suggested corrections 655 | 656 | If zero results were found for the original query then a single entry of type "searchInsteadFor" will be returned. 657 | If alternatives were found that return more results than the original query they are returned as "didYouMean" options. 658 | The highest quality suggestion is first. 659 | type: array 660 | items: 661 | type: object 662 | properties: 663 | "type": 664 | type: string 665 | enum: 666 | - searchInsteadFor 667 | - didYouMean 668 | suggestion: 669 | description: A suggested alternative query 670 | type: array 671 | items: 672 | type: string 673 | GenericFacetResponse: 674 | type: object 675 | properties: 676 | type: 677 | description: The facet type, eg. interval, range, pivot, stats 678 | type: string 679 | label: 680 | description: The field name or its explicit label, if provided on the request 681 | type: string 682 | buckets: 683 | description: An array of buckets and values 684 | type: array 685 | items: 686 | $ref: '#/definitions/GenericBucket' 687 | GenericBucket: 688 | description: A bucket of facet results 689 | type: object 690 | properties: 691 | label: 692 | description: The bucket label 693 | type: string 694 | filterQuery: 695 | description: The filter query you can use to apply this facet 696 | type: string 697 | display: 698 | description: An optional field for additional display information 699 | type: object 700 | metrics: 701 | description: An array of buckets and values 702 | type: array 703 | items: 704 | $ref: '#/definitions/GenericMetric' 705 | facets: 706 | description: Additional list of nested facets 707 | type: array 708 | items: 709 | type: object 710 | bucketInfo: 711 | description: Additional information of nested facet 712 | type: object 713 | properties: 714 | start: 715 | description: The start of range 716 | type: string 717 | startInclusive: 718 | description: Includes values greater or equal to "start" 719 | type: boolean 720 | end: 721 | description: The end of range 722 | type: string 723 | endInclusive: 724 | description: Includes values less than or equal to "end" 725 | type: boolean 726 | GenericMetric: 727 | description: A metric used in faceting 728 | type: object 729 | properties: 730 | type: 731 | description: The type of metric, e.g. count 732 | type: string 733 | value: 734 | description: | 735 | The metric value, e.g. {"count": 34} 736 | type: object 737 | ResultBuckets: 738 | type: object 739 | properties: 740 | label: 741 | description: The field name or its explicit label, if provided on the request 742 | type: string 743 | buckets: 744 | description: An array of buckets and values 745 | type: array 746 | items: 747 | type: object 748 | properties: 749 | label: 750 | description: The bucket label 751 | type: string 752 | filterQuery: 753 | description: The filter query you can use to apply this facet 754 | type: string 755 | count: 756 | description: The count for the bucket 757 | type: integer 758 | display: 759 | description: An optional field for additional display information 760 | type: object 761 | ResultSetRowEntry: 762 | description: A row in the result set 763 | type: object 764 | required: 765 | - entry 766 | properties: 767 | ## Standard response structure 768 | entry: 769 | $ref: '#/definitions/ResultNode' 770 | 771 | ResultNode: 772 | allOf: 773 | - $ref: '#/definitions/Node' 774 | - type: object 775 | properties: 776 | search: 777 | $ref: '#/definitions/SearchEntry' 778 | archivedByUser: 779 | $ref: '#/definitions/UserInfo' 780 | archivedAt: 781 | type: string 782 | format: date-time 783 | versionLabel: 784 | type: string 785 | versionComment: 786 | type: string 787 | SearchEntry: 788 | type: object 789 | properties: 790 | score: 791 | description: The score for this row 792 | type: number 793 | format: float 794 | highlight: 795 | description: | 796 | Highlight fragments if requested and available. A match can happen in any of the requested field. 797 | type: array 798 | items: 799 | type: object 800 | properties: 801 | field: 802 | description: The field where a match occured (one of the fields defined on the request) 803 | type: string 804 | snippets: 805 | description: Any number of snippets for the specified field highlighting the matching text 806 | type: array 807 | items: 808 | description: The highlighted fragment for the field. 809 | type: string 810 | 811 | ## Standard definition 812 | Node: 813 | type: object 814 | required: 815 | - id 816 | - name 817 | - nodeType 818 | - isFolder 819 | - isFile 820 | - createdAt 821 | - createdByUser 822 | - modifiedAt 823 | - modifiedByUser 824 | properties: 825 | id: 826 | type: string 827 | name: 828 | type: string 829 | pattern: "^(?!(.*[\\\"\\*\\\\\\>\\<\\?\\/\\:\\|]+.*)|(.*[\\.]?.*[\\.]+$)|(.*[ ]+$))" 830 | description: | 831 | The name must not contain spaces or the following special characters: * " `<` `>` \ / ? : and |. 832 | The character . must not be used at the end of the name. 833 | nodeType: 834 | type: string 835 | isFolder: 836 | type: boolean 837 | isFile: 838 | type: boolean 839 | isLocked: 840 | type: boolean 841 | default: false 842 | modifiedAt: 843 | type: string 844 | format: date-time 845 | modifiedByUser: 846 | $ref: '#/definitions/UserInfo' 847 | createdAt: 848 | type: string 849 | format: date-time 850 | createdByUser: 851 | $ref: '#/definitions/UserInfo' 852 | parentId: 853 | type: string 854 | isLink: 855 | type: boolean 856 | content: 857 | $ref: '#/definitions/ContentInfo' 858 | aspectNames: 859 | type: array 860 | items: 861 | type: string 862 | properties: 863 | type: object 864 | allowableOperations: 865 | type: array 866 | items: 867 | type: string 868 | path: 869 | $ref: '#/definitions/PathInfo' 870 | isFavorite: 871 | type: boolean 872 | ## Standard definition 873 | UserInfo: 874 | type: object 875 | required: 876 | - displayName 877 | - id 878 | properties: 879 | displayName: 880 | type: string 881 | id: 882 | type: string 883 | 884 | ## Standard definition 885 | ContentInfo: 886 | type: object 887 | required: 888 | - mimeType 889 | - mimeTypeName 890 | - sizeInBytes 891 | properties: 892 | mimeType: 893 | type: string 894 | mimeTypeName: 895 | type: string 896 | sizeInBytes: 897 | type: integer 898 | encoding: 899 | type: string 900 | mimeTypeGroup: 901 | type: string 902 | 903 | ## Standard definition 904 | PathElement: 905 | type: object 906 | properties: 907 | id: 908 | type: string 909 | name: 910 | type: string 911 | 912 | ## Standard definition 913 | PathInfo: 914 | type: object 915 | properties: 916 | elements: 917 | type: array 918 | items: 919 | $ref: '#/definitions/PathElement' 920 | name: 921 | type: string 922 | isComplete: 923 | type: boolean 924 | 925 | RequestDefaults: 926 | description: Common query defaults 927 | type: object 928 | properties: 929 | textAttributes: 930 | description: | 931 | A list of query fields/properties used to expand TEXT: queries. 932 | The default is cm:content. 933 | You could include all content properties using d:content or list all individual content properties or types. 934 | As more terms are included the query size, complexity, memory impact and query time will increase. 935 | type: array 936 | items: 937 | type: string 938 | default: cm:content 939 | defaultFTSOperator: 940 | description: | 941 | The default way to combine query parts when AND or OR is not explicitly stated - includes ! - + 942 | one two three 943 | (one two three) 944 | type: string 945 | default: AND 946 | enum: 947 | - AND 948 | - OR 949 | defaultFTSFieldOperator: 950 | description: | 951 | The default way to combine query parts in field query groups when AND or OR is not explicitly stated - includes ! - + 952 | FIELD:(one two three) 953 | type: string 954 | default: AND 955 | enum: 956 | - AND 957 | - OR 958 | namespace: 959 | description: The default name space to use if one is not provided 960 | type: string 961 | default: cm 962 | defaultFieldName: 963 | type: string 964 | default: TEXT 965 | RequestTemplates: 966 | description: | 967 | Templates usewd for query expansion. 968 | A template called "WOOF" defined as "%(cm:name cm:title)" allows 969 | WOOF:example 970 | to generate 971 | cm:name:example cm:name:example 972 | type: array 973 | items: 974 | type: object 975 | properties: 976 | name: 977 | description: The template name 978 | type: string 979 | template: 980 | description: The template 981 | type: string 982 | RequestScope: 983 | description: Scope 984 | type: object 985 | properties: 986 | locations: 987 | description: | 988 | The locations to include in the query 989 | type: string 990 | enum: 991 | - nodes 992 | - versions 993 | - deleted-nodes 994 | RequestPagination: 995 | type: object 996 | properties: 997 | maxItems: 998 | description: The maximum number of items to return in the query results 999 | type: integer 1000 | minimum: 1 1001 | default: 100 1002 | skipCount: 1003 | description: The number of items to skip from the start of the query set 1004 | type: integer 1005 | minimum: 0 1006 | default: 0 1007 | Pagination: 1008 | type: object 1009 | required: 1010 | - count 1011 | - hasMoreItems 1012 | - skipCount 1013 | - maxItems 1014 | properties: 1015 | count: 1016 | type: integer 1017 | format: int64 1018 | description: | 1019 | The number of objects in the entries array. 1020 | hasMoreItems: 1021 | type: boolean 1022 | description: | 1023 | A boolean value which is **true** if there are more entities in the collection 1024 | beyond those in this response. A true value means a request with a larger value 1025 | for the **skipCount** or the **maxItems** parameter will return more entities. 1026 | totalItems: 1027 | type: integer 1028 | format: int64 1029 | description: | 1030 | An integer describing the total number of entities in the collection. 1031 | The API might not be able to determine this value, 1032 | in which case this property will not be present. 1033 | skipCount: 1034 | type: integer 1035 | format: int64 1036 | description: | 1037 | An integer describing how many entities exist in the collection before 1038 | those included in this list. 1039 | maxItems: 1040 | type: integer 1041 | format: int64 1042 | description: | 1043 | The value of the **maxItems** parameter used to generate this list, 1044 | or if there was no **maxItems** parameter the default value is 100 1045 | ResponseConsistency: 1046 | description: The consistency state of the index used to execute the query 1047 | type: object 1048 | properties: 1049 | lastTxId: 1050 | description: The id of the last indexed transaction 1051 | type: integer 1052 | RequestFacetQueries: 1053 | description: Facet queries to include 1054 | type: array 1055 | items: 1056 | type: object 1057 | properties: 1058 | query: 1059 | description: A facet query 1060 | type: string 1061 | label: 1062 | description: A label to include in place of the facet query 1063 | type: string 1064 | 1065 | RequestFacetFields: 1066 | description: | 1067 | Simple facet fields to include 1068 | The Properties reflect the global properties related to field facts in SOLR. 1069 | They are descripbed in detail by the SOLR documentation 1070 | type: object 1071 | properties: 1072 | facets: 1073 | description: | 1074 | Define specifc fields on which to facet (adds SOLR facet.field and f.field.facet.* options) 1075 | type: array 1076 | items: 1077 | $ref: '#/definitions/RequestFacetField' 1078 | RequestFacetField: 1079 | description: A simple facet field 1080 | type: object 1081 | properties: 1082 | field: 1083 | description: The facet field 1084 | type: string 1085 | label: 1086 | description: A label to include in place of the facet field 1087 | type: string 1088 | prefix: 1089 | description: Restricts the possible constraints to only indexed values with a specified prefix. 1090 | type: string 1091 | sort: 1092 | type: string 1093 | enum: 1094 | - COUNT 1095 | - INDEX 1096 | method: 1097 | type: string 1098 | enum: 1099 | - ENUM 1100 | - FC 1101 | missing: 1102 | description: When true, count results that match the query but which have no facet value for the field (in addition to the Term-based constraints). 1103 | type: boolean 1104 | default: false 1105 | limit: 1106 | type: integer 1107 | offset: 1108 | type: integer 1109 | mincount: 1110 | type: integer 1111 | description: The minimum count required for a facet field to be included in the response. 1112 | default: 1 1113 | facetEnumCacheMinDf: 1114 | type: integer 1115 | excludeFilters: 1116 | description: | 1117 | Filter Queries with tags listed here will not be included in facet counts. 1118 | This is used for multi-select facetting. 1119 | type: array 1120 | items: 1121 | type: string 1122 | RequestLimits: 1123 | description: Limit the time and resources used for query execution 1124 | type: object 1125 | properties: 1126 | permissionEvaluationTime: 1127 | description: Maximum time for post query permission evaluation 1128 | type: integer 1129 | default: 20000 1130 | permissionEvaluationCount: 1131 | description: Maximum count of post query permission evaluations 1132 | type: integer 1133 | default: 2000 1134 | RequestFacetIntervals: 1135 | description: Facet Intervals 1136 | type: object 1137 | properties: 1138 | sets: 1139 | description: Sets the intervals for all fields. 1140 | type: array 1141 | items: 1142 | $ref: '#/definitions/RequestFacetSet' 1143 | intervals: 1144 | description: Specifies the fields to facet by interval. 1145 | type : array 1146 | items: 1147 | type: object 1148 | properties: 1149 | field: 1150 | description: The field to facet on 1151 | type: string 1152 | label: 1153 | description: A label to use to identify the field facet 1154 | type: string 1155 | sets: 1156 | description: Sets the intervals for all fields. 1157 | type: array 1158 | items: 1159 | $ref: '#/definitions/RequestFacetSet' 1160 | RequestFacetSet: 1161 | description: The interval to Set 1162 | type: object 1163 | properties: 1164 | label: 1165 | description: A label to use to identify the set 1166 | type: string 1167 | start: 1168 | description: The start of the range 1169 | type: string 1170 | end: 1171 | description: The end of the range 1172 | type: string 1173 | startInclusive: 1174 | description: When true, the set will include values greater or equal to "start" 1175 | type: boolean 1176 | default: true 1177 | endInclusive: 1178 | description: When true, the set will include values less than or equal to "end" 1179 | type: boolean 1180 | default: true 1181 | RequestFilterQueries: 1182 | description: Filter Queries. Constraints that apply to the results set but do not affect the score of each entry. 1183 | type: array 1184 | items: 1185 | type: object 1186 | properties: 1187 | query: 1188 | description: | 1189 | The filter query expression. 1190 | For multi-select facets selected facets must be order together 1191 | type: string 1192 | tags: 1193 | description: Tags used exclude the filters from facet evaluation for multi-select facet support 1194 | type: array 1195 | items: 1196 | type: string 1197 | RequestSortDefinition: 1198 | description: How to sort the rows? An array of sort specifications. The array order defines the ordering precedence. 1199 | type: array 1200 | items: 1201 | type: object 1202 | properties: 1203 | type: 1204 | description: How to order - using a field, when position of the document in the index, score/relevence. 1205 | type: string 1206 | default: FIELD 1207 | enum: 1208 | - FIELD 1209 | - DOCUMENT 1210 | - SCORE 1211 | field: 1212 | description: The name of the field 1213 | type: string 1214 | ascending: 1215 | description: The sort order. (The ordering of nulls is determined by the SOLR configuration) 1216 | type: boolean 1217 | default: false 1218 | 1219 | RequestSpellcheck: 1220 | description: | 1221 | Request that spellcheck fragments to be added to result set rows 1222 | The properties reflect SOLR spellcheck parameters. 1223 | type: object 1224 | properties: 1225 | query: 1226 | type: string 1227 | 1228 | RequestHighlight: 1229 | description: | 1230 | Request that highlight fragments to be added to result set rows 1231 | The properties reflect SOLR highlighting parameters. 1232 | type: object 1233 | properties: 1234 | prefix: 1235 | description: The string used to mark the start of a highlight in a fragment. 1236 | type: string 1237 | postfix: 1238 | description: The string used to mark the end of a highlight in a fragment. 1239 | type: string 1240 | snippetCount: 1241 | description: The maximum number of distinct highlight snippets to return for each highlight field. 1242 | type: integer 1243 | fragmentSize: 1244 | description: The character length of each snippet. 1245 | type: integer 1246 | maxAnalyzedChars: 1247 | description: The number of characters to be considered for highlighting. Matches after this count will not be shown. 1248 | type: integer 1249 | mergeContiguous: 1250 | description: If fragments over lap they can be merged into one larger fragment 1251 | type: boolean 1252 | usePhraseHighlighter: 1253 | description: Should phrases be identified. 1254 | type: boolean 1255 | fields: 1256 | description: The fields to highlight and field specific configuration properties for each field 1257 | type: array 1258 | items: 1259 | type: object 1260 | properties: 1261 | field: 1262 | description: The name of the field to highlight. 1263 | type: string 1264 | snippetCount: 1265 | type: integer 1266 | fragmentSize: 1267 | type: integer 1268 | mergeContiguous: 1269 | type: boolean 1270 | prefix: 1271 | type: string 1272 | postfix: 1273 | type: string 1274 | RequestRange: 1275 | description: Facet range 1276 | type: object 1277 | properties: 1278 | field: 1279 | description: The name of the field to perform range 1280 | type: string 1281 | start: 1282 | description: The start of the range 1283 | type: string 1284 | end: 1285 | description: The end of the range 1286 | type: string 1287 | gap: 1288 | description: Bucket size 1289 | type: string 1290 | hardend: 1291 | description: If true means that the last bucket will end at “end” even if it is less than “gap” wide. 1292 | type: boolean 1293 | other: 1294 | description: before, after, between, non, all 1295 | type: array 1296 | items: 1297 | type: string 1298 | include: 1299 | description: lower, upper, edge, outer, all 1300 | type: array 1301 | items: 1302 | type: string 1303 | label: 1304 | description: A label to include as a pivot reference 1305 | type: string 1306 | excludeFilters: 1307 | description: Filter queries to exclude when calculating statistics 1308 | type: array 1309 | items: 1310 | type: string 1311 | -------------------------------------------------------------------------------- /src/main/webapp/definitions/index.jsp: -------------------------------------------------------------------------------- 1 | <%@ page import="java.io.*" 2 | %><%@ page import="java.util.Arrays" 3 | %><%@ page contentType="application/json;charset=UTF-8" 4 | %><% File jsp = new File(request.getSession().getServletContext().getRealPath(request.getServletPath())); 5 | File dir = jsp.getParentFile(); 6 | String requestPath = request.getRequestURL().substring(0,request.getRequestURL().lastIndexOf("index.jsp")); 7 | File[] list = dir.listFiles(new FilenameFilter() { 8 | @Override 9 | public boolean accept(File dir, String name) { 10 | return name.endsWith(".yaml") || name.endsWith(".json"); 11 | } 12 | }); 13 | %>[<% 14 | for(int i = 0; i < list.length; i++) { 15 | %><%=i!=0?", ":"" %> 16 | "<%=requestPath+list[i].getName()%>"<% 17 | } %> 18 | ] -------------------------------------------------------------------------------- /src/main/webapp/images/logo.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | image/svg+xml -------------------------------------------------------------------------------- /src/main/webapp/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | Alfresco Content Services REST API Explorer 7 | 8 | 9 | 10 | 11 | 12 | 49 | 50 | 51 | 52 |
53 | 54 | 55 | 56 | 85 | 86 | 87 | -------------------------------------------------------------------------------- /src/main/webapp/version.jsp: -------------------------------------------------------------------------------- 1 | <%@ page import="java.io.*" 2 | %><%@ page import="java.util.Map" 3 | %><%@ page import="java.util.jar.Manifest"%><%@ page import="java.util.jar.Attributes"%><%@ page contentType="application/json;charset=UTF-8" 4 | %><% 5 | InputStream inputStream = request.getSession().getServletContext().getResourceAsStream("/META-INF/MANIFEST.MF"); 6 | Manifest manifest = new Manifest(inputStream); 7 | Attributes attributes = manifest.getMainAttributes(); 8 | 9 | %>{<% 10 | for (Map.Entry entry : attributes.entrySet()) { 11 | %>"<%=entry.getKey()%>": "<%=entry.getValue()%>", <% 12 | } 13 | %> "swaggerui-version":"<%=manifest.getAttributes("Libraries").getValue("swaggerui-version")%>" 14 | } -------------------------------------------------------------------------------- /src/test/java/org/alfresco/api/YamlToJson.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2005-2016 Alfresco Software Limited. 3 | * 4 | * This file is part of Alfresco 5 | * 6 | * Alfresco is free software: you can redistribute it and/or modify 7 | * it under the terms of the GNU Lesser General Public License as published by 8 | * the Free Software Foundation, either version 3 of the License, or 9 | * (at your option) any later version. 10 | * 11 | * Alfresco is distributed in the hope that it will be useful, 12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 | * GNU Lesser General Public License for more details. 15 | * 16 | * You should have received a copy of the GNU Lesser General Public License 17 | * along with Alfresco. If not, see . 18 | */ 19 | package org.alfresco.api; 20 | 21 | import io.swagger.models.Swagger; 22 | import io.swagger.parser.SwaggerParser; 23 | import io.swagger.util.Json; 24 | 25 | import java.io.File; 26 | import java.io.IOException; 27 | 28 | /** 29 | * Generates the Json version of the Yaml file 30 | * 31 | * @author Gethin James 32 | */ 33 | public class YamlToJson { 34 | 35 | public static final String JSON_DESTINATION = "/target/api-explorer/definitions/"; 36 | public static final String CORE_DEFINITION = "/src/main/webapp/definitions/alfresco-core.yaml"; 37 | public static final String CORE_JSON_DEFINITION = JSON_DESTINATION + "alfresco-core.json"; 38 | public static final String CORE_DEFINITION_TITLE = "Alfresco Core REST API"; 39 | 40 | public static final String AUTH_DEFINITION = "/src/main/webapp/definitions/alfresco-auth.yaml"; 41 | public static final String AUTH_JSON_DEFINITION = JSON_DESTINATION + "alfresco-auth.json"; 42 | public static final String AUTH_DEFINITION_TITLE = "Alfresco Authentication REST API"; 43 | 44 | public static final String WORKFLOW_DEFINITION = "/src/main/webapp/definitions/alfresco-workflow.yaml"; 45 | public static final String WORKFLOW_JSON_DEFINITION = JSON_DESTINATION + "alfresco-workflow.json"; 46 | public static final String WORKFLOW_DEFINITION_TITLE = "Alfresco Workflow REST API"; 47 | 48 | public static final String SEARCH_DEFINITION = "/src/main/webapp/definitions/alfresco-search.yaml"; 49 | public static final String SEARCH_JSON_DEFINITION = JSON_DESTINATION + "alfresco-search.json"; 50 | public static final String SEARCH_DEFINITION_TITLE = "Alfresco Search REST API"; 51 | public static final String SEARCH_SQL_DEFINITION = "/src/main/webapp/definitions/alfresco-search-sql.yaml"; 52 | public static final String SEARCH_SQL_JSON_DEFINITION = JSON_DESTINATION + "alfresco-search-sql.json"; 53 | public static final String SEARCH_SQL_DEFINITION_TITLE = "Alfresco SQL Search REST API"; 54 | 55 | public static final String DISCOVERY_DEFINITION = "/src/main/webapp/definitions/alfresco-discovery.yaml"; 56 | public static final String DISCOVERY_JSON_DEFINITION = JSON_DESTINATION + "alfresco-discovery.json"; 57 | public static final String DISCOVERY_DEFINITION_TITLE = "Alfresco Discovery REST API"; 58 | 59 | public static final String MODEL_DEFINITION = "/src/main/webapp/definitions/alfresco-model.yaml"; 60 | public static final String MODEL_JSON_DEFINITION = JSON_DESTINATION + "alfresco-model.json"; 61 | public static final String MODEL_DEFINITION_TITLE = "Alfresco Model REST API"; 62 | 63 | public static void main(String[] args) { 64 | 65 | String rootPath = args[0]; 66 | 67 | try { 68 | 69 | //Create destination dir 70 | new File(rootPath + JSON_DESTINATION).mkdirs(); 71 | 72 | //Core 73 | Swagger swagger = parseSwaggerDef(new File(rootPath + CORE_DEFINITION), CORE_DEFINITION_TITLE); 74 | Json.mapper().writeValue(new File(rootPath + CORE_JSON_DEFINITION), swagger); 75 | 76 | //Authentication 77 | swagger = parseSwaggerDef(new File(rootPath + AUTH_DEFINITION), AUTH_DEFINITION_TITLE); 78 | Json.mapper().writeValue(new File(rootPath + AUTH_JSON_DEFINITION), swagger); 79 | 80 | //Workflow 81 | swagger = parseSwaggerDef(new File(rootPath + WORKFLOW_DEFINITION), WORKFLOW_DEFINITION_TITLE); 82 | Json.mapper().writeValue(new File(rootPath + WORKFLOW_JSON_DEFINITION), swagger); 83 | 84 | //Search 85 | swagger = parseSwaggerDef(new File(rootPath + SEARCH_DEFINITION), SEARCH_DEFINITION_TITLE); 86 | Json.mapper().writeValue(new File(rootPath + SEARCH_JSON_DEFINITION), swagger); 87 | 88 | //Search SQL 89 | swagger = parseSwaggerDef(new File(rootPath + SEARCH_SQL_DEFINITION), SEARCH_SQL_DEFINITION_TITLE); 90 | Json.mapper().writeValue(new File(rootPath + SEARCH_SQL_JSON_DEFINITION), swagger); 91 | 92 | //Discovery 93 | swagger = parseSwaggerDef(new File(rootPath + DISCOVERY_DEFINITION), DISCOVERY_DEFINITION_TITLE); 94 | Json.mapper().writeValue(new File(rootPath + DISCOVERY_JSON_DEFINITION), swagger); 95 | 96 | //Model 97 | swagger = parseSwaggerDef(new File(rootPath + MODEL_DEFINITION), MODEL_DEFINITION_TITLE); 98 | Json.mapper().writeValue(new File(rootPath + MODEL_JSON_DEFINITION), swagger); 99 | 100 | } catch (IOException e) { 101 | System.err.println("Failed to create a json definitions: " + e.getLocalizedMessage()); 102 | System.exit(1); 103 | } 104 | 105 | } 106 | 107 | protected static Swagger parseSwaggerDef(File coreFile, String title) { 108 | Swagger swagger = new SwaggerParser().read(coreFile.getAbsolutePath()); 109 | assert swagger != null; 110 | assert title.equals(swagger.getInfo().getTitle()); 111 | return swagger; 112 | } 113 | } 114 | -------------------------------------------------------------------------------- /src/test/java/org/alfresco/test/APIExplorerIntegrationTest.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2005-2016 Alfresco Software Limited. 3 | * 4 | * This file is part of Alfresco 5 | * 6 | * Alfresco is free software: you can redistribute it and/or modify 7 | * it under the terms of the GNU Lesser General Public License as published by 8 | * the Free Software Foundation, either version 3 of the License, or 9 | * (at your option) any later version. 10 | * 11 | * Alfresco is distributed in the hope that it will be useful, 12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 | * GNU Lesser General Public License for more details. 15 | * 16 | * You should have received a copy of the GNU Lesser General Public License 17 | * along with Alfresco. If not, see . 18 | */ 19 | package org.alfresco.test; 20 | 21 | import static org.junit.Assert.assertEquals; 22 | import static org.junit.Assert.assertNotNull; 23 | import static org.junit.Assert.assertTrue; 24 | 25 | import com.fasterxml.jackson.core.type.TypeReference; 26 | import io.swagger.models.Path; 27 | import io.swagger.models.Swagger; 28 | import io.swagger.parser.SwaggerParser; 29 | 30 | import java.io.StringWriter; 31 | import java.util.List; 32 | import java.util.Map; 33 | 34 | import io.swagger.util.Json; 35 | import org.apache.commons.io.IOUtils; 36 | import org.apache.http.HttpEntity; 37 | import org.apache.http.client.methods.CloseableHttpResponse; 38 | import org.apache.http.client.methods.HttpGet; 39 | import org.apache.http.impl.client.CloseableHttpClient; 40 | import org.apache.http.impl.client.HttpClients; 41 | import org.apache.http.util.EntityUtils; 42 | import org.junit.Test; 43 | 44 | /** 45 | * Test to verify the API Explorer WAR is functioning correctly. 46 | * 47 | * @author Gavin Cornwell 48 | */ 49 | public class APIExplorerIntegrationTest 50 | { 51 | static final String YAML = ".yaml"; 52 | static final String JSON = ".json"; 53 | 54 | @Test 55 | public void testIndexPage() throws Exception 56 | { 57 | // get index page content 58 | String indexPageContent = this.retrievePageContent("http://localhost:8085/api-explorer", 200); 59 | 60 | // make sure the content is correct 61 | int titleIndex = indexPageContent.indexOf("Alfresco Content Services REST API Explorer"); 62 | assertTrue("Expected to find page title", titleIndex != -1); 63 | } 64 | 65 | @Test 66 | public void testCoreAPIDefinition() throws Exception 67 | { 68 | String coreDefinitionUrl = "http://localhost:8085/api-explorer/definitions/alfresco-core"; 69 | 70 | // get core definition content 71 | String coreDefinitionContent = this.retrievePageContent(coreDefinitionUrl+YAML, 200); 72 | 73 | // make sure the content is correct 74 | int swaggerIndex = coreDefinitionContent.indexOf("swagger:"); 75 | assertTrue("Expected to find 'swagger:'", swaggerIndex != -1); 76 | 77 | int nodeInfoEndpointIndex = coreDefinitionContent.indexOf("'/nodes/{nodeId}':"); 78 | assertTrue("Expected to find '/nodes/{nodeId}':", nodeInfoEndpointIndex != -1); 79 | 80 | int commentsEndpointIndex = coreDefinitionContent.indexOf("'/nodes/{nodeId}/comments':"); 81 | assertTrue("Expected to find '/nodes/{nodeId}/comments':", commentsEndpointIndex != -1); 82 | 83 | int sharedLinksEndpointIndex = coreDefinitionContent.indexOf("'/shared-links':"); 84 | assertTrue("Expected to find '/shared-links':", sharedLinksEndpointIndex != -1); 85 | 86 | // ensure the core API definition can be read and parsed 87 | validateCoreDefn(coreDefinitionUrl+YAML); 88 | validateCoreDefn(coreDefinitionUrl+JSON); 89 | } 90 | 91 | private void validateCoreDefn(String coreDefinitionUrl) { 92 | Swagger swagger = validateSwaggerDef(coreDefinitionUrl, "Alfresco Content Services REST API", "Core API", "1"); 93 | Map paths = swagger.getPaths(); 94 | assertNotNull("Expected to retrieve a map of paths", paths); 95 | assertTrue("Expected to find /nodes/{nodeId} path", paths.containsKey("/nodes/{nodeId}")); 96 | assertTrue("Expected to find /nodes/{nodeId}/comments path", paths.containsKey("/nodes/{nodeId}/comments")); 97 | assertTrue("Expected to find /shared-links path", paths.containsKey("/shared-links")); 98 | } 99 | 100 | 101 | @Test 102 | public void testAuthAPIDefinition() throws Exception { 103 | String definitionUrl = "http://localhost:8085/api-explorer/definitions/alfresco-auth"; 104 | 105 | // get definition content 106 | String definitionContent = this.retrievePageContent(definitionUrl + YAML, 200); 107 | // make sure the content is correct 108 | int swaggerIndex = definitionContent.indexOf("swagger:"); 109 | assertTrue("Expected to find 'swagger:'", swaggerIndex != -1); 110 | 111 | validateAuthDefn(definitionUrl + YAML); 112 | validateAuthDefn(definitionUrl + JSON); 113 | } 114 | 115 | @Test 116 | public void testSearchAPIDefinition() throws Exception { 117 | String definitionUrl = "http://localhost:8085/api-explorer/definitions/alfresco-search"; 118 | 119 | // get definition content 120 | String definitionContent = this.retrievePageContent(definitionUrl + YAML, 200); 121 | 122 | // make sure the content is correct 123 | int swaggerIndex = definitionContent.indexOf("swagger:"); 124 | assertTrue("Expected to find 'swagger:'", swaggerIndex != -1); 125 | 126 | validateSearchDefn(definitionUrl + YAML); 127 | validateSearchDefn(definitionUrl + JSON); 128 | } 129 | @Test 130 | public void testSearchSQLAPIDefinition() throws Exception { 131 | String definitionUrl = "http://localhost:8085/api-explorer/definitions/alfresco-search-sql"; 132 | 133 | // get definition content 134 | String definitionContent = this.retrievePageContent(definitionUrl + YAML, 200); 135 | 136 | // make sure the content is correct 137 | int swaggerIndex = definitionContent.indexOf("swagger:"); 138 | assertTrue("Expected to find 'swagger:'", swaggerIndex != -1); 139 | 140 | validateSearchSQLDefn(definitionUrl + YAML); 141 | validateSearchSQLDefn(definitionUrl + JSON); 142 | } 143 | 144 | private void validateAuthDefn(String definitionUrl) { 145 | Swagger swagger = validateSwaggerDef(definitionUrl, "Alfresco Content Services REST API", "Authentication API", "1"); 146 | Map paths = swagger.getPaths(); 147 | assertNotNull("Expected to retrieve a map of paths", paths); 148 | assertTrue("Expected to find /tickets path", paths.containsKey("/tickets")); 149 | } 150 | 151 | @Test 152 | public void testWorkflowAPIDefinition() throws Exception 153 | { 154 | String workflowDefinitionUrl = "http://localhost:8085/api-explorer/definitions/alfresco-workflow"; 155 | 156 | // get workflow definition content 157 | String workflowDefinitionContent = this.retrievePageContent(workflowDefinitionUrl+YAML, 200); 158 | 159 | // make sure the content is correct 160 | int swaggerIndex = workflowDefinitionContent.indexOf("swagger:"); 161 | assertTrue("Expected to find 'swagger:'", swaggerIndex != -1); 162 | 163 | int deploymentEndpointIndex = workflowDefinitionContent.indexOf("'/deployments/{deploymentId}':"); 164 | assertTrue("Expected to find ''/deployments/{deploymentId}':", deploymentEndpointIndex != -1); 165 | 166 | // ensure the workflow API definition can be read and parsed 167 | validateWorkflow(workflowDefinitionUrl+YAML); 168 | validateWorkflow(workflowDefinitionUrl+JSON); 169 | } 170 | 171 | private void validateWorkflow(String workflowDefinitionUrl) { 172 | Swagger swagger = validateSwaggerDef(workflowDefinitionUrl, "Alfresco Content Services REST API", "Workflow API", "1"); 173 | Map paths = swagger.getPaths(); 174 | assertNotNull("Expected to retrieve a map of paths", paths); 175 | assertTrue("Expected to find /deployments/{deploymentId} path", paths.containsKey("/deployments/{deploymentId}")); 176 | } 177 | 178 | private void validateSearchDefn(String definitionUrl) { 179 | Swagger swagger = validateSwaggerDef(definitionUrl, "Alfresco Content Services REST API", "Search API", "1"); 180 | Map paths = swagger.getPaths(); 181 | assertNotNull("Expected to retrieve a map of paths", paths); 182 | assertTrue("Expected to find /search path", paths.containsKey("/search")); 183 | } 184 | 185 | private void validateSearchSQLDefn(String definitionUrl) { 186 | Swagger swagger = validateSwaggerDef(definitionUrl, "Alfresco Insight Engine REST API", "Search SQL API", "1"); 187 | Map paths = swagger.getPaths(); 188 | System.out.println(paths); 189 | assertNotNull("Expected to retrieve a map of paths", paths); 190 | assertTrue("Expected to find /sql path", paths.containsKey("/sql")); 191 | } 192 | 193 | @Test 194 | public void testDiscoveryAPIDefinition() throws Exception { 195 | String definitionUrl = "http://localhost:8085/api-explorer/definitions/alfresco-discovery"; 196 | 197 | // get definition content 198 | String definitionContent = this.retrievePageContent(definitionUrl + YAML, 200); 199 | 200 | // make sure the content is correct 201 | int swaggerIndex = definitionContent.indexOf("swagger:"); 202 | assertTrue("Expected to find 'swagger:'", swaggerIndex != -1); 203 | 204 | validateDiscoveryDefn(definitionUrl + YAML); 205 | validateDiscoveryDefn(definitionUrl + JSON); 206 | } 207 | 208 | private void validateDiscoveryDefn(String definitionUrl) { 209 | Swagger swagger = validateSwaggerDef(definitionUrl, "Alfresco Content Services REST API", "Discovery API", "1"); 210 | Map paths = swagger.getPaths(); 211 | assertNotNull("Expected to retrieve a map of paths", paths); 212 | assertTrue("Expected to find /discovery path", paths.containsKey("/discovery")); 213 | } 214 | 215 | @Test 216 | public void testModelDefinition() throws Exception { 217 | String definitionUrl = "http://localhost:8085/api-explorer/definitions/alfresco-model"; 218 | 219 | // get definition content 220 | String definitionContent = this.retrievePageContent(definitionUrl + YAML, 200); 221 | 222 | // make sure the content is correct 223 | int swaggerIndex = definitionContent.indexOf("swagger:"); 224 | assertTrue("Expected to find 'swagger:'", swaggerIndex != -1); 225 | 226 | validateModelDefn(definitionUrl + YAML); 227 | validateModelDefn(definitionUrl + JSON); 228 | } 229 | 230 | private void validateModelDefn(String definitionUrl) { 231 | Swagger swagger = validateSwaggerDef(definitionUrl, "Alfresco Content Services REST API", "Model API", "1"); 232 | Map paths = swagger.getPaths(); 233 | assertNotNull("Expected to retrieve a map of paths", paths); 234 | assertTrue("Expected to find /aspects path", paths.containsKey("/aspects")); 235 | } 236 | 237 | private Swagger validateSwaggerDef(String definitionUrl, String title, String description, String version) { 238 | Swagger swagger = new SwaggerParser().read(definitionUrl); 239 | assertNotNull("Expected the API definition to parse successfully: "+ definitionUrl, swagger); 240 | assertEquals("Incorrect title", title, swagger.getInfo().getTitle()); 241 | assertTrue("Expected description to contain: " + description, swagger.getInfo().getDescription().indexOf(description) != -1); 242 | assertEquals("Incorrect version", version, swagger.getInfo().getVersion()); 243 | return swagger; 244 | } 245 | 246 | @Test 247 | public void testAllDefinitions() throws Exception 248 | { 249 | String defs = this.retrievePageContent("http://localhost:8085/api-explorer/definitions/index.jsp", 200); 250 | List definitions = Json.mapper().readValue(defs, new TypeReference>(){}); 251 | assertNotNull(definitions); 252 | assertEquals("7 definitions in 2 formats should be 14.", 14, definitions.size()); 253 | } 254 | 255 | public String retrievePageContent(String url, int expectedStatus) throws Exception 256 | { 257 | String pageContent = null; 258 | 259 | CloseableHttpClient httpclient = HttpClients.createDefault(); 260 | try 261 | { 262 | HttpGet httpGet = new HttpGet(url); 263 | CloseableHttpResponse response = httpclient.execute(httpGet); 264 | try 265 | { 266 | // make sure the status was as expected 267 | int actualStatus = response.getStatusLine().getStatusCode(); 268 | assertEquals("Expected status code of " + expectedStatus + " but received " + actualStatus, 269 | expectedStatus, actualStatus); 270 | 271 | // grab the page content 272 | HttpEntity entity = response.getEntity(); 273 | StringWriter writer = new StringWriter(); 274 | IOUtils.copy(entity.getContent(), writer, "UTF-8"); 275 | pageContent = writer.toString(); 276 | 277 | // ensure it is fully consumed 278 | EntityUtils.consume(entity); 279 | } 280 | finally 281 | { 282 | response.close(); 283 | } 284 | } 285 | finally 286 | { 287 | httpclient.close(); 288 | } 289 | 290 | // make sure we got some content 291 | assertNotNull("Expected content from the index page", pageContent); 292 | 293 | return pageContent; 294 | } 295 | } 296 | --------------------------------------------------------------------------------