This is an automated email from the ASF dual-hosted git repository.
heneveld pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/brooklyn-server.git
The following commit(s) were added to refs/heads/master by this push:
new 471161db1f provide a way for extended rest endpoints to indicate the
correct path to swagger
471161db1f is described below
commit 471161db1f4c46b9766dde4c06d34039acd9fcdc
Author: Alex Heneveld <[email protected]>
AuthorDate: Mon Jun 17 16:55:45 2024 +0100
provide a way for extended rest endpoints to indicate the correct path to
swagger
without this, swagger looks at the @Path annotation and the basepath,
but that doesn't work for osgi blueprints that have an intermediate path
that is non-empty,
and only one can be installed at the base path.
---
.../rest/apidoc/RestApiResourceScanner.java | 54 +++++++++++++++++-----
1 file changed, 43 insertions(+), 11 deletions(-)
diff --git
a/utils/rest-swagger/src/main/java/org/apache/brooklyn/rest/apidoc/RestApiResourceScanner.java
b/utils/rest-swagger/src/main/java/org/apache/brooklyn/rest/apidoc/RestApiResourceScanner.java
index dc164b0415..be78868fea 100644
---
a/utils/rest-swagger/src/main/java/org/apache/brooklyn/rest/apidoc/RestApiResourceScanner.java
+++
b/utils/rest-swagger/src/main/java/org/apache/brooklyn/rest/apidoc/RestApiResourceScanner.java
@@ -15,17 +15,6 @@
*/
package org.apache.brooklyn.rest.apidoc;
-import java.util.Arrays;
-import java.util.Collection;
-import java.util.Collections;
-import java.util.HashSet;
-import java.util.Map;
-import java.util.Set;
-import java.util.WeakHashMap;
-
-import javax.servlet.ServletConfig;
-import javax.ws.rs.core.Application;
-
import io.swagger.annotations.Api;
import io.swagger.config.Scanner;
import io.swagger.config.ScannerFactory;
@@ -35,6 +24,7 @@ import io.swagger.jaxrs.config.JaxrsScanner;
import io.swagger.jaxrs.config.SwaggerContextService;
import io.swagger.jaxrs.config.SwaggerScannerLocator;
import io.swagger.models.Info;
+import io.swagger.models.Path;
import io.swagger.models.Scheme;
import io.swagger.models.Swagger;
import io.swagger.models.auth.ApiKeyAuthDefinition;
@@ -44,6 +34,18 @@ import io.swagger.models.properties.ArrayProperty;
import io.swagger.models.properties.Property;
import io.swagger.models.properties.RefProperty;
import io.swagger.models.refs.RefFormat;
+import io.swagger.util.ReflectionUtils;
+import java.util.Arrays;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.HashSet;
+import java.util.LinkedHashMap;
+import java.util.Map;
+import java.util.Optional;
+import java.util.Set;
+import java.util.WeakHashMap;
+import javax.servlet.ServletConfig;
+import javax.ws.rs.core.Application;
/**
* Scans resources for Swagger API resources. Makes them available to the
Swagger scanner.
@@ -64,6 +66,7 @@ public class RestApiResourceScanner extends AbstractScanner
implements JaxrsScan
private boolean scannerDirty = true;
private final Set<Class<?>> globalClasses = new HashSet<>();
+ private final Map<Class<?>,String> classExtraPrefixes = new
LinkedHashMap<>();
private final Map<Application,Set<Class<?>>> appCache = new
WeakHashMap<>();
@@ -157,6 +160,27 @@ public class RestApiResourceScanner extends
AbstractScanner implements JaxrsScan
arrayProp.setItems(new RefProperty("#/definitions/TypeToken",
RefFormat.INTERNAL));
}
}
+
+ if (!classExtraPrefixes.isEmpty()) {
+ Map<String, String> extraPrefixesByTag = new LinkedHashMap<>();
+ classExtraPrefixes.forEach((clazz, prefix) -> {
+ Api api = ReflectionUtils.getAnnotation(clazz, Api.class);
+ if (api==null) throw new IllegalStateException("Cannot install
"+clazz+" to REST API doc because it does not define an @Api tag for Swagger.");
+ extraPrefixesByTag.put(api.value(), prefix);
+ });
+ Map<String, Path> oldPaths = swagger.getPaths();
+ Map<String, Path> newPaths = new LinkedHashMap<>();
+ oldPaths.forEach((k, v) -> {
+ Optional<String> prefix = v.getOperations().stream().filter(op
-> op != null).flatMap(op ->
op.getTags().stream().map(extraPrefixesByTag::get).filter(x -> x != null))
+ .findFirst();
+ if (prefix.isPresent()) {
+ newPaths.put("/" + prefix.get() + k, v);
+ } else {
+ newPaths.put(k,v);
+ }
+ });
+ swagger.setPaths(newPaths);
+ }
}
private Info getSwaggerInfo() {
@@ -190,6 +214,14 @@ public class RestApiResourceScanner extends
AbstractScanner implements JaxrsScan
((RestApiResourceScanner)ScannerFactory.getScanner()).scannerDirty =
true;
}
+ /** as {@link #install(Collection)} but for one resource class, with an
extra prefix prepended by Swagger.
+ * this is required because extension REST endpoints usin gan OSGi
blueprint.xml need to specify the subpath relative to the basepath,
+ * so the @Path annotation which Swagger relies upon is not set. */
+ public static synchronized void install(Class<?> resourceClass, String
prefixForClass) {
+ install(Arrays.asList(resourceClass));
+
((RestApiResourceScanner)ScannerFactory.getScanner()).classExtraPrefixes.put(resourceClass,
prefixForClass);
+ }
+
public static void rescanIfNeeded(Runnable r) {
if (ScannerFactory.getScanner() instanceof RestApiResourceScanner &&
((RestApiResourceScanner)ScannerFactory.getScanner()).scannerDirty) {
r.run();