You are viewing a plain text version of this content. The canonical link for it is here.
Posted to oak-commits@jackrabbit.apache.org by an...@apache.org on 2021/01/07 10:29:58 UTC

svn commit: r1885237 - in /jackrabbit/oak/trunk: oak-benchmarks/src/main/java/org/apache/jackrabbit/oak/benchmark/authentication/external/ oak-core-spi/src/main/java/org/apache/jackrabbit/oak/stats/ oak-core/src/main/java/org/apache/jackrabbit/oak/secu...

Author: angela
Date: Thu Jan  7 10:29:57 2021
New Revision: 1885237

URL: http://svn.apache.org/viewvc?rev=1885237&view=rev
Log:
OAK-9246 : Avoid hardcoding stats classes in SecurityProviderRegistration

Added:
    jackrabbit/oak/trunk/oak-core-spi/src/main/java/org/apache/jackrabbit/oak/stats/Monitor.java   (with props)
    jackrabbit/oak/trunk/oak-security-spi/src/test/java/org/apache/jackrabbit/oak/spi/security/authentication/LoginModuleMonitorTest.java   (with props)
Modified:
    jackrabbit/oak/trunk/oak-benchmarks/src/main/java/org/apache/jackrabbit/oak/benchmark/authentication/external/ExternalLoginTest.java
    jackrabbit/oak/trunk/oak-core-spi/src/main/java/org/apache/jackrabbit/oak/stats/package-info.java
    jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/security/authentication/AuthenticationConfigurationImpl.java
    jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/security/internal/SecurityProviderRegistration.java
    jackrabbit/oak/trunk/oak-core/src/test/java/org/apache/jackrabbit/oak/security/authentication/AuthenticationConfigurationImplTest.java
    jackrabbit/oak/trunk/oak-core/src/test/java/org/apache/jackrabbit/oak/security/internal/SecurityProviderRegistrationTest.java
    jackrabbit/oak/trunk/oak-security-spi/src/main/java/org/apache/jackrabbit/oak/spi/security/CompositeConfiguration.java
    jackrabbit/oak/trunk/oak-security-spi/src/main/java/org/apache/jackrabbit/oak/spi/security/SecurityConfiguration.java
    jackrabbit/oak/trunk/oak-security-spi/src/main/java/org/apache/jackrabbit/oak/spi/security/authentication/LoginModuleMBean.java
    jackrabbit/oak/trunk/oak-security-spi/src/main/java/org/apache/jackrabbit/oak/spi/security/authentication/LoginModuleMonitor.java
    jackrabbit/oak/trunk/oak-security-spi/src/main/java/org/apache/jackrabbit/oak/spi/security/authentication/LoginModuleStatsCollector.java
    jackrabbit/oak/trunk/oak-security-spi/src/main/java/org/apache/jackrabbit/oak/spi/security/authentication/package-info.java
    jackrabbit/oak/trunk/oak-security-spi/src/main/java/org/apache/jackrabbit/oak/spi/security/authentication/token/package-info.java
    jackrabbit/oak/trunk/oak-security-spi/src/main/java/org/apache/jackrabbit/oak/spi/security/authorization/package-info.java
    jackrabbit/oak/trunk/oak-security-spi/src/main/java/org/apache/jackrabbit/oak/spi/security/package-info.java
    jackrabbit/oak/trunk/oak-security-spi/src/main/java/org/apache/jackrabbit/oak/spi/security/principal/package-info.java
    jackrabbit/oak/trunk/oak-security-spi/src/main/java/org/apache/jackrabbit/oak/spi/security/privilege/package-info.java
    jackrabbit/oak/trunk/oak-security-spi/src/main/java/org/apache/jackrabbit/oak/spi/security/user/package-info.java
    jackrabbit/oak/trunk/oak-security-spi/src/test/java/org/apache/jackrabbit/oak/spi/security/CompositeConfigurationTest.java
    jackrabbit/oak/trunk/oak-security-spi/src/test/java/org/apache/jackrabbit/oak/spi/security/authentication/LoginModuleStatsTest.java

Modified: jackrabbit/oak/trunk/oak-benchmarks/src/main/java/org/apache/jackrabbit/oak/benchmark/authentication/external/ExternalLoginTest.java
URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-benchmarks/src/main/java/org/apache/jackrabbit/oak/benchmark/authentication/external/ExternalLoginTest.java?rev=1885237&r1=1885236&r2=1885237&view=diff
==============================================================================
--- jackrabbit/oak/trunk/oak-benchmarks/src/main/java/org/apache/jackrabbit/oak/benchmark/authentication/external/ExternalLoginTest.java (original)
+++ jackrabbit/oak/trunk/oak-benchmarks/src/main/java/org/apache/jackrabbit/oak/benchmark/authentication/external/ExternalLoginTest.java Thu Jan  7 10:29:57 2021
@@ -16,39 +16,35 @@
  */
 package org.apache.jackrabbit.oak.benchmark.authentication.external;
 
-import static javax.security.auth.login.AppConfigurationEntry.LoginModuleControlFlag.OPTIONAL;
-import static javax.security.auth.login.AppConfigurationEntry.LoginModuleControlFlag.SUFFICIENT;
-import static org.junit.Assert.assertEquals;
-
-import java.util.Collections;
-import java.util.HashSet;
-import java.util.List;
-import java.util.Set;
-import java.util.TreeSet;
-import java.util.concurrent.atomic.AtomicLong;
-import java.util.stream.Collectors;
-import java.util.stream.StreamSupport;
-
-import javax.jcr.LoginException;
-import javax.jcr.Session;
-import javax.jcr.SimpleCredentials;
-import javax.security.auth.login.AppConfigurationEntry;
-import javax.security.auth.login.Configuration;
-
+import com.google.common.collect.ImmutableMap;
 import org.apache.commons.lang3.reflect.FieldUtils;
 import org.apache.jackrabbit.oak.jcr.delegate.SessionDelegate;
 import org.apache.jackrabbit.oak.security.authentication.token.TokenLoginModule;
 import org.apache.jackrabbit.oak.security.authentication.user.LoginModuleImpl;
 import org.apache.jackrabbit.oak.spi.security.authentication.AuthenticationConfiguration;
 import org.apache.jackrabbit.oak.spi.security.authentication.GuestLoginModule;
-import org.apache.jackrabbit.oak.spi.security.authentication.LoginModuleStats;
-import org.apache.jackrabbit.oak.spi.security.authentication.LoginModuleStatsCollector;
 import org.apache.jackrabbit.oak.spi.security.authentication.external.ExternalIdentityRef;
 import org.apache.jackrabbit.oak.spi.security.authentication.external.impl.ExternalLoginModule;
 import org.apache.jackrabbit.oak.stats.StatisticsProvider;
 import org.jetbrains.annotations.NotNull;
 
-import com.google.common.collect.ImmutableMap;
+import javax.jcr.LoginException;
+import javax.jcr.Session;
+import javax.jcr.SimpleCredentials;
+import javax.security.auth.login.AppConfigurationEntry;
+import javax.security.auth.login.Configuration;
+import java.util.Collections;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Set;
+import java.util.TreeSet;
+import java.util.concurrent.atomic.AtomicLong;
+import java.util.stream.Collectors;
+import java.util.stream.StreamSupport;
+
+import static javax.security.auth.login.AppConfigurationEntry.LoginModuleControlFlag.OPTIONAL;
+import static javax.security.auth.login.AppConfigurationEntry.LoginModuleControlFlag.SUFFICIENT;
+import static org.junit.Assert.assertEquals;
 
 /**
  * Login against the {@link ExternalLoginModule} with a randomly selected user.
@@ -63,19 +59,19 @@ public class ExternalLoginTest extends A
     private final int numberOfUsers;
     private final int numberOfGroups;
     private final Reporter reporter;
-    private final LoginModuleStats lmStats;
+    StatisticsProvider statisticsProvider;
     private final List<String> auto;
 
     private Set<String> uniques;
     private AtomicLong err;
 
     public ExternalLoginTest(int numberOfUsers, int numberOfGroups, long expTime, boolean dynamicMembership,
-            @NotNull List<String> autoMembership, boolean report, StatisticsProvider statsProvider) {
+            @NotNull List<String> autoMembership, boolean report, @NotNull StatisticsProvider statsProvider) {
         super(numberOfUsers, numberOfGroups, expTime, dynamicMembership, autoMembership);
         this.numberOfUsers = numberOfUsers;
         this.numberOfGroups = numberOfGroups;
         this.reporter = new Reporter(report);
-        this.lmStats = new LoginModuleStats(statsProvider);
+        this.statisticsProvider = statsProvider;
         this.auto = autoMembership;
     }
 
@@ -87,9 +83,7 @@ public class ExternalLoginTest extends A
         err = new AtomicLong();
         AuthenticationConfiguration authenticationConfiguration = getSecurityProvider()
                 .getConfiguration(AuthenticationConfiguration.class);
-        if (authenticationConfiguration instanceof LoginModuleStatsCollector) {
-            ((LoginModuleStatsCollector) authenticationConfiguration).setLoginModuleMonitor(lmStats);
-        }
+        authenticationConfiguration.getMonitors(statisticsProvider);
     }
 
     @Override

Added: jackrabbit/oak/trunk/oak-core-spi/src/main/java/org/apache/jackrabbit/oak/stats/Monitor.java
URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-core-spi/src/main/java/org/apache/jackrabbit/oak/stats/Monitor.java?rev=1885237&view=auto
==============================================================================
--- jackrabbit/oak/trunk/oak-core-spi/src/main/java/org/apache/jackrabbit/oak/stats/Monitor.java (added)
+++ jackrabbit/oak/trunk/oak-core-spi/src/main/java/org/apache/jackrabbit/oak/stats/Monitor.java Thu Jan  7 10:29:57 2021
@@ -0,0 +1,43 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you 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 org.apache.jackrabbit.oak.stats;
+
+import org.jetbrains.annotations.NotNull;
+import org.osgi.annotation.versioning.ProviderType;
+
+import java.util.Map;
+
+/**
+ * Marker interface for monitors that are to be registered with a {@link org.apache.jackrabbit.oak.spi.whiteboard.Whiteboard}.
+ */
+@ProviderType
+public interface Monitor<T> {
+
+    /**
+     * @return The type to be passed to {@link org.apache.jackrabbit.oak.spi.whiteboard.Whiteboard#register(Class, Object, Map)}
+     */
+    @NotNull
+    Class<T> getMonitorClass();
+
+    /**
+     * @return The properties to be passed to {@link org.apache.jackrabbit.oak.spi.whiteboard.Whiteboard#register(Class, Object, Map)}
+     */
+    @NotNull
+    Map<Object, Object> getMonitorProperties();
+}

Propchange: jackrabbit/oak/trunk/oak-core-spi/src/main/java/org/apache/jackrabbit/oak/stats/Monitor.java
------------------------------------------------------------------------------
    svn:eol-style = native

Modified: jackrabbit/oak/trunk/oak-core-spi/src/main/java/org/apache/jackrabbit/oak/stats/package-info.java
URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-core-spi/src/main/java/org/apache/jackrabbit/oak/stats/package-info.java?rev=1885237&r1=1885236&r2=1885237&view=diff
==============================================================================
--- jackrabbit/oak/trunk/oak-core-spi/src/main/java/org/apache/jackrabbit/oak/stats/package-info.java (original)
+++ jackrabbit/oak/trunk/oak-core-spi/src/main/java/org/apache/jackrabbit/oak/stats/package-info.java Thu Jan  7 10:29:57 2021
@@ -14,7 +14,7 @@
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
-@Version("1.1.0")
+@Version("1.2.0")
 package org.apache.jackrabbit.oak.stats;
 
 import org.osgi.annotation.versioning.Version;

Modified: jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/security/authentication/AuthenticationConfigurationImpl.java
URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/security/authentication/AuthenticationConfigurationImpl.java?rev=1885237&r1=1885236&r2=1885237&view=diff
==============================================================================
--- jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/security/authentication/AuthenticationConfigurationImpl.java (original)
+++ jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/security/authentication/AuthenticationConfigurationImpl.java Thu Jan  7 10:29:57 2021
@@ -16,7 +16,6 @@
  */
 package org.apache.jackrabbit.oak.security.authentication;
 
-import java.util.Map;
 import org.apache.jackrabbit.oak.api.ContentRepository;
 import org.apache.jackrabbit.oak.spi.security.ConfigurationBase;
 import org.apache.jackrabbit.oak.spi.security.ConfigurationParameters;
@@ -25,9 +24,11 @@ import org.apache.jackrabbit.oak.spi.sec
 import org.apache.jackrabbit.oak.spi.security.authentication.AuthenticationConfiguration;
 import org.apache.jackrabbit.oak.spi.security.authentication.LoginContextProvider;
 import org.apache.jackrabbit.oak.spi.security.authentication.LoginModuleMonitor;
-import org.apache.jackrabbit.oak.spi.security.authentication.LoginModuleStatsCollector;
+import org.apache.jackrabbit.oak.spi.security.authentication.LoginModuleStats;
 import org.apache.jackrabbit.oak.spi.whiteboard.Whiteboard;
 import org.apache.jackrabbit.oak.spi.whiteboard.WhiteboardAware;
+import org.apache.jackrabbit.oak.stats.Monitor;
+import org.apache.jackrabbit.oak.stats.StatisticsProvider;
 import org.jetbrains.annotations.NotNull;
 import org.osgi.service.component.annotations.Activate;
 import org.osgi.service.component.annotations.Component;
@@ -37,6 +38,9 @@ import org.osgi.service.metatype.annotat
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
+import java.util.Collections;
+import java.util.Map;
+
 /**
  * Default implementation of the {@code AuthenticationConfiguration} with the
  * following characteristics:
@@ -51,7 +55,7 @@ import org.slf4j.LoggerFactory;
  */
 @Component(service = {AuthenticationConfiguration.class, SecurityConfiguration.class})
 @Designate(ocd = AuthenticationConfigurationImpl.Configuration.class)
-public class AuthenticationConfigurationImpl extends ConfigurationBase implements AuthenticationConfiguration, LoginModuleStatsCollector {
+public class AuthenticationConfigurationImpl extends ConfigurationBase implements AuthenticationConfiguration {
 
     @ObjectClassDefinition(name = "Apache Jackrabbit Oak AuthenticationConfiguration")
     @interface Configuration {
@@ -106,6 +110,13 @@ public class AuthenticationConfiguration
         return NAME;
     }
 
+    @NotNull
+    @Override
+    public Iterable<Monitor<?>> getMonitors(@NotNull StatisticsProvider statisticsProvider) {
+        lmMonitor = new LoginModuleStats(statisticsProvider);
+        return Collections.singleton(lmMonitor);
+    }
+
     //----------------------------------------< AuthenticationConfiguration >---
     /**
      * Create a {@code LoginContextProvider} using standard
@@ -144,9 +155,4 @@ public class AuthenticationConfiguration
         }
         return new LoginContextProviderImpl(appName, getParameters(), contentRepository, provider, whiteboard, lmMonitor);
     }
-
-    @Override
-    public void setLoginModuleMonitor(@NotNull LoginModuleMonitor lmMonitor) {
-        this.lmMonitor = lmMonitor;
-    }
 }

Modified: jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/security/internal/SecurityProviderRegistration.java
URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/security/internal/SecurityProviderRegistration.java?rev=1885237&r1=1885236&r2=1885237&view=diff
==============================================================================
--- jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/security/internal/SecurityProviderRegistration.java (original)
+++ jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/security/internal/SecurityProviderRegistration.java Thu Jan  7 10:29:57 2021
@@ -16,18 +16,8 @@
  */
 package org.apache.jackrabbit.oak.security.internal;
 
-import java.io.Closeable;
-import java.security.Principal;
-import java.util.Collection;
-import java.util.Collections;
-import java.util.Dictionary;
-import java.util.Hashtable;
-import java.util.List;
-import java.util.Map;
-import java.util.Set;
-import java.util.SortedMap;
-import java.util.TreeMap;
-
+import com.google.common.collect.Iterables;
+import com.google.common.io.Closer;
 import org.apache.jackrabbit.api.security.JackrabbitAccessControlManager;
 import org.apache.jackrabbit.oak.commons.PropertiesUtil;
 import org.apache.jackrabbit.oak.osgi.OsgiWhiteboard;
@@ -45,9 +35,6 @@ import org.apache.jackrabbit.oak.spi.sec
 import org.apache.jackrabbit.oak.spi.security.SecurityProvider;
 import org.apache.jackrabbit.oak.spi.security.authentication.AuthenticationConfiguration;
 import org.apache.jackrabbit.oak.spi.security.authentication.LoginModuleMBean;
-import org.apache.jackrabbit.oak.spi.security.authentication.LoginModuleMonitor;
-import org.apache.jackrabbit.oak.spi.security.authentication.LoginModuleStats;
-import org.apache.jackrabbit.oak.spi.security.authentication.LoginModuleStatsCollector;
 import org.apache.jackrabbit.oak.spi.security.authentication.token.CompositeTokenConfiguration;
 import org.apache.jackrabbit.oak.spi.security.authentication.token.TokenConfiguration;
 import org.apache.jackrabbit.oak.spi.security.authorization.AuthorizationConfiguration;
@@ -65,6 +52,7 @@ import org.apache.jackrabbit.oak.spi.sec
 import org.apache.jackrabbit.oak.spi.security.user.action.AuthorizableActionProvider;
 import org.apache.jackrabbit.oak.spi.whiteboard.Registration;
 import org.apache.jackrabbit.oak.spi.whiteboard.Whiteboard;
+import org.apache.jackrabbit.oak.stats.Monitor;
 import org.apache.jackrabbit.oak.stats.StatisticsProvider;
 import org.jetbrains.annotations.NotNull;
 import org.jetbrains.annotations.Nullable;
@@ -86,14 +74,22 @@ import org.osgi.service.metatype.annotat
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
-import com.google.common.io.Closer;
-
 import javax.jcr.security.AccessControlManager;
+import java.security.Principal;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.Dictionary;
+import java.util.Hashtable;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+import java.util.SortedMap;
+import java.util.TreeMap;
 
 import static com.google.common.collect.Lists.newArrayList;
-import static org.apache.jackrabbit.oak.spi.security.RegistrationConstants.OAK_SECURITY_NAME;
 import static org.apache.jackrabbit.oak.commons.IOUtils.closeQuietly;
 import static org.apache.jackrabbit.oak.spi.security.ConfigurationParameters.EMPTY;
+import static org.apache.jackrabbit.oak.spi.security.RegistrationConstants.OAK_SECURITY_NAME;
 import static org.apache.jackrabbit.oak.spi.whiteboard.WhiteboardUtils.registerMBean;
 
 @Component(immediate=true)
@@ -518,9 +514,10 @@ public class SecurityProviderRegistratio
         properties.put("type", "default");
 
         Whiteboard whiteboard = new OsgiWhiteboard(context);
+        SecurityProvider securityProvider = createSecurityProvider(whiteboard);
         ServiceRegistration registration = context.registerService(
                 SecurityProvider.class.getName(),
-                createSecurityProvider(whiteboard),
+                securityProvider,
                 properties
         );
 
@@ -530,16 +527,15 @@ public class SecurityProviderRegistratio
         }
 
         closer = Closer.create();
-        if (authenticationConfiguration instanceof LoginModuleStatsCollector) {
-            LoginModuleStats lmMonitor = new LoginModuleStats(statisticsProvider);
-            ((LoginModuleStatsCollector) authenticationConfiguration).setLoginModuleMonitor(lmMonitor);
-
-            Registration mon = whiteboard.register(LoginModuleMonitor.class, lmMonitor, Collections.emptyMap());
-            closer.register((Closeable) mon::unregister);
-
-            Registration mbean = registerMBean(whiteboard, LoginModuleMBean.class, lmMonitor, LoginModuleMBean.TYPE,
-                    "LoginModule statistics");
-            closer.register((Closeable) mbean::unregister);
+        Iterable<Iterable<Monitor<?>>> monitors = Iterables.transform(securityProvider.getConfigurations(), sc -> sc.getMonitors(statisticsProvider));
+        for (Monitor monitor : Iterables.concat(monitors)) {
+            Registration reg = whiteboard.register(monitor.getMonitorClass(), monitor, monitor.getMonitorProperties());
+            closer.register(reg::unregister);
+
+            if (monitor instanceof LoginModuleMBean) {
+                Registration mbean = registerMBean(whiteboard, LoginModuleMBean.class, (LoginModuleMBean) monitor, LoginModuleMBean.TYPE, LoginModuleMBean.NAME);
+                closer.register(mbean::unregister);
+            }
         }
 
         log.info("SecurityProvider instance registered");

Modified: jackrabbit/oak/trunk/oak-core/src/test/java/org/apache/jackrabbit/oak/security/authentication/AuthenticationConfigurationImplTest.java
URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-core/src/test/java/org/apache/jackrabbit/oak/security/authentication/AuthenticationConfigurationImplTest.java?rev=1885237&r1=1885236&r2=1885237&view=diff
==============================================================================
--- jackrabbit/oak/trunk/oak-core/src/test/java/org/apache/jackrabbit/oak/security/authentication/AuthenticationConfigurationImplTest.java (original)
+++ jackrabbit/oak/trunk/oak-core/src/test/java/org/apache/jackrabbit/oak/security/authentication/AuthenticationConfigurationImplTest.java Thu Jan  7 10:29:57 2021
@@ -16,15 +16,19 @@
  */
 package org.apache.jackrabbit.oak.security.authentication;
 
+import com.google.common.collect.Iterables;
 import org.apache.jackrabbit.oak.api.ContentRepository;
 import org.apache.jackrabbit.oak.security.internal.SecurityProviderBuilder;
 import org.apache.jackrabbit.oak.spi.security.SecurityProvider;
 import org.apache.jackrabbit.oak.spi.security.authentication.AuthenticationConfiguration;
 import org.apache.jackrabbit.oak.spi.security.authentication.LoginContextProvider;
 import org.apache.jackrabbit.oak.spi.security.authentication.LoginModuleMonitor;
+import org.apache.jackrabbit.oak.spi.security.authentication.LoginModuleStats;
 import org.apache.jackrabbit.oak.spi.whiteboard.DefaultWhiteboard;
 import org.apache.jackrabbit.oak.spi.whiteboard.Whiteboard;
 import org.apache.jackrabbit.oak.spi.whiteboard.WhiteboardAware;
+import org.apache.jackrabbit.oak.stats.Monitor;
+import org.apache.jackrabbit.oak.stats.StatisticsProvider;
 import org.junit.Test;
 import org.mockito.Mockito;
 
@@ -89,15 +93,17 @@ public class AuthenticationConfiguration
     }
 
     @Test
-    public void testSetLoginModuleMonitor() throws Exception {
+    public void testGetMonitors() throws Exception {
         Field f = AuthenticationConfigurationImpl.class.getDeclaredField("lmMonitor");
         f.setAccessible(true);
-
         assertSame(LoginModuleMonitor.NOOP, f.get(authConfiguration));
 
-        LoginModuleMonitor monitor = mock(LoginModuleMonitor.class);
-        authConfiguration.setLoginModuleMonitor(monitor);
-
-        assertSame(monitor, f.get(authConfiguration));
+        StatisticsProvider statisticsProvider = StatisticsProvider.NOOP;
+        Iterable<Monitor<?>> monitors = authConfiguration.getMonitors(statisticsProvider);
+        assertEquals(1, Iterables.size(monitors));
+
+        Monitor<?> m = monitors.iterator().next();
+        assertTrue(m instanceof LoginModuleStats);
+        assertTrue(f.get(authConfiguration) instanceof LoginModuleStats);
     }
 }
\ No newline at end of file

Modified: jackrabbit/oak/trunk/oak-core/src/test/java/org/apache/jackrabbit/oak/security/internal/SecurityProviderRegistrationTest.java
URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-core/src/test/java/org/apache/jackrabbit/oak/security/internal/SecurityProviderRegistrationTest.java?rev=1885237&r1=1885236&r2=1885237&view=diff
==============================================================================
--- jackrabbit/oak/trunk/oak-core/src/test/java/org/apache/jackrabbit/oak/security/internal/SecurityProviderRegistrationTest.java (original)
+++ jackrabbit/oak/trunk/oak-core/src/test/java/org/apache/jackrabbit/oak/security/internal/SecurityProviderRegistrationTest.java Thu Jan  7 10:29:57 2021
@@ -51,6 +51,7 @@ import org.apache.jackrabbit.oak.spi.sec
 import org.apache.jackrabbit.oak.spi.security.authentication.AuthenticationConfiguration;
 import org.apache.jackrabbit.oak.spi.security.authentication.LoginModuleMBean;
 import org.apache.jackrabbit.oak.spi.security.authentication.LoginModuleMonitor;
+import org.apache.jackrabbit.oak.spi.security.authentication.LoginModuleStats;
 import org.apache.jackrabbit.oak.spi.security.authentication.LoginModuleStatsCollector;
 import org.apache.jackrabbit.oak.spi.security.authentication.token.CompositeTokenConfiguration;
 import org.apache.jackrabbit.oak.spi.security.authentication.token.TokenConfiguration;
@@ -69,6 +70,8 @@ import org.apache.jackrabbit.oak.spi.sec
 import org.apache.jackrabbit.oak.spi.security.user.UserConstants;
 import org.apache.jackrabbit.oak.spi.security.user.action.AuthorizableActionProvider;
 import org.apache.jackrabbit.oak.spi.security.user.action.DefaultAuthorizableActionProvider;
+import org.apache.jackrabbit.oak.stats.Monitor;
+import org.apache.jackrabbit.oak.stats.StatisticsProvider;
 import org.apache.sling.testing.mock.osgi.junit.OsgiContext;
 import org.jetbrains.annotations.NotNull;
 import org.junit.Rule;
@@ -81,6 +84,7 @@ import javax.jcr.security.AccessControlP
 import java.lang.annotation.Annotation;
 import java.lang.reflect.Field;
 import java.util.Collection;
+import java.util.Collections;
 import java.util.Hashtable;
 import java.util.List;
 import java.util.Map;
@@ -326,6 +330,7 @@ public class SecurityProviderRegistratio
         
         // register AuthenticationConfiguration to trigger MBean registration 
         AuthenticationConfigurationImpl mockAc = mock(AuthenticationConfigurationImpl.class);
+        when(mockAc.getMonitors(any(StatisticsProvider.class))).thenReturn(Collections.singleton(new LoginModuleStats(StatisticsProvider.NOOP)));
         registration.bindAuthenticationConfiguration(mockAc);
 
         // register required service
@@ -502,7 +507,8 @@ public class SecurityProviderRegistratio
         // trigger maybeRegister
         registration.bindAuthorizationConfiguration(mockConfiguration(AuthorizationConfiguration.class), ConfigurationParameters.of(OAK_SECURITY_NAME, "authorizationId"));
 
-        verify(((LoginModuleStatsCollector) ac), times(1)).setLoginModuleMonitor(any(LoginModuleMonitor.class));
+        verify(((LoginModuleStatsCollector) ac), never()).setLoginModuleMonitor(any(LoginModuleMonitor.class));
+        verify(ac, times(1)).getMonitors(any(StatisticsProvider.class));
     }
 
     @Test
@@ -1093,4 +1099,32 @@ public class SecurityProviderRegistratio
         verify(filter1, never()).stop(acMgr, ImmutableSet.of(EveryonePrincipal.getInstance()));
         verify(filter2, times(1)).stop(acMgr, ImmutableSet.of(EveryonePrincipal.getInstance()));
     }
+
+    @Test
+    public void testRegisterWithMonitors() {
+        registration.activate(context.bundleContext(), configWithRequiredServiceIds("customAuthorizationConfig"));
+        assertNull(context.getService(SecurityProvider.class));
+
+        AuthorizationConfiguration mockConfiguration = mockConfiguration(AuthorizationConfiguration.class);
+        when(mockConfiguration.getMonitors(any(StatisticsProvider.class))).thenReturn(ImmutableList.of(new TestMonitor()));
+
+        registration.bindAuthorizationConfiguration(mockConfiguration, Collections.singletonMap(SERVICE_PID, "customAuthorizationConfig"));
+        SecurityProvider service = context.getService(SecurityProvider.class);
+        assertNotNull(service);
+
+        verify(mockConfiguration, times(1)).getMonitors(any(StatisticsProvider.class));
+    }
+
+    private static final class TestMonitor implements Monitor<TestMonitor> {
+
+        @Override
+        public @NotNull Class<TestMonitor> getMonitorClass() {
+            return TestMonitor.class;
+        }
+
+        @Override
+        public @NotNull Map<Object, Object> getMonitorProperties() {
+            return Collections.emptyMap();
+        }
+    }
 }

Modified: jackrabbit/oak/trunk/oak-security-spi/src/main/java/org/apache/jackrabbit/oak/spi/security/CompositeConfiguration.java
URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-security-spi/src/main/java/org/apache/jackrabbit/oak/spi/security/CompositeConfiguration.java?rev=1885237&r1=1885236&r2=1885237&view=diff
==============================================================================
--- jackrabbit/oak/trunk/oak-security-spi/src/main/java/org/apache/jackrabbit/oak/spi/security/CompositeConfiguration.java (original)
+++ jackrabbit/oak/trunk/oak-security-spi/src/main/java/org/apache/jackrabbit/oak/spi/security/CompositeConfiguration.java Thu Jan  7 10:29:57 2021
@@ -18,12 +18,6 @@
  */
 package org.apache.jackrabbit.oak.spi.security;
 
-import java.security.Principal;
-import java.util.List;
-import java.util.Map;
-import java.util.Set;
-import java.util.concurrent.ConcurrentHashMap;
-import java.util.concurrent.CopyOnWriteArrayList;
 import com.google.common.base.Function;
 import com.google.common.collect.ImmutableList;
 import com.google.common.collect.Iterables;
@@ -44,11 +38,20 @@ import org.apache.jackrabbit.oak.spi.lif
 import org.apache.jackrabbit.oak.spi.lifecycle.RepositoryInitializer;
 import org.apache.jackrabbit.oak.spi.lifecycle.WorkspaceInitializer;
 import org.apache.jackrabbit.oak.spi.xml.ProtectedItemImporter;
+import org.apache.jackrabbit.oak.stats.Monitor;
+import org.apache.jackrabbit.oak.stats.StatisticsProvider;
 import org.jetbrains.annotations.NotNull;
 import org.jetbrains.annotations.Nullable;
 import org.osgi.annotation.versioning.ProviderType;
 import org.osgi.framework.Constants;
 
+import java.security.Principal;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+import java.util.concurrent.ConcurrentHashMap;
+import java.util.concurrent.CopyOnWriteArrayList;
+
 /**
  * Abstract base implementation for {@link SecurityConfiguration}s that can
  * combine different implementations.
@@ -264,6 +267,13 @@ public abstract class CompositeConfigura
         return ctx;
     }
 
+    @NotNull
+    @Override
+    public Iterable<Monitor<?>> getMonitors(@NotNull StatisticsProvider statisticsProvider) {
+        return Iterables.concat(
+                Iterables.transform(getConfigurations(), securityConfiguration -> securityConfiguration.getMonitors(statisticsProvider)));
+    }
+
     private static final class Ranking {
 
         private Map<SecurityConfiguration, Integer> m = new ConcurrentHashMap<>();

Modified: jackrabbit/oak/trunk/oak-security-spi/src/main/java/org/apache/jackrabbit/oak/spi/security/SecurityConfiguration.java
URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-security-spi/src/main/java/org/apache/jackrabbit/oak/spi/security/SecurityConfiguration.java?rev=1885237&r1=1885236&r2=1885237&view=diff
==============================================================================
--- jackrabbit/oak/trunk/oak-security-spi/src/main/java/org/apache/jackrabbit/oak/spi/security/SecurityConfiguration.java (original)
+++ jackrabbit/oak/trunk/oak-security-spi/src/main/java/org/apache/jackrabbit/oak/spi/security/SecurityConfiguration.java Thu Jan  7 10:29:57 2021
@@ -16,13 +16,6 @@
  */
 package org.apache.jackrabbit.oak.spi.security;
 
-import java.security.Principal;
-import java.util.Collections;
-import java.util.List;
-import java.util.Set;
-
-import org.jetbrains.annotations.NotNull;
-import org.osgi.annotation.versioning.ProviderType;
 import org.apache.jackrabbit.oak.spi.commit.CommitHook;
 import org.apache.jackrabbit.oak.spi.commit.MoveTracker;
 import org.apache.jackrabbit.oak.spi.commit.ThreeWayConflictHandler;
@@ -30,6 +23,15 @@ import org.apache.jackrabbit.oak.spi.com
 import org.apache.jackrabbit.oak.spi.lifecycle.RepositoryInitializer;
 import org.apache.jackrabbit.oak.spi.lifecycle.WorkspaceInitializer;
 import org.apache.jackrabbit.oak.spi.xml.ProtectedItemImporter;
+import org.apache.jackrabbit.oak.stats.Monitor;
+import org.apache.jackrabbit.oak.stats.StatisticsProvider;
+import org.jetbrains.annotations.NotNull;
+import org.osgi.annotation.versioning.ProviderType;
+
+import java.security.Principal;
+import java.util.Collections;
+import java.util.List;
+import java.util.Set;
 
 /**
  * Base interface for all security related configurations.
@@ -120,6 +122,11 @@ public interface SecurityConfiguration {
     @NotNull
     Context getContext();
 
+    @NotNull
+    default Iterable<Monitor<?>> getMonitors(@NotNull StatisticsProvider statisticsProvider) {
+        return Collections.emptySet();
+    }
+
     /**
      * Default implementation that provides empty initializers, validators,
      * commit hooks and parameters.

Modified: jackrabbit/oak/trunk/oak-security-spi/src/main/java/org/apache/jackrabbit/oak/spi/security/authentication/LoginModuleMBean.java
URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-security-spi/src/main/java/org/apache/jackrabbit/oak/spi/security/authentication/LoginModuleMBean.java?rev=1885237&r1=1885236&r2=1885237&view=diff
==============================================================================
--- jackrabbit/oak/trunk/oak-security-spi/src/main/java/org/apache/jackrabbit/oak/spi/security/authentication/LoginModuleMBean.java (original)
+++ jackrabbit/oak/trunk/oak-security-spi/src/main/java/org/apache/jackrabbit/oak/spi/security/authentication/LoginModuleMBean.java Thu Jan  7 10:29:57 2021
@@ -25,6 +25,8 @@ public interface LoginModuleMBean {
 
     String TYPE = "LoginModuleStats";
 
+    String NAME = "LoginModule statistics";
+
     long getLoginErrors();
 
     CompositeData getLoginErrorsHistory();

Modified: jackrabbit/oak/trunk/oak-security-spi/src/main/java/org/apache/jackrabbit/oak/spi/security/authentication/LoginModuleMonitor.java
URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-security-spi/src/main/java/org/apache/jackrabbit/oak/spi/security/authentication/LoginModuleMonitor.java?rev=1885237&r1=1885236&r2=1885237&view=diff
==============================================================================
--- jackrabbit/oak/trunk/oak-security-spi/src/main/java/org/apache/jackrabbit/oak/spi/security/authentication/LoginModuleMonitor.java (original)
+++ jackrabbit/oak/trunk/oak-security-spi/src/main/java/org/apache/jackrabbit/oak/spi/security/authentication/LoginModuleMonitor.java Thu Jan  7 10:29:57 2021
@@ -16,10 +16,15 @@
  */
 package org.apache.jackrabbit.oak.spi.security.authentication;
 
+import org.apache.jackrabbit.oak.stats.Monitor;
+import org.jetbrains.annotations.NotNull;
 import org.osgi.annotation.versioning.ProviderType;
 
+import java.util.Collections;
+import java.util.Map;
+
 @ProviderType
-public interface LoginModuleMonitor {
+public interface LoginModuleMonitor extends Monitor<LoginModuleMonitor> {
 
     LoginModuleMonitor NOOP = new LoginModuleMonitor() {
 
@@ -36,4 +41,13 @@ public interface LoginModuleMonitor {
      */
     void loginError();
 
+    @Override
+    default @NotNull Class<LoginModuleMonitor> getMonitorClass() {
+        return LoginModuleMonitor.class;
+    }
+
+    @Override
+    default @NotNull Map<Object, Object> getMonitorProperties() {
+        return Collections.emptyMap();
+    }
 }

Modified: jackrabbit/oak/trunk/oak-security-spi/src/main/java/org/apache/jackrabbit/oak/spi/security/authentication/LoginModuleStatsCollector.java
URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-security-spi/src/main/java/org/apache/jackrabbit/oak/spi/security/authentication/LoginModuleStatsCollector.java?rev=1885237&r1=1885236&r2=1885237&view=diff
==============================================================================
--- jackrabbit/oak/trunk/oak-security-spi/src/main/java/org/apache/jackrabbit/oak/spi/security/authentication/LoginModuleStatsCollector.java (original)
+++ jackrabbit/oak/trunk/oak-security-spi/src/main/java/org/apache/jackrabbit/oak/spi/security/authentication/LoginModuleStatsCollector.java Thu Jan  7 10:29:57 2021
@@ -16,9 +16,14 @@
  */
 package org.apache.jackrabbit.oak.spi.security.authentication;
 
+import org.apache.jackrabbit.oak.stats.StatisticsProvider;
 import org.jetbrains.annotations.NotNull;
 import org.osgi.annotation.versioning.ProviderType;
 
+/**
+ * @deprecated Since Oak 1.38.0 in favor of {@link org.apache.jackrabbit.oak.spi.security.SecurityConfiguration#getMonitors(StatisticsProvider)}
+ */
+@Deprecated
 @ProviderType
 public interface LoginModuleStatsCollector {
 

Modified: jackrabbit/oak/trunk/oak-security-spi/src/main/java/org/apache/jackrabbit/oak/spi/security/authentication/package-info.java
URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-security-spi/src/main/java/org/apache/jackrabbit/oak/spi/security/authentication/package-info.java?rev=1885237&r1=1885236&r2=1885237&view=diff
==============================================================================
--- jackrabbit/oak/trunk/oak-security-spi/src/main/java/org/apache/jackrabbit/oak/spi/security/authentication/package-info.java (original)
+++ jackrabbit/oak/trunk/oak-security-spi/src/main/java/org/apache/jackrabbit/oak/spi/security/authentication/package-info.java Thu Jan  7 10:29:57 2021
@@ -14,7 +14,7 @@
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
-@Version("1.4.0")
+@Version("1.5.0")
 package org.apache.jackrabbit.oak.spi.security.authentication;
 
 import org.osgi.annotation.versioning.Version;

Modified: jackrabbit/oak/trunk/oak-security-spi/src/main/java/org/apache/jackrabbit/oak/spi/security/authentication/token/package-info.java
URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-security-spi/src/main/java/org/apache/jackrabbit/oak/spi/security/authentication/token/package-info.java?rev=1885237&r1=1885236&r2=1885237&view=diff
==============================================================================
--- jackrabbit/oak/trunk/oak-security-spi/src/main/java/org/apache/jackrabbit/oak/spi/security/authentication/token/package-info.java (original)
+++ jackrabbit/oak/trunk/oak-security-spi/src/main/java/org/apache/jackrabbit/oak/spi/security/authentication/token/package-info.java Thu Jan  7 10:29:57 2021
@@ -14,7 +14,7 @@
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
-@Version("1.6.1")
+@Version("1.7.0")
 package org.apache.jackrabbit.oak.spi.security.authentication.token;
 
 import org.osgi.annotation.versioning.Version;

Modified: jackrabbit/oak/trunk/oak-security-spi/src/main/java/org/apache/jackrabbit/oak/spi/security/authorization/package-info.java
URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-security-spi/src/main/java/org/apache/jackrabbit/oak/spi/security/authorization/package-info.java?rev=1885237&r1=1885236&r2=1885237&view=diff
==============================================================================
--- jackrabbit/oak/trunk/oak-security-spi/src/main/java/org/apache/jackrabbit/oak/spi/security/authorization/package-info.java (original)
+++ jackrabbit/oak/trunk/oak-security-spi/src/main/java/org/apache/jackrabbit/oak/spi/security/authorization/package-info.java Thu Jan  7 10:29:57 2021
@@ -14,7 +14,7 @@
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
-@Version("1.1.1")
+@Version("1.2.0")
 package org.apache.jackrabbit.oak.spi.security.authorization;
 
 import org.osgi.annotation.versioning.Version;

Modified: jackrabbit/oak/trunk/oak-security-spi/src/main/java/org/apache/jackrabbit/oak/spi/security/package-info.java
URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-security-spi/src/main/java/org/apache/jackrabbit/oak/spi/security/package-info.java?rev=1885237&r1=1885236&r2=1885237&view=diff
==============================================================================
--- jackrabbit/oak/trunk/oak-security-spi/src/main/java/org/apache/jackrabbit/oak/spi/security/package-info.java (original)
+++ jackrabbit/oak/trunk/oak-security-spi/src/main/java/org/apache/jackrabbit/oak/spi/security/package-info.java Thu Jan  7 10:29:57 2021
@@ -14,7 +14,7 @@
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
-@Version("2.2.1")
+@Version("2.3.0")
 package org.apache.jackrabbit.oak.spi.security;
 
 import org.osgi.annotation.versioning.Version;

Modified: jackrabbit/oak/trunk/oak-security-spi/src/main/java/org/apache/jackrabbit/oak/spi/security/principal/package-info.java
URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-security-spi/src/main/java/org/apache/jackrabbit/oak/spi/security/principal/package-info.java?rev=1885237&r1=1885236&r2=1885237&view=diff
==============================================================================
--- jackrabbit/oak/trunk/oak-security-spi/src/main/java/org/apache/jackrabbit/oak/spi/security/principal/package-info.java (original)
+++ jackrabbit/oak/trunk/oak-security-spi/src/main/java/org/apache/jackrabbit/oak/spi/security/principal/package-info.java Thu Jan  7 10:29:57 2021
@@ -14,7 +14,7 @@
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
-@Version("2.0.0")
+@Version("2.1.0")
 package org.apache.jackrabbit.oak.spi.security.principal;
 
 import org.osgi.annotation.versioning.Version;

Modified: jackrabbit/oak/trunk/oak-security-spi/src/main/java/org/apache/jackrabbit/oak/spi/security/privilege/package-info.java
URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-security-spi/src/main/java/org/apache/jackrabbit/oak/spi/security/privilege/package-info.java?rev=1885237&r1=1885236&r2=1885237&view=diff
==============================================================================
--- jackrabbit/oak/trunk/oak-security-spi/src/main/java/org/apache/jackrabbit/oak/spi/security/privilege/package-info.java (original)
+++ jackrabbit/oak/trunk/oak-security-spi/src/main/java/org/apache/jackrabbit/oak/spi/security/privilege/package-info.java Thu Jan  7 10:29:57 2021
@@ -14,7 +14,7 @@
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
-@Version("1.3.0")
+@Version("1.4.0")
 package org.apache.jackrabbit.oak.spi.security.privilege;
 
 import org.osgi.annotation.versioning.Version;

Modified: jackrabbit/oak/trunk/oak-security-spi/src/main/java/org/apache/jackrabbit/oak/spi/security/user/package-info.java
URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-security-spi/src/main/java/org/apache/jackrabbit/oak/spi/security/user/package-info.java?rev=1885237&r1=1885236&r2=1885237&view=diff
==============================================================================
--- jackrabbit/oak/trunk/oak-security-spi/src/main/java/org/apache/jackrabbit/oak/spi/security/user/package-info.java (original)
+++ jackrabbit/oak/trunk/oak-security-spi/src/main/java/org/apache/jackrabbit/oak/spi/security/user/package-info.java Thu Jan  7 10:29:57 2021
@@ -14,7 +14,7 @@
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
-@Version("2.3.1")
+@Version("2.4.0")
 package org.apache.jackrabbit.oak.spi.security.user;
 
 import org.osgi.annotation.versioning.Version;

Modified: jackrabbit/oak/trunk/oak-security-spi/src/test/java/org/apache/jackrabbit/oak/spi/security/CompositeConfigurationTest.java
URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-security-spi/src/test/java/org/apache/jackrabbit/oak/spi/security/CompositeConfigurationTest.java?rev=1885237&r1=1885236&r2=1885237&view=diff
==============================================================================
--- jackrabbit/oak/trunk/oak-security-spi/src/test/java/org/apache/jackrabbit/oak/spi/security/CompositeConfigurationTest.java (original)
+++ jackrabbit/oak/trunk/oak-security-spi/src/test/java/org/apache/jackrabbit/oak/spi/security/CompositeConfigurationTest.java Thu Jan  7 10:29:57 2021
@@ -16,11 +16,9 @@
  */
 package org.apache.jackrabbit.oak.spi.security;
 
-import java.security.Principal;
-import java.util.List;
-import java.util.Set;
 import com.google.common.collect.ImmutableList;
 import com.google.common.collect.ImmutableSet;
+import com.google.common.collect.Iterables;
 import org.apache.jackrabbit.oak.plugins.tree.RootProvider;
 import org.apache.jackrabbit.oak.plugins.tree.TreeProvider;
 import org.apache.jackrabbit.oak.spi.commit.CommitHook;
@@ -31,7 +29,11 @@ import org.apache.jackrabbit.oak.spi.lif
 import org.apache.jackrabbit.oak.spi.lifecycle.CompositeWorkspaceInitializer;
 import org.apache.jackrabbit.oak.spi.lifecycle.RepositoryInitializer;
 import org.apache.jackrabbit.oak.spi.lifecycle.WorkspaceInitializer;
+import org.apache.jackrabbit.oak.spi.security.authentication.LoginModuleMonitor;
+import org.apache.jackrabbit.oak.spi.security.authentication.LoginModuleStats;
 import org.apache.jackrabbit.oak.spi.xml.ProtectedItemImporter;
+import org.apache.jackrabbit.oak.stats.Monitor;
+import org.apache.jackrabbit.oak.stats.StatisticsProvider;
 import org.jetbrains.annotations.NotNull;
 import org.jetbrains.annotations.Nullable;
 import org.junit.Before;
@@ -39,6 +41,10 @@ import org.junit.Test;
 import org.mockito.Mockito;
 import org.osgi.framework.Constants;
 
+import java.security.Principal;
+import java.util.List;
+import java.util.Set;
+
 import static org.junit.Assert.assertArrayEquals;
 import static org.junit.Assert.assertEquals;
 import static org.junit.Assert.assertFalse;
@@ -384,4 +390,27 @@ public class CompositeConfigurationTest
         assertEquals(ImmutableSet.copyOf(ConfigurationParameters.of(params, params2).keySet()), ImmutableSet.copyOf(compositeParams.keySet()));
         assertEquals("valueA2", compositeParams.getConfigValue("a", "def"));
     }
+
+    @Test
+    public void testGetMonitors() {
+        StatisticsProvider statisticsProvider = StatisticsProvider.NOOP;
+        assertTrue(Iterables.isEmpty(compositeConfiguration.getMonitors(statisticsProvider)));
+
+        addConfiguration(new SecurityConfiguration.Default());
+        assertTrue(Iterables.isEmpty(compositeConfiguration.getMonitors(statisticsProvider)));
+
+        Monitor<LoginModuleMonitor> monitor = new LoginModuleStats(statisticsProvider);
+        SecurityConfiguration withMonitors = new SecurityConfiguration.Default() {
+            @NotNull
+            @Override
+            public Iterable<Monitor<?>> getMonitors(@NotNull StatisticsProvider statisticsProvider) {
+                return ImmutableList.of(monitor);
+            }
+        };
+        addConfiguration(withMonitors);
+
+        Iterable<Monitor<?>> monitors = compositeConfiguration.getMonitors(statisticsProvider);
+        assertEquals(1, Iterables.size(monitors));
+        assertSame(monitor, monitors.iterator().next());
+    }
 }

Added: jackrabbit/oak/trunk/oak-security-spi/src/test/java/org/apache/jackrabbit/oak/spi/security/authentication/LoginModuleMonitorTest.java
URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-security-spi/src/test/java/org/apache/jackrabbit/oak/spi/security/authentication/LoginModuleMonitorTest.java?rev=1885237&view=auto
==============================================================================
--- jackrabbit/oak/trunk/oak-security-spi/src/test/java/org/apache/jackrabbit/oak/spi/security/authentication/LoginModuleMonitorTest.java (added)
+++ jackrabbit/oak/trunk/oak-security-spi/src/test/java/org/apache/jackrabbit/oak/spi/security/authentication/LoginModuleMonitorTest.java Thu Jan  7 10:29:57 2021
@@ -0,0 +1,40 @@
+package org.apache.jackrabbit.oak.spi.security.authentication;
+
+import org.junit.Test;
+import org.mockito.Answers;
+
+import static org.junit.Assert.assertSame;
+import static org.junit.Assert.assertTrue;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.reset;
+import static org.mockito.Mockito.spy;
+import static org.mockito.Mockito.verifyNoInteractions;
+import static org.mockito.Mockito.withSettings;
+
+public class LoginModuleMonitorTest {
+
+    private final LoginModuleMonitor noop = spy(LoginModuleMonitor.NOOP);
+    private final LoginModuleMonitor monitor = mock(LoginModuleMonitor.class, withSettings().defaultAnswer(Answers.CALLS_REAL_METHODS));
+
+    @Test
+    public void testLoginError() {
+        noop.loginError();
+        verifyNoInteractions(monitor);
+        reset(noop, monitor);
+
+        monitor.loginError();
+        verifyNoInteractions(noop);
+    }
+
+    @Test
+    public void testGetMonitorClass() {
+        assertSame(LoginModuleMonitor.class, noop.getMonitorClass());
+        assertSame(LoginModuleMonitor.class, monitor.getMonitorClass());
+    }
+
+    @Test
+    public void testGetMonitorProperties() {
+        assertTrue(noop.getMonitorProperties().isEmpty());
+        assertTrue(monitor.getMonitorProperties().isEmpty());
+    }
+}

Propchange: jackrabbit/oak/trunk/oak-security-spi/src/test/java/org/apache/jackrabbit/oak/spi/security/authentication/LoginModuleMonitorTest.java
------------------------------------------------------------------------------
    svn:eol-style = native

Modified: jackrabbit/oak/trunk/oak-security-spi/src/test/java/org/apache/jackrabbit/oak/spi/security/authentication/LoginModuleStatsTest.java
URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-security-spi/src/test/java/org/apache/jackrabbit/oak/spi/security/authentication/LoginModuleStatsTest.java?rev=1885237&r1=1885236&r2=1885237&view=diff
==============================================================================
--- jackrabbit/oak/trunk/oak-security-spi/src/test/java/org/apache/jackrabbit/oak/spi/security/authentication/LoginModuleStatsTest.java (original)
+++ jackrabbit/oak/trunk/oak-security-spi/src/test/java/org/apache/jackrabbit/oak/spi/security/authentication/LoginModuleStatsTest.java Thu Jan  7 10:29:57 2021
@@ -29,7 +29,7 @@ import org.junit.Test;
 public class LoginModuleStatsTest {
 
     @Test
-    public void testLoginError() throws Exception {
+    public void testLoginError() {
         ScheduledExecutorService executor = Executors.newSingleThreadScheduledExecutor();
         StatisticsProvider sp = new DefaultStatisticsProvider(executor);