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.resourcemanager;
11 import com.google.common.base.Optional;
12 import com.google.common.base.Preconditions;
13 import com.google.common.util.concurrent.Futures;
14 import java.util.ArrayList;
15 import java.util.List;
16 import java.util.concurrent.ConcurrentHashMap;
17 import java.util.concurrent.ExecutionException;
18 import java.util.concurrent.Future;
19 import org.opendaylight.controller.md.sal.binding.api.DataBroker;
20 import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType;
21 import org.opendaylight.genius.mdsalutil.MDSALUtil;
22 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.idmanager.rev160406.AllocateIdRangeInputBuilder;
23 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.idmanager.rev160406.AllocateIdRangeOutput;
24 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.idmanager.rev160406.IdManagerService;
25 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.idmanager.rev160406.ReleaseIdInputBuilder;
26 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.idmanager.rev160406.id.pools.IdPool;
27 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.idmanager.rev160406.id.pools.id.pool.AvailableIdsHolder;
28 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.idmanager.rev160406.id.pools.id.pool.ReleasedIdsHolder;
29 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.idmanager.rev160406.released.ids.DelayedIdEntries;
30 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.resourcemanager.rev160622.AllocateResourceInput;
31 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.resourcemanager.rev160622.AllocateResourceOutput;
32 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.resourcemanager.rev160622.AllocateResourceOutputBuilder;
33 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.resourcemanager.rev160622.GetAvailableResourcesInput;
34 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.resourcemanager.rev160622.GetAvailableResourcesOutput;
35 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.resourcemanager.rev160622.GetAvailableResourcesOutputBuilder;
36 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.resourcemanager.rev160622.GetResourcePoolInput;
37 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.resourcemanager.rev160622.GetResourcePoolOutput;
38 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.resourcemanager.rev160622.GetResourcePoolOutputBuilder;
39 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.resourcemanager.rev160622.ReleaseResourceInput;
40 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.resourcemanager.rev160622.ResourceManagerService;
41 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.resourcemanager.rev160622.ResourceTypeBase;
42 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.resourcemanager.rev160622.ResourceTypeGroupIds;
43 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.resourcemanager.rev160622.ResourceTypeMeterIds;
44 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.resourcemanager.rev160622.ResourceTypeTableIds;
45 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.resourcemanager.rev160622.getresourcepool.output.AvailableIdsBuilder;
46 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.resourcemanager.rev160622.released.resource.ids.DelayedResourceEntries;
47 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.resourcemanager.rev160622.released.resource.ids.DelayedResourceEntriesBuilder;
48 import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
49 import org.opendaylight.yangtools.yang.common.RpcError;
50 import org.opendaylight.yangtools.yang.common.RpcResult;
51 import org.opendaylight.yangtools.yang.common.RpcResultBuilder;
52 import org.slf4j.Logger;
53 import org.slf4j.LoggerFactory;
55 public class ResourceManager implements ResourceManagerService, AutoCloseable {
57 private static final Logger LOG = LoggerFactory.getLogger(ResourceManager.class);
58 private final DataBroker broker;
59 private final IdManagerService idManager;
60 private final ConcurrentHashMap<Class<? extends ResourceTypeBase>, String> resourceMap;
61 private final String tablesName = "resource.tables.name";
62 private final String groupsName = "resource.groups.name";
63 private final String metersName = "resource.meters.name";
65 public ResourceManager(DataBroker broker, IdManagerService idManager) {
67 this.idManager = idManager;
68 this.resourceMap = new ConcurrentHashMap<>();
69 if (System.getProperty(tablesName) != null && System.getProperty(groupsName) != null
70 && System.getProperty(metersName) != null) {
71 resourceMap.put(ResourceTypeTableIds.class, System.getProperty(tablesName));
72 resourceMap.put(ResourceTypeGroupIds.class, System.getProperty(groupsName));
73 resourceMap.put(ResourceTypeMeterIds.class, System.getProperty(metersName));
75 //Updating Map with default values
76 resourceMap.put(ResourceTypeTableIds.class, "tables");
77 resourceMap.put(ResourceTypeGroupIds.class, "groups");
78 resourceMap.put(ResourceTypeMeterIds.class, "meters");
83 public void close() throws Exception {
84 LOG.info("ResourceManager closed");
88 public Future<RpcResult<AllocateResourceOutput>> allocateResource(AllocateResourceInput input) {
90 Preconditions.checkNotNull(input.getResourceType());
91 Preconditions.checkNotNull(input.getIdKey());
92 Preconditions.checkNotNull(input.getSize());
93 Preconditions.checkNotNull(resourceMap.get(input.getResourceType()));
94 } catch (NullPointerException e) {
95 LOG.error("Incorrect parameters for AllocateResourceInput");
97 AllocateIdRangeInputBuilder allocateIdRangeBuilder = new AllocateIdRangeInputBuilder();
98 allocateIdRangeBuilder.setIdKey(input.getIdKey()).setPoolName(resourceMap.get(input.getResourceType()))
99 .setSize(input.getSize());
100 Future<RpcResult<AllocateIdRangeOutput>> output = idManager.allocateIdRange(allocateIdRangeBuilder.build());
101 AllocateResourceOutputBuilder allocateResourceOutputBuilder = new AllocateResourceOutputBuilder();
102 RpcResultBuilder<AllocateResourceOutput> allocateResourceOutputRpcBuilder = null;
103 List<Long> idValues = new ArrayList<>();
105 if (output.get().isSuccessful()) {
106 AllocateIdRangeOutput allocateIdRangeOutput = output.get().getResult();
107 idValues = allocateIdRangeOutput.getIdValues();
108 allocateResourceOutputBuilder.setIdValues(idValues);
109 allocateResourceOutputRpcBuilder = RpcResultBuilder.success();
110 allocateResourceOutputRpcBuilder.withResult(allocateResourceOutputBuilder.build());
112 } catch (InterruptedException | ExecutionException e) {
113 allocateResourceOutputRpcBuilder = RpcResultBuilder.failed();
114 allocateResourceOutputRpcBuilder.withError(RpcError.ErrorType.APPLICATION, e.getMessage());
115 } catch (NullPointerException e) {
116 LOG.error("Allocate Resource failed for resource {} due to {} ", input.getResourceType(), e);
117 allocateResourceOutputRpcBuilder = RpcResultBuilder.failed();
118 allocateResourceOutputRpcBuilder.withError(RpcError.ErrorType.APPLICATION, e.getMessage());
121 if (allocateResourceOutputRpcBuilder == null) {
122 allocateResourceOutputRpcBuilder = RpcResultBuilder.failed();
123 allocateResourceOutputRpcBuilder.withError(RpcError.ErrorType.APPLICATION, "Resource cannot be allocated");
125 return Futures.immediateFuture(allocateResourceOutputRpcBuilder.build());
129 public Future<RpcResult<GetResourcePoolOutput>> getResourcePool(GetResourcePoolInput input) {
130 IdPool parentIdPool = null;
131 IdPool localIdPool = null;
132 GetResourcePoolOutputBuilder outputBuilder = null;
133 RpcResultBuilder<GetResourcePoolOutput> rpcOutputBuilder = null;
134 long currentTimeSec = System.currentTimeMillis() / 1000;
136 Preconditions.checkNotNull(input.getResourceType());
137 Preconditions.checkNotNull(resourceMap.get(input.getResourceType()));
138 } catch (NullPointerException e) {
139 LOG.error("Incorrect parameters for GetResourcePool");
142 List<org.opendaylight.yang.gen.v1.urn.opendaylight.genius.resourcemanager
143 .rev160622.getresourcepool.output.AvailableIds> availableIdsList = new ArrayList<>();
144 List<DelayedResourceEntries> delayedIdEntriesList = new ArrayList<>();
145 InstanceIdentifier<IdPool> parentId = ResourceManagerUtils.getIdPoolInstance(resourceMap
146 .get(input.getResourceType()));
147 Optional<IdPool> optionalParentIdPool = MDSALUtil.read(LogicalDatastoreType.CONFIGURATION, parentId, broker);
148 if (optionalParentIdPool != null && optionalParentIdPool.isPresent()) {
149 parentIdPool = optionalParentIdPool.get();
150 AvailableIdsHolder availableParentIdsHolder = parentIdPool.getAvailableIdsHolder();
151 if (availableParentIdsHolder.getStart() < availableParentIdsHolder.getEnd()) {
152 availableIdsList.add(new AvailableIdsBuilder().setStart(availableParentIdsHolder.getStart())
153 .setEnd(availableParentIdsHolder.getEnd()).build());
155 ReleasedIdsHolder releasedParentIdsHolder = parentIdPool.getReleasedIdsHolder();
156 if (releasedParentIdsHolder != null) {
157 List<DelayedIdEntries> delayedIdParentList = releasedParentIdsHolder.getDelayedIdEntries();
158 if (delayedIdParentList != null && !delayedIdParentList.isEmpty()) {
159 for (DelayedIdEntries delayedParentEntry : delayedIdParentList) {
160 delayedIdEntriesList.add(new DelayedResourceEntriesBuilder().setId(delayedParentEntry.getId())
161 .setReadyTimeSec(delayedParentEntry.getReadyTimeSec()).build());
167 String localPool = ResourceManagerUtils.getLocalPoolName(resourceMap.get(input.getResourceType()));
168 InstanceIdentifier<IdPool> localId = ResourceManagerUtils.getIdPoolInstance(localPool);
169 Optional<IdPool> optionalLocalId = MDSALUtil.read(LogicalDatastoreType.CONFIGURATION, localId,broker);
170 if (optionalLocalId != null && optionalLocalId.isPresent()) {
171 localIdPool = optionalLocalId.get();
172 AvailableIdsHolder availableLocalIdsHolder = localIdPool.getAvailableIdsHolder();
173 if (availableLocalIdsHolder != null
174 && availableLocalIdsHolder.getStart() < availableLocalIdsHolder.getEnd()) {
175 availableIdsList.add(new AvailableIdsBuilder().setStart(availableLocalIdsHolder.getStart())
176 .setEnd(availableLocalIdsHolder.getEnd()).build());
178 ReleasedIdsHolder releasedLocalIdsHolder = localIdPool.getReleasedIdsHolder();
179 if (releasedLocalIdsHolder != null) {
180 List<DelayedIdEntries> delayedIdLocalList = releasedLocalIdsHolder.getDelayedIdEntries();
181 if (delayedIdLocalList != null && !delayedIdLocalList.isEmpty()) {
182 for (DelayedIdEntries delayedLocalEntry : delayedIdLocalList) {
183 if (delayedLocalEntry.getReadyTimeSec() > currentTimeSec) {
186 delayedIdEntriesList.add(new DelayedResourceEntriesBuilder().setId(delayedLocalEntry.getId())
187 .setReadyTimeSec(delayedLocalEntry.getReadyTimeSec()).build());
195 outputBuilder = new GetResourcePoolOutputBuilder().setAvailableIds(availableIdsList)
196 .setDelayedResourceEntries(delayedIdEntriesList);
197 rpcOutputBuilder = RpcResultBuilder.success();
198 rpcOutputBuilder.withResult(outputBuilder.build());
199 } catch (NullPointerException e) {
200 rpcOutputBuilder = RpcResultBuilder.failed();
201 rpcOutputBuilder.withError(RpcError.ErrorType.APPLICATION, e.getMessage());
203 return Futures.immediateFuture(rpcOutputBuilder.build());
207 public Future<RpcResult<GetAvailableResourcesOutput>> getAvailableResources(GetAvailableResourcesInput input) {
209 IdPool parentIdPool = null;
210 IdPool localIdPool = null;
211 long totalIdsAvailableForAllocation = 0;
212 long currentTimeSec = System.currentTimeMillis() / 1000;
214 Preconditions.checkNotNull(input.getResourceType());
215 Preconditions.checkNotNull(resourceMap.get(input.getResourceType()));
216 } catch (NullPointerException e) {
217 LOG.error("Incorrect parameters for GetAvailableResources");
219 InstanceIdentifier<IdPool> parentId = ResourceManagerUtils
220 .getIdPoolInstance(resourceMap.get(input.getResourceType()));
221 Optional<IdPool> optionalParentIdPool = MDSALUtil.read(LogicalDatastoreType.CONFIGURATION, parentId, broker);
222 if (optionalParentIdPool != null && optionalParentIdPool.isPresent()) {
223 parentIdPool = optionalParentIdPool.get();
224 AvailableIdsHolder availableParentIdsHolder = parentIdPool.getAvailableIdsHolder();
225 totalIdsAvailableForAllocation = availableParentIdsHolder.getEnd() - availableParentIdsHolder.getCursor();
226 ReleasedIdsHolder releasedParentIdsHolder = parentIdPool.getReleasedIdsHolder();
227 if (releasedParentIdsHolder != null) {
228 List<DelayedIdEntries> delayedIdParentList = releasedParentIdsHolder.getDelayedIdEntries();
229 if (delayedIdParentList != null && !delayedIdParentList.isEmpty()) {
230 totalIdsAvailableForAllocation += delayedIdParentList.size();
235 String localPool = ResourceManagerUtils.getLocalPoolName(resourceMap.get(input.getResourceType()));
236 InstanceIdentifier<IdPool> localId = ResourceManagerUtils.getIdPoolInstance(localPool);
237 Optional<IdPool> optionalLocalId = MDSALUtil.read(LogicalDatastoreType.CONFIGURATION, localId,broker);
238 if (optionalLocalId != null && optionalLocalId.isPresent()) {
239 localIdPool = optionalLocalId.get();
240 AvailableIdsHolder availableLocalIdsHolder = localIdPool.getAvailableIdsHolder();
241 if (availableLocalIdsHolder != null) {
242 totalIdsAvailableForAllocation +=
243 availableLocalIdsHolder.getEnd() - availableLocalIdsHolder.getCursor();
245 ReleasedIdsHolder releasedLocalIdsHolder = localIdPool.getReleasedIdsHolder();
246 if (releasedLocalIdsHolder != null) {
248 List<DelayedIdEntries> delayedIdLocalList = releasedLocalIdsHolder.getDelayedIdEntries();
249 if (delayedIdLocalList != null && !delayedIdLocalList.isEmpty()) {
250 for (DelayedIdEntries delayedLocalEntry : delayedIdLocalList) {
251 if (delayedLocalEntry.getReadyTimeSec() > currentTimeSec) {
257 totalIdsAvailableForAllocation += count;
261 GetAvailableResourcesOutputBuilder outputBuilder = new GetAvailableResourcesOutputBuilder()
262 .setTotalAvailableIdCount(totalIdsAvailableForAllocation);
263 RpcResultBuilder<GetAvailableResourcesOutput> rpcOutputBuilder = null;
264 rpcOutputBuilder = RpcResultBuilder.success();
265 rpcOutputBuilder.withResult(outputBuilder.build());
267 return Futures.immediateFuture(rpcOutputBuilder.build());
271 public Future<RpcResult<Void>> releaseResource(ReleaseResourceInput input) {
273 Preconditions.checkNotNull(input.getResourceType());
274 Preconditions.checkNotNull(input.getIdKey());
275 Preconditions.checkNotNull(resourceMap.get(input.getResourceType()));
276 } catch (NullPointerException e) {
277 LOG.error("Incorrect parameters for the ReleaseResourceInput");
279 ReleaseIdInputBuilder releaseIdInputBuilder = new ReleaseIdInputBuilder();
280 releaseIdInputBuilder.setIdKey(input.getIdKey()).setPoolName(resourceMap.get(input.getResourceType()));
281 RpcResultBuilder<Void> releaseIdRpcBuilder;
283 idManager.releaseId(releaseIdInputBuilder.build());
284 releaseIdRpcBuilder = RpcResultBuilder.success();
285 } catch (NullPointerException e) {
286 LOG.error("Release resource failed for resource {} due to {}", input.getResourceType(), e);
287 releaseIdRpcBuilder = RpcResultBuilder.failed();
288 releaseIdRpcBuilder.withError(RpcError.ErrorType.APPLICATION, e.getMessage());
290 return Futures.immediateFuture(releaseIdRpcBuilder.build());