2 * Copyright (c) 2015 Ericsson India Global Services Pvt Ltd. and others. All rights reserved.
4 * This program and the accompanying materials are made available under the
5 * terms of the Eclipse Public License v1.0 which accompanies this distribution,
6 * and is available at http://www.eclipse.org/legal/epl-v10.html
9 package org.opendaylight.idmanager;
11 import java.util.Collections;
12 import java.util.Comparator;
13 import java.util.LinkedList;
14 import java.util.List;
15 import java.util.concurrent.ExecutionException;
16 import java.util.concurrent.Future;
18 import org.opendaylight.controller.md.sal.binding.api.DataBroker;
19 import org.opendaylight.controller.md.sal.binding.api.DataChangeListener;
20 import org.opendaylight.controller.md.sal.binding.api.ReadOnlyTransaction;
21 import org.opendaylight.controller.md.sal.binding.api.WriteTransaction;
22 import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType;
23 import org.opendaylight.controller.md.sal.common.api.data.TransactionCommitFailedException;
24 import org.opendaylight.vpnservice.mdsalutil.MDSALUtil;
25 import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.idmanager.rev150403.AllocateIdInput;
26 import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.idmanager.rev150403.AllocateIdOutput;
27 import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.idmanager.rev150403.AllocateIdOutputBuilder;
28 import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.idmanager.rev150403.CreateIdPoolInput;
29 import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.idmanager.rev150403.DeleteIdPoolInput;
30 import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.idmanager.rev150403.IdManagerService;
31 import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.idmanager.rev150403.IdPools;
32 import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.idmanager.rev150403.ReleaseIdInput;
33 import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.idmanager.rev150403.id.pools.IdPool;
34 import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.idmanager.rev150403.id.pools.IdPoolBuilder;
35 import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.idmanager.rev150403.id.pools.IdPoolKey;
36 import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.idmanager.rev150403.id.pools.id.pool.AvailableIdsHolder;
37 import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.idmanager.rev150403.id.pools.id.pool.AvailableIdsHolderBuilder;
38 import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.idmanager.rev150403.id.pools.id.pool.ChildPools;
39 import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.idmanager.rev150403.id.pools.id.pool.IdEntries;
40 import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.idmanager.rev150403.id.pools.id.pool.ReleasedIdsHolder;
41 import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.idmanager.rev150403.id.pools.id.pool.ReleasedIdsHolderBuilder;
42 import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.idmanager.rev150403.released.ids.DelayedIdEntries;
43 import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.idmanager.rev150403.released.ids.DelayedIdEntriesBuilder;
44 import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.lockmanager.rev150819.LockManagerService;
45 import org.opendaylight.yangtools.concepts.ListenerRegistration;
46 import org.opendaylight.yangtools.yang.binding.DataObject;
47 import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
48 import org.opendaylight.yangtools.yang.common.RpcError.ErrorType;
49 import org.opendaylight.yangtools.yang.common.RpcResult;
50 import org.opendaylight.yangtools.yang.common.RpcResultBuilder;
51 import org.slf4j.Logger;
52 import org.slf4j.LoggerFactory;
54 import com.google.common.base.Optional;
55 import com.google.common.util.concurrent.CheckedFuture;
56 import com.google.common.util.concurrent.Futures;
58 public class IdManager implements IdManagerService, AutoCloseable{
59 private static final Logger LOG = LoggerFactory.getLogger(IdManager.class);
61 private static final long DEFAULT_IDLE_TIME = 24 * 60 * 60;
63 private ListenerRegistration<DataChangeListener> listenerRegistration;
64 private final DataBroker broker;
65 private LockManagerService lockManager;
68 public void close() throws Exception {
69 if (listenerRegistration != null) {
71 listenerRegistration.close();
72 } catch (final Exception e) {
73 LOG.error("Error when cleaning up DataChangeListener.", e);
75 listenerRegistration = null;
77 LOG.info("IDManager Closed");
80 public IdManager(final DataBroker db) {
84 public void setLockManager(LockManagerService lockManager) {
85 this.lockManager = lockManager;
89 public Future<RpcResult<Void>> createIdPool(CreateIdPoolInput input) {
90 LOG.debug("createIdPool called with input {}", input);
91 String poolName = input.getPoolName();
92 long low = input.getLow();
93 long high = input.getHigh();
94 long blockSize = IdUtils.computeBlockSize(low, high);
95 RpcResultBuilder<Void> createIdPoolRpcBuilder;
96 IdUtils.lockPool(lockManager, poolName);
98 InstanceIdentifier<IdPool> idPoolInstanceIdentifier = IdUtils.getIdPoolInstance(poolName);
99 poolName = poolName.intern();
101 idPool = createGlobalPool(poolName, low, high, blockSize, idPoolInstanceIdentifier);
102 String localPoolName = IdUtils.getLocalPoolName(poolName);
103 if (createLocalPool(localPoolName, idPool)) {
104 LOG.debug("Updating global id pool {} with childPool {}", poolName, localPoolName);
105 updateChildPool(poolName, localPoolName);
107 createIdPoolRpcBuilder = RpcResultBuilder.success();
108 } catch (Exception ex) {
109 LOG.error("Creation of Id Pool {} failed due to {}", poolName, ex);
110 createIdPoolRpcBuilder = RpcResultBuilder.failed();
111 createIdPoolRpcBuilder.withError(ErrorType.APPLICATION, ex.getMessage());
113 IdUtils.unlockPool(lockManager, poolName);
115 return Futures.immediateFuture(createIdPoolRpcBuilder.build());
119 public Future<RpcResult<AllocateIdOutput>> allocateId(AllocateIdInput input) {
120 LOG.debug("AllocateId called with input {}", input);
121 String idKey = input.getIdKey();
122 String poolName = input.getPoolName();
123 String localPoolName = IdUtils.getLocalPoolName(poolName);
124 RpcResultBuilder<AllocateIdOutput> allocateIdRpcBuilder;
125 long newIdValue = -1;
126 AllocateIdOutputBuilder output = new AllocateIdOutputBuilder();
128 newIdValue = allocateIdFromLocalPool(localPoolName, idKey);
129 output.setIdValue(newIdValue);
130 allocateIdRpcBuilder = RpcResultBuilder.success();
131 allocateIdRpcBuilder.withResult(output.build());
132 } catch (Exception ex) {
133 LOG.error("Allocate id in pool {} failed due to {}", poolName, ex);
134 allocateIdRpcBuilder = RpcResultBuilder.failed();
135 allocateIdRpcBuilder.withError(ErrorType.APPLICATION, ex.getMessage());
137 return Futures.immediateFuture(allocateIdRpcBuilder.build());
141 public Future<RpcResult<Void>> deleteIdPool(DeleteIdPoolInput input) {
142 LOG.debug("DeleteIdPool called with input {}", input);
143 String poolName = input.getPoolName();
144 RpcResultBuilder<Void> deleteIdPoolRpcBuilder;
146 InstanceIdentifier<IdPool> idPoolToBeDeleted = IdUtils.getIdPoolInstance(poolName);
147 poolName = poolName.intern();
148 synchronized(poolName) {
149 IdPool idPool = getIdPool(idPoolToBeDeleted);
150 List<ChildPools> childPoolList = idPool.getChildPools();
151 if (childPoolList != null) {
152 for (ChildPools childPoolName : childPoolList) {
153 deletePool(childPoolName.getChildPoolName());
156 MDSALUtil.syncDelete(broker, LogicalDatastoreType.CONFIGURATION, idPoolToBeDeleted);
157 LOG.debug("Deleted id pool {}", poolName);
159 deleteIdPoolRpcBuilder = RpcResultBuilder.success();
161 catch (Exception ex) {
162 LOG.error("Delete id in pool {} failed due to {}", poolName, ex);
163 deleteIdPoolRpcBuilder = RpcResultBuilder.failed();
164 deleteIdPoolRpcBuilder.withError(ErrorType.APPLICATION, ex.getMessage());
166 return Futures.immediateFuture(deleteIdPoolRpcBuilder.build());
170 public Future<RpcResult<Void>> releaseId(ReleaseIdInput input) {
171 String poolName = input.getPoolName();
172 String idKey = input.getIdKey();
173 RpcResultBuilder<Void> releaseIdRpcBuilder;
175 releaseIdFromLocalPool(IdUtils.getLocalPoolName(poolName), idKey);
176 releaseIdRpcBuilder = RpcResultBuilder.success();
177 } catch (Exception ex) {
178 LOG.error("Release id {} from pool {} failed due to {}", idKey, poolName, ex);
179 releaseIdRpcBuilder = RpcResultBuilder.failed();
180 releaseIdRpcBuilder.withError(ErrorType.APPLICATION, ex.getMessage());
182 return Futures.immediateFuture(releaseIdRpcBuilder.build());
185 private long allocateIdFromLocalPool(String localPoolName, String idKey) {
186 long newIdValue = -1;
187 InstanceIdentifier<IdPool> idPoolInstanceIdentifier = IdUtils.getIdPoolInstance(localPoolName);
188 localPoolName = localPoolName.intern();
189 synchronized (localPoolName) {
190 IdEntries newIdEntry;
191 IdPool pool = getIdPool(idPoolInstanceIdentifier);
192 List<IdEntries> idEntries = pool.getIdEntries();
194 AvailableIdsHolderBuilder availableIds = IdUtils.getAvailableIdsHolderBuilder(pool);
195 ReleasedIdsHolderBuilder releasedIds = IdUtils.getReleaseIdsHolderBuilder(pool);
196 //Calling cleanupExcessIds since there could be excessive ids.
197 cleanupExcessIds(availableIds, releasedIds, pool.getParentPoolName(), pool.getBlockSize());
198 if (idEntries == null) {
199 idEntries = new LinkedList<IdEntries>();
201 InstanceIdentifier<IdEntries> existingId = IdUtils.getIdEntry(idPoolInstanceIdentifier, idKey);
202 Optional<IdEntries> existingIdEntry = MDSALUtil.read(broker, LogicalDatastoreType.CONFIGURATION, existingId);
203 if (existingIdEntry.isPresent()) {
204 newIdValue = existingIdEntry.get().getIdValue();
205 LOG.debug("Existing id {} for the key {} ", idKey, newIdValue);
206 InstanceIdentifier<ReleasedIdsHolder> releasedIdsHolderInstanceIdentifier = InstanceIdentifier
207 .builder(IdPools.class).child(IdPool.class, new IdPoolKey(localPoolName)).child(ReleasedIdsHolder.class).build();
208 MDSALUtil.syncWrite(broker, LogicalDatastoreType.CONFIGURATION, releasedIdsHolderInstanceIdentifier, releasedIds.build());
212 newIdValue = getIdFromPool(pool, availableIds, releasedIds);
213 newIdEntry = IdUtils.createIdEntries(idKey, newIdValue);
214 idEntries.add(newIdEntry);
215 pool = new IdPoolBuilder(pool).setIdEntries(idEntries)
216 .setAvailableIdsHolder(availableIds.build()).setReleasedIdsHolder(releasedIds.build()).build();
217 MDSALUtil.syncWrite(broker, LogicalDatastoreType.CONFIGURATION, idPoolInstanceIdentifier, pool);
218 updateChildPool(pool.getParentPoolName(), localPoolName);
223 private long getIdFromPool(IdPool pool, AvailableIdsHolderBuilder availableIds, ReleasedIdsHolderBuilder releasedIds) {
224 long newIdValue = -1;
226 newIdValue = IdUtils.getIdFromReleaseIdsIfAvailable(releasedIds);
227 if (newIdValue != -1) {
228 LOG.debug("Retrieved id value {} from released id holder", newIdValue);
231 newIdValue = IdUtils.getIdFromAvailableIds(availableIds);
232 if (newIdValue != -1) {
233 LOG.debug("Creating a new id {} for the pool: {} ", newIdValue, pool.getPoolName());
236 long idCount = allocateIdBlockFromParentPool(pool.getParentPoolName(), availableIds, releasedIds);
238 LOG.debug("Unable to allocate Id block from global pool");
239 throw new RuntimeException(String.format("Ids exhausted for pool : %s", pool.getPoolName()));
245 * Changes made to releaseIds and AvailableIds are not persisted.
246 * @param availableIds
248 * @param parentPoolName
251 private void cleanupExcessIds(AvailableIdsHolderBuilder availableIds, ReleasedIdsHolderBuilder releasedIds, String parentPoolName, int blockSize) {
252 IdUtils.processDelayList(releasedIds);
253 long totalAvailableIdCount = releasedIds.getAvailableIdCount() + IdUtils.getAvailableIdsCount(availableIds);
254 if (totalAvailableIdCount > blockSize * 2) {
255 parentPoolName = parentPoolName.intern();
256 InstanceIdentifier<ReleasedIdsHolder> releasedIdInstanceIdentifier = IdUtils.getReleasedIdsHolderInstance(parentPoolName);
257 IdUtils.lockPool(lockManager, parentPoolName);
259 Optional<ReleasedIdsHolder> releasedIdsHolder = MDSALUtil.read(broker, LogicalDatastoreType.CONFIGURATION, releasedIdInstanceIdentifier);
260 ReleasedIdsHolderBuilder releasedIdsParent;
261 if (!releasedIdsHolder.isPresent()) {
262 LOG.error("ReleasedIds not present in parent pool. Unable to cleanup excess ids");
265 releasedIdsParent = new ReleasedIdsHolderBuilder(releasedIdsHolder.get());
266 LOG.debug("Releasing excesss Ids from local pool");
267 IdUtils.freeExcessAvailableIds(releasedIds, releasedIdsParent, blockSize);
268 MDSALUtil.syncWrite(broker, LogicalDatastoreType.CONFIGURATION, releasedIdInstanceIdentifier, releasedIdsParent.build());
270 IdUtils.unlockPool(lockManager, parentPoolName);
276 * Changes made to availableIds and releasedIds will not be persisted to the datastore
277 * @param parentPoolName
278 * @param availableIdsBuilder
279 * @param releasedIdsBuilder
282 private long allocateIdBlockFromParentPool(String parentPoolName,
283 AvailableIdsHolderBuilder availableIdsBuilder, ReleasedIdsHolderBuilder releasedIdsBuilder) {
284 LOG.debug("Allocating block of id from parent pool {}", parentPoolName);
285 InstanceIdentifier<IdPool> idPoolInstanceIdentifier = IdUtils.getIdPoolInstance(parentPoolName);
286 parentPoolName = parentPoolName.intern();
288 IdUtils.lockPool(lockManager, parentPoolName);
290 IdPool parentIdPool = getIdPool(idPoolInstanceIdentifier);
291 ReleasedIdsHolderBuilder releasedIdsBuilderParent = IdUtils.getReleaseIdsHolderBuilder(parentIdPool);
293 idCount = allocateIdBlockFromReleasedIdsHolder(releasedIdsBuilder, releasedIdsBuilderParent, parentIdPool);
297 idCount = allocateIdBlockFromAvailableIdsHolder(availableIdsBuilder, parentIdPool);
301 idCount = getIdsFromOtherChildPools(releasedIdsBuilderParent, parentIdPool);
303 LOG.debug("Unable to allocate Id block from global pool");
304 throw new RuntimeException(String.format("Ids exhausted for pool : %s", parentPoolName));
309 IdUtils.unlockPool(lockManager, parentPoolName);
313 private long getIdsFromOtherChildPools(ReleasedIdsHolderBuilder releasedIdsBuilderParent, IdPool parentIdPool) {
314 List<ChildPools> childPoolsList = parentIdPool.getChildPools();
315 // Sorting the child pools on last accessed time so that the pool that was not accessed for a long time comes first.
316 Collections.sort(childPoolsList, new Comparator<ChildPools>() {
318 public int compare(ChildPools childPool1, ChildPools childPool2) {
319 return childPool1.getLastAccessTime().compareTo(childPool2.getLastAccessTime());
322 long currentTime = System.currentTimeMillis() / 1000;
323 for (ChildPools childPools : childPoolsList) {
324 if (childPools.getLastAccessTime() + DEFAULT_IDLE_TIME < currentTime) {
327 if (!childPools.getChildPoolName().equals(IdUtils.getLocalPoolName(parentIdPool.getPoolName()))) {
328 InstanceIdentifier<IdPool> idPoolInstanceIdentifier = IdUtils.getIdPoolInstance(childPools.getChildPoolName());
329 IdPool otherChildPool = getIdPool(idPoolInstanceIdentifier);
330 ReleasedIdsHolderBuilder releasedIds = IdUtils.getReleaseIdsHolderBuilder(otherChildPool);
331 AvailableIdsHolderBuilder availableIds = IdUtils.getAvailableIdsHolderBuilder(otherChildPool);
332 long totalAvailableIdCount = releasedIds.getDelayedIdEntries().size() + IdUtils.getAvailableIdsCount(availableIds);
333 List<DelayedIdEntries> delayedIdEntriesChild = releasedIds.getDelayedIdEntries();
334 List<DelayedIdEntries> delayedIdEntriesParent = releasedIdsBuilderParent.getDelayedIdEntries();
335 if (delayedIdEntriesParent == null) {
336 delayedIdEntriesParent = new LinkedList<>();
338 delayedIdEntriesParent.addAll(delayedIdEntriesChild);
339 delayedIdEntriesChild.removeAll(delayedIdEntriesChild);
340 while (IdUtils.isIdAvailable(availableIds)) {
341 long cursor = availableIds.getCursor() + 1;
342 delayedIdEntriesParent.add(new DelayedIdEntriesBuilder().setId(cursor).setReadyTimeSec(System.currentTimeMillis()).build());
343 availableIds.setCursor(cursor);
345 long count = releasedIdsBuilderParent.getAvailableIdCount() + totalAvailableIdCount;
346 releasedIdsBuilderParent.setDelayedIdEntries(delayedIdEntriesParent).setAvailableIdCount(count);
347 MDSALUtil.syncWrite(broker, LogicalDatastoreType.CONFIGURATION, idPoolInstanceIdentifier,
348 new IdPoolBuilder(otherChildPool).setAvailableIdsHolder(availableIds.build()).setReleasedIdsHolder(releasedIds.build()).build());
349 return totalAvailableIdCount;
355 private long allocateIdBlockFromReleasedIdsHolder(ReleasedIdsHolderBuilder releasedIdsBuilderChild, ReleasedIdsHolderBuilder releasedIdsBuilderParent, IdPool parentIdPool) {
356 if (releasedIdsBuilderParent.getAvailableIdCount() == 0) {
357 LOG.debug("Ids unavailable in releasedIds of parent pool {}", parentIdPool);
360 List<DelayedIdEntries> delayedIdEntriesParent = releasedIdsBuilderParent.getDelayedIdEntries();
361 List<DelayedIdEntries> delayedIdEntriesChild = releasedIdsBuilderChild.getDelayedIdEntries();
362 if (delayedIdEntriesChild == null) {
363 delayedIdEntriesChild = new LinkedList<DelayedIdEntries>();
365 int idCount = Math.min(delayedIdEntriesParent.size(), parentIdPool.getBlockSize());
366 List<DelayedIdEntries> idEntriesToBeRemoved = delayedIdEntriesParent.subList(0, idCount);
367 delayedIdEntriesChild.addAll(0, idEntriesToBeRemoved);
368 delayedIdEntriesParent.removeAll(idEntriesToBeRemoved);
369 releasedIdsBuilderParent.setDelayedIdEntries(delayedIdEntriesParent);
370 releasedIdsBuilderChild.setDelayedIdEntries(delayedIdEntriesChild);
371 releasedIdsBuilderChild.setAvailableIdCount(releasedIdsBuilderChild.getAvailableIdCount() + idCount);
372 InstanceIdentifier<ReleasedIdsHolder> releasedIdsHolderInstanceIdentifier = InstanceIdentifier
373 .builder(IdPools.class).child(IdPool.class,
374 new IdPoolKey(parentIdPool.getPoolName())).child(ReleasedIdsHolder.class).build();
375 releasedIdsBuilderParent.setAvailableIdCount(releasedIdsBuilderParent.getAvailableIdCount() - idCount);
376 LOG.debug("Allocated {} ids from releasedIds of parent pool {}", idCount, parentIdPool);
377 MDSALUtil.syncUpdate(broker, LogicalDatastoreType.CONFIGURATION, releasedIdsHolderInstanceIdentifier, releasedIdsBuilderParent.build());
381 private long allocateIdBlockFromAvailableIdsHolder(AvailableIdsHolderBuilder availableIdsBuilder, IdPool parentIdPool) {
383 AvailableIdsHolderBuilder availableIdsBuilderParent = IdUtils.getAvailableIdsHolderBuilder(parentIdPool);
384 long end = availableIdsBuilderParent.getEnd();
385 long cur = availableIdsBuilderParent.getCursor();
386 if (!IdUtils.isIdAvailable(availableIdsBuilderParent)) {
387 LOG.debug("Ids exhausted in parent pool {}", parentIdPool);
390 // Update availableIdsHolder of Local Pool
391 availableIdsBuilder.setStart(cur + 1);
392 idCount = Math.min(end - cur, parentIdPool.getBlockSize());
393 availableIdsBuilder.setEnd(cur + idCount);
394 availableIdsBuilder.setCursor(cur);
395 // Update availableIdsHolder of Global Pool
396 InstanceIdentifier<AvailableIdsHolder> availableIdsHolderInstanceIdentifier = InstanceIdentifier
397 .builder(IdPools.class).child(IdPool.class,
398 new IdPoolKey(parentIdPool.getPoolName())).child(AvailableIdsHolder.class).build();
399 availableIdsBuilderParent.setCursor(cur + idCount);
400 LOG.debug("Allocated {} ids from availableIds of global pool {}", idCount, parentIdPool);
401 MDSALUtil.syncUpdate(broker, LogicalDatastoreType.CONFIGURATION, availableIdsHolderInstanceIdentifier, availableIdsBuilderParent.build());
405 private void releaseIdFromLocalPool(String poolName, String idKey) {
406 InstanceIdentifier<IdPool> idPoolInstanceIdentifier = IdUtils.getIdPoolInstance(poolName);
407 poolName = poolName.intern();
408 synchronized (poolName) {
409 IdPool pool = getIdPool(idPoolInstanceIdentifier);
410 List<IdEntries> idEntries = pool.getIdEntries();
411 List<IdEntries> newIdEntries = idEntries;
412 if (idEntries == null) {
413 throw new RuntimeException("Id Entries does not exist");
415 InstanceIdentifier<IdEntries> existingId = IdUtils.getIdEntry(idPoolInstanceIdentifier, idKey);
416 Optional<IdEntries> existingIdEntryObject = MDSALUtil.read(broker, LogicalDatastoreType.CONFIGURATION, existingId);
417 if (!existingIdEntryObject.isPresent()) {
418 throw new RuntimeException(String.format("Specified Id key %s does not exist in id pool %s", idKey, poolName));
420 IdEntries existingIdEntry = existingIdEntryObject.get();
421 long idValue = existingIdEntry.getIdValue();
422 newIdEntries.remove(existingIdEntry);
423 ReleasedIdsHolderBuilder releasedIds = IdUtils.getReleaseIdsHolderBuilder(pool);
424 AvailableIdsHolderBuilder availableIds = IdUtils.getAvailableIdsHolderBuilder(pool);
425 long delayTime = System.currentTimeMillis() / 1000 + releasedIds.getDelayedTimeSec();
426 DelayedIdEntries delayedIdEntry = IdUtils.createDelayedIdEntry(idValue, delayTime);
427 List<DelayedIdEntries> delayedIdEntries = releasedIds.getDelayedIdEntries();
428 if (delayedIdEntries == null) {
429 delayedIdEntries = new LinkedList<DelayedIdEntries>();
431 delayedIdEntries.add(delayedIdEntry);
432 long availableIdCount = releasedIds
433 .getAvailableIdCount() == null ? 0
434 : releasedIds.getAvailableIdCount();
435 releasedIds.setDelayedIdEntries(delayedIdEntries);
436 releasedIds.setAvailableIdCount(availableIdCount);
437 //Calling cleanupExcessIds since there could be excessive ids.
438 cleanupExcessIds(availableIds, releasedIds, pool.getParentPoolName(), pool.getBlockSize());
439 pool = new IdPoolBuilder(pool).setIdEntries(newIdEntries)
440 .setAvailableIdsHolder(availableIds.build())
441 .setReleasedIdsHolder(releasedIds.build()).build();
442 MDSALUtil.syncWrite(broker, LogicalDatastoreType.CONFIGURATION, idPoolInstanceIdentifier, pool);
443 LOG.debug("Released id ({}, {}) from pool {}", idKey, idValue, poolName);
447 private IdPool createGlobalPool(String poolName, long low, long high,
448 long blockSize, InstanceIdentifier<IdPool> idPoolInstanceIdentifier) {
450 Optional<IdPool> existingIdPool = MDSALUtil.read(broker, LogicalDatastoreType.CONFIGURATION, idPoolInstanceIdentifier);
451 if (!existingIdPool.isPresent()) {
452 LOG.debug("Creating new global pool {}", poolName);
453 idPool = IdUtils.createGlobalPool(poolName, low, high, blockSize);
454 MDSALUtil.syncWrite(broker, LogicalDatastoreType.CONFIGURATION, idPoolInstanceIdentifier, idPool);
457 idPool = existingIdPool.get();
458 LOG.debug("GlobalPool exists {}", idPool);
463 private boolean createLocalPool(String localPoolName, IdPool idPool) {
464 localPoolName = localPoolName.intern();
465 synchronized (localPoolName) {
466 InstanceIdentifier<IdPool> localIdPoolInstanceIdentifier = IdUtils.getIdPoolInstance(localPoolName);
467 Optional<IdPool> localIdPool = MDSALUtil.read(broker, LogicalDatastoreType.CONFIGURATION, localIdPoolInstanceIdentifier);
468 if (!localIdPool.isPresent()) {
469 LOG.debug("Creating new local pool");
470 IdPool newLocalIdPool = IdUtils.createLocalIdPool(localPoolName, idPool);
471 MDSALUtil.syncWrite(broker, LogicalDatastoreType.CONFIGURATION, localIdPoolInstanceIdentifier, newLocalIdPool);
472 LOG.debug("Local pool created {}", newLocalIdPool);
479 private void deletePool(String poolName) {
480 InstanceIdentifier<IdPool> idPoolToBeDeleted = IdUtils.getIdPoolInstance(poolName);
481 synchronized (poolName) {
482 Optional<IdPool> idPool = MDSALUtil.read(broker, LogicalDatastoreType.CONFIGURATION, idPoolToBeDeleted);
483 if (idPool.isPresent()) {
484 MDSALUtil.syncDelete(broker, LogicalDatastoreType.CONFIGURATION, idPoolToBeDeleted);
485 LOG.debug("Deleted local pool {}", poolName);
490 private IdPool getIdPool(InstanceIdentifier<IdPool> idPoolInstanceIdentifier) {
491 Optional<IdPool> idPool = MDSALUtil.read(broker, LogicalDatastoreType.CONFIGURATION, idPoolInstanceIdentifier);
492 if (!idPool.isPresent()) {
493 throw new RuntimeException(String.format("Specified pool %s does not exist" , idPool));
498 private void updateChildPool(String poolName, String localPoolName) {
499 ChildPools childPool = IdUtils.createChildPool(localPoolName);
500 InstanceIdentifier<ChildPools> childPoolInstanceIdentifier = IdUtils.getChildPoolsInstanceIdentifier(poolName, localPoolName);
501 MDSALUtil.syncUpdate(broker, LogicalDatastoreType.CONFIGURATION, childPoolInstanceIdentifier, childPool);