X-Git-Url: https://git.opendaylight.org/gerrit/gitweb?a=blobdiff_plain;f=opendaylight%2Fnetconf%2Fnetconf-util%2Fsrc%2Fmain%2Fjava%2Forg%2Fopendaylight%2Fcontroller%2Fnetconf%2Futil%2FAbstractNetconfSessionNegotiator.java;h=7f2d8c30f045fb6830458aa7fd461cc7885e8349;hb=b925756421ea8565637d8575d8143dbf46db5a86;hp=9986b82bd8d6902a084e77a1a11a6421125ccb17;hpb=2e7347fdc0eb7734ff59a4f902227a93ab6afece;p=controller.git
diff --git a/opendaylight/netconf/netconf-util/src/main/java/org/opendaylight/controller/netconf/util/AbstractNetconfSessionNegotiator.java b/opendaylight/netconf/netconf-util/src/main/java/org/opendaylight/controller/netconf/util/AbstractNetconfSessionNegotiator.java
index 9986b82bd8..7f2d8c30f0 100644
--- a/opendaylight/netconf/netconf-util/src/main/java/org/opendaylight/controller/netconf/util/AbstractNetconfSessionNegotiator.java
+++ b/opendaylight/netconf/netconf-util/src/main/java/org/opendaylight/controller/netconf/util/AbstractNetconfSessionNegotiator.java
@@ -8,19 +8,30 @@
package org.opendaylight.controller.netconf.util;
+import io.netty.channel.Channel;
+import io.netty.channel.ChannelHandler;
+import io.netty.channel.ChannelHandlerContext;
+import io.netty.handler.ssl.SslHandler;
+import io.netty.util.Timeout;
+import io.netty.util.Timer;
+import io.netty.util.TimerTask;
+import io.netty.util.concurrent.Future;
+import io.netty.util.concurrent.GenericFutureListener;
+import io.netty.util.concurrent.Promise;
+
import java.util.concurrent.TimeUnit;
+import io.netty.channel.ChannelInboundHandlerAdapter;
import org.opendaylight.controller.netconf.api.AbstractNetconfSession;
import org.opendaylight.controller.netconf.api.NetconfMessage;
import org.opendaylight.controller.netconf.api.NetconfSessionListener;
import org.opendaylight.controller.netconf.api.NetconfSessionPreferences;
import org.opendaylight.controller.netconf.util.handler.FramingMechanismHandlerFactory;
-import org.opendaylight.controller.netconf.util.messages.NetconfHelloMessage;
-import org.opendaylight.controller.netconf.util.handler.NetconfMessageAggregator;
-import org.opendaylight.controller.netconf.util.handler.NetconfMessageChunkDecoder;
+import org.opendaylight.controller.netconf.util.handler.NetconfChunkAggregator;
import org.opendaylight.controller.netconf.util.handler.NetconfMessageToXMLEncoder;
import org.opendaylight.controller.netconf.util.handler.NetconfXMLToMessageDecoder;
import org.opendaylight.controller.netconf.util.messages.FramingMechanism;
+import org.opendaylight.controller.netconf.util.messages.NetconfHelloMessage;
import org.opendaylight.controller.netconf.util.xml.XmlUtil;
import org.opendaylight.protocol.framework.AbstractSessionNegotiator;
import org.slf4j.Logger;
@@ -31,25 +42,13 @@ import org.w3c.dom.NodeList;
import com.google.common.base.Optional;
import com.google.common.base.Preconditions;
-import io.netty.channel.Channel;
-import io.netty.channel.ChannelHandler;
-import io.netty.channel.ChannelHandlerContext;
-import io.netty.handler.ssl.SslHandler;
-import io.netty.util.Timeout;
-import io.netty.util.Timer;
-import io.netty.util.TimerTask;
-import io.netty.util.concurrent.Future;
-import io.netty.util.concurrent.GenericFutureListener;
-import io.netty.util.concurrent.Promise;
-
public abstract class AbstractNetconfSessionNegotiator
, L extends NetconfSessionListener>
extends AbstractSessionNegotiator {
private static final Logger logger = LoggerFactory.getLogger(AbstractNetconfSessionNegotiator.class);
public static final String NAME_OF_EXCEPTION_HANDLER = "lastExceptionHandler";
- public static final String CHUNK_DECODER_CHANNEL_HANDLER_KEY = "chunkDecoder";
- protected final P sessionPreferences;
+ private final P sessionPreferences;
private final L sessionListener;
private Timeout timeout;
@@ -81,14 +80,15 @@ extends AbstractSessionNegotiator {
Future future = sslHandler.get().handshakeFuture();
future.addListener(new GenericFutureListener>() {
@Override
- public void operationComplete(Future super Channel> future) throws Exception {
+ public void operationComplete(Future super Channel> future) {
Preconditions.checkState(future.isSuccess(), "Ssl handshake was not successful");
logger.debug("Ssl handshake complete");
start();
}
});
- } else
+ } else {
start();
+ }
}
private static Optional getSslHandler(Channel channel) {
@@ -96,31 +96,19 @@ extends AbstractSessionNegotiator {
return sslHandler == null ? Optional. absent() : Optional.of(sslHandler);
}
+ public P getSessionPreferences() {
+ return sessionPreferences;
+ }
+
private void start() {
final NetconfMessage helloMessage = this.sessionPreferences.getHelloMessage();
logger.debug("Session negotiation started with hello message {}", XmlUtil.toString(helloMessage.getDocument()));
- channel.pipeline().addLast(NAME_OF_EXCEPTION_HANDLER, new ChannelHandler() {
- @Override
- public void handlerAdded(ChannelHandlerContext ctx) throws Exception {
- }
-
- @Override
- public void handlerRemoved(ChannelHandlerContext ctx) throws Exception {
- }
-
- @Override
- public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) throws Exception {
- logger.warn("An exception occurred during negotiation on channel {}", channel.localAddress(), cause);
- cancelTimeout();
- negotiationFailed(cause);
- changeState(State.FAILED);
- }
- });
+ channel.pipeline().addLast(NAME_OF_EXCEPTION_HANDLER, new ExceptionHandlingInboundChannelHandler());
timeout = this.timer.newTimeout(new TimerTask() {
@Override
- public void run(final Timeout timeout) throws Exception {
+ public void run(final Timeout timeout) {
synchronized (this) {
if (state != State.ESTABLISHED) {
logger.debug("Connection timeout after {}, session is in state {}", timeout, state);
@@ -140,8 +128,9 @@ extends AbstractSessionNegotiator {
}
private void cancelTimeout() {
- if(timeout!=null)
+ if(timeout!=null) {
timeout.cancel();
+ }
}
private void sendMessage(NetconfMessage message) {
@@ -150,27 +139,20 @@ extends AbstractSessionNegotiator {
@Override
protected void handleMessage(NetconfHelloMessage netconfMessage) {
- final Document doc = netconfMessage.getDocument();
+ Preconditions.checkNotNull(netconfMessage != null, "netconfMessage");
- // Only Hello message should arrive during negotiation
- if (netconfMessage instanceof NetconfHelloMessage) {
+ final Document doc = netconfMessage.getDocument();
- replaceHelloMessageHandlers();
+ replaceHelloMessageHandlers();
- if (shouldUseChunkFraming(doc)) {
- insertChunkFramingToPipeline();
- }
+ if (shouldUseChunkFraming(doc)) {
+ insertChunkFramingToPipeline();
+ }
- changeState(State.ESTABLISHED);
- S session = getSession(sessionListener, channel, (NetconfHelloMessage)netconfMessage);
+ changeState(State.ESTABLISHED);
+ S session = getSession(sessionListener, channel, netconfMessage);
- negotiationSuccessful(session);
- } else {
- final IllegalStateException cause = new IllegalStateException(
- "Received message was not hello as expected, but was " + XmlUtil.toString(doc));
- logger.warn("Negotiation of netconf session failed", cause);
- negotiationFailed(cause);
- }
+ negotiationSuccessful(session);
}
/**
@@ -180,9 +162,7 @@ extends AbstractSessionNegotiator {
replaceChannelHandler(channel, AbstractChannelInitializer.NETCONF_MESSAGE_FRAME_ENCODER,
FramingMechanismHandlerFactory.createHandler(FramingMechanism.CHUNK));
replaceChannelHandler(channel, AbstractChannelInitializer.NETCONF_MESSAGE_AGGREGATOR,
- new NetconfMessageAggregator(FramingMechanism.CHUNK));
- channel.pipeline().addAfter(AbstractChannelInitializer.NETCONF_MESSAGE_AGGREGATOR,
- CHUNK_DECODER_CHANNEL_HANDLER_KEY, new NetconfMessageChunkDecoder());
+ new NetconfChunkAggregator());
}
private boolean shouldUseChunkFraming(Document doc) {
@@ -222,14 +202,31 @@ extends AbstractSessionNegotiator {
}
private static boolean isStateChangePermitted(State state, State newState) {
- if (state == State.IDLE && newState == State.OPEN_WAIT)
+ if (state == State.IDLE && newState == State.OPEN_WAIT) {
return true;
- if (state == State.OPEN_WAIT && newState == State.ESTABLISHED)
+ }
+ if (state == State.OPEN_WAIT && newState == State.ESTABLISHED) {
return true;
- if (state == State.OPEN_WAIT && newState == State.FAILED)
+ }
+ if (state == State.OPEN_WAIT && newState == State.FAILED) {
return true;
+ }
logger.debug("Transition from {} to {} is not allowed", state, newState);
return false;
}
+
+ /**
+ * Handler to catch exceptions in pipeline during negotiation
+ */
+ private final class ExceptionHandlingInboundChannelHandler extends ChannelInboundHandlerAdapter {
+
+ @Override
+ public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) {
+ logger.warn("An exception occurred during negotiation on channel {}", channel.localAddress(), cause);
+ cancelTimeout();
+ negotiationFailed(cause);
+ changeState(State.FAILED);
+ }
+ }
}