Skip to content

Commit 3fb8184

Browse files
authored
Merge pull request #5610 from sergey-shandar/sergey-engine-squashed
Strategies: IEngine for context dependent ids.
2 parents 7c12657 + 7920357 commit 3fb8184

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

48 files changed

+746
-593
lines changed

setup/azurecmdfiles.wxi

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -277,8 +277,8 @@
277277
<Component Id="cmp4677B0CE124023330EDD7AA4FECFF45E" Guid="*">
278278
<File Id="fil58F144170E43C2EFEC66E5F3DE2FA977" KeyPath="yes" Source="$(var.sourceDir)\ResourceManager\AzureResourceManager\AzureRM.Compute\AzureRM.Compute.psm1" />
279279
</Component>
280-
<Component Id="cmp32CF42EA1F0A7DA716459A5A6A21C24D" Guid="*">
281-
<File Id="fil5AE28BCCEED67270ECF02C93C9688AD5" KeyPath="yes" Source="$(var.sourceDir)\ResourceManager\AzureResourceManager\AzureRM.Compute\Microsoft.Azure.Commands.Common.Strategies.dll" />
280+
<Component Id="cmp561E55C40D05D507C193CFCE5CA35C18" Guid="*">
281+
<File Id="fil2F8613299D44A39AB296BD6F8806CBF7" KeyPath="yes" Source="$(var.sourceDir)\ResourceManager\AzureResourceManager\AzureRM.Compute\Microsoft.Azure.Commands.Common.Strategies.3.dll" />
282282
</Component>
283283
<Component Id="cmpFBB75A5451448B356C97E62D2C6C10A0" Guid="*">
284284
<File Id="fil24BE7D514EE83ED7D31C68CBFFA8FBB8" KeyPath="yes" Source="$(var.sourceDir)\ResourceManager\AzureResourceManager\AzureRM.Compute\Microsoft.Azure.Commands.Compute.dll" />
@@ -3302,7 +3302,7 @@
33023302
<ComponentRef Id="cmpD2516E302D41812368A84BD6010FB066" />
33033303
<ComponentRef Id="cmp594709EB2E69BD7173BC8833BE2061B4" />
33043304
<ComponentRef Id="cmp4677B0CE124023330EDD7AA4FECFF45E" />
3305-
<ComponentRef Id="cmp32CF42EA1F0A7DA716459A5A6A21C24D" />
3305+
<ComponentRef Id="cmp561E55C40D05D507C193CFCE5CA35C18" />
33063306
<ComponentRef Id="cmpFBB75A5451448B356C97E62D2C6C10A0" />
33073307
<ComponentRef Id="cmp1CB1E6D6A2D939FB32D9ACD70681644D" />
33083308
<ComponentRef Id="cmpAA00FCFEE63D9A20C2618B36B1848D7C" />

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

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,14 @@
3030
<WarningLevel>4</WarningLevel>
3131
</PropertyGroup>
3232
<ItemGroup>
33+
<Reference Include="Microsoft.Rest.ClientRuntime, Version=2.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL">
34+
<HintPath>..\..\..\packages\Microsoft.Rest.ClientRuntime.2.3.10\lib\net452\Microsoft.Rest.ClientRuntime.dll</HintPath>
35+
<Private>True</Private>
36+
</Reference>
37+
<Reference Include="Newtonsoft.Json, Version=6.0.0.0, Culture=neutral, PublicKeyToken=30ad4fe6b2a6aeed, processorArchitecture=MSIL">
38+
<HintPath>..\..\..\packages\Newtonsoft.Json.6.0.8\lib\net45\Newtonsoft.Json.dll</HintPath>
39+
<Private>True</Private>
40+
</Reference>
3341
<Reference Include="System" />
3442
<Reference Include="System.Core" />
3543
<Reference Include="System.Xml.Linq" />
@@ -58,6 +66,7 @@
5866
<ItemGroup>
5967
<Compile Include="Compute\ImageVersionTest.cs" />
6068
<Compile Include="Properties\AssemblyInfo.cs" />
69+
<Compile Include="TargetStateTest.cs" />
6170
<Compile Include="TimeSlotTest.cs" />
6271
</ItemGroup>
6372
<ItemGroup>
Lines changed: 110 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,110 @@
1+
using Microsoft.Rest;
2+
using Microsoft.WindowsAzure.Commands.ScenarioTest;
3+
using System.Threading;
4+
using Xunit;
5+
using System.Collections.Generic;
6+
using System.Linq;
7+
8+
namespace Microsoft.Azure.Commands.Common.Strategies.UnitTest
9+
{
10+
public class TargetStateTest
11+
{
12+
class Client : ServiceClient<Client>, IClient
13+
{
14+
public T GetClient<T>() where T : ServiceClient<T>
15+
=> this as T;
16+
}
17+
18+
class NestedModel
19+
{
20+
public string Name { get; set; }
21+
22+
public string Id { get; set; }
23+
}
24+
25+
class Model
26+
{
27+
public string Location { get; set; }
28+
29+
public IList<NestedModel> Nested { get; set; }
30+
}
31+
32+
[Fact]
33+
[Trait(Category.AcceptanceType, Category.CheckIn)]
34+
public void TestDependencyGraph()
35+
{
36+
// resource group
37+
var rgStrategy = ResourceStrategy.Create<Model, Client, Client>(
38+
ResourceType.ResourceGroup,
39+
c => c,
40+
async (c, m) => null,
41+
async (c, m) => new Model(),
42+
m => m.Location,
43+
(m, location) => m.Location = location,
44+
m => 0,
45+
false);
46+
47+
var rgConfig = rgStrategy.CreateResourceConfig(null, "rgname");
48+
var rgConfig2 = rgStrategy.CreateResourceConfig(null, "rgname2");
49+
50+
// resource
51+
var resourceStrategy = ResourceStrategy.Create<Model, Client, Client>(
52+
new ResourceType("Company.Namespace", "resourceProvider"),
53+
c => c,
54+
async (c, m) => null,
55+
async (c, m) => new Model(),
56+
m => m.Location,
57+
(m, location) => m.Location = location,
58+
m => 0,
59+
false);
60+
61+
var resource = resourceStrategy.CreateResourceConfig(rgConfig, "res");
62+
63+
// nested resource
64+
var rgNestedStrategy = NestedResourceStrategy.Create<NestedModel, Model>(
65+
"rgnested",
66+
m => m.Nested,
67+
(m, list) => m.Nested = list,
68+
nm => nm.Name,
69+
(nm, name) => nm.Name = name);
70+
71+
// add the nested resource to the resource group.
72+
var rgNestedConfig = rgConfig.CreateNested(rgNestedStrategy, "rgnestedname");
73+
74+
// nested resource
75+
var nestedStrategy = NestedResourceStrategy.Create<NestedModel, Model>(
76+
"nested",
77+
m => m.Nested,
78+
(m, list) => m.Nested = list,
79+
nm => nm.Name,
80+
(nm, name) => nm.Name = name);
81+
82+
// add the nested resource to a resource.
83+
var nestedConfig = resource.CreateNested(
84+
nestedStrategy,
85+
"nestedname",
86+
e => new NestedModel
87+
{
88+
Id = e.GetId(rgConfig2)
89+
});
90+
91+
//
92+
var engine = new SdkEngine("s");
93+
94+
// empty state.
95+
var current = new StateOperationContext(new Client(), new CancellationToken())
96+
.Result;
97+
98+
var state = resource.GetTargetState(current, engine, "eastus");
99+
var rgModel = state.Get(rgConfig);
100+
101+
Assert.Equal("eastus", rgModel.Location);
102+
103+
var rgNestedModel = rgModel.Nested.First() as NestedModel;
104+
Assert.Equal("rgnestedname", rgNestedModel.Name);
105+
106+
var rgModel2 = state.Get(rgConfig2);
107+
Assert.NotNull(rgModel2);
108+
}
109+
}
110+
}

src/ResourceManager/Common/Commands.Common.Strategies.UnitTest/packages.config

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,7 @@
11
<?xml version="1.0" encoding="utf-8"?>
22
<packages>
3+
<package id="Microsoft.Rest.ClientRuntime" version="2.3.10" targetFramework="net452" />
4+
<package id="Newtonsoft.Json" version="6.0.8" targetFramework="net452" />
35
<package id="xunit" version="2.1.0" targetFramework="net452" />
46
<package id="xunit.abstractions" version="2.0.0" targetFramework="net452" />
57
<package id="xunit.assert" version="2.1.0" targetFramework="net452" />

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

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88
<OutputType>Library</OutputType>
99
<AppDesignerFolder>Properties</AppDesignerFolder>
1010
<RootNamespace>Microsoft.Azure.Commands.Common.Strategies</RootNamespace>
11-
<AssemblyName>Microsoft.Azure.Commands.Common.Strategies</AssemblyName>
11+
<AssemblyName>Microsoft.Azure.Commands.Common.Strategies.3</AssemblyName>
1212
<TargetFrameworkVersion>v4.5.2</TargetFrameworkVersion>
1313
<FileAlignment>512</FileAlignment>
1414
</PropertyGroup>
@@ -56,6 +56,14 @@
5656
</ItemGroup>
5757
<ItemGroup>
5858
<Compile Include="Compute\ImageVersion.cs" />
59+
<Compile Include="DependencyEngine.cs" />
60+
<Compile Include="INestedResourceConfig.cs" />
61+
<Compile Include="INestedResourceConfigVisitor.cs" />
62+
<Compile Include="INestedResourceStrategy.cs" />
63+
<Compile Include="Property.cs" />
64+
<Compile Include="ResourceType.cs" />
65+
<Compile Include="SdkEngine.cs" />
66+
<Compile Include="IEngine.cs" />
5967
<Compile Include="IResourceConfig.cs" />
6068
<Compile Include="IResourceConfigVisitor.cs" />
6169
<Compile Include="IResourceStrategy.cs" />
@@ -78,7 +86,6 @@
7886
<Compile Include="IEntityConfigVisitor.cs" />
7987
<Compile Include="IEntityStrategy.cs" />
8088
<Compile Include="IState.cs" />
81-
<Compile Include="NestedResourceConfigExtensions.cs" />
8289
<Compile Include="ResourceConfigExtensions.cs" />
8390
<Compile Include="StateExtensions.cs" />
8491
<Compile Include="NestedResourceConfig.cs" />
Lines changed: 11 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -12,19 +12,20 @@
1212
// limitations under the License.
1313
// ----------------------------------------------------------------------------------
1414

15-
using System;
15+
using System.Collections.Concurrent;
1616

1717
namespace Microsoft.Azure.Commands.Common.Strategies
1818
{
19-
public static class NestedResourceConfigExtensions
19+
internal sealed class DependencyEngine : IEngine
2020
{
21-
public static NestedResourceConfig<TModel, TParenModel> CreateConfig<TModel, TParenModel>(
22-
this NestedResourceStrategy<TModel, TParenModel> strategy,
23-
IEntityConfig<TParenModel> parent,
24-
string name,
25-
Func<string, TModel> createModel)
26-
where TModel : class
27-
where TParenModel : class
28-
=> new NestedResourceConfig<TModel, TParenModel>(strategy, parent, name, createModel);
21+
public ConcurrentDictionary<string, IEntityConfig> Dependencies { get; }
22+
= new ConcurrentDictionary<string, IEntityConfig>();
23+
24+
public string GetId(IEntityConfig config)
25+
{
26+
var id = config.DefaultIdStr();
27+
Dependencies.GetOrAdd(id, config);
28+
return id;
29+
}
2930
}
3031
}

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

Lines changed: 19 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@
1313
// ----------------------------------------------------------------------------------
1414

1515
using System.Collections.Generic;
16+
using System.Linq;
1617

1718
namespace Microsoft.Azure.Commands.Common.Strategies
1819
{
@@ -22,6 +23,23 @@ public static string IdToString(this IEnumerable<string> id)
2223
=> "/" + string.Join("/", id);
2324

2425
public static string DefaultIdStr(this IEntityConfig config)
25-
=> config.GetId(string.Empty).IdToString();
26+
=> config.GetIdFromSubscription().IdToString();
27+
28+
public static string GetResourceGroupName(this IEntityConfig config)
29+
=> config.ResourceGroup?.Name ?? config.Name;
30+
31+
public static IEnumerable<string> GetIdFromSubscription(this IEntityConfig config)
32+
{
33+
var resourceGroupId = new[]
34+
{
35+
ResourceType.ResourceGroups, config.GetResourceGroupName()
36+
};
37+
return config.ResourceGroup == null
38+
? resourceGroupId
39+
: resourceGroupId.Concat(config.GetProvidersId());
40+
}
41+
42+
internal static IEnumerable<string> GetProvidersId(this IEntityConfig config)
43+
=> new[] { "providers" }.Concat(config.GetIdFromResourceGroup());
2644
}
2745
}

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

Lines changed: 0 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -21,15 +21,6 @@ namespace Microsoft.Azure.Commands.Common.Strategies
2121
{
2222
public static class Extensions
2323
{
24-
/// <summary>
25-
/// Returns an empty sequence if the given parameter is null.
26-
/// </summary>
27-
/// <typeparam name="T"></typeparam>
28-
/// <param name="value"></param>
29-
/// <returns></returns>
30-
public static IEnumerable<T> EmptyIfNull<T>(this IEnumerable<T> value)
31-
=> value ?? Enumerable.Empty<T>();
32-
3324
public static TValue GetOrNull<TKey, TValue>(
3425
this IDictionary<TKey, TValue> dictionary, TKey key)
3526
where TValue : class
Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
// ----------------------------------------------------------------------------------
2+
//
3+
// Copyright Microsoft Corporation
4+
// Licensed under the Apache License, Version 2.0 (the "License");
5+
// you may not use this file except in compliance with the License.
6+
// You may obtain a copy of the License at
7+
// http://www.apache.org/licenses/LICENSE-2.0
8+
// Unless required by applicable law or agreed to in writing, software
9+
// distributed under the License is distributed on an "AS IS" BASIS,
10+
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
11+
// See the License for the specific language governing permissions and
12+
// limitations under the License.
13+
// ----------------------------------------------------------------------------------
14+
15+
namespace Microsoft.Azure.Commands.Common.Strategies
16+
{
17+
public interface IEngine
18+
{
19+
string GetId(IEntityConfig config);
20+
}
21+
}

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

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,20 +23,32 @@ public interface IEntityConfig
2323
{
2424
IEntityStrategy Strategy { get; }
2525

26+
IResourceConfig ResourceGroup { get; }
27+
2628
string Name { get; }
2729

2830
IResourceConfig Resource { get; }
2931

3032
TResult Accept<TContext, TResult>(
3133
IEntityConfigVisitor<TContext, TResult> visitor, TContext context);
3234

33-
IEnumerable<string> GetId(string subscription);
35+
IEnumerable<string> GetIdFromResourceGroup();
36+
37+
IEnumerable<INestedResourceConfig> NestedResources { get; }
38+
39+
IEnumerable<IEntityConfig> Dependencies { get; }
3440
}
3541

3642
public interface IEntityConfig<TModel> : IEntityConfig
3743
where TModel : class
3844
{
3945
TResult Accept<TContext, TResult>(
4046
IEntityConfigVisitor<TModel, TContext, TResult> visitor, TContext context);
47+
48+
void AddNested<TNestedModel>(
49+
NestedResourceConfig<TNestedModel, TModel> config)
50+
where TNestedModel : class;
51+
52+
new IEnumerable<INestedResourceConfig<TModel>> NestedResources { get; }
4153
}
4254
}
Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
// ----------------------------------------------------------------------------------
2+
//
3+
// Copyright Microsoft Corporation
4+
// Licensed under the Apache License, Version 2.0 (the "License");
5+
// you may not use this file except in compliance with the License.
6+
// You may obtain a copy of the License at
7+
// http://www.apache.org/licenses/LICENSE-2.0
8+
// Unless required by applicable law or agreed to in writing, software
9+
// distributed under the License is distributed on an "AS IS" BASIS,
10+
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
11+
// See the License for the specific language governing permissions and
12+
// limitations under the License.
13+
// ----------------------------------------------------------------------------------
14+
15+
namespace Microsoft.Azure.Commands.Common.Strategies
16+
{
17+
public interface INestedResourceConfig : IEntityConfig
18+
{
19+
new INestedResourceStrategy Strategy { get; }
20+
21+
IEntityConfig Parent { get; }
22+
}
23+
24+
public interface INestedResourceConfig<TParentModel> : INestedResourceConfig
25+
where TParentModel : class
26+
{
27+
new IEntityConfig<TParentModel> Parent { get; }
28+
29+
TResult Accept<TContext, TResult>(
30+
INestedResourceConfigVisitor<TParentModel, TContext, TResult> visitor, TContext context);
31+
}
32+
}
Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
// ----------------------------------------------------------------------------------
2+
//
3+
// Copyright Microsoft Corporation
4+
// Licensed under the Apache License, Version 2.0 (the "License");
5+
// you may not use this file except in compliance with the License.
6+
// You may obtain a copy of the License at
7+
// http://www.apache.org/licenses/LICENSE-2.0
8+
// Unless required by applicable law or agreed to in writing, software
9+
// distributed under the License is distributed on an "AS IS" BASIS,
10+
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
11+
// See the License for the specific language governing permissions and
12+
// limitations under the License.
13+
// ----------------------------------------------------------------------------------
14+
15+
namespace Microsoft.Azure.Commands.Common.Strategies
16+
{
17+
public interface INestedResourceConfigVisitor<TParentModel, TContext, TResult>
18+
where TParentModel : class
19+
{
20+
TResult Visit<TModel>(NestedResourceConfig<TModel, TParentModel> config, TContext context)
21+
where TModel : class;
22+
}
23+
}

0 commit comments

Comments
 (0)