Rework netconf-executor
authorAlexis de Talhouët <adetalhouet89@gmail.com>
Wed, 13 Feb 2019 04:05:01 +0000 (23:05 -0500)
committerAlexis de Talhouët <adetalhouet89@gmail.com>
Sun, 17 Feb 2019 00:08:17 +0000 (19:08 -0500)
- rework connection logic
- rework rpc service
- rework netconf session handling
- rework netconf device communicator
- rework python netconf bindings
- rework python netconf client
- add python script showcasing netconf functions

Change-Id: Ibb9bf811e7d96e993aa866371d56c172de83be2c
Issue-ID: CCSDK-790:x
Signed-off-by: Alexis de Talhouët <adetalhouet89@gmail.com>
29 files changed:
ms/blueprintsprocessor/application/pom.xml
ms/blueprintsprocessor/application/src/main/resources/application.properties
ms/blueprintsprocessor/distribution/pom.xml
ms/blueprintsprocessor/functions/netconf-executor/src/main/kotlin/org/onap/ccsdk/apps/blueprintsprocessor/functions/netconf/executor/ComponentNetconfExecutor.kt
ms/blueprintsprocessor/functions/netconf-executor/src/main/kotlin/org/onap/ccsdk/apps/blueprintsprocessor/functions/netconf/executor/NetconfComponentFunction.kt
ms/blueprintsprocessor/functions/netconf-executor/src/main/kotlin/org/onap/ccsdk/apps/blueprintsprocessor/functions/netconf/executor/NetconfDevice.kt [new file with mode: 0644]
ms/blueprintsprocessor/functions/netconf-executor/src/main/kotlin/org/onap/ccsdk/apps/blueprintsprocessor/functions/netconf/executor/NetconfException.kt [deleted file]
ms/blueprintsprocessor/functions/netconf-executor/src/main/kotlin/org/onap/ccsdk/apps/blueprintsprocessor/functions/netconf/executor/NetconfExecutorConfiguration.kt [deleted file]
ms/blueprintsprocessor/functions/netconf-executor/src/main/kotlin/org/onap/ccsdk/apps/blueprintsprocessor/functions/netconf/executor/NetconfRpcService.kt [deleted file]
ms/blueprintsprocessor/functions/netconf-executor/src/main/kotlin/org/onap/ccsdk/apps/blueprintsprocessor/functions/netconf/executor/api/DeviceInfo.kt [moved from ms/blueprintsprocessor/functions/netconf-executor/src/main/kotlin/org/onap/ccsdk/apps/blueprintsprocessor/functions/netconf/executor/interfaces/DeviceInfo.kt with 79% similarity]
ms/blueprintsprocessor/functions/netconf-executor/src/main/kotlin/org/onap/ccsdk/apps/blueprintsprocessor/functions/netconf/executor/api/NetconfException.kt [moved from ms/blueprintsprocessor/functions/netconf-executor/src/main/kotlin/org/onap/ccsdk/apps/blueprintsprocessor/functions/netconf/executor/data/NetconfSshClientLib.kt with 65% similarity]
ms/blueprintsprocessor/functions/netconf-executor/src/main/kotlin/org/onap/ccsdk/apps/blueprintsprocessor/functions/netconf/executor/api/NetconfMessage.kt [new file with mode: 0644]
ms/blueprintsprocessor/functions/netconf-executor/src/main/kotlin/org/onap/ccsdk/apps/blueprintsprocessor/functions/netconf/executor/api/NetconfRpcService.kt [moved from ms/blueprintsprocessor/functions/netconf-executor/src/main/kotlin/org/onap/ccsdk/apps/blueprintsprocessor/functions/netconf/executor/interfaces/NetconfRpcClientService.kt with 72% similarity]
ms/blueprintsprocessor/functions/netconf-executor/src/main/kotlin/org/onap/ccsdk/apps/blueprintsprocessor/functions/netconf/executor/api/NetconfSession.kt [new file with mode: 0644]
ms/blueprintsprocessor/functions/netconf-executor/src/main/kotlin/org/onap/ccsdk/apps/blueprintsprocessor/functions/netconf/executor/api/NetconfSessionListener.kt [moved from ms/blueprintsprocessor/functions/netconf-executor/src/main/kotlin/org/onap/ccsdk/apps/blueprintsprocessor/functions/netconf/executor/interfaces/NetconfSessionDelegate.java with 69% similarity]
ms/blueprintsprocessor/functions/netconf-executor/src/main/kotlin/org/onap/ccsdk/apps/blueprintsprocessor/functions/netconf/executor/core/NetconfDeviceCommunicator.kt [moved from ms/blueprintsprocessor/functions/netconf-executor/src/main/kotlin/org/onap/ccsdk/apps/blueprintsprocessor/functions/netconf/executor/core/NetconfStreamThread.kt with 57% similarity]
ms/blueprintsprocessor/functions/netconf-executor/src/main/kotlin/org/onap/ccsdk/apps/blueprintsprocessor/functions/netconf/executor/core/NetconfRpcServiceImpl.kt [new file with mode: 0644]
ms/blueprintsprocessor/functions/netconf-executor/src/main/kotlin/org/onap/ccsdk/apps/blueprintsprocessor/functions/netconf/executor/core/NetconfSessionFactory.kt [deleted file]
ms/blueprintsprocessor/functions/netconf-executor/src/main/kotlin/org/onap/ccsdk/apps/blueprintsprocessor/functions/netconf/executor/core/NetconfSessionImpl.kt
ms/blueprintsprocessor/functions/netconf-executor/src/main/kotlin/org/onap/ccsdk/apps/blueprintsprocessor/functions/netconf/executor/data/NetconfAdaptorConstant.kt [deleted file]
ms/blueprintsprocessor/functions/netconf-executor/src/main/kotlin/org/onap/ccsdk/apps/blueprintsprocessor/functions/netconf/executor/data/NetconfExecutionData.kt [deleted file]
ms/blueprintsprocessor/functions/netconf-executor/src/main/kotlin/org/onap/ccsdk/apps/blueprintsprocessor/functions/netconf/executor/interfaces/NetconfSession.kt [deleted file]
ms/blueprintsprocessor/functions/netconf-executor/src/main/kotlin/org/onap/ccsdk/apps/blueprintsprocessor/functions/netconf/executor/utils/NetconfConstant.kt [new file with mode: 0644]
ms/blueprintsprocessor/functions/netconf-executor/src/main/kotlin/org/onap/ccsdk/apps/blueprintsprocessor/functions/netconf/executor/utils/NetconfMessageUtils.kt [moved from ms/blueprintsprocessor/functions/netconf-executor/src/main/kotlin/org/onap/ccsdk/apps/blueprintsprocessor/functions/netconf/executor/utils/RpcMessageUtils.kt with 51% similarity]
ms/blueprintsprocessor/functions/netconf-executor/src/main/kotlin/org/onap/ccsdk/apps/blueprintsprocessor/functions/netconf/executor/utils/RpcConstants.kt [deleted file]
ms/blueprintsprocessor/functions/netconf-executor/src/test/kotlin/org/onap/ccsdk/apps/blueprintsprocessor/functions/netconf/executor/ComponentNetconfExecutorTest.kt
ms/blueprintsprocessor/functions/netconf-executor/src/test/kotlin/org/onap/ccsdk/apps/blueprintsprocessor/functions/netconf/executor/NetconfSessionImplTest.kt
ms/blueprintsprocessor/functions/netconf-executor/src/test/kotlin/org/onap/ccsdk/apps/blueprintsprocessor/functions/netconf/executor/mocks/NetconfDeviceSimulator.kt
ms/blueprintsprocessor/functions/netconf-executor/src/test/kotlin/org/onap/ccsdk/apps/blueprintsprocessor/functions/netconf/executor/utils/RpcMessageUtilsTest.kt

index b02e9e9..83dc706 100755 (executable)
             <groupId>org.onap.ccsdk.apps.blueprintsprocessor.functions</groupId>
             <artifactId>python-executor</artifactId>
         </dependency>
+        <dependency>
+            <groupId>org.onap.ccsdk.apps.blueprintsprocessor.functions</groupId>
+            <artifactId>netconf-executor</artifactId>
+        </dependency>
         <dependency>
             <groupId>org.onap.ccsdk.apps.blueprintsprocessor</groupId>
             <artifactId>selfservice-api</artifactId>
index e5c928d..cfef4f8 100755 (executable)
@@ -1,6 +1,5 @@
 #
-#  Copyright � 2017-2018 AT&T Intellectual Property.
-#  Modifications Copyright © 2019 IBM, Bell Canada.
+#  Copyright (c) 2017-2019 AT&T, IBM, Bell Canada.
 #
 #  Licensed under the Apache License, Version 2.0 (the "License");
 #  you may not use this file except in compliance with the License.
@@ -35,5 +34,5 @@ blueprintsprocessor.db.primary.hibernateDDLAuto=update
 blueprintsprocessor.db.primary.hibernateNamingStrategy=org.hibernate.cfg.ImprovedNamingStrategy
 blueprintsprocessor.db.primary.hibernateDialect=org.hibernate.dialect.MySQL5InnoDBDialect
 # Python executor
-blueprints.processor.functions.python.executor.executionPath=/opt/app/onap/scripts/jython
-blueprints.processor.functions.python.executor.modulePaths=/opt/app/onap/scripts/jython
\ No newline at end of file
+blueprints.processor.functions.python.executor.executionPath=/opt/app/onap/scripts/jython/ccsdk_blueprints
+blueprints.processor.functions.python.executor.modulePaths=/opt/app/onap/scripts/jython/ccsdk_blueprints,/opt/app/onap/scripts/jython/ccsdk_netconf
index b3eabc1..97d4271 100755 (executable)
@@ -29,7 +29,7 @@
     <name>Blueprints Processor Distribution</name>
     <properties>
         <assembly.id>maven</assembly.id>
-        <name.space>org.onap.ccsdk.apps</name.space>     <!-- <name.space>${namespace}</name.space> -->
+        <name.space>org.onap.ccsdk.apps</name.space>
         <serviceArtifactName>blueprintsprocessor</serviceArtifactName>
         <image.name>onap/ccsdk-blueprintsprocessor</image.name>
         <docker.buildArg.https_proxy>${https_proxy}</docker.buildArg.https_proxy>
index ab3372e..c32aa9d 100644 (file)
@@ -35,7 +35,7 @@ open class ComponentNetconfExecutor(private val blueprintJythonService: Blueprin
 
     lateinit var scriptComponent: NetconfComponentFunction
 
-    override fun process(executionServiceInput: ExecutionServiceInput) {
+    override fun process(executionRequest: ExecutionServiceInput) {
 
         scriptComponent = blueprintJythonService.jythonComponentInstance(this) as NetconfComponentFunction
         checkNotNull(scriptComponent) { "failed to get netconf script component" }
index d480bdd..c98009f 100644 (file)
@@ -1,5 +1,5 @@
 /*
- *  Copyright © 2018 IBM.
+ *  Copyright © 2018-2019 IBM, Bell Canada.
  *
  *  Licensed under the Apache License, Version 2.0 (the "License");
  *  you may not use this file except in compliance with the License.
 package org.onap.ccsdk.apps.blueprintsprocessor.functions.netconf.executor
 
 import com.fasterxml.jackson.databind.JsonNode
-import org.onap.ccsdk.apps.blueprintsprocessor.functions.netconf.executor.interfaces.DeviceInfo
-import org.onap.ccsdk.apps.blueprintsprocessor.functions.netconf.executor.interfaces.NetconfRpcClientService
+import org.onap.ccsdk.apps.blueprintsprocessor.functions.netconf.executor.api.DeviceInfo
 import org.onap.ccsdk.apps.blueprintsprocessor.services.execution.AbstractComponentFunction
 import org.onap.ccsdk.apps.controllerblueprints.core.utils.JacksonUtils
 
-
 abstract class NetconfComponentFunction : AbstractComponentFunction() {
 
-    fun deviceProperties(requirementName: String): DeviceInfo {
+    // Called from python script
+    fun initializeNetconfConnection(requirementName: String): NetconfDevice {
+        val deviceInfo = deviceProperties(requirementName)
+        return NetconfDevice(deviceInfo)
+    }
+
+    fun generateMessage(): String {
+        TODO()
+    }
+
+    fun resolveAndGenerateMesssage(): String {
+        TODO()
+    }
+
+    private fun deviceProperties(requirementName: String): DeviceInfo {
 
         val blueprintContext = bluePrintRuntimeService.bluePrintContext()
 
         val requirement = blueprintContext.nodeTemplateRequirement(nodeTemplateName, requirementName)
 
         val capabilityProperties = bluePrintRuntimeService.resolveNodeTemplateCapabilityProperties(requirement
-                .node!!, requirement.capability!!)
+            .node!!, requirement.capability!!)
 
         return deviceProperties(capabilityProperties)
     }
 
-    fun deviceProperties(capabilityProperty: MutableMap<String, JsonNode>): DeviceInfo {
+    private fun deviceProperties(capabilityProperty: MutableMap<String, JsonNode>): DeviceInfo {
         return JacksonUtils.getInstanceFromMap(capabilityProperty, DeviceInfo::class.java)
     }
-
-    fun netconfRpcClientService(): NetconfRpcClientService {
-        return NetconfRpcService()
-    }
-
-    fun netconfRpcClientService(requirementName: String): NetconfRpcClientService {
-        val deviceProperties = deviceProperties(requirementName)
-        val netconfRpcClientService = NetconfRpcService()
-        netconfRpcClientService.connect(deviceProperties)
-        return netconfRpcClientService
-    }
-
-    fun generateMessage(): String {
-        TODO()
-    }
-
-    fun resolveAndGenerateMesssage(): String {
-        TODO()
-    }
-
 }
\ No newline at end of file
diff --git a/ms/blueprintsprocessor/functions/netconf-executor/src/main/kotlin/org/onap/ccsdk/apps/blueprintsprocessor/functions/netconf/executor/NetconfDevice.kt b/ms/blueprintsprocessor/functions/netconf-executor/src/main/kotlin/org/onap/ccsdk/apps/blueprintsprocessor/functions/netconf/executor/NetconfDevice.kt
new file mode 100644 (file)
index 0000000..5477662
--- /dev/null
@@ -0,0 +1,32 @@
+/*
+ * Copyright (C) 2019 Bell Canada.
+ *
+ * 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.ccsdk.apps.blueprintsprocessor.functions.netconf.executor
+
+import org.onap.ccsdk.apps.blueprintsprocessor.functions.netconf.executor.api.DeviceInfo
+import org.onap.ccsdk.apps.blueprintsprocessor.functions.netconf.executor.api.NetconfSession
+import org.onap.ccsdk.apps.blueprintsprocessor.functions.netconf.executor.core.NetconfRpcServiceImpl
+import org.onap.ccsdk.apps.blueprintsprocessor.functions.netconf.executor.core.NetconfSessionImpl
+
+class NetconfDevice(deviceInfo: DeviceInfo) {
+    val netconfRpcService: NetconfRpcServiceImpl
+    val netconfSession: NetconfSession
+
+    init {
+        netconfRpcService = NetconfRpcServiceImpl(deviceInfo)
+        netconfSession = NetconfSessionImpl(deviceInfo, netconfRpcService)
+        netconfRpcService.setNetconfSession(netconfSession)
+    }
+}
\ No newline at end of file
diff --git a/ms/blueprintsprocessor/functions/netconf-executor/src/main/kotlin/org/onap/ccsdk/apps/blueprintsprocessor/functions/netconf/executor/NetconfException.kt b/ms/blueprintsprocessor/functions/netconf-executor/src/main/kotlin/org/onap/ccsdk/apps/blueprintsprocessor/functions/netconf/executor/NetconfException.kt
deleted file mode 100644 (file)
index 37aa63d..0000000
+++ /dev/null
@@ -1,45 +0,0 @@
-/*
- * Copyright © 2017-2018 AT&T Intellectual Property.
- *
- * 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.ccsdk.apps.blueprintsprocessor.functions.netconf.executor
-
-import java.io.IOException
-
-class NetconfException : IOException {
-
-    var code: Int = 100
-
-    constructor(cause: Throwable) : super(cause)
-    constructor(message: String) : super(message)
-    constructor(message: String, cause: Throwable) : super(message, cause)
-    constructor(cause: Throwable, message: String, vararg args: Any?) : super(String.format(message, *args), cause)
-
-    constructor(code: Int, cause: Throwable) : super(cause) {
-        this.code = code
-    }
-
-    constructor(code: Int, message: String) : super(message) {
-        this.code = code
-    }
-
-    constructor(code: Int, message: String, cause: Throwable) : super(message, cause) {
-        this.code = code
-    }
-
-    constructor(code: Int, cause: Throwable, message: String, vararg args: Any?)
-            : super(String.format(message, *args), cause) {
-        this.code = code
-    }
-}
diff --git a/ms/blueprintsprocessor/functions/netconf-executor/src/main/kotlin/org/onap/ccsdk/apps/blueprintsprocessor/functions/netconf/executor/NetconfExecutorConfiguration.kt b/ms/blueprintsprocessor/functions/netconf-executor/src/main/kotlin/org/onap/ccsdk/apps/blueprintsprocessor/functions/netconf/executor/NetconfExecutorConfiguration.kt
deleted file mode 100644 (file)
index 562dd76..0000000
+++ /dev/null
@@ -1,68 +0,0 @@
-/*
- * Copyright © 2017-2018 AT&T Intellectual Property.
- *
- * 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.ccsdk.apps.blueprintsprocessor.functions.netconf.executor
-
-import org.springframework.boot.context.properties.EnableConfigurationProperties
-import org.springframework.context.annotation.ComponentScan
-import org.springframework.context.annotation.Configuration
-
-@Configuration
-@ComponentScan
-@EnableConfigurationProperties
-open class NetconfExecutorConfiguration
-
-
-class NetconfExecutorConstants {
-    companion object {
-        const val CONTEX_PARAM_MESSAGE = "message"
-        const val COMPONENT_SCRIPT_PATH = "component-scripts"
-
-        const val REQ_NETCONF_CONNECTION = "netconf-connection"
-        const val NETCONF_CONNECTION_SOURCE = "source"
-        const val NETCONF_CONNECTION_LOGIN_KEY = "login-key"
-        const val NETCONF_CONNECTION_LOGIN_ACCOUNT = "login-account"
-        const val NETCONF_CONNECTION_TARGET_IP = "target-ip-address"
-        const val NETCONF_CONNECTION_MESSAGE_PORT = "port-number"
-        const val NETCONF_CONNECTION_TIMEOUT = "connection-time-out"
-
-        const val INPUT_PARAM_REQUEST_ID = "request-id"
-        const val INPUT_PARAM_RESOURCE_ID = "resource-id"
-        const val INPUT_PARAM_RESERVATION_ID = "reservation-id"
-        const val INPUT_PARAM_RESOURCE_TYPE = "resource-type"
-        const val INPUT_PARAM_ACTION_NAME = "action-name"
-        const val INPUT_PARAM_TEMPLATE_NAME = "template-name"
-        const val INPUT_PARAM_ASSIGNMENT_ACTION_NAME = "assignment-action-name"
-
-        const val SCRIPT_OUTPUT_RESPONSE_DATA = "responseData"
-        const val SCRIPT_OUTPUT_ERROR_MESSAGE = "errorMessage"
-
-        const val OUTPUT_PARAM_RESPONSE_DATA = "response-data"
-        const val OUTPUT_PARAM_ERROR_MESSAGE = "error-message"
-        const val OUTPUT_PARAM_STATUS = "status"
-        const val OUTPUT_STATUS_SUCCESS = "success"
-        const val OUTPUT_STATUS_FAILURE = "failure"
-
-        const val CONFIG_DATA_TYPE_XML = "XML"
-        const val CONFIG_DATA_TYPE_JSON = "JSON"
-
-        const val CONFIG_TARGET_RUNNING = "running"
-        const val CONFIG_TARGET_CANDIDATE = "candidate"
-        const val CONFIG_DEFAULT_OPERATION_MERGE = "merge"
-        const val CONFIG_DEFAULT_OPERATION_REPLACE = "replace"
-        const val DEFAULT_NETCONF_SESSION_MANAGER_TYPE = "DEFAULT_NETCONF_SESSION"
-    }
-}
\ No newline at end of file
diff --git a/ms/blueprintsprocessor/functions/netconf-executor/src/main/kotlin/org/onap/ccsdk/apps/blueprintsprocessor/functions/netconf/executor/NetconfRpcService.kt b/ms/blueprintsprocessor/functions/netconf-executor/src/main/kotlin/org/onap/ccsdk/apps/blueprintsprocessor/functions/netconf/executor/NetconfRpcService.kt
deleted file mode 100644 (file)
index 0e264bc..0000000
+++ /dev/null
@@ -1,375 +0,0 @@
-/*
- * Copyright © 2017-2018 AT&T Intellectual Property.
- *
- * 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.ccsdk.apps.blueprintsprocessor.functions.netconf.executor
-
-import org.apache.commons.collections.CollectionUtils
-import org.onap.ccsdk.apps.blueprintsprocessor.functions.netconf.executor.core.NetconfSessionFactory
-import org.onap.ccsdk.apps.blueprintsprocessor.functions.netconf.executor.data.DeviceResponse
-import org.onap.ccsdk.apps.blueprintsprocessor.functions.netconf.executor.data.NetconfAdaptorConstant
-import org.onap.ccsdk.apps.blueprintsprocessor.functions.netconf.executor.interfaces.DeviceInfo
-import org.onap.ccsdk.apps.blueprintsprocessor.functions.netconf.executor.interfaces.NetconfRpcClientService
-import org.onap.ccsdk.apps.blueprintsprocessor.functions.netconf.executor.interfaces.NetconfSession
-import org.onap.ccsdk.apps.blueprintsprocessor.functions.netconf.executor.utils.RpcMessageUtils
-import org.slf4j.LoggerFactory
-import org.springframework.beans.factory.config.ConfigurableBeanFactory
-import org.springframework.context.annotation.Scope
-import org.springframework.stereotype.Service
-import java.util.*
-import java.util.concurrent.TimeUnit
-
-
-@Service("netconf-rpc-service")
-@Scope(value = ConfigurableBeanFactory.SCOPE_PROTOTYPE)
-class NetconfRpcService : NetconfRpcClientService {
-
-    val log = LoggerFactory.getLogger(NetconfRpcService::class.java)
-
-    lateinit var deviceInfo: DeviceInfo
-    lateinit var netconfSession: NetconfSession
-
-    private val applyConfigIds = ArrayList<String>()
-    private val recordedApplyConfigIds = ArrayList<String>()
-    private val DEFAULT_MESSAGE_TIME_OUT = 30
-
-
-    override fun connect(deviceInfo: DeviceInfo): NetconfSession {
-        try {
-
-            this.deviceInfo = deviceInfo
-
-            log.info("Connecting Netconf Device .....")
-            this.netconfSession = NetconfSessionFactory.instance("DEFAULT_NETCONF_SESSION", deviceInfo)
-            publishMessage("Netconf Device Connection Established")
-            return this.netconfSession
-        } catch (e: NetconfException) {
-            publishMessage(String.format("Netconf Device Connection Failed, %s", e.message))
-            throw NetconfException("Netconf Device Connection Failed,$deviceInfo",e)
-        }
-    }
-
-    override  fun disconnect() {
-        netconfSession.close()
-    }
-
-    override fun reconnect() {
-        disconnect()
-        connect(deviceInfo)
-    }
-
-    override fun getConfig(messageId: String, messageContent: String, configTarget: String, messageTimeout: Int): DeviceResponse {
-        var output = DeviceResponse()
-        log.info("in the NetconfRpcService "+messageId)
-        try {
-            val message = RpcMessageUtils.getConfig(messageId, configTarget, messageContent)
-            output = asyncRpc(message, messageId, messageTimeout)
-        } catch (e: Exception) {
-            output.status = NetconfAdaptorConstant.STATUS_FAILURE
-            output.errorMessage = e.message
-        }
-
-        return output
-    }
-
-    override fun deleteConfig(messageId: String, configTarget: String, messageTimeout: Int): DeviceResponse {
-        var output = DeviceResponse()
-        try {
-            val deleteConfigMessage = RpcMessageUtils.deleteConfig(messageId, configTarget)
-            output.requestMessage = deleteConfigMessage
-            output = asyncRpc(deleteConfigMessage, messageId, messageTimeout)
-        } catch (e: Exception) {
-            output.status = NetconfAdaptorConstant.STATUS_FAILURE
-            output.errorMessage = "failed in delete config command " + e.message
-        }
-
-        return output
-    }
-
-    override fun lock(messageId: String, configTarget: String, messageTimeout: Int): DeviceResponse {
-        var output = DeviceResponse()
-        try {
-            val lockMessage = RpcMessageUtils.lock(messageId, configTarget)
-            output.requestMessage = lockMessage
-            output = asyncRpc(lockMessage, messageId, messageTimeout)
-        } catch (e: Exception) {
-            output.status = NetconfAdaptorConstant.STATUS_FAILURE
-            output.errorMessage = "failed in lock command " + e.message
-        }
-
-        return output
-    }
-
-    override fun unLock(messageId: String, configTarget: String, messageTimeout: Int): DeviceResponse {
-        var output = DeviceResponse()
-        try {
-            val unlockMessage = RpcMessageUtils.unlock(messageId, configTarget)
-            output.requestMessage = unlockMessage
-            output = asyncRpc(unlockMessage, messageId, messageTimeout)
-        } catch (e: Exception) {
-            output.status = NetconfAdaptorConstant.STATUS_FAILURE
-            output.errorMessage = "failed in lock command " + e.message
-        }
-
-        return output
-    }
-
-    override fun commit(messageId: String, message: String, discardChanges: Boolean, messageTimeout: Int): DeviceResponse {
-        var output = DeviceResponse()
-        try {
-            val messageContent = RpcMessageUtils.commit(messageId, message)
-            output = asyncRpc(messageContent, messageId, messageTimeout)
-        } catch (e: Exception) {
-            output.status = NetconfAdaptorConstant.STATUS_FAILURE
-            output.errorMessage = "failed in commit command " + e.message
-        } finally {
-            // Update the Apply Config status
-            if (CollectionUtils.isNotEmpty(applyConfigIds)) {
-                val status = if (NetconfAdaptorConstant.STATUS_SUCCESS.equals(output.status,ignoreCase = true))
-                    NetconfAdaptorConstant.CONFIG_STATUS_SUCCESS
-                else
-                    NetconfAdaptorConstant.CONFIG_STATUS_FAILED
-
-                applyConfigIds.forEach{
-                    recordedApplyConfigIds.add(it)
-                    try {
-                        //TODO persistance logic
-                       // configPersistService.updateApplyConfig(applyConfigId, status)
-                    } catch (e: Exception) {
-                        log.error("failed to update apply config ($it) status ($status)")
-                    }
-
-                }
-                applyConfigIds.clear()
-            }
-            // TODO
-            // Update the Configuration in Running Config Table from 1810 release
-            // String recordMessageId = "recoded-running-config-" + messageId;
-            // recordRunningConfig(recordMessageId, null);
-        }
-
-        // If commit failed apply discard changes
-        if (discardChanges && NetconfAdaptorConstant.STATUS_FAILURE.equals(output.status,ignoreCase = true)) {
-            try {
-                val discardChangesConfigMessageId = "$messageId-discard-changes"
-                discardConfig(discardChangesConfigMessageId, NetconfAdaptorConstant.DEFAULT_MESSAGE_TIME_OUT)
-            } catch (e: Exception) {
-                log.error("failed to rollback ($e) ")
-            }
-
-        }
-
-        return output
-    }
-    override fun discardConfig(messageId: String, messageTimeout: Int): DeviceResponse {
-        var output = DeviceResponse()
-        try {
-            val discardChangesMessage = RpcMessageUtils.discardChanges(messageId)
-            output.requestMessage = discardChangesMessage
-            output = asyncRpc(discardChangesMessage, messageId, messageTimeout)
-        } catch (e: Exception) {
-            output.status = NetconfAdaptorConstant.STATUS_FAILURE
-            output.errorMessage = "failed in discard changes command " + e.message
-        }
-
-        return output
-    }
-
-    override fun close(messageId: String, force: Boolean, messageTimeout: Int): DeviceResponse {
-        var output = DeviceResponse()
-        try {
-            val messageContent = RpcMessageUtils.closeSession(messageId, force)
-            output = asyncRpc(messageContent, messageId, messageTimeout)
-        } catch (e: Exception) {
-            output.status = NetconfAdaptorConstant.STATUS_FAILURE
-            output.responseMessage = "failed in close command " + e.message
-        }
-
-        return output
-    }
-
-
-    override fun asyncRpc(request: String, msgId: String, timeOut: Int): DeviceResponse {
-        val response = DeviceResponse()
-                try {
-            recordMessage("RPC request $request")
-            response.requestMessage = request
-            publishMessage("Netconf RPC InProgress")
-
-            val rpcResponse = netconfSession.asyncRpc(request, msgId).get(timeOut.toLong(), TimeUnit.SECONDS)
-            response.responseMessage = rpcResponse
-
-            if (!RpcMessageUtils.checkReply(rpcResponse)) {
-                throw NetconfException(rpcResponse)
-            }
-            response.status = NetconfAdaptorConstant.STATUS_SUCCESS
-            response.errorMessage = null
-        } catch (e: Exception) {
-            response.status = NetconfAdaptorConstant.STATUS_FAILURE
-            response.errorMessage = e.message
-        } finally {
-            recordMessage(String.format("RPC Response status (%s) reply (%s), error message (%s)", response.status,
-                    response.responseMessage, response.errorMessage))
-
-              when {
-                   NetconfAdaptorConstant.STATUS_FAILURE.equals(response.status,ignoreCase = true) -> publishMessage(String.format("Netconf RPC Failed for messgaeID (%s) with (%s)", msgId,
-                           response.errorMessage))
-                   else -> publishMessage(String.format("Netconf RPC Success for messgaeID (%s)", msgId))
-               }
-        }
-
-        return response
-    }
-
-    override fun editConfig(messageId: String, messageContent: String, reConnect: Boolean, wait: Int, lock: Boolean, configTarget: String, editDefaultOperation: String, clearCandidate: Boolean, validate: Boolean, commit: Boolean, discardChanges: Boolean, unlock: Boolean, preRestartWait: Int, postRestartWait: Int, messageTimeout: Int): DeviceResponse {
-        var editConfigDeviceResponse = DeviceResponse()
-
-        try {
-            val editMessage = RpcMessageUtils.editConfig(messageId, NetconfAdaptorConstant.CONFIG_TARGET_CANDIDATE,
-                    editDefaultOperation, messageContent)
-            editConfigDeviceResponse.requestMessage = editMessage
-
-           /* val applyConfigId = configPersistService.saveApplyConfig(netconfExecutionRequest.getRequestId(),
-                    netconfDeviceInfo.getName(), netconfDeviceInfo.getDeviceId(), ConfigModelConstant.PROTOCOL_NETCONF,
-                    configTarget, editMessage)
-
-            applyConfigIds.add(applyConfigId)  */
-
-            // Reconnect Client Session
-            if (reConnect) {
-                reconnect()
-            }
-            // Provide invocation Delay
-            if (wait > 0) {
-                log.info("Waiting for {} sec for the transaction to start", wait)
-                Thread.sleep(wait * 1000L)
-            }
-
-            if (lock) {
-                val lockMessageId = "$messageId-lock"
-                val lockDeviceResponse = lock(lockMessageId, configTarget, DEFAULT_MESSAGE_TIME_OUT)
-                editConfigDeviceResponse.addSubDeviceResponse(lockMessageId, lockDeviceResponse)
-                if (!NetconfAdaptorConstant.STATUS_SUCCESS.equals(lockDeviceResponse.status,ignoreCase = true)) {
-                    throw NetconfException(lockDeviceResponse.errorMessage!!)
-                }
-            }
-
-            if (clearCandidate) {
-                val deleteConfigMessageId = "$messageId-delete"
-                val deleteConfigDeviceResponse = deleteConfig(deleteConfigMessageId,
-                        NetconfAdaptorConstant.CONFIG_TARGET_CANDIDATE, DEFAULT_MESSAGE_TIME_OUT)
-                editConfigDeviceResponse.addSubDeviceResponse(deleteConfigMessageId, deleteConfigDeviceResponse)
-                if (!NetconfAdaptorConstant.STATUS_SUCCESS.equals(deleteConfigDeviceResponse.status,ignoreCase = true)) {
-                    throw NetconfException(deleteConfigDeviceResponse.errorMessage!!)
-                }
-            }
-
-            if (discardChanges) {
-                val discardConfigMessageId = "$messageId-discard"
-                val discardConfigDeviceResponse = discardConfig(discardConfigMessageId, DEFAULT_MESSAGE_TIME_OUT)
-                editConfigDeviceResponse.addSubDeviceResponse(discardConfigMessageId, discardConfigDeviceResponse)
-                if (!NetconfAdaptorConstant.STATUS_SUCCESS.equals(discardConfigDeviceResponse.status,ignoreCase = true)) {
-                    throw NetconfException(discardConfigDeviceResponse.errorMessage!!)
-                }
-            }
-
-            editConfigDeviceResponse = asyncRpc(editMessage, messageId, messageTimeout)
-            if (!NetconfAdaptorConstant.STATUS_SUCCESS.equals(editConfigDeviceResponse.status,ignoreCase = true)) {
-                throw NetconfException(editConfigDeviceResponse.errorMessage!!)
-            }
-
-            if (validate) {
-                val validateMessageId = "$messageId-validate"
-                val validateDeviceResponse = validate(validateMessageId,
-                        NetconfAdaptorConstant.CONFIG_TARGET_CANDIDATE, DEFAULT_MESSAGE_TIME_OUT)
-                editConfigDeviceResponse.addSubDeviceResponse(validateMessageId, validateDeviceResponse)
-                if (!NetconfAdaptorConstant.STATUS_SUCCESS.equals(validateDeviceResponse.status,ignoreCase = true)) {
-                    throw NetconfException(validateDeviceResponse.errorMessage!!)
-                }
-            }
-
-            /**
-             * If Commit is enable, the commit response is treated as Edit config response, If commit failed, we
-             * need not to throw an exception, until we unlock the device.
-             */
-            if (commit) {
-                val commitMessageId = "$messageId-commit"
-                val commitDeviceResponse = commit(commitMessageId, commitMessageId, discardChanges, DEFAULT_MESSAGE_TIME_OUT)
-                editConfigDeviceResponse.addSubDeviceResponse(commitMessageId, commitDeviceResponse)
-                if (!NetconfAdaptorConstant.STATUS_SUCCESS.equals(commitDeviceResponse.status,ignoreCase = true)) {
-                    throw NetconfException(commitDeviceResponse.errorMessage!!)
-                }
-            }
-
-            // Provide pre restart Delay
-            if (preRestartWait > 0) {
-                log.info("Waiting for {} sec for restart", wait)
-                Thread.sleep(preRestartWait * 1000L)
-            }
-            // TODO Restart Device
-            // Provide post restart Delay
-            if (postRestartWait > 0) {
-                log.info("Waiting for {} sec for the post restart", wait)
-                Thread.sleep(postRestartWait * 1000L)
-            }
-
-        } catch (e: Exception) {
-            editConfigDeviceResponse.status = NetconfAdaptorConstant.STATUS_FAILURE
-            editConfigDeviceResponse.errorMessage = e.message
-        } finally {
-            if (unlock) {
-                val unlockMessageId = "$messageId-unlock"
-                val unlockDeviceResponse = unLock(unlockMessageId, configTarget, DEFAULT_MESSAGE_TIME_OUT)
-                editConfigDeviceResponse.addSubDeviceResponse(unlockMessageId, unlockDeviceResponse)
-                if (!NetconfAdaptorConstant.STATUS_SUCCESS.equals(unlockDeviceResponse.status,ignoreCase = true)) {
-                    editConfigDeviceResponse.status = NetconfAdaptorConstant.STATUS_FAILURE
-                    editConfigDeviceResponse.errorMessage = unlockDeviceResponse.errorMessage
-                }
-            }
-        }
-        return editConfigDeviceResponse
-    }
-
-    override fun validate(messageId: String, configTarget: String, messageTimeout: Int): DeviceResponse {
-        var output = DeviceResponse()
-        try {
-            val validateMessage = RpcMessageUtils.validate(messageId, configTarget)
-            output.requestMessage = validateMessage
-            output = asyncRpc(validateMessage, messageId, messageTimeout)
-        } catch (e: Exception) {
-            output.status = NetconfAdaptorConstant.STATUS_FAILURE
-            output.errorMessage = "failed in validate command " + e.message
-        }
-
-        return output
-    }
-
-
-    fun recordMessage(message: String) {
-        recordMessage(NetconfAdaptorConstant.LOG_MESSAGE_TYPE_LOG, message)
-    }
-
-    fun recordMessage(messageType: String, message: String) {
-        //TODO
-        //eventPublishService.recordMessage(netconfExecutionRequest.getRequestId(), messageType, message)
-    }
-
-    fun publishMessage(message: String) {
-        //TODO
-        //eventPublishService.publishMessage(netconfExecutionRequest.getRequestId(), message)
-    }
-
-
-}
\ No newline at end of file
  * limitations under the License.
  */
 
-package org.onap.ccsdk.apps.blueprintsprocessor.functions.netconf.executor.interfaces
+package org.onap.ccsdk.apps.blueprintsprocessor.functions.netconf.executor.api
 
 import com.fasterxml.jackson.annotation.JsonIgnore
 import com.fasterxml.jackson.annotation.JsonProperty
 
 class DeviceInfo {
     @get:JsonProperty("login-account")
-    var name: String? = null
+    var username: String? = null
     @get:JsonProperty("login-key")
-    var pass: String? = null
+    var password: String? = null
     @get:JsonProperty("target-ip-address")
     var ipAddress: String? = null
     @get:JsonProperty("port-number")
     var port: Int = 0
-    @get:JsonIgnore
-    var key: String? = null
-    @get:JsonProperty("source")
-    var source: String? = null
     @get:JsonProperty("connection-time-out")
-    var connectTimeoutSec: Long = 30
+    var connectTimeout: Long = 5
     @get:JsonIgnore
-    var replyTimeout: Int = 60
+    var source: String? = null
     @get:JsonIgnore
-    var idleTimeout: Int = 45
+    var replyTimeout: Int = 5
     @get:JsonIgnore
-    var deviceId: String = "$ipAddress:$port"
+    var idleTimeout: Int = 99999
+
+    override fun toString(): String {
+        return "$ipAddress:$port"
+    }
 }
\ No newline at end of file
@@ -1,5 +1,5 @@
 /*
- * Copyright © 2017-2018 AT&T Intellectual Property.
+ * Copyright © 2017-2019 AT&T, Bell Canada
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
-package org.onap.ccsdk.apps.blueprintsprocessor.functions.netconf.executor.data
+package org.onap.ccsdk.apps.blueprintsprocessor.functions.netconf.executor.api
 
-enum class NetconfSshClientLib(val sshClientString :String) {
-    APACHE_MINA("apache-mina"),
-    ETHZ_SSH2("ethz-ssh2");
+class NetconfException : Exception {
 
-    fun getEnum(valueOf: String): NetconfSshClientLib {
-        return NetconfSshClientLib.valueOf(valueOf.toUpperCase().replace('-', '_'))
-    }
+    constructor(cause: Throwable) : super(cause)
+    constructor(message: String) : super(message)
+    constructor(message: String, cause: Throwable) : super(message, cause)
 
 }
\ No newline at end of file
diff --git a/ms/blueprintsprocessor/functions/netconf-executor/src/main/kotlin/org/onap/ccsdk/apps/blueprintsprocessor/functions/netconf/executor/api/NetconfMessage.kt b/ms/blueprintsprocessor/functions/netconf-executor/src/main/kotlin/org/onap/ccsdk/apps/blueprintsprocessor/functions/netconf/executor/api/NetconfMessage.kt
new file mode 100644 (file)
index 0000000..da74661
--- /dev/null
@@ -0,0 +1,74 @@
+/*
+ * Copyright © 2017-2019 AT&T, Bell Canada
+ *
+ * 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.ccsdk.apps.blueprintsprocessor.functions.netconf.executor.api
+
+import org.onap.ccsdk.apps.blueprintsprocessor.functions.netconf.executor.utils.RpcStatus
+
+class DeviceResponse {
+    var status: String? = null
+    var errorMessage: String? = null
+    var responseMessage: String? = null
+    var requestMessage: String? = null
+    private var subDeviceResponse: MutableMap<Any, Any>? = null
+
+    fun addSubDeviceResponse(key: String, subDeviceResponse: DeviceResponse) {
+        if (this.subDeviceResponse == null) {
+            this.subDeviceResponse = hashMapOf()
+        }
+        this.subDeviceResponse!![key] = subDeviceResponse
+    }
+
+    fun isSuccess(): Boolean {
+        if (this.status != RpcStatus.SUCCESS && !this.errorMessage.isNullOrEmpty()) {
+            return false
+        }
+        return true
+    }
+}
+
+
+/**
+ * Creates an event of a given type and for the specified subject and the current time.
+ *
+ * @param type event type
+ * @param payload message from the device
+ * @param messageId id of the message related to the event
+ * @param deviceInfo device of event
+ */
+class NetconfReceivedEvent
+    (private var type: Type, private var payload: String = "", private var messageId: String = "",
+     private var deviceInfo: DeviceInfo) {
+
+    enum class Type {
+        DEVICE_REPLY,
+        DEVICE_UNREGISTERED,
+        DEVICE_ERROR,
+        SESSION_CLOSED
+    }
+
+    fun getType(): Type {
+        return type
+    }
+
+    fun getMessagePayload(): String {
+        return payload
+    }
+
+    fun getMessageID(): String {
+        return messageId
+    }
+}
\ No newline at end of file
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
-package org.onap.ccsdk.apps.blueprintsprocessor.functions.netconf.executor.interfaces
+package org.onap.ccsdk.apps.blueprintsprocessor.functions.netconf.executor.api
 
-import org.onap.ccsdk.apps.blueprintsprocessor.functions.netconf.executor.data.DeviceResponse
-
-interface NetconfRpcClientService {
-
-    /**
-     * @param deviceProperties deviceProperties
-     * @return NetconfSession
-     */
-    fun connect(deviceInfo: DeviceInfo): NetconfSession
-
-
-    fun disconnect()
-
-
-    fun reconnect()
+interface NetconfRpcService {
 
     /**
+     * Lock
      * @param messageId message id of the request.
-     * @param configTarget config target ( running or candidate)
+     * @param configTarget datastore ( running or candidate)
      * @param messageTimeout message timeout of the request.
      * @return Device response
      */
     fun lock(messageId: String, configTarget: String, messageTimeout: Int): DeviceResponse
 
     /**
+     * Get-config
      * @param messageId message id of the request.
-     * @param messageContent filter content.
+     * @param filter filter content.
      * @param configTarget config target ( running or candidate)
      * @param messageTimeout message timeout of the request.
      * @return Device response
      */
-    fun getConfig(messageId: String, messageContent: String, configTarget: String, messageTimeout: Int): DeviceResponse
+    fun getConfig(messageId: String, filter: String, configTarget: String, messageTimeout: Int): DeviceResponse
 
     /**
+     * Delete config from datastore
      * @param messageId message id of the request.
      * @param configTarget config target ( running or candidate)
      * @param messageTimeout message timeout of the request.
@@ -57,10 +46,9 @@ interface NetconfRpcClientService {
     fun deleteConfig(messageId: String, configTarget: String, messageTimeout: Int): DeviceResponse
 
     /**
+     * Edit-config
      * @param messageId message id of the request.
      * @param messageContent edit config content.
-     * @param reConnect reconnect session
-     * @param wait waiting time to perform operation ( 0 indicates no wait )
      * @param lock lock the device before performing edit.
      * @param configTarget config target ( running or candidate)
      * @param editDefaultOperation edit default operation (merge | replace | create | delete | remove or
@@ -70,16 +58,15 @@ interface NetconfRpcClientService {
      * @param discardChanges Rollback on failure
      * @param validate validate the config before commit
      * @param unlock unlock device after edit
-     * @param preRestartWait
-     * @param postRestartWait
      * @param messageTimeout message timeout of the request.
      * @return Device response
      */
-    fun editConfig(messageId: String, messageContent: String, reConnect: Boolean, wait: Int, lock: Boolean,
-                   configTarget: String, editDefaultOperation: String, clearCandidate: Boolean, validate: Boolean, commit: Boolean,
-                   discardChanges: Boolean, unlock: Boolean, preRestartWait: Int, postRestartWait: Int, messageTimeout: Int): DeviceResponse
+    fun editConfig(messageId: String, messageContent: String, lock: Boolean, configTarget: String,
+                   editDefaultOperation: String, deleteConfig: Boolean, validate: Boolean, commit: Boolean,
+                   discardChanges: Boolean, unlock: Boolean, messageTimeout: Int): DeviceResponse
 
     /**
+     * Validate
      * @param messageId message id of the request.
      * @param configTarget config target ( running or candidate)
      * @param messageTimeout message timeout of the request.
@@ -88,15 +75,16 @@ interface NetconfRpcClientService {
     fun validate(messageId: String, configTarget: String, messageTimeout: Int): DeviceResponse
 
     /**
+     * Commit
      * @param messageId message id of the request.
-     * @param message optional commit message
      * @param discardChanges Rollback on failure
      * @param messageTimeout message timeout of the request.
      * @return Device response
      */
-    fun commit(messageId: String, message: String, discardChanges: Boolean, messageTimeout: Int): DeviceResponse
+    fun commit(messageId: String, discardChanges: Boolean, messageTimeout: Int): DeviceResponse
 
     /**
+     * Unlock
      * @param messageId message id of the request.
      * @param configTarget config target ( running or candidate)
      * @param messageTimeout message timeout of the request.
@@ -105,6 +93,7 @@ interface NetconfRpcClientService {
     fun unLock(messageId: String, configTarget: String, messageTimeout: Int): DeviceResponse
 
     /**
+     * Discard config
      * @param messageId message id of the request.
      * @param messageTimeout message timeout of the request.
      * @return Device response
@@ -112,12 +101,13 @@ interface NetconfRpcClientService {
     fun discardConfig(messageId: String, messageTimeout: Int): DeviceResponse
 
     /**
+     * Close session
      * @param messageId message id of the request.
-     * @param force force close
+     * @param force force closeSession
      * @param messageTimeout message timeout of the request.
      * @return Device response
      */
-    fun close(messageId: String, force: Boolean, messageTimeout: Int): DeviceResponse
+    fun closeSession(messageId: String, force: Boolean, messageTimeout: Int): DeviceResponse
 
     /**
      * Executes an RPC request to the netconf server.
diff --git a/ms/blueprintsprocessor/functions/netconf-executor/src/main/kotlin/org/onap/ccsdk/apps/blueprintsprocessor/functions/netconf/executor/api/NetconfSession.kt b/ms/blueprintsprocessor/functions/netconf-executor/src/main/kotlin/org/onap/ccsdk/apps/blueprintsprocessor/functions/netconf/executor/api/NetconfSession.kt
new file mode 100644 (file)
index 0000000..6a655d9
--- /dev/null
@@ -0,0 +1,86 @@
+/*
+ * Copyright © 2017-2018 AT&T Intellectual Property.
+ *
+ * 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.ccsdk.apps.blueprintsprocessor.functions.netconf.executor.api
+
+import java.util.concurrent.CompletableFuture
+
+interface NetconfSession {
+
+    /**
+     * Establish netconf session
+     */
+    fun connect()
+
+
+    /**
+     * Disconnect netconf session
+     */
+    fun disconnect()
+
+    /**
+     * Reconnect netconf session
+     */
+    fun reconnect()
+
+    /**
+     * Executes an synchronous RPC request.
+     *
+     * @param request the XML request
+     * @param messageId message id of the request.
+     * @return Response
+     */
+    @Throws(NetconfException::class)
+    fun syncRpc(request: String, messageId: String): String
+
+    /**
+     * Executes an asynchronous RPC request.
+     *
+     * @param request the XML request
+     * @param messageId message id of the request.
+     * @return Response
+     */
+    @Throws(NetconfException::class)
+    fun asyncRpc(request: String, messageId: String): CompletableFuture<String>
+
+    /**
+     * Checks the state of the underlying SSH session and connection and if necessary it reestablishes
+     * it.
+     */
+    @Throws(NetconfException::class)
+    fun checkAndReestablish()
+
+    /**
+     * Get the device information for initialised session.
+     *
+     * @return DeviceInfo as device information
+     */
+    fun getDeviceInfo(): DeviceInfo
+
+    /**
+     * Gets the session ID of the Netconf session.
+     *
+     * @return Session ID as a string.
+     */
+    fun getSessionId(): String
+
+    /**
+     * Gets the capabilities of the remote Netconf device associated to this session.
+     *
+     * @return Network capabilities as strings in a Set.
+     */
+    fun getDeviceCapabilitiesSet(): Set<String>
+}
\ No newline at end of file
@@ -1,5 +1,5 @@
 /*
- * Copyright © 2017-2018 AT&T Intellectual Property.
+ * Copyright © 2017-2019 AT&T, Bell Canada
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
-package org.onap.ccsdk.apps.blueprintsprocessor.functions.netconf.executor.interfaces;
+package org.onap.ccsdk.apps.blueprintsprocessor.functions.netconf.executor.api
 
-import org.onap.ccsdk.apps.blueprintsprocessor.functions.netconf.executor.data.NetconfDeviceOutputEvent;
+interface NetconfSessionListener {
 
-public interface NetconfSessionDelegate {
-
-    void notify(NetconfDeviceOutputEvent event);
+    fun notify(event: NetconfReceivedEvent)
 }
@@ -1,5 +1,5 @@
 /*
- * Copyright © 2017-2018 AT&T Intellectual Property.
+ * Copyright © 2017-2019 AT&T, Bell Canada
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
 
 package org.onap.ccsdk.apps.blueprintsprocessor.functions.netconf.executor.core
 
-import org.onap.ccsdk.apps.blueprintsprocessor.functions.netconf.executor.NetconfException
-import org.onap.ccsdk.apps.blueprintsprocessor.functions.netconf.executor.data.NetconfDeviceOutputEvent
-import org.onap.ccsdk.apps.blueprintsprocessor.functions.netconf.executor.interfaces.DeviceInfo
-import org.onap.ccsdk.apps.blueprintsprocessor.functions.netconf.executor.interfaces.NetconfSessionDelegate
-import org.onap.ccsdk.apps.blueprintsprocessor.functions.netconf.executor.utils.RpcConstants
+import org.onap.ccsdk.apps.blueprintsprocessor.functions.netconf.executor.api.DeviceInfo
+import org.onap.ccsdk.apps.blueprintsprocessor.functions.netconf.executor.api.NetconfReceivedEvent
+import org.onap.ccsdk.apps.blueprintsprocessor.functions.netconf.executor.api.NetconfSessionListener
+import org.onap.ccsdk.apps.blueprintsprocessor.functions.netconf.executor.utils.NetconfMessageUtils
 import org.onap.ccsdk.apps.blueprintsprocessor.functions.netconf.executor.utils.RpcMessageUtils
 import org.slf4j.LoggerFactory
-import java.io.*
+import java.io.BufferedReader
+import java.io.IOException
+import java.io.InputStream
+import java.io.InputStreamReader
+import java.io.OutputStream
+import java.io.OutputStreamWriter
 import java.nio.charset.StandardCharsets
 import java.util.concurrent.CompletableFuture
 
+class NetconfDeviceCommunicator(private var inputStream: InputStream,
+                                private var out: OutputStream,
+                                private val deviceInfo: DeviceInfo,
+                                private val sessionListener: NetconfSessionListener,
+                                private var replies: MutableMap<String, CompletableFuture<String>>) : Thread() {
 
-class NetconfStreamThread(private var inputStream: InputStream, private var out : OutputStream,
-                          private val netconfDeviceInfo: DeviceInfo, private val netconfSessionDelegate: NetconfSessionDelegate,
-                          private var replies :MutableMap<String, CompletableFuture<String>> ) : Thread() {
+    private val log = LoggerFactory.getLogger(NetconfDeviceCommunicator::class.java)
+    private var state = NetconfMessageState.NO_MATCHING_PATTERN
 
-    val log = LoggerFactory.getLogger(NetconfStreamThread::class.java)
-    lateinit var state : NetconfMessageState
-   // val outputStream = OutputStreamWriter(out, StandardCharsets.UTF_8)
-   private var outputStream: OutputStreamWriter? = null
+    init {
+        start()
+    }
 
     override fun run() {
         var bufferReader: BufferedReader? = null
@@ -47,52 +54,58 @@ class NetconfStreamThread(private var inputStream: InputStream, private var out
             var socketClosed = false
             val deviceReplyBuilder = StringBuilder()
             while (!socketClosed) {
-                val cInt = bufferReader!!.read()
+                val cInt = bufferReader.read()
                 if (cInt == -1) {
-                    log.debug("Netconf device {} sent error char in session will need to be reopend",
-                            netconfDeviceInfo)
-                    NetconfDeviceOutputEvent(NetconfDeviceOutputEvent.Type.SESSION_CLOSED, null!!, null!!,
-                            null !!, netconfDeviceInfo)
+                    log.error("$deviceInfo: Received cInt = -1")
+//                    bufferReader.close()
                     socketClosed = true
-                    log.debug("Netconf device {} ERROR cInt == -1 socketClosed = true", netconfDeviceInfo)
+//                    sessionListener.notify(NetconfReceivedEvent(
+//                        NetconfReceivedEvent.Type.SESSION_CLOSED,
+//                        deviceInfo = deviceInfo))
                 }
                 val c = cInt.toChar()
                 state = state.evaluateChar(c)
                 deviceReplyBuilder.append(c)
                 if (state === NetconfMessageState.END_PATTERN) {
                     var deviceReply = deviceReplyBuilder.toString()
-                    if (deviceReply == RpcConstants.END_PATTERN) {
+                    if (deviceReply == RpcMessageUtils.END_PATTERN) {
                         socketClosed = true
-                        close(deviceReply)
+                        bufferReader.close()
+                        sessionListener.notify(NetconfReceivedEvent(
+                            NetconfReceivedEvent.Type.DEVICE_UNREGISTERED,
+                            deviceInfo = deviceInfo))
                     } else {
-                        deviceReply = deviceReply.replace(RpcConstants.END_PATTERN, "")
-                        dealWithReply(deviceReply)
+                        deviceReply = deviceReply.replace(RpcMessageUtils.END_PATTERN, "")
+                        receivedMessage(deviceReply)
                         deviceReplyBuilder.setLength(0)
                     }
                 } else if (state === NetconfMessageState.END_CHUNKED_PATTERN) {
                     var deviceReply = deviceReplyBuilder.toString()
-                    if (!RpcMessageUtils.validateChunkedFraming(deviceReply)) {
-                        log.debug("Netconf device {} send badly framed message {}", netconfDeviceInfo, deviceReply)
+                    if (!NetconfMessageUtils.validateChunkedFraming(deviceReply)) {
+                        log.debug("$deviceInfo: Received badly framed message $deviceReply")
                         socketClosed = true
-                        close(deviceReply)
+                        sessionListener.notify(NetconfReceivedEvent(
+                            NetconfReceivedEvent.Type.DEVICE_ERROR,
+                            deviceInfo = deviceInfo))
                     } else {
-                        deviceReply = deviceReply.replace(RpcConstants.MSGLEN_REGEX_PATTERN.toRegex(), "")
-                        deviceReply = deviceReply.replace(RpcMessageUtils.CHUNKED_END_REGEX_PATTERN.toRegex(), "")
-                        dealWithReply(deviceReply)
+                        deviceReply = deviceReply.replace(RpcMessageUtils.MSGLEN_REGEX_PATTERN.toRegex(), "")
+                        deviceReply = deviceReply.replace(NetconfMessageUtils.CHUNKED_END_REGEX_PATTERN.toRegex(), "")
+                        receivedMessage(deviceReply)
                         deviceReplyBuilder.setLength(0)
                     }
                 }
             }
+
         } catch (e: IOException) {
-            log.warn("Error in reading from the session for device {} ", netconfDeviceInfo, e)
-            throw IllegalStateException(
-                    NetconfException(message = "Error in reading from the session for device {}$netconfDeviceInfo"))
+            log.warn("$deviceInfo: Fail while reading from channel", e)
+            sessionListener.notify(NetconfReceivedEvent(
+                NetconfReceivedEvent.Type.DEVICE_ERROR,
+                deviceInfo = deviceInfo))
         }
 
     }
 
-    enum class NetconfMessageState {
-
+    private enum class NetconfMessageState {
         NO_MATCHING_PATTERN {
             override fun evaluateChar(c: Char): NetconfMessageState {
                 return if (c == ']') {
@@ -194,50 +207,37 @@ class NetconfStreamThread(private var inputStream: InputStream, private var out
         internal abstract fun evaluateChar(c: Char): NetconfMessageState
     }
 
-    private fun close(deviceReply: String) {
-        log.debug("Netconf device {} socketClosed = true DEVICE_UNREGISTERED {}", netconfDeviceInfo, deviceReply)
-        NetconfDeviceOutputEvent(NetconfDeviceOutputEvent.Type.DEVICE_UNREGISTERED, null!!, null!!, null!!,
-                netconfDeviceInfo)
-        this.interrupt()
-    }
-
-    private fun dealWithReply(deviceReply: String) {
-        if (deviceReply.contains(RpcConstants.RPC_REPLY) || deviceReply.contains(RpcConstants.RPC_ERROR)
-                || deviceReply.contains(RpcConstants.HELLO)) {
-            log.info("From Netconf Device: {} \n for Message-ID: {} \n Device-Reply: \n {} \n ", netconfDeviceInfo,
-                    RpcMessageUtils.getMsgId(deviceReply), deviceReply)
-            val event = NetconfDeviceOutputEvent(NetconfDeviceOutputEvent.Type.DEVICE_REPLY,
-                    null!!, deviceReply, RpcMessageUtils.getMsgId(deviceReply), netconfDeviceInfo)
-            netconfSessionDelegate.notify(event)
-        } else {
-            log.debug("Error Reply: \n {} \n from Netconf Device: {}", deviceReply, netconfDeviceInfo)
-        }
-    }
-
-    @SuppressWarnings("squid:S3655")
-    @Override
-    fun sendMessage(request: String): CompletableFuture<String> {
-        val messageId = RpcMessageUtils.getMsgId(request)
-        return sendMessage(request, messageId.get())
-    }
-
     fun sendMessage(request: String, messageId: String): CompletableFuture<String> {
-        log.info("Sending message: \n {} \n to NETCONF Device: {}", request, netconfDeviceInfo)
-        val cf = CompletableFuture<String>()
-        replies.put(messageId, cf)
-       // outputStream = OutputStreamWriter(out, StandardCharsets.UTF_8)
-        synchronized(OutputStreamWriter(out, StandardCharsets.UTF_8)) {
+        log.info("$deviceInfo: Sending message: \n $request")
+        val future = CompletableFuture<String>()
+        replies.put(messageId, future)
+        val outputStream = OutputStreamWriter(out, StandardCharsets.UTF_8)
+        synchronized(this) {
             try {
-
-                OutputStreamWriter(out, StandardCharsets.UTF_8).write(request)
-                OutputStreamWriter(out, StandardCharsets.UTF_8).flush()
+                outputStream.write(request)
+                outputStream.flush()
             } catch (e: IOException) {
-                log.error("Writing to NETCONF Device {} failed", netconfDeviceInfo, e)
-                cf.completeExceptionally(e)
+                log.error("$deviceInfo: Failed to send message : \n $request", e)
+                future.completeExceptionally(e)
             }
 
         }
-        return cf
+        return future
     }
 
-}
\ No newline at end of file
+    private fun receivedMessage(deviceReply: String) {
+        if (deviceReply.contains(RpcMessageUtils.RPC_REPLY) || deviceReply.contains(RpcMessageUtils.RPC_ERROR)
+            || deviceReply.contains(RpcMessageUtils.HELLO)) {
+            log.info("$deviceInfo: Received message with messageId: {}  \n $deviceReply",
+                NetconfMessageUtils.getMsgId(deviceReply))
+
+        } else {
+            log.error("$deviceInfo: Invalid message received: \n $deviceReply")
+        }
+        sessionListener.notify(NetconfReceivedEvent(
+            NetconfReceivedEvent.Type.DEVICE_REPLY,
+            deviceReply,
+            NetconfMessageUtils.getMsgId(deviceReply),
+            deviceInfo))
+    }
+}
diff --git a/ms/blueprintsprocessor/functions/netconf-executor/src/main/kotlin/org/onap/ccsdk/apps/blueprintsprocessor/functions/netconf/executor/core/NetconfRpcServiceImpl.kt b/ms/blueprintsprocessor/functions/netconf-executor/src/main/kotlin/org/onap/ccsdk/apps/blueprintsprocessor/functions/netconf/executor/core/NetconfRpcServiceImpl.kt
new file mode 100644 (file)
index 0000000..5c633a5
--- /dev/null
@@ -0,0 +1,265 @@
+/*
+ * Copyright © 2017-2019 AT&T, Bell Canada
+ *
+ * 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.ccsdk.apps.blueprintsprocessor.functions.netconf.executor.core
+
+import org.onap.ccsdk.apps.blueprintsprocessor.functions.netconf.executor.api.DeviceInfo
+import org.onap.ccsdk.apps.blueprintsprocessor.functions.netconf.executor.api.DeviceResponse
+import org.onap.ccsdk.apps.blueprintsprocessor.functions.netconf.executor.api.NetconfException
+import org.onap.ccsdk.apps.blueprintsprocessor.functions.netconf.executor.api.NetconfRpcService
+import org.onap.ccsdk.apps.blueprintsprocessor.functions.netconf.executor.api.NetconfSession
+import org.onap.ccsdk.apps.blueprintsprocessor.functions.netconf.executor.utils.NetconfDatastore
+import org.onap.ccsdk.apps.blueprintsprocessor.functions.netconf.executor.utils.NetconfMessageUtils
+import org.onap.ccsdk.apps.blueprintsprocessor.functions.netconf.executor.utils.RpcStatus
+import org.slf4j.LoggerFactory
+import java.util.concurrent.TimeUnit
+
+class NetconfRpcServiceImpl(private val deviceInfo: DeviceInfo) : NetconfRpcService {
+
+    private val log = LoggerFactory.getLogger(NetconfRpcService::class.java)
+
+    private lateinit var netconfSession: NetconfSession
+
+    fun setNetconfSession(netconfSession: NetconfSession) {
+        this.netconfSession = netconfSession
+    }
+
+    override fun getConfig(messageId: String, filter: String, configTarget: String,
+                           messageTimeout: Int): DeviceResponse {
+        var output = DeviceResponse()
+        log.info("$deviceInfo: getConfig: messageId($messageId)")
+        try {
+            val message = NetconfMessageUtils.getConfig(messageId, configTarget, filter)
+            output = asyncRpc(message, messageId, messageTimeout)
+        } catch (e: Exception) {
+            output.status = RpcStatus.FAILURE
+            output.errorMessage = "$deviceInfo: failed in get-config command $e.message"
+        }
+        return output
+    }
+
+    override fun deleteConfig(messageId: String, configTarget: String, messageTimeout: Int): DeviceResponse {
+        var output = DeviceResponse()
+        log.info("$deviceInfo: deleteConfig: messageId($messageId)")
+        try {
+            val deleteConfigMessage = NetconfMessageUtils.deleteConfig(messageId, configTarget)
+            output.requestMessage = deleteConfigMessage
+            output = asyncRpc(deleteConfigMessage, messageId, messageTimeout)
+        } catch (e: Exception) {
+            output.status = RpcStatus.FAILURE
+            output.errorMessage = "$deviceInfo: failed in delete config command $e.message"
+        }
+        return output
+    }
+
+    override fun lock(messageId: String, configTarget: String, messageTimeout: Int): DeviceResponse {
+        var output = DeviceResponse()
+        log.info("$deviceInfo: lock: messageId($messageId)")
+        try {
+            val lockMessage = NetconfMessageUtils.lock(messageId, configTarget)
+            output.requestMessage = lockMessage
+            output = asyncRpc(lockMessage, messageId, messageTimeout)
+        } catch (e: Exception) {
+            output.status = RpcStatus.FAILURE
+            output.errorMessage = "$deviceInfo: failed in lock command $e.message"
+        }
+
+        return output
+    }
+
+    override fun unLock(messageId: String, configTarget: String, messageTimeout: Int): DeviceResponse {
+        var output = DeviceResponse()
+        log.info("$deviceInfo: unLock: messageId($messageId)")
+        try {
+            val unlockMessage = NetconfMessageUtils.unlock(messageId, configTarget)
+            output.requestMessage = unlockMessage
+            output = asyncRpc(unlockMessage, messageId, messageTimeout)
+        } catch (e: Exception) {
+            output.status = RpcStatus.FAILURE
+            output.errorMessage = "$deviceInfo: failed in lock command $e.message"
+        }
+        return output
+    }
+
+    override fun commit(messageId: String, discardChanges: Boolean, messageTimeout: Int): DeviceResponse {
+        var output = DeviceResponse()
+        log.info("$deviceInfo: commit: messageId($messageId)")
+        try {
+            val messageContent = NetconfMessageUtils.commit(messageId)
+            output = asyncRpc(messageContent, messageId, messageTimeout)
+        } catch (e: Exception) {
+            output.status = RpcStatus.FAILURE
+            output.errorMessage = "$deviceInfo: failed in commit command $e.message"
+
+            // If commit failed apply discard changes
+            if (discardChanges) {
+                val discardChangesConfigMessageId = "$messageId-discard-changes"
+                val discardOutput = discardConfig(discardChangesConfigMessageId, deviceInfo.replyTimeout)
+                output.addSubDeviceResponse(discardChangesConfigMessageId, discardOutput)
+            }
+        }
+        return output
+    }
+
+    override fun discardConfig(messageId: String, messageTimeout: Int): DeviceResponse {
+        var output = DeviceResponse()
+        log.info("$deviceInfo: discard: messageId($messageId)")
+        try {
+            val discardChangesMessage = NetconfMessageUtils.discardChanges(messageId)
+            output.requestMessage = discardChangesMessage
+            output = asyncRpc(discardChangesMessage, messageId, messageTimeout)
+        } catch (e: Exception) {
+            output.status = RpcStatus.FAILURE
+            output.errorMessage = "$deviceInfo: failed in discard changes command " + e.message
+        }
+        return output
+    }
+
+    override fun closeSession(messageId: String, force: Boolean, messageTimeout: Int): DeviceResponse {
+        var output = DeviceResponse()
+        log.info("$deviceInfo: closeSession: messageId($messageId)")
+        try {
+            val messageContent = NetconfMessageUtils.closeSession(messageId, force)
+            output = asyncRpc(messageContent, messageId, messageTimeout)
+        } catch (e: Exception) {
+            output.status = RpcStatus.FAILURE
+            output.errorMessage = "$deviceInfo: failed in closeSession command " + e.message
+        }
+        return output
+    }
+
+    @Throws(NetconfException::class)
+    override fun asyncRpc(request: String, messageId: String, messageTimeout: Int): DeviceResponse {
+        val response = DeviceResponse()
+        log.info("$deviceInfo: send asyncRpc with messageId($messageId)")
+        response.requestMessage = request
+
+        val rpcResponse = netconfSession.asyncRpc(request, messageId).get(messageTimeout.toLong(), TimeUnit.SECONDS)
+        if (!NetconfMessageUtils.checkReply(rpcResponse)) {
+            throw NetconfException(rpcResponse)
+        }
+        response.responseMessage = rpcResponse
+        response.status = RpcStatus.SUCCESS
+        response.errorMessage = null
+        return response
+    }
+
+    override fun editConfig(messageId: String, messageContent: String, lock: Boolean, configTarget: String,
+                            editDefaultOperation: String, deleteConfig: Boolean, validate: Boolean, commit: Boolean,
+                            discardChanges: Boolean, unlock: Boolean, messageTimeout: Int): DeviceResponse {
+        var editConfigDeviceResponse =
+            DeviceResponse()
+
+        try {
+            val editMessage =
+                NetconfMessageUtils.editConfig(messageId, configTarget, editDefaultOperation, messageContent)
+            editConfigDeviceResponse.requestMessage = editMessage
+
+            if (lock) {
+                val lockMessageId = "$messageId-lock"
+                val lockDeviceResponse = lock(lockMessageId, configTarget, deviceInfo.replyTimeout)
+                editConfigDeviceResponse.addSubDeviceResponse(lockMessageId, lockDeviceResponse)
+                if (!RpcStatus.SUCCESS.equals(lockDeviceResponse.status, ignoreCase = true)) {
+                    throw NetconfException(
+                        lockDeviceResponse.errorMessage!!)
+                }
+            }
+
+            if (deleteConfig) {
+                val deleteConfigMessageId = "$messageId-delete"
+                val deleteConfigDeviceResponse = deleteConfig(deleteConfigMessageId,
+                    NetconfDatastore.CANDIDATE, deviceInfo.replyTimeout)
+                editConfigDeviceResponse.addSubDeviceResponse(deleteConfigMessageId, deleteConfigDeviceResponse)
+                if (!RpcStatus.SUCCESS.equals(deleteConfigDeviceResponse.status,
+                        ignoreCase = true)) {
+                    throw NetconfException(
+                        deleteConfigDeviceResponse.errorMessage!!)
+                }
+            }
+
+            if (discardChanges) {
+                val discardConfigMessageId = "$messageId-discard"
+                val discardConfigDeviceResponse = discardConfig(discardConfigMessageId, deviceInfo.replyTimeout)
+                editConfigDeviceResponse.addSubDeviceResponse(discardConfigMessageId, discardConfigDeviceResponse)
+                if (!RpcStatus.SUCCESS.equals(discardConfigDeviceResponse.status,
+                        ignoreCase = true)) {
+                    throw NetconfException(
+                        discardConfigDeviceResponse.errorMessage!!)
+                }
+            }
+
+            editConfigDeviceResponse = asyncRpc(editMessage, messageId, messageTimeout)
+            if (!RpcStatus.SUCCESS.equals(editConfigDeviceResponse.status, ignoreCase = true)) {
+                throw NetconfException(
+                    editConfigDeviceResponse.errorMessage!!)
+            }
+
+            if (validate) {
+                val validateMessageId = "$messageId-validate"
+                val validateDeviceResponse = validate(validateMessageId,
+                    NetconfDatastore.CANDIDATE, deviceInfo.replyTimeout)
+                editConfigDeviceResponse.addSubDeviceResponse(validateMessageId, validateDeviceResponse)
+                if (!RpcStatus.SUCCESS.equals(validateDeviceResponse.status, ignoreCase = true)) {
+                    throw NetconfException(
+                        validateDeviceResponse.errorMessage!!)
+                }
+            }
+
+            /**
+             * If Commit is enable, the commit response is treated as Edit config response, If commit failed, we
+             * need not to throw an exception, until we unlock the device.
+             */
+            if (commit) {
+                val commitMessageId = "$messageId-commit"
+                val commitDeviceResponse =
+                    commit(commitMessageId, discardChanges, deviceInfo.replyTimeout)
+                editConfigDeviceResponse.addSubDeviceResponse(commitMessageId, commitDeviceResponse)
+                if (!RpcStatus.SUCCESS.equals(commitDeviceResponse.status, ignoreCase = true)) {
+                    throw NetconfException(
+                        commitDeviceResponse.errorMessage!!)
+                }
+            }
+
+        } catch (e: Exception) {
+            editConfigDeviceResponse.status = RpcStatus.FAILURE
+            editConfigDeviceResponse.errorMessage = e.message
+        } finally {
+            if (unlock) {
+                val unlockMessageId = "$messageId-unlock"
+                val unlockDeviceResponse = unLock(unlockMessageId, configTarget, deviceInfo.replyTimeout)
+                editConfigDeviceResponse.addSubDeviceResponse(unlockMessageId, unlockDeviceResponse)
+                if (!RpcStatus.SUCCESS.equals(unlockDeviceResponse.status, ignoreCase = true)) {
+                    editConfigDeviceResponse.status = RpcStatus.FAILURE
+                    editConfigDeviceResponse.errorMessage = unlockDeviceResponse.errorMessage
+                }
+            }
+        }
+        return editConfigDeviceResponse
+    }
+
+    override fun validate(messageId: String, configTarget: String, messageTimeout: Int): DeviceResponse {
+        var output = DeviceResponse()
+        try {
+            val validateMessage = NetconfMessageUtils.validate(messageId, configTarget)
+            output.requestMessage = validateMessage
+            output = asyncRpc(validateMessage, messageId, messageTimeout)
+        } catch (e: Exception) {
+            output.status = RpcStatus.FAILURE
+            output.errorMessage = "$deviceInfo: failed in validate command " + e.message
+        }
+        return output
+    }
+}
\ No newline at end of file
diff --git a/ms/blueprintsprocessor/functions/netconf-executor/src/main/kotlin/org/onap/ccsdk/apps/blueprintsprocessor/functions/netconf/executor/core/NetconfSessionFactory.kt b/ms/blueprintsprocessor/functions/netconf-executor/src/main/kotlin/org/onap/ccsdk/apps/blueprintsprocessor/functions/netconf/executor/core/NetconfSessionFactory.kt
deleted file mode 100644 (file)
index 370ea7a..0000000
+++ /dev/null
@@ -1,50 +0,0 @@
-/*
- * Copyright © 2017-2018 AT&T Intellectual Property.
- *
- * 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.ccsdk.apps.blueprintsprocessor.functions.netconf.executor.core
-
-import org.onap.ccsdk.apps.blueprintsprocessor.functions.netconf.executor.NetconfException
-import org.onap.ccsdk.apps.blueprintsprocessor.functions.netconf.executor.interfaces.DeviceInfo
-import org.onap.ccsdk.apps.blueprintsprocessor.functions.netconf.executor.interfaces.NetconfSession
-import java.util.*
-
-object NetconfSessionFactory {
-
-    private fun NetconfSessionFactory() {}
-
-    val netConfSessionManagerMap = HashMap<String, NetconfSession>()
-
-    fun registerNetConfSessionManager(type: String, netconfSession: NetconfSession) {
-        netConfSessionManagerMap[type] = netconfSession
-    }
-
-    /**
-     * Creates a new NETCONF session for the specified device.
-     *
-     * @param type type of the session.
-     * @param netconfDeviceInfo information of the device to create the session for.
-     * @return Instance of NetconfSession.
-     * @throws NetconfException when problems arise establishing the connection.
-     */
-    @Throws(NetconfException::class)
-    fun instance(type: String, netconfDeviceInfo: DeviceInfo): NetconfSession {
-        return if (netConfSessionManagerMap.containsKey(type)) {
-            netConfSessionManagerMap[type]!!
-        } else {
-            return NetconfSessionImpl(netconfDeviceInfo)
-        }
-    }
-}
\ No newline at end of file
index 34c0181..21570a2 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright © 2017-2018 AT&T Intellectual Property.
+ * Copyright © 2017-2019 AT&T, Bell Canada
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -18,200 +18,141 @@ package org.onap.ccsdk.apps.blueprintsprocessor.functions.netconf.executor.core
 
 import com.google.common.collect.ImmutableList
 import com.google.common.collect.ImmutableSet
-import org.apache.sshd.client.ClientBuilder
 import org.apache.sshd.client.SshClient
 import org.apache.sshd.client.channel.ClientChannel
 import org.apache.sshd.client.session.ClientSession
-import org.apache.sshd.client.simple.SimpleClient
 import org.apache.sshd.common.FactoryManager
 import org.apache.sshd.server.keyprovider.SimpleGeneratorHostKeyProvider
-import org.onap.ccsdk.apps.blueprintsprocessor.functions.netconf.executor.NetconfException
-import org.onap.ccsdk.apps.blueprintsprocessor.functions.netconf.executor.data.NetconfDeviceOutputEvent
-import org.onap.ccsdk.apps.blueprintsprocessor.functions.netconf.executor.interfaces.DeviceInfo
-import org.onap.ccsdk.apps.blueprintsprocessor.functions.netconf.executor.interfaces.NetconfSession
-import org.onap.ccsdk.apps.blueprintsprocessor.functions.netconf.executor.interfaces.NetconfSessionDelegate
-import org.onap.ccsdk.apps.blueprintsprocessor.functions.netconf.executor.utils.RpcConstants
+import org.onap.ccsdk.apps.blueprintsprocessor.functions.netconf.executor.api.DeviceInfo
+import org.onap.ccsdk.apps.blueprintsprocessor.functions.netconf.executor.api.NetconfException
+import org.onap.ccsdk.apps.blueprintsprocessor.functions.netconf.executor.api.NetconfReceivedEvent
+import org.onap.ccsdk.apps.blueprintsprocessor.functions.netconf.executor.api.NetconfRpcService
+import org.onap.ccsdk.apps.blueprintsprocessor.functions.netconf.executor.api.NetconfSession
+import org.onap.ccsdk.apps.blueprintsprocessor.functions.netconf.executor.api.NetconfSessionListener
+import org.onap.ccsdk.apps.blueprintsprocessor.functions.netconf.executor.utils.NetconfMessageUtils
 import org.onap.ccsdk.apps.blueprintsprocessor.functions.netconf.executor.utils.RpcMessageUtils
+import org.onap.ccsdk.apps.blueprintsprocessor.functions.netconf.executor.utils.RpcStatus
 import org.slf4j.LoggerFactory
 import java.io.IOException
 import java.util.*
-import java.util.concurrent.*
+import java.util.concurrent.CompletableFuture
+import java.util.concurrent.ConcurrentHashMap
+import java.util.concurrent.ExecutionException
+import java.util.concurrent.TimeUnit
+import java.util.concurrent.TimeoutException
 import java.util.concurrent.atomic.AtomicInteger
 
+class NetconfSessionImpl(private val deviceInfo: DeviceInfo, private val rpcService: NetconfRpcService) :
+    NetconfSession {
 
-class NetconfSessionImpl(private val deviceInfo: DeviceInfo ): NetconfSession  {
-    val log = LoggerFactory.getLogger(NetconfSessionImpl::class.java)
-    var connectTimeout: Long = 0
-    var replyTimeout: Int = 0
-    var idleTimeout: Int = 0
-    var sessionID: String? = null
-    var errorReplies: MutableList<String> = mutableListOf()
-    var netconfCapabilities = ImmutableList.of("urn:ietf:params:netconf:base:1.0", "urn:ietf:params:netconf:base:1.1")
+    private val log = LoggerFactory.getLogger(NetconfSessionImpl::class.java)
 
-   // var replies: MutableMap<String, CompletableFuture<String>> = mutableListOf<String,CompletableFuture<String>()>()
-    var replies: MutableMap<String, CompletableFuture<String>> = ConcurrentHashMap()
-    val deviceCapabilities = LinkedHashSet<String>()
+    private val errorReplies: MutableList<String> = Collections.synchronizedList(listOf())
+    private val replies: MutableMap<String, CompletableFuture<String>> = ConcurrentHashMap()
+    private val deviceCapabilities = setOf<String>()
 
-    lateinit var session: ClientSession
-    lateinit var client: SshClient
-    lateinit var channel: ClientChannel
-    var streamHandler: NetconfStreamThread? = null
+    private var connectionTimeout: Long = 0
+    private var replyTimeout: Int = 0
+    private var idleTimeout: Int = 0
+    private var sessionId: String? = null
 
-    val messageIdInteger = AtomicInteger(1)
-    private var onosCapabilities = ImmutableList.of<String>(RpcConstants.NETCONF_10_CAPABILITY, RpcConstants.NETCONF_11_CAPABILITY)
+    private lateinit var session: ClientSession
+    private lateinit var client: SshClient
+    private lateinit var channel: ClientChannel
+    private lateinit var streamHandler: NetconfDeviceCommunicator
 
+    private val messageIdInteger = AtomicInteger(1)
+    private var capabilities =
+        ImmutableList.of(RpcMessageUtils.NETCONF_10_CAPABILITY, RpcMessageUtils.NETCONF_11_CAPABILITY)
 
-    init {
-          startConnection()
-    }
-
-    private fun startConnection() {
-        connectTimeout = deviceInfo.connectTimeoutSec
-        replyTimeout = deviceInfo.replyTimeout
-        idleTimeout = deviceInfo.idleTimeout
-        log.info("Connecting to NETCONF Device {} with timeouts C:{}, R:{}, I:{}", deviceInfo, connectTimeout,
-                replyTimeout, idleTimeout)
+    override fun connect() {
         try {
-            startClient()
-        } catch (e: IOException) {
-            throw NetconfException("Failed to establish SSH with device ${deviceInfo.deviceId}",e)
-        } catch (e:Exception){
-            throw NetconfException("Failed to establish SSH with device $deviceInfo",e)
+            log.info("$deviceInfo: Connecting to Netconf Device with timeouts C:${deviceInfo.connectTimeout}, " +
+                    "R:${deviceInfo.replyTimeout}, I:${deviceInfo.idleTimeout}")
+            startConnection()
+            log.info("$deviceInfo: Connected to Netconf Device")
+        } catch (e: NetconfException) {
+            log.error("$deviceInfo: Netconf Device Connection Failed. ${e.message}")
+            throw NetconfException(e)
         }
-
     }
 
-    private fun startClient() {
-        log.info("in the startClient")
-        // client = SshClient.setUpDefaultClient().toInt()
-        client = SshClient.setUpDefaultClient()
+    override fun disconnect() {
+        if (rpcService.closeSession(messageIdInteger.incrementAndGet().toString(), false, replyTimeout).status.equals(
+                RpcStatus.FAILURE, true)) {
+            rpcService.closeSession(messageIdInteger.incrementAndGet().toString(), true, replyTimeout)
+        }
 
-        client = ClientBuilder.builder().build() as SshClient
-        log.info("client {}>>",client)
-        client.getProperties().putIfAbsent(FactoryManager.IDLE_TIMEOUT, TimeUnit.SECONDS.toMillis(idleTimeout.toLong()))
-        client.getProperties().putIfAbsent(FactoryManager.NIO2_READ_TIMEOUT,
-                TimeUnit.SECONDS.toMillis(idleTimeout + 15L))
-        client.start()
-        client.setKeyPairProvider(SimpleGeneratorHostKeyProvider())
-        log.info("client {}>>",client.isOpen)
-        startSession()
+        session.close()
+        // Closes the socket which should interrupt the streamHandler
+        channel.close()
+        client.close()
     }
 
-    private fun startSession() {
-        log.info("in the startSession")
-        val connectFuture = client.connect(deviceInfo.name, deviceInfo.ipAddress, deviceInfo.port)
-                .verify(connectTimeout, TimeUnit.SECONDS)
-        log.info("connectFuture {}>>"+connectFuture)
-        session = connectFuture.session
-
-        session.addPasswordIdentity(deviceInfo.pass)
-        session.auth().verify(connectTimeout, TimeUnit.SECONDS)
-
-        val event = session.waitFor(ImmutableSet.of(ClientSession.ClientSessionEvent.WAIT_AUTH,
-                ClientSession.ClientSessionEvent.CLOSED, ClientSession.ClientSessionEvent.AUTHED), 0)
-
-        if (!event.contains(ClientSession.ClientSessionEvent.AUTHED)) {
-            log.debug("Session closed {} for event {}", session.isClosed(), event)
-            throw NetconfException(String
-                    .format("Failed to authenticate session with device (%s) check the user/pwd or key", deviceInfo))
-        }
-        openChannel()
+    override fun reconnect() {
+        disconnect()
+        connect()
     }
 
-    private fun openChannel() {
-        log.info("in the open Channel")
-        channel = session.createSubsystemChannel("netconf")
-        val channeuture = channel.open()
-
-        if (channeuture!!.await(connectTimeout, TimeUnit.SECONDS) && channeuture.isOpened) {
-           val netconfSessionDelegate:NetconfSessionDelegate = NetconfSessionDelegateImpl()
-            streamHandler = NetconfStreamThread(channel.getInvertedOut(), channel.getInvertedIn(), deviceInfo,
-                    netconfSessionDelegate, replies)
-            sendHello()
-        } else {
-            throw NetconfException(String.format("Failed to open channel with device (%s) $deviceInfo", deviceInfo))
-        }
-    }
+    override fun syncRpc(request: String, messageId: String): String {
+        val formattedRequest = NetconfMessageUtils.formatRPCRequest(request, messageId, deviceCapabilities)
 
-    private fun sendHello() {
-        sessionID = (-1).toString()
+        checkAndReestablish()
 
-        val serverHelloResponse = syncRpc(RpcMessageUtils.createHelloString(onosCapabilities), (-1).toString())
-        val sessionIDMatcher = RpcMessageUtils.SESSION_ID_REGEX_PATTERN.matcher(serverHelloResponse)
+        try {
+            return streamHandler.sendMessage(formattedRequest, messageId).get(replyTimeout.toLong(), TimeUnit.SECONDS)
+//            replies.remove(messageId)
+        } catch (e: InterruptedException) {
+            Thread.currentThread().interrupt()
+            throw NetconfException("$deviceInfo: Interrupted while waiting for reply for request: $formattedRequest", e)
+        } catch (e: TimeoutException) {
+            throw NetconfException("$deviceInfo: Timed out while waiting for reply for request $formattedRequest after $replyTimeout sec.",
+                e)
+        } catch (e: ExecutionException) {
+            log.warn("$deviceInfo: Closing session($sessionId) due to unexpected Error", e)
+            try {
+                session.close()
+                // Closes the socket which should interrupt the streamHandler
+                channel.close()
+                client.close()
+            } catch (ioe: IOException) {
+                log.warn("$deviceInfo: Error closing session($sessionId) for host($deviceInfo)", ioe)
+            }
 
-        if (sessionIDMatcher.find()) {
-            sessionID = sessionIDMatcher.group(1)
-        } else {
-            throw NetconfException("Missing SessionID in server hello reponse.")
-        }
+//            NetconfReceivedEvent(NetconfReceivedEvent.Type.SESSION_CLOSED, "",
+//                "Closed due to unexpected error " + e.cause, "-1", deviceInfo)
+            errorReplies.clear() // move to cleanUp()?
+            replies.clear()
 
-        val capabilityMatcher = RpcMessageUtils.CAPABILITY_REGEX_PATTERN.matcher(serverHelloResponse)
-        while (capabilityMatcher.find()) {
-            deviceCapabilities.add(capabilityMatcher.group(1))
+            throw NetconfException("$deviceInfo: Closing session $sessionId for request $formattedRequest", e)
         }
     }
 
+    override fun asyncRpc(request: String, messageId: String): CompletableFuture<String> {
+        val formattedRequest = NetconfMessageUtils.formatRPCRequest(request, messageId, deviceCapabilities)
 
-    override fun asyncRpc( request: String, msgId: String): CompletableFuture<String> {
-        //return close(false);
-       var  request = RpcMessageUtils.formatRPCRequest(request, msgId, deviceCapabilities)
-        /**
-         * Checking Liveliness of the Session
-         */
         checkAndReestablish()
 
-        return streamHandler!!.sendMessage(request, msgId).handleAsync { reply, t ->
+        return streamHandler.sendMessage(formattedRequest, messageId).handleAsync { reply, t ->
             if (t != null) {
-                //throw NetconfTransportException(t)
-                throw NetconfException(msgId)
+                throw NetconfException(messageId, t)
             }
             reply
         }
     }
 
-    override fun close(): Boolean {
-        return close(false);
-    }
-    @Throws(NetconfException::class)
-    private fun close(force: Boolean): Boolean {
-        val rpc = StringBuilder()
-        rpc.append("<rpc xmlns=\"urn:ietf:params:xml:ns:netconf:base:1.0\">")
-        if (force) {
-            rpc.append("<kill-session/>")
-        } else {
-            rpc.append("<close-session/>")
-        }
-        rpc.append("</rpc>")
-        rpc.append(RpcConstants.END_PATTERN)
-        return RpcMessageUtils.checkReply(sendRequest(rpc.toString())) || close(true)
-    }
-
-
-
-    override fun getSessionId(): String? {
-          return this.sessionID
-    }
-
-    override fun getDeviceCapabilitiesSet(): Set<String> {
-        return Collections.unmodifiableSet(deviceCapabilities);
-    }
-
-    fun setCapabilities(capabilities: ImmutableList<String>) {
-        onosCapabilities = capabilities
-    }
-
     override fun checkAndReestablish() {
         try {
             if (client.isClosed) {
-                log.debug("Trying to restart the whole SSH connection with {}", deviceInfo.deviceId)
+                log.info("Trying to restart the whole SSH connection with {}", deviceInfo)
                 replies.clear()
                 startConnection()
             } else if (session.isClosed) {
-                log.debug("Trying to restart the session with {}", deviceInfo.deviceId)
+                log.info("Trying to restart the session with {}", deviceInfo)
                 replies.clear()
                 startSession()
             } else if (channel.isClosed) {
-                log.debug("Trying to reopen the channel with {}", deviceInfo.deviceId)
+                log.info("Trying to reopen the channel with {}", deviceInfo)
                 replies.clear()
                 openChannel()
             } else {
@@ -227,73 +168,111 @@ class NetconfSessionImpl(private val deviceInfo: DeviceInfo ): NetconfSession  {
 
     }
 
-    override fun setCapabilities(capabilities: List<String>) {
-        super.setCapabilities(capabilities)
-    }
-
     override fun getDeviceInfo(): DeviceInfo {
         return deviceInfo
     }
 
-    @Throws(NetconfException::class)
-    private fun sendRequest(request: String): String {
-        return syncRpc(request, messageIdInteger.getAndIncrement().toString())
+    override fun getSessionId(): String {
+        return this.sessionId!!
     }
 
-    @Throws(NetconfException::class)
-    override fun syncRpc(request: String, messageId: String): String {
-        var request = request
-        request = RpcMessageUtils.formatRPCRequest(request, messageId, deviceCapabilities)
-
-        /**
-         * Checking Liveliness of the Session
-         */
-        checkAndReestablish()
+    override fun getDeviceCapabilitiesSet(): Set<String> {
+        return Collections.unmodifiableSet(deviceCapabilities)
+    }
 
-        val response: String
+    private fun startConnection() {
+        connectionTimeout = deviceInfo.connectTimeout
+        replyTimeout = deviceInfo.replyTimeout
+        idleTimeout = deviceInfo.idleTimeout
         try {
-            response = streamHandler!!.sendMessage(request, messageId).get(replyTimeout.toLong(), TimeUnit.SECONDS)
-            replies.remove(messageId) // Why here???
-        } catch (e: InterruptedException) {
-            Thread.currentThread().interrupt()
-            throw NetconfException("Interrupted waiting for reply for request$request",e)
-        } catch (e: TimeoutException) {
-            throw NetconfException(
-                    "Timed out waiting for reply for request $request after $replyTimeout sec.",e)
-        } catch (e: ExecutionException) {
-            log.warn("Closing session {} for {} due to unexpected Error", sessionID, deviceInfo, e)
-            try {
-                session.close()
-                channel.close() // Closes the socket which should interrupt NetconfStreamThread
-                client.close()
-            } catch (ioe: IOException) {
-                log.warn("Error closing session {} on {}", sessionID, deviceInfo, ioe)
-            }
+            startClient()
+        } catch (e: Exception) {
+            throw NetconfException("$deviceInfo: Failed to establish SSH session", e)
+        }
 
-            NetconfDeviceOutputEvent(NetconfDeviceOutputEvent.Type.SESSION_CLOSED, null!!,
-                    "Closed due to unexpected error " + e.cause, Optional.of("-1"), deviceInfo)
-            errorReplies.clear() // move to cleanUp()?
-            replies.clear()
+    }
+
+    private fun startClient() {
+        client = SshClient.setUpDefaultClient()
+        client.properties.putIfAbsent(FactoryManager.IDLE_TIMEOUT, TimeUnit.SECONDS.toMillis(idleTimeout.toLong()))
+        client.properties.putIfAbsent(FactoryManager.NIO2_READ_TIMEOUT, TimeUnit.SECONDS.toMillis(idleTimeout + 15L))
+        client.keyPairProvider = SimpleGeneratorHostKeyProvider()
+        client.start()
+
+        startSession()
+    }
+
+    private fun startSession() {
+        log.info("$deviceInfo: Starting SSH session")
+        val connectFuture = client.connect(deviceInfo.username, deviceInfo.ipAddress, deviceInfo.port)
+            .verify(connectionTimeout, TimeUnit.SECONDS)
+        session = connectFuture.session
+        log.info("$deviceInfo: SSH session created")
+
+        authSession()
+    }
+
+    private fun authSession() {
+        session.addPasswordIdentity(deviceInfo.password)
+        session.auth().verify(connectionTimeout, TimeUnit.SECONDS)
+        val event = session.waitFor(ImmutableSet.of(ClientSession.ClientSessionEvent.WAIT_AUTH,
+            ClientSession.ClientSessionEvent.CLOSED, ClientSession.ClientSessionEvent.AUTHED), 0)
+        if (!event.contains(ClientSession.ClientSessionEvent.AUTHED)) {
+            throw NetconfException("$deviceInfo: Failed to authenticate session.")
+        }
+        log.info("$deviceInfo: SSH session authenticated")
+
+        openChannel()
+    }
+
+    private fun openChannel() {
+        channel = session.createSubsystemChannel("netconf")
+        val channelFuture = channel.open()
+        if (channelFuture.await(connectionTimeout, TimeUnit.SECONDS) && channelFuture.isOpened) {
+            log.info("$deviceInfo: SSH NETCONF subsystem channel opened")
+            setupHandler()
+        } else {
+            throw NetconfException("$deviceInfo: Failed to open SSH subsystem channel")
+        }
+    }
+
+    private fun setupHandler() {
+        val sessionListener: NetconfSessionListener = NetconfSessionListenerImpl()
+        streamHandler = NetconfDeviceCommunicator(channel.invertedOut, channel.invertedIn, deviceInfo,
+            sessionListener, replies)
+
+        exchangeHelloMessage()
+    }
+
+    private fun exchangeHelloMessage() {
+        sessionId = "-1"
+        val messageId = "-1"
 
-            throw NetconfException(
-                    "Closing session $sessionID for $deviceInfo for request $request",e)
+        val serverHelloResponse = syncRpc(NetconfMessageUtils.createHelloString(capabilities), messageId)
+        val sessionIDMatcher = NetconfMessageUtils.SESSION_ID_REGEX_PATTERN.matcher(serverHelloResponse)
+
+        if (sessionIDMatcher.find()) {
+            sessionId = sessionIDMatcher.group(1)
+        } else {
+            throw NetconfException("$deviceInfo: Missing sessionId in server hello message: $serverHelloResponse")
         }
 
-        log.debug("Response from NETCONF Device: \n {} \n", response)
-        return response.trim { it <= ' ' }
+        val capabilityMatcher = NetconfMessageUtils.CAPABILITY_REGEX_PATTERN.matcher(serverHelloResponse)
+        while (capabilityMatcher.find()) {
+            deviceCapabilities.plus(capabilityMatcher.group(1))
+        }
     }
 
-    inner class NetconfSessionDelegateImpl : NetconfSessionDelegate {
-        override fun notify(event: NetconfDeviceOutputEvent) {
+    inner class NetconfSessionListenerImpl : NetconfSessionListener {
+        override fun notify(event: NetconfReceivedEvent) {
             val messageId = event.getMessageID()
-            log.debug("messageID {}, waiting replies messageIDs {}", messageId, replies.keys)
-            if (messageId.isNullOrBlank()) {
-                errorReplies.add(event.getMessagePayload().toString())
-                log.error("Device {} sent error reply {}", event.getDeviceInfo(), event.getMessagePayload())
-                return
+
+            when (event.getType()) {
+                NetconfReceivedEvent.Type.DEVICE_UNREGISTERED -> disconnect()
+                NetconfReceivedEvent.Type.DEVICE_ERROR -> errorReplies.add(event.getMessagePayload())
+                NetconfReceivedEvent.Type.DEVICE_REPLY -> replies[messageId]?.complete(event.getMessagePayload())
+                NetconfReceivedEvent.Type.SESSION_CLOSED -> disconnect()
             }
-            val completedReply = replies[messageId] // remove(..)?
-            completedReply?.complete(event.getMessagePayload())
         }
     }
-    }
\ No newline at end of file
+}
\ No newline at end of file
diff --git a/ms/blueprintsprocessor/functions/netconf-executor/src/main/kotlin/org/onap/ccsdk/apps/blueprintsprocessor/functions/netconf/executor/data/NetconfAdaptorConstant.kt b/ms/blueprintsprocessor/functions/netconf-executor/src/main/kotlin/org/onap/ccsdk/apps/blueprintsprocessor/functions/netconf/executor/data/NetconfAdaptorConstant.kt
deleted file mode 100644 (file)
index d49c991..0000000
+++ /dev/null
@@ -1,43 +0,0 @@
-/*
- * Copyright © 2017-2018 AT&T Intellectual Property.
- *
- * 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.ccsdk.apps.blueprintsprocessor.functions.netconf.executor.data
-
-class NetconfAdaptorConstant {
-    companion object{
-        const val STATUS_CODE_SUCCESS = "200"
-        const val STATUS_CODE_FAILURE = "400"
-
-        const val STATUS_SUCCESS = "success"
-        const val STATUS_FAILURE = "failure"
-        const val STATUS_SKIPPED = "skipped"
-        const val LOG_MESSAGE_TYPE_LOG = "Log"
-
-        const val CONFIG_TARGET_RUNNING = "running"
-        const val CONFIG_TARGET_CANDIDATE = "candidate"
-        const val CONFIG_DEFAULT_OPERATION_MERGE = "merge"
-        const val CONFIG_DEFAULT_OPERATION_REPLACE = "replace"
-
-        const val DEFAULT_NETCONF_SESSION_MANAGER_TYPE = "DEFAULT_NETCONF_SESSION"
-
-        const val CONFIG_STATUS_PENDING = "pending"
-        const val CONFIG_STATUS_FAILED = "failed"
-        const val CONFIG_STATUS_SUCCESS = "success"
-
-        const val DEFAULT_MESSAGE_TIME_OUT = 30
-
-
-    }
-}
\ No newline at end of file
diff --git a/ms/blueprintsprocessor/functions/netconf-executor/src/main/kotlin/org/onap/ccsdk/apps/blueprintsprocessor/functions/netconf/executor/data/NetconfExecutionData.kt b/ms/blueprintsprocessor/functions/netconf-executor/src/main/kotlin/org/onap/ccsdk/apps/blueprintsprocessor/functions/netconf/executor/data/NetconfExecutionData.kt
deleted file mode 100644 (file)
index f66c14a..0000000
+++ /dev/null
@@ -1,122 +0,0 @@
-/*
- * Copyright © 2017-2018 AT&T Intellectual Property.
- *
- * 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.ccsdk.apps.blueprintsprocessor.functions.netconf.executor.data
-
-import org.onap.ccsdk.apps.blueprintsprocessor.functions.netconf.executor.interfaces.DeviceInfo
-import java.util.*
-
-
-class DeviceResponse {
-    lateinit var deviceInfo: DeviceInfo
-    lateinit var status: String
-    var errorMessage: String? = null
-    var responseMessage: String? = null
-    var requestMessage: String? = null
-    var subDeviceResponse: MutableMap<Any, Any>? = null
-
-    fun addSubDeviceResponse(key: String, subDeviceResponse: DeviceResponse) {
-        if (this.subDeviceResponse == null) {
-            this.subDeviceResponse = hashMapOf()
-        }
-        this.subDeviceResponse!![key] = subDeviceResponse
-    }
-}
-
-class NetconfDeviceOutputEvent {
-
-        private var type: NetconfDeviceOutputEvent.Type
-        private var messagePayload: String? = null
-        private var messageID: String? = null
-        private var deviceInfo: DeviceInfo? = null
-        private var subject: Any? = null
-        private var time: Long = 0
-
-        /**
-         * Type of device related events.
-         */
-        enum class Type {
-            DEVICE_REPLY,
-            DEVICE_NOTIFICATION,
-            DEVICE_UNREGISTERED,
-            DEVICE_ERROR,
-            SESSION_CLOSED
-        }
-
-        /**
-         * Creates an event of a given type and for the specified subject and the current time.
-         *
-         * @param type event type
-         * @param subject event subject
-         * @param payload message from the device
-         * @param msgID id of the message related to the event
-         * @param netconfDeviceInfo device of event
-         */
-        constructor(type: Type, subject: String, payload: String, msgID: Optional<String>, netconfDeviceInfo: DeviceInfo) {
-            this.type = type
-            this.subject = subject
-            this.messagePayload = payload
-            this.deviceInfo = netconfDeviceInfo
-            this.messageID = msgID.get()
-        }
-
-        /**
-         * Creates an event of a given type and for the specified subject and time.
-         *
-         * @param type event type
-         * @param subject event subject
-         * @param payload message from the device
-         * @param msgID id of the message related to the event
-         * @param netconfDeviceInfo device of event
-         * @param time occurrence time
-         */
-        constructor(type: Type, subject: Any, payload: String, msgID: String, netconfDeviceInfo: DeviceInfo, time: Long) {
-            this.type = type
-            this.subject = subject
-            this.time = time
-            this.messagePayload = payload
-            this.deviceInfo = netconfDeviceInfo
-            this.messageID = msgID
-        }
-
-    /**
-     * return the message payload of the reply form the device.
-     *
-     * @return reply
-     */
-    fun getMessagePayload(): String? {
-        return messagePayload
-    }
-
-    /**
-     * Event-related device information.
-     *
-     * @return information about the device
-     */
-    fun getDeviceInfo(): DeviceInfo? {
-        return deviceInfo
-    }
-
-    /**
-     * Reply messageId.
-     *
-     * @return messageId
-     */
-    fun getMessageID(): String? {
-        return messageID
-    }
-
-}
\ No newline at end of file
diff --git a/ms/blueprintsprocessor/functions/netconf-executor/src/main/kotlin/org/onap/ccsdk/apps/blueprintsprocessor/functions/netconf/executor/interfaces/NetconfSession.kt b/ms/blueprintsprocessor/functions/netconf-executor/src/main/kotlin/org/onap/ccsdk/apps/blueprintsprocessor/functions/netconf/executor/interfaces/NetconfSession.kt
deleted file mode 100644 (file)
index 8e16ab7..0000000
+++ /dev/null
@@ -1,110 +0,0 @@
-/*
- * Copyright © 2017-2018 AT&T Intellectual Property.
- *
- * 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.ccsdk.apps.blueprintsprocessor.functions.netconf.executor.interfaces
-
-import org.slf4j.LoggerFactory
-import java.util.concurrent.CompletableFuture
-
-interface NetconfSession {
-
-    /**
-     * Executes an asynchronous RPC request to the server and obtains a future for it's response.
-     *
-     * @param request the XML containing the RPC request for the server.
-     * @param msgId message id of the request.
-     * @return Server response or ERROR
-     * @throws NetconfException when there is a problem in the communication process on the underlying
-     * connection
-     * @throws NetconfTransportException on secure transport-layer error
-     */
-    fun asyncRpc(request: String, msgId: String): CompletableFuture<String>
-
-    /**
-     * Closes the Netconf session with the device. the first time it tries gracefully, then kills it
-     * forcefully
-     *
-     * @return true if closed
-     * @throws NetconfException when there is a problem in the communication process on the underlying
-     * connection
-     */
-    fun close(): Boolean
-
-    /**
-     * Gets the session ID of the Netconf session.
-     *
-     * @return Session ID as a string.
-     */
-    fun getSessionId(): String?
-
-    /**
-     * Gets the capabilities of the remote Netconf device associated to this session.
-     *
-     * @return Network capabilities as strings in a Set.
-     */
-    fun getDeviceCapabilitiesSet(): Set<String>
-
-    /**
-     * Checks the state of the underlying SSH session and connection and if necessary it reestablishes
-     * it. Should be implemented, providing a default here for retro compatibility.
-     *
-     * @throws NetconfException when there is a problem in reestablishing the connection or the session
-     * to the device.
-     */
-    fun checkAndReestablish() {
-        val log = LoggerFactory.getLogger(NetconfSession::class.java)
-        log.error("Not implemented/exposed by the underlying ({}) implementation", "NetconfSession")
-    }
-
-    /**
-     * Sets the ONOS side capabilities.
-     *
-     * @param capabilities list of capabilities has.
-     */
-    fun setCapabilities(capabilities: List<String>) {
-        // default implementation should be removed in the future
-        // no-op
-    }
-
-    /**
-     * Get the device information for initialised session.
-     *
-     * @return DeviceInfo as device information
-     */
-    fun getDeviceInfo(): DeviceInfo
-
-
-    /**
-     * Executes an asynchronous RPC request to the server and obtains a future for it's response.
-     *
-     * @param request the XML containing the RPC request for the server.
-     * @param msgId message id of the request.
-     * @return Server response or ERROR
-     * @throws NetconfException when there is a problem in the communication process on the underlying
-     * connection
-     * @throws NetconfTransportException on secure transport-layer error
-     */
-    fun syncRpc(request: String, msgId: String): String
-
-    /**
-     * Closes the Netconf session with the device. the first time it tries gracefully, then kills it
-     * forcefully
-     *
-     * @return true if closed
-     * @throws NetconfException when there is a problem in the communication process on the underlying
-     * connection
-     */
-}
\ No newline at end of file
diff --git a/ms/blueprintsprocessor/functions/netconf-executor/src/main/kotlin/org/onap/ccsdk/apps/blueprintsprocessor/functions/netconf/executor/utils/NetconfConstant.kt b/ms/blueprintsprocessor/functions/netconf-executor/src/main/kotlin/org/onap/ccsdk/apps/blueprintsprocessor/functions/netconf/executor/utils/NetconfConstant.kt
new file mode 100644 (file)
index 0000000..e0cbde5
--- /dev/null
@@ -0,0 +1,84 @@
+/*
+ * Copyright © 2017-2019 AT&T, Bell Canada
+ *
+ * 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.ccsdk.apps.blueprintsprocessor.functions.netconf.executor.utils
+
+object NetconfDatastore {
+    const val RUNNING = "running"
+    const val CANDIDATE = "candidate"
+}
+
+object RpcStatus {
+    const val SUCCESS = "success"
+    const val FAILURE = "failure"
+}
+
+object RpcMessageUtils {
+    const val OPEN = "<"
+    const val CLOSE = ">"
+    const val EQUAL = "="
+
+    const val HASH = "#"
+    const val HASH_CHAR = '#'
+
+    const val LF_CHAR = '\n'
+    const val NEW_LINE = "\n"
+
+    const val QUOTE = "\""
+    const val QUOTE_SPACE = "\" "
+
+    const val TAG_CLOSE = "/>"
+    const val END_OF_RPC_OPEN_TAG = "\">"
+    const val END_PATTERN = "]]>]]>"
+
+    const val HELLO = "hello"
+    const val RPC_REPLY = "rpc-reply"
+    const val RPC_ERROR = "rpc-error"
+
+    const val RPC_OPEN = "<rpc "
+    const val RPC_CLOSE = "</rpc>"
+    const val WITH_DEFAULT_OPEN = "<with-defaults "
+    const val WITH_DEFAULT_CLOSE = "</with-defaults>"
+    const val DEFAULT_OPERATION_OPEN = "<default-operation>"
+    const val DEFAULT_OPERATION_CLOSE = "</default-operation>"
+    const val SUBTREE_FILTER_OPEN = "<filter type=\"subtree\">"
+    const val SUBTREE_FILTER_CLOSE = "</filter>"
+    const val TARGET_OPEN = "<target>"
+    const val TARGET_CLOSE = "</target>"
+    const val SOURCE_OPEN = "<source>"
+    const val SOURCE_CLOSE = "</source>"
+    const val CONFIG_OPEN = "<config xmlns:nc=\"urn:ietf:params:xml:ns:netconf:base:1.0\">"
+    const val CONFIG_CLOSE = "</config>"
+    const val MSGLEN_REGEX_PATTERN = "\n#\\d+\n"
+
+    const val NUMBER_BETWEEN_QUOTES_MATCHER = "\"+([0-9]+)+\""
+
+    const val XML_HEADER = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>"
+    const val NETCONF_BASE_NAMESPACE = "xmlns=\"urn:ietf:params:xml:ns:netconf:base:1.0\""
+    const val NETCONF_WITH_DEFAULTS_NAMESPACE = "xmlns=\"urn:ietf:params:xml:ns:yang:ietf-netconf-with-defaults\""
+    const val SUBSCRIPTION_SUBTREE_FILTER_OPEN =
+        "<filter xmlns:base10=\"urn:ietf:params:xml:ns:netconf:base:1.0\" base10:type=\"subtree\">"
+
+    const val INTERLEAVE_CAPABILITY_STRING = "urn:ietf:params:netconf:capability:interleave:1.0"
+
+    const val CAPABILITY_REGEX = "capability>\\s*(.*?)\\s*capability>"
+
+    const val SESSION_ID_REGEX = "session-id>\\s*(.*?)\\s*session-id>"
+
+    const val MESSAGE_ID_STRING = "message-id"
+
+    const val NETCONF_10_CAPABILITY = "urn:ietf:params:netconf:base:1.0"
+    const val NETCONF_11_CAPABILITY = "urn:ietf:params:netconf:base:1.1"
+}
\ No newline at end of file
@@ -1,5 +1,5 @@
 /*
- * Copyright © 2017-2018 AT&T Intellectual Property.
+ * Copyright © 2017-2019 AT&T, Bell Canada
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
 package org.onap.ccsdk.apps.blueprintsprocessor.functions.netconf.executor.utils
 
 import org.apache.commons.lang3.StringUtils
-import org.onap.ccsdk.apps.blueprintsprocessor.functions.netconf.executor.NetconfException
-import org.onap.ccsdk.apps.blueprintsprocessor.functions.netconf.executor.data.NetconfAdaptorConstant
+import org.onap.ccsdk.apps.blueprintsprocessor.functions.netconf.executor.api.NetconfException
 import org.slf4j.LoggerFactory
 import org.xml.sax.InputSource
 import java.io.StringReader
 import java.nio.charset.StandardCharsets
-import java.util.Optional
 import java.util.regex.MatchResult
 import java.util.regex.Pattern
 import javax.xml.XMLConstants
 import javax.xml.parsers.DocumentBuilderFactory
-import kotlin.collections.ArrayList
 import kotlin.text.Charsets.UTF_8
 
 
-class RpcMessageUtils {
+class NetconfMessageUtils {
 
     companion object {
-        val log = LoggerFactory.getLogger(RpcMessageUtils::class.java)
-        // pattern to verify whole Chunked-Message format
-        val CHUNKED_FRAMING_PATTERN = Pattern.compile("(\\n#([1-9][0-9]*)\\n(.+))+\\n##\\n", Pattern.DOTALL)
-        val CHUNKED_END_REGEX_PATTERN = "\n##\n"
-        // pattern to parse each chunk-size in ChunkedMessage chunk
-        val CHUNKED_SIZE_PATTERN = Pattern.compile("\\n#([1-9][0-9]*)\\n")
-        val CAPABILITY_REGEX_PATTERN = Pattern.compile(RpcConstants.CAPABILITY_REGEX)
-        val SESSION_ID_REGEX_PATTERN = Pattern.compile(RpcConstants.SESSION_ID_REGEX)
-        val MSGID_STRING_PATTERN = Pattern.compile("${RpcConstants.MESSAGE_ID_STRING}=\"(.*?)\"")
-        val NEW_LINE = "\n"
+        val log = LoggerFactory.getLogger(NetconfMessageUtils::class.java)
+
+        const val NEW_LINE = "\n"
+        const val CHUNKED_END_REGEX_PATTERN = "\n##\n"
+
+        val CAPABILITY_REGEX_PATTERN: Pattern = Pattern.compile(RpcMessageUtils.CAPABILITY_REGEX)
+        val SESSION_ID_REGEX_PATTERN: Pattern = Pattern.compile(RpcMessageUtils.SESSION_ID_REGEX)
+
+        private val CHUNKED_FRAMING_PATTERN: Pattern =
+            Pattern.compile("(\\n#([1-9][0-9]*)\\n(.+))+\\n##\\n", Pattern.DOTALL)
+        private val CHUNKED_SIZE_PATTERN: Pattern = Pattern.compile("\\n#([1-9][0-9]*)\\n")
+        private val MSG_ID_STRING_PATTERN = Pattern.compile("${RpcMessageUtils.MESSAGE_ID_STRING}=\"(.*?)\"")
 
         fun getConfig(messageId: String, configType: String, filterContent: String?): String {
             val request = StringBuilder()
 
             request.append("<get-config>").append(NEW_LINE)
-            request.append(RpcConstants.SOURCE_OPEN).append(NEW_LINE)
-            request.append(RpcConstants.OPEN).append(configType).append(RpcConstants.TAG_CLOSE).append(NEW_LINE)
-            request.append(RpcConstants.SOURCE_CLOSE).append(NEW_LINE)
+            request.append(RpcMessageUtils.SOURCE_OPEN).append(NEW_LINE)
+            request.append(RpcMessageUtils.OPEN).append(configType).append(RpcMessageUtils.TAG_CLOSE)
+                .append(NEW_LINE)
+            request.append(RpcMessageUtils.SOURCE_CLOSE).append(NEW_LINE)
 
-            if (filterContent != null) {
-                request.append(RpcConstants.SUBTREE_FILTER_OPEN).append(NEW_LINE)
+            if (!filterContent.isNullOrEmpty()) {
+                request.append(RpcMessageUtils.SUBTREE_FILTER_OPEN).append(NEW_LINE)
                 request.append(filterContent).append(NEW_LINE)
-                request.append(RpcConstants.SUBTREE_FILTER_CLOSE).append(NEW_LINE)
+                request.append(RpcMessageUtils.SUBTREE_FILTER_CLOSE).append(NEW_LINE)
             }
             request.append("</get-config>").append(NEW_LINE)
 
@@ -64,13 +64,14 @@ class RpcMessageUtils {
         }
 
         fun doWrappedRpc(messageId: String, request: String): String {
-            val rpc = StringBuilder(RpcConstants.XML_HEADER).append(NEW_LINE)
-            rpc.append(RpcConstants.RPC_OPEN)
-            rpc.append(RpcConstants.MESSAGE_ID_STRING).append(RpcConstants.EQUAL)
-            rpc.append(RpcConstants.QUOTE).append(messageId).append(RpcConstants.QUOTE_SPACE)
-            rpc.append(RpcConstants.NETCONF_BASE_NAMESPACE).append(RpcConstants.CLOSE).append(NEW_LINE)
+            val rpc = StringBuilder(RpcMessageUtils.XML_HEADER).append(NEW_LINE)
+            rpc.append(RpcMessageUtils.RPC_OPEN)
+            rpc.append(RpcMessageUtils.MESSAGE_ID_STRING).append(RpcMessageUtils.EQUAL)
+            rpc.append(RpcMessageUtils.QUOTE).append(messageId).append(RpcMessageUtils.QUOTE_SPACE)
+            rpc.append(RpcMessageUtils.NETCONF_BASE_NAMESPACE).append(RpcMessageUtils.CLOSE)
+                .append(NEW_LINE)
             rpc.append(request)
-            rpc.append(RpcConstants.RPC_CLOSE)
+            rpc.append(RpcMessageUtils.RPC_CLOSE)
             // rpc.append(NEW_LINE).append(END_PATTERN);
 
             return rpc.toString()
@@ -82,18 +83,20 @@ class RpcMessageUtils {
             val request = StringBuilder()
 
             request.append("<edit-config>").append(NEW_LINE)
-            request.append(RpcConstants.TARGET_OPEN).append(NEW_LINE)
-            request.append(RpcConstants.OPEN).append(configType).append(RpcConstants.TAG_CLOSE).append(NEW_LINE)
-            request.append(RpcConstants.TARGET_CLOSE).append(NEW_LINE)
+            request.append(RpcMessageUtils.TARGET_OPEN).append(NEW_LINE)
+            request.append(RpcMessageUtils.OPEN).append(configType).append(RpcMessageUtils.TAG_CLOSE)
+                .append(NEW_LINE)
+            request.append(RpcMessageUtils.TARGET_CLOSE).append(NEW_LINE)
 
             if (defaultOperation != null) {
-                request.append(RpcConstants.DEFAULT_OPERATION_OPEN).append(defaultOperation).append(RpcConstants.DEFAULT_OPERATION_CLOSE)
+                request.append(RpcMessageUtils.DEFAULT_OPERATION_OPEN).append(defaultOperation)
+                    .append(RpcMessageUtils.DEFAULT_OPERATION_CLOSE)
                 request.append(NEW_LINE)
             }
 
-            request.append(RpcConstants.CONFIG_OPEN).append(NEW_LINE)
+            request.append(RpcMessageUtils.CONFIG_OPEN).append(NEW_LINE)
             request.append(newConfiguration.trim { it <= ' ' }).append(NEW_LINE)
-            request.append(RpcConstants.CONFIG_CLOSE).append(NEW_LINE)
+            request.append(RpcMessageUtils.CONFIG_CLOSE).append(NEW_LINE)
             request.append("</edit-config>").append(NEW_LINE)
 
             return doWrappedRpc(messageId, request.toString())
@@ -103,15 +106,16 @@ class RpcMessageUtils {
             val request = StringBuilder()
 
             request.append("<validate>").append(NEW_LINE)
-            request.append(RpcConstants.SOURCE_OPEN).append(NEW_LINE)
-            request.append(RpcConstants.OPEN).append(configType).append(RpcConstants.TAG_CLOSE).append(NEW_LINE)
-            request.append(RpcConstants.SOURCE_CLOSE).append(NEW_LINE)
+            request.append(RpcMessageUtils.SOURCE_OPEN).append(NEW_LINE)
+            request.append(RpcMessageUtils.OPEN).append(configType).append(RpcMessageUtils.TAG_CLOSE)
+                .append(NEW_LINE)
+            request.append(RpcMessageUtils.SOURCE_CLOSE).append(NEW_LINE)
             request.append("</validate>").append(NEW_LINE)
 
             return doWrappedRpc(messageId, request.toString())
         }
 
-        fun commit(messageId: String, message: String): String {
+        fun commit(messageId: String): String {
             val request = StringBuilder()
 
             request.append("<commit>").append(NEW_LINE)
@@ -125,9 +129,10 @@ class RpcMessageUtils {
             val request = StringBuilder()
 
             request.append("<unlock>").append(NEW_LINE)
-            request.append(RpcConstants.TARGET_OPEN).append(NEW_LINE)
-            request.append(RpcConstants.OPEN).append(configType).append(RpcConstants.TAG_CLOSE).append(NEW_LINE)
-            request.append(RpcConstants.TARGET_CLOSE).append(NEW_LINE)
+            request.append(RpcMessageUtils.TARGET_OPEN).append(NEW_LINE)
+            request.append(RpcMessageUtils.OPEN).append(configType).append(RpcMessageUtils.TAG_CLOSE)
+                .append(NEW_LINE)
+            request.append(RpcMessageUtils.TARGET_CLOSE).append(NEW_LINE)
             request.append("</unlock>").append(NEW_LINE)
 
             return doWrappedRpc(messageId, request.toString())
@@ -135,7 +140,7 @@ class RpcMessageUtils {
 
         @Throws(NetconfException::class)
         fun deleteConfig(messageId: String, netconfTargetConfig: String): String {
-            if (netconfTargetConfig == NetconfAdaptorConstant.CONFIG_TARGET_RUNNING) {
+            if (netconfTargetConfig == NetconfDatastore.RUNNING) {
                 log.warn("Target configuration for delete operation can't be \"running\" {}", netconfTargetConfig)
                 throw NetconfException("Target configuration for delete operation can't be running")
             }
@@ -143,9 +148,11 @@ class RpcMessageUtils {
             val request = StringBuilder()
 
             request.append("<delete-config>").append(NEW_LINE)
-            request.append(RpcConstants.TARGET_OPEN).append(NEW_LINE)
-            request.append(RpcConstants.OPEN).append(netconfTargetConfig).append(RpcConstants.TAG_CLOSE).append(NEW_LINE)
-            request.append(RpcConstants.TARGET_CLOSE).append(NEW_LINE)
+            request.append(RpcMessageUtils.TARGET_OPEN).append(NEW_LINE)
+            request.append(RpcMessageUtils.OPEN).append(netconfTargetConfig)
+                .append(RpcMessageUtils.TAG_CLOSE)
+                .append(NEW_LINE)
+            request.append(RpcMessageUtils.TARGET_CLOSE).append(NEW_LINE)
             request.append("</delete-config>").append(NEW_LINE)
 
             return doWrappedRpc(messageId, request.toString())
@@ -161,9 +168,10 @@ class RpcMessageUtils {
             val request = StringBuilder()
 
             request.append("<lock>").append(NEW_LINE)
-            request.append(RpcConstants.TARGET_OPEN).append(NEW_LINE)
-            request.append(RpcConstants.OPEN).append(configType).append(RpcConstants.TAG_CLOSE).append(NEW_LINE)
-            request.append(RpcConstants.TARGET_CLOSE).append(NEW_LINE)
+            request.append(RpcMessageUtils.TARGET_OPEN).append(NEW_LINE)
+            request.append(RpcMessageUtils.OPEN).append(configType).append(RpcMessageUtils.TAG_CLOSE)
+                .append(NEW_LINE)
+            request.append(RpcMessageUtils.TARGET_CLOSE).append(NEW_LINE)
             request.append("</lock>").append(NEW_LINE)
 
             return doWrappedRpc(messageId, request.toString())
@@ -190,7 +198,8 @@ class RpcMessageUtils {
                 dbf.setFeature(XMLConstants.FEATURE_SECURE_PROCESSING, true)
                 dbf.setFeature("http://xml.org/sax/features/external-general-entities", false)
                 dbf.setFeature("http://xml.org/sax/features/external-parameter-entities", false)
-                dbf.newDocumentBuilder().parse(InputSource(StringReader(rpcRequest.replace(RpcConstants.END_PATTERN, ""))))
+                dbf.newDocumentBuilder()
+                    .parse(InputSource(StringReader(rpcRequest.replace(RpcMessageUtils.END_PATTERN, ""))))
                 return true
             } catch (e: Exception) {
                 return false
@@ -198,14 +207,14 @@ class RpcMessageUtils {
 
         }
 
-        fun getMsgId(message: String): Optional<String> {
-            val matcher = MSGID_STRING_PATTERN.matcher(message)
+        fun getMsgId(message: String): String {
+            val matcher = MSG_ID_STRING_PATTERN.matcher(message)
             if (matcher.find()) {
-                return Optional.of(matcher.group(1))
+                return matcher.group(1)
             }
-            return if (message.contains(RpcConstants.HELLO)) {
-                Optional.of((-1).toString())
-            } else Optional.empty()
+            return if (message.contains(RpcMessageUtils.HELLO)) {
+                (-1).toString()
+            } else ""
         }
 
         fun validateChunkedFraming(reply: String): Boolean {
@@ -214,52 +223,51 @@ class RpcMessageUtils {
                 log.debug("Error Reply: {}", reply)
                 return false
             }
-            var chunkM = CHUNKED_SIZE_PATTERN.matcher(reply)
-            var chunks = ArrayList<MatchResult>()
+            val chunkM = CHUNKED_SIZE_PATTERN.matcher(reply)
+            val chunks = ArrayList<MatchResult>()
             var chunkdataStr = ""
             while (chunkM.find()) {
                 chunks.add(chunkM.toMatchResult())
                 // extract chunk-data (and later) in bytes
                 val bytes = Integer.parseInt(chunkM.group(1))
-                // var chunkdata = reply.substring(chunkM.end()).getBytes(StandardCharsets.UTF_8)
-                var chunkdata = reply.substring(chunkM.end()).toByteArray(StandardCharsets.UTF_8)
+                val chunkdata = reply.substring(chunkM.end()).toByteArray(StandardCharsets.UTF_8)
                 if (bytes > chunkdata.size) {
                     log.debug("Error Reply - wrong chunk size {}", reply)
                     return false
                 }
                 // convert (only) chunk-data part into String
-
                 chunkdataStr = String(chunkdata, 0, bytes, StandardCharsets.UTF_8)
                 // skip chunk-data part from next match
                 chunkM.region(chunkM.end() + chunkdataStr.length, reply.length)
             }
-            if (!CHUNKED_END_REGEX_PATTERN
-                            .equals(reply.substring(chunks[chunks.size - 1].end() + chunkdataStr.length))) {
+            if (!CHUNKED_END_REGEX_PATTERN.equals(reply.substring(chunks[chunks.size - 1].end() + chunkdataStr.length))) {
                 log.debug("Error Reply: {}", reply)
                 return false
             }
             return true
         }
 
-
         fun createHelloString(capabilities: List<String>): String {
-            val hellobuffer = StringBuilder()
-            hellobuffer.append(RpcConstants.XML_HEADER).append(NEW_LINE)
-            hellobuffer.append("<hello xmlns=\"urn:ietf:params:xml:ns:netconf:base:1.0\">").append(NEW_LINE)
-            hellobuffer.append("  <capabilities>").append(NEW_LINE)
+            val helloMessage = StringBuilder()
+            helloMessage.append(RpcMessageUtils.XML_HEADER).append(NEW_LINE)
+            helloMessage.append("<hello xmlns=\"urn:ietf:params:xml:ns:netconf:base:1.0\">").append(NEW_LINE)
+            helloMessage.append("  <capabilities>").append(NEW_LINE)
             if (capabilities.isNotEmpty()) {
-                capabilities.forEach { cap -> hellobuffer.append("    <capability>").append(cap).append("</capability>").append(NEW_LINE) }
+                capabilities.forEach { cap ->
+                    helloMessage.append("    <capability>").append(cap).append("</capability>").append(NEW_LINE)
+                }
             }
-            hellobuffer.append("  </capabilities>").append(NEW_LINE)
-            hellobuffer.append("</hello>").append(NEW_LINE)
-            hellobuffer.append(RpcConstants.END_PATTERN)
-            return hellobuffer.toString()
+            helloMessage.append("  </capabilities>").append(NEW_LINE)
+            helloMessage.append("</hello>").append(NEW_LINE)
+            helloMessage.append(RpcMessageUtils.END_PATTERN)
+            return helloMessage.toString()
         }
+
         fun formatRPCRequest(request: String, messageId: String, deviceCapabilities: Set<String>): String {
             var request = request
-            request = RpcMessageUtils.formatNetconfMessage(deviceCapabilities, request)
-            request = RpcMessageUtils.formatXmlHeader(request)
-            request = RpcMessageUtils.formatRequestMessageId(request, messageId)
+            request = NetconfMessageUtils.formatNetconfMessage(deviceCapabilities, request)
+            request = NetconfMessageUtils.formatXmlHeader(request)
+            request = NetconfMessageUtils.formatRequestMessageId(request, messageId)
 
             return request
         }
@@ -274,10 +282,10 @@ class RpcMessageUtils {
          */
         fun formatNetconfMessage(deviceCapabilities: Set<String>, message: String): String {
             var message = message
-            if (deviceCapabilities.contains(RpcConstants.NETCONF_11_CAPABILITY)) {
+            if (deviceCapabilities.contains(RpcMessageUtils.NETCONF_11_CAPABILITY)) {
                 message = formatChunkedMessage(message)
-            } else if (!message.endsWith(RpcConstants.END_PATTERN)) {
-                message = message + NEW_LINE + RpcConstants.END_PATTERN
+            } else if (!message.endsWith(RpcMessageUtils.END_PATTERN)) {
+                message = message + NEW_LINE + RpcMessageUtils.END_PATTERN
             }
             return message
         }
@@ -290,16 +298,17 @@ class RpcMessageUtils {
          */
         fun formatChunkedMessage(message: String): String {
             var message = message
-            if (message.endsWith(RpcConstants.END_PATTERN)) {
+            if (message.endsWith(RpcMessageUtils.END_PATTERN)) {
                 // message given had Netconf 1.0 EOM pattern -> remove
-                message = message.substring(0, message.length - RpcConstants.END_PATTERN.length)
+                message = message.substring(0, message.length - RpcMessageUtils.END_PATTERN.length)
             }
-            if (!message.startsWith(RpcConstants.NEW_LINE + RpcConstants.HASH)) {
+            if (!message.startsWith(RpcMessageUtils.NEW_LINE + RpcMessageUtils.HASH)) {
                 // chunk encode message
-                //message = (RpcConstants.NEW_LINE + RpcConstants.HASH + message.getBytes(UTF_8).size + RpcConstants.NEW_LINE + message +RpcConstants. NEW_LINE + RpcConstants.HASH + RpcConstants.HASH
-                 //       + RpcConstants.NEW_LINE)
-                message = (RpcConstants.NEW_LINE + RpcConstants.HASH + message.toByteArray(UTF_8).size + RpcConstants.NEW_LINE + message +RpcConstants. NEW_LINE + RpcConstants.HASH + RpcConstants.HASH
-                      + RpcConstants.NEW_LINE)
+                //message = (RpcMessageUtils.NEW_LINE + RpcMessageUtils.HASH + message.getBytes(UTF_8).size + RpcMessageUtils.NEW_LINE + message +RpcMessageUtils. NEW_LINE + RpcMessageUtils.HASH + RpcMessageUtils.HASH
+                //       + RpcMessageUtils.NEW_LINE)
+                message =
+                    (RpcMessageUtils.NEW_LINE + RpcMessageUtils.HASH + message.toByteArray(UTF_8).size + RpcMessageUtils.NEW_LINE + message + RpcMessageUtils.NEW_LINE + RpcMessageUtils.HASH + RpcMessageUtils.HASH
+                            + RpcMessageUtils.NEW_LINE)
             }
             return message
         }
@@ -312,11 +321,13 @@ class RpcMessageUtils {
          */
         fun formatXmlHeader(request: String): String {
             var request = request
-            if (!request.contains(RpcConstants.XML_HEADER)) {
-                if (request.startsWith(RpcConstants.NEW_LINE + RpcConstants.HASH)) {
-                    request = request.split("<".toRegex()).dropLastWhile { it.isEmpty() }.toTypedArray()[0] + RpcConstants.XML_HEADER + request.substring(request.split("<".toRegex()).dropLastWhile { it.isEmpty() }.toTypedArray()[0].length)
+            if (!request.contains(RpcMessageUtils.XML_HEADER)) {
+                if (request.startsWith(RpcMessageUtils.NEW_LINE + RpcMessageUtils.HASH)) {
+                    request =
+                        request.split("<".toRegex()).dropLastWhile { it.isEmpty() }.toTypedArray()[0] + RpcMessageUtils.XML_HEADER + request.substring(
+                            request.split("<".toRegex()).dropLastWhile { it.isEmpty() }.toTypedArray()[0].length)
                 } else {
-                    request = RpcConstants.XML_HEADER + "\n" + request
+                    request = RpcMessageUtils.XML_HEADER + "\n" + request
                 }
             }
             return request
@@ -324,23 +335,32 @@ class RpcMessageUtils {
 
         fun formatRequestMessageId(request: String, messageId: String): String {
             var request = request
-            if (request.contains(RpcConstants.MESSAGE_ID_STRING)) {
-                request = request.replaceFirst((RpcConstants.MESSAGE_ID_STRING + RpcConstants.EQUAL + RpcConstants.NUMBER_BETWEEN_QUOTES_MATCHER).toRegex(), RpcConstants.MESSAGE_ID_STRING +RpcConstants. EQUAL + RpcConstants.QUOTE + messageId + RpcConstants.QUOTE)
-            } else if (!request.contains(RpcConstants.MESSAGE_ID_STRING) && !request.contains(RpcConstants.HELLO)) {
-                request = request.replaceFirst(RpcConstants.END_OF_RPC_OPEN_TAG.toRegex(), RpcConstants.QUOTE_SPACE + RpcConstants.MESSAGE_ID_STRING + RpcConstants.EQUAL + RpcConstants.QUOTE + messageId + RpcConstants.QUOTE + ">")
+            if (request.contains(RpcMessageUtils.MESSAGE_ID_STRING)) {
+                request =
+                    request.replaceFirst((RpcMessageUtils.MESSAGE_ID_STRING + RpcMessageUtils.EQUAL + RpcMessageUtils.NUMBER_BETWEEN_QUOTES_MATCHER).toRegex(),
+                        RpcMessageUtils.MESSAGE_ID_STRING + RpcMessageUtils.EQUAL + RpcMessageUtils.QUOTE + messageId + RpcMessageUtils.QUOTE)
+            } else if (!request.contains(RpcMessageUtils.MESSAGE_ID_STRING) && !request.contains(
+                    RpcMessageUtils.HELLO)) {
+                request = request.replaceFirst(RpcMessageUtils.END_OF_RPC_OPEN_TAG.toRegex(),
+                    RpcMessageUtils.QUOTE_SPACE + RpcMessageUtils.MESSAGE_ID_STRING + RpcMessageUtils.EQUAL + RpcMessageUtils.QUOTE + messageId + RpcMessageUtils.QUOTE + ">")
             }
             return updateRequestLength(request)
         }
 
         fun updateRequestLength(request: String): String {
-            if (request.contains(NEW_LINE + RpcConstants.HASH + RpcConstants.HASH + NEW_LINE)) {
-                val oldLen = Integer.parseInt(request.split(RpcConstants.HASH.toRegex()).dropLastWhile({ it.isEmpty() }).toTypedArray()[1].split(NEW_LINE.toRegex()).dropLastWhile({ it.isEmpty() }).toTypedArray()[0])
+            if (request.contains(NEW_LINE + RpcMessageUtils.HASH + RpcMessageUtils.HASH + NEW_LINE)) {
+                val oldLen =
+                    Integer.parseInt(request.split(RpcMessageUtils.HASH.toRegex()).dropLastWhile({ it.isEmpty() }).toTypedArray()[1].split(
+                        NEW_LINE.toRegex()).dropLastWhile({ it.isEmpty() }).toTypedArray()[0])
                 val rpcWithEnding = request.substring(request.indexOf('<'))
-                val firstBlock = request.split(RpcConstants.MSGLEN_REGEX_PATTERN.toRegex()).dropLastWhile({ it.isEmpty() }).toTypedArray()[1].split((NEW_LINE + RpcConstants.HASH +RpcConstants. HASH + NEW_LINE).toRegex()).dropLastWhile({ it.isEmpty() }).toTypedArray()[0]
+                val firstBlock =
+                    request.split(RpcMessageUtils.MSGLEN_REGEX_PATTERN.toRegex()).dropLastWhile({ it.isEmpty() }).toTypedArray()[1].split(
+                        (NEW_LINE + RpcMessageUtils.HASH + RpcMessageUtils.HASH + NEW_LINE).toRegex()).dropLastWhile(
+                        { it.isEmpty() }).toTypedArray()[0]
                 var newLen = 0
                 newLen = firstBlock.toByteArray(UTF_8).size
                 if (oldLen != newLen) {
-                    return NEW_LINE + RpcConstants.HASH + newLen + NEW_LINE + rpcWithEnding
+                    return NEW_LINE + RpcMessageUtils.HASH + newLen + NEW_LINE + rpcWithEnding
                 }
             }
             return request
@@ -348,11 +368,9 @@ class RpcMessageUtils {
 
         fun checkReply(reply: String?): Boolean {
             return if (reply != null) {
-                !reply.contains("<rpc-error>") || reply.contains("warning") || reply.contains("<ok/>")
+                !reply.contains("rpc-error>") || reply.contains("warning") || reply.contains("ok/>")
             } else false
         }
-
-
     }
 
 }
\ No newline at end of file
diff --git a/ms/blueprintsprocessor/functions/netconf-executor/src/main/kotlin/org/onap/ccsdk/apps/blueprintsprocessor/functions/netconf/executor/utils/RpcConstants.kt b/ms/blueprintsprocessor/functions/netconf-executor/src/main/kotlin/org/onap/ccsdk/apps/blueprintsprocessor/functions/netconf/executor/utils/RpcConstants.kt
deleted file mode 100644 (file)
index 25715c9..0000000
+++ /dev/null
@@ -1,82 +0,0 @@
-/*
- * Copyright © 2017-2018 AT&T Intellectual Property.
- *
- * 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.ccsdk.apps.blueprintsprocessor.functions.netconf.executor.utils
-
-import java.util.regex.Pattern;
- class RpcConstants {
-     companion object {
-         const  val OPEN = "<"
-         const val CLOSE = ">"
-         const val EQUAL = "="
-
-         const val HASH = "#"
-         const val HASH_CHAR = '#'
-
-         const val LF_CHAR = '\n'
-         const val NEW_LINE = "\n"
-
-         const val QUOTE = "\""
-         const val QUOTE_SPACE = "\" "
-
-         const val TAG_CLOSE = "/>"
-         const val END_OF_RPC_OPEN_TAG = "\">"
-         const val END_PATTERN = "]]>]]>"
-
-         const val HELLO = "hello"
-         const val RPC_REPLY = "rpc-reply"
-         const val RPC_ERROR = "rpc-error"
-
-         const val RPC_OPEN = "<rpc "
-         const val RPC_CLOSE = "</rpc>"
-         const val WITH_DEFAULT_OPEN = "<with-defaults "
-         const val WITH_DEFAULT_CLOSE = "</with-defaults>"
-         const val DEFAULT_OPERATION_OPEN = "<default-operation>"
-         const val DEFAULT_OPERATION_CLOSE = "</default-operation>"
-         const val SUBTREE_FILTER_OPEN = "<filter type=\"subtree\">"
-         const val SUBTREE_FILTER_CLOSE = "</filter>"
-         const val TARGET_OPEN = "<target>"
-         const val TARGET_CLOSE = "</target>"
-         const val SOURCE_OPEN = "<source>"
-         const val SOURCE_CLOSE = "</source>"
-         const val CONFIG_OPEN = "<config xmlns:nc=\"urn:ietf:params:xml:ns:netconf:base:1.0\">"
-         const val CONFIG_CLOSE = "</config>"
-         const val MSGLEN_REGEX_PATTERN = "\n#\\d+\n"
-
-
-         const val NUMBER_BETWEEN_QUOTES_MATCHER = "\"+([0-9]+)+\""
-
-         const val XML_HEADER = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>"
-         const val NETCONF_BASE_NAMESPACE = "xmlns=\"urn:ietf:params:xml:ns:netconf:base:1.0\""
-         const val NETCONF_WITH_DEFAULTS_NAMESPACE = "xmlns=\"urn:ietf:params:xml:ns:yang:ietf-netconf-with-defaults\""
-         const val SUBSCRIPTION_SUBTREE_FILTER_OPEN = "<filter xmlns:base10=\"urn:ietf:params:xml:ns:netconf:base:1.0\" base10:type=\"subtree\">"
-
-         const val INTERLEAVE_CAPABILITY_STRING = "urn:ietf:params:netconf:capability:interleave:1.0"
-
-         const val CAPABILITY_REGEX = "capability>\\s*(.*?)\\s*capability>"
-
-
-         const val SESSION_ID_REGEX = "session-id>\\s*(.*?)\\s*session-id>"
-
-
-         const val MESSAGE_ID_STRING = "message-id"
-
-
-         const val NETCONF_10_CAPABILITY = "urn:ietf:params:netconf:base:1.0"
-         const val NETCONF_11_CAPABILITY = "urn:ietf:params:netconf:base:1.1"
-
-
-     }
-}
\ No newline at end of file
index d6f737f..7b31610 100644 (file)
@@ -35,8 +35,7 @@ import org.springframework.test.context.TestPropertySource
 import org.springframework.test.context.junit4.SpringRunner
 
 @RunWith(SpringRunner::class)
-@ContextConfiguration(classes = [NetconfExecutorConfiguration::class, BlueprintJythonService::class,
-    PythonExecutorProperty::class])
+@ContextConfiguration(classes = [BlueprintJythonService::class, PythonExecutorProperty::class, ComponentNetconfExecutor::class, JsonParserService::class])
 @TestPropertySource(properties =
 ["blueprints.processor.functions.python.executor.modulePaths=./../../../../components/scripts/python/ccsdk_netconf,./../../../../components/scripts/python/ccsdk_blueprints",
     "blueprints.processor.functions.python.executor.executionPath=./../../../../components/scripts/python/ccsdk_netconf"])
@@ -50,10 +49,10 @@ class ComponentNetconfExecutorTest {
     fun testComponentNetconfExecutor() {
 
         val executionServiceInput = JacksonUtils.readValueFromClassPathFile("requests/sample-activate-request.json",
-                ExecutionServiceInput::class.java)!!
+            ExecutionServiceInput::class.java)!!
 
         val bluePrintRuntimeService = BluePrintMetadataUtils.getBluePrintRuntime("1234",
-                "./../../../../components/model-catalog/blueprint-model/test-blueprint/baseconfiguration")
+            "./../../../../components/model-catalog/blueprint-model/test-blueprint/baseconfiguration")
 
         val executionContext = bluePrintRuntimeService.getExecutionContext()
 
@@ -63,7 +62,7 @@ class ComponentNetconfExecutorTest {
 
         val stepMetaData: MutableMap<String, JsonNode> = hashMapOf()
         stepMetaData.putJsonElement(BluePrintConstants.PROPERTY_CURRENT_NODE_TEMPLATE, "activate-netconf")
-        stepMetaData.putJsonElement(BluePrintConstants.PROPERTY_CURRENT_INTERFACE, "NetconfExecutorComponent")
+        stepMetaData.putJsonElement(BluePrintConstants.PROPERTY_CURRENT_INTERFACE, "ComponentNetconfExecutor")
         stepMetaData.putJsonElement(BluePrintConstants.PROPERTY_CURRENT_OPERATION, "process")
         // Set Step Inputs in Blueprint Runtime Service
         bluePrintRuntimeService.put("activate-netconf-step-inputs", stepMetaData.asJsonNode())
index 4ee48bc..045725c 100644 (file)
@@ -18,10 +18,10 @@ package org.onap.ccsdk.apps.blueprintsprocessor.functions.netconf.executor
 import org.junit.After
 import org.junit.Assert
 import org.junit.Before
+import org.onap.ccsdk.apps.blueprintsprocessor.functions.netconf.executor.api.DeviceInfo
+import org.onap.ccsdk.apps.blueprintsprocessor.functions.netconf.executor.core.NetconfRpcServiceImpl
 import org.onap.ccsdk.apps.blueprintsprocessor.functions.netconf.executor.core.NetconfSessionImpl
-import org.onap.ccsdk.apps.blueprintsprocessor.functions.netconf.executor.interfaces.DeviceInfo
-import org.onap.ccsdk.apps.blueprintsprocessor.functions.netconf.executor.utils.NetconfDeviceSimulator
-
+import org.onap.ccsdk.apps.blueprintsprocessor.functions.netconf.executor.mocks.NetconfDeviceSimulator
 
 class NetconfSessionImplTest {
 
@@ -31,11 +31,11 @@ class NetconfSessionImplTest {
     @Before
     fun before() {
         deviceInfo = DeviceInfo().apply {
-            name = "name"
-            pass = "password"
+            username = "username"
+            password = "password"
             ipAddress = "localhost"
             port = 2224
-            connectTimeoutSec = 10
+            connectTimeout = 10
         }
 
         device = NetconfDeviceSimulator(deviceInfo!!.port)
@@ -49,7 +49,7 @@ class NetconfSessionImplTest {
 
     @Throws(Exception::class)
     fun testNetconfSession() {
-        val netconfSession = NetconfSessionImpl(deviceInfo!!)
+        val netconfSession = NetconfSessionImpl(deviceInfo!!, NetconfRpcServiceImpl(DeviceInfo()))
 
         Assert.assertNotNull(netconfSession.getSessionId())
         Assert.assertEquals("localhost:2224", netconfSession.getDeviceInfo().toString())
index 6471df3..a2a3946 100644 (file)
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
-package org.onap.ccsdk.apps.blueprintsprocessor.functions.netconf.executor.utils
+package org.onap.ccsdk.apps.blueprintsprocessor.functions.netconf.executor.mocks
 
 
 import org.apache.sshd.common.NamedFactory
 import org.apache.sshd.server.Command
-import java.util.ArrayList
-import org.apache.sshd.server.auth.UserAuthNoneFactory
-import org.apache.sshd.server.keyprovider.SimpleGeneratorHostKeyProvider
 import org.apache.sshd.server.SshServer
 import org.apache.sshd.server.auth.UserAuth
+import org.apache.sshd.server.auth.UserAuthNoneFactory
+import org.apache.sshd.server.keyprovider.SimpleGeneratorHostKeyProvider
+import org.onap.ccsdk.apps.blueprintsprocessor.functions.netconf.executor.utils.NetconfSubsystemFactory
+import java.util.*
 
 
 class NetconfDeviceSimulator(private val port: Int) {
index 08a2e68..20b04fb 100644 (file)
 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.junit.Assert.*
-import org.springframework.beans.factory.annotation.Autowired
-
 class RpcMessageUtilsTest {
 
     @Test
@@ -34,9 +32,9 @@ class RpcMessageUtilsTest {
         val configType = "candidate"
         val filterContent = "Test-Filter-Content"
 
-        val result = RpcMessageUtils.getConfig(messageId, configType, filterContent).replace("[\n\r\t]".toRegex(), "")
+        val result = NetconfMessageUtils.getConfig(messageId, configType, filterContent).replace("[\n\r\t]".toRegex(), "")
 
-        assertTrue(RpcMessageUtils.validateRPCXML(result))
+        assertTrue(NetconfMessageUtils.validateRPCXML(result))
         Assert.assertEquals(checkString, result)
     }
 
@@ -53,9 +51,9 @@ class RpcMessageUtilsTest {
         val configType = "candidate"
         val filterContent = "Test-Filter-Content"
 
-        val result = RpcMessageUtils.getConfig(messageId, configType, filterContent).replace("[\n\r\t]".toRegex(), "")
+        val result = NetconfMessageUtils.getConfig(messageId, configType, filterContent).replace("[\n\r\t]".toRegex(), "")
 
-        assertTrue(RpcMessageUtils.validateRPCXML(result))
+        assertTrue(NetconfMessageUtils.validateRPCXML(result))
         Assert.assertEquals(checkString, result)
     }
 
@@ -68,9 +66,9 @@ class RpcMessageUtilsTest {
         val messageId = "Test-Message-ID"
         val configType = "candidate"
 
-        val result = RpcMessageUtils.validate(messageId, configType).replace("[\n\r\t]".toRegex(), "")
+        val result = NetconfMessageUtils.validate(messageId, configType).replace("[\n\r\t]".toRegex(), "")
 
-        assertTrue(RpcMessageUtils.validateRPCXML(result))
+        assertTrue(NetconfMessageUtils.validateRPCXML(result))
         Assert.assertEquals(checkString, result)
     }
 
@@ -81,11 +79,10 @@ class RpcMessageUtilsTest {
                 + "<commit></commit></rpc>")
 
         val messageId = "Test-Message-ID"
-        val message = "Test-Message"
 
-        val result = RpcMessageUtils.commit(messageId, message).replace("[\n\r\t]".toRegex(), "")
+        val result = NetconfMessageUtils.commit(messageId).replace("[\n\r\t]".toRegex(), "")
 
-        assertTrue(RpcMessageUtils.validateRPCXML(result))
+        assertTrue(NetconfMessageUtils.validateRPCXML(result))
         Assert.assertEquals(checkString, result)
 
     }
@@ -99,9 +96,9 @@ class RpcMessageUtilsTest {
         val messageId = "Test-Message-ID"
         val configType = "candidate"
 
-        val result = RpcMessageUtils.unlock(messageId, configType).replace("[\n\r\t]".toRegex(), "")
+        val result = NetconfMessageUtils.unlock(messageId, configType).replace("[\n\r\t]".toRegex(), "")
 
-        assertTrue(RpcMessageUtils.validateRPCXML(result))
+        assertTrue(NetconfMessageUtils.validateRPCXML(result))
         Assert.assertEquals(checkString, result)
     }
 
@@ -114,9 +111,9 @@ class RpcMessageUtilsTest {
         val messageId = "Test-Message-ID"
         val netconfTargetConfig = "candidate"
 
-        val result = RpcMessageUtils.deleteConfig(messageId, netconfTargetConfig).replace("[\n\r\t]".toRegex(), "")
+        val result = NetconfMessageUtils.deleteConfig(messageId, netconfTargetConfig).replace("[\n\r\t]".toRegex(), "")
 
-        assertTrue(RpcMessageUtils.validateRPCXML(result))
+        assertTrue(NetconfMessageUtils.validateRPCXML(result))
         Assert.assertEquals(checkString, result)
     }
 
@@ -128,9 +125,9 @@ class RpcMessageUtilsTest {
 
         val messageId = "Test-Message-ID"
 
-        val result = RpcMessageUtils.discardChanges(messageId).replace("[\n\r\t]".toRegex(), "")
+        val result = NetconfMessageUtils.discardChanges(messageId).replace("[\n\r\t]".toRegex(), "")
 
-        assertTrue(RpcMessageUtils.validateRPCXML(result))
+        assertTrue(NetconfMessageUtils.validateRPCXML(result))
         Assert.assertEquals(checkString, result)
     }
 
@@ -142,9 +139,9 @@ class RpcMessageUtilsTest {
 
         val messageId = "Test-Message-ID"
         val configType = "candidate"
-        val result = RpcMessageUtils.lock(messageId, configType).replace("[\n\r\t]".toRegex(), "")
+        val result = NetconfMessageUtils.lock(messageId, configType).replace("[\n\r\t]".toRegex(), "")
 
-        assertTrue(RpcMessageUtils.validateRPCXML(result))
+        assertTrue(NetconfMessageUtils.validateRPCXML(result))
         Assert.assertEquals(checkString, result)
     }