pankaj

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

...@@ -3,6 +3,7 @@ package org.onlab.onos.net; ...@@ -3,6 +3,7 @@ package org.onlab.onos.net;
3 import org.onlab.onos.net.provider.ProviderId; 3 import org.onlab.onos.net.provider.ProviderId;
4 4
5 import static com.google.common.base.Preconditions.checkArgument; 5 import static com.google.common.base.Preconditions.checkArgument;
6 +import static com.google.common.base.Preconditions.checkNotNull;
6 7
7 /** 8 /**
8 * Default edge link model implementation. 9 * Default edge link model implementation.
...@@ -52,10 +53,14 @@ public class DefaultEdgeLink extends DefaultLink implements EdgeLink { ...@@ -52,10 +53,14 @@ public class DefaultEdgeLink extends DefaultLink implements EdgeLink {
52 * for network-to-host direction 53 * for network-to-host direction
53 * @return new phantom edge link 54 * @return new phantom edge link
54 */ 55 */
55 - public static DefaultEdgeLink createEdgeLink(HostLocation edgePort, 56 + public static DefaultEdgeLink createEdgeLink(ConnectPoint edgePort,
56 boolean isIngress) { 57 boolean isIngress) {
58 + checkNotNull(edgePort, "Edge port cannot be null");
59 + HostLocation location = (edgePort instanceof HostLocation) ?
60 + (HostLocation) edgePort : new HostLocation(edgePort, 0);
57 return new DefaultEdgeLink(ProviderId.NONE, 61 return new DefaultEdgeLink(ProviderId.NONE,
58 new ConnectPoint(HostId.NONE, PortNumber.P0), 62 new ConnectPoint(HostId.NONE, PortNumber.P0),
59 - edgePort, isIngress); 63 + location, isIngress);
60 } 64 }
65 +
61 } 66 }
......
...@@ -22,6 +22,17 @@ public class HostLocation extends ConnectPoint { ...@@ -22,6 +22,17 @@ public class HostLocation extends ConnectPoint {
22 } 22 }
23 23
24 /** 24 /**
25 + * Creates a new host location derived from the supplied connection point.
26 + *
27 + * @param connectPoint connection point
28 + * @param time time when detected, in millis since start of epoch
29 + */
30 + public HostLocation(ConnectPoint connectPoint, long time) {
31 + super(connectPoint.deviceId(), connectPoint.port());
32 + this.time = time;
33 + }
34 +
35 + /**
25 * Returns the time when the location was established, given in 36 * Returns the time when the location was established, given in
26 * milliseconds since start of epoch. 37 * milliseconds since start of epoch.
27 * 38 *
......
...@@ -5,6 +5,7 @@ import org.junit.Test; ...@@ -5,6 +5,7 @@ import org.junit.Test;
5 import org.onlab.onos.net.provider.ProviderId; 5 import org.onlab.onos.net.provider.ProviderId;
6 6
7 import static org.junit.Assert.assertEquals; 7 import static org.junit.Assert.assertEquals;
8 +import static org.onlab.onos.net.DefaultEdgeLink.createEdgeLink;
8 import static org.onlab.onos.net.DefaultLinkTest.cp; 9 import static org.onlab.onos.net.DefaultLinkTest.cp;
9 import static org.onlab.onos.net.DeviceId.deviceId; 10 import static org.onlab.onos.net.DeviceId.deviceId;
10 import static org.onlab.onos.net.HostId.hostId; 11 import static org.onlab.onos.net.HostId.hostId;
...@@ -55,4 +56,24 @@ public class DefaultEdgeLinkTest { ...@@ -55,4 +56,24 @@ public class DefaultEdgeLinkTest {
55 assertEquals("incorrect time", 123L, link.hostLocation().time()); 56 assertEquals("incorrect time", 123L, link.hostLocation().time());
56 } 57 }
57 58
59 + @Test
60 + public void phantomIngress() {
61 + HostLocation hostLocation = new HostLocation(DID1, P1, 123L);
62 + EdgeLink link = createEdgeLink(hostLocation, true);
63 + assertEquals("incorrect dst", hostLocation, link.dst());
64 + assertEquals("incorrect type", Link.Type.EDGE, link.type());
65 + assertEquals("incorrect connect point", hostLocation, link.hostLocation());
66 + assertEquals("incorrect time", 123L, link.hostLocation().time());
67 + }
68 +
69 + @Test
70 + public void phantomEgress() {
71 + ConnectPoint hostLocation = new ConnectPoint(DID1, P1);
72 + EdgeLink link = createEdgeLink(hostLocation, false);
73 + assertEquals("incorrect src", hostLocation, link.src());
74 + assertEquals("incorrect type", Link.Type.EDGE, link.type());
75 + assertEquals("incorrect connect point", hostLocation, link.hostLocation());
76 + assertEquals("incorrect time", 0L, link.hostLocation().time());
77 + }
78 +
58 } 79 }
......
...@@ -119,8 +119,10 @@ public class GossipDeviceStore ...@@ -119,8 +119,10 @@ public class GossipDeviceStore
119 serializerPool = KryoPool.newBuilder() 119 serializerPool = KryoPool.newBuilder()
120 .register(KryoPoolUtil.API) 120 .register(KryoPoolUtil.API)
121 .register(InternalDeviceEvent.class, new InternalDeviceEventSerializer()) 121 .register(InternalDeviceEvent.class, new InternalDeviceEventSerializer())
122 + .register(InternalDeviceOfflineEvent.class, new InternalDeviceOfflineEventSerializer())
122 .register(InternalPortEvent.class, new InternalPortEventSerializer()) 123 .register(InternalPortEvent.class, new InternalPortEventSerializer())
123 .register(InternalPortStatusEvent.class, new InternalPortStatusEventSerializer()) 124 .register(InternalPortStatusEvent.class, new InternalPortStatusEventSerializer())
125 + .register(Timestamp.class)
124 .register(Timestamped.class) 126 .register(Timestamped.class)
125 .register(MastershipBasedTimestamp.class, new MastershipBasedTimestampSerializer()) 127 .register(MastershipBasedTimestamp.class, new MastershipBasedTimestampSerializer())
126 .build() 128 .build()
...@@ -134,6 +136,8 @@ public class GossipDeviceStore ...@@ -134,6 +136,8 @@ public class GossipDeviceStore
134 clusterCommunicator.addSubscriber( 136 clusterCommunicator.addSubscriber(
135 GossipDeviceStoreMessageSubjects.DEVICE_UPDATE, new InternalDeviceEventListener()); 137 GossipDeviceStoreMessageSubjects.DEVICE_UPDATE, new InternalDeviceEventListener());
136 clusterCommunicator.addSubscriber( 138 clusterCommunicator.addSubscriber(
139 + GossipDeviceStoreMessageSubjects.DEVICE_OFFLINE, new InternalDeviceOfflineEventListener());
140 + clusterCommunicator.addSubscriber(
137 GossipDeviceStoreMessageSubjects.PORT_UPDATE, new InternalPortEventListener()); 141 GossipDeviceStoreMessageSubjects.PORT_UPDATE, new InternalPortEventListener());
138 clusterCommunicator.addSubscriber( 142 clusterCommunicator.addSubscriber(
139 GossipDeviceStoreMessageSubjects.PORT_STATUS_UPDATE, new InternalPortStatusEventListener()); 143 GossipDeviceStoreMessageSubjects.PORT_STATUS_UPDATE, new InternalPortStatusEventListener());
...@@ -177,7 +181,7 @@ public class GossipDeviceStore ...@@ -177,7 +181,7 @@ public class GossipDeviceStore
177 try { 181 try {
178 notifyPeers(new InternalDeviceEvent(providerId, deviceId, deltaDesc)); 182 notifyPeers(new InternalDeviceEvent(providerId, deviceId, deltaDesc));
179 } catch (IOException e) { 183 } catch (IOException e) {
180 - log.error("Failed to notify peers of a device update topology event or providerId: " 184 + log.error("Failed to notify peers of a device update topology event for providerId: "
181 + providerId + " and deviceId: " + deviceId, e); 185 + providerId + " and deviceId: " + deviceId, e);
182 } 186 }
183 } 187 }
...@@ -280,7 +284,18 @@ public class GossipDeviceStore ...@@ -280,7 +284,18 @@ public class GossipDeviceStore
280 @Override 284 @Override
281 public DeviceEvent markOffline(DeviceId deviceId) { 285 public DeviceEvent markOffline(DeviceId deviceId) {
282 Timestamp timestamp = clockService.getTimestamp(deviceId); 286 Timestamp timestamp = clockService.getTimestamp(deviceId);
283 - return markOfflineInternal(deviceId, timestamp); 287 + DeviceEvent event = markOfflineInternal(deviceId, timestamp);
288 + if (event != null) {
289 + log.info("Notifying peers of a device offline topology event for deviceId: {}",
290 + deviceId);
291 + try {
292 + notifyPeers(new InternalDeviceOfflineEvent(deviceId, timestamp));
293 + } catch (IOException e) {
294 + log.error("Failed to notify peers of a device offline topology event for deviceId: {}",
295 + deviceId);
296 + }
297 + }
298 + return event;
284 } 299 }
285 300
286 private DeviceEvent markOfflineInternal(DeviceId deviceId, Timestamp timestamp) { 301 private DeviceEvent markOfflineInternal(DeviceId deviceId, Timestamp timestamp) {
...@@ -811,6 +826,14 @@ public class GossipDeviceStore ...@@ -811,6 +826,14 @@ public class GossipDeviceStore
811 clusterCommunicator.broadcast(message); 826 clusterCommunicator.broadcast(message);
812 } 827 }
813 828
829 + private void notifyPeers(InternalDeviceOfflineEvent event) throws IOException {
830 + ClusterMessage message = new ClusterMessage(
831 + clusterService.getLocalNode().id(),
832 + GossipDeviceStoreMessageSubjects.DEVICE_OFFLINE,
833 + SERIALIZER.encode(event));
834 + clusterCommunicator.broadcast(message);
835 + }
836 +
814 private void notifyPeers(InternalPortEvent event) throws IOException { 837 private void notifyPeers(InternalPortEvent event) throws IOException {
815 ClusterMessage message = new ClusterMessage( 838 ClusterMessage message = new ClusterMessage(
816 clusterService.getLocalNode().id(), 839 clusterService.getLocalNode().id(),
...@@ -830,15 +853,32 @@ public class GossipDeviceStore ...@@ -830,15 +853,32 @@ public class GossipDeviceStore
830 private class InternalDeviceEventListener implements ClusterMessageHandler { 853 private class InternalDeviceEventListener implements ClusterMessageHandler {
831 @Override 854 @Override
832 public void handle(ClusterMessage message) { 855 public void handle(ClusterMessage message) {
856 +
833 log.info("Received device update event from peer: {}", message.sender()); 857 log.info("Received device update event from peer: {}", message.sender());
834 InternalDeviceEvent event = (InternalDeviceEvent) SERIALIZER.decode(message.payload()); 858 InternalDeviceEvent event = (InternalDeviceEvent) SERIALIZER.decode(message.payload());
859 +
835 ProviderId providerId = event.providerId(); 860 ProviderId providerId = event.providerId();
836 DeviceId deviceId = event.deviceId(); 861 DeviceId deviceId = event.deviceId();
837 Timestamped<DeviceDescription> deviceDescription = event.deviceDescription(); 862 Timestamped<DeviceDescription> deviceDescription = event.deviceDescription();
863 +
838 createOrUpdateDeviceInternal(providerId, deviceId, deviceDescription); 864 createOrUpdateDeviceInternal(providerId, deviceId, deviceDescription);
839 } 865 }
840 } 866 }
841 867
868 + private class InternalDeviceOfflineEventListener implements ClusterMessageHandler {
869 + @Override
870 + public void handle(ClusterMessage message) {
871 +
872 + log.info("Received device offline event from peer: {}", message.sender());
873 + InternalDeviceOfflineEvent event = (InternalDeviceOfflineEvent) SERIALIZER.decode(message.payload());
874 +
875 + DeviceId deviceId = event.deviceId();
876 + Timestamp timestamp = event.timestamp();
877 +
878 + markOfflineInternal(deviceId, timestamp);
879 + }
880 + }
881 +
842 private class InternalPortEventListener implements ClusterMessageHandler { 882 private class InternalPortEventListener implements ClusterMessageHandler {
843 @Override 883 @Override
844 public void handle(ClusterMessage message) { 884 public void handle(ClusterMessage message) {
......
...@@ -3,13 +3,14 @@ package org.onlab.onos.store.device.impl; ...@@ -3,13 +3,14 @@ package org.onlab.onos.store.device.impl;
3 import org.onlab.onos.store.cluster.messaging.MessageSubject; 3 import org.onlab.onos.store.cluster.messaging.MessageSubject;
4 4
5 /** 5 /**
6 - * MessageSubjects used by GossipDeviceStore. 6 + * MessageSubjects used by GossipDeviceStore peer-peer communication.
7 */ 7 */
8 public final class GossipDeviceStoreMessageSubjects { 8 public final class GossipDeviceStoreMessageSubjects {
9 9
10 private GossipDeviceStoreMessageSubjects() {} 10 private GossipDeviceStoreMessageSubjects() {}
11 11
12 public static final MessageSubject DEVICE_UPDATE = new MessageSubject("peer-device-update"); 12 public static final MessageSubject DEVICE_UPDATE = new MessageSubject("peer-device-update");
13 + public static final MessageSubject DEVICE_OFFLINE = new MessageSubject("peer-device-offline");
13 public static final MessageSubject PORT_UPDATE = new MessageSubject("peer-port-update"); 14 public static final MessageSubject PORT_UPDATE = new MessageSubject("peer-port-update");
14 public static final MessageSubject PORT_STATUS_UPDATE = new MessageSubject("peer-port-status-update"); 15 public static final MessageSubject PORT_STATUS_UPDATE = new MessageSubject("peer-port-status-update");
15 } 16 }
......
1 +package org.onlab.onos.store.device.impl;
2 +
3 +import org.onlab.onos.net.DeviceId;
4 +import org.onlab.onos.store.Timestamp;
5 +
6 +/**
7 + * Information published by GossipDeviceStore to notify peers of a device
8 + * going offline.
9 + */
10 +public class InternalDeviceOfflineEvent {
11 +
12 + private final DeviceId deviceId;
13 + private final Timestamp timestamp;
14 +
15 + /**
16 + * Creates a InternalDeviceOfflineEvent.
17 + * @param deviceId identifier of device going offline.
18 + * @param timestamp timestamp of when the device went offline.
19 + */
20 + public InternalDeviceOfflineEvent(DeviceId deviceId, Timestamp timestamp) {
21 + this.deviceId = deviceId;
22 + this.timestamp = timestamp;
23 + }
24 +
25 + public DeviceId deviceId() {
26 + return deviceId;
27 + }
28 +
29 + public Timestamp timestamp() {
30 + return timestamp;
31 + }
32 +
33 + // for serializer
34 + @SuppressWarnings("unused")
35 + private InternalDeviceOfflineEvent() {
36 + deviceId = null;
37 + timestamp = null;
38 + }
39 +}
1 +package org.onlab.onos.store.device.impl;
2 +
3 +import org.onlab.onos.net.DeviceId;
4 +import org.onlab.onos.store.Timestamp;
5 +
6 +import com.esotericsoftware.kryo.Kryo;
7 +import com.esotericsoftware.kryo.Serializer;
8 +import com.esotericsoftware.kryo.io.Input;
9 +import com.esotericsoftware.kryo.io.Output;
10 +
11 +/**
12 + * Kryo Serializer for {@link InternalDeviceOfflineEvent}.
13 + */
14 +public class InternalDeviceOfflineEventSerializer extends Serializer<InternalDeviceOfflineEvent> {
15 +
16 + /**
17 + * Creates a serializer for {@link InternalDeviceOfflineEvent}.
18 + */
19 + public InternalDeviceOfflineEventSerializer() {
20 + // does not accept null
21 + super(false);
22 + }
23 +
24 + @Override
25 + public void write(Kryo kryo, Output output, InternalDeviceOfflineEvent event) {
26 + kryo.writeClassAndObject(output, event.deviceId());
27 + kryo.writeClassAndObject(output, event.timestamp());
28 + }
29 +
30 + @Override
31 + public InternalDeviceOfflineEvent read(Kryo kryo, Input input,
32 + Class<InternalDeviceOfflineEvent> type) {
33 + DeviceId deviceId = (DeviceId) kryo.readClassAndObject(input);
34 + Timestamp timestamp = (Timestamp) kryo.readClassAndObject(input);
35 +
36 + return new InternalDeviceOfflineEvent(deviceId, timestamp);
37 + }
38 +}
...@@ -9,10 +9,14 @@ export KARAF_ZIP=${KARAF_ZIP:-~/Downloads/apache-karaf-3.0.1.zip} ...@@ -9,10 +9,14 @@ export KARAF_ZIP=${KARAF_ZIP:-~/Downloads/apache-karaf-3.0.1.zip}
9 export KARAF_TAR=${KARAF_TAR:-~/Downloads/apache-karaf-3.0.1.tar.gz} 9 export KARAF_TAR=${KARAF_TAR:-~/Downloads/apache-karaf-3.0.1.tar.gz}
10 export KARAF_DIST=$(basename $KARAF_ZIP .zip) 10 export KARAF_DIST=$(basename $KARAF_ZIP .zip)
11 11
12 +# Fallback build number us derived from from the user name & time
13 +export BUILD_NUMBER=${BUILD_NUMBER:-$(id -un)~$(date +'%Y/%m/%d@%H:%M')}
14 +
12 # ONOS Version and onos.tar.gz staging environment 15 # ONOS Version and onos.tar.gz staging environment
13 -export ONOS_VERSION=${ONOS_VERSION:-1.0.0-SNAPSHOT} 16 +export ONOS_POM_VERSION="1.0.0-SNAPSHOT"
17 +export ONOS_VERSION=${ONOS_VERSION:-1.0.0.$BUILD_NUMBER}
18 +export ONOS_BITS=onos-${ONOS_VERSION%~*}
14 export ONOS_STAGE_ROOT=${ONOS_STAGE_ROOT:-/tmp} 19 export ONOS_STAGE_ROOT=${ONOS_STAGE_ROOT:-/tmp}
15 -export ONOS_BITS=onos-$ONOS_VERSION
16 export ONOS_STAGE=$ONOS_STAGE_ROOT/$ONOS_BITS 20 export ONOS_STAGE=$ONOS_STAGE_ROOT/$ONOS_BITS
17 export ONOS_TAR=$ONOS_STAGE.tar.gz 21 export ONOS_TAR=$ONOS_STAGE.tar.gz
18 22
......
...@@ -49,7 +49,7 @@ export ONOS_FEATURES="${ONOS_FEATURES:-webconsole,onos-api,onos-core,onos-cli,on ...@@ -49,7 +49,7 @@ export ONOS_FEATURES="${ONOS_FEATURES:-webconsole,onos-api,onos-core,onos-cli,on
49 # ONOS Patching ---------------------------------------------------------------- 49 # ONOS Patching ----------------------------------------------------------------
50 50
51 # Patch the Apache Karaf distribution file to add ONOS features repository 51 # Patch the Apache Karaf distribution file to add ONOS features repository
52 -perl -pi.old -e "s|^(featuresRepositories=.*)|\1,mvn:org.onlab.onos/onos-features/$ONOS_VERSION/xml/features|" \ 52 +perl -pi.old -e "s|^(featuresRepositories=.*)|\1,mvn:org.onlab.onos/onos-features/$ONOS_POM_VERSION/xml/features|" \
53 $ONOS_STAGE/$KARAF_DIST/etc/org.apache.karaf.features.cfg 53 $ONOS_STAGE/$KARAF_DIST/etc/org.apache.karaf.features.cfg
54 54
55 # Patch the Apache Karaf distribution file to load ONOS features 55 # Patch the Apache Karaf distribution file to load ONOS features
...@@ -57,17 +57,14 @@ perl -pi.old -e "s|^(featuresBoot=.*)|\1,$ONOS_FEATURES|" \ ...@@ -57,17 +57,14 @@ perl -pi.old -e "s|^(featuresBoot=.*)|\1,$ONOS_FEATURES|" \
57 $ONOS_STAGE/$KARAF_DIST/etc/org.apache.karaf.features.cfg 57 $ONOS_STAGE/$KARAF_DIST/etc/org.apache.karaf.features.cfg
58 58
59 # Patch the Apache Karaf distribution with ONOS branding bundle 59 # Patch the Apache Karaf distribution with ONOS branding bundle
60 -cp $M2_REPO/org/onlab/onos/onos-branding/$ONOS_VERSION/onos-branding-*.jar \ 60 +cp $M2_REPO/org/onlab/onos/onos-branding/$ONOS_POM_VERSION/onos-branding-*.jar \
61 $ONOS_STAGE/$KARAF_DIST/lib 61 $ONOS_STAGE/$KARAF_DIST/lib
62 62
63 -# Patch in the ONOS version file use the build number or the user name for 63 +# Patch in the ONOS version file
64 -# build postfix in place of the SNAPSHOT post-fix. 64 +echo $ONOS_VERSION > $ONOS_STAGE/VERSION
65 -build=${BUILD_NUMBER:-$(id -un)~$(date +'%Y/%m/%d@%H:%M')}
66 -grep '<version>' $ONOS_ROOT/pom.xml | head -n1 | \
67 - sed 's:.*<version>::g;s:</version>.*::g' | sed "s#SNAPSHOT#$build#g" \
68 - >> $ONOS_STAGE/VERSION
69 65
70 # Now package up the ONOS tar file 66 # Now package up the ONOS tar file
71 cd $ONOS_STAGE_ROOT 67 cd $ONOS_STAGE_ROOT
72 COPYFILE_DISABLE=1 tar zcf $ONOS_TAR $ONOS_BITS 68 COPYFILE_DISABLE=1 tar zcf $ONOS_TAR $ONOS_BITS
73 ls -l $ONOS_TAR >&2 69 ls -l $ONOS_TAR >&2
70 +rm -r $ONOS_STAGE
......
1 +#!/usr/bin/python
2 +# Launches mininet with Tower topology configuration.
3 +import sys, tower
4 +net = tower.Tower(cip=sys.argv[1])
5 +net.run()