Add distributed persistent store and manager for instance port

Change-Id: I9a4ba11a3e0fb494aedf9cb35c2e9a7a7bcbf5c7
diff --git a/apps/openstacknetworking/app/src/main/java/org/onosproject/openstacknetworking/impl/DefaultInstancePort.java b/apps/openstacknetworking/app/src/main/java/org/onosproject/openstacknetworking/impl/DefaultInstancePort.java
new file mode 100644
index 0000000..b1addf0
--- /dev/null
+++ b/apps/openstacknetworking/app/src/main/java/org/onosproject/openstacknetworking/impl/DefaultInstancePort.java
@@ -0,0 +1,258 @@
+/*
+ * Copyright 2018-present Open Networking Foundation
+ *
+ * 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.openstacknetworking.impl;
+
+import com.google.common.base.MoreObjects;
+import com.google.common.base.Strings;
+import org.onlab.packet.IpAddress;
+import org.onlab.packet.MacAddress;
+import org.onosproject.net.DeviceId;
+import org.onosproject.net.Host;
+import org.onosproject.net.PortNumber;
+import org.onosproject.openstacknetworking.api.InstancePort;
+
+import java.util.Objects;
+
+import static com.google.common.base.Preconditions.checkArgument;
+import static com.google.common.base.Preconditions.checkNotNull;
+
+/**
+ * Default implementation of instance port.
+ */
+public final class DefaultInstancePort implements InstancePort {
+
+    private static final String ANNOTATION_NETWORK_ID = "networkId";
+    private static final String ANNOTATION_PORT_ID = "portId";
+    private static final String ANNOTATION_CREATE_TIME = "createTime";
+
+    private static final String NOT_NULL_MSG = "Instance Port % cannot be null";
+
+    private final String networkId;
+    private final String portId;
+    private final MacAddress macAddress;
+    private final IpAddress ipAddress;
+    private final DeviceId deviceId;
+    private final PortNumber portNumber;
+    private final State state;
+
+    // private constructor not intended for invoked from external
+    private DefaultInstancePort(String networkId, String portId,
+                                MacAddress macAddress, IpAddress ipAddress,
+                                DeviceId deviceId, PortNumber portNumber,
+                                State state) {
+        this.networkId = networkId;
+        this.portId = portId;
+        this.macAddress = macAddress;
+        this.ipAddress = ipAddress;
+        this.deviceId = deviceId;
+        this.portNumber = portNumber;
+        this.state = state;
+    }
+
+    private DefaultInstancePort(Host host, State state) {
+        this.networkId = host.annotations().value(ANNOTATION_NETWORK_ID);
+        this.portId = host.annotations().value(ANNOTATION_PORT_ID);
+        this.macAddress = host.mac();
+
+        this.ipAddress = host.ipAddresses().stream().findFirst().orElse(null);
+
+        this.deviceId = host.location().deviceId();
+        this.portNumber = host.location().port();
+        this.state = state;
+    }
+
+    public static DefaultInstancePort from(Host host, State state) {
+        checkNotNull(host);
+        checkArgument(!Strings.isNullOrEmpty(
+                                host.annotations().value(ANNOTATION_NETWORK_ID)));
+        checkArgument(!Strings.isNullOrEmpty(
+                                host.annotations().value(ANNOTATION_PORT_ID)));
+        checkArgument(!Strings.isNullOrEmpty(
+                                host.annotations().value(ANNOTATION_CREATE_TIME)));
+
+        return new DefaultInstancePort(host, state);
+    }
+
+    @Override
+    public String networkId() {
+        return networkId;
+    }
+
+    @Override
+    public String portId() {
+        return portId;
+    }
+
+    @Override
+    public MacAddress macAddress() {
+        return macAddress;
+    }
+
+    @Override
+    public IpAddress ipAddress() {
+        return ipAddress;
+    }
+
+    @Override
+    public DeviceId deviceId() {
+        return deviceId;
+    }
+
+    @Override
+    public PortNumber portNumber() {
+        return portNumber;
+    }
+
+    @Override
+    public State state() {
+        return state;
+    }
+
+    @Override
+    public InstancePort updateState(State newState) {
+        return new Builder()
+                .networkId(networkId)
+                .portId(portId)
+                .macAddress(macAddress)
+                .ipAddress(ipAddress)
+                .deviceId(deviceId)
+                .portNumber(portNumber)
+                .state(newState)
+                .build();
+    }
+
+    @Override
+    public String toString() {
+        return MoreObjects.toStringHelper(getClass())
+                .add("networkId", networkId)
+                .add("portId", portId)
+                .add("macAddress", macAddress)
+                .add("ipAddress", ipAddress)
+                .add("deviceId", deviceId)
+                .add("portNumber", portNumber)
+                .add("state", state)
+                .toString();
+    }
+
+    @Override
+    public boolean equals(Object obj) {
+        if (this == obj) {
+            return true;
+        }
+        if (obj instanceof DefaultInstancePort) {
+            DefaultInstancePort that = (DefaultInstancePort) obj;
+            return Objects.equals(networkId, that.networkId) &&
+                    Objects.equals(portId, that.portId) &&
+                    Objects.equals(macAddress, that.macAddress) &&
+                    Objects.equals(ipAddress, that.ipAddress) &&
+                    Objects.equals(deviceId, that.deviceId) &&
+                    Objects.equals(portNumber, that.portNumber) &&
+                    Objects.equals(state, that.state);
+        }
+        return false;
+    }
+
+    @Override
+    public int hashCode() {
+        return Objects.hash(networkId,
+                portId,
+                macAddress,
+                ipAddress,
+                deviceId,
+                portNumber,
+                state);
+    }
+
+    /**
+     * A builder class for instance port.
+     */
+    public static final class Builder implements InstancePort.Builder {
+
+        private String networkId;
+        private String portId;
+        private MacAddress macAddress;
+        private IpAddress ipAddress;
+        private DeviceId deviceId;
+        private PortNumber portNumber;
+        private State state;
+
+        // private constructor not intended to use from external
+        private Builder() {
+        }
+
+        @Override
+        public InstancePort build() {
+
+            checkArgument(networkId != null, NOT_NULL_MSG, "networkId");
+            checkArgument(portId != null, NOT_NULL_MSG, "portId");
+            checkArgument(macAddress != null, NOT_NULL_MSG, "macAddress");
+            checkArgument(ipAddress != null, NOT_NULL_MSG, "ipAddress");
+            checkArgument(deviceId != null, NOT_NULL_MSG, "deviceId");
+            checkArgument(portNumber != null, NOT_NULL_MSG, "portNumber");
+            checkArgument(state != null, NOT_NULL_MSG, "state");
+
+            return new DefaultInstancePort(networkId,
+                    portId,
+                    macAddress,
+                    ipAddress,
+                    deviceId,
+                    portNumber,
+                    state);
+        }
+
+        @Override
+        public InstancePort.Builder networkId(String networkId) {
+            this.networkId = networkId;
+            return this;
+        }
+
+        @Override
+        public InstancePort.Builder portId(String portId) {
+            this.portId = portId;
+            return this;
+        }
+
+        @Override
+        public InstancePort.Builder macAddress(MacAddress macAddress) {
+            this.macAddress = macAddress;
+            return this;
+        }
+
+        @Override
+        public InstancePort.Builder ipAddress(IpAddress ipAddress) {
+            this.ipAddress = ipAddress;
+            return this;
+        }
+
+        @Override
+        public InstancePort.Builder deviceId(DeviceId deviceId) {
+            this.deviceId = deviceId;
+            return this;
+        }
+
+        @Override
+        public InstancePort.Builder portNumber(PortNumber portNumber) {
+            this.portNumber = portNumber;
+            return this;
+        }
+
+        @Override
+        public InstancePort.Builder state(State state) {
+            this.state = state;
+            return this;
+        }
+    }
+}