示例#1
0
        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);
        }
示例#2
0
        /// <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));
        }
示例#3
0
            /** Convenience ctor */

            internal Packet(RequestHeader requestHeader, ReplyHeader replyHeader,
                            Record request, Record response,
                            ZooKeeper.WatchRegistration watchRegistration) :
                this(requestHeader, replyHeader, request, response,
                     watchRegistration, false)
            {
            }
示例#4
0
        /// <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);
            }
        }
示例#5
0
        /// <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);
        }
示例#6
0
        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);
            }
        }
示例#7
0
        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);
        }
示例#8
0
        /// <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);
        }
示例#9
0
        /// <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);
        }
示例#10
0
        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);
        }
示例#11
0
        /// <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);
        }
示例#12
0
        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) {
            }
        }
示例#13
0
        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);
        }
示例#14
0
        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);
        }
示例#15
0
 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;
 }
示例#16
0
 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;
 }
示例#17
0
        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);
        }
示例#18
0
        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);
        }
示例#19
0
        /// <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();
                }
            }
        }
示例#20
0
 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);
        }
示例#22
0
        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);
        }
示例#23
0
        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);
        }
示例#24
0
        /// <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);
        }
示例#25
0
        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);
        }
示例#26
0
        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);
        }
示例#27
0
        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));
        }
示例#28
0
 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));
 }
示例#29
0
        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);
            }
        }
示例#30
0
        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());
                }
            }
        }