Ejemplo n.º 1
0
        internal void Add(Guid databaseId, DatabaseLocationInfo dbLocationInfo)
        {
            bool flag = false;

            try
            {
                int num = 0;
                while (num < 2 && !flag)
                {
                    flag = this.m_rwlock.TryEnterWriteLock(DatabaseLocationCache.s_cacheLockTimeout);
                    num++;
                }
                if (flag)
                {
                    this.m_cache[databaseId] = new TimedDbInfo(dbLocationInfo);
                }
                else
                {
                    ExAssert.RetailAssert(false, "Timeout waiting for write lock in DatabaseLocationCache.Add()");
                }
            }
            finally
            {
                if (flag)
                {
                    this.m_rwlock.ExitWriteLock();
                }
            }
        }
Ejemplo n.º 2
0
        internal static void CalculatePreferredHomeServerInternal(ActiveManager activeManager, IADDatabase database, ITopologyConfigurationSession adSession, IFindAdObject <IADDatabaseAvailabilityGroup> dagLookup, IFindAdObject <IADClientAccessArray> findClientAccessArray, IFindMiniClientAccessServerOrArray findMiniClientAccessServer, out LegacyDN preferredRpcClientAccessServerLegacyDN, out ADObjectId preferredServerSite)
        {
            Util.ThrowOnNullArgument(activeManager, "activeManager");
            preferredRpcClientAccessServerLegacyDN = LegacyDN.Parse(database.RpcClientAccessServerLegacyDN);
            ADObjectId masterServerOrAvailabilityGroup = database.MasterServerOrAvailabilityGroup;
            IADDatabaseAvailabilityGroup iaddatabaseAvailabilityGroup = (masterServerOrAvailabilityGroup != null) ? dagLookup.ReadAdObjectByObjectId(masterServerOrAvailabilityGroup) : null;

            if (iaddatabaseAvailabilityGroup == null || !iaddatabaseAvailabilityGroup.AllowCrossSiteRpcClientAccess)
            {
                ExTraceGlobals.ActiveManagerClientTracer.TraceDebug <ADObjectId, ADObjectId>((long)activeManager.GetHashCode(), "CalculatePreferredHomeServerInternal: Cross-site is not allowed. Database = '{0}', DAG = '{1}'", database.Id, masterServerOrAvailabilityGroup);
                DatabaseLocationInfo databaseLocationInfo = null;
                preferredServerSite = null;
                try
                {
                    databaseLocationInfo = activeManager.GetServerForDatabase(database.Guid, GetServerForDatabaseFlags.IgnoreAdSiteBoundary, NullPerformanceDataLogger.Instance);
                    if (databaseLocationInfo != null)
                    {
                        preferredServerSite = databaseLocationInfo.ServerSite;
                    }
                }
                catch (DatabaseNotFoundException arg)
                {
                    ExTraceGlobals.ActiveManagerClientTracer.TraceDebug <ADObjectId, DatabaseNotFoundException>((long)activeManager.GetHashCode(), "CalculatePreferredHomeServerInternal: The database '{0}' does not exist. Exception = {1}", database.Id, arg);
                    preferredServerSite = null;
                }
                catch (ObjectNotFoundException arg2)
                {
                    ExTraceGlobals.ActiveManagerClientTracer.TraceDebug <ADObjectId, ObjectNotFoundException>((long)activeManager.GetHashCode(), "CalculatePreferredHomeServerInternal: Server hosting the database {0} cannot be found. Exception = {1}", database.Id, arg2);
                    preferredServerSite = null;
                }
                if (preferredServerSite == null)
                {
                    preferredRpcClientAccessServerLegacyDN = null;
                    return;
                }
                IADMiniClientAccessServerOrArray iadminiClientAccessServerOrArray = findMiniClientAccessServer.FindMiniClientAccessServerOrArrayByLegdn(databaseLocationInfo.RpcClientAccessServerLegacyDN);
                if (iadminiClientAccessServerOrArray != null && iadminiClientAccessServerOrArray.ServerSite != null && iadminiClientAccessServerOrArray.ServerSite.Equals(preferredServerSite))
                {
                    preferredRpcClientAccessServerLegacyDN = LegacyDN.Parse(databaseLocationInfo.RpcClientAccessServerLegacyDN);
                    return;
                }
                preferredRpcClientAccessServerLegacyDN = ActiveManagerImplementation.FindClientAccessArrayOrServerFromSite(preferredServerSite, database.HostServerForPreference1, findClientAccessArray, findMiniClientAccessServer, AdObjectLookupFlags.None);
                return;
            }
            else
            {
                IADMiniClientAccessServerOrArray iadminiClientAccessServerOrArray2 = findMiniClientAccessServer.FindMiniClientAccessServerOrArrayByLegdn(preferredRpcClientAccessServerLegacyDN.ToString());
                ExTraceGlobals.ActiveManagerClientTracer.TraceDebug <LegacyDN, string>((long)activeManager.GetHashCode(), "CalculatePreferredHomeServerInternal. preferredRpcClientAccessServerLegacyDN = {0}, preferredMiniServer = {1}.", preferredRpcClientAccessServerLegacyDN, (iadminiClientAccessServerOrArray2 == null) ? "<null>" : iadminiClientAccessServerOrArray2.Fqdn);
                if (iadminiClientAccessServerOrArray2 == null)
                {
                    preferredServerSite = null;
                    preferredRpcClientAccessServerLegacyDN = null;
                    return;
                }
                preferredRpcClientAccessServerLegacyDN = LegacyDN.Parse(iadminiClientAccessServerOrArray2.ExchangeLegacyDN);
                preferredServerSite = iadminiClientAccessServerOrArray2.ServerSite;
                return;
            }
        }
Ejemplo n.º 3
0
        private DatabaseLocationInfo GetServerInformationForDatabase(Guid databaseId, IADDatabase database, DatabaseLocationInfo dbLocationInfo, GetServerForDatabaseFlags gsfdFlags, IPerformanceDataLogger perfLogger)
        {
            if (database != null && databaseId != database.Guid)
            {
                throw new ArgumentException("When passing in database, its GUID must match databaseId.", "database");
            }
            ExTraceGlobals.ActiveManagerClientTracer.TraceFunction <Guid, DatabaseLocationInfo, int>((long)this.GetHashCode(), "Entering GetServerInformationForDatabase(Guid={0}, minimalLocationInfo={1}, Flags={2})", databaseId, dbLocationInfo, (int)gsfdFlags);
            this.DisposeCheck();
            bool flag  = (gsfdFlags & GetServerForDatabaseFlags.IgnoreAdSiteBoundary) != GetServerForDatabaseFlags.None;
            bool flag2 = (gsfdFlags & GetServerForDatabaseFlags.ReadThrough) != GetServerForDatabaseFlags.None;

            if (flag2 || dbLocationInfo.ServerLegacyDN == null)
            {
                if (database == null)
                {
                    AdObjectLookupFlags flags = flag2 ? AdObjectLookupFlags.ReadThrough : AdObjectLookupFlags.None;
                    using (new StopwatchPerformanceTracker("GetServerInformationForDatabaseGetDatabaseByGuidEx", perfLogger))
                    {
                        database = this.GetDatabaseByGuidEx(databaseId, flags, perfLogger);
                    }
                }
                ActiveManagerImplementation.GetServerInformationForDatabaseInternal(database, dbLocationInfo, this.m_miniServerLookup);
            }
            if (dbLocationInfo != null)
            {
                DatabaseLocationInfoResult databaseLocationInfoResult = dbLocationInfo.RequestResult;
                bool flag3 = false;
                if (flag && databaseLocationInfoResult == DatabaseLocationInfoResult.SiteViolation)
                {
                    databaseLocationInfoResult = DatabaseLocationInfoResult.Success;
                    flag3 = true;
                }
                if (flag && databaseLocationInfoResult == DatabaseLocationInfoResult.InTransitCrossSite)
                {
                    databaseLocationInfoResult = DatabaseLocationInfoResult.InTransitSameSite;
                    flag3 = true;
                }
                ExTraceGlobals.FaultInjectionTracer.TraceTest <DatabaseLocationInfoResult>(3831901501U, ref databaseLocationInfoResult);
                ExTraceGlobals.FaultInjectionTracer.TraceTest <bool>(2221288765U, ref flag3);
                if (flag3)
                {
                    ExTraceGlobals.ActiveManagerClientTracer.TraceDebug <DatabaseLocationInfoResult, DatabaseLocationInfoResult>((long)this.GetHashCode(), "GetServerForDatabase(): At the caller's request, changing the location info's result from {0} to {1}.", dbLocationInfo.RequestResult, databaseLocationInfoResult);
                    dbLocationInfo = DatabaseLocationInfo.CloneDatabaseLocationInfo(dbLocationInfo, databaseLocationInfoResult);
                }
            }
            if (ExTraceGlobals.ActiveManagerClientTracer.IsTraceEnabled(TraceType.DebugTrace))
            {
                ExTraceGlobals.ActiveManagerClientTracer.TraceDebug <Guid, DatabaseLocationInfo>((long)this.GetHashCode(), "Database Location Info ({0}) = {1}", databaseId, dbLocationInfo);
            }
            ExTraceGlobals.ActiveManagerClientTracer.TraceFunction <Guid>((long)this.GetHashCode(), "Exiting GetServerInformationForDatabase(Guid={0})", databaseId);
            return(dbLocationInfo);
        }
Ejemplo n.º 4
0
        private bool GetDbLocationInfoByRegistry(Guid databaseId, out DatabaseLocationInfo databaseLocationInfo)
        {
            databaseLocationInfo = null;
            if (this.m_key == null)
            {
                this.m_key = Registry.LocalMachine.OpenSubKey("SOFTWARE\\Microsoft\\ExchangeServer\\v15\\ActiveManager\\TestOverride", RegistryKeyPermissionCheck.ReadSubTree);
                if (this.m_key == null)
                {
                    ExTraceGlobals.ActiveManagerClientTracer.TraceDebug((long)this.GetHashCode(), "GetServerForDatabase failed opening the registry override key!");
                    return(false);
                }
                ExTraceGlobals.ActiveManagerClientTracer.TraceDebug((long)this.GetHashCode(), "Found registry override entry");
            }
            object value = this.m_key.GetValue(databaseId.ToString());

            if (value == null)
            {
                return(false);
            }
            string text = value as string;

            if (text == null)
            {
                throw new ArgumentException("Registry override for active server should be a string-typed value", "regValue");
            }
            string[] array = text.Split(new char[]
            {
                '|'
            });
            int num = array.Length;

            if (num == 3)
            {
                databaseLocationInfo = new DatabaseLocationInfo(array[0], array[1], ActiveManagerUtil.GetServerSiteFromServer(LocalServer.GetServer()), new ServerVersion(int.Parse(array[2], CultureInfo.InvariantCulture)), false);
                return(true);
            }
            if (num != 9)
            {
                throw new ArgumentException("Registry override for active server should be in a \"<fqdn>|<legacyDN>|<version>|<lastMountedServerFqdn>|<lastMountedServerLegacyDN>|<databaseLegacyDN>|<mountedTime>|<serverVersion>|<isHA>\" format", "databaseId");
            }
            databaseLocationInfo = new DatabaseLocationInfo(array[0], array[1], array[2], array[3], array[4], array[1], string.Empty, false, false, string.IsNullOrEmpty(array[5]) ? Guid.Empty : new Guid(array[5]), DateTime.Parse(array[6]), null, ActiveManagerUtil.GetServerSiteFromServer(LocalServer.GetServer()), new ServerVersion(int.Parse(array[7], CultureInfo.InvariantCulture)), MailboxRelease.None, DatabaseLocationInfoResult.Success, bool.Parse(array[8]));
            return(true);
        }
Ejemplo n.º 5
0
        private void DatabaseCacheUpdateCallback(object unusedState)
        {
            this.m_dbChaceUpdateStartTime = DateTime.UtcNow;
            Thread.CurrentPrincipal       = null;
            ExTraceGlobals.ActiveManagerClientTracer.TraceDebug((long)this.GetHashCode(), "Entering AM cache update callback");
            Guid[] array = this.m_dbCache.CopyDatabaseGuids();
            Dictionary <Guid, DatabaseLocationInfo> dictionary = new Dictionary <Guid, DatabaseLocationInfo>(array.Length);
            Dictionary <Guid, int> dictionary2 = new Dictionary <Guid, int>(array.Length);

            foreach (Guid guid in array)
            {
                if (this.m_stopCacheUpdate)
                {
                    break;
                }
                DatabaseLocationInfo databaseLocationInfo = null;
                int value = 0;
                try
                {
                    IADDatabase databaseByGuidEx = this.GetDatabaseByGuidEx(guid, AdObjectLookupFlags.None, NullPerformanceDataLogger.Instance);
                    databaseLocationInfo = ActiveManagerImplementation.GetServerNameForDatabaseInternal(databaseByGuidEx, this.m_networkCredential, this.m_dagLookup, this.m_miniServerLookup, this.m_perfCounters, false, this.m_isRunningInService);
                    if (ExTraceGlobals.ActiveManagerClientTracer.IsTraceEnabled(TraceType.DebugTrace))
                    {
                        ExTraceGlobals.ActiveManagerClientTracer.TraceDebug <Guid, DatabaseLocationInfo>((long)this.GetHashCode(), "(Cache update thread) Database Location Info ({0}) = {1}", guid, databaseLocationInfo);
                    }
                    value = 2;
                }
                catch (DataValidationException arg)
                {
                    ExTraceGlobals.ActiveManagerClientTracer.TraceDebug <Guid, DataValidationException>((long)this.GetHashCode(), "Some of the Database {0} properties are invalid (exception: {1})", guid, arg);
                }
                catch (ServerForDatabaseNotFoundException arg2)
                {
                    ExTraceGlobals.ActiveManagerClientTracer.TraceDebug <Guid, ServerForDatabaseNotFoundException>((long)this.GetHashCode(), "Server for database {0} not found (exception: {1})", guid, arg2);
                }
                catch (ObjectNotFoundException arg3)
                {
                    ExTraceGlobals.ActiveManagerClientTracer.TraceDebug <Guid, ObjectNotFoundException>((long)this.GetHashCode(), "Database {0} does not exist anymore (exception: {1})", guid, arg3);
                }
                catch (StorageTransientException arg4)
                {
                    ExTraceGlobals.ActiveManagerClientTracer.TraceDebug <Guid, StorageTransientException>((long)this.GetHashCode(), "GetSFD({0}) generated exception {1}", guid, arg4);
                }
                catch (StoragePermanentException arg5)
                {
                    ExTraceGlobals.ActiveManagerClientTracer.TraceDebug <Guid, StoragePermanentException>((long)this.GetHashCode(), "GetSFD({0}) generated exception {1}", guid, arg5);
                }
                catch (DataSourceOperationException arg6)
                {
                    ExTraceGlobals.ActiveManagerClientTracer.TraceDebug <Guid, DataSourceOperationException>((long)this.GetHashCode(), "GetSFD({0}) generated exception {1}", guid, arg6);
                }
                catch (DataSourceTransientException arg7)
                {
                    ExTraceGlobals.ActiveManagerClientTracer.TraceDebug <Guid, DataSourceTransientException>((long)this.GetHashCode(), "GetSFD({0}) generated exception {1}", guid, arg7);
                }
                catch (AmDatabaseMasterIsInvalid arg8)
                {
                    ExTraceGlobals.ActiveManagerClientTracer.TraceDebug <Guid, AmDatabaseMasterIsInvalid>((long)this.GetHashCode(), "GetSFD({0}) generated exception {1}", guid, arg8);
                }
                catch (AmDatabaseADException arg9)
                {
                    ExTraceGlobals.ActiveManagerClientTracer.TraceDebug <Guid, AmDatabaseADException>((long)this.GetHashCode(), "GetSFD({0}) generated exception {1}", guid, arg9);
                }
                dictionary[guid]  = databaseLocationInfo;
                dictionary2[guid] = value;
            }
            if (!this.m_stopCacheUpdate)
            {
                this.m_dbCache.Update(dictionary, this.m_cacheExpiryThreshold, dictionary2);
            }
            TimeSpan arg10 = DateTime.UtcNow - this.m_dbChaceUpdateStartTime;

            try
            {
                this.m_perfCounters.CacheUpdateTimeInSec.RawValue = (long)arg10.TotalSeconds;
            }
            catch (InvalidOperationException)
            {
                ExTraceGlobals.ActiveManagerClientTracer.TraceError((long)this.GetHashCode(), "Perf counters are broken. Please use lodctr to add them back");
            }
            ExTraceGlobals.ActiveManagerClientTracer.TraceDebug <TimeSpan>((long)this.GetHashCode(), "Leaving AM cache update callback. Time in callback {0}.", arg10);
            if ((long)arg10.TotalMilliseconds > 120000L)
            {
                ExTraceGlobals.ActiveManagerClientTracer.TraceDebug <TimeSpan, int>((long)this.GetHashCode(), "AM cache update callback took longer than expected. Time in callback {0}. Maximum time is {1} msec. Cache will be cleared as mitigation.", arg10, 120000);
                this.m_dbCache.Clear();
            }
        }
Ejemplo n.º 6
0
        private DatabaseLocationInfo LookupDatabaseAndPossiblyPopulateCache(IADDatabase database, bool throwOnErrors)
        {
            DatabaseLocationInfo databaseLocationInfo = null;

            if (this.m_isCacheEnabled)
            {
                bool flag = false;
                try
                {
                    flag = this.m_dbCache.CheckAndSetRPCLock(database.Guid);
                    if (flag)
                    {
                        databaseLocationInfo = ActiveManagerImplementation.GetServerNameForDatabaseInternal(database, this.m_networkCredential, this.m_dagLookup, this.m_miniServerLookup, this.m_perfCounters, throwOnErrors, this.m_isRunningInService);
                    }
                }
                finally
                {
                    if (flag)
                    {
                        this.m_dbCache.ReleaseRPCLock(database.Guid);
                    }
                }
                if (databaseLocationInfo == null)
                {
                    ExTraceGlobals.ActiveManagerClientTracer.TraceError <ADObjectId>((long)this.GetHashCode(), "DatabaseLocationInfo for Database {0} is null because some other thread is already trying to do RPC.", database.Id);
                    if (throwOnErrors)
                    {
                        throw new ServerForDatabaseNotFoundException(database.Name, database.Guid.ToString(), new RPCOperationAbortedBecauseOfAnotherRPCThreadException());
                    }
                    databaseLocationInfo = new DatabaseLocationInfo(null, null, null, null, null, null, string.Empty, false, false, Guid.Empty, DateTime.MinValue, null, null, null, MailboxRelease.None, DatabaseLocationInfoResult.Unknown, false);
                }
            }
            else
            {
                databaseLocationInfo = ActiveManagerImplementation.GetServerNameForDatabaseInternal(database, this.m_networkCredential, this.m_dagLookup, this.m_miniServerLookup, this.m_perfCounters, throwOnErrors, this.m_isRunningInService);
            }
            if (databaseLocationInfo != null)
            {
                if (this.m_isCacheEnabled)
                {
                    this.m_dbCache.Add(database.Guid, databaseLocationInfo);
                    if (!this.m_stopCacheUpdate)
                    {
                        this.StartOrRefreshPeriodicCacheUpdate();
                    }
                }
            }
            else
            {
                ExTraceGlobals.ActiveManagerClientTracer.TraceError <ADObjectId>((long)this.GetHashCode(), "DatabaseLocationInfo for Database {0} is null.", database.Id);
            }
            try
            {
                this.m_perfCounters.GetServerForDatabaseClientLocationCacheEntries.RawValue = (long)this.m_dbCache.Count;
            }
            catch (InvalidOperationException)
            {
                ExTraceGlobals.ActiveManagerClientTracer.TraceError((long)this.GetHashCode(), "Perf counters are broken. Please use lodctr to add them back");
            }
            return(databaseLocationInfo);
        }
Ejemplo n.º 7
0
        public static ActiveManagerOperationResult TryGetCachedServerForDatabaseBasic(Guid mdbGuid, GetServerForDatabaseFlags gsfdFlags, out DatabaseLocationInfo databaseLocationInfo)
        {
            Exception ex = null;

            databaseLocationInfo = null;
            ActiveManager cachingActiveManagerInstance = ActiveManager.GetCachingActiveManagerInstance();

            try
            {
                databaseLocationInfo = cachingActiveManagerInstance.GetServerForDatabase(mdbGuid, gsfdFlags, NullPerformanceDataLogger.Instance);
                return(new ActiveManagerOperationResult(true, ex));
            }
            catch (DatabaseNotFoundException ex2)
            {
                ex = ex2;
            }
            catch (ObjectNotFoundException ex3)
            {
                ex = ex3;
            }
            catch (StoragePermanentException ex4)
            {
                ex = ex4;
            }
            catch (StorageTransientException ex5)
            {
                ex = ex5;
            }
            catch (ServerForDatabaseNotFoundException ex6)
            {
                ex = ex6;
            }
            return(new ActiveManagerOperationResult(false, ex));
        }
Ejemplo n.º 8
0
 public static ActiveManagerOperationResult TryGetCachedServerForDatabaseBasic(Guid mdbGuid, out DatabaseLocationInfo databaseLocationInfo)
 {
     return(ActiveManager.TryGetCachedServerForDatabaseBasic(mdbGuid, GetServerForDatabaseFlags.IgnoreAdSiteBoundary | GetServerForDatabaseFlags.BasicQuery, out databaseLocationInfo));
 }
Ejemplo n.º 9
0
 internal TimedDbInfo(DatabaseLocationInfo dbInfo)
 {
     this.m_dbInfo = dbInfo;
     this.m_negativeExpiringCounter = 0;
 }
Ejemplo n.º 10
0
 internal virtual bool Equals(DatabaseLocationInfo cmpObj)
 {
     return(cmpObj != null && (this.DatabaseIsPublic == cmpObj.DatabaseIsPublic && this.DatabaseIsRestored == cmpObj.DatabaseIsRestored && this.IsDatabaseHighlyAvailable == cmpObj.IsDatabaseHighlyAvailable && this.HomePublicFolderDatabaseGuid == cmpObj.HomePublicFolderDatabaseGuid && this.MailboxRelease == cmpObj.MailboxRelease && this.RequestResult == cmpObj.RequestResult && string.Equals(this.DatabaseLegacyDN, cmpObj.DatabaseLegacyDN) && string.Equals(this.DatabaseName, cmpObj.DatabaseName) && string.Equals(this.LastMountedServerFqdn, cmpObj.LastMountedServerFqdn) && string.Equals(this.LastMountedServerLegacyDN, cmpObj.LastMountedServerLegacyDN) && string.Equals(this.RpcClientAccessServerLegacyDN, cmpObj.RpcClientAccessServerLegacyDN) && string.Equals(this.ServerFqdn, cmpObj.ServerFqdn) && string.Equals(this.ServerLegacyDN, cmpObj.ServerLegacyDN) && this.MountedTime.Equals(cmpObj.MountedTime) && (object.ReferenceEquals(this.ServerSite, cmpObj.ServerSite) || (this.ServerSite != null && this.ServerSite.Equals(cmpObj.ServerSite)))));
 }
Ejemplo n.º 11
0
 internal bool DetectFailover(DatabaseLocationInfo oldDatabaseLocationInfo)
 {
     return(this.ServerSite != oldDatabaseLocationInfo.ServerSite || this.ServerLegacyDN != oldDatabaseLocationInfo.ServerLegacyDN);
 }
Ejemplo n.º 12
0
 internal static DatabaseLocationInfo CloneDatabaseLocationInfo(DatabaseLocationInfo right, DatabaseLocationInfoResult requestResult)
 {
     return(new DatabaseLocationInfo(right.ServerFqdn, right.ServerLegacyDN, right.LastMountedServerFqdn, right.LastMountedServerLegacyDN, right.DatabaseLegacyDN, right.RpcClientAccessServerLegacyDN, right.DatabaseName, right.DatabaseIsPublic, right.DatabaseIsRestored, right.HomePublicFolderDatabaseGuid, right.MountedTime, right.serverGuid, right.ServerSite, right.AdminDisplayVersion, right.MailboxRelease, requestResult, right.IsDatabaseHighlyAvailable));
 }
Ejemplo n.º 13
0
        internal static void GetServerInformationForDatabaseInternal(IADDatabase database, DatabaseLocationInfo minimalLocationInfo, IFindMiniServer findMiniServer)
        {
            Guid       guid = database.Guid;
            string     lastMountedServerFqdn = minimalLocationInfo.LastMountedServerFqdn;
            IADServer  iadserver             = null;
            ADObjectId adobjectId            = null;
            string     serverFqdn            = minimalLocationInfo.ServerFqdn;

            if (serverFqdn != null)
            {
                iadserver = findMiniServer.FindMiniServerByFqdn(serverFqdn);
            }
            else
            {
                ExTraceGlobals.ActiveManagerClientTracer.TraceDebug <string>(0L, "GetServerInformationForDatabaseInternal({0}) is falling back to database.Server from AD, which may be stale.", database.Name);
                iadserver = findMiniServer.ReadMiniServerByObjectId(database.Server);
            }
            if (iadserver == null)
            {
                throw new UnableToFindServerForDatabaseException(database.Name, guid.ToString());
            }
            ADObjectId serverSiteFromMiniServer = ActiveManagerUtil.GetServerSiteFromMiniServer(iadserver);
            string     fqdn = iadserver.Fqdn;

            if (iadserver.IsExchange2007OrLater && (serverSiteFromMiniServer == null || string.IsNullOrEmpty(fqdn) || (iadserver.IsExchange2007OrLater && !iadserver.IsMailboxServer)))
            {
                throw new UnableToFindServerForDatabaseException(database.Name, guid.ToString());
            }
            if (string.Equals(lastMountedServerFqdn, serverFqdn, StringComparison.OrdinalIgnoreCase))
            {
                adobjectId = iadserver.Id;
            }
            else
            {
                adobjectId = ActiveManagerImplementation.TryGetServerIdByFqdn(findMiniServer, lastMountedServerFqdn);
            }
            if (adobjectId == null)
            {
                ExTraceGlobals.ActiveManagerClientTracer.TraceDebug <ADObjectId>(0L, "lastMountedServer was null. Setting to the current server ({0}).", iadserver.Id);
                adobjectId = iadserver.Id;
            }
            DatabaseLocationInfoResult requestResult = DatabaseLocationInfoResult.Success;
            IADServer iadserver2 = null;

            if (iadserver.Id.Equals(adobjectId))
            {
                iadserver2 = iadserver;
            }
            else
            {
                try
                {
                    iadserver2 = findMiniServer.ReadMiniServerByObjectId(adobjectId);
                }
                catch (ADTransientException arg)
                {
                    ActiveManagerImplementation.Tracer.TraceDebug <ADTransientException>(0L, "ReadMiniServer() threw an ADTransientException: {0}", arg);
                }
            }
            IADToplogyConfigurationSession adSession = findMiniServer.AdSession;
            IADSite iadsite = ActiveManagerImplementation.RetrieveLocalSite(adSession);

            if (iadsite == null)
            {
                ExTraceGlobals.ActiveManagerClientTracer.TraceDebug(0L, "GetServerForDatabase detected an Unknown state! adSession.GetLocalSite() is null.");
                requestResult = DatabaseLocationInfoResult.Unknown;
            }
            else if (iadserver2 == null)
            {
                ExTraceGlobals.ActiveManagerClientTracer.TraceDebug <ADObjectId>(0L, "GetServerForDatabase detected an Unknown state! lastMountedServerId ({0}) could not be resolved.", adobjectId);
                requestResult = DatabaseLocationInfoResult.Unknown;
            }
            else if (!iadserver.Id.Equals(adobjectId))
            {
                ADObjectId serverSiteFromMiniServer2 = ActiveManagerUtil.GetServerSiteFromMiniServer(iadserver2);
                if (serverSiteFromMiniServer == serverSiteFromMiniServer2 || (serverSiteFromMiniServer != null && serverSiteFromMiniServer.Equals(serverSiteFromMiniServer2)))
                {
                    ExTraceGlobals.ActiveManagerClientTracer.TraceDebug(0L, "GetServerForDatabase detected InTransitSameSite! masterServer (name={0},site={1}), lastMountedServer (name={2},site={3}.", new object[]
                    {
                        iadserver.Id,
                        serverSiteFromMiniServer,
                        adobjectId,
                        serverSiteFromMiniServer2
                    });
                    requestResult = DatabaseLocationInfoResult.InTransitSameSite;
                }
                else
                {
                    ExTraceGlobals.ActiveManagerClientTracer.TraceDebug(0L, "GetServerForDatabase detected InTransitCrossSite! masterServer (name={0},site={1}), lastMountedServer (name={2},site={3}.", new object[]
                    {
                        iadserver.Id,
                        serverSiteFromMiniServer,
                        adobjectId,
                        serverSiteFromMiniServer2
                    });
                    requestResult = DatabaseLocationInfoResult.InTransitCrossSite;
                }
            }
            else if (!iadsite.Id.Equals(serverSiteFromMiniServer))
            {
                ExTraceGlobals.ActiveManagerClientTracer.TraceDebug <ADObjectId, ADObjectId>(0L, "GetServerForDatabase detected a SiteViolation! GetLocalSite().Id != serverSiteId ({0} != {1}).", iadsite.Id, serverSiteFromMiniServer);
                requestResult = DatabaseLocationInfoResult.SiteViolation;
            }
            string        exchangeLegacyDN    = iadserver.ExchangeLegacyDN;
            ServerVersion adminDisplayVersion = iadserver.AdminDisplayVersion;
            Guid          objectGuid          = iadserver.Id.ObjectGuid;
            string        exchangeLegacyDN2   = iadserver2.ExchangeLegacyDN;

            iadserver2 = null;
            ExTraceGlobals.ActiveManagerClientTracer.TraceDebug <Guid>(0L, "GetServerInformationForDatabaseInternal: Updating the location information for {0} in place.", guid);
            ADObjectId mailboxPublicFolderDatabase = database.MailboxPublicFolderDatabase;

            minimalLocationInfo.UpdateInPlace(fqdn, exchangeLegacyDN, minimalLocationInfo.LastMountedServerFqdn, exchangeLegacyDN2, database.ExchangeLegacyDN, database.RpcClientAccessServerLegacyDN, database.Name, database.IsPublicFolderDatabase, database.Recovery, (mailboxPublicFolderDatabase != null) ? mailboxPublicFolderDatabase.ObjectGuid : Guid.Empty, minimalLocationInfo.MountedTime, new Guid?(objectGuid), serverSiteFromMiniServer, adminDisplayVersion, iadserver.MailboxRelease, requestResult, minimalLocationInfo.IsDatabaseHighlyAvailable);
        }
Ejemplo n.º 14
0
        internal void Update(Dictionary <Guid, DatabaseLocationInfo> newCache, int expiryThreshold, Dictionary <Guid, int> negativeExpiryThresholds)
        {
            bool flag = false;

            try
            {
                int num = 0;
                while (num < 2 && !flag)
                {
                    flag = this.m_rwlock.TryEnterWriteLock(DatabaseLocationCache.s_cacheLockTimeout);
                    num++;
                }
                if (flag)
                {
                    foreach (KeyValuePair <Guid, DatabaseLocationInfo> keyValuePair in newCache)
                    {
                        Guid key = keyValuePair.Key;
                        DatabaseLocationInfo value       = keyValuePair.Value;
                        TimedDbInfo          timedDbInfo = null;
                        if (this.m_cache.TryGetValue(key, out timedDbInfo))
                        {
                            timedDbInfo.ExpiringCounter++;
                            if (!timedDbInfo.IsExpired(expiryThreshold) && value != null)
                            {
                                if (!value.Equals(timedDbInfo.DbLocationInfo))
                                {
                                    timedDbInfo.DbLocationInfo = value;
                                }
                            }
                            else if (value == null)
                            {
                                timedDbInfo.NegativeExpiringCounter++;
                                if (timedDbInfo.IsNegativeCacheExpired(negativeExpiryThresholds[key]))
                                {
                                    ExTraceGlobals.ActiveManagerClientTracer.TraceDebug <Guid>((long)this.GetHashCode(), "RPC to find database {0} was not succesful and negative expire threshold was reached, removing database from cache.", key);
                                    this.m_cache.Remove(key);
                                }
                                else
                                {
                                    ExTraceGlobals.ActiveManagerClientTracer.TraceDebug <Guid>((long)this.GetHashCode(), "RPC to find database {0} was not succesful but negative expire threshold is not reached, keeping stale info in the cache.", key);
                                }
                            }
                            else
                            {
                                ExTraceGlobals.ActiveManagerClientTracer.TraceDebug <Guid>((long)this.GetHashCode(), "Removing database {0} from cache since the expiry threshold has reached", key);
                                this.m_cache.Remove(key);
                            }
                        }
                    }
                    ExTraceGlobals.ActiveManagerClientTracer.TraceDebug <int>((long)this.GetHashCode(), "Total number of elements in database cache = {0}", this.m_cache.Count);
                }
                else
                {
                    ExAssert.RetailAssert(false, "Timeout waiting for write lock in DatabaseLocationCache.Update()");
                }
            }
            finally
            {
                if (flag)
                {
                    this.m_rwlock.ExitWriteLock();
                }
            }
        }