diff options
author | vempo <vitaliy.emporopulo@amdocs.com> | 2018-10-25 19:27:22 +0300 |
---|---|---|
committer | Avi Gaffa <avi.gaffa@amdocs.com> | 2018-10-28 06:58:23 +0000 |
commit | 933cdbd4c20f18fe47f253bd721baf6ae996e906 (patch) | |
tree | d8298cf67446c13b688ceb1446a15516da698fc5 /common/onap-common-configuration-management/onap-configuration-management-core/src/main/java/org/onap/config/impl/ConfigurationChangeNotifier.java | |
parent | edc8d7bbb0faad568b367e60012db476525c288c (diff) |
Code formatting of configuration framework
Fixed code formatting, removed meaningless Javadoc comments,
added copyright headers, minor (and safe) static analysis fixes.
Change-Id: I3eda1f242905da5b80e024cf30a69ff59381fc43
Issue-ID: SDC-1867
Signed-off-by: vempo <vitaliy.emporopulo@amdocs.com>
Diffstat (limited to 'common/onap-common-configuration-management/onap-configuration-management-core/src/main/java/org/onap/config/impl/ConfigurationChangeNotifier.java')
-rw-r--r-- | common/onap-common-configuration-management/onap-configuration-management-core/src/main/java/org/onap/config/impl/ConfigurationChangeNotifier.java | 708 |
1 files changed, 313 insertions, 395 deletions
diff --git a/common/onap-common-configuration-management/onap-configuration-management-core/src/main/java/org/onap/config/impl/ConfigurationChangeNotifier.java b/common/onap-common-configuration-management/onap-configuration-management-core/src/main/java/org/onap/config/impl/ConfigurationChangeNotifier.java index 88c71c14e0..cd6481f97b 100644 --- a/common/onap-common-configuration-management/onap-configuration-management-core/src/main/java/org/onap/config/impl/ConfigurationChangeNotifier.java +++ b/common/onap-common-configuration-management/onap-configuration-management-core/src/main/java/org/onap/config/impl/ConfigurationChangeNotifier.java @@ -1,11 +1,21 @@ +/* + * Copyright © 2016-2018 European Support Limited + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + package org.onap.config.impl; -import org.onap.config.ConfigurationUtils; -import org.onap.config.Constants; -import org.onap.config.api.ConfigurationChangeListener; -import org.onap.config.api.ConfigurationManager; -import org.onap.config.api.Hint; - import java.io.File; import java.io.IOException; import java.lang.management.ManagementFactory; @@ -35,441 +45,349 @@ import java.util.concurrent.TimeUnit; import javax.management.JMX; import javax.management.MBeanServerConnection; import javax.management.ObjectName; +import org.onap.config.ConfigurationUtils; +import org.onap.config.Constants; +import org.onap.config.api.ConfigurationChangeListener; +import org.onap.config.api.ConfigurationManager; +import org.onap.config.api.Hint; - -/** - * The type Configuration change notifier. - */ public final class ConfigurationChangeNotifier { - private final HashMap<String, List<NotificationData>> store = new HashMap<>(); - private final ScheduledExecutorService executor = - Executors.newScheduledThreadPool(5, ConfigurationUtils.getThreadFactory()); - private final ExecutorService notificationExecutor = - Executors.newCachedThreadPool(ConfigurationUtils.getThreadFactory()); - private final Map<String, WatchService> watchServiceCollection = - Collections.synchronizedMap(new HashMap<>()); - - static { - if (!Thread.currentThread().getStackTrace()[2].getClassName() - .equals(ConfigurationImpl.class.getName())) { - throw new RuntimeException("Illegal access."); + static { + if (!Thread.currentThread().getStackTrace()[2].getClassName().equals(ConfigurationImpl.class.getName())) { + throw new RuntimeException("Illegal access."); + } } - } - /** - * Instantiates a new Configuration change notifier. - * - * @param inMemoryConfig the in memory config - */ - public ConfigurationChangeNotifier(Map<String, AggregateConfiguration> inMemoryConfig) { - executor.scheduleWithFixedDelay(() -> this - .pollFilesystemAndUpdateConfigurationIfRequired(inMemoryConfig, - System.getProperty("config.location"), false), 1, 1, TimeUnit.MILLISECONDS); - executor.scheduleWithFixedDelay(() -> this - .pollFilesystemAndUpdateConfigurationIfRequired(inMemoryConfig, - System.getProperty("tenant.config.location"), true), 1, 1, TimeUnit.MILLISECONDS); - executor.scheduleWithFixedDelay(() -> this - .pollFilesystemAndUpdateNodeSpecificConfigurationIfRequired( - System.getProperty("node.config.location")), 1, 1, TimeUnit.MILLISECONDS); - } + private final HashMap<String, List<NotificationData>> store = new HashMap<>(); + private final ScheduledExecutorService executor = + Executors.newScheduledThreadPool(5, ConfigurationUtils.getThreadFactory()); + private final ExecutorService notificationExecutor = + Executors.newCachedThreadPool(ConfigurationUtils.getThreadFactory()); + private final Map<String, WatchService> watchServiceCollection = Collections.synchronizedMap(new HashMap<>()); - /** - * Shutdown. - */ - public void shutdown() { - for (WatchService watch : watchServiceCollection.values()) { - try { - watch.close(); - } catch (IOException exception) { - //do nothing - } + public ConfigurationChangeNotifier(Map<String, AggregateConfiguration> inMemoryConfig) { + executor.scheduleWithFixedDelay(() -> this.pollFilesystemAndUpdateConfigurationIfRequired(inMemoryConfig, + System.getProperty("config.location"), false), 1, 1, TimeUnit.MILLISECONDS); + executor.scheduleWithFixedDelay(() -> this.pollFilesystemAndUpdateConfigurationIfRequired(inMemoryConfig, + System.getProperty("tenant.config.location"), true), 1, 1, TimeUnit.MILLISECONDS); + executor.scheduleWithFixedDelay(() -> this.pollFilesystemAndUpdateNodeSpecificConfigurationIfRequired( + System.getProperty("node.config.location")), 1, 1, TimeUnit.MILLISECONDS); } - executor.shutdownNow(); - } - /** - * Poll filesystem and update configuration if required. - * - * @param inMemoryConfig the in memory config - * @param location the location - * @param isTenantLocation the is tenant location - */ - public void pollFilesystemAndUpdateConfigurationIfRequired( - Map<String, AggregateConfiguration> inMemoryConfig, String location, - boolean isTenantLocation) { - try { - Set<Path> paths = watchForChange(location); - if (paths != null) { - for (Path path : paths) { - File file = path.toAbsolutePath().toFile(); - String repositoryKey = null; - if (ConfigurationUtils.isConfig(file) && file.isFile()) { - if (isTenantLocation) { - Collection<File> tenantsRoot = - ConfigurationUtils.getAllFiles(new File(location), false, true); - for (File tenantRoot : tenantsRoot) { - if (file.getAbsolutePath().startsWith(tenantRoot.getAbsolutePath())) { - repositoryKey = ConfigurationUtils.getConfigurationRepositoryKey( - (tenantRoot.getName() + Constants.TENANT_NAMESPACE_SAPERATOR - + ConfigurationUtils.getNamespace(file)) - .split(Constants.TENANT_NAMESPACE_SAPERATOR)); + public void pollFilesystemAndUpdateConfigurationIfRequired(Map<String, AggregateConfiguration> inMemoryConfig, + String location, boolean isTenantLocation) { + try { + Set<Path> paths = watchForChange(location); + if (paths != null) { + for (Path path : paths) { + File file = path.toAbsolutePath().toFile(); + String repositoryKey = null; + if (ConfigurationUtils.isConfig(file) && file.isFile()) { + if (isTenantLocation) { + Collection<File> tenantsRoot = + ConfigurationUtils.getAllFiles(new File(location), false, true); + for (File tenantRoot : tenantsRoot) { + if (file.getAbsolutePath().startsWith(tenantRoot.getAbsolutePath())) { + repositoryKey = ConfigurationUtils.getConfigurationRepositoryKey( + (tenantRoot.getName() + Constants.TENANT_NAMESPACE_SEPARATOR + + ConfigurationUtils.getNamespace(file)) + .split(Constants.TENANT_NAMESPACE_SEPARATOR)); + } + } + } else { + repositoryKey = ConfigurationUtils.getConfigurationRepositoryKey(file); + } + AggregateConfiguration config = inMemoryConfig.get(repositoryKey); + if (config != null) { + LinkedHashMap origConfig = ConfigurationUtils.toMap(config.getFinalConfiguration()); + config.addConfig(file); + LinkedHashMap latestConfig = ConfigurationUtils.toMap(config.getFinalConfiguration()); + Map map = ConfigurationUtils.diff(origConfig, latestConfig); + String[] tenantNamespaceArray = repositoryKey.split(Constants.KEY_ELEMENTS_DELIMETER); + updateConfigurationValues(tenantNamespaceArray[0], tenantNamespaceArray[1], map); + } + } else { + for (String configKey : inMemoryConfig.keySet()) { + repositoryKey = configKey; + AggregateConfiguration config = inMemoryConfig.get(repositoryKey); + if (config.containsConfig(file)) { + LinkedHashMap origConfig = ConfigurationUtils.toMap(config.getFinalConfiguration()); + config.removeConfig(file); + LinkedHashMap latestConfig = ConfigurationUtils.toMap(config.getFinalConfiguration()); + Map map = ConfigurationUtils.diff(origConfig, latestConfig); + String[] tenantNamespaceArray = repositoryKey.split(Constants.KEY_ELEMENTS_DELIMETER); + updateConfigurationValues(tenantNamespaceArray[0], tenantNamespaceArray[1], map); + } + } + } } - } - } else { - repositoryKey = ConfigurationUtils.getConfigurationRepositoryKey(file); } - AggregateConfiguration config = inMemoryConfig.get(repositoryKey); - if (config != null) { - LinkedHashMap origConfig = ConfigurationUtils.toMap(config.getFinalConfiguration()); - config.addConfig(file); - LinkedHashMap latestConfig = ConfigurationUtils.toMap(config.getFinalConfiguration()); - Map map = ConfigurationUtils.diff(origConfig, latestConfig); - String[] tenantNamespaceArray = - repositoryKey.split(Constants.KEY_ELEMENTS_DELEMETER); - updateConfigurationValues(tenantNamespaceArray[0], tenantNamespaceArray[1], map); - } - } else { - for (String configKey : inMemoryConfig.keySet()) { - repositoryKey = configKey; - AggregateConfiguration config = inMemoryConfig.get(repositoryKey); - if (config.containsConfig(file)) { - LinkedHashMap origConfig = ConfigurationUtils.toMap(config.getFinalConfiguration()); - config.removeConfig(file); - LinkedHashMap latestConfig = - ConfigurationUtils.toMap(config.getFinalConfiguration()); - Map map = ConfigurationUtils.diff(origConfig, latestConfig); - String[] tenantNamespaceArray = - repositoryKey.split(Constants.KEY_ELEMENTS_DELEMETER); - updateConfigurationValues(tenantNamespaceArray[0], tenantNamespaceArray[1], - map); - } - } - } + } catch (ClosedWatchServiceException exception) { + // do nothing. + } catch (Exception exception) { + exception.printStackTrace(); } - } - } catch (ClosedWatchServiceException exception) { - // do nothing. - } catch (Exception exception) { - exception.printStackTrace(); } - } - - private void updateConfigurationValues(String tenant, String namespace, Map map) - throws Exception { - MBeanServerConnection mbsc = ManagementFactory.getPlatformMBeanServer(); - ObjectName mbeanName = new ObjectName(Constants.MBEAN_NAME); - ConfigurationManager conf = - JMX.newMBeanProxy(mbsc, mbeanName, ConfigurationManager.class, - true); - conf.updateConfigurationValues(tenant, namespace, map); - } - /** - * Poll filesystem and update node specific configuration if required. - * - * @param location the location - */ - public void pollFilesystemAndUpdateNodeSpecificConfigurationIfRequired(String location) { - try { - Set<Path> paths = watchForChange(location); - if (paths != null) { - for (Path path : paths) { - File file = path.toAbsolutePath().toFile(); + public void pollFilesystemAndUpdateNodeSpecificConfigurationIfRequired(String location) { + try { + Set<Path> paths = watchForChange(location); + if (paths != null) { + for (Path path : paths) { + File file = path.toAbsolutePath().toFile(); - if (ConfigurationUtils.isConfig(file)) { - String repositoryKey = ConfigurationUtils.getConfigurationRepositoryKey(file); - ConfigurationRepository.lookup().populateOverrideConfigurtaion(repositoryKey, file); - } else { - ConfigurationRepository.lookup().removeOverrideConfigurtaion(file); - } + if (ConfigurationUtils.isConfig(file)) { + String repositoryKey = ConfigurationUtils.getConfigurationRepositoryKey(file); + ConfigurationRepository.lookup().populateOverrideConfiguration(repositoryKey, file); + } else { + ConfigurationRepository.lookup().removeOverrideConfiguration(file); + } + } + } + } catch (Exception exception) { + exception.printStackTrace(); } - } - } catch (Exception exception) { - exception.printStackTrace(); } - } - /** - * Notify changes towards. - * - * @param tenant the tenant - * @param component the component - * @param key the key - * @param myself the myself - * @throws Exception the exception - */ - public void notifyChangesTowards(String tenant, String component, String key, - ConfigurationChangeListener myself) throws Exception { - List<NotificationData> notificationList = - store.get(tenant + Constants.KEY_ELEMENTS_DELEMETER + component); - if (notificationList == null) { - notificationList = Collections.synchronizedList(new ArrayList<>()); - store.put(tenant + Constants.KEY_ELEMENTS_DELEMETER + component, notificationList); - executor.scheduleWithFixedDelay( - () -> triggerScanning(tenant + Constants.KEY_ELEMENTS_DELEMETER + component), 1, 30000, - TimeUnit.MILLISECONDS); + private Set<Path> watchForChange(String location) throws Exception { + if (location == null || location.trim().length() == 0) { + return Collections.emptySet(); + } + File file = new File(location); + if (!file.exists()) { + return Collections.emptySet(); + } + Path path = file.toPath(); + Set<Path> toReturn = new HashSet<>(); + try (final WatchService watchService = FileSystems.getDefault().newWatchService()) { + watchServiceCollection.put(location, watchService); + path.register(watchService, StandardWatchEventKinds.ENTRY_MODIFY, StandardWatchEventKinds.ENTRY_CREATE, + StandardWatchEventKinds.ENTRY_DELETE); + for (File dir : ConfigurationUtils.getAllFiles(file, true, true)) { + dir.toPath().register(watchService, StandardWatchEventKinds.ENTRY_MODIFY, + StandardWatchEventKinds.ENTRY_CREATE, StandardWatchEventKinds.ENTRY_DELETE); + } + while (true) { + final WatchKey wk = watchService.take(); + Thread.sleep(ConfigurationRepository.lookup() + .getConfigurationFor(Constants.DEFAULT_TENANT, Constants.DB_NAMESPACE) + .getLong("event.fetch.delay")); + for (WatchEvent<?> event : wk.pollEvents()) { + Object context = event.context(); + if (context instanceof Path) { + File newFile = new File(((Path) wk.watchable()).toFile(), context.toString()); + if (event.kind() == StandardWatchEventKinds.ENTRY_CREATE) { + if (newFile.isDirectory()) { + newFile.toPath().register(watchService, StandardWatchEventKinds.ENTRY_MODIFY, + StandardWatchEventKinds.ENTRY_CREATE, StandardWatchEventKinds.ENTRY_DELETE); + continue; + } + } else if (event.kind() == StandardWatchEventKinds.ENTRY_MODIFY) { + if (newFile.isDirectory()) { + continue; + } + } + toReturn.add(newFile.toPath()); + } + } + if (toReturn.isEmpty()) { + continue; + } + break; + } + } + return toReturn; } - notificationList.add(new NotificationData(tenant, component, key, myself)); - } - /** - * Stop notification towards. - * - * @param tenant the tenant - * @param component the component - * @param key the key - * @param myself the myself - * @throws Exception the exception - */ - public void stopNotificationTowards(String tenant, String component, String key, - ConfigurationChangeListener myself) throws Exception { - List<NotificationData> notificationList = - store.get(tenant + Constants.KEY_ELEMENTS_DELEMETER + component); - if (notificationList != null) { - boolean removed = - notificationList.remove(new NotificationData(tenant, component, key, myself)); - if (removed && notificationList.isEmpty()) { - store.remove(tenant + Constants.KEY_ELEMENTS_DELEMETER + component); - } + private void updateConfigurationValues(String tenant, String namespace, Map map) throws Exception { + MBeanServerConnection mbsc = ManagementFactory.getPlatformMBeanServer(); + ObjectName mbeanName = new ObjectName(Constants.MBEAN_NAME); + ConfigurationManager conf = JMX.newMBeanProxy(mbsc, mbeanName, ConfigurationManager.class, true); + conf.updateConfigurationValues(tenant, namespace, map); } - } - - private void triggerScanning(String key) { - if (store.get(key) != null) { - notificationExecutor.submit(() -> scanForChanges(key)); - } else { - throw new IllegalArgumentException("Notification service for " + key + " is suspended."); + public void shutdown() { + for (WatchService watch : watchServiceCollection.values()) { + try { + watch.close(); + } catch (IOException exception) { + //do nothing + } + } + executor.shutdownNow(); } - } - private void scanForChanges(String key) { - List<NotificationData> list = store.get(key); - if (list != null) { - list.stream() - .filter(NotificationData::isChanged) - .forEach(notificationData -> notificationExecutor.submit(() -> sendNotification(notificationData))); + public void notifyChangesTowards(String tenant, String component, String key, ConfigurationChangeListener myself) + throws Exception { + List<NotificationData> notificationList = store.get(tenant + Constants.KEY_ELEMENTS_DELIMETER + component); + if (notificationList == null) { + notificationList = Collections.synchronizedList(new ArrayList<>()); + store.put(tenant + Constants.KEY_ELEMENTS_DELIMETER + component, notificationList); + executor.scheduleWithFixedDelay( + () -> triggerScanning(tenant + Constants.KEY_ELEMENTS_DELIMETER + component), 1, 30000, + TimeUnit.MILLISECONDS); + } + notificationList.add(new NotificationData(tenant, component, key, myself)); } - } - private void sendNotification(NotificationData notificationData) { - try { - notificationData.dispatchNotification(); - } catch (Exception exception) { - exception.printStackTrace(); + private void triggerScanning(String key) { + if (store.get(key) != null) { + notificationExecutor.submit(() -> scanForChanges(key)); + } else { + throw new IllegalArgumentException("Notification service for " + key + " is suspended."); + } } - } - private Set<Path> watchForChange(String location) throws Exception { - if (location == null || location.trim().length() == 0) { - return Collections.emptySet(); + private void scanForChanges(String key) { + List<NotificationData> list = store.get(key); + if (list != null) { + list.stream().filter(NotificationData::isChanged) + .forEach(notificationData -> notificationExecutor.submit(() -> sendNotification(notificationData))); + } } - File file = new File(location); - if (!file.exists()) { - return Collections.emptySet(); + + private void sendNotification(NotificationData notificationData) { + try { + notificationData.dispatchNotification(); + } catch (Exception exception) { + exception.printStackTrace(); + } } - Path path = file.toPath(); - Set<Path> toReturn = new HashSet<>(); - try (final WatchService watchService = FileSystems.getDefault().newWatchService()) { - watchServiceCollection.put(location, watchService); - path.register(watchService, StandardWatchEventKinds.ENTRY_MODIFY, - StandardWatchEventKinds.ENTRY_CREATE, StandardWatchEventKinds.ENTRY_DELETE); - for (File dir : ConfigurationUtils.getAllFiles(file, true, true)) { - dir.toPath().register(watchService, StandardWatchEventKinds.ENTRY_MODIFY, - StandardWatchEventKinds.ENTRY_CREATE, StandardWatchEventKinds.ENTRY_DELETE); - } - while (true) { - final WatchKey wk = watchService.take(); - Thread.sleep(ConfigurationRepository.lookup() - .getConfigurationFor(Constants.DEFAULT_TENANT, Constants.DB_NAMESPACE) - .getLong("event.fetch.delay")); - for (WatchEvent<?> event : wk.pollEvents()) { - Object context = event.context(); - if (context instanceof Path) { - File newFile = new File(((Path) wk.watchable()).toFile(), context.toString()); - if (event.kind() == StandardWatchEventKinds.ENTRY_CREATE) { - if (newFile.isDirectory()) { - newFile.toPath().register(watchService, StandardWatchEventKinds.ENTRY_MODIFY, - StandardWatchEventKinds.ENTRY_CREATE, StandardWatchEventKinds.ENTRY_DELETE); - continue; - } - } else if (event.kind() == StandardWatchEventKinds.ENTRY_MODIFY) { - if (newFile.isDirectory()) { - continue; - } + + public void stopNotificationTowards(String tenant, String component, String key, ConfigurationChangeListener myself) + throws Exception { + List<NotificationData> notificationList = store.get(tenant + Constants.KEY_ELEMENTS_DELIMETER + component); + if (notificationList != null) { + boolean removed = notificationList.remove(new NotificationData(tenant, component, key, myself)); + if (removed && notificationList.isEmpty()) { + store.remove(tenant + Constants.KEY_ELEMENTS_DELIMETER + component); } - toReturn.add(newFile.toPath()); - } } - if (toReturn.isEmpty()) { - continue; - } - break; - } + } - return toReturn; - } - /** - * The type Notification data. - */ - static class NotificationData { + static class NotificationData { - /** - * The Tenant. - */ - final String tenant; - /** - * The Namespace. - */ - final String namespace; - /** - * The Key. - */ - final String key; - /** - * The Myself. - */ - final ConfigurationChangeListener myself; - /** - * The Current value. - */ - Object currentValue; - /** - * The Is array. - */ - boolean isArray; + final String tenant; - /** - * Instantiates a new Notification data. - * - * @param tenant the tenant - * @param component the component - * @param key the key - * @param myself the myself - * @throws Exception the exception - */ - public NotificationData(String tenant, String component, String key, - ConfigurationChangeListener myself) throws Exception { - this.tenant = tenant; - this.namespace = component; - this.key = key; - this.myself = myself; - if (!ConfigurationRepository.lookup().getConfigurationFor(tenant, component) - .containsKey(key)) { - throw new RuntimeException("Key[" + key + "] not found."); - } - isArray = ConfigurationUtils.isArray(tenant, component, key, Hint.DEFAULT.value()); - if (isArray) { - currentValue = ConfigurationManager.lookup().getAsStringValues(tenant, component, key); - } else { - currentValue = ConfigurationManager.lookup().getAsString(tenant, component, key); - } - } + final String namespace; - @Override - public boolean equals(Object obj) { - if (!(obj instanceof NotificationData)) { - return false; - } - NotificationData nd = (NotificationData) obj; - return Objects.equals(tenant, nd.tenant) - && Objects.equals(namespace, nd.namespace) - && Objects.equals(key, nd.key) - && Objects.equals(myself, nd.myself) - && Objects.equals(currentValue, nd.currentValue) // it's either String or List<String> - && isArray == nd.isArray; - } + final String key; - @Override - public int hashCode() { - return Objects.hash(tenant, namespace, key, myself, currentValue, isArray); - } + final ConfigurationChangeListener myself; - /** - * Is changed boolean. - * - * @return the boolean - */ - public boolean isChanged() { - Object latestValue; - try { - if (isArray) { - latestValue = ConfigurationManager.lookup().getAsStringValues(tenant, namespace, key); - } else { - latestValue = ConfigurationManager.lookup().getAsString(tenant, namespace, key); - } - if (!isArray) { - return !currentValue.equals(latestValue); - } else { - Collection<String> oldCollection = (Collection<String>) currentValue; - Collection<String> newCollection = (Collection<String>) latestValue; - for (String val : oldCollection) { - if (!newCollection.remove(val)) { - return true; + Object currentValue; + + boolean isArray; + + public NotificationData(String tenant, String component, String key, ConfigurationChangeListener myself) + throws Exception { + this.tenant = tenant; + this.namespace = component; + this.key = key; + this.myself = myself; + if (!ConfigurationRepository.lookup().getConfigurationFor(tenant, component).containsKey(key)) { + throw new RuntimeException("Key[" + key + "] not found."); + } + isArray = ConfigurationUtils.isArray(tenant, component, key, Hint.DEFAULT.value()); + if (isArray) { + currentValue = ConfigurationManager.lookup().getAsStringValues(tenant, component, key); + } else { + currentValue = ConfigurationManager.lookup().getAsString(tenant, component, key); } - } - return !newCollection.isEmpty(); } - } catch (Exception exception) { - return false; - } - } - /** - * Dispatch notification. - * - * @throws Exception the exception - */ - public void dispatchNotification() throws Exception { - Method method = null; - Vector<Object> parameters = null; - try { - Object latestValue; - if (isArray) { - latestValue = ConfigurationManager.lookup().getAsStringValues(tenant, namespace, key); - } else { - latestValue = ConfigurationManager.lookup().getAsString(tenant, namespace, key); + @Override + public int hashCode() { + return Objects.hash(tenant, namespace, key, myself, currentValue, isArray); } - Method[] methods = myself.getClass().getDeclaredMethods(); - if (methods != null && methods.length > 0) { - method = methods[0]; - int paramCount = method.getParameterCount(); - parameters = new Vector<>(); - if (paramCount > 4) { - if (tenant.equals(Constants.DEFAULT_TENANT)) { - parameters.add(null); - } else { - parameters.add(tenant); - } - } - if (paramCount > 3) { - if (namespace.equals(Constants.DEFAULT_NAMESPACE)) { - parameters.add(null); - } else { - parameters.add(namespace); + + @Override + public boolean equals(Object obj) { + if (!(obj instanceof NotificationData)) { + return false; } - } - parameters.add(key); - parameters.add(currentValue); - parameters.add(latestValue); - method.setAccessible(true); + NotificationData nd = (NotificationData) obj; + return Objects.equals(tenant, nd.tenant) && Objects.equals(namespace, nd.namespace) && Objects.equals(key, + nd.key) && Objects.equals(myself, nd.myself) && Objects.equals(currentValue, nd.currentValue) + // it's either String or List<String> + && isArray == nd.isArray; } - } catch (Exception exception) { - exception.printStackTrace(); - } finally { - isArray = ConfigurationUtils.isArray(tenant, namespace, key, Hint.DEFAULT.value()); - if (isArray) { - currentValue = ConfigurationManager.lookup().getAsStringValues(tenant, namespace, key); - } else { - currentValue = ConfigurationManager.lookup().getAsString(tenant, namespace, key); + + public boolean isChanged() { + Object latestValue; + try { + if (isArray) { + latestValue = ConfigurationManager.lookup().getAsStringValues(tenant, namespace, key); + } else { + latestValue = ConfigurationManager.lookup().getAsString(tenant, namespace, key); + } + if (!isArray) { + return !currentValue.equals(latestValue); + } else { + Collection<String> oldCollection = (Collection<String>) currentValue; + Collection<String> newCollection = (Collection<String>) latestValue; + for (String val : oldCollection) { + if (!newCollection.remove(val)) { + return true; + } + } + return !newCollection.isEmpty(); + } + } catch (Exception exception) { + return false; + } } - if (method != null && parameters != null) { - method.invoke(myself, parameters.toArray()); + + public void dispatchNotification() throws Exception { + Method method = null; + Vector<Object> parameters = null; + try { + Object latestValue; + if (isArray) { + latestValue = ConfigurationManager.lookup().getAsStringValues(tenant, namespace, key); + } else { + latestValue = ConfigurationManager.lookup().getAsString(tenant, namespace, key); + } + Method[] methods = myself.getClass().getDeclaredMethods(); + if (methods != null && methods.length > 0) { + method = methods[0]; + int paramCount = method.getParameterCount(); + parameters = new Vector<>(); + if (paramCount > 4) { + if (tenant.equals(Constants.DEFAULT_TENANT)) { + parameters.add(null); + } else { + parameters.add(tenant); + } + } + if (paramCount > 3) { + if (namespace.equals(Constants.DEFAULT_NAMESPACE)) { + parameters.add(null); + } else { + parameters.add(namespace); + } + } + parameters.add(key); + parameters.add(currentValue); + parameters.add(latestValue); + method.setAccessible(true); + } + } catch (Exception exception) { + exception.printStackTrace(); + } finally { + isArray = ConfigurationUtils.isArray(tenant, namespace, key, Hint.DEFAULT.value()); + if (isArray) { + currentValue = ConfigurationManager.lookup().getAsStringValues(tenant, namespace, key); + } else { + currentValue = ConfigurationManager.lookup().getAsString(tenant, namespace, key); + } + if (method != null && parameters != null) { + method.invoke(myself, parameters.toArray()); + } + } } - } } - } } |