package org.rzo.yajsw.tray.ahessian.client; import java.net.InetSocketAddress; import java.util.HashMap; import java.util.Map; import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors; import java.util.concurrent.TimeUnit; import java.util.concurrent.locks.Condition; import java.util.concurrent.locks.Lock; import java.util.concurrent.locks.ReentrantLock; import javax.management.MBeanServerConnection; import org.jboss.netty.bootstrap.ClientBootstrap; import org.jboss.netty.channel.ChannelFuture; import org.jboss.netty.channel.socket.nio.NioClientSocketChannelFactory; import org.jboss.netty.util.HashedWheelTimer; import org.rzo.netty.ahessian.application.jmx.remote.service.AsyncMBeanServerConnection; import org.rzo.netty.ahessian.application.jmx.remote.service.MBeanServerConnectionAsyncAdapter; import org.rzo.netty.ahessian.rpc.client.BootstrapProvider; import org.rzo.netty.ahessian.rpc.client.HessianProxyFactory; import org.rzo.netty.mcast.discovery.DiscoveryClient; import org.rzo.netty.mcast.discovery.DiscoveryListener; public class AHessianJmxClient implements BootstrapProvider { boolean stop = false; DiscoveryClient discovery = null; ExecutorService executor = Executors.newCachedThreadPool(); ClientBootstrap bootstrap = new ClientBootstrap(new NioClientSocketChannelFactory(executor, executor)); MBeanServerConnection mbeanServer; final Lock lock = new ReentrantLock(); final Condition connected = lock.newCondition(); String currentHost = null; HessianProxyFactory factory; public AHessianJmxClient(String discoveryName, int port) throws Exception { factory = new HessianProxyFactory(executor, "AHessianJMX", null); // in case we are disconnected: start the discovery factory.setDisconnectedListener(new Runnable() { public void run() { try { close(); if (discovery != null) { if (currentHost != null) discovery.removeHost(currentHost); discovery.start(); } } catch (Exception e) { e.printStackTrace(); } } }); factory.setConnectedListener(new Runnable() { public void run() { // if (discovery == null) doConnected(); } }); bootstrap.setOption("reuseAddress", true); // if we do not have a port: use discovery if (port == 0) { discovery = new DiscoveryClient(); bootstrap.setPipelineFactory(new AHessianClientPipelineFactory(executor, factory, null)); discovery.setName(discoveryName); discovery.addListener(new DiscoveryListener() { // we have discovered our mbean server public void newHost(String name, String host) { try { // get the port - hostName should be the local host String[] x = host.split("&"); int port = Integer.parseInt(x[2]); String hostName = x[1]; // try to connect ChannelFuture future = bootstrap.connect(new InetSocketAddress(hostName, port)); // future.await(10000); // stop discovery discovery.stop(); // doConnected(); currentHost = host; } catch (Exception ex) { ex.printStackTrace(); } } }); discovery.init(); discovery.start(); } // if we have a port connect to that port else { bootstrap.setOption("remoteAddress", new InetSocketAddress("localhost", port)); bootstrap.setPipelineFactory(new AHessianClientPipelineFactory(executor, factory, this, new HashedWheelTimer())); bootstrap.connect(); } } private void doConnected() { lock.lock(); Map options = new HashMap(); options.put("sync", true); options.put("timeout", (long) 2000); // we will be using a synchronous service AsyncMBeanServerConnection asyncService = (AsyncMBeanServerConnection) factory.create(AsyncMBeanServerConnection.class, AHessianJmxClient.class.getClassLoader(), options); mbeanServer = new MBeanServerConnectionAsyncAdapter(asyncService); connected.signal(); lock.unlock(); } public MBeanServerConnection getMBeanServer() { while (mbeanServer == null && !stop) { lock.lock(); try { connected.await(1000, TimeUnit.MILLISECONDS); } catch (InterruptedException e) { e.printStackTrace(); } lock.unlock(); } return mbeanServer; } public void close() { factory.setBlocked(true); factory.invalidateAllPendingCalls(); factory.invalidateProxies(); mbeanServer = null; if (factory.getChannel() != null && factory.getChannel().isConnected()) factory.getChannel().close(); } public void open() { factory.setBlocked(false); } public void stop() { stop = true; } public ClientBootstrap getBootstrap() { return bootstrap; } }