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." };
51 private static final String START_RELEASE_LC = "Starting release for: {}";
53 private ResourceManager resourceManager;
54 private EndPointAllocator endPointAllocator;
55 private SpeedUtil speedUtil;
57 public ResourceAllocator() {
58 log.info("ResourceAllocator created.");
62 public QueryStatus notify(String resource, String action, String key, SvcLogicContext ctx)
63 throws SvcLogicException {
64 return QueryStatus.SUCCESS;
68 public QueryStatus update(String resource, String key, Map<String, String> parms, String prefix,
69 SvcLogicContext ctx) throws SvcLogicException {
71 return QueryStatus.SUCCESS;
75 public QueryStatus exists(String resource, String key, String prefix, SvcLogicContext ctx)
76 throws SvcLogicException {
77 return QueryStatus.SUCCESS;
81 public QueryStatus delete(String arg0, String arg1, SvcLogicContext arg2) throws SvcLogicException {
82 return QueryStatus.SUCCESS;
86 public QueryStatus save(String arg0, boolean arg1, boolean arg2, String arg3, Map<String, String> arg4, String arg5,
87 SvcLogicContext arg6) throws SvcLogicException {
88 return QueryStatus.SUCCESS;
92 public QueryStatus isAvailable(String resource, String key, String prefix, SvcLogicContext ctx)
93 throws SvcLogicException {
94 return allocateResources(ctx, true, prefix);
98 public QueryStatus query(String resource, boolean localOnly, String select, String key, String prefix,
99 String orderBy, SvcLogicContext ctx) throws SvcLogicException {
101 String resourceEntityId = getParam(ctx,
102 new String[] { "service-instance-id", "reservation-entity-id", "resource-entity-id" }, false, null);
103 String resourceEntityType = getParam(ctx, new String[] { "reservation-entity-type", "resource-entity-type" },
105 String resourceEntityVersion = getParam(ctx,
106 new String[] { "reservation-entity-version", "resource-entity-version" }, false, "1");
108 String resourceTargetId = getParam(ctx, new String[] { "reservation-target-id", "resource-target-id" }, false,
110 String resourceTargetType = getParam(ctx, new String[] { "reservation-target-type", "resource-target-type" },
112 String resourceName = getParam(ctx, "resource-name", false, null);
114 if (resourceEntityId != null && resourceEntityType != null) {
115 List<ResourceData> rdlist = endPointAllocator.getResourcesForEntity(resourceEntityType, resourceEntityId,
116 resourceEntityVersion);
117 setResourceDataInContext(ctx, prefix, rdlist);
118 } else if (resourceTargetId != null && resourceTargetType != null && resourceName != null) {
119 ResourceData rd = endPointAllocator.getResource(resourceTargetType, resourceTargetId, resourceName);
120 setResourceDataInContext(ctx, prefix, Collections.singletonList(rd));
123 return QueryStatus.SUCCESS;
126 public AllocationStatus query(ResourceEntity sd, ResourceTarget rt, ResourceRequest rr,
127 List<ResourceResponse> rsList) throws Exception {
129 if (sd.resourceEntityId != null && sd.resourceEntityType != null) {
130 List<ResourceData> rdlist = endPointAllocator.getResourcesForEntity(sd.resourceEntityType,
131 sd.resourceEntityId, sd.resourceEntityVersion);
132 setResourceDataInResponse(rdlist, rsList);
133 } else if (rt.resourceTargetId != null && rt.resourceTargetType != null && rr.resourceName != null) {
134 ResourceData rd = endPointAllocator.getResource(rt.resourceTargetType, rt.resourceTargetId,
136 setResourceDataInResponse(Collections.singletonList(rd), rsList);
139 return AllocationStatus.Success;
142 private void setResourceDataInContext(SvcLogicContext ctx, String prefix, List<ResourceData> rdlist) {
143 prefix = prefix == null ? "" : prefix + '.';
145 setAttr(ctx, prefix + "resource-list_length", String.valueOf(rdlist.size()));
147 for (int i = 0; i < rdlist.size(); i++) {
148 ResourceData rd = rdlist.get(i);
150 String pp = prefix + "resource-list[" + i + "].";
152 setAttr(ctx, pp + "resource-name", rd.resourceName);
153 setAttr(ctx, pp + "endpoint-position", rd.endPointPosition);
154 setAttr(ctx, pp + "resource-target-type", rd.resourceTargetType);
155 setAttr(ctx, pp + "resource-target-id", rd.resourceTargetId);
157 setAttr(ctx, pp + "resource-target-value", rd.resourceTargetValue);
158 setAttr(ctx, pp + "status", rd.status);
160 if (rd.data != null && !rd.data.isEmpty()) {
161 for (String kk : rd.data.keySet()) {
162 String value = String.valueOf(rd.data.get(kk));
163 setAttr(ctx, pp + kk, value);
170 public QueryStatus reserve(String resource, String select, String key, String prefix, SvcLogicContext ctx)
171 throws SvcLogicException {
172 return allocateResources(ctx, false, prefix);
175 public AllocationStatus reserve(ResourceEntity sd, ResourceTarget rt, ResourceRequest rr,
176 List<ResourceResponse> rsList) throws Exception {
177 return allocateResources(sd, rt, rr, rsList);
181 public QueryStatus release(String resource, String key, SvcLogicContext ctx) throws SvcLogicException {
182 String resourceEntityId = getParam(ctx,
183 new String[] { "service-instance-id", "reservation-entity-id", "resource-entity-id" }, true, null);
184 String resourceEntityType = getParam(ctx, new String[] { "reservation-entity-type", "resource-entity-type" },
186 String resourceEntityVersion = getParam(ctx,
187 new String[] { "reservation-entity-version", "resource-entity-version" }, false, null);
189 String endPointPosition = getParam(ctx, "endpoint-position", false, null);
191 ResourceEntity sd = new ResourceEntity();
192 sd.resourceEntityId = resourceEntityId;
193 sd.resourceEntityType = resourceEntityType;
194 sd.resourceEntityVersion = resourceEntityVersion;
196 ResourceRequest rr = new ResourceRequest();
197 rr.endPointPosition = endPointPosition;
200 this.release(sd, rr);
201 } catch (Exception e) {
202 throw new SvcLogicException(e.getMessage());
204 return QueryStatus.SUCCESS;
207 public AllocationStatus release(ResourceEntity sd) throws Exception {
209 if (sd.resourceEntityVersion != null) {
210 String resourceSet = sd.resourceEntityType + "::" + sd.resourceEntityId + "::" + sd.resourceEntityVersion;
211 log.info(START_RELEASE_LC, resourceSet);
213 resourceManager.releaseResourceSet(resourceSet);
215 String resourceUnion = sd.resourceEntityType + "::" + sd.resourceEntityId;
216 log.info(START_RELEASE_LC, resourceUnion);
218 resourceManager.releaseResourceUnion(resourceUnion);
221 return AllocationStatus.Success;
225 public AllocationStatus release(ResourceEntity sd, ResourceRequest rr) throws Exception {
227 if (sd != null && sd.resourceEntityVersion != null) {
228 if (rr != null && rr.endPointPosition != null && !rr.endPointPosition.isEmpty()) {
229 String resourceSet = sd.resourceEntityType + "::" + sd.resourceEntityId + "::" + rr.endPointPosition
230 + "::" + sd.resourceEntityVersion;
231 log.info(START_RELEASE_LC, resourceSet);
232 resourceManager.releaseResourceSet(resourceSet);
235 String resourceSet = sd.resourceEntityType + "::" + sd.resourceEntityId + "::"
236 + sd.resourceEntityVersion;
237 log.info(START_RELEASE_LC, resourceSet);
238 resourceManager.releaseResourceSet(resourceSet);
241 } else if (sd != null && (sd.resourceEntityVersion == null || sd.resourceEntityVersion.isEmpty())) {
242 if (rr != null && rr.endPointPosition != null && !rr.endPointPosition.isEmpty()) {
243 String resourceUnion = sd.resourceEntityType + "::" + sd.resourceEntityId + "::" + rr.endPointPosition;
244 log.info(START_RELEASE_LC, resourceUnion);
245 resourceManager.releaseResourceUnion(resourceUnion);
248 String resourceUnion = sd.resourceEntityType + "::" + sd.resourceEntityId;
249 log.info(START_RELEASE_LC, resourceUnion);
250 resourceManager.releaseResourceUnion(resourceUnion);
254 return AllocationStatus.Success;
258 private QueryStatus allocateResources(SvcLogicContext ctx, boolean checkOnly, String prefix)
259 throws SvcLogicException {
260 String serviceModel = getParam(ctx, "service-model", true, null);
261 String requestType = getParam(ctx, "request-type", false, "New");
263 ResourceEntity sd = getResourceEntityData(ctx);
264 ResourceTarget rt = getResourceTargetData(ctx);
265 ResourceRequest rr = getResourceRequest(ctx);
267 log.info("Starting reserve: " + requestType + ", service-model: " + serviceModel);
268 StrUtil.info(log, sd);
269 StrUtil.info(log, rt);
270 StrUtil.info(log, rr);
272 boolean change = requestType.equalsIgnoreCase("change");
274 List<ResourceData> rlist = endPointAllocator.allocateResources(serviceModel, sd, rt, rr, checkOnly, change);
276 if (rlist != null && !rlist.isEmpty()) {
277 setResourceDataInContext(ctx, prefix, rlist);
279 for (ResourceData rd : rlist) {
280 if (!rd.status.equals("Success")) {
281 log.info("Capacity not found for: " + sd.resourceEntityType + "::" + sd.resourceEntityId);
282 return QueryStatus.NOT_FOUND;
286 return QueryStatus.SUCCESS;
289 private AllocationStatus allocateResources(ResourceEntity sd, ResourceTarget rt, ResourceRequest rr,
290 List<ResourceResponse> rsList) throws Exception {
292 String serviceModel = rr.serviceModel;
293 String requestType = rr.requestType == null ? "New" : rr.requestType;
295 log.info("Starting reserve: " + requestType + ", service-model: " + serviceModel);
296 StrUtil.info(log, sd);
297 StrUtil.info(log, rt);
298 StrUtil.info(log, rr);
300 boolean change = requestType.equalsIgnoreCase("change");
302 List<ResourceData> rlist = endPointAllocator.allocateResources(serviceModel, sd, rt, rr, rr.checkOnly, change);
304 if (rlist != null && !rlist.isEmpty()) {
305 setResourceDataInResponse(rlist, rsList);
307 for (ResourceData rd : rlist) {
308 if (!rd.status.equals("Success")) {
309 log.info("Capacity not found for: " + sd.resourceEntityType + "::" + sd.resourceEntityId);
310 return AllocationStatus.ResourceNotFound;
315 return AllocationStatus.Success;
318 private void setResourceDataInResponse(List<ResourceData> rlist, List<ResourceResponse> rsList) {
319 for (ResourceData rd : emptyIfNull(rlist)) {
320 ResourceResponse res = new ResourceResponse();
321 res.resourceName = rd.resourceName;
322 res.endPointPosition = rd.endPointPosition;
323 res.resourceTargetId = rd.resourceTargetId;
324 res.resourceTargetType = rd.resourceTargetType;
325 res.status = rd.status;
326 if (rd.data != null && !rd.data.isEmpty()) {
327 for (String kk : rd.data.keySet()) {
328 if (kk.equalsIgnoreCase("allocated")) {
329 res.resourceAllocated = String.valueOf(rd.data.get(kk));
332 if (kk.equalsIgnoreCase("used")) {
333 res.resourceUsed = String.valueOf(rd.data.get(kk));
336 if (kk.equalsIgnoreCase("available")) {
337 res.resourceAvailable = String.valueOf(rd.data.get(kk));
340 if (kk.equalsIgnoreCase("limit")) {
341 res.resourceLimit = String.valueOf(rd.data.get(kk));
351 public static <T> Iterable<T> emptyIfNull(Iterable<T> iterable) {
352 return iterable == null ? Collections.<T>emptyList() : iterable;
355 private void setAttr(SvcLogicContext ctx, String name, String value) {
356 ctx.setAttribute(name, value);
357 log.info("Added context attr: " + name + ": " + value);
360 private ResourceEntity getResourceEntityData(SvcLogicContext ctx) throws SvcLogicException {
361 ResourceEntity sd = new ResourceEntity();
362 sd.resourceEntityId = getParam(ctx,
363 new String[] { "service-instance-id", "reservation-entity-id", "resource-entity-id" }, true, null);
364 sd.resourceEntityType = getParam(ctx, new String[] { "reservation-entity-type", "resource-entity-type" }, true,
366 sd.resourceEntityVersion = getParam(ctx,
367 new String[] { "reservation-entity-version", "resource-entity-version" }, false, "1");
368 sd.data = getDataParam(ctx, "reservation-entity-data", "resource-entity-data", "service-data");
372 private ResourceTarget getResourceTargetData(SvcLogicContext ctx) throws SvcLogicException {
373 ResourceTarget sd = new ResourceTarget();
374 sd.resourceTargetId = getParam(ctx, new String[] { "reservation-target-id", "resource-target-id" }, true, null);
375 sd.resourceTargetType = getParam(ctx, new String[] { "reservation-target-type", "resource-target-type" }, true,
377 sd.data = getDataParam(ctx, "reservation-target-data", "resource-target-data", "equipment-data");
381 private ResourceRequest getResourceRequest(SvcLogicContext ctx) throws SvcLogicException {
382 ResourceRequest rr = new ResourceRequest();
383 rr.resourceName = getParam(ctx, "resource-name", false, null);
384 rr.resourceShareGroup = getParam(ctx, "resource-share-group", false, null);
385 rr.rangeRequestedNumbers = getParam(ctx, "range-requested-numbers", false, null);
386 rr.rangeExcludeNumbers = getParam(ctx, "range-exclude-numbers", false, null);
387 String rangeReverseOrderStr = getParam(ctx, "range-reverse-order", false, "false");
388 rr.rangeReverseOrder = Boolean.parseBoolean(rangeReverseOrderStr);
389 String rangeMinOverrideStr = getParam(ctx, "range-min-override", false, "-1");
390 rr.rangeMinOverride = Integer.parseInt(rangeMinOverrideStr);
391 String rangeMaxOverrideStr = getParam(ctx, "range-max-override", false, "-1");
392 rr.rangeMaxOverride = Integer.parseInt(rangeMaxOverrideStr);
393 String rangeForceNewNumbersStr = getParam(ctx, "range-force-new-numbers", false, "false");
394 rr.rangeForceNewNumbers = Boolean.parseBoolean(rangeForceNewNumbersStr);
395 String replaceStr = getParam(ctx, "replace", false, "true");
396 rr.replace = Boolean.parseBoolean(replaceStr);
397 rr.applicationId = getParam(ctx, "application-id", false, "SDNC");
398 rr.endPointPosition = getParam(ctx, "endpoint-position", false, null);
402 private String getParam(SvcLogicContext ctx, String name, boolean required, String def) throws SvcLogicException {
404 for (String p : INPUT_PREFIX) {
405 v = ctx.getAttribute(p + name);
406 if (v != null && v.trim().length() > 0) {
407 log.info("Param: " + name + ": " + v.trim());
412 throw new SvcLogicException("The following variable is required in DG context: " + name);
415 log.info("Param: " + name + " not supplied. Using default: " + def);
419 private String getParam(SvcLogicContext ctx, String[] names, boolean required, String def)
420 throws SvcLogicException {
422 for (String name : names) {
423 v = getParam(ctx, name, false, def);
429 throw new SvcLogicException(
430 "One of the following variable is required in DG context: " + Arrays.deepToString(names));
433 log.info("Param: " + names + " not supplied. Using default: " + def);
437 private Map<String, String> getDataParam(SvcLogicContext ctx, String... names) {
438 Map<String, String> data = new HashMap<>();
439 Set<String> ctxNames = ctx.getAttributeKeySet();
440 for (String n : ctxNames) {
441 for (String p : INPUT_PREFIX) {
442 for (String name : names) {
443 String pp = p + name + '.';
444 if (n.startsWith(pp)) {
445 String nn = n.substring(pp.length());
446 String vv = ctx.getAttribute(n);
449 log.info("Data param: " + nn + ": " + vv);
451 if (ctxNames.contains(n + "-unit")) {
453 long v = Long.parseLong(vv);
454 String unit = ctx.getAttribute(n + "-unit");
455 long kbps = speedUtil.convertToKbps(v, unit);
456 long mbps = speedUtil.convertToMbps(v, unit);
457 data.put(nn + "-kbps", String.valueOf(kbps));
458 data.put(nn + "-mbps", String.valueOf(mbps));
460 log.info("Data param: " + nn + "-kbps: " + kbps);
461 log.info("Data param: " + nn + "-mbps: " + mbps);
463 } catch (Exception e) {
464 log.warn("Invalid number for " + n + ": " + vv);
474 public void setResourceManager(ResourceManager resourceManager) {
475 this.resourceManager = resourceManager;
478 public void setEndPointAllocator(EndPointAllocator endPointAllocator) {
479 this.endPointAllocator = endPointAllocator;
482 public void setSpeedUtil(SpeedUtil speedUtil) {
483 this.speedUtil = speedUtil;