/// <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(); } } }
/// <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)); }