You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@brooklyn.apache.org by he...@apache.org on 2021/12/03 12:39:34 UTC

[brooklyn-server] branch master updated: Fixes race where multiple RestApiResourceScanner created

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 d867ba0  Fixes race where multiple RestApiResourceScanner created
     new b11240c  This closes #1281
d867ba0 is described below

commit d867ba0a0c8cc979efd9ea72bd5bff688d8ce658
Author: Andrew Donald Kennedy <an...@gmail.com>
AuthorDate: Fri Dec 3 12:22:42 2021 +0000

    Fixes race where multiple RestApiResourceScanner created
    
    Signed-off-by: Andrew Donald Kennedy <an...@gmail.com>
---
 .../brooklyn/rest/util/ScannerInjectHelper.java    | 14 ++------
 .../rest/apidoc/RestApiResourceScanner.java        | 38 ++++++++++++++--------
 2 files changed, 27 insertions(+), 25 deletions(-)

diff --git a/rest/rest-resources/src/main/java/org/apache/brooklyn/rest/util/ScannerInjectHelper.java b/rest/rest-resources/src/main/java/org/apache/brooklyn/rest/util/ScannerInjectHelper.java
index e65783d..55c81c8 100644
--- a/rest/rest-resources/src/main/java/org/apache/brooklyn/rest/util/ScannerInjectHelper.java
+++ b/rest/rest-resources/src/main/java/org/apache/brooklyn/rest/util/ScannerInjectHelper.java
@@ -1,5 +1,5 @@
 /*
- * Copyright 2015 The Apache Software Foundation.
+ * Copyright 2015-2021 The Apache Software Foundation.
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -15,21 +15,11 @@
  */
 package org.apache.brooklyn.rest.util;
 
-import io.swagger.jaxrs.config.SwaggerContextService;
-import io.swagger.jaxrs.config.SwaggerScannerLocator;
 import org.apache.brooklyn.rest.apidoc.RestApiResourceScanner;
 import org.apache.cxf.jaxrs.JAXRSServerFactoryBean;
 
-import io.swagger.config.ScannerFactory;
-
 public class ScannerInjectHelper {
     public void setServer(JAXRSServerFactoryBean server) {
-        RestApiResourceScanner scanner = new RestApiResourceScanner(server.getResourceClasses());
-        ScannerFactory.setScanner(scanner);
-        // Above method broken in Swagger 1.6.2:
-        // In Swagger 1.6.2 the method SwaggerContextService.getScanner calls to ScannerFactory.getScanner() only
-        // when SwaggerScannerLocator.getInstance().getScanner(scannerIdKey) == null, but seeing its implementations,
-        // it's impossible to get a null value, so we need to use SwaggerScannerLocator instead.
-        SwaggerScannerLocator.getInstance().putScanner(SwaggerContextService.SCANNER_ID_DEFAULT, scanner);
+        RestApiResourceScanner.install(server.getResourceClasses());
     }
 }
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 cf9c9c4..336e833 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
@@ -1,5 +1,5 @@
 /*
- * Copyright 2015 The Apache Software Foundation.
+ * Copyright 2015-2021 The Apache Software Foundation.
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -15,18 +15,25 @@
  */
 package org.apache.brooklyn.rest.apidoc;
 
-
-import io.swagger.config.Scanner;
-import io.swagger.config.ScannerFactory;
-import java.util.*;
+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;
 import io.swagger.config.SwaggerConfig;
 import io.swagger.jaxrs.config.AbstractScanner;
 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.Scheme;
 import io.swagger.models.Swagger;
@@ -34,7 +41,6 @@ import io.swagger.models.auth.ApiKeyAuthDefinition;
 import io.swagger.models.auth.BasicAuthDefinition;
 import io.swagger.models.auth.In;
 
-
 /**
  * Scans resources for Swagger API resources. Makes them available to the Swagger scanner.
  * Much like DefaultJaxrsScanner, but looks at annotations of ancestors as well.
@@ -57,9 +63,9 @@ public class RestApiResourceScanner extends AbstractScanner implements JaxrsScan
 
     private final Map<Application,Set<Class<?>>> appCache = new WeakHashMap<>();
 
-    public RestApiResourceScanner() {}
+    private RestApiResourceScanner() {}
 
-    public RestApiResourceScanner(Collection<Class<?>> resourceClasses) {
+    private RestApiResourceScanner(Collection<Class<?>> resourceClasses) {
         addAnnotatedClasses(globalClasses, resourceClasses);
     }
 
@@ -68,7 +74,7 @@ public class RestApiResourceScanner extends AbstractScanner implements JaxrsScan
     }
 
     private void addAnnotatedClasses(Set<Class<?>> output, Collection<Class<?>> classes) {
-        if (classes!=null) {
+        if (classes != null) {
             for (Class<?> clz : classes) {
                 if (clz.getAnnotation(Api.class) != null) {
                     output.add(clz);
@@ -114,7 +120,7 @@ public class RestApiResourceScanner extends AbstractScanner implements JaxrsScan
     @Override
     public Swagger configure(Swagger swagger) {
         swagger.setBasePath("/v1");
-        swagger.setSchemes(Arrays.asList(new Scheme[]{Scheme.HTTPS}));  // only advertise https
+        swagger.setSchemes(Collections.singletonList(Scheme.HTTPS)); // only advertise https
 
         swagger.info(getSwaggerInfo());
 
@@ -134,7 +140,7 @@ public class RestApiResourceScanner extends AbstractScanner implements JaxrsScan
     private Info getSwaggerInfo() {
         Info info = new Info();
         info.setTitle("Apache Brooklyn API");
-        info.setVersion(this.getClass().getPackage()!=null?this.getClass().getPackage().getImplementationVersion():"");
+        info.setVersion(getClass().getPackage() != null ? getClass().getPackage().getImplementationVersion() : "");
         info.setDescription("API specification for Apache Brooklyn");
         return info;
     }
@@ -144,8 +150,8 @@ public class RestApiResourceScanner extends AbstractScanner implements JaxrsScan
         return null;
     }
 
-    /** install this as the scanner which Swagger will use, with the given class also installed */
-    public static void install(Collection<Class<?>> resourceClasses) {
+    /** install this as the scanner which Swagger will use, with the given classes also installed */
+    public static synchronized void install(Collection<Class<?>> resourceClasses) {
         Scanner scanner = ScannerFactory.getScanner();
         if (scanner instanceof RestApiResourceScanner) {
             ((RestApiResourceScanner)scanner).addAnnotatedClasses(resourceClasses);
@@ -153,6 +159,12 @@ public class RestApiResourceScanner extends AbstractScanner implements JaxrsScan
             scanner = new RestApiResourceScanner(resourceClasses);
         }
         ScannerFactory.setScanner(scanner);
+        // Above method broken in Swagger 1.6.2:
+        // In Swagger 1.6.2 the method SwaggerContextService.getScanner calls to ScannerFactory.getScanner() only
+        // when SwaggerScannerLocator.getInstance().getScanner(scannerIdKey) == null, but seeing its implementations,
+        // it's impossible to get a null value, so we need to use SwaggerScannerLocator instead.
+        SwaggerScannerLocator.getInstance().putScanner(SwaggerContextService.SCANNER_ID_DEFAULT, scanner);
+
         ((RestApiResourceScanner)ScannerFactory.getScanner()).scannerDirty = true;
     }