blob: a7183de8cb6557e4fc370fbec779e621f914900d [file] [log] [blame]
Thomas Vachuska58de4162015-09-10 16:15:33 -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 */
Brian O'Connor6de2e202015-05-21 14:30:41 -070016package org.onosproject.incubator.store.resource.impl;
jccde3e92e2015-03-28 01:40:44 -070017
18import static org.onlab.util.Tools.groupedThreads;
19import static org.slf4j.LoggerFactory.getLogger;
20
21import java.util.Collection;
22import java.util.Collections;
23import java.util.HashSet;
24import java.util.Iterator;
25import java.util.Map;
26import java.util.Set;
27import java.util.concurrent.ExecutionException;
28import java.util.concurrent.ExecutorService;
29import java.util.concurrent.Executors;
30import java.util.concurrent.Future;
31import java.util.concurrent.TimeUnit;
32import java.util.concurrent.TimeoutException;
jccde3e92e2015-03-28 01:40:44 -070033
34import org.apache.felix.scr.annotations.Activate;
35import org.apache.felix.scr.annotations.Component;
36import org.apache.felix.scr.annotations.Deactivate;
37import org.apache.felix.scr.annotations.Reference;
38import org.apache.felix.scr.annotations.ReferenceCardinality;
39import org.apache.felix.scr.annotations.Service;
40import org.onlab.util.KryoNamespace;
41import org.onosproject.cluster.ClusterService;
Madan Jampanic156dd02015-08-12 15:57:46 -070042import org.onosproject.cluster.NodeId;
Brian O'Connor6de2e202015-05-21 14:30:41 -070043import org.onosproject.incubator.net.resource.label.DefaultLabelResource;
44import org.onosproject.incubator.net.resource.label.LabelResource;
45import org.onosproject.incubator.net.resource.label.LabelResourceDelegate;
46import org.onosproject.incubator.net.resource.label.LabelResourceEvent;
47import org.onosproject.incubator.net.resource.label.LabelResourceEvent.Type;
48import org.onosproject.incubator.net.resource.label.LabelResourceId;
49import org.onosproject.incubator.net.resource.label.LabelResourcePool;
50import org.onosproject.incubator.net.resource.label.LabelResourceRequest;
51import org.onosproject.incubator.net.resource.label.LabelResourceStore;
Madan Jampanic156dd02015-08-12 15:57:46 -070052import org.onosproject.mastership.MastershipService;
samuel7a5691a2015-05-23 00:36:32 +080053import org.onosproject.net.Device;
54import org.onosproject.net.DeviceId;
55import org.onosproject.net.device.DeviceService;
jccde3e92e2015-03-28 01:40:44 -070056import org.onosproject.store.AbstractStore;
57import org.onosproject.store.cluster.messaging.ClusterCommunicationService;
58import org.onosproject.store.cluster.messaging.ClusterMessage;
59import org.onosproject.store.cluster.messaging.ClusterMessageHandler;
jccde3e92e2015-03-28 01:40:44 -070060import org.onosproject.store.serializers.KryoNamespaces;
jccde3e92e2015-03-28 01:40:44 -070061import org.onosproject.store.service.ConsistentMap;
62import org.onosproject.store.service.Serializer;
63import org.onosproject.store.service.StorageService;
samuel7a5691a2015-05-23 00:36:32 +080064import org.onosproject.store.service.Versioned;
jccde3e92e2015-03-28 01:40:44 -070065import org.slf4j.Logger;
66
67import com.google.common.collect.ImmutableSet;
68import com.google.common.collect.Multimap;
69
70/**
71 * Manages label resources using copycat.
72 */
73@Component(immediate = true, enabled = true)
74@Service
75public class DistributedLabelResourceStore
76 extends AbstractStore<LabelResourceEvent, LabelResourceDelegate>
77 implements LabelResourceStore {
78 private final Logger log = getLogger(getClass());
79
80 private static final String POOL_MAP_NAME = "labelresourcepool";
81
82 private static final String GLOBAL_RESOURCE_POOL_DEVICE_ID = "global_resource_pool_device_id";
jccde3e92e2015-03-28 01:40:44 -070083
84 private ConsistentMap<DeviceId, LabelResourcePool> resourcePool = null;
85
86 @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
87 protected StorageService storageService;
88
89 @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
Madan Jampanic156dd02015-08-12 15:57:46 -070090 protected MastershipService mastershipService;
jccde3e92e2015-03-28 01:40:44 -070091
92 @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
93 protected ClusterCommunicationService clusterCommunicator;
94
95 @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
96 protected ClusterService clusterService;
97
98 @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
99 protected DeviceService deviceService;
100
101 private ExecutorService messageHandlingExecutor;
102 private static final int MESSAGE_HANDLER_THREAD_POOL_SIZE = 8;
103 private static final long PEER_REQUEST_TIMEOUT_MS = 5000;
104
samuel7a5691a2015-05-23 00:36:32 +0800105 private static final Serializer SERIALIZER = Serializer
106 .using(new KryoNamespace.Builder().register(KryoNamespaces.API)
jccde3e92e2015-03-28 01:40:44 -0700107 .register(LabelResourceEvent.class)
108 .register(LabelResourcePool.class).register(DeviceId.class)
109 .register(LabelResourceRequest.class)
110 .register(LabelResourceRequest.Type.class)
111 .register(LabelResourceEvent.Type.class)
112 .register(DefaultLabelResource.class)
samuel7a5691a2015-05-23 00:36:32 +0800113 .register(LabelResourceId.class)
114 .nextId(KryoNamespaces.BEGIN_USER_CUSTOM_ID).build());
jccde3e92e2015-03-28 01:40:44 -0700115
116 @Activate
117 public void activate() {
118
119 resourcePool = storageService
120 .<DeviceId, LabelResourcePool>consistentMapBuilder()
samuel7a5691a2015-05-23 00:36:32 +0800121 .withName(POOL_MAP_NAME).withSerializer(SERIALIZER)
122 .withPartitionsDisabled().build();
jccde3e92e2015-03-28 01:40:44 -0700123 messageHandlingExecutor = Executors
124 .newFixedThreadPool(MESSAGE_HANDLER_THREAD_POOL_SIZE,
125 groupedThreads("onos/store/flow",
126 "message-handlers"));
127 clusterCommunicator
128 .addSubscriber(LabelResourceMessageSubjects.LABEL_POOL_CREATED,
129 new ClusterMessageHandler() {
130
131 @Override
132 public void handle(ClusterMessage message) {
133 LabelResourcePool operation = SERIALIZER
134 .decode(message.payload());
135 log.trace("received get flow entry request for {}",
136 operation);
137 boolean b = internalCreate(operation);
samuel7a5691a2015-05-23 00:36:32 +0800138 message.respond(SERIALIZER.encode(b));
jccde3e92e2015-03-28 01:40:44 -0700139 }
140 }, messageHandlingExecutor);
141 clusterCommunicator
142 .addSubscriber(LabelResourceMessageSubjects.LABEL_POOL_DESTROYED,
143 new ClusterMessageHandler() {
144
145 @Override
146 public void handle(ClusterMessage message) {
147 DeviceId deviceId = SERIALIZER
148 .decode(message.payload());
149 log.trace("received get flow entry request for {}",
150 deviceId);
151 boolean b = internalDestroy(deviceId);
samuel7a5691a2015-05-23 00:36:32 +0800152 message.respond(SERIALIZER.encode(b));
jccde3e92e2015-03-28 01:40:44 -0700153 }
154 }, messageHandlingExecutor);
155 clusterCommunicator
156 .addSubscriber(LabelResourceMessageSubjects.LABEL_POOL_APPLY,
157 new ClusterMessageHandler() {
158
159 @Override
160 public void handle(ClusterMessage message) {
161 LabelResourceRequest request = SERIALIZER
162 .decode(message.payload());
163 log.trace("received get flow entry request for {}",
164 request);
165 final Collection<LabelResource> resource = internalApply(request);
samuel7a5691a2015-05-23 00:36:32 +0800166 message.respond(SERIALIZER
167 .encode(resource));
jccde3e92e2015-03-28 01:40:44 -0700168 }
169 }, messageHandlingExecutor);
170 clusterCommunicator
171 .addSubscriber(LabelResourceMessageSubjects.LABEL_POOL_RELEASE,
172 new ClusterMessageHandler() {
173
174 @Override
175 public void handle(ClusterMessage message) {
176 LabelResourceRequest request = SERIALIZER
177 .decode(message.payload());
178 log.trace("received get flow entry request for {}",
179 request);
180 final boolean isSuccess = internalRelease(request);
samuel7a5691a2015-05-23 00:36:32 +0800181 message.respond(SERIALIZER
182 .encode(isSuccess));
jccde3e92e2015-03-28 01:40:44 -0700183 }
184 }, messageHandlingExecutor);
185 log.info("Started");
186 }
187
188 @Deactivate
189 public void deactivate() {
190 clusterCommunicator
191 .removeSubscriber(LabelResourceMessageSubjects.LABEL_POOL_CREATED);
192 clusterCommunicator
193 .removeSubscriber(LabelResourceMessageSubjects.LABEL_POOL_APPLY);
194 clusterCommunicator
195 .removeSubscriber(LabelResourceMessageSubjects.LABEL_POOL_DESTROYED);
196 clusterCommunicator
197 .removeSubscriber(LabelResourceMessageSubjects.LABEL_POOL_RELEASE);
198 messageHandlingExecutor.shutdown();
199 log.info("Stopped");
200 }
201
202 @Override
203 public boolean createDevicePool(DeviceId deviceId,
204 LabelResourceId beginLabel,
205 LabelResourceId endLabel) {
206 LabelResourcePool pool = new LabelResourcePool(deviceId.toString(),
207 beginLabel.labelId(),
208 endLabel.labelId());
209 return this.create(pool);
210 }
211
212 @Override
213 public boolean createGlobalPool(LabelResourceId beginLabel,
214 LabelResourceId endLabel) {
Satish K0de87612015-11-24 13:44:52 +0530215 LabelResourcePool pool = new LabelResourcePool(GLOBAL_RESOURCE_POOL_DEVICE_ID,
jccde3e92e2015-03-28 01:40:44 -0700216 beginLabel.labelId(),
217 endLabel.labelId());
218 return this.internalCreate(pool);
219 }
220
221 private boolean create(LabelResourcePool pool) {
222 Device device = (Device) deviceService.getDevice(pool.deviceId());
223 if (device == null) {
224 return false;
225 }
226
Madan Jampanic156dd02015-08-12 15:57:46 -0700227 NodeId master = mastershipService.getMasterFor(pool.deviceId());
jccde3e92e2015-03-28 01:40:44 -0700228
Madan Jampanic156dd02015-08-12 15:57:46 -0700229 if (master == null) {
230 log.warn("Failed to create label resource pool: No master for {}", pool);
jccde3e92e2015-03-28 01:40:44 -0700231 return false;
232 }
233
Madan Jampanic156dd02015-08-12 15:57:46 -0700234 if (master.equals(clusterService.getLocalNode().id())) {
jccde3e92e2015-03-28 01:40:44 -0700235 return internalCreate(pool);
236 }
237
238 log.trace("Forwarding getFlowEntries to {}, which is the primary (master) for device {}",
Madan Jampanic156dd02015-08-12 15:57:46 -0700239 master, pool.deviceId());
jccde3e92e2015-03-28 01:40:44 -0700240
241 return complete(clusterCommunicator
242 .sendAndReceive(pool,
243 LabelResourceMessageSubjects.LABEL_POOL_CREATED,
244 SERIALIZER::encode, SERIALIZER::decode,
Madan Jampanic156dd02015-08-12 15:57:46 -0700245 master));
jccde3e92e2015-03-28 01:40:44 -0700246 }
247
248 private boolean internalCreate(LabelResourcePool pool) {
samuel7a5691a2015-05-23 00:36:32 +0800249 Versioned<LabelResourcePool> poolOld = resourcePool
250 .get(pool.deviceId());
jccde3e92e2015-03-28 01:40:44 -0700251 if (poolOld == null) {
252 resourcePool.put(pool.deviceId(), pool);
Satish K0de87612015-11-24 13:44:52 +0530253 LabelResourceEvent event = new LabelResourceEvent(Type.POOL_CREATED,
jccde3e92e2015-03-28 01:40:44 -0700254 pool);
255 notifyDelegate(event);
256 return true;
257 }
jccde3e92e2015-03-28 01:40:44 -0700258 return false;
259 }
260
261 @Override
262 public boolean destroyDevicePool(DeviceId deviceId) {
263 Device device = (Device) deviceService.getDevice(deviceId);
264 if (device == null) {
265 return false;
266 }
jccde3e92e2015-03-28 01:40:44 -0700267
Madan Jampanic156dd02015-08-12 15:57:46 -0700268 NodeId master = mastershipService.getMasterFor(deviceId);
269
270 if (master == null) {
271 log.warn("Failed to destroyDevicePool. No master for {}", deviceId);
jccde3e92e2015-03-28 01:40:44 -0700272 return false;
273 }
274
Madan Jampanic156dd02015-08-12 15:57:46 -0700275 if (master.equals(clusterService.getLocalNode().id())) {
jccde3e92e2015-03-28 01:40:44 -0700276 return internalDestroy(deviceId);
277 }
278
Madan Jampanic156dd02015-08-12 15:57:46 -0700279 log.trace("Forwarding request to {}, which is the primary (master) for device {}",
280 master, deviceId);
jccde3e92e2015-03-28 01:40:44 -0700281
282 return complete(clusterCommunicator
283 .sendAndReceive(deviceId,
284 LabelResourceMessageSubjects.LABEL_POOL_DESTROYED,
285 SERIALIZER::encode, SERIALIZER::decode,
Madan Jampanic156dd02015-08-12 15:57:46 -0700286 master));
jccde3e92e2015-03-28 01:40:44 -0700287 }
288
289 private boolean internalDestroy(DeviceId deviceId) {
samuel7a5691a2015-05-23 00:36:32 +0800290 Versioned<LabelResourcePool> poolOld = resourcePool.get(deviceId);
jccde3e92e2015-03-28 01:40:44 -0700291 if (poolOld != null) {
292 resourcePool.remove(deviceId);
Satish K0de87612015-11-24 13:44:52 +0530293 LabelResourceEvent event = new LabelResourceEvent(Type.POOL_DESTROYED,
samuel7a5691a2015-05-23 00:36:32 +0800294 poolOld.value());
jccde3e92e2015-03-28 01:40:44 -0700295 notifyDelegate(event);
296 }
297 log.info("success to destroy the label resource pool of device id {}",
298 deviceId);
299 return true;
300 }
301
302 @Override
303 public Collection<LabelResource> applyFromDevicePool(DeviceId deviceId,
304 long applyNum) {
305 Device device = (Device) deviceService.getDevice(deviceId);
306 if (device == null) {
307 return Collections.emptyList();
308 }
Satish K0de87612015-11-24 13:44:52 +0530309 LabelResourceRequest request = new LabelResourceRequest(deviceId,
jccde3e92e2015-03-28 01:40:44 -0700310 LabelResourceRequest.Type.APPLY,
311 applyNum, null);
Madan Jampanic156dd02015-08-12 15:57:46 -0700312 NodeId master = mastershipService.getMasterFor(deviceId);
jccde3e92e2015-03-28 01:40:44 -0700313
Madan Jampanic156dd02015-08-12 15:57:46 -0700314 if (master == null) {
315 log.warn("Failed to applyFromDevicePool: No master for {}", deviceId);
jccde3e92e2015-03-28 01:40:44 -0700316 return Collections.emptyList();
317 }
318
Madan Jampanic156dd02015-08-12 15:57:46 -0700319 if (master.equals(clusterService.getLocalNode().id())) {
jccde3e92e2015-03-28 01:40:44 -0700320 return internalApply(request);
321 }
322
Madan Jampanic156dd02015-08-12 15:57:46 -0700323 log.trace("Forwarding request to {}, which is the primary (master) for device {}",
324 master, deviceId);
jccde3e92e2015-03-28 01:40:44 -0700325
326 return complete(clusterCommunicator
327 .sendAndReceive(request,
328 LabelResourceMessageSubjects.LABEL_POOL_APPLY,
329 SERIALIZER::encode, SERIALIZER::decode,
Madan Jampanic156dd02015-08-12 15:57:46 -0700330 master));
jccde3e92e2015-03-28 01:40:44 -0700331 }
332
333 private Collection<LabelResource> internalApply(LabelResourceRequest request) {
jccde3e92e2015-03-28 01:40:44 -0700334 DeviceId deviceId = request.deviceId();
335 long applyNum = request.applyNum();
samuel7a5691a2015-05-23 00:36:32 +0800336 Versioned<LabelResourcePool> poolOld = resourcePool.get(deviceId);
337 LabelResourcePool pool = poolOld.value();
jccde3e92e2015-03-28 01:40:44 -0700338 Collection<LabelResource> result = new HashSet<LabelResource>();
339 long freeNum = this.getFreeNumOfDevicePool(deviceId);
340 if (applyNum > freeNum) {
341 log.info("the free number of the label resource pool of deviceId {} is not enough.");
jccde3e92e2015-03-28 01:40:44 -0700342 return Collections.emptyList();
343 }
Satish K0de87612015-11-24 13:44:52 +0530344 Set<LabelResource> releaseLabels = new HashSet<LabelResource>(pool.releaseLabelId());
jccde3e92e2015-03-28 01:40:44 -0700345 long tmp = releaseLabels.size() > applyNum ? applyNum : releaseLabels
346 .size();
347 LabelResource resource = null;
348 for (int i = 0; i < tmp; i++) {
349 Iterator<LabelResource> it = releaseLabels.iterator();
350 if (it.hasNext()) {
351 resource = it.next();
352 releaseLabels.remove(resource);
353 }
354 result.add(resource);
355 }
356 for (long j = pool.currentUsedMaxLabelId().labelId(); j < pool
357 .currentUsedMaxLabelId().labelId() + applyNum - tmp; j++) {
358 resource = new DefaultLabelResource(deviceId,
359 LabelResourceId
360 .labelResourceId(j));
361 result.add(resource);
362 }
363 long beginLabel = pool.beginLabel().labelId();
364 long endLabel = pool.endLabel().labelId();
365 long totalNum = pool.totalNum();
366 long current = pool.currentUsedMaxLabelId().labelId() + applyNum - tmp;
367 long usedNum = pool.usedNum() + applyNum;
368 ImmutableSet<LabelResource> freeLabel = ImmutableSet
369 .copyOf(releaseLabels);
370 LabelResourcePool newPool = new LabelResourcePool(deviceId.toString(),
371 beginLabel, endLabel,
372 totalNum, usedNum,
373 current, freeLabel);
374 resourcePool.put(deviceId, newPool);
375 log.info("success to apply label resource");
jccde3e92e2015-03-28 01:40:44 -0700376 return result;
377 }
378
379 @Override
380 public boolean releaseToDevicePool(Multimap<DeviceId, LabelResource> release) {
381 Map<DeviceId, Collection<LabelResource>> maps = release.asMap();
382 Set<DeviceId> deviceIdSet = maps.keySet();
383 LabelResourceRequest request = null;
384 for (Iterator<DeviceId> it = deviceIdSet.iterator(); it.hasNext();) {
385 DeviceId deviceId = (DeviceId) it.next();
386 Device device = (Device) deviceService.getDevice(deviceId);
387 if (device == null) {
388 continue;
389 }
390 ImmutableSet<LabelResource> collection = ImmutableSet.copyOf(maps
391 .get(deviceId));
Satish K0de87612015-11-24 13:44:52 +0530392 request = new LabelResourceRequest(deviceId,
jccde3e92e2015-03-28 01:40:44 -0700393 LabelResourceRequest.Type.RELEASE,
394 0, collection);
Madan Jampanic156dd02015-08-12 15:57:46 -0700395 NodeId master = mastershipService.getMasterFor(deviceId);
jccde3e92e2015-03-28 01:40:44 -0700396
Madan Jampanic156dd02015-08-12 15:57:46 -0700397 if (master == null) {
398 log.warn("Failed to releaseToDevicePool: No master for {}", deviceId);
jccde3e92e2015-03-28 01:40:44 -0700399 return false;
400 }
401
Madan Jampanic156dd02015-08-12 15:57:46 -0700402 if (master.equals(clusterService.getLocalNode().id())) {
jccde3e92e2015-03-28 01:40:44 -0700403 return internalRelease(request);
404 }
405
Madan Jampanic156dd02015-08-12 15:57:46 -0700406 log.trace("Forwarding request to {}, which is the primary (master) for device {}",
407 master, deviceId);
jccde3e92e2015-03-28 01:40:44 -0700408
409 return complete(clusterCommunicator
410 .sendAndReceive(request,
411 LabelResourceMessageSubjects.LABEL_POOL_RELEASE,
412 SERIALIZER::encode, SERIALIZER::decode,
Madan Jampanic156dd02015-08-12 15:57:46 -0700413 master));
jccde3e92e2015-03-28 01:40:44 -0700414 }
415 return false;
416 }
417
418 private boolean internalRelease(LabelResourceRequest request) {
jccde3e92e2015-03-28 01:40:44 -0700419 DeviceId deviceId = request.deviceId();
420 Collection<LabelResource> release = request.releaseCollection();
samuel7a5691a2015-05-23 00:36:32 +0800421 Versioned<LabelResourcePool> poolOld = resourcePool.get(deviceId);
422 LabelResourcePool pool = poolOld.value();
jccde3e92e2015-03-28 01:40:44 -0700423 if (pool == null) {
jccde3e92e2015-03-28 01:40:44 -0700424 log.info("the label resource pool of device id {} does not exist");
425 return false;
426 }
Satish K0de87612015-11-24 13:44:52 +0530427 Set<LabelResource> storeSet = new HashSet<LabelResource>(pool.releaseLabelId());
jccde3e92e2015-03-28 01:40:44 -0700428 LabelResource labelResource = null;
429 long realReleasedNum = 0;
430 for (Iterator<LabelResource> it = release.iterator(); it.hasNext();) {
431 labelResource = it.next();
432 if (labelResource.labelResourceId().labelId() < pool.beginLabel()
433 .labelId()
434 || labelResource.labelResourceId().labelId() > pool
435 .endLabel().labelId()) {
436 continue;
437 }
438 if (pool.currentUsedMaxLabelId().labelId() > labelResource
439 .labelResourceId().labelId()
440 || !storeSet.contains(labelResource)) {
441 storeSet.add(labelResource);
442 realReleasedNum++;
443 }
444 }
445 long beginNum = pool.beginLabel().labelId();
446 long endNum = pool.endLabel().labelId();
447 long totalNum = pool.totalNum();
448 long usedNum = pool.usedNum() - realReleasedNum;
449 long current = pool.currentUsedMaxLabelId().labelId();
450 ImmutableSet<LabelResource> s = ImmutableSet.copyOf(storeSet);
451 LabelResourcePool newPool = new LabelResourcePool(deviceId.toString(),
452 beginNum, endNum,
453 totalNum, usedNum,
454 current, s);
455 resourcePool.put(deviceId, newPool);
456 log.info("success to release label resource");
jccde3e92e2015-03-28 01:40:44 -0700457 return true;
458 }
459
460 @Override
461 public boolean isDevicePoolFull(DeviceId deviceId) {
samuel7a5691a2015-05-23 00:36:32 +0800462 Versioned<LabelResourcePool> pool = resourcePool.get(deviceId);
jccde3e92e2015-03-28 01:40:44 -0700463 if (pool == null) {
464 return true;
465 }
samuel7a5691a2015-05-23 00:36:32 +0800466 return pool.value().currentUsedMaxLabelId() == pool.value().endLabel()
467 && pool.value().releaseLabelId().size() == 0 ? true : false;
jccde3e92e2015-03-28 01:40:44 -0700468 }
469
470 @Override
471 public long getFreeNumOfDevicePool(DeviceId deviceId) {
samuel7a5691a2015-05-23 00:36:32 +0800472 Versioned<LabelResourcePool> pool = resourcePool.get(deviceId);
jccde3e92e2015-03-28 01:40:44 -0700473 if (pool == null) {
474 return 0;
475 }
samuel7a5691a2015-05-23 00:36:32 +0800476 return pool.value().endLabel().labelId()
477 - pool.value().currentUsedMaxLabelId().labelId()
478 + pool.value().releaseLabelId().size();
jccde3e92e2015-03-28 01:40:44 -0700479 }
480
481 @Override
482 public LabelResourcePool getDeviceLabelResourcePool(DeviceId deviceId) {
samuel7a5691a2015-05-23 00:36:32 +0800483 Versioned<LabelResourcePool> pool = resourcePool.get(deviceId);
484 return pool == null ? null : pool.value();
jccde3e92e2015-03-28 01:40:44 -0700485 }
486
487 @Override
488 public boolean destroyGlobalPool() {
489 return this.internalDestroy(DeviceId
490 .deviceId(GLOBAL_RESOURCE_POOL_DEVICE_ID));
491 }
492
493 @Override
494 public Collection<LabelResource> applyFromGlobalPool(long applyNum) {
Satish K0de87612015-11-24 13:44:52 +0530495 LabelResourceRequest request = new LabelResourceRequest(DeviceId.deviceId(GLOBAL_RESOURCE_POOL_DEVICE_ID),
jccde3e92e2015-03-28 01:40:44 -0700496 LabelResourceRequest.Type.APPLY,
497 applyNum, null);
498 return this.internalApply(request);
499 }
500
501 @Override
502 public boolean releaseToGlobalPool(Set<LabelResourceId> release) {
503 Set<LabelResource> set = new HashSet<LabelResource>();
504 DefaultLabelResource resource = null;
505 for (LabelResourceId labelResource : release) {
Satish K0de87612015-11-24 13:44:52 +0530506 resource = new DefaultLabelResource(DeviceId.deviceId(GLOBAL_RESOURCE_POOL_DEVICE_ID),
jccde3e92e2015-03-28 01:40:44 -0700507 labelResource);
508 set.add(resource);
509 }
Satish K0de87612015-11-24 13:44:52 +0530510 LabelResourceRequest request = new LabelResourceRequest(DeviceId.deviceId(GLOBAL_RESOURCE_POOL_DEVICE_ID),
jccde3e92e2015-03-28 01:40:44 -0700511 LabelResourceRequest.Type.APPLY,
512 0,
Satish K0de87612015-11-24 13:44:52 +0530513 ImmutableSet.copyOf(set));
jccde3e92e2015-03-28 01:40:44 -0700514 return this.internalRelease(request);
515 }
516
517 @Override
518 public boolean isGlobalPoolFull() {
519 return this.isDevicePoolFull(DeviceId
520 .deviceId(GLOBAL_RESOURCE_POOL_DEVICE_ID));
521 }
522
523 @Override
524 public long getFreeNumOfGlobalPool() {
525 return this.getFreeNumOfDevicePool(DeviceId
526 .deviceId(GLOBAL_RESOURCE_POOL_DEVICE_ID));
527 }
528
529 @Override
530 public LabelResourcePool getGlobalLabelResourcePool() {
531 return this.getDeviceLabelResourcePool(DeviceId
532 .deviceId(GLOBAL_RESOURCE_POOL_DEVICE_ID));
533 }
534
535 private <T> T complete(Future<T> future) {
536 try {
samuel7a5691a2015-05-23 00:36:32 +0800537 return future.get(PEER_REQUEST_TIMEOUT_MS, TimeUnit.MILLISECONDS);
jccde3e92e2015-03-28 01:40:44 -0700538 } catch (InterruptedException e) {
539 Thread.currentThread().interrupt();
540 log.error("Interrupted while waiting for operation to complete.", e);
541 return null;
542 } catch (TimeoutException | ExecutionException e) {
543 log.error("Failed remote operation", e);
544 return null;
545 }
546 }
547}