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