fbbe3428ef59f373d4ccc25e75cb814bf7c79087
[onosfw.git] /
1 /*
2  * Copyright 2014 Open Networking Laboratory
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.onosproject.openflow.controller.impl;
18
19 import java.util.concurrent.TimeUnit;
20
21 import org.jboss.netty.channel.ChannelHandlerContext;
22 import org.jboss.netty.channel.ChannelStateEvent;
23 import org.jboss.netty.channel.Channels;
24 import org.jboss.netty.channel.SimpleChannelUpstreamHandler;
25 import org.jboss.netty.util.Timeout;
26 import org.jboss.netty.util.Timer;
27 import org.jboss.netty.util.TimerTask;
28
29 /**
30  * Trigger a timeout if a switch fails to complete handshake soon enough.
31  */
32 public class HandshakeTimeoutHandler
33     extends SimpleChannelUpstreamHandler {
34     static final HandshakeTimeoutException EXCEPTION =
35             new HandshakeTimeoutException();
36
37     final OFChannelHandler channelHandler;
38     final Timer timer;
39     final long timeoutNanos;
40     volatile Timeout timeout;
41
42     public HandshakeTimeoutHandler(OFChannelHandler channelHandler,
43                                    Timer timer,
44                                    long timeoutSeconds) {
45         super();
46         this.channelHandler = channelHandler;
47         this.timer = timer;
48         this.timeoutNanos = TimeUnit.SECONDS.toNanos(timeoutSeconds);
49
50     }
51
52     @Override
53     public void channelOpen(ChannelHandlerContext ctx, ChannelStateEvent e)
54             throws Exception {
55         if (timeoutNanos > 0) {
56             timeout = timer.newTimeout(new HandshakeTimeoutTask(ctx),
57                                        timeoutNanos, TimeUnit.NANOSECONDS);
58         }
59         ctx.sendUpstream(e);
60     }
61
62     @Override
63     public void channelClosed(ChannelHandlerContext ctx, ChannelStateEvent e)
64             throws Exception {
65         if (timeout != null) {
66             timeout.cancel();
67             timeout = null;
68         }
69     }
70
71     private final class HandshakeTimeoutTask implements TimerTask {
72
73         private final ChannelHandlerContext ctx;
74
75         HandshakeTimeoutTask(ChannelHandlerContext ctx) {
76             this.ctx = ctx;
77         }
78
79         @Override
80         public void run(Timeout t) throws Exception {
81             if (t.isCancelled()) {
82                 return;
83             }
84
85             if (!ctx.getChannel().isOpen()) {
86                 return;
87             }
88             if (!channelHandler.isHandshakeComplete()) {
89                 Channels.fireExceptionCaught(ctx, EXCEPTION);
90             }
91         }
92     }
93 }