blob: 0ce4ce767db3a1951753722ef260932cdb9e6a5b [file] [log] [blame]
Jian Li1d13c262016-02-09 14:58:28 -08001/*
2 * Copyright 2016 Open Networking Laboratory
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
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;
22import org.onlab.metrics.MetricsComponent;
23import org.onlab.metrics.MetricsFeature;
24import org.onlab.metrics.MetricsService;
25import org.onosproject.cpman.ControlMessage;
26import org.onosproject.cpman.DefaultControlMessage;
27import org.onosproject.cpman.message.ControlMessageProviderService;
28import org.onosproject.net.DeviceId;
29import org.projectfloodlight.openflow.protocol.OFMessage;
30import org.projectfloodlight.openflow.protocol.OFType;
31
32import java.util.ArrayList;
33import java.util.Collection;
34import java.util.Collections;
35import java.util.Map;
36import java.util.Set;
37
38import static org.onosproject.provider.of.message.impl.OpenFlowControlMessageMapper.lookupControlMessageType;
39
40/**
41 * Collects the OpenFlow messages and aggregates using MetricsService.
42 */
43public class OpenFlowControlMessageAggregator implements Runnable {
44
45 private static final Set<OFType> OF_TYPE_SET =
46 ImmutableSet.of(OFType.PACKET_IN, OFType.PACKET_OUT, OFType.FLOW_MOD,
47 OFType.FLOW_REMOVED, OFType.STATS_REQUEST, OFType.STATS_REPLY);
48
49 private final Map<OFType, Meter> rateMeterMap = Maps.newHashMap();
50 private final Map<OFType, Meter> countMeterMap = Maps.newHashMap();
51
52 private final DeviceId deviceId;
53 private final ControlMessageProviderService providerService;
54
55 private static final String RATE_NAME = "rate";
56 private static final String COUNT_NAME = "count";
57
58 private Collection<ControlMessage> controlMessages = new ArrayList<>();
59
60 // TODO: this needs to be configurable
61 private static final int EXECUTE_PERIOD_IN_SECOND = 60;
62
63 /**
64 * Generates an OpenFlow message aggregator instance.
65 * The instance is for aggregating a specific OpenFlow message
66 * type of an OpenFlow switch.
67 *
68 * @param metricsService metrics service reference object
69 * @param providerService control message provider service reference object
70 * @param deviceId device identification
71 */
72 public OpenFlowControlMessageAggregator(MetricsService metricsService,
73 ControlMessageProviderService providerService,
74 DeviceId deviceId) {
75 MetricsComponent mc = metricsService.registerComponent(deviceId.toString());
76
77 OF_TYPE_SET.forEach(type -> {
78 MetricsFeature metricsFeature = mc.registerFeature(type.toString());
79 Meter rateMeter = metricsService.createMeter(mc, metricsFeature, RATE_NAME);
80 Meter countMeter = metricsService.createMeter(mc, metricsFeature, COUNT_NAME);
81 rateMeterMap.put(type, rateMeter);
82 countMeterMap.put(type, countMeter);
83 });
84
85 this.deviceId = deviceId;
86 this.providerService = providerService;
87 }
88
89 /**
90 * Increments the meter rate by n, and the meter count by 1.
91 *
92 * @param msg OpenFlow message
93 */
94 public void increment(OFMessage msg) {
95 rateMeterMap.get(msg.getType()).mark(msg.toString().length());
96 countMeterMap.get(msg.getType()).mark(1);
97 }
98
99 @Override
100 public void run() {
101 // update 1 minute statistic information of all control messages
102 OF_TYPE_SET.forEach(type -> controlMessages.add(
103 new DefaultControlMessage(lookupControlMessageType(type),
104 getLoad(type), getRate(type), getCount(type),
105 System.currentTimeMillis())));
106 providerService.updateStatsInfo(deviceId,
107 Collections.unmodifiableCollection(controlMessages));
108 }
109
110 /**
111 * Returns the average load value.
112 *
113 * @param type OpenFlow message type
114 * @return load value
115 */
116 private long getLoad(OFType type) {
117 return (long) rateMeterMap.get(type).getOneMinuteRate() /
118 (long) countMeterMap.get(type).getOneMinuteRate();
119 }
120
121 /**
122 * Returns the average meter rate within recent 1 minute.
123 *
124 * @param type OpenFlow message type
125 * @return rate value
126 */
127 private long getRate(OFType type) {
128 return (long) rateMeterMap.get(type).getOneMinuteRate();
129 }
130
131 /**
132 * Returns the average meter count within recent 1 minute.
133 *
134 * @param type OpenFlow message type
135 * @return count value
136 */
137 private long getCount(OFType type) {
138 return (long) countMeterMap.get(type).getOneMinuteRate() *
139 EXECUTE_PERIOD_IN_SECOND;
140 }
141}