[java-shib-profile] branch main updated: IDP-2118 - Add metrics for request processing

Scott Cantor cantor.2 at osu.edu
Wed May 31 17:56:18 UTC 2023


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

scantor pushed a commit to branch main
in repository java-shib-profile.

View the commit online:
http://git.shibboleth.net/view/?p=java-shib-profile.git;a=commit;h=4f867b5d442787b94c9b5fe01c1828df9e38a1e7

The following commit(s) were added to refs/heads/main by this push:
     new 4f867b5  IDP-2118 - Add metrics for request processing
4f867b5 is described below

commit 4f867b5d442787b94c9b5fe01c1828df9e38a1e7
Author: Scott Cantor <cantor.2 at osu.edu>
AuthorDate: Wed May 31 13:56:16 2023 -0400

    IDP-2118 - Add metrics for request processing
    
    https://shibboleth.atlassian.net/browse/IDP-2118
    
    Cleanup of approach to relying party counters.
    Added counters for non-overrides.
---
 .../DefaultRelyingPartyConfigurationResolver.java  | 94 ++++++++++++++++++----
 1 file changed, 77 insertions(+), 17 deletions(-)

diff --git a/shib-profile-impl/src/main/java/net/shibboleth/profile/relyingparty/impl/DefaultRelyingPartyConfigurationResolver.java b/shib-profile-impl/src/main/java/net/shibboleth/profile/relyingparty/impl/DefaultRelyingPartyConfigurationResolver.java
index d365b9a..ba11f27 100644
--- a/shib-profile-impl/src/main/java/net/shibboleth/profile/relyingparty/impl/DefaultRelyingPartyConfigurationResolver.java
+++ b/shib-profile-impl/src/main/java/net/shibboleth/profile/relyingparty/impl/DefaultRelyingPartyConfigurationResolver.java
@@ -21,6 +21,7 @@ import java.util.ArrayList;
 import java.util.Collection;
 import java.util.HashSet;
 import java.util.List;
+import java.util.Map;
 import java.util.stream.Collectors;
 
 import javax.annotation.Nonnull;
@@ -40,12 +41,14 @@ import org.slf4j.Logger;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.beans.factory.annotation.Qualifier;
 
-import com.codahale.metrics.MetricRegistry;
+import com.codahale.metrics.Counter;
+import com.codahale.metrics.Gauge;
 
 import net.shibboleth.profile.context.RelyingPartyContext;
 import net.shibboleth.profile.relyingparty.RelyingPartyConfiguration;
 import net.shibboleth.profile.relyingparty.RelyingPartyConfigurationResolver;
 import net.shibboleth.profile.relyingparty.VerifiedProfileCriterion;
+import net.shibboleth.shared.annotation.constraint.NotEmpty;
 import net.shibboleth.shared.annotation.constraint.NotLive;
 import net.shibboleth.shared.annotation.constraint.Unmodifiable;
 import net.shibboleth.shared.collection.CollectionSupport;
@@ -79,6 +82,13 @@ import net.shibboleth.spring.security.CredentialHolder;
 public class DefaultRelyingPartyConfigurationResolver extends AbstractIdentifiableInitializableComponent
         implements RelyingPartyConfigurationResolver {
 
+    /** Counter ID for default RP. */
+    @Nonnull @NotEmpty private static final String DEFAULT_RELYING_PARTY_COUNTER = "shibboleth.DefaultRelyingParty";
+
+    /** Counter ID for unverified RP. */
+    @Nonnull @NotEmpty
+    private static final String UNVERIFIED_RELYING_PARTY_COUNTER = "shibboleth.UnverifiedRelyingParty";
+
     /** Class logger. */
     @Nonnull private final Logger log = LoggerFactory.getLogger(DefaultRelyingPartyConfigurationResolver.class);
 
@@ -97,14 +107,21 @@ public class DefaultRelyingPartyConfigurationResolver extends AbstractIdentifiab
     /** The global list of all configured encryption credentials. */
     @Nonnull private List<Credential> encryptionCredentials;
     
-    /** Prefix for counter metric for overrides. */
-    @Nullable private String overrideCounterPrefix;
+    /** Name for counter map metric. */
+    @Nullable private String metricName;
+
+    /** Stored copy of metric for teardown. */
+    @Nullable private Gauge<Map<String,Counter>> counterGauge;
+    
+    /** Map of override counters. */
+    @Nonnull private Map<String,Counter> counterMap;
 
     /** Constructor. */
     public DefaultRelyingPartyConfigurationResolver() {
         rpConfigurations = CollectionSupport.emptyList();
         signingCredentials = CollectionSupport.emptyList();
         encryptionCredentials = CollectionSupport.emptyList();
+        counterMap = CollectionSupport.emptyMap();
     }
     
     /**
@@ -175,17 +192,16 @@ public class DefaultRelyingPartyConfigurationResolver extends AbstractIdentifiab
     }
     
     /**
-     * Set prefix to use for counters maintained when {@link #resolveSingle(CriteriaSet)} returns
-     * an override.
+     * Set name of metric to use for counters to track use of configurations.
      * 
-     * @param prefix counter prefix for override tracking
+     * @param name name for counter metrics
      * 
      * @since 5.0.0
      */
-    public void setOverrideCounterPrefix(@Nullable final String prefix) {
+    public void setMetricName(@Nullable final String name) {
         checkSetterPreconditions();
         
-        overrideCounterPrefix = StringSupport.trimOrNull(prefix);
+        metricName = StringSupport.trimOrNull(name);
     }
 
     /** {@inheritDoc} */
@@ -200,10 +216,41 @@ public class DefaultRelyingPartyConfigurationResolver extends AbstractIdentifiab
             }
             configIds.add(config.getId());
         }
+
+        // Set up counters for metrics, but add the two "other" slots in.
+        configIds.add(DEFAULT_RELYING_PARTY_COUNTER);
+        configIds.add(UNVERIFIED_RELYING_PARTY_COUNTER);
+        
+        final String localMetricName = metricName;
+        if (localMetricName != null && !configIds.isEmpty()) {
+            // Build map of config IDs to counters.
+            counterMap = configIds.stream().collect(
+                    CollectionSupport.nonnullCollector(
+                            Collectors.toUnmodifiableMap(id -> id, id -> new Counter()))).get();
+            // Note that this gauge must use the support method to register in a synchronized fashion,
+            // and also must store off the instance for later use in destroy.
+            counterGauge = MetricsSupport.register(localMetricName,
+                    new Gauge<Map<String, Counter>>() {
+                        public Map<String, Counter> getValue() {
+                            return counterMap;
+                        }
+                    },
+                    true);
+        }
+    }
+    
+    /** {@inheritDoc} */
+    @Override protected void doDestroy() {
+        if (metricName != null && counterGauge != null) {
+            MetricsSupport.remove(metricName, counterGauge);
+        }
+        
+        super.doDestroy();
     }
 
     /** {@inheritDoc} */
-    @Nonnull public Iterable<RelyingPartyConfiguration> resolve(@Nullable final CriteriaSet criteria) throws ResolverException {
+    @Nonnull public Iterable<RelyingPartyConfiguration> resolve(@Nullable final CriteriaSet criteria)
+            throws ResolverException {
         checkComponentActive();
 
         log.debug("Resolving relying party configuration");
@@ -220,6 +267,7 @@ public class DefaultRelyingPartyConfigurationResolver extends AbstractIdentifiab
                 return CollectionSupport.emptyList();
             }
             log.debug("Profile request is unverified, returning configuration {}", uvc.getId());
+            increment(UNVERIFIED_RELYING_PARTY_COUNTER);
             return CollectionSupport.singleton(uvc);
         }
         
@@ -231,6 +279,7 @@ public class DefaultRelyingPartyConfigurationResolver extends AbstractIdentifiab
             log.debug("Checking if relying party configuration {} is applicable", configuration.getId());
             if (configuration.test(context)) {
                 log.debug("Relying party configuration {} is applicable", configuration.getId());
+                increment(configuration.getId());
                 matches.add(configuration);
             } else {
                 log.debug("Relying party configuration {} is not applicable", configuration.getId());
@@ -241,6 +290,7 @@ public class DefaultRelyingPartyConfigurationResolver extends AbstractIdentifiab
             if (defaultRelyingPartyConfiguration != null) {
                 log.debug("No matching relying party configuration applicable, returning default: {}",
                         defaultRelyingPartyConfiguration.getId());
+                increment(DEFAULT_RELYING_PARTY_COUNTER);
                 assert defaultRelyingPartyConfiguration != null;
                 return CollectionSupport.singleton(defaultRelyingPartyConfiguration);
             } else {
@@ -252,7 +302,8 @@ public class DefaultRelyingPartyConfigurationResolver extends AbstractIdentifiab
     }
 
     /** {@inheritDoc} */
-    @Nullable public RelyingPartyConfiguration resolveSingle(@Nullable final CriteriaSet criteria) throws ResolverException {
+    @Nullable public RelyingPartyConfiguration resolveSingle(@Nullable final CriteriaSet criteria)
+            throws ResolverException {
         checkComponentActive();
 
         log.debug("Resolving relying party configuration");
@@ -269,6 +320,7 @@ public class DefaultRelyingPartyConfigurationResolver extends AbstractIdentifiab
                 return null;
             }
             log.debug("Profile request is unverified, returning configuration {}", uvc.getId());
+            increment(UNVERIFIED_RELYING_PARTY_COUNTER);
             return uvc;
         }
 
@@ -278,12 +330,7 @@ public class DefaultRelyingPartyConfigurationResolver extends AbstractIdentifiab
             log.debug("Checking if relying party configuration {} is applicable", configuration.getId());
             if (configuration.test(context)) {
                 log.debug("Relying party configuration {} is applicable", configuration.getId());
-                if (overrideCounterPrefix != null && configuration.getId() != null) {
-                    final MetricRegistry registry = MetricsSupport.getMetricRegistry();
-                    if (registry != null) {
-                        registry.counter(MetricRegistry.name(overrideCounterPrefix, configuration.getId())).inc();
-                    }
-                }
+                increment(configuration.getId());
                 return configuration;
             }
             log.debug("Relying party configuration {} is not applicable", configuration.getId());
@@ -292,6 +339,7 @@ public class DefaultRelyingPartyConfigurationResolver extends AbstractIdentifiab
         if (defaultRelyingPartyConfiguration != null) {
             log.debug("No matching relying party configuration applicable, returning default: {}",
                     defaultRelyingPartyConfiguration.getId());
+            increment(DEFAULT_RELYING_PARTY_COUNTER);
             assert defaultRelyingPartyConfiguration != null;
             return defaultRelyingPartyConfiguration;
         }
@@ -299,7 +347,7 @@ public class DefaultRelyingPartyConfigurationResolver extends AbstractIdentifiab
         log.warn("No matching relying party configuration applicable, returning nothing");
         return null;
     }
-
+    
     /** {@inheritDoc} */
     @Nonnull @Unmodifiable @NotLive public Collection<Credential> getSigningCredentials() {
         return signingCredentials;
@@ -348,6 +396,18 @@ public class DefaultRelyingPartyConfigurationResolver extends AbstractIdentifiab
         }
     }
     
+    /**
+     * Increment relying party counter.
+     * 
+     * @param name name of counter
+     */
+    private void increment(@Nullable final String name) {
+        final Counter counter = counterMap.get(name);
+        if (counter != null) {
+            counter.inc();
+        }
+    }
+    
     /**
      * Get the {@link ProfileRequestContext} included in the input criteria, if any.
      * 

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


More information about the commits mailing list