/************************************************************************* * 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.compute.common.internal.account; import java.util.NoSuchElementException; import java.util.ServiceLoader; import java.util.concurrent.TimeUnit; import org.apache.log4j.Logger; import com.eucalyptus.entities.Entities; import com.eucalyptus.entities.TransactionException; import com.eucalyptus.entities.TransactionResource; import com.google.common.cache.Cache; import com.google.common.cache.CacheBuilder; /** * */ public class ComputeAccounts { private static final Logger logger = Logger.getLogger( ComputeAccounts.class ); private static final Cache<String,Object> accountCache = CacheBuilder .<String,Object>newBuilder( ) .maximumSize( 1_000 ) .expireAfterWrite( 1, TimeUnit.HOURS ) .build( ); private static final Iterable<ComputeAccountInitializer> initializers = ServiceLoader.load( ComputeAccountInitializer.class ); public static void ensureInitialized( final String accountNumber ) { if ( accountCache.getIfPresent( accountNumber ) == null ) { boolean initialized = false; synchronized ( sync( accountNumber ) ) { if ( accountCache.getIfPresent( accountNumber ) == null ) { try ( final TransactionResource tx = Entities.transactionFor( ComputeAccount.class ) ) { try { Entities.uniqueResult( ComputeAccount.exampleWithAccountNumber( accountNumber ) ); } catch ( NoSuchElementException e ) { Entities.persist( ComputeAccount.create( accountNumber ) ); tx.commit( ); initialized = true; } accountCache.put( accountNumber, accountNumber ); } catch ( TransactionException e ) { logger.error( "Error checking for account initialization " + accountNumber, e ); } } } if ( initialized ) { initialize( accountNumber ); } } } private static Object sync( final String accountNumber ) { return ( "account-create-sync-" + accountNumber ).intern( ); } private static void initialize( final String accountNumber ) { for ( final ComputeAccountInitializer initializer : initializers ) { try { initializer.initialize( accountNumber ); } catch ( final Exception e ) { logger.error( "Error in account initializer", e ); } } } public interface ComputeAccountInitializer { void initialize( String accountNumber ); } }