I am working to add the Hystrix CircuitBreaker pattern to an existing ASP.NET Core microservice, using Steeltoe CircuitBreaker, while maintaining the existing logging functionality with minimal refactoring (or as little as I can hope for).
Currently, an incoming HTTP request goes through the following layers:
Controller -> Service -> DerivedProvider -> AbstractProvider (and out to downstream service)
with Hystrix, I would like it to be:
Controller -> Service -> HystrixCommand<> -> DerviedProvider (via HystrixCommand's ExecuteAsync) -> AbstractProvider
Lots of context is stored in the providers, which is passed down through the layers via constructors, and logging is then happening in the AbstractProvider using that context, regardless of the outgoing call's result. The AbstractProvider also supports a fair amount of custom logic, such as optional pre and post execution callbacks. The post callback is invoked when a non-success response message is returned. Needless to say, changing the layers drastically doesn't appear easy to me, with my current understanding.
After reviewing the Hystrix documentation and Steeltoe CircuitBreaker documentation I am unclear if I can maintain, and access, the provider and its context within the HystrixCommand<>.RunFallbackAsync().
Perhaps the answer might relate to the lifecycle hooks you can override? Like onFallbackStart(HystrixInvokable commandInstance?
Ultimately, the goal is simply to make sure that any existing callback/logging functionality is not lost by wrapping these existing providers in a HystrixCommand. I am failing to understand how the HystrixCommand manages the providers and its context, and when/where you do or do not have access to them. Any suggestions or direction you can offer would be very much appreciated! Cheers!
Hystrix commands can be added to the service container or can be "new'd" (i.e. new MyHystrixCommand(...) whichever makes the most sense for you situation.
Remember that Hystrix commands can not be reused .. i.e. once you create and execute the command you must not try and reuse it.
Clearly if you are new'ng the HystrixCommand then you can define whatever arguments you want in the constructor and supply it with the right arguments (i.e. state) it needs to execute.
If you are injecting it into a controller or another service.. then before you use it... you can initialize it with whatever state you want using properties and then execute it.
Related
when I use a #RepositoryEventHandler then its methods are only invoked when the call into the repository comes in via HTTP.
Any reason why? OK, it is called Spring Data REST, but wouldn't it be VERY useful to invoke the handler too, when I call my Repo directly, not via HTTP?
Any way to invoke the handler when called directly (some magic AOP-stuff)?
Thank you
The reason for that is that the different persistence mechanisms covered by the different Spring Data modules already ship with event mechanisms. Depending on the one you use you now get a different mechanism to use.
Unfortunately this can't be unified as e.g. with JPA not all persistence operations need to go through the repository in the first place, as JPA automatically flushes all changes that were made to an attached instance on EntityManager flush. In this case even AOP on the repository instance doesn't help.
So you're basically left with two choices:
The events exposed by Spring Data REST for all repositories (as we basically don't make use of the automatic change tracking in JPA).
The store specific event mechanisms that will make sure that the persistence mechanism exposes events as documented.
I don't know if the solution I put below from other stackoverflow questions would seen as acceptable by #Olivier-drotbohm, but from:
SpringDataRest #RepositoryEventHandler not running when Controller is added
and
#RepositoryEventHandler events stop with #RepositoryRestController
you could inject/autowire the "ApplicationEventPublisher" and fire the BeforeCreateEvent/AfterCreateEvent manually to trigger the RepositoryEventHandler.
This is not a perfect solution, but I hope it is good enough for you (and we tested it: it works).
Problem:
I am building a four layer system with Ui, ServiceLayer, BizLayer and DataLayer. In line with good practice the ServiceLayer hides the BizLayer and DataLayer from the Ui, and of course the ServiceLayer doesn't know what the Ui Layer is.
My implementation is a single .NET application with each layer in its own assembly. I am using Autofac.MVC3 in my MVC3 Ui layer to do all the resolving classes used in a web request. I also include standard Autofac in my ServiceLayer so that it can handle the registration of all other layers in my application. At system startup I call a method to register all the types with Autofac. This does:
Register the lower levels by calling a module inside the ServiceLayer. That handles the registration of itself and all other assemblies using the standard NuGet Autofac package.
Then the Ui layer uses the NuGet Autofac.MVC package to register the various controllers and the IActionInvoker for Action Method injection.
My UnitOfWork class in my DataLayer is currently registered with InstancePerLifetimeScope because it is registered by the ServiceLayer which uses plain Autofac and knows nothing about InstancePerHttpRequest. However I read here that I should use InstancePerHttpRequest scope.
Question:
My question is, can I pass a lifetime scope around, i.e. could the MVC layer pass the InstancePerHttpRequest down to the service layer to use where needed? Alex Meyer-Gleaves seemed to suggest this was possible in his comment from this post below:
It is also possible to pass your own ILifetimeScopeProvider implementation to the AutofacDependencyResolver so that you can control the creation of lifetime scopes outside of the ASP.NET runtime
However the way he suggests seems to be MVC specific as ILifetimeScopeProvider is a MVC extension class. Can anyone suggest another way or is InstancePerLifetimeScope OK?
InstancePerHttpRequestScope is in fact a variant of InstantPerLifetimeScope. The first one only works in a request. If you want to execute some stuff on a background thread, it won't be available.
Like you I'm using autofac in as.net mvc and multiple app layers. I pass around the Container itself for the cases where I need to have a lifetime scope. I have a background queue which executes tasks. Each taks pretty much needs to have its own scope and to be exdecuted in a transaction. The Queue has an instance of IContainer (which is a singleton) and for every task, it begins a new scope and executes the task.
Db access and all are setup as INstancePerLifetimeScope in order to work in this case and I don't have aproblem when I use them in a controller.
With the help of MikeSW, Cecil Philips and Travis Illig (thanks guys) I have been put on the right track. My reading of the various posts, especially Alex Meyer-Gleaves post here, it seems that InstancePerLifetimeScope is treated as InstancePerHttpRequest when resolved by the Autofac.MVC package, within certain limitations (read Alex's post for what those limitations they). Alex's comment is:
Using InstancePerHttpRequest ensures that the service is resolved from the correct lifetime scope at runtime. In the case of MVC this is always the special HTTP request lifetime scope.
This means that I can safely register anything that needs a single instance for the whole htpp request as InstancePerLifetimeScope and it will work fine as long as I don't have child scoped items. That is fine and I can work with that.
I have a WCF service application (actually, it uses WCF Web API preview 5) that intercepts each request and extracts several header values passed from the client. The idea is that the 'interceptor' will extract these values and setup a ClientContext object that is then globally available within the application for the duration of the request. The server is stateless, so the context is per-call.
My problem is that the application uses IoC (Unity) for dependency injection so there is no use of singleton's, etc. Any class that needs to use the context receives it via DI.
So, how do I 'dynamically' create a new context object for each request and make sure that it is used by the container for the duration of that request? I also need to be sure that it is completely thread-safe in that each request is truly using the correct instance.
UPDATE
So I realize as I look into the suggestions below that part of my problem is encapsulation. The idea is that the interface used for the context (IClientContext) contains only read-only properties so that the rest of the application code doesn't have the ability to make changes. (And in a team development environment, if the code allows it, someone will inevitably do it.)
As a result, in my message handler that intercepts the request, I can get an instance of the type implementing the interface from the container but I can't make use of it. I still want to only expose a read-only interface to all other code but need a way to set the property values. Any ideas?
I'm considering implementing two interfaces, one that provides read-only access and one that allows me to initialize the instance. Or casting the resolved object to a type that allows me to set the values. Unfortunately, this isn't fool-proof either but unless someone has a better idea, it might be the best I can do.
Read Andrew Oakley's Blog on WCF specific lifetime managers. He creates a UnityOperationContextLifetimeManager:
we came up with the idea to build a Unity lifetime manager tied to
WCF's OperationContext. That way, our container objects would live
only for the lifetime of the request...
Configure your context class with that lifetime manager and then just resolve it. It should give you an "operation singleton".
Sounds like you need a Unity LifetimeManager. See this SO question or this MSDN article.
I have a WCF service that supports about 10 contracts, we have been supporting a client with all the business rules specific to this client now we have another client who will be using the exact same contracts (so we cannot change that) they will be calling the service exactly the same way the previous client called now the only way we can differentiate between the two clients is by one of the input parameters. Based on this input parameter we have to use a slightly different business logic – the logic for both the Client will be same 50% of the time the remainder will have different logic (across Business / DAL layers) . I don’t want to use if else statement in each of contract implementation to differentiate and reroute the logic also what if another client comes in. Is there a clean way of handling a situation like this. I am using framework 3.5. Like I said I cannot change any of the contracts (service / data contract ) or the current service calling infrastructure for the new client. Thanks
Can you possibly host the services twice and have the clients connect to the right one? Apart from that, you have to use some kind of if-else, I guess.
I can't say whether this is applicable to you, but we have solved a similar problem along this path:
We add a Header information to the message that states in which context some logic is called.
This information ends up in a RequestContext class.
We delegate responsibility of instantiating the implementation of the contract to a DI Container (in our case StructureMap)
We have defined a strategy how certain components are to be provided by the container:
There is a default for a component of some kind.
Attributes can be placed on specializations that denote for which type of request context this specialization should be used.
This is registered into the container through available mechanisms
We make a call to the Container by stating ObjectFactory.With(requestcontext).getInstance<CONTRACT>()
Dependencies of the service implementations are now resolved in a way that the described process is applied. That is, specializations are provided based ultimately on a request information placed in the header.
This is an example how this may be solvable.
I'm looking for some input for a challenge that I'm currently facing.
I have built a custom WIF STS which I use to identify users who want to call some WCF services that my system offers. The WCF services use a custom authorization manager that determines whether or not the caller has the required claims to invoke a given service.
Now, I'm building a WPF app. on top of those WCF services. I'm using the MVVM pattern, such that the View Model invokes the protected WCF services (which implement the Model). The challenge that I'm facing is that I do not know whether or not the current user can succesfully invoke the web service methods without actually invoking them. Basically, what I want to achieve is to enable/disable certain parts of the UI based on the ability to succesfully invoke a method.
The best solution that I have come up with thus far is to create a service, which based on the same business logic as the custom authorization policy manager will be able to determine whether or not a user can invoke a given method. Now, the method would have to passed to this service as a string, or actually two strings, ServiceAddress and Method (Action), and based on that input, the service would be able to determine if the current user has the required claims to access the method. Obviously, for this to work, this service would itself have to require a issued token from the same STS, and with the same claims, in order to do its job.
Have any of you done something similar in the past, or do you have any good ideas on how to do this?
Thanks in advance,
Klaus
This depends a bit on what claims you're requiring in your services.
If your services require the same set of claims, I would recommend making a service that does nothing but checks the claims, and call that in advance. This would let you "pre-authorize" the user, in turn enabling/disabling the appropriate portions of the UI. When it comes time to call your actual services, the user can just call them at will, and you've already checked that it's safe.
If the services all require different sets of claims, and there is no easy way to verify that they will work in advance, I would just let the user call them, and handle this via normal exception handling. This is going to make life a bit trickier, though, since you'll have to let the user try (and fail) then disable.
Otherwise, you can do something like what you suggested - put in some form of catalog you can query for a specific user. In addition to just passing a address/method, it might be nicer to allow you to just pass an address, and retrieve the entire set of allowed (or disallowed, whichever is smaller) methods. This way you could reduce the round trips just for authentication.
An approach that I have taken is a class that does the inspection of a ClaimSet to guard the methods behind the service. I use attributes to decorate the methods with type, resource and right property values. Then the inspection class has a Demand method that throws an exception if the caller's ClaimSet does not contain a Claim with those property values. So before any method code executes, the claim inspection demand is called first. If the method is still executing after the demand, then the caller is good. There is also a bool function in the inspection class to answer the same question (does the caller have the appropriate claims) without throwing an exception.
I then package the inspection class so that it is deployed with clients and, as long as the client can also get the caller's ClaimSet (which I provide via a GetClaimSet method on the service) then it has everything it needs to make the same evaluations that the domain model is doing. I then use the bool method of the claim inspection class in the CanExecute method of ICommand properties in my view models to enable/disable controls and basically keep the user from getting authorization exceptions by not letting them do things that they don't have the claims for.
As far as how the client knows what claims are required for what methods, I guess I leave that up to the client developer to just know. In general on my projects this isn't a big problem because the methods have been very classic crud. So if the method is to add an Apple, then the claim required is intuitively going to be Type = Apple, Right = Add.
Not sure if this helps your situation but it has worked pretty well on some projects I have done.