Merge "Increase max service-binding's"
[genius.git] / resourcemanager / resourcemanager-impl / src / main / java / org / opendaylight / genius / resourcemanager / ResourceManager.java
1 /*
2  * Copyright (c) 2016 Ericsson India Global Services Pvt Ltd. and others.  All rights reserved.
3  *
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
7  */
8
9 package org.opendaylight.genius.resourcemanager;
10
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;
54
55 public class ResourceManager implements ResourceManagerService, AutoCloseable  {
56
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";
64
65     public ResourceManager(DataBroker broker, IdManagerService idManager) {
66         this.broker = broker;
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));
74         } else {
75             //Updating Map with default values
76             resourceMap.put(ResourceTypeTableIds.class, "tables");
77             resourceMap.put(ResourceTypeGroupIds.class, "groups");
78             resourceMap.put(ResourceTypeMeterIds.class, "meters");
79         }
80     }
81
82     @Override
83     public void close() throws Exception {
84         LOG.info("ResourceManager closed");
85     }
86
87     @Override
88     public Future<RpcResult<AllocateResourceOutput>> allocateResource(AllocateResourceInput input) {
89         try {
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");
96         }
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<>();
104         try {
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());
111             }
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());
119         }
120
121         if (allocateResourceOutputRpcBuilder == null) {
122             allocateResourceOutputRpcBuilder = RpcResultBuilder.failed();
123             allocateResourceOutputRpcBuilder.withError(RpcError.ErrorType.APPLICATION, "Resource cannot be  allocated");
124         }
125         return Futures.immediateFuture(allocateResourceOutputRpcBuilder.build());
126     }
127
128     @Override
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;
135         try {
136             Preconditions.checkNotNull(input.getResourceType());
137             Preconditions.checkNotNull(resourceMap.get(input.getResourceType()));
138         } catch (NullPointerException e) {
139             LOG.error("Incorrect parameters for GetResourcePool");
140         }
141
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());
154             }
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());
162                     }
163                 }
164             }
165         }
166
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());
177             }
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) {
184                             break;
185                         }
186                         delayedIdEntriesList.add(new DelayedResourceEntriesBuilder().setId(delayedLocalEntry.getId())
187                                 .setReadyTimeSec(delayedLocalEntry.getReadyTimeSec()).build());
188                     }
189                 }
190
191             }
192         }
193
194         try {
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());
202         }
203         return Futures.immediateFuture(rpcOutputBuilder.build());
204     }
205
206     @Override
207     public Future<RpcResult<GetAvailableResourcesOutput>> getAvailableResources(GetAvailableResourcesInput input) {
208
209         IdPool parentIdPool = null;
210         IdPool localIdPool = null;
211         long totalIdsAvailableForAllocation = 0;
212         long currentTimeSec = System.currentTimeMillis() / 1000;
213         try {
214             Preconditions.checkNotNull(input.getResourceType());
215             Preconditions.checkNotNull(resourceMap.get(input.getResourceType()));
216         } catch (NullPointerException e) {
217             LOG.error("Incorrect parameters for GetAvailableResources");
218         }
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();
231                 }
232             }
233         }
234
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();
244             }
245             ReleasedIdsHolder releasedLocalIdsHolder = localIdPool.getReleasedIdsHolder();
246             if (releasedLocalIdsHolder != null) {
247                 long count = 0;
248                 List<DelayedIdEntries> delayedIdLocalList = releasedLocalIdsHolder.getDelayedIdEntries();
249                 if (delayedIdLocalList != null && !delayedIdLocalList.isEmpty()) {
250                     for (DelayedIdEntries delayedLocalEntry : delayedIdLocalList) {
251                         if (delayedLocalEntry.getReadyTimeSec() > currentTimeSec) {
252                             break;
253                         }
254                     }
255                     count++;
256                 }
257                 totalIdsAvailableForAllocation += count;
258             }
259         }
260
261         GetAvailableResourcesOutputBuilder outputBuilder = new GetAvailableResourcesOutputBuilder()
262                 .setTotalAvailableIdCount(totalIdsAvailableForAllocation);
263         RpcResultBuilder<GetAvailableResourcesOutput> rpcOutputBuilder = null;
264         rpcOutputBuilder = RpcResultBuilder.success();
265         rpcOutputBuilder.withResult(outputBuilder.build());
266
267         return Futures.immediateFuture(rpcOutputBuilder.build());
268     }
269
270     @Override
271     public Future<RpcResult<Void>> releaseResource(ReleaseResourceInput input) {
272         try {
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");
278         }
279         ReleaseIdInputBuilder releaseIdInputBuilder = new ReleaseIdInputBuilder();
280         releaseIdInputBuilder.setIdKey(input.getIdKey()).setPoolName(resourceMap.get(input.getResourceType()));
281         RpcResultBuilder<Void> releaseIdRpcBuilder;
282         try {
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());
289         }
290         return Futures.immediateFuture(releaseIdRpcBuilder.build());
291     }
292 }