/************************************************************************* * Copyright 2009-2016 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. ************************************************************************/ package com.eucalyptus.autoscaling.common.internal.groups; import static com.eucalyptus.autoscaling.common.AutoScalingMetadata.AutoScalingGroupMetadata; import java.util.Collection; import java.util.Collections; import java.util.List; import java.util.Set; import java.util.stream.Collectors; import org.hibernate.criterion.DetachedCriteria; import org.hibernate.criterion.Example; import org.hibernate.criterion.Junction; import org.hibernate.criterion.Projections; import org.hibernate.criterion.Property; import org.hibernate.criterion.Restrictions; import com.eucalyptus.autoscaling.common.AutoScalingResourceName; import com.eucalyptus.autoscaling.common.internal.instances.AutoScalingInstance; import com.eucalyptus.autoscaling.common.internal.instances.HealthStatus; import com.eucalyptus.autoscaling.common.internal.metadata.AbstractOwnedPersistents; import com.eucalyptus.autoscaling.common.internal.metadata.AbstractOwnedPersistentsWithResourceNameSupport; import com.eucalyptus.autoscaling.common.internal.metadata.AutoScalingMetadataException; import com.eucalyptus.component.annotation.ComponentNamed; import com.eucalyptus.util.Callback; import com.eucalyptus.auth.principal.OwnerFullName; import com.eucalyptus.util.FUtils; 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.collect.Sets; /** * */ @ComponentNamed public class PersistenceAutoScalingGroups extends AutoScalingGroups { private PersistenceSupport persistenceSupport = new PersistenceSupport(); @Override public <T> List<T> list( final OwnerFullName ownerFullName, final Predicate<? super AutoScalingGroup> filter, final Function<? super AutoScalingGroup,T> transform ) throws AutoScalingMetadataException { return persistenceSupport.list( ownerFullName, filter, transform ); } @Override public <T> List<T> listRequiringScaling( final Function<? super AutoScalingGroup,T> transform ) throws AutoScalingMetadataException { return persistenceSupport.listByExample( AutoScalingGroup.requiringScaling(), Predicates.alwaysTrue(), transform ); } @Override public <T> List<T> listRequiringInstanceReplacement( final Function<? super AutoScalingGroup,T> transform ) throws AutoScalingMetadataException { final DetachedCriteria criteria = DetachedCriteria.forClass( AutoScalingInstance.class ) .add( Example.create( AutoScalingInstance.withHealthStatus( HealthStatus.Unhealthy ) ) ) .setProjection( Projections.property( "autoScalingGroup" ) ); return persistenceSupport.listByExample( AutoScalingGroup.withOwner( null ), Predicates.alwaysTrue(), Property.forName( "id" ).in( criteria ), Collections.<String, String>emptyMap(), transform ); } @Override public <T> List<T> listRequiringMonitoring( final Set<MonitoringSelector> selectors, final Function<? super AutoScalingGroup,T> transform ) throws AutoScalingMetadataException { final Collection<String> suffixes = selectors.stream( ) .flatMap( FUtils.chain( MonitoringSelector::suffixes, Collection::stream ) ) .collect( Collectors.toSet( ) ); final Junction likeAnyOf = Restrictions.disjunction(); for ( final String suffix : suffixes ) { likeAnyOf.add( Restrictions.ilike( "id", "%" + suffix ) ); } return persistenceSupport.listByExample( AutoScalingGroup.withOwner( null ), Predicates.alwaysTrue(), likeAnyOf, Collections.<String,String>emptyMap(), transform ); } @Override public <T> T lookup( final OwnerFullName ownerFullName, final String autoScalingGroupName, final Function<? super AutoScalingGroup,T> transform ) throws AutoScalingMetadataException { return persistenceSupport.lookup( ownerFullName, autoScalingGroupName, transform ); } @Override public void update( final OwnerFullName ownerFullName, final String autoScalingGroupName, final Callback<AutoScalingGroup> groupUpdateCallback ) throws AutoScalingMetadataException { persistenceSupport.updateWithRetries( ownerFullName, autoScalingGroupName, groupUpdateCallback ); } @Override public void markScalingRequiredForZones( final Set<String> availabilityZones ) throws AutoScalingMetadataException { if ( !availabilityZones.isEmpty() ) { persistenceSupport.transactionWithRetry( AutoScalingGroup.class, new AbstractOwnedPersistents.WorkCallback<Void>() { @Override public Void doWork() throws AutoScalingMetadataException { final List<AutoScalingGroup> groups = persistenceSupport.listByExample( AutoScalingGroup.withOwner( null ), Predicates.alwaysTrue(), Functions.<AutoScalingGroup>identity() ); for ( final AutoScalingGroup group : groups ) { if ( !Sets.union( Sets.newHashSet( group.getAvailabilityZones() ), availabilityZones ).isEmpty() ) { group.setScalingRequired( true ); } } return null; } } ); } } @Override public boolean delete( final AutoScalingGroupMetadata autoScalingGroup ) throws AutoScalingMetadataException { return persistenceSupport.delete( autoScalingGroup ); } @Override public AutoScalingGroup save( final AutoScalingGroup autoScalingGroup ) throws AutoScalingMetadataException { return persistenceSupport.save( autoScalingGroup ); } private static class PersistenceSupport extends AbstractOwnedPersistentsWithResourceNameSupport<AutoScalingGroup> { private PersistenceSupport() { super( AutoScalingResourceName.Type.autoScalingGroup ); } @Override protected AutoScalingGroup exampleWithOwner( final OwnerFullName ownerFullName ) { return AutoScalingGroup.withOwner( ownerFullName ); } @Override protected AutoScalingGroup exampleWithName( final OwnerFullName ownerFullName, final String name ) { return AutoScalingGroup.named( ownerFullName, name ); } @Override protected AutoScalingGroup exampleWithUuid( final String uuid ) { return AutoScalingGroup.withUuid( uuid ); } } }