Skip to content

Commit 1a20c07

Browse files
authored
Merge pull request #68 from microsoft/release/update/201114084827
Bug Fixes and Updates to expose some new properties for the future.
2 parents 15c1527 + 2d315a4 commit 1a20c07

16 files changed

+324
-140
lines changed

src/Build.Shared.props

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -3,8 +3,8 @@
33
<PropertyGroup>
44
<PackageVersion_AppInsights>2.9.1</PackageVersion_AppInsights>
55
<PackageVersion_Adal>3.19.8</PackageVersion_Adal>
6-
<PackageVersion_CdsSdk>4.5.4487</PackageVersion_CdsSdk>
7-
<PackageVersion_CDSServerNuget>4.5.4487</PackageVersion_CDSServerNuget>
6+
<PackageVersion_CdsSdk>4.6.875-weekly-2011.2</PackageVersion_CdsSdk>
7+
<PackageVersion_CDSServerNuget>4.6.875-weekly-2011.2</PackageVersion_CDSServerNuget>
88
<PackageVersion_Newtonsoft>10.0.3</PackageVersion_Newtonsoft>
99
<PackageVersion_RestClientRuntime>2.3.20</PackageVersion_RestClientRuntime>
1010
<PackageVersion_XrmSdk>9.0.2.25</PackageVersion_XrmSdk>
@@ -33,7 +33,7 @@
3333
</PropertyGroup>
3434

3535
<PropertyGroup Condition="'$(SignAssembly)' == 'true'">
36-
<AssemblyOriginatorKeyFile>$(RepoRoot)\build\crmKey\35MSSharedLib1024.snk</AssemblyOriginatorKeyFile>
36+
<AssemblyOriginatorKeyFile>$(RepoRoot)\build\crmkey\35MSSharedLib1024.snk</AssemblyOriginatorKeyFile>
3737
<DelaySign>true</DelaySign>
3838
</PropertyGroup>
3939

src/GeneralTools/CDSClient/Client/CdsConnectionService.cs

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -309,6 +309,11 @@ internal System.Net.NetworkCredential CdsServiceAccessCredential
309309
/// </summary>
310310
internal string InternetProtocalToUse { get { return _InternetProtocalToUse; } set { _InternetProtocalToUse = value; } }
311311

312+
/// <summary>
313+
/// returns the connected organization detail object.
314+
/// </summary>
315+
internal OrganizationDetail ConnectedOrganizationDetail { get { return _OrgDetail; } }
316+
312317
/// <summary>
313318
///
314319
/// </summary>
@@ -1438,11 +1443,14 @@ internal void SetClonedProperties(CdsServiceClient sourceClient)
14381443
}
14391444

14401445
// Add User Agent and request id to send.
1441-
string Agent = string.Empty;
1446+
string Agent = "Unknown";
14421447
if (AppDomain.CurrentDomain != null)
14431448
{
14441449
Agent = AppDomain.CurrentDomain.FriendlyName;
14451450
}
1451+
Agent = $"{Agent} (CdsSvcClient:{Environs.FileVersion})";
1452+
1453+
14461454
if (!_httpRequest.Headers.Contains(Utilities.CDSRequestHeaders.USER_AGENT_HTTP_HEADER))
14471455
_httpRequest.Headers.TryAddWithoutValidation(Utilities.CDSRequestHeaders.USER_AGENT_HTTP_HEADER, string.IsNullOrEmpty(Agent) ? "" : Agent);
14481456

src/GeneralTools/CDSClient/Client/CdsServiceClient.cs

Lines changed: 95 additions & 56 deletions
Large diffs are not rendered by default.

src/GeneralTools/CDSClient/Client/MetadataUtility.cs

Lines changed: 63 additions & 66 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
using System.Globalization;
44
using Microsoft.Xrm.Sdk.Metadata;
55
using Microsoft.Xrm.Sdk.Messages;
6+
using System.Collections.Concurrent;
67

78
namespace Microsoft.PowerPlatform.Cds.Client
89
{
@@ -15,19 +16,19 @@ internal class MetadataUtility
1516
/// <summary>
1617
/// MetadataCache object.
1718
/// </summary>
18-
private Dictionary<String, EntityMetadata> _entityMetadataCache = new Dictionary<String, EntityMetadata>();
19+
private ConcurrentDictionary<String, EntityMetadata> _entityMetadataCache = new ConcurrentDictionary<String, EntityMetadata>();
1920
/// <summary>
2021
/// Attribute metadata cache object
2122
/// </summary>
22-
private Dictionary<String, AttributeMetadata> _attributeMetadataCache = new Dictionary<String, AttributeMetadata>();
23+
private ConcurrentDictionary<String, AttributeMetadata> _attributeMetadataCache = new ConcurrentDictionary<String, AttributeMetadata>();
2324
/// <summary>
2425
/// Global option metadata cache object.
2526
/// </summary>
26-
private Dictionary<String, OptionSetMetadata> _globalOptionMetadataCache = new Dictionary<String, OptionSetMetadata>();
27+
private ConcurrentDictionary<String, OptionSetMetadata> _globalOptionMetadataCache = new ConcurrentDictionary<String, OptionSetMetadata>();
2728
/// <summary>
2829
/// Entity Name catch object
2930
/// </summary>
30-
private Dictionary<int, string> _entityNameCache = new Dictionary<int, string>();
31+
private ConcurrentDictionary<int, string> _entityNameCache = new ConcurrentDictionary<int, string>();
3132
/// <summary>
3233
/// Lock object
3334
/// </summary>
@@ -52,13 +53,17 @@ public MetadataUtility(CdsServiceClient svcActions)
5253
/// <param name="entityName"></param>
5354
public void ClearCachedEntityMetadata(string entityName)
5455
{
56+
TouchMetadataDate();
5557
// Not clearing the ETC ID's as they do not change...
56-
lock (_lockObject)
58+
if (_entityMetadataCache.ContainsKey(entityName))
5759
{
58-
if (_entityMetadataCache.ContainsKey(entityName))
59-
_entityMetadataCache.Remove(entityName);
60-
if (_attributeMetadataCache.ContainsKey(entityName))
61-
_attributeMetadataCache.Remove(entityName);
60+
EntityMetadata removedEntData;
61+
_entityMetadataCache.TryRemove(entityName, out removedEntData);
62+
}
63+
if (_attributeMetadataCache.ContainsKey(entityName))
64+
{
65+
AttributeMetadata removedAttribData;
66+
_attributeMetadataCache.TryRemove(entityName, out removedAttribData);
6267
}
6368
}
6469

@@ -82,21 +87,19 @@ public List<EntityMetadata> GetAllEntityMetadata(bool onlyPublished, EntityFilte
8287
{
8388
foreach (var entity in response.EntityMetadata)
8489
{
85-
lock (_lockObject)
86-
{
87-
if (_entityMetadataCache.ContainsKey(entity.LogicalName))
88-
_entityMetadataCache[entity.LogicalName] = entity; // Update local copy of the entity...
89-
else
90-
_entityMetadataCache.Add(entity.LogicalName, entity);
91-
92-
results.Add(entity);
93-
// Preload the entity data catch as this has been called already
94-
if (_entityNameCache.ContainsKey(entity.ObjectTypeCode.Value))
95-
continue;
96-
else
97-
_entityNameCache.Add(entity.ObjectTypeCode.Value, entity.LogicalName);
98-
}
90+
if (_entityMetadataCache.ContainsKey(entity.LogicalName))
91+
_entityMetadataCache[entity.LogicalName] = entity; // Update local copy of the entity...
92+
else
93+
_entityMetadataCache.TryAdd(entity.LogicalName, entity);
94+
95+
results.Add(entity);
96+
// Preload the entity data catch as this has been called already
97+
if (_entityNameCache.ContainsKey(entity.ObjectTypeCode.Value))
98+
continue;
99+
else
100+
_entityNameCache.TryAdd(entity.ObjectTypeCode.Value, entity.LogicalName);
99101
}
102+
TouchMetadataDate();
100103
}
101104

102105
return results;
@@ -169,16 +172,13 @@ public EntityMetadata GetEntityMetadata(EntityFilters requestType, String entity
169172
if (response != null)
170173
{
171174
entityMetadata = response.EntityMetadata;
172-
lock (_lockObject)
173-
{
174-
if (!_entityMetadataCache.ContainsKey(entityName))
175-
_entityMetadataCache.Add(entityName, entityMetadata);
176-
else
177-
_entityMetadataCache[entityName] = entityMetadata;
175+
if (!_entityMetadataCache.ContainsKey(entityName))
176+
_entityMetadataCache.TryAdd(entityName, entityMetadata);
177+
else
178+
_entityMetadataCache[entityName] = entityMetadata;
178179

179-
if (!bSelectiveUpdate)
180-
_metadataLastValidatedAt = DateTime.Now;
181-
}
180+
if (!bSelectiveUpdate)
181+
TouchMetadataDate();
182182
}
183183
}
184184
return entityMetadata;
@@ -204,20 +204,17 @@ public string GetEntityLogicalName(int entityTypeCode)
204204
RetrieveAllEntitiesResponse response = (RetrieveAllEntitiesResponse)svcAct.CdsCommand_Execute(request, "GetEntityLogicalName");
205205
if (response != null)
206206
{
207-
lock (_lockObject)
207+
foreach (EntityMetadata metadata in response.EntityMetadata)
208208
{
209-
foreach (EntityMetadata metadata in response.EntityMetadata)
210-
{
211-
_entityNameCache.Add(metadata.ObjectTypeCode.Value, metadata.LogicalName);
212-
213-
// reload metadata cache.
214-
if (_entityMetadataCache.ContainsKey(metadata.LogicalName))
215-
continue;
216-
else
217-
_entityMetadataCache.Add(metadata.LogicalName, metadata);
218-
}
219-
_metadataLastValidatedAt = DateTime.Now;
209+
_entityNameCache.TryAdd(metadata.ObjectTypeCode.Value, metadata.LogicalName);
210+
211+
// reload metadata cache.
212+
if (_entityMetadataCache.ContainsKey(metadata.LogicalName))
213+
continue;
214+
else
215+
_entityMetadataCache.TryAdd(metadata.LogicalName, metadata);
220216
}
217+
TouchMetadataDate();
221218
}
222219
}
223220
}
@@ -249,11 +246,8 @@ public AttributeMetadata GetAttributeMetadata(string entityName, string attribut
249246
if (response != null)
250247
{
251248
attributeMetadata = response.AttributeMetadata;
252-
lock (_lockObject)
253-
{
254-
_attributeMetadataCache.Add(String.Format(CultureInfo.InvariantCulture, "{0}.{1}", entityName, attributeName), attributeMetadata);
255-
_metadataLastValidatedAt = DateTime.Now;
256-
}
249+
_attributeMetadataCache.TryAdd(String.Format(CultureInfo.InvariantCulture, "{0}.{1}", entityName, attributeName), attributeMetadata);
250+
_metadataLastValidatedAt = DateTime.UtcNow;
257251
}
258252
}
259253
}
@@ -333,10 +327,8 @@ public OptionSetMetadata GetGlobalOptionSetMetadata(string optionSetName)
333327
{
334328
if (response.OptionSetMetadata is OptionSetMetadata && (OptionSetMetadata)response.OptionSetMetadata != null)
335329
{
336-
lock (_lockObject)
337-
{
338-
_globalOptionMetadataCache.Add(optionSetName, (OptionSetMetadata)response.OptionSetMetadata);
339-
}
330+
_globalOptionMetadataCache.TryAdd(optionSetName, (OptionSetMetadata)response.OptionSetMetadata);
331+
TouchMetadataDate();
340332
return _globalOptionMetadataCache[optionSetName];
341333
}
342334
}
@@ -348,17 +340,22 @@ public OptionSetMetadata GetGlobalOptionSetMetadata(string optionSetName)
348340
/// </summary>
349341
private void ValidateMetadata()
350342
{
351-
if (DateTime.Now.Subtract(_metadataLastValidatedAt).TotalHours > 1)
352-
{
353-
lock (_lockObject)
354-
{
355-
_metadataLastValidatedAt = DateTime.Now;
356-
_attributeMetadataCache.Clear();
357-
_entityMetadataCache.Clear();
358-
_entityNameCache.Clear();
359-
_globalOptionMetadataCache.Clear();
360-
}
361-
}
362-
}
363-
}
343+
if (DateTime.UtcNow.Subtract(_metadataLastValidatedAt).TotalHours > 1)
344+
{
345+
TouchMetadataDate();
346+
_attributeMetadataCache.Clear();
347+
_entityMetadataCache.Clear();
348+
_entityNameCache.Clear();
349+
_globalOptionMetadataCache.Clear();
350+
}
351+
}
352+
353+
private void TouchMetadataDate()
354+
{
355+
lock (_lockObject)
356+
{
357+
_metadataLastValidatedAt = DateTime.UtcNow;
358+
}
359+
}
360+
}
364361
}

src/GeneralTools/CDSClient/Client/Microsoft.Powerplatform.Cds.Client.csproj

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@
66
<SignAssembly>true</SignAssembly>
77
<CopyLocalLockFileAssemblies>true</CopyLocalLockFileAssemblies>
88
</PropertyGroup>
9-
<Import Project="..\..\..\Build.Common.Core.props" />
9+
<Import Project="..\..\..\Build.Common.core.props" />
1010

1111
<PropertyGroup>
1212
<GeneratePackageOnBuild>false</GeneratePackageOnBuild>
Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
using System;
2+
using System.Collections.Generic;
3+
using System.Linq;
4+
using System.Text;
5+
using System.Threading.Tasks;
6+
7+
namespace Microsoft.PowerPlatform.Cds.Client
8+
{
9+
/// <summary>
10+
/// Properties valid for the extraParameters collection of ImportSolution.
11+
/// </summary>
12+
public static class ImportSolutionProperties
13+
{
14+
/// <summary>
15+
/// Parameter used to change the default layering behavior during solution import
16+
/// </summary>
17+
public static string DESIREDLAYERORDERPARAM = "DesiredLayerOrder";
18+
/// <summary>
19+
/// Parameter used to specify whether Solution Import processed ribbon metadata asynchronously
20+
/// </summary>
21+
public static string ASYNCRIBBONPROCESSING = "AsyncRibbonProcessing";
22+
/// <summary>
23+
/// Parameter used to pass the solution name - Telemetry only
24+
/// </summary>
25+
public static string SOLUTIONNAMEPARAM = "SolutionName";
26+
/// <summary>
27+
/// Parameter used to pass a collection of component parameters to the import job.
28+
/// </summary>
29+
public static string COMPONENTPARAMETERSPARAM = "ComponentParameters";
30+
}
31+
}

src/GeneralTools/CDSClient/Client/Utils/Utils.cs

Lines changed: 70 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -301,12 +301,14 @@ internal static bool IsRequestValidForTranslationToWebAPI(OrganizationRequest re
301301
case "delete":
302302
return true;
303303
case "upsert":
304+
// Disabling WebAPI support for upsert right now due to issues with generating the response.
305+
304306
// avoid bug in WebAPI around Support for key's as EntityRefeances //TODO: TEMP
305-
Xrm.Sdk.Messages.UpsertRequest upsert = (Xrm.Sdk.Messages.UpsertRequest)req;
306-
if (upsert.Target.KeyAttributes?.Any(a => a.Value is string) != true)
307-
return false;
308-
else
309-
return true;
307+
//Xrm.Sdk.Messages.UpsertRequest upsert = (Xrm.Sdk.Messages.UpsertRequest)req;
308+
//if (upsert.Target.KeyAttributes?.Any(a => a.Value is string) != true)
309+
// return false;
310+
//else
311+
//return true;
310312
default:
311313
return false;
312314
}
@@ -419,7 +421,7 @@ internal static string ParseAltKeyCollection (KeyAttributeCollection keyValues)
419421
{
420422
if (itm.Value is EntityReference er)
421423
{
422-
keycollection += $"_{itm.Key}_value='{er.Id.ToString("P")}',";
424+
keycollection += $"_{itm.Key}_value={er.Id.ToString("P")},";
423425
}
424426
else
425427
{
@@ -531,5 +533,67 @@ internal static class CDSRequestHeaders
531533

532534
}
533535

536+
/// <summary>
537+
/// Minim Version numbers for various features of CDS API's.
538+
/// </summary>
539+
internal static class CDSFeatureVersionMinimums
540+
{
541+
/// <summary>
542+
/// Lowest server version that can be connected too.
543+
/// </summary>
544+
internal static Version CDSVersionForThisAPI = new Version("5.0.9688.1533");
545+
546+
/// <summary>
547+
/// Minimum version that supports batch Operations.
548+
/// </summary>
549+
internal static Version BatchOperations = new Version("5.0.9690.3000");
550+
551+
/// <summary>
552+
/// Minimum version that supports holding solutions.
553+
/// </summary>
554+
internal static Version ImportHoldingSolution = new Version("7.2.0.9");
555+
556+
/// <summary>
557+
/// Minimum version that supports the Internal Upgrade Flag
558+
/// </summary>
559+
internal static Version InternalUpgradeSolution = new Version("9.0.0.0");
560+
561+
/// <summary>
562+
/// MinVersion that supports AAD Caller ID.
563+
/// </summary>
564+
internal static Version AADCallerIDSupported = new Version("8.1.0.0");
565+
566+
/// <summary>
567+
/// MinVersion that supports Session ID Telemetry Tracking.
568+
/// </summary>
569+
internal static Version SessionTrackingSupported = new Version("9.0.2.0");
570+
571+
/// <summary>
572+
/// MinVersion that supports Forcing Cache Sync.
573+
/// </summary>
574+
internal static Version ForceConsistencySupported = new Version("9.1.0.0");
575+
576+
/// <summary>
577+
/// Minimum version to allow plug in bypass param.
578+
/// </summary>
579+
internal static Version AllowBypassCustomPlugin = new Version("9.1.0.20918");
580+
581+
/// <summary>
582+
/// Minimum version supported by the Web API
583+
/// </summary>
584+
internal static Version WebAPISupported = new Version("8.0.0.0");
585+
586+
/// <summary>
587+
/// Minimum version supported for AsyncRibbonProcessing.
588+
/// </summary>
589+
internal static Version AllowAsyncRibbonProcessing = new Version("9.1.0.15400");
590+
591+
/// <summary>
592+
/// Minimum version supported for Passing Component data to CDS as part of solution deployment..
593+
/// </summary>
594+
internal static Version AllowComponetInfoProcessing = new Version("9.1.0.16547");
595+
}
596+
597+
534598
}
535599
}

src/GeneralTools/CDSClient/Extensions/DynamicsExtension/Microsoft.Powerplatform.Cds.Client.Dynamics.csproj

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@
55
<ComponentAreaName>CdsClient</ComponentAreaName>
66
<SignAssembly>true</SignAssembly>
77
</PropertyGroup>
8-
<Import Project="..\..\..\..\Build.Common.Core.props" />
8+
<Import Project="..\..\..\..\Build.Common.core.props" />
99

1010
<PropertyGroup>
1111
<GeneratePackageOnBuild>false</GeneratePackageOnBuild>

0 commit comments

Comments
 (0)