2  * ============LICENSE_START=======================================================
 
   4  * ================================================================================
 
   5  * Copyright (C) 2017 AT&T Intellectual Property. All rights
 
   7  * ================================================================================
 
   8  * Licensed under the Apache License, Version 2.0 (the "License");
 
   9  * you may not use this file except in compliance with the License.
 
  10  * You may obtain a copy of the License at
 
  12  *      http://www.apache.org/licenses/LICENSE-2.0
 
  14  * Unless required by applicable law or agreed to in writing, software
 
  15  * distributed under the License is distributed on an "AS IS" BASIS,
 
  16  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 
  17  * See the License for the specific language governing permissions and
 
  18  * limitations under the License.
 
  19  * ============LICENSE_END=========================================================
 
  22 package org.openecomp.appc.adapter.netconf.jsch;
 
  24 import com.jcraft.jsch.Channel;
 
  25 import com.jcraft.jsch.ChannelSubsystem;
 
  26 import com.jcraft.jsch.JSch;
 
  27 import com.jcraft.jsch.Session;
 
  29 import java.io.IOException;
 
  30 import java.util.List;
 
  31 import java.util.Properties;
 
  33 import org.openecomp.appc.adapter.netconf.NetconfClient;
 
  34 import org.openecomp.appc.adapter.netconf.NetconfConnectionDetails;
 
  35 import org.openecomp.appc.adapter.netconf.internal.NetconfAdapter;
 
  36 import org.openecomp.appc.adapter.netconf.internal.NetconfConstMessages;
 
  37 import org.openecomp.appc.encryption.EncryptionTool;
 
  38 import org.openecomp.appc.exceptions.APPCException;
 
  39 import org.openecomp.appc.i18n.Msg;
 
  40 import com.att.eelf.i18n.EELFResourceManager;
 
  43  * Implementation of NetconfClient interface based on JCraft jsch library.
 
  45 public class NetconfClientJsch implements NetconfClient {
 
  47     private static final int SESSION_CONNECT_TIMEOUT = 30000;
 
  48     private static final int CHANNEL_CONNECT_TIMEOUT = 10000;
 
  50     private Session session;
 
  51     private Channel channel;
 
  52     private NetconfAdapter netconfAdapter;
 
  53 //    private NetconfAdapter2 netconfAdapter;
 
  57     public void connect(NetconfConnectionDetails connectionDetails) throws APPCException {
 
  58         String host = connectionDetails.getHost();
 
  59         int port = connectionDetails.getPort();
 
  60         String username = connectionDetails.getUsername();
 
  61         String password = connectionDetails.getPassword();
 
  63             JSch.setLogger(new JSchLogger());
 
  64             JSch jsch = new JSch();
 
  65             session = jsch.getSession(EncryptionTool.getInstance().decrypt(username), host, port);
 
  66             session.setPassword(EncryptionTool.getInstance().decrypt(password));
 
  67             session.setConfig("StrictHostKeyChecking", "no");
 
  69             Properties additionalProps = connectionDetails.getAdditionalProperties();
 
  70             if((additionalProps != null) && !additionalProps.isEmpty()) {
 
  71                 session.setConfig(additionalProps);
 
  74             session.connect(SESSION_CONNECT_TIMEOUT);
 
  75             session.setTimeout(10000);
 
  77 //                session.setServerAliveCountMax(0); // If this is not set to '0', then socket timeout on all reads will not work!!!!
 
  78                 channel = session.openChannel("subsystem");
 
  79                 ((ChannelSubsystem)channel).setSubsystem("netconf");
 
  80                 netconfAdapter = new NetconfAdapter(channel.getInputStream(), channel.getOutputStream());
 
  81 //                netconfAdapter = new NetconfAdapter2();
 
  82 //                channel.setInputStream(netconfAdapter.getIn());
 
  83 //                channel.setOutputStream(netconfAdapter.getOut());
 
  84                 channel.connect(CHANNEL_CONNECT_TIMEOUT);
 
  85                 hello(connectionDetails.getCapabilities());
 
  86             } catch(Exception e) {
 
  90         } catch(Exception e) {
 
  91             String message = EELFResourceManager.format(Msg.CANNOT_ESTABLISH_CONNECTION, host, String.valueOf(port), username);
 
  92             throw new APPCException(message, e);
 
  97     public String exchangeMessage(String message) throws APPCException {
 
  99             netconfAdapter.sendMessage(message);
 
 100             return netconfAdapter.receiveMessage();
 
 101         } catch(IOException e) {
 
 102             throw new APPCException(e);
 
 107     public void configure(String configuration) throws APPCException {
 
 109             isOk(exchangeMessage(configuration));
 
 110         } catch(IOException e) {
 
 111             throw new APPCException(e);
 
 116     public String getConfiguration() throws APPCException {
 
 117         return exchangeMessage(NetconfConstMessages.GET_RUNNING_CONFIG);
 
 121     public void disconnect() {
 
 123             if((channel != null) && !channel.isClosed()) {
 
 124                 netconfAdapter.sendMessage(NetconfConstMessages.CLOSE_SESSION);
 
 125                 isOk(netconfAdapter.receiveMessage());
 
 127         } catch(IOException e) {
 
 128             throw new RuntimeException("Error closing netconf device", e);
 
 130             netconfAdapter = null;
 
 131             if(channel != null) {
 
 132                 channel.disconnect();
 
 135             if(session != null) {
 
 136                 session.disconnect();
 
 142     private void hello(List<String> capabilities) throws IOException {
 
 143         String helloIn = netconfAdapter.receiveMessage();
 
 144         if(helloIn == null) {
 
 145             throw new IOException("Expected hello message, but nothing received error from netconf device");
 
 147         if(helloIn.contains("<rpc-error>")) {
 
 148             throw new IOException("Expected hello message, but received error from netconf device:\n" + helloIn);
 
 150         StringBuilder sb = new StringBuilder();
 
 151         sb.append(NetconfConstMessages.CAPABILITIES_START);
 
 152         sb.append(NetconfConstMessages.CAPABILITIES_BASE);
 
 153         if(capabilities != null) {
 
 154             for(String capability: capabilities) {
 
 155                 sb.append("    ").append(capability).append("\n");
 
 158         sb.append(NetconfConstMessages.CAPABILITIES_END);
 
 159         String helloOut = sb.toString();
 
 160         netconfAdapter.sendMessage(helloOut);
 
 163     private void isOk(String response) throws IOException {
 
 164         if(response == null) {
 
 165             throw new IOException("No response from netconf device");
 
 167         if(!response.contains("<ok/>")) {
 
 168             throw new IOException("Error response from netconf device: \n" + response);