GBP core tests improvements
[groupbasedpolicy.git] / groupbasedpolicy / src / main / java / org / opendaylight / groupbasedpolicy / statistics / StatisticsManagerImpl.java
1 /*
2  * Copyright (c) 2015 Cisco Systems, Inc. and others. All rights reserved.
3  *
4  * This program and the accompanying materials are made available under the
5  * terms of the Eclipse Public License v1.0 which accompanies this distribution,
6  * and is available at http://www.eclipse.org/legal/epl-v10.html
7  */
8
9 package org.opendaylight.groupbasedpolicy.statistics;
10
11 import java.util.ArrayList;
12 import java.util.HashMap;
13 import java.util.Iterator;
14 import java.util.List;
15 import java.util.Map;
16 import java.util.concurrent.ExecutionException;
17
18 import org.opendaylight.controller.md.sal.binding.api.DataBroker;
19 import org.opendaylight.controller.md.sal.binding.api.ReadOnlyTransaction;
20 import org.opendaylight.controller.md.sal.binding.api.WriteTransaction;
21 import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType;
22 import org.opendaylight.groupbasedpolicy.api.StatisticsManager;
23 import org.opendaylight.groupbasedpolicy.util.DataStoreHelper;
24 import org.opendaylight.groupbasedpolicy.util.IidFactory;
25 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.yang.types.rev100924.MacAddress;
26 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.common.rev140421.L2BridgeDomainId;
27 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.common.rev140421.TenantId;
28 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.statistics.rev151215.statistic.records.StatRecords;
29 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.statistics.rev151215.statistic.records.StatRecordsBuilder;
30 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.statistics.rev151215.statistic.records.stat.records.EpToEpStatistic;
31 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.statistics.rev151215.statistic.records.stat.records.EpToEpStatisticBuilder;
32 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.statistics.rev151215.statistic.records.stat.records.EpToEpStatisticKey;
33 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.statistics.rev151215.statistic.records.stat.records.ep.to.ep.statistic.EpEpgToEpEpgStatistic;
34 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.statistics.rev151215.statistic.records.stat.records.ep.to.ep.statistic.EpEpgToEpEpgStatisticBuilder;
35 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.statistics.rev151215.statistic.records.stat.records.ep.to.ep.statistic.EpEpgToEpEpgStatisticKey;
36 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;
37 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;
38 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;
39 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.statistics.store.rev151215.RecordId;
40 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.statistics.store.rev151215.StatisticsStore;
41 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.statistics.store.rev151215.StatisticsStoreBuilder;
42 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.statistics.store.rev151215.dst.ep.fields.DstEndpointBuilder;
43 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.statistics.store.rev151215.source.ep.fields.SrcEndpointBuilder;
44 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.statistics.store.rev151215.statistics.store.StatisticRecord;
45 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.statistics.store.rev151215.statistics.store.StatisticRecordBuilder;
46 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.statistics.store.rev151215.statistics.store.StatisticRecordKey;
47 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.statistics.store.rev151215.statistics.store.statistic.record.Statistic;
48 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.statistics.store.rev151215.statistics.store.statistic.record.StatisticBuilder;
49 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.statistics.store.rev151215.statistics.store.statistic.record.StatisticKey;
50 import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
51 import org.slf4j.Logger;
52 import org.slf4j.LoggerFactory;
53
54 import com.google.common.base.Optional;
55
56 public class StatisticsManagerImpl implements StatisticsManager, AutoCloseable {
57
58     private static final Logger LOG = LoggerFactory.getLogger(StatisticsManagerImpl.class);
59     private static long recordKey = 0;
60     private DataBroker dataBroker;
61
62     public StatisticsManagerImpl(DataBroker broker) {
63         this.dataBroker = broker;
64         inicializeStatistics();
65     }
66
67     private void inicializeStatistics() {
68         InstanceIdentifier<StatisticsStore> statsIID = InstanceIdentifier.builder(StatisticsStore.class).build();
69         WriteTransaction wtx = dataBroker.newWriteOnlyTransaction();
70         LOG.debug("Initalizing statistics");
71         wtx.put(LogicalDatastoreType.OPERATIONAL, statsIID, new StatisticsStoreBuilder().build());
72         wtx.submit();
73     }
74
75     @Override
76     public boolean writeStat(StatRecords record) {
77         WriteTransaction wtx = dataBroker.newWriteOnlyTransaction();
78         for (EpToEpStatistic epStats : record.getEpToEpStatistic()) {
79             SrcEndpointBuilder srcBuilder = new SrcEndpointBuilder();
80             DstEndpointBuilder dstBuilder = new DstEndpointBuilder();
81             srcBuilder.setMacAddress(epStats.getSrcMacAddress())
82                     .setL2Context(epStats.getSrcL2c())
83                     .setTenant(epStats.getSrcTenant());
84             dstBuilder.setMacAddress(epStats.getDstMacAddress())
85                     .setL2Context(epStats.getDstL2c())
86                     .setTenant(epStats.getDstTenant());
87             for (EpEpgToEpEpgStatistic epgStats : epStats.getEpEpgToEpEpgStatistic()) {
88                 StatisticRecordKey key = new StatisticRecordKey(new RecordId(recordKey++));
89                 StatisticRecord statRecord;
90                 srcBuilder.setEndpointGroup(epgStats.getSrcEpg());
91                 dstBuilder.setEndpointGroup(epgStats.getDstEpg());
92                 List<Statistic> statisticList = new ArrayList<>();
93                 for (MatchedRuleStatistic ruleStats : epgStats.getMatchedRuleStatistic()) {
94                     Statistic statistic = new StatisticBuilder()
95                             .setKey(new StatisticKey(ruleStats.getContract(),
96                                     ruleStats.getMatchedRule(), ruleStats.getSubject()))
97                             .setContract(ruleStats.getContract())
98                             .setSubject(ruleStats.getSubject())
99                             .setRule(ruleStats.getMatchedRule())
100                             .setAction(ruleStats.getAction())
101                             .setClassifier(ruleStats.getClassifier())
102                             .setByteCount(ruleStats.getByteCount())
103                             .setPacketCount(ruleStats.getPacketCount())
104                             .build();
105                     statisticList.add(statistic);
106
107                 }
108                 statRecord = new StatisticRecordBuilder().setKey(key)
109                         .setRecordId(new RecordId(recordKey))
110                         .setTimestamp(epStats.getTimestamp())
111                         .setSrcEndpoint(srcBuilder.build())
112                         .setDstEndpoint(dstBuilder.build())
113                         .setStatistic(statisticList)
114                         .build();
115
116                 InstanceIdentifier<StatisticRecord> statIID = IidFactory.statisticRecordIid(key);
117                 LOG.debug("Writing statistics to datastore: {}", statRecord);
118                 wtx.put(LogicalDatastoreType.OPERATIONAL, statIID, statRecord, true);
119             }
120         }
121         return DataStoreHelper.submitToDs(wtx);
122     }
123
124     @Override
125     public StatRecords readStats() {
126         InstanceIdentifier<StatisticsStore> statsIID = InstanceIdentifier.builder(StatisticsStore.class).build();
127         ReadOnlyTransaction rtx = dataBroker.newReadOnlyTransaction();
128         LOG.debug("Reading statistics");
129         Optional<StatisticsStore> storeOpt = Optional.absent();
130         try {
131             storeOpt = rtx.read(LogicalDatastoreType.OPERATIONAL, statsIID).get();
132         } catch (InterruptedException | ExecutionException e) {
133             LOG.error("Exception thrown on reading from Datastore: {}", e.getMessage());
134             return null;
135         }
136         if (storeOpt.isPresent()) {
137             StatisticsStore store = storeOpt.get();
138             Map<EpToEpStatisticKey, EpToEpStatisticBuilder> map = new HashMap<>();
139             for (StatisticRecord storeStat : store.getStatisticRecord()) {
140                 MacAddress srcMac = storeStat.getSrcEndpoint().getMacAddress();
141                 MacAddress dstMac = storeStat.getDstEndpoint().getMacAddress();
142                 L2BridgeDomainId srcL2C = storeStat.getSrcEndpoint().getL2Context();
143                 L2BridgeDomainId dstL2C = storeStat.getDstEndpoint().getL2Context();
144                 TenantId srcTenant = storeStat.getSrcEndpoint().getTenant();
145                 TenantId dstTenant = storeStat.getDstEndpoint().getTenant();
146                 EpToEpStatisticKey epKey = new EpToEpStatisticKey(dstL2C, dstMac, srcL2C, srcMac);
147                 EpEpgToEpEpgStatisticKey epgKey = new EpEpgToEpEpgStatisticKey(
148                         storeStat.getDstEndpoint().getEndpointGroup(), storeStat.getSrcEndpoint().getEndpointGroup());
149                 EpToEpStatisticBuilder epStat = map.get(epKey);
150                 if (epStat == null) {
151                     // eptoep combination doesnt exist
152                     epStat = new EpToEpStatisticBuilder();
153                     epStat.setKey(epKey)
154                         .setSrcMacAddress(srcMac)
155                         .setSrcL2c(srcL2C)
156                         .setSrcTenant(storeStat.getSrcEndpoint().getTenant())
157                         .setDstMacAddress(dstMac)
158                         .setDstL2c(dstL2C)
159                         .setDstTenant(storeStat.getDstEndpoint().getTenant());
160                 }
161                 List<MatchedRuleStatistic> ruleStatList = new ArrayList<>();
162                 for(Statistic statistic : storeStat.getStatistic())
163                 {
164                     MatchedRuleStatisticBuilder statBuilder = new MatchedRuleStatisticBuilder()
165                             .setKey(new MatchedRuleStatisticKey(statistic.getContract()
166                                     ,statistic.getRule()
167                                     ,statistic.getSubject()))
168                             .setContract(statistic.getContract())
169                             .setSubject(statistic.getSubject())
170                             .setMatchedRule(statistic.getRule())
171                             .setAction(statistic.getAction())
172                             .setClassifier(statistic.getClassifier())
173                             .setByteCount(statistic.getByteCount())
174                             .setPacketCount(statistic.getPacketCount());
175                     ruleStatList.add(statBuilder.build());
176                 }
177                 EpEpgToEpEpgStatisticBuilder epgtoepgBuilder = new EpEpgToEpEpgStatisticBuilder();
178                 epgtoepgBuilder.setKey(epgKey)
179                     .setSrcEpg(storeStat.getSrcEndpoint().getEndpointGroup())
180                     .setDstEpg(storeStat.getDstEndpoint().getEndpointGroup())
181                     .setMatchedRuleStatistic(ruleStatList);
182                 epStat.setEpEpgToEpEpgStatistic(
183                         addIfNotExists(epgtoepgBuilder, epStat.getEpEpgToEpEpgStatistic()));
184                 map.put(epKey, epStat);
185             }
186             List<EpToEpStatistic> epList = new ArrayList<>();
187             for (EpToEpStatisticBuilder statBuilder : map.values()) {
188                 epList.add(statBuilder.build());
189             }
190             StatRecordsBuilder statStore = new StatRecordsBuilder();
191             statStore.setEpToEpStatistic(epList);
192             return statStore.build();
193         }
194         LOG.debug("Statistics store empty");
195         return null;
196     }
197
198     private List<EpEpgToEpEpgStatistic> addIfNotExists(EpEpgToEpEpgStatisticBuilder stat,
199             List<EpEpgToEpEpgStatistic> list) {
200         if ( list == null ) {
201             list = new ArrayList<>();
202         } else {
203             Iterator<EpEpgToEpEpgStatistic> iterator = list.iterator();
204             while (iterator.hasNext()) {
205                 EpEpgToEpEpgStatistic epgStat = iterator.next();
206                 if (stat.getKey().equals(epgStat.getKey())) {
207                     List<MatchedRuleStatistic> newMatches = new ArrayList<>();
208                     Iterator<MatchedRuleStatistic> iteratorNew = stat.getMatchedRuleStatistic().iterator();
209                     while(iteratorNew.hasNext()) {
210                         MatchedRuleStatistic newStat = iteratorNew.next();
211                         Iterator<MatchedRuleStatistic> iteratorOld = epgStat.getMatchedRuleStatistic().iterator();
212                         boolean matched = false;
213                         while(iteratorOld.hasNext()) {
214                             MatchedRuleStatistic oldStat = iteratorOld.next();
215                             if(oldStat.getKey().equals(newStat.getKey())) {
216                                 MatchedRuleStatistic newRuleStat = new MatchedRuleStatisticBuilder(oldStat)
217                                         .setByteCount(sumNullableValues(oldStat.getByteCount(), newStat.getByteCount()))
218                                         .setPacketCount(sumNullableValues(oldStat.getPacketCount(), newStat.getPacketCount()))
219                                         .build();
220                                 newMatches.add(newRuleStat);
221                                 matched = true;
222                             } else {
223                                 newMatches.add(oldStat);
224                             }
225                         }
226                         if (!matched) {
227                             newMatches.add(newStat);
228                         }
229                     }
230                     stat.setMatchedRuleStatistic(newMatches);
231                     iterator.remove();
232                     break;
233                 }
234             }
235         }
236         list.add(stat.build());
237         return list;
238     }
239
240     public Long sumNullableValues (Long... x ) {
241         long result = 0;
242         for (Long num : x) {
243             if (num != null) {
244                 result += num;
245             }
246         }
247         return result;
248     }
249
250     @Override
251     public void close() throws Exception {
252         // TODO Auto-generated method stub
253
254     }
255
256 }