Skip to content

Commit

Permalink
Added support for GCP PubSub and Google Spanner database
Browse files Browse the repository at this point in the history
  • Loading branch information
jhakp committed Jun 13, 2022
1 parent 7a7a1bd commit 1c79b60
Show file tree
Hide file tree
Showing 23 changed files with 1,570 additions and 2 deletions.
25 changes: 23 additions & 2 deletions CAP.sln
Original file line number Diff line number Diff line change
Expand Up @@ -86,7 +86,13 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Sample.RabbitMQ.SqlServer.D
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "DotNetCore.CAP.OpenTelemetry", "src\DotNetCore.CAP.OpenTelemetry\DotNetCore.CAP.OpenTelemetry.csproj", "{83DDB126-A00B-4064-86E7-568322CA67EC}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Sample.AzureServiceBus.InMemory", "samples\Sample.AzureServiceBus.InMemory\Sample.AzureServiceBus.InMemory.csproj", "{0C734FB2-7D75-4FF3-B564-1E50E6280B14}"
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Sample.AzureServiceBus.InMemory", "samples\Sample.AzureServiceBus.InMemory\Sample.AzureServiceBus.InMemory.csproj", "{0C734FB2-7D75-4FF3-B564-1E50E6280B14}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Sample.GcpPubSub.GoogleSpanner", "samples\Sample.GcpPubSub.GoogleSpanner\Sample.GcpPubSub.GoogleSpanner.csproj", "{5F857ABF-449B-46C7-B160-CAC1C02DB782}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "DotNetCore.CAP.GooglePubSub", "src\DotNetCore.CAP.GooglePubSub\DotNetCore.CAP.GooglePubSub.csproj", "{AB823637-CA8C-4139-B9EC-DD29494E2276}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "DotNetCore.CAP.GoogleSpanner", "src\DotNetCore.CAP.GoogleSpanner\DotNetCore.CAP.GoogleSpanner.csproj", "{79278DDF-D699-4E1F-ACB4-907F8903E350}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Expand Down Expand Up @@ -214,6 +220,18 @@ Global
{0C734FB2-7D75-4FF3-B564-1E50E6280B14}.Debug|Any CPU.Build.0 = Debug|Any CPU
{0C734FB2-7D75-4FF3-B564-1E50E6280B14}.Release|Any CPU.ActiveCfg = Release|Any CPU
{0C734FB2-7D75-4FF3-B564-1E50E6280B14}.Release|Any CPU.Build.0 = Release|Any CPU
{5F857ABF-449B-46C7-B160-CAC1C02DB782}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{5F857ABF-449B-46C7-B160-CAC1C02DB782}.Debug|Any CPU.Build.0 = Debug|Any CPU
{5F857ABF-449B-46C7-B160-CAC1C02DB782}.Release|Any CPU.ActiveCfg = Release|Any CPU
{5F857ABF-449B-46C7-B160-CAC1C02DB782}.Release|Any CPU.Build.0 = Release|Any CPU
{AB823637-CA8C-4139-B9EC-DD29494E2276}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{AB823637-CA8C-4139-B9EC-DD29494E2276}.Debug|Any CPU.Build.0 = Debug|Any CPU
{AB823637-CA8C-4139-B9EC-DD29494E2276}.Release|Any CPU.ActiveCfg = Release|Any CPU
{AB823637-CA8C-4139-B9EC-DD29494E2276}.Release|Any CPU.Build.0 = Release|Any CPU
{79278DDF-D699-4E1F-ACB4-907F8903E350}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{79278DDF-D699-4E1F-ACB4-907F8903E350}.Debug|Any CPU.Build.0 = Debug|Any CPU
{79278DDF-D699-4E1F-ACB4-907F8903E350}.Release|Any CPU.ActiveCfg = Release|Any CPU
{79278DDF-D699-4E1F-ACB4-907F8903E350}.Release|Any CPU.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
Expand Down Expand Up @@ -249,8 +267,11 @@ Global
{DCDF58E8-F823-4F04-9F8C-E8076DC16A68} = {3A6B6931-A123-477A-9469-8B468B5385AF}
{83DDB126-A00B-4064-86E7-568322CA67EC} = {9B2AE124-6636-4DE9-83A3-70360DABD0C4}
{0C734FB2-7D75-4FF3-B564-1E50E6280B14} = {3A6B6931-A123-477A-9469-8B468B5385AF}
{5F857ABF-449B-46C7-B160-CAC1C02DB782} = {3A6B6931-A123-477A-9469-8B468B5385AF}
{AB823637-CA8C-4139-B9EC-DD29494E2276} = {9B2AE124-6636-4DE9-83A3-70360DABD0C4}
{79278DDF-D699-4E1F-ACB4-907F8903E350} = {9B2AE124-6636-4DE9-83A3-70360DABD0C4}
EndGlobalSection
GlobalSection(ExtensibilityGlobals) = postSolution
SolutionGuid = {2E70565D-94CF-40B4-BFE1-AC18D5F736AB}
EndGlobalSection
EndGlobal
EndGlobal
Original file line number Diff line number Diff line change
@@ -0,0 +1,79 @@
using System;
using System.Data;
using System.Text.Json;
using System.Threading.Tasks;
using Dapper;
using DotNetCore.CAP;
using Google.Cloud.Spanner.Data;
using Microsoft.AspNetCore.Mvc;
using Microsoft.Extensions.Configuration;

namespace Sample.GcpPubSub.GoogleSpanner
{
[Route("api/[controller]")]
public class ValuesController : Controller, ICapSubscribe
{
public class MyObj
{
public string SingerId { get; set; }
public string FirstName { get; set; }
}

private readonly string _connectionString;
private readonly ICapPublisher _capBus;

public ValuesController(ICapPublisher producer, IConfiguration configuration)
{
_capBus = producer;
_connectionString = configuration.GetConnectionString("SpannerDB");
}

[Route("~/without/transaction")]
public async Task<IActionResult> WithoutTransaction()
{
await _capBus.PublishAsync("sample.gcppubsub.googlespanner", DateTime.Now);

return Ok();
}

[Route("~/adonet/transaction")]
public IActionResult AdonetWithTransaction()
{
var random = new Random().Next(1, 10000);
try
{
using (var connection = new SpannerConnection(_connectionString))
{
using (var transaction = connection.BeginTransaction())
{
var id = Guid.NewGuid().ToString();
var sql = "INSERT INTO Singers (SingerId, FirstName, LastName, FullName) " +
" values ('" + id + "', 'User" + random + "', 'Doe', 'User" + random + " Doe')";
var cmd = connection.CreateDmlCommand(sql);
cmd.Transaction = transaction;
_ = cmd.ExecuteNonQuery();

var msg = new MyObj { SingerId = id, FirstName = "User" + random };

_capBus.Publish("sample.gcppubsub.googlespanner", msg);

transaction.Commit();
}
}
}
catch (Exception ex)
{
Console.WriteLine(ex);
}

return Ok();
}


[CapSubscribe("sample.gcppubsub.googlespanner")]
public void Test2(MyObj value)
{
Console.WriteLine("Subscriber output message: " + JsonSerializer.Serialize(value));
}
}
}
20 changes: 20 additions & 0 deletions samples/Sample.GcpPubSub.GoogleSpanner/Program.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
using Microsoft.AspNetCore.Hosting;
using Microsoft.Extensions.Hosting;

namespace Sample.GcpPubSub.GoogleSpanner
{
public class Program
{
public static void Main(string[] args)
{
CreateHostBuilder(args).Build().Run();
}

public static IHostBuilder CreateHostBuilder(string[] args) =>
Host.CreateDefaultBuilder(args)
.ConfigureWebHostDefaults(webBuilder =>
{
webBuilder.UseStartup<Startup>();
});
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
<Project Sdk="Microsoft.NET.Sdk.Web">

<PropertyGroup>
<TargetFramework>net6.0</TargetFramework>
<WarningsAsErrors>NU1701</WarningsAsErrors>
<NoWarn>NU1701</NoWarn>
</PropertyGroup>

<ItemGroup>
<PackageReference Include="Dapper" Version="2.0.35" />
<PackageReference Include="Microsoft.Extensions.Configuration" Version="3.1.7" />
<PackageReference Include="System.Configuration.ConfigurationManager" Version="6.0.0" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\..\src\DotNetCore.CAP.Dashboard\DotNetCore.CAP.Dashboard.csproj" />
<ProjectReference Include="..\..\src\DotNetCore.CAP.GooglePubSub\DotNetCore.CAP.GooglePubSub.csproj" />
<ProjectReference Include="..\..\src\DotNetCore.CAP.GoogleSpanner\DotNetCore.CAP.GoogleSpanner.csproj" />
<ProjectReference Include="..\..\src\DotNetCore.CAP\DotNetCore.CAP.csproj" />
</ItemGroup>

</Project>
48 changes: 48 additions & 0 deletions samples/Sample.GcpPubSub.GoogleSpanner/Startup.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
using Microsoft.AspNetCore.Builder;
using Microsoft.Extensions.DependencyInjection;
using DotNetCore.CAP.GoogleSpanner;
using Microsoft.Extensions.Configuration;
using DotNetCore.CAP;
using DotNetCore.CAP.Dashboard.NodeDiscovery;

namespace Sample.GcpPubSub.GoogleSpanner
{
public class Startup
{
public Startup(IConfiguration configuration)
{
Configuration = configuration;
}

public IConfiguration Configuration { get; }

public void ConfigureServices(IServiceCollection services)
{
string connectionString = Configuration["ConnectionStrings:SpannerCapDB"];

services.AddCap(x =>
{
x.UseGoogleSpanner(connectionString);
x.UseGooglePubSub(cfg =>
{
cfg.ProjectId = Configuration["Pubsub:ProjectId"];
cfg.SubscriptionId = Configuration["Pubsub:SubscriptionId"];
cfg.VerificationToken = Configuration["Pubsub:VerificationToken"];
cfg.TopicId = Configuration["Pubsub:TopicId"];
});
x.UseDashboard();
});
//services.AddSingleton<INodeDiscoveryProvider>();
services.AddControllers();
}

public void Configure(IApplicationBuilder app)
{
app.UseRouting();
app.UseEndpoints(endpoints =>
{
endpoints.MapControllers();
});
}
}
}
18 changes: 18 additions & 0 deletions samples/Sample.GcpPubSub.GoogleSpanner/appsettings.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
{
"Pubsub": {
"ProjectId": "<project-id>",
"VerificationToken": "<gcp-token>",
"TopicId": "<gcp-topic-id>",
"SubscriptionId": "<gcp-subscription-id>"
},
"ConnectionStrings": {
"SpannerDB": "Data Source=projects/{project}/instances/{instance}/databases/{database}",
"SpannerCapDB": "Data Source=projects/{project}/instances/{instance}/databases/{database}"
},
"Logging": {
"IncludeScopes": false,
"LogLevel": {
"Default": "Debug"
}
}
}
23 changes: 23 additions & 0 deletions src/DotNetCore.CAP.GooglePubSub/CAP.GooglePubSubOptions.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
// Copyright (c) .NET Core Community. All rights reserved.
// Licensed under the MIT License. See License.txt in the project root for license information.

// ReSharper disable once CheckNamespace
namespace DotNetCore.CAP
{
/// <summary>
/// Provides programmatic configuration for the CAP Google Cloud Platform Pub/Sub project.
/// </summary>
public class GooglePubSubOptions
{
/// <summary>
/// The GCP <c>Project</c> ID.
/// </summary>
public string ProjectId { get; set; }

public string TopicId { get; set; } = "CAP";

public string VerificationToken { get; set; }

public string SubscriptionId { get; set; }
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
// Copyright (c) .NET Core Community. All rights reserved.
// Licensed under the MIT License. See License.txt in the project root for license information.

using System;
using DotNetCore.CAP.GooglePubSub;
using DotNetCore.CAP.Transport;
using Microsoft.Extensions.DependencyInjection;

// ReSharper disable once CheckNamespace
namespace DotNetCore.CAP
{
internal sealed class GooglePubSubOptionsExtension : ICapOptionsExtension
{
private readonly Action<GooglePubSubOptions> _configure;

public GooglePubSubOptionsExtension(Action<GooglePubSubOptions> configure)
{
_configure = configure;
}

public void AddServices(IServiceCollection services)
{
services.AddSingleton<CapMessageQueueMakerService>();

services.Configure(_configure);

services.AddSingleton<IConsumerClientFactory, GooglePubSubConsumerClientFactory>();
services.AddSingleton<ITransport,GooglePubSubTransport>();
}
}
}
42 changes: 42 additions & 0 deletions src/DotNetCore.CAP.GooglePubSub/CAP.Options.Extensions.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
// Copyright (c) .NET Core Community. All rights reserved.
// Licensed under the MIT License. See License.txt in the project root for license information.

using System;
using DotNetCore.CAP;

// ReSharper disable once CheckNamespace
namespace Microsoft.Extensions.DependencyInjection
{
public static class CapOptionsExtensions
{
/// <summary>
/// Configuration to use Google Cloud Pub/Sub in CAP.
/// </summary>
/// <param name="options">CAP configuration options</param>
/// <param name="projectId">The GCP <c>Project</c> ID.</param>
public static CapOptions UseGooglePubSub(this CapOptions options,string projectId)
{
return options.UseGooglePubSub(opt =>
{
opt.ProjectId = projectId;
});
}

/// <summary>
/// Configuration to use Google Cloud Pub/Sub in CAP.
/// </summary>
/// <param name="options">CAP configuration options</param>
/// <param name="configure">Provides programmatic configuration for the Google Cloud Pub/Sub.</param>
public static CapOptions UseGooglePubSub(this CapOptions options, Action<GooglePubSubOptions> configure)
{
if (configure == null)
{
throw new ArgumentNullException(nameof(configure));
}

options.RegisterExtension(new GooglePubSubOptionsExtension(configure));

return options;
}
}
}
23 changes: 23 additions & 0 deletions src/DotNetCore.CAP.GooglePubSub/DotNetCore.CAP.GooglePubSub.csproj
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
<Project Sdk="Microsoft.NET.Sdk">

<PropertyGroup>
<TargetFramework>netstandard2.1</TargetFramework>
<AssemblyName>DotNetCore.CAP.GooglePubSub</AssemblyName>
<PackageTags>$(PackageTags);PubSub;GCP;Google Cloud PubSub</PackageTags>
</PropertyGroup>

<PropertyGroup>
<WarningsAsErrors>NU1605;NU1701</WarningsAsErrors>
<NoWarn>NU1701;CS1591</NoWarn>
<DocumentationFile>bin\$(Configuration)\netstandard2.0\DotNetCore.CAP.GooglePubSub.xml</DocumentationFile>
</PropertyGroup>

<ItemGroup>
<PackageReference Include="Google.Cloud.PubSub.V1" Version="2.1.0" />
</ItemGroup>

<ItemGroup>
<ProjectReference Include="..\DotNetCore.CAP\DotNetCore.CAP.csproj" />
</ItemGroup>

</Project>
Loading

0 comments on commit 1c79b60

Please sign in to comment.