Madan Jampani | c27b6b2 | 2016-02-05 11:36:31 -0800 | [diff] [blame] | 1 | /* |
Brian O'Connor | a09fe5b | 2017-08-03 21:12:30 -0700 | [diff] [blame] | 2 | * Copyright 2015-present Open Networking Foundation |
Madan Jampani | c27b6b2 | 2016-02-05 11:36:31 -0800 | [diff] [blame] | 3 | * |
| 4 | * Licensed under the Apache License, Version 2.0 (the "License"); |
| 5 | * you may not use this file except in compliance with the License. |
| 6 | * You may obtain a copy of the License at |
| 7 | * |
| 8 | * http://www.apache.org/licenses/LICENSE-2.0 |
| 9 | * |
| 10 | * Unless required by applicable law or agreed to in writing, software |
| 11 | * distributed under the License is distributed on an "AS IS" BASIS, |
| 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
| 13 | * See the License for the specific language governing permissions and |
| 14 | * limitations under the License. |
| 15 | */ |
| 16 | |
| 17 | package org.onosproject.net.statistic.impl; |
| 18 | |
Ray Milkey | d84f89b | 2018-08-17 14:54:17 -0700 | [diff] [blame] | 19 | import com.google.common.base.MoreObjects; |
| 20 | import com.google.common.base.Predicate; |
| 21 | import com.google.common.collect.ImmutableSet; |
Madan Jampani | c27b6b2 | 2016-02-05 11:36:31 -0800 | [diff] [blame] | 22 | import org.onosproject.net.ConnectPoint; |
| 23 | import org.onosproject.net.Device; |
| 24 | import org.onosproject.net.Port; |
| 25 | import org.onosproject.net.PortNumber; |
| 26 | import org.onosproject.net.device.DeviceService; |
Sangsik Yoon | b1b823f | 2016-05-16 18:55:39 +0900 | [diff] [blame] | 27 | import org.onosproject.net.flow.DefaultFlowEntry; |
Madan Jampani | c27b6b2 | 2016-02-05 11:36:31 -0800 | [diff] [blame] | 28 | import org.onosproject.net.flow.DefaultTypedFlowEntry; |
| 29 | import org.onosproject.net.flow.FlowEntry; |
| 30 | import org.onosproject.net.flow.FlowRule; |
Sangsik Yoon | b1b823f | 2016-05-16 18:55:39 +0900 | [diff] [blame] | 31 | import org.onosproject.net.flow.StoredFlowEntry; |
Madan Jampani | c27b6b2 | 2016-02-05 11:36:31 -0800 | [diff] [blame] | 32 | import org.onosproject.net.flow.TypedStoredFlowEntry; |
| 33 | import org.onosproject.net.flow.instructions.Instruction; |
| 34 | import org.onosproject.net.statistic.DefaultLoad; |
Sangsik Yoon | b1b823f | 2016-05-16 18:55:39 +0900 | [diff] [blame] | 35 | import org.onosproject.net.statistic.FlowEntryWithLoad; |
Madan Jampani | c27b6b2 | 2016-02-05 11:36:31 -0800 | [diff] [blame] | 36 | import org.onosproject.net.statistic.FlowStatisticService; |
| 37 | import org.onosproject.net.statistic.Load; |
Sangsik Yoon | b1b823f | 2016-05-16 18:55:39 +0900 | [diff] [blame] | 38 | import org.onosproject.net.statistic.PollInterval; |
| 39 | import org.onosproject.net.statistic.StatisticStore; |
Madan Jampani | c27b6b2 | 2016-02-05 11:36:31 -0800 | [diff] [blame] | 40 | import org.onosproject.net.statistic.SummaryFlowEntryWithLoad; |
| 41 | import org.onosproject.net.statistic.TypedFlowEntryWithLoad; |
Ray Milkey | a695719 | 2017-06-01 13:04:16 -0700 | [diff] [blame] | 42 | import org.onosproject.utils.Comparators; |
Ray Milkey | d84f89b | 2018-08-17 14:54:17 -0700 | [diff] [blame] | 43 | import org.osgi.service.component.annotations.Activate; |
| 44 | import org.osgi.service.component.annotations.Component; |
| 45 | import org.osgi.service.component.annotations.Deactivate; |
| 46 | import org.osgi.service.component.annotations.Reference; |
| 47 | import org.osgi.service.component.annotations.ReferenceCardinality; |
Madan Jampani | c27b6b2 | 2016-02-05 11:36:31 -0800 | [diff] [blame] | 48 | import org.slf4j.Logger; |
| 49 | |
Ray Milkey | d84f89b | 2018-08-17 14:54:17 -0700 | [diff] [blame] | 50 | import java.util.ArrayList; |
| 51 | import java.util.HashMap; |
| 52 | import java.util.List; |
| 53 | import java.util.Map; |
| 54 | import java.util.Objects; |
| 55 | import java.util.Set; |
| 56 | import java.util.TreeMap; |
| 57 | import java.util.stream.Collectors; |
Madan Jampani | c27b6b2 | 2016-02-05 11:36:31 -0800 | [diff] [blame] | 58 | |
| 59 | import static com.google.common.base.Preconditions.checkNotNull; |
| 60 | import static org.onosproject.security.AppGuard.checkPermission; |
Ray Milkey | a695719 | 2017-06-01 13:04:16 -0700 | [diff] [blame] | 61 | import static org.onosproject.security.AppPermission.Type.STATISTIC_READ; |
Madan Jampani | c27b6b2 | 2016-02-05 11:36:31 -0800 | [diff] [blame] | 62 | import static org.slf4j.LoggerFactory.getLogger; |
Madan Jampani | c27b6b2 | 2016-02-05 11:36:31 -0800 | [diff] [blame] | 63 | |
| 64 | /** |
| 65 | * Provides an implementation of the Flow Statistic Service. |
| 66 | */ |
Ray Milkey | d84f89b | 2018-08-17 14:54:17 -0700 | [diff] [blame] | 67 | @Component(immediate = true, service = FlowStatisticService.class) |
Madan Jampani | c27b6b2 | 2016-02-05 11:36:31 -0800 | [diff] [blame] | 68 | public class FlowStatisticManager implements FlowStatisticService { |
| 69 | private final Logger log = getLogger(getClass()); |
| 70 | |
Ray Milkey | d84f89b | 2018-08-17 14:54:17 -0700 | [diff] [blame] | 71 | @Reference(cardinality = ReferenceCardinality.MANDATORY) |
Sangsik Yoon | b1b823f | 2016-05-16 18:55:39 +0900 | [diff] [blame] | 72 | protected StatisticStore statisticStore; |
Madan Jampani | c27b6b2 | 2016-02-05 11:36:31 -0800 | [diff] [blame] | 73 | |
Ray Milkey | d84f89b | 2018-08-17 14:54:17 -0700 | [diff] [blame] | 74 | @Reference(cardinality = ReferenceCardinality.MANDATORY) |
Madan Jampani | c27b6b2 | 2016-02-05 11:36:31 -0800 | [diff] [blame] | 75 | protected DeviceService deviceService; |
| 76 | |
Madan Jampani | c27b6b2 | 2016-02-05 11:36:31 -0800 | [diff] [blame] | 77 | @Activate |
| 78 | public void activate() { |
Madan Jampani | c27b6b2 | 2016-02-05 11:36:31 -0800 | [diff] [blame] | 79 | log.info("Started"); |
| 80 | } |
| 81 | |
| 82 | @Deactivate |
| 83 | public void deactivate() { |
Madan Jampani | c27b6b2 | 2016-02-05 11:36:31 -0800 | [diff] [blame] | 84 | log.info("Stopped"); |
| 85 | } |
| 86 | |
| 87 | @Override |
| 88 | public Map<ConnectPoint, SummaryFlowEntryWithLoad> loadSummary(Device device) { |
| 89 | checkPermission(STATISTIC_READ); |
| 90 | |
Sangsik Yoon | b1b823f | 2016-05-16 18:55:39 +0900 | [diff] [blame] | 91 | Map<ConnectPoint, SummaryFlowEntryWithLoad> summaryLoad = |
| 92 | new TreeMap<>(Comparators.CONNECT_POINT_COMPARATOR); |
Madan Jampani | c27b6b2 | 2016-02-05 11:36:31 -0800 | [diff] [blame] | 93 | |
| 94 | if (device == null) { |
| 95 | return summaryLoad; |
| 96 | } |
| 97 | |
| 98 | List<Port> ports = new ArrayList<>(deviceService.getPorts(device.id())); |
| 99 | |
| 100 | for (Port port : ports) { |
| 101 | ConnectPoint cp = new ConnectPoint(device.id(), port.number()); |
| 102 | SummaryFlowEntryWithLoad sfe = loadSummaryPortInternal(cp); |
| 103 | summaryLoad.put(cp, sfe); |
| 104 | } |
| 105 | |
| 106 | return summaryLoad; |
| 107 | } |
| 108 | |
| 109 | @Override |
| 110 | public SummaryFlowEntryWithLoad loadSummary(Device device, PortNumber pNumber) { |
| 111 | checkPermission(STATISTIC_READ); |
| 112 | |
| 113 | ConnectPoint cp = new ConnectPoint(device.id(), pNumber); |
| 114 | return loadSummaryPortInternal(cp); |
| 115 | } |
| 116 | |
| 117 | @Override |
Sangsik Yoon | b1b823f | 2016-05-16 18:55:39 +0900 | [diff] [blame] | 118 | public Map<ConnectPoint, List<FlowEntryWithLoad>> loadAllByType(Device device, |
| 119 | FlowEntry.FlowLiveType liveType, |
Madan Jampani | c27b6b2 | 2016-02-05 11:36:31 -0800 | [diff] [blame] | 120 | Instruction.Type instType) { |
| 121 | checkPermission(STATISTIC_READ); |
| 122 | |
Sangsik Yoon | b1b823f | 2016-05-16 18:55:39 +0900 | [diff] [blame] | 123 | Map<ConnectPoint, List<FlowEntryWithLoad>> allLoad = |
| 124 | new TreeMap<>(Comparators.CONNECT_POINT_COMPARATOR); |
Madan Jampani | c27b6b2 | 2016-02-05 11:36:31 -0800 | [diff] [blame] | 125 | |
| 126 | if (device == null) { |
| 127 | return allLoad; |
| 128 | } |
| 129 | |
| 130 | List<Port> ports = new ArrayList<>(deviceService.getPorts(device.id())); |
| 131 | |
| 132 | for (Port port : ports) { |
| 133 | ConnectPoint cp = new ConnectPoint(device.id(), port.number()); |
Sangsik Yoon | b1b823f | 2016-05-16 18:55:39 +0900 | [diff] [blame] | 134 | List<FlowEntryWithLoad> fel = loadAllPortInternal(cp, liveType, instType); |
| 135 | allLoad.put(cp, fel); |
Madan Jampani | c27b6b2 | 2016-02-05 11:36:31 -0800 | [diff] [blame] | 136 | } |
| 137 | |
| 138 | return allLoad; |
| 139 | } |
| 140 | |
| 141 | @Override |
Sangsik Yoon | b1b823f | 2016-05-16 18:55:39 +0900 | [diff] [blame] | 142 | public List<FlowEntryWithLoad> loadAllByType(Device device, PortNumber pNumber, |
| 143 | FlowEntry.FlowLiveType liveType, |
Madan Jampani | c27b6b2 | 2016-02-05 11:36:31 -0800 | [diff] [blame] | 144 | Instruction.Type instType) { |
| 145 | checkPermission(STATISTIC_READ); |
| 146 | |
| 147 | ConnectPoint cp = new ConnectPoint(device.id(), pNumber); |
| 148 | return loadAllPortInternal(cp, liveType, instType); |
| 149 | } |
| 150 | |
| 151 | @Override |
Sangsik Yoon | b1b823f | 2016-05-16 18:55:39 +0900 | [diff] [blame] | 152 | public Map<ConnectPoint, List<FlowEntryWithLoad>> loadTopnByType(Device device, |
| 153 | FlowEntry.FlowLiveType liveType, |
Madan Jampani | c27b6b2 | 2016-02-05 11:36:31 -0800 | [diff] [blame] | 154 | Instruction.Type instType, |
| 155 | int topn) { |
| 156 | checkPermission(STATISTIC_READ); |
| 157 | |
Sangsik Yoon | b1b823f | 2016-05-16 18:55:39 +0900 | [diff] [blame] | 158 | Map<ConnectPoint, List<FlowEntryWithLoad>> allLoad = |
| 159 | new TreeMap<>(Comparators.CONNECT_POINT_COMPARATOR); |
Madan Jampani | c27b6b2 | 2016-02-05 11:36:31 -0800 | [diff] [blame] | 160 | |
| 161 | if (device == null) { |
| 162 | return allLoad; |
| 163 | } |
| 164 | |
| 165 | List<Port> ports = new ArrayList<>(deviceService.getPorts(device.id())); |
| 166 | |
| 167 | for (Port port : ports) { |
| 168 | ConnectPoint cp = new ConnectPoint(device.id(), port.number()); |
Sangsik Yoon | b1b823f | 2016-05-16 18:55:39 +0900 | [diff] [blame] | 169 | List<FlowEntryWithLoad> fel = loadTopnPortInternal(cp, liveType, instType, topn); |
| 170 | allLoad.put(cp, fel); |
Madan Jampani | c27b6b2 | 2016-02-05 11:36:31 -0800 | [diff] [blame] | 171 | } |
| 172 | |
| 173 | return allLoad; |
| 174 | } |
| 175 | |
| 176 | @Override |
Sangsik Yoon | b1b823f | 2016-05-16 18:55:39 +0900 | [diff] [blame] | 177 | public List<FlowEntryWithLoad> loadTopnByType(Device device, PortNumber pNumber, |
| 178 | FlowEntry.FlowLiveType liveType, |
Madan Jampani | c27b6b2 | 2016-02-05 11:36:31 -0800 | [diff] [blame] | 179 | Instruction.Type instType, |
| 180 | int topn) { |
| 181 | checkPermission(STATISTIC_READ); |
| 182 | |
| 183 | ConnectPoint cp = new ConnectPoint(device.id(), pNumber); |
| 184 | return loadTopnPortInternal(cp, liveType, instType, topn); |
| 185 | } |
| 186 | |
| 187 | private SummaryFlowEntryWithLoad loadSummaryPortInternal(ConnectPoint cp) { |
| 188 | checkPermission(STATISTIC_READ); |
| 189 | |
| 190 | Set<FlowEntry> currentStats; |
| 191 | Set<FlowEntry> previousStats; |
| 192 | |
| 193 | TypedStatistics typedStatistics; |
Sangsik Yoon | b1b823f | 2016-05-16 18:55:39 +0900 | [diff] [blame] | 194 | synchronized (statisticStore) { |
| 195 | currentStats = statisticStore.getCurrentStatistic(cp); |
Madan Jampani | c27b6b2 | 2016-02-05 11:36:31 -0800 | [diff] [blame] | 196 | if (currentStats == null) { |
| 197 | return new SummaryFlowEntryWithLoad(cp, new DefaultLoad()); |
| 198 | } |
Sangsik Yoon | b1b823f | 2016-05-16 18:55:39 +0900 | [diff] [blame] | 199 | previousStats = statisticStore.getPreviousStatistic(cp); |
Madan Jampani | c27b6b2 | 2016-02-05 11:36:31 -0800 | [diff] [blame] | 200 | if (previousStats == null) { |
| 201 | return new SummaryFlowEntryWithLoad(cp, new DefaultLoad()); |
| 202 | } |
| 203 | // copy to local flow entry |
| 204 | typedStatistics = new TypedStatistics(currentStats, previousStats); |
| 205 | |
| 206 | // Check for validity of this stats data |
| 207 | checkLoadValidity(currentStats, previousStats); |
| 208 | } |
| 209 | |
| 210 | // current and previous set is not empty! |
| 211 | Set<FlowEntry> currentSet = typedStatistics.current(); |
| 212 | Set<FlowEntry> previousSet = typedStatistics.previous(); |
Sangsik Yoon | b1b823f | 2016-05-16 18:55:39 +0900 | [diff] [blame] | 213 | PollInterval pollIntervalInstance = PollInterval.getInstance(); |
Madan Jampani | c27b6b2 | 2016-02-05 11:36:31 -0800 | [diff] [blame] | 214 | |
Sangsik Yoon | b1b823f | 2016-05-16 18:55:39 +0900 | [diff] [blame] | 215 | // We assume that default pollInterval is flowPollFrequency in case adaptiveFlowSampling is true or false |
| 216 | Load totalLoad = new DefaultLoad(aggregateBytesSet(currentSet), aggregateBytesSet(previousSet), |
| 217 | pollIntervalInstance.getPollInterval()); |
| 218 | |
| 219 | Map<FlowRule, FlowEntry> currentMap; |
| 220 | Map<FlowRule, FlowEntry> previousMap; |
Madan Jampani | c27b6b2 | 2016-02-05 11:36:31 -0800 | [diff] [blame] | 221 | |
| 222 | currentMap = typedStatistics.currentImmediate(); |
| 223 | previousMap = typedStatistics.previousImmediate(); |
| 224 | Load immediateLoad = new DefaultLoad(aggregateBytesMap(currentMap), aggregateBytesMap(previousMap), |
Sangsik Yoon | b1b823f | 2016-05-16 18:55:39 +0900 | [diff] [blame] | 225 | pollIntervalInstance.getPollInterval()); |
Madan Jampani | c27b6b2 | 2016-02-05 11:36:31 -0800 | [diff] [blame] | 226 | |
| 227 | currentMap = typedStatistics.currentShort(); |
| 228 | previousMap = typedStatistics.previousShort(); |
| 229 | Load shortLoad = new DefaultLoad(aggregateBytesMap(currentMap), aggregateBytesMap(previousMap), |
Sangsik Yoon | b1b823f | 2016-05-16 18:55:39 +0900 | [diff] [blame] | 230 | pollIntervalInstance.getPollInterval()); |
Madan Jampani | c27b6b2 | 2016-02-05 11:36:31 -0800 | [diff] [blame] | 231 | |
| 232 | currentMap = typedStatistics.currentMid(); |
| 233 | previousMap = typedStatistics.previousMid(); |
| 234 | Load midLoad = new DefaultLoad(aggregateBytesMap(currentMap), aggregateBytesMap(previousMap), |
Sangsik Yoon | b1b823f | 2016-05-16 18:55:39 +0900 | [diff] [blame] | 235 | pollIntervalInstance.getMidPollInterval()); |
Madan Jampani | c27b6b2 | 2016-02-05 11:36:31 -0800 | [diff] [blame] | 236 | |
| 237 | currentMap = typedStatistics.currentLong(); |
| 238 | previousMap = typedStatistics.previousLong(); |
| 239 | Load longLoad = new DefaultLoad(aggregateBytesMap(currentMap), aggregateBytesMap(previousMap), |
Sangsik Yoon | b1b823f | 2016-05-16 18:55:39 +0900 | [diff] [blame] | 240 | pollIntervalInstance.getLongPollInterval()); |
Madan Jampani | c27b6b2 | 2016-02-05 11:36:31 -0800 | [diff] [blame] | 241 | |
| 242 | currentMap = typedStatistics.currentUnknown(); |
| 243 | previousMap = typedStatistics.previousUnknown(); |
| 244 | Load unknownLoad = new DefaultLoad(aggregateBytesMap(currentMap), aggregateBytesMap(previousMap), |
Sangsik Yoon | b1b823f | 2016-05-16 18:55:39 +0900 | [diff] [blame] | 245 | pollIntervalInstance.getPollInterval()); |
Madan Jampani | c27b6b2 | 2016-02-05 11:36:31 -0800 | [diff] [blame] | 246 | |
| 247 | return new SummaryFlowEntryWithLoad(cp, totalLoad, immediateLoad, shortLoad, midLoad, longLoad, unknownLoad); |
| 248 | } |
| 249 | |
Sangsik Yoon | b1b823f | 2016-05-16 18:55:39 +0900 | [diff] [blame] | 250 | private List<FlowEntryWithLoad> loadAllPortInternal(ConnectPoint cp, |
| 251 | FlowEntry.FlowLiveType liveType, |
Madan Jampani | c27b6b2 | 2016-02-05 11:36:31 -0800 | [diff] [blame] | 252 | Instruction.Type instType) { |
| 253 | checkPermission(STATISTIC_READ); |
| 254 | |
Sangsik Yoon | b1b823f | 2016-05-16 18:55:39 +0900 | [diff] [blame] | 255 | List<FlowEntryWithLoad> retFel = new ArrayList<>(); |
Madan Jampani | c27b6b2 | 2016-02-05 11:36:31 -0800 | [diff] [blame] | 256 | |
| 257 | Set<FlowEntry> currentStats; |
| 258 | Set<FlowEntry> previousStats; |
| 259 | |
| 260 | TypedStatistics typedStatistics; |
Sangsik Yoon | b1b823f | 2016-05-16 18:55:39 +0900 | [diff] [blame] | 261 | synchronized (statisticStore) { |
| 262 | currentStats = statisticStore.getCurrentStatistic(cp); |
Madan Jampani | c27b6b2 | 2016-02-05 11:36:31 -0800 | [diff] [blame] | 263 | if (currentStats == null) { |
Sangsik Yoon | b1b823f | 2016-05-16 18:55:39 +0900 | [diff] [blame] | 264 | return retFel; |
Madan Jampani | c27b6b2 | 2016-02-05 11:36:31 -0800 | [diff] [blame] | 265 | } |
Sangsik Yoon | b1b823f | 2016-05-16 18:55:39 +0900 | [diff] [blame] | 266 | previousStats = statisticStore.getPreviousStatistic(cp); |
Madan Jampani | c27b6b2 | 2016-02-05 11:36:31 -0800 | [diff] [blame] | 267 | if (previousStats == null) { |
Sangsik Yoon | b1b823f | 2016-05-16 18:55:39 +0900 | [diff] [blame] | 268 | return retFel; |
Madan Jampani | c27b6b2 | 2016-02-05 11:36:31 -0800 | [diff] [blame] | 269 | } |
| 270 | // copy to local flow entry set |
| 271 | typedStatistics = new TypedStatistics(currentStats, previousStats); |
| 272 | |
| 273 | // Check for validity of this stats data |
| 274 | checkLoadValidity(currentStats, previousStats); |
| 275 | } |
| 276 | |
| 277 | // current and previous set is not empty! |
Madan Jampani | c27b6b2 | 2016-02-05 11:36:31 -0800 | [diff] [blame] | 278 | boolean isAllInstType = (instType == null ? true : false); // null is all inst type |
sivachidambaram subramanian | dde26b6 | 2017-02-07 16:18:33 +0530 | [diff] [blame] | 279 | boolean isAllLiveType = (liveType == null ? true : false); // null is all live type |
Madan Jampani | c27b6b2 | 2016-02-05 11:36:31 -0800 | [diff] [blame] | 280 | |
Sangsik Yoon | b1b823f | 2016-05-16 18:55:39 +0900 | [diff] [blame] | 281 | Map<FlowRule, FlowEntry> currentMap; |
| 282 | Map<FlowRule, FlowEntry> previousMap; |
Madan Jampani | c27b6b2 | 2016-02-05 11:36:31 -0800 | [diff] [blame] | 283 | |
sivachidambaram subramanian | dde26b6 | 2017-02-07 16:18:33 +0530 | [diff] [blame] | 284 | if (isAllLiveType) { |
Sangsik Yoon | b1b823f | 2016-05-16 18:55:39 +0900 | [diff] [blame] | 285 | currentMap = typedStatistics.currentAll(); |
| 286 | previousMap = typedStatistics.previousAll(); |
| 287 | } else { |
| 288 | switch (liveType) { |
| 289 | case IMMEDIATE: |
| 290 | currentMap = typedStatistics.currentImmediate(); |
| 291 | previousMap = typedStatistics.previousImmediate(); |
| 292 | break; |
| 293 | case SHORT: |
| 294 | currentMap = typedStatistics.currentShort(); |
| 295 | previousMap = typedStatistics.previousShort(); |
| 296 | break; |
| 297 | case MID: |
| 298 | currentMap = typedStatistics.currentMid(); |
| 299 | previousMap = typedStatistics.previousMid(); |
| 300 | break; |
| 301 | case LONG: |
| 302 | currentMap = typedStatistics.currentLong(); |
| 303 | previousMap = typedStatistics.previousLong(); |
| 304 | break; |
| 305 | case UNKNOWN: |
| 306 | currentMap = typedStatistics.currentUnknown(); |
| 307 | previousMap = typedStatistics.previousUnknown(); |
| 308 | break; |
| 309 | default: |
| 310 | currentMap = new HashMap<>(); |
| 311 | previousMap = new HashMap<>(); |
| 312 | break; |
Madan Jampani | c27b6b2 | 2016-02-05 11:36:31 -0800 | [diff] [blame] | 313 | } |
| 314 | } |
| 315 | |
Sangsik Yoon | b1b823f | 2016-05-16 18:55:39 +0900 | [diff] [blame] | 316 | return typedFlowEntryLoadByInstInternal(cp, currentMap, previousMap, isAllInstType, instType); |
Madan Jampani | c27b6b2 | 2016-02-05 11:36:31 -0800 | [diff] [blame] | 317 | } |
| 318 | |
Sangsik Yoon | b1b823f | 2016-05-16 18:55:39 +0900 | [diff] [blame] | 319 | private List<FlowEntryWithLoad> typedFlowEntryLoadByInstInternal(ConnectPoint cp, |
| 320 | Map<FlowRule, FlowEntry> currentMap, |
| 321 | Map<FlowRule, FlowEntry> previousMap, |
Madan Jampani | c27b6b2 | 2016-02-05 11:36:31 -0800 | [diff] [blame] | 322 | boolean isAllInstType, |
Sangsik Yoon | b1b823f | 2016-05-16 18:55:39 +0900 | [diff] [blame] | 323 | Instruction.Type instType) { |
| 324 | List<FlowEntryWithLoad> fel = new ArrayList<>(); |
Madan Jampani | c27b6b2 | 2016-02-05 11:36:31 -0800 | [diff] [blame] | 325 | |
Sangsik Yoon | b1b823f | 2016-05-16 18:55:39 +0900 | [diff] [blame] | 326 | currentMap.values().forEach(fe -> { |
Madan Jampani | c27b6b2 | 2016-02-05 11:36:31 -0800 | [diff] [blame] | 327 | if (isAllInstType || |
Sangsik Yoon | b1b823f | 2016-05-16 18:55:39 +0900 | [diff] [blame] | 328 | fe.treatment().allInstructions().stream(). |
Madan Jampani | c27b6b2 | 2016-02-05 11:36:31 -0800 | [diff] [blame] | 329 | filter(i -> i.type() == instType). |
| 330 | findAny().isPresent()) { |
Sangsik Yoon | b1b823f | 2016-05-16 18:55:39 +0900 | [diff] [blame] | 331 | long currentBytes = fe.bytes(); |
| 332 | long previousBytes = previousMap.getOrDefault(fe, new DefaultFlowEntry(fe)).bytes(); |
| 333 | long liveTypePollInterval = getLiveTypePollInterval(fe.liveType()); |
Madan Jampani | c27b6b2 | 2016-02-05 11:36:31 -0800 | [diff] [blame] | 334 | Load fLoad = new DefaultLoad(currentBytes, previousBytes, liveTypePollInterval); |
Sangsik Yoon | b1b823f | 2016-05-16 18:55:39 +0900 | [diff] [blame] | 335 | fel.add(new FlowEntryWithLoad(cp, fe, fLoad)); |
Madan Jampani | c27b6b2 | 2016-02-05 11:36:31 -0800 | [diff] [blame] | 336 | } |
Sangsik Yoon | b1b823f | 2016-05-16 18:55:39 +0900 | [diff] [blame] | 337 | }); |
Madan Jampani | c27b6b2 | 2016-02-05 11:36:31 -0800 | [diff] [blame] | 338 | |
| 339 | return fel; |
| 340 | } |
| 341 | |
Sangsik Yoon | b1b823f | 2016-05-16 18:55:39 +0900 | [diff] [blame] | 342 | private List<FlowEntryWithLoad> loadTopnPortInternal(ConnectPoint cp, |
| 343 | FlowEntry.FlowLiveType liveType, |
Madan Jampani | c27b6b2 | 2016-02-05 11:36:31 -0800 | [diff] [blame] | 344 | Instruction.Type instType, |
| 345 | int topn) { |
Sangsik Yoon | b1b823f | 2016-05-16 18:55:39 +0900 | [diff] [blame] | 346 | List<FlowEntryWithLoad> fel = loadAllPortInternal(cp, liveType, instType); |
Madan Jampani | c27b6b2 | 2016-02-05 11:36:31 -0800 | [diff] [blame] | 347 | |
| 348 | // Sort with descending order of load |
Sangsik Yoon | b1b823f | 2016-05-16 18:55:39 +0900 | [diff] [blame] | 349 | List<FlowEntryWithLoad> retFel = |
| 350 | fel.stream().sorted(Comparators.FLOWENTRY_WITHLOAD_COMPARATOR). |
Madan Jampani | c27b6b2 | 2016-02-05 11:36:31 -0800 | [diff] [blame] | 351 | limit(topn).collect(Collectors.toList()); |
| 352 | |
Sangsik Yoon | b1b823f | 2016-05-16 18:55:39 +0900 | [diff] [blame] | 353 | return retFel; |
Madan Jampani | c27b6b2 | 2016-02-05 11:36:31 -0800 | [diff] [blame] | 354 | } |
| 355 | |
| 356 | private long aggregateBytesSet(Set<FlowEntry> setFE) { |
| 357 | return setFE.stream().mapToLong(FlowEntry::bytes).sum(); |
| 358 | } |
| 359 | |
Sangsik Yoon | b1b823f | 2016-05-16 18:55:39 +0900 | [diff] [blame] | 360 | private long aggregateBytesMap(Map<FlowRule, FlowEntry> mapFE) { |
Madan Jampani | c27b6b2 | 2016-02-05 11:36:31 -0800 | [diff] [blame] | 361 | return mapFE.values().stream().mapToLong(FlowEntry::bytes).sum(); |
| 362 | } |
| 363 | |
Sangsik Yoon | b1b823f | 2016-05-16 18:55:39 +0900 | [diff] [blame] | 364 | private long getLiveTypePollInterval(FlowEntry.FlowLiveType liveType) { |
| 365 | // returns the flow live type poll interval value |
| 366 | PollInterval pollIntervalInstance = PollInterval.getInstance(); |
| 367 | |
| 368 | switch (liveType) { |
| 369 | case LONG: |
| 370 | return pollIntervalInstance.getLongPollInterval(); |
| 371 | case MID: |
| 372 | return pollIntervalInstance.getMidPollInterval(); |
| 373 | case SHORT: |
| 374 | case IMMEDIATE: |
| 375 | default: // UNKNOWN |
| 376 | return pollIntervalInstance.getPollInterval(); |
| 377 | } |
| 378 | } |
| 379 | |
Sangsik Yoon | b1b823f | 2016-05-16 18:55:39 +0900 | [diff] [blame] | 380 | private TypedStoredFlowEntry.FlowLiveType toTypedStoredFlowEntryLiveType(FlowEntry.FlowLiveType liveType) { |
| 381 | if (liveType == null) { |
| 382 | return null; |
| 383 | } |
| 384 | |
| 385 | // convert TypedStoredFlowEntry flow live type to FlowEntry one |
| 386 | switch (liveType) { |
| 387 | case IMMEDIATE: |
| 388 | return TypedStoredFlowEntry.FlowLiveType.IMMEDIATE_FLOW; |
| 389 | case SHORT: |
| 390 | return TypedStoredFlowEntry.FlowLiveType.SHORT_FLOW; |
| 391 | case MID: |
| 392 | return TypedStoredFlowEntry.FlowLiveType.MID_FLOW; |
| 393 | case LONG: |
| 394 | return TypedStoredFlowEntry.FlowLiveType.LONG_FLOW; |
| 395 | default: |
| 396 | return TypedStoredFlowEntry.FlowLiveType.UNKNOWN_FLOW; |
| 397 | } |
| 398 | } |
| 399 | |
| 400 | private Map<ConnectPoint, List<TypedFlowEntryWithLoad>> toFlowEntryWithLoadMap( |
| 401 | Map<ConnectPoint, List<FlowEntryWithLoad>> loadMap) { |
| 402 | // convert FlowEntryWithLoad list to TypedFlowEntryWithLoad list |
| 403 | Map<ConnectPoint, List<TypedFlowEntryWithLoad>> allLoad = |
| 404 | new TreeMap<>(Comparators.CONNECT_POINT_COMPARATOR); |
| 405 | |
| 406 | loadMap.forEach((k, v) -> { |
| 407 | List<TypedFlowEntryWithLoad> tfelList = |
| 408 | toFlowEntryWithLoad(v); |
| 409 | allLoad.put(k, tfelList); |
| 410 | }); |
| 411 | |
| 412 | return allLoad; |
| 413 | } |
| 414 | |
| 415 | private List<TypedFlowEntryWithLoad> toFlowEntryWithLoad(List<FlowEntryWithLoad> loadList) { |
| 416 | // convert FlowEntryWithLoad list to TypedFlowEntryWithLoad list |
| 417 | List<TypedFlowEntryWithLoad> tfelList = new ArrayList<>(); |
| 418 | loadList.forEach(fel -> { |
| 419 | StoredFlowEntry sfe = fel.storedFlowEntry(); |
| 420 | TypedStoredFlowEntry.FlowLiveType liveType = toTypedStoredFlowEntryLiveType(sfe.liveType()); |
| 421 | TypedStoredFlowEntry tfe = new DefaultTypedFlowEntry(sfe, liveType); |
| 422 | TypedFlowEntryWithLoad tfel = new TypedFlowEntryWithLoad(fel.connectPoint(), tfe, fel.load()); |
| 423 | tfelList.add(tfel); |
| 424 | }); |
| 425 | |
| 426 | return tfelList; |
| 427 | } |
| 428 | |
Madan Jampani | c27b6b2 | 2016-02-05 11:36:31 -0800 | [diff] [blame] | 429 | /** |
Sangsik Yoon | b1b823f | 2016-05-16 18:55:39 +0900 | [diff] [blame] | 430 | * Internal data class holding two set of flow entries included flow liveType. |
Madan Jampani | c27b6b2 | 2016-02-05 11:36:31 -0800 | [diff] [blame] | 431 | */ |
| 432 | private static class TypedStatistics { |
Sangsik Yoon | b1b823f | 2016-05-16 18:55:39 +0900 | [diff] [blame] | 433 | private final ImmutableSet<FlowEntry> current; |
| 434 | private final ImmutableSet<FlowEntry> previous; |
Madan Jampani | c27b6b2 | 2016-02-05 11:36:31 -0800 | [diff] [blame] | 435 | |
Sangsik Yoon | b1b823f | 2016-05-16 18:55:39 +0900 | [diff] [blame] | 436 | private final Map<FlowRule, FlowEntry> currentAll = new HashMap<>(); |
| 437 | private final Map<FlowRule, FlowEntry> previousAll = new HashMap<>(); |
Madan Jampani | c27b6b2 | 2016-02-05 11:36:31 -0800 | [diff] [blame] | 438 | |
Sangsik Yoon | b1b823f | 2016-05-16 18:55:39 +0900 | [diff] [blame] | 439 | private final Map<FlowRule, FlowEntry> currentImmediate = new HashMap<>(); |
| 440 | private final Map<FlowRule, FlowEntry> previousImmediate = new HashMap<>(); |
Madan Jampani | c27b6b2 | 2016-02-05 11:36:31 -0800 | [diff] [blame] | 441 | |
Sangsik Yoon | b1b823f | 2016-05-16 18:55:39 +0900 | [diff] [blame] | 442 | private final Map<FlowRule, FlowEntry> currentShort = new HashMap<>(); |
| 443 | private final Map<FlowRule, FlowEntry> previousShort = new HashMap<>(); |
Madan Jampani | c27b6b2 | 2016-02-05 11:36:31 -0800 | [diff] [blame] | 444 | |
Sangsik Yoon | b1b823f | 2016-05-16 18:55:39 +0900 | [diff] [blame] | 445 | private final Map<FlowRule, FlowEntry> currentMid = new HashMap<>(); |
| 446 | private final Map<FlowRule, FlowEntry> previousMid = new HashMap<>(); |
Madan Jampani | c27b6b2 | 2016-02-05 11:36:31 -0800 | [diff] [blame] | 447 | |
Sangsik Yoon | b1b823f | 2016-05-16 18:55:39 +0900 | [diff] [blame] | 448 | private final Map<FlowRule, FlowEntry> currentLong = new HashMap<>(); |
| 449 | private final Map<FlowRule, FlowEntry> previousLong = new HashMap<>(); |
| 450 | |
| 451 | private final Map<FlowRule, FlowEntry> currentUnknown = new HashMap<>(); |
| 452 | private final Map<FlowRule, FlowEntry> previousUnknown = new HashMap<>(); |
Madan Jampani | c27b6b2 | 2016-02-05 11:36:31 -0800 | [diff] [blame] | 453 | |
| 454 | public TypedStatistics(Set<FlowEntry> current, Set<FlowEntry> previous) { |
Sangsik Yoon | b1b823f | 2016-05-16 18:55:39 +0900 | [diff] [blame] | 455 | this.current = ImmutableSet.copyOf(checkNotNull(current)); |
| 456 | this.previous = ImmutableSet.copyOf(checkNotNull(previous)); |
Madan Jampani | c27b6b2 | 2016-02-05 11:36:31 -0800 | [diff] [blame] | 457 | |
Sangsik Yoon | b1b823f | 2016-05-16 18:55:39 +0900 | [diff] [blame] | 458 | current.forEach(fe -> { |
| 459 | switch (fe.liveType()) { |
| 460 | case IMMEDIATE: |
| 461 | currentImmediate.put(fe, fe); |
Madan Jampani | c27b6b2 | 2016-02-05 11:36:31 -0800 | [diff] [blame] | 462 | break; |
Sangsik Yoon | b1b823f | 2016-05-16 18:55:39 +0900 | [diff] [blame] | 463 | case SHORT: |
| 464 | currentShort.put(fe, fe); |
Madan Jampani | c27b6b2 | 2016-02-05 11:36:31 -0800 | [diff] [blame] | 465 | break; |
Sangsik Yoon | b1b823f | 2016-05-16 18:55:39 +0900 | [diff] [blame] | 466 | case MID: |
| 467 | currentMid.put(fe, fe); |
Madan Jampani | c27b6b2 | 2016-02-05 11:36:31 -0800 | [diff] [blame] | 468 | break; |
Sangsik Yoon | b1b823f | 2016-05-16 18:55:39 +0900 | [diff] [blame] | 469 | case LONG: |
| 470 | currentLong.put(fe, fe); |
Madan Jampani | c27b6b2 | 2016-02-05 11:36:31 -0800 | [diff] [blame] | 471 | break; |
Sangsik Yoon | b1b823f | 2016-05-16 18:55:39 +0900 | [diff] [blame] | 472 | default: // unknown |
| 473 | currentUnknown.put(fe, fe); |
Madan Jampani | c27b6b2 | 2016-02-05 11:36:31 -0800 | [diff] [blame] | 474 | break; |
| 475 | } |
Sangsik Yoon | b1b823f | 2016-05-16 18:55:39 +0900 | [diff] [blame] | 476 | currentAll.put(fe, fe); |
Madan Jampani | c27b6b2 | 2016-02-05 11:36:31 -0800 | [diff] [blame] | 477 | }); |
| 478 | |
Sangsik Yoon | b1b823f | 2016-05-16 18:55:39 +0900 | [diff] [blame] | 479 | previous.forEach(fe -> { |
| 480 | switch (fe.liveType()) { |
| 481 | case IMMEDIATE: |
Madan Jampani | c27b6b2 | 2016-02-05 11:36:31 -0800 | [diff] [blame] | 482 | if (currentImmediate.containsKey(fe)) { |
Sangsik Yoon | b1b823f | 2016-05-16 18:55:39 +0900 | [diff] [blame] | 483 | previousImmediate.put(fe, fe); |
Madan Jampani | c27b6b2 | 2016-02-05 11:36:31 -0800 | [diff] [blame] | 484 | } else if (currentShort.containsKey(fe)) { |
Sangsik Yoon | b1b823f | 2016-05-16 18:55:39 +0900 | [diff] [blame] | 485 | previousShort.put(fe, fe); |
Madan Jampani | c27b6b2 | 2016-02-05 11:36:31 -0800 | [diff] [blame] | 486 | } else if (currentMid.containsKey(fe)) { |
Sangsik Yoon | b1b823f | 2016-05-16 18:55:39 +0900 | [diff] [blame] | 487 | previousMid.put(fe, fe); |
Madan Jampani | c27b6b2 | 2016-02-05 11:36:31 -0800 | [diff] [blame] | 488 | } else if (currentLong.containsKey(fe)) { |
Sangsik Yoon | b1b823f | 2016-05-16 18:55:39 +0900 | [diff] [blame] | 489 | previousLong.put(fe, fe); |
Madan Jampani | c27b6b2 | 2016-02-05 11:36:31 -0800 | [diff] [blame] | 490 | } else { |
Sangsik Yoon | b1b823f | 2016-05-16 18:55:39 +0900 | [diff] [blame] | 491 | previousUnknown.put(fe, fe); |
Madan Jampani | c27b6b2 | 2016-02-05 11:36:31 -0800 | [diff] [blame] | 492 | } |
| 493 | break; |
Sangsik Yoon | b1b823f | 2016-05-16 18:55:39 +0900 | [diff] [blame] | 494 | case SHORT: |
Madan Jampani | c27b6b2 | 2016-02-05 11:36:31 -0800 | [diff] [blame] | 495 | if (currentShort.containsKey(fe)) { |
Sangsik Yoon | b1b823f | 2016-05-16 18:55:39 +0900 | [diff] [blame] | 496 | previousShort.put(fe, fe); |
Madan Jampani | c27b6b2 | 2016-02-05 11:36:31 -0800 | [diff] [blame] | 497 | } else if (currentMid.containsKey(fe)) { |
Sangsik Yoon | b1b823f | 2016-05-16 18:55:39 +0900 | [diff] [blame] | 498 | previousMid.put(fe, fe); |
Madan Jampani | c27b6b2 | 2016-02-05 11:36:31 -0800 | [diff] [blame] | 499 | } else if (currentLong.containsKey(fe)) { |
Sangsik Yoon | b1b823f | 2016-05-16 18:55:39 +0900 | [diff] [blame] | 500 | previousLong.put(fe, fe); |
Madan Jampani | c27b6b2 | 2016-02-05 11:36:31 -0800 | [diff] [blame] | 501 | } else { |
Sangsik Yoon | b1b823f | 2016-05-16 18:55:39 +0900 | [diff] [blame] | 502 | previousUnknown.put(fe, fe); |
Madan Jampani | c27b6b2 | 2016-02-05 11:36:31 -0800 | [diff] [blame] | 503 | } |
| 504 | break; |
Sangsik Yoon | b1b823f | 2016-05-16 18:55:39 +0900 | [diff] [blame] | 505 | case MID: |
Madan Jampani | c27b6b2 | 2016-02-05 11:36:31 -0800 | [diff] [blame] | 506 | if (currentMid.containsKey(fe)) { |
Sangsik Yoon | b1b823f | 2016-05-16 18:55:39 +0900 | [diff] [blame] | 507 | previousMid.put(fe, fe); |
Madan Jampani | c27b6b2 | 2016-02-05 11:36:31 -0800 | [diff] [blame] | 508 | } else if (currentLong.containsKey(fe)) { |
Sangsik Yoon | b1b823f | 2016-05-16 18:55:39 +0900 | [diff] [blame] | 509 | previousLong.put(fe, fe); |
Madan Jampani | c27b6b2 | 2016-02-05 11:36:31 -0800 | [diff] [blame] | 510 | } else { |
Sangsik Yoon | b1b823f | 2016-05-16 18:55:39 +0900 | [diff] [blame] | 511 | previousUnknown.put(fe, fe); |
Madan Jampani | c27b6b2 | 2016-02-05 11:36:31 -0800 | [diff] [blame] | 512 | } |
| 513 | break; |
Sangsik Yoon | b1b823f | 2016-05-16 18:55:39 +0900 | [diff] [blame] | 514 | case LONG: |
Madan Jampani | c27b6b2 | 2016-02-05 11:36:31 -0800 | [diff] [blame] | 515 | if (currentLong.containsKey(fe)) { |
Sangsik Yoon | b1b823f | 2016-05-16 18:55:39 +0900 | [diff] [blame] | 516 | previousLong.put(fe, fe); |
Madan Jampani | c27b6b2 | 2016-02-05 11:36:31 -0800 | [diff] [blame] | 517 | } else { |
Sangsik Yoon | b1b823f | 2016-05-16 18:55:39 +0900 | [diff] [blame] | 518 | previousUnknown.put(fe, fe); |
Madan Jampani | c27b6b2 | 2016-02-05 11:36:31 -0800 | [diff] [blame] | 519 | } |
| 520 | break; |
Sangsik Yoon | b1b823f | 2016-05-16 18:55:39 +0900 | [diff] [blame] | 521 | default: // unknown |
| 522 | previousUnknown.put(fe, fe); |
Madan Jampani | c27b6b2 | 2016-02-05 11:36:31 -0800 | [diff] [blame] | 523 | break; |
| 524 | } |
Sangsik Yoon | b1b823f | 2016-05-16 18:55:39 +0900 | [diff] [blame] | 525 | previousAll.put(fe, fe); |
Madan Jampani | c27b6b2 | 2016-02-05 11:36:31 -0800 | [diff] [blame] | 526 | }); |
| 527 | } |
| 528 | |
| 529 | /** |
| 530 | * Returns flow entries as the current value. |
| 531 | * |
| 532 | * @return flow entries as the current value |
| 533 | */ |
| 534 | public ImmutableSet<FlowEntry> current() { |
Sangsik Yoon | b1b823f | 2016-05-16 18:55:39 +0900 | [diff] [blame] | 535 | return current; |
Madan Jampani | c27b6b2 | 2016-02-05 11:36:31 -0800 | [diff] [blame] | 536 | } |
| 537 | |
| 538 | /** |
| 539 | * Returns flow entries as the previous value. |
| 540 | * |
| 541 | * @return flow entries as the previous value |
| 542 | */ |
| 543 | public ImmutableSet<FlowEntry> previous() { |
Sangsik Yoon | b1b823f | 2016-05-16 18:55:39 +0900 | [diff] [blame] | 544 | return previous; |
| 545 | } |
| 546 | |
| 547 | public Map<FlowRule, FlowEntry> currentAll() { |
| 548 | return currentAll; |
| 549 | } |
| 550 | |
| 551 | public Map<FlowRule, FlowEntry> previousAll() { |
Madan Jampani | c27b6b2 | 2016-02-05 11:36:31 -0800 | [diff] [blame] | 552 | return previousAll; |
| 553 | } |
| 554 | |
Sangsik Yoon | b1b823f | 2016-05-16 18:55:39 +0900 | [diff] [blame] | 555 | public Map<FlowRule, FlowEntry> currentImmediate() { |
Madan Jampani | c27b6b2 | 2016-02-05 11:36:31 -0800 | [diff] [blame] | 556 | return currentImmediate; |
| 557 | } |
Sangsik Yoon | b1b823f | 2016-05-16 18:55:39 +0900 | [diff] [blame] | 558 | public Map<FlowRule, FlowEntry> previousImmediate() { |
Madan Jampani | c27b6b2 | 2016-02-05 11:36:31 -0800 | [diff] [blame] | 559 | return previousImmediate; |
| 560 | } |
Sangsik Yoon | b1b823f | 2016-05-16 18:55:39 +0900 | [diff] [blame] | 561 | public Map<FlowRule, FlowEntry> currentShort() { |
Madan Jampani | c27b6b2 | 2016-02-05 11:36:31 -0800 | [diff] [blame] | 562 | return currentShort; |
| 563 | } |
Sangsik Yoon | b1b823f | 2016-05-16 18:55:39 +0900 | [diff] [blame] | 564 | public Map<FlowRule, FlowEntry> previousShort() { |
Madan Jampani | c27b6b2 | 2016-02-05 11:36:31 -0800 | [diff] [blame] | 565 | return previousShort; |
| 566 | } |
Sangsik Yoon | b1b823f | 2016-05-16 18:55:39 +0900 | [diff] [blame] | 567 | public Map<FlowRule, FlowEntry> currentMid() { |
Madan Jampani | c27b6b2 | 2016-02-05 11:36:31 -0800 | [diff] [blame] | 568 | return currentMid; |
| 569 | } |
Sangsik Yoon | b1b823f | 2016-05-16 18:55:39 +0900 | [diff] [blame] | 570 | public Map<FlowRule, FlowEntry> previousMid() { |
Madan Jampani | c27b6b2 | 2016-02-05 11:36:31 -0800 | [diff] [blame] | 571 | return previousMid; |
| 572 | } |
Sangsik Yoon | b1b823f | 2016-05-16 18:55:39 +0900 | [diff] [blame] | 573 | public Map<FlowRule, FlowEntry> currentLong() { |
Madan Jampani | c27b6b2 | 2016-02-05 11:36:31 -0800 | [diff] [blame] | 574 | return currentLong; |
| 575 | } |
Sangsik Yoon | b1b823f | 2016-05-16 18:55:39 +0900 | [diff] [blame] | 576 | public Map<FlowRule, FlowEntry> previousLong() { |
Madan Jampani | c27b6b2 | 2016-02-05 11:36:31 -0800 | [diff] [blame] | 577 | return previousLong; |
| 578 | } |
Sangsik Yoon | b1b823f | 2016-05-16 18:55:39 +0900 | [diff] [blame] | 579 | public Map<FlowRule, FlowEntry> currentUnknown() { |
Madan Jampani | c27b6b2 | 2016-02-05 11:36:31 -0800 | [diff] [blame] | 580 | return currentUnknown; |
| 581 | } |
Sangsik Yoon | b1b823f | 2016-05-16 18:55:39 +0900 | [diff] [blame] | 582 | public Map<FlowRule, FlowEntry> previousUnknown() { |
Madan Jampani | c27b6b2 | 2016-02-05 11:36:31 -0800 | [diff] [blame] | 583 | return previousUnknown; |
| 584 | } |
| 585 | |
| 586 | /** |
| 587 | * Validates values are not empty. |
| 588 | * |
| 589 | * @return false if either of the sets is empty. Otherwise, true. |
| 590 | */ |
| 591 | public boolean isValid() { |
| 592 | return !(currentAll.isEmpty() || previousAll.isEmpty()); |
| 593 | } |
| 594 | |
| 595 | @Override |
| 596 | public int hashCode() { |
| 597 | return Objects.hash(currentAll, previousAll); |
| 598 | } |
| 599 | |
| 600 | @Override |
| 601 | public boolean equals(Object obj) { |
| 602 | if (this == obj) { |
| 603 | return true; |
| 604 | } |
| 605 | if (!(obj instanceof TypedStatistics)) { |
| 606 | return false; |
| 607 | } |
| 608 | final TypedStatistics other = (TypedStatistics) obj; |
| 609 | return Objects.equals(this.currentAll, other.currentAll) && |
| 610 | Objects.equals(this.previousAll, other.previousAll); |
| 611 | } |
| 612 | |
| 613 | @Override |
| 614 | public String toString() { |
| 615 | return MoreObjects.toStringHelper(this) |
| 616 | .add("current", currentAll) |
| 617 | .add("previous", previousAll) |
| 618 | .toString(); |
| 619 | } |
| 620 | } |
| 621 | |
| 622 | private void checkLoadValidity(Set<FlowEntry> current, Set<FlowEntry> previous) { |
Sho SHIMIZU | a09e1bb | 2016-08-01 14:25:25 -0700 | [diff] [blame] | 623 | current.forEach(c -> { |
Madan Jampani | c27b6b2 | 2016-02-05 11:36:31 -0800 | [diff] [blame] | 624 | FlowEntry f = previous.stream().filter(p -> c.equals(p)). |
| 625 | findAny().orElse(null); |
| 626 | if (f != null && c.bytes() < f.bytes()) { |
| 627 | log.debug("FlowStatisticManager:checkLoadValidity():" + |
| 628 | "Error: " + c + " :Previous bytes=" + f.bytes() + |
| 629 | " is larger than current bytes=" + c.bytes() + " !!!"); |
| 630 | } |
| 631 | }); |
| 632 | |
| 633 | } |
| 634 | |
| 635 | /** |
| 636 | * Creates a predicate that checks the instruction type of a flow entry is the same as |
| 637 | * the specified instruction type. |
| 638 | * |
| 639 | * @param instType instruction type to be checked |
| 640 | * @return predicate |
| 641 | */ |
| 642 | private static Predicate<FlowEntry> hasInstructionType(Instruction.Type instType) { |
| 643 | return new Predicate<FlowEntry>() { |
| 644 | @Override |
| 645 | public boolean apply(FlowEntry flowEntry) { |
| 646 | List<Instruction> allInstructions = flowEntry.treatment().allInstructions(); |
| 647 | |
| 648 | return allInstructions.stream().filter(i -> i.type() == instType).findAny().isPresent(); |
| 649 | } |
| 650 | }; |
| 651 | } |
| 652 | |
| 653 | /** |
Sangsik Yoon | b1b823f | 2016-05-16 18:55:39 +0900 | [diff] [blame] | 654 | * Creates a predicate that checks the flow type of a flow entry is the same as |
| 655 | * the specified live type. |
| 656 | * |
| 657 | * @param liveType flow live type to be checked |
| 658 | * @return predicate |
Madan Jampani | c27b6b2 | 2016-02-05 11:36:31 -0800 | [diff] [blame] | 659 | */ |
Sangsik Yoon | b1b823f | 2016-05-16 18:55:39 +0900 | [diff] [blame] | 660 | private static Predicate<FlowEntry> hasLiveType(FlowEntry.FlowLiveType liveType) { |
| 661 | return flowEntry -> flowEntry.liveType() == liveType; |
Madan Jampani | c27b6b2 | 2016-02-05 11:36:31 -0800 | [diff] [blame] | 662 | } |
| 663 | } |