5d29e4be860852d65ba17538ce1558775f8dd964
[openflowjava.git] / openflow-protocol-impl / src / main / java / org / opendaylight / openflowjava / protocol / impl / core / PublishingChannelInitializer.java
1 /*
2  * Copyright (c) 2013 Pantheon Technologies s.r.o. 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
9 package org.opendaylight.openflowjava.protocol.impl.core;
10
11 import io.netty.channel.Channel;
12 import io.netty.channel.ChannelInitializer;
13 import io.netty.channel.group.DefaultChannelGroup;
14 import io.netty.channel.socket.SocketChannel;
15 import io.netty.handler.ssl.SslHandler;
16
17 import java.net.InetAddress;
18 import java.util.Iterator;
19 import java.util.concurrent.TimeUnit;
20
21 import javax.net.ssl.SSLEngine;
22
23 import org.opendaylight.openflowjava.protocol.api.connection.SwitchConnectionHandler;
24 import org.opendaylight.openflowjava.protocol.api.connection.TlsConfiguration;
25 import org.opendaylight.openflowjava.protocol.impl.connection.ConnectionAdapterFactory;
26 import org.opendaylight.openflowjava.protocol.impl.connection.ConnectionAdapterFactoryImpl;
27 import org.opendaylight.openflowjava.protocol.impl.connection.ConnectionFacade;
28 import org.opendaylight.openflowjava.protocol.impl.deserialization.DeserializationFactory;
29 import org.opendaylight.openflowjava.protocol.impl.serialization.SerializationFactory;
30 import org.slf4j.Logger;
31 import org.slf4j.LoggerFactory;
32
33 /**
34  * Initializes the channel
35  * @author michal.polkorab
36  */
37 public class PublishingChannelInitializer extends ChannelInitializer<SocketChannel> {
38
39     /**
40      * Enum used for storing names of used components (in pipeline).
41      */
42     public static enum COMPONENT_NAMES {
43
44         /**
45          * Detects switch idle state
46          */
47         IDLE_HANDLER,
48         /**
49          * Detects TLS connections
50          */
51         TLS_DETECTOR,
52         /**
53          * Component for handling TLS frames
54          */
55         SSL_HANDLER,
56         /**
57          * Decodes incoming messages into message frames
58          */
59         OF_FRAME_DECODER,
60         /**
61          * Detects version of incoming OpenFlow Protocol message
62          */
63         OF_VERSION_DETECTOR,
64         /**
65          * Transforms OpenFlow Protocol byte messages into POJOs
66          */
67         OF_DECODER,
68         /**
69          * Transforms POJOs into OpenFlow Protocol byte messages
70          */
71         OF_ENCODER,
72         /**
73          * Delegates translated POJOs into MessageConsumer
74          */
75         DELEGATING_INBOUND_HANDLER,
76     }
77
78     private static final Logger LOGGER = LoggerFactory
79             .getLogger(PublishingChannelInitializer.class);
80     private final DefaultChannelGroup allChannels;
81     private SwitchConnectionHandler switchConnectionHandler;
82     private long switchIdleTimeout;
83     private SerializationFactory serializationFactory;
84     private DeserializationFactory deserializationFactory;
85     private ConnectionAdapterFactory connectionAdapterFactory;
86     private TlsConfiguration tlsConfiguration ;
87
88     /**
89      * default ctor
90      */
91     public PublishingChannelInitializer() {
92         this( new DefaultChannelGroup("netty-receiver", null), new ConnectionAdapterFactoryImpl() );
93     }
94
95     /**
96      * Testing Constructor
97      * 
98      */
99     protected PublishingChannelInitializer( DefaultChannelGroup channelGroup, ConnectionAdapterFactory connAdaptorFactory ) {
100         allChannels = channelGroup ;
101         connectionAdapterFactory = connAdaptorFactory ;
102     }
103     
104     @Override
105     protected void initChannel(final SocketChannel ch) {
106         InetAddress switchAddress = ch.remoteAddress().getAddress();
107         int port = ch.localAddress().getPort();
108         int remotePort = ch.remoteAddress().getPort();
109         LOGGER.info("Incoming connection from (remote address): " + switchAddress.toString()
110                 + ":" + remotePort + " --> :" + port);
111         if (!switchConnectionHandler.accept(switchAddress)) {
112             ch.disconnect();
113             LOGGER.info("Incoming connection rejected");
114             return;
115         }
116         LOGGER.info("Incoming connection accepted - building pipeline");
117         allChannels.add(ch);
118         ConnectionFacade connectionFacade = null;
119         connectionFacade = connectionAdapterFactory.createConnectionFacade(ch);
120         try {
121             LOGGER.debug("calling plugin: " + switchConnectionHandler);
122             switchConnectionHandler.onSwitchConnected(connectionFacade);
123             connectionFacade.checkListeners();
124             ch.pipeline().addLast(COMPONENT_NAMES.IDLE_HANDLER.name(), new IdleHandler(switchIdleTimeout, TimeUnit.MILLISECONDS));
125             
126             // If this channel is configured to support SSL it will only support SSL
127             if (tlsConfiguration != null) {
128                 SslContextFactory sslFactory = new SslContextFactory(tlsConfiguration);
129                 SSLEngine engine = sslFactory.getServerContext().createSSLEngine();
130                 engine.setNeedClientAuth(true);
131                 engine.setUseClientMode(false);
132                 ch.pipeline().addLast(COMPONENT_NAMES.SSL_HANDLER.name(), new SslHandler(engine));
133             }
134             ch.pipeline().addLast(COMPONENT_NAMES.OF_FRAME_DECODER.name(), new OFFrameDecoder(connectionFacade));
135             ch.pipeline().addLast(COMPONENT_NAMES.OF_VERSION_DETECTOR.name(), new OFVersionDetector());
136             OFDecoder ofDecoder = new OFDecoder();
137             ofDecoder.setDeserializationFactory(deserializationFactory);
138             ch.pipeline().addLast(COMPONENT_NAMES.OF_DECODER.name(), ofDecoder);
139             OFEncoder ofEncoder = new OFEncoder();
140             ofEncoder.setSerializationFactory(serializationFactory);
141             ch.pipeline().addLast(COMPONENT_NAMES.OF_ENCODER.name(), ofEncoder);
142             ch.pipeline().addLast(COMPONENT_NAMES.DELEGATING_INBOUND_HANDLER.name(), new DelegatingInboundHandler(connectionFacade));
143             if (tlsConfiguration == null) {
144                 connectionFacade.fireConnectionReadyNotification();
145             }
146         } catch (Exception e) {
147             LOGGER.error("Failed to initialize channel", e);
148             ch.close();
149         }
150     }
151
152     /**
153      * @return iterator through active connections
154      */
155     public Iterator<Channel> getConnectionIterator() {
156         return allChannels.iterator();
157     }
158
159     /**
160      * @return amount of active channels
161      */
162     public int size() {
163         return allChannels.size();
164     }
165
166     /**
167      * @param switchConnectionHandler the switchConnectionHandler to set
168      */
169     public void setSwitchConnectionHandler(final SwitchConnectionHandler switchConnectionHandler) {
170         this.switchConnectionHandler = switchConnectionHandler;
171     }
172
173     /**
174      * @param switchIdleTimeout the switchIdleTimeout to set
175      */
176     public void setSwitchIdleTimeout(final long switchIdleTimeout) {
177         this.switchIdleTimeout = switchIdleTimeout;
178     }
179
180     /**
181      * @param serializationFactory
182      */
183     public void setSerializationFactory(final SerializationFactory serializationFactory) {
184         this.serializationFactory = serializationFactory;
185     }
186
187     /**
188      * @param deserializationFactory
189      */
190     public void setDeserializationFactory(final DeserializationFactory deserializationFactory) {
191         this.deserializationFactory = deserializationFactory;
192     }
193
194     /**
195      * @param tlsConfiguration
196      */
197     public void setTlsConfiguration(TlsConfiguration tlsConfiguration) {
198         this.tlsConfiguration = tlsConfiguration;
199     }
200 }