Skip to content

Commit 186926e

Browse files
Address comments.
1 parent 013ac18 commit 186926e

26 files changed

+409
-356
lines changed

src/ResourceManager/Common/Commands.Common.Strategies/AsyncOperationContext.cs

Lines changed: 15 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -5,41 +5,42 @@
55

66
namespace Microsoft.Azure.Commands.Common.Strategies
77
{
8+
/// <summary>
9+
/// Context for asyncronous operations, such as GetAsync or CreateOrUpdateAsync.
10+
/// </summary>
811
public sealed class AsyncOperationContext
912
{
1013
public IClient Client { get; }
1114

1215
public CancellationToken CancellationToken { get; }
1316

14-
public IState Result => State;
17+
public IState Result => _Result;
1518

1619
public AsyncOperationContext(IClient client, CancellationToken cancellationToken)
1720
{
1821
Client = client;
1922
CancellationToken = cancellationToken;
2023
}
2124

22-
public async Task<Model> GetOrAddAsync<Model>(
23-
ResourceConfig<Model> config, Func<Task<Model>> create)
24-
where Model : class
25-
{
26-
var result = await TaskMap.GetOrAdd(
25+
public async Task<TModel> GetOrAddAsync<TModel>(
26+
ResourceConfig<TModel> config, Func<Task<TModel>> operation)
27+
where TModel : class
28+
=> await _TaskMap.GetOrAddWithCast(
2729
config.DefaultIdStr(),
28-
async _ =>
30+
async () =>
2931
{
30-
var model = await create();
32+
var model = await operation();
3133
if (model != null)
3234
{
33-
State.GetOrAdd(config, () => model);
35+
// add the operation result to a result.
36+
_Result.GetOrAdd(config, () => model);
3437
}
3538
return model;
3639
});
37-
return result as Model;
38-
}
3940

40-
State State { get; } = new State();
41+
readonly State _Result = new State();
4142

42-
ConcurrentDictionary<string, Task<object>> TaskMap { get; }
43-
= new ConcurrentDictionary<string, Task<object>>();
43+
readonly ConcurrentDictionary<string, Task> _TaskMap
44+
= new ConcurrentDictionary<string, Task>();
4445
}
4546
}

src/ResourceManager/Common/Commands.Common.Strategies/Commands.Common.Strategies.csproj

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -70,8 +70,9 @@
7070
<Compile Include="AsyncOperationContext.cs" />
7171
<Compile Include="Compute\ComputeStrategy.cs" />
7272
<Compile Include="Compute\VirtualMachineStrategy.cs" />
73-
<Compile Include="CreateOrUpdateAsyncOperation.cs" />
73+
<Compile Include="CreateOrUpdateAsyncExtensions.cs" />
7474
<Compile Include="CreateOrUpdateAsyncParams.cs" />
75+
<Compile Include="EntityConfigExtensions.cs" />
7576
<Compile Include="Extensions.cs" />
7677
<Compile Include="GetAsyncOperation.cs" />
7778
<Compile Include="GetAsyncParams.cs" />
@@ -80,8 +81,10 @@
8081
<Compile Include="IEntityConfigVisitor.cs" />
8182
<Compile Include="IEntityStrategy.cs" />
8283
<Compile Include="IState.cs" />
84+
<Compile Include="NestedResourceConfigExtensions.cs" />
85+
<Compile Include="ResourceConfigExtensions.cs" />
86+
<Compile Include="StateExtensions.cs" />
8387
<Compile Include="TargetDependencies.cs" />
84-
<Compile Include="TypedDictionary.cs" />
8588
<Compile Include="NestedResourceConfig.cs" />
8689
<Compile Include="NestedResourceStrategy.cs" />
8790
<Compile Include="Network\NetworkInterfaceStrategy.cs" />

src/ResourceManager/Common/Commands.Common.Strategies/Compute/ComputeStrategy.cs

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -7,12 +7,12 @@ namespace Microsoft.Azure.Commands.Common.Strategies.Compute
77
{
88
public static class ComputePolicy
99
{
10-
public static ResourceStrategy<Model> Create<Model, Operations>(
10+
public static ResourceStrategy<TModel> Create<TModel, TOperations>(
1111
string header,
12-
Func<ComputeManagementClient, Operations> getOperations,
13-
Func<Operations, GetAsyncParams, Task<Model>> getAsync,
14-
Func<Operations, CreateOrUpdateAsyncParams<Model>, Task<Model>> createOrUpdateAsync)
15-
where Model : Resource
12+
Func<ComputeManagementClient, TOperations> getOperations,
13+
Func<TOperations, GetAsyncParams, Task<TModel>> getAsync,
14+
Func<TOperations, CreateOrUpdateAsyncParams<TModel>, Task<TModel>> createOrUpdateAsync)
15+
where TModel : Resource
1616
=> ResourceStrategy.Create(
1717
new[] { "Microsoft.Compute", header },
1818
getOperations,
Lines changed: 83 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,83 @@
1+
using System.Linq;
2+
using System.Threading;
3+
using System.Threading.Tasks;
4+
5+
namespace Microsoft.Azure.Commands.Common.Strategies
6+
{
7+
public static class CreateOrUpdateAsyncExtensions
8+
{
9+
public static async Task<IState> CreateOrUpdateAsync<TModel>(
10+
this ResourceConfig<TModel> config,
11+
IClient client,
12+
IState target,
13+
CancellationToken cancellationToken)
14+
where TModel : class
15+
{
16+
var context = new Context(new AsyncOperationContext(client, cancellationToken), target);
17+
await context.CreateOrUpdateAsync(config);
18+
return context.Result;
19+
}
20+
21+
sealed class Context
22+
{
23+
public IState Result => _OperationContext.Result;
24+
25+
readonly AsyncOperationContext _OperationContext;
26+
27+
readonly IState _Target;
28+
29+
public Context(AsyncOperationContext operationContext, IState target)
30+
{
31+
_OperationContext = operationContext;
32+
_Target = target;
33+
}
34+
35+
public async Task CreateOrUpdateAsync<TModel>(ResourceConfig<TModel> config)
36+
where TModel : class
37+
{
38+
var model = _Target.Get(config);
39+
if (model != null)
40+
{
41+
await _OperationContext.GetOrAddAsync(
42+
config,
43+
async () =>
44+
{
45+
// wait for all dependencies
46+
var tasks = config.Dependencies.Select(CreateOrUpdateAsyncDispatch);
47+
await Task.WhenAll(tasks);
48+
// call the main function.
49+
return await config.Strategy.CreateOrUpdateAsync(
50+
_OperationContext.Client,
51+
CreateOrUpdateAsyncParams.Create(
52+
config.ResourceGroupName,
53+
config.Name,
54+
model,
55+
_OperationContext.CancellationToken));
56+
});
57+
}
58+
}
59+
60+
public Task CreateOrUpdateAsync<TModel, TParentModel>(
61+
NestedResourceConfig<TModel, TParentModel> config)
62+
where TModel : class
63+
where TParentModel : class
64+
=> CreateOrUpdateAsyncDispatch(config.Parent);
65+
66+
public Task CreateOrUpdateAsyncDispatch(IEntityConfig config)
67+
=> config.Accept(new CreateOrUpdateAsyncVisitor(), this);
68+
}
69+
70+
sealed class CreateOrUpdateAsyncVisitor : IEntityConfigVisitor<Context, Task>
71+
{
72+
public Task Visit<TModel>(ResourceConfig<TModel> config, Context context)
73+
where TModel : class
74+
=> context.CreateOrUpdateAsync(config);
75+
76+
public Task Visit<TModel, TParentModel>(
77+
NestedResourceConfig<TModel, TParentModel> config, Context context)
78+
where TModel : class
79+
where TParentModel : class
80+
=> context.CreateOrUpdateAsync(config);
81+
}
82+
}
83+
}

src/ResourceManager/Common/Commands.Common.Strategies/CreateOrUpdateAsyncOperation.cs

Lines changed: 0 additions & 80 deletions
This file was deleted.

src/ResourceManager/Common/Commands.Common.Strategies/CreateOrUpdateAsyncParams.cs

Lines changed: 10 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -4,12 +4,19 @@ namespace Microsoft.Azure.Commands.Common.Strategies
44
{
55
public static class CreateOrUpdateAsyncParams
66
{
7-
public static CreateOrUpdateAsyncParams<Model> Create<Model>(
8-
string resourceGroupName, string name, Model model, CancellationToken cancellationToken)
9-
=> new CreateOrUpdateAsyncParams<Model>(
7+
public static CreateOrUpdateAsyncParams<TModel> Create<TModel>(
8+
string resourceGroupName,
9+
string name,
10+
TModel model,
11+
CancellationToken cancellationToken)
12+
=> new CreateOrUpdateAsyncParams<TModel>(
1013
resourceGroupName, name, model, cancellationToken);
1114
}
1215

16+
/// <summary>
17+
/// Parameters for CreateOrUpdateAsync functions.
18+
/// </summary>
19+
/// <typeparam name="TModel"></typeparam>
1320
public sealed class CreateOrUpdateAsyncParams<TModel>
1421
{
1522
public string ResourceGroupName { get; }
Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
using System.Collections.Generic;
2+
3+
namespace Microsoft.Azure.Commands.Common.Strategies
4+
{
5+
public static class EntityConfigExtensions
6+
{
7+
public static string IdToString(this IEnumerable<string> id)
8+
=> "/" + string.Join("/", id);
9+
10+
public static string DefaultIdStr(this IEntityConfig config)
11+
=> config.GetId(string.Empty).IdToString();
12+
}
13+
}

src/ResourceManager/Common/Commands.Common.Strategies/Extensions.cs

Lines changed: 10 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -10,15 +10,18 @@ public static class Extensions
1010
public static IEnumerable<T> EmptyIfNull<T>(this IEnumerable<T> value)
1111
=> value ?? Enumerable.Empty<T>();
1212

13-
public static V GetOrNull<K, V>(this IDictionary<K, V> dictionary, K key)
14-
where V : class
13+
public static TValue GetOrNull<TKey, TValue>(
14+
this IDictionary<TKey, TValue> dictionary, TKey key)
15+
where TValue : class
1516
{
16-
V result;
17-
return dictionary.TryGetValue(key, out result) ? result : null;
17+
TValue result;
18+
dictionary.TryGetValue(key, out result);
19+
return result;
1820
}
1921

20-
public static V GetOrAdd<K, V, T>(this ConcurrentDictionary<K, T> dictionary, K key, Func<V> add)
21-
where V : T
22-
=> (V)dictionary.GetOrAdd(key, _ => add());
22+
public static T GetOrAddWithCast<TKey, T, TBase>(
23+
this ConcurrentDictionary<TKey, TBase> dictionary, TKey key, Func<T> add)
24+
where T : TBase
25+
=> (T)dictionary.GetOrAdd(key, _ => add());
2326
}
2427
}

0 commit comments

Comments
 (0)