X-Git-Url: https://gerrit.o-ran-sc.org/r/gitweb?a=blobdiff_plain;f=policy-agent%2Fsrc%2Fmain%2Fjava%2Forg%2Foransc%2Fpolicyagent%2Fconfiguration%2FApplicationConfig.java;h=7e5228425c957d124e0c3b44a1a6c3078f60c784;hb=f694dec2ff16069e6bb5c9de845278f44e8c9591;hp=04471c88629d656ec41f834628004e0ea83c83eb;hpb=6fe1880bfac3daa86c05461da80147325f5f47a2;p=nonrtric.git diff --git a/policy-agent/src/main/java/org/oransc/policyagent/configuration/ApplicationConfig.java b/policy-agent/src/main/java/org/oransc/policyagent/configuration/ApplicationConfig.java index 04471c88..7e522842 100644 --- a/policy-agent/src/main/java/org/oransc/policyagent/configuration/ApplicationConfig.java +++ b/policy-agent/src/main/java/org/oransc/policyagent/configuration/ApplicationConfig.java @@ -33,6 +33,9 @@ import java.io.IOException; import java.io.InputStream; import java.io.InputStreamReader; import java.time.Duration; +import java.util.Collection; +import java.util.HashMap; +import java.util.Map; import java.util.Optional; import java.util.Properties; import java.util.ServiceLoader; @@ -54,6 +57,7 @@ import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Value; import org.springframework.boot.context.properties.ConfigurationProperties; import org.springframework.boot.context.properties.EnableConfigurationProperties; + import reactor.core.Disposable; import reactor.core.publisher.Flux; import reactor.core.publisher.Mono; @@ -67,25 +71,30 @@ public class ApplicationConfig { Properties systemEnvironment; private Disposable refreshConfigTask = null; + private Collection observers = new Vector<>(); + + private Map ricConfigs = new HashMap<>(); @NotEmpty private String filepath; - private Vector ricConfigs; - @Autowired public ApplicationConfig() { } + protected String getLocalConfigurationFilePath() { + return this.filepath; + } + public synchronized void setFilepath(String filepath) { this.filepath = filepath; } - public Vector getRicConfigs() { - return this.ricConfigs; + public synchronized Collection getRicConfigs() { + return this.ricConfigs.values(); } - public Optional lookupRicConfigForManagedElement(String managedElementId) { + public synchronized Optional lookupRicConfigForManagedElement(String managedElementId) { for (RicConfig ricConfig : getRicConfigs()) { if (ricConfig.managedElementIds().contains(managedElementId)) { return Optional.of(ricConfig); @@ -105,12 +114,24 @@ public class ApplicationConfig { public void initialize() { stop(); - loadConfigurationFromFile(this.filepath); + loadConfigurationFromFile(); refreshConfigTask = createRefreshTask() // - .subscribe(e -> logger.info("Refreshed configuration data"), - throwable -> logger.error("Configuration refresh terminated due to exception", throwable), - () -> logger.error("Configuration refresh terminated")); + .subscribe(notUsed -> logger.info("Refreshed configuration data"), + throwable -> logger.error("Configuration refresh terminated due to exception", throwable), + () -> logger.error("Configuration refresh terminated")); + } + + public static enum RicConfigUpdate { + ADDED, CHANGED, REMOVED + } + + public interface Observer { + void onRicConfigUpdate(RicConfig ric, RicConfigUpdate event); + } + + public void addObserver(Observer o) { + this.observers.add(o); } Mono getEnvironment(Properties systemEnvironment) { @@ -119,10 +140,10 @@ public class ApplicationConfig { Flux createRefreshTask() { return getEnvironment(systemEnvironment) // - .flatMap(this::createCbsClient) // - .flatMapMany(this::periodicConfigurationUpdates) // - .map(this::parseRicConfigurationfromConsul) // - .onErrorResume(this::onErrorResume); + .flatMap(this::createCbsClient) // + .flatMapMany(this::periodicConfigurationUpdates) // + .map(this::parseRicConfigurationfromConsul) // + .onErrorResume(this::onErrorResume); } Mono createCbsClient(EnvProperties env) { @@ -153,8 +174,48 @@ public class ApplicationConfig { return this; } - private synchronized void setConfiguration(@NotNull Vector ricConfigs) { - this.ricConfigs = ricConfigs; + private class Notification { + final RicConfig ric; + final RicConfigUpdate event; + + Notification(RicConfig ric, RicConfigUpdate event) { + this.ric = ric; + this.event = event; + } + } + + private void setConfiguration(@NotNull Collection ricConfigs) { + Collection notifications = new Vector<>(); + synchronized (this) { + Map newRicConfigs = new HashMap<>(); + for (RicConfig newConfig : ricConfigs) { + RicConfig oldConfig = this.ricConfigs.get(newConfig.name()); + if (oldConfig == null) { + newRicConfigs.put(newConfig.name(), newConfig); + notifications.add(new Notification(newConfig, RicConfigUpdate.ADDED)); + this.ricConfigs.remove(newConfig.name()); + } else if (!newConfig.equals(newConfig)) { + notifications.add(new Notification(newConfig, RicConfigUpdate.CHANGED)); + newRicConfigs.put(newConfig.name(), newConfig); + this.ricConfigs.remove(newConfig.name()); + } else { + newRicConfigs.put(oldConfig.name(), oldConfig); + } + } + for (RicConfig deletedConfig : this.ricConfigs.values()) { + notifications.add(new Notification(deletedConfig, RicConfigUpdate.REMOVED)); + } + this.ricConfigs = newRicConfigs; + } + notifyObservers(notifications); + } + + private void notifyObservers(Collection notifications) { + for (Observer observer : this.observers) { + for (Notification notif : notifications) { + observer.onRicConfigUpdate(notif.ric, notif.event); + } + } } public void stop() { @@ -167,7 +228,12 @@ public class ApplicationConfig { /** * Reads the configuration from file. */ - protected void loadConfigurationFromFile(String filepath) { + public void loadConfigurationFromFile() { + String filepath = getLocalConfigurationFilePath(); + if (filepath == null) { + logger.debug("No localconfiguration file used"); + return; + } GsonBuilder gsonBuilder = new GsonBuilder(); ServiceLoader.load(TypeAdapterFactory.class).forEach(gsonBuilder::registerTypeAdapterFactory); @@ -179,7 +245,7 @@ public class ApplicationConfig { } ApplicationConfigParser appParser = new ApplicationConfigParser(); appParser.parse(rootObject); - this.ricConfigs = appParser.getRicConfigs(); + setConfiguration(appParser.getRicConfigs()); logger.info("Local configuration file loaded: {}", filepath); } catch (JsonSyntaxException | ServiceException | IOException e) { logger.trace("Local configuration file not loaded: {}", filepath, e); @@ -193,5 +259,4 @@ public class ApplicationConfig { InputStream createInputStream(@NotNull String filepath) throws IOException { return new BufferedInputStream(new FileInputStream(filepath)); } - }