5c633a5b9ba65bcca6b1525f65bf493cc7edd016
[ccsdk/cds.git] /
1 /*
2  * Copyright © 2017-2019 AT&T, Bell Canada
3  *
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
7  *
8  *     http://www.apache.org/licenses/LICENSE-2.0
9  *
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.
15  */
16
17 package org.onap.ccsdk.apps.blueprintsprocessor.functions.netconf.executor.core
18
19 import org.onap.ccsdk.apps.blueprintsprocessor.functions.netconf.executor.api.DeviceInfo
20 import org.onap.ccsdk.apps.blueprintsprocessor.functions.netconf.executor.api.DeviceResponse
21 import org.onap.ccsdk.apps.blueprintsprocessor.functions.netconf.executor.api.NetconfException
22 import org.onap.ccsdk.apps.blueprintsprocessor.functions.netconf.executor.api.NetconfRpcService
23 import org.onap.ccsdk.apps.blueprintsprocessor.functions.netconf.executor.api.NetconfSession
24 import org.onap.ccsdk.apps.blueprintsprocessor.functions.netconf.executor.utils.NetconfDatastore
25 import org.onap.ccsdk.apps.blueprintsprocessor.functions.netconf.executor.utils.NetconfMessageUtils
26 import org.onap.ccsdk.apps.blueprintsprocessor.functions.netconf.executor.utils.RpcStatus
27 import org.slf4j.LoggerFactory
28 import java.util.concurrent.TimeUnit
29
30 class NetconfRpcServiceImpl(private val deviceInfo: DeviceInfo) : NetconfRpcService {
31
32     private val log = LoggerFactory.getLogger(NetconfRpcService::class.java)
33
34     private lateinit var netconfSession: NetconfSession
35
36     fun setNetconfSession(netconfSession: NetconfSession) {
37         this.netconfSession = netconfSession
38     }
39
40     override fun getConfig(messageId: String, filter: String, configTarget: String,
41                            messageTimeout: Int): DeviceResponse {
42         var output = DeviceResponse()
43         log.info("$deviceInfo: getConfig: messageId($messageId)")
44         try {
45             val message = NetconfMessageUtils.getConfig(messageId, configTarget, filter)
46             output = asyncRpc(message, messageId, messageTimeout)
47         } catch (e: Exception) {
48             output.status = RpcStatus.FAILURE
49             output.errorMessage = "$deviceInfo: failed in get-config command $e.message"
50         }
51         return output
52     }
53
54     override fun deleteConfig(messageId: String, configTarget: String, messageTimeout: Int): DeviceResponse {
55         var output = DeviceResponse()
56         log.info("$deviceInfo: deleteConfig: messageId($messageId)")
57         try {
58             val deleteConfigMessage = NetconfMessageUtils.deleteConfig(messageId, configTarget)
59             output.requestMessage = deleteConfigMessage
60             output = asyncRpc(deleteConfigMessage, messageId, messageTimeout)
61         } catch (e: Exception) {
62             output.status = RpcStatus.FAILURE
63             output.errorMessage = "$deviceInfo: failed in delete config command $e.message"
64         }
65         return output
66     }
67
68     override fun lock(messageId: String, configTarget: String, messageTimeout: Int): DeviceResponse {
69         var output = DeviceResponse()
70         log.info("$deviceInfo: lock: messageId($messageId)")
71         try {
72             val lockMessage = NetconfMessageUtils.lock(messageId, configTarget)
73             output.requestMessage = lockMessage
74             output = asyncRpc(lockMessage, messageId, messageTimeout)
75         } catch (e: Exception) {
76             output.status = RpcStatus.FAILURE
77             output.errorMessage = "$deviceInfo: failed in lock command $e.message"
78         }
79
80         return output
81     }
82
83     override fun unLock(messageId: String, configTarget: String, messageTimeout: Int): DeviceResponse {
84         var output = DeviceResponse()
85         log.info("$deviceInfo: unLock: messageId($messageId)")
86         try {
87             val unlockMessage = NetconfMessageUtils.unlock(messageId, configTarget)
88             output.requestMessage = unlockMessage
89             output = asyncRpc(unlockMessage, messageId, messageTimeout)
90         } catch (e: Exception) {
91             output.status = RpcStatus.FAILURE
92             output.errorMessage = "$deviceInfo: failed in lock command $e.message"
93         }
94         return output
95     }
96
97     override fun commit(messageId: String, discardChanges: Boolean, messageTimeout: Int): DeviceResponse {
98         var output = DeviceResponse()
99         log.info("$deviceInfo: commit: messageId($messageId)")
100         try {
101             val messageContent = NetconfMessageUtils.commit(messageId)
102             output = asyncRpc(messageContent, messageId, messageTimeout)
103         } catch (e: Exception) {
104             output.status = RpcStatus.FAILURE
105             output.errorMessage = "$deviceInfo: failed in commit command $e.message"
106
107             // If commit failed apply discard changes
108             if (discardChanges) {
109                 val discardChangesConfigMessageId = "$messageId-discard-changes"
110                 val discardOutput = discardConfig(discardChangesConfigMessageId, deviceInfo.replyTimeout)
111                 output.addSubDeviceResponse(discardChangesConfigMessageId, discardOutput)
112             }
113         }
114         return output
115     }
116
117     override fun discardConfig(messageId: String, messageTimeout: Int): DeviceResponse {
118         var output = DeviceResponse()
119         log.info("$deviceInfo: discard: messageId($messageId)")
120         try {
121             val discardChangesMessage = NetconfMessageUtils.discardChanges(messageId)
122             output.requestMessage = discardChangesMessage
123             output = asyncRpc(discardChangesMessage, messageId, messageTimeout)
124         } catch (e: Exception) {
125             output.status = RpcStatus.FAILURE
126             output.errorMessage = "$deviceInfo: failed in discard changes command " + e.message
127         }
128         return output
129     }
130
131     override fun closeSession(messageId: String, force: Boolean, messageTimeout: Int): DeviceResponse {
132         var output = DeviceResponse()
133         log.info("$deviceInfo: closeSession: messageId($messageId)")
134         try {
135             val messageContent = NetconfMessageUtils.closeSession(messageId, force)
136             output = asyncRpc(messageContent, messageId, messageTimeout)
137         } catch (e: Exception) {
138             output.status = RpcStatus.FAILURE
139             output.errorMessage = "$deviceInfo: failed in closeSession command " + e.message
140         }
141         return output
142     }
143
144     @Throws(NetconfException::class)
145     override fun asyncRpc(request: String, messageId: String, messageTimeout: Int): DeviceResponse {
146         val response = DeviceResponse()
147         log.info("$deviceInfo: send asyncRpc with messageId($messageId)")
148         response.requestMessage = request
149
150         val rpcResponse = netconfSession.asyncRpc(request, messageId).get(messageTimeout.toLong(), TimeUnit.SECONDS)
151         if (!NetconfMessageUtils.checkReply(rpcResponse)) {
152             throw NetconfException(rpcResponse)
153         }
154         response.responseMessage = rpcResponse
155         response.status = RpcStatus.SUCCESS
156         response.errorMessage = null
157         return response
158     }
159
160     override fun editConfig(messageId: String, messageContent: String, lock: Boolean, configTarget: String,
161                             editDefaultOperation: String, deleteConfig: Boolean, validate: Boolean, commit: Boolean,
162                             discardChanges: Boolean, unlock: Boolean, messageTimeout: Int): DeviceResponse {
163         var editConfigDeviceResponse =
164             DeviceResponse()
165
166         try {
167             val editMessage =
168                 NetconfMessageUtils.editConfig(messageId, configTarget, editDefaultOperation, messageContent)
169             editConfigDeviceResponse.requestMessage = editMessage
170
171             if (lock) {
172                 val lockMessageId = "$messageId-lock"
173                 val lockDeviceResponse = lock(lockMessageId, configTarget, deviceInfo.replyTimeout)
174                 editConfigDeviceResponse.addSubDeviceResponse(lockMessageId, lockDeviceResponse)
175                 if (!RpcStatus.SUCCESS.equals(lockDeviceResponse.status, ignoreCase = true)) {
176                     throw NetconfException(
177                         lockDeviceResponse.errorMessage!!)
178                 }
179             }
180
181             if (deleteConfig) {
182                 val deleteConfigMessageId = "$messageId-delete"
183                 val deleteConfigDeviceResponse = deleteConfig(deleteConfigMessageId,
184                     NetconfDatastore.CANDIDATE, deviceInfo.replyTimeout)
185                 editConfigDeviceResponse.addSubDeviceResponse(deleteConfigMessageId, deleteConfigDeviceResponse)
186                 if (!RpcStatus.SUCCESS.equals(deleteConfigDeviceResponse.status,
187                         ignoreCase = true)) {
188                     throw NetconfException(
189                         deleteConfigDeviceResponse.errorMessage!!)
190                 }
191             }
192
193             if (discardChanges) {
194                 val discardConfigMessageId = "$messageId-discard"
195                 val discardConfigDeviceResponse = discardConfig(discardConfigMessageId, deviceInfo.replyTimeout)
196                 editConfigDeviceResponse.addSubDeviceResponse(discardConfigMessageId, discardConfigDeviceResponse)
197                 if (!RpcStatus.SUCCESS.equals(discardConfigDeviceResponse.status,
198                         ignoreCase = true)) {
199                     throw NetconfException(
200                         discardConfigDeviceResponse.errorMessage!!)
201                 }
202             }
203
204             editConfigDeviceResponse = asyncRpc(editMessage, messageId, messageTimeout)
205             if (!RpcStatus.SUCCESS.equals(editConfigDeviceResponse.status, ignoreCase = true)) {
206                 throw NetconfException(
207                     editConfigDeviceResponse.errorMessage!!)
208             }
209
210             if (validate) {
211                 val validateMessageId = "$messageId-validate"
212                 val validateDeviceResponse = validate(validateMessageId,
213                     NetconfDatastore.CANDIDATE, deviceInfo.replyTimeout)
214                 editConfigDeviceResponse.addSubDeviceResponse(validateMessageId, validateDeviceResponse)
215                 if (!RpcStatus.SUCCESS.equals(validateDeviceResponse.status, ignoreCase = true)) {
216                     throw NetconfException(
217                         validateDeviceResponse.errorMessage!!)
218                 }
219             }
220
221             /**
222              * If Commit is enable, the commit response is treated as Edit config response, If commit failed, we
223              * need not to throw an exception, until we unlock the device.
224              */
225             if (commit) {
226                 val commitMessageId = "$messageId-commit"
227                 val commitDeviceResponse =
228                     commit(commitMessageId, discardChanges, deviceInfo.replyTimeout)
229                 editConfigDeviceResponse.addSubDeviceResponse(commitMessageId, commitDeviceResponse)
230                 if (!RpcStatus.SUCCESS.equals(commitDeviceResponse.status, ignoreCase = true)) {
231                     throw NetconfException(
232                         commitDeviceResponse.errorMessage!!)
233                 }
234             }
235
236         } catch (e: Exception) {
237             editConfigDeviceResponse.status = RpcStatus.FAILURE
238             editConfigDeviceResponse.errorMessage = e.message
239         } finally {
240             if (unlock) {
241                 val unlockMessageId = "$messageId-unlock"
242                 val unlockDeviceResponse = unLock(unlockMessageId, configTarget, deviceInfo.replyTimeout)
243                 editConfigDeviceResponse.addSubDeviceResponse(unlockMessageId, unlockDeviceResponse)
244                 if (!RpcStatus.SUCCESS.equals(unlockDeviceResponse.status, ignoreCase = true)) {
245                     editConfigDeviceResponse.status = RpcStatus.FAILURE
246                     editConfigDeviceResponse.errorMessage = unlockDeviceResponse.errorMessage
247                 }
248             }
249         }
250         return editConfigDeviceResponse
251     }
252
253     override fun validate(messageId: String, configTarget: String, messageTimeout: Int): DeviceResponse {
254         var output = DeviceResponse()
255         try {
256             val validateMessage = NetconfMessageUtils.validate(messageId, configTarget)
257             output.requestMessage = validateMessage
258             output = asyncRpc(validateMessage, messageId, messageTimeout)
259         } catch (e: Exception) {
260             output.status = RpcStatus.FAILURE
261             output.errorMessage = "$deviceInfo: failed in validate command " + e.message
262         }
263         return output
264     }
265 }