Commit 2 for Integrate minizinc optimizer engine 17/84017/1
authorJerry Flood <jflood@att.com>
Tue, 2 Apr 2019 22:52:18 +0000 (18:52 -0400)
committerJerry Flood <jflood@att.com>
Tue, 2 Apr 2019 22:55:32 +0000 (18:55 -0400)
Multiple commits required due to commit size limitation.

Change-Id: I50c6dffbdd8a1170d151432dad745589b5925eb6
Issue-ID: OPTFRA-436
Signed-off-by: Jerry Flood <jflood@att.com>
cmso-optimizer/src/main/java/org/onap/optf/cmso/optimizer/availability/timewindows/RecurringWindows.java
cmso-optimizer/src/main/java/org/onap/optf/cmso/optimizer/clients/optimizer/ElementAvailability.java [new file with mode: 0644]
cmso-optimizer/src/main/java/org/onap/optf/cmso/optimizer/clients/optimizer/ElementWindowMapping.java [new file with mode: 0644]
cmso-optimizer/src/main/java/org/onap/optf/cmso/optimizer/clients/optimizer/OptimizerClient.java [new file with mode: 0644]

index 84fc039..23e3ad8 100644 (file)
@@ -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 (file)
index 0000000..4766db2
--- /dev/null
@@ -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 (file)
index 0000000..42c69a2
--- /dev/null
@@ -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 (file)
index 0000000..514097e
--- /dev/null
@@ -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;
+    }
+
+
+}