Skip to content

Commit

Permalink
ResourceOperations
Browse files Browse the repository at this point in the history
  • Loading branch information
sergey-shandar committed Nov 14, 2017
1 parent 74ff467 commit 95173ef
Show file tree
Hide file tree
Showing 20 changed files with 411 additions and 147 deletions.
Original file line number Diff line number Diff line change
@@ -1,19 +1,20 @@
using Microsoft.Azure.Management.Compute;
using Microsoft.Azure.Management.Compute.Models;
using System;
using System.Threading;
using System.Threading.Tasks;

namespace Microsoft.Azure.Experiments.Compute
{
public static class ComputePolicy
{
public static ResourcePolicy<Config> Create<Config, Operations>(
string header,
Func<IComputeManagementClient, Operations> getOperations,
Func<GetAsyncParams<Operations>, Task<Config>> getAsync,
Func<CreateOrUpdateAsyncParams<Operations, Config>, Task<Config>> createOrUpdateAsync)
where Config : Resource
=> ResourcePolicy.Create(
new[] { "Microsoft.Compute", header },
getOperations,
getAsync,
createOrUpdateAsync,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ public static class VirtualMachinePolicy
{
public static ResourcePolicy<VirtualMachine> Policy { get; }
= ComputePolicy.Create(
"virtualMachines",
client => client.VirtualMachines,
p => p.Operations.GetAsync(
p.ResourceGroupName, p.Name, null, p.CancellationToken),
Expand Down
50 changes: 0 additions & 50 deletions experiments/Azure.Experiments/Azure.Experiments/CreateOperation.cs

This file was deleted.

Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
using System.Collections.Concurrent;

namespace Microsoft.Azure.Experiments
{
public static class Parameters
{
public static IState GetParameters<Config>(
string subscription, string location, IResourceConfig<Config> config)
where Config : class
{
var visitor = new Visitor(subscription, location);
visitor.Get(config);
return visitor.Result;
}

sealed class Visitor : IResourceConfigVisitor<object>
{
public Visitor(string subscription, string location)
{
Subscription = subscription;
Location = location;
}

public Config Get<Config>(IResourceConfig<Config> config)
where Config : class
=> Result.GetOrAdd(config, () => config.Apply(this) as Config);

public object Visit<Config>(ResourceConfig<Config> config) where Config : class
{
var p = config.CreateConfig(Subscription);
config.Policy.SetLocation(p, Location);
return p;
}

public object Visit<Config, ParentConfig>(
NestedResourceConfig<Config, ParentConfig> config)
where Config : class
where ParentConfig : class
{
var result = config.Create();
config.Policy.Set(Get(config.Parent), result);
return result;
}

string Subscription { get; }

string Location { get; }

public State Result { get; } = new State();
}
}
}
87 changes: 87 additions & 0 deletions experiments/Azure.Experiments/Azure.Experiments/CurrentState.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,87 @@
using Microsoft.Rest.Azure;
using System.Collections.Concurrent;
using System.Linq;
using System.Net;
using System.Threading;
using System.Threading.Tasks;

namespace Microsoft.Azure.Experiments
{
public static class CurrentState
{
public static async Task<IState> GetState<Config>(
IClient client, IResourceConfig<Config> resourceConfig)
where Config : class
{
var visitor = new Visitor(client);
await visitor.GetOrAdd(resourceConfig);
return visitor.Result;
}

sealed class Visitor : IResourceConfigVisitor<Task<object>>
{
public async Task<object> GetOrAddUntyped(IResourceConfig config)
=> await Map.GetOrAdd(
config,
async _ =>
{
var info = await config.Apply(this);
if (info != null)
{
Result.GetOrAddUntyped(config, () => info);
}
return info;
});

public async Task<Config> GetOrAdd<Config>(IResourceConfig<Config> config)
where Config : class
{
var result = await GetOrAddUntyped(config);
return result as Config;
}

public async Task<object> Visit<Config>(ResourceConfig<Config> config)
where Config : class
{
Config info;
try
{
info = await config.Policy.GetAsync(GetAsyncParams.Create(
Client, config.ResourceGroupName, config.Name, new CancellationToken()));
}
catch (CloudException e) when (e.Response.StatusCode == HttpStatusCode.NotFound)
{
info = null;
}
if (info == null)
{
var tasks = config.Dependencies.Select(GetOrAddUntyped);
await Task.WhenAll(tasks);
return null;
}
return info;
}

public async Task<object> Visit<Config, ParentConfig>(
NestedResourceConfig<Config, ParentConfig> config)
where Config : class
where ParentConfig : class
{
var parent = await GetOrAdd(config.Parent);
return parent == null ? null : config.Policy.Get(parent);
}

public Visitor(IClient client)
{
Client = client;
}

public State Result { get; } = new State();

IClient Client { get; }

ConcurrentDictionary<IResourceConfig, Task<object>> Map { get; }
= new ConcurrentDictionary<IResourceConfig, Task<object>>();
}
}
}
Original file line number Diff line number Diff line change
@@ -1,9 +1,12 @@
namespace Microsoft.Azure.Experiments
using System.Collections.Generic;

namespace Microsoft.Azure.Experiments
{
public interface IResourceConfigVisitor<Result>
{
Result Visit<Config>(ResourceConfig<Config> config)
where Config : class;

Result Visit<Config, ParentConfig>(NestedResourceConfig<Config, ParentConfig> config)
where Config : class
where ParentConfig : class;
Expand All @@ -12,6 +15,8 @@ Result Visit<Config, ParentConfig>(NestedResourceConfig<Config, ParentConfig> co
public interface IResourceConfig
{
Result Apply<Result>(IResourceConfigVisitor<Result> visitor);

IEnumerable<string> GetId(string subscription);
}

public interface IResourceConfig<Config> : IResourceConfig
Expand Down
2 changes: 1 addition & 1 deletion experiments/Azure.Experiments/Azure.Experiments/IState.cs
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
{
public interface IState
{
Config Get<Config>(IResourceConfig<Config> config)
Config GetOrNull<Config>(IResourceConfig<Config> config)
where Config : class;
}
}
Original file line number Diff line number Diff line change
@@ -1,21 +1,37 @@
namespace Microsoft.Azure.Experiments
using System;
using System.Collections.Generic;
using System.Linq;

namespace Microsoft.Azure.Experiments
{
public sealed class NestedResourceConfig<Config, ParentConfig> : IResourceConfig<Config>
where Config : class
where ParentConfig : class
{
public NestedResourcePolicy<Config, ParentConfig> Policy { get; }

public string Name { get; }

public IResourceConfig<ParentConfig> Parent { get; }

public Func<Config> Create { get; }

public NestedResourceConfig(
NestedResourcePolicy<Config, ParentConfig> policy, IResourceConfig<ParentConfig> parent)
NestedResourcePolicy<Config, ParentConfig> policy,
IResourceConfig<ParentConfig> parent,
string name,
Func<Config> create)
{
Policy = policy;
Name = name;
Parent = parent;
Create = create;
}

public Result Apply<Result>(IResourceConfigVisitor<Result> visitor)
=> visitor.Visit(this);

public IEnumerable<string> GetId(string subscription)
=> Parent.GetId(subscription).Concat(Policy.GetId(Name));
}
}
Original file line number Diff line number Diff line change
@@ -1,16 +1,22 @@
using System;
using System.Collections.Generic;

namespace Microsoft.Azure.Experiments
{
public sealed class NestedResourcePolicy<Config, ParentConfig> : IResourcePolicy
{
public Func<string, IEnumerable<string>> GetId { get; }

public Func<ParentConfig, Config> Get { get; }

public Action<ParentConfig, Config> Set { get; }

public NestedResourcePolicy(
Func<ParentConfig, Config> get, Action<ParentConfig, Config> set)
Func<string, IEnumerable<string>> getId,
Func<ParentConfig, Config> get,
Action<ParentConfig, Config> set)
{
GetId = getId;
Get = get;
Set = set;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,14 +8,41 @@ public static class NetworkInterfacePolicy
{
public static ResourcePolicy<NetworkInterface> Policy { get; }
= NetworkPolicy.Create(
"networkInterfaces",
client => client.NetworkInterfaces,
p => p.Operations.GetAsync(
p.ResourceGroupName, p.Name, null, p.CancellationToken),
p => p.Operations.CreateOrUpdateAsync(
p.ResourceGroupName, p.Name, p.Config, p.CancellationToken));

public static ResourceConfig<NetworkInterface> CreateNetworkSecurityGroupConfig(
this ResourceConfig<ResourceGroup> resourceGroup, string name)
=> Policy.CreateConfig(resourceGroup, name);
this ResourceConfig<ResourceGroup> resourceGroup,
string name,
ResourceConfig<Subnet> subnet,
ResourceConfig<PublicIPAddress> publicIPAddress,
ResourceConfig<NetworkSecurityGroup> networkSecurityGroup)
=> Policy.CreateConfig(
resourceGroup,
name,
subscription => new NetworkInterface
{
IpConfigurations = new []
{
new NetworkInterfaceIPConfiguration
{
Name = name,
Subnet = new Subnet { Id = subnet.GetId(subscription).IdToString() },
PublicIPAddress = new PublicIPAddress
{
Id = publicIPAddress.GetId(subscription).IdToString()
}
}
},
NetworkSecurityGroup = new NetworkSecurityGroup
{
Id = networkSecurityGroup.GetId(subscription).IdToString()
}
},
new IResourceConfig[] { subnet, publicIPAddress, networkSecurityGroup });
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -8,11 +8,13 @@ namespace Microsoft.Azure.Experiments.Network
public static class NetworkPolicy
{
public static ResourcePolicy<Config> Create<Config, Operations>(
string header,
Func<INetworkManagementClient, Operations> getOperations,
Func<GetAsyncParams<Operations>, Task<Config>> getAsync,
Func<CreateOrUpdateAsyncParams<Operations, Config>, Task<Config>> createOrUpdateAsync)
where Config : Resource
=> ResourcePolicy.Create(
new [] { "Microsoft.Network", header },
getOperations,
getAsync,
createOrUpdateAsync,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ public static class NetworkSecurityGroupPolicy
{
public static ResourcePolicy<NetworkSecurityGroup> Policy { get; }
= NetworkPolicy.Create(
"networkSecurityGroups",
client => client.NetworkSecurityGroups,
p => p.Operations.GetAsync(
p.ResourceGroupName, p.Name, null, p.CancellationToken),
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ public static class PublicIPAddressPolicy
{
public static ResourcePolicy<PublicIPAddress> Policy { get; }
= NetworkPolicy.Create(
"publicIPAddresses",
client => client.PublicIPAddresses,
p => p.Operations.GetAsync(
p.ResourceGroupName, p.Name, null, p.CancellationToken),
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ public static class VirtualNetworkPolicy
{
public static ResourcePolicy<VirtualNetwork> Policy { get; }
= NetworkPolicy.Create(
"virtualNetworks",
client => client.VirtualNetworks,
p => p.Operations.GetAsync(
p.ResourceGroupName, p.Name, null, p.CancellationToken),
Expand Down
Loading

0 comments on commit 95173ef

Please sign in to comment.