Java tutorial
/************************************************************************* * Copyright 2009-2015 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.compute.common.internal.vm; import java.util.Collections; import java.util.List; import java.util.Map; import java.util.NoSuchElementException; import java.util.concurrent.atomic.AtomicReference; import javax.annotation.Nonnull; import javax.annotation.Nullable; import javax.persistence.EntityTransaction; import org.apache.log4j.Logger; import org.hibernate.Criteria; import org.hibernate.criterion.Criterion; import org.hibernate.criterion.Example; import org.hibernate.criterion.Projection; import org.hibernate.criterion.Restrictions; import com.eucalyptus.compute.common.CloudMetadata; import com.eucalyptus.entities.Entities; import com.eucalyptus.entities.TransactionResource; import com.eucalyptus.records.Logs; import com.eucalyptus.util.CollectionUtils; import com.eucalyptus.auth.principal.OwnerFullName; import com.eucalyptus.util.RestrictedTypes; import com.google.common.base.Function; import com.google.common.base.Functions; import com.google.common.base.Predicate; import com.google.common.base.Predicates; import com.google.common.base.Supplier; import com.google.common.collect.Iterables; import com.google.common.collect.Lists; /** * */ public class VmInstances { private static final Logger LOG = Logger.getLogger(VmInstances.class); protected static final AtomicReference<String> ebsRootDeviceName = new AtomicReference<String>("emi"); public static String getEbsRootDeviceName() { return ebsRootDeviceName.get(); } /** * Lookup a VM instance. * * @param name The instance identifier (display name) * @return The instance. * @throws java.util.NoSuchElementException If the instance is not found */ @Nonnull public static VmInstance lookupAny(final String name) throws NoSuchElementException { return PersistentLookup.INSTANCE.apply(name); } /** * Lookup a non-terminated VM instance. * * @param name The instance identifier (display name) * @return The instance. * @throws NoSuchElementException If the instance is not found * @throws TerminatedInstanceException If the instance is terminated. */ @Nonnull public static VmInstance lookup(final String name) throws NoSuchElementException, TerminatedInstanceException { return lookup().apply(name); } /** * Function for lookup of non-terminated VM instances. * * <p>The function parameter is the instance identifier the return is the * instance. The function will not return null, but may throw * NoSuchElementException or TerminatedInstanceException.</p> * * @return The function. */ public static Function<String, VmInstance> lookup() { return Functions.compose(TerminatedInstanceCheck.INSTANCE, PersistentLookup.INSTANCE); } /** * Function for lookup of running VM instance by public IP. * * @param ip The public/elastic IP for the instance * @return The instance * @throws NoSuchElementException if an instance was not found with the IP */ @Nonnull public static VmInstance lookupByPublicIp(final String ip) throws NoSuchElementException { try (TransactionResource db = Entities.transactionFor(VmInstance.class)) { VmInstance vmExample = VmInstance.exampleWithPublicIp(ip); VmInstance vm = (VmInstance) Entities.createCriteriaUnique(VmInstance.class) .add(Example.create(vmExample)) .add(VmInstance.criterion(VmInstance.VmState.RUNNING, VmInstance.VmState.PENDING)) .uniqueResult(); if (vm == null) { throw new NoSuchElementException("VmInstance with public ip: " + ip); } db.commit(); return vm; } catch (Exception ex) { Logs.exhaust().error(ex, ex); throw new NoSuchElementException(ex.getMessage()); } } /** * List instances that are not done and match the given predicate. * * @param predicate The predicate to match * @return The matching instances * @see com.eucalyptus.compute.common.internal.vm.VmInstance.VmStateSet#DONE */ public static List<VmInstance> list(@Nullable Predicate<? super VmInstance> predicate) { return list((OwnerFullName) null, predicate); } /** * List instances that are not done and match the given owner/predicate. * * @param ownerFullName The owning user or account * @param predicate The predicate to match * @return The matching instances * @see com.eucalyptus.compute.common.internal.vm.VmInstance.VmStateSet#DONE */ public static List<VmInstance> list(@Nullable OwnerFullName ownerFullName, @Nullable Predicate<? super VmInstance> predicate) { return list(ownerFullName, Restrictions.not(VmInstance.criterion(VmInstance.VmStateSet.DONE.array())), Collections.<String, String>emptyMap(), Predicates.and(VmInstance.VmStateSet.DONE.not(), checkPredicate(predicate)), false); } /** * List instances in any state that match the given parameters. */ public static List<VmInstance> list(@Nullable final OwnerFullName ownerFullName, final Criterion criterion, final Map<String, String> aliases, @Nullable final Predicate<? super VmInstance> predicate) { return list(ownerFullName, criterion, aliases, predicate, false); } /** * List instances in any state that match the given parameters. */ public static List<VmInstance> list(@Nullable final OwnerFullName ownerFullName, final Criterion criterion, final Map<String, String> aliases, @Nullable final Predicate<? super VmInstance> predicate, final boolean outerJoins) { return list(new Supplier<List<VmInstance>>() { @Override public List<VmInstance> get() { return Entities.query(VmInstance.named(ownerFullName, null), false, criterion, aliases, outerJoins); } }, Predicates.and(RestrictedTypes.filterByOwner(ownerFullName), checkPredicate(predicate))); } /** * List instances in any state that match the given parameters. */ public static List<VmInstance> listByClientToken(@Nullable final OwnerFullName ownerFullName, @Nullable final String clientToken, @Nullable Predicate<? super VmInstance> predicate) { return list(new Supplier<List<VmInstance>>() { @Override public List<VmInstance> get() { return Entities.query(VmInstance.withToken(ownerFullName, clientToken)); } }, Predicates.and(CollectionUtils.propertyPredicate(clientToken, VmInstance.clientToken()), RestrictedTypes.filterByOwner(ownerFullName), checkPredicate(predicate))); } private static List<VmInstance> list(@Nonnull Supplier<List<VmInstance>> instancesSupplier, @Nullable Predicate<? super VmInstance> predicate) { predicate = checkPredicate(predicate); return listPersistent(instancesSupplier, predicate); } private static List<VmInstance> listPersistent(@Nonnull Supplier<List<VmInstance>> instancesSupplier, @Nonnull Predicate<? super VmInstance> predicate) { final EntityTransaction db = Entities.get(VmInstance.class); try { final Iterable<VmInstance> vms = Iterables.filter(instancesSupplier.get(), predicate); final List<VmInstance> instances = Lists.newArrayList(vms); db.commit(); return instances; } catch (final Exception ex) { LOG.error(ex); Logs.extreme().error(ex, ex); return Lists.newArrayList(); } finally { if (db.isActive()) db.rollback(); } } public interface InstanceProjection<T> { Projection getProjection(); List<T> results(List<?> listing); } public static InstanceProjection<String> instanceIdProjection() { return StringInstanceProjections.INSTANCE_ID; } public static InstanceProjection<String> instanceUuidProjection() { return StringInstanceProjections.INSTANCE_UUID; } private enum StringInstanceProjections implements InstanceProjection<String> { INSTANCE_ID { @Override public Projection getProjection() { return VmInstance.instanceIdProjection(); } }, INSTANCE_UUID { @Override public Projection getProjection() { return VmInstance.instanceUuidProjection(); } },; @Override public List<String> results(final List<?> listing) { //noinspection unchecked return (List<String>) listing; } } public static <T> List<T> listWithProjection(@Nonnull final InstanceProjection<T> projection, final Criterion... criterions) { try (final TransactionResource db = Entities.readOnlyDistinctTransactionFor(VmInstance.class)) { final Criteria query = Entities.createCriteria(VmInstance.class).setReadOnly(true).setFetchSize(25_000) .add(Restrictions.and(criterions)).setProjection(projection.getProjection()); return projection.results(query.list()); } } private static <T> Predicate<T> checkPredicate(Predicate<T> predicate) { return predicate == null ? Predicates.<T>alwaysTrue() : predicate; } public static VmVolumeAttachment lookupVolumeAttachment(final String volumeId, final List<VmInstance> vms) { VmVolumeAttachment ret = null; try { for (VmInstance vm : vms) { try { ret = vm.lookupVolumeAttachment(volumeId); if (ret.getVmInstance() == null) { ret.setVmInstance(vm); } } catch (NoSuchElementException ex) { continue; } } if (ret == null) { throw new NoSuchElementException("VmVolumeAttachment: no volume attachment for " + volumeId); } return ret; } catch (Exception ex) { throw new NoSuchElementException(ex.getMessage()); } } @RestrictedTypes.Resolver(CloudMetadata.VmInstanceMetadata.class) enum PersistentLookup implements Function<String, VmInstance> { INSTANCE; /** * @see com.google.common.base.Function#apply(java.lang.Object) */ @Nonnull @Override public VmInstance apply(final String name) { return VmInstance.Lookup.INSTANCE.apply(name); } } enum TerminatedInstanceCheck implements Function<VmInstance, VmInstance> { INSTANCE; @Nullable @Override public VmInstance apply(final VmInstance instance) { if (instance != null && VmInstance.VmStateSet.DONE.apply(instance)) { throw new TerminatedInstanceException(instance.getDisplayName()); } return instance; } } public static class TerminatedInstanceException extends NoSuchElementException { /** * */ private static final long serialVersionUID = 1L; TerminatedInstanceException(final String s) { super(s); } } }