[java-shib-attribute] 01/02: JSATTR-29 Data connector caching improvements

Rod Widdowson rdw at steadingsoftware.com
Fri Jul 19 15:11:47 UTC 2024


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

rdw pushed a commit to branch main
in repository java-shib-attribute.

View the commit online:
http://git.shibboleth.net/view/?p=java-shib-attribute.git;a=commit;h=2d647bf59b6a65eeab43ae8b2856a23bc4a2dc1d

commit 2d647bf59b6a65eeab43ae8b2856a23bc4a2dc1d
Author: Rod Widdowson <rdw at steadingsoftware.com>
AuthorDate: Fri Jul 19 14:05:26 2024 +0100

    JSATTR-29 Data connector caching improvements
    
    https://shibboleth.atlassian.net/issues/JSATTR-29
    
    Add a metric <root>.'cache' to return the Guava CacheStats
---
 .../impl/AttributeResolverServiceGaugeSet.java     | 82 +++++++++++++++++++++-
 1 file changed, 80 insertions(+), 2 deletions(-)

diff --git a/shib-attribute-resolver-impl/src/main/java/net/shibboleth/idp/attribute/resolver/impl/AttributeResolverServiceGaugeSet.java b/shib-attribute-resolver-impl/src/main/java/net/shibboleth/idp/attribute/resolver/impl/AttributeResolverServiceGaugeSet.java
index 26245fe26..a06bb364f 100644
--- a/shib-attribute-resolver-impl/src/main/java/net/shibboleth/idp/attribute/resolver/impl/AttributeResolverServiceGaugeSet.java
+++ b/shib-attribute-resolver-impl/src/main/java/net/shibboleth/idp/attribute/resolver/impl/AttributeResolverServiceGaugeSet.java
@@ -26,9 +26,12 @@ import com.codahale.metrics.Gauge;
 import com.codahale.metrics.MetricFilter;
 import com.codahale.metrics.MetricRegistry;
 import com.codahale.metrics.MetricSet;
+import com.google.common.cache.Cache;
+import com.google.common.cache.CacheStats;
 
 import net.shibboleth.idp.attribute.resolver.AttributeResolver;
 import net.shibboleth.idp.attribute.resolver.DataConnector;
+import net.shibboleth.idp.attribute.resolver.dc.impl.AbstractSearchDataConnector;
 import net.shibboleth.shared.annotation.ParameterName;
 import net.shibboleth.shared.annotation.constraint.NotEmpty;
 import net.shibboleth.shared.component.ComponentInitializationException;
@@ -117,7 +120,42 @@ public class AttributeResolverServiceGaugeSet extends ReloadableServiceGaugeSet<
                         return Map.copyOf(mapBuilder);
                     }
                 });
-        
+
+        getMetricMap().put(
+                MetricRegistry.name(metricName, "cache"),
+                new Gauge<Map<String,CacheStatsPojo>>() {
+                    public Map<String,CacheStatsPojo> getValue() {
+                        final Map<String,CacheStatsPojo> mapBuilder = new HashMap<>();
+                        try (final ServiceableComponent<AttributeResolver> component =
+                                getService().getServiceableComponent()) {
+                            final Object resolver = component.getComponent();
+                            if (resolver instanceof AttributeResolverImpl) {
+                                final Collection<DataConnector> connectors =
+                                        ((AttributeResolverImpl) resolver).getDataConnectors().values();
+                                for (final DataConnector connector: connectors) {
+                                    if (connector instanceof AbstractSearchDataConnector) {
+                                        final AbstractSearchDataConnector<?,?> search = (AbstractSearchDataConnector<?,?>) connector;
+                                        final var cache = search.getResultsCache();
+                                        final var stats = cache == null ? null : cache.stats();
+                                        if (stats != null) {
+                                            mapBuilder.put(connector.getId(), new CacheStatsPojo(stats));
+                                        }
+                                    }
+                                }
+                            } else if (resolver instanceof AttributeResolver) {
+                               log.debug("{}: Cannot get Data Connector failure " +
+                                       " information from unsupported class type {}",
+                                       getLogPrefix(), resolver.getClass());
+                            } else {
+                                log.warn("{}: Injected Service was not for an AttributeResolver ({})",
+                                        getLogPrefix(), resolver.getClass());
+                            }
+                        } catch (final ServiceException e) {
+                            // Nothing to do.
+                        }
+                        return Map.copyOf(mapBuilder);
+                    }
+                });
     }
 // Checkstyle: AnonInnerLength|MethodLength ON
 
@@ -141,4 +179,44 @@ public class AttributeResolverServiceGaugeSet extends ReloadableServiceGaugeSet<
         }
     }
 
-}
\ No newline at end of file
+    /** A Plain Old Java Object to encapsulate the counts from a {@link CacheStats} */
+    public static class CacheStatsPojo {
+        /**
+         * The number of times {@link Cache} lookup methods have returned a cached value.
+         * See {@link CacheStats#hitCount()}
+         */
+        final long hitCount;
+        /**
+         * The the number of times {@link Cache} lookup methods have returned an uncached (newly loaded) value, or null.
+         * See {@link CacheStats#missCount()}
+         */
+        final public long missCount;
+        /**
+         * The number of times {@link Cache} lookup methods have successfully loaded a new value.
+         * See {@link CacheStats#loadSuccessCount()}
+         */
+        final public long loadSuccessCount;
+        /**
+         * The number of times {@link Cache} lookup methods threw an exception while loading a new
+         * value.  See {@link CacheStats#loadExceptionCount()}
+         */
+        final public long loadExceptionCount;
+        /**
+         * The Returns the number of times an entry has been evicted.  See {@link CacheStats#evictionCount()}
+         */
+        final public long evictionCount;
+          
+        /**
+         * Constructor.
+         *
+         * @param s what to return.
+         */
+        CacheStatsPojo(final CacheStats s) {
+            hitCount = s.hitCount();
+            missCount = s.missCount();
+            loadExceptionCount = s.loadExceptionCount();
+            loadSuccessCount = s.loadSuccessCount();
+            evictionCount = s.evictionCount();
+        }
+    }
+}

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


More information about the commits mailing list