package com.winterthur.jackpot.jboss.jndi;
import java.util.Properties;
import javax.management.MBeanServer;
import javax.management.MBeanServerFactory;
import javax.management.ObjectName;
import javax.naming.Binding;
import javax.naming.Context;
import javax.naming.InitialContext;
import javax.naming.Name;
import javax.naming.NameAlreadyBoundException;
import javax.naming.NameNotFoundException;
import javax.naming.NameParser;
import javax.naming.NamingEnumeration;
import javax.naming.NamingException;
import org.jboss.naming.JNDIView;
import junit.framework.TestCase;
import org.jboss.naming.ExternalContext;
import org.jboss.naming.NamingAlias;
import org.jboss.naming.NamingService;
import org.jboss.util.naming.Util;
/**
*
* This test shows the behaviour of the jboss jndi, the
* org.jboss.util.naming.Util utility regarding the NamingAlias and external
* context features.
* For the test, two jboss jndi server are started (in the current vm). For the
* ldap tests, an external LDAP directory is needed.
*
* @author Roland Räz
*/
public class JBossJndiUnbindTest extends TestCase {
private static final NamingService NAMING_SERVICE1 = new NamingService();;
private static final NamingService NAMING_SERVICE2 = new NamingService();;
private static final MBeanServer SERVER;
private static int NS1_PORT = 10100;
private static int NS2_PORT = 10102;
private static final Properties EXTERNAL_INITIAL_PROPERTIES = new Properties();
private static final Properties LDAP_INITIAL_PROPERTIES = new Properties();
private InitialContext ctx;
private static final JNDIView VIEW = new org.jboss.naming.JNDIView();;
static {
System.setProperty("java.naming.factory.initial",
"org.jnp.interfaces.NamingContextFactory");
System.setProperty("java.naming.factory.url.pkgs",
"org.jboss.naming:org.jnp.interfaces");
System.setProperty("java.naming.provider.url", "jnp://localhost:"
+ NS1_PORT);
SERVER = MBeanServerFactory.createMBeanServer("jboss");
createNs(NAMING_SERVICE1, NS1_PORT);
createNs(NAMING_SERVICE2, NS2_PORT);
// create properties for the external context
EXTERNAL_INITIAL_PROPERTIES.putAll(System.getProperties());
EXTERNAL_INITIAL_PROPERTIES.setProperty("java.naming.provider.url",
"jnp://localhost:" + NS2_PORT);
// create properties for the externalLdap context
LDAP_INITIAL_PROPERTIES.put(Context.INITIAL_CONTEXT_FACTORY,
"com.sun.jndi.ldap.LdapCtxFactory");
LDAP_INITIAL_PROPERTIES.put(Context.SECURITY_PRINCIPAL,
"cn=Manager,ou=JMX,o=winterthur,c=ch");
LDAP_INITIAL_PROPERTIES
.put(Context.PROVIDER_URL,
"ldap://ecpent01/cn=roli,ou=Connectors,ou=JMX,o=winterthur,c=ch");
LDAP_INITIAL_PROPERTIES.put(Context.SECURITY_CREDENTIALS, "xxx");
LDAP_INITIAL_PROPERTIES.put(Context.REFERRAL, "follow");
// start jndi view to debug
createJndiView();
}
private static void createNs(NamingService namingService, int port) {
try {
namingService.setCallByValue(true);
namingService.setPort(port);
namingService.setBindAddress("0.0.0.0");
namingService.setRmiBindAddress("0.0.0.0");
namingService.setRmiPort(port + 1);
namingService.create();
namingService.start();
} catch (Exception ex) {
ex.printStackTrace();
throw new RuntimeException(ex);
}
}
private static void createJndiView() {
try {
VIEW.setHANamingService("jboss:service=HaJndi");
VIEW.preRegister(SERVER, new ObjectName("jboss:service=JNDIView"));
VIEW.create();
VIEW.start();
} catch (Exception ex) {
ex.printStackTrace();
}
}
protected void setUp() throws Exception {
super.setUp();
ctx = new InitialContext();
cleanUp(ctx);
Context external = new InitialContext(EXTERNAL_INITIAL_PROPERTIES);
cleanUp(external);
ctx.createSubcontext("a");
ctx.createSubcontext("mnt");
// create an alias alias -> a
NamingAlias namingAlias = new NamingAlias();
namingAlias.setFromName("mnt/alias");
namingAlias.setToName("a");
namingAlias.start();
// create a link to the second jndi server
ExternalContext externalContextNS2 = new ExternalContext();
externalContextNS2.setJndiName("mnt/external");
externalContextNS2.setProperties(EXTERNAL_INITIAL_PROPERTIES);
externalContextNS2.create();
externalContextNS2.start();
// create a link to an ldap server
ExternalContext externalContextLdap = new ExternalContext();
externalContextLdap.setJndiName("mnt/externalLdap");
externalContextLdap.setProperties(LDAP_INITIAL_PROPERTIES);
externalContextLdap.create();
externalContextLdap.start();
}
private void cleanUp(Context ctx) throws NamingException {
NamingEnumeration e = ctx.listBindings("");
while (e.hasMoreElements()) {
Binding b = (Binding) e.next();
b.getName();
ctx.unbind(b.getName());
}
}
public void testAlias() throws Exception {
String name = "mnt/alias/b/c/d";
String value = "x";
directTst(name, value, false);
}
public void testAliasUtil() throws Exception {
String name = "mnt/alias/b/c/d";
String value = "x";
utilTst(name, value);
}
public void testAliasWorkaraound() throws Exception {
String name = "mnt/alias/b/c/d";
String value = "x";
directTst(name, value, true);
}
public void testSimple() throws Exception {
String name = "a/b/c/d";
String value = "x";
directTst(name, value, false);
}
public void testSimpleUtil() throws Exception {
String name = "a/b/c/d";
String value = "x";
utilTst(name, value);
}
public void testSimpleWorkaraound() throws Exception {
String name = "a/b/c/d";
String value = "x";
directTst(name, value, true);
}
public void testExternal() throws Exception {
String name = "mnt/external/a/b/c/d";
String value = "x";
directTst(name, value, false);
}
public void testExternalUtil() throws Exception {
String name = "external/a/b/c/d";
String value = "x";
utilTst(name, value);
}
public void testExternalWorkaround() throws Exception {
String name = "mnt/external/a/b/c/d";
String value = "x";
directTst(name, value, true);
}
public void testExternalLdap() throws Exception {
String name = "mnt/externalLdap/cn=test,cn=roli1";
String value = "x";
directTst(name, value, false);
}
public void testExternalLdapUtil() throws Exception {
String name = "mnt/externalLdap/cn=test,cn=roli2";
String value = "x";
utilTst(name, value);
}
public void testExternalLdapWorkaround() throws Exception {
String name = "mnt/externalLdap/cn=test,cn=roli3";
String value = "x";
directTst(name, value, true);
}
private void directTst(String name, String value,
boolean useParentContextToBindAndUnbind) throws NamingException {
show("_________________\nbefore bind:");
bind(ctx, name, value, useParentContextToBindAndUnbind);
show("_________________\nafter bind:");
Object result = ctx.lookup(name);
assertEquals(value, result);
rebind(ctx, name, value, useParentContextToBindAndUnbind);
show("_________________\nafter rebind:");
unbind(ctx, name, useParentContextToBindAndUnbind);
show("_________________\nafter unbind:");
try {
ctx.lookup(name);
fail(name + " should not be bound");
} catch (NameNotFoundException ignore) {
}
}
private void utilTst(String name, String value) throws NamingException {
show("_________________\nbefore bind:");
Util.bind(ctx, name, value);
show("_________________\nafter bind:");
Object result = ctx.lookup(name);
assertEquals(value, result);
Util.rebind(ctx, name, value);
show("_________________\nafter rebind:");
Util.unbind(ctx, name);
show("_________________\nafter unbind:");
try {
ctx.lookup(name);
fail(name + " should not be bound");
} catch (NameNotFoundException ignore) {
}
}
private void bind(Context ctx, String name, Object value,
boolean useParentContextToBindAndUnbind) throws NamingException {
NameParser np = ctx.getNameParser(name);
Name n = np.parse(name);
Context myContext = ctx;
while (n.size() > 1) {
String nameComponent = n.get(0);
try {
myContext = (Context) myContext.lookup(nameComponent);
} catch (NameNotFoundException ex) {
myContext = myContext.createSubcontext(nameComponent);
}
Name tempN = n.getSuffix(1);
np = myContext.getNameParser(n);
n = np.parse(tempN.toString());
}
if (useParentContextToBindAndUnbind) {
try {
myContext.bind(n.get(0), value);
} catch (NameAlreadyBoundException ex) {
// fix naming for a further test !!!
myContext.unbind(n.get(0));
ex.printStackTrace();
fail(ex.toString());
}
} else {
try {
ctx.bind(name, value);
} catch (NameAlreadyBoundException ex) {
// fix naming for a further test !!!
ctx.unbind(name);
ex.printStackTrace();
fail(ex.toString());
}
}
}
private void unbind(Context ctx, String name,
boolean useParentContextToBindAndUnbind) throws NamingException {
if (useParentContextToBindAndUnbind) {
NameParser np = ctx.getNameParser(name);
Name n = np.parse(name);
Context parent = (Context) ctx.lookup(n.getPrefix(n.size() - 1));
parent.unbind(n.get(n.size() - 1));
} else {
ctx.unbind(name);
}
}
private void rebind(Context ctx, String name, Object value,
boolean useParentContextToBindAndUnbind) throws NamingException {
if (useParentContextToBindAndUnbind) {
NameParser np = ctx.getNameParser(name);
Name n = np.parse(name);
Context parent = (Context) ctx.lookup(n.getPrefix(n.size() - 1));
parent.rebind(n.get(n.size() - 1), value);
} else {
ctx.rebind(name, value);
}
}
static void show(String msg) {
String result = VIEW.list(false);
System.out.println(msg);
System.out.println(result);
}
}