Skip to content

Commit

Permalink
Merge pull request #68 from microsoft/release/update/201114084827
Browse files Browse the repository at this point in the history
Bug Fixes and Updates to expose some new properties for the future.
  • Loading branch information
MattB-msft committed Nov 14, 2020
2 parents 15c1527 + 2d315a4 commit 1a20c07
Show file tree
Hide file tree
Showing 16 changed files with 324 additions and 140 deletions.
6 changes: 3 additions & 3 deletions src/Build.Shared.props
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,8 @@
<PropertyGroup>
<PackageVersion_AppInsights>2.9.1</PackageVersion_AppInsights>
<PackageVersion_Adal>3.19.8</PackageVersion_Adal>
<PackageVersion_CdsSdk>4.5.4487</PackageVersion_CdsSdk>
<PackageVersion_CDSServerNuget>4.5.4487</PackageVersion_CDSServerNuget>
<PackageVersion_CdsSdk>4.6.875-weekly-2011.2</PackageVersion_CdsSdk>
<PackageVersion_CDSServerNuget>4.6.875-weekly-2011.2</PackageVersion_CDSServerNuget>
<PackageVersion_Newtonsoft>10.0.3</PackageVersion_Newtonsoft>
<PackageVersion_RestClientRuntime>2.3.20</PackageVersion_RestClientRuntime>
<PackageVersion_XrmSdk>9.0.2.25</PackageVersion_XrmSdk>
Expand Down Expand Up @@ -33,7 +33,7 @@
</PropertyGroup>

<PropertyGroup Condition="'$(SignAssembly)' == 'true'">
<AssemblyOriginatorKeyFile>$(RepoRoot)\build\crmKey\35MSSharedLib1024.snk</AssemblyOriginatorKeyFile>
<AssemblyOriginatorKeyFile>$(RepoRoot)\build\crmkey\35MSSharedLib1024.snk</AssemblyOriginatorKeyFile>
<DelaySign>true</DelaySign>
</PropertyGroup>

Expand Down
10 changes: 9 additions & 1 deletion src/GeneralTools/CDSClient/Client/CdsConnectionService.cs
Original file line number Diff line number Diff line change
Expand Up @@ -309,6 +309,11 @@ internal System.Net.NetworkCredential CdsServiceAccessCredential
/// </summary>
internal string InternetProtocalToUse { get { return _InternetProtocalToUse; } set { _InternetProtocalToUse = value; } }

/// <summary>
/// returns the connected organization detail object.
/// </summary>
internal OrganizationDetail ConnectedOrganizationDetail { get { return _OrgDetail; } }

/// <summary>
///
/// </summary>
Expand Down Expand Up @@ -1438,11 +1443,14 @@ internal void SetClonedProperties(CdsServiceClient sourceClient)
}

// Add User Agent and request id to send.
string Agent = string.Empty;
string Agent = "Unknown";
if (AppDomain.CurrentDomain != null)
{
Agent = AppDomain.CurrentDomain.FriendlyName;
}
Agent = $"{Agent} (CdsSvcClient:{Environs.FileVersion})";


if (!_httpRequest.Headers.Contains(Utilities.CDSRequestHeaders.USER_AGENT_HTTP_HEADER))
_httpRequest.Headers.TryAddWithoutValidation(Utilities.CDSRequestHeaders.USER_AGENT_HTTP_HEADER, string.IsNullOrEmpty(Agent) ? "" : Agent);

Expand Down
151 changes: 95 additions & 56 deletions src/GeneralTools/CDSClient/Client/CdsServiceClient.cs

Large diffs are not rendered by default.

129 changes: 63 additions & 66 deletions src/GeneralTools/CDSClient/Client/MetadataUtility.cs
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
using System.Globalization;
using Microsoft.Xrm.Sdk.Metadata;
using Microsoft.Xrm.Sdk.Messages;
using System.Collections.Concurrent;

namespace Microsoft.PowerPlatform.Cds.Client
{
Expand All @@ -15,19 +16,19 @@ internal class MetadataUtility
/// <summary>
/// MetadataCache object.
/// </summary>
private Dictionary<String, EntityMetadata> _entityMetadataCache = new Dictionary<String, EntityMetadata>();
private ConcurrentDictionary<String, EntityMetadata> _entityMetadataCache = new ConcurrentDictionary<String, EntityMetadata>();
/// <summary>
/// Attribute metadata cache object
/// </summary>
private Dictionary<String, AttributeMetadata> _attributeMetadataCache = new Dictionary<String, AttributeMetadata>();
private ConcurrentDictionary<String, AttributeMetadata> _attributeMetadataCache = new ConcurrentDictionary<String, AttributeMetadata>();
/// <summary>
/// Global option metadata cache object.
/// </summary>
private Dictionary<String, OptionSetMetadata> _globalOptionMetadataCache = new Dictionary<String, OptionSetMetadata>();
private ConcurrentDictionary<String, OptionSetMetadata> _globalOptionMetadataCache = new ConcurrentDictionary<String, OptionSetMetadata>();
/// <summary>
/// Entity Name catch object
/// </summary>
private Dictionary<int, string> _entityNameCache = new Dictionary<int, string>();
private ConcurrentDictionary<int, string> _entityNameCache = new ConcurrentDictionary<int, string>();
/// <summary>
/// Lock object
/// </summary>
Expand All @@ -52,13 +53,17 @@ public MetadataUtility(CdsServiceClient svcActions)
/// <param name="entityName"></param>
public void ClearCachedEntityMetadata(string entityName)
{
TouchMetadataDate();
// Not clearing the ETC ID's as they do not change...
lock (_lockObject)
if (_entityMetadataCache.ContainsKey(entityName))
{
if (_entityMetadataCache.ContainsKey(entityName))
_entityMetadataCache.Remove(entityName);
if (_attributeMetadataCache.ContainsKey(entityName))
_attributeMetadataCache.Remove(entityName);
EntityMetadata removedEntData;
_entityMetadataCache.TryRemove(entityName, out removedEntData);
}
if (_attributeMetadataCache.ContainsKey(entityName))
{
AttributeMetadata removedAttribData;
_attributeMetadataCache.TryRemove(entityName, out removedAttribData);
}
}

Expand All @@ -82,21 +87,19 @@ public List<EntityMetadata> GetAllEntityMetadata(bool onlyPublished, EntityFilte
{
foreach (var entity in response.EntityMetadata)
{
lock (_lockObject)
{
if (_entityMetadataCache.ContainsKey(entity.LogicalName))
_entityMetadataCache[entity.LogicalName] = entity; // Update local copy of the entity...
else
_entityMetadataCache.Add(entity.LogicalName, entity);

results.Add(entity);
// Preload the entity data catch as this has been called already
if (_entityNameCache.ContainsKey(entity.ObjectTypeCode.Value))
continue;
else
_entityNameCache.Add(entity.ObjectTypeCode.Value, entity.LogicalName);
}
if (_entityMetadataCache.ContainsKey(entity.LogicalName))
_entityMetadataCache[entity.LogicalName] = entity; // Update local copy of the entity...
else
_entityMetadataCache.TryAdd(entity.LogicalName, entity);

results.Add(entity);
// Preload the entity data catch as this has been called already
if (_entityNameCache.ContainsKey(entity.ObjectTypeCode.Value))
continue;
else
_entityNameCache.TryAdd(entity.ObjectTypeCode.Value, entity.LogicalName);
}
TouchMetadataDate();
}

return results;
Expand Down Expand Up @@ -169,16 +172,13 @@ public EntityMetadata GetEntityMetadata(EntityFilters requestType, String entity
if (response != null)
{
entityMetadata = response.EntityMetadata;
lock (_lockObject)
{
if (!_entityMetadataCache.ContainsKey(entityName))
_entityMetadataCache.Add(entityName, entityMetadata);
else
_entityMetadataCache[entityName] = entityMetadata;
if (!_entityMetadataCache.ContainsKey(entityName))
_entityMetadataCache.TryAdd(entityName, entityMetadata);
else
_entityMetadataCache[entityName] = entityMetadata;

if (!bSelectiveUpdate)
_metadataLastValidatedAt = DateTime.Now;
}
if (!bSelectiveUpdate)
TouchMetadataDate();
}
}
return entityMetadata;
Expand All @@ -204,20 +204,17 @@ public string GetEntityLogicalName(int entityTypeCode)
RetrieveAllEntitiesResponse response = (RetrieveAllEntitiesResponse)svcAct.CdsCommand_Execute(request, "GetEntityLogicalName");
if (response != null)
{
lock (_lockObject)
foreach (EntityMetadata metadata in response.EntityMetadata)
{
foreach (EntityMetadata metadata in response.EntityMetadata)
{
_entityNameCache.Add(metadata.ObjectTypeCode.Value, metadata.LogicalName);

// reload metadata cache.
if (_entityMetadataCache.ContainsKey(metadata.LogicalName))
continue;
else
_entityMetadataCache.Add(metadata.LogicalName, metadata);
}
_metadataLastValidatedAt = DateTime.Now;
_entityNameCache.TryAdd(metadata.ObjectTypeCode.Value, metadata.LogicalName);

// reload metadata cache.
if (_entityMetadataCache.ContainsKey(metadata.LogicalName))
continue;
else
_entityMetadataCache.TryAdd(metadata.LogicalName, metadata);
}
TouchMetadataDate();
}
}
}
Expand Down Expand Up @@ -249,11 +246,8 @@ public AttributeMetadata GetAttributeMetadata(string entityName, string attribut
if (response != null)
{
attributeMetadata = response.AttributeMetadata;
lock (_lockObject)
{
_attributeMetadataCache.Add(String.Format(CultureInfo.InvariantCulture, "{0}.{1}", entityName, attributeName), attributeMetadata);
_metadataLastValidatedAt = DateTime.Now;
}
_attributeMetadataCache.TryAdd(String.Format(CultureInfo.InvariantCulture, "{0}.{1}", entityName, attributeName), attributeMetadata);
_metadataLastValidatedAt = DateTime.UtcNow;
}
}
}
Expand Down Expand Up @@ -333,10 +327,8 @@ public OptionSetMetadata GetGlobalOptionSetMetadata(string optionSetName)
{
if (response.OptionSetMetadata is OptionSetMetadata && (OptionSetMetadata)response.OptionSetMetadata != null)
{
lock (_lockObject)
{
_globalOptionMetadataCache.Add(optionSetName, (OptionSetMetadata)response.OptionSetMetadata);
}
_globalOptionMetadataCache.TryAdd(optionSetName, (OptionSetMetadata)response.OptionSetMetadata);
TouchMetadataDate();
return _globalOptionMetadataCache[optionSetName];
}
}
Expand All @@ -348,17 +340,22 @@ public OptionSetMetadata GetGlobalOptionSetMetadata(string optionSetName)
/// </summary>
private void ValidateMetadata()
{
if (DateTime.Now.Subtract(_metadataLastValidatedAt).TotalHours > 1)
{
lock (_lockObject)
{
_metadataLastValidatedAt = DateTime.Now;
_attributeMetadataCache.Clear();
_entityMetadataCache.Clear();
_entityNameCache.Clear();
_globalOptionMetadataCache.Clear();
}
}
}
}
if (DateTime.UtcNow.Subtract(_metadataLastValidatedAt).TotalHours > 1)
{
TouchMetadataDate();
_attributeMetadataCache.Clear();
_entityMetadataCache.Clear();
_entityNameCache.Clear();
_globalOptionMetadataCache.Clear();
}
}

private void TouchMetadataDate()
{
lock (_lockObject)
{
_metadataLastValidatedAt = DateTime.UtcNow;
}
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
<SignAssembly>true</SignAssembly>
<CopyLocalLockFileAssemblies>true</CopyLocalLockFileAssemblies>
</PropertyGroup>
<Import Project="..\..\..\Build.Common.Core.props" />
<Import Project="..\..\..\Build.Common.core.props" />

<PropertyGroup>
<GeneratePackageOnBuild>false</GeneratePackageOnBuild>
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace Microsoft.PowerPlatform.Cds.Client
{
/// <summary>
/// Properties valid for the extraParameters collection of ImportSolution.
/// </summary>
public static class ImportSolutionProperties
{
/// <summary>
/// Parameter used to change the default layering behavior during solution import
/// </summary>
public static string DESIREDLAYERORDERPARAM = "DesiredLayerOrder";
/// <summary>
/// Parameter used to specify whether Solution Import processed ribbon metadata asynchronously
/// </summary>
public static string ASYNCRIBBONPROCESSING = "AsyncRibbonProcessing";
/// <summary>
/// Parameter used to pass the solution name - Telemetry only
/// </summary>
public static string SOLUTIONNAMEPARAM = "SolutionName";
/// <summary>
/// Parameter used to pass a collection of component parameters to the import job.
/// </summary>
public static string COMPONENTPARAMETERSPARAM = "ComponentParameters";
}
}
76 changes: 70 additions & 6 deletions src/GeneralTools/CDSClient/Client/Utils/Utils.cs
Original file line number Diff line number Diff line change
Expand Up @@ -301,12 +301,14 @@ internal static bool IsRequestValidForTranslationToWebAPI(OrganizationRequest re
case "delete":
return true;
case "upsert":
// Disabling WebAPI support for upsert right now due to issues with generating the response.

// avoid bug in WebAPI around Support for key's as EntityRefeances //TODO: TEMP
Xrm.Sdk.Messages.UpsertRequest upsert = (Xrm.Sdk.Messages.UpsertRequest)req;
if (upsert.Target.KeyAttributes?.Any(a => a.Value is string) != true)
return false;
else
return true;
//Xrm.Sdk.Messages.UpsertRequest upsert = (Xrm.Sdk.Messages.UpsertRequest)req;
//if (upsert.Target.KeyAttributes?.Any(a => a.Value is string) != true)
// return false;
//else
//return true;
default:
return false;
}
Expand Down Expand Up @@ -419,7 +421,7 @@ internal static string ParseAltKeyCollection (KeyAttributeCollection keyValues)
{
if (itm.Value is EntityReference er)
{
keycollection += $"_{itm.Key}_value='{er.Id.ToString("P")}',";
keycollection += $"_{itm.Key}_value={er.Id.ToString("P")},";
}
else
{
Expand Down Expand Up @@ -531,5 +533,67 @@ internal static class CDSRequestHeaders

}

/// <summary>
/// Minim Version numbers for various features of CDS API's.
/// </summary>
internal static class CDSFeatureVersionMinimums
{
/// <summary>
/// Lowest server version that can be connected too.
/// </summary>
internal static Version CDSVersionForThisAPI = new Version("5.0.9688.1533");

/// <summary>
/// Minimum version that supports batch Operations.
/// </summary>
internal static Version BatchOperations = new Version("5.0.9690.3000");

/// <summary>
/// Minimum version that supports holding solutions.
/// </summary>
internal static Version ImportHoldingSolution = new Version("7.2.0.9");

/// <summary>
/// Minimum version that supports the Internal Upgrade Flag
/// </summary>
internal static Version InternalUpgradeSolution = new Version("9.0.0.0");

/// <summary>
/// MinVersion that supports AAD Caller ID.
/// </summary>
internal static Version AADCallerIDSupported = new Version("8.1.0.0");

/// <summary>
/// MinVersion that supports Session ID Telemetry Tracking.
/// </summary>
internal static Version SessionTrackingSupported = new Version("9.0.2.0");

/// <summary>
/// MinVersion that supports Forcing Cache Sync.
/// </summary>
internal static Version ForceConsistencySupported = new Version("9.1.0.0");

/// <summary>
/// Minimum version to allow plug in bypass param.
/// </summary>
internal static Version AllowBypassCustomPlugin = new Version("9.1.0.20918");

/// <summary>
/// Minimum version supported by the Web API
/// </summary>
internal static Version WebAPISupported = new Version("8.0.0.0");

/// <summary>
/// Minimum version supported for AsyncRibbonProcessing.
/// </summary>
internal static Version AllowAsyncRibbonProcessing = new Version("9.1.0.15400");

/// <summary>
/// Minimum version supported for Passing Component data to CDS as part of solution deployment..
/// </summary>
internal static Version AllowComponetInfoProcessing = new Version("9.1.0.16547");
}


}
}
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
<ComponentAreaName>CdsClient</ComponentAreaName>
<SignAssembly>true</SignAssembly>
</PropertyGroup>
<Import Project="..\..\..\..\Build.Common.Core.props" />
<Import Project="..\..\..\..\Build.Common.core.props" />

<PropertyGroup>
<GeneratePackageOnBuild>false</GeneratePackageOnBuild>
Expand Down
Loading

0 comments on commit 1a20c07

Please sign in to comment.