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.openflow.md.ModelDrivenSwitch;
26 import org.opendaylight.openflowplugin.api.OFConstants;
27 import org.opendaylight.openflowplugin.openflow.md.core.ConnectionConductor;
28 import org.opendaylight.openflowplugin.openflow.md.core.ErrorHandler;
29 import org.opendaylight.openflowplugin.openflow.md.core.NotificationEnqueuer;
30 import org.opendaylight.openflowplugin.openflow.md.core.NotificationQueueWrapper;
31 import org.opendaylight.openflowplugin.api.openflow.md.core.SwitchConnectionDistinguisher;
32 import org.opendaylight.openflowplugin.openflow.md.queue.QueueProcessor;
33 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.BarrierInput;
34 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.BarrierInputBuilder;
35 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.BarrierOutput;
36 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.EchoInput;
37 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.EchoOutput;
38 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.EchoReplyInput;
39 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.ExperimenterInput;
40 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.ExperimenterInputBuilder;
41 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.FlowModInput;
42 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.GetAsyncInput;
43 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.GetAsyncInputBuilder;
44 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.GetAsyncOutput;
45 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.GetConfigInput;
46 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.GetConfigInputBuilder;
47 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.GetConfigOutput;
48 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.GetFeaturesInput;
49 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.GetFeaturesInputBuilder;
50 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.GetFeaturesOutput;
51 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.GetQueueConfigInput;
52 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.GetQueueConfigInputBuilder;
53 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.GetQueueConfigOutput;
54 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.GroupModInput;
55 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.HelloInput;
56 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.MeterModInput;
57 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.MultipartRequestInput;
58 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.MultipartRequestInputBuilder;
59 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.OfHeader;
60 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.OpenflowProtocolListener;
61 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.PacketOutInput;
62 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.PacketOutInputBuilder;
63 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.PortGrouping;
64 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.PortModInput;
65 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.RoleRequestInput;
66 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.RoleRequestInputBuilder;
67 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.RoleRequestOutput;
68 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.SetAsyncInput;
69 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.SetConfigInput;
70 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.TableModInput;
71 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.TableModInputBuilder;
72 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.system.rev130927.SystemNotificationsListener;
73 import org.opendaylight.yangtools.concepts.CompositeObjectRegistration;
74 import org.opendaylight.yangtools.yang.binding.DataObject;
75 import org.opendaylight.yangtools.yang.common.RpcError;
76 import org.opendaylight.yangtools.yang.common.RpcResult;
79 * test for {@link MessageDispatchServiceImpl}
81 public class MessageDispatchServiceImplTest {
83 MockSessionContext session;
86 * @throws java.lang.Exception
89 public void setUp() throws Exception {
90 session = new MockSessionContext(0);
95 * Test barrier message for null cookie
100 public void testBarrierMessageForPrimary() throws Exception {
101 MockConnectionConductor conductor = new MockConnectionConductor(1);
102 SwitchConnectionDistinguisher cookie = conductor.getAuxiliaryKey();
103 BarrierInputBuilder barrierMsg = new BarrierInputBuilder();
104 session.getMessageDispatchService().barrier(barrierMsg.build(), cookie);
105 Assert.assertEquals(MessageType.BARRIER, session.getPrimaryConductor().getMessageType());
109 * Test experimenter message for null cookie
112 public void testExperimenter() {
113 MockConnectionConductor conductor = new MockConnectionConductor(1);
114 SwitchConnectionDistinguisher cookie = conductor.getAuxiliaryKey();
115 ExperimenterInputBuilder experimenterInputBuilder = new ExperimenterInputBuilder();
116 session.getMessageDispatchService().experimenter(experimenterInputBuilder.build(), cookie);
117 Assert.assertEquals(MessageType.NONE, session.getPrimaryConductor().getMessageType());
121 * Test get async input with null cookie
124 public void testGetAsync() throws ExecutionException, InterruptedException {
125 MockConnectionConductor conductor = new MockConnectionConductor(1);
126 SwitchConnectionDistinguisher cookie = conductor.getAuxiliaryKey();
127 GetAsyncInputBuilder getAsyncInputBuilder = new GetAsyncInputBuilder();
128 session.getMessageDispatchService().getAsync(getAsyncInputBuilder.build(), cookie);
129 Assert.assertEquals(MessageType.NONE, session.getPrimaryConductor().getMessageType());
133 * Test get async output with null cookie
136 public void testGetConfig() {
137 MockConnectionConductor conductor = new MockConnectionConductor(1);
138 SwitchConnectionDistinguisher cookie = conductor.getAuxiliaryKey();
139 GetConfigInputBuilder getConfigInputBuilder = new GetConfigInputBuilder();
140 session.getMessageDispatchService().getConfig(getConfigInputBuilder.build(), cookie);
141 Assert.assertEquals(MessageType.NONE, session.getPrimaryConductor().getMessageType());
145 * Test get features with null cookie
148 public void testGetFeatures() {
149 MockConnectionConductor conductor = new MockConnectionConductor(1);
150 SwitchConnectionDistinguisher cookie = conductor.getAuxiliaryKey();
151 GetFeaturesInputBuilder getFeaturesInputBuilder = new GetFeaturesInputBuilder();
152 session.getMessageDispatchService().getFeatures(getFeaturesInputBuilder.build(), cookie);
153 Assert.assertEquals(MessageType.NONE, session.getPrimaryConductor().getMessageType());
157 * Test get queue config with null cookie
160 public void testGetQueueConfig() {
161 MockConnectionConductor conductor = new MockConnectionConductor(1);
162 SwitchConnectionDistinguisher cookie = conductor.getAuxiliaryKey();
163 GetQueueConfigInputBuilder getQueueConfigInputBuilder = new GetQueueConfigInputBuilder();
164 session.getMessageDispatchService().getQueueConfig(getQueueConfigInputBuilder.build(), cookie);
165 Assert.assertEquals(MessageType.NONE, session.getPrimaryConductor().getMessageType());
169 * Test multipart request with null cookie
172 public void testGetMultipart() {
173 MockConnectionConductor conductor = new MockConnectionConductor(1);
174 SwitchConnectionDistinguisher cookie = conductor.getAuxiliaryKey();
175 MultipartRequestInputBuilder multipartRequestInputBuilder = new MultipartRequestInputBuilder();
176 session.getMessageDispatchService().multipartRequest(multipartRequestInputBuilder.build(), cookie);
177 Assert.assertEquals(MessageType.NONE, session.getPrimaryConductor().getMessageType());
181 * Test role request with null cookie
184 public void testRoleRequest() {
185 MockConnectionConductor conductor = new MockConnectionConductor(1);
186 SwitchConnectionDistinguisher cookie = conductor.getAuxiliaryKey();
187 RoleRequestInputBuilder roleRequestInputBuilder = new RoleRequestInputBuilder();
188 session.getMessageDispatchService().roleRequest(roleRequestInputBuilder.build(), cookie);
189 Assert.assertEquals(MessageType.NONE, session.getPrimaryConductor().getMessageType());
193 * Test table mod with null cookie
196 public void testTableMod() {
197 MockConnectionConductor conductor = new MockConnectionConductor(1);
198 SwitchConnectionDistinguisher cookie = conductor.getAuxiliaryKey();
199 TableModInputBuilder tableModInputBuilder = new TableModInputBuilder();
200 session.getMessageDispatchService().tableMod(tableModInputBuilder.build(), cookie);
201 Assert.assertEquals(MessageType.TABLEMOD, session.getPrimaryConductor().getMessageType());
206 * Test packet out message for primary connection
211 public void testPacketOutMessageForPrimary() throws Exception {
212 session.getMessageDispatchService().packetOut(null, null);
213 Assert.assertEquals(MessageType.PACKETOUT, session.getPrimaryConductor().getMessageType());
217 * Test packet out message for auxiliary connection
222 public void testPacketOutMessageForAuxiliary() throws Exception {
223 MockConnectionConductor conductor = new MockConnectionConductor(1);
224 SwitchConnectionDistinguisher cookie = conductor.getAuxiliaryKey();
225 session.addAuxiliaryConductor(cookie, conductor);
226 session.getMessageDispatchService().packetOut(null, cookie);
227 Assert.assertEquals(MessageType.NONE, session.getPrimaryConductor().getMessageType());
228 conductor = (MockConnectionConductor) session.getAuxiliaryConductor(cookie);
229 Assert.assertEquals(MessageType.PACKETOUT, conductor.getMessageType());
233 * Test packet out message when multiple auxiliary connection exist
238 public void testPacketOutMessageForMultipleAuxiliary() throws Exception {
239 MockConnectionConductor conductor1 = new MockConnectionConductor(1);
240 SwitchConnectionDistinguisher cookie1 = conductor1.getAuxiliaryKey();
241 session.addAuxiliaryConductor(cookie1, conductor1);
242 MockConnectionConductor conductor2 = new MockConnectionConductor(2);
243 SwitchConnectionDistinguisher cookie2 = conductor2.getAuxiliaryKey();
244 session.addAuxiliaryConductor(cookie2, conductor2);
245 MockConnectionConductor conductor3 = new MockConnectionConductor(3);
246 SwitchConnectionDistinguisher cookie3 = conductor3.getAuxiliaryKey();
247 session.addAuxiliaryConductor(cookie3, conductor3);
248 PacketOutInputBuilder builder = new PacketOutInputBuilder();
250 session.getMessageDispatchService().packetOut(builder.build(), cookie2);
252 Assert.assertEquals(MessageType.NONE, session.getPrimaryConductor().getMessageType());
254 conductor3 = (MockConnectionConductor) session.getAuxiliaryConductor(cookie3);
255 Assert.assertEquals(MessageType.NONE, conductor3.getMessageType());
257 conductor2 = (MockConnectionConductor) session.getAuxiliaryConductor(cookie2);
258 Assert.assertEquals(MessageType.PACKETOUT, conductor2.getMessageType());
260 conductor1 = (MockConnectionConductor) session.getAuxiliaryConductor(cookie1);
261 Assert.assertEquals(MessageType.NONE, conductor1.getMessageType());
266 * Test for invalid session
271 public void testInvalidSession() throws Exception {
272 session.setValid(false);
273 Future<RpcResult<Void>> resultFuture = session.getMessageDispatchService().packetOut(null, null);
274 if (resultFuture.isDone()) {
275 RpcResult<Void> rpcResult = resultFuture.get();
276 Assert.assertTrue(!rpcResult.getErrors().isEmpty());
278 Iterator<RpcError> it = rpcResult.getErrors().iterator();
279 RpcError rpcError = it.next();
281 Assert.assertTrue(rpcError.getApplicationTag().equals(OFConstants.APPLICATION_TAG));
282 Assert.assertTrue(rpcError.getTag().equals(OFConstants.ERROR_TAG_TIMEOUT));
283 Assert.assertTrue(rpcError.getErrorType().equals(RpcError.ErrorType.TRANSPORT));
289 class MockSessionContext implements SessionContext {
290 private MockConnectionConductor conductor;
291 private Map<SwitchConnectionDistinguisher, ConnectionConductor> map;
292 private IMessageDispatchService messageService;
293 private boolean isValid = true;
294 private CompositeObjectRegistration<ModelDrivenSwitch> registration;
297 MockSessionContext(int conductorNum) {
298 conductor = new MockConnectionConductor(conductorNum);
299 map = new HashMap<SwitchConnectionDistinguisher, ConnectionConductor>();
300 messageService = new MessageDispatchServiceImpl(this);
304 public MockConnectionConductor getPrimaryConductor() {
305 // TODO Auto-generated method stub
310 public GetFeaturesOutput getFeatures() {
311 // TODO Auto-generated method stub
316 public ConnectionConductor getAuxiliaryConductor(SwitchConnectionDistinguisher auxiliaryKey) {
318 return map.get(auxiliaryKey);
322 public Set<Entry<SwitchConnectionDistinguisher, ConnectionConductor>> getAuxiliaryConductors() {
323 // TODO Auto-generated method stub
328 public void addAuxiliaryConductor(SwitchConnectionDistinguisher auxiliaryKey, ConnectionConductor conductorArg) {
329 map.put(auxiliaryKey, conductorArg);
333 public ConnectionConductor removeAuxiliaryConductor(SwitchConnectionDistinguisher connectionCookie) {
334 return map.remove(connectionCookie);
338 public boolean isValid() {
339 // TODO Auto-generated method stub
344 public void setValid(boolean valid) {
349 public SwitchSessionKeyOF getSessionKey() {
350 // TODO Auto-generated method stub
355 public IMessageDispatchService getMessageDispatchService() {
356 // TODO Auto-generated method stub
357 return messageService;
361 public Long getNextXid() {
362 // TODO Auto-generated method stub
367 public Map<Long, PortGrouping> getPhysicalPorts() {
368 // TODO Auto-generated method stub
373 public Set<Long> getPorts() {
374 // TODO Auto-generated method stub
379 public PortGrouping getPhysicalPort(Long portNumber) {
380 // TODO Auto-generated method stub
385 public Boolean getPortBandwidth(Long portNumber) {
386 // TODO Auto-generated method stub
391 public boolean isPortEnabled(long portNumber) {
392 // TODO Auto-generated method stub
397 public boolean isPortEnabled(PortGrouping port) {
398 // TODO Auto-generated method stub
403 public List<PortGrouping> getEnabledPorts() {
404 // TODO Auto-generated method stub
409 public Map<Long, Boolean> getPortsBandwidth() {
410 // TODO Auto-generated method stub
415 public CompositeObjectRegistration<ModelDrivenSwitch> getProviderRegistration() {
420 public void setProviderRegistration(
421 CompositeObjectRegistration<ModelDrivenSwitch> registration) {
422 this.registration = registration;
426 public int getSeed() {
431 * @param seed the seed to set
433 public void setSeed(int seed) {
438 public NotificationEnqueuer getNotificationEnqueuer() {
443 class MockConnectionConductor implements ConnectionConductor, NotificationEnqueuer {
445 private int conductorNum;
446 private MockConnectionAdapter adapter;
448 public MockConnectionConductor(int conductorNumber) {
449 conductorNum = conductorNumber;
450 adapter = new MockConnectionAdapter();
455 // TODO Auto-generated method stub
460 public Short getVersion() {
461 // TODO Auto-generated method stub
466 public CONDUCTOR_STATE getConductorState() {
467 // TODO Auto-generated method stub
472 public void setConductorState(CONDUCTOR_STATE conductorState) {
473 // TODO Auto-generated method stub
478 public Future<Boolean> disconnect() {
479 // TODO Auto-generated method stub
484 public void setSessionContext(SessionContext context) {
485 // TODO Auto-generated method stub
490 public void setConnectionCookie(SwitchConnectionDistinguisher auxiliaryKey) {
491 // TODO Auto-generated method stub
496 public SessionContext getSessionContext() {
497 // TODO Auto-generated method stub
502 public SwitchConnectionDistinguisher getAuxiliaryKey() {
503 if (0 != conductorNum) {
504 SwitchConnectionCookieOFImpl key = new SwitchConnectionCookieOFImpl();
505 key.setAuxiliaryId((short) conductorNum);
513 public ConnectionAdapter getConnectionAdapter() {
514 // TODO Auto-generated method stub
518 public MessageType getMessageType() {
519 return adapter.getMessageType();
523 public void setQueueProcessor(QueueProcessor<OfHeader, DataObject> queueKeeper) {
528 public void setErrorHandler(ErrorHandler errorHandler) {
533 public void setId(int conductorId) {
538 public void enqueueNotification(NotificationQueueWrapper notification) {
544 NONE, BARRIER, FLOWMOD, TABLEMOD, PACKETOUT;
547 class MockConnectionAdapter implements ConnectionAdapter {
549 private MessageType messageType;
550 private ConnectionReadyListener connectionReadyListener;
552 public MockConnectionAdapter() {
553 setMessageType(MessageType.NONE);
557 public Future<RpcResult<BarrierOutput>> barrier(BarrierInput input) {
558 setMessageType(MessageType.BARRIER);
563 public Future<RpcResult<EchoOutput>> echo(EchoInput input) {
564 // TODO Auto-generated method stub
569 public Future<RpcResult<Void>> echoReply(EchoReplyInput input) {
570 // TODO Auto-generated method stub
575 public Future<RpcResult<Void>> experimenter(ExperimenterInput input) {
576 // TODO Auto-generated method stub
581 public Future<RpcResult<Void>> flowMod(FlowModInput input) {
582 setMessageType(MessageType.FLOWMOD);
587 public Future<RpcResult<GetAsyncOutput>> getAsync(GetAsyncInput input) {
588 // TODO Auto-generated method stub
593 public Future<RpcResult<GetConfigOutput>> getConfig(GetConfigInput input) {
594 // TODO Auto-generated method stub
599 public Future<RpcResult<GetFeaturesOutput>> getFeatures(GetFeaturesInput input) {
600 // TODO Auto-generated method stub
605 public Future<RpcResult<GetQueueConfigOutput>> getQueueConfig(GetQueueConfigInput input) {
606 // TODO Auto-generated method stub
611 public Future<RpcResult<Void>> groupMod(GroupModInput input) {
612 // TODO Auto-generated method stub
617 public Future<RpcResult<Void>> hello(HelloInput input) {
618 // TODO Auto-generated method stub
623 public Future<RpcResult<Void>> meterMod(MeterModInput input) {
624 // TODO Auto-generated method stub
629 public Future<RpcResult<Void>> packetOut(PacketOutInput input) {
630 setMessageType(MessageType.PACKETOUT);
635 public Future<RpcResult<Void>> portMod(PortModInput input) {
636 // TODO Auto-generated method stub
641 public Future<RpcResult<RoleRequestOutput>> roleRequest(RoleRequestInput input) {
642 // TODO Auto-generated method stub
647 public Future<RpcResult<Void>> setAsync(SetAsyncInput input) {
648 // TODO Auto-generated method stub
653 public Future<RpcResult<Void>> setConfig(SetConfigInput input) {
654 // TODO Auto-generated method stub
659 public Future<RpcResult<Void>> tableMod(TableModInput input) {
660 setMessageType(MessageType.TABLEMOD);
665 public Future<Boolean> disconnect() {
666 // TODO Auto-generated method stub
671 public boolean isAlive() {
672 // TODO Auto-generated method stub
677 public void setMessageListener(OpenflowProtocolListener messageListener) {
678 // TODO Auto-generated method stub
683 public void setSystemListener(SystemNotificationsListener systemListener) {
684 // TODO Auto-generated method stub
689 public void checkListeners() {
690 // TODO Auto-generated method stub
695 * @return the messageType
697 public MessageType getMessageType() {
702 * @param messageType the messageType to set
704 public void setMessageType(MessageType messageType) {
705 this.messageType = messageType;
709 public void fireConnectionReadyNotification() {
710 connectionReadyListener.onConnectionReady();
714 public void setConnectionReadyListener(
715 ConnectionReadyListener connectionReadyListener) {
716 this.connectionReadyListener = connectionReadyListener;
720 public Future<RpcResult<Void>> multipartRequest(
721 MultipartRequestInput input) {
722 // TODO Auto-generated method stub
727 * @see org.opendaylight.openflowjava.protocol.api.connection.ConnectionAdapter#getRemoteAddress()
730 public InetSocketAddress getRemoteAddress() {
731 // TODO Auto-generated method stub