mirror of https://github.com/apache/activemq.git
https://issues.apache.org/jira/browse/AMQ-3845 - handle LDAP restarts in cached ldap authorization map
git-svn-id: https://svn.apache.org/repos/asf/activemq/trunk@1348761 13f79535-47bb-0310-9956-ffa450edef68
This commit is contained in:
parent
21a0465448
commit
06949a5074
|
@ -94,21 +94,7 @@ public class CachedLDAPAuthorizationMap extends DefaultAuthorizationMap implemen
|
|||
protected HashMap<ActiveMQDestination, AuthorizationEntry> entries =
|
||||
new HashMap<ActiveMQDestination, AuthorizationEntry>();
|
||||
|
||||
/**
|
||||
* Returns the existing open context or creates a new one and registers listeners for
|
||||
* push notifications if such an update style is enabled. This implementation should not
|
||||
* be invoked concurrently.
|
||||
*
|
||||
* @return the current context
|
||||
*
|
||||
* @throws NamingException if there is an error setting things up
|
||||
*/
|
||||
protected DirContext open() throws NamingException {
|
||||
if (context != null) {
|
||||
return context;
|
||||
}
|
||||
|
||||
try {
|
||||
protected DirContext createContext() throws NamingException {
|
||||
Hashtable<String, String> env = new Hashtable<String, String>();
|
||||
env.put(Context.INITIAL_CONTEXT_FACTORY, initialContextFactory);
|
||||
if (connectionUsername != null || !"".equals(connectionUsername)) {
|
||||
|
@ -120,8 +106,35 @@ public class CachedLDAPAuthorizationMap extends DefaultAuthorizationMap implemen
|
|||
env.put(Context.SECURITY_PROTOCOL, connectionProtocol);
|
||||
env.put(Context.PROVIDER_URL, connectionURL);
|
||||
env.put(Context.SECURITY_AUTHENTICATION, authentication);
|
||||
context = new InitialDirContext(env);
|
||||
//env.put("com.sun.jndi.ldap.connect.pool", "true");
|
||||
return new InitialDirContext(env);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the existing open context or creates a new one and registers listeners for
|
||||
* push notifications if such an update style is enabled. This implementation should not
|
||||
* be invoked concurrently.
|
||||
*
|
||||
* @return the current context
|
||||
*
|
||||
* @throws NamingException if there is an error setting things up
|
||||
*/
|
||||
protected DirContext open() throws NamingException {
|
||||
if (context != null) {
|
||||
boolean alive = true;
|
||||
try {
|
||||
context.getAttributes("");
|
||||
} catch (Exception e) {
|
||||
LOG.info("LDAP connection failed", e);
|
||||
alive = false;
|
||||
}
|
||||
if (alive) {
|
||||
return context;
|
||||
}
|
||||
}
|
||||
|
||||
try {
|
||||
context = createContext();
|
||||
|
||||
if (refreshInterval == -1 && !refreshDisabled) {
|
||||
eventContext = ((EventDirContext)context.lookup(""));
|
||||
|
@ -158,6 +171,7 @@ public class CachedLDAPAuthorizationMap extends DefaultAuthorizationMap implemen
|
|||
eventContext.addNamingListener(tempSearchBase, getFilterForPermissionType(permissionType), constraints,
|
||||
this.new CachedLDAPAuthorizationMapNamespaceChangeListener(DestinationType.TEMP, permissionType));
|
||||
}
|
||||
|
||||
}
|
||||
} catch (NamingException e) {
|
||||
context = null;
|
||||
|
@ -616,8 +630,15 @@ public class CachedLDAPAuthorizationMap extends DefaultAuthorizationMap implemen
|
|||
* and are the refresh interval has elapsed.
|
||||
*/
|
||||
protected void checkForUpdates() {
|
||||
if (!refreshDisabled && (refreshInterval != -1 && System.currentTimeMillis() >= lastUpdated + refreshInterval)) {
|
||||
|
||||
if (context == null || (!refreshDisabled && (refreshInterval != -1 && System.currentTimeMillis() >= lastUpdated + refreshInterval))) {
|
||||
if (context == null) {
|
||||
try {
|
||||
context = createContext();
|
||||
} catch (NamingException ne) {
|
||||
// LDAP is down, use already cached values
|
||||
return;
|
||||
}
|
||||
}
|
||||
reset();
|
||||
setTempDestinationAuthorizationEntry(null);
|
||||
entries.clear();
|
||||
|
@ -688,6 +709,7 @@ public class CachedLDAPAuthorizationMap extends DefaultAuthorizationMap implemen
|
|||
* {@link AuthorizationEntry} is not setup for concurrent access.
|
||||
*/
|
||||
public synchronized Set<Object> getReadACLs(ActiveMQDestination destination) {
|
||||
checkForUpdates();
|
||||
return super.getReadACLs(destination);
|
||||
}
|
||||
|
||||
|
@ -696,6 +718,7 @@ public class CachedLDAPAuthorizationMap extends DefaultAuthorizationMap implemen
|
|||
* {@link AuthorizationEntry} is not setup for concurrent access.
|
||||
*/
|
||||
public synchronized Set<Object> getWriteACLs(ActiveMQDestination destination) {
|
||||
checkForUpdates();
|
||||
return super.getWriteACLs(destination);
|
||||
}
|
||||
|
||||
|
@ -850,6 +873,7 @@ public class CachedLDAPAuthorizationMap extends DefaultAuthorizationMap implemen
|
|||
* @param namingExceptionEvent the exception event
|
||||
*/
|
||||
public void namingExceptionThrown(NamingExceptionEvent namingExceptionEvent) {
|
||||
context = null;
|
||||
LOG.error("Caught unexpected exception.", namingExceptionEvent.getException());
|
||||
}
|
||||
|
||||
|
|
|
@ -275,6 +275,53 @@ public abstract class AbstractCachedLDAPAuthorizationMapLegacyTest extends Abstr
|
|||
assertEquals("set size: " + failedACLs, 1, failedACLs.size());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testRestartAsync() throws Exception {
|
||||
testRestart(false);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testRestartSync() throws Exception {
|
||||
testRestart(true);
|
||||
}
|
||||
|
||||
public void testRestart(boolean sync) throws Exception {
|
||||
map.query();
|
||||
if (sync) {
|
||||
map.setRefreshInterval(1);
|
||||
}
|
||||
|
||||
Set<?> failedACLs = map.getReadACLs(new ActiveMQQueue("FAILED"));
|
||||
assertEquals("set size: " + failedACLs, 0, failedACLs.size());
|
||||
|
||||
failedACLs = map.getReadACLs(new ActiveMQQueue("TEST.FOO"));
|
||||
assertEquals("set size: " + failedACLs, 2, failedACLs.size());
|
||||
|
||||
getLdapServer().stop();
|
||||
|
||||
Thread.sleep(1000);
|
||||
|
||||
failedACLs = map.getReadACLs(new ActiveMQQueue("TEST.FOO"));
|
||||
assertEquals("set size: " + failedACLs, 2, failedACLs.size());
|
||||
|
||||
getLdapServer().start();
|
||||
|
||||
Thread.sleep(1000);
|
||||
|
||||
connection = getLdapConnection();
|
||||
|
||||
LdifReader reader = new LdifReader(getAddLdif());
|
||||
|
||||
for (LdifEntry entry : reader) {
|
||||
connection.add(entry.getEntry());
|
||||
}
|
||||
|
||||
Thread.sleep(2000);
|
||||
|
||||
failedACLs = map.getReadACLs(new ActiveMQQueue("FAILED"));
|
||||
assertEquals("set size: " + failedACLs, 2, failedACLs.size());
|
||||
}
|
||||
|
||||
protected CachedLDAPAuthorizationMap createMap() {
|
||||
return new CachedLDAPAuthorizationMap();
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue