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
9 * http://www.apache.org/licenses/LICENSE-2.0
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=================================================
19 package org.onap.optf.cmso.optimizer.clients.optimizer;
21 import com.google.ical.compat.jodatime.DateTimeIterator;
22 import java.text.ParseException;
23 import java.util.Date;
24 import java.util.List;
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.ElementInfo;
36 import org.onap.optf.cmso.optimizer.service.rs.models.OptimizerRequest;
37 import org.onap.optf.cmso.optimizer.service.rs.models.OptimizerScheduleInfo;
38 import org.onap.optf.cmso.optimizer.service.rs.models.ScheduledElement;
39 import org.onap.optf.cmso.optimizer.service.rs.models.ScheduledElement.ScheduleType;
40 import org.onap.optf.cmso.optimizer.service.rs.models.UnScheduledElement;
41 import org.onap.optf.cmso.optimizer.service.rs.models.UnScheduledElement.NotScheduledReason;
43 // This class ensures that the node indices nodes and the time slots are the
44 // same when processing the optimizer engine response as when initiating.
45 public class ElementWindowMapping {
47 protected OptimizerRequest optimizerRequest;
48 protected TopologyResponse topologyResponse;
50 protected Map<String, TopologyElementInfo> nodeInfo = new TreeMap<>();
51 private List<TopologyElementInfo> nodeArray = null;
53 public ElementWindowMapping(OptimizerRequest optimizerRequest, TopologyResponse topologyResponse)
54 throws ParseException {
55 this.optimizerRequest = optimizerRequest;
56 this.topologyResponse = topologyResponse;
61 private void initialize() throws ParseException {
62 List<TopologyElementInfo> elements = topologyResponse.getElements();
63 for (TopologyElementInfo info : elements) {
64 nodeInfo.put(info.getElementId(), info);
68 protected DateTimeIterator getRecurringIterator() throws ParseException {
69 // Only support 1 change window for now
70 ChangeWindow window = optimizerRequest.getChangeWindows().get(0);
71 Long duration = new Long(optimizerRequest.getNormalDuration());
72 if (optimizerRequest.getAdditionalDuration() != null) {
73 duration += optimizerRequest.getAdditionalDuration();
75 DateTimeIterator recur = RecurringWindows.getRecurringListForChangeWindow(window, duration);
79 public void initializeForProcessResult() {
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());
87 public OptimizerScheduleInfo processResult(OptimizerSchedule result) throws ParseException {
88 // When considering the memory vs performance
89 // 5 minute duration for a month long change window is 8928 slots
90 // The assumption is that there were be fewer allocated slots
91 // than potential slots.
92 List<ElementSlot> elements = result.getElementSlotLoader();
93 Map<Integer, List<ElementSlot>> mapSlotToElement =
94 elements.stream().collect(Collectors.groupingBy(ElementSlot::getSlot));
95 DateTimeIterator iter = getRecurringIterator();
96 // TODO - supporting only 1 change window at the moment.....
97 Long endWindow = optimizerRequest.getChangeWindows().get(0).getEndTime().getTime();
98 Integer slotIndex = 1;
99 while (iter.hasNext()) {
100 DateTime dateTime = iter.next();
101 if (dateTime.isAfter(endWindow))
103 List<ElementSlot> list = mapSlotToElement.get(slotIndex);
105 list.stream().forEach(x -> x.setTime(dateTime.getMillis()));
110 // All assigned ElementSlots now have corresponding UTC time
112 OptimizerScheduleInfo info = new OptimizerScheduleInfo();
113 for (ElementSlot slot : elements) {
114 updateInfo(slot, info);
119 private void updateInfo(ElementSlot slot, OptimizerScheduleInfo info) {
120 TopologyElementInfo element = nodeArray.get(slot.getElementIndex()-1);
121 if (slot.getSlot() > 0) {
122 ScheduledElement scheduled = new ScheduledElement();
123 Integer durationInSeconds = optimizerRequest.getNormalDuration();
124 if (optimizerRequest.getAdditionalDuration() != null) {
125 durationInSeconds += optimizerRequest.getAdditionalDuration();
127 scheduled.setDurationSeconds(durationInSeconds.longValue());
128 scheduled.setElementId(element.getElementId());
129 scheduled.setStartTime(new Date(slot.getTime()));
130 scheduled.setEndTime(new Date(slot.getTime() + (durationInSeconds*1000)));
131 scheduled.setScheduleType(ScheduleType.INDIVIDUAL);
132 scheduled.setGroupId(getGroupId(scheduled.getElementId()));
133 info.getScheduledElements().add(scheduled);
135 UnScheduledElement unscheduled = new UnScheduledElement();
136 unscheduled.setElementId(element.getElementId());
137 unscheduled.setGroupId("unknown");
138 unscheduled.getNotScheduledReaons().add(NotScheduledReason.Other);
139 unscheduled.getNotScheduledMessages().add("Unknown");
140 info.getUnScheduledElements().add(unscheduled);
144 private String getGroupId(String elementId) {
145 ElementInfo info = getElementInfo(elementId);
147 return info.getGroupId();
152 private ElementInfo getElementInfo(String elementId) {
153 List<ElementInfo> elements = optimizerRequest.getElements();
154 ElementInfo info = elements.stream().filter(x -> x.getElementId().equals(elementId)).findAny().orElse(null);