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 2016/06/06 09:10:48 UTC
svn commit: r1746975 - in /jackrabbit/oak/trunk/oak-auth-external/src:
main/java/org/apache/jackrabbit/oak/spi/security/authentication/external/impl/jmx/
test/java/org/apache/jackrabbit/oak/spi/security/authentication/external/impl/jmx/
Author: angela
Date: Mon Jun 6 09:10:48 2016
New Revision: 1746975
URL: http://svn.apache.org/viewvc?rev=1746975&view=rev
Log:
OAK-4379 : Batch mode for SyncMBeanImpl
Added:
jackrabbit/oak/trunk/oak-auth-external/src/test/java/org/apache/jackrabbit/oak/spi/security/authentication/external/impl/jmx/AbstractJmxTest.java
jackrabbit/oak/trunk/oak-auth-external/src/test/java/org/apache/jackrabbit/oak/spi/security/authentication/external/impl/jmx/DelegateeBatchOneTest.java
jackrabbit/oak/trunk/oak-auth-external/src/test/java/org/apache/jackrabbit/oak/spi/security/authentication/external/impl/jmx/DelegateeBatchTwoTest.java
jackrabbit/oak/trunk/oak-auth-external/src/test/java/org/apache/jackrabbit/oak/spi/security/authentication/external/impl/jmx/DelegateeTest.java
Modified:
jackrabbit/oak/trunk/oak-auth-external/src/main/java/org/apache/jackrabbit/oak/spi/security/authentication/external/impl/jmx/Delegatee.java
jackrabbit/oak/trunk/oak-auth-external/src/test/java/org/apache/jackrabbit/oak/spi/security/authentication/external/impl/jmx/SyncMBeanImplTest.java
Modified: jackrabbit/oak/trunk/oak-auth-external/src/main/java/org/apache/jackrabbit/oak/spi/security/authentication/external/impl/jmx/Delegatee.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/jmx/Delegatee.java?rev=1746975&r1=1746974&r2=1746975&view=diff
==============================================================================
--- jackrabbit/oak/trunk/oak-auth-external/src/main/java/org/apache/jackrabbit/oak/spi/security/authentication/external/impl/jmx/Delegatee.java (original)
+++ jackrabbit/oak/trunk/oak-auth-external/src/main/java/org/apache/jackrabbit/oak/spi/security/authentication/external/impl/jmx/Delegatee.java Mon Jun 6 09:10:48 2016
@@ -21,6 +21,7 @@ import java.security.PrivilegedException
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
+import javax.annotation.CheckForNull;
import javax.annotation.Nonnull;
import javax.annotation.Nullable;
import javax.jcr.Repository;
@@ -58,26 +59,41 @@ final class Delegatee {
private static final String ERROR_CREATE_DELEGATEE = "Unable to create delegatee";
private static final String ERROR_SYNC_USER = "Error while syncing user {}";
+ private static final int NO_BATCH_SIZE = 0;
+ private static final int DEFAULT_BATCH_SIZE = 100;
+
private final SyncHandler handler;
private final ExternalIdentityProvider idp;
private final UserManager userMgr;
private final Session systemSession;
+ private final int batchSize;
+
private SyncContext context;
private Delegatee(@Nonnull SyncHandler handler, @Nonnull ExternalIdentityProvider idp,
- @Nonnull JackrabbitSession systemSession) throws SyncException, RepositoryException {
+ @Nonnull JackrabbitSession systemSession, int batchSize) throws SyncException, RepositoryException {
this.handler = handler;
this.idp = idp;
this.systemSession = systemSession;
this.userMgr = systemSession.getUserManager();
this.context = handler.createContext(idp, userMgr, systemSession.getValueFactory());
+ this.batchSize = batchSize;
log.info("Created delegatee for SyncMBean with session: {} {}", systemSession, systemSession.getUserID());
}
- static Delegatee createInstance(@Nonnull final Repository repository, @Nonnull SyncHandler handler, @Nonnull ExternalIdentityProvider idp) {
+ static Delegatee createInstance(@Nonnull final Repository repository,
+ @Nonnull SyncHandler handler,
+ @Nonnull ExternalIdentityProvider idp) {
+ return createInstance(repository, handler, idp, DEFAULT_BATCH_SIZE);
+ }
+
+ static Delegatee createInstance(@Nonnull final Repository repository,
+ @Nonnull SyncHandler handler,
+ @Nonnull ExternalIdentityProvider idp,
+ int batchSize) {
Session systemSession;
try {
systemSession = Subject.doAs(SystemSubject.INSTANCE, new PrivilegedExceptionAction<Session>() {
@@ -100,7 +116,7 @@ final class Delegatee {
throw new SyncRuntimeException("Unable to create SyncContext: JackrabbitSession required.");
}
try {
- return new Delegatee(handler, idp, (JackrabbitSession) systemSession);
+ return new Delegatee(handler, idp, (JackrabbitSession) systemSession, batchSize);
} catch (RepositoryException e) {
systemSession.logout();
throw new SyncRuntimeException(ERROR_CREATE_DELEGATEE, e);
@@ -129,14 +145,12 @@ final class Delegatee {
.setForceGroupSync(true)
.setForceUserSync(true);
List<String> list = new ArrayList<String>();
+
+ List<SyncResult> results = new ArrayList<SyncResult>(batchSize);
for (String userId : userIds) {
- try {
- append(list, syncUser(userId));
- } catch (SyncException e) {
- log.warn(ERROR_SYNC_USER, userId, e);
- append(list, new DefaultSyncedIdentity(userId, null, false, -1), e);
- }
+ results = syncUser(userId, false, results, list);
}
+ commit(list, results, NO_BATCH_SIZE);
return list.toArray(new String[list.size()]);
}
@@ -150,18 +164,16 @@ final class Delegatee {
context.setKeepMissing(!purge)
.setForceGroupSync(true)
.setForceUserSync(true);
- Iterator<SyncedIdentity> iter = handler.listIdentities(userMgr);
- while (iter.hasNext()) {
- SyncedIdentity id = iter.next();
+ Iterator<SyncedIdentity> it = handler.listIdentities(userMgr);
+
+ List<SyncResult> results = new ArrayList<SyncResult>(batchSize);
+ while (it.hasNext()) {
+ SyncedIdentity id = it.next();
if (isMyIDP(id)) {
- try {
- append(list, syncUser(id.getId()));
- } catch (SyncException e) {
- log.error(ERROR_SYNC_USER, id, e);
- append(list, id, e);
- }
+ results = syncUser(id.getId(), false, results, list);
}
}
+ commit(list, results, NO_BATCH_SIZE);
return list.toArray(new String[list.size()]);
} catch (RepositoryException e) {
throw new IllegalStateException("Error retrieving users for syncing", e);
@@ -175,32 +187,30 @@ final class Delegatee {
String[] syncExternalUsers(@Nonnull String[] externalIds) {
List<String> list = new ArrayList<String>();
context.setForceGroupSync(true).setForceUserSync(true);
+
+ List<SyncResult> results = new ArrayList<SyncResult>(batchSize);
for (String externalId : externalIds) {
ExternalIdentityRef ref = ExternalIdentityRef.fromString(externalId);
if (!idp.getName().equals(ref.getProviderName())) {
- append(list, new DefaultSyncResultImpl(new DefaultSyncedIdentity(ref.getId(), ref, false, -1), SyncResult.Status.FOREIGN));
+ results.add(new DefaultSyncResultImpl(new DefaultSyncedIdentity(ref.getId(), ref, false, -1), SyncResult.Status.FOREIGN));
} else {
try {
ExternalIdentity id = idp.getIdentity(ref);
- SyncResult r;
if (id != null) {
- r = syncUser(id);
+ results = syncUser(id, results, list);
} else {
- r = new DefaultSyncResultImpl(
+ results.add(new DefaultSyncResultImpl(
new DefaultSyncedIdentity("", ref, false, -1),
SyncResult.Status.NO_SUCH_IDENTITY
- );
+ ));
}
- append(list, r);
} catch (ExternalIdentityException e) {
log.warn("error while fetching the external identity {}", externalId, e);
- append(list, ref, e);
- } catch (SyncException e) {
- log.error(ERROR_SYNC_USER, ref, e);
- append(list, ref, e);
+ results.add(new ErrorSyncResult(ref, e));
}
}
}
+ commit(list, results, NO_BATCH_SIZE);
return list.toArray(new String[list.size()]);
}
@@ -212,26 +222,13 @@ final class Delegatee {
List<String> list = new ArrayList<String>();
context.setForceGroupSync(true).setForceUserSync(true);
try {
- Iterator<ExternalUser> iter = idp.listUsers();
- while (iter.hasNext()) {
- ExternalUser user = iter.next();
- try {
- SyncResult r = syncUser(user);
- if (r.getIdentity() == null) {
- r = new DefaultSyncResultImpl(
- new DefaultSyncedIdentity(user.getId(), user.getExternalId(), false, -1),
- SyncResult.Status.NO_SUCH_IDENTITY
- );
- log.warn("sync failed. {}", r.getIdentity());
- } else {
- log.info("synced {}", r.getIdentity());
- }
- append(list, r);
- } catch (SyncException e) {
- log.error(ERROR_SYNC_USER, user, e);
- append(list, user.getExternalId(), e);
- }
+ List<SyncResult> results = new ArrayList<SyncResult>(batchSize);
+ Iterator<ExternalUser> it = idp.listUsers();
+ while (it.hasNext()) {
+ ExternalUser user = it.next();
+ results = syncUser(user, results, list);
}
+ commit(list, results, NO_BATCH_SIZE);
return list.toArray(new String[list.size()]);
} catch (ExternalIdentityException e) {
throw new SyncRuntimeException("Unable to retrieve external users", e);
@@ -254,15 +251,13 @@ final class Delegatee {
context.setKeepMissing(false);
List<String> list = new ArrayList<String>();
Iterator<String> orphanedIdentities = internalListOrphanedIdentities();
+
+ List<SyncResult> results = new ArrayList<SyncResult>(batchSize);
while (orphanedIdentities.hasNext()) {
String userId = orphanedIdentities.next();
- try {
- append(list, syncUser(userId));
- } catch (SyncException e) {
- log.warn(ERROR_SYNC_USER, userId, e);
- append(list, new DefaultSyncedIdentity(userId, new ExternalIdentityRef(userId, idp.getName()), false, -1), e);
- }
+ results = syncUser(userId, true, results, list);
}
+ commit(list, results, NO_BATCH_SIZE);
return list.toArray(new String[list.size()]);
}
@@ -274,34 +269,64 @@ final class Delegatee {
return providerName != null && (providerName.isEmpty() || providerName.equals(idp.getName()));
}
-
@Nonnull
- private SyncResult syncUser(@Nonnull ExternalIdentity id) throws SyncException {
+ private List<SyncResult> syncUser(@Nonnull ExternalIdentity id, @Nonnull List<SyncResult> results, @Nonnull List<String> list) {
try {
SyncResult r = context.sync(id);
- systemSession.save();
- return r;
- } catch (RepositoryException e) {
- throw new SyncException(e);
+ if (r.getIdentity() == null) {
+ r = new DefaultSyncResultImpl(
+ new DefaultSyncedIdentity(id.getId(), id.getExternalId(), false, -1),
+ SyncResult.Status.NO_SUCH_IDENTITY
+ );
+ log.warn("sync failed. {}", r.getIdentity());
+ } else {
+ log.info("synced {}", r.getIdentity());
+ }
+ results.add(r);
+ } catch (SyncException e) {
+ log.error(ERROR_SYNC_USER, id, e);
+ results.add(new ErrorSyncResult(id.getExternalId(), e));
}
+ return commit(list, results, batchSize);
}
- @Nonnull
- private SyncResult syncUser(@Nonnull String userId) throws SyncException {
+ private List<SyncResult> syncUser(@Nonnull String userId, boolean includeIdpName,
+ @Nonnull List<SyncResult> results, @Nonnull List<String> list) {
try {
- SyncResult r = context.sync(userId);
- systemSession.save();
- return r;
- } catch (RepositoryException e) {
- throw new SyncException(e);
+ results.add(context.sync(userId));
+ } catch (SyncException e) {
+ log.warn(ERROR_SYNC_USER, userId, e);
+ results.add(new ErrorSyncResult(userId, ((includeIdpName) ? idp.getName() : null), e));
+ }
+ return commit(list, results, batchSize);
+ }
+
+ private List<SyncResult> commit(@Nonnull List<String> list, @Nonnull List<SyncResult> resultList, int size) {
+ if (resultList.isEmpty() || resultList.size() < size) {
+ return resultList;
+ } else {
+ try {
+ systemSession.save();
+ append(list, resultList);
+ } catch (RepositoryException e) {
+ append(list, resultList, e);
+ } finally {
+ // make sure there are not pending changes that would fail the next batches
+ try {
+ systemSession.refresh(false);
+ } catch (RepositoryException e) {
+ log.warn(e.getMessage());
+ }
+ }
+ return new ArrayList<SyncResult>(size);
}
}
@Nonnull
private Iterator<String> internalListOrphanedIdentities() {
try {
- Iterator<SyncedIdentity> iter = handler.listIdentities(userMgr);
- return Iterators.filter(Iterators.transform(iter, new Function<SyncedIdentity, String>() {
+ Iterator<SyncedIdentity> it = handler.listIdentities(userMgr);
+ return Iterators.filter(Iterators.transform(it, new Function<SyncedIdentity, String>() {
@Nullable
@Override
public String apply(@Nullable SyncedIdentity syncedIdentity) {
@@ -326,28 +351,52 @@ final class Delegatee {
}
private static void append(@Nonnull List<String> list, @Nonnull SyncResult r) {
- SyncedIdentity syncedIdentity = r.getIdentity();
+ if (r instanceof ErrorSyncResult) {
+ ((ErrorSyncResult) r).append(list);
+ } else {
+ append(list, r.getIdentity(), getOperationFromStatus(r.getStatus()), null);
+ }
+ }
+
+ private static void append(@Nonnull List<String> list, @CheckForNull SyncedIdentity syncedIdentity, @Nonnull Exception e) {
+ append(list, syncedIdentity, "ERR", e.toString());
+ }
+
+ private static void append(@Nonnull List<String> list, @CheckForNull SyncedIdentity syncedIdentity, @Nonnull String op, @CheckForNull String msg) {
String uid = JsonUtil.getJsonString((syncedIdentity == null ? null : syncedIdentity.getId()));
ExternalIdentityRef externalIdentityRef = (syncedIdentity == null) ? null : syncedIdentity.getExternalIdRef();
String eid = (externalIdentityRef == null) ? "\"\"" : JsonUtil.getJsonString(externalIdentityRef.getString());
- String jsonStr = String.format("{op:\"%s\",uid:%s,eid:%s}", getOperationFromStatus(r.getStatus()), uid, eid);
- list.add(jsonStr);
+
+ if (msg == null) {
+ list.add(String.format("{op:\"%s\",uid:%s,eid:%s}", op, uid, eid));
+ } else {
+ list.add(String.format("{op:\"%s\",uid:%s,eid:%s,msg:%s}", op, uid, eid, JsonUtil.getJsonString(msg)));
+ }
}
- private static void append(@Nonnull List<String> list, @Nonnull ExternalIdentityRef idRef, @Nonnull Exception e) {
- String uid = JsonUtil.getJsonString(idRef.getId());
- String eid = JsonUtil.getJsonString(idRef.getString());
- String msg = JsonUtil.getJsonString(e.toString());
- String jsonStr = String.format("{op:\"ERR\",uid:%s,eid:%s,msg:%s}", uid, eid, msg);
- list.add(jsonStr);
+ private static void append(@Nonnull List<String> list, @Nonnull List<SyncResult> results) {
+ for (SyncResult result : results) {
+ append(list, result);
+ }
}
- private static void append(@Nonnull List<String> list, @Nonnull SyncedIdentity id, @Nonnull Exception e) {
- String uid = JsonUtil.getJsonString(id.getId());
- ExternalIdentityRef ref = id.getExternalIdRef();
- String eid = (ref == null) ? "\"\"" : JsonUtil.getJsonString(ref.getString());
- String msg = JsonUtil.getJsonString(e.toString());
- list.add(String.format("{op:\"ERR\",uid:%s,eid:%s,msg:%s}", uid, eid, msg));
+ private static void append(@Nonnull List<String> list, @Nonnull List<SyncResult> results, @Nonnull Exception e) {
+ for (SyncResult result : results) {
+ if (result instanceof ErrorSyncResult) {
+ ((ErrorSyncResult) result).append(list);
+ } else {
+ SyncResult.Status st = result.getStatus();
+ switch (st) {
+ case ADD:
+ case DELETE:
+ case UPDATE:
+ append(list, result.getIdentity(), e);
+ break;
+ default:
+ append(list, result);
+ }
+ }
+ }
}
private static String getOperationFromStatus(SyncResult.Status syncStatus) {
@@ -382,4 +431,37 @@ final class Delegatee {
}
return op;
}
+
+ private static final class ErrorSyncResult implements SyncResult {
+
+ private final SyncedIdentity syncedIdentity;
+ private final Exception error;
+
+ private ErrorSyncResult(@Nonnull String userId, @CheckForNull String idpName, @Nonnull Exception error) {
+ ExternalIdentityRef ref = (idpName != null) ? new ExternalIdentityRef(userId, idpName) : null;
+ this.syncedIdentity = new DefaultSyncedIdentity(userId, ref, false, -1);
+ this.error = error;
+ }
+
+ private ErrorSyncResult(@Nonnull ExternalIdentityRef ref, @Nonnull Exception error) {
+ this.syncedIdentity = new DefaultSyncedIdentity(ref.getId(), ref, false, -1);
+ this.error = error;
+ }
+
+ @Nonnull
+ @Override
+ public SyncedIdentity getIdentity() {
+ return syncedIdentity;
+ }
+
+ @Nonnull
+ @Override
+ public Status getStatus() {
+ return Status.NOP;
+ }
+
+ private void append(@Nonnull List<String> list) {
+ Delegatee.append(list, syncedIdentity, error);
+ }
+ }
}
Added: jackrabbit/oak/trunk/oak-auth-external/src/test/java/org/apache/jackrabbit/oak/spi/security/authentication/external/impl/jmx/AbstractJmxTest.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/jmx/AbstractJmxTest.java?rev=1746975&view=auto
==============================================================================
--- jackrabbit/oak/trunk/oak-auth-external/src/test/java/org/apache/jackrabbit/oak/spi/security/authentication/external/impl/jmx/AbstractJmxTest.java (added)
+++ jackrabbit/oak/trunk/oak-auth-external/src/test/java/org/apache/jackrabbit/oak/spi/security/authentication/external/impl/jmx/AbstractJmxTest.java Mon Jun 6 09:10:48 2016
@@ -0,0 +1,171 @@
+/*
+ * 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.jmx;
+
+import java.util.Iterator;
+import java.util.Map;
+import java.util.Set;
+import javax.annotation.Nonnull;
+import javax.annotation.Nullable;
+import javax.jcr.Repository;
+import javax.jcr.RepositoryException;
+import javax.jcr.Session;
+import javax.jcr.SimpleCredentials;
+
+import com.google.common.base.Function;
+import com.google.common.base.Predicates;
+import com.google.common.collect.ImmutableMap;
+import com.google.common.collect.Iterators;
+import com.google.common.collect.Sets;
+import org.apache.jackrabbit.api.JackrabbitSession;
+import org.apache.jackrabbit.api.security.user.Authorizable;
+import org.apache.jackrabbit.api.security.user.Group;
+import org.apache.jackrabbit.api.security.user.User;
+import org.apache.jackrabbit.api.security.user.UserManager;
+import org.apache.jackrabbit.oak.jcr.Jcr;
+import org.apache.jackrabbit.oak.spi.security.authentication.external.ExternalIdentity;
+import org.apache.jackrabbit.oak.spi.security.authentication.external.ExternalIdentityProvider;
+import org.apache.jackrabbit.oak.spi.security.authentication.external.ExternalIdentityRef;
+import org.apache.jackrabbit.oak.spi.security.authentication.external.ExternalUser;
+import org.apache.jackrabbit.oak.spi.security.authentication.external.SyncContext;
+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.basic.DefaultSyncConfig;
+import org.apache.jackrabbit.oak.spi.security.authentication.external.basic.DefaultSyncContext;
+import org.junit.After;
+import org.junit.Before;
+import org.junit.BeforeClass;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertTrue;
+
+public abstract class AbstractJmxTest {
+
+ static Repository REPOSITORY;
+
+ Session session;
+ UserManager userManager;
+
+ DefaultSyncConfig syncConfig;
+
+ ExternalIdentityProvider idp;
+ ExternalIdentityProvider foreignIDP;
+
+ private Set<String> ids;
+
+ @BeforeClass
+ public static void beforeClass() {
+ REPOSITORY = new Jcr().createRepository();
+ }
+
+ @Before
+ public void before() throws Exception {
+ session = REPOSITORY.login(new SimpleCredentials("admin", "admin".toCharArray()));
+ if (!(session instanceof JackrabbitSession)) {
+ throw new IllegalStateException();
+ } else {
+ userManager = ((JackrabbitSession) session).getUserManager();
+ }
+ ids = Sets.newHashSet(getAllAuthorizableIds(userManager));
+
+ syncConfig = new DefaultSyncConfig();
+ syncConfig.user().setMembershipNestingDepth(1);
+
+ idp = new TestIdentityProvider();
+ foreignIDP = new TestIdentityProvider("anotherIDP");
+ }
+
+ @After
+ public void after() throws Exception {
+ try {
+ session.refresh(false);
+ Iterator<String> iter = getAllAuthorizableIds(userManager);
+ while (iter.hasNext()) {
+ String id = iter.next();
+ if (!ids.remove(id)) {
+ Authorizable a = userManager.getAuthorizable(id);
+ if (a != null) {
+ a.remove();
+ }
+ }
+ }
+ session.save();
+ } finally {
+ session.logout();
+ }
+ }
+
+ private static Iterator<String> getAllAuthorizableIds(@Nonnull UserManager userManager) throws Exception {
+ Iterator<Authorizable> it = userManager.findAuthorizables("jcr:primaryType", null);
+ return Iterators.filter(Iterators.transform(it, new Function<Authorizable, String>() {
+ @Nullable
+ @Override
+ public String apply(Authorizable input) {
+ try {
+ if (input != null) {
+ return input.getID();
+ }
+ } catch (RepositoryException e) {
+ // failed to retrieve ID
+ }
+ return null;
+ }
+ }), Predicates.notNull());
+ }
+
+ static void assertResultMessages(@Nonnull String[] resultMessages, String uid, @Nonnull String expectedOperation) {
+ assertResultMessages(resultMessages, ImmutableMap.of(uid, expectedOperation));
+ }
+
+ static void assertResultMessages(@Nonnull String[] resultMessages, @Nonnull Map<String, String> expected) {
+ assertEquals(expected.size(), resultMessages.length);
+ for (int i = 0; i < resultMessages.length; i++) {
+ String rm = resultMessages[i];
+ String op = rm.substring(rm.indexOf(":") + 2, rm.indexOf("\","));
+
+ int index = rm.indexOf("uid:\"") + 5;
+ String uid = rm.substring(index, rm.indexOf("\",", index));
+
+ assertTrue(expected.containsKey(uid));
+ assertEquals(expected.get(uid), op);
+ }
+ }
+
+ static void assertSync(@Nonnull ExternalIdentity ei, @Nonnull UserManager userManager) throws Exception {
+ Authorizable authorizable;
+ if (ei instanceof ExternalUser) {
+ authorizable = userManager.getAuthorizable(ei.getId(), User.class);
+ } else {
+ authorizable = userManager.getAuthorizable(ei.getId(), Group.class);
+ }
+ assertNotNull(ei.getId(), authorizable);
+ assertEquals(ei.getId(), authorizable.getID());
+ assertEquals(ei.getExternalId(), ExternalIdentityRef.fromString(authorizable.getProperty(DefaultSyncContext.REP_EXTERNAL_ID)[0].getString()));
+ }
+
+ SyncResult sync(@Nonnull ExternalIdentityProvider idp, @Nonnull String id, boolean isGroup) throws Exception {
+ return sync((isGroup) ? idp.getGroup(id) : idp.getUser(id), idp);
+ }
+
+ SyncResult sync(@Nonnull ExternalIdentity externalIdentity, @Nonnull ExternalIdentityProvider idp) throws Exception {
+ SyncContext ctx = new DefaultSyncContext(syncConfig, idp, userManager, session.getValueFactory());
+ SyncResult res = ctx.sync(externalIdentity);
+ session.save();
+ return res;
+ }
+}
\ 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/jmx/DelegateeBatchOneTest.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/jmx/DelegateeBatchOneTest.java?rev=1746975&view=auto
==============================================================================
--- jackrabbit/oak/trunk/oak-auth-external/src/test/java/org/apache/jackrabbit/oak/spi/security/authentication/external/impl/jmx/DelegateeBatchOneTest.java (added)
+++ jackrabbit/oak/trunk/oak-auth-external/src/test/java/org/apache/jackrabbit/oak/spi/security/authentication/external/impl/jmx/DelegateeBatchOneTest.java Mon Jun 6 09:10:48 2016
@@ -0,0 +1,25 @@
+/*
+ * 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.jmx;
+
+public class DelegateeBatchOneTest extends DelegateeTest {
+
+ @Override
+ int getBatchSize() {
+ return 1;
+ }
+}
\ 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/jmx/DelegateeBatchTwoTest.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/jmx/DelegateeBatchTwoTest.java?rev=1746975&view=auto
==============================================================================
--- jackrabbit/oak/trunk/oak-auth-external/src/test/java/org/apache/jackrabbit/oak/spi/security/authentication/external/impl/jmx/DelegateeBatchTwoTest.java (added)
+++ jackrabbit/oak/trunk/oak-auth-external/src/test/java/org/apache/jackrabbit/oak/spi/security/authentication/external/impl/jmx/DelegateeBatchTwoTest.java Mon Jun 6 09:10:48 2016
@@ -0,0 +1,26 @@
+/*
+ * 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.jmx;
+
+public class DelegateeBatchTwoTest extends DelegateeTest {
+
+ @Override
+ int getBatchSize() {
+ // test-idp-provider has 3 users => forcing save in the final commit
+ return 2;
+ }
+}
\ 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/jmx/DelegateeTest.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/jmx/DelegateeTest.java?rev=1746975&view=auto
==============================================================================
--- jackrabbit/oak/trunk/oak-auth-external/src/test/java/org/apache/jackrabbit/oak/spi/security/authentication/external/impl/jmx/DelegateeTest.java (added)
+++ jackrabbit/oak/trunk/oak-auth-external/src/test/java/org/apache/jackrabbit/oak/spi/security/authentication/external/impl/jmx/DelegateeTest.java Mon Jun 6 09:10:48 2016
@@ -0,0 +1,524 @@
+/*
+ * 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.jmx;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.OutputStream;
+import java.lang.reflect.Field;
+import java.security.AccessControlException;
+import java.util.ArrayList;
+import java.util.Iterator;
+import java.util.List;
+import javax.annotation.Nonnull;
+import javax.jcr.Credentials;
+import javax.jcr.Item;
+import javax.jcr.Node;
+import javax.jcr.Property;
+import javax.jcr.Repository;
+import javax.jcr.RepositoryException;
+import javax.jcr.Session;
+import javax.jcr.ValueFactory;
+import javax.jcr.Workspace;
+import javax.jcr.retention.RetentionManager;
+import javax.jcr.security.AccessControlManager;
+
+import com.google.common.collect.ImmutableMap;
+import org.apache.jackrabbit.api.JackrabbitSession;
+import org.apache.jackrabbit.api.security.principal.PrincipalManager;
+import org.apache.jackrabbit.api.security.user.UserManager;
+import org.apache.jackrabbit.oak.spi.security.authentication.external.ExternalIdentityException;
+import org.apache.jackrabbit.oak.spi.security.authentication.external.ExternalIdentityProvider;
+import org.apache.jackrabbit.oak.spi.security.authentication.external.ExternalIdentityRef;
+import org.apache.jackrabbit.oak.spi.security.authentication.external.ExternalUser;
+import org.apache.jackrabbit.oak.spi.security.authentication.external.TestIdentityProvider;
+import org.apache.jackrabbit.oak.spi.security.authentication.external.impl.DefaultSyncHandler;
+import org.junit.Before;
+import org.junit.Test;
+import org.xml.sax.ContentHandler;
+import org.xml.sax.SAXException;
+
+import static org.junit.Assert.assertFalse;
+
+public class DelegateeTest extends AbstractJmxTest {
+
+ private Delegatee delegatee;
+
+ private static final String[] TEST_IDS = new String[] {
+ TestIdentityProvider.ID_TEST_USER,
+ TestIdentityProvider.ID_SECOND_USER,
+ TestIdentityProvider.ID_WILDCARD_USER};
+
+ @Before
+ public void before() throws Exception {
+ super.before();
+
+ delegatee = createDelegatee(new TestIdentityProvider());
+ }
+
+ @Override
+ public void after() throws Exception {
+ try {
+ if (delegatee != null) {
+ delegatee.close();
+ }
+ } finally {
+ super.after();
+ }
+ }
+
+ int getBatchSize() {
+ return 100;
+ }
+
+ private Delegatee createDelegatee(@Nonnull ExternalIdentityProvider idp) {
+ return Delegatee.createInstance(REPOSITORY, new DefaultSyncHandler(syncConfig), idp, getBatchSize());
+ }
+
+ private static Session preventSessionSave(@Nonnull Delegatee delegatee) throws Exception {
+ Field sessionField = Delegatee.class.getDeclaredField("systemSession");
+ sessionField.setAccessible(true);
+
+ JackrabbitSession s = (JackrabbitSession) sessionField.get(delegatee);
+ s.refresh(false);
+ sessionField.set(delegatee, new ThrowingSession(s));
+ return s;
+ }
+
+ @Test
+ public void testDoubleClose() {
+ delegatee.close();
+ delegatee.close();
+ }
+
+ @Test
+ public void testSyncUsersBeforeSaveError() throws Exception {
+ Session s = preventSessionSave(delegatee);;
+
+ String[] result = delegatee.syncUsers(TEST_IDS, false);
+ assertResultMessages(result, ImmutableMap.of(
+ TestIdentityProvider.ID_TEST_USER, "nsa",
+ TestIdentityProvider.ID_SECOND_USER, "nsa",
+ TestIdentityProvider.ID_WILDCARD_USER, "nsa"));
+ assertFalse(s.hasPendingChanges());
+ }
+
+ @Test
+ public void testSyncUsersSaveError() throws Exception {
+ sync(idp, TestIdentityProvider.ID_TEST_USER, false);
+ sync(foreignIDP, TestIdentityProvider.ID_SECOND_USER, false);
+ // don't sync ID_WILDCARD_USER
+
+ Session s = preventSessionSave(delegatee);
+
+ String[] result = delegatee.syncUsers(new String[] {
+ TestIdentityProvider.ID_TEST_USER,
+ TestIdentityProvider.ID_SECOND_USER,
+ TestIdentityProvider.ID_WILDCARD_USER}, false);
+ assertResultMessages(result, ImmutableMap.of(
+ TestIdentityProvider.ID_TEST_USER, "ERR",
+ TestIdentityProvider.ID_SECOND_USER, "for",
+ TestIdentityProvider.ID_WILDCARD_USER, "nsa"));
+ assertFalse(s.hasPendingChanges());
+ }
+
+ @Test
+ public void testSyncAllUsersBeforeSaveError() throws Exception {
+ Session s = preventSessionSave(delegatee);;
+
+ String[] result = delegatee.syncAllUsers(false);
+ assertResultMessages(result, ImmutableMap.<String,String>of());
+ assertFalse(s.hasPendingChanges());
+ }
+
+ @Test
+ public void testSyncAllUsersSaveError() throws Exception {
+ sync(idp, TestIdentityProvider.ID_TEST_USER, false);
+ sync(idp, TestIdentityProvider.ID_SECOND_USER, false);
+ sync(new TestIdentityProvider.TestUser("third", idp.getName()), idp);
+ sync(foreignIDP, TestIdentityProvider.ID_WILDCARD_USER, false);
+
+ Session s = preventSessionSave(delegatee);;
+
+ ImmutableMap<String, String> expected = ImmutableMap.<String, String>builder()
+ .put(TestIdentityProvider.ID_TEST_USER, "ERR")
+ .put("a", "ERR")
+ .put("b", "ERR")
+ .put("c", "ERR")
+ .put(TestIdentityProvider.ID_SECOND_USER, "ERR")
+ .put("secondGroup", "ERR")
+ .put("third", "mis").build();
+
+ String[] result = delegatee.syncAllUsers(false);
+ assertResultMessages(result, expected);
+ // NOTE: foreign user is not included in the results
+ assertFalse(s.hasPendingChanges());
+ }
+
+ @Test
+ public void testSyncAllUsersPurgeSaveError() throws Exception {
+ sync(idp, TestIdentityProvider.ID_TEST_USER, false);
+ sync(idp, TestIdentityProvider.ID_SECOND_USER, false);
+ sync(new TestIdentityProvider.TestUser("third", idp.getName()), idp);
+ sync(foreignIDP, TestIdentityProvider.ID_WILDCARD_USER, false);
+
+ Session s = preventSessionSave(delegatee);;
+
+ ImmutableMap<String, String> expected = ImmutableMap.<String, String>builder()
+ .put(TestIdentityProvider.ID_TEST_USER, "ERR")
+ .put("a", "ERR")
+ .put("b", "ERR")
+ .put("c", "ERR")
+ .put(TestIdentityProvider.ID_SECOND_USER, "ERR")
+ .put("secondGroup", "ERR")
+ .put("third", "ERR").build();
+
+ String[] result = delegatee.syncAllUsers(true);
+ assertResultMessages(result, expected);
+ // NOTE: foreign user is not included in the results
+ assertFalse(s.hasPendingChanges());
+ }
+
+ @Test
+ public void testSyncNonExistingExternalUserSaveError() throws Exception {
+ Session s = preventSessionSave(delegatee);;
+
+ String[] result = delegatee.syncExternalUsers(new String[] {new ExternalIdentityRef("nonExisting", idp.getName()).getString()});
+ assertResultMessages(result, "", "nsi");
+ assertFalse(s.hasPendingChanges());
+ }
+
+ @Test
+ public void testSyncForeignExternalUserSaveError() throws Exception {
+ Session s = preventSessionSave(delegatee);;
+
+ String[] result = delegatee.syncExternalUsers(new String[] {new ExternalIdentityRef(TestIdentityProvider.ID_TEST_USER, foreignIDP.getName()).getString()});
+ assertResultMessages(result, TestIdentityProvider.ID_TEST_USER, "for");
+ assertFalse(s.hasPendingChanges());
+ }
+
+ @Test
+ public void testSyncThrowingExternalUserSaveError() throws Exception {
+ Session s = preventSessionSave(delegatee);;
+
+ String[] result = delegatee.syncExternalUsers(new String[] {new ExternalIdentityRef(TestIdentityProvider.ID_EXCEPTION, idp.getName()).getString()});
+ assertResultMessages(result, TestIdentityProvider.ID_EXCEPTION, "ERR");
+ assertFalse(s.hasPendingChanges());
+ }
+
+ @Test
+ public void testSyncExternalUsersSaveError() throws Exception {
+ Session s = preventSessionSave(delegatee);;
+
+ List<String> externalIds = new ArrayList();
+ for (String id : TEST_IDS) {
+ externalIds.add(new ExternalIdentityRef(id, idp.getName()).getString());
+ }
+ String[] result = delegatee.syncExternalUsers(externalIds.toArray(new String[externalIds.size()]));
+ assertResultMessages(result, ImmutableMap.of(
+ TestIdentityProvider.ID_TEST_USER, "ERR",
+ TestIdentityProvider.ID_SECOND_USER, "ERR",
+ TestIdentityProvider.ID_WILDCARD_USER, "ERR"));
+ assertFalse(s.hasPendingChanges());
+ }
+
+ @Test
+ public void testSyncAllExternalUsersSaveError() throws Exception {
+ Session s = preventSessionSave(delegatee);;
+
+ String[] result = delegatee.syncAllExternalUsers();
+ assertResultMessages(result, ImmutableMap.of(
+ TestIdentityProvider.ID_TEST_USER, "ERR",
+ TestIdentityProvider.ID_SECOND_USER, "ERR",
+ TestIdentityProvider.ID_WILDCARD_USER, "ERR"));
+ assertFalse(s.hasPendingChanges());
+ }
+
+
+ @Test(expected = SyncRuntimeException.class)
+ public void testSyncAllExternalUsersThrowingIDP() {
+ Delegatee dg = Delegatee.createInstance(REPOSITORY, new DefaultSyncHandler(syncConfig), new TestIdentityProvider("throwing") {
+
+ @Nonnull
+ @Override
+ public Iterator<ExternalUser> listUsers() throws ExternalIdentityException {
+ throw new ExternalIdentityException();
+ }
+ }, getBatchSize());
+
+ dg.syncAllExternalUsers();
+ }
+
+ @Test
+ public void testPurgeOrphanedSaveError() throws Exception {
+ sync(new TestIdentityProvider.TestUser("third", idp.getName()), idp);
+ sync(new TestIdentityProvider.TestUser("forth", idp.getName()), idp);
+ sync(idp, TestIdentityProvider.ID_TEST_USER, false);
+
+ Session s = preventSessionSave(delegatee);;
+
+ String[] result = delegatee.purgeOrphanedUsers();
+ assertResultMessages(result, ImmutableMap.of(
+ "third", "ERR",
+ "forth", "ERR"));
+ assertFalse(s.hasPendingChanges());
+ }
+
+ private static final class ThrowingSession implements JackrabbitSession {
+
+ private JackrabbitSession base;
+
+ private ThrowingSession(@Nonnull JackrabbitSession session) {
+ this.base = session;
+ }
+ @Override
+ public boolean hasPermission(@Nonnull String s, @Nonnull String... strings) throws RepositoryException {
+ return base.hasPermission(s, strings);
+ }
+
+ @Override
+ public PrincipalManager getPrincipalManager() throws RepositoryException {
+ return base.getPrincipalManager();
+ }
+
+ @Override
+ public UserManager getUserManager() throws RepositoryException {
+ return base.getUserManager();
+ }
+
+ @Override
+ public Item getItemOrNull(String s) throws RepositoryException {
+ return base.getItemOrNull(s);
+ }
+
+ @Override
+ public Property getPropertyOrNull(String s) throws RepositoryException {
+ return base.getPropertyOrNull(s);
+ }
+
+ @Override
+ public Node getNodeOrNull(String s) throws RepositoryException {
+ return getNodeOrNull(s);
+ }
+
+ @Override
+ public Repository getRepository() {
+ return base.getRepository();
+ }
+
+ @Override
+ public String getUserID() {
+ return base.getUserID();
+ }
+
+ @Override
+ public String[] getAttributeNames() {
+ return base.getAttributeNames();
+ }
+
+ @Override
+ public Object getAttribute(String name) {
+ return base.getAttribute(name);
+ }
+
+ @Override
+ public Workspace getWorkspace() {
+ return base.getWorkspace();
+ }
+
+ @Override
+ public Node getRootNode() throws RepositoryException {
+ return base.getRootNode();
+ }
+
+ @Override
+ public Session impersonate(Credentials credentials) throws RepositoryException {
+ return base.impersonate(credentials);
+ }
+
+ @Override
+ public Node getNodeByUUID(String uuid) throws RepositoryException {
+ return base.getNodeByUUID(uuid);
+ }
+
+ @Override
+ public Node getNodeByIdentifier(String id) throws RepositoryException {
+ return base.getNodeByIdentifier(id);
+ }
+
+ @Override
+ public Item getItem(String absPath) throws RepositoryException {
+ return base.getItem(absPath);
+ }
+
+ @Override
+ public Node getNode(String absPath) throws RepositoryException {
+ return base.getNode(absPath);
+ }
+
+ @Override
+ public Property getProperty(String absPath) throws RepositoryException {
+ return base.getProperty(absPath);
+ }
+
+ @Override
+ public boolean itemExists(String absPath) throws RepositoryException {
+ return base.itemExists(absPath);
+ }
+
+ @Override
+ public boolean nodeExists(String absPath) throws RepositoryException {
+ return base.nodeExists(absPath);
+ }
+
+ @Override
+ public boolean propertyExists(String absPath) throws RepositoryException {
+ return base.propertyExists(absPath);
+ }
+
+ @Override
+ public void move(String srcAbsPath, String destAbsPath) throws RepositoryException {
+ base.move(srcAbsPath, destAbsPath);
+ }
+
+ @Override
+ public void removeItem(String absPath) throws RepositoryException {
+ base.removeItem(absPath);
+ }
+
+ @Override
+ public void save() throws RepositoryException {
+ throw new RepositoryException();
+
+ }
+
+ @Override
+ public void refresh(boolean keepChanges) throws RepositoryException {
+ base.refresh(keepChanges);
+ }
+
+ @Override
+ public boolean hasPendingChanges() throws RepositoryException {
+ return base.hasPendingChanges();
+ }
+
+ @Override
+ public ValueFactory getValueFactory() throws RepositoryException {
+ return base.getValueFactory();
+ }
+
+ @Override
+ public boolean hasPermission(String absPath, String actions) throws RepositoryException {
+ return base.hasPermission(absPath, actions);
+ }
+
+ @Override
+ public void checkPermission(String absPath, String actions) throws AccessControlException, RepositoryException {
+ base.checkPermission(absPath, actions);
+ }
+
+ @Override
+ public boolean hasCapability(String methodName, Object target, Object[] arguments) throws RepositoryException {
+ return base.hasCapability(methodName, target, arguments);
+ }
+
+ @Override
+ public ContentHandler getImportContentHandler(String parentAbsPath, int uuidBehavior) throws RepositoryException {
+ return base.getImportContentHandler(parentAbsPath, uuidBehavior);
+ }
+
+ @Override
+ public void importXML(String parentAbsPath, InputStream in, int uuidBehavior) throws IOException, RepositoryException {
+ base.importXML(parentAbsPath, in, uuidBehavior);
+ }
+
+ @Override
+ public void exportSystemView(String absPath, ContentHandler contentHandler, boolean skipBinary, boolean noRecurse) throws SAXException, RepositoryException {
+ base.exportSystemView(absPath, contentHandler, skipBinary, noRecurse);
+ }
+
+ @Override
+ public void exportSystemView(String absPath, OutputStream out, boolean skipBinary, boolean noRecurse) throws IOException, RepositoryException {
+ base.exportSystemView(absPath, out, skipBinary, noRecurse);
+ }
+
+ @Override
+ public void exportDocumentView(String absPath, ContentHandler contentHandler, boolean skipBinary, boolean noRecurse) throws SAXException, RepositoryException {
+ base.exportDocumentView(absPath, contentHandler, skipBinary, noRecurse);
+ }
+
+ @Override
+ public void exportDocumentView(String absPath, OutputStream out, boolean skipBinary, boolean noRecurse) throws IOException, RepositoryException {
+ base.exportDocumentView(absPath, out, skipBinary, noRecurse);
+ }
+
+ @Override
+ public void setNamespacePrefix(String prefix, String uri) throws RepositoryException {
+ base.setNamespacePrefix(prefix, uri);
+ }
+
+ @Override
+ public String[] getNamespacePrefixes() throws RepositoryException {
+ return base.getNamespacePrefixes();
+ }
+
+ @Override
+ public String getNamespaceURI(String prefix) throws RepositoryException {
+ return base.getNamespaceURI(prefix);
+ }
+
+ @Override
+ public String getNamespacePrefix(String uri) throws RepositoryException {
+ return base.getNamespacePrefix(uri);
+ }
+
+ @Override
+ public void logout() {
+ base.logout();
+ }
+
+ @Override
+ public boolean isLive() {
+ return base.isLive();
+ }
+
+ @Override
+ public void addLockToken(String lt) {
+ base.addLockToken(lt);
+ }
+
+ @Override
+ public String[] getLockTokens() {
+ return base.getLockTokens();
+ }
+
+ @Override
+ public void removeLockToken(String lt) {
+ base.removeLockToken(lt);
+ }
+
+ @Override
+ public AccessControlManager getAccessControlManager() throws RepositoryException {
+ return base.getAccessControlManager();
+ }
+
+ @Override
+ public RetentionManager getRetentionManager() throws RepositoryException {
+ return base.getRetentionManager();
+ }
+ }
+}
\ No newline at end of file
Modified: jackrabbit/oak/trunk/oak-auth-external/src/test/java/org/apache/jackrabbit/oak/spi/security/authentication/external/impl/jmx/SyncMBeanImplTest.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/jmx/SyncMBeanImplTest.java?rev=1746975&r1=1746974&r2=1746975&view=diff
==============================================================================
--- jackrabbit/oak/trunk/oak-auth-external/src/test/java/org/apache/jackrabbit/oak/spi/security/authentication/external/impl/jmx/SyncMBeanImplTest.java (original)
+++ jackrabbit/oak/trunk/oak-auth-external/src/test/java/org/apache/jackrabbit/oak/spi/security/authentication/external/impl/jmx/SyncMBeanImplTest.java Mon Jun 6 09:10:48 2016
@@ -19,28 +19,17 @@ package org.apache.jackrabbit.oak.spi.se
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;
-import java.util.Set;
import javax.annotation.CheckForNull;
import javax.annotation.Nonnull;
-import javax.annotation.Nullable;
-import javax.jcr.Repository;
import javax.jcr.RepositoryException;
-import javax.jcr.Session;
-import javax.jcr.SimpleCredentials;
import javax.jcr.ValueFactory;
-import com.google.common.base.Function;
-import com.google.common.base.Predicates;
import com.google.common.collect.ImmutableMap;
import com.google.common.collect.ImmutableSet;
-import com.google.common.collect.Iterators;
-import com.google.common.collect.Sets;
-import org.apache.jackrabbit.api.JackrabbitSession;
import org.apache.jackrabbit.api.security.user.Authorizable;
import org.apache.jackrabbit.api.security.user.Group;
import org.apache.jackrabbit.api.security.user.User;
import org.apache.jackrabbit.api.security.user.UserManager;
-import org.apache.jackrabbit.oak.jcr.Jcr;
import org.apache.jackrabbit.oak.spi.security.authentication.external.ExternalGroup;
import org.apache.jackrabbit.oak.spi.security.authentication.external.ExternalIdentity;
import org.apache.jackrabbit.oak.spi.security.authentication.external.ExternalIdentityException;
@@ -55,13 +44,10 @@ import org.apache.jackrabbit.oak.spi.sec
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.TestIdentityProvider;
-import org.apache.jackrabbit.oak.spi.security.authentication.external.basic.DefaultSyncConfig;
import org.apache.jackrabbit.oak.spi.security.authentication.external.basic.DefaultSyncContext;
import org.apache.jackrabbit.oak.spi.security.authentication.external.impl.DefaultSyncHandler;
import org.apache.jackrabbit.oak.spi.security.user.UserConstants;
-import org.junit.After;
import org.junit.Before;
-import org.junit.BeforeClass;
import org.junit.Test;
import static org.junit.Assert.assertEquals;
@@ -70,41 +56,18 @@ import static org.junit.Assert.assertNul
import static org.junit.Assert.assertTrue;
import static org.junit.Assert.fail;
-public class SyncMBeanImplTest {
+public class SyncMBeanImplTest extends AbstractJmxTest {
private static final String SYNC_NAME = "testSyncName";
- private static Repository REPOSITORY;
-
- private ExternalIdentityProvider idp;
- private ExternalIdentityProvider foreignIDP;
- private DefaultSyncConfig syncConfig;
private SyncMBeanImpl syncMBean;
private SyncManager syncMgr;
private ExternalIdentityProviderManager idpMgr;
- private Session session;
- private UserManager userManager;
- private Set<String> ids;
-
- @BeforeClass
- public static void beforeClass() {
- REPOSITORY = new Jcr().createRepository();
- }
-
@Before
public void before() throws Exception {
- idp = new TestIdentityProvider();
- foreignIDP = new TestIdentityProvider() {
- @Nonnull
- public String getName() {
- return "anotherIDP";
- }
-
- };
- syncConfig = new DefaultSyncConfig();
- syncConfig.user().setMembershipNestingDepth(1);
+ super.before();
syncMgr = new SyncManager() {
@CheckForNull
@@ -133,93 +96,6 @@ public class SyncMBeanImplTest {
}
};
syncMBean = new SyncMBeanImpl(REPOSITORY, syncMgr, SYNC_NAME, idpMgr, idp.getName());
-
- session = REPOSITORY.login(new SimpleCredentials("admin", "admin".toCharArray()));
- if (!(session instanceof JackrabbitSession)) {
- throw new IllegalStateException();
- } else {
- userManager = ((JackrabbitSession) session).getUserManager();
- }
- ids = Sets.newHashSet(getAllAuthorizableIds(userManager));
- }
-
- @After
- public void after() throws Exception {
- try {
- session.refresh(false);
- Iterator<String> iter = getAllAuthorizableIds(userManager);
- while (iter.hasNext()) {
- String id = iter.next();
- if (!ids.remove(id)) {
- Authorizable a = userManager.getAuthorizable(id);
- if (a != null) {
- a.remove();
- }
- }
- }
- session.save();
- } finally {
- session.logout();
- }
- }
-
- private static Iterator<String> getAllAuthorizableIds(@Nonnull UserManager userManager) throws Exception {
- Iterator<Authorizable> iter = userManager.findAuthorizables("jcr:primaryType", null);
- return Iterators.filter(Iterators.transform(iter, new Function<Authorizable, String>() {
- @Nullable
- @Override
- public String apply(Authorizable input) {
- try {
- if (input != null) {
- return input.getID();
- }
- } catch (RepositoryException e) {
- // failed to retrieve ID
- }
- return null;
- }
- }), Predicates.notNull());
- }
-
- private static void assertResultMessages(@Nonnull String[] resultMessages, String uid, @Nonnull String expectedOperation) {
- assertResultMessages(resultMessages, ImmutableMap.of(uid, expectedOperation));
- }
-
- private static void assertResultMessages(@Nonnull String[] resultMessages, @Nonnull Map<String, String> expected) {
- assertEquals(expected.size(), resultMessages.length);
- for (int i = 0; i < resultMessages.length; i++) {
- String rm = resultMessages[i];
- String op = rm.substring(rm.indexOf(":") + 2, rm.indexOf("\","));
-
- int index = rm.indexOf("uid:\"") + 5;
- String uid = rm.substring(index, rm.indexOf("\",", index));
-
- assertTrue(expected.containsKey(uid));
- assertEquals(expected.get(uid), op);
- }
- }
-
- private static void assertSync(@Nonnull ExternalIdentity ei, @Nonnull UserManager userManager) throws Exception {
- Authorizable authorizable;
- if (ei instanceof ExternalUser) {
- authorizable = userManager.getAuthorizable(ei.getId(), User.class);
- } else {
- authorizable = userManager.getAuthorizable(ei.getId(), Group.class);
- }
- assertNotNull(ei.getId(), authorizable);
- assertEquals(ei.getId(), authorizable.getID());
- assertEquals(ei.getExternalId(), ExternalIdentityRef.fromString(authorizable.getProperty(DefaultSyncContext.REP_EXTERNAL_ID)[0].getString()));
- }
-
- private SyncResult sync(@Nonnull ExternalIdentityProvider idp, @Nonnull String id, boolean isGroup) throws Exception {
- return sync((isGroup) ? idp.getGroup(id) : idp.getUser(id), idp);
- }
-
- private SyncResult sync(@Nonnull ExternalIdentity externalIdentity, @Nonnull ExternalIdentityProvider idp) throws Exception {
- SyncContext ctx = new DefaultSyncContext(syncConfig, idp, userManager, session.getValueFactory());
- SyncResult res = ctx.sync(externalIdentity);
- session.save();
- return res;
}
private Map<String, String> getExpectedUserResult(String expectedOp, boolean includeGroups) throws ExternalIdentityException {