How do I add middleware to the Rebus message processing pipeline, before and after sending a message, and before and after handling a message? - rebus

I need this to simplify the implementation of the following typical, routine operations:
I would like to capture the user's context before sending the message and restores the user context before the message is handling, similar to how it was done in the following legacy example: https://github.com/rebus-org/RebusSamples/tree/master/old/UserContextHeaders
I would like to validate and deduplicating messages before handling them and log results after the message is handling.

As the question author correctly figured out, the Rebus.Events package provides readable and accessible ways of hooking into before/after messages are sent/received.
If that is sufficient, I would definitely go with that.
However, if e.g. you want to WRAP the entire processing of a single message inside a try/finally (which I recommend you when you restore the sending user's identity to process a message), you probably want to look at the native extension mechanism, which is based on decorators.
You can read the wiki page about extensibility about how to extend Rebus by decorating its pipelines.
For example, to do something with the current claims principal before and after handling a message, you can implement an "incoming pipeline step" like this:
[StepDocumentation("Write a nice descriptoion here")]
class MyIncomingStep : IIncomingStep
{
public async Task Process(IncomingStepContext context, Func<Task> next)
{
var originalPrincipal = ClaimsPrincipal.Current;
try
{
// establish user identity here
ClaimsPrincipal.Current = ...
// handle message
await next();
}
finally
{
ClaimsPrincipal.Current = originalPrincipal;
}
}
}
and then you can decorate Rebus' IPipeline with a "step injector", declaratively stating where in the pipeline you want the step to be inserted:
.Options(o => {
o.Decorate<IPipeline>(c =>
{
var pipeline = c.Get<IPipeline>();
var stepToInject = new MyIncomingStep();
return new PipelineStepInjector(pipeline)
.OnReceive(stepToInject, PipelineRelativePosition.Before, typeof(DispatchIncomingMessageStep));
});
})
and then – to makes things pretty – you can wrap the code above inside an extension method for OptionsConfigurer, making for a much prettier configuration syntax:
.Options(o => {
o.RestoreClaimsPrincipalWhenHandlingMessages();
})
or whatever you think it should be called :)
Everything works in an analogous fashion when sending messages, you just want to
//....
return new PipelineStepInjector(pipeline)
.OnSend(stepToInject, PipelineRelativePosition.Before, typeof(SerializeOutgoingMessageStep));
instead.

Related

Firebase authenticaiton error handling in unity

I have been struggling to find a solution for this and it seems that i'm doing something in the wrong way due to my limited knowladge, so here is the breakdown of the problem:
public void RegisterNewUser()
{
FetchRegisterInputValues();
if (CheckRegisterDataIntegrity())
{
_auth.CreateUserWithEmailAndPasswordAsync(_email, _password).ContinueWith(task => {
if (task.IsCanceled) {
Debug.LogError("CreateUserWithEmailAndPasswordAsync was canceled.");
return;
}
if (task.IsFaulted)
{
HandleRegistrationErrors(task.Exception);
return;
}
// Firebase user has been created.
Firebase.Auth.FirebaseUser newUser = task.Result;
Debug.LogFormat("Firebase user created successfully: {0} ({1})",
newUser.DisplayName, newUser.UserId);
});
}
else if (!CheckRegisterDataIntegrity())
{
HandleRegistrationErrors(new AggregateException("passwords do not match"));
}
}
above is the Registration function that I got straight from Firebase docs, it's very straightforward
the FetchRegisterInputValues(); function gets the email and passwords, the CheckRegisterDataIntegrity() compares the password with the password conformation in the form, and finally HandleRegistrationErrors(task.Exception); is meant to fire a popup panel to show the error,
this is how HandleRegistrationErrors(task.Exception); looks
private void HandleRegistrationErrors(AggregateException errMsg)
{
print("its here from the errors method " + errMsg.Message);
registerErrorPopup.OpenNotification();
registerErrorPopup.description = errMsg.Message;
}
it's using a UI asset from the asset store, the .OpenNotification(); starts the animation and pops it up, and then im just showing the message.
Now, I got two problems, the first is when there is an error encountered by Firebase and the if (task.IsFaulted) Condition is true, the HandleRegistrationErrors function should be called, right?. well that's exactly what happens, except only the print("it's here from the errors method " + errMsg.Message); line gets called and the rest of the function does not execute, I thought at first that its a problem with asset, but I tried doing it manually (created a native UI with unity and used SetActive() method to start the popUp), but again only print method executed, I think its because of the
CreateUserWithEmailAndPasswordAsync is Asynchronous and I should handle errors accordingly, but I really don't know how to go about it and there is no documentation that I could find.
The second problem is how to get the correct Error Message because of the task.Exception.Message always returns me a "One or more errors occurred". while the task.Exception itself gives the right message but it's not formatted correctly.
The first question is the easiest. To update your code with the minimal amount of effort, just replace ContinueWith with ContinueWithOnMainThread will force logic onto the main thread. Also, you should avoid calling task.Result if task.Exception is non-null as it will just raise the exception (see the related documentation).
For the threading related stuff: I go into much more detail about threading with Firebase and Unity here and you can read about the ContinueWithOnMainThread extension here.
For your second issue, the issue you're running into is that task.Exception is an AggregateException. I typically just attach a debugger and inspect this when debugging (or let Crashlytics analyze it in the field), and my UI state is only concerned about success or failure. If you want to inspect the error, the documentation I linked for AggregateException recommends doing something like:
task.Exception.Handle((e) => Debug.LogError($"Failed because {e}"));
Although I would play with .Flatten() or .GetBaseException() to see if those are easier to deal with.
I hope this helps!
--Patrick

PACT Consumer Driven setUP test data in Provider

I am executing some test whereby if Consumer set some ID or any Text which is not exists inside Provider Database then I want to do the below step in Provider Tests
Receive the PACT file with the information as what are the things needs to setup first
Then I will have my function , which will start inserting those unavailable data into DB
Then make API calls to , which will provide the Actual response.
Now I want to know , which field Consumer should use to let Provider know that , there is some prerequisite or pre setup needed before actual API call.
I saw the sample , where there is a setUp : InsertIntoDatabase but doesnot say that how to find which is the input supplied by consumer.
[TestMethod]
public void Ensure_OfferApi_HonoursPact_WithDeal_ForSendingLatestSoftOffer()
{
//Arrange
var outputter = new CustomOutputter();
var config = new PactVerifierConfig();
config.ReportOutputters.Add(outputter);
IPactVerifier pactVerifier = new PactVerifier(() => { InsertEventIntoDatabase(); }, () => { }, config);
pactVerifier
.ProviderState(
"Given the Offer Exist in Offer System I WANT TO See Latest SoftOffer",
setUp: InsertEventsIntoDatabase); // in case you want to insert something
//Act / Assert
using (var client = new HttpClient { BaseAddress = new Uri("http://localhost:9999") })
{
pactVerifier
.ServiceProvider("Offer API", client)
.HonoursPactWith("Consumer")
.PactUri(#"C:\TOSS\TestSample\log\deal-offer.json")
.Verify();
}
// Verify that verifaction log is also sent to additional reporters defined in the config
Assert.IsNotNull(outputter.Output);
}
Lets say the setup function is InsertEventsIntoDatabase and I want to add events what ever consumer is providing via PACT file. so that I dont need to update this code when ever Consumer changes the input.

Reactjs/Flux : When actions depend on async actions

Reactjs 0.14.0 , Vanilla Flux
Async Actions dependencies are a constant conceptual struggle. I've looked at this for months(dead serious) and every similar thread just doesn't make plain what I think is one of the hardest parts of the React/Flux learning curve.
The Problem:
If you want ActionB to be carried out one time directly after ActionA is done it's not really obvious at all where to put that to be updated by the View as the Flux pattern suggests( cause supposedly ActionA->ActionB chaining is an anti-pattern)
Note: maybe componentDidUpdate is the best that can be done, but it implies that ActionB can be called many times needlessly.
What I'm Trying to Do
So I'm using the common ActionA->WebAPI->Action->Dispatcher->Stores->View->ActionB
Which in most cases flows like this:
ActionA->WebAPI->Action(Async)->Dispatcher->Stores->View->ActionB
And often it is the case that ActionB is dependent on the Payload data of ActionA to be ready in it's store.(waitFor() was not designed for async situations like this supposedly.)
Example:
Main.js
componentWillMount: function(){
AuthActionCreators.checkForSession((loggedIn) => { //THIS IS A CALLBACK TO DO AN ACTION DEPENDENT ON USER DATA BEING IN THE USERSTORE
if(loggedIn){
AnotherActionCreators.updateAnotherStoreNowUserStuffIsInStores(this.props.someProp);//Action->Action(supposedly an anti-pattern)
}
});
},
AuthActionCreators.js
//Problem #1 Pointless Middle-Men Actions When Using The Pattern: ActionToServer->WebAPIUtils->ActionWithPayload
//Note: Many say to not call WebAPIUtils directly in Components
checkForSession: function(callback){
/* Notice how this action SEEMED to not need the dispatcher
because its a call to a server and I wait for a return to call an Action
that can actually dispatch a payload)*/
WebAPIUtils.hasSession(callback);
},
WebAPIUtils.js
//Problem #2 Async Actions calling dependent Actions
//ActionA -> ActionB is supposedly an anti pattern instead of :ActionA -> Dispatcher -> Store -> View -> ActionB
var hasSession = function(callbackDepOnUserData) {
let jwt = localStorage.getItem('jwt');
if (jwt) {
$.ajax(this.href, {
success: function(userData) {
ServerActionCreators.receiveUserPayloadInStore(userData);//Async Action that will actually sends a payload(I'm kinda okay with this action)
callbackDepOnUserData(true);//This callback(which is an action)feels like an anti-pattern but it the only way to call after dependent data is
//available in store
},
});
}
else{
console.log("does not have a session");
}
}

Servicestack async method (v4)

at this moment I am developing an android db access to a servicestack web api.
I need to show a message of "wait please..." when the user interacts with the db, I read some documentation:
Calling from client side an async method
But I cannot found how the async method must be implemented in the webapi, serverside.
Can you please share a link to the documentation? or a simple working sample?
I have this before trying to convert it to an async call.
var response = jsonClient.Send(new UsuarioLogin { Cuenta = txtCuenta.Text, P = txtPass.Text});
After some read, the latter code is converted into this:
var response = await jsonClient.SendAsync(new UsuarioLogin { Cuenta = txtCuenta.Text, P = txtPass.Text});
So, in the server side I have this(just an extract):
public object Post(UsuarioLogin request)
{
var _usuario = usuarioRepo.Login(_cuenta, _password);
if (_usuario != null)
{
if (_usuario.UsuarioPerfilId != 2 )
{
return new UsuarioLoginResponse { Ret = -3 };
}
How can I convert it to an async method?
Thanks in advance.
Server-side and client-side async are opaque and unrelated, i.e. an async call on the client works the same way irrespective if it's calling a sync or an async service, there's also no difference for sync client either. Essentially how the server is implemented has no effect on how it's called on the client.
To make an async service on the Server you just need to return a Task, you can look at the AsyncTaskTests for different examples of how to create an async Service.
There are a lot of benefits for making non-blocking async calls on the client since this can be called from the UI thread without blocking the UI. But there's less value of server-side async which adds a lot of hidden artificial complexity, is easy to deadlock, requires rewriting I/O operations to be async and in many cases wont improve performance unless I/O is the bottleneck, e.g. async doesn't help when calling a single RDBMS. You're going to get a lot more performance benefits from using Caching instead.

How to alter object server-side before save in Meteor

I am trying to run certain insert statements after a collection has been updated. For example, if a user adds an embedded document Location to their User document, I would like to also insert that embedded document into a separate Location collection. Is there a way to do this on the server side so that the operation is guaranteed to run?
If you're willing to use some code I wrote (https://gist.github.com/matb33/5258260), you can hook in like so:
EDIT: code is now part of a project at https://github.com/matb33/meteor-collection-hooks
var test = new Meteor.Collection("test");
if (Meteor.isServer) {
test.before("insert", function (userId, doc) {
doc.created = doc.created || Date.now();
});
test.before("update", function (userId, selector, modifier, options) {
if (!modifier.$set) modifier.$set = {};
modifier.$set.modified = Date.now();
});
test.after("update", function (userId, selector, modifier, options, previous) {
doSomething();
});
}
you would need to do it in a method.. you can keep latency compensation by implementing a client-side Method stub:
Calling methods on the client defines stub functions associated with
server methods of the same name. You don't have to define a stub for
your method if you don't want to. In that case, method calls are just
like remote procedure calls in other systems, and you'll have to wait
for the results from the server.
If you do define a stub, when a client invokes a server method it will
also run its stub in parallel. On the client, the return value of a
stub is ignored. Stubs are run for their side-effects: they are
intended to simulate the result of what the server's method will do,
but without waiting for the round trip delay. If a stub throws an
exception it will be logged to the console.
see my Meteor stub example here: https://stackoverflow.com/a/13145432/1029644

Resources