blob: 21778097cd50a9e247f7370a4ff7d20f96d6adeb [file] [log] [blame]
/*
* Copyright (c) 1997, 2020 Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2021 Contributors to the Eclipse Foundation
*
* This program and the accompanying materials are made available under the
* terms of the Eclipse Public License v. 2.0, which is available at
* http://www.eclipse.org/legal/epl-2.0.
*
* This Source Code may also be made available under the following Secondary
* Licenses when the conditions for such availability set forth in the
* Eclipse Public License v. 2.0 are satisfied: GNU General Public License,
* version 2 with the GNU Classpath Exception, which is available at
* https://www.gnu.org/software/classpath/license.html.
*
* SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0
*/
package test.com.sun.jaspic.config;
import static org.hamcrest.MatcherAssert.assertThat;
import static org.hamcrest.Matchers.arrayWithSize;
import static org.hamcrest.Matchers.greaterThan;
import static org.junit.jupiter.api.Assertions.assertFalse;
import static org.junit.jupiter.api.Assertions.assertNotNull;
import static org.junit.jupiter.api.Assertions.assertNull;
import static org.junit.jupiter.api.Assertions.assertTrue;
import static org.junit.jupiter.api.Assertions.fail;
import java.security.PrivilegedExceptionAction;
import java.security.Security;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Random;
import java.util.concurrent.Callable;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.Future;
import java.util.concurrent.TimeUnit;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.security.auth.Subject;
import javax.security.auth.callback.CallbackHandler;
import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import com.sun.jaspic.config.factory.AuthConfigFileFactory;
import com.sun.jaspic.config.factory.BaseAuthConfigFactory;
import com.sun.jaspic.config.factory.EntryInfo;
import com.sun.jaspic.config.factory.RegStoreFileParser;
import jakarta.security.auth.message.AuthException;
import jakarta.security.auth.message.MessageInfo;
import jakarta.security.auth.message.config.AuthConfigFactory;
import jakarta.security.auth.message.config.AuthConfigFactory.RegistrationContext;
import jakarta.security.auth.message.config.AuthConfigProvider;
import jakarta.security.auth.message.config.ClientAuthConfig;
import jakarta.security.auth.message.config.ClientAuthContext;
import jakarta.security.auth.message.config.RegistrationListener;
import jakarta.security.auth.message.config.ServerAuthConfig;
import jakarta.security.auth.message.config.ServerAuthContext;
/**
* @author Ron Monzillo
*/
public class FactoryTest {
/** switch definition of default test factory to test native factory
* will also need to configure proper dependencies
*/
// private static final String DEFAULT_TEST_FACTORY_CLASS_NAME = "com.sun.enterprise.security.jmac.config.SaveAuthConfigFactory";
private static final String DEFAULT_TEST_FACTORY_CLASS_NAME = AuthConfigFileFactory.class.getName();
private static String testFactoryClassName = DEFAULT_TEST_FACTORY_CLASS_NAME;
public static final String DEFAULT_FACTORY_SECURITY_PROPERTY = "authconfigprovider.factory";
public static final String USER_DIR_PROPERTY = "user.dir";
static final String THREAD_COUNT_KEY = "test.thread.count";
static final String MAX_JOIN_SECONDS_KEY = "test.max.join.seconds";
static final String TEST_FACTORY_CLASS_NAME_KEY = "test.factory.class.name";
static final int DEFAULT_THREAD_COUNT = 32;
static final int DEFAULT_MAX_JOIN_SECONDS = 600;
static final Logger logger = Logger.getLogger(FactoryTest.class.getName());
private static String defaultFactoryClassName;
private static AuthConfigFactory testFactory;
static HashMap<String, String> options = new HashMap<>();
private static ExecutorService threadPool;
static int consumerCount;
static int activeConsumers;
static Random random = new Random();
static final String[] layers = new String[4];
static final String[] contexts = new String[16];
static {
layers[0] = null;
for (int i = 1; i < layers.length; i++) {
layers[i] = "layer" + Integer.toString(i);
}
contexts[0] = null;
for (int i = 1; i < contexts.length; i++) {
contexts[i] = "context" + Integer.toString(i);
}
}
static AuthConfigProvider[] providers = new AuthConfigProvider[4];
public static String getStringOption(String key, String defaultValue) {
String s = options == null ? null : (String) options.get(key);
if (s == null) {
return defaultValue;
}
return s;
}
public static int getIntOption(String key, int defaultValue) {
String s = options == null ? null : (String) options.get(key);
if (s == null) {
return defaultValue;
}
return Integer.valueOf(s).intValue();
}
public static boolean getbooleanOption(String key, boolean defaultValue) {
String s = options == null ? null : (String) options.get(key);
if (s == null) {
return defaultValue;
}
return Boolean.valueOf(s).booleanValue();
}
public static String[] splitStringOption(String s) {
if (s == null) {
return new String[0];
}
return s.split(",|:| |;");
}
static Map<String, String> getProviderProperties() {
return new HashMap<>();
}
static AuthConfigFactory loadFactory(final String className) {
AuthConfigFactory factory = null;
try {
PrivilegedExceptionAction action = () -> {
ClassLoader loader = Thread.currentThread().getContextClassLoader();
Class clazz = Class.forName(className, true, loader);
return clazz.newInstance();
};
factory = (AuthConfigFactory) java.security.AccessController.doPrivileged(action);
} catch (java.security.PrivilegedActionException pae) {
throw new SecurityException(pae.getException());
} finally {
assertNotNull(factory, "loadFactory returned null");
}
return factory;
}
@BeforeEach
public void beforeTest() {
try {
defaultFactoryClassName = Security.getProperty(DEFAULT_FACTORY_SECURITY_PROPERTY);
logger.log(Level.INFO, "\n\tSecurity Manager is {0}\n\t{1} is {2}\n\t{3} is {4}\n\t{5} is {6}\n",
new Object[]{
(System.getSecurityManager() == null ? "OFF" : "ON"),
DEFAULT_FACTORY_SECURITY_PROPERTY, defaultFactoryClassName,
"Test Factory Class Name", testFactoryClassName,
USER_DIR_PROPERTY, System.getProperty(USER_DIR_PROPERTY)});
testFactory = loadFactory(testFactoryClassName);
AuthConfigFactory.setFactory(testFactory);
} catch (Throwable t) {
logger.log(Level.SEVERE, "Exception in test setup", t);
fail("exception in test setup: " + t.toString());
}
assertNotNull(AuthConfigFactory.getFactory(), "at exit of beforeTest getFactory returns null");
}
@AfterEach
public void afterTest() {
AuthConfigFactory.setFactory(null);
}
@Test
public void testSetFactory() {
logger.info("BEGIN Set FACTORY TEST");
AuthConfigFactory.setFactory(null);
assertTrue(defaultFactoryClassName == null
? AuthConfigFactory.getFactory() == null
: defaultFactoryClassName.equals(AuthConfigFactory.getFactory().getClass().getName()));
if (defaultFactoryClassName != null) {
Security.setProperty(DEFAULT_FACTORY_SECURITY_PROPERTY, testFactoryClassName);
AuthConfigFactory.setFactory(null);
assertTrue(testFactoryClassName.equals(AuthConfigFactory.getFactory().getClass().getName()));
Security.setProperty(DEFAULT_FACTORY_SECURITY_PROPERTY, defaultFactoryClassName);
AuthConfigFactory.setFactory(null);
assertTrue(defaultFactoryClassName.equals(AuthConfigFactory.getFactory().getClass().getName()));
}
AuthConfigFactory.setFactory(testFactory);
assertTrue(testFactoryClassName.equals(AuthConfigFactory.getFactory().getClass().getName()));
}
@Test
public void testRegistrationWithNonStringProperty() {
logger.info("BEGIN Registration with NonString Property FACTORY TEST");
Security.setProperty(DEFAULT_FACTORY_SECURITY_PROPERTY, testFactoryClassName);
String className = _AuthConfigProvider.class.getName();
HashMap properties = new HashMap();
ArrayList list = new ArrayList();
list.add("larry was here");
properties.put("test", list);
String layer = "HttpServlet";
String appContext = "context";
String description = null;
String regId = null;
try {
regId = AuthConfigFactory.getFactory().registerConfigProvider(className, properties, layer, appContext, description);
} catch (IllegalArgumentException iae) {
assertNull(regId, "Failed Registration Should Have Resulted in a NULL RegistrationID returned but did not.");
}
AuthConfigProvider acp = null;
acp = AuthConfigFactory.getFactory().getConfigProvider(layer, appContext, null);
assertNull(acp, "Registration Should Have Failed and Therefore No ACP Should Have been Found.");
}
@Test
public void testOverrideForDefaultEntries() {
logger.info("BEGIN overrideGetDefaultEntries TEST");
AuthConfigFactory f = new _ExtendsBaseAuthConfigFactory();
f = new _Extends_ExtendsAuthConfigFactory();
}
static class _ExtendsBaseAuthConfigFactory extends BaseAuthConfigFactory {
// regStore MUST hide regStore of bade class
private static RegStoreFileParser regStore = null;
/**
* To specialize the defaultEntries passed to the RegStoreFileParser,
* construct EntryInfo objects within this constructor.
* THE EentyInfo OBJECTS MUST ONLY BE CONSTRCTED USING THE FOLLOWING
* CONSTRUCTOR: EntryInfo(String className, Map<String, String> properties)
* NO Entries are passed by this test, because to do so, the parent
* test class would need to import EntryInfo (which it can't).
*/
public _ExtendsBaseAuthConfigFactory() {
rLock.lock();
try {
if (regStore != null) {
return;
}
} finally {
rLock.unlock();
}
String userDir = System.getProperty("user.dir");
wLock.lock();
try {
if (regStore == null) {
EntryInfo e = new EntryInfo(_AuthConfigProvider.class.getName(),null);
List<EntryInfo> defaultEntries = new ArrayList<>();
defaultEntries.add(e);
regStore = new RegStoreFileParser(userDir,
BaseAuthConfigFactory.CONF_FILE_NAME,defaultEntries);
_loadFactory();
}
} finally {
wLock.unlock();
}
RegStoreFileParser rS = getRegStore();
assertTrue(rS == _ExtendsBaseAuthConfigFactory.regStore);
}
@Override
protected RegStoreFileParser getRegStore() {
rLock.lock();
try {
return regStore;
} finally {
rLock.unlock();
}
}
}
static class _Extends_ExtendsAuthConfigFactory extends _ExtendsBaseAuthConfigFactory {
// regStore MUST hide regStore of base class
private static RegStoreFileParser regStore = null;
/**
* To specialize the defaultEntries passed to the RegStoreFileParser,
* construct EntryInfo objects within this constructor.
* THE EentyInfo OBJECTS MUST ONLY BE CONSTRCTED USING THE FOLLOWING
* CONSTRUCTOR: EntryInfo(String className, Map<String, String> properties)
* NO Entries are passed by this test, because to do so, the parent
* test class would need to import EntryInfo (which it can't).
*/
public _Extends_ExtendsAuthConfigFactory() {
rLock.lock();
try {
if (regStore != null) {
return;
}
} finally {
rLock.unlock();
}
String userDir = System.getProperty("user.dir");
wLock.lock();
try {
if (regStore == null) {
EntryInfo e = new EntryInfo(_AuthConfigProvider.class.getName(),null);
List<EntryInfo> defaultEntries = new ArrayList<>();
defaultEntries.add(e);
regStore = new RegStoreFileParser(userDir,
BaseAuthConfigFactory.CONF_FILE_NAME,defaultEntries);
_loadFactory();
}
} finally {
wLock.unlock();
}
RegStoreFileParser rS = getRegStore();
assertTrue(rS == _Extends_ExtendsAuthConfigFactory.regStore);
}
@Override
protected RegStoreFileParser getRegStore() {
rLock.lock();
try {
return regStore;
} finally {
rLock.unlock();
}
}
}
@Test
public void testRemoveRegistration() {
logger.info("BEGIN Remove Registration TEST");
final AuthConfigFactory f = AuthConfigFactory.getFactory();
f.refresh();
// does self registration
AuthConfigProvider p = new _AuthConfigProvider(new HashMap(), f);
RegistrationContext rc;
String[] rids = f.getRegistrationIDs(p);
boolean removed;
assertThat("provider did not self register", rids, arrayWithSize(greaterThan(0)));
for (String i : rids) {
rc = f.getRegistrationContext(i);
removed = f.removeRegistration(i);
assertNotNull(rc);
assertTrue(removed, "expected true from removeRegistration - rid: " + i);
}
for (String i : rids) {
rc = f.getRegistrationContext(i);
removed = f.removeRegistration(i);
assertNull(rc);
assertFalse(removed, "expected false from removeRegistration - rid: " + i);
}
// testing registration and removal of null provider;
String rid = f.registerConfigProvider(null, null, null, "null registration");
rc = f.getRegistrationContext(rid);
removed = f.removeRegistration(rid);
assertNotNull(rc);
assertTrue(removed, "testing null provider - expected true from removeRegistration - rid: " + rid);
// testing for interferece with null provider
rc = f.getRegistrationContext(rid);
removed = f.removeRegistration(rid);
assertNull(rc);
assertFalse(removed, "testing null provider - expected false from removeRegistration - rid: " + rid);
rid = f.registerConfigProvider(null, null, null, "null registration");
// temporary to force call to decomposeRegId in getEffectedListeners
f.getConfigProvider(null, null, new _Listener(null, null, false));
rc = f.getRegistrationContext(rid);
assertNotNull(rid, "testing null provider - getRegistrationContext - rid: " + rid);
String badRid = "someInvalidId";
rc = f.getRegistrationContext(badRid);
removed = f.removeRegistration(badRid);
assertNull(rc);
assertFalse(removed, "expected false from removeRegistration - rid: " + badRid);
rc = f.getRegistrationContext(rid);
removed = f.removeRegistration(rid);
assertNotNull(rc);
assertTrue(removed, "testing null provider - expected true from removeRegistration - rid: " + rid);
}
@Test
public void testListeners() {
logger.info("BEGIN Listener TEST");
final AuthConfigFactory f = AuthConfigFactory.getFactory();
final AuthConfigProvider p = new _AuthConfigProvider(new HashMap(), null);
String layer[] = {null, "11", "l2"};
String context[] = {null, "c1", "c2"};
String rid[] = new String[(layer.length - 1) * (context.length - 1)];
String ridLayer[] = new String[rid.length];
String ridContext[] = new String[rid.length];
int z = 0;
for (int i = 0; i < 2; i++) {
for (int j = 0; j < 2; j++) {
ridLayer[z] = layer[i];
ridContext[z] = context[j];
rid[z] = f.registerConfigProvider(p, ridLayer[z], ridContext[z],
ridLayer[z] + ridContext[z]);
z++;
}
}
_Listener listener[] = new _Listener[rid.length];
z = 0;
for (int i = 1; i < layer.length; i++) {
for (int j = 1; j < context.length; j++) {
listener[z] = new _Listener(layer[i], context[j], true);
f.getConfigProvider(layer[i], context[j], listener[z]);
z++;
}
}
for (String element : rid) {
f.removeRegistration(element);
}
f.detachListener(listener[0], null, null);
f.detachListener(listener[1], listener[1].getLayer(), null);
f.detachListener(listener[2], null, listener[2].getAppContext());
f.detachListener(listener[3], listener[3].getLayer(), listener[3].getAppContext());
//should not find any left to detach
for (_Listener element : listener) {
f.detachListener(element, element.getLayer(), element.getAppContext());
}
for (int i = 0; i < rid.length; i++) {
rid[i] = f.registerConfigProvider(p, ridLayer[i], ridContext[i], ridLayer[i] + ridContext[i]);
}
z = 0;
for (int i = 1; i < layer.length; i++) {
for (int j = 1; j < context.length; j++) {
listener[z] = new _Listener(layer[i], context[j], false);
f.getConfigProvider(layer[i], context[j], listener[z]);
z++;
}
}
for (int i = 0; i < rid.length; i++) {
for (_Listener element : listener) {
if (element.notified) {
assertTrue(element.register(), "Test Setup Failure - listener could not be registered");
}
}
f.removeRegistration(rid[i]);
for (_Listener element : listener) {
element.check(ridLayer[i], ridContext[i]);
}
}
//repeat with null provider registrations
for (int i = 0; i < rid.length; i++) {
rid[i] = f.registerConfigProvider(null, ridLayer[i], ridContext[i], ridLayer[i] + ridContext[i]);
}
z = 0;
for (int i = 1; i < layer.length; i++) {
for (int j = 1; j < context.length; j++) {
listener[z] = new _Listener(layer[i], context[j], false);
f.getConfigProvider(layer[i], context[j], listener[z]);
z++;
}
}
for (int i = 0; i < rid.length; i++) {
for (_Listener element : listener) {
if (element.notified) {
assertTrue(element.register(), "Test Setup Failure - listener could not be registered");
}
}
f.removeRegistration(rid[i]);
for (_Listener element : listener) {
element.check(ridLayer[i], ridContext[i]);
}
}
}
static class _Listener implements RegistrationListener {
String layer;
String appContext;
boolean reRegister;
boolean notified;
_Listener(String layer, String appContext, boolean reRegister) {
this.layer = layer;
this.appContext = appContext;
this.reRegister = reRegister;
this.notified = false;
}
String getLayer() {
return layer;
}
String getAppContext() {
return appContext;
}
synchronized boolean register() {
boolean rvalue = false;
if (notified) {
notified = false;
rvalue = true;
AuthConfigFactory.getFactory().getConfigProvider(layer, appContext, this);
}
return rvalue;
}
synchronized boolean notified() {
return notified;
}
void check(String l, String c) {
boolean shouldHaveBeenNotified = false;
if ((l == null || layer.equals(l)) && (c == null || appContext.equals(c))) {
shouldHaveBeenNotified = true;
}
if (shouldHaveBeenNotified) {
String msg = "listener at layer,context: " + layer + "," + appContext + " should have been notified at: "
+ l + "," + c;
assertTrue(notified(), msg);
} else {
String msg = "listener at layer,context: " + layer + "," + appContext + " should NOT have been notified at: "
+ l + "," + c;
assertFalse(notified(), msg);
}
}
@Override
public void notify(String l, String c) {
synchronized (this) {
notified = true;
}
boolean validNotification = (layer == l || layer.equals(l))
&& (appContext == c || appContext.equals(c));
String msg = "listener notified at wrong layer: " + l + " or context: " + c;
assertTrue(validNotification, msg);
if (validNotification && reRegister) {
register();
}
}
}
@Test
public void stressFactory() {
stressFactory(DEFAULT_THREAD_COUNT, DEFAULT_MAX_JOIN_SECONDS);
}
public void stressFactory(int threadCount, int maxJoinSeconds) {
logger.info("BEGIN stress FACTORY TEST");
AuthConfigFactory f = AuthConfigFactory.getFactory();
f.refresh();
providers[0] = null;
for (int i = 1; i < providers.length; i++) {
providers[i] = new _AuthConfigProvider(getProviderProperties(), null);
}
threadPool = Executors.newFixedThreadPool(threadCount);
synchronized (_Thread.class) {
activeConsumers = threadCount;
consumerCount = threadCount;
}
ArrayList<Callable<_ResultCarrier>> tasks = new ArrayList<>();
for (int i = 0; i < threadCount; i++) {
_ResultCarrier carrier = new _ResultCarrier();
Callable<_ResultCarrier> task =
Executors.callable(new _Thread(threadCount,carrier),carrier);
tasks.add(task);
}
logger.log(Level.INFO, "STARTING {0} THREADS", threadCount);
try {
List<Future<_ResultCarrier>> futures = threadPool.invokeAll(tasks,maxJoinSeconds,TimeUnit.SECONDS);
for (Future<_ResultCarrier> future : futures) {
if (future.isCancelled()) {
logger.log(Level.WARNING,
"try increasing maxJoinSeconds in {0}: test aborted because it did not terminate in {1} seconds",
new Object[]{this.getClass().getName(),maxJoinSeconds});
fail("test did not terminate in: " + maxJoinSeconds + " seconds");
} else if (future.isDone()) {
String errorMessage = future.get().getResult();
if (errorMessage != null) {
logger.log(Level.SEVERE, errorMessage);
fail(errorMessage);
}
}
}
} catch (Throwable t) {
String exceptionMessage = "exception from invoking tasks or from invoked task";
logger.log(Level.SEVERE, exceptionMessage,t);
fail(exceptionMessage + t.toString());
}
synchronized (_Thread.class) {
logger.log(Level.INFO, "ALL THREADS JOINED - producers: {0} consumers: {1}",
new Object[]{threadCount - consumerCount, consumerCount});
}
String[] rids = f.getRegistrationIDs(null);
for (String i : rids) {
RegistrationContext rc = f.getRegistrationContext(i);
f.removeRegistration(i);
}
logger.info("ALL REGISTRATIONS REMOVED");
f.refresh();
}
static class _ResultCarrier {
String result;
synchronized String getResult() {
return result;
}
synchronized void setResult(String result) {
this.result = result;
}
}
static class _Thread extends Thread implements RegistrationListener {
_ResultCarrier resultCarrier;
boolean runAsConsumer;
boolean stop;
_Thread(int threadCount, _ResultCarrier carrier) {
this.resultCarrier = carrier;
synchronized (_Thread.class) {
if (consumerCount == threadCount) {
runAsConsumer = false;
} else {
runAsConsumer = (random.nextInt(10) != 1);
}
if (!runAsConsumer) {
consumerCount--;
activeConsumers--;
logger.log(Level.FINE, "creating producer, remaining consumers: {0}", consumerCount);
}
}
setResult(null);
stop = false;
}
private void setResult(String result) {
resultCarrier.setResult(result);
}
@Override
public void run() {
AuthConfigFactory f = AuthConfigFactory.getFactory();
if (f == null) {
String msg = "new thread: " + getId() + " found null factory";
logger.log(Level.SEVERE,msg);
setResult(msg);
}
else if (runAsConsumer) {
doConsumer(f, layers[random.nextInt(layers.length)],
contexts[random.nextInt(contexts.length)]);
} else {
while (true) {
synchronized (_Thread.class) {
if (activeConsumers == 0) {
setResult(null);
return;
}
}
switch (random.nextInt(5)) {
case 0:
if (random.nextInt(25) == 1) {
try {
f.refresh();
} catch (Exception e) {
String msg = "producer thread(refresh): " + getId() + " caught exception: ";
logger.log(Level.SEVERE, msg, e);
setResult(msg + e.toString());
return;
}
}
break;
case 1:
if (random.nextInt(1000) == 1) {
try {
f = AuthConfigFactory.getFactory();
if (f == null) {
String msg = "producer thread(get/set): " + getId() + " found null factory";
logger.log(Level.SEVERE, msg);
setResult(msg);
return;
}
AuthConfigFactory.setFactory(f);
} catch (Exception e) {
String msg = "producer thread(get/setFactory): " + getId() + " caught exception: ";
logger.log(Level.SEVERE, msg, e);
setResult(msg + e.toString());
return;
}
}
break;
case 2:
try {
f.registerConfigProvider(
_AuthConfigProvider.class.getName(),
getProviderProperties(),
layers[random.nextInt(layers.length)],
contexts[random.nextInt(contexts.length)],
"persistent registration");
} catch (Exception e) {
String msg = "producer thread(register persistent): " + getId() + " caught exception: ";
logger.log(Level.SEVERE, msg, e);
setResult(msg + e.toString());
return;
}
break;
case 3:
try {
f.registerConfigProvider(
providers[random.nextInt(providers.length)],
layers[random.nextInt(layers.length)],
contexts[random.nextInt(contexts.length)],
"transient registration");
} catch (Exception e) {
String msg = "producer thread(register transient): " + getId() + " caught exception: ";
logger.log(Level.SEVERE, msg, e);
setResult(msg + e.toString());
return;
}
break;
case 4:
try {
String[] rids = f.getRegistrationIDs(
providers[random.nextInt(providers.length)]);
int length = rids.length;
boolean removeNext = true;
for (String rid : rids) {
RegistrationContext rc = f.getRegistrationContext(rid);
if (rc == null) {
removeNext = true;
} else if (removeNext) {
f.removeRegistration(rid);
removeNext = false;
} else {
removeNext = true;
}
}
} catch (Exception e) {
String msg = "producer thread(remove registration): " + getId() + " caught exception: ";
logger.log(Level.SEVERE, msg, e);
setResult(msg + e.toString());
return;
}
break;
}
}
}
}
public void doConsumer(AuthConfigFactory f, String layer, String context) {
String msg = null;
synchronized (_Thread.class) {
logger.log(Level.FINE, "creating consumer");
this.stop = false;
}
try {
f.getConfigProvider(layer, context, this);
while (true) {
sleep(10);
synchronized (_Thread.class) {
if (this.stop) {
break;
}
}
}
f.detachListener(this, null, null);
} catch (Exception e) {
msg = "consumer thread: " + getId() + " caught exception";
logger.log(Level.SEVERE, msg, e);
setResult(msg + e.toString());
} finally {
synchronized (_Thread.class) {
activeConsumers--;
logger.log(Level.INFO, "consumer thread: {0} stopping - remaining: {1}",
new Object[]{getId(), activeConsumers});
}
}
}
@Override
public void notify(String layer, String context) {
if (random.nextInt(100) == 1) {
synchronized (_Thread.class) {
setResult(null);
this.stop = true;
}
} else {
AuthConfigFactory factory = AuthConfigFactory.getFactory();
if (factory != null) {
factory.getConfigProvider(layer, context, this);
} else {
synchronized (_Thread.class) {
setResult("factory is null in notify call on consumer");
this.stop = true;
}
}
}
}
}
public static class _AuthConfigProvider implements AuthConfigProvider {
public _AuthConfigProvider(Map<String, String> properties, AuthConfigFactory f) {
if (f != null) {
f.registerConfigProvider(this,
layers[random.nextInt(layers.length)],
contexts[random.nextInt(contexts.length)],
"self registration");
}
}
@Override
public ClientAuthConfig getClientAuthConfig(final String layer,
final String appCtxt, CallbackHandler ch) throws AuthException {
return new ClientAuthConfig() {
@Override
public ClientAuthContext getAuthContext(String string, Subject sbjct, Map map) throws AuthException {
throw new UnsupportedOperationException();
}
@Override
public String getMessageLayer() {
return layer;
}
@Override
public String getAppContext() {
return appCtxt;
}
@Override
public String getAuthContextID(MessageInfo mi) {
throw new UnsupportedOperationException();
}
@Override
public void refresh() {
}
@Override
public boolean isProtected() {
throw new UnsupportedOperationException();
}
};
}
@Override
public ServerAuthConfig getServerAuthConfig(final String layer,
final String appCtxt, CallbackHandler ch) throws AuthException {
return new ServerAuthConfig() {
@Override
public ServerAuthContext getAuthContext(String string, Subject sbjct, Map map) throws AuthException {
throw new UnsupportedOperationException();
}
@Override
public String getMessageLayer() {
return layer;
}
@Override
public String getAppContext() {
return appCtxt;
}
@Override
public String getAuthContextID(MessageInfo mi) {
throw new UnsupportedOperationException();
}
@Override
public void refresh() {
}
@Override
public boolean isProtected() {
throw new UnsupportedOperationException();
}
};
}
@Override
public void refresh() {
}
}
}