Class sharing between byte-buddy interceptors/advices - byte-buddy

I am trying to pass monitoring/tracing information through all my external calls in my java application.
To make it transparent, I'm trying to use byte-buddy but have some troubles getting it to work.
To trace every incoming (http) request, I intercept HttpServlet.service(), extract the token header from the HttpServletRequest and put it in a static ThreadLocal in a class named TokenHolder.
To trace every outgoing (http) request, I intercept HttpURLConnection and add the token header I get from the same ThreadLocal (TokenHolder).
The problem I have is that TokenHolder seems to be initialized twice and my 2 interceptors are not writing-to/reading-from the same ThreadLocal and I can't find a way to do it.
I suppose the problem is that HttpURLConnection lives in the bootclasspath while the servlet API does not.
Bonus question: is it possible to intercept URL.openConnection()? That was my first idea but I never could do it because I suppose the URL class is loaded before the agent (because of URLClassLoader) but I don't know if there are workarounds to that.

Yes, you can register a RedefinitionStrategy where Byte Buddy transforms previously loaded classes. To do so, you do however need to avoid adding methods or fields. This can typically be done by using Advice only.
You are also right that classes need to live on the bootstrap loader. You can inject classes into the bootstrap loader by placing them in a jar and using the designated method in the Instrumentation interface.

Related

Change implementation of ninject dependency after singleton instantiation

So, I have a viewmodel class in a xamarin project that I inject some dependencies into via ninject binding on app start. One of these is an IDialogService.
When my MainPage in my application changes it raises a property changed event and I rebind the implementation of the dialog service since it is tied to the MainPage.
If my viewmodel has already been created with lets say DialogServiceA and then when MainPage changes we rebind to DialogServiceB, will my viewmodel be using service A or B? I think it is using A and therefore does not display in the UI because it is tied to a MainPage that no longer exists.
So, if this is the case how can I dynamically change my dialog service but then update classes that have already been instantiated without changing everything to get the current dialog service from the container every time its used (therefore not injecting it at all really, and doing more of a servicelocator)
Also, if this approach is completely wrong, set me straight.
You're right. Re-configuration of the container does not affect already instanciated objects.
If you want to change dependencies without re-instanciating the dependent (parent ViewModel) there's a few possibilities for you:
use a factory to instanciate the service every time. Implement an Abstract Factory (Site by Mark Seeman) or use Ninject.Extensions.Factory to do so
instead of injecting a service directly, inject an adapter. The adapter then redirects the request to the currently appropriate service. To do so, either all service can be injected into the adapter, or you can use a factory as with the possibility above.
instead of inject a service directly, inject a proxy. The proxy is quite similar to the adapter, but instead of coding every method / property redirection specifically, you code a generic redirect by an interceptor. Here's a tutorial on castle dynamic proxy
At the end of the day, however, i believe you'll also need a way to manage when to change the service / which it should be. There's probably a design alternative which doesn't rely on exchanging objects in such a manner.. which would make it an easier (and thus better?) design.
Edit: i just saw that you also tagged the question as xamarin-forms. In that case it most likely won't be an option to use either a dynamic proxy nor ninject.extensions.factory (it relies on dynamic proxies, too). Why? dynamic proxy / IL emitting is not supported on all platforms, AFAIR specifically on Apple devices this can't be done.

Ninject: What is MvcModule: GlobalKernelRegistrationModule<OnePerRequestHttpModule>?

I'm seeing Ninject source code, I cannot understand the MvcModule (source code in github).
Why the OnePerRequestHttpModule stand as a generic template type? What does it mean for?
As you undoubtedly know, Ninject.Web.Common defines InRequestScope. This scope is for the activations that should live for the lifetime of a single http request. When an http request is finished, you might want to clear your activation cache for this request, but how do you know that the request has ended?
Well, the usual way of finding out is creating an Http Module and subscribing for the EndRequest event.
Suppose you've done that. Now you need to implement the event handler. In the event handler you want to clear your activation cache for this request, but how does the handler know where this activation cache is located? Ultimately this cache is part of ninject kernel, so if only you could get access to that.
But that's no problem, right? You are the implementer, so why don't you wire up your HttpModule during your kernel set-up?
Unfortunately there are quite a few problems with this approach. First, HttpModules have to be registered during the pre application startup up phase and there is no guarantee that your kernel will be created at that time. More importantly, what if you have multiple kernels? Does each of these going to create a new instance of HTTP Module? Better to avoid that.
So this is what ninject does.
The GlobalKernelRegistration class is almost static class that keeps per domain collection of kernels. It has one instance method - protected void MapKernels(Action<IKernel> action). This method executes and action on every kernel in the list. The kernel lists are kept per registration type, such as OnePerRequestHttpModule.
So what you (as a ninject author) do is derive OnePerRequestHttpModule from GlobalKernelRegistration and then in your implementation of EndRequest event handler you use this.MapKernels to execute your code to clean up the activation cache for the request.
GlobalKernelRegistrationModule class is a simple class that registers your generic type parameter (in your case OnePerRequestHttpModule) and the current kernel in the registry (GlobalKernelRegistration).
When you derive your MvcModule from GlobalKernelRegistrationModule<OnePerRequestHttpModule> this registration happens automatically when your MvcModule is loaded into the kernel.
You also need to make sure that OnePerRequestHttpModule is registered as an Http Module which is usually done in the bootstrap code inside NinjectWebCommon.cs or in NinjectHttpApplication (if the project is not using webapi).
It deactivates objects InRequestScope after the request ended.

Passing client context using Unity in WCF service application

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.

Operation Contract with Different Source or Action Url

Our third party API provides two different web services but have identical methods, models. Nevertheless they only differ on URIs (Web Service Path, Action Path [Operation Contract].
So I have decided to:
Generate the code from their wsdl using VS.
Edit the namespacing to use the same and to be "Common" and not use the service reference instead i use the Reference.cs edited code.
Create a new proxy that will handle the correct URI of the service to use (wrapped the Reference.cs inside of it).
Now, I having an issue with the "Method1", because they have different Action Name. Having an exception of:
"Server did not recognize the value of
HTTP Header SOAPAction:
http://www.api.com/service/Method1"
I just notice that it the correct action name is: http://www.api.com/service1/Method1
The question now is, is there any configuration or behavior that i can use to correct the action name for each method for each service?
Or as long as they keep on adding contracts for each implementation of the API, i should also keep on adding the contracts for each, and just use the ChannelFactory for this?
Please help, thanks.
I ended up directly using the ChannelFactory when faced with the same problem
In my implementation, I had a base interface that had all the common methods to the 2 APIs. Then I had 2 seperate intefaces - one for each 3-rd party API version - that inherits from the base interface and adds methods and [OperationContract] attributes that varied between the two implementations.
When instantianting ChannelFactory<> I used one of the child interfaces. Helped to keep the consumer code clean and maintainable

Inject behavior into WCF After or During identification of WebGet Method to call

I am trying to solve a problem where i have a WCF system that i have built a custom Host, Factory host, instance providers and service behaviors to do authentication and dependency injection.
However I have come up with a problem at the authorisation level as I would like to do authorisation at the level of the method being called.
For example
[OperationContract]
[WebGet(UriTemplate = "/{ConstituentNumber}/")]
public Constituent GetConstituent(string ConstituentNumber)
{
Authorisation.Factory.Instance.IsAuthorised(MethodBase.GetCurrentMethod().Name, WebOperationContext.Current.IncomingRequest.Headers["Authorization"]);
return constituentSoapService.GetConstituentDetails(ConstituentNumber);
}
Basically I now have to copy the Call to IsAuthorised across every web method I have. This has two problems.
It is not very testable. I Have extracted the dependecies as best that I can. But this setup means that I have to mock out calls to the database and calls to the
WebOperationContext.
I Have to Copy that Method over and over again.
What I would like to know is, is there a spot in the WCF pipeline that enables me to know which method is about to be called. Execute the authorisation request. and then execute the method based on the true false value of the authorisation response.
Even better if i can build an attribute that will say how to evaluate the method.
One possible way to do what you want might be by intercepting requests with a custom IDispatchMessageInspector (or similar WCF extension point).
The trick there, however, is that all you get is the raw message, but not where it will be processed (i.e. the method name). With a bit of work, however, it should be possible to build a map of URIs/actions and the matching method names (this is how you'd do it for SOAP, though haven't tried it for WebGet/WebInvoke yet).