Upgrade to Atomix 3.0-rc5
* Upgrade Raft primitives to Atomix 3.0
* Replace cluster store and messaging implementations with Atomix cluster management/messaging
* Add test scripts for installing/starting Atomix cluster
* Replace core primitives with Atomix primitives.

Change-Id: I7623653c81292a34f21b01f5f38ca11b5ef15cad
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 56ea048..edbd1f7 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
@@ -16,15 +16,9 @@
 package org.onosproject.cluster.impl;
 
 import java.time.Instant;
-import java.util.ArrayList;
-import java.util.Collection;
-import java.util.Collections;
-import java.util.HashSet;
-import java.util.List;
 import java.util.Set;
 import java.util.concurrent.atomic.AtomicReference;
 
-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;
@@ -33,26 +27,20 @@
 import org.apache.felix.scr.annotations.Service;
 import org.apache.karaf.system.SystemService;
 import org.onlab.packet.IpAddress;
-import org.onlab.util.Tools;
 import org.onosproject.cluster.ClusterAdminService;
 import org.onosproject.cluster.ClusterEvent;
 import org.onosproject.cluster.ClusterEventListener;
 import org.onosproject.cluster.ClusterMetadata;
-import org.onosproject.cluster.ClusterMetadataAdminService;
 import org.onosproject.cluster.ClusterMetadataDiff;
 import org.onosproject.cluster.ClusterMetadataEvent;
 import org.onosproject.cluster.ClusterMetadataEventListener;
-import org.onosproject.cluster.ClusterMetadataService;
 import org.onosproject.cluster.ClusterService;
 import org.onosproject.cluster.ClusterStore;
 import org.onosproject.cluster.ClusterStoreDelegate;
 import org.onosproject.cluster.ControllerNode;
-import org.onosproject.cluster.DefaultPartition;
+import org.onosproject.cluster.Node;
 import org.onosproject.cluster.NodeId;
-import org.onosproject.cluster.Partition;
-import org.onosproject.cluster.PartitionId;
 import org.onosproject.core.Version;
-import org.onosproject.core.VersionService;
 import org.onosproject.event.AbstractListenerManager;
 import org.slf4j.Logger;
 
@@ -78,20 +66,11 @@
     private ClusterStoreDelegate delegate = new InternalStoreDelegate();
 
     @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
-    protected ClusterMetadataService clusterMetadataService;
-
-    @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
-    protected ClusterMetadataAdminService clusterMetadataAdminService;
-
-    @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
     protected ClusterStore store;
 
     @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
     protected SystemService systemService;
 
-    @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
-    protected VersionService versionService;
-
     private final AtomicReference<ClusterMetadata> currentMetadata = new AtomicReference<>();
     private final InternalClusterMetadataListener metadataListener = new InternalClusterMetadataListener();
 
@@ -99,14 +78,11 @@
     public void activate() {
         store.setDelegate(delegate);
         eventDispatcher.addSink(ClusterEvent.class, listenerRegistry);
-        clusterMetadataService.addListener(metadataListener);
-        processMetadata(clusterMetadataService.getClusterMetadata());
         log.info("Started");
     }
 
     @Deactivate
     public void deactivate() {
-        clusterMetadataService.removeListener(metadataListener);
         store.unsetDelegate(delegate);
         eventDispatcher.removeSink(ClusterEvent.class);
         log.info("Stopped");
@@ -119,6 +95,12 @@
     }
 
     @Override
+    public Set<Node> getConsensusNodes() {
+        checkPermission(CLUSTER_READ);
+        return store.getStorageNodes();
+    }
+
+    @Override
     public Set<ControllerNode> getNodes() {
         checkPermission(CLUSTER_READ);
         return store.getNodes();
@@ -163,25 +145,7 @@
 
     @Override
     public void formCluster(Set<ControllerNode> nodes, int partitionSize) {
-        checkNotNull(nodes, "Nodes cannot be null");
-        checkArgument(!nodes.isEmpty(), "Nodes cannot be empty");
-
-        // Validate that the given nodes intersect with the currently configured nodes.
-        Set<ControllerNode> existingNodes = Sets.newHashSet(clusterMetadataService.getClusterMetadata().getNodes());
-        checkArgument(
-            !Sets.intersection(nodes, existingNodes).isEmpty(),
-            "Nodes must intersect with current cluster configuration");
-
-        ClusterMetadata metadata = new ClusterMetadata("default", nodes, buildDefaultPartitions(nodes, partitionSize));
-        clusterMetadataAdminService.setClusterMetadata(metadata);
-        try {
-            log.warn("Shutting down container for cluster reconfiguration!");
-            // Clean up persistent state associated with previous cluster configuration.
-            Tools.removeDirectory(System.getProperty("karaf.data") + "/db/partitions/");
-            systemService.reboot("now", SystemService.Swipe.NONE);
-        } catch (Exception e) {
-            log.error("Unable to reboot container", e);
-        }
+        log.warn("formCluster is deprecated");
     }
 
     @Override
@@ -206,24 +170,6 @@
         }
     }
 
-    private Set<Partition> buildDefaultPartitions(Collection<ControllerNode> nodes, int partitionSize) {
-        List<ControllerNode> sorted = new ArrayList<>(nodes);
-        Collections.sort(sorted, (o1, o2) -> o1.id().toString().compareTo(o2.id().toString()));
-        Set<Partition> partitions = Sets.newHashSet();
-        // add partitions
-        int length = nodes.size();
-        int count = Math.min(partitionSize, length);
-        for (int i = 0; i < length; i++) {
-            int index = i;
-            Set<NodeId> set = new HashSet<>(count);
-            for (int j = 0; j < count; j++) {
-                set.add(sorted.get((i + j) % length).id());
-            }
-            partitions.add(new DefaultPartition(PartitionId.from((index + 1)), versionService.version(), set));
-        }
-        return partitions;
-    }
-
     /**
      * Processes metadata by adding and removing nodes from the cluster.
      */
diff --git a/core/net/src/main/java/org/onosproject/cluster/impl/ClusterMetadataManager.java b/core/net/src/main/java/org/onosproject/cluster/impl/ClusterMetadataManager.java
index 75e6f3f..347c812 100644
--- a/core/net/src/main/java/org/onosproject/cluster/impl/ClusterMetadataManager.java
+++ b/core/net/src/main/java/org/onosproject/cluster/impl/ClusterMetadataManager.java
@@ -15,6 +15,15 @@
  */
 package org.onosproject.cluster.impl;
 
+import java.net.Inet4Address;
+import java.net.InetAddress;
+import java.net.MalformedURLException;
+import java.net.NetworkInterface;
+import java.net.SocketException;
+import java.net.URL;
+import java.net.UnknownHostException;
+import java.util.Enumeration;
+
 import org.apache.felix.scr.annotations.Activate;
 import org.apache.felix.scr.annotations.Component;
 import org.apache.felix.scr.annotations.Deactivate;
@@ -29,6 +38,7 @@
 import org.onosproject.cluster.ClusterMetadataProviderService;
 import org.onosproject.cluster.ClusterMetadataService;
 import org.onosproject.cluster.ControllerNode;
+import org.onosproject.cluster.DefaultControllerNode;
 import org.onosproject.cluster.NodeId;
 import org.onosproject.cluster.PartitionId;
 import org.onosproject.net.provider.AbstractListenerProviderRegistry;
@@ -36,14 +46,6 @@
 import org.onosproject.store.service.Versioned;
 import org.slf4j.Logger;
 
-import java.net.InetAddress;
-import java.net.MalformedURLException;
-import java.net.NetworkInterface;
-import java.net.SocketException;
-import java.net.URL;
-import java.util.Collection;
-import java.util.Enumeration;
-
 import static com.google.common.base.Preconditions.checkNotNull;
 import static org.onosproject.security.AppGuard.checkPermission;
 import static org.onosproject.security.AppPermission.Type.CLUSTER_READ;
@@ -96,7 +98,20 @@
     public ControllerNode getLocalNode() {
         checkPermission(CLUSTER_READ);
         if (localNode == null) {
-            establishSelfIdentity();
+            ControllerNode localNode = getProvider().getClusterMetadata().value().getLocalNode();
+            try {
+                if (localNode != null) {
+                    this.localNode = new DefaultControllerNode(
+                        localNode.id(),
+                        localNode.ip() != null ? localNode.ip() : findLocalIp(),
+                        localNode.tcpPort());
+                } else {
+                    IpAddress ip = findLocalIp();
+                    this.localNode = new DefaultControllerNode(NodeId.nodeId(ip.toString()), ip);
+                }
+            } catch (SocketException e) {
+                throw new IllegalStateException(e);
+            }
         }
         return localNode;
     }
@@ -141,37 +156,32 @@
         }
     }
 
-    private IpAddress findLocalIp(Collection<ControllerNode> controllerNodes) throws SocketException {
-        Enumeration<NetworkInterface> interfaces =
-                NetworkInterface.getNetworkInterfaces();
+    private IpAddress findLocalIp() throws SocketException {
+        Enumeration<NetworkInterface> interfaces = NetworkInterface.getNetworkInterfaces();
         while (interfaces.hasMoreElements()) {
             NetworkInterface iface = interfaces.nextElement();
+            if (iface.isLoopback() || iface.isPointToPoint()) {
+                continue;
+            }
+
             Enumeration<InetAddress> inetAddresses = iface.getInetAddresses();
             while (inetAddresses.hasMoreElements()) {
-                IpAddress ip = IpAddress.valueOf(inetAddresses.nextElement());
-                if (controllerNodes.stream()
-                        .map(ControllerNode::ip)
-                        .anyMatch(nodeIp -> ip.equals(nodeIp))) {
-                    return ip;
+                InetAddress inetAddress = inetAddresses.nextElement();
+                if (inetAddress instanceof Inet4Address) {
+                    Inet4Address inet4Address = (Inet4Address) inetAddress;
+                    try {
+                        if (!inet4Address.getHostAddress().equals(InetAddress.getLocalHost().getHostAddress())) {
+                            return IpAddress.valueOf(inetAddress);
+                        }
+                    } catch (UnknownHostException e) {
+                        return IpAddress.valueOf(inetAddress);
+                    }
                 }
             }
         }
         throw new IllegalStateException("Unable to determine local ip");
     }
 
-    private void establishSelfIdentity() {
-        try {
-            IpAddress ip = findLocalIp(getClusterMetadata().getNodes());
-            localNode = getClusterMetadata().getNodes()
-                                            .stream()
-                                            .filter(node -> node.ip().equals(ip))
-                                            .findFirst()
-                                            .get();
-        } catch (SocketException e) {
-            throw new IllegalStateException("Cannot determine local IP", e);
-        }
-    }
-
     private class InternalClusterMetadataProviderService
             extends AbstractProviderService<ClusterMetadataProvider>
             implements ClusterMetadataProviderService {
diff --git a/core/net/src/main/java/org/onosproject/cluster/impl/ConfigFileBasedClusterMetadataProvider.java b/core/net/src/main/java/org/onosproject/cluster/impl/ConfigFileBasedClusterMetadataProvider.java
index c1b5de1..8086206 100644
--- a/core/net/src/main/java/org/onosproject/cluster/impl/ConfigFileBasedClusterMetadataProvider.java
+++ b/core/net/src/main/java/org/onosproject/cluster/impl/ConfigFileBasedClusterMetadataProvider.java
@@ -15,17 +15,19 @@
  */
 package org.onosproject.cluster.impl;
 
-import com.fasterxml.jackson.core.JsonGenerator;
-import com.fasterxml.jackson.core.JsonParser;
-import com.fasterxml.jackson.core.JsonProcessingException;
-import com.fasterxml.jackson.databind.DeserializationContext;
-import com.fasterxml.jackson.databind.JsonDeserializer;
-import com.fasterxml.jackson.databind.JsonNode;
-import com.fasterxml.jackson.databind.JsonSerializer;
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.IOException;
+import java.net.HttpURLConnection;
+import java.net.URL;
+import java.util.Set;
+import java.util.UUID;
+import java.util.concurrent.ScheduledExecutorService;
+import java.util.concurrent.TimeUnit;
+import java.util.concurrent.atomic.AtomicReference;
+import java.util.stream.Collectors;
+
 import com.fasterxml.jackson.databind.ObjectMapper;
-import com.fasterxml.jackson.databind.SerializerProvider;
-import com.fasterxml.jackson.databind.module.SimpleModule;
-import com.google.common.collect.Sets;
 import com.google.common.io.Files;
 import org.apache.felix.scr.annotations.Activate;
 import org.apache.felix.scr.annotations.Component;
@@ -37,26 +39,14 @@
 import org.onosproject.cluster.ClusterMetadataProvider;
 import org.onosproject.cluster.ClusterMetadataProviderRegistry;
 import org.onosproject.cluster.ClusterMetadataProviderService;
-import org.onosproject.cluster.ControllerNode;
 import org.onosproject.cluster.DefaultControllerNode;
-import org.onosproject.cluster.DefaultPartition;
+import org.onosproject.cluster.Node;
 import org.onosproject.cluster.NodeId;
-import org.onosproject.cluster.Partition;
 import org.onosproject.cluster.PartitionId;
 import org.onosproject.net.provider.ProviderId;
 import org.onosproject.store.service.Versioned;
 import org.slf4j.Logger;
 
-import java.io.File;
-import java.io.FileInputStream;
-import java.io.IOException;
-import java.net.HttpURLConnection;
-import java.net.URL;
-import java.util.Set;
-import java.util.concurrent.ScheduledExecutorService;
-import java.util.concurrent.TimeUnit;
-import java.util.concurrent.atomic.AtomicReference;
-
 import static com.google.common.base.Preconditions.checkState;
 import static java.util.concurrent.Executors.newSingleThreadScheduledExecutor;
 import static org.onlab.util.Tools.groupedThreads;
@@ -70,11 +60,6 @@
 
     private final Logger log = getLogger(getClass());
 
-    // constants for filed names (used in serialization)
-    private static final String ID = "id";
-    private static final String PORT = "port";
-    private static final String IP = "ip";
-
     private static final String CONFIG_DIR = "../config";
     private static final String CONFIG_FILE_NAME = "cluster.json";
     private static final File CONFIG_FILE = new File(CONFIG_DIR, CONFIG_FILE_NAME);
@@ -94,16 +79,6 @@
     @Activate
     public void activate() {
         mapper = new ObjectMapper();
-        SimpleModule module = new SimpleModule();
-        module.addSerializer(NodeId.class, new NodeIdSerializer());
-        module.addDeserializer(NodeId.class, new NodeIdDeserializer());
-        module.addSerializer(ControllerNode.class, new ControllerNodeSerializer());
-        module.addDeserializer(ControllerNode.class, new ControllerNodeDeserializer());
-        module.addSerializer(Partition.class, new PartitionSerializer());
-        module.addDeserializer(Partition.class, new PartitionDeserializer());
-        module.addSerializer(PartitionId.class, new PartitionIdSerializer());
-        module.addDeserializer(PartitionId.class, new PartitionIdDeserializer());
-        mapper.registerModule(module);
         providerService = providerRegistry.register(this);
         metadataUrl = System.getProperty("onos.cluster.metadata.uri", "file://" + CONFIG_DIR + "/" + CONFIG_FILE);
         configFileChangeDetector.scheduleWithFixedDelay(() -> watchUrl(metadataUrl), 100, 500, TimeUnit.MILLISECONDS);
@@ -133,12 +108,31 @@
         }
     }
 
+    private ClusterMetadataPrototype toPrototype(ClusterMetadata metadata) {
+        ClusterMetadataPrototype prototype = new ClusterMetadataPrototype();
+        prototype.setName(metadata.getName());
+        prototype.setCluster(metadata.getNodes()
+            .stream()
+            .map(this::toPrototype)
+            .collect(Collectors.toSet()));
+        return prototype;
+    }
+
+    private NodePrototype toPrototype(Node node) {
+        NodePrototype prototype = new NodePrototype();
+        prototype.setId(node.id().id());
+        prototype.setIp(node.ip().toString());
+        prototype.setPort(node.tcpPort());
+        return prototype;
+    }
+
     @Override
     public void setClusterMetadata(ClusterMetadata metadata) {
         try {
             File configFile = new File(metadataUrl.replaceFirst("file://", ""));
             Files.createParentDirs(configFile);
-            mapper.writeValue(configFile, metadata);
+            ClusterMetadataPrototype metadataPrototype = toPrototype(metadata);
+            mapper.writeValue(configFile, metadataPrototype);
             cachedMetadata.set(fetchMetadata(metadataUrl));
             providerService.clusterMetadataChanged(new Versioned<>(metadata, configFile.lastModified()));
         } catch (IOException e) {
@@ -202,12 +196,12 @@
     private Versioned<ClusterMetadata> fetchMetadata(String metadataUrl) {
         try {
             URL url = new URL(metadataUrl);
-            ClusterMetadata metadata = null;
+            ClusterMetadataPrototype metadata = null;
             long version = 0;
             if ("file".equals(url.getProtocol())) {
                 File file = new File(metadataUrl.replaceFirst("file://", ""));
                 version = file.lastModified();
-                metadata = mapper.readValue(new FileInputStream(file), ClusterMetadata.class);
+                metadata = mapper.readValue(new FileInputStream(file), ClusterMetadataPrototype.class);
             } else if ("http".equals(url.getProtocol())) {
                 try {
                     HttpURLConnection conn = (HttpURLConnection) url.openConnection();
@@ -219,7 +213,7 @@
                         return null;
                     }
                     version = conn.getLastModified();
-                    metadata = mapper.readValue(conn.getInputStream(), ClusterMetadata.class);
+                    metadata = mapper.readValue(conn.getInputStream(), ClusterMetadataPrototype.class);
                 } catch (IOException e) {
                     log.warn("Could not reach metadata URL {}. Retrying...", url);
                     return null;
@@ -231,105 +225,35 @@
                 throw new NullPointerException();
             }
 
-            // If the configured partitions are empty then return a null metadata to indicate that the configuration
-            // needs to be polled until the partitions are populated.
-            if (metadata.getPartitions().isEmpty() || metadata.getPartitions().stream()
-                    .map(partition -> partition.getMembers().size())
-                    .reduce(Math::min)
-                    .orElse(0) == 0) {
-                return null;
-            }
-            return new Versioned<>(new ClusterMetadata(PROVIDER_ID,
-                                                       metadata.getName(),
-                                                       Sets.newHashSet(metadata.getNodes()),
-                                                       Sets.newHashSet(metadata.getPartitions())),
-                                   version);
+            return new Versioned<>(new ClusterMetadata(
+                PROVIDER_ID,
+                metadata.getName(),
+                metadata.getNode() != null ?
+                    new DefaultControllerNode(
+                        metadata.getNode().getId() != null
+                            ? NodeId.nodeId(metadata.getNode().getId())
+                            : metadata.getNode().getIp() != null
+                            ? NodeId.nodeId(IpAddress.valueOf(metadata.getNode().getIp()).toString())
+                            : NodeId.nodeId(UUID.randomUUID().toString()),
+                        metadata.getNode().getIp() != null
+                            ? IpAddress.valueOf(metadata.getNode().getIp())
+                            : null,
+                        metadata.getNode().getPort() != null
+                            ? metadata.getNode().getPort()
+                            : DefaultControllerNode.DEFAULT_PORT) : null,
+                metadata.getCluster()
+                    .stream()
+                    .map(node -> new DefaultControllerNode(
+                        NodeId.nodeId(node.getId()),
+                        IpAddress.valueOf(node.getIp()),
+                        node.getPort() != null ? node.getPort() : 5679))
+                    .collect(Collectors.toSet())),
+                version);
         } catch (IOException e) {
             throw new IllegalArgumentException(e);
         }
     }
 
-    private static class PartitionSerializer extends JsonSerializer<Partition> {
-        @Override
-        public void serialize(Partition partition, JsonGenerator jgen, SerializerProvider serializerProvider)
-                throws IOException, JsonProcessingException {
-            jgen.writeStartObject();
-            jgen.writeNumberField("id", partition.getId().asInt());
-            jgen.writeArrayFieldStart("members");
-            for (NodeId nodeId : partition.getMembers()) {
-                jgen.writeString(nodeId.id());
-            }
-            jgen.writeEndArray();
-            jgen.writeEndObject();
-        }
-    }
-
-    private static class PartitionDeserializer extends JsonDeserializer<Partition> {
-        @Override
-        public Partition deserialize(JsonParser jp, DeserializationContext ctxt)
-                throws IOException, JsonProcessingException {
-            return jp.readValueAs(DefaultPartition.class);
-        }
-    }
-
-    private static class PartitionIdSerializer extends JsonSerializer<PartitionId> {
-        @Override
-        public void serialize(PartitionId partitionId, JsonGenerator jgen, SerializerProvider provider)
-          throws IOException, JsonProcessingException {
-            jgen.writeNumber(partitionId.asInt());
-        }
-    }
-
-    private class PartitionIdDeserializer extends JsonDeserializer<PartitionId> {
-        @Override
-        public PartitionId deserialize(JsonParser jp, DeserializationContext ctxt)
-          throws IOException, JsonProcessingException {
-            JsonNode node = jp.getCodec().readTree(jp);
-            return new PartitionId(node.asInt());
-        }
-    }
-
-    private static class ControllerNodeSerializer extends JsonSerializer<ControllerNode> {
-        @Override
-        public void serialize(ControllerNode node, JsonGenerator jgen, SerializerProvider provider)
-          throws IOException, JsonProcessingException {
-            jgen.writeStartObject();
-            jgen.writeStringField(ID, node.id().toString());
-            jgen.writeStringField(IP, node.ip().toString());
-            jgen.writeNumberField(PORT, node.tcpPort());
-            jgen.writeEndObject();
-        }
-    }
-
-    private static class ControllerNodeDeserializer extends JsonDeserializer<ControllerNode> {
-        @Override
-        public ControllerNode deserialize(JsonParser jp, DeserializationContext ctxt)
-                throws IOException, JsonProcessingException {
-            JsonNode node = jp.getCodec().readTree(jp);
-            NodeId nodeId = new NodeId(node.get(ID).textValue());
-            IpAddress ip = IpAddress.valueOf(node.get(IP).textValue());
-            int port = node.get(PORT).asInt();
-            return new DefaultControllerNode(nodeId, ip, port);
-        }
-    }
-
-    private static class NodeIdSerializer extends JsonSerializer<NodeId> {
-        @Override
-        public void serialize(NodeId nodeId, JsonGenerator jgen, SerializerProvider provider)
-          throws IOException, JsonProcessingException {
-            jgen.writeString(nodeId.toString());
-        }
-    }
-
-    private class NodeIdDeserializer extends JsonDeserializer<NodeId> {
-        @Override
-        public NodeId deserialize(JsonParser jp, DeserializationContext ctxt)
-          throws IOException, JsonProcessingException {
-            JsonNode node = jp.getCodec().readTree(jp);
-            return new NodeId(node.asText());
-        }
-    }
-
     /**
      * Monitors the metadata url for any updates and notifies providerService accordingly.
      */
@@ -350,4 +274,64 @@
             log.error("Unable to parse metadata : ", e);
         }
     }
+
+    private static class ClusterMetadataPrototype {
+        private String name;
+        private NodePrototype node;
+        private Set<NodePrototype> cluster;
+
+        public String getName() {
+            return name;
+        }
+
+        public void setName(String name) {
+            this.name = name;
+        }
+
+        public NodePrototype getNode() {
+            return node;
+        }
+
+        public void setNode(NodePrototype node) {
+            this.node = node;
+        }
+
+        public Set<NodePrototype> getCluster() {
+            return cluster;
+        }
+
+        public void setCluster(Set<NodePrototype> cluster) {
+            this.cluster = cluster;
+        }
+    }
+
+    private static class NodePrototype {
+        private String id;
+        private String ip;
+        private Integer port;
+
+        public String getId() {
+            return id;
+        }
+
+        public void setId(String id) {
+            this.id = id;
+        }
+
+        public String getIp() {
+            return ip;
+        }
+
+        public void setIp(String ip) {
+            this.ip = ip;
+        }
+
+        public Integer getPort() {
+            return port;
+        }
+
+        public void setPort(Integer port) {
+            this.port = port;
+        }
+    }
 }
\ No newline at end of file
diff --git a/core/net/src/main/java/org/onosproject/cluster/impl/DefaultClusterMetadataProvider.java b/core/net/src/main/java/org/onosproject/cluster/impl/DefaultClusterMetadataProvider.java
index 83fe78b..aa32da2 100644
--- a/core/net/src/main/java/org/onosproject/cluster/impl/DefaultClusterMetadataProvider.java
+++ b/core/net/src/main/java/org/onosproject/cluster/impl/DefaultClusterMetadataProvider.java
@@ -15,9 +15,6 @@
  */
 package org.onosproject.cluster.impl;
 
-import static java.net.NetworkInterface.getNetworkInterfaces;
-import static org.slf4j.LoggerFactory.getLogger;
-
 import java.net.Inet4Address;
 import java.net.InetAddress;
 import java.net.NetworkInterface;
@@ -26,6 +23,7 @@
 import java.util.concurrent.atomic.AtomicReference;
 import java.util.function.Function;
 
+import com.google.common.collect.ImmutableSet;
 import org.apache.felix.scr.annotations.Activate;
 import org.apache.felix.scr.annotations.Component;
 import org.apache.felix.scr.annotations.Deactivate;
@@ -37,16 +35,15 @@
 import org.onosproject.cluster.ClusterMetadataProviderRegistry;
 import org.onosproject.cluster.ControllerNode;
 import org.onosproject.cluster.DefaultControllerNode;
-import org.onosproject.cluster.DefaultPartition;
 import org.onosproject.cluster.NodeId;
-import org.onosproject.cluster.Partition;
 import org.onosproject.cluster.PartitionId;
 import org.onosproject.core.VersionService;
 import org.onosproject.net.provider.ProviderId;
 import org.onosproject.store.service.Versioned;
 import org.slf4j.Logger;
 
-import com.google.common.collect.ImmutableSet;
+import static java.net.NetworkInterface.getNetworkInterfaces;
+import static org.slf4j.LoggerFactory.getLogger;
 
 /**
  * Provider of default {@link ClusterMetadata cluster metadata}.
@@ -75,15 +72,8 @@
         String localIp = getSiteLocalAddress();
         ControllerNode localNode =
                 new DefaultControllerNode(new NodeId(localIp), IpAddress.valueOf(localIp), DEFAULT_ONOS_PORT);
-        // partition 1
-        Partition partition = new DefaultPartition(
-                PartitionId.from(1),
-                versionService.version(),
-                ImmutableSet.of(localNode.id()));
-        ClusterMetadata metadata = new ClusterMetadata(PROVIDER_ID,
-                                        "default",
-                                        ImmutableSet.of(localNode),
-                                        ImmutableSet.of(partition));
+        ClusterMetadata metadata = new ClusterMetadata(
+            PROVIDER_ID, "default", localNode, ImmutableSet.of());
         long version = System.currentTimeMillis();
         cachedMetadata.set(new Versioned<>(metadata, version));
         providerRegistry.register(this);