GEODE-3023: TcpServer move soTimout for the socket for SSL Locators

Project: http://git-wip-us.apache.org/repos/asf/geode/repo
Commit: http://git-wip-us.apache.org/repos/asf/geode/commit/214cd732
Tree: http://git-wip-us.apache.org/repos/asf/geode/tree/214cd732
Diff: http://git-wip-us.apache.org/repos/asf/geode/diff/214cd732

Branch: refs/heads/feature/GEM-1483
Commit: 214cd732d17b20252f8b52b24dedfa088ec3b245
Parents: 76784eb
Author: Udo Kohlmeyer <ukohlme...@pivotal.io>
Authored: Fri Jun 9 15:06:14 2017 -0700
Committer: Udo Kohlmeyer <ukohlme...@pivotal.io>
Committed: Fri Jun 9 15:06:14 2017 -0700

----------------------------------------------------------------------
 .../internal/tcpserver/TcpServer.java           |  67 ++++----
 .../tcpserver/TCPServerSSLJUnitTest.java        | 167 +++++++++++++++++++
 .../internal/tcpserver/TcpServerJUnitTest.java  |  40 ++---
 .../geode/internal/net/DummySocketCreator.java  |  45 +++++
 4 files changed, 266 insertions(+), 53 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/geode/blob/214cd732/geode-core/src/main/java/org/apache/geode/distributed/internal/tcpserver/TcpServer.java
----------------------------------------------------------------------
diff --git 
a/geode-core/src/main/java/org/apache/geode/distributed/internal/tcpserver/TcpServer.java
 
b/geode-core/src/main/java/org/apache/geode/distributed/internal/tcpserver/TcpServer.java
index 86fe532..976f504 100755
--- 
a/geode-core/src/main/java/org/apache/geode/distributed/internal/tcpserver/TcpServer.java
+++ 
b/geode-core/src/main/java/org/apache/geode/distributed/internal/tcpserver/TcpServer.java
@@ -14,32 +14,6 @@
  */
 package org.apache.geode.distributed.internal.tcpserver;
 
-import java.io.DataInputStream;
-import java.io.DataOutputStream;
-import java.io.EOFException;
-import java.io.File;
-import java.io.IOException;
-import java.io.StreamCorruptedException;
-import java.net.InetAddress;
-import java.net.ServerSocket;
-import java.net.Socket;
-import java.net.SocketAddress;
-import java.net.URL;
-import java.util.Date;
-import java.util.HashMap;
-import java.util.Iterator;
-import java.util.Map;
-import java.util.Properties;
-import java.util.concurrent.SynchronousQueue;
-import java.util.concurrent.ThreadFactory;
-import java.util.concurrent.ThreadPoolExecutor;
-import java.util.concurrent.TimeUnit;
-import java.util.concurrent.atomic.AtomicInteger;
-
-import javax.net.ssl.SSLException;
-
-import org.apache.logging.log4j.Logger;
-
 import org.apache.geode.CancelException;
 import org.apache.geode.DataSerializer;
 import org.apache.geode.SystemFailure;
@@ -62,6 +36,31 @@ import org.apache.geode.internal.logging.LogService;
 import org.apache.geode.internal.net.SocketCreator;
 import org.apache.geode.internal.net.SocketCreatorFactory;
 import org.apache.geode.internal.security.SecurableCommunicationChannel;
+import org.apache.logging.log4j.Logger;
+
+import java.io.DataInputStream;
+import java.io.DataOutputStream;
+import java.io.EOFException;
+import java.io.File;
+import java.io.IOException;
+import java.io.StreamCorruptedException;
+import java.net.InetAddress;
+import java.net.ServerSocket;
+import java.net.Socket;
+import java.net.SocketAddress;
+import java.net.URL;
+import java.text.SimpleDateFormat;
+import java.util.Date;
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.Map;
+import java.util.Properties;
+import java.util.concurrent.SynchronousQueue;
+import java.util.concurrent.ThreadFactory;
+import java.util.concurrent.ThreadPoolExecutor;
+import java.util.concurrent.TimeUnit;
+import java.util.concurrent.atomic.AtomicInteger;
+import javax.net.ssl.SSLException;
 
 /**
  * TCP server which listens on a port and delegates requests to a request 
handler. The server uses
@@ -128,7 +127,7 @@ public class TcpServer {
   private final String threadName;
   private volatile Thread serverThread;
 
-  private SocketCreator socketCreator;
+  protected SocketCreator socketCreator;
 
   /*
    * GemStoneAddition - Initialize versions map. Warning: This map must be 
compatible with all
@@ -164,13 +163,14 @@ public class TcpServer {
       }
       cfg = new DistributionConfigImpl(sslConfig);
     }
+  }
 
+  protected SocketCreator getSocketCreator() {
     if (this.socketCreator == null) {
       this.socketCreator =
           
SocketCreatorFactory.getSocketCreatorForComponent(SecurableCommunicationChannel.LOCATOR);
-    } else {
-      throw new RuntimeException("The socket Creator already exists");
     }
+    return socketCreator;
   }
 
   private static PooledExecutorWithDMStats createExecutor(PoolStatHelper 
poolHelper,
@@ -210,10 +210,10 @@ public class TcpServer {
   private void startServerThread() throws IOException {
     if (srv_sock == null || srv_sock.isClosed()) {
       if (bind_address == null) {
-        srv_sock = socketCreator.createServerSocket(port, BACKLOG);
+        srv_sock = getSocketCreator().createServerSocket(port, BACKLOG);
         bind_address = srv_sock.getInetAddress();
       } else {
-        srv_sock = socketCreator.createServerSocket(port, BACKLOG, 
bind_address);
+        srv_sock = getSocketCreator().createServerSocket(port, BACKLOG, 
bind_address);
       }
 
       if (log.isInfoEnabled()) {
@@ -340,8 +340,10 @@ public class TcpServer {
       DataInputStream input = null;
       Object request, response;
       try {
-        socketCreator.configureServerSSLSocket(sock);
+
         sock.setSoTimeout(READ_TIMEOUT);
+        getSocketCreator().configureServerSSLSocket(sock);
+
         try {
           input = new DataInputStream(sock.getInputStream());
         } catch (StreamCorruptedException e) {
@@ -351,7 +353,6 @@ public class TcpServer {
               + (sock.getInetAddress().getHostAddress() + ":" + 
sock.getPort()), e);
           return;
         }
-
         int gossipVersion = readGossipVersion(sock, input);
 
         short versionOrdinal;

http://git-wip-us.apache.org/repos/asf/geode/blob/214cd732/geode-core/src/test/java/org/apache/geode/distributed/internal/tcpserver/TCPServerSSLJUnitTest.java
----------------------------------------------------------------------
diff --git 
a/geode-core/src/test/java/org/apache/geode/distributed/internal/tcpserver/TCPServerSSLJUnitTest.java
 
b/geode-core/src/test/java/org/apache/geode/distributed/internal/tcpserver/TCPServerSSLJUnitTest.java
new file mode 100644
index 0000000..b3a0901
--- /dev/null
+++ 
b/geode-core/src/test/java/org/apache/geode/distributed/internal/tcpserver/TCPServerSSLJUnitTest.java
@@ -0,0 +1,167 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more 
contributor license
+ * agreements. See the NOTICE file distributed with this work for additional 
information regarding
+ * copyright ownership. The ASF licenses this file to You under the Apache 
License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance with the 
License. You may obtain a
+ * copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software 
distributed under the License
+ * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 
KIND, either express
+ * or implied. See the License for the specific language governing permissions 
and limitations under
+ * the License.
+ */
+package org.apache.geode.distributed.internal.tcpserver;
+
+import static org.apache.geode.distributed.ConfigurationProperties.SSL_CIPHERS;
+import static 
org.apache.geode.distributed.ConfigurationProperties.SSL_ENABLED_COMPONENTS;
+import static 
org.apache.geode.distributed.ConfigurationProperties.SSL_KEYSTORE;
+import static 
org.apache.geode.distributed.ConfigurationProperties.SSL_KEYSTORE_PASSWORD;
+import static 
org.apache.geode.distributed.ConfigurationProperties.SSL_KEYSTORE_TYPE;
+import static 
org.apache.geode.distributed.ConfigurationProperties.SSL_PROTOCOLS;
+import static 
org.apache.geode.distributed.ConfigurationProperties.SSL_TRUSTSTORE;
+import static 
org.apache.geode.distributed.ConfigurationProperties.SSL_TRUSTSTORE_PASSWORD;
+
+import org.apache.geode.distributed.internal.DistributionConfig;
+import org.apache.geode.distributed.internal.DistributionConfigImpl;
+import org.apache.geode.distributed.internal.PoolStatHelper;
+import org.apache.geode.internal.AvailablePort;
+import org.apache.geode.internal.admin.SSLConfig;
+import org.apache.geode.internal.net.DummySocketCreator;
+import org.apache.geode.internal.net.SSLConfigurationFactory;
+import org.apache.geode.internal.net.SocketCreator;
+import org.apache.geode.internal.net.SocketCreatorFactory;
+import org.apache.geode.internal.security.SecurableCommunicationChannel;
+import org.apache.geode.test.junit.categories.IntegrationTest;
+import org.apache.geode.test.junit.categories.MembershipTest;
+import org.apache.geode.util.test.TestUtil;
+import org.junit.After;
+import org.junit.Assert;
+import org.junit.Before;
+import org.junit.Rule;
+import org.junit.Test;
+import org.junit.contrib.java.lang.system.RestoreSystemProperties;
+import org.junit.experimental.categories.Category;
+import org.mockito.Mockito;
+
+import java.io.IOException;
+import java.net.InetAddress;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Properties;
+
+@Category({IntegrationTest.class, MembershipTest.class})
+public class TCPServerSSLJUnitTest {
+
+  private InetAddress localhost;
+  private int port;
+  private DummyTcpServer server;
+
+  @Rule
+  public RestoreSystemProperties restoreSystemProperties = new 
RestoreSystemProperties();
+  private final String expectedSocketTimeout = "2000";
+
+  @Before
+  public void setup() {
+    SocketCreatorFactory.setDistributionConfig(new DistributionConfigImpl(new 
Properties()));
+  }
+
+  @After
+  public void teardown() {
+    SocketCreatorFactory.close();
+  }
+
+  private void startTimeDelayedTcpServer(Properties sslProperties) throws 
IOException {
+    localhost = InetAddress.getLocalHost();
+    port = AvailablePort.getRandomAvailablePort(AvailablePort.SOCKET);
+
+    server =
+        new DummyTcpServer(port, localhost, sslProperties, null, 
Mockito.mock(TcpHandler.class),
+            Mockito.mock(PoolStatHelper.class), 
Thread.currentThread().getThreadGroup(),
+            "server thread");
+    server.start();
+  }
+
+  @Test
+  public void testSSLSocketTimeOut() throws IOException {
+    boolean caughtLocatorException = false;
+    try {
+
+      System.setProperty(DistributionConfig.GEMFIRE_PREFIX + 
"TcpServer.READ_TIMEOUT",
+          expectedSocketTimeout);
+      Properties sslProperties = getSSLConfigurationProperties();
+      startTimeDelayedTcpServer(sslProperties);
+
+      createTcpClientConnection();
+
+    } catch (LocatorCancelException e) {
+      // we catching the LocatorCancelException. Expected to have the 
exception thrown
+      caughtLocatorException = true;
+    }
+
+    Assert.assertTrue(caughtLocatorException);
+    List<Integer> recordedSocketsForSocketCreator = 
server.getRecordedSocketTimeouts();
+
+    Assert.assertEquals(1, recordedSocketsForSocketCreator.size());
+    for (Integer socketTimeOut : recordedSocketsForSocketCreator) {
+      Assert.assertEquals(Integer.parseInt(expectedSocketTimeout), 
socketTimeOut.intValue());
+    }
+  }
+
+  private Properties getSSLConfigurationProperties() {
+    Properties sslProperties = new Properties();
+    sslProperties.setProperty(SSL_ENABLED_COMPONENTS,
+        SecurableCommunicationChannel.LOCATOR.getConstant());
+    sslProperties.setProperty(SSL_KEYSTORE,
+        TestUtil.getResourcePath(getClass(), 
"/org/apache/geode/internal/net/multiKey.jks"));
+    sslProperties.setProperty(SSL_TRUSTSTORE,
+        TestUtil.getResourcePath(getClass(), 
"/org/apache/geode/internal/net/multiKeyTrust.jks"));
+    sslProperties.setProperty(SSL_KEYSTORE_PASSWORD, "password");
+    sslProperties.setProperty(SSL_TRUSTSTORE_PASSWORD, "password");
+    sslProperties.setProperty(SSL_KEYSTORE_TYPE, "JKS");
+    sslProperties.setProperty(SSL_CIPHERS, "any");
+    sslProperties.setProperty(SSL_PROTOCOLS, "any");
+    return sslProperties;
+  }
+
+  private void createTcpClientConnection() {
+    try {
+      new TcpClient().requestToServer(localhost, port, Boolean.valueOf(false), 
5 * 1000);
+    } catch (IOException e) {
+      e.printStackTrace();
+    } catch (ClassNotFoundException e) {
+      e.printStackTrace();
+    }
+  }
+
+  private class DummyTcpServer extends TcpServer {
+    private DistributionConfig distributionConfig;
+    private List<Integer> recordedSocketsTimeouts = new ArrayList<>();
+
+    public DummyTcpServer(int port, InetAddress bind_address, Properties 
sslConfig,
+                          DistributionConfigImpl cfg, TcpHandler handler, 
PoolStatHelper poolHelper,
+                          ThreadGroup threadGroup, String threadName) {
+      super(port, bind_address, sslConfig, cfg, handler, poolHelper, 
threadGroup, threadName);
+      if (cfg == null) {
+        cfg = new DistributionConfigImpl(sslConfig);
+      }
+      this.distributionConfig = cfg;
+    }
+
+    @Override
+    protected SocketCreator getSocketCreator() {
+      if (this.socketCreator == null) {
+        SSLConfigurationFactory.setDistributionConfig(distributionConfig);
+        SSLConfig sslConfig =
+            
SSLConfigurationFactory.getSSLConfigForComponent(SecurableCommunicationChannel.LOCATOR);
+        this.socketCreator = new DummySocketCreator(sslConfig, 
recordedSocketsTimeouts);
+      }
+      return socketCreator;
+    }
+
+    public List<Integer> getRecordedSocketTimeouts() {
+      return recordedSocketsTimeouts;
+    }
+  }
+}

http://git-wip-us.apache.org/repos/asf/geode/blob/214cd732/geode-core/src/test/java/org/apache/geode/distributed/internal/tcpserver/TcpServerJUnitTest.java
----------------------------------------------------------------------
diff --git 
a/geode-core/src/test/java/org/apache/geode/distributed/internal/tcpserver/TcpServerJUnitTest.java
 
b/geode-core/src/test/java/org/apache/geode/distributed/internal/tcpserver/TcpServerJUnitTest.java
index 7c7a2b3..eda0641 100644
--- 
a/geode-core/src/test/java/org/apache/geode/distributed/internal/tcpserver/TcpServerJUnitTest.java
+++ 
b/geode-core/src/test/java/org/apache/geode/distributed/internal/tcpserver/TcpServerJUnitTest.java
@@ -14,7 +14,25 @@
  */
 package org.apache.geode.distributed.internal.tcpserver;
 
-import static org.junit.Assert.*;
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertTrue;
+
+import org.apache.geode.DataSerializable;
+import org.apache.geode.cache.GemFireCache;
+import org.apache.geode.distributed.DistributedSystem;
+import org.apache.geode.distributed.internal.ClusterConfigurationService;
+import org.apache.geode.distributed.internal.DistributionConfigImpl;
+import org.apache.geode.distributed.internal.PoolStatHelper;
+import org.apache.geode.internal.AvailablePort;
+import org.apache.geode.internal.net.SocketCreatorFactory;
+import org.apache.geode.test.junit.categories.IntegrationTest;
+import org.apache.geode.test.junit.categories.MembershipTest;
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.experimental.categories.Category;
 
 import java.io.DataInput;
 import java.io.DataOutput;
@@ -27,22 +45,6 @@ import java.util.concurrent.TimeUnit;
 import java.util.concurrent.atomic.AtomicBoolean;
 import java.util.concurrent.atomic.AtomicInteger;
 
-import org.apache.geode.distributed.internal.ClusterConfigurationService;
-import org.apache.geode.test.junit.categories.MembershipTest;
-import org.junit.After;
-import org.junit.Before;
-import org.junit.Test;
-import org.junit.experimental.categories.Category;
-
-import org.apache.geode.DataSerializable;
-import org.apache.geode.cache.GemFireCache;
-import org.apache.geode.distributed.DistributedSystem;
-import org.apache.geode.distributed.internal.DistributionConfigImpl;
-import org.apache.geode.distributed.internal.PoolStatHelper;
-import org.apache.geode.internal.AvailablePort;
-import org.apache.geode.internal.net.SocketCreatorFactory;
-import org.apache.geode.test.junit.categories.IntegrationTest;
-
 @Category({IntegrationTest.class, MembershipTest.class})
 public class TcpServerJUnitTest {
 
@@ -205,10 +207,8 @@ public class TcpServerJUnitTest {
         } catch (InterruptedException e) {
           Thread.currentThread().interrupt();
         }
-        return delay;
-      } else {
-        return delay;
       }
+      return delay;
     }
 
     public void shutDown() {}

http://git-wip-us.apache.org/repos/asf/geode/blob/214cd732/geode-core/src/test/java/org/apache/geode/internal/net/DummySocketCreator.java
----------------------------------------------------------------------
diff --git 
a/geode-core/src/test/java/org/apache/geode/internal/net/DummySocketCreator.java
 
b/geode-core/src/test/java/org/apache/geode/internal/net/DummySocketCreator.java
new file mode 100644
index 0000000..2c5ff92
--- /dev/null
+++ 
b/geode-core/src/test/java/org/apache/geode/internal/net/DummySocketCreator.java
@@ -0,0 +1,45 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more 
contributor license
+ * agreements. See the NOTICE file distributed with this work for additional 
information regarding
+ * copyright ownership. The ASF licenses this file to You under the Apache 
License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance with the 
License. You may obtain a
+ * copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software 
distributed under the License
+ * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 
KIND, either express
+ * or implied. See the License for the specific language governing permissions 
and limitations under
+ * the License.
+ */
+package org.apache.geode.internal.net;
+
+import org.apache.geode.internal.admin.SSLConfig;
+
+import java.io.IOException;
+import java.net.Socket;
+import java.util.List;
+import javax.net.ssl.SSLException;
+
+public class DummySocketCreator extends SocketCreator {
+
+  private List<Integer> socketSoTimeouts;
+
+  /**
+   * Constructs new SocketCreator instance.
+   */
+  public DummySocketCreator(SSLConfig sslConfig, List<Integer> sockets) {
+    super(sslConfig);
+    this.socketSoTimeouts = sockets;
+  }
+
+  @Override
+  public void configureServerSSLSocket(Socket socket) throws IOException {
+    this.socketSoTimeouts.add(socket.getSoTimeout());
+    throw new SSLException("This is a test SSLException");
+  }
+
+  public List<Integer> getSocketSoTimeouts() {
+    return socketSoTimeouts;
+  }
+}

Reply via email to