Commit 1 for Define OPtimizer API mS 07/83807/1
authorJerry Flood <jflood@att.com>
Sun, 31 Mar 2019 12:31:18 +0000 (08:31 -0400)
committerJerry Flood <jflood@att.com>
Sun, 31 Mar 2019 12:38:43 +0000 (08:38 -0400)
Multiple commits required due to commit size limitation.

Change-Id: If34d19e3ed8bebcab1a348cbac39254336a456f9
Issue-ID: OPTFRA-437
Signed-off-by: Jerry Flood <jflood@att.com>
cmso-database/src/main/resources/optimizer-dbchanges/onap-optimizer-v1-schema.sql
cmso-optimizer/data/policies/EveryDay_00_06.json [new file with mode: 0644]
cmso-optimizer/data/policies/Weekend_00_06.json [new file with mode: 0644]
cmso-optimizer/etc/config/optimizer.properties
cmso-optimizer/src/main/java/org/onap/optf/cmso/optimizer/availability/policies/PolicyManager.java
cmso-optimizer/src/main/java/org/onap/optf/cmso/optimizer/availability/policies/model/AllowedPeriodicTime.java
cmso-optimizer/src/main/java/org/onap/optf/cmso/optimizer/availability/policies/model/Policy.java
cmso-optimizer/src/main/java/org/onap/optf/cmso/optimizer/availability/policies/model/TimeLimitAndVerticalTopology.java
cmso-optimizer/src/main/java/org/onap/optf/cmso/optimizer/availability/policies/model/TimeRange.java
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/common/models/ElementCriteria.java [new file with mode: 0644]

index 02daa60..d91a17e 100644 (file)
@@ -7,6 +7,7 @@ CREATE TABLE IF NOT EXISTS `optimizer`.`request` (
   request_start BIGINT(20) NULL DEFAULT NULL,
   request_end BIGINT(20) NULL DEFAULT NULL,
   status VARCHAR(45) NULL DEFAULT NULL,
+  message MEDIUMTEXT NULL DEFAULT NULL,
   PRIMARY KEY (`uuid`))
 ENGINE = InnoDB
 DEFAULT CHARACTER SET = utf8;
diff --git a/cmso-optimizer/data/policies/EveryDay_00_06.json b/cmso-optimizer/data/policies/EveryDay_00_06.json
new file mode 100644 (file)
index 0000000..53350ff
--- /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": "06:00:00+00:00"
+                        }
+                    ]
+                },
+                {
+                    "day": "weekend",
+                    "timeRange": [
+                        {
+                            "start_time": "00:00:00+00:00",
+                            "end_time": "06:00:00+00:00"
+                        }
+                    ]
+                }
+            ]
+        },
+        "nodeType": ["vnf"],
+        "type": "timeLimitAndVerticalTopology",
+        "conflictScope": "vnf_pserver"
+    }
+}
\ No newline at end of file
diff --git a/cmso-optimizer/data/policies/Weekend_00_06.json b/cmso-optimizer/data/policies/Weekend_00_06.json
new file mode 100644 (file)
index 0000000..5e26cb4
--- /dev/null
@@ -0,0 +1,38 @@
+{
+    "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": "weekend",
+                    "timeRange": [
+                        {
+                            "start_time": "00:00:00+00:00",
+                            "end_time": "06:00:00+00:00"
+                        }
+                    ]
+                }
+            ]
+        },
+        "nodeType": ["vnf"],
+        "type": "timeLimitAndVerticalTopology",
+        "conflictScope": "vnf_pserver"
+    }
+}
\ No newline at end of file
index 8b8c6a1..ac39ec8 100644 (file)
@@ -45,5 +45,5 @@ logging.level.org.hibernate=TRACE
 
 
 cmso.topology.create.request.url=http://127.0.0.1:7998/topology/v1/current
-
+cmso.ticket.create.request.url=http://127.0.0.1:7999/ticketmgt/v1/activetickets
 cmso.local.policy.folder=data/policies
\ No newline at end of file
index d6ae196..d82932b 100644 (file)
@@ -44,12 +44,9 @@ public class PolicyManager {
         TimeLimitAndVerticalTopology returnPolicy = null;
         if (policy != null) {
             ObjectMapper om = new ObjectMapper();
-            try
-            {
+            try {
                 returnPolicy = om.convertValue(policy.getContent(), TimeLimitAndVerticalTopology.class);
-            }
-            catch (Exception e)
-            {
+            } catch (Exception e) {
                 Observation.report(LogMessages.UNEXPECTED_EXCEPTION, e, e.getMessage());
             }
         }
index 4bc0f71..abdb5f8 100644 (file)
@@ -36,28 +36,35 @@ import java.util.List;
  */
 public class AllowedPeriodicTime {
 
-    public enum Day
-    {
-        weekday("RRULE:FREQ=WEEKLY;BYDAY=MO,TU,WE,TH,FR"),
-        weekend("RRULE:FREQ=WEEKLY;BYDAY=SA,SU"),
-        ;
+    public enum Day {
+        weekday("RRULE:FREQ=WEEKLY;BYDAY=MO,TU,WE,TH,FR"), weekend("RRULE:FREQ=WEEKLY;BYDAY=SA,SU"),;
         private String rrule;
-        private Day(String rrule) {this.rrule = rrule;}
-        public String getRrule() {return rrule;}
+
+        private Day(String rrule) {
+            this.rrule = rrule;
+        }
+
+        public String getRrule() {
+            return rrule;
+        }
 
     }
 
     private Day day;
     private List<TimeRange> timeRange;
+
     public Day getDay() {
         return day;
     }
+
     public void setDay(Day day) {
         this.day = day;
     }
+
     public List<TimeRange> getTimeRange() {
         return timeRange;
     }
+
     public void setTimeRange(List<TimeRange> timeRange) {
         this.timeRange = timeRange;
     }
index 50acd9b..f6bdf74 100644 (file)
@@ -71,63 +71,83 @@ public class Policy {
     private String riskLevel;
     private String guard;
     private Object content;
+
     public String getService() {
         return service;
     }
+
     public void setService(String service) {
         this.service = service;
     }
+
     public String getPolicyName() {
         return policyName;
     }
+
     public void setPolicyName(String policyName) {
         this.policyName = policyName;
     }
+
     public String getDescription() {
         return description;
     }
+
     public void setDescription(String description) {
         this.description = description;
     }
+
     public String getTemplateVersion() {
         return templateVersion;
     }
+
     public void setTemplateVersion(String templateVersion) {
         this.templateVersion = templateVersion;
     }
+
     public String getVersion() {
         return version;
     }
+
     public void setVersion(String version) {
         this.version = version;
     }
+
     public String getPriority() {
         return priority;
     }
+
     public void setPriority(String priority) {
         this.priority = priority;
     }
+
     public String getRiskType() {
         return riskType;
     }
+
     public void setRiskType(String riskType) {
         this.riskType = riskType;
     }
+
     public String getRiskLevel() {
         return riskLevel;
     }
+
     public void setRiskLevel(String riskLevel) {
         this.riskLevel = riskLevel;
     }
+
     public String getGuard() {
         return guard;
     }
+
     public void setGuard(String guard) {
         this.guard = guard;
     }
+
     public Object getContent() {
         return content;
     }
+
     public void setContent(Object content) {
         this.content = content;
     }
index 58846f4..7af22e3 100644 (file)
@@ -51,8 +51,7 @@ import java.util.List;
 }
  */
 
-public class TimeLimitAndVerticalTopology
-{
+public class TimeLimitAndVerticalTopology {
 
     public enum ConflictScope {
         timeLimitAndVerticalTopology,
@@ -72,42 +71,55 @@ public class TimeLimitAndVerticalTopology
     public String getServiceType() {
         return serviceType;
     }
+
     public void setServiceType(String serviceType) {
         this.serviceType = serviceType;
     }
+
     public String getIdentity() {
         return identity;
     }
+
     public void setIdentity(String identity) {
         this.identity = identity;
     }
+
     public PolicyScope getPolicyScope() {
         return policyScope;
     }
+
     public void setPolicyScope(PolicyScope policyScope) {
         this.policyScope = policyScope;
     }
+
     public TimeSchedule getTimeSchedule() {
         return timeSchedule;
     }
+
     public void setTimeSchedule(TimeSchedule timeSchedule) {
         this.timeSchedule = timeSchedule;
     }
+
     public List<String> getNodeType() {
         return nodeType;
     }
+
     public void setNodeType(List<String> nodeType) {
         this.nodeType = nodeType;
     }
+
     public String getType() {
         return type;
     }
+
     public void setType(String type) {
         this.type = type;
     }
+
     public String getConflictScope() {
         return conflictScope;
     }
+
     public void setConflictScope(String conflictScope) {
         this.conflictScope = conflictScope;
     }
index 6b6ba0b..0f8f851 100644 (file)
@@ -27,20 +27,22 @@ package org.onap.optf.cmso.optimizer.availability.policies.model;
 }
 
  */
-public class TimeRange
-{
+public class TimeRange {
     private String start_time;
     private String end_time;
 
     public String getStart_time() {
         return start_time;
     }
+
     public void setStart_time(String start_time) {
         this.start_time = start_time;
     }
+
     public String getEnd_time() {
         return end_time;
     }
+
     public void setEnd_time(String end_time) {
         this.end_time = end_time;
     }
index f9704ff..dce64b4 100644 (file)
 
 package org.onap.optf.cmso.optimizer.availability.timewindows;
 
+import com.google.ical.compat.jodatime.DateTimeIterator;
+import com.google.ical.compat.jodatime.DateTimeIteratorFactory;
+import java.text.ParseException;
 import java.time.Instant;
+import java.time.LocalDate;
+import java.time.LocalDateTime;
+import java.time.LocalTime;
+import java.time.OffsetDateTime;
+import java.time.OffsetTime;
+import java.time.ZoneOffset;
+import java.time.ZonedDateTime;
+import java.time.temporal.ChronoUnit;
 import java.util.ArrayList;
 import java.util.Date;
+import java.util.HashSet;
 import java.util.List;
+import java.util.Set;
+import org.joda.time.DateTime;
+import org.joda.time.DateTimeZone;
 import org.onap.observations.Observation;
 import org.onap.optf.cmso.optimizer.availability.policies.model.AllowedPeriodicTime;
 import org.onap.optf.cmso.optimizer.availability.policies.model.TimeLimitAndVerticalTopology;
@@ -30,8 +45,18 @@ import org.onap.optf.cmso.optimizer.availability.policies.model.TimeRange;
 import org.onap.optf.cmso.optimizer.common.LogMessages;
 import org.onap.optf.cmso.optimizer.service.rs.models.ChangeWindow;
 
+/**
+ * The Class RecurringWindows.
+ */
 public class RecurringWindows {
 
+    /**
+     * Gets the availability windows for policies.
+     *
+     * @param policies the policies
+     * @param changeWindow the change window
+     * @return the availability windows for policies
+     */
     public static List<ChangeWindow> getAvailabilityWindowsForPolicies(List<TimeLimitAndVerticalTopology> policies,
                     ChangeWindow changeWindow) {
         List<ChangeWindow> availableList = new ArrayList<>();
@@ -42,19 +67,46 @@ public class RecurringWindows {
                 }
             }
         }
+        // Collapse all duplicate and overlapping availabity windows into minimum
+        // number of windows
+        availableList = collapseWindows(availableList);
         return availableList;
 
     }
 
 
+    private static List<ChangeWindow> collapseWindows(List<ChangeWindow> availableList) {
+        List<ChangeWindow> collapsed = new ArrayList<>();
+        Set<ChangeWindow> consumed = new HashSet<>();
+        for (ChangeWindow win : availableList) {
+            if (!consumed.contains(win)) {
+                // Find all windows that can collapse into this one
+                consumed.add(win);
+                boolean allUnique = false;
+                while (!allUnique) {
+                    allUnique = true;
+                    for (ChangeWindow test : availableList) {
+                        // if availability windows overlap
+                        if (!consumed.contains(test)) {
+                            if (win.absorbIfOverlapping(test)) {
+                                consumed.add(test);
+                                allUnique = false;
+                            }
+                        }
+                    }
+                }
+                collapsed.add(win);
+            }
+        }
+        return collapsed;
+    }
+
     // "RRULE:FREQ=WEEKLY;BYDAY=MO,TU,WE,TH,FR",
     private static void getAvailableWindowsForApt(AllowedPeriodicTime available, ChangeWindow changeWindow,
                     List<ChangeWindow> availableList) {
 
-        if (available.getDay() != null)
-        {
-            switch (available.getDay())
-            {
+        if (available.getDay() != null) {
+            switch (available.getDay()) {
                 case weekday:
                 case weekend:
                     getAvailableWindowsForAptDay(available, changeWindow, availableList);
@@ -63,46 +115,102 @@ public class RecurringWindows {
 
             }
         }
+        availableList.add(changeWindow);
         Observation.report(LogMessages.UNSUPPORTED_PERIODIC_TIME, available.toString());
 
     }
+
     // "RRULE:FREQ=WEEKLY;BYDAY=MO,TU,WE,TH,FR",
+
     private static void getAvailableWindowsForAptDay(AllowedPeriodicTime available, ChangeWindow changeWindow,
                     List<ChangeWindow> availableList) {
-        try
-        {
+        try {
             List<TimeRange> ranges = available.getTimeRange();
-            if (ranges.size() == 0)
-            {
+            if (ranges.size() == 0) {
                 TimeRange range = new TimeRange();
                 range.setStart_time("00:00:00+00:00");
                 range.setStart_time("23:59:59+00:00");
                 ranges.add(range);
             }
-            String rrule = available.getDay().getRrule();
-            for (TimeRange range : ranges)
-            {
-
-                Date cwStartDate =changeWindow.getStartTime();
-                Date cwEndDate =changeWindow.getEndTime();
-
-                Instant cwStartInstant = Instant.ofEpochMilli(cwStartDate.getTime());
-                Instant cwEndInstant = Instant.ofEpochMilli(cwEndDate.getTime());
-                Instant startInstant = Instant.parse(range.getStart_time());
-                Instant endInstant = Instant.parse(range.getEnd_time());
-                if (cwStartInstant.isAfter(startInstant))
-                {
-                    // We expect this since startInstant has no  date (1/1/1970)
-                    //
+            StringBuilder rdata = new StringBuilder();
+            rdata.append(available.getDay().getRrule()).append("\n");
+            for (TimeRange range : ranges) {
+                processRange(range, changeWindow, availableList, rdata);
+            }
+        } catch (Exception e) {
+            Observation.report(LogMessages.UNEXPECTED_EXCEPTION, e, e.getMessage());
+        }
+    }
+
+
+    private static void processRange(TimeRange range, ChangeWindow changeWindow, List<ChangeWindow> availableList,
+                    StringBuilder rdata) throws ParseException {
+
+        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);
+        // Pair them up to make change windows
+        // Everything should be UTC time
+        for (int i = 0; i < startList.size(); i++) {
+            DateTime startDt = startList.get(i);
+            if (i < endList.size()) {
+                DateTime endDt = endList.get(i);
+                if (endDt.isAfter(startDt)) {
+                    ChangeWindow cw = new ChangeWindow();
+                    cw.setStartTime(startDt.toDate());
+                    cw.setEndTime(endDt.toDate());
+                    availableList.add(cw);
                 }
 
+            }
+        }
+
+    }
+
 
+    private static List<DateTime> getRecurringList(String rangeTime, Instant cwStartInstant, StringBuilder rdata,
+                    Instant cwEndInstant) throws ParseException {
+
+        Instant startInstant = getInstanceFromTime(rangeTime, cwStartInstant);
+        DateTime start = new DateTime(startInstant.toEpochMilli());
+        DateTimeIterator recur =
+                        DateTimeIteratorFactory.createDateTimeIterator(rdata.toString(), start, DateTimeZone.UTC, true);
+        List<DateTime> list = new ArrayList<>();
+        while (recur.hasNext()) {
+            DateTime next = recur.next();
+            // System.out.println(next.toString());
+            if (next.isAfter(cwEndInstant.toEpochMilli())) {
+                break;
             }
+            list.add(next);
         }
-        catch (Exception e)
-        {
-            Observation.report(LogMessages.UNEXPECTED_EXCEPTION, e, e.getMessage());
+        return list;
+    }
+
+
+    //
+    // The policies with 'Day' enumeration only have time with no day so we add the
+    // date portion of the change window to the dtstart
+    //
+    private static Instant getInstanceFromTime(String timeIn, Instant cwStartInstant) {
+        Instant instant = null;
+        Instant date = cwStartInstant.truncatedTo(ChronoUnit.DAYS);
+        LocalDate epoch = LocalDate.ofEpochDay(0);
+        try {
+            OffsetTime offset = OffsetTime.parse(timeIn);
+            OffsetDateTime odt = offset.atDate(epoch);
+            ZonedDateTime startTime = odt.atZoneSameInstant(ZoneOffset.UTC.normalized());
+            instant = Instant.from(startTime);
+        } catch (Exception e) {
+            LocalTime local = LocalTime.parse(timeIn);
+            LocalDateTime ldt = local.atDate(epoch);
+            ZonedDateTime startTime = ldt.atZone(ZoneOffset.UTC.normalized());
+            instant = Instant.from(startTime);
         }
+        return instant.plus(date.toEpochMilli(), ChronoUnit.MILLIS);
     }
 
+
 }
diff --git a/cmso-optimizer/src/main/java/org/onap/optf/cmso/optimizer/clients/common/models/ElementCriteria.java b/cmso-optimizer/src/main/java/org/onap/optf/cmso/optimizer/clients/common/models/ElementCriteria.java
new file mode 100644 (file)
index 0000000..7b16a2f
--- /dev/null
@@ -0,0 +1,63 @@
+/*******************************************************************************
+ *
+ * Copyright © 2019 AT&T Intellectual Property.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
+ * in compliance with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software distributed under the License
+ * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
+ * or implied. See the License for the specific language governing permissions and limitations under
+ * the License.
+ *
+ *
+ * Unless otherwise specified, all documentation contained herein is licensed under the Creative
+ * Commons License, Attribution 4.0 Intl. (the "License"); you may not use this documentation except
+ * in compliance with the License. You may obtain a copy of the License at
+ *
+ * https://creativecommons.org/licenses/by/4.0/
+ *
+ * Unless required by applicable law or agreed to in writing, documentation distributed under the
+ * License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
+ * express or implied. See the License for the specific language governing permissions and
+ * limitations under the License.
+ ******************************************************************************/
+
+package org.onap.optf.cmso.optimizer.clients.common.models;
+
+import io.swagger.annotations.ApiModel;
+import io.swagger.annotations.ApiModelProperty;
+import java.io.Serializable;
+import java.util.ArrayList;
+import java.util.List;
+import org.onap.optf.cmso.optimizer.service.rs.models.NameValue;
+
+@ApiModel(value = "Element Critera", description = "Element criteria for retrieving topology.")
+public class ElementCriteria implements Serializable {
+    private static final long serialVersionUID = 1L;
+
+    @ApiModelProperty(value = "Element id unique to the request.")
+    private String elementId;
+
+    @ApiModelProperty(value = "Implementation specific element data.")
+    public List<NameValue> elementData = new ArrayList<>();
+
+    public String getElementId() {
+        return elementId;
+    }
+
+    public void setElementId(String elementId) {
+        this.elementId = elementId;
+    }
+
+    public List<NameValue> getElementData() {
+        return elementData;
+    }
+
+    public void setElementData(List<NameValue> elementData) {
+        this.elementData = elementData;
+    }
+
+}