Jian Li
Committed by Gerrit Code Review

Refactor the logic on collecting OpenFlow message statistics

Change-Id: I34c209c0ca90cb094ed5f82c96a8a43d3519b807
Showing 21 changed files with 153 additions and 1028 deletions
......@@ -65,13 +65,6 @@ public interface OpenFlowController {
OpenFlowSwitch getEqualSwitch(Dpid dpid);
/**
* If this set to be true, all incoming events are monitored.
* Other wise, only stats related incoming events are monitored
* @param monitor monitoring flag
*/
void monitorAllEvents(boolean monitor);
/**
* Register a listener for meta events that occur to OF
* devices.
* @param listener the listener to notify
......@@ -86,6 +79,20 @@ public interface OpenFlowController {
void removeListener(OpenFlowSwitchListener listener);
/**
* Register a listener for all OF msg types.
*
* @param listener the listener to notify
*/
void addMessageListener(OpenFlowMessageListener listener);
/**
* Unregister a listener for all OF msg types.
*
* @param listener the listener to notify
*/
void removeMessageListener(OpenFlowMessageListener listener);
/**
* Register a listener for packet events.
* @param priority the importance of this listener, lower values are more important
* @param listener the listener to notify
......
/*
* Copyright 2016-present Open Networking Laboratory
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.onosproject.openflow.controller;
import org.projectfloodlight.openflow.protocol.OFMessage;
import java.util.List;
/**
* Notifies providers about all OpenFlow messages.
*/
public interface OpenFlowMessageListener {
/**
* Handles all incoming OpenFlow messages.
*
* @param dpid the switch where the message generated
* @param msg raw OpenFlow message
*/
void handleIncomingMessage(Dpid dpid, OFMessage msg);
/**
* Handles all outgoing OpenFlow messages.
*
* @param dpid the switch where the message to be sent
* @param msgs a collection of raw OpenFlow message
*/
void handleOutgoingMessage(Dpid dpid, List<OFMessage> msgs);
}
......@@ -157,18 +157,4 @@ public interface OpenFlowSwitch {
* @return string representation of the connection to the device
*/
String channelId();
/**
* Registers a listener for OF msg events.
*
* @param listener the listener to notify
*/
void addEventListener(OpenFlowEventListener listener);
/**
* Unregisters a listener.
*
* @param listener the listener to unregister
*/
void removeEventListener(OpenFlowEventListener listener);
}
......
......@@ -22,7 +22,6 @@ import org.onlab.packet.IpAddress;
import org.onosproject.net.Device;
import org.onosproject.net.driver.AbstractHandlerBehaviour;
import org.onosproject.openflow.controller.Dpid;
import org.onosproject.openflow.controller.OpenFlowEventListener;
import org.onosproject.openflow.controller.RoleState;
import org.projectfloodlight.openflow.protocol.OFDescStatsReply;
import org.projectfloodlight.openflow.protocol.OFErrorMsg;
......@@ -37,7 +36,6 @@ import org.projectfloodlight.openflow.protocol.OFPortDescStatsReply;
import org.projectfloodlight.openflow.protocol.OFPortStatus;
import org.projectfloodlight.openflow.protocol.OFRoleReply;
import org.projectfloodlight.openflow.protocol.OFRoleRequest;
import org.projectfloodlight.openflow.protocol.OFType;
import org.projectfloodlight.openflow.protocol.OFVersion;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
......@@ -48,16 +46,10 @@ import java.net.SocketAddress;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.Set;
import java.util.concurrent.CopyOnWriteArraySet;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.atomic.AtomicInteger;
import java.util.concurrent.atomic.AtomicReference;
import java.util.stream.Collectors;
import static org.onlab.util.Tools.groupedThreads;
/**
* An abstract representation of an OpenFlow switch. Can be extended by others
* to serve as a base for their vendor specific representation of a switch.
......@@ -90,11 +82,6 @@ public abstract class AbstractOpenFlowSwitch extends AbstractHandlerBehaviour
protected OFFeaturesReply features;
protected OFDescStatsReply desc;
protected Set<OpenFlowEventListener> ofOutgoingMsgListener = new CopyOnWriteArraySet<>();
protected ExecutorService executorMsgs =
Executors.newCachedThreadPool(groupedThreads("onos/of", "event-outgoing-msg-stats-%d", log));
// messagesPendingMastership is used as synchronization variable for
// all mastership related changes. In this block, mastership (including
// role update) will have either occurred or not.
......@@ -133,9 +120,9 @@ public abstract class AbstractOpenFlowSwitch extends AbstractHandlerBehaviour
a synchronization primitive, because the message would have just been
dropped anyway.
*/
if (role == RoleState.MASTER) {
// fast path send when we are master
sendMsgsOnChannel(msgs);
return;
}
......@@ -166,23 +153,10 @@ public abstract class AbstractOpenFlowSwitch extends AbstractHandlerBehaviour
}
}
private void countOutgoingMsg(List<OFMessage> msgs) {
// listen to outgoing control messages only if listeners are registered
if (ofOutgoingMsgListener.size() != 0) {
msgs.forEach(m -> {
if (m.getType() == OFType.PACKET_OUT ||
m.getType() == OFType.FLOW_MOD ||
m.getType() == OFType.STATS_REQUEST) {
executorMsgs.execute(new OFMessageHandler(dpid, m));
}
});
}
}
private void sendMsgsOnChannel(List<OFMessage> msgs) {
if (channel.isConnected()) {
channel.write(msgs);
countOutgoingMsg(msgs);
agent.processDownstreamMessage(dpid, msgs);
} else {
log.warn("Dropping messages for switch {} because channel is not connected: {}",
dpid, msgs);
......@@ -335,16 +309,6 @@ public abstract class AbstractOpenFlowSwitch extends AbstractHandlerBehaviour
}
@Override
public void addEventListener(OpenFlowEventListener listener) {
ofOutgoingMsgListener.add(listener);
}
@Override
public void removeEventListener(OpenFlowEventListener listener) {
ofOutgoingMsgListener.remove(listener);
}
@Override
public OFFactory factory() {
return OFFactories.getFactory(ofVersion);
}
......@@ -535,25 +499,4 @@ public abstract class AbstractOpenFlowSwitch extends AbstractHandlerBehaviour
? channel.getRemoteAddress() : "?")
+ " DPID[" + ((getStringId() != null) ? getStringId() : "?") + "]]";
}
/**
* OpenFlow message handler for outgoing control messages.
*/
protected final class OFMessageHandler implements Runnable {
protected final OFMessage msg;
protected final Dpid dpid;
public OFMessageHandler(Dpid dpid, OFMessage msg) {
this.msg = msg;
this.dpid = dpid;
}
@Override
public void run() {
for (OpenFlowEventListener listener : ofOutgoingMsgListener) {
listener.handleMessage(dpid, msg);
}
}
}
}
......
......@@ -20,6 +20,8 @@ import org.onosproject.openflow.controller.OpenFlowSwitch;
import org.onosproject.openflow.controller.RoleState;
import org.projectfloodlight.openflow.protocol.OFMessage;
import java.util.List;
/**
* Responsible for keeping track of the current set of switches
* connected to the system. As well as whether they are in Master
......@@ -84,6 +86,14 @@ public interface OpenFlowAgent {
void removeConnectedSwitch(Dpid dpid);
/**
* Notify OpenFlow message listeners on all outgoing message event.
*
* @param dpid the dpid the message sent to
* @param m the collection of messages to sent out
*/
void processDownstreamMessage(Dpid dpid, List<OFMessage> m);
/**
* Process a message coming from a switch.
*
* @param dpid the dpid the message came on.
......
......@@ -52,15 +52,21 @@ public class OpenflowControllerAdapter implements OpenFlowController {
}
@Override
public void monitorAllEvents(boolean monitor) {
public void addListener(OpenFlowSwitchListener listener) {
}
@Override
public void addListener(OpenFlowSwitchListener listener) {
public void removeListener(OpenFlowSwitchListener listener) {
}
@Override
public void removeListener(OpenFlowSwitchListener listener) {
public void addMessageListener(OpenFlowMessageListener listener) {
}
@Override
public void removeMessageListener(OpenFlowMessageListener listener) {
}
@Override
......
/*
* Copyright 2015-present Open Networking Laboratory
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.onosproject.openflow.controller.driver;
import org.jboss.netty.channel.Channel;
import org.jboss.netty.channel.ChannelConfig;
import org.jboss.netty.channel.ChannelFactory;
import org.jboss.netty.channel.ChannelFuture;
import org.jboss.netty.channel.ChannelPipeline;
import org.junit.Before;
import org.junit.Test;
import org.onosproject.openflow.controller.Dpid;
import org.onosproject.openflow.controller.OpenFlowEventListener;
import org.onosproject.openflow.controller.RoleState;
import org.projectfloodlight.openflow.protocol.OFMessage;
import java.net.SocketAddress;
import java.util.ArrayList;
import java.util.List;
import static org.hamcrest.MatcherAssert.assertThat;
import static org.hamcrest.Matchers.hasSize;
import static org.hamcrest.Matchers.is;
/**
* Tests for packet processing in the abstract openflow switch class.
*/
public class AbstractOpenFlowSwitchTest {
OpenFlowSwitchImpl ofSwitch;
TestExecutorService executorService;
/**
* Mock executor service that tracks submits.
*/
static class TestExecutorService extends ExecutorServiceAdapter {
private List<OFMessage> submittedMessages = new ArrayList<>();
List<OFMessage> submittedMessages() {
return submittedMessages;
}
@Override
public void execute(Runnable task) {
AbstractOpenFlowSwitch.OFMessageHandler handler =
(AbstractOpenFlowSwitch.OFMessageHandler) task;
submittedMessages.add(handler.msg);
}
}
/**
* Sets up switches to use as data.
*/
@Before
public void setUp() {
ofSwitch = new OpenFlowSwitchImpl();
executorService = new TestExecutorService();
ofSwitch.executorMsgs = executorService;
Channel channel = new MockChannel();
ofSwitch.setChannel(channel);
ofSwitch.role = RoleState.MASTER;
ofSwitch.addEventListener(new OpenFlowEventListenerAdapter());
}
/**
* Tests a packet out operation.
*/
@Test
public void testPacketOut() {
OFMessage ofPacketOut = new MockOfPacketOut();
ofSwitch.sendMsg(ofPacketOut);
assertThat(executorService.submittedMessages(), hasSize(1));
assertThat(executorService.submittedMessages().get(0), is(ofPacketOut));
}
/**
* Tests a flow mod operation.
*/
@Test
public void testFlowMod() {
OFMessage ofFlowMod = new MockOfFlowMod();
ofSwitch.sendMsg(ofFlowMod);
assertThat(executorService.submittedMessages(), hasSize(1));
assertThat(executorService.submittedMessages().get(0), is(ofFlowMod));
}
/**
* Tests a stats request operation.
*/
@Test
public void testStatsRequest() {
OFMessage ofStatsRequest = new MockOfStatsRequest();
ofSwitch.sendMsg(ofStatsRequest);
assertThat(executorService.submittedMessages(), hasSize(1));
assertThat(executorService.submittedMessages().get(0), is(ofStatsRequest));
}
protected class OpenFlowSwitchImpl extends AbstractOpenFlowSwitch {
@Override
public Boolean supportNxRole() {
return null;
}
@Override
public void startDriverHandshake() {
}
@Override
public boolean isDriverHandshakeComplete() {
return false;
}
@Override
public void processDriverHandshakeMessage(OFMessage m) {
}
}
private class OpenFlowEventListenerAdapter implements OpenFlowEventListener {
@Override
public void handleMessage(Dpid dpid, OFMessage msg) {
}
}
private class MockChannel implements Channel {
@Override
public Integer getId() {
return null;
}
@Override
public ChannelFactory getFactory() {
return null;
}
@Override
public Channel getParent() {
return null;
}
@Override
public ChannelConfig getConfig() {
return null;
}
@Override
public ChannelPipeline getPipeline() {
return null;
}
@Override
public boolean isOpen() {
return false;
}
@Override
public boolean isBound() {
return false;
}
@Override
public boolean isConnected() {
// we assume that the channel is connected
return true;
}
@Override
public SocketAddress getLocalAddress() {
return null;
}
@Override
public SocketAddress getRemoteAddress() {
return null;
}
@Override
public ChannelFuture write(Object message) {
return null;
}
@Override
public ChannelFuture write(Object message, SocketAddress remoteAddress) {
return null;
}
@Override
public ChannelFuture bind(SocketAddress localAddress) {
return null;
}
@Override
public ChannelFuture connect(SocketAddress remoteAddress) {
return null;
}
@Override
public ChannelFuture disconnect() {
return null;
}
@Override
public ChannelFuture unbind() {
return null;
}
@Override
public ChannelFuture close() {
return null;
}
@Override
public ChannelFuture getCloseFuture() {
return null;
}
@Override
public int getInterestOps() {
return 0;
}
@Override
public boolean isReadable() {
return false;
}
@Override
public boolean isWritable() {
return false;
}
@Override
public ChannelFuture setInterestOps(int interestOps) {
return null;
}
@Override
public ChannelFuture setReadable(boolean readable) {
return null;
}
@Override
public boolean getUserDefinedWritability(int index) {
return false;
}
@Override
public void setUserDefinedWritability(int index, boolean isWritable) {
}
@Override
public Object getAttachment() {
return null;
}
@Override
public void setAttachment(Object attachment) {
}
@Override
public int compareTo(Channel o) {
return 0;
}
}
}
/*
* Copyright 2015-present Open Networking Laboratory
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.onosproject.openflow.controller.driver;
import java.util.Collection;
import java.util.List;
import java.util.concurrent.Callable;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Future;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.TimeoutException;
/**
* Test harness adapter for the ExecutorService.
*/
public class ExecutorServiceAdapter implements ExecutorService {
@Override
public void shutdown() {
}
@Override
public List<Runnable> shutdownNow() {
return null;
}
@Override
public boolean isShutdown() {
return false;
}
@Override
public boolean isTerminated() {
return false;
}
@Override
public boolean awaitTermination(long timeout, TimeUnit unit)
throws InterruptedException {
return false;
}
@Override
public <T> Future<T> submit(Callable<T> task) {
return null;
}
@Override
public <T> Future<T> submit(Runnable task, T result) {
return null;
}
@Override
public Future<?> submit(Runnable task) {
return null;
}
@Override
public <T> List<Future<T>> invokeAll(Collection<? extends Callable<T>> tasks)
throws InterruptedException {
return null;
}
@Override
public <T> List<Future<T>> invokeAll(Collection<? extends Callable<T>> tasks, long timeout, TimeUnit unit)
throws InterruptedException {
return null;
}
@Override
public <T> T invokeAny(Collection<? extends Callable<T>> tasks) throws InterruptedException, ExecutionException {
return null;
}
@Override
public <T> T invokeAny(Collection<? extends Callable<T>> tasks, long timeout, TimeUnit unit)
throws InterruptedException, ExecutionException, TimeoutException {
return null;
}
@Override
public void execute(Runnable command) {
}
}
/*
* Copyright 2015-present Open Networking Laboratory
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.onosproject.openflow.controller.driver;
import org.projectfloodlight.openflow.protocol.OFFlowMod;
import org.projectfloodlight.openflow.protocol.OFFlowModCommand;
import org.projectfloodlight.openflow.protocol.OFType;
import org.projectfloodlight.openflow.protocol.OFFlowModFlags;
import org.projectfloodlight.openflow.protocol.action.OFAction;
import org.projectfloodlight.openflow.protocol.instruction.OFInstruction;
import org.projectfloodlight.openflow.protocol.match.Match;
import org.projectfloodlight.openflow.types.OFBufferId;
import org.projectfloodlight.openflow.types.OFPort;
import org.projectfloodlight.openflow.types.TableId;
import org.projectfloodlight.openflow.types.U64;
import org.projectfloodlight.openflow.types.OFGroup;
import java.util.List;
import java.util.Set;
/**
* Mock of the Open Flow flow mod message.
*/
public class MockOfFlowMod extends OfMessageAdapter implements OFFlowMod {
public MockOfFlowMod() {
super(OFType.FLOW_MOD);
}
@Override
public U64 getCookie() {
return null;
}
@Override
public U64 getCookieMask() throws UnsupportedOperationException {
return null;
}
@Override
public TableId getTableId() throws UnsupportedOperationException {
return null;
}
@Override
public OFFlowModCommand getCommand() {
return null;
}
@Override
public int getIdleTimeout() {
return 0;
}
@Override
public int getHardTimeout() {
return 0;
}
@Override
public int getPriority() {
return 0;
}
@Override
public OFBufferId getBufferId() {
return null;
}
@Override
public OFPort getOutPort() {
return null;
}
@Override
public OFGroup getOutGroup() throws UnsupportedOperationException {
return null;
}
@Override
public Set<OFFlowModFlags> getFlags() {
return null;
}
@Override
public Match getMatch() {
return null;
}
@Override
public List<OFInstruction> getInstructions() throws UnsupportedOperationException {
return null;
}
@Override
public List<OFAction> getActions() throws UnsupportedOperationException {
return null;
}
@Override
public OFFlowMod.Builder createBuilder() {
return null;
}
}
/*
* Copyright 2015-present Open Networking Laboratory
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.onosproject.openflow.controller.driver;
import org.projectfloodlight.openflow.protocol.OFPacketOut;
import org.projectfloodlight.openflow.protocol.OFType;
import org.projectfloodlight.openflow.protocol.action.OFAction;
import org.projectfloodlight.openflow.types.OFBufferId;
import org.projectfloodlight.openflow.types.OFPort;
import java.util.List;
/**
* Mock of the Open Flow packet out message.
*/
public class MockOfPacketOut extends OfMessageAdapter implements OFPacketOut {
public MockOfPacketOut() {
super(OFType.PACKET_OUT);
}
@Override
public OFBufferId getBufferId() {
return null;
}
@Override
public OFPort getInPort() {
return null;
}
@Override
public List<OFAction> getActions() {
return null;
}
@Override
public byte[] getData() {
return new byte[0];
}
@Override
public OFPacketOut.Builder createBuilder() {
return null;
}
}
/*
* Copyright 2015-present Open Networking Laboratory
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.onosproject.openflow.controller.driver;
import org.projectfloodlight.openflow.protocol.OFStatsRequest;
import org.projectfloodlight.openflow.protocol.OFStatsType;
import org.projectfloodlight.openflow.protocol.OFType;
import org.projectfloodlight.openflow.protocol.OFStatsReplyFlags;
import java.util.Set;
/**
* Mock of the Open Flow stats request message.
*/
public class MockOfStatsRequest extends OfMessageAdapter implements OFStatsRequest {
public MockOfStatsRequest() {
super(OFType.STATS_REQUEST);
}
@Override
public OFStatsType getStatsType() {
return null;
}
@Override
public Set<OFStatsReplyFlags> getFlags() {
return null;
}
@Override
public OFStatsRequest.Builder createBuilder() {
return null;
}
}
/*
* Copyright 2015-present Open Networking Laboratory
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.onosproject.openflow.controller.driver;
import org.jboss.netty.buffer.ChannelBuffer;
import org.projectfloodlight.openflow.protocol.OFMessage;
import org.projectfloodlight.openflow.protocol.OFType;
import org.projectfloodlight.openflow.protocol.OFVersion;
import com.google.common.hash.PrimitiveSink;
/**
* Adapter for testing against an OpenFlow message.
*/
public class OfMessageAdapter implements OFMessage {
OFType type;
private OfMessageAdapter() {}
public OfMessageAdapter(OFType type) {
this.type = type;
}
@Override
public OFType getType() {
return type;
}
@Override
public OFVersion getVersion() {
return null;
}
@Override
public long getXid() {
return 0;
}
@Override
public void writeTo(ChannelBuffer channelBuffer) { }
@Override
public Builder createBuilder() {
return null;
}
@Override
public void putTo(PrimitiveSink sink) { }
}
......@@ -34,6 +34,7 @@ import org.onosproject.openflow.controller.DefaultOpenFlowPacketContext;
import org.onosproject.openflow.controller.Dpid;
import org.onosproject.openflow.controller.OpenFlowController;
import org.onosproject.openflow.controller.OpenFlowEventListener;
import org.onosproject.openflow.controller.OpenFlowMessageListener;
import org.onosproject.openflow.controller.OpenFlowPacketContext;
import org.onosproject.openflow.controller.OpenFlowSwitch;
import org.onosproject.openflow.controller.OpenFlowSwitchListener;
......@@ -134,7 +135,7 @@ public class OpenFlowControllerImpl implements OpenFlowController {
protected Set<OpenFlowEventListener> ofEventListener = new CopyOnWriteArraySet<>();
protected boolean monitorAllEvents = false;
protected Set<OpenFlowMessageListener> ofMessageListener = new CopyOnWriteArraySet<>();
protected Multimap<Dpid, OFFlowStatsEntry> fullFlowStats =
ArrayListMultimap.create();
......@@ -217,11 +218,6 @@ public class OpenFlowControllerImpl implements OpenFlowController {
}
@Override
public void monitorAllEvents(boolean monitor) {
this.monitorAllEvents = monitor;
}
@Override
public void addListener(OpenFlowSwitchListener listener) {
if (!ofSwitchListener.contains(listener)) {
this.ofSwitchListener.add(listener);
......@@ -234,6 +230,16 @@ public class OpenFlowControllerImpl implements OpenFlowController {
}
@Override
public void addMessageListener(OpenFlowMessageListener listener) {
ofMessageListener.add(listener);
}
@Override
public void removeMessageListener(OpenFlowMessageListener listener) {
ofMessageListener.remove(listener);
}
@Override
public void addPacketListener(int priority, PacketListener listener) {
ofPacketListener.put(priority, listener);
}
......@@ -625,8 +631,20 @@ public class OpenFlowControllerImpl implements OpenFlowController {
}
@Override
public void processDownstreamMessage(Dpid dpid, List<OFMessage> m) {
for (OpenFlowMessageListener listener : ofMessageListener) {
listener.handleOutgoingMessage(dpid, m);
}
}
@Override
public void processMessage(Dpid dpid, OFMessage m) {
processPacket(dpid, m);
for (OpenFlowMessageListener listener : ofMessageListener) {
listener.handleIncomingMessage(dpid, m);
}
}
@Override
......
/*
* Copyright 2015-present Open Networking Laboratory
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.onosproject.openflow;
import org.projectfloodlight.openflow.protocol.OFPacketIn;
import org.projectfloodlight.openflow.protocol.OFPacketInReason;
import org.projectfloodlight.openflow.protocol.OFType;
import org.projectfloodlight.openflow.protocol.match.Match;
import org.projectfloodlight.openflow.types.OFBufferId;
import org.projectfloodlight.openflow.types.OFPort;
import org.projectfloodlight.openflow.types.TableId;
import org.projectfloodlight.openflow.types.U64;
/**
* Mock of the Open Flow packet in message.
*/
public class MockOfPacketIn extends OfMessageAdapter implements OFPacketIn {
public MockOfPacketIn() {
super(OFType.PACKET_IN);
}
@Override
public OFBufferId getBufferId() {
return null;
}
@Override
public int getTotalLen() {
return 0;
}
@Override
public OFPacketInReason getReason() {
return null;
}
@Override
public TableId getTableId() {
return null;
}
@Override
public Match getMatch() {
return null;
}
@Override
public byte[] getData() {
return new byte[0];
}
@Override
public OFPort getInPort() {
return null;
}
@Override
public OFPort getInPhyPort() {
return null;
}
@Override
public U64 getCookie() {
return null;
}
@Override
public OFPacketIn.Builder createBuilder() {
return null;
}
}
......@@ -15,14 +15,11 @@
*/
package org.onosproject.openflow;
import java.util.List;
import org.jboss.netty.channel.Channel;
import org.onosproject.net.Device;
import org.onosproject.net.driver.DriverData;
import org.onosproject.net.driver.DriverHandler;
import org.onosproject.openflow.controller.Dpid;
import org.onosproject.openflow.controller.OpenFlowEventListener;
import org.onosproject.openflow.controller.RoleState;
import org.onosproject.openflow.controller.driver.OpenFlowAgent;
import org.onosproject.openflow.controller.driver.OpenFlowSwitchDriver;
......@@ -38,6 +35,8 @@ import org.projectfloodlight.openflow.protocol.OFPortDesc;
import org.projectfloodlight.openflow.protocol.OFPortDescStatsReply;
import org.projectfloodlight.openflow.protocol.OFVersion;
import java.util.List;
/**
* Testing adapter for the OpenFlow switch driver class.
*/
......@@ -300,12 +299,4 @@ public class OpenflowSwitchDriverAdapter implements OpenFlowSwitchDriver {
public String channelId() {
return null;
}
@Override
public void addEventListener(OpenFlowEventListener listener) {
}
@Override
public void removeEventListener(OpenFlowEventListener listener) {
}
}
......
/*
* Copyright 2015-present Open Networking Laboratory
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.onosproject.openflow.controller.impl;
import org.onosproject.openflow.OfMessageAdapter;
import org.projectfloodlight.openflow.protocol.OFFlowRemoved;
import org.projectfloodlight.openflow.protocol.OFType;
import org.projectfloodlight.openflow.protocol.match.Match;
import org.projectfloodlight.openflow.types.TableId;
import org.projectfloodlight.openflow.types.U64;
/**
* Mock of the Open Flow packet removed message.
*/
public class MockOfFlowRemoved extends OfMessageAdapter implements OFFlowRemoved {
public MockOfFlowRemoved() {
super(OFType.FLOW_REMOVED);
}
@Override
public U64 getCookie() {
return null;
}
@Override
public int getPriority() {
return 0;
}
@Override
public short getReason() {
return 0;
}
@Override
public TableId getTableId() throws UnsupportedOperationException {
return null;
}
@Override
public long getDurationSec() {
return 0;
}
@Override
public long getDurationNsec() {
return 0;
}
@Override
public int getIdleTimeout() {
return 0;
}
@Override
public int getHardTimeout() throws UnsupportedOperationException {
return 0;
}
@Override
public U64 getPacketCount() {
return null;
}
@Override
public U64 getByteCount() {
return null;
}
@Override
public Match getMatch() {
return null;
}
@Override
public OFFlowRemoved.Builder createBuilder() {
return null;
}
}
......@@ -104,7 +104,6 @@ public class OpenFlowControllerImplPacketsTest {
agent = controller.agent;
switchListener = new OpenFlowSwitchListenerAdapter();
controller.addListener(switchListener);
controller.monitorAllEvents(true);
packetListener = new TestPacketListener();
controller.addPacketListener(100, packetListener);
......
......@@ -38,6 +38,7 @@ import org.onosproject.net.provider.ProviderId;
import org.onosproject.openflow.controller.Dpid;
import org.onosproject.openflow.controller.OpenFlowController;
import org.onosproject.openflow.controller.OpenFlowEventListener;
import org.onosproject.openflow.controller.OpenFlowMessageListener;
import org.onosproject.openflow.controller.OpenFlowSwitch;
import org.onosproject.openflow.controller.OpenFlowSwitchListener;
import org.onosproject.openflow.controller.PacketListener;
......@@ -275,10 +276,6 @@ public class OpenFlowDeviceProviderTest {
}
@Override
public void monitorAllEvents(boolean monitor) {
}
@Override
public void addListener(OpenFlowSwitchListener listener) {
this.listener = listener;
}
......@@ -289,6 +286,16 @@ public class OpenFlowDeviceProviderTest {
}
@Override
public void addMessageListener(OpenFlowMessageListener listener) {
}
@Override
public void removeMessageListener(OpenFlowMessageListener listener) {
}
@Override
public void addPacketListener(int priority, PacketListener listener) {
}
......@@ -416,14 +423,6 @@ public class OpenFlowDeviceProviderTest {
return "1.2.3.4:1";
}
@Override
public void addEventListener(OpenFlowEventListener listener) {
}
@Override
public void removeEventListener(OpenFlowEventListener listener) {
}
}
}
......
......@@ -41,6 +41,7 @@ import org.onosproject.net.provider.ProviderId;
import org.onosproject.openflow.controller.Dpid;
import org.onosproject.openflow.controller.OpenFlowController;
import org.onosproject.openflow.controller.OpenFlowEventListener;
import org.onosproject.openflow.controller.OpenFlowMessageListener;
import org.onosproject.openflow.controller.OpenFlowSwitch;
import org.onosproject.openflow.controller.OpenFlowSwitchListener;
import org.onosproject.openflow.controller.PacketListener;
......@@ -225,6 +226,16 @@ public class OpenFlowGroupProviderTest {
}
@Override
public void addMessageListener(OpenFlowMessageListener listener) {
}
@Override
public void removeMessageListener(OpenFlowMessageListener listener) {
}
@Override
public void addPacketListener(int priority, PacketListener listener) {
}
......@@ -288,11 +299,6 @@ public class OpenFlowGroupProviderTest {
public OpenFlowSwitch getEqualSwitch(Dpid dpid) {
return null;
}
@Override
public void monitorAllEvents(boolean monitor) {
}
}
private class TestGroupProviderRegistry implements GroupProviderRegistry {
......@@ -411,14 +417,5 @@ public class OpenFlowGroupProviderTest {
public String channelId() {
return null;
}
@Override
public void addEventListener(OpenFlowEventListener listener) {
}
@Override
public void removeEventListener(OpenFlowEventListener listener) {
}
}
}
\ No newline at end of file
......
......@@ -32,7 +32,7 @@ import org.onosproject.net.provider.AbstractProvider;
import org.onosproject.net.provider.ProviderId;
import org.onosproject.openflow.controller.Dpid;
import org.onosproject.openflow.controller.OpenFlowController;
import org.onosproject.openflow.controller.OpenFlowEventListener;
import org.onosproject.openflow.controller.OpenFlowMessageListener;
import org.onosproject.openflow.controller.OpenFlowSwitch;
import org.onosproject.openflow.controller.OpenFlowSwitchListener;
import org.onosproject.openflow.controller.RoleState;
......@@ -42,6 +42,7 @@ import org.projectfloodlight.openflow.protocol.OFType;
import org.slf4j.Logger;
import java.util.HashMap;
import java.util.List;
import java.util.concurrent.ScheduledFuture;
import java.util.concurrent.TimeUnit;
......@@ -71,11 +72,8 @@ public class OpenFlowControlMessageProvider extends AbstractProvider
private final InternalDeviceProvider listener = new InternalDeviceProvider();
private final InternalIncomingMessageProvider inMsgListener =
new InternalIncomingMessageProvider();
private final InternalOutgoingMessageProvider outMsgListener =
new InternalOutgoingMessageProvider();
private final InternalControlMessageListener messageListener =
new InternalControlMessageListener();
private HashMap<Dpid, OpenFlowControlMessageAggregator> aggregators = Maps.newHashMap();
private SharedScheduledExecutorService executor;
......@@ -98,12 +96,8 @@ public class OpenFlowControlMessageProvider extends AbstractProvider
// listens all OpenFlow device related events
controller.addListener(listener);
// listens all OpenFlow incoming message events
controller.addEventListener(inMsgListener);
controller.monitorAllEvents(true);
// listens all OpenFlow outgoing message events
controller.getSwitches().forEach(sw -> sw.addEventListener(outMsgListener));
// listens all OpenFlow control message
controller.addMessageListener(messageListener);
executor = SharedScheduledExecutors.getSingleThreadExecutor();
......@@ -117,12 +111,8 @@ public class OpenFlowControlMessageProvider extends AbstractProvider
providerRegistry.unregister(this);
providerService = null;
// stops listening all OpenFlow incoming message events
controller.monitorAllEvents(false);
controller.removeEventListener(inMsgListener);
// stops listening all OpenFlow outgoing message events
controller.getSwitches().forEach(sw -> sw.removeEventListener(outMsgListener));
// stops listening all OpenFlow control message events
controller.removeMessageListener(messageListener);
log.info("Stopped");
}
......@@ -149,12 +139,6 @@ public class OpenFlowControlMessageProvider extends AbstractProvider
return;
}
OpenFlowSwitch sw = controller.getSwitch(dpid);
if (sw != null) {
// start to monitor the outgoing control messages
sw.addEventListener(outMsgListener);
}
DeviceId deviceId = deviceId(uri(dpid));
OpenFlowControlMessageAggregator ofcma =
new OpenFlowControlMessageAggregator(metricsService,
......@@ -171,12 +155,6 @@ public class OpenFlowControlMessageProvider extends AbstractProvider
return;
}
OpenFlowSwitch sw = controller.getSwitch(dpid);
if (sw != null) {
// stop monitoring the outgoing control messages
sw.removeEventListener(outMsgListener);
}
// removes the aggregator when switch is removed
// this also stops the aggregator from running
OpenFlowControlMessageAggregator aggregator = aggregators.remove(dpid);
......@@ -200,12 +178,12 @@ public class OpenFlowControlMessageProvider extends AbstractProvider
}
/**
* A listener for incoming OpenFlow messages.
* A listener for all OpenFlow control messages.
*/
private class InternalIncomingMessageProvider implements OpenFlowEventListener {
private class InternalControlMessageListener implements OpenFlowMessageListener {
@Override
public void handleMessage(Dpid dpid, OFMessage msg) {
public void handleIncomingMessage(Dpid dpid, OFMessage msg) {
if (msg.getType() == OFType.PACKET_IN ||
msg.getType() == OFType.FLOW_MOD ||
msg.getType() == OFType.STATS_REPLY) {
......@@ -215,19 +193,19 @@ public class OpenFlowControlMessageProvider extends AbstractProvider
});
}
}
}
/**
* A listener for outgoing OpenFlow messages.
*/
private class InternalOutgoingMessageProvider implements OpenFlowEventListener {
@Override
public void handleMessage(Dpid dpid, OFMessage msg) {
public void handleOutgoingMessage(Dpid dpid, List<OFMessage> msgs) {
for (OFMessage msg : msgs) {
if (msg.getType() == OFType.PACKET_OUT ||
msg.getType() == OFType.FLOW_MOD ||
msg.getType() == OFType.STATS_REQUEST) {
aggregators.computeIfPresent(dpid, (k, v) -> {
v.increment(msg);
return v;
});
}
}
}
}
}
......
......@@ -40,6 +40,7 @@ import org.onosproject.openflow.controller.DefaultOpenFlowPacketContext;
import org.onosproject.openflow.controller.Dpid;
import org.onosproject.openflow.controller.OpenFlowController;
import org.onosproject.openflow.controller.OpenFlowEventListener;
import org.onosproject.openflow.controller.OpenFlowMessageListener;
import org.onosproject.openflow.controller.OpenFlowPacketContext;
import org.onosproject.openflow.controller.OpenFlowSwitch;
import org.onosproject.openflow.controller.OpenFlowSwitchListener;
......@@ -287,15 +288,21 @@ public class OpenFlowPacketProviderTest {
}
@Override
public void monitorAllEvents(boolean monitor) {
public void addListener(OpenFlowSwitchListener listener) {
}
@Override
public void addListener(OpenFlowSwitchListener listener) {
public void removeListener(OpenFlowSwitchListener listener) {
}
@Override
public void removeListener(OpenFlowSwitchListener listener) {
public void addMessageListener(OpenFlowMessageListener listener) {
}
@Override
public void removeMessageListener(OpenFlowMessageListener listener) {
}
@Override
......@@ -428,16 +435,6 @@ public class OpenFlowPacketProviderTest {
public String channelId() {
return "1.2.3.4:1";
}
@Override
public void addEventListener(OpenFlowEventListener listener) {
}
@Override
public void removeEventListener(OpenFlowEventListener listener) {
}
}
}
......