5

I am a very much new to Netflix archaius. I have a code snippet which reads Java property file and prints property value.

When this program runs it prints the value of property named "Fields" from testproperty.properties file. Now while this program is running I am updating the value of "Fields" property, so archaius should fetch change value dynamically. But it is still printing older value.

What is the correct way to use archaius with this Java Program? Or to update properties in a program without restarting it ? If someone can point out correction in this code snippet it would be helpful.

I want to run a demo with Netflix archaius, so I have imported archaius through maven in my project.

Now I am updating my properties file. But still it prints the old property value. (P.S.: I have kept the continuous while loop in driver program to see if archaius picks the update property value runtime. I guess that's what archaius suppose to do. Fetching the updated property without restarting application. Correct me if I am wrong.)

Below is my code snippet :

import com.netflix.config.DynamicPropertyFactory;
import com.netflix.config.DynamicStringProperty;

public class PropertyChangetest {

    public static void main(String args[]) {

        DynamicPropertyFactory sampleProp = DynamicPropertyFactory.getInstance();
        System.setProperty("archaius.configurationSource.defaultFileName", "TestProperty.properties");
        System.setProperty("archaius.fixedDelayPollingScheduler.delayMills", "500");

        while(true) {
            DynamicStringProperty sampleProp1 = sampleProp.getStringProperty("fields","");
            System.out.println(sampleProp1.get());
        }
    }
}

My "TestProperty.properties" file only have one property called fields. After running the program, I am updating my property file but it still prints older value.

Brent Worden
  • 10,624
  • 7
  • 52
  • 57
Bharat
  • 311
  • 3
  • 11
  • Please provide us with a specific question. – António Ribeiro Feb 16 '16 at 22:46
  • When this program runs it prints the value of property named "Fields" from testproperty.properties file. Now while this program is running I am updating the value of "Fields" property, so archaius should fetch change value dynamically. But it is still printing older value. – Bharat Feb 16 '16 at 22:49
  • Ok, I understand you've a problem. But you're still not asking anything. Do you mind update your post with your doubts? – António Ribeiro Feb 16 '16 at 22:53
  • 1
    Updated ..Please check and let me know if its OK – Bharat Feb 16 '16 at 22:57
  • Have you tried to use `DynamicPropertyFactor.getInstance()..getBackingConfigurationSource() ` (doc in [here](http://netflix.github.io/archaius/archaius-core-javadoc/com/netflix/config/DynamicPropertyFactory.html#getBackingConfigurationSource())) in order to retrieve the `Configuration` and then [adding](http://netflix.github.io/archaius/archaius-core-javadoc/com/netflix/config/ConcurrentCompositeConfiguration.htm) the property you want? – António Ribeiro Feb 16 '16 at 23:13
  • 1
    I'm also facing similar issue. Overriding the proerty via backing configuration works but the default poller is not updating the property. I also made sure that the poller properties are updated so that polling is done at a faster pace i.e. these two commands were also executed : System.setProperty("archaius.fixedDelayPollingScheduler.initialDelayMills", "1"); System.setProperty("archaius.fixedDelayPollingScheduler.delayMills", "100"); – abhishekmahawar Jan 09 '17 at 13:13

3 Answers3

0

The idea is to implement a custom PolledConfigurationSource, so Archaius can poll the source and update the property for consumption. I have also included a callback that the smart way to consume the property without your App polling it again (remember Archaius is doing the polling part for you).

Important note on the sample code : The program exits after the first callback. If you want to test more callbacks, increase the counter at class variable 'latch'

package com.test.config;

import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.CountDownLatch;

import org.apache.commons.configuration.PropertiesConfiguration;
import org.junit.Test;

import com.netflix.config.AbstractPollingScheduler;
import com.netflix.config.ConcurrentMapConfiguration;
import com.netflix.config.ConfigurationManager;
import com.netflix.config.DynamicConfiguration;
import com.netflix.config.DynamicPropertyFactory;
import com.netflix.config.DynamicStringProperty;
import com.netflix.config.FixedDelayPollingScheduler;
import com.netflix.config.PollResult;
import com.netflix.config.PolledConfigurationSource;

public class TestArchaius {
    CountDownLatch latch = new CountDownLatch(1);

    @Test
    public void tes() throws Exception {
        AbstractPollingScheduler scheduler = new FixedDelayPollingScheduler(0, 1000, false);
        DynamicConfiguration dynamicConfiguration = new DynamicConfiguration(new MyPolledConfigurationSource(), scheduler);

        ConfigurationManager.install(dynamicConfiguration);

        DynamicStringProperty fieldsProperty = DynamicPropertyFactory.getInstance().getStringProperty("fields", "");
        fieldsProperty.addCallback(() -> {
            System.out.println(fieldsProperty.get());
            latch.countDown();
        });

        latch.await();
    }

    class MyPolledConfigurationSource implements PolledConfigurationSource {

        @Override
        public PollResult poll(boolean initial, Object checkPoint) throws Exception {
            ConcurrentMapConfiguration configFromPropertiesFile = new ConcurrentMapConfiguration(
                    new PropertiesConfiguration("TestProperty.properties"));
            Map<String, Object> fullProperties = new HashMap<String, Object>();
            configFromPropertiesFile.getProperties().forEach((k, v) -> fullProperties.put((String) k, v));
            return PollResult.createFull(fullProperties);
        }

    }
}
linkcrux
  • 328
  • 4
  • 13
0

I ran into this issue recently. I wanted to implement a use case such as the DynamicPropertyFactory's prop should be updated via a REST API request. I had googled a lot on how to do that since the property was not getting updated after using the .setProperty(String prop, String value) method. But I found that if a property is not defined before then the property gets added with the help of this method. So the problem comes down like its not possible to override a property. Also I found that it is using ConcurrentCompositeConfiguration for the Config instance and not the ConcurrentMapConfiguration. As I googled further found tabnine posts and found there is a method called

setOverrideProperty(java.lang.String key, java.lang.Object finalValue)
          Override the same property in any other configurations in the list.

So casting to this class setting the override property resolved the issue. Property got updated successfully.

#Reference to ConcurrentCompositeConfiguration - http://netflix.github.io/archaius/archaius-core-javadoc/com/netflix/config/ConcurrentCompositeConfiguration.html

Mahadev K
  • 330
  • 2
  • 9
0

The probable reason for its failure is that you used the IDE to modify config file, you don't know when ide really write change to file and save(of couese you can change ide settint). try to open config file with other software as windows notebook or notepad, change the config value and save the file, you may see the code print the latest config value after setting time.

Lajos Arpad
  • 64,414
  • 37
  • 100
  • 175
Aithosa
  • 21
  • 2