Dynamically update Eureka instance metadata - spring-cloud

When Spring Cloud Eureka instance starts I can define some instance metadata statically (in eureka.instance.metadataMap.* in my application.yml) or dynamically (using EurekaInstanceConfigBean for example). But once instance is registered, this metadata no longer updates in Eureka after I update the config bean.
Is there a way to define some metadata that will dynamically update in Eureka? So Eureka will work kind of like a key-value storage for each instance.

If you want to update any metadata from eureka client for itself, just use com.netflix.appinfo.ApplicationInfoManagerobject and call registerAppMetadata(Map<String, String>).
If so, this info will be updated in Eureka Server usually soon or at least in 30sec.You can use DI to get the instance of ApplicationInfoManger.
If you want to update metadata for other service instance, just invoke REST API like below to eureka server.
PUT /eureka/apps/appID/instanceID/metadata?key=value

Related

RestTemplate annotated by #LoadBalanced get wrong service address by service name from eureka sometimes

I use springcloud to build the system, including many microservices。 For some interface calls, I use resttemplate annotated by #LoadBalance to implement load balancing, and use eureka as a registry center. However, when I call interfaces between different micro services, resttemplate sometimes will connect to wrong service. For example, I have service A, B, C, when service A call a service B's interface, resttemplate annotated by #LoadBalance will find the actual ip&port from eureka by service name first, and then build the actual url and send the request to target server, but sometimes, it will find the service C's ip&port when I call service B's interface, which cause a fail invoking. This case occurs infrequently but nerver disappear, I have been troubled for a long time, could anyone give me some suggestions? Thanks.
I learned why yesterday: it is a bug in spring cloud Dalston.RELEASE(https://github.com/spring-cloud/spring-cloud-commons/issues/224), and we happen to use this version. Spring cloud had fixed this bug in Dalston.SR2, and now it works fine

Is it possible to have a single frontend select between backends (defined dynamically)?

I am currently looking into deploying Traefik/Træfik on our service fabric cluster.
Basically I have a setup where I have any number of Applications (services), defined with a tenant name and each of these services is in fact a separate Web UI.
I am trying to figure out if I can configure a single frontend to target a backend so I don't have to define a new frontend each time I deploy a new UI app. Something like
[frontend.tenantui]
rule = "HostRegexp:localhost,{tenantName:[a-z]+}.example.com"
backend = "fabric:/WebApp/{tenantName}"
The idea is to have it such that I can just deploy new UI services without updating the frontend configuration.
I am currently using the Service Fabric provider for my backend services, but I am open to using the file provider or something else if that is required.
Update:
The servicemanifset contains labels, so as to let traefik create backends and frontends.
The labels are defined for one service, lets call it WebUI as an example. Now when I deploy an instance of WebUI it gets a label and traefik understands it.
Then I deploy ANOTHER instance with a DIFFERENT set of parameters, its still the WebUI service and it uses the same manifest, so it gets the same labels, and the same routing. But what I would really want was to let it have a label containing some sort of rule so I could route to the name of the service instance (determine at runtime not design time). Specifically I would like for the runtime part to be part of the domainname (thus the suggestion of a HostRegexp style rule)
I don't think it is possible to use the matched group from the HostRegexp to determine the backend.
A possibility would be to use the Property Manager API to dynamically set the frontend rule for the service instance after creating it. Also, see this for a complete example on using the API.

Communication between microservice using ServiceID from discovery instead of directory host?

I'm new microservice, I'm reading some example about discovery server, I see we can call another microservice api by using url like:
http://inventory-service/api/inventory/{productCode}.
"inventory-service" is a service instance I registered in discovery.
So my question is what is the benefit of using serviceId intead of call directory host:port:
http://localhost:9009/api/inventory/{productCode}.
Let asume you register inventory-service with Eureka server by configuring Eureka serviceUrl in src/main/resources/bootstrap.properties.
spring.application.name=inventory-service
eureka.client.service-url.defaultZone=http://localhost:8761/eureka/
Then build inventory-service and start 2 instances of it by running following commands.
java -jar -Dserver.port=9001 target/inventory-service-0.0.1-SNAPSHOT-exec.jar
java -jar -Dserver.port=9002 target/inventory-service-0.0.1-SNAPSHOT-exec.jar
When you visit Eureka Dashboard http://localhost:8761/ you will see 2 instances of inventory-service registered.
If you want to apply Client Load Balancing from your consumer application you would need a config like this:
server.ribbon.listOfServers=localhost:9001,localhost:9002
server.ribbon.eureka.enabled=false
If you want to start new instances you would need to register them in your consumer configuration.
With ServiceID you don't have to worry about it, because all instances will register with the same identifier. It will be added automatically in the list of available servers.It is one of the advantages of using ServiceId instead hostname

Create app instance (in service fabric cluster explorer) ignores number of instances on local machine

Using 5.1.163 version of service fabric run time.
Created a service fabric application with one stateless web api (i.e. using owin communication listener).
Modified the generated code so that listening endpoint to contain partition id/instance id/new_guid (just as is the case for stateful services). This should allow me to create another app instance so that I can have multi-tenancy at application level.
By default, Local.xml file is set to 1 instance for this service.
Deployed it to local machine by F5. Verified that it is deployed to only one instance.
Verified that service is working fine.
Navigated to local service fabric explorer and clicked on the Cluster/Application/AppType node. Clicked on 'Create app instance'.
It successfully created 2nd app instance.
However in this new instance, the service is deployed to all 5 nodes.
I was expecting it deploy the service instance only one node. Is this a bug? But only in this version of service fabric?
When you deploy a Service Fabric application using Visual Studio (or from PowerShell) you use the Deploy-FabricApplication.ps1 that is generated for your application and found in /scripts under your SF project. This script does two things (mainly):
Create/update the application type
Create a new/upgrade existing instance of the application type
The second part there is similar to what you do in the SF Explorer, except this one also considers the publisher profile file you supply. The PS-script actually reads your publisher profile xml files and extracts any parameters in there to a hashset (a dictionary) and passes that as an argument in step 2.
You can create an instance of an SF application type using the PS cmdlets (alternatively you can use FabricClient). The following command does this: New-ServiceFabricApplication. Here you have the chance to supply your own application parameters, including instance count for services in your new application instance (if you have a dynamic parameter for that in your application manifest).
So, when you use the SF explorer to create a new application instance you cannot control how that instance is created, it is always using the default parameter values as specified directly in ApplicationManifest.xml, not values you have specified in your publisher profiles (local1, local5, cloud, etc.).
To controll the creation, run New-ServiceFabricApplication with yor parameters as a hashset.

How to dynamically configure security for Artemis MQ addresses

Trying to dynamically create and provide security metadata for artemis mq topics (as opposed to defining them statically in broker.xml).
For that purpose I've implemented (as described here) the SecuritySettingPlugin interface.
Now, the issue is the getSecurityRoles/populateSecurityRoles of the implementation are called only at server startup.
So, at some point in time after the mq server has been started, a topic will be created :
org.apache.activemq.artemis.api.jms.management.JMSServerControl.createTopic("newTopic")
Now I would like artemis to call again my SecuritySettingPlugin implementation to get the updated security roles (which will include configuration for the newly created newTopic).
Is that possible ?
P.S. security-invalidation-interval does not invalidate roles configuration cache.
Seems there is a way to customize an address security by API :
ActiveMQServerControl.addSecuritySettings()