com.abiquo.api.tasks.util.DatacenterTaskBuilder.java Source code

Java tutorial

Introduction

Here is the source code for com.abiquo.api.tasks.util.DatacenterTaskBuilder.java

Source

/**
 * Abiquo community edition
 * cloud management application for hybrid clouds
 * Copyright (C) 2008-2010 - Abiquo Holdings S.L.
 *
 * This application is free software; you can redistribute it and/or
 * modify it under the terms of the GNU LESSER GENERAL PUBLIC
 * LICENSE as published by the Free Software Foundation under
 * version 3 of the License
 *
 * This software is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * LESSER GENERAL PUBLIC LICENSE v.3 for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with this library; if not, write to the
 * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
 * Boston, MA 02111-1307, USA.
 */

package com.abiquo.api.tasks.util;

import java.security.InvalidParameterException;
import java.util.Map;

import org.apache.commons.io.FilenameUtils;
import org.apache.commons.lang.StringUtils;
import org.apache.commons.lang.WordUtils;

import com.abiquo.commons.amqp.impl.tarantino.domain.DiskSnapshot;
import com.abiquo.commons.amqp.impl.tarantino.domain.HypervisorConnection;
import com.abiquo.commons.amqp.impl.tarantino.domain.StateTransition;
import com.abiquo.commons.amqp.impl.tarantino.domain.VirtualMachineDefinition;
import com.abiquo.commons.amqp.impl.tarantino.domain.dto.DatacenterTasks;
import com.abiquo.commons.amqp.impl.tarantino.domain.operations.ApplyVirtualMachineStateOp;
import com.abiquo.commons.amqp.impl.tarantino.domain.operations.ReconfigureVirtualMachineOp;
import com.abiquo.commons.amqp.impl.tarantino.domain.operations.RefreshVirtualMachineResourcesOp;
import com.abiquo.commons.amqp.impl.tarantino.domain.operations.SnapshotVirtualMachineOp;
import com.abiquo.server.core.cloud.VirtualMachineStateTransition;
import com.abiquo.server.core.task.Job;
import com.abiquo.server.core.task.Job.JobType;
import com.abiquo.server.core.task.Task;
import com.abiquo.server.core.task.enums.TaskType;

/**
 * Builder with a fluent interface to simplify the creation of {@link DatacenterTasks} and
 * {@link Task}.
 * 
 * @author serafin.sedano@abiquo.com
 * @author enric.ruiz@abiquo.com
 */
public class DatacenterTaskBuilder {
    protected VirtualMachineDefinition definition;

    protected HypervisorConnection hypervisor;

    protected Task asyncTask;

    protected DatacenterTasks tarantinoTask;

    public DatacenterTaskBuilder(final VirtualMachineDefinition definition, final HypervisorConnection hypervisor,
            final String userId) {
        init(definition, hypervisor, userId);
    }

    public DatacenterTaskBuilder(final String userId) {
        init(null, null, userId);
    }

    /**
     * Initializes and reset the builder.
     * 
     * @param definition {@link VirtualMachineDefinition} to use
     * @param hypervisor {@link HypervisorConnection} to use
     * @return The {@link DatacenterTaskBuilder} self
     */
    public DatacenterTaskBuilder init(final VirtualMachineDefinition definition,
            final HypervisorConnection hypervisor, final String userId) {
        this.tarantinoTask = new DatacenterTasks();
        this.tarantinoTask.setDependent(Boolean.TRUE);

        this.asyncTask = new Task();
        this.asyncTask.setTaskId(this.tarantinoTask.getId());
        this.asyncTask.setUserId(userId);

        this.definition = definition;
        this.hypervisor = hypervisor;

        return this;
    }

    /**
     * End builder-method to get the {@link DatacenterTasks} for Tarantino.
     * 
     * @return The {@link DatacenterTasks} for Tarantino
     */
    public DatacenterTasks buildTarantinoTask() {
        return this.tarantinoTask;
    }

    /**
     * End builder-method to get the {@link Task} for Redis persistence.
     * 
     * @return The {@link Task} for Redis persistence
     */
    public Task buildAsyncTask(final String ownerId, final TaskType taskType) {
        if (StringUtils.isBlank(ownerId) || taskType == null) {
            throw new InvalidParameterException();
        }

        this.asyncTask.setOwnerId(ownerId);
        this.asyncTask.setType(taskType);

        for (Job job : this.asyncTask.getJobs()) {
            String jobName = format(job.getType().name(), false);
            String taskName = format(this.asyncTask.getType().name(), true);
            String ownerName = format(this.asyncTask.getType().getOwnerType().name(), false);

            job.setDescription(
                    String.format("%s task's %s on %s with id %s", taskName, jobName, ownerName, ownerId));
        }

        return this.asyncTask;
    }

    private String format(final String name, final boolean capitalize) {
        String formatted = name.toLowerCase();

        if (capitalize) {
            formatted = WordUtils.capitalize(formatted);
        }

        return formatted.replace("_", " ");
    }

    /**
     * Add new {@link VirtualMachineStateTransition}. This method must be used to add transitions
     * that only needs {@link VirtualMachineDefinition} and {@link HypervisorConnection} to be
     * created.
     * 
     * @param transition The transition type to create
     * @return The {@link DatacenterTaskBuilder} self
     */
    public DatacenterTaskBuilder add(final VirtualMachineStateTransition transition) {
        return add(this.definition, this.hypervisor, transition, null);
    }

    /**
     * Add new {@link VirtualMachineStateTransition}. This method must be used to add transitions
     * that only needs {@link VirtualMachineDefinition} and {@link HypervisorConnection} to be
     * created.
     * 
     * @param transition The transition type to create
     * @param extraData map with extra data to add to the job.
     * @return The {@link DatacenterTaskBuilder} self
     */
    public DatacenterTaskBuilder add(final VirtualMachineStateTransition transition,
            final Map<String, String> extraData) {
        return add(this.definition, this.hypervisor, transition, extraData);
    }

    /**
     * Add new {@link VirtualMachineStateTransition}. This method must be used to add transitions
     * that only needs {@link VirtualMachineDefinition} and {@link HypervisorConnection} to be
     * created.
     * 
     * @param transition The transition type to create
     * @param extraData map to add to the job.
     * @return The {@link DatacenterTaskBuilder} self
     */
    protected DatacenterTaskBuilder add(final VirtualMachineDefinition definition,
            final HypervisorConnection hypervisor, final VirtualMachineStateTransition transition,
            final Map<String, String> extraData) {
        switch (transition) {
        case PAUSE:
        case POWEROFF:
        case POWERON:
        case RESET:
        case RESUME:
        case CONFIGURE:
        case DECONFIGURE:
            ApplyVirtualMachineStateOp job = new ApplyVirtualMachineStateOp();
            job.setVirtualMachine(definition);
            job.setHypervisorConnection(hypervisor);
            job.setTransaction(toCommonsTransition(transition));

            this.tarantinoTask.addDatacenterJob(job);
            Job redisJob = createRedisJob(job.getId(), this.getTaskTypeFromTransition(transition));
            if (extraData != null) {
                redisJob.getData().putAll(extraData);
            }
            this.asyncTask.getJobs().add(redisJob);

            break;

        case ALLOCATE:
        case DEALLOCATE:
        case SNAPSHOT:
        case RECONFIGURE:
            throw new InvalidParameterException();
        }

        return this;
    }

    /**
     * Adds a new {@link ReconfigureVirtualMachineOp} to the Jobs collection.
     * 
     * @param newDefinition The virtualmachine redefinition
     * @return The {@link DatacenterTaskBuilder} self
     */
    public DatacenterTaskBuilder addReconfigure(final VirtualMachineDefinition newDefinition) {
        ReconfigureVirtualMachineOp job = new ReconfigureVirtualMachineOp();
        job.setVirtualMachine(definition);
        job.setHypervisorConnection(hypervisor);
        job.setNewVirtualMachine(newDefinition);

        this.tarantinoTask.addDatacenterJob(job);
        this.asyncTask.getJobs().add(createRedisJob(job.getId(), JobType.RECONFIGURE));

        return this;
    }

    /**
     * Adds a new {@link SnapshotVirtualMachineOp} to the Jobs collection.
     * 
     * @param destinationDisk The destination disk for the snapshot
     * @return The {@link DatacenterTaskBuilder} self
     */
    public DatacenterTaskBuilder addSnapshot(final DiskSnapshot destinationDisk) {
        SnapshotVirtualMachineOp job = new SnapshotVirtualMachineOp();
        job.setVirtualMachine(definition);
        job.setHypervisorConnection(hypervisor);
        job.setDiskSnapshot(destinationDisk);

        this.tarantinoTask.addDatacenterJob(job);

        Job redisJob = createRedisJob(job.getId(), JobType.SNAPSHOT);
        redisJob.getData().put("name", destinationDisk.getName());
        redisJob.getData().put("path",
                FilenameUtils.concat(destinationDisk.getPath(), destinationDisk.getSnapshotFilename()));

        this.asyncTask.getJobs().add(redisJob);

        return this;
    }

    /**
     * Adds a new {@link SnapshotVirtualMachineOp} to the Jobs collection.
     * 
     * @param destinationDisk The destination disk for the snapshot
     * @return The {@link DatacenterTaskBuilder} self
     */
    public DatacenterTaskBuilder addRefreshResources() {
        RefreshVirtualMachineResourcesOp job = new RefreshVirtualMachineResourcesOp();
        job.setVirtualMachine(definition);
        job.setHypervisorConnection(hypervisor);

        this.tarantinoTask.addDatacenterJob(job);
        this.asyncTask.getJobs().add(createRedisJob(job.getId(), JobType.REFRESH));

        return this;
    }

    /**
     * Encapsulates the {@link Job} creation.
     * 
     * @param jobId The job ID to set
     * @param jobType The job type
     * @return A new instance of {@link Job}
     */
    protected Job createRedisJob(final String jobId, final JobType jobType) {
        Job job = new Job();

        job.setId(jobId);
        job.setParentTaskId(this.asyncTask.getTaskId());
        job.setType(jobType);

        return job;
    }

    /**
     * Translate a {@link VirtualMachineStateTransition} to {@link StateTransition}
     * 
     * @param transition The transition to translate
     * @return The {@link StateTransition} translation
     */
    protected StateTransition toCommonsTransition(final VirtualMachineStateTransition transition) {
        switch (transition) {
        case ALLOCATE:
            return StateTransition.ALLOCATE;

        case CONFIGURE:
            return StateTransition.CONFIGURE;

        case DEALLOCATE:
            return StateTransition.DEALLOCATE;

        case DECONFIGURE:
            return StateTransition.DECONFIGURE;

        case PAUSE:
            return StateTransition.PAUSE;

        case POWEROFF:
            return StateTransition.POWEROFF;

        case POWERON:
            return StateTransition.POWERON;

        case RECONFIGURE:
            return StateTransition.RECONFIGURE;

        case RESET:
            return StateTransition.RESET;

        case RESUME:
            return StateTransition.RESUME;

        case SNAPSHOT:
            return StateTransition.SNAPSHOT;

        default:
            throw new InvalidParameterException("Error unknown transition: " + transition);
        }
    }

    /**
     * Return the {@link JobType} that is related to this {@link VirtualMachineStateTransition}. <br>
     * <br>
     * Null if empty.
     * 
     * @param machineStateTransition the current.
     * @return JobType
     */
    public JobType getTaskTypeFromTransition(final VirtualMachineStateTransition machineStateTransition) {
        switch (machineStateTransition) {
        case CONFIGURE: {
            return JobType.CONFIGURE;
        }
        case DECONFIGURE: {
            return JobType.DECONFIGURE;
        }
        case POWEROFF: {
            return JobType.POWER_OFF;
        }
        case POWERON: {
            return JobType.POWER_ON;
        }
        case PAUSE: {
            return JobType.PAUSE;
        }
        case RESUME: {
            return JobType.RESET;
        }
        case SNAPSHOT: {
            return JobType.SNAPSHOT;
        }
        case RECONFIGURE: {
            return JobType.RECONFIGURE;
        }
        case RESET: {
            return JobType.RESET;
        }
        default: {
            throw new InvalidParameterException("Error unknown transition: " + machineStateTransition);
        }
        }
    }
}