Manually cherry-picked from
https://git.opendaylight.org/gerrit/#/c/28985 as the files have moved in
master.
Also the code has changed slightly in master, specifically the
ConfigPusherImplTest no longer uses a Thread uncaught exception handler
for verification. However it does rely on exceptions thrown from the
ConfigPusherImpl so, to keep the same behavior, I added a
propagateExceptions flag to ConfigPusherImpl#process. The
ConfigPersisterActivator production code passes false so unchecked
exceptions aren't handled as uncaught exceptions.
Change-Id: Iabc22030abc22cf11a1476986ba3d3366021b4fb
Signed-off-by: Tom Pantelis <tpanteli@brocade.com>
- public void process(List<AutoCloseable> autoCloseables, MBeanServerConnection platformMBeanServer, Persister persisterAggregator) throws InterruptedException {
- while(true) {
- processSingle(autoCloseables, platformMBeanServer, persisterAggregator);
+ public void process(List<AutoCloseable> autoCloseables, MBeanServerConnection platformMBeanServer,
+ Persister persisterAggregator, boolean propagateExceptions) throws InterruptedException {
+ while(processSingle(autoCloseables, platformMBeanServer, persisterAggregator, propagateExceptions)) {
+ ;
- void processSingle(final List<AutoCloseable> autoCloseables, final MBeanServerConnection platformMBeanServer, final Persister persisterAggregator) throws InterruptedException {
+ boolean processSingle(final List<AutoCloseable> autoCloseables, final MBeanServerConnection platformMBeanServer,
+ final Persister persisterAggregator, boolean propagateExceptions) throws InterruptedException {
final List<? extends ConfigSnapshotHolder> configs = queue.take();
try {
internalPushConfigs(configs);
final List<? extends ConfigSnapshotHolder> configs = queue.take();
try {
internalPushConfigs(configs);
}
LOG.debug("ConfigPusher has pushed configs {}", configs);
}
LOG.debug("ConfigPusher has pushed configs {}", configs);
- } catch (DocumentedException e) {
- LOG.error("Error pushing configs {}",configs);
- throw new IllegalStateException(e);
+ } catch (Exception e) {
+ // Exceptions are logged to error downstream
+ LOG.debug("Failed to push some of configs: {}", configs, e);
+
+ if(propagateExceptions) {
+ if(e instanceof RuntimeException) {
+ throw (RuntimeException)e;
+ } else {
+ throw new IllegalStateException(e);
+ }
+ } else {
+ return false;
+ }
// start pushing snapshots
for (ConfigSnapshotHolder configSnapshotHolder : configs) {
if (configSnapshotHolder != null) {
// start pushing snapshots
for (ConfigSnapshotHolder configSnapshotHolder : configs) {
if (configSnapshotHolder != null) {
+ LOG.info("Pushing configuration snapshot {}", configSnapshotHolder);
boolean pushResult = false;
try {
pushResult = pushConfigWithConflictingVersionRetries(configSnapshotHolder);
} catch (ConfigSnapshotFailureException e) {
boolean pushResult = false;
try {
pushResult = pushConfigWithConflictingVersionRetries(configSnapshotHolder);
} catch (ConfigSnapshotFailureException e) {
- LOG.warn("Failed to apply configuration snapshot: {}. Config snapshot is not semantically correct and will be IGNORED. " +
+ LOG.error("Failed to apply configuration snapshot: {}. Config snapshot is not semantically correct and will be IGNORED. " +
"for detailed information see enclosed exception.", e.getConfigIdForReporting(), e);
throw new IllegalStateException("Failed to apply configuration snapshot " + e.getConfigIdForReporting(), e);
"for detailed information see enclosed exception.", e.getConfigIdForReporting(), e);
throw new IllegalStateException("Failed to apply configuration snapshot " + e.getConfigIdForReporting(), e);
+ } catch (Exception e) {
+ String msg = String.format("Failed to apply configuration snapshot: %s", configSnapshotHolder);
+ LOG.error(msg, e);
+ throw new IllegalStateException(msg, e);
- LOG.debug("Config snapshot pushed successfully: {}, result: {}", configSnapshotHolder, result);
+
+ LOG.info("Successfully pushed configuration snapshot {}", configSnapshotHolder);
result.put(configSnapshotHolder, pushResult);
}
}
result.put(configSnapshotHolder, pushResult);
}
}
}
if(context != null) {
registration = context.registerService(ConfigPusher.class.getName(), configPusher, null);
}
if(context != null) {
registration = context.registerService(ConfigPusher.class.getName(), configPusher, null);
- configPusher.process(autoCloseables, platformMBeanServer, persisterAggregator);
+ configPusher.process(autoCloseables, platformMBeanServer, persisterAggregator, false);
} else {
LOG.warn("Unable to process configs as BundleContext is null");
}
} else {
LOG.warn("Unable to process configs as BundleContext is null");
}
package org.opendaylight.controller.config.persist.impl;
import static org.junit.Assert.assertEquals;
package org.opendaylight.controller.config.persist.impl;
import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertTrue;
import static org.junit.Assert.fail;
import static org.mockito.Matchers.any;
import static org.junit.Assert.assertTrue;
import static org.junit.Assert.fail;
import static org.mockito.Matchers.any;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.times;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.times;
import static org.mockito.Mockito.verify;
+import com.google.common.base.Throwables;
import com.google.common.collect.Lists;
import com.google.common.collect.Sets;
import java.lang.management.ManagementFactory;
import com.google.common.collect.Lists;
import com.google.common.collect.Sets;
import java.lang.management.ManagementFactory;
configPusher.pushConfigs(Collections.singletonList(mockedConfigSnapshot));
try {
configPusher.pushConfigs(Collections.singletonList(mockedConfigSnapshot));
try {
- configPusher.process(Lists.<AutoCloseable>newArrayList(), ManagementFactory.getPlatformMBeanServer(), mockedAggregator);
+ configPusher.process(Lists.<AutoCloseable>newArrayList(), ManagementFactory.getPlatformMBeanServer(),
+ mockedAggregator, true);
} catch(IllegalStateException e) {
} catch(IllegalStateException e) {
- assertNotNull(e.getCause());
- assertTrue(e.getCause() instanceof ConfigPusherImpl.NotEnoughCapabilitiesException);
- final Set<String> missingCaps = ((ConfigPusherImpl.NotEnoughCapabilitiesException) e.getCause()).getMissingCaps();
+ Throwable cause = Throwables.getRootCause(e);
+ assertTrue(cause instanceof ConfigPusherImpl.NotEnoughCapabilitiesException);
+ final Set<String> missingCaps = ((ConfigPusherImpl.NotEnoughCapabilitiesException) cause).getMissingCaps();
assertEquals(missingCaps.size(), 1);
assertEquals(missingCaps.iterator().next(), "required-cap");
return;
assertEquals(missingCaps.size(), 1);
assertEquals(missingCaps.iterator().next(), "required-cap");
return;
final ConfigPusherImpl configPusher = new ConfigPusherImpl(facadeFactory, 0, 0);
configPusher.pushConfigs(Collections.singletonList(mockedConfigSnapshot));
final ConfigPusherImpl configPusher = new ConfigPusherImpl(facadeFactory, 0, 0);
configPusher.pushConfigs(Collections.singletonList(mockedConfigSnapshot));
- configPusher.processSingle(Lists.<AutoCloseable>newArrayList(), mBeanServer, mockedAggregator);
+ configPusher.processSingle(Lists.<AutoCloseable>newArrayList(), mBeanServer, mockedAggregator, true);
verify(facade).executeConfigExecution(cfgExec);
verify(facade).commitSilentTransaction();
verify(facade).executeConfigExecution(cfgExec);
verify(facade).commitSilentTransaction();
configPusher.pushConfigs(Collections.singletonList(mockedConfigSnapshot));
try {
configPusher.pushConfigs(Collections.singletonList(mockedConfigSnapshot));
try {
- configPusher.processSingle(Lists.<AutoCloseable>newArrayList(), mBeanServer, mockedAggregator);
+ configPusher.processSingle(Lists.<AutoCloseable>newArrayList(), mBeanServer, mockedAggregator, true);
} catch (IllegalStateException e) {
} catch (IllegalStateException e) {
- assertNotNull(e.getCause());
- assertTrue(e.getCause() instanceof ConflictingVersionException);
+ Throwable cause = Throwables.getRootCause(e);
+ assertTrue(cause instanceof ConflictingVersionException);
final ConfigPusherImpl configPusher = new ConfigPusherImpl(facadeFactory, 5000, 5000);
configPusher.pushConfigs(Collections.singletonList(mockedConfigSnapshot));
final ConfigPusherImpl configPusher = new ConfigPusherImpl(facadeFactory, 5000, 5000);
configPusher.pushConfigs(Collections.singletonList(mockedConfigSnapshot));
- configPusher.processSingle(Lists.<AutoCloseable>newArrayList(), mBeanServer, mockedAggregator);
+ configPusher.processSingle(Lists.<AutoCloseable>newArrayList(), mBeanServer, mockedAggregator, true);
verify(facade, times(3)).executeConfigExecution(cfgExec);
verify(facade, times(3)).commitSilentTransaction();
verify(facade, times(3)).executeConfigExecution(cfgExec);
verify(facade, times(3)).commitSilentTransaction();