@Override
  public void initializeSecurity(TCredentials credentials, String principal, byte[] token)
      throws AccumuloSecurityException {
    try {
      // remove old settings from zookeeper first, if any
      IZooReaderWriter zoo = ZooReaderWriter.getInstance();
      synchronized (zooCache) {
        zooCache.clear();
        if (zoo.exists(ZKUserPath)) {
          zoo.recursiveDelete(ZKUserPath, NodeMissingPolicy.SKIP);
          log.info("Removed " + ZKUserPath + "/" + " from zookeeper");
        }

        // prep parent node of users with root username
        zoo.putPersistentData(ZKUserPath, principal.getBytes(UTF_8), NodeExistsPolicy.FAIL);

        constructUser(principal, ZKSecurityTool.createPass(token));
      }
    } catch (KeeperException e) {
      log.error("{}", e.getMessage(), e);
      throw new RuntimeException(e);
    } catch (InterruptedException e) {
      log.error("{}", e.getMessage(), e);
      throw new RuntimeException(e);
    } catch (AccumuloException e) {
      log.error("{}", e.getMessage(), e);
      throw new RuntimeException(e);
    }
  }
 @Override
 public void changePassword(String principal, AuthenticationToken token)
     throws AccumuloSecurityException {
   if (!(token instanceof PasswordToken))
     throw new AccumuloSecurityException(principal, SecurityErrorCode.INVALID_TOKEN);
   PasswordToken pt = (PasswordToken) token;
   if (userExists(principal)) {
     try {
       synchronized (zooCache) {
         zooCache.clear(ZKUserPath + "/" + principal);
         ZooReaderWriter.getInstance()
             .putPrivatePersistentData(
                 ZKUserPath + "/" + principal,
                 ZKSecurityTool.createPass(pt.getPassword()),
                 NodeExistsPolicy.OVERWRITE);
       }
     } catch (KeeperException e) {
       log.error("{}", e.getMessage(), e);
       throw new AccumuloSecurityException(principal, SecurityErrorCode.CONNECTION_ERROR, e);
     } catch (InterruptedException e) {
       log.error("{}", e.getMessage(), e);
       throw new RuntimeException(e);
     } catch (AccumuloException e) {
       log.error("{}", e.getMessage(), e);
       throw new AccumuloSecurityException(principal, SecurityErrorCode.DEFAULT_SECURITY_ERROR, e);
     }
   } else
     throw new AccumuloSecurityException(
         principal, SecurityErrorCode.USER_DOESNT_EXIST); // user doesn't exist
 }
 @Override
 public boolean authenticateUser(String principal, AuthenticationToken token)
     throws AccumuloSecurityException {
   if (!(token instanceof PasswordToken))
     throw new AccumuloSecurityException(principal, SecurityErrorCode.INVALID_TOKEN);
   PasswordToken pt = (PasswordToken) token;
   byte[] pass;
   String zpath = ZKUserPath + "/" + principal;
   pass = zooCache.get(zpath);
   boolean result = ZKSecurityTool.checkPass(pt.getPassword(), pass);
   if (!result) {
     zooCache.clear(zpath);
     pass = zooCache.get(zpath);
     result = ZKSecurityTool.checkPass(pt.getPassword(), pass);
   }
   return result;
 }
 @Override
 public void createUser(String principal, AuthenticationToken token)
     throws AccumuloSecurityException {
   try {
     if (!(token instanceof PasswordToken))
       throw new AccumuloSecurityException(principal, SecurityErrorCode.INVALID_TOKEN);
     PasswordToken pt = (PasswordToken) token;
     constructUser(principal, ZKSecurityTool.createPass(pt.getPassword()));
   } catch (KeeperException e) {
     if (e.code().equals(KeeperException.Code.NODEEXISTS))
       throw new AccumuloSecurityException(principal, SecurityErrorCode.USER_EXISTS, e);
     throw new AccumuloSecurityException(principal, SecurityErrorCode.CONNECTION_ERROR, e);
   } catch (InterruptedException e) {
     log.error("{}", e.getMessage(), e);
     throw new RuntimeException(e);
   } catch (AccumuloException e) {
     log.error("{}", e.getMessage(), e);
     throw new AccumuloSecurityException(principal, SecurityErrorCode.DEFAULT_SECURITY_ERROR, e);
   }
 }