Roll version for Casablanca
[ccsdk/sli/adaptors.git] / resource-assignment / provider / src / main / java / org / onap / ccsdk / sli / adaptors / ra / comp / EndPointAllocatorImpl.java
1 /*-
2  * ============LICENSE_START=======================================================
3  * openECOMP : SDN-C
4  * ================================================================================
5  * Copyright (C) 2017 AT&T 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.onap.ccsdk.sli.adaptors.ra.comp;
23
24 import java.util.ArrayList;
25 import java.util.Arrays;
26 import java.util.Collections;
27 import java.util.HashMap;
28 import java.util.List;
29 import java.util.Map;
30
31 import org.apache.commons.lang.NotImplementedException;
32 import org.onap.ccsdk.sli.adaptors.ra.equip.data.EquipmentData;
33 import org.onap.ccsdk.sli.adaptors.rm.comp.ResourceManager;
34 import org.onap.ccsdk.sli.adaptors.rm.data.AllocationItem;
35 import org.onap.ccsdk.sli.adaptors.rm.data.AllocationOutcome;
36 import org.onap.ccsdk.sli.adaptors.rm.data.AllocationRequest;
37 import org.onap.ccsdk.sli.adaptors.rm.data.AllocationStatus;
38 import org.onap.ccsdk.sli.adaptors.rm.data.LimitAllocationItem;
39 import org.onap.ccsdk.sli.adaptors.rm.data.LimitResource;
40 import org.onap.ccsdk.sli.adaptors.rm.data.RangeAllocationItem;
41 import org.onap.ccsdk.sli.adaptors.rm.data.RangeResource;
42 import org.onap.ccsdk.sli.adaptors.rm.data.Resource;
43 import org.slf4j.Logger;
44 import org.slf4j.LoggerFactory;
45
46 public class EndPointAllocatorImpl implements EndPointAllocator {
47
48     private static final Logger log = LoggerFactory.getLogger(EndPointAllocatorImpl.class);
49
50     private Map<String, List<EndPointAllocationDefinition>> endPointAllocationDefinitionMap;
51
52     private ResourceManager resourceManager;
53
54     @Override
55     public List<EndPointData> allocateEndPoints(
56             ServiceData serviceData,
57             Map<String, Object> equipmentConstraints,
58             boolean checkOnly,
59             boolean change,
60             int changeNumber) {
61         List<EndPointAllocationDefinition> defList = endPointAllocationDefinitionMap.get(serviceData.serviceModel);
62         if (defList == null)
63             throw new NotImplementedException("Service model: " + serviceData.serviceModel + " not supported");
64
65         List<EndPointData> epList = new ArrayList<>();
66         for (EndPointAllocationDefinition def : defList) {
67             if (serviceData.endPointPosition != null && !serviceData.endPointPosition.equals(def.endPointPosition))
68                 continue;
69
70             log.info(
71                     "Starting allocation of end point: " + def.endPointPosition + ": " + serviceData.serviceInstanceId);
72
73             String resourceUnionId = serviceData.serviceInstanceId + '/' + def.endPointPosition;
74             String resourceSetId = resourceUnionId + '/' + changeNumber;
75
76             String equipmentId = (String) equipmentConstraints.get("equipment-id");
77             if (equipmentId == null) {
78                 EndPointData epExisting = readEndPoint(resourceUnionId, resourceSetId);
79                 if (epExisting != null && epExisting.equipmentId != null) {
80                     equipmentConstraints.put("equipment-id", epExisting.equipmentId);
81
82                     log.info("Trying assignment on the current equipment: " + epExisting.equipmentId);
83                 }
84             }
85
86             List<EquipmentData> equipList = def.equipmentReader.readEquipment(equipmentConstraints);
87             if (equipList == null || equipList.isEmpty()) {
88                 log.info("Equipment not found for " + def.endPointPosition);
89                 break;
90             }
91
92             if (def.equipmentCheckList != null) {
93                 for (EquipmentCheck filter : def.equipmentCheckList) {
94                     List<EquipmentData> newEquipList = new ArrayList<>();
95                     for (EquipmentData equipData : equipList)
96                         if (filter.checkEquipment(def.endPointPosition, serviceData, equipData, equipmentConstraints))
97                             newEquipList.add(equipData);
98                     equipList = newEquipList;
99                 }
100                 if (equipList.isEmpty()) {
101                     log.info("No equipment meets the requiremets for the service for: " + def.endPointPosition);
102                     break;
103                 }
104             }
105
106             if (equipList.size() > 1 && def.preferenceRuleList != null && !def.preferenceRuleList.isEmpty()) {
107
108                 List<PrefEquipment> prefEquipList = new ArrayList<>();
109                 for (EquipmentData equipData : equipList) {
110                     PrefEquipment prefEquip = new PrefEquipment();
111                     prefEquip.equipData = equipData;
112                     prefEquip.prefNumbers = new long[def.preferenceRuleList.size()];
113                     prefEquipList.add(prefEquip);
114
115                     int i = 0;
116                     for (PreferenceRule prefRule : def.preferenceRuleList)
117                         prefEquip.prefNumbers[i++] =
118                                 prefRule.assignOrderNumber(def.endPointPosition, serviceData, equipData);
119                 }
120
121                 Collections.sort(prefEquipList);
122
123                 equipList = new ArrayList<>();
124                 for (PrefEquipment prefEquip : prefEquipList)
125                     equipList.add(prefEquip.equipData);
126             }
127
128             for (EquipmentData equipData : equipList) {
129                 boolean allgood = true;
130                 if (def.allocationRuleList != null)
131                     for (AllocationRule allocationRule : def.allocationRuleList) {
132                         AllocationRequest ar = allocationRule.buildAllocationRequest(resourceUnionId, resourceSetId,
133                                 def.endPointPosition, serviceData, equipData, checkOnly, change);
134                         if (ar != null) {
135                             AllocationOutcome ao = resourceManager.allocateResources(ar);
136                             if (ao.status != AllocationStatus.Success) {
137                                 allgood = false;
138                                 break;
139                             }
140                         }
141                     }
142                 if (allgood) {
143                     EndPointData ep = readEndPoint(resourceUnionId, resourceSetId);
144                     epList.add(ep);
145                     break;
146                 }
147             }
148         }
149
150         return epList;
151     }
152
153     private EndPointData readEndPoint(String resourceUnionId, String resourceSetId) {
154         EndPointData ep = new EndPointData();
155         ep.resourceUnionId = resourceUnionId;
156         ep.resourceSetId = resourceSetId;
157
158         int i1 = resourceUnionId.indexOf('/');
159         if (i1 > 0)
160             ep.endPointPosition = resourceUnionId.substring(i1 + 1);
161
162         ep.data = new HashMap<>();
163
164         List<Resource> rlist = resourceManager.getResourceUnion(resourceUnionId);
165         for (Resource r : rlist) {
166             if (r instanceof RangeResource) {
167                 RangeResource rr = (RangeResource) r;
168                 for (AllocationItem ai : r.allocationItems)
169                     if (ai.resourceUnionId.equals(resourceUnionId)) {
170                         RangeAllocationItem rai = (RangeAllocationItem) ai;
171                         ep.data.put(ep.endPointPosition + '.' + rr.resourceKey.resourceName, rai.used.first());
172                     }
173             }
174             if (r instanceof LimitResource) {
175                 LimitResource rr = (LimitResource) r;
176                 for (AllocationItem ai : r.allocationItems)
177                     if (ai.resourceUnionId.equals(resourceUnionId)) {
178                         LimitAllocationItem rai = (LimitAllocationItem) ai;
179                         ep.data.put(ep.endPointPosition + '.' + rr.resourceKey.resourceName + ".allocated", rai.used);
180                         ep.data.put(ep.endPointPosition + '.' + rr.resourceKey.resourceName + ".used", rr.used);
181                         ep.data.put(ep.endPointPosition + '.' + rr.resourceKey.resourceName + ".assetId",
182                                 r.resourceKey.assetId);
183                     }
184             }
185         }
186
187         return ep;
188     }
189
190     private static class PrefEquipment implements Comparable<PrefEquipment> {
191
192         public long[] prefNumbers;
193         public EquipmentData equipData;
194
195         @Override
196         public int compareTo(PrefEquipment o) {
197             for (int i = 0; i < prefNumbers.length; i++) {
198                 if (prefNumbers[i] < o.prefNumbers[i])
199                     return -1;
200                 if (prefNumbers[i] > o.prefNumbers[i])
201                     return 1;
202             }
203             return 0;
204         }
205
206         @Override
207         public boolean equals(Object object) {
208             if (this == object) {
209                 return true;
210             }
211             if (!(object instanceof PrefEquipment)) {
212                 return false;
213             }
214             if (!super.equals(object)) {
215                 return false;
216             }
217
218             PrefEquipment that = (PrefEquipment) object;
219             if (equipData != null ? !equipData.equals(that.equipData) : that.equipData != null) {
220                 return false;
221             }
222
223             if (!Arrays.equals(prefNumbers, that.prefNumbers)) {
224                 return false;
225             }
226
227             return true;
228         }
229
230         @Override
231         public int hashCode() {
232             int result = super.hashCode();
233             result = 31 * result + (equipData != null ? equipData.hashCode() : 0);
234             result = 31 * result + Arrays.hashCode(prefNumbers);
235             return result;
236         }
237     }
238
239     public void setEndPointAllocationDefinitionMap(
240             Map<String, List<EndPointAllocationDefinition>> endPointAllocationDefinitionMap) {
241         this.endPointAllocationDefinitionMap = endPointAllocationDefinitionMap;
242     }
243
244     public void setResourceManager(ResourceManager resourceManager) {
245         this.resourceManager = resourceManager;
246     }
247 }