alshabib
Committed by Gerrit Code Review

adding device specific counters for meter ids in

the meter service.

Change-Id: I38d38a0a85024927f5a74013b2b4d9efa9b32d22
...@@ -43,7 +43,8 @@ public final class DefaultMeterRequest implements MeterRequest { ...@@ -43,7 +43,8 @@ public final class DefaultMeterRequest implements MeterRequest {
43 43
44 private DefaultMeterRequest(DeviceId deviceId, ApplicationId appId, 44 private DefaultMeterRequest(DeviceId deviceId, ApplicationId appId,
45 Meter.Unit unit, boolean burst, 45 Meter.Unit unit, boolean burst,
46 - Collection<Band> bands, MeterContext context, Type op) { 46 + Collection<Band> bands, MeterContext context,
47 + Type op) {
47 this.deviceId = deviceId; 48 this.deviceId = deviceId;
48 this.appId = appId; 49 this.appId = appId;
49 this.unit = unit; 50 this.unit = unit;
...@@ -58,6 +59,7 @@ public final class DefaultMeterRequest implements MeterRequest { ...@@ -58,6 +59,7 @@ public final class DefaultMeterRequest implements MeterRequest {
58 return deviceId; 59 return deviceId;
59 } 60 }
60 61
62 +
61 @Override 63 @Override
62 public ApplicationId appId() { 64 public ApplicationId appId() {
63 return appId; 65 return appId;
...@@ -107,6 +109,7 @@ public final class DefaultMeterRequest implements MeterRequest { ...@@ -107,6 +109,7 @@ public final class DefaultMeterRequest implements MeterRequest {
107 private Collection<Band> bands; 109 private Collection<Band> bands;
108 private DeviceId deviceId; 110 private DeviceId deviceId;
109 private MeterContext context; 111 private MeterContext context;
112 + private Optional<MeterId> desiredId = Optional.empty();
110 113
111 114
112 @Override 115 @Override
......
1 +/*
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 + */
16 +package org.onosproject.net.meter;
17 +
18 +import com.google.common.base.Objects;
19 +import org.onosproject.net.DeviceId;
20 +
21 +/**
22 + * A meter key represents a meter uniquely.
23 + */
24 +public final class MeterKey {
25 +
26 + private final DeviceId deviceId;
27 + private final MeterId id;
28 +
29 + private MeterKey(DeviceId deviceId, MeterId id) {
30 + this.deviceId = deviceId;
31 + this.id = id;
32 + }
33 +
34 + public DeviceId deviceId() {
35 + return deviceId;
36 + }
37 +
38 + public MeterId meterId() {
39 + return id;
40 + }
41 +
42 + @Override
43 + public boolean equals(Object o) {
44 + if (this == o) {
45 + return true;
46 + }
47 + if (o == null || getClass() != o.getClass()) {
48 + return false;
49 + }
50 + MeterKey meterKey = (MeterKey) o;
51 + return Objects.equal(deviceId, meterKey.deviceId) &&
52 + Objects.equal(id, meterKey.id);
53 + }
54 +
55 + @Override
56 + public int hashCode() {
57 + return Objects.hashCode(deviceId, id);
58 + }
59 +
60 + public static MeterKey key(DeviceId deviceId, MeterId id) {
61 + return new MeterKey(deviceId, id);
62 + }
63 +}
...@@ -16,6 +16,7 @@ ...@@ -16,6 +16,7 @@
16 package org.onosproject.net.meter; 16 package org.onosproject.net.meter;
17 17
18 import org.onosproject.event.ListenerService; 18 import org.onosproject.event.ListenerService;
19 +import org.onosproject.net.DeviceId;
19 20
20 import java.util.Collection; 21 import java.util.Collection;
21 22
...@@ -46,10 +47,11 @@ public interface MeterService ...@@ -46,10 +47,11 @@ public interface MeterService
46 /** 47 /**
47 * Fetch the meter by the meter id. 48 * Fetch the meter by the meter id.
48 * 49 *
50 + * @param deviceId a device id
49 * @param id a meter id 51 * @param id a meter id
50 * @return a meter 52 * @return a meter
51 */ 53 */
52 - Meter getMeter(MeterId id); 54 + Meter getMeter(DeviceId deviceId, MeterId id);
53 55
54 /** 56 /**
55 * Fetches all the meters. 57 * Fetches all the meters.
......
...@@ -57,12 +57,12 @@ public interface MeterStore extends Store<MeterEvent, MeterStoreDelegate> { ...@@ -57,12 +57,12 @@ public interface MeterStore extends Store<MeterEvent, MeterStoreDelegate> {
57 void updateMeterState(Meter meter); 57 void updateMeterState(Meter meter);
58 58
59 /** 59 /**
60 - * Obtains a meter matching the given meter id. 60 + * Obtains a meter matching the given meter key.
61 * 61 *
62 - * @param meterId a meter id 62 + * @param key a meter key
63 * @return a meter 63 * @return a meter
64 */ 64 */
65 - Meter getMeter(MeterId meterId); 65 + Meter getMeter(MeterKey key);
66 66
67 /** 67 /**
68 * Returns all meters stored in the store. 68 * Returns all meters stored in the store.
......
...@@ -15,6 +15,7 @@ ...@@ -15,6 +15,7 @@
15 */ 15 */
16 package org.onosproject.incubator.net.meter.impl; 16 package org.onosproject.incubator.net.meter.impl;
17 17
18 +import com.google.common.collect.Maps;
18 import org.apache.felix.scr.annotations.Activate; 19 import org.apache.felix.scr.annotations.Activate;
19 import org.apache.felix.scr.annotations.Component; 20 import org.apache.felix.scr.annotations.Component;
20 import org.apache.felix.scr.annotations.Deactivate; 21 import org.apache.felix.scr.annotations.Deactivate;
...@@ -27,6 +28,7 @@ import org.onosproject.net.meter.Meter; ...@@ -27,6 +28,7 @@ import org.onosproject.net.meter.Meter;
27 import org.onosproject.net.meter.MeterEvent; 28 import org.onosproject.net.meter.MeterEvent;
28 import org.onosproject.net.meter.MeterFailReason; 29 import org.onosproject.net.meter.MeterFailReason;
29 import org.onosproject.net.meter.MeterId; 30 import org.onosproject.net.meter.MeterId;
31 +import org.onosproject.net.meter.MeterKey;
30 import org.onosproject.net.meter.MeterListener; 32 import org.onosproject.net.meter.MeterListener;
31 import org.onosproject.net.meter.MeterOperation; 33 import org.onosproject.net.meter.MeterOperation;
32 import org.onosproject.net.meter.MeterProvider; 34 import org.onosproject.net.meter.MeterProvider;
...@@ -61,7 +63,7 @@ public class MeterManager extends AbstractListenerProviderRegistry<MeterEvent, M ...@@ -61,7 +63,7 @@ public class MeterManager extends AbstractListenerProviderRegistry<MeterEvent, M
61 MeterProvider, MeterProviderService> 63 MeterProvider, MeterProviderService>
62 implements MeterService, MeterProviderRegistry { 64 implements MeterService, MeterProviderRegistry {
63 65
64 - private final String meterIdentifier = "meter-id-counter"; 66 + private static final String METERCOUNTERIDENTIFIER = "meter-id-counter-%s";
65 private final Logger log = getLogger(getClass()); 67 private final Logger log = getLogger(getClass());
66 private final MeterStoreDelegate delegate = new InternalMeterStoreDelegate(); 68 private final MeterStoreDelegate delegate = new InternalMeterStoreDelegate();
67 69
...@@ -71,15 +73,16 @@ public class MeterManager extends AbstractListenerProviderRegistry<MeterEvent, M ...@@ -71,15 +73,16 @@ public class MeterManager extends AbstractListenerProviderRegistry<MeterEvent, M
71 @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY) 73 @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
72 protected MeterStore store; 74 protected MeterStore store;
73 75
74 - private AtomicCounter meterIdCounter; 76 + private Map<DeviceId, AtomicCounter> meterIdCounters
77 + = Maps.newConcurrentMap();
75 78
76 private TriConsumer<MeterRequest, MeterStoreResult, Throwable> onComplete; 79 private TriConsumer<MeterRequest, MeterStoreResult, Throwable> onComplete;
77 80
78 @Activate 81 @Activate
79 public void activate() { 82 public void activate() {
80 - meterIdCounter = storageService.atomicCounterBuilder() 83 + /*meterIdCounter = storageService.atomicCounterBuilder()
81 - .withName(meterIdentifier) 84 + .withName(METERCOUNTERIDENTIFIER)
82 - .build(); 85 + .build();*/
83 86
84 store.setDelegate(delegate); 87 store.setDelegate(delegate);
85 88
...@@ -115,11 +118,13 @@ public class MeterManager extends AbstractListenerProviderRegistry<MeterEvent, M ...@@ -115,11 +118,13 @@ public class MeterManager extends AbstractListenerProviderRegistry<MeterEvent, M
115 @Override 118 @Override
116 public Meter submit(MeterRequest request) { 119 public Meter submit(MeterRequest request) {
117 120
121 + MeterId id = allocateMeterId(request.deviceId());
122 +
118 Meter.Builder mBuilder = DefaultMeter.builder() 123 Meter.Builder mBuilder = DefaultMeter.builder()
119 .forDevice(request.deviceId()) 124 .forDevice(request.deviceId())
120 .fromApp(request.appId()) 125 .fromApp(request.appId())
121 .withBands(request.bands()) 126 .withBands(request.bands())
122 - .withId(allocateMeterId()) 127 + .withId(id)
123 .withUnit(request.unit()); 128 .withUnit(request.unit());
124 129
125 if (request.isBurst()) { 130 if (request.isBurst()) {
...@@ -152,8 +157,9 @@ public class MeterManager extends AbstractListenerProviderRegistry<MeterEvent, M ...@@ -152,8 +157,9 @@ public class MeterManager extends AbstractListenerProviderRegistry<MeterEvent, M
152 } 157 }
153 158
154 @Override 159 @Override
155 - public Meter getMeter(MeterId id) { 160 + public Meter getMeter(DeviceId deviceId, MeterId id) {
156 - return store.getMeter(id); 161 + MeterKey key = MeterKey.key(deviceId, id);
162 + return store.getMeter(key);
157 } 163 }
158 164
159 @Override 165 @Override
...@@ -161,9 +167,21 @@ public class MeterManager extends AbstractListenerProviderRegistry<MeterEvent, M ...@@ -161,9 +167,21 @@ public class MeterManager extends AbstractListenerProviderRegistry<MeterEvent, M
161 return store.getAllMeters(); 167 return store.getAllMeters();
162 } 168 }
163 169
164 - private MeterId allocateMeterId() { 170 + private MeterId allocateMeterId(DeviceId deviceId) {
165 - // FIXME: This will break one day. 171 + long id = meterIdCounters.compute(deviceId, (k, v) -> {
166 - return MeterId.meterId((int) meterIdCounter.incrementAndGet()); 172 + if (v == null) {
173 + return allocateCounter(k);
174 + }
175 + return v;
176 + }).incrementAndGet();
177 +
178 + return MeterId.meterId((int) id);
179 + }
180 +
181 + private AtomicCounter allocateCounter(DeviceId deviceId) {
182 + return storageService.atomicCounterBuilder()
183 + .withName(String.format(METERCOUNTERIDENTIFIER, deviceId))
184 + .build();
167 } 185 }
168 186
169 private class InternalMeterProviderService 187 private class InternalMeterProviderService
......
...@@ -130,7 +130,7 @@ public class MeterManagerTest { ...@@ -130,7 +130,7 @@ public class MeterManagerTest {
130 m2 = DefaultMeter.builder() 130 m2 = DefaultMeter.builder()
131 .forDevice(did("2")) 131 .forDevice(did("2"))
132 .fromApp(APP_ID) 132 .fromApp(APP_ID)
133 - .withId(MeterId.meterId(2)) 133 + .withId(MeterId.meterId(1))
134 .withUnit(Meter.Unit.KB_PER_SEC) 134 .withUnit(Meter.Unit.KB_PER_SEC)
135 .withBands(Collections.singletonList(band)) 135 .withBands(Collections.singletonList(band))
136 .build(); 136 .build();
...@@ -167,7 +167,7 @@ public class MeterManagerTest { ...@@ -167,7 +167,7 @@ public class MeterManagerTest {
167 167
168 assertTrue("The meter was not added", manager.getAllMeters().size() == 1); 168 assertTrue("The meter was not added", manager.getAllMeters().size() == 1);
169 169
170 - assertThat(manager.getMeter(MeterId.meterId(1)), is(m1)); 170 + assertThat(manager.getMeter(did("1"), MeterId.meterId(1)), is(m1));
171 } 171 }
172 172
173 @Test 173 @Test
...@@ -175,7 +175,7 @@ public class MeterManagerTest { ...@@ -175,7 +175,7 @@ public class MeterManagerTest {
175 manager.submit(m1Request.add()); 175 manager.submit(m1Request.add());
176 manager.withdraw(m1Request.remove(), m1.id()); 176 manager.withdraw(m1Request.remove(), m1.id());
177 177
178 - assertThat(manager.getMeter(MeterId.meterId(1)).state(), 178 + assertThat(manager.getMeter(did("1"), MeterId.meterId(1)).state(),
179 is(MeterState.PENDING_REMOVE)); 179 is(MeterState.PENDING_REMOVE));
180 180
181 providerService.pushMeterMetrics(m1.deviceId(), Collections.emptyList()); 181 providerService.pushMeterMetrics(m1.deviceId(), Collections.emptyList());
...@@ -184,7 +184,16 @@ public class MeterManagerTest { ...@@ -184,7 +184,16 @@ public class MeterManagerTest {
184 184
185 } 185 }
186 186
187 + @Test
188 + public void testMultipleDevice() {
189 + manager.submit(m1Request.add());
190 + manager.submit(m2Request.add());
187 191
192 + assertTrue("The meters were not added", manager.getAllMeters().size() == 2);
193 +
194 + assertThat(manager.getMeter(did("1"), MeterId.meterId(1)), is(m1));
195 + assertThat(manager.getMeter(did("2"), MeterId.meterId(1)), is(m2));
196 + }
188 197
189 public class TestApplicationId extends DefaultApplicationId { 198 public class TestApplicationId extends DefaultApplicationId {
190 public TestApplicationId(int id, String name) { 199 public TestApplicationId(int id, String name) {
......
...@@ -33,6 +33,7 @@ import org.onosproject.net.meter.Meter; ...@@ -33,6 +33,7 @@ import org.onosproject.net.meter.Meter;
33 import org.onosproject.net.meter.MeterEvent; 33 import org.onosproject.net.meter.MeterEvent;
34 import org.onosproject.net.meter.MeterFailReason; 34 import org.onosproject.net.meter.MeterFailReason;
35 import org.onosproject.net.meter.MeterId; 35 import org.onosproject.net.meter.MeterId;
36 +import org.onosproject.net.meter.MeterKey;
36 import org.onosproject.net.meter.MeterOperation; 37 import org.onosproject.net.meter.MeterOperation;
37 import org.onosproject.net.meter.MeterState; 38 import org.onosproject.net.meter.MeterState;
38 import org.onosproject.net.meter.MeterStore; 39 import org.onosproject.net.meter.MeterStore;
...@@ -78,12 +79,12 @@ public class DistributedMeterStore extends AbstractStore<MeterEvent, MeterStoreD ...@@ -78,12 +79,12 @@ public class DistributedMeterStore extends AbstractStore<MeterEvent, MeterStoreD
78 @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY) 79 @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
79 private ClusterService clusterService; 80 private ClusterService clusterService;
80 81
81 - private ConsistentMap<MeterId, MeterData> meters; 82 + private ConsistentMap<MeterKey, MeterData> meters;
82 private NodeId local; 83 private NodeId local;
83 84
84 private MapEventListener mapListener = new InternalMapEventListener(); 85 private MapEventListener mapListener = new InternalMapEventListener();
85 86
86 - private Map<MeterId, CompletableFuture<MeterStoreResult>> futures = 87 + private Map<MeterKey, CompletableFuture<MeterStoreResult>> futures =
87 Maps.newConcurrentMap(); 88 Maps.newConcurrentMap();
88 89
89 @Activate 90 @Activate
...@@ -92,9 +93,10 @@ public class DistributedMeterStore extends AbstractStore<MeterEvent, MeterStoreD ...@@ -92,9 +93,10 @@ public class DistributedMeterStore extends AbstractStore<MeterEvent, MeterStoreD
92 local = clusterService.getLocalNode().id(); 93 local = clusterService.getLocalNode().id();
93 94
94 95
95 - meters = storageService.<MeterId, MeterData>consistentMapBuilder() 96 + meters = storageService.<MeterKey, MeterData>consistentMapBuilder()
96 .withName(METERSTORE) 97 .withName(METERSTORE)
97 .withSerializer(Serializer.using(Arrays.asList(KryoNamespaces.API), 98 .withSerializer(Serializer.using(Arrays.asList(KryoNamespaces.API),
99 + MeterKey.class,
98 MeterData.class, 100 MeterData.class,
99 DefaultMeter.class, 101 DefaultMeter.class,
100 DefaultBand.class, 102 DefaultBand.class,
...@@ -120,11 +122,12 @@ public class DistributedMeterStore extends AbstractStore<MeterEvent, MeterStoreD ...@@ -120,11 +122,12 @@ public class DistributedMeterStore extends AbstractStore<MeterEvent, MeterStoreD
120 @Override 122 @Override
121 public CompletableFuture<MeterStoreResult> storeMeter(Meter meter) { 123 public CompletableFuture<MeterStoreResult> storeMeter(Meter meter) {
122 CompletableFuture<MeterStoreResult> future = new CompletableFuture<>(); 124 CompletableFuture<MeterStoreResult> future = new CompletableFuture<>();
123 - futures.put(meter.id(), future); 125 + MeterKey key = MeterKey.key(meter.deviceId(), meter.id());
126 + futures.put(key, future);
124 MeterData data = new MeterData(meter, null, local); 127 MeterData data = new MeterData(meter, null, local);
125 128
126 try { 129 try {
127 - meters.put(meter.id(), data); 130 + meters.put(key, data);
128 } catch (StorageException e) { 131 } catch (StorageException e) {
129 future.completeExceptionally(e); 132 future.completeExceptionally(e);
130 } 133 }
...@@ -136,14 +139,15 @@ public class DistributedMeterStore extends AbstractStore<MeterEvent, MeterStoreD ...@@ -136,14 +139,15 @@ public class DistributedMeterStore extends AbstractStore<MeterEvent, MeterStoreD
136 @Override 139 @Override
137 public CompletableFuture<MeterStoreResult> deleteMeter(Meter meter) { 140 public CompletableFuture<MeterStoreResult> deleteMeter(Meter meter) {
138 CompletableFuture<MeterStoreResult> future = new CompletableFuture<>(); 141 CompletableFuture<MeterStoreResult> future = new CompletableFuture<>();
139 - futures.put(meter.id(), future); 142 + MeterKey key = MeterKey.key(meter.deviceId(), meter.id());
143 + futures.put(key, future);
140 144
141 MeterData data = new MeterData(meter, null, local); 145 MeterData data = new MeterData(meter, null, local);
142 146
143 // update the state of the meter. It will be pruned by observing 147 // update the state of the meter. It will be pruned by observing
144 // that it has been removed from the dataplane. 148 // that it has been removed from the dataplane.
145 try { 149 try {
146 - if (meters.computeIfPresent(meter.id(), (k, v) -> data) == null) { 150 + if (meters.computeIfPresent(key, (k, v) -> data) == null) {
147 future.complete(MeterStoreResult.success()); 151 future.complete(MeterStoreResult.success());
148 } 152 }
149 } catch (StorageException e) { 153 } catch (StorageException e) {
...@@ -157,11 +161,12 @@ public class DistributedMeterStore extends AbstractStore<MeterEvent, MeterStoreD ...@@ -157,11 +161,12 @@ public class DistributedMeterStore extends AbstractStore<MeterEvent, MeterStoreD
157 @Override 161 @Override
158 public CompletableFuture<MeterStoreResult> updateMeter(Meter meter) { 162 public CompletableFuture<MeterStoreResult> updateMeter(Meter meter) {
159 CompletableFuture<MeterStoreResult> future = new CompletableFuture<>(); 163 CompletableFuture<MeterStoreResult> future = new CompletableFuture<>();
160 - futures.put(meter.id(), future); 164 + MeterKey key = MeterKey.key(meter.deviceId(), meter.id());
165 + futures.put(key, future);
161 166
162 MeterData data = new MeterData(meter, null, local); 167 MeterData data = new MeterData(meter, null, local);
163 try { 168 try {
164 - if (meters.computeIfPresent(meter.id(), (k, v) -> data) == null) { 169 + if (meters.computeIfPresent(key, (k, v) -> data) == null) {
165 future.complete(MeterStoreResult.fail(MeterFailReason.INVALID_METER)); 170 future.complete(MeterStoreResult.fail(MeterFailReason.INVALID_METER));
166 } 171 }
167 } catch (StorageException e) { 172 } catch (StorageException e) {
...@@ -172,7 +177,8 @@ public class DistributedMeterStore extends AbstractStore<MeterEvent, MeterStoreD ...@@ -172,7 +177,8 @@ public class DistributedMeterStore extends AbstractStore<MeterEvent, MeterStoreD
172 177
173 @Override 178 @Override
174 public void updateMeterState(Meter meter) { 179 public void updateMeterState(Meter meter) {
175 - meters.computeIfPresent(meter.id(), (id, v) -> { 180 + MeterKey key = MeterKey.key(meter.deviceId(), meter.id());
181 + meters.computeIfPresent(key, (k, v) -> {
176 DefaultMeter m = (DefaultMeter) v.meter(); 182 DefaultMeter m = (DefaultMeter) v.meter();
177 m.setState(meter.state()); 183 m.setState(meter.state());
178 m.setProcessedPackets(meter.packetsSeen()); 184 m.setProcessedPackets(meter.packetsSeen());
...@@ -185,8 +191,8 @@ public class DistributedMeterStore extends AbstractStore<MeterEvent, MeterStoreD ...@@ -185,8 +191,8 @@ public class DistributedMeterStore extends AbstractStore<MeterEvent, MeterStoreD
185 } 191 }
186 192
187 @Override 193 @Override
188 - public Meter getMeter(MeterId meterId) { 194 + public Meter getMeter(MeterKey key) {
189 - MeterData data = Versioned.valueOrElse(meters.get(meterId), null); 195 + MeterData data = Versioned.valueOrElse(meters.get(key), null);
190 return data == null ? null : data.meter(); 196 return data == null ? null : data.meter();
191 } 197 }
192 198
...@@ -198,14 +204,16 @@ public class DistributedMeterStore extends AbstractStore<MeterEvent, MeterStoreD ...@@ -198,14 +204,16 @@ public class DistributedMeterStore extends AbstractStore<MeterEvent, MeterStoreD
198 204
199 @Override 205 @Override
200 public void failedMeter(MeterOperation op, MeterFailReason reason) { 206 public void failedMeter(MeterOperation op, MeterFailReason reason) {
201 - meters.computeIfPresent(op.meter().id(), (k, v) -> 207 + MeterKey key = MeterKey.key(op.meter().deviceId(), op.meter().id());
208 + meters.computeIfPresent(key, (k, v) ->
202 new MeterData(v.meter(), reason, v.origin())); 209 new MeterData(v.meter(), reason, v.origin()));
203 } 210 }
204 211
205 @Override 212 @Override
206 public void deleteMeterNow(Meter m) { 213 public void deleteMeterNow(Meter m) {
207 - futures.remove(m.id()); 214 + MeterKey key = MeterKey.key(m.deviceId(), m.id());
208 - meters.remove(m.id()); 215 + futures.remove(key);
216 + meters.remove(key);
209 } 217 }
210 218
211 private class InternalMapEventListener implements MapEventListener<MeterId, MeterData> { 219 private class InternalMapEventListener implements MapEventListener<MeterId, MeterData> {
......