private void PopulateSingleServerMetrics(ADServerMetrics dcMetrics) { Exception ex = null; try { ExTraceGlobals.ResourceHealthManagerTracer.TraceDebug <string>((long)this.GetHashCode(), "[ADMetrics::PopulateSingleServerMetrics] Reading metrics for {0}.", dcMetrics.DnsHostName); string text; LocalizedString localizedString; if (!SuitabilityVerifier.IsServerSuitableIgnoreExceptions(dcMetrics.DnsHostName, false, null, out text, out localizedString)) { ExTraceGlobals.ResourceHealthManagerTracer.TraceError <string, LocalizedString>((long)this.GetHashCode(), "[ADMetrics::PopulateSingleServerMetrics] Suitability checks failed for {0}: {1}", dcMetrics.DnsHostName, localizedString); dcMetrics.ErrorMessage = localizedString; return; } ITopologyConfigurationSession topologyConfigurationSession = DirectorySessionFactory.Default.CreateTopologyConfigurationSession(dcMetrics.DnsHostName, true, ConsistencyMode.PartiallyConsistent, null, ADSessionSettings.FromAccountPartitionRootOrgScopeSet(new PartitionId(this.forestFqdn)), 470, "PopulateSingleServerMetrics", "f:\\15.00.1497\\sources\\dev\\data\\src\\directory\\throttling\\ResourceHealth\\ADMetrics.cs"); topologyConfigurationSession.UseGlobalCatalog = false; ExDateTime utcNow = ExDateTime.UtcNow; RootDse rootDse = topologyConfigurationSession.GetRootDse(); dcMetrics.IsSynchronized = rootDse.IsSynchronized; if (!dcMetrics.IsSynchronized) { ExTraceGlobals.ResourceHealthManagerTracer.TraceError <string>((long)this.GetHashCode(), "[ADMetrics::PopulateSingleServerMetrics] {0} is not synchronized yet.", dcMetrics.DnsHostName); return; } MultiValuedProperty <ReplicationCursor> source; MultiValuedProperty <ReplicationNeighbor> neighbors; topologyConfigurationSession.ReadReplicationData(topologyConfigurationSession.ConfigurationNamingContext, out source, out neighbors); IEnumerable <ReplicationCursor> replicationCursors = from cursor in source where neighbors.Any((ReplicationNeighbor neighbor) => this.NotNullAndEquals(neighbor.SourceDsa, cursor.SourceDsa)) select cursor; ICollection <ADReplicationLinkMetrics> configReplicationMetrics = this.ReadReplicationMetrics(replicationCursors); topologyConfigurationSession.UseConfigNC = false; topologyConfigurationSession.ReadReplicationData(dcMetrics.ServerId.DomainId, out source, out neighbors); replicationCursors = from cursor in source where neighbors.Any((ReplicationNeighbor neighbor) => this.NotNullAndEquals(neighbor.SourceDsa, cursor.SourceDsa)) select cursor; ICollection <ADReplicationLinkMetrics> domainReplicationMetrics = this.ReadReplicationMetrics(replicationCursors); dcMetrics.Initialize(utcNow, rootDse.HighestCommittedUSN, configReplicationMetrics, domainReplicationMetrics); dcMetrics.IsSuitable = true; ExTraceGlobals.ResourceHealthManagerTracer.TraceDebug <string>((long)this.GetHashCode(), "[ADMetrics::PopulateSingleServerMetrics] Finished reading metrics for {0}.", dcMetrics.DnsHostName); } catch (ADTransientException ex2) { ex = ex2; } catch (ADOperationException ex3) { ex = ex3; } catch (OperationCanceledException ex4) { ex = ex4; } if (ex != null) { ExTraceGlobals.ResourceHealthManagerTracer.TraceError <string, Exception>((long)this.GetHashCode(), "[ADMetrics::PopulateSingleServerMetrics] Failed to get read AD metrics from {0}: {1}", dcMetrics.DnsHostName, ex); dcMetrics.ErrorMessage = new LocalizedString(ex.Message); } }
public Exception SetErrorState(Exception e) { DateTime utcNow = DateTime.UtcNow; if (this.LastReadFailureStartTime == DateTime.MinValue) { this.LastReadFailureStartTime = utcNow; ExTraceGlobals.TenantRelocationTracer.TraceDebug <DateTime, Guid>((long)this.TenantConfigUnitObjectGuid.GetHashCode(), "SetErrorState: LastReadFailureStartTime set, time:{0}, tenant={1}", utcNow, this.TenantConfigUnitObjectGuid); return(e); } if (utcNow.Subtract(this.LastReadFailureStartTime) < TenantRelocationSyncConfiguration.FailoverTimeout) { ExTraceGlobals.TenantRelocationTracer.TraceDebug <DateTime, DateTime, Guid>((long)this.TenantConfigUnitObjectGuid.GetHashCode(), "SetErrorState: subsequent error set, LastReadFailureStartTime:{0}, time:{1}, tenant={2}", this.LastReadFailureStartTime, DateTime.UtcNow, this.TenantConfigUnitObjectGuid); return(e); } string text; LocalizedString localizedString; if (!string.IsNullOrEmpty(this.AffinityDcFqdn) && !SuitabilityVerifier.IsServerSuitableIgnoreExceptions(this.AffinityDcFqdn, false, null, out text, out localizedString)) { ExTraceGlobals.TenantRelocationTracer.TraceDebug <DateTime, DateTime, Guid>((long)this.TenantConfigUnitObjectGuid.GetHashCode(), "SetErrorState: source failover triggered, LastReadFailureStartTime:{0}, time:{1}, tenant={2}", this.LastReadFailureStartTime, DateTime.UtcNow, this.TenantConfigUnitObjectGuid); this.PrepareForFailover(); } if (!string.IsNullOrEmpty(this.AffinityTargetDcFqdn) && !SuitabilityVerifier.IsServerSuitableIgnoreExceptions(this.AffinityTargetDcFqdn, false, null, out text, out localizedString)) { ExTraceGlobals.TenantRelocationTracer.TraceDebug <DateTime, DateTime, Guid>((long)this.TenantConfigUnitObjectGuid.GetHashCode(), "SetErrorState: target failover triggered, LastReadFailureStartTime:{0}, time:{1}, tenant={2}", this.LastReadFailureStartTime, DateTime.UtcNow, this.TenantConfigUnitObjectGuid); this.AffinityTargetDcFqdn = null; } return(e); }
private bool TrySelectDomainController(ITopologyConfigurationSession session, string domainControllerFqdn, PartitionId partitionId, bool checkSuitability, out Guid resultInvocationId) { ExTraceGlobals.ActiveDirectoryTracer.TraceDebug <string>((long)base.TenantExternalDirectoryId.GetHashCode(), "MergePageToken.TrySelectDomainController dc {0}", domainControllerFqdn); resultInvocationId = Guid.Empty; string text; LocalizedString localizedString; if (checkSuitability && !SuitabilityVerifier.IsServerSuitableIgnoreExceptions(domainControllerFqdn, false, null, out text, out localizedString)) { ExTraceGlobals.ActiveDirectoryTracer.TraceWarning <string, string>((long)base.TenantExternalDirectoryId.GetHashCode(), "DC {0} is not available for Tenant Full Backsync, error {1}", domainControllerFqdn, localizedString.ToString()); return(false); } ITopologyConfigurationSession configSession = DirectorySessionFactory.Default.CreateTopologyConfigurationSession(domainControllerFqdn, true, ConsistencyMode.IgnoreInvalid, null, ADSessionSettings.FromAccountPartitionRootOrgScopeSet(partitionId), 461, "TrySelectDomainController", "f:\\15.00.1497\\sources\\dev\\data\\src\\directory\\Sync\\BackSync\\MergePageToken.cs"); WatermarkMap replicationCursors = SyncConfiguration.GetReplicationCursors(configSession, false, true); if (replicationCursors.ContainsAllChanges(base.Watermarks)) { Guid invocationIdByFqdn = session.GetInvocationIdByFqdn(domainControllerFqdn); long num; if (base.Watermarks.TryGetValue(invocationIdByFqdn, out num)) { base.ObjectUpdateSequenceNumber = num + 1L; base.TombstoneUpdateSequenceNumber = num + 1L; base.InvocationId = invocationIdByFqdn; if (base.UseContainerizedUsnChangedIndex) { base.SoftDeletedObjectUpdateSequenceNumber = num + 1L; } ExTraceGlobals.ActiveDirectoryTracer.TraceDebug((long)base.TenantExternalDirectoryId.GetHashCode(), "DC {0}({1})has all changes reported by the Tenant Full Sync Watermarks for {2} and CAN be used. \r\nFull sync watermarks: \r\n{3}\r\nDC replication cursors: \r\n{4}", new object[] { domainControllerFqdn, base.InvocationId, base.TenantExternalDirectoryId, base.Watermarks.SerializeToString(), replicationCursors.SerializeToString() }); resultInvocationId = invocationIdByFqdn; return(true); } ExTraceGlobals.ActiveDirectoryTracer.TraceDebug((long)base.TenantExternalDirectoryId.GetHashCode(), "DC {0}({1})has all changes reported by the Tenant Full Sync Watermarks for {2} but cannot be used since its invocationId is not part of the TFS watermarks. \r\nFull sync watermarks: \r\n{3}\r\n", new object[] { domainControllerFqdn, base.InvocationId, base.TenantExternalDirectoryId, base.Watermarks.SerializeToString() }); } else { ExTraceGlobals.ActiveDirectoryTracer.TraceDebug((long)base.TenantExternalDirectoryId.GetHashCode(), "DC {0} does not have all changes reported by the Tenant Full Sync Watermarks for {1} and cannot be used. \r\nFull sync watermarks: \r\n{2}\r\nDC replication cursors: \r\n{3}", new object[] { domainControllerFqdn, base.TenantExternalDirectoryId, base.Watermarks.SerializeToString(), replicationCursors.SerializeToString() }); } return(false); }
private static ADServerInfo FindDirectoryServerForForestOrDomain(string domainOrForestFqdn, NetworkCredential credential, bool requireGCs = false) { StringCollection stringCollection = requireGCs ? NativeHelpers.FindAllGlobalCatalogs(domainOrForestFqdn, null) : NativeHelpers.FindAllDomainControllers(domainOrForestFqdn, null); LocalizedString value = LocalizedString.Empty; LocalizedString empty = LocalizedString.Empty; string writableNC = null; string siteName = null; foreach (string text in stringCollection) { if (SuitabilityVerifier.IsServerSuitableIgnoreExceptions(text, requireGCs, credential, out writableNC, out siteName, out empty)) { if (!requireGCs) { Globals.LogEvent(DirectoryEventLogConstants.Tuple_DSC_EVENT_GET_DC_FROM_DOMAIN, domainOrForestFqdn, new object[] { domainOrForestFqdn, text }); } return(new ADServerInfo(text, domainOrForestFqdn, requireGCs ? 3268 : 389, writableNC, 100, AuthType.Kerberos, true) { SiteName = siteName }); } ExTraceGlobals.TopologyProviderTracer.TraceError(0L, "{0} {1} {2} was found not suitable. Will try to find another {1} in the forest\\domain. Error message: {3}", new object[] { domainOrForestFqdn, requireGCs ? "Global Catalog" : "Domain Controller", text, empty }); value = DirectoryStrings.AppendLocalizedStrings(value, empty); } if (requireGCs) { Globals.LogEvent(DirectoryEventLogConstants.Tuple_DSC_EVENT_ALL_GC_DOWN, string.Empty, new object[] { domainOrForestFqdn, string.Empty }); throw new NoSuitableServerFoundException(DirectoryStrings.ErrorNoSuitableGCInForest(domainOrForestFqdn, value)); } Globals.LogEvent(DirectoryEventLogConstants.Tuple_DSC_EVENT_GET_DC_FROM_DOMAIN_FAILED, domainOrForestFqdn, new object[] { domainOrForestFqdn }); throw new NoSuitableServerFoundException(DirectoryStrings.ErrorNoSuitableDCInDomain(domainOrForestFqdn, value)); }
private bool IsServerSuitableAsGC(string fqdn, NetworkCredential credential) { LocalizedString empty = LocalizedString.Empty; string text; bool flag = SuitabilityVerifier.IsServerSuitableIgnoreExceptions(fqdn, true, credential, out text, out empty); if (!flag) { TaskLogger.Trace("Server {0} is not suitable as a Global Catalog. Reason: {1}", new object[] { fqdn, empty }); } return(flag); }
private ADServerInfo GetDirectoryServer(string partitionFqdn, ADRole role) { ExTraceGlobals.TopologyProviderTracer.TraceDebug <string, ADRole>((long)this.GetHashCode(), "GetDirectoryServer PartitionFqdn {0}. Role {1}", partitionFqdn, role); LocatorFlags locatorFlags = LocatorFlags.ForceRediscovery | LocatorFlags.DirectoryServicesRequired | LocatorFlags.ReturnDnsName; string text = partitionFqdn; if (ADRole.GlobalCatalog == role) { ADObjectId rootDomainNamingContext = base.GetRootDomainNamingContext(partitionFqdn); ADObjectId domainNamingContext = base.GetDomainNamingContext(partitionFqdn); if (!rootDomainNamingContext.DistinguishedName.Equals(domainNamingContext.DistinguishedName, StringComparison.OrdinalIgnoreCase)) { text = NativeHelpers.CanonicalNameFromDistinguishedName(rootDomainNamingContext.DistinguishedName); } locatorFlags |= LocatorFlags.GCRequired; } ExTraceGlobals.TopologyProviderTracer.TraceDebug <string, string, LocatorFlags>((long)this.GetHashCode(), "GetDirectoryServer. Partition Fqdn {0} Parent Domain {1}. Flags {2}", partitionFqdn, text, locatorFlags); ADServerInfo serverInfo = new ADServerInfo(null, text, (ADRole.GlobalCatalog == role) ? 3268 : 389, null, 100, AuthType.Kerberos, true); PooledLdapConnection pooledLdapConnection = null; ADServerInfo adserverInfo = null; try { pooledLdapConnection = LdapConnectionPool.CreateOneTimeConnection(null, serverInfo, locatorFlags); if (!string.IsNullOrEmpty(pooledLdapConnection.SessionOptions.HostName)) { adserverInfo = pooledLdapConnection.ADServerInfo.CloneWithServerNameResolved(pooledLdapConnection.SessionOptions.HostName); } ExTraceGlobals.TopologyProviderTracer.TraceDebug <string, string>((long)this.GetHashCode(), "GetDirectoryServer. Partition Fqdn {0}. Server {1}", partitionFqdn, pooledLdapConnection.SessionOptions.HostName ?? string.Empty); } finally { if (pooledLdapConnection != null) { pooledLdapConnection.ReturnToPool(); } } string text2; LocalizedString localizedString; if (adserverInfo != null && SuitabilityVerifier.IsServerSuitableIgnoreExceptions(adserverInfo.Fqdn, ADRole.GlobalCatalog == role, null, out text2, out localizedString)) { return(adserverInfo); } return(LdapTopologyProvider.FindDirectoryServerForForestOrDomain(text, null, ADRole.GlobalCatalog == role)); }
private static bool IsServerSuitable(Guid invocationId, ITopologyConfigurationSession session, out string dnsHostName, out bool isInLocalSite) { dnsHostName = string.Empty; isInLocalSite = false; ADServer adserver = session.FindDCByInvocationId(invocationId); if (adserver == null) { return(false); } dnsHostName = adserver.DnsHostName; isInLocalSite = adserver.IsInLocalSite; LocalizedString empty = LocalizedString.Empty; string text; return(SuitabilityVerifier.IsServerSuitableIgnoreExceptions(adserver.DnsHostName, true, null, out text, out empty)); }
private static ReconciliationCookie GetReconciliationCookieForDomainController(Fqdn fqdn, ITopologyConfigurationSession configSession, Task.TaskErrorLoggingDelegate errorLogger) { ADServer adserver = configSession.FindDCByFqdn(fqdn); if (adserver != null) { LocalizedString empty = LocalizedString.Empty; string text; if (SuitabilityVerifier.IsServerSuitableIgnoreExceptions(adserver.DnsHostName, true, null, out text, out empty)) { ITopologyConfigurationSession sessionForDC = ProvisioningReconciliationHelper.GetSessionForDC(adserver); RootDse rootDse = sessionForDC.GetRootDse(); Guid invocationIdByDC = sessionForDC.GetInvocationIdByDC(adserver); return(new ReconciliationCookie(ProvisioningReconciliationHelper.CurrentCookieVersion, adserver.DnsHostName, invocationIdByDC, rootDse.HighestCommittedUSN)); } } return(null); }
private bool WaitForReplicationConvergenceInTargetForest(string domainController, TimeSpan timeout) { base.WriteVerbose(Strings.VerboseWaitingForReplicationInTargetForest); WatermarkMap watermarkMap = new WatermarkMap(); ReadOnlyCollection <ADServer> readOnlyCollection = ADForest.GetForest(this.DataObject.TargetForest, null).FindRootDomain().FindAllDomainControllers(); DateTime utcNow = DateTime.UtcNow; foreach (ADServer adserver in readOnlyCollection) { string text; LocalizedString localizedString; if (SuitabilityVerifier.IsServerSuitableIgnoreExceptions(adserver.DnsHostName, false, null, out text, out localizedString)) { Guid key; WatermarkMap watermarkMap2; long value = this.ReadDcHighestUSN(this.DataObject.TargetOrganizationId.PartitionId, adserver.DnsHostName, false, out key, out watermarkMap2); watermarkMap[key] = value; } } ITopologyConfigurationSession session = DirectorySessionFactory.Default.CreateTopologyConfigurationSession(domainController, true, ConsistencyMode.PartiallyConsistent, null, ADSessionSettings.FromAccountPartitionRootOrgScopeSet(this.DataObject.TargetOrganizationId.PartitionId), 514, "WaitForReplicationConvergenceInTargetForest", "f:\\15.00.1497\\sources\\dev\\Management\\src\\Management\\Relocation\\RemoveTenantRelocationRequest.cs"); bool flag = false; while (!flag) { flag = this.CheckReplicationStatus(session, watermarkMap, false); if (flag || utcNow + timeout < DateTime.UtcNow) { break; } Thread.Sleep(5000); } if (flag) { base.WriteVerbose(Strings.VerboseTargetDcIsUpToDate(domainController)); } return(flag); }
private static string FindAvailableServerByInvocationId(Guid invocationId, IConfigurationSession configSession, ADObjectId allowedSite) { QueryFilter filter = new ComparisonFilter(ComparisonOperator.Equal, NtdsDsaSchema.InvocationId, invocationId); NtdsDsa[] array = configSession.Find <NtdsDsa>(allowedSite, QueryScope.SubTree, filter, null, 1); if (array == null || array.Length <= 0) { return(null); } ADServer adserver = configSession.Read <ADServer>(array[0].Id.Parent); if (adserver == null) { return(null); } LocalizedString empty = LocalizedString.Empty; string text; if (!SuitabilityVerifier.IsServerSuitableIgnoreExceptions(adserver.DnsHostName, true, null, out text, out empty)) { return(null); } return(adserver.DnsHostName); }