[java-plugin-shibd] branch main updated: JSHIBD-7 - Decompose Application layer to avoid protocol dependencies

Codeberg noreply at shibboleth.net
Thu Feb 5 19:36:36 UTC 2026


This is an automated email from the git hooks/post-receive script.

codeberg pushed a commit to branch main
in repository java-plugin-shibd.

View the commit online:
https://codeberg.org/Shibboleth/java-plugin-shibd/commit/572f46fbb6f169b8376c461f15ab254f3f09a293

The following commit(s) were added to refs/heads/main by this push:
     new 572f46f  JSHIBD-7 - Decompose Application layer to avoid protocol dependencies
572f46f is described below

commit 572f46fbb6f169b8376c461f15ab254f3f09a293
Author: Scott Cantor <cantor.2 at osu.edu>
AuthorDate: Thu Feb 5 14:30:25 2026 -0500

    JSHIBD-7 - Decompose Application layer to avoid protocol dependencies
    
    https://shibboleth.atlassian.net/browse/JSHIBD-7
    
    Moved MetadataResolver into new protocol service API layer.
---
 .../net/shibboleth/sp/conf/agents-system.xml       |  1 -
 sp-server-api/pom.xml                              | 10 ---
 .../main/java/net/shibboleth/sp/Application.java   | 21 +++---
 .../net/shibboleth/sp/ProtocolSupportService.java  |  3 +-
 .../ApplicationMetadataResolverLookupFunction.java | 68 ------------------
 .../net/shibboleth/sp/impl/BasicApplication.java   | 81 +++++++++++++---------
 .../impl/InitializeAgentRequestContextTest.java    |  1 -
 .../sp/profile/impl/BaseAgentRequestTest.java      |  1 -
 8 files changed, 63 insertions(+), 123 deletions(-)

diff --git a/sp-conf-impl/src/main/resources/net/shibboleth/sp/conf/agents-system.xml b/sp-conf-impl/src/main/resources/net/shibboleth/sp/conf/agents-system.xml
index e344528..b704d0e 100644
--- a/sp-conf-impl/src/main/resources/net/shibboleth/sp/conf/agents-system.xml
+++ b/sp-conf-impl/src/main/resources/net/shibboleth/sp/conf/agents-system.xml
@@ -53,7 +53,6 @@
         p:allowInheritance="false"
         p:metricName="net.shibboleth.sp.relyingparty.configurations"
         p:authenticatingAuthority="%{sp.defaultAuthority:}"
-        p:metadataResolver-ref="shibboleth.MetadataResolverService"
         p:attributeTranscoderRegistry-ref="shibboleth.AttributeRegistryService"
         p:attributeResolver-ref="shibboleth.AttributeResolverService"
         p:attributeFilter-ref="shibboleth.AttributeFilterService"
diff --git a/sp-server-api/pom.xml b/sp-server-api/pom.xml
index 1a657cb..7ece971 100644
--- a/sp-server-api/pom.xml
+++ b/sp-server-api/pom.xml
@@ -45,16 +45,6 @@
             <artifactId>shib-attribute-filter-api</artifactId>
             <scope>provided</scope>
         </dependency>
-        <dependency>
-            <groupId>${shib-metadata.groupId}</groupId>
-            <artifactId>shib-metadata-api</artifactId>
-            <scope>provided</scope>
-        </dependency>
-        <dependency>
-            <groupId>${shib-metadata.groupId}</groupId>
-            <artifactId>shib-metadata-impl</artifactId>
-            <scope>provided</scope>
-        </dependency>
 
         <dependency>
             <groupId>${shib-shared.groupId}</groupId>
diff --git a/sp-server-api/src/main/java/net/shibboleth/sp/Application.java b/sp-server-api/src/main/java/net/shibboleth/sp/Application.java
index 0c75df6..4cdfd61 100644
--- a/sp-server-api/src/main/java/net/shibboleth/sp/Application.java
+++ b/sp-server-api/src/main/java/net/shibboleth/sp/Application.java
@@ -23,7 +23,6 @@ import javax.annotation.concurrent.ThreadSafe;
 
 import org.opensaml.profile.context.ProfileRequestContext;
 import org.opensaml.profile.criterion.ProfileRequestContextCriterion;
-import org.opensaml.saml.metadata.resolver.MetadataResolver;
 
 import net.shibboleth.idp.attribute.filter.AttributeFilter;
 import net.shibboleth.idp.attribute.resolver.AttributeResolver;
@@ -100,13 +99,6 @@ public interface Application extends RelyingPartyConfigurationResolver {
      * @return the manager to use
      */
     @Nonnull StateTokenManager getStateTokenManager();
-    
-    /**
-     * Gets {@link MetadataResolver} for this {@link Application}.
-     * 
-     * @return the metadata source to use
-     */
-    @Nonnull ReloadableService<MetadataResolver> getMetadataResolver();
 
     /**
      * Gets {@link AttributeTranscoderRegistry} for this {@link Application}.
@@ -128,5 +120,16 @@ public interface Application extends RelyingPartyConfigurationResolver {
      * @return the attribute filter to use
      */
     @Nonnull ReloadableService<AttributeFilter> getAttributeFilter();
-
+    
+    /**
+     * Gets the {@link ProtocolSupportService} subtype for a particular protocol.
+     * 
+     * @param protocol protocol to fetch
+     * @param claz type to fetch
+     * 
+     * @return the corresponding service object or null
+     */
+    @Nullable <T extends ProtocolSupportService> T getProtocolSupportService(@Nonnull @NotEmpty final String protocol,
+            @Nonnull final Class<T> claz);
+    
 }
\ No newline at end of file
diff --git a/sp-server-api/src/main/java/net/shibboleth/sp/ProtocolSupportService.java b/sp-server-api/src/main/java/net/shibboleth/sp/ProtocolSupportService.java
index 0b8873b..e91497c 100644
--- a/sp-server-api/src/main/java/net/shibboleth/sp/ProtocolSupportService.java
+++ b/sp-server-api/src/main/java/net/shibboleth/sp/ProtocolSupportService.java
@@ -23,6 +23,7 @@ import net.shibboleth.profile.config.ProfileConfiguration;
 import net.shibboleth.shared.annotation.constraint.NotLive;
 import net.shibboleth.shared.annotation.constraint.Unmodifiable;
 import net.shibboleth.shared.component.IdentifiedComponent;
+import net.shibboleth.shared.component.InitializableComponent;
 
 /**
  * This is an interface to a plugin-provided infrastructure bean that will be auto-wired
@@ -33,7 +34,7 @@ import net.shibboleth.shared.component.IdentifiedComponent;
  * Agents will implement an instance of this interface to expose their specifics for use
  * by the protocol-independent classes in this plugin.</p>
  */
-public interface ProtocolSupportService extends IdentifiedComponent {
+public interface ProtocolSupportService extends IdentifiedComponent, InitializableComponent {
 
     /**
      * Gets a default-ordered list of session initiator flows supported by this protocol plugin.
diff --git a/sp-server-api/src/main/java/net/shibboleth/sp/profile/context/navigate/messaging/ApplicationMetadataResolverLookupFunction.java b/sp-server-api/src/main/java/net/shibboleth/sp/profile/context/navigate/messaging/ApplicationMetadataResolverLookupFunction.java
deleted file mode 100644
index ed32fe3..0000000
--- a/sp-server-api/src/main/java/net/shibboleth/sp/profile/context/navigate/messaging/ApplicationMetadataResolverLookupFunction.java
+++ /dev/null
@@ -1,68 +0,0 @@
-/*
- * Licensed 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 net.shibboleth.sp.profile.context.navigate.messaging;
-
-import javax.annotation.Nonnull;
-import javax.annotation.Nullable;
-
-import org.opensaml.messaging.context.MessageContext;
-import org.opensaml.saml.metadata.resolver.MetadataResolver;
-import org.opensaml.saml.metadata.resolver.RoleDescriptorResolver;
-import org.opensaml.saml.metadata.resolver.impl.PredicateRoleDescriptorResolver;
-import org.slf4j.Logger;
-
-import net.shibboleth.idp.saml.metadata.impl.ReloadableMetadataResolver;
-import net.shibboleth.shared.component.ComponentInitializationException;
-import net.shibboleth.shared.primitive.LoggerFactory;
-import net.shibboleth.sp.Application;
-import net.shibboleth.sp.context.AgentRequestContext;
-
-/**
- * Locates the {@link MetadataResolver} associated with the {@link Application} making an agent request,
- * and wraps it in a {@link RoleDescriptorResolver}.
- */
-public class ApplicationMetadataResolverLookupFunction
-        extends AbstractAgentRequestLookupFunction<RoleDescriptorResolver> {
-
-    /** Class logger. */
-    @Nonnull private final Logger log = LoggerFactory.getLogger(ApplicationMetadataResolverLookupFunction.class);
-    
-    /** {@inheritDoc} */
-    @Nullable public RoleDescriptorResolver apply(@Nullable final MessageContext input) {
-        final AgentRequestContext arc = getAgentRequestContext(input);
-        if (arc != null) {
-            final Application application = arc.getApplication();
-            if (application != null) {
-                try {
-                    final ReloadableMetadataResolver metadataResolver =
-                            new ReloadableMetadataResolver(application.getMetadataResolver());
-                    metadataResolver.setId(application.getId() + " MetadataResolver");
-                    metadataResolver.initialize();
-                    
-                    final PredicateRoleDescriptorResolver roleResolver =
-                            new PredicateRoleDescriptorResolver(metadataResolver);
-                    roleResolver.initialize();
-                    
-                    return roleResolver;
-                } catch (final ComponentInitializationException e) {
-                    log.error("Exception wrapping Application-supplied MetadataResolver for use", e);
-                }
-            }
-        }
-        
-        return null;
-    }
-
-}
\ No newline at end of file
diff --git a/sp-server-impl/src/main/java/net/shibboleth/sp/impl/BasicApplication.java b/sp-server-impl/src/main/java/net/shibboleth/sp/impl/BasicApplication.java
index 6305d1b..156eb84 100644
--- a/sp-server-impl/src/main/java/net/shibboleth/sp/impl/BasicApplication.java
+++ b/sp-server-impl/src/main/java/net/shibboleth/sp/impl/BasicApplication.java
@@ -17,6 +17,7 @@ package net.shibboleth.sp.impl;
 
 import java.util.ArrayList;
 import java.util.Collection;
+import java.util.HashMap;
 import java.util.List;
 import java.util.Map;
 import java.util.Objects;
@@ -26,7 +27,6 @@ import javax.annotation.Nonnull;
 import javax.annotation.Nullable;
 
 import org.opensaml.profile.context.ProfileRequestContext;
-import org.opensaml.saml.metadata.resolver.MetadataResolver;
 import org.opensaml.security.config.SecurityConfiguration;
 import org.opensaml.security.credential.Credential;
 import org.springframework.beans.factory.annotation.Autowired;
@@ -75,9 +75,12 @@ public class BasicApplication extends BasicRelyingPartyConfiguration implements
     /** Our self-managed "defaults". */
     @NonnullAfterInit private ApplicationAwareRelyingPartyResolver relyingPartyResolver;
     
-    /** Manager of protocol auto-registration options. */
+    /** Manager of protocol auto-registration material. */
     @Nonnull final ProtocolSupportServiceManager protocolServiceManager;
     
+    /** Map of protocol support services. */
+    @Nonnull Map<String,ProtocolSupportService> protocolServiceMap;
+    
     /** Lookup strategy for authenticating authority. */
     @Nonnull private Function<ProfileRequestContext,String> authenticatingAuthorityLookupStrategy;
     
@@ -93,9 +96,6 @@ public class BasicApplication extends BasicRelyingPartyConfiguration implements
     /** State token management. */
     @Nullable private StateTokenManager stateTokenManager;
     
-    /** Metadata source. */
-    @Nullable private ReloadableService<MetadataResolver> metadataResolver;
-    
     /** Transcoding registry. */
     @Nullable private ReloadableService<AttributeTranscoderRegistry> transcodingRegistry;
     
@@ -119,6 +119,13 @@ public class BasicApplication extends BasicRelyingPartyConfiguration implements
         relyingPartyResolver = new ApplicationAwareRelyingPartyResolver();
         relyingPartyResolver.setDefaultConfiguration(this);
         
+        // Populate service map with autowired objects by default.
+        protocolServiceMap = new HashMap<>();
+        for (final ProtocolSupportService service : protocolManager.getComponents()) {
+            assert service != null;
+            protocolServiceMap.put(service.getId(), service);
+        }
+        
         authenticatingAuthorityLookupStrategy = FunctionSupport.constant(null);
         discoveryServiceLookupStrategy = FunctionSupport.constant(null);
     }
@@ -349,31 +356,6 @@ public class BasicApplication extends BasicRelyingPartyConfiguration implements
         
         stateTokenManager = Constraint.isNotNull(manager, "StateTokenManager cannot be null");
     }
-        
-    /** {@inheritDoc} */
-    @Nonnull public ReloadableService<MetadataResolver> getMetadataResolver() {
-        checkComponentActive();
-        if (metadataResolver != null) {
-            return metadataResolver;
-        }
-        
-        if (parent != null && allowInheritance) {
-            return parent.getMetadataResolver();
-        }
-        
-        throw new ConstraintViolationException("MetadataResolver cannot be null");
-    }
-    
-    /**
-     * Set the {@link MetadataResolver} to use.
-     * 
-     * @param service metadata resolver service
-     */
-    public void setMetadataResolver(@Nonnull final ReloadableService<MetadataResolver> service) {
-        checkSetterPreconditions();
-        
-        metadataResolver = Constraint.isNotNull(service, "MetadataResolver service cannot be null");
-    }
 
     /** {@inheritDoc} */
     @Nonnull public ReloadableService<AttributeTranscoderRegistry> getAttributeTranscoderRegistry() {
@@ -450,6 +432,43 @@ public class BasicApplication extends BasicRelyingPartyConfiguration implements
         attributeFilter = Constraint.isNotNull(service, "AttributeFilter service cannot be null");
     }
 
+    
+    /** {@inheritDoc} */
+    @Nullable public <T extends ProtocolSupportService> T getProtocolSupportService(
+            @Nonnull @NotEmpty final String protocol, @Nonnull Class<T> claz) {
+        checkComponentActive();
+        
+        final ProtocolSupportService service = protocolServiceMap.get(protocol);
+        if (claz.isInstance(service)) {
+            return claz.cast(service);
+        }
+        
+        if (parent != null && allowInheritance) {
+            return parent.getProtocolSupportService(protocol, claz);
+        }
+        
+        return null;
+    }
+    
+    /**
+     * Sets overridden {@link ProtocolSupportService} instances for specific protocols.
+     * 
+     * <p>This collection overlays any default-installed instamces so it will merge the overrides into
+     * the default map and leave any other instances alone.</p>
+     * 
+     * @param services service information to override
+     */
+    public void setPeotocolSupportServices(@Nullable final Collection<ProtocolSupportService> services) {
+        checkSetterPreconditions();
+        
+        if (services != null) {
+            for (final ProtocolSupportService service : services) {
+                assert service != null;
+                protocolServiceMap.put(service.getId(), service);
+            }
+        }
+    }
+    
     // Override RelyingPartyConfiguration getters for inheritance purposes.
     
     /** {@inheritDoc} */
@@ -545,8 +564,6 @@ public class BasicApplication extends BasicRelyingPartyConfiguration implements
         
         if (stateTokenManager == null) {
             throw new ComponentInitializationException("StateTokenManager cannot be null");
-        } else if (metadataResolver == null) {
-            throw new ComponentInitializationException("MetadataResolver cannot be null");
         } else if (transcodingRegistry == null) {
             throw new ComponentInitializationException("AttributeTranscoderRegistry cannot be null");
         } else if (attributeResolver == null) {
diff --git a/sp-server-impl/src/test/java/net/shibboleth/sp/authn/impl/InitializeAgentRequestContextTest.java b/sp-server-impl/src/test/java/net/shibboleth/sp/authn/impl/InitializeAgentRequestContextTest.java
index e0bd62b..45101b4 100644
--- a/sp-server-impl/src/test/java/net/shibboleth/sp/authn/impl/InitializeAgentRequestContextTest.java
+++ b/sp-server-impl/src/test/java/net/shibboleth/sp/authn/impl/InitializeAgentRequestContextTest.java
@@ -54,7 +54,6 @@ public class InitializeAgentRequestContextTest {
         
         agent = new BasicAgent(new ProtocolSupportServiceManager(null));
         agent.setId("foo");
-        agent.setMetadataResolver(new MockReloadableService<>(null));
         agent.setAttributeResolver(new MockReloadableService<>(null));
         agent.setAttributeFilter(new MockReloadableService<>(null));
         agent.setAttributeTranscoderRegistry(new MockReloadableService<>(null));
diff --git a/sp-server-impl/src/test/java/net/shibboleth/sp/profile/impl/BaseAgentRequestTest.java b/sp-server-impl/src/test/java/net/shibboleth/sp/profile/impl/BaseAgentRequestTest.java
index 18bf605..92ae364 100644
--- a/sp-server-impl/src/test/java/net/shibboleth/sp/profile/impl/BaseAgentRequestTest.java
+++ b/sp-server-impl/src/test/java/net/shibboleth/sp/profile/impl/BaseAgentRequestTest.java
@@ -49,7 +49,6 @@ public abstract class BaseAgentRequestTest extends OpenSAMLInitBaseTestCase {
         
         agent = new BasicAgent(new ProtocolSupportServiceManager(null));
         agent.setId("test");
-        agent.setMetadataResolver(new MockReloadableService<>(null));
         agent.setAttributeResolver(new MockReloadableService<>(null));
         agent.setAttributeFilter(new MockReloadableService<>(null));
         agent.setAttributeTranscoderRegistry(new MockReloadableService<>(null));

-- 
To stop receiving notification emails like this one, please contact
the administrator of this repository.


More information about the commits mailing list