<|start_filename|>src/main/java/com/autotune/analyzer/k8sObjects/SelectorInfo.java<|end_filename|>
/*******************************************************************************
 * Copyright (c) 2020, 2021 Red Hat, IBM Corporation and others.
 *
 * 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.
 *******************************************************************************/
package com.autotune.analyzer.k8sObjects;

import com.autotune.analyzer.exceptions.InvalidValueException;

/**
 * Holds information about the selector key in the autotune object yaml
 *
 * Example:
 *   selector:
 *     matchLabel: "org.kubernetes.io/name"
 *     matchLabelValue: "spring-petclinic"
 *     matchRoute: ""
 *     matchURI: ""
 *     matchService: "https"
 */
public final class SelectorInfo
{
	private final String matchLabel;
	private final String matchLabelValue;
	private final String matchURI;
	private final String matchRoute;
	private final String matchService;

	public SelectorInfo(String matchLabel,
			String matchLabelValue,
			String matchURI,
			String matchRoute,
			String matchService) throws InvalidValueException {
		//TODO Can this be blank?
		if (matchLabel != null && !matchLabel.equals(""))
			this.matchLabel = matchLabel;
		else throw new InvalidValueException("Invalid MatchLabel");

		if (matchLabelValue != null && !matchLabelValue.equals(""))
			this.matchLabelValue = matchLabelValue;
		else throw new InvalidValueException("Invalid MatchLabelValue");

		this.matchURI = matchURI;
		this.matchRoute = matchRoute;
		this.matchService = matchService;
	}

	public SelectorInfo(SelectorInfo copy) {
		this.matchLabel = copy.getMatchLabel();
		this.matchLabelValue = copy.getMatchLabelValue();
		this.matchURI = copy.getMatchURI();
		this.matchRoute = copy.getMatchRoute();
		this.matchService = copy.getMatchService();
	}

	public String getMatchLabel() {
		return matchLabel;
	}

	public String getMatchLabelValue() {
		return matchLabelValue;
	}

	public String getMatchURI() {
		return matchURI;
	}

	public String getMatchRoute() {
		return matchRoute;
	}

	public String getMatchService() {
		return matchService;
	}

	@Override
	public String toString() {
		return "SelectorInfo{" +
				"matchLabel='" + matchLabel + '\'' +
				", matchLabelValue='" + matchLabelValue + '\'' +
				", matchURI='" + matchURI + '\'' +
				", matchRoute='" + matchRoute + '\'' +
				", matchService='" + matchService + '\'' +
				'}';
	}
}


<|start_filename|>src/main/java/com/autotune/queue/AutotuneExecutor.java<|end_filename|>
/*******************************************************************************
 * Copyright (c) 2020, 2021 Red Hat, IBM Corporation and others.
 *
 * 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.
 *******************************************************************************/
package com.autotune.queue;

import java.util.concurrent.Callable;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.Future;

/**
 * AutotuneExector is an abstraction of ExecutorService,
 * if you will not specify the default size it will create a
 * fixed size thread pool.
 * @author bipkumar
 */

public class AutotuneExecutor {
	
	/**
	 * Default pool size = 5, it can be configured with new size while 
	 * Initializing the AutotuneExecutor.
	 */
	private final int DEFAULT_POOL_SIZE = 5;
	
	private ExecutorService executorService=null;
	
	public AutotuneExecutor(int poolSize) {
		executorService = Executors.newFixedThreadPool(poolSize);
	}
	
	public AutotuneExecutor() {
		executorService = Executors.newFixedThreadPool(DEFAULT_POOL_SIZE);
		
	}
	
	public Future<AutotuneDTO> submitTask(Callable<AutotuneDTO> task) {
		if (null != this.executorService) {
			return executorService.submit(task);
		}
		return null;
	}
	
	public void shutdown() {
		executorService.shutdown();
	}
	
}


<|start_filename|>src/main/java/com/autotune/queue/EventConsumer.java<|end_filename|>
/*******************************************************************************
 * Copyright (c) 2020, 2021 Red Hat, IBM Corporation and others.
 *
 * 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.
 *******************************************************************************/
package com.autotune.queue;

import java.util.concurrent.Callable;
/**
 * EventConsumer is a Callable run in a separate thread
 * and receive data from AutotuneQueue.
 * @author bipkumar
 *
 */
public class EventConsumer implements Callable<AutotuneDTO> {
	private final AutotuneQueue queue;
	private AutotuneDTO taskDto;

	public EventConsumer(AutotuneQueue queue) {
		this.queue = queue;
	}

	@Override
	public AutotuneDTO call() throws Exception {
		try {
			taskDto = queue.get();

		} catch (InterruptedException e) {
			e.printStackTrace();
		}
		return taskDto;
	}
}


<|start_filename|>src/main/java/com/autotune/queue/AutotuneQueue.java<|end_filename|>
/*******************************************************************************
 * Copyright (c) 2020, 2021 Red Hat, IBM Corporation and others.
 *
 * 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.
 *******************************************************************************/

package com.autotune.queue;
/**
 * AutotuneQueue is an interface having three main contracts
 * send method: it send data to the AutotuneQueue 
 * get method: received data from AutotuneQueue
 * getName method: return the name of the component currently operating on AutotuneDTO object
 * @author bipkumar
 */
public interface AutotuneQueue {
	
	public boolean send(AutotuneDTO data) throws InterruptedException;
	
	public AutotuneDTO get() throws InterruptedException;
	
	public String getName();
}


<|start_filename|>src/main/java/com/autotune/experimentManager/core/EMExecutorService.java<|end_filename|>
/*******************************************************************************
 * Copyright (c) 2021, 2021 Red Hat, IBM Corporation and others.
 *
 * 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.
 *******************************************************************************/

package com.autotune.experimentManager.core;

import com.autotune.experimentManager.settings.EMSettings;
import com.autotune.experimentManager.utils.EMConstants;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.util.concurrent.*;

public class EMExecutorService {

    private static EMExecutorService emExecutorService = null;
    private ExecutorService emExecutor;
    private ScheduledExecutorService emScheduledExecutor;

    private static final Logger LOGGER = LoggerFactory.getLogger(EMExecutorService.class);

    private EMExecutorService() {
        emExecutor = null;
    }

    /**
     * Initialises a singleton class object for EMExecutorService class
     * object is created in a synchronized block as we allow only one
     * object to be created
     *
     * @return emExecutorService
     */
    public static EMExecutorService getInstance() {
        if (null == emExecutorService) {
            synchronized (EMExecutorService.class) {
                if (null == emExecutorService) {
                    emExecutorService = new EMExecutorService();
                }
            }
        }
        return emExecutorService;
    }

    /**
     * Creates the Regular and Scheduled executors
     *
     * @param poolSize
     */

    public void createExecutors(int poolSize) {
        if (null == emExecutor) {
            LOGGER.info(EMConstants.Logs.EMExecutorService.CREATE_REGULAR_EXECUTOR);
            synchronized (EMExecutorService.class) {
                if (null == emExecutor) {
                    emExecutor = Executors.newFixedThreadPool(poolSize);
                }
            }
        }
        if (null == emScheduledExecutor) {
            LOGGER.info(EMConstants.Logs.EMExecutorService.CREATE_SCHEDULED_EXECUTOR);
            synchronized (EMExecutorService.class) {
                if (null == emScheduledExecutor) {
                    emScheduledExecutor = Executors.newScheduledThreadPool(poolSize);
                }
            }
        }
    }

    /**
     * Sets Max Pool Size for the executors
     * @param maxPoolSize
     */
    public void setMaxExecutors(int maxPoolSize) {
        if (maxPoolSize >= EMConstants.EMExecutorService.MIN_EXECUTOR_POOL_SIZE && maxPoolSize <= EMSettings.getController().getMaxExecutors()) {
            ((ThreadPoolExecutor) emExecutor).setMaximumPoolSize(maxPoolSize);
            ((ThreadPoolExecutor) emScheduledExecutor).setMaximumPoolSize(maxPoolSize);
        }
    }

    /**
     * Sets Current Pool Size for executors
     * @param currentPoolSize
     */
    public void setCoreExecutors(int currentPoolSize) {
        if (currentPoolSize >= EMConstants.EMExecutorService.MIN_EXECUTOR_POOL_SIZE && currentPoolSize <= EMSettings.getController().getMaxExecutors()) {
            ((ThreadPoolExecutor) emExecutor).setCorePoolSize(currentPoolSize);
            ((ThreadPoolExecutor) emScheduledExecutor).setCorePoolSize(currentPoolSize);
        }
    }

    /**
     * Executes the given callable in the regular executor
     * @param trial
     */
    public Future<String> execute(Callable<String> trial) {
        if (null != emExecutor) {
            LOGGER.info(EMConstants.Logs.EMExecutorService.START_EXECUTE_TRIAL);
            return emExecutor.submit(trial);
        }
        return null;
    }

    public Future<String> scheduledExecute(Callable<String> trial, int delayInSecs, TimeUnit seconds) {
        if (null != emScheduledExecutor) {
            LOGGER.info(EMConstants.Logs.EMExecutorService.START_SCHEDULED_EXECUTE_TRIAL);
            return emScheduledExecutor.schedule(trial, delayInSecs, seconds);
        }
        return null;
    }

    public Future initiateExperimentStageProcessor(Callable stageProcessor) {
        if (null != emExecutor) {
            LOGGER.info(EMConstants.Logs.EMExecutorService.START_STAGE_PROCESSORS);
            return emExecutor.submit(stageProcessor);
        }
        return null;
    }
}


<|start_filename|>src/main/java/com/autotune/analyzer/k8sObjects/FunctionVariable.java<|end_filename|>
/*******************************************************************************
 * Copyright (c) 2020, 2021 Red Hat, IBM Corporation and others.
 *
 * 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.
 *******************************************************************************/
package com.autotune.analyzer.k8sObjects;

/**
 * Holds the variables used in the objective_function for the autotune object
 *
 *  objective_function: "transaction_response_time"
 *  function_variables:
 *  - name: "transaction_response_time"
 *    query: "application_org_acme_microprofile_metrics_PrimeNumberChecker_checksTimer_mean_seconds"
 *    datasource: "prometheus"
 *    value_type: "double"
 */
public final class FunctionVariable
{
	private final String name;
	private final String query;
	private final String datasource;
	private final String valueType;

	public FunctionVariable(String name,
			String query,
			String datasource,
			String valueType) {
		this.name = name;
		this.query = query;
		this.datasource = datasource;
		this.valueType = valueType;
	}

	public String getName() {
		return name;
	}

	public String getQuery() {
		return query;
	}

	public String getDatasource() {
		return datasource;
	}

	public String getValueType() {
		return valueType;
	}
}


<|start_filename|>src/main/java/com/autotune/experimentManager/settings/EMSettings.java<|end_filename|>
/*******************************************************************************
 * Copyright (c) 2021, 2021 Red Hat, IBM Corporation and others.
 *
 * 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.
 *******************************************************************************/

package com.autotune.experimentManager.settings;

import com.autotune.experimentManager.utils.EMConstants;

/*
 * class name : EMS (Experiment Manager Settings)
 *
 * EMS is a singleton class which is used to store the settings
 * of the Experiment Manager
 *
 * The EMS object is returned by calling the `getController` function
 *
 * It holds settings like:
 *  - Max Executors Size
 *  - Current Executors Size
 */
public class EMSettings {

    /*
     *  static variable of type EMSettings initialized to null
     *  later set to a new EMSettings instance on the first call
     *  to the getController method
     */
    private static EMSettings EMSettings = null;

    /**
     *  Maximum number of worker threads
     */
    private int maxExecutors;

    /**
     *  Current number of worker threads to run in parallel
     */
    private int currentExecutors;

    /**
     *  private constructor to make sure that we cannot create the
     *  object for EMS externally
     *
     *  Sets the defaults values for the variables
     */
    private EMSettings() {
        maxExecutors = calculateMaxExecutors();
        currentExecutors = calculateCoreExecutors();
    }

    /**
     *  method name : getController
     *  return type : EMS object
     *  description : on calling this methods it checks if the `ems` object is null
     *  and if yes it creates a new instance to EMS class and returns it. Subsequent calls
     *  to this function returns the already created EMS instance
     */
    public static EMSettings getController() {
        if (null == EMSettings) {
            EMSettings = new EMSettings();
        }
        return EMSettings;
    }

    public int getMaxExecutors() {
        return maxExecutors;
    }

    public void setMaxExecutors(int maxExecutors) {
        this.maxExecutors = maxExecutors;
    }

    public int getCurrentExecutors() {
        return currentExecutors;
    }

    public void setCurrentExecutors(int currentExecutors) {
        this.currentExecutors = currentExecutors;
    }

    private int calculateCoreExecutors() {
        return (Runtime.getRuntime().availableProcessors() * EMConstants.EMSettings.EXECUTORS_MULTIPLIER);
    }

    private int calculateMaxExecutors() {
        return (Runtime.getRuntime().availableProcessors() * EMConstants.EMSettings.MAX_EXECUTORS_MULTIPLIER);
    }

}
