Skip to content

Commit

Permalink
Showing 19 changed files with 104 additions and 36 deletions.
6 changes: 3 additions & 3 deletions docs/guide/http/endpoints.md
Original file line number Diff line number Diff line change
@@ -15,7 +15,7 @@ public static ArithmeticResults PostJson(Question question)
};
}
```
<sup><a href='https://github.com/JasperFx/wolverine/blob/main/src/Http/WolverineWebApi/TestEndpoints.cs#L83-L95' title='Snippet source file'>snippet source</a> | <a href='#snippet-sample_simple_wolverine_http_endpoint' title='Start of snippet'>anchor</a></sup>
<sup><a href='https://github.com/JasperFx/wolverine/blob/main/src/Http/WolverineWebApi/TestEndpoints.cs#L85-L97' title='Snippet source file'>snippet source</a> | <a href='#snippet-sample_simple_wolverine_http_endpoint' title='Start of snippet'>anchor</a></sup>
<!-- endSnippet -->

In the method signature above, `Question` is the "request" type (the payload sent from the client to the server) and `Answer` is the "resource" type (what is being returned to the client).
@@ -36,7 +36,7 @@ public static Task<ArithmeticResults> PostJsonAsync(Question question)
return Task.FromResult(results);
}
```
<sup><a href='https://github.com/JasperFx/wolverine/blob/main/src/Http/WolverineWebApi/TestEndpoints.cs#L97-L111' title='Snippet source file'>snippet source</a> | <a href='#snippet-sample_simple_wolverine_http_endpoint_async' title='Start of snippet'>anchor</a></sup>
<sup><a href='https://github.com/JasperFx/wolverine/blob/main/src/Http/WolverineWebApi/TestEndpoints.cs#L99-L113' title='Snippet source file'>snippet source</a> | <a href='#snippet-sample_simple_wolverine_http_endpoint_async' title='Start of snippet'>anchor</a></sup>
<!-- endSnippet -->

The resource type is still `Answer`. Likewise, if an endpoint returns `ValueTask<Answer>`, the resource type
@@ -311,7 +311,7 @@ and register that strategy within our `MapWolverineEndpoints()` set up like so:
// Customizing parameter handling
opts.AddParameterHandlingStrategy<NowParameterStrategy>();
```
<sup><a href='https://github.com/JasperFx/wolverine/blob/main/src/Http/WolverineWebApi/Program.cs#L146-L151' title='Snippet source file'>snippet source</a> | <a href='#snippet-sample_adding_custom_parameter_handling' title='Start of snippet'>anchor</a></sup>
<sup><a href='https://github.com/JasperFx/wolverine/blob/main/src/Http/WolverineWebApi/Program.cs#L150-L155' title='Snippet source file'>snippet source</a> | <a href='#snippet-sample_adding_custom_parameter_handling' title='Start of snippet'>anchor</a></sup>
<!-- endSnippet -->

And lastly, here's the application within an HTTP endpoint for extra context:
2 changes: 1 addition & 1 deletion docs/guide/http/fluentvalidation.md
Original file line number Diff line number Diff line change
@@ -45,5 +45,5 @@ app.MapWolverineEndpoints(opts =>
// Wolverine.Http.FluentValidation
opts.UseFluentValidationProblemDetailMiddleware();
```
<sup><a href='https://github.com/JasperFx/wolverine/blob/main/src/Http/WolverineWebApi/Program.cs#L104-L126' title='Snippet source file'>snippet source</a> | <a href='#snippet-sample_using_configure_endpoints' title='Start of snippet'>anchor</a></sup>
<sup><a href='https://github.com/JasperFx/wolverine/blob/main/src/Http/WolverineWebApi/Program.cs#L108-L130' title='Snippet source file'>snippet source</a> | <a href='#snippet-sample_using_configure_endpoints' title='Start of snippet'>anchor</a></sup>
<!-- endSnippet -->
7 changes: 5 additions & 2 deletions docs/guide/http/json.md
Original file line number Diff line number Diff line change
@@ -100,7 +100,10 @@ builder.Services.AddScoped<IUserService, UserService>();
builder.Services.AddMarten(Servers.PostgresConnectionString)
.IntegrateWithWolverine();

builder.Host.UseWolverine();
builder.Host.UseWolverine(opts =>
{
opts.Discovery.IncludeAssembly(GetType().Assembly);
});

await using var host = await AlbaHost.For(builder, app =>
{
@@ -112,5 +115,5 @@ await using var host = await AlbaHost.For(builder, app =>
});
});
```
<sup><a href='https://github.com/JasperFx/wolverine/blob/main/src/Http/Wolverine.Http.Tests/using_newtonsoft_for_serialization.cs#L18-L38' title='Snippet source file'>snippet source</a> | <a href='#snippet-sample_use_newtonsoft_for_http_serialization' title='Start of snippet'>anchor</a></sup>
<sup><a href='https://github.com/JasperFx/wolverine/blob/main/src/Http/Wolverine.Http.Tests/using_newtonsoft_for_serialization.cs#L18-L41' title='Snippet source file'>snippet source</a> | <a href='#snippet-sample_use_newtonsoft_for_http_serialization' title='Start of snippet'>anchor</a></sup>
<!-- endSnippet -->
2 changes: 1 addition & 1 deletion docs/guide/http/mediator.md
Original file line number Diff line number Diff line change
@@ -43,7 +43,7 @@ app.MapPostToWolverine<CustomRequest, CustomResponse>("/wolverine/request");
app.MapDeleteToWolverine<CustomRequest, CustomResponse>("/wolverine/request");
app.MapPutToWolverine<CustomRequest, CustomResponse>("/wolverine/request");
```
<sup><a href='https://github.com/JasperFx/wolverine/blob/main/src/Http/WolverineWebApi/Program.cs#L155-L167' title='Snippet source file'>snippet source</a> | <a href='#snippet-sample_optimized_mediator_usage' title='Start of snippet'>anchor</a></sup>
<sup><a href='https://github.com/JasperFx/wolverine/blob/main/src/Http/WolverineWebApi/Program.cs#L159-L171' title='Snippet source file'>snippet source</a> | <a href='#snippet-sample_optimized_mediator_usage' title='Start of snippet'>anchor</a></sup>
<!-- endSnippet -->

With this mechanism, Wolverine is able to optimize the runtime function for Minimal API by eliminating IoC service locations
2 changes: 1 addition & 1 deletion docs/guide/http/middleware.md
Original file line number Diff line number Diff line change
@@ -49,7 +49,7 @@ Which is registered like this (or as described in [`Registering Middleware by Me
opts.AddMiddlewareByMessageType(typeof(FakeAuthenticationMiddleware));
opts.AddMiddlewareByMessageType(typeof(CanShipOrderMiddleWare));
```
<sup><a href='https://github.com/JasperFx/wolverine/blob/main/src/Http/WolverineWebApi/Program.cs#L132-L135' title='Snippet source file'>snippet source</a> | <a href='#snippet-sample_register_http_middleware_by_type' title='Start of snippet'>anchor</a></sup>
<sup><a href='https://github.com/JasperFx/wolverine/blob/main/src/Http/WolverineWebApi/Program.cs#L136-L139' title='Snippet source file'>snippet source</a> | <a href='#snippet-sample_register_http_middleware_by_type' title='Start of snippet'>anchor</a></sup>
<!-- endSnippet -->

The key point to notice there is that `IResult` is a "return value" of the middleware. In the case of an HTTP endpoint,
4 changes: 2 additions & 2 deletions docs/guide/http/multi-tenancy.md
Original file line number Diff line number Diff line change
@@ -261,7 +261,7 @@ public static string NoTenantNoProblem()
return "hey";
}
```
<sup><a href='https://github.com/JasperFx/wolverine/blob/main/src/Http/Wolverine.Http.Tests/multi_tenancy_detection_and_integration.cs#L365-L374' title='Snippet source file'>snippet source</a> | <a href='#snippet-sample_using_nottenanted' title='Start of snippet'>anchor</a></sup>
<sup><a href='https://github.com/JasperFx/wolverine/blob/main/src/Http/Wolverine.Http.Tests/multi_tenancy_detection_and_integration.cs#L379-L388' title='Snippet source file'>snippet source</a> | <a href='#snippet-sample_using_nottenanted' title='Start of snippet'>anchor</a></sup>
<!-- endSnippet -->

If the above usage completely disabled all tenant id detection or validation, in the case of an endpoint that *might* be
@@ -279,7 +279,7 @@ public static string MaybeTenanted(IMessageBus bus)
return bus.TenantId ?? "none";
}
```
<sup><a href='https://github.com/JasperFx/wolverine/blob/main/src/Http/Wolverine.Http.Tests/multi_tenancy_detection_and_integration.cs#L376-L385' title='Snippet source file'>snippet source</a> | <a href='#snippet-sample_maybe_tenanted_attribute_usage' title='Start of snippet'>anchor</a></sup>
<sup><a href='https://github.com/JasperFx/wolverine/blob/main/src/Http/Wolverine.Http.Tests/multi_tenancy_detection_and_integration.cs#L390-L399' title='Snippet source file'>snippet source</a> | <a href='#snippet-sample_maybe_tenanted_attribute_usage' title='Start of snippet'>anchor</a></sup>
<!-- endSnippet -->


4 changes: 2 additions & 2 deletions docs/guide/http/policies.md
Original file line number Diff line number Diff line change
@@ -66,7 +66,7 @@ app.MapWolverineEndpoints(opts =>
// Wolverine.Http.FluentValidation
opts.UseFluentValidationProblemDetailMiddleware();
```
<sup><a href='https://github.com/JasperFx/wolverine/blob/main/src/Http/WolverineWebApi/Program.cs#L104-L126' title='Snippet source file'>snippet source</a> | <a href='#snippet-sample_using_configure_endpoints' title='Start of snippet'>anchor</a></sup>
<sup><a href='https://github.com/JasperFx/wolverine/blob/main/src/Http/WolverineWebApi/Program.cs#L108-L130' title='Snippet source file'>snippet source</a> | <a href='#snippet-sample_using_configure_endpoints' title='Start of snippet'>anchor</a></sup>
<!-- endSnippet -->

The `HttpChain` model is a configuration time structure that Wolverine.Http will use at runtime to create the full
@@ -99,5 +99,5 @@ app.MapWolverineEndpoints(opts =>
// Wolverine.Http.FluentValidation
opts.UseFluentValidationProblemDetailMiddleware();
```
<sup><a href='https://github.com/JasperFx/wolverine/blob/main/src/Http/WolverineWebApi/Program.cs#L104-L126' title='Snippet source file'>snippet source</a> | <a href='#snippet-sample_using_configure_endpoints' title='Start of snippet'>anchor</a></sup>
<sup><a href='https://github.com/JasperFx/wolverine/blob/main/src/Http/WolverineWebApi/Program.cs#L108-L130' title='Snippet source file'>snippet source</a> | <a href='#snippet-sample_using_configure_endpoints' title='Start of snippet'>anchor</a></sup>
<!-- endSnippet -->
4 changes: 2 additions & 2 deletions docs/guide/http/querystring.md
Original file line number Diff line number Diff line change
@@ -24,7 +24,7 @@ public static string UsingQueryString(string name) // name is from the query str
return name.IsEmpty() ? "Name is missing" : $"Name is {name}";
}
```
<sup><a href='https://github.com/JasperFx/wolverine/blob/main/src/Http/WolverineWebApi/TestEndpoints.cs#L47-L55' title='Snippet source file'>snippet source</a> | <a href='#snippet-sample_using_string_value_as_query_string' title='Start of snippet'>anchor</a></sup>
<sup><a href='https://github.com/JasperFx/wolverine/blob/main/src/Http/WolverineWebApi/TestEndpoints.cs#L49-L57' title='Snippet source file'>snippet source</a> | <a href='#snippet-sample_using_string_value_as_query_string' title='Start of snippet'>anchor</a></sup>
<!-- endSnippet -->

And the corresponding tests:
@@ -69,5 +69,5 @@ public async Task use_decimal_querystring_hit()
body.ReadAsText().ShouldBe("Amount is 42.1");
}
```
<sup><a href='https://github.com/JasperFx/wolverine/blob/main/src/Http/Wolverine.Http.Tests/end_to_end.cs#L187-L226' title='Snippet source file'>snippet source</a> | <a href='#snippet-sample_query_string_usage' title='Start of snippet'>anchor</a></sup>
<sup><a href='https://github.com/JasperFx/wolverine/blob/main/src/Http/Wolverine.Http.Tests/using_querystring_parameters.cs#L131-L170' title='Snippet source file'>snippet source</a> | <a href='#snippet-sample_query_string_usage' title='Start of snippet'>anchor</a></sup>
<!-- endSnippet -->
4 changes: 2 additions & 2 deletions docs/guide/http/routing.md
Original file line number Diff line number Diff line change
@@ -21,7 +21,7 @@ public static string SimpleStringRouteArgument(string name)
return $"Name is {name}";
}
```
<sup><a href='https://github.com/JasperFx/wolverine/blob/main/src/Http/WolverineWebApi/TestEndpoints.cs#L27-L35' title='Snippet source file'>snippet source</a> | <a href='#snippet-sample_using_string_route_parameter' title='Start of snippet'>anchor</a></sup>
<sup><a href='https://github.com/JasperFx/wolverine/blob/main/src/Http/WolverineWebApi/TestEndpoints.cs#L29-L37' title='Snippet source file'>snippet source</a> | <a href='#snippet-sample_using_string_route_parameter' title='Start of snippet'>anchor</a></sup>
<!-- endSnippet -->

In the sample above, the `name` argument will be the value of the route argument
@@ -36,7 +36,7 @@ public static string IntRouteArgument(int age)
return $"Age is {age}";
}
```
<sup><a href='https://github.com/JasperFx/wolverine/blob/main/src/Http/WolverineWebApi/TestEndpoints.cs#L37-L45' title='Snippet source file'>snippet source</a> | <a href='#snippet-sample_using_numeric_route_parameter' title='Start of snippet'>anchor</a></sup>
<sup><a href='https://github.com/JasperFx/wolverine/blob/main/src/Http/WolverineWebApi/TestEndpoints.cs#L39-L47' title='Snippet source file'>snippet source</a> | <a href='#snippet-sample_using_numeric_route_parameter' title='Start of snippet'>anchor</a></sup>
<!-- endSnippet -->

The following code snippet from `WolverineFx.Http` itself shows the valid route
22 changes: 17 additions & 5 deletions docs/guide/messaging/broadcast-to-topic.md
Original file line number Diff line number Diff line change
@@ -34,10 +34,22 @@ await publisher.BroadcastToTopicAsync("color.purple", new Message1());
<sup><a href='https://github.com/JasperFx/wolverine/blob/main/src/Transports/RabbitMQ/Wolverine.RabbitMQ.Tests/send_by_topics.cs#L72-L79' title='Snippet source file'>snippet source</a> | <a href='#snippet-sample_send_to_topic' title='Start of snippet'>anchor</a></sup>
<!-- endSnippet -->

## Topic Sending as Cascading Message

## Scheduling Message Delivery

TODO -- write stuff here


Wolverine is pretty serious about enabling as many message handlers or HTTP endpoints as possible to be [pure functions](https://en.wikipedia.org/wiki/Pure_function)
where the unit testing is easier, so there's an option to broadcast messages to a particular topic as a cascaded message:

<!-- snippet: sample_cascaded_to_topic_message -->
<a id='snippet-sample_cascaded_to_topic_message'></a>
```cs
public class ManuallyRoutedTopicResponseHandler
{
public IEnumerable<object> Consume(MyMessage message, Envelope envelope)
{
// Go North now at the "direction" queue
yield return new GoNorth().ToTopic($"direction/{envelope.TenantId}");
}
}
```
<sup><a href='https://github.com/JasperFx/wolverine/blob/main/src/Samples/DocumentationSamples/CascadingSamples.cs#L175-L186' title='Snippet source file'>snippet source</a> | <a href='#snippet-sample_cascaded_to_topic_message' title='Start of snippet'>anchor</a></sup>
<!-- endSnippet -->
Original file line number Diff line number Diff line change
@@ -20,7 +20,7 @@ using var host = await Host.CreateDefaultBuilder()
.UseConventionalRouting();
}).StartAsync();
```
<sup><a href='https://github.com/JasperFx/wolverine/blob/main/src/Transports/RabbitMQ/Wolverine.RabbitMQ.Tests/Samples.cs#L225-L235' title='Snippet source file'>snippet source</a> | <a href='#snippet-sample_activating_rabbit_mq_conventional_routing' title='Start of snippet'>anchor</a></sup>
<sup><a href='https://github.com/JasperFx/wolverine/blob/main/src/Transports/RabbitMQ/Wolverine.RabbitMQ.Tests/Samples.cs#L281-L291' title='Snippet source file'>snippet source</a> | <a href='#snippet-sample_activating_rabbit_mq_conventional_routing' title='Start of snippet'>anchor</a></sup>
<!-- endSnippet -->

With the defaults from above, for each message that the application can handle
@@ -73,7 +73,7 @@ using var host = await Host.CreateDefaultBuilder()
});
}).StartAsync();
```
<sup><a href='https://github.com/JasperFx/wolverine/blob/main/src/Transports/RabbitMQ/Wolverine.RabbitMQ.Tests/Samples.cs#L240-L274' title='Snippet source file'>snippet source</a> | <a href='#snippet-sample_activating_rabbit_mq_conventional_routing_customized' title='Start of snippet'>anchor</a></sup>
<sup><a href='https://github.com/JasperFx/wolverine/blob/main/src/Transports/RabbitMQ/Wolverine.RabbitMQ.Tests/Samples.cs#L296-L330' title='Snippet source file'>snippet source</a> | <a href='#snippet-sample_activating_rabbit_mq_conventional_routing_customized' title='Start of snippet'>anchor</a></sup>
<!-- endSnippet -->


6 changes: 3 additions & 3 deletions docs/guide/messaging/transports/rabbitmq/deadletterqueues.md
Original file line number Diff line number Diff line change
@@ -36,7 +36,7 @@ using var host = await Host.CreateDefaultBuilder()

}).StartAsync();
```
<sup><a href='https://github.com/JasperFx/wolverine/blob/main/src/Transports/RabbitMQ/Wolverine.RabbitMQ.Tests/Samples.cs#L279-L301' title='Snippet source file'>snippet source</a> | <a href='#snippet-sample_overriding_rabbit_mq_dead_letter_queue' title='Start of snippet'>anchor</a></sup>
<sup><a href='https://github.com/JasperFx/wolverine/blob/main/src/Transports/RabbitMQ/Wolverine.RabbitMQ.Tests/Samples.cs#L335-L357' title='Snippet source file'>snippet source</a> | <a href='#snippet-sample_overriding_rabbit_mq_dead_letter_queue' title='Start of snippet'>anchor</a></sup>
<!-- endSnippet -->

::: warning
@@ -71,7 +71,7 @@ using var host = await Host.CreateDefaultBuilder()

}).StartAsync();
```
<sup><a href='https://github.com/JasperFx/wolverine/blob/main/src/Transports/RabbitMQ/Wolverine.RabbitMQ.Tests/Samples.cs#L306-L328' title='Snippet source file'>snippet source</a> | <a href='#snippet-sample_overriding_rabbit_mq_dead_letter_queue_interop_friendly' title='Start of snippet'>anchor</a></sup>
<sup><a href='https://github.com/JasperFx/wolverine/blob/main/src/Transports/RabbitMQ/Wolverine.RabbitMQ.Tests/Samples.cs#L362-L384' title='Snippet source file'>snippet source</a> | <a href='#snippet-sample_overriding_rabbit_mq_dead_letter_queue_interop_friendly' title='Start of snippet'>anchor</a></sup>
<!-- endSnippet -->

And lastly, if you don't particularly want to have any Rabbit MQ dead letter queues and you quite like the [database backed
@@ -100,7 +100,7 @@ using var host = await Host.CreateDefaultBuilder()

}).StartAsync();
```
<sup><a href='https://github.com/JasperFx/wolverine/blob/main/src/Transports/RabbitMQ/Wolverine.RabbitMQ.Tests/Samples.cs#L333-L355' title='Snippet source file'>snippet source</a> | <a href='#snippet-sample_disable_rabbit_mq_dead_letter_queue' title='Start of snippet'>anchor</a></sup>
<sup><a href='https://github.com/JasperFx/wolverine/blob/main/src/Transports/RabbitMQ/Wolverine.RabbitMQ.Tests/Samples.cs#L389-L411' title='Snippet source file'>snippet source</a> | <a href='#snippet-sample_disable_rabbit_mq_dead_letter_queue' title='Start of snippet'>anchor</a></sup>
<!-- endSnippet -->


4 changes: 2 additions & 2 deletions docs/guide/messaging/transports/rabbitmq/interoperability.md
Original file line number Diff line number Diff line change
@@ -36,7 +36,7 @@ using var host = await Host.CreateDefaultBuilder()
.DefaultIncomingMessage<SendEmail>();
}).StartAsync();
```
<sup><a href='https://github.com/JasperFx/wolverine/blob/main/src/Transports/RabbitMQ/Wolverine.RabbitMQ.Tests/Samples.cs#L360-L376' title='Snippet source file'>snippet source</a> | <a href='#snippet-sample_setting_default_message_type_with_rabbit' title='Start of snippet'>anchor</a></sup>
<sup><a href='https://github.com/JasperFx/wolverine/blob/main/src/Transports/RabbitMQ/Wolverine.RabbitMQ.Tests/Samples.cs#L416-L432' title='Snippet source file'>snippet source</a> | <a href='#snippet-sample_setting_default_message_type_with_rabbit' title='Start of snippet'>anchor</a></sup>
<!-- endSnippet -->

With this setting, there is **no other required headers** for Wolverine to process incoming messages. However, Wolverine will be
@@ -128,7 +128,7 @@ using var host = await Host.CreateDefaultBuilder()
.DefaultIncomingMessage<SendEmail>();
}).StartAsync();
```
<sup><a href='https://github.com/JasperFx/wolverine/blob/main/src/Transports/RabbitMQ/Wolverine.RabbitMQ.Tests/Samples.cs#L381-L400' title='Snippet source file'>snippet source</a> | <a href='#snippet-sample_registering_custom_rabbit_mq_envelope_mapper' title='Start of snippet'>anchor</a></sup>
<sup><a href='https://github.com/JasperFx/wolverine/blob/main/src/Transports/RabbitMQ/Wolverine.RabbitMQ.Tests/Samples.cs#L437-L456' title='Snippet source file'>snippet source</a> | <a href='#snippet-sample_registering_custom_rabbit_mq_envelope_mapper' title='Start of snippet'>anchor</a></sup>
<!-- endSnippet -->


4 changes: 2 additions & 2 deletions docs/guide/messaging/transports/rabbitmq/listening.md
Original file line number Diff line number Diff line change
@@ -38,7 +38,7 @@ using var host = await Host.CreateDefaultBuilder()
});
}).StartAsync();
```
<sup><a href='https://github.com/JasperFx/wolverine/blob/main/src/Transports/RabbitMQ/Wolverine.RabbitMQ.Tests/Samples.cs#L84-L115' title='Snippet source file'>snippet source</a> | <a href='#snippet-sample_listening_to_rabbitmq_queue' title='Start of snippet'>anchor</a></sup>
<sup><a href='https://github.com/JasperFx/wolverine/blob/main/src/Transports/RabbitMQ/Wolverine.RabbitMQ.Tests/Samples.cs#L140-L171' title='Snippet source file'>snippet source</a> | <a href='#snippet-sample_listening_to_rabbitmq_queue' title='Start of snippet'>anchor</a></sup>
<!-- endSnippet -->

To optimize and tune the message processing, you may want to read more about the [Rabbit MQ prefetch count and prefetch
@@ -80,5 +80,5 @@ using var host = await Host.CreateDefaultBuilder()
});
}).StartAsync();
```
<sup><a href='https://github.com/JasperFx/wolverine/blob/main/src/Transports/RabbitMQ/Wolverine.RabbitMQ.Tests/Samples.cs#L84-L115' title='Snippet source file'>snippet source</a> | <a href='#snippet-sample_listening_to_rabbitmq_queue' title='Start of snippet'>anchor</a></sup>
<sup><a href='https://github.com/JasperFx/wolverine/blob/main/src/Transports/RabbitMQ/Wolverine.RabbitMQ.Tests/Samples.cs#L140-L171' title='Snippet source file'>snippet source</a> | <a href='#snippet-sample_listening_to_rabbitmq_queue' title='Start of snippet'>anchor</a></sup>
<!-- endSnippet -->
6 changes: 3 additions & 3 deletions docs/guide/messaging/transports/rabbitmq/object-management.md
Original file line number Diff line number Diff line change
@@ -30,7 +30,7 @@ using var host = await Host.CreateDefaultBuilder()
opts.PublishAllMessages().ToRabbitExchange("exchange1");
}).StartAsync();
```
<sup><a href='https://github.com/JasperFx/wolverine/blob/main/src/Transports/RabbitMQ/Wolverine.RabbitMQ.Tests/Samples.cs#L170-L190' title='Snippet source file'>snippet source</a> | <a href='#snippet-sample_publish_to_rabbitmq_routing_key' title='Start of snippet'>anchor</a></sup>
<sup><a href='https://github.com/JasperFx/wolverine/blob/main/src/Transports/RabbitMQ/Wolverine.RabbitMQ.Tests/Samples.cs#L226-L246' title='Snippet source file'>snippet source</a> | <a href='#snippet-sample_publish_to_rabbitmq_routing_key' title='Start of snippet'>anchor</a></sup>
<!-- endSnippet -->

At development time -- or occasionally in production systems -- you may want to have the messaging
@@ -47,7 +47,7 @@ using var host = await Host.CreateDefaultBuilder()
.AutoPurgeOnStartup();
}).StartAsync();
```
<sup><a href='https://github.com/JasperFx/wolverine/blob/main/src/Transports/RabbitMQ/Wolverine.RabbitMQ.Tests/Samples.cs#L195-L204' title='Snippet source file'>snippet source</a> | <a href='#snippet-sample_autopurge_rabbitmq' title='Start of snippet'>anchor</a></sup>
<sup><a href='https://github.com/JasperFx/wolverine/blob/main/src/Transports/RabbitMQ/Wolverine.RabbitMQ.Tests/Samples.cs#L251-L260' title='Snippet source file'>snippet source</a> | <a href='#snippet-sample_autopurge_rabbitmq' title='Start of snippet'>anchor</a></sup>
<!-- endSnippet -->

Or you can be more selective and only have certain queues of volatile messages purged
@@ -64,7 +64,7 @@ using var host = await Host.CreateDefaultBuilder()
.DeclareQueue("queue2", q => q.PurgeOnStartup = true);
}).StartAsync();
```
<sup><a href='https://github.com/JasperFx/wolverine/blob/main/src/Transports/RabbitMQ/Wolverine.RabbitMQ.Tests/Samples.cs#L210-L220' title='Snippet source file'>snippet source</a> | <a href='#snippet-sample_autopurge_selective_queues' title='Start of snippet'>anchor</a></sup>
<sup><a href='https://github.com/JasperFx/wolverine/blob/main/src/Transports/RabbitMQ/Wolverine.RabbitMQ.Tests/Samples.cs#L266-L276' title='Snippet source file'>snippet source</a> | <a href='#snippet-sample_autopurge_selective_queues' title='Start of snippet'>anchor</a></sup>
<!-- endSnippet -->

Wolverine's Rabbit MQ integration also supports the [Oakton stateful resource](https://jasperfx.github.io/oakton/guide/host/resources.html) model,
6 changes: 3 additions & 3 deletions docs/guide/messaging/transports/rabbitmq/publishing.md
Original file line number Diff line number Diff line change
@@ -23,7 +23,7 @@ using var host = await Host.CreateDefaultBuilder()
opts.PublishAllMessages().ToRabbitQueue("special", queue => { queue.IsExclusive = true; });
}).StartAsync();
```
<sup><a href='https://github.com/JasperFx/wolverine/blob/main/src/Transports/RabbitMQ/Wolverine.RabbitMQ.Tests/Samples.cs#L120-L137' title='Snippet source file'>snippet source</a> | <a href='#snippet-sample_publish_to_rabbitmq_queue' title='Start of snippet'>anchor</a></sup>
<sup><a href='https://github.com/JasperFx/wolverine/blob/main/src/Transports/RabbitMQ/Wolverine.RabbitMQ.Tests/Samples.cs#L176-L193' title='Snippet source file'>snippet source</a> | <a href='#snippet-sample_publish_to_rabbitmq_queue' title='Start of snippet'>anchor</a></sup>
<!-- endSnippet -->

## Publish to an Exchange
@@ -55,7 +55,7 @@ using var host = await Host.CreateDefaultBuilder()
});
}).StartAsync();
```
<sup><a href='https://github.com/JasperFx/wolverine/blob/main/src/Transports/RabbitMQ/Wolverine.RabbitMQ.Tests/Samples.cs#L142-L165' title='Snippet source file'>snippet source</a> | <a href='#snippet-sample_publish_to_rabbitmq_exchange' title='Start of snippet'>anchor</a></sup>
<sup><a href='https://github.com/JasperFx/wolverine/blob/main/src/Transports/RabbitMQ/Wolverine.RabbitMQ.Tests/Samples.cs#L198-L221' title='Snippet source file'>snippet source</a> | <a href='#snippet-sample_publish_to_rabbitmq_exchange' title='Start of snippet'>anchor</a></sup>
<!-- endSnippet -->

## Publish to a Routing Key
@@ -84,6 +84,6 @@ using var host = await Host.CreateDefaultBuilder()
opts.PublishAllMessages().ToRabbitExchange("exchange1");
}).StartAsync();
```
<sup><a href='https://github.com/JasperFx/wolverine/blob/main/src/Transports/RabbitMQ/Wolverine.RabbitMQ.Tests/Samples.cs#L170-L190' title='Snippet source file'>snippet source</a> | <a href='#snippet-sample_publish_to_rabbitmq_routing_key' title='Start of snippet'>anchor</a></sup>
<sup><a href='https://github.com/JasperFx/wolverine/blob/main/src/Transports/RabbitMQ/Wolverine.RabbitMQ.Tests/Samples.cs#L226-L246' title='Snippet source file'>snippet source</a> | <a href='#snippet-sample_publish_to_rabbitmq_routing_key' title='Start of snippet'>anchor</a></sup>
<!-- endSnippet -->

14 changes: 14 additions & 0 deletions src/Samples/DocumentationSamples/CascadingSamples.cs
Original file line number Diff line number Diff line change
@@ -169,4 +169,18 @@ public IEnumerable<object> Consume(MyMessage message)
}
}

#endregion


#region sample_cascaded_to_topic_message

public class ManuallyRoutedTopicResponseHandler
{
public IEnumerable<object> Consume(MyMessage message, Envelope envelope)
{
// Go North now at the "direction" queue
yield return new GoNorth().ToTopic($"direction/{envelope.TenantId}");
}
}

#endregion
17 changes: 17 additions & 0 deletions src/Testing/CoreTests/ConfiguredMessageExtensionsTests.cs
Original file line number Diff line number Diff line change
@@ -1,4 +1,7 @@
using JasperFx.Core;
using JasperFx.Core.Reflection;
using NSubstitute;
using TestingSupport;
using TestMessages;
using Xunit;

@@ -51,6 +54,20 @@ public void to_uri()
message.Destination.ShouldBe(destination);
message.DeliveryOptions.DeliverBy.HasValue.ShouldBeTrue();
}

[Fact]
public async Task to_topic()
{
var inner = new Message1();
var message = inner.ToTopic("blue");
message.Message.ShouldBeSameAs(inner);
message.Topic.ShouldBe("blue");

var bus = Substitute.For<IMessageContext>();
await message.As<ISendMyself>().ApplyAsync(bus);

await bus.Received().BroadcastToTopicAsync("blue", inner);
}


}
22 changes: 22 additions & 0 deletions src/Wolverine/ISendMyself.cs
Original file line number Diff line number Diff line change
@@ -121,8 +121,30 @@ public static RoutedToEndpointMessage<T> ToDestination<T>(this T message, Uri de
{
return new RoutedToEndpointMessage<T>(destination, message, options);
}

/// <summary>
/// Send a message to the supplied topic
/// </summary>
/// <param name="message"></param>
/// <param name="topic">The topic name for the underlying message broker</param>
/// <param name="options">Optional delivery options</param>
/// <typeparam name="T"></typeparam>
/// <returns></returns>
public static TopicMessage<T> ToTopic<T>(this T message, string topic, DeliveryOptions? options = null)
{
return new TopicMessage<T>(message, topic, options);
}
}

public record TopicMessage<T>(T Message, string Topic, DeliveryOptions? Options) : ISendMyself
{
ValueTask ISendMyself.ApplyAsync(IMessageContext context)
{
return context.BroadcastToTopicAsync(Topic, Message!);
}
}


/// <summary>
/// Wrapper for a cascading message that has delayed delivery
/// </summary>

0 comments on commit 88ea7fb

Please sign in to comment.