42c69a2e5029f3708f3c14223c4ae336b6cba7f4
[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.Date;
24 import java.util.List;
25 import java.util.Map;
26 import java.util.TreeMap;
27 import java.util.stream.Collectors;
28 import org.joda.time.DateTime;
29 import org.onap.optf.cmso.optimizer.availability.timewindows.RecurringWindows;
30 import org.onap.optf.cmso.optimizer.clients.optimizer.models.ElementSlot;
31 import org.onap.optf.cmso.optimizer.clients.optimizer.models.OptimizerSchedule;
32 import org.onap.optf.cmso.optimizer.clients.topology.models.TopologyElementInfo;
33 import org.onap.optf.cmso.optimizer.clients.topology.models.TopologyResponse;
34 import org.onap.optf.cmso.optimizer.service.rs.models.ChangeWindow;
35 import org.onap.optf.cmso.optimizer.service.rs.models.OptimizerRequest;
36 import org.onap.optf.cmso.optimizer.service.rs.models.OptimizerScheduleInfo;
37 import org.onap.optf.cmso.optimizer.service.rs.models.ScheduledElement;
38 import org.onap.optf.cmso.optimizer.service.rs.models.ScheduledElement.ScheduleType;
39 import org.onap.optf.cmso.optimizer.service.rs.models.UnScheduledElement;
40 import org.onap.optf.cmso.optimizer.service.rs.models.UnScheduledElement.NotScheduledReason;
41
42 // This class ensures that the node indices nodes and the time slots are the
43 // same when processing the optimizer engine response as when initiating.
44 public class ElementWindowMapping {
45
46     protected OptimizerRequest optimizerRequest;
47     protected TopologyResponse topologyResponse;
48
49     protected Map<String, TopologyElementInfo> nodeInfo = new TreeMap<>();
50     private List<TopologyElementInfo> nodeArray = null;
51
52     public ElementWindowMapping(OptimizerRequest optimizerRequest, TopologyResponse topologyResponse)
53                     throws ParseException {
54         this.optimizerRequest = optimizerRequest;
55         this.topologyResponse = topologyResponse;
56         initialize();
57
58     }
59
60     private void initialize() throws ParseException {
61         List<TopologyElementInfo> elements = topologyResponse.getElements();
62         for (TopologyElementInfo info : elements) {
63             nodeInfo.put(info.getElementId(), info);
64         }
65     }
66
67     protected DateTimeIterator getRecurringIterator() throws ParseException {
68         // Only support 1 change window for now
69         ChangeWindow window = optimizerRequest.getChangeWindows().get(0);
70         Long duration = new Long(optimizerRequest.getNormalDuration());
71         if (optimizerRequest.getAdditionalDuration() != null) {
72             duration += optimizerRequest.getAdditionalDuration();
73         }
74         DateTimeIterator recur = RecurringWindows.getRecurringListForChangeWindow(window, duration);
75         return recur;
76     }
77
78     public void initializeForProcessResult()
79     {
80        // we need nodeInfo to be an array to speed up the result processing.
81        // but we need it sorted by elementId as when we created it....
82        nodeArray = nodeInfo.values().stream().collect(Collectors.toList());
83        nodeInfo.clear();
84
85     }
86     public OptimizerScheduleInfo processResult(OptimizerSchedule result) throws ParseException {
87         // When considering the memory vs performance
88         // 5 minute duration for a month long change window is 8928 slots
89         // The assumption is that there were be fewer allocated slots
90         // than potential slots.
91         List<ElementSlot> elements = result.getElementSlotLoader();
92         Map<Integer, List<ElementSlot>> mapSlotToElement = elements.stream().
93                         collect(Collectors.groupingBy(ElementSlot::getSlot));
94         DateTimeIterator iter = getRecurringIterator();
95         // TODO - supporting only 1 change window at the moment.....
96         Long endWindow = optimizerRequest.getChangeWindows().get(0).getEndTime().getTime();
97         Integer slotIndex = 1;
98         while (iter.hasNext()) {
99             DateTime dateTime = iter.next();
100             if (dateTime.isAfter(endWindow))
101                 break;
102             List<ElementSlot> list = mapSlotToElement.get(slotIndex);
103             if (list != null) {
104                 list.stream().forEach(x -> x.setTime(dateTime.getMillis()));
105             }
106             slotIndex++;
107         }
108         //
109         // All assigned ElementSlots now have corresponding UTC time
110         //
111         OptimizerScheduleInfo info = new OptimizerScheduleInfo();
112         for (ElementSlot slot : elements)
113         {
114             updateInfo(slot, info);
115         }
116         return info;
117     }
118
119     private void updateInfo(ElementSlot slot, OptimizerScheduleInfo info)
120     {
121         TopologyElementInfo element = nodeArray.get(slot.getElementIndex()-1);
122         if (slot.getSlot() > 0)
123         {
124             ScheduledElement scheduled = new ScheduledElement();
125             Integer durationInSeconds = optimizerRequest.getNormalDuration();
126             if (optimizerRequest.getAdditionalDuration() != null) {
127                 durationInSeconds += optimizerRequest.getAdditionalDuration();
128             }
129             scheduled.setDurationSeconds(durationInSeconds.longValue());
130             scheduled.setElementId(element.getElementId());
131             scheduled.setStartTime(new Date(slot.getTime()));
132             scheduled.setEndTime(new Date(slot.getTime() + (durationInSeconds*1000)));
133             scheduled.setScheduleType(ScheduleType.INDIVIDUAL);
134             info.getScheduledElements().add(scheduled);
135         }
136         else
137         {
138             UnScheduledElement unscheduled = new UnScheduledElement();
139             unscheduled.setElementId(element.getElementId());
140             unscheduled.setGroupId("unknown");
141             unscheduled.getNotScheduledReaons().add(NotScheduledReason.Other);
142             unscheduled.getNotScheduledMessages().add("Unknown");
143             info.getUnScheduledElements().add(unscheduled);
144         }
145     }
146
147
148 }