From 6bb43b6c2696877ffd5040e9a75d5c0d66b3924b Mon Sep 17 00:00:00 2001 From: Jerry Flood Date: Sun, 31 Mar 2019 08:31:18 -0400 Subject: Commit 1 for Define OPtimizer API mS Multiple commits required due to commit size limitation. Change-Id: If34d19e3ed8bebcab1a348cbac39254336a456f9 Issue-ID: OPTFRA-437 Signed-off-by: Jerry Flood --- .../availability/policies/PolicyManager.java | 7 +- .../policies/model/AllowedPeriodicTime.java | 21 ++- .../availability/policies/model/Policy.java | 20 +++ .../model/TimeLimitAndVerticalTopology.java | 16 ++- .../availability/policies/model/TimeRange.java | 6 +- .../availability/timewindows/RecurringWindows.java | 160 +++++++++++++++++---- .../clients/common/models/ElementCriteria.java | 63 ++++++++ 7 files changed, 251 insertions(+), 42 deletions(-) create mode 100644 cmso-optimizer/src/main/java/org/onap/optf/cmso/optimizer/clients/common/models/ElementCriteria.java (limited to 'cmso-optimizer/src/main') diff --git a/cmso-optimizer/src/main/java/org/onap/optf/cmso/optimizer/availability/policies/PolicyManager.java b/cmso-optimizer/src/main/java/org/onap/optf/cmso/optimizer/availability/policies/PolicyManager.java index d6ae196..d82932b 100644 --- a/cmso-optimizer/src/main/java/org/onap/optf/cmso/optimizer/availability/policies/PolicyManager.java +++ b/cmso-optimizer/src/main/java/org/onap/optf/cmso/optimizer/availability/policies/PolicyManager.java @@ -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()); } } diff --git a/cmso-optimizer/src/main/java/org/onap/optf/cmso/optimizer/availability/policies/model/AllowedPeriodicTime.java b/cmso-optimizer/src/main/java/org/onap/optf/cmso/optimizer/availability/policies/model/AllowedPeriodicTime.java index 4bc0f71..abdb5f8 100644 --- a/cmso-optimizer/src/main/java/org/onap/optf/cmso/optimizer/availability/policies/model/AllowedPeriodicTime.java +++ b/cmso-optimizer/src/main/java/org/onap/optf/cmso/optimizer/availability/policies/model/AllowedPeriodicTime.java @@ -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; + public Day getDay() { return day; } + public void setDay(Day day) { this.day = day; } + public List getTimeRange() { return timeRange; } + public void setTimeRange(List timeRange) { this.timeRange = timeRange; } diff --git a/cmso-optimizer/src/main/java/org/onap/optf/cmso/optimizer/availability/policies/model/Policy.java b/cmso-optimizer/src/main/java/org/onap/optf/cmso/optimizer/availability/policies/model/Policy.java index 50acd9b..f6bdf74 100644 --- a/cmso-optimizer/src/main/java/org/onap/optf/cmso/optimizer/availability/policies/model/Policy.java +++ b/cmso-optimizer/src/main/java/org/onap/optf/cmso/optimizer/availability/policies/model/Policy.java @@ -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; } diff --git a/cmso-optimizer/src/main/java/org/onap/optf/cmso/optimizer/availability/policies/model/TimeLimitAndVerticalTopology.java b/cmso-optimizer/src/main/java/org/onap/optf/cmso/optimizer/availability/policies/model/TimeLimitAndVerticalTopology.java index 58846f4..7af22e3 100644 --- a/cmso-optimizer/src/main/java/org/onap/optf/cmso/optimizer/availability/policies/model/TimeLimitAndVerticalTopology.java +++ b/cmso-optimizer/src/main/java/org/onap/optf/cmso/optimizer/availability/policies/model/TimeLimitAndVerticalTopology.java @@ -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 getNodeType() { return nodeType; } + public void setNodeType(List 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; } diff --git a/cmso-optimizer/src/main/java/org/onap/optf/cmso/optimizer/availability/policies/model/TimeRange.java b/cmso-optimizer/src/main/java/org/onap/optf/cmso/optimizer/availability/policies/model/TimeRange.java index 6b6ba0b..0f8f851 100644 --- a/cmso-optimizer/src/main/java/org/onap/optf/cmso/optimizer/availability/policies/model/TimeRange.java +++ b/cmso-optimizer/src/main/java/org/onap/optf/cmso/optimizer/availability/policies/model/TimeRange.java @@ -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; } diff --git a/cmso-optimizer/src/main/java/org/onap/optf/cmso/optimizer/availability/timewindows/RecurringWindows.java b/cmso-optimizer/src/main/java/org/onap/optf/cmso/optimizer/availability/timewindows/RecurringWindows.java index f9704ff..dce64b4 100644 --- a/cmso-optimizer/src/main/java/org/onap/optf/cmso/optimizer/availability/timewindows/RecurringWindows.java +++ b/cmso-optimizer/src/main/java/org/onap/optf/cmso/optimizer/availability/timewindows/RecurringWindows.java @@ -19,10 +19,25 @@ 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 getAvailabilityWindowsForPolicies(List policies, ChangeWindow changeWindow) { List 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 collapseWindows(List availableList) { + List collapsed = new ArrayList<>(); + Set 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 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 availableList) { - try - { + try { List 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 availableList, + StringBuilder rdata) throws ParseException { + + Instant cwStartInstant = changeWindow.getStartTime().toInstant(); + Instant cwEndInstant = changeWindow.getEndTime().toInstant(); + + List startList = getRecurringList(range.getStart_time(), cwStartInstant, rdata, cwEndInstant); + List 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 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 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 index 0000000..7b16a2f --- /dev/null +++ b/cmso-optimizer/src/main/java/org/onap/optf/cmso/optimizer/clients/common/models/ElementCriteria.java @@ -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 elementData = new ArrayList<>(); + + public String getElementId() { + return elementId; + } + + public void setElementId(String elementId) { + this.elementId = elementId; + } + + public List getElementData() { + return elementData; + } + + public void setElementData(List elementData) { + this.elementData = elementData; + } + +} -- cgit 1.2.3-korg