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