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


Reply via email to