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 org.apache.commons.collections.CollectionUtils
20 import org.onap.ccsdk.apps.blueprintsprocessor.functions.netconf.executor.core.NetconfSessionFactory
21 import org.onap.ccsdk.apps.blueprintsprocessor.functions.netconf.executor.data.DeviceResponse
22 import org.onap.ccsdk.apps.blueprintsprocessor.functions.netconf.executor.data.NetconfAdaptorConstant
23 import org.onap.ccsdk.apps.blueprintsprocessor.functions.netconf.executor.interfaces.DeviceInfo
24 import org.onap.ccsdk.apps.blueprintsprocessor.functions.netconf.executor.interfaces.NetconfRpcClientService
25 import org.onap.ccsdk.apps.blueprintsprocessor.functions.netconf.executor.interfaces.NetconfSession
26 import org.onap.ccsdk.apps.blueprintsprocessor.functions.netconf.executor.utils.RpcMessageUtils
27 import org.slf4j.LoggerFactory
28 import org.springframework.beans.factory.config.ConfigurableBeanFactory
29 import org.springframework.context.annotation.Scope
30 import org.springframework.stereotype.Service
32 import java.util.concurrent.TimeUnit
35 @Service("netconf-rpc-service")
36 @Scope(value = ConfigurableBeanFactory.SCOPE_PROTOTYPE)
37 class NetconfRpcService : NetconfRpcClientService {
39 val log = LoggerFactory.getLogger(NetconfRpcService::class.java)
41 lateinit var deviceInfo: DeviceInfo
42 lateinit var netconfSession: NetconfSession
44 private val applyConfigIds = ArrayList<String>()
45 private val recordedApplyConfigIds = ArrayList<String>()
46 private val DEFAULT_MESSAGE_TIME_OUT = 30
49 override fun connect(deviceInfo: DeviceInfo): NetconfSession {
52 this.deviceInfo = deviceInfo
54 log.info("Connecting Netconf Device .....")
55 this.netconfSession = NetconfSessionFactory.instance("DEFAULT_NETCONF_SESSION", deviceInfo)
56 publishMessage("Netconf Device Connection Established")
57 return this.netconfSession
58 } catch (e: NetconfException) {
59 publishMessage(String.format("Netconf Device Connection Failed, %s", e.message))
60 throw NetconfException("Netconf Device Connection Failed,$deviceInfo",e)
64 override fun disconnect() {
65 netconfSession.close()
68 override fun reconnect() {
73 override fun getConfig(messageId: String, messageContent: String, configTarget: String, messageTimeout: Int): DeviceResponse {
74 var output = DeviceResponse()
75 log.info("in the NetconfRpcService "+messageId)
77 val message = RpcMessageUtils.getConfig(messageId, configTarget, messageContent)
78 output = asyncRpc(message, messageId, messageTimeout)
79 } catch (e: Exception) {
80 output.status = NetconfAdaptorConstant.STATUS_FAILURE
81 output.errorMessage = e.message
87 override fun deleteConfig(messageId: String, configTarget: String, messageTimeout: Int): DeviceResponse {
88 var output = DeviceResponse()
90 val deleteConfigMessage = RpcMessageUtils.deleteConfig(messageId, configTarget)
91 output.requestMessage = deleteConfigMessage
92 output = asyncRpc(deleteConfigMessage, messageId, messageTimeout)
93 } catch (e: Exception) {
94 output.status = NetconfAdaptorConstant.STATUS_FAILURE
95 output.errorMessage = "failed in delete config command " + e.message
101 override fun lock(messageId: String, configTarget: String, messageTimeout: Int): DeviceResponse {
102 var output = DeviceResponse()
104 val lockMessage = RpcMessageUtils.lock(messageId, configTarget)
105 output.requestMessage = lockMessage
106 output = asyncRpc(lockMessage, messageId, messageTimeout)
107 } catch (e: Exception) {
108 output.status = NetconfAdaptorConstant.STATUS_FAILURE
109 output.errorMessage = "failed in lock command " + e.message
115 override fun unLock(messageId: String, configTarget: String, messageTimeout: Int): DeviceResponse {
116 var output = DeviceResponse()
118 val unlockMessage = RpcMessageUtils.unlock(messageId, configTarget)
119 output.requestMessage = unlockMessage
120 output = asyncRpc(unlockMessage, messageId, messageTimeout)
121 } catch (e: Exception) {
122 output.status = NetconfAdaptorConstant.STATUS_FAILURE
123 output.errorMessage = "failed in lock command " + e.message
129 override fun commit(messageId: String, message: String, discardChanges: Boolean, messageTimeout: Int): DeviceResponse {
130 var output = DeviceResponse()
132 val messageContent = RpcMessageUtils.commit(messageId, message)
133 output = asyncRpc(messageContent, messageId, messageTimeout)
134 } catch (e: Exception) {
135 output.status = NetconfAdaptorConstant.STATUS_FAILURE
136 output.errorMessage = "failed in commit command " + e.message
138 // Update the Apply Config status
139 if (CollectionUtils.isNotEmpty(applyConfigIds)) {
140 val status = if (NetconfAdaptorConstant.STATUS_SUCCESS.equals(output.status,ignoreCase = true))
141 NetconfAdaptorConstant.CONFIG_STATUS_SUCCESS
143 NetconfAdaptorConstant.CONFIG_STATUS_FAILED
145 applyConfigIds.forEach{
146 recordedApplyConfigIds.add(it)
148 //TODO persistance logic
149 // configPersistService.updateApplyConfig(applyConfigId, status)
150 } catch (e: Exception) {
151 log.error("failed to update apply config ($it) status ($status)")
155 applyConfigIds.clear()
158 // Update the Configuration in Running Config Table from 1810 release
159 // String recordMessageId = "recoded-running-config-" + messageId;
160 // recordRunningConfig(recordMessageId, null);
163 // If commit failed apply discard changes
164 if (discardChanges && NetconfAdaptorConstant.STATUS_FAILURE.equals(output.status,ignoreCase = true)) {
166 val discardChangesConfigMessageId = "$messageId-discard-changes"
167 discardConfig(discardChangesConfigMessageId, NetconfAdaptorConstant.DEFAULT_MESSAGE_TIME_OUT)
168 } catch (e: Exception) {
169 log.error("failed to rollback ($e) ")
176 override fun discardConfig(messageId: String, messageTimeout: Int): DeviceResponse {
177 var output = DeviceResponse()
179 val discardChangesMessage = RpcMessageUtils.discardChanges(messageId)
180 output.requestMessage = discardChangesMessage
181 output = asyncRpc(discardChangesMessage, messageId, messageTimeout)
182 } catch (e: Exception) {
183 output.status = NetconfAdaptorConstant.STATUS_FAILURE
184 output.errorMessage = "failed in discard changes command " + e.message
190 override fun close(messageId: String, force: Boolean, messageTimeout: Int): DeviceResponse {
191 var output = DeviceResponse()
193 val messageContent = RpcMessageUtils.closeSession(messageId, force)
194 output = asyncRpc(messageContent, messageId, messageTimeout)
195 } catch (e: Exception) {
196 output.status = NetconfAdaptorConstant.STATUS_FAILURE
197 output.responseMessage = "failed in close command " + e.message
204 override fun asyncRpc(request: String, msgId: String, timeOut: Int): DeviceResponse {
205 val response = DeviceResponse()
207 recordMessage("RPC request $request")
208 response.requestMessage = request
209 publishMessage("Netconf RPC InProgress")
211 val rpcResponse = netconfSession.asyncRpc(request, msgId).get(timeOut.toLong(), TimeUnit.SECONDS)
212 response.responseMessage = rpcResponse
214 if (!RpcMessageUtils.checkReply(rpcResponse)) {
215 throw NetconfException(rpcResponse)
217 response.status = NetconfAdaptorConstant.STATUS_SUCCESS
218 response.errorMessage = null
219 } catch (e: Exception) {
220 response.status = NetconfAdaptorConstant.STATUS_FAILURE
221 response.errorMessage = e.message
223 recordMessage(String.format("RPC Response status (%s) reply (%s), error message (%s)", response.status,
224 response.responseMessage, response.errorMessage))
227 NetconfAdaptorConstant.STATUS_FAILURE.equals(response.status,ignoreCase = true) -> publishMessage(String.format("Netconf RPC Failed for messgaeID (%s) with (%s)", msgId,
228 response.errorMessage))
229 else -> publishMessage(String.format("Netconf RPC Success for messgaeID (%s)", msgId))
236 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 {
237 var editConfigDeviceResponse = DeviceResponse()
240 val editMessage = RpcMessageUtils.editConfig(messageId, NetconfAdaptorConstant.CONFIG_TARGET_CANDIDATE,
241 editDefaultOperation, messageContent)
242 editConfigDeviceResponse.requestMessage = editMessage
244 /* val applyConfigId = configPersistService.saveApplyConfig(netconfExecutionRequest.getRequestId(),
245 netconfDeviceInfo.getName(), netconfDeviceInfo.getDeviceId(), ConfigModelConstant.PROTOCOL_NETCONF,
246 configTarget, editMessage)
248 applyConfigIds.add(applyConfigId) */
250 // Reconnect Client Session
254 // Provide invocation Delay
256 log.info("Waiting for {} sec for the transaction to start", wait)
257 Thread.sleep(wait * 1000L)
261 val lockMessageId = "$messageId-lock"
262 val lockDeviceResponse = lock(lockMessageId, configTarget, DEFAULT_MESSAGE_TIME_OUT)
263 editConfigDeviceResponse.addSubDeviceResponse(lockMessageId, lockDeviceResponse)
264 if (!NetconfAdaptorConstant.STATUS_SUCCESS.equals(lockDeviceResponse.status,ignoreCase = true)) {
265 throw NetconfException(lockDeviceResponse.errorMessage!!)
269 if (clearCandidate) {
270 val deleteConfigMessageId = "$messageId-delete"
271 val deleteConfigDeviceResponse = deleteConfig(deleteConfigMessageId,
272 NetconfAdaptorConstant.CONFIG_TARGET_CANDIDATE, DEFAULT_MESSAGE_TIME_OUT)
273 editConfigDeviceResponse.addSubDeviceResponse(deleteConfigMessageId, deleteConfigDeviceResponse)
274 if (!NetconfAdaptorConstant.STATUS_SUCCESS.equals(deleteConfigDeviceResponse.status,ignoreCase = true)) {
275 throw NetconfException(deleteConfigDeviceResponse.errorMessage!!)
279 if (discardChanges) {
280 val discardConfigMessageId = "$messageId-discard"
281 val discardConfigDeviceResponse = discardConfig(discardConfigMessageId, DEFAULT_MESSAGE_TIME_OUT)
282 editConfigDeviceResponse.addSubDeviceResponse(discardConfigMessageId, discardConfigDeviceResponse)
283 if (!NetconfAdaptorConstant.STATUS_SUCCESS.equals(discardConfigDeviceResponse.status,ignoreCase = true)) {
284 throw NetconfException(discardConfigDeviceResponse.errorMessage!!)
288 editConfigDeviceResponse = asyncRpc(editMessage, messageId, messageTimeout)
289 if (!NetconfAdaptorConstant.STATUS_SUCCESS.equals(editConfigDeviceResponse.status,ignoreCase = true)) {
290 throw NetconfException(editConfigDeviceResponse.errorMessage!!)
294 val validateMessageId = "$messageId-validate"
295 val validateDeviceResponse = validate(validateMessageId,
296 NetconfAdaptorConstant.CONFIG_TARGET_CANDIDATE, DEFAULT_MESSAGE_TIME_OUT)
297 editConfigDeviceResponse.addSubDeviceResponse(validateMessageId, validateDeviceResponse)
298 if (!NetconfAdaptorConstant.STATUS_SUCCESS.equals(validateDeviceResponse.status,ignoreCase = true)) {
299 throw NetconfException(validateDeviceResponse.errorMessage!!)
304 * If Commit is enable, the commit response is treated as Edit config response, If commit failed, we
305 * need not to throw an exception, until we unlock the device.
308 val commitMessageId = "$messageId-commit"
309 val commitDeviceResponse = commit(commitMessageId, commitMessageId, discardChanges, DEFAULT_MESSAGE_TIME_OUT)
310 editConfigDeviceResponse.addSubDeviceResponse(commitMessageId, commitDeviceResponse)
311 if (!NetconfAdaptorConstant.STATUS_SUCCESS.equals(commitDeviceResponse.status,ignoreCase = true)) {
312 throw NetconfException(commitDeviceResponse.errorMessage!!)
316 // Provide pre restart Delay
317 if (preRestartWait > 0) {
318 log.info("Waiting for {} sec for restart", wait)
319 Thread.sleep(preRestartWait * 1000L)
321 // TODO Restart Device
322 // Provide post restart Delay
323 if (postRestartWait > 0) {
324 log.info("Waiting for {} sec for the post restart", wait)
325 Thread.sleep(postRestartWait * 1000L)
328 } catch (e: Exception) {
329 editConfigDeviceResponse.status = NetconfAdaptorConstant.STATUS_FAILURE
330 editConfigDeviceResponse.errorMessage = e.message
333 val unlockMessageId = "$messageId-unlock"
334 val unlockDeviceResponse = unLock(unlockMessageId, configTarget, DEFAULT_MESSAGE_TIME_OUT)
335 editConfigDeviceResponse.addSubDeviceResponse(unlockMessageId, unlockDeviceResponse)
336 if (!NetconfAdaptorConstant.STATUS_SUCCESS.equals(unlockDeviceResponse.status,ignoreCase = true)) {
337 editConfigDeviceResponse.status = NetconfAdaptorConstant.STATUS_FAILURE
338 editConfigDeviceResponse.errorMessage = unlockDeviceResponse.errorMessage
342 return editConfigDeviceResponse
345 override fun validate(messageId: String, configTarget: String, messageTimeout: Int): DeviceResponse {
346 var output = DeviceResponse()
348 val validateMessage = RpcMessageUtils.validate(messageId, configTarget)
349 output.requestMessage = validateMessage
350 output = asyncRpc(validateMessage, messageId, messageTimeout)
351 } catch (e: Exception) {
352 output.status = NetconfAdaptorConstant.STATUS_FAILURE
353 output.errorMessage = "failed in validate command " + e.message
360 fun recordMessage(message: String) {
361 recordMessage(NetconfAdaptorConstant.LOG_MESSAGE_TYPE_LOG, message)
364 fun recordMessage(messageType: String, message: String) {
366 //eventPublishService.recordMessage(netconfExecutionRequest.getRequestId(), messageType, message)
369 fun publishMessage(message: String) {
371 //eventPublishService.publishMessage(netconfExecutionRequest.getRequestId(), message)