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.net.InetSocketAddress;
11 import java.util.HashMap;
12 import java.util.Iterator;
13 import java.util.List;
15 import java.util.Map.Entry;
17 import java.util.concurrent.ExecutionException;
18 import java.util.concurrent.Future;
20 import org.junit.Assert;
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.api.openflow.md.core.session.IMessageDispatchService;
26 import org.opendaylight.openflowplugin.api.openflow.md.core.session.SessionContext;
27 import org.opendaylight.openflowplugin.api.openflow.md.core.session.SwitchSessionKeyOF;
28 import org.opendaylight.openflowplugin.api.openflow.md.ModelDrivenSwitch;
29 import org.opendaylight.openflowplugin.api.OFConstants;
30 import org.opendaylight.openflowplugin.api.openflow.md.core.ConnectionConductor;
31 import org.opendaylight.openflowplugin.api.openflow.md.core.ErrorHandler;
32 import org.opendaylight.openflowplugin.api.openflow.md.core.NotificationEnqueuer;
33 import org.opendaylight.openflowplugin.api.openflow.md.core.NotificationQueueWrapper;
34 import org.opendaylight.openflowplugin.api.openflow.md.core.SwitchConnectionDistinguisher;
35 import org.opendaylight.openflowplugin.api.openflow.md.queue.QueueProcessor;
36 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.BarrierInput;
37 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.BarrierInputBuilder;
38 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.BarrierOutput;
39 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.EchoInput;
40 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.EchoOutput;
41 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.EchoReplyInput;
42 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.ExperimenterInput;
43 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.ExperimenterInputBuilder;
44 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.FlowModInput;
45 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.GetAsyncInput;
46 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.GetAsyncInputBuilder;
47 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.GetAsyncOutput;
48 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.GetConfigInput;
49 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.GetConfigInputBuilder;
50 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.GetConfigOutput;
51 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.GetFeaturesInput;
52 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.GetFeaturesInputBuilder;
53 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.GetFeaturesOutput;
54 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.GetQueueConfigInput;
55 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.GetQueueConfigInputBuilder;
56 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.GetQueueConfigOutput;
57 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.GroupModInput;
58 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.HelloInput;
59 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.MeterModInput;
60 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.MultipartRequestInput;
61 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.MultipartRequestInputBuilder;
62 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.OfHeader;
63 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.OpenflowProtocolListener;
64 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.PacketOutInput;
65 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.PacketOutInputBuilder;
66 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.PortGrouping;
67 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.PortModInput;
68 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.RoleRequestInput;
69 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.RoleRequestInputBuilder;
70 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.RoleRequestOutput;
71 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.SetAsyncInput;
72 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.SetConfigInput;
73 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.TableModInput;
74 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.TableModInputBuilder;
75 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.system.rev130927.SystemNotificationsListener;
76 import org.opendaylight.yangtools.concepts.CompositeObjectRegistration;
77 import org.opendaylight.yangtools.yang.binding.DataObject;
78 import org.opendaylight.yangtools.yang.common.RpcError;
79 import org.opendaylight.yangtools.yang.common.RpcResult;
82 * test for {@link MessageDispatchServiceImpl}
84 public class MessageDispatchServiceImplTest {
86 MockSessionContext session;
89 * @throws java.lang.Exception
92 public void setUp() throws Exception {
93 session = new MockSessionContext(0);
98 * Test barrier message for null cookie
103 public void testBarrierMessageForPrimary() throws Exception {
104 MockConnectionConductor conductor = new MockConnectionConductor(1);
105 SwitchConnectionDistinguisher cookie = conductor.getAuxiliaryKey();
106 BarrierInputBuilder barrierMsg = new BarrierInputBuilder();
107 session.getMessageDispatchService().barrier(barrierMsg.build(), cookie);
108 Assert.assertEquals(MessageType.BARRIER, session.getPrimaryConductor().getMessageType());
112 * Test experimenter message for null cookie
115 public void testExperimenter() {
116 MockConnectionConductor conductor = new MockConnectionConductor(1);
117 SwitchConnectionDistinguisher cookie = conductor.getAuxiliaryKey();
118 ExperimenterInputBuilder experimenterInputBuilder = new ExperimenterInputBuilder();
119 session.getMessageDispatchService().experimenter(experimenterInputBuilder.build(), cookie);
120 Assert.assertEquals(MessageType.NONE, session.getPrimaryConductor().getMessageType());
124 * Test get async input with null cookie
127 public void testGetAsync() throws ExecutionException, InterruptedException {
128 MockConnectionConductor conductor = new MockConnectionConductor(1);
129 SwitchConnectionDistinguisher cookie = conductor.getAuxiliaryKey();
130 GetAsyncInputBuilder getAsyncInputBuilder = new GetAsyncInputBuilder();
131 session.getMessageDispatchService().getAsync(getAsyncInputBuilder.build(), cookie);
132 Assert.assertEquals(MessageType.NONE, session.getPrimaryConductor().getMessageType());
136 * Test get async output with null cookie
139 public void testGetConfig() {
140 MockConnectionConductor conductor = new MockConnectionConductor(1);
141 SwitchConnectionDistinguisher cookie = conductor.getAuxiliaryKey();
142 GetConfigInputBuilder getConfigInputBuilder = new GetConfigInputBuilder();
143 session.getMessageDispatchService().getConfig(getConfigInputBuilder.build(), cookie);
144 Assert.assertEquals(MessageType.NONE, session.getPrimaryConductor().getMessageType());
148 * Test get features with null cookie
151 public void testGetFeatures() {
152 MockConnectionConductor conductor = new MockConnectionConductor(1);
153 SwitchConnectionDistinguisher cookie = conductor.getAuxiliaryKey();
154 GetFeaturesInputBuilder getFeaturesInputBuilder = new GetFeaturesInputBuilder();
155 session.getMessageDispatchService().getFeatures(getFeaturesInputBuilder.build(), cookie);
156 Assert.assertEquals(MessageType.NONE, session.getPrimaryConductor().getMessageType());
160 * Test get queue config with null cookie
163 public void testGetQueueConfig() {
164 MockConnectionConductor conductor = new MockConnectionConductor(1);
165 SwitchConnectionDistinguisher cookie = conductor.getAuxiliaryKey();
166 GetQueueConfigInputBuilder getQueueConfigInputBuilder = new GetQueueConfigInputBuilder();
167 session.getMessageDispatchService().getQueueConfig(getQueueConfigInputBuilder.build(), cookie);
168 Assert.assertEquals(MessageType.NONE, session.getPrimaryConductor().getMessageType());
172 * Test multipart request with null cookie
175 public void testGetMultipart() {
176 MockConnectionConductor conductor = new MockConnectionConductor(1);
177 SwitchConnectionDistinguisher cookie = conductor.getAuxiliaryKey();
178 MultipartRequestInputBuilder multipartRequestInputBuilder = new MultipartRequestInputBuilder();
179 session.getMessageDispatchService().multipartRequest(multipartRequestInputBuilder.build(), cookie);
180 Assert.assertEquals(MessageType.NONE, session.getPrimaryConductor().getMessageType());
184 * Test role request with null cookie
187 public void testRoleRequest() {
188 MockConnectionConductor conductor = new MockConnectionConductor(1);
189 SwitchConnectionDistinguisher cookie = conductor.getAuxiliaryKey();
190 RoleRequestInputBuilder roleRequestInputBuilder = new RoleRequestInputBuilder();
191 session.getMessageDispatchService().roleRequest(roleRequestInputBuilder.build(), cookie);
192 Assert.assertEquals(MessageType.NONE, session.getPrimaryConductor().getMessageType());
196 * Test table mod with null cookie
199 public void testTableMod() {
200 MockConnectionConductor conductor = new MockConnectionConductor(1);
201 SwitchConnectionDistinguisher cookie = conductor.getAuxiliaryKey();
202 TableModInputBuilder tableModInputBuilder = new TableModInputBuilder();
203 session.getMessageDispatchService().tableMod(tableModInputBuilder.build(), cookie);
204 Assert.assertEquals(MessageType.TABLEMOD, session.getPrimaryConductor().getMessageType());
209 * Test packet out message for primary connection
214 public void testPacketOutMessageForPrimary() throws Exception {
215 session.getMessageDispatchService().packetOut(null, null);
216 Assert.assertEquals(MessageType.PACKETOUT, session.getPrimaryConductor().getMessageType());
220 * Test packet out message for auxiliary connection
225 public void testPacketOutMessageForAuxiliary() throws Exception {
226 MockConnectionConductor conductor = new MockConnectionConductor(1);
227 SwitchConnectionDistinguisher cookie = conductor.getAuxiliaryKey();
228 session.addAuxiliaryConductor(cookie, conductor);
229 session.getMessageDispatchService().packetOut(null, cookie);
230 Assert.assertEquals(MessageType.NONE, session.getPrimaryConductor().getMessageType());
231 conductor = (MockConnectionConductor) session.getAuxiliaryConductor(cookie);
232 Assert.assertEquals(MessageType.PACKETOUT, conductor.getMessageType());
236 * Test packet out message when multiple auxiliary connection exist
241 public void testPacketOutMessageForMultipleAuxiliary() throws Exception {
242 MockConnectionConductor conductor1 = new MockConnectionConductor(1);
243 SwitchConnectionDistinguisher cookie1 = conductor1.getAuxiliaryKey();
244 session.addAuxiliaryConductor(cookie1, conductor1);
245 MockConnectionConductor conductor2 = new MockConnectionConductor(2);
246 SwitchConnectionDistinguisher cookie2 = conductor2.getAuxiliaryKey();
247 session.addAuxiliaryConductor(cookie2, conductor2);
248 MockConnectionConductor conductor3 = new MockConnectionConductor(3);
249 SwitchConnectionDistinguisher cookie3 = conductor3.getAuxiliaryKey();
250 session.addAuxiliaryConductor(cookie3, conductor3);
251 PacketOutInputBuilder builder = new PacketOutInputBuilder();
253 session.getMessageDispatchService().packetOut(builder.build(), cookie2);
255 Assert.assertEquals(MessageType.NONE, session.getPrimaryConductor().getMessageType());
257 conductor3 = (MockConnectionConductor) session.getAuxiliaryConductor(cookie3);
258 Assert.assertEquals(MessageType.NONE, conductor3.getMessageType());
260 conductor2 = (MockConnectionConductor) session.getAuxiliaryConductor(cookie2);
261 Assert.assertEquals(MessageType.PACKETOUT, conductor2.getMessageType());
263 conductor1 = (MockConnectionConductor) session.getAuxiliaryConductor(cookie1);
264 Assert.assertEquals(MessageType.NONE, conductor1.getMessageType());
269 * Test for invalid session
274 public void testInvalidSession() throws Exception {
275 session.setValid(false);
276 Future<RpcResult<Void>> resultFuture = session.getMessageDispatchService().packetOut(null, null);
277 if (resultFuture.isDone()) {
278 RpcResult<Void> rpcResult = resultFuture.get();
279 Assert.assertTrue(!rpcResult.getErrors().isEmpty());
281 Iterator<RpcError> it = rpcResult.getErrors().iterator();
282 RpcError rpcError = it.next();
284 Assert.assertTrue(rpcError.getApplicationTag().equals(OFConstants.APPLICATION_TAG));
285 Assert.assertTrue(rpcError.getTag().equals(OFConstants.ERROR_TAG_TIMEOUT));
286 Assert.assertTrue(rpcError.getErrorType().equals(RpcError.ErrorType.TRANSPORT));
292 class MockSessionContext implements SessionContext {
293 private MockConnectionConductor conductor;
294 private Map<SwitchConnectionDistinguisher, ConnectionConductor> map;
295 private IMessageDispatchService messageService;
296 private boolean isValid = true;
297 private CompositeObjectRegistration<ModelDrivenSwitch> registration;
300 MockSessionContext(int conductorNum) {
301 conductor = new MockConnectionConductor(conductorNum);
302 map = new HashMap<SwitchConnectionDistinguisher, ConnectionConductor>();
303 messageService = new MessageDispatchServiceImpl(this);
307 public MockConnectionConductor getPrimaryConductor() {
308 // TODO Auto-generated method stub
313 public GetFeaturesOutput getFeatures() {
314 // TODO Auto-generated method stub
319 public ConnectionConductor getAuxiliaryConductor(SwitchConnectionDistinguisher auxiliaryKey) {
321 return map.get(auxiliaryKey);
325 public Set<Entry<SwitchConnectionDistinguisher, ConnectionConductor>> getAuxiliaryConductors() {
326 // TODO Auto-generated method stub
331 public void addAuxiliaryConductor(SwitchConnectionDistinguisher auxiliaryKey, ConnectionConductor conductorArg) {
332 map.put(auxiliaryKey, conductorArg);
336 public ConnectionConductor removeAuxiliaryConductor(SwitchConnectionDistinguisher connectionCookie) {
337 return map.remove(connectionCookie);
341 public boolean isValid() {
342 // TODO Auto-generated method stub
347 public void setValid(boolean valid) {
352 public SwitchSessionKeyOF getSessionKey() {
353 // TODO Auto-generated method stub
358 public IMessageDispatchService getMessageDispatchService() {
359 // TODO Auto-generated method stub
360 return messageService;
364 public Long getNextXid() {
365 // TODO Auto-generated method stub
370 public Map<Long, PortGrouping> getPhysicalPorts() {
371 // TODO Auto-generated method stub
376 public Set<Long> getPorts() {
377 // TODO Auto-generated method stub
382 public PortGrouping getPhysicalPort(Long portNumber) {
383 // TODO Auto-generated method stub
388 public Boolean getPortBandwidth(Long portNumber) {
389 // TODO Auto-generated method stub
394 public boolean isPortEnabled(long portNumber) {
395 // TODO Auto-generated method stub
400 public boolean isPortEnabled(PortGrouping port) {
401 // TODO Auto-generated method stub
406 public List<PortGrouping> getEnabledPorts() {
407 // TODO Auto-generated method stub
412 public Map<Long, Boolean> getPortsBandwidth() {
413 // TODO Auto-generated method stub
418 public CompositeObjectRegistration<ModelDrivenSwitch> getProviderRegistration() {
423 public void setProviderRegistration(
424 CompositeObjectRegistration<ModelDrivenSwitch> registration) {
425 this.registration = registration;
429 public int getSeed() {
434 * @param seed the seed to set
436 public void setSeed(int seed) {
441 public NotificationEnqueuer getNotificationEnqueuer() {
446 class MockConnectionConductor implements ConnectionConductor, NotificationEnqueuer {
448 private int conductorNum;
449 private MockConnectionAdapter adapter;
451 public MockConnectionConductor(int conductorNumber) {
452 conductorNum = conductorNumber;
453 adapter = new MockConnectionAdapter();
458 // TODO Auto-generated method stub
463 public Short getVersion() {
464 // TODO Auto-generated method stub
469 public CONDUCTOR_STATE getConductorState() {
470 // TODO Auto-generated method stub
475 public void setConductorState(CONDUCTOR_STATE conductorState) {
476 // TODO Auto-generated method stub
481 public Future<Boolean> disconnect() {
482 // TODO Auto-generated method stub
487 public void setSessionContext(SessionContext context) {
488 // TODO Auto-generated method stub
493 public void setConnectionCookie(SwitchConnectionDistinguisher auxiliaryKey) {
494 // TODO Auto-generated method stub
499 public SessionContext getSessionContext() {
500 // TODO Auto-generated method stub
505 public SwitchConnectionDistinguisher getAuxiliaryKey() {
506 if (0 != conductorNum) {
507 SwitchConnectionCookieOFImpl key = new SwitchConnectionCookieOFImpl();
508 key.setAuxiliaryId((short) conductorNum);
516 public ConnectionAdapter getConnectionAdapter() {
517 // TODO Auto-generated method stub
521 public MessageType getMessageType() {
522 return adapter.getMessageType();
526 public void setQueueProcessor(QueueProcessor<OfHeader, DataObject> queueKeeper) {
531 public void setErrorHandler(ErrorHandler errorHandler) {
536 public void setId(int conductorId) {
541 public void enqueueNotification(NotificationQueueWrapper notification) {
547 NONE, BARRIER, FLOWMOD, TABLEMOD, PACKETOUT;
550 class MockConnectionAdapter implements ConnectionAdapter {
552 private MessageType messageType;
553 private ConnectionReadyListener connectionReadyListener;
555 public MockConnectionAdapter() {
556 setMessageType(MessageType.NONE);
560 public Future<RpcResult<BarrierOutput>> barrier(BarrierInput input) {
561 setMessageType(MessageType.BARRIER);
566 public Future<RpcResult<EchoOutput>> echo(EchoInput input) {
567 // TODO Auto-generated method stub
572 public Future<RpcResult<Void>> echoReply(EchoReplyInput input) {
573 // TODO Auto-generated method stub
578 public Future<RpcResult<Void>> experimenter(ExperimenterInput input) {
579 // TODO Auto-generated method stub
584 public Future<RpcResult<Void>> flowMod(FlowModInput input) {
585 setMessageType(MessageType.FLOWMOD);
590 public Future<RpcResult<GetAsyncOutput>> getAsync(GetAsyncInput input) {
591 // TODO Auto-generated method stub
596 public Future<RpcResult<GetConfigOutput>> getConfig(GetConfigInput input) {
597 // TODO Auto-generated method stub
602 public Future<RpcResult<GetFeaturesOutput>> getFeatures(GetFeaturesInput input) {
603 // TODO Auto-generated method stub
608 public Future<RpcResult<GetQueueConfigOutput>> getQueueConfig(GetQueueConfigInput input) {
609 // TODO Auto-generated method stub
614 public Future<RpcResult<Void>> groupMod(GroupModInput input) {
615 // TODO Auto-generated method stub
620 public Future<RpcResult<Void>> hello(HelloInput input) {
621 // TODO Auto-generated method stub
626 public Future<RpcResult<Void>> meterMod(MeterModInput input) {
627 // TODO Auto-generated method stub
632 public Future<RpcResult<Void>> packetOut(PacketOutInput input) {
633 setMessageType(MessageType.PACKETOUT);
638 public Future<RpcResult<Void>> portMod(PortModInput input) {
639 // TODO Auto-generated method stub
644 public Future<RpcResult<RoleRequestOutput>> roleRequest(RoleRequestInput input) {
645 // TODO Auto-generated method stub
650 public Future<RpcResult<Void>> setAsync(SetAsyncInput input) {
651 // TODO Auto-generated method stub
656 public Future<RpcResult<Void>> setConfig(SetConfigInput input) {
657 // TODO Auto-generated method stub
662 public Future<RpcResult<Void>> tableMod(TableModInput input) {
663 setMessageType(MessageType.TABLEMOD);
668 public Future<Boolean> disconnect() {
669 // TODO Auto-generated method stub
674 public boolean isAlive() {
675 // TODO Auto-generated method stub
680 public void setMessageListener(OpenflowProtocolListener messageListener) {
681 // TODO Auto-generated method stub
686 public void setSystemListener(SystemNotificationsListener systemListener) {
687 // TODO Auto-generated method stub
692 public void checkListeners() {
693 // TODO Auto-generated method stub
698 * @return the messageType
700 public MessageType getMessageType() {
705 * @param messageType the messageType to set
707 public void setMessageType(MessageType messageType) {
708 this.messageType = messageType;
712 public void fireConnectionReadyNotification() {
713 connectionReadyListener.onConnectionReady();
717 public void setConnectionReadyListener(
718 ConnectionReadyListener connectionReadyListener) {
719 this.connectionReadyListener = connectionReadyListener;
723 public Future<RpcResult<Void>> multipartRequest(
724 MultipartRequestInput input) {
725 // TODO Auto-generated method stub
730 * @see org.opendaylight.openflowjava.protocol.api.connection.ConnectionAdapter#getRemoteAddress()
733 public InetSocketAddress getRemoteAddress() {
734 // TODO Auto-generated method stub