blob: 47450c72f58062b1cb99bac298483493a2f39533 [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;
alshabib7bb05012015-08-05 10:15:09 -070025import org.onosproject.incubator.net.meter.DefaultMeter;
alshabib1d2bc402015-07-31 17:04:11 -070026import org.onosproject.incubator.net.meter.Meter;
27import org.onosproject.incubator.net.meter.MeterEvent;
28import org.onosproject.incubator.net.meter.MeterFailReason;
29import org.onosproject.incubator.net.meter.MeterId;
30import org.onosproject.incubator.net.meter.MeterListener;
31import org.onosproject.incubator.net.meter.MeterOperation;
32import org.onosproject.incubator.net.meter.MeterProvider;
33import org.onosproject.incubator.net.meter.MeterProviderRegistry;
34import org.onosproject.incubator.net.meter.MeterProviderService;
35import org.onosproject.incubator.net.meter.MeterService;
alshabib7bb05012015-08-05 10:15:09 -070036import org.onosproject.incubator.net.meter.MeterState;
37import org.onosproject.incubator.net.meter.MeterStore;
alshabib1d2bc402015-07-31 17:04:11 -070038import org.onosproject.incubator.net.meter.MeterStoreDelegate;
alshabibeadfc8e2015-08-18 15:40:46 -070039import org.onosproject.incubator.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;
48
49import static org.slf4j.LoggerFactory.getLogger;
50
51
52/**
53 * Provides implementation of the meter service APIs.
54 */
55@Component(immediate = true)
56@Service
57public class MeterManager extends AbstractListenerProviderRegistry<MeterEvent, MeterListener,
58 MeterProvider, MeterProviderService>
59 implements MeterService, MeterProviderRegistry {
60
61 private final String meterIdentifier = "meter-id-counter";
62 private final Logger log = getLogger(getClass());
63 private final MeterStoreDelegate delegate = new InternalMeterStoreDelegate();
64
65 @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
66 protected StorageService storageService;
67
alshabib7bb05012015-08-05 10:15:09 -070068 @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
69 MeterStore store;
70
alshabib1d2bc402015-07-31 17:04:11 -070071 private AtomicCounter meterIdCounter;
72
alshabibeadfc8e2015-08-18 15:40:46 -070073 private TriConsumer<MeterOperation, MeterStoreResult, Throwable> onComplete;
74
alshabib1d2bc402015-07-31 17:04:11 -070075 @Activate
76 public void activate() {
77 meterIdCounter = storageService.atomicCounterBuilder()
78 .withName(meterIdentifier)
79 .build();
alshabibeadfc8e2015-08-18 15:40:46 -070080
81 onComplete = (op, result, error) ->
82 {
83 op.context().ifPresent(c -> {
84 if (error != null) {
85 c.onError(op.meter(), MeterFailReason.UNKNOWN);
86 } else {
87 if (result.reason().isPresent()) {
88 c.onError(op.meter(), result.reason().get());
89 } else {
90 c.onSuccess(op.meter());
91 }
92 }
93 });
94
95 };
alshabib1d2bc402015-07-31 17:04:11 -070096 log.info("Started");
97 }
98
99 @Deactivate
100 public void deactivate() {
101 log.info("Stopped");
102 }
103
104 @Override
105 protected MeterProviderService createProviderService(MeterProvider provider) {
106 return new InternalMeterProviderService(provider);
107 }
108
109 @Override
alshabibeadfc8e2015-08-18 15:40:46 -0700110 public void addMeter(MeterOperation op) {
111 DefaultMeter m = (DefaultMeter) op.meter();
alshabib7bb05012015-08-05 10:15:09 -0700112 m.setState(MeterState.PENDING_ADD);
alshabibeadfc8e2015-08-18 15:40:46 -0700113 store.storeMeter(m).whenComplete((result, error) ->
114 onComplete.accept(op, result, error));
alshabib1d2bc402015-07-31 17:04:11 -0700115 }
116
117 @Override
alshabibeadfc8e2015-08-18 15:40:46 -0700118 public void updateMeter(MeterOperation op) {
119 DefaultMeter m = (DefaultMeter) op.meter();
alshabib7bb05012015-08-05 10:15:09 -0700120 m.setState(MeterState.PENDING_ADD);
alshabibeadfc8e2015-08-18 15:40:46 -0700121 store.updateMeter(m).whenComplete((result, error) ->
122 onComplete.accept(op, result, error));
alshabib1d2bc402015-07-31 17:04:11 -0700123 }
124
125 @Override
alshabibeadfc8e2015-08-18 15:40:46 -0700126 public void removeMeter(MeterOperation op) {
127 DefaultMeter m = (DefaultMeter) op.meter();
alshabib7bb05012015-08-05 10:15:09 -0700128 m.setState(MeterState.PENDING_REMOVE);
alshabibeadfc8e2015-08-18 15:40:46 -0700129 store.deleteMeter(m).whenComplete((result, error) ->
130 onComplete.accept(op, result, error));
alshabib1d2bc402015-07-31 17:04:11 -0700131 }
132
133 @Override
134 public Meter getMeter(MeterId id) {
alshabib7bb05012015-08-05 10:15:09 -0700135 return store.getMeter(id);
alshabib1d2bc402015-07-31 17:04:11 -0700136 }
137
138 @Override
139 public MeterId allocateMeterId() {
140 // FIXME: This will break one day.
141 return MeterId.meterId((int) meterIdCounter.getAndIncrement());
142 }
143
144 private class InternalMeterProviderService
145 extends AbstractProviderService<MeterProvider>
146 implements MeterProviderService {
147
148 /**
149 * Creates a provider service on behalf of the specified provider.
150 *
151 * @param provider provider to which this service is being issued
152 */
153 protected InternalMeterProviderService(MeterProvider provider) {
154 super(provider);
155 }
156
157 @Override
alshabib7bb05012015-08-05 10:15:09 -0700158 public void meterOperationFailed(MeterOperation operation,
159 MeterFailReason reason) {
160 store.failedMeter(operation, reason);
alshabib1d2bc402015-07-31 17:04:11 -0700161 }
162
163 @Override
164 public void pushMeterMetrics(DeviceId deviceId, Collection<Meter> meterEntries) {
alshabib7bb05012015-08-05 10:15:09 -0700165 meterEntries.forEach(m -> store.updateMeterState(m));
alshabib1d2bc402015-07-31 17:04:11 -0700166 }
167 }
168
169 private class InternalMeterStoreDelegate implements MeterStoreDelegate {
170
171 @Override
172 public void notify(MeterEvent event) {
alshabibeadfc8e2015-08-18 15:40:46 -0700173 DeviceId deviceId = event.subject().deviceId();
174 MeterProvider p = getProvider(event.subject().deviceId());
alshabib7bb05012015-08-05 10:15:09 -0700175 switch (event.type()) {
alshabibeadfc8e2015-08-18 15:40:46 -0700176 case METER_ADD_REQ:
177 p.performMeterOperation(deviceId, new MeterOperation(event.subject(),
178 MeterOperation.Type.ADD,
179 null));
alshabib7bb05012015-08-05 10:15:09 -0700180 break;
alshabibeadfc8e2015-08-18 15:40:46 -0700181 case METER_REM_REQ:
182 p.performMeterOperation(deviceId, new MeterOperation(event.subject(),
183 MeterOperation.Type.REMOVE,
184 null));
alshabib7bb05012015-08-05 10:15:09 -0700185 break;
186 default:
187 log.warn("Unknown meter event {}", event.type());
188 }
alshabib1d2bc402015-07-31 17:04:11 -0700189
190 }
191 }
192
193}