Rework OpenFlowPluginProviderImpl connection provider tracking
[openflowplugin.git] / openflowjava / openflow-protocol-it / src / test / java / org / opendaylight / openflowjava / protocol / it / integration / IntegrationTest.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 package org.opendaylight.openflowjava.protocol.it.integration;
9
10 import static org.mockito.ArgumentMatchers.any;
11 import static org.mockito.Mockito.doAnswer;
12 import static org.mockito.Mockito.doReturn;
13 import static org.mockito.Mockito.mock;
14
15 import java.net.InetAddress;
16 import java.util.ArrayList;
17 import java.util.Deque;
18 import java.util.List;
19 import java.util.concurrent.ExecutionException;
20 import java.util.concurrent.ExecutorService;
21 import java.util.concurrent.TimeUnit;
22 import java.util.concurrent.TimeoutException;
23 import org.junit.After;
24 import org.junit.Test;
25 import org.junit.runner.RunWith;
26 import org.mockito.ArgumentMatchers;
27 import org.mockito.Mock;
28 import org.mockito.junit.MockitoJUnitRunner;
29 import org.opendaylight.infrautils.diagstatus.DiagStatusService;
30 import org.opendaylight.infrautils.diagstatus.ServiceRegistration;
31 import org.opendaylight.openflowjava.protocol.api.connection.TlsConfiguration;
32 import org.opendaylight.openflowjava.protocol.api.connection.TlsConfigurationImpl;
33 import org.opendaylight.openflowjava.protocol.impl.clients.ClientEvent;
34 import org.opendaylight.openflowjava.protocol.impl.clients.ListeningSimpleClient;
35 import org.opendaylight.openflowjava.protocol.impl.clients.OFClient;
36 import org.opendaylight.openflowjava.protocol.impl.clients.ScenarioFactory;
37 import org.opendaylight.openflowjava.protocol.impl.clients.ScenarioHandler;
38 import org.opendaylight.openflowjava.protocol.impl.clients.SendEvent;
39 import org.opendaylight.openflowjava.protocol.impl.clients.SimpleClient;
40 import org.opendaylight.openflowjava.protocol.impl.clients.SleepEvent;
41 import org.opendaylight.openflowjava.protocol.impl.clients.UdpSimpleClient;
42 import org.opendaylight.openflowjava.protocol.impl.clients.WaitForMessageEvent;
43 import org.opendaylight.openflowjava.protocol.impl.core.SwitchConnectionProviderImpl;
44 import org.opendaylight.openflowjava.protocol.impl.core.connection.ConnectionConfigurationImpl;
45 import org.opendaylight.openflowjava.util.ByteBufUtils;
46 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.config.rev140630.KeystoreType;
47 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.config.rev140630.PathType;
48 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.config.rev140630.TransportProtocol;
49 import org.slf4j.Logger;
50 import org.slf4j.LoggerFactory;
51
52 /**
53  * End-to-end integration test.
54  *
55  * @author michal.polkorab
56  * @author timotej.kubas
57  */
58 @RunWith(MockitoJUnitRunner.class)
59 public class IntegrationTest {
60
61     private static final Logger LOGGER = LoggerFactory
62             .getLogger(IntegrationTest.class);
63
64     private static int port;
65     private TlsConfiguration tlsConfiguration;
66     private static final int CHANNEL_OUTBOUND_QUEUE_SIZE = 1024;
67     private static final int SWITCH_IDLE_TIMEOUT = 2000;
68     private static final long CONNECTION_TIMEOUT = 2000;
69     private InetAddress startupAddress;
70     private MockPlugin mockPlugin;
71     private SwitchConnectionProviderImpl switchConnectionProvider;
72     private ConnectionConfigurationImpl connConfig;
73     @Mock
74     private ExecutorService executorService;
75
76     private Thread thread;
77
78     private enum ClientType {
79         SIMPLE,
80         LISTENING
81     }
82
83     public void setUp(final TransportProtocol protocol) throws Exception {
84         LOGGER.debug("\n starting test -------------------------------");
85         doAnswer(invocation -> {
86             invocation.getArgument(0, Runnable.class).run();
87             return null;
88         }).when(executorService).execute(ArgumentMatchers.any());
89
90         final String currentDir = System.getProperty("user.dir");
91         LOGGER.debug("Current dir using System: {}", currentDir);
92         startupAddress = InetAddress.getLocalHost();
93         tlsConfiguration = null;
94         if (protocol.equals(TransportProtocol.TLS)) {
95             tlsConfiguration = new TlsConfigurationImpl(KeystoreType.JKS,
96                     "/selfSignedSwitch", PathType.CLASSPATH, KeystoreType.JKS,
97                     "/selfSignedController", PathType.CLASSPATH,
98                     List.of());
99         }
100         connConfig = new ConnectionConfigurationImpl(startupAddress, 0, tlsConfiguration,
101                 SWITCH_IDLE_TIMEOUT, true, false, CHANNEL_OUTBOUND_QUEUE_SIZE);
102         connConfig.setTransferProtocol(protocol);
103         mockPlugin = new MockPlugin(executorService);
104
105         final var diagStatusService = mock(DiagStatusService.class);
106         doReturn(mock(ServiceRegistration.class)).when(diagStatusService).register(any());
107
108         switchConnectionProvider = new SwitchConnectionProviderImpl(diagStatusService, connConfig);
109         switchConnectionProvider.startup(mockPlugin).get(CONNECTION_TIMEOUT, TimeUnit.MILLISECONDS);
110         port = switchConnectionProvider.getServerFacade().localAddress().getPort();
111     }
112
113     @After
114     public void tearDown() throws Exception {
115         switchConnectionProvider.close();
116         LOGGER.debug("\n ending test -------------------------------");
117     }
118
119     /**
120      * Library integration and communication test with handshake.
121      */
122     @Test
123     public void testHandshake() throws Exception {
124         setUp(TransportProtocol.TCP);
125         final int amountOfCLients = 1;
126         final Deque<ClientEvent> scenario = ScenarioFactory.createHandshakeScenario();
127         final ScenarioHandler handler = new ScenarioHandler(scenario);
128         final List<OFClient> clients = createAndStartClient(amountOfCLients, handler,
129                 TransportProtocol.TCP, ClientType.SIMPLE);
130         final OFClient firstClient = clients.get(0);
131         firstClient.getScenarioDone().get();
132         Thread.sleep(1000);
133
134         LOGGER.debug("testHandshake() Finished") ;
135     }
136
137     /**
138      * Library integration and secured communication test with handshake.
139      */
140     @Test
141     public void testTlsHandshake() throws Exception {
142         setUp(TransportProtocol.TLS);
143         final int amountOfCLients = 1;
144         final Deque<ClientEvent> scenario = ScenarioFactory.createHandshakeScenario();
145         final ScenarioHandler handler = new ScenarioHandler(scenario);
146         final List<OFClient> clients = createAndStartClient(amountOfCLients, handler,
147                 TransportProtocol.TLS, ClientType.SIMPLE);
148         final OFClient firstClient = clients.get(0);
149         firstClient.getScenarioDone().get();
150         Thread.sleep(1000);
151
152         LOGGER.debug("testTlsHandshake() Finished") ;
153     }
154
155     /**
156      * Library integration and communication test with handshake + echo exchange.
157      */
158     @Test
159     public void testHandshakeAndEcho() throws Exception {
160         setUp(TransportProtocol.TCP);
161         final int amountOfCLients = 1;
162         final Deque<ClientEvent> scenario = ScenarioFactory.createHandshakeScenario();
163         scenario.addFirst(new SleepEvent(1000));
164         scenario.addFirst(new SendEvent(ByteBufUtils.hexStringToBytes("04 02 00 08 00 00 00 04")));
165         scenario.addFirst(new SleepEvent(1000));
166         scenario.addFirst(new WaitForMessageEvent(ByteBufUtils.hexStringToBytes("04 03 00 08 00 00 00 04")));
167         final ScenarioHandler handler = new ScenarioHandler(scenario);
168         final List<OFClient> clients = createAndStartClient(amountOfCLients, handler,
169                 TransportProtocol.TCP, ClientType.SIMPLE);
170         final OFClient firstClient = clients.get(0);
171         firstClient.getScenarioDone().get();
172
173         LOGGER.debug("testHandshakeAndEcho() Finished") ;
174     }
175
176     /**
177      * Library integration and secured communication test with handshake + echo exchange.
178      */
179     @Test
180     public void testTlsHandshakeAndEcho() throws Exception {
181         setUp(TransportProtocol.TLS);
182         final int amountOfCLients = 1;
183         final Deque<ClientEvent> scenario = ScenarioFactory.createHandshakeScenario();
184         scenario.addFirst(new SleepEvent(1000));
185         scenario.addFirst(new SendEvent(ByteBufUtils.hexStringToBytes("04 02 00 08 00 00 00 04")));
186         scenario.addFirst(new SleepEvent(1000));
187         scenario.addFirst(new WaitForMessageEvent(ByteBufUtils.hexStringToBytes("04 03 00 08 00 00 00 04")));
188         final ScenarioHandler handler = new ScenarioHandler(scenario);
189         final List<OFClient> clients = createAndStartClient(amountOfCLients, handler,
190                 TransportProtocol.TLS, ClientType.SIMPLE);
191         final OFClient firstClient = clients.get(0);
192         firstClient.getScenarioDone().get();
193
194         LOGGER.debug("testTlsHandshakeAndEcho() Finished") ;
195     }
196
197     /**
198      * Library udp integration and communication test with handshake + echo exchange.
199      */
200     @Test
201     public void testUdpHandshakeAndEcho() throws Exception {
202         setUp(TransportProtocol.UDP);
203         final int amountOfCLients = 1;
204         final Deque<ClientEvent> scenario = ScenarioFactory.createHandshakeScenario();
205         scenario.addFirst(new SleepEvent(1000));
206         scenario.addFirst(new SendEvent(ByteBufUtils.hexStringToBytes("04 02 00 08 00 00 00 04")));
207         scenario.addFirst(new SleepEvent(1000));
208         scenario.addFirst(new WaitForMessageEvent(ByteBufUtils.hexStringToBytes("04 03 00 08 00 00 00 04")));
209         final ScenarioHandler handler = new ScenarioHandler(scenario);
210         final List<OFClient> clients = createAndStartClient(amountOfCLients, handler,
211                 TransportProtocol.UDP, ClientType.SIMPLE);
212         final OFClient firstClient = clients.get(0);
213         firstClient.getScenarioDone().get();
214
215         LOGGER.debug("testUdpHandshakeAndEcho() Finished") ;
216     }
217
218     /**
219      * Library integration and communication test (with virtual machine).
220      */
221     //@Test
222     public void testCommunicationWithVM() throws Exception {
223         mockPlugin.getFinishedFuture().get();
224     }
225
226     /**
227      * Creates and start a client.
228      *
229      * @param amountOfCLients number of clients
230      * @param protocol true if encrypted connection should be used
231      * @return new clients up and running
232      * @throws ExecutionException if some client could not start
233      */
234     private List<OFClient> createAndStartClient(final int amountOfCLients, final ScenarioHandler scenarioHandler,
235             final TransportProtocol protocol, final ClientType clientType)
236                     throws ExecutionException, InterruptedException, TimeoutException {
237         final List<OFClient> clientsHorde = new ArrayList<>();
238         for (int i = 0; i < amountOfCLients; i++) {
239             LOGGER.debug("startup address in createclient: {}", startupAddress.getHostAddress());
240             OFClient sc = null;
241             if (clientType == ClientType.SIMPLE) {
242                 if (protocol.equals(TransportProtocol.TCP)) {
243                     sc = new SimpleClient(startupAddress.getHostAddress(), port);
244                     sc.setSecuredClient(false);
245                 } else if (protocol.equals(TransportProtocol.TLS)) {
246                     sc = new SimpleClient(startupAddress.getHostAddress(), port);
247                     sc.setSecuredClient(true);
248                 } else {
249                     sc = new UdpSimpleClient(startupAddress.getHostAddress(), port);
250                 }
251             } else if (clientType == ClientType.LISTENING) {
252                 sc = new ListeningSimpleClient(0);
253                 sc.setScenarioHandler(scenarioHandler);
254                 sc.setSecuredClient(false);
255             } else {
256                 LOGGER.error("Unknown type of client.");
257                 throw new IllegalStateException("Unknown type of client.");
258             }
259
260             sc.setScenarioHandler(scenarioHandler);
261             clientsHorde.add(sc);
262             //sc.run();
263             thread = new Thread(sc);
264             thread.start();
265         }
266         for (final OFClient sc : clientsHorde) {
267             sc.getIsOnlineFuture().get(CONNECTION_TIMEOUT, TimeUnit.MILLISECONDS);
268         }
269         return clientsHorde;
270     }
271
272     @Test
273     public void testInitiateConnection() throws Exception {
274         setUp(TransportProtocol.TCP);
275
276         final Deque<ClientEvent> scenario = ScenarioFactory.createHandshakeScenario();
277         final ScenarioHandler handler = new ScenarioHandler(scenario);
278         final List<OFClient> clients = createAndStartClient(1, handler, TransportProtocol.TCP, ClientType.LISTENING);
279         final OFClient ofClient = clients.get(0);
280         ofClient.getIsOnlineFuture().get(CONNECTION_TIMEOUT, TimeUnit.MILLISECONDS);
281         final int listeningClientPort = ((ListeningSimpleClient) ofClient).getPort();
282         mockPlugin.initiateConnection(switchConnectionProvider, "localhost", listeningClientPort);
283         ofClient.getScenarioDone().get();
284         LOGGER.debug("testInitiateConnection() Finished") ;
285     }
286 }