Search in sources :

Example 6 with VersionedDataOutputStream

use of org.apache.geode.internal.VersionedDataOutputStream in project geode by apache.

the class TcpClient method requestToServer.

/**
   * Send a request to a Locator
   * 
   * @param ipAddr The locator's inet socket address
   * @param request The request message
   * @param timeout Timeout for sending the message and receiving a reply
   * @param replyExpected Whether to wait for a reply
   *
   * @return The reply, or null if no reply is expected
   *
   * @throws IOException
   * @throws ClassNotFoundException
   */
public Object requestToServer(InetSocketAddress ipAddr, Object request, int timeout, boolean replyExpected) throws IOException, ClassNotFoundException {
    /*
     * InetSocketAddress ipAddr; if (addr == null) { ipAddr = new InetSocketAddress(port); } else {
     * ipAddr = new InetSocketAddress(addr, port); // fix for bug 30810 }
     */
    long giveupTime = System.currentTimeMillis() + timeout;
    // Get the GemFire version of the TcpServer first, before sending any other request.
    short serverVersion = getServerVersion(ipAddr, timeout).shortValue();
    if (serverVersion > Version.CURRENT_ORDINAL) {
        serverVersion = Version.CURRENT_ORDINAL;
    }
    // establish the old GossipVersion for the server
    int gossipVersion = TcpServer.getCurrentGossipVersion();
    if (Version.GFE_71.compareTo(serverVersion) > 0) {
        gossipVersion = TcpServer.getOldGossipVersion();
    }
    long newTimeout = giveupTime - System.currentTimeMillis();
    if (newTimeout <= 0) {
        return null;
    }
    logger.debug("TcpClient sending {} to {}", request, ipAddr);
    Socket sock = socketCreator.connect(ipAddr.getAddress(), ipAddr.getPort(), (int) newTimeout, null, false);
    sock.setSoTimeout((int) newTimeout);
    DataOutputStream out = null;
    try {
        out = new DataOutputStream(sock.getOutputStream());
        if (serverVersion < Version.CURRENT_ORDINAL) {
            out = new VersionedDataOutputStream(out, Version.fromOrdinalNoThrow(serverVersion, false));
        }
        out.writeInt(gossipVersion);
        if (gossipVersion > TcpServer.getOldGossipVersion()) {
            out.writeShort(serverVersion);
        }
        DataSerializer.writeObject(request, out);
        out.flush();
        if (replyExpected) {
            DataInputStream in = new DataInputStream(sock.getInputStream());
            in = new VersionedDataInputStream(in, Version.fromOrdinal(serverVersion, false));
            try {
                Object response = DataSerializer.readObject(in);
                logger.debug("received response: {}", response);
                return response;
            } catch (EOFException ex) {
                EOFException eof = new EOFException("Locator at " + ipAddr + " did not respond. This is normal if the locator was shutdown. If it wasn't check its log for exceptions.");
                eof.initCause(ex);
                throw eof;
            }
        } else {
            return null;
        }
    } catch (UnsupportedVersionException ex) {
        if (logger.isDebugEnabled()) {
            logger.debug("Remote TcpServer version: " + serverVersion + " is higher than local version: " + Version.CURRENT_ORDINAL + ". This is never expected as remoteVersion");
        }
        return null;
    } finally {
        try {
            if (replyExpected) {
                // the locator's machine.
                if (!sock.isClosed() && !socketCreator.useSSL()) {
                    sock.setSoLinger(true, 0);
                }
            }
            sock.close();
        } catch (Exception e) {
            logger.error("Error closing socket ", e);
        }
        if (out != null) {
            out.close();
        }
    }
}
Also used : DataOutputStream(java.io.DataOutputStream) VersionedDataOutputStream(org.apache.geode.internal.VersionedDataOutputStream) VersionedDataOutputStream(org.apache.geode.internal.VersionedDataOutputStream) EOFException(java.io.EOFException) DataInputStream(java.io.DataInputStream) VersionedDataInputStream(org.apache.geode.internal.VersionedDataInputStream) Socket(java.net.Socket) VersionedDataInputStream(org.apache.geode.internal.VersionedDataInputStream) SSLHandshakeException(javax.net.ssl.SSLHandshakeException) IOException(java.io.IOException) EOFException(java.io.EOFException) SSLException(javax.net.ssl.SSLException) UnsupportedVersionException(org.apache.geode.cache.UnsupportedVersionException) UnsupportedVersionException(org.apache.geode.cache.UnsupportedVersionException)

Example 7 with VersionedDataOutputStream

use of org.apache.geode.internal.VersionedDataOutputStream in project geode by apache.

the class TcpServer method processRequest.

/**
   * fix for bug 33711 - client requests are spun off to another thread for processing. Requests are
   * synchronized in processGossip.
   */
private void processRequest(final Socket sock) {
    executor.execute(() -> {
        long startTime = DistributionStats.getStatTime();
        DataInputStream input = null;
        Object request, response;
        try {
            socketCreator.configureServerSSLSocket(sock);
            sock.setSoTimeout(READ_TIMEOUT);
            try {
                input = new DataInputStream(sock.getInputStream());
            } catch (StreamCorruptedException e) {
                // Some garbage can be left on the socket stream
                // if a peer disappears at exactly the wrong moment.
                log.debug("Discarding illegal request from " + (sock.getInetAddress().getHostAddress() + ":" + sock.getPort()), e);
                return;
            }
            int gossipVersion = readGossipVersion(sock, input);
            short versionOrdinal;
            if (gossipVersion <= getCurrentGossipVersion() && GOSSIP_TO_GEMFIRE_VERSION_MAP.containsKey(gossipVersion)) {
                // Create a versioned stream to remember sender's GemFire version
                versionOrdinal = (short) GOSSIP_TO_GEMFIRE_VERSION_MAP.get(gossipVersion);
            } else {
                // Close the socket. We can not accept requests from a newer version
                try {
                    sock.getOutputStream().write("unknown protocol version".getBytes());
                    sock.getOutputStream().flush();
                } catch (IOException e) {
                    log.debug("exception in sending reply to process using unknown protocol " + gossipVersion, e);
                }
                sock.close();
                return;
            }
            if (Version.GFE_71.compareTo(versionOrdinal) <= 0) {
                // Recent versions of TcpClient will send the version ordinal
                versionOrdinal = input.readShort();
            }
            if (log.isDebugEnabled() && versionOrdinal != Version.CURRENT_ORDINAL) {
                log.debug("Locator reading request from " + sock.getInetAddress() + " with version " + Version.fromOrdinal(versionOrdinal, false));
            }
            input = new VersionedDataInputStream(input, Version.fromOrdinal(versionOrdinal, false));
            request = DataSerializer.readObject(input);
            if (log.isDebugEnabled()) {
                log.debug("Locator received request " + request + " from " + sock.getInetAddress());
            }
            if (request instanceof ShutdownRequest) {
                shuttingDown = true;
                // Don't call shutdown from within the worker thread, see java bug #6576792.
                // Closing the socket will cause our acceptor thread to shutdown the executor
                this.serverSocketPortAtClose = srv_sock.getLocalPort();
                srv_sock.close();
                response = new ShutdownResponse();
            } else if (request instanceof InfoRequest) {
                response = handleInfoRequest(request);
            } else if (request instanceof VersionRequest) {
                response = handleVersionRequest(request);
            } else {
                response = handler.processRequest(request);
            }
            handler.endRequest(request, startTime);
            startTime = DistributionStats.getStatTime();
            if (response != null) {
                DataOutputStream output = new DataOutputStream(sock.getOutputStream());
                if (versionOrdinal != Version.CURRENT_ORDINAL) {
                    output = new VersionedDataOutputStream(output, Version.fromOrdinal(versionOrdinal, false));
                }
                DataSerializer.writeObject(response, output);
                output.flush();
            }
            handler.endResponse(request, startTime);
        } catch (EOFException ignore) {
        // client went away - ignore
        } catch (CancelException ignore) {
        // ignore
        } catch (ClassNotFoundException ex) {
            String sender = null;
            if (sock != null) {
                sender = sock.getInetAddress().getHostAddress();
            }
            log.info("Unable to process request from " + sender + " exception=" + ex.getMessage());
        } catch (Exception ex) {
            String sender = null;
            if (sock != null) {
                sender = sock.getInetAddress().getHostAddress();
            }
            if (ex instanceof IOException) {
                // log with severe.
                if (!sock.isClosed()) {
                    log.info("Exception in processing request from " + sender, ex);
                }
            } else {
                log.fatal("Exception in processing request from " + sender, ex);
            }
        } catch (VirtualMachineError err) {
            SystemFailure.initiateFailure(err);
            throw err;
        } catch (Throwable ex) {
            SystemFailure.checkFailure();
            String sender = null;
            if (sock != null) {
                sender = sock.getInetAddress().getHostAddress();
            }
            try {
                log.fatal("Exception in processing request from " + sender, ex);
            } catch (VirtualMachineError err) {
                SystemFailure.initiateFailure(err);
                throw err;
            } catch (Throwable t) {
                SystemFailure.checkFailure();
                t.printStackTrace();
            }
        } finally {
            try {
                sock.close();
            } catch (IOException ignore) {
            // ignore
            }
        }
    });
}
Also used : DataOutputStream(java.io.DataOutputStream) VersionedDataOutputStream(org.apache.geode.internal.VersionedDataOutputStream) IOException(java.io.IOException) DataInputStream(java.io.DataInputStream) VersionedDataInputStream(org.apache.geode.internal.VersionedDataInputStream) CancelException(org.apache.geode.CancelException) StreamCorruptedException(java.io.StreamCorruptedException) IOException(java.io.IOException) EOFException(java.io.EOFException) SSLException(javax.net.ssl.SSLException) VersionedDataOutputStream(org.apache.geode.internal.VersionedDataOutputStream) EOFException(java.io.EOFException) StreamCorruptedException(java.io.StreamCorruptedException) CancelException(org.apache.geode.CancelException) VersionedDataInputStream(org.apache.geode.internal.VersionedDataInputStream)

Example 8 with VersionedDataOutputStream

use of org.apache.geode.internal.VersionedDataOutputStream in project geode by apache.

the class OldClientSupportDUnitTest method testConversionOfArrayTypes.

@Test
public void testConversionOfArrayTypes() throws Exception {
    OldClientSupportService oldClientSupport = OldClientSupportProvider.getService(myCache);
    Version oldClientVersion = Version.GFE_82;
    VersionedDataOutputStream dout = new VersionedDataOutputStream(new HeapDataOutputStream(10, oldClientVersion), oldClientVersion);
    for (String geodeClassName : newArrayClassNames) {
        String newName = oldClientSupport.processOutgoingClassName(geodeClassName, dout);
        Assert.assertNotEquals(geodeClassName, newName);
    }
    for (String className : allNonconformingArrayClassNames) {
        String newName = oldClientSupport.processOutgoingClassName(className, dout);
        Assert.assertEquals(className, newName);
    }
    VersionedDataInputStream din = new VersionedDataInputStream(new DataInputStream(new ByteArrayInputStream(new byte[10])), oldClientVersion);
    for (String oldClassName : oldArrayClassNames) {
        String newName = oldClientSupport.processIncomingClassName(oldClassName, din);
        Assert.assertNotEquals(oldClassName, newName);
    }
}
Also used : Version(org.apache.geode.internal.Version) ByteArrayInputStream(java.io.ByteArrayInputStream) HeapDataOutputStream(org.apache.geode.internal.HeapDataOutputStream) VersionedDataOutputStream(org.apache.geode.internal.VersionedDataOutputStream) OldClientSupportService(org.apache.geode.internal.cache.tier.sockets.OldClientSupportService) DataInputStream(java.io.DataInputStream) VersionedDataInputStream(org.apache.geode.internal.VersionedDataInputStream) VersionedDataInputStream(org.apache.geode.internal.VersionedDataInputStream) Test(org.junit.Test) DistributedTest(org.apache.geode.test.junit.categories.DistributedTest)

Aggregations

VersionedDataOutputStream (org.apache.geode.internal.VersionedDataOutputStream)8 DataInputStream (java.io.DataInputStream)6 VersionedDataInputStream (org.apache.geode.internal.VersionedDataInputStream)6 DataOutputStream (java.io.DataOutputStream)5 IOException (java.io.IOException)4 EOFException (java.io.EOFException)3 SSLException (javax.net.ssl.SSLException)3 UnsupportedVersionException (org.apache.geode.cache.UnsupportedVersionException)3 HeapDataOutputStream (org.apache.geode.internal.HeapDataOutputStream)3 Version (org.apache.geode.internal.Version)3 Socket (java.net.Socket)2 SSLHandshakeException (javax.net.ssl.SSLHandshakeException)2 CancelException (org.apache.geode.CancelException)2 ByteArrayInputStream (java.io.ByteArrayInputStream)1 DataOutput (java.io.DataOutput)1 InputStream (java.io.InputStream)1 StreamCorruptedException (java.io.StreamCorruptedException)1 SocketAddress (java.net.SocketAddress)1 CacheException (org.apache.geode.cache.CacheException)1 RegionDestroyedException (org.apache.geode.cache.RegionDestroyedException)1