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

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?

Related

Spring boot Zuul server logging

I just created simple Zuul Proxy at the front end for our microservices environment but now I wanted to log all the entries into the log file which went through the proxy.
Do any properly which I need to enable to do this.
I assume an implementation of zuul as a regular spring boot driven microservice with a bunch of netflix's beans running under the hood.
In this case it can run on tomcat (probably for other services the idea is the same, but the technical implementation might be different).
So for tomcat:
As a first resort you can take advantage of tomcat feature of "access logs" that logs all the requests anyway. It also allows some level of customizations (what to log). The technical difficulty is that tomcat access log is not by default managed by logback, so you'll have to use some kind of adapter.
Here you can find ideas of how to resolve this technically and integrate access log with logback.
An another approach would be creating a Filter that will extract required pieces and log the request / response / whatever you want to log
Here is an example of creating a custom filter like this.
Of course I you also need to log something from response you should configure the filter type (see the java code example in the link)
One tip / caution: think about performance implications, so that this feature won't slow down the processing if the server is under high load of requests.

When Instrumenting Zuul gateway with Jaeger, all routes marked GET

I am using Zuul as an api-gateway in a spring-cloud micro-service app, so that every access to api-gateway/some-service/a_route is redirected to /a_route in a generic way (the discovery is backed by consul).
I am trying to use Jaeger to instrument this system. And at this point I am using opentracing-spring-web-autoconfigure, because I cannot upgrade my spring boot/cloud version easily (I am using1.4.5.RELEASE Camden.SR7). So I just added the dependency, created the Jaeger tracer and redirect it to the docker all in one collector.
I have begin by instrumenting the gateway and It somewhat works => It generate span on the gateway, but all the route are marked :
apigateway-service: GET
and there is no information concerning the forwarded route at this level, the full route itself is store in a tag : http.url
"http://localhost:8080/collection-service/collections/projects/"
To be useful I would prefer to have span named :
apigateway-service: GET collection-service/collections/projects/
Can this be configured somewhere ?
No, it cannot, but it wouldn't hurt to open an issue there with this suggestion.

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

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.

What are some Websphere Application Server "time-out definition" solutions?

My organization is using Websphere Application Server with RAD. My unit is developing Web Services that take data from a consumer, and often pass the data through other Web Services.
Currently, we have two ways of defining time-out's for data to be returned from called services:
Using the Spring framework
Websphere profile configuration
If we need to update the values using Spring we need to re-deploy our service. If we define them as JVM properties we need to do a JVM configuration change and 'restart/recycle/stop and start' the application.
My co-worker had it suggested to him that there may be some better solutions to this problem. I'm wondering if this is true, and if so what they are?
edit:
One option we might be considering is "Application Policy Sets". We'd like to know if this is a good alternative method:
can we define Spring to leverage policy sets
can we define multiple policy sets for an application when timeout values for different services called by our service are different?
Does this console change take affect at run-time, or do we need to recycle?
I suggest you use JAX-WS policy sets and bindings on WAS level, because it allows you to:
define policy set for each web service separately
in policy set define web service parameters, from HTTP transport parameters to WS-Security policies such as UsernameToken, digital signature and encryption
web services remain unchanged, the code remains the same
there is only one place where you change it: in WAS console, application is not changed
The only drawback here is that web services should be generated from RAD (you can use top-down or bottom-up approach).
Please see more details in this excellent 3-part DeveloperWorks tutorial

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.

Resources