Add support for commit confirmed capability 58/78858/4
authorAlexis de Talhouët <adetalhouet89@gmail.com>
Tue, 19 Feb 2019 15:02:00 +0000 (10:02 -0500)
committerAlexis de Talhouët <adetalhouet89@gmail.com>
Wed, 20 Feb 2019 21:02:16 +0000 (21:02 +0000)
Change-Id: I3608a6a62469d4b5dfc5fc69f610f9da186156c2
Issue-ID: CCSDK-790
Signed-off-by: Alexis de Talhouët <adetalhouet89@gmail.com>
components/scripts/python/ccsdk_netconf/netconfclient.py
ms/blueprintsprocessor/functions/netconf-executor/src/main/kotlin/org/onap/ccsdk/apps/blueprintsprocessor/functions/netconf/executor/api/NetconfRpcService.kt
ms/blueprintsprocessor/functions/netconf-executor/src/main/kotlin/org/onap/ccsdk/apps/blueprintsprocessor/functions/netconf/executor/core/NetconfRpcServiceImpl.kt
ms/blueprintsprocessor/functions/netconf-executor/src/main/kotlin/org/onap/ccsdk/apps/blueprintsprocessor/functions/netconf/executor/utils/NetconfMessageUtils.kt
ms/blueprintsprocessor/functions/netconf-executor/src/test/kotlin/org/onap/ccsdk/apps/blueprintsprocessor/functions/netconf/executor/utils/RpcMessageUtilsTest.kt

index dd7d2dc..d898ec0 100644 (file)
@@ -35,8 +35,14 @@ class NetconfClient:
                                                          edit_default_peration)
     return device_response
 
-  def commit(self):
-    device_response = self.netconf_rpc_client.commit()
+  def commit(self, confirmed=False, confirm_timeout=60, persist="",
+      persist_id=""):
+    device_response = self.netconf_rpc_client.commit(confirmed, confirm_timeout,
+                                                     persist, persist_id)
+    return device_response
+
+  def cancel_commit(self, persist_id=""):
+    device_response = self.netconf_rpc_client.cancelCommit(persist_id)
     return device_response
 
   def unlock(self, config_target=CONFIG_TARGET_CANDIDATE):
index e2c9bf9..5508521 100644 (file)
@@ -67,9 +67,29 @@ interface NetconfRpcService {
     /**
      * Commit
      *
+     * @param confirmed Perform a confirmed <commit> operation. If flag set to true,
+     * then it is expected to have a follow-up <commit> operation to confirm the request
+     * @param confirmTimeout Timeout period for confirmed commit, in seconds.
+     * @param persist Make the confirmed commit survive a session termination, and
+     * set a token on the ongoing confirmed commit.
+     * @param persistId Used to issue a follow-up confirmed commit or a confirming
+     * commit from any session, with the token from the previous <commit> operation.
+     * If unspecified, the confirm timeout defaults to 600 seconds.
      * @return Device response
      */
-    fun commit(): DeviceResponse
+    fun commit(confirmed: Boolean = false, confirmTimeout: Int = 60, persist: String = "",
+               persistId: String = ""): DeviceResponse
+
+    /**
+     * Cancels an ongoing confirmed commit.  If the <persist-id> parameter is not given,
+     * the <cancel-commit> operation MUST be issued on the same session that issued
+     * the confirmed commit.
+     *
+     * @param persistId Cancels a persistent confirmed commit.  The value MUST be equal
+     * to the value given in the <persist> parameter to the <commit> operation.
+     * If the value does not match, the operation fails with an "invalid-value" error.
+     */
+    fun cancelCommit(persistId: String = ""): DeviceResponse
 
     /**
      * Unlock
index be83555..8d8e0ea 100644 (file)
@@ -101,12 +101,12 @@ class NetconfRpcServiceImpl(private var deviceInfo: DeviceInfo) : NetconfRpcServ
         return output
     }
 
-    override fun commit(): DeviceResponse {
+    override fun commit(confirmed: Boolean, confirmTimeout: Int, persist: String, persistId: String): DeviceResponse {
         var output = DeviceResponse()
         val messageId = messageIdInteger.getAndIncrement().toString()
         log.info("$deviceInfo: commit: messageId($messageId)")
         try {
-            val messageContent = NetconfMessageUtils.commit(messageId)
+            val messageContent = NetconfMessageUtils.commit(messageId, confirmed, confirmTimeout, persist, persistId)
             output = asyncRpc(messageContent, messageId)
         } catch (e: Exception) {
             output.status = RpcStatus.FAILURE
@@ -115,6 +115,20 @@ class NetconfRpcServiceImpl(private var deviceInfo: DeviceInfo) : NetconfRpcServ
         return output
     }
 
+    override fun cancelCommit(persistId: String): DeviceResponse {
+        var output = DeviceResponse()
+        val messageId = messageIdInteger.getAndIncrement().toString()
+        log.info("$deviceInfo: cancelCommit: messageId($messageId)")
+        try {
+            val messageContent = NetconfMessageUtils.cancelCommit(messageId, persistId)
+            output = asyncRpc(messageContent, messageId)
+        } catch (e: Exception) {
+            output.status = RpcStatus.FAILURE
+            output.errorMessage = "$deviceInfo: failed in cancelCommit command $e.message"
+        }
+        return output
+    }
+
     override fun discardConfig(): DeviceResponse {
         var output = DeviceResponse()
         val messageId = messageIdInteger.getAndIncrement().toString()
index 7e48912..4de3860 100644 (file)
@@ -115,15 +115,45 @@ class NetconfMessageUtils {
             return doWrappedRpc(messageId, request.toString())
         }
 
-        fun commit(messageId: String): String {
-            val request = StringBuilder()
+        fun commit(messageId: String, confirmed: Boolean, confirmTimeout: Int, persist: String,
+                   persistId: String): String {
+
+            if (!persist.isEmpty() && !persistId.isEmpty()) {
+                throw NetconfException("Can't proceed <commit> with both persist($persist) and " +
+                        "persistId($persistId) specified. Only one should be specified.")
+            }
+            if (confirmed && !persistId.isEmpty()) {
+                throw NetconfException("Can't proceed <commit> with both confirmed flag and " +
+                        "persistId($persistId) specified. Only one should be specified.")
+            }
 
+            val request = StringBuilder()
             request.append("<commit>").append(NEW_LINE)
+            if (confirmed) {
+                request.append("<confirmed/>")
+                request.append("<confirm-timeout>$confirmTimeout</confirm-timeout>")
+                if (!persist.isEmpty()) {
+                    request.append("<persist>$persist</persist>")
+                }
+            }
+            if (!persistId.isEmpty()) {
+                request.append("<persist-id>$persistId</persist-id>")
+            }
             request.append("</commit>").append(NEW_LINE)
 
             return doWrappedRpc(messageId, request.toString())
         }
 
+        fun cancelCommit(messageId: String, persistId: String): String {
+            val request = StringBuilder()
+            request.append("<cancel-commit>").append(NEW_LINE)
+            if (!persistId.isEmpty()) {
+                request.append("<persist-id>$persistId</persist-id>")
+            }
+            request.append("</cancel-commit>").append(NEW_LINE)
+
+            return doWrappedRpc(messageId, request.toString())
+        }
 
         fun unlock(messageId: String, configType: String): String {
             val request = StringBuilder()
index 2cd2d10..d4c27b1 100644 (file)
@@ -18,6 +18,8 @@ package org.onap.ccsdk.apps.blueprintsprocessor.functions.netconf.executor.utils
 import org.junit.Assert
 import org.junit.Assert.assertTrue
 import org.junit.Test
+import org.onap.ccsdk.apps.blueprintsprocessor.functions.netconf.executor.api.NetconfException
+import kotlin.test.fail
 
 class RpcMessageUtilsTest {
 
@@ -32,14 +34,14 @@ class RpcMessageUtilsTest {
         val configType = NetconfDatastore.CANDIDATE.datastore
         val filterContent = "Test-Filter-Content"
 
-        val result = NetconfMessageUtils.getConfig(messageId, configType, filterContent).replace("[\n\r\t]".toRegex(), "")
+        val result =
+            NetconfMessageUtils.getConfig(messageId, configType, filterContent).replace("[\n\r\t]".toRegex(), "")
 
         assertTrue(NetconfMessageUtils.validateRPCXML(result))
         Assert.assertEquals(checkString, result)
     }
 
 
-
     @Test
     fun editConfig() {
         val checkString = ("<?xml version=\"1.0\" encoding=\"UTF-8\"?>"
@@ -51,7 +53,8 @@ class RpcMessageUtilsTest {
         val configType = NetconfDatastore.CANDIDATE.datastore
         val filterContent = "Test-Filter-Content"
 
-        val result = NetconfMessageUtils.getConfig(messageId, configType, filterContent).replace("[\n\r\t]".toRegex(), "")
+        val result =
+            NetconfMessageUtils.getConfig(messageId, configType, filterContent).replace("[\n\r\t]".toRegex(), "")
 
         assertTrue(NetconfMessageUtils.validateRPCXML(result))
         Assert.assertEquals(checkString, result)
@@ -72,6 +75,40 @@ class RpcMessageUtilsTest {
         Assert.assertEquals(checkString, result)
     }
 
+    @Test
+    fun cancelCommit() {
+        val checkString =
+            ("<?xml version=\"1.0\" encoding=\"UTF-8\"?>" +
+                    "<rpc message-id=\"Test-Message-ID\" xmlns=\"urn:ietf:params:xml:ns:netconf:base:1.0\">" +
+                    "<cancel-commit>" +
+                    "<persist-id>1234</persist-id>" +
+                    "</cancel-commit></rpc>")
+
+        val messageId = "Test-Message-ID"
+
+        val cancelCommitPersistId =
+            NetconfMessageUtils.cancelCommit(messageId, "1234").replace("[\n\r\t]".toRegex(), "")
+
+        assertTrue(NetconfMessageUtils.validateRPCXML(cancelCommitPersistId))
+        Assert.assertEquals(checkString, cancelCommitPersistId)
+    }
+
+    @Test
+    fun cancelCommitNoPersistId() {
+        val checkString =
+            ("<?xml version=\"1.0\" encoding=\"UTF-8\"?>" +
+                    "<rpc message-id=\"Test-Message-ID\" xmlns=\"urn:ietf:params:xml:ns:netconf:base:1.0\">" +
+                    "<cancel-commit>" +
+                    "</cancel-commit></rpc>")
+
+        val messageId = "Test-Message-ID"
+
+        val cancelCommitNoPersistId = NetconfMessageUtils.cancelCommit(messageId, "").replace("[\n\r\t]".toRegex(), "")
+
+        assertTrue(NetconfMessageUtils.validateRPCXML(cancelCommitNoPersistId))
+        Assert.assertEquals(checkString, cancelCommitNoPersistId)
+    }
+
     @Test
     fun commit() {
         val checkString = ("<?xml version=\"1.0\" encoding=\"UTF-8\"?>"
@@ -80,11 +117,69 @@ class RpcMessageUtilsTest {
 
         val messageId = "Test-Message-ID"
 
-        val result = NetconfMessageUtils.commit(messageId).replace("[\n\r\t]".toRegex(), "")
+        val commit = NetconfMessageUtils.commit(messageId, false, 0, "", "").replace("[\n\r\t]".toRegex(), "")
+
+        val commitWithPersistButNotConfirmed =
+            NetconfMessageUtils.commit(messageId, false, 0, "1234", "").replace("[\n\r\t]".toRegex(), "")
+
+        assertTrue(NetconfMessageUtils.validateRPCXML(commit))
+        Assert.assertEquals(checkString, commit)
+        Assert.assertEquals(checkString, commitWithPersistButNotConfirmed)
+
+    }
+
+    @Test
+    fun commitPersistId() {
+        val checkString =
+            ("<?xml version=\"1.0\" encoding=\"UTF-8\"?>" +
+                    "<rpc message-id=\"Test-Message-ID\" xmlns=\"urn:ietf:params:xml:ns:netconf:base:1.0\">" +
+                    "<commit>" +
+                    "<persist-id>1234</persist-id>" +
+                    "</commit></rpc>")
+
+        val messageId = "Test-Message-ID"
+
+        val result = NetconfMessageUtils.commit(messageId, false, 30, "", "1234").replace("[\n\r\t]".toRegex(), "")
+        assertTrue(NetconfMessageUtils.validateRPCXML(result))
+        Assert.assertEquals(checkString, result)
+
+        try {
+            NetconfMessageUtils.commit(messageId, true, 30, "", "1234").replace("[\n\r\t]".toRegex(), "")
+        } catch (e: NetconfException) {
+            Assert.assertEquals("Can't proceed <commit> with both confirmed flag and persistId(1234) specified. Only one should be specified.",
+                e.message)
+            return
+        }
+
+        fail()
+    }
+
+    @Test
+    fun commitPersist() {
+        val checkString =
+            ("<?xml version=\"1.0\" encoding=\"UTF-8\"?>" +
+                    "<rpc message-id=\"Test-Message-ID\" xmlns=\"urn:ietf:params:xml:ns:netconf:base:1.0\">" +
+                    "<commit>" +
+                    "<confirmed/>" +
+                    "<confirm-timeout>30</confirm-timeout>" +
+                    "<persist>1234</persist>" +
+                    "</commit></rpc>")
+
+        val messageId = "Test-Message-ID"
+
+        val result = NetconfMessageUtils.commit(messageId, true, 30, "1234", "").replace("[\n\r\t]".toRegex(), "")
 
         assertTrue(NetconfMessageUtils.validateRPCXML(result))
         Assert.assertEquals(checkString, result)
 
+        try {
+            NetconfMessageUtils.commit(messageId, false, 30, "1234", "1234").replace("[\n\r\t]".toRegex(), "")
+        } catch (e: NetconfException) {
+            Assert.assertEquals("Can't proceed <commit> with both persist(1234) and persistId(1234) specified. Only one should be specified.",
+                e.message)
+            return
+        }
+        fail()
     }
 
     @Test