Search in sources :

Example 1 with RMISocketFactory

use of java.rmi.server.RMISocketFactory in project jdk8u_jdk by JetBrains.

the class RMIMasterSocketFactory method createSocket.

/**
     * Create a new client socket.  If we remember connecting to this host
     * successfully before, then use the same factory again.  Otherwise,
     * try using a direct socket connection and then the alternate factories
     * in the order specified in altFactoryList.
     */
public Socket createSocket(String host, int port) throws IOException {
    if (proxyLog.isLoggable(Log.BRIEF)) {
        proxyLog.log(Log.BRIEF, "host: " + host + ", port: " + port);
    }
    /*
         * If we don't have any alternate factories to consult, short circuit
         * the fallback procedure and delegate to the initial factory.
         */
    if (altFactoryList.size() == 0) {
        return initialFactory.createSocket(host, port);
    }
    RMISocketFactory factory;
    /*
         * If we remember successfully connecting to this host before,
         * use the same factory.
         */
    factory = successTable.get(host);
    if (factory != null) {
        if (proxyLog.isLoggable(Log.BRIEF)) {
            proxyLog.log(Log.BRIEF, "previously successful factory found: " + factory);
        }
        return factory.createSocket(host, port);
    }
    /*
         * Next, try a direct socket connection.  Open socket in another
         * thread and only wait for specified timeout, in case the socket
         * would otherwise spend minutes trying an unreachable host.
         */
    Socket initialSocket = null;
    Socket fallbackSocket = null;
    final AsyncConnector connector = new AsyncConnector(initialFactory, host, port, AccessController.getContext());
    // connection must be attempted with
    // this thread's access control context
    IOException initialFailure = null;
    try {
        synchronized (connector) {
            Thread t = java.security.AccessController.doPrivileged(new NewThreadAction(connector, "AsyncConnector", true));
            t.start();
            try {
                long now = System.currentTimeMillis();
                long deadline = now + connectTimeout;
                do {
                    connector.wait(deadline - now);
                    initialSocket = checkConnector(connector);
                    if (initialSocket != null)
                        break;
                    now = System.currentTimeMillis();
                } while (now < deadline);
            } catch (InterruptedException e) {
                throw new InterruptedIOException("interrupted while waiting for connector");
            }
        }
        // assume no route to host (for now) if no connection yet
        if (initialSocket == null)
            throw new NoRouteToHostException("connect timed out: " + host);
        proxyLog.log(Log.BRIEF, "direct socket connection successful");
        return initialSocket;
    } catch (UnknownHostException | NoRouteToHostException e) {
        initialFailure = e;
    } catch (SocketException e) {
        if (eagerHttpFallback) {
            initialFailure = e;
        } else {
            throw e;
        }
    } finally {
        if (initialFailure != null) {
            if (proxyLog.isLoggable(Log.BRIEF)) {
                proxyLog.log(Log.BRIEF, "direct socket connection failed: ", initialFailure);
            }
            // Finally, try any alternate connection mechanisms.
            for (int i = 0; i < altFactoryList.size(); ++i) {
                factory = altFactoryList.elementAt(i);
                if (proxyLog.isLoggable(Log.BRIEF)) {
                    proxyLog.log(Log.BRIEF, "trying with factory: " + factory);
                }
                try (Socket testSocket = factory.createSocket(host, port)) {
                    // For HTTP connections, the output (POST request) must
                    // be sent before we verify a successful connection.
                    // So, sacrifice a socket for the sake of testing...
                    // The following sequence should verify a successful
                    // HTTP connection if no IOException is thrown.
                    InputStream in = testSocket.getInputStream();
                    // probably -1 for EOF...
                    int b = in.read();
                } catch (IOException ex) {
                    if (proxyLog.isLoggable(Log.BRIEF)) {
                        proxyLog.log(Log.BRIEF, "factory failed: ", ex);
                    }
                    continue;
                }
                proxyLog.log(Log.BRIEF, "factory succeeded");
                // factory succeeded, open new socket for caller's use
                try {
                    fallbackSocket = factory.createSocket(host, port);
                } catch (IOException ex) {
                // if it fails 2nd time,
                }
                // just give up
                break;
            }
        }
    }
    synchronized (successTable) {
        try {
            // check once again to see if direct connection succeeded
            synchronized (connector) {
                initialSocket = checkConnector(connector);
            }
            if (initialSocket != null) {
                // if we had made another one as well, clean it up...
                if (fallbackSocket != null)
                    fallbackSocket.close();
                return initialSocket;
            }
            // if connector ever does get socket, it won't be used
            connector.notUsed();
        } catch (UnknownHostException | NoRouteToHostException e) {
            initialFailure = e;
        } catch (SocketException e) {
            if (eagerHttpFallback) {
                initialFailure = e;
            } else {
                throw e;
            }
        }
        // if we had found an alternate mechanism, go and use it
        if (fallbackSocket != null) {
            // remember this successful host/factory pair
            rememberFactory(host, factory);
            return fallbackSocket;
        }
        throw initialFailure;
    }
}
Also used : RMISocketFactory(java.rmi.server.RMISocketFactory) NewThreadAction(sun.rmi.runtime.NewThreadAction)

Example 2 with RMISocketFactory

use of java.rmi.server.RMISocketFactory in project opennms by OpenNMS.

the class JmxRemoteAdminIT method canConnect.

@Test
public void canConnect() throws Exception {
    final InetSocketAddress addr = m_testEnvironment.getServiceAddress(ContainerAlias.OPENNMS, 18980);
    final String hostString = "localhost".equals(addr.getHostString()) ? "127.0.0.1" : addr.getHostString();
    final int port = addr.getPort();
    final RMISocketFactory socketFactory = new JMXTestClientSocketFactory();
    System.setProperty("sun.rmi.transport.tcp.responseTimeout", "5000");
    final Callable<Integer> getRmiConnection = new Callable<Integer>() {

        @Override
        public Integer call() throws Exception {
            LOG.debug("getRmiConnection({}:{})", hostString, port);
            try {
                final Registry registry = LocateRegistry.getRegistry(hostString, port, socketFactory);
                final String[] bound = registry.list();
                LOG.debug("bound={}", Arrays.asList(bound));
                if (bound.length > 0) {
                    return bound.length;
                }
            } catch (final Exception e) {
            }
            return null;
        }
    };
    await().atMost(5, MINUTES).pollInterval(10, SECONDS).until(getRmiConnection, greaterThanOrEqualTo(1));
    final Callable<Integer> getJmxConnection = new Callable<Integer>() {

        @Override
        public Integer call() throws Exception {
            LOG.debug("getJmxConnection({}:{})", hostString, port);
            try {
                RMISocketFactory.setSocketFactory(socketFactory);
                final Map<String, Object> env = new HashMap<>();
                final String[] credentials = { "admin", "admin" };
                env.put(JMXConnector.CREDENTIALS, credentials);
                env.put(RMIConnectorServer.RMI_CLIENT_SOCKET_FACTORY_ATTRIBUTE, socketFactory);
                final String urlString = String.format("service:jmx:rmi:///jndi/rmi://%s:%d/jmxrmi", hostString, port);
                LOG.debug("getJmxConnection(): connecting to {}", urlString);
                final JMXServiceURL url = new JMXServiceURL(urlString);
                final JMXConnector jmxc = JMXConnectorFactory.connect(url, env);
                final MBeanServerConnection mbsc = jmxc.getMBeanServerConnection();
                LOG.debug("mbeanCount={}", mbsc.getMBeanCount());
                if (mbsc.getMBeanCount() > 0) {
                    return mbsc.getMBeanCount();
                }
            } catch (final Exception e) {
            }
            return null;
        }
    };
    await().atMost(5, MINUTES).pollInterval(10, SECONDS).until(getJmxConnection, greaterThanOrEqualTo(1));
}
Also used : JMXServiceURL(javax.management.remote.JMXServiceURL) HashMap(java.util.HashMap) InetSocketAddress(java.net.InetSocketAddress) Registry(java.rmi.registry.Registry) LocateRegistry(java.rmi.registry.LocateRegistry) RMISocketFactory(java.rmi.server.RMISocketFactory) Callable(java.util.concurrent.Callable) IOException(java.io.IOException) JMXConnector(javax.management.remote.JMXConnector) MBeanServerConnection(javax.management.MBeanServerConnection) Test(org.junit.Test)

Aggregations

RMISocketFactory (java.rmi.server.RMISocketFactory)2 IOException (java.io.IOException)1 InetSocketAddress (java.net.InetSocketAddress)1 LocateRegistry (java.rmi.registry.LocateRegistry)1 Registry (java.rmi.registry.Registry)1 HashMap (java.util.HashMap)1 Callable (java.util.concurrent.Callable)1 MBeanServerConnection (javax.management.MBeanServerConnection)1 JMXConnector (javax.management.remote.JMXConnector)1 JMXServiceURL (javax.management.remote.JMXServiceURL)1 Test (org.junit.Test)1 NewThreadAction (sun.rmi.runtime.NewThreadAction)1