fix ISSUE-361: Pulsar manager's swagger dose not work. (#369)
Fixes #ISSUE-361
### Motivation
Pulsar manager's swagger does not work, so I try to fix this issue.
### Modifications
1. Swagger urls can't be accessed because the interceptors blocked them, so I modified the interceptors to allow swagger urls.
2. I added a swagger configration in `application.properties`, thus, if you want to use swagger in development environment, you can set the value `true`. And if you don't want to enable swagger in production environment, you can set the value `false`.
3. I modified the `SwaggerConfig` class, because swagger need some authorization infomation, otherwise it will receive 401 code in response header.
4. I modified the README.md to show how to use swagger, and added some images in docs.
5. Now the swagger can work correctly.
### Verifying this change
- [x] Make sure that the change passes the `./gradlew build` checks.
diff --git a/docs/img/swagger-authorize.png b/docs/img/swagger-authorize.png
new file mode 100644
index 0000000..a7b3042
--- /dev/null
+++ b/docs/img/swagger-authorize.png
Binary files differ
diff --git a/docs/img/swagger-request-login.png b/docs/img/swagger-request-login.png
new file mode 100644
index 0000000..a54bd99
--- /dev/null
+++ b/docs/img/swagger-request-login.png
Binary files differ
diff --git a/src/README.md b/src/README.md
index 301d9a6..2fbc0b6 100644
--- a/src/README.md
+++ b/src/README.md
@@ -187,6 +187,37 @@
apachepulsar/pulsar-manager:v0.2.0
```
+### Enable swagger UI
+To enable swagger UI, set `swagger.enabled=true` in the `application.properties` file. The default value is `true`.
+
+If you want to disable swagger UI in the production environment, you can set `swagger.enabled=false`.
+
+### How to use swagger to access the API
+1. Enable swagger UI by setting 'swagger.enabled=true' in the `application.properties` file.
+
+2. Visit http://YOUR_BACKEND_SERVICE_HOST:7750/swagger-ui.html
+
+3. Request the login API, use the username and password of the Pulsar Manager to login, copy the `token` of the response header.
+
+ The request body is as follows:
+ ```$xslt
+ {
+ "username": "admin",
+ "password": "apachepulsar"
+ }
+ ```
+ Copy the token of the response header.
+ ![swagger-request-login](../docs/img/swagger-request-login.png)
+
+4. Authorize. Click the `Authorize` button in swagger UI, and then fill in the authorization information of swagger.
+ - environment: the environment name you have configured in Pulsar Manager.
+ - token: the token you have copied in the previous step.
+ - username: the username you login.
+
+ ![swagger-authorize](../docs/img/swagger-authorize.png)
+
+5. Request other APIs.
+
#### Third party login options
```
diff --git a/src/main/java/org/apache/pulsar/manager/interceptor/WebAppConfigurer.java b/src/main/java/org/apache/pulsar/manager/interceptor/WebAppConfigurer.java
index 9637f43..ddfd79f 100644
--- a/src/main/java/org/apache/pulsar/manager/interceptor/WebAppConfigurer.java
+++ b/src/main/java/org/apache/pulsar/manager/interceptor/WebAppConfigurer.java
@@ -29,6 +29,7 @@
@Resource
private AdminHandlerInterceptor adminHandlerInterceptor;
+
@Override
public void addInterceptors(InterceptorRegistry registry) {
registry.addInterceptor(adminHandlerInterceptor).addPathPatterns("/**")
@@ -40,6 +41,14 @@
.excludePathPatterns("/ui")
.excludePathPatterns("/static")
.excludePathPatterns("/error")
+ // swagger
+ .excludePathPatterns("/swagger-ui.html")
+ .excludePathPatterns("/swagger/**")
+ .excludePathPatterns("/swagger-resources/**")
+ .excludePathPatterns("/v2/**")
+ .excludePathPatterns("/webjars/**")
+ .excludePathPatterns("/configuration/**")
+ .excludePathPatterns("/doc.html")
// BKVM
.excludePathPatterns("/bkvm")
;
diff --git a/src/main/java/org/apache/pulsar/manager/swagger/SwaggerConfig.java b/src/main/java/org/apache/pulsar/manager/swagger/SwaggerConfig.java
index 50f87c3..f82af2c 100644
--- a/src/main/java/org/apache/pulsar/manager/swagger/SwaggerConfig.java
+++ b/src/main/java/org/apache/pulsar/manager/swagger/SwaggerConfig.java
@@ -13,34 +13,80 @@
*/
package org.apache.pulsar.manager.swagger;
+import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import springfox.documentation.builders.ApiInfoBuilder;
import springfox.documentation.builders.PathSelectors;
import springfox.documentation.builders.RequestHandlerSelectors;
import springfox.documentation.service.ApiInfo;
+import springfox.documentation.service.ApiKey;
+import springfox.documentation.service.AuthorizationScope;
+import springfox.documentation.service.SecurityReference;
import springfox.documentation.spi.DocumentationType;
+import springfox.documentation.spi.service.contexts.SecurityContext;
import springfox.documentation.spring.web.plugins.Docket;
import springfox.documentation.swagger2.annotations.EnableSwagger2;
+import java.util.ArrayList;
+import java.util.List;
+
/**
* Swagger config class.
*/
@Configuration
@EnableSwagger2
public class SwaggerConfig {
+ public static final String TOKEN = "token";
+ public static final String USERNAME = "username";
+ public static final String ENVIRONMENT = "environment";
+ public static final String HEADER = "header";
+
+ @Value(value = "${swagger.enabled}")
+ private boolean swaggerEnabled;
@Bean
public Docket createRestApi() {
return new Docket(DocumentationType.SWAGGER_2)
+ .enable(swaggerEnabled)
.apiInfo(apiInfo())
.select()
.apis(RequestHandlerSelectors.basePackage("org.apache.pulsar.manager.controller"))
.paths(PathSelectors.any())
- .build();
+ .build()
+ .securitySchemes(securitySchemes())
+ .securityContexts(securityContexts());
}
private ApiInfo apiInfo() {
return new ApiInfoBuilder().title("Pulsar manager custom rest api").version("0.1").build();
}
+
+ private List<ApiKey> securitySchemes() {
+ List<ApiKey> arrayList = new ArrayList();
+ arrayList.add(new ApiKey(TOKEN, TOKEN, HEADER));
+ arrayList.add(new ApiKey(USERNAME, USERNAME, HEADER));
+ arrayList.add(new ApiKey(ENVIRONMENT, ENVIRONMENT, HEADER));
+ return arrayList;
+ }
+
+ private List<SecurityContext> securityContexts() {
+ List<SecurityContext> securityContextsList = new ArrayList();
+ securityContextsList.add(SecurityContext.builder()
+ .securityReferences(defaultAuth())
+ .forPaths(PathSelectors.regex("/.*"))
+ .build());
+ return securityContextsList;
+ }
+
+ private List<SecurityReference> defaultAuth() {
+ AuthorizationScope authorizationScope = new AuthorizationScope("global", "accessEverything");
+ AuthorizationScope[] authorizationScopes = new AuthorizationScope[1];
+ authorizationScopes[0] = authorizationScope;
+ List<SecurityReference> defaultAuthList = new ArrayList<>();
+ defaultAuthList.add(new SecurityReference(TOKEN, authorizationScopes));
+ defaultAuthList.add(new SecurityReference(USERNAME, authorizationScopes));
+ defaultAuthList.add(new SecurityReference(ENVIRONMENT, authorizationScopes));
+ return defaultAuthList;
+ }
}
diff --git a/src/main/resources/application.properties b/src/main/resources/application.properties
index 31a07b1..282391b 100644
--- a/src/main/resources/application.properties
+++ b/src/main/resources/application.properties
@@ -153,3 +153,6 @@
# support peek message, default false
pulsar.peek.message=false
+
+# swagger configration
+swagger.enabled=false