/*************************************************************************
* 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.
************************************************************************/
package com.eucalyptus.autoscaling.common.internal.metadata;
import static com.eucalyptus.autoscaling.common.AutoScalingMetadata.AutoScalingMetadataWithResourceName;
import javax.annotation.Nullable;
import com.eucalyptus.auth.principal.AccountFullName;
import com.eucalyptus.autoscaling.common.AutoScalingMetadata;
import com.eucalyptus.autoscaling.common.AutoScalingResourceName;
import com.eucalyptus.entities.AbstractOwnedPersistent;
import com.eucalyptus.entities.AbstractPersistentSupport;
import com.eucalyptus.util.Callback;
import com.eucalyptus.auth.principal.OwnerFullName;
import com.eucalyptus.auth.type.RestrictedType;
import com.google.common.base.Function;
import com.google.common.base.Functions;
import com.google.common.base.Predicate;
import com.google.common.base.Predicates;
/**
*
*/
public abstract class AbstractOwnedPersistentsWithResourceNameSupport<AOP extends AbstractOwnedPersistent & AutoScalingMetadataWithResourceName> extends AbstractOwnedPersistents<AOP> {
private final AutoScalingResourceName.Type type;
@Nullable
private final AutoScalingResourceName.Type scopeType;
protected AbstractOwnedPersistentsWithResourceNameSupport( final AutoScalingResourceName.Type type ) {
this( type, null );
}
protected AbstractOwnedPersistentsWithResourceNameSupport( final AutoScalingResourceName.Type type,
@Nullable final AutoScalingResourceName.Type scopeType ) {
super( type.describe() );
this.type = type;
this.scopeType = scopeType;
}
public final <T> T lookup( final OwnerFullName ownerFullName,
final String nameOrArn,
final Function<? super AOP,T> transform ) throws AutoScalingMetadataException {
return lookup( ownerFullName, null, nameOrArn, transform );
}
public final <T> T lookup( final OwnerFullName ownerFullName,
@Nullable final String scopeNameOrArn,
final String nameOrArn,
final Function<? super AOP,T> transform ) throws AutoScalingMetadataException {
if ( AutoScalingResourceName.isResourceName().apply( nameOrArn ) ) {
return lookupByUuid(
AutoScalingResourceName.parse( nameOrArn, type ).getUuid(),
Predicates.alwaysTrue( ),
transform );
} else {
final String scopeName = getNameFromScopeNameOrArn( scopeNameOrArn );
return lookupByName( ownerFullName, scopeName, nameOrArn, transform );
}
}
public AOP update( final OwnerFullName ownerFullName,
final String nameOrArn,
final Callback<AOP> updateCallback ) throws AutoScalingMetadataException {
return update( ownerFullName, null, nameOrArn, updateCallback );
}
public AOP updateWithRetries( final OwnerFullName ownerFullName,
final String nameOrArn,
final Callback<AOP> updateCallback ) throws AutoScalingMetadataException {
return updateWithRetries( ownerFullName, null, nameOrArn, updateCallback );
}
public AOP update( final OwnerFullName ownerFullName,
@Nullable final String scopeNameOrArn,
final String nameOrArn,
final Callback<AOP> updateCallback ) throws AutoScalingMetadataException {
return update( ownerFullName, scopeNameOrArn, nameOrArn, updateCallback, Functions.<AbstractPersistentSupport<AutoScalingMetadata, AOP, AutoScalingMetadataException>>identity( ) );
}
public AOP updateWithRetries( final OwnerFullName ownerFullName,
@Nullable final String scopeNameOrArn,
final String nameOrArn,
final Callback<AOP> updateCallback ) throws AutoScalingMetadataException {
return update( ownerFullName, scopeNameOrArn, nameOrArn, updateCallback, retries( ) );
}
private AOP update( final OwnerFullName ownerFullName,
@Nullable final String scopeNameOrArn,
final String nameOrArn,
final Callback<AOP> updateCallback,
final Function<AbstractPersistentSupport<AutoScalingMetadata, AOP, AutoScalingMetadataException>,AbstractPersistentSupport<AutoScalingMetadata, AOP, AutoScalingMetadataException>> persistenceTransformer ) throws AutoScalingMetadataException {
final AOP example;
if ( AutoScalingResourceName.isResourceName().apply( nameOrArn ) ) {
example = exampleWithUuid( AutoScalingResourceName.parse( nameOrArn, type ).getUuid() );
} else {
final String scopeName = getNameFromScopeNameOrArn( scopeNameOrArn );
example = exampleWithName( ownerFullName, scopeName, nameOrArn );
}
//noinspection ConstantConditions
return persistenceTransformer.apply( this ).updateByExample( example, ownerFullName, nameOrArn, updateCallback );
}
protected AOP exampleWithName( OwnerFullName ownerFullName, String scope, String name ) {
return exampleWithName( ownerFullName, name );
}
protected <T> T lookupByUuid( final String uuid,
final Predicate<? super AOP> filter,
final Function<? super AOP,T> transform ) throws AutoScalingMetadataException {
return lookupByExample( exampleWithUuid( uuid ), null, uuid, filter, transform );
}
protected <T> T lookupByName( final OwnerFullName ownerFullName,
final String scope,
final String name,
final Function<? super AOP,T> transform ) throws AutoScalingMetadataException {
return lookupByExample( exampleWithName( ownerFullName, scope, name ), ownerFullName, name, Predicates.alwaysTrue(), transform );
}
@Override
public boolean delete( final AutoScalingMetadata metadata ) throws AutoScalingMetadataException {
try {
return !withRetries( ).deleteByExample(
metadata instanceof AutoScalingMetadataWithResourceName ?
exampleWithUuid( AutoScalingResourceName.parse( ((AutoScalingMetadataWithResourceName)metadata).getArn(), type ).getUuid() ) :
exampleWithName( AccountFullName.getInstance( metadata.getOwner().getAccountNumber() ), metadata.getDisplayName( ) )
).isEmpty( );
} catch ( Exception e ) {
throw new AutoScalingMetadataException( "Error deleting "+typeDescription+" '"+describe( metadata )+"'", e );
}
}
@Override
protected final String describe( final RestrictedType metadata ) {
if ( metadata instanceof AutoScalingMetadataWithResourceName ) {
return ((AutoScalingMetadataWithResourceName)metadata).getArn();
} else {
return super.describe( metadata );
}
}
protected abstract AOP exampleWithUuid( String uuid );
private Function<AbstractPersistentSupport<AutoScalingMetadata, AOP, AutoScalingMetadataException>,AbstractPersistentSupport<AutoScalingMetadata, AOP, AutoScalingMetadataException>> retries( ) {
return new Function<AbstractPersistentSupport<AutoScalingMetadata, AOP, AutoScalingMetadataException>,AbstractPersistentSupport<AutoScalingMetadata, AOP, AutoScalingMetadataException>>(){
@Override
public AbstractPersistentSupport<AutoScalingMetadata, AOP, AutoScalingMetadataException> apply(
final AbstractPersistentSupport<AutoScalingMetadata, AOP, AutoScalingMetadataException> persistence
) {
return persistence.withRetries( );
}
};
}
private String getNameFromScopeNameOrArn( final String scopeNameOrArn ) {
final String scopeName;
if ( scopeNameOrArn != null &&
scopeType != null &&
AutoScalingResourceName.isResourceName().apply( scopeNameOrArn ) ) {
scopeName = AutoScalingResourceName.parse( scopeNameOrArn, type ).getName( scopeType );
} else {
scopeName = scopeNameOrArn;
}
return scopeName;
}
}