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