aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--cmso-optimizer/etc/config/optimizer.properties7
-rw-r--r--cmso-optimizer/pom.xml10
-rw-r--r--cmso-optimizer/scripts/minizinc/generic_attributes.mzn199
-rw-r--r--cmso-optimizer/src/main/docker/assembly/cmso-files.xml1
-rw-r--r--cmso-optimizer/src/main/java/org/onap/observations/Mdc.java2
-rw-r--r--cmso-optimizer/src/main/java/org/onap/optf/cmso/optimizer/availability/timewindows/RecurringWindows.java13
-rw-r--r--cmso-optimizer/src/main/java/org/onap/optf/cmso/optimizer/clients/optimizer/ElementAvailability.java197
-rw-r--r--cmso-optimizer/src/main/java/org/onap/optf/cmso/optimizer/clients/optimizer/ElementWindowMapping.java148
-rw-r--r--cmso-optimizer/src/main/java/org/onap/optf/cmso/optimizer/clients/optimizer/OptimizerClient.java279
-rw-r--r--cmso-optimizer/src/main/java/org/onap/optf/cmso/optimizer/clients/optimizer/OptimizerRequestManager.java185
-rw-r--r--cmso-optimizer/src/main/java/org/onap/optf/cmso/optimizer/clients/optimizer/models/ElementSlot.java106
-rw-r--r--cmso-optimizer/src/main/java/org/onap/optf/cmso/optimizer/clients/optimizer/models/OptimizerEngineResponse.java65
-rw-r--r--cmso-optimizer/src/main/java/org/onap/optf/cmso/optimizer/clients/optimizer/models/OptimizerOutResults.java46
-rw-r--r--cmso-optimizer/src/main/java/org/onap/optf/cmso/optimizer/clients/optimizer/models/OptimizerOutSchedule.java60
-rw-r--r--cmso-optimizer/src/main/java/org/onap/optf/cmso/optimizer/clients/optimizer/models/OptimizerOutYaml.java65
-rw-r--r--cmso-optimizer/src/main/java/org/onap/optf/cmso/optimizer/clients/optimizer/models/OptimizerParameters.java225
-rw-r--r--cmso-optimizer/src/main/java/org/onap/optf/cmso/optimizer/clients/optimizer/models/OptimizerResponseUtility.java82
-rw-r--r--cmso-optimizer/src/main/java/org/onap/optf/cmso/optimizer/clients/optimizer/models/OptimizerResults.java46
-rw-r--r--cmso-optimizer/src/main/java/org/onap/optf/cmso/optimizer/clients/optimizer/models/OptimizerSchedule.java63
-rw-r--r--cmso-optimizer/src/main/java/org/onap/optf/cmso/optimizer/clients/optimizer/models/Results.java46
-rw-r--r--cmso-optimizer/src/main/java/org/onap/optf/cmso/optimizer/clients/ticketmgt/TicketMgtRequestManager.java30
-rw-r--r--cmso-optimizer/src/main/java/org/onap/optf/cmso/optimizer/clients/topology/TopologyRequestManager.java15
-rw-r--r--cmso-optimizer/src/main/java/org/onap/optf/cmso/optimizer/common/LogMessages.java2
-rw-r--r--cmso-optimizer/src/main/java/org/onap/optf/cmso/optimizer/core/OptimizerManager.java88
-rw-r--r--cmso-optimizer/src/main/java/org/onap/optf/cmso/optimizer/service/rs/models/ChangeWindow.java34
-rw-r--r--cmso-optimizer/src/main/java/org/onap/optf/cmso/optimizer/service/rs/models/OptimizerResponse.java11
-rw-r--r--cmso-optimizer/src/test/data/resultsTest001.yaml28
-rw-r--r--cmso-optimizer/src/test/java/org/onap/optf/cmso/optimizer/clients/optimizer/models/ResultsTest.java40
-rw-r--r--cmso-optimizer/src/test/java/org/onap/optf/cmso/optimizer/service/rs/models/ChangeWindowTest.java53
-rw-r--r--pom.xml2
30 files changed, 2116 insertions, 32 deletions
diff --git a/cmso-optimizer/etc/config/optimizer.properties b/cmso-optimizer/etc/config/optimizer.properties
index ac39ec8..641bbeb 100644
--- a/cmso-optimizer/etc/config/optimizer.properties
+++ b/cmso-optimizer/etc/config/optimizer.properties
@@ -46,4 +46,9 @@ 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
+cmso.local.policy.folder=data/policies
+
+cmso.minizinc.command.exe="C:/Program Files/MiniZinc IDE (bundled)/minizinc.exe"
+cmso.minizinc.command.solver=OSICBC
+cmso.minizinc.command.timelimit=60000
+cmso.minizinc.command.mzn=scripts/minizinc/generic_attributes.mzn
diff --git a/cmso-optimizer/pom.xml b/cmso-optimizer/pom.xml
index 8db7eb2..2ede9e7 100644
--- a/cmso-optimizer/pom.xml
+++ b/cmso-optimizer/pom.xml
@@ -141,6 +141,11 @@
<artifactId>httpclient</artifactId>
</dependency>
<dependency>
+ <groupId>commons-io</groupId>
+ <artifactId>commons-io</artifactId>
+ <version>2.6</version>
+ </dependency>
+ <dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-test</artifactId>
<scope>test</scope>
@@ -205,6 +210,11 @@
</exclusions>
</dependency>
+ <dependency>
+ <groupId>org.yaml</groupId>
+ <artifactId>snakeyaml</artifactId>
+ </dependency>
+
<!-- <dependency> <groupId>org.onap.aaf.authz</groupId> <artifactId>aaf-cadi-aaf</artifactId>
<version>2.1.1</version> </dependency> -->
<dependency>
diff --git a/cmso-optimizer/scripts/minizinc/generic_attributes.mzn b/cmso-optimizer/scripts/minizinc/generic_attributes.mzn
new file mode 100644
index 0000000..af38df9
--- /dev/null
+++ b/cmso-optimizer/scripts/minizinc/generic_attributes.mzn
@@ -0,0 +1,199 @@
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%% element scheduling problem
+%% Modified on Mar 08, 2019
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% Parameters
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% Required (core) parameters
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+
+% Number of elements.
+int: numElements;
+
+% Number of loaders/engineers.
+int: numLoaders;
+
+% Index of last possible time-slot for scheduling These time slots can be
+% minutes, hours, or nights. E.g., if scheduling happens at the granularity of
+% nights, 1st night is counted as 1, 2nd night counted as 2, and so on. OTOH,
+% if we have 6 hours each night and we are scheduling at the granularity of
+% hours, 1st hour of 1st night is 1, 1st hour of 2nd night is 7, and so on.
+int: maxTime;
+
+% TRUE, if i-th element does NOT have a conflict on j-th timeslot/night.
+array[1..numElements, 1..maxTime] of bool: noConflict;
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% Optional parameters (defined via policy)
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% Each attribute is composed of 3 parameters that must be supplied. When an
+% attribute is selected, all parameters related to it must be given.
+
+%%%%%%%%%%%%%%%%%%%%
+% Timeslots / nights capacities
+%%%%%%%%%%%%%%%%%%%%
+
+% Maximum number of elements that can be scheduled on j-th timeslot/night.
+array[1..maxTime] of 0..numElements: elementSlotCapacity;
+
+%%%%%%%%%%%%%%%%%%%%
+% Loader capacities
+%%%%%%%%%%%%%%%%%%%%
+
+% Maximum number of elements that can be assigned to the j-th loader per
+% timeslot/night.
+array[1..numLoaders, 1..maxTime] of 0..numElements: loaderCapacity;
+
+%%%%%%%%%%%%%%%%%%%%
+% Attribute matrix
+%%%%%%%%%%%%%%%%%%%%
+
+% Number of attributes for wach node, e.g., hardware, software, oss, market,
+% pool, etc.
+int: numAttributes;
+
+% Assume that i-th attribute has a range 0..attribute_range[i].
+% Assume that 0 indicates NA. E.g, we may have pools and a node
+% that does not belong to any pools will have 'pool attribute = 0
+% when we write constraints, we only consider attribute values >= 1.
+array[1..numAttributes] of int: attributesRange;
+
+% The attribute matrix that holds values of each attribute for a element.
+array[1..numElements, 1..numAttributes] of int: attributes;
+
+% Maximum number of nodes per time-slot that match on a given attribute.
+array[1..numAttributes, 1..maxTime] of int: attributeConcurrencyLimit;
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% Variables
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+
+% TRUE, if i-th element gets scheduled on j-th night.
+array[1..numElements, 1..maxTime] of var bool: ELEMENT2TIMESLOT;
+
+% TRUE, if i-th element gets scheduled to j-th loader.
+array[1..numElements, 1..numLoaders] of var bool: ELEMENT2LOADER;
+
+% Indicates the time slot (nigth) in which the elements were scheduled.
+array[1..numElements] of var 0..maxTime: SCHEDULED_SLOT =
+ [sum(j in 1..maxTime)(j * bool2int(ELEMENT2TIMESLOT[i,j])) | i in 1..numElements];
+
+% Indicates the loader for which the elements were scheduled.
+array[1..numElements] of var 0..numLoaders: SCHEDULED_LOADER =
+ [sum(l in 1..numLoaders)(l * bool2int(ELEMENT2LOADER[i,l])) | i in 1..numElements];
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% Constraints
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% Required (core) constraints
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+
+% Schedule only on noConclict nights.
+constraint
+forall(i in 1..numElements, j in 1..maxTime)(
+ ELEMENT2TIMESLOT[i,j] -> noConflict[i,j]
+);
+
+% Schedule a element to a loader
+constraint
+forall(i in 1..numElements)(
+ sum(t in 1..maxTime)(bool2int(ELEMENT2TIMESLOT[i,t])) ==
+ sum(l in 1..numLoaders)(bool2int(ELEMENT2LOADER[i,l]))
+);
+
+% Schedule each element exactly one timeslot/night (or none).
+constraint
+forall(i in 1..numElements)(
+ sum(j in 1..maxTime)(bool2int(ELEMENT2TIMESLOT[i,j])) <= 1
+);
+
+% Schedule each element exactly one loader (or none).
+constraint
+forall(i in 1..numElements)(
+ sum(j in 1..numLoaders)(bool2int(ELEMENT2LOADER[i,j])) <= 1
+);
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% Optional constraints (defined via policy)
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%These constraints are defined via policy and require sets of parameters also
+%defined via policy. They must be both available.
+
+%%%%%%%%%%%%%%%%%%%%
+% General capacity constraints
+%%%%%%%%%%%%%%%%%%%%
+
+% Satisfy element timeslot/nightly capacity.
+constraint
+forall(j in 1..maxTime)(
+ sum(i in 1..numElements)(bool2int(ELEMENT2TIMESLOT[i,j])) <= elementSlotCapacity[j]
+);
+
+% Satisfy loader/timeslot capacity.
+constraint
+forall(l in 1..numLoaders, t in 1..maxTime)(
+ sum(i in 1..numElements)(
+ bool2int(ELEMENT2LOADER[i,l] /\ ELEMENT2TIMESLOT[i,t])
+ ) <= loaderCapacity[l,t]
+);
+
+%%%%%%%%%%%%%%%%%%%%
+% Attribute capacity constraints
+%%%%%%%%%%%%%%%%%%%%
+
+% For attribute a and timeslot/night t, limits the number of elements having
+% the same value for attribute k, scheduled in the same timeslot/night t.
+constraint
+forall(t in 1..maxTime, a in 1..numAttributes)(
+ forall(m in 1..attributesRange[a])(
+ sum(i in 1..numElements)(
+ bool2int(attributes[i,a] == m /\ ELEMENT2TIMESLOT[i,t])
+ ) <= attributeConcurrencyLimit[a,t]
+ )
+);
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% Objective function
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+
+% Computes the number of scheduled elements.
+var int: NUM_SCHEDULED = sum(i in 1..numElements)(bool2int(SCHEDULED_SLOT[i] > 0));
+
+% Computes the (average) completion time of all elements. Note that average is
+% just a simple division by a constant, and it can be dropped from the model
+% for robusteness.
+var int: TOTAL_COMPLETION_TIME = sum(i in 1..numElements)(SCHEDULED_SLOT[i]);
+
+% First, maximize the number of scheduled elements (using a heavy weight)
+% and then minimize the (average) completion time for all elements.
+solve maximize maxTime * numElements * NUM_SCHEDULED - TOTAL_COMPLETION_TIME;
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% Output
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+
+output
+["results:"] ++
+["\n -"] ++
+["\n num_scheduled: " ++ show(NUM_SCHEDULED)] ++
+["\n total_completion_time: " ++ show(TOTAL_COMPLETION_TIME)] ++
+["\n element_slot_loader: |"] ++
+[
+ "\n " ++ show(element) ++ "," ++ show(SCHEDULED_SLOT[element]) ++ "," ++
+ show(SCHEDULED_LOADER[element])
+| element in 1..numElements
+]
+
+%output
+%["\n - num_scheduled: " ++ show(NUM_SCHEDULED)] ++
+%["\n total_completion_time: " ++ show(TOTAL_COMPLETION_TIME)] ++
+%["\n elementSlotLoader |"] ++
+%[ "\n " ++ show(element) ++ "," ++
+%show(SCHEDULED_SLOT[element]) ++ "," ++ show(SCHEDULED_LOADER[element]) | element in
+%1..numElements ]
diff --git a/cmso-optimizer/src/main/docker/assembly/cmso-files.xml b/cmso-optimizer/src/main/docker/assembly/cmso-files.xml
index 37804ec..2e3f19e 100644
--- a/cmso-optimizer/src/main/docker/assembly/cmso-files.xml
+++ b/cmso-optimizer/src/main/docker/assembly/cmso-files.xml
@@ -1,5 +1,4 @@
<!-- ============LICENSE_START=======================================================
- ECOMP CMSO ================================================================================
Copyright (C) 2019 AT&T Intellectual Property. All rights reserved. ================================================================================
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
diff --git a/cmso-optimizer/src/main/java/org/onap/observations/Mdc.java b/cmso-optimizer/src/main/java/org/onap/observations/Mdc.java
index 0686f59..5dea5aa 100644
--- a/cmso-optimizer/src/main/java/org/onap/observations/Mdc.java
+++ b/cmso-optimizer/src/main/java/org/onap/observations/Mdc.java
@@ -53,7 +53,7 @@ import org.onap.observations.MessageHeaders.HeadersEnum;
import org.slf4j.MDC;
/**
- * ECOMP EELF logging MDC fields not defined in the MDC Configuration (i.e. MDC_ALERT_SEVERITY)
+ * EELF logging MDC fields not defined in the MDC Configuration (i.e. MDC_ALERT_SEVERITY)
**/
public class Mdc {
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 dce64b4..23e3ad8 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
@@ -32,7 +32,6 @@ 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;
@@ -212,5 +211,17 @@ public class RecurringWindows {
return instant.plus(date.toEpochMilli(), ChronoUnit.MILLIS);
}
+ public static DateTimeIterator getRecurringListForChangeWindow(ChangeWindow window, Long durationInSeconds)
+ throws ParseException {
+
+ String rdata = "RRULE:FREQ=MINUTELY;INTERVAL=" + durationInSeconds/60;
+ DateTime start = new DateTime(window.getStartTime().toInstant().toEpochMilli());
+ DateTimeIterator recur =
+ DateTimeIteratorFactory.createDateTimeIterator(rdata, start, DateTimeZone.UTC, true);
+ return recur;
+ }
+
+
+
}
diff --git a/cmso-optimizer/src/main/java/org/onap/optf/cmso/optimizer/clients/optimizer/ElementAvailability.java b/cmso-optimizer/src/main/java/org/onap/optf/cmso/optimizer/clients/optimizer/ElementAvailability.java
new file mode 100644
index 0000000..4766db2
--- /dev/null
+++ b/cmso-optimizer/src/main/java/org/onap/optf/cmso/optimizer/clients/optimizer/ElementAvailability.java
@@ -0,0 +1,197 @@
+/*
+ * ============LICENSE_START==============================================
+ * Copyright (c) 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.
+ * ============LICENSE_END=================================================
+ */
+
+package org.onap.optf.cmso.optimizer.clients.optimizer;
+
+import com.google.ical.compat.jodatime.DateTimeIterator;
+import java.text.ParseException;
+import java.util.ArrayList;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+import java.util.TreeMap;
+import org.joda.time.DateTime;
+import org.onap.optf.cmso.optimizer.availability.policies.model.TimeLimitAndVerticalTopology;
+import org.onap.optf.cmso.optimizer.availability.timewindows.RecurringWindows;
+import org.onap.optf.cmso.optimizer.clients.optimizer.models.OptimizerParameters;
+import org.onap.optf.cmso.optimizer.clients.ticketmgt.models.ActiveTicketsResponse;
+import org.onap.optf.cmso.optimizer.clients.ticketmgt.models.TicketData;
+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{
+
+ private List<TimeLimitAndVerticalTopology> policies;
+ private ActiveTicketsResponse ticketResponse;
+
+ private OptimizerParameters parameters = null;
+
+ private List<List<ChangeWindow>> globalRelativeAvailability = new ArrayList<>();
+
+ private Map<String, List<TicketData>> nodeUnAvailability = new TreeMap<>();
+
+ public ElementAvailability(List<TimeLimitAndVerticalTopology> policies, OptimizerRequest optimizerRequest,
+ TopologyResponse topologyResponse, ActiveTicketsResponse ticketResponse) throws ParseException
+ {
+ super(optimizerRequest, topologyResponse);
+ this.policies = policies;
+ this.ticketResponse = ticketResponse;
+ }
+
+ public void populate(OptimizerParameters parameters) throws ParseException {
+ this.parameters = parameters;
+ for (ChangeWindow changeWindow : optimizerRequest.getChangeWindows()) {
+ if (policies.size() > 0) {
+ globalRelativeAvailability.add(RecurringWindows.getAvailabilityWindowsForPolicies(policies, changeWindow));
+ }
+ else {
+ List<ChangeWindow> wholeWindow = new ArrayList<>();
+ wholeWindow.add(changeWindow);
+ globalRelativeAvailability.add(wholeWindow);
+ }
+ }
+ for (String id : nodeInfo.keySet()) {
+ calculateNodeAvailability(nodeInfo.get(id));
+ }
+ setNoConflicts();
+ parameters.setMaxTime(new Long(parameters.getNoConflict().get(0).size()));
+ parameters.setNumElements(new Long(parameters.getNoConflict().size()));
+
+ // for now we have 1 loader with unlimited capacity
+ parameters.setNumLoaders(1L);
+ Long loaderCapacity = parameters.getNumElements();
+ List<Long> capacity = new ArrayList<>();
+ for (Long slot =0L ; slot < parameters.getMaxTime() ; slot++) {
+ capacity.add(loaderCapacity);
+ }
+ parameters.getLoaderCapacity().add(capacity);
+
+ // For now every slot has the same concurrency limit
+ capacity = new ArrayList<>();
+ Long limit = new Long(optimizerRequest.getConcurrencyLimit());
+ if (limit > parameters.getNumElements()) {
+ limit = parameters.getNumElements();
+ }
+
+ for (Long slot =0L ; slot < parameters.getMaxTime() ; slot++) {
+ capacity.add(limit);
+ }
+ parameters.setElementSlotCapacity(capacity);
+
+ }
+
+ private void setNoConflicts() throws ParseException {
+ // Only support 1 change window for now
+ ChangeWindow window = optimizerRequest.getChangeWindows().get(0);
+ Long duration = new Long(optimizerRequest.getNormalDuration());
+ if (optimizerRequest.getAdditionalDuration() != null) {
+ duration += optimizerRequest.getAdditionalDuration();
+ }
+ for (String elementId : nodeInfo.keySet()) {
+
+ TopologyElementInfo info = nodeInfo.get(elementId);
+ Long timeZoneOffset = getTimeZoneOffset(info);
+ DateTimeIterator recur = getRecurringIterator();
+ List<Boolean> element = new ArrayList<>();
+ while (recur.hasNext()) {
+ DateTime next = recur.next();
+ if (next.isAfter(window.getEndTime().getTime())) {
+ break;
+ }
+ ChangeWindow slot = new ChangeWindow();
+ slot.setStartTime(next.toDate());
+ slot.setEndTime(next.plus(duration).toDate());
+ if (slotIsAvailable(slot, timeZoneOffset, nodeUnAvailability.get(elementId))) {
+ element.add(true);
+ } else {
+ element.add(false);
+ }
+ }
+ parameters.getNoConflict().add(element);
+ }
+
+ }
+
+ private boolean slotIsAvailable(ChangeWindow slot, Long timeZoneOffset, List<TicketData> tickets) {
+ if (isGloballyAvailable(slot, timeZoneOffset) && isNotRestricted(slot, tickets)) {
+ return true;
+ }
+ return false;
+ }
+
+ private boolean isNotRestricted(ChangeWindow slot, List<TicketData> tickets) {
+ if (tickets != null) {
+ for (TicketData ticket : tickets) {
+ ChangeWindow window = new ChangeWindow();
+ window.setStartTime(ticket.getStartTime());
+ window.setEndTime(ticket.getEndTime());
+ if (slot.overlaps(window)) {
+ return false;
+ }
+ }
+ }
+ return true;
+ }
+
+ private boolean isGloballyAvailable(ChangeWindow slot, Long timeZoneOffset) {
+ for (ChangeWindow global : globalRelativeAvailability.get(0)) {
+ if (global.containsInTimeZone(slot, timeZoneOffset)) {
+ return true;
+ }
+ }
+ return false;
+ }
+
+ private Long getTimeZoneOffset(TopologyElementInfo info) {
+ // TODO Auto-generated method stub
+ return 0L;
+ }
+
+ private void calculateNodeAvailability(TopologyElementInfo info) {
+ Set<String> requiredElements = new HashSet<>();
+ requiredElements.add(info.getElementId());
+ if (info.getRequiredElements() != null) {
+ requiredElements.addAll(info.getRequiredElements());
+ }
+ if (ticketResponse.getElements() != null) {
+ List<TicketData> tickets = ticketResponse.getElements();
+ for (TicketData data : tickets) {
+ for (String id : data.getElementIds()) {
+ if (requiredElements.contains(id)) {
+ updateNodeAvailability(id, data);
+ break;
+ }
+ }
+ }
+ }
+ }
+
+ private void updateNodeAvailability(String elementId, TicketData data) {
+ List<TicketData> list = nodeUnAvailability.get(elementId);
+ if (list == null) {
+ list = new ArrayList<>();
+ nodeUnAvailability.put(elementId, list);
+ }
+ list.add(data);
+ }
+
+}
diff --git a/cmso-optimizer/src/main/java/org/onap/optf/cmso/optimizer/clients/optimizer/ElementWindowMapping.java b/cmso-optimizer/src/main/java/org/onap/optf/cmso/optimizer/clients/optimizer/ElementWindowMapping.java
new file mode 100644
index 0000000..42c69a2
--- /dev/null
+++ b/cmso-optimizer/src/main/java/org/onap/optf/cmso/optimizer/clients/optimizer/ElementWindowMapping.java
@@ -0,0 +1,148 @@
+/*
+ * ============LICENSE_START==============================================
+ * Copyright (c) 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.
+ * ============LICENSE_END=================================================
+ */
+
+package org.onap.optf.cmso.optimizer.clients.optimizer;
+
+import com.google.ical.compat.jodatime.DateTimeIterator;
+import java.text.ParseException;
+import java.util.Date;
+import java.util.List;
+import java.util.Map;
+import java.util.TreeMap;
+import java.util.stream.Collectors;
+import org.joda.time.DateTime;
+import org.onap.optf.cmso.optimizer.availability.timewindows.RecurringWindows;
+import org.onap.optf.cmso.optimizer.clients.optimizer.models.ElementSlot;
+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.OptimizerRequest;
+import org.onap.optf.cmso.optimizer.service.rs.models.OptimizerScheduleInfo;
+import org.onap.optf.cmso.optimizer.service.rs.models.ScheduledElement;
+import org.onap.optf.cmso.optimizer.service.rs.models.ScheduledElement.ScheduleType;
+import org.onap.optf.cmso.optimizer.service.rs.models.UnScheduledElement;
+import org.onap.optf.cmso.optimizer.service.rs.models.UnScheduledElement.NotScheduledReason;
+
+// This class ensures that the node indices nodes and the time slots are the
+// same when processing the optimizer engine response as when initiating.
+public class ElementWindowMapping {
+
+ protected OptimizerRequest optimizerRequest;
+ protected TopologyResponse topologyResponse;
+
+ protected Map<String, TopologyElementInfo> nodeInfo = new TreeMap<>();
+ private List<TopologyElementInfo> nodeArray = null;
+
+ public ElementWindowMapping(OptimizerRequest optimizerRequest, TopologyResponse topologyResponse)
+ throws ParseException {
+ this.optimizerRequest = optimizerRequest;
+ this.topologyResponse = topologyResponse;
+ initialize();
+
+ }
+
+ private void initialize() throws ParseException {
+ List<TopologyElementInfo> elements = topologyResponse.getElements();
+ for (TopologyElementInfo info : elements) {
+ nodeInfo.put(info.getElementId(), info);
+ }
+ }
+
+ protected DateTimeIterator getRecurringIterator() throws ParseException {
+ // Only support 1 change window for now
+ ChangeWindow window = optimizerRequest.getChangeWindows().get(0);
+ Long duration = new Long(optimizerRequest.getNormalDuration());
+ if (optimizerRequest.getAdditionalDuration() != null) {
+ duration += optimizerRequest.getAdditionalDuration();
+ }
+ DateTimeIterator recur = RecurringWindows.getRecurringListForChangeWindow(window, duration);
+ return recur;
+ }
+
+ 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));
+ DateTimeIterator iter = getRecurringIterator();
+ // TODO - supporting only 1 change window at the moment.....
+ Long endWindow = optimizerRequest.getChangeWindows().get(0).getEndTime().getTime();
+ Integer slotIndex = 1;
+ while (iter.hasNext()) {
+ DateTime dateTime = iter.next();
+ if (dateTime.isAfter(endWindow))
+ break;
+ List<ElementSlot> list = mapSlotToElement.get(slotIndex);
+ if (list != null) {
+ list.stream().forEach(x -> x.setTime(dateTime.getMillis()));
+ }
+ slotIndex++;
+ }
+ //
+ // All assigned ElementSlots now have corresponding UTC time
+ //
+ OptimizerScheduleInfo info = new OptimizerScheduleInfo();
+ for (ElementSlot slot : elements)
+ {
+ updateInfo(slot, info);
+ }
+ return info;
+ }
+
+ private void updateInfo(ElementSlot slot, OptimizerScheduleInfo info)
+ {
+ TopologyElementInfo element = nodeArray.get(slot.getElementIndex()-1);
+ if (slot.getSlot() > 0)
+ {
+ ScheduledElement scheduled = new ScheduledElement();
+ Integer durationInSeconds = optimizerRequest.getNormalDuration();
+ if (optimizerRequest.getAdditionalDuration() != null) {
+ durationInSeconds += optimizerRequest.getAdditionalDuration();
+ }
+ scheduled.setDurationSeconds(durationInSeconds.longValue());
+ scheduled.setElementId(element.getElementId());
+ scheduled.setStartTime(new Date(slot.getTime()));
+ scheduled.setEndTime(new Date(slot.getTime() + (durationInSeconds*1000)));
+ scheduled.setScheduleType(ScheduleType.INDIVIDUAL);
+ info.getScheduledElements().add(scheduled);
+ }
+ else
+ {
+ UnScheduledElement unscheduled = new UnScheduledElement();
+ unscheduled.setElementId(element.getElementId());
+ unscheduled.setGroupId("unknown");
+ unscheduled.getNotScheduledReaons().add(NotScheduledReason.Other);
+ unscheduled.getNotScheduledMessages().add("Unknown");
+ info.getUnScheduledElements().add(unscheduled);
+ }
+ }
+
+
+}
diff --git a/cmso-optimizer/src/main/java/org/onap/optf/cmso/optimizer/clients/optimizer/OptimizerClient.java b/cmso-optimizer/src/main/java/org/onap/optf/cmso/optimizer/clients/optimizer/OptimizerClient.java
new file mode 100644
index 0000000..514097e
--- /dev/null
+++ b/cmso-optimizer/src/main/java/org/onap/optf/cmso/optimizer/clients/optimizer/OptimizerClient.java
@@ -0,0 +1,279 @@
+/*
+ * ============LICENSE_START==============================================
+ * Copyright (c) 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.
+ * ============LICENSE_END=================================================
+ *
+ */
+
+package org.onap.optf.cmso.optimizer.clients.optimizer;
+
+import com.att.eelf.configuration.EELFLogger;
+import com.att.eelf.configuration.EELFManager;
+import com.fasterxml.jackson.core.JsonParseException;
+import com.fasterxml.jackson.core.JsonProcessingException;
+import com.fasterxml.jackson.databind.JsonMappingException;
+import com.fasterxml.jackson.databind.ObjectMapper;
+import java.io.File;
+import java.io.IOException;
+import java.nio.file.Files;
+import java.nio.file.Path;
+import java.nio.file.Paths;
+import java.text.ParseException;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.UUID;
+import org.apache.commons.io.IOUtils;
+import org.onap.observations.Observation;
+import org.onap.optf.cmso.common.PropertiesManagement;
+import org.onap.optf.cmso.common.exceptions.CmsoException;
+import org.onap.optf.cmso.optimizer.availability.policies.PolicyManager;
+import org.onap.optf.cmso.optimizer.availability.policies.model.TimeLimitAndVerticalTopology;
+import org.onap.optf.cmso.optimizer.clients.optimizer.models.OptimizerEngineResponse;
+import org.onap.optf.cmso.optimizer.clients.optimizer.models.OptimizerEngineResponse.OptimizerEngineResponseStatus;
+import org.onap.optf.cmso.optimizer.clients.optimizer.models.OptimizerParameters;
+import org.onap.optf.cmso.optimizer.clients.optimizer.models.OptimizerResponseUtility;
+import org.onap.optf.cmso.optimizer.clients.optimizer.models.OptimizerResults;
+import org.onap.optf.cmso.optimizer.clients.ticketmgt.TicketMgtRequestManager;
+import org.onap.optf.cmso.optimizer.clients.ticketmgt.models.ActiveTicketsResponse;
+import org.onap.optf.cmso.optimizer.clients.topology.TopologyRequestManager;
+import org.onap.optf.cmso.optimizer.clients.topology.models.TopologyResponse;
+import org.onap.optf.cmso.optimizer.common.LogMessages;
+import org.onap.optf.cmso.optimizer.model.Optimizer;
+import org.onap.optf.cmso.optimizer.model.Request;
+import org.onap.optf.cmso.optimizer.model.Ticket;
+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;
+import org.springframework.stereotype.Component;
+
+/**
+ * The Class OptimizerClient.
+ */
+@Component
+public class OptimizerClient {
+ private static EELFLogger debug = EELFManager.getInstance().getDebugLogger();
+
+ @Autowired
+ Environment env;
+
+ @Autowired
+ PropertiesManagement pm;
+
+ @Autowired
+ RequestDao requestDao;
+
+ @Autowired
+ TopologyRequestManager topologyRequestManager;
+
+ @Autowired
+ TicketMgtRequestManager ticketMgtRequestManager;
+
+ @Autowired
+ OptimizerDao optimizerDao;
+
+ @Autowired
+ PolicyManager policyManager;
+
+ /**
+ * Make request.
+ *
+ * @param request the request
+ * @param optimizer the Optimizer
+ * @return the Optimizer response
+ */
+ public OptimizerEngineResponse makeRequest(Request request, Optimizer optimizer) {
+ Integer maxAttempts = env.getProperty("cmso.optimizer.maxAttempts", Integer.class, 20);
+ OptimizerEngineResponse apiResponse = new OptimizerEngineResponse();
+ if (optimizer.getOptimizeRetries() >= maxAttempts) {
+ apiResponse.setStatus(OptimizerEngineResponseStatus.FAILED);
+ apiResponse.setErrorMessage(LogMessages.EXCEEDED_RETRY_LIMIT.format("Optimizer", maxAttempts.toString()));
+ Observation.report(LogMessages.EXCEEDED_RETRY_LIMIT, "Optimizer", maxAttempts.toString());
+ return apiResponse;
+ }
+ OptimizerRequest optimizerRequest = null;
+ TopologyResponse topologyResponse = null;
+ ActiveTicketsResponse ticketResponse = null;
+ try {
+ optimizerRequest = getOptimizerRequest(request);
+ topologyResponse = getTopologyResponse(request.getUuid());
+ ticketResponse = getTicketResponse(request.getUuid());
+ OptimizerParameters optimizerParameters =
+ buildOptimizerParameters(optimizerRequest, topologyResponse, ticketResponse);
+ apiResponse = initiateOptimizer(optimizerParameters, request);
+ } catch (Exception e) {
+ apiResponse.setStatus(OptimizerEngineResponseStatus.FAILED);
+ apiResponse.setErrorMessage(LogMessages.UNEXPECTED_EXCEPTION.format(e.getMessage()));
+ Observation.report(LogMessages.UNEXPECTED_EXCEPTION, e, e.getMessage());
+ }
+ return apiResponse;
+ }
+
+ private OptimizerParameters buildOptimizerParameters(OptimizerRequest optimizerRequest,
+ TopologyResponse topologyResponse, ActiveTicketsResponse ticketResponse) throws ParseException {
+ List<TimeLimitAndVerticalTopology> policies = getPolicies(optimizerRequest);
+ OptimizerParameters parameters = new OptimizerParameters();
+ ElementAvailability elementAvailability =
+ new ElementAvailability(policies, optimizerRequest, topologyResponse, ticketResponse);
+ elementAvailability.populate(parameters);
+
+ // Policies for this are undefined...
+ parameters.setAttributes(getAttributes(policies, optimizerRequest));
+ parameters.setAttributesRange(getAttributesRange(policies, optimizerRequest));
+ parameters.setAttributeConcurrencyLimit(getAttributeConcrrencyLimit(policies, optimizerRequest));
+ parameters.setNumAttributes(new Long(parameters.getAttributesRange().size()));
+ return parameters;
+ }
+
+ private List<List<Long>> getAttributeConcrrencyLimit(List<TimeLimitAndVerticalTopology> policies,
+ OptimizerRequest optimizerRequest) {
+ List<List<Long>> list = new ArrayList<>();
+ return list;
+ }
+
+ private List<Long> getAttributesRange(List<TimeLimitAndVerticalTopology> policies,
+ OptimizerRequest optimizerRequest) {
+ List<Long> list = new ArrayList<>();
+ return list;
+ }
+
+ private List<List<Long>> getAttributes(List<TimeLimitAndVerticalTopology> policies,
+ OptimizerRequest optimizerRequest) {
+ List<List<Long>> list = new ArrayList<>();
+ return list;
+ }
+
+
+ private List<TimeLimitAndVerticalTopology> getPolicies(OptimizerRequest optimizerRequest) {
+ List<TimeLimitAndVerticalTopology> list = new ArrayList<>();
+ for (PolicyInfo policyInfo : optimizerRequest.getPolicies()) {
+ TimeLimitAndVerticalTopology policy =
+ policyManager.getTimeLimitAndVerticalTopologyByName(policyInfo.getPolicyName());
+ list.add(policy);
+ }
+ return list;
+ }
+
+ private ActiveTicketsResponse getTicketResponse(UUID uuid)
+ throws JsonParseException, JsonMappingException, IOException {
+ Ticket ticketRow = ticketMgtRequestManager.getExistingTickets(uuid);
+ String ticketString = ticketRow.getTickets();
+ ObjectMapper om = new ObjectMapper();
+ return om.readValue(ticketString, ActiveTicketsResponse.class);
+ }
+
+ private TopologyResponse getTopologyResponse(UUID uuid)
+ throws JsonParseException, JsonMappingException, IOException {
+ Topology topologyRow = topologyRequestManager.getExistingTopology(uuid);
+ String topologyString = topologyRow.getTopology();
+ ObjectMapper om = new ObjectMapper();
+ return om.readValue(topologyString, TopologyResponse.class);
+ }
+
+ private OptimizerRequest getOptimizerRequest(Request request)
+ throws JsonParseException, JsonMappingException, IOException {
+ String requestString = request.getRequest();
+ ObjectMapper om = new ObjectMapper();
+ return om.readValue(requestString, OptimizerRequest.class);
+ }
+
+
+ private OptimizerEngineResponse initiateOptimizer(OptimizerParameters request, Request requestRow)
+ throws CmsoException, JsonProcessingException {
+
+
+ UUID uuid = requestRow.getUuid();
+ OptimizerEngineResponse apiResponse = new OptimizerEngineResponse();
+ apiResponse.setRequestId(uuid.toString());
+
+ String workingFolderString = env.getProperty("cmso.optimizer.engine.working.folder", "data/engine");
+ File workingFolder = new File(workingFolderString + File.separator + requestRow.getUuid().toString());
+ workingFolder.mkdirs();
+ Long timeLimit = env.getProperty("cmso.minizinc.command.timelimit", Long.class);
+ // TODO calculate time limit
+ Process p = null;
+ try {
+ Path inputFileName = Paths.get(workingFolder.getAbsolutePath(), "input.dzn");
+ Path outputFileName = Paths.get(workingFolder.getAbsolutePath(), "results.yaml");
+ String dzn = request.toMiniZinc();
+ Files.write(inputFileName, dzn.getBytes());
+ List<String> command = buildCommand(inputFileName, outputFileName, timeLimit.toString());
+ debug.debug("engine command=", command.toString());
+ ProcessBuilder pb = new ProcessBuilder(command);
+ p = pb.start();
+ String stdout = IOUtils.toString(p.getInputStream(), "UTF-8");
+ String stderr = IOUtils.toString(p.getErrorStream(), "UTF-8");
+ debug.debug("stdout=" + stdout);
+ debug.debug("stderr=" + stderr);
+ if (p.isAlive()) {
+ p.wait();
+ }
+ OptimizerResponseUtility responseUtility = new OptimizerResponseUtility();
+ OptimizerResults optimizerResults = responseUtility.parseOptimizerResult(outputFileName.toFile());
+ apiResponse.setOptimizerResults(optimizerResults);
+ apiResponse.setStatus(OptimizerEngineResponseStatus.COMPLETED);
+
+ } catch (InterruptedException e) {
+ apiResponse.setStatus(OptimizerEngineResponseStatus.FAILED);
+ apiResponse.setErrorMessage(
+ LogMessages.OPTIMIZER_REQUEST_TIMEOUT.format(uuid.toString(), timeLimit.toString()));
+ Observation.report(LogMessages.OPTIMIZER_REQUEST_TIMEOUT, uuid.toString(), timeLimit.toString());
+ p.destroyForcibly();
+ } catch (Exception e) {
+ apiResponse.setStatus(OptimizerEngineResponseStatus.FAILED);
+ apiResponse.setErrorMessage(LogMessages.UNEXPECTED_EXCEPTION.format(e.getMessage()));
+ Observation.report(LogMessages.UNEXPECTED_RESPONSE, e, e.getMessage());
+ } finally {
+ if (workingFolder.exists()) {
+ workingFolder.delete();
+ }
+ }
+ return apiResponse;
+ }
+
+ private List<String> buildCommand(Path inputFileName, Path outputFileName, String timeLimit) {
+ List<String> command = new ArrayList<>();
+ String minizinc = env.getProperty("cmso.minizinc.command.exe", "minizinc");
+ String solver = env.getProperty("cmso.minizinc.command.solver", "OSICBC");
+ String additional = env.getProperty("cmso.minizinc.command.additional", "");
+ String script = env.getProperty("cmso.minizinc.command.mzn", "scripts/minizinc/generic_attributes.mzn");
+
+ command.add(minizinc);
+ command.add("--solver");
+ command.add(solver);
+ command.add("--time-limit");
+ command.add(timeLimit);
+ command.add("--time-limit");
+ command.add(timeLimit);
+ command.add("--soln-sep");
+ command.add("\"\"");
+ command.add("--search-complete-msg");
+ command.add("\"\"");
+ for (String add : additional.split(" ")) {
+ command.add(add);
+ }
+ command.add("-o");
+ command.add(outputFileName.toString());
+ command.add(script);
+ command.add(inputFileName.toString());
+ return command;
+ }
+
+
+}
diff --git a/cmso-optimizer/src/main/java/org/onap/optf/cmso/optimizer/clients/optimizer/OptimizerRequestManager.java b/cmso-optimizer/src/main/java/org/onap/optf/cmso/optimizer/clients/optimizer/OptimizerRequestManager.java
new file mode 100644
index 0000000..34de3df
--- /dev/null
+++ b/cmso-optimizer/src/main/java/org/onap/optf/cmso/optimizer/clients/optimizer/OptimizerRequestManager.java
@@ -0,0 +1,185 @@
+/*
+ * ============LICENSE_START==============================================
+ * Copyright (c) 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.
+ * ============LICENSE_END=================================================
+ *
+ */
+
+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;
+import org.onap.optf.cmso.optimizer.clients.optimizer.models.OptimizerEngineResponse;
+import org.onap.optf.cmso.optimizer.clients.optimizer.models.OptimizerEngineResponse.OptimizerEngineResponseStatus;
+import org.onap.optf.cmso.optimizer.clients.optimizer.models.OptimizerResults;
+import org.onap.optf.cmso.optimizer.clients.optimizer.models.OptimizerSchedule;
+import org.onap.optf.cmso.optimizer.clients.topology.TopologyRequestManager;
+import org.onap.optf.cmso.optimizer.clients.topology.models.TopologyResponse;
+import org.onap.optf.cmso.optimizer.common.LogMessages;
+import org.onap.optf.cmso.optimizer.model.Optimizer;
+import org.onap.optf.cmso.optimizer.model.Request;
+import org.onap.optf.cmso.optimizer.model.Response;
+import org.onap.optf.cmso.optimizer.model.dao.OptimizerDao;
+import org.onap.optf.cmso.optimizer.model.dao.RequestDao;
+import org.onap.optf.cmso.optimizer.model.dao.ResponseDao;
+import org.onap.optf.cmso.optimizer.service.rs.models.OptimizerRequest;
+import org.onap.optf.cmso.optimizer.service.rs.models.OptimizerResponse;
+import org.onap.optf.cmso.optimizer.service.rs.models.OptimizerResponse.OptimizeScheduleStatus;
+import org.onap.optf.cmso.optimizer.service.rs.models.OptimizerScheduleInfo;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.core.env.Environment;
+import org.springframework.stereotype.Component;
+
+/**
+ * The Class OPtimizerRequestManager.
+ */
+@Component
+public class OptimizerRequestManager {
+
+ @Autowired
+ Environment env;
+
+ @Autowired
+ RequestDao requestDao;
+
+ @Autowired
+ OptimizerDao optimizerDao;
+
+ @Autowired
+ ResponseDao responseDao;
+
+ @Autowired
+ OptimizerClient optimizerClient;
+
+ @Autowired
+ TopologyRequestManager topologyRequestManager;
+
+ /**
+ * Creates the Optimizer request.
+ *
+ * @param requestRow the request row
+ * @return the Optimizer response
+ */
+ public OptimizerEngineResponse createOptimizerRequest(Request requestRow) {
+ //
+ if (okToDispatch()) {
+ Optimizer optimizer = getExistingOptmizer(requestRow.getUuid());
+ if (optimizer == null) {
+ optimizer = new Optimizer();
+ optimizer.setUuid(requestRow.getUuid());
+ optimizer.setOptimizeRetries(0);
+ }
+ optimizer.setOptimizeStart(System.currentTimeMillis());
+ OptimizerEngineResponse apiResponse = optimizerClient.makeRequest(requestRow, optimizer);
+ if (apiResponse.getStatus() == OptimizerEngineResponseStatus.COMPLETED) {
+ optimizer.setOptimizeEnd(System.currentTimeMillis());
+ optimizer.setOptimizeResponse(""); // Perhaps we do not need to persist...
+ buildFinalResponse(requestRow, apiResponse);
+ }
+ optimizerDao.save(optimizer);
+ return apiResponse;
+ } else {
+ OptimizerEngineResponse apiResponse = new OptimizerEngineResponse();
+ apiResponse.setRequestId(requestRow.getUuid().toString());
+ apiResponse.setStatus(OptimizerEngineResponseStatus.IN_QUEUE);
+ apiResponse.setPollingSeconds(60);
+ return apiResponse;
+ }
+ }
+
+
+ private void buildFinalResponse(Request requestRow, OptimizerEngineResponse apiResponse) {
+ Optional<Response> opt = responseDao.findById(requestRow.getUuid());
+ Response responseRow = null;
+ if (opt.isPresent())
+ {
+ responseRow = opt.get();
+ }
+ if (responseRow == null)
+ {
+ responseRow = new Response();
+ responseRow.setUuid(requestRow.getUuid());
+ }
+
+ try
+ {
+ OptimizerResults results = apiResponse.getOptimizerResults();
+ OptimizerResponse response = new OptimizerResponse();
+ response.setRequestId(requestRow.getUuid().toString());
+
+ String optString = requestRow.getRequest();
+
+ OptimizerRequest optimizerResquest = new ObjectMapper().readValue(optString, OptimizerRequest.class);
+ TopologyResponse topologyResponse = topologyRequestManager.getTopologyResponse(requestRow.getUuid());
+ ElementWindowMapping ewm = new ElementWindowMapping(optimizerResquest, topologyResponse);
+ ewm.initializeForProcessResult();
+ for (OptimizerSchedule result : results.getSchedules()) {
+ OptimizerScheduleInfo info = ewm.processResult(result);
+ if (info != null) {
+ response.getSchedules().add(info);
+ }
+ }
+ responseRow.setRepsonse(new ObjectMapper().writeValueAsString(response));
+ requestRow.setStatus(OptimizeScheduleStatus.COMPLETED.toString());
+ responseDao.save(responseRow);
+ requestDao.save(requestRow);
+ }
+ catch (Exception e)
+ {
+ Observation.report(LogMessages.UNEXPECTED_EXCEPTION, e, e.getMessage());
+ requestRow.setStatus(OptimizeScheduleStatus.FAILED.toString());
+ requestRow.setMessage(e.getMessage());
+ responseRow.setRepsonse("");
+ responseDao.save(responseRow);
+ requestDao.save(requestRow);
+ }
+ }
+
+
+
+ private boolean okToDispatch() {
+ // TODO Auto-generated method stub
+
+ // Will probably change to @Async on makeRequest to queue requests in a different thread.
+ return true;
+ }
+
+
+ /**
+ * Gets the existing optimizer row.
+ *
+ * @param uuid the uuid
+ * @return the existing optmizer row
+ */
+ public Optimizer getExistingOptmizer(UUID uuid) {
+ Optional<Optimizer> oppt = optimizerDao.findById(uuid);
+ if (oppt.isPresent()) {
+ return oppt.get();
+ }
+ return null;
+ }
+
+
+ public List<OptimizerScheduleInfo> getScheduleInfo(Response responseRow) {
+ // TODO Auto-generated method stub
+ return null;
+ }
+
+
+
+}
diff --git a/cmso-optimizer/src/main/java/org/onap/optf/cmso/optimizer/clients/optimizer/models/ElementSlot.java b/cmso-optimizer/src/main/java/org/onap/optf/cmso/optimizer/clients/optimizer/models/ElementSlot.java
new file mode 100644
index 0000000..8f76b10
--- /dev/null
+++ b/cmso-optimizer/src/main/java/org/onap/optf/cmso/optimizer/clients/optimizer/models/ElementSlot.java
@@ -0,0 +1,106 @@
+/*
+ * ============LICENSE_START==============================================
+ * Copyright (c) 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.
+ * ============LICENSE_END=================================================
+ */
+
+package org.onap.optf.cmso.optimizer.clients.optimizer.models;
+
+/**
+ * The Class ElementSlot.
+ */
+/*
+ 1,0,1
+ 2,0,1
+ 3,0,1
+ 4,0,1
+ 5,0,1
+ */
+public class ElementSlot {
+ private Integer elementIndex = 0;
+ private Integer slot = 0;
+ private Integer loader = 0;
+ private Long time = 0L;
+
+ public Integer getElementIndex() {
+ return elementIndex;
+ }
+
+ public void setElementIndex(Integer elementIndex) {
+ this.elementIndex = elementIndex;
+ }
+
+ /**
+ * Gets the slot.
+ *
+ * @return the slot
+ */
+ public Integer getSlot() {
+ return slot;
+ }
+
+ /**
+ * Sets the slot.
+ *
+ * @param slot the new slot
+ */
+ public void setSlot(Integer slot) {
+ this.slot = slot;
+ }
+
+ /**
+ * Gets the loader.
+ *
+ * @return the loader
+ */
+ public Integer getLoader() {
+ return loader;
+ }
+
+ /**
+ * Sets the loader.
+ *
+ * @param loader the new loader
+ */
+ public void setLoader(Integer loader) {
+ this.loader = loader;
+ }
+
+ /**
+ * Instantiates a new element slot.
+ *
+ * @param cols the values
+ */
+ public ElementSlot(String[] cols) {
+ if (cols.length > 0) {
+ elementIndex = Integer.valueOf(cols[0]);
+ }
+ if (cols.length > 1) {
+ slot = Integer.valueOf(cols[1]);
+ }
+ if (cols.length > 2) {
+ loader = Integer.valueOf(cols[2]);
+ }
+ }
+
+ public Long getTime() {
+ return time;
+ }
+
+ public void setTime(Long time) {
+ this.time = time;
+ }
+}
+
diff --git a/cmso-optimizer/src/main/java/org/onap/optf/cmso/optimizer/clients/optimizer/models/OptimizerEngineResponse.java b/cmso-optimizer/src/main/java/org/onap/optf/cmso/optimizer/clients/optimizer/models/OptimizerEngineResponse.java
new file mode 100644
index 0000000..7315b31
--- /dev/null
+++ b/cmso-optimizer/src/main/java/org/onap/optf/cmso/optimizer/clients/optimizer/models/OptimizerEngineResponse.java
@@ -0,0 +1,65 @@
+/*
+ * ============LICENSE_START==============================================
+ * Copyright (c) 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.
+ * ============LICENSE_END=================================================
+ */
+
+package org.onap.optf.cmso.optimizer.clients.optimizer.models;
+
+public class OptimizerEngineResponse
+{
+
+ public enum OptimizerEngineResponseStatus {
+ IN_PROGRESS, COMPLETED, FAILED, IN_QUEUE,
+ }
+
+ private String requestId;
+ private OptimizerResults optimizerResults;
+ private OptimizerEngineResponseStatus status;
+ private Integer pollingSeconds;
+ private String errorMessage;
+ public String getRequestId() {
+ return requestId;
+ }
+ public void setRequestId(String requestId) {
+ this.requestId = requestId;
+ }
+ public OptimizerResults getOptimizerResults() {
+ return optimizerResults;
+ }
+ public void setOptimizerResults(OptimizerResults oprimizerResults) {
+ this.optimizerResults = oprimizerResults;
+ }
+ public OptimizerEngineResponseStatus getStatus() {
+ return status;
+ }
+ public void setStatus(OptimizerEngineResponseStatus status) {
+ this.status = status;
+ }
+ public Integer getPollingSeconds() {
+ return pollingSeconds;
+ }
+ public void setPollingSeconds(Integer pollingSeconds) {
+ this.pollingSeconds = pollingSeconds;
+ }
+ public String getErrorMessage() {
+ return errorMessage;
+ }
+ public void setErrorMessage(String errorMessage) {
+ this.errorMessage = errorMessage;
+ }
+
+
+}
diff --git a/cmso-optimizer/src/main/java/org/onap/optf/cmso/optimizer/clients/optimizer/models/OptimizerOutResults.java b/cmso-optimizer/src/main/java/org/onap/optf/cmso/optimizer/clients/optimizer/models/OptimizerOutResults.java
new file mode 100644
index 0000000..2c1c777
--- /dev/null
+++ b/cmso-optimizer/src/main/java/org/onap/optf/cmso/optimizer/clients/optimizer/models/OptimizerOutResults.java
@@ -0,0 +1,46 @@
+/*
+ * ============LICENSE_START==============================================
+ * Copyright (c) 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.
+ * ============LICENSE_END=================================================
+ */
+
+package org.onap.optf.cmso.optimizer.clients.optimizer.models;
+
+import java.util.List;
+
+/*
+
+ */
+public class OptimizerOutResults {
+ private Long elapsedMillis;
+ private List<OptimizerOutSchedule> results;
+
+ public Long getElapsedMillis() {
+ return elapsedMillis;
+ }
+
+ public void setElapsedMillis(Long elapsed_millis) {
+ this.elapsedMillis = elapsed_millis;
+ }
+
+ public List<OptimizerOutSchedule> getResults() {
+ return results;
+ }
+
+ public void setResults(List<OptimizerOutSchedule> schedules) {
+ this.results = schedules;
+ }
+
+}
diff --git a/cmso-optimizer/src/main/java/org/onap/optf/cmso/optimizer/clients/optimizer/models/OptimizerOutSchedule.java b/cmso-optimizer/src/main/java/org/onap/optf/cmso/optimizer/clients/optimizer/models/OptimizerOutSchedule.java
new file mode 100644
index 0000000..abcebf2
--- /dev/null
+++ b/cmso-optimizer/src/main/java/org/onap/optf/cmso/optimizer/clients/optimizer/models/OptimizerOutSchedule.java
@@ -0,0 +1,60 @@
+/*
+ * ============LICENSE_START==============================================
+ * Copyright (c) 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.
+ * ============LICENSE_END=================================================
+ */
+
+package org.onap.optf.cmso.optimizer.clients.optimizer.models;
+
+/*
+num_scheduled: 0
+total_completion_time: 0
+element_slot_loader: |
+ 1,0,1
+ 2,0,1
+ 3,0,1
+ 4,0,1
+ 5,0,1
+ */
+public class OptimizerOutSchedule {
+ private Long numScheduled;
+ private Long totalCompletionTime;
+ private String elementSlotLoader;
+
+ public Long getNumScheduled() {
+ return numScheduled;
+ }
+
+ public void setNumScheduled(Long numScheduled) {
+ this.numScheduled = numScheduled;
+ }
+
+ public Long getTotalCompletionTime() {
+ return totalCompletionTime;
+ }
+
+ public void setTotalCompletionTime(Long totalCompletionTime) {
+ this.totalCompletionTime = totalCompletionTime;
+ }
+
+ public String getElementSlotLoader() {
+ return elementSlotLoader;
+ }
+
+ public void setElementSlotLoader(String elementSlotLoader) {
+ this.elementSlotLoader = elementSlotLoader;
+ }
+}
+
diff --git a/cmso-optimizer/src/main/java/org/onap/optf/cmso/optimizer/clients/optimizer/models/OptimizerOutYaml.java b/cmso-optimizer/src/main/java/org/onap/optf/cmso/optimizer/clients/optimizer/models/OptimizerOutYaml.java
new file mode 100644
index 0000000..c9c16cb
--- /dev/null
+++ b/cmso-optimizer/src/main/java/org/onap/optf/cmso/optimizer/clients/optimizer/models/OptimizerOutYaml.java
@@ -0,0 +1,65 @@
+/*
+ * ============LICENSE_START==============================================
+ * Copyright (c) 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.
+ * ============LICENSE_END=================================================
+ */
+
+package org.onap.optf.cmso.optimizer.clients.optimizer.models;
+
+/*
+results:
+ result:
+ num_scheduled: 0
+ total_completion_time: 0
+ element_slot_loader: |
+ 1,0,1
+ 2,0,1
+ 3,0,1
+ 4,0,1
+ 5,0,1
+ result:
+ num_scheduled: 1
+ total_completion_time: 2
+ element_slot_loader: |
+ 1,0,1
+ 2,0,1
+ 3,2,1
+ 4,0,1
+ 5,0,1
+ result:
+ num_scheduled: 4
+ total_completion_time: 8
+ element_slot_loader: |
+ 1,2,1
+ 2,1,1
+ 3,2,1
+ 4,0,1
+ 5,3,1
+ elapsed_millis: 3400
+
+ */
+public class OptimizerOutYaml {
+
+ private OptimizerOutResults results;
+
+ public OptimizerOutResults getResults() {
+ return results;
+ }
+
+ public void setResults(OptimizerOutResults results) {
+ this.results = results;
+ }
+
+}
diff --git a/cmso-optimizer/src/main/java/org/onap/optf/cmso/optimizer/clients/optimizer/models/OptimizerParameters.java b/cmso-optimizer/src/main/java/org/onap/optf/cmso/optimizer/clients/optimizer/models/OptimizerParameters.java
new file mode 100644
index 0000000..be74e37
--- /dev/null
+++ b/cmso-optimizer/src/main/java/org/onap/optf/cmso/optimizer/clients/optimizer/models/OptimizerParameters.java
@@ -0,0 +1,225 @@
+/*
+ * ============LICENSE_START==============================================
+ * Copyright (c) 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.
+ * ============LICENSE_END=================================================
+ */
+
+package org.onap.optf.cmso.optimizer.clients.optimizer.models;
+
+import java.util.ArrayList;
+import java.util.List;
+
+
+/*
+ * numElements = 5;
+maxTime = 5;
+numLoaders = 1;
+noConflict = [| true , true , true , true , true
+ | true , true , true , true , true
+ | false , true , false , true , false
+ | false , false , false , false , false
+ | true , false , true , false , true
+ |];
+slotCapacity = [5, 5, 5, 5, 5];
+loaderCapacity = [|
+5, 5, 5, 5, 5
+|];
+
+
+numAttributes = 0;
+attributesRange = [];
+attributes = [];
+attributeConcurrencyLimit = [];
+ */
+public class OptimizerParameters {
+ private Long numElements;
+ private Long numLoaders;
+ private List<Long> elementSlotCapacity = new ArrayList<>();
+ private Long maxTime;
+ private List<List<Boolean>> noConflict = new ArrayList<>();
+ private List<List<Long>> loaderCapacity = new ArrayList<>();
+
+ private Long numAttributes;
+ private List<Long> attributesRange = new ArrayList<>();
+ private List<List<Long>> attributes = new ArrayList<>();
+ private List<List<Long>> attributeConcurrencyLimit = new ArrayList<>();
+
+ public Long getNumElements() {
+ return numElements;
+ }
+
+ public void setNumElements(Long numElements) {
+ this.numElements = numElements;
+ }
+
+ public Long getMaxTime() {
+ return maxTime;
+ }
+
+ public void setMaxTime(Long maxTime) {
+ this.maxTime = maxTime;
+ }
+
+ public Long getNumLoaders() {
+ return numLoaders;
+ }
+
+ public void setNumLoaders(Long numLoaders) {
+ this.numLoaders = numLoaders;
+ }
+
+ public List<List<Boolean>> getNoConflict() {
+ return noConflict;
+ }
+
+ public void setNoConflict(List<List<Boolean>> noConflict) {
+ this.noConflict = noConflict;
+ }
+
+ public List<Long> getElementSlotCapacity() {
+ return elementSlotCapacity;
+ }
+
+ public void setElementSlotCapacity(List<Long> slotCapacity) {
+ this.elementSlotCapacity = slotCapacity;
+ }
+
+ public List<List<Long>> getLoaderCapacity() {
+ return loaderCapacity;
+ }
+
+ public void setLoaderCapacity(List<List<Long>> loaderCapacity) {
+ this.loaderCapacity = loaderCapacity;
+ }
+
+ public Long getNumAttributes() {
+ return numAttributes;
+ }
+
+ public void setNumAttributes(Long numAttributes) {
+ this.numAttributes = numAttributes;
+ }
+
+ public List<Long> getAttributesRange() {
+ return attributesRange;
+ }
+
+ public void setAttributesRange(List<Long> attributesRange) {
+ this.attributesRange = attributesRange;
+ }
+
+ public List<List<Long>> getAttributes() {
+ return attributes;
+ }
+
+ public void setAttributes(List<List<Long>> attributes) {
+ this.attributes = attributes;
+ }
+
+ public List<List<Long>> getAttributeConcurrencyLimit() {
+ return attributeConcurrencyLimit;
+ }
+
+ public void setAttributeConcurrencyLimit(List<List<Long>> attributeConcurrencyLimit) {
+ this.attributeConcurrencyLimit = attributeConcurrencyLimit;
+ }
+
+
+
+ public String toMiniZinc() {
+ StringBuilder sb = new StringBuilder();
+ appendAttribute(sb, "numElements", numElements.toString());
+ appendAttribute(sb, "maxTime", maxTime.toString());
+ appendAttribute(sb, "numLoaders", numLoaders.toString());
+ appendAttribute(sb, "numAttributes", numAttributes.toString());
+
+ appendAttribute(sb, "noConflict", "[|\n" + formatBooleanRows(noConflict) + "|]");
+ appendAttribute(sb, "elementSlotCapacity", "[" + formatLongList(elementSlotCapacity) + "]");
+ appendAttribute(sb, "loaderCapacity", "[|\n" + formatLongRows(loaderCapacity) + "|]");
+
+
+ if (attributesRange.size() > 0) {
+ appendAttribute(sb, "attributesRange", "[" + formatLongList(attributesRange) + "]");
+ }
+ else {
+ appendAttribute(sb, "attributesRange", "[]");
+ }
+ if (attributes.size() > 0) {
+ appendAttribute(sb, "attributes", "[|\n" + formatLongRows(attributes) + "|]");
+ }
+ else {
+ appendAttribute(sb, "attributes", "array2d(1..numElements, 1..numAttributes, [])");
+ }
+ if (attributeConcurrencyLimit.size() > 0) {
+ appendAttribute(sb, "attributeConcurrencyLimit", "[|\n" + formatLongRows(attributeConcurrencyLimit) + "|]");
+ }
+ else
+ {
+ appendAttribute(sb, "attributeConcurrencyLimit", "array2d(1..numAttributes, 1..maxTime, [])");
+ }
+ return sb.toString();
+ }
+
+ private void appendAttribute(StringBuilder sb, String name, String value) {
+ sb.append(name).append(" = ").append(value).append(";\n");
+ }
+
+ // Methods to dump minizinc parameters. THese may be very large
+ //
+ private String formatBooleanRows(List<List<Boolean>> list) {
+ StringBuilder sb = new StringBuilder();
+ String row = "";
+ for (List<Boolean> objectList : list) {
+ sb.append(row).append(formatBooleanList(objectList));
+ row = "| ";
+ }
+ sb.append("\n");
+ return sb.toString();
+ }
+
+ private String formatBooleanList(List<Boolean> list) {
+ StringBuilder sb = new StringBuilder();
+ String comma = "";
+ for (Object object : list) {
+ sb.append(comma).append(object.toString());
+ comma = ", ";
+ }
+ return sb.toString();
+ }
+
+ private String formatLongRows(List<List<Long>> list) {
+ StringBuilder sb = new StringBuilder();
+ String row = "";
+ for (List<Long> objectList : list) {
+ sb.append(row).append(formatLongList(objectList));
+ row = "| ";
+ }
+ sb.append("\n");
+ return sb.toString();
+ }
+
+ private String formatLongList(List<Long> list) {
+ StringBuilder sb = new StringBuilder();
+ String comma = "";
+ for (Object object : list) {
+ sb.append(comma).append(object.toString());
+ comma = ", ";
+ }
+ return sb.toString();
+ }
+
+}
+
+
diff --git a/cmso-optimizer/src/main/java/org/onap/optf/cmso/optimizer/clients/optimizer/models/OptimizerResponseUtility.java b/cmso-optimizer/src/main/java/org/onap/optf/cmso/optimizer/clients/optimizer/models/OptimizerResponseUtility.java
new file mode 100644
index 0000000..89208b2
--- /dev/null
+++ b/cmso-optimizer/src/main/java/org/onap/optf/cmso/optimizer/clients/optimizer/models/OptimizerResponseUtility.java
@@ -0,0 +1,82 @@
+/*
+ * ============LICENSE_START==============================================
+ * Copyright (c) 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.
+ * ============LICENSE_END=================================================
+ */
+
+package org.onap.optf.cmso.optimizer.clients.optimizer.models;
+
+import com.google.common.base.CaseFormat;
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.InputStream;
+import java.util.ArrayList;
+import java.util.List;
+import org.onap.observations.Observation;
+import org.onap.optf.cmso.optimizer.common.LogMessages;
+import org.yaml.snakeyaml.Yaml;
+import org.yaml.snakeyaml.constructor.Constructor;
+import org.yaml.snakeyaml.introspector.Property;
+import org.yaml.snakeyaml.introspector.PropertyUtils;
+
+public class OptimizerResponseUtility extends PropertyUtils {
+
+ public OptimizerResults parseOptimizerResult(File resultsFile) {
+ OptimizerResults results = null;
+ try (InputStream input = new FileInputStream(resultsFile)) {
+ Constructor constructor = new Constructor(OptimizerOutResults.class);
+ constructor.setPropertyUtils(this);
+ Yaml yaml = new Yaml(constructor);
+ OptimizerOutResults optimizerOut = yaml.load(input);
+ results = marshall(optimizerOut);
+ } catch (Exception e) {
+ Observation.report(LogMessages.UNEXPECTED_EXCEPTION, e, e.getMessage());
+ }
+ return results;
+ }
+
+ private OptimizerResults marshall(OptimizerOutResults optimizerOut) {
+ OptimizerResults results = new OptimizerResults();
+ results.setElapsedMillis(optimizerOut.getElapsedMillis());
+ List<OptimizerSchedule> schedules = new ArrayList<>();
+ results.setSchedules(schedules);
+ for (OptimizerOutSchedule sch : optimizerOut.getResults()) {
+ schedules.add(marshall(sch));
+ }
+ return results;
+ }
+
+ private OptimizerSchedule marshall(OptimizerOutSchedule sch) {
+ OptimizerSchedule optimizerSchedule = new OptimizerSchedule();
+ optimizerSchedule.setNumScheduled(sch.getNumScheduled());
+ optimizerSchedule.setTotalCompletionTime(sch.getTotalCompletionTime());
+ String[] rows = sch.getElementSlotLoader().split("\n");
+ List<ElementSlot> slots = new ArrayList<>();
+ optimizerSchedule.setElementSlotLoader(slots);
+ for (String row : rows) {
+ String[] cols = row.split(",");
+ ElementSlot slot = new ElementSlot(cols);
+ slots.add(slot);
+ }
+ return optimizerSchedule;
+ }
+
+ @Override
+ public Property getProperty(Class<? extends Object> type, String name) {
+ name = CaseFormat.LOWER_UNDERSCORE.to(CaseFormat.LOWER_CAMEL, name);
+ return super.getProperty(type, name);
+ }
+
+}
diff --git a/cmso-optimizer/src/main/java/org/onap/optf/cmso/optimizer/clients/optimizer/models/OptimizerResults.java b/cmso-optimizer/src/main/java/org/onap/optf/cmso/optimizer/clients/optimizer/models/OptimizerResults.java
new file mode 100644
index 0000000..9c31a9f
--- /dev/null
+++ b/cmso-optimizer/src/main/java/org/onap/optf/cmso/optimizer/clients/optimizer/models/OptimizerResults.java
@@ -0,0 +1,46 @@
+/*
+ * ============LICENSE_START==============================================
+ * Copyright (c) 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.
+ * ============LICENSE_END=================================================
+ */
+
+package org.onap.optf.cmso.optimizer.clients.optimizer.models;
+
+import java.util.List;
+
+/*
+
+ */
+public class OptimizerResults {
+ private Long elapsedMillis;
+ private List<OptimizerSchedule> schedules;
+
+ public Long getElapsedMillis() {
+ return elapsedMillis;
+ }
+
+ public void setElapsedMillis(Long elapsed_millis) {
+ this.elapsedMillis = elapsed_millis;
+ }
+
+ public List<OptimizerSchedule> getSchedules() {
+ return schedules;
+ }
+
+ public void setSchedules(List<OptimizerSchedule> schedules) {
+ this.schedules = schedules;
+ }
+
+}
diff --git a/cmso-optimizer/src/main/java/org/onap/optf/cmso/optimizer/clients/optimizer/models/OptimizerSchedule.java b/cmso-optimizer/src/main/java/org/onap/optf/cmso/optimizer/clients/optimizer/models/OptimizerSchedule.java
new file mode 100644
index 0000000..d4bc008
--- /dev/null
+++ b/cmso-optimizer/src/main/java/org/onap/optf/cmso/optimizer/clients/optimizer/models/OptimizerSchedule.java
@@ -0,0 +1,63 @@
+/*
+ * ============LICENSE_START==============================================
+ * Copyright (c) 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.
+ * ============LICENSE_END=================================================
+ */
+
+package org.onap.optf.cmso.optimizer.clients.optimizer.models;
+
+import java.util.List;
+
+/*
+num_scheduled: 0
+total_completion_time: 0
+element_slot_loader: |
+ 1,0,1
+ 2,0,1
+ 3,0,1
+ 4,0,1
+ 5,0,1
+ */
+public class OptimizerSchedule {
+ private Long numScheduled;
+ private Long totalCompletionTime;
+ private List<ElementSlot> elementSlotLoader;
+
+ public Long getNumScheduled() {
+ return numScheduled;
+ }
+
+ public void setNumScheduled(Long numScheduled) {
+ this.numScheduled = numScheduled;
+ }
+
+ public Long getTotalCompletionTime() {
+ return totalCompletionTime;
+ }
+
+ public void setTotalCompletionTime(Long totalCompletionTime) {
+ this.totalCompletionTime = totalCompletionTime;
+ }
+
+ public List<ElementSlot> getElementSlotLoader() {
+ return elementSlotLoader;
+ }
+
+ public void setElementSlotLoader(List<ElementSlot> elementSlotLoader) {
+ this.elementSlotLoader = elementSlotLoader;
+ }
+
+}
+
diff --git a/cmso-optimizer/src/main/java/org/onap/optf/cmso/optimizer/clients/optimizer/models/Results.java b/cmso-optimizer/src/main/java/org/onap/optf/cmso/optimizer/clients/optimizer/models/Results.java
new file mode 100644
index 0000000..402bdf2
--- /dev/null
+++ b/cmso-optimizer/src/main/java/org/onap/optf/cmso/optimizer/clients/optimizer/models/Results.java
@@ -0,0 +1,46 @@
+/*
+ * ============LICENSE_START==============================================
+ * Copyright (c) 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.
+ * ============LICENSE_END=================================================
+ */
+
+package org.onap.optf.cmso.optimizer.clients.optimizer.models;
+
+import java.util.List;
+
+/*
+
+ */
+public class Results {
+ private Long elapsedMillis;
+ private List<OptimizerSchedule> schedules;
+
+ public Long getElapsedMillis() {
+ return elapsedMillis;
+ }
+
+ public void setElapsedMillis(Long elapsed_millis) {
+ this.elapsedMillis = elapsed_millis;
+ }
+
+ public List<OptimizerSchedule> getSchedules() {
+ return schedules;
+ }
+
+ public void setSchedules(List<OptimizerSchedule> schedules) {
+ this.schedules = schedules;
+ }
+
+}
diff --git a/cmso-optimizer/src/main/java/org/onap/optf/cmso/optimizer/clients/ticketmgt/TicketMgtRequestManager.java b/cmso-optimizer/src/main/java/org/onap/optf/cmso/optimizer/clients/ticketmgt/TicketMgtRequestManager.java
index 8c7dfb6..8520809 100644
--- a/cmso-optimizer/src/main/java/org/onap/optf/cmso/optimizer/clients/ticketmgt/TicketMgtRequestManager.java
+++ b/cmso-optimizer/src/main/java/org/onap/optf/cmso/optimizer/clients/ticketmgt/TicketMgtRequestManager.java
@@ -20,11 +20,13 @@
package org.onap.optf.cmso.optimizer.clients.ticketmgt;
import java.util.Optional;
+import java.util.UUID;
import org.onap.observations.Observation;
import org.onap.optf.cmso.optimizer.clients.ticketmgt.models.ActiveTicketsResponse;
import org.onap.optf.cmso.optimizer.common.LogMessages;
import org.onap.optf.cmso.optimizer.model.Request;
import org.onap.optf.cmso.optimizer.model.Ticket;
+import org.onap.optf.cmso.optimizer.model.Topology;
import org.onap.optf.cmso.optimizer.model.dao.RequestDao;
import org.onap.optf.cmso.optimizer.model.dao.TicketDao;
import org.springframework.beans.factory.annotation.Autowired;
@@ -53,13 +55,12 @@ public class TicketMgtRequestManager {
TicketMgtClient ticketmgtClient;
/**
- * Creates the topology request.
+ * Creates the tickets request.
*
* @param requestRow the uuid
* @return the active tickets response
*/
public ActiveTicketsResponse createTicketsRequest(Request requestRow) {
- try {
Ticket row = null;
Optional<Ticket> rowOpt = ticketDao.findById(requestRow.getUuid());
if (rowOpt.isPresent()) {
@@ -72,22 +73,21 @@ public class TicketMgtRequestManager {
row.setTicketsRetries(0);
}
ActiveTicketsResponse apiResponse = ticketmgtClient.makeRequest(requestRow, row);
- switch (apiResponse.getStatus()) {
- case COMPLETED:
- break;
- case FAILED:
- break;
- case IN_PROGRESS:
- break;
- default:
- break;
- }
+ ticketDao.save(row);
return apiResponse;
- } catch (Exception e) {
- Observation.report(LogMessages.UNEXPECTED_EXCEPTION, e, e.getMessage());
+ }
+ /**
+ * Gets the existing tickets.
+ *
+ * @param uuid the uuid
+ * @return the existing tickets
+ */
+ public Ticket getExistingTickets(UUID uuid) {
+ Optional<Ticket> opt = ticketDao.findById(uuid);
+ if (opt.isPresent()) {
+ return opt.get();
}
return null;
-
}
}
diff --git a/cmso-optimizer/src/main/java/org/onap/optf/cmso/optimizer/clients/topology/TopologyRequestManager.java b/cmso-optimizer/src/main/java/org/onap/optf/cmso/optimizer/clients/topology/TopologyRequestManager.java
index ce0d583..a1cb51d 100644
--- a/cmso-optimizer/src/main/java/org/onap/optf/cmso/optimizer/clients/topology/TopologyRequestManager.java
+++ b/cmso-optimizer/src/main/java/org/onap/optf/cmso/optimizer/clients/topology/TopologyRequestManager.java
@@ -19,6 +19,10 @@
package org.onap.optf.cmso.optimizer.clients.topology;
+import com.fasterxml.jackson.core.JsonParseException;
+import com.fasterxml.jackson.databind.JsonMappingException;
+import com.fasterxml.jackson.databind.ObjectMapper;
+import java.io.IOException;
import java.util.Optional;
import java.util.UUID;
import org.onap.optf.cmso.optimizer.clients.topology.models.TopologyResponse;
@@ -81,4 +85,15 @@ public class TopologyRequestManager {
}
return null;
}
+
+
+ public TopologyResponse getTopologyResponse(UUID uuid) throws JsonParseException, JsonMappingException, IOException {
+ Topology row = getExistingTopology(uuid);
+ if (row != null)
+ {
+ String responseString = row.getTopology();
+ return new ObjectMapper().readValue(responseString, TopologyResponse.class);
+ }
+ return null;
+ }
}
diff --git a/cmso-optimizer/src/main/java/org/onap/optf/cmso/optimizer/common/LogMessages.java b/cmso-optimizer/src/main/java/org/onap/optf/cmso/optimizer/common/LogMessages.java
index f36caee..f8d23eb 100644
--- a/cmso-optimizer/src/main/java/org/onap/optf/cmso/optimizer/common/LogMessages.java
+++ b/cmso-optimizer/src/main/java/org/onap/optf/cmso/optimizer/common/LogMessages.java
@@ -85,6 +85,8 @@ public enum LogMessages implements ObservationInterface {
Level.ERROR),
FAILED_TO_CREATE_OPTIMIZER_REQUEST("Failed to create optimizer request for id={0}", Status.INTERNAL_SERVER_ERROR,
Level.ERROR),
+ OPTIMIZER_REQUEST_TIMEOUT("Optimizer engine request timed out id={0} timelimit={1}", Status.INTERNAL_SERVER_ERROR,
+ Level.ERROR),
;
private final String defaultId;
diff --git a/cmso-optimizer/src/main/java/org/onap/optf/cmso/optimizer/core/OptimizerManager.java b/cmso-optimizer/src/main/java/org/onap/optf/cmso/optimizer/core/OptimizerManager.java
index 43ecf3f..eabebec 100644
--- a/cmso-optimizer/src/main/java/org/onap/optf/cmso/optimizer/core/OptimizerManager.java
+++ b/cmso-optimizer/src/main/java/org/onap/optf/cmso/optimizer/core/OptimizerManager.java
@@ -26,13 +26,17 @@ import java.util.Optional;
import java.util.UUID;
import javax.ws.rs.core.Response.Status;
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;
import org.onap.optf.cmso.optimizer.clients.ticketmgt.TicketMgtRequestManager;
import org.onap.optf.cmso.optimizer.clients.ticketmgt.models.ActiveTicketsResponse;
import org.onap.optf.cmso.optimizer.clients.topology.TopologyRequestManager;
import org.onap.optf.cmso.optimizer.clients.topology.models.TopologyResponse;
import org.onap.optf.cmso.optimizer.common.LogMessages;
import org.onap.optf.cmso.optimizer.model.Request;
+import org.onap.optf.cmso.optimizer.model.Response;
import org.onap.optf.cmso.optimizer.model.dao.RequestDao;
+import org.onap.optf.cmso.optimizer.model.dao.ResponseDao;
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;
@@ -51,11 +55,17 @@ public class OptimizerManager {
RequestDao requestDao;
@Autowired
+ ResponseDao responseDao;
+
+ @Autowired
TopologyRequestManager topologyRequestManager;
@Autowired
TicketMgtRequestManager ticketMgtRequestManager;
+ @Autowired
+ OptimizerRequestManager optimizerRequestManager;
+
/**
* Validate optimizer request.
*
@@ -147,13 +157,22 @@ public class OptimizerManager {
} catch (JsonProcessingException e) {
throw new CmsoException(Status.BAD_REQUEST, LogMessages.INVALID_REQUEST, e.getMessage());
}
- requestRow.setStatus(OptimizeScheduleStatus.FAILED.toString());
+ requestRow.setStatus(OptimizeScheduleStatus.PENDING_TOPOLOGY.toString());
requestDao.save(requestRow);
initiateDataGathering(requestRow);
requestDao.save(requestRow);
OptimizeScheduleStatus status = OptimizeScheduleStatus.valueOf(requestRow.getStatus());
- optimizerResponse.setStatus(status);
- optimizerResponse.setErrorMessage("");
+ if (status == OptimizeScheduleStatus.COMPLETED)
+ {
+ // COmpletely synchronous optimization
+ optimizerResponse = getCompletedOptimizerResponse(uuid);
+ }
+ else
+ {
+ // One or more steps are asynchronous
+ optimizerResponse.setStatus(status);
+ optimizerResponse.setErrorMessage("");
+ }
return optimizerResponse;
}
@@ -174,8 +193,8 @@ public class OptimizerManager {
return;
case IN_PROGRESS:
requestRow.setRequestStart(System.currentTimeMillis());
- requestRow.setStatus(OptimizeScheduleStatus.PENDING_TOPOLOGY.toString());
- break;
+ requestRow.setStatus(OptimizeScheduleStatus.TOPOLOGY_IN_PROGRESS.toString());
+ return;
default:
break;
}
@@ -192,17 +211,17 @@ public class OptimizerManager {
requestRow.setRequestStart(System.currentTimeMillis());
requestRow.setStatus(OptimizeScheduleStatus.PENDING_OPTIMIZER.toString());
initiateOptimizer(requestRow);
- break;
+ return;
case FAILED:
requestRow.setRequestStart(System.currentTimeMillis());
requestRow.setRequestEnd(System.currentTimeMillis());
requestRow.setStatus(OptimizeScheduleStatus.FAILED.toString());
requestRow.setMessage(apiResponse.getErrorMessage());
- break;
+ return;
case IN_PROGRESS:
requestRow.setRequestStart(System.currentTimeMillis());
- requestRow.setStatus(OptimizeScheduleStatus.PENDING_TICKETS.toString());
- break;
+ requestRow.setStatus(OptimizeScheduleStatus.TICKETS_IN_PROGRESS.toString());
+ return;
default:
break;
}
@@ -212,9 +231,54 @@ public class OptimizerManager {
}
- private void initiateOptimizer(Request requestRow) {
- // TODO Auto-generated method stub
+ private void initiateOptimizer(Request requestRow) throws CmsoException {
+ OptimizerEngineResponse apiResponse = optimizerRequestManager.createOptimizerRequest(requestRow);
+ if (apiResponse != null) {
+ switch (apiResponse.getStatus()) {
+ case COMPLETED:
+ requestRow.setRequestEnd(System.currentTimeMillis());
+ requestRow.setStatus(OptimizeScheduleStatus.COMPLETED.toString());
+ return;
+ case FAILED:
+ requestRow.setRequestStart(System.currentTimeMillis());
+ requestRow.setRequestEnd(System.currentTimeMillis());
+ requestRow.setStatus(OptimizeScheduleStatus.FAILED.toString());
+ requestRow.setMessage(apiResponse.getErrorMessage());
+ return;
+ case IN_PROGRESS:
+ case IN_QUEUE:
+ requestRow.setRequestStart(System.currentTimeMillis());
+ requestRow.setStatus(OptimizeScheduleStatus.OPTIMIZER_IN_PROGRESS.toString());
+ return;
+ default:
+ break;
+ }
+ }
+ throw new CmsoException(Status.INTERNAL_SERVER_ERROR, LogMessages.FAILED_TO_CREATE_TICKET_REQUEST,
+ requestRow.getUuid().toString());
+ }
+ public OptimizerResponse getCompletedOptimizerResponse(UUID uuid)
+ {
+ OptimizerResponse response = new OptimizerResponse();
+ response.setRequestId(uuid.toString());
+ response.setStatus(OptimizeScheduleStatus.COMPLETED);
+ Response responseRow = getResponseRow(uuid);
+ if (responseRow != null)
+ {
+ response.setSchedules(optimizerRequestManager.getScheduleInfo(responseRow));
+ }
+ return response;
+ }
+
+ public Response getResponseRow(UUID uuid)
+ {
+ Optional<Response> opt = responseDao.findById(uuid);
+ if (opt.isPresent())
+ {
+ return opt.get();
+ }
+ return null;
}
@SuppressWarnings("unused")
@@ -225,7 +289,7 @@ public class OptimizerManager {
return requestOptional.get();
}
throw new CmsoException(Status.INTERNAL_SERVER_ERROR, LogMessages.EXPECTED_DATA_NOT_FOUND,
- requestRow.toString(), "Request table");
+ uuid.toString(), "Request table");
}
diff --git a/cmso-optimizer/src/main/java/org/onap/optf/cmso/optimizer/service/rs/models/ChangeWindow.java b/cmso-optimizer/src/main/java/org/onap/optf/cmso/optimizer/service/rs/models/ChangeWindow.java
index d0af5c4..4eb6824 100644
--- a/cmso-optimizer/src/main/java/org/onap/optf/cmso/optimizer/service/rs/models/ChangeWindow.java
+++ b/cmso-optimizer/src/main/java/org/onap/optf/cmso/optimizer/service/rs/models/ChangeWindow.java
@@ -33,6 +33,7 @@ import com.fasterxml.jackson.databind.ObjectMapper;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import java.io.Serializable;
+import java.time.Instant;
import java.util.Date;
import org.springframework.format.annotation.DateTimeFormat;
@@ -111,6 +112,38 @@ public class ChangeWindow implements Serializable {
}
/**
+ * Test if this window contains the passed window.
+ *
+ * @param test the test
+ * @return true, if this change window contains the passed change window
+ */
+ public boolean contains(ChangeWindow test) {
+ if (!test.getStartTime().before(getStartTime()) && !test.getEndTime().after(getEndTime())) {
+ return true;
+ }
+ return false;
+ }
+
+ /**
+ * Passed slot time (test) is within this change window adjusted for the time zone of the element.
+ * This is used to interpret global relative availability (maintenance) windows as opposed to
+ * absolute UTC times provided in tickets which should already be adjusted for time zone.
+ *
+ * @param test the test
+ * @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)) {
+ return true;
+ }
+ return false;
+ }
+
+ /**
* Absorb if overlapping window.
*
* @param test the test window
@@ -145,4 +178,5 @@ public class ChangeWindow implements Serializable {
return "";
}
+
}
diff --git a/cmso-optimizer/src/main/java/org/onap/optf/cmso/optimizer/service/rs/models/OptimizerResponse.java b/cmso-optimizer/src/main/java/org/onap/optf/cmso/optimizer/service/rs/models/OptimizerResponse.java
index 2f8e705..b8b5a21 100644
--- a/cmso-optimizer/src/main/java/org/onap/optf/cmso/optimizer/service/rs/models/OptimizerResponse.java
+++ b/cmso-optimizer/src/main/java/org/onap/optf/cmso/optimizer/service/rs/models/OptimizerResponse.java
@@ -42,7 +42,16 @@ public class OptimizerResponse implements Serializable {
private static EELFLogger log = EELFManager.getInstance().getLogger(OptimizerResponse.class);
public enum OptimizeScheduleStatus {
- CREATED, PENDING_TOPOLOGY, PENDING_TICKETS, PENDING_OPTIMIZER, COMPLETED, FAILED, DELETED,
+ CREATED,
+ PENDING_TOPOLOGY,
+ TOPOLOGY_IN_PROGRESS,
+ PENDING_TICKETS,
+ TICKETS_IN_PROGRESS,
+ PENDING_OPTIMIZER,
+ OPTIMIZER_IN_PROGRESS,
+ COMPLETED,
+ FAILED,
+ DELETED,
}
@ApiModelProperty(value = "Unique Id of the request")
diff --git a/cmso-optimizer/src/test/data/resultsTest001.yaml b/cmso-optimizer/src/test/data/resultsTest001.yaml
new file mode 100644
index 0000000..1c7eed6
--- /dev/null
+++ b/cmso-optimizer/src/test/data/resultsTest001.yaml
@@ -0,0 +1,28 @@
+results:
+ - num_scheduled: 0
+ total_completion_time: 0
+ element_slot_loader: |
+ 1,0,1
+ 2,0,1
+ 3,0,1
+ 4,0,1
+ 5,0,1
+ -
+ num_scheduled: 1
+ total_completion_time: 2
+ element_slot_loader: |
+ 1,0,1
+ 2,0,1
+ 3,2,1
+ 4,0,1
+ 5,0,1
+ -
+ num_scheduled: 4
+ total_completion_time: 8
+ element_slot_loader: |
+ 1,2,1
+ 2,1,1
+ 3,2,1
+ 4,0,1
+ 5,3,1
+elapsed_millis: 3400 \ No newline at end of file
diff --git a/cmso-optimizer/src/test/java/org/onap/optf/cmso/optimizer/clients/optimizer/models/ResultsTest.java b/cmso-optimizer/src/test/java/org/onap/optf/cmso/optimizer/clients/optimizer/models/ResultsTest.java
new file mode 100644
index 0000000..ddbee2f
--- /dev/null
+++ b/cmso-optimizer/src/test/java/org/onap/optf/cmso/optimizer/clients/optimizer/models/ResultsTest.java
@@ -0,0 +1,40 @@
+/*
+ * ============LICENSE_START==============================================
+ * Copyright (c) 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.
+ * ============LICENSE_END=================================================
+ */
+
+package org.onap.optf.cmso.optimizer.clients.optimizer.models;
+
+import java.io.File;
+import org.junit.Assert;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.mockito.runners.MockitoJUnitRunner;
+import org.yaml.snakeyaml.introspector.PropertyUtils;
+
+@RunWith(MockitoJUnitRunner.class)
+public class ResultsTest extends PropertyUtils {
+ @Test
+ public void yamlTests() {
+ OptimizerResponseUtility util = new OptimizerResponseUtility();
+ File resultsFile = new File("src/test/data/resultsTest001.yaml");
+ OptimizerResults results = util.parseOptimizerResult(resultsFile);
+ Assert.assertTrue(results != null);
+
+ }
+
+
+}
diff --git a/cmso-optimizer/src/test/java/org/onap/optf/cmso/optimizer/service/rs/models/ChangeWindowTest.java b/cmso-optimizer/src/test/java/org/onap/optf/cmso/optimizer/service/rs/models/ChangeWindowTest.java
new file mode 100644
index 0000000..b1309fb
--- /dev/null
+++ b/cmso-optimizer/src/test/java/org/onap/optf/cmso/optimizer/service/rs/models/ChangeWindowTest.java
@@ -0,0 +1,53 @@
+package org.onap.optf.cmso.optimizer.service.rs.models;
+
+/*
+ * ============LICENSE_START==============================================
+ * Copyright (c) 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.
+ * ============LICENSE_END=================================================
+ *
+ */
+
+import java.time.Instant;
+import java.util.Date;
+import org.junit.Assert;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.mockito.runners.MockitoJUnitRunner;
+
+@RunWith(MockitoJUnitRunner.class)
+public class ChangeWindowTest {
+
+
+ @Test
+ public void chagneWindowTest() {
+ ChangeWindow window = new ChangeWindow();
+ window.setStartTime(Date.from(Instant.parse("2019-03-08T00:00:00.00Z")));
+ window.setEndTime(Date.from(Instant.parse("2019-03-12T00:00:00.00Z")));
+ testContains(window, "2019-03-08T00:00:00.00Z", "2019-03-12T00:00:00.00Z", true);
+ 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);
+
+ }
+
+ private void testContains(ChangeWindow window, String from, String to, boolean contains) {
+ ChangeWindow test = new ChangeWindow();
+ test.setStartTime(Date.from(Instant.parse(from)));
+ test.setEndTime(Date.from(Instant.parse(to)));
+ Assert.assertTrue(window.contains(test) == contains);
+ }
+
+}
diff --git a/pom.xml b/pom.xml
index 3c302d7..e6ea475 100644
--- a/pom.xml
+++ b/pom.xml
@@ -63,6 +63,8 @@
<modules>
<module>cmso-database</module>
+ <module>cmso-service</module>
+ <module>cmso-topology</module>
<module>cmso-ticketmgt</module>
<module>cmso-robot</module>
</modules>