Skip to content

Commit

Permalink
CreaOperation, StateLocation
Browse files Browse the repository at this point in the history
  • Loading branch information
sergey-shandar committed Nov 14, 2017
1 parent b18f0d1 commit 74ff467
Show file tree
Hide file tree
Showing 2 changed files with 124 additions and 0 deletions.
50 changes: 50 additions & 0 deletions experiments/Azure.Experiments/Azure.Experiments/CreateOperation.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
using System.Collections.Concurrent;
using System.Collections.Generic;
using System.Linq;

namespace Microsoft.Azure.Experiments
{
public sealed class CreateOperation
{
public IEnumerable<CreateOperation> Dependencies { get; }

public CreateOperation(IEnumerable<CreateOperation> dependencies)
{
Dependencies = dependencies;
}

public static CreateOperation Create<Config>(IState state, IResourceConfig<Config> config)
where Config : class
=> new Visitor(state).Get(config);

sealed class Visitor : IResourceConfigVisitor<CreateOperation>
{
public CreateOperation Get(IResourceConfig config)
=> Map.GetOrAdd(config, _ => config.Apply(this));

public CreateOperation Visit<Config>(ResourceConfig<Config> config) where Config : class
{
var info = State.Get(config);
return info == null
? new CreateOperation(config.Dependencies.Select(d => Get(d)))
: null;
}

public CreateOperation Visit<Config, ParentConfig>(
NestedResourceConfig<Config, ParentConfig> config)
where Config : class
where ParentConfig : class
=> Get(config.Parent);

public Visitor(IState state)
{
State = state;
}

IState State { get; }

ConcurrentDictionary<IResourceConfig, CreateOperation> Map { get; }
= new ConcurrentDictionary<IResourceConfig, CreateOperation>();
}
}
}
74 changes: 74 additions & 0 deletions experiments/Azure.Experiments/Azure.Experiments/StateLocation.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,74 @@
using Microsoft.Azure.Management.ResourceManager.Models;
using System.Linq;

namespace Microsoft.Azure.Experiments
{
public static class StateLocation
{
public static string GetLocation(this IState state, IResourceConfig config)
=> config.Apply(new Visitor(state))?.Location;

class DependencyLocation
{
public string Location { get; }

public bool IsCompulsory { get; }

public DependencyLocation(string location, bool isCompulsory)
{
Location = location;
IsCompulsory = isCompulsory;
}
}

static DependencyLocation Merge(this DependencyLocation a, DependencyLocation b)
{
if (a == null)
{
return b;
}
if (b == null)
{
return a;
}

if (a.IsCompulsory != b.IsCompulsory)
{
return a.IsCompulsory ? b : a;
}

// a.IsCompulsory == b.IsCompulsory
return a.Location == b.Location ? a : new DependencyLocation(null, a.IsCompulsory);
}

sealed class Visitor : IResourceConfigVisitor<DependencyLocation>
{
public DependencyLocation Visit<Config>(ResourceConfig<Config> config)
where Config : class
{
var info = State.Get(config);
return info != null
? new DependencyLocation(
config.Policy.GetLocation(info),
typeof(Config) != typeof(ResourceGroup))
: config
.Dependencies
.Select(c => c.Apply(this))
.Aggregate((DependencyLocation)null, Merge);
}

public DependencyLocation Visit<Config, ParentConfig>(
NestedResourceConfig<Config, ParentConfig> config)
where Config : class
where ParentConfig : class
=> config.Parent.Apply(this);

public Visitor(IState state)
{
State = state;
}

IState State { get; }
}
}
}

0 comments on commit 74ff467

Please sign in to comment.