Skip to content

Commit

Permalink
resolved conflicts
Browse files Browse the repository at this point in the history
Signed-off-by: msvinaykumar <vinakuma@redhat.com>
  • Loading branch information
msvinaykumar committed Jul 21, 2023
1 parent c970aa3 commit 70780ea
Show file tree
Hide file tree
Showing 3 changed files with 92 additions and 68 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -21,19 +21,22 @@
import com.autotune.analyzer.recommendations.Recommendation;
import com.autotune.analyzer.recommendations.RecommendationConstants;
import com.autotune.analyzer.recommendations.RecommendationNotification;
import com.autotune.analyzer.utils.AnalyzerConstants;
import com.autotune.analyzer.recommendations.engine.DurationBasedRecommendationEngine;
import com.autotune.analyzer.recommendations.engine.KruizeRecommendationEngine;
import com.autotune.analyzer.utils.AnalyzerConstants;
import com.autotune.common.data.result.ContainerData;
import com.autotune.common.data.result.ExperimentResultData;
import com.autotune.common.k8sObjects.K8sObject;
import com.autotune.database.service.ExperimentDBService;
import com.autotune.utils.KruizeConstants;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.sql.Timestamp;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
* Util class to validate the performance profile metrics with the experiment results metrics.
Expand All @@ -43,20 +46,20 @@ public class ResourceOptimizationOpenshiftImpl extends PerfProfileImpl {
private static final Logger LOGGER = LoggerFactory.getLogger(ResourceOptimizationOpenshiftImpl.class);
List<KruizeRecommendationEngine> kruizeRecommendationEngineList;

public ResourceOptimizationOpenshiftImpl() {
this.init();
}

private void init() {
// Add new engines
kruizeRecommendationEngineList = new ArrayList<KruizeRecommendationEngine>();
// Create Duration based engine
DurationBasedRecommendationEngine durationBasedRecommendationEngine = new DurationBasedRecommendationEngine();
DurationBasedRecommendationEngine durationBasedRecommendationEngine = new DurationBasedRecommendationEngine();
// TODO: Create profile based engine
AnalyzerConstants.RegisterRecommendationEngineStatus _unused_status = registerEngine(durationBasedRecommendationEngine);
// TODO: Add profile based once recommendation algos are available
}

public ResourceOptimizationOpenshiftImpl() {
this.init();
}

@Override
public AnalyzerConstants.RegisterRecommendationEngineStatus registerEngine(KruizeRecommendationEngine kruizeRecommendationEngine) {
if (null == kruizeRecommendationEngine) {
Expand All @@ -77,73 +80,92 @@ public List<KruizeRecommendationEngine> getEngines() {
}

@Override
public void generateRecommendation(KruizeObject kruizeObject, ExperimentResultData experimentResultData) {
public void generateRecommendation(KruizeObject kruizeObject, List<ExperimentResultData> experimentResultDataList, Timestamp interval_start_time, Timestamp interval_end_time) throws Exception {
/*
To restrict the number of rows in the result set, the Load results operation involves locating the appropriate method and configuring the desired limitation.
It's important to note that in order for the Limit rows feature to function correctly,
the CreateExperiment API must adhere strictly to the trail settings' measurement duration and should not allow arbitrary values
*/
String experiment_name = kruizeObject.getExperimentName();
int limitRows = (int) ((
KruizeConstants.RecommendationEngineConstants.DurationBasedEngine.DurationAmount.LONG_TERM_DURATION_DAYS *
KruizeConstants.DateFormats.MINUTES_FOR_DAY)
/ kruizeObject.getTrial_settings().getMeasurement_durationMinutes_inDouble());
Map<String, KruizeObject> mainKruizeExperimentMap = new HashMap<>();
mainKruizeExperimentMap.put(experiment_name, kruizeObject);
new ExperimentDBService().loadResultsFromDBByName(mainKruizeExperimentMap,
experiment_name,
interval_end_time,
limitRows);

//TODO: Will be updated once algo is completed
if (null != kruizeObject && null != experimentResultData) {
RecommendationSettings recommendationSettings = kruizeObject.getRecommendation_settings();
for (ExperimentResultData experimentResultData : experimentResultDataList) {
if (null != kruizeObject && null != experimentResultData) {
RecommendationSettings recommendationSettings = kruizeObject.getRecommendation_settings();

for (K8sObject k8sObjectResultData : experimentResultData.getKubernetes_objects()) {
// We only support one K8sObject currently
K8sObject k8sObjectKruizeObject = kruizeObject.getKubernetes_objects().get(0);
for (String cName : k8sObjectResultData.getContainerDataMap().keySet()) {
ContainerData containerDataResultData = k8sObjectResultData.getContainerDataMap().get(cName);
if (null == containerDataResultData.getResults())
continue;
if (containerDataResultData.getResults().isEmpty())
continue;
// Get the monitoringEndTime from ResultData's ContainerData. Should have only one element
Timestamp monitoringEndTime = containerDataResultData.getResults().keySet().stream().max(Timestamp::compareTo).get();
// Get the ContainerData from the KruizeObject and not from ResultData
ContainerData containerDataKruizeObject = k8sObjectKruizeObject.getContainerDataMap().get(cName);
for (KruizeRecommendationEngine engine : getEngines()) {
// Check if minimum data available to generate recommendation
if (!engine.checkIfMinDataAvailable(containerDataKruizeObject))
for (K8sObject k8sObjectResultData : experimentResultData.getKubernetes_objects()) {
// We only support one K8sObject currently
K8sObject k8sObjectKruizeObject = kruizeObject.getKubernetes_objects().get(0);
for (String cName : k8sObjectResultData.getContainerDataMap().keySet()) {
ContainerData containerDataResultData = k8sObjectResultData.getContainerDataMap().get(cName);
if (null == containerDataResultData.getResults())
continue;

// Now generate a new recommendation for the new data corresponding to the monitoringEndTime
HashMap<String, Recommendation> recommendationHashMap = engine.generateRecommendation(containerDataKruizeObject, monitoringEndTime, recommendationSettings);
if (null == recommendationHashMap || recommendationHashMap.isEmpty())
if (containerDataResultData.getResults().isEmpty())
continue;
ContainerRecommendations containerRecommendations = containerDataKruizeObject.getContainerRecommendations();
// Just to make sure the container recommendations object is not empty
if (null == containerRecommendations) {
containerRecommendations = new ContainerRecommendations();
}
// check if notification exists
boolean notificationExist = false;
if (containerRecommendations.getNotificationMap().containsKey(RecommendationConstants.NotificationCodes.INFO_DURATION_BASED_RECOMMENDATIONS_AVAILABLE))
notificationExist = true;
// Get the monitoringEndTime from ResultData's ContainerData. Should have only one element
Timestamp monitoringEndTime = containerDataResultData.getResults().keySet().stream().max(Timestamp::compareTo).get();
// Get the ContainerData from the KruizeObject and not from ResultData
ContainerData containerDataKruizeObject = k8sObjectKruizeObject.getContainerDataMap().get(cName);
for (KruizeRecommendationEngine engine : getEngines()) {
// Check if minimum data available to generate recommendation
if (!engine.checkIfMinDataAvailable(containerDataKruizeObject))
continue;

// If there is no notification add one
if (!notificationExist) {
RecommendationNotification recommendationNotification = new RecommendationNotification(
RecommendationConstants.RecommendationNotification.INFO_DURATION_BASED_RECOMMENDATIONS_AVAILABLE
);
containerRecommendations.getNotificationMap().put(recommendationNotification.getCode(), recommendationNotification);
}
// Now generate a new recommendation for the new data corresponding to the monitoringEndTime
HashMap<String, Recommendation> recommendationHashMap = engine.generateRecommendation(containerDataKruizeObject, monitoringEndTime, recommendationSettings);
if (null == recommendationHashMap || recommendationHashMap.isEmpty())
continue;
ContainerRecommendations containerRecommendations = containerDataKruizeObject.getContainerRecommendations();
// Just to make sure the container recommendations object is not empty
if (null == containerRecommendations) {
containerRecommendations = new ContainerRecommendations();
}
// check if notification exists
boolean notificationExist = false;
if (containerRecommendations.getNotificationMap().containsKey(RecommendationConstants.NotificationCodes.INFO_DURATION_BASED_RECOMMENDATIONS_AVAILABLE))
notificationExist = true;

// Get the engine recommendation map for a time stamp if it exists else create one
HashMap<Timestamp, HashMap<String, HashMap<String,Recommendation>>> timestampBasedRecommendationMap
= containerRecommendations.getData();
if (null == timestampBasedRecommendationMap) {
timestampBasedRecommendationMap = new HashMap<Timestamp, HashMap<String, HashMap<String, Recommendation>>>();
}
// check if engines map exists else create one
HashMap<String, HashMap<String, Recommendation>> enginesRecommendationMap = null;
if (timestampBasedRecommendationMap.containsKey(monitoringEndTime)) {
enginesRecommendationMap = timestampBasedRecommendationMap.get(monitoringEndTime);
} else {
enginesRecommendationMap = new HashMap<String, HashMap<String, Recommendation>>();
// If there is no notification add one
if (!notificationExist) {
RecommendationNotification recommendationNotification = new RecommendationNotification(
RecommendationConstants.RecommendationNotification.INFO_DURATION_BASED_RECOMMENDATIONS_AVAILABLE
);
containerRecommendations.getNotificationMap().put(recommendationNotification.getCode(), recommendationNotification);
}

// Get the engine recommendation map for a time stamp if it exists else create one
HashMap<Timestamp, HashMap<String, HashMap<String, Recommendation>>> timestampBasedRecommendationMap
= containerRecommendations.getData();
if (null == timestampBasedRecommendationMap) {
timestampBasedRecommendationMap = new HashMap<Timestamp, HashMap<String, HashMap<String, Recommendation>>>();
}
// check if engines map exists else create one
HashMap<String, HashMap<String, Recommendation>> enginesRecommendationMap = null;
if (timestampBasedRecommendationMap.containsKey(monitoringEndTime)) {
enginesRecommendationMap = timestampBasedRecommendationMap.get(monitoringEndTime);
} else {
enginesRecommendationMap = new HashMap<String, HashMap<String, Recommendation>>();
}
// put recommendations tagging to engine
enginesRecommendationMap.put(engine.getEngineKey(), recommendationHashMap);
// put recommendations tagging to timestamp
timestampBasedRecommendationMap.put(monitoringEndTime, enginesRecommendationMap);
// set the data object to map
containerRecommendations.setData(timestampBasedRecommendationMap);
// set the container recommendations in container object
containerDataKruizeObject.setContainerRecommendations(containerRecommendations);
}
// put recommendations tagging to engine
enginesRecommendationMap.put(engine.getEngineKey(), recommendationHashMap);
// put recommendations tagging to timestamp
timestampBasedRecommendationMap.put(monitoringEndTime, enginesRecommendationMap);
// set the data object to map
containerRecommendations.setData(timestampBasedRecommendationMap);
// set the container recommendations in container object
containerDataKruizeObject.setContainerRecommendations(containerRecommendations);
}
}
}
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,10 +17,10 @@

import com.autotune.analyzer.experiment.ExperimentInitiator;
import com.autotune.analyzer.kruizeObject.KruizeObject;
import com.autotune.analyzer.recommendations.RecommendationConstants;
import com.autotune.analyzer.serviceObjects.ContainerAPIObject;
import com.autotune.analyzer.serviceObjects.Converters;
import com.autotune.analyzer.serviceObjects.ListRecommendationsAPIObject;
import com.autotune.analyzer.utils.AnalyzerConstants;
import com.autotune.analyzer.utils.AnalyzerErrorConstants;
import com.autotune.analyzer.utils.GsonUTCDateAdapter;
import com.autotune.common.data.result.ContainerData;
Expand Down Expand Up @@ -114,7 +114,7 @@ protected void doPost(HttpServletRequest request, HttpServletResponse response)
if (success)
sendSuccessResponse(response, kruizeObject, interval_end_time);
else {
sendErrorResponse(response, null, HttpServletResponse.SC_BAD_REQUEST, AnalyzerConstants.RecommendationNotificationMsgConstant.NOT_ENOUGH_DATA);
sendErrorResponse(response, null, HttpServletResponse.SC_BAD_REQUEST, RecommendationConstants.RecommendationNotificationMsgConstant.NOT_ENOUGH_DATA);
}
} catch (Exception e) {
e.printStackTrace();
Expand Down
2 changes: 2 additions & 0 deletions src/main/java/com/autotune/utils/KruizeConstants.java
Original file line number Diff line number Diff line change
Expand Up @@ -365,6 +365,8 @@ private DBConstants() {
public static final class DateFormats {
public static final String STANDARD_JSON_DATE_FORMAT = "yyyy-MM-dd'T'HH:mm:ss.SSS'Z'";
public static final String DB_EXTRACTION_FORMAT = "yyyy-MM-dd HH:mm:ss.SSS";
public static final long MILLI_SECONDS_FOR_DAY = 24 * 60 * 60 * 1000;
public static final long MINUTES_FOR_DAY = 24 * 60;

private DateFormats() {

Expand Down

0 comments on commit 70780ea

Please sign in to comment.