+ RpcResultBuilder<Void> releaseIdRpcBuilder;
+ try {
+ releaseIdFromLocalPool(IdUtils.getLocalPoolName(poolName), idKey);
+ releaseIdRpcBuilder = RpcResultBuilder.success();
+ } catch (Exception ex) {
+ LOG.error("Release id {} from pool {} failed due to {}", idKey, poolName, ex);
+ releaseIdRpcBuilder = RpcResultBuilder.failed();
+ releaseIdRpcBuilder.withError(ErrorType.APPLICATION, ex.getMessage());
+ }
+ return Futures.immediateFuture(releaseIdRpcBuilder.build());
+ }
+
+ private long allocateIdFromLocalPool(String parentPoolName, String localPoolName, String idKey) {
+ LOG.trace("Allocating id from local pool {}. Parent pool {}. Idkey {}", localPoolName, parentPoolName, idKey);
+ long newIdValue = -1;
+ InstanceIdentifier<IdPool> localIdPoolInstanceIdentifier = IdUtils.getIdPoolInstance(localPoolName);
+ localPoolName = localPoolName.intern();
+ synchronized (localPoolName) {
+ InstanceIdentifier<IdPool> parentIdPoolInstanceIdentifier = IdUtils.getIdPoolInstance(parentPoolName);
+ IdPool parentIdPool = getIdPool(parentIdPoolInstanceIdentifier);
+ IdPool localPool = null;
+ try {
+ localPool = getIdPool(localIdPoolInstanceIdentifier);
+ } catch (NoSuchElementException e){
+ LOG.trace("Creating local pool {} since it was not present", localPoolName);
+ localPool = IdUtils.createLocalIdPool(localPoolName, parentIdPool);
+ MDSALUtil.syncWrite(broker, LogicalDatastoreType.CONFIGURATION, localIdPoolInstanceIdentifier, localPool);
+ IdUtils.lockPool(lockManager, parentPoolName);
+ try {
+ updateChildPool(parentPoolName, localPoolName);
+ } finally {
+ IdUtils.unlockPool(lockManager, parentPoolName);
+ }
+ LOG.debug("Updating global id pool {} with childPool {}", parentPoolName, localPoolName);
+ }
+ IdEntries newIdEntry;
+ List<IdEntries> idEntries = parentIdPool.getIdEntries();
+ AvailableIdsHolderBuilder availableIds = IdUtils.getAvailableIdsHolderBuilder(localPool);
+ ReleasedIdsHolderBuilder releasedIds = IdUtils.getReleaseIdsHolderBuilder(localPool);
+ //Calling cleanupExcessIds since there could be excessive ids.
+ cleanupExcessIds(availableIds, releasedIds, parentPoolName, localPool.getBlockSize());
+ if (idEntries == null) {
+ idEntries = new LinkedList<IdEntries>();
+ } else {
+ InstanceIdentifier<IdEntries> existingId = IdUtils.getIdEntry(parentIdPoolInstanceIdentifier, idKey);
+ Optional<IdEntries> existingIdEntry = MDSALUtil.read(broker, LogicalDatastoreType.CONFIGURATION, existingId);
+ if (existingIdEntry.isPresent()) {
+ newIdValue = existingIdEntry.get().getIdValue();
+ LOG.debug("Existing id {} for the key {} ", idKey, newIdValue);
+ InstanceIdentifier<ReleasedIdsHolder> releasedIdsHolderInstanceIdentifier = InstanceIdentifier
+ .builder(IdPools.class).child(IdPool.class, new IdPoolKey(localPoolName)).child(ReleasedIdsHolder.class).build();
+ MDSALUtil.syncWrite(broker, LogicalDatastoreType.CONFIGURATION, releasedIdsHolderInstanceIdentifier, releasedIds.build());
+ return newIdValue;
+ }
+ }
+ newIdValue = getIdFromPool(localPool, availableIds, releasedIds);
+ LOG.debug("The newIdValue {} for the idKey {}", newIdValue, idKey);
+ newIdEntry = IdUtils.createIdEntries(idKey, newIdValue);
+ idEntries.add(newIdEntry);
+ LOG.debug("The availablelIds are {}", availableIds.build());
+ localPool = new IdPoolBuilder(localPool).setAvailableIdsHolder(availableIds.build())
+ .setReleasedIdsHolder(releasedIds.build()).build();
+ MDSALUtil.syncWrite(broker, LogicalDatastoreType.CONFIGURATION, localIdPoolInstanceIdentifier, localPool);
+ updateChildPool(localPool.getParentPoolName(), localPoolName);
+ //Updating id entries in the parent pool. This will be used for restart scenario
+ IdUtils.lockPool(lockManager, parentPoolName);
+ try {
+ parentIdPool = getIdPool(parentIdPoolInstanceIdentifier);
+ IdPool parentPool = new IdPoolBuilder(parentIdPool).setIdEntries(idEntries).build();
+ MDSALUtil.syncWrite(broker, LogicalDatastoreType.CONFIGURATION, parentIdPoolInstanceIdentifier, parentPool);
+ } catch (Exception ex) {
+ LOG.error("Saving of Id entries to parent pool {} failed due to {}", parentPoolName, ex);
+ } finally {
+ IdUtils.unlockPool(lockManager, parentPoolName);
+ }
+ }
+ return newIdValue;
+ }