You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@cassandra.apache.org by jb...@apache.org on 2011/06/08 15:16:14 UTC

svn commit: r1133389 - in /cassandra/branches/cassandra-0.8: CHANGES.txt src/java/org/apache/cassandra/locator/Ec2Snitch.java

Author: jbellis
Date: Wed Jun  8 13:16:14 2011
New Revision: 1133389

URL: http://svn.apache.org/viewvc?rev=1133389&view=rev
Log:
fix nodetoolring use with Ec2Snitch
patch by Vijay; reviewed by jbellis for CASSANDRA-2733

Modified:
    cassandra/branches/cassandra-0.8/CHANGES.txt
    cassandra/branches/cassandra-0.8/src/java/org/apache/cassandra/locator/Ec2Snitch.java

Modified: cassandra/branches/cassandra-0.8/CHANGES.txt
URL: http://svn.apache.org/viewvc/cassandra/branches/cassandra-0.8/CHANGES.txt?rev=1133389&r1=1133388&r2=1133389&view=diff
==============================================================================
--- cassandra/branches/cassandra-0.8/CHANGES.txt (original)
+++ cassandra/branches/cassandra-0.8/CHANGES.txt Wed Jun  8 13:16:14 2011
@@ -41,6 +41,7 @@
  * workaround large resultsets causing large allocation retention
    by nio sockets (CASSANDRA-2654)
  * restrict repair streaming to specific columnfamilies (CASSANDRA-2280)
+ * fix nodetool ring use with Ec2Snitch (CASSANDRA-2733)
 
 
 0.8.0-final

Modified: cassandra/branches/cassandra-0.8/src/java/org/apache/cassandra/locator/Ec2Snitch.java
URL: http://svn.apache.org/viewvc/cassandra/branches/cassandra-0.8/src/java/org/apache/cassandra/locator/Ec2Snitch.java?rev=1133389&r1=1133388&r2=1133389&view=diff
==============================================================================
--- cassandra/branches/cassandra-0.8/src/java/org/apache/cassandra/locator/Ec2Snitch.java (original)
+++ cassandra/branches/cassandra-0.8/src/java/org/apache/cassandra/locator/Ec2Snitch.java Wed Jun  8 13:16:14 2011
@@ -25,11 +25,13 @@ import java.net.HttpURLConnection;
 import java.net.InetAddress;
 import java.net.URL;
 
+import com.google.common.base.Charsets;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
 import org.apache.cassandra.config.ConfigurationException;
 import org.apache.cassandra.gms.ApplicationState;
+import org.apache.cassandra.gms.EndpointState;
 import org.apache.cassandra.gms.Gossiper;
 import org.apache.cassandra.service.StorageService;
 import org.apache.cassandra.utils.FBUtilities;
@@ -41,47 +43,54 @@ import org.apache.cassandra.utils.FBUtil
 public class Ec2Snitch extends AbstractNetworkTopologySnitch
 {
     protected static Logger logger = LoggerFactory.getLogger(Ec2Snitch.class);
+    protected static final String ZONE_NAME_QUERY_URL = "http://169.254.169.254/latest/meta-data/placement/availability-zone";
     protected String ec2zone;
     protected String ec2region;
 
     public Ec2Snitch() throws IOException, ConfigurationException
     {
-        // Populate the region and zone by introspection, fail if 404 on metadata
-        HttpURLConnection conn = (HttpURLConnection) new URL("http://169.254.169.254/latest/meta-data/placement/availability-zone").openConnection();
-        conn.setRequestMethod("GET");
-        if (conn.getResponseCode() != 200)
-        {
-            throw new ConfigurationException("Ec2Snitch was unable to find region/zone data. Not an ec2 node?");
-        }
-
-        // Read the information. I wish I could say (String) conn.getContent() here...
-        int cl = conn.getContentLength();
-        byte[] b = new byte[cl];
-        DataInputStream d = new DataInputStream((FilterInputStream)conn.getContent());
-        d.readFully(b);
-
         // Split "us-east-1a" or "asia-1a" into "us-east"/"1a" and "asia"/"1a".
-        String azone = new String(b ,"UTF-8");
-        String[] splits = azone.split("-");
+        String[] splits = awsApiCall(ZONE_NAME_QUERY_URL).split("-");
         ec2zone = splits[splits.length - 1];
-        ec2region = splits.length < 3 ? splits[0] : splits[0]+"-"+splits[1];
+        ec2region = splits.length < 3 ? splits[0] : splits[0] + "-" + splits[1];
         logger.info("EC2Snitch using region: " + ec2region + ", zone: " + ec2zone + ".");
     }
+    
+    String awsApiCall(String url) throws IOException, ConfigurationException
+    {
+        // Populate the region and zone by introspection, fail if 404 on metadata
+        HttpURLConnection conn = (HttpURLConnection) new URL(url).openConnection();
+        try
+        {
+            conn.setRequestMethod("GET");
+            if (conn.getResponseCode() != 200)
+                throw new ConfigurationException("Ec2Snitch was unable to execute the API call. Not an ec2 node?");
+
+            // Read the information. I wish I could say (String) conn.getContent() here...
+            int cl = conn.getContentLength();
+            byte[] b = new byte[cl];
+            DataInputStream d = new DataInputStream((FilterInputStream) conn.getContent());
+            d.readFully(b);
+            return new String(b, Charsets.UTF_8);
+        }
+        finally
+        {
+            conn.disconnect();
+        }
+    }
 
     public String getRack(InetAddress endpoint)
     {
-        if (endpoint == FBUtilities.getLocalAddress())
+        if (endpoint.equals(FBUtilities.getLocalAddress()))
             return ec2zone;
-        else
-            return Gossiper.instance.getEndpointStateForEndpoint(endpoint).getApplicationState(ApplicationState.RACK).value;
+        return Gossiper.instance.getEndpointStateForEndpoint(endpoint).getApplicationState(ApplicationState.RACK).value;
     }
 
     public String getDatacenter(InetAddress endpoint)
     {
-        if (endpoint == FBUtilities.getLocalAddress())
+        if (endpoint.equals(FBUtilities.getLocalAddress()))
             return ec2region;
-        else
-            return Gossiper.instance.getEndpointStateForEndpoint(endpoint).getApplicationState(ApplicationState.DC).value;
+        return Gossiper.instance.getEndpointStateForEndpoint(endpoint).getApplicationState(ApplicationState.DC).value;
     }
 
     @Override