Integrating custom kafka consumer with Spring cloud config client - spring-cloud

We are using spring config client to refresh properties dynamically. We have added spring-cloud-starter-bus-kafka on the classpath and everything works fine. Pom version of all these dependencies is 2.X.
What I want to do is, remove spring-cloud-starter-bus-kafka and add my custom code to pick up consumer event and refresh context and in turn refresh properties using cloud config client. I believe somewhere Spring is calling ConfigServicePropertySourceLocator.locate. Basically, I want to just replicate what Spring has done in spring-cloud-starter-bus-kafka to make refreshing of properties in real time possible.
The reason I'm doing all this is, I'm internally using an older version of kafka-clients. We have a homegrown version of that, it supports encryption and what not. Problem is coming since spring-cloud-starter-bus-kafka is using 2.X version of kakfa-clients and our home version is not ready for that. Due to this, either one of them is working at one point in time.
Can someone show me some pointer on what needs to be done to consume refresh event from kafka and refresh the property? I don't imagine this being too much complicated. It should be consuming kafka event and somewhere calling ConfigSourceLocator to refresh the properties.

It's even simpler than that. If you look in the RefreshListener class you can see that all it does is
Set<String> keys = this.contextRefresher.refresh();
log.info("Received remote refresh request. Keys refreshed " + keys);
Where contextRefresher is a org.springframework.cloud.context.refresh.ContextRefresher.
This will trigger the code that handles looking up configuration automatically.

Related

Eclipse milo - OPCUA - What is the best practice to inform server (value/node) changes to the client to trigger a refresh?

I am getting started with OPCUA and eclipse milo and I am trying to understand how to best inform the client that a value or node has changed in the server.
So far my guess is that I need to trigger an event in the node that has changed, and then the client should monitor/subscribe to events in such node. Am I right on this?
If my understanding is correct, which event is most appropriated to trigger for this purpose?
I am using a free UI OPCUA client to test my server changes, and I need to refresh manually to observe my changes. I was expecting that by triggering the correct (OPCUA standard) event I would indicate the client to refresh automatically, is this possible?
Thanks!
You don't need Events to notify a client of an attribute change - that's the entire point of Subscriptions and MonitoredItems.
The client creates a MonitoredItem for the Value attribute (or any other attribute) and the server will report changes when that attribute changes.
As far as what you need to do as a user of the Milo Server SDK - see the ExampleNamespace. Your namespace implements the onDataItemCreated and other related methods to be notified that a client has created a MonitoredItem and you should start sampling values for it.

#RefreshScope and /refresh not working for multiple instance

#RefreshScope and /refresh not working for updating multiple service instance i know this can be done using spring cloud bus but due to some constraint i can not opt for that is there any alternatives
Consider using Ribbon to determine the available instances and then call refresh event for all of them. I have not tried this, but seems to be possible as I read in the documentations

Getting more detail from the Spring cloud Discovery Client

I note that with the various refactoring of common elements into spring cloud commons, the information that you get from auto wiring DiscoveryClient is rather sparse.
Lets say that I want to get more information for the incoming service data that the service gets when it registers with Eureka. Much of what i want is in the Application object.
I know that I could get this detail form the EurekaClient. How can I get access to the EurekaClient object.
I suspect you mean InstanceInfo objects, since Application basically just holds a list on InstanceInfo's. The ServiceInstance returned from the Spring Cloud DiscoveryClient.getInstances(serviceId) backed by an InstanceInfo. My guess is it would be easiest for you to autowire EurekaClient (or com.netflix.*.DiscoveryClient if your using an older version) and go from there. We have to be sparse as we support more than just eureka (consul, zookeeper).

JAX-WS service and client versioning

My group is getting into web services for the first time. What is the usual way to control versioning issues with web services and clients? We're generating our services and clients using in IBM's RAD using the wizards it presents. The services and clients work well enough, but we're wondering how managing these will become a task going forward.
-If a service changes, and it's interface doesn't change I presume older clients would never know the difference and would work fine.
-If a service changes to add a new property to a parameter, would older clients work with it if they didn't need to set that value?
-How do people handle version control of web services as they grow in number and the number of apps using their clients grows? What is best practice on this sort of thing?
There are two types of versioning that we use. One that is visible to clients (public) and one that isn't (private). This comes from (what you already touched upon) whether clients are affected or not.
If clients are affect by, for example change in XSD Schema definitions or functionality of the WS changes in such way that clients must also modify their end, we change the public version. We increment the version number in WS context root, which means that it will have different URL than the previous version. Also make sure that the code archive, in our case they are war, have also the public version, as not to overwrite the previous deployment.
For example our WS called foo is in public version 2. Its URL is http://ourserver:8000/foo_2 and war file is called foo_2. We modified our XSD Schema, so the clients must react to the change. We update the version and now URL is http://ourserver:8000/foo_3 and war file is called foo_3. The previous version still exists, while clients can slowly transition to the new version.
If the change does not force any action from clients, then we call this private versioning. This usually shows up, in combination with public version, as a part of a project name. Using previous example, we have a WS foo, with private version 5 and public 2. Our project for this service is called WS_foo_2_5. We now change the order in which we store incoming data. This does not effect the clients, so we change the private version. In effect we have project WS_foo_2_6. We create a code archive from it called foo_2 and deploy it with URL set to http://ourserver:8000/foo_2. This way we modified the version, without changing anything from clients POV.

GWT application freezes when new version is deployed while using it

While using the GWT application, I deployed the new version of the application.
Once deployment is complete my application freezes until I do the full refresh.
I originally thought this was caching problem, so I assigned all the files to be no-cache by setting all response headers using the filter. But still with this filter application freezes when I deploy a new version.
What could be a cause of this?
What I am trying to achieve here is to be able to deploy a new version of GWT application while user is using the application. This means when the JavaScript changes I want user to get it from the server instead of using the cached one without any glitch (maybe slow response time since request need to go to the server in this case).
Note:
This is observed when deployed with the changes in the code, so I am
guessing one of the cache.js file.
When deployed without any changes to a code this is not observed.
Your question is not clear because it does not tell which situation you are in:
You deploy the new GWT app and you want the new server-side to respond to the old client-side.
You deploy the new GWT app and you want the client browser to immediately replace the GWT client with the new version.
I would like to speak about situation 2, first. I am thinking you came from a background of servlets and JSP, plus dynamically generated HTML and Javascript. In those env, the client is immediately replaced everytime your client places requests the server. That is because the client UI is refreshed by new response generated by the server.
In GWT, the root panel is not refreshed. The root panel is held by the hosting html page. If the hosting html page is not refreshed, the GWT client will forever be the old version. That is the very idea of AJAX and GWT. You don't want to have to refresh the web page and yet allowing the web page to continuously emit/receiv async requests/responses.
You might be reminded that GWT is compiled into javascript.
In order to get the new version, you have to refresh the web page. There is no way in GWT technology for the new javascript to sneak into the browser to replace the old sets of javascript, unless you refresh the page.
The script tag source link is already read when the GWT javascripts are loaded. Those links will not be reread unless you refresh the page. If those links are not re-read, then the new javascripts will never be reloaded.
You need to detach your JSP/servlet experience when dealing with AJAX.
Back to situation 1 ..
Since the new GWT UI version was not loaded, because you did not perform a refresh, you would have incongruences between the data structure expected by the old UI version with that of the new server-side version. If you can guarantee the stability of RPC or client-server data structure and sequences of exchange, I believe you should not have a problem.
However, with GAE, the serialization id is important. You may have changed the data structure of a POJO without updating the serialization id. That would confuse the GAE client-server traffic, because ... hmmm ... I can faintly recall the exact sequence of problem I had faced - You better read up on GAE pojo serialization id yourself.
I also had such problem. In such case you should have one table which keeps every new upload information. And also you should have one async request (maybe in your EntryPoint) for checking whether you have new upload or not.
public void success(String version) {
if(!Cookies.getCookie("version").equals(version)){
Window.open(currentUrl, "_self", "");
}
}
This is what i've done and working without any problem...
The problem is from your web server not the GWT itself. You should see if your Web Server supports hot-deployment or not and how it works with it.
UPDATE :
For example Tomcat prior to version 7 does not support Hot-deployment and you have to restart the server on every update whereas Tomcat 7 supports Hot-deployment and you only have to reload the page to get the new module.