blob: d641bdc3f662e8abef0add7f586917c7f4ee2666 [file] [log] [blame]
Jian Li1d13c262016-02-09 14:58:28 -08001/*
Brian O'Connor5ab426f2016-04-09 01:19:45 -07002 * Copyright 2016-present Open Networking Laboratory
Jian Li1d13c262016-02-09 14:58:28 -08003 *
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
17package org.onosproject.provider.of.message.impl;
18
19import com.codahale.metrics.Meter;
20import com.google.common.collect.ImmutableSet;
21import com.google.common.collect.Maps;
Jian Li72b9b122016-02-11 15:58:51 -080022import com.google.common.collect.Sets;
Jian Li1d13c262016-02-09 14:58:28 -080023import org.onlab.metrics.MetricsComponent;
24import org.onlab.metrics.MetricsFeature;
25import org.onlab.metrics.MetricsService;
26import org.onosproject.cpman.ControlMessage;
27import org.onosproject.cpman.DefaultControlMessage;
28import org.onosproject.cpman.message.ControlMessageProviderService;
29import org.onosproject.net.DeviceId;
30import org.projectfloodlight.openflow.protocol.OFMessage;
31import org.projectfloodlight.openflow.protocol.OFType;
Jian Li7d9d4392016-02-11 11:41:26 -080032import org.slf4j.Logger;
Jian Li1d13c262016-02-09 14:58:28 -080033
Jian Li1d13c262016-02-09 14:58:28 -080034import java.util.Map;
35import java.util.Set;
36
37import static org.onosproject.provider.of.message.impl.OpenFlowControlMessageMapper.lookupControlMessageType;
Jian Li7d9d4392016-02-11 11:41:26 -080038import static org.slf4j.LoggerFactory.getLogger;
Jian Li1d13c262016-02-09 14:58:28 -080039
40/**
41 * Collects the OpenFlow messages and aggregates using MetricsService.
42 */
43public class OpenFlowControlMessageAggregator implements Runnable {
44
Jian Li7d9d4392016-02-11 11:41:26 -080045 private final Logger log = getLogger(getClass());
46
Jian Li1d13c262016-02-09 14:58:28 -080047 private static final Set<OFType> OF_TYPE_SET =
48 ImmutableSet.of(OFType.PACKET_IN, OFType.PACKET_OUT, OFType.FLOW_MOD,
49 OFType.FLOW_REMOVED, OFType.STATS_REQUEST, OFType.STATS_REPLY);
50
51 private final Map<OFType, Meter> rateMeterMap = Maps.newHashMap();
52 private final Map<OFType, Meter> countMeterMap = Maps.newHashMap();
53
54 private final DeviceId deviceId;
55 private final ControlMessageProviderService providerService;
56
57 private static final String RATE_NAME = "rate";
58 private static final String COUNT_NAME = "count";
59
Jian Li72b9b122016-02-11 15:58:51 -080060 private Set<ControlMessage> controlMessages = Sets.newConcurrentHashSet();
Jian Li1d13c262016-02-09 14:58:28 -080061
62 // TODO: this needs to be configurable
63 private static final int EXECUTE_PERIOD_IN_SECOND = 60;
64
65 /**
66 * Generates an OpenFlow message aggregator instance.
67 * The instance is for aggregating a specific OpenFlow message
68 * type of an OpenFlow switch.
69 *
70 * @param metricsService metrics service reference object
71 * @param providerService control message provider service reference object
72 * @param deviceId device identification
73 */
74 public OpenFlowControlMessageAggregator(MetricsService metricsService,
75 ControlMessageProviderService providerService,
76 DeviceId deviceId) {
77 MetricsComponent mc = metricsService.registerComponent(deviceId.toString());
78
79 OF_TYPE_SET.forEach(type -> {
80 MetricsFeature metricsFeature = mc.registerFeature(type.toString());
81 Meter rateMeter = metricsService.createMeter(mc, metricsFeature, RATE_NAME);
82 Meter countMeter = metricsService.createMeter(mc, metricsFeature, COUNT_NAME);
83 rateMeterMap.put(type, rateMeter);
84 countMeterMap.put(type, countMeter);
85 });
86
87 this.deviceId = deviceId;
88 this.providerService = providerService;
Jian Li55cbd5c2016-04-06 09:50:20 -070089 metricsService.notifyReporters();
Jian Li1d13c262016-02-09 14:58:28 -080090 }
91
92 /**
93 * Increments the meter rate by n, and the meter count by 1.
94 *
95 * @param msg OpenFlow message
96 */
97 public void increment(OFMessage msg) {
98 rateMeterMap.get(msg.getType()).mark(msg.toString().length());
99 countMeterMap.get(msg.getType()).mark(1);
100 }
101
102 @Override
103 public void run() {
104 // update 1 minute statistic information of all control messages
105 OF_TYPE_SET.forEach(type -> controlMessages.add(
106 new DefaultControlMessage(lookupControlMessageType(type),
Jian Li72b9b122016-02-11 15:58:51 -0800107 deviceId, getLoad(type), getRate(type), getCount(type),
Jian Li1d13c262016-02-09 14:58:28 -0800108 System.currentTimeMillis())));
Jian Li7d9d4392016-02-11 11:41:26 -0800109 log.debug("sent aggregated control message");
Jian Li72b9b122016-02-11 15:58:51 -0800110 providerService.updateStatsInfo(deviceId, ImmutableSet.copyOf(controlMessages));
Jian Li7d9d4392016-02-11 11:41:26 -0800111 controlMessages.clear();
Jian Li1d13c262016-02-09 14:58:28 -0800112 }
113
114 /**
115 * Returns the average load value.
116 *
117 * @param type OpenFlow message type
118 * @return load value
119 */
120 private long getLoad(OFType type) {
Jian Li7d9d4392016-02-11 11:41:26 -0800121 if (countMeterMap.get(type).getOneMinuteRate() == 0D) {
122 return 0L;
123 }
Jian Li72b9b122016-02-11 15:58:51 -0800124 return (long) (rateMeterMap.get(type).getOneMinuteRate() /
125 countMeterMap.get(type).getOneMinuteRate());
Jian Li1d13c262016-02-09 14:58:28 -0800126 }
127
128 /**
129 * Returns the average meter rate within recent 1 minute.
130 *
131 * @param type OpenFlow message type
132 * @return rate value
133 */
134 private long getRate(OFType type) {
135 return (long) rateMeterMap.get(type).getOneMinuteRate();
136 }
137
138 /**
139 * Returns the average meter count within recent 1 minute.
140 *
141 * @param type OpenFlow message type
142 * @return count value
143 */
144 private long getCount(OFType type) {
Jian Lidaf55ea2016-04-04 20:38:30 -0700145 return (long) (countMeterMap.get(type).getOneMinuteRate()
146 * EXECUTE_PERIOD_IN_SECOND);
Jian Li1d13c262016-02-09 14:58:28 -0800147 }
148}