Skip to content

Asynchronous monitor example

nacx edited this page May 25, 2012 · 2 revisions

This example shows how to deploy an existing virtual machine, and monitor the deployment process asynchronously without blocking the main thread. Before you continue, make sure you have read the basics and the deploy tutorial so you can understand the code.

DeployExample.java

This is the main application thread. It deploys the virtual machine and starts the monitoring thread to asynchronously monitor the deployment process.

import org.jclouds.ContextBuilder;
import org.jclouds.abiquo.AbiquoApiMetadata;
import org.jclouds.abiquo.AbiquoContext;
import org.jclouds.abiquo.domain.cloud.VirtualAppliance;
import org.jclouds.abiquo.domain.cloud.VirtualDatacenter;
import org.jclouds.abiquo.domain.cloud.VirtualMachine;
import org.jclouds.abiquo.monitor.VirtualMachineMonitor;
import org.jclouds.abiquo.predicates.cloud.VirtualMachinePredicates;
import org.jclouds.logging.config.NullLoggingModule;

import com.google.common.collect.ImmutableSet;
import com.google.inject.Module;

/**
 * Asynchronous deployment example.
 * <p>
 * This example shows how to deploy a virtual machine and asynchronously monitor the deployment
 * process without blocking the main thread.
 */
public class DeployExample
{
    public static void main(final String[] args)
    {
        // Build the context (we use a NullLoggingModule because we don't want logging in this
        // example)
        AbiquoContext context = ContextBuilder.newBuilder(new AbiquoApiMetadata())
            .endpoint("http://10.60.21.33/api")
            .credentials("user", "password")
            .modules(ImmutableSet.<Module> of(new NullLoggingModule()))
            .build(AbiquoContext.class);

        try
        {
            // Get the virtual datacenter and virtual appliance by id
            VirtualDatacenter vdc = context.getCloudService().getVirtualDatacenter(7);
            VirtualAppliance vapp = vdc.getVirtualAppliance(6);
            VirtualMachine vm =
                vapp.findVirtualMachine(VirtualMachinePredicates
                    .name("ABQ_524095a7-85d4-4fa2-8d96-5109f308ae1e"));

            // Create the event handler that will be notified asynchronously when deployment
            // finishes
            VmEventHandler handler = new VmEventHandler(context, vm);

            // Register the event handler in the monitoring service. This way the service will
            // notify all deploy related events to it.
            VirtualMachineMonitor monitor =
                context.getMonitoringService().getVirtualMachineMonitor();
            monitor.register(handler);

            // Deploy the virtual machine
            vm.deploy();

            // Start monitoring it
            monitor.monitorDeploy(vm);

            // The monitor method does not block the thread until deployment finishes. Instead it
            // spawns a monitoring thread and will asynchronously notify all registered event
            // handlers when deployment finishes.
            System.out.println("Started monitoring virtual machine");
            System.out.println("Terminating main thread");
        }
        catch (Exception ex)
        {
            // Note that in this example we don't close the context in a finally block. We only
            // close it if something fails; otherwise, the event handler will close the context in a
            // separate thread when the deploy operation finishes
            if (context != null)
            {
                context.close();
            }
        }
    }
}

VmEventHandler.java

This is the event handler that will be notified with all events related to virtual machines.

import org.jclouds.abiquo.AbiquoContext;
import org.jclouds.abiquo.domain.cloud.VirtualMachine;
import org.jclouds.abiquo.events.handlers.AbstractEventHandler;
import org.jclouds.abiquo.events.monitor.CompletedEvent;
import org.jclouds.abiquo.events.monitor.FailedEvent;
import org.jclouds.abiquo.events.monitor.MonitorEvent;
import org.jclouds.abiquo.events.monitor.TimeoutEvent;
import org.jclouds.abiquo.monitor.VirtualMachineMonitor;

import com.google.common.eventbus.Subscribe;

/**
 * Handles events related to a concrete virtual machine.
 */
public class VmEventHandler extends AbstractEventHandler<VirtualMachine>
{
    /** Used to close the context when the job finishes. */
    private AbiquoContext context;

    /** Thwe monitored virtual machine. */
    private VirtualMachine vm;

    public VmEventHandler(final AbiquoContext context, final VirtualMachine vm)
    {
        super();
        this.context = context;
        this.vm = vm;
    }

    /**
     * Async monitors will receive all events, so we need to be careful and handle only the events
     * we are interested in.
     * 
     * @param event The populated event. It holds the monitored object in the event.getTarget()
     *            property.
     * @return A boolean indicating if this handler instance must handle the given event.
     */
    @Override
    protected boolean handles(final MonitorEvent<VirtualMachine> event)
    {
        return event.getTarget().getId().equals(vm.getId());
    }

    /**
     * This method will be called when the monitored job completes without error.
     */
    @Subscribe  //The subscribe annotation registers the method as an event handler.
    public void onComplete(final CompletedEvent<VirtualMachine> event)
    {
        if (handles(event))
        {
            System.out.println("VM " + event.getTarget().getName() + " deployed");

            // Stop listening to events and close the context (in this example when the vm is
            // deployed the application should end)
            unregisterAndClose();
        }
    }

    /**
     * This method will be called when the monitored job fails.
     */
    @Subscribe  //The subscribe annotation registers the method as an event handler.
    public void onFailure(final FailedEvent<VirtualMachine> event)
    {
        if (handles(event))
        {
            System.out.println("Deployment for" + event.getTarget().getName() + " failed");

            // Stop listening to events and close the context (in this example when the vm is
            // deployed the application should end)
            unregisterAndClose();
        }
    }

    /**
     * This method will be called when the monitored job times out.
     * <p>
     * In our example we are not invoking the
     * {@link VirtualMachineMonitor#monitorDeploy(Long, java.util.concurrent.TimeUnit, VirtualMachine...)}
     * method to specify a timeout, so this method will never be called.
     */
    @Subscribe  //The subscribe annotation registers the method as an event handler.
    public void onTimeout(final TimeoutEvent<VirtualMachine> event)
    {
        if (handles(event))
        {
            System.out.println("Deployment for vm " + event.getTarget().getName() + " timed out");

            // Stop listening to events and close the context (in this example when the vm is
            // deployed the application should end)
            unregisterAndClose();
        }
    }

    /**
     * Unregisters the handler and closes the context.
     */
    private void unregisterAndClose()
    {
        context.getMonitoringService().unregister(this);
        context.close();
        System.out.println("Terminating monitoring thread");
    }
}