/// <summary>
            /// sets up the tree for commands, with the given Acls and structure
            /// </summary>
            internal void SetupCommandTree()
            {
                // instantiate a fake session with proper credentials
                ClientSession ses = this.backend.GetLoopbackSession(RMCommands.CommanderDigest);

                try
                {
                    // extract the digest from Auth, and build Acls
                    string[] digestieces = ses.Auth.ClientDigest.Split(':');

                    List <Acl> acls = null;
                    if (digestieces.Length == 2)
                    {
                        acls = new List <Acl>()
                        {
                            new Acl((int)Perm.ALL, new Id(digestieces[0], digestieces[1]))
                        };
                    }

                    // now, build the tree
                    RequestResponse resp;

                    // try to create the path to the commands node, with the Acls
                    resp = this.backend.ProcessMessage(new RequestCreate(this.backend.ReplicaCommandPathPrefix, null, null, acls, CreateMode.PersistentAllowPathCreation, null), ses);
                    Trace.TraceInformation("SetupCommandTree: create({0})-->{1}", this.backend.ReplicaCommandPathPrefix, (Code)resp.ResultCode);

                    bool needsAcl = true;

                    // try to override the ACls, in case those were wrong
                    Stat anyStat = new Stat();
                    anyStat.Aversion = anyStat.Cversion = anyStat.Version = -1;
                    resp             = this.backend.ProcessMessage(new RequestGetAcl(this.backend.ReplicaCommandPathPrefix, null, anyStat, null), ses);

                    if (resp != null && resp.ResultCode == (int)Code.Ok)
                    {
                        IList <Acl> prevAcl = resp.Content as IList <Acl>;

                        if (EqualityHelper.Equals(acls, prevAcl))
                        {
                            needsAcl = false;
                        }
                    }

                    if (needsAcl)
                    {
                        // try to override the ACls, in case those were wrong
                        resp = this.backend.ProcessMessage(new RequestSetAcl(this.backend.ReplicaCommandPathPrefix, null, acls, -1, null), ses);
                        Trace.TraceInformation("SetupCommandTree: setacl({0})-->{1}", this.backend.ReplicaCommandPathPrefix, (Code)resp.ResultCode);
                    }
                    else
                    {
                        Trace.TraceInformation("SetupCommandTree: setacl({0})-->{1}", this.backend.ReplicaCommandPathPrefix, "not needed");
                    }

                    // now we add the paths we need to have
                    List <string> paths = new List <string>()
                    {
                        this.thisCommandPathPrimary,
                        this.thisCommandPathOneSecondary,
                        this.thisCommandPathAllReplicas,
                        this.thisCommandPathAllSecondaries,
                    };

                    // append the instance command nodes
                    foreach (ClusterMember m in this.backend.Factory.GetAgreedMembers())
                    {
                        paths.Add(this.backend.ReplicaCommandPathPrefix + "/$$" + m.MemberId);
                    }

                    // create the command nodes
                    foreach (string path in paths)
                    {
                        resp = this.backend.ProcessMessage(new RequestCreate(path, null, null, null, CreateMode.Persistent, null), ses);
                        Trace.TraceInformation("SetupCommandTree: create({0})-->{1}", path, (Code)resp.ResultCode);
                    }
                }
                finally
                {
                    if (ses != null)
                    {
                        ses.Close();
                    }
                }
            }
Example #2
0
        /// <summary>
        /// Completes the actions for terminating a session.
        /// </summary>
        protected virtual void CompleteTermination()
        {
            Trace.TraceInformation("ClientSession[{0}]: Executing terminate actions", this.SessionId);

            try
            {
                List <KeyValuePair <string, Action <bool> > > torun = null;
                this.actionsOnTerminateLock.EnterWriteLock();

                try
                {
                    if (this.actionsOnTerminate != null)
                    {
                        // we need a copy of the list because the actions can modify the collection itself
                        torun = new List <KeyValuePair <string, Action <bool> > >(this.actionsOnTerminate);

                        this.actionsOnTerminate = null;
                    }

                    this.State = SessionState.Terminating;
                }
                finally
                {
                    this.actionsOnTerminateLock.ExitWriteLock();
                }

                if (torun != null)
                {
                    Trace.TraceInformation("ClientSession[{0}]: Running terminate actions. count={1}", this.SessionId, torun.Count);
                    int watcherTerminateActionsCount = 0;

                    // Run the watcher terminate actions first.
                    foreach (KeyValuePair <string, Action <bool> > item in torun)
                    {
                        if (item.Key.StartsWith("watcher-"))
                        {
                            watcherTerminateActionsCount++;
                            item.Value(true);
                        }
                    }

                    ClientSession.RemoveAllBulkWatchers(this.SessionId);

                    // Then run the non watcher terminate actions.
                    foreach (KeyValuePair <string, Action <bool> > item in torun)
                    {
                        if (!item.Key.StartsWith("watcher-"))
                        {
                            item.Value(true);
                        }
                    }

                    Trace.TraceInformation("ClientSession[{0}]: Completed terminate actions. count={1}, watcherTerminateActionsCount={2}", this.SessionId, torun.Count, watcherTerminateActionsCount);
                }

                this.State = SessionState.Closed;
            }
            finally
            {
                if (this.OnTerminated != null)
                {
                    this.OnTerminated();
                }
            }

            Trace.WriteLine(string.Format("ClientSession[{0}]: Terminated", this.SessionId));
        }