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

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

/////////////////////////////////////////////////////////////////////////
//
// © 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 uk.ac.soton.itinnovation.pes.optimiser.common.OptimiserResult;
import uk.ac.soton.itinnovation.pes.optimiser.common.OptimiserUtil;
import uk.ac.soton.itinnovation.pes.optimiser.common.IOptimisationManager;
import uk.ac.soton.itinnovation.pes.optimiser.common.AObjectiveFunction;
import uk.ac.soton.itinnovation.pes.optimiser.common.IPriceCalculator;
import uk.ac.soton.itinnovation.pes.optimiser.common.AModel;
import uk.ac.soton.itinnovation.pes.optimiser.common.IOptimisationAlgorithm;
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.EstimationResult;
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.ObjectiveFunctionConfig;
import uk.ac.soton.itinnovation.pes.data.model.OptimisationAlgConfig;
import uk.ac.soton.itinnovation.pes.data.model.Resource;
import uk.ac.soton.itinnovation.pes.data.model.UnitType;
import uk.ac.soton.itinnovation.pes.data.model.ValueType;
import eu.irmosproject.pes.common.PESClassLoader;

import java.io.File;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
import uk.ac.soton.itinnovation.pes.optimiser.core.OptimisationManager;

/**
* This is a Sample test framework for running the optimiser, which allows a user
* to specify XML files for loading an optimisation algorithm, objective function
* and application model (wrapper).
*
* Since this is a test framework for the optimiser independent of the performance
* estimation service it can be plugged into, there are limitations to what can be
* tested with this class:
*
*    1: Interaction with a database to cache execution results is not possible
*       since this relies on information to be put in the database that is
*       performed by an Estimation Manager (a part of the PES Service).
*    2: The optimisation space is hard coded.
*    3: The ASLA parameters are hard coded.
*
* The arguments to this test framework are:
*    1: Full path to the XML file describing the optimisation algorithm
*    2: Full path to the XML file describing the objective function
*    3: Full path to the XML file describing the application model (wrapper)
*    4: Full path to the workspace where files can be saved optimiser components
*
* For example:
*
*    SampleOptimiserTest C:\OptAlg.xml C:\ObjFunc.xml C:\Model.xml C:\workspace
*
*/
public class SampleOptimiserTest
{
    private final static MetricType exactType = MetricType.EXACT;

    private OptimiserUtil optUtil = null;
    private PESClassLoader classLoader = null;

    private final static int optAlgIdx    = 0;
    private final static int objFuncIdx   = 1;
    private final static int modelIdx     = 2;
    private final static int workspaceIdx = 3;

    /**
   * Main method for test execution framework to run from command line.
   * Expecting the following command line arguments:
     *    1: Full path to the XML file describing the optimisation algorithm
     *    2: Full path to the XML file describing the objective function
     *    3: Full path to the XML file describing the application model (wrapper)
     *    4: Full path to the workspace where files can be saved optimiser components
   */
    public static void main(String[] args)
    {
        SampleOptimiserTest testOptimiser = new SampleOptimiserTest();
        IOptimisationManager optimiser = null;
    OptimiserResult optRes = null;

        System.out.println("\n\n");
        System.out.println("==== OPTIMISER TEST ====\n\n");

        if (!testOptimiser.validateArguments(args))
            System.exit(1);

        try
        {
            optimiser = testOptimiser.setUp(args);
        }
    catch (Exception ex)
        {
            System.out.println("[TestFramework] Failed to set up the Optimiser: " + ex.getMessage());
            System.exit(1);
        }

        try {
            optRes = optimiser.getOptimalResources();
            if (optRes != null) {
                System.out.println("\n[TestFramework] Optimisation successful!");
            } else {
                System.out.println("\n[TestFramework] Optimisation failed :(");
            }
        }
    catch (Exception ex) {
            System.out.println("\n[TestFramework] The optimisation failed, an exception was caught: " + ex.getMessage());
            System.exit(1);
        }

        System.out.println("\n\nSo long, and thanks for all the fish!\n\n");
    }

    /**
   * Validate the command line arguments.
   * @param args Command line arguments from the main method.
   * @return True if valid.
   */
    private boolean validateArguments (String[] args)
    {
        File optAlgFile, objFuncFile, modelFile, workspace;

        if (args == null)
        {
            System.out.println("[TestFramework] ERROR: no arguments given");
            return false;
        }

        if (args.length < 4)
        {
            System.out.println("[TestFramework] ERROR: not enough arguments given");
            System.out.println("[TestFramework] Expecting: ");
            System.out.println("[TestFramework]    1: full path to xml file for the optimisation algorithm");
            System.out.println("[TestFramework]    2: full path to xml file for the objective function");
            System.out.println("[TestFramework]    3: full path to xml file for the model");
            System.out.println("[TestFramework]    4: full path to workspace where file I/O can be done by the optimisation components");
            return false;
        }

        optAlgFile  = new File (args[optAlgIdx]);
        objFuncFile = new File (args[objFuncIdx]);
        modelFile   = new File (args[modelIdx]);
        workspace   = new File (args[workspaceIdx]);

        if (!optAlgFile.exists() || !optAlgFile.isFile())
        {
            System.out.println("[TestFramework] ERROR with argument 1: not a valid path to the xml file for an optimisation algorithm '"+args[optAlgIdx]+"'");
            return false;
        }
        if (!objFuncFile.exists() || !objFuncFile.isFile())
        {
            System.out.println("[TestFramework] ERROR with argument 2: not a valid path to the xml file for an objective function '"+args[objFuncIdx]+"'");
            return false;
        }
        if (!modelFile.exists() || !modelFile.isFile())
        {
            System.out.println("[TestFramework] ERROR with argument 3: not a valid path to the xml file for a model '"+args[modelIdx]+"'");
            return false;
        }
        if (!workspace.exists() || !workspace.isDirectory())
        {
            System.out.println("[TestFramework] ERROR with argument 4: not a valid path to a workspace directory");
            return false;
        }

        return true;
    }

    /**
   * Create and configure an optimisation manager instance according to the
     * XML files provided as command line arguments to the main method.
   * @param args Command line arguments from main method.
   * @return Optimisation manager instance.
   */
    private IOptimisationManager setUp (String[] args) throws Exception
    {
        DAOFactory daoFactory = null;
        EstimationResult estimationResult = null;
        IPriceCalculator priceCalculator = null;
        Map<String, List<AttributeType>> aslaParams = null;
        Map<String, Set<Resource>> optimisationSpace = null;
        IOptimisationAlgorithm optAlg = null;
        AModel appModel = null;
        AObjectiveFunction objFunc = null;
    IOptimisationManager opt;
    boolean valid = false;

        //--- Setting up various things required by several components ---//
        optUtil = OptimiserUtil.getInstance();
        classLoader = new PESClassLoader();

        daoFactory = DAOFactory.createInstance(DAOFactory.HIBERNATE);
        estimationResult = new EstimationResult();
        priceCalculator = new SamplePriceCalculator();

        //--- Setting up ASLA parameters and optimisation space ---//
        aslaParams = setUpASLAParams();
        optimisationSpace = setUpOptimisationSpace();

        //--- Setting up optimiser components from XML files ---//
        optAlg = setUpOptAlg(args[optAlgIdx]);
        appModel = setUpAppModel(args[modelIdx], daoFactory);
        objFunc = setUpObjFunc(args[objFuncIdx], appModel, priceCalculator, estimationResult, daoFactory, args[workspaceIdx], aslaParams);

        //--- Creating and initialising the Optimiser ---//
        opt = new OptimisationManager();
        valid = opt.init(optimisationSpace, optAlg, objFunc, priceCalculator, args[workspaceIdx], estimationResult, daoFactory);
        if (!valid)
            throw new RuntimeException("ERROR: Optimiser could not be initialised");

        //--- Disabling caching to allow this to execute stand-alone ---//
        optUtil.disableDBCaching = true;
        return opt;
    }

    /**
   * Create a new model instance from the XML file provided as a command line
     * argument to the main method.
   * @param modelXML XML configuration file specified as a command line argument.
   * @param daoFactory DAOFactory required for caching execution results.
   * @return model wrapper instance.
   */
    private AModel setUpAppModel(String modelXML, DAOFactory daoFactory) throws Exception
    {
        Model m = null;
        AModel appModel = null;

    System.out.println("[TestFramework] Loading model from XML file");
        m = optUtil.loadAppModel(modelXML);
        appModel = classLoader.getApplicationModelInstance(m.getWrapper());

        System.out.println("[TestFramework] Initialising model wrapper");
        appModel.init(m, daoFactory);

        System.out.println();
        return appModel;
    }

    /**
   * create a new objective function instance from the XML file provided as a command line
     * argument to the main method.
   * @param xmlFile XML configuration file specified as a command line argument.
   * @param appModel Application model wrapper that should be executed when the
     *                 objective function is evaluated.
   * @param priceCalculator Price calculator instance.
   * @param estimationResult Estimation result object used when caching execution results.
   * @param daoFactory DAOFactory required for caching execution results.
   * @param workspace The workspace directory where file I/O can be performed.
   * @param aslaParams ASLA parameter map.
   * @return objective function instance.
   */
    private AObjectiveFunction setUpObjFunc(String xmlFile, AModel appModel,
            IPriceCalculator priceCalculator, EstimationResult estimationResult,
            DAOFactory daoFactory, String workspace, Map<String, List<AttributeType>> aslaParams) throws Exception
    {
        ObjectiveFunctionConfig objFuncConfig = null;
        AObjectiveFunction objFunc = null;

    System.out.println("[TestFramework] Loading objective function from XML file");
        objFuncConfig = optUtil.loadObjectiveFunction(xmlFile);
        objFunc = classLoader.getObjectiveFunctionInstance(objFuncConfig.getImplClazz());

        System.out.println("[TestFramework] Initialising objective function");
        objFunc.init(objFuncConfig, appModel, aslaParams, workspace, estimationResult, daoFactory);
        objFunc.setPriceCalculator(priceCalculator);

        System.out.println();
        return objFunc;
    }

    /**
   * Create a new optimisation algorithm instance from the XML file provided as a command line
     * argument to the main method.
   * @param xmlFile XML configuration file specified as a command line argument.
   * @return optimisation algorithm instance.
   */
    private IOptimisationAlgorithm setUpOptAlg(String xmlFile) throws Exception
    {
        OptimisationAlgConfig optAlgConfig = null;
        IOptimisationAlgorithm optAlg = null;

        System.out.println("[TestFramework] Loading optimisation algorithm from XML file");
        optAlgConfig = optUtil.loadOptAlg(xmlFile);
        optAlg = classLoader.getOptimisationAlgorithmInstance(optAlgConfig.getAlgClassName());

    System.out.println();
        return optAlg;
    }

    /**
   * Create a new ASLA parameter map.
   * @return ASLA parameter map with a hard coded example value for 'reliability'.
   */
    private Map<String, List<AttributeType>> setUpASLAParams()
    {
        Map<String, List<AttributeType>> params = null;
        List<AttributeType> attrList1 = null;

    params = new HashMap<String, List<AttributeType>>();
        attrList1 = new ArrayList<AttributeType>();
        attrList1.add(optUtil.newAttribute("reliability", "A hypothetical reliability from an ASLA", BasicType.FLOAT, "0.99"));
        params.put("LoadBalancer", attrList1);

        return params;
    }

    /**
     * Sets up an optimisation space for a very simple scenario of two servers,
     * a load balancer and two network links.
     * @return an optimisation space in the form Map<String, Set<Resource>>
     */
    private Map<String, Set<Resource>> setUpOptimisationSpace()
    {
        Map<String, Set<Resource>> optSpace = new HashMap<String, Set<Resource>>();

        optSpace.put("Server1", getASCResources());
        optSpace.put("Server2", getASCResources());
        optSpace.put("LoadBalancer", getASCResources());
        optSpace.put("Link1", getLinkResources());
        optSpace.put("Link2", getLinkResources());

        return optSpace;
    }

    /**
   * Create a new ASC resource set of a CPU, RAM and DISK.
   * @return ASC resource set.
   */
    private Set<Resource> getASCResources ()
    {
        Set<Resource> resources = new HashSet<Resource>();
        resources.add(getCPUResource());
        resources.add(getRAMResource());
        resources.add(getDiskResource());
        return resources;
    }

    /**
   * Create a new CPU resource, which sets up Model, Speed, computationTime,
     * computationDeadline and computationInterval. Only Speed is variable.
   * @return CPU resource.
   */
    private Resource getCPUResource ()
    {
        Resource res = new Resource();

        res.setName("CPU");
        res.addAnAttr(newCpuModelAttrib());
        res.addAnAttr(newCpuSpeedAttrib());
        res.addAnAttr(newCPUCompAttrib("computationTime", 100, "msec"));
        res.addAnAttr(newCPUCompAttrib("computationDeadline", 100, "msec"));
        res.addAnAttr(newCPUCompAttrib("computationInterval", 100, "msec"));

        return res;
    }

    /**
   * Create a new CPU model attribute with hard coded 'x86_80486' value.
   * @return CPU model attribute.
   */
    private AttributeType newCpuModelAttrib()
    {
        AttributeType a = new AttributeType();
        a.setName("cpuModel");
        a.setType(BasicType.STRING);
        a.addAValue(new ValueType("x86_80486", MetricType.EXACT));
        return a;
    }

    /**
   * Create a new CPU speed attribute with hard coded allowed values of '2000, 2200, 2400 MHz'.
   * @return CPU speed attribute.
   */
    private AttributeType newCpuSpeedAttrib()
    {
        AttributeType a = new AttributeType();
        a.setName("cpuSpeed");
        a.setType(BasicType.STRING);
        a.setUnit(new UnitType("MHz", null, null, null));
        a.addAValue(new ValueType("2000", MetricType.VALUESALLOWED));
        a.addAValue(new ValueType("2200", MetricType.VALUESALLOWED));
        a.addAValue(new ValueType("2400", MetricType.VALUESALLOWED));

        return a;
    }

    /**
   * Set up a CPU attribute with a specific name, value (int) and unit type.
   * @return AttributeType instance.
   */
    private AttributeType newCPUCompAttrib(String name, int val, String unit)
    {
        AttributeType a = new AttributeType();
        a.setName(name);
        a.setType(BasicType.INT);
        a.setUnit(new UnitType(unit, null, null, null));
        a.addAValue(new ValueType(String.valueOf(val), MetricType.EXACT));

        return a;
    }

    /**
   * Set up a CPU attribute with a specific name, unit type and a min/max/step value range (int).
   * @return AttributeType instance.
   */
    private AttributeType newCPUCompAttrib(String name, int min, int max, int step, String unit)
    {
        AttributeType a = new AttributeType();
        a.setName(name);
        a.setType(BasicType.INT);
        a.setUnit(new UnitType(unit, null, null, null));
        a.addAValue(new ValueType(String.valueOf(min), MetricType.MIN));
        a.addAValue(new ValueType(String.valueOf(max), MetricType.MAX));
        a.addAValue(new ValueType(String.valueOf(step), MetricType.STEP));

        return a;
    }

    /**
   * Set up a CPU attribute with a specific name, value (double) and unit type.
   * @return AttributeType instance.
   */
    private AttributeType newCPUCompAttrib(String name, double val, String unit)
    {
        AttributeType a = new AttributeType();
        a.setName(name);
        a.setType(BasicType.DOUBLE);
        a.setUnit(new UnitType(unit, null, null, null));
        a.addAValue(new ValueType(String.valueOf(val), MetricType.EXACT));

        return a;
    }

    /**
   * Set up a CPU attribute with a specific name, unit type and a min/max/step value range (double).
   * @return AttributeType instance.
   */
    private AttributeType newCPUCompAttrib(String name, double min, double max, double step, String unit)
    {
        AttributeType a = new AttributeType();
        a.setName(name);
        a.setType(BasicType.DOUBLE);
        a.setUnit(new UnitType(unit, null, null, null));
        a.addAValue(new ValueType(String.valueOf(min), MetricType.MIN));
        a.addAValue(new ValueType(String.valueOf(max), MetricType.MAX));
        a.addAValue(new ValueType(String.valueOf(step), MetricType.STEP));

        return a;
    }

    /**
   * Create a new RAM resource with a hard coded value of '2048 Mbytes'
   * @return RAM resource instance.
   */
    private Resource getRAMResource ()
    {
        Resource res = new Resource();
        AttributeType a = new AttributeType();

        res.setName("RAM");

    a.setName("ramSize");
        a.setType(BasicType.STRING);
        a.setUnit(new UnitType("MB", null, null, null));
        a.addAValue(new ValueType("2048", MetricType.EXACT));

        res.addAnAttr(a);

        return res;
    }

    /**
   * Create a new disk resource with a hard coded value of '100 GBytes'
   * @return Disk resource object.
   */
    private Resource getDiskResource ()
    {
        Resource res = new Resource();
        AttributeType a = new AttributeType();

    res.setName("DISK");

        a.setName("DISKSPACE");
        a.setType(BasicType.STRING);
        a.setUnit(new UnitType("GB", null, null, null));
        a.addAValue(new ValueType("100", MetricType.EXACT));

        res.addAnAttr(a);
        return res;
    }

    /**
   * Create a new link resource (for network links etc), which sets up a set of
     * an INBOUND and OUTBOUND resource.
   * @return Link resource set.
   */
    private Set<Resource> getLinkResources ()
    {
        Set<Resource> resources = new HashSet<Resource>();
        resources.add(getLinkResource("INBOUND"));
        resources.add(getLinkResource("OUTBOUND"));
        return resources;
    }

    /**
   * Create a new link resource (for network links etc).
   * @param name name of the link (INBOUND or OUTBOUND allowed values)
   * @return link resource instance.
   */
    private Resource getLinkResource (String name) // INBOUND or OUTBOUND
    {
        Resource res = new Resource();

        res.setName(name);
        res.addAnAttr(newBandwidthAttrib());
        res.addAnAttr(newJitterAttrib());
        res.addAnAttr(newDelayAttrib());

        return res;
    }

    /**
   * Create a bandwidth attribute with hard coded allowed values in the range
     * [1000000, 10000000] with steps of 1000000 bps.
   * @return Bandwidth attribute instance.
   */
    private AttributeType newBandwidthAttrib()
    {
        AttributeType a = new AttributeType();
        a.setName("bandwidth");
        a.setType(BasicType.INT);
        a.setUnit(new UnitType("bps", null, null, null));
        a.addAValue(new ValueType("1000000", MetricType.MIN));
        a.addAValue(new ValueType("10000000", MetricType.MAX));
        a.addAValue(new ValueType("1000000", MetricType.STEP));
        return a;
    }

    /**
   * Create a jitter attribute with a hard coded value of '20 ms'.
   * @return Jitter attribute instance.
   */
    private AttributeType newJitterAttrib()
    {
        AttributeType a = new AttributeType();

        a.setName("jitter");
        a.setType(BasicType.INT);
        a.setUnit(new UnitType("msec", null, null, null));
        a.addAValue(new ValueType("20", MetricType.EXACT));

        return a;
    }

    /**
   * Create a delay attribute with a hard coded value of '20 ms'.
   * @return Delay attribute instance.
   */
    private AttributeType newDelayAttrib()
    {
        AttributeType a = new AttributeType();
        a.setName("delay");
        a.setType(BasicType.INT);
        a.setUnit(new UnitType("msec", null, null, null));
        a.addAValue(new ValueType("20", MetricType.EXACT));
        return a;
    }

} // SampleOptimiserTest
TOP

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

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.