Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add Akka.Hosting extension methods #199

Merged
merged 10 commits into from
Apr 10, 2023
Merged
Show file tree
Hide file tree
Changes from 3 commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 12 additions & 0 deletions Akka.Persistence.Sql.sln
Original file line number Diff line number Diff line change
Expand Up @@ -70,6 +70,10 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Akka.Persistence.Sql.TagTab
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Akka.Persistence.Sql.Tests.Common", "src\Akka.Persistence.Sql.Tests.Common\Akka.Persistence.Sql.Tests.Common.csproj", "{BDF8A537-A9D3-45A4-81EA-4B77DBD544D6}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Akka.Persistence.Sql.Hosting", "src\Akka.Persistence.Sql.Hosting\Akka.Persistence.Sql.Hosting.csproj", "{91E36B4F-5306-42AE-8B98-5459DB1CC3E3}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Akka.Persistence.Sql.Hosting.Tests", "src\Akka.Persistence.Sql.Hosting.Tests\Akka.Persistence.Sql.Hosting.Tests.csproj", "{F68A1A98-17C4-4D13-9422-D93D49886008}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
Expand Down Expand Up @@ -108,6 +112,14 @@ Global
{BDF8A537-A9D3-45A4-81EA-4B77DBD544D6}.Debug|Any CPU.Build.0 = Debug|Any CPU
{BDF8A537-A9D3-45A4-81EA-4B77DBD544D6}.Release|Any CPU.ActiveCfg = Release|Any CPU
{BDF8A537-A9D3-45A4-81EA-4B77DBD544D6}.Release|Any CPU.Build.0 = Release|Any CPU
{91E36B4F-5306-42AE-8B98-5459DB1CC3E3}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{91E36B4F-5306-42AE-8B98-5459DB1CC3E3}.Debug|Any CPU.Build.0 = Debug|Any CPU
{91E36B4F-5306-42AE-8B98-5459DB1CC3E3}.Release|Any CPU.ActiveCfg = Release|Any CPU
{91E36B4F-5306-42AE-8B98-5459DB1CC3E3}.Release|Any CPU.Build.0 = Release|Any CPU
{F68A1A98-17C4-4D13-9422-D93D49886008}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{F68A1A98-17C4-4D13-9422-D93D49886008}.Debug|Any CPU.Build.0 = Debug|Any CPU
{F68A1A98-17C4-4D13-9422-D93D49886008}.Release|Any CPU.ActiveCfg = Release|Any CPU
{F68A1A98-17C4-4D13-9422-D93D49886008}.Release|Any CPU.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
<Project Sdk="Microsoft.NET.Sdk">

<PropertyGroup>
<TargetFramework>$(NetCoreTestVersion)</TargetFramework>
<ImplicitUsings>enable</ImplicitUsings>
<Nullable>enable</Nullable>

<IsPackable>false</IsPackable>
</PropertyGroup>

<ItemGroup>
<PackageReference Include="FluentAssertions" />
<PackageReference Include="Microsoft.NET.Test.Sdk" />
<PackageReference Include="xunit" />
<PackageReference Include="xunit.runner.visualstudio" />
<PackageReference Include="coverlet.collector" />
</ItemGroup>

<ItemGroup>
<ProjectReference Include="..\Akka.Persistence.Sql.Hosting\Akka.Persistence.Sql.Hosting.csproj" />
</ItemGroup>

</Project>
159 changes: 159 additions & 0 deletions src/Akka.Persistence.Sql.Hosting.Tests/JournalSettingsSpec.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,159 @@
using Akka.Configuration;
using Akka.Persistence.Sql.Config;
using FluentAssertions;
using LanguageExt.UnitsOfMeasure;
using Xunit;

namespace Akka.Persistence.Sql.Hosting.Tests
{
public class JournalSettingsSpec
{
[Fact(DisplayName = "Default options should not override default hocon config")]
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM

public void DefaultOptionsTest()
{
var defaultConfig = ConfigurationFactory.ParseString(@"
akka.persistence.journal.sql {
connection-string = a
provider-name = b
}")
.WithFallback(SqlPersistence.DefaultConfiguration);

defaultConfig = defaultConfig.GetConfig(SqlPersistence.JournalConfigPath);

var opt = new SqlJournalOptions
{
ConnectionString = "a",
ProviderName = "b"
};
var actualConfig = opt.ToConfig().WithFallback(SqlPersistence.DefaultConfiguration);

actualConfig = actualConfig.GetConfig(SqlPersistence.JournalConfigPath);

actualConfig.GetString("connection-string").Should().Be(defaultConfig.GetString("connection-string"));
actualConfig.GetString("provider-name").Should().Be(defaultConfig.GetString("provider-name"));
actualConfig.GetString("table-mapping").Should().Be(defaultConfig.GetString("table-mapping"));
actualConfig.GetString("serializer").Should().Be(defaultConfig.GetString("serializer"));
actualConfig.GetBoolean("auto-initialize").Should().Be(defaultConfig.GetBoolean("auto-initialize"));
actualConfig.GetString("default.schema-name").Should().Be(defaultConfig.GetString("default.schema-name"));

var defaultJournalConfig = defaultConfig.GetConfig("default.journal");
var actualJournalConfig = actualConfig.GetConfig("default.journal");

actualJournalConfig.GetBoolean("use-writer-uuid-column").Should().Be(defaultJournalConfig.GetBoolean("use-writer-uuid-column"));
actualJournalConfig.GetString("table-name").Should().Be(defaultJournalConfig.GetString("table-name"));
actualJournalConfig.GetString("columns.ordering").Should().Be(defaultJournalConfig.GetString("columns.ordering"));
actualJournalConfig.GetString("columns.deleted").Should().Be(defaultJournalConfig.GetString("columns.deleted"));
actualJournalConfig.GetString("columns.persistence-id").Should().Be(defaultJournalConfig.GetString("columns.persistence-id"));
actualJournalConfig.GetString("columns.sequence-number").Should().Be(defaultJournalConfig.GetString("columns.sequence-number"));
actualJournalConfig.GetString("columns.created").Should().Be(defaultJournalConfig.GetString("columns.created"));
actualJournalConfig.GetString("columns.tags").Should().Be(defaultJournalConfig.GetString("columns.tags"));
actualJournalConfig.GetString("columns.message").Should().Be(defaultJournalConfig.GetString("columns.message"));
actualJournalConfig.GetString("columns.identifier").Should().Be(defaultJournalConfig.GetString("columns.identifier"));
actualJournalConfig.GetString("columns.manifest").Should().Be(defaultJournalConfig.GetString("columns.manifest"));
actualJournalConfig.GetString("columns.writer-uuid").Should().Be(defaultJournalConfig.GetString("columns.writer-uuid"));

var defaultMetaConfig = defaultConfig.GetConfig("default.metadata");
var actualMetaConfig = actualConfig.GetConfig("default.metadata");

actualMetaConfig.GetString("table-name").Should().Be(defaultMetaConfig.GetString("table-name"));
actualMetaConfig.GetString("columns.persistence-id").Should().Be(defaultMetaConfig.GetString("columns.persistence-id"));
actualMetaConfig.GetString("columns.sequence-number").Should().Be(defaultMetaConfig.GetString("columns.sequence-number"));

var defaultTagConfig = defaultConfig.GetConfig("default.tag");
var actualTagConfig = actualConfig.GetConfig("default.tag");

actualTagConfig.GetString("table-name").Should().Be(defaultTagConfig.GetString("table-name"));
actualTagConfig.GetString("columns.ordering-id").Should().Be(defaultTagConfig.GetString("columns.ordering-id"));
actualTagConfig.GetString("columns.tag-value").Should().Be(defaultTagConfig.GetString("columns.tag-value"));
actualTagConfig.GetString("columns.persistence-id").Should().Be(defaultTagConfig.GetString("columns.persistence-id"));
actualTagConfig.GetString("columns.sequence-nr").Should().Be(defaultTagConfig.GetString("columns.sequence-nr"));
}

[Fact(DisplayName = "Custom Options should modify default config")]
public void ModifiedOptionsTest()
{
var opt = new SqlJournalOptions(false, "custom")
{
AutoInitialize = false,
ConnectionString = "a",
ProviderName = "b",
QueryRefreshInterval = 5.Seconds(),
Serializer = "hyperion",
DatabaseOptions = new JournalDatabaseOptions(DatabaseMapping.SqlServer)
{
SchemaName = "schema",
JournalTable = new JournalTableOptions
{
TableName = "aa",
UseWriterUuidColumn = false,
OrderingColumnName = "a",
DeletedColumnName = "b",
PersistenceIdColumnName = "c",
SequenceNumberColumnName = "d",
CreatedColumnName = "e",
TagsColumnName = "f",
MessageColumnName = "g",
IdentifierColumnName = "h",
ManifestColumnName = "i",
WriterUuidColumnName = "j"
},
MetadataTable = new MetadataTableOptions
{
TableName = "bb",
PersistenceIdColumnName = "a",
SequenceNumberColumnName = "b"
},
TagTable = new TagTableOptions
{
TableName = "cc",
OrderingColumnName = "a",
TagColumnName = "b",
PersistenceIdColumnName = "c",
SequenceNumberColumnName = "d"
}
}
};

var fullConfig = opt.ToConfig();
var journalConfig = fullConfig
.GetConfig("akka.persistence.journal.custom")
.WithFallback(SqlPersistence.DefaultJournalConfiguration);
var config = new JournalConfig(journalConfig);

fullConfig.GetTimeSpan("akka.persistence.query.journal.sql.refresh-interval").Should().Be(5.Seconds());

config.AutoInitialize.Should().BeFalse();
config.ConnectionString.Should().Be("a");
config.ProviderName.Should().Be("b");
config.DefaultSerializer.Should().Be("hyperion");

config.TableConfig.SchemaName.Should().Be("schema");

var journalTable = config.TableConfig.EventJournalTable;
journalTable.UseWriterUuidColumn.Should().BeFalse();
journalTable.Name.Should().Be("aa");
journalTable.ColumnNames.Ordering.Should().Be("a");
journalTable.ColumnNames.Deleted.Should().Be("b");
journalTable.ColumnNames.PersistenceId.Should().Be("c");
journalTable.ColumnNames.SequenceNumber.Should().Be("d");
journalTable.ColumnNames.Created.Should().Be("e");
journalTable.ColumnNames.Tags.Should().Be("f");
journalTable.ColumnNames.Message.Should().Be("g");
journalTable.ColumnNames.Identifier.Should().Be("h");
journalTable.ColumnNames.Manifest.Should().Be("i");
journalTable.ColumnNames.WriterUuid.Should().Be("j");

var metaTable = config.TableConfig.MetadataTable;
metaTable.Name.Should().Be("bb");
metaTable.ColumnNames.PersistenceId.Should().Be("a");
metaTable.ColumnNames.SequenceNumber.Should().Be("b");

var tagTable = config.TableConfig.TagTable;
tagTable.Name.Should().Be("cc");
tagTable.ColumnNames.OrderingId.Should().Be("a");
tagTable.ColumnNames.Tag.Should().Be("b");
tagTable.ColumnNames.PersistenceId.Should().Be("c");
tagTable.ColumnNames.SequenceNumber.Should().Be("d");
}
}
}
104 changes: 104 additions & 0 deletions src/Akka.Persistence.Sql.Hosting.Tests/SnapshotSettingsSpec.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,104 @@
// -----------------------------------------------------------------------
// <copyright file="SnapshotSettingsSpec.cs" company="Akka.NET Project">
// Copyright (C) 2013-2023 .NET Foundation <https://github.com/akkadotnet/akka.net>
// </copyright>
// -----------------------------------------------------------------------

using Akka.Configuration;
using Akka.Persistence.Sql.Config;
using FluentAssertions;
using Xunit;

namespace Akka.Persistence.Sql.Hosting.Tests
{
public class SnapshotSettingsSpec
{
[Fact(DisplayName = "Default options should not override default hocon config")]
public void DefaultOptionsTest()
{
var defaultConfig = ConfigurationFactory.ParseString(@"
akka.persistence.snapshot-store.sql {
connection-string = a
provider-name = b
}")
.WithFallback(SqlPersistence.DefaultConfiguration);

defaultConfig = defaultConfig.GetConfig(SqlPersistence.SnapshotStoreConfigPath);

var opt = new SqlSnapshotOptions
{
ConnectionString = "a",
ProviderName = "b"
};
var actualConfig = opt.ToConfig().WithFallback(SqlPersistence.DefaultConfiguration);

actualConfig = actualConfig.GetConfig(SqlPersistence.SnapshotStoreConfigPath);

actualConfig.GetString("connection-string").Should().Be(defaultConfig.GetString("connection-string"));
actualConfig.GetString("provider-name").Should().Be(defaultConfig.GetString("provider-name"));
actualConfig.GetString("table-mapping").Should().Be(defaultConfig.GetString("table-mapping"));
actualConfig.GetString("serializer").Should().Be(defaultConfig.GetString("serializer"));
actualConfig.GetBoolean("auto-initialize").Should().Be(defaultConfig.GetBoolean("auto-initialize"));
actualConfig.GetString("default.schema-name").Should().Be(defaultConfig.GetString("default.schema-name"));

var defaultSnapshotConfig = defaultConfig.GetConfig("default.snapshot");
var actualSnapshotConfig = actualConfig.GetConfig("default.snapshot");

actualSnapshotConfig.GetString("table-name").Should().Be(defaultSnapshotConfig.GetString("table-name"));
actualSnapshotConfig.GetString("columns.persistence-id").Should().Be(defaultSnapshotConfig.GetString("columns.persistence-id"));
actualSnapshotConfig.GetString("columns.sequence-number").Should().Be(defaultSnapshotConfig.GetString("columns.sequence-number"));
actualSnapshotConfig.GetString("columns.created").Should().Be(defaultSnapshotConfig.GetString("columns.created"));
actualSnapshotConfig.GetString("columns.snapshot").Should().Be(defaultSnapshotConfig.GetString("columns.snapshot"));
actualSnapshotConfig.GetString("columns.manifest").Should().Be(defaultSnapshotConfig.GetString("columns.manifest"));
actualSnapshotConfig.GetString("columns.serializerId").Should().Be(defaultSnapshotConfig.GetString("columns.serializerId"));
}

[Fact(DisplayName = "Custom Options should modify default config")]
public void ModifiedOptionsTest()
{
var opt = new SqlSnapshotOptions(false, "custom")
{
AutoInitialize = false,
ConnectionString = "a",
ProviderName = "b",
Serializer = "hyperion",
DatabaseOptions = new SnapshotDatabaseOptions(DatabaseMapping.SqlServer)
{
SchemaName = "schema",
SnapshotTable = new SnapshotTableOptions
{
TableName = "aa",
PersistenceIdColumnName = "a",
SequenceNumberColumnName = "b",
CreatedColumnName = "c",
SnapshotColumnName = "d",
ManifestColumnName = "e",
SerializerIdColumnName = "f"
}
}
};

var fullConfig = opt.ToConfig();
var snapshotConfig = fullConfig
.GetConfig("akka.persistence.snapshot-store.custom")
.WithFallback(SqlPersistence.DefaultSnapshotConfiguration);
var config = new SnapshotConfig(snapshotConfig);

config.AutoInitialize.Should().BeFalse();
config.ConnectionString.Should().Be("a");
config.ProviderName.Should().Be("b");
config.DefaultSerializer.Should().Be("hyperion");

config.TableConfig.SchemaName.Should().Be("schema");

var snapshotTable = config.TableConfig.SnapshotTable;
snapshotTable.Name.Should().Be("aa");
snapshotTable.ColumnNames.PersistenceId.Should().Be("a");
snapshotTable.ColumnNames.SequenceNumber.Should().Be("b");
snapshotTable.ColumnNames.Created.Should().Be("c");
snapshotTable.ColumnNames.Snapshot.Should().Be("d");
snapshotTable.ColumnNames.Manifest.Should().Be("e");
snapshotTable.ColumnNames.SerializerId.Should().Be("f");
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
<Project Sdk="Microsoft.NET.Sdk">

<PropertyGroup>
<TargetFramework>$(NetStandardLibVersion)</TargetFramework>
<Nullable>enable</Nullable>
</PropertyGroup>

<ItemGroup>
<PackageReference Include="Akka.Persistence.Hosting" />
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM, version range for the MSFT.EXT packages is controlled by the base Akka.Hosting library.

</ItemGroup>

<ItemGroup>
<ProjectReference Include="..\Akka.Persistence.Sql\Akka.Persistence.Sql.csproj" />
</ItemGroup>
</Project>
44 changes: 44 additions & 0 deletions src/Akka.Persistence.Sql.Hosting/DatabaseMapping.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
// -----------------------------------------------------------------------
// <copyright file="DatabaseMapping.cs" company="Akka.NET Project">
// Copyright (C) 2013-2023 .NET Foundation <https://github.com/akkadotnet/akka.net>
// </copyright>
// -----------------------------------------------------------------------

using System;

namespace Akka.Persistence.Sql.Hosting
{
public enum DatabaseMapping
{
Default,
Sqlite,
SqlServer,
PostgreSql,
MySql,
}

public static class DatabaseMappingExtension
{
public static string Name(this DatabaseMapping map)
=> map switch
{
DatabaseMapping.Default => "default",
DatabaseMapping.Sqlite => "sqlite",
DatabaseMapping.SqlServer => "sql-server",
DatabaseMapping.PostgreSql => "postgresql",
DatabaseMapping.MySql => "mysql",
_ => throw new Exception($"Unknown DatabaseMapping: {map}")
};

public static JournalDatabaseOptions DatabaseOption(DatabaseMapping map)
=> map switch
{
DatabaseMapping.Default => JournalDatabaseOptions.Default,
DatabaseMapping.SqlServer => JournalDatabaseOptions.SqlServer,
DatabaseMapping.Sqlite => JournalDatabaseOptions.Sqlite,
DatabaseMapping.PostgreSql => JournalDatabaseOptions.PostgreSql,
DatabaseMapping.MySql => JournalDatabaseOptions.MySql,
_ => throw new Exception($"Unknown DatabaseMapping: {map}")
};
}
}
Loading