br.unb.cic.bionimbuz.controller.slacontroller.SlaController.java Source code

Java tutorial

Introduction

Here is the source code for br.unb.cic.bionimbuz.controller.slacontroller.SlaController.java

Source

/*
 * To change this license header, choose License Headers in Project Properties.
 * To change this template file, choose Tools | Templates
 * and open the template in the editor.
 */
package br.unb.cic.bionimbuz.controller.slacontroller;

import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.List;
import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.TimeUnit;

import org.apache.commons.lang3.concurrent.BasicThreadFactory;
import org.apache.zookeeper.WatchedEvent;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.google.common.base.Preconditions;
import com.google.inject.Inject;

import br.unb.cic.bionimbuz.controller.Controller;
import br.unb.cic.bionimbuz.controller.elasticitycontroller.AmazonAPI;
import br.unb.cic.bionimbuz.controller.elasticitycontroller.GoogleAPI;
import br.unb.cic.bionimbuz.controller.usercontroller.UserController;
import br.unb.cic.bionimbuz.model.Instance;
import br.unb.cic.bionimbuz.model.Log;
import br.unb.cic.bionimbuz.model.LogSeverity;
import br.unb.cic.bionimbuz.model.Prediction;
import br.unb.cic.bionimbuz.model.SLA;
import br.unb.cic.bionimbuz.model.User;
import br.unb.cic.bionimbuz.model.Workflow;
import br.unb.cic.bionimbuz.persistence.dao.WorkflowLoggerDao;
import br.unb.cic.bionimbuz.plugin.PluginInfo;
import br.unb.cic.bionimbuz.services.RepositoryService;
import br.unb.cic.bionimbuz.services.messaging.CloudMessageService;
import br.unb.cic.bionimbuz.services.messaging.CuratorMessageService.Path;
import br.unb.cic.bionimbuz.services.monitor.MonitoringService;

/**
 *
 * @author zoonimbus
 */
public class SlaController implements Controller, Runnable {

    private static final int TIME_TO_RUN = 1;
    private static final long ONE_HOUR_MILLES = 36 * 100000;
    private static final Logger LOGGER = LoggerFactory.getLogger(UserController.class);
    private final WorkflowLoggerDao loggerDao;
    private final ScheduledExecutorService threadExecutor = Executors.newScheduledThreadPool(1,
            new BasicThreadFactory.Builder().namingPattern("SlaController-%d").build());
    protected CloudMessageService cms;
    private final RepositoryService rs;

    /**
     * Starts SlaController execution
     *
     * @param cms
     * @param rs
     */
    @Inject
    public SlaController(CloudMessageService cms, RepositoryService rs) {
        Preconditions.checkNotNull(cms);
        Preconditions.checkNotNull(rs);
        this.cms = cms;
        this.rs = rs;
        this.loggerDao = new WorkflowLoggerDao();
    }

    @Override
    public void start() {
        LOGGER.info("SLAController started");
        this.threadExecutor.scheduleAtFixedRate(this, 0, TIME_TO_RUN, TimeUnit.MINUTES);
    }

    @Override
    public void shutdown() {
        throw new UnsupportedOperationException("Not supported yet."); // To change body of generated methods, choose Tools | Templates.
    }

    @Override
    public void getStatus() {
        throw new UnsupportedOperationException("Not supported yet."); // To change body of generated methods, choose Tools | Templates.
    }

    @Override
    public void verifyPlugins() {
        throw new UnsupportedOperationException("Not supported yet."); // To change body of generated methods, choose Tools | Templates.
    }

    @Override
    public void event(WatchedEvent eventType) {
        LOGGER.info("DISPARADOOOOOOOOOOOOOOOOOOOOOO");
        switch (eventType.getType()) {

        case NodeChildrenChanged:
            if (eventType.getPath().equals(Path.USERS_INFO.getFullPath())) {
                LOGGER.info("Imprimir");

                // for (User u : MonitoringService.getZkUsers()) {
                // LOGGER.info("User: " + u.toString());
                // for (Workflow work : u.getWorkflows()) {
                // LOGGER.info("Workflow: " + work.toString());
                // }
                // }
            }
            break;
        case NodeDeleted:
            break;
        case NodeCreated:
            break;
        case NodeDataChanged:
            break;
        case None:
            break;
        default:
            break;
        }
    }

    @Override
    public void run() {
        LOGGER.info("[SlaController] Checking SLA users: "
                + new SimpleDateFormat("dd/MM/yyyy HH:mm:ss").format(new Date(System.currentTimeMillis())));
        this.checkSla();
        // if(!repositoryService.getUsers().isEmpty()){
        // users=repositoryService.getUsers();
        // }
    }

    /**
     * Check all the SLA from all users
     */
    private void checkSla() {
        try {
            //
            for (final User u : MonitoringService.getZkUsers()) {
                boolean deleteZkWorkflow = false;
                for (final Workflow work : u.getWorkflows()) {
                    final Double toleranceCost = work.getSla().getExeceedValueExecutionCost();
                    final Double limitCost = work.getSla().getLimitationValueExecutionCost();
                    final Long limitTime = work.getSla().getLimitationValueExecutionTime();
                    double workflowCostPerHour = 0d;
                    double currentCost = 0D;
                    long period = System.currentTimeMillis();
                    final int VARIANCE = 60 * 1000 * TIME_TO_RUN;
                    // calcula o gasto atual
                    if (limitCost != null || limitTime != null) {
                        for (final Instance i : work.getIntancesWorkflow()) {
                            workflowCostPerHour += i.getCostPerHour();
                            currentCost += (System.currentTimeMillis() + VARIANCE - i.getCreationTimer())
                                    * i.getCostPerHour();
                            if (i.getCreationTimer() < period) {
                                period = i.getCreationTimer();
                            }
                        }
                        LOGGER.info(
                                "[SlaController] Checking SLA user: " + u.getNome() + " Workflow: " + work.getId());
                        // Se aceitou a predio na montagem do workflow
                        if (work.getSla().getPrediction()) {
                            // System.out.println("Verificar os tempos, atribuidos aos servios");
                            for (final Prediction pred : work.getSla().getSolutions()) {
                                for (final Instance i : work.getIntancesWorkflow()) {
                                    // Verifica se o ip da instancia  o mesmo da solucao dada pela predicao
                                    if (pred.getInstance().getIp().equals(i.getId())) {
                                        // Se for verifica se o tempo previsto foi extrapolado
                                        if (System.currentTimeMillis() - i.getCreationTimer() > pred
                                                .getTimeService()) {
                                            // se tiver estrapolado tem que mandar um alerta ainda nao definido
                                            LOGGER.info("[SlaController] Execution time service has been hitted");
                                            this.loggerDao.log(new Log("Tempo limite da instncia: " + i.getIp()
                                                    + " previsto passou, tempo previsto: "
                                                    + new SimpleDateFormat("HH:mm:ss")
                                                            .format(new Date(pred.getTimeService()))
                                                    + " tempo atual: "
                                                    + new SimpleDateFormat("HH:mm:ss").format(new Date(
                                                            System.currentTimeMillis() - i.getCreationTimer())),
                                                    work.getUserId(), work.getId(), LogSeverity.WARN));
                                            // deleteInstances(i.getProvider(), i.getIp());
                                        }
                                        if ((System.currentTimeMillis() - i.getCreationTimer())
                                                * i.getCostPerHour() > pred.getCustoService()) {
                                            // se tiver estrapolado tem que mandar um alerta ainda nao definido
                                            LOGGER.info("[SlaController] Execution cust service has been hitted");
                                            this.loggerDao
                                                    .log(new Log(
                                                            "Custo limite da instncia: " + i.getIp()
                                                                    + " previsto passou, custo previsto:$ "
                                                                    + pred.getCustoService() + " Custo: "
                                                                    + (System.currentTimeMillis()
                                                                            - i.getCreationTimer())
                                                                            * i.getCostPerHour(),
                                                            work.getUserId(), work.getId(), LogSeverity.WARN));
                                            // deleteInstances(i.getProvider(), i.getIp());
                                        }
                                    }
                                }
                            }
                        } else {
                            if (work.getSla().getLimitationExecution()) {
                                // se passou o limite e o usuario esta disposto a pagar um pouco mais para finalizar o workflow
                                if (limitTime != null
                                        && System.currentTimeMillis() - period > limitTime - VARIANCE) {
                                    final long toleranceTime = (long) (toleranceCost / workflowCostPerHour
                                            * ONE_HOUR_MILLES);
                                    if (System.currentTimeMillis() - period > toleranceTime + limitTime
                                            - VARIANCE) {
                                        this.deleteInstances(work.getIntancesWorkflow());
                                        deleteZkWorkflow = true;
                                        final String message = String.format(
                                                "O tempo limite de execuo (%s horas) do Workflow Id: %s foi excedido em %s.",
                                                limitTime, work.getId(),
                                                System.currentTimeMillis() - (toleranceTime + limitTime));
                                        this.loggerDao.log(
                                                new Log(message, work.getUserId(), work.getId(), LogSeverity.WARN));
                                        LOGGER.debug(
                                                "[SlaController] Limitating execution time has been hitted, Removing workflow: "
                                                        + work.getId() + " from User: " + u.getNome());
                                    }
                                }
                            }
                        }
                        // TODO tem que modificar para verificar se o workflow
                        // terminou pegando dos peers;
                        if (limitCost != null && limitCost > 0 && currentCost > toleranceCost + limitCost) {
                            // terminate instances by elasticity controller
                            this.deleteInstances(work.getIntancesWorkflow());
                            deleteZkWorkflow = true;
                            final String message = String.format(
                                    "O custo limite de execuo (U$ %s) do Workflow Id: %s foi excedido em %s. Workflow interrompido.",
                                    limitCost + toleranceCost, work.getId(),
                                    currentCost - (limitCost + toleranceCost));
                            this.loggerDao.log(new Log(message, work.getUserId(), work.getId(), LogSeverity.WARN));
                            LOGGER.debug(
                                    "[SlaController] Limitating execution cost has been hitted, Removing workflow: "
                                            + work.getId() + " from User: " + u.getNome());
                        }
                    }
                    // deleta do zookeeper o workflow que teve suas maquinas excluidas
                    if (deleteZkWorkflow) {
                        this.cms.delete(Path.NODE_WORFLOW_USER.getFullPath(u.getLogin(), work.getId()));
                        u.getWorkflows().remove(work);
                        deleteZkWorkflow = false;
                    }
                }
            }
        } catch (final Exception ex) {
            LOGGER.debug(ex.getMessage());
        }
    }

    /**
     * Sobrecarga para deletar todas as instancias do workflow e os peers
     * correspondentes do zookeeper
     *
     * @param list
     */
    private void deleteInstances(List<Instance> list) {
        for (final Instance element : list) {
            this.deleteInstances(element.getProvider(), element.getIp());
        }
    }

    /**
     * Chama o metodo das api da amazon ou da google para deletar a instancia
     * com o ip
     *
     * @param provider
     * @param ip
     */
    private void deleteInstances(String provider, String ip) {
        switch (provider) {
        case "Amazon": {
            final AmazonAPI amazonapi = new AmazonAPI();
            // amazonapi.createinstance(type, nameInstance);
            amazonapi.terminate(ip);
            break;
        }
        case "Google": {
            final GoogleAPI googleapi = new GoogleAPI();
            // amazonapi.createinstance(type, nameInstance);
            googleapi.terminate(ip);
        }
        default:
            break;
        }
    }
    /**
     * TODO fazer a verificao do jobs nos peers
     *
     * @param wokflow
     */
    // public void verificaJobs(Workflow wokflow){
    // for(final PluginInfo peer : this.rs.getPeers().values()){
    // for (final String taskId : this.cms.getChildren(Path.TASKS.getFullPath(peer.getId()), null)) {
    // Job jobp = new Job();
    // try {
    // final PluginTask plugintask = new ObjectMapper().readValue(this.cms.getData(Path.NODE_TASK.getFullPath(peer.getId(), taskId), null), PluginTask.class);
    // jobp= plugintask.getJobInfo();
    // } catch (IOException ex) {
    // java.util.logging.Logger.getLogger(SlaController.class.getName()).log(Level.SEVERE, null, ex);
    // }
    // for(Job job : wokflow.getJobs()){
    // if (job.getId().equals(jobp.getId())){
    // if(jobp.getTimestamp()){
    // }
    // }
    // }
    // }
    // }
    // }

    /**
     * verifica se as instancias criadas pelos servidores so as mesmas das especificaes
     *
     * @param instancesUser
     * @param userId
     * @param worflowId
     */
    public void compareHardware(List<Instance> instancesUser, Long userId, String worflowId) {

        for (final Instance iUser : instancesUser) {
            this.loggerDao.log(
                    new Log("Mquina virtual criada...Ip: " + iUser.getIp() + " Provedor: " + iUser.getProvider(),
                            userId, worflowId, LogSeverity.INFO));
            for (final PluginInfo peer : this.rs.getPeers().values()) {
                if (iUser.getIp().equals(peer.getHost().getAddress())) {
                    if (!peer.getNumCores().equals(iUser.getNumCores())) {
                        this.loggerDao.log(new Log("Instncia: " + iUser.getIp()
                                + " no corresponde as especificaes de numeros de cores esperados: "
                                + iUser.getNumCores() + " nmero de cores da instncia: " + peer.getNumCores(),
                                userId, worflowId, LogSeverity.WARN));
                    }
                    if (((peer.getFactoryFrequencyCore()) / 1000000000.0D) != iUser.getCpuHtz()) {
                        this.loggerDao.log(new Log(
                                "Instncia: " + iUser.getIp()
                                        + " no corresponde as especificaes da frequncia de clock esperada: "
                                        + iUser.getCpuHtz() + "GHZ frequncia de clock da instncia: "
                                        + peer.getFactoryFrequencyCore() + "GHZ",
                                userId, worflowId, LogSeverity.WARN));
                    }
                    if (!peer.getMemoryTotal().equals(iUser.getMemoryTotal())) {
                        this.loggerDao.log(new Log("Instncia: " + iUser.getIp()
                                + " no corresponde as especificaes de quantidade de memoria esperada: "
                                + iUser.getMemoryTotal() + "GB, quantidade de memria da instncia: "
                                + peer.getMemoryTotal() + " GB", userId, worflowId, LogSeverity.WARN));
                    }
                }
            }
        }
    }

    public void startSla(SLA sla, Workflow workflow) {

    }

    public void createSlaTemplate(SLA sla, Workflow workflow) {

    }

}