From: Maros Marsalek Date: Fri, 29 May 2015 12:39:06 +0000 (+0200) Subject: BUG-2150 Report errors for semantic issues with config snapshots X-Git-Tag: release/beryllium~504 X-Git-Url: https://git.opendaylight.org/gerrit/gitweb?p=controller.git;a=commitdiff_plain;h=12613b3cfb0af8d185e430ffd404298191bee518 BUG-2150 Report errors for semantic issues with config snapshots Change-Id: Ie8cf61e71649f64147a3cff6f92ae67b26454cb9 Signed-off-by: Maros Marsalek (cherry picked from commit 2763c33336189a88b1c7ae1cc1c5311709610ee2) --- diff --git a/opendaylight/netconf/config-persister-impl/src/main/java/org/opendaylight/controller/netconf/persist/impl/ConfigPusherImpl.java b/opendaylight/netconf/config-persister-impl/src/main/java/org/opendaylight/controller/netconf/persist/impl/ConfigPusherImpl.java index 0e179ad7d5..c41a2f4d16 100644 --- a/opendaylight/netconf/config-persister-impl/src/main/java/org/opendaylight/controller/netconf/persist/impl/ConfigPusherImpl.java +++ b/opendaylight/netconf/config-persister-impl/src/main/java/org/opendaylight/controller/netconf/persist/impl/ConfigPusherImpl.java @@ -98,7 +98,14 @@ public class ConfigPusherImpl implements ConfigPusher { // start pushing snapshots: for (ConfigSnapshotHolder configSnapshotHolder : configs) { if(configSnapshotHolder != null) { - EditAndCommitResponse editAndCommitResponseWithRetries = pushConfigWithConflictingVersionRetries(configSnapshotHolder); + EditAndCommitResponse editAndCommitResponseWithRetries = null; + try { + editAndCommitResponseWithRetries = pushConfigWithConflictingVersionRetries(configSnapshotHolder); + } catch (ConfigSnapshotFailureException e) { + LOG.warn("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); + } LOG.debug("Config snapshot pushed successfully: {}, result: {}", configSnapshotHolder, result); result.put(configSnapshotHolder, editAndCommitResponseWithRetries); } @@ -113,7 +120,7 @@ public class ConfigPusherImpl implements ConfigPusher { * is caught, whole process is retried - new service instance need to be obtained from the factory. Closes * {@link NetconfOperationService} after each use. */ - private synchronized EditAndCommitResponse pushConfigWithConflictingVersionRetries(ConfigSnapshotHolder configSnapshotHolder) throws NetconfDocumentedException { + private synchronized EditAndCommitResponse pushConfigWithConflictingVersionRetries(ConfigSnapshotHolder configSnapshotHolder) throws ConfigSnapshotFailureException { ConflictingVersionException lastException; Stopwatch stopwatch = Stopwatch.createUnstarted(); do { @@ -200,6 +207,20 @@ public class ConfigPusherImpl implements ConfigPusher { } } + private static final class ConfigSnapshotFailureException extends ConfigPusherException { + + private final String configIdForReporting; + + public ConfigSnapshotFailureException(final String configIdForReporting, final String operationNameForReporting, final Exception e) { + super(String.format("Failed to apply config snapshot: %s during phase: %s", configIdForReporting, operationNameForReporting), e); + this.configIdForReporting = configIdForReporting; + } + + public String getConfigIdForReporting() { + return configIdForReporting; + } + } + /** * Get NetconfOperationService iif all required capabilities are present. * @@ -257,7 +278,7 @@ public class ConfigPusherImpl implements ConfigPusher { * @throws java.lang.RuntimeException if edit-config or commit fails otherwise */ private synchronized EditAndCommitResponse pushConfig(ConfigSnapshotHolder configSnapshotHolder, NetconfOperationService operationService) - throws ConflictingVersionException, NetconfDocumentedException { + throws ConflictingVersionException, ConfigSnapshotFailureException { Element xmlToBePersisted; try { @@ -289,14 +310,19 @@ public class ConfigPusherImpl implements ConfigPusher { return new EditAndCommitResponse(editResponseMessage, commitResponseMessage); } - private NetconfOperation findOperation(NetconfMessage request, NetconfOperationService operationService) throws NetconfDocumentedException { + private NetconfOperation findOperation(NetconfMessage request, NetconfOperationService operationService) { TreeMap allOperations = new TreeMap<>(); Set netconfOperations = operationService.getNetconfOperations(); if (netconfOperations.isEmpty()) { throw new IllegalStateException("Possible code error: no config operations"); } for (NetconfOperation netconfOperation : netconfOperations) { - HandlingPriority handlingPriority = netconfOperation.canHandle(request.getDocument()); + HandlingPriority handlingPriority = null; + try { + handlingPriority = netconfOperation.canHandle(request.getDocument()); + } catch (NetconfDocumentedException e) { + throw new IllegalStateException("Possible code error: canHandle threw exception", e); + } allOperations.put(handlingPriority, netconfOperation); } Entry highestEntry = allOperations.lastEntry(); @@ -308,24 +334,23 @@ public class ConfigPusherImpl implements ConfigPusher { private Document sendRequestGetResponseCheckIsOK(NetconfMessage request, NetconfOperationService operationService, String operationNameForReporting, String configIdForReporting) - throws ConflictingVersionException, NetconfDocumentedException { + throws ConflictingVersionException, ConfigSnapshotFailureException { NetconfOperation operation = findOperation(request, operationService); Document response; try { response = operation.handle(request.getDocument(), NetconfOperationChainedExecution.EXECUTION_TERMINATION_POINT); - } catch (NetconfDocumentedException | RuntimeException e) { - if (e instanceof NetconfDocumentedException && e.getCause() instanceof ConflictingVersionException) { + return NetconfUtil.checkIsMessageOk(response); + } catch (NetconfDocumentedException e) { + if (e.getCause() instanceof ConflictingVersionException) { throw (ConflictingVersionException) e.getCause(); } - throw new IllegalStateException("Failed to send " + operationNameForReporting + - " for configuration " + configIdForReporting, e); + throw new ConfigSnapshotFailureException(configIdForReporting, operationNameForReporting, e); } - return NetconfUtil.checkIsMessageOk(response); } // load editConfig.xml template, populate /rpc/edit-config/config with parameter - private static NetconfMessage createEditConfigMessage(Element dataElement) throws NetconfDocumentedException { + private static NetconfMessage createEditConfigMessage(Element dataElement) { String editConfigResourcePath = "/netconfOp/editConfig.xml"; try (InputStream stream = ConfigPersisterNotificationHandler.class.getResourceAsStream(editConfigResourcePath)) { checkNotNull(stream, "Unable to load resource " + editConfigResourcePath); @@ -341,7 +366,7 @@ public class ConfigPusherImpl implements ConfigPusher { } editConfigElement.appendChild(configWrapper.getDomElement()); return new NetconfMessage(doc); - } catch (IOException | SAXException e) { + } catch (IOException | SAXException | NetconfDocumentedException e) { // error reading the xml file bundled into the jar throw new IllegalStateException("Error while opening local resource " + editConfigResourcePath, e); }