You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@manifoldcf.apache.org by kw...@apache.org on 2013/12/16 10:30:52 UTC

svn commit: r1551138 - in /manifoldcf/trunk: ./ framework/core/src/main/java/org/apache/manifoldcf/core/lockmanager/

Author: kwright
Date: Mon Dec 16 09:30:52 2013
New Revision: 1551138

URL: http://svn.apache.org/r1551138
Log:
Fix for CONNECTORS-838.

Modified:
    manifoldcf/trunk/CHANGES.txt
    manifoldcf/trunk/framework/core/src/main/java/org/apache/manifoldcf/core/lockmanager/ZooKeeperConnection.java
    manifoldcf/trunk/framework/core/src/main/java/org/apache/manifoldcf/core/lockmanager/ZooKeeperLockManager.java
    manifoldcf/trunk/framework/core/src/main/java/org/apache/manifoldcf/core/lockmanager/ZooKeeperLockObject.java

Modified: manifoldcf/trunk/CHANGES.txt
URL: http://svn.apache.org/viewvc/manifoldcf/trunk/CHANGES.txt?rev=1551138&r1=1551137&r2=1551138&view=diff
==============================================================================
--- manifoldcf/trunk/CHANGES.txt (original)
+++ manifoldcf/trunk/CHANGES.txt Mon Dec 16 09:30:52 2013
@@ -3,6 +3,10 @@ $Id$
 
 ======================= 1.5-dev =====================
 
+CONNECTORS-838: Character-stuff names that ZooKeeper sees, to
+prevent issues with '/' characters.
+(Karl Wright)
+
 CONNECTORS-837: Specifying 1 connection causes hang.
 (Karl Wright)
 

Modified: manifoldcf/trunk/framework/core/src/main/java/org/apache/manifoldcf/core/lockmanager/ZooKeeperConnection.java
URL: http://svn.apache.org/viewvc/manifoldcf/trunk/framework/core/src/main/java/org/apache/manifoldcf/core/lockmanager/ZooKeeperConnection.java?rev=1551138&r1=1551137&r2=1551138&view=diff
==============================================================================
--- manifoldcf/trunk/framework/core/src/main/java/org/apache/manifoldcf/core/lockmanager/ZooKeeperConnection.java (original)
+++ manifoldcf/trunk/framework/core/src/main/java/org/apache/manifoldcf/core/lockmanager/ZooKeeperConnection.java Mon Dec 16 09:30:52 2013
@@ -511,6 +511,51 @@ public class ZooKeeperConnection
     zookeeperWatcher = null;
   }
   
+  public static String zooKeeperSafeName(String input)
+  {
+    // Escape "/" characters
+    StringBuilder sb = new StringBuilder();
+    for (int i = 0; i < input.length(); i++)
+    {
+      char x = input.charAt(i);
+      if (x == '/')
+        sb.append('\\').append('0');
+      else if (x == '\\')
+        sb.append('\\').append('\\');
+      else
+        sb.append(x);
+    }
+    return sb.toString();
+  }
+
+  public static String zooKeeperDecodeSafeName(String input)
+  {
+    // Escape "/" characters
+    StringBuilder sb = new StringBuilder();
+    int i = 0;
+    while (i < input.length())
+    {
+      char x = input.charAt(i);
+      if (x == '\\')
+      {
+        i++;
+        if (i == input.length())
+          throw new RuntimeException("Supposedly safe zookeeper name is not properly encoded!!");
+        x = input.charAt(i);
+        if (x == '0')
+          sb.append('/');
+        else if (x == '\\')
+          sb.append('\\');
+        else
+          throw new RuntimeException("Supposedly safe zookeeper name is not properly encoded!!");
+      }
+      else
+        sb.append(x);
+      i++;
+    }
+    return sb.toString();
+  }
+
   // Protected methods
   
   /** Create a node and a sequential child node.  Neither node has any data.

Modified: manifoldcf/trunk/framework/core/src/main/java/org/apache/manifoldcf/core/lockmanager/ZooKeeperLockManager.java
URL: http://svn.apache.org/viewvc/manifoldcf/trunk/framework/core/src/main/java/org/apache/manifoldcf/core/lockmanager/ZooKeeperLockManager.java?rev=1551138&r1=1551137&r2=1551138&view=diff
==============================================================================
--- manifoldcf/trunk/framework/core/src/main/java/org/apache/manifoldcf/core/lockmanager/ZooKeeperLockManager.java (original)
+++ manifoldcf/trunk/framework/core/src/main/java/org/apache/manifoldcf/core/lockmanager/ZooKeeperLockManager.java Mon Dec 16 09:30:52 2013
@@ -152,7 +152,9 @@ public class ZooKeeperLockManager extend
           if (serviceName == null)
             serviceName = constructUniqueServiceName(connection, serviceType);
 
-          String activePath = buildServiceTypeActivePath(serviceType, serviceName);
+          String encodedServiceName = ZooKeeperConnection.zooKeeperSafeName(serviceName);
+          
+          String activePath = buildServiceTypeActivePath(serviceType, encodedServiceName);
           if (connection.checkNodeExists(activePath))
             throw new ManifoldCFException("Service '"+serviceName+"' of type '"+serviceType+"' is already active");
           // First, see where we stand.
@@ -162,11 +164,11 @@ public class ZooKeeperLockManager extend
           List<String> children = connection.getChildren(registrationNodePath);
           boolean foundService = false;
           boolean foundActiveService = false;
-          for (String registeredServiceName : children)
+          for (String encodedRegisteredServiceName : children)
           {
-            if (registeredServiceName.equals(serviceName))
+            if (encodedRegisteredServiceName.equals(encodedServiceName))
               foundService = true;
-            if (connection.checkNodeExists(buildServiceTypeActivePath(serviceType, registeredServiceName)))
+            if (connection.checkNodeExists(buildServiceTypeActivePath(serviceType, encodedRegisteredServiceName)))
               foundActiveService = true;
           }
           
@@ -197,17 +199,17 @@ public class ZooKeeperLockManager extend
           if (unregisterAll)
           {
             // Unregister all (since we did a global cleanup)
-            for (String registeredServiceName : children)
+            for (String encodedRegisteredServiceName : children)
             {
-              if (!registeredServiceName.equals(serviceName))
-                connection.deleteChild(registrationNodePath, registeredServiceName);
+              if (!encodedRegisteredServiceName.equals(encodedServiceName))
+                connection.deleteChild(registrationNodePath, encodedRegisteredServiceName);
             }
           }
 
           // Now, register (if needed)
           if (!foundService)
           {
-            connection.createChild(registrationNodePath, serviceName);
+            connection.createChild(registrationNodePath, encodedServiceName);
           }
           
           // Last, set the appropriate active flag
@@ -248,7 +250,7 @@ public class ZooKeeperLockManager extend
         enterServiceRegistryWriteLock(connection, serviceType);
         try
         {
-          String activePath = buildServiceTypeActivePath(serviceType, serviceName);
+          String activePath = buildServiceTypeActivePath(serviceType, ZooKeeperConnection.zooKeeperSafeName(serviceName));
           connection.setNodeData(activePath, (serviceData==null)?new byte[0]:serviceData);
         }
         finally
@@ -284,7 +286,7 @@ public class ZooKeeperLockManager extend
         enterServiceRegistryReadLock(connection, serviceType);
         try
         {
-          String activePath = buildServiceTypeActivePath(serviceType, serviceName);
+          String activePath = buildServiceTypeActivePath(serviceType, ZooKeeperConnection.zooKeeperSafeName(serviceName));
           return connection.getNodeData(activePath);
         }
         finally
@@ -321,13 +323,13 @@ public class ZooKeeperLockManager extend
         {
           String registrationNodePath = buildServiceTypeRegistrationPath(serviceType);
           List<String> children = connection.getChildren(registrationNodePath);
-          for (String registeredServiceName : children)
+          for (String encodedRegisteredServiceName : children)
           {
-            String activeNodePath = buildServiceTypeActivePath(serviceType, registeredServiceName);
+            String activeNodePath = buildServiceTypeActivePath(serviceType, encodedRegisteredServiceName);
             if (connection.checkNodeExists(activeNodePath))
             {
               byte[] serviceData = connection.getNodeData(activeNodePath);
-              if (dataAcceptor.acceptServiceData(registeredServiceName, serviceData))
+              if (dataAcceptor.acceptServiceData(ZooKeeperConnection.zooKeeperDecodeSafeName(encodedRegisteredServiceName), serviceData))
                 break;
             }
           }
@@ -368,9 +370,9 @@ public class ZooKeeperLockManager extend
           String registrationNodePath = buildServiceTypeRegistrationPath(serviceType);
           List<String> children = connection.getChildren(registrationNodePath);
           int activeServiceCount = 0;
-          for (String registeredServiceName : children)
+          for (String encodedRegisteredServiceName : children)
           {
-            if (connection.checkNodeExists(buildServiceTypeActivePath(serviceType, registeredServiceName)))
+            if (connection.checkNodeExists(buildServiceTypeActivePath(serviceType, encodedRegisteredServiceName)))
               activeServiceCount++;
           }
           return activeServiceCount;
@@ -417,25 +419,25 @@ public class ZooKeeperLockManager extend
           // Presumably the caller will lather, rinse, and repeat.
           String registrationNodePath = buildServiceTypeRegistrationPath(serviceType);
           List<String> children = connection.getChildren(registrationNodePath);
-          String serviceName = null;
-          for (String registeredServiceName : children)
+          String encodedServiceName = null;
+          for (String encodedRegisteredServiceName : children)
           {
-            if (!connection.checkNodeExists(buildServiceTypeActivePath(serviceType, registeredServiceName)))
+            if (!connection.checkNodeExists(buildServiceTypeActivePath(serviceType, encodedRegisteredServiceName)))
             {
-              serviceName = registeredServiceName;
+              encodedServiceName = encodedRegisteredServiceName;
               break;
             }
           }
-          if (serviceName == null)
+          if (encodedServiceName == null)
             return true;
           
           // Found one, in serviceName, at position i
           // Ideally, we should signal at this point that we're cleaning up after it, and then leave
           // the exclusive lock, so that other activity can take place.  MHL
-          cleanup.cleanUpService(serviceName);
+          cleanup.cleanUpService(ZooKeeperConnection.zooKeeperDecodeSafeName(encodedServiceName));
 
           // Unregister the service.
-          connection.deleteChild(registrationNodePath, serviceName);
+          connection.deleteChild(registrationNodePath, encodedServiceName);
           return false;
         }
         finally
@@ -473,7 +475,7 @@ public class ZooKeeperLockManager extend
         enterServiceRegistryWriteLock(connection, serviceType);
         try
         {
-          connection.deleteNode(buildServiceTypeActivePath(serviceType, serviceName));
+          connection.deleteNode(buildServiceTypeActivePath(serviceType, ZooKeeperConnection.zooKeeperSafeName(serviceName)));
         }
         finally
         {
@@ -510,7 +512,7 @@ public class ZooKeeperLockManager extend
         enterServiceRegistryReadLock(connection, serviceType);
         try
         {
-          return connection.checkNodeExists(buildServiceTypeActivePath(serviceType, serviceName));
+          return connection.checkNodeExists(buildServiceTypeActivePath(serviceType, ZooKeeperConnection.zooKeeperSafeName(serviceName)));
         }
         finally
         {
@@ -576,7 +578,7 @@ public class ZooKeeperLockManager extend
   */
   protected static String makeServiceCounterName(String serviceType)
   {
-    return SERVICETYPE_ANONYMOUS_COUNTER_PREFIX + serviceType;
+    return SERVICETYPE_ANONYMOUS_COUNTER_PREFIX + ZooKeeperConnection.zooKeeperSafeName(serviceType);
   }
   
   /** Read service counter.
@@ -621,21 +623,21 @@ public class ZooKeeperLockManager extend
   */
   protected static String buildServiceTypeLockPath(String serviceType)
   {
-    return SERVICETYPE_LOCK_PATH_PREFIX + serviceType;
+    return SERVICETYPE_LOCK_PATH_PREFIX + ZooKeeperConnection.zooKeeperSafeName(serviceType);
   }
   
   /** Build a zk path for the active node for a specific service of a specific type.
   */
-  protected static String buildServiceTypeActivePath(String serviceType, String serviceName)
+  protected static String buildServiceTypeActivePath(String serviceType, String encodedServiceName)
   {
-    return SERVICETYPE_ACTIVE_PATH_PREFIX + serviceType + "-" + serviceName;
+    return SERVICETYPE_ACTIVE_PATH_PREFIX + ZooKeeperConnection.zooKeeperSafeName(serviceType) + "-" + encodedServiceName;
   }
   
   /** Build a zk path for the registration node for a specific service type.
   */
   protected static String buildServiceTypeRegistrationPath(String serviceType)
   {
-    return SERVICETYPE_REGISTER_PATH_PREFIX + serviceType;
+    return SERVICETYPE_REGISTER_PATH_PREFIX + ZooKeeperConnection.zooKeeperSafeName(serviceType);
   }
   
   // Shared configuration
@@ -731,7 +733,7 @@ public class ZooKeeperLockManager extend
       ZooKeeperConnection connection = pool.grab();
       try
       {
-        connection.setGlobalFlag(FLAG_PATH_PREFIX + flagName);
+        connection.setGlobalFlag(FLAG_PATH_PREFIX + ZooKeeperConnection.zooKeeperSafeName(flagName));
       }
       finally
       {
@@ -756,7 +758,7 @@ public class ZooKeeperLockManager extend
       ZooKeeperConnection connection = pool.grab();
       try
       {
-        connection.clearGlobalFlag(FLAG_PATH_PREFIX + flagName);
+        connection.clearGlobalFlag(FLAG_PATH_PREFIX + ZooKeeperConnection.zooKeeperSafeName(flagName));
       }
       finally
       {
@@ -782,7 +784,7 @@ public class ZooKeeperLockManager extend
       ZooKeeperConnection connection = pool.grab();
       try
       {
-        return connection.checkGlobalFlag(FLAG_PATH_PREFIX + flagName);
+        return connection.checkGlobalFlag(FLAG_PATH_PREFIX + ZooKeeperConnection.zooKeeperSafeName(flagName));
       }
       finally
       {
@@ -809,7 +811,7 @@ public class ZooKeeperLockManager extend
       ZooKeeperConnection connection = pool.grab();
       try
       {
-        return connection.readData(RESOURCE_PATH_PREFIX + resourceName);
+        return connection.readData(RESOURCE_PATH_PREFIX + ZooKeeperConnection.zooKeeperSafeName(resourceName));
       }
       finally
       {
@@ -836,7 +838,7 @@ public class ZooKeeperLockManager extend
       ZooKeeperConnection connection = pool.grab();
       try
       {
-        connection.writeData(RESOURCE_PATH_PREFIX + resourceName, data);
+        connection.writeData(RESOURCE_PATH_PREFIX + ZooKeeperConnection.zooKeeperSafeName(resourceName), data);
       }
       finally
       {

Modified: manifoldcf/trunk/framework/core/src/main/java/org/apache/manifoldcf/core/lockmanager/ZooKeeperLockObject.java
URL: http://svn.apache.org/viewvc/manifoldcf/trunk/framework/core/src/main/java/org/apache/manifoldcf/core/lockmanager/ZooKeeperLockObject.java?rev=1551138&r1=1551137&r2=1551138&view=diff
==============================================================================
--- manifoldcf/trunk/framework/core/src/main/java/org/apache/manifoldcf/core/lockmanager/ZooKeeperLockObject.java (original)
+++ manifoldcf/trunk/framework/core/src/main/java/org/apache/manifoldcf/core/lockmanager/ZooKeeperLockObject.java Mon Dec 16 09:30:52 2013
@@ -41,7 +41,7 @@ public class ZooKeeperLockObject extends
   {
     super(lockPool,lockKey);
     this.pool = pool;
-    this.lockPath = LOCK_PATH_PREFIX + lockKey.toString();
+    this.lockPath = LOCK_PATH_PREFIX + ZooKeeperConnection.zooKeeperSafeName(lockKey.toString());
   }
 
   @Override