Jian Li | 6080432 | 2015-12-02 14:46:31 -0800 | [diff] [blame] | 1 | /* |
Jian Li | e044d1a | 2016-01-25 09:01:20 -0800 | [diff] [blame] | 2 | * Copyright 2015-2016 Open Networking Laboratory |
Jian Li | 6080432 | 2015-12-02 14:46: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 | */ |
Jian Li | 6b86a76 | 2016-01-29 09:30:40 -0800 | [diff] [blame] | 16 | package org.onosproject.cpman.impl; |
Jian Li | 6080432 | 2015-12-02 14:46:31 -0800 | [diff] [blame] | 17 | |
Jian Li | 9f3a885 | 2016-04-07 13:37:39 -0700 | [diff] [blame] | 18 | import com.google.common.collect.ImmutableMap; |
Jian Li | 7d180c5 | 2016-02-01 21:53:08 -0800 | [diff] [blame] | 19 | import com.google.common.collect.ImmutableSet; |
Jian Li | 85060ac | 2016-02-04 09:58:56 -0800 | [diff] [blame] | 20 | import com.google.common.collect.Maps; |
| 21 | import com.google.common.collect.Sets; |
Jian Li | 6080432 | 2015-12-02 14:46:31 -0800 | [diff] [blame] | 22 | import org.apache.felix.scr.annotations.Activate; |
Jian Li | c132c11 | 2016-01-28 20:27:34 -0800 | [diff] [blame] | 23 | import org.apache.felix.scr.annotations.Component; |
Jian Li | 6080432 | 2015-12-02 14:46:31 -0800 | [diff] [blame] | 24 | import org.apache.felix.scr.annotations.Deactivate; |
Jian Li | 7d180c5 | 2016-02-01 21:53:08 -0800 | [diff] [blame] | 25 | import org.apache.felix.scr.annotations.Reference; |
| 26 | import org.apache.felix.scr.annotations.ReferenceCardinality; |
Jian Li | 6080432 | 2015-12-02 14:46:31 -0800 | [diff] [blame] | 27 | import org.apache.felix.scr.annotations.Service; |
Jian Li | 23906cc | 2016-03-31 11:16:44 -0700 | [diff] [blame] | 28 | import org.onlab.util.KryoNamespace; |
Jian Li | 7d180c5 | 2016-02-01 21:53:08 -0800 | [diff] [blame] | 29 | import org.onosproject.cluster.ClusterService; |
Jian Li | 6080432 | 2015-12-02 14:46:31 -0800 | [diff] [blame] | 30 | import org.onosproject.cluster.NodeId; |
Jian Li | 6b86a76 | 2016-01-29 09:30:40 -0800 | [diff] [blame] | 31 | import org.onosproject.cpman.ControlLoad; |
| 32 | import org.onosproject.cpman.ControlMetric; |
| 33 | import org.onosproject.cpman.ControlMetricType; |
| 34 | import org.onosproject.cpman.ControlPlaneMonitorService; |
Jian Li | 7d180c5 | 2016-02-01 21:53:08 -0800 | [diff] [blame] | 35 | import org.onosproject.cpman.MetricsDatabase; |
Jian Li | 6080432 | 2015-12-02 14:46:31 -0800 | [diff] [blame] | 36 | import org.onosproject.net.DeviceId; |
Jian Li | 23906cc | 2016-03-31 11:16:44 -0700 | [diff] [blame] | 37 | import org.onosproject.store.cluster.messaging.ClusterCommunicationService; |
| 38 | import org.onosproject.store.cluster.messaging.MessageSubject; |
| 39 | import org.onosproject.store.serializers.KryoNamespaces; |
| 40 | import org.onosproject.store.service.Serializer; |
Jian Li | 6080432 | 2015-12-02 14:46:31 -0800 | [diff] [blame] | 41 | import org.slf4j.Logger; |
Jian Li | 7d180c5 | 2016-02-01 21:53:08 -0800 | [diff] [blame] | 42 | import org.slf4j.LoggerFactory; |
Jian Li | 6080432 | 2015-12-02 14:46:31 -0800 | [diff] [blame] | 43 | |
Jian Li | 7d180c5 | 2016-02-01 21:53:08 -0800 | [diff] [blame] | 44 | import java.util.Map; |
Jian Li | 6080432 | 2015-12-02 14:46:31 -0800 | [diff] [blame] | 45 | import java.util.Optional; |
Jian Li | c5cb4a1 | 2016-02-03 23:24:42 -0800 | [diff] [blame] | 46 | import java.util.Set; |
Jian Li | 23906cc | 2016-03-31 11:16:44 -0700 | [diff] [blame] | 47 | import java.util.concurrent.CompletableFuture; |
| 48 | import java.util.concurrent.ExecutorService; |
| 49 | import java.util.concurrent.Executors; |
Jian Li | 85060ac | 2016-02-04 09:58:56 -0800 | [diff] [blame] | 50 | import java.util.stream.Collectors; |
Jian Li | 6080432 | 2015-12-02 14:46:31 -0800 | [diff] [blame] | 51 | |
Jian Li | 23906cc | 2016-03-31 11:16:44 -0700 | [diff] [blame] | 52 | import static com.google.common.base.Preconditions.checkArgument; |
| 53 | import static org.onlab.util.Tools.groupedThreads; |
| 54 | import static org.onosproject.cpman.ControlResource.CONTROL_MESSAGE_METRICS; |
| 55 | import static org.onosproject.cpman.ControlResource.CPU_METRICS; |
| 56 | import static org.onosproject.cpman.ControlResource.DISK_METRICS; |
| 57 | import static org.onosproject.cpman.ControlResource.MEMORY_METRICS; |
| 58 | import static org.onosproject.cpman.ControlResource.NETWORK_METRICS; |
| 59 | import static org.onosproject.cpman.ControlResource.Type; |
Jian Li | 6080432 | 2015-12-02 14:46:31 -0800 | [diff] [blame] | 60 | |
| 61 | /** |
| 62 | * Control plane monitoring service class. |
| 63 | */ |
| 64 | @Component(immediate = true) |
| 65 | @Service |
| 66 | public class ControlPlaneMonitor implements ControlPlaneMonitorService { |
| 67 | |
Jian Li | 7d180c5 | 2016-02-01 21:53:08 -0800 | [diff] [blame] | 68 | private final Logger log = LoggerFactory.getLogger(getClass()); |
| 69 | private MetricsDatabase cpuMetrics; |
| 70 | private MetricsDatabase memoryMetrics; |
| 71 | private Map<DeviceId, MetricsDatabase> controlMessageMap; |
| 72 | private Map<String, MetricsDatabase> diskMetricsMap; |
| 73 | private Map<String, MetricsDatabase> networkMetricsMap; |
| 74 | |
| 75 | @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY) |
| 76 | protected ClusterService clusterService; |
| 77 | |
Jian Li | 23906cc | 2016-03-31 11:16:44 -0700 | [diff] [blame] | 78 | @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY) |
| 79 | protected ClusterCommunicationService communicationService; |
| 80 | |
Jian Li | daf55ea | 2016-04-04 20:38:30 -0700 | [diff] [blame] | 81 | private static final String DEFAULT_RESOURCE = "default"; |
| 82 | |
Jian Li | 85060ac | 2016-02-04 09:58:56 -0800 | [diff] [blame] | 83 | private static final Set RESOURCE_TYPE_SET = |
| 84 | ImmutableSet.of(Type.CONTROL_MESSAGE, Type.DISK, Type.NETWORK); |
Jian Li | 7d180c5 | 2016-02-01 21:53:08 -0800 | [diff] [blame] | 85 | |
Jian Li | 23906cc | 2016-03-31 11:16:44 -0700 | [diff] [blame] | 86 | private static final MessageSubject CONTROL_STATS = |
| 87 | new MessageSubject("control-plane-stats"); |
| 88 | |
Jian Li | 7d180c5 | 2016-02-01 21:53:08 -0800 | [diff] [blame] | 89 | private Map<ControlMetricType, Double> cpuBuf; |
| 90 | private Map<ControlMetricType, Double> memoryBuf; |
| 91 | private Map<String, Map<ControlMetricType, Double>> diskBuf; |
| 92 | private Map<String, Map<ControlMetricType, Double>> networkBuf; |
| 93 | private Map<DeviceId, Map<ControlMetricType, Double>> ctrlMsgBuf; |
Jian Li | 6080432 | 2015-12-02 14:46:31 -0800 | [diff] [blame] | 94 | |
Jian Li | 85060ac | 2016-02-04 09:58:56 -0800 | [diff] [blame] | 95 | private Map<Type, Set<String>> availableResourceMap; |
| 96 | private Set<DeviceId> availableDeviceIdSet; |
| 97 | |
Jian Li | 23906cc | 2016-03-31 11:16:44 -0700 | [diff] [blame] | 98 | private ExecutorService messageHandlingExecutor; |
| 99 | |
| 100 | private static final String METRIC_TYPE_NULL = "Control metric type cannot be null"; |
| 101 | |
Jian Li | daf55ea | 2016-04-04 20:38:30 -0700 | [diff] [blame] | 102 | Set<Map<ControlMetricType, Double>> debugSets = Sets.newHashSet(); |
| 103 | |
Jian Li | 23906cc | 2016-03-31 11:16:44 -0700 | [diff] [blame] | 104 | private static final Serializer SERIALIZER = Serializer |
| 105 | .using(new KryoNamespace.Builder() |
| 106 | .register(KryoNamespaces.API) |
| 107 | .register(ControlMetricsRequest.class) |
| 108 | .register(DefaultControlLoad.class) |
| 109 | .register(DefaultMetricsDatabase.class) |
| 110 | .register(ControlMetricType.class) |
| 111 | .nextId(KryoNamespaces.BEGIN_USER_CUSTOM_ID).build()); |
| 112 | |
Jian Li | 6080432 | 2015-12-02 14:46:31 -0800 | [diff] [blame] | 113 | @Activate |
| 114 | public void activate() { |
Jian Li | daf55ea | 2016-04-04 20:38:30 -0700 | [diff] [blame] | 115 | cpuMetrics = genMDbBuilder(DEFAULT_RESOURCE, Type.CPU, CPU_METRICS); |
| 116 | memoryMetrics = genMDbBuilder(DEFAULT_RESOURCE, Type.MEMORY, MEMORY_METRICS); |
Jian Li | 85060ac | 2016-02-04 09:58:56 -0800 | [diff] [blame] | 117 | controlMessageMap = Maps.newConcurrentMap(); |
| 118 | diskMetricsMap = Maps.newConcurrentMap(); |
| 119 | networkMetricsMap = Maps.newConcurrentMap(); |
Jian Li | 7d180c5 | 2016-02-01 21:53:08 -0800 | [diff] [blame] | 120 | |
Jian Li | 85060ac | 2016-02-04 09:58:56 -0800 | [diff] [blame] | 121 | cpuBuf = Maps.newConcurrentMap(); |
| 122 | memoryBuf = Maps.newConcurrentMap(); |
| 123 | diskBuf = Maps.newConcurrentMap(); |
| 124 | networkBuf = Maps.newConcurrentMap(); |
| 125 | ctrlMsgBuf = Maps.newConcurrentMap(); |
| 126 | |
| 127 | availableResourceMap = Maps.newConcurrentMap(); |
| 128 | availableDeviceIdSet = Sets.newConcurrentHashSet(); |
Jian Li | 7d180c5 | 2016-02-01 21:53:08 -0800 | [diff] [blame] | 129 | |
Jian Li | 23906cc | 2016-03-31 11:16:44 -0700 | [diff] [blame] | 130 | messageHandlingExecutor = Executors.newSingleThreadScheduledExecutor( |
| 131 | groupedThreads("onos/app/cpman", "message-handlers")); |
| 132 | |
| 133 | communicationService.addSubscriber(CONTROL_STATS, |
| 134 | SERIALIZER::decode, this::handleRequest, messageHandlingExecutor); |
| 135 | |
Jian Li | 7d180c5 | 2016-02-01 21:53:08 -0800 | [diff] [blame] | 136 | log.info("Started"); |
Jian Li | 6080432 | 2015-12-02 14:46:31 -0800 | [diff] [blame] | 137 | } |
| 138 | |
| 139 | @Deactivate |
| 140 | public void deactivate() { |
Jian Li | 7d180c5 | 2016-02-01 21:53:08 -0800 | [diff] [blame] | 141 | |
| 142 | // TODO: need to handle the mdb close. |
| 143 | cpuBuf.clear(); |
| 144 | memoryBuf.clear(); |
| 145 | diskBuf.clear(); |
| 146 | networkBuf.clear(); |
| 147 | ctrlMsgBuf.clear(); |
| 148 | |
Jian Li | 23906cc | 2016-03-31 11:16:44 -0700 | [diff] [blame] | 149 | communicationService.removeSubscriber(CONTROL_STATS); |
| 150 | |
Jian Li | 7d180c5 | 2016-02-01 21:53:08 -0800 | [diff] [blame] | 151 | log.info("Stopped"); |
Jian Li | 6080432 | 2015-12-02 14:46:31 -0800 | [diff] [blame] | 152 | } |
| 153 | |
Jian Li | 6080432 | 2015-12-02 14:46:31 -0800 | [diff] [blame] | 154 | @Override |
Jian Li | c5cb4a1 | 2016-02-03 23:24:42 -0800 | [diff] [blame] | 155 | public void updateMetric(ControlMetric cm, int updateIntervalInMinutes, |
Jian Li | 6080432 | 2015-12-02 14:46:31 -0800 | [diff] [blame] | 156 | Optional<DeviceId> deviceId) { |
Jian Li | 7d180c5 | 2016-02-01 21:53:08 -0800 | [diff] [blame] | 157 | if (deviceId.isPresent()) { |
Jian Li | 4614890 | 2016-01-29 13:33:50 -0800 | [diff] [blame] | 158 | |
Jian Li | 7d180c5 | 2016-02-01 21:53:08 -0800 | [diff] [blame] | 159 | // insert a new device entry if we cannot find any |
Jian Li | 85060ac | 2016-02-04 09:58:56 -0800 | [diff] [blame] | 160 | ctrlMsgBuf.putIfAbsent(deviceId.get(), Maps.newConcurrentMap()); |
Jian Li | 7d180c5 | 2016-02-01 21:53:08 -0800 | [diff] [blame] | 161 | |
| 162 | // update control message metrics |
Jian Li | 85060ac | 2016-02-04 09:58:56 -0800 | [diff] [blame] | 163 | if (CONTROL_MESSAGE_METRICS.contains(cm.metricType())) { |
| 164 | |
| 165 | if (!availableDeviceIdSet.contains(deviceId.get())) { |
| 166 | availableDeviceIdSet.add(deviceId.get()); |
| 167 | } |
Jian Li | 7d180c5 | 2016-02-01 21:53:08 -0800 | [diff] [blame] | 168 | |
| 169 | // we will accumulate the metric value into buffer first |
| 170 | ctrlMsgBuf.get(deviceId.get()).putIfAbsent(cm.metricType(), |
| 171 | (double) cm.metricValue().getLoad()); |
| 172 | |
| 173 | // if buffer contains all control message metrics, |
| 174 | // we simply set and update the values into MetricsDatabase. |
Jian Li | 85060ac | 2016-02-04 09:58:56 -0800 | [diff] [blame] | 175 | if (ctrlMsgBuf.get(deviceId.get()).keySet() |
| 176 | .containsAll(CONTROL_MESSAGE_METRICS)) { |
Jian Li | 7d180c5 | 2016-02-01 21:53:08 -0800 | [diff] [blame] | 177 | updateControlMessages(ctrlMsgBuf.get(deviceId.get()), deviceId.get()); |
Jian Li | daf55ea | 2016-04-04 20:38:30 -0700 | [diff] [blame] | 178 | ctrlMsgBuf.get(deviceId.get()); |
Jian Li | 7d180c5 | 2016-02-01 21:53:08 -0800 | [diff] [blame] | 179 | } |
| 180 | } |
| 181 | } else { |
| 182 | |
| 183 | // update cpu metrics |
| 184 | if (CPU_METRICS.contains(cm.metricType())) { |
| 185 | cpuBuf.putIfAbsent(cm.metricType(), |
| 186 | (double) cm.metricValue().getLoad()); |
| 187 | if (cpuBuf.keySet().containsAll(CPU_METRICS)) { |
| 188 | cpuMetrics.updateMetrics(convertMap(cpuBuf)); |
| 189 | cpuBuf.clear(); |
| 190 | } |
| 191 | } |
| 192 | |
| 193 | // update memory metrics |
| 194 | if (MEMORY_METRICS.contains(cm.metricType())) { |
| 195 | memoryBuf.putIfAbsent(cm.metricType(), |
| 196 | (double) cm.metricValue().getLoad()); |
| 197 | if (memoryBuf.keySet().containsAll(MEMORY_METRICS)) { |
| 198 | memoryMetrics.updateMetrics(convertMap(memoryBuf)); |
| 199 | memoryBuf.clear(); |
| 200 | } |
| 201 | } |
| 202 | } |
Jian Li | 6080432 | 2015-12-02 14:46:31 -0800 | [diff] [blame] | 203 | } |
| 204 | |
| 205 | @Override |
Jian Li | c5cb4a1 | 2016-02-03 23:24:42 -0800 | [diff] [blame] | 206 | public void updateMetric(ControlMetric cm, int updateIntervalInMinutes, |
Jian Li | e044d1a | 2016-01-25 09:01:20 -0800 | [diff] [blame] | 207 | String resourceName) { |
Jian Li | 7d180c5 | 2016-02-01 21:53:08 -0800 | [diff] [blame] | 208 | // update disk metrics |
| 209 | if (DISK_METRICS.contains(cm.metricType())) { |
Jian Li | 85060ac | 2016-02-04 09:58:56 -0800 | [diff] [blame] | 210 | diskBuf.putIfAbsent(resourceName, Maps.newConcurrentMap()); |
| 211 | |
| 212 | availableResourceMap.putIfAbsent(Type.DISK, Sets.newHashSet()); |
| 213 | availableResourceMap.computeIfPresent(Type.DISK, (k, v) -> { |
| 214 | v.add(resourceName); |
| 215 | return v; |
| 216 | }); |
| 217 | |
Jian Li | 7d180c5 | 2016-02-01 21:53:08 -0800 | [diff] [blame] | 218 | diskBuf.get(resourceName).putIfAbsent(cm.metricType(), |
| 219 | (double) cm.metricValue().getLoad()); |
| 220 | if (diskBuf.get(resourceName).keySet().containsAll(DISK_METRICS)) { |
| 221 | updateDiskMetrics(diskBuf.get(resourceName), resourceName); |
| 222 | diskBuf.clear(); |
| 223 | } |
| 224 | } |
Jian Li | e044d1a | 2016-01-25 09:01:20 -0800 | [diff] [blame] | 225 | |
Jian Li | 7d180c5 | 2016-02-01 21:53:08 -0800 | [diff] [blame] | 226 | // update network metrics |
| 227 | if (NETWORK_METRICS.contains(cm.metricType())) { |
Jian Li | 85060ac | 2016-02-04 09:58:56 -0800 | [diff] [blame] | 228 | networkBuf.putIfAbsent(resourceName, Maps.newConcurrentMap()); |
| 229 | |
| 230 | availableResourceMap.putIfAbsent(Type.NETWORK, Sets.newHashSet()); |
| 231 | availableResourceMap.computeIfPresent(Type.NETWORK, (k, v) -> { |
| 232 | v.add(resourceName); |
| 233 | return v; |
| 234 | }); |
| 235 | |
Jian Li | 7d180c5 | 2016-02-01 21:53:08 -0800 | [diff] [blame] | 236 | networkBuf.get(resourceName).putIfAbsent(cm.metricType(), |
| 237 | (double) cm.metricValue().getLoad()); |
| 238 | if (networkBuf.get(resourceName).keySet().containsAll(NETWORK_METRICS)) { |
| 239 | updateNetworkMetrics(networkBuf.get(resourceName), resourceName); |
| 240 | networkBuf.clear(); |
| 241 | } |
| 242 | } |
Jian Li | e044d1a | 2016-01-25 09:01:20 -0800 | [diff] [blame] | 243 | } |
| 244 | |
| 245 | @Override |
Jian Li | 23906cc | 2016-03-31 11:16:44 -0700 | [diff] [blame] | 246 | public ControlLoad getLocalLoad(ControlMetricType type, |
| 247 | Optional<DeviceId> deviceId) { |
| 248 | if (deviceId.isPresent()) { |
| 249 | if (CONTROL_MESSAGE_METRICS.contains(type) && |
| 250 | availableDeviceIdSet.contains(deviceId.get())) { |
| 251 | return new DefaultControlLoad(controlMessageMap.get(deviceId.get()), type); |
Jian Li | 7d180c5 | 2016-02-01 21:53:08 -0800 | [diff] [blame] | 252 | } |
| 253 | } else { |
Jian Li | 23906cc | 2016-03-31 11:16:44 -0700 | [diff] [blame] | 254 | // returns controlLoad of CPU metrics |
| 255 | if (CPU_METRICS.contains(type)) { |
| 256 | return new DefaultControlLoad(cpuMetrics, type); |
| 257 | } |
| 258 | |
| 259 | // returns memoryLoad of memory metrics |
| 260 | if (MEMORY_METRICS.contains(type)) { |
| 261 | return new DefaultControlLoad(memoryMetrics, type); |
| 262 | } |
Jian Li | 7d180c5 | 2016-02-01 21:53:08 -0800 | [diff] [blame] | 263 | } |
Jian Li | 6080432 | 2015-12-02 14:46:31 -0800 | [diff] [blame] | 264 | return null; |
| 265 | } |
| 266 | |
| 267 | @Override |
Jian Li | 23906cc | 2016-03-31 11:16:44 -0700 | [diff] [blame] | 268 | public ControlLoad getLocalLoad(ControlMetricType type, String resourceName) { |
| 269 | if (DISK_METRICS.contains(type) && |
| 270 | availableResources(Type.DISK).contains(resourceName)) { |
| 271 | return new DefaultControlLoad(diskMetricsMap.get(resourceName), type); |
| 272 | } |
Jian Li | 7d180c5 | 2016-02-01 21:53:08 -0800 | [diff] [blame] | 273 | |
Jian Li | 23906cc | 2016-03-31 11:16:44 -0700 | [diff] [blame] | 274 | if (NETWORK_METRICS.contains(type) && |
| 275 | availableResources(Type.NETWORK).contains(resourceName)) { |
| 276 | return new DefaultControlLoad(networkMetricsMap.get(resourceName), type); |
Jian Li | 7d180c5 | 2016-02-01 21:53:08 -0800 | [diff] [blame] | 277 | } |
Jian Li | 6080432 | 2015-12-02 14:46:31 -0800 | [diff] [blame] | 278 | return null; |
| 279 | } |
Jian Li | 7d180c5 | 2016-02-01 21:53:08 -0800 | [diff] [blame] | 280 | |
Jian Li | 85060ac | 2016-02-04 09:58:56 -0800 | [diff] [blame] | 281 | @Override |
Jian Li | 23906cc | 2016-03-31 11:16:44 -0700 | [diff] [blame] | 282 | public CompletableFuture<ControlLoad> getRemoteLoad(NodeId nodeId, |
| 283 | ControlMetricType type, |
| 284 | Optional<DeviceId> deviceId) { |
| 285 | return communicationService.sendAndReceive(createRequest(type, deviceId), |
| 286 | CONTROL_STATS, SERIALIZER::encode, SERIALIZER::decode, nodeId); |
| 287 | } |
| 288 | |
| 289 | @Override |
| 290 | public CompletableFuture<ControlLoad> getRemoteLoad(NodeId nodeId, |
| 291 | ControlMetricType type, |
| 292 | String resourceName) { |
| 293 | return communicationService.sendAndReceive(createRequest(type, resourceName), |
| 294 | CONTROL_STATS, SERIALIZER::encode, SERIALIZER::decode, nodeId); |
| 295 | } |
| 296 | |
| 297 | |
| 298 | @Override |
Jian Li | 85060ac | 2016-02-04 09:58:56 -0800 | [diff] [blame] | 299 | public Set<String> availableResources(Type resourceType) { |
| 300 | if (RESOURCE_TYPE_SET.contains(resourceType)) { |
| 301 | if (Type.CONTROL_MESSAGE.equals(resourceType)) { |
| 302 | return availableDeviceIdSet.stream().map(id -> |
| 303 | id.toString()).collect(Collectors.toSet()); |
| 304 | } else { |
Jian Li | 4563aa2 | 2016-04-04 14:57:38 -0700 | [diff] [blame] | 305 | Set<String> res = availableResourceMap.get(resourceType); |
| 306 | return res == null ? ImmutableSet.of() : res; |
Jian Li | 85060ac | 2016-02-04 09:58:56 -0800 | [diff] [blame] | 307 | } |
| 308 | } |
Jian Li | 4563aa2 | 2016-04-04 14:57:38 -0700 | [diff] [blame] | 309 | return ImmutableSet.of(); |
Jian Li | 85060ac | 2016-02-04 09:58:56 -0800 | [diff] [blame] | 310 | } |
| 311 | |
Jian Li | daf55ea | 2016-04-04 20:38:30 -0700 | [diff] [blame] | 312 | private MetricsDatabase genMDbBuilder(String resourceName, |
| 313 | Type resourceType, |
Jian Li | c5cb4a1 | 2016-02-03 23:24:42 -0800 | [diff] [blame] | 314 | Set<ControlMetricType> metricTypes) { |
Jian Li | 7d180c5 | 2016-02-01 21:53:08 -0800 | [diff] [blame] | 315 | MetricsDatabase.Builder builder = new DefaultMetricsDatabase.Builder(); |
Jian Li | 85060ac | 2016-02-04 09:58:56 -0800 | [diff] [blame] | 316 | builder.withMetricName(resourceType.toString()); |
Jian Li | daf55ea | 2016-04-04 20:38:30 -0700 | [diff] [blame] | 317 | builder.withResourceName(resourceName); |
Jian Li | 7d180c5 | 2016-02-01 21:53:08 -0800 | [diff] [blame] | 318 | metricTypes.forEach(type -> builder.addMetricType(type.toString())); |
| 319 | return builder.build(); |
| 320 | } |
| 321 | |
| 322 | private void updateNetworkMetrics(Map<ControlMetricType, Double> metricMap, |
| 323 | String resName) { |
Jian Li | daf55ea | 2016-04-04 20:38:30 -0700 | [diff] [blame] | 324 | networkMetricsMap.putIfAbsent(resName, genMDbBuilder(resName, |
| 325 | Type.NETWORK, NETWORK_METRICS)); |
Jian Li | 7d180c5 | 2016-02-01 21:53:08 -0800 | [diff] [blame] | 326 | networkMetricsMap.get(resName).updateMetrics(convertMap(metricMap)); |
| 327 | } |
| 328 | |
| 329 | private void updateDiskMetrics(Map<ControlMetricType, Double> metricMap, |
| 330 | String resName) { |
Jian Li | daf55ea | 2016-04-04 20:38:30 -0700 | [diff] [blame] | 331 | diskMetricsMap.putIfAbsent(resName, genMDbBuilder(resName, |
| 332 | Type.DISK, DISK_METRICS)); |
Jian Li | 7d180c5 | 2016-02-01 21:53:08 -0800 | [diff] [blame] | 333 | diskMetricsMap.get(resName).updateMetrics(convertMap(metricMap)); |
| 334 | } |
| 335 | |
| 336 | private void updateControlMessages(Map<ControlMetricType, Double> metricMap, |
| 337 | DeviceId devId) { |
Jian Li | daf55ea | 2016-04-04 20:38:30 -0700 | [diff] [blame] | 338 | controlMessageMap.putIfAbsent(devId, genMDbBuilder(devId.toString(), |
| 339 | Type.CONTROL_MESSAGE, CONTROL_MESSAGE_METRICS)); |
Jian Li | 7d180c5 | 2016-02-01 21:53:08 -0800 | [diff] [blame] | 340 | controlMessageMap.get(devId).updateMetrics(convertMap(metricMap)); |
| 341 | } |
| 342 | |
| 343 | private Map convertMap(Map<ControlMetricType, Double> map) { |
Jian Li | 9f3a885 | 2016-04-07 13:37:39 -0700 | [diff] [blame] | 344 | if (map == null) { |
| 345 | return ImmutableMap.of(); |
| 346 | } |
Jian Li | 85060ac | 2016-02-04 09:58:56 -0800 | [diff] [blame] | 347 | Map newMap = Maps.newConcurrentMap(); |
Jian Li | 7d180c5 | 2016-02-01 21:53:08 -0800 | [diff] [blame] | 348 | map.forEach((k, v) -> newMap.putIfAbsent(k.toString(), v)); |
| 349 | return newMap; |
| 350 | } |
Jian Li | 23906cc | 2016-03-31 11:16:44 -0700 | [diff] [blame] | 351 | |
| 352 | private CompletableFuture<ControlLoad> handleRequest(ControlMetricsRequest request) { |
| 353 | |
| 354 | checkArgument(request.getType() != null, METRIC_TYPE_NULL); |
| 355 | |
| 356 | ControlLoad load; |
| 357 | if (request.getResourceName() != null) { |
| 358 | load = getLocalLoad(request.getType(), request.getResourceName()); |
| 359 | } else { |
| 360 | load = getLocalLoad(request.getType(), request.getDeviceId()); |
| 361 | } |
| 362 | return CompletableFuture.completedFuture(load); |
| 363 | } |
| 364 | |
| 365 | private ControlMetricsRequest createRequest(ControlMetricType type, |
| 366 | Optional<DeviceId> deviceId) { |
| 367 | return new ControlMetricsRequest(type, deviceId); |
| 368 | } |
| 369 | |
| 370 | private ControlMetricsRequest createRequest(ControlMetricType type, |
| 371 | String resourceName) { |
| 372 | return new ControlMetricsRequest(type, resourceName); |
| 373 | } |
| 374 | } |