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/03/09 15:53:40 UTC
svn commit: r1887377 - in /jackrabbit/oak/trunk/oak-auth-external/src:
main/java/org/apache/jackrabbit/oak/spi/security/authentication/external/impl/
main/java/org/apache/jackrabbit/oak/spi/security/authentication/external/impl/monitor/
main/java/org/a...
Author: angela
Date: Tue Mar 9 15:53:40 2021
New Revision: 1887377
URL: http://svn.apache.org/viewvc?rev=1887377&view=rev
Log:
OAK-9368 : Monitoring for external authentication
Added:
jackrabbit/oak/trunk/oak-auth-external/src/main/java/org/apache/jackrabbit/oak/spi/security/authentication/external/impl/monitor/
jackrabbit/oak/trunk/oak-auth-external/src/main/java/org/apache/jackrabbit/oak/spi/security/authentication/external/impl/monitor/ExternalIdentityMonitor.java (with props)
jackrabbit/oak/trunk/oak-auth-external/src/main/java/org/apache/jackrabbit/oak/spi/security/authentication/external/impl/monitor/ExternalIdentityMonitorImpl.java (with props)
jackrabbit/oak/trunk/oak-auth-external/src/test/java/org/apache/jackrabbit/oak/spi/security/authentication/external/impl/monitor/
jackrabbit/oak/trunk/oak-auth-external/src/test/java/org/apache/jackrabbit/oak/spi/security/authentication/external/impl/monitor/ExternalIdentityMonitorImplTest.java (with props)
Modified:
jackrabbit/oak/trunk/oak-auth-external/src/main/java/org/apache/jackrabbit/oak/spi/security/authentication/external/impl/ExternalLoginModule.java
jackrabbit/oak/trunk/oak-auth-external/src/main/java/org/apache/jackrabbit/oak/spi/security/authentication/external/impl/principal/ExternalPrincipalConfiguration.java
jackrabbit/oak/trunk/oak-auth-external/src/test/java/org/apache/jackrabbit/oak/spi/security/authentication/external/impl/ExternalLoginModuleTest.java
jackrabbit/oak/trunk/oak-auth-external/src/test/java/org/apache/jackrabbit/oak/spi/security/authentication/external/impl/principal/ExternalPrincipalConfigurationTest.java
Modified: jackrabbit/oak/trunk/oak-auth-external/src/main/java/org/apache/jackrabbit/oak/spi/security/authentication/external/impl/ExternalLoginModule.java
URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-auth-external/src/main/java/org/apache/jackrabbit/oak/spi/security/authentication/external/impl/ExternalLoginModule.java?rev=1887377&r1=1887376&r2=1887377&view=diff
==============================================================================
--- jackrabbit/oak/trunk/oak-auth-external/src/main/java/org/apache/jackrabbit/oak/spi/security/authentication/external/impl/ExternalLoginModule.java (original)
+++ jackrabbit/oak/trunk/oak-auth-external/src/main/java/org/apache/jackrabbit/oak/spi/security/authentication/external/impl/ExternalLoginModule.java Tue Mar 9 15:53:40 2021
@@ -16,6 +16,7 @@
*/
package org.apache.jackrabbit.oak.spi.security.authentication.external.impl;
+import com.google.common.base.Stopwatch;
import com.google.common.collect.Iterables;
import org.apache.jackrabbit.api.security.user.UserManager;
import org.apache.jackrabbit.oak.api.AuthInfo;
@@ -42,6 +43,7 @@ import org.apache.jackrabbit.oak.spi.sec
import org.apache.jackrabbit.oak.spi.security.authentication.external.SyncManager;
import org.apache.jackrabbit.oak.spi.security.authentication.external.SyncResult;
import org.apache.jackrabbit.oak.spi.security.authentication.external.SyncedIdentity;
+import org.apache.jackrabbit.oak.spi.security.authentication.external.impl.monitor.ExternalIdentityMonitor;
import org.apache.jackrabbit.oak.spi.whiteboard.Whiteboard;
import org.apache.jackrabbit.oak.spi.whiteboard.WhiteboardUtils;
import org.jetbrains.annotations.NotNull;
@@ -59,9 +61,12 @@ import java.util.HashMap;
import java.util.Map;
import java.util.Objects;
import java.util.Set;
+import java.util.concurrent.TimeUnit;
import java.util.stream.Collectors;
import java.util.stream.Stream;
+import static java.util.concurrent.TimeUnit.NANOSECONDS;
+
/**
* {@code ExternalLoginModule} implements a {@code LoginModule} that uses an
* {@link ExternalIdentityProvider} for authentication.
@@ -116,6 +121,8 @@ public class ExternalLoginModule extends
private Set<? extends Principal> principals;
private AuthInfo authInfo;
+ private ExternalIdentityMonitor monitor;
+
/**
* Default constructor for the OSGIi LoginModuleFactory case and the default non-OSGi JAAS case.
*/
@@ -186,6 +193,12 @@ public class ExternalLoginModule extends
} else {
log.debug("No 'SupportedCredentials' configured. Using default implementation supporting 'SimpleCredentials'.");
}
+
+ monitor = WhiteboardUtils.getService(whiteboard, ExternalIdentityMonitor.class);
+ if (monitor == null) {
+ log.debug("No ExternalIdentityMonitor registered.");
+ monitor = ExternalIdentityMonitor.NOOP;
+ }
}
@Override
@@ -268,6 +281,7 @@ public class ExternalLoginModule extends
} catch (SyncException e) {
log.error("SyncHandler {} throws sync exception for '{}'", syncHandler.getName(), logId, e);
onError();
+ monitor.syncFailed(e);
throw createLoginException(e, "Error while syncing user.");
}
}
@@ -364,6 +378,7 @@ public class ExternalLoginModule extends
private void syncUser(@NotNull ExternalUser user, @Nullable UserManager userMgr) throws SyncException {
Root root = getRootOrThrow();
UserManager userManager = getUsermanagerOrThrow(userMgr);
+ Stopwatch watch = Stopwatch.createStarted();
int numAttempt = 0;
while (numAttempt++ < MAX_SYNC_ATTEMPTS) {
SyncContext context = syncHandler.createContext(idp, userManager, new ValueFactoryImpl(root, NamePathMapper.DEFAULT));
@@ -376,6 +391,7 @@ public class ExternalLoginModule extends
timer.mark("commit");
}
debug("syncUser({}) {}, status: {}", user.getId(), timer.getString(), syncResult.getStatus().toString());
+ monitor.doneSyncExternalIdentity(watch.elapsed(NANOSECONDS), syncResult, numAttempt-1);
return;
} catch (CommitFailedException e) {
log.warn("User synchronization failed during commit: {}. (attempt {}/{})", e, numAttempt, MAX_SYNC_ATTEMPTS);
@@ -396,13 +412,15 @@ public class ExternalLoginModule extends
UserManager userManager = getUsermanagerOrThrow(userMgr);
SyncContext context = syncHandler.createContext(idp, userManager, new ValueFactoryImpl(root, NamePathMapper.DEFAULT));
try {
+ Stopwatch watch = Stopwatch.createStarted();
DebugTimer timer = new DebugTimer();
context = syncHandler.createContext(idp, userManager, new ValueFactoryImpl(root, NamePathMapper.DEFAULT));
- context.sync(id);
+ SyncResult syncResult = context.sync(id);
timer.mark("sync");
root.commit();
timer.mark("commit");
debug("validateUser({}) {}", id, timer.getString());
+ monitor.doneSyncId(watch.elapsed(NANOSECONDS), syncResult);
} catch (CommitFailedException e) {
throw new SyncException("User synchronization failed during commit.", e);
} finally {
Added: jackrabbit/oak/trunk/oak-auth-external/src/main/java/org/apache/jackrabbit/oak/spi/security/authentication/external/impl/monitor/ExternalIdentityMonitor.java
URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-auth-external/src/main/java/org/apache/jackrabbit/oak/spi/security/authentication/external/impl/monitor/ExternalIdentityMonitor.java?rev=1887377&view=auto
==============================================================================
--- jackrabbit/oak/trunk/oak-auth-external/src/main/java/org/apache/jackrabbit/oak/spi/security/authentication/external/impl/monitor/ExternalIdentityMonitor.java (added)
+++ jackrabbit/oak/trunk/oak-auth-external/src/main/java/org/apache/jackrabbit/oak/spi/security/authentication/external/impl/monitor/ExternalIdentityMonitor.java Tue Mar 9 15:53:40 2021
@@ -0,0 +1,67 @@
+/*
+ * 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.spi.security.authentication.external.impl.monitor;
+
+import org.apache.jackrabbit.oak.spi.security.authentication.external.ExternalIdentity;
+import org.apache.jackrabbit.oak.spi.security.authentication.external.SyncException;
+import org.apache.jackrabbit.oak.spi.security.authentication.external.SyncResult;
+import org.apache.jackrabbit.oak.stats.Monitor;
+import org.jetbrains.annotations.NotNull;
+
+import java.util.Collections;
+import java.util.Map;
+
+public interface ExternalIdentityMonitor extends Monitor<ExternalIdentityMonitor> {
+
+ ExternalIdentityMonitor NOOP = new ExternalIdentityMonitor() {};
+
+ /**
+ * Mark the successful completion of {@link org.apache.jackrabbit.oak.spi.security.authentication.external.SyncContext#sync(ExternalIdentity)}.
+ *
+ * @param timeTakenNanos Time in nanoseconds spend to complete {@link org.apache.jackrabbit.oak.spi.security.authentication.external.SyncContext#sync(ExternalIdentity)}
+ * @param result The result of the sync operation.
+ * @param retryCount The number of retries needed to complete the sync.
+ */
+ default void doneSyncExternalIdentity(long timeTakenNanos, @NotNull SyncResult result, int retryCount) {};
+
+ /**
+ * Mark the successful completion of {@link org.apache.jackrabbit.oak.spi.security.authentication.external.SyncContext#sync(String)}.
+ *
+ * @param timeTakenNanos Time in nanoseconds spend to complete {@link org.apache.jackrabbit.oak.spi.security.authentication.external.SyncContext#sync(String)}
+ * @param result The result of the sync operation.
+ */
+ default void doneSyncId(long timeTakenNanos, @NotNull SyncResult result) {};
+
+ /**
+ * Mark the failure of a sync operation that resulted in the given {@link SyncException}.
+ *
+ * @param syncException The sync exception.
+ */
+ default void syncFailed(@NotNull SyncException syncException) {};
+
+ @Override
+ @NotNull
+ default Class<ExternalIdentityMonitor> getMonitorClass() {
+ return ExternalIdentityMonitor.class;
+ }
+
+ @Override
+ @NotNull
+ default Map<Object, Object> getMonitorProperties() {
+ return Collections.emptyMap();
+ }
+}
\ No newline at end of file
Propchange: jackrabbit/oak/trunk/oak-auth-external/src/main/java/org/apache/jackrabbit/oak/spi/security/authentication/external/impl/monitor/ExternalIdentityMonitor.java
------------------------------------------------------------------------------
svn:eol-style = native
Added: jackrabbit/oak/trunk/oak-auth-external/src/main/java/org/apache/jackrabbit/oak/spi/security/authentication/external/impl/monitor/ExternalIdentityMonitorImpl.java
URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-auth-external/src/main/java/org/apache/jackrabbit/oak/spi/security/authentication/external/impl/monitor/ExternalIdentityMonitorImpl.java?rev=1887377&view=auto
==============================================================================
--- jackrabbit/oak/trunk/oak-auth-external/src/main/java/org/apache/jackrabbit/oak/spi/security/authentication/external/impl/monitor/ExternalIdentityMonitorImpl.java (added)
+++ jackrabbit/oak/trunk/oak-auth-external/src/main/java/org/apache/jackrabbit/oak/spi/security/authentication/external/impl/monitor/ExternalIdentityMonitorImpl.java Tue Mar 9 15:53:40 2021
@@ -0,0 +1,64 @@
+/*
+ * 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.spi.security.authentication.external.impl.monitor;
+
+import org.apache.jackrabbit.oak.spi.security.authentication.external.SyncException;
+import org.apache.jackrabbit.oak.spi.security.authentication.external.SyncResult;
+import org.apache.jackrabbit.oak.stats.MeterStats;
+import org.apache.jackrabbit.oak.stats.StatisticsProvider;
+import org.apache.jackrabbit.oak.stats.StatsOptions;
+import org.apache.jackrabbit.oak.stats.TimerStats;
+import org.jetbrains.annotations.NotNull;
+
+import static java.util.concurrent.TimeUnit.NANOSECONDS;
+
+public class ExternalIdentityMonitorImpl implements ExternalIdentityMonitor {
+
+ private final TimerStats syncTimer;
+ private final MeterStats syncRetries;
+ private final TimerStats syncIdTimer;
+ private final MeterStats syncFailed;
+
+ public ExternalIdentityMonitorImpl(@NotNull StatisticsProvider statisticsProvider) {
+ syncTimer = statisticsProvider.getTimer("security.authentication.external.sync_external_identity.timer", StatsOptions.METRICS_ONLY);
+ syncRetries = statisticsProvider.getMeter("security.authentication.external.sync_external_identity.retries", StatsOptions.DEFAULT);
+ syncIdTimer = statisticsProvider.getTimer("security.authentication.external.sync_id.timer", StatsOptions.METRICS_ONLY);
+ syncFailed = statisticsProvider.getMeter("security.authentication.external.sync.failed", StatsOptions.DEFAULT);
+ }
+
+ @Override
+ public void doneSyncExternalIdentity(long timeTakenNanos, @NotNull SyncResult result, int retryCount) {
+ // note: currently the sync-result is ignored. further improvements might choose to exclude certain
+ // results or refine the stats gather by result type.
+ syncTimer.update(timeTakenNanos, NANOSECONDS);
+ if (retryCount > 0){
+ syncRetries.mark(retryCount);
+ }
+ }
+
+ @Override
+ public void doneSyncId(long timeTakenNanos, @NotNull SyncResult result) {
+ // note: currently the sync-result is ignored. further improvements might choose to exclude certain
+ // results or refine the stats gather by result type.
+ syncIdTimer.update(timeTakenNanos, NANOSECONDS);
+ }
+
+ @Override
+ public void syncFailed(@NotNull SyncException syncException) {
+ syncFailed.mark();
+ }
+}
Propchange: jackrabbit/oak/trunk/oak-auth-external/src/main/java/org/apache/jackrabbit/oak/spi/security/authentication/external/impl/monitor/ExternalIdentityMonitorImpl.java
------------------------------------------------------------------------------
svn:eol-style = native
Modified: jackrabbit/oak/trunk/oak-auth-external/src/main/java/org/apache/jackrabbit/oak/spi/security/authentication/external/impl/principal/ExternalPrincipalConfiguration.java
URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-auth-external/src/main/java/org/apache/jackrabbit/oak/spi/security/authentication/external/impl/principal/ExternalPrincipalConfiguration.java?rev=1887377&r1=1887376&r2=1887377&view=diff
==============================================================================
--- jackrabbit/oak/trunk/oak-auth-external/src/main/java/org/apache/jackrabbit/oak/spi/security/authentication/external/impl/principal/ExternalPrincipalConfiguration.java (original)
+++ jackrabbit/oak/trunk/oak-auth-external/src/main/java/org/apache/jackrabbit/oak/spi/security/authentication/external/impl/principal/ExternalPrincipalConfiguration.java Tue Mar 9 15:53:40 2021
@@ -42,12 +42,16 @@ import org.apache.jackrabbit.oak.spi.sec
import org.apache.jackrabbit.oak.spi.security.SecurityConfiguration;
import org.apache.jackrabbit.oak.spi.security.SecurityProvider;
import org.apache.jackrabbit.oak.spi.security.authentication.external.impl.ExternalIdentityConstants;
+import org.apache.jackrabbit.oak.spi.security.authentication.external.impl.monitor.ExternalIdentityMonitor;
+import org.apache.jackrabbit.oak.spi.security.authentication.external.impl.monitor.ExternalIdentityMonitorImpl;
import org.apache.jackrabbit.oak.spi.security.principal.EmptyPrincipalProvider;
import org.apache.jackrabbit.oak.spi.security.principal.PrincipalConfiguration;
import org.apache.jackrabbit.oak.spi.security.principal.PrincipalManagerImpl;
import org.apache.jackrabbit.oak.spi.security.principal.PrincipalProvider;
import org.apache.jackrabbit.oak.spi.security.user.UserConfiguration;
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.framework.BundleContext;
import org.slf4j.Logger;
@@ -85,6 +89,8 @@ public class ExternalPrincipalConfigurat
private SyncConfigTracker syncConfigTracker;
private SyncHandlerMappingTracker syncHandlerMappingTracker;
+ private ExternalIdentityMonitor monitor = ExternalIdentityMonitor.NOOP;
+
@SuppressWarnings("UnusedDeclaration")
public ExternalPrincipalConfiguration() {
super();
@@ -137,6 +143,12 @@ public class ExternalPrincipalConfigurat
return Collections.singletonList(new ExternalIdentityImporter());
}
+ @Override
+ public @NotNull Iterable<Monitor<?>> getMonitors(@NotNull StatisticsProvider statisticsProvider) {
+ monitor = new ExternalIdentityMonitorImpl(statisticsProvider);
+ return Collections.singleton(monitor);
+ }
+
@NotNull
@Override
public List<ThreeWayConflictHandler> getConflictHandlers() {
Modified: jackrabbit/oak/trunk/oak-auth-external/src/test/java/org/apache/jackrabbit/oak/spi/security/authentication/external/impl/ExternalLoginModuleTest.java
URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-auth-external/src/test/java/org/apache/jackrabbit/oak/spi/security/authentication/external/impl/ExternalLoginModuleTest.java?rev=1887377&r1=1887376&r2=1887377&view=diff
==============================================================================
--- jackrabbit/oak/trunk/oak-auth-external/src/test/java/org/apache/jackrabbit/oak/spi/security/authentication/external/impl/ExternalLoginModuleTest.java (original)
+++ jackrabbit/oak/trunk/oak-auth-external/src/test/java/org/apache/jackrabbit/oak/spi/security/authentication/external/impl/ExternalLoginModuleTest.java Tue Mar 9 15:53:40 2021
@@ -19,6 +19,7 @@ package org.apache.jackrabbit.oak.spi.se
import com.google.common.collect.ImmutableMap;
import com.google.common.collect.ImmutableSet;
import com.google.common.collect.Maps;
+import org.apache.jackrabbit.api.security.user.Authorizable;
import org.apache.jackrabbit.api.security.user.User;
import org.apache.jackrabbit.oak.AbstractSecurityTest;
import org.apache.jackrabbit.oak.api.AuthInfo;
@@ -39,7 +40,9 @@ import org.apache.jackrabbit.oak.spi.sec
import org.apache.jackrabbit.oak.spi.security.authentication.external.ExternalIdentityProviderManager;
import org.apache.jackrabbit.oak.spi.security.authentication.external.SyncException;
import org.apache.jackrabbit.oak.spi.security.authentication.external.SyncManager;
+import org.apache.jackrabbit.oak.spi.security.authentication.external.SyncResult;
import org.apache.jackrabbit.oak.spi.security.authentication.external.TestIdentityProvider;
+import org.apache.jackrabbit.oak.spi.security.authentication.external.impl.monitor.ExternalIdentityMonitor;
import org.apache.jackrabbit.oak.spi.security.principal.EmptyPrincipalProvider;
import org.apache.jackrabbit.oak.spi.security.principal.PrincipalConfiguration;
import org.apache.jackrabbit.oak.spi.security.principal.PrincipalImpl;
@@ -49,6 +52,7 @@ import org.apache.jackrabbit.oak.spi.whi
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.junit.After;
+import org.junit.Before;
import org.junit.Test;
import javax.jcr.Credentials;
@@ -89,8 +93,8 @@ import static org.mockito.Mockito.never;
import static org.mockito.Mockito.spy;
import static org.mockito.Mockito.times;
import static org.mockito.Mockito.verify;
-import static org.mockito.Mockito.verifyNoInteractions;
import static org.mockito.Mockito.verifyNoMoreInteractions;
+import static org.mockito.Mockito.verifyNoInteractions;
import static org.mockito.Mockito.when;
import static org.mockito.Mockito.withSettings;
@@ -102,13 +106,23 @@ public class ExternalLoginModuleTest ext
private final ExternalIdentityProviderManager extIPMgr = mock(ExternalIdentityProviderManager.class);
private final SyncManager syncManager = mock(SyncManager.class);
private final LoginModuleMonitor monitor = mock(LoginModuleMonitor.class);
+ private final ExternalIdentityMonitor externalIdentityMonitor = mock(ExternalIdentityMonitor.class);
+
+ @Before
+ public void before() throws Exception {
+ super.before();
+ wb.register(ExternalIdentityMonitor.class, externalIdentityMonitor, Collections.emptyMap());
+ }
@After
- public void after() {
- clearInvocations(monitor, syncManager, extIPMgr, wb);
+ public void after() throws Exception {
+ try {
+ clearInvocations(externalIdentityMonitor, monitor, syncManager, extIPMgr);
+ } finally {
+ super.after();
+ }
}
- @NotNull
private CallbackHandler createCallbackHandler(@Nullable Whiteboard wb, @Nullable ContentRepository contentRepository, @Nullable SecurityProvider securityProvider, @Nullable Credentials creds) {
return callbacks -> {
for (Callback cb : callbacks) {
@@ -120,13 +134,19 @@ public class ExternalLoginModuleTest ext
((RepositoryCallback) cb).setLoginModuleMonitor(monitor);
} else if (cb instanceof CredentialsCallback) {
((CredentialsCallback) cb).setCredentials(creds);
- }else {
+ } else {
throw new UnsupportedCallbackException(cb);
}
}
};
}
+ private void verifySyncException(@NotNull Exception e) {
+ assertTrue(e.getCause() instanceof SyncException);
+ verify(externalIdentityMonitor).syncFailed((SyncException) e.getCause());
+ verifyNoMoreInteractions(externalIdentityMonitor);
+ }
+
@Test
public void testInitializeMissingWhiteboard() throws LoginException {
loginModule.setIdpManager(extIPMgr);
@@ -383,7 +403,7 @@ public class ExternalLoginModuleTest ext
try {
loginModule.login();
} catch (LoginException e) {
- assertTrue(e.getCause() instanceof SyncException);
+ verifySyncException(e);
throw e;
} finally {
verify(monitor, times(2)).loginError();
@@ -411,7 +431,7 @@ public class ExternalLoginModuleTest ext
try {
loginModule.login();
} catch (LoginException e) {
- assertTrue(e.getCause() instanceof SyncException);
+ verifySyncException(e);
throw e;
} finally {
verify(monitor, times(2)).loginError();
@@ -444,7 +464,7 @@ public class ExternalLoginModuleTest ext
try {
loginModule.login();
} catch (LoginException e) {
- assertTrue(e.getCause() instanceof SyncException);
+ verifySyncException(e);
throw e;
} finally {
verify(monitor).loginError();
@@ -477,6 +497,7 @@ public class ExternalLoginModuleTest ext
assertFalse(loginModule.commit());
assertFalse(loginModule.logout());
+ verify(externalIdentityMonitor).doneSyncId(anyLong(), any(SyncResult.class));
verifyNoInteractions(monitor);
}
@@ -508,7 +529,7 @@ public class ExternalLoginModuleTest ext
try {
loginModule.login();
} catch (LoginException e) {
- assertTrue(e.getCause() instanceof SyncException);
+ verifySyncException(e);
throw e;
} finally {
verify(monitor).loginError();
@@ -535,4 +556,30 @@ public class ExternalLoginModuleTest ext
verifyNoMoreInteractions(monitor);
}
}
+
+ @Test
+ public void testSyncUser() throws Exception {
+ when(extIPMgr.getProvider(DEFAULT_IDP_NAME)).thenReturn(new TestIdentityProvider());
+ when(syncManager.getSyncHandler("syncHandler")).thenReturn(new DefaultSyncHandler(new DefaultSyncConfigImpl().setName("syncHandler")));
+
+ wb.register(ExternalIdentityProviderManager.class, extIPMgr, Collections.emptyMap());
+ wb.register(SyncManager.class, syncManager, Collections.emptyMap());
+
+ Credentials crds = new SimpleCredentials("testUser", new char[0]);
+ CallbackHandler cbh = createCallbackHandler(wb, getContentRepository(), getSecurityProvider(), crds);
+
+ loginModule.initialize(new Subject(), cbh, new HashMap<>(), ImmutableMap.of(PARAM_IDP_NAME, DEFAULT_IDP_NAME, PARAM_SYNC_HANDLER_NAME, "syncHandler"));
+ assertTrue(loginModule.login());
+ root.refresh();
+ Authorizable a = getUserManager(root).getAuthorizable("testUser");
+ assertNotNull(a);
+ assertTrue(a.hasProperty(REP_EXTERNAL_ID));
+
+ assertTrue(loginModule.commit());
+ assertTrue(loginModule.logout());
+
+ verify(externalIdentityMonitor).doneSyncExternalIdentity(anyLong(), any(SyncResult.class), anyInt());
+ verify(monitor).principalsCollected(anyLong(), anyInt());
+ verifyNoMoreInteractions(externalIdentityMonitor, monitor);
+ }
}
\ No newline at end of file
Added: jackrabbit/oak/trunk/oak-auth-external/src/test/java/org/apache/jackrabbit/oak/spi/security/authentication/external/impl/monitor/ExternalIdentityMonitorImplTest.java
URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-auth-external/src/test/java/org/apache/jackrabbit/oak/spi/security/authentication/external/impl/monitor/ExternalIdentityMonitorImplTest.java?rev=1887377&view=auto
==============================================================================
--- jackrabbit/oak/trunk/oak-auth-external/src/test/java/org/apache/jackrabbit/oak/spi/security/authentication/external/impl/monitor/ExternalIdentityMonitorImplTest.java (added)
+++ jackrabbit/oak/trunk/oak-auth-external/src/test/java/org/apache/jackrabbit/oak/spi/security/authentication/external/impl/monitor/ExternalIdentityMonitorImplTest.java Tue Mar 9 15:53:40 2021
@@ -0,0 +1,113 @@
+/*
+ * 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.spi.security.authentication.external.impl.monitor;
+
+import org.apache.jackrabbit.oak.spi.security.authentication.external.SyncException;
+import org.apache.jackrabbit.oak.spi.security.authentication.external.SyncResult;
+import org.apache.jackrabbit.oak.stats.CounterStats;
+import org.apache.jackrabbit.oak.stats.MeterStats;
+import org.apache.jackrabbit.oak.stats.StatisticsProvider;
+import org.apache.jackrabbit.oak.stats.StatsOptions;
+import org.apache.jackrabbit.oak.stats.TimerStats;
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Test;
+
+import static java.util.concurrent.TimeUnit.NANOSECONDS;
+import static org.junit.Assert.assertSame;
+import static org.junit.Assert.assertTrue;
+import static org.mockito.ArgumentMatchers.any;
+import static org.mockito.ArgumentMatchers.anyString;
+import static org.mockito.Mockito.clearInvocations;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.times;
+import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.verifyNoInteractions;
+import static org.mockito.Mockito.verifyNoMoreInteractions;
+import static org.mockito.Mockito.when;
+
+public class ExternalIdentityMonitorImplTest {
+
+ private final MeterStats meter = mock(MeterStats.class);
+ private final TimerStats timer = mock(TimerStats.class);
+ private final CounterStats counter = mock(CounterStats.class);
+
+ private StatisticsProvider statisticsProvider;
+ private ExternalIdentityMonitorImpl monitor;
+
+ @Before
+ public void before() {
+ statisticsProvider = mockStatisticsProvider();
+ monitor = new ExternalIdentityMonitorImpl(statisticsProvider);
+ }
+
+ @After
+ public void after() {
+ clearInvocations(meter, timer, statisticsProvider);
+ }
+
+ private StatisticsProvider mockStatisticsProvider() {
+ StatisticsProvider statisticsProvider = mock(StatisticsProvider.class);
+ when(statisticsProvider.getMeter(anyString(), any(StatsOptions.class))).thenReturn(meter);
+ when(statisticsProvider.getTimer(anyString(), any(StatsOptions.class))).thenReturn(timer);
+ when(statisticsProvider.getCounterStats(anyString(), any(StatsOptions.class))).thenReturn(counter);
+ return statisticsProvider;
+ }
+
+ @Test
+ public void testConstructor() {
+ verify(statisticsProvider, times(2)).getMeter(anyString(), any(StatsOptions.class));
+ verify(statisticsProvider, times(2)).getTimer(anyString(), any(StatsOptions.class));
+ verifyNoMoreInteractions(statisticsProvider);
+ verifyNoInteractions(meter);
+ verifyNoInteractions(timer);
+ }
+
+ @Test
+ public void testDoneSyncExternalIdentity() {
+ monitor.doneSyncExternalIdentity(20, mock(SyncResult.class), 34);
+ verify(timer).update(20, NANOSECONDS);
+ verify(meter).mark(34);
+ verifyNoMoreInteractions(meter, timer);
+ }
+
+ @Test
+ public void testDoneSyncId() {
+ monitor.doneSyncId(5, mock(SyncResult.class));
+ verify(timer).update(5, NANOSECONDS);
+ verifyNoMoreInteractions(timer);
+ verifyNoInteractions(meter);
+ }
+
+ @Test
+ public void testSyncFailed() {
+ monitor.syncFailed(mock(SyncException.class));
+ verify(meter).mark();
+ verifyNoMoreInteractions(meter);
+ verifyNoInteractions(timer);
+ }
+
+ @Test
+ public void testGetMonitorClass() {
+ assertSame(ExternalIdentityMonitor.class, monitor.getMonitorClass());
+ }
+
+ @Test
+ public void testGetMonitorProperties() {
+ assertTrue(monitor.getMonitorProperties().isEmpty());
+ }
+}
\ No newline at end of file
Propchange: jackrabbit/oak/trunk/oak-auth-external/src/test/java/org/apache/jackrabbit/oak/spi/security/authentication/external/impl/monitor/ExternalIdentityMonitorImplTest.java
------------------------------------------------------------------------------
svn:eol-style = native
Modified: jackrabbit/oak/trunk/oak-auth-external/src/test/java/org/apache/jackrabbit/oak/spi/security/authentication/external/impl/principal/ExternalPrincipalConfigurationTest.java
URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-auth-external/src/test/java/org/apache/jackrabbit/oak/spi/security/authentication/external/impl/principal/ExternalPrincipalConfigurationTest.java?rev=1887377&r1=1887376&r2=1887377&view=diff
==============================================================================
--- jackrabbit/oak/trunk/oak-auth-external/src/test/java/org/apache/jackrabbit/oak/spi/security/authentication/external/impl/principal/ExternalPrincipalConfigurationTest.java (original)
+++ jackrabbit/oak/trunk/oak-auth-external/src/test/java/org/apache/jackrabbit/oak/spi/security/authentication/external/impl/principal/ExternalPrincipalConfigurationTest.java Tue Mar 9 15:53:40 2021
@@ -25,6 +25,7 @@ import java.util.Map;
import javax.jcr.ValueFactory;
import com.google.common.collect.ImmutableMap;
+import com.google.common.collect.Iterables;
import org.apache.jackrabbit.api.security.user.UserManager;
import org.apache.jackrabbit.oak.api.ContentSession;
import org.apache.jackrabbit.oak.namepath.NamePathMapper;
@@ -45,9 +46,12 @@ import org.apache.jackrabbit.oak.spi.sec
import org.apache.jackrabbit.oak.spi.security.authentication.external.impl.ExternalIdentityConstants;
import org.apache.jackrabbit.oak.spi.security.authentication.external.impl.ExternalLoginModuleFactory;
import org.apache.jackrabbit.oak.spi.security.authentication.external.impl.SyncHandlerMapping;
+import org.apache.jackrabbit.oak.spi.security.authentication.external.impl.monitor.ExternalIdentityMonitorImpl;
import org.apache.jackrabbit.oak.spi.security.principal.PrincipalConfiguration;
import org.apache.jackrabbit.oak.spi.security.principal.PrincipalProvider;
import org.apache.jackrabbit.oak.spi.xml.ProtectedItemImporter;
+import org.apache.jackrabbit.oak.stats.Monitor;
+import org.apache.jackrabbit.oak.stats.StatisticsProvider;
import org.apache.sling.testing.mock.osgi.MockOsgi;
import org.jetbrains.annotations.NotNull;
import org.junit.Ignore;
@@ -189,6 +193,13 @@ public class ExternalPrincipalConfigurat
}
@Test
+ public void testGetMonitors() {
+ Iterable<Monitor<?>> monitors = externalPrincipalConfiguration.getMonitors(StatisticsProvider.NOOP);
+ assertEquals(1, Iterables.size(monitors));
+ assertTrue(monitors.iterator().next() instanceof ExternalIdentityMonitorImpl);
+ }
+
+ @Test
public void testDeactivateWithNullTrackers() {
ExternalPrincipalConfiguration epc = new ExternalPrincipalConfiguration(getSecurityProvider());
MockOsgi.deactivate(epc, context.bundleContext(), Collections.emptyMap());