/// <summary>
        /// release resources.
        /// </summary>
        /// <param name="dispose">a value indicating whether release the resources.</param>
        protected virtual void Dispose(bool dispose)
        {
            if (dispose)
            {
                if (this.brokerNodeTimer != null)
                {
                    this.brokerNodeTimer.Dispose();
                    this.brokerNodeTimer = null;
                }

                if (this.schedulerField != null)
                {
                    this.schedulerField.Close();
                    this.schedulerField.Dispose();
                    this.schedulerField = null;
                }

                if (this.failoverClusterConnections != null)
                {
                    lock (this.failoverClusterConnections)
                    {
                        foreach (KeyValuePair <string, IntPtr> connection in this.failoverClusterConnections)
                        {
                            try
                            {
                                Win32API.CloseCluster(connection.Value);
                            }
                            catch (Exception ex)
                            {
                                TraceHelper.TraceEvent(TraceEventType.Warning, "[BrokerNodesManager].Dispose: Exception {0}", ex);
                            }   // Shutting down so just swallow exceptions
                        }
                    }

                    this.failoverClusterConnections = null;
                }
            }
        }
Beispiel #2
0
        /// <summary>
        /// Get broker's identity. If on a failover cluster, get resoruce group network name
        /// computer account login token
        /// Notice: This method returns null if it is not failover cluster or it is Azure cluster.
        /// </summary>
        /// <returns></returns>
        private static WindowsIdentity GetBrokerIdentity()
        {
            if (SoaHelper.IsOnAzure())
            {
                // Skip following logic if it is on Azure.
                return(null);
            }

            int clusterState = (int)ClusterState.ClusterStateNotInstalled;

            uint ret = Win32API.GetNodeClusterState(null, out clusterState);

            if (ret != 0)
            {
                TraceHelper.TraceEvent(TraceEventType.Error, "Cannot access local failover cluster state. Error = {0}", ret);
                return(null);
            }

            if (clusterState == (int)ClusterState.ClusterStateNotConfigured || clusterState == (int)ClusterState.ClusterStateNotInstalled)
            {
                TraceHelper.TraceEvent(TraceEventType.Information, "Cannot access local failover cluster state. Error = {0}", ret);
                return(null);
            }

            IntPtr hCluster  = IntPtr.Zero;
            IntPtr hResource = IntPtr.Zero;

            try
            {
                // Get handle to local failover cluster
                hCluster = Win32API.OpenCluster(null);
                if (hCluster == IntPtr.Zero)
                {
                    TraceHelper.TraceEvent(TraceEventType.Error, "Cannot connect to local failover cluster. Error = {0}", Marshal.GetLastWin32Error());
                    return(null);
                }

                // Get handle to this broker's network name resource
                hResource = Win32API.OpenClusterResource(hCluster, Environment.MachineName);
                if (hResource == IntPtr.Zero)
                {
                    TraceHelper.TraceEvent(TraceEventType.Error, "Cannot connect to local failover cluster. Error = {0}", Marshal.GetLastWin32Error());
                    return(null);
                }

                // Get the login token of the network name for the broker's resource group's network name. This
                // is a computer account login token and is use to impersonate all calls to the services. The services
                // then ensure calls are only from broker nodes or resource groups.
                IntPtr loginToken = IntPtr.Zero;

                try
                {
                    loginToken = GetNetworkNameLoginToken(hCluster, hResource);

                    if (loginToken != IntPtr.Zero)
                    {
                        // Put login token in a WindowsIdentity object
                        // WindowsIdentity calls DuplicateToken and it is fine to close the handle later
                        return(new WindowsIdentity(loginToken));
                    }
                    else
                    {
                        return(null);
                    }
                }
                finally
                {
                    if (loginToken != IntPtr.Zero)
                    {
                        Win32API.CloseHandle(loginToken);
                    }
                }
            }

            finally
            {
                if (hResource != IntPtr.Zero)
                {
                    Win32API.CloseClusterResource(hResource);
                }

                if (hCluster != IntPtr.Zero)
                {
                    Win32API.CloseCluster(hCluster);
                }
            }
        }