Ditch use of SystemNotificationsListener
[openflowplugin.git] / openflowjava / openflow-protocol-it / src / test / java / org / opendaylight / openflowjava / protocol / it / integration / MockPlugin.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 com.google.common.util.concurrent.SettableFuture;
11 import java.net.InetAddress;
12 import java.util.concurrent.ExecutionException;
13 import java.util.concurrent.ExecutorService;
14 import java.util.concurrent.Future;
15 import java.util.concurrent.TimeUnit;
16 import java.util.concurrent.TimeoutException;
17 import org.opendaylight.openflowjava.protocol.api.connection.ConnectionAdapter;
18 import org.opendaylight.openflowjava.protocol.api.connection.ConnectionAdapter.SystemListener;
19 import org.opendaylight.openflowjava.protocol.api.connection.ConnectionReadyListener;
20 import org.opendaylight.openflowjava.protocol.api.connection.SwitchConnectionHandler;
21 import org.opendaylight.openflowjava.protocol.impl.core.SwitchConnectionProviderImpl;
22 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.EchoReplyInput;
23 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.EchoReplyInputBuilder;
24 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.EchoRequestMessage;
25 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.ErrorMessage;
26 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.ExperimenterMessage;
27 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.FlowRemovedMessage;
28 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.GetFeaturesInput;
29 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.GetFeaturesInputBuilder;
30 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.GetFeaturesOutput;
31 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.HelloInput;
32 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.HelloInputBuilder;
33 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.HelloMessage;
34 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.MultipartReplyMessage;
35 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.OpenflowProtocolListener;
36 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.PacketInMessage;
37 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.PortStatusMessage;
38 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.system.rev130927.DisconnectEvent;
39 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.system.rev130927.SslConnectionError;
40 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.system.rev130927.SwitchIdleEvent;
41 import org.opendaylight.yangtools.yang.common.RpcError;
42 import org.opendaylight.yangtools.yang.common.RpcResult;
43 import org.opendaylight.yangtools.yang.common.Uint32;
44 import org.opendaylight.yangtools.yang.common.Uint8;
45 import org.slf4j.Logger;
46 import org.slf4j.LoggerFactory;
47
48 /**
49  * Mock plugin.
50  *
51  * @author michal.polkorab
52  */
53 public class MockPlugin implements OpenflowProtocolListener, SwitchConnectionHandler, SystemListener,
54         ConnectionReadyListener {
55     protected static final Logger LOGGER = LoggerFactory.getLogger(MockPlugin.class);
56
57     private final SettableFuture<Void> finishedFuture;
58     private final ExecutorService executorService;
59
60     private int idleCounter = 0;
61
62     protected volatile ConnectionAdapter adapter;
63
64     public MockPlugin(final ExecutorService executorService) {
65         LOGGER.trace("Creating MockPlugin");
66         finishedFuture = SettableFuture.create();
67         this.executorService = executorService;
68         LOGGER.debug("mockPlugin: {}", System.identityHashCode(this));
69     }
70
71     @Override
72     public void onSwitchConnected(final ConnectionAdapter connection) {
73         LOGGER.debug("onSwitchConnected: {}", connection);
74         adapter = connection;
75         connection.setMessageListener(this);
76         connection.setSystemListener(this);
77         connection.setConnectionReadyListener(this);
78         connection.setExecutorService(executorService);
79     }
80
81     @Override
82     public boolean accept(final InetAddress switchAddress) {
83         LOGGER.debug("MockPlugin.accept(): {}", switchAddress.toString());
84         return true;
85     }
86
87     @Override
88     public void onDisconnect(final DisconnectEvent disconnect) {
89         LOGGER.debug("disconnection occured: {}", disconnect.getInfo());
90     }
91
92     @Override
93     public void onSslConnectionError(final SslConnectionError sslConnectionError) {
94         LOGGER.debug("Ssl error occured: {}", sslConnectionError.getInfo());
95     }
96
97     @Override
98     public void onSwitchIdle(final SwitchIdleEvent switchIdle) {
99         LOGGER.debug("MockPlugin.onSwitchIdleEvent() switch status: {}", switchIdle.getInfo());
100         idleCounter++;
101     }
102
103     @Override
104     public void onEchoRequestMessage(final EchoRequestMessage notification) {
105         LOGGER.debug("MockPlugin.onEchoRequestMessage() adapter: {}", adapter);
106         new Thread(() -> {
107             LOGGER.debug("MockPlugin.onEchoRequestMessage().run() started adapter: {}", adapter);
108             EchoReplyInputBuilder replyBuilder = new EchoReplyInputBuilder();
109             replyBuilder.setVersion(Uint8.valueOf(4));
110             replyBuilder.setXid(notification.getXid());
111             EchoReplyInput echoReplyInput = replyBuilder.build();
112             adapter.echoReply(echoReplyInput);
113             LOGGER.debug("adapter.EchoReply(Input) sent : ", echoReplyInput.toString());
114             LOGGER.debug("MockPlugin.onEchoRequestMessage().run() finished adapter: {}", adapter);
115         }).start();
116     }
117
118     @Override
119     public void onErrorMessage(final ErrorMessage notification) {
120         LOGGER.debug("Error message received");
121     }
122
123     @Override
124     public void onExperimenterMessage(final ExperimenterMessage notification) {
125         LOGGER.debug("Experimenter message received");
126     }
127
128     @Override
129     public void onFlowRemovedMessage(final FlowRemovedMessage notification) {
130         LOGGER.debug("FlowRemoved message received");
131     }
132
133     @Override
134     public void onHelloMessage(final HelloMessage notification) {
135         new Thread(() -> {
136             LOGGER.debug("MockPlugin.onHelloMessage().run() Hello message received");
137             HelloInputBuilder hib = new HelloInputBuilder();
138             hib.setVersion(Uint8.valueOf(4));
139             hib.setXid(Uint32.TWO);
140             HelloInput hi = hib.build();
141             adapter.hello(hi);
142             LOGGER.debug("hello msg sent");
143             new Thread(this::getSwitchFeatures).start();
144         }).start();
145     }
146
147     protected void getSwitchFeatures() {
148         GetFeaturesInputBuilder featuresBuilder = new GetFeaturesInputBuilder();
149         featuresBuilder.setVersion(Uint8.valueOf(4));
150         featuresBuilder.setXid(Uint32.valueOf(3));
151         GetFeaturesInput featuresInput = featuresBuilder.build();
152         try {
153             LOGGER.debug("Requesting features ");
154             RpcResult<GetFeaturesOutput> rpcResult = adapter.getFeatures(
155                     featuresInput).get(2500, TimeUnit.MILLISECONDS);
156             if (rpcResult.isSuccessful()) {
157                 LOGGER.debug("DatapathId: {}", rpcResult.getResult().getDatapathId());
158             } else {
159                 RpcError rpcError = rpcResult.getErrors().iterator().next();
160                 LOGGER.warn("rpcResult failed", rpcError.getCause());
161             }
162         } catch (InterruptedException | ExecutionException | TimeoutException e) {
163             LOGGER.error("getSwitchFeatures() exception caught: ", e.getMessage(), e);
164         }
165     }
166
167     protected void shutdown() throws InterruptedException, ExecutionException {
168         LOGGER.debug("MockPlugin.shutdown() sleeping 5... : {}", System.identityHashCode(this));
169         Thread.sleep(500);
170         if (adapter != null) {
171             Future<Boolean> disconnect = adapter.disconnect();
172             disconnect.get();
173             LOGGER.debug("MockPlugin.shutdown() Disconnected");
174         }
175
176         finishedFuture.set(null);
177     }
178
179     @Override
180     public void onMultipartReplyMessage(final MultipartReplyMessage notification) {
181         LOGGER.debug("MultipartReply message received");
182     }
183
184     @Override
185     public void onPacketInMessage(final PacketInMessage notification) {
186         LOGGER.debug("PacketIn message received");
187         LOGGER.debug("BufferId: {}", notification.getBufferId());
188         LOGGER.debug("TotalLength: {}", notification.getTotalLen());
189         LOGGER.debug("Reason: {}", notification.getReason());
190         LOGGER.debug("TableId: {}", notification.getTableId());
191         LOGGER.debug("Cookie: {}", notification.getCookie());
192         LOGGER.debug("Class: {}", notification.getMatch().getMatchEntry().get(0).getOxmClass());
193         LOGGER.debug("Field: {}", notification.getMatch().getMatchEntry().get(0).getOxmMatchField());
194         LOGGER.debug("Datasize: {}", notification.getData().length);
195     }
196
197     @Override
198     public void onPortStatusMessage(final PortStatusMessage notification) {
199         LOGGER.debug("MockPlugin.onPortStatusMessage() message received");
200     }
201
202     public SettableFuture<Void> getFinishedFuture() {
203         return finishedFuture;
204     }
205
206     /**
207      * Returns number of occurred idleEvents.
208      */
209     public int getIdleCounter() {
210         return idleCounter;
211     }
212
213     @Override
214     public void onConnectionReady() {
215         LOGGER.trace("MockPlugin().onConnectionReady()");
216     }
217
218     /**
219      * Initiates connection to device.
220      *
221      * @param switchConnectionProvider the SwitchConnectionProviderImpl
222      * @param host                     - host IP
223      * @param port                     - port number
224      */
225     public void initiateConnection(final SwitchConnectionProviderImpl switchConnectionProvider, final String host,
226             final int port) {
227         LOGGER.trace("MockPlugin().initiateConnection()");
228         switchConnectionProvider.initiateConnection(host, port);
229     }
230 }