Moved domain and shared to submodule

This commit is contained in:
Philip Dimitratos 2017-10-26 15:50:25 -07:00
Родитель 57cb68e5ee
Коммит 890a72b6d6
42 изменённых файлов: 38 добавлений и 1115 удалений

Просмотреть файл

@ -1,26 +0,0 @@
using Microsoft.EntityFrameworkCore;
using Sia.Data.Playbooks.Models;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace Sia.Data.Playbooks
{
public static class EagerLoading
{
public static IQueryable<EventType> WithEagerLoading(this DbSet<EventType> table)
{
return table
.Include(et => et.ActionAssociations)
.ThenInclude(ettaa => ettaa.Action)
.ThenInclude(act => act.ActionTemplate)
.ThenInclude(at => at.Sources)
.Include(et => et.ActionAssociations)
.ThenInclude(ettaa => ettaa.Action)
.ThenInclude(act => act.ConditionSets)
.ThenInclude(cs => cs.Conditions)
.ThenInclude(cond => cond.ConditionSource);
}
}
}

Просмотреть файл

@ -1,21 +0,0 @@
using Sia.Shared.Data;
using System;
using System.Collections.Generic;
using System.Text;
namespace Sia.Data.Playbooks.Models
{
public class Action : IEntity
{
public long Id { get; set; }
public string Name { get; set; }
public ActionTemplate ActionTemplate { get; set; }
public long ActionTemplateId { get; set; }
public ICollection<ConditionSet> ConditionSets { get; set; }
= new HashSet<ConditionSet>();
public ICollection<EventTypeToActionAssociation> EventTypeAssociations { get; set; }
= new HashSet<EventTypeToActionAssociation>();
public ICollection<EventType> EventTypes
=> new ManyToManyCollection<Action, EventTypeToActionAssociation, EventType>(this, EventTypeAssociations);
}
}

Просмотреть файл

@ -1,20 +0,0 @@
using Sia.Shared.Data;
using System;
using System.Collections.Generic;
using System.Text;
namespace Sia.Data.Playbooks.Models
{
public class ActionTemplate : IEntity
{
public long Id { get; set; }
public string Name { get; set; }
public bool IsUrl { get; set; }
public string Template { get; set; }
public ICollection<Action> Actions { get; set; }
= new HashSet<Action>();
public ICollection<ActionTemplateSource> Sources { get; set; }
= new HashSet<ActionTemplateSource>();
}
}

Просмотреть файл

@ -1,12 +0,0 @@
using System;
using System.Collections.Generic;
using System.Text;
namespace Sia.Data.Playbooks.Models
{
public class ActionTemplateSource : Source
{
public ActionTemplate ActionTemplate { get; set; }
public long ActionTemplateId { get; set; }
}
}

Просмотреть файл

@ -1,27 +0,0 @@
using Sia.Shared.Data;
using System;
using System.Collections.Generic;
using System.Text;
namespace Sia.Data.Playbooks.Models
{
public class Condition : IEntity
{
public long Id { get; set; }
public string Name { get; set; }
public ConditionType ConditionType { get; set; }
public string ComparisonValue { get; set; }
public ConditionSource ConditionSource { get; set; }
public long ConditionSourceId { get; set; }
public ConditionSet ConditionSet { get; set; }
public long ConditionSetId { get; set; }
}
public enum ConditionType
{
Equals,
DoesNotEqual,
Contains,
DoesNotContain
}
}

Просмотреть файл

@ -1,25 +0,0 @@
using Sia.Shared.Data;
using System;
using System.Collections.Generic;
using System.Text;
namespace Sia.Data.Playbooks.Models
{
public class ConditionSet : IEntity
{
public long Id { get; set; }
public string Name { get; set; }
public ConditionSetType Type { get; set; }
public Action Action { get; set; }
public long ActionId { get; set; }
public ICollection<Condition> Conditions { get; set; }
= new HashSet<Condition>();
}
public enum ConditionSetType
{
AnyOf,
AllOf,
NoneOf
}
}

Просмотреть файл

@ -1,11 +0,0 @@
using System;
using System.Collections.Generic;
using System.Text;
namespace Sia.Data.Playbooks.Models
{
public class ConditionSource : Source
{
public ICollection<Condition> Conditions { get; set; }
}
}

Просмотреть файл

@ -1,19 +0,0 @@
using Sia.Shared.Data;
using System;
using System.Collections.Generic;
using System.Text;
namespace Sia.Data.Playbooks.Models
{
public class EventType : IEntity
{
public long Id { get; set; }
public string Name { get; set; }
public dynamic Data { get; set; }
public ICollection<EventTypeToActionAssociation> ActionAssociations { get; set; }
= new HashSet<EventTypeToActionAssociation>();
public ICollection<Action> Actions
=> new ManyToManyCollection<EventType, EventTypeToActionAssociation, Action>(this, ActionAssociations);
}
}

Просмотреть файл

@ -1,21 +0,0 @@
using Sia.Shared.Data;
using System;
using System.Collections.Generic;
using System.Text;
namespace Sia.Data.Playbooks.Models
{
public class EventTypeToActionAssociation
: BidrectionalAssociation<EventType, Action>
{
public long EventTypeId { get; set; }
public long ActionId { get; set; }
public EventType EventType { get; set; }
public Action Action { get; set; }
protected override long _leftId { get => EventTypeId; set => EventTypeId = value; }
protected override long _rightId { get => ActionId; set => ActionId = value; }
protected override EventType _left { get => EventType; set => EventType = value; }
protected override Action _right { get => Action; set => Action = value; }
}
}

Просмотреть файл

@ -1,23 +0,0 @@
using Sia.Shared.Data;
using System;
using System.Collections.Generic;
using System.Text;
namespace Sia.Data.Playbooks.Models
{
public abstract class Source : IEntity
{
public long Id { get; set; }
public string Name { get; set; }
public SourceObject SourceObject { get; set; }
public string Key { get; set; }
}
public enum SourceObject
{
Event,
Ticket,
EventType,
Engagement
}
}

Просмотреть файл

@ -1,29 +0,0 @@
using Microsoft.EntityFrameworkCore;
using Sia.Data.Playbooks.Models;
namespace Sia.Data.Playbooks
{
public class PlaybookContext : DbContext
{
public PlaybookContext(DbContextOptions<PlaybookContext> options) { }
protected override void OnModelCreating(ModelBuilder modelBuilder)
{
modelBuilder.WithManyToManyAssociation<EventType, Action, EventTypeToActionAssociation>
(
(eventType) => eventType.ActionAssociations,
(action) => action.EventTypeAssociations
);
}
public DbSet<Action> Actions { get; set; }
public DbSet<ActionTemplate> ActionTemplates { get; set; }
public DbSet<ActionTemplateSource> ActionTemplateSources { get; set; }
public DbSet<Condition> Conditions { get; set; }
public DbSet<ConditionSet> ConditionSets { get; set; }
public DbSet<ConditionSource> ConditionSources { get; set; }
public DbSet<EventType> EventTypes { get; set; }
public DbSet<EventTypeToActionAssociation> EventTypeToActionAssociations { get; set; }
}
}

Просмотреть файл

@ -1,11 +0,0 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>netcoreapp2.0</TargetFramework>
</PropertyGroup>
<ItemGroup>
<ProjectReference Include="..\src\Sia.Shared\Sia.Shared.csproj" />
</ItemGroup>
</Project>

Просмотреть файл

@ -1,14 +1,8 @@

Microsoft Visual Studio Solution File, Format Version 12.00
# Visual Studio 15
VisualStudioVersion = 15.0.26730.16
VisualStudioVersion = 15.0.27004.2005
MinimumVisualStudioVersion = 10.0.40219.1
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Sia.Shared", "src\Sia.Shared\Sia.Shared.csproj", "{C4AA9F6D-DFB1-4044-A7CD-FA3B6D5BA6AE}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Sia.Domain", "src\Sia.Domain\Sia.Domain.csproj", "{06A61034-E432-4BA2-97F4-3339A95B1871}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Sia.Domain.ApiModels", "src\Sia.Domain.ApiModels\Sia.Domain.ApiModels.csproj", "{A08AACCD-A349-4EA9-BC36-CDE18E8A9E56}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Sia.Data.Incidents", "src\Sia.Data.Incident\Sia.Data.Incidents.csproj", "{269ABD9E-3E8E-4F7D-8D45-6FE13F405C5A}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Sia.Connectors.Tickets", "src\Sia.Connectors.Tickets\Sia.Connectors.Tickets.csproj", "{B92790C5-C4F1-4052-ABA7-68448F28DDB2}"
@ -21,9 +15,15 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "test", "test", "{931F26AB-5
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Sia.Gateway.Tests", "test\Sia.Gateway.Tests\Sia.Gateway.Tests.csproj", "{7FED8930-1B06-4954-8337-C2DEC6697D6F}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Sia.Shared.Tests", "Sia.Shared.Tests\Sia.Shared.Tests.csproj", "{BF2EE536-9EB2-4E97-8F6A-BDF6571BAA67}"
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Sia.Root", "Sia.Root", "{AAE5FA7E-B788-4E88-8E65-D27B7D1B0E0B}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Sia.Data.Playbooks", "Sia.Data.Playbooks\Sia.Data.Playbooks.csproj", "{8223434F-1377-4793-869A-ADF9EE2F08AF}"
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Sia.Domain", "domain\Domain\Sia.Domain\Sia.Domain.csproj", "{89DF1F67-19EC-4E38-B962-C1860C8D1D13}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Sia.Domain.ApiModels", "domain\Domain\Sia.Domain.ApiModels\Sia.Domain.ApiModels.csproj", "{826F9246-47E0-4333-947B-F8AB7C480383}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Sia.Shared", "domain\Domain\Sia.Shared\Sia.Shared.csproj", "{B258FBE4-E2D5-465E-805B-DE989CEA8CC5}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Sia.Shared.Tests", "domain\Domain\Sia.Shared.Tests\Sia.Shared.Tests.csproj", "{26C3DFC8-1AF2-4AD8-B54C-A4535285440C}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
@ -31,18 +31,6 @@ Global
Release|Any CPU = Release|Any CPU
EndGlobalSection
GlobalSection(ProjectConfigurationPlatforms) = postSolution
{C4AA9F6D-DFB1-4044-A7CD-FA3B6D5BA6AE}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{C4AA9F6D-DFB1-4044-A7CD-FA3B6D5BA6AE}.Debug|Any CPU.Build.0 = Debug|Any CPU
{C4AA9F6D-DFB1-4044-A7CD-FA3B6D5BA6AE}.Release|Any CPU.ActiveCfg = Release|Any CPU
{C4AA9F6D-DFB1-4044-A7CD-FA3B6D5BA6AE}.Release|Any CPU.Build.0 = Release|Any CPU
{06A61034-E432-4BA2-97F4-3339A95B1871}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{06A61034-E432-4BA2-97F4-3339A95B1871}.Debug|Any CPU.Build.0 = Debug|Any CPU
{06A61034-E432-4BA2-97F4-3339A95B1871}.Release|Any CPU.ActiveCfg = Release|Any CPU
{06A61034-E432-4BA2-97F4-3339A95B1871}.Release|Any CPU.Build.0 = Release|Any CPU
{A08AACCD-A349-4EA9-BC36-CDE18E8A9E56}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{A08AACCD-A349-4EA9-BC36-CDE18E8A9E56}.Debug|Any CPU.Build.0 = Debug|Any CPU
{A08AACCD-A349-4EA9-BC36-CDE18E8A9E56}.Release|Any CPU.ActiveCfg = Release|Any CPU
{A08AACCD-A349-4EA9-BC36-CDE18E8A9E56}.Release|Any CPU.Build.0 = Release|Any CPU
{269ABD9E-3E8E-4F7D-8D45-6FE13F405C5A}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{269ABD9E-3E8E-4F7D-8D45-6FE13F405C5A}.Debug|Any CPU.Build.0 = Debug|Any CPU
{269ABD9E-3E8E-4F7D-8D45-6FE13F405C5A}.Release|Any CPU.ActiveCfg = Release|Any CPU
@ -59,28 +47,35 @@ Global
{7FED8930-1B06-4954-8337-C2DEC6697D6F}.Debug|Any CPU.Build.0 = Debug|Any CPU
{7FED8930-1B06-4954-8337-C2DEC6697D6F}.Release|Any CPU.ActiveCfg = Release|Any CPU
{7FED8930-1B06-4954-8337-C2DEC6697D6F}.Release|Any CPU.Build.0 = Release|Any CPU
{BF2EE536-9EB2-4E97-8F6A-BDF6571BAA67}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{BF2EE536-9EB2-4E97-8F6A-BDF6571BAA67}.Debug|Any CPU.Build.0 = Debug|Any CPU
{BF2EE536-9EB2-4E97-8F6A-BDF6571BAA67}.Release|Any CPU.ActiveCfg = Release|Any CPU
{BF2EE536-9EB2-4E97-8F6A-BDF6571BAA67}.Release|Any CPU.Build.0 = Release|Any CPU
{8223434F-1377-4793-869A-ADF9EE2F08AF}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{8223434F-1377-4793-869A-ADF9EE2F08AF}.Debug|Any CPU.Build.0 = Debug|Any CPU
{8223434F-1377-4793-869A-ADF9EE2F08AF}.Release|Any CPU.ActiveCfg = Release|Any CPU
{8223434F-1377-4793-869A-ADF9EE2F08AF}.Release|Any CPU.Build.0 = Release|Any CPU
{89DF1F67-19EC-4E38-B962-C1860C8D1D13}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{89DF1F67-19EC-4E38-B962-C1860C8D1D13}.Debug|Any CPU.Build.0 = Debug|Any CPU
{89DF1F67-19EC-4E38-B962-C1860C8D1D13}.Release|Any CPU.ActiveCfg = Release|Any CPU
{89DF1F67-19EC-4E38-B962-C1860C8D1D13}.Release|Any CPU.Build.0 = Release|Any CPU
{826F9246-47E0-4333-947B-F8AB7C480383}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{826F9246-47E0-4333-947B-F8AB7C480383}.Debug|Any CPU.Build.0 = Debug|Any CPU
{826F9246-47E0-4333-947B-F8AB7C480383}.Release|Any CPU.ActiveCfg = Release|Any CPU
{826F9246-47E0-4333-947B-F8AB7C480383}.Release|Any CPU.Build.0 = Release|Any CPU
{B258FBE4-E2D5-465E-805B-DE989CEA8CC5}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{B258FBE4-E2D5-465E-805B-DE989CEA8CC5}.Debug|Any CPU.Build.0 = Debug|Any CPU
{B258FBE4-E2D5-465E-805B-DE989CEA8CC5}.Release|Any CPU.ActiveCfg = Release|Any CPU
{B258FBE4-E2D5-465E-805B-DE989CEA8CC5}.Release|Any CPU.Build.0 = Release|Any CPU
{26C3DFC8-1AF2-4AD8-B54C-A4535285440C}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{26C3DFC8-1AF2-4AD8-B54C-A4535285440C}.Debug|Any CPU.Build.0 = Debug|Any CPU
{26C3DFC8-1AF2-4AD8-B54C-A4535285440C}.Release|Any CPU.ActiveCfg = Release|Any CPU
{26C3DFC8-1AF2-4AD8-B54C-A4535285440C}.Release|Any CPU.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
EndGlobalSection
GlobalSection(NestedProjects) = preSolution
{C4AA9F6D-DFB1-4044-A7CD-FA3B6D5BA6AE} = {09E441A6-06F8-457A-981A-394473FB8CD5}
{06A61034-E432-4BA2-97F4-3339A95B1871} = {09E441A6-06F8-457A-981A-394473FB8CD5}
{A08AACCD-A349-4EA9-BC36-CDE18E8A9E56} = {09E441A6-06F8-457A-981A-394473FB8CD5}
{269ABD9E-3E8E-4F7D-8D45-6FE13F405C5A} = {09E441A6-06F8-457A-981A-394473FB8CD5}
{B92790C5-C4F1-4052-ABA7-68448F28DDB2} = {09E441A6-06F8-457A-981A-394473FB8CD5}
{8D465104-1385-4EE4-A1ED-AEE7708A537F} = {09E441A6-06F8-457A-981A-394473FB8CD5}
{7FED8930-1B06-4954-8337-C2DEC6697D6F} = {931F26AB-58CD-4667-A281-EEC186F2FB59}
{BF2EE536-9EB2-4E97-8F6A-BDF6571BAA67} = {931F26AB-58CD-4667-A281-EEC186F2FB59}
{8223434F-1377-4793-869A-ADF9EE2F08AF} = {09E441A6-06F8-457A-981A-394473FB8CD5}
{89DF1F67-19EC-4E38-B962-C1860C8D1D13} = {AAE5FA7E-B788-4E88-8E65-D27B7D1B0E0B}
{826F9246-47E0-4333-947B-F8AB7C480383} = {AAE5FA7E-B788-4E88-8E65-D27B7D1B0E0B}
{B258FBE4-E2D5-465E-805B-DE989CEA8CC5} = {AAE5FA7E-B788-4E88-8E65-D27B7D1B0E0B}
{26C3DFC8-1AF2-4AD8-B54C-A4535285440C} = {AAE5FA7E-B788-4E88-8E65-D27B7D1B0E0B}
EndGlobalSection
GlobalSection(ExtensibilityGlobals) = postSolution
SolutionGuid = {05069EBB-9F94-4DAA-A619-C2F496B37BA4}

Просмотреть файл

@ -1,134 +0,0 @@
using Microsoft.VisualStudio.TestTools.UnitTesting;
using Newtonsoft.Json.Linq;
using Sia.Shared.Data;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace Sia.Shared.Tests.Data
{
[TestClass]
public class PartialJsonResolverTests
{
[TestMethod]
public void ResolveJsonToString_Method_Resolve_WhenSourceValid_SerializesSourceArgumentObjectToString()
{
var input = new TestHasJsonDataObject
{
Data = new JsonSerializationTestObject()
};
var expectedResultDataValue = JsonSerializationTestObject.ExpectedSerialization();
var objectUnderTest = new ResolveJsonToString<TestHasJsonDataObject, TestHasJsonDataString>();
var result = objectUnderTest.Resolve(input, null, null, null);
Assert.AreEqual(expectedResultDataValue, result, false);
}
[TestMethod]
public void ResolveStringToJson_Method_Resolve_WhenSourceValid_SerializesSourceArgumentStringToObject()
{
var input = new TestHasJsonDataString()
{
Data = JsonSerializationTestObject.ExpectedSerialization()
};
var expectedResult = new JsonSerializationTestObject();
var objectUnderTest = new ResolveStringToJson<TestHasJsonDataString, TestHasJsonDataObject>();
var result = objectUnderTest.Resolve(input, null, null, null);
Assert.AreEqual(expectedResult.a, ExtractPropertyFromResult(result, "a"));
Assert.AreEqual(expectedResult.b, ExtractPropertyFromResult(result, "b"));
}
[TestMethod]
public void ResolveJsonToString_Method_Resolve_WhenSourceDataNull_ReturnsNull()
{
var input = new TestHasJsonDataObject
{
Data = null
};
var expectedResultDataValue = JsonSerializationTestObject.ExpectedSerialization();
var objectUnderTest = new ResolveJsonToString<TestHasJsonDataObject, TestHasJsonDataString>();
var result = objectUnderTest.Resolve(input, null, null, null);
Assert.AreEqual(null, result);
}
[TestMethod]
public void ResolveStringToJson_Method_Resolve_WhenSourceDataNull_ReturnsNull()
{
var input = new TestHasJsonDataString()
{
Data = null
};
var expectedResult = new JsonSerializationTestObject();
var objectUnderTest = new ResolveStringToJson<TestHasJsonDataString, TestHasJsonDataObject>();
var result = objectUnderTest.Resolve(input, null, null, null);
Assert.AreEqual(null, result);
}
[TestMethod]
public void ResolveJsonToString_Method_Resolve_WhenSourceNull_ReturnsNull()
{
TestHasJsonDataObject input = null;
var expectedResultDataValue = JsonSerializationTestObject.ExpectedSerialization();
var objectUnderTest = new ResolveJsonToString<TestHasJsonDataObject, TestHasJsonDataString>();
var result = objectUnderTest.Resolve(input, null, null, null);
Assert.AreEqual(null, result);
}
[TestMethod]
public void ResolveStringToJson_Method_Resolve_WhenSourceNull_ReturnsNull()
{
TestHasJsonDataString input = null;
var expectedResult = new JsonSerializationTestObject();
var objectUnderTest = new ResolveStringToJson<TestHasJsonDataString, TestHasJsonDataObject>();
var result = objectUnderTest.Resolve(input, null, null, null);
Assert.AreEqual(null, result);
}
private static JToken ExtractPropertyFromResult(object result, string propName) => ((JObject)result).Property(propName).Value;
}
internal class JsonSerializationTestObject :IEquatable<JsonSerializationTestObject>
{
public static string ExpectedSerialization()
=> "{\"a\":\"ValueOfA\",\"b\":1}";
public bool Equals(JsonSerializationTestObject other)
=> a == other.a && b == other.b;
public string a { get; set; } = "ValueOfA";
public int b { get; set; } = 1;
}
internal class TestHasJsonDataString : IJsonDataString
{
public string Data { get; set; }
}
internal class TestHasJsonDataObject : IJsonDataObject
{
public object Data { get; set; }
}
}

Просмотреть файл

@ -1,17 +0,0 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>netcoreapp2.0</TargetFramework>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="15.5.0-preview-20171012-09" />
<PackageReference Include="MSTest.TestAdapter" Version="1.2.0" />
<PackageReference Include="MSTest.TestFramework" Version="1.2.0" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\src\Sia.Shared\Sia.Shared.csproj" />
</ItemGroup>
</Project>

Просмотреть файл

@ -1,65 +0,0 @@
using Microsoft.VisualStudio.TestTools.UnitTesting;
using Sia.Shared.Validation;
using System;
using System.Collections.Generic;
using System.Text;
namespace Sia.Shared.Tests.Validation
{
[TestClass]
public class ThrowIfTests
{
[TestMethod]
public void Null_StaticMethod_WhenObjectIsNotNull_ReturnsObject()
{
var input = new Object();
var result = ThrowIf.Null(input, nameof(input));
Assert.AreSame(input, result);
}
[TestMethod]
[ExpectedException(typeof(ArgumentNullException))]
public void Null_StaticMethod_WhenObjectIsNull_ThrowsArgumentNullException()
{
object input = null;
var result = ThrowIf.Null(input, nameof(input));
//expect exception
}
[TestMethod]
[ExpectedException(typeof(ArgumentException))]
public void NullOrWhiteSpace_StaticMethod_WhenInputIsNull_ThrowsArgumentException()
{
string input = null;
var result = ThrowIf.NullOrWhiteSpace(input, nameof(input));
//Expect exception
}
[TestMethod]
[ExpectedException(typeof(ArgumentException))]
public void NullOrWhiteSpace_StaticMethod_WhenInputIsOnlyWhitespace_ThrowsArgumentException()
{
string input = " ";
var result = ThrowIf.NullOrWhiteSpace(input, nameof(input));
//Expect exception
}
[TestMethod]
public void NullOrWhiteSpace_StaticMethod_WhenInputStringWithAnyNonWhitespace_ReturnsString()
{
string input = " . ";
var result = ThrowIf.NullOrWhiteSpace(input, nameof(input));
Assert.AreSame(input, result);
}
}
}

Просмотреть файл

@ -18,10 +18,9 @@
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\..\domain\Domain\Sia.Domain\Sia.Domain.csproj" />
<ProjectReference Include="..\..\domain\Domain\Sia.Shared\Sia.Shared.csproj" />
<ProjectReference Include="..\Sia.Data.Incident\Sia.Data.Incidents.csproj" />
<ProjectReference Include="..\Sia.Domain.ApiModels\Sia.Domain.ApiModels.csproj" />
<ProjectReference Include="..\Sia.Domain\Sia.Domain.csproj" />
<ProjectReference Include="..\Sia.Shared\Sia.Shared.csproj" />
</ItemGroup>
</Project>

Просмотреть файл

@ -22,7 +22,7 @@
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\Sia.Shared\Sia.Shared.csproj" />
<ProjectReference Include="..\..\domain\Domain\Sia.Shared\Sia.Shared.csproj" />
</ItemGroup>
</Project>

Просмотреть файл

@ -30,10 +30,11 @@
<DotNetCliToolReference Include="Microsoft.VisualStudio.Web.CodeGeneration.Tools" Version="1.0.0" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\..\domain\Domain\Sia.Domain.ApiModels\Sia.Domain.ApiModels.csproj" />
<ProjectReference Include="..\..\domain\Domain\Sia.Domain\Sia.Domain.csproj" />
<ProjectReference Include="..\..\domain\Domain\Sia.Shared\Sia.Shared.csproj" />
<ProjectReference Include="..\Sia.Connectors.Tickets\Sia.Connectors.Tickets.csproj" />
<ProjectReference Include="..\Sia.Data.Incident\Sia.Data.Incidents.csproj" />
<ProjectReference Include="..\Sia.Domain.ApiModels\Sia.Domain.ApiModels.csproj" />
<ProjectReference Include="..\Sia.Domain\Sia.Domain.csproj" />
</ItemGroup>
</Project>

Просмотреть файл

@ -1,68 +0,0 @@
using Microsoft.Azure.KeyVault;
using Microsoft.Azure.KeyVault.Models;
using Microsoft.Extensions.Configuration;
using Microsoft.IdentityModel.Clients.ActiveDirectory;
using Sia.Shared.Validation;
using System;
using System.Security.Cryptography.X509Certificates;
using System.Threading.Tasks;
namespace Sia.Shared.Authentication
{
public class AzureSecretVault
{
private readonly KeyVaultConfiguration _config;
private const string _secretsEndpoint = "/secrets/";
private const string _keysEndpoint = "/keys/";
private const string _certificatesEndpoint = "/certificates/";
public AzureSecretVault(KeyVaultConfiguration configuration)
{
_config = ThrowIf.Null(configuration, nameof(configuration));
}
public async Task<string> Get(string secretName)
{
try
{
var secret = await GetKeyVaultClient().GetSecretAsync(_config.Vault + _secretsEndpoint + secretName).ConfigureAwait(false);
return secret.Value;
}
catch (KeyVaultErrorException ex)
{
return string.Empty;
}
}
public async Task<X509Certificate2> GetCertificate(string certificateName)
{
try
{
var cert = await GetKeyVaultClient()
.GetCertificateAsync(_config.Vault, certificateName)
.ConfigureAwait(false);
return new X509Certificate2(cert.Cer);
}
catch (KeyVaultErrorException ex)
{
return null;
}
}
private async Task<string> GetToken(string authority, string resource, string scope)
{
var authContext = new AuthenticationContext(authority);
ClientCredential clientCred = new ClientCredential(_config.ClientId, _config.ClientSecret);
AuthenticationResult result = await authContext.AcquireTokenAsync(resource, clientCred);
if (result == null)
throw new InvalidOperationException("Failed to obtain the JWT token");
return result.AccessToken;
}
private KeyVaultClient GetKeyVaultClient() => new KeyVaultClient(new KeyVaultClient.AuthenticationCallback(GetToken));
}
}

Просмотреть файл

@ -1,20 +0,0 @@
using System.Net.Http;
using System.Security.Cryptography.X509Certificates;
namespace Sia.Shared.Authentication
{
public abstract class CertificateRetriever : IHttpClientFactory
{
protected X509Certificate2 _cert;
public abstract X509Certificate2 Certificate { get; }
public virtual HttpClient GetClient()
{
var handler = new HttpClientHandler();
handler.ClientCertificates.Add(Certificate);
return new HttpClient(handler);
}
}
}

Просмотреть файл

@ -1,9 +0,0 @@
using System.Net.Http;
namespace Sia.Shared.Authentication
{
public interface IHttpClientFactory
{
HttpClient GetClient();
}
}

Просмотреть файл

@ -1,40 +0,0 @@
using Sia.Shared.Validation;
using System;
using System.Collections.Generic;
using System.Security.Cryptography.X509Certificates;
using System.Text;
using System.Threading.Tasks;
namespace Sia.Shared.Authentication
{
public class KeyVaultCertificateRetriever
: CertificateRetriever
{
private X509Certificate2 _certificate;
private readonly string _certName;
private readonly AzureSecretVault _certVault;
public KeyVaultCertificateRetriever(AzureSecretVault certificateVault, string certificateName)
{
_certName = ThrowIf.NullOrWhiteSpace(certificateName, nameof(certificateName));
_certVault = ThrowIf.Null(certificateVault, nameof(certificateVault));
}
private X509Certificate2 StoreCertificate(AzureSecretVault certificateVault, string certificateName)
{
var certTask = certificateVault.GetCertificate(certificateName);
Task.WaitAll(new Task[] { certTask });
if (certTask.IsCompleted)
{
_certificate = certTask.Result;
}
return _certificate;
}
public override X509Certificate2 Certificate =>
_certificate is null
? StoreCertificate(_certVault, _certName)
: _certificate;
}
}
;

Просмотреть файл

@ -1,24 +0,0 @@
using Microsoft.Extensions.Configuration;
using Sia.Shared.Validation;
using System;
using System.Collections.Generic;
using System.Text;
namespace Sia.Shared.Authentication
{
public class KeyVaultConfiguration
{
public KeyVaultConfiguration(string clientId, string clientSecret, string vault)
{
ClientId = ThrowIf.NullOrWhiteSpace(clientId, nameof(clientId));
ClientSecret = ThrowIf.NullOrWhiteSpace(clientSecret, nameof(clientSecret));
Vault = String.Format(secretUriBase, ThrowIf.NullOrWhiteSpace(vault, nameof(vault)));
}
private const string secretUriBase = "https://{0}.vault.azure.net";
public readonly string Vault;
public readonly string ClientId;
public readonly string ClientSecret;
}
}

Просмотреть файл

@ -1,52 +0,0 @@
using System.Collections.Generic;
using System.Security.Cryptography.X509Certificates;
namespace Sia.Shared.Authentication
{
public class LocalCertificateRetriever
: CertificateRetriever
{
private readonly string _certThumbprint;
private List<StoreLocation> _storeLocations
=> new List<StoreLocation>
{
StoreLocation.CurrentUser,
StoreLocation.LocalMachine
};
public LocalCertificateRetriever(string certThumbprint)
{
_certThumbprint = certThumbprint;
}
public override X509Certificate2 Certificate
{
get
{
if (_cert == null)
{
_cert = GetCertFromStore();
}
return _cert;
}
}
private X509Certificate2 GetCertFromStore()
{
foreach (var location in _storeLocations)
{
using (X509Store store = new X509Store("My", location))
{
store.Open(OpenFlags.ReadOnly | OpenFlags.OpenExistingOnly);
X509Certificate2Collection certificates = store.Certificates.Find(X509FindType.FindByThumbprint, _certThumbprint, true);
if (certificates.Count > 0)
return certificates[0];
}
}
throw new KeyNotFoundException("Could not find valid certificate");
}
}
}

Просмотреть файл

@ -1,17 +0,0 @@
using System.Net.Http;
namespace Sia.Shared.Authentication
{
public class UnauthenticatedClientFactory : IHttpClientFactory
{
HttpClient _httpClient;
public HttpClient GetClient()
{
if (_httpClient == null)
{
_httpClient = new HttpClient();
}
return _httpClient;
}
}
}

Просмотреть файл

@ -1,52 +0,0 @@
using System;
using System.Collections.Generic;
using System.Linq.Expressions;
using System.Text;
namespace Sia.Shared.Data
{
public interface IAssociation<TLeft, TRight>
{
void Associate(TLeft left, TRight right);
KeyValuePair<TLeft, TRight> AssociatesBetween();
}
public abstract class Association<TLeft, TRight>
: IAssociation<TLeft, TRight>
where TLeft : IEntity
where TRight : IEntity
{
protected internal abstract long _leftId { get; set; }
protected internal abstract long _rightId { get; set; }
protected internal abstract TLeft _left { get; set; }
protected internal abstract TRight _right { get; set; }
public void Associate(TLeft left, TRight right)
{
_left = left;
_right = right;
_leftId = left.Id;
_rightId = right.Id;
}
public KeyValuePair<TLeft, TRight> AssociatesBetween()
=> new KeyValuePair<TLeft, TRight>(_left, _right);
}
public abstract class BidrectionalAssociation<TLeft, TRight>
: Association<TLeft, TRight>,
IAssociation<TRight, TLeft>
where TLeft : IEntity
where TRight : IEntity
{
protected BidrectionalAssociation()
{
}
void IAssociation<TRight, TLeft>.Associate(TRight left, TLeft right)
=> Associate(right, left);
KeyValuePair<TRight, TLeft> IAssociation<TRight, TLeft>.AssociatesBetween()
=> new KeyValuePair<TRight, TLeft>(_right, _left);
}
}

Просмотреть файл

@ -1,11 +0,0 @@
using System;
using System.Collections.Generic;
using System.Text;
namespace Sia.Shared.Data
{
public interface IEntity
{
long Id { get; }
}
}

Просмотреть файл

@ -1,75 +0,0 @@
using System;
using System.Collections;
using System.Collections.Generic;
using System.Linq;
namespace Sia.Shared.Data
{
public class ManyToManyCollection<TItem, TAssociation, TAssociated> : ICollection<TAssociated>
where TAssociation : IAssociation<TItem, TAssociated>, new()
{
private TItem _parent;
private ICollection<TAssociation> _associations;
private IEnumerable<TAssociated> _associated => _associations.Select(assoc => assoc.AssociatesBetween().Value);
public ManyToManyCollection(TItem parent, ICollection<TAssociation> associations)
{
_parent = parent;
_associations = associations;
}
public int Count => _associations.Count;
public bool IsReadOnly => false;
public void Add(TAssociated item)
{
var associationToAdd = new TAssociation();
associationToAdd.Associate(_parent, item);
_associations.Add(associationToAdd);
}
public void Clear()
{
_associations.Clear();
}
public bool Contains(TAssociated item)
{
return _associated.Contains(item);
}
public void CopyTo(TAssociated[] array, int arrayIndex)
{
if (array == null) throw new ArgumentNullException(nameof(arrayIndex));
if (arrayIndex < 0) throw new ArgumentOutOfRangeException(nameof(arrayIndex), arrayIndex, "Array Index cannot be less than 0!");
if (array.GetLength(0) - arrayIndex > Count) throw new ArgumentException("The number of elements in the source System.Collections.Generic.ICollection`1 is greater than the available space from arrayIndex to the end of the destination array.", nameof(arrayIndex));
_associated.ToList().CopyTo(array, arrayIndex);
}
public IEnumerator<TAssociated> GetEnumerator()
{
return _associated.GetEnumerator();
}
public bool Remove(TAssociated item)
{
var relevantAssociations = _associations.Where(assoc => assoc.AssociatesBetween().Value.Equals(item));
bool success = true;
foreach (var association in relevantAssociations)
{
if (!_associations.Remove(association))
{
success = false;
}
}
return success;
}
IEnumerator IEnumerable.GetEnumerator()
{
return _associated.GetEnumerator();
}
}
}

Просмотреть файл

@ -1,31 +0,0 @@
using Sia.Shared.Data;
using System;
using System.Collections.Generic;
using System.Linq.Expressions;
using System.Text;
namespace Microsoft.EntityFrameworkCore
{
public static class ModelBuilderExtensions
{
public static void WithManyToManyAssociation<TLeft, TRight, TAssociation>(this ModelBuilder builder
, Expression<Func<TLeft, IEnumerable<TAssociation>>> associationsFromLeft
, Expression<Func<TRight, IEnumerable<TAssociation>>> associationsFromRight
)
where TAssociation : BidrectionalAssociation<TLeft, TRight>
where TLeft : class, IEntity
where TRight : class, IEntity
{
builder.Entity<TAssociation>()
.HasOne(assoc => assoc._left)
.WithMany(associationsFromLeft)
.HasForeignKey(assoc => assoc._leftId);
builder.Entity<TAssociation>()
.HasOne(assoc => assoc._right)
.WithMany(associationsFromRight)
.HasForeignKey(assoc => assoc._rightId);
builder.Entity<TAssociation>()
.HasKey(assoc => new { assoc._leftId, assoc._rightId });
}
}
}

Просмотреть файл

@ -1,39 +0,0 @@
using AutoMapper;
using Newtonsoft.Json;
using System;
using System.Collections.Generic;
using System.Dynamic;
using System.Linq;
using System.Threading.Tasks;
namespace Sia.Shared.Data
{
public interface IJsonDataString
{
string Data { get; set; }
}
public interface IJsonDataObject
{
object Data { get; set; }
}
public class ResolveJsonToString<TSource, TDestination>
: IValueResolver<TSource, TDestination, string>
where TSource: IJsonDataObject
where TDestination: IJsonDataString
{
public string Resolve(TSource source, TDestination destination, string destMember, ResolutionContext context)
=> source?.Data is null ? null : JsonConvert.SerializeObject(source.Data);
}
public class ResolveStringToJson<TSource, TDestination>
: IValueResolver<TSource, TDestination, object>
where TSource : IJsonDataString
where TDestination : IJsonDataObject
{
public object Resolve(TSource source, TDestination destination, object destMember, ResolutionContext context)
=> source?.Data is null ? null : JsonConvert.DeserializeObject(source.Data);
}
}

Просмотреть файл

@ -1,11 +0,0 @@
namespace Sia.Shared.Exceptions
{
public class BadRequestException : BaseException
{
public BadRequestException(string message) : base(message)
{
}
public override int StatusCode => 400;
}
}

Просмотреть файл

@ -1,13 +0,0 @@
using System;
namespace Sia.Shared.Exceptions
{
public abstract class BaseException : Exception
{
public BaseException(string message) : base(message)
{
}
public abstract int StatusCode { get; }
}
}

Просмотреть файл

@ -1,11 +0,0 @@
namespace Sia.Shared.Exceptions
{
public class ConflictException : BaseException
{
public ConflictException(string message) : base(message)
{
}
public override int StatusCode => 409;
}
}

Просмотреть файл

@ -1,32 +0,0 @@
using Sia.Shared.Transactions;
using System;
namespace Sia.Shared.Exceptions
{
public static class ConvertStatusToException
{
public static void ThrowExceptionOnUnsuccessfulStatus<T>(this IResponse<T> response)
{
if (response.IsSuccessStatusCode)
{
return;
}
var message = response.Content;
switch (response.StatusCode)
{
case System.Net.HttpStatusCode.BadRequest:
throw new BadRequestException(message);
case System.Net.HttpStatusCode.Conflict:
throw new ConflictException(message);
case System.Net.HttpStatusCode.Forbidden:
throw new UnauthorizedException(message);
case System.Net.HttpStatusCode.NotFound:
throw new NotFoundException(message);
case System.Net.HttpStatusCode.Unauthorized:
throw new UnauthorizedException(message);
default:
throw new Exception(message);
}
}
}
}

Просмотреть файл

@ -1,11 +0,0 @@
namespace Sia.Shared.Exceptions
{
public class NotFoundException : BaseException
{
public NotFoundException(string message) : base(message)
{
}
public override int StatusCode => 404;
}
}

Просмотреть файл

@ -1,11 +0,0 @@
namespace Sia.Shared.Exceptions
{
public class UnauthorizedException : BaseException
{
public UnauthorizedException(string message) : base(message)
{
}
public override int StatusCode => 403;
}
}

Просмотреть файл

@ -1,25 +0,0 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>netstandard2.0</TargetFramework>
<Version>1.1.0-alpha</Version>
<PackageId>Microsoft.Sia.Shared</PackageId>
<Authors>pdimit, magpint, jache, chtownes</Authors>
<Company>Microsoft</Company>
<Product>SRE Incident Assistant</Product>
<Description>SIA utility and shared code</Description>
<PackageReleaseNotes>Initial open source release, intended for prototyping.</PackageReleaseNotes>
<Copyright>Copyright 2017</Copyright>
<GeneratePackageOnBuild>true</GeneratePackageOnBuild>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="AutoMapper" Version="6.1.1" />
<PackageReference Include="Microsoft.Azure.KeyVault" Version="2.3.2" />
<PackageReference Include="Microsoft.EntityFrameworkCore" Version="2.0.0" />
<PackageReference Include="Microsoft.Extensions.Configuration" Version="2.0.0" />
<PackageReference Include="Microsoft.IdentityModel.Clients.ActiveDirectory" Version="3.16.1" />
<PackageReference Include="Newtonsoft.Json" Version="10.0.3" />
</ItemGroup>
</Project>

Просмотреть файл

@ -1,12 +0,0 @@
using System.Net;
namespace Sia.Shared.Transactions
{
public interface IResponse<T>
{
HttpStatusCode StatusCode { get; }
bool IsSuccessStatusCode { get; }
string Content { get; }
T Value { get; }
}
}

Просмотреть файл

@ -1,31 +0,0 @@
using Newtonsoft.Json;
using System.Net;
using System.Net.Http;
using System.Threading.Tasks;
namespace Sia.Shared.Transactions
{
public class Response<T> : IResponse<T>
{
public HttpStatusCode StatusCode { get; private set; }
public bool IsSuccessStatusCode { get; private set; }
public string Content { get; private set; }
public T Value { get; private set; }
public static async Task<Response<T>> Create(HttpResponseMessage message)
{
var response = new Response<T>();
response.IsSuccessStatusCode = message.IsSuccessStatusCode;
response.StatusCode = message.StatusCode;
var content = await message.Content.ReadAsStringAsync();
if (message.IsSuccessStatusCode)
{
response.Value = JsonConvert.DeserializeObject<T>(content);
}
else
{
response.Content = content;
}
return response;
}
}
}

Просмотреть файл

@ -1,18 +0,0 @@
using System;
namespace Sia.Shared.Validation
{
public static class ThrowIf
{
public static TParam Null<TParam>(TParam o, string paramName)
where TParam : class
=> o ?? throw new ArgumentNullException(paramName);
public static string NullOrWhiteSpace(string input, string paramName)
{
if (string.IsNullOrWhiteSpace(input)) throw new ArgumentException("Value cannot be null or white space", paramName);
return input;
}
}
}

Просмотреть файл

@ -13,7 +13,9 @@
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\..\src\Sia.Domain\Sia.Domain.csproj" />
<ProjectReference Include="..\..\domain\Domain\Sia.Domain.ApiModels\Sia.Domain.ApiModels.csproj" />
<ProjectReference Include="..\..\domain\Domain\Sia.Domain\Sia.Domain.csproj" />
<ProjectReference Include="..\..\domain\Domain\Sia.Shared\Sia.Shared.csproj" />
<ProjectReference Include="..\..\src\Sia.Gateway\Sia.Gateway.csproj" />
</ItemGroup>