Package uk.ac.soton.itinnovation.pes.optimiser.test

Source Code of uk.ac.soton.itinnovation.pes.optimiser.test.SampleModel

/////////////////////////////////////////////////////////////////////////
//
// © University of Southampton IT Innovation Centre, 2011
//
// Copyright in this software belongs to University of Southampton
// IT Innovation Centre of 2 Venture Road, Chilworth Science Park, Southampton SO16 7NP, UK.
//
// This software may not be used, sold, licensed, transferred, copied
// or reproduced in whole or in part in any manner or form or in or
// on any media by any person other than in accordance with the terms
// of the Licence Agreement supplied with the software, or otherwise
// without the prior written consent of the copyright owners.
//
// This software is distributed WITHOUT ANY WARRANTY, without even the
// implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
// PURPOSE, except where stated in the Licence Agreement supplied with
// the software.
//
//  Created By :      Vegard Engen, Stuart E. Middleton
//  Created Date :      13-Jan-2011
//  Created for Project :   IRMOS---BonFIRE
//
/////////////////////////////////////////////////////////////////////////
//
//  Dependencies : none
//
/////////////////////////////////////////////////////////////////////////
package uk.ac.soton.itinnovation.pes.optimiser.test;

import java.io.File;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Random;
import java.util.Set;
import uk.ac.soton.itinnovation.pes.data.dao.DAOFactory;
import uk.ac.soton.itinnovation.pes.data.model.AttributeType;
import uk.ac.soton.itinnovation.pes.data.model.BasicType;
import uk.ac.soton.itinnovation.pes.data.model.MetricType;
import uk.ac.soton.itinnovation.pes.data.model.Model;
import uk.ac.soton.itinnovation.pes.data.model.ModelExecutionResult;
import uk.ac.soton.itinnovation.pes.data.model.Resource;
import uk.ac.soton.itinnovation.pes.data.model.ValueType;
import java.util.Map.Entry;
import uk.ac.soton.itinnovation.pes.optimiser.common.AModel;
import uk.ac.soton.itinnovation.pes.optimiser.common.OptimiserUtil;

/**
* A sample model wrapper that simulates that a model is executed and a reliability
* value is calculated as a measurement of the probability of achieving some desired
* QoS defined in an hypothetical ASLA.
*/
public class SampleModel extends AModel
{
    private Model model = null;
    private DAOFactory daoFactory = null;
    private File configFile = null;
    private Random rand = new Random(); // used to randomly set the output values
    private int executionTime = 1000;   // (sleep time) the unit is milliseconds
    private OptimiserUtil optUtil = OptimiserUtil.getInstance();

  /**
   * constructor
   */
    public SampleModel()
    {
        System.out.println("[AppModel] created instance");
        rand.setSeed(System.currentTimeMillis());
    }

  /**
   * Initialise and validate the application model wrapper.
     * Normally both the Model and DAOFactory objects should be validated
     * since these are required by the super class to perform caching of the
     * execution results. However, since this sample model wrapper was designed
     * to be used within the optimiser without a database to perform caching,
     * only the Model object is validated.
   * @param m Model object specifying details of the application model.
   * @param daoFact DAOFactory object used for DB caching.
     * @throws Exception if initialisation fails.
   */
    @Override
    public void init(Model m, DAOFactory daoFact) throws Exception
    {
        this.model = m;
        this.daoFactory = daoFact;

        if (validateModelParams())
            System.out.println("[AppModel] initialised");
        else
        {
            System.out.println("[AppModel] failed to initialise");
            throw new RuntimeException("Failed to initialise application model. The model parameters could not be validated.");
        }
    }

  /**
   * Initialise and validate the application model wrapper.
     * Normally both the Model and DAOFactory objects should be validated
     * since these are required by the super class to perform caching of the
     * execution results. However, since this sample model wrapper was designed
     * to be used within the optimiser without a database to perform caching,
     * only the Model object is validated.
   * @param m Model object specifying details of the application model.
   * @param daoFact DAOFactory object used for DB caching.
   * @param aslaParams ASLA parameters.
     * @throws Exception if initialisation fails.
   */
    @Override
    public void init(Model m, DAOFactory daoFact, Map<String, List<AttributeType>> aslaParams) throws Exception
    {
        this.model = m;
        this.daoFactory = daoFact;

        if (validateModelParams())
            System.out.println("[AppModel] initialised");
        else
        {
            System.out.println("[AppModel] failed to initialise");
            throw new RuntimeException("Failed to initialise application model. The model parameters could not be validated.");
        }
    }

    /**
   * Validates the model execution file path and config file. Parameters are
   * extracted from the config file and validated too.
   * @return True if all valid, false otherwise.
   */
  private boolean validateModelParams()
  {
    boolean returnVal = true;
    Map<String, String> configParams = null;

        if (model == null)
    {
      System.out.println("[AppModel] ERROR: Model object is NULL");
      returnVal = false;
    }
        else
        {
            System.out.println("[AppModel] model name        = " + model.getName());
            System.out.println("[AppModel] model version     = " + model.getVersion());

            // check config file
            if ((model.getConfigFilePath() != null) && (model.getConfigFilePath().length() > 0))
            {
                configFile = new File (model.getConfigFilePath());
                if (configFile.exists())
                {
                    System.out.println("[AppModel] configFile        = " +configFile.getAbsolutePath());

                    try
                    {
                        configParams = optUtil.readKeyValueFile(configFile);

                        if (configParams != null)
                        {
                            if (validateAndSaveConfigParams(configParams))
                            {
                                System.out.println("[AppModel] execution time set to " + executionTime + "ms");
                            }
                            else
                            {
                                System.out.println("[AppModel] ERROR: unable to find all expected parameters from the config file: " + configFile.getAbsolutePath());
                                System.out.println("[AppModel] default parameter values will be used");
                                returnVal = false;
                            }
                        }
                        else
                        {
                            System.out.println("[AppModel] ERROR: unable to extract config parameters from the file: " + configFile.getAbsolutePath());
                            System.out.println("[AppModel] default parameter values will be used");
                        }
                    } catch (Exception ex){
                        System.out.println("[AppModel] ERROR: unable to read config file :: " + ex.getMessage());
                    }
                }
                else // config file does not exist
                {
                    System.out.println("[AppModel] model config file path invalid: " + configFile.getAbsolutePath());
                    System.out.println("[AppModel] default parameter values will be used");
                }
            }
            else // no config file set
            {
                System.out.println("[AppModel] model config file path not set");
                System.out.println("[AppModel] default parameter values will be used");
            }
        } // end if (model != null)

        if (!optUtil.disableDBCaching && daoFactory == null)
    {
      System.out.println("[AppModel] ERROR: DAOFactory object is NULL");
      returnVal = false;
    }

    return returnVal;
  }

  /**
   * Set the values of configuration parameters according to the data read in
   * from the config file (stored in the parameter map passed on to this method).
   * @param paramMap A map of the configuration parameters and their values.
   * @return True if all expected configuration parameters are found and their values are valid.
   */
  private boolean validateAndSaveConfigParams (Map<String, String> paramMap)
  {
    System.out.println("[AppModel] validating the config parameters");
    boolean valid = true;

    try
    {
      if (paramMap.containsKey("executionTime"))
      {
        executionTime = Integer.parseInt(paramMap.get("executionTime"));
                if (executionTime < 0)
                {
                    System.out.println("[AppModel] ERROR: cheeky human! executionTime cannot be set to a negative value");
                    System.out.println("[AppModel] executionTime set to the default value");
                    executionTime = 1000;
                }
      }
    }
    catch (java.lang.NumberFormatException ex)
    {
      System.out.println("[AppModel] ERROR: NumberFormatException thrown when trying to save config parameters");
      valid = false;
    }

    return valid;
  }

  /**
   * Return the model instance.
   */
    @Override
    public Model getModel() {
        return model;
    }

  /**
   * Setup the ASLA parameter map.
   * OBS: NOT USED always does nothing.
   */
    @Override
    public void setASLAParameters(Map<String, List<AttributeType>> parameters) throws Exception {}

  /**
   * Return the ASLA parameter map.
   * OBS: NOT USED always returns NULL.
   */
    @Override
    public Map<String, List<AttributeType>> getASLAParameters() {
        return null;
    }

  /**
   * Return if the model instance has been setup correctly.
   * @return true if model instance setup correctly.
   */
    @Override
    public boolean isValid() {
        if (model != null)
            return true;
        else
            return false;
    }

  /**
   * This is the execute method that will be called by the objective function,
     * passing on a map of the chosen HW specifications.
   * @param inputs Hardware specifications given by the objective function.
   * @param outoutDir The directory where model outputs could be saved (e.g. log file).
   * @return ModelExecutionResult containing the reliability calculated by this wrapper.
   */
    @Override
    public ModelExecutionResult execute(Map<String, Set<Resource>> inputs, String outputDir) throws Exception
    {
    Set<AttributeType> outputs = null;
    double output;
    AttributeType reliability = null;

        if (!optUtil.disableDBCaching) // will not check for cached execution results
        {
            System.out.println("         checking for cached execution result in the DB");
            ModelExecutionResult res = super.checkExecutionResult(model, daoFactory, optUtil.convertResourceMapToSet(inputs), null, null);
            if (res != null)
            {
                System.out.println("         found a model execution result, which is returned");
                return res;
            }
            System.out.println("         did not find a matching existing execution result in the DB");
        }
        System.out.println("         executing " + model.getName());

        // Add some sleep time to simulate some wait time if a model had been executed
        Thread.sleep(executionTime);

        // This would be a point at which an application model would be executed,
        // which could be done with the ModelExecuter class in pes-common.
        // Since we do not provide an excutable application model, this sample
        // wrapper calculates a reliability (probability of achieving some QoS
        // constraints) based on a simple hard coded formula that has been invented
        // for this simple test.
        output = optUtil.roundDouble(getReliability(inputs), 3);
        System.out.println("         reliability calculated as " + output);

        // create an output set for the ModelExecutionResult object
        outputs = new HashSet<AttributeType>();
    reliability = new AttributeType();
    reliability.setName("reliability");
    reliability.setType(BasicType.convert("double"));
    reliability.addAValue(new ValueType(String.valueOf(output), MetricType.DEFAULT));
    outputs.add(reliability);

        if (!optUtil.disableDBCaching)
            return super.saveExecutionResult(model, daoFactory, optUtil.convertResourceMapToSet(inputs), null, null, outputs, null);
        else
            return new ModelExecutionResult(model, optUtil.convertResourceMapToSet(inputs), outputs);
    }

  /**
   * Return the reliability (based on to CPU speed and bandwidth)
   * @param inputs The HW spec from the objective function.
   * @return A value between 0 to 100, specifying the reliability.
   */
    private double getReliability(Map<String, Set<Resource>> inputs) throws Exception
    {
    String mapKey = null;
    Set<Resource> resourceSet = null;

        // semi-random generation of reliability according to CPU speed and bandwidth
        //double reliability = optUtil.roundDouble(90.0 + (rand.nextDouble()*10), 3);
        double reliability = 80;

        int cpuSpeed_s1 = 0; // max  3
        int cpuSpeed_s2 = 0; // max  3
        int cpuSpeed_lb = 0; // max  3
        int bw_l1_in    = 0; // max  5
        int bw_l1_out   = 0; // max  5
        int bw_l2_in    = 0; // max  5
        int bw_l2_out   = 0; // max  5
        //----------------------------
        //                      sum 29
        //============================

        for (Entry<String, Set<Resource>> entry : inputs.entrySet())
        {
            mapKey = entry.getKey();
            resourceSet = entry.getValue();

            for (Resource resource : resourceSet)
            {
                if (resource.getName().equalsIgnoreCase("CPU"))
                {
                    for (AttributeType attribute : resource.getAttrs())
                    {
                        if (attribute.getName().equalsIgnoreCase("cpuSpeed"))
                        {
                            if (mapKey.equalsIgnoreCase("Server1"))
                                cpuSpeed_s1 = Integer.parseInt(attribute.getExactValue().getVal());
                            else if (mapKey.equalsIgnoreCase("Server2"))
                                cpuSpeed_s2 = Integer.parseInt(attribute.getExactValue().getVal());
                            else if (mapKey.equalsIgnoreCase("LoadBalancer"))
                                cpuSpeed_lb = Integer.parseInt(attribute.getExactValue().getVal());
                            break;
                        }
                    } // end for all attributes
                } // end if resource == CPU
                else if (resource.getName().equalsIgnoreCase("INBOUND"))
                {
                    for (AttributeType attribute : resource.getAttrs())
                    {
                        if (attribute.getName().equalsIgnoreCase("bandwidth"))
                        {
                            if (mapKey.equalsIgnoreCase("Link1"))
                                bw_l1_in = Integer.parseInt(attribute.getExactValue().getVal());
                            else if (mapKey.equalsIgnoreCase("Link2"))
                                bw_l2_in = Integer.parseInt(attribute.getExactValue().getVal());
                            break;
                        }
                    } // end for all attributes
                } // end if resource == INBOUND
                else if(resource.getName().equalsIgnoreCase("OUTBOUND"))
                {
                    for (AttributeType attribute : resource.getAttrs())
                    {
                        if (attribute.getName().equalsIgnoreCase("bandwidth"))
                        {
                            if (mapKey.equalsIgnoreCase("Link1"))
                                bw_l2_out = Integer.parseInt(attribute.getExactValue().getVal());
                            else if (mapKey.equalsIgnoreCase("Link2"))
                                bw_l2_out = Integer.parseInt(attribute.getExactValue().getVal());
                            break;
                        }
                    } // end for all attributes
                } // end if resource == OUTBOUND
            } // end for all resources
        } // end for all map entries

        reliability += getCpuSpeedAcc(cpuSpeed_s1);
        reliability += getCpuSpeedAcc(cpuSpeed_s2);
        reliability += getCpuSpeedAcc(cpuSpeed_lb);
        reliability += getBandwidthAcc(bw_l1_in);
        reliability += getBandwidthAcc(bw_l1_out);
        reliability += getBandwidthAcc(bw_l2_in);
        reliability += getBandwidthAcc(bw_l2_out);

        if (reliability > 100)
            reliability = 100;

        return reliability;
    }

  /**
   * Get the cost of a specific CPU speed.
   * @param speed A positive integer in the set {2000, 2200, 2400}, which is
     *              hard coded according to the test framework.
   * @return A cost for the CPU.
   */
    private double getCpuSpeedAcc (int speed)
    {
        switch (speed)
        {
            case 2000:
            {
                return 1;
            }
            case 2200:
            {
                return 2;
            }
            case 2400:
            {
                return 3;
            }
            default:
                return 1;
        }
    }

  /**
   * Get the cost of a specific bandwidth.
   * @param bw A positive value in the range [1000000, 10000000].
   * @return A cost, calculated by scaling the value of the bandwidth within the
     *         range [1,5]. That is, the minimum bandwidth gives a cost of 1, and
     *         the maximum bandwidth gives a cost of 5.
   */
    private double getBandwidthAcc (int bw)
    {
        // [1000000, 10000000]
        // scale to [1, 5]
        return optUtil.scale(bw, 1000000, 10000000, 1, 5);
    }

    //============================ UNUSED METHODS ============================//

  /**
   * method unused
   */
    @Override
    public ModelExecutionResult execute(Set<AttributeType> inputs, String outputDir) throws Exception {
        throw new UnsupportedOperationException("Not supported yet.");
    }

  /**
   * method unused
   */
    @Override
    public ModelExecutionResult execute(File[] inputFiles, String outputDir) throws Exception {
        throw new UnsupportedOperationException("Not supported yet.");
    }

  /**
   * method unused
   */
    @Override
    public ModelExecutionResult execute(File inputFile, String outputDir) throws Exception {
        throw new UnsupportedOperationException("Not supported yet.");
    }

  /**
   * method unused
   */
    @Override
    public ModelExecutionResult execute(String[] inputs, String outputDir) throws Exception {
        throw new UnsupportedOperationException("Not supported yet.");
    }

  /**
   * method unused
   */
    @Override
    public ModelExecutionResult execute(String input, String outputDir) throws Exception {
        throw new UnsupportedOperationException("Not supported yet.");
    }

} // SampleModel
TOP

Related Classes of uk.ac.soton.itinnovation.pes.optimiser.test.SampleModel

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.