alshabib

merge pom.xml

Showing 46 changed files with 1453 additions and 102 deletions
......@@ -10,15 +10,25 @@ import org.osgi.framework.FrameworkUtil;
public abstract class AbstractShellCommand extends OsgiCommandSupport {
/**
* Returns the reference to the implementaiton of the specified service.
* Returns the reference to the implementation of the specified service.
*
* @param serviceClass service class
* @param <T> type of service
* @return service implementation
*/
static <T> T get(Class<T> serviceClass) {
public static <T> T get(Class<T> serviceClass) {
BundleContext bc = FrameworkUtil.getBundle(AbstractShellCommand.class).getBundleContext();
return bc.getService(bc.getServiceReference(serviceClass));
}
/**
* Prints the arguments using the specified format.
*
* @param format format string; see {@link String#format}
* @param args arguments
*/
public static void print(String format, Object... args) {
System.out.println(String.format(format, args));
}
}
......
......@@ -2,7 +2,6 @@ package org.onlab.onos.cli;
import org.apache.karaf.shell.commands.Argument;
import org.apache.karaf.shell.commands.Command;
import org.apache.karaf.shell.console.OsgiCommandSupport;
import org.onlab.onos.GreetService;
/**
......@@ -10,7 +9,7 @@ import org.onlab.onos.GreetService;
* use of an optional parameter as well.
*/
@Command(scope = "onos", name = "greet", description = "Issues a greeting")
public class GreetCommand extends OsgiCommandSupport {
public class GreetCommand extends AbstractShellCommand {
@Argument(index = 0, name = "name", description = "Name to greet",
required = false, multiValued = false)
......@@ -18,7 +17,7 @@ public class GreetCommand extends OsgiCommandSupport {
@Override
protected Object doExecute() throws Exception {
System.out.println(getService(GreetService.class).yo(name));
print(getService(GreetService.class).yo(name));
return null;
}
}
......
package org.onlab.onos.cli.net;
import org.apache.karaf.shell.console.Completer;
import org.apache.karaf.shell.console.completer.StringsCompleter;
import org.onlab.onos.cli.AbstractShellCommand;
import org.onlab.onos.net.Device;
import org.onlab.onos.net.device.DeviceService;
import java.util.Iterator;
import java.util.List;
import java.util.SortedSet;
/**
* Device ID completer.
*/
public class DeviceIdCompleter implements Completer {
@Override
public int complete(String buffer, int cursor, List<String> candidates) {
// Delegate string completer
StringsCompleter delegate = new StringsCompleter();
// Fetch our service and feed it's offerings to the string completer
DeviceService service = AbstractShellCommand.get(DeviceService.class);
Iterator<Device> it = service.getDevices().iterator();
SortedSet<String> strings = delegate.getStrings();
while (it.hasNext()) {
strings.add(it.next().id().toString());
}
// Now let the completer do the work for figuring out what to offer.
return delegate.complete(buffer, cursor, candidates);
}
}
package org.onlab.onos.cli.net;
import org.apache.karaf.shell.commands.Argument;
import org.apache.karaf.shell.commands.Command;
import org.onlab.onos.net.Device;
import org.onlab.onos.net.Port;
import org.onlab.onos.net.device.DeviceService;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.List;
import static org.onlab.onos.net.DeviceId.deviceId;
/**
* Lists all ports or all ports of a device.
*/
@Command(scope = "onos", name = "ports",
description = "Lists all ports or all ports of a device")
public class DevicePortsListCommand extends DevicesListCommand {
private static final String FMT = " port=%s, state=%s";
@Argument(index = 0, name = "uri", description = "Device ID",
required = false, multiValued = false)
String uri = null;
private static final Comparator<Port> PORT_COMPARATOR = new Comparator<Port>() {
@Override
public int compare(Port p1, Port p2) {
long delta = p1.number().toLong() - p2.number().toLong();
return delta == 0 ? 0 : (delta < 0 ? -1 : +1);
}
};
@Override
protected Object doExecute() throws Exception {
DeviceService service = getService(DeviceService.class);
if (uri == null) {
for (Device device : getSortedDevices(service)) {
printDevice(service, device);
}
} else {
printDevice(service, service.getDevice(deviceId(uri)));
}
return null;
}
@Override
protected void printDevice(DeviceService service, Device device) {
super.printDevice(service, device);
List<Port> ports = new ArrayList<>(service.getPorts(device.id()));
Collections.sort(ports, PORT_COMPARATOR);
for (Port port : ports) {
print(FMT, port.number(), port.isEnabled() ? "enabled" : "disabled");
}
}
}
package org.onlab.onos.cli.net;
import org.apache.karaf.shell.commands.Argument;
import org.apache.karaf.shell.commands.Command;
import org.onlab.onos.cli.AbstractShellCommand;
import org.onlab.onos.net.DeviceId;
import org.onlab.onos.net.device.DeviceAdminService;
/**
* Removes an infrastructure device.
*/
@Command(scope = "onos", name = "device-remove",
description = "Removes an infrastructure device")
public class DeviceRemoveCommand extends AbstractShellCommand {
@Argument(index = 0, name = "uri", description = "Device ID",
required = true, multiValued = false)
String uri = null;
@Override
protected Object doExecute() throws Exception {
getService(DeviceAdminService.class).removeDevice(DeviceId.deviceId(uri));
return null;
}
}
package org.onlab.onos.cli.net;
import org.apache.karaf.shell.commands.Command;
import org.onlab.onos.cli.AbstractShellCommand;
import org.onlab.onos.net.Device;
import org.onlab.onos.net.device.DeviceService;
import java.util.Collections;
import java.util.Comparator;
import java.util.List;
import static com.google.common.collect.Lists.newArrayList;
/**
* Lists all infrastructure devices.
*/
@Command(scope = "onos", name = "devices",
description = "Lists all infrastructure devices")
public class DevicesListCommand extends AbstractShellCommand {
private static final String FMT =
"id=%s, available=%s, role=%s, type=%s, mfr=%s, hw=%s, sw=%s, serial=%s";
protected static final Comparator<Device> ID_COMPARATOR = new Comparator<Device>() {
@Override
public int compare(Device d1, Device d2) {
return d1.id().uri().toString().compareTo(d2.id().uri().toString());
}
};
@Override
protected Object doExecute() throws Exception {
DeviceService service = getService(DeviceService.class);
for (Device device : getSortedDevices(service)) {
printDevice(service, device);
}
return null;
}
/**
* Returns the list of devices sorted using the device ID URIs.
*
* @param service device service
* @return sorted device list
*/
protected List<Device> getSortedDevices(DeviceService service) {
List<Device> devices = newArrayList(service.getDevices());
Collections.sort(devices, ID_COMPARATOR);
return devices;
}
/**
* Prints information about the specified device.
*
* @param service device service
* @param device infrastructure device
*/
protected void printDevice(DeviceService service, Device device) {
print(FMT, device.id(), service.isAvailable(device.id()),
service.getRole(device.id()), device.type(),
device.manufacturer(), device.hwVersion(), device.swVersion(),
device.serialNumber());
}
}
package org.onlab.onos.cli.net;
import org.apache.karaf.shell.commands.Argument;
import org.apache.karaf.shell.commands.Command;
import org.onlab.onos.cli.AbstractShellCommand;
import org.onlab.onos.net.Link;
import org.onlab.onos.net.link.LinkService;
import static org.onlab.onos.net.DeviceId.deviceId;
/**
* Lists all infrastructure links.
*/
@Command(scope = "onos", name = "links",
description = "Lists all infrastructure links")
public class LinksListCommand extends AbstractShellCommand {
private static final String FMT = "src=%s/%s, dst=%s/%s, type=%s";
@Argument(index = 0, name = "uri", description = "Device ID",
required = false, multiValued = false)
String uri = null;
@Override
protected Object doExecute() throws Exception {
LinkService service = getService(LinkService.class);
Iterable<Link> links = uri != null ?
service.getDeviceLinks(deviceId(uri)) : service.getLinks();
for (Link link : links) {
print(FMT, link.src().deviceId(), link.src().port(),
link.dst().deviceId(), link.dst().port(), link.type());
}
return null;
}
}
......@@ -2,6 +2,29 @@
<command-bundle xmlns="http://karaf.apache.org/xmlns/shell/v1.1.0">
<command>
<action class="org.onlab.onos.cli.net.DevicesListCommand"/>
</command>
<command>
<action class="org.onlab.onos.cli.net.DevicePortsListCommand"/>
<completers>
<ref component-id="deviceIdCompleter"/>
</completers>
</command>
<command>
<action class="org.onlab.onos.cli.net.DeviceRemoveCommand"/>
<completers>
<ref component-id="deviceIdCompleter"/>
</completers>
</command>
<command>
<action class="org.onlab.onos.cli.net.LinksListCommand"/>
<completers>
<ref component-id="deviceIdCompleter"/>
</completers>
</command>
<command>
<action class="org.onlab.onos.cli.GreetCommand"/>
<completers>
<ref component-id="nameCompleter"/>
......@@ -9,6 +32,8 @@
</command>
</command-bundle>
<bean id="deviceIdCompleter" class="org.onlab.onos.cli.net.DeviceIdCompleter"/>
<bean id="nameCompleter" class="org.onlab.onos.cli.NameCompleter"/>
</blueprint>
......
......@@ -5,7 +5,8 @@
<feature name="onos-thirdparty-base" version="1.0.0"
description="ONOS 3rd party dependencies">
<bundle>mvn:com.google.guava/guava/17.0</bundle>
<bundle>mvn:commons-lang/commons-lang/2.6</bundle>
<bundle>mvn:com.google.guava/guava/18.0</bundle>
</feature>
<feature name="onos-thirdparty-web" version="1.0.0"
......
package org.onlab.onos.net;
import java.util.Objects;
import static com.google.common.base.MoreObjects.toStringHelper;
/**
* Abstraction of a network connection point expressed as a pair of the
* device identifier and the device port number.
* network element identifier and port number.
*/
public interface ConnectPoint {
public class ConnectPoint {
private final ElementId elementId;
private final PortNumber portNumber;
/**
* Creates a new connection point.
*
* @param elementId network element identifier
* @param portNumber port number
*/
public ConnectPoint(ElementId elementId, PortNumber portNumber) {
this.elementId = elementId;
this.portNumber = portNumber;
}
/**
* Returns the connection device identifier.
* Returns the network element identifier.
*
* @return device id
* @return element identifier
*/
DeviceId deviceId();
public ElementId elementId() {
return elementId;
}
/**
* Returns the identifier of the infrastructure device if the connection
* point belongs to a network element which is indeed an infrastructure
* device.
*
* @return network element identifier as a device identifier
* @throws java.lang.IllegalStateException if connection point is not
* associated with a device
*/
@SuppressWarnings("unchecked")
public DeviceId deviceId() {
if (elementId instanceof DeviceId) {
return (DeviceId) elementId;
}
throw new IllegalStateException("Connection point not associated " +
"with an infrastructure device");
}
/**
* Returns the connection port number.
*
* @return port number
*/
PortNumber port();
public PortNumber port() {
return portNumber;
}
@Override
public int hashCode() {
return Objects.hash(elementId, portNumber);
}
@Override
public boolean equals(Object obj) {
if (obj instanceof ConnectPoint) {
final ConnectPoint other = (ConnectPoint) obj;
return Objects.equals(this.elementId, other.elementId) &&
Objects.equals(this.portNumber, other.portNumber);
}
return false;
}
@Override
public String toString() {
return toStringHelper(this)
.add("elementId", elementId)
.add("portNumber", portNumber)
.toString();
}
}
......
......@@ -4,10 +4,10 @@ import org.onlab.onos.net.provider.ProviderId;
import java.util.Objects;
import static com.google.common.base.Objects.toStringHelper;
import static com.google.common.base.MoreObjects.toStringHelper;
/**
* Default device model implementation.
* Default infrastructure device model implementation.
*/
public class DefaultDevice extends AbstractElement implements Device {
......
package org.onlab.onos.net;
import org.onlab.onos.net.provider.ProviderId;
import java.util.Objects;
import static com.google.common.base.MoreObjects.toStringHelper;
/**
* Default infrastructure link model implementation.
*/
public class DefaultLink extends AbstractModel implements Link {
private final ConnectPoint src;
private final ConnectPoint dst;
private final Type type;
/**
* Creates a link description using the supplied information.
*
* @param providerId provider identity
* @param src link source
* @param dst link destination
* @param type link type
*/
public DefaultLink(ProviderId providerId, ConnectPoint src, ConnectPoint dst,
Type type) {
super(providerId);
this.src = src;
this.dst = dst;
this.type = type;
}
@Override
public ConnectPoint src() {
return src;
}
@Override
public ConnectPoint dst() {
return dst;
}
@Override
public Type type() {
return type;
}
@Override
public int hashCode() {
return Objects.hash(src, dst, type);
}
@Override
public boolean equals(Object obj) {
if (obj instanceof DefaultLink) {
final DefaultLink other = (DefaultLink) obj;
return Objects.equals(this.src, other.src) &&
Objects.equals(this.dst, other.dst) &&
Objects.equals(this.type, other.type);
}
return false;
}
@Override
public String toString() {
return toStringHelper(this)
.add("src", src)
.add("dst", dst)
.add("type", type)
.toString();
}
}
......@@ -2,7 +2,7 @@ package org.onlab.onos.net;
import java.util.Objects;
import static com.google.common.base.Objects.toStringHelper;
import static com.google.common.base.MoreObjects.toStringHelper;
/**
* Default port implementation.
......
......@@ -3,8 +3,6 @@ package org.onlab.onos.net;
import java.net.URI;
import java.util.Objects;
import static com.google.common.base.Objects.toStringHelper;
/**
* Immutable representation of a network element identity.
*/
......@@ -47,7 +45,7 @@ public abstract class ElementId {
@Override
public String toString() {
return toStringHelper(this).add("uri", uri).toString();
return uri.toString();
}
}
......
package org.onlab.onos.net;
import java.util.Objects;
/**
* Representation of a network edge location where an end-station host is
* connected.
*/
public interface HostLocation extends ConnectPoint {
public class HostLocation extends ConnectPoint {
private final long time;
public HostLocation(DeviceId deviceId, PortNumber portNumber, long time) {
super(deviceId, portNumber);
this.time = time;
}
/**
* Returns the timestamp when the location was established, given in
......@@ -12,6 +21,22 @@ public interface HostLocation extends ConnectPoint {
*
* @return timestamp in milliseconds since start of epoch
*/
long time();
public long time() {
return time;
}
@Override
public int hashCode() {
return 31 * super.hashCode() + Objects.hash(time);
}
@Override
public boolean equals(Object obj) {
if (obj instanceof HostLocation) {
final HostLocation other = (HostLocation) obj;
return super.equals(obj) && Objects.equals(this.time, other.time);
}
return false;
}
}
......
......@@ -4,7 +4,6 @@ package org.onlab.onos.net;
* Abstraction of a network infrastructure link.
*/
public interface Link extends Provided {
// TODO: Consider extending graph Edge<Element> once the graph module is available
/**
* Coarse representation of the link type.
......@@ -38,6 +37,13 @@ public interface Link extends Provided {
*/
ConnectPoint dst();
/**
* Returns the link type.
*
* @return link type
*/
Type type();
// LinkInfo info(); // Additional link information / decorations
}
......
......@@ -2,7 +2,7 @@ package org.onlab.onos.net.device;
import java.net.URI;
import static com.google.common.base.Objects.toStringHelper;
import static com.google.common.base.MoreObjects.toStringHelper;
import static com.google.common.base.Preconditions.checkNotNull;
import static org.onlab.onos.net.Device.Type;
......
......@@ -55,13 +55,22 @@ public interface DeviceService {
/**
* Returns the port with the specified number and hosted by the given device.
* @param deviceId device identifier
*
* @param deviceId device identifier
* @param portNumber port number
* @return device port
*/
Port getPort(DeviceId deviceId, PortNumber portNumber);
/**
* Indicates whether or not the device is presently online and available.
*
* @param deviceId device identifier
* @return true if the device is available
*/
boolean isAvailable(DeviceId deviceId);
/**
* Adds the specified device listener.
*
* @param listener device listener
......
package org.onlab.onos.net.link;
import org.onlab.onos.net.ConnectPoint;
import org.onlab.onos.net.Link;
/**
* Default implementation of immutable link description entity.
*/
public class DefaultLinkDescription implements LinkDescription {
private final ConnectPoint src;
private final ConnectPoint dst;
private final Link.Type type;
/**
* Creates a link description using the supplied information.
*
* @param src link source
* @param dst link destination
* @param type link type
*/
public DefaultLinkDescription(ConnectPoint src, ConnectPoint dst, Link.Type type) {
this.src = src;
this.dst = dst;
this.type = type;
}
@Override
public ConnectPoint src() {
return src;
}
@Override
public ConnectPoint dst() {
return dst;
}
@Override
public Link.Type type() {
return type;
}
}
package org.onlab.onos.net.link;
import org.onlab.onos.net.ConnectPoint;
import org.onlab.onos.net.DeviceId;
/**
* Service for administering the inventory of infrastructure links.
*/
public interface LinkAdminService {
/**
* Removes all infrastructure links leading to and from the
* specified connection point.
*
* @param connectPoint connection point
*/
void removeLinks(ConnectPoint connectPoint);
/**
* Removes all infrastructure links leading to and from the
* specified device.
*
* @param deviceId device identifier
*/
void removeLinks(DeviceId deviceId);
}
package org.onlab.onos.net.link;
import org.onlab.onos.net.ConnectPoint;
import org.onlab.onos.net.Link;
/**
* Describes an infrastructure link.
*/
public interface LinkDescription {
// TODO: src, dst connection points, which are pairs of (DeviceId, PortNumber)
/**
* Returns the link source.
*
* @return links source
*/
ConnectPoint src();
/**
* Returns the link destination.
*
* @return links destination
*/
ConnectPoint dst();
// On the north:
// Link = (ConnectPoint src, ConnectPoint dst);
// ConnectPoint = (DeviceId, PortNumber);
/**
* Returns the link type.
*
* @return link type
*/
Link.Type type();
// On the south
// LinkDescription ~ Link
// Add further link attributes
}
......
......@@ -18,6 +18,11 @@ public class LinkEvent extends AbstractEvent<LinkEvent.Type, Link> {
LINK_ADDED,
/**
* Signifies that a link has been updated.
*/
LINK_UPDATED,
/**
* Signifies that a link has been removed.
*/
LINK_REMOVED
......
package org.onlab.onos.net.link;
import org.onlab.onos.net.ConnectPoint;
import org.onlab.onos.net.DeviceId;
import org.onlab.onos.net.provider.ProviderService;
/**
......@@ -21,4 +23,20 @@ public interface LinkProviderService extends ProviderService<LinkProvider> {
*/
void linkVanished(LinkDescription linkDescription);
/**
* Signals that infrastructure links associated with the specified
* connect point have vanished.
*
* @param connectPoint connect point
*/
void linksVanished(ConnectPoint connectPoint);
/**
* Signals that infrastructure links associated with the specified
* device have vanished.
*
* @param deviceId device identifier
*/
void linksVanished(DeviceId deviceId);
}
......
package org.onlab.onos.net.link;
import org.onlab.onos.net.ConnectPoint;
import org.onlab.onos.net.DeviceId;
import org.onlab.onos.net.Link;
......@@ -11,6 +12,13 @@ import java.util.Set;
public interface LinkService {
/**
* Returns the count of all known infrastructure links.
*
* @return number of infrastructure links
*/
int getLinkCount();
/**
* Returns a collection of all known infrastructure links.
*
* @return all infrastructure links
......@@ -40,7 +48,44 @@ public interface LinkService {
* @param deviceId device identifier
* @return set of device ingress links
*/
Set<Link> getDeviceInressLinks(DeviceId deviceId);
Set<Link> getDeviceIngressLinks(DeviceId deviceId);
/**
* Returns set of all infrastructure links leading to and from the
* specified connection point.
*
* @param connectPoint connection point
* @return set of links
*/
Set<Link> getLinks(ConnectPoint connectPoint);
/**
* Returns set of all infrastructure links leading from the specified
* connection point.
*
* @param connectPoint connection point
* @return set of device egress links
*/
Set<Link> getEgressLinks(ConnectPoint connectPoint);
/**
* Returns set of all infrastructure links leading to the specified
* connection point.
*
* @param connectPoint connection point
* @return set of device ingress links
*/
Set<Link> getIngressLinks(ConnectPoint connectPoint);
/**
* Returns the infrastructure links between the specified source
* and destination connection points.
*
* @param src source connection point
* @param dst destination connection point
* @return link from source to destination; null if none found
*/
Link getLink(ConnectPoint src, ConnectPoint dst);
/**
* Adds the specified link listener.
......
......@@ -2,7 +2,7 @@ package org.onlab.onos.net.provider;
import java.util.Objects;
import static com.google.common.base.Objects.toStringHelper;
import static com.google.common.base.MoreObjects.toStringHelper;
/**
* Notion of provider identity.
......
package org.onlab.onos.net;
import com.google.common.testing.EqualsTester;
import org.junit.Test;
import org.onlab.onos.net.provider.ProviderId;
import static org.junit.Assert.assertEquals;
import static org.onlab.onos.net.DeviceId.deviceId;
import static org.onlab.onos.net.Link.Type.DIRECT;
import static org.onlab.onos.net.Link.Type.INDIRECT;
import static org.onlab.onos.net.PortNumber.portNumber;
/**
* Test of the default link model entity.
*/
public class DefaultLinkTest {
private static final ProviderId PID = new ProviderId("foo");
private static final DeviceId DID1 = deviceId("of:foo");
private static final DeviceId DID2 = deviceId("of:bar");
private static final PortNumber P1 = portNumber(1);
private static final PortNumber P2 = portNumber(2);
public static ConnectPoint cp(DeviceId id, PortNumber pn) {
return new ConnectPoint(id, pn);
}
@Test
public void testEquality() {
Link l1 = new DefaultLink(PID, cp(DID1, P1), cp(DID2, P2), DIRECT);
Link l2 = new DefaultLink(PID, cp(DID1, P1), cp(DID2, P2), DIRECT);
Link l3 = new DefaultLink(PID, cp(DID1, P2), cp(DID2, P2), DIRECT);
Link l4 = new DefaultLink(PID, cp(DID1, P2), cp(DID2, P2), DIRECT);
Link l5 = new DefaultLink(PID, cp(DID1, P2), cp(DID2, P2), INDIRECT);
new EqualsTester().addEqualityGroup(l1, l2)
.addEqualityGroup(l3, l4)
.addEqualityGroup(l5)
.testEquals();
}
@Test
public void basics() {
Link link = new DefaultLink(PID, cp(DID1, P1), cp(DID2, P2), DIRECT);
assertEquals("incorrect src", cp(DID1, P1), link.src());
assertEquals("incorrect dst", cp(DID2, P2), link.dst());
assertEquals("incorrect type", DIRECT, link.type());
}
}
package org.onlab.onos.net.link;
import org.junit.Test;
import org.onlab.onos.net.DeviceId;
import org.onlab.onos.net.PortNumber;
import static org.junit.Assert.assertEquals;
import static org.onlab.onos.net.DefaultLinkTest.cp;
import static org.onlab.onos.net.DeviceId.deviceId;
import static org.onlab.onos.net.Link.Type.DIRECT;
import static org.onlab.onos.net.PortNumber.portNumber;
/**
* Test of the default link description.
*/
public class DefaultLinkDescriptionTest {
private static final DeviceId DID1 = deviceId("of:foo");
private static final DeviceId DID2 = deviceId("of:bar");
private static final PortNumber P1 = portNumber(1);
@Test
public void basics() {
LinkDescription desc = new DefaultLinkDescription(cp(DID1, P1), cp(DID2, P1), DIRECT);
assertEquals("incorrect src", cp(DID1, P1), desc.src());
assertEquals("incorrect dst", cp(DID2, P1), desc.dst());
assertEquals("incorrect type", DIRECT, desc.type());
}
}
package org.onlab.onos.net.link;
import org.junit.Test;
import org.onlab.onos.event.AbstractEventTest;
import org.onlab.onos.net.ConnectPoint;
import org.onlab.onos.net.DefaultLink;
import org.onlab.onos.net.Link;
import org.onlab.onos.net.provider.ProviderId;
import static org.onlab.onos.net.DeviceId.deviceId;
import static org.onlab.onos.net.PortNumber.portNumber;
/**
* Tests of the device event.
*/
public class LinkEventTest extends AbstractEventTest {
private Link createLink() {
return new DefaultLink(new ProviderId("foo"),
new ConnectPoint(deviceId("of:foo"), portNumber(1)),
new ConnectPoint(deviceId("of:bar"), portNumber(2)),
Link.Type.INDIRECT);
}
@Test
public void withTime() {
Link link = createLink();
LinkEvent event = new LinkEvent(LinkEvent.Type.LINK_ADDED, link, 123L);
validateEvent(event, LinkEvent.Type.LINK_ADDED, link, 123L);
}
@Test
public void withoutTime() {
Link link = createLink();
long before = System.currentTimeMillis();
LinkEvent event = new LinkEvent(LinkEvent.Type.LINK_ADDED, link);
long after = System.currentTimeMillis();
validateEvent(event, LinkEvent.Type.LINK_ADDED, link, before, after);
}
}
......@@ -104,6 +104,12 @@ public class SimpleDeviceManager
}
@Override
public boolean isAvailable(DeviceId deviceId) {
checkNotNull(deviceId, DEVICE_ID_NULL);
return store.isAvailable(deviceId);
}
@Override
public void addListener(DeviceListener listener) {
listenerRegistry.addListener(listener);
}
......@@ -152,6 +158,7 @@ public class SimpleDeviceManager
public void deviceConnected(DeviceId deviceId, DeviceDescription deviceDescription) {
checkNotNull(deviceId, DEVICE_ID_NULL);
checkNotNull(deviceDescription, DEVICE_DESCRIPTION_NULL);
checkValidity();
log.info("Device {} connected", deviceId);
DeviceEvent event = store.createOrUpdateDevice(provider().id(),
deviceId, deviceDescription);
......@@ -161,6 +168,7 @@ public class SimpleDeviceManager
@Override
public void deviceDisconnected(DeviceId deviceId) {
checkNotNull(deviceId, DEVICE_ID_NULL);
checkValidity();
log.info("Device {} disconnected", deviceId);
DeviceEvent event = store.markOffline(deviceId);
post(event);
......@@ -170,6 +178,7 @@ public class SimpleDeviceManager
public void updatePorts(DeviceId deviceId, List<PortDescription> portDescriptions) {
checkNotNull(deviceId, DEVICE_ID_NULL);
checkNotNull(portDescriptions, "Port descriptions list cannot be null");
checkValidity();
log.info("Device {} ports updated", deviceId);
List<DeviceEvent> events = store.updatePorts(deviceId, portDescriptions);
for (DeviceEvent event : events) {
......@@ -181,13 +190,16 @@ public class SimpleDeviceManager
public void portStatusChanged(DeviceId deviceId, PortDescription portDescription) {
checkNotNull(deviceId, DEVICE_ID_NULL);
checkNotNull(portDescription, PORT_DESCRIPTION_NULL);
log.info("Device {} port status changed", deviceId);
checkValidity();
DeviceEvent event = store.updatePortStatus(deviceId, portDescription);
if (event != null) {
log.info("Device {} port status changed", deviceId);
}
post(event);
}
}
// Posts the specified event to a local event dispatcher
// Posts the specified event to the local event dispatcher.
private void post(DeviceEvent event) {
if (event != null && eventDispatcher != null) {
eventDispatcher.post(event);
......
......@@ -45,7 +45,7 @@ class SimpleDeviceStore {
*
* @return number of devices
*/
public int getDeviceCount() {
int getDeviceCount() {
return devices.size();
}
......@@ -271,6 +271,16 @@ class SimpleDeviceStore {
}
/**
* Indicates whether the specified device is available/online.
*
* @param deviceId device identifier
* @return true if device is available
*/
boolean isAvailable(DeviceId deviceId) {
return availableDevices.contains(deviceId);
}
/**
* Returns the mastership role determined for this device.
*
* @param deviceId device identifier
......
package org.onlab.onos.net.trivial.impl;
import com.google.common.collect.Sets;
import org.apache.felix.scr.annotations.Activate;
import org.apache.felix.scr.annotations.Component;
import org.apache.felix.scr.annotations.Deactivate;
......@@ -8,16 +9,24 @@ import org.apache.felix.scr.annotations.ReferenceCardinality;
import org.apache.felix.scr.annotations.Service;
import org.onlab.onos.event.AbstractListenerRegistry;
import org.onlab.onos.event.EventDeliveryService;
import org.onlab.onos.net.ConnectPoint;
import org.onlab.onos.net.DeviceId;
import org.onlab.onos.net.Link;
import org.onlab.onos.net.link.LinkAdminService;
import org.onlab.onos.net.link.LinkDescription;
import org.onlab.onos.net.link.LinkEvent;
import org.onlab.onos.net.link.LinkListener;
import org.onlab.onos.net.link.LinkProvider;
import org.onlab.onos.net.link.LinkProviderRegistry;
import org.onlab.onos.net.link.LinkProviderService;
import org.onlab.onos.net.link.LinkService;
import org.onlab.onos.net.provider.AbstractProviderRegistry;
import org.onlab.onos.net.provider.AbstractProviderService;
import org.slf4j.Logger;
import java.util.Set;
import static com.google.common.base.Preconditions.checkNotNull;
import static org.slf4j.LoggerFactory.getLogger;
/**
......@@ -27,15 +36,21 @@ import static org.slf4j.LoggerFactory.getLogger;
@Service
public class SimpleLinkManager
extends AbstractProviderRegistry<LinkProvider, LinkProviderService>
implements LinkProviderRegistry {
implements LinkService, LinkAdminService, LinkProviderRegistry {
private static final String DEVICE_ID_NULL = "Device ID cannot be null";
private static final String LINK_DESC_NULL = "Link description cannot be null";
private static final String CONNECT_POINT_NULL = "Connection point cannot be null";
private final Logger log = getLogger(getClass());
private final AbstractListenerRegistry<LinkEvent, LinkListener>
listenerRegistry = new AbstractListenerRegistry<>();
private final SimpleLinkStore store = new SimpleLinkStore();
@Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
private EventDeliveryService eventDispatcher;
protected EventDeliveryService eventDispatcher;
@Activate
public void activate() {
......@@ -54,6 +69,81 @@ public class SimpleLinkManager
return new InternalLinkProviderService(provider);
}
@Override
public int getLinkCount() {
return store.getLinkCount();
}
@Override
public Iterable<Link> getLinks() {
return store.getLinks();
}
@Override
public Set<Link> getDeviceLinks(DeviceId deviceId) {
checkNotNull(deviceId, DEVICE_ID_NULL);
return Sets.union(store.getDeviceEgressLinks(deviceId),
store.getDeviceIngressLinks(deviceId));
}
@Override
public Set<Link> getDeviceEgressLinks(DeviceId deviceId) {
checkNotNull(deviceId, DEVICE_ID_NULL);
return store.getDeviceEgressLinks(deviceId);
}
@Override
public Set<Link> getDeviceIngressLinks(DeviceId deviceId) {
checkNotNull(deviceId, DEVICE_ID_NULL);
return store.getDeviceIngressLinks(deviceId);
}
@Override
public Set<Link> getLinks(ConnectPoint connectPoint) {
checkNotNull(connectPoint, CONNECT_POINT_NULL);
return Sets.union(store.getEgressLinks(connectPoint),
store.getIngressLinks(connectPoint));
}
@Override
public Set<Link> getEgressLinks(ConnectPoint connectPoint) {
checkNotNull(connectPoint, CONNECT_POINT_NULL);
return store.getEgressLinks(connectPoint);
}
@Override
public Set<Link> getIngressLinks(ConnectPoint connectPoint) {
checkNotNull(connectPoint, CONNECT_POINT_NULL);
return store.getIngressLinks(connectPoint);
}
@Override
public Link getLink(ConnectPoint src, ConnectPoint dst) {
checkNotNull(src, CONNECT_POINT_NULL);
checkNotNull(dst, CONNECT_POINT_NULL);
return store.getLink(src, dst);
}
@Override
public void removeLinks(ConnectPoint connectPoint) {
removeLinks(getLinks(connectPoint));
}
@Override
public void removeLinks(DeviceId deviceId) {
removeLinks(getDeviceLinks(deviceId));
}
@Override
public void addListener(LinkListener listener) {
listenerRegistry.addListener(listener);
}
@Override
public void removeListener(LinkListener listener) {
listenerRegistry.removeListener(listener);
}
// Personalized link provider service issued to the supplied provider.
private class InternalLinkProviderService extends AbstractProviderService<LinkProvider>
implements LinkProviderService {
......@@ -64,12 +154,54 @@ public class SimpleLinkManager
@Override
public void linkDetected(LinkDescription linkDescription) {
checkNotNull(linkDescription, LINK_DESC_NULL);
checkValidity();
log.info("Link {} detected", linkDescription);
LinkEvent event = store.createOrUpdateLink(provider().id(),
linkDescription);
post(event);
}
@Override
public void linkVanished(LinkDescription linkDescription) {
checkNotNull(linkDescription, LINK_DESC_NULL);
checkValidity();
log.info("Link {} vanished", linkDescription);
LinkEvent event = store.removeLink(linkDescription.src(),
linkDescription.dst());
post(event);
}
@Override
public void linksVanished(ConnectPoint connectPoint) {
checkNotNull(connectPoint, "Connect point cannot be null");
checkValidity();
log.info("Link for connection point {} vanished", connectPoint);
removeLinks(getLinks(connectPoint));
}
@Override
public void linksVanished(DeviceId deviceId) {
checkNotNull(deviceId, DEVICE_ID_NULL);
checkValidity();
log.info("Link for device {} vanished", deviceId);
removeLinks(getDeviceLinks(deviceId));
}
}
// Removes all links in the specified set and emits appropriate events.
private void removeLinks(Set<Link> links) {
for (Link link : links) {
LinkEvent event = store.removeLink(link.src(), link.dst());
post(event);
}
}
// Posts the specified event to the local event dispatcher.
private void post(LinkEvent event) {
if (event != null && eventDispatcher != null) {
eventDispatcher.post(event);
}
}
}
......
package org.onlab.onos.net.trivial.impl;
import com.google.common.collect.HashMultimap;
import com.google.common.collect.ImmutableSet;
import com.google.common.collect.Multimap;
import org.onlab.onos.net.ConnectPoint;
import org.onlab.onos.net.DefaultLink;
import org.onlab.onos.net.DeviceId;
import org.onlab.onos.net.Link;
import org.onlab.onos.net.link.LinkDescription;
import org.onlab.onos.net.link.LinkEvent;
import org.onlab.onos.net.provider.ProviderId;
import java.util.Collections;
import java.util.HashSet;
import java.util.Map;
import java.util.Objects;
import java.util.Set;
import java.util.concurrent.ConcurrentHashMap;
import static org.onlab.onos.net.Link.Type.DIRECT;
import static org.onlab.onos.net.Link.Type.INDIRECT;
import static org.onlab.onos.net.link.LinkEvent.Type.LINK_ADDED;
import static org.onlab.onos.net.link.LinkEvent.Type.LINK_REMOVED;
import static org.onlab.onos.net.link.LinkEvent.Type.LINK_UPDATED;
/**
* Manages inventory of infrastructure links using trivial in-memory link
* implementation.
*/
class SimpleLinkStore {
// Link inventory
private final Map<LinkKey, DefaultLink> links = new ConcurrentHashMap<>();
// Egress and ingress link sets
private final Multimap<DeviceId, Link> srcLinks = HashMultimap.create();
private final Multimap<DeviceId, Link> dstLinks = HashMultimap.create();
private static final Set<Link> EMPTY = ImmutableSet.copyOf(new Link[]{});
/**
* Returns the number of links in the store.
*
* @return number of links
*/
int getLinkCount() {
return links.size();
}
/**
* Returns an iterable collection of all links in the inventory.
*
* @return collection of all links
*/
Iterable<Link> getLinks() {
return Collections.unmodifiableSet(new HashSet<Link>(links.values()));
}
/**
* Returns all links egressing from the specified device.
*
* @param deviceId device identifier
* @return set of device links
*/
Set<Link> getDeviceEgressLinks(DeviceId deviceId) {
return ImmutableSet.copyOf(srcLinks.get(deviceId));
}
/**
* Returns all links ingressing from the specified device.
*
* @param deviceId device identifier
* @return set of device links
*/
Set<Link> getDeviceIngressLinks(DeviceId deviceId) {
return ImmutableSet.copyOf(dstLinks.get(deviceId));
}
/**
* Returns the link between the two end-points.
*
* @param src source connection point
* @param dst destination connection point
* @return link or null if one not found between the end-points
*/
Link getLink(ConnectPoint src, ConnectPoint dst) {
return links.get(new LinkKey(src, dst));
}
/**
* Returns all links egressing from the specified connection point.
*
* @param src source connection point
* @return set of connection point links
*/
Set<Link> getEgressLinks(ConnectPoint src) {
Set<Link> egress = new HashSet<>();
for (Link link : srcLinks.get(src.deviceId())) {
if (link.src().equals(src)) {
egress.add(link);
}
}
return egress;
}
/**
* Returns all links ingressing to the specified connection point.
*
* @param dst destination connection point
* @return set of connection point links
*/
Set<Link> getIngressLinks(ConnectPoint dst) {
Set<Link> ingress = new HashSet<>();
for (Link link : dstLinks.get(dst.deviceId())) {
if (link.dst().equals(dst)) {
ingress.add(link);
}
}
return ingress;
}
/**
* Creates a new link, or updates an existing one, based on the given
* information.
*
* @param providerId provider identity
* @param linkDescription link description
* @return create or update link event, or null if no change resulted
*/
public LinkEvent createOrUpdateLink(ProviderId providerId,
LinkDescription linkDescription) {
LinkKey key = new LinkKey(linkDescription.src(), linkDescription.dst());
DefaultLink link = links.get(key);
if (link == null) {
return createLink(providerId, key, linkDescription);
}
return updateLink(providerId, link, key, linkDescription);
}
// Creates and stores the link and returns the appropriate event.
private LinkEvent createLink(ProviderId providerId, LinkKey key,
LinkDescription linkDescription) {
DefaultLink link = new DefaultLink(providerId, key.src, key.dst,
linkDescription.type());
synchronized (this) {
links.put(key, link);
srcLinks.put(link.src().deviceId(), link);
dstLinks.put(link.dst().deviceId(), link);
}
return new LinkEvent(LINK_ADDED, link);
}
// Updates, if necessary the specified link and returns the appropriate event.
private LinkEvent updateLink(ProviderId providerId, DefaultLink link,
LinkKey key, LinkDescription linkDescription) {
if (link.type() == INDIRECT && linkDescription.type() == DIRECT) {
synchronized (this) {
srcLinks.remove(link.src().deviceId(), link);
dstLinks.remove(link.dst().deviceId(), link);
DefaultLink updated =
new DefaultLink(providerId, link.src(), link.dst(),
linkDescription.type());
links.put(key, updated);
srcLinks.put(link.src().deviceId(), updated);
dstLinks.put(link.dst().deviceId(), updated);
return new LinkEvent(LINK_UPDATED, updated);
}
}
return null;
}
/**
* Removes the link based on the specified information.
*
* @param src link source
* @param dst link destination
* @return remove link event, or null if no change resulted
*/
LinkEvent removeLink(ConnectPoint src, ConnectPoint dst) {
synchronized (this) {
Link link = links.remove(new LinkKey(src, dst));
if (link != null) {
srcLinks.remove(link.src().deviceId(), link);
dstLinks.remove(link.dst().deviceId(), link);
return new LinkEvent(LINK_REMOVED, link);
}
return null;
}
}
// Auxiliary key to track links.
private class LinkKey {
final ConnectPoint src;
final ConnectPoint dst;
LinkKey(ConnectPoint src, ConnectPoint dst) {
this.src = src;
this.dst = dst;
}
@Override
public int hashCode() {
return Objects.hash(src, dst);
}
@Override
public boolean equals(Object obj) {
if (obj instanceof LinkKey) {
final LinkKey other = (LinkKey) obj;
return Objects.equals(this.src, other.src) &&
Objects.equals(this.dst, other.dst);
}
return false;
}
}
}
......@@ -104,6 +104,7 @@ public class SimpleDeviceManagerTest {
assertNotNull("one device expected", it.next());
assertFalse("only one device expected", it.hasNext());
assertEquals("incorrect device count", 1, service.getDeviceCount());
assertTrue("device should be available", service.isAvailable(DID1));
}
@Test
......@@ -111,10 +112,12 @@ public class SimpleDeviceManagerTest {
connectDevice(DID1, SW1);
connectDevice(DID2, SW1);
validateEvents(DEVICE_ADDED, DEVICE_ADDED);
assertTrue("device should be available", service.isAvailable(DID1));
// Disconnect
providerService.deviceDisconnected(DID1);
assertNotNull("device should not be found", service.getDevice(DID1));
assertFalse("device should not be available", service.isAvailable(DID1));
validateEvents(DEVICE_AVAILABILITY_CHANGED);
// Reconnect
......
package org.onlab.onos.net.trivial.impl;
import com.google.common.collect.ImmutableSet;
import org.junit.After;
import org.junit.Before;
import org.junit.Test;
import org.onlab.onos.event.Event;
import org.onlab.onos.net.ConnectPoint;
import org.onlab.onos.net.Device;
import org.onlab.onos.net.DeviceId;
import org.onlab.onos.net.Link;
import org.onlab.onos.net.MastershipRole;
import org.onlab.onos.net.PortNumber;
import org.onlab.onos.net.link.DefaultLinkDescription;
import org.onlab.onos.net.link.LinkAdminService;
import org.onlab.onos.net.link.LinkEvent;
import org.onlab.onos.net.link.LinkListener;
import org.onlab.onos.net.link.LinkProvider;
import org.onlab.onos.net.link.LinkProviderRegistry;
import org.onlab.onos.net.link.LinkProviderService;
import org.onlab.onos.net.link.LinkService;
import org.onlab.onos.net.provider.AbstractProvider;
import org.onlab.onos.net.provider.ProviderId;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import java.util.Set;
import static org.junit.Assert.*;
import static org.onlab.onos.net.DeviceId.deviceId;
import static org.onlab.onos.net.Link.Type.DIRECT;
import static org.onlab.onos.net.Link.Type.INDIRECT;
import static org.onlab.onos.net.link.LinkEvent.Type.*;
/**
* Test codifying the link service & link provider service contracts.
*/
public class SimpleLinkManagerTest {
private static final ProviderId PID = new ProviderId("foo");
private static final DeviceId DID1 = deviceId("of:foo");
private static final DeviceId DID2 = deviceId("of:bar");
private static final DeviceId DID3 = deviceId("of:goo");
private static final PortNumber P1 = PortNumber.portNumber(1);
private static final PortNumber P2 = PortNumber.portNumber(2);
private static final PortNumber P3 = PortNumber.portNumber(3);
private SimpleLinkManager mgr;
protected LinkService service;
protected LinkAdminService admin;
protected LinkProviderRegistry registry;
protected LinkProviderService providerService;
protected TestProvider provider;
protected TestListener listener = new TestListener();
@Before
public void setUp() {
mgr = new SimpleLinkManager();
service = mgr;
admin = mgr;
registry = mgr;
mgr.eventDispatcher = new TestEventDispatcher();
mgr.activate();
service.addListener(listener);
provider = new TestProvider();
providerService = registry.register(provider);
assertTrue("provider should be registered",
registry.getProviders().contains(provider.id()));
}
@After
public void tearDown() {
registry.unregister(provider);
assertFalse("provider should not be registered",
registry.getProviders().contains(provider.id()));
service.removeListener(listener);
mgr.deactivate();
}
@Test
public void createLink() {
addLink(DID1, P1, DID2, P2, DIRECT);
addLink(DID2, P2, DID1, P1, DIRECT);
assertEquals("incorrect link count", 2, service.getLinkCount());
Iterator<Link> it = service.getLinks().iterator();
it.next();
it.next();
assertFalse("incorrect link count", it.hasNext());
}
@Test
public void updateLink() {
addLink(DID1, P1, DID2, P2, DIRECT);
addLink(DID2, P2, DID1, P1, INDIRECT);
assertEquals("incorrect link count", 2, service.getLinkCount());
providerService.linkDetected(new DefaultLinkDescription(cp(DID2, P2), cp(DID1, P1), DIRECT));
validateEvents(LINK_UPDATED);
assertEquals("incorrect link count", 2, service.getLinkCount());
providerService.linkDetected(new DefaultLinkDescription(cp(DID2, P2), cp(DID1, P1), INDIRECT));
providerService.linkDetected(new DefaultLinkDescription(cp(DID2, P2), cp(DID1, P1), DIRECT));
assertEquals("no events expected", 0, listener.events.size());
}
@Test
public void removeLink() {
addLink(DID1, P1, DID2, P2, DIRECT);
addLink(DID2, P2, DID1, P1, DIRECT);
assertEquals("incorrect link count", 2, service.getLinkCount());
providerService.linkVanished(new DefaultLinkDescription(cp(DID1, P1), cp(DID2, P2), DIRECT));
validateEvents(LINK_REMOVED);
assertEquals("incorrect link count", 1, service.getLinkCount());
assertNull("link should not be found", service.getLink(cp(DID1, P1), cp(DID2, P2)));
assertNotNull("link should be found", service.getLink(cp(DID2, P2), cp(DID1, P1)));
providerService.linkVanished(new DefaultLinkDescription(cp(DID1, P1), cp(DID2, P2), DIRECT));
assertEquals("no events expected", 0, listener.events.size());
}
@Test
public void removeLinksByConnectionPoint() {
Link l1 = addLink(DID1, P1, DID2, P2, DIRECT);
Link l2 = addLink(DID2, P2, DID1, P1, DIRECT);
addLink(DID3, P3, DID2, P1, DIRECT);
addLink(DID2, P1, DID3, P3, DIRECT);
assertEquals("incorrect link count", 4, service.getLinkCount());
providerService.linksVanished(cp(DID1, P1));
assertEquals("incorrect link count", 2, service.getLinkCount());
assertNull("link should be gone", service.getLink(l1.src(), l1.dst()));
assertNull("link should be gone", service.getLink(l2.src(), l2.dst()));
}
@Test
public void removeLinksByDevice() {
addLink(DID1, P1, DID2, P2, DIRECT);
addLink(DID2, P2, DID1, P1, DIRECT);
addLink(DID3, P3, DID2, P1, DIRECT);
addLink(DID2, P1, DID3, P3, DIRECT);
Link l5 = addLink(DID3, P1, DID1, P2, DIRECT);
Link l6 = addLink(DID1, P2, DID3, P1, DIRECT);
assertEquals("incorrect link count", 6, service.getLinkCount());
providerService.linksVanished(DID2);
assertEquals("incorrect link count", 2, service.getLinkCount());
assertNotNull("link should not be gone", service.getLink(l5.src(), l5.dst()));
assertNotNull("link should not be gone", service.getLink(l6.src(), l6.dst()));
}
@Test
public void removeLinksAsAdminByConnectionPoint() {
Link l1 = addLink(DID1, P1, DID2, P2, DIRECT);
Link l2 = addLink(DID2, P2, DID1, P1, DIRECT);
addLink(DID3, P3, DID2, P1, DIRECT);
addLink(DID2, P1, DID3, P3, DIRECT);
assertEquals("incorrect link count", 4, service.getLinkCount());
admin.removeLinks(cp(DID1, P1));
assertEquals("incorrect link count", 2, service.getLinkCount());
assertNull("link should be gone", service.getLink(l1.src(), l1.dst()));
assertNull("link should be gone", service.getLink(l2.src(), l2.dst()));
}
@Test
public void removeLinksAsAdminByDevice() {
addLink(DID1, P1, DID2, P2, DIRECT);
addLink(DID2, P2, DID1, P1, DIRECT);
addLink(DID3, P3, DID2, P1, DIRECT);
addLink(DID2, P1, DID3, P3, DIRECT);
Link l5 = addLink(DID3, P1, DID1, P2, DIRECT);
Link l6 = addLink(DID1, P2, DID3, P1, DIRECT);
assertEquals("incorrect link count", 6, service.getLinkCount());
admin.removeLinks(DID2);
assertEquals("incorrect link count", 2, service.getLinkCount());
assertNotNull("link should not be gone", service.getLink(l5.src(), l5.dst()));
assertNotNull("link should not be gone", service.getLink(l6.src(), l6.dst()));
}
@Test
public void getLinks() {
Link l1 = addLink(DID1, P1, DID2, P2, DIRECT);
Link l2 = addLink(DID2, P2, DID1, P1, DIRECT);
Link l3 = addLink(DID3, P3, DID2, P1, DIRECT);
Link l4 = addLink(DID2, P1, DID3, P3, DIRECT);
assertEquals("incorrect link count", 4, service.getLinkCount());
Set<Link> links = service.getLinks(cp(DID1, P1));
assertEquals("incorrect links", ImmutableSet.of(l1, l2), links);
links = service.getEgressLinks(cp(DID1, P1));
assertEquals("incorrect links", ImmutableSet.of(l1), links);
links = service.getIngressLinks(cp(DID1, P1));
assertEquals("incorrect links", ImmutableSet.of(l2), links);
links = service.getDeviceLinks(DID2);
assertEquals("incorrect links", ImmutableSet.of(l1, l2, l3, l4), links);
links = service.getDeviceLinks(DID3);
assertEquals("incorrect links", ImmutableSet.of(l3, l4), links);
links = service.getDeviceEgressLinks(DID2);
assertEquals("incorrect links", ImmutableSet.of(l2, l4), links);
links = service.getDeviceIngressLinks(DID2);
assertEquals("incorrect links", ImmutableSet.of(l1, l3), links);
}
private Link addLink(DeviceId sd, PortNumber sp, DeviceId dd, PortNumber dp,
Link.Type type) {
providerService.linkDetected(new DefaultLinkDescription(cp(sd, sp), cp(dd, dp), type));
Link link = listener.events.get(0).subject();
validateEvents(LINK_ADDED);
return link;
}
private ConnectPoint cp(DeviceId id, PortNumber portNumber) {
return new ConnectPoint(id, portNumber);
}
protected void validateEvents(Enum... types) {
int i = 0;
assertEquals("wrong events received", types.length, listener.events.size());
for (Event event : listener.events) {
assertEquals("incorrect event type", types[i], event.type());
i++;
}
listener.events.clear();
}
private class TestProvider extends AbstractProvider implements LinkProvider {
private Device deviceReceived;
private MastershipRole roleReceived;
public TestProvider() {
super(PID);
}
}
private static class TestListener implements LinkListener {
final List<LinkEvent> events = new ArrayList<>();
@Override
public void event(LinkEvent event) {
events.add(event);
}
}
}
......@@ -232,7 +232,7 @@ public class Controller {
}
public void start(OpenFlowAgent ag) {
log.info("Initialising OpenFlow Lib and IO");
log.info("Starting OpenFlow IO");
this.agent = ag;
this.init(new HashMap<String, String>());
this.run();
......@@ -240,6 +240,7 @@ public class Controller {
public void stop() {
log.info("Stopping OpenFlow IO");
execFactory.shutdown();
cg.close();
}
......
package org.onlab.onos.of.controller.impl;
import java.util.ArrayList;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;
import org.apache.felix.scr.annotations.Activate;
import org.apache.felix.scr.annotations.Component;
import org.apache.felix.scr.annotations.Deactivate;
import org.apache.felix.scr.annotations.Service;
import org.onlab.onos.of.controller.Dpid;
import org.onlab.onos.of.controller.OpenFlowController;
import org.onlab.onos.of.controller.OpenFlowSwitch;
......@@ -19,6 +16,16 @@ import org.projectfloodlight.openflow.protocol.OFPortStatus;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;
@Component(immediate = true)
@Service
public class OpenFlowControllerImpl implements OpenFlowController {
private static final Logger log =
......@@ -32,11 +39,11 @@ public class OpenFlowControllerImpl implements OpenFlowController {
new ConcurrentHashMap<Dpid, OpenFlowSwitch>();
protected OpenFlowSwitchAgent agent = new OpenFlowSwitchAgent();
protected ArrayList<OpenFlowSwitchListener> ofEventListener =
new ArrayList<OpenFlowSwitchListener>();
protected Set<OpenFlowSwitchListener> ofEventListener =
new HashSet<>();
protected ArrayList<PacketListener> ofPacketListener =
new ArrayList<PacketListener>();
protected List<PacketListener> ofPacketListener =
new ArrayList<>();
private final Controller ctrl = new Controller();
......@@ -110,19 +117,19 @@ public class OpenFlowControllerImpl implements OpenFlowController {
@Override
public void processPacket(Dpid dpid, OFMessage msg) {
switch (msg.getType()) {
case PORT_STATUS:
for (OpenFlowSwitchListener l : ofEventListener) {
l.portChanged(dpid, (OFPortStatus) msg);
}
break;
case PACKET_IN:
for (PacketListener p : ofPacketListener) {
//TODO fix me!
p.handlePacket(null);
}
break;
default:
log.warn("Handling message type {} not yet implemented", msg.getType());
case PORT_STATUS:
for (OpenFlowSwitchListener l : ofEventListener) {
l.portChanged(dpid, (OFPortStatus) msg);
}
break;
case PACKET_IN:
for (PacketListener p : ofPacketListener) {
//TODO fix me!
p.handlePacket(null);
}
break;
default:
log.warn("Handling message type {} not yet implemented", msg.getType());
}
}
......@@ -135,7 +142,6 @@ public class OpenFlowControllerImpl implements OpenFlowController {
* Implementation of an OpenFlow Agent which is responsible for
* keeping track of connected switches and the state in which
* they are.
*
*/
public class OpenFlowSwitchAgent implements OpenFlowAgent {
......@@ -146,7 +152,7 @@ public class OpenFlowControllerImpl implements OpenFlowController {
public boolean addConnectedSwitch(Dpid dpid, OpenFlowSwitch sw) {
if (connectedSwitches.get(dpid) != null) {
log.error("Trying to add connectedSwitch but found a previous "
+ "value for dpid: {}", dpid);
+ "value for dpid: {}", dpid);
return false;
} else {
log.error("Added switch {}", dpid);
......@@ -162,18 +168,18 @@ public class OpenFlowControllerImpl implements OpenFlowController {
public boolean validActivation(Dpid dpid) {
if (connectedSwitches.get(dpid) == null) {
log.error("Trying to activate switch but is not in "
+ "connected switches: dpid {}. Aborting ..",
dpid);
+ "connected switches: dpid {}. Aborting ..",
dpid);
return false;
}
if (activeMasterSwitches.get(dpid) != null ||
activeEqualSwitches.get(dpid) != null) {
log.error("Trying to activate switch but it is already "
+ "activated: dpid {}. Found in activeMaster: {} "
+ "Found in activeEqual: {}. Aborting ..", new Object[] {
dpid,
(activeMasterSwitches.get(dpid) == null) ? 'N' : 'Y',
(activeEqualSwitches.get(dpid) == null) ? 'N' : 'Y'});
+ "activated: dpid {}. Found in activeMaster: {} "
+ "Found in activeEqual: {}. Aborting ..", new Object[]{
dpid,
(activeMasterSwitches.get(dpid) == null) ? 'N' : 'Y',
(activeEqualSwitches.get(dpid) == null) ? 'N' : 'Y'});
return false;
}
return true;
......@@ -219,7 +225,7 @@ public class OpenFlowControllerImpl implements OpenFlowController {
OpenFlowSwitch sw = activeEqualSwitches.remove(dpid);
if (sw == null) {
log.error("Transition to master called on sw {}, but switch "
+ "was not found in controller-cache", dpid);
+ "was not found in controller-cache", dpid);
return;
}
log.info("Transitioned switch {} to MASTER", dpid);
......@@ -240,7 +246,7 @@ public class OpenFlowControllerImpl implements OpenFlowController {
OpenFlowSwitch sw = activeMasterSwitches.remove(dpid);
if (sw == null) {
log.error("Transition to equal called on sw {}, but switch "
+ "was not found in controller-cache", dpid);
+ "was not found in controller-cache", dpid);
return;
}
log.info("Transitioned switch {} to EQUAL", dpid);
......@@ -270,5 +276,4 @@ public class OpenFlowControllerImpl implements OpenFlowController {
}
}
......
......@@ -58,16 +58,21 @@
<dependency>
<groupId>com.google.guava</groupId>
<artifactId>guava</artifactId>
<version>17.0</version>
<version>18.0</version>
</dependency>
<dependency>
<groupId>com.google.guava</groupId>
<artifactId>guava-testlib</artifactId>
<version>17.0</version>
<version>18.0</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>commons-lang</groupId>
<artifactId>commons-lang</artifactId>
<version>2.6</version>
</dependency>
<!-- Web related -->
<dependency>
......
......@@ -85,19 +85,19 @@ public class OpenFlowDeviceProvider extends AbstractProvider implements DevicePr
@Override
public void roleChanged(Device device, MastershipRole newRole) {
switch (newRole) {
case MASTER:
controller.setRole(new Dpid(device.id().uri().getSchemeSpecificPart()),
RoleState.MASTER);
break;
case STANDBY:
controller.setRole(new Dpid(device.id().uri().getSchemeSpecificPart()),
RoleState.EQUAL);
case NONE:
controller.setRole(new Dpid(device.id().uri().getSchemeSpecificPart()),
RoleState.SLAVE);
break;
default:
log.error("Unknown Mastership state : {}", newRole);
case MASTER:
controller.setRole(new Dpid(device.id().uri().getSchemeSpecificPart()),
RoleState.MASTER);
break;
case STANDBY:
controller.setRole(new Dpid(device.id().uri().getSchemeSpecificPart()),
RoleState.EQUAL);
case NONE:
controller.setRole(new Dpid(device.id().uri().getSchemeSpecificPart()),
RoleState.SLAVE);
break;
default:
log.error("Unknown Mastership state : {}", newRole);
}
log.info("Accepting mastership role change for device {}", device.id());
......@@ -114,10 +114,10 @@ public class OpenFlowDeviceProvider extends AbstractProvider implements DevicePr
DeviceDescription description =
new DefaultDeviceDescription(buildURI(dpid), Device.Type.SWITCH,
sw.manfacturerDescription(),
sw.hardwareDescription(),
sw.softwareDescription(),
sw.softwareDescription());
sw.manfacturerDescription(),
sw.hardwareDescription(),
sw.softwareDescription(),
sw.serialNumber());
providerService.deviceConnected(deviceId(uri), description);
providerService.updatePorts(deviceId(uri), buildPortDescriptions(sw.getPorts()));
}
......@@ -140,6 +140,7 @@ public class OpenFlowDeviceProvider extends AbstractProvider implements DevicePr
/**
* Given a dpid builds a URI for the device.
*
* @param dpid the dpid to build the uri from
* @return returns a uri of the form of:<dpidHexForm>
*/
......@@ -155,6 +156,7 @@ public class OpenFlowDeviceProvider extends AbstractProvider implements DevicePr
/**
* Builds a list of port descriptions for a given list of ports.
*
* @param ports the list of ports
* @return list of portdescriptions
*/
......@@ -169,6 +171,7 @@ public class OpenFlowDeviceProvider extends AbstractProvider implements DevicePr
/**
* Build a portDescription from a given port.
*
* @param port the port to build from.
* @return portDescription for the port.
*/
......
......@@ -20,7 +20,6 @@
<dependency>
<groupId>com.google.guava</groupId>
<artifactId>guava-testlib</artifactId>
<version>17.0</version>
<scope>test</scope>
</dependency>
<dependency>
......
......@@ -2,6 +2,7 @@ package org.onlab.graph;
import java.util.Objects;
import static com.google.common.base.MoreObjects.toStringHelper;
import static com.google.common.base.Preconditions.checkNotNull;
/**
......@@ -49,7 +50,7 @@ public abstract class AbstractEdge<V extends Vertex> implements Edge<V> {
@Override
public String toString() {
return com.google.common.base.Objects.toStringHelper(this)
return toStringHelper(this)
.add("src", src)
.add("dst", dst)
.toString();
......
......@@ -6,6 +6,7 @@ import com.google.common.collect.ImmutableSetMultimap;
import java.util.Objects;
import java.util.Set;
import static com.google.common.base.MoreObjects.toStringHelper;
import static com.google.common.base.Preconditions.checkNotNull;
/**
......@@ -94,7 +95,7 @@ public class AdjacencyListsGraph<V extends Vertex, E extends Edge<V>> implements
@Override
public String toString() {
return com.google.common.base.Objects.toStringHelper(this)
return toStringHelper(this)
.add("vertexes", vertexes)
.add("edges", edges)
.toString();
......
......@@ -6,6 +6,7 @@ import java.util.ArrayList;
import java.util.List;
import java.util.Objects;
import static com.google.common.base.MoreObjects.toStringHelper;
import static com.google.common.base.Preconditions.checkArgument;
import static com.google.common.base.Preconditions.checkNotNull;
......@@ -91,7 +92,7 @@ public class DefaultMutablePath<V extends Vertex, E extends Edge<V>> implements
@Override
public String toString() {
return com.google.common.base.Objects.toStringHelper(this)
return toStringHelper(this)
.add("src", src())
.add("dst", dst())
.add("cost", cost)
......
......@@ -6,6 +6,7 @@ import java.util.Collections;
import java.util.List;
import java.util.Objects;
import static com.google.common.base.MoreObjects.toStringHelper;
import static com.google.common.base.Preconditions.checkArgument;
import static com.google.common.base.Preconditions.checkNotNull;
......@@ -56,7 +57,7 @@ public class DefaultPath<V extends Vertex, E extends Edge<V>> implements Path<V,
@Override
public String toString() {
return com.google.common.base.Objects.toStringHelper(this)
return toStringHelper(this)
.add("src", src)
.add("dst", dst)
.add("cost", cost)
......
......@@ -7,6 +7,7 @@ import java.util.Iterator;
import java.util.List;
import java.util.Objects;
import static com.google.common.base.MoreObjects.toStringHelper;
import static com.google.common.base.Preconditions.checkNotNull;
/**
......@@ -181,7 +182,7 @@ public class Heap<T> {
@Override
public String toString() {
return com.google.common.base.Objects.toStringHelper(this)
return toStringHelper(this)
.add("data", data)
.add("comparator", comparator)
.toString();
......
......@@ -2,7 +2,7 @@ package org.onlab.graph;
import java.util.Objects;
import static com.google.common.base.Objects.toStringHelper;
import static com.google.common.base.MoreObjects.toStringHelper;
/**
* Test edge.
......
......@@ -27,11 +27,6 @@
<groupId>com.google.guava</groupId>
<artifactId>guava</artifactId>
</dependency>
<dependency>
<groupId>commons-lang</groupId>
<artifactId>commons-lang</artifactId>
<version>2.3</version>
</dependency>
</dependencies>
<build>
......