From 03ad5d5de8f0c36dfcd17932aa151d46e3e5db5d Mon Sep 17 00:00:00 2001 From: Release-Agent <> Date: Mon, 25 Apr 2022 21:34:24 +0000 Subject: [PATCH] Sync up from Mainline branch for CommitId 25f5e261092966df7c70ce069aa6af1aa63ad6f3 --- .../Client/Auth/AuthProcessor.cs | 10 +- .../Client/Auth/MSALHttpHelper.cs | 2 +- .../TokenCache/FileBackedTokenCacheHints.cs | 4 +- .../Client/ConnectionService.cs | 21 +- .../OrganizationServiceProxyAsync.cs | 17 +- .../Client/Connector/WebProxyClient.cs | 17 +- .../Client/DataverseTelemetryBehaviors.cs | 2 +- .../Client/DataverseTraceLogger.cs | 7 + .../DataverseClient/Client/Environs.cs | 44 +- .../Client/Model/DiscoveryServers.cs | 481 +++++++++--------- .../DataverseClient/Client/ServiceClient.cs | 17 +- .../DataverseClient/Client/TestingHelper.cs | 38 +- .../DataverseClient/Client/Utils/Utils.cs | 66 +-- .../ConnectControl/ConnectionManager.cs | 18 + .../Model/OnlineDiscoveryServers.cs | 6 + .../ConnectControl/ServerLoginControl.xaml.cs | 9 + ...Platform.Dataverse.Client.ReleaseNotes.txt | 11 + 17 files changed, 407 insertions(+), 363 deletions(-) diff --git a/src/GeneralTools/DataverseClient/Client/Auth/AuthProcessor.cs b/src/GeneralTools/DataverseClient/Client/Auth/AuthProcessor.cs index b5b579c..b7cac72 100644 --- a/src/GeneralTools/DataverseClient/Client/Auth/AuthProcessor.cs +++ b/src/GeneralTools/DataverseClient/Client/Auth/AuthProcessor.cs @@ -183,7 +183,7 @@ internal async static Task ExecuteAuthenticateServ { ClientId = clientId, EnablePiiLogging = true, - RedirectUri = redirectUri.ToString(), + RedirectUri = redirectUri?.ToString(), LogLevel = LogLevel.Verbose, }) .WithAuthority(Authority) @@ -196,7 +196,7 @@ internal async static Task ExecuteAuthenticateServ if (tokenCacheStorePath != null) { var f = new FileBackedTokenCache(new FileBackedTokenCacheHints(tokenCacheStorePath)); - await f.Initialize(pApp.UserTokenCache); + await f.Initialize(pApp.UserTokenCache).ConfigureAwait(false); } } @@ -241,7 +241,7 @@ internal async static Task ExecuteAuthenticateServ } catch (MsalException ex) { - var errorHandledResult = await ProcessMsalExecptionAsync(serviceUrl, clientCredentials, userCert, clientId, redirectUri, promptBehavior, isOnPrem, authority, msalAuthClient, logSink, useDefaultCreds, msalEx: ex, memoryBackedTokenCache: memoryBackedTokenCache, tokenCacheStorePath: tokenCacheStorePath); + var errorHandledResult = await ProcessMsalExecptionAsync(serviceUrl, clientCredentials, userCert, clientId, redirectUri, promptBehavior, isOnPrem, authority, msalAuthClient, logSink, useDefaultCreds, msalEx: ex, memoryBackedTokenCache: memoryBackedTokenCache, tokenCacheStorePath: tokenCacheStorePath).ConfigureAwait(false); if (errorHandledResult != null) processResult = errorHandledResult; } @@ -431,7 +431,7 @@ internal static UriBuilder GetUriBuilderWithVersion(Uri discoveryServiceUri) } UriBuilder versionTaggedUriBuilder = new UriBuilder(webUrlBuilder.Uri); - string version = FileVersionInfo.GetVersionInfo(typeof(Xrm.Sdk.Organization.OrganizationDetail).Assembly.Location).FileVersion; + string version = Environs.XrmSdkFileVersion; string versionQueryStringParameter = string.Format("SDKClientVersion={0}", version); if (string.IsNullOrEmpty(versionTaggedUriBuilder.Query)) @@ -458,7 +458,7 @@ private static async Task GetAuthorityFromTargetServiceAs { var client = clientFactory.CreateClient("DataverseHttpClientFactory"); var resolver = new AuthorityResolver(client, (t, msg) => logger.Log(msg, t)); - return await resolver.ProbeForExpectedAuthentication(targetServiceUrl, isOnPrem); + return await resolver.ProbeForExpectedAuthentication(targetServiceUrl, isOnPrem).ConfigureAwait(false); } /// diff --git a/src/GeneralTools/DataverseClient/Client/Auth/MSALHttpHelper.cs b/src/GeneralTools/DataverseClient/Client/Auth/MSALHttpHelper.cs index d968a0e..f458e12 100644 --- a/src/GeneralTools/DataverseClient/Client/Auth/MSALHttpHelper.cs +++ b/src/GeneralTools/DataverseClient/Client/Auth/MSALHttpHelper.cs @@ -27,7 +27,7 @@ protected override async Task SendAsync(HttpRequestMessage HttpResponseMessage response = null; for (int i = 0; i < MaxRetryCount; i++) { - response = await base.SendAsync(request, cancellationToken); + response = await base.SendAsync(request, cancellationToken).ConfigureAwait(false); if (response.IsSuccessStatusCode) { return response; diff --git a/src/GeneralTools/DataverseClient/Client/Auth/TokenCache/FileBackedTokenCacheHints.cs b/src/GeneralTools/DataverseClient/Client/Auth/TokenCache/FileBackedTokenCacheHints.cs index e7ce61f..bb0d538 100644 --- a/src/GeneralTools/DataverseClient/Client/Auth/TokenCache/FileBackedTokenCacheHints.cs +++ b/src/GeneralTools/DataverseClient/Client/Auth/TokenCache/FileBackedTokenCacheHints.cs @@ -1,4 +1,4 @@ -using System; +using System; using System.Collections.Generic; using System.IO; using Microsoft.Identity.Client.Extensions.Msal; @@ -38,7 +38,7 @@ public FileBackedTokenCacheHints(string tokenPathAndFileName) { hostName = Path.GetFileNameWithoutExtension(AppDomain.CurrentDomain.FriendlyName); } - string hostVersion = typeof(OrganizationDetail).Assembly.GetCustomAttribute().Version ?? FileVersionInfo.GetVersionInfo(typeof(OrganizationDetail).Assembly.Location).FileVersion; + string hostVersion = Environs.XrmSdkFileVersion; string companyName = typeof(OrganizationDetail).Assembly.GetCustomAttribute().Company; diff --git a/src/GeneralTools/DataverseClient/Client/ConnectionService.cs b/src/GeneralTools/DataverseClient/Client/ConnectionService.cs index d45892c..4ab016a 100644 --- a/src/GeneralTools/DataverseClient/Client/ConnectionService.cs +++ b/src/GeneralTools/DataverseClient/Client/ConnectionService.cs @@ -1822,10 +1822,9 @@ internal async Task Command_WebAPIProcess_ExecuteAsync(Org bool? suppressDuplicateDetection = null; if (req.Parameters.ContainsKey(Utilities.RequestHeaders.SUPPRESSDUPLICATEDETECTION)) { - if (req.Parameters[Utilities.RequestHeaders.SUPPRESSDUPLICATEDETECTION].GetType() == typeof(bool) && - (bool)req.Parameters[Utilities.RequestHeaders.SUPPRESSDUPLICATEDETECTION]) + if (req.Parameters[Utilities.RequestHeaders.SUPPRESSDUPLICATEDETECTION].GetType() == typeof(bool)) { - suppressDuplicateDetection = true; + suppressDuplicateDetection = (bool)req.Parameters[Utilities.RequestHeaders.SUPPRESSDUPLICATEDETECTION]; } } @@ -1911,7 +1910,7 @@ internal async Task Command_WebAPIProcess_ExecuteAsync(Org if (suppressDuplicateDetection.HasValue) { - headers.Add($"{Utilities.RequestHeaders.DATAVERSEHEADERPROPERTYPREFIX}{Utilities.RequestHeaders.SUPPRESSDUPLICATEDETECTION}", new List() { "true" }); + headers.Add($"{Utilities.RequestHeaders.DATAVERSEHEADERPROPERTYPREFIX}{Utilities.RequestHeaders.SUPPRESSDUPLICATEDETECTION}", new List() { suppressDuplicateDetection.ToString() }); } string addedQueryParams = ""; @@ -1963,7 +1962,7 @@ internal async Task Command_WebAPIProcess_ExecuteAsync(Org } else { - var json = await sResp.Content.ReadAsStringAsync(); + var json = await sResp.Content.ReadAsStringAsync().ConfigureAwait(false); if (_knownTypesFactory.TryCreate($"{req.RequestName}Response", out var response, json)) { @@ -2166,6 +2165,9 @@ internal async Task Command_WebExecuteAsync(string queryStr } HttpResponseMessage resp = null; + + //RequestId Logging line for telemetry + string requestIdLogSegement = logEntry.GetFormatedRequestSessionIdString(requestTrackingId, SessionTrackingId); do { // Add authorization header. - Here to catch the situation where a token expires during retry. @@ -2174,11 +2176,10 @@ internal async Task Command_WebExecuteAsync(string queryStr logDt.Restart(); // start clock. - logEntry.Log(string.Format(CultureInfo.InvariantCulture, "Execute Command - {0}{1}: RequestID={2} {3}", + logEntry.Log(string.Format(CultureInfo.InvariantCulture, "Execute Command - {0}{1}: {2}", $"{method} {queryString}", string.IsNullOrEmpty(errorStringCheck) ? "" : $" : {errorStringCheck} ", - requestTrackingId.ToString(), - SessionTrackingId.HasValue && SessionTrackingId.Value != Guid.Empty ? $"SessionID={SessionTrackingId.Value.ToString()} : " : "" + requestIdLogSegement ), TraceEventType.Verbose); try { @@ -2225,7 +2226,7 @@ internal async Task Command_WebExecuteAsync(string queryStr else { retry = false; - logEntry.Log(string.Format(CultureInfo.InvariantCulture, "Failed to Execute Command - {3} {0} : {2}RequestID={1}", queryString, requestTrackingId.ToString(), SessionTrackingId.HasValue && SessionTrackingId.Value != Guid.Empty ? $"SessionID={SessionTrackingId.Value.ToString()} : " : "", method), TraceEventType.Verbose); + logEntry.Log(string.Format(CultureInfo.InvariantCulture, "Failed to Execute Command - {2} {0} : {1}", queryString, requestIdLogSegement, method), TraceEventType.Verbose); logEntry.Log(string.Format(CultureInfo.InvariantCulture, "************ Exception - {2} : {0} |=> {1}", errorStringCheck, ex.Message, queryString), TraceEventType.Error, ex); return null; } @@ -2379,7 +2380,7 @@ private bool ShouldRetryWebAPI(Exception ex, int retryCount, int maxRetryCount, { Agent = AppDomain.CurrentDomain.FriendlyName; } - Agent = $"{Agent} (DataverseSvcClient:{Environs.FileVersion})"; + Agent = $"{Agent} (DataverseSvcClient:{Environs.DvSvcClientFileVersion})"; if (!_httpRequest.Headers.Contains(Utilities.RequestHeaders.USER_AGENT_HTTP_HEADER)) diff --git a/src/GeneralTools/DataverseClient/Client/Connector/OnPremises/OrganizationServiceProxyAsync.cs b/src/GeneralTools/DataverseClient/Client/Connector/OnPremises/OrganizationServiceProxyAsync.cs index 88900ed..a819fa5 100644 --- a/src/GeneralTools/DataverseClient/Client/Connector/OnPremises/OrganizationServiceProxyAsync.cs +++ b/src/GeneralTools/DataverseClient/Client/Connector/OnPremises/OrganizationServiceProxyAsync.cs @@ -113,22 +113,7 @@ internal static string GetXrmSdkAssemblyFileVersion() { if (string.IsNullOrEmpty(_xrmSdkAssemblyFileVersion)) { - string[] assembliesToCheck = new string[] { "Microsoft.Xrm.Sdk.dll" }; - Assembly[] assemblies = AppDomain.CurrentDomain.GetAssemblies(); - - foreach (var assemblyToCheck in assembliesToCheck) - { - foreach (Assembly assembly in assemblies) - { - if (assembly.ManifestModule.Name.Equals(assemblyToCheck, StringComparison.OrdinalIgnoreCase) && - !string.IsNullOrEmpty(assembly.Location) && - System.IO.File.Exists(assembly.Location)) - { - _xrmSdkAssemblyFileVersion = FileVersionInfo.GetVersionInfo(assembly.Location).FileVersion; - break; - } - } - } + _xrmSdkAssemblyFileVersion = Environs.XrmSdkFileVersion; } // If the assembly is embedded as resource and loaded from memory, there is no physical file on disk to check for file version diff --git a/src/GeneralTools/DataverseClient/Client/Connector/WebProxyClient.cs b/src/GeneralTools/DataverseClient/Client/Connector/WebProxyClient.cs index e912883..5a34895 100644 --- a/src/GeneralTools/DataverseClient/Client/Connector/WebProxyClient.cs +++ b/src/GeneralTools/DataverseClient/Client/Connector/WebProxyClient.cs @@ -169,22 +169,7 @@ internal string GetXrmSdkAssemblyFileVersion() { if (string.IsNullOrEmpty(_xrmSdkAssemblyFileVersion)) { - string[] assembliesToCheck = { "Microsoft.Xrm.Sdk.dll" }; - Assembly[] assemblies = AppDomain.CurrentDomain.GetAssemblies(); - - foreach (string assemblyToCheck in assembliesToCheck) - { - foreach (Assembly assembly in assemblies) - { - if (assembly.ManifestModule.Name.Equals(assemblyToCheck, StringComparison.OrdinalIgnoreCase) && - !string.IsNullOrEmpty(assembly.Location) && - System.IO.File.Exists(assembly.Location)) - { - _xrmSdkAssemblyFileVersion = FileVersionInfo.GetVersionInfo(assembly.Location).FileVersion; - break; - } - } - } + _xrmSdkAssemblyFileVersion = Environs.XrmSdkFileVersion; } // If the assembly is embedded as resource and loaded from memory, there is no physical file on disk to check for file version diff --git a/src/GeneralTools/DataverseClient/Client/DataverseTelemetryBehaviors.cs b/src/GeneralTools/DataverseClient/Client/DataverseTelemetryBehaviors.cs index 017485c..f5e55ad 100644 --- a/src/GeneralTools/DataverseClient/Client/DataverseTelemetryBehaviors.cs +++ b/src/GeneralTools/DataverseClient/Client/DataverseTelemetryBehaviors.cs @@ -56,7 +56,7 @@ public DataverseTelemetryBehaviors(ConnectionService cli) _userAgent = AppDomain.CurrentDomain.FriendlyName; } - _userAgent = $"{_userAgent} (DataverseSvcClient:{Environs.FileVersion})"; + _userAgent = $"{_userAgent} (DataverseSvcClient:{Environs.DvSvcClientFileVersion})"; if (_maxFaultSize == -1 && !string.IsNullOrEmpty(_configuration.Value.MaxFaultSizeOverride)) { diff --git a/src/GeneralTools/DataverseClient/Client/DataverseTraceLogger.cs b/src/GeneralTools/DataverseClient/Client/DataverseTraceLogger.cs index 8b73ab3..5275b9f 100644 --- a/src/GeneralTools/DataverseClient/Client/DataverseTraceLogger.cs +++ b/src/GeneralTools/DataverseClient/Client/DataverseTraceLogger.cs @@ -316,6 +316,13 @@ public void LogFailure(OrganizationRequest req, Guid requestTrackingId, Guid? se } } + internal string GetFormatedRequestSessionIdString( Guid requestId, Guid? sessionId ) + { + return string.Format("RequestID={0} {1}", + requestId.ToString(), + sessionId.HasValue && sessionId.Value != Guid.Empty ? $": SessionID={sessionId.Value.ToString()} : " : ""); + } + /// /// Logs data to memory. /// diff --git a/src/GeneralTools/DataverseClient/Client/Environs.cs b/src/GeneralTools/DataverseClient/Client/Environs.cs index 5f1abd0..396e958 100644 --- a/src/GeneralTools/DataverseClient/Client/Environs.cs +++ b/src/GeneralTools/DataverseClient/Client/Environs.cs @@ -1,4 +1,5 @@ -using System.Diagnostics; +using Microsoft.Xrm.Sdk.Organization; +using System.Diagnostics; using System.Reflection; namespace Microsoft.PowerPlatform.Dataverse.Client @@ -7,28 +8,43 @@ internal static class Environs { private static object _initLock = new object(); - public static string FileVersion { get; private set; } + /// + /// Version number of the XrmSDK + /// + public static string XrmSdkFileVersion { get; private set; } + + public static string DvSvcClientFileVersion { get; private set; } static Environs() { - if (string.IsNullOrEmpty(FileVersion)) + + if (string.IsNullOrEmpty(XrmSdkFileVersion)) + { + lock(_initLock) + { + if ( string.IsNullOrEmpty(XrmSdkFileVersion)) + { + XrmSdkFileVersion = "Unknown"; + try + { + XrmSdkFileVersion = typeof(OrganizationDetail).Assembly.GetCustomAttribute().Version ?? FileVersionInfo.GetVersionInfo(typeof(OrganizationDetail).Assembly.Location).FileVersion; + } + catch { } + } + } + } + + + if (string.IsNullOrEmpty(DvSvcClientFileVersion)) { lock (_initLock) { - if (string.IsNullOrEmpty(FileVersion)) + if (string.IsNullOrEmpty(DvSvcClientFileVersion)) { - FileVersion = "Unknown"; + DvSvcClientFileVersion = "Unknown"; try { - string location = Assembly.GetExecutingAssembly().Location; - if (!string.IsNullOrEmpty(location)) - { - string version = FileVersionInfo.GetVersionInfo(location).FileVersion; - if (!string.IsNullOrEmpty(version)) - { - FileVersion = version; - } - } + DvSvcClientFileVersion = typeof(ServiceClient).Assembly.GetCustomAttribute().Version ?? FileVersionInfo.GetVersionInfo(typeof(ServiceClient).Assembly.Location).FileVersion; } catch { diff --git a/src/GeneralTools/DataverseClient/Client/Model/DiscoveryServers.cs b/src/GeneralTools/DataverseClient/Client/Model/DiscoveryServers.cs index d1e173c..d42df69 100644 --- a/src/GeneralTools/DataverseClient/Client/Model/DiscoveryServers.cs +++ b/src/GeneralTools/DataverseClient/Client/Model/DiscoveryServers.cs @@ -1,4 +1,4 @@ -using System; +using System; using System.Collections.Generic; using System.Linq; using System.Text; @@ -9,272 +9,275 @@ namespace Microsoft.PowerPlatform.Dataverse.Client.Model { - /// - /// Dataverse online Discovery server enumeration - /// - public class DiscoveryServers : INotifyPropertyChanged , IDisposable - { - /// - /// Log entry - /// - DataverseTraceLogger logger = null; + /// + /// Dataverse online Discovery server enumeration + /// + public class DiscoveryServers : INotifyPropertyChanged, IDisposable + { + /// + /// Log entry + /// + DataverseTraceLogger logger = null; - /// - /// Contains the list of Online Discovery Servers - /// - private ObservableCollection _OSDPServers = new ObservableCollection(); + /// + /// Contains the list of Online Discovery Servers + /// + private ObservableCollection _OSDPServers = new ObservableCollection(); - /// - /// Public Property to discovery servers - /// - public ObservableCollection OSDPServers { get { return _OSDPServers; } set { if (value != _OSDPServers) _OSDPServers = value; NotifyPropertyChanged("OSDPServers"); } } + /// + /// Public Property to discovery servers + /// + public ObservableCollection OSDPServers { get { return _OSDPServers; } set { if (value != _OSDPServers) _OSDPServers = value; NotifyPropertyChanged("OSDPServers"); } } - /// - /// Default constructor, Builds baseline data for the Servers. - /// - public DiscoveryServers() - { - if ( logger == null ) - logger = new DataverseTraceLogger(); + /// + /// Default constructor, Builds baseline data for the Servers. + /// + public DiscoveryServers() + { + if (logger == null) + logger = new DataverseTraceLogger(); - if (_OSDPServers == null) - _OSDPServers = new ObservableCollection(); + if (_OSDPServers == null) + _OSDPServers = new ObservableCollection(); - _OSDPServers.Add(new DiscoveryServer() { DiscoveryServerUri = null, DisplayName = "Don’t Know", ShortName = "" }); + _OSDPServers.Add(new DiscoveryServer() { DiscoveryServerUri = null, DisplayName = "Don’t Know", ShortName = "" }); - _OSDPServers.Add(new DiscoveryServer() { DiscoveryServerUri = new Uri("https://disco.crm5.dynamics.com/XRMServices/2011/Discovery.svc"), DisplayName = "Asia Pacific Area", ShortName = "APAC" , GeoCode="APAC" }); - _OSDPServers.Add(new DiscoveryServer() { DiscoveryServerUri = new Uri("https://disco.crm3.dynamics.com/XRMServices/2011/Discovery.svc"), DisplayName = "Canada", ShortName = "CAN" , GeoCode="CAN" }); - _OSDPServers.Add(new DiscoveryServer() { DiscoveryServerUri = new Uri("https://disco.crm.dynamics.cn/XRMServices/2011/Discovery.svc"), DisplayName = "China", ShortName = "CHN", GeoCode="CHN", RequiresRegionalDiscovery = true, RegionalGlobalDiscoveryServer = new Uri("https://globaldisco.crm.dynamics.cn") }); - _OSDPServers.Add(new DiscoveryServer() { DiscoveryServerUri = new Uri("https://disco.crm4.dynamics.com/XRMServices/2011/Discovery.svc"), DisplayName = "Europe, Middle East and Africa", ShortName = "EMEA" , GeoCode= "EMEA" }); - _OSDPServers.Add(new DiscoveryServer() { DiscoveryServerUri = new Uri("https://disco.crm12.dynamics.com/XRMServices/2011/Discovery.svc"), DisplayName = "France", ShortName = "FRA" , GeoCode= "FRA" }); - _OSDPServers.Add(new DiscoveryServer() { DiscoveryServerUri = new Uri("https://disco.crm16.dynamics.com/XRMServices/2011/Discovery.svc"), DisplayName = "Germany (Go Local)", ShortName = "GER" , GeoCode= "GER" }); - _OSDPServers.Add(new DiscoveryServer() { DiscoveryServerUri = new Uri("https://disco.crm.Microsoftdynamics.de/XRMServices/2011/Discovery.svc"), DisplayName = "Germany", ShortName = "DEU", RequiresRegionalDiscovery = true , GeoCode="DEU"}); - _OSDPServers.Add(new DiscoveryServer() { DiscoveryServerUri = new Uri("https://disco.crm8.dynamics.com/XRMServices/2011/Discovery.svc"), DisplayName = "India", ShortName = "IND" , GeoCode="IND" }); - _OSDPServers.Add(new DiscoveryServer() { DiscoveryServerUri = new Uri("https://disco.crm7.dynamics.com/XRMServices/2011/Discovery.svc"), DisplayName = "Japan", ShortName = "JPN" , GeoCode ="JPN" }); - _OSDPServers.Add(new DiscoveryServer() { DiscoveryServerUri = new Uri("https://disco.crm.dynamics.com/XRMServices/2011/Discovery.svc"), DisplayName = "North America", ShortName = "NorthAmerica" }); // Do not add Geo code to NAM or GCC, as they use the same server level GEO code. - _OSDPServers.Add(new DiscoveryServer() { DiscoveryServerUri = new Uri("https://disco.crm9.dynamics.com/XRMServices/2011/Discovery.svc"), DisplayName = "North America 2", ShortName = "NorthAmerica2", RequiresRegionalDiscovery = true, RegionalGlobalDiscoveryServer = new Uri("https://globaldisco.crm9.dynamics.com")}); - _OSDPServers.Add(new DiscoveryServer() { DiscoveryServerUri = new Uri("https://disco.crm6.dynamics.com/XRMServices/2011/Discovery.svc"), DisplayName = "Oceania", ShortName = "Oceania" , GeoCode="OCE" }); - _OSDPServers.Add(new DiscoveryServer() { DiscoveryServerUri = new Uri("https://disco.crm14.dynamics.com/XRMServices/2011/Discovery.svc"), DisplayName = "South Africa", ShortName = "ZAF" , GeoCode= "ZAF" }); - _OSDPServers.Add(new DiscoveryServer() { DiscoveryServerUri = new Uri("https://disco.crm2.dynamics.com/XRMServices/2011/Discovery.svc"), DisplayName = "South America", ShortName = "SouthAmerica" , GeoCode="LATAM" }); - _OSDPServers.Add(new DiscoveryServer() { DiscoveryServerUri = new Uri("https://disco.crm17.dynamics.com/XRMServices/2011/Discovery.svc"), DisplayName = "Switzerland", ShortName = "Switzerland", GeoCode = "CHE" }); - _OSDPServers.Add(new DiscoveryServer() { DiscoveryServerUri = new Uri("https://disco.crm15.dynamics.com/XRMServices/2011/Discovery.svc"), DisplayName = "United Arab Emirates", ShortName = "UAE" , GeoCode="UAE" }); - _OSDPServers.Add(new DiscoveryServer() { DiscoveryServerUri = new Uri("https://disco.crm11.dynamics.com/XRMServices/2011/Discovery.svc"), DisplayName = "United Kingdom", ShortName = "GBR" , GeoCode = "GBR" }); - _OSDPServers.Add(new DiscoveryServer() { DiscoveryServerUri = new Uri("https://disco.crm.appsplatform.us/XRMServices/2011/Discovery.svc"), DisplayName = "US Gov DoD", ShortName = "DoD", GeoCode= "DOD", RequiresRegionalDiscovery = true, RegionalGlobalDiscoveryServer = new Uri("https://globaldisco.crm.appsplatform.us")}); - _OSDPServers.Add(new DiscoveryServer() { DiscoveryServerUri = new Uri("https://disco.crm.microsoftdynamics.us/XRMServices/2011/Discovery.svc"), DisplayName = "US Gov High", ShortName = "USG", GeoCode = "USG" , RequiresRegionalDiscovery = true, RegionalGlobalDiscoveryServer = new Uri("https://globaldisco.crm.microsoftdynamics.us")}); + _OSDPServers.Add(new DiscoveryServer() { DiscoveryServerUri = new Uri("https://disco.crm5.dynamics.com/XRMServices/2011/Discovery.svc"), DisplayName = "Asia Pacific Area", ShortName = "APAC", GeoCode = "APAC" }); + _OSDPServers.Add(new DiscoveryServer() { DiscoveryServerUri = new Uri("https://disco.crm3.dynamics.com/XRMServices/2011/Discovery.svc"), DisplayName = "Canada", ShortName = "CAN", GeoCode = "CAN" }); + _OSDPServers.Add(new DiscoveryServer() { DiscoveryServerUri = new Uri("https://disco.crm.dynamics.cn/XRMServices/2011/Discovery.svc"), DisplayName = "China", ShortName = "CHN", GeoCode = "CHN", RequiresRegionalDiscovery = true, RegionalGlobalDiscoveryServer = new Uri("https://globaldisco.crm.dynamics.cn") }); + _OSDPServers.Add(new DiscoveryServer() { DiscoveryServerUri = new Uri("https://disco.crm4.dynamics.com/XRMServices/2011/Discovery.svc"), DisplayName = "Europe, Middle East and Africa", ShortName = "EMEA", GeoCode = "EMEA" }); + _OSDPServers.Add(new DiscoveryServer() { DiscoveryServerUri = new Uri("https://disco.crm12.dynamics.com/XRMServices/2011/Discovery.svc"), DisplayName = "France", ShortName = "FRA", GeoCode = "FRA" }); + _OSDPServers.Add(new DiscoveryServer() { DiscoveryServerUri = new Uri("https://disco.crm16.dynamics.com/XRMServices/2011/Discovery.svc"), DisplayName = "Germany (Go Local)", ShortName = "GER", GeoCode = "GER" }); + _OSDPServers.Add(new DiscoveryServer() { DiscoveryServerUri = new Uri("https://disco.crm.Microsoftdynamics.de/XRMServices/2011/Discovery.svc"), DisplayName = "Germany", ShortName = "DEU", RequiresRegionalDiscovery = true, GeoCode = "DEU" }); + _OSDPServers.Add(new DiscoveryServer() { DiscoveryServerUri = new Uri("https://disco.crm8.dynamics.com/XRMServices/2011/Discovery.svc"), DisplayName = "India", ShortName = "IND", GeoCode = "IND" }); + _OSDPServers.Add(new DiscoveryServer() { DiscoveryServerUri = new Uri("https://disco.crm7.dynamics.com/XRMServices/2011/Discovery.svc"), DisplayName = "Japan", ShortName = "JPN", GeoCode = "JPN" }); + _OSDPServers.Add(new DiscoveryServer() { DiscoveryServerUri = new Uri("https://disco.crm21.dynamics.com/XRMServices/2011/Discovery.svc"), DisplayName = "Korea", ShortName = "KOR", GeoCode = "KOR" }); + _OSDPServers.Add(new DiscoveryServer() { DiscoveryServerUri = new Uri("https://disco.crm.dynamics.com/XRMServices/2011/Discovery.svc"), DisplayName = "North America", ShortName = "NorthAmerica" }); // Do not add Geo code to NAM or GCC, as they use the same server level GEO code. + _OSDPServers.Add(new DiscoveryServer() { DiscoveryServerUri = new Uri("https://disco.crm9.dynamics.com/XRMServices/2011/Discovery.svc"), DisplayName = "North America 2", ShortName = "NorthAmerica2", RequiresRegionalDiscovery = true, RegionalGlobalDiscoveryServer = new Uri("https://globaldisco.crm9.dynamics.com") }); + _OSDPServers.Add(new DiscoveryServer() { DiscoveryServerUri = new Uri("https://disco.crm19.dynamics.com/XRMServices/2011/Discovery.svc"), DisplayName = "Norway", ShortName = "NOR", GeoCode = "NOR" }); + _OSDPServers.Add(new DiscoveryServer() { DiscoveryServerUri = new Uri("https://disco.crm6.dynamics.com/XRMServices/2011/Discovery.svc"), DisplayName = "Oceania", ShortName = "Oceania", GeoCode = "OCE" }); + _OSDPServers.Add(new DiscoveryServer() { DiscoveryServerUri = new Uri("https://disco.crm14.dynamics.com/XRMServices/2011/Discovery.svc"), DisplayName = "South Africa", ShortName = "ZAF", GeoCode = "ZAF" }); + _OSDPServers.Add(new DiscoveryServer() { DiscoveryServerUri = new Uri("https://disco.crm2.dynamics.com/XRMServices/2011/Discovery.svc"), DisplayName = "South America", ShortName = "SouthAmerica", GeoCode = "LATAM" }); + _OSDPServers.Add(new DiscoveryServer() { DiscoveryServerUri = new Uri("https://disco.crm17.dynamics.com/XRMServices/2011/Discovery.svc"), DisplayName = "Switzerland", ShortName = "Switzerland", GeoCode = "CHE" }); + _OSDPServers.Add(new DiscoveryServer() { DiscoveryServerUri = new Uri("https://disco.crm15.dynamics.com/XRMServices/2011/Discovery.svc"), DisplayName = "United Arab Emirates", ShortName = "UAE", GeoCode = "UAE" }); + _OSDPServers.Add(new DiscoveryServer() { DiscoveryServerUri = new Uri("https://disco.crm11.dynamics.com/XRMServices/2011/Discovery.svc"), DisplayName = "United Kingdom", ShortName = "GBR", GeoCode = "GBR" }); + _OSDPServers.Add(new DiscoveryServer() { DiscoveryServerUri = new Uri("https://disco.crm.appsplatform.us/XRMServices/2011/Discovery.svc"), DisplayName = "US Gov DoD", ShortName = "DoD", GeoCode = "DOD", RequiresRegionalDiscovery = true, RegionalGlobalDiscoveryServer = new Uri("https://globaldisco.crm.appsplatform.us") }); + _OSDPServers.Add(new DiscoveryServer() { DiscoveryServerUri = new Uri("https://disco.crm.microsoftdynamics.us/XRMServices/2011/Discovery.svc"), DisplayName = "US Gov High", ShortName = "USG", GeoCode = "USG", RequiresRegionalDiscovery = true, RegionalGlobalDiscoveryServer = new Uri("https://globaldisco.crm.microsoftdynamics.us") }); #if DEBUG - var internalEnvInfo = new InternalEnvInfo(); - _OSDPServers.Add(new DiscoveryServer(internalEnvInfo.CrmLiveTieOSDP)); - _OSDPServers.Add(new DiscoveryServer(internalEnvInfo.CrmIntOSDP)); - _OSDPServers.Add(new DiscoveryServer(internalEnvInfo.CrmLiveTodayDebugOSDP)); - _OSDPServers.Add(new DiscoveryServer(internalEnvInfo.CrmLiveTodayDebugLIVE)); - _OSDPServers.Add(new DiscoveryServer(internalEnvInfo.Crm1BoxTest)); - _OSDPServers.Add(new DiscoveryServer(internalEnvInfo.CrmTIP)); - _OSDPServers.Add(new DiscoveryServer(internalEnvInfo.Crm2LiveTie)); + var internalEnvInfo = new InternalEnvInfo(); + _OSDPServers.Add(new DiscoveryServer(internalEnvInfo.DataverseInternalTest)); + _OSDPServers.Add(new DiscoveryServer(internalEnvInfo.CrmTIP)); + _OSDPServers.Add(new DiscoveryServer(internalEnvInfo.CrmLiveTieOSDP)); + _OSDPServers.Add(new DiscoveryServer(internalEnvInfo.CrmIntOSDP)); + _OSDPServers.Add(new DiscoveryServer(internalEnvInfo.CrmLiveTodayDebugOSDP)); + _OSDPServers.Add(new DiscoveryServer(internalEnvInfo.CrmLiveTodayDebugLIVE)); + _OSDPServers.Add(new DiscoveryServer(internalEnvInfo.Crm1BoxTest)); + _OSDPServers.Add(new DiscoveryServer(internalEnvInfo.Crm2LiveTie)); #endif - } + } - /// - /// Parses an OrgURI to determine what the supporting discovery server is. - /// - /// - /// - public DiscoveryServer GetServerByOrgUrl ( Uri orgUri ) - { - if (orgUri == null) - return null; - // remove the https://disco from the request. - string domainUri = orgUri.GetComponents(UriComponents.Host, UriFormat.UriEscaped); - if (_OSDPServers != null) - { - var rslts = _OSDPServers.Where(w => w.DiscoveryServerUri.ToString().Contains(domainUri)); - if (rslts.Count() > 0) - { - return rslts.FirstOrDefault(); - } - else - return null; - } - else - return null; - } + /// + /// Parses an OrgURI to determine what the supporting discovery server is. + /// + /// + /// + public DiscoveryServer GetServerByOrgUrl(Uri orgUri) + { + if (orgUri == null) + return null; + // remove the https://disco from the request. + string domainUri = orgUri.GetComponents(UriComponents.Host, UriFormat.UriEscaped); + if (_OSDPServers != null) + { + var rslts = _OSDPServers.Where(w => w.DiscoveryServerUri.ToString().Contains(domainUri)); + if (rslts.Count() > 0) + { + return rslts.FirstOrDefault(); + } + else + return null; + } + else + return null; + } - /// - /// Finds a Server by Name in the List or return null. - /// - /// Short Name of the server you are looking for - /// DiscoveryServer Data or Null - public DiscoveryServer GetServerByShortName(string shortName) - { - if (_OSDPServers != null) - return _OSDPServers.FirstOrDefault(i => i.ShortName.Equals(shortName, StringComparison.CurrentCultureIgnoreCase)); - else - return null; - } + /// + /// Finds a Server by Name in the List or return null. + /// + /// Short Name of the server you are looking for + /// DiscoveryServer Data or Null + public DiscoveryServer GetServerByShortName(string shortName) + { + if (_OSDPServers != null) + return _OSDPServers.FirstOrDefault(i => i.ShortName.Equals(shortName, StringComparison.CurrentCultureIgnoreCase)); + else + return null; + } - /// - /// Finds a Server Info by GEO Code. Note NorthAmerica and GCC cannot be located this way. - /// to use with NA you must short name, NorthAmerica for NAM and NorthAmerica2 for GCC. - /// - /// GEO of Discovery Instance you are looking for - /// DiscoveryServer Data or Null - public DiscoveryServer GetServerByGeo(string geoCode) - { - if (_OSDPServers != null) - return _OSDPServers.FirstOrDefault(i => i.GeoCode.Equals(geoCode, StringComparison.CurrentCultureIgnoreCase)); - else - return null; - } + /// + /// Finds a Server Info by GEO Code. Note NorthAmerica and GCC cannot be located this way. + /// to use with NA you must short name, NorthAmerica for NAM and NorthAmerica2 for GCC. + /// + /// GEO of Discovery Instance you are looking for + /// DiscoveryServer Data or Null + public DiscoveryServer GetServerByGeo(string geoCode) + { + if (_OSDPServers != null) + return _OSDPServers.FirstOrDefault(i => i.GeoCode.Equals(geoCode, StringComparison.CurrentCultureIgnoreCase)); + else + return null; + } - /// - /// Finds the server short name by server uri - /// - /// Name of the Server to find - /// - public string GetServerShortNameByDisplayName(string serverDisplayName) - { - try - { - if (serverDisplayName.Equals("User Defined Org Detail")) - return null; + /// + /// Finds the server short name by server uri + /// + /// Name of the Server to find + /// + public string GetServerShortNameByDisplayName(string serverDisplayName) + { + try + { + if (serverDisplayName.Equals("User Defined Org Detail")) + return null; - if (_OSDPServers != null) - return _OSDPServers.FirstOrDefault(i => i.DisplayName.Equals(serverDisplayName, StringComparison.CurrentCultureIgnoreCase)).ShortName; - } - catch (Exception Ex) - { - logger.Log(string.Format(CultureInfo.InvariantCulture, "Failed to find Short Name for {0}", serverDisplayName), System.Diagnostics.TraceEventType.Error, Ex); - } - return null; - } + if (_OSDPServers != null) + return _OSDPServers.FirstOrDefault(i => i.DisplayName.Equals(serverDisplayName, StringComparison.CurrentCultureIgnoreCase)).ShortName; + } + catch (Exception Ex) + { + logger.Log(string.Format(CultureInfo.InvariantCulture, "Failed to find Short Name for {0}", serverDisplayName), System.Diagnostics.TraceEventType.Error, Ex); + } + return null; + } - #region INotifyPropertyChanged - /// - /// Raised when a property changes - /// - public event PropertyChangedEventHandler PropertyChanged; - private void NotifyPropertyChanged(String info) - { - if (PropertyChanged != null) - { - PropertyChanged(this, new PropertyChangedEventArgs(info)); - } - } + #region INotifyPropertyChanged + /// + /// Raised when a property changes + /// + public event PropertyChangedEventHandler PropertyChanged; + private void NotifyPropertyChanged(String info) + { + if (PropertyChanged != null) + { + PropertyChanged(this, new PropertyChangedEventArgs(info)); + } + } - #region IDisposable Support - private bool disposedValue = false; // To detect redundant calls + #region IDisposable Support + private bool disposedValue = false; // To detect redundant calls - /// - /// Clean up - /// - /// - protected virtual void Dispose(bool disposing) - { - if (!disposedValue) - { - if (disposing) - { - if (logger != null) - logger.Dispose(); + /// + /// Clean up + /// + /// + protected virtual void Dispose(bool disposing) + { + if (!disposedValue) + { + if (disposing) + { + if (logger != null) + logger.Dispose(); - if (_OSDPServers != null) - _OSDPServers.Clear(); + if (_OSDPServers != null) + _OSDPServers.Clear(); - } + } - _OSDPServers = null; + _OSDPServers = null; - disposedValue = true; - } - } + disposedValue = true; + } + } - /// - /// Clean up - /// - public void Dispose() - { - Dispose(true); - } - #endregion - #endregion - } + /// + /// Clean up + /// + public void Dispose() + { + Dispose(true); + } + #endregion + #endregion + } - #region CrmOnlineDiscoServerListing for WPF Controls + #region CrmOnlineDiscoServerListing for WPF Controls - /// - /// Describes a discovery server that can be used to determine what organizations a user is a member of. - /// - public class DiscoveryServer : INotifyPropertyChanged - { - #region Properties + /// + /// Describes a discovery server that can be used to determine what organizations a user is a member of. + /// + public class DiscoveryServer : INotifyPropertyChanged + { + #region Properties - private string _DisplayName = string.Empty; - private string _ShortName = string.Empty; - private Uri _DiscoveryServer = null; - private bool _RequiresRegionalDiscovery = false; - private Uri _RegionalGlobalDiscovery = null; - private string _GeoCode = string.Empty; + private string _DisplayName = string.Empty; + private string _ShortName = string.Empty; + private Uri _DiscoveryServer = null; + private bool _RequiresRegionalDiscovery = false; + private Uri _RegionalGlobalDiscovery = null; + private string _GeoCode = string.Empty; - /// - /// Display name of the Discovery Server - /// - public string DisplayName { get { return _DisplayName; } set { if (value != _DisplayName) _DisplayName = value; NotifyPropertyChanged("DisplayName"); } } - /// - /// Short name of the Discovery Server, this is used to store the server in the users config for later use. - /// - public string ShortName { get { return _ShortName; } set { if (value != _ShortName) _ShortName = value; NotifyPropertyChanged("ShortName"); } } - /// - /// Discovery server Uri, this is the URI necessary to connect to the Discovery server - /// - public Uri DiscoveryServerUri { get { return _DiscoveryServer; } set { if (value != _DiscoveryServer) _DiscoveryServer = value; NotifyPropertyChanged("DiscoveryServer"); } } - /// - /// When true, the global discovery server cannot be used to locate this instance, it must be a regional discovery query - /// - public bool RequiresRegionalDiscovery { get { return _RequiresRegionalDiscovery; } set { if (value != _RequiresRegionalDiscovery) _RequiresRegionalDiscovery = value; NotifyPropertyChanged("IsRestricted"); } } - /// - /// Server used to override the regional discovery server, if present its treated as using the Global Discovery server - /// - public Uri RegionalGlobalDiscoveryServer { get { return _RegionalGlobalDiscovery; } set { if (value != _RegionalGlobalDiscovery) _RegionalGlobalDiscovery = value; NotifyPropertyChanged("RegionalGlobalDiscoveryServer"); } } - /// - /// Geo that hosts this Disco endpoint - /// - public string GeoCode { get { return _GeoCode; } set { if (value != _GeoCode) _GeoCode = value; NotifyPropertyChanged("GeoCode"); } } - #endregion + /// + /// Display name of the Discovery Server + /// + public string DisplayName { get { return _DisplayName; } set { if (value != _DisplayName) _DisplayName = value; NotifyPropertyChanged("DisplayName"); } } + /// + /// Short name of the Discovery Server, this is used to store the server in the users config for later use. + /// + public string ShortName { get { return _ShortName; } set { if (value != _ShortName) _ShortName = value; NotifyPropertyChanged("ShortName"); } } + /// + /// Discovery server Uri, this is the URI necessary to connect to the Discovery server + /// + public Uri DiscoveryServerUri { get { return _DiscoveryServer; } set { if (value != _DiscoveryServer) _DiscoveryServer = value; NotifyPropertyChanged("DiscoveryServer"); } } + /// + /// When true, the global discovery server cannot be used to locate this instance, it must be a regional discovery query + /// + public bool RequiresRegionalDiscovery { get { return _RequiresRegionalDiscovery; } set { if (value != _RequiresRegionalDiscovery) _RequiresRegionalDiscovery = value; NotifyPropertyChanged("IsRestricted"); } } + /// + /// Server used to override the regional discovery server, if present its treated as using the Global Discovery server + /// + public Uri RegionalGlobalDiscoveryServer { get { return _RegionalGlobalDiscovery; } set { if (value != _RegionalGlobalDiscovery) _RegionalGlobalDiscovery = value; NotifyPropertyChanged("RegionalGlobalDiscoveryServer"); } } + /// + /// Geo that hosts this Disco endpoint + /// + public string GeoCode { get { return _GeoCode; } set { if (value != _GeoCode) _GeoCode = value; NotifyPropertyChanged("GeoCode"); } } + #endregion - /// - /// Default constructor - /// - public DiscoveryServer() - { } + /// + /// Default constructor + /// + public DiscoveryServer() + { } - /// - /// Accepts a Server Info object - /// - public DiscoveryServer(ServerInfo serverInfo) - { - // load info from a server Info object. - DiscoveryServerUri = new Uri(serverInfo.DiscoveryServer); - DisplayName = serverInfo.DisplayName; - ShortName = serverInfo.ShortName; - RequiresRegionalDiscovery = serverInfo.RequiresRegionalDiscovery; - RegionalGlobalDiscoveryServer = serverInfo.RegionalGlobalDiscoveryUri; - GeoCode = serverInfo.GeoCode; - } + /// + /// Accepts a Server Info object + /// + public DiscoveryServer(ServerInfo serverInfo) + { + // load info from a server Info object. + DiscoveryServerUri = new Uri(serverInfo.DiscoveryServer); + DisplayName = serverInfo.DisplayName; + ShortName = serverInfo.ShortName; + RequiresRegionalDiscovery = serverInfo.RequiresRegionalDiscovery; + RegionalGlobalDiscoveryServer = serverInfo.RegionalGlobalDiscoveryUri; + GeoCode = serverInfo.GeoCode; + } - #region INotifyPropertyChanged - /// - /// Raised when a property changes - /// - public event PropertyChangedEventHandler PropertyChanged; - private void NotifyPropertyChanged(String info) - { - if (PropertyChanged != null) - { - PropertyChanged(this, new PropertyChangedEventArgs(info)); - } - } - #endregion - } + #region INotifyPropertyChanged + /// + /// Raised when a property changes + /// + public event PropertyChangedEventHandler PropertyChanged; + private void NotifyPropertyChanged(String info) + { + if (PropertyChanged != null) + { + PropertyChanged(this, new PropertyChangedEventArgs(info)); + } + } + #endregion + } - #endregion + #endregion } diff --git a/src/GeneralTools/DataverseClient/Client/ServiceClient.cs b/src/GeneralTools/DataverseClient/Client/ServiceClient.cs index 93e9d08..0e4459b 100644 --- a/src/GeneralTools/DataverseClient/Client/ServiceClient.cs +++ b/src/GeneralTools/DataverseClient/Client/ServiceClient.cs @@ -577,7 +577,7 @@ public string SdkVersionProperty { if (string.IsNullOrEmpty(_sdkVersionProperty)) { - _sdkVersionProperty = typeof(OrganizationDetail).Assembly.GetCustomAttribute().Version ?? FileVersionInfo.GetVersionInfo(typeof(OrganizationDetail).Assembly.Location).FileVersion; + _sdkVersionProperty = Environs.XrmSdkFileVersion; } return _sdkVersionProperty; } @@ -1741,11 +1741,13 @@ internal OrganizationResponse Command_Execute(OrganizationRequest req, string er if (bypassPluginExecution && Utilities.FeatureVersionMinimums.IsFeatureValidForEnviroment(_connectionSvc?.OrganizationVersion, Utilities.FeatureVersionMinimums.AllowBypassCustomPlugin)) req.Parameters.Add(Utilities.RequestHeaders.BYPASSCUSTOMPLUGINEXECUTION, true); - _logEntry.Log(string.Format(CultureInfo.InvariantCulture, "Execute Command - {0}{1}: {3}RequestID={2}", + //RequestId Logging line for telemetry + string requestIdLogSegement = _logEntry.GetFormatedRequestSessionIdString(requestTrackingId, SessionTrackingId); + + _logEntry.Log(string.Format(CultureInfo.InvariantCulture, "Execute Command - {0}{1}: {2}", req.RequestName, string.IsNullOrEmpty(errorStringCheck) ? "" : $" : {errorStringCheck} ", - requestTrackingId.ToString(), - SessionTrackingId.HasValue && SessionTrackingId.Value != Guid.Empty ? $"SessionID={SessionTrackingId.Value.ToString()} : " : "" + requestIdLogSegement ), TraceEventType.Verbose); logDt.Restart(); @@ -1761,13 +1763,12 @@ internal OrganizationResponse Command_Execute(OrganizationRequest req, string er rsp = DataverseService.Execute(req); logDt.Stop(); - _logEntry.Log(string.Format(CultureInfo.InvariantCulture, "Executed Command - {0}{2}: {5}RequestID={3} {4}: duration={1}", + _logEntry.Log(string.Format(CultureInfo.InvariantCulture, "Executed Command - {0}{2}: {3} {4}: duration={1}", req.RequestName, logDt.Elapsed.ToString(), string.IsNullOrEmpty(errorStringCheck) ? "" : $" : {errorStringCheck} ", - requestTrackingId.ToString(), - LockWait == TimeSpan.Zero ? string.Empty : string.Format(": LockWaitDuration={0} ", LockWait.ToString()), - SessionTrackingId.HasValue && SessionTrackingId.Value != Guid.Empty ? $"SessionID={SessionTrackingId.Value.ToString()} : " : "" + requestIdLogSegement, + LockWait == TimeSpan.Zero ? string.Empty : string.Format(": LockWaitDuration={0} ", LockWait.ToString()) ), TraceEventType.Verbose); resp = rsp; } diff --git a/src/GeneralTools/DataverseClient/Client/TestingHelper.cs b/src/GeneralTools/DataverseClient/Client/TestingHelper.cs index 2f68143..33978ea 100644 --- a/src/GeneralTools/DataverseClient/Client/TestingHelper.cs +++ b/src/GeneralTools/DataverseClient/Client/TestingHelper.cs @@ -1,4 +1,4 @@ -using System; +using System; using System.Collections.Generic; namespace Microsoft.PowerPlatform.Dataverse.Client @@ -128,7 +128,7 @@ public sealed class ServerInfo public string ShortName { get; set; } /// - /// Sets the restricted status of the instance. ( restricted means it is not in the global discovery servers ) + /// Sets the restricted status of the instance. ( restricted means it is not in the global discovery servers ) /// public bool RequiresRegionalDiscovery { get; set; } @@ -138,7 +138,7 @@ public sealed class ServerInfo public Uri RegionalGlobalDiscoveryUri { get; set; } /// - /// Geo Code + /// Geo Code /// public string GeoCode { get; set; } @@ -149,10 +149,10 @@ public ServerInfo() { // Defaulting to true for Restricted access RequiresRegionalDiscovery = true; - // defaulting to null + // defaulting to null RegionalGlobalDiscoveryUri = null; - // Default to null. - GeoCode = null; + // Default to null. + GeoCode = null; } } @@ -171,6 +171,7 @@ public sealed class InternalEnvInfo private ServerInfo _discocrm1boxtestOSDP; private ServerInfo _discocrmtipOSDP; private ServerInfo _discocrm2LiveTieOSDP; + private ServerInfo _dvInternalTest; #region Live Specific /// @@ -238,6 +239,29 @@ public ServerInfo CrmLiveTodayDebugLIVE #endregion Live Specific #region OSDP Specific + + /// + /// Dataverse internal debug replacement for TIE + /// + public ServerInfo DataverseInternalTest + { + get + { + if (_dvInternalTest == null) + { + _dvInternalTest = new ServerInfo() + { + DiscoveryServer = "https://disco.crm.crmtest.com/XRMServices/2011/Discovery.svc", + DisplayName = "Internal TEST", + ShortName = "TST", + GeoCode="TST" + }; + } + + return _dvInternalTest; + } + } + /// /// Returns settings for CrmLiveTieOSDP /// @@ -301,7 +325,7 @@ public ServerInfo CrmLiveTodayDebugOSDP } /// - /// this is the connect infor for the 1box config for EDOG env. + /// this is the connect infor for the 1box config for EDOG env. /// public ServerInfo Crm1BoxTest { diff --git a/src/GeneralTools/DataverseClient/Client/Utils/Utils.cs b/src/GeneralTools/DataverseClient/Client/Utils/Utils.cs index 9598b70..4ead4d7 100644 --- a/src/GeneralTools/DataverseClient/Client/Utils/Utils.cs +++ b/src/GeneralTools/DataverseClient/Client/Utils/Utils.cs @@ -11,6 +11,7 @@ using System.Collections.Generic; using System.Diagnostics; using System.Dynamic; +using System.Globalization; using System.Linq; using System.Net; using System.Net.Http; @@ -25,46 +26,6 @@ namespace Microsoft.PowerPlatform.Dataverse.Client /// internal class Utilities { - /// - /// Returns the file version of passed "executing Assembly" - /// - /// The assembly whose version is required. - /// - public static Version GetFileVersion(Assembly executingAssembly) - { - try - { - if (executingAssembly != null) - { - AssemblyName asmName = new AssemblyName(executingAssembly.FullName); - Version fileVersion = asmName.Version; - - // try to get the build version - string localPath = string.Empty; - - Uri fileUri = null; - if (Uri.TryCreate(executingAssembly.CodeBase, UriKind.Absolute, out fileUri)) - { - if (fileUri.IsFile) - localPath = fileUri.LocalPath; - - if (!string.IsNullOrEmpty(localPath)) - if (System.IO.File.Exists(localPath)) - { - FileVersionInfo fv = FileVersionInfo.GetVersionInfo(localPath); - if (fv != null) - { - fileVersion = new Version(fv.FileVersion); - } - } - } - return fileVersion; - } - } - catch { } - - return null; - } internal static DiscoveryServer GetDiscoveryServerByUri(Uri orgUri) { @@ -610,19 +571,19 @@ internal static ExpandoObject ToExpandoObject(Entity sourceEntity, MetadataUtili { if (attribDateTimeData.DateTimeBehavior == DateTimeBehavior.DateOnly) { - value = dateTimeValue.ToUniversalTime().ToString("yyyy-MM-dd"); + value = dateTimeValue.ToUniversalTime().ToString("yyyy-MM-dd", CultureInfo.InvariantCulture); } else { if (attribDateTimeData.DateTimeBehavior == DateTimeBehavior.TimeZoneIndependent) { - value = dateTimeValue.ToUniversalTime().ToString("yyyy-MM-ddTHH:mm:ss.fff"); + value = dateTimeValue.ToUniversalTime().ToString("yyyy-MM-ddTHH:mm:ss", CultureInfo.InvariantCulture); } else { if (attribDateTimeData.DateTimeBehavior == DateTimeBehavior.UserLocal) { - value = dateTimeValue.ToUniversalTime().ToString("yyyy-MM-ddTHH:mm:ss.fffZ"); + value = dateTimeValue.ToUniversalTime().ToString("yyyy-MM-ddTHH:mm:ssZ", CultureInfo.InvariantCulture); } } } @@ -848,7 +809,24 @@ internal static string ParseAltKeyCollection(KeyAttributeCollection keyValues) } else { - keycollection += $"{itm.Key}='{itm.Value}',"; + if (itm.Value is int iValue) + { + keycollection += $"{itm.Key}={iValue.ToString(CultureInfo.InvariantCulture)},"; + } + else if (itm.Value is float fValue) + { + keycollection += $"{itm.Key}={fValue.ToString(CultureInfo.InvariantCulture)},"; + } + else if (itm.Value is OptionSetValue oValue) + { + keycollection += $"{itm.Key}={oValue.Value},"; + } + else if (itm.Value is DateTime dtValue) // Note : Should work for 'datetime types' may not work for date only types. + { + keycollection += $"{itm.Key}={dtValue.ToUniversalTime().ToString("yyyy-MM-ddTHH:mm:ssZ", CultureInfo.InvariantCulture)},"; + } + else + keycollection += $"{itm.Key}='{itm.Value.ToString().Replace("'", "''")}',"; } } return keycollection.Remove(keycollection.Length - 1); // remove trailing , diff --git a/src/GeneralTools/DataverseClient/ConnectControl/ConnectionManager.cs b/src/GeneralTools/DataverseClient/ConnectControl/ConnectionManager.cs index fa17fda..2fff664 100644 --- a/src/GeneralTools/DataverseClient/ConnectControl/ConnectionManager.cs +++ b/src/GeneralTools/DataverseClient/ConnectControl/ConnectionManager.cs @@ -522,6 +522,19 @@ private void bgWorker_DoWork(object sender, DoWorkEventArgs e) bServerGood = ValidateServerConnection(null); e.Result = bServerGood; + if (!bServerGood) + { + // Clear settings to allow for a retry using non direct communication + StorageUtils.SetConfigKey(ServerConfigKeys, Dynamics_ConfigFileServerKeys.DirectConnectionUri, string.Empty); + StorageUtils.SetConfigKey(ServerConfigKeys, Dynamics_ConfigFileServerKeys.UseDirectConnection, false.ToString()); + } + else + { + // Set URL that was connected too. + StorageUtils.SetConfigKey(ServerConfigKeys, Dynamics_ConfigFileServerKeys.DirectConnectionUri, ServiceClient.ConnectedOrgUriActual.ToString()); + StorageUtils.SetConfigKey(ServerConfigKeys, Dynamics_ConfigFileServerKeys.UseDirectConnection, true.ToString()); + } + if (_orgListView != null && _orgListView.OrgsList != null && _orgListView.OrgsList.Count > 1) // Orgs found in the last run... Raise the MultiOrg Event. _bgWorker.ReportProgress(100, new ServerConnectStatusEventArgs("User attention required", false, true)); @@ -1927,6 +1940,8 @@ public Dictionary LoadConfigFromFile(bool SetServerConfigKey(config, Dynamics_ConfigFileServerKeys.Authority, overrideDefaultSet: readLocalFirst); SetServerConfigKey(config, Dynamics_ConfigFileServerKeys.UserId, overrideDefaultSet: readLocalFirst); SetServerConfigKey(config, Dynamics_ConfigFileServerKeys.DirectConnectionUri, overrideDefaultSet: readLocalFirst); + SetServerConfigKey(config, Dynamics_ConfigFileServerKeys.UseDirectConnection, overrideDefaultSet: readLocalFirst); + if (config.AppSettings.Settings[Dynamics_ConfigFileServerKeys.UseDefaultCreds.ToString()] != null) { @@ -2105,6 +2120,8 @@ public bool SaveConfigToFile(Dictionary c config.AppSettings.Settings.Remove(Dynamics_ConfigFileServerKeys.AskForOrg.ToString()); config.AppSettings.Settings.Remove(Dynamics_ConfigFileServerKeys.AdvancedCheck.ToString()); config.AppSettings.Settings.Remove(Dynamics_ConfigFileServerKeys.DirectConnectionUri.ToString()); + config.AppSettings.Settings.Remove(Dynamics_ConfigFileServerKeys.UseDirectConnection.ToString()); + // Create new data. config.AppSettings.Settings.Add(Dynamics_ConfigFileServerKeys.CrmDeploymentType.ToString(), StorageUtils.GetConfigKey(configToSave, Dynamics_ConfigFileServerKeys.CrmDeploymentType)); @@ -2120,6 +2137,7 @@ public bool SaveConfigToFile(Dictionary c config.AppSettings.Settings.Add(Dynamics_ConfigFileServerKeys.CrmDomain.ToString(), StorageUtils.GetConfigKey(configToSave, Dynamics_ConfigFileServerKeys.CrmDomain)); config.AppSettings.Settings.Add(Dynamics_ConfigFileServerKeys.AdvancedCheck.ToString(), StorageUtils.GetConfigKey(configToSave, Dynamics_ConfigFileServerKeys.AdvancedCheck)); config.AppSettings.Settings.Add(Dynamics_ConfigFileServerKeys.DirectConnectionUri.ToString(), StorageUtils.GetConfigKey(configToSave, Dynamics_ConfigFileServerKeys.DirectConnectionUri)); + config.AppSettings.Settings.Add(Dynamics_ConfigFileServerKeys.UseDirectConnection.ToString(), StorageUtils.GetConfigKey(configToSave, Dynamics_ConfigFileServerKeys.UseDirectConnection)); if (ServiceClient != null && ServiceClient.ActiveAuthenticationType == AuthenticationType.OAuth) { diff --git a/src/GeneralTools/DataverseClient/ConnectControl/Model/OnlineDiscoveryServers.cs b/src/GeneralTools/DataverseClient/ConnectControl/Model/OnlineDiscoveryServers.cs index 382699f..d6124dd 100644 --- a/src/GeneralTools/DataverseClient/ConnectControl/Model/OnlineDiscoveryServers.cs +++ b/src/GeneralTools/DataverseClient/ConnectControl/Model/OnlineDiscoveryServers.cs @@ -85,8 +85,10 @@ public OnlineDiscoveryServers() RegionalServers.Add(new OnlineDiscoveryServer() { DiscoveryServer = new Uri("https://disco.crm16.dynamics.com/XRMServices/2011/Discovery.svc"), DisplayName = "Germany (Go Local)", ShortName = "GER", GeoCode = "GER" }); RegionalServers.Add(new OnlineDiscoveryServer() { DiscoveryServer = new Uri("https://disco.crm8.dynamics.com/XRMServices/2011/Discovery.svc"), DisplayName = "India", ShortName = "IND", GeoCode = "IND" }); RegionalServers.Add(new OnlineDiscoveryServer() { DiscoveryServer = new Uri("https://disco.crm7.dynamics.com/XRMServices/2011/Discovery.svc"), DisplayName = "Japan", ShortName = "JPN", GeoCode = "JPN" }); + RegionalServers.Add(new OnlineDiscoveryServer() { DiscoveryServer = new Uri("https://disco.crm21.dynamics.com/XRMServices/2011/Discovery.svc"), DisplayName = "Korea", ShortName = "KOR", GeoCode = "KOR" }); RegionalServers.Add(new OnlineDiscoveryServer() { DiscoveryServer = new Uri("https://disco.crm.dynamics.com/XRMServices/2011/Discovery.svc"), DisplayName = "North America", ShortName = "NorthAmerica" }); // Do not add Geo code to NAM or GCC, as they use the same server level GEO code. RegionalServers.Add(new OnlineDiscoveryServer() { DiscoveryServer = new Uri("https://disco.crm9.dynamics.com/XRMServices/2011/Discovery.svc"), DisplayName = "North America 2 (GCC)", ShortName = "NorthAmerica2", RequiresRegionalDiscovery = true, RegionalGlobalDiscoveryServer = new Uri("https://globaldisco.crm9.dynamics.com") }); + RegionalServers.Add(new OnlineDiscoveryServer() { DiscoveryServer = new Uri("https://disco.crm19.dynamics.com/XRMServices/2011/Discovery.svc"), DisplayName = "Norway", ShortName = "NOR", GeoCode = "NOR" }); RegionalServers.Add(new OnlineDiscoveryServer() { DiscoveryServer = new Uri("https://disco.crm6.dynamics.com/XRMServices/2011/Discovery.svc"), DisplayName = "Oceania", ShortName = "Oceania", GeoCode = "OCE" }); RegionalServers.Add(new OnlineDiscoveryServer() { DiscoveryServer = new Uri("https://disco.crm14.dynamics.com/XRMServices/2011/Discovery.svc"), DisplayName = "South Africa", ShortName = "ZAF", GeoCode = "ZAF" }); RegionalServers.Add(new OnlineDiscoveryServer() { DiscoveryServer = new Uri("https://disco.crm2.dynamics.com/XRMServices/2011/Discovery.svc"), DisplayName = "South America", ShortName = "SouthAmerica", GeoCode = "LATAM" }); @@ -104,8 +106,10 @@ public OnlineDiscoveryServers() _OSDPServers.Add(new OnlineDiscoveryServer() { DiscoveryServer = new Uri("https://disco.crm.Microsoftdynamics.de/XRMServices/2011/Discovery.svc"), DisplayName = "Germany", ShortName = "DEU", RequiresRegionalDiscovery = true, GeoCode = "DEU" }); _OSDPServers.Add(new OnlineDiscoveryServer() { DiscoveryServer = new Uri("https://disco.crm8.dynamics.com/XRMServices/2011/Discovery.svc"), DisplayName = "India", ShortName = "IND", GeoCode = "IND" }); _OSDPServers.Add(new OnlineDiscoveryServer() { DiscoveryServer = new Uri("https://disco.crm7.dynamics.com/XRMServices/2011/Discovery.svc"), DisplayName = "Japan", ShortName = "JPN", GeoCode = "JPN" }); + _OSDPServers.Add(new OnlineDiscoveryServer() { DiscoveryServer = new Uri("https://disco.crm21.dynamics.com/XRMServices/2011/Discovery.svc"), DisplayName = "Korea", ShortName = "KOR", GeoCode = "KOR" }); _OSDPServers.Add(new OnlineDiscoveryServer() { DiscoveryServer = new Uri("https://disco.crm.dynamics.com/XRMServices/2011/Discovery.svc"), DisplayName = "North America", ShortName = "NorthAmerica" }); // Do not add Geo code to NAM or GCC, as they use the same server level GEO code. _OSDPServers.Add(new OnlineDiscoveryServer() { DiscoveryServer = new Uri("https://disco.crm9.dynamics.com/XRMServices/2011/Discovery.svc"), DisplayName = "North America 2 (GCC)", ShortName = "NorthAmerica2", RequiresRegionalDiscovery = true, RegionalGlobalDiscoveryServer = new Uri("https://globaldisco.crm9.dynamics.com") }); + _OSDPServers.Add(new OnlineDiscoveryServer() { DiscoveryServer = new Uri("https://disco.crm19.dynamics.com/XRMServices/2011/Discovery.svc"), DisplayName = "Norway", ShortName = "NOR", GeoCode = "NOR" }); _OSDPServers.Add(new OnlineDiscoveryServer() { DiscoveryServer = new Uri("https://disco.crm6.dynamics.com/XRMServices/2011/Discovery.svc"), DisplayName = "Oceania", ShortName = "Oceania", GeoCode = "OCE" }); _OSDPServers.Add(new OnlineDiscoveryServer() { DiscoveryServer = new Uri("https://disco.crm14.dynamics.com/XRMServices/2011/Discovery.svc"), DisplayName = "South Africa", ShortName = "ZAF", GeoCode = "ZAF" }); _OSDPServers.Add(new OnlineDiscoveryServer() { DiscoveryServer = new Uri("https://disco.crm2.dynamics.com/XRMServices/2011/Discovery.svc"), DisplayName = "South America", ShortName = "SouthAmerica", GeoCode = "LATAM" }); @@ -123,6 +127,7 @@ public OnlineDiscoveryServers() TestServers.Add(new OnlineDiscoveryServer(internalEnvInfo.Crm1BoxTest)); TestServers.Add(new OnlineDiscoveryServer(internalEnvInfo.CrmTIP)); TestServers.Add(new OnlineDiscoveryServer(internalEnvInfo.Crm2LiveTie)); + TestServers.Add(new OnlineDiscoveryServer(internalEnvInfo.DataverseInternalTest)); _OSDPServers.Add(new OnlineDiscoveryServer(internalEnvInfo.CrmLiveTieOSDP)); _OSDPServers.Add(new OnlineDiscoveryServer(internalEnvInfo.CrmIntOSDP)); @@ -131,6 +136,7 @@ public OnlineDiscoveryServers() _OSDPServers.Add(new OnlineDiscoveryServer(internalEnvInfo.Crm1BoxTest)); _OSDPServers.Add(new OnlineDiscoveryServer(internalEnvInfo.CrmTIP)); _OSDPServers.Add(new OnlineDiscoveryServer(internalEnvInfo.Crm2LiveTie)); + _OSDPServers.Add(new OnlineDiscoveryServer(internalEnvInfo.DataverseInternalTest)); #endif } diff --git a/src/GeneralTools/DataverseClient/ConnectControl/ServerLoginControl.xaml.cs b/src/GeneralTools/DataverseClient/ConnectControl/ServerLoginControl.xaml.cs index 0b9a35c..2e71f26 100644 --- a/src/GeneralTools/DataverseClient/ConnectControl/ServerLoginControl.xaml.cs +++ b/src/GeneralTools/DataverseClient/ConnectControl/ServerLoginControl.xaml.cs @@ -457,9 +457,18 @@ private void UpdateServerConfigKeysFromUI() StorageUtils.SetConfigKey(ServerConfigKeys, Dynamics_ConfigFileServerKeys.AuthHomeRealm, string.Empty); if (cbAskforOrg.IsChecked.Value) + { StorageUtils.SetConfigKey(ServerConfigKeys, Dynamics_ConfigFileServerKeys.CrmOrg, string.Empty); + StorageUtils.SetConfigKey(ServerConfigKeys, Dynamics_ConfigFileServerKeys.UseDirectConnection, false.ToString()); + } else + { StorageUtils.SetConfigKey(ServerConfigKeys, Dynamics_ConfigFileServerKeys.CrmOrg, tbCrmOrg.Text); + if (!string.IsNullOrEmpty(StorageUtils.GetConfigKey(ServerConfigKeys, Dynamics_ConfigFileServerKeys.DirectConnectionUri))) + { + StorageUtils.SetConfigKey(ServerConfigKeys, Dynamics_ConfigFileServerKeys.UseDirectConnection, true.ToString()); + } + } StorageUtils.SetConfigKey(ServerConfigKeys, Dynamics_ConfigFileServerKeys.AdvancedCheck, cbAdvanced.IsChecked.Value.ToString()); diff --git a/src/nuspecs/Microsoft.PowerPlatform.Dataverse.Client.ReleaseNotes.txt b/src/nuspecs/Microsoft.PowerPlatform.Dataverse.Client.ReleaseNotes.txt index 965aa78..7cbdd27 100644 --- a/src/nuspecs/Microsoft.PowerPlatform.Dataverse.Client.ReleaseNotes.txt +++ b/src/nuspecs/Microsoft.PowerPlatform.Dataverse.Client.ReleaseNotes.txt @@ -8,6 +8,17 @@ Notice: Note: that only AD on FullFramework, OAuth, Certificate, ClientSecret Authentication types are supported at this time. ++CURRENTRELEASEID++ +Accepted fixes requested by Git user 0xced - thanks for your contrib's! +Fixed Null ref bug for missing redirect URI (if it gets that far) https://github.com/microsoft/PowerPlatform-DataverseServiceClient/pull/246 +Fixed Missing ConfigureAwait's on some Async methods in auth chain. https://github.com/microsoft/PowerPlatform-DataverseServiceClient/pull/247 +Fixed several issues with Alternate Keys being used for entity references relating to use of Int's OptionSets and DateTime alt Key types. Git Issues #244 and #231 +Fixed issue with suppress duplicate detection header not working correctly via WebAPI path Git Issue #266 +Fixed an issue with DateTime's being incorrectly formatted on non english hosts. Git Issue #216 +Speculative Fix for Date Only types not correctly interpreting TimeZone Offset when in a UTC + Timezone. Git Issue #143 +Added Discovery Filter support for Korea and Norway GEO's + + +0.6.1: Minor Bump to 0.6.x - *Should* be last bump prior to 1.0. Added initial support for AD auth for OnPremise. This will work for full framework only.