/* */ package org.jboss.invocation.pooled.server;
/* */
/* */ import java.io.PrintStream;
/* */ import java.lang.reflect.Method;
/* */ import java.net.BindException;
/* */ import java.net.InetAddress;
/* */ import java.net.ServerSocket;
/* */ import java.net.Socket;
/* */ import java.net.UnknownHostException;
/* */ import java.rmi.NoSuchObjectException;
/* */ import java.security.AccessController;
/* */ import java.security.PrivilegedActionException;
/* */ import java.security.PrivilegedExceptionAction;
/* */ import java.util.LinkedList;
/* */ import javax.management.MBeanServer;
/* */ import javax.management.ObjectName;
/* */ import javax.naming.InitialContext;
/* */ import javax.net.ServerSocketFactory;
/* */ import javax.net.SocketFactory;
/* */ import javax.transaction.Transaction;
/* */ import javax.transaction.TransactionManager;
/* */ import org.jboss.invocation.Invocation;
/* */ import org.jboss.invocation.pooled.interfaces.PooledInvokerProxy;
/* */ import org.jboss.invocation.pooled.interfaces.PooledMarshalledInvocation;
/* */ import org.jboss.invocation.pooled.interfaces.ServerAddress;
/* */ import org.jboss.logging.Logger;
/* */ import org.jboss.mx.util.JMXExceptionDecoder;
/* */ import org.jboss.net.sockets.DefaultSocketFactory;
/* */ import org.jboss.proxy.TransactionInterceptor;
/* */ import org.jboss.security.SecurityDomain;
/* */ import org.jboss.system.Registry;
/* */ import org.jboss.system.ServiceMBeanSupport;
/* */ import org.jboss.system.server.ServerConfigUtil;
/* */ import org.jboss.tm.TransactionPropagationContextFactory;
/* */ import org.jboss.tm.TransactionPropagationContextImporter;
/* */ import org.jboss.tm.TransactionPropagationContextUtil;
/* */ import org.jboss.util.UnreachableStatementException;
/* */
/* */ public class PooledInvoker extends ServiceMBeanSupport
/* */ implements PooledInvokerMBean, Runnable
/* */ {
/* 85 */ protected static final Logger log = Logger.getLogger(PooledInvoker.class);
/* */ protected boolean enableTcpNoDelay;
/* */ protected String serverBindAddress;
/* */ protected int serverBindPort;
/* */ protected String clientConnectAddress;
/* */ protected int clientConnectPort;
/* */ protected int clientRetryCount;
/* */ protected int backlog;
/* */ protected String clientSocketFactoryName;
/* */ protected String serverSocketFactoryName;
/* */ protected SocketFactory clientSocketFactory;
/* */ protected ServerSocketFactory serverSocketFactory;
/* */ protected ServerSocket serverSocket;
/* */ protected String sslDomain;
/* */ protected int timeout;
/* */ protected int maxPoolSize;
/* */ protected int clientMaxPoolSize;
/* */ protected int numAcceptThreads;
/* */ protected Thread[] acceptThreads;
/* */ protected LRUPool clientpool;
/* */ protected LinkedList threadpool;
/* */ protected boolean running;
/* */ protected boolean trace;
/* */ protected ObjectName transactionManagerService;
/* */ protected PooledInvokerProxy optimizedInvokerProxy;
/* */ private MBeanServerAction serverAction;
/* */ protected static TransactionPropagationContextFactory tpcFactory;
/* */ protected static TransactionPropagationContextImporter tpcImporter;
/* */
/* */ public PooledInvoker()
/* */ {
/* 90 */ this.enableTcpNoDelay = false;
/* */
/* 95 */ this.serverBindAddress = null;
/* */
/* 100 */ this.serverBindPort = 0;
/* */
/* 105 */ this.clientConnectAddress = null;
/* */
/* 110 */ this.clientConnectPort = 0;
/* */
/* 114 */ this.clientRetryCount = 1;
/* */
/* 116 */ this.backlog = 200;
/* */
/* 130 */ this.serverSocket = null;
/* */
/* 135 */ this.timeout = 60000;
/* */
/* 137 */ this.maxPoolSize = 300;
/* */
/* 139 */ this.clientMaxPoolSize = 300;
/* */
/* 141 */ this.numAcceptThreads = 1;
/* */
/* 146 */ this.running = true;
/* */
/* 148 */ this.trace = false;
/* */
/* 155 */ this.optimizedInvokerProxy = null;
/* */
/* 157 */ this.serverAction = new MBeanServerAction();
/* */ }
/* */
/* */ protected void jmxBind()
/* */ {
/* 170 */ Registry.bind(getServiceName(), this.optimizedInvokerProxy);
/* */ }
/* */
/* */ public void startService()
/* */ throws Exception
/* */ {
/* 180 */ this.trace = log.isTraceEnabled();
/* */
/* 185 */ InitialContext ctx = new InitialContext();
/* */
/* 188 */ tpcFactory = TransactionPropagationContextUtil.getTPCFactory();
/* */
/* 191 */ tpcImporter = TransactionPropagationContextUtil.getTPCImporter();
/* */
/* 194 */ TransactionInterceptor.setTransactionManager((TransactionManager)ctx.lookup("java:/TransactionManager"));
/* */
/* 200 */ InetAddress bindAddress = (this.serverBindAddress == null) || (this.serverBindAddress.length() == 0) ? null : InetAddress.getByName(this.serverBindAddress);
/* */
/* 205 */ this.clientConnectAddress = ((this.clientConnectAddress == null) || (this.clientConnectAddress.length() == 0) ? InetAddress.getLocalHost().getHostName() : this.clientConnectAddress);
/* */
/* 213 */ this.clientConnectAddress = ServerConfigUtil.fixRemoteAddress(this.clientConnectAddress);
/* */
/* 216 */ loadCustomSocketFactories();
/* */
/* 218 */ this.clientpool = new LRUPool(2, this.maxPoolSize);
/* 219 */ this.clientpool.create();
/* 220 */ this.threadpool = new LinkedList();
/* */ try
/* */ {
/* 223 */ if (this.serverSocketFactory != null)
/* 224 */ this.serverSocket = this.serverSocketFactory.createServerSocket(this.serverBindPort, this.backlog, bindAddress);
/* */ else
/* 226 */ this.serverSocket = new ServerSocket(this.serverBindPort, this.backlog, bindAddress);
/* */ }
/* */ catch (BindException be)
/* */ {
/* 230 */ throw new Exception("Port " + this.serverBindPort + " is already in use", be);
/* */ }
/* 232 */ this.serverBindPort = this.serverSocket.getLocalPort();
/* 233 */ this.clientConnectPort = (this.clientConnectPort == 0 ? this.serverSocket.getLocalPort() : this.clientConnectPort);
/* */
/* 235 */ ServerAddress sa = new ServerAddress(this.clientConnectAddress, this.clientConnectPort, this.enableTcpNoDelay, this.timeout, this.clientSocketFactory);
/* */
/* 237 */ this.optimizedInvokerProxy = new PooledInvokerProxy(sa, this.clientMaxPoolSize, this.clientRetryCount);
/* */
/* 243 */ jmxBind();
/* 244 */ log.debug("Bound invoker for JMX node");
/* 245 */ ctx.close();
/* */
/* 247 */ this.acceptThreads = new Thread[this.numAcceptThreads];
/* 248 */ for (int i = 0; i < this.numAcceptThreads; i++)
/* */ {
/* 250 */ String name = "PooledInvokerAcceptor#" + i + "-" + this.serverBindPort;
/* 251 */ this.acceptThreads[i] = new Thread(this, name);
/* 252 */ this.acceptThreads[i].start();
/* */ }
/* */ }
/* */
/* */ public void run()
/* */ {
/* 258 */ while (this.running)
/* */ {
/* */ try
/* */ {
/* 262 */ Socket socket = this.serverSocket.accept();
/* 263 */ if (this.trace)
/* 264 */ log.trace("Accepted: " + socket);
/* 265 */ ServerThread thread = null;
/* 266 */ boolean newThread = false;
/* */
/* 268 */ while (thread == null)
/* */ {
/* 270 */ synchronized (this.threadpool)
/* */ {
/* 272 */ if (this.threadpool.size() > 0)
/* */ {
/* 274 */ thread = (ServerThread)this.threadpool.removeFirst();
/* */ }
/* */ }
/* 277 */ if (thread != null)
/* */ continue;
/* 279 */ synchronized (this.clientpool)
/* */ {
/* 281 */ if (this.clientpool.size() < this.maxPoolSize)
/* */ {
/* 283 */ thread = new ServerThread(socket, this, this.clientpool, this.threadpool, this.timeout);
/* 284 */ newThread = true;
/* */ }
/* 286 */ if (thread == null)
/* */ {
/* 288 */ this.clientpool.evict();
/* 289 */ if (this.trace)
/* 290 */ log.trace("Waiting for a thread...");
/* 291 */ this.clientpool.wait();
/* 292 */ if (this.trace) {
/* 293 */ log.trace("Notified of available thread");
/* */ }
/* */ }
/* */ }
/* */ }
/* 298 */ synchronized (this.clientpool)
/* */ {
/* 300 */ this.clientpool.insert(thread, thread);
/* */ }
/* */
/* 303 */ if (newThread)
/* */ {
/* 305 */ if (this.trace)
/* 306 */ log.trace("Created a new thread, t=" + thread);
/* 307 */ thread.start();
/* */ }
/* */ else
/* */ {
/* 311 */ if (this.trace)
/* 312 */ log.trace("Reusing thread t=" + thread);
/* 313 */ thread.wakeup(socket, this.timeout);
/* */ }
/* */ }
/* */ catch (Throwable ex)
/* */ {
/* 318 */ if (this.running)
/* 319 */ log.error("Failed to accept socket connection", ex);
/* */ }
/* */ }
/* */ }
/* */
/* */ public void stopService()
/* */ throws Exception
/* */ {
/* 329 */ this.running = false;
/* 330 */ this.maxPoolSize = 0;
/* 331 */ for (int i = 0; i < this.acceptThreads.length; i++)
/* */ {
/* */ try
/* */ {
/* 335 */ this.acceptThreads[i].interrupt();
/* */ } catch (Exception ignored) {
/* */ }
/* */ }
/* 339 */ this.clientpool.flush();
/* 340 */ for (int i = 0; i < this.threadpool.size(); i++)
/* */ {
/* 342 */ ServerThread thread = (ServerThread)this.threadpool.removeFirst();
/* 343 */ thread.shutdown();
/* */ }
/* */
/* */ try
/* */ {
/* 348 */ this.serverSocket.close();
/* */ }
/* */ catch (Exception e)
/* */ {
/* */ }
/* */ }
/* */
/* */ protected void destroyService()
/* */ throws Exception
/* */ {
/* 358 */ Registry.unbind(getServiceName());
/* */ }
/* */
/* */ public Object invoke(Invocation invocation)
/* */ throws Exception
/* */ {
/* 367 */ Thread currentThread = Thread.currentThread();
/* 368 */ ClassLoader oldCl = currentThread.getContextClassLoader();
/* */ try
/* */ {
/* 373 */ PooledMarshalledInvocation mi = (PooledMarshalledInvocation)invocation;
/* 374 */ invocation.setTransaction(importTPC(mi.getTransactionPropagationContext()));
/* 375 */ ObjectName mbean = (ObjectName)Registry.lookup(invocation.getObjectName());
/* 376 */ if (mbean == null)
/* */ {
/* 378 */ System.err.println("NoSuchObjectException: " + invocation.getObjectName());
/* 379 */ throw new NoSuchObjectException("Failed to find target for objectName: " + invocation.getObjectName());
/* */ }
/* */
/* 383 */ Object obj = this.serverAction.invoke(mbean, "invoke", new Object[] { invocation }, Invocation.INVOKE_SIGNATURE);
/* */
/* 386 */ localObject1 = obj;
/* */ }
/* */ catch (Exception e)
/* */ {
/* */ Object localObject1;
/* 390 */ JMXExceptionDecoder.rethrow(e);
/* */
/* 393 */ throw new UnreachableStatementException();
/* */ }
/* */ finally
/* */ {
/* 397 */ currentThread.setContextClassLoader(oldCl);
/* */ }
/* */ }
/* */
/* */ protected Transaction importTPC(Object tpc)
/* */ {
/* 403 */ if (tpc != null)
/* 404 */ return tpcImporter.importTransactionPropagationContext(tpc);
/* 405 */ return null;
/* */ }
/* */
/* */ public int getNumAcceptThreads()
/* */ {
/* 418 */ return this.numAcceptThreads;
/* */ }
/* */
/* */ public void setNumAcceptThreads(int size)
/* */ {
/* 429 */ this.numAcceptThreads = size;
/* */ }
/* */
/* */ public int getMaxPoolSize()
/* */ {
/* 440 */ return this.maxPoolSize;
/* */ }
/* */
/* */ public void setMaxPoolSize(int maxPoolSize)
/* */ {
/* 451 */ this.maxPoolSize = maxPoolSize;
/* */ }
/* */
/* */ public int getClientMaxPoolSize()
/* */ {
/* 462 */ return this.clientMaxPoolSize;
/* */ }
/* */
/* */ public void setClientMaxPoolSize(int clientMaxPoolSize)
/* */ {
/* 473 */ this.clientMaxPoolSize = clientMaxPoolSize;
/* */ }
/* */
/* */ public int getSocketTimeout()
/* */ {
/* 484 */ return this.timeout;
/* */ }
/* */
/* */ public void setSocketTimeout(int time)
/* */ {
/* 495 */ this.timeout = time;
/* */ }
/* */
/* */ public int getCurrentClientPoolSize()
/* */ {
/* 505 */ return this.clientpool.size();
/* */ }
/* */
/* */ public int getCurrentThreadPoolSize()
/* */ {
/* 515 */ return this.threadpool.size();
/* */ }
/* */
/* */ public int getServerBindPort()
/* */ {
/* 526 */ return this.serverBindPort;
/* */ }
/* */
/* */ public void setServerBindPort(int serverBindPort)
/* */ {
/* 537 */ this.serverBindPort = serverBindPort;
/* */ }
/* */
/* */ public String getClientConnectAddress()
/* */ {
/* 545 */ return this.clientConnectAddress;
/* */ }
/* */
/* */ public void setClientConnectAddress(String clientConnectAddress)
/* */ {
/* 553 */ this.clientConnectAddress = clientConnectAddress;
/* */ }
/* */
/* */ public int getClientConnectPort()
/* */ {
/* 561 */ return this.clientConnectPort;
/* */ }
/* */
/* */ public void setClientConnectPort(int clientConnectPort)
/* */ {
/* 569 */ this.clientConnectPort = clientConnectPort;
/* */ }
/* */
/* */ public int getClientRetryCount()
/* */ {
/* 577 */ return this.clientRetryCount;
/* */ }
/* */
/* */ public void setClientRetryCount(int clientRetryCount)
/* */ {
/* 585 */ this.clientRetryCount = clientRetryCount;
/* */ }
/* */
/* */ public int getBacklog()
/* */ {
/* 593 */ return this.backlog;
/* */ }
/* */
/* */ public void setBacklog(int backlog)
/* */ {
/* 601 */ this.backlog = backlog;
/* */ }
/* */
/* */ public boolean isEnableTcpNoDelay()
/* */ {
/* 609 */ return this.enableTcpNoDelay;
/* */ }
/* */
/* */ public void setEnableTcpNoDelay(boolean enableTcpNoDelay)
/* */ {
/* 617 */ this.enableTcpNoDelay = enableTcpNoDelay;
/* */ }
/* */
/* */ public String getServerBindAddress()
/* */ {
/* 625 */ return this.serverBindAddress;
/* */ }
/* */
/* */ public void setServerBindAddress(String serverBindAddress)
/* */ {
/* 633 */ this.serverBindAddress = serverBindAddress;
/* */ }
/* */
/* */ public String getClientSocketFactoryName()
/* */ {
/* 641 */ return this.clientSocketFactoryName;
/* */ }
/* */
/* */ public void setClientSocketFactoryName(String clientSocketFactoryName)
/* */ {
/* 649 */ this.clientSocketFactoryName = clientSocketFactoryName;
/* */ }
/* */
/* */ public String getServerSocketFactoryName()
/* */ {
/* 657 */ return this.serverSocketFactoryName;
/* */ }
/* */
/* */ public void setServerSocketFactoryName(String serverSocketFactoryName)
/* */ {
/* 665 */ this.serverSocketFactoryName = serverSocketFactoryName;
/* */ }
/* */
/* */ public SocketFactory getClientSocketFactory()
/* */ {
/* 673 */ return this.clientSocketFactory;
/* */ }
/* */
/* */ public void setClientSocketFactory(SocketFactory clientSocketFactory)
/* */ {
/* 681 */ this.clientSocketFactory = clientSocketFactory;
/* */ }
/* */
/* */ public ServerSocket getServerSocket()
/* */ {
/* 689 */ return this.serverSocket;
/* */ }
/* */
/* */ public void setServerSocket(ServerSocket serverSocket)
/* */ {
/* 697 */ this.serverSocket = serverSocket;
/* */ }
/* */
/* */ public String getSslDomain()
/* */ {
/* 705 */ return this.sslDomain;
/* */ }
/* */
/* */ public void setSslDomain(String sslDomain)
/* */ {
/* 713 */ this.sslDomain = sslDomain;
/* */ }
/* */
/* */ public ServerSocketFactory getServerSocketFactory()
/* */ {
/* 721 */ return this.serverSocketFactory;
/* */ }
/* */
/* */ public void setServerSocketFactory(ServerSocketFactory serverSocketFactory)
/* */ {
/* 729 */ this.serverSocketFactory = serverSocketFactory;
/* */ }
/* */
/* */ public ObjectName getTransactionManagerService()
/* */ {
/* 741 */ return this.transactionManagerService;
/* */ }
/* */
/* */ public void setTransactionManagerService(ObjectName transactionManagerService)
/* */ {
/* 753 */ this.transactionManagerService = transactionManagerService;
/* */ }
/* */
/* */ public PooledInvokerProxy getOptimizedInvokerProxy()
/* */ {
/* 761 */ return this.optimizedInvokerProxy;
/* */ }
/* */
/* */ protected void loadCustomSocketFactories()
/* */ {
/* 770 */ ClassLoader loader = Thread.currentThread().getContextClassLoader();
/* */ try
/* */ {
/* 774 */ if (this.clientSocketFactoryName != null)
/* */ {
/* 776 */ Class csfClass = loader.loadClass(this.clientSocketFactoryName);
/* 777 */ this.clientSocketFactory = ((SocketFactory)csfClass.newInstance());
/* */ }
/* */ }
/* */ catch (Exception e)
/* */ {
/* 782 */ log.error("Failed to load client socket factory", e);
/* 783 */ this.clientSocketFactory = null;
/* */ }
/* */
/* */ try
/* */ {
/* 788 */ if (this.serverSocketFactory == null)
/* */ {
/* 790 */ if (this.serverSocketFactoryName != null)
/* */ {
/* 792 */ Class ssfClass = loader.loadClass(this.serverSocketFactoryName);
/* 793 */ this.serverSocketFactory = ((ServerSocketFactory)ssfClass.newInstance());
/* 794 */ if (this.serverBindAddress != null)
/* */ {
/* */ try
/* */ {
/* 799 */ Class[] parameterTypes = { String.class };
/* 800 */ Method m = ssfClass.getMethod("setBindAddress", parameterTypes);
/* 801 */ Object[] args = { this.serverBindAddress };
/* 802 */ m.invoke(this.serverSocketFactory, args);
/* */ }
/* */ catch (NoSuchMethodException e)
/* */ {
/* 806 */ log.warn("Socket factory does not support setBindAddress(String)");
/* */ }
/* */ catch (Exception e)
/* */ {
/* 811 */ log.warn("Failed to setBindAddress=" + this.serverBindAddress + " on socket factory", e);
/* */ }
/* */
/* */ }
/* */
/* 818 */ if (this.sslDomain != null)
/* */ {
/* */ try
/* */ {
/* 822 */ InitialContext ctx = new InitialContext();
/* 823 */ SecurityDomain domain = (SecurityDomain)ctx.lookup(this.sslDomain);
/* 824 */ Class[] parameterTypes = { SecurityDomain.class };
/* 825 */ Method m = ssfClass.getMethod("setSecurityDomain", parameterTypes);
/* 826 */ Object[] args = { domain };
/* 827 */ m.invoke(this.serverSocketFactory, args);
/* */ }
/* */ catch (NoSuchMethodException e)
/* */ {
/* 831 */ log.error("Socket factory does not support setSecurityDomain(SecurityDomain)");
/* */ }
/* */ catch (Exception e)
/* */ {
/* 835 */ log.error("Failed to setSecurityDomain=" + this.sslDomain + " on socket factory", e);
/* */ }
/* */ }
/* */
/* */ }
/* 840 */ else if (this.serverBindAddress != null)
/* */ {
/* 842 */ DefaultSocketFactory defaultFactory = new DefaultSocketFactory(this.backlog);
/* 843 */ this.serverSocketFactory = defaultFactory;
/* */ try
/* */ {
/* 846 */ defaultFactory.setBindAddress(this.serverBindAddress);
/* */ }
/* */ catch (UnknownHostException e)
/* */ {
/* 850 */ log.error("Failed to setBindAddress=" + this.serverBindAddress + " on socket factory", e);
/* */ }
/* */ }
/* */ }
/* */ }
/* */ catch (Exception e)
/* */ {
/* 857 */ log.error("operation failed", e);
/* 858 */ this.serverSocketFactory = null;
/* */ }
/* */ }
/* */
/* */ class MBeanServerAction implements PrivilegedExceptionAction
/* */ {
/* */ private ObjectName target;
/* */ String method;
/* */ Object[] args;
/* */ String[] sig;
/* */
/* */ MBeanServerAction() {
/* */ }
/* */
/* */ MBeanServerAction(ObjectName target, String method, Object[] args, String[] sig) {
/* 877 */ this.target = target;
/* 878 */ this.method = method;
/* 879 */ this.args = args;
/* 880 */ this.sig = sig;
/* */ }
/* */
/* */ public Object run() throws Exception
/* */ {
/* 885 */ Object rtnValue = PooledInvoker.this.server.invoke(this.target, this.method, this.args, this.sig);
/* 886 */ return rtnValue;
/* */ }
/* */
/* */ Object invoke(ObjectName target, String method, Object[] args, String[] sig) throws Exception
/* */ {
/* 891 */ SecurityManager sm = System.getSecurityManager();
/* 892 */ Object rtnValue = null;
/* 893 */ if (sm == null)
/* */ {
/* 896 */ rtnValue = PooledInvoker.this.server.invoke(target, method, args, sig);
/* */ }
/* */ else
/* */ {
/* */ try
/* */ {
/* 903 */ MBeanServerAction action = new MBeanServerAction(PooledInvoker.this, target, method, args, sig);
/* 904 */ rtnValue = AccessController.doPrivileged(action);
/* */ }
/* */ catch (PrivilegedActionException e)
/* */ {
/* 908 */ Exception ex = e.getException();
/* 909 */ throw ex;
/* */ }
/* */ }
/* 912 */ return rtnValue;
/* */ }
/* */ }
/* */ }
/* Location: /home/mnovotny/projects/EMBEDDED_JBOSS_BETA3_COMMUNITY/embedded/output/lib/embedded-jboss/lib/jboss-embedded-all.jar
* Qualified Name: org.jboss.invocation.pooled.server.PooledInvoker
* JD-Core Version: 0.6.0
*/