Prevent ConfigPusher from killing its thread
[controller.git] / opendaylight / netconf / config-persister-impl / src / main / java / org / opendaylight / controller / netconf / persist / impl / ConfigPusher.java
index 6e62a982d1588217215f999011b6cfba4a443e46..0a844b69ab8a61d37d39bd11fa1a1f4bf2b37867 100644 (file)
@@ -72,10 +72,15 @@ public class ConfigPusher {
     }
 
     private synchronized NetconfClient pushAllConfigs(List<ConfigSnapshotHolder> configs) throws InterruptedException {
+        // first just make sure we can connect to netconf, even if nothing is being pushed
         NetconfClient netconfClient = makeNetconfConnection(Collections.<String>emptySet(), Optional.<NetconfClient>absent());
+        // start pushing snapshots:
         for (ConfigSnapshotHolder configSnapshotHolder: configs){
             netconfClient = pushSnapshotWithRetries(configSnapshotHolder, Optional.of(netconfClient));
+            logger.debug("Config snapshot pushed successfully: {}", configSnapshotHolder);
         }
+
+        logger.debug("All configuration snapshots have been pushed successfully.");
         return netconfClient;
     }
 
@@ -83,7 +88,7 @@ public class ConfigPusher {
                                                                Optional<NetconfClient> oldClientForPossibleReuse)
             throws InterruptedException {
 
-        ConflictingVersionException lastException = null;
+        Exception lastException = null;
         int maxAttempts = 30;
         for(int i = 0 ; i < maxAttempts; i++) {
             NetconfClient netconfClient = makeNetconfConnection(configSnapshotHolder.getCapabilities(), oldClientForPossibleReuse);
@@ -91,11 +96,11 @@ public class ConfigPusher {
             try {
                 pushLastConfig(configSnapshotHolder, netconfClient);
                 return netconfClient;
-            } catch(ConflictingVersionException e) {
+            } catch (ConflictingVersionException | IOException e) {
                 Util.closeClientAndDispatcher(netconfClient);
                 lastException = e;
                 Thread.sleep(1000);
-            } catch (SAXException | IOException e) {
+            } catch (SAXException e) {
                 throw new IllegalStateException("Unable to load last config", e);
             }
         }
@@ -106,21 +111,16 @@ public class ConfigPusher {
     /**
      * @param expectedCaps capabilities that server hello must contain. Will retry until all are found or throws RuntimeException.
      *                     If empty set is provided, will only make sure netconf client successfuly connected to the server.
-     * @param oldClientForPossibleReuse if present, try to get expected capabilities from it before closing it and retrying with
-     *                                  new client connection.
+     * @param maybeOldClient if present, close it.
      * @return NetconfClient that has all required capabilities from server.
      */
     private synchronized NetconfClient makeNetconfConnection(Set<String> expectedCaps,
-                                                             Optional<NetconfClient> oldClientForPossibleReuse)
+                                                             Optional<NetconfClient> maybeOldClient)
             throws InterruptedException {
 
-        if (oldClientForPossibleReuse.isPresent()) {
-            NetconfClient oldClient = oldClientForPossibleReuse.get();
-            if (Util.isSubset(oldClient, expectedCaps)) {
-                return oldClient;
-            } else {
-                Util.closeClientAndDispatcher(oldClient);
-            }
+        if (maybeOldClient.isPresent()) {
+            NetconfClient oldClient = maybeOldClient.get();
+            Util.closeClientAndDispatcher(oldClient);
         }
 
         // TODO think about moving capability subset check to netconf client
@@ -192,16 +192,16 @@ public class ConfigPusher {
         logger.trace("Detailed message {}", response);
     }
 
-    private static NetconfMessage getResponse(NetconfMessage request, NetconfClient netconfClient) {
+    private static NetconfMessage getResponse(NetconfMessage request, NetconfClient netconfClient) throws IOException {
         try {
             return netconfClient.sendMessage(request, NETCONF_SEND_ATTEMPTS, NETCONF_SEND_ATTEMPT_MS_DELAY);
-        } catch(RuntimeException e) {
-            logger.error("Error while sending message {} to {}", request, netconfClient);
-            throw e;
+        } catch (RuntimeException e) {
+            logger.debug("Error while executing netconf transaction {} to {}", request, netconfClient, e);
+            throw new IOException("Failed to execute netconf transaction", e);
         }
     }
 
-    private static NetconfMessage createEditConfigMessage(Element dataElement, String editConfigResourcename) {
+    private static NetconfMessage createEditConfigMessage(Element dataElement, String editConfigResourcename) throws IOException, SAXException {
         try (InputStream stream = ConfigPersisterNotificationHandler.class.getResourceAsStream(editConfigResourcename)) {
             Preconditions.checkNotNull(stream, "Unable to load resource " + editConfigResourcename);
 
@@ -217,16 +217,18 @@ public class ConfigPusher {
             editConfigElement.appendChild(configWrapper.getDomElement());
             return new NetconfMessage(doc);
         } catch (IOException | SAXException e) {
-            throw new RuntimeException("Unable to parse message from resources " + editConfigResourcename, e);
+            logger.debug("Failed to create edit-config message for resource {}", editConfigResourcename, e);
+            throw e;
         }
     }
 
-    private static NetconfMessage getNetconfMessageFromResource(String resource) {
+    private static NetconfMessage getNetconfMessageFromResource(String resource) throws IOException, SAXException {
         try (InputStream stream = ConfigPusher.class.getResourceAsStream(resource)) {
             Preconditions.checkNotNull(stream, "Unable to load resource " + resource);
             return new NetconfMessage(XmlUtil.readXmlToDocument(stream));
         } catch (SAXException | IOException e) {
-            throw new RuntimeException("Unable to parse message from resources " + resource, e);
+            logger.debug("Failed to parse netconf message for resource {}", resource, e);
+            throw e;
         }
     }
 }