2 * Copyright © 2017-2018 AT&T Intellectual Property.
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
8 * http://www.apache.org/licenses/LICENSE-2.0
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
17 package org.onap.ccsdk.apps.blueprintsprocessor.functions.netconf.executor
19 import com.fasterxml.jackson.databind.JsonNode
20 import com.google.common.base.Preconditions
21 import org.apache.commons.collections.CollectionUtils
22 import org.onap.ccsdk.apps.blueprintsprocessor.functions.netconf.executor.core.NetconfSessionFactory
23 import org.onap.ccsdk.apps.blueprintsprocessor.functions.netconf.executor.data.DeviceResponse
24 import org.onap.ccsdk.apps.blueprintsprocessor.functions.netconf.executor.data.NetconfAdaptorConstant
25 import org.onap.ccsdk.apps.blueprintsprocessor.functions.netconf.executor.interfaces.DeviceInfo
26 import org.onap.ccsdk.apps.blueprintsprocessor.functions.netconf.executor.interfaces.NetconfRpcClientService
27 import org.onap.ccsdk.apps.blueprintsprocessor.functions.netconf.executor.interfaces.NetconfSession
28 import org.onap.ccsdk.apps.blueprintsprocessor.functions.netconf.executor.utils.RpcMessageUtils
29 import org.onap.ccsdk.apps.controllerblueprints.core.utils.JacksonUtils
30 import org.slf4j.LoggerFactory
31 import org.springframework.beans.factory.config.ConfigurableBeanFactory
32 import org.springframework.context.annotation.Scope
33 import org.springframework.stereotype.Service
35 import java.util.concurrent.TimeUnit
38 @Service("netconf-rpc-service")
39 @Scope(value = ConfigurableBeanFactory.SCOPE_PROTOTYPE)
40 class NetconfRpcService : NetconfRpcClientService {
42 val log = LoggerFactory.getLogger(NetconfRpcService::class.java)
44 lateinit var deviceInfo: DeviceInfo
45 lateinit var netconfSession: NetconfSession
47 private val applyConfigIds = ArrayList<String>()
48 private val recordedApplyConfigIds = ArrayList<String>()
49 private val DEFAULT_MESSAGE_TIME_OUT = 30
51 @Throws(NetconfException::class)
52 fun NetconfRpcService(capabilityProperty: MutableMap<String, JsonNode> ) {
54 Preconditions.checkNotNull(capabilityProperty, "missing netconfDeviceInfo in netconf rpc client")
55 connect(getNetconfDeviceInfo(capabilityProperty))
56 log.info("NetconfRpcService initialised with deviceInfo {}", deviceInfo)
57 //configPersistService = ConfigPersistService(configResourceService)
59 } catch (e: NetconfException) {
60 publishMessage(String.format("Netconf Device Connection Failed, %s", e.message))
61 throw NetconfException("Netconf Device Connection Failed,$deviceInfo",e)
66 fun setdeviceInfo(deviceInfo: DeviceInfo) {
67 this.deviceInfo = deviceInfo
70 fun getNetconfDeviceInfo(capabilityProperty: MutableMap<String, JsonNode> ):DeviceInfo{
71 val netconfDeviceInfo = JacksonUtils.getInstanceFromMap(capabilityProperty, DeviceInfo::class.java)
72 this.deviceInfo = netconfDeviceInfo
73 return netconfDeviceInfo
76 fun connect(netconfDeviceInfo: DeviceInfo) {
77 log.info("in the connect method")
78 setdeviceInfo(netconfDeviceInfo)
79 netconfSession = NetconfSessionFactory.instance("DEFAULT_NETCONF_SESSION", netconfDeviceInfo)
80 publishMessage("Netconf Device Connection Established");
84 override fun disconnect() {
85 netconfSession.close()
88 override fun reconnect() {
93 override fun getConfig(messageId: String, messageContent: String, configTarget: String, messageTimeout: Int): DeviceResponse {
94 var output = DeviceResponse()
95 log.info("in the NetconfRpcService "+messageId)
97 val message = RpcMessageUtils.getConfig(messageId, configTarget, messageContent)
98 output = asyncRpc(message, messageId, messageTimeout)
99 } catch (e: Exception) {
100 output.status = NetconfAdaptorConstant.STATUS_FAILURE
101 output.errorMessage = e.message
107 override fun deleteConfig(messageId: String, configTarget: String, messageTimeout: Int): DeviceResponse {
108 var output = DeviceResponse()
110 val deleteConfigMessage = RpcMessageUtils.deleteConfig(messageId, configTarget)
111 output.requestMessage = deleteConfigMessage
112 output = asyncRpc(deleteConfigMessage, messageId, messageTimeout)
113 } catch (e: Exception) {
114 output.status = NetconfAdaptorConstant.STATUS_FAILURE
115 output.errorMessage = "failed in delete config command " + e.message
121 override fun lock(messageId: String, configTarget: String, messageTimeout: Int): DeviceResponse {
122 var output = DeviceResponse()
124 val lockMessage = RpcMessageUtils.lock(messageId, configTarget)
125 output.requestMessage = lockMessage
126 output = asyncRpc(lockMessage, messageId, messageTimeout)
127 } catch (e: Exception) {
128 output.status = NetconfAdaptorConstant.STATUS_FAILURE
129 output.errorMessage = "failed in lock command " + e.message
135 override fun unLock(messageId: String, configTarget: String, messageTimeout: Int): DeviceResponse {
136 var output = DeviceResponse()
138 val unlockMessage = RpcMessageUtils.unlock(messageId, configTarget)
139 output.requestMessage = unlockMessage
140 output = asyncRpc(unlockMessage, messageId, messageTimeout)
141 } catch (e: Exception) {
142 output.status = NetconfAdaptorConstant.STATUS_FAILURE
143 output.errorMessage = "failed in lock command " + e.message
149 override fun commit(messageId: String, message: String, discardChanges: Boolean, messageTimeout: Int): DeviceResponse {
150 var output = DeviceResponse()
152 val messageContent = RpcMessageUtils.commit(messageId, message)
153 output = asyncRpc(messageContent, messageId, messageTimeout)
154 } catch (e: Exception) {
155 output.status = NetconfAdaptorConstant.STATUS_FAILURE
156 output.errorMessage = "failed in commit command " + e.message
158 // Update the Apply Config status
159 if (CollectionUtils.isNotEmpty(applyConfigIds)) {
160 val status = if (NetconfAdaptorConstant.STATUS_SUCCESS.equals(output.status,ignoreCase = true))
161 NetconfAdaptorConstant.CONFIG_STATUS_SUCCESS
163 NetconfAdaptorConstant.CONFIG_STATUS_FAILED
165 applyConfigIds.forEach{
166 recordedApplyConfigIds.add(it)
168 //TODO persistance logic
169 // configPersistService.updateApplyConfig(applyConfigId, status)
170 } catch (e: Exception) {
171 log.error("failed to update apply config ($it) status ($status)")
175 applyConfigIds.clear()
178 // Update the Configuration in Running Config Table from 1810 release
179 // String recordMessageId = "recoded-running-config-" + messageId;
180 // recordRunningConfig(recordMessageId, null);
183 // If commit failed apply discard changes
184 if (discardChanges && NetconfAdaptorConstant.STATUS_FAILURE.equals(output.status,ignoreCase = true)) {
186 val discardChangesConfigMessageId = "$messageId-discard-changes"
187 discardConfig(discardChangesConfigMessageId, NetconfAdaptorConstant.DEFAULT_MESSAGE_TIME_OUT)
188 } catch (e: Exception) {
189 log.error("failed to rollback ($e) ")
196 override fun discardConfig(messageId: String, messageTimeout: Int): DeviceResponse {
197 var output = DeviceResponse()
199 val discardChangesMessage = RpcMessageUtils.discardChanges(messageId)
200 output.requestMessage = discardChangesMessage
201 output = asyncRpc(discardChangesMessage, messageId, messageTimeout)
202 } catch (e: Exception) {
203 output.status = NetconfAdaptorConstant.STATUS_FAILURE
204 output.errorMessage = "failed in discard changes command " + e.message
210 override fun close(messageId: String, force: Boolean, messageTimeout: Int): DeviceResponse {
211 var output = DeviceResponse()
213 val messageContent = RpcMessageUtils.closeSession(messageId, force)
214 output = asyncRpc(messageContent, messageId, messageTimeout)
215 } catch (e: Exception) {
216 output.status = NetconfAdaptorConstant.STATUS_FAILURE
217 output.responseMessage = "failed in close command " + e.message
224 override fun asyncRpc(request: String, msgId: String, timeOut: Int): DeviceResponse {
225 val response = DeviceResponse()
227 recordMessage("RPC request $request")
228 response.requestMessage = request
229 publishMessage("Netconf RPC InProgress")
231 val rpcResponse = netconfSession.asyncRpc(request, msgId).get(timeOut.toLong(), TimeUnit.SECONDS)
232 response.responseMessage = rpcResponse
234 if (!RpcMessageUtils.checkReply(rpcResponse)) {
235 throw NetconfException(rpcResponse)
237 response.status = NetconfAdaptorConstant.STATUS_SUCCESS
238 response.errorMessage = null
239 } catch (e: Exception) {
240 response.status = NetconfAdaptorConstant.STATUS_FAILURE
241 response.errorMessage = e.message
243 recordMessage(String.format("RPC Response status (%s) reply (%s), error message (%s)", response.status,
244 response.responseMessage, response.errorMessage))
247 NetconfAdaptorConstant.STATUS_FAILURE.equals(response.status,ignoreCase = true) -> publishMessage(String.format("Netconf RPC Failed for messgaeID (%s) with (%s)", msgId,
248 response.errorMessage))
249 else -> publishMessage(String.format("Netconf RPC Success for messgaeID (%s)", msgId))
256 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 {
257 var editConfigDeviceResponse = DeviceResponse()
260 val editMessage = RpcMessageUtils.editConfig(messageId, NetconfAdaptorConstant.CONFIG_TARGET_CANDIDATE,
261 editDefaultOperation, messageContent)
262 editConfigDeviceResponse.requestMessage = editMessage
264 /* val applyConfigId = configPersistService.saveApplyConfig(netconfExecutionRequest.getRequestId(),
265 netconfDeviceInfo.getName(), netconfDeviceInfo.getDeviceId(), ConfigModelConstant.PROTOCOL_NETCONF,
266 configTarget, editMessage)
268 applyConfigIds.add(applyConfigId) */
270 // Reconnect Client Session
274 // Provide invocation Delay
276 log.info("Waiting for {} sec for the transaction to start", wait)
277 Thread.sleep(wait * 1000L)
281 val lockMessageId = "$messageId-lock"
282 val lockDeviceResponse = lock(lockMessageId, configTarget, DEFAULT_MESSAGE_TIME_OUT)
283 editConfigDeviceResponse.addSubDeviceResponse(lockMessageId, lockDeviceResponse)
284 if (!NetconfAdaptorConstant.STATUS_SUCCESS.equals(lockDeviceResponse.status,ignoreCase = true)) {
285 throw NetconfException(lockDeviceResponse.errorMessage!!)
289 if (clearCandidate) {
290 val deleteConfigMessageId = "$messageId-delete"
291 val deleteConfigDeviceResponse = deleteConfig(deleteConfigMessageId,
292 NetconfAdaptorConstant.CONFIG_TARGET_CANDIDATE, DEFAULT_MESSAGE_TIME_OUT)
293 editConfigDeviceResponse.addSubDeviceResponse(deleteConfigMessageId, deleteConfigDeviceResponse)
294 if (!NetconfAdaptorConstant.STATUS_SUCCESS.equals(deleteConfigDeviceResponse.status,ignoreCase = true)) {
295 throw NetconfException(deleteConfigDeviceResponse.errorMessage!!)
299 if (discardChanges) {
300 val discardConfigMessageId = "$messageId-discard"
301 val discardConfigDeviceResponse = discardConfig(discardConfigMessageId, DEFAULT_MESSAGE_TIME_OUT)
302 editConfigDeviceResponse.addSubDeviceResponse(discardConfigMessageId, discardConfigDeviceResponse)
303 if (!NetconfAdaptorConstant.STATUS_SUCCESS.equals(discardConfigDeviceResponse.status,ignoreCase = true)) {
304 throw NetconfException(discardConfigDeviceResponse.errorMessage!!)
308 editConfigDeviceResponse = asyncRpc(editMessage, messageId, messageTimeout)
309 if (!NetconfAdaptorConstant.STATUS_SUCCESS.equals(editConfigDeviceResponse.status,ignoreCase = true)) {
310 throw NetconfException(editConfigDeviceResponse.errorMessage!!)
314 val validateMessageId = "$messageId-validate"
315 val validateDeviceResponse = validate(validateMessageId,
316 NetconfAdaptorConstant.CONFIG_TARGET_CANDIDATE, DEFAULT_MESSAGE_TIME_OUT)
317 editConfigDeviceResponse.addSubDeviceResponse(validateMessageId, validateDeviceResponse)
318 if (!NetconfAdaptorConstant.STATUS_SUCCESS.equals(validateDeviceResponse.status,ignoreCase = true)) {
319 throw NetconfException(validateDeviceResponse.errorMessage!!)
324 * If Commit is enable, the commit response is treated as Edit config response, If commit failed, we
325 * need not to throw an exception, until we unlock the device.
328 val commitMessageId = "$messageId-commit"
329 val commitDeviceResponse = commit(commitMessageId, commitMessageId, discardChanges, DEFAULT_MESSAGE_TIME_OUT)
330 editConfigDeviceResponse.addSubDeviceResponse(commitMessageId, commitDeviceResponse)
331 if (!NetconfAdaptorConstant.STATUS_SUCCESS.equals(commitDeviceResponse.status,ignoreCase = true)) {
332 throw NetconfException(commitDeviceResponse.errorMessage!!)
336 // Provide pre restart Delay
337 if (preRestartWait > 0) {
338 log.info("Waiting for {} sec for restart", wait)
339 Thread.sleep(preRestartWait * 1000L)
341 // TODO Restart Device
342 // Provide post restart Delay
343 if (postRestartWait > 0) {
344 log.info("Waiting for {} sec for the post restart", wait)
345 Thread.sleep(postRestartWait * 1000L)
348 } catch (e: Exception) {
349 editConfigDeviceResponse.status = NetconfAdaptorConstant.STATUS_FAILURE
350 editConfigDeviceResponse.errorMessage = e.message
353 val unlockMessageId = "$messageId-unlock"
354 val unlockDeviceResponse = unLock(unlockMessageId, configTarget, DEFAULT_MESSAGE_TIME_OUT)
355 editConfigDeviceResponse.addSubDeviceResponse(unlockMessageId, unlockDeviceResponse)
356 if (!NetconfAdaptorConstant.STATUS_SUCCESS.equals(unlockDeviceResponse.status,ignoreCase = true)) {
357 editConfigDeviceResponse.status = NetconfAdaptorConstant.STATUS_FAILURE
358 editConfigDeviceResponse.errorMessage = unlockDeviceResponse.errorMessage
362 return editConfigDeviceResponse
365 override fun validate(messageId: String, configTarget: String, messageTimeout: Int): DeviceResponse {
366 var output = DeviceResponse()
368 val validateMessage = RpcMessageUtils.validate(messageId, configTarget)
369 output.requestMessage = validateMessage
370 output = asyncRpc(validateMessage, messageId, messageTimeout)
371 } catch (e: Exception) {
372 output.status = NetconfAdaptorConstant.STATUS_FAILURE
373 output.errorMessage = "failed in validate command " + e.message
380 fun recordMessage(message: String) {
381 recordMessage(NetconfAdaptorConstant.LOG_MESSAGE_TYPE_LOG, message)
384 fun recordMessage(messageType: String, message: String) {
386 //eventPublishService.recordMessage(netconfExecutionRequest.getRequestId(), messageType, message)
389 fun publishMessage(message: String) {
391 //eventPublishService.publishMessage(netconfExecutionRequest.getRequestId(), message)