diff options
author | Ashlee Young <ashlee@onosfw.com> | 2015-09-09 22:15:21 -0700 |
---|---|---|
committer | Ashlee Young <ashlee@onosfw.com> | 2015-09-09 22:15:21 -0700 |
commit | 13d05bc8458758ee39cb829098241e89616717ee (patch) | |
tree | 22a4d1ce65f15952f07a3df5af4b462b4697cb3a /framework/src/onos/incubator/net/src/main/java/org/onosproject/incubator/net/meter/impl/MeterManager.java | |
parent | 6139282e1e93c2322076de4b91b1c85d0bc4a8b3 (diff) |
ONOS checkin based on commit tag e796610b1f721d02f9b0e213cf6f7790c10ecd60
Change-Id: Ife8810491034fe7becdba75dda20de4267bd15cd
Diffstat (limited to 'framework/src/onos/incubator/net/src/main/java/org/onosproject/incubator/net/meter/impl/MeterManager.java')
-rw-r--r-- | framework/src/onos/incubator/net/src/main/java/org/onosproject/incubator/net/meter/impl/MeterManager.java | 233 |
1 files changed, 233 insertions, 0 deletions
diff --git a/framework/src/onos/incubator/net/src/main/java/org/onosproject/incubator/net/meter/impl/MeterManager.java b/framework/src/onos/incubator/net/src/main/java/org/onosproject/incubator/net/meter/impl/MeterManager.java new file mode 100644 index 00000000..575a7153 --- /dev/null +++ b/framework/src/onos/incubator/net/src/main/java/org/onosproject/incubator/net/meter/impl/MeterManager.java @@ -0,0 +1,233 @@ +/* + * Copyright 2015 Open Networking Laboratory + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.onosproject.incubator.net.meter.impl; + +import org.apache.felix.scr.annotations.Activate; +import org.apache.felix.scr.annotations.Component; +import org.apache.felix.scr.annotations.Deactivate; +import org.apache.felix.scr.annotations.Reference; +import org.apache.felix.scr.annotations.ReferenceCardinality; +import org.apache.felix.scr.annotations.Service; +import org.onlab.util.TriConsumer; +import org.onosproject.net.meter.DefaultMeter; +import org.onosproject.net.meter.Meter; +import org.onosproject.net.meter.MeterEvent; +import org.onosproject.net.meter.MeterFailReason; +import org.onosproject.net.meter.MeterId; +import org.onosproject.net.meter.MeterListener; +import org.onosproject.net.meter.MeterOperation; +import org.onosproject.net.meter.MeterProvider; +import org.onosproject.net.meter.MeterProviderRegistry; +import org.onosproject.net.meter.MeterProviderService; +import org.onosproject.net.meter.MeterRequest; +import org.onosproject.net.meter.MeterService; +import org.onosproject.net.meter.MeterState; +import org.onosproject.net.meter.MeterStore; +import org.onosproject.net.meter.MeterStoreDelegate; +import org.onosproject.net.meter.MeterStoreResult; +import org.onosproject.net.DeviceId; +import org.onosproject.net.provider.AbstractListenerProviderRegistry; +import org.onosproject.net.provider.AbstractProviderService; +import org.onosproject.store.service.AtomicCounter; +import org.onosproject.store.service.StorageService; +import org.slf4j.Logger; + +import java.util.Collection; +import java.util.Map; +import java.util.stream.Collectors; + +import static org.slf4j.LoggerFactory.getLogger; + + +/** + * Provides implementation of the meter service APIs. + */ +@Component(immediate = true, enabled = true) +@Service +public class MeterManager extends AbstractListenerProviderRegistry<MeterEvent, MeterListener, + MeterProvider, MeterProviderService> + implements MeterService, MeterProviderRegistry { + + private final String meterIdentifier = "meter-id-counter"; + private final Logger log = getLogger(getClass()); + private final MeterStoreDelegate delegate = new InternalMeterStoreDelegate(); + + @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY) + protected StorageService storageService; + + @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY) + protected MeterStore store; + + private AtomicCounter meterIdCounter; + + private TriConsumer<MeterRequest, MeterStoreResult, Throwable> onComplete; + + @Activate + public void activate() { + meterIdCounter = storageService.atomicCounterBuilder() + .withName(meterIdentifier) + .build(); + + store.setDelegate(delegate); + + onComplete = (request, result, error) -> + { + request.context().ifPresent(c -> { + if (error != null) { + c.onError(request, MeterFailReason.UNKNOWN); + } else { + if (result.reason().isPresent()) { + c.onError(request, result.reason().get()); + } else { + c.onSuccess(request); + } + } + }); + + }; + log.info("Started"); + } + + @Deactivate + public void deactivate() { + store.unsetDelegate(delegate); + log.info("Stopped"); + } + + @Override + protected MeterProviderService createProviderService(MeterProvider provider) { + return new InternalMeterProviderService(provider); + } + + @Override + public Meter submit(MeterRequest request) { + + Meter.Builder mBuilder = DefaultMeter.builder() + .forDevice(request.deviceId()) + .fromApp(request.appId()) + .withBands(request.bands()) + .withId(allocateMeterId()) + .withUnit(request.unit()); + + if (request.isBurst()) { + mBuilder.burst(); + } + DefaultMeter m = (DefaultMeter) mBuilder.build(); + m.setState(MeterState.PENDING_ADD); + store.storeMeter(m).whenComplete((result, error) -> + onComplete.accept(request, result, error)); + return m; + } + + @Override + public void withdraw(MeterRequest request, MeterId meterId) { + Meter.Builder mBuilder = DefaultMeter.builder() + .forDevice(request.deviceId()) + .fromApp(request.appId()) + .withBands(request.bands()) + .withId(meterId) + .withUnit(request.unit()); + + if (request.isBurst()) { + mBuilder.burst(); + } + + DefaultMeter m = (DefaultMeter) mBuilder.build(); + m.setState(MeterState.PENDING_REMOVE); + store.deleteMeter(m).whenComplete((result, error) -> + onComplete.accept(request, result, error)); + } + + @Override + public Meter getMeter(MeterId id) { + return store.getMeter(id); + } + + @Override + public Collection<Meter> getAllMeters() { + return store.getAllMeters(); + } + + private MeterId allocateMeterId() { + // FIXME: This will break one day. + return MeterId.meterId((int) meterIdCounter.incrementAndGet()); + } + + private class InternalMeterProviderService + extends AbstractProviderService<MeterProvider> + implements MeterProviderService { + + /** + * Creates a provider service on behalf of the specified provider. + * + * @param provider provider to which this service is being issued + */ + protected InternalMeterProviderService(MeterProvider provider) { + super(provider); + } + + @Override + public void meterOperationFailed(MeterOperation operation, + MeterFailReason reason) { + store.failedMeter(operation, reason); + } + + @Override + public void pushMeterMetrics(DeviceId deviceId, Collection<Meter> meterEntries) { + //FIXME: FOLLOWING CODE CANNOT BE TESTED UNTIL SOMETHING THAT + //FIXME: IMPLEMENTS METERS EXISTS + Map<MeterId, Meter> storedMeterMap = store.getAllMeters().stream() + .collect(Collectors.toMap(Meter::id, m -> m)); + + meterEntries.stream() + .filter(m -> storedMeterMap.remove(m.id()) != null) + .forEach(m -> store.updateMeterState(m)); + + storedMeterMap.values().stream().forEach(m -> { + if (m.state() == MeterState.PENDING_ADD) { + provider().performMeterOperation(m.deviceId(), + new MeterOperation(m, + MeterOperation.Type.ADD)); + } else { + store.deleteMeterNow(m); + } + }); + } + } + + private class InternalMeterStoreDelegate implements MeterStoreDelegate { + + @Override + public void notify(MeterEvent event) { + DeviceId deviceId = event.subject().deviceId(); + MeterProvider p = getProvider(event.subject().deviceId()); + switch (event.type()) { + case METER_ADD_REQ: + p.performMeterOperation(deviceId, new MeterOperation(event.subject(), + MeterOperation.Type.ADD)); + break; + case METER_REM_REQ: + p.performMeterOperation(deviceId, new MeterOperation(event.subject(), + MeterOperation.Type.REMOVE)); + break; + default: + log.warn("Unknown meter event {}", event.type()); + } + + } + } + +} |