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

Non-Multi-Tenant Support for Notifications #29

Merged
merged 2 commits into from
Apr 27, 2023
Merged
Show file tree
Hide file tree
Changes from all 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
Original file line number Diff line number Diff line change
Expand Up @@ -14,10 +14,10 @@ public IdentityEventController(IWebhookNotifier<IdentityWebhook> notifier) {
this.notifier = notifier;
}

[HttpPost]
public async Task<IActionResult> PostAsync(UserCreatedEvent userCreated) {
[HttpPost("{tenantId}")]
public async Task<IActionResult> PostAsync([FromRoute] string tenantId, [FromBody] UserCreatedEvent userCreated) {
var eventInfo = new EventInfo("user", "created", userCreated);
var result = await notifier.NotifyAsync(userCreated.TenantId, eventInfo, HttpContext.RequestAborted);
var result = await notifier.NotifyAsync(eventInfo, HttpContext.RequestAborted);

// TODO: output the result of the notification

Expand Down
15 changes: 1 addition & 14 deletions samples/WebhookNotifierApp/Program.cs
Original file line number Diff line number Diff line change
Expand Up @@ -28,30 +28,17 @@ public static void Main(string[] args) {
});
});

builder.Services.AddMultiTenant<TenantInfo>()
.WithClaimStrategy("tenant")
.WithRouteStrategy("tenant")
.WithInMemoryStore(options => {
options.Tenants.Add(new TenantInfo {
Id = "339191991",
Identifier = "tenant1",
Name = "Tenant 1",
ConnectionString = builder.Configuration.GetConnectionString("WebhookSubscriptions")
});
});

builder.Services.AddWebhooks<IdentityWebhook>()
.AddNotifier(notifier => notifier
.UseWebhookFactory<UserCreatedWebhookFactory>()
.UseMongoSubscriptionResolver());

builder.Services.AddWebhookSubscriptions<MongoWebhookSubscription>()
.UseMongoDb(mongo => mongo.UseMultiTenant());
.UseMongoDb("WebhookSubscriptions");

var app = builder.Build();

app.UseMultiTenant();

// Configure the HTTP request pipeline.

app.UseHttpsRedirection();
Expand Down
17 changes: 11 additions & 6 deletions samples/WebhookNotifierApp/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -22,17 +22,22 @@ builder.Services.AddWebhooks<IdentityWebhook>()
.UseMongoSubscriptionResolver());

builder.Services.AddWebhookSubscriptions<MongoWebhookSubscription>()
.UseMongoDb(mongo => mongo.UseMultiTenant());
.UseMongoDb("WebhookSubscriptions");
```

* The `AddWebhooks` method activates the webhook services for the webhooks of type `IdentityWebhook`.
* The `IdentityWebhook` is a custom webhook type implemented in the scope of this sample, and it is used to send notifications to a webhook endpoint when a user is created.
* When calling the `AddWebhooks` method without arguments, the webhook services are activated for the default type, that is a `Webhook` oject.

* The `AddNotifier` method configures the default webhook notifier services, activating a default implementation of the sender service.

* The `UseWebhookFactory<UserCreatedWebhookFactory>` method registers the webhook factory that is used to create the webhook for the event `user.created`, that has a `UserCreatedEvent` as payload.
* More advanced implementations of an application might include a pipeline for the transormation of the incoming event, using the IEventDataFactory instances, to obtain an event that holds a Data property that can be handled by the webhook factory.

* The `UseMongoSubscriptionResolver` method configures the subscription resolver to use a MongoDB database to store the subscriptions - this comes by default with the Deveel.Webhooks.MongoDb package, and uses the `MongoWebhookSubscription` model to store and retrieve the subscriptions.
* The `AddWebhookSubscriptions` method activates the webhook subscription management services, using the `MongoWebhookSubscription` model to store and retrieve the subscriptions.
* The `UseMongoDb` method configures the MongoDB database as the storage for the subscriptions.
* The `UseMultiTenant` method configures the MongoDB database to be used in a multi-tenant application - this will require that Finbuckle.MultiTenant is configured in the application.
- Using MongoDB as the resolver of the subscriptions is a conventience choice for this sample application, but it can be replaced with any other implementation of the `IWebhookSubscriptionResolver` interface.
- Future implementations might use alternative methods to resolve subscriptions, like a Redis cache, a SQL storage or even a remote service.

## Notes
* The `AddWebhookSubscriptions` method activates the webhook subscription management services, using the `MongoWebhookSubscription` model to store and retrieve the subscriptions.

* **Multi-tenant Storage** - At the present time, the notifier is limited to the scenarios of webhook notifications to subscribers of a tenant, that requires the configuration of a multi-tenant storage. Future implementations will overcome this limitation, by allowing to store the subscriptions in a single-tenant storage, and to resolve the tenant of the subscriber at the time of the notification.
* The `UseMongoDb` method configures the MongoDB database as the storage for the subscriptions, using the given connection string.
Original file line number Diff line number Diff line change
@@ -1,4 +1,18 @@
using System;
// Copyright 2022-2023 Deveel
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

using System;

namespace Deveel.Webhooks {
/// <summary>
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,18 @@
namespace Deveel.Webhooks {
// Copyright 2022-2023 Deveel
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

namespace Deveel.Webhooks {
/// <summary>
/// Defines the options for the handling of a received webhook
/// from a single instance of a middleware of an application.
Expand Down
16 changes: 16 additions & 0 deletions src/Deveel.Webhooks.Service.MongoDb/Deveel.Webhooks.MongoDb.xml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Original file line number Diff line number Diff line change
@@ -1,4 +1,18 @@
namespace Deveel.Webhooks {
// Copyright 2022-2023 Deveel
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

namespace Deveel.Webhooks {
/// <summary>
/// A service that is used to convert a webhook to an
/// object that can be stored in a MongoDB database.
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,18 @@
using MongoDB.Driver;
// Copyright 2022-2023 Deveel
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

using MongoDB.Driver;

using MongoFramework;

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,29 @@ public static class WebhookNotifierBuilderExtensions {
/// </returns>
public static WebhookNotifierBuilder<TWebhook> UseMongoSubscriptionResolver<TWebhook>(this WebhookNotifierBuilder<TWebhook> builder)
where TWebhook : class {
return builder.UseDefaultSubscriptionResolver(typeof(MongoWebhookSubscription));
return builder
.UseDefaultSubscriptionResolver(typeof(MongoWebhookSubscription));
}

/// <summary>
/// Registers the MongoDB storage for resolving
/// webhook subscriptions to the notifier.
/// </summary>
/// <typeparam name="TWebhook">
/// The type of the webhook to be notified.
/// </typeparam>
/// <param name="builder">
/// The builder of the notifier service where to register
/// the resolver.
/// </param>
/// <returns>
/// Returns the builder to continue the configuration.
/// </returns>
public static WebhookNotifierBuilder<TWebhook> UseMongoTenantSubscriptionResolver<TWebhook>(this WebhookNotifierBuilder<TWebhook> builder)
where TWebhook : class {
return builder
.UseDefaultTenantSubscriptionResolver(typeof(MongoWebhookSubscription));
}

}
}
128 changes: 99 additions & 29 deletions src/Deveel.Webhooks.Service/Deveel.Webhooks.Service.xml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Loading