How can I change feign client Logger.Level level dynamically? - java

I'm writing a spring boot app and use spring-cloud-starter-openfeign. It will be rather convenient to change logger level dynamically (through API call, for example) but I can't find the way to do it without creating a new feign client manually. It seems I need to get access to feign client implementation and to get its properties. There I probably can set a new Logger level but haven't managed to find the way ho to do this. Does anyone have ideas on how to do it, or someone might face similar issues?

Related

How do I connect to multiple databases/instances in GCP Spanner using Spring Cloud GCP Starter?

I am currently building an application that connects to a database on Spanner. The end goal of the application is to be able to connect to multiple databases (and possibly instances) so it can pull data using a GraphQL implementation. I am currently using Spring Cloud GCP Starter and Spring Cloud GCP Starter Data Spanner Maven packages to handle the configuration and data mapping. The Spring Cloud GCP Starter asks me to set up these lines in application.properties:
spring.cloud.gcp.spanner.instance-id=blah
spring.cloud.gcp.spanner.database=blah
spring.cloud.gcp.project-id=blah
Currently the application is set up to have models for each table, a repository (using SpannerRepository), and a controller.
The issue is I haven't been able to figure out how to change the configuration from the initial values when the application is run. Has anyone run into this and figured it out, or is it a limitation of my current implementation in Spring Cloud GCP Starter and I should look for different solution?
What I have tried:
Tried finding someone with the same issue online, nothing similar that I can find currently
Tried looking how to use/change the low level implementations things like SpannerTemplate that the autoconfiguration creates, but wasn't able to figure out how to change/use them
Tried finding a way to change application.properties and reloading during runtime, but after some research this seemed like a horrible idea
Any help would be greatly appreciated, thank you!
I finally found it!
Documentation
By creating a custom bean for DatabaseIdProvider you can set the projectId, instanceId, and database to whatever you would like. Confirmed to be working the SpannerRepository implementation as well.
If anyone else finds this, here is an example of how you would create your own implementation (how you go about feeding it a new database name is up to you):
#Bean
public DatabaseIdProvider databaseIdProvider() {
return () -> DatabaseId.of("projectId", "instanceId", "databaseName");
}
The DatabaseIdProvider interface extends Supplier<DatabaseId>. DatabaseId has a method (of) that creates the new DatabaseId that you need to connect to a different database/instance.

What is the right approach for extending Spring Cloud Config Client?

I want to replace Basic Authentication for Spring Cloud Config Server with oAuth implementation. Let's leave Config Server alone for now and focus on changes for Config Client. Obviously I don't want to write my own implementation for whole thing, but instead execute my own logic and fallback on standard Config Client. Also I have to pack my changes into library since I will use it in multiple micro-services.
Long story short I want to achieve following:
1a. Create custom Starter which will contain Spring Cloud Config Client as dependency. Is it even doable or necessary?
or
1b. Create custom Starter with only my custom logic which will be executed before Spring Cloud Config Client. In this case each micro-service will have Spring Cloud Config Client and custom Starter as dependencies. How can I manage execution order and inject custom logic results into Config Client?
2.Introduce new bootstrap settings. e.g. spring.cloud.config.custom.username and spring.cloud.config.custom.password (Optional).
3.Introduce custom annotation for custom Starter. e.g. #enableCustomConfigClient (Optional).
I started with building custom Starter with following code in /resources/META-INF/spring.factories:
# Bootstrap components
org.springframework.cloud.bootstrap.BootstrapConfiguration=\
com.example.greeter.config.ConfigClientBootstrapConfiguration
But this code invoked after profile is set, not the first thing like Config Client does.
Any suggestions and especially code samples are appreciated. Thanks!
Posting approach I chose for future reference.
Create new package which will be executed on top of / before Spring Cloud Config Client. Two main features here:
Create file src/main/resources/META-INF/spring.factories with org.springframework.cloud.bootstrap.BootstrapConfiguration={YOUR_CLASS}
In {YOUR_CLASS} apply custom logic. Don't forget to use #org.springframework.core.annotation.Order({YOUR_PRECEDENCE}) and fact that Ordered.LOWEST_PRECEDENCE will be executed first
Build jar from previous step and include it into your project (as local file or via artifactory)
Add Custom logic to Spring Cloud Config Server so it can use JWT.
Working example is here: https://github.com/ka4ok85/spring-cloud-config-client-jwt

hazelcast : changing configuration programatically doesnt work

I am unable to configure/change the Map(declared as part of hazelcast config in spring) properties after hazelcast instance start up. I am using hazelcast integrated with spring as hibernate second level cache. I am trying to configure the properties of map (like TTL) in an init method (PostConstruct annotated) which is called during spring bean initialization.
There is not enough Documentation , if there is please guide me to it.
Mean while i went through this post and found this Hazelcast MapStoreConfig ignored
But how does the management center changes the config, will it recreate a new instance again ?
Is hazelcast Instance light weight unlike session factory ? i assume not,
please share your thoughts
This is not yet supported. JCache is the only on-the-fly configuration data structure at the moment.
However you'll most probably be able to destroy a proxy (DistributedObject like IMap, IQueue, ...), reconfigure it and recreate it. Anyhow at the time of recreation you must make sure that every node sees the same configuration, for example by storing the configuration itself inside an IMap or something like that. You'll have to do some wrapping on your own.
PS: This is not officially supported and an implementation detail that might change at later versions!
PPS: This feature is on the roadmap for quite some time but didn't made it into a release version yet, it however is still expected to have full support at some time in the future.

Axis2 1.4 Client Side Concurrency Issue (Re-Using Stub)

I've been assigned a piece of work to investigate and propose a fix for an intermittent and (apparently) non-replicable bug which is causing web service calls to fail with the following error:
Message does not conform to configured policy [ TimestampPolicy(S) AuthenticationTokenPolicy(S) ]: No Security Header found
The application is the Spring based back end for an online public facing high traffic web site. The web services are accessed with a Axis2 1.4 client.
I think I've managed to track the issue down to a possible concurrency issue, but it doesn't seem to be tied to load exactly, the failure statistics don't support it (sometimes days with low load are worse than days with high load).
Anyway, all of client code for the web services is contained within a single class with a #Repository annotation. Classes in the wider application that need access to this WebServiceClient class have it declared at class scope with #Resource annotation where it is autowired in as required.
The problem as I see it is that in the WebServiceClient the stubs are declared at class scope like so:
private ValidationStub validationStub;
private CustInfoStub custInfoStub;
and are initialised in method scope when the web service is called
this.validationStub= new ValidationStub (this.url);
prepareStub(this.validationPort, username, password);
where the prepareStub method creates the security header and adds it as follows:
stub._getServiceClient().addHeader(element);
I think if I move the stubs from class scope to method scope it will solve the issue, like so:
ValidationStub validationStub = new ValidationStub(this.url);
Has anyone ran into a similar issue? I'm a bit concerned that making this change will have a performance impact.

Logging request-response from java service

I have generated some proxy classes that are consumed by a Java Service. (using WSDL2JAVA)
I need to find a way to log requests and responses whenever the proxy class invokes the respective external web service.
Is there any easy way to achieve this?
Thanks!
Silvio.
If you are using Axis, configure log4j like this:
log4j.rootLogger=ERROR
log4j.appender.axisLogFile=org.apache.log4j.RollingFileAppender
log4j.appender.axisLogFile.File=soap-messages.log
log4j.appender.axisLogFile.layout=org.apache.log4j.PatternLayout
log4j.appender.axisLogFile.layout.ConversionPattern=[%d{DATE} - %-5p] %m%n
log4j.logger.org.apache.axis.transport.http.HTTPSender=DEBUG, axisLogFile
This is awesome, you need add the following for in java code.
PropertyConfigurator.configure(<log4j property file>);

Categories