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;
19 import org.junit.Assert;
20 import org.junit.Before;
21 import org.junit.Test;
22 import org.opendaylight.openflowjava.protocol.api.connection.ConnectionAdapter;
23 import org.opendaylight.openflowjava.protocol.api.connection.ConnectionReadyListener;
24 import org.opendaylight.openflowplugin.openflow.md.ModelDrivenSwitch;
25 import org.opendaylight.openflowplugin.api.OFConstants;
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.QueueProcessor;
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.ExperimenterInputBuilder;
38 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.FlowModInput;
39 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.GetAsyncInput;
40 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.GetAsyncInputBuilder;
41 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.GetAsyncOutput;
42 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.GetConfigInput;
43 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.GetConfigInputBuilder;
44 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.GetConfigOutput;
45 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.GetFeaturesInput;
46 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.GetFeaturesInputBuilder;
47 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.GetFeaturesOutput;
48 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.GetQueueConfigInput;
49 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.GetQueueConfigInputBuilder;
50 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.GetQueueConfigOutput;
51 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.GroupModInput;
52 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.HelloInput;
53 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.MeterModInput;
54 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.MultipartRequestInput;
55 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.MultipartRequestInputBuilder;
56 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.OfHeader;
57 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.OpenflowProtocolListener;
58 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.PacketOutInput;
59 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.PacketOutInputBuilder;
60 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.PortGrouping;
61 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.PortModInput;
62 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.RoleRequestInput;
63 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.RoleRequestInputBuilder;
64 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.RoleRequestOutput;
65 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.SetAsyncInput;
66 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.SetConfigInput;
67 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.TableModInput;
68 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.TableModInputBuilder;
69 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.system.rev130927.SystemNotificationsListener;
70 import org.opendaylight.yangtools.concepts.CompositeObjectRegistration;
71 import org.opendaylight.yangtools.yang.binding.DataObject;
72 import org.opendaylight.yangtools.yang.common.RpcError;
73 import org.opendaylight.yangtools.yang.common.RpcResult;
76 * test for {@link MessageDispatchServiceImpl}
78 public class MessageDispatchServiceImplTest {
80 MockSessionContext session;
83 * @throws java.lang.Exception
86 public void setUp() throws Exception {
87 session = new MockSessionContext(0);
92 * Test barrier message for null cookie
97 public void testBarrierMessageForPrimary() throws Exception {
98 MockConnectionConductor conductor = new MockConnectionConductor(1);
99 SwitchConnectionDistinguisher cookie = conductor.getAuxiliaryKey();
100 BarrierInputBuilder barrierMsg = new BarrierInputBuilder();
101 session.getMessageDispatchService().barrier(barrierMsg.build(), cookie);
102 Assert.assertEquals(MessageType.BARRIER, session.getPrimaryConductor().getMessageType());
106 * Test experimenter message for null cookie
109 public void testExperimenter() {
110 MockConnectionConductor conductor = new MockConnectionConductor(1);
111 SwitchConnectionDistinguisher cookie = conductor.getAuxiliaryKey();
112 ExperimenterInputBuilder experimenterInputBuilder = new ExperimenterInputBuilder();
113 session.getMessageDispatchService().experimenter(experimenterInputBuilder.build(), cookie);
114 Assert.assertEquals(MessageType.NONE, session.getPrimaryConductor().getMessageType());
118 * Test get async input with null cookie
121 public void testGetAsync() throws ExecutionException, InterruptedException {
122 MockConnectionConductor conductor = new MockConnectionConductor(1);
123 SwitchConnectionDistinguisher cookie = conductor.getAuxiliaryKey();
124 GetAsyncInputBuilder getAsyncInputBuilder = new GetAsyncInputBuilder();
125 session.getMessageDispatchService().getAsync(getAsyncInputBuilder.build(), cookie);
126 Assert.assertEquals(MessageType.NONE, session.getPrimaryConductor().getMessageType());
130 * Test get async output with null cookie
133 public void testGetConfig() {
134 MockConnectionConductor conductor = new MockConnectionConductor(1);
135 SwitchConnectionDistinguisher cookie = conductor.getAuxiliaryKey();
136 GetConfigInputBuilder getConfigInputBuilder = new GetConfigInputBuilder();
137 session.getMessageDispatchService().getConfig(getConfigInputBuilder.build(), cookie);
138 Assert.assertEquals(MessageType.NONE, session.getPrimaryConductor().getMessageType());
142 * Test get features with null cookie
145 public void testGetFeatures() {
146 MockConnectionConductor conductor = new MockConnectionConductor(1);
147 SwitchConnectionDistinguisher cookie = conductor.getAuxiliaryKey();
148 GetFeaturesInputBuilder getFeaturesInputBuilder = new GetFeaturesInputBuilder();
149 session.getMessageDispatchService().getFeatures(getFeaturesInputBuilder.build(), cookie);
150 Assert.assertEquals(MessageType.NONE, session.getPrimaryConductor().getMessageType());
154 * Test get queue config with null cookie
157 public void testGetQueueConfig() {
158 MockConnectionConductor conductor = new MockConnectionConductor(1);
159 SwitchConnectionDistinguisher cookie = conductor.getAuxiliaryKey();
160 GetQueueConfigInputBuilder getQueueConfigInputBuilder = new GetQueueConfigInputBuilder();
161 session.getMessageDispatchService().getQueueConfig(getQueueConfigInputBuilder.build(), cookie);
162 Assert.assertEquals(MessageType.NONE, session.getPrimaryConductor().getMessageType());
166 * Test multipart request with null cookie
169 public void testGetMultipart() {
170 MockConnectionConductor conductor = new MockConnectionConductor(1);
171 SwitchConnectionDistinguisher cookie = conductor.getAuxiliaryKey();
172 MultipartRequestInputBuilder multipartRequestInputBuilder = new MultipartRequestInputBuilder();
173 session.getMessageDispatchService().multipartRequest(multipartRequestInputBuilder.build(), cookie);
174 Assert.assertEquals(MessageType.NONE, session.getPrimaryConductor().getMessageType());
178 * Test role request with null cookie
181 public void testRoleRequest() {
182 MockConnectionConductor conductor = new MockConnectionConductor(1);
183 SwitchConnectionDistinguisher cookie = conductor.getAuxiliaryKey();
184 RoleRequestInputBuilder roleRequestInputBuilder = new RoleRequestInputBuilder();
185 session.getMessageDispatchService().roleRequest(roleRequestInputBuilder.build(), cookie);
186 Assert.assertEquals(MessageType.NONE, session.getPrimaryConductor().getMessageType());
190 * Test table mod with null cookie
193 public void testTableMod() {
194 MockConnectionConductor conductor = new MockConnectionConductor(1);
195 SwitchConnectionDistinguisher cookie = conductor.getAuxiliaryKey();
196 TableModInputBuilder tableModInputBuilder = new TableModInputBuilder();
197 session.getMessageDispatchService().tableMod(tableModInputBuilder.build(), cookie);
198 Assert.assertEquals(MessageType.TABLEMOD, session.getPrimaryConductor().getMessageType());
203 * Test packet out message for primary connection
208 public void testPacketOutMessageForPrimary() throws Exception {
209 session.getMessageDispatchService().packetOut(null, null);
210 Assert.assertEquals(MessageType.PACKETOUT, session.getPrimaryConductor().getMessageType());
214 * Test packet out message for auxiliary connection
219 public void testPacketOutMessageForAuxiliary() throws Exception {
220 MockConnectionConductor conductor = new MockConnectionConductor(1);
221 SwitchConnectionDistinguisher cookie = conductor.getAuxiliaryKey();
222 session.addAuxiliaryConductor(cookie, conductor);
223 session.getMessageDispatchService().packetOut(null, cookie);
224 Assert.assertEquals(MessageType.NONE, session.getPrimaryConductor().getMessageType());
225 conductor = (MockConnectionConductor) session.getAuxiliaryConductor(cookie);
226 Assert.assertEquals(MessageType.PACKETOUT, conductor.getMessageType());
230 * Test packet out message when multiple auxiliary connection exist
235 public void testPacketOutMessageForMultipleAuxiliary() throws Exception {
236 MockConnectionConductor conductor1 = new MockConnectionConductor(1);
237 SwitchConnectionDistinguisher cookie1 = conductor1.getAuxiliaryKey();
238 session.addAuxiliaryConductor(cookie1, conductor1);
239 MockConnectionConductor conductor2 = new MockConnectionConductor(2);
240 SwitchConnectionDistinguisher cookie2 = conductor2.getAuxiliaryKey();
241 session.addAuxiliaryConductor(cookie2, conductor2);
242 MockConnectionConductor conductor3 = new MockConnectionConductor(3);
243 SwitchConnectionDistinguisher cookie3 = conductor3.getAuxiliaryKey();
244 session.addAuxiliaryConductor(cookie3, conductor3);
245 PacketOutInputBuilder builder = new PacketOutInputBuilder();
247 session.getMessageDispatchService().packetOut(builder.build(), cookie2);
249 Assert.assertEquals(MessageType.NONE, session.getPrimaryConductor().getMessageType());
251 conductor3 = (MockConnectionConductor) session.getAuxiliaryConductor(cookie3);
252 Assert.assertEquals(MessageType.NONE, conductor3.getMessageType());
254 conductor2 = (MockConnectionConductor) session.getAuxiliaryConductor(cookie2);
255 Assert.assertEquals(MessageType.PACKETOUT, conductor2.getMessageType());
257 conductor1 = (MockConnectionConductor) session.getAuxiliaryConductor(cookie1);
258 Assert.assertEquals(MessageType.NONE, conductor1.getMessageType());
263 * Test for invalid session
268 public void testInvalidSession() throws Exception {
269 session.setValid(false);
270 Future<RpcResult<Void>> resultFuture = session.getMessageDispatchService().packetOut(null, null);
271 if (resultFuture.isDone()) {
272 RpcResult<Void> rpcResult = resultFuture.get();
273 Assert.assertTrue(!rpcResult.getErrors().isEmpty());
275 Iterator<RpcError> it = rpcResult.getErrors().iterator();
276 RpcError rpcError = it.next();
278 Assert.assertTrue(rpcError.getApplicationTag().equals(OFConstants.APPLICATION_TAG));
279 Assert.assertTrue(rpcError.getTag().equals(OFConstants.ERROR_TAG_TIMEOUT));
280 Assert.assertTrue(rpcError.getErrorType().equals(RpcError.ErrorType.TRANSPORT));
286 class MockSessionContext implements SessionContext {
287 private MockConnectionConductor conductor;
288 private Map<SwitchConnectionDistinguisher, ConnectionConductor> map;
289 private IMessageDispatchService messageService;
290 private boolean isValid = true;
291 private CompositeObjectRegistration<ModelDrivenSwitch> registration;
294 MockSessionContext(int conductorNum) {
295 conductor = new MockConnectionConductor(conductorNum);
296 map = new HashMap<SwitchConnectionDistinguisher, ConnectionConductor>();
297 messageService = new MessageDispatchServiceImpl(this);
301 public MockConnectionConductor getPrimaryConductor() {
302 // TODO Auto-generated method stub
307 public GetFeaturesOutput getFeatures() {
308 // TODO Auto-generated method stub
313 public ConnectionConductor getAuxiliaryConductor(SwitchConnectionDistinguisher auxiliaryKey) {
315 return map.get(auxiliaryKey);
319 public Set<Entry<SwitchConnectionDistinguisher, ConnectionConductor>> getAuxiliaryConductors() {
320 // TODO Auto-generated method stub
325 public void addAuxiliaryConductor(SwitchConnectionDistinguisher auxiliaryKey, ConnectionConductor conductorArg) {
326 map.put(auxiliaryKey, conductorArg);
330 public ConnectionConductor removeAuxiliaryConductor(SwitchConnectionDistinguisher connectionCookie) {
331 return map.remove(connectionCookie);
335 public boolean isValid() {
336 // TODO Auto-generated method stub
341 public void setValid(boolean valid) {
346 public SwitchSessionKeyOF getSessionKey() {
347 // TODO Auto-generated method stub
352 public IMessageDispatchService getMessageDispatchService() {
353 // TODO Auto-generated method stub
354 return messageService;
358 public Long getNextXid() {
359 // TODO Auto-generated method stub
364 public Map<Long, PortGrouping> getPhysicalPorts() {
365 // TODO Auto-generated method stub
370 public Set<Long> getPorts() {
371 // TODO Auto-generated method stub
376 public PortGrouping getPhysicalPort(Long portNumber) {
377 // TODO Auto-generated method stub
382 public Boolean getPortBandwidth(Long portNumber) {
383 // TODO Auto-generated method stub
388 public boolean isPortEnabled(long portNumber) {
389 // TODO Auto-generated method stub
394 public boolean isPortEnabled(PortGrouping port) {
395 // TODO Auto-generated method stub
400 public List<PortGrouping> getEnabledPorts() {
401 // TODO Auto-generated method stub
406 public Map<Long, Boolean> getPortsBandwidth() {
407 // TODO Auto-generated method stub
412 public CompositeObjectRegistration<ModelDrivenSwitch> getProviderRegistration() {
417 public void setProviderRegistration(
418 CompositeObjectRegistration<ModelDrivenSwitch> registration) {
419 this.registration = registration;
423 public int getSeed() {
428 * @param seed the seed to set
430 public void setSeed(int seed) {
435 class MockConnectionConductor implements ConnectionConductor {
437 private int conductorNum;
438 private MockConnectionAdapter adapter;
440 public MockConnectionConductor(int conductorNumber) {
441 conductorNum = conductorNumber;
442 adapter = new MockConnectionAdapter();
447 // TODO Auto-generated method stub
452 public Short getVersion() {
453 // TODO Auto-generated method stub
458 public CONDUCTOR_STATE getConductorState() {
459 // TODO Auto-generated method stub
464 public void setConductorState(CONDUCTOR_STATE conductorState) {
465 // TODO Auto-generated method stub
470 public Future<Boolean> disconnect() {
471 // TODO Auto-generated method stub
476 public void setSessionContext(SessionContext context) {
477 // TODO Auto-generated method stub
482 public void setConnectionCookie(SwitchConnectionDistinguisher auxiliaryKey) {
483 // TODO Auto-generated method stub
488 public SessionContext getSessionContext() {
489 // TODO Auto-generated method stub
494 public SwitchConnectionDistinguisher getAuxiliaryKey() {
495 if (0 != conductorNum) {
496 SwitchConnectionCookieOFImpl key = new SwitchConnectionCookieOFImpl();
497 key.setAuxiliaryId((short) conductorNum);
505 public ConnectionAdapter getConnectionAdapter() {
506 // TODO Auto-generated method stub
510 public MessageType getMessageType() {
511 return adapter.getMessageType();
515 public void setQueueProcessor(QueueProcessor<OfHeader, DataObject> queueKeeper) {
520 public void setErrorHandler(ErrorHandler errorHandler) {
525 public void setId(int conductorId) {
531 NONE, BARRIER, FLOWMOD, TABLEMOD, PACKETOUT;
534 class MockConnectionAdapter implements ConnectionAdapter {
536 private MessageType messageType;
537 private ConnectionReadyListener connectionReadyListener;
539 public MockConnectionAdapter() {
540 setMessageType(MessageType.NONE);
544 public Future<RpcResult<BarrierOutput>> barrier(BarrierInput input) {
545 setMessageType(MessageType.BARRIER);
550 public Future<RpcResult<EchoOutput>> echo(EchoInput input) {
551 // TODO Auto-generated method stub
556 public Future<RpcResult<Void>> echoReply(EchoReplyInput input) {
557 // TODO Auto-generated method stub
562 public Future<RpcResult<Void>> experimenter(ExperimenterInput input) {
563 // TODO Auto-generated method stub
568 public Future<RpcResult<Void>> flowMod(FlowModInput input) {
569 setMessageType(MessageType.FLOWMOD);
574 public Future<RpcResult<GetAsyncOutput>> getAsync(GetAsyncInput input) {
575 // TODO Auto-generated method stub
580 public Future<RpcResult<GetConfigOutput>> getConfig(GetConfigInput input) {
581 // TODO Auto-generated method stub
586 public Future<RpcResult<GetFeaturesOutput>> getFeatures(GetFeaturesInput input) {
587 // TODO Auto-generated method stub
592 public Future<RpcResult<GetQueueConfigOutput>> getQueueConfig(GetQueueConfigInput input) {
593 // TODO Auto-generated method stub
598 public Future<RpcResult<Void>> groupMod(GroupModInput input) {
599 // TODO Auto-generated method stub
604 public Future<RpcResult<Void>> hello(HelloInput input) {
605 // TODO Auto-generated method stub
610 public Future<RpcResult<Void>> meterMod(MeterModInput input) {
611 // TODO Auto-generated method stub
616 public Future<RpcResult<Void>> packetOut(PacketOutInput input) {
617 setMessageType(MessageType.PACKETOUT);
622 public Future<RpcResult<Void>> portMod(PortModInput input) {
623 // TODO Auto-generated method stub
628 public Future<RpcResult<RoleRequestOutput>> roleRequest(RoleRequestInput input) {
629 // TODO Auto-generated method stub
634 public Future<RpcResult<Void>> setAsync(SetAsyncInput input) {
635 // TODO Auto-generated method stub
640 public Future<RpcResult<Void>> setConfig(SetConfigInput input) {
641 // TODO Auto-generated method stub
646 public Future<RpcResult<Void>> tableMod(TableModInput input) {
647 setMessageType(MessageType.TABLEMOD);
652 public Future<Boolean> disconnect() {
653 // TODO Auto-generated method stub
658 public boolean isAlive() {
659 // TODO Auto-generated method stub
664 public void setMessageListener(OpenflowProtocolListener messageListener) {
665 // TODO Auto-generated method stub
670 public void setSystemListener(SystemNotificationsListener systemListener) {
671 // TODO Auto-generated method stub
676 public void checkListeners() {
677 // TODO Auto-generated method stub
682 * @return the messageType
684 public MessageType getMessageType() {
689 * @param messageType the messageType to set
691 public void setMessageType(MessageType messageType) {
692 this.messageType = messageType;
696 public void fireConnectionReadyNotification() {
697 connectionReadyListener.onConnectionReady();
701 public void setConnectionReadyListener(
702 ConnectionReadyListener connectionReadyListener) {
703 this.connectionReadyListener = connectionReadyListener;
707 public Future<RpcResult<Void>> multipartRequest(
708 MultipartRequestInput input) {
709 // TODO Auto-generated method stub
714 * @see org.opendaylight.openflowjava.protocol.api.connection.ConnectionAdapter#getRemoteAddress()
717 public InetSocketAddress getRemoteAddress() {
718 // TODO Auto-generated method stub