Add skeleton codes of sFlow sample records

Change-Id: Ifa661bcd9ac917184dc3ce6dc12b4a07abb67c99
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
new file mode 100644
index 0000000..f1eddfb
--- /dev/null
+++ b/apps/ipflow-monitor/sflow/api/src/main/java/org/onosproject/sflow/CounterSample.java
@@ -0,0 +1,70 @@
+/*
+ * Copyright 2024-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.sflow;
+
+import java.util.List;
+import org.onlab.packet.Deserializer;
+
+/**
+ * the sFlow Agent keep a list of counter sources being sampled.
+ * When a flow sample is generated the
+ * sFlow Agent examines the list and adds counters to the sample
+ * datagram, least recently sampled first.  Counters are only added to
+ * the datagram if the sources are within a short period,
+ * of failing to meet the required sampling interval (see
+ * sFlowCounterSamplingInterval in SFLOW MIB).  Whenever a counter
+ * source's statistics are added to a sample datagram, the time the
+ * counter source was last sampled is updated and the counter source is
+ * placed at the end of the list.  Periodically, say every second, the
+ * sFlow Agent examines the list of counter sources and sends any
+ * counters that need to be sent to meet the sampling interval
+ * requirement.
+ * Ref: https://www.ietf.org/rfc/rfc3954.txt
+ */
+public final class CounterSample extends SflowSample {
+
+    /*
+    0                   1                   2                   3
+    0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
+   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+   |                     Sequence Number                           |
+   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+   |                         Source Id                             |
+   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+   |                       Source Index                            |
+   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+   |              Total Number Of Counter Records                  |
+   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+   |                         Records                               |
+   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+    */
+
+
+    private List<Object> records;
+
+
+    /**
+     * Data deserializer function for flow interface counter.
+     *
+     * @return data deserializer function
+     */
+    public static Deserializer<CounterSample> deserializer() {
+        return (data, offset, length) -> {
+            return null;
+        };
+    }
+
+}
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
new file mode 100644
index 0000000..fbce79c
--- /dev/null
+++ b/apps/ipflow-monitor/sflow/api/src/main/java/org/onosproject/sflow/FlowSample.java
@@ -0,0 +1,93 @@
+/*
+ * Copyright 2024-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.sflow;
+
+import java.util.List;
+
+import org.onlab.packet.Deserializer;
+
+/**
+ * A sample involves either copying the packet's header, or
+ * extracting features from the packet (see sFlow Datagram Format for a
+ * description of the different forms of sample).  Every time a sample
+ * is taken, the counter Total_Samples, is incremented.  Total_Samples
+ * is a count of the number of samples generated.  Samples are sent by
+ * the sampling entity to the sFlow Agent for processing.  The sample
+ * includes the packet information, and the values of the Total_Packets
+ * and Total_Samples counters.
+ * Ref: https://www.ietf.org/rfc/rfc3954.txt
+ */
+public final class FlowSample extends SflowSample {
+
+    /*
+    0                   1                   2                   3
+    0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
+   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+   |                     Sequence Number                           |
+   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+   |                         Source Id                             |
+   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+   |                       Source Index                            |
+   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+   |                        Sampling Rate                          |
+   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+   |                          Sample Pool                          |
+   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+   |                       Packet drop counter                     |
+   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+   |                        Input Interface Id                     |
+   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+   |                 Input Interface reason (Optional)             |
+   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+   |                      Output Interface Id                      |
+   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+   |                Output Interface reason (Optional)             |
+   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+   |                 Total Number Of Flow Records                  |
+   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+   |                         Records                               |
+   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+    */
+
+    private int samplingRate;
+
+    private int samplePool;
+
+    private int drops;
+
+    private int inputInterfaceId;
+
+    private int inputInterfaceValue;
+
+    private int outputInterfaceId;
+
+    private int outputInterfaceValue;
+
+    private List<Object> records;
+
+
+    /**
+     * Data deserializer function for flow sample data.
+     *
+     * @return data deserializer function
+     */
+    public static Deserializer<FlowSample> deserializer() {
+        return (data, offset, length) -> {
+            return null;
+        };
+    }
+
+}
\ No newline at end of file
diff --git a/apps/ipflow-monitor/sflow/api/src/main/java/org/onosproject/sflow/SflowSample.java b/apps/ipflow-monitor/sflow/api/src/main/java/org/onosproject/sflow/SflowSample.java
index 041e994..a05bb6b 100644
--- a/apps/ipflow-monitor/sflow/api/src/main/java/org/onosproject/sflow/SflowSample.java
+++ b/apps/ipflow-monitor/sflow/api/src/main/java/org/onosproject/sflow/SflowSample.java
@@ -15,20 +15,142 @@
  */
 package org.onosproject.sflow;
 
+import java.util.Arrays;
+import java.util.Map;
+import java.util.Optional;
+import java.util.concurrent.ConcurrentHashMap;
+
+import org.onlab.packet.BasePacket;
+import org.onlab.packet.DeserializationException;
+import org.onlab.packet.Deserializer;
+
 /**
  * The sFlow Agent uses two forms of sampling.
  * statistical packet-based sampling of switched flows,
- * and time-based sampling of network interface statistics.
+ * and time-based sampling of network interface statistics..
  * Ref : https://datatracker.ietf.org/doc/html/rfc3176
  */
-public interface SflowSample {
+public abstract class SflowSample extends BasePacket {
+
+    private int enterprise;
+
+    private Type type;
+
+    private int length;
+
+    private int sequenceNumber;
+
+    private int sourceId;
+
+    private int sourceIndex;
+
+    private int numberOfRecords;
 
     /**
-     * Get sflow sampling type.
-     * Sflow packet sampling type.
+     * Get sFlow agent enterprise id.
      *
-     *
-     * @return sampling type number.
+     * @return agent enterprise.
      */
-    int getSampleType();
+    public int getEnterprise() {
+        return enterprise;
+    }
+
+    /**
+     * Get sFlow sample type.
+     *
+     * @return sample type.
+     */
+    public Type getType() {
+        return type;
+    }
+
+    /**
+     * Get sFlow sample length.
+     *
+     * @return sample length.
+     */
+    public int getLength() {
+        return length;
+    }
+
+    /**
+     * Get sFlow sample sequence number.
+     *
+     * @return sequence number.
+     */
+    public int getSequenceNumber() {
+        return sequenceNumber;
+    }
+
+    /**
+     * Get sFlow source id.
+     *
+     * @return source id.
+     */
+    public int getSourceId() {
+        return sourceId;
+    }
+
+    /**
+     * Get sFlow source index.
+     *
+     * @return source index.
+     */
+    public int getSourceIndex() {
+        return sourceIndex;
+    }
+
+    /**
+     * Get total number of sample records.
+     *
+     * @return total number of sample records.
+     */
+    public int getNumberOfRecords() {
+        return numberOfRecords;
+    }
+
+    /**
+     * Sample type.
+     * Samples: Flow sample, Counter sample.
+     */
+    public enum Type {
+
+        FLOW_DATA(1, FlowSample.deserializer()),
+        COUNTER_DATA(2, CounterSample.deserializer());
+
+
+        private final int sampleType;
+        private final Deserializer deserializer;
+
+        Type(int sampleType, Deserializer deserializer) {
+            this.sampleType = sampleType;
+            this.deserializer = deserializer;
+        }
+
+        private static Map<Integer, Type> parser = new ConcurrentHashMap<>();
+
+        static {
+            Arrays.stream(Type.values()).forEach(type -> parser.put(type.sampleType, type));
+        }
+
+        public static Type getType(int sampleType) throws DeserializationException {
+            if ((sampleType < 1) || (sampleType > 2)) {
+                throw new DeserializationException("Invalid sample type");
+            }
+            return Optional.of(sampleType)
+                    .filter(id -> parser.containsKey(id))
+                    .map(id -> parser.get(id))
+                    .orElse(FLOW_DATA);
+        }
+
+        public Deserializer getDecoder() {
+            return this.deserializer;
+        }
+
+    }
+
+    @Override
+    public byte[] serialize() {
+        throw new UnsupportedOperationException("Not supported yet.");
+    }
 }