[ONOS-7683] Add FlowInfo and StatsInfo impls with unit tests

Change-Id: I86327507c528a9b7eea60af858ccfb1fb4b2f8ce
diff --git a/apps/openstacktelemetry/app/src/main/java/org/onosproject/openstacktelemetry/impl/DefaultFlowInfo.java b/apps/openstacktelemetry/app/src/main/java/org/onosproject/openstacktelemetry/impl/DefaultFlowInfo.java
new file mode 100644
index 0000000..b7a9545
--- /dev/null
+++ b/apps/openstacktelemetry/app/src/main/java/org/onosproject/openstacktelemetry/impl/DefaultFlowInfo.java
@@ -0,0 +1,313 @@
+/*
+ * 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.openstacktelemetry.impl;
+
+import org.onlab.packet.IpPrefix;
+import org.onlab.packet.MacAddress;
+import org.onlab.packet.VlanId;
+import org.onosproject.net.DeviceId;
+import org.onosproject.net.PortNumber;
+import org.onosproject.openstacktelemetry.api.FlowInfo;
+import org.onosproject.openstacktelemetry.api.StatsInfo;
+
+import java.util.Objects;
+
+import static com.google.common.base.MoreObjects.toStringHelper;
+import static com.google.common.base.Preconditions.checkNotNull;
+
+/**
+ * Implementation class of FlowInfo.
+ */
+public final class DefaultFlowInfo implements FlowInfo {
+
+    private final byte flowType;
+    private final DeviceId deviceId;
+    private final int inputInterfaceId;
+    private final int outputInterfaceId;
+    private final VlanId vlanId;
+    private final short vxlanId;
+    private final IpPrefix srcIp;
+    private final IpPrefix dstIp;
+    private final PortNumber srcPort;
+    private final PortNumber dstPort;
+    private final byte protocol;
+    private final MacAddress srcMac;
+    private final MacAddress dstMac;
+    private final StatsInfo statsInfo;
+
+    private DefaultFlowInfo(byte flowType, DeviceId deviceId,
+                            int inputInterfaceId, int outputInterfaceId,
+                            VlanId vlanId, short vxlanId, IpPrefix srcIp,
+                            IpPrefix dstIp, PortNumber srcPort, PortNumber dstPort,
+                            byte protocol, MacAddress srcMac, MacAddress dstMac,
+                            StatsInfo statsInfo) {
+        this.flowType = flowType;
+        this.deviceId = deviceId;
+        this.inputInterfaceId = inputInterfaceId;
+        this.outputInterfaceId = outputInterfaceId;
+        this.vlanId = vlanId;
+        this.vxlanId = vxlanId;
+        this.srcIp = srcIp;
+        this.dstIp = dstIp;
+        this.srcPort = srcPort;
+        this.dstPort = dstPort;
+        this.protocol = protocol;
+        this.srcMac = srcMac;
+        this.dstMac = dstMac;
+        this.statsInfo = statsInfo;
+    }
+
+    @Override
+    public byte flowType() {
+        return flowType;
+    }
+
+    @Override
+    public DeviceId deviceId() {
+        return deviceId;
+    }
+
+    @Override
+    public int inputInterfaceId() {
+        return inputInterfaceId;
+    }
+
+    @Override
+    public int outputInterfaceId() {
+        return outputInterfaceId;
+    }
+
+    @Override
+    public VlanId vlanId() {
+        return vlanId;
+    }
+
+    @Override
+    public short vxlanId() {
+        return vxlanId;
+    }
+
+    @Override
+    public IpPrefix srcIp() {
+        return srcIp;
+    }
+
+    @Override
+    public IpPrefix dstIp() {
+        return dstIp;
+    }
+
+    @Override
+    public PortNumber srcPort() {
+        return srcPort;
+    }
+
+    @Override
+    public PortNumber dstPort() {
+        return dstPort;
+    }
+
+    @Override
+    public byte protocol() {
+        return protocol;
+    }
+
+    @Override
+    public MacAddress srcMac() {
+        return srcMac;
+    }
+
+    @Override
+    public MacAddress dstMac() {
+        return dstMac;
+    }
+
+    @Override
+    public StatsInfo statsInfo() {
+        return statsInfo;
+    }
+
+    @Override
+    public boolean equals(Object obj) {
+        if (this == obj) {
+            return true;
+        }
+
+        if (obj instanceof DefaultFlowInfo) {
+            final DefaultFlowInfo other = (DefaultFlowInfo) obj;
+            return Objects.equals(this.flowType, other.flowType) &&
+                    Objects.equals(this.deviceId, other.deviceId) &&
+                    Objects.equals(this.inputInterfaceId, other.inputInterfaceId) &&
+                    Objects.equals(this.outputInterfaceId, other.outputInterfaceId) &&
+                    Objects.equals(this.vlanId, other.vlanId) &&
+                    Objects.equals(this.vxlanId, other.vxlanId) &&
+                    Objects.equals(this.srcIp, other.srcIp) &&
+                    Objects.equals(this.dstIp, other.dstIp) &&
+                    Objects.equals(this.srcPort, other.srcPort) &&
+                    Objects.equals(this.dstPort, other.dstPort) &&
+                    Objects.equals(this.protocol, other.protocol) &&
+                    Objects.equals(this.srcMac, other.srcMac) &&
+                    Objects.equals(this.dstMac, other.dstMac) &&
+                    Objects.equals(this.statsInfo, other.statsInfo);
+        }
+        return false;
+    }
+
+    @Override
+    public int hashCode() {
+        return Objects.hash(flowType, deviceId, inputInterfaceId,
+                outputInterfaceId, vlanId, vxlanId, srcIp, dstIp, srcPort, dstPort,
+                protocol, srcMac, dstMac, statsInfo);
+    }
+
+    @Override
+    public String toString() {
+        return toStringHelper(this)
+                .add("flowType", flowType)
+                .add("deviceId", deviceId)
+                .add("inputInterfaceId", inputInterfaceId)
+                .add("outputInterfaceId", outputInterfaceId)
+                .add("vlanId", vlanId)
+                .add("vxlanId", vxlanId)
+                .add("srcIp", srcIp)
+                .add("dstIp", dstIp)
+                .add("srcPort", srcPort)
+                .add("dstPort", dstPort)
+                .add("protocol", protocol)
+                .add("srcMac", srcMac)
+                .add("dstMac", dstMac)
+                .add("statsInfo", statsInfo)
+                .toString();
+    }
+
+    /**
+     * Builder class of DefaultFlowInfo.
+     */
+    public static final class DefaultBuilder implements FlowInfo.Builder {
+
+        private byte flowType;
+        private DeviceId deviceId;
+        private int inputInterfaceId;
+        private int outputInterfaceId;
+        private VlanId vlanId;
+        private short vxlanId;
+        private IpPrefix srcIp;
+        private IpPrefix dstIp;
+        private PortNumber srcPort;
+        private PortNumber dstPort;
+        private byte protocol;
+        private MacAddress srcMac;
+        private MacAddress dstMac;
+        private StatsInfo statsInfo;
+
+        @Override
+        public Builder withFlowType(byte flowType) {
+            this.flowType = flowType;
+            return this;
+        }
+
+        @Override
+        public Builder withDeviceId(DeviceId deviceId) {
+            this.deviceId = deviceId;
+            return this;
+        }
+
+        @Override
+        public Builder withInputInterfaceId(int inputInterfaceId) {
+            this.inputInterfaceId = inputInterfaceId;
+            return this;
+        }
+
+        @Override
+        public Builder withOutputInterfaceId(int outputInterfaceId) {
+            this.outputInterfaceId = outputInterfaceId;
+            return this;
+        }
+
+        @Override
+        public Builder withVlanId(VlanId vlanId) {
+            this.vlanId = vlanId;
+            return this;
+        }
+
+        @Override
+        public Builder withVxlanId(short vxlanId) {
+            this.vxlanId = vxlanId;
+            return this;
+        }
+
+        @Override
+        public Builder withSrcIp(IpPrefix srcIp) {
+            this.srcIp = srcIp;
+            return this;
+        }
+
+        @Override
+        public Builder withDstIp(IpPrefix dstIp) {
+            this.dstIp = dstIp;
+            return this;
+        }
+
+        @Override
+        public Builder withSrcPort(PortNumber srcPort) {
+            this.srcPort = srcPort;
+            return this;
+        }
+
+        @Override
+        public Builder withDstPort(PortNumber dstPort) {
+            this.dstPort = dstPort;
+            return this;
+        }
+
+        @Override
+        public Builder withProtocol(byte protocol) {
+            this.protocol = protocol;
+            return this;
+        }
+
+        @Override
+        public Builder withSrcMac(MacAddress srcMac) {
+            this.srcMac = srcMac;
+            return this;
+        }
+
+        @Override
+        public Builder withDstMac(MacAddress dstMac) {
+            this.dstMac = dstMac;
+            return this;
+        }
+
+        @Override
+        public Builder withStatsInfo(StatsInfo statsInfo) {
+            this.statsInfo = statsInfo;
+            return this;
+        }
+
+        @Override
+        public FlowInfo build() {
+
+            // TODO: need to check the null value for more properties
+            checkNotNull(srcIp, "Source IP address cannot be null");
+            checkNotNull(dstIp, "Destination IP address cannot be null");
+            checkNotNull(statsInfo, "StatsInfo cannot be null");
+
+            return new DefaultFlowInfo(flowType, deviceId, inputInterfaceId,
+                    outputInterfaceId, vlanId, vxlanId, srcIp, dstIp, srcPort, dstPort,
+                    protocol, srcMac, dstMac, statsInfo);
+        }
+    }
+}
diff --git a/apps/openstacktelemetry/app/src/main/java/org/onosproject/openstacktelemetry/impl/DefaultStatsInfo.java b/apps/openstacktelemetry/app/src/main/java/org/onosproject/openstacktelemetry/impl/DefaultStatsInfo.java
new file mode 100644
index 0000000..6e085a2
--- /dev/null
+++ b/apps/openstacktelemetry/app/src/main/java/org/onosproject/openstacktelemetry/impl/DefaultStatsInfo.java
@@ -0,0 +1,217 @@
+/*
+ * 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.openstacktelemetry.impl;
+
+import org.onosproject.openstacktelemetry.api.StatsInfo;
+
+import java.util.Objects;
+
+import static com.google.common.base.MoreObjects.toStringHelper;
+
+/**
+ * Implementation class of StatsInfo.
+ */
+public final class DefaultStatsInfo implements StatsInfo {
+
+    private final long startupTime;
+    private final long fstPktArrTime;
+    private final int lstPktOffset;
+    private final long prevAccBytes;
+    private final int prevAccPkts;
+    private final long currAccBytes;
+    private final int currAccPkts;
+    private final short errorPkts;
+    private final short dropPkts;
+
+    private DefaultStatsInfo(long startupTime, long fstPktArrTime, int lstPktOffset,
+                             long prevAccBytes, int prevAccPkts, long currAccBytes,
+                             int currAccPkts, short errorPkts, short dropPkts) {
+        this.startupTime = startupTime;
+        this.fstPktArrTime = fstPktArrTime;
+        this.lstPktOffset = lstPktOffset;
+        this.prevAccBytes = prevAccBytes;
+        this.prevAccPkts = prevAccPkts;
+        this.currAccBytes = currAccBytes;
+        this.currAccPkts = currAccPkts;
+        this.errorPkts = errorPkts;
+        this.dropPkts = dropPkts;
+    }
+
+    @Override
+    public long startupTime() {
+        return startupTime;
+    }
+
+    @Override
+    public long fstPktArrTime() {
+        return fstPktArrTime;
+    }
+
+    @Override
+    public int lstPktOffset() {
+        return lstPktOffset;
+    }
+
+    @Override
+    public long prevAccBytes() {
+        return prevAccBytes;
+    }
+
+    @Override
+    public int prevAccPkts() {
+        return prevAccPkts;
+    }
+
+    @Override
+    public long currAccBytes() {
+        return currAccBytes;
+    }
+
+    @Override
+    public int currAccPkts() {
+        return currAccPkts;
+    }
+
+    @Override
+    public short errorPkts() {
+        return errorPkts;
+    }
+
+    @Override
+    public short dropPkts() {
+        return dropPkts;
+    }
+
+    @Override
+    public boolean equals(Object obj) {
+        if (this == obj) {
+            return true;
+        }
+
+        if (obj instanceof DefaultStatsInfo) {
+            final DefaultStatsInfo other = (DefaultStatsInfo) obj;
+            return Objects.equals(this.startupTime, other.startupTime) &&
+                    Objects.equals(this.fstPktArrTime, other.fstPktArrTime) &&
+                    Objects.equals(this.lstPktOffset, other.lstPktOffset) &&
+                    Objects.equals(this.prevAccBytes, other.prevAccBytes) &&
+                    Objects.equals(this.prevAccPkts, other.prevAccPkts) &&
+                    Objects.equals(this.currAccBytes, other.currAccBytes) &&
+                    Objects.equals(this.currAccPkts, other.currAccPkts) &&
+                    Objects.equals(this.errorPkts, other.errorPkts) &&
+                    Objects.equals(this.dropPkts, other.dropPkts);
+        }
+        return false;
+    }
+
+    @Override
+    public int hashCode() {
+        return Objects.hash(startupTime, fstPktArrTime, lstPktOffset,
+                prevAccBytes, prevAccPkts, currAccBytes, currAccPkts,
+                errorPkts, dropPkts);
+    }
+
+    @Override
+    public String toString() {
+        return toStringHelper(this)
+                .add("startupTime", startupTime)
+                .add("fstPktArrTime", fstPktArrTime)
+                .add("lstPktOffset", lstPktOffset)
+                .add("prevAccBytes", prevAccBytes)
+                .add("prevAccPkts", prevAccPkts)
+                .add("currAccBytes", currAccBytes)
+                .add("currAccPkts", currAccPkts)
+                .add("errorPkts", errorPkts)
+                .add("dropPkts", dropPkts)
+                .toString();
+    }
+
+    /**
+     * Builder class of DefaultStatsInfo.
+     */
+    public static final class DefaultBuilder implements StatsInfo.Builder {
+        private long startupTime;
+        private long fstPktArrTime;
+        private int lstPktOffset;
+        private long prevAccBytes;
+        private int prevAccPkts;
+        private long currAccBytes;
+        private int currAccPkts;
+        private short errorPkts;
+        private short dropPkts;
+
+        @Override
+        public Builder withStartupTime(long startupTime) {
+            this.startupTime = startupTime;
+            return this;
+        }
+
+        @Override
+        public Builder withFstPktArrTime(long fstPktArrTime) {
+            this.fstPktArrTime = fstPktArrTime;
+            return this;
+        }
+
+        @Override
+        public Builder withLstPktOffset(int lstPktOffset) {
+            this.lstPktOffset = lstPktOffset;
+            return this;
+        }
+
+        @Override
+        public Builder withPrevAccBytes(long prevAccBytes) {
+            this.prevAccBytes = prevAccBytes;
+            return this;
+        }
+
+        @Override
+        public Builder withPrevAccPkts(int prevAccPkts) {
+            this.prevAccPkts = prevAccPkts;
+            return this;
+        }
+
+        @Override
+        public Builder withCurrAccBytes(long currAccBytes) {
+            this.currAccBytes = currAccBytes;
+            return this;
+        }
+
+        @Override
+        public Builder withCurrAccPkts(int currAccPkts) {
+            this.currAccPkts = currAccPkts;
+            return this;
+        }
+
+        @Override
+        public Builder withErrorPkts(short errorPkts) {
+            this.errorPkts = errorPkts;
+            return this;
+        }
+
+        @Override
+        public Builder withDropPkts(short dropPkts) {
+            this.dropPkts = dropPkts;
+            return this;
+        }
+
+        @Override
+        public StatsInfo build() {
+
+            return new DefaultStatsInfo(startupTime, fstPktArrTime, lstPktOffset,
+                    prevAccBytes, prevAccPkts, currAccBytes, currAccPkts,
+                    errorPkts, dropPkts);
+        }
+    }
+}