This is an automated email from the ASF dual-hosted git repository. onichols pushed a commit to branch support/1.15 in repository https://gitbox.apache.org/repos/asf/geode.git
The following commit(s) were added to refs/heads/support/1.15 by this push: new 41305de140 GEODE-10282: Migrate from springfox to springdoc (#7659) 41305de140 is described below commit 41305de1405c2125142e6b337c3f1704f736fca4 Author: Patrick Johnson <jpatr...@vmware.com> AuthorDate: Tue May 10 11:25:20 2022 -0700 GEODE-10282: Migrate from springfox to springdoc (#7659) springfox swagger is no longer maintained, so springdoc is the best choice going forward. (cherry picked from commit 9fbd35a8f9816d4c9baf98d7fec38c5850686177) --- .../src/test/resources/expected-pom.xml | 15 +-- .../gradle/plugins/DependencyConstraints.groovy | 7 +- dev-tools/dependencies/bump.sh | 2 +- geode-assembly/build.gradle | 8 +- .../management/JQFilterVerificationDUnitTest.java | 20 ++-- ...aggerManagementVerificationIntegrationTest.java | 2 +- .../DevRestSwaggerVerificationIntegrationTest.java | 2 +- .../integrationTest/resources/assembly_content.txt | 2 +- .../integrationTest/resources/expected_jars.txt | 33 +++--- .../resources/gfsh_dependency_classpath.txt | 2 +- geode-core/build.gradle | 2 +- geode-core/src/test/resources/expected-pom.xml | 2 +- .../geode-deployment-legacy/build.gradle | 4 +- geode-gfsh/build.gradle | 3 +- geode-gfsh/src/test/resources/expected-pom.xml | 2 +- geode-management/build.gradle | 4 +- .../geode/management/configuration/Deployment.java | 8 +- geode-server-all/build.gradle | 2 +- .../resources/dependency_classpath.txt | 2 +- .../src/test/resources/expected-pom.xml | 2 +- geode-web-api/build.gradle | 9 +- .../web/controllers/CommonCrudController.java | 78 ++++++------- .../web/controllers/FunctionAccessController.java | 38 +++---- .../web/controllers/PdxBasedCrudController.java | 122 ++++++++++----------- .../web/controllers/QueryAccessController.java | 93 ++++++++-------- .../web/security/RestSecurityConfiguration.java | 6 +- .../internal/web/swagger/config/SwaggerConfig.java | 54 ++++----- .../src/main/resources/swagger.properties | 3 +- .../src/main/webapp/WEB-INF/geode-servlet.xml | 1 + geode-web-management/build.gradle | 8 +- .../DeploymentManagementController.java | 23 ++-- .../rest/controllers/DiskStoreController.java | 24 ++-- .../rest/controllers/DocLinksController.java | 4 +- .../controllers/GatewayManagementController.java | 18 +-- .../controllers/MemberManagementController.java | 10 +- .../rest/controllers/PdxManagementController.java | 24 ++-- .../rest/controllers/PingManagementController.java | 5 +- .../controllers/RebalanceOperationController.java | 8 +- .../controllers/RegionManagementController.java | 47 ++++---- .../RestoreRedundancyOperationController.java | 8 +- .../rest/security/RestSecurityConfiguration.java | 6 +- .../internal/rest/swagger/SwaggerConfig.java | 70 ++++++------ .../main/resources/swagger-management.properties | 3 +- .../src/main/webapp/WEB-INF/management-servlet.xml | 1 + 44 files changed, 379 insertions(+), 408 deletions(-) diff --git a/boms/geode-all-bom/src/test/resources/expected-pom.xml b/boms/geode-all-bom/src/test/resources/expected-pom.xml index 6007d1d0ed..cbe85e3ec8 100644 --- a/boms/geode-all-bom/src/test/resources/expected-pom.xml +++ b/boms/geode-all-bom/src/test/resources/expected-pom.xml @@ -198,9 +198,9 @@ <version>1.8.5</version> </dependency> <dependency> - <groupId>io.swagger</groupId> + <groupId>io.swagger.core.v3</groupId> <artifactId>swagger-annotations</artifactId> - <version>1.6.6</version> + <version>2.2.0</version> </dependency> <dependency> <groupId>it.unimi.dsi</groupId> @@ -513,14 +513,9 @@ <version>1.0</version> </dependency> <dependency> - <groupId>io.springfox</groupId> - <artifactId>springfox-swagger-ui</artifactId> - <version>2.9.2</version> - </dependency> - <dependency> - <groupId>io.springfox</groupId> - <artifactId>springfox-swagger2</artifactId> - <version>2.9.2</version> + <groupId>org.springdoc</groupId> + <artifactId>springdoc-openapi-ui</artifactId> + <version>1.6.8</version> </dependency> <dependency> <groupId>mx4j</groupId> diff --git a/build-tools/geode-dependency-management/src/main/groovy/org/apache/geode/gradle/plugins/DependencyConstraints.groovy b/build-tools/geode-dependency-management/src/main/groovy/org/apache/geode/gradle/plugins/DependencyConstraints.groovy index fdd38a564c..9b097f2b71 100644 --- a/build-tools/geode-dependency-management/src/main/groovy/org/apache/geode/gradle/plugins/DependencyConstraints.groovy +++ b/build-tools/geode-dependency-management/src/main/groovy/org/apache/geode/gradle/plugins/DependencyConstraints.groovy @@ -119,7 +119,7 @@ class DependencyConstraints { api(group: 'io.github.resilience4j', name: 'resilience4j-retry', version: '1.7.1') api(group: 'io.lettuce', name: 'lettuce-core', version: '6.1.8.RELEASE') api(group: 'io.micrometer', name: 'micrometer-core', version: get('micrometer.version')) - api(group: 'io.swagger', name: 'swagger-annotations', version: '1.6.6') + api(group: 'io.swagger.core.v3', name: 'swagger-annotations', version: '2.2.0') api(group: 'it.unimi.dsi', name: 'fastutil', version: get('fastutil.version')) api(group: 'javax.annotation', name: 'javax.annotation-api', version: '1.3.2') api(group: 'javax.annotation', name: 'jsr250-api', version: '1.0') @@ -203,9 +203,8 @@ class DependencyConstraints { entry('junit-quickcheck-generators') } - dependencySet(group: 'io.springfox', version: '2.9.2') { - entry('springfox-swagger-ui') - entry('springfox-swagger2') + dependencySet(group: 'org.springdoc', version: '1.6.8') { + entry('springdoc-openapi-ui') } dependencySet(group: 'mx4j', version: '3.0.2') { diff --git a/dev-tools/dependencies/bump.sh b/dev-tools/dependencies/bump.sh index ad86edde4c..23e1a90352 100755 --- a/dev-tools/dependencies/bump.sh +++ b/dev-tools/dependencies/bump.sh @@ -26,7 +26,7 @@ if [ "$2" = "-l" ] ; then find . | grep build/dependencyUpdates/report.txt | xargs rm -f ./gradlew dependencyUpdates -Drevision=release find . | grep build/dependencyUpdates/report.txt | xargs cat \ - | grep ' -> ' | egrep -v '(Gradle|antlr|lucene|JUnitParams|docker-compose-rule|javax.servlet-api|springfox|derby|selenium|jgroups|jmh|\[6.0.37|commons-collections|jaxb|testcontainers|gradle-tooling-api|slf4j|archunit)' \ + | grep ' -> ' | egrep -v '(Gradle|antlr|lucene|JUnitParams|docker-compose-rule|javax.servlet-api|derby|selenium|jgroups|jmh|\[6.0.37|commons-collections|jaxb|testcontainers|gradle-tooling-api|slf4j|archunit)' \ | sort -u | tr -d '][' | sed -e 's/ -> / /' -e 's#.*:#'"$0 $1"' #' echo "cd .. ; geode/dev-tools/release/license_review.sh -v HEAD && echo ':)' || echo 'ERROR(S) WERE FOUND, SEE ABOVE' ; cd $(pwd)" echo "#Also: manually check for newer version of plugins listed in build.gradle (search on https://plugins.gradle.org/)" diff --git a/geode-assembly/build.gradle b/geode-assembly/build.gradle index 0740174703..78f1f5e377 100755 --- a/geode-assembly/build.gradle +++ b/geode-assembly/build.gradle @@ -198,13 +198,13 @@ dependencies { integrationTestImplementation('javax.servlet:javax.servlet-api') - integrationTestRuntimeOnly('io.swagger:swagger-annotations') + integrationTestRuntimeOnly('io.swagger.core.v3:swagger-annotations') // these two modules are for testing only integrationTestRuntimeOnly('com.fasterxml.jackson.datatype:jackson-datatype-joda') integrationTestRuntimeOnly('joda-time:joda-time') distributedTestCompileOnly(platform(project(':boms:geode-all-bom'))) - distributedTestCompileOnly('io.swagger:swagger-annotations') + distributedTestCompileOnly('io.swagger.core.v3:swagger-annotations') distributedTestImplementation(project(':geode-gfsh')) distributedTestImplementation(project(':geode-logging')) distributedTestImplementation(project(':geode-membership')) @@ -231,7 +231,7 @@ dependencies { } distributedTestImplementation('org.codehaus.cargo:cargo-core-uberjar') - distributedTestRuntimeOnly('io.swagger:swagger-annotations') + distributedTestRuntimeOnly('io.swagger.core.v3:swagger-annotations') distributedTestRuntimeOnly(project(':geode-wan')) acceptanceTestImplementation(project(':geode-server-all')) @@ -272,7 +272,7 @@ dependencies { upgradeTestImplementation('org.apache.httpcomponents:httpclient') upgradeTestCompileOnly(platform(project(':boms:geode-all-bom'))) - upgradeTestCompileOnly('io.swagger:swagger-annotations') + upgradeTestCompileOnly('io.swagger.core.v3:swagger-annotations') upgradeTestRuntimeOnly(project(path: ':geode-old-versions', configuration: 'classpathsOutput')) upgradeTestRuntimeOnly(project(':extensions:session-testing-war')) upgradeTestRuntimeOnly('org.codehaus.cargo:cargo-core-uberjar') diff --git a/geode-assembly/src/distributedTest/java/org/apache/geode/management/JQFilterVerificationDUnitTest.java b/geode-assembly/src/distributedTest/java/org/apache/geode/management/JQFilterVerificationDUnitTest.java index a6b9d69646..5312d97771 100644 --- a/geode-assembly/src/distributedTest/java/org/apache/geode/management/JQFilterVerificationDUnitTest.java +++ b/geode-assembly/src/distributedTest/java/org/apache/geode/management/JQFilterVerificationDUnitTest.java @@ -104,7 +104,7 @@ public class JQFilterVerificationDUnitTest { while (methods.hasNext()) { Map.Entry<String, JsonNode> method = methods.next(); // gather all the rest endpoint that has jqFilter defined. - if (method.getValue().get("jqFilter") != null) { + if (method.getValue().get("x-jqFilter") != null) { apiWithJQFilters.put(url.getKey(), method.getValue()); } } @@ -123,7 +123,7 @@ public class JQFilterVerificationDUnitTest { public void getMembers() throws IOException { String uri = "/v1/members"; JqResponse response = - getJqResponse(uri, apiWithJQFilters.remove(uri).get("jqFilter").textValue()); + getJqResponse(uri, apiWithJQFilters.remove(uri).get("x-jqFilter").textValue()); Assertions.assertThat(response.hasErrors()).isFalse(); System.out.println("JQ output: " + response.getOutput()); Assertions.assertThat(response.getOutput()).contains("\"name\":\"locator-0\""); @@ -133,7 +133,7 @@ public class JQFilterVerificationDUnitTest { public void getMember() throws Exception { String uri = "/v1/members/locator-0"; JqResponse response = getJqResponse(uri, - apiWithJQFilters.remove("/v1/members/{id}").get("jqFilter").textValue()); + apiWithJQFilters.remove("/v1/members/{id}").get("x-jqFilter").textValue()); Assertions.assertThat(response.hasErrors()).isFalse(); System.out.println("JQ output: " + response.getOutput()); Assertions.assertThat(response.getOutput()).contains("\"name\":\"locator-0\""); @@ -143,7 +143,7 @@ public class JQFilterVerificationDUnitTest { public void listRegions() throws Exception { String uri = "/v1/regions"; JqResponse response = - getJqResponse(uri, apiWithJQFilters.remove(uri).get("jqFilter").textValue()); + getJqResponse(uri, apiWithJQFilters.remove(uri).get("x-jqFilter").textValue()); Assertions.assertThat(response.hasErrors()).isFalse(); System.out.println("JQ output: " + response.getOutput()); Assertions.assertThat(response.getOutput()).contains("\"name\":\"regionA\""); @@ -160,7 +160,7 @@ public class JQFilterVerificationDUnitTest { public void getRegion() throws Exception { String uri = "/v1/regions/regionA"; JqResponse response = getJqResponse(uri, - apiWithJQFilters.remove("/v1/regions/{id}").get("jqFilter").textValue()); + apiWithJQFilters.remove("/v1/regions/{id}").get("x-jqFilter").textValue()); Assertions.assertThat(response.hasErrors()).isFalse(); System.out.println("JQ output: " + response.getOutput()); Assertions.assertThat(response.getOutput()).contains("\"name\":\"regionA\""); @@ -170,7 +170,7 @@ public class JQFilterVerificationDUnitTest { public void listIndex() throws Exception { String uri = "/v1/indexes"; JqResponse response = - getJqResponse(uri, apiWithJQFilters.remove(uri).get("jqFilter").textValue()); + getJqResponse(uri, apiWithJQFilters.remove(uri).get("x-jqFilter").textValue()); Assertions.assertThat(response.hasErrors()).isFalse(); System.out.println("JQ output: " + response.getOutput()); Assertions.assertThat(response.getOutput()).contains("\"name\":\"index1\""); @@ -180,7 +180,7 @@ public class JQFilterVerificationDUnitTest { public void listRegionIndex() throws Exception { String uri = "/v1/regions/regionA/indexes"; JqResponse response = getJqResponse(uri, apiWithJQFilters - .remove("/v1/regions/{regionName}/indexes").get("jqFilter").textValue()); + .remove("/v1/regions/{regionName}/indexes").get("x-jqFilter").textValue()); Assertions.assertThat(response.hasErrors()).isFalse(); System.out.println("JQ output: " + response.getOutput()); Assertions.assertThat(response.getOutput()).contains("\"name\":\"index1\""); @@ -190,7 +190,7 @@ public class JQFilterVerificationDUnitTest { public void getIndex() throws Exception { String uri = "/v1/regions/regionA/indexes/index1"; JqResponse response = getJqResponse(uri, apiWithJQFilters - .remove("/v1/regions/{regionName}/indexes/{id}").get("jqFilter").textValue()); + .remove("/v1/regions/{regionName}/indexes/{id}").get("x-jqFilter").textValue()); Assertions.assertThat(response.hasErrors()).isFalse(); System.out.println("JQ output: " + response.getOutput()); Assertions.assertThat(response.getOutput()).contains("\"name\":\"index1\""); @@ -200,7 +200,7 @@ public class JQFilterVerificationDUnitTest { public void listDiskStores() throws Exception { String uri = "/v1/diskstores"; JqResponse response = - getJqResponse(uri, apiWithJQFilters.remove(uri).get("jqFilter").textValue()); + getJqResponse(uri, apiWithJQFilters.remove(uri).get("x-jqFilter").textValue()); Assertions.assertThat(response.hasErrors()).isFalse(); System.out.println("JQ output: " + response.getOutput()); Assertions.assertThat(response.getOutput()).contains("\"Member\":\"server-1\""); @@ -212,7 +212,7 @@ public class JQFilterVerificationDUnitTest { String uri = "/v1/diskstores/diskstore1"; JqResponse response = getJqResponse(uri, - apiWithJQFilters.remove("/v1/diskstores/{id}").get("jqFilter").textValue()); + apiWithJQFilters.remove("/v1/diskstores/{id}").get("x-jqFilter").textValue()); response.getErrors().forEach(System.out::println); Assertions.assertThat(response.hasErrors()).isFalse(); System.out.println("JQ output: " + response.getOutput()); diff --git a/geode-assembly/src/integrationTest/java/org/apache/geode/management/internal/rest/SwaggerManagementVerificationIntegrationTest.java b/geode-assembly/src/integrationTest/java/org/apache/geode/management/internal/rest/SwaggerManagementVerificationIntegrationTest.java index 627dc59dde..5b13b5b89c 100644 --- a/geode-assembly/src/integrationTest/java/org/apache/geode/management/internal/rest/SwaggerManagementVerificationIntegrationTest.java +++ b/geode-assembly/src/integrationTest/java/org/apache/geode/management/internal/rest/SwaggerManagementVerificationIntegrationTest.java @@ -57,7 +57,7 @@ public class SwaggerManagementVerificationIntegrationTest { JsonNode json = assertResponse(client.get("/management/v1/api-docs")).hasStatusCode(200) .getJsonObject(); - assertThat(json.get("swagger").asText(), is("2.0")); + assertThat(json.get("openapi").asText(), is("3.0.1")); JsonNode info = json.get("info"); assertThat(info.get("description").asText(), diff --git a/geode-assembly/src/integrationTest/java/org/apache/geode/rest/internal/web/DevRestSwaggerVerificationIntegrationTest.java b/geode-assembly/src/integrationTest/java/org/apache/geode/rest/internal/web/DevRestSwaggerVerificationIntegrationTest.java index 3925c63435..beca1aa57a 100644 --- a/geode-assembly/src/integrationTest/java/org/apache/geode/rest/internal/web/DevRestSwaggerVerificationIntegrationTest.java +++ b/geode-assembly/src/integrationTest/java/org/apache/geode/rest/internal/web/DevRestSwaggerVerificationIntegrationTest.java @@ -54,7 +54,7 @@ public class DevRestSwaggerVerificationIntegrationTest { JsonNode json = assertResponse(client.get("/geode/v1/api-docs")).hasStatusCode(200) .getJsonObject(); - assertThat(json.get("swagger").asText(), is("2.0")); + assertThat(json.get("openapi").asText(), is("3.0.1")); JsonNode info = json.get("info"); assertThat(info.get("description").asText(), diff --git a/geode-assembly/src/integrationTest/resources/assembly_content.txt b/geode-assembly/src/integrationTest/resources/assembly_content.txt index cb8917966f..d6d8720dfb 100644 --- a/geode-assembly/src/integrationTest/resources/assembly_content.txt +++ b/geode-assembly/src/integrationTest/resources/assembly_content.txt @@ -1060,7 +1060,7 @@ lib/spring-core-5.3.19.jar lib/spring-jcl-5.3.19.jar lib/spring-shell-1.2.0.RELEASE.jar lib/spring-web-5.3.19.jar -lib/swagger-annotations-1.6.6.jar +lib/swagger-annotations-2.2.0.jar tools/Extensions/geode-web-0.0.0.war tools/Extensions/geode-web-api-0.0.0.war tools/Extensions/geode-web-management-0.0.0.war diff --git a/geode-assembly/src/integrationTest/resources/expected_jars.txt b/geode-assembly/src/integrationTest/resources/expected_jars.txt index 85b202bdea..11d6f45f18 100644 --- a/geode-assembly/src/integrationTest/resources/expected_jars.txt +++ b/geode-assembly/src/integrationTest/resources/expected_jars.txt @@ -4,10 +4,7 @@ LatencyUtils accessors-smart antlr asm -byte-buddy -checker-qual classgraph -classmate commons-beanutils commons-codec commons-collections @@ -20,18 +17,19 @@ commons-modeler commons-text commons-validator content-type -error_prone_annotations -failureaccess fastutil gfsh-dependencies.jar -guava httpclient httpcore istack-commons-runtime -j2objc-annotations jackson-annotations jackson-core jackson-databind +jackson-dataformat-yaml +jackson-datatype-jsr +jakarta.activation-api +jakarta.validation-api +jakarta.xml.bind-api javax.activation-api javax.mail-api javax.resource-api @@ -56,9 +54,7 @@ jna-platform jopt-simple json-path json-smart -jsr lang-tag -listenablefuture log4j-api log4j-core log4j-jcl @@ -69,7 +65,6 @@ lucene-analyzers-phonetic lucene-core lucene-queries lucene-queryparser -mapstruct micrometer-core mx4j mx4j-remote @@ -88,10 +83,13 @@ shiro-crypto-hash shiro-event shiro-lang slf4j-api +snakeyaml snappy spring-aop spring-aspects spring-beans +spring-boot +spring-boot-autoconfigure spring-context spring-core spring-expression @@ -99,8 +97,6 @@ spring-hateoas spring-jcl spring-ldap-core spring-oxm -spring-plugin-core -spring-plugin-metadata spring-security-config spring-security-core spring-security-crypto @@ -113,12 +109,11 @@ spring-shell spring-tx spring-web spring-webmvc -springfox-core -springfox-schema -springfox-spi -springfox-spring-web -springfox-swagger -springfox-swagger-common -springfox-swagger-ui +springdoc-openapi-common +springdoc-openapi-ui +springdoc-openapi-webmvc-core swagger-annotations +swagger-core swagger-models +swagger-ui +webjars-locator-core diff --git a/geode-assembly/src/integrationTest/resources/gfsh_dependency_classpath.txt b/geode-assembly/src/integrationTest/resources/gfsh_dependency_classpath.txt index 327bf666b0..9238a593ae 100644 --- a/geode-assembly/src/integrationTest/resources/gfsh_dependency_classpath.txt +++ b/geode-assembly/src/integrationTest/resources/gfsh_dependency_classpath.txt @@ -24,7 +24,7 @@ rmiio-2.1.2.jar jackson-annotations-2.13.2.jar jackson-core-2.13.2.jar jackson-databind-2.13.2.2.jar -swagger-annotations-1.6.6.jar +swagger-annotations-2.2.0.jar jopt-simple-5.0.4.jar log4j-slf4j-impl-2.17.2.jar log4j-core-2.17.2.jar diff --git a/geode-core/build.gradle b/geode-core/build.gradle index 1126b66892..a63aefa0ae 100755 --- a/geode-core/build.gradle +++ b/geode-core/build.gradle @@ -285,7 +285,7 @@ dependencies { implementation('org.apache.logging.log4j:log4j-api') - implementation('io.swagger:swagger-annotations') { + implementation('io.swagger.core.v3:swagger-annotations') { ext.optional = true } diff --git a/geode-core/src/test/resources/expected-pom.xml b/geode-core/src/test/resources/expected-pom.xml index 4f1d3cd0a0..74187a6805 100644 --- a/geode-core/src/test/resources/expected-pom.xml +++ b/geode-core/src/test/resources/expected-pom.xml @@ -147,7 +147,7 @@ <scope>runtime</scope> </dependency> <dependency> - <groupId>io.swagger</groupId> + <groupId>io.swagger.core.v3</groupId> <artifactId>swagger-annotations</artifactId> <scope>runtime</scope> <optional>true</optional> diff --git a/geode-deployment/geode-deployment-legacy/build.gradle b/geode-deployment/geode-deployment-legacy/build.gradle index b482154ed8..4a64dcc8e9 100644 --- a/geode-deployment/geode-deployment-legacy/build.gradle +++ b/geode-deployment/geode-deployment-legacy/build.gradle @@ -31,10 +31,10 @@ dependencies { compileOnly(project(':geode-common')) compileOnly(project(':geode-logging')) compileOnly('com.fasterxml.jackson.core:jackson-databind') - compileOnly('io.swagger:swagger-annotations') + compileOnly('io.swagger.core.v3:swagger-annotations') - testCompileOnly('io.swagger:swagger-annotations') + testCompileOnly('io.swagger.core.v3:swagger-annotations') testImplementation(project(':geode-core')) testImplementation(project(':geode-common')) testImplementation(project(':geode-junit')) diff --git a/geode-gfsh/build.gradle b/geode-gfsh/build.gradle index fd573fd35b..985dbe46db 100644 --- a/geode-gfsh/build.gradle +++ b/geode-gfsh/build.gradle @@ -38,7 +38,7 @@ dependencies { implementation('org.apache.commons:commons-lang3') implementation('com.healthmarketscience.rmiio:rmiio') implementation('com.fasterxml.jackson.core:jackson-databind') - implementation('io.swagger:swagger-annotations') + implementation('io.swagger.core.v3:swagger-annotations') // //Find bugs is used in multiple places in the code to suppress findbugs warnings testImplementation('com.github.stephenc.findbugs:findbugs-annotations') @@ -56,7 +56,6 @@ dependencies { distributedTestRuntimeOnly('org.apache.derby:derby') testCompileOnly(platform(project(':boms:geode-all-bom'))) - testCompileOnly('io.swagger:swagger-annotations') upgradeTestImplementation(project(':geode-junit')) upgradeTestImplementation(project(':geode-dunit')) diff --git a/geode-gfsh/src/test/resources/expected-pom.xml b/geode-gfsh/src/test/resources/expected-pom.xml index c367815d73..df8b3fadf1 100644 --- a/geode-gfsh/src/test/resources/expected-pom.xml +++ b/geode-gfsh/src/test/resources/expected-pom.xml @@ -142,7 +142,7 @@ <scope>runtime</scope> </dependency> <dependency> - <groupId>io.swagger</groupId> + <groupId>io.swagger.core.v3</groupId> <artifactId>swagger-annotations</artifactId> <scope>runtime</scope> </dependency> diff --git a/geode-management/build.gradle b/geode-management/build.gradle index 8f263ba6c9..32f94873a9 100755 --- a/geode-management/build.gradle +++ b/geode-management/build.gradle @@ -37,7 +37,7 @@ dependencies { compileOnly(project(':geode-common')) { exclude module: 'junit' } - compileOnly('io.springfox:springfox-swagger2') { + compileOnly('org.springdoc:springdoc-openapi-ui') { exclude module: 'slf4j-api' exclude module: "jackson-annotations" } @@ -48,7 +48,7 @@ dependencies { } testCompileOnly(platform(project(':boms:geode-all-bom'))) - testCompileOnly('io.swagger:swagger-annotations') + testCompileOnly('io.swagger.core.v3:swagger-annotations') integrationTestImplementation(project(':geode-dunit')) integrationTestImplementation(project(':geode-junit')) diff --git a/geode-management/src/main/java/org/apache/geode/management/configuration/Deployment.java b/geode-management/src/main/java/org/apache/geode/management/configuration/Deployment.java index a3ecc68ccc..cb1d15e485 100644 --- a/geode-management/src/main/java/org/apache/geode/management/configuration/Deployment.java +++ b/geode-management/src/main/java/org/apache/geode/management/configuration/Deployment.java @@ -15,14 +15,14 @@ package org.apache.geode.management.configuration; -import static io.swagger.annotations.ApiModelProperty.AccessMode.READ_ONLY; +import static io.swagger.v3.oas.annotations.media.Schema.AccessMode.READ_ONLY; import java.io.File; import java.io.IOException; import java.util.Objects; import com.fasterxml.jackson.annotation.JsonIgnore; -import io.swagger.annotations.ApiModelProperty; +import io.swagger.v3.oas.annotations.media.Schema; import org.apache.geode.management.api.CommandType; import org.apache.geode.management.runtime.DeploymentInfo; @@ -31,9 +31,9 @@ public class Deployment extends GroupableConfiguration<DeploymentInfo> implement private static final long serialVersionUID = 6992732279452865384L; public static final String DEPLOYMENT_ENDPOINT = "/deployments"; private String jarFileName; - @ApiModelProperty(accessMode = READ_ONLY) + @Schema(accessMode = READ_ONLY) private String deployedTime; - @ApiModelProperty(accessMode = READ_ONLY) + @Schema(accessMode = READ_ONLY) private String deployedBy; // the file is not serialized over the wire diff --git a/geode-server-all/build.gradle b/geode-server-all/build.gradle index cbe9264cd1..94b525f3ae 100644 --- a/geode-server-all/build.gradle +++ b/geode-server-all/build.gradle @@ -53,7 +53,7 @@ dependencies { // These were ext.optional in geode-core serverNonOptional(project(':geode-http-service')) serverNonOptional('org.iq80.snappy:snappy') - serverNonOptional('io.swagger:swagger-annotations') + serverNonOptional('io.swagger.core.v3:swagger-annotations') integrationTestImplementation(project(':geode-junit')) diff --git a/geode-server-all/src/integrationTest/resources/dependency_classpath.txt b/geode-server-all/src/integrationTest/resources/dependency_classpath.txt index 2b53c964fe..81dd6bfae7 100644 --- a/geode-server-all/src/integrationTest/resources/dependency_classpath.txt +++ b/geode-server-all/src/integrationTest/resources/dependency_classpath.txt @@ -52,7 +52,7 @@ geode-membership-0.0.0.jar jetty-webapp-9.4.46.v20220331.jar commons-lang3-3.12.0.jar jopt-simple-5.0.4.jar -swagger-annotations-1.6.6.jar +swagger-annotations-2.2.0.jar snappy-0.4.jar geode-wan-0.0.0.jar log4j-api-2.17.2.jar diff --git a/geode-server-all/src/test/resources/expected-pom.xml b/geode-server-all/src/test/resources/expected-pom.xml index 45fea7df0e..92a10910b5 100644 --- a/geode-server-all/src/test/resources/expected-pom.xml +++ b/geode-server-all/src/test/resources/expected-pom.xml @@ -137,7 +137,7 @@ <scope>runtime</scope> </dependency> <dependency> - <groupId>io.swagger</groupId> + <groupId>io.swagger.core.v3</groupId> <artifactId>swagger-annotations</artifactId> <scope>runtime</scope> </dependency> diff --git a/geode-web-api/build.gradle b/geode-web-api/build.gradle index 58e156a4d9..dcb46bd7ec 100644 --- a/geode-web-api/build.gradle +++ b/geode-web-api/build.gradle @@ -51,16 +51,9 @@ dependencies { exclude module: 'jackson-annotations' } - compileOnly('io.swagger:swagger-annotations') - - implementation('io.springfox:springfox-swagger2') { + implementation('org.springdoc:springdoc-openapi-ui') { exclude module: 'slf4j-api' exclude module: 'jackson-annotations' - exclude module: 'swagger-annotations' - } - - implementation('io.springfox:springfox-swagger-ui') { - exclude module: 'slf4j-api' } implementation('org.springframework:spring-beans') diff --git a/geode-web-api/src/main/java/org/apache/geode/rest/internal/web/controllers/CommonCrudController.java b/geode-web-api/src/main/java/org/apache/geode/rest/internal/web/controllers/CommonCrudController.java index 57cb759ee2..a51ad05f2f 100644 --- a/geode-web-api/src/main/java/org/apache/geode/rest/internal/web/controllers/CommonCrudController.java +++ b/geode-web-api/src/main/java/org/apache/geode/rest/internal/web/controllers/CommonCrudController.java @@ -19,9 +19,9 @@ import java.util.HashSet; import java.util.List; import java.util.Set; -import io.swagger.annotations.ApiOperation; -import io.swagger.annotations.ApiResponse; -import io.swagger.annotations.ApiResponses; +import io.swagger.v3.oas.annotations.Operation; +import io.swagger.v3.oas.annotations.responses.ApiResponse; +import io.swagger.v3.oas.annotations.responses.ApiResponses; import org.apache.logging.log4j.Logger; import org.springframework.http.HttpHeaders; import org.springframework.http.HttpStatus; @@ -63,12 +63,12 @@ public abstract class CommonCrudController extends AbstractBaseController { * @return JSON document containing result */ @RequestMapping(method = RequestMethod.GET, produces = {APPLICATION_JSON_UTF8_VALUE}) - @ApiOperation(value = "list all resources (Regions)", - notes = "List all available resources (Regions) in the Geode cluster") - @ApiResponses({@ApiResponse(code = 200, message = "OK."), - @ApiResponse(code = 401, message = "Invalid Username or Password."), - @ApiResponse(code = 403, message = "Insufficient privileges for operation."), - @ApiResponse(code = 500, message = "GemFire throws an error or exception.")}) + @Operation(summary = "list all resources (Regions)", + description = "List all available resources (Regions) in the Geode cluster") + @ApiResponses({@ApiResponse(responseCode = "200", description = "OK."), + @ApiResponse(responseCode = "401", description = "Invalid Username or Password."), + @ApiResponse(responseCode = "403", description = "Insufficient privileges for operation."), + @ApiResponse(responseCode = "500", description = "GemFire throws an error or exception.")}) @PreAuthorize("@securityService.authorize('DATA', 'READ')") public ResponseEntity<?> regions() { logger.debug("Listing all resources (Regions) in Geode..."); @@ -90,12 +90,12 @@ public abstract class CommonCrudController extends AbstractBaseController { */ @RequestMapping(method = RequestMethod.GET, value = "/{region}/keys", produces = {APPLICATION_JSON_UTF8_VALUE}) - @ApiOperation(value = "list all keys", notes = "List all keys in region") - @ApiResponses({@ApiResponse(code = 200, message = "OK"), - @ApiResponse(code = 401, message = "Invalid Username or Password."), - @ApiResponse(code = 403, message = "Insufficient privileges for operation."), - @ApiResponse(code = 404, message = "Region does not exist"), - @ApiResponse(code = 500, message = "GemFire throws an error or exception")}) + @Operation(summary = "list all keys", description = "List all keys in region") + @ApiResponses({@ApiResponse(responseCode = "200", description = "OK"), + @ApiResponse(responseCode = "401", description = "Invalid Username or Password."), + @ApiResponse(responseCode = "403", description = "Insufficient privileges for operation."), + @ApiResponse(responseCode = "404", description = "Region does not exist"), + @ApiResponse(responseCode = "500", description = "GemFire throws an error or exception")}) @PreAuthorize("@securityService.authorize('DATA', 'READ', #region)") public ResponseEntity<?> keys(@PathVariable("region") String region) { logger.debug("Reading all Keys in Region ({})...", region); @@ -118,13 +118,13 @@ public abstract class CommonCrudController extends AbstractBaseController { */ @RequestMapping(method = RequestMethod.DELETE, value = "/{region}/{keys}", produces = {APPLICATION_JSON_UTF8_VALUE}) - @ApiOperation(value = "delete data for key(s)", - notes = "Delete data for one or more keys in a region. Deprecated in favor of /{region}?keys=.") - @ApiResponses({@ApiResponse(code = 200, message = "OK"), - @ApiResponse(code = 401, message = "Invalid Username or Password."), - @ApiResponse(code = 403, message = "Insufficient privileges for operation."), - @ApiResponse(code = 404, message = "Region or key(s) does not exist"), - @ApiResponse(code = 500, message = "GemFire throws an error or exception")}) + @Operation(summary = "delete data for key(s)", + description = "Delete data for one or more keys in a region. Deprecated in favor of /{region}?keys=.") + @ApiResponses({@ApiResponse(responseCode = "200", description = "OK"), + @ApiResponse(responseCode = "401", description = "Invalid Username or Password."), + @ApiResponse(responseCode = "403", description = "Insufficient privileges for operation."), + @ApiResponse(responseCode = "404", description = "Region or key(s) does not exist"), + @ApiResponse(responseCode = "500", description = "GemFire throws an error or exception")}) public ResponseEntity<?> delete(@PathVariable("region") String region, @PathVariable("keys") String[] keys) { region = decode(region); @@ -147,13 +147,13 @@ public abstract class CommonCrudController extends AbstractBaseController { * @return JSON document containing result */ @RequestMapping(method = RequestMethod.DELETE, value = "/{region}") - @ApiOperation(value = "delete all data or the specified keys", - notes = "Delete all in the region or just the specified keys") - @ApiResponses({@ApiResponse(code = 200, message = "OK"), - @ApiResponse(code = 401, message = "Invalid Username or Password."), - @ApiResponse(code = 403, message = "Insufficient privileges for operation."), - @ApiResponse(code = 404, message = "Region does not exist"), - @ApiResponse(code = 500, message = "if GemFire throws an error or exception")}) + @Operation(summary = "delete all data or the specified keys", + description = "Delete all in the region or just the specified keys") + @ApiResponses({@ApiResponse(responseCode = "200", description = "OK"), + @ApiResponse(responseCode = "401", description = "Invalid Username or Password."), + @ApiResponse(responseCode = "403", description = "Insufficient privileges for operation."), + @ApiResponse(responseCode = "404", description = "Region does not exist"), + @ApiResponse(responseCode = "500", description = "if GemFire throws an error or exception")}) public ResponseEntity<?> deleteAllOrGivenKeys(@PathVariable("region") String region, @RequestParam(value = "keys", required = false) final String[] encodedKeys) { logger.debug("Deleting all data in Region ({})...", region); @@ -178,22 +178,22 @@ public abstract class CommonCrudController extends AbstractBaseController { * Ping is not secured so that it may not be used to determine a valid username/password */ @RequestMapping(method = {RequestMethod.GET, RequestMethod.HEAD}, value = "/ping") - @ApiOperation(value = "Check Rest service status ", - notes = "Check whether gemfire REST service is up and running!") - @ApiResponses({@ApiResponse(code = 200, message = "OK"), - @ApiResponse(code = 500, message = "if GemFire throws an error or exception")}) + @Operation(summary = "Check Rest service status ", + description = "Check whether gemfire REST service is up and running!") + @ApiResponses({@ApiResponse(responseCode = "200", description = "OK"), + @ApiResponse(responseCode = "500", description = "if GemFire throws an error or exception")}) public ResponseEntity<?> ping() { return new ResponseEntity<>(HttpStatus.OK); } @RequestMapping(method = {RequestMethod.GET}, value = "/servers", produces = {APPLICATION_JSON_UTF8_VALUE}) - @ApiOperation(value = "fetch all REST enabled servers in the DS", - notes = "Find all gemfire node where developer REST service is up and running!") - @ApiResponses({@ApiResponse(code = 200, message = "OK"), - @ApiResponse(code = 401, message = "Invalid Username or Password."), - @ApiResponse(code = 403, message = "Insufficient privileges for operation."), - @ApiResponse(code = 500, message = "if GemFire throws an error or exception")}) + @Operation(summary = "fetch all REST enabled servers in the DS", + description = "Find all gemfire node where developer REST service is up and running!") + @ApiResponses({@ApiResponse(responseCode = "200", description = "OK"), + @ApiResponse(responseCode = "401", description = "Invalid Username or Password."), + @ApiResponse(responseCode = "403", description = "Insufficient privileges for operation."), + @ApiResponse(responseCode = "500", description = "if GemFire throws an error or exception")}) @PreAuthorize("@securityService.authorize('CLUSTER', 'READ')") public ResponseEntity<?> servers() { logger.debug("Executing function to get REST enabled gemfire nodes in the DS!"); diff --git a/geode-web-api/src/main/java/org/apache/geode/rest/internal/web/controllers/FunctionAccessController.java b/geode-web-api/src/main/java/org/apache/geode/rest/internal/web/controllers/FunctionAccessController.java index 538f553d90..dfe7ba35be 100644 --- a/geode-web-api/src/main/java/org/apache/geode/rest/internal/web/controllers/FunctionAccessController.java +++ b/geode-web-api/src/main/java/org/apache/geode/rest/internal/web/controllers/FunctionAccessController.java @@ -20,10 +20,10 @@ import java.util.List; import java.util.Map; import java.util.Set; -import io.swagger.annotations.Api; -import io.swagger.annotations.ApiOperation; -import io.swagger.annotations.ApiResponse; -import io.swagger.annotations.ApiResponses; +import io.swagger.v3.oas.annotations.Operation; +import io.swagger.v3.oas.annotations.responses.ApiResponse; +import io.swagger.v3.oas.annotations.responses.ApiResponses; +import io.swagger.v3.oas.annotations.tags.Tag; import org.apache.logging.log4j.Logger; import org.springframework.http.HttpHeaders; import org.springframework.http.HttpStatus; @@ -60,7 +60,7 @@ import org.apache.geode.security.ResourcePermission; * @since GemFire 8.0 */ @Controller("functionController") -@Api(value = "functions", tags = "functions") +@Tag(name = "functions", description = "functions") @RequestMapping(FunctionAccessController.REST_API_VERSION + "/functions") @SuppressWarnings("unused") public class FunctionAccessController extends AbstractBaseController { @@ -84,12 +84,12 @@ public class FunctionAccessController extends AbstractBaseController { * @return result as a JSON document. */ @RequestMapping(method = RequestMethod.GET, produces = {APPLICATION_JSON_UTF8_VALUE}) - @ApiOperation(value = "list all functions", - notes = "list all functions available in the GemFire cluster") - @ApiResponses({@ApiResponse(code = 200, message = "OK."), - @ApiResponse(code = 401, message = "Invalid Username or Password."), - @ApiResponse(code = 403, message = "Insufficient privileges for operation."), - @ApiResponse(code = 500, message = "GemFire throws an error or exception.")}) + @Operation(summary = "list all functions", + description = "list all functions available in the GemFire cluster") + @ApiResponses({@ApiResponse(responseCode = "200", description = "OK."), + @ApiResponse(responseCode = "401", description = "Invalid Username or Password."), + @ApiResponse(responseCode = "403", description = "Insufficient privileges for operation."), + @ApiResponse(responseCode = "500", description = "GemFire throws an error or exception.")}) @ResponseBody @ResponseStatus(HttpStatus.OK) @PreAuthorize("@securityService.authorize('DATA', 'READ')") @@ -121,14 +121,14 @@ public class FunctionAccessController extends AbstractBaseController { */ @RequestMapping(method = RequestMethod.POST, value = "/{functionId:.+}", produces = {APPLICATION_JSON_UTF8_VALUE}) - @ApiOperation(value = "execute function", - notes = "Execute function with arguments on regions, members, or group(s). By default function will be executed on all nodes if none of (onRegion, onMembers, onGroups) specified") - @ApiResponses({@ApiResponse(code = 200, message = "OK."), - @ApiResponse(code = 401, message = "Invalid Username or Password."), - @ApiResponse(code = 403, message = "Insufficient privileges for operation."), - @ApiResponse(code = 500, message = "if GemFire throws an error or exception"), - @ApiResponse(code = 400, - message = "if Function arguments specified as JSON document in the request body is invalid")}) + @Operation(summary = "execute function", + description = "Execute function with arguments on regions, members, or group(s). By default function will be executed on all nodes if none of (onRegion, onMembers, onGroups) specified") + @ApiResponses({@ApiResponse(responseCode = "200", description = "OK."), + @ApiResponse(responseCode = "401", description = "Invalid Username or Password."), + @ApiResponse(responseCode = "403", description = "Insufficient privileges for operation."), + @ApiResponse(responseCode = "500", description = "if GemFire throws an error or exception"), + @ApiResponse(responseCode = "400", + description = "if Function arguments specified as JSON document in the request body is invalid")}) @ResponseBody @ResponseStatus(HttpStatus.OK) public ResponseEntity<String> execute(@PathVariable("functionId") String functionId, diff --git a/geode-web-api/src/main/java/org/apache/geode/rest/internal/web/controllers/PdxBasedCrudController.java b/geode-web-api/src/main/java/org/apache/geode/rest/internal/web/controllers/PdxBasedCrudController.java index 1c8415c402..8cfa93c2f0 100644 --- a/geode-web-api/src/main/java/org/apache/geode/rest/internal/web/controllers/PdxBasedCrudController.java +++ b/geode-web-api/src/main/java/org/apache/geode/rest/internal/web/controllers/PdxBasedCrudController.java @@ -21,10 +21,10 @@ import java.util.Map; import javax.servlet.http.HttpServletRequest; -import io.swagger.annotations.Api; -import io.swagger.annotations.ApiOperation; -import io.swagger.annotations.ApiResponse; -import io.swagger.annotations.ApiResponses; +import io.swagger.v3.oas.annotations.Operation; +import io.swagger.v3.oas.annotations.responses.ApiResponse; +import io.swagger.v3.oas.annotations.responses.ApiResponses; +import io.swagger.v3.oas.annotations.tags.Tag; import org.apache.logging.log4j.Logger; import org.springframework.http.HttpHeaders; import org.springframework.http.HttpStatus; @@ -54,7 +54,7 @@ import org.apache.geode.rest.internal.web.util.ArrayUtils; * @since GemFire 8.0 */ @Controller("pdxCrudController") -@Api(value = "region", tags = "region") +@Tag(name = "region", description = "region") @RequestMapping(PdxBasedCrudController.REST_API_VERSION) @SuppressWarnings("unused") public class PdxBasedCrudController extends CommonCrudController { @@ -80,16 +80,16 @@ public class PdxBasedCrudController extends CommonCrudController { */ @RequestMapping(method = RequestMethod.POST, value = "/{region}", consumes = APPLICATION_JSON_UTF8_VALUE, produces = {APPLICATION_JSON_UTF8_VALUE}) - @ApiOperation(value = "create entry", notes = "Create (put-if-absent) data in region." + @Operation(summary = "create entry", description = "Create (put-if-absent) data in region." + " The key is not decoded so if the key contains special characters use PUT/{region}?keys=EncodedKey&op=CREATE.") - @ApiResponses({@ApiResponse(code = 201, message = "Created."), - @ApiResponse(code = 400, - message = "Data specified (JSON doc) in the request body is invalid."), - @ApiResponse(code = 401, message = "Invalid Username or Password."), - @ApiResponse(code = 403, message = "Insufficient privileges for operation."), - @ApiResponse(code = 404, message = "Region does not exist."), - @ApiResponse(code = 409, message = "Key already exist in region."), - @ApiResponse(code = 500, message = "GemFire throws an error or exception.")}) + @ApiResponses({@ApiResponse(responseCode = "201", description = "Created."), + @ApiResponse(responseCode = "400", + description = "Data specified (JSON doc) in the request body is invalid."), + @ApiResponse(responseCode = "401", description = "Invalid Username or Password."), + @ApiResponse(responseCode = "403", description = "Insufficient privileges for operation."), + @ApiResponse(responseCode = "404", description = "Region does not exist."), + @ApiResponse(responseCode = "409", description = "Key already exist in region."), + @ApiResponse(responseCode = "500", description = "GemFire throws an error or exception.")}) @PreAuthorize("@securityService.authorize('DATA', 'WRITE', #region)") public ResponseEntity<?> create(@PathVariable("region") String region, @RequestParam(value = "key", required = false) String key, @RequestBody final String json) { @@ -141,15 +141,15 @@ public class PdxBasedCrudController extends CommonCrudController { */ @RequestMapping(method = RequestMethod.GET, value = "/{region}", produces = APPLICATION_JSON_UTF8_VALUE) - @ApiOperation(value = "read all data for region or the specified keys", - notes = "If reading all data for region then the limit parameter can be used to give the maximum number of values to return." + @Operation(summary = "read all data for region or the specified keys", + description = "If reading all data for region then the limit parameter can be used to give the maximum number of values to return." + " If reading specif keys then the ignoredMissingKey parameter can be used to not fail if a key is missing.") - @ApiResponses({@ApiResponse(code = 200, message = "OK."), - @ApiResponse(code = 400, message = "Bad request."), - @ApiResponse(code = 401, message = "Invalid Username or Password."), - @ApiResponse(code = 403, message = "Insufficient privileges for operation."), - @ApiResponse(code = 404, message = "Region does not exist."), - @ApiResponse(code = 500, message = "GemFire throws an error or exception.")}) + @ApiResponses({@ApiResponse(responseCode = "200", description = "OK."), + @ApiResponse(responseCode = "400", description = "Bad request."), + @ApiResponse(responseCode = "401", description = "Invalid Username or Password."), + @ApiResponse(responseCode = "403", description = "Insufficient privileges for operation."), + @ApiResponse(responseCode = "404", description = "Region does not exist."), + @ApiResponse(responseCode = "500", description = "GemFire throws an error or exception.")}) @PreAuthorize("@securityService.authorize('DATA', 'READ', #region)") public ResponseEntity<?> read(@PathVariable("region") String region, @RequestParam(value = "limit", @@ -228,14 +228,14 @@ public class PdxBasedCrudController extends CommonCrudController { */ @RequestMapping(method = RequestMethod.GET, value = "/{region}/{keys}", produces = APPLICATION_JSON_UTF8_VALUE) - @ApiOperation(value = "read data for specific keys", - notes = "Read data for specif set of keys in a region. Deprecated in favor of /{region}?keys=.") - @ApiResponses({@ApiResponse(code = 200, message = "OK."), - @ApiResponse(code = 400, message = "Bad Request."), - @ApiResponse(code = 401, message = "Invalid Username or Password."), - @ApiResponse(code = 403, message = "Insufficient privileges for operation."), - @ApiResponse(code = 404, message = "Region does not exist."), - @ApiResponse(code = 500, message = "GemFire throws an error or exception.")}) + @Operation(summary = "read data for specific keys", + description = "Read data for specif set of keys in a region. Deprecated in favor of /{region}?keys=.") + @ApiResponses({@ApiResponse(responseCode = "200", description = "OK."), + @ApiResponse(responseCode = "400", description = "Bad Request."), + @ApiResponse(responseCode = "401", description = "Invalid Username or Password."), + @ApiResponse(responseCode = "403", description = "Insufficient privileges for operation."), + @ApiResponse(responseCode = "404", description = "Region does not exist."), + @ApiResponse(responseCode = "500", description = "GemFire throws an error or exception.")}) public ResponseEntity<?> read(@PathVariable("region") String region, @PathVariable("keys") final String[] keys, @RequestParam(value = "ignoreMissingKey", required = false) final String ignoreMissingKey) { @@ -339,20 +339,20 @@ public class PdxBasedCrudController extends CommonCrudController { @RequestMapping(method = RequestMethod.PUT, value = "/{region}/{keys}", consumes = {APPLICATION_JSON_UTF8_VALUE}, produces = { APPLICATION_JSON_UTF8_VALUE}) - @ApiOperation(value = "update data for key", - notes = "Update or insert (put) data for keys in a region." + @Operation(summary = "update data for key", + description = "Update or insert (put) data for keys in a region." + " Deprecated in favor of /{region}?keys=." + " If op=REPLACE, update (replace) data with key if and only if the key exists in the region." + " If op=CAS update (compare-and-set) value having key with a new value if and only if the \"@old\" value sent matches the current value for the key in the region.") - @ApiResponses({@ApiResponse(code = 200, message = "OK."), - @ApiResponse(code = 400, message = "Bad Request."), - @ApiResponse(code = 401, message = "Invalid Username or Password."), - @ApiResponse(code = 403, message = "Insufficient privileges for operation."), - @ApiResponse(code = 404, - message = "Region does not exist or if key is not mapped to some value for REPLACE or CAS."), - @ApiResponse(code = 409, - message = "For CAS, @old value does not match to the current value in region"), - @ApiResponse(code = 500, message = "GemFire throws an error or exception.")}) + @ApiResponses({@ApiResponse(responseCode = "200", description = "OK."), + @ApiResponse(responseCode = "400", description = "Bad Request."), + @ApiResponse(responseCode = "401", description = "Invalid Username or Password."), + @ApiResponse(responseCode = "403", description = "Insufficient privileges for operation."), + @ApiResponse(responseCode = "404", + description = "Region does not exist or if key is not mapped to some value for REPLACE or CAS."), + @ApiResponse(responseCode = "409", + description = "For CAS, @old value does not match to the current value in region"), + @ApiResponse(responseCode = "500", description = "GemFire throws an error or exception.")}) @PreAuthorize("@securityService.authorize('WRITE', #region, #keys)") public ResponseEntity<?> update(@PathVariable("region") String region, @PathVariable("keys") String[] keys, @@ -403,8 +403,8 @@ public class PdxBasedCrudController extends CommonCrudController { @RequestMapping(method = RequestMethod.PUT, value = "/{region}", consumes = {APPLICATION_JSON_UTF8_VALUE}, produces = { APPLICATION_JSON_UTF8_VALUE}) - @ApiOperation(value = "update data for key(s)", - notes = "Update or insert (put) data for keys in a region." + @Operation(summary = "update data for key(s)", + description = "Update or insert (put) data for keys in a region." + " The keys are a comma separated list." + " If multiple keys are given then put (create or update) the data for each key." + " The op parameter is ignored if more than one key is given." @@ -412,16 +412,16 @@ public class PdxBasedCrudController extends CommonCrudController { + " If op=CREATE, create data for the given key if and only if the key does not exit in the region." + " If op=REPLACE, update (replace) data for the given key if and only if the key exists in the region." + " If op=CAS, update (compare-and-set) value having key with a new value if and only if the \"@old\" value sent matches the current value for the key in the region.") - @ApiResponses({@ApiResponse(code = 200, message = "OK."), - @ApiResponse(code = 201, message = "For op=CREATE on success."), - @ApiResponse(code = 400, message = "Bad Request."), - @ApiResponse(code = 401, message = "Invalid Username or Password."), - @ApiResponse(code = 403, message = "Insufficient privileges for operation."), - @ApiResponse(code = 404, - message = "Region does not exist or if key is not mapped to some value for REPLACE or CAS."), - @ApiResponse(code = 409, - message = "For op=CREATE, key already exist in region. For op=CAS, @old value does not match to the current value in region."), - @ApiResponse(code = 500, message = "GemFire throws an error or exception.")}) + @ApiResponses({@ApiResponse(responseCode = "200", description = "OK."), + @ApiResponse(responseCode = "201", description = "For op=CREATE on success."), + @ApiResponse(responseCode = "400", description = "Bad Request."), + @ApiResponse(responseCode = "401", description = "Invalid Username or Password."), + @ApiResponse(responseCode = "403", description = "Insufficient privileges for operation."), + @ApiResponse(responseCode = "404", + description = "Region does not exist or if key is not mapped to some value for REPLACE or CAS."), + @ApiResponse(responseCode = "409", + description = "For op=CREATE, key already exist in region. For op=CAS, @old value does not match to the current value in region."), + @ApiResponse(responseCode = "500", description = "GemFire throws an error or exception.")}) public ResponseEntity<?> updateKeys(@PathVariable("region") final String encodedRegion, @RequestParam(value = "keys") final String[] encodedKeys, @RequestParam(value = "op", defaultValue = "PUT") final String opValue, @@ -461,14 +461,14 @@ public class PdxBasedCrudController extends CommonCrudController { @RequestMapping(method = RequestMethod.HEAD, value = "/{region}", produces = APPLICATION_JSON_UTF8_VALUE) - @ApiOperation(value = "Get total number of entries", - notes = "Get total number of entries into the specified region") - @ApiResponses({@ApiResponse(code = 200, message = "OK."), - @ApiResponse(code = 400, message = "Bad request."), - @ApiResponse(code = 401, message = "Invalid Username or Password."), - @ApiResponse(code = 403, message = "Insufficient privileges for operation."), - @ApiResponse(code = 404, message = "Region does not exist."), - @ApiResponse(code = 500, message = "GemFire throws an error or exception.")}) + @Operation(summary = "Get total number of entries", + description = "Get total number of entries into the specified region") + @ApiResponses({@ApiResponse(responseCode = "200", description = "OK."), + @ApiResponse(responseCode = "400", description = "Bad request."), + @ApiResponse(responseCode = "401", description = "Invalid Username or Password."), + @ApiResponse(responseCode = "403", description = "Insufficient privileges for operation."), + @ApiResponse(responseCode = "404", description = "Region does not exist."), + @ApiResponse(responseCode = "500", description = "GemFire throws an error or exception.")}) @PreAuthorize("@securityService.authorize('DATA', 'READ', #region)") public ResponseEntity<?> size(@PathVariable("region") String region) { logger.debug("Determining the number of entries in Region ({})...", region); diff --git a/geode-web-api/src/main/java/org/apache/geode/rest/internal/web/controllers/QueryAccessController.java b/geode-web-api/src/main/java/org/apache/geode/rest/internal/web/controllers/QueryAccessController.java index 90cbb951d2..35fab2f290 100644 --- a/geode-web-api/src/main/java/org/apache/geode/rest/internal/web/controllers/QueryAccessController.java +++ b/geode-web-api/src/main/java/org/apache/geode/rest/internal/web/controllers/QueryAccessController.java @@ -16,10 +16,10 @@ package org.apache.geode.rest.internal.web.controllers; import java.util.concurrent.ConcurrentHashMap; -import io.swagger.annotations.Api; -import io.swagger.annotations.ApiOperation; -import io.swagger.annotations.ApiResponse; -import io.swagger.annotations.ApiResponses; +import io.swagger.v3.oas.annotations.Operation; +import io.swagger.v3.oas.annotations.responses.ApiResponse; +import io.swagger.v3.oas.annotations.responses.ApiResponses; +import io.swagger.v3.oas.annotations.tags.Tag; import org.apache.logging.log4j.Logger; import org.springframework.http.HttpHeaders; import org.springframework.http.HttpStatus; @@ -57,8 +57,7 @@ import org.apache.geode.rest.internal.web.util.ValidationUtils; * @since GemFire 8.0 */ @Controller("queryController") -@Api(value = "queries", produces = AbstractBaseController.APPLICATION_JSON_UTF8_VALUE, - tags = "queries") +@Tag(name = "queries", description = "queries") @RequestMapping(QueryAccessController.REST_API_VERSION + "/queries") @SuppressWarnings("unused") public class QueryAccessController extends AbstractBaseController { @@ -88,12 +87,12 @@ public class QueryAccessController extends AbstractBaseController { * @return result as a JSON document. */ @RequestMapping(method = RequestMethod.GET, produces = {APPLICATION_JSON_UTF8_VALUE}) - @ApiOperation(value = "list all parametrized queries", - notes = "List all parametrized queries by id/name") - @ApiResponses({@ApiResponse(code = 200, message = "OK."), - @ApiResponse(code = 401, message = "Invalid Username or Password."), - @ApiResponse(code = 403, message = "Insufficient privileges for operation."), - @ApiResponse(code = 500, message = "if GemFire throws an error or exception")}) + @Operation(summary = "list all parametrized queries", + description = "List all parametrized queries by id/name") + @ApiResponses({@ApiResponse(responseCode = "200", description = "OK."), + @ApiResponse(responseCode = "401", description = "Invalid Username or Password."), + @ApiResponse(responseCode = "403", description = "Insufficient privileges for operation."), + @ApiResponse(responseCode = "500", description = "if GemFire throws an error or exception")}) @ResponseBody @ResponseStatus(HttpStatus.OK) @PreAuthorize("@securityService.authorize('DATA', 'READ')") @@ -118,13 +117,13 @@ public class QueryAccessController extends AbstractBaseController { * @return result as a JSON document. */ @RequestMapping(method = RequestMethod.POST) - @ApiOperation(value = "create a parametrized Query", - notes = "Prepare the specified parametrized query and assign the corresponding ID for lookup") - @ApiResponses({@ApiResponse(code = 201, message = "Successfully created."), - @ApiResponse(code = 401, message = "Invalid Username or Password."), - @ApiResponse(code = 403, message = "Insufficient privileges for operation."), - @ApiResponse(code = 409, message = "QueryId already assigned to other query."), - @ApiResponse(code = 500, message = "GemFire throws an error or exception.")}) + @Operation(summary = "create a parametrized Query", + description = "Prepare the specified parametrized query and assign the corresponding ID for lookup") + @ApiResponses({@ApiResponse(responseCode = "201", description = "Successfully created."), + @ApiResponse(responseCode = "401", description = "Invalid Username or Password."), + @ApiResponse(responseCode = "403", description = "Insufficient privileges for operation."), + @ApiResponse(responseCode = "409", description = "QueryId already assigned to other query."), + @ApiResponse(responseCode = "500", description = "GemFire throws an error or exception.")}) @PreAuthorize("@securityService.authorize('DATA', 'READ')") public ResponseEntity<?> create(@RequestParam("id") final String queryId, @RequestParam(value = "q", required = false) String oqlInUrl, @@ -159,12 +158,12 @@ public class QueryAccessController extends AbstractBaseController { */ @RequestMapping(method = RequestMethod.GET, value = "/adhoc", produces = {APPLICATION_JSON_UTF8_VALUE}) - @ApiOperation(value = "run an adhoc query", - notes = "Run an unnamed (unidentified), ad-hoc query passed as a URL parameter") - @ApiResponses({@ApiResponse(code = 200, message = "OK."), - @ApiResponse(code = 401, message = "Invalid Username or Password."), - @ApiResponse(code = 403, message = "Insufficient privileges for operation."), - @ApiResponse(code = 500, message = "GemFire throws an error or exception")}) + @Operation(summary = "run an adhoc query", + description = "Run an unnamed (unidentified), ad-hoc query passed as a URL parameter") + @ApiResponses({@ApiResponse(responseCode = "200", description = "OK."), + @ApiResponse(responseCode = "401", description = "Invalid Username or Password."), + @ApiResponse(responseCode = "403", description = "Insufficient privileges for operation."), + @ApiResponse(responseCode = "500", description = "GemFire throws an error or exception")}) @ResponseBody @ResponseStatus(HttpStatus.OK) @PreAuthorize("@securityService.authorize('DATA', 'READ')") @@ -217,14 +216,14 @@ public class QueryAccessController extends AbstractBaseController { */ @RequestMapping(method = RequestMethod.POST, value = "/{query}", produces = {APPLICATION_JSON_UTF8_VALUE}) - @ApiOperation(value = "run parametrized query", - notes = "run the specified named query passing in scalar values for query parameters in the GemFire cluster") - @ApiResponses({@ApiResponse(code = 200, message = "Query successfully executed."), - @ApiResponse(code = 401, message = "Invalid Username or Password."), - @ApiResponse(code = 403, message = "Insufficient privileges for operation."), - @ApiResponse(code = 400, - message = "Query bind params specified as JSON document in the request body is invalid"), - @ApiResponse(code = 500, message = "GemFire throws an error or exception")}) + @Operation(summary = "run parametrized query", + description = "run the specified named query passing in scalar values for query parameters in the GemFire cluster") + @ApiResponses({@ApiResponse(responseCode = "200", description = "Query successfully executed."), + @ApiResponse(responseCode = "401", description = "Invalid Username or Password."), + @ApiResponse(responseCode = "403", description = "Insufficient privileges for operation."), + @ApiResponse(responseCode = "400", + description = "Query bind params specified as JSON document in the request body is invalid"), + @ApiResponse(responseCode = "500", description = "GemFire throws an error or exception")}) @ResponseBody @ResponseStatus(HttpStatus.OK) @PreAuthorize("@securityService.authorize('DATA', 'READ')") @@ -300,13 +299,13 @@ public class QueryAccessController extends AbstractBaseController { * @param oqlInBody OQL query string specified in a request body */ @RequestMapping(method = RequestMethod.PUT, value = "/{query}") - @ApiOperation(value = "update parametrized query", - notes = "Update named, parametrized query by ID") - @ApiResponses({@ApiResponse(code = 200, message = "Updated successfully."), - @ApiResponse(code = 401, message = "Invalid Username or Password."), - @ApiResponse(code = 403, message = "Insufficient privileges for operation."), - @ApiResponse(code = 404, message = "queryId does not exist."), - @ApiResponse(code = 500, message = "GemFire throws an error or exception.")}) + @Operation(summary = "update parametrized query", + description = "Update named, parametrized query by ID") + @ApiResponses({@ApiResponse(responseCode = "200", description = "Updated successfully."), + @ApiResponse(responseCode = "401", description = "Invalid Username or Password."), + @ApiResponse(responseCode = "403", description = "Insufficient privileges for operation."), + @ApiResponse(responseCode = "404", description = "queryId does not exist."), + @ApiResponse(responseCode = "500", description = "GemFire throws an error or exception.")}) @PreAuthorize("@securityService.authorize('DATA', 'READ')") public ResponseEntity<?> update(@PathVariable("query") final String queryId, @RequestParam(value = "q", required = false) String oqlInUrl, @@ -331,13 +330,13 @@ public class QueryAccessController extends AbstractBaseController { * @param queryId uniquely identify the query to be deleted */ @RequestMapping(method = RequestMethod.DELETE, value = "/{query}") - @ApiOperation(value = "delete parametrized query", - notes = "delete named, parametrized query by ID") - @ApiResponses({@ApiResponse(code = 200, message = "Deleted successfully."), - @ApiResponse(code = 401, message = "Invalid Username or Password."), - @ApiResponse(code = 403, message = "Insufficient privileges for operation."), - @ApiResponse(code = 404, message = "queryId does not exist."), - @ApiResponse(code = 500, message = "GemFire throws an error or exception")}) + @Operation(summary = "delete parametrized query", + description = "delete named, parametrized query by ID") + @ApiResponses({@ApiResponse(responseCode = "200", description = "Deleted successfully."), + @ApiResponse(responseCode = "401", description = "Invalid Username or Password."), + @ApiResponse(responseCode = "403", description = "Insufficient privileges for operation."), + @ApiResponse(responseCode = "404", description = "queryId does not exist."), + @ApiResponse(responseCode = "500", description = "GemFire throws an error or exception")}) @PreAuthorize("@securityService.authorize('DATA', 'WRITE')") public ResponseEntity<?> delete(@PathVariable("query") final String queryId) { logger.debug("Deleting a named, parametrized Query with ID ({}).", queryId); diff --git a/geode-web-api/src/main/java/org/apache/geode/rest/internal/web/security/RestSecurityConfiguration.java b/geode-web-api/src/main/java/org/apache/geode/rest/internal/web/security/RestSecurityConfiguration.java index 342fdd772e..d3e3be11b1 100644 --- a/geode-web-api/src/main/java/org/apache/geode/rest/internal/web/security/RestSecurityConfiguration.java +++ b/geode-web-api/src/main/java/org/apache/geode/rest/internal/web/security/RestSecurityConfiguration.java @@ -38,7 +38,7 @@ public class RestSecurityConfiguration extends WebSecurityConfigurerAdapter { private GeodeAuthenticationProvider authProvider; @Override - protected void configure(AuthenticationManagerBuilder auth) throws Exception { + protected void configure(AuthenticationManagerBuilder auth) { auth.authenticationProvider(authProvider); } @@ -53,8 +53,8 @@ public class RestSecurityConfiguration extends WebSecurityConfigurerAdapter { http.sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS).and() .authorizeRequests() - .antMatchers("/docs/**", "/swagger-ui.html", - Links.URI_VERSION + "/api-docs/**", "/webjars/springfox-swagger-ui/**", + .antMatchers("/docs/**", "/swagger-ui.html", "/swagger-ui/index.html", + Links.URI_VERSION + "/api-docs/**", "/webjars/springdoc-openapi-ui/**", "/swagger-resources/**") .permitAll().and().csrf().disable(); diff --git a/geode-web-api/src/main/java/org/apache/geode/rest/internal/web/swagger/config/SwaggerConfig.java b/geode-web-api/src/main/java/org/apache/geode/rest/internal/web/swagger/config/SwaggerConfig.java index be665a3933..a186611632 100644 --- a/geode-web-api/src/main/java/org/apache/geode/rest/internal/web/swagger/config/SwaggerConfig.java +++ b/geode-web-api/src/main/java/org/apache/geode/rest/internal/web/swagger/config/SwaggerConfig.java @@ -14,46 +14,46 @@ */ package org.apache.geode.rest.internal.web.swagger.config; + +import io.swagger.v3.oas.models.OpenAPI; +import io.swagger.v3.oas.models.info.Contact; +import io.swagger.v3.oas.models.info.Info; +import io.swagger.v3.oas.models.info.License; +import org.springdoc.core.GroupedOpenApi; +import org.springframework.boot.autoconfigure.SpringBootApplication; +import org.springframework.boot.autoconfigure.ldap.LdapAutoConfiguration; +import org.springframework.boot.autoconfigure.transaction.TransactionAutoConfiguration; import org.springframework.context.annotation.Bean; -import org.springframework.context.annotation.Configuration; import org.springframework.context.annotation.PropertySource; -import springfox.documentation.builders.ApiInfoBuilder; -import springfox.documentation.builders.PathSelectors; -import springfox.documentation.builders.RequestHandlerSelectors; -import springfox.documentation.service.ApiInfo; -import springfox.documentation.service.Contact; -import springfox.documentation.spi.DocumentationType; -import springfox.documentation.spring.web.plugins.Docket; -import springfox.documentation.swagger2.annotations.EnableSwagger2; @PropertySource({"classpath:swagger.properties"}) -@Configuration -@EnableSwagger2 +@SpringBootApplication(exclude = {TransactionAutoConfiguration.class, LdapAutoConfiguration.class}) @SuppressWarnings("unused") public class SwaggerConfig { @Bean - public Docket api() { - return new Docket(DocumentationType.SWAGGER_2).select().apis(RequestHandlerSelectors.any()) - .paths(PathSelectors.any()).build().apiInfo(apiInfo()); + public GroupedOpenApi api() { + return GroupedOpenApi.builder() + .group("developer-apis") + .pathsToMatch("/**") + .build(); } /** * API Info as it appears on the Swagger-UI page */ - private ApiInfo apiInfo() { - return new ApiInfoBuilder() - .title("Apache Geode Developer REST API") - .description( - "Developer REST API and interface to Geode's distributed, in-memory data grid and cache.") - .version("1.0") - .termsOfServiceUrl("http://www.apache.org/licenses/") - .license("Apache License, version 2.0") - .licenseUrl("http://www.apache.org/licenses/") - .contact(new Contact("the Apache Geode Community", - "http://geode.apache.org", - "u...@geode.apache.org")) - .build(); + @Bean + public OpenAPI apiInfo() { + return new OpenAPI() + .info(new Info().title("Apache Geode Developer REST API") + .description( + "Developer REST API and interface to Geode's distributed, in-memory data grid and cache.") + .version("v1") + .termsOfService("http://www.apache.org/licenses/") + .license(new License().name("Apache License, version 2.0") + .url("http://www.apache.org/licenses/")) + .contact(new Contact().name("the Apache Geode Community").url("http://geode.apache.org") + .email("u...@geode.apache.org"))); } } diff --git a/geode-web-api/src/main/resources/swagger.properties b/geode-web-api/src/main/resources/swagger.properties index 3ac097d058..332dd37f70 100644 --- a/geode-web-api/src/main/resources/swagger.properties +++ b/geode-web-api/src/main/resources/swagger.properties @@ -12,4 +12,5 @@ # or implied. See the License for the specific language governing permissions and limitations under # the License. # -springfox.documentation.swagger.v2.path=/v1/api-docs \ No newline at end of file +springdoc.api-docs.path=/v1/api-docs +springdoc.swagger-ui.path=/swagger-ui.html \ No newline at end of file diff --git a/geode-web-api/src/main/webapp/WEB-INF/geode-servlet.xml b/geode-web-api/src/main/webapp/WEB-INF/geode-servlet.xml index 9af206b014..75575e1096 100644 --- a/geode-web-api/src/main/webapp/WEB-INF/geode-servlet.xml +++ b/geode-web-api/src/main/webapp/WEB-INF/geode-servlet.xml @@ -45,6 +45,7 @@ limitations under the License. <mvc:default-servlet-handler/> <bean id="contentNegotiationManager" class="org.springframework.web.accept.ContentNegotiationManagerFactoryBean" + autowire-candidate="false" p:favorPathExtension="true" p:favorParameter="false" p:ignoreAcceptHeader="false" diff --git a/geode-web-management/build.gradle b/geode-web-management/build.gradle index 1c89f4913b..feeae3ea09 100644 --- a/geode-web-management/build.gradle +++ b/geode-web-management/build.gradle @@ -72,15 +72,9 @@ dependencies { exclude module: 'jackson-annotations' } - compileOnly('io.swagger:swagger-annotations') - - implementation('io.springfox:springfox-swagger2') { + implementation('org.springdoc:springdoc-openapi-ui') { exclude module: 'slf4j-api' exclude module: 'jackson-annotations' - exclude module: 'swagger-annotations' - } - implementation('io.springfox:springfox-swagger-ui') { - exclude module: 'slf4j-api' } implementation('org.springframework:spring-beans') diff --git a/geode-web-management/src/main/java/org/apache/geode/management/internal/rest/controllers/DeploymentManagementController.java b/geode-web-management/src/main/java/org/apache/geode/management/internal/rest/controllers/DeploymentManagementController.java index 4be6227157..0aa76268c5 100644 --- a/geode-web-management/src/main/java/org/apache/geode/management/internal/rest/controllers/DeploymentManagementController.java +++ b/geode-web-management/src/main/java/org/apache/geode/management/internal/rest/controllers/DeploymentManagementController.java @@ -21,10 +21,10 @@ import java.io.File; import java.io.IOException; import java.nio.file.Path; -import io.swagger.annotations.ApiOperation; -import io.swagger.annotations.ApiParam; -import io.swagger.annotations.ApiResponse; -import io.swagger.annotations.ApiResponses; +import io.swagger.v3.oas.annotations.Operation; +import io.swagger.v3.oas.annotations.Parameter; +import io.swagger.v3.oas.annotations.responses.ApiResponse; +import io.swagger.v3.oas.annotations.responses.ApiResponses; import org.apache.commons.lang3.StringUtils; import org.apache.logging.log4j.Logger; import org.springframework.beans.factory.annotation.Autowired; @@ -59,7 +59,7 @@ public class DeploymentManagementController extends AbstractManagementController private static final Logger logger = LogService.getLogger(); - @ApiOperation(value = "list deployed") + @Operation(summary = "list deployed") @PreAuthorize("@securityService.authorize('CLUSTER', 'READ')") @GetMapping(Deployment.DEPLOYMENT_ENDPOINT) public ClusterManagementListResult<Deployment, DeploymentInfo> list( @@ -75,7 +75,7 @@ public class DeploymentManagementController extends AbstractManagementController return clusterManagementService.list(deployment); } - @ApiOperation(value = "get deployed") + @Operation(summary = "get deployed") @PreAuthorize("@securityService.authorize('CLUSTER', 'READ')") @GetMapping(Deployment.DEPLOYMENT_ENDPOINT + "/{id:.+}") public ClusterManagementGetResult<Deployment, DeploymentInfo> getDeployed( @@ -87,17 +87,18 @@ public class DeploymentManagementController extends AbstractManagementController return clusterManagementService.get(deployment); } - @ApiOperation(value = "deploy") + @Operation(summary = "deploy") @ApiResponses({ - @ApiResponse(code = 400, message = "Bad request."), - @ApiResponse(code = 500, message = "Internal error.")}) + @ApiResponse(responseCode = "400", description = "Bad request."), + @ApiResponse(responseCode = "500", description = "Internal error.")}) @PreAuthorize("@securityService.authorize('CLUSTER', 'MANAGE', 'DEPLOY')") @PutMapping(value = Deployment.DEPLOYMENT_ENDPOINT, consumes = {"multipart/form-data"}) public ResponseEntity<ClusterManagementResult> deploy( - @ApiParam(value = "filePath", + @Parameter(name = "filePath", required = true) @RequestParam(HasFile.FILE_PARAM) MultipartFile file, - @ApiParam("deployment json configuration") @RequestParam(value = HasFile.CONFIG_PARAM, + @Parameter(description = "deployment json configuration") @RequestParam( + value = HasFile.CONFIG_PARAM, required = false) String json) throws IOException { // save the file to the staging area diff --git a/geode-web-management/src/main/java/org/apache/geode/management/internal/rest/controllers/DiskStoreController.java b/geode-web-management/src/main/java/org/apache/geode/management/internal/rest/controllers/DiskStoreController.java index b83144a92c..76571e0f23 100644 --- a/geode-web-management/src/main/java/org/apache/geode/management/internal/rest/controllers/DiskStoreController.java +++ b/geode-web-management/src/main/java/org/apache/geode/management/internal/rest/controllers/DiskStoreController.java @@ -22,11 +22,11 @@ package org.apache.geode.management.internal.rest.controllers; import static org.apache.geode.management.configuration.DiskStore.DISK_STORE_CONFIG_ENDPOINT; import static org.apache.geode.management.configuration.Links.URI_VERSION; -import io.swagger.annotations.ApiOperation; -import io.swagger.annotations.ApiResponse; -import io.swagger.annotations.ApiResponses; -import io.swagger.annotations.Extension; -import io.swagger.annotations.ExtensionProperty; +import io.swagger.v3.oas.annotations.Operation; +import io.swagger.v3.oas.annotations.extensions.Extension; +import io.swagger.v3.oas.annotations.extensions.ExtensionProperty; +import io.swagger.v3.oas.annotations.responses.ApiResponse; +import io.swagger.v3.oas.annotations.responses.ApiResponses; import org.apache.commons.lang3.StringUtils; import org.springframework.http.HttpStatus; import org.springframework.http.ResponseEntity; @@ -51,11 +51,11 @@ import org.apache.geode.security.ResourcePermission; @RequestMapping(URI_VERSION) public class DiskStoreController extends AbstractManagementController { - @ApiOperation(value = "create disk-store") + @Operation(summary = "create disk-store") @ApiResponses({ - @ApiResponse(code = 400, message = "Bad request."), - @ApiResponse(code = 409, message = "Diskstore already exists."), - @ApiResponse(code = 500, message = "Internal error.")}) + @ApiResponse(responseCode = "400", description = "Bad request."), + @ApiResponse(responseCode = "409", description = "Diskstore already exists."), + @ApiResponse(responseCode = "500", description = "Internal error.")}) @PreAuthorize("@securityService.authorize('CLUSTER', 'MANAGE')") @PostMapping(DISK_STORE_CONFIG_ENDPOINT) public ResponseEntity<ClusterManagementResult> createDiskStore( @@ -64,7 +64,7 @@ public class DiskStoreController extends AbstractManagementController { return new ResponseEntity<>(result, HttpStatus.CREATED); } - @ApiOperation(value = "list disk-stores", + @Operation(summary = "list disk-stores", extensions = {@Extension(properties = { @ExtensionProperty(name = "jqFilter", value = ".result[] | .groups[] | .runtimeInfo[] + .configuration | {Member:.memberName,\"Disk Store Name\":.name}")})}) @@ -83,7 +83,7 @@ public class DiskStoreController extends AbstractManagementController { return clusterManagementService.list(filter); } - @ApiOperation(value = "get disk-store", + @Operation(summary = "get disk-store", extensions = {@Extension(properties = { @ExtensionProperty(name = "jqFilter", value = ".result | .groups[] | .runtimeInfo[] + .configuration | {Member:.memberName,\"Disk Store Name\":.name}")})}) @@ -97,7 +97,7 @@ public class DiskStoreController extends AbstractManagementController { return clusterManagementService.get(config); } - @ApiOperation(value = "delete disk-store") + @Operation(summary = "delete disk-store") @PreAuthorize("@securityService.authorize('CLUSTER', 'MANAGE')") @DeleteMapping(DISK_STORE_CONFIG_ENDPOINT + "/{id}") public ClusterManagementResult deleteDiskStore( diff --git a/geode-web-management/src/main/java/org/apache/geode/management/internal/rest/controllers/DocLinksController.java b/geode-web-management/src/main/java/org/apache/geode/management/internal/rest/controllers/DocLinksController.java index 606ccf75b3..93665e20ee 100644 --- a/geode-web-management/src/main/java/org/apache/geode/management/internal/rest/controllers/DocLinksController.java +++ b/geode-web-management/src/main/java/org/apache/geode/management/internal/rest/controllers/DocLinksController.java @@ -20,7 +20,7 @@ import java.util.List; import javax.servlet.http.HttpServletRequest; -import io.swagger.annotations.ApiOperation; +import io.swagger.v3.oas.annotations.Operation; import org.springframework.http.HttpStatus; import org.springframework.http.ResponseEntity; import org.springframework.web.bind.annotation.GetMapping; @@ -29,7 +29,7 @@ import org.springframework.web.bind.annotation.RestController; @RestController("apiDocumentation") public class DocLinksController { - @ApiOperation("get documentation-links") + @Operation(summary = "get documentation-links") @GetMapping("/") public ResponseEntity<DocLinks> getDocumentationLinks(HttpServletRequest request) { DocLinks docLinks = new DocLinks(); diff --git a/geode-web-management/src/main/java/org/apache/geode/management/internal/rest/controllers/GatewayManagementController.java b/geode-web-management/src/main/java/org/apache/geode/management/internal/rest/controllers/GatewayManagementController.java index ada9b16400..70979055bc 100644 --- a/geode-web-management/src/main/java/org/apache/geode/management/internal/rest/controllers/GatewayManagementController.java +++ b/geode-web-management/src/main/java/org/apache/geode/management/internal/rest/controllers/GatewayManagementController.java @@ -18,9 +18,9 @@ package org.apache.geode.management.internal.rest.controllers; import static org.apache.geode.management.configuration.GatewayReceiver.GATEWAY_RECEIVERS_ENDPOINTS; import static org.apache.geode.management.configuration.Links.URI_VERSION; -import io.swagger.annotations.ApiOperation; -import io.swagger.annotations.ApiResponse; -import io.swagger.annotations.ApiResponses; +import io.swagger.v3.oas.annotations.Operation; +import io.swagger.v3.oas.annotations.responses.ApiResponse; +import io.swagger.v3.oas.annotations.responses.ApiResponses; import org.apache.commons.lang3.StringUtils; import org.springframework.http.HttpStatus; import org.springframework.http.ResponseEntity; @@ -43,7 +43,7 @@ import org.apache.geode.management.runtime.GatewayReceiverInfo; @RestController("gatewayManagement") @RequestMapping(URI_VERSION) public class GatewayManagementController extends AbstractManagementController { - @ApiOperation(value = "list gateway-receivers") + @Operation(summary = "list gateway-receivers") @PreAuthorize("@securityService.authorize('CLUSTER', 'READ')") @GetMapping(GATEWAY_RECEIVERS_ENDPOINTS) public ClusterManagementListResult<GatewayReceiver, GatewayReceiverInfo> listGatewayReceivers( @@ -55,7 +55,7 @@ public class GatewayManagementController extends AbstractManagementController { return clusterManagementService.list(filter); } - @ApiOperation(value = "get gateway-receiver") + @Operation(summary = "get gateway-receiver") @PreAuthorize("@securityService.authorize('CLUSTER', 'READ')") @GetMapping(GATEWAY_RECEIVERS_ENDPOINTS + "/{id:.+}") public ClusterManagementGetResult<GatewayReceiver, GatewayReceiverInfo> getGatewayReceiver( @@ -65,11 +65,11 @@ public class GatewayManagementController extends AbstractManagementController { return clusterManagementService.get(config); } - @ApiOperation(value = "create gateway-receiver") + @Operation(summary = "create gateway-receiver") @ApiResponses({ - @ApiResponse(code = 400, message = "Bad request."), - @ApiResponse(code = 409, message = "Gateway receiver already exists."), - @ApiResponse(code = 500, message = "Internal error.")}) + @ApiResponse(responseCode = "400", description = "Bad request."), + @ApiResponse(responseCode = "409", description = "Gateway receiver already exists."), + @ApiResponse(responseCode = "500", description = "Internal error.")}) @PreAuthorize("@securityService.authorize('CLUSTER', 'MANAGE')") @PostMapping(GATEWAY_RECEIVERS_ENDPOINTS) public ResponseEntity<ClusterManagementResult> createGatewayReceiver( diff --git a/geode-web-management/src/main/java/org/apache/geode/management/internal/rest/controllers/MemberManagementController.java b/geode-web-management/src/main/java/org/apache/geode/management/internal/rest/controllers/MemberManagementController.java index 0e51cf3f71..f9d3d12955 100644 --- a/geode-web-management/src/main/java/org/apache/geode/management/internal/rest/controllers/MemberManagementController.java +++ b/geode-web-management/src/main/java/org/apache/geode/management/internal/rest/controllers/MemberManagementController.java @@ -18,9 +18,9 @@ package org.apache.geode.management.internal.rest.controllers; import static org.apache.geode.management.configuration.Links.URI_VERSION; import static org.apache.geode.management.configuration.Member.MEMBER_ENDPOINT; -import io.swagger.annotations.ApiOperation; -import io.swagger.annotations.Extension; -import io.swagger.annotations.ExtensionProperty; +import io.swagger.v3.oas.annotations.Operation; +import io.swagger.v3.oas.annotations.extensions.Extension; +import io.swagger.v3.oas.annotations.extensions.ExtensionProperty; import org.apache.commons.lang3.StringUtils; import org.springframework.security.access.prepost.PreAuthorize; import org.springframework.web.bind.annotation.GetMapping; @@ -37,7 +37,7 @@ import org.apache.geode.management.runtime.MemberInformation; @RestController("members") @RequestMapping(URI_VERSION) public class MemberManagementController extends AbstractManagementController { - @ApiOperation(value = "get member", + @Operation(summary = "get member", extensions = {@Extension(properties = { @ExtensionProperty(name = "jqFilter", value = ".result | .groups[] | .runtimeInfo[] | {name:.memberName,status:.status}")})}) @@ -50,7 +50,7 @@ public class MemberManagementController extends AbstractManagementController { return clusterManagementService.get(config); } - @ApiOperation(value = "list members", + @Operation(summary = "list members", extensions = {@Extension(properties = { @ExtensionProperty(name = "jqFilter", value = ".result[] | .groups[] | .runtimeInfo[] | {name:.memberName,status:.status}")})}) diff --git a/geode-web-management/src/main/java/org/apache/geode/management/internal/rest/controllers/PdxManagementController.java b/geode-web-management/src/main/java/org/apache/geode/management/internal/rest/controllers/PdxManagementController.java index 5ef0878946..ef70cfdbd2 100644 --- a/geode-web-management/src/main/java/org/apache/geode/management/internal/rest/controllers/PdxManagementController.java +++ b/geode-web-management/src/main/java/org/apache/geode/management/internal/rest/controllers/PdxManagementController.java @@ -18,9 +18,9 @@ package org.apache.geode.management.internal.rest.controllers; import static org.apache.geode.management.configuration.Links.URI_VERSION; import static org.apache.geode.management.configuration.Pdx.PDX_ENDPOINT; -import io.swagger.annotations.ApiOperation; -import io.swagger.annotations.ApiResponse; -import io.swagger.annotations.ApiResponses; +import io.swagger.v3.oas.annotations.Operation; +import io.swagger.v3.oas.annotations.responses.ApiResponse; +import io.swagger.v3.oas.annotations.responses.ApiResponses; import org.springframework.http.HttpStatus; import org.springframework.http.ResponseEntity; import org.springframework.security.access.prepost.PreAuthorize; @@ -41,11 +41,11 @@ import org.apache.geode.management.runtime.PdxInfo; @RequestMapping(URI_VERSION) public class PdxManagementController extends AbstractManagementController { - @ApiOperation(value = "configure pdx") + @Operation(summary = "configure pdx") @ApiResponses({ - @ApiResponse(code = 400, message = "Bad request."), - @ApiResponse(code = 409, message = "Pdx already configured."), - @ApiResponse(code = 500, message = "Internal error.")}) + @ApiResponse(responseCode = "400", description = "Bad request."), + @ApiResponse(responseCode = "409", description = "Pdx already configured."), + @ApiResponse(responseCode = "500", description = "Internal error.")}) @PreAuthorize("@securityService.authorize('CLUSTER', 'MANAGE')") @PostMapping(PDX_ENDPOINT) public ResponseEntity<ClusterManagementResult> configurePdx( @@ -54,17 +54,17 @@ public class PdxManagementController extends AbstractManagementController { return new ResponseEntity<>(result, HttpStatus.CREATED); } - @ApiOperation(value = "get pdx") + @Operation(summary = "get pdx") @PreAuthorize("@securityService.authorize('CLUSTER', 'READ')") @GetMapping(PDX_ENDPOINT) public ClusterManagementGetResult<Pdx, PdxInfo> getPDX() { return clusterManagementService.get(new Pdx()); } - @ApiOperation(value = "update pdx") + @Operation(summary = "update pdx") @ApiResponses({ - @ApiResponse(code = 400, message = "Bad request."), - @ApiResponse(code = 500, message = "Internal error.")}) + @ApiResponse(responseCode = "400", description = "Bad request."), + @ApiResponse(responseCode = "500", description = "Internal error.")}) @PreAuthorize("@securityService.authorize('CLUSTER', 'MANAGE')") @PutMapping(PDX_ENDPOINT) public ResponseEntity<ClusterManagementResult> updatePdx(@RequestBody Pdx pdxType) { @@ -73,7 +73,7 @@ public class PdxManagementController extends AbstractManagementController { return new ResponseEntity<>(result, HttpStatus.CREATED); } - @ApiOperation(value = "delete pdx") + @Operation(summary = "delete pdx") @PreAuthorize("@securityService.authorize('CLUSTER', 'MANAGE')") @DeleteMapping(PDX_ENDPOINT) public ClusterManagementResult deletePDX() { diff --git a/geode-web-management/src/main/java/org/apache/geode/management/internal/rest/controllers/PingManagementController.java b/geode-web-management/src/main/java/org/apache/geode/management/internal/rest/controllers/PingManagementController.java index 1cbfde356f..c1da4a21dc 100644 --- a/geode-web-management/src/main/java/org/apache/geode/management/internal/rest/controllers/PingManagementController.java +++ b/geode-web-management/src/main/java/org/apache/geode/management/internal/rest/controllers/PingManagementController.java @@ -17,19 +17,20 @@ package org.apache.geode.management.internal.rest.controllers; import static org.apache.geode.management.configuration.Links.URI_VERSION; -import io.swagger.annotations.ApiOperation; +import io.swagger.v3.oas.annotations.Operation; import org.springframework.http.HttpStatus; import org.springframework.http.ResponseEntity; import org.springframework.stereotype.Controller; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.RequestMapping; -@ApiOperation(value = "ping") + @Controller("ping") @RequestMapping(URI_VERSION) public class PingManagementController extends AbstractManagementController { @GetMapping("/ping") + @Operation(summary = "ping") public ResponseEntity<String> ping() { return new ResponseEntity<>("pong", HttpStatus.OK); } diff --git a/geode-web-management/src/main/java/org/apache/geode/management/internal/rest/controllers/RebalanceOperationController.java b/geode-web-management/src/main/java/org/apache/geode/management/internal/rest/controllers/RebalanceOperationController.java index a5b0de6fb8..ba3ab7be26 100644 --- a/geode-web-management/src/main/java/org/apache/geode/management/internal/rest/controllers/RebalanceOperationController.java +++ b/geode-web-management/src/main/java/org/apache/geode/management/internal/rest/controllers/RebalanceOperationController.java @@ -20,7 +20,7 @@ import static org.apache.geode.management.operation.RebalanceOperation.REBALANCE import java.util.Optional; -import io.swagger.annotations.ApiOperation; +import io.swagger.v3.oas.annotations.Operation; import org.springframework.http.HttpStatus; import org.springframework.http.ResponseEntity; import org.springframework.security.access.prepost.PreAuthorize; @@ -40,7 +40,7 @@ import org.apache.geode.management.runtime.RebalanceResult; @RestController("rebalanceOperation") @RequestMapping(URI_VERSION) public class RebalanceOperationController extends AbstractManagementController { - @ApiOperation(value = "start rebalance") + @Operation(summary = "start rebalance") @PreAuthorize("@securityService.authorize('DATA', 'MANAGE')") @PostMapping(REBALANCE_ENDPOINT) public ResponseEntity<ClusterManagementOperationResult<RebalanceOperation, RebalanceResult>> startRebalance( @@ -54,14 +54,14 @@ public class RebalanceOperationController extends AbstractManagementController { return new ResponseEntity<>(result, HttpStatus.ACCEPTED); } - @ApiOperation(value = "list rebalances") + @Operation(summary = "list rebalances") @PreAuthorize("@securityService.authorize('DATA', 'MANAGE')") @GetMapping(REBALANCE_ENDPOINT) public ClusterManagementListOperationsResult<RebalanceOperation, RebalanceResult> listRebalances() { return clusterManagementService.list(new RebalanceOperation()); } - @ApiOperation(value = "get rebalance") + @Operation(summary = "get rebalance") @PreAuthorize("@securityService.authorize('DATA', 'MANAGE')") @GetMapping(REBALANCE_ENDPOINT + "/{id:.+}") public ClusterManagementOperationResult<RebalanceOperation, RebalanceResult> getRebalance( diff --git a/geode-web-management/src/main/java/org/apache/geode/management/internal/rest/controllers/RegionManagementController.java b/geode-web-management/src/main/java/org/apache/geode/management/internal/rest/controllers/RegionManagementController.java index ff3e8d8113..d3f41c5b52 100644 --- a/geode-web-management/src/main/java/org/apache/geode/management/internal/rest/controllers/RegionManagementController.java +++ b/geode-web-management/src/main/java/org/apache/geode/management/internal/rest/controllers/RegionManagementController.java @@ -19,11 +19,10 @@ import static org.apache.geode.management.configuration.Index.INDEXES; import static org.apache.geode.management.configuration.Links.URI_VERSION; import static org.apache.geode.management.configuration.Region.REGION_CONFIG_ENDPOINT; -import io.swagger.annotations.ApiOperation; -import io.swagger.annotations.ApiResponse; -import io.swagger.annotations.ApiResponses; -import io.swagger.annotations.Extension; -import io.swagger.annotations.ExtensionProperty; +import io.swagger.v3.oas.annotations.extensions.Extension; +import io.swagger.v3.oas.annotations.extensions.ExtensionProperty; +import io.swagger.v3.oas.annotations.responses.ApiResponse; +import io.swagger.v3.oas.annotations.responses.ApiResponses; import org.apache.commons.lang3.StringUtils; import org.springframework.http.HttpStatus; import org.springframework.http.ResponseEntity; @@ -51,11 +50,11 @@ import org.apache.geode.security.ResourcePermission.Resource; @RequestMapping(URI_VERSION) public class RegionManagementController extends AbstractManagementController { - @ApiOperation(value = "create region") + @io.swagger.v3.oas.annotations.Operation(summary = "create region") @ApiResponses({ - @ApiResponse(code = 400, message = "Bad request."), - @ApiResponse(code = 409, message = "Region already exists."), - @ApiResponse(code = 500, message = "Internal error.")}) + @ApiResponse(responseCode = "400", description = "Bad request."), + @ApiResponse(responseCode = "409", description = "Region already exists."), + @ApiResponse(responseCode = "500", description = "Internal error.")}) @PreAuthorize("@securityService.authorize('DATA', 'MANAGE')") @PostMapping(REGION_CONFIG_ENDPOINT) public ResponseEntity<ClusterManagementResult> createRegion( @@ -66,7 +65,7 @@ public class RegionManagementController extends AbstractManagementController { HttpStatus.CREATED); } - @ApiOperation(value = "list regions", + @io.swagger.v3.oas.annotations.Operation(summary = "list regions", extensions = {@Extension(properties = { @ExtensionProperty(name = "jqFilter", value = ".result[] | .groups[] | .runtimeInfo[] + .configuration | {name:.name,type:.type,entryCount:.entryCount}")})}) @@ -85,7 +84,7 @@ public class RegionManagementController extends AbstractManagementController { return clusterManagementService.list(filter); } - @ApiOperation(value = "get region", + @io.swagger.v3.oas.annotations.Operation(summary = "get region", extensions = {@Extension(properties = { @ExtensionProperty(name = "jqFilter", value = ".result | .groups[] | .runtimeInfo[] + .configuration | {name:.name,type:.type,entryCount:.entryCount}")})}) @@ -98,7 +97,7 @@ public class RegionManagementController extends AbstractManagementController { return clusterManagementService.get(config); } - @ApiOperation(value = "delete region") + @io.swagger.v3.oas.annotations.Operation(summary = "delete region") @PreAuthorize("@securityService.authorize('DATA', 'MANAGE')") @DeleteMapping(REGION_CONFIG_ENDPOINT + "/{id:.+}") public ClusterManagementResult deleteRegion( @@ -112,7 +111,7 @@ public class RegionManagementController extends AbstractManagementController { return clusterManagementService.delete(config); } - @ApiOperation(value = "list region indexes", + @io.swagger.v3.oas.annotations.Operation(summary = "list region indexes", extensions = {@Extension(properties = { @ExtensionProperty(name = "jqFilter", value = ".result[] | .groups[] | .configuration | {name:.name,expression:.expression}")})}) @@ -130,7 +129,7 @@ public class RegionManagementController extends AbstractManagementController { return clusterManagementService.list(filter); } - @ApiOperation(value = "list indexes", + @io.swagger.v3.oas.annotations.Operation(summary = "list indexes", extensions = {@Extension(properties = { @ExtensionProperty(name = "jqFilter", value = ".result[] | .groups[] | .configuration | {name:.name,expression:.expression,regionPath:.regionPath}")})}) @@ -145,7 +144,7 @@ public class RegionManagementController extends AbstractManagementController { return clusterManagementService.list(filter); } - @ApiOperation(value = "get index", + @io.swagger.v3.oas.annotations.Operation(summary = "get index", extensions = {@Extension(properties = { @ExtensionProperty(name = "jqFilter", value = ".result | .groups[] | .configuration | {name:.name,expression:.expression}")})}) @@ -161,11 +160,11 @@ public class RegionManagementController extends AbstractManagementController { return clusterManagementService.get(filter); } - @ApiOperation(value = "create index") + @io.swagger.v3.oas.annotations.Operation(summary = "create index") @ApiResponses({ - @ApiResponse(code = 400, message = "Bad request."), - @ApiResponse(code = 409, message = "Index already exists."), - @ApiResponse(code = 500, message = "Internal error.")}) + @ApiResponse(responseCode = "400", description = "Bad request."), + @ApiResponse(responseCode = "409", description = "Index already exists."), + @ApiResponse(responseCode = "500", description = "Internal error.")}) @PreAuthorize("@securityService.authorize('CLUSTER', 'MANAGE', 'QUERY')") @PostMapping(INDEXES) public ResponseEntity<ClusterManagementResult> createIndex( @@ -176,11 +175,11 @@ public class RegionManagementController extends AbstractManagementController { HttpStatus.CREATED); } - @ApiOperation(value = "create region index") + @io.swagger.v3.oas.annotations.Operation(summary = "create region index") @ApiResponses({ - @ApiResponse(code = 400, message = "Bad request."), - @ApiResponse(code = 409, message = "Index already exists."), - @ApiResponse(code = 500, message = "Internal error.")}) + @ApiResponse(responseCode = "400", description = "Bad request."), + @ApiResponse(responseCode = "409", description = "Index already exists."), + @ApiResponse(responseCode = "500", description = "Internal error.")}) @PreAuthorize("@securityService.authorize('CLUSTER', 'MANAGE', 'QUERY')") @PostMapping(REGION_CONFIG_ENDPOINT + "/{regionName}" + INDEXES) public ResponseEntity<ClusterManagementResult> createIndexOnRegion( @@ -197,7 +196,7 @@ public class RegionManagementController extends AbstractManagementController { HttpStatus.CREATED); } - @ApiOperation(value = "delete region index") + @io.swagger.v3.oas.annotations.Operation(summary = "delete region index") @PreAuthorize("@securityService.authorize('CLUSTER', 'MANAGE', 'QUERY')") @DeleteMapping(REGION_CONFIG_ENDPOINT + "/{regionName}" + INDEXES + "/{indexName:.+}") public ClusterManagementResult deleteIndex( diff --git a/geode-web-management/src/main/java/org/apache/geode/management/internal/rest/controllers/RestoreRedundancyOperationController.java b/geode-web-management/src/main/java/org/apache/geode/management/internal/rest/controllers/RestoreRedundancyOperationController.java index 5f1ece4511..0e50b40e0e 100644 --- a/geode-web-management/src/main/java/org/apache/geode/management/internal/rest/controllers/RestoreRedundancyOperationController.java +++ b/geode-web-management/src/main/java/org/apache/geode/management/internal/rest/controllers/RestoreRedundancyOperationController.java @@ -21,7 +21,7 @@ import static org.apache.geode.management.operation.RestoreRedundancyRequest.RES import java.util.Optional; -import io.swagger.annotations.ApiOperation; +import io.swagger.v3.oas.annotations.Operation; import org.springframework.http.HttpStatus; import org.springframework.http.ResponseEntity; import org.springframework.security.access.prepost.PreAuthorize; @@ -41,7 +41,7 @@ import org.apache.geode.management.runtime.RestoreRedundancyResults; @RestController("restoreRedundancyOperation") @RequestMapping(URI_VERSION) public class RestoreRedundancyOperationController extends AbstractManagementController { - @ApiOperation(value = "start restore-redundancy") + @Operation(summary = "start restore-redundancy") @PreAuthorize("@securityService.authorize('DATA', 'MANAGE')") @PostMapping(RESTORE_REDUNDANCY_ENDPOINT) public ResponseEntity<ClusterManagementOperationResult<RestoreRedundancyRequest, RestoreRedundancyResults>> startRestoreRedundancy( @@ -55,14 +55,14 @@ public class RestoreRedundancyOperationController extends AbstractManagementCont return new ResponseEntity<>(result, HttpStatus.ACCEPTED); } - @ApiOperation(value = "list restore-redundancy") + @Operation(summary = "list restore-redundancy") @PreAuthorize("@securityService.authorize('DATA', 'MANAGE')") @GetMapping(RESTORE_REDUNDANCY_ENDPOINT) public ClusterManagementListOperationsResult<RestoreRedundancyRequest, RestoreRedundancyResults> listRestoreRedundancies() { return clusterManagementService.list(new RestoreRedundancyRequest()); } - @ApiOperation(value = "get restore-redundancy") + @Operation(summary = "get restore-redundancy") @PreAuthorize("@securityService.authorize('DATA', 'MANAGE')") @GetMapping(RESTORE_REDUNDANCY_ENDPOINT + "/{id:.+}") public ClusterManagementOperationResult<RestoreRedundancyRequest, RestoreRedundancyResults> getRestoreRedundancy( diff --git a/geode-web-management/src/main/java/org/apache/geode/management/internal/rest/security/RestSecurityConfiguration.java b/geode-web-management/src/main/java/org/apache/geode/management/internal/rest/security/RestSecurityConfiguration.java index e543da3d16..237bb225f1 100644 --- a/geode-web-management/src/main/java/org/apache/geode/management/internal/rest/security/RestSecurityConfiguration.java +++ b/geode-web-management/src/main/java/org/apache/geode/management/internal/rest/security/RestSecurityConfiguration.java @@ -59,7 +59,7 @@ public class RestSecurityConfiguration extends WebSecurityConfigurerAdapter { private ObjectMapper objectMapper; @Override - protected void configure(AuthenticationManagerBuilder auth) throws Exception { + protected void configure(AuthenticationManagerBuilder auth) { auth.authenticationProvider(authProvider); } @@ -88,8 +88,8 @@ public class RestSecurityConfiguration extends WebSecurityConfigurerAdapter { protected void configure(HttpSecurity http) throws Exception { http.sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS).and() .authorizeRequests() - .antMatchers("/docs/**", "/swagger-ui.html", "/", - Links.URI_VERSION + "/api-docs/**", "/webjars/springfox-swagger-ui/**", + .antMatchers("/docs/**", "/swagger-ui.html", "/swagger-ui/index.html", "/", + Links.URI_VERSION + "/api-docs/**", "/webjars/springdoc-openapi-ui/**", "/swagger-resources/**") .permitAll() .and().csrf().disable(); diff --git a/geode-web-management/src/main/java/org/apache/geode/management/internal/rest/swagger/SwaggerConfig.java b/geode-web-management/src/main/java/org/apache/geode/management/internal/rest/swagger/SwaggerConfig.java index ea9bea452e..a98a587bf9 100644 --- a/geode-web-management/src/main/java/org/apache/geode/management/internal/rest/swagger/SwaggerConfig.java +++ b/geode-web-management/src/main/java/org/apache/geode/management/internal/rest/swagger/SwaggerConfig.java @@ -14,41 +14,35 @@ */ package org.apache.geode.management.internal.rest.swagger; -import java.util.ArrayList; -import java.util.List; +import java.util.HashMap; +import java.util.Map; +import io.swagger.v3.oas.models.OpenAPI; +import io.swagger.v3.oas.models.info.Contact; +import io.swagger.v3.oas.models.info.Info; +import io.swagger.v3.oas.models.info.License; +import org.springdoc.core.GroupedOpenApi; import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.autoconfigure.SpringBootApplication; +import org.springframework.boot.autoconfigure.ldap.LdapAutoConfiguration; +import org.springframework.boot.autoconfigure.transaction.TransactionAutoConfiguration; import org.springframework.context.annotation.Bean; -import org.springframework.context.annotation.Configuration; import org.springframework.context.annotation.PropertySource; -import springfox.documentation.builders.ApiInfoBuilder; -import springfox.documentation.builders.PathSelectors; -import springfox.documentation.builders.RequestHandlerSelectors; -import springfox.documentation.service.ApiInfo; -import springfox.documentation.service.Contact; -import springfox.documentation.service.StringVendorExtension; -import springfox.documentation.service.VendorExtension; -import springfox.documentation.spi.DocumentationType; -import springfox.documentation.spring.web.plugins.Docket; -import springfox.documentation.swagger2.annotations.EnableSwagger2; import org.apache.geode.management.internal.rest.security.GeodeAuthenticationProvider; @PropertySource({"classpath:swagger-management.properties"}) -@Configuration -@EnableSwagger2 +@SpringBootApplication(exclude = {TransactionAutoConfiguration.class, LdapAutoConfiguration.class}) @SuppressWarnings("unused") public class SwaggerConfig { @Bean - public Docket api() { - return new Docket(DocumentationType.SWAGGER_2) - .select() - .apis(RequestHandlerSelectors.any()) - .paths(PathSelectors.any()) - .build() - .apiInfo(apiInfo()); + public GroupedOpenApi api() { + return GroupedOpenApi.builder() + .group("management-api") + .pathsToMatch("/**") + .build(); } @Autowired @@ -57,23 +51,21 @@ public class SwaggerConfig { /** * API Info as it appears on the Swagger-UI page */ - private ApiInfo apiInfo() { - List<VendorExtension> extensions = new ArrayList<>(); - VendorExtension<String> authInfo = new StringVendorExtension("authTokenEnabled", + @Bean + public OpenAPI apiInfo() { + Map<String, Object> extensions = new HashMap<>(); + extensions.put("authTokenEnabled", Boolean.toString(authProvider.isAuthTokenEnabled())); - extensions.add(authInfo); - return new ApiInfoBuilder() - .title("Apache Geode Management REST API") - .description( - "REST API to manage Geode. This is experimental. All request/response formats are subject to change.") - .version("v1") - .extensions(extensions) - .termsOfServiceUrl("http://www.apache.org/licenses/") - .license("Apache License, version 2.0") - .licenseUrl("http://www.apache.org/licenses/") - .contact(new Contact("the Apache Geode Community", - "http://geode.apache.org", - "u...@geode.apache.org")) - .build(); + return new OpenAPI() + .info(new Info().title("Apache Geode Management REST API") + .description( + "REST API to manage Geode. This is experimental. All request/response formats are subject to change.") + .version("v1") + .extensions(extensions) + .termsOfService("http://www.apache.org/licenses/") + .license(new License().name("Apache License, version 2.0") + .url("http://www.apache.org/licenses/")) + .contact(new Contact().name("the Apache Geode Community").url("http://geode.apache.org") + .email("u...@geode.apache.org"))); } } diff --git a/geode-web-management/src/main/resources/swagger-management.properties b/geode-web-management/src/main/resources/swagger-management.properties index 3ac097d058..332dd37f70 100644 --- a/geode-web-management/src/main/resources/swagger-management.properties +++ b/geode-web-management/src/main/resources/swagger-management.properties @@ -12,4 +12,5 @@ # or implied. See the License for the specific language governing permissions and limitations under # the License. # -springfox.documentation.swagger.v2.path=/v1/api-docs \ No newline at end of file +springdoc.api-docs.path=/v1/api-docs +springdoc.swagger-ui.path=/swagger-ui.html \ No newline at end of file diff --git a/geode-web-management/src/main/webapp/WEB-INF/management-servlet.xml b/geode-web-management/src/main/webapp/WEB-INF/management-servlet.xml index 4778676bce..9115b3b7e9 100644 --- a/geode-web-management/src/main/webapp/WEB-INF/management-servlet.xml +++ b/geode-web-management/src/main/webapp/WEB-INF/management-servlet.xml @@ -44,6 +44,7 @@ <mvc:default-servlet-handler/> <bean id="contentNegotiationManager" class="org.springframework.web.accept.ContentNegotiationManagerFactoryBean" + autowire-candidate="false" p:favorPathExtension="true" p:favorParameter="false" p:ignoreAcceptHeader="false"