adcba131ed1298bfe94f97703560bf3525b61ba9
[ccsdk/apps.git] /
1 /*
2  * Copyright © 2017-2018 AT&T Intellectual Property.
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 com.google.common.collect.ImmutableList
20 import com.google.common.collect.ImmutableSet
21 import org.apache.sshd.client.SshClient
22 import org.apache.sshd.client.channel.ClientChannel
23 import org.apache.sshd.client.session.ClientSession
24 import org.apache.sshd.common.FactoryManager
25 import org.apache.sshd.server.keyprovider.SimpleGeneratorHostKeyProvider
26 import org.onap.ccsdk.apps.blueprintsprocessor.functions.netconf.executor.data.NetconfException
27 import org.onap.ccsdk.apps.blueprintsprocessor.functions.netconf.executor.interfaces.DeviceInfo
28 import org.onap.ccsdk.apps.blueprintsprocessor.functions.netconf.executor.interfaces.NetconfSession
29 import org.slf4j.LoggerFactory
30 import java.io.IOException
31 import java.util.*
32 import java.util.concurrent.CompletableFuture
33 import java.util.concurrent.ConcurrentHashMap
34 import java.util.concurrent.TimeUnit
35 import java.util.concurrent.atomic.AtomicInteger
36
37 class NetconfSessionImpl(val deviceInfo: DeviceInfo): NetconfSession  {
38     val log = LoggerFactory.getLogger(NetconfSessionImpl::class.java)
39     var connectTimeout: Long = 0
40     var replyTimeout: Int = 0
41     var idleTimeout: Int = 0
42     var sessionID: String? = null
43     var errorReplies: MutableList<String> = mutableListOf()
44     var netconfCapabilities = ImmutableList.of("urn:ietf:params:netconf:base:1.0", "urn:ietf:params:netconf:base:1.1")
45
46    // var replies: MutableMap<String, CompletableFuture<String>> = mutableListOf<String,CompletableFuture<String>()>()
47     var replies: Map<String, CompletableFuture<String>> = ConcurrentHashMap()
48     val deviceCapabilities = LinkedHashSet<String>()
49
50     lateinit var session: ClientSession
51     lateinit var client: SshClient
52     lateinit var channel: ClientChannel
53     //var streamHandler: NetconfStreamHandler? = null
54
55     val messageIdInteger = AtomicInteger(1)
56
57     init {
58         startConnection()
59     }
60
61     private fun startConnection() {
62         connectTimeout = deviceInfo.connectTimeoutSec
63         replyTimeout = deviceInfo.replyTimeout
64         idleTimeout = deviceInfo.idleTimeout
65         log.info("Connecting to NETCONF Device {} with timeouts C:{}, R:{}, I:{}", deviceInfo, connectTimeout,
66                 replyTimeout, idleTimeout)
67         try {
68             startClient()
69         } catch (e: IOException) {
70             throw NetconfException("Failed to establish SSH with device $deviceInfo")
71         }
72
73     }
74
75     private fun startClient() {
76         //client = SshClient.setUpDefaultClient().toInt()
77         client = SshClient()
78         client.getProperties().putIfAbsent(FactoryManager.IDLE_TIMEOUT, TimeUnit.SECONDS.toMillis(idleTimeout.toLong()))
79         client.getProperties().putIfAbsent(FactoryManager.NIO2_READ_TIMEOUT,
80                 TimeUnit.SECONDS.toMillis(idleTimeout + 15L))
81         client.start()
82         client.setKeyPairProvider(SimpleGeneratorHostKeyProvider())
83         startSession()
84     }
85
86     private fun startSession() {
87         val connectFuture = client.connect(deviceInfo.name, deviceInfo.ipAddress, deviceInfo.port)
88                 .verify(connectTimeout, TimeUnit.SECONDS)
89
90         session = connectFuture.session
91
92         session.addPasswordIdentity(deviceInfo.pass)
93         session.auth().verify(connectTimeout, TimeUnit.SECONDS)
94
95         val event = session.waitFor(ImmutableSet.of(ClientSession.ClientSessionEvent.WAIT_AUTH,
96                 ClientSession.ClientSessionEvent.CLOSED, ClientSession.ClientSessionEvent.AUTHED), 0)
97
98         if (!event.contains(ClientSession.ClientSessionEvent.AUTHED)) {
99             log.debug("Session closed {} for event {}", session.isClosed(), event)
100             throw NetconfException(String
101                     .format("Failed to authenticate session with device (%s) check the user/pwd or key", deviceInfo))
102         }
103         openChannel()
104     }
105
106     private fun openChannel() {
107         channel = session.createSubsystemChannel("netconf")
108         val channeuture = channel.open()
109
110         if (channeuture!!.await(connectTimeout, TimeUnit.SECONDS) && channeuture.isOpened) {
111            // streamHandler = NetconfStreamThread(channel.getInvertedOut(), channel.getInvertedIn(), deviceInfo,
112            //         NetconfSessionDelegateImpl(), replies)
113            // sendHello()
114         } else {
115             throw NetconfException(String.format("Failed to open channel with device (%s)", deviceInfo))
116         }
117     }
118
119     private fun sendHello() {
120         TODO("not implemented") //To change body of created functions use File | Settings | File Templates.
121     }
122
123
124     override fun asyncRpc(request: String, msgId: String): CompletableFuture<String> {
125         TODO("not implemented") //To change body of created functions use File | Settings | File Templates.
126     }
127
128     override fun close(): Boolean {
129         TODO("not implemented") //To change body of created functions use File | Settings | File Templates.
130     }
131
132     override fun getSessionId(): String {
133         TODO("not implemented") //To change body of created functions use File | Settings | File Templates.
134     }
135
136     override fun getDeviceCapabilitiesSet(): Set<String> {
137         TODO("not implemented") //To change body of created functions use File | Settings | File Templates.
138     }
139
140     override fun checkAndReestablish() {
141         super.checkAndReestablish()
142     }
143
144     override fun setCapabilities(capabilities: List<String>) {
145         super.setCapabilities(capabilities)
146     }
147 }