[ONOS-6756] Replicate node version information for ISSU
Change-Id: Ibd31c573990f2732b7abf8615ca914ffb77615ec
diff --git a/cli/src/main/java/org/onosproject/cli/NodesListCommand.java b/cli/src/main/java/org/onosproject/cli/NodesListCommand.java
index 1ecb3f2..9c43f6f 100644
--- a/cli/src/main/java/org/onosproject/cli/NodesListCommand.java
+++ b/cli/src/main/java/org/onosproject/cli/NodesListCommand.java
@@ -24,6 +24,7 @@
import org.onlab.util.Tools;
import org.onosproject.cluster.ClusterAdminService;
import org.onosproject.cluster.ControllerNode;
+import org.onosproject.core.Version;
import org.onosproject.utils.Comparators;
import java.util.Collections;
@@ -39,7 +40,7 @@
description = "Lists all controller cluster nodes")
public class NodesListCommand extends AbstractShellCommand {
- private static final String FMT = "id=%s, address=%s:%s, state=%s, updated=%s %s";
+ private static final String FMT = "id=%s, address=%s:%s, state=%s, version=%s, updated=%s %s";
@Override
protected void execute() {
@@ -56,9 +57,12 @@
if (lastUpdated != null) {
timeAgo = Tools.timeAgo(lastUpdated.getMillis());
}
+ Version version = service.getVersion(node.id());
print(FMT, node.id(), node.ip(), node.tcpPort(),
- service.getState(node.id()), timeAgo,
- node.equals(self) ? "*" : "");
+ service.getState(node.id()),
+ version == null ? "unknown" : version,
+ timeAgo,
+ node.equals(self) ? "*" : "");
}
}
}
@@ -70,6 +74,7 @@
ControllerNode self = service.getLocalNode();
for (ControllerNode node : nodes) {
ControllerNode.State nodeState = service.getState(node.id());
+ Version nodeVersion = service.getVersion(node.id());
ObjectNode newNode = mapper.createObjectNode()
.put("id", node.id().toString())
.put("ip", node.ip().toString())
@@ -78,6 +83,9 @@
if (nodeState != null) {
newNode.put("state", nodeState.toString());
}
+ if (nodeVersion != null) {
+ newNode.put("version", nodeVersion.toString());
+ }
result.add(newNode);
}
return result;
diff --git a/core/api/src/main/java/org/onosproject/cluster/ClusterService.java b/core/api/src/main/java/org/onosproject/cluster/ClusterService.java
index aa984c0..1c4e2d7 100644
--- a/core/api/src/main/java/org/onosproject/cluster/ClusterService.java
+++ b/core/api/src/main/java/org/onosproject/cluster/ClusterService.java
@@ -18,6 +18,7 @@
import java.util.Set;
import org.joda.time.DateTime;
+import org.onosproject.core.Version;
import org.onosproject.event.ListenerService;
/**
@@ -60,6 +61,14 @@
ControllerNode.State getState(NodeId nodeId);
/**
+ * Returns the version of the given controller node.
+ *
+ * @param nodeId controller node identifier
+ * @return controller version
+ */
+ Version getVersion(NodeId nodeId);
+
+ /**
* Returns the system time when the availability state was last updated.
*
* @param nodeId controller node identifier
diff --git a/core/api/src/main/java/org/onosproject/cluster/ClusterStore.java b/core/api/src/main/java/org/onosproject/cluster/ClusterStore.java
index e3660f3..a181c4f 100644
--- a/core/api/src/main/java/org/onosproject/cluster/ClusterStore.java
+++ b/core/api/src/main/java/org/onosproject/cluster/ClusterStore.java
@@ -17,6 +17,7 @@
import org.joda.time.DateTime;
import org.onlab.packet.IpAddress;
+import org.onosproject.core.Version;
import org.onosproject.store.Store;
import java.util.Set;
@@ -57,6 +58,14 @@
ControllerNode.State getState(NodeId nodeId);
/**
+ * Returns the version of the specified controller node.
+ *
+ * @param nodeId controller instance identifier
+ * @return controller version
+ */
+ Version getVersion(NodeId nodeId);
+
+ /**
* Marks the current node as fully started.
*
* @param started true indicates all components have been started
diff --git a/core/api/src/main/java/org/onosproject/core/VersionService.java b/core/api/src/main/java/org/onosproject/core/VersionService.java
new file mode 100644
index 0000000..409ffbe
--- /dev/null
+++ b/core/api/src/main/java/org/onosproject/core/VersionService.java
@@ -0,0 +1,30 @@
+/*
+ * Copyright 2017-present Open Networking Laboratory
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.onosproject.core;
+
+/**
+ * Node version service.
+ */
+public interface VersionService {
+
+ /**
+ * Returns the product version.
+ *
+ * @return product version
+ */
+ Version version();
+
+}
\ No newline at end of file
diff --git a/core/api/src/test/java/org/onosproject/cluster/ClusterServiceAdapter.java b/core/api/src/test/java/org/onosproject/cluster/ClusterServiceAdapter.java
index 6f7917d..3c8cd36 100644
--- a/core/api/src/test/java/org/onosproject/cluster/ClusterServiceAdapter.java
+++ b/core/api/src/test/java/org/onosproject/cluster/ClusterServiceAdapter.java
@@ -21,6 +21,7 @@
import org.onlab.packet.IpAddress;
import com.google.common.collect.ImmutableSet;
+import org.onosproject.core.Version;
/**
* Test adapter for the cluster service.
@@ -50,6 +51,11 @@
}
@Override
+ public Version getVersion(NodeId nodeId) {
+ return null;
+ }
+
+ @Override
public DateTime getLastUpdated(NodeId nodeId) {
return null;
}
diff --git a/core/api/src/test/java/org/onosproject/core/VersionServiceAdapter.java b/core/api/src/test/java/org/onosproject/core/VersionServiceAdapter.java
new file mode 100644
index 0000000..d0031c0
--- /dev/null
+++ b/core/api/src/test/java/org/onosproject/core/VersionServiceAdapter.java
@@ -0,0 +1,26 @@
+/*
+ * Copyright 2017-present Open Networking Laboratory
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.onosproject.core;
+
+/**
+ * Version service adapter.
+ */
+public class VersionServiceAdapter implements VersionService {
+ @Override
+ public Version version() {
+ return null;
+ }
+}
diff --git a/core/common/src/test/java/org/onosproject/store/trivial/SimpleClusterStore.java b/core/common/src/test/java/org/onosproject/store/trivial/SimpleClusterStore.java
index ea65b54..d9c72d8 100644
--- a/core/common/src/test/java/org/onosproject/store/trivial/SimpleClusterStore.java
+++ b/core/common/src/test/java/org/onosproject/store/trivial/SimpleClusterStore.java
@@ -31,6 +31,8 @@
import org.onosproject.cluster.ControllerNode;
import org.onosproject.cluster.DefaultControllerNode;
import org.onosproject.cluster.NodeId;
+import org.onosproject.core.Version;
+import org.onosproject.core.VersionService;
import org.onosproject.event.EventDeliveryService;
import org.onosproject.event.ListenerRegistry;
import org.onosproject.net.intent.WorkPartitionEvent;
@@ -67,6 +69,9 @@
@Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
protected EventDeliveryService eventDispatcher;
+ @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
+ protected VersionService versionService;
+
private ListenerRegistry<WorkPartitionEvent, WorkPartitionEventListener> listenerRegistry;
private boolean started = false;
@@ -108,6 +113,11 @@
}
@Override
+ public Version getVersion(NodeId nodeId) {
+ return instance.id().equals(nodeId) ? versionService.version() : null;
+ }
+
+ @Override
public void markFullyStarted(boolean started) {
this.started = started;
}
diff --git a/core/common/src/test/java/org/onosproject/store/trivial/SimpleMastershipStore.java b/core/common/src/test/java/org/onosproject/store/trivial/SimpleMastershipStore.java
index ad4386e..2a8caf0 100644
--- a/core/common/src/test/java/org/onosproject/store/trivial/SimpleMastershipStore.java
+++ b/core/common/src/test/java/org/onosproject/store/trivial/SimpleMastershipStore.java
@@ -45,6 +45,8 @@
import org.onosproject.cluster.DefaultControllerNode;
import org.onosproject.cluster.NodeId;
import org.onosproject.cluster.RoleInfo;
+import org.onosproject.core.Version;
+import org.onosproject.core.VersionService;
import org.onosproject.mastership.MastershipEvent;
import org.onosproject.mastership.MastershipStore;
import org.onosproject.mastership.MastershipStoreDelegate;
@@ -75,6 +77,9 @@
@Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
protected ClusterService clusterService;
+ @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
+ protected VersionService versionService;
+
//devices mapped to their masters, to emulate multiple nodes
protected final Map<DeviceId, NodeId> masterMap = new HashMap<>();
//emulate backups with pile of nodes
@@ -122,6 +127,14 @@
}
@Override
+ public Version getVersion(NodeId nodeId) {
+ if (instance.id().equals(nodeId)) {
+ return versionService.version();
+ }
+ return null;
+ }
+
+ @Override
public DateTime getLastUpdated(NodeId nodeId) {
return creationTime;
}
diff --git a/core/net/src/main/java/org/onosproject/cluster/impl/ClusterManager.java b/core/net/src/main/java/org/onosproject/cluster/impl/ClusterManager.java
index a2b9000..b7c9045 100644
--- a/core/net/src/main/java/org/onosproject/cluster/impl/ClusterManager.java
+++ b/core/net/src/main/java/org/onosproject/cluster/impl/ClusterManager.java
@@ -44,6 +44,7 @@
import org.onosproject.cluster.NodeId;
import org.onosproject.cluster.Partition;
import org.onosproject.cluster.PartitionId;
+import org.onosproject.core.Version;
import org.onosproject.event.AbstractListenerManager;
import org.slf4j.Logger;
@@ -135,6 +136,13 @@
}
@Override
+ public Version getVersion(NodeId nodeId) {
+ checkPermission(CLUSTER_READ);
+ checkNotNull(nodeId, INSTANCE_ID_NULL);
+ return store.getVersion(nodeId);
+ }
+
+ @Override
public void markFullyStarted(boolean started) {
store.markFullyStarted(started);
}
diff --git a/core/net/src/main/java/org/onosproject/core/impl/CoreManager.java b/core/net/src/main/java/org/onosproject/core/impl/CoreManager.java
index cda738f..4ff6eb0 100644
--- a/core/net/src/main/java/org/onosproject/core/impl/CoreManager.java
+++ b/core/net/src/main/java/org/onosproject/core/impl/CoreManager.java
@@ -35,18 +35,13 @@
import org.onosproject.core.IdBlockStore;
import org.onosproject.core.IdGenerator;
import org.onosproject.core.Version;
+import org.onosproject.core.VersionService;
import org.onosproject.event.EventDeliveryService;
import org.osgi.service.component.ComponentContext;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
-import java.io.File;
-import java.io.IOException;
-import java.nio.file.Files;
-import java.nio.file.Path;
-import java.nio.file.Paths;
import java.util.Dictionary;
-import java.util.List;
import java.util.Set;
import static com.google.common.base.Preconditions.checkNotNull;
@@ -54,7 +49,6 @@
import static org.onosproject.security.AppPermission.Type.APP_READ;
import static org.onosproject.security.AppPermission.Type.APP_WRITE;
-
/**
* Core service implementation.
*/
@@ -64,8 +58,8 @@
private final Logger log = LoggerFactory.getLogger(getClass());
- private static final File VERSION_FILE = new File("../VERSION");
- private static Version version = Version.version("1.11.0-SNAPSHOT");
+ @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
+ protected VersionService versionService;
@Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
protected ApplicationIdStore applicationIdStore;
@@ -105,16 +99,6 @@
protected void activate() {
registerApplication(CORE_APP_NAME);
cfgService.registerProperties(getClass());
- try {
- Path path = Paths.get(VERSION_FILE.getPath());
- List<String> versionLines = Files.readAllLines(path);
- if (versionLines != null && !versionLines.isEmpty()) {
- version = Version.version(versionLines.get(0));
- }
- } catch (IOException e) {
- // version file not found, using default
- log.trace("Version file not found", e);
- }
}
@Deactivate
@@ -127,7 +111,7 @@
@Override
public Version version() {
checkPermission(APP_READ);
- return version;
+ return versionService.version();
}
@Override
@@ -148,7 +132,6 @@
return applicationIdStore.getAppId(name);
}
-
@Override
public ApplicationId registerApplication(String name) {
checkPermission(APP_WRITE);
@@ -171,7 +154,6 @@
return new BlockAllocatorBasedIdGenerator(allocator);
}
-
@Modified
protected void modified(ComponentContext context) {
Dictionary<?, ?> properties = context.getProperties();
diff --git a/core/net/src/main/java/org/onosproject/core/impl/VersionManager.java b/core/net/src/main/java/org/onosproject/core/impl/VersionManager.java
new file mode 100644
index 0000000..c683205
--- /dev/null
+++ b/core/net/src/main/java/org/onosproject/core/impl/VersionManager.java
@@ -0,0 +1,63 @@
+/*
+ * Copyright 2017-present Open Networking Laboratory
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.onosproject.core.impl;
+
+import java.io.File;
+import java.io.IOException;
+import java.nio.file.Files;
+import java.nio.file.Path;
+import java.nio.file.Paths;
+import java.util.List;
+
+import org.apache.felix.scr.annotations.Activate;
+import org.apache.felix.scr.annotations.Component;
+import org.apache.felix.scr.annotations.Service;
+import org.onosproject.core.Version;
+import org.onosproject.core.VersionService;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+/**
+ * Node version service implementation.
+ */
+@Component(immediate = true)
+@Service
+public class VersionManager implements VersionService {
+
+ private final Logger log = LoggerFactory.getLogger(getClass());
+
+ private static final File VERSION_FILE = new File("../VERSION");
+ private static Version version = Version.version("1.11.0-SNAPSHOT");
+
+ @Activate
+ protected void activate() {
+ try {
+ Path path = Paths.get(VERSION_FILE.getPath());
+ List<String> versionLines = Files.readAllLines(path);
+ if (versionLines != null && !versionLines.isEmpty()) {
+ version = Version.version(versionLines.get(0));
+ }
+ } catch (IOException e) {
+ // version file not found, using default
+ log.trace("Version file not found", e);
+ }
+ }
+
+ @Override
+ public Version version() {
+ return version;
+ }
+}
\ No newline at end of file
diff --git a/core/net/src/test/java/org/onosproject/core/impl/VersionManagerTest.java b/core/net/src/test/java/org/onosproject/core/impl/VersionManagerTest.java
new file mode 100644
index 0000000..aa87d90
--- /dev/null
+++ b/core/net/src/test/java/org/onosproject/core/impl/VersionManagerTest.java
@@ -0,0 +1,31 @@
+/*
+ * Copyright 2017-present Open Networking Laboratory
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.onosproject.core.impl;
+
+import org.junit.Test;
+
+import static org.junit.Assert.assertNotNull;
+
+/**
+ * Version manager test.
+ */
+public class VersionManagerTest {
+ @Test
+ public void testVersionManager() throws Exception {
+ VersionManager versionManager = new VersionManager();
+ assertNotNull(versionManager.version());
+ }
+}
\ No newline at end of file
diff --git a/core/store/dist/src/main/java/org/onosproject/store/cluster/impl/DistributedClusterStore.java b/core/store/dist/src/main/java/org/onosproject/store/cluster/impl/DistributedClusterStore.java
index d727ebe..4374a43 100644
--- a/core/store/dist/src/main/java/org/onosproject/store/cluster/impl/DistributedClusterStore.java
+++ b/core/store/dist/src/main/java/org/onosproject/store/cluster/impl/DistributedClusterStore.java
@@ -15,7 +15,6 @@
*/
package org.onosproject.store.cluster.impl;
-import com.google.common.base.MoreObjects;
import com.google.common.collect.ImmutableSet;
import com.google.common.collect.Maps;
@@ -41,6 +40,8 @@
import org.onosproject.cluster.ControllerNode.State;
import org.onosproject.cluster.DefaultControllerNode;
import org.onosproject.cluster.NodeId;
+import org.onosproject.core.Version;
+import org.onosproject.core.VersionService;
import org.onosproject.store.AbstractStore;
import org.onosproject.store.cluster.messaging.Endpoint;
import org.onosproject.store.cluster.messaging.MessagingService;
@@ -59,6 +60,7 @@
import java.util.function.BiConsumer;
import java.util.stream.Collectors;
+import static com.google.common.base.MoreObjects.firstNonNull;
import static com.google.common.base.Preconditions.checkArgument;
import static com.google.common.base.Preconditions.checkNotNull;
import static com.google.common.base.Strings.isNullOrEmpty;
@@ -93,7 +95,7 @@
private int phiFailureThreshold = DEFAULT_PHI_FAILURE_THRESHOLD;
private static final StoreSerializer SERIALIZER = StoreSerializer.using(
- KryoNamespace.newBuilder()
+ KryoNamespace.newBuilder()
.register(KryoNamespaces.API)
.nextId(KryoNamespaces.BEGIN_USER_CUSTOM_ID)
.register(HeartbeatMessage.class)
@@ -103,7 +105,8 @@
private final Map<NodeId, ControllerNode> allNodes = Maps.newConcurrentMap();
private final Map<NodeId, State> nodeStates = Maps.newConcurrentMap();
- private final Map<NodeId, DateTime> nodeStateLastUpdatedTimes = Maps.newConcurrentMap();
+ private final Map<NodeId, Version> nodeVersions = Maps.newConcurrentMap();
+ private final Map<NodeId, DateTime> nodeLastUpdatedTimes = Maps.newConcurrentMap();
private ScheduledExecutorService heartBeatSender = Executors.newSingleThreadScheduledExecutor(
groupedThreads("onos/cluster/membership", "heartbeat-sender", log));
@@ -113,6 +116,10 @@
private PhiAccrualFailureDetector failureDetector;
private ControllerNode localNode;
+ private Version localVersion;
+
+ @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
+ protected VersionService versionService;
@Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
protected ClusterMetadataService clusterMetadataService;
@@ -122,9 +129,9 @@
// This must be optional to avoid a cyclic dependency
@Reference(cardinality = ReferenceCardinality.OPTIONAL_UNARY,
- bind = "bindComponentConfigService",
- unbind = "unbindComponentConfigService",
- policy = ReferencePolicy.DYNAMIC)
+ bind = "bindComponentConfigService",
+ unbind = "unbindComponentConfigService",
+ policy = ReferencePolicy.DYNAMIC)
protected ComponentConfigService cfgService;
/**
@@ -155,14 +162,16 @@
@Activate
public void activate() {
localNode = clusterMetadataService.getLocalNode();
+ localVersion = versionService.version();
+ nodeVersions.put(localNode.id(), localVersion);
messagingService.registerHandler(HEARTBEAT_MESSAGE,
- new HeartbeatMessageHandler(), heartBeatMessageHandler);
+ new HeartbeatMessageHandler(), heartBeatMessageHandler);
failureDetector = new PhiAccrualFailureDetector();
heartBeatSender.scheduleWithFixedDelay(this::heartbeat, 0,
- heartbeatInterval, TimeUnit.MILLISECONDS);
+ heartbeatInterval, TimeUnit.MILLISECONDS);
log.info("Started");
}
@@ -216,12 +225,18 @@
@Override
public State getState(NodeId nodeId) {
checkNotNull(nodeId, INSTANCE_ID_NULL);
- return MoreObjects.firstNonNull(nodeStates.get(nodeId), State.INACTIVE);
+ return firstNonNull(nodeStates.get(nodeId), State.INACTIVE);
+ }
+
+ @Override
+ public Version getVersion(NodeId nodeId) {
+ checkNotNull(nodeId, INSTANCE_ID_NULL);
+ return nodeVersions.get(nodeId);
}
@Override
public void markFullyStarted(boolean started) {
- updateState(localNode.id(), started ? State.READY : State.ACTIVE);
+ updateNode(localNode.id(), started ? State.READY : State.ACTIVE, null);
}
@Override
@@ -238,22 +253,27 @@
ControllerNode node = allNodes.remove(nodeId);
if (node != null) {
nodeStates.remove(nodeId);
+ nodeVersions.remove(nodeId);
notifyDelegate(new ClusterEvent(ClusterEvent.Type.INSTANCE_REMOVED, node));
}
}
private void addNode(ControllerNode node) {
allNodes.put(node.id(), node);
- updateState(node.id(), node.equals(localNode) ? State.ACTIVE : State.INACTIVE);
+ updateNode(node.id(), node.equals(localNode) ? State.ACTIVE : State.INACTIVE, null);
notifyDelegate(new ClusterEvent(ClusterEvent.Type.INSTANCE_ADDED, node));
}
- private void updateState(NodeId nodeId, State newState) {
+ private void updateNode(NodeId nodeId, State newState, Version newVersion) {
State currentState = nodeStates.get(nodeId);
- if (!Objects.equals(currentState, newState)) {
+ Version currentVersion = nodeVersions.get(nodeId);
+ if (!Objects.equals(currentState, newState) || !Objects.equals(currentVersion, newVersion)) {
nodeStates.put(nodeId, newState);
- nodeStateLastUpdatedTimes.put(nodeId, DateTime.now());
- notifyStateChange(nodeId, currentState, newState);
+ if (newVersion != null) {
+ nodeVersions.put(nodeId, newVersion);
+ }
+ nodeLastUpdatedTimes.put(nodeId, DateTime.now());
+ notifyChange(nodeId, currentState, newState, currentVersion, newVersion);
}
}
@@ -264,18 +284,18 @@
.filter(node -> !(node.id().equals(localNode.id())))
.collect(Collectors.toSet());
State state = nodeStates.get(localNode.id());
- byte[] hbMessagePayload = SERIALIZER.encode(new HeartbeatMessage(localNode, state));
+ byte[] hbMessagePayload = SERIALIZER.encode(new HeartbeatMessage(localNode, state, localVersion));
peers.forEach((node) -> {
heartbeatToPeer(hbMessagePayload, node);
State currentState = nodeStates.get(node.id());
double phi = failureDetector.phi(node.id());
if (phi >= phiFailureThreshold) {
if (currentState.isActive()) {
- updateState(node.id(), State.INACTIVE);
+ updateNode(node.id(), State.INACTIVE, null);
}
} else {
if (currentState == State.INACTIVE) {
- updateState(node.id(), State.ACTIVE);
+ updateNode(node.id(), State.ACTIVE, null);
}
}
});
@@ -284,8 +304,8 @@
}
}
- private void notifyStateChange(NodeId nodeId, State oldState, State newState) {
- if (oldState != newState) {
+ private void notifyChange(NodeId nodeId, State oldState, State newState, Version oldVersion, Version newVersion) {
+ if (oldState != newState || !Objects.equals(oldVersion, newVersion)) {
ControllerNode node = allNodes.get(nodeId);
// Either this node or that node is no longer part of the same cluster
if (node == null) {
@@ -314,7 +334,7 @@
HeartbeatMessage hb = SERIALIZER.decode(message);
if (clusterMetadataService.getClusterMetadata().getNodes().contains(hb.source())) {
failureDetector.report(hb.source().id());
- updateState(hb.source().id(), hb.state);
+ updateNode(hb.source().id(), hb.state, hb.version);
}
}
}
@@ -322,10 +342,12 @@
private static class HeartbeatMessage {
private ControllerNode source;
private State state;
+ private Version version;
- public HeartbeatMessage(ControllerNode source, State state) {
+ public HeartbeatMessage(ControllerNode source, State state, Version version) {
this.source = source;
this.state = state != null ? state : State.ACTIVE;
+ this.version = version;
}
public ControllerNode source() {
@@ -335,7 +357,7 @@
@Override
public DateTime getLastUpdated(NodeId nodeId) {
- return nodeStateLastUpdatedTimes.get(nodeId);
+ return nodeLastUpdatedTimes.get(nodeId);
}
/**
@@ -353,7 +375,7 @@
DEFAULT_HEARTBEAT_INTERVAL);
} else {
int newHeartbeatInterval = isNullOrEmpty(s) ? DEFAULT_HEARTBEAT_INTERVAL
- : Integer.parseInt(s.trim());
+ : Integer.parseInt(s.trim());
if (newHeartbeatInterval > 0 && heartbeatInterval != newHeartbeatInterval) {
heartbeatInterval = newHeartbeatInterval;
restartHeartbeatSender();
@@ -370,7 +392,7 @@
DEFAULT_PHI_FAILURE_THRESHOLD);
} else {
int newPhiFailureThreshold = isNullOrEmpty(s) ? DEFAULT_HEARTBEAT_INTERVAL
- : Integer.parseInt(s.trim());
+ : Integer.parseInt(s.trim());
setPhiFailureThreshold(newPhiFailureThreshold);
log.info("Configured. Phi failure threshold is configured to {}",
phiFailureThreshold);
@@ -414,10 +436,10 @@
heartBeatSender = Executors.newSingleThreadScheduledExecutor(
groupedThreads("onos/cluster/membership", "heartbeat-sender-%d", log));
heartBeatSender.scheduleWithFixedDelay(this::heartbeat, 0,
- heartbeatInterval, TimeUnit.MILLISECONDS);
+ heartbeatInterval, TimeUnit.MILLISECONDS);
prevSender.shutdown();
} catch (Exception e) {
log.warn(e.getMessage());
}
}
-}
+}
\ No newline at end of file
diff --git a/core/store/dist/src/test/java/org/onosproject/store/cluster/impl/DistributedClusterStoreTest.java b/core/store/dist/src/test/java/org/onosproject/store/cluster/impl/DistributedClusterStoreTest.java
index 512d162..7c48791 100644
--- a/core/store/dist/src/test/java/org/onosproject/store/cluster/impl/DistributedClusterStoreTest.java
+++ b/core/store/dist/src/test/java/org/onosproject/store/cluster/impl/DistributedClusterStoreTest.java
@@ -27,6 +27,8 @@
import org.onosproject.cluster.ControllerNode;
import org.onosproject.cluster.DefaultControllerNode;
import org.onosproject.cluster.NodeId;
+import org.onosproject.core.Version;
+import org.onosproject.core.VersionServiceAdapter;
import org.onosproject.store.cluster.messaging.impl.NettyMessagingManager;
import java.util.Set;
@@ -55,7 +57,6 @@
private static final int PORT2 = 2;
private static Set<ControllerNode> nodes;
-
private TestDelegate delegate = new TestDelegate();
private class TestDelegate implements ClusterStoreDelegate {
private ClusterEvent event;
@@ -65,8 +66,6 @@
}
}
-
-
@Before
public void setUp() throws Exception {
distributedClusterStore = new DistributedClusterStore();
@@ -78,6 +77,12 @@
};
distributedClusterStore.messagingService = new NettyMessagingManager();
distributedClusterStore.cfgService = new ComponentConfigAdapter();
+ distributedClusterStore.versionService = new VersionServiceAdapter() {
+ @Override
+ public Version version() {
+ return Version.version("1.1.1");
+ }
+ };
distributedClusterStore.activate();
clusterStore = distributedClusterStore;
}
@@ -93,11 +98,11 @@
assertThat(clusterStore.getNode((nodeId)), is(nullValue()));
assertFalse(clusterStore.hasDelegate());
assertThat(clusterStore.getState(nodeId), is(ControllerNode.State.INACTIVE));
+ assertThat(clusterStore.getVersion(nodeId), is(nullValue()));
}
@Test
public void addNodes() {
-
clusterStore.setDelegate(delegate);
assertThat(clusterStore.hasDelegate(), is(true));
clusterStore.addNode(NID1, IP1, PORT1);
diff --git a/incubator/store/src/main/java/org/onosproject/incubator/store/virtual/impl/SimpleVirtualMastershipStore.java b/incubator/store/src/main/java/org/onosproject/incubator/store/virtual/impl/SimpleVirtualMastershipStore.java
index 47b9c6f..c390513 100644
--- a/incubator/store/src/main/java/org/onosproject/incubator/store/virtual/impl/SimpleVirtualMastershipStore.java
+++ b/incubator/store/src/main/java/org/onosproject/incubator/store/virtual/impl/SimpleVirtualMastershipStore.java
@@ -32,6 +32,8 @@
import org.onosproject.cluster.DefaultControllerNode;
import org.onosproject.cluster.NodeId;
import org.onosproject.cluster.RoleInfo;
+import org.onosproject.core.Version;
+import org.onosproject.core.VersionService;
import org.onosproject.incubator.net.virtual.NetworkId;
import org.onosproject.incubator.net.virtual.VirtualNetworkMastershipStore;
import org.onosproject.mastership.MastershipEvent;
@@ -74,6 +76,9 @@
@Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
protected ClusterService clusterService;
+ @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
+ protected VersionService versionService;
+
//devices mapped to their masters, to emulate multiple nodes
protected final Map<NetworkId, Map<DeviceId, NodeId>> masterMapByNetwork =
new HashMap<>();
@@ -479,6 +484,14 @@
}
@Override
+ public Version getVersion(NodeId nodeId) {
+ if (instance.id().equals(nodeId)) {
+ return versionService.version();
+ }
+ return null;
+ }
+
+ @Override
public DateTime getLastUpdated(NodeId nodeId) {
return creationTime;
}
diff --git a/tools/build/onos-change-version b/tools/build/onos-change-version
index f0de5f6..a985e9a 100755
--- a/tools/build/onos-change-version
+++ b/tools/build/onos-change-version
@@ -33,9 +33,9 @@
sed -i "" -E "s/ -Dversion=.*\"/ -Dversion=$NEW_VERSION\"/" $ONOS_ROOT/tools/test/bin/onos-archetypes-test
sed -i "" -E "s/ONOS_POM_VERSION=.*\"/ONOS_POM_VERSION=\"$NEW_VERSION\"/" $ONOS_ROOT/tools/build/envDefaults
-# Augment fallback version in CoreManager
+# Augment fallback version in VersionManager
sed -i "" -E "s/Version\.version\(\"[^\"]*\"\)/Version.version(\"$NEW_VERSION\")/" \
- $ONOS_ROOT/core/net/src/main/java/org/onosproject/core/impl/CoreManager.java
+ $ONOS_ROOT/core/net/src/main/java/org/onosproject/core/impl/VersionManager.java
# Augment the version in archetypes tree.
mvn -f tools/package/archetypes/pom.xml versions:set -DnewVersion=$NEW_VERSION versions:commit