blob: fda0d83dcf0666a23218f37df18f1fe406daab01 [file] [log] [blame]
Thomas Vachuska58de4162015-09-10 16:15:33 -07001/*
Brian O'Connor5ab426f2016-04-09 01:19:45 -07002 * Copyright 2015-present Open Networking Laboratory
Thomas Vachuska58de4162015-09-10 16:15:33 -07003 *
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;
jccde3e92e2015-03-28 01:40:44 -070058import org.onosproject.store.serializers.KryoNamespaces;
jccde3e92e2015-03-28 01:40:44 -070059import org.onosproject.store.service.ConsistentMap;
60import org.onosproject.store.service.Serializer;
61import org.onosproject.store.service.StorageService;
samuel7a5691a2015-05-23 00:36:32 +080062import org.onosproject.store.service.Versioned;
jccde3e92e2015-03-28 01:40:44 -070063import org.slf4j.Logger;
64
65import com.google.common.collect.ImmutableSet;
66import com.google.common.collect.Multimap;
67
68/**
69 * Manages label resources using copycat.
70 */
71@Component(immediate = true, enabled = true)
72@Service
73public class DistributedLabelResourceStore
74 extends AbstractStore<LabelResourceEvent, LabelResourceDelegate>
75 implements LabelResourceStore {
76 private final Logger log = getLogger(getClass());
77
78 private static final String POOL_MAP_NAME = "labelresourcepool";
79
80 private static final String GLOBAL_RESOURCE_POOL_DEVICE_ID = "global_resource_pool_device_id";
jccde3e92e2015-03-28 01:40:44 -070081
82 private ConsistentMap<DeviceId, LabelResourcePool> resourcePool = null;
83
84 @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
85 protected StorageService storageService;
86
87 @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
Madan Jampanic156dd02015-08-12 15:57:46 -070088 protected MastershipService mastershipService;
jccde3e92e2015-03-28 01:40:44 -070089
90 @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
91 protected ClusterCommunicationService clusterCommunicator;
92
93 @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
94 protected ClusterService clusterService;
95
96 @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
97 protected DeviceService deviceService;
98
99 private ExecutorService messageHandlingExecutor;
100 private static final int MESSAGE_HANDLER_THREAD_POOL_SIZE = 8;
101 private static final long PEER_REQUEST_TIMEOUT_MS = 5000;
102
samuel7a5691a2015-05-23 00:36:32 +0800103 private static final Serializer SERIALIZER = Serializer
104 .using(new KryoNamespace.Builder().register(KryoNamespaces.API)
jccde3e92e2015-03-28 01:40:44 -0700105 .register(LabelResourceEvent.class)
HIGUCHI Yutac0f50452016-05-13 19:26:05 -0700106 .register(LabelResourcePool.class)
jccde3e92e2015-03-28 01:40:44 -0700107 .register(LabelResourceRequest.class)
108 .register(LabelResourceRequest.Type.class)
109 .register(LabelResourceEvent.Type.class)
110 .register(DefaultLabelResource.class)
samuel7a5691a2015-05-23 00:36:32 +0800111 .register(LabelResourceId.class)
112 .nextId(KryoNamespaces.BEGIN_USER_CUSTOM_ID).build());
jccde3e92e2015-03-28 01:40:44 -0700113
114 @Activate
115 public void activate() {
116
117 resourcePool = storageService
118 .<DeviceId, LabelResourcePool>consistentMapBuilder()
Madan Jampani54c5e232016-07-11 15:35:25 -0700119 .withName(POOL_MAP_NAME).withSerializer(SERIALIZER).build();
jccde3e92e2015-03-28 01:40:44 -0700120 messageHandlingExecutor = Executors
121 .newFixedThreadPool(MESSAGE_HANDLER_THREAD_POOL_SIZE,
122 groupedThreads("onos/store/flow",
123 "message-handlers"));
124 clusterCommunicator
125 .addSubscriber(LabelResourceMessageSubjects.LABEL_POOL_CREATED,
Sho SHIMIZUc032c832016-01-13 13:02:05 -0800126 SERIALIZER::<LabelResourcePool>decode,
127 operation -> {
128 log.trace("received get flow entry request for {}", operation);
129 return internalCreate(operation);
130 },
131 SERIALIZER::<Boolean>encode,
132 messageHandlingExecutor);
jccde3e92e2015-03-28 01:40:44 -0700133 clusterCommunicator
134 .addSubscriber(LabelResourceMessageSubjects.LABEL_POOL_DESTROYED,
Sho SHIMIZUc032c832016-01-13 13:02:05 -0800135 SERIALIZER::<DeviceId>decode,
136 deviceId -> {
137 log.trace("received get flow entry request for {}", deviceId);
138 return internalDestroy(deviceId);
139 },
140 SERIALIZER::<Boolean>encode,
141 messageHandlingExecutor);
jccde3e92e2015-03-28 01:40:44 -0700142 clusterCommunicator
143 .addSubscriber(LabelResourceMessageSubjects.LABEL_POOL_APPLY,
Sho SHIMIZUc032c832016-01-13 13:02:05 -0800144 SERIALIZER::<LabelResourceRequest>decode,
145 request -> {
146 log.trace("received get flow entry request for {}", request);
147 return internalApply(request);
jccde3e92e2015-03-28 01:40:44 -0700148
Sho SHIMIZUc032c832016-01-13 13:02:05 -0800149 },
150 SERIALIZER::<Collection<LabelResource>>encode,
151 messageHandlingExecutor);
jccde3e92e2015-03-28 01:40:44 -0700152 clusterCommunicator
153 .addSubscriber(LabelResourceMessageSubjects.LABEL_POOL_RELEASE,
Sho SHIMIZUc032c832016-01-13 13:02:05 -0800154 SERIALIZER::<LabelResourceRequest>decode,
155 request -> {
156 log.trace("received get flow entry request for {}",
157 request);
158 return internalRelease(request);
159 },
160 SERIALIZER::<Boolean>encode,
161 messageHandlingExecutor);
jccde3e92e2015-03-28 01:40:44 -0700162 log.info("Started");
163 }
164
165 @Deactivate
166 public void deactivate() {
167 clusterCommunicator
168 .removeSubscriber(LabelResourceMessageSubjects.LABEL_POOL_CREATED);
169 clusterCommunicator
170 .removeSubscriber(LabelResourceMessageSubjects.LABEL_POOL_APPLY);
171 clusterCommunicator
172 .removeSubscriber(LabelResourceMessageSubjects.LABEL_POOL_DESTROYED);
173 clusterCommunicator
174 .removeSubscriber(LabelResourceMessageSubjects.LABEL_POOL_RELEASE);
175 messageHandlingExecutor.shutdown();
176 log.info("Stopped");
177 }
178
179 @Override
180 public boolean createDevicePool(DeviceId deviceId,
181 LabelResourceId beginLabel,
182 LabelResourceId endLabel) {
183 LabelResourcePool pool = new LabelResourcePool(deviceId.toString(),
184 beginLabel.labelId(),
185 endLabel.labelId());
186 return this.create(pool);
187 }
188
189 @Override
190 public boolean createGlobalPool(LabelResourceId beginLabel,
191 LabelResourceId endLabel) {
Satish K0de87612015-11-24 13:44:52 +0530192 LabelResourcePool pool = new LabelResourcePool(GLOBAL_RESOURCE_POOL_DEVICE_ID,
jccde3e92e2015-03-28 01:40:44 -0700193 beginLabel.labelId(),
194 endLabel.labelId());
195 return this.internalCreate(pool);
196 }
197
198 private boolean create(LabelResourcePool pool) {
HIGUCHI Yutac0f50452016-05-13 19:26:05 -0700199 Device device = deviceService.getDevice(pool.deviceId());
jccde3e92e2015-03-28 01:40:44 -0700200 if (device == null) {
201 return false;
202 }
203
Madan Jampanic156dd02015-08-12 15:57:46 -0700204 NodeId master = mastershipService.getMasterFor(pool.deviceId());
jccde3e92e2015-03-28 01:40:44 -0700205
Madan Jampanic156dd02015-08-12 15:57:46 -0700206 if (master == null) {
207 log.warn("Failed to create label resource pool: No master for {}", pool);
jccde3e92e2015-03-28 01:40:44 -0700208 return false;
209 }
210
Madan Jampanic156dd02015-08-12 15:57:46 -0700211 if (master.equals(clusterService.getLocalNode().id())) {
jccde3e92e2015-03-28 01:40:44 -0700212 return internalCreate(pool);
213 }
214
215 log.trace("Forwarding getFlowEntries to {}, which is the primary (master) for device {}",
Madan Jampanic156dd02015-08-12 15:57:46 -0700216 master, pool.deviceId());
jccde3e92e2015-03-28 01:40:44 -0700217
218 return complete(clusterCommunicator
219 .sendAndReceive(pool,
220 LabelResourceMessageSubjects.LABEL_POOL_CREATED,
221 SERIALIZER::encode, SERIALIZER::decode,
Madan Jampanic156dd02015-08-12 15:57:46 -0700222 master));
jccde3e92e2015-03-28 01:40:44 -0700223 }
224
225 private boolean internalCreate(LabelResourcePool pool) {
samuel7a5691a2015-05-23 00:36:32 +0800226 Versioned<LabelResourcePool> poolOld = resourcePool
227 .get(pool.deviceId());
jccde3e92e2015-03-28 01:40:44 -0700228 if (poolOld == null) {
229 resourcePool.put(pool.deviceId(), pool);
Satish K0de87612015-11-24 13:44:52 +0530230 LabelResourceEvent event = new LabelResourceEvent(Type.POOL_CREATED,
jccde3e92e2015-03-28 01:40:44 -0700231 pool);
232 notifyDelegate(event);
233 return true;
234 }
jccde3e92e2015-03-28 01:40:44 -0700235 return false;
236 }
237
238 @Override
239 public boolean destroyDevicePool(DeviceId deviceId) {
HIGUCHI Yutac0f50452016-05-13 19:26:05 -0700240 Device device = deviceService.getDevice(deviceId);
jccde3e92e2015-03-28 01:40:44 -0700241 if (device == null) {
242 return false;
243 }
jccde3e92e2015-03-28 01:40:44 -0700244
Madan Jampanic156dd02015-08-12 15:57:46 -0700245 NodeId master = mastershipService.getMasterFor(deviceId);
246
247 if (master == null) {
248 log.warn("Failed to destroyDevicePool. No master for {}", deviceId);
jccde3e92e2015-03-28 01:40:44 -0700249 return false;
250 }
251
Madan Jampanic156dd02015-08-12 15:57:46 -0700252 if (master.equals(clusterService.getLocalNode().id())) {
jccde3e92e2015-03-28 01:40:44 -0700253 return internalDestroy(deviceId);
254 }
255
Madan Jampanic156dd02015-08-12 15:57:46 -0700256 log.trace("Forwarding request to {}, which is the primary (master) for device {}",
257 master, deviceId);
jccde3e92e2015-03-28 01:40:44 -0700258
259 return complete(clusterCommunicator
260 .sendAndReceive(deviceId,
261 LabelResourceMessageSubjects.LABEL_POOL_DESTROYED,
262 SERIALIZER::encode, SERIALIZER::decode,
Madan Jampanic156dd02015-08-12 15:57:46 -0700263 master));
jccde3e92e2015-03-28 01:40:44 -0700264 }
265
266 private boolean internalDestroy(DeviceId deviceId) {
samuel7a5691a2015-05-23 00:36:32 +0800267 Versioned<LabelResourcePool> poolOld = resourcePool.get(deviceId);
jccde3e92e2015-03-28 01:40:44 -0700268 if (poolOld != null) {
269 resourcePool.remove(deviceId);
Satish K0de87612015-11-24 13:44:52 +0530270 LabelResourceEvent event = new LabelResourceEvent(Type.POOL_DESTROYED,
samuel7a5691a2015-05-23 00:36:32 +0800271 poolOld.value());
jccde3e92e2015-03-28 01:40:44 -0700272 notifyDelegate(event);
273 }
274 log.info("success to destroy the label resource pool of device id {}",
275 deviceId);
276 return true;
277 }
278
279 @Override
280 public Collection<LabelResource> applyFromDevicePool(DeviceId deviceId,
281 long applyNum) {
HIGUCHI Yutac0f50452016-05-13 19:26:05 -0700282 Device device = deviceService.getDevice(deviceId);
jccde3e92e2015-03-28 01:40:44 -0700283 if (device == null) {
284 return Collections.emptyList();
285 }
Satish K0de87612015-11-24 13:44:52 +0530286 LabelResourceRequest request = new LabelResourceRequest(deviceId,
jccde3e92e2015-03-28 01:40:44 -0700287 LabelResourceRequest.Type.APPLY,
288 applyNum, null);
Madan Jampanic156dd02015-08-12 15:57:46 -0700289 NodeId master = mastershipService.getMasterFor(deviceId);
jccde3e92e2015-03-28 01:40:44 -0700290
Madan Jampanic156dd02015-08-12 15:57:46 -0700291 if (master == null) {
292 log.warn("Failed to applyFromDevicePool: No master for {}", deviceId);
jccde3e92e2015-03-28 01:40:44 -0700293 return Collections.emptyList();
294 }
295
Madan Jampanic156dd02015-08-12 15:57:46 -0700296 if (master.equals(clusterService.getLocalNode().id())) {
jccde3e92e2015-03-28 01:40:44 -0700297 return internalApply(request);
298 }
299
Madan Jampanic156dd02015-08-12 15:57:46 -0700300 log.trace("Forwarding request to {}, which is the primary (master) for device {}",
301 master, deviceId);
jccde3e92e2015-03-28 01:40:44 -0700302
303 return complete(clusterCommunicator
304 .sendAndReceive(request,
305 LabelResourceMessageSubjects.LABEL_POOL_APPLY,
306 SERIALIZER::encode, SERIALIZER::decode,
Madan Jampanic156dd02015-08-12 15:57:46 -0700307 master));
jccde3e92e2015-03-28 01:40:44 -0700308 }
309
310 private Collection<LabelResource> internalApply(LabelResourceRequest request) {
jccde3e92e2015-03-28 01:40:44 -0700311 DeviceId deviceId = request.deviceId();
312 long applyNum = request.applyNum();
samuel7a5691a2015-05-23 00:36:32 +0800313 Versioned<LabelResourcePool> poolOld = resourcePool.get(deviceId);
Satish Kf8ba8f02016-02-17 13:18:35 +0530314 if (poolOld == null) {
315 log.info("label resource pool not allocated for deviceId {}.", deviceId);
316 return Collections.emptyList();
317 }
samuel7a5691a2015-05-23 00:36:32 +0800318 LabelResourcePool pool = poolOld.value();
HIGUCHI Yutac0f50452016-05-13 19:26:05 -0700319 Collection<LabelResource> result = new HashSet<>();
jccde3e92e2015-03-28 01:40:44 -0700320 long freeNum = this.getFreeNumOfDevicePool(deviceId);
321 if (applyNum > freeNum) {
322 log.info("the free number of the label resource pool of deviceId {} is not enough.");
jccde3e92e2015-03-28 01:40:44 -0700323 return Collections.emptyList();
324 }
HIGUCHI Yutac0f50452016-05-13 19:26:05 -0700325 Set<LabelResource> releaseLabels = new HashSet<>(pool.releaseLabelId());
jccde3e92e2015-03-28 01:40:44 -0700326 long tmp = releaseLabels.size() > applyNum ? applyNum : releaseLabels
327 .size();
328 LabelResource resource = null;
329 for (int i = 0; i < tmp; i++) {
330 Iterator<LabelResource> it = releaseLabels.iterator();
331 if (it.hasNext()) {
332 resource = it.next();
333 releaseLabels.remove(resource);
334 }
335 result.add(resource);
336 }
337 for (long j = pool.currentUsedMaxLabelId().labelId(); j < pool
338 .currentUsedMaxLabelId().labelId() + applyNum - tmp; j++) {
339 resource = new DefaultLabelResource(deviceId,
340 LabelResourceId
341 .labelResourceId(j));
342 result.add(resource);
343 }
344 long beginLabel = pool.beginLabel().labelId();
345 long endLabel = pool.endLabel().labelId();
346 long totalNum = pool.totalNum();
347 long current = pool.currentUsedMaxLabelId().labelId() + applyNum - tmp;
348 long usedNum = pool.usedNum() + applyNum;
349 ImmutableSet<LabelResource> freeLabel = ImmutableSet
350 .copyOf(releaseLabels);
351 LabelResourcePool newPool = new LabelResourcePool(deviceId.toString(),
352 beginLabel, endLabel,
353 totalNum, usedNum,
354 current, freeLabel);
355 resourcePool.put(deviceId, newPool);
356 log.info("success to apply label resource");
jccde3e92e2015-03-28 01:40:44 -0700357 return result;
358 }
359
360 @Override
361 public boolean releaseToDevicePool(Multimap<DeviceId, LabelResource> release) {
362 Map<DeviceId, Collection<LabelResource>> maps = release.asMap();
363 Set<DeviceId> deviceIdSet = maps.keySet();
364 LabelResourceRequest request = null;
365 for (Iterator<DeviceId> it = deviceIdSet.iterator(); it.hasNext();) {
HIGUCHI Yutac0f50452016-05-13 19:26:05 -0700366 DeviceId deviceId = it.next();
367 Device device = deviceService.getDevice(deviceId);
jccde3e92e2015-03-28 01:40:44 -0700368 if (device == null) {
369 continue;
370 }
371 ImmutableSet<LabelResource> collection = ImmutableSet.copyOf(maps
372 .get(deviceId));
Satish K0de87612015-11-24 13:44:52 +0530373 request = new LabelResourceRequest(deviceId,
jccde3e92e2015-03-28 01:40:44 -0700374 LabelResourceRequest.Type.RELEASE,
375 0, collection);
Madan Jampanic156dd02015-08-12 15:57:46 -0700376 NodeId master = mastershipService.getMasterFor(deviceId);
jccde3e92e2015-03-28 01:40:44 -0700377
Madan Jampanic156dd02015-08-12 15:57:46 -0700378 if (master == null) {
379 log.warn("Failed to releaseToDevicePool: No master for {}", deviceId);
jccde3e92e2015-03-28 01:40:44 -0700380 return false;
381 }
382
Madan Jampanic156dd02015-08-12 15:57:46 -0700383 if (master.equals(clusterService.getLocalNode().id())) {
jccde3e92e2015-03-28 01:40:44 -0700384 return internalRelease(request);
385 }
386
Madan Jampanic156dd02015-08-12 15:57:46 -0700387 log.trace("Forwarding request to {}, which is the primary (master) for device {}",
388 master, deviceId);
jccde3e92e2015-03-28 01:40:44 -0700389
390 return complete(clusterCommunicator
391 .sendAndReceive(request,
392 LabelResourceMessageSubjects.LABEL_POOL_RELEASE,
393 SERIALIZER::encode, SERIALIZER::decode,
Madan Jampanic156dd02015-08-12 15:57:46 -0700394 master));
jccde3e92e2015-03-28 01:40:44 -0700395 }
396 return false;
397 }
398
399 private boolean internalRelease(LabelResourceRequest request) {
jccde3e92e2015-03-28 01:40:44 -0700400 DeviceId deviceId = request.deviceId();
401 Collection<LabelResource> release = request.releaseCollection();
samuel7a5691a2015-05-23 00:36:32 +0800402 Versioned<LabelResourcePool> poolOld = resourcePool.get(deviceId);
Satish Kf8ba8f02016-02-17 13:18:35 +0530403 if (poolOld == null) {
404 log.info("the label resource pool of device id {} not allocated");
405 return false;
406 }
samuel7a5691a2015-05-23 00:36:32 +0800407 LabelResourcePool pool = poolOld.value();
jccde3e92e2015-03-28 01:40:44 -0700408 if (pool == null) {
jccde3e92e2015-03-28 01:40:44 -0700409 log.info("the label resource pool of device id {} does not exist");
410 return false;
411 }
HIGUCHI Yutac0f50452016-05-13 19:26:05 -0700412 Set<LabelResource> storeSet = new HashSet<>(pool.releaseLabelId());
jccde3e92e2015-03-28 01:40:44 -0700413 LabelResource labelResource = null;
414 long realReleasedNum = 0;
415 for (Iterator<LabelResource> it = release.iterator(); it.hasNext();) {
416 labelResource = it.next();
417 if (labelResource.labelResourceId().labelId() < pool.beginLabel()
418 .labelId()
419 || labelResource.labelResourceId().labelId() > pool
420 .endLabel().labelId()) {
421 continue;
422 }
423 if (pool.currentUsedMaxLabelId().labelId() > labelResource
424 .labelResourceId().labelId()
425 || !storeSet.contains(labelResource)) {
426 storeSet.add(labelResource);
427 realReleasedNum++;
428 }
429 }
430 long beginNum = pool.beginLabel().labelId();
431 long endNum = pool.endLabel().labelId();
432 long totalNum = pool.totalNum();
433 long usedNum = pool.usedNum() - realReleasedNum;
434 long current = pool.currentUsedMaxLabelId().labelId();
435 ImmutableSet<LabelResource> s = ImmutableSet.copyOf(storeSet);
436 LabelResourcePool newPool = new LabelResourcePool(deviceId.toString(),
437 beginNum, endNum,
438 totalNum, usedNum,
439 current, s);
440 resourcePool.put(deviceId, newPool);
441 log.info("success to release label resource");
jccde3e92e2015-03-28 01:40:44 -0700442 return true;
443 }
444
445 @Override
446 public boolean isDevicePoolFull(DeviceId deviceId) {
samuel7a5691a2015-05-23 00:36:32 +0800447 Versioned<LabelResourcePool> pool = resourcePool.get(deviceId);
jccde3e92e2015-03-28 01:40:44 -0700448 if (pool == null) {
449 return true;
450 }
samuel7a5691a2015-05-23 00:36:32 +0800451 return pool.value().currentUsedMaxLabelId() == pool.value().endLabel()
452 && pool.value().releaseLabelId().size() == 0 ? true : false;
jccde3e92e2015-03-28 01:40:44 -0700453 }
454
455 @Override
456 public long getFreeNumOfDevicePool(DeviceId deviceId) {
samuel7a5691a2015-05-23 00:36:32 +0800457 Versioned<LabelResourcePool> pool = resourcePool.get(deviceId);
jccde3e92e2015-03-28 01:40:44 -0700458 if (pool == null) {
459 return 0;
460 }
samuel7a5691a2015-05-23 00:36:32 +0800461 return pool.value().endLabel().labelId()
462 - pool.value().currentUsedMaxLabelId().labelId()
463 + pool.value().releaseLabelId().size();
jccde3e92e2015-03-28 01:40:44 -0700464 }
465
466 @Override
467 public LabelResourcePool getDeviceLabelResourcePool(DeviceId deviceId) {
samuel7a5691a2015-05-23 00:36:32 +0800468 Versioned<LabelResourcePool> pool = resourcePool.get(deviceId);
469 return pool == null ? null : pool.value();
jccde3e92e2015-03-28 01:40:44 -0700470 }
471
472 @Override
473 public boolean destroyGlobalPool() {
474 return this.internalDestroy(DeviceId
475 .deviceId(GLOBAL_RESOURCE_POOL_DEVICE_ID));
476 }
477
478 @Override
479 public Collection<LabelResource> applyFromGlobalPool(long applyNum) {
Satish K0de87612015-11-24 13:44:52 +0530480 LabelResourceRequest request = new LabelResourceRequest(DeviceId.deviceId(GLOBAL_RESOURCE_POOL_DEVICE_ID),
jccde3e92e2015-03-28 01:40:44 -0700481 LabelResourceRequest.Type.APPLY,
482 applyNum, null);
483 return this.internalApply(request);
484 }
485
486 @Override
487 public boolean releaseToGlobalPool(Set<LabelResourceId> release) {
HIGUCHI Yutac0f50452016-05-13 19:26:05 -0700488 Set<LabelResource> set = new HashSet<>();
jccde3e92e2015-03-28 01:40:44 -0700489 DefaultLabelResource resource = null;
490 for (LabelResourceId labelResource : release) {
Satish K0de87612015-11-24 13:44:52 +0530491 resource = new DefaultLabelResource(DeviceId.deviceId(GLOBAL_RESOURCE_POOL_DEVICE_ID),
jccde3e92e2015-03-28 01:40:44 -0700492 labelResource);
493 set.add(resource);
494 }
Satish K0de87612015-11-24 13:44:52 +0530495 LabelResourceRequest request = new LabelResourceRequest(DeviceId.deviceId(GLOBAL_RESOURCE_POOL_DEVICE_ID),
Priyanka Ba6364052016-02-01 10:25:42 +0530496 LabelResourceRequest.Type.RELEASE,
jccde3e92e2015-03-28 01:40:44 -0700497 0,
Satish K0de87612015-11-24 13:44:52 +0530498 ImmutableSet.copyOf(set));
jccde3e92e2015-03-28 01:40:44 -0700499 return this.internalRelease(request);
500 }
501
502 @Override
503 public boolean isGlobalPoolFull() {
504 return this.isDevicePoolFull(DeviceId
505 .deviceId(GLOBAL_RESOURCE_POOL_DEVICE_ID));
506 }
507
508 @Override
509 public long getFreeNumOfGlobalPool() {
510 return this.getFreeNumOfDevicePool(DeviceId
511 .deviceId(GLOBAL_RESOURCE_POOL_DEVICE_ID));
512 }
513
514 @Override
515 public LabelResourcePool getGlobalLabelResourcePool() {
516 return this.getDeviceLabelResourcePool(DeviceId
517 .deviceId(GLOBAL_RESOURCE_POOL_DEVICE_ID));
518 }
519
520 private <T> T complete(Future<T> future) {
521 try {
samuel7a5691a2015-05-23 00:36:32 +0800522 return future.get(PEER_REQUEST_TIMEOUT_MS, TimeUnit.MILLISECONDS);
jccde3e92e2015-03-28 01:40:44 -0700523 } catch (InterruptedException e) {
524 Thread.currentThread().interrupt();
525 log.error("Interrupted while waiting for operation to complete.", e);
526 return null;
527 } catch (TimeoutException | ExecutionException e) {
528 log.error("Failed remote operation", e);
529 return null;
530 }
531 }
532}