diff --git a/core/store/dist/src/main/java/org/onlab/onos/store/device/impl/GossipDeviceStore.java b/core/store/dist/src/main/java/org/onlab/onos/store/device/impl/GossipDeviceStore.java index 66366c11ce..19dc3e3fb2 100644 --- a/core/store/dist/src/main/java/org/onlab/onos/store/device/impl/GossipDeviceStore.java +++ b/core/store/dist/src/main/java/org/onlab/onos/store/device/impl/GossipDeviceStore.java @@ -32,6 +32,8 @@ import org.onlab.onos.cluster.ClusterService; import org.onlab.onos.cluster.ControllerNode; import org.onlab.onos.cluster.NodeId; import org.onlab.onos.mastership.MastershipService; +import org.onlab.onos.mastership.MastershipTerm; +import org.onlab.onos.mastership.MastershipTermService; import org.onlab.onos.net.AnnotationsUtil; import org.onlab.onos.net.DefaultAnnotations; import org.onlab.onos.net.DefaultDevice; @@ -39,6 +41,7 @@ import org.onlab.onos.net.DefaultPort; import org.onlab.onos.net.Device; import org.onlab.onos.net.Device.Type; import org.onlab.onos.net.DeviceId; +import org.onlab.onos.net.MastershipRole; import org.onlab.onos.net.Port; import org.onlab.onos.net.PortNumber; import org.onlab.onos.net.device.DeviceClockService; @@ -89,6 +92,7 @@ import static com.google.common.base.Verify.verify; import static org.onlab.util.Tools.namedThreads; import static java.util.concurrent.Executors.newSingleThreadScheduledExecutor; import static org.onlab.onos.store.device.impl.GossipDeviceStoreMessageSubjects.DEVICE_ADVERTISE; +import static org.onlab.onos.store.device.impl.GossipDeviceStoreMessageSubjects.DEVICE_REMOVE_REQ; // TODO: give me a better name /** @@ -160,6 +164,7 @@ public class GossipDeviceStore GossipDeviceStoreMessageSubjects.DEVICE_UPDATE, new InternalDeviceEventListener()); clusterCommunicator.addSubscriber( GossipDeviceStoreMessageSubjects.DEVICE_OFFLINE, new InternalDeviceOfflineEventListener()); + clusterCommunicator.addSubscriber(DEVICE_REMOVE_REQ, new InternalRemoveRequestListener()); clusterCommunicator.addSubscriber( GossipDeviceStoreMessageSubjects.DEVICE_REMOVED, new InternalDeviceRemovedEventListener()); clusterCommunicator.addSubscriber( @@ -715,14 +720,48 @@ public class GossipDeviceStore @Override public synchronized DeviceEvent removeDevice(DeviceId deviceId) { - final NodeId master = mastershipService.getMasterFor(deviceId); - if (!clusterService.getLocalNode().id().equals(master)) { - log.info("Removal of device {} requested on non master node", deviceId); - // FIXME silently ignoring. Should be forwarding or broadcasting to - // master. - return null; + final NodeId myId = clusterService.getLocalNode().id(); + NodeId master = mastershipService.getMasterFor(deviceId); + + // if there exist a master, forward + // if there is no master, try to become one and process + + boolean relinquishAtEnd = false; + if (master == null) { + final MastershipRole myRole = mastershipService.getLocalRole(deviceId); + if (myRole != MastershipRole.NONE) { + relinquishAtEnd = true; + } + log.info("Temporarlily requesting role for {} to remove", deviceId); + mastershipService.requestRoleFor(deviceId); + MastershipTermService termService = mastershipService.requestTermService(); + MastershipTerm term = termService.getMastershipTerm(deviceId); + if (myId.equals(term.master())) { + master = myId; + } } + if (!myId.equals(master)) { + log.info("{} has control of {}, forwarding remove request", + master, deviceId); + + ClusterMessage message = new ClusterMessage( + myId, + DEVICE_REMOVE_REQ, + SERIALIZER.encode(deviceId)); + + try { + clusterCommunicator.unicast(message, master); + } catch (IOException e) { + log.error("Failed to forward {} remove request to {}", deviceId, master, e); + } + + // event will be triggered after master processes it. + return null; + } + + // I have control.. + Timestamp timestamp = deviceClockService.getTimestamp(deviceId); DeviceEvent event = removeDeviceInternal(deviceId, timestamp); if (event != null) { @@ -735,6 +774,10 @@ public class GossipDeviceStore deviceId); } } + if (relinquishAtEnd) { + log.info("Relinquishing temporary role acquired for {}", deviceId); + mastershipService.relinquishMastership(deviceId); + } return event; } @@ -1241,6 +1284,16 @@ public class GossipDeviceStore } } + private final class InternalRemoveRequestListener + implements ClusterMessageHandler { + @Override + public void handle(ClusterMessage message) { + log.debug("Received device remove request from peer: {}", message.sender()); + DeviceId did = SERIALIZER.decode(message.payload()); + removeDevice(did); + } + } + private class InternalDeviceRemovedEventListener implements ClusterMessageHandler { @Override public void handle(ClusterMessage message) { diff --git a/core/store/dist/src/main/java/org/onlab/onos/store/device/impl/GossipDeviceStoreMessageSubjects.java b/core/store/dist/src/main/java/org/onlab/onos/store/device/impl/GossipDeviceStoreMessageSubjects.java index 89577a841e..4c9e48ccac 100644 --- a/core/store/dist/src/main/java/org/onlab/onos/store/device/impl/GossipDeviceStoreMessageSubjects.java +++ b/core/store/dist/src/main/java/org/onlab/onos/store/device/impl/GossipDeviceStoreMessageSubjects.java @@ -27,6 +27,7 @@ public final class 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 DEVICE_REMOVE_REQ = new MessageSubject("peer-device-remove-request"); public static final MessageSubject DEVICE_REMOVED = new MessageSubject("peer-device-removed"); public static final MessageSubject PORT_UPDATE = new MessageSubject("peer-port-update"); public static final MessageSubject PORT_STATUS_UPDATE = new MessageSubject("peer-port-status-update"); diff --git a/pom.xml b/pom.xml index 5c245162ef..5583f30e6e 100644 --- a/pom.xml +++ b/pom.xml @@ -361,8 +361,8 @@ 2.5.1 - 1.7 - 1.7 + 1.8 + 1.8 @@ -407,7 +407,7 @@ org.apache.felix maven-scr-plugin - 1.15.0 + 1.20.0 generate-scr-srcdescriptor diff --git a/tools/package/bin/onos-service b/tools/package/bin/onos-service index 9250d5b41d..ae6d97007e 100755 --- a/tools/package/bin/onos-service +++ b/tools/package/bin/onos-service @@ -3,7 +3,7 @@ # Starts ONOS Apache Karaf container # ----------------------------------------------------------------------------- -export JAVA_HOME=${JAVA_HOME:-/usr/lib/jvm/java-7-openjdk-amd64/} +#export JAVA_HOME=${JAVA_HOME:-/usr/lib/jvm/java-7-openjdk-amd64/} export JAVA_OPTS="${JAVA_OPTS:--Xms256M -Xmx2048M}" cd /opt/onos diff --git a/tools/package/debian/onos.conf b/tools/package/debian/onos.conf index 1d8f10af88..888c02b79f 100644 --- a/tools/package/debian/onos.conf +++ b/tools/package/debian/onos.conf @@ -11,8 +11,8 @@ kill timeout 60 respawn env LANG=en_US.UTF-8 -env JAVA_HOME=/usr/lib/jvm/java-7-openjdk-amd64 -env NEW_JAVA_HOME=/usr/lib/jvm/java-8-oracle/ +#env JAVA_HOME=/usr/lib/jvm/java-7-openjdk-amd64 +#env NEW_JAVA_HOME=/usr/lib/jvm/java-8-oracle/ pre-stop script /opt/onos/bin/onos halt 2>/opt/onos/var/stderr.log diff --git a/utils/junit/src/test/java/org/onlab/junit/TestUtilsTest.java b/utils/junit/src/test/java/org/onlab/junit/TestUtilsTest.java index 39712ba857..68e407fc18 100644 --- a/utils/junit/src/test/java/org/onlab/junit/TestUtilsTest.java +++ b/utils/junit/src/test/java/org/onlab/junit/TestUtilsTest.java @@ -101,9 +101,9 @@ public class TestUtilsTest { @Test public void testSetGetPrivateField() throws TestUtilsException { - assertEquals(42, TestUtils.getField(test, "privateField")); + assertEquals(42, (int) TestUtils.getField(test, "privateField")); TestUtils.setField(test, "privateField", 0xDEAD); - assertEquals(0xDEAD, TestUtils.getField(test, "privateField")); + assertEquals(0xDEAD, (int) TestUtils.getField(test, "privateField")); } /** @@ -114,9 +114,9 @@ public class TestUtilsTest { @Test public void testSetGetProtectedField() throws TestUtilsException { - assertEquals(2501, TestUtils.getField(test, "protectedField")); + assertEquals(2501, (int) TestUtils.getField(test, "protectedField")); TestUtils.setField(test, "protectedField", 0xBEEF); - assertEquals(0xBEEF, TestUtils.getField(test, "protectedField")); + assertEquals(0xBEEF, (int) TestUtils.getField(test, "protectedField")); } /**