how to access Netty ChannelHandlerContext (or similar) within Jersey Resources - jersey

I am using Jersey + Netty as my framework for providing a RESTful API.
I would like to be able to access the ChannelHandlerContext, Channel (or similar), via a mechanism such as #Context as part of Resource methods - use cases include remote IP addresses. Similar to HttpHeaders and others.
Using #Context currently resources in the ChannelHandlerContext being null, therefore I am assuming something either doesn't exist (i.e. i have to write it?) or isn't setup to handle the injection.

This is now possible in 2.28 as SecurityContext may be cast to NettySecurityContext which has a getNettyContext() method.

Related

Spring cloud gateway support for services running on non-root URLs

Our spring cloud gateway needs to support services located in non-root URLs. For example:
https://thehost/api/theservice
I can configure the service using SimpleDiscoveryClient and SimpleReactiveDiscoveryClient or I can create my own implementation of the discovery clients. However, no matter what I do I'm still limited by this interface:
ServiceInstance
This interface has a nice method getUri(), which default implementation implements poorly and loses everything except host, port and scheme. I can provide my own implementation, but unfortunately this method:
LoadBalancerUriTools.doReconstructURI()
which the ReactiveLoadBalancerClientFilter relies on to reconstruct URI, ignores all the complexity of the original URI and in my example results in this:
https://thehost:443/theresource
Note that it hardcodes the port for https URI as well, which is not good either.
I'd like this functionality to respect the original configuration and construct the following instead:
https://thehost/api/theservice/theresource
Is there way to achieve a proper service URL handling? Maybe there's a way to customize the behavior somehow?

Connection pooling in spring WebClient

I want to use Spring WebClient in a project to consume some external web service.
Can WebClient object be singleton or shared among all threads (requests)?
If my application is going to get millions of requests per second, then do I need to pool WebClient Objects? If yes, I am unable to find any documentation or examples.
Does mono.block() internally work similar to future.get() or latch.await()?
The WebClient is a non-blocking implementation of a REST client built on the Reactive Stack, so I guess the only issue you should focus on is to complete a non-blocking call.
Can WebClient object be a singleton or shared among all threads (requests)?
A standard way I have seen everywhere is to inject WebClient as a bean. I find no reason to do any different.
#Autowired
WebClient webClient;
If my application is going to get millions of requests per second, then do I need to pool WebClient Objects?
That's a lot! This should definitely need to be solved with service replication, load-balancers, bulkhead, etc. In terms of the client itself, see the following performance of reactive client using newer versions of Spring: WebFlux Reactive Programming Performance Test. Moreover, that is the expected maximal throughput?
Does mono.block() internally work similar to future.get() or latch.await()?
Yes, it does.

How to create a dynamic dispatch client using apache CXF

I want to use apache CXF to build my client. Unfortunately, I do not see a way by which it allows me to dispatch a client dynamically based on the port and operation name. If there is a huge wsdl, JaxWsDynamicClientFactory would create classes for all services contained in it which is an overhead that I'd like to avoid.
I found a similar implementation in JAX-WS. Is there any api in CXF that would do the same?
CXF supports the JAX-WS Dispatch API, which is a low-level interface to SOAP.
That means you can create a Dispatch that represents a particular port-type on a service and then invoke the methods by building the message
// Set things up...
Service s = ...
Dispatch<DOMSource> dispatch =
s.createDispatch(portName, // << a QName!
DOMSource.class, Service.Mode.PAYLOAD);
// Construct the request message here
Node response = dispatch.invoke(new DOMSource(request)).getNode();
// Understand the response message here
Of course, that then means you've got to work with the DOM for the messages, which is highly annoying. I think that's the part of tooling that's really worthwhile.

Reuse jax-ws client proxies for different addresses

I have a bunch of web services servers (around 200) running on the same machine which expose the same service on different ports.
I have a client which perform tasks which include calling the service on different servers.
Something like:
while (true) {
task = readTask();
runHelloService(task.serverAddress)
}
I was wondering what is the best way to generate the HelloService client proxy.
Can I generate one and replace the target address before each call?
Should i generate a client per server (which means 200 client proxies) and use the relevant one?
I will probably want to run the above loop concurrently on several threads.
Currently I have only one proxy which is generated by spring and cxf with the jaxws:client declaration.
This is an interesting use case. I believe that changing the endpoint whilst sharing the proxy amongst multiple threads will not work. There is a one-to-one relationship between a client proxy and a conduit definition. Changes to a conduit are explicitly not thread safe.
I recommend eschewing Spring configuration altogether to create client proxies and instead use programmatic construction of the 200 client proxies.
See also Custom CXF Transport - Simplified Client Workflow.

Using a DataServiceContext with custom annotations

When using the an instance of the DataServiceContext class to materialise objects from an odata endpoint where the endpoint exposes some custom annotations, how does one get hold of the annotations data. I can't see any obvious extensibility points.
Custom annotations aren't exposed as a first-class concept on the DataServiceContext, but you can access them by hooking into the client response processing pipeline. This code will run after every entity is finished being read:
context.Configurations.ResponsePipeline.OnEntryEnded(
entryArgs => DoSomething(entryArgs.Entry.InstanceAnnotations));
Internally, the WCF Data Services Client uses a lower-level library called ODataLib (aka Microsoft.Data.OData on NuGet). The response and request pipelines allow you to dip into that lower level to get extra information when you need it, but you still get all the conveniences of using the full-fledged WCF Data Services client library. The classes like ODataEntry, ODataFeed, etc. that you work with on the processing pipelines are all part of the ODataLib API.

Resources