2 * ============LICENSE_START=======================================================
4 * ================================================================================
5 * Copyright (C) 2017 AT&T Intellectual Property. All rights
7 * ================================================================================
8 * Licensed under the Apache License, Version 2.0 (the "License");
9 * you may not use this file except in compliance with the License.
10 * You may obtain a copy of the License at
12 * http://www.apache.org/licenses/LICENSE-2.0
14 * Unless required by applicable law or agreed to in writing, software
15 * distributed under the License is distributed on an "AS IS" BASIS,
16 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
17 * See the License for the specific language governing permissions and
18 * limitations under the License.
19 * ============LICENSE_END=========================================================
22 package org.onap.ccsdk.sli.adaptors.ra;
24 import java.util.Arrays;
25 import java.util.Collections;
26 import java.util.HashMap;
27 import java.util.List;
30 import org.onap.ccsdk.sli.adaptors.ra.comp.EndPointAllocator;
31 import org.onap.ccsdk.sli.adaptors.ra.comp.ResourceData;
32 import org.onap.ccsdk.sli.adaptors.ra.comp.ResourceEntity;
33 import org.onap.ccsdk.sli.adaptors.ra.comp.ResourceRequest;
34 import org.onap.ccsdk.sli.adaptors.ra.comp.ResourceResponse;
35 import org.onap.ccsdk.sli.adaptors.ra.comp.ResourceTarget;
36 import org.onap.ccsdk.sli.adaptors.rm.comp.ResourceManager;
37 import org.onap.ccsdk.sli.adaptors.rm.data.AllocationStatus;
38 import org.onap.ccsdk.sli.adaptors.util.speed.SpeedUtil;
39 import org.onap.ccsdk.sli.adaptors.util.str.StrUtil;
40 import org.onap.ccsdk.sli.core.sli.SvcLogicContext;
41 import org.onap.ccsdk.sli.core.sli.SvcLogicException;
42 import org.onap.ccsdk.sli.core.sli.SvcLogicResource;
43 import org.slf4j.Logger;
44 import org.slf4j.LoggerFactory;
46 public class ResourceAllocator implements SvcLogicResource {
48 private static final Logger log = LoggerFactory.getLogger(ResourceAllocator.class);
50 private static final String[] INPUT_PREFIX = {"ra-input.", "tmp.resource-allocator."};
52 private ResourceManager resourceManager;
53 private EndPointAllocator endPointAllocator;
54 private SpeedUtil speedUtil;
56 public ResourceAllocator() {
57 log.info("ResourceAllocator created.");
61 public QueryStatus notify(String resource, String action, String key, SvcLogicContext ctx)
62 throws SvcLogicException {
63 return QueryStatus.SUCCESS;
67 public QueryStatus update(String resource, String key, Map<String, String> parms, String prefix,
68 SvcLogicContext ctx) throws SvcLogicException {
70 return QueryStatus.SUCCESS;
74 public QueryStatus exists(String resource, String key, String prefix, SvcLogicContext ctx)
75 throws SvcLogicException {
76 return QueryStatus.SUCCESS;
80 public QueryStatus delete(String arg0, String arg1, SvcLogicContext arg2) throws SvcLogicException {
81 return QueryStatus.SUCCESS;
85 public QueryStatus save(String arg0, boolean arg1, boolean arg2, String arg3, Map<String, String> arg4, String arg5,
86 SvcLogicContext arg6) throws SvcLogicException {
87 return QueryStatus.SUCCESS;
91 public QueryStatus isAvailable(String resource, String key, String prefix, SvcLogicContext ctx)
92 throws SvcLogicException {
93 return allocateResources(ctx, true, prefix);
97 public QueryStatus query(String resource, boolean localOnly, String select, String key, String prefix,
98 String orderBy, SvcLogicContext ctx) throws SvcLogicException {
100 String resourceEntityId = getParam(ctx,
101 new String[] {"service-instance-id", "reservation-entity-id", "resource-entity-id"}, false, null);
102 String resourceEntityType =
103 getParam(ctx, new String[] {"reservation-entity-type", "resource-entity-type"}, false, null);
104 String resourceEntityVersion =
105 getParam(ctx, new String[] {"reservation-entity-version", "resource-entity-version"}, false, "1");
107 String resourceTargetId =
108 getParam(ctx, new String[] {"reservation-target-id", "resource-target-id"}, false, null);
109 String resourceTargetType =
110 getParam(ctx, new String[] {"reservation-target-type", "resource-target-type"}, false, null);
111 String resourceName = getParam(ctx, "resource-name", false, null);
113 if (resourceEntityId != null && resourceEntityType != null) {
114 List<ResourceData> rdlist = endPointAllocator.getResourcesForEntity(resourceEntityType, resourceEntityId,
115 resourceEntityVersion);
116 setResourceDataInContext(ctx, prefix, rdlist);
117 } else if (resourceTargetId != null && resourceTargetType != null && resourceName != null) {
118 ResourceData rd = endPointAllocator.getResource(resourceTargetType, resourceTargetId, resourceName);
119 setResourceDataInContext(ctx, prefix, Collections.singletonList(rd));
122 return QueryStatus.SUCCESS;
125 public AllocationStatus query(ResourceEntity sd, ResourceTarget rt, ResourceRequest rr,
126 List<ResourceResponse> rsList) throws Exception {
128 if (sd.resourceEntityId != null && sd.resourceEntityType != null) {
129 List<ResourceData> rdlist = endPointAllocator.getResourcesForEntity(sd.resourceEntityType,
130 sd.resourceEntityId, sd.resourceEntityVersion);
131 setResourceDataInResponse(rdlist, rsList);
132 } else if (rt.resourceTargetId != null && rt.resourceTargetType != null && rr.resourceName != null) {
134 endPointAllocator.getResource(rt.resourceTargetType, rt.resourceTargetId, rr.resourceName);
135 setResourceDataInResponse(Collections.singletonList(rd), rsList);
138 return AllocationStatus.Success;
141 private void setResourceDataInContext(SvcLogicContext ctx, String prefix, List<ResourceData> rdlist) {
142 prefix = prefix == null ? "" : prefix + '.';
144 setAttr(ctx, prefix + "resource-list_length", String.valueOf(rdlist.size()));
146 for (int i = 0; i < rdlist.size(); i++) {
147 ResourceData rd = rdlist.get(i);
149 String pp = prefix + "resource-list[" + i + "].";
151 setAttr(ctx, pp + "resource-name", rd.resourceName);
152 setAttr(ctx, pp + "endpoint-position", rd.endPointPosition);
153 setAttr(ctx, pp + "resource-target-type", rd.resourceTargetType);
154 setAttr(ctx, pp + "resource-target-id", rd.resourceTargetId);
156 setAttr(ctx, pp + "resource-target-value", rd.resourceTargetValue);
157 setAttr(ctx, pp + "status", rd.status);
159 if (rd.data != null && !rd.data.isEmpty()) {
160 for (String kk : rd.data.keySet()) {
161 String value = String.valueOf(rd.data.get(kk));
162 setAttr(ctx, pp + kk, value);
169 public QueryStatus reserve(String resource, String select, String key, String prefix, SvcLogicContext ctx)
170 throws SvcLogicException {
171 return allocateResources(ctx, false, prefix);
174 public AllocationStatus reserve(ResourceEntity sd, ResourceTarget rt, ResourceRequest rr,
175 List<ResourceResponse> rsList) throws Exception {
176 return allocateResources(sd, rt, rr, rsList);
180 public QueryStatus release(String resource, String key, SvcLogicContext ctx) throws SvcLogicException {
181 String resourceEntityId = getParam(ctx,
182 new String[] {"service-instance-id", "reservation-entity-id", "resource-entity-id"}, true, null);
183 String resourceEntityType =
184 getParam(ctx, new String[] {"reservation-entity-type", "resource-entity-type"}, true, null);
185 String resourceEntityVersion =
186 getParam(ctx, new String[] {"reservation-entity-version", "resource-entity-version"}, false, null);
188 ResourceEntity sd = new ResourceEntity();
189 sd.resourceEntityId = resourceEntityId;
190 sd.resourceEntityType = resourceEntityType;
191 sd.resourceEntityVersion = resourceEntityVersion;
195 } catch (Exception e) {
196 throw new SvcLogicException(e.getMessage());
198 return QueryStatus.SUCCESS;
201 public AllocationStatus release(ResourceEntity sd) throws Exception {
203 if (sd.resourceEntityVersion != null) {
204 String resourceSet = sd.resourceEntityType + "::" + sd.resourceEntityId + "::" + sd.resourceEntityVersion;
205 log.info("Starting release for: " + resourceSet);
207 resourceManager.releaseResourceSet(resourceSet);
209 String resourceUnion = sd.resourceEntityType + "::" + sd.resourceEntityId;
210 log.info("Starting release for: " + resourceUnion);
212 resourceManager.releaseResourceUnion(resourceUnion);
215 return AllocationStatus.Success;
219 private QueryStatus allocateResources(SvcLogicContext ctx, boolean checkOnly, String prefix)
220 throws SvcLogicException {
221 String serviceModel = getParam(ctx, "service-model", true, null);
222 String requestType = getParam(ctx, "request-type", false, "New");
224 ResourceEntity sd = getResourceEntityData(ctx);
225 ResourceTarget rt = getResourceTargetData(ctx);
226 ResourceRequest rr = getResourceRequest(ctx);
228 log.info("Starting reserve: " + requestType + ", service-model: " + serviceModel);
229 StrUtil.info(log, sd);
230 StrUtil.info(log, rt);
231 StrUtil.info(log, rr);
233 boolean change = requestType.equalsIgnoreCase("change");
235 List<ResourceData> rlist = endPointAllocator.allocateResources(serviceModel, sd, rt, rr, checkOnly, change);
237 if (rlist != null && !rlist.isEmpty()) {
238 setResourceDataInContext(ctx, prefix, rlist);
240 for (ResourceData rd : rlist) {
241 if (!rd.status.equals("Success")) {
242 log.info("Capacity not found for: " + sd.resourceEntityType + "::" + sd.resourceEntityId);
243 return QueryStatus.NOT_FOUND;
247 return QueryStatus.SUCCESS;
250 private AllocationStatus allocateResources(ResourceEntity sd, ResourceTarget rt, ResourceRequest rr,
251 List<ResourceResponse> rsList) throws Exception {
253 String serviceModel = rr.serviceModel;
254 String requestType = rr.requestType == null ? "New" : rr.requestType;
256 log.info("Starting reserve: " + requestType + ", service-model: " + serviceModel);
257 StrUtil.info(log, sd);
258 StrUtil.info(log, rt);
259 StrUtil.info(log, rr);
261 boolean change = requestType.equalsIgnoreCase("change");
263 List<ResourceData> rlist = endPointAllocator.allocateResources(serviceModel, sd, rt, rr, rr.checkOnly, change);
265 if (rlist != null && !rlist.isEmpty()) {
266 setResourceDataInResponse(rlist, rsList);
268 for (ResourceData rd : rlist) {
269 if (!rd.status.equals("Success")) {
270 log.info("Capacity not found for: " + sd.resourceEntityType + "::" + sd.resourceEntityId);
271 return AllocationStatus.ResourceNotFound;
276 return AllocationStatus.Success;
279 private void setResourceDataInResponse(List<ResourceData> rlist, List<ResourceResponse> rsList) {
280 for (ResourceData rd : emptyIfNull(rlist)) {
281 ResourceResponse res = new ResourceResponse();
282 res.resourceName = rd.resourceName;
283 res.endPointPosition = rd.endPointPosition;
284 res.resourceTargetId = rd.resourceTargetId;
285 res.resourceTargetType = rd.resourceTargetType;
286 res.status = rd.status;
287 if (rd.data != null && !rd.data.isEmpty()) {
288 for (String kk : rd.data.keySet()) {
289 if (kk.equalsIgnoreCase("allocated")) {
290 res.resourceAllocated = String.valueOf(rd.data.get(kk));
293 if (kk.equalsIgnoreCase("used")) {
294 res.resourceUsed = String.valueOf(rd.data.get(kk));
297 if (kk.equalsIgnoreCase("available")) {
298 res.resourceAvailable = String.valueOf(rd.data.get(kk));
301 if (kk.equalsIgnoreCase("limit")) {
302 res.resourceLimit = String.valueOf(rd.data.get(kk));
312 public static <T> Iterable<T> emptyIfNull(Iterable<T> iterable) {
313 return iterable == null ? Collections.<T>emptyList() : iterable;
316 private void setAttr(SvcLogicContext ctx, String name, String value) {
317 ctx.setAttribute(name, value);
318 log.info("Added context attr: " + name + ": " + value);
321 private ResourceEntity getResourceEntityData(SvcLogicContext ctx) throws SvcLogicException {
322 ResourceEntity sd = new ResourceEntity();
323 sd.resourceEntityId = getParam(ctx,
324 new String[] {"service-instance-id", "reservation-entity-id", "resource-entity-id"}, true, null);
325 sd.resourceEntityType =
326 getParam(ctx, new String[] {"reservation-entity-type", "resource-entity-type"}, true, null);
327 sd.resourceEntityVersion =
328 getParam(ctx, new String[] {"reservation-entity-version", "resource-entity-version"}, false, "1");
329 sd.data = getDataParam(ctx, "reservation-entity-data", "resource-entity-data", "service-data");
333 private ResourceTarget getResourceTargetData(SvcLogicContext ctx) throws SvcLogicException {
334 ResourceTarget sd = new ResourceTarget();
335 sd.resourceTargetId = getParam(ctx, new String[] {"reservation-target-id", "resource-target-id"}, true, null);
336 sd.resourceTargetType =
337 getParam(ctx, new String[] {"reservation-target-type", "resource-target-type"}, true, null);
338 sd.data = getDataParam(ctx, "reservation-target-data", "resource-target-data", "equipment-data");
342 private ResourceRequest getResourceRequest(SvcLogicContext ctx) throws SvcLogicException {
343 ResourceRequest rr = new ResourceRequest();
344 rr.resourceName = getParam(ctx, "resource-name", false, null);
345 rr.resourceShareGroup = getParam(ctx, "resource-share-group", false, null);
346 rr.rangeRequestedNumbers = getParam(ctx, "range-requested-numbers", false, null);
347 rr.rangeExcludeNumbers = getParam(ctx, "range-exclude-numbers", false, null);
348 String rangeReverseOrderStr = getParam(ctx, "range-reverse-order", false, "false");
349 rr.rangeReverseOrder = Boolean.parseBoolean(rangeReverseOrderStr);
350 String rangeMinOverrideStr = getParam(ctx, "range-min-override", false, "-1");
351 rr.rangeMinOverride = Integer.parseInt(rangeMinOverrideStr);
352 String rangeMaxOverrideStr = getParam(ctx, "range-max-override", false, "-1");
353 rr.rangeMaxOverride = Integer.parseInt(rangeMaxOverrideStr);
354 String rangeForceNewNumbersStr = getParam(ctx, "range-force-new-numbers", false, "false");
355 rr.rangeForceNewNumbers = Boolean.parseBoolean(rangeForceNewNumbersStr);
356 String replaceStr = getParam(ctx, "replace", false, "true");
357 rr.replace = Boolean.parseBoolean(replaceStr);
358 rr.applicationId = getParam(ctx, "application-id", false, "SDNC");
359 rr.endPointPosition = getParam(ctx, "endpoint-position", false, null);
363 private String getParam(SvcLogicContext ctx, String name, boolean required, String def) throws SvcLogicException {
365 for (String p : INPUT_PREFIX) {
366 v = ctx.getAttribute(p + name);
367 if (v != null && v.trim().length() > 0) {
368 log.info("Param: " + name + ": " + v.trim());
373 throw new SvcLogicException("The following variable is required in DG context: " + name);
376 log.info("Param: " + name + " not supplied. Using default: " + def);
380 private String getParam(SvcLogicContext ctx, String[] names, boolean required, String def)
381 throws SvcLogicException {
383 for (String name : names) {
384 v = getParam(ctx, name, false, def);
390 throw new SvcLogicException(
391 "One of the following variable is required in DG context: " + Arrays.deepToString(names));
394 log.info("Param: " + names + " not supplied. Using default: " + def);
398 private Map<String, String> getDataParam(SvcLogicContext ctx, String... names) {
399 Map<String, String> data = new HashMap<>();
400 Set<String> ctxNames = ctx.getAttributeKeySet();
401 for (String n : ctxNames) {
402 for (String p : INPUT_PREFIX) {
403 for (String name : names) {
404 String pp = p + name + '.';
405 if (n.startsWith(pp)) {
406 String nn = n.substring(pp.length());
407 String vv = ctx.getAttribute(n);
410 log.info("Data param: " + nn + ": " + vv);
412 if (ctxNames.contains(n + "-unit")) {
414 long v = Long.parseLong(vv);
415 String unit = ctx.getAttribute(n + "-unit");
416 long kbps = speedUtil.convertToKbps(v, unit);
417 long mbps = speedUtil.convertToMbps(v, unit);
418 data.put(nn + "-kbps", String.valueOf(kbps));
419 data.put(nn + "-mbps", String.valueOf(mbps));
421 log.info("Data param: " + nn + "-kbps: " + kbps);
422 log.info("Data param: " + nn + "-mbps: " + mbps);
424 } catch (Exception e) {
425 log.warn("Invalid number for " + n + ": " + vv);
435 public void setResourceManager(ResourceManager resourceManager) {
436 this.resourceManager = resourceManager;
439 public void setEndPointAllocator(EndPointAllocator endPointAllocator) {
440 this.endPointAllocator = endPointAllocator;
443 public void setSpeedUtil(SpeedUtil speedUtil) {
444 this.speedUtil = speedUtil;