Merge "Bug 2820 - LLDP TLV support and testing"
[controller.git] / opendaylight / netconf / netconf-impl / src / main / java / org / opendaylight / controller / netconf / impl / NetconfServerSession.java
index 7d409092b9178bcd2816c96371108930f200fe3a..4368f7ec7940152ef038a1b4320dbc3c858732cf 100644 (file)
@@ -10,15 +10,17 @@ package org.opendaylight.controller.netconf.impl;
 
 import com.google.common.base.Preconditions;
 import io.netty.channel.Channel;
+import io.netty.channel.ChannelFuture;
+import io.netty.channel.ChannelFutureListener;
+import io.netty.handler.codec.ByteToMessageDecoder;
+import io.netty.handler.codec.MessageToByteEncoder;
 import java.text.SimpleDateFormat;
 import java.util.Date;
 import java.util.regex.Matcher;
 import java.util.regex.Pattern;
+import org.opendaylight.controller.netconf.api.NetconfMessage;
 import org.opendaylight.controller.netconf.api.monitoring.NetconfManagementSession;
 import org.opendaylight.controller.netconf.nettyutil.AbstractNetconfSession;
-import org.opendaylight.controller.netconf.nettyutil.handler.NetconfEXICodec;
-import org.opendaylight.controller.netconf.nettyutil.handler.NetconfEXIToMessageDecoder;
-import org.opendaylight.controller.netconf.nettyutil.handler.NetconfMessageToEXIEncoder;
 import org.opendaylight.controller.netconf.nettyutil.handler.NetconfMessageToXMLEncoder;
 import org.opendaylight.controller.netconf.nettyutil.handler.NetconfXMLToMessageDecoder;
 import org.opendaylight.controller.netconf.util.messages.NetconfHelloMessageAdditionalHeader;
@@ -39,25 +41,49 @@ import org.slf4j.LoggerFactory;
 
 public final class NetconfServerSession extends AbstractNetconfSession<NetconfServerSession, NetconfServerSessionListener> implements NetconfManagementSession {
 
-    private static final Logger logger = LoggerFactory.getLogger(NetconfServerSession.class);
+    private static final Logger LOG = LoggerFactory.getLogger(NetconfServerSession.class);
 
     private final NetconfHelloMessageAdditionalHeader header;
 
     private Date loginTime;
     private long inRpcSuccess, inRpcFail, outRpcError;
+    private volatile boolean delayedClose;
 
-    public NetconfServerSession(NetconfServerSessionListener sessionListener, Channel channel, long sessionId,
-            NetconfHelloMessageAdditionalHeader header) {
+    public NetconfServerSession(final NetconfServerSessionListener sessionListener, final Channel channel, final long sessionId,
+            final NetconfHelloMessageAdditionalHeader header) {
         super(sessionListener, channel, sessionId);
         this.header = header;
-        logger.debug("Session {} created", toString());
+        LOG.debug("Session {} created", toString());
     }
 
     @Override
     protected void sessionUp() {
-        super.sessionUp();
         Preconditions.checkState(loginTime == null, "Session is already up");
         this.loginTime = new Date();
+        super.sessionUp();
+    }
+
+    /**
+     * Close this session after next message is sent.
+     * Suitable for close rpc that needs to send ok response before the session is closed.
+     */
+    public void delayedClose() {
+        this.delayedClose = true;
+    }
+
+    @Override
+    public ChannelFuture sendMessage(final NetconfMessage netconfMessage) {
+        final ChannelFuture channelFuture = super.sendMessage(netconfMessage);
+        // delayed close was set, close after the message was sent
+        if(delayedClose) {
+            channelFuture.addListener(new ChannelFutureListener() {
+                @Override
+                public void operationComplete(final ChannelFuture future) throws Exception {
+                    close();
+                }
+            });
+        }
+        return channelFuture;
     }
 
     public void onIncommingRpcSuccess() {
@@ -109,15 +135,18 @@ public final class NetconfServerSession extends AbstractNetconfSession<NetconfSe
         return builder.build();
     }
 
-    private Class<? extends Transport> getTransportForString(String transport) {
+    private Class<? extends Transport> getTransportForString(final String transport) {
         switch(transport) {
-        case "ssh" : return NetconfSsh.class;
-        case "tcp" : return NetconfTcp.class;
-        default: throw new IllegalArgumentException("Unknown transport type " + transport);
+        case "ssh" :
+            return NetconfSsh.class;
+        case "tcp" :
+            return NetconfTcp.class;
+        default:
+            throw new IllegalArgumentException("Unknown transport type " + transport);
         }
     }
 
-    private String formatDateTime(Date loginTime) {
+    private String formatDateTime(final Date loginTime) {
         SimpleDateFormat dateFormat = new SimpleDateFormat(ISO_DATE_FORMAT);
         return dateFormat.format(loginTime);
     }
@@ -128,9 +157,9 @@ public final class NetconfServerSession extends AbstractNetconfSession<NetconfSe
     }
 
     @Override
-    protected void addExiHandlers(NetconfEXICodec exiCodec) {
-        replaceMessageDecoder(new NetconfEXIToMessageDecoder(exiCodec));
-        replaceMessageEncoderAfterNextMessage(new NetconfMessageToEXIEncoder(exiCodec));
+    protected void addExiHandlers(final ByteToMessageDecoder decoder, final MessageToByteEncoder<NetconfMessage> encoder) {
+        replaceMessageDecoder(decoder);
+        replaceMessageEncoderAfterNextMessage(encoder);
     }
 
     @Override