Added change to change InetAddress when there is IOException

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

Branch: refs/heads/feature/GEODE-2804v3
Commit: 3a46b791f5d6f542893e6a708edbe48814aa5913
Parents: 718583b
Author: Hitesh Khamesra <hkhame...@pivotal.io>
Authored: Tue Jun 13 15:56:33 2017 -0700
Committer: Hitesh Khamesra <hkhame...@pivotal.io>
Committed: Tue Jun 27 12:53:07 2017 -0700

----------------------------------------------------------------------
 .../internal/AutoConnectionSourceImpl.java      | 72 ++++++++++++++++++--
 .../membership/gms/membership/GMSJoinLeave.java |  3 +-
 .../internal/tcpserver/TcpClient.java           | 27 +++++++-
 .../internal/JmxManagerLocatorRequest.java      |  5 +-
 .../cli/commands/LauncherLifecycleCommands.java |  1 +
 .../AutoConnectionSourceImplJUnitTest.java      | 64 +++++++++++++++++
 6 files changed, 162 insertions(+), 10 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/geode/blob/3a46b791/geode-core/src/main/java/org/apache/geode/cache/client/internal/AutoConnectionSourceImpl.java
----------------------------------------------------------------------
diff --git 
a/geode-core/src/main/java/org/apache/geode/cache/client/internal/AutoConnectionSourceImpl.java
 
b/geode-core/src/main/java/org/apache/geode/cache/client/internal/AutoConnectionSourceImpl.java
index 53d401a..070451c 100644
--- 
a/geode-core/src/main/java/org/apache/geode/cache/client/internal/AutoConnectionSourceImpl.java
+++ 
b/geode-core/src/main/java/org/apache/geode/cache/client/internal/AutoConnectionSourceImpl.java
@@ -204,12 +204,10 @@ public class AutoConnectionSourceImpl implements 
ConnectionSource {
 
   private ServerLocationResponse queryOneLocator(InetSocketAddress locator,
       ServerLocationRequest request) {
-    InetAddress addr = locator.getAddress();
-    int port = locator.getPort();
     Object returnObj = null;
     try {
       pool.getStats().incLocatorRequests();
-      returnObj = tcpClient.requestToServer(addr, port, request, 
connectionTimeout);
+      returnObj = tcpClient.requestToServer(locator, request, 
connectionTimeout, true);
       ServerLocationResponse response = (ServerLocationResponse) returnObj;
       pool.getStats().incLocatorResponses();
       if (response != null) {
@@ -218,6 +216,7 @@ public class AutoConnectionSourceImpl implements 
ConnectionSource {
       return response;
     } catch (IOException ioe) {
       reportDeadLocator(locator, ioe);
+      updateLocatorInLocatorList(locator);
       return null;
     } catch (ClassNotFoundException e) {
       logger.warn(
@@ -234,6 +233,45 @@ public class AutoConnectionSourceImpl implements 
ConnectionSource {
     }
   }
 
+  /**
+   * If connecting to the locator fails with an IOException, this may be 
because the locator's IP
+   * has changed. Add the locator back to the list of locators using host 
address rather than IP.
+   * This will cause another DNS lookup, hopefully finding the locator.
+   * 
+   * @param locator
+   */
+  protected void updateLocatorInLocatorList(InetSocketAddress locator) {
+    if (locator.getHostName() != null) {
+      LocatorList locatorList = locators.get();
+      List<InetSocketAddress> newLocatorsList = new ArrayList<>();
+
+      for (InetSocketAddress tloc : locatorList.getLocators()) {
+        if (tloc.equals(locator)) {
+          /**
+           * This call doesn't throw UnknownHostException;
+           */
+          InetSocketAddress changeLoc =
+              new InetSocketAddress(locator.getHostName(), locator.getPort());
+          newLocatorsList.add(changeLoc);
+          logger.info("updateLocatorInLocatorList changing locator list: loc 
form: " + locator
+              + " ,loc to: " + changeLoc);
+        } else {
+          newLocatorsList.add(tloc);
+        }
+      }
+
+      logger.info("updateLocatorInLocatorList locator list from:" + 
locatorList.getLocators()
+          + " to: " + newLocatorsList);
+
+      LocatorList newLocatorList = new LocatorList(newLocatorsList);
+      locators.set(newLocatorList);
+    }
+  }
+
+  protected List<InetSocketAddress> getCurrentLocators() {
+    return locators.get().locators;
+  }
+
   protected ServerLocationResponse queryLocators(ServerLocationRequest 
request) {
     Iterator controllerItr = locators.get().iterator();
     ServerLocationResponse response = null;
@@ -276,7 +314,7 @@ public class AutoConnectionSourceImpl implements 
ConnectionSource {
       badLocators.remove(address);
     }
 
-    newLocators.addAll(badLocators);
+    addbadLocators(newLocators, badLocators);
 
     if (logger.isInfoEnabled()) {
       LocatorList oldLocators = (LocatorList) locators.get();
@@ -300,11 +338,37 @@ public class AutoConnectionSourceImpl implements 
ConnectionSource {
       }
     }
     LocatorList newLocatorList = new LocatorList(newLocators);
+
     locators.set(newLocatorList);
     onlineLocators.set(new LocatorList(newOnlineLocators));
     pool.getStats().setLocatorCount(newLocators.size());
   }
 
+  /**
+   * This method will add bad locator only when locator with hostname and port 
is not already in
+   * list.
+   */
+  protected void addbadLocators(List<InetSocketAddress> newLocators,
+      Set<InetSocketAddress> badLocators) {
+    for (InetSocketAddress badLoc : badLocators) {
+      boolean addIt = true;
+      for (InetSocketAddress goodloc : newLocators) {
+        boolean isSameHost = 
badLoc.getHostName().equals(goodloc.getHostName());
+        if (isSameHost) {
+          boolean isSamePort = badLoc.getPort() == goodloc.getPort();
+          if (isSamePort) {
+            // ip has been changed so don't add this in current list
+            addIt = false;
+            break;
+          }
+        }
+      }
+      if (addIt) {
+        newLocators.add(badLoc);
+      }
+    }
+  }
+
   public void start(InternalPool pool) {
     this.pool = pool;
     pool.getStats().setInitialContacts(((LocatorList) locators.get()).size());

http://git-wip-us.apache.org/repos/asf/geode/blob/3a46b791/geode-core/src/main/java/org/apache/geode/distributed/internal/membership/gms/membership/GMSJoinLeave.java
----------------------------------------------------------------------
diff --git 
a/geode-core/src/main/java/org/apache/geode/distributed/internal/membership/gms/membership/GMSJoinLeave.java
 
b/geode-core/src/main/java/org/apache/geode/distributed/internal/membership/gms/membership/GMSJoinLeave.java
index bc3d708..93c5bf8 100644
--- 
a/geode-core/src/main/java/org/apache/geode/distributed/internal/membership/gms/membership/GMSJoinLeave.java
+++ 
b/geode-core/src/main/java/org/apache/geode/distributed/internal/membership/gms/membership/GMSJoinLeave.java
@@ -1187,8 +1187,7 @@ public class GMSJoinLeave implements JoinLeave, 
MessageHandler {
         FindCoordinatorRequest request, int connectTimeout)
         throws ClassNotFoundException, IOException {
       TcpClient client = new TcpClient();
-      return client.requestToServer(addr.getAddress(), addr.getPort(), 
request, connectTimeout,
-          true);
+      return client.requestToServer(addr.getAddress(), addr.getPort(), 
request, connectTimeout);
     }
   }
 

http://git-wip-us.apache.org/repos/asf/geode/blob/3a46b791/geode-core/src/main/java/org/apache/geode/distributed/internal/tcpserver/TcpClient.java
----------------------------------------------------------------------
diff --git 
a/geode-core/src/main/java/org/apache/geode/distributed/internal/tcpserver/TcpClient.java
 
b/geode-core/src/main/java/org/apache/geode/distributed/internal/tcpserver/TcpClient.java
index 6b54170..e9476b5 100644
--- 
a/geode-core/src/main/java/org/apache/geode/distributed/internal/tcpserver/TcpClient.java
+++ 
b/geode-core/src/main/java/org/apache/geode/distributed/internal/tcpserver/TcpClient.java
@@ -134,6 +134,7 @@ public class TcpClient {
    */
   public Object requestToServer(InetAddress addr, int port, Object request, 
int timeout)
       throws IOException, ClassNotFoundException {
+
     return requestToServer(addr, port, request, timeout, true);
   }
 
@@ -146,7 +147,7 @@ public class TcpClient {
    * @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
+   * @return the reply
    *
    * @throws IOException
    * @throws ClassNotFoundException
@@ -157,8 +158,30 @@ public class TcpClient {
     if (addr == null) {
       ipAddr = new InetSocketAddress(port);
     } else {
-      ipAddr = new InetSocketAddress(addr, port); // fix for bug 30810
+      ipAddr = new InetSocketAddress(addr.getHostName(), port); // fix for bug 
30810
     }
+    return requestToServer(ipAddr, request, timeout, replyExpected);
+  }
+
+  /**
+   * 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;
 

http://git-wip-us.apache.org/repos/asf/geode/blob/3a46b791/geode-core/src/main/java/org/apache/geode/management/internal/JmxManagerLocatorRequest.java
----------------------------------------------------------------------
diff --git 
a/geode-core/src/main/java/org/apache/geode/management/internal/JmxManagerLocatorRequest.java
 
b/geode-core/src/main/java/org/apache/geode/management/internal/JmxManagerLocatorRequest.java
index 0efba01..eb71d38 100644
--- 
a/geode-core/src/main/java/org/apache/geode/management/internal/JmxManagerLocatorRequest.java
+++ 
b/geode-core/src/main/java/org/apache/geode/management/internal/JmxManagerLocatorRequest.java
@@ -18,6 +18,7 @@ import java.io.DataInput;
 import java.io.DataOutput;
 import java.io.IOException;
 import java.net.InetAddress;
+import java.net.InetSocketAddress;
 import java.util.Map;
 import java.util.Properties;
 
@@ -71,6 +72,7 @@ public class JmxManagerLocatorRequest implements 
DataSerializableFixedID {
       Map<String, String> sslConfigProps) throws IOException {
     Properties distributionConfigProps = new Properties();
     InetAddress networkAddress = InetAddress.getByName(locatorHost);
+    InetSocketAddress inetSockAddr = new InetSocketAddress(networkAddress, 
locatorPort);
 
     try {
       if (sslConfigProps != null) {
@@ -78,8 +80,7 @@ public class JmxManagerLocatorRequest implements 
DataSerializableFixedID {
       }
 
       TcpClient client = new TcpClient(new 
DistributionConfigImpl(distributionConfigProps));
-      Object responseFromServer =
-          client.requestToServer(networkAddress, locatorPort, SINGLETON, 
msTimeout);
+      Object responseFromServer = client.requestToServer(inetSockAddr, 
SINGLETON, msTimeout, true);
 
       return (JmxManagerLocatorResponse) responseFromServer;
     } catch (ClassNotFoundException unexpected) {

http://git-wip-us.apache.org/repos/asf/geode/blob/3a46b791/geode-core/src/main/java/org/apache/geode/management/internal/cli/commands/LauncherLifecycleCommands.java
----------------------------------------------------------------------
diff --git 
a/geode-core/src/main/java/org/apache/geode/management/internal/cli/commands/LauncherLifecycleCommands.java
 
b/geode-core/src/main/java/org/apache/geode/management/internal/cli/commands/LauncherLifecycleCommands.java
index 88832ba..b325e18 100755
--- 
a/geode-core/src/main/java/org/apache/geode/management/internal/cli/commands/LauncherLifecycleCommands.java
+++ 
b/geode-core/src/main/java/org/apache/geode/management/internal/cli/commands/LauncherLifecycleCommands.java
@@ -101,6 +101,7 @@ import java.io.FileWriter;
 import java.io.IOException;
 import java.io.InputStreamReader;
 import java.net.InetAddress;
+import java.net.InetSocketAddress;
 import java.net.MalformedURLException;
 import java.util.ArrayList;
 import java.util.Arrays;

http://git-wip-us.apache.org/repos/asf/geode/blob/3a46b791/geode-core/src/test/java/org/apache/geode/cache/client/internal/AutoConnectionSourceImplJUnitTest.java
----------------------------------------------------------------------
diff --git 
a/geode-core/src/test/java/org/apache/geode/cache/client/internal/AutoConnectionSourceImplJUnitTest.java
 
b/geode-core/src/test/java/org/apache/geode/cache/client/internal/AutoConnectionSourceImplJUnitTest.java
index 3cc3cfc..9169904 100644
--- 
a/geode-core/src/test/java/org/apache/geode/cache/client/internal/AutoConnectionSourceImplJUnitTest.java
+++ 
b/geode-core/src/test/java/org/apache/geode/cache/client/internal/AutoConnectionSourceImplJUnitTest.java
@@ -45,15 +45,20 @@ import org.junit.Test;
 import org.junit.contrib.java.lang.system.RestoreSystemProperties;
 import org.junit.experimental.categories.Category;
 
+import junit.framework.Assert;
+
 import java.io.IOException;
 import java.net.ConnectException;
 import java.net.InetAddress;
 import java.net.InetSocketAddress;
 import java.net.UnknownHostException;
 import java.util.ArrayList;
+import java.util.HashSet;
+import java.util.Iterator;
 import java.util.List;
 import java.util.Map;
 import java.util.Properties;
+import java.util.Set;
 import java.util.concurrent.Executors;
 import java.util.concurrent.ScheduledExecutorService;
 import java.util.concurrent.TimeUnit;
@@ -141,6 +146,65 @@ public class AutoConnectionSourceImplJUnitTest {
     }
   }
 
+  /**
+   * This test validates the 
AutoConnectionSourceImpl.updateLocatorInLocatorList method. That method
+   * takes InetSocketAddres of locator which unable to connect to locator. And 
update that
+   * InetSocketAddres with hostaddress of locator in locatorlist.
+   * 
+   * In this test we validate this using identityHashCode.
+   */
+  @Test
+  public void testLocatorIpChange() {
+    int port = 11011;
+    List<InetSocketAddress> locators = new ArrayList();
+    InetSocketAddress floc1 = new InetSocketAddress("fakeLocalHost1", port);
+    InetSocketAddress floc2 = new InetSocketAddress("fakeLocalHost2", port);
+    locators.add(floc1);
+    locators.add(floc2);
+    AutoConnectionSourceImpl src = new AutoConnectionSourceImpl(locators, "", 
60 * 1000);
+
+    // This method will create a new InetSocketAddress of floc1
+    src.updateLocatorInLocatorList(floc1);
+
+    List<InetSocketAddress> cLocList = src.getCurrentLocators();
+
+    Assert.assertEquals(2, cLocList.size());
+
+    Iterator<InetSocketAddress> itr = cLocList.iterator();
+
+    while (itr.hasNext()) {
+      InetSocketAddress t = itr.next();
+      Assert.assertFalse("Should have replaced floc1 intsance", t == floc1);
+    }
+  }
+
+  /**
+   * This test validates the AutoConnectionSourceImpl.addbadLocators method. 
That method adds
+   * badLocator from badLocator list to new Locator list. And it make sure 
that new locator list
+   * doesn't have similar entry. For that it checks hostname and port only.
+   */
+  @Test
+  public void testAddBadLocator() {
+    int port = 11011;
+    List<InetSocketAddress> locators = new ArrayList();
+    InetSocketAddress floc1 = new InetSocketAddress("fakeLocalHost1", port);
+    InetSocketAddress floc2 = new InetSocketAddress("fakeLocalHost2", port);
+    locators.add(floc1);
+    locators.add(floc2);
+    AutoConnectionSourceImpl src = new AutoConnectionSourceImpl(locators, "", 
60 * 1000);
+
+
+    Set<InetSocketAddress> badLocators = new HashSet<>();
+    InetSocketAddress b1 = new InetSocketAddress("fakeLocalHost1", port);
+    InetSocketAddress b2 = new InetSocketAddress("fakeLocalHost3", port);
+    badLocators.add(b1);
+    badLocators.add(b2);
+
+    src.addbadLocators(locators, badLocators);
+
+    Assert.assertEquals(3, locators.size());
+  }
+
   @Test
   public void testNoRespondingLocators() {
     try {

Reply via email to