aboutsummaryrefslogtreecommitdiffstats
path: root/cmso-optimizer
diff options
context:
space:
mode:
authorVikas Varma <vv8305@att.com>2019-04-03 01:40:22 +0000
committerGerrit Code Review <gerrit@onap.org>2019-04-03 01:40:22 +0000
commitc8c7ec4aa51bca71fcf5ca84b49eef90697be876 (patch)
treecc2151b1d75ea90331b6dc5bc2ca48195fb84e56 /cmso-optimizer
parent5ec78004e7687167a487895fead0cb16d4fbecf6 (diff)
parent7c554acddb9414eb5cb285562adef4a8e94b8510 (diff)
Merge "Commit 2 for Integrate minizinc optimizer engine"
Diffstat (limited to 'cmso-optimizer')
-rw-r--r--cmso-optimizer/src/main/java/org/onap/optf/cmso/optimizer/availability/timewindows/RecurringWindows.java12
-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
4 files changed, 636 insertions, 0 deletions
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 84fc039..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
@@ -211,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;
+ }
+
+
+}