2 * Copyright IBM Corporation, 2013. All rights reserved.
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
8 package org.opendaylight.controller.md.statistics.manager;
10 import java.util.HashMap;
11 import java.util.List;
12 import java.util.concurrent.ConcurrentMap;
14 import org.opendaylight.controller.sal.binding.api.data.DataModificationTransaction;
15 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.FlowCapableNode;
16 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.FlowCapableNodeConnector;
17 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.FlowId;
18 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.meters.Meter;
19 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.meters.MeterBuilder;
20 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.meters.MeterKey;
21 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.tables.Table;
22 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.tables.TableBuilder;
23 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.tables.TableKey;
24 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.tables.table.Flow;
25 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.tables.table.FlowBuilder;
26 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.tables.table.FlowKey;
27 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.statistics.rev130819.AggregateFlowStatisticsData;
28 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.statistics.rev130819.AggregateFlowStatisticsDataBuilder;
29 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.statistics.rev130819.AggregateFlowStatisticsUpdate;
30 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.statistics.rev130819.FlowStatisticsData;
31 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.statistics.rev130819.FlowStatisticsDataBuilder;
32 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.statistics.rev130819.FlowsStatisticsUpdate;
33 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.statistics.rev130819.OpendaylightFlowStatisticsListener;
34 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.statistics.rev130819.aggregate.flow.statistics.AggregateFlowStatisticsBuilder;
35 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.statistics.rev130819.flow.and.statistics.map.list.FlowAndStatisticsMapList;
36 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.statistics.rev130819.flow.and.statistics.map.list.FlowAndStatisticsMapListBuilder;
37 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.statistics.rev130819.flow.statistics.FlowStatisticsBuilder;
38 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.table.statistics.rev131215.FlowTableStatisticsData;
39 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.table.statistics.rev131215.FlowTableStatisticsDataBuilder;
40 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.table.statistics.rev131215.FlowTableStatisticsUpdate;
41 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.table.statistics.rev131215.OpendaylightFlowTableStatisticsListener;
42 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.table.statistics.rev131215.flow.table.and.statistics.map.FlowTableAndStatisticsMap;
43 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.table.statistics.rev131215.flow.table.statistics.FlowTableStatisticsBuilder;
44 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.port.rev130925.queues.Queue;
45 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.port.rev130925.queues.QueueBuilder;
46 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.port.rev130925.queues.QueueKey;
47 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.queue.rev130925.QueueId;
48 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.flow.Match;
49 import org.opendaylight.yang.gen.v1.urn.opendaylight.group.statistics.rev131111.GroupDescStatsUpdated;
50 import org.opendaylight.yang.gen.v1.urn.opendaylight.group.statistics.rev131111.GroupFeaturesUpdated;
51 import org.opendaylight.yang.gen.v1.urn.opendaylight.group.statistics.rev131111.GroupStatisticsUpdated;
52 import org.opendaylight.yang.gen.v1.urn.opendaylight.group.statistics.rev131111.NodeGroupDescStats;
53 import org.opendaylight.yang.gen.v1.urn.opendaylight.group.statistics.rev131111.NodeGroupDescStatsBuilder;
54 import org.opendaylight.yang.gen.v1.urn.opendaylight.group.statistics.rev131111.NodeGroupFeatures;
55 import org.opendaylight.yang.gen.v1.urn.opendaylight.group.statistics.rev131111.NodeGroupFeaturesBuilder;
56 import org.opendaylight.yang.gen.v1.urn.opendaylight.group.statistics.rev131111.NodeGroupStatistics;
57 import org.opendaylight.yang.gen.v1.urn.opendaylight.group.statistics.rev131111.NodeGroupStatisticsBuilder;
58 import org.opendaylight.yang.gen.v1.urn.opendaylight.group.statistics.rev131111.OpendaylightGroupStatisticsListener;
59 import org.opendaylight.yang.gen.v1.urn.opendaylight.group.statistics.rev131111.group.desc.GroupDescBuilder;
60 import org.opendaylight.yang.gen.v1.urn.opendaylight.group.statistics.rev131111.group.features.GroupFeaturesBuilder;
61 import org.opendaylight.yang.gen.v1.urn.opendaylight.group.statistics.rev131111.group.statistics.GroupStatisticsBuilder;
62 import org.opendaylight.yang.gen.v1.urn.opendaylight.group.types.rev131018.group.desc.stats.reply.GroupDescStats;
63 import org.opendaylight.yang.gen.v1.urn.opendaylight.group.types.rev131018.group.statistics.reply.GroupStats;
64 import org.opendaylight.yang.gen.v1.urn.opendaylight.group.types.rev131018.groups.Group;
65 import org.opendaylight.yang.gen.v1.urn.opendaylight.group.types.rev131018.groups.GroupBuilder;
66 import org.opendaylight.yang.gen.v1.urn.opendaylight.group.types.rev131018.groups.GroupKey;
67 import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.NodeId;
68 import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.NodeRef;
69 import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.Nodes;
70 import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.node.NodeConnector;
71 import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.node.NodeConnectorBuilder;
72 import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.node.NodeConnectorKey;
73 import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.nodes.Node;
74 import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.nodes.NodeBuilder;
75 import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.nodes.NodeKey;
76 import org.opendaylight.yang.gen.v1.urn.opendaylight.meter.statistics.rev131111.MeterConfigStatsUpdated;
77 import org.opendaylight.yang.gen.v1.urn.opendaylight.meter.statistics.rev131111.MeterFeaturesUpdated;
78 import org.opendaylight.yang.gen.v1.urn.opendaylight.meter.statistics.rev131111.MeterStatisticsUpdated;
79 import org.opendaylight.yang.gen.v1.urn.opendaylight.meter.statistics.rev131111.NodeMeterConfigStats;
80 import org.opendaylight.yang.gen.v1.urn.opendaylight.meter.statistics.rev131111.NodeMeterConfigStatsBuilder;
81 import org.opendaylight.yang.gen.v1.urn.opendaylight.meter.statistics.rev131111.NodeMeterFeatures;
82 import org.opendaylight.yang.gen.v1.urn.opendaylight.meter.statistics.rev131111.NodeMeterFeaturesBuilder;
83 import org.opendaylight.yang.gen.v1.urn.opendaylight.meter.statistics.rev131111.NodeMeterStatistics;
84 import org.opendaylight.yang.gen.v1.urn.opendaylight.meter.statistics.rev131111.NodeMeterStatisticsBuilder;
85 import org.opendaylight.yang.gen.v1.urn.opendaylight.meter.statistics.rev131111.OpendaylightMeterStatisticsListener;
86 import org.opendaylight.yang.gen.v1.urn.opendaylight.meter.statistics.rev131111.nodes.node.MeterFeaturesBuilder;
87 import org.opendaylight.yang.gen.v1.urn.opendaylight.meter.statistics.rev131111.nodes.node.meter.MeterConfigStatsBuilder;
88 import org.opendaylight.yang.gen.v1.urn.opendaylight.meter.statistics.rev131111.nodes.node.meter.MeterStatisticsBuilder;
89 import org.opendaylight.yang.gen.v1.urn.opendaylight.meter.types.rev130918.meter.config.stats.reply.MeterConfigStats;
90 import org.opendaylight.yang.gen.v1.urn.opendaylight.meter.types.rev130918.meter.statistics.reply.MeterStats;
91 import org.opendaylight.yang.gen.v1.urn.opendaylight.model.match.types.rev131026.match.EthernetMatch;
92 import org.opendaylight.yang.gen.v1.urn.opendaylight.model.match.types.rev131026.match.VlanMatch;
93 import org.opendaylight.yang.gen.v1.urn.opendaylight.model.match.types.rev131026.match.layer._3.match.Ipv4Match;
94 import org.opendaylight.yang.gen.v1.urn.opendaylight.model.match.types.rev131026.match.layer._4.match.TcpMatch;
95 import org.opendaylight.yang.gen.v1.urn.opendaylight.model.statistics.types.rev130925.GenericQueueStatistics;
96 import org.opendaylight.yang.gen.v1.urn.opendaylight.model.statistics.types.rev130925.GenericStatistics;
97 import org.opendaylight.yang.gen.v1.urn.opendaylight.port.statistics.rev131214.FlowCapableNodeConnectorStatisticsData;
98 import org.opendaylight.yang.gen.v1.urn.opendaylight.port.statistics.rev131214.FlowCapableNodeConnectorStatisticsDataBuilder;
99 import org.opendaylight.yang.gen.v1.urn.opendaylight.port.statistics.rev131214.NodeConnectorStatisticsUpdate;
100 import org.opendaylight.yang.gen.v1.urn.opendaylight.port.statistics.rev131214.OpendaylightPortStatisticsListener;
101 import org.opendaylight.yang.gen.v1.urn.opendaylight.port.statistics.rev131214.flow.capable.node.connector.statistics.FlowCapableNodeConnectorStatisticsBuilder;
102 import org.opendaylight.yang.gen.v1.urn.opendaylight.port.statistics.rev131214.node.connector.statistics.and.port.number.map.NodeConnectorStatisticsAndPortNumberMap;
103 import org.opendaylight.yang.gen.v1.urn.opendaylight.queue.statistics.rev131216.FlowCapableNodeConnectorQueueStatisticsData;
104 import org.opendaylight.yang.gen.v1.urn.opendaylight.queue.statistics.rev131216.FlowCapableNodeConnectorQueueStatisticsDataBuilder;
105 import org.opendaylight.yang.gen.v1.urn.opendaylight.queue.statistics.rev131216.OpendaylightQueueStatisticsListener;
106 import org.opendaylight.yang.gen.v1.urn.opendaylight.queue.statistics.rev131216.QueueStatisticsUpdate;
107 import org.opendaylight.yang.gen.v1.urn.opendaylight.queue.statistics.rev131216.flow.capable.node.connector.queue.statistics.FlowCapableNodeConnectorQueueStatisticsBuilder;
108 import org.opendaylight.yang.gen.v1.urn.opendaylight.queue.statistics.rev131216.queue.id.and.statistics.map.QueueIdAndStatisticsMap;
109 import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
110 import org.opendaylight.yangtools.yang.binding.InstanceIdentifier.InstanceIdentifierBuilder;
111 import org.slf4j.Logger;
112 import org.slf4j.LoggerFactory;
115 * Class implement statistics manager related listener interface and augment all the
116 * received statistics data to data stores.
117 * TODO: Need to add error message listener and clean-up the associated tx id
118 * if it exists in the tx-id cache.
119 * @author vishnoianil
122 public class StatisticsUpdateCommiter implements OpendaylightGroupStatisticsListener,
123 OpendaylightMeterStatisticsListener,
124 OpendaylightFlowStatisticsListener,
125 OpendaylightPortStatisticsListener,
126 OpendaylightFlowTableStatisticsListener,
127 OpendaylightQueueStatisticsListener{
129 public final static Logger sucLogger = LoggerFactory.getLogger(StatisticsUpdateCommiter.class);
131 private final StatisticsProvider statisticsManager;
133 private final int unaccountedFlowsCounter = 1;
135 public StatisticsUpdateCommiter(final StatisticsProvider manager){
137 this.statisticsManager = manager;
140 public StatisticsProvider getStatisticsManager(){
141 return statisticsManager;
145 public void onMeterConfigStatsUpdated(MeterConfigStatsUpdated notification) {
146 //Check if response is for the request statistics-manager sent.
147 if(this.statisticsManager.getMultipartMessageManager().removeTxId(notification.getTransactionId()) == null)
150 //Add statistics to local cache
151 ConcurrentMap<NodeId, NodeStatistics> cache = this.statisticsManager.getStatisticsCache();
152 if(!cache.containsKey(notification.getId())){
153 cache.put(notification.getId(), new NodeStatistics());
155 cache.get(notification.getId()).setMeterConfigStats(notification.getMeterConfigStats());
157 //Publish data to configuration data store
158 NodeKey key = new NodeKey(notification.getId());
160 List<MeterConfigStats> eterConfigStatsList = notification.getMeterConfigStats();
162 for(MeterConfigStats meterConfigStats : eterConfigStatsList){
163 DataModificationTransaction it = this.statisticsManager.startChange();
164 MeterBuilder meterBuilder = new MeterBuilder();
165 MeterKey meterKey = new MeterKey(meterConfigStats.getMeterId());
166 meterBuilder.setKey(meterKey);
168 InstanceIdentifier<Meter> meterRef = InstanceIdentifier.builder(Nodes.class).child(Node.class,key)
169 .augmentation(FlowCapableNode.class)
170 .child(Meter.class,meterKey).toInstance();
172 NodeMeterConfigStatsBuilder meterConfig= new NodeMeterConfigStatsBuilder();
173 MeterConfigStatsBuilder stats = new MeterConfigStatsBuilder();
174 stats.fieldsFrom(meterConfigStats);
175 meterConfig.setMeterConfigStats(stats.build());
177 //Update augmented data
178 meterBuilder.addAugmentation(NodeMeterConfigStats.class, meterConfig.build());
179 it.putOperationalData(meterRef, meterBuilder.build());
186 public void onMeterStatisticsUpdated(MeterStatisticsUpdated notification) {
188 //Check if response is for the request statistics-manager sent.
189 if(this.statisticsManager.getMultipartMessageManager().removeTxId(notification.getTransactionId()) == null)
192 //Add statistics to local cache
193 ConcurrentMap<NodeId, NodeStatistics> cache = this.statisticsManager.getStatisticsCache();
194 if(!cache.containsKey(notification.getId())){
195 cache.put(notification.getId(), new NodeStatistics());
197 cache.get(notification.getId()).setMeterStatistics(notification.getMeterStats());
199 NodeKey key = new NodeKey(notification.getId());
201 List<MeterStats> meterStatsList = notification.getMeterStats();
203 for(MeterStats meterStats : meterStatsList){
205 //Publish data to configuration data store
206 DataModificationTransaction it = this.statisticsManager.startChange();
207 MeterBuilder meterBuilder = new MeterBuilder();
208 MeterKey meterKey = new MeterKey(meterStats.getMeterId());
209 meterBuilder.setKey(meterKey);
211 InstanceIdentifier<Meter> meterRef = InstanceIdentifier.builder(Nodes.class).child(Node.class,key)
212 .augmentation(FlowCapableNode.class)
213 .child(Meter.class,meterKey).toInstance();
215 NodeMeterStatisticsBuilder meterStatsBuilder= new NodeMeterStatisticsBuilder();
216 MeterStatisticsBuilder stats = new MeterStatisticsBuilder();
217 stats.fieldsFrom(meterStats);
218 meterStatsBuilder.setMeterStatistics(stats.build());
220 //Update augmented data
221 meterBuilder.addAugmentation(NodeMeterStatistics.class, meterStatsBuilder.build());
222 it.putOperationalData(meterRef, meterBuilder.build());
228 public void onGroupDescStatsUpdated(GroupDescStatsUpdated notification) {
230 //Check if response is for the request statistics-manager sent.
231 if(this.statisticsManager.getMultipartMessageManager().removeTxId(notification.getTransactionId()) == null)
234 //Add statistics to local cache
235 ConcurrentMap<NodeId, NodeStatistics> cache = this.statisticsManager.getStatisticsCache();
236 if(!cache.containsKey(notification.getId())){
237 cache.put(notification.getId(), new NodeStatistics());
239 cache.get(notification.getId()).setGroupDescStats(notification.getGroupDescStats());
241 //Publish data to configuration data store
242 NodeKey key = new NodeKey(notification.getId());
243 List<GroupDescStats> groupDescStatsList = notification.getGroupDescStats();
245 for(GroupDescStats groupDescStats : groupDescStatsList){
246 DataModificationTransaction it = this.statisticsManager.startChange();
248 GroupBuilder groupBuilder = new GroupBuilder();
249 GroupKey groupKey = new GroupKey(groupDescStats.getGroupId());
250 groupBuilder.setKey(groupKey);
252 InstanceIdentifier<Group> groupRef = InstanceIdentifier.builder(Nodes.class).child(Node.class,key)
253 .augmentation(FlowCapableNode.class)
254 .child(Group.class,groupKey).toInstance();
256 NodeGroupDescStatsBuilder groupDesc= new NodeGroupDescStatsBuilder();
257 GroupDescBuilder stats = new GroupDescBuilder();
258 stats.fieldsFrom(groupDescStats);
259 groupDesc.setGroupDesc(stats.build());
261 //Update augmented data
262 groupBuilder.addAugmentation(NodeGroupDescStats.class, groupDesc.build());
264 it.putOperationalData(groupRef, groupBuilder.build());
270 public void onGroupStatisticsUpdated(GroupStatisticsUpdated notification) {
272 //Check if response is for the request statistics-manager sent.
273 if(this.statisticsManager.getMultipartMessageManager().removeTxId(notification.getTransactionId()) == null)
276 //Add statistics to local cache
277 ConcurrentMap<NodeId, NodeStatistics> cache = this.statisticsManager.getStatisticsCache();
278 if(!cache.containsKey(notification.getId())){
279 cache.put(notification.getId(), new NodeStatistics());
281 cache.get(notification.getId()).setGroupStatistics(notification.getGroupStats());
283 //Publish data to configuration data store
284 NodeKey key = new NodeKey(notification.getId());
285 List<GroupStats> groupStatsList = notification.getGroupStats();
287 for(GroupStats groupStats : groupStatsList){
288 DataModificationTransaction it = this.statisticsManager.startChange();
290 GroupBuilder groupBuilder = new GroupBuilder();
291 GroupKey groupKey = new GroupKey(groupStats.getGroupId());
292 groupBuilder.setKey(groupKey);
294 InstanceIdentifier<Group> groupRef = InstanceIdentifier.builder(Nodes.class).child(Node.class,key)
295 .augmentation(FlowCapableNode.class)
296 .child(Group.class,groupKey).toInstance();
298 NodeGroupStatisticsBuilder groupStatisticsBuilder= new NodeGroupStatisticsBuilder();
299 GroupStatisticsBuilder stats = new GroupStatisticsBuilder();
300 stats.fieldsFrom(groupStats);
301 groupStatisticsBuilder.setGroupStatistics(stats.build());
303 //Update augmented data
304 groupBuilder.addAugmentation(NodeGroupStatistics.class, groupStatisticsBuilder.build());
305 it.putOperationalData(groupRef, groupBuilder.build());
311 public void onMeterFeaturesUpdated(MeterFeaturesUpdated notification) {
313 //Add statistics to local cache
314 ConcurrentMap<NodeId, NodeStatistics> cache = this.statisticsManager.getStatisticsCache();
315 if(!cache.containsKey(notification.getId())){
316 cache.put(notification.getId(), new NodeStatistics());
318 MeterFeaturesBuilder meterFeature = new MeterFeaturesBuilder();
319 meterFeature.setMeterBandSupported(notification.getMeterBandSupported());
320 meterFeature.setMeterCapabilitiesSupported(notification.getMeterCapabilitiesSupported());
321 meterFeature.setMaxBands(notification.getMaxBands());
322 meterFeature.setMaxColor(notification.getMaxColor());
323 meterFeature.setMaxMeter(notification.getMaxMeter());
325 cache.get(notification.getId()).setMeterFeatures(meterFeature.build());
327 //Publish data to configuration data store
328 DataModificationTransaction it = this.statisticsManager.startChange();
329 NodeKey key = new NodeKey(notification.getId());
330 NodeRef ref = getNodeRef(key);
332 final NodeBuilder nodeData = new NodeBuilder();
333 nodeData.setKey(key);
335 NodeMeterFeaturesBuilder nodeMeterFeatures= new NodeMeterFeaturesBuilder();
336 nodeMeterFeatures.setMeterFeatures(meterFeature.build());
338 //Update augmented data
339 nodeData.addAugmentation(NodeMeterFeatures.class, nodeMeterFeatures.build());
341 InstanceIdentifier<? extends Object> refValue = ref.getValue();
342 it.putOperationalData(refValue, nodeData.build());
347 public void onGroupFeaturesUpdated(GroupFeaturesUpdated notification) {
349 //Add statistics to local cache
350 ConcurrentMap<NodeId, NodeStatistics> cache = this.statisticsManager.getStatisticsCache();
351 if(!cache.containsKey(notification.getId())){
352 cache.put(notification.getId(), new NodeStatistics());
355 GroupFeaturesBuilder groupFeatures = new GroupFeaturesBuilder();
356 groupFeatures.setActions(notification.getActions());
357 groupFeatures.setGroupCapabilitiesSupported(notification.getGroupCapabilitiesSupported());
358 groupFeatures.setGroupTypesSupported(notification.getGroupTypesSupported());
359 groupFeatures.setMaxGroups(notification.getMaxGroups());
360 cache.get(notification.getId()).setGroupFeatures(groupFeatures.build());
362 //Publish data to configuration data store
363 DataModificationTransaction it = this.statisticsManager.startChange();
364 NodeKey key = new NodeKey(notification.getId());
365 NodeRef ref = getNodeRef(key);
367 final NodeBuilder nodeData = new NodeBuilder();
368 nodeData.setKey(key);
370 NodeGroupFeaturesBuilder nodeGroupFeatures= new NodeGroupFeaturesBuilder();
371 nodeGroupFeatures.setGroupFeatures(groupFeatures.build());
373 //Update augmented data
374 nodeData.addAugmentation(NodeGroupFeatures.class, nodeGroupFeatures.build());
376 InstanceIdentifier<? extends Object> refValue = ref.getValue();
377 it.putOperationalData(refValue, nodeData.build());
382 public void onFlowsStatisticsUpdate(FlowsStatisticsUpdate notification) {
384 //Check if response is for the request statistics-manager sent.
385 if(this.statisticsManager.getMultipartMessageManager().removeTxId(notification.getTransactionId()) == null)
388 NodeKey key = new NodeKey(notification.getId());
389 sucLogger.debug("Received flow stats update : {}",notification.toString());
391 for(FlowAndStatisticsMapList map: notification.getFlowAndStatisticsMapList()){
392 short tableId = map.getTableId();
394 DataModificationTransaction it = this.statisticsManager.startChange();
396 boolean foundOriginalFlow = false;
398 FlowBuilder flowBuilder = new FlowBuilder();
400 FlowStatisticsDataBuilder flowStatisticsData = new FlowStatisticsDataBuilder();
402 FlowBuilder flow = new FlowBuilder();
403 flow.setContainerName(map.getContainerName());
404 flow.setBufferId(map.getBufferId());
405 flow.setCookie(map.getCookie());
406 flow.setCookieMask(map.getCookieMask());
407 flow.setFlags(map.getFlags());
408 flow.setFlowName(map.getFlowName());
409 flow.setHardTimeout(map.getHardTimeout());
410 if(map.getFlowId() != null)
411 flow.setId(new FlowId(map.getFlowId().getValue()));
412 flow.setIdleTimeout(map.getIdleTimeout());
413 flow.setInstallHw(map.isInstallHw());
414 flow.setInstructions(map.getInstructions());
415 if(map.getFlowId()!= null)
416 flow.setKey(new FlowKey(new FlowId(map.getKey().getFlowId().getValue())));
417 flow.setMatch(map.getMatch());
418 flow.setOutGroup(map.getOutGroup());
419 flow.setOutPort(map.getOutPort());
420 flow.setPriority(map.getPriority());
421 flow.setStrict(map.isStrict());
422 flow.setTableId(tableId);
424 Flow flowRule = flow.build();
426 FlowAndStatisticsMapListBuilder stats = new FlowAndStatisticsMapListBuilder();
427 stats.setByteCount(map.getByteCount());
428 stats.setPacketCount(map.getPacketCount());
429 stats.setDuration(map.getDuration());
431 GenericStatistics flowStats = stats.build();
433 //Add statistics to local cache
434 ConcurrentMap<NodeId, NodeStatistics> cache = this.statisticsManager.getStatisticsCache();
435 if(!cache.containsKey(notification.getId())){
436 cache.put(notification.getId(), new NodeStatistics());
438 if(!cache.get(notification.getId()).getFlowAndStatsMap().containsKey(tableId)){
439 cache.get(notification.getId()).getFlowAndStatsMap().put(tableId, new HashMap<Flow,GenericStatistics>());
441 cache.get(notification.getId()).getFlowAndStatsMap().get(tableId).put(flowRule,flowStats);
443 //Augment the data to the flow node
445 FlowStatisticsBuilder flowStatistics = new FlowStatisticsBuilder();
446 flowStatistics.setByteCount(flowStats.getByteCount());
447 flowStatistics.setPacketCount(flowStats.getPacketCount());
448 flowStatistics.setDuration(flowStats.getDuration());
449 flowStatistics.setContainerName(map.getContainerName());
450 flowStatistics.setBufferId(map.getBufferId());
451 flowStatistics.setCookie(map.getCookie());
452 flowStatistics.setCookieMask(map.getCookieMask());
453 flowStatistics.setFlags(map.getFlags());
454 flowStatistics.setFlowName(map.getFlowName());
455 flowStatistics.setHardTimeout(map.getHardTimeout());
456 flowStatistics.setIdleTimeout(map.getIdleTimeout());
457 flowStatistics.setInstallHw(map.isInstallHw());
458 flowStatistics.setInstructions(map.getInstructions());
459 flowStatistics.setMatch(map.getMatch());
460 flowStatistics.setOutGroup(map.getOutGroup());
461 flowStatistics.setOutPort(map.getOutPort());
462 flowStatistics.setPriority(map.getPriority());
463 flowStatistics.setStrict(map.isStrict());
464 flowStatistics.setTableId(tableId);
466 flowStatisticsData.setFlowStatistics(flowStatistics.build());
468 sucLogger.debug("Flow : {}",flowRule.toString());
469 sucLogger.debug("Statistics to augment : {}",flowStatistics.build().toString());
471 InstanceIdentifier<Table> tableRef = InstanceIdentifier.builder(Nodes.class).child(Node.class, key)
472 .augmentation(FlowCapableNode.class).child(Table.class, new TableKey(tableId)).toInstance();
474 Table table= (Table)it.readConfigurationData(tableRef);
476 //TODO: Not a good way to do it, need to figure out better way.
477 //TODO: major issue in any alternate approach is that flow key is incrementally assigned
478 //to the flows stored in data store.
481 for(Flow existingFlow : table.getFlow()){
482 sucLogger.debug("Existing flow in data store : {}",existingFlow.toString());
483 if(flowEquals(flowRule,existingFlow)){
484 InstanceIdentifier<Flow> flowRef = InstanceIdentifier.builder(Nodes.class).child(Node.class, key)
485 .augmentation(FlowCapableNode.class)
486 .child(Table.class, new TableKey(tableId))
487 .child(Flow.class,existingFlow.getKey()).toInstance();
488 flowBuilder.setKey(existingFlow.getKey());
489 flowBuilder.addAugmentation(FlowStatisticsData.class, flowStatisticsData.build());
490 sucLogger.info("Found matching flow in the datastore, augmenting statistics");
491 foundOriginalFlow = true;
492 it.putOperationalData(flowRef, flowBuilder.build());
499 if(!foundOriginalFlow){
500 sucLogger.debug("Associated original flow is not found in data store. Augmenting flow in operational data store");
501 //TODO: Temporary fix: format [ 1+tableid+1+unaccounted flow counter]
502 long flowKey = Long.parseLong(new String("1"+Short.toString(tableId)+"1"+Integer.toString(this.unaccountedFlowsCounter)));
503 FlowKey newFlowKey = new FlowKey(new FlowId(flowKey));
504 InstanceIdentifier<Flow> flowRef = InstanceIdentifier.builder(Nodes.class).child(Node.class, key)
505 .augmentation(FlowCapableNode.class)
506 .child(Table.class, new TableKey(tableId))
507 .child(Flow.class,newFlowKey).toInstance();
508 flowBuilder.setKey(newFlowKey);
509 flowBuilder.addAugmentation(FlowStatisticsData.class, flowStatisticsData.build());
510 sucLogger.info("Flow was no present in data store, augmenting statistics as an unaccounted flow");
511 it.putOperationalData(flowRef, flowBuilder.build());
518 public void onAggregateFlowStatisticsUpdate(AggregateFlowStatisticsUpdate notification) {
519 //Check if response is for the request statistics-manager sent.
520 if(this.statisticsManager.getMultipartMessageManager().removeTxId(notification.getTransactionId()) == null)
523 NodeKey key = new NodeKey(notification.getId());
524 sucLogger.debug("Received aggregate flow statistics update : {}",notification.toString());
526 Short tableId = this.statisticsManager.getMultipartMessageManager().getTableIdForTxId(notification.getTransactionId());
529 DataModificationTransaction it = this.statisticsManager.startChange();
531 InstanceIdentifier<Table> tableRef = InstanceIdentifier.builder(Nodes.class).child(Node.class, key)
532 .augmentation(FlowCapableNode.class).child(Table.class, new TableKey(tableId)).toInstance();
534 AggregateFlowStatisticsDataBuilder aggregateFlowStatisticsDataBuilder = new AggregateFlowStatisticsDataBuilder();
535 AggregateFlowStatisticsBuilder aggregateFlowStatisticsBuilder = new AggregateFlowStatisticsBuilder();
536 aggregateFlowStatisticsBuilder.setByteCount(notification.getByteCount());
537 aggregateFlowStatisticsBuilder.setFlowCount(notification.getFlowCount());
538 aggregateFlowStatisticsBuilder.setPacketCount(notification.getPacketCount());
539 aggregateFlowStatisticsDataBuilder.setAggregateFlowStatistics(aggregateFlowStatisticsBuilder.build());
541 ConcurrentMap<NodeId, NodeStatistics> cache = this.statisticsManager.getStatisticsCache();
542 if(!cache.containsKey(notification.getId())){
543 cache.put(notification.getId(), new NodeStatistics());
545 cache.get(notification.getId()).getTableAndAggregateFlowStatsMap().put(tableId,aggregateFlowStatisticsBuilder.build());
547 sucLogger.debug("Augment aggregate statistics: {} for table {} on Node {}",aggregateFlowStatisticsBuilder.build().toString(),tableId,key);
549 TableBuilder tableBuilder = new TableBuilder();
550 tableBuilder.setKey(new TableKey(tableId));
551 tableBuilder.addAugmentation(AggregateFlowStatisticsData.class, aggregateFlowStatisticsDataBuilder.build());
552 it.putOperationalData(tableRef, tableBuilder.build());
559 public void onNodeConnectorStatisticsUpdate(NodeConnectorStatisticsUpdate notification) {
560 //Check if response is for the request statistics-manager sent.
561 if(this.statisticsManager.getMultipartMessageManager().removeTxId(notification.getTransactionId()) == null)
564 NodeKey key = new NodeKey(notification.getId());
565 sucLogger.debug("Received port stats update : {}",notification.toString());
567 //Add statistics to local cache
568 ConcurrentMap<NodeId, NodeStatistics> cache = this.statisticsManager.getStatisticsCache();
569 if(!cache.containsKey(notification.getId())){
570 cache.put(notification.getId(), new NodeStatistics());
574 List<NodeConnectorStatisticsAndPortNumberMap> portsStats = notification.getNodeConnectorStatisticsAndPortNumberMap();
575 for(NodeConnectorStatisticsAndPortNumberMap portStats : portsStats){
577 DataModificationTransaction it = this.statisticsManager.startChange();
579 FlowCapableNodeConnectorStatisticsBuilder statisticsBuilder
580 = new FlowCapableNodeConnectorStatisticsBuilder();
581 statisticsBuilder.setBytes(portStats.getBytes());
582 statisticsBuilder.setCollisionCount(portStats.getCollisionCount());
583 statisticsBuilder.setDuration(portStats.getDuration());
584 statisticsBuilder.setPackets(portStats.getPackets());
585 statisticsBuilder.setReceiveCrcError(portStats.getReceiveCrcError());
586 statisticsBuilder.setReceiveDrops(portStats.getReceiveDrops());
587 statisticsBuilder.setReceiveErrors(portStats.getReceiveErrors());
588 statisticsBuilder.setReceiveFrameError(portStats.getReceiveFrameError());
589 statisticsBuilder.setReceiveOverRunError(portStats.getReceiveOverRunError());
590 statisticsBuilder.setTransmitDrops(portStats.getTransmitDrops());
591 statisticsBuilder.setTransmitErrors(portStats.getTransmitErrors());
593 //Update data in the cache
594 cache.get(notification.getId()).getNodeConnectorStats().put(portStats.getNodeConnectorId(), statisticsBuilder.build());
596 //Augment data to the node-connector
597 FlowCapableNodeConnectorStatisticsDataBuilder statisticsDataBuilder =
598 new FlowCapableNodeConnectorStatisticsDataBuilder();
600 statisticsDataBuilder.setFlowCapableNodeConnectorStatistics(statisticsBuilder.build());
602 InstanceIdentifier<NodeConnector> nodeConnectorRef = InstanceIdentifier.builder(Nodes.class).child(Node.class, key).child(NodeConnector.class, new NodeConnectorKey(portStats.getNodeConnectorId())).toInstance();
604 NodeConnector nodeConnector = (NodeConnector)it.readOperationalData(nodeConnectorRef);
606 if(nodeConnector != null){
607 sucLogger.debug("Augmenting port statistics {} to port {}",statisticsDataBuilder.build().toString(),nodeConnectorRef.toString());
608 NodeConnectorBuilder nodeConnectorBuilder = new NodeConnectorBuilder();
609 nodeConnectorBuilder.addAugmentation(FlowCapableNodeConnectorStatisticsData.class, statisticsDataBuilder.build());
610 it.putOperationalData(nodeConnectorRef, nodeConnectorBuilder.build());
617 public void onFlowTableStatisticsUpdate(FlowTableStatisticsUpdate notification) {
618 //Check if response is for the request statistics-manager sent.
619 if(this.statisticsManager.getMultipartMessageManager().removeTxId(notification.getTransactionId()) == null)
622 NodeKey key = new NodeKey(notification.getId());
623 sucLogger.debug("Received flow table statistics update : {}",notification.toString());
625 List<FlowTableAndStatisticsMap> flowTablesStatsList = notification.getFlowTableAndStatisticsMap();
626 for (FlowTableAndStatisticsMap ftStats : flowTablesStatsList){
628 DataModificationTransaction it = this.statisticsManager.startChange();
630 InstanceIdentifier<Table> tableRef = InstanceIdentifier.builder(Nodes.class).child(Node.class, key)
631 .augmentation(FlowCapableNode.class).child(Table.class, new TableKey(ftStats.getTableId().getValue())).toInstance();
633 FlowTableStatisticsDataBuilder statisticsDataBuilder = new FlowTableStatisticsDataBuilder();
635 FlowTableStatisticsBuilder statisticsBuilder = new FlowTableStatisticsBuilder();
636 statisticsBuilder.setActiveFlows(ftStats.getActiveFlows());
637 statisticsBuilder.setPacketsLookedUp(ftStats.getPacketsLookedUp());
638 statisticsBuilder.setPacketsMatched(ftStats.getPacketsMatched());
640 statisticsDataBuilder.setFlowTableStatistics(statisticsBuilder.build());
642 ConcurrentMap<NodeId, NodeStatistics> cache = this.statisticsManager.getStatisticsCache();
643 if(!cache.containsKey(notification.getId())){
644 cache.put(notification.getId(), new NodeStatistics());
646 cache.get(notification.getId()).getFlowTableAndStatisticsMap().put(ftStats.getTableId().getValue(),statisticsBuilder.build());
648 sucLogger.debug("Augment flow table statistics: {} for table {} on Node {}",statisticsBuilder.build().toString(),ftStats.getTableId(),key);
650 TableBuilder tableBuilder = new TableBuilder();
651 tableBuilder.setKey(new TableKey(ftStats.getTableId().getValue()));
652 tableBuilder.addAugmentation(FlowTableStatisticsData.class, statisticsDataBuilder.build());
653 it.putOperationalData(tableRef, tableBuilder.build());
659 public void onQueueStatisticsUpdate(QueueStatisticsUpdate notification) {
661 //Check if response is for the request statistics-manager sent.
662 if(this.statisticsManager.getMultipartMessageManager().removeTxId(notification.getTransactionId()) == null)
665 NodeKey key = new NodeKey(notification.getId());
666 sucLogger.debug("Received queue stats update : {}",notification.toString());
668 //Add statistics to local cache
669 ConcurrentMap<NodeId, NodeStatistics> cache = this.statisticsManager.getStatisticsCache();
670 if(!cache.containsKey(notification.getId())){
671 cache.put(notification.getId(), new NodeStatistics());
674 List<QueueIdAndStatisticsMap> queuesStats = notification.getQueueIdAndStatisticsMap();
675 for(QueueIdAndStatisticsMap swQueueStats : queuesStats){
677 if(!cache.get(notification.getId()).getNodeConnectorAndQueuesStatsMap().containsKey(swQueueStats.getNodeConnectorId())){
678 cache.get(notification.getId()).getNodeConnectorAndQueuesStatsMap().put(swQueueStats.getNodeConnectorId(), new HashMap<QueueId,GenericQueueStatistics>());
681 FlowCapableNodeConnectorQueueStatisticsDataBuilder queueStatisticsDataBuilder = new FlowCapableNodeConnectorQueueStatisticsDataBuilder();
683 FlowCapableNodeConnectorQueueStatisticsBuilder queueStatisticsBuilder = new FlowCapableNodeConnectorQueueStatisticsBuilder();
685 queueStatisticsBuilder.fieldsFrom(swQueueStats);
687 queueStatisticsDataBuilder.setFlowCapableNodeConnectorQueueStatistics(queueStatisticsBuilder.build());
689 cache.get(notification.getId()).getNodeConnectorAndQueuesStatsMap()
690 .get(swQueueStats.getNodeConnectorId())
691 .put(swQueueStats.getQueueId(), queueStatisticsBuilder.build());
694 DataModificationTransaction it = this.statisticsManager.startChange();
696 InstanceIdentifier<Queue> queueRef
697 = InstanceIdentifier.builder(Nodes.class)
698 .child(Node.class, key)
699 .child(NodeConnector.class, new NodeConnectorKey(swQueueStats.getNodeConnectorId()))
700 .augmentation(FlowCapableNodeConnector.class)
701 .child(Queue.class, new QueueKey(swQueueStats.getQueueId())).toInstance();
703 QueueBuilder queueBuilder = new QueueBuilder();
704 queueBuilder.addAugmentation(FlowCapableNodeConnectorQueueStatisticsData.class, queueStatisticsDataBuilder.build());
705 queueBuilder.setKey(new QueueKey(swQueueStats.getQueueId()));
707 sucLogger.info("Augmenting queue statistics {} of queue {} to port {}"
708 ,queueStatisticsDataBuilder.build().toString(),
709 swQueueStats.getQueueId(),
710 swQueueStats.getNodeConnectorId());
712 it.putOperationalData(queueRef, queueBuilder.build());
719 private NodeRef getNodeRef(NodeKey nodeKey){
720 InstanceIdentifierBuilder<?> builder = InstanceIdentifier.builder(Nodes.class).child(Node.class, nodeKey);
721 return new NodeRef(builder.toInstance());
724 public boolean flowEquals(Flow statsFlow, Flow storedFlow) {
725 if (statsFlow.getClass() != storedFlow.getClass()) {
728 if (statsFlow.getBufferId()== null) {
729 if (storedFlow.getBufferId() != null) {
732 } else if(!statsFlow.getBufferId().equals(storedFlow.getBufferId())) {
735 if (statsFlow.getContainerName()== null) {
736 if (storedFlow.getContainerName()!= null) {
739 } else if(!statsFlow.getContainerName().equals(storedFlow.getContainerName())) {
742 if (statsFlow.getCookie()== null) {
743 if (storedFlow.getCookie()!= null) {
746 } else if(!statsFlow.getCookie().equals(storedFlow.getCookie())) {
749 if (statsFlow.getMatch()== null) {
750 if (storedFlow.getMatch() != null) {
753 } //else if(!statsFlow.getMatch().equals(storedFlow.getMatch())) {
754 else if(!matchEquals(statsFlow.getMatch(), storedFlow.getMatch())) {
757 if (statsFlow.getHardTimeout() == null) {
758 if (storedFlow.getHardTimeout() != null) {
761 } else if(!statsFlow.getHardTimeout().equals(storedFlow.getHardTimeout() )) {
764 if (statsFlow.getIdleTimeout()== null) {
765 if (storedFlow.getIdleTimeout() != null) {
768 } else if(!statsFlow.getIdleTimeout().equals(storedFlow.getIdleTimeout())) {
771 if (statsFlow.getPriority() == null) {
772 if (storedFlow.getPriority() != null) {
775 } else if(!statsFlow.getPriority().equals(storedFlow.getPriority())) {
778 if (statsFlow.getTableId() == null) {
779 if (storedFlow.getTableId() != null) {
782 } else if(!statsFlow.getTableId().equals(storedFlow.getTableId())) {
789 * Explicit equals method to compare the 'match' for flows stored in the data-stores and flow fetched from the switch.
790 * Usecase: e.g If user don't set any ethernet source and destination address for match,data store will store null for
792 * e.g [_ethernetMatch=EthernetMatch [_ethernetDestination=null, _ethernetSource=null, _ethernetType=
793 * EthernetType [_type=EtherType [_value=2048], _mask=null, augmentation=[]]
795 * But when you fetch the flows from switch, openflow driver library converts all zero bytes of mac address in the
796 * message stream to 00:00:00:00:00:00. Following string shows how library interpret the zero mac address bytes and
797 * eventually when translator convert it to MD-SAL match, this is how it looks
798 * [_ethernetDestination=EthernetDestination [_address=MacAddress [_value=00:00:00:00:00:00], _mask=null, augmentation=[]],
799 * _ethernetSource=EthernetSource [_address=MacAddress [_value=00:00:00:00:00:00], _mask=null, augmentation=[]],
800 * _ethernetType=EthernetType [_type=EtherType [_value=2048], _mask=null, augmentation=[]]
802 * Similarly for inPort, if user/application don't set any value for it, FRM will store null value for it in data store.
803 * When we fetch the same flow (with its statistics) from switch, plugin converts its value to openflow:X:0.
804 * e.g _inPort=Uri [_value=openflow:1:0]
806 * So this custom equals method add additional check to take care of these scenario, in case any match element is null in data-store-flow, but not
807 * in the flow fetched from switch.
813 public boolean matchEquals(Match statsFlow, Match storedFlow) {
814 if (statsFlow == storedFlow) {
817 if (storedFlow.getClass() != statsFlow.getClass()) {
820 if (storedFlow.getEthernetMatch() == null) {
821 if (statsFlow.getEthernetMatch() != null) {
822 if(!statsFlow.getEthernetMatch().getEthernetDestination().getAddress().getValue().equals("00:00:00:00:00:00") ||
823 !statsFlow.getEthernetMatch().getEthernetSource().getAddress().getValue().equals("00:00:00:00:00:00")){
827 } else if(!EthernetMatchEquals(statsFlow.getEthernetMatch(),storedFlow.getEthernetMatch())) {
830 if (storedFlow.getIcmpv4Match()== null) {
831 if (statsFlow.getIcmpv4Match() != null) {
834 } else if(!storedFlow.getIcmpv4Match().equals(statsFlow.getIcmpv4Match())) {
837 if (storedFlow.getIcmpv6Match() == null) {
838 if (statsFlow.getIcmpv6Match() != null) {
841 } else if(!storedFlow.getIcmpv6Match().equals(statsFlow.getIcmpv6Match())) {
844 if (storedFlow.getInPhyPort() == null) {
845 if (statsFlow.getInPhyPort() != null) {
848 } else if(!storedFlow.getInPhyPort().equals(statsFlow.getInPhyPort())) {
851 if (storedFlow.getInPort()== null) {
852 if (statsFlow.getInPort() != null) {
853 String[] portArr = statsFlow.getInPort().getValue().split(":");
854 if(portArr.length >= 3){
855 if(Integer.parseInt(portArr[2]) != 0){
860 } else if(!storedFlow.getInPort().equals(statsFlow.getInPort())) {
863 if (storedFlow.getIpMatch()== null) {
864 if (statsFlow.getIpMatch() != null) {
867 } else if(!storedFlow.getIpMatch().equals(statsFlow.getIpMatch())) {
870 if (storedFlow.getLayer3Match()== null) {
871 if (statsFlow.getLayer3Match() != null) {
872 Ipv4Match ipv4Match = (Ipv4Match)statsFlow.getLayer3Match();
873 if(!ipv4Match.getIpv4Source().getValue().equals("0.0.0.0/0") ||
874 !ipv4Match.getIpv4Destination().getValue().equals("0.0.0.0/0")){
878 } else if(!storedFlow.getLayer3Match().equals(statsFlow.getLayer3Match())) {
881 if (storedFlow.getLayer4Match()== null) {
882 if (statsFlow.getLayer4Match() != null) {
883 TcpMatch tcpMatch = (TcpMatch)statsFlow.getLayer4Match();
884 if(!tcpMatch.getTcpDestinationPort().getValue().equals(0) ||
885 !tcpMatch.getTcpSourcePort().getValue().equals(0)){
889 } else if(!storedFlow.getLayer4Match().equals(statsFlow.getLayer4Match())) {
892 if (storedFlow.getMetadata() == null) {
893 if (statsFlow.getMetadata() != null) {
896 } else if(!storedFlow.getMetadata().equals(statsFlow.getMetadata())) {
899 if (storedFlow.getProtocolMatchFields() == null) {
900 if (statsFlow.getProtocolMatchFields() != null) {
903 } else if(!storedFlow.getProtocolMatchFields().equals(statsFlow.getProtocolMatchFields())) {
906 if (storedFlow.getTunnel()== null) {
907 if (statsFlow.getTunnel() != null) {
910 } else if(!storedFlow.getTunnel().equals(statsFlow.getTunnel())) {
913 if (storedFlow.getVlanMatch()== null) {
914 if (statsFlow.getVlanMatch() != null) {
915 VlanMatch vlanMatch = statsFlow.getVlanMatch();
916 if(!vlanMatch.getVlanId().getVlanId().getValue().equals(0) ||
917 !vlanMatch.getVlanPcp().getValue().equals((short)0)){
921 } else if(!storedFlow.getVlanMatch().equals(statsFlow.getVlanMatch())) {
927 public boolean EthernetMatchEquals(EthernetMatch statsEtherMatch, EthernetMatch storedEtherMatch) {
928 if (statsEtherMatch == storedEtherMatch) {
931 if (storedEtherMatch.getEthernetDestination()== null) {
932 if (statsEtherMatch.getEthernetDestination() != null) {
933 if(!statsEtherMatch.getEthernetDestination().getAddress().getValue().equals("00:00:00:00:00:00")){
937 } else if(!storedEtherMatch.getEthernetDestination().equals(statsEtherMatch.getEthernetDestination())) {
940 if (storedEtherMatch.getEthernetSource() == null) {
941 if (statsEtherMatch.getEthernetSource() != null) {
942 if(!statsEtherMatch.getEthernetSource().getAddress().getValue().equals("00:00:00:00:00:00")){
946 } else if(!storedEtherMatch.getEthernetSource().equals(statsEtherMatch.getEthernetSource())) {
949 if (storedEtherMatch.getEthernetType() == null) {
950 if (statsEtherMatch.getEthernetType() != null) {
951 if(!statsEtherMatch.getEthernetType().getType().getValue().equals(0)){
955 } else if(!storedEtherMatch.getEthernetType().equals(statsEtherMatch.getEthernetType())) {