Inject ServletSupport into KeystoneAuthRealm 18/101718/2
authorRobert Varga <robert.varga@pantheon.tech>
Mon, 4 Jul 2022 11:53:23 +0000 (13:53 +0200)
committerRobert Varga <robert.varga@pantheon.tech>
Mon, 4 Jul 2022 12:10:01 +0000 (14:10 +0200)
Do not rely on jax-rs working, but rather explicitly route to the
provider.

Change-Id: I75306b14d22512984deed91e6799e77956563039
Signed-off-by: Robert Varga <robert.varga@pantheon.tech>
aaa-shiro/impl/src/main/java/org/opendaylight/aaa/shiro/realm/KeystoneAuthRealm.java
aaa-shiro/impl/src/main/java/org/opendaylight/aaa/shiro/web/env/AAAIniWebEnvironment.java
aaa-shiro/impl/src/test/java/org/opendaylight/aaa/shiro/realm/KeystoneAuthRealmTest.java

index 278a5af84afdba9fb967005808c8f833afea9af5..7de57278a83263917843a54787a618195c5355c5 100644 (file)
@@ -21,12 +21,14 @@ import java.net.URISyntaxException;
 import java.net.URL;
 import java.util.Set;
 import java.util.concurrent.TimeUnit;
+import java.util.function.Supplier;
 import java.util.stream.Collectors;
 import javax.net.ssl.HostnameVerifier;
 import javax.net.ssl.HttpsURLConnection;
 import javax.net.ssl.SSLContext;
 import javax.ws.rs.HttpMethod;
 import javax.ws.rs.WebApplicationException;
+import javax.ws.rs.client.ClientBuilder;
 import javax.ws.rs.core.MediaType;
 import org.apache.shiro.authc.AuthenticationException;
 import org.apache.shiro.authc.AuthenticationInfo;
@@ -46,6 +48,7 @@ import org.opendaylight.aaa.shiro.principal.ODLPrincipalImpl;
 import org.opendaylight.aaa.shiro.realm.util.http.SimpleHttpClient;
 import org.opendaylight.aaa.shiro.realm.util.http.SimpleHttpRequest;
 import org.opendaylight.aaa.shiro.realm.util.http.UntrustedSSL;
+import org.opendaylight.aaa.web.servlet.ServletSupport;
 import org.opendaylight.yangtools.concepts.Registration;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
@@ -69,11 +72,13 @@ public class KeystoneAuthRealm extends AuthorizingRealm {
     private static final int CLIENT_EXPIRE_AFTER_WRITE = 10;
 
     private static final ThreadLocal<ICertificateManager> CERT_MANAGER_TL = new ThreadLocal<>();
+    private static final ThreadLocal<Supplier<ClientBuilder>> SERVLET_SUPPORT_TL = new ThreadLocal<>();
 
     private volatile URI serverUri = null;
     private volatile boolean sslVerification = true;
     private volatile String defaultDomain = DEFAULT_KEYSTONE_DOMAIN;
 
+    private final Supplier<ClientBuilder> clientBuilderFactory;
     private final ICertificateManager certManager;
     private final LoadingCache<Boolean, SimpleHttpClient> clientCache = CacheBuilder.newBuilder()
         .expireAfterAccess(CLIENT_EXPIRE_AFTER_ACCESS, TimeUnit.SECONDS)
@@ -81,22 +86,34 @@ public class KeystoneAuthRealm extends AuthorizingRealm {
         .build(new CacheLoader<>() {
             @Override
             public SimpleHttpClient load(final Boolean withSslVerification) {
-                return buildClient(withSslVerification, certManager, SimpleHttpClient.clientBuilder());
+                return buildClient(withSslVerification, certManager,
+                    SimpleHttpClient.clientBuilder(clientBuilderFactory.get()));
             }
         });
 
     public KeystoneAuthRealm() {
-        this(verifyNotNull(CERT_MANAGER_TL.get(), "KeystoneAuthRealm loading not prepared"));
+        this(requireThreadLocal(CERT_MANAGER_TL), requireThreadLocal(SERVLET_SUPPORT_TL));
     }
 
-    public KeystoneAuthRealm(final ICertificateManager certManager) {
+    private static <T> T requireThreadLocal(final ThreadLocal<T> threadLocal) {
+        return verifyNotNull(threadLocal.get(), "KeystoneAuthRealm loading not prepared");
+    }
+
+    public KeystoneAuthRealm(final ICertificateManager certManager,
+            final Supplier<ClientBuilder> clientBuilderFactory) {
         this.certManager = requireNonNull(certManager);
+        this.clientBuilderFactory = requireNonNull(clientBuilderFactory);
         LOG.info("KeystoneAuthRealm created");
     }
 
-    public static Registration prepareForLoad(final ICertificateManager certManager) {
+    public static Registration prepareForLoad(final ICertificateManager certManager,
+            final ServletSupport servletSupport) {
         CERT_MANAGER_TL.set(requireNonNull(certManager));
-        return CERT_MANAGER_TL::remove;
+        SERVLET_SUPPORT_TL.set(requireNonNull(servletSupport)::newClientBuilder);
+        return () -> {
+            CERT_MANAGER_TL.remove();
+            SERVLET_SUPPORT_TL.remove();
+        };
     }
 
     @Override
index a5337cba7dfecde6f4994e764f1b5a328b9b89e2..e1a2cededc1eab9f4867d65f3123813f1ebaee5f 100644 (file)
@@ -98,7 +98,7 @@ class AAAIniWebEnvironment extends IniWebEnvironment {
     public void init() {
         try (
             var filterLoad = MDSALDynamicAuthorizationFilter.prepareForLoad(dataBroker);
-            var keyStoneLoad = KeystoneAuthRealm.prepareForLoad(certificateManager);
+            var keyStoneLoad = KeystoneAuthRealm.prepareForLoad(certificateManager, servletSupport);
             var mdsalLoad = MdsalRealm.prepareForLoad(passwordHashService, dataBroker);
             var moonLoad = MoonRealm.prepareForLoad(servletSupport);
             var tokenAuthLoad = TokenAuthRealm.prepareForLoad(authenticationService, tokenAuthenticators, tokenStore)) {
index 81a2b7099348bddb305e505b9026e4b05e39c2c1..5020d22fb5b3b49ca251103e8a375d069a32cada 100644 (file)
@@ -26,6 +26,7 @@ import java.util.stream.Stream;
 import javax.net.ssl.HttpsURLConnection;
 import javax.net.ssl.SSLContext;
 import javax.ws.rs.HttpMethod;
+import javax.ws.rs.client.ClientBuilder;
 import javax.ws.rs.core.MediaType;
 import org.apache.shiro.authc.AuthenticationException;
 import org.apache.shiro.authc.AuthenticationInfo;
@@ -82,7 +83,7 @@ public class KeystoneAuthRealmTest {
 
     @Before
     public void setup() throws MalformedURLException, URISyntaxException {
-        keystoneAuthRealm = spy(new KeystoneAuthRealm(certificateManager));
+        keystoneAuthRealm = spy(new KeystoneAuthRealm(certificateManager, ClientBuilder::newBuilder));
 
         final String testUrl = "http://example.com";