statistics support 81/31281/12
authorMatej Perina <matej.perina@pantheon.sk>
Mon, 11 Jan 2016 10:40:29 +0000 (11:40 +0100)
committerMatej Perina <matej.perina@pantheon.sk>
Mon, 11 Jan 2016 10:45:09 +0000 (11:45 +0100)
Change-Id: If61e5812a06f66432558830a3193308a32630e75
Signed-off-by: Matej Perina <matej.perina@pantheon.sk>
groupbasedpolicy/src/main/config/default-config.xml
groupbasedpolicy/src/main/java/org/opendaylight/controller/config/yang/config/groupbasedpolicy/StatisticsManagerImplModule.java [new file with mode: 0644]
groupbasedpolicy/src/main/java/org/opendaylight/controller/config/yang/config/groupbasedpolicy/StatisticsManagerImplModuleFactory.java [new file with mode: 0644]
groupbasedpolicy/src/main/java/org/opendaylight/groupbasedpolicy/api/StatisticsManager.java [new file with mode: 0644]
groupbasedpolicy/src/main/java/org/opendaylight/groupbasedpolicy/statistics/StatisticsManagerImpl.java [new file with mode: 0644]
groupbasedpolicy/src/main/java/org/opendaylight/groupbasedpolicy/util/IidFactory.java
groupbasedpolicy/src/main/yang/groupbasedpolicy-cfg.yang
groupbasedpolicy/src/main/yang/model/statistics-store.yang [new file with mode: 0644]
groupbasedpolicy/src/main/yang/model/statistics.yang [new file with mode: 0644]
groupbasedpolicy/src/test/java/org/opendaylight/groupbasedpolicy/statistics/StatisticManagerImplTest.java [new file with mode: 0644]

index 523043cfa386beddb2ce1b50a25e32e179342543..bf4ae2c43a5c4e72b9eb8856d0ffb81a68ebd4ae 100755 (executable)
                         <name>binding-rpc-broker</name>
                     </rpc-registry>
                 </module>
+                <module>
+                    <type xmlns:groupbasedpolicy="urn:opendaylight:params:xml:ns:yang:controller:config:groupbasedpolicy">
+                        groupbasedpolicy:statistics-manager-impl
+                    </type>
+                    <name>statistics-manager-impl</name>
+
+                    <data-broker>
+                        <type xmlns:binding="urn:opendaylight:params:xml:ns:yang:controller:md:sal:binding">binding:binding-async-data-broker</type>
+                        <name>binding-data-broker</name>
+                    </data-broker>
+                </module>
             </modules>
 
             <services xmlns="urn:opendaylight:params:xml:ns:yang:controller:config">
                         <provider>/modules/module[type='ep-renderer-augmentation-registry-impl'][name='ep-renderer-augmentation-registry']</provider>
                     </instance>
                 </service>
+                <service>
+                    <type xmlns:groupbasedpolicy="urn:opendaylight:params:xml:ns:yang:controller:config:groupbasedpolicy">
+                        groupbasedpolicy:statistics-manager
+                    </type>
+
+                    <instance>
+                        <name>statistics-manager</name>
+                        <provider>/modules/module[type='statistics-manager-impl'][name='statistics-manager-impl']</provider>
+                    </instance>
+                </service>
             </services>
         </data>
 
diff --git a/groupbasedpolicy/src/main/java/org/opendaylight/controller/config/yang/config/groupbasedpolicy/StatisticsManagerImplModule.java b/groupbasedpolicy/src/main/java/org/opendaylight/controller/config/yang/config/groupbasedpolicy/StatisticsManagerImplModule.java
new file mode 100644 (file)
index 0000000..cf09e09
--- /dev/null
@@ -0,0 +1,27 @@
+package org.opendaylight.controller.config.yang.config.groupbasedpolicy;
+
+import org.opendaylight.controller.md.sal.binding.api.DataBroker;
+import org.opendaylight.groupbasedpolicy.statistics.StatisticsManagerImpl;
+
+public class StatisticsManagerImplModule extends org.opendaylight.controller.config.yang.config.groupbasedpolicy.AbstractStatisticsManagerImplModule {
+    public StatisticsManagerImplModule(org.opendaylight.controller.config.api.ModuleIdentifier identifier, org.opendaylight.controller.config.api.DependencyResolver dependencyResolver) {
+        super(identifier, dependencyResolver);
+    }
+
+    public StatisticsManagerImplModule(org.opendaylight.controller.config.api.ModuleIdentifier identifier, org.opendaylight.controller.config.api.DependencyResolver dependencyResolver, org.opendaylight.controller.config.yang.config.groupbasedpolicy.StatisticsManagerImplModule oldModule, java.lang.AutoCloseable oldInstance) {
+        super(identifier, dependencyResolver, oldModule, oldInstance);
+    }
+
+    @Override
+    public void customValidation() {
+        // add custom validation form module attributes here.
+    }
+
+    @Override
+    public java.lang.AutoCloseable createInstance() {
+        DataBroker broker = getDataBrokerDependency();
+        StatisticsManagerImpl manager = new StatisticsManagerImpl(broker);
+        return manager;
+    }
+
+}
diff --git a/groupbasedpolicy/src/main/java/org/opendaylight/controller/config/yang/config/groupbasedpolicy/StatisticsManagerImplModuleFactory.java b/groupbasedpolicy/src/main/java/org/opendaylight/controller/config/yang/config/groupbasedpolicy/StatisticsManagerImplModuleFactory.java
new file mode 100644 (file)
index 0000000..19c5037
--- /dev/null
@@ -0,0 +1,13 @@
+/*
+* Generated file
+*
+* Generated from: yang module name: groupbasedpolicy-cfg yang module local name: statistics-manager-impl
+* Generated by: org.opendaylight.controller.config.yangjmxgenerator.plugin.JMXGenerator
+* Generated at: Mon Dec 14 14:12:17 CET 2015
+*
+* Do not modify this file unless it is present under src/main directory
+*/
+package org.opendaylight.controller.config.yang.config.groupbasedpolicy;
+public class StatisticsManagerImplModuleFactory extends org.opendaylight.controller.config.yang.config.groupbasedpolicy.AbstractStatisticsManagerImplModuleFactory {
+
+}
diff --git a/groupbasedpolicy/src/main/java/org/opendaylight/groupbasedpolicy/api/StatisticsManager.java b/groupbasedpolicy/src/main/java/org/opendaylight/groupbasedpolicy/api/StatisticsManager.java
new file mode 100644 (file)
index 0000000..ed023d6
--- /dev/null
@@ -0,0 +1,27 @@
+/*
+ * Copyright (c) 2015 Cisco Systems, Inc. and others.  All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+
+package org.opendaylight.groupbasedpolicy.api;
+
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.statistics.rev151215.statistic.records.StatRecords;
+
+public interface StatisticsManager {
+
+    /**
+     * Write Record into the datastore
+     * @param record record to write to datastore
+     * @return wheater the write operation was successfull or not
+     */
+    boolean writeStat(StatRecords record);
+
+    /**
+     * Returns all records stored in datastore
+     * @return all records from datastore
+     */
+    StatRecords readStats();
+}
diff --git a/groupbasedpolicy/src/main/java/org/opendaylight/groupbasedpolicy/statistics/StatisticsManagerImpl.java b/groupbasedpolicy/src/main/java/org/opendaylight/groupbasedpolicy/statistics/StatisticsManagerImpl.java
new file mode 100644 (file)
index 0000000..5e268fb
--- /dev/null
@@ -0,0 +1,232 @@
+/*
+ * Copyright (c) 2015 Cisco Systems, Inc. and others. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+
+package org.opendaylight.groupbasedpolicy.statistics;
+
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Map;
+
+import org.opendaylight.controller.md.sal.binding.api.DataBroker;
+import org.opendaylight.controller.md.sal.binding.api.ReadOnlyTransaction;
+import org.opendaylight.controller.md.sal.binding.api.WriteTransaction;
+import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType;
+import org.opendaylight.groupbasedpolicy.api.StatisticsManager;
+import org.opendaylight.groupbasedpolicy.util.IidFactory;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.yang.types.rev100924.MacAddress;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.common.rev140421.L2BridgeDomainId;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.common.rev140421.TenantId;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.statistics.rev151215.statistic.records.StatRecords;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.statistics.rev151215.statistic.records.StatRecordsBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.statistics.rev151215.statistic.records.stat.records.EpToEpStatistic;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.statistics.rev151215.statistic.records.stat.records.EpToEpStatisticBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.statistics.rev151215.statistic.records.stat.records.EpToEpStatisticKey;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.statistics.rev151215.statistic.records.stat.records.ep.to.ep.statistic.EpEpgToEpEpgStatistic;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.statistics.rev151215.statistic.records.stat.records.ep.to.ep.statistic.EpEpgToEpEpgStatisticBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.statistics.rev151215.statistic.records.stat.records.ep.to.ep.statistic.EpEpgToEpEpgStatisticKey;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.statistics.rev151215.statistic.records.stat.records.ep.to.ep.statistic.ep.epg.to.ep.epg.statistic.MatchedRuleStatistic;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.statistics.rev151215.statistic.records.stat.records.ep.to.ep.statistic.ep.epg.to.ep.epg.statistic.MatchedRuleStatisticBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.statistics.rev151215.statistic.records.stat.records.ep.to.ep.statistic.ep.epg.to.ep.epg.statistic.MatchedRuleStatisticKey;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.statistics.store.rev151215.RecordId;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.statistics.store.rev151215.StatisticsStore;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.statistics.store.rev151215.StatisticsStoreBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.statistics.store.rev151215.dst.ep.fields.DstEndpointBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.statistics.store.rev151215.source.ep.fields.SrcEndpointBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.statistics.store.rev151215.statistics.store.StatisticRecord;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.statistics.store.rev151215.statistics.store.StatisticRecordBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.statistics.store.rev151215.statistics.store.StatisticRecordKey;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.statistics.store.rev151215.statistics.store.statistic.record.Statistic;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.statistics.store.rev151215.statistics.store.statistic.record.StatisticBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.statistics.store.rev151215.statistics.store.statistic.record.StatisticKey;
+import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import com.google.common.base.Optional;
+
+public class StatisticsManagerImpl implements StatisticsManager, AutoCloseable {
+
+    private static final Logger LOG = LoggerFactory.getLogger(StatisticsManagerImpl.class);
+    private static long recordKey = 0;
+    private DataBroker dataBroker;
+
+    public StatisticsManagerImpl(DataBroker broker) {
+        this.dataBroker = broker;
+        inicializeStatistics();
+    }
+
+    private void inicializeStatistics() {
+        InstanceIdentifier<StatisticsStore> statsIID = InstanceIdentifier.builder(StatisticsStore.class).build();
+        WriteTransaction wtx = dataBroker.newWriteOnlyTransaction();
+        LOG.debug("Initalizing statistics");
+        wtx.put(LogicalDatastoreType.OPERATIONAL, statsIID, new StatisticsStoreBuilder().build());
+        wtx.submit();
+    }
+
+    @Override
+    public boolean writeStat(StatRecords record) {
+        for (EpToEpStatistic epStats : record.getEpToEpStatistic()) {
+            SrcEndpointBuilder srcBuilder = new SrcEndpointBuilder();
+            DstEndpointBuilder dstBuilder = new DstEndpointBuilder();
+            srcBuilder.setMacAddress(epStats.getSrcMacAddress())
+                .setL2Context(epStats.getSrcL2c())
+                .setTenant(epStats.getSrcTenant());
+            dstBuilder.setMacAddress(epStats.getDstMacAddress())
+                .setL2Context(epStats.getDstL2c())
+                .setTenant(epStats.getDstTenant());
+            for (EpEpgToEpEpgStatistic epgStats : epStats.getEpEpgToEpEpgStatistic()) {
+                StatisticRecordKey key = new StatisticRecordKey(new RecordId(recordKey++));
+                StatisticRecord statRecord;
+                srcBuilder.setEndpointGroup(epgStats.getSrcEpg());
+                dstBuilder.setEndpointGroup(epgStats.getDstEpg());
+                ArrayList<Statistic> statisticList = new ArrayList<>();
+                for (MatchedRuleStatistic ruleStats : epgStats.getMatchedRuleStatistic()) {
+                    Statistic statistic = new StatisticBuilder()
+                        .setKey(new StatisticKey(ruleStats.getContract(), ruleStats.getMatchedRule(),
+                                ruleStats.getSubject()))
+                        .setContract(ruleStats.getContract())
+                        .setSubject(ruleStats.getSubject())
+                        .setRule(ruleStats.getMatchedRule())
+                        .setAction(ruleStats.getAction())
+                        .setClassifier(ruleStats.getClassifier())
+                        .setByteCount(ruleStats.getByteCount())
+                        .setPacketCount(ruleStats.getPacketCount())
+                        .build();
+                    statisticList.add(statistic);
+                }
+                statRecord = new StatisticRecordBuilder().setKey(key)
+                    .setRecordId(new RecordId(recordKey))
+                    .setSrcEndpoint(srcBuilder.build())
+                    .setDstEndpoint(dstBuilder.build())
+                    .setStatistic(statisticList)
+                    .build();
+
+                InstanceIdentifier<StatisticRecord> statIID = IidFactory.statisticRecordIid(key);
+                WriteTransaction wtx = dataBroker.newWriteOnlyTransaction();
+                LOG.debug("Writing statistics to datastore");
+                wtx.put(LogicalDatastoreType.OPERATIONAL, statIID, statRecord);
+                wtx.submit();
+            }
+        }
+        return true;
+    }
+
+    @Override
+    public StatRecords readStats() {
+        InstanceIdentifier<StatisticsStore> statsIID = InstanceIdentifier.builder(StatisticsStore.class).build();
+        ReadOnlyTransaction rtx = dataBroker.newReadOnlyTransaction();
+        LOG.debug("Reading statistics");
+        Optional<StatisticsStore> storeOpt = Optional.absent();
+        try {
+            storeOpt = rtx.read(LogicalDatastoreType.OPERATIONAL, statsIID).get();
+        } catch (Exception e) {
+            e.printStackTrace();
+        }
+        if (storeOpt.isPresent()) {
+            StatisticsStore store = storeOpt.get();
+            Map<EpToEpStatisticKey, EpToEpStatisticBuilder> map = new HashMap<>();
+            for (StatisticRecord storeStat : store.getStatisticRecord()) {
+                MacAddress srcMac = storeStat.getSrcEndpoint().getMacAddress();
+                MacAddress dstMac = storeStat.getDstEndpoint().getMacAddress();
+                L2BridgeDomainId srcL2C = storeStat.getSrcEndpoint().getL2Context();
+                L2BridgeDomainId dstL2C = storeStat.getDstEndpoint().getL2Context();
+                TenantId srcTenant = storeStat.getSrcEndpoint().getTenant();
+                TenantId dstTenant = storeStat.getDstEndpoint().getTenant();
+                EpToEpStatisticKey epKey = new EpToEpStatisticKey(dstL2C, dstMac, srcL2C, srcMac);
+                EpEpgToEpEpgStatisticKey epgKey = new EpEpgToEpEpgStatisticKey(
+                        storeStat.getDstEndpoint().getEndpointGroup(), storeStat.getSrcEndpoint().getEndpointGroup());
+                EpToEpStatisticBuilder epStat = map.get(epKey);
+                if (epStat == null) {
+                    // eptoep combination doesnt exist
+                    epStat = new EpToEpStatisticBuilder();
+                    epStat.setKey(epKey)
+                        .setSrcMacAddress(srcMac)
+                        .setSrcL2c(srcL2C)
+                        .setSrcTenant(storeStat.getSrcEndpoint().getTenant())
+                        .setDstMacAddress(dstMac)
+                        .setDstL2c(dstL2C)
+                        .setDstTenant(storeStat.getDstEndpoint().getTenant());
+                }
+                List<MatchedRuleStatistic> ruleStatList = new ArrayList<>();
+                for(Statistic statistic : storeStat.getStatistic())
+                {
+                    MatchedRuleStatisticBuilder statBuilder = new MatchedRuleStatisticBuilder()
+                            .setKey(new MatchedRuleStatisticKey(statistic.getContract()
+                                    ,statistic.getRule()
+                                    ,statistic.getSubject()))
+                            .setContract(statistic.getContract())
+                            .setSubject(statistic.getSubject())
+                            .setMatchedRule(statistic.getRule())
+                            .setAction(statistic.getAction())
+                            .setClassifier(statistic.getClassifier())
+                            .setByteCount(statistic.getByteCount())
+                            .setPacketCount(statistic.getPacketCount());
+                    ruleStatList.add(statBuilder.build());
+                }
+                EpEpgToEpEpgStatisticBuilder epgtoepgBuilder = new EpEpgToEpEpgStatisticBuilder();
+                epgtoepgBuilder.setKey(epgKey)
+                    .setSrcEpg(storeStat.getSrcEndpoint().getEndpointGroup())
+                    .setDstEpg(storeStat.getDstEndpoint().getEndpointGroup())
+                    .setMatchedRuleStatistic(ruleStatList);
+                epStat.setEpEpgToEpEpgStatistic(
+                        addIfNotExists(epgtoepgBuilder, epStat.getEpEpgToEpEpgStatistic()));
+                map.put(epKey, epStat);
+            }
+            List<EpToEpStatistic> epList = new ArrayList<>();
+            for (EpToEpStatisticBuilder statBuilder : map.values()) {
+                epList.add(statBuilder.build());
+            }
+            StatRecordsBuilder statStore = new StatRecordsBuilder();
+            statStore.setEpToEpStatistic(epList);
+            return statStore.build();
+        }
+        LOG.debug("Statistics store empty");
+        return null;
+    }
+
+    private List<EpEpgToEpEpgStatistic> addIfNotExists(EpEpgToEpEpgStatisticBuilder stat,
+            List<EpEpgToEpEpgStatistic> list) {
+        Iterator<EpEpgToEpEpgStatistic> iterator = list.iterator();
+        while (iterator.hasNext()) {
+            EpEpgToEpEpgStatistic epgStat = iterator.next();
+            if (stat.getKey().equals(epgStat.getKey())) {
+                Iterator<MatchedRuleStatistic> iteratorNew = stat.getMatchedRuleStatistic().iterator();
+                while(iteratorNew.hasNext()) {
+                    MatchedRuleStatistic newStat = iteratorNew.next();
+                    Iterator<MatchedRuleStatistic> iteratorOld = epgStat.getMatchedRuleStatistic().iterator();
+                    while(iteratorOld.hasNext()) {
+                        MatchedRuleStatistic oldStat = iteratorOld.next();
+                        if(oldStat.getKey().equals(newStat.getKey())) {
+                            newStat = new MatchedRuleStatisticBuilder(oldStat)
+                                    .setByteCount(oldStat.getByteCount()+newStat.getByteCount())
+                                    .setPacketCount(oldStat.getPacketCount()+newStat.getPacketCount())
+                                    .build();
+                            iteratorNew.remove();
+                            iteratorOld.remove();
+                            break;
+                        }
+                    }
+                    epgStat.getMatchedRuleStatistic().add(newStat);
+                }
+                iterator.remove();
+                break;
+            }
+        }
+        list.add(stat.build());
+        return list;
+    }
+
+    @Override
+    public void close() throws Exception {
+        // TODO Auto-generated method stub
+
+    }
+
+}
index 4d0a4289f1b7bf691ead39386416186230c17134..74125c07f87d45b644333123c82ee5c42899ffa5 100644 (file)
@@ -85,6 +85,9 @@ import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.renderer.r
 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.renderer.rev151103.renderers.renderer.interests.followed.tenants.FollowedTenantKey;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.renderer.rev151103.renderers.renderer.interests.followed.tenants.followed.tenant.FollowedEndpointGroup;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.renderer.rev151103.renderers.renderer.interests.followed.tenants.followed.tenant.FollowedEndpointGroupKey;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.statistics.store.rev151215.StatisticsStore;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.statistics.store.rev151215.statistics.store.StatisticRecord;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.statistics.store.rev151215.statistics.store.StatisticRecordKey;
 import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
 
 public class IidFactory {
@@ -324,6 +327,10 @@ public class IidFactory {
             .build();
     }
 
+    public static InstanceIdentifier<StatisticRecord> statisticRecordIid(StatisticRecordKey key) {
+        return InstanceIdentifier.builder(StatisticsStore.class).child(StatisticRecord.class, key).build();
+    }
+
     public static InstanceIdentifier<FollowedTenant> followedTenantIid(RendererName rendererName, TenantId tenantId) {
         return InstanceIdentifier.builder(Renderers.class)
             .child(Renderer.class, new RendererKey(rendererName))
index a9c961a2b43636342bdc8cf9f3cffe5fa1b08b97..f67909879e8bbeeecf79edf20ee3ce3d57041731 100644 (file)
@@ -39,6 +39,14 @@ module groupbasedpolicy-cfg {
         config:java-class "org.opendaylight.groupbasedpolicy.api.PolicyValidatorRegistry";
     }
 
+    identity statistics-manager {
+        description
+            "statistics-manager service definition";
+
+        base "config:service-type";
+        config:java-class "org.opendaylight.groupbasedpolicy.api.StatisticsManager";
+    }
+
     identity policy-validator-registry-impl {
         base "config:module-type";
 
@@ -53,6 +61,13 @@ module groupbasedpolicy-cfg {
         config:java-name-prefix EpRendererAugmentationRegistryImpl;
     }
 
+    identity statistics-manager-impl {
+        base "config:module-type";
+
+        config:provided-service statistics-manager;
+        config:java-name-prefix StatisticsManagerImpl;
+    }
+
     identity groupbasedpolicy-impl {
         base "config:module-type";
 
@@ -126,5 +141,18 @@ module groupbasedpolicy-cfg {
                 }
             }
         }
+        case statistics-manager-impl {
+            when "/config:modules/config:module/config:type = 'statistics-manager-impl'";
+
+          //wires in the data-broker service
+            container data-broker {
+                uses config:service-ref {
+                    refine type {
+                        mandatory true;
+                        config:required-identity mdsal:binding-async-data-broker;
+                    }
+                }
+            }
+        }
     }
 }
diff --git a/groupbasedpolicy/src/main/yang/model/statistics-store.yang b/groupbasedpolicy/src/main/yang/model/statistics-store.yang
new file mode 100644 (file)
index 0000000..e669095
--- /dev/null
@@ -0,0 +1,100 @@
+/*
+ * Copyright (c) 2015 Cisco Systems, Inc. and others.  All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+
+module statistics-store {
+    yang-version 1;
+
+    namespace "urn:opendaylight:groupbasedpolicy:statistics:store";
+    prefix "gbp-statistics-store";
+
+    import endpoint {
+        prefix endpoint;
+        revision-date 2014-04-21;
+    }
+    import gbp-common {
+        prefix gbp-common;
+        revision-date 2014-04-21;
+        }
+    import ietf-inet-types {
+        prefix inet;
+        revision-date 2010-09-24;
+    }
+    description
+        "This module defines gbp statistics store.";
+
+    revision "2015-12-15" {
+        description
+            "Initial revision.";
+    }
+
+    typedef record-id {
+        type int64;
+    }
+    grouping source-ep-fields {
+        container src-endpoint {
+            uses endpoint:l2-key;
+            leaf endpoint-group {
+                type gbp-common:endpoint-group-id;
+            }
+            leaf tenant {
+                type gbp-common:tenant-id;
+            }
+        }
+    }
+
+    grouping dst-ep-fields {
+        container dst-endpoint {
+            uses endpoint:l2-key;
+            leaf endpoint-group {
+                type gbp-common:endpoint-group-id;
+            }
+            leaf tenant {
+                type gbp-common:tenant-id;
+            }
+        }
+    }
+
+    grouping statisitc-fields {
+        leaf contract {
+            type gbp-common:contract-id;
+        }
+        leaf rule {
+            type gbp-common:rule-name;
+        }
+        leaf subject {
+            type gbp-common:subject-name;
+        }
+        leaf-list classifier {
+            type gbp-common:classifier-name;
+        }
+        leaf-list action {
+            type gbp-common:action-name;
+        }
+        leaf byte-count {
+            type int64;
+        }
+        leaf packet-count {
+            type int64;
+        }
+    }
+
+    container statistics-store {
+        list statistic-record {
+            key "record-id";
+            leaf record-id {
+                type record-id;
+            }
+            uses source-ep-fields;
+            uses dst-ep-fields;
+            list statistic {
+                key "contract subject rule";
+                uses statisitc-fields;
+            }
+        }
+    }
+}
\ No newline at end of file
diff --git a/groupbasedpolicy/src/main/yang/model/statistics.yang b/groupbasedpolicy/src/main/yang/model/statistics.yang
new file mode 100644 (file)
index 0000000..fbc8048
--- /dev/null
@@ -0,0 +1,112 @@
+/*
+ * Copyright (c) 2015 Cisco Systems, Inc. and others.  All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+
+module statistics {
+    yang-version 1;
+
+    namespace "urn:opendaylight:groupbasedpolicy:statistics";
+    prefix "gbp-statistics";
+
+    import endpoint {
+        prefix endpoint;
+        revision-date 2014-04-21;
+    }
+    import gbp-common {
+        prefix gbp-common;
+        revision-date 2014-04-21;
+        }
+    import ietf-inet-types {
+        prefix inet;
+        revision-date 2010-09-24;
+    }
+    import ietf-yang-types {
+        prefix yang;
+        revision-date 2010-09-24;
+    }
+
+    description
+        "This module defines gbp statistics model.";
+
+    revision "2015-12-15" {
+        description
+            "Initial revision.";
+    }
+
+    grouping statistic-records {
+        container stat-records {
+            //////////////////////
+            //  EP combination  //
+            //specific statistic//
+            //////////////////////
+            list ep-to-ep-statistic {
+                key "src-mac-address src-l2c dst-mac-address dst-l2c";
+                /////////////
+                //Source EP//
+                /////////////
+                leaf src-mac-address {
+                    type yang:mac-address;
+                }
+                leaf src-l2c {
+                    type gbp-common:l2-bridge-domain-id;
+                }
+                leaf src-tenant {
+                    type gbp-common:tenant-id;
+                }
+                //////////////////
+                //Destination EP//
+                //////////////////
+                leaf dst-mac-address {
+                    type yang:mac-address;
+                }
+                leaf dst-l2c {
+                    type gbp-common:l2-bridge-domain-id;
+                }
+                leaf dst-tenant {
+                    type gbp-common:tenant-id;
+                }
+                //////////////////////
+                //  EPG combination //
+                //specific statistic//
+                //////////////////////
+                list ep-epg-to-ep-epg-statistic {
+                    key "src-epg dst-epg";
+                    leaf src-epg {
+                        type gbp-common:endpoint-group-id;
+                    }
+                    leaf dst-epg {
+                        type gbp-common:endpoint-group-id;
+                    }
+                    list matched-rule-statistic {
+                        key "contract subject matched-rule";
+                        leaf contract {
+                            type gbp-common:contract-id;
+                        }
+                        leaf subject {
+                            type gbp-common:subject-name;
+                        }
+                        leaf matched-rule {
+                            type gbp-common:rule-name;
+                        }
+                        leaf-list classifier {
+                            type gbp-common:classifier-name;
+                        }
+                        leaf-list action {
+                            type gbp-common:action-name;
+                        }
+                        leaf byte-count {
+                            type int64;
+                        }
+                        leaf packet-count {
+                            type int64;
+                        }
+                    }
+                }
+            }
+        }
+    }
+}
\ No newline at end of file
diff --git a/groupbasedpolicy/src/test/java/org/opendaylight/groupbasedpolicy/statistics/StatisticManagerImplTest.java b/groupbasedpolicy/src/test/java/org/opendaylight/groupbasedpolicy/statistics/StatisticManagerImplTest.java
new file mode 100644 (file)
index 0000000..1330fc0
--- /dev/null
@@ -0,0 +1,220 @@
+/*
+ * Copyright (c) 2015 Cisco Systems, Inc. and others. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+
+package org.opendaylight.groupbasedpolicy.statistics;
+
+import java.util.ArrayList;
+import java.util.Collections;
+
+import org.junit.Assert;
+import org.junit.Before;
+import org.junit.Test;
+import org.mockito.Mockito;
+import org.opendaylight.controller.md.sal.binding.api.DataBroker;
+import org.opendaylight.controller.md.sal.binding.api.ReadOnlyTransaction;
+import org.opendaylight.controller.md.sal.binding.api.WriteTransaction;
+import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType;
+import org.opendaylight.controller.md.sal.common.api.data.ReadFailedException;
+import org.opendaylight.groupbasedpolicy.util.IidFactory;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.yang.types.rev100924.MacAddress;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.common.rev140421.ActionName;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.common.rev140421.ClassifierName;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.common.rev140421.ContractId;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.common.rev140421.EndpointGroupId;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.common.rev140421.L2BridgeDomainId;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.common.rev140421.RuleName;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.common.rev140421.SubjectName;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.common.rev140421.TenantId;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.statistics.rev151215.statistic.records.StatRecords;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.statistics.rev151215.statistic.records.StatRecordsBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.statistics.rev151215.statistic.records.stat.records.EpToEpStatisticBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.statistics.rev151215.statistic.records.stat.records.EpToEpStatisticKey;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.statistics.rev151215.statistic.records.stat.records.ep.to.ep.statistic.EpEpgToEpEpgStatisticBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.statistics.rev151215.statistic.records.stat.records.ep.to.ep.statistic.EpEpgToEpEpgStatisticKey;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.statistics.rev151215.statistic.records.stat.records.ep.to.ep.statistic.ep.epg.to.ep.epg.statistic.MatchedRuleStatisticBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.statistics.rev151215.statistic.records.stat.records.ep.to.ep.statistic.ep.epg.to.ep.epg.statistic.MatchedRuleStatisticKey;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.statistics.store.rev151215.RecordId;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.statistics.store.rev151215.StatisticsStore;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.statistics.store.rev151215.StatisticsStoreBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.statistics.store.rev151215.dst.ep.fields.DstEndpointBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.statistics.store.rev151215.source.ep.fields.SrcEndpointBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.statistics.store.rev151215.statistics.store.StatisticRecord;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.statistics.store.rev151215.statistics.store.StatisticRecordBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.statistics.store.rev151215.statistics.store.StatisticRecordKey;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.statistics.store.rev151215.statistics.store.statistic.record.StatisticBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.statistics.store.rev151215.statistics.store.statistic.record.StatisticKey;
+import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
+
+import com.google.common.base.Optional;
+import com.google.common.util.concurrent.CheckedFuture;
+
+public class StatisticManagerImplTest {
+
+    private DataBroker dataBroker;
+    private StatisticsManagerImpl manager;
+    private WriteTransaction wtx;
+    private ReadOnlyTransaction rtx;
+
+    @Before
+    public void init() {
+        dataBroker = Mockito.mock(DataBroker.class);
+        wtx = Mockito.mock(WriteTransaction.class);
+        rtx = Mockito.mock(ReadOnlyTransaction.class);
+        Mockito.when(dataBroker.newWriteOnlyTransaction()).thenReturn(wtx);
+        Mockito.when(dataBroker.newReadOnlyTransaction()).thenReturn(rtx);
+        manager = new StatisticsManagerImpl(dataBroker);
+    }
+
+    @Test
+    public void writeStatTest() {
+        MacAddress srcMac = new MacAddress("00:00:00:00:00:01");
+        MacAddress dstMac = new MacAddress("00:00:00:00:00:02");
+        L2BridgeDomainId srcL2C = new L2BridgeDomainId("srcL2C");
+        L2BridgeDomainId dstL2C = new L2BridgeDomainId("dstL2C");
+        EndpointGroupId srcEPG = new EndpointGroupId("srcEPG");
+        EndpointGroupId dstEPG = new EndpointGroupId("dstEPG");
+        TenantId srcTenant = new TenantId("srcTenant");
+        TenantId dstTenant = new TenantId("dstTenant");
+        ContractId contract = new ContractId("contract");
+        SubjectName subject = new SubjectName("subject");
+        RuleName rule = new RuleName("rule");
+        ActionName action = new ActionName("action");
+        ClassifierName classifier = new ClassifierName("classifier");
+        // input
+        StatRecordsBuilder recordsBuilder = new StatRecordsBuilder();
+        EpToEpStatisticBuilder epBuilder = new EpToEpStatisticBuilder();
+        EpEpgToEpEpgStatisticBuilder epgBuilder = new EpEpgToEpEpgStatisticBuilder();
+        epgBuilder.setSrcEpg(srcEPG)
+            .setDstEpg(dstEPG)
+            .setKey(new EpEpgToEpEpgStatisticKey(dstEPG, srcEPG))
+            .setMatchedRuleStatistic(Collections.singletonList(new MatchedRuleStatisticBuilder()
+                .setKey(new MatchedRuleStatisticKey(contract, rule, subject))
+                .setContract(contract)
+                .setSubject(subject)
+                .setMatchedRule(rule)
+                .setAction(Collections.singletonList(action))
+                .setClassifier(Collections.singletonList(classifier))
+                .setByteCount(25l)
+                .setPacketCount(5l)
+                .build()));
+        epBuilder.setSrcMacAddress(srcMac)
+            .setDstMacAddress(dstMac)
+            .setSrcL2c(srcL2C)
+            .setDstL2c(dstL2C)
+            .setSrcTenant(srcTenant)
+            .setDstTenant(dstTenant)
+            .setKey(new EpToEpStatisticKey(dstL2C, dstMac, srcL2C, srcMac))
+            .setEpEpgToEpEpgStatistic(Collections.singletonList(epgBuilder.build()));
+        recordsBuilder.setEpToEpStatistic(Collections.singletonList(epBuilder.build()));
+        // output
+        SrcEndpointBuilder srcBuilder = new SrcEndpointBuilder();
+        DstEndpointBuilder dstBuilder = new DstEndpointBuilder();
+        srcBuilder.setMacAddress(srcMac).setL2Context(srcL2C).setTenant(srcTenant);
+        dstBuilder.setMacAddress(dstMac).setL2Context(dstL2C).setTenant(dstTenant);
+        srcBuilder.setEndpointGroup(srcEPG);
+        dstBuilder.setEndpointGroup(dstEPG);
+        StatisticBuilder statBuilder = new StatisticBuilder().setKey(new StatisticKey(contract, rule, subject))
+            .setContract(contract)
+            .setRule(rule)
+            .setSubject(subject)
+            .setClassifier(Collections.singletonList(classifier))
+            .setAction(Collections.singletonList(action))
+            .setByteCount(25l)
+            .setPacketCount(5l);
+        StatisticRecordKey key = new StatisticRecordKey(new RecordId(0l));
+        StatisticRecordBuilder statRecord = new StatisticRecordBuilder().setKey(key)
+            .setStatistic(Collections.singletonList(statBuilder.build()))
+            .setSrcEndpoint(srcBuilder.build())
+            .setDstEndpoint(dstBuilder.build());
+
+        manager.writeStat(recordsBuilder.build());
+        Mockito.verify(wtx).put(LogicalDatastoreType.OPERATIONAL,
+                IidFactory.statisticRecordIid(key),
+                statRecord.build());
+    }
+
+    @Test
+    public void readStatsTest() {
+        MacAddress srcMac = new MacAddress("00:00:00:00:00:01");
+        MacAddress dstMac = new MacAddress("00:00:00:00:00:02");
+        L2BridgeDomainId srcL2C = new L2BridgeDomainId("srcL2C");
+        L2BridgeDomainId dstL2C = new L2BridgeDomainId("dstL2C");
+        EndpointGroupId srcEPG = new EndpointGroupId("srcEPG");
+        EndpointGroupId dstEPG = new EndpointGroupId("dstEPG");
+        TenantId srcTenant = new TenantId("srcTenant");
+        TenantId dstTenant = new TenantId("dstTenant");
+        ContractId contract = new ContractId("contract");
+        SubjectName subject = new SubjectName("subject");
+        RuleName rule = new RuleName("rule");
+        ActionName action = new ActionName("action");
+        ClassifierName classifier = new ClassifierName("classifier");
+        // input
+        SrcEndpointBuilder srcBuilder = new SrcEndpointBuilder();
+        DstEndpointBuilder dstBuilder = new DstEndpointBuilder();
+        srcBuilder.setMacAddress(srcMac).setL2Context(srcL2C).setTenant(srcTenant);
+        dstBuilder.setMacAddress(dstMac).setL2Context(dstL2C).setTenant(dstTenant);
+        srcBuilder.setEndpointGroup(srcEPG);
+        dstBuilder.setEndpointGroup(dstEPG);
+        StatisticBuilder statBuilder = new StatisticBuilder().setKey(new StatisticKey(contract, rule, subject))
+            .setContract(contract)
+            .setRule(rule)
+            .setSubject(subject)
+            .setClassifier(Collections.singletonList(classifier))
+            .setAction(Collections.singletonList(action))
+            .setByteCount(25l)
+            .setPacketCount(5l);
+        StatisticRecordKey key = new StatisticRecordKey(new RecordId(0l));
+        StatisticRecordBuilder statRecord = new StatisticRecordBuilder().setKey(key)
+            .setStatistic(Collections.singletonList(statBuilder.build()))
+            .setSrcEndpoint(srcBuilder.build())
+            .setDstEndpoint(dstBuilder.build());
+        ArrayList<StatisticRecord> stats = new ArrayList<>();
+        stats.add(statRecord.build());
+        statRecord.setKey(new StatisticRecordKey(new RecordId(1l)));
+        stats.add(statRecord.build());
+        // output
+        StatRecordsBuilder recordsBuilder = new StatRecordsBuilder();
+        EpToEpStatisticBuilder epBuilder = new EpToEpStatisticBuilder();
+        EpEpgToEpEpgStatisticBuilder epgBuilder = new EpEpgToEpEpgStatisticBuilder();
+        epgBuilder.setSrcEpg(srcEPG)
+            .setDstEpg(dstEPG)
+            .setKey(new EpEpgToEpEpgStatisticKey(dstEPG, srcEPG))
+            .setMatchedRuleStatistic(Collections.singletonList(new MatchedRuleStatisticBuilder()
+                .setKey(new MatchedRuleStatisticKey(contract, rule, subject))
+                .setContract(contract)
+                .setSubject(subject)
+                .setMatchedRule(rule)
+                .setAction(Collections.singletonList(action))
+                .setClassifier(Collections.singletonList(classifier))
+                .setByteCount(50l)
+                .setPacketCount(10l)
+                .build()));
+        epBuilder.setSrcMacAddress(srcMac)
+            .setDstMacAddress(dstMac)
+            .setSrcL2c(srcL2C)
+            .setDstL2c(dstL2C)
+            .setSrcTenant(srcTenant)
+            .setDstTenant(dstTenant)
+            .setKey(new EpToEpStatisticKey(dstL2C, dstMac, srcL2C, srcMac))
+            .setEpEpgToEpEpgStatistic(Collections.singletonList(epgBuilder.build()));
+        recordsBuilder.setEpToEpStatistic(Collections.singletonList(epBuilder.build()));
+
+        CheckedFuture<Optional<StatisticsStore>, ReadFailedException> future = Mockito.mock(CheckedFuture.class);
+        try {
+            Mockito.when(future.get())
+                .thenReturn(Optional.of(new StatisticsStoreBuilder().setStatisticRecord(stats).build()));
+            Mockito.when(rtx.read(LogicalDatastoreType.OPERATIONAL,
+                    InstanceIdentifier.builder(StatisticsStore.class).build()))
+                .thenReturn(future);
+            StatRecords read = manager.readStats();
+            Assert.assertEquals(recordsBuilder.build(), read);
+        } catch (Exception e) {
+        }
+
+    }
+}