diff --git a/src/LegacyArtifacts/LegacyArtifacts.csproj b/src/LegacyArtifacts/LegacyArtifacts.csproj index c43b9ad2c1..7632abb5cd 100644 --- a/src/LegacyArtifacts/LegacyArtifacts.csproj +++ b/src/LegacyArtifacts/LegacyArtifacts.csproj @@ -11,4 +11,5 @@ --> + diff --git a/src/Particular.PlatformSample.ServiceControl/buildProps/build/Particular.PlatformSample.ServiceControl.props b/src/Particular.PlatformSample.ServiceControl/buildProps/build/Particular.PlatformSample.ServiceControl.props index ce70b7e6b5..7dcd072371 100644 --- a/src/Particular.PlatformSample.ServiceControl/buildProps/build/Particular.PlatformSample.ServiceControl.props +++ b/src/Particular.PlatformSample.ServiceControl/buildProps/build/Particular.PlatformSample.ServiceControl.props @@ -5,15 +5,15 @@ - + - + - + diff --git a/src/Persisters.Audit.Includes.props b/src/ProjectReferences.Persisters.Audit.props similarity index 99% rename from src/Persisters.Audit.Includes.props rename to src/ProjectReferences.Persisters.Audit.props index 37dcec6c3f..cb409ec769 100644 --- a/src/Persisters.Audit.Includes.props +++ b/src/ProjectReferences.Persisters.Audit.props @@ -1,6 +1,8 @@ + + \ No newline at end of file diff --git a/src/Persisters.Primary.Includes.props b/src/ProjectReferences.Persisters.Primary.props similarity index 99% rename from src/Persisters.Primary.Includes.props rename to src/ProjectReferences.Persisters.Primary.props index 1cdabb3928..b1eb798370 100644 --- a/src/Persisters.Primary.Includes.props +++ b/src/ProjectReferences.Persisters.Primary.props @@ -1,5 +1,7 @@ + + \ No newline at end of file diff --git a/src/ProjectReferences.Transports.props b/src/ProjectReferences.Transports.props new file mode 100644 index 0000000000..ebf9c3d4b6 --- /dev/null +++ b/src/ProjectReferences.Transports.props @@ -0,0 +1,14 @@ + + + + + + + + + + + + + + \ No newline at end of file diff --git a/src/ServiceControl.AcceptanceTests.RavenDB5/ServiceControl.AcceptanceTests.RavenDB5.csproj b/src/ServiceControl.AcceptanceTests.RavenDB5/ServiceControl.AcceptanceTests.RavenDB5.csproj index 56ca657cf8..08a3855215 100644 --- a/src/ServiceControl.AcceptanceTests.RavenDB5/ServiceControl.AcceptanceTests.RavenDB5.csproj +++ b/src/ServiceControl.AcceptanceTests.RavenDB5/ServiceControl.AcceptanceTests.RavenDB5.csproj @@ -3,7 +3,7 @@ net472 ServiceControl.runsettings - 8 + 8.0 @@ -25,7 +25,7 @@ - + - + diff --git a/src/ServiceControl.AcceptanceTests.RavenDB5/ServiceControl.runsettings b/src/ServiceControl.AcceptanceTests.RavenDB5/ServiceControl.runsettings index ea2e767f89..624cd65002 100644 --- a/src/ServiceControl.AcceptanceTests.RavenDB5/ServiceControl.runsettings +++ b/src/ServiceControl.AcceptanceTests.RavenDB5/ServiceControl.runsettings @@ -1,7 +1,7 @@  - - - x64 - + + + x64 + diff --git a/src/ServiceControl.Audit.AcceptanceTests.RavenDB5/ServiceControl.Audit.AcceptanceTests.RavenDB5.csproj b/src/ServiceControl.Audit.AcceptanceTests.RavenDB5/ServiceControl.Audit.AcceptanceTests.RavenDB5.csproj index e865288fd6..8d6fafce95 100644 --- a/src/ServiceControl.Audit.AcceptanceTests.RavenDB5/ServiceControl.Audit.AcceptanceTests.RavenDB5.csproj +++ b/src/ServiceControl.Audit.AcceptanceTests.RavenDB5/ServiceControl.Audit.AcceptanceTests.RavenDB5.csproj @@ -3,7 +3,7 @@ net472 ServiceControl.runsettings - 8 + 8.0 diff --git a/src/ServiceControl.Audit.AcceptanceTests.RavenDB5/ServiceControl.runsettings b/src/ServiceControl.Audit.AcceptanceTests.RavenDB5/ServiceControl.runsettings index ea2e767f89..624cd65002 100644 --- a/src/ServiceControl.Audit.AcceptanceTests.RavenDB5/ServiceControl.runsettings +++ b/src/ServiceControl.Audit.AcceptanceTests.RavenDB5/ServiceControl.runsettings @@ -1,7 +1,7 @@  - - - x64 - + + + x64 + diff --git a/src/ServiceControl.Audit.AcceptanceTests/ServiceControl.Audit.AcceptanceTests.csproj b/src/ServiceControl.Audit.AcceptanceTests/ServiceControl.Audit.AcceptanceTests.csproj index 1d668f3f6c..61a8c6b82f 100644 --- a/src/ServiceControl.Audit.AcceptanceTests/ServiceControl.Audit.AcceptanceTests.csproj +++ b/src/ServiceControl.Audit.AcceptanceTests/ServiceControl.Audit.AcceptanceTests.csproj @@ -3,13 +3,13 @@ net472 ServiceControl.runsettings - 8 + 8.0 - + diff --git a/src/ServiceControl.Audit.AcceptanceTests/ServiceControl.runsettings b/src/ServiceControl.Audit.AcceptanceTests/ServiceControl.runsettings index ea2e767f89..624cd65002 100644 --- a/src/ServiceControl.Audit.AcceptanceTests/ServiceControl.runsettings +++ b/src/ServiceControl.Audit.AcceptanceTests/ServiceControl.runsettings @@ -1,7 +1,7 @@  - - - x64 - + + + x64 + diff --git a/src/ServiceControl.Audit.Persistence.RavenDb5/EmbeddedDatabase.cs b/src/ServiceControl.Audit.Persistence.RavenDb5/EmbeddedDatabase.cs index a39c7746af..a2cebf9eea 100644 --- a/src/ServiceControl.Audit.Persistence.RavenDb5/EmbeddedDatabase.cs +++ b/src/ServiceControl.Audit.Persistence.RavenDb5/EmbeddedDatabase.cs @@ -5,6 +5,7 @@ using System.Diagnostics; using System.Globalization; using System.IO; + using System.Reflection; using System.Threading; using System.Threading.Tasks; using ByteSizeLib; @@ -25,30 +26,22 @@ public EmbeddedDatabase(DatabaseConfiguration configuration) static (string LicenseFileName, string ServerDirectory) GetRavenLicenseFileNameAndServerDirectory() { + var assembly = Assembly.GetExecutingAssembly(); + var assemblyDirectory = Path.GetDirectoryName(assembly.Location); + var licenseFileName = "RavenLicense.json"; - var localRavenLicense = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, licenseFileName); - if (File.Exists(localRavenLicense)) + var ravenLicense = Path.Combine(assemblyDirectory, licenseFileName); + var serverDirectory = Path.Combine(assemblyDirectory, "RavenDBServer"); + + if (File.Exists(ravenLicense)) { - return (localRavenLicense, null); + return (ravenLicense, serverDirectory); } - - const string Persisters = "Persisters"; - const string RavenDB5 = "RavenDB5"; - - var persisterDirectory = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, Persisters, RavenDB5); - - localRavenLicense = Path.Combine(persisterDirectory, licenseFileName); - if (!File.Exists(localRavenLicense)) + else { - throw new Exception($"RavenDB license not found. Make sure the RavenDB license file, '{licenseFileName}', " + - $"is stored in the '{AppDomain.CurrentDomain.BaseDirectory}' folder or in the '{Persisters}/{RavenDB5}' subfolder."); + var assemblyName = Path.GetFileName(assembly.Location); + throw new Exception($"RavenDB license not found. Make sure the RavenDB license file '{licenseFileName}' is stored in the same directory as {assemblyName}."); } - - // By default RavenDB 5 searches its binaries in the RavenDBServer right below the BaseDirectory. - // If we're loading from Persisters/RavenDB5 we also have to signal RavenDB where are binaries - var serverDirectory = Path.Combine(persisterDirectory, "RavenDBServer"); - - return (localRavenLicense, serverDirectory); } public static EmbeddedDatabase Start(DatabaseConfiguration databaseConfiguration) diff --git a/src/ServiceControl.Audit.Persistence.Tests.RavenDb5/ServiceControl.Audit.Persistence.Tests.RavenDb5.csproj b/src/ServiceControl.Audit.Persistence.Tests.RavenDb5/ServiceControl.Audit.Persistence.Tests.RavenDb5.csproj index bf93387da9..ad26e94b62 100644 --- a/src/ServiceControl.Audit.Persistence.Tests.RavenDb5/ServiceControl.Audit.Persistence.Tests.RavenDb5.csproj +++ b/src/ServiceControl.Audit.Persistence.Tests.RavenDb5/ServiceControl.Audit.Persistence.Tests.RavenDb5.csproj @@ -21,7 +21,7 @@ - + diff --git a/src/ServiceControl.Audit.Persistence.Tests/PersistenceManifestLibraryTests.cs b/src/ServiceControl.Audit.Persistence.Tests/PersistenceManifestLibraryTests.cs index aacb1baae7..4df40b6583 100644 --- a/src/ServiceControl.Audit.Persistence.Tests/PersistenceManifestLibraryTests.cs +++ b/src/ServiceControl.Audit.Persistence.Tests/PersistenceManifestLibraryTests.cs @@ -11,7 +11,6 @@ public class PersistenceManifestLibraryTests { const string persistenceName = "RavenDB5"; const string persistenceType = "ServiceControl.Audit.Persistence.RavenDb.RavenDbPersistenceConfiguration, ServiceControl.Audit.Persistence.RavenDb5"; - const string persistenceFolder = "RavenDB5"; [Test] public void Should_find_persistence_type_by_name() @@ -22,7 +21,7 @@ public void Should_find_persistence_type_by_name() } [Test] - public void Should_find_tpersistence_type_by_type() + public void Should_find_persistence_type_by_type() { var _persistenceType = PersistenceManifestLibrary.Find(persistenceType); @@ -43,15 +42,15 @@ public void Should_find_persistence_type_folder_by_name() { var _persistenceTypeFolder = PersistenceManifestLibrary.GetPersistenceFolder(persistenceName); - Assert.AreEqual(persistenceFolder, _persistenceTypeFolder); + Assert.IsNotNull(_persistenceTypeFolder); } [Test] - public void Should_find_tpersistence_type_folder_by_type() + public void Should_find_persistence_type_folder_by_type() { var _persistenceTypeFolder = PersistenceManifestLibrary.GetPersistenceFolder(persistenceType); - Assert.AreEqual(persistenceFolder, _persistenceTypeFolder); + Assert.IsNotNull(_persistenceTypeFolder); } [Test] @@ -66,38 +65,24 @@ public void Should_return_null_for_not_found_persistence_type() [Test] public void All_types_defined_in_manifest_files_exist_in_specified_assembly() { - var assemblyLocation = Assembly.GetExecutingAssembly().Location; - var appDirectory = Path.GetDirectoryName(assemblyLocation); - PersistenceManifestLibrary.GetPersistenceFolder("dummy"); //to initialise the collection + var count = 0; - var supportedManifests = PersistenceManifestLibrary.PersistenceManifests.Where(p => p.IsSupported).ToList(); - Assert.True(supportedManifests.Count >= 1); - - supportedManifests.ForEach(p => + foreach (var definition in PersistenceManifestLibrary.PersistenceManifests) { - var persistenceFolder = PersistenceManifestLibrary.GetPersistenceFolder(p.Name); - var subFolderPath = Path.Combine(appDirectory, "Persisters", persistenceFolder); - var assemblyName = p.TypeName.Split(',')[1].Trim(); - var assembly = TryLoadTypeFromSubdirectory(subFolderPath, assemblyName); + count++; + var persistenceFolder = PersistenceManifestLibrary.GetPersistenceFolder(definition.Name); + var assemblyName = definition.TypeName.Split(',')[1].Trim(); + var assemblyFile = Path.Combine(persistenceFolder, assemblyName + ".dll"); + var assembly = Assembly.LoadFrom(assemblyFile); Assert.IsNotNull(assembly, $"Could not load assembly {assemblyName}"); //NOTE not checking namespace here as it doesn't match for RavenDb5 - //Assert.IsTrue(assembly.GetTypes().Any(a => a.FullName == p.TypeName.Split(',').FirstOrDefault() && a.Namespace == assemblyName), $"Persistence type {p.TypeName} not found in assembly {assemblyName}"); - Assert.IsTrue(assembly.GetTypes().Any(a => a.FullName == p.TypeName.Split(',').FirstOrDefault()), $"Persistence type {p.TypeName} not found in assembly {assemblyName}"); - }); - } - - Assembly TryLoadTypeFromSubdirectory(string subFolderPath, string requestingName) - { - //look into any subdirectory - var file = Directory.EnumerateFiles(subFolderPath, requestingName + ".dll", SearchOption.AllDirectories).SingleOrDefault(); - if (file != null) - { - return Assembly.LoadFrom(file); + //Assert.IsTrue(assembly.GetTypes().Any(a => a.FullName == definition.TypeName.Split(',').FirstOrDefault() && a.Namespace == assemblyName), $"Persistence type {definition.TypeName} not found in assembly {assemblyName}"); + Assert.IsTrue(assembly.GetTypes().Any(a => a.FullName == definition.TypeName.Split(',').FirstOrDefault()), $"Persistence type {definition.TypeName} not found in assembly {assemblyName}"); } - return null; + Assert.NotZero(count, "No persistence manifests found."); } } } \ No newline at end of file diff --git a/src/ServiceControl.Audit.Persistence.Tests/ServiceControl.Audit.Persistence.Tests.csproj b/src/ServiceControl.Audit.Persistence.Tests/ServiceControl.Audit.Persistence.Tests.csproj index f564d7aa23..381edcf9e0 100644 --- a/src/ServiceControl.Audit.Persistence.Tests/ServiceControl.Audit.Persistence.Tests.csproj +++ b/src/ServiceControl.Audit.Persistence.Tests/ServiceControl.Audit.Persistence.Tests.csproj @@ -3,21 +3,9 @@ net472 - - - - - - - - - - - - - + diff --git a/src/ServiceControl.Audit.Persistence/DevelopmentPersistenceLocations.cs b/src/ServiceControl.Audit.Persistence/DevelopmentPersistenceLocations.cs new file mode 100644 index 0000000000..a193528577 --- /dev/null +++ b/src/ServiceControl.Audit.Persistence/DevelopmentPersistenceLocations.cs @@ -0,0 +1,37 @@ +namespace ServiceControl.Persistence +{ + using System.Collections.Generic; + using System.IO; + + static class DevelopmentPersistenceLocations + { + public static List ManifestFiles { get; } = new List(); + + static DevelopmentPersistenceLocations() + { + var assembly = typeof(DevelopmentPersistenceLocations).Assembly.Location; + var assemblyDirectory = Path.GetDirectoryName(assembly); + + // Becomes null if it navigates past the root of a drive + var srcFolder = Path.GetDirectoryName(Path.GetDirectoryName(Path.GetDirectoryName(Path.GetDirectoryName(assemblyDirectory)))); + + if (!string.IsNullOrWhiteSpace(srcFolder) && srcFolder.EndsWith("src")) + { + ManifestFiles.Add(BuildManifestPath(srcFolder, "ServiceControl.Audit.Persistence.InMemory")); + ManifestFiles.Add(BuildManifestPath(srcFolder, "ServiceControl.Audit.Persistence.RavenDb5")); + } + } + + static string BuildManifestPath(string srcFolder, string projectName) => Path.Combine(srcFolder, projectName, "bin", configuration, framework, "persistence.manifest"); + +#if DEBUG + const string configuration = "Debug"; +#else + const string configuration = "Release"; +#endif + +#if NET472 + const string framework = "net472"; +#endif + } +} diff --git a/src/ServiceControl.Audit.Persistence/PersistenceManifest.cs b/src/ServiceControl.Audit.Persistence/PersistenceManifest.cs index 0936dcd0df..e476e7eef0 100644 --- a/src/ServiceControl.Audit.Persistence/PersistenceManifest.cs +++ b/src/ServiceControl.Audit.Persistence/PersistenceManifest.cs @@ -6,14 +6,22 @@ using System.Linq; using System.Text.Json; using NServiceBus.Logging; + using ServiceControl.Persistence; public class PersistenceManifest { public string Version { get; set; } + + public string Location { get; set; } + public string Name { get; set; } + public string DisplayName { get; set; } + public string Description { get; set; } + public string TypeName { get; set; } + public bool IsSupported { get; set; } = true; internal bool IsMatch(string persistenceType) => @@ -23,34 +31,43 @@ internal bool IsMatch(string persistenceType) => public static class PersistenceManifestLibrary { - public static List PersistenceManifests { get; set; } + public static List PersistenceManifests { get; } = new List(); - static bool initialized; - static void Initialize() + static PersistenceManifestLibrary() { - if (PersistenceManifests == null) - { - PersistenceManifests = new List(); - } + var assemblyDirectory = GetAssemblyDirectory(); - if (!initialized) + try { - initialized = true; - var assemblyLocation = GetAssemblyDirectory(); - try + foreach (var manifestFile in Directory.EnumerateFiles(assemblyDirectory, "persistence.manifest", SearchOption.AllDirectories)) { - PersistenceManifests.AddRange( - Directory.EnumerateFiles(assemblyLocation, "persistence.manifest", SearchOption.AllDirectories) - .Select(manifest => JsonSerializer.Deserialize(File.ReadAllText(manifest))) - ); + var manifest = JsonSerializer.Deserialize(File.ReadAllText(manifestFile)); + manifest.Location = Path.GetDirectoryName(manifestFile); - PersistenceManifests.ForEach(m => logger.Info($"Found persistence manifest for {m.DisplayName}")); + PersistenceManifests.Add(manifest); } - catch (Exception ex) + } + catch (Exception ex) + { + logger.Warn($"Failed to load persistence manifests from {assemblyDirectory}", ex); + } + + try + { + foreach (var manifestFile in DevelopmentPersistenceLocations.ManifestFiles) { - logger.Warn($"Failed to load persistence manifests from {assemblyLocation}", ex); + var manifest = JsonSerializer.Deserialize(File.ReadAllText(manifestFile)); + manifest.Location = Path.GetDirectoryName(manifestFile); + + PersistenceManifests.Add(manifest); } } + catch (Exception ex) + { + logger.Warn($"Failed to load persistence manifests from development locations", ex); + } + + PersistenceManifests.ForEach(m => logger.Info($"Found persistence manifest for {m.DisplayName}")); } static string GetAssemblyDirectory() @@ -66,16 +83,9 @@ public static string Find(string persistenceType) throw new Exception("No persistenceType has been configured. Either provide a Type or Name in the PersistenceType setting."); } - Initialize(); - var persistenceManifestDefinition = PersistenceManifests.FirstOrDefault(w => w.IsMatch(persistenceType)); - if (persistenceManifestDefinition != null) - { - return persistenceManifestDefinition.TypeName; - } - - return persistenceType; + return persistenceManifestDefinition?.TypeName ?? persistenceType; } public static string GetPersistenceFolder(string persistenceType) @@ -85,19 +95,12 @@ public static string GetPersistenceFolder(string persistenceType) throw new Exception("No persistenceType has been configured. Either provide a Type or Name in the PersistenceType setting."); } - Initialize(); - var persistenceManifestDefinition = PersistenceManifests.FirstOrDefault(w => w.IsMatch(persistenceType)); - if (persistenceManifestDefinition != null) - { - return persistenceManifestDefinition.Name.Split('.').FirstOrDefault(); - } - - return null; + return persistenceManifestDefinition?.Location; } - static ILog logger = LogManager.GetLogger(typeof(PersistenceManifestLibrary)); + static readonly ILog logger = LogManager.GetLogger(typeof(PersistenceManifestLibrary)); } } diff --git a/src/ServiceControl.Audit.UnitTests/ServiceControl.Audit.UnitTests.csproj b/src/ServiceControl.Audit.UnitTests/ServiceControl.Audit.UnitTests.csproj index 10d2e30cfc..80ba33276a 100644 --- a/src/ServiceControl.Audit.UnitTests/ServiceControl.Audit.UnitTests.csproj +++ b/src/ServiceControl.Audit.UnitTests/ServiceControl.Audit.UnitTests.csproj @@ -4,11 +4,11 @@ net472 ServiceControl.runsettings - + + - diff --git a/src/ServiceControl.Audit.UnitTests/ServiceControl.runsettings b/src/ServiceControl.Audit.UnitTests/ServiceControl.runsettings index ea2e767f89..624cd65002 100644 --- a/src/ServiceControl.Audit.UnitTests/ServiceControl.runsettings +++ b/src/ServiceControl.Audit.UnitTests/ServiceControl.runsettings @@ -1,7 +1,7 @@  - - - x64 - + + + x64 + diff --git a/src/ServiceControl.Audit/App.config b/src/ServiceControl.Audit/App.config index 435f41a343..cf43fbd84f 100644 --- a/src/ServiceControl.Audit/App.config +++ b/src/ServiceControl.Audit/App.config @@ -27,7 +27,7 @@ These settings are only here so that we can debug ServiceControl while developin - + --> diff --git a/src/ServiceControl.Audit/Program.cs b/src/ServiceControl.Audit/Program.cs index a77a9c3ccd..a03354abcc 100644 --- a/src/ServiceControl.Audit/Program.cs +++ b/src/ServiceControl.Audit/Program.cs @@ -50,33 +50,32 @@ static Assembly ResolveAssembly(string name) var combine = Path.Combine(appDirectory, requestingName + ".dll"); var assembly = !File.Exists(combine) ? null : Assembly.LoadFrom(combine); + if (assembly == null && settings != null) { var transportFolder = TransportManifestLibrary.GetTransportFolder(settings.TransportType); - if (transportFolder != null) - { - var subFolderPath = Path.Combine(appDirectory, "Transports", transportFolder); - assembly = TryLoadTypeFromSubdirectory(subFolderPath, requestingName); - } + assembly = TryLoadAssembly(transportFolder, requestingName); + } + if (assembly == null && settings != null) + { var persistenceFolder = PersistenceManifestLibrary.GetPersistenceFolder(settings.PersistenceType); - if (assembly == null && persistenceFolder != null) - { - var subFolderPath = Path.Combine(appDirectory, "Persisters", persistenceFolder); - assembly = TryLoadTypeFromSubdirectory(subFolderPath, requestingName); - } + assembly = TryLoadAssembly(persistenceFolder, requestingName); } return assembly; } - static Assembly TryLoadTypeFromSubdirectory(string subFolderPath, string requestingName) + static Assembly TryLoadAssembly(string folderPath, string requestingName) { - var path = Path.Combine(subFolderPath, $"{requestingName}.dll"); - - if (File.Exists(path)) + if (folderPath != null) { - return Assembly.LoadFrom(path); + var path = Path.Combine(folderPath, $"{requestingName}.dll"); + + if (File.Exists(path)) + { + return Assembly.LoadFrom(path); + } } return null; @@ -84,4 +83,4 @@ static Assembly TryLoadTypeFromSubdirectory(string subFolderPath, string request static readonly ILog Logger = LogManager.GetLogger(typeof(Program)); } -} \ No newline at end of file +} diff --git a/src/ServiceControl.Audit/ServiceControl.Audit.csproj b/src/ServiceControl.Audit/ServiceControl.Audit.csproj index 239aae652c..e47edf652e 100644 --- a/src/ServiceControl.Audit/ServiceControl.Audit.csproj +++ b/src/ServiceControl.Audit/ServiceControl.Audit.csproj @@ -6,14 +6,10 @@ Operations.ico - - + + + - - - - - diff --git a/src/ServiceControl.Infrastructure/ServiceControl.Infrastructure.csproj b/src/ServiceControl.Infrastructure/ServiceControl.Infrastructure.csproj index 643937d08c..a5c1475468 100644 --- a/src/ServiceControl.Infrastructure/ServiceControl.Infrastructure.csproj +++ b/src/ServiceControl.Infrastructure/ServiceControl.Infrastructure.csproj @@ -9,5 +9,5 @@ - + \ No newline at end of file diff --git a/src/ServiceControl.LoadTests.AuditGenerator/ServiceControl.LoadTests.AuditGenerator.csproj b/src/ServiceControl.LoadTests.AuditGenerator/ServiceControl.LoadTests.AuditGenerator.csproj index 67c9906027..0786dbcd5d 100644 --- a/src/ServiceControl.LoadTests.AuditGenerator/ServiceControl.LoadTests.AuditGenerator.csproj +++ b/src/ServiceControl.LoadTests.AuditGenerator/ServiceControl.LoadTests.AuditGenerator.csproj @@ -4,7 +4,7 @@ net472 Exe AuditGenerator - 8 + 8.0 diff --git a/src/ServiceControl.Monitoring.AcceptanceTests/ServiceControl.Monitoring.AcceptanceTests.csproj b/src/ServiceControl.Monitoring.AcceptanceTests/ServiceControl.Monitoring.AcceptanceTests.csproj index 23c078953d..d8f69b3844 100644 --- a/src/ServiceControl.Monitoring.AcceptanceTests/ServiceControl.Monitoring.AcceptanceTests.csproj +++ b/src/ServiceControl.Monitoring.AcceptanceTests/ServiceControl.Monitoring.AcceptanceTests.csproj @@ -5,7 +5,6 @@ 8 - diff --git a/src/ServiceControl.Monitoring/Program.cs b/src/ServiceControl.Monitoring/Program.cs index 675dc3134b..703dd3686a 100644 --- a/src/ServiceControl.Monitoring/Program.cs +++ b/src/ServiceControl.Monitoring/Program.cs @@ -47,28 +47,26 @@ static Assembly ResolveAssembly(string name) var combine = Path.Combine(appDirectory, requestingName + ".dll"); var assembly = !File.Exists(combine) ? null : Assembly.LoadFrom(combine); + if (assembly == null && settings != null) { - //look into transport directory var transportFolder = TransportManifestLibrary.GetTransportFolder(settings.TransportType); - if (transportFolder != null) - { - var transportsPath = Path.Combine(appDirectory, "Transports", transportFolder); - - assembly = TryLoadTypeFromSubdirectory(transportsPath, requestingName); - } + assembly = TryLoadAssembly(transportFolder, requestingName); } return assembly; } - static Assembly TryLoadTypeFromSubdirectory(string subFolderPath, string requestingName) + static Assembly TryLoadAssembly(string folderPath, string requestingName) { - var path = Path.Combine(subFolderPath, $"{requestingName}.dll"); - - if (File.Exists(path)) + if (folderPath != null) { - return Assembly.LoadFrom(path); + var path = Path.Combine(folderPath, $"{requestingName}.dll"); + + if (File.Exists(path)) + { + return Assembly.LoadFrom(path); + } } return null; diff --git a/src/ServiceControl.Monitoring/ServiceControl.Monitoring.csproj b/src/ServiceControl.Monitoring/ServiceControl.Monitoring.csproj index 30c7a291a4..9ec7eb594b 100644 --- a/src/ServiceControl.Monitoring/ServiceControl.Monitoring.csproj +++ b/src/ServiceControl.Monitoring/ServiceControl.Monitoring.csproj @@ -6,11 +6,8 @@ Operations.ico - - - - - + + diff --git a/src/ServiceControl.MultiInstance.AcceptanceTests/ServiceControl.runsettings b/src/ServiceControl.MultiInstance.AcceptanceTests/ServiceControl.runsettings index ea2e767f89..624cd65002 100644 --- a/src/ServiceControl.MultiInstance.AcceptanceTests/ServiceControl.runsettings +++ b/src/ServiceControl.MultiInstance.AcceptanceTests/ServiceControl.runsettings @@ -1,7 +1,7 @@  - - - x64 - + + + x64 + diff --git a/src/ServiceControl.Persistence.RavenDb5/EmbeddedDatabase.cs b/src/ServiceControl.Persistence.RavenDb5/EmbeddedDatabase.cs index 7cb42cb5d6..48c0f30335 100644 --- a/src/ServiceControl.Persistence.RavenDb5/EmbeddedDatabase.cs +++ b/src/ServiceControl.Persistence.RavenDb5/EmbeddedDatabase.cs @@ -5,6 +5,7 @@ using System.Diagnostics; using System.Globalization; using System.IO; + using System.Reflection; using System.Threading; using System.Threading.Tasks; using ByteSizeLib; @@ -25,30 +26,22 @@ public class EmbeddedDatabase : IDisposable static (string LicenseFileName, string ServerDirectory) GetRavenLicenseFileNameAndServerDirectory() { + var assembly = Assembly.GetExecutingAssembly(); + var assemblyDirectory = Path.GetDirectoryName(assembly.Location); + var licenseFileName = "RavenLicense.json"; - var localRavenLicense = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, licenseFileName); - if (File.Exists(localRavenLicense)) + var ravenLicense = Path.Combine(assemblyDirectory, licenseFileName); + var serverDirectory = Path.Combine(assemblyDirectory, "RavenDBServer"); + + if (File.Exists(ravenLicense)) { - return (localRavenLicense, null); + return (ravenLicense, serverDirectory); } - - const string Persisters = "Persisters"; - const string RavenDB5 = "RavenDB5"; - - var persisterDirectory = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, Persisters, RavenDB5); - - localRavenLicense = Path.Combine(persisterDirectory, licenseFileName); - if (!File.Exists(localRavenLicense)) + else { - throw new Exception($"RavenDB license not found. Make sure the RavenDB license file, '{licenseFileName}', " + - $"is stored in the '{AppDomain.CurrentDomain.BaseDirectory}' folder or in the '{Persisters}/{RavenDB5}' subfolder."); + var assemblyName = Path.GetFileName(assembly.Location); + throw new Exception($"RavenDB license not found. Make sure the RavenDB license file '{licenseFileName}' is stored in the same directory as {assemblyName}."); } - - // By default RavenDB 5 searches its binaries in the RavenDBServer right below the BaseDirectory. - // If we're loading from Persisters/RavenDB5 we also have to signal RavenDB where are binaries - var serverDirectory = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "Persisters", "RavenDB5", "RavenDBServer"); - - return (localRavenLicense, serverDirectory); } internal static EmbeddedDatabase Start(RavenDBPersisterSettings settings) diff --git a/src/ServiceControl.Persistence.RavenDb5/ServiceControl.Persistence.RavenDb5.csproj b/src/ServiceControl.Persistence.RavenDb5/ServiceControl.Persistence.RavenDb5.csproj index 85fe63bef3..a507ef682d 100644 --- a/src/ServiceControl.Persistence.RavenDb5/ServiceControl.Persistence.RavenDb5.csproj +++ b/src/ServiceControl.Persistence.RavenDb5/ServiceControl.Persistence.RavenDb5.csproj @@ -6,14 +6,14 @@ - + - + diff --git a/src/ServiceControl.Persistence.Tests.RavenDb5/ServiceControl.Persistence.Tests.RavenDb5.csproj b/src/ServiceControl.Persistence.Tests.RavenDb5/ServiceControl.Persistence.Tests.RavenDb5.csproj index 1aa7242079..ad0944943d 100644 --- a/src/ServiceControl.Persistence.Tests.RavenDb5/ServiceControl.Persistence.Tests.RavenDb5.csproj +++ b/src/ServiceControl.Persistence.Tests.RavenDb5/ServiceControl.Persistence.Tests.RavenDb5.csproj @@ -5,12 +5,9 @@ ServiceControl.runsettings - - - - + @@ -18,15 +15,15 @@ + - - + diff --git a/src/ServiceControl.Persistence.Tests.RavenDb5/ServiceControl.runsettings b/src/ServiceControl.Persistence.Tests.RavenDb5/ServiceControl.runsettings index ea2e767f89..624cd65002 100644 --- a/src/ServiceControl.Persistence.Tests.RavenDb5/ServiceControl.runsettings +++ b/src/ServiceControl.Persistence.Tests.RavenDb5/ServiceControl.runsettings @@ -1,7 +1,7 @@  - - - x64 - + + + x64 + diff --git a/src/ServiceControl.Persistence/DevelopmentPersistenceLocations.cs b/src/ServiceControl.Persistence/DevelopmentPersistenceLocations.cs new file mode 100644 index 0000000000..9ae7cb7a0c --- /dev/null +++ b/src/ServiceControl.Persistence/DevelopmentPersistenceLocations.cs @@ -0,0 +1,36 @@ +namespace ServiceControl.Persistence +{ + using System.Collections.Generic; + using System.IO; + + static class DevelopmentPersistenceLocations + { + public static List ManifestFiles { get; } = new List(); + + static DevelopmentPersistenceLocations() + { + var assembly = typeof(DevelopmentPersistenceLocations).Assembly.Location; + var assemblyDirectory = Path.GetDirectoryName(assembly); + + // Becomes null if it navigates past the root of a drive + var srcFolder = Path.GetDirectoryName(Path.GetDirectoryName(Path.GetDirectoryName(Path.GetDirectoryName(assemblyDirectory)))); + + if (!string.IsNullOrWhiteSpace(srcFolder) && srcFolder.EndsWith("src")) + { + ManifestFiles.Add(BuildManifestPath(srcFolder, "ServiceControl.Persistence.RavenDb5")); + } + } + + static string BuildManifestPath(string srcFolder, string projectName) => Path.Combine(srcFolder, projectName, "bin", configuration, framework, "persistence.manifest"); + +#if DEBUG + const string configuration = "Debug"; +#else + const string configuration = "Release"; +#endif + +#if NET472 + const string framework = "net472"; +#endif + } +} diff --git a/src/ServiceControl.Persistence/PersistenceManifestLibrary.cs b/src/ServiceControl.Persistence/PersistenceManifestLibrary.cs index 9d1ebaa4c6..56009dc84e 100644 --- a/src/ServiceControl.Persistence/PersistenceManifestLibrary.cs +++ b/src/ServiceControl.Persistence/PersistenceManifestLibrary.cs @@ -10,10 +10,17 @@ public class PersistenceManifest { public string Version { get; set; } + + public string Location { get; set; } + public string Name { get; set; } + public string DisplayName { get; set; } + public string Description { get; set; } + public string TypeName { get; set; } + public bool IsSupported { get; set; } = true; internal bool IsMatch(string persistenceType) => @@ -23,34 +30,43 @@ internal bool IsMatch(string persistenceType) => public static class PersistenceManifestLibrary { - public static List PersistenceManifests { get; set; } + public static List PersistenceManifests { get; } = new List(); - static bool initialized; - static void Initialize() + static PersistenceManifestLibrary() { - if (PersistenceManifests == null) - { - PersistenceManifests = new List(); - } + var assemblyDirectory = GetAssemblyDirectory(); - if (!initialized) + try { - initialized = true; - var assemblyLocation = GetAssemblyDirectory(); - try + foreach (var manifestFile in Directory.EnumerateFiles(assemblyDirectory, "persistence.manifest", SearchOption.AllDirectories)) { - PersistenceManifests.AddRange( - Directory.EnumerateFiles(assemblyLocation, "persistence.manifest", SearchOption.AllDirectories) - .Select(manifest => JsonSerializer.Deserialize(File.ReadAllText(manifest))) - ); + var manifest = JsonSerializer.Deserialize(File.ReadAllText(manifestFile)); + manifest.Location = Path.GetDirectoryName(manifestFile); - PersistenceManifests.ForEach(m => logger.Info($"Found persistence manifest for {m.DisplayName}")); + PersistenceManifests.Add(manifest); } - catch (Exception ex) + } + catch (Exception ex) + { + logger.Warn($"Failed to load persistence manifests from {assemblyDirectory}", ex); + } + + try + { + foreach (var manifestFile in DevelopmentPersistenceLocations.ManifestFiles) { - logger.Warn($"Failed to load persistence manifests from {assemblyLocation}", ex); + var manifest = JsonSerializer.Deserialize(File.ReadAllText(manifestFile)); + manifest.Location = Path.GetDirectoryName(manifestFile); + + PersistenceManifests.Add(manifest); } } + catch (Exception ex) + { + logger.Warn($"Failed to load persistence manifests from development locations", ex); + } + + PersistenceManifests.ForEach(m => logger.Info($"Found persistence manifest for {m.DisplayName}")); } static string GetAssemblyDirectory() @@ -66,16 +82,9 @@ public static string Find(string persistenceType) throw new Exception("No persistenceType has been configured. Either provide a Type or Name in the PersistenceType setting."); } - Initialize(); - var persistenceManifestDefinition = PersistenceManifests.FirstOrDefault(w => w.IsMatch(persistenceType)); - if (persistenceManifestDefinition != null) - { - return persistenceManifestDefinition.TypeName; - } - - return persistenceType; + return persistenceManifestDefinition?.TypeName ?? persistenceType; } public static string GetPersistenceFolder(string persistenceType) @@ -85,19 +94,12 @@ public static string GetPersistenceFolder(string persistenceType) throw new Exception("No persistenceType has been configured. Either provide a Type or Name in the PersistenceType setting."); } - Initialize(); - var persistenceManifestDefinition = PersistenceManifests.FirstOrDefault(w => w.IsMatch(persistenceType)); - if (persistenceManifestDefinition != null) - { - return persistenceManifestDefinition.Name.Split('.').FirstOrDefault(); - } - - return null; + return persistenceManifestDefinition?.Location; } - static ILog logger = LogManager.GetLogger(typeof(PersistenceManifestLibrary)); + static readonly ILog logger = LogManager.GetLogger(typeof(PersistenceManifestLibrary)); } } diff --git a/src/ServiceControl.Persistence/ServiceControl.Persistence.csproj b/src/ServiceControl.Persistence/ServiceControl.Persistence.csproj index fd6857877f..a8a9989c7d 100644 --- a/src/ServiceControl.Persistence/ServiceControl.Persistence.csproj +++ b/src/ServiceControl.Persistence/ServiceControl.Persistence.csproj @@ -4,18 +4,19 @@ net472 + + + + + - + - - - - \ No newline at end of file diff --git a/src/ServiceControl.Transports.ASB/ServiceControl.Transports.ASB.csproj b/src/ServiceControl.Transports.ASB/ServiceControl.Transports.ASB.csproj index a0ca58b37d..56513e9cd0 100644 --- a/src/ServiceControl.Transports.ASB/ServiceControl.Transports.ASB.csproj +++ b/src/ServiceControl.Transports.ASB/ServiceControl.Transports.ASB.csproj @@ -14,11 +14,11 @@ - + - + \ No newline at end of file diff --git a/src/ServiceControl.Transports.ASBEndpointTopology.Tests/ServiceControl.Transports.ASBEndpointTopology.Tests.csproj b/src/ServiceControl.Transports.ASBEndpointTopology.Tests/ServiceControl.Transports.ASBEndpointTopology.Tests.csproj index d0ec0d26e7..5fd518683d 100644 --- a/src/ServiceControl.Transports.ASBEndpointTopology.Tests/ServiceControl.Transports.ASBEndpointTopology.Tests.csproj +++ b/src/ServiceControl.Transports.ASBEndpointTopology.Tests/ServiceControl.Transports.ASBEndpointTopology.Tests.csproj @@ -2,27 +2,25 @@ net472 - false + + + + + + - - - - - - - + - \ No newline at end of file diff --git a/src/ServiceControl.Transports.ASBForwardingTopology.Tests/ServiceControl.Transports.ASBForwardingTopology.Tests.csproj b/src/ServiceControl.Transports.ASBForwardingTopology.Tests/ServiceControl.Transports.ASBForwardingTopology.Tests.csproj index 9799830b13..33c09df6f6 100644 --- a/src/ServiceControl.Transports.ASBForwardingTopology.Tests/ServiceControl.Transports.ASBForwardingTopology.Tests.csproj +++ b/src/ServiceControl.Transports.ASBForwardingTopology.Tests/ServiceControl.Transports.ASBForwardingTopology.Tests.csproj @@ -2,27 +2,25 @@ net472 - false + + + + + + - - - - - - - + - \ No newline at end of file diff --git a/src/ServiceControl.Transports.ASBS.Tests/ServiceControl.Transports.ASBS.Tests.csproj b/src/ServiceControl.Transports.ASBS.Tests/ServiceControl.Transports.ASBS.Tests.csproj index c9254cf4e2..d0deb53b83 100644 --- a/src/ServiceControl.Transports.ASBS.Tests/ServiceControl.Transports.ASBS.Tests.csproj +++ b/src/ServiceControl.Transports.ASBS.Tests/ServiceControl.Transports.ASBS.Tests.csproj @@ -2,27 +2,26 @@ net472 - false + + + + + + + - - - - - - - + - diff --git a/src/ServiceControl.Transports.ASBS/ServiceControl.Transports.ASBS.csproj b/src/ServiceControl.Transports.ASBS/ServiceControl.Transports.ASBS.csproj index 72d28e4c23..0030a9638e 100644 --- a/src/ServiceControl.Transports.ASBS/ServiceControl.Transports.ASBS.csproj +++ b/src/ServiceControl.Transports.ASBS/ServiceControl.Transports.ASBS.csproj @@ -15,11 +15,11 @@ - + - + \ No newline at end of file diff --git a/src/ServiceControl.Transports.ASQ.Tests/ServiceControl.Transports.ASQ.Tests.csproj b/src/ServiceControl.Transports.ASQ.Tests/ServiceControl.Transports.ASQ.Tests.csproj index 2b06001bc7..a370581049 100644 --- a/src/ServiceControl.Transports.ASQ.Tests/ServiceControl.Transports.ASQ.Tests.csproj +++ b/src/ServiceControl.Transports.ASQ.Tests/ServiceControl.Transports.ASQ.Tests.csproj @@ -2,27 +2,25 @@ net472 - false + + + + + + - - - - - - - + - \ No newline at end of file diff --git a/src/ServiceControl.Transports.ASQ/ServiceControl.Transports.ASQ.csproj b/src/ServiceControl.Transports.ASQ/ServiceControl.Transports.ASQ.csproj index 15cb68d906..60dec855f3 100644 --- a/src/ServiceControl.Transports.ASQ/ServiceControl.Transports.ASQ.csproj +++ b/src/ServiceControl.Transports.ASQ/ServiceControl.Transports.ASQ.csproj @@ -13,11 +13,11 @@ - + - + diff --git a/src/ServiceControl.Transports.Learning/ServiceControl.Transports.Learning.csproj b/src/ServiceControl.Transports.Learning/ServiceControl.Transports.Learning.csproj index ec57ecfa82..773bb37ec0 100644 --- a/src/ServiceControl.Transports.Learning/ServiceControl.Transports.Learning.csproj +++ b/src/ServiceControl.Transports.Learning/ServiceControl.Transports.Learning.csproj @@ -9,11 +9,11 @@ - + - + \ No newline at end of file diff --git a/src/ServiceControl.Transports.Msmq.Tests/ServiceControl.Transports.Msmq.Tests.csproj b/src/ServiceControl.Transports.Msmq.Tests/ServiceControl.Transports.Msmq.Tests.csproj index e4e436e979..4a3798364f 100644 --- a/src/ServiceControl.Transports.Msmq.Tests/ServiceControl.Transports.Msmq.Tests.csproj +++ b/src/ServiceControl.Transports.Msmq.Tests/ServiceControl.Transports.Msmq.Tests.csproj @@ -3,21 +3,22 @@ net472 + + + + + + + - - - - - - - + @@ -25,6 +26,6 @@ - + diff --git a/src/ServiceControl.Transports.Msmq/ServiceControl.Transports.Msmq.csproj b/src/ServiceControl.Transports.Msmq/ServiceControl.Transports.Msmq.csproj index 8b757b14db..8d35f8ded1 100644 --- a/src/ServiceControl.Transports.Msmq/ServiceControl.Transports.Msmq.csproj +++ b/src/ServiceControl.Transports.Msmq/ServiceControl.Transports.Msmq.csproj @@ -14,11 +14,11 @@ - + - + diff --git a/src/ServiceControl.Transports.RabbitMQ/ServiceControl.Transports.RabbitMQ.csproj b/src/ServiceControl.Transports.RabbitMQ/ServiceControl.Transports.RabbitMQ.csproj index 28dd5f110c..19e6524e09 100644 --- a/src/ServiceControl.Transports.RabbitMQ/ServiceControl.Transports.RabbitMQ.csproj +++ b/src/ServiceControl.Transports.RabbitMQ/ServiceControl.Transports.RabbitMQ.csproj @@ -13,11 +13,11 @@ - + - + \ No newline at end of file diff --git a/src/ServiceControl.Transports.RabbitMQClassicConventionalRouting.Tests/ServiceControl.Transports.RabbitMQClassicConventionalRoutingTests.csproj b/src/ServiceControl.Transports.RabbitMQClassicConventionalRouting.Tests/ServiceControl.Transports.RabbitMQClassicConventionalRoutingTests.csproj index 2c481cd13e..1be9f368d0 100644 --- a/src/ServiceControl.Transports.RabbitMQClassicConventionalRouting.Tests/ServiceControl.Transports.RabbitMQClassicConventionalRoutingTests.csproj +++ b/src/ServiceControl.Transports.RabbitMQClassicConventionalRouting.Tests/ServiceControl.Transports.RabbitMQClassicConventionalRoutingTests.csproj @@ -2,27 +2,25 @@ net472 - false + + + + + + - - - - - - - + - \ No newline at end of file diff --git a/src/ServiceControl.Transports.RabbitMQClassicDirectRouting.Tests/ServiceControl.Transports.RabbitMQClassicDirectRouting.Tests.csproj b/src/ServiceControl.Transports.RabbitMQClassicDirectRouting.Tests/ServiceControl.Transports.RabbitMQClassicDirectRouting.Tests.csproj index 2c481cd13e..1be9f368d0 100644 --- a/src/ServiceControl.Transports.RabbitMQClassicDirectRouting.Tests/ServiceControl.Transports.RabbitMQClassicDirectRouting.Tests.csproj +++ b/src/ServiceControl.Transports.RabbitMQClassicDirectRouting.Tests/ServiceControl.Transports.RabbitMQClassicDirectRouting.Tests.csproj @@ -2,27 +2,25 @@ net472 - false + + + + + + - - - - - - - + - \ No newline at end of file diff --git a/src/ServiceControl.Transports.RabbitMQQuorumConventionalRouting.Tests/ServiceControl.Transports.RabbitMQQuorumConventionalRouting.Tests.csproj b/src/ServiceControl.Transports.RabbitMQQuorumConventionalRouting.Tests/ServiceControl.Transports.RabbitMQQuorumConventionalRouting.Tests.csproj index 479fba8815..b570abbaab 100644 --- a/src/ServiceControl.Transports.RabbitMQQuorumConventionalRouting.Tests/ServiceControl.Transports.RabbitMQQuorumConventionalRouting.Tests.csproj +++ b/src/ServiceControl.Transports.RabbitMQQuorumConventionalRouting.Tests/ServiceControl.Transports.RabbitMQQuorumConventionalRouting.Tests.csproj @@ -2,27 +2,25 @@ net472 - false + + + + + + - - - - - - - + - diff --git a/src/ServiceControl.Transports.RabbitMQQuorumDirectRouting.Tests/ServiceControl.Transports.RabbitMQQuorumDirectRouting.Tests.csproj b/src/ServiceControl.Transports.RabbitMQQuorumDirectRouting.Tests/ServiceControl.Transports.RabbitMQQuorumDirectRouting.Tests.csproj index 2c481cd13e..1be9f368d0 100644 --- a/src/ServiceControl.Transports.RabbitMQQuorumDirectRouting.Tests/ServiceControl.Transports.RabbitMQQuorumDirectRouting.Tests.csproj +++ b/src/ServiceControl.Transports.RabbitMQQuorumDirectRouting.Tests/ServiceControl.Transports.RabbitMQQuorumDirectRouting.Tests.csproj @@ -2,27 +2,25 @@ net472 - false + + + + + + - - - - - - - + - \ No newline at end of file diff --git a/src/ServiceControl.Transports.SQS.Tests/ServiceControl.Transports.SQS.Tests.csproj b/src/ServiceControl.Transports.SQS.Tests/ServiceControl.Transports.SQS.Tests.csproj index 70bfa641b1..cebcd325a8 100644 --- a/src/ServiceControl.Transports.SQS.Tests/ServiceControl.Transports.SQS.Tests.csproj +++ b/src/ServiceControl.Transports.SQS.Tests/ServiceControl.Transports.SQS.Tests.csproj @@ -2,25 +2,23 @@ net472 - false + + + + + + - - - - - - - - + diff --git a/src/ServiceControl.Transports.SQS/ServiceControl.Transports.SQS.csproj b/src/ServiceControl.Transports.SQS/ServiceControl.Transports.SQS.csproj index 24434d2573..ae94a61a17 100644 --- a/src/ServiceControl.Transports.SQS/ServiceControl.Transports.SQS.csproj +++ b/src/ServiceControl.Transports.SQS/ServiceControl.Transports.SQS.csproj @@ -13,11 +13,11 @@ - + - + \ No newline at end of file diff --git a/src/ServiceControl.Transports.SqlServer.Tests/ServiceControl.Transports.SqlServer.Tests.csproj b/src/ServiceControl.Transports.SqlServer.Tests/ServiceControl.Transports.SqlServer.Tests.csproj index 9536fb1219..39eba65cec 100644 --- a/src/ServiceControl.Transports.SqlServer.Tests/ServiceControl.Transports.SqlServer.Tests.csproj +++ b/src/ServiceControl.Transports.SqlServer.Tests/ServiceControl.Transports.SqlServer.Tests.csproj @@ -2,27 +2,25 @@ net472 - false + + + + + + - - - - - - - + - diff --git a/src/ServiceControl.Transports.SqlServer/ServiceControl.Transports.SqlServer.csproj b/src/ServiceControl.Transports.SqlServer/ServiceControl.Transports.SqlServer.csproj index 4a7540227a..8544613fa7 100644 --- a/src/ServiceControl.Transports.SqlServer/ServiceControl.Transports.SqlServer.csproj +++ b/src/ServiceControl.Transports.SqlServer/ServiceControl.Transports.SqlServer.csproj @@ -13,11 +13,11 @@ - + - + diff --git a/src/ServiceControl.Transports.Tests/ApprovalFiles/APIApprovals.ServiceControlTransport.approved.txt b/src/ServiceControl.Transports.Tests/ApprovalFiles/APIApprovals.ServiceControlTransport.approved.txt index 061de48e55..1cad24fd90 100644 --- a/src/ServiceControl.Transports.Tests/ApprovalFiles/APIApprovals.ServiceControlTransport.approved.txt +++ b/src/ServiceControl.Transports.Tests/ApprovalFiles/APIApprovals.ServiceControlTransport.approved.txt @@ -50,6 +50,7 @@ namespace ServiceControl.Transports { public TransportManifest() { } public ServiceControl.Transports.TransportManifestDefinition[] Definitions { get; set; } + public string Location { get; set; } public string Version { get; set; } } public class TransportManifestDefinition @@ -62,7 +63,7 @@ namespace ServiceControl.Transports } public static class TransportManifestLibrary { - public static System.Collections.Generic.List TransportManifests { get; set; } + public static System.Collections.Generic.List TransportManifests { get; } public static string Find(string transportType) { } public static string GetTransportFolder(string transportType) { } } diff --git a/src/ServiceControl.Transports.Tests/ServiceControl.Transports.Tests.csproj b/src/ServiceControl.Transports.Tests/ServiceControl.Transports.Tests.csproj index 03e03bbb27..7d6b0235a6 100644 --- a/src/ServiceControl.Transports.Tests/ServiceControl.Transports.Tests.csproj +++ b/src/ServiceControl.Transports.Tests/ServiceControl.Transports.Tests.csproj @@ -4,20 +4,11 @@ net472 - - - - - - - - - - + + - @@ -28,10 +19,4 @@ - - - - - - diff --git a/src/ServiceControl.Transports.Tests/TransportManifestLibraryTests.cs b/src/ServiceControl.Transports.Tests/TransportManifestLibraryTests.cs index 7f9a6f62e3..73b9189db2 100644 --- a/src/ServiceControl.Transports.Tests/TransportManifestLibraryTests.cs +++ b/src/ServiceControl.Transports.Tests/TransportManifestLibraryTests.cs @@ -12,7 +12,6 @@ public class TransportManifestLibraryTests const string transportName = "AzureServiceBus.EndpointOriented"; const string transportType = "ServiceControl.Transports.ASB.ASBEndpointTopologyTransportCustomization, ServiceControl.Transports.ASB"; const string transportAlias = "ServiceControl.Transports.LegacyAzureServiceBus.EndpointOrientedTopologyAzureServiceBusTransport, ServiceControl.Transports.LegacyAzureServiceBus"; - const string transportFolderName = "AzureServiceBus"; [Test] public void Should_find_transport_type_by_name() @@ -52,7 +51,7 @@ public void Should_find_transport_type_folder_by_name() { var _transportTypeFolder = TransportManifestLibrary.GetTransportFolder(transportName); - Assert.AreEqual(transportFolderName, _transportTypeFolder); + Assert.IsNotNull(_transportTypeFolder); } [Test] @@ -60,7 +59,7 @@ public void Should_find_transport_type_folder_by_type() { var _transportTypeFolder = TransportManifestLibrary.GetTransportFolder(transportType); - Assert.AreEqual(transportFolderName, _transportTypeFolder); + Assert.IsNotNull(_transportTypeFolder); } [Test] @@ -68,7 +67,7 @@ public void Should_find_transport_type_folder_by_alias() { var _transportTypeFolder = TransportManifestLibrary.GetTransportFolder(transportAlias); - Assert.AreEqual(transportFolderName, _transportTypeFolder); + Assert.IsNotNull(_transportTypeFolder); } [Test] @@ -83,32 +82,21 @@ public void Should_return_null_for_not_found_transport_type() [Test] public void All_types_defined_in_manifest_files_exist_in_specified_assembly() { - var assemblyLocation = Assembly.GetExecutingAssembly().Location; - var appDirectory = Path.GetDirectoryName(assemblyLocation); - TransportManifestLibrary.GetTransportFolder("dummy"); //to initialise the collection - TransportManifestLibrary.TransportManifests.SelectMany(t => t.Definitions).ToList().ForEach(t => + var count = 0; + + foreach (var definition in TransportManifestLibrary.TransportManifests.SelectMany(t => t.Definitions)) { - var transportFolder = TransportManifestLibrary.GetTransportFolder(t.Name); - var subFolderPath = Path.Combine(appDirectory, "Transports", transportFolder); - var assemblyName = t.TypeName.Split(',')[1].Trim(); - var assembly = TryLoadTypeFromSubdirectory(subFolderPath, assemblyName); + count++; + var transportFolder = TransportManifestLibrary.GetTransportFolder(definition.Name); + var assemblyName = definition.TypeName.Split(',')[1].Trim(); + var assemblyFile = Path.Combine(transportFolder, assemblyName + ".dll"); + var assembly = Assembly.LoadFrom(assemblyFile); Assert.IsNotNull(assembly, $"Could not load assembly {assemblyName}"); - - Assert.IsTrue(assembly.GetTypes().Any(a => a.FullName == t.TypeName.Split(',').FirstOrDefault() && a.Namespace == assemblyName), $"Transport type {t.TypeName} not found in assembly {assemblyName}"); - }); - } - - Assembly TryLoadTypeFromSubdirectory(string subFolderPath, string requestingName) - { - //look into any subdirectory - var file = Directory.EnumerateFiles(subFolderPath, requestingName + ".dll", SearchOption.AllDirectories).SingleOrDefault(); - if (file != null) - { - return Assembly.LoadFrom(file); + Assert.IsTrue(assembly.GetTypes().Any(a => a.FullName == definition.TypeName.Split(',').FirstOrDefault() && a.Namespace == assemblyName), $"Transport type {definition.TypeName} not found in assembly {assemblyName}"); } - return null; + Assert.NotZero(count, "No transport manifests found."); } } } \ No newline at end of file diff --git a/src/ServiceControl.Transports/DevelopmentTransportLocations.cs b/src/ServiceControl.Transports/DevelopmentTransportLocations.cs new file mode 100644 index 0000000000..c6006c2d0a --- /dev/null +++ b/src/ServiceControl.Transports/DevelopmentTransportLocations.cs @@ -0,0 +1,43 @@ +namespace ServiceControl.Transports +{ + using System.Collections.Generic; + using System.IO; + + static class DevelopmentTransportLocations + { + public static List ManifestFiles { get; } = new List(); + + static DevelopmentTransportLocations() + { + var assembly = typeof(DevelopmentTransportLocations).Assembly.Location; + var assemblyDirectory = Path.GetDirectoryName(assembly); + + // Becomes null if it navigates past the root of a drive + var srcFolder = Path.GetDirectoryName(Path.GetDirectoryName(Path.GetDirectoryName(Path.GetDirectoryName(assemblyDirectory)))); + + if (!string.IsNullOrWhiteSpace(srcFolder) && srcFolder.EndsWith("src")) + { + ManifestFiles.Add(BuildManifestPath(srcFolder, "ServiceControl.Transports.ASB")); + ManifestFiles.Add(BuildManifestPath(srcFolder, "ServiceControl.Transports.ASBS")); + ManifestFiles.Add(BuildManifestPath(srcFolder, "ServiceControl.Transports.ASQ")); + ManifestFiles.Add(BuildManifestPath(srcFolder, "ServiceControl.Transports.Learning")); + ManifestFiles.Add(BuildManifestPath(srcFolder, "ServiceControl.Transports.Msmq")); + ManifestFiles.Add(BuildManifestPath(srcFolder, "ServiceControl.Transports.RabbitMQ")); + ManifestFiles.Add(BuildManifestPath(srcFolder, "ServiceControl.Transports.SqlServer")); + ManifestFiles.Add(BuildManifestPath(srcFolder, "ServiceControl.Transports.SQS")); + } + } + + static string BuildManifestPath(string srcFolder, string projectName) => Path.Combine(srcFolder, projectName, "bin", configuration, framework, "transport.manifest"); + +#if DEBUG + const string configuration = "Debug"; +#else + const string configuration = "Release"; +#endif + +#if NET472 + const string framework = "net472"; +#endif + } +} diff --git a/src/ServiceControl.Transports/TransportManifest.cs b/src/ServiceControl.Transports/TransportManifest.cs index ef8d8be4b4..4456e7a5d7 100644 --- a/src/ServiceControl.Transports/TransportManifest.cs +++ b/src/ServiceControl.Transports/TransportManifest.cs @@ -10,14 +10,20 @@ public class TransportManifest { public string Version { get; set; } + + public string Location { get; set; } + public TransportManifestDefinition[] Definitions { get; set; } } public class TransportManifestDefinition { public string Name { get; set; } + public string DisplayName { get; set; } + public string TypeName { get; set; } + public string[] Aliases { get; set; } internal bool IsMatch(string transportType) => @@ -38,34 +44,43 @@ bool AliasesContain(string transportType) public static class TransportManifestLibrary { - public static List TransportManifests { get; set; } + public static List TransportManifests { get; } = new List(); - static bool initialized; - static void Initialize() + static TransportManifestLibrary() { - if (TransportManifests == null) - { - TransportManifests = new List(); - } + var assemblyDirectory = GetAssemblyDirectory(); - if (!initialized) + try { - initialized = true; - var assemblyLocation = GetAssemblyDirectory(); - try + foreach (var manifestFile in Directory.EnumerateFiles(assemblyDirectory, "transport.manifest", SearchOption.AllDirectories)) { - TransportManifests.AddRange( - Directory.EnumerateFiles(assemblyLocation, "transport.manifest", SearchOption.AllDirectories) - .Select(manifest => JsonSerializer.Deserialize(File.ReadAllText(manifest))) - ); + var manifest = JsonSerializer.Deserialize(File.ReadAllText(manifestFile)); + manifest.Location = Path.GetDirectoryName(manifestFile); - TransportManifests.SelectMany(t => t.Definitions).ToList().ForEach(m => logger.Info($"Found transport manifest for {m.DisplayName}")); + TransportManifests.Add(manifest); } - catch (Exception ex) + } + catch (Exception ex) + { + logger.Warn($"Failed to load transport manifests from {assemblyDirectory}", ex); + } + + try + { + foreach (var manifestFile in DevelopmentTransportLocations.ManifestFiles) { - logger.Warn($"Failed to load transport manifests from {assemblyLocation}", ex); + var manifest = JsonSerializer.Deserialize(File.ReadAllText(manifestFile)); + manifest.Location = Path.GetDirectoryName(manifestFile); + + TransportManifests.Add(manifest); } } + catch (Exception ex) + { + logger.Warn($"Failed to load transport manifests from development locations", ex); + } + + TransportManifests.SelectMany(t => t.Definitions).ToList().ForEach(m => logger.Info($"Found transport manifest for {m.DisplayName}")); } static string GetAssemblyDirectory() @@ -81,18 +96,11 @@ public static string Find(string transportType) throw new Exception("No transport has been configured. Either provide a Type or Name in the TransportType setting."); } - Initialize(); - var transportManifestDefinition = TransportManifests .SelectMany(t => t.Definitions) .FirstOrDefault(w => w.IsMatch(transportType)); - if (transportManifestDefinition != null) - { - return transportManifestDefinition.TypeName; - } - - return transportType; + return transportManifestDefinition?.TypeName ?? transportType; } public static string GetTransportFolder(string transportType) @@ -102,21 +110,32 @@ public static string GetTransportFolder(string transportType) throw new Exception("No transport has been configured. Either provide a Type or Name in the TransportType setting."); } - Initialize(); + string transportFolder = null; - var transportManifestDefinition = TransportManifests - .SelectMany(t => t.Definitions) - .FirstOrDefault(w => w.IsMatch(transportType)); - - if (transportManifestDefinition != null) + foreach (var manifest in TransportManifests) { - return transportManifestDefinition.Name.Split('.').FirstOrDefault(); + var match = false; + + foreach (var definition in manifest.Definitions) + { + if (definition.IsMatch(transportType)) + { + match = true; + break; + } + } + + if (match) + { + transportFolder = manifest.Location; + break; + } } - return null; + return transportFolder; } - static ILog logger = LogManager.GetLogger(typeof(TransportManifestLibrary)); + static readonly ILog logger = LogManager.GetLogger(typeof(TransportManifestLibrary)); } } diff --git a/src/ServiceControl.UnitTests/ServiceControl.runsettings b/src/ServiceControl.UnitTests/ServiceControl.runsettings index ea2e767f89..624cd65002 100644 --- a/src/ServiceControl.UnitTests/ServiceControl.runsettings +++ b/src/ServiceControl.UnitTests/ServiceControl.runsettings @@ -1,7 +1,7 @@  - - - x64 - + + + x64 + diff --git a/src/ServiceControl.runsettings b/src/ServiceControl.runsettings index 7a67eed179..cf4838b8a9 100644 --- a/src/ServiceControl.runsettings +++ b/src/ServiceControl.runsettings @@ -1,6 +1,6 @@  - - x64 - + + x64 + diff --git a/src/ServiceControl.sln b/src/ServiceControl.sln index 2c6de35bad..fd6b635bdf 100644 --- a/src/ServiceControl.sln +++ b/src/ServiceControl.sln @@ -46,9 +46,9 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Items", "Solution Custom.Build.props = Custom.Build.props Directory.Build.targets = Directory.Build.targets Directory.Packages.props = Directory.Packages.props - Persisters.Audit.Includes.props = Persisters.Audit.Includes.props - Persisters.Primary.Includes.props = Persisters.Primary.Includes.props - Transports.Includes.props = Transports.Includes.props + ProjectReferences.Persisters.Audit.props = ProjectReferences.Persisters.Audit.props + ProjectReferences.Persisters.Primary.props = ProjectReferences.Persisters.Primary.props + ProjectReferences.Transports.props = ProjectReferences.Transports.props EndProjectSection EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "ServiceControl.Transports", "ServiceControl.Transports\ServiceControl.Transports.csproj", "{3D9E3A53-164F-4430-A6A4-D35551F5DC88}" diff --git a/src/ServiceControl/App.config b/src/ServiceControl/App.config index 9cd12c53e7..7f10914c78 100644 --- a/src/ServiceControl/App.config +++ b/src/ServiceControl/App.config @@ -23,7 +23,7 @@ These settings are only here so that we can debug ServiceControl while developin --> - + @@ -34,7 +34,7 @@ These settings are only here so that we can debug ServiceControl while developin - + --> diff --git a/src/ServiceControl/Program.cs b/src/ServiceControl/Program.cs index 842f26ae66..8a491398ae 100644 --- a/src/ServiceControl/Program.cs +++ b/src/ServiceControl/Program.cs @@ -48,34 +48,32 @@ static Assembly ResolveAssembly(string name) var combine = Path.Combine(appDirectory, requestingName + ".dll"); var assembly = !File.Exists(combine) ? null : Assembly.LoadFrom(combine); + if (assembly == null && settings != null) { var transportFolder = TransportManifestLibrary.GetTransportFolder(settings.TransportType); + assembly = TryLoadAssembly(transportFolder, requestingName); + } - if (transportFolder != null) - { - var subFolderPath = Path.Combine(appDirectory, "Transports", transportFolder); - assembly = TryLoadTypeFromSubdirectory(subFolderPath, requestingName); - } - + if (assembly == null && settings != null) + { var persistenceFolder = PersistenceManifestLibrary.GetPersistenceFolder(settings.PersistenceType); - if (assembly == null && persistenceFolder != null) - { - var subFolderPath = Path.Combine(appDirectory, "Persisters", persistenceFolder); - assembly = TryLoadTypeFromSubdirectory(subFolderPath, requestingName); - } + assembly = TryLoadAssembly(persistenceFolder, requestingName); } return assembly; } - static Assembly TryLoadTypeFromSubdirectory(string subFolderPath, string requestingName) + static Assembly TryLoadAssembly(string folderPath, string requestingName) { - var path = Path.Combine(subFolderPath, $"{requestingName}.dll"); - - if (File.Exists(path)) + if (folderPath != null) { - return Assembly.LoadFrom(path); + var path = Path.Combine(folderPath, $"{requestingName}.dll"); + + if (File.Exists(path)) + { + return Assembly.LoadFrom(path); + } } return null; diff --git a/src/ServiceControl/ServiceControl.csproj b/src/ServiceControl/ServiceControl.csproj index 20b548d915..ecef688e15 100644 --- a/src/ServiceControl/ServiceControl.csproj +++ b/src/ServiceControl/ServiceControl.csproj @@ -7,18 +7,9 @@ true - - - - - - - - - - - - + + + diff --git a/src/ServiceControlInstaller.Packaging/ServiceControlInstaller.Packaging.csproj b/src/ServiceControlInstaller.Packaging/ServiceControlInstaller.Packaging.csproj index dab9e16cde..d14e4ea6fa 100644 --- a/src/ServiceControlInstaller.Packaging/ServiceControlInstaller.Packaging.csproj +++ b/src/ServiceControlInstaller.Packaging/ServiceControlInstaller.Packaging.csproj @@ -10,26 +10,6 @@ - - - - - - - - - - - - - - - - - - - - diff --git a/src/Transports.Includes.props b/src/Transports.Includes.props deleted file mode 100644 index 879d64d39b..0000000000 --- a/src/Transports.Includes.props +++ /dev/null @@ -1,12 +0,0 @@ - - - - - - - - - - - - \ No newline at end of file