This is an automated email from the ASF dual-hosted git repository.
Jackie-Jiang pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/pinot.git
The following commit(s) were added to refs/heads/master by this push:
new 00d1c88763d Expose authorization header in Swagger API docs (#18974)
00d1c88763d is described below
commit 00d1c88763d4015b9ce966ad7c13a52abf30f9b2
Author: deepinsight coder <[email protected]>
AuthorDate: Thu Jul 16 15:10:48 2026 -0700
Expose authorization header in Swagger API docs (#18974)
---
.../pinot/common/swagger/SwaggerSetupUtils.java | 44 ++++++++++++----
.../common/swagger/SwaggerSetupUtilsTest.java | 61 ++++++++++++++++++++++
2 files changed, 94 insertions(+), 11 deletions(-)
diff --git
a/pinot-common/src/main/java/org/apache/pinot/common/swagger/SwaggerSetupUtils.java
b/pinot-common/src/main/java/org/apache/pinot/common/swagger/SwaggerSetupUtils.java
index ae97abff6c2..93f3088c0d5 100644
---
a/pinot-common/src/main/java/org/apache/pinot/common/swagger/SwaggerSetupUtils.java
+++
b/pinot-common/src/main/java/org/apache/pinot/common/swagger/SwaggerSetupUtils.java
@@ -18,12 +18,18 @@
*/
package org.apache.pinot.common.swagger;
+import com.google.common.annotations.VisibleForTesting;
import io.swagger.jaxrs.config.BeanConfig;
+import io.swagger.models.SecurityRequirement;
+import io.swagger.models.Swagger;
+import io.swagger.models.auth.ApiKeyAuthDefinition;
+import io.swagger.models.auth.In;
import java.io.InputStream;
import java.net.URL;
import java.net.URLClassLoader;
import java.util.Objects;
import java.util.Properties;
+import javax.ws.rs.core.HttpHeaders;
import org.apache.commons.lang3.StringUtils;
import org.apache.pinot.common.utils.PinotStaticHttpHandler;
import org.apache.pinot.spi.utils.CommonConstants;
@@ -37,6 +43,24 @@ public class SwaggerSetupUtils {
public static void setupSwagger(String componentType, String
resourcePackage, boolean useHttps, String basePath,
HttpServer httpServer) {
+ BeanConfig beanConfig = buildSwaggerConfig(componentType, resourcePackage,
useHttps, basePath);
+ beanConfig.setScan(true);
+
+ ClassLoader classLoader = SwaggerSetupUtils.class.getClassLoader();
+ CLStaticHttpHandler staticHttpHandler = new
CLStaticHttpHandler(classLoader, "/api/");
+ // map both /api and /help to swagger docs. /api because it looks nice.
/help for backward compatibility
+ httpServer.getServerConfiguration().addHttpHandler(staticHttpHandler,
"/api/", "/help/");
+
+ String swaggerVersion = findSwaggerVersion(classLoader);
+ URL swaggerDistLocation = classLoader.getResource(
+ CommonConstants.CONFIG_OF_SWAGGER_RESOURCES_PATH + swaggerVersion
+ "/");
+ CLStaticHttpHandler swaggerDist = new PinotStaticHttpHandler(new
URLClassLoader(new URL[]{swaggerDistLocation}));
+ httpServer.getServerConfiguration().addHttpHandler(swaggerDist,
"/swaggerui-dist/");
+ }
+
+ @VisibleForTesting
+ static BeanConfig buildSwaggerConfig(String componentType, String
resourcePackage, boolean useHttps,
+ String basePath) {
BeanConfig beanConfig = new BeanConfig();
beanConfig.setTitle(String.format("Pinot %s API", componentType));
beanConfig.setDescription(String.format("APIs for accessing Pinot %s
information", componentType));
@@ -50,18 +74,16 @@ public class SwaggerSetupUtils {
}
beanConfig.setBasePath(basePath);
beanConfig.setResourcePackage(resourcePackage);
- beanConfig.setScan(true);
-
- ClassLoader classLoader = SwaggerSetupUtils.class.getClassLoader();
- CLStaticHttpHandler staticHttpHandler = new
CLStaticHttpHandler(classLoader, "/api/");
- // map both /api and /help to swagger docs. /api because it looks nice.
/help for backward compatibility
- httpServer.getServerConfiguration().addHttpHandler(staticHttpHandler,
"/api/", "/help/");
+ addAuthorizationHeaderSecurity(beanConfig.getSwagger());
+ return beanConfig;
+ }
- String swaggerVersion = findSwaggerVersion(classLoader);
- URL swaggerDistLocation = classLoader.getResource(
- CommonConstants.CONFIG_OF_SWAGGER_RESOURCES_PATH + swaggerVersion
+ "/");
- CLStaticHttpHandler swaggerDist = new PinotStaticHttpHandler(new
URLClassLoader(new URL[]{swaggerDistLocation}));
- httpServer.getServerConfiguration().addHttpHandler(swaggerDist,
"/swaggerui-dist/");
+ private static void addAuthorizationHeaderSecurity(Swagger swagger) {
+ ApiKeyAuthDefinition authorizationHeader =
+ new ApiKeyAuthDefinition(HttpHeaders.AUTHORIZATION, In.HEADER);
+ authorizationHeader.setDescription("Pinot authentication token. Use
\"Basic <token>\" or \"Bearer <token>\".");
+ swagger.securityDefinition(CommonConstants.SWAGGER_AUTHORIZATION_KEY,
authorizationHeader);
+ swagger.security(new
SecurityRequirement().requirement(CommonConstants.SWAGGER_AUTHORIZATION_KEY));
}
private static String findSwaggerVersion(ClassLoader classLoader) {
diff --git
a/pinot-common/src/test/java/org/apache/pinot/common/swagger/SwaggerSetupUtilsTest.java
b/pinot-common/src/test/java/org/apache/pinot/common/swagger/SwaggerSetupUtilsTest.java
new file mode 100644
index 00000000000..e19685f53a8
--- /dev/null
+++
b/pinot-common/src/test/java/org/apache/pinot/common/swagger/SwaggerSetupUtilsTest.java
@@ -0,0 +1,61 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.pinot.common.swagger;
+
+import io.swagger.jaxrs.config.BeanConfig;
+import io.swagger.models.SecurityRequirement;
+import io.swagger.models.Swagger;
+import io.swagger.models.auth.ApiKeyAuthDefinition;
+import io.swagger.models.auth.In;
+import io.swagger.models.auth.SecuritySchemeDefinition;
+import java.util.List;
+import java.util.Map;
+import javax.ws.rs.core.HttpHeaders;
+import org.apache.pinot.spi.utils.CommonConstants;
+import org.testng.Assert;
+import org.testng.annotations.Test;
+
+
+public class SwaggerSetupUtilsTest {
+ @Test
+ public void
testBuildSwaggerConfigAddsAuthorizationHeaderSecurityDefinition() {
+ BeanConfig beanConfig =
+ SwaggerSetupUtils.buildSwaggerConfig("Controller",
"org.apache.pinot.common.swagger", false, "/");
+ beanConfig.setScan(true);
+ Swagger swagger = beanConfig.getSwagger();
+
+ Map<String, SecuritySchemeDefinition> securityDefinitions =
swagger.getSecurityDefinitions();
+ Assert.assertNotNull(securityDefinitions);
+ Assert.assertFalse(securityDefinitions.isEmpty());
+ SecuritySchemeDefinition securityDefinition =
securityDefinitions.get(CommonConstants.SWAGGER_AUTHORIZATION_KEY);
+ Assert.assertTrue(securityDefinition instanceof ApiKeyAuthDefinition);
+
+ ApiKeyAuthDefinition apiKeyAuthDefinition = (ApiKeyAuthDefinition)
securityDefinition;
+ Assert.assertEquals(apiKeyAuthDefinition.getName(),
HttpHeaders.AUTHORIZATION);
+ Assert.assertEquals(apiKeyAuthDefinition.getIn(), In.HEADER);
+ Assert.assertEquals(apiKeyAuthDefinition.getType(), "apiKey");
+
+ List<SecurityRequirement> securityRequirements = swagger.getSecurity();
+ Assert.assertNotNull(securityRequirements);
+ Assert.assertEquals(securityRequirements.size(), 1);
+ Map<String, List<String>> requirements =
securityRequirements.get(0).getRequirements();
+
Assert.assertTrue(requirements.containsKey(CommonConstants.SWAGGER_AUTHORIZATION_KEY));
+
Assert.assertTrue(requirements.get(CommonConstants.SWAGGER_AUTHORIZATION_KEY).isEmpty());
+ }
+}
---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]