2 * Copyright (c) 2016 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.genius.idmanager;
11 import com.google.common.net.InetAddresses;
12 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.idmanager.rev160406.DelayedIdEntry;
13 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.idmanager.rev160406.IdPools;
14 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.idmanager.rev160406.id.pools.IdPool;
15 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.idmanager.rev160406.id.pools.IdPoolBuilder;
16 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.idmanager.rev160406.id.pools.IdPoolKey;
17 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.idmanager.rev160406.id.pools.id.pool.*;
18 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.idmanager.rev160406.released.ids.DelayedIdEntries;
19 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.idmanager.rev160406.released.ids.DelayedIdEntriesBuilder;
20 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.lockmanager.rev160413.*;
21 import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
22 import org.opendaylight.yangtools.yang.common.RpcResult;
23 import org.slf4j.Logger;
24 import org.slf4j.LoggerFactory;
26 import java.net.InetAddress;
27 import java.util.LinkedList;
28 import java.util.List;
29 import java.util.concurrent.ExecutionException;
30 import java.util.concurrent.Future;
34 private static final Logger LOGGER = LoggerFactory.getLogger(IdUtils.class);
35 private static final long DEFAULT_DELAY_TIME = 30;
36 private static final long DEFAULT_AVAILABLE_ID_COUNT = 0;
37 private static final int DEFAULT_BLOCK_SIZE_DIFF = 50;
39 private static int BLADE_ID;
42 BLADE_ID = InetAddresses.coerceToInteger(InetAddress.getLocalHost());
43 } catch (Exception e) {
44 LOGGER.error("IdManager - Exception - {}", e.getMessage());
48 protected static InstanceIdentifier<IdEntries> getIdEntry(InstanceIdentifier<IdPool> poolName, String idKey) {
49 InstanceIdentifier.InstanceIdentifierBuilder<IdEntries> idEntriesBuilder = poolName
50 .builder().child(IdEntries.class, new IdEntriesKey(idKey));
51 InstanceIdentifier<IdEntries> idEntry = idEntriesBuilder.build();
55 protected static IdEntries createIdEntries(String idKey, List<Long> newIdVals) {
56 return new IdEntriesBuilder().setKey(new IdEntriesKey(idKey))
57 .setIdKey(idKey).setIdValue(newIdVals).build();
60 protected static DelayedIdEntries createDelayedIdEntry(long idValue, long delayTime) {
61 return new DelayedIdEntriesBuilder()
63 .setReadyTimeSec(delayTime).build();
66 protected static IdPool createGlobalPool(String poolName, long low, long high, long blockSize) {
67 AvailableIdsHolder availableIdsHolder = createAvailableIdsHolder(low, high, low - 1);
68 ReleasedIdsHolder releasedIdsHolder = createReleasedIdsHolder(DEFAULT_AVAILABLE_ID_COUNT, 0);
69 int size = (int) blockSize;
70 return new IdPoolBuilder().setKey(new IdPoolKey(poolName))
71 .setBlockSize(size).setPoolName(poolName)
72 .setAvailableIdsHolder(availableIdsHolder)
73 .setReleasedIdsHolder(releasedIdsHolder).build();
76 protected static AvailableIdsHolder createAvailableIdsHolder(long low, long high, long cursor) {
77 AvailableIdsHolder availableIdsHolder = new AvailableIdsHolderBuilder()
78 .setStart(low).setEnd(high).setCursor(cursor).build();
79 return availableIdsHolder;
82 protected static ReleasedIdsHolder createReleasedIdsHolder(long availableIdCount, long delayTime) {
83 ReleasedIdsHolder releasedIdsHolder = new ReleasedIdsHolderBuilder()
84 .setAvailableIdCount(availableIdCount)
85 .setDelayedTimeSec(delayTime).build();
86 return releasedIdsHolder;
89 protected static InstanceIdentifier<IdPool> getIdPoolInstance(String poolName) {
90 InstanceIdentifier.InstanceIdentifierBuilder<IdPool> idPoolBuilder = InstanceIdentifier
91 .builder(IdPools.class).child(IdPool.class,
92 new IdPoolKey(poolName));
93 InstanceIdentifier<IdPool> id = idPoolBuilder.build();
97 protected static InstanceIdentifier<ReleasedIdsHolder> getReleasedIdsHolderInstance(String poolName) {
98 InstanceIdentifier.InstanceIdentifierBuilder<ReleasedIdsHolder> releasedIdsHolder = InstanceIdentifier
99 .builder(IdPools.class).child(IdPool.class,
100 new IdPoolKey(poolName)).child(ReleasedIdsHolder.class);
101 InstanceIdentifier<ReleasedIdsHolder> releasedIds = releasedIdsHolder.build();
106 * Changes made to releasedIds are not persisted in the datastore.
110 protected static long getIdFromReleaseIdsIfAvailable(ReleasedIdsHolderBuilder releasedIds) {
111 List<DelayedIdEntries> delayedIdEntries = releasedIds.getDelayedIdEntries();
112 long newIdValue = -1;
113 if (delayedIdEntries != null && !delayedIdEntries.isEmpty()) {
114 processDelayList(releasedIds);
115 if (releasedIds.getAvailableIdCount() > 0) {
116 DelayedIdEntries delayedIdEntry= delayedIdEntries.get(0);
117 newIdValue = delayedIdEntry.getId();
118 delayedIdEntries.remove(delayedIdEntry);
119 releasedIds.setDelayedIdEntries(delayedIdEntries);
120 releasedIds.setAvailableIdCount(releasedIds.getAvailableIdCount() - 1);
127 * Changes made to availableIds are not persisted to datastore.
128 * @param availableIds
131 protected static long getIdFromAvailableIds(AvailableIdsHolderBuilder availableIds) {
132 long newIdValue = -1;
133 if (availableIds != null && isIdAvailable(availableIds)) {
134 newIdValue = availableIds.getCursor() + 1;
135 availableIds.setCursor(newIdValue);
140 protected static boolean isIdAvailable(AvailableIdsHolderBuilder availableIds) {
141 if (availableIds.getCursor() != null && availableIds.getEnd() != null)
142 return availableIds.getCursor() < availableIds.getEnd();
146 protected static String getLocalPoolName(String poolName) {
147 return (poolName + "." + BLADE_ID);
150 protected static IdPool createLocalIdPool(String localPoolName, IdPool parentIdPool) {
151 IdPoolBuilder idPoolBuilder = new IdPoolBuilder();
152 ReleasedIdsHolder releasedIdsHolder = createReleasedIdsHolder(DEFAULT_AVAILABLE_ID_COUNT, DEFAULT_DELAY_TIME);
153 return idPoolBuilder.setKey(new IdPoolKey(localPoolName))
154 .setPoolName(localPoolName)
155 .setParentPoolName(parentIdPool.getPoolName())
156 .setBlockSize(parentIdPool.getBlockSize())
157 .setReleasedIdsHolder(releasedIdsHolder).build();
160 protected static ChildPools createChildPool(String childPoolName) {
161 return new ChildPoolsBuilder().setKey(new ChildPoolsKey(childPoolName)).setChildPoolName(childPoolName).setLastAccessTime(System.currentTimeMillis() / 1000).build();
164 protected static AvailableIdsHolderBuilder getAvailableIdsHolderBuilder(IdPool pool) {
165 AvailableIdsHolder availableIds = pool.getAvailableIdsHolder();
166 if (availableIds != null )
167 return new AvailableIdsHolderBuilder(availableIds);
168 return new AvailableIdsHolderBuilder();
171 protected static ReleasedIdsHolderBuilder getReleaseIdsHolderBuilder(IdPool pool) {
172 ReleasedIdsHolder releasedIds = pool.getReleasedIdsHolder();
173 if (releasedIds != null)
174 return new ReleasedIdsHolderBuilder(releasedIds);
175 return new ReleasedIdsHolderBuilder();
179 * Changes made to releaseIds are not persisted to the Datastore. Method invoking should ensure that releaseIds gets persisted.
182 protected static void processDelayList(ReleasedIdsHolderBuilder releasedIds) {
183 List<DelayedIdEntries> delayedIdEntries = releasedIds.getDelayedIdEntries();
184 if (delayedIdEntries == null)
186 long availableIdCount = releasedIds.getAvailableIdCount() == null ? 0 : releasedIds.getAvailableIdCount();
187 int index = (int) availableIdCount;
188 long currentTimeSec = System.currentTimeMillis() / 1000;
189 DelayedIdEntry delayedIdEntry;
190 while (index < delayedIdEntries.size()) {
191 delayedIdEntry = delayedIdEntries.get(index);
192 if (delayedIdEntry.getReadyTimeSec() > currentTimeSec) {
198 releasedIds.setAvailableIdCount(availableIdCount);
202 * Changes made to the parameters passed are not persisted to the Datastore. Method invoking should ensure that these gets persisted.
203 * @param releasedIdsChild
204 * @param releasedIdsParent
205 * @param idCountToBeFreed
207 protected static void freeExcessAvailableIds(ReleasedIdsHolderBuilder releasedIdsChild, ReleasedIdsHolderBuilder releasedIdsParent, int idCountToBeFreed) {
208 List<DelayedIdEntries> existingDelayedIdEntriesInParent = releasedIdsParent.getDelayedIdEntries();
209 List<DelayedIdEntries> delayedIdEntriesChild = releasedIdsChild.getDelayedIdEntries();
210 long availableIdCountParent = releasedIdsParent.getAvailableIdCount();
211 long availableIdCountChild = releasedIdsChild.getAvailableIdCount();
212 if (existingDelayedIdEntriesInParent == null) {
213 existingDelayedIdEntriesInParent = new LinkedList<>();
215 idCountToBeFreed = Math.min(idCountToBeFreed, delayedIdEntriesChild.size());
216 for (int index = 0; index < idCountToBeFreed; index++) {
217 existingDelayedIdEntriesInParent.add(delayedIdEntriesChild.get(0));
218 delayedIdEntriesChild.remove(0);
220 releasedIdsChild.setDelayedIdEntries(delayedIdEntriesChild).setAvailableIdCount(availableIdCountChild - idCountToBeFreed);
221 releasedIdsParent.setDelayedIdEntries(existingDelayedIdEntriesInParent).setAvailableIdCount(availableIdCountParent + idCountToBeFreed);
224 protected static InstanceIdentifier<IdEntries> getIdEntriesInstanceIdentifier(String poolName, String idKey) {
225 InstanceIdentifier<IdEntries> idEntries = InstanceIdentifier
226 .builder(IdPools.class).child(IdPool.class,
227 new IdPoolKey(poolName)).child(IdEntries.class, new IdEntriesKey(idKey)).build();
231 protected static InstanceIdentifier<ChildPools> getChildPoolsInstanceIdentifier(String poolName, String localPoolName) {
232 InstanceIdentifier<ChildPools> childPools = InstanceIdentifier
233 .builder(IdPools.class)
234 .child(IdPool.class, new IdPoolKey(poolName))
235 .child(ChildPools.class, new ChildPoolsKey(localPoolName)).build();
239 protected static long computeBlockSize(long low, long high) {
242 long diff = high - low;
243 if (diff > DEFAULT_BLOCK_SIZE_DIFF) {
244 blockSize = diff / DEFAULT_BLOCK_SIZE_DIFF;
251 public static long getAvailableIdsCount(AvailableIdsHolderBuilder availableIds) {
252 if(availableIds != null && isIdAvailable(availableIds)) {
253 return availableIds.getEnd() - availableIds.getCursor();
258 public static void lockPool(LockManagerService lockManager, String poolName) {
259 LockInput input = new LockInputBuilder().setLockName(poolName).build();
260 Future<RpcResult<Void>> result = lockManager.lock(input);
262 if ((result != null) && (result.get().isSuccessful())) {
263 if (LOGGER.isDebugEnabled()) {
264 LOGGER.debug("Acquired lock {}", poolName);
267 throw new RuntimeException(String.format("Unable to getLock for pool %s", poolName));
269 } catch (InterruptedException | ExecutionException e) {
270 LOGGER.error("Unable to getLock for pool {}", poolName);
271 throw new RuntimeException(String.format("Unable to getLock for pool %s", poolName), e.getCause());
275 public static void unlockPool(LockManagerService lockManager, String poolName) {
276 UnlockInput input = new UnlockInputBuilder().setLockName(poolName).build();
277 Future<RpcResult<Void>> result = lockManager.unlock(input);
279 if ((result != null) && (result.get().isSuccessful())) {
280 if (LOGGER.isDebugEnabled()) {
281 LOGGER.debug("Unlocked {}", poolName);
284 if (LOGGER.isDebugEnabled()) {
285 LOGGER.debug("Unable to unlock pool {}", poolName);
288 } catch (InterruptedException | ExecutionException e) {
289 LOGGER.error("Unable to unlock for pool {}", poolName);
290 throw new RuntimeException(String.format("Unable to unlock pool %s", poolName), e.getCause());