[CCSDK-6] Populate seed code
[ccsdk/sli/adaptors.git] / resource-assignment / provider / src / main / java / org / openecomp / sdnc / ra / ResourceAllocator.java
1 /*-
2  * ============LICENSE_START=======================================================
3  * openECOMP : SDN-C
4  * ================================================================================
5  * Copyright (C) 2017 ONAP Intellectual Property. All rights
6  *                                              reserved.
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
11  * 
12  *      http://www.apache.org/licenses/LICENSE-2.0
13  * 
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=========================================================
20  */
21
22 package org.openecomp.sdnc.ra;
23
24 import java.util.ArrayList;
25 import java.util.Collections;
26 import java.util.Comparator;
27 import java.util.HashMap;
28 import java.util.List;
29 import java.util.Map;
30
31 import org.onap.ccsdk.sli.core.sli.SvcLogicContext;
32 import org.onap.ccsdk.sli.core.sli.SvcLogicException;
33 import org.onap.ccsdk.sli.core.sli.SvcLogicResource;
34 import org.onap.ccsdk.sli.core.sli.SvcLogicResource.QueryStatus;
35 import org.openecomp.sdnc.ra.comp.EndPointAllocator;
36 import org.openecomp.sdnc.ra.comp.EndPointData;
37 import org.openecomp.sdnc.ra.comp.ServiceData;
38 import org.openecomp.sdnc.ra.equip.dao.ServerDao;
39 import org.openecomp.sdnc.ra.equip.dao.VpePortDao;
40 import org.openecomp.sdnc.ra.equip.dao.VplspePortDao;
41 import org.openecomp.sdnc.ra.equip.data.EquipmentData;
42 import org.openecomp.sdnc.ra.equip.data.EquipmentLevel;
43 import org.openecomp.sdnc.ra.rule.comp.AllocationRequestBuilder;
44 import org.openecomp.sdnc.ra.rule.dao.MaxPortSpeedDao;
45 import org.openecomp.sdnc.ra.rule.dao.MaxServerSpeedDao;
46 import org.openecomp.sdnc.ra.rule.dao.ParameterDao;
47 import org.openecomp.sdnc.ra.rule.data.ThresholdStatus;
48 import org.openecomp.sdnc.ra.service.dao.ServiceResourceDao;
49 import org.openecomp.sdnc.ra.service.data.ServiceResource;
50 import org.openecomp.sdnc.ra.service.data.ServiceStatus;
51 import org.openecomp.sdnc.rm.comp.ResourceManager;
52 import org.openecomp.sdnc.rm.data.AllocationAction;
53 import org.openecomp.sdnc.rm.data.AllocationItem;
54 import org.openecomp.sdnc.rm.data.AllocationOutcome;
55 import org.openecomp.sdnc.rm.data.AllocationRequest;
56 import org.openecomp.sdnc.rm.data.AllocationStatus;
57 import org.openecomp.sdnc.rm.data.LimitAllocationOutcome;
58 import org.openecomp.sdnc.rm.data.LimitAllocationRequest;
59 import org.openecomp.sdnc.rm.data.LimitResource;
60 import org.openecomp.sdnc.rm.data.MultiResourceAllocationOutcome;
61 import org.openecomp.sdnc.rm.data.RangeAllocationItem;
62 import org.openecomp.sdnc.rm.data.RangeResource;
63 import org.openecomp.sdnc.rm.data.Resource;
64 import org.openecomp.sdnc.util.speed.SpeedUtil;
65 import org.openecomp.sdnc.util.str.StrUtil;
66 import org.slf4j.Logger;
67 import org.slf4j.LoggerFactory;
68
69 public class ResourceAllocator implements SvcLogicResource {
70
71         private static final Logger log = LoggerFactory.getLogger(ResourceAllocator.class);
72
73         public ResourceAllocator() {
74                 log.info("ResourceAllocator created.");
75         }
76
77         private ServerDao serverDao;
78         private VpePortDao vpePortDao;
79         private VplspePortDao vplspePortDao;
80         private MaxPortSpeedDao maxPortSpeedDao;
81         private MaxServerSpeedDao maxServerSpeedDao;
82         private ServiceResourceDao serviceResourceDao;
83         private ParameterDao parameterDao;
84
85         private AllocationRequestBuilder allocationRequestBuilder;
86         private ResourceManager resourceManager;
87         private SpeedUtil speedUtil;
88
89         private EndPointAllocator endPointAllocator;
90
91         @Override
92         public QueryStatus notify(String resource, String action, String key, SvcLogicContext ctx)
93                 throws SvcLogicException {
94                 return (QueryStatus.SUCCESS);
95         }
96
97         @Override
98         public QueryStatus update(
99                 String resource,
100                 String key,
101                 Map<String, String> parms,
102                 String prefix,
103                 SvcLogicContext ctx) throws SvcLogicException {
104
105                 return QueryStatus.SUCCESS;
106         }
107
108         @Override
109         public QueryStatus exists(String resource, String key, String prefix, SvcLogicContext ctx)
110                 throws SvcLogicException {
111                 return QueryStatus.SUCCESS;
112         }
113
114         @Override
115         public QueryStatus delete(String arg0, String arg1, SvcLogicContext arg2) throws SvcLogicException {
116                 return QueryStatus.SUCCESS;
117         }
118
119         @Override
120         public QueryStatus save(
121                 String arg0,
122                 boolean arg1,
123                 boolean arg2,
124                 String arg3,
125                 Map<String, String> arg4,
126                 String arg5,
127                 SvcLogicContext arg6) throws SvcLogicException {
128                 return QueryStatus.SUCCESS;
129         }
130
131         @Override
132         public QueryStatus isAvailable(String resource, String key, String prefix, SvcLogicContext ctx)
133                 throws SvcLogicException {
134                 String serviceModel = ctx.getAttribute("tmp.resource-allocator.service-model");
135                 if (serviceModel != null && serviceModel.trim().length() > 0)
136                         return allocateResources(serviceModel, ctx, true, prefix);
137                 return allocateResourcesL3SDN(ctx, true, prefix);
138         }
139
140         @Override
141         public QueryStatus query(
142                 String resource,
143                 boolean localOnly,
144                 String select,
145                 String key,
146                 String prefix,
147                 String orderBy,
148                 SvcLogicContext ctx) throws SvcLogicException {
149
150                 prefix = prefix == null ? "" : prefix + '.';
151
152                 if (!resource.equals("NetworkCapacity")) {
153                         log.info("resource: " + resource);
154                         log.info("key: " + key);
155
156                         Resource r = resourceManager.getResource(resource, key);
157                         if (r == null)
158                                 return QueryStatus.NOT_FOUND;
159
160                         if (r instanceof LimitResource) {
161                                 ctx.setAttribute(prefix + "used", String.valueOf(((LimitResource) r).used));
162
163                                 log.info("Added context attr: " + prefix + "used: " + String.valueOf(((LimitResource) r).used));
164                         }
165
166                         return QueryStatus.SUCCESS;
167                 }
168
169                 log.info("key: " + key);
170                 log.info("prefix: " + prefix);
171
172                 if (key == null)
173                         return QueryStatus.SUCCESS;
174
175                 if (key.startsWith("'") && key.endsWith("'"))
176                         key = key.substring(1, key.length() - 1);
177
178                 String endPointPosition = "VPE-Cust";
179
180                 String resourceUnionId = key + '/' + endPointPosition;
181                 List<Resource> rlist = resourceManager.getResourceUnion(resourceUnionId);
182
183                 log.info("Resources found for " + resourceUnionId + ": " + rlist.size());
184
185                 String assetId = null;
186                 for (Resource r : rlist) {
187                         log.info("Resource: " + r.resourceKey.resourceName);
188
189                         if (r instanceof RangeResource) {
190                                 RangeResource rr = (RangeResource) r;
191                                 for (AllocationItem ai : r.allocationItems)
192                                         if (ai.resourceUnionId.equals(resourceUnionId)) {
193                                                 RangeAllocationItem rai = (RangeAllocationItem) ai;
194                                                 ctx.setAttribute(prefix + r.resourceKey.resourceName, String.valueOf(rai.used.first()));
195
196                                                 log.info("Added context attr: " + prefix + r.resourceKey.resourceName + ": " +
197                                                         String.valueOf(rr.used.first()));
198
199                                                 assetId = r.resourceKey.assetId;
200                                                 String vpeName = assetId;
201                                                 int i1 = assetId.indexOf('/');
202                                                 if (i1 > 0)
203                                                         vpeName = assetId.substring(0, i1);
204                                                 ctx.setAttribute(prefix + "vpe-name", vpeName);
205
206                                                 log.info("Added context attr: " + prefix + "vpe-name: " + vpeName);
207                                         }
208                         }
209                 }
210
211                 String affinityLink = "1";
212                 if (assetId != null) {
213                         for (Resource r : rlist) {
214                                 if (r instanceof LimitResource) {
215                                         LimitResource ll = (LimitResource) r;
216                                         if (ll.resourceKey.assetId.startsWith(assetId + '-')) {
217                                                 int i1 = ll.resourceKey.assetId.lastIndexOf('-');
218                                                 affinityLink = ll.resourceKey.assetId.substring(i1 + 1);
219                                                 break;
220                                         }
221                                 }
222                         }
223                 }
224
225                 ctx.setAttribute(prefix + "affinity-link", affinityLink);
226
227                 log.info("Added context attr: " + prefix + "affinity-link: " + affinityLink);
228
229                 return QueryStatus.SUCCESS;
230         }
231
232         @Override
233         public QueryStatus reserve(String resource, String select, String key, String prefix, SvcLogicContext ctx)
234                 throws SvcLogicException {
235                 String serviceModel = ctx.getAttribute("tmp.resource-allocator.service-model");
236                 if (serviceModel != null && serviceModel.trim().length() > 0)
237                         return allocateResources(serviceModel, ctx, false, prefix);
238                 return allocateResourcesL3SDN(ctx, false, prefix);
239         }
240
241         @Override
242         public QueryStatus release(String resource, String key, SvcLogicContext ctx) throws SvcLogicException {
243                 String serviceInstanceId = ctx.getAttribute("tmp.resource-allocator.service-instance-id");
244                 if (serviceInstanceId == null)
245                         throw new SvcLogicException("tmp.resource-allocator.service-instance-id is required in ResourceAllocator");
246
247                 String requestTypeStr = ctx.getAttribute("tmp.resource-allocator.request-type");
248                 if (requestTypeStr == null)
249                         throw new SvcLogicException("tmp.resource-allocator.request-type is required in ResourceAllocator");
250
251                 ReleaseRequestType requestType = null;
252                 try {
253                         requestType = ReleaseRequestType.convert(requestTypeStr);
254                 } catch (IllegalArgumentException e) {
255                         throw new SvcLogicException("Invalid tmp.resource-allocator.request-type: " + requestTypeStr +
256                                 ". Supported values are Cancel, Activate, Disconnect.");
257                 }
258
259                 log.info("Starting release: " + requestType + " for: " + serviceInstanceId);
260
261                 ServiceResource activeServiceResource =
262                         serviceResourceDao.getServiceResource(serviceInstanceId, ServiceStatus.Active);
263                 ServiceResource pendingServiceResource =
264                         serviceResourceDao.getServiceResource(serviceInstanceId, ServiceStatus.Pending);
265
266                 log.info("Active ServiceResource: ");
267                 StrUtil.info(log, activeServiceResource);
268                 log.info("Pending ServiceResource: ");
269                 StrUtil.info(log, pendingServiceResource);
270
271                 if (requestType == ReleaseRequestType.Cancel) {
272                         if (pendingServiceResource != null) {
273                                 log.info("Releasing pending resources: " + pendingServiceResource.resourceSetId);
274
275                                 resourceManager.releaseResourceSet(pendingServiceResource.resourceSetId);
276                                 serviceResourceDao.deleteServiceResource(serviceInstanceId, ServiceStatus.Pending);
277                         } else {
278                                 log.info("Pending record not found for service instance: " + serviceInstanceId + ". Nothing to do.");
279                         }
280
281                 } else if (requestType == ReleaseRequestType.Activate) {
282                         if (pendingServiceResource != null) {
283                                 if (activeServiceResource != null) {
284                                         log.info("Releasing active resources: " + activeServiceResource.resourceSetId);
285
286                                         resourceManager.releaseResourceSet(activeServiceResource.resourceSetId);
287                                         serviceResourceDao.deleteServiceResource(serviceInstanceId, ServiceStatus.Active);
288                                 }
289
290                                 log.info("Updating the status of the pending record to active.");
291
292                                 serviceResourceDao.updateServiceStatus(serviceInstanceId, ServiceStatus.Pending, ServiceStatus.Active);
293                         } else {
294                                 log.info("Pending record not found for service instance: " + serviceInstanceId + ". Nothing to do.");
295                         }
296
297                 } else if (requestType == ReleaseRequestType.Disconnect) {
298                         if (pendingServiceResource != null) {
299                                 log.info("Releasing pending resources: " + pendingServiceResource.resourceSetId);
300
301                                 resourceManager.releaseResourceSet(pendingServiceResource.resourceSetId);
302                                 serviceResourceDao.deleteServiceResource(serviceInstanceId, ServiceStatus.Pending);
303                         }
304                         if (activeServiceResource != null) {
305                                 log.info("Releasing active resources: " + activeServiceResource.resourceSetId);
306
307                                 resourceManager.releaseResourceSet(activeServiceResource.resourceSetId);
308                                 serviceResourceDao.deleteServiceResource(serviceInstanceId, ServiceStatus.Active);
309                         }
310                 }
311
312                 return QueryStatus.SUCCESS;
313         }
314
315         private QueryStatus allocateResourcesL3SDN(SvcLogicContext ctx, boolean checkOnly, String prefix)
316                 throws SvcLogicException {
317                 prefix = prefix == null ? "" : prefix + '.';
318
319                 String aicSiteId = getAicSiteId(ctx);
320                 Map<String, Object> service = getServiceData(ctx);
321
322                 String requestTypeStr = ctx.getAttribute("tmp.resource-allocator.request-type");
323                 if (requestTypeStr == null)
324                         requestTypeStr = "New";
325
326                 ReserveRequestType requestType = null;
327                 try {
328                         requestType = ReserveRequestType.convert(requestTypeStr);
329                 } catch (IllegalArgumentException e) {
330                         throw new SvcLogicException("Invalid tmp.resource-allocator.request-type: " + requestTypeStr +
331                                 ". Supported values are New, Change.");
332                 }
333
334                 String serviceInstanceId = String.valueOf(service.get("service-instance-id"));
335
336                 ServiceResource activeServiceResource =
337                         serviceResourceDao.getServiceResource(serviceInstanceId, ServiceStatus.Active);
338                 ServiceResource pendingServiceResource =
339                         serviceResourceDao.getServiceResource(serviceInstanceId, ServiceStatus.Pending);
340
341                 log.info("Active ServiceResource: ");
342                 StrUtil.info(log, activeServiceResource);
343                 log.info("Pending ServiceResource: ");
344                 StrUtil.info(log, pendingServiceResource);
345
346                 ServiceResource sr = new ServiceResource();
347                 sr.serviceInstanceId = serviceInstanceId;
348                 sr.serviceStatus = ServiceStatus.Pending;
349                 sr.serviceChangeNumber = 1;
350                 if (pendingServiceResource != null)
351                         sr.serviceChangeNumber = pendingServiceResource.serviceChangeNumber + 1;
352                 else if (activeServiceResource != null)
353                         sr.serviceChangeNumber = activeServiceResource.serviceChangeNumber + 1;
354                 sr.resourceSetId = serviceInstanceId + "/" + sr.serviceChangeNumber;
355                 sr.resourceUnionId = serviceInstanceId;
356
357                 log.info("New ServiceResource: ");
358                 StrUtil.info(log, sr);
359
360                 List<Map<String, Object>> vpePortData = vpePortDao.getVpePortData(aicSiteId);
361                 List<Map<String, Object>> vplspePortData = vplspePortDao.getVplspePortData(aicSiteId);
362                 List<Map<String, Object>> serverData = serverDao.getServerData(aicSiteId);
363
364                 vpePortData = orderVpe(vpePortData);
365
366                 long maxAvailableSpeedVpePort = 0;
367                 boolean vpePortFound = false;
368
369                 for (Map<String, Object> vpe : vpePortData) {
370                         String vpeId = String.valueOf(vpe.get("vpe-id"));
371                         String interfaceName = String.valueOf(vpe.get("physical-interface-name"));
372                         String portId = vpeId + "/" + interfaceName;
373
374                         log.info("Checking VPE port: " + portId);
375
376                         String provStatus = String.valueOf(vpe.get("provisioning-status"));
377                         if (!provStatus.equals("PROV")) {
378                                 log.info("Skipping port " + portId + ": Provisioning status is not PROV.");
379                                 continue;
380                         }
381
382                         String imageFile = String.valueOf(vpe.get("image-file-name"));
383                         String endPointPosition = "VPE-Cust";
384                         long maxPortSpeed = maxPortSpeedDao.getMaxPortSpeed(imageFile, endPointPosition, interfaceName);
385                         vpe.put("max-port-speed", maxPortSpeed);
386
387                         EquipmentData ed = new EquipmentData();
388                         ed.data = vpe;
389                         ed.equipmentId = portId;
390                         ed.equipmentLevel = EquipmentLevel.Port;
391
392                         ServiceData sd = new ServiceData();
393                         sd.data = service;
394                         sd.serviceModel = "L3SDN";
395                         sd.endPointPosition = endPointPosition;
396                         sd.resourceUnionId = sr.resourceUnionId;
397                         sd.resourceSetId = sr.resourceSetId;
398
399                         StrUtil.info(log, ed);
400                         StrUtil.info(log, sd);
401
402                         AllocationRequest ar = allocationRequestBuilder.buildAllocationRequest(sd, ed, checkOnly,
403                                 requestType == ReserveRequestType.Change);
404                         AllocationOutcome ao = resourceManager.allocateResources(ar);
405
406                         if (ao.status == AllocationStatus.Success) {
407
408                                 // Assign affinity link
409                                 if (!checkOnly) {
410                                         List<String> affinityLinkIdList = new ArrayList<>();
411                                         affinityLinkIdList.add("0");
412                                         affinityLinkIdList.add("1");
413                                         affinityLinkIdList.add("2");
414                                         affinityLinkIdList.add("3");
415
416                                         String preferedAffinityLinkId = "0";
417                                         long lowestAssignedBw = Long.MAX_VALUE;
418                                         for (String affinityLinkId : affinityLinkIdList) {
419                                                 long used = 0;
420                                                 String assetId = ed.equipmentId + "-" + affinityLinkId;
421                                                 Resource r = resourceManager.getResource("Bandwidth", assetId);
422                                                 if (r != null) {
423                                                         LimitResource ll = (LimitResource) r;
424                                                         used = ll.used;
425                                                 }
426                                                 if (used < lowestAssignedBw) {
427                                                         lowestAssignedBw = used;
428                                                         preferedAffinityLinkId = affinityLinkId;
429                                                 }
430                                                 log.info("Assigned bandwidth on affinity link: " + assetId + ": " + used);
431                                         }
432
433                                         log.info("Prefered affinity link for " + ed.equipmentId + ": " + preferedAffinityLinkId);
434
435                                         ctx.setAttribute(prefix + "affinity-link", preferedAffinityLinkId);
436
437                                         LimitAllocationRequest ar1 = new LimitAllocationRequest();
438                                         ar1.resourceSetId = sd.resourceSetId;
439                                         ar1.resourceUnionId = sd.resourceUnionId;
440                                         ar1.resourceShareGroupList = null;
441                                         ar1.resourceName = "Bandwidth";
442                                         ar1.assetId = ed.equipmentId + "-" + preferedAffinityLinkId;
443                                         ar1.missingResourceAction = AllocationAction.Succeed_Allocate;
444                                         ar1.expiredResourceAction = AllocationAction.Succeed_Allocate;
445                                         ar1.replace = true;
446                                         ar1.strict = false;
447                                         ar1.checkLimit = Long.MAX_VALUE;
448                                         ar1.checkCount = 0;
449                                         ar1.allocateCount = (Long) sd.data.get("service-speed-kbps");
450
451                                         resourceManager.allocateResources(ar1);
452                                 }
453
454                                 ctx.setAttribute(prefix + "vpe-name", vpeId);
455
456                                 vpePortFound = true;
457                                 break;
458                         }
459
460                         if (ao instanceof LimitAllocationOutcome) {
461                                 LimitAllocationOutcome lao = (LimitAllocationOutcome) ao;
462                                 long available = lao.limit - lao.used;
463                                 if (available > maxAvailableSpeedVpePort)
464                                         maxAvailableSpeedVpePort = available;
465                         }
466                 }
467
468                 long maxAvailableSpeedVplspePort = 0;
469                 boolean vplspePortFound = false;
470
471                 for (Map<String, Object> vplspe : vplspePortData) {
472                         String vplspeId = String.valueOf(vplspe.get("vplspe-id"));
473                         String interfaceName = String.valueOf(vplspe.get("physical-interface-name"));
474                         String portId = vplspeId + "/" + interfaceName;
475
476                         log.info("Checking VPLSPE port: " + portId);
477
478                         String provStatus = String.valueOf(vplspe.get("provisioning-status"));
479                         if (!provStatus.equals("PROV")) {
480                                 log.info("Skipping port " + portId + ": Provisioning status is not PROV.");
481                                 continue;
482                         }
483
484                         long physicalSpeed = (Long) vplspe.get("physical-interface-speed");
485                         String physicalSpeedUnit = String.valueOf(vplspe.get("physical-interface-speed-unit"));
486                         long maxPortSpeed = speedUtil.convertToKbps(physicalSpeed, physicalSpeedUnit);
487                         vplspe.put("max-port-speed", maxPortSpeed);
488
489                         EquipmentData ed = new EquipmentData();
490                         ed.data = vplspe;
491                         ed.equipmentId = portId;
492                         ed.equipmentLevel = EquipmentLevel.Port;
493
494                         ServiceData sd = new ServiceData();
495                         sd.data = service;
496                         sd.serviceModel = "L3SDN";
497                         sd.endPointPosition = "IPAG-TOA";
498                         sd.resourceUnionId = sr.resourceUnionId;
499                         sd.resourceSetId = sr.resourceSetId;
500
501                         StrUtil.info(log, ed);
502                         StrUtil.info(log, sd);
503
504                         AllocationRequest ar = allocationRequestBuilder.buildAllocationRequest(sd, ed, checkOnly,
505                                 requestType == ReserveRequestType.Change);
506                         AllocationOutcome ao = resourceManager.allocateResources(ar);
507
508                         if (ao.status == AllocationStatus.Success) {
509                                 vplspePortFound = true;
510                                 break;
511                         }
512
513                         if (ao instanceof LimitAllocationOutcome) {
514                                 LimitAllocationOutcome lao = (LimitAllocationOutcome) ao;
515                                 long available = lao.limit - lao.used;
516                                 if (available > maxAvailableSpeedVplspePort)
517                                         maxAvailableSpeedVplspePort = available;
518                         }
519                 }
520
521                 long maxAvailableSpeedServer = 0;
522                 boolean serverFound = false;
523
524                 for (Map<String, Object> server : serverData) {
525                         String serverId = String.valueOf(server.get("server-id"));
526                         String serverModel = String.valueOf(server.get("server-model"));
527
528                         log.info("Checking Server: " + serverId);
529
530                         String endPointPosition = "VCE-Cust";
531
532                         int serverCount = (Integer) server.get("server-count");
533                         if (serverCount == 0)
534                                 serverCount = 1;
535                         String ratioString = parameterDao.getParameter("homing.pserver.sparing.ratio");
536                         if (ratioString == null || ratioString.length() == 0)
537                                 ratioString = "1:1";
538                         int primaryServerCount = calculatePrimaryServerCount(serverCount, ratioString);
539                         server.put("number-primary-servers", primaryServerCount);
540
541                         int evcCount = getEvcCountOnServer(serverId);
542                         int evcCountPerServer = (evcCount + primaryServerCount - 1) / primaryServerCount;
543                         long maxServerSpeed = maxServerSpeedDao.getMaxServerSpeed(serverModel, evcCountPerServer);
544                         server.put("max-server-speed", maxServerSpeed);
545                         server.put("evc-count", evcCount);
546                         server.put("evc-count-per-server", evcCountPerServer);
547
548                         EquipmentData ed = new EquipmentData();
549                         ed.data = server;
550                         ed.equipmentId = serverId;
551                         ed.equipmentLevel = EquipmentLevel.Server;
552
553                         ServiceData sd = new ServiceData();
554                         sd.data = service;
555                         sd.serviceModel = "L3SDN";
556                         sd.endPointPosition = endPointPosition;
557                         sd.resourceUnionId = sr.resourceUnionId;
558                         sd.resourceSetId = sr.resourceSetId;
559
560                         StrUtil.info(log, ed);
561                         StrUtil.info(log, sd);
562
563                         AllocationRequest ar = allocationRequestBuilder.buildAllocationRequest(sd, ed, checkOnly,
564                                 requestType == ReserveRequestType.Change);
565                         AllocationOutcome ao = resourceManager.allocateResources(ar);
566
567                         if (ao.status == AllocationStatus.Success) {
568                                 serverFound = true;
569
570                                 if (ao instanceof MultiResourceAllocationOutcome) {
571                                         MultiResourceAllocationOutcome mrao = (MultiResourceAllocationOutcome) ao;
572                                         for (AllocationOutcome ao1 : mrao.allocationOutcomeList) {
573                                                 if (ao1 instanceof LimitAllocationOutcome) {
574                                                         LimitAllocationOutcome lao = (LimitAllocationOutcome) ao1;
575                                                         if (lao.request.resourceName.equals("Bandwidth")) {
576                                                                 ThresholdStatus th = allocationRequestBuilder.getThresholdStatus(sd, ed, lao);
577                                                                 setThresholdData(ctx, th, sd, ed);
578                                                         }
579                                                 }
580                                         }
581                                 }
582
583                                 break;
584                         }
585
586                         if (ao instanceof MultiResourceAllocationOutcome) {
587                                 MultiResourceAllocationOutcome mrao = (MultiResourceAllocationOutcome) ao;
588                                 for (AllocationOutcome ao1 : mrao.allocationOutcomeList) {
589                                         if (ao1 instanceof LimitAllocationOutcome) {
590                                                 LimitAllocationOutcome lao = (LimitAllocationOutcome) ao1;
591                                                 if (lao.status == AllocationStatus.Failure && lao.request.resourceName.equals("Bandwidth")) {
592                                                         long available = lao.limit - lao.used;
593                                                         if (available > maxAvailableSpeedServer)
594                                                                 maxAvailableSpeedServer = available;
595                                                 }
596                                                 if (lao.status == AllocationStatus.Failure && lao.request.resourceName.equals("Connection")) {
597                                                         maxAvailableSpeedServer = 0;
598                                                         break;
599                                                 }
600
601                                                 ThresholdStatus th = allocationRequestBuilder.getThresholdStatus(sd, ed, lao);
602                                                 setThresholdData(ctx, th, sd, ed);
603                                         }
604                                 }
605                         }
606                 }
607
608                 if (vpePortFound && vplspePortFound && serverFound) {
609                         if (!checkOnly) {
610                                 if (pendingServiceResource == null) {
611                                         log.info("Adding the pending service resource record to DB.");
612                                         serviceResourceDao.addServiceResource(sr);
613                                 } else {
614                                         log.info("Releasing previously allocated resources for resource set id: " +
615                                                 pendingServiceResource.resourceSetId);
616                                         resourceManager.releaseResourceSet(pendingServiceResource.resourceSetId);
617
618                                         log.info("Updating the pending service resource record in DB with service change number: " +
619                                                 sr.serviceChangeNumber);
620                                         serviceResourceDao.updateServiceResource(sr);
621                                 }
622                         }
623
624                         return QueryStatus.SUCCESS;
625                 }
626
627                 log.info("Releasing allocated resources (if any) for resource set id: " + sr.resourceSetId);
628                 resourceManager.releaseResourceSet(sr.resourceSetId);
629
630                 long maxAvailableSpeed = Long.MAX_VALUE;
631                 if (!vpePortFound && maxAvailableSpeedVpePort < maxAvailableSpeed)
632                         maxAvailableSpeed = maxAvailableSpeedVpePort;
633                 if (!vplspePortFound && maxAvailableSpeedVplspePort < maxAvailableSpeed)
634                         maxAvailableSpeed = maxAvailableSpeedVplspePort;
635                 if (!serverFound && maxAvailableSpeedServer < maxAvailableSpeed)
636                         maxAvailableSpeed = maxAvailableSpeedServer;
637
638                 setOutputContext(ctx, maxAvailableSpeed, "kbps");
639                 return QueryStatus.NOT_FOUND;
640         }
641
642         private List<Map<String, Object>> orderVpe(List<Map<String, Object>> vpePortData) {
643                 for (Map<String, Object> vpe : vpePortData) {
644                         String vpeId = String.valueOf(vpe.get("vpe-id"));
645                         String interfaceName = String.valueOf(vpe.get("physical-interface-name"));
646                         String portId = vpeId + "/" + interfaceName;
647                         Resource r = resourceManager.getResource("Bandwidth", portId);
648                         long used = 0;
649                         if (r != null) {
650                                 LimitResource ll = (LimitResource) r;
651                                 used = ll.used;
652                         }
653                         vpe.put("used-bandwidth", used);
654
655                         log.info("Used bandwidth on VPE: " + vpeId + ": " + used);
656                 }
657
658                 Collections.sort(vpePortData, new Comparator<Map<String, Object>>() {
659
660                         @Override
661                         public int compare(Map<String, Object> o1, Map<String, Object> o2) {
662                                 long used1 = (Long) o1.get("used-bandwidth");
663                                 long used2 = (Long) o2.get("used-bandwidth");
664                                 if (used1 < used2)
665                                         return -1;
666                                 if (used1 > used2)
667                                         return 1;
668                                 return 0;
669                         }
670                 });
671
672                 return vpePortData;
673         }
674
675         private void setThresholdData(SvcLogicContext ctx, ThresholdStatus th, ServiceData sd, EquipmentData ed) {
676                 if (th == null)
677                         return;
678
679                 String pp = "tmp.resource-allocator-output.threshold-notification-list.threshold-hotification[0].";
680                 ctx.setAttribute("tmp.resource-allocator-output.threshold-notification-list.threshold-hotification_length",
681                         "1");
682                 ctx.setAttribute(pp + "message", th.resourceThreshold.message);
683                 ctx.setAttribute(pp + "resource-rule.service-model", th.resourceRule.serviceModel);
684                 ctx.setAttribute(pp + "resource-rule.endpoint-position", th.resourceRule.endPointPosition);
685                 ctx.setAttribute(pp + "resource-rule.resource-name", th.resourceRule.resourceName);
686                 ctx.setAttribute(pp + "resource-rule.equipment-level", th.resourceRule.equipmentLevel);
687                 ctx.setAttribute(pp + "resource-rule.soft-limit-expression", th.resourceRule.softLimitExpression);
688                 ctx.setAttribute(pp + "resource-rule.hard-limit-expression", th.resourceRule.hardLimitExpression);
689                 ctx.setAttribute(pp + "resource-state.used", String.valueOf(th.used));
690                 ctx.setAttribute(pp + "resource-state.limit-value", String.valueOf(th.limitValue));
691                 ctx.setAttribute(pp + "resource-state.threshold-value", String.valueOf(th.thresholdValue));
692                 ctx.setAttribute(pp + "resource-state.last-added", String.valueOf(th.lastAdded));
693                 ctx.setAttribute(pp + "equipment-data.equipment-id", ed.equipmentId);
694                 for (String edKey : ed.data.keySet())
695                         ctx.setAttribute(pp + "equipment-data." + edKey, String.valueOf(ed.data.get(edKey)));
696         }
697
698         private QueryStatus allocateResources(String serviceModel, SvcLogicContext ctx, boolean checkOnly, String prefix)
699                 throws SvcLogicException {
700                 prefix = prefix == null ? "" : prefix + '.';
701
702                 Map<String, Object> service = getServiceData(ctx);
703                 Map<String, Object> ec = getEquipConstraints(ctx);
704
705                 String requestTypeStr = ctx.getAttribute("tmp.resource-allocator.request-type");
706                 if (requestTypeStr == null)
707                         requestTypeStr = "New";
708
709                 ReserveRequestType requestType = null;
710                 try {
711                         requestType = ReserveRequestType.convert(requestTypeStr);
712                 } catch (IllegalArgumentException e) {
713                         throw new SvcLogicException("Invalid tmp.resource-allocator.request-type: " + requestTypeStr +
714                                 ". Supported values are New, Change.");
715                 }
716
717                 String serviceInstanceId = String.valueOf(service.get("service-instance-id"));
718
719                 log.info("Starting reserve: " + requestType + ", service-instance-id: " + serviceInstanceId);
720
721                 ServiceResource activeServiceResource =
722                         serviceResourceDao.getServiceResource(serviceInstanceId, ServiceStatus.Active);
723                 ServiceResource pendingServiceResource =
724                         serviceResourceDao.getServiceResource(serviceInstanceId, ServiceStatus.Pending);
725
726                 log.info("Active ServiceResource: ");
727                 StrUtil.info(log, activeServiceResource);
728                 log.info("Pending ServiceResource: ");
729                 StrUtil.info(log, pendingServiceResource);
730
731                 int changeNumber = 1;
732                 if (pendingServiceResource != null)
733                         changeNumber = pendingServiceResource.serviceChangeNumber + 1;
734                 else if (activeServiceResource != null)
735                         changeNumber = activeServiceResource.serviceChangeNumber + 1;
736
737                 ServiceData sd = new ServiceData();
738                 sd.data = service;
739                 sd.serviceModel = serviceModel;
740                 sd.endPointPosition = (String) service.get("end-point-position");
741                 sd.resourceShareGroup = (String) service.get("resource-share-group");
742                 sd.resourceName = (String) service.get("resource-name");
743                 sd.serviceInstanceId = serviceInstanceId;
744
745                 StrUtil.info(log, sd);
746
747                 List<EndPointData> epList = endPointAllocator.allocateEndPoints(sd, ec, checkOnly,
748                         requestType == ReserveRequestType.Change, changeNumber);
749
750                 if (epList != null && !epList.isEmpty()) {
751                         if (!checkOnly) {
752                                 EndPointData ep = epList.get(0);
753
754                                 if (sd.resourceName == null) {
755                                 ServiceResource sr = new ServiceResource();
756                                 sr.serviceInstanceId = serviceInstanceId;
757                                 sr.serviceStatus = ServiceStatus.Pending;
758                                 sr.serviceChangeNumber = changeNumber;
759                                 sr.resourceSetId = ep.resourceSetId;
760                                 sr.resourceUnionId = ep.resourceUnionId;
761
762                                 log.info("New ServiceResource: ");
763                                 StrUtil.info(log, sr);
764
765                                 if (pendingServiceResource == null) {
766                                         log.info("Adding the pending service resource record to DB.");
767                                         serviceResourceDao.addServiceResource(sr);
768                                 } else {
769                                         log.info("Releasing previously allocated resources for resource set id: " +
770                                                 pendingServiceResource.resourceSetId);
771                                         resourceManager.releaseResourceSet(pendingServiceResource.resourceSetId);
772
773                                         log.info("Updating the pending service resource record in DB with service change number: " +
774                                                 sr.serviceChangeNumber);
775                                         serviceResourceDao.updateServiceResource(sr);
776                                 }
777                         }
778
779                                 for (EndPointData ep1 : epList)
780                                         if (ep1.data != null && !ep1.data.isEmpty())
781                                                 for (String key : ep1.data.keySet()) {
782                                                         String value = String.valueOf(ep1.data.get(key));
783                                                         ctx.setAttribute(prefix + key, value);
784
785                                                         log.info("Added context attr: " + prefix + key + ": " + value);
786                                                 }
787                         }
788
789                         return QueryStatus.SUCCESS;
790                 }
791
792                 log.info("Capacity not found for EVC: " + serviceInstanceId);
793
794                 return QueryStatus.NOT_FOUND;
795         }
796
797         private int getEvcCountOnServer(String serverId) {
798                 LimitResource l = (LimitResource) resourceManager.getResource("Connection", serverId);
799                 if (l != null)
800                         return (int) l.used;
801                 return 0;
802         }
803
804         private String getAicSiteId(SvcLogicContext ctx) throws SvcLogicException {
805                 String aicSiteId = ctx.getAttribute("tmp.resource-allocator.aic-site-id");
806                 if (aicSiteId == null)
807                         throw new SvcLogicException("tmp.resource-allocator.aic-site-id is required in ResourceAllocator");
808                 return aicSiteId;
809         }
810
811         private Map<String, Object> getServiceData(SvcLogicContext ctx) throws SvcLogicException {
812                 Map<String, Object> sd = new HashMap<String, Object>();
813
814                 String endPointPosition = ctx.getAttribute("tmp.resource-allocator.end-point-position");
815                 if (endPointPosition != null && endPointPosition.trim().length() > 0)
816                         sd.put("end-point-position", endPointPosition.trim());
817
818                 String resourceName = ctx.getAttribute("tmp.resource-allocator.resource-name");
819                 if (resourceName != null && resourceName.trim().length() > 0)
820                         sd.put("resource-name", resourceName.trim());
821
822                 String resourceShareGroup = ctx.getAttribute("tmp.resource-allocator.resource-share-group");
823                 if (resourceShareGroup != null && resourceShareGroup.trim().length() > 0)
824                         sd.put("resource-share-group", resourceShareGroup.trim());
825
826                 String serviceInstanceId = ctx.getAttribute("tmp.resource-allocator.service-instance-id");
827                 if (serviceInstanceId == null)
828                         serviceInstanceId = "checkServiceInstance";
829                 sd.put("service-instance-id", serviceInstanceId);
830
831                 String speedStr = ctx.getAttribute("tmp.resource-allocator.speed");
832                 if (speedStr != null && speedStr.trim().length() > 0) {
833                 long speed = 0;
834                 try {
835                         speed = Long.parseLong(speedStr);
836                 } catch (NumberFormatException e) {
837                         throw new SvcLogicException("Invalid tmp.resource-allocator.speed. Must be a number.");
838                 }
839                 String unit = ctx.getAttribute("tmp.resource-allocator.speed-unit");
840                 if (unit == null || unit.trim().length() == 0)
841                         throw new SvcLogicException("tmp.resource-allocator.speed-unit is required in ResourceAllocator");
842                 long serviceSpeedKbps = speedUtil.convertToKbps(speed, unit);
843
844                 sd.put("service-speed-kbps", serviceSpeedKbps);
845                 }
846
847                 String vpnId = ctx.getAttribute("tmp.resource-allocator.vpn-id");
848                 if (vpnId != null && vpnId.trim().length() > 0)
849                         sd.put("vpn-id", vpnId.trim());
850
851                 String vpnIdList = ctx.getAttribute("tmp.resource-allocator.vpn-id-list");
852                 if (vpnIdList != null && vpnIdList.trim().length() > 0)
853                         sd.put("vpn-id-list", vpnIdList.trim());
854
855                 String vrfName = ctx.getAttribute("tmp.resource-allocator.vrf-name");
856                 if (vrfName != null && vrfName.trim().length() > 0)
857                         sd.put("vrf-name", vrfName.trim());
858
859                 String vrfNameList = ctx.getAttribute("tmp.resource-allocator.vrf-name-list");
860                 if (vrfNameList != null && vrfNameList.trim().length() > 0)
861                         sd.put("vrf-name-list", vrfNameList.trim());
862
863                 String v4multicast = ctx.getAttribute("tmp.resource-allocator.v4-multicast");
864                 if (v4multicast != null && v4multicast.trim().length() > 0)
865                         sd.put("v4-multicast", v4multicast.trim());
866
867                 String v6multicast = ctx.getAttribute("tmp.resource-allocator.v6-multicast");
868                 if (v6multicast != null && v6multicast.trim().length() > 0)
869                         sd.put("v6-multicast", v6multicast.trim());
870
871                 String v4ServingSite = ctx.getAttribute("tmp.resource-allocator.v4-serving-site");
872                 if (v4ServingSite != null && v4ServingSite.trim().length() > 0)
873                         sd.put("v4-serving-site", v4ServingSite.trim());
874
875                 String v6ServingSite = ctx.getAttribute("tmp.resource-allocator.v6-serving-site");
876                 if (v6ServingSite != null && v6ServingSite.trim().length() > 0)
877                         sd.put("v6-serving-site", v6ServingSite.trim());
878
879                 return sd;
880         }
881
882         private Map<String, Object> getEquipConstraints(SvcLogicContext ctx) throws SvcLogicException {
883                 Map<String, Object> mm = new HashMap<String, Object>();
884
885                 String vrfRequired = ctx.getAttribute("tmp.resource-allocator.vrf-required");
886                 if (vrfRequired != null && vrfRequired.trim().length() > 0)
887                         mm.put("vrf-required", vrfRequired.trim());
888
889                 String clli = ctx.getAttribute("tmp.resource-allocator.clli");
890                 if (clli == null || clli.trim().length() == 0)
891                         clli = ctx.getAttribute("tmp.resource-allocator.aic-site-id");
892                 if (clli != null) {
893                 mm.put("clli", clli.trim());
894                         mm.put("aic-site-id", clli.trim());
895                 }
896
897                 String vpeName = ctx.getAttribute("tmp.resource-allocator.vpe-name");
898                 if (vpeName != null && vpeName.trim().length() > 0)
899                         mm.put("vpe-name", vpeName.trim());
900
901                 String vnfName = ctx.getAttribute("tmp.resource-allocator.device-name");
902                 if (vnfName != null && vnfName.trim().length() > 0)
903                         mm.put("vnf-name", vnfName.trim());
904
905                 String excludeVpeList = ctx.getAttribute("tmp.resource-allocator.exclude-vpe-list");
906                 if (excludeVpeList != null && excludeVpeList.trim().length() > 0)
907                         mm.put("exclude-vpe-list", excludeVpeList.trim());
908
909                 String uplinkCircuitCountStr =
910                         ctx.getAttribute("tmp.resource-allocator.uplink-circuit-list.uplink-circuit_length");
911                 if (uplinkCircuitCountStr != null) {
912                         long uplinkCircuitCount = 0;
913                         try {
914                                 uplinkCircuitCount = Long.parseLong(uplinkCircuitCountStr);
915                         } catch (NumberFormatException e) {
916                                 throw new SvcLogicException(
917                                         "Invalid tmp.resource-allocator.uplink-circuit-list.uplink-circuit_length. Must be a number.");
918                         }
919                         List<Map<String, Object>> uplinkCircuitList = new ArrayList<>();
920                         for (int i = 0; i < uplinkCircuitCount; i++) {
921                                 String uplinkCircuitId = ctx.getAttribute(
922                                         "tmp.resource-allocator.uplink-circuit-list.uplink-circuit[" + i + "].uplink-circuit-id");
923                                 String uplinkCircuitBandwidthStr =
924                                         ctx.getAttribute("tmp.resource-allocator.uplink-circuit-list.uplink-circuit[" + i +
925                                                 "].uplink-circuit-bandwidth");
926                                 String uplinkCircuitBandwidthUnit =
927                                         ctx.getAttribute("tmp.resource-allocator.uplink-circuit-list.uplink-circuit[" + i +
928                                                 "].uplink-circuit-bandwidth-unit");
929
930                                 long uplinkCircuitBandwidth = 0;
931                                 try {
932                                         uplinkCircuitBandwidth = Long.parseLong(uplinkCircuitBandwidthStr);
933                                 } catch (NumberFormatException e) {
934                                         throw new SvcLogicException("Invalid tmp.resource-allocator.uplink-circuit-list.uplink-circuit[" +
935                                                 i + "].uplink-circuit-id. Must be a number.");
936                                 }
937
938                                 long uplinkCircuitBandwidthKbps =
939                                         speedUtil.convertToKbps(uplinkCircuitBandwidth, uplinkCircuitBandwidthUnit);
940
941                                 Map<String, Object> uplinkCircuit = new HashMap<String, Object>();
942                                 uplinkCircuit.put("uplink-circuit-id", uplinkCircuitId);
943                                 uplinkCircuit.put("uplink-circuit-bandwidth", uplinkCircuitBandwidthKbps);
944                                 uplinkCircuitList.add(uplinkCircuit);
945                         }
946                         mm.put("uplink-circuit-list", uplinkCircuitList);
947                 }
948
949                 return mm;
950         }
951
952         private void setOutputContext(SvcLogicContext ctx, long maxAvailableSpeed, String unit) {
953                 ctx.setAttribute("tmp.resource-allocator-output.max-available-speed", String.valueOf(maxAvailableSpeed));
954                 ctx.setAttribute("tmp.resource-allocator-output.speed-unit", unit);
955         }
956
957         private int calculatePrimaryServerCount(int serverCount, String ratioString) throws SvcLogicException {
958                 String[] ss = ratioString.split(":");
959                 if (ss.length != 2)
960                         throw new SvcLogicException("Invalid value for homing.pserver.sparing.ratio: " + ratioString);
961
962                 int n = 1, m = 1;
963                 try {
964                         n = Integer.parseInt(ss[0]);
965                         m = Integer.parseInt(ss[1]);
966                 } catch (Exception e) {
967                         throw new SvcLogicException("Invalid value for homing.pserver.sparing.ratio: " + ratioString);
968                 }
969
970                 return (serverCount - 1) * n / (n + m) + 1;
971         }
972
973         public void setServerDao(ServerDao serverDao) {
974                 this.serverDao = serverDao;
975         }
976
977         public void setVpePortDao(VpePortDao vpePortDao) {
978                 this.vpePortDao = vpePortDao;
979         }
980
981         public void setVplspePortDao(VplspePortDao vplspePortDao) {
982                 this.vplspePortDao = vplspePortDao;
983         }
984
985         public void setMaxPortSpeedDao(MaxPortSpeedDao maxPortSpeedDao) {
986                 this.maxPortSpeedDao = maxPortSpeedDao;
987         }
988
989         public void setMaxServerSpeedDao(MaxServerSpeedDao maxServerSpeedDao) {
990                 this.maxServerSpeedDao = maxServerSpeedDao;
991         }
992
993         public void setAllocationRequestBuilder(AllocationRequestBuilder allocationRequestBuilder) {
994                 this.allocationRequestBuilder = allocationRequestBuilder;
995         }
996
997         public void setResourceManager(ResourceManager resourceManager) {
998                 this.resourceManager = resourceManager;
999         }
1000
1001         public void setSpeedUtil(SpeedUtil speedUtil) {
1002                 this.speedUtil = speedUtil;
1003         }
1004
1005         public void setServiceResourceDao(ServiceResourceDao serviceResourceDao) {
1006                 this.serviceResourceDao = serviceResourceDao;
1007         }
1008
1009         public void setEndPointAllocator(EndPointAllocator endPointAllocator) {
1010                 this.endPointAllocator = endPointAllocator;
1011         }
1012
1013         public void setParameterDao(ParameterDao parameterDao) {
1014                 this.parameterDao = parameterDao;
1015         }
1016 }