Interface counter sample packet

Change-Id: Ic74e1fd5e889c5dd4f58367f8cb6df606834df7e
diff --git a/apps/ipflow-monitor/sflow/api/src/main/java/org/onosproject/sflow/CounterSample.java b/apps/ipflow-monitor/sflow/api/src/main/java/org/onosproject/sflow/CounterSample.java
index f1eddfb..502646f 100644
--- a/apps/ipflow-monitor/sflow/api/src/main/java/org/onosproject/sflow/CounterSample.java
+++ b/apps/ipflow-monitor/sflow/api/src/main/java/org/onosproject/sflow/CounterSample.java
@@ -15,9 +15,16 @@
  */
 package org.onosproject.sflow;
 
-import java.util.List;
 import org.onlab.packet.Deserializer;
 
+import java.util.LinkedList;
+import java.util.List;
+import java.util.Objects;
+
+import com.google.common.base.MoreObjects;
+
+import static com.google.common.base.Preconditions.checkState;
+
 /**
  * the sFlow Agent keep a list of counter sources being sampled.
  * When a flow sample is generated the
@@ -55,6 +62,25 @@
 
     private List<Object> records;
 
+    private CounterSample(Builder builder) {
+        this.enterprise = builder.enterprise;
+        this.type = builder.type;
+        this.length = builder.length;
+        this.sequenceNumber = builder.sequenceNumber;
+        this.sourceId = builder.sourceId;
+        this.sourceIndex = builder.sourceIndex;
+        this.numberOfRecords = builder.numberOfRecords;
+        this.records = builder.records;
+    }
+
+    /**
+     * Get sFlow counter records.
+     *
+     * @return counter records.
+     */
+    public List<Object> getRecords() {
+        return records;
+    }
 
     /**
      * Data deserializer function for flow interface counter.
@@ -67,4 +93,204 @@
         };
     }
 
-}
+    @Override
+    public int hashCode() {
+        int hash = 3;
+        hash = 59 * hash + Objects.hashCode(this.type);
+        hash = 59 * hash + this.length;
+        hash = 59 * hash + this.sequenceNumber;
+        hash = 59 * hash + this.sourceId;
+        hash = 59 * hash + this.numberOfRecords;
+        hash = 59 * hash + Objects.hashCode(this.records);
+        return hash;
+    }
+
+    @Override
+    public boolean equals(Object obj) {
+        if (this == obj) {
+            return true;
+        }
+        if (obj == null) {
+            return false;
+        }
+        if (getClass() != obj.getClass()) {
+            return false;
+        }
+        final CounterSample other = (CounterSample) obj;
+        if (this.type != other.type) {
+            return false;
+        }
+        if (this.length != other.length) {
+            return false;
+        }
+        if (this.sequenceNumber != other.sequenceNumber) {
+            return false;
+        }
+        if (this.sourceId != other.sourceId) {
+            return false;
+        }
+        if (this.sourceIndex != other.sourceIndex) {
+            return false;
+        }
+        if (this.numberOfRecords != other.numberOfRecords) {
+            return false;
+        }
+        return Objects.equals(this.records, other.records);
+    }
+
+    @Override
+    public String toString() {
+        return MoreObjects.toStringHelper(getClass())
+                .add("enterprise", enterprise)
+                .add("type", type)
+                .add("length", length)
+                .add("sequenceNumber", sequenceNumber)
+                .add("sourceId", sourceId)
+                .add("sourceIndex", sourceIndex)
+                .add("numberOfRecords", numberOfRecords)
+                .add("records", records)
+                .toString();
+    }
+
+    /**
+     * Builder for sFlow counter sample packet.
+     */
+    private static class Builder {
+
+        private int enterprise;
+
+        private SflowSample.Type type;
+
+        private int length;
+
+        private int sequenceNumber;
+
+        private int sourceId;
+
+        private int sourceIndex;
+
+        private int numberOfRecords;
+
+        private List<Object> records = new LinkedList<>();
+
+        /**
+         * Setter sFlow enterprise id.
+         *
+         * @param enterprise sFlow enterprise id.
+         * @return this class builder.
+         */
+        public Builder enterprise(int enterprise) {
+            this.enterprise = enterprise;
+            return this;
+        }
+
+        /**
+         * Setter sFlow sample length.
+         *
+         * @param length sample length.
+         * @return this class builder.
+         */
+        public Builder length(int length) {
+            this.length = length;
+            return this;
+        }
+
+        /**
+         * Setter sFlow sample type.
+         *
+         * @param type sFlow sample type.
+         * @return this class builder.
+         */
+        public Builder type(SflowSample.Type type) {
+            this.type = type;
+            return this;
+        }
+
+        /**
+         * Setter sFlow flow packet sequence number.
+         *
+         * @param sequenceNumber flow packet sequence number.
+         * @return this class builder.
+         */
+        public Builder sequenceNumber(int sequenceNumber) {
+            this.sequenceNumber = sequenceNumber;
+            return this;
+        }
+
+        /**
+         * Setter sFlow agent source index.
+         *
+         * @param sourceIndex agent source index.
+         * @return this class builder.
+         */
+        public Builder sourceIndex(int sourceIndex) {
+            this.sourceIndex = sourceIndex;
+            return this;
+        }
+
+        /**
+         * Setter sFlow agent source id.
+         *
+         * @param sourceId agent source id.
+         * @return this class builder.
+         */
+        public Builder sourceId(int sourceId) {
+            this.sourceId = sourceId;
+            return this;
+        }
+
+        /**
+         * Setter sFlow flow packet record count.
+         *
+         * @param numberOfRecords flow packet record count.
+         * @return this class builder.
+         */
+        public Builder numberOfRecords(int numberOfRecords) {
+            this.numberOfRecords = numberOfRecords;
+            return this;
+        }
+
+        /**
+         * Setter sFlow interface counter records.
+         *
+         * @param records interface counter records.
+         * @return this class builder.
+         */
+        public Builder records(List<Object> records) {
+            this.records = records;
+            return this;
+        }
+
+        /**
+         * Setter sFlow sample interface counter record.
+         *
+         * @param record sample interface counter record.
+         * @return this class builder.
+         */
+        public Builder record(Object record) {
+            this.records.add(record);
+            return this;
+        }
+
+        /**
+         * Checks arguments for sFlow sample interface counter.
+         */
+        private void checkArguments() {
+            checkState(type != null, "Invalid sample type.");
+            checkState(sourceId != 0, "Invalid source id.");
+            checkState(sequenceNumber != 0, "Invalid sequence number.");
+            checkState(numberOfRecords != 0, "Invalid number of records.");
+            checkState(records.size() != 0, "Interface counter record is empty.");
+        }
+
+        /**
+         * Builds sFlow interface counter sample.
+         *
+         * @return interface counter sample.
+         */
+        public CounterSample build() {
+            checkArguments();
+            return new CounterSample(this);
+        }
+    }
+}
\ No newline at end of file
diff --git a/apps/ipflow-monitor/sflow/api/src/main/java/org/onosproject/sflow/FlowSample.java b/apps/ipflow-monitor/sflow/api/src/main/java/org/onosproject/sflow/FlowSample.java
index 73dff7b..323726e 100644
--- a/apps/ipflow-monitor/sflow/api/src/main/java/org/onosproject/sflow/FlowSample.java
+++ b/apps/ipflow-monitor/sflow/api/src/main/java/org/onosproject/sflow/FlowSample.java
@@ -23,6 +23,8 @@
 
 import com.google.common.base.MoreObjects;
 
+import static com.google.common.base.Preconditions.checkState;
+
 /**
  * A sample involves either copying the packet's header, or
  * extracting features from the packet (see sFlow Datagram Format for a
@@ -82,6 +84,95 @@
 
     private List<Object> records;
 
+    private FlowSample(Builder builder) {
+        this.enterprise = builder.enterprise;
+        this.type = builder.type;
+        this.length = builder.length;
+        this.sequenceNumber = builder.sequenceNumber;
+        this.sourceId = builder.sourceId;
+        this.sourceIndex = builder.sourceIndex;
+        this.numberOfRecords = builder.numberOfRecords;
+        this.samplingRate = builder.samplingRate;
+        this.samplePool = builder.samplePool;
+        this.drops = builder.drops;
+        this.inputInterfaceId = builder.inputInterfaceId;
+        this.inputInterfaceValue = builder.inputInterfaceValue;
+        this.outputInterfaceId = builder.outputInterfaceId;
+        this.outputInterfaceValue = builder.outputInterfaceValue;
+        this.records = builder.records;
+    }
+
+    /**
+     * Get sFlow flow sampling rate.
+     *
+     * @return flow sampling rate.
+     */
+    public int getSamplingRate() {
+        return samplingRate;
+    }
+
+    /**
+     * Get sFlow sample pool.
+     *
+     * @return flow sample pool.
+     */
+    public int getSamplePool() {
+        return samplePool;
+    }
+
+    /**
+     * Get sFlow packet drop.
+     *
+     * @return packet drop.
+     */
+    public int getDrops() {
+        return drops;
+    }
+
+    /**
+     * Get sFlow packet ingress interface id.
+     *
+     * @return packet ingress interface id.
+     */
+    public int getInputInterfaceId() {
+        return inputInterfaceId;
+    }
+
+    /**
+     * Get sFlow packet ingress interface value.
+     *
+     * @return packet ingress interface value.
+     */
+    public int getInputInterfaceValue() {
+        return inputInterfaceValue;
+    }
+
+    /**
+     * Get sFlow packet egress interface id.
+     *
+     * @return packet egress interface id.
+     */
+    public int getOutputInterfaceId() {
+        return outputInterfaceId;
+    }
+
+    /**
+     * Get sFlow packet egress interface value.
+     *
+     * @return packet egress interface value.
+     */
+    public int getOutputInterfaceValue() {
+        return outputInterfaceValue;
+    }
+
+    /**
+     * Get sFlow flow records.
+     *
+     * @return flow records.
+     */
+    public List<Object> getRecords() {
+        return records;
+    }
 
     /**
      * Data deserializer function for flow sample data.
@@ -180,7 +271,7 @@
     }
 
     /**
-     * Builder for sFlow packet.
+     * Builder for sFlow flow sample.
      */
     private static class Builder {
 
@@ -390,6 +481,28 @@
             return this;
         }
 
+        /**
+         * Checks arguments for sFlow sample flow.
+         */
+        private void checkArguments() {
+            checkState(type != null, "Invalid sample type.");
+            checkState(sourceId != 0, "Invalid source id.");
+            checkState(sequenceNumber != 0, "Invalid sequence number.");
+            checkState(numberOfRecords != 0, "Invalid number of records.");
+            checkState(samplingRate != 0, "Invalid sample rate.");
+            checkState(inputInterfaceId != 0, "Invalid ingress interface id.");
+            checkState(outputInterfaceId != 0, "Invalid egress interface id.");
+            checkState(records.size() != 0, "Sample record is empty.");
+        }
 
+        /**
+         * Builds sFlow sample flow.
+         *
+         * @return flowsample.
+         */
+        public FlowSample build() {
+            checkArguments();
+            return new FlowSample(this);
+        }
     }
 }
\ No newline at end of file