2 * Copyright IBM Corporation, 2013. All rights reserved.
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
8 package org.opendaylight.openflowplugin.openflow.md.core.session;
10 import java.math.BigInteger;
11 import java.util.HashMap;
12 import java.util.List;
14 import java.util.Map.Entry;
16 import java.util.concurrent.Future;
18 import junit.framework.Assert;
20 import org.junit.After;
21 import org.junit.Before;
22 import org.junit.Test;
23 import org.opendaylight.openflowjava.protocol.api.connection.ConnectionAdapter;
24 import org.opendaylight.openflowjava.protocol.api.connection.ConnectionReadyListener;
25 import org.opendaylight.openflowplugin.openflow.md.ModelDrivenSwitch;
26 import org.opendaylight.openflowplugin.openflow.md.core.ConnectionConductor;
27 import org.opendaylight.openflowplugin.openflow.md.core.ErrorHandler;
28 import org.opendaylight.openflowplugin.openflow.md.core.SwitchConnectionDistinguisher;
29 import org.opendaylight.openflowplugin.openflow.md.queue.QueueKeeper;
30 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.BarrierInput;
31 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.BarrierInputBuilder;
32 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.BarrierOutput;
33 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.EchoInput;
34 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.EchoOutput;
35 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.EchoReplyInput;
36 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.ExperimenterInput;
37 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.FlowModInput;
38 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.GetAsyncInput;
39 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.GetAsyncOutput;
40 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.GetConfigInput;
41 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.GetConfigOutput;
42 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.GetFeaturesInput;
43 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.GetFeaturesOutput;
44 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.GetQueueConfigInput;
45 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.GetQueueConfigOutput;
46 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.GroupModInput;
47 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.HelloInput;
48 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.MeterModInput;
49 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.MultipartRequestInput;
50 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.OfHeader;
51 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.OpenflowProtocolListener;
52 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.PacketOutInput;
53 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.PacketOutInputBuilder;
54 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.PortGrouping;
55 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.PortModInput;
56 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.RoleRequestInput;
57 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.RoleRequestOutput;
58 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.SetAsyncInput;
59 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.SetConfigInput;
60 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.TableModInput;
61 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.system.rev130927.SystemNotificationsListener;
62 import org.opendaylight.yangtools.concepts.CompositeObjectRegistration;
63 import org.opendaylight.yangtools.yang.binding.DataObject;
64 import org.opendaylight.yangtools.yang.common.RpcResult;
66 import com.google.common.cache.Cache;
68 public class MessageDispatchServiceImplTest {
70 MockSessionContext session;
73 * @throws java.lang.Exception
76 public void setUp() throws Exception {
77 session = new MockSessionContext(0);
82 * @throws java.lang.Exception
85 public void tearDown() throws Exception {
90 * Test barrier message for null cookie
95 public void testBarrierMessageForPrimary() throws Exception {
96 MockConnectionConductor conductor = new MockConnectionConductor(1);
97 SwitchConnectionDistinguisher cookie = conductor.getAuxiliaryKey();
98 BarrierInputBuilder barrierMsg = new BarrierInputBuilder();
99 session.getMessageDispatchService().barrier(barrierMsg.build(), cookie);
100 Assert.assertEquals(MessageType.BARRIER, session.getPrimaryConductor().getMessageType());
104 * Test packet out message for primary connection
109 public void testPacketOutMessageForPrimary() throws Exception {
110 session.getMessageDispatchService().packetOut(null, null);
111 Assert.assertEquals(MessageType.PACKETOUT, session.getPrimaryConductor().getMessageType());
115 * Test packet out message for auxiliary connection
120 public void testPacketOutMessageForAuxiliary() throws Exception {
121 MockConnectionConductor conductor = new MockConnectionConductor(1);
122 SwitchConnectionDistinguisher cookie = conductor.getAuxiliaryKey();
123 session.addAuxiliaryConductor(cookie, conductor);
124 session.getMessageDispatchService().packetOut(null, cookie);
125 Assert.assertEquals(MessageType.NONE, session.getPrimaryConductor().getMessageType());
126 conductor = (MockConnectionConductor) session.getAuxiliaryConductor(cookie);
127 Assert.assertEquals(MessageType.PACKETOUT, conductor.getMessageType());
131 * Test packet out message when multiple auxiliary connection exist
136 public void testPacketOutMessageForMultipleAuxiliary() throws Exception {
137 MockConnectionConductor conductor1 = new MockConnectionConductor(1);
138 SwitchConnectionDistinguisher cookie1 = conductor1.getAuxiliaryKey();
139 session.addAuxiliaryConductor(cookie1, conductor1);
140 MockConnectionConductor conductor2 = new MockConnectionConductor(2);
141 SwitchConnectionDistinguisher cookie2 = conductor2.getAuxiliaryKey();
142 session.addAuxiliaryConductor(cookie2, conductor2);
143 MockConnectionConductor conductor3 = new MockConnectionConductor(3);
144 SwitchConnectionDistinguisher cookie3 = conductor3.getAuxiliaryKey();
145 session.addAuxiliaryConductor(cookie3, conductor3);
146 PacketOutInputBuilder builder = new PacketOutInputBuilder();
148 session.getMessageDispatchService().packetOut(builder.build(), cookie2);
150 Assert.assertEquals(MessageType.NONE, session.getPrimaryConductor().getMessageType());
152 conductor3 = (MockConnectionConductor) session.getAuxiliaryConductor(cookie3);
153 Assert.assertEquals(MessageType.NONE, conductor3.getMessageType());
155 conductor2 = (MockConnectionConductor) session.getAuxiliaryConductor(cookie2);
156 Assert.assertEquals(MessageType.PACKETOUT, conductor2.getMessageType());
158 conductor1 = (MockConnectionConductor) session.getAuxiliaryConductor(cookie1);
159 Assert.assertEquals(MessageType.NONE, conductor1.getMessageType());
164 * Test for invalid session
169 public void testInvalidSession() throws Exception {
170 session.setValid(false);
172 session.getMessageDispatchService().packetOut(null, null);
173 Assert.assertTrue(false);
174 } catch (IllegalArgumentException ex) {
175 Assert.assertTrue(true);
181 class MockSessionContext implements SessionContext {
182 private MockConnectionConductor conductor;
183 private Map<SwitchConnectionDistinguisher, ConnectionConductor> map;
184 private IMessageDispatchService messageService;
185 private boolean isValid = true;
186 private CompositeObjectRegistration<ModelDrivenSwitch> registration;
188 MockSessionContext(int conductorNum) {
189 conductor = new MockConnectionConductor(conductorNum);
190 map = new HashMap<SwitchConnectionDistinguisher, ConnectionConductor>();
191 messageService = new MessageDispatchServiceImpl(this);
195 public MockConnectionConductor getPrimaryConductor() {
196 // TODO Auto-generated method stub
201 public GetFeaturesOutput getFeatures() {
202 // TODO Auto-generated method stub
207 public ConnectionConductor getAuxiliaryConductor(SwitchConnectionDistinguisher auxiliaryKey) {
209 return map.get(auxiliaryKey);
213 public Set<Entry<SwitchConnectionDistinguisher, ConnectionConductor>> getAuxiliaryConductors() {
214 // TODO Auto-generated method stub
219 public void addAuxiliaryConductor(SwitchConnectionDistinguisher auxiliaryKey, ConnectionConductor conductor) {
220 map.put(auxiliaryKey, conductor);
224 public ConnectionConductor removeAuxiliaryConductor(SwitchConnectionDistinguisher connectionCookie) {
225 return map.remove(connectionCookie);
229 public boolean isValid() {
230 // TODO Auto-generated method stub
235 public void setValid(boolean valid) {
240 public SwitchConnectionDistinguisher getSessionKey() {
241 // TODO Auto-generated method stub
246 public Cache<TransactionKey, Object> getbulkTransactionCache() {
251 public IMessageDispatchService getMessageDispatchService() {
252 // TODO Auto-generated method stub
253 return messageService;
257 public Long getNextXid() {
258 // TODO Auto-generated method stub
263 public Map<Long, PortGrouping> getPhysicalPorts() {
264 // TODO Auto-generated method stub
269 public Set<Long> getPorts() {
270 // TODO Auto-generated method stub
275 public PortGrouping getPhysicalPort(Long portNumber) {
276 // TODO Auto-generated method stub
281 public Boolean getPortBandwidth(Long portNumber) {
282 // TODO Auto-generated method stub
287 public boolean isPortEnabled(long portNumber) {
288 // TODO Auto-generated method stub
293 public boolean isPortEnabled(PortGrouping port) {
294 // TODO Auto-generated method stub
299 public List<PortGrouping> getEnabledPorts() {
300 // TODO Auto-generated method stub
305 public Map<Long, Boolean> getPortsBandwidth() {
306 // TODO Auto-generated method stub
311 public CompositeObjectRegistration<ModelDrivenSwitch> getProviderRegistration() {
316 public void setProviderRegistration(
317 CompositeObjectRegistration<ModelDrivenSwitch> registration) {
318 this.registration = registration;
322 class MockConnectionConductor implements ConnectionConductor {
324 private int conductorNum;
325 private MockConnectionAdapter adapter;
327 public MockConnectionConductor(int conductorNumber) {
328 conductorNum = conductorNumber;
329 adapter = new MockConnectionAdapter();
334 // TODO Auto-generated method stub
339 public Short getVersion() {
340 // TODO Auto-generated method stub
345 public CONDUCTOR_STATE getConductorState() {
346 // TODO Auto-generated method stub
351 public void setConductorState(CONDUCTOR_STATE conductorState) {
352 // TODO Auto-generated method stub
357 public Future<Boolean> disconnect() {
358 // TODO Auto-generated method stub
363 public void setSessionContext(SessionContext context) {
364 // TODO Auto-generated method stub
369 public void setConnectionCookie(SwitchConnectionDistinguisher auxiliaryKey) {
370 // TODO Auto-generated method stub
375 public SessionContext getSessionContext() {
376 // TODO Auto-generated method stub
381 public SwitchConnectionDistinguisher getAuxiliaryKey() {
382 if (0 != conductorNum) {
383 SwitchConnectionCookieOFImpl key = new SwitchConnectionCookieOFImpl();
384 key.setDatapathId(BigInteger.valueOf(10L));
385 key.setAuxiliaryId((short) conductorNum);
393 public ConnectionAdapter getConnectionAdapter() {
394 // TODO Auto-generated method stub
398 public MessageType getMessageType() {
399 return adapter.getMessageType();
403 public void setQueueKeeper(QueueKeeper<OfHeader, DataObject> queueKeeper) {
408 public void setErrorHandler(ErrorHandler errorHandler) {
413 NONE, BARRIER, FLOWMOD, TABLEMOD, PACKETOUT;
416 class MockConnectionAdapter implements ConnectionAdapter {
418 private MessageType messageType;
419 private ConnectionReadyListener connectionReadyListener;
421 public MockConnectionAdapter() {
422 setMessageType(MessageType.NONE);
426 public Future<RpcResult<BarrierOutput>> barrier(BarrierInput input) {
427 setMessageType(MessageType.BARRIER);
432 public Future<RpcResult<EchoOutput>> echo(EchoInput input) {
433 // TODO Auto-generated method stub
438 public Future<RpcResult<Void>> echoReply(EchoReplyInput input) {
439 // TODO Auto-generated method stub
444 public Future<RpcResult<Void>> experimenter(ExperimenterInput input) {
445 // TODO Auto-generated method stub
450 public Future<RpcResult<Void>> flowMod(FlowModInput input) {
451 setMessageType(MessageType.FLOWMOD);
456 public Future<RpcResult<GetAsyncOutput>> getAsync(GetAsyncInput input) {
457 // TODO Auto-generated method stub
462 public Future<RpcResult<GetConfigOutput>> getConfig(GetConfigInput input) {
463 // TODO Auto-generated method stub
468 public Future<RpcResult<GetFeaturesOutput>> getFeatures(GetFeaturesInput input) {
469 // TODO Auto-generated method stub
474 public Future<RpcResult<GetQueueConfigOutput>> getQueueConfig(GetQueueConfigInput input) {
475 // TODO Auto-generated method stub
480 public Future<RpcResult<Void>> groupMod(GroupModInput input) {
481 // TODO Auto-generated method stub
486 public Future<RpcResult<Void>> hello(HelloInput input) {
487 // TODO Auto-generated method stub
492 public Future<RpcResult<Void>> meterMod(MeterModInput input) {
493 // TODO Auto-generated method stub
498 public Future<RpcResult<Void>> packetOut(PacketOutInput input) {
499 setMessageType(MessageType.PACKETOUT);
504 public Future<RpcResult<Void>> portMod(PortModInput input) {
505 // TODO Auto-generated method stub
510 public Future<RpcResult<RoleRequestOutput>> roleRequest(RoleRequestInput input) {
511 // TODO Auto-generated method stub
516 public Future<RpcResult<Void>> setAsync(SetAsyncInput input) {
517 // TODO Auto-generated method stub
522 public Future<RpcResult<Void>> setConfig(SetConfigInput input) {
523 // TODO Auto-generated method stub
528 public Future<RpcResult<Void>> tableMod(TableModInput input) {
529 setMessageType(MessageType.TABLEMOD);
534 public Future<Boolean> disconnect() {
535 // TODO Auto-generated method stub
540 public boolean isAlive() {
541 // TODO Auto-generated method stub
546 public void setMessageListener(OpenflowProtocolListener messageListener) {
547 // TODO Auto-generated method stub
552 public void setSystemListener(SystemNotificationsListener systemListener) {
553 // TODO Auto-generated method stub
558 public void checkListeners() {
559 // TODO Auto-generated method stub
564 * @return the messageType
566 public MessageType getMessageType() {
572 * the messageType to set
574 public void setMessageType(MessageType messageType) {
575 this.messageType = messageType;
579 public void fireConnectionReadyNotification() {
580 connectionReadyListener.onConnectionReady();
584 public void setConnectionReadyListener(
585 ConnectionReadyListener connectionReadyListener) {
586 this.connectionReadyListener = connectionReadyListener;
590 public Future<RpcResult<Void>> multipartRequest(
591 MultipartRequestInput input) {
592 // TODO Auto-generated method stub