Updates for ETE with minizinc 37/84137/2
authorJerry Flood <jflood@att.com>
Wed, 3 Apr 2019 19:10:10 +0000 (15:10 -0400)
committerJerry Flood <jflood@att.com>
Wed, 3 Apr 2019 19:25:37 +0000 (15:25 -0400)
Issue-ID: OPTFRA-436
Change-Id: Ib6eb65728bcdbb2ea27a94125580b181d63babd6
Signed-off-by: Jerry Flood <jflood@att.com>
12 files changed:
cmso-optimizer/data/policies/AllDayEveryDay.json [new file with mode: 0644]
cmso-optimizer/src/main/java/org/onap/optf/cmso/optimizer/availability/timewindows/RecurringWindows.java
cmso-optimizer/src/main/java/org/onap/optf/cmso/optimizer/clients/optimizer/ElementAvailability.java
cmso-optimizer/src/main/java/org/onap/optf/cmso/optimizer/clients/optimizer/ElementWindowMapping.java
cmso-optimizer/src/main/java/org/onap/optf/cmso/optimizer/clients/optimizer/OptimizerClient.java
cmso-optimizer/src/main/java/org/onap/optf/cmso/optimizer/clients/optimizer/OptimizerRequestManager.java
cmso-optimizer/src/main/java/org/onap/optf/cmso/optimizer/core/OptimizerManager.java
cmso-optimizer/src/main/java/org/onap/optf/cmso/optimizer/service/rs/models/ChangeWindow.java
cmso-optimizer/src/test/java/org/onap/optf/cmso/optimizer/availability/policies/PolicyManagerTest.java
cmso-optimizer/src/test/java/org/onap/optf/cmso/optimizer/availability/timewindows/RecurringWindowsTest.java
cmso-optimizer/src/test/java/org/onap/optf/cmso/optimizer/service/rs/models/ChangeWindowTest.java
pom.xml

diff --git a/cmso-optimizer/data/policies/AllDayEveryDay.json b/cmso-optimizer/data/policies/AllDayEveryDay.json
new file mode 100644 (file)
index 0000000..b2f794d
--- /dev/null
@@ -0,0 +1,47 @@
+{
+    "service": "TimeLimitAndVerticalTopology",
+    "policyName": "CMSO.Weekday_00_06",
+    "description": "dev instance",
+    "templateVersion": "Dublin",
+    "version": "0001",
+    "priority": "4",
+    "riskType": "test",
+    "riskLevel": "3",
+    "guard": "False",
+    "content": {
+        "serviceType": "networkOnDemand",
+        "identity": "vnf_upgrade_policy",
+        "policyScope": {
+            "serviceType": ["networkOnDemand"],
+            "aicZone": [
+                " "
+            ],
+            "entityType": ["vnf"]
+        },
+        "timeSchedule": {
+            "allowedPeriodicTime": [
+                {
+                    "day": "weekday",
+                    "timeRange": [
+                        {
+                            "start_time": "00:00:00+00:00",
+                            "end_time": "23:59:59+00:00"
+                        }
+                    ]
+                },
+                {
+                    "day": "weekend",
+                    "timeRange": [
+                        {
+                            "start_time": "00:00:00+00:00",
+                            "end_time": "23:59:59+00:00"
+                        }
+                    ]
+                }
+            ]
+        },
+        "nodeType": ["vnf"],
+        "type": "timeLimitAndVerticalTopology",
+        "conflictScope": "vnf_pserver"
+    }
+}
\ No newline at end of file
index 23e3ad8..c3536b7 100644 (file)
@@ -148,8 +148,8 @@ public class RecurringWindows {
         Instant cwStartInstant = changeWindow.getStartTime().toInstant();
         Instant cwEndInstant = changeWindow.getEndTime().toInstant();
 
-        List<DateTime> startList = getRecurringList(range.getStart_time(), cwStartInstant, rdata, cwEndInstant);
-        List<DateTime> endList = getRecurringList(range.getEnd_time(), cwStartInstant, rdata, cwEndInstant);
+        List<DateTime> startList = getRecurringList(range.getStart_time(), cwStartInstant, rdata, cwEndInstant, -1);
+        List<DateTime> endList = getRecurringList(range.getEnd_time(), cwStartInstant, rdata, cwEndInstant, startList.size());
         // Pair them up to make change windows
         // Everything should be UTC time
         for (int i = 0; i < startList.size(); i++) {
@@ -170,7 +170,7 @@ public class RecurringWindows {
 
 
     private static List<DateTime> getRecurringList(String rangeTime, Instant cwStartInstant, StringBuilder rdata,
-                    Instant cwEndInstant) throws ParseException {
+                    Instant cwEndInstant, int endingSize) throws ParseException {
 
         Instant startInstant = getInstanceFromTime(rangeTime, cwStartInstant);
         DateTime start = new DateTime(startInstant.toEpochMilli());
@@ -180,8 +180,15 @@ public class RecurringWindows {
         while (recur.hasNext()) {
             DateTime next = recur.next();
             // System.out.println(next.toString());
+            if (endingSize == -1) {
             if (next.isAfter(cwEndInstant.toEpochMilli())) {
                 break;
+                }
+            }
+            else {
+                if  (list.size() == endingSize) {
+                    break;
+                }
             }
             list.add(next);
         }
index 4766db2..ffaeeb9 100644 (file)
@@ -36,7 +36,6 @@ import org.onap.optf.cmso.optimizer.clients.topology.models.TopologyElementInfo;
 import org.onap.optf.cmso.optimizer.clients.topology.models.TopologyResponse;
 import org.onap.optf.cmso.optimizer.service.rs.models.ChangeWindow;
 import org.onap.optf.cmso.optimizer.service.rs.models.OptimizerRequest;
-import org.springframework.expression.spel.ast.OpInc;
 
 public class ElementAvailability extends ElementWindowMapping{
 
@@ -50,8 +49,7 @@ public class ElementAvailability extends ElementWindowMapping{
     private Map<String, List<TicketData>> nodeUnAvailability = new TreeMap<>();
 
     public ElementAvailability(List<TimeLimitAndVerticalTopology> policies, OptimizerRequest optimizerRequest,
-                    TopologyResponse topologyResponse, ActiveTicketsResponse ticketResponse) throws ParseException
-    {
+                    TopologyResponse topologyResponse, ActiveTicketsResponse ticketResponse) throws ParseException {
         super(optimizerRequest, topologyResponse);
         this.policies         = policies;
         this.ticketResponse   = ticketResponse;
@@ -61,9 +59,9 @@ public class ElementAvailability extends ElementWindowMapping{
         this.parameters = parameters;
         for (ChangeWindow changeWindow : optimizerRequest.getChangeWindows()) {
             if  (policies.size() > 0) {
-                globalRelativeAvailability.add(RecurringWindows.getAvailabilityWindowsForPolicies(policies, changeWindow));
-            }
-            else {
+                globalRelativeAvailability
+                                .add(RecurringWindows.getAvailabilityWindowsForPolicies(policies, changeWindow));
+            else {
                 List<ChangeWindow> wholeWindow = new ArrayList<>();
                 wholeWindow.add(changeWindow);
                 globalRelativeAvailability.add(wholeWindow);
@@ -109,10 +107,18 @@ public class ElementAvailability extends ElementWindowMapping{
         for (String elementId : nodeInfo.keySet()) {
 
             TopologyElementInfo info = nodeInfo.get(elementId);
-            Long timeZoneOffset = getTimeZoneOffset(info);
+            // Library for lat/lon to timzezone is MIT license.
+            // We must provided
+            String timeZone = "GMT";
+            if (info.getElementLocation() != null && info.getElementLocation().getTimezone() != null
+                            && !info.getElementLocation().getTimezone().equals("")) {
+                timeZone = info.getElementLocation().getTimezone();
+            }
             DateTimeIterator recur = getRecurringIterator();
             List<Boolean> element = new ArrayList<>();
-            while (recur.hasNext()) {
+            // calculate number time slots
+            long numberOfTimeSlots = calculateNumberOfSlotsInWindow(window, duration);
+            while (recur.hasNext() && element.size() < numberOfTimeSlots) {
                 DateTime next = recur.next();
                 if (next.isAfter(window.getEndTime().getTime())) {
                     break;
@@ -120,7 +126,7 @@ public class ElementAvailability extends ElementWindowMapping{
                 ChangeWindow slot = new ChangeWindow();
                 slot.setStartTime(next.toDate());
                 slot.setEndTime(next.plus(duration).toDate());
-                if (slotIsAvailable(slot, timeZoneOffset, nodeUnAvailability.get(elementId))) {
+                if (slotIsAvailable(slot, timeZone, nodeUnAvailability.get(elementId))) {
                     element.add(true);
                 } else {
                     element.add(false);
@@ -131,8 +137,15 @@ public class ElementAvailability extends ElementWindowMapping{
 
     }
 
-    private boolean slotIsAvailable(ChangeWindow slot, Long timeZoneOffset, List<TicketData> tickets) {
-        if (isGloballyAvailable(slot, timeZoneOffset) && isNotRestricted(slot, tickets)) {
+    private long calculateNumberOfSlotsInWindow(ChangeWindow window, Long duration)
+    {
+        long windowSize = window.getEndTime().getTime() - window.getStartTime().getTime();
+        long numberOfSlots = windowSize /duration;
+        return numberOfSlots;
+    }
+
+    private boolean slotIsAvailable(ChangeWindow slot, String timeZone, List<TicketData> tickets) {
+        if (isGloballyAvailable(slot, timeZone) && isNotRestricted(slot, tickets)) {
             return true;
         }
         return false;
@@ -152,18 +165,27 @@ public class ElementAvailability extends ElementWindowMapping{
         return true;
     }
 
-    private boolean isGloballyAvailable(ChangeWindow slot, Long timeZoneOffset) {
+    //
+    // Globally availability are generally maintenance window definitions
+    // which are UTC times that are treated as relative to the local time zone.
+    // The slot is an absolute UTCT time as well.
+    // When we test to see if the slot is 'globally' available we must adjust it
+    // to the local time of the element to see it it matches the relative
+    // Consider
+    // slot UTC time is 06:00-07:00
+    // global availability (maintenance window) 00:00-06:00
+    // the slot for an element in US/Eastern
+    // time would be converted to 01:00-02:00
+    // and would fit in the local maintenance window
+    //
+    private boolean isGloballyAvailable(ChangeWindow slot, String timeZone) {
+        boolean available = false;
         for (ChangeWindow global : globalRelativeAvailability.get(0)) {
-            if (global.containsInTimeZone(slot, timeZoneOffset)) {
-                return true;
+            if (global.containsInTimeZone(slot, timeZone)) {
+                available = true;
             }
         }
-        return false;
-    }
-
-    private Long getTimeZoneOffset(TopologyElementInfo info) {
-        // TODO Auto-generated method stub
-        return 0L;
+        return available;
     }
 
     private void calculateNodeAvailability(TopologyElementInfo info) {
index 42c69a2..246a725 100644 (file)
@@ -32,6 +32,7 @@ import org.onap.optf.cmso.optimizer.clients.optimizer.models.OptimizerSchedule;
 import org.onap.optf.cmso.optimizer.clients.topology.models.TopologyElementInfo;
 import org.onap.optf.cmso.optimizer.clients.topology.models.TopologyResponse;
 import org.onap.optf.cmso.optimizer.service.rs.models.ChangeWindow;
+import org.onap.optf.cmso.optimizer.service.rs.models.ElementInfo;
 import org.onap.optf.cmso.optimizer.service.rs.models.OptimizerRequest;
 import org.onap.optf.cmso.optimizer.service.rs.models.OptimizerScheduleInfo;
 import org.onap.optf.cmso.optimizer.service.rs.models.ScheduledElement;
@@ -75,22 +76,22 @@ public class ElementWindowMapping {
         return recur;
     }
 
-    public void initializeForProcessResult()
-    {
+    public void initializeForProcessResult() {
        // we need nodeInfo to be an array to speed up the result processing.
        // but we need it sorted by elementId as when we created it....
        nodeArray = nodeInfo.values().stream().collect(Collectors.toList());
        nodeInfo.clear();
 
     }
+
     public OptimizerScheduleInfo processResult(OptimizerSchedule result) throws ParseException {
         // When considering the memory vs performance
         // 5 minute duration for a month long change window is 8928 slots
         // The assumption is that there were be fewer allocated slots
         // than potential slots.
         List<ElementSlot> elements = result.getElementSlotLoader();
-        Map<Integer, List<ElementSlot>> mapSlotToElement = elements.stream().
-                        collect(Collectors.groupingBy(ElementSlot::getSlot));
+        Map<Integer, List<ElementSlot>> mapSlotToElement =
+                        elements.stream().collect(Collectors.groupingBy(ElementSlot::getSlot));
         DateTimeIterator iter = getRecurringIterator();
         // TODO - supporting only 1 change window at the moment.....
         Long endWindow = optimizerRequest.getChangeWindows().get(0).getEndTime().getTime();
@@ -109,18 +110,15 @@ public class ElementWindowMapping {
         // All assigned ElementSlots now have corresponding UTC time
         //
         OptimizerScheduleInfo info = new OptimizerScheduleInfo();
-        for (ElementSlot slot : elements)
-        {
+        for (ElementSlot slot : elements) {
             updateInfo(slot, info);
         }
         return info;
     }
 
-    private void updateInfo(ElementSlot slot, OptimizerScheduleInfo info)
-    {
+    private void updateInfo(ElementSlot slot, OptimizerScheduleInfo info) {
         TopologyElementInfo element = nodeArray.get(slot.getElementIndex()-1);
-        if (slot.getSlot() > 0)
-        {
+        if (slot.getSlot() > 0) {
             ScheduledElement scheduled = new ScheduledElement();
             Integer durationInSeconds = optimizerRequest.getNormalDuration();
             if (optimizerRequest.getAdditionalDuration() != null) {
@@ -131,10 +129,9 @@ public class ElementWindowMapping {
             scheduled.setStartTime(new Date(slot.getTime()));
             scheduled.setEndTime(new Date(slot.getTime() + (durationInSeconds*1000)));
             scheduled.setScheduleType(ScheduleType.INDIVIDUAL);
+            scheduled.setGroupId(getGroupId(scheduled.getElementId()));
             info.getScheduledElements().add(scheduled);
-        }
-        else
-        {
+        } else {
             UnScheduledElement unscheduled = new UnScheduledElement();
             unscheduled.setElementId(element.getElementId());
             unscheduled.setGroupId("unknown");
@@ -144,5 +141,18 @@ public class ElementWindowMapping {
         }
     }
 
+    private String getGroupId(String elementId) {
+        ElementInfo info = getElementInfo(elementId);
+        if (info != null) {
+            return info.getGroupId();
+        }
+        return "";
+    }
+
+    private ElementInfo getElementInfo(String elementId) {
+        List<ElementInfo> elements = optimizerRequest.getElements();
+        ElementInfo info = elements.stream().filter(x -> x.getElementId().equals(elementId)).findAny().orElse(null);
+        return info;
+    }
 
 }
index 514097e..3147bc5 100644 (file)
@@ -57,7 +57,6 @@ import org.onap.optf.cmso.optimizer.model.Topology;
 import org.onap.optf.cmso.optimizer.model.dao.OptimizerDao;
 import org.onap.optf.cmso.optimizer.model.dao.RequestDao;
 import org.onap.optf.cmso.optimizer.service.rs.models.OptimizerRequest;
-import org.onap.optf.cmso.optimizer.service.rs.models.OptimizerResponse.OptimizeScheduleStatus;
 import org.onap.optf.cmso.optimizer.service.rs.models.PolicyInfo;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.core.env.Environment;
index 34de3df..c911804 100644 (file)
@@ -20,7 +20,6 @@
 package org.onap.optf.cmso.optimizer.clients.optimizer;
 
 import com.fasterxml.jackson.databind.ObjectMapper;
-import java.util.List;
 import java.util.Optional;
 import java.util.UUID;
 import org.onap.observations.Observation;
@@ -121,7 +120,7 @@ public class OptimizerRequestManager {
             OptimizerResults results = apiResponse.getOptimizerResults();
             OptimizerResponse response = new OptimizerResponse();
             response.setRequestId(requestRow.getUuid().toString());
-
+            response.setStatus(OptimizeScheduleStatus.COMPLETED);
             String optString = requestRow.getRequest();
 
             OptimizerRequest optimizerResquest = new ObjectMapper().readValue(optString, OptimizerRequest.class);
@@ -175,11 +174,6 @@ public class OptimizerRequestManager {
     }
 
 
-    public List<OptimizerScheduleInfo> getScheduleInfo(Response responseRow) {
-        // TODO Auto-generated method stub
-        return null;
-    }
-
 
 
 }
index eabebec..d2e3153 100644 (file)
@@ -25,6 +25,7 @@ import java.util.List;
 import java.util.Optional;
 import java.util.UUID;
 import javax.ws.rs.core.Response.Status;
+import org.onap.observations.Observation;
 import org.onap.optf.cmso.common.exceptions.CmsoException;
 import org.onap.optf.cmso.optimizer.clients.optimizer.OptimizerRequestManager;
 import org.onap.optf.cmso.optimizer.clients.optimizer.models.OptimizerEngineResponse;
@@ -260,13 +261,20 @@ public class OptimizerManager {
 
     public OptimizerResponse getCompletedOptimizerResponse(UUID uuid)
     {
-        OptimizerResponse response = new OptimizerResponse();
-        response.setRequestId(uuid.toString());
-        response.setStatus(OptimizeScheduleStatus.COMPLETED);
+        OptimizerResponse response = null;
         Response responseRow  = getResponseRow(uuid);
-        if (responseRow != null)
+        try
         {
-            response.setSchedules(optimizerRequestManager.getScheduleInfo(responseRow));
+            String responseStr = responseRow.getRepsonse();
+            response = new ObjectMapper().readValue(responseStr, OptimizerResponse.class);
+        }
+        catch (Exception e)
+        {
+            Observation.report(LogMessages.UNEXPECTED_EXCEPTION, e, e.getMessage());
+            response = new OptimizerResponse();
+            response.setRequestId(uuid.toString());
+            response.setStatus(OptimizeScheduleStatus.FAILED);
+            response.setErrorMessage(LogMessages.UNEXPECTED_EXCEPTION.format(e.getMessage()));
         }
         return response;
     }
index 4eb6824..e9218b2 100644 (file)
@@ -34,7 +34,9 @@ import io.swagger.annotations.ApiModel;
 import io.swagger.annotations.ApiModelProperty;
 import java.io.Serializable;
 import java.time.Instant;
+import java.time.temporal.ChronoUnit;
 import java.util.Date;
+import java.util.TimeZone;
 import org.springframework.format.annotation.DateTimeFormat;
 
 /**
@@ -133,16 +135,25 @@ public class ChangeWindow implements Serializable {
      * @param timeZoneOffset the time zone offset
      * @return true, if successful
      */
-    public boolean containsInTimeZone(ChangeWindow test, Long timeZoneOffset) {
-        Instant startInstant = startTime.toInstant().plusMillis(timeZoneOffset);
-        Instant endInstant = endTime.toInstant().plusMillis(timeZoneOffset);
-        if (!test.getStartTime().toInstant().isBefore(startInstant)
-                        && !test.getEndTime().toInstant().isAfter(endInstant)) {
+    public boolean containsInTimeZone(ChangeWindow test, Integer startTimeZoneOffset, Integer endTimeZoneOffset) {
+        Instant startInstant = startTime.toInstant();
+        Instant endInstant = endTime.toInstant();
+        Instant testStart = test.getStartTime().toInstant().plusMillis(startTimeZoneOffset);;
+        Instant testEnd = test.getEndTime().toInstant().plusMillis(startTimeZoneOffset);;
+        if (!testStart.isBefore(startInstant)
+                        && !testEnd.isAfter(endInstant)) {
             return true;
         }
         return false;
     }
 
+    public boolean containsInTimeZone(ChangeWindow test, String timeZone) {
+        TimeZone tz = TimeZone.getTimeZone(timeZone);
+        Integer startTimeZoneOffset = tz.getOffset(startTime.toInstant().truncatedTo(ChronoUnit.DAYS).toEpochMilli());
+        Integer endTimeZoneOffset = tz.getOffset(endTime.toInstant().truncatedTo(ChronoUnit.DAYS).toEpochMilli());
+        return containsInTimeZone(test, startTimeZoneOffset, endTimeZoneOffset);
+    }
+
     /**
      * Absorb if overlapping window.
      *
index c71c829..817c8de 100644 (file)
@@ -52,7 +52,7 @@ public class PolicyManagerTest {
     public void getPolicyByName() {
         String policyName = "Weekday_00_06";
 
-        String result = "CMSO.Weekday_00_06,CMSO.Weekday_00_06,CMSO.Weekday_00_06,";
+        String result = "CMSO.Weekday_00_06,CMSO.Weekday_00_06,CMSO.Weekday_00_06,CMSO.Weekday_00_06,";
         List<Policy> policies = policyManager.getSupportedPolicies();
         StringBuilder sb = new StringBuilder();
         for (Policy pol : policies) {
index ce1f1a4..d772650 100644 (file)
@@ -23,6 +23,7 @@ import java.time.Instant;
 import java.util.ArrayList;
 import java.util.Date;
 import java.util.List;
+import java.util.TimeZone;
 import org.junit.Assert;
 import org.junit.Before;
 import org.junit.Test;
@@ -55,10 +56,10 @@ public class RecurringWindowsTest {
 
     @Test
     public void getAvailabilityWindowsForPolicies() {
-        getAvailabilityWindowsForPolicy("Weekday_00_06", "2019-03-08T00:00:00.00Z", "2019-03-12T00:00:00.00Z", 2);
-        getAvailabilityWindowsForPolicy("EveryDay_00_06", "2019-03-08T00:00:00.00Z", "2019-03-12T00:00:00.00Z", 4);
+        getAvailabilityWindowsForPolicy("AllDayEveryDay", "2019-03-08T00:00:00.00Z", "2019-03-12T00:00:00.00Z", 5);
+        getAvailabilityWindowsForPolicy("Weekday_00_06", "2019-03-08T00:00:00.00Z", "2019-03-12T00:00:00.00Z", 3);
+        getAvailabilityWindowsForPolicy("EveryDay_00_06", "2019-03-08T00:00:00.00Z", "2019-03-12T00:00:00.00Z", 5);
         getAvailabilityWindowsForPolicy("Weekend_00_06", "2019-03-08T00:00:00.00Z", "2019-03-12T00:00:00.00Z", 3);
-
     }
 
     private void getAvailabilityWindowsForPolicy(String policyName, String startStr, String endStr, int size) {
index b1309fb..67242ef 100644 (file)
@@ -39,7 +39,12 @@ public class ChangeWindowTest {
         testContains(window, "2019-03-07T23:59:59Z", "2019-03-12T00:00:00.00Z", false);
         testContains(window, "2019-03-09T23:59:59Z", "2019-03-11T00:00:00.00Z", true);
         testContains(window, "2019-03-06T23:59:59Z", "2019-03-06T23:59:59Z", false);
-        testContains(window, "2019-03-12T23:59:59Z", "2019-03-13T00:00:00.00Z", false);
+
+        String tz = "US/Eastern";
+        window.setStartTime(Date.from(Instant.parse("2019-03-08T00:00:00.00Z")));
+        window.setEndTime(Date.from(Instant.parse("2019-03-08T06:00:00.00Z")));
+        testContainsTz(window, "2019-03-08T06:00:00Z", "2019-03-08T07:00:00.00Z", tz, true);
+        testContainsTz(window, "2019-03-08T00:00:00Z", "2019-03-08T01:00:00.00Z", tz, false);
 
     }
 
@@ -50,4 +55,11 @@ public class ChangeWindowTest {
         Assert.assertTrue(window.contains(test) == contains);
     }
 
+    private void testContainsTz(ChangeWindow window, String from, String to, String tz,  boolean contains) {
+        ChangeWindow test = new ChangeWindow();
+        test.setStartTime(Date.from(Instant.parse(from)));
+        test.setEndTime(Date.from(Instant.parse(to)));
+        Assert.assertTrue(window.containsInTimeZone(test, tz) == contains);
+    }
+
 }
diff --git a/pom.xml b/pom.xml
index e6ea475..5f8175e 100644 (file)
--- a/pom.xml
+++ b/pom.xml
@@ -65,6 +65,7 @@
         <module>cmso-database</module>\r
         <module>cmso-service</module>\r
         <module>cmso-topology</module>\r
+        <module>cmso-optimizer</module>\r
         <module>cmso-ticketmgt</module>\r
         <module>cmso-robot</module>\r
     </modules>\r