com.eucalyptus.vm.VmControl.java Source code

Java tutorial

Introduction

Here is the source code for com.eucalyptus.vm.VmControl.java

Source

/*************************************************************************
 * Copyright 2009-2014 Eucalyptus Systems, Inc.
 *
 * This program is free software: you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation; version 3 of the License.
 *
 * This program 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 General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program.  If not, see http://www.gnu.org/licenses/.
 *
 * Please contact Eucalyptus Systems, Inc., 6755 Hollister Ave., Goleta
 * CA 93117, USA or visit http://www.eucalyptus.com/licenses/ if you need
 * additional information or have any questions.
 *
 * This file may incorporate work covered under the following copyright
 * and permission notice:
 *
 *   Software License Agreement (BSD License)
 *
 *   Copyright (c) 2008, Regents of the University of California
 *   All rights reserved.
 *
 *   Redistribution and use of this software in source and binary forms,
 *   with or without modification, are permitted provided that the
 *   following conditions are met:
 *
 *     Redistributions of source code must retain the above copyright
 *     notice, this list of conditions and the following disclaimer.
 *
 *     Redistributions in binary form must reproduce the above copyright
 *     notice, this list of conditions and the following disclaimer
 *     in the documentation and/or other materials provided with the
 *     distribution.
 *
 *   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
 *   "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
 *   LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
 *   FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
 *   COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
 *   INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
 *   BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
 *   LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
 *   CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
 *   LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
 *   ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
 *   POSSIBILITY OF SUCH DAMAGE. USERS OF THIS SOFTWARE ACKNOWLEDGE
 *   THE POSSIBLE PRESENCE OF OTHER OPEN SOURCE LICENSED MATERIAL,
 *   COPYRIGHTED MATERIAL OR PATENTED MATERIAL IN THIS SOFTWARE,
 *   AND IF ANY SUCH MATERIAL IS DISCOVERED THE PARTY DISCOVERING
 *   IT MAY INFORM DR. RICH WOLSKI AT THE UNIVERSITY OF CALIFORNIA,
 *   SANTA BARBARA WHO WILL THEN ASCERTAIN THE MOST APPROPRIATE REMEDY,
 *   WHICH IN THE REGENTS' DISCRETION MAY INCLUDE, WITHOUT LIMITATION,
 *   REPLACEMENT OF THE CODE SO IDENTIFIED, LICENSING OF THE CODE SO
 *   IDENTIFIED, OR WITHDRAWAL OF THE CODE CAPABILITY TO THE EXTENT
 *   NEEDED TO COMPLY WITH ANY SUCH LICENSES OR RIGHTS.
 ************************************************************************/

package com.eucalyptus.vm;

import static com.eucalyptus.cloud.run.VerifyMetadata.ImageInstanceTypeVerificationException;

import java.util.ArrayList;
import java.util.Collection;
import java.util.Date;
import java.util.List;
import java.util.Map;
import java.util.NoSuchElementException;
import java.util.Set;

import javax.crypto.Mac;
import javax.crypto.spec.SecretKeySpec;
import javax.persistence.EntityTransaction;

import com.eucalyptus.auth.AccessKeys;
import com.eucalyptus.auth.Accounts;
import com.eucalyptus.auth.AuthException;
import com.eucalyptus.blockstorage.Volume;
import com.eucalyptus.blockstorage.Volumes;
import com.eucalyptus.cloud.util.InvalidInstanceProfileMetadataException;
import com.eucalyptus.cloud.util.NoSuchImageIdException;
import com.eucalyptus.cloud.util.NotEnoughResourcesException;
import com.eucalyptus.compute.ComputeException;
import com.eucalyptus.compute.identifier.InvalidResourceIdentifier;
import com.eucalyptus.cloud.VmInstanceLifecycleHelpers;
import com.eucalyptus.cloud.util.InvalidMetadataException;
import com.eucalyptus.cloud.util.NoSuchMetadataException;
import com.eucalyptus.compute.identifier.ResourceIdentifiers;
import com.eucalyptus.crypto.util.B64;
import com.eucalyptus.entities.TransactionResource;
import com.eucalyptus.images.KernelImageInfo;
import com.eucalyptus.images.RamdiskImageInfo;
import com.eucalyptus.images.Images;
import com.eucalyptus.keys.NoSuchKeyMetadataException;
import com.eucalyptus.network.NetworkGroup;
import com.eucalyptus.vmtypes.VmType;
import com.eucalyptus.vmtypes.VmTypes;
import com.google.common.base.Joiner;

import org.apache.log4j.Logger;
import org.bouncycastle.util.encoders.Base64;
import org.bouncycastle.util.encoders.DecoderException;
import org.hibernate.criterion.Criterion;
import org.hibernate.criterion.Restrictions;

import com.eucalyptus.auth.principal.AccessKey;
import com.eucalyptus.auth.principal.AccountFullName;
import com.eucalyptus.compute.common.CloudMetadatas;
import com.eucalyptus.compute.common.ImageMetadata;
import com.eucalyptus.cloud.ResourceToken;
import com.eucalyptus.cloud.run.AdmissionControl;
import com.eucalyptus.cloud.run.Allocations;
import com.eucalyptus.cloud.run.Allocations.Allocation;
import com.eucalyptus.cloud.run.ClusterAllocator;
import com.eucalyptus.cloud.run.ContractEnforcement;
import com.eucalyptus.cloud.run.VerifyMetadata;
import com.eucalyptus.cluster.Cluster;
import com.eucalyptus.cluster.Clusters;
import com.eucalyptus.cluster.callback.RebootCallback;
import com.eucalyptus.component.ServiceConfiguration;
import com.eucalyptus.component.Topology;
import com.eucalyptus.component.id.ClusterController;
import com.eucalyptus.compute.ClientComputeException;
import com.eucalyptus.context.Context;
import com.eucalyptus.context.Contexts;
import com.eucalyptus.entities.Entities;
import com.eucalyptus.entities.TransactionException;
import com.eucalyptus.images.BlockStorageImageInfo;
import com.eucalyptus.records.EventRecord;
import com.eucalyptus.records.EventType;
import com.eucalyptus.records.Logs;
import com.eucalyptus.tags.Filter;
import com.eucalyptus.tags.Filters;
import com.eucalyptus.tags.Tag;
import com.eucalyptus.tags.TagSupport;
import com.eucalyptus.tags.Tags;
import com.eucalyptus.util.EucalyptusCloudException;
import com.eucalyptus.util.Exceptions;
import com.eucalyptus.util.OwnerFullName;
import com.eucalyptus.util.RestrictedTypes;
import com.eucalyptus.util.TypeMappers;
import com.eucalyptus.util.async.AsyncRequests;
import com.eucalyptus.util.async.Request;
import com.eucalyptus.vm.Bundles.BundleCallback;
import com.eucalyptus.vm.VmBundleTask.BundleState;
import com.eucalyptus.vm.VmInstance.VmState;
import com.eucalyptus.vm.VmInstance.VmStateSet;
import com.eucalyptus.vm.VmInstances.TerminatedInstanceException;
import com.google.common.base.Function;
import com.google.common.base.Objects;
import com.google.common.base.Predicate;
import com.google.common.base.Predicates;
import com.google.common.base.Strings;
import com.google.common.collect.Collections2;
import com.google.common.collect.Iterables;
import com.google.common.collect.Lists;
import com.google.common.collect.Maps;
import com.google.common.collect.Multimap;
import com.google.common.collect.Sets;
import com.google.common.collect.TreeMultimap;

import edu.ucsb.eucalyptus.msgs.CreatePlacementGroupResponseType;
import edu.ucsb.eucalyptus.msgs.CreatePlacementGroupType;
import edu.ucsb.eucalyptus.msgs.DeletePlacementGroupResponseType;
import edu.ucsb.eucalyptus.msgs.DeletePlacementGroupType;
import edu.ucsb.eucalyptus.msgs.DescribeInstanceAttributeResponseType;
import edu.ucsb.eucalyptus.msgs.DescribeInstanceAttributeType;
import edu.ucsb.eucalyptus.msgs.DescribeInstanceStatusResponseType;
import edu.ucsb.eucalyptus.msgs.DescribeInstanceStatusType;
import edu.ucsb.eucalyptus.msgs.DescribeInstancesResponseType;
import edu.ucsb.eucalyptus.msgs.DescribeInstancesType;
import edu.ucsb.eucalyptus.msgs.DescribePlacementGroupsResponseType;
import edu.ucsb.eucalyptus.msgs.DescribePlacementGroupsType;
import edu.ucsb.eucalyptus.msgs.GetConsoleOutputResponseType;
import edu.ucsb.eucalyptus.msgs.GetConsoleOutputType;
import edu.ucsb.eucalyptus.msgs.GetPasswordDataResponseType;
import edu.ucsb.eucalyptus.msgs.GetPasswordDataType;
import edu.ucsb.eucalyptus.msgs.InstanceStatusItemType;
import edu.ucsb.eucalyptus.msgs.ModifyInstanceAttributeResponseType;
import edu.ucsb.eucalyptus.msgs.ModifyInstanceAttributeType;
import edu.ucsb.eucalyptus.msgs.MonitorInstanceState;
import edu.ucsb.eucalyptus.msgs.MonitorInstancesResponseType;
import edu.ucsb.eucalyptus.msgs.MonitorInstancesType;
import edu.ucsb.eucalyptus.msgs.RebootInstancesResponseType;
import edu.ucsb.eucalyptus.msgs.RebootInstancesType;
import edu.ucsb.eucalyptus.msgs.ReservationInfoType;
import edu.ucsb.eucalyptus.msgs.ResetInstanceAttributeResponseType;
import edu.ucsb.eucalyptus.msgs.ResetInstanceAttributeType;
import edu.ucsb.eucalyptus.msgs.ResourceTag;
import edu.ucsb.eucalyptus.msgs.RunInstancesResponseType;
import edu.ucsb.eucalyptus.msgs.RunInstancesType;
import edu.ucsb.eucalyptus.msgs.GroupItemType;
import edu.ucsb.eucalyptus.msgs.RunningInstancesItemType;
import edu.ucsb.eucalyptus.msgs.StartInstancesResponseType;
import edu.ucsb.eucalyptus.msgs.StartInstancesType;
import edu.ucsb.eucalyptus.msgs.StopInstancesResponseType;
import edu.ucsb.eucalyptus.msgs.StopInstancesType;
import edu.ucsb.eucalyptus.msgs.TerminateInstancesItemType;
import edu.ucsb.eucalyptus.msgs.TerminateInstancesResponseType;
import edu.ucsb.eucalyptus.msgs.TerminateInstancesType;
import edu.ucsb.eucalyptus.msgs.UnmonitorInstancesResponseType;
import edu.ucsb.eucalyptus.msgs.UnmonitorInstancesType;
import edu.ucsb.eucalyptus.msgs.InstanceBlockDeviceMapping;

public class VmControl {

    private static Logger LOG = Logger.getLogger(VmControl.class);

    public static RunInstancesResponseType runInstances(RunInstancesType request) throws Exception {
        RunInstancesResponseType reply = request.getReply();
        Allocation allocInfo = Allocations.run(request);
        final EntityTransaction db = Entities.get(VmInstance.class);
        try {
            if (!Strings.isNullOrEmpty(allocInfo.getClientToken())) {
                final List<VmInstance> instances = VmInstances.listByClientToken(
                        allocInfo.getOwnerFullName().asAccountFullName(), allocInfo.getClientToken(),
                        RestrictedTypes.filterPrivileged());
                if (!instances.isEmpty()) {
                    final VmInstance vm = instances.get(0);
                    final ReservationInfoType reservationInfoType = TypeMappers.transform(vm,
                            ReservationInfoType.class);
                    for (final VmInstance instance : instances) {
                        reservationInfoType.getInstancesSet().add(VmInstances.transform(instance));
                    }
                    reply.setRsvInfo(reservationInfoType);
                    return reply;
                }
            }

            Predicates.and(VerifyMetadata.get(), AdmissionControl.run(), ContractEnforcement.run())
                    .apply(allocInfo);
            allocInfo.commit();

            ReservationInfoType reservation = new ReservationInfoType(allocInfo.getReservationId(),
                    allocInfo.getOwnerFullName().getAccountNumber(),
                    Collections2.transform(allocInfo.getNetworkGroups(),
                            TypeMappers.lookup(NetworkGroup.class, GroupItemType.class)));

            reply.setRsvInfo(reservation);
            for (ResourceToken allocToken : allocInfo.getAllocationTokens()) {
                VmInstance entity = Entities.merge(allocToken.getVmInstance());
                reservation.getInstancesSet().add(VmInstances.transform(entity));
            }
            db.commit();
        } catch (Exception ex) {
            allocInfo.abort();
            final ImageInstanceTypeVerificationException e1 = Exceptions.findCause(ex,
                    ImageInstanceTypeVerificationException.class);
            if (e1 != null)
                throw new ClientComputeException("InvalidParameterCombination", e1.getMessage());
            final NotEnoughResourcesException e2 = Exceptions.findCause(ex, NotEnoughResourcesException.class);
            if (e2 != null)
                throw new ComputeException("InsufficientInstanceCapacity", e2.getMessage());
            final NoSuchKeyMetadataException e3 = Exceptions.findCause(ex, NoSuchKeyMetadataException.class);
            if (e3 != null)
                throw new ClientComputeException("InvalidKeyPair.NotFound", e3.getMessage());
            final InvalidMetadataException e4 = Exceptions.findCause(ex, InvalidMetadataException.class);
            if (e4 != null)
                throw new ClientComputeException("InvalidParameterValue", e4.getMessage());
            final NoSuchImageIdException e5 = Exceptions.findCause(ex, NoSuchImageIdException.class);
            if (e5 != null)
                throw new ClientComputeException("InvalidAMIID.NotFound", e5.getMessage());
            LOG.error(ex, ex);
            throw ex;
        } finally {
            if (db.isActive())
                db.rollback();
        }
        ClusterAllocator.get().apply(allocInfo);
        return reply;
    }

    public DescribeInstancesResponseType describeInstances(final DescribeInstancesType msg)
            throws EucalyptusCloudException {
        final DescribeInstancesResponseType reply = (DescribeInstancesResponseType) msg.getReply();
        Context ctx = Contexts.lookup();
        boolean showAll = msg.getInstancesSet().remove("verbose");
        final Multimap<String, RunningInstancesItemType> instanceMap = TreeMultimap.create();
        final Map<String, ReservationInfoType> reservations = Maps.newHashMap();
        final Collection<String> identifiers = normalizeIdentifiers(msg.getInstancesSet());
        final Filter filter = Filters.generateFor(msg.getFilterSet(), VmInstance.class)
                .withOptionalInternalFilter("instance-id", identifiers).generate();
        final Predicate<? super VmInstance> requestedAndAccessible = CloudMetadatas.filteringFor(VmInstance.class)
                .byId(identifiers) // filters without wildcard support
                .byPredicate(filter.asPredicate()).byPrivileges().buildPredicate();
        final Criterion criterion = filter
                .asCriterionWithConjunction(Restrictions.not(VmInstances.criterion(VmState.BURIED)));
        final OwnerFullName ownerFullName = (ctx.isAdministrator() && showAll) ? null
                : ctx.getUserFullName().asAccountFullName();
        try (final TransactionResource db = Entities.transactionFor(VmInstance.class)) {
            final List<VmInstance> instances = VmInstances.list(ownerFullName, criterion, filter.getAliases(),
                    requestedAndAccessible);
            final Map<String, List<Tag>> tagsMap = TagSupport.forResourceClass(VmInstance.class).getResourceTagMap(
                    AccountFullName.getInstance(ctx.getAccount()),
                    Iterables.transform(instances, CloudMetadatas.toDisplayName()));

            for (final VmInstance vm : instances) {
                if (instanceMap.put(vm.getReservationId(), VmInstances.transform(vm))
                        && !reservations.containsKey(vm.getReservationId())) {
                    reservations.put(vm.getReservationId(), TypeMappers.transform(vm, ReservationInfoType.class));
                }
            }
            List<ReservationInfoType> replyReservations = reply.getReservationSet();
            for (ReservationInfoType r : reservations.values()) {
                Collection<RunningInstancesItemType> instanceSet = instanceMap.get(r.getReservationId());
                if (!instanceSet.isEmpty()) {
                    for (final RunningInstancesItemType instancesItemType : instanceSet) {
                        Tags.addFromTags(instancesItemType.getTagSet(), ResourceTag.class,
                                tagsMap.get(instancesItemType.getInstanceId()));
                    }
                    r.getInstancesSet().addAll(instanceSet);
                    replyReservations.add(r);
                }
            }
        } catch (final Exception e) {
            LOG.error(e);
            LOG.debug(e, e);
            throw new EucalyptusCloudException(e.getMessage());
        }
        return reply;
    }

    public DescribeInstanceStatusResponseType describeInstanceStatus(final DescribeInstanceStatusType msg)
            throws EucalyptusCloudException {
        final DescribeInstanceStatusResponseType reply = (DescribeInstanceStatusResponseType) msg.getReply();
        final Context ctx = Contexts.lookup();
        final boolean showAll = msg.getInstancesSet().remove("verbose");
        final boolean includeAllInstances = Objects.firstNonNull(msg.getIncludeAllInstances(), Boolean.FALSE);
        final Collection<String> identifiers = normalizeIdentifiers(msg.getInstancesSet());
        final Filter filter = Filters.generateFor(msg.getFilterSet(), VmInstance.class, "status")
                .withOptionalInternalFilter("instance-id", identifiers).generate();
        final Predicate<? super VmInstance> requestedAndAccessible = CloudMetadatas.filteringFor(VmInstance.class)
                .byId(identifiers) // filters without wildcard support
                .byPredicate(includeAllInstances ? Predicates.<VmInstance>alwaysTrue() : VmState.RUNNING)
                .byPredicate(filter.asPredicate()).byPrivileges().buildPredicate();
        final Criterion criterion = filter
                .asCriterionWithConjunction(Restrictions.not(VmInstances.criterion(VmState.BURIED)));
        final OwnerFullName ownerFullName = (ctx.isAdministrator() && showAll) ? null
                : ctx.getUserFullName().asAccountFullName();
        try {
            final List<VmInstance> instances = VmInstances.list(ownerFullName, criterion, filter.getAliases(),
                    requestedAndAccessible);

            Iterables.addAll(reply.getInstanceStatusSet().getItem(), Iterables.transform(instances,
                    TypeMappers.lookup(VmInstance.class, InstanceStatusItemType.class)));

        } catch (final Exception e) {
            LOG.error(e);
            LOG.debug(e, e);
            throw new EucalyptusCloudException(e.getMessage());
        }
        return reply;
    }

    public TerminateInstancesResponseType terminateInstances(final TerminateInstancesType request)
            throws EucalyptusCloudException {
        final TerminateInstancesResponseType reply = request.getReply();
        final List<String> failedVmList = new ArrayList<String>();
        final List<VmInstance> vmList = new ArrayList<VmInstance>();
        final Collection<String> identifiers = normalizeIdentifiers(request.getInstancesSet());
        try {
            for (String requestedInstanceId : identifiers) {
                try {
                    VmInstance vm = RestrictedTypes.doPrivileged(requestedInstanceId, VmInstance.class);
                    vmList.add(vm);
                } catch (final Exception e) {
                    LOG.debug(e);
                    LOG.debug("Ignoring terminate request for non-existant instance: " + requestedInstanceId);
                    failedVmList.add(requestedInstanceId);
                }
            }
            if (!failedVmList.isEmpty()) {
                throw new NoSuchElementException("InvalidInstanceID.NotFound");
            }
            final List<TerminateInstancesItemType> results = reply.getInstancesSet();
            Function<VmInstance, TerminateInstancesItemType> terminateFunction = new Function<VmInstance, TerminateInstancesItemType>() {
                @Override
                public TerminateInstancesItemType apply(final VmInstance vm) {
                    String oldState = null, newState = null;
                    int oldCode = 0, newCode = 0;
                    TerminateInstancesItemType result = null;
                    try {
                        if (MigrationState.isMigrating(vm)) {
                            throw Exceptions
                                    .toUndeclared("Cannot terminate an instance which is currently migrating: "
                                            + vm.getInstanceId() + " " + vm.getMigrationTask());
                        }
                        oldCode = vm.getState().getCode();
                        oldState = vm.getState().getName();
                        if (VmState.STOPPED.apply(vm)) {
                            newCode = VmState.TERMINATED.getCode();
                            newState = VmState.TERMINATED.getName();
                            VmInstances.terminated(vm);
                        } else if (VmStateSet.RUN.apply(vm)) {
                            newCode = VmState.SHUTTING_DOWN.getCode();
                            newState = VmState.SHUTTING_DOWN.getName();
                            VmInstances.shutDown(vm);
                        } else if (VmState.SHUTTING_DOWN.apply(vm)) {
                            newCode = VmState.SHUTTING_DOWN.getCode();
                            newState = VmState.SHUTTING_DOWN.getName();
                        } else if (VmStateSet.DONE.apply(vm)) {
                            oldCode = newCode = VmState.TERMINATED.getCode();
                            oldState = newState = VmState.TERMINATED.getName();
                            VmInstances.delete(vm);
                        }
                        result = new TerminateInstancesItemType(vm.getInstanceId(), oldCode, oldState, newCode,
                                newState);
                    } catch (final TerminatedInstanceException e) {
                        oldCode = newCode = VmState.TERMINATED.getCode();
                        oldState = newState = VmState.TERMINATED.getName();
                        VmInstances.delete(vm.getInstanceId());
                        result = new TerminateInstancesItemType(vm.getInstanceId(), oldCode, oldState, newCode,
                                newState);
                    } catch (final NoSuchElementException e) {
                        LOG.debug("Ignoring terminate request for non-existant instance: " + vm.getInstanceId());
                    } catch (final Exception e) {
                        throw Exceptions.toUndeclared(e);
                    }
                    return result;
                }
            };
            Function<VmInstance, TerminateInstancesItemType> terminateTx = Entities.asTransaction(VmInstance.class,
                    terminateFunction, VmInstances.TX_RETRIES);
            for (VmInstance vm : vmList) {
                try {
                    TerminateInstancesItemType termInstance = terminateTx.apply(vm);
                    if (termInstance != null) {
                        results.add(termInstance);
                    }
                } catch (Exception ex) {
                    LOG.error(ex);
                    Logs.extreme().error(ex, ex);
                }
            }
            reply.set_return(!reply.getInstancesSet().isEmpty());
            return reply;
        } catch (final Throwable e) {
            LOG.error(e);
            LOG.debug(e, e);
            if (Exceptions.isCausedBy(e, NoSuchElementException.class)) {
                if (failedVmList.size() > 1)
                    throw new ClientComputeException("InvalidInstanceID.NotFound",
                            "The instance IDs '" + Joiner.on(", ").join(failedVmList) + "' do not exist");
                else
                    throw new ClientComputeException("InvalidInstanceID.NotFound",
                            "The instance ID '" + Joiner.on(", ").join(failedVmList) + "' does not exist");
            }
            throw new EucalyptusCloudException(e.getMessage());
        }
    }

    public RebootInstancesResponseType rebootInstances(final RebootInstancesType request)
            throws EucalyptusCloudException {
        final RebootInstancesResponseType reply = (RebootInstancesResponseType) request.getReply();
        try {
            List<String> instanceSet = normalizeIdentifiers(request.getInstancesSet());
            ArrayList<String> noAccess = new ArrayList<String>();
            ArrayList<String> migrating = new ArrayList<String>();
            ArrayList<String> noSuchElement = new ArrayList<String>();
            for (int i = 0; i < instanceSet.size(); i++) {
                String currentInstance = instanceSet.get(i);
                try {
                    final VmInstance v = VmInstances.lookup(currentInstance);
                    if (!RestrictedTypes.filterPrivileged().apply(v)) {
                        noAccess.add(currentInstance);
                    }
                    if (MigrationState.isMigrating(v)) {
                        migrating.add(currentInstance);
                    }
                } catch (NoSuchElementException nse) {
                    if (!(nse instanceof TerminatedInstanceException)) {
                        noSuchElement.add(currentInstance);
                    } else {
                        instanceSet.remove(i--);
                    }
                }
                if ((i == instanceSet.size() - 1) && (!noSuchElement.isEmpty())) {
                    String outList = noSuchElement.toString();
                    throw new EucalyptusCloudException(
                            "No such instance(s): " + outList.substring(1, outList.length() - 1));
                } else if ((i == instanceSet.size() - 1) && (!noAccess.isEmpty())) {
                    String outList = noAccess.toString();
                    throw new EucalyptusCloudException(
                            "Permission denied for vm(s): " + outList.substring(1, outList.length() - 1));
                } else if ((i == instanceSet.size() - 1) && (!migrating.isEmpty())) {
                    String outList = noAccess.toString();
                    throw new EucalyptusCloudException("Cannot reboot an instances which is currently migrating: "
                            + outList.substring(1, outList.length() - 1));
                }
            }
            final boolean result = Iterables.all(instanceSet, new Predicate<String>() {
                @Override
                public boolean apply(final String instanceId) {
                    try {
                        final VmInstance v = VmInstances.lookup(instanceId);
                        final Request<RebootInstancesType, RebootInstancesResponseType> req = AsyncRequests
                                .newRequest(new RebootCallback(v.getInstanceId()));
                        req.getRequest().regarding(request);
                        ServiceConfiguration ccConfig = Topology.lookup(ClusterController.class,
                                v.lookupPartition());
                        req.dispatch(ccConfig);
                        return true;
                    } catch (final NoSuchElementException e) {
                        return false;
                    }
                }
            });
            reply.set_return(result);
            return reply;
        } catch (final Exception e) {
            LOG.error(e);
            LOG.debug(e, e);
            throw new EucalyptusCloudException(e.getMessage());
        }
    }

    public GetConsoleOutputResponseType getConsoleOutput(final GetConsoleOutputType request)
            throws EucalyptusCloudException {
        final String instanceId = normalizeIdentifier(request.getInstanceId());
        VmInstance v;
        try {
            v = VmInstances.lookup(instanceId);
        } catch (final NoSuchElementException ex) {
            throw new ClientComputeException("InvalidInstanceID.NotFound",
                    "The instance ID '" + instanceId + "' does not exist");
        }
        if (!RestrictedTypes.filterPrivileged().apply(v)) {
            throw new EucalyptusCloudException("Permission denied for vm: " + instanceId);
        } else if (!VmState.RUNNING.apply(v)) {
            throw new EucalyptusCloudException("Instance " + instanceId + " is not in a running state.");
        } else {
            Cluster cluster;
            try {
                ServiceConfiguration ccConfig = Topology.lookup(ClusterController.class, v.lookupPartition());
                cluster = Clusters.lookup(ccConfig);
            } catch (final NoSuchElementException e1) {
                throw new EucalyptusCloudException(
                        "Failed to find cluster info for '" + v.getPartition() + "' related to vm: " + instanceId);
            }
            try {
                final GetConsoleOutputResponseType response = AsyncRequests.sendSync(cluster.getConfiguration(),
                        new GetConsoleOutputType(instanceId));
                GetConsoleOutputResponseType reply = request.getReply();
                reply.setInstanceId(instanceId);
                reply.setTimestamp(response.getTimestamp());
                reply.setOutput(response.getOutput());
                return reply;
            } catch (Exception e) {
                LOG.error(e, e);
                throw new ComputeException("InternalError", "Error processing request: " + e.getMessage());
            }
        }
    }

    public DescribeBundleTasksResponseType describeBundleTasks(final DescribeBundleTasksType request)
            throws EucalyptusCloudException {
        final DescribeBundleTasksResponseType reply = request.getReply();

        final Filter filter = Filters.generate(request.getFilterSet(), VmBundleTask.class);
        final EntityTransaction db = Entities.get(VmInstance.class);
        try {

            // Get all from cache that match filters......
            final Predicate<? super VmBundleTask> filteredAndBundling = Predicates.and(filter.asPredicate(),
                    VmBundleTask.Filters.BUNDLING);
            Collection<VmBundleTask> cachedValues = Bundles.getPreviousBundleTasks().values();
            final Map<String, VmBundleTask> cachedBundles = buildMap(
                    Collections2.filter(cachedValues, filteredAndBundling));
            final Predicate<? super VmInstance> requestedAndAccessible = CloudMetadatas
                    .filteringFor(VmInstance.class).byId(toInstanceIds(request.getBundleIds())).byPrivileges()
                    .buildPredicate();
            // Get all from the db that are owned

            final Predicate<? super VmInstance> filteredInstances = Predicates.compose(filter.asPredicate(),
                    VmInstances.bundleTask());
            final Filter noFilters = Filters.generate(new ArrayList<edu.ucsb.eucalyptus.msgs.Filter>(),
                    VmBundleTask.class);
            final Collection<VmInstance> dbBundles = VmInstances.list(null, noFilters.asCriterion(),
                    noFilters.getAliases(), requestedAndAccessible);
            for (final VmInstance v : dbBundles) {

                if (filteredInstances.apply(v) && VmInstance.Filters.BUNDLING.apply(v)) {
                    LOG.debug("Getting current bundle for " + v.getInstanceId());
                    reply.getBundleTasks().add(Bundles.transform(v.getRuntimeState().getBundleTask()));
                } else {
                    if (!VmInstance.Filters.BUNDLING.apply(v) && cachedBundles.containsKey(v.getInstanceId())) {
                        LOG.debug("Getting previous bundle for " + v.getInstanceId());
                        reply.getBundleTasks().add(Bundles.transform(cachedBundles.get(v.getInstanceId())));
                    }
                }
            }
        } catch (Exception ex) {
            Logs.exhaust().error(ex, ex);
            throw new EucalyptusCloudException(ex);
        } finally {
            db.rollback();
        }
        return reply;
    }

    private static Map<String, VmBundleTask> buildMap(Collection<VmBundleTask> tasks) {
        Map<String, VmBundleTask> map = Maps.newHashMap();
        for (VmBundleTask task : tasks) {
            map.put(task.getInstanceId(), task);
        }
        return map;
    }

    public UnmonitorInstancesResponseType unmonitorInstances(final UnmonitorInstancesType request)
            throws EucalyptusCloudException {
        final UnmonitorInstancesResponseType reply = request.getReply();
        final List<String> instanceSet = normalizeIdentifiers(request.getInstancesSet());
        final List<MonitorInstanceState> monitorFalseList = Lists.newArrayList();

        for (final String inst : instanceSet) {
            final MonitorInstanceState monitorInstanceState = new MonitorInstanceState();
            monitorInstanceState.setInstanceId(inst);
            monitorInstanceState.setMonitoringState("disabled");
            monitorFalseList.add(monitorInstanceState);
        }

        reply.setInstancesSet(SetMonitorFunction.INSTANCE.apply(monitorFalseList));
        return reply;
    }

    public StartInstancesResponseType startInstances(final StartInstancesType request) throws Exception {
        final StartInstancesResponseType reply = request.getReply();
        for (String instanceId : normalizeIdentifiers(request.getInstancesSet())) {
            final EntityTransaction db = Entities.get(VmInstance.class);
            try {//scope for transaction
                final VmInstance vm = RestrictedTypes.doPrivileged(instanceId, VmInstance.class);
                if (VmState.STOPPED.equals(vm.getState())) {
                    Allocation allocInfo = Allocations.start(vm);
                    VmInstanceLifecycleHelpers.get().prepareAllocation(vm, allocInfo);
                    try {//scope for allocInfo
                        AdmissionControl.run().apply(allocInfo);
                        for (final ResourceToken resourceToken : allocInfo.getAllocationTokens()) {
                            VmInstanceLifecycleHelpers.get().startVmInstance(resourceToken, vm);
                        }
                        final int oldCode = vm.getState().getCode();
                        final int newCode = VmState.PENDING.getCode();
                        final String oldState = vm.getState().getName();
                        final String newState = VmState.PENDING.getName();
                        vm.setState(VmState.PENDING);
                        db.commit();
                        ClusterAllocator.get().apply(allocInfo);
                        reply.getInstancesSet().add(new TerminateInstancesItemType(vm.getInstanceId(), oldCode,
                                oldState, newCode, newState));
                    } catch (Exception ex) {
                        db.rollback();
                        allocInfo.abort();
                        throw ex;
                    }
                }
            } catch (Exception ex1) {
                LOG.trace(ex1, ex1);
                throw ex1;
            } finally {
                if (db.isActive())
                    db.rollback();
            }
        }
        return reply;
    }

    public StopInstancesResponseType stopInstances(final StopInstancesType request)
            throws EucalyptusCloudException {
        final StopInstancesResponseType reply = request.getReply();
        try {
            final Context ctx = Contexts.lookup();
            final List<TerminateInstancesItemType> results = reply.getInstancesSet();
            Predicate<String> stopPredicate = new Predicate<String>() {
                @Override
                public boolean apply(final String instanceId) {
                    try {
                        final VmInstance v = VmInstances.lookup(instanceId);
                        if (RestrictedTypes.filterPrivileged().apply(v)) {
                            if (!MigrationState.isMigrating(v)
                                    && v.getBootRecord().getMachine() instanceof BlockStorageImageInfo) {
                                final int oldCode = v.getState().getCode(), newCode = VmState.STOPPING.getCode();
                                final String oldState = v.getState().getName(),
                                        newState = VmState.STOPPING.getName();
                                TerminateInstancesItemType termInfo = new TerminateInstancesItemType(
                                        v.getInstanceId(), oldCode, oldState, newCode, newState);
                                if (!results.contains(termInfo)) {
                                    results.add(termInfo);
                                }
                                VmInstances.stopped(v);
                            }
                        }
                        return true;//GRZE: noop needs to be true to continue Iterables.all
                    } catch (final NoSuchElementException e) {
                        try {
                            VmInstances.stopped(instanceId);
                            return true;
                        } catch (final NoSuchElementException e1) {
                            return true;
                        } catch (TransactionException ex) {
                            Logs.extreme().error(ex, ex);
                            return true;
                        }
                    } catch (Exception ex) {
                        LOG.error(ex);
                        Logs.extreme().error(ex, ex);
                        throw Exceptions.toUndeclared(ex);
                    }
                }
            };

            final List<String> identifiers = normalizeIdentifiers(request.getInstancesSet());
            for (final String instanceId : identifiers) {
                try {
                    final VmInstance vm = VmInstances.lookup(instanceId);
                    if (!vm.isBlockStorage())
                        throw new ClientComputeException("UnsupportedOperation", String.format(
                                "The instance '%s' does not have an 'ebs' root device type and cannot be stopped.",
                                instanceId));
                } catch (final TerminatedInstanceException ex) {
                    throw new ClientComputeException("IncorrectInstanceState", String.format(
                            "This instance '%s' is not in a state from which it can be stopped.", instanceId));
                } catch (final NoSuchElementException ex) {
                    throw new ClientComputeException("InvalidInstanceID.NotFound",
                            String.format("The instance ID '%s' does not exist", instanceId));
                } catch (final EucalyptusCloudException ex) {
                    throw ex;
                }
            }

            Predicate<String> stopTx = Entities.asTransaction(VmInstance.class, stopPredicate);
            Iterables.all(identifiers, stopTx);
            reply.set_return(!reply.getInstancesSet().isEmpty());
            return reply;
        } catch (final EucalyptusCloudException ex) {
            throw ex;
        } catch (final Throwable e) {
            LOG.error(e);
            LOG.debug(e, e);
            throw new EucalyptusCloudException(e.getMessage());
        }
    }

    public ResetInstanceAttributeResponseType resetInstanceAttribute(final ResetInstanceAttributeType request)
            throws EucalyptusCloudException {
        final ResetInstanceAttributeResponseType reply = request.getReply();
        final String instanceId = normalizeIdentifier(request.getInstanceId());

        final EntityTransaction tx = Entities.get(VmInstance.class);
        try {
            final VmInstance vm = RestrictedTypes.doPrivileged(instanceId, VmInstance.class);
            if (VmState.STOPPED.equals(vm.getState())) {
                if (request.getAttribute().equals("kernel")) {
                    String kernelId = vm.getKernelId();
                    if (kernelId == null) {
                        vm.getBootRecord().setKernel();
                    } else {
                        KernelImageInfo kernelImg = Images.lookupKernel(kernelId);
                        if (!ImageMetadata.State.available.equals(kernelImg.getState())) {
                            throw new NoSuchElementException(
                                    "InvalidAMIID.NotFound: Unable to start instance with deregistered/failed image : "
                                            + kernelImg.getImageName());
                        }
                        vm.getBootRecord().setKernel(kernelImg);
                    }
                    Entities.merge(vm);
                    tx.commit();
                } else if (request.getAttribute().equals("ramdisk")) {
                    String ramdiskId = vm.getRamdiskId();
                    if (ramdiskId == null) {
                        vm.getBootRecord().setRamdisk();
                    } else {
                        RamdiskImageInfo ramdiskImg = Images.lookupRamdisk(ramdiskId);
                        if (!ImageMetadata.State.available.equals(ramdiskImg.getState())) {
                            throw new NoSuchElementException(
                                    "InvalidAMIID.NotFound: Unable to start instance with deregistered/failed image : "
                                            + ramdiskImg.getImageName());
                        }
                        vm.getBootRecord().setRamdisk(ramdiskImg);
                    }
                    Entities.merge(vm);
                    tx.commit();
                } else {
                    // SourceDestCheck not implemented
                }
                reply.set_return(true);
            } else {
                throw new EucalyptusCloudException(
                        "IncorrectInstanceState: The instance '" + instanceId + "' is not in the 'stopped' state.");
            }
        } catch (Exception ex) {
            LOG.error(ex);
            if (Exceptions.isCausedBy(ex, EucalyptusCloudException.class)) {
                throw new ClientComputeException("IncorrectInstanceState",
                        "The instance '" + instanceId + "' is not in the 'stopped' state.");
            } else if (Exceptions.isCausedBy(ex, NoSuchElementException.class)
                    && ex.toString().contains("InvalidAMIID.NotFound")) {
                throw new ClientComputeException("InvalidAMIID.NotFound",
                        "The default " + request.getAttribute() + " does not exist");
            }
            throw new ClientComputeException("InvalidInstanceID.NotFound",
                    "The instance ID '" + instanceId + "' does not exist");
        } finally {
            if (tx.isActive())
                tx.rollback();
        }
        return reply;
    }

    public MonitorInstancesResponseType monitorInstances(final MonitorInstancesType request)
            throws EucalyptusCloudException {
        final MonitorInstancesResponseType reply = request.getReply();
        final List<String> instanceSet = normalizeIdentifiers(request.getInstancesSet());
        final List<MonitorInstanceState> monitorTrueList = Lists.newArrayList();

        for (final String inst : instanceSet) {
            final MonitorInstanceState monitorInstanceState = new MonitorInstanceState();
            monitorInstanceState.setInstanceId(inst);
            monitorInstanceState.setMonitoringState("enabled");
            monitorTrueList.add(monitorInstanceState);
        }

        reply.setInstancesSet(SetMonitorFunction.INSTANCE.apply(monitorTrueList));
        return reply;
    }

    private enum SetMonitorFunction
            implements Function<List<MonitorInstanceState>, ArrayList<MonitorInstanceState>> {
        INSTANCE;

        @Override
        public ArrayList<MonitorInstanceState> apply(final List<MonitorInstanceState> monitorList) {

            ArrayList<MonitorInstanceState> monitorInstanceSet = Lists.newArrayList();

            for (final MonitorInstanceState monitorInst : monitorList) {

                final EntityTransaction db = Entities.get(VmInstance.class);

                try {

                    VmInstance vmInst = VmInstances.lookup(monitorInst.getInstanceId());

                    if (RestrictedTypes.filterPrivileged().apply(vmInst)) {
                        vmInst.getBootRecord().setMonitoring(
                                monitorInst.getMonitoringState().equals("enabled") ? Boolean.TRUE : Boolean.FALSE);
                        Entities.merge(vmInst);
                        monitorInstanceSet.add(monitorInst);
                        db.commit();
                    }

                } catch (NoSuchElementException nse) {
                    LOG.debug("Unable to find instance : " + monitorInst.getInstanceId());
                } catch (Exception ex) {
                    LOG.debug("Unable to set monitoring state for instance : " + monitorInst.getInstanceId());
                } finally {
                    if (db.isActive())
                        db.rollback();
                }
            }

            return monitorInstanceSet;
        }

    }

    public ModifyInstanceAttributeResponseType modifyInstanceAttribute(final ModifyInstanceAttributeType request)
            throws EucalyptusCloudException, NoSuchMetadataException {
        final ModifyInstanceAttributeResponseType reply = request.getReply();
        final String instanceId = normalizeIdentifier(request.getInstanceId());
        Context ctx = Contexts.lookup();

        try (final TransactionResource tx = Entities.transactionFor(VmInstance.class)) {
            final VmInstance vm;
            try {
                vm = RestrictedTypes.doPrivileged(instanceId, VmInstance.class);
            } catch (AuthException | NoSuchElementException e) {
                throw new ClientComputeException("InvalidInstanceID.NotFound",
                        "The instance ID '" + instanceId + "' does not exist");
            }

            if (request.getBlockDeviceMappingAttribute() != null) {
                boolean isValidBlockDevice = false;
                Set<VmVolumeAttachment> persistentVolumes = vm.getBootRecord().getPersistentVolumes();
                for (VmVolumeAttachment vmVolumeAttachment : persistentVolumes) {
                    if (vmVolumeAttachment.getDevice().equals(request.getBlockDeviceMappingDeviceName())) {
                        // NOTE: AWS looks for a valid device name with any valid volume Id.
                        // Invalid volume Id results an InvalidVolumeID.Malformed.
                        // Current implementation for this negative use case is to throw InvalidVolumeID.Malformed exception
                        // when user is not allowed to access the requested volume
                        try {
                            Volume volume = Volumes.lookup(ctx.getUserFullName().asAccountFullName(),
                                    request.getBlockDeviceMappingVolumeId());
                        } catch (Exception e) {
                            throw new NoSuchElementException("InvalidVolumeID.Malformed: '"
                                    + request.getBlockDeviceMappingVolumeId() + "' does not exist or "
                                    + ctx.getUserFullName() + " is now allowed to access this volume.");
                        }
                        isValidBlockDevice = true;
                        vmVolumeAttachment.setDeleteOnTerminate(request.getBlockDeviceMappingDeleteOnTermination());
                        break;
                    }
                }
                if (!isValidBlockDevice)
                    throw new NoSuchElementException("NoSuchBlockDevice: " + "No device is currently mapped at "
                            + request.getBlockDeviceMappingDeviceName());
                Entities.merge(vm);
                tx.commit();
            } else {
                if (!VmState.STOPPED.equals(vm.getState())) {
                    throw new EucalyptusCloudException("IncorrectInstanceState: " + "The instance '" + instanceId
                            + "' is not in the 'stopped' state.");
                }
                if (request.getInstanceTypeValue() != null) {
                    VmType vmType = VmTypes.lookup(request.getInstanceTypeValue()); // throws NoSuchMetadataException
                    if (!RestrictedTypes.filterPrivileged().apply(vmType)) {
                        throw new IllegalAccessException(
                                "Not authorized to allocate vm type " + vmType + " for " + ctx.getUserFullName());
                    }
                    vm.getBootRecord().setVmType(vmType);
                    Entities.merge(vm);
                    tx.commit();
                } else if (request.getKernelValue() != null) {
                    try {
                        final KernelImageInfo kernelImg = Images.lookupKernel(request.getKernelValue());
                        if (Images.FilterPermissions.INSTANCE.apply(kernelImg)
                                && ImageMetadata.State.available.equals(kernelImg.getState())) {
                            if (!RestrictedTypes.filterPrivilegedWithoutOwner().apply(kernelImg))
                                throw new IllegalAccessException("Not authorize to use image " + kernelImg.getName()
                                        + " for ModifyInstanceAttribute");
                            vm.getBootRecord().setKernel(kernelImg);
                            Entities.merge(vm);
                            tx.commit();
                        } else {
                            throw new NoSuchElementException("InvalidAMIID.NotFound: " + "The image id '["
                                    + request.getKernelValue() + "]' does not exist");
                        }
                    } catch (Exception e) {
                        throw e;
                    }
                } else if (request.getRamdiskValue() != null) {
                    try {
                        final RamdiskImageInfo ramdiskImg = Images.lookupRamdisk(request.getRamdiskValue());
                        if (Images.FilterPermissions.INSTANCE.apply(ramdiskImg)
                                && ImageMetadata.State.available.equals(ramdiskImg.getState())) {
                            if (!RestrictedTypes.filterPrivilegedWithoutOwner().apply(ramdiskImg))
                                throw new IllegalAccessException("Not authorize to use image "
                                        + ramdiskImg.getName() + " for ModifyInstanceAttribute");
                            vm.getBootRecord().setRamdisk(ramdiskImg);
                            Entities.merge(vm);
                            tx.commit();
                        } else {
                            throw new NoSuchElementException("InvalidAMIID.NotFound: " + "The image id '["
                                    + request.getRamdiskValue() + "]' does not exist");
                        }
                    } catch (Exception e) {
                        throw e;
                    }
                } else if (request.getUserDataValue() != null) {
                    final byte[] userData;
                    try {
                        userData = B64.standard.dec(request.getUserDataValue());
                    } catch (ArrayIndexOutOfBoundsException | StringIndexOutOfBoundsException
                            | DecoderException e) {
                        throw new ClientComputeException("InvalidParameterValue", "User data decoding error.");
                    }
                    if (userData.length > Integer.parseInt(VmInstances.USER_DATA_MAX_SIZE_KB) * 1024) {
                        throw new InvalidMetadataException(
                                "User data may not exceed " + VmInstances.USER_DATA_MAX_SIZE_KB + " KB");
                    }
                    vm.getBootRecord().setUserData(userData);
                    Entities.merge(vm);
                    tx.commit();
                } else {
                    // InstanceInitiatedShutdownBehavior, SourceDestCheck, GroupId [EC2-VPC], EbsOptimized are not supported yet.
                }
            }
            reply.set_return(true);
        } catch (final ComputeException e) {
            throw e;
        } catch (Exception ex) {
            if (Exceptions.isCausedBy(ex, EucalyptusCloudException.class)) {
                throw new ClientComputeException("IncorrectInstanceState",
                        "The instance '" + instanceId + "' is not in the 'stopped' state.");
            } else if (Exceptions.isCausedBy(ex, NoSuchMetadataException.class)) {
                throw new ClientComputeException("InvalidInstanceAttributeValue",
                        "The instanceType '" + request.getInstanceTypeValue() + "' is invalid.");
            } else if (Exceptions.isCausedBy(ex, IllegalAccessException.class)) {
                throw new ClientComputeException("UnauthorizedOperation",
                        "You are not authorized to perform this operation.");
            } else if (Exceptions.isCausedBy(ex, NoSuchElementException.class)) {
                if (ex.toString().contains("InvalidAMIID.NotFound")) {
                    String imageId = (request.getKernelValue() != null) ? request.getKernelValue()
                            : request.getRamdiskValue();
                    throw new ClientComputeException("InvalidAMIID.NotFound",
                            "The image id '[" + imageId + "]' does not exist");
                } else if (ex.toString().contains("NoSuchBlockDevice")) {
                    throw new ClientComputeException("InvalidInstanceAttributeValue",
                            "No device is currently mapped at " + request.getBlockDeviceMappingDeviceName());
                } else if (ex.toString().contains("InvalidVolumeID.Malformed")) {
                    throw new ClientComputeException("InvalidVolumeID.Malformed",
                            "Invalid id: '" + request.getBlockDeviceMappingVolumeId() + "'");
                }
            } else if (Exceptions.isCausedBy(ex, InvalidMetadataException.class)) {
                throw new ClientComputeException("InvalidParameterValue", "User data is limited to 16384 bytes");
            }
            LOG.error(ex, ex);
            throw new ComputeException("InternalError", "Error processing request: " + ex.getMessage());
        }
        return reply;
    }

    public DescribePlacementGroupsResponseType describePlacementGroups(final DescribePlacementGroupsType request) {
        final DescribePlacementGroupsResponseType reply = request.getReply();
        return reply;
    }

    public DescribeInstanceAttributeResponseType describeInstanceAttribute(
            final DescribeInstanceAttributeType request) throws EucalyptusCloudException {
        final DescribeInstanceAttributeResponseType reply = request.getReply();
        final String instanceId = normalizeIdentifier(request.getInstanceId());
        reply.setInstanceId(instanceId);
        final EntityTransaction tx = Entities.get(VmInstance.class);
        try {
            final VmInstance vm = RestrictedTypes.doPrivileged(instanceId, VmInstance.class);
            if (request.getAttribute().equals("kernel")) {
                if (vm.getKernelId() != null) {
                    reply.getKernel().add(vm.getKernelId());
                }
            } else if (request.getAttribute().equals("ramdisk")) {
                if (vm.getRamdiskId() != null) {
                    reply.getRamdisk().add(vm.getRamdiskId());
                }
            } else if (request.getAttribute().equals("instanceType")) {
                if (vm.getBootRecord().getVmType().getDisplayName() != null) {
                    reply.getInstanceType().add(vm.getBootRecord().getVmType().getDisplayName());
                }
            } else if (request.getAttribute().equals("userData")) {
                if (vm.getUserData() != null) {
                    reply.getUserData().add(Base64.toBase64String(vm.getUserData()));
                }
            } else if (request.getAttribute().equals("rootDeviceName")) {
                if (vm.getBootRecord().getMachine() != null
                        && vm.getBootRecord().getMachine().getRootDeviceName() != null) {
                    reply.getRootDeviceName().add((vm.getBootRecord().getMachine().getRootDeviceName()));
                }
            } else if (request.getAttribute().equals("blockDeviceMapping")) {
                if (vm.getBootRecord().getMachine() instanceof BlockStorageImageInfo) {
                    BlockStorageImageInfo bfebsInfo = (BlockStorageImageInfo) vm.getBootRecord().getMachine();
                    Set<VmVolumeAttachment> persistentVolumes = vm.getBootRecord().getPersistentVolumes();
                    for (VmVolumeAttachment volumeAttachment : persistentVolumes) {
                        if (volumeAttachment.getIsRootDevice()) {
                            reply.getBlockDeviceMapping()
                                    .add(new InstanceBlockDeviceMapping(bfebsInfo.getRootDeviceName(),
                                            volumeAttachment.getVolumeId(), volumeAttachment.getStatus(),
                                            volumeAttachment.getAttachTime(),
                                            volumeAttachment.getDeleteOnTerminate()));
                        } else {
                            reply.getBlockDeviceMapping()
                                    .add(new InstanceBlockDeviceMapping(volumeAttachment.getDevice(),
                                            volumeAttachment.getVolumeId(), volumeAttachment.getStatus(),
                                            volumeAttachment.getAttachTime(),
                                            volumeAttachment.getDeleteOnTerminate()));
                        }
                    }
                }
            } else if (request.getAttribute().equals("groupSet")) {
                Set<NetworkGroupId> networkGroups = vm.getNetworkGroupIds();
                for (NetworkGroupId networkGroup : networkGroups) {
                    reply.getGroupSet()
                            .add(new GroupItemType(networkGroup.getGroupId(), networkGroup.getGroupName()));
                }
            } else {
                // disableApiTermination | ebsOptimized | instanceInitiatedShutdownBehavior | productCodes | sourceDestCheck
            }
        } catch (Exception ex) {
            LOG.error(ex);
            throw new ClientComputeException("InvalidInstanceID.NotFound",
                    "The instance ID '" + instanceId + "' does not exist");
        } finally {
            if (tx.isActive())
                tx.rollback();
        }
        return reply;
    }

    public DeletePlacementGroupResponseType deletePlacementGroup(final DeletePlacementGroupType request) {
        final DeletePlacementGroupResponseType reply = request.getReply();
        return reply;
    }

    public CreatePlacementGroupResponseType createPlacementGroup(final CreatePlacementGroupType request) {
        final CreatePlacementGroupResponseType reply = request.getReply();
        return reply;
    }

    public CancelBundleTaskResponseType cancelBundleTask(final CancelBundleTaskType request)
            throws EucalyptusCloudException {
        final CancelBundleTaskResponseType reply = request.getReply();
        reply.set_return(true);
        final Context ctx = Contexts.lookup();
        try {
            final VmInstance v = VmInstances.lookupByBundleId(normalizeBundleIdentifier(request.getBundleId()));
            BundleState bundleState = v.getRuntimeState().getBundleTaskState();
            if (!(bundleState == BundleState.pending || bundleState == BundleState.storing))
                throw new EucalyptusCloudException(
                        "Can't cancel bundle task when the bundle task is " + bundleState);

            if (RestrictedTypes.filterPrivileged().apply(v)) {
                v.getRuntimeState().updateBundleTaskState(BundleState.canceling);
                LOG.info(EventRecord.here(BundleCallback.class, EventType.BUNDLE_CANCELING,
                        ctx.getUserFullName().toString(), v.getRuntimeState().getBundleTask().getBundleId(),
                        v.getInstanceId()));

                ServiceConfiguration ccConfig = Topology.lookup(ClusterController.class, v.lookupPartition());
                final Cluster cluster = Clusters.lookup(ccConfig);

                request.setInstanceId(v.getInstanceId());
                reply.setTask(Bundles.transform(v.getRuntimeState().getBundleTask()));
                AsyncRequests.newRequest(Bundles.cancelCallback(request)).dispatch(cluster.getConfiguration());
                return reply;
            } else {
                throw new EucalyptusCloudException("Failed to find bundle task: " + request.getBundleId());
            }
        } catch (final NoSuchElementException e) {
            throw new EucalyptusCloudException("Failed to find bundle task: " + request.getBundleId());
        }
    }

    public BundleInstanceResponseType bundleInstance(final BundleInstanceType request)
            throws EucalyptusCloudException {
        final Context ctx = Contexts.lookup();
        final BundleInstanceResponseType reply = request.getReply();//TODO: check if the instance has platform windows.
        final String instanceId = normalizeIdentifier(request.getInstanceId());
        if (!validBucketName(request.getBucket())) {
            throw new ClientComputeException(" InvalidParameterValue",
                    "Value (" + request.getBucket() + ") for parameter Bucket is invalid.");
        } else if (!validBucketName(request.getPrefix())) {
            throw new ClientComputeException(" InvalidParameterValue",
                    "Value (" + request.getPrefix() + ") for parameter Prefix is invalid.");
        }

        Bundles.checkAndCreateBucket(ctx.getUser(), request.getBucket());
        Function<String, VmInstance> bundleFunc = new Function<String, VmInstance>() {

            @Override
            public VmInstance apply(String input) {
                reply.set_return(false);
                try {
                    final VmInstance v = RestrictedTypes.doPrivileged(input, VmInstance.class);
                    if (v.getRuntimeState().isBundling()) {
                        reply.setTask(Bundles.transform(v.getRuntimeState().getBundleTask()));
                        reply.markWinning();
                    } else if (!VmState.RUNNING.equals(v.getState())) {
                        throw new EucalyptusCloudException(
                                "Failed to bundle requested vm because it is not currently 'running': "
                                        + instanceId);
                    } else if (RestrictedTypes.filterPrivileged().apply(v)) {
                        final VmBundleTask bundleTask = Bundles.create(v, request.getBucket(), request.getPrefix(),
                                new String(Base64.decode(request.getUploadPolicy())));
                        if (v.getRuntimeState().startBundleTask(bundleTask)) {
                            reply.setTask(Bundles.transform(bundleTask));
                            reply.markWinning();
                        } else if (v.getRuntimeState().getBundleTask() == null) {
                            v.resetBundleTask();
                            if (v.getRuntimeState().startBundleTask(bundleTask)) {
                                reply.setTask(Bundles.transform(bundleTask));
                                reply.markWinning();
                            }
                        } else {
                            throw new EucalyptusCloudException("Instance is already being bundled: "
                                    + v.getRuntimeState().getBundleTask().getBundleId());
                        }
                        EventRecord
                                .here(VmControl.class, EventType.BUNDLE_PENDING, ctx.getUserFullName().toString(),
                                        v.getRuntimeState().getBundleTask().getBundleId(), v.getInstanceId())
                                .debug();
                    } else {
                        throw new EucalyptusCloudException("Failed to find instance: " + instanceId);
                    }
                    return v;
                } catch (Exception ex) {
                    LOG.error(ex);
                    Logs.extreme().error(ex, ex);
                    throw Exceptions.toUndeclared(ex);
                }
            }
        };

        final Function<String, AccessKey> LookupAccessKey = new Function<String, AccessKey>() {
            @Override
            public AccessKey apply(final String policySignature) {
                try {
                    final List<AccessKey> keys = ctx.getUser().getKeys();
                    AccessKey keyForSign = null;
                    final Mac hmac = Mac.getInstance("HmacSHA1");
                    for (final AccessKey key : keys) {
                        hmac.init(new SecretKeySpec(key.getSecretKey().getBytes("UTF-8"), "HmacSHA1"));
                        final String sig = B64.standard
                                .encString(hmac.doFinal(request.getUploadPolicy().getBytes("UTF-8")));
                        if (sig.equals(policySignature)) {
                            keyForSign = key;
                            break;
                        }
                    }
                    return keyForSign;
                } catch (final Exception ex) {
                    LOG.warn("Failed to generate upload policy signature", ex);
                    return null;
                }
            }
        };

        final AccessKey accessKeyForPolicySignature = LookupAccessKey.apply(request.getUploadPolicySignature());
        if (accessKeyForPolicySignature == null) {
            throw new ComputeException("InternalError",
                    "Error processing request: unable to find the access key signed the upload policy");
        }

        VmInstance bundledVm = Entities.asTransaction(VmInstance.class, bundleFunc).apply(instanceId);
        try {
            ServiceConfiguration cluster = Topology.lookup(ClusterController.class, bundledVm.lookupPartition());
            BundleInstanceType reqInternal = new BundleInstanceType() {
                {
                    setInstanceId(request.getInstanceId());
                    setBucket(request.getBucket());
                    setPrefix(request.getPrefix());
                    setAwsAccessKeyId(accessKeyForPolicySignature.getAccessKey());
                    setUploadPolicy(request.getUploadPolicy());
                    setUploadPolicySignature(request.getUploadPolicySignature());
                    setUrl(request.getUrl());
                    setUserKey(request.getUserKey());
                }
            }.regardingUserRequest(request);
            AsyncRequests.newRequest(Bundles.createCallback(reqInternal)).dispatch(cluster);
        } catch (Exception ex) {
            LOG.error(ex);
            Logs.extreme().error(ex, ex);
            throw Exceptions.toUndeclared(ex);
        }
        return reply;
    }

    public GetPasswordDataResponseType getPasswordData(final GetPasswordDataType request) throws Exception {
        final String instanceId = normalizeIdentifier(request.getInstanceId());
        final VmInstance v;
        try {
            v = VmInstances.lookup(instanceId);
        } catch (NoSuchElementException e) {
            throw new ClientComputeException("InvalidInstanceID.NotFound",
                    "The instance ID '" + instanceId + "' does not exist");
        }

        if (!RestrictedTypes.filterPrivileged().apply(v)) {
            throw new EucalyptusCloudException("Instance " + instanceId + " does not exist.");
        }

        if (!VmState.RUNNING.equals(v.getState())) {
            throw new EucalyptusCloudException("Instance " + instanceId + " is not in a running state.");
        }

        if (!ImageMetadata.Platform.windows.name().equals(v.getPlatform())) {
            throw new ClientComputeException("OperationNotPermitted", "Instance's platform is not Windows");
        }

        if (Strings.isNullOrEmpty(v.getKeyPair().getPublicKey())) {
            throw new ClientComputeException("OperationNotPermitted", "Keypair is not found for the instance");
        }

        if (v.getPasswordData() == null) {
            try {
                final GetConsoleOutputResponseType consoleOutput = getConsoleOutput(
                        new GetConsoleOutputType(instanceId));
                final String tempCo = B64.standard.decString(String.valueOf(consoleOutput.getOutput()))
                        .replaceAll("[\r\n]*", "");
                final String passwordData = tempCo.replaceAll(".*<Password>", "").replaceAll("</Password>.*", "");
                if (tempCo.matches(".*<Password>[\\w=+/]*</Password>.*")) {
                    Entities.asTransaction(VmInstance.class, new Predicate<String>() {
                        @Override
                        public boolean apply(final String passwordData) {
                            final VmInstance vm = Entities.merge(v);
                            vm.updatePasswordData(passwordData);
                            return true;
                        }
                    }).apply(passwordData);
                    v.updatePasswordData(passwordData);
                }
            } catch (Exception e) {
                throw new ComputeException("InternalError", "Error processing request: " + e.getMessage());
            }
        }

        final GetPasswordDataResponseType reply = request.getReply();
        reply.set_return(true);
        reply.setOutput(v.getPasswordData());
        reply.setTimestamp(new Date());
        reply.setInstanceId(v.getInstanceId());
        return reply;
    }

    private static Set<String> toInstanceIds(final Iterable<String> ids) throws EucalyptusCloudException {
        final Set<String> result = Sets.newHashSet();
        if (ids != null)
            for (final String id : ids) {
                result.add(normalizeBundleIdentifier(id).replace("bun-", "i-"));
            }
        return result;
    }

    private boolean validBucketName(String name) {
        return java.util.regex.Pattern.matches("^[a-zA-Z\\d\\.\\-_]{3,255}$", name);
    }

    private static String normalizeIdentifier(final String identifier) throws EucalyptusCloudException {
        try {
            return ResourceIdentifiers.parse(VmInstance.ID_PREFIX, identifier).getIdentifier();
        } catch (final InvalidResourceIdentifier e) {
            throw new ClientComputeException("InvalidInstanceID.Malformed",
                    "Invalid id: \"" + e.getIdentifier() + "\"");
        }
    }

    private static List<String> normalizeIdentifiers(final List<String> identifiers)
            throws EucalyptusCloudException {
        try {
            return ResourceIdentifiers.normalize(VmInstance.ID_PREFIX, identifiers);
        } catch (final InvalidResourceIdentifier e) {
            throw new ClientComputeException("InvalidInstanceID.Malformed",
                    "Invalid id: \"" + e.getIdentifier() + "\"");
        }
    }

    private static String normalizeBundleIdentifier(final String identifier) throws EucalyptusCloudException {
        try {
            return ResourceIdentifiers.parse("bun", identifier).getIdentifier();
        } catch (final InvalidResourceIdentifier e) {
            throw new ClientComputeException("InvalidInstanceID.Malformed",
                    "Invalid id: \"" + e.getIdentifier() + "\"");
        }
    }
}