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.net.InetAddress;
12 import java.util.LinkedList;
13 import java.util.List;
14 import java.util.concurrent.ExecutionException;
15 import java.util.concurrent.Future;
17 import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.idmanager.rev150403.DelayedIdEntry;
18 import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.idmanager.rev150403.IdPools;
19 import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.idmanager.rev150403.id.pools.IdPool;
20 import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.idmanager.rev150403.id.pools.IdPoolBuilder;
21 import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.idmanager.rev150403.id.pools.IdPoolKey;
22 import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.idmanager.rev150403.id.pools.id.pool.AvailableIdsHolder;
23 import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.idmanager.rev150403.id.pools.id.pool.AvailableIdsHolderBuilder;
24 import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.idmanager.rev150403.id.pools.id.pool.ChildPools;
25 import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.idmanager.rev150403.id.pools.id.pool.ChildPoolsBuilder;
26 import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.idmanager.rev150403.id.pools.id.pool.ChildPoolsKey;
27 import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.idmanager.rev150403.id.pools.id.pool.IdEntries;
28 import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.idmanager.rev150403.id.pools.id.pool.IdEntriesBuilder;
29 import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.idmanager.rev150403.id.pools.id.pool.IdEntriesKey;
30 import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.idmanager.rev150403.id.pools.id.pool.ReleasedIdsHolder;
31 import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.idmanager.rev150403.id.pools.id.pool.ReleasedIdsHolderBuilder;
32 import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.idmanager.rev150403.released.ids.DelayedIdEntries;
33 import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.idmanager.rev150403.released.ids.DelayedIdEntriesBuilder;
34 import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.lockmanager.rev150819.LockInput;
35 import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.lockmanager.rev150819.LockInputBuilder;
36 import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.lockmanager.rev150819.LockManagerService;
37 import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.lockmanager.rev150819.UnlockInput;
38 import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.lockmanager.rev150819.UnlockInputBuilder;
39 import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
40 import org.opendaylight.yangtools.yang.common.RpcResult;
41 import org.slf4j.Logger;
42 import org.slf4j.LoggerFactory;
44 import com.google.common.net.InetAddresses;
48 private static final Logger LOGGER = LoggerFactory.getLogger(IdUtils.class);
49 private static final long DEFAULT_DELAY_TIME = 30;
50 private static final long DEFAULT_AVAILABLE_ID_COUNT = 0;
51 private static final int DEFAULT_BLOCK_SIZE_DIFF = 50;
53 private static int BLADE_ID;
57 hostName = InetAddress.getLocalHost().getHostName();
58 BLADE_ID = InetAddresses.coerceToInteger(InetAddress.getLocalHost());
59 if (hostName.indexOf("-") > 0) {
60 BLADE_ID = new Integer(hostName.split("-")[1].toString()).intValue();
62 LOGGER.error("Host name {} is not matching with the condition!! PL-X is expected", hostName);
64 } catch (Exception e) {
65 LOGGER.error("IdManager - Exception - {}", e.getMessage());
69 protected static InstanceIdentifier<IdEntries> getIdEntry(InstanceIdentifier<IdPool> poolName, String idKey) {
70 InstanceIdentifier.InstanceIdentifierBuilder<IdEntries> idEntriesBuilder = poolName
71 .builder().child(IdEntries.class, new IdEntriesKey(idKey));
72 InstanceIdentifier<IdEntries> idEntry = idEntriesBuilder.build();
76 protected static IdEntries createIdEntries(String idKey, long newIdVal) {
77 return new IdEntriesBuilder().setKey(new IdEntriesKey(idKey))
78 .setIdKey(idKey).setIdValue(newIdVal).build();
81 protected static DelayedIdEntries createDelayedIdEntry(long idValue, long delayTime) {
82 return new DelayedIdEntriesBuilder()
84 .setReadyTimeSec(delayTime).build();
87 protected static IdPool createGlobalPool(String poolName, long low, long high, long blockSize) {
88 AvailableIdsHolder availableIdsHolder = createAvailableIdsHolder(low, high, low - 1);
89 ReleasedIdsHolder releasedIdsHolder = createReleasedIdsHolder(DEFAULT_AVAILABLE_ID_COUNT, 0);
90 int size = (int) blockSize;
91 return new IdPoolBuilder().setKey(new IdPoolKey(poolName))
92 .setBlockSize(size).setPoolName(poolName)
93 .setAvailableIdsHolder(availableIdsHolder)
94 .setReleasedIdsHolder(releasedIdsHolder).build();
97 protected static AvailableIdsHolder createAvailableIdsHolder(long low, long high, long cursor) {
98 AvailableIdsHolder availableIdsHolder = new AvailableIdsHolderBuilder()
99 .setStart(low).setEnd(high).setCursor(cursor).build();
100 return availableIdsHolder;
103 protected static ReleasedIdsHolder createReleasedIdsHolder(long availableIdCount, long delayTime) {
104 ReleasedIdsHolder releasedIdsHolder = new ReleasedIdsHolderBuilder()
105 .setAvailableIdCount(availableIdCount)
106 .setDelayedTimeSec(delayTime).build();
107 return releasedIdsHolder;
110 protected static InstanceIdentifier<IdPool> getIdPoolInstance(String poolName) {
111 InstanceIdentifier.InstanceIdentifierBuilder<IdPool> idPoolBuilder = InstanceIdentifier
112 .builder(IdPools.class).child(IdPool.class,
113 new IdPoolKey(poolName));
114 InstanceIdentifier<IdPool> id = idPoolBuilder.build();
118 protected static InstanceIdentifier<ReleasedIdsHolder> getReleasedIdsHolderInstance(String poolName) {
119 InstanceIdentifier.InstanceIdentifierBuilder<ReleasedIdsHolder> releasedIdsHolder = InstanceIdentifier
120 .builder(IdPools.class).child(IdPool.class,
121 new IdPoolKey(poolName)).child(ReleasedIdsHolder.class);
122 InstanceIdentifier<ReleasedIdsHolder> releasedIds = releasedIdsHolder.build();
127 * Changes made to releasedIds are not persisted in the datastore.
131 protected static long getIdFromReleaseIdsIfAvailable(ReleasedIdsHolderBuilder releasedIds) {
132 List<DelayedIdEntries> delayedIdEntries = releasedIds.getDelayedIdEntries();
133 long newIdValue = -1;
134 if (delayedIdEntries != null && !delayedIdEntries.isEmpty()) {
135 processDelayList(releasedIds);
136 if (releasedIds.getAvailableIdCount() > 0) {
137 DelayedIdEntries delayedIdEntry= delayedIdEntries.get(0);
138 newIdValue = delayedIdEntry.getId();
139 delayedIdEntries.remove(delayedIdEntry);
140 releasedIds.setDelayedIdEntries(delayedIdEntries);
141 releasedIds.setAvailableIdCount(releasedIds.getAvailableIdCount() - 1);
148 * Changes made to availableIds are not persisted to datastore.
149 * @param availableIds
152 protected static long getIdFromAvailableIds(AvailableIdsHolderBuilder availableIds) {
153 long newIdValue = -1;
154 if (availableIds != null && isIdAvailable(availableIds)) {
155 newIdValue = availableIds.getCursor() + 1;
156 availableIds.setCursor(newIdValue);
161 protected static boolean isIdAvailable(AvailableIdsHolderBuilder availableIds) {
162 if (availableIds.getCursor() != null && availableIds.getEnd() != null)
163 return availableIds.getCursor() < availableIds.getEnd();
167 protected static String getLocalPoolName(String poolName) {
168 return (poolName + "." + BLADE_ID);
171 protected static IdPool createLocalIdPool(String localPoolName, IdPool parentIdPool) {
172 ReleasedIdsHolder releasedIdsHolder = createReleasedIdsHolder(DEFAULT_AVAILABLE_ID_COUNT, DEFAULT_DELAY_TIME);
173 return new IdPoolBuilder().setKey(new IdPoolKey(localPoolName))
174 .setPoolName(localPoolName)
175 .setParentPoolName(parentIdPool.getPoolName())
176 .setBlockSize(parentIdPool.getBlockSize())
177 .setReleasedIdsHolder(releasedIdsHolder).build();
180 protected static ChildPools createChildPool(String childPoolName) {
181 return new ChildPoolsBuilder().setKey(new ChildPoolsKey(childPoolName)).setChildPoolName(childPoolName).setLastAccessTime(System.currentTimeMillis() / 1000).build();
184 protected static AvailableIdsHolderBuilder getAvailableIdsHolderBuilder(IdPool pool) {
185 AvailableIdsHolder availableIds = pool.getAvailableIdsHolder();
186 if (availableIds != null )
187 return new AvailableIdsHolderBuilder(availableIds);
188 return new AvailableIdsHolderBuilder();
191 protected static ReleasedIdsHolderBuilder getReleaseIdsHolderBuilder(IdPool pool) {
192 ReleasedIdsHolder releasedIds = pool.getReleasedIdsHolder();
193 if (releasedIds != null)
194 return new ReleasedIdsHolderBuilder(releasedIds);
195 return new ReleasedIdsHolderBuilder();
199 * Changes made to releaseIds are not persisted to the Datastore. Method invoking should ensure that releaseIds gets persisted.
202 protected static void processDelayList(ReleasedIdsHolderBuilder releasedIds) {
203 List<DelayedIdEntries> delayedIdEntries = releasedIds.getDelayedIdEntries();
204 if (delayedIdEntries == null)
206 long availableIdCount = releasedIds.getAvailableIdCount() == null ? 0 : releasedIds.getAvailableIdCount();
207 int index = (int) availableIdCount;
208 long currentTimeSec = System.currentTimeMillis() / 1000;
209 DelayedIdEntry delayedIdEntry;
210 while (index < delayedIdEntries.size()) {
211 delayedIdEntry = delayedIdEntries.get(index);
212 if (delayedIdEntry.getReadyTimeSec() > currentTimeSec) {
218 releasedIds.setAvailableIdCount(availableIdCount);
222 * Changes made to the parameters passed are not persisted to the Datastore. Method invoking should ensure that these gets persisted.
223 * @param releasedIdsChild
224 * @param releasedIdsParent
225 * @param idCountToBeFreed
227 protected static void freeExcessAvailableIds(ReleasedIdsHolderBuilder releasedIdsChild, ReleasedIdsHolderBuilder releasedIdsParent, int idCountToBeFreed) {
228 List<DelayedIdEntries> existingDelayedIdEntriesInParent = releasedIdsParent.getDelayedIdEntries();
229 List<DelayedIdEntries> delayedIdEntriesChild = releasedIdsChild.getDelayedIdEntries();
230 long availableIdCountParent = releasedIdsParent.getAvailableIdCount();
231 long availableIdCountChild = releasedIdsChild.getAvailableIdCount();
232 if (existingDelayedIdEntriesInParent == null) {
233 existingDelayedIdEntriesInParent = new LinkedList<>();
235 idCountToBeFreed = Math.min(idCountToBeFreed, delayedIdEntriesChild.size());
236 for (int index = 0; index < idCountToBeFreed; index++) {
237 existingDelayedIdEntriesInParent.add(delayedIdEntriesChild.get(0));
238 delayedIdEntriesChild.remove(0);
240 releasedIdsChild.setDelayedIdEntries(delayedIdEntriesChild).setAvailableIdCount(availableIdCountChild - idCountToBeFreed);
241 releasedIdsParent.setDelayedIdEntries(existingDelayedIdEntriesInParent).setAvailableIdCount(availableIdCountParent + idCountToBeFreed);
244 protected static InstanceIdentifier<IdEntries> getIdEntriesInstanceIdentifier(String poolName, String idKey) {
245 InstanceIdentifier<IdEntries> idEntries = InstanceIdentifier
246 .builder(IdPools.class).child(IdPool.class,
247 new IdPoolKey(poolName)).child(IdEntries.class, new IdEntriesKey(idKey)).build();
251 protected static InstanceIdentifier<ChildPools> getChildPoolsInstanceIdentifier(String poolName, String localPoolName) {
252 InstanceIdentifier<ChildPools> childPools = InstanceIdentifier
253 .builder(IdPools.class)
254 .child(IdPool.class, new IdPoolKey(poolName))
255 .child(ChildPools.class, new ChildPoolsKey(localPoolName)).build();
259 protected static long computeBlockSize(long low, long high) {
262 long diff = high - low;
263 if (diff > DEFAULT_BLOCK_SIZE_DIFF) {
264 blockSize = diff / DEFAULT_BLOCK_SIZE_DIFF;
271 public static long getAvailableIdsCount(AvailableIdsHolderBuilder availableIds) {
272 if(availableIds != null && isIdAvailable(availableIds)) {
273 return availableIds.getEnd() - availableIds.getCursor();
278 public static void lockPool(LockManagerService lockManager, String poolName) {
279 LockInput input = new LockInputBuilder().setLockName(poolName).build();
280 Future<RpcResult<Void>> result = lockManager.lock(input);
282 if ((result != null) && (result.get().isSuccessful())) {
283 LOGGER.debug("Acquired lock {}", poolName);
285 throw new RuntimeException(String.format("Unable to getLock for pool %s", poolName));
287 } catch (InterruptedException | ExecutionException e) {
288 LOGGER.error("Unable to getLock for pool {}", poolName);
289 throw new RuntimeException(String.format("Unable to getLock for pool %s", poolName), e.getCause());
293 public static void unlockPool(LockManagerService lockManager, String poolName) {
294 UnlockInput input = new UnlockInputBuilder().setLockName(poolName).build();
295 Future<RpcResult<Void>> result = lockManager.unlock(input);
297 if ((result != null) && (result.get().isSuccessful())) {
298 LOGGER.debug("Unlocked {}", poolName);
300 LOGGER.debug("Unable to unlock pool {}", poolName);
302 } catch (InterruptedException | ExecutionException e) {
303 LOGGER.error("Unable to unlock for pool {}", poolName);
304 throw new RuntimeException(String.format("Unable to unlock pool %s", poolName), e.getCause());