private async Task <IEnumerable <string> > GetChildrenAsyncInternal(string path, IWatcher watcher, bool sync) { 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 = sync ? cnxn.SubmitRequest(h, request, response, wcb) : await cnxn.SubmitRequestAsync(h, request, response, wcb).ConfigureAwait(false); if (r.Err != 0) { throw KeeperException.Create((KeeperException.Code)Enum.ToObject(typeof(KeeperException.Code), r.Err), clientPath); } return(response.Children); }
/// <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)); }
/** Convenience ctor */ internal Packet(RequestHeader requestHeader, ReplyHeader replyHeader, Record request, Record response, ZooKeeper.WatchRegistration watchRegistration) : this(requestHeader, replyHeader, request, response, watchRegistration, false) { }
/// <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); } }
/// <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); }
public Packet QueuePacket(RequestHeader h, ReplyHeader r, IRecord request, IRecord response, string clientPath, string serverPath, ZooKeeper.WatchRegistration watchRegistration) { lock (outgoingQueueLock) { //lock here for XID? if (h.Type != (int)OpCode.Ping && h.Type != (int)OpCode.Auth) { h.Xid = Xid; } Packet p = new Packet(h, r, request, response, null, watchRegistration, clientPath, serverPath); p.clientPath = clientPath; p.serverPath = serverPath; if (!zooKeeper.State.IsAlive()) { ConLossPacket(p); } else { outgoingQueue.AddLast(p); Monitor.PulseAll(outgoingQueueLock); } return(p); } }
public Packet QueuePacket(RequestHeader h, ReplyHeader r, IRecord request, IRecord response, string clientPath, string serverPath, ZooKeeper.WatchRegistration watchRegistration) { if (h.Type != (int)OpCode.Ping && h.Type != (int)OpCode.Auth) { h.Xid = Xid; } Packet p = new Packet(h, r, request, response, null, watchRegistration, clientPath, serverPath); if (!zooKeeper.State.IsAlive() || closing || Interlocked.CompareExchange(ref isDisposed, 0, 0) == 1) { if (LOG.IsDebugEnabled) { LOG.DebugFormat("Connection closing. Sending ConLossPacket. IsAlive: {0}, closing: {1}", zooKeeper.State.IsAlive(), closing); } ConLossPacket(p); } else { if (h.Type == (int)OpCode.CloseSession) { closing = true; } // enqueue the packet when zookeeper is connected addPacketLast(p); } return(p); }
/// <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(); request.Path = serverPath; request.Data = data; request.Version = 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> /// 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); }
private async Task <Stat> SetACLAsyncInternal(string path, IEnumerable <ACL> acl, int version, bool sync) { 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 = sync ? cnxn.SubmitRequest(h, request, response, null) : await cnxn.SubmitRequestAsync(h, request, response, null).ConfigureAwait(false); 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); }
public async Task testNonExistingOpCode() { ZooKeeper zk = await createClient(); const string path = "/m1"; RequestHeader h = new RequestHeader(); h.set_Type(888); // This code does not exists ExistsRequest request = new ExistsRequest(); request.setPath(path); request.setWatch(false); ExistsResponse response = new ExistsResponse(); ReplyHeader r = await zk.cnxn.submitRequest(h, request, response, null); Assert.assertEquals(r.getErr(), (int)KeeperException.Code.UNIMPLEMENTED); try { await zk.existsAsync("/m1", false); Assert.fail("The connection should have been closed"); } catch (KeeperException.ConnectionLossException) { } }
internal Packet queuePacket(RequestHeader h, ReplyHeader rep, Record request, Record response, string clientPath, string serverPath, ZooKeeper.WatchRegistration watchRegistration) { Packet packet; // Note that we do not generate the Xid for the packet yet. It is // generated later at send-time, by an implementation of // ClientCnxnSocket::doIO(), // where the packet is actually sent. lock (outgoingQueue) { packet = new Packet(h, rep, request, response, watchRegistration); packet.clientPath = clientPath; packet.serverPath = serverPath; if (!getState().isAlive() || closing.Value) { conLossPacket(packet); } else { // If the client is asking to close the session then // mark as closing if (h.get_Type() == (int)ZooDefs.OpCode.closeSession) { closing.Value = true; } outgoingQueue.AddLast(packet); } } clientCnxnSocket.wakeupCnxn(); return(packet); }
public async Task <ReplyHeader> submitRequest(RequestHeader h, Record request, Record response, ZooKeeper.WatchRegistration watchRegistration) { ReplyHeader rep = new ReplyHeader(); Packet packet = queuePacket(h, rep, request, response, null, null, watchRegistration); await packet.PacketTask.ConfigureAwait(false); return(rep); }
internal Packet(RequestHeader requestHeader, ReplyHeader replyHeader, Record request, Record response, ZooKeeper.WatchRegistration watchRegistration, bool readOnly) { this.requestHeader = requestHeader; this.replyHeader = replyHeader; this.request = request; this.response = response; this.readOnly = readOnly; this.watchRegistration = watchRegistration; }
internal Packet(RequestHeader requestHeader, ReplyHeader replyHeader, Record request, Record response, ZooKeeper.WatchRegistration watchRegistration, bool readOnly) : base(TaskCreationOptions.RunContinuationsAsynchronously) { this.requestHeader = requestHeader; this.replyHeader = replyHeader; this.request = request; this.response = response; this.readOnly = readOnly; this.watchRegistration = watchRegistration; }
public ReplyHeader SubmitRequest(RequestHeader h, IRecord request, IRecord response, ZooKeeper.WatchRegistration watchRegistration) { ReplyHeader r = new ReplyHeader(); Packet p = QueuePacket(h, r, request, response, null, null, watchRegistration, null, null); if (!p.Task.Wait(SessionTimeout)) { throw new TimeoutException($"The request {request} timed out while waiting for a response from the server."); } return(r); }
public ReplyHeader SubmitRequest(RequestHeader h, IRecord request, IRecord response, ZooKeeper.WatchRegistration watchRegistration) { ReplyHeader r = new ReplyHeader(); Packet p = QueuePacket(h, r, request, response, null, null, watchRegistration, null, null); if (!p.WaitUntilFinishedSlim(SessionTimeout)) { throw new TimeoutException(new StringBuilder("The request ").Append(request).Append(" timed out while waiting for a response from the server.").ToString()); } return(r); }
/// <summary> /// Performs application-defined tasks associated with freeing, releasing, or resetting unmanaged resources. /// </summary> private void InternalDispose() { if (Interlocked.CompareExchange(ref isClosed, 1, 0) == 0) { //closing = true; if (LOG.IsDebugEnabled) { LOG.DebugFormat("Closing client for session: 0x{0:X}", SessionId); } try { ReplyHeader r = SubmitRequest(new RequestHeader { Type = (int)OpCode.CloseSession }, null, null, null); // @@@ Fixed a shutdown deadlock bug // @@@ Repro steps. // @@@ 1. Run ZooKeeper server // @@@ 2. Client (ZooKeeperNet) connect to the server and issue some commands // @@@ 3. Kill ZooKeeper server // @@@ 4. Close (exit) ZooKeeper client // @@@ // @@@ Added error code checking in ReplayHeader to prevent the infinite spin waiting. // @@@ TODO: It'd be a good idea add some waiting timeout inside the spin waiting loop. if (r.Err == 0 /* (int)KeeperException.Code.OK */) { SpinWait spin = new SpinWait(); while (!producer.IsConnectionClosedByServer) { spin.SpinOnce(); if (spin.Count > maxSpin) { spin.Reset(); } } } } catch (ThreadInterruptedException) { // ignore, close the send/event threads } catch (Exception ex) { LOG.WarnFormat("Error disposing {0} : {1}", this.GetType().FullName, ex.Message); } finally { producer.Dispose(); consumer.Dispose(); } } }
internal Packet(RequestHeader header, ReplyHeader replyHeader, IRecord request, IRecord response, byte[] data, ZooKeeper.WatchRegistration watchRegistration, string serverPath, string clientPath) { this.header = header; this.replyHeader = replyHeader; this.request = request; this.response = response; this.serverPath = serverPath; this.clientPath = clientPath; if (data != null) { this.data = data; } else { try { MemoryStream ms = new MemoryStream(); using (EndianBinaryWriter writer = new EndianBinaryWriter(EndianBitConverter.Big, ms, Encoding.UTF8)) { BinaryOutputArchive boa = BinaryOutputArchive.getArchive(writer); boa.WriteInt(-1, "len"); // We'll fill this in later if (header != null) { header.Serialize(boa, "header"); } if (request != null) { request.Serialize(boa, "request"); } ms.Position = 0; int len = Convert.ToInt32(ms.Length); // now we have the real length writer.Write(len - 4); // update the length info this.data = ms.ToArray(); } } #if !NET_CORE catch (IOException e) { LOG.Warn("Ignoring unexpected exception", e); } #endif #if NET_CORE catch (Exception e) { } #endif } this.watchRegistration = watchRegistration; }
public ReplyHeader SubmitRequest(RequestHeader h, IRecord request, IRecord response, ZooKeeper.WatchRegistration watchRegistration) { ReplyHeader r = new ReplyHeader(); Packet p = QueuePacket(h, r, request, response, null, null, watchRegistration, null, null); lock (p) { while (!p.Finished) { if (!Monitor.Wait(p, SessionTimeout)) { throw new TimeoutException(string.Format("The request {0} timed out while waiting for a resposne from the server.", request)); } } } return(r); }
public async Task <ReplyHeader> SubmitRequestAsync(RequestHeader h, IRecord request, IRecord response, ZooKeeper.WatchRegistration watchRegistration) { ReplyHeader r = new ReplyHeader(); Packet p = QueuePacket(h, r, request, response, null, null, watchRegistration, null, null); CancellationTokenSource cts = new CancellationTokenSource(); if (await Task.WhenAny(p.Task, Task.Delay(SessionTimeout, cts.Token)).ConfigureAwait(false) != p.Task) { throw new TimeoutException($"The request {request} timed out while waiting for a response from the server."); } cts.Cancel(); // we haven't timed out - cancel the timeout task await p.Task; // forces exceptions to be thrown correctly return(r); }
private async Task <Stat> SetDataAsyncInternal(string path, byte[] data, int version, bool sync) { 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); }
public ReplyHeader SubmitRequest(RequestHeader h, IRecord request, IRecord response, ZooKeeper.WatchRegistration watchRegistration) { ReplyHeader r = new ReplyHeader(); Packet p = QueuePacket(h, r, request, response, null, null, watchRegistration, null, null); SpinWait spin = new SpinWait(); DateTime start = DateTime.Now; // now wait for reply for the packet while (!p.Finished) { spin.SpinOnce(); if (spin.Count > ClientConnection.maxSpin) { if (DateTime.Now.Subtract(start) > SessionTimeout) { throw new TimeoutException(new StringBuilder("The request ").Append(request).Append(" timed out while waiting for a response from the server.").ToString()); } spin.Reset(); } } return(r); }
private async Task <IEnumerable <ACL> > GetACLAsyncInternal(string path, Stat stat, bool sync) { 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 = sync ? cnxn.SubmitRequest(h, request, response, null) : await cnxn.SubmitRequestAsync(h, request, response, null).ConfigureAwait(false); 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); }
public async Task testNonExistingOpCode() { DisconnectedWatcher disconnectedWatcher = new DisconnectedWatcher(); ZooKeeper zk = await createClient(disconnectedWatcher); const string path = "/m1"; RequestHeader h = new RequestHeader(); h.set_Type(888); // This code does not exists ExistsRequest request = new ExistsRequest(); request.setPath(path); request.setWatch(false); ExistsResponse response = new ExistsResponse(); ReplyHeader r = await zk.cnxn.submitRequest(h, request, response, null); Assert.assertEquals(r.getErr(), (int)KeeperException.Code.UNIMPLEMENTED); // Sending a nonexisting opcode should cause the server to disconnect Assert.assertTrue("failed to disconnect", await disconnectedWatcher.getTask().WithTimeout(5000)); }
public Packet QueuePacket(RequestHeader h, ReplyHeader r, IRecord request, IRecord response, string clientPath, string serverPath, ZooKeeper.WatchRegistration watchRegistration, object callback, object ctx) { return(producer.QueuePacket(h, r, request, response, clientPath, serverPath, watchRegistration)); }
private void PrimeConnection() { LOG.InfoFormat("Socket connection established to {0}, initiating session", client.Client.RemoteEndPoint); ConnectRequest conReq = new ConnectRequest(0, lastZxid, Convert.ToInt32(conn.SessionTimeout.TotalMilliseconds), conn.SessionId, conn.SessionPassword); Packet conPacket = new Packet(null, null, conReq, null, null, null, null, null); if (conn.saslClient != null) { lock (outgoingQueue) { // SASL negociation is synchronous, and must complete before we send the (non-SASL) auth data and // watches. We explicitly drive the send/receive as the queue processing loop is not active yet. // First, push the ConnectRequest down the pipe. DoSend(conPacket); conPacket = null; byte[] token = conn.saslClient.Start((IPEndPoint)client.Client.LocalEndPoint, (IPEndPoint)client.Client.RemoteEndPoint); try { bool lastPacket = false; do { RequestHeader h = new RequestHeader(); ReplyHeader r = new ReplyHeader(); h.Type = (int)OpCode.SASL; GetSASLRequest request = new GetSASLRequest(token != null ? token : new byte[0]); SetSASLResponse response = new SetSASLResponse(); Packet p = new Packet(h, r, request, response, null, null, null, null); // Push the packet. DoSend(p); // Synchronously wait for the response. if (!p.Task.Wait(conn.ConnectionTimeout)) { throw new TimeoutException($"The request {request} timed out while waiting for a response from the server."); } if (r.Err != 0) { throw KeeperException.Create((KeeperException.Code)Enum.ToObject(typeof(KeeperException.Code), r.Err)); } if (lastPacket) { break; } // SASL round. token = conn.saslClient.EvaluateChallenge(response.Token); if (conn.saslClient.IsCompleted) { if (conn.saslClient.HasLastPacket) { lastPacket = true; } else { break; } } } // We must have received a 'ConnectResponse' by // now, as we have waited for 1+ packets. while (zooKeeper.State.IsConnected()); } finally { conn.saslClient.Finish(); } } if (zooKeeper.State.IsConnected()) { conn.consumer.QueueEvent(new WatchedEvent(KeeperState.SaslAuthenticated, EventType.None, null)); } } bool hasOutgoingRequests; lock (outgoingQueue) { if (!ClientConnection.DisableAutoWatchReset && (!zooKeeper.DataWatches.IsEmpty() || !zooKeeper.ExistWatches.IsEmpty() || !zooKeeper.ChildWatches.IsEmpty())) { var sw = new SetWatches(lastZxid, prependChroot(zooKeeper.DataWatches), prependChroot(zooKeeper.ExistWatches), prependChroot(zooKeeper.ChildWatches)); var h = new RequestHeader(); h.Type = (int)OpCode.SetWatches; h.Xid = -8; Packet packet = new Packet(h, new ReplyHeader(), sw, null, null, null, null, null); //outgoingQueue.AddFirst(packet); addPacketFirst(packet); } foreach (ClientConnection.AuthData id in conn.authInfo) { addPacketFirst( new Packet(new RequestHeader(-4, (int)OpCode.Auth), null, new AuthPacket(0, id.Scheme, id.GetData()), null, null, null, null, null)); } // The ConnectRequest packet has already been sent in the SASL case. if (conPacket != null) { addPacketFirst(conPacket); conPacket = null; } hasOutgoingRequests = !outgoingQueue.IsEmpty(); } if (hasOutgoingRequests) { packetAre.Set(); } if (LOG.IsDebugEnabled) { LOG.DebugFormat("Session establishment request sent on {0}", client.Client.RemoteEndPoint); } }
private void ReadResponse(byte[] content) { using (var reader = new EndianBinaryReader(EndianBitConverter.Big, new MemoryStream(content), Encoding.UTF8)) { BinaryInputArchive bbia = BinaryInputArchive.GetArchive(reader); ReplyHeader replyHdr = new ReplyHeader(); replyHdr.Deserialize(bbia, "header"); if (replyHdr.Xid == -2) { // -2 is the xid for pings if (LOG.IsDebugEnabled) { LOG.DebugFormat("Got ping response for sessionid: 0x{0:X} after {1}ms", conn.SessionId, (DateTime.UtcNow.Nanos() - lastPingSentNs) / 1000000); } return; } if (replyHdr.Xid == -4) { // -2 is the xid for AuthPacket // TODO: process AuthPacket here if (LOG.IsDebugEnabled) { LOG.DebugFormat("Got auth sessionid:0x{0:X}", conn.SessionId); } return; } if (replyHdr.Xid == -1) { // -1 means notification if (LOG.IsDebugEnabled) { LOG.DebugFormat("Got notification sessionid:0x{0}", conn.SessionId); } WatcherEvent @event = new WatcherEvent(); @event.Deserialize(bbia, "response"); // convert from a server path to a client path if (conn.ChrootPath != null) { string serverPath = @event.Path; if (serverPath.CompareTo(conn.ChrootPath) == 0) { @event.Path = PathUtils.PathSeparator; } else { @event.Path = serverPath.Substring(conn.ChrootPath.Length); } } WatchedEvent we = new WatchedEvent(@event); if (LOG.IsDebugEnabled) { LOG.DebugFormat("Got {0} for sessionid 0x{1:X}", we, conn.SessionId); } conn.consumer.QueueEvent(we); return; } Packet packet; /* * Since requests are processed in order, we better get a response * to the first request! */ if (pendingQueue.TryDequeue(out packet)) { try { if (packet.header.Xid != replyHdr.Xid) { packet.replyHeader.Err = (int)KeeperException.Code.CONNECTIONLOSS; throw new IOException(new StringBuilder("Xid out of order. Got ").Append(replyHdr.Xid).Append(" expected ").Append(packet.header.Xid).ToString()); } packet.replyHeader.Xid = replyHdr.Xid; packet.replyHeader.Err = replyHdr.Err; packet.replyHeader.Zxid = replyHdr.Zxid; if (replyHdr.Zxid > 0) { lastZxid = replyHdr.Zxid; } if (packet.response != null && replyHdr.Err == 0) { packet.response.Deserialize(bbia, "response"); } if (LOG.IsDebugEnabled) { LOG.DebugFormat("Reading reply sessionid:0x{0:X}, packet:: {1}", conn.SessionId, packet); } } finally { FinishPacket(packet); } } else { throw new IOException(new StringBuilder("Nothing in the queue, but got ").Append(replyHdr.Xid).ToString()); } } }