blob: b48a25b43a3904b5e4e415978ba013b6fe17a7c6 [file] [log] [blame]
alshabib1d2bc402015-07-31 17:04:11 -07001/*
2 * Copyright 2015 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 */
16package org.onosproject.incubator.net.meter.impl;
17
18import org.apache.felix.scr.annotations.Activate;
19import org.apache.felix.scr.annotations.Component;
20import org.apache.felix.scr.annotations.Deactivate;
21import org.apache.felix.scr.annotations.Reference;
22import org.apache.felix.scr.annotations.ReferenceCardinality;
23import org.apache.felix.scr.annotations.Service;
alshabibeadfc8e2015-08-18 15:40:46 -070024import org.onlab.util.TriConsumer;
alshabib10c810b2015-08-18 16:59:04 -070025import org.onosproject.net.meter.DefaultMeter;
26import org.onosproject.net.meter.Meter;
27import org.onosproject.net.meter.MeterEvent;
28import org.onosproject.net.meter.MeterFailReason;
29import org.onosproject.net.meter.MeterId;
30import org.onosproject.net.meter.MeterListener;
31import org.onosproject.net.meter.MeterOperation;
32import org.onosproject.net.meter.MeterProvider;
33import org.onosproject.net.meter.MeterProviderRegistry;
34import org.onosproject.net.meter.MeterProviderService;
35import org.onosproject.net.meter.MeterService;
36import org.onosproject.net.meter.MeterState;
37import org.onosproject.net.meter.MeterStore;
38import org.onosproject.net.meter.MeterStoreDelegate;
39import org.onosproject.net.meter.MeterStoreResult;
alshabib1d2bc402015-07-31 17:04:11 -070040import org.onosproject.net.DeviceId;
41import org.onosproject.net.provider.AbstractListenerProviderRegistry;
42import org.onosproject.net.provider.AbstractProviderService;
43import org.onosproject.store.service.AtomicCounter;
44import org.onosproject.store.service.StorageService;
45import org.slf4j.Logger;
46
47import java.util.Collection;
alshabib5eb79392015-08-19 18:09:55 -070048import java.util.Map;
49import java.util.stream.Collectors;
alshabib1d2bc402015-07-31 17:04:11 -070050
51import static org.slf4j.LoggerFactory.getLogger;
52
53
54/**
55 * Provides implementation of the meter service APIs.
56 */
alshabib58fe6dc2015-08-19 17:16:13 -070057@Component(immediate = true, enabled = true)
alshabib1d2bc402015-07-31 17:04:11 -070058@Service
59public class MeterManager extends AbstractListenerProviderRegistry<MeterEvent, MeterListener,
60 MeterProvider, MeterProviderService>
61 implements MeterService, MeterProviderRegistry {
62
63 private final String meterIdentifier = "meter-id-counter";
64 private final Logger log = getLogger(getClass());
65 private final MeterStoreDelegate delegate = new InternalMeterStoreDelegate();
66
67 @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
68 protected StorageService storageService;
69
alshabib7bb05012015-08-05 10:15:09 -070070 @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
alshabib58fe6dc2015-08-19 17:16:13 -070071 protected MeterStore store;
alshabib7bb05012015-08-05 10:15:09 -070072
alshabib1d2bc402015-07-31 17:04:11 -070073 private AtomicCounter meterIdCounter;
74
alshabibeadfc8e2015-08-18 15:40:46 -070075 private TriConsumer<MeterOperation, MeterStoreResult, Throwable> onComplete;
76
alshabib1d2bc402015-07-31 17:04:11 -070077 @Activate
78 public void activate() {
79 meterIdCounter = storageService.atomicCounterBuilder()
80 .withName(meterIdentifier)
81 .build();
alshabibeadfc8e2015-08-18 15:40:46 -070082
alshabib58fe6dc2015-08-19 17:16:13 -070083 store.setDelegate(delegate);
84
alshabibeadfc8e2015-08-18 15:40:46 -070085 onComplete = (op, result, error) ->
86 {
87 op.context().ifPresent(c -> {
88 if (error != null) {
89 c.onError(op.meter(), MeterFailReason.UNKNOWN);
90 } else {
91 if (result.reason().isPresent()) {
92 c.onError(op.meter(), result.reason().get());
93 } else {
94 c.onSuccess(op.meter());
95 }
96 }
97 });
98
99 };
alshabib1d2bc402015-07-31 17:04:11 -0700100 log.info("Started");
101 }
102
103 @Deactivate
104 public void deactivate() {
alshabib58fe6dc2015-08-19 17:16:13 -0700105 store.unsetDelegate(delegate);
alshabib1d2bc402015-07-31 17:04:11 -0700106 log.info("Stopped");
107 }
108
109 @Override
110 protected MeterProviderService createProviderService(MeterProvider provider) {
111 return new InternalMeterProviderService(provider);
112 }
113
114 @Override
alshabibeadfc8e2015-08-18 15:40:46 -0700115 public void addMeter(MeterOperation op) {
116 DefaultMeter m = (DefaultMeter) op.meter();
alshabib7bb05012015-08-05 10:15:09 -0700117 m.setState(MeterState.PENDING_ADD);
alshabibeadfc8e2015-08-18 15:40:46 -0700118 store.storeMeter(m).whenComplete((result, error) ->
119 onComplete.accept(op, result, error));
alshabib1d2bc402015-07-31 17:04:11 -0700120 }
121
122 @Override
alshabibeadfc8e2015-08-18 15:40:46 -0700123 public void updateMeter(MeterOperation op) {
124 DefaultMeter m = (DefaultMeter) op.meter();
alshabib7bb05012015-08-05 10:15:09 -0700125 m.setState(MeterState.PENDING_ADD);
alshabibeadfc8e2015-08-18 15:40:46 -0700126 store.updateMeter(m).whenComplete((result, error) ->
127 onComplete.accept(op, result, error));
alshabib1d2bc402015-07-31 17:04:11 -0700128 }
129
130 @Override
alshabibeadfc8e2015-08-18 15:40:46 -0700131 public void removeMeter(MeterOperation op) {
132 DefaultMeter m = (DefaultMeter) op.meter();
alshabib7bb05012015-08-05 10:15:09 -0700133 m.setState(MeterState.PENDING_REMOVE);
alshabibeadfc8e2015-08-18 15:40:46 -0700134 store.deleteMeter(m).whenComplete((result, error) ->
135 onComplete.accept(op, result, error));
alshabib1d2bc402015-07-31 17:04:11 -0700136 }
137
138 @Override
139 public Meter getMeter(MeterId id) {
alshabib7bb05012015-08-05 10:15:09 -0700140 return store.getMeter(id);
alshabib1d2bc402015-07-31 17:04:11 -0700141 }
142
143 @Override
alshabib58fe6dc2015-08-19 17:16:13 -0700144 public Collection<Meter> getAllMeters() {
145 return store.getAllMeters();
146 }
147
148 @Override
alshabib1d2bc402015-07-31 17:04:11 -0700149 public MeterId allocateMeterId() {
150 // FIXME: This will break one day.
151 return MeterId.meterId((int) meterIdCounter.getAndIncrement());
152 }
153
154 private class InternalMeterProviderService
155 extends AbstractProviderService<MeterProvider>
156 implements MeterProviderService {
157
158 /**
159 * Creates a provider service on behalf of the specified provider.
160 *
161 * @param provider provider to which this service is being issued
162 */
163 protected InternalMeterProviderService(MeterProvider provider) {
164 super(provider);
165 }
166
167 @Override
alshabib7bb05012015-08-05 10:15:09 -0700168 public void meterOperationFailed(MeterOperation operation,
169 MeterFailReason reason) {
170 store.failedMeter(operation, reason);
alshabib1d2bc402015-07-31 17:04:11 -0700171 }
172
173 @Override
174 public void pushMeterMetrics(DeviceId deviceId, Collection<Meter> meterEntries) {
alshabib5eb79392015-08-19 18:09:55 -0700175 //FIXME: FOLLOWING CODE CANNOT BE TESTED UNTIL SOMETHING THAT
176 //FIXME: IMPLEMENTS METERS EXISTS
177 Map<MeterId, Meter> storedMeterMap = store.getAllMeters().stream()
178 .collect(Collectors.toMap(Meter::id, m -> m));
179
180 meterEntries.stream()
181 .filter(m -> storedMeterMap.remove(m.id()) != null)
182 .forEach(m -> store.updateMeterState(m));
183
184 storedMeterMap.values().stream().forEach(m -> {
185 if (m.state() == MeterState.PENDING_ADD) {
186 provider().performMeterOperation(m.deviceId(),
187 new MeterOperation(m,
188 MeterOperation.Type.ADD,
189 null));
190 } else {
191 store.deleteMeterNow(m);
192 }
193 });
alshabib1d2bc402015-07-31 17:04:11 -0700194 }
195 }
196
197 private class InternalMeterStoreDelegate implements MeterStoreDelegate {
198
199 @Override
200 public void notify(MeterEvent event) {
alshabibeadfc8e2015-08-18 15:40:46 -0700201 DeviceId deviceId = event.subject().deviceId();
202 MeterProvider p = getProvider(event.subject().deviceId());
alshabib7bb05012015-08-05 10:15:09 -0700203 switch (event.type()) {
alshabibeadfc8e2015-08-18 15:40:46 -0700204 case METER_ADD_REQ:
205 p.performMeterOperation(deviceId, new MeterOperation(event.subject(),
206 MeterOperation.Type.ADD,
207 null));
alshabib7bb05012015-08-05 10:15:09 -0700208 break;
alshabibeadfc8e2015-08-18 15:40:46 -0700209 case METER_REM_REQ:
210 p.performMeterOperation(deviceId, new MeterOperation(event.subject(),
211 MeterOperation.Type.REMOVE,
212 null));
alshabib7bb05012015-08-05 10:15:09 -0700213 break;
214 default:
215 log.warn("Unknown meter event {}", event.type());
216 }
alshabib1d2bc402015-07-31 17:04:11 -0700217
218 }
219 }
220
221}