/// <summary> /// Set the ACL for the node of the given path if such a node exists and the /// given version matches the version of the node. Return the stat of the /// node. /// /// A KeeperException with error code KeeperException.NoNode will be thrown /// if no node with the given path exists. /// /// A KeeperException with error code KeeperException.BadVersion will be /// thrown if the given version does not match the node's version. /// @param path /// @param acl /// @param version /// @return the stat of the node. /// @throws InterruptedException If the server transaction is interrupted. /// @throws KeeperException If the server signals an error with a non-zero error code. /// @throws org.apache.zookeeper.KeeperException.InvalidACLException If the acl is invalide. /// @throws IllegalArgumentException if an invalid path is specified /// </summary> public Stat SetACL(string path, IEnumerable <ACL> acl, int version) { string clientPath = path; PathUtils.ValidatePath(clientPath); if (acl != null && acl.Count() == 0) { throw new KeeperException.InvalidACLException(); } string serverPath = PrependChroot(clientPath); RequestHeader h = new RequestHeader(); h.Type = (int)OpCode.SetACL; SetACLRequest request = new SetACLRequest(serverPath, acl, version); SetACLResponse response = new SetACLResponse(); ReplyHeader r = cnxn.SubmitRequest(h, request, response, null); if (r.Err != 0) { throw KeeperException.Create((KeeperException.Code)Enum.ToObject(typeof(KeeperException.Code), r.Err), clientPath); } return(response.Stat); }
/// <summary> /// For the given znode path return the stat and children list. /// /// If the watch is non-null and the call is successful (no exception is thrown), /// a watch will be left on the node with the given path. The watch willbe /// triggered by a successful operation that deletes the node of the given /// path or creates/delete a child under the node. /// /// The list of children returned is not sorted and no guarantee is provided /// as to its natural or lexical order. /// /// A KeeperException with error code KeeperException.NoNode will be thrown /// if no node with the given path exists. /// @since 3.3.0 /// /// @param path /// @param watcher explicit watcher /// @param stat stat of the znode designated by path /// @return an unordered array of children of the node with the given path /// @throws InterruptedException If the server transaction is interrupted. /// @throws KeeperException If the server signals an error with a non-zero error code. /// @throws IllegalArgumentException if an invalid path is specified /// </summary> public IEnumerable <string> GetChildren(string path, IWatcher watcher, Stat stat) { string clientPath = path; PathUtils.ValidatePath(clientPath); // the watch contains the un-chroot path WatchRegistration wcb = null; if (watcher != null) { wcb = new ChildWatchRegistration(watchManager, watcher, clientPath); } string serverPath = PrependChroot(clientPath); RequestHeader h = new RequestHeader(); h.Type = (int)OpCode.GetChildren2; GetChildren2Request request = new GetChildren2Request(serverPath, watcher != null); GetChildren2Response response = new GetChildren2Response(); ReplyHeader r = cnxn.SubmitRequest(h, request, response, wcb); if (r.Err != 0) { throw KeeperException.Create((KeeperException.Code)Enum.ToObject(typeof(KeeperException.Code), r.Err), clientPath); } if (stat != null) { DataTree.CopyStat(response.Stat, stat); } return(response.Children); }
/// <summary> /// Return the stat of the node of the given path. Return null if no such a /// node exists. /// /// If the watch is non-null and the call is successful (no exception is thrown), /// a watch will be left on the node with the given path. The watch will be /// triggered by a successful operation that creates/delete the node or sets /// the data on the node. /// </summary> /// <param name="path">The path.</param> /// <param name="watcher">The watcher.</param> /// <returns>the stat of the node of the given path; return null if no such a node exists.</returns> public Stat Exists(string path, IWatcher watcher) { string clientPath = path; PathUtils.ValidatePath(clientPath); // the watch contains the un-chroot path WatchRegistration wcb = null; if (watcher != null) { wcb = new ExistsWatchRegistration(watchManager, watcher, clientPath); } string serverPath = PrependChroot(clientPath); RequestHeader h = new RequestHeader(); h.Type = (int)OpCode.Exists; ExistsRequest request = new ExistsRequest(serverPath, watcher != null); SetDataResponse response = new SetDataResponse(); ReplyHeader r = cnxn.SubmitRequest(h, request, response, wcb); if (r.Err != 0) { if (r.Err == (int)KeeperException.Code.NONODE) { return(null); } throw KeeperException.Create((KeeperException.Code)Enum.ToObject(typeof(KeeperException.Code), r.Err), clientPath); } return(response.Stat.Czxid == -1 ? null : response.Stat); }
/// <summary> /// Delete the node with the given path. The call will succeed if such a node /// exists, and the given version matches the node's version (if the given /// version is -1, it matches any node's versions). /// /// A KeeperException with error code KeeperException.NoNode will be thrown /// if the nodes does not exist. /// /// A KeeperException with error code KeeperException.BadVersion will be /// thrown if the given version does not match the node's version. /// /// A KeeperException with error code KeeperException.NotEmpty will be thrown /// if the node has children. /// /// This operation, if successful, will trigger all the watches on the node /// of the given path left by exists API calls, and the watches on the parent /// node left by getChildren API calls. /// </summary> /// <param name="path">The path.</param> /// <param name="version">The version.</param> public void Delete(string path, int version) { string clientPath = path; PathUtils.ValidatePath(clientPath); string serverPath; // maintain semantics even in chroot case // specifically - root cannot be deleted // I think this makes sense even in chroot case. if (clientPath.Equals(PathUtils.PathSeparator)) { // a bit of a hack, but delete(/) will never succeed and ensures // that the same semantics are maintained serverPath = clientPath; } else { serverPath = PrependChroot(clientPath); } RequestHeader h = new RequestHeader(); h.Type = (int)OpCode.Delete; DeleteRequest request = new DeleteRequest(serverPath, version); ReplyHeader r = cnxn.SubmitRequest(h, request, null, null); if (r.Err != 0) { throw KeeperException.Create((KeeperException.Code)Enum.ToObject(typeof(KeeperException.Code), r.Err), clientPath); } }
/** * All non-specific keeper exceptions should be constructed via * this factory method in order to guarantee consistency in error * codes and such. If you know the error code, then you should * construct the special purpose exception directly. That will * allow you to have the most specific possible declarations of * what exceptions might actually be thrown. * * @param code The error code. * @param path The ZooKeeper path being operated on. * @return The specialized exception, presumably to be thrown by * the caller. */ public static KeeperException Create(Code code, string path) { KeeperException r = Create(code); r.path = path; return(r); }
/// <summary> /// Set the data for the node of the given path if such a node exists and the /// given version matches the version of the node (if the given version is /// -1, it matches any node's versions). Return the stat of the node. /// /// This operation, if successful, will trigger all the watches on the node /// of the given path left by getData calls. /// /// A KeeperException with error code KeeperException.NoNode will be thrown /// if no node with the given path exists. /// /// A KeeperException with error code KeeperException.BadVersion will be /// thrown if the given version does not match the node's version. /// /// The maximum allowable size of the data array is 1 MB (1,048,576 bytes). /// Arrays larger than this will cause a KeeperExecption to be thrown. /// @param path /// the path of the node /// @param data /// the data to set /// @param version /// the expected matching version /// @return the state of the node /// @throws InterruptedException If the server transaction is interrupted. /// @throws KeeperException If the server signals an error with a non-zero error code. /// @throws IllegalArgumentException if an invalid path is specified /// </summary> public Stat SetData(string path, byte[] data, int version) { string clientPath = path; PathUtils.ValidatePath(clientPath); string serverPath = PrependChroot(clientPath); RequestHeader h = new RequestHeader(); h.Type = (int)OpCode.SetData; SetDataRequest request = new SetDataRequest(serverPath, data, version); SetDataResponse response = new SetDataResponse(); ReplyHeader r = cnxn.SubmitRequest(h, request, response, null); if (r.Err != 0) { throw KeeperException.Create((KeeperException.Code)Enum.ToObject(typeof(KeeperException.Code), r.Err), clientPath); } return(response.Stat); }
/// <summary> /// Return the ACL and stat of the node of the given path. /// /// A KeeperException with error code KeeperException.NoNode will be thrown /// if no node with the given path exists. /// @param path /// the given path for the node /// @param stat /// the stat of the node will be copied to this parameter. /// @return the ACL array of the given node. /// @throws InterruptedException If the server transaction is interrupted. /// @throws KeeperException If the server signals an error with a non-zero error code. /// @throws IllegalArgumentException if an invalid path is specified /// </summary> public IEnumerable <ACL> GetACL(string path, Stat stat) { string clientPath = path; PathUtils.ValidatePath(clientPath); string serverPath = PrependChroot(clientPath); RequestHeader h = new RequestHeader(); h.Type = (int)OpCode.GetACL; GetACLRequest request = new GetACLRequest(serverPath); GetACLResponse response = new GetACLResponse(); ReplyHeader r = cnxn.SubmitRequest(h, request, response, null); if (r.Err != 0) { throw KeeperException.Create((KeeperException.Code)Enum.ToObject(typeof(KeeperException.Code), r.Err), clientPath); } DataTree.CopyStat(response.Stat, stat); return(response.Acl); }
/// <summary> /// Create a node with the given path. The node data will be the given data, /// and node acl will be the given acl. /// /// The flags argument specifies whether the created node will be ephemeral /// or not. /// /// An ephemeral node will be removed by the ZooKeeper automatically when the /// session associated with the creation of the node expires. /// /// The flags argument can also specify to create a sequential node. The /// actual path name of a sequential node will be the given path plus a /// suffix "i" where i is the current sequential number of the node. The sequence /// number is always fixed length of 10 digits, 0 padded. Once /// such a node is created, the sequential number will be incremented by one. /// /// If a node with the same actual path already exists in the ZooKeeper, a /// KeeperException with error code KeeperException.NodeExists will be /// thrown. Note that since a different actual path is used for each /// invocation of creating sequential node with the same path argument, the /// call will never throw "file exists" KeeperException. /// /// If the parent node does not exist in the ZooKeeper, a KeeperException /// with error code KeeperException.NoNode will be thrown. /// /// An ephemeral node cannot have children. If the parent node of the given /// path is ephemeral, a KeeperException with error code /// KeeperException.NoChildrenForEphemerals will be thrown. /// /// This operation, if successful, will trigger all the watches left on the /// node of the given path by exists and getData API calls, and the watches /// left on the parent node by getChildren API calls. /// /// If a node is created successfully, the ZooKeeper server will trigger the /// watches on the path left by exists calls, and the watches on the parent /// of the node by getChildren calls. /// /// The maximum allowable size of the data array is 1 MB (1,048,576 bytes). /// Arrays larger than this will cause a KeeperExecption to be thrown. /// </summary> /// <param name="path">The path for the node.</param> /// <param name="data">The data for the node.</param> /// <param name="acl">The acl for the node.</param> /// <param name="createMode">specifying whether the node to be created is ephemeral and/or sequential.</param> /// <returns></returns> public string Create(string path, byte[] data, IEnumerable <ACL> acl, CreateMode createMode) { string clientPath = path; PathUtils.ValidatePath(clientPath, createMode.Sequential); if (acl != null && acl.Count() == 0) { throw new KeeperException.InvalidACLException(); } string serverPath = PrependChroot(clientPath); RequestHeader h = new RequestHeader(); h.Type = (int)OpCode.Create; CreateRequest request = new CreateRequest(serverPath, data, acl, createMode.Flag); CreateResponse response = new CreateResponse(); ReplyHeader r = cnxn.SubmitRequest(h, request, response, null); if (r.Err != 0) { throw KeeperException.Create((KeeperException.Code)Enum.ToObject(typeof(KeeperException.Code), r.Err), clientPath); } return(cnxn.ChrootPath == null ? response.Path : response.Path.Substring(cnxn.ChrootPath.Length)); }
/// <summary> /// /// </summary> private void StartConnect() { zooKeeper.State = States.CONNECTING; TcpClient tempClient = null; WaitHandle wh = null; do { if (zkEndpoints.EndPointID != -1) { try { Thread.Sleep(new TimeSpan(0, 0, 0, 0, random.Next(0, 50))); } catch (ThreadInterruptedException e1) { log.Warn("Unexpected exception", e1); } if (!zkEndpoints.IsNextEndPointAvailable) { try { // Try not to spin too fast! Thread.Sleep(1000); } catch (ThreadInterruptedException e) { log.Warn("Unexpected exception", e); } } } //advance through available connections; zkEndpoints.GetNextAvailableEndpoint(); Cleanup(tempClient); log.InfoFormat("Opening socket connection to server {0}", zkEndpoints.CurrentEndPoint.ServerAddress); tempClient = new TcpClient(); tempClient.LingerState = new LingerOption(false, 0); tempClient.NoDelay = true; Interlocked.Exchange(ref initialized, 0); IsConnectionClosedByServer = false; try { IAsyncResult ar = tempClient.BeginConnect(zkEndpoints.CurrentEndPoint.ServerAddress.Address, zkEndpoints.CurrentEndPoint.ServerAddress.Port, null, null); wh = ar.AsyncWaitHandle; if (!ar.AsyncWaitHandle.WaitOne(conn.ConnectionTimeout, false)) { Cleanup(tempClient); tempClient = null; throw new TimeoutException(); } tempClient.EndConnect(ar); break; } catch (Exception ex) { if (ex is SocketException || ex is TimeoutException) { Cleanup(tempClient); tempClient = null; zkEndpoints.CurrentEndPoint.SetAsFailure(); log.WarnFormat(string.Format("Failed to connect to {0}:{1}.", zkEndpoints.CurrentEndPoint.ServerAddress.Address.ToString(), zkEndpoints.CurrentEndPoint.ServerAddress.Port.ToString())); } else { throw; } } finally { wh.Close(); } }while (zkEndpoints.IsNextEndPointAvailable); if (tempClient == null) { throw KeeperException.Create(KeeperException.Code.CONNECTIONLOSS); } client = tempClient; client.GetStream().BeginRead(incomingBuffer, 0, incomingBuffer.Length, ReceiveAsynch, incomingBuffer); PrimeConnection(); }