ArchaiusPropertyResolver.java 3.6 KB
Newer Older
E
elandau 已提交
1 2 3
package com.netflix.client.config;

import com.netflix.config.ConfigurationManager;
4
import org.apache.commons.configuration.AbstractConfiguration;
E
elandau 已提交
5 6 7 8 9 10 11
import org.apache.commons.configuration.event.ConfigurationEvent;
import org.apache.commons.configuration.event.ConfigurationListener;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.util.Arrays;
import java.util.Optional;
12
import java.util.concurrent.CopyOnWriteArrayList;
E
elandau 已提交
13
import java.util.concurrent.TimeUnit;
14
import java.util.function.BiConsumer;
E
elandau 已提交
15 16 17 18 19 20
import java.util.stream.Collectors;

public class ArchaiusPropertyResolver implements PropertyResolver {
    private static final Logger LOG = LoggerFactory.getLogger(ArchaiusPropertyResolver.class);

    public static final ArchaiusPropertyResolver INSTANCE = new ArchaiusPropertyResolver();
21
    private final AbstractConfiguration config;
22
    private final CopyOnWriteArrayList<Runnable> actions = new CopyOnWriteArrayList<>();
23 24 25

    private ArchaiusPropertyResolver() {
        this.config = ConfigurationManager.getConfigInstance();
26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42

        ConfigurationManager.getConfigInstance().addConfigurationListener(new ConfigurationListener() {
            @Override
            public void configurationChanged(ConfigurationEvent event) {
                if (!event.isBeforeUpdate()) {
                    actions.forEach(ArchaiusPropertyResolver::invokeAction);
                }
            }
        });
    }

    private static void invokeAction(Runnable action) {
        try {
            action.run();
        } catch (Exception e) {
            LOG.info("Failed to invoke action", e);
        }
43
    }
E
elandau 已提交
44 45 46 47

    @Override
    public <T> Optional<T> get(String key, Class<T> type) {
        if (Integer.class.equals(type)) {
48
            return Optional.ofNullable((T) config.getInteger(key, null));
E
elandau 已提交
49
        } else if (Boolean.class.equals(type)) {
50
            return Optional.ofNullable((T) config.getBoolean(key, null));
E
elandau 已提交
51
        } else if (Float.class.equals(type)) {
52
            return Optional.ofNullable((T) config.getFloat(key, null));
E
elandau 已提交
53
        } else if (Long.class.equals(type)) {
54
            return Optional.ofNullable((T) config.getLong(key, null));
E
elandau 已提交
55
        } else if (Double.class.equals(type)) {
56
            return Optional.ofNullable((T) config.getDouble(key, null));
E
elandau 已提交
57
        } else if (TimeUnit.class.equals(type)) {
58
            return Optional.ofNullable((T) TimeUnit.valueOf(config.getString(key, null)));
E
elandau 已提交
59
        } else {
60
            return Optional.ofNullable(config.getStringArray(key))
E
elandau 已提交
61 62 63 64 65 66
                    .filter(ar -> ar.length > 0)
                    .map(ar -> Arrays.stream(ar).collect(Collectors.joining(",")))
                    .map(value -> {
                        if (type.equals(String.class)) {
                            return (T)value;
                        } else {
67
                            return PropertyUtils.resolveWithValueOf(type, value)
E
elandau 已提交
68 69 70
                                    .orElseThrow(() -> new IllegalArgumentException("Unable to convert value to desired type " + type));
                        }
                    });
71 72
        }
    }
E
elandau 已提交
73

74 75 76 77 78 79 80 81 82 83 84
    @Override
    public void forEach(String prefix, BiConsumer<String, String> consumer) {
        Optional.ofNullable(config.subset(prefix))
                .ifPresent(subconfig -> {
                    subconfig.getKeys().forEachRemaining(key -> {
                        String value = config.getString(prefix + "." + key);
                        consumer.accept(key, value);
                    });
                });
    }

E
elandau 已提交
85 86
    @Override
    public void onChange(Runnable action) {
87 88 89 90 91
        actions.add(action);
    }

    public int getActionCount() {
        return actions.size();
E
elandau 已提交
92 93
    }
}