b3b8163b60176117edf54bfa2e5d97a11909156b
[bgpcep.git] / pcep / impl / src / main / java / org / opendaylight / protocol / pcep / impl / AbstractSessionNegotiator.java
1 /*
2  * Copyright (c) 2015 Cisco Systems, Inc. and others.  All rights reserved.
3  *
4  * This program and the accompanying materials are made available under the
5  * terms of the Eclipse Public License v1.0 which accompanies this distribution,
6  * and is available at http://www.eclipse.org/legal/epl-v10.html
7  */
8 package org.opendaylight.protocol.pcep.impl;
9
10 import com.google.common.base.Preconditions;
11 import io.netty.channel.Channel;
12 import io.netty.channel.ChannelFuture;
13 import io.netty.channel.ChannelFutureListener;
14 import io.netty.channel.ChannelHandlerContext;
15 import io.netty.channel.ChannelInboundHandlerAdapter;
16 import io.netty.util.concurrent.Promise;
17 import java.util.concurrent.ExecutionException;
18 import org.opendaylight.protocol.pcep.SessionNegotiator;
19 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.types.rev131005.Message;
20 import org.slf4j.Logger;
21 import org.slf4j.LoggerFactory;
22
23 public abstract class AbstractSessionNegotiator extends ChannelInboundHandlerAdapter implements SessionNegotiator {
24     private static final Logger LOG = LoggerFactory.getLogger(AbstractSessionNegotiator.class);
25     protected final Channel channel;
26     protected final Promise<PCEPSessionImpl> promise;
27
28     protected AbstractSessionNegotiator(final Promise<PCEPSessionImpl> promise, final Channel channel) {
29         this.promise = Preconditions.checkNotNull(promise);
30         this.channel = Preconditions.checkNotNull(channel);
31     }
32
33     protected final void negotiationSuccessful(final PCEPSessionImpl session) {
34         LOG.debug("Negotiation on channel {} successful with session {}", this.channel, session);
35         this.channel.pipeline().replace(this, "session", session);
36         this.promise.setSuccess(session);
37     }
38
39     protected void negotiationFailed(final Throwable cause) {
40         LOG.debug("Negotiation on channel {} failed", this.channel, cause);
41         this.channel.close();
42         this.promise.setFailure(cause);
43     }
44
45     protected final void sendMessage(final Message msg) {
46         this.channel.writeAndFlush(msg).addListener((ChannelFutureListener) f -> {
47             if (!f.isSuccess()) {
48                 LOG.info("Failed to send message {}", msg, f.cause());
49                 negotiationFailed(f.cause());
50             } else {
51                 LOG.trace("Message {} sent to socket", msg);
52             }
53
54         });
55     }
56
57     @Override
58     public final void channelActive(final ChannelHandlerContext ctx) {
59         LOG.debug("Starting session negotiation on channel {}", this.channel);
60
61         try {
62             this.startNegotiation();
63         } catch (final Exception e) {
64             LOG.warn("Unexpected negotiation failure", e);
65             this.negotiationFailed(e);
66         }
67
68     }
69
70     @Override
71     public final void channelRead(final ChannelHandlerContext ctx, final Object msg) {
72         LOG.debug("Negotiation read invoked on channel {}", this.channel);
73
74         try {
75             this.handleMessage((Message) msg);
76         } catch (Exception e) {
77             LOG.debug("Unexpected error while handling negotiation message {}", msg, e);
78             this.negotiationFailed(e);
79         }
80
81     }
82
83     @Override
84     public void exceptionCaught(final ChannelHandlerContext ctx, final Throwable cause) {
85         LOG.info("Unexpected error during negotiation", cause);
86         this.negotiationFailed(cause);
87     }
88
89     protected abstract void startNegotiation() throws ExecutionException;
90
91     protected abstract void handleMessage(final Message msg);
92 }