d65a623a63b12a30a082f230d7d8849b31f77ccb
[openflowjava.git] / openflow-protocol-impl / src / main / java / org / opendaylight / openflowjava / protocol / impl / core / SwitchConnectionProviderImpl.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
10 package org.opendaylight.openflowjava.protocol.impl.core;
11
12 import com.google.common.util.concurrent.ListenableFuture;
13 import com.google.common.util.concurrent.SettableFuture;
14 import io.netty.channel.EventLoopGroup;
15 import io.netty.channel.epoll.Epoll;
16 import org.opendaylight.openflowjava.protocol.api.connection.ConnectionConfiguration;
17 import org.opendaylight.openflowjava.protocol.api.connection.SwitchConnectionHandler;
18 import org.opendaylight.openflowjava.protocol.api.extensibility.DeserializerRegistry;
19 import org.opendaylight.openflowjava.protocol.api.extensibility.OFDeserializer;
20 import org.opendaylight.openflowjava.protocol.api.extensibility.OFGeneralDeserializer;
21 import org.opendaylight.openflowjava.protocol.api.extensibility.OFGeneralSerializer;
22 import org.opendaylight.openflowjava.protocol.api.extensibility.OFSerializer;
23 import org.opendaylight.openflowjava.protocol.api.extensibility.SerializerRegistry;
24 import org.opendaylight.openflowjava.protocol.api.keys.ActionSerializerKey;
25 import org.opendaylight.openflowjava.protocol.api.keys.ExperimenterActionDeserializerKey;
26 import org.opendaylight.openflowjava.protocol.api.keys.ExperimenterDeserializerKey;
27 import org.opendaylight.openflowjava.protocol.api.keys.ExperimenterIdDeserializerKey;
28 import org.opendaylight.openflowjava.protocol.api.keys.ExperimenterIdMeterSubTypeSerializerKey;
29 import org.opendaylight.openflowjava.protocol.api.keys.ExperimenterIdSerializerKey;
30 import org.opendaylight.openflowjava.protocol.api.keys.ExperimenterInstructionDeserializerKey;
31 import org.opendaylight.openflowjava.protocol.api.keys.ExperimenterSerializerKey;
32 import org.opendaylight.openflowjava.protocol.api.keys.InstructionSerializerKey;
33 import org.opendaylight.openflowjava.protocol.api.keys.MatchEntryDeserializerKey;
34 import org.opendaylight.openflowjava.protocol.api.keys.MatchEntrySerializerKey;
35 import org.opendaylight.openflowjava.protocol.api.keys.MessageCodeKey;
36 import org.opendaylight.openflowjava.protocol.api.keys.MessageTypeKey;
37 import org.opendaylight.openflowjava.protocol.impl.deserialization.DeserializationFactory;
38 import org.opendaylight.openflowjava.protocol.impl.deserialization.DeserializerRegistryImpl;
39 import org.opendaylight.openflowjava.protocol.impl.serialization.SerializationFactory;
40 import org.opendaylight.openflowjava.protocol.impl.serialization.SerializerRegistryImpl;
41 import org.opendaylight.openflowjava.protocol.spi.connection.SwitchConnectionProvider;
42 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.config.rev140630.TransportProtocol;
43 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.oxm.rev150225.MatchField;
44 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.oxm.rev150225.OxmClassBase;
45 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.ErrorMessage;
46 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.experimenter.core.ExperimenterDataOfChoice;
47 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.meter.band.header.meter.band.MeterBandExperimenterCase;
48 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.queue.property.header.QueueProperty;
49 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.table.features.properties.grouping.TableFeatureProperties;
50 import org.slf4j.Logger;
51 import org.slf4j.LoggerFactory;
52
53 /**
54  * Exposed class for server handling<br>
55  * C - {@link MatchEntrySerializerKey} parameter representing oxm_class (see specification)<br>
56  * F - {@link MatchEntrySerializerKey} parameter representing oxm_field (see specification)
57  * @author mirehak
58  * @author michal.polkorab
59  */
60 public class SwitchConnectionProviderImpl implements SwitchConnectionProvider, ConnectionInitializer {
61
62     private static final Logger LOG = LoggerFactory
63             .getLogger(SwitchConnectionProviderImpl.class);
64     private SwitchConnectionHandler switchConnectionHandler;
65     private ServerFacade serverFacade;
66     private ConnectionConfiguration connConfig;
67     private final SerializationFactory serializationFactory;
68     private final SerializerRegistry serializerRegistry;
69     private final DeserializerRegistry deserializerRegistry;
70     private final DeserializationFactory deserializationFactory;
71     private TcpConnectionInitializer connectionInitializer;
72
73     /** Constructor */
74     public SwitchConnectionProviderImpl() {
75         serializerRegistry = new SerializerRegistryImpl();
76         serializerRegistry.init();
77         serializationFactory = new SerializationFactory();
78         serializationFactory.setSerializerTable(serializerRegistry);
79         deserializerRegistry = new DeserializerRegistryImpl();
80         deserializerRegistry.init();
81         deserializationFactory = new DeserializationFactory();
82         deserializationFactory.setRegistry(deserializerRegistry);
83     }
84
85     @Override
86     public void setConfiguration(final ConnectionConfiguration connConfig) {
87         this.connConfig = connConfig;
88     }
89
90     @Override
91     public void setSwitchConnectionHandler(final SwitchConnectionHandler switchConnectionHandler) {
92         LOG.debug("setSwitchConnectionHandler");
93         this.switchConnectionHandler = switchConnectionHandler;
94     }
95
96     @Override
97     public ListenableFuture<Boolean> shutdown() {
98         LOG.debug("Shutdown summoned");
99         if(serverFacade == null){
100             LOG.warn("Can not shutdown - not configured or started");
101             throw new IllegalStateException("SwitchConnectionProvider is not started or not configured.");
102         }
103         return serverFacade.shutdown();
104     }
105
106     @Override
107     public ListenableFuture<Boolean> startup() {
108         LOG.debug("Startup summoned");
109         ListenableFuture<Boolean> result = null;
110         try {
111             serverFacade = createAndConfigureServer();
112             if (switchConnectionHandler == null) {
113                 throw new IllegalStateException("SwitchConnectionHandler is not set");
114             }
115             new Thread(serverFacade).start();
116             result = serverFacade.getIsOnlineFuture();
117         } catch (final Exception e) {
118             final SettableFuture<Boolean> exResult = SettableFuture.create();
119             exResult.setException(e);
120             result = exResult;
121         }
122         return result;
123     }
124
125     /**
126      * @return
127      */
128     private ServerFacade createAndConfigureServer() {
129         LOG.debug("Configuring ..");
130         ServerFacade server = null;
131         final ChannelInitializerFactory factory = new ChannelInitializerFactory();
132         factory.setSwitchConnectionHandler(switchConnectionHandler);
133         factory.setSwitchIdleTimeout(connConfig.getSwitchIdleTimeout());
134         factory.setTlsConfig(connConfig.getTlsConfiguration());
135         factory.setSerializationFactory(serializationFactory);
136         factory.setDeserializationFactory(deserializationFactory);
137         factory.setUseBarrier(connConfig.useBarrier());
138         final TransportProtocol transportProtocol = (TransportProtocol) connConfig.getTransferProtocol();
139
140         // Check if Epoll native transport is available.
141         // TODO : Add option to disable Epoll.
142         boolean isEpollEnabled = Epoll.isAvailable();
143
144         if (transportProtocol.equals(TransportProtocol.TCP) || transportProtocol.equals(TransportProtocol.TLS)) {
145             server = new TcpHandler(connConfig.getAddress(), connConfig.getPort());
146             final TcpChannelInitializer channelInitializer = factory.createPublishingChannelInitializer();
147             ((TcpHandler) server).setChannelInitializer(channelInitializer);
148             ((TcpHandler) server).initiateEventLoopGroups(connConfig.getThreadConfiguration(), isEpollEnabled);
149
150             final EventLoopGroup workerGroupFromTcpHandler = ((TcpHandler) server).getWorkerGroup();
151             connectionInitializer = new TcpConnectionInitializer(workerGroupFromTcpHandler, isEpollEnabled);
152             connectionInitializer.setChannelInitializer(channelInitializer);
153             connectionInitializer.run();
154         } else if (transportProtocol.equals(TransportProtocol.UDP)){
155             server = new UdpHandler(connConfig.getAddress(), connConfig.getPort());
156             ((UdpHandler) server).initiateEventLoopGroups(connConfig.getThreadConfiguration(), isEpollEnabled);
157             ((UdpHandler) server).setChannelInitializer(factory.createUdpChannelInitializer());
158         } else {
159             throw new IllegalStateException("Unknown transport protocol received: " + transportProtocol);
160         }
161         server.setThreadConfig(connConfig.getThreadConfiguration());
162         return server;
163     }
164
165     /**
166      * @return servers
167      */
168     public ServerFacade getServerFacade() {
169         return serverFacade;
170     }
171
172     @Override
173     public void close() throws Exception {
174         shutdown();
175     }
176
177     @Override
178     public boolean unregisterSerializer(final ExperimenterSerializerKey key) {
179         return serializerRegistry.unregisterSerializer((MessageTypeKey<?>) key);
180     }
181
182     @Override
183     public boolean unregisterDeserializer(final ExperimenterDeserializerKey key) {
184         return deserializerRegistry.unregisterDeserializer((MessageCodeKey) key);
185     }
186
187     @Override
188     public void registerActionSerializer(final ActionSerializerKey<?> key,
189             final OFGeneralSerializer serializer) {
190         serializerRegistry.registerSerializer(key, serializer);
191     }
192
193     @Override
194     public void registerActionDeserializer(final ExperimenterActionDeserializerKey key,
195             final OFGeneralDeserializer deserializer) {
196         deserializerRegistry.registerDeserializer(key, deserializer);
197     }
198
199     @Override
200     public void registerInstructionSerializer(final InstructionSerializerKey<?> key,
201             final OFGeneralSerializer serializer) {
202         serializerRegistry.registerSerializer(key, serializer);
203     }
204
205     @Override
206     public void registerInstructionDeserializer(final ExperimenterInstructionDeserializerKey key,
207             final OFGeneralDeserializer deserializer) {
208         deserializerRegistry.registerDeserializer(key, deserializer);
209     }
210
211     @Override
212     public <C extends OxmClassBase, F extends MatchField> void registerMatchEntrySerializer(final MatchEntrySerializerKey<C, F> key,
213             final OFGeneralSerializer serializer) {
214         serializerRegistry.registerSerializer(key, serializer);
215     }
216
217     @Override
218     public void registerMatchEntryDeserializer(final MatchEntryDeserializerKey key,
219             final OFGeneralDeserializer deserializer) {
220         deserializerRegistry.registerDeserializer(key, deserializer);
221     }
222
223     @Override
224     public void registerErrorDeserializer(final ExperimenterIdDeserializerKey key,
225             final OFDeserializer<ErrorMessage> deserializer) {
226         deserializerRegistry.registerDeserializer(key, deserializer);
227     }
228
229     @Override
230     public void registerExperimenterMessageDeserializer(ExperimenterIdDeserializerKey key,
231                                                         OFDeserializer<? extends ExperimenterDataOfChoice> deserializer) {
232         deserializerRegistry.registerDeserializer(key, deserializer);
233     }
234
235     @Override
236     public void registerMultipartReplyMessageDeserializer(ExperimenterIdDeserializerKey key,
237                                                           OFDeserializer<? extends ExperimenterDataOfChoice> deserializer) {
238         deserializerRegistry.registerDeserializer(key, deserializer);
239     }
240
241     @Override
242     public void registerMultipartReplyTFDeserializer(final ExperimenterIdDeserializerKey key,
243             final OFGeneralDeserializer deserializer) {
244         deserializerRegistry.registerDeserializer(key, deserializer);
245     }
246
247     @Override
248     public void registerQueuePropertyDeserializer(final ExperimenterIdDeserializerKey key,
249             final OFDeserializer<QueueProperty> deserializer) {
250         deserializerRegistry.registerDeserializer(key, deserializer);
251     }
252
253     @Override
254     public void registerMeterBandDeserializer(final ExperimenterIdDeserializerKey key,
255             final OFDeserializer<MeterBandExperimenterCase> deserializer) {
256         deserializerRegistry.registerDeserializer(key, deserializer);
257     }
258
259     @Override
260     public void registerExperimenterMessageSerializer(ExperimenterIdSerializerKey<? extends ExperimenterDataOfChoice> key,
261                                                       OFSerializer<? extends ExperimenterDataOfChoice> serializer) {
262         serializerRegistry.registerSerializer(key, serializer);
263     }
264
265     @Override
266     public void registerMultipartRequestSerializer(ExperimenterIdSerializerKey<? extends ExperimenterDataOfChoice> key,
267                                                    OFSerializer<? extends ExperimenterDataOfChoice> serializer) {
268         serializerRegistry.registerSerializer(key, serializer);
269     }
270
271     @Override
272     public void registerMultipartRequestTFSerializer(final ExperimenterIdSerializerKey<TableFeatureProperties> key,
273             final OFGeneralSerializer serializer) {
274         serializerRegistry.registerSerializer(key, serializer);
275     }
276
277     @Override
278     /**
279      * @deprecated Since we have used ExperimenterIdMeterSubTypeSerializerKey as MeterBandSerializer's key, in order to avoid
280      * the occurrence of an error, we should discard this function
281      */
282     @Deprecated
283     public void registerMeterBandSerializer(final ExperimenterIdSerializerKey<MeterBandExperimenterCase> key,
284             final OFSerializer<MeterBandExperimenterCase> serializer) {
285         serializerRegistry.registerSerializer(key, serializer);
286     }
287
288     @Override
289     public void registerMeterBandSerializer(final ExperimenterIdMeterSubTypeSerializerKey<MeterBandExperimenterCase> key,
290                                             final OFSerializer<MeterBandExperimenterCase> serializer) {
291         serializerRegistry.registerSerializer(key, serializer);
292     }
293
294     @Override
295     public void initiateConnection(final String host, final int port) {
296         connectionInitializer.initiateConnection(host, port);
297     }
298
299     @Override
300     public ConnectionConfiguration getConfiguration() {
301         return this.connConfig;
302     }
303
304      @Override
305     public <K> void registerSerializer(MessageTypeKey<K> key, OFGeneralSerializer serializer) {
306         serializerRegistry.registerSerializer(key, serializer);
307     }
308
309     @Override
310     public void registerDeserializer(MessageCodeKey key, OFGeneralDeserializer deserializer) {
311        deserializerRegistry.registerDeserializer(key, deserializer);
312     }
313 }