summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rwxr-xr-xms/blueprintsprocessor/application/pom.xml4
-rwxr-xr-xms/blueprintsprocessor/application/src/main/resources/application.properties7
-rwxr-xr-xms/blueprintsprocessor/distribution/pom.xml2
-rw-r--r--ms/blueprintsprocessor/functions/netconf-executor/src/main/kotlin/org/onap/ccsdk/apps/blueprintsprocessor/functions/netconf/executor/ComponentNetconfExecutor.kt2
-rw-r--r--ms/blueprintsprocessor/functions/netconf-executor/src/main/kotlin/org/onap/ccsdk/apps/blueprintsprocessor/functions/netconf/executor/NetconfComponentFunction.kt46
-rw-r--r--ms/blueprintsprocessor/functions/netconf-executor/src/main/kotlin/org/onap/ccsdk/apps/blueprintsprocessor/functions/netconf/executor/NetconfDevice.kt32
-rw-r--r--ms/blueprintsprocessor/functions/netconf-executor/src/main/kotlin/org/onap/ccsdk/apps/blueprintsprocessor/functions/netconf/executor/NetconfException.kt45
-rw-r--r--ms/blueprintsprocessor/functions/netconf-executor/src/main/kotlin/org/onap/ccsdk/apps/blueprintsprocessor/functions/netconf/executor/NetconfExecutorConfiguration.kt68
-rw-r--r--ms/blueprintsprocessor/functions/netconf-executor/src/main/kotlin/org/onap/ccsdk/apps/blueprintsprocessor/functions/netconf/executor/NetconfRpcService.kt375
-rw-r--r--ms/blueprintsprocessor/functions/netconf-executor/src/main/kotlin/org/onap/ccsdk/apps/blueprintsprocessor/functions/netconf/executor/api/DeviceInfo.kt (renamed from ms/blueprintsprocessor/functions/netconf-executor/src/main/kotlin/org/onap/ccsdk/apps/blueprintsprocessor/functions/netconf/executor/interfaces/DeviceInfo.kt)22
-rw-r--r--ms/blueprintsprocessor/functions/netconf-executor/src/main/kotlin/org/onap/ccsdk/apps/blueprintsprocessor/functions/netconf/executor/api/NetconfException.kt (renamed from ms/blueprintsprocessor/functions/netconf-executor/src/main/kotlin/org/onap/ccsdk/apps/blueprintsprocessor/functions/netconf/executor/data/NetconfSshClientLib.kt)14
-rw-r--r--ms/blueprintsprocessor/functions/netconf-executor/src/main/kotlin/org/onap/ccsdk/apps/blueprintsprocessor/functions/netconf/executor/api/NetconfMessage.kt74
-rw-r--r--ms/blueprintsprocessor/functions/netconf-executor/src/main/kotlin/org/onap/ccsdk/apps/blueprintsprocessor/functions/netconf/executor/api/NetconfRpcService.kt (renamed from ms/blueprintsprocessor/functions/netconf-executor/src/main/kotlin/org/onap/ccsdk/apps/blueprintsprocessor/functions/netconf/executor/interfaces/NetconfRpcClientService.kt)50
-rw-r--r--ms/blueprintsprocessor/functions/netconf-executor/src/main/kotlin/org/onap/ccsdk/apps/blueprintsprocessor/functions/netconf/executor/api/NetconfSession.kt86
-rw-r--r--ms/blueprintsprocessor/functions/netconf-executor/src/main/kotlin/org/onap/ccsdk/apps/blueprintsprocessor/functions/netconf/executor/api/NetconfSessionListener.kt (renamed from ms/blueprintsprocessor/functions/netconf-executor/src/main/kotlin/org/onap/ccsdk/apps/blueprintsprocessor/functions/netconf/executor/interfaces/NetconfSessionDelegate.java)10
-rw-r--r--ms/blueprintsprocessor/functions/netconf-executor/src/main/kotlin/org/onap/ccsdk/apps/blueprintsprocessor/functions/netconf/executor/core/NetconfDeviceCommunicator.kt (renamed from ms/blueprintsprocessor/functions/netconf-executor/src/main/kotlin/org/onap/ccsdk/apps/blueprintsprocessor/functions/netconf/executor/core/NetconfStreamThread.kt)148
-rw-r--r--ms/blueprintsprocessor/functions/netconf-executor/src/main/kotlin/org/onap/ccsdk/apps/blueprintsprocessor/functions/netconf/executor/core/NetconfRpcServiceImpl.kt265
-rw-r--r--ms/blueprintsprocessor/functions/netconf-executor/src/main/kotlin/org/onap/ccsdk/apps/blueprintsprocessor/functions/netconf/executor/core/NetconfSessionFactory.kt50
-rw-r--r--ms/blueprintsprocessor/functions/netconf-executor/src/main/kotlin/org/onap/ccsdk/apps/blueprintsprocessor/functions/netconf/executor/core/NetconfSessionImpl.kt371
-rw-r--r--ms/blueprintsprocessor/functions/netconf-executor/src/main/kotlin/org/onap/ccsdk/apps/blueprintsprocessor/functions/netconf/executor/data/NetconfAdaptorConstant.kt43
-rw-r--r--ms/blueprintsprocessor/functions/netconf-executor/src/main/kotlin/org/onap/ccsdk/apps/blueprintsprocessor/functions/netconf/executor/data/NetconfExecutionData.kt122
-rw-r--r--ms/blueprintsprocessor/functions/netconf-executor/src/main/kotlin/org/onap/ccsdk/apps/blueprintsprocessor/functions/netconf/executor/interfaces/NetconfSession.kt110
-rw-r--r--ms/blueprintsprocessor/functions/netconf-executor/src/main/kotlin/org/onap/ccsdk/apps/blueprintsprocessor/functions/netconf/executor/utils/NetconfConstant.kt84
-rw-r--r--ms/blueprintsprocessor/functions/netconf-executor/src/main/kotlin/org/onap/ccsdk/apps/blueprintsprocessor/functions/netconf/executor/utils/NetconfMessageUtils.kt (renamed from ms/blueprintsprocessor/functions/netconf-executor/src/main/kotlin/org/onap/ccsdk/apps/blueprintsprocessor/functions/netconf/executor/utils/RpcMessageUtils.kt)218
-rw-r--r--ms/blueprintsprocessor/functions/netconf-executor/src/main/kotlin/org/onap/ccsdk/apps/blueprintsprocessor/functions/netconf/executor/utils/RpcConstants.kt82
-rw-r--r--ms/blueprintsprocessor/functions/netconf-executor/src/test/kotlin/org/onap/ccsdk/apps/blueprintsprocessor/functions/netconf/executor/ComponentNetconfExecutorTest.kt9
-rw-r--r--ms/blueprintsprocessor/functions/netconf-executor/src/test/kotlin/org/onap/ccsdk/apps/blueprintsprocessor/functions/netconf/executor/NetconfSessionImplTest.kt14
-rw-r--r--ms/blueprintsprocessor/functions/netconf-executor/src/test/kotlin/org/onap/ccsdk/apps/blueprintsprocessor/functions/netconf/executor/mocks/NetconfDeviceSimulator.kt9
-rw-r--r--ms/blueprintsprocessor/functions/netconf-executor/src/test/kotlin/org/onap/ccsdk/apps/blueprintsprocessor/functions/netconf/executor/utils/RpcMessageUtilsTest.kt37
29 files changed, 1010 insertions, 1389 deletions
diff --git a/ms/blueprintsprocessor/application/pom.xml b/ms/blueprintsprocessor/application/pom.xml
index b02e9e982..83dc7061f 100755
--- a/ms/blueprintsprocessor/application/pom.xml
+++ b/ms/blueprintsprocessor/application/pom.xml
@@ -50,6 +50,10 @@
<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>
</dependency>
diff --git a/ms/blueprintsprocessor/application/src/main/resources/application.properties b/ms/blueprintsprocessor/application/src/main/resources/application.properties
index e5c928d2f..cfef4f82f 100755
--- a/ms/blueprintsprocessor/application/src/main/resources/application.properties
+++ b/ms/blueprintsprocessor/application/src/main/resources/application.properties
@@ -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
diff --git a/ms/blueprintsprocessor/distribution/pom.xml b/ms/blueprintsprocessor/distribution/pom.xml
index b3eabc109..97d4271d2 100755
--- a/ms/blueprintsprocessor/distribution/pom.xml
+++ b/ms/blueprintsprocessor/distribution/pom.xml
@@ -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>
diff --git a/ms/blueprintsprocessor/functions/netconf-executor/src/main/kotlin/org/onap/ccsdk/apps/blueprintsprocessor/functions/netconf/executor/ComponentNetconfExecutor.kt b/ms/blueprintsprocessor/functions/netconf-executor/src/main/kotlin/org/onap/ccsdk/apps/blueprintsprocessor/functions/netconf/executor/ComponentNetconfExecutor.kt
index ab3372e96..c32aa9d51 100644
--- a/ms/blueprintsprocessor/functions/netconf-executor/src/main/kotlin/org/onap/ccsdk/apps/blueprintsprocessor/functions/netconf/executor/ComponentNetconfExecutor.kt
+++ b/ms/blueprintsprocessor/functions/netconf-executor/src/main/kotlin/org/onap/ccsdk/apps/blueprintsprocessor/functions/netconf/executor/ComponentNetconfExecutor.kt
@@ -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" }
diff --git a/ms/blueprintsprocessor/functions/netconf-executor/src/main/kotlin/org/onap/ccsdk/apps/blueprintsprocessor/functions/netconf/executor/NetconfComponentFunction.kt b/ms/blueprintsprocessor/functions/netconf-executor/src/main/kotlin/org/onap/ccsdk/apps/blueprintsprocessor/functions/netconf/executor/NetconfComponentFunction.kt
index d480bdd42..c98009fe6 100644
--- a/ms/blueprintsprocessor/functions/netconf-executor/src/main/kotlin/org/onap/ccsdk/apps/blueprintsprocessor/functions/netconf/executor/NetconfComponentFunction.kt
+++ b/ms/blueprintsprocessor/functions/netconf-executor/src/main/kotlin/org/onap/ccsdk/apps/blueprintsprocessor/functions/netconf/executor/NetconfComponentFunction.kt
@@ -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.
@@ -17,47 +17,39 @@
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
index 000000000..547766211
--- /dev/null
+++ b/ms/blueprintsprocessor/functions/netconf-executor/src/main/kotlin/org/onap/ccsdk/apps/blueprintsprocessor/functions/netconf/executor/NetconfDevice.kt
@@ -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
index 37aa63da2..000000000
--- a/ms/blueprintsprocessor/functions/netconf-executor/src/main/kotlin/org/onap/ccsdk/apps/blueprintsprocessor/functions/netconf/executor/NetconfException.kt
+++ /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
index 562dd7689..000000000
--- a/ms/blueprintsprocessor/functions/netconf-executor/src/main/kotlin/org/onap/ccsdk/apps/blueprintsprocessor/functions/netconf/executor/NetconfExecutorConfiguration.kt
+++ /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
index 0e264bcb9..000000000
--- a/ms/blueprintsprocessor/functions/netconf-executor/src/main/kotlin/org/onap/ccsdk/apps/blueprintsprocessor/functions/netconf/executor/NetconfRpcService.kt
+++ /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
diff --git a/ms/blueprintsprocessor/functions/netconf-executor/src/main/kotlin/org/onap/ccsdk/apps/blueprintsprocessor/functions/netconf/executor/interfaces/DeviceInfo.kt b/ms/blueprintsprocessor/functions/netconf-executor/src/main/kotlin/org/onap/ccsdk/apps/blueprintsprocessor/functions/netconf/executor/api/DeviceInfo.kt
index f4360c7e6..466e6b5ed 100644
--- a/ms/blueprintsprocessor/functions/netconf-executor/src/main/kotlin/org/onap/ccsdk/apps/blueprintsprocessor/functions/netconf/executor/interfaces/DeviceInfo.kt
+++ b/ms/blueprintsprocessor/functions/netconf-executor/src/main/kotlin/org/onap/ccsdk/apps/blueprintsprocessor/functions/netconf/executor/api/DeviceInfo.kt
@@ -14,30 +14,30 @@
* 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
diff --git a/ms/blueprintsprocessor/functions/netconf-executor/src/main/kotlin/org/onap/ccsdk/apps/blueprintsprocessor/functions/netconf/executor/data/NetconfSshClientLib.kt b/ms/blueprintsprocessor/functions/netconf-executor/src/main/kotlin/org/onap/ccsdk/apps/blueprintsprocessor/functions/netconf/executor/api/NetconfException.kt
index f21cce4a7..d7642e75f 100644
--- a/ms/blueprintsprocessor/functions/netconf-executor/src/main/kotlin/org/onap/ccsdk/apps/blueprintsprocessor/functions/netconf/executor/data/NetconfSshClientLib.kt
+++ b/ms/blueprintsprocessor/functions/netconf-executor/src/main/kotlin/org/onap/ccsdk/apps/blueprintsprocessor/functions/netconf/executor/api/NetconfException.kt
@@ -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.
@@ -13,14 +13,12 @@
* 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
index 000000000..da7466143
--- /dev/null
+++ b/ms/blueprintsprocessor/functions/netconf-executor/src/main/kotlin/org/onap/ccsdk/apps/blueprintsprocessor/functions/netconf/executor/api/NetconfMessage.kt
@@ -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
diff --git a/ms/blueprintsprocessor/functions/netconf-executor/src/main/kotlin/org/onap/ccsdk/apps/blueprintsprocessor/functions/netconf/executor/interfaces/NetconfRpcClientService.kt b/ms/blueprintsprocessor/functions/netconf-executor/src/main/kotlin/org/onap/ccsdk/apps/blueprintsprocessor/functions/netconf/executor/api/NetconfRpcService.kt
index 668fb552f..554368c7e 100644
--- a/ms/blueprintsprocessor/functions/netconf-executor/src/main/kotlin/org/onap/ccsdk/apps/blueprintsprocessor/functions/netconf/executor/interfaces/NetconfRpcClientService.kt
+++ b/ms/blueprintsprocessor/functions/netconf-executor/src/main/kotlin/org/onap/ccsdk/apps/blueprintsprocessor/functions/netconf/executor/api/NetconfRpcService.kt
@@ -13,42 +13,31 @@
* 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
index 000000000..6a655d91f
--- /dev/null
+++ b/ms/blueprintsprocessor/functions/netconf-executor/src/main/kotlin/org/onap/ccsdk/apps/blueprintsprocessor/functions/netconf/executor/api/NetconfSession.kt
@@ -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
diff --git a/ms/blueprintsprocessor/functions/netconf-executor/src/main/kotlin/org/onap/ccsdk/apps/blueprintsprocessor/functions/netconf/executor/interfaces/NetconfSessionDelegate.java b/ms/blueprintsprocessor/functions/netconf-executor/src/main/kotlin/org/onap/ccsdk/apps/blueprintsprocessor/functions/netconf/executor/api/NetconfSessionListener.kt
index 479558043..8854894fa 100644
--- a/ms/blueprintsprocessor/functions/netconf-executor/src/main/kotlin/org/onap/ccsdk/apps/blueprintsprocessor/functions/netconf/executor/interfaces/NetconfSessionDelegate.java
+++ b/ms/blueprintsprocessor/functions/netconf-executor/src/main/kotlin/org/onap/ccsdk/apps/blueprintsprocessor/functions/netconf/executor/api/NetconfSessionListener.kt
@@ -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.
@@ -13,11 +13,9 @@
* 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)
}
diff --git a/ms/blueprintsprocessor/functions/netconf-executor/src/main/kotlin/org/onap/ccsdk/apps/blueprintsprocessor/functions/netconf/executor/core/NetconfStreamThread.kt b/ms/blueprintsprocessor/functions/netconf-executor/src/main/kotlin/org/onap/ccsdk/apps/blueprintsprocessor/functions/netconf/executor/core/NetconfDeviceCommunicator.kt
index cfcf24bb1..694756195 100644
--- a/ms/blueprintsprocessor/functions/netconf-executor/src/main/kotlin/org/onap/ccsdk/apps/blueprintsprocessor/functions/netconf/executor/core/NetconfStreamThread.kt
+++ b/ms/blueprintsprocessor/functions/netconf-executor/src/main/kotlin/org/onap/ccsdk/apps/blueprintsprocessor/functions/netconf/executor/core/NetconfDeviceCommunicator.kt
@@ -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.
@@ -16,26 +16,33 @@
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
index 000000000..5c633a5b9
--- /dev/null
+++ b/ms/blueprintsprocessor/functions/netconf-executor/src/main/kotlin/org/onap/ccsdk/apps/blueprintsprocessor/functions/netconf/executor/core/NetconfRpcServiceImpl.kt
@@ -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
index 370ea7a50..000000000
--- a/ms/blueprintsprocessor/functions/netconf-executor/src/main/kotlin/org/onap/ccsdk/apps/blueprintsprocessor/functions/netconf/executor/core/NetconfSessionFactory.kt
+++ /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
diff --git a/ms/blueprintsprocessor/functions/netconf-executor/src/main/kotlin/org/onap/ccsdk/apps/blueprintsprocessor/functions/netconf/executor/core/NetconfSessionImpl.kt b/ms/blueprintsprocessor/functions/netconf-executor/src/main/kotlin/org/onap/ccsdk/apps/blueprintsprocessor/functions/netconf/executor/core/NetconfSessionImpl.kt
index 34c01813a..21570a235 100644
--- a/ms/blueprintsprocessor/functions/netconf-executor/src/main/kotlin/org/onap/ccsdk/apps/blueprintsprocessor/functions/netconf/executor/core/NetconfSessionImpl.kt
+++ b/ms/blueprintsprocessor/functions/netconf-executor/src/main/kotlin/org/onap/ccsdk/apps/blueprintsprocessor/functions/netconf/executor/core/NetconfSessionImpl.kt
@@ -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
index d49c99153..000000000
--- a/ms/blueprintsprocessor/functions/netconf-executor/src/main/kotlin/org/onap/ccsdk/apps/blueprintsprocessor/functions/netconf/executor/data/NetconfAdaptorConstant.kt
+++ /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
index f66c14a59..000000000
--- a/ms/blueprintsprocessor/functions/netconf-executor/src/main/kotlin/org/onap/ccsdk/apps/blueprintsprocessor/functions/netconf/executor/data/NetconfExecutionData.kt
+++ /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
index 8e16ab737..000000000
--- a/ms/blueprintsprocessor/functions/netconf-executor/src/main/kotlin/org/onap/ccsdk/apps/blueprintsprocessor/functions/netconf/executor/interfaces/NetconfSession.kt
+++ /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
index 000000000..e0cbde532
--- /dev/null
+++ b/ms/blueprintsprocessor/functions/netconf-executor/src/main/kotlin/org/onap/ccsdk/apps/blueprintsprocessor/functions/netconf/executor/utils/NetconfConstant.kt
@@ -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
diff --git a/ms/blueprintsprocessor/functions/netconf-executor/src/main/kotlin/org/onap/ccsdk/apps/blueprintsprocessor/functions/netconf/executor/utils/RpcMessageUtils.kt b/ms/blueprintsprocessor/functions/netconf-executor/src/main/kotlin/org/onap/ccsdk/apps/blueprintsprocessor/functions/netconf/executor/utils/NetconfMessageUtils.kt
index 28e1361ca..b0310d786 100644
--- a/ms/blueprintsprocessor/functions/netconf-executor/src/main/kotlin/org/onap/ccsdk/apps/blueprintsprocessor/functions/netconf/executor/utils/RpcMessageUtils.kt
+++ b/ms/blueprintsprocessor/functions/netconf-executor/src/main/kotlin/org/onap/ccsdk/apps/blueprintsprocessor/functions/netconf/executor/utils/NetconfMessageUtils.kt
@@ -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.
@@ -16,47 +16,47 @@
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
index 25715c9c8..000000000
--- a/ms/blueprintsprocessor/functions/netconf-executor/src/main/kotlin/org/onap/ccsdk/apps/blueprintsprocessor/functions/netconf/executor/utils/RpcConstants.kt
+++ /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
diff --git a/ms/blueprintsprocessor/functions/netconf-executor/src/test/kotlin/org/onap/ccsdk/apps/blueprintsprocessor/functions/netconf/executor/ComponentNetconfExecutorTest.kt b/ms/blueprintsprocessor/functions/netconf-executor/src/test/kotlin/org/onap/ccsdk/apps/blueprintsprocessor/functions/netconf/executor/ComponentNetconfExecutorTest.kt
index d6f737fdd..7b31610c2 100644
--- a/ms/blueprintsprocessor/functions/netconf-executor/src/test/kotlin/org/onap/ccsdk/apps/blueprintsprocessor/functions/netconf/executor/ComponentNetconfExecutorTest.kt
+++ b/ms/blueprintsprocessor/functions/netconf-executor/src/test/kotlin/org/onap/ccsdk/apps/blueprintsprocessor/functions/netconf/executor/ComponentNetconfExecutorTest.kt
@@ -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())
diff --git a/ms/blueprintsprocessor/functions/netconf-executor/src/test/kotlin/org/onap/ccsdk/apps/blueprintsprocessor/functions/netconf/executor/NetconfSessionImplTest.kt b/ms/blueprintsprocessor/functions/netconf-executor/src/test/kotlin/org/onap/ccsdk/apps/blueprintsprocessor/functions/netconf/executor/NetconfSessionImplTest.kt
index 4ee48bc82..045725c79 100644
--- a/ms/blueprintsprocessor/functions/netconf-executor/src/test/kotlin/org/onap/ccsdk/apps/blueprintsprocessor/functions/netconf/executor/NetconfSessionImplTest.kt
+++ b/ms/blueprintsprocessor/functions/netconf-executor/src/test/kotlin/org/onap/ccsdk/apps/blueprintsprocessor/functions/netconf/executor/NetconfSessionImplTest.kt
@@ -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())
diff --git a/ms/blueprintsprocessor/functions/netconf-executor/src/test/kotlin/org/onap/ccsdk/apps/blueprintsprocessor/functions/netconf/executor/mocks/NetconfDeviceSimulator.kt b/ms/blueprintsprocessor/functions/netconf-executor/src/test/kotlin/org/onap/ccsdk/apps/blueprintsprocessor/functions/netconf/executor/mocks/NetconfDeviceSimulator.kt
index 6471df3e6..a2a3946db 100644
--- a/ms/blueprintsprocessor/functions/netconf-executor/src/test/kotlin/org/onap/ccsdk/apps/blueprintsprocessor/functions/netconf/executor/mocks/NetconfDeviceSimulator.kt
+++ b/ms/blueprintsprocessor/functions/netconf-executor/src/test/kotlin/org/onap/ccsdk/apps/blueprintsprocessor/functions/netconf/executor/mocks/NetconfDeviceSimulator.kt
@@ -13,16 +13,17 @@
* 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) {
diff --git a/ms/blueprintsprocessor/functions/netconf-executor/src/test/kotlin/org/onap/ccsdk/apps/blueprintsprocessor/functions/netconf/executor/utils/RpcMessageUtilsTest.kt b/ms/blueprintsprocessor/functions/netconf-executor/src/test/kotlin/org/onap/ccsdk/apps/blueprintsprocessor/functions/netconf/executor/utils/RpcMessageUtilsTest.kt
index 08a2e686a..20b04fb5b 100644
--- a/ms/blueprintsprocessor/functions/netconf-executor/src/test/kotlin/org/onap/ccsdk/apps/blueprintsprocessor/functions/netconf/executor/utils/RpcMessageUtilsTest.kt
+++ b/ms/blueprintsprocessor/functions/netconf-executor/src/test/kotlin/org/onap/ccsdk/apps/blueprintsprocessor/functions/netconf/executor/utils/RpcMessageUtilsTest.kt
@@ -16,11 +16,9 @@
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)
}