Accessing HTTP headers in GraphQL v17 - kotlin

Currently, I am using a custom context object in my GraphQL application. It is built via a class that extends GraphQLServletContextBuilder. In version 17, they have deprecated the use of the context object. Our app is using the custom context to get access to a variable in the HTTP header to make it available to resolvers via the DataFetchingEnvironment variable added to resolver functions.
I cannot seem to find how to replicate get access to HTTP headers in a resolver function outside of using a custom context object. We're using the built in servlet as part of the GraphQL kickstart package. The only way I've seen referenced so far on how to get anything into the new context is by setting the context via the ExecutionInput call. And that call is buried in their servlet.
The example I've seen:
var executionInput = ExecutionInput.newExecutionInput()
.query(query)
.variables(variables)
.graphQLContext(Map.of(CustomContext.class, context));
I don't necessarily need a custom context object (especially since it's eventually going away), I just need to know how to get access to an HTTP header inside a resolver function if a custom context is no longer the way to do it going forward.

Related

Can I create an object from the DI container/Lamar in .NET 6.0 minimal hosting, preserving singletons?

We have migrated from a windows Framework 4.7 application to .NET 6.0. Lamar is added for Dependency Injection. We are trying to finalize a refactor to the latest "one-file" program.cs but are getting unexpected System.ObjectDisposedException: 'Cannot access a disposed object'. In all cases, the error is against a Func<T> during object creation.
All our tests are running correctly using the same environment, except to start the tests we (a) create the DI container and (b) use the container to create an object that loads the singletons (from MongoDB):
Container = new Container(registry);
var start = Container.GetInstance<HomeService>();
In the program.cs, we configure the container, but do not get to see it created, or access it inside program.cs. Instead we create HomeService from IServiceProvider during the first use of a controller. Here we were trying to limit the lifecyle scope during creation:
using (var scope = _container.CreateScope())
{
scope.ServiceProvider.GetService<INewHomeService>();
}
For test, we use the same loading steps, except for adding controllers/mvc, of course (i.e. NOT using builder.Services.AddControllers(); and builder.Services.AddMvc() for (integration) testing).
We have tried a lot of different things, like creating our object independently to the startup, but that did not align the singletons. We can get functionality by using static instead, but then we lose dynamic change access.
Some great tips like Resolving instances with ASP.NET Core DI from within ConfigureServices and https://andrewlock.net/exploring-dotnet-6-part-10-new-dependency-injection-features-in-dotnet-6/ but I can't see the specific example to get the live container just after initial creation.
Is it possible that the issue is just the difference between the lifecycle management of the new .NET DI implementation? As this is configuration at the composition root, if we can configure as per our testing approach, it should solve our problem. Other solutions welcome!
The problem 'Cannot access a disposed object' was being caused by a lifecycle mismatch between retained context and the controller access. The code retained a handle on the state object, that had a handle on the factory using FUNC. As we did not configure the Func as anything, it was transient during the controller graph creation, and so was disposed when the controller request ended.
To solve, we tried registering ALL of the FUNC, per How to use Func<T> in built-in dependency injection which was a large task as we had a few factories throughout an old codebase.
The better solution was to create a factory in the composition root, and use an injected IserviceProvider (or with Lamar an IContainer). This is a simple workaround.
With our creation concern, the creation of our object after the completion of the startup process is working correctly as a lazy validation of the first controller access.

Class sharing between byte-buddy interceptors/advices

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.

Jax-rs URI call

I'm using HttpClient to access some api(Kubernetes) but I want to switch to jax-rs. Can the same functionality be achieved from Jax-rs? I was accessing the APIs in a java function. I'm a newbie to jax-rs and so far I know that it's use to create APIs.
Any help would be appreciable.
https://docs.oracle.com/javaee/7/api/javax/ws/rs/client/package-summary.html is the package summary for the javax.ws.rs.client package. with examples and directions below. Basically,
use a ClientBuilder to get a Client (with heavyweight/common stuff
like http/https parameters)
Create a WebTarget to denote an endpoint (including template placeholders)
Resolve that target (to get another WebTarget) with parameters
Invoke it to get and process the results (comes back in a Response object)

Autofac scope in ASP.NET Core appears to differ between middleware

When registering an object with Autofac and resolving in middleware and again in the MVC middleware via a controller, the instance is different. Instances are registered per lifetime scope.
I've popped a repro project here https://github.com/jakkaj/AutofacResolveIssue.
The app sets a value to the IUserService in the middleware, then try to read that value in the ValuesController later.
This same technique worked in older versions of ASP.NET with autofac. Any ideas what's going on?
Okay, so I made the mistake of injecting my dependency in to the constructor of the middleware.
You should inject dependencies into the Invoke.
The entire middleware object is singleton across all app instances!
Change builder registration to use SingleInstance() insted of InstancePerLifetimeScope(), So that every dependent component or call to Resolve() gets the same, shared instance.
builder.RegisterAssemblyTypes(typeof(UserService).GetTypeInfo().Assembly)
.Where(t => t.Name.EndsWith("Service") || t.Name.EndsWith("Repo"))
.AsImplementedInterfaces()
.SingleInstance();
Single Instance This is also known as ‘singleton.’ Using single instance scope, one instance is returned from all requests in
the root and all nested scopes. When you resolve a single
instance component, you always get the same instance no matter where
you request it.
Check the link for more details
http://docs.autofac.org/en/latest/lifetime/instance-scope.html#single-instance

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.