pankaj

Merge branch 'master' of ssh://gerrit.onlab.us:29418/onos-next

......@@ -3,6 +3,7 @@ package org.onlab.onos.net;
import org.onlab.onos.net.provider.ProviderId;
import static com.google.common.base.Preconditions.checkArgument;
import static com.google.common.base.Preconditions.checkNotNull;
/**
* Default edge link model implementation.
......@@ -52,10 +53,14 @@ public class DefaultEdgeLink extends DefaultLink implements EdgeLink {
* for network-to-host direction
* @return new phantom edge link
*/
public static DefaultEdgeLink createEdgeLink(HostLocation edgePort,
public static DefaultEdgeLink createEdgeLink(ConnectPoint edgePort,
boolean isIngress) {
checkNotNull(edgePort, "Edge port cannot be null");
HostLocation location = (edgePort instanceof HostLocation) ?
(HostLocation) edgePort : new HostLocation(edgePort, 0);
return new DefaultEdgeLink(ProviderId.NONE,
new ConnectPoint(HostId.NONE, PortNumber.P0),
edgePort, isIngress);
location, isIngress);
}
}
......
......@@ -22,6 +22,17 @@ public class HostLocation extends ConnectPoint {
}
/**
* Creates a new host location derived from the supplied connection point.
*
* @param connectPoint connection point
* @param time time when detected, in millis since start of epoch
*/
public HostLocation(ConnectPoint connectPoint, long time) {
super(connectPoint.deviceId(), connectPoint.port());
this.time = time;
}
/**
* Returns the time when the location was established, given in
* milliseconds since start of epoch.
*
......
......@@ -5,6 +5,7 @@ import org.junit.Test;
import org.onlab.onos.net.provider.ProviderId;
import static org.junit.Assert.assertEquals;
import static org.onlab.onos.net.DefaultEdgeLink.createEdgeLink;
import static org.onlab.onos.net.DefaultLinkTest.cp;
import static org.onlab.onos.net.DeviceId.deviceId;
import static org.onlab.onos.net.HostId.hostId;
......@@ -55,4 +56,24 @@ public class DefaultEdgeLinkTest {
assertEquals("incorrect time", 123L, link.hostLocation().time());
}
@Test
public void phantomIngress() {
HostLocation hostLocation = new HostLocation(DID1, P1, 123L);
EdgeLink link = createEdgeLink(hostLocation, true);
assertEquals("incorrect dst", hostLocation, link.dst());
assertEquals("incorrect type", Link.Type.EDGE, link.type());
assertEquals("incorrect connect point", hostLocation, link.hostLocation());
assertEquals("incorrect time", 123L, link.hostLocation().time());
}
@Test
public void phantomEgress() {
ConnectPoint hostLocation = new ConnectPoint(DID1, P1);
EdgeLink link = createEdgeLink(hostLocation, false);
assertEquals("incorrect src", hostLocation, link.src());
assertEquals("incorrect type", Link.Type.EDGE, link.type());
assertEquals("incorrect connect point", hostLocation, link.hostLocation());
assertEquals("incorrect time", 0L, link.hostLocation().time());
}
}
......
......@@ -119,8 +119,10 @@ public class GossipDeviceStore
serializerPool = KryoPool.newBuilder()
.register(KryoPoolUtil.API)
.register(InternalDeviceEvent.class, new InternalDeviceEventSerializer())
.register(InternalDeviceOfflineEvent.class, new InternalDeviceOfflineEventSerializer())
.register(InternalPortEvent.class, new InternalPortEventSerializer())
.register(InternalPortStatusEvent.class, new InternalPortStatusEventSerializer())
.register(Timestamp.class)
.register(Timestamped.class)
.register(MastershipBasedTimestamp.class, new MastershipBasedTimestampSerializer())
.build()
......@@ -134,6 +136,8 @@ public class GossipDeviceStore
clusterCommunicator.addSubscriber(
GossipDeviceStoreMessageSubjects.DEVICE_UPDATE, new InternalDeviceEventListener());
clusterCommunicator.addSubscriber(
GossipDeviceStoreMessageSubjects.DEVICE_OFFLINE, new InternalDeviceOfflineEventListener());
clusterCommunicator.addSubscriber(
GossipDeviceStoreMessageSubjects.PORT_UPDATE, new InternalPortEventListener());
clusterCommunicator.addSubscriber(
GossipDeviceStoreMessageSubjects.PORT_STATUS_UPDATE, new InternalPortStatusEventListener());
......@@ -177,7 +181,7 @@ public class GossipDeviceStore
try {
notifyPeers(new InternalDeviceEvent(providerId, deviceId, deltaDesc));
} catch (IOException e) {
log.error("Failed to notify peers of a device update topology event or providerId: "
log.error("Failed to notify peers of a device update topology event for providerId: "
+ providerId + " and deviceId: " + deviceId, e);
}
}
......@@ -280,7 +284,18 @@ public class GossipDeviceStore
@Override
public DeviceEvent markOffline(DeviceId deviceId) {
Timestamp timestamp = clockService.getTimestamp(deviceId);
return markOfflineInternal(deviceId, timestamp);
DeviceEvent event = markOfflineInternal(deviceId, timestamp);
if (event != null) {
log.info("Notifying peers of a device offline topology event for deviceId: {}",
deviceId);
try {
notifyPeers(new InternalDeviceOfflineEvent(deviceId, timestamp));
} catch (IOException e) {
log.error("Failed to notify peers of a device offline topology event for deviceId: {}",
deviceId);
}
}
return event;
}
private DeviceEvent markOfflineInternal(DeviceId deviceId, Timestamp timestamp) {
......@@ -811,6 +826,14 @@ public class GossipDeviceStore
clusterCommunicator.broadcast(message);
}
private void notifyPeers(InternalDeviceOfflineEvent event) throws IOException {
ClusterMessage message = new ClusterMessage(
clusterService.getLocalNode().id(),
GossipDeviceStoreMessageSubjects.DEVICE_OFFLINE,
SERIALIZER.encode(event));
clusterCommunicator.broadcast(message);
}
private void notifyPeers(InternalPortEvent event) throws IOException {
ClusterMessage message = new ClusterMessage(
clusterService.getLocalNode().id(),
......@@ -830,15 +853,32 @@ public class GossipDeviceStore
private class InternalDeviceEventListener implements ClusterMessageHandler {
@Override
public void handle(ClusterMessage message) {
log.info("Received device update event from peer: {}", message.sender());
InternalDeviceEvent event = (InternalDeviceEvent) SERIALIZER.decode(message.payload());
ProviderId providerId = event.providerId();
DeviceId deviceId = event.deviceId();
Timestamped<DeviceDescription> deviceDescription = event.deviceDescription();
createOrUpdateDeviceInternal(providerId, deviceId, deviceDescription);
}
}
private class InternalDeviceOfflineEventListener implements ClusterMessageHandler {
@Override
public void handle(ClusterMessage message) {
log.info("Received device offline event from peer: {}", message.sender());
InternalDeviceOfflineEvent event = (InternalDeviceOfflineEvent) SERIALIZER.decode(message.payload());
DeviceId deviceId = event.deviceId();
Timestamp timestamp = event.timestamp();
markOfflineInternal(deviceId, timestamp);
}
}
private class InternalPortEventListener implements ClusterMessageHandler {
@Override
public void handle(ClusterMessage message) {
......
......@@ -3,13 +3,14 @@ package org.onlab.onos.store.device.impl;
import org.onlab.onos.store.cluster.messaging.MessageSubject;
/**
* MessageSubjects used by GossipDeviceStore.
* MessageSubjects used by GossipDeviceStore peer-peer communication.
*/
public final class GossipDeviceStoreMessageSubjects {
private GossipDeviceStoreMessageSubjects() {}
public static final MessageSubject DEVICE_UPDATE = new MessageSubject("peer-device-update");
public static final MessageSubject DEVICE_OFFLINE = new MessageSubject("peer-device-offline");
public static final MessageSubject PORT_UPDATE = new MessageSubject("peer-port-update");
public static final MessageSubject PORT_STATUS_UPDATE = new MessageSubject("peer-port-status-update");
}
......
package org.onlab.onos.store.device.impl;
import org.onlab.onos.net.DeviceId;
import org.onlab.onos.store.Timestamp;
/**
* Information published by GossipDeviceStore to notify peers of a device
* going offline.
*/
public class InternalDeviceOfflineEvent {
private final DeviceId deviceId;
private final Timestamp timestamp;
/**
* Creates a InternalDeviceOfflineEvent.
* @param deviceId identifier of device going offline.
* @param timestamp timestamp of when the device went offline.
*/
public InternalDeviceOfflineEvent(DeviceId deviceId, Timestamp timestamp) {
this.deviceId = deviceId;
this.timestamp = timestamp;
}
public DeviceId deviceId() {
return deviceId;
}
public Timestamp timestamp() {
return timestamp;
}
// for serializer
@SuppressWarnings("unused")
private InternalDeviceOfflineEvent() {
deviceId = null;
timestamp = null;
}
}
package org.onlab.onos.store.device.impl;
import org.onlab.onos.net.DeviceId;
import org.onlab.onos.store.Timestamp;
import com.esotericsoftware.kryo.Kryo;
import com.esotericsoftware.kryo.Serializer;
import com.esotericsoftware.kryo.io.Input;
import com.esotericsoftware.kryo.io.Output;
/**
* Kryo Serializer for {@link InternalDeviceOfflineEvent}.
*/
public class InternalDeviceOfflineEventSerializer extends Serializer<InternalDeviceOfflineEvent> {
/**
* Creates a serializer for {@link InternalDeviceOfflineEvent}.
*/
public InternalDeviceOfflineEventSerializer() {
// does not accept null
super(false);
}
@Override
public void write(Kryo kryo, Output output, InternalDeviceOfflineEvent event) {
kryo.writeClassAndObject(output, event.deviceId());
kryo.writeClassAndObject(output, event.timestamp());
}
@Override
public InternalDeviceOfflineEvent read(Kryo kryo, Input input,
Class<InternalDeviceOfflineEvent> type) {
DeviceId deviceId = (DeviceId) kryo.readClassAndObject(input);
Timestamp timestamp = (Timestamp) kryo.readClassAndObject(input);
return new InternalDeviceOfflineEvent(deviceId, timestamp);
}
}
......@@ -9,10 +9,14 @@ export KARAF_ZIP=${KARAF_ZIP:-~/Downloads/apache-karaf-3.0.1.zip}
export KARAF_TAR=${KARAF_TAR:-~/Downloads/apache-karaf-3.0.1.tar.gz}
export KARAF_DIST=$(basename $KARAF_ZIP .zip)
# Fallback build number us derived from from the user name & time
export BUILD_NUMBER=${BUILD_NUMBER:-$(id -un)~$(date +'%Y/%m/%d@%H:%M')}
# ONOS Version and onos.tar.gz staging environment
export ONOS_VERSION=${ONOS_VERSION:-1.0.0-SNAPSHOT}
export ONOS_POM_VERSION="1.0.0-SNAPSHOT"
export ONOS_VERSION=${ONOS_VERSION:-1.0.0.$BUILD_NUMBER}
export ONOS_BITS=onos-${ONOS_VERSION%~*}
export ONOS_STAGE_ROOT=${ONOS_STAGE_ROOT:-/tmp}
export ONOS_BITS=onos-$ONOS_VERSION
export ONOS_STAGE=$ONOS_STAGE_ROOT/$ONOS_BITS
export ONOS_TAR=$ONOS_STAGE.tar.gz
......
......@@ -49,7 +49,7 @@ export ONOS_FEATURES="${ONOS_FEATURES:-webconsole,onos-api,onos-core,onos-cli,on
# ONOS Patching ----------------------------------------------------------------
# Patch the Apache Karaf distribution file to add ONOS features repository
perl -pi.old -e "s|^(featuresRepositories=.*)|\1,mvn:org.onlab.onos/onos-features/$ONOS_VERSION/xml/features|" \
perl -pi.old -e "s|^(featuresRepositories=.*)|\1,mvn:org.onlab.onos/onos-features/$ONOS_POM_VERSION/xml/features|" \
$ONOS_STAGE/$KARAF_DIST/etc/org.apache.karaf.features.cfg
# Patch the Apache Karaf distribution file to load ONOS features
......@@ -57,17 +57,14 @@ perl -pi.old -e "s|^(featuresBoot=.*)|\1,$ONOS_FEATURES|" \
$ONOS_STAGE/$KARAF_DIST/etc/org.apache.karaf.features.cfg
# Patch the Apache Karaf distribution with ONOS branding bundle
cp $M2_REPO/org/onlab/onos/onos-branding/$ONOS_VERSION/onos-branding-*.jar \
cp $M2_REPO/org/onlab/onos/onos-branding/$ONOS_POM_VERSION/onos-branding-*.jar \
$ONOS_STAGE/$KARAF_DIST/lib
# Patch in the ONOS version file use the build number or the user name for
# build postfix in place of the SNAPSHOT post-fix.
build=${BUILD_NUMBER:-$(id -un)~$(date +'%Y/%m/%d@%H:%M')}
grep '<version>' $ONOS_ROOT/pom.xml | head -n1 | \
sed 's:.*<version>::g;s:</version>.*::g' | sed "s#SNAPSHOT#$build#g" \
>> $ONOS_STAGE/VERSION
# Patch in the ONOS version file
echo $ONOS_VERSION > $ONOS_STAGE/VERSION
# Now package up the ONOS tar file
cd $ONOS_STAGE_ROOT
COPYFILE_DISABLE=1 tar zcf $ONOS_TAR $ONOS_BITS
ls -l $ONOS_TAR >&2
rm -r $ONOS_STAGE
......
#!/usr/bin/python
# Launches mininet with Tower topology configuration.
import sys, tower
net = tower.Tower(cip=sys.argv[1])
net.run()