Skip to content

Commit

Permalink
Merge pull request #589 from dolittle/7.3.0-legolas
Browse files Browse the repository at this point in the history
Legolas - Tenants and Resources
  • Loading branch information
jakhog authored Nov 18, 2021
2 parents 7c80b06 + dbf7121 commit 82abce9
Show file tree
Hide file tree
Showing 21 changed files with 530 additions and 16 deletions.
3 changes: 2 additions & 1 deletion .github/workflows/release.yml
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
name: Release

env:
PRERELEASE_BRANCHES: aragorn # Comma separated list of prerelease branch names. 'alpha,rc, ...'
PRERELEASE_BRANCHES: legolas # Comma separated list of prerelease branch names. 'alpha,rc, ...'

on:
pull_request:
Expand Down Expand Up @@ -45,6 +45,7 @@ jobs:
uses: dolittle/github-release-action@v2
if: ${{ steps.context.outputs.should-publish == 'true' }}
with:
token: ${{ secrets.BUILD_PAT }}
version: ${{ steps.increment-version.outputs.next-version }}
body: ${{ steps.context.outputs.pr-body }}

Expand Down
15 changes: 15 additions & 0 deletions Runtime.sln
Original file line number Diff line number Diff line change
Expand Up @@ -191,6 +191,8 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Aggregates.Management", "So
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Events.Management", "Source\Events.Management\Events.Management.csproj", "{493EF936-F918-4A78-8AD9-A6A6F93D761A}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Resources", "Source\Resources\Resources.csproj", "{C70D8ED8-A701-4697-BE87-B623E37D8976}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
Expand Down Expand Up @@ -1308,6 +1310,18 @@ Global
{493EF936-F918-4A78-8AD9-A6A6F93D761A}.Release|x64.Build.0 = Release|Any CPU
{493EF936-F918-4A78-8AD9-A6A6F93D761A}.Release|x86.ActiveCfg = Release|Any CPU
{493EF936-F918-4A78-8AD9-A6A6F93D761A}.Release|x86.Build.0 = Release|Any CPU
{C70D8ED8-A701-4697-BE87-B623E37D8976}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{C70D8ED8-A701-4697-BE87-B623E37D8976}.Debug|Any CPU.Build.0 = Debug|Any CPU
{C70D8ED8-A701-4697-BE87-B623E37D8976}.Debug|x64.ActiveCfg = Debug|Any CPU
{C70D8ED8-A701-4697-BE87-B623E37D8976}.Debug|x64.Build.0 = Debug|Any CPU
{C70D8ED8-A701-4697-BE87-B623E37D8976}.Debug|x86.ActiveCfg = Debug|Any CPU
{C70D8ED8-A701-4697-BE87-B623E37D8976}.Debug|x86.Build.0 = Debug|Any CPU
{C70D8ED8-A701-4697-BE87-B623E37D8976}.Release|Any CPU.ActiveCfg = Release|Any CPU
{C70D8ED8-A701-4697-BE87-B623E37D8976}.Release|Any CPU.Build.0 = Release|Any CPU
{C70D8ED8-A701-4697-BE87-B623E37D8976}.Release|x64.ActiveCfg = Release|Any CPU
{C70D8ED8-A701-4697-BE87-B623E37D8976}.Release|x64.Build.0 = Release|Any CPU
{C70D8ED8-A701-4697-BE87-B623E37D8976}.Release|x86.ActiveCfg = Release|Any CPU
{C70D8ED8-A701-4697-BE87-B623E37D8976}.Release|x86.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(NestedProjects) = preSolution
{ACACF102-3A61-442F-B202-BDF92F6FD26A} = {562DC4C5-91AB-4280-B40C-A2E0C43AA21C}
Expand Down Expand Up @@ -1402,5 +1416,6 @@ Global
{F8BDD9B1-64AA-4038-B7ED-FB12F360DA62} = {95D3ED76-BB5F-442F-A99A-F48FF34FEDA6}
{D5CD6014-99D7-46EC-A149-9ECCD72687AC} = {562DC4C5-91AB-4280-B40C-A2E0C43AA21C}
{493EF936-F918-4A78-8AD9-A6A6F93D761A} = {562DC4C5-91AB-4280-B40C-A2E0C43AA21C}
{C70D8ED8-A701-4697-BE87-B623E37D8976} = {562DC4C5-91AB-4280-B40C-A2E0C43AA21C}
EndGlobalSection
EndGlobal
20 changes: 20 additions & 0 deletions Source/Resources/MongoDB/Bindings.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
// Copyright (c) Dolittle. All rights reserved.
// Licensed under the MIT license. See LICENSE file in the project root for full license information.

using Dolittle.Runtime.DependencyInversion;

namespace Dolittle.Runtime.Resources.MongoDB
{
/// <summary>
/// Represents <see cref="ICanProvideBindings">bindings</see> for the resources system.
/// </summary>
public class Bindings : ICanProvideBindings
{
/// <inheritdoc />
public void Provide(IBindingProviderBuilder builder)
{
builder.Bind<IKnowTheConnectionString>().To<ConnectionStringFromResourceConfiguration>();
builder.Bind<ICanGetResourceForTenant>().To<ResourceForTenantGetter>();
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
// Copyright (c) Dolittle. All rights reserved.
// Licensed under the MIT license. See LICENSE file in the project root for full license information.

using Dolittle.Runtime.Lifecycle;
using Dolittle.Runtime.ResourceTypes.Configuration;
using MongoDB.Driver;

namespace Dolittle.Runtime.Resources.MongoDB
{
/// <summary>
/// Represents an implementation of <see cref="IKnowTheConnectionString"/>.
/// </summary>
[SingletonPerTenant]
public class ConnectionStringFromResourceConfiguration : IKnowTheConnectionString
{

/// <summary>
/// Initializes a new instance of the <see cref="ConnectionStringFromResourceConfiguration"/> class.
/// </summary>
/// <param name="configuration">The <see cref="IConfigurationFor{T}"/> of type <see cref="ResourceConfiguration"/> to use.</param>
public ConnectionStringFromResourceConfiguration(IConfigurationFor<ResourceConfiguration> configuration)
{
ConnectionString = BuildConnectionString(configuration.Instance);
}

/// <inheritdoc />
public MongoUrl ConnectionString { get; }

MongoUrl BuildConnectionString(ResourceConfiguration configuration)
{
var builder = new MongoUrlBuilder(configuration.Host);
builder.UseTls = configuration.UseSSL;
builder.DatabaseName = configuration.Database;
return builder.ToMongoUrl();
}
}
}
21 changes: 21 additions & 0 deletions Source/Resources/MongoDB/ICanGetResourceForTenant.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
// Copyright (c) Dolittle. All rights reserved.
// Licensed under the MIT license. See LICENSE file in the project root for full license information.

using Dolittle.Runtime.Execution;
using Dolittle.Runtime.Resources.Contracts;

namespace Dolittle.Runtime.Resources.MongoDB
{
/// <summary>
/// Defines a system that can get the MongoDB resource details for a specific tenant.
/// </summary>
public interface ICanGetResourceForTenant
{
/// <summary>
/// Gets the MongoDB resource for a specific tenant.
/// </summary>
/// <param name="executionContext">The <see cref="ExecutionContext"/> that specifies the tenant..</param>
/// <returns>The <see cref="GetMongoDBResponse"/> with the details for using the MongoDB resource.</returns>
GetMongoDBResponse GetResource(ExecutionContext executionContext);
}
}
18 changes: 18 additions & 0 deletions Source/Resources/MongoDB/IKnowTheConnectionString.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
// Copyright (c) Dolittle. All rights reserved.
// Licensed under the MIT license. See LICENSE file in the project root for full license information.

using MongoDB.Driver;

namespace Dolittle.Runtime.Resources.MongoDB
{
/// <summary>
/// Defines a system that knows about the connection string to a MongoDB resource for the current tenant.
/// </summary>
public interface IKnowTheConnectionString
{
/// <summary>
/// Gets the <see cref="MongoUrl">connection string</see> for the MongoDB resource for the current tenant.
/// </summary>
MongoUrl ConnectionString { get; }
}
}
33 changes: 33 additions & 0 deletions Source/Resources/MongoDB/LoggerExtensions.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
// Copyright (c) Dolittle. All rights reserved.
// Licensed under the MIT license. See LICENSE file in the project root for full license information.

using System;
using Dolittle.Runtime.ApplicationModel;
using Microsoft.Extensions.Logging;

namespace Dolittle.Runtime.Resources.MongoDB
{
/// <summary>
/// Represents a extensions for <see cref="Grpc.Core.Logging.ILogger" />.
/// </summary>
static class LoggerExtensions
{
static readonly Action<ILogger, Guid, Exception> _getResourceCalled = LoggerMessage
.Define<Guid>(
LogLevel.Information,
new EventId(1231142, nameof(GetResourceCalled)),
"Getting MongoDB resource for {Tenant}");

static readonly Action<ILogger, Guid, Exception> _failedToGetResource = LoggerMessage
.Define<Guid>(
LogLevel.Information,
new EventId(1231143, nameof(FailedToGetResource)),
"Failed to get MongoDB resource for {Tenant}");

internal static void GetResourceCalled(this ILogger logger, TenantId tenantId)
=> _getResourceCalled(logger, tenantId, null);

internal static void FailedToGetResource(this ILogger logger, TenantId tenantId, Exception ex)
=> _failedToGetResource(logger, tenantId, ex);
}
}
26 changes: 26 additions & 0 deletions Source/Resources/MongoDB/ResourceConfiguration.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
// Copyright (c) Dolittle. All rights reserved.
// Licensed under the MIT license. See LICENSE file in the project root for full license information.

namespace Dolittle.Runtime.Resources.MongoDB
{
/// <summary>
/// Represents the resource configuration for a MongoDB resource.
/// </summary>
public class ResourceConfiguration
{
/// <summary>
/// Gets or sets the MongoDB host.
/// </summary>
public string Host { get; set; }

/// <summary>
/// Gets or sets the database name.
/// </summary>
public string Database { get; set; }

/// <summary>
/// Gets or sets the value indicating whether or not to use SSL.
/// </summary>
public bool UseSSL { get; set; }
}
}
57 changes: 57 additions & 0 deletions Source/Resources/MongoDB/ResourceForTenantGetter.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
// Copyright (c) Dolittle. All rights reserved.
// Licensed under the MIT license. See LICENSE file in the project root for full license information.

using System;
using Dolittle.Runtime.DependencyInversion;
using Dolittle.Runtime.Execution;
using Dolittle.Runtime.Protobuf;
using Dolittle.Runtime.Resources.Contracts;
using Microsoft.Extensions.Logging;

namespace Dolittle.Runtime.Resources.MongoDB
{
/// <summary>
/// Represents the implementation of <see cref="ICanGetResourceForTenant"/>.
/// </summary>
public class ResourceForTenantGetter : ICanGetResourceForTenant
{
readonly FactoryFor<IKnowTheConnectionString> _getConnectionString;
readonly IExecutionContextManager _executionContextManager;
readonly ILogger _logger;


/// <summary>
/// Initializes a new instance of the <see cref="ResourceForTenantGetter"/> class.
/// </summary>
/// <param name="getConnectionString">The <see cref="FactoryFor{T}"/> of type <see cref="IKnowTheConnectionString"/> to use to get connection strings after setting the execution context.</param>
/// <param name="executionContextManager">The <see cref="IExecutionContextManager"/> to use to set the execution context.</param>
/// <param name="logger">The <see cref="ILogger"/> to use for logging.</param>
public ResourceForTenantGetter(FactoryFor<IKnowTheConnectionString> getConnectionString, IExecutionContextManager executionContextManager, ILogger logger)
{
_getConnectionString = getConnectionString;
_executionContextManager = executionContextManager;
_logger = logger;
}

/// <inheritdoc />
public GetMongoDBResponse GetResource(ExecutionContext executionContext)
{
try
{
_logger.GetResourceCalled(executionContext.Tenant);
_executionContextManager.CurrentFor(executionContext);

var mongoUrl = _getConnectionString().ConnectionString;
return new GetMongoDBResponse
{
ConnectionString = mongoUrl.ToString(),
};
}
catch (Exception ex)
{
_logger.FailedToGetResource(executionContext.Tenant, ex);
return new GetMongoDBResponse {Failure = new Failure(ex.Message) };
}
}
}
}
32 changes: 32 additions & 0 deletions Source/Resources/MongoDB/ResourceType.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
// Copyright (c) Dolittle. All rights reserved.
// Licensed under the MIT license. See LICENSE file in the project root for full license information.

using System;
using System.Collections.Generic;
using Dolittle.Runtime.ResourceTypes;

namespace Dolittle.Runtime.Resources.MongoDB
{
/// <summary>
/// Represents a <see cref="IAmAResourceType">resource type</see> for the MongoDB resource.
/// </summary>
/// <remarks>The name is currently readModels to support for legacy cases.</remarks>
public class ResourceType : IAmAResourceType
{
/// <summary>
/// The <see cref="ResourceTypes.ResourceType"/> name.
/// </summary>
/// <remarks>
/// Although this resource type is a MongoDB specific type that cannot be swapped out with another implementation
/// like the historical "Read Models" storage could, we're keeping the implementation for the configuration the
/// same to make the Runtime compatible with the previous configuration files style.
/// </remarks>
public static ResourceTypes.ResourceType ResourceTypeName => "readModels";

/// <inheritdoc/>
public ResourceTypes.ResourceType Name => ResourceTypeName;

/// <inheritdoc/>
public IEnumerable<Type> Services { get; } = new[] { typeof(IKnowTheConnectionString) };
}
}
30 changes: 30 additions & 0 deletions Source/Resources/MongoDB/ResourceTypeRepresentation.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
// Copyright (c) Dolittle. All rights reserved.
// Licensed under the MIT license. See LICENSE file in the project root for full license information.

using System;
using System.Collections.Generic;
using Dolittle.Runtime.ResourceTypes;

namespace Dolittle.Runtime.Resources.MongoDB
{
/// <inheritdoc/>
public class ResourceTypeRepresentation : IRepresentAResourceType
{
static readonly IDictionary<Type, Type> _bindings = new Dictionary<Type, Type>
{
{ typeof(IKnowTheConnectionString), typeof(ConnectionStringFromResourceConfiguration) }
};

/// <inheritdoc/>
public ResourceTypes.ResourceType Type => ResourceType.ResourceTypeName;

/// <inheritdoc/>
public ResourceTypeImplementation ImplementationName => "MongoDB";

/// <inheritdoc/>
public Type ConfigurationObjectType => typeof(ResourceConfiguration);

/// <inheritdoc/>
public IDictionary<Type, Type> Bindings => _bindings;
}
}
21 changes: 21 additions & 0 deletions Source/Resources/Resources.csproj
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
<Project Sdk="Microsoft.NET.Sdk">
<Import Project="../../default.props" />

<PropertyGroup>
<RootNamespace>Dolittle.Runtime.Resources</RootNamespace>
<AssemblyName>Dolittle.Runtime.Resources</AssemblyName>
</PropertyGroup>

<ItemGroup>
<PackageReference Include="MongoDB.Driver" Version="$(MongoDBDriverVersion)" />
<PackageReference Include="Dolittle.Runtime.Contracts" Version="$(ContractsVersion)" />
</ItemGroup>

<ItemGroup>
<ProjectReference Include="../Tenancy/Tenancy.csproj" />
<ProjectReference Include="../Rudimentary/Rudimentary.csproj" />
<ProjectReference Include="../ResourceTypes/ResourceTypes.csproj" />
<ProjectReference Include="../ResourceTypes.Configuration/ResourceTypes.Configuration.csproj" />
</ItemGroup>

</Project>
31 changes: 31 additions & 0 deletions Source/Resources/ResourcesService.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
// Copyright (c) Dolittle. All rights reserved.
// Licensed under the MIT license. See LICENSE file in the project root for full license information.

using System.Threading.Tasks;
using Dolittle.Runtime.Protobuf;
using Dolittle.Runtime.Resources.Contracts;
using Grpc.Core;
using static Dolittle.Runtime.Resources.Contracts.Resources;

namespace Dolittle.Runtime.Resources
{
/// <summary>
/// Represents an implementation of <see cref="ResourcesBase"/>.
/// </summary>
public class ResourcesService : ResourcesBase
{
readonly MongoDB.ICanGetResourceForTenant _mongodb;

/// <summary>
/// Initializes a new instance of the <see cref="ResourcesService"/> class.
/// </summary>
public ResourcesService(MongoDB.ICanGetResourceForTenant mongodbService)
{
_mongodb = mongodbService;
}

/// <inheritdoc />
public override Task<GetMongoDBResponse> GetMongoDB(GetRequest request, ServerCallContext context)
=> Task.FromResult(_mongodb.GetResource(request.CallContext.ExecutionContext.ToExecutionContext()));
}
}
Loading

0 comments on commit 82abce9

Please sign in to comment.