[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);
+        }
+    }
+}