Remove netconf from commons/opendaylight pom
[controller.git] / opendaylight / netconf / netconf-client / src / main / java / org / opendaylight / controller / netconf / client / NetconfClientSessionNegotiator.java
index 971ea39ade5b6fb57d07a041f999ec18890528df..17f5608a1c3d0bafffe134f289ffee809324b572 100644 (file)
@@ -8,6 +8,8 @@
 
 package org.opendaylight.controller.netconf.client;
 
+import com.google.common.base.Strings;
+import com.google.common.collect.ImmutableList;
 import io.netty.channel.Channel;
 import io.netty.channel.ChannelFuture;
 import io.netty.channel.ChannelFutureListener;
@@ -15,12 +17,10 @@ import io.netty.channel.ChannelHandlerContext;
 import io.netty.channel.ChannelInboundHandlerAdapter;
 import io.netty.util.Timer;
 import io.netty.util.concurrent.Promise;
-
 import java.util.Collection;
-
 import javax.xml.xpath.XPathConstants;
 import javax.xml.xpath.XPathExpression;
-
+import org.opendaylight.controller.config.util.xml.XmlUtil;
 import org.opendaylight.controller.netconf.api.NetconfClientSessionPreferences;
 import org.opendaylight.controller.netconf.api.NetconfDocumentedException;
 import org.opendaylight.controller.netconf.api.NetconfMessage;
@@ -31,7 +31,6 @@ import org.opendaylight.controller.netconf.nettyutil.handler.exi.NetconfStartExi
 import org.opendaylight.controller.netconf.util.messages.NetconfHelloMessage;
 import org.opendaylight.controller.netconf.util.messages.NetconfMessageUtil;
 import org.opendaylight.controller.netconf.util.xml.XMLNetconfUtil;
-import org.opendaylight.controller.netconf.util.xml.XmlUtil;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 import org.w3c.dom.Document;
@@ -41,36 +40,39 @@ import org.w3c.dom.NodeList;
 public class NetconfClientSessionNegotiator extends
         AbstractNetconfSessionNegotiator<NetconfClientSessionPreferences, NetconfClientSession, NetconfClientSessionListener>
 {
-    private static final Logger logger = LoggerFactory.getLogger(NetconfClientSessionNegotiator.class);
+    private static final Logger LOG = LoggerFactory.getLogger(NetconfClientSessionNegotiator.class);
 
     private static final XPathExpression sessionIdXPath = XMLNetconfUtil
             .compileXPath("/netconf:hello/netconf:session-id");
 
+    private static final XPathExpression sessionIdXPathNoNamespace = XMLNetconfUtil
+            .compileXPath("/hello/session-id");
+
     private static final String EXI_1_0_CAPABILITY_MARKER = "exi:1.0";
 
-    protected NetconfClientSessionNegotiator(NetconfClientSessionPreferences sessionPreferences,
-                                             Promise<NetconfClientSession> promise,
-                                             Channel channel,
-                                             Timer timer,
-                                             NetconfClientSessionListener sessionListener,
-                                             long connectionTimeoutMillis) {
+    protected NetconfClientSessionNegotiator(final NetconfClientSessionPreferences sessionPreferences,
+                                             final Promise<NetconfClientSession> promise,
+                                             final Channel channel,
+                                             final Timer timer,
+                                             final NetconfClientSessionListener sessionListener,
+                                             final long connectionTimeoutMillis) {
         super(sessionPreferences, promise, channel, timer, sessionListener, connectionTimeoutMillis);
     }
 
     @Override
-    protected void handleMessage(NetconfHelloMessage netconfMessage) throws NetconfDocumentedException {
+    protected void handleMessage(final NetconfHelloMessage netconfMessage) throws NetconfDocumentedException {
         final NetconfClientSession session = getSessionForHelloMessage(netconfMessage);
         replaceHelloMessageInboundHandler(session);
 
         // If exi should be used, try to initiate exi communication
         // Call negotiationSuccessFul after exi negotiation is finished successfully or not
         if (shouldUseExi(netconfMessage)) {
-            logger.debug("Netconf session {} should use exi.", session);
+            LOG.debug("Netconf session {} should use exi.", session);
             NetconfStartExiMessage startExiMessage = (NetconfStartExiMessage) sessionPreferences.getStartExiMessage();
             tryToInitiateExi(session, startExiMessage);
-        // Exi is not supported, release session immediately
         } else {
-            logger.debug("Netconf session {} isn't capable of using exi.", session);
+            // Exi is not supported, release session immediately
+            LOG.debug("Netconf session {} isn't capable of using exi.", session);
             negotiationSuccessful(session);
         }
     }
@@ -89,21 +91,21 @@ public class NetconfClientSessionNegotiator extends
             @Override
             public void operationComplete(final ChannelFuture f) {
                 if (!f.isSuccess()) {
-                    logger.warn("Failed to send start-exi message {} on session {}", startExiMessage, this, f.cause());
+                    LOG.warn("Failed to send start-exi message {} on session {}", startExiMessage, this, f.cause());
                     channel.pipeline().remove(ExiConfirmationInboundHandler.EXI_CONFIRMED_HANDLER);
                 } else {
-                    logger.trace("Start-exi message {} sent to socket on session {}", startExiMessage, this);
+                    LOG.trace("Start-exi message {} sent to socket on session {}", startExiMessage, this);
                 }
             }
         });
     }
 
-    private boolean shouldUseExi(NetconfHelloMessage helloMsg) {
+    private boolean shouldUseExi(final NetconfHelloMessage helloMsg) {
         return containsExi10Capability(helloMsg.getDocument())
                 && containsExi10Capability(sessionPreferences.getHelloMessage().getDocument());
     }
 
-    private boolean containsExi10Capability(final Document doc) {
+    private static boolean containsExi10Capability(final Document doc) {
         final NodeList nList = doc.getElementsByTagName(XmlNetconfConstants.CAPABILITY);
         for (int i = 0; i < nList.getLength(); i++) {
             if (nList.item(i).getTextContent().contains(EXI_1_0_CAPABILITY_MARKER)) {
@@ -113,21 +115,32 @@ public class NetconfClientSessionNegotiator extends
         return false;
     }
 
-    private long extractSessionId(Document doc) {
-        final Node sessionIdNode = (Node) XmlUtil.evaluateXPath(sessionIdXPath, doc, XPathConstants.NODE);
-        String textContent = sessionIdNode.getTextContent();
-        if (textContent == null || textContent.equals("")) {
-            throw new IllegalStateException("Session id not received from server");
+    private static long extractSessionId(final Document doc) {
+        String textContent = getSessionIdWithXPath(doc, sessionIdXPath);
+        if (Strings.isNullOrEmpty(textContent)) {
+            textContent = getSessionIdWithXPath(doc, sessionIdXPathNoNamespace);
+            if (Strings.isNullOrEmpty(textContent)) {
+                throw new IllegalStateException("Session id not received from server, hello message: " + XmlUtil.toString(doc));
+            }
         }
 
         return Long.valueOf(textContent);
     }
 
+    private static String getSessionIdWithXPath(final Document doc, final XPathExpression sessionIdXPath) {
+        final Node sessionIdNode = (Node) XmlUtil.evaluateXPath(sessionIdXPath, doc, XPathConstants.NODE);
+        return sessionIdNode != null ? sessionIdNode.getTextContent() : null;
+    }
+
     @Override
-    protected NetconfClientSession getSession(NetconfClientSessionListener sessionListener, Channel channel,
-            NetconfHelloMessage message) throws NetconfDocumentedException {
+    protected NetconfClientSession getSession(final NetconfClientSessionListener sessionListener, final Channel channel,
+            final NetconfHelloMessage message) throws NetconfDocumentedException {
         long sessionId = extractSessionId(message.getDocument());
-        Collection<String> capabilities = NetconfMessageUtil.extractCapabilitiesFromHello(message.getDocument());
+
+        // Copy here is important: it disconnects the strings from the document
+        Collection<String> capabilities = ImmutableList.copyOf(NetconfMessageUtil.extractCapabilitiesFromHello(message.getDocument()));
+
+        // FIXME: scalability: we could instantiate a cache to share the same collections
         return new NetconfClientSession(sessionListener, channel, sessionId, capabilities);
     }
 
@@ -138,41 +151,40 @@ public class NetconfClientSessionNegotiator extends
         private static final String EXI_CONFIRMED_HANDLER = "exiConfirmedHandler";
 
         private final NetconfClientSession session;
-        private NetconfStartExiMessage startExiMessage;
+        private final NetconfStartExiMessage startExiMessage;
 
-        ExiConfirmationInboundHandler(NetconfClientSession session, final NetconfStartExiMessage startExiMessage) {
+        ExiConfirmationInboundHandler(final NetconfClientSession session, final NetconfStartExiMessage startExiMessage) {
             this.session = session;
             this.startExiMessage = startExiMessage;
         }
 
         @Override
-        public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception {
+        public void channelRead(final ChannelHandlerContext ctx, final Object msg) throws Exception {
             ctx.pipeline().remove(ExiConfirmationInboundHandler.EXI_CONFIRMED_HANDLER);
 
             NetconfMessage netconfMessage = (NetconfMessage) msg;
 
             // Ok response to start-exi, try to add exi handlers
             if (NetconfMessageUtil.isOKMessage(netconfMessage)) {
-                logger.trace("Positive response on start-exi call received on session {}", session);
+                LOG.trace("Positive response on start-exi call received on session {}", session);
                 try {
                     session.startExiCommunication(startExiMessage);
                 } catch (RuntimeException e) {
                     // Unable to add exi, continue without exi
-                    logger.warn("Unable to start exi communication, Communication will continue without exi on session {}", session, e);
+                    LOG.warn("Unable to start exi communication, Communication will continue without exi on session {}", session, e);
                 }
 
                 // Error response
             } else if(NetconfMessageUtil.isErrorMessage(netconfMessage)) {
-                logger.warn(
+                LOG.warn(
                         "Error response to start-exi message {}, Communication will continue without exi on session {}",
-                        XmlUtil.toString(netconfMessage.getDocument()), session);
+                        netconfMessage, session);
 
                 // Unexpected response to start-exi, throwing message away, continue without exi
             } else {
-                logger.warn(
-                        "Unexpected response to start-exi message, should be ok, was {}, " +
-                                "Communication will continue without exi and response message will be thrown away on session {}",
-                        XmlUtil.toString(netconfMessage.getDocument()), session);
+                LOG.warn("Unexpected response to start-exi message, should be ok, was {}, " +
+                         "Communication will continue without exi and response message will be thrown away on session {}",
+                         netconfMessage, session);
             }
 
             negotiationSuccessful(session);