4766db212a0ee36110e647d7f1281e4f6a015e73
[optf/cmso.git] /
1 /*
2  *  ============LICENSE_START==============================================
3  *  Copyright (c) 2019 AT&T Intellectual Property.
4  *  =======================================================================
5  *  Licensed under the Apache License, Version 2.0 (the "License"); you may
6  *  not use this file except in compliance with the License. You may obtain a
7  *  copy of the License at
8  *
9  *         http://www.apache.org/licenses/LICENSE-2.0
10  *
11  * Unless required by applicable law or agreed to in writing, software
12  * distributed under the License is distributed on an "AS IS" BASIS,
13  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
14  * or implied. See the License for the specific language governing
15  * permissions and limitations under the License.
16  * ============LICENSE_END=================================================
17  */
18
19 package org.onap.optf.cmso.optimizer.clients.optimizer;
20
21 import com.google.ical.compat.jodatime.DateTimeIterator;
22 import java.text.ParseException;
23 import java.util.ArrayList;
24 import java.util.HashSet;
25 import java.util.List;
26 import java.util.Map;
27 import java.util.Set;
28 import java.util.TreeMap;
29 import org.joda.time.DateTime;
30 import org.onap.optf.cmso.optimizer.availability.policies.model.TimeLimitAndVerticalTopology;
31 import org.onap.optf.cmso.optimizer.availability.timewindows.RecurringWindows;
32 import org.onap.optf.cmso.optimizer.clients.optimizer.models.OptimizerParameters;
33 import org.onap.optf.cmso.optimizer.clients.ticketmgt.models.ActiveTicketsResponse;
34 import org.onap.optf.cmso.optimizer.clients.ticketmgt.models.TicketData;
35 import org.onap.optf.cmso.optimizer.clients.topology.models.TopologyElementInfo;
36 import org.onap.optf.cmso.optimizer.clients.topology.models.TopologyResponse;
37 import org.onap.optf.cmso.optimizer.service.rs.models.ChangeWindow;
38 import org.onap.optf.cmso.optimizer.service.rs.models.OptimizerRequest;
39 import org.springframework.expression.spel.ast.OpInc;
40
41 public class ElementAvailability extends ElementWindowMapping{
42
43     private List<TimeLimitAndVerticalTopology> policies;
44     private ActiveTicketsResponse ticketResponse;
45
46     private OptimizerParameters parameters = null;
47
48     private List<List<ChangeWindow>> globalRelativeAvailability = new ArrayList<>();
49
50     private Map<String, List<TicketData>> nodeUnAvailability = new TreeMap<>();
51
52     public ElementAvailability(List<TimeLimitAndVerticalTopology> policies, OptimizerRequest optimizerRequest,
53                     TopologyResponse topologyResponse, ActiveTicketsResponse ticketResponse) throws ParseException
54     {
55         super(optimizerRequest, topologyResponse);
56         this.policies         = policies;
57         this.ticketResponse   = ticketResponse;
58     }
59
60     public void populate(OptimizerParameters parameters) throws ParseException {
61         this.parameters = parameters;
62         for (ChangeWindow changeWindow : optimizerRequest.getChangeWindows()) {
63             if  (policies.size() > 0) {
64                 globalRelativeAvailability.add(RecurringWindows.getAvailabilityWindowsForPolicies(policies, changeWindow));
65             }
66             else {
67                 List<ChangeWindow> wholeWindow = new ArrayList<>();
68                 wholeWindow.add(changeWindow);
69                 globalRelativeAvailability.add(wholeWindow);
70             }
71         }
72         for (String id : nodeInfo.keySet()) {
73             calculateNodeAvailability(nodeInfo.get(id));
74         }
75         setNoConflicts();
76         parameters.setMaxTime(new Long(parameters.getNoConflict().get(0).size()));
77         parameters.setNumElements(new Long(parameters.getNoConflict().size()));
78
79         // for now we have 1 loader with unlimited capacity
80         parameters.setNumLoaders(1L);
81         Long loaderCapacity = parameters.getNumElements();
82         List<Long> capacity =  new ArrayList<>();
83         for (Long slot =0L ; slot < parameters.getMaxTime() ; slot++) {
84             capacity.add(loaderCapacity);
85         }
86         parameters.getLoaderCapacity().add(capacity);
87
88         // For now every slot has the same concurrency limit
89         capacity =  new ArrayList<>();
90         Long limit = new Long(optimizerRequest.getConcurrencyLimit());
91         if (limit > parameters.getNumElements()) {
92             limit = parameters.getNumElements();
93         }
94
95         for (Long slot =0L ; slot < parameters.getMaxTime() ; slot++) {
96             capacity.add(limit);
97         }
98         parameters.setElementSlotCapacity(capacity);
99
100     }
101
102     private void setNoConflicts() throws ParseException {
103         // Only support 1 change window for now
104         ChangeWindow window = optimizerRequest.getChangeWindows().get(0);
105         Long duration = new Long(optimizerRequest.getNormalDuration());
106         if (optimizerRequest.getAdditionalDuration() != null) {
107             duration += optimizerRequest.getAdditionalDuration();
108         }
109         for (String elementId : nodeInfo.keySet()) {
110
111             TopologyElementInfo info = nodeInfo.get(elementId);
112             Long timeZoneOffset = getTimeZoneOffset(info);
113             DateTimeIterator recur = getRecurringIterator();
114             List<Boolean> element = new ArrayList<>();
115             while (recur.hasNext()) {
116                 DateTime next = recur.next();
117                 if (next.isAfter(window.getEndTime().getTime())) {
118                     break;
119                 }
120                 ChangeWindow slot = new ChangeWindow();
121                 slot.setStartTime(next.toDate());
122                 slot.setEndTime(next.plus(duration).toDate());
123                 if (slotIsAvailable(slot, timeZoneOffset, nodeUnAvailability.get(elementId))) {
124                     element.add(true);
125                 } else {
126                     element.add(false);
127                 }
128             }
129             parameters.getNoConflict().add(element);
130         }
131
132     }
133
134     private boolean slotIsAvailable(ChangeWindow slot, Long timeZoneOffset, List<TicketData> tickets) {
135         if (isGloballyAvailable(slot, timeZoneOffset) && isNotRestricted(slot, tickets)) {
136             return true;
137         }
138         return false;
139     }
140
141     private boolean isNotRestricted(ChangeWindow slot, List<TicketData> tickets) {
142         if (tickets != null) {
143             for (TicketData ticket : tickets) {
144                 ChangeWindow window = new ChangeWindow();
145                 window.setStartTime(ticket.getStartTime());
146                 window.setEndTime(ticket.getEndTime());
147                 if (slot.overlaps(window)) {
148                     return false;
149                 }
150             }
151         }
152         return true;
153     }
154
155     private boolean isGloballyAvailable(ChangeWindow slot, Long timeZoneOffset) {
156         for (ChangeWindow global : globalRelativeAvailability.get(0)) {
157             if (global.containsInTimeZone(slot, timeZoneOffset)) {
158                 return true;
159             }
160         }
161         return false;
162     }
163
164     private Long getTimeZoneOffset(TopologyElementInfo info) {
165         // TODO Auto-generated method stub
166         return 0L;
167     }
168
169     private void calculateNodeAvailability(TopologyElementInfo info) {
170         Set<String> requiredElements = new HashSet<>();
171         requiredElements.add(info.getElementId());
172         if (info.getRequiredElements() != null) {
173             requiredElements.addAll(info.getRequiredElements());
174         }
175         if (ticketResponse.getElements() != null) {
176             List<TicketData> tickets = ticketResponse.getElements();
177             for (TicketData data : tickets) {
178                 for (String id : data.getElementIds()) {
179                     if (requiredElements.contains(id)) {
180                         updateNodeAvailability(id, data);
181                         break;
182                     }
183                 }
184             }
185         }
186     }
187
188     private void updateNodeAvailability(String elementId, TicketData data) {
189         List<TicketData> list = nodeUnAvailability.get(elementId);
190         if (list == null) {
191             list = new ArrayList<>();
192             nodeUnAvailability.put(elementId, list);
193         }
194         list.add(data);
195     }
196
197 }