2015-10-12 18:03:39 +02:00
/ * *
*
* /
package org.gcube.accounting.persistence ;
import java.io.File ;
import java.util.HashMap ;
import java.util.Map ;
import java.util.ServiceLoader ;
2015-10-14 10:46:13 +02:00
import java.util.concurrent.TimeUnit ;
2015-10-30 16:56:38 +01:00
import java.util.concurrent.locks.ReentrantLock ;
2015-10-12 18:03:39 +02:00
import org.gcube.accounting.aggregation.scheduler.AggregationScheduler ;
import org.gcube.common.scope.api.ScopeProvider ;
import org.gcube.common.scope.impl.ScopeBean ;
import org.slf4j.Logger ;
import org.slf4j.LoggerFactory ;
/ * *
* @author Luca Frosini ( ISTI - CNR ) http : //www.lucafrosini.com/
*
* /
public abstract class AccountingPersistenceBackendFactory {
2015-10-30 16:56:38 +01:00
2015-10-12 18:03:39 +02:00
private static final Logger logger = LoggerFactory . getLogger ( AccountingPersistenceBackendFactory . class ) ;
2015-10-30 16:56:38 +01:00
2015-10-12 18:03:39 +02:00
public final static String HOME_SYSTEM_PROPERTY = " user.home " ;
2015-10-30 16:56:38 +01:00
2015-10-12 18:03:39 +02:00
private static final String ACCOUTING_FALLBACK_FILENAME = " accountingFallback.log " ;
2015-10-30 16:56:38 +01:00
2015-10-12 18:03:39 +02:00
private static String fallbackLocation ;
2015-10-30 16:56:38 +01:00
private static ReentrantLock lock = new ReentrantLock ( ) ;
private static ReentrantLock persistenceLock = new ReentrantLock ( ) ;
2015-10-12 18:03:39 +02:00
private static Map < String , AccountingPersistenceBackend > persistencePersistenceBackends ;
2015-10-30 16:56:38 +01:00
2015-10-12 18:03:39 +02:00
static {
persistencePersistenceBackends = new HashMap < String , AccountingPersistenceBackend > ( ) ;
}
2015-10-30 16:56:38 +01:00
2015-10-12 18:03:39 +02:00
private static File file ( File file ) throws IllegalArgumentException {
2015-10-30 16:56:38 +01:00
2015-10-12 18:03:39 +02:00
if ( ! file . isDirectory ( ) ) {
file = file . getParentFile ( ) ;
}
//create folder structure if not exist
if ( ! file . exists ( ) )
file . mkdirs ( ) ;
2015-10-30 16:56:38 +01:00
2015-10-12 18:03:39 +02:00
return file ;
2015-10-30 16:56:38 +01:00
2015-10-12 18:03:39 +02:00
}
2015-10-30 16:56:38 +01:00
protected static void setFallbackLocation ( String path ) {
lock . lock ( ) ;
try {
if ( fallbackLocation = = null ) {
if ( path = = null ) {
path = System . getProperty ( HOME_SYSTEM_PROPERTY ) ;
}
file ( new File ( path ) ) ;
fallbackLocation = path ;
2015-10-12 18:03:39 +02:00
}
2015-10-30 16:56:38 +01:00
} finally {
lock . unlock ( ) ;
2015-10-12 18:03:39 +02:00
}
}
2015-10-30 16:56:38 +01:00
protected static AccountingPersistenceBackend getPersistenceBackend ( ) {
2015-10-12 18:03:39 +02:00
String scope = ScopeProvider . instance . get ( ) ;
if ( scope = = null ) {
logger . error ( " No Scope available. FallbackPersistence will be used " ) ;
File fallbackFile = new File ( fallbackLocation , ACCOUTING_FALLBACK_FILENAME ) ;
return new FallbackPersistence ( fallbackFile ) ;
}
2015-10-30 16:56:38 +01:00
persistenceLock . lock ( ) ;
2015-10-12 18:03:39 +02:00
AccountingPersistenceBackend persistence = persistencePersistenceBackends . get ( scope ) ;
if ( persistence = = null ) {
2015-10-30 16:56:38 +01:00
FallbackPersistence fallbackPersistence ;
try {
ScopeBean bean = new ScopeBean ( scope ) ;
/ *
if ( bean . is ( Type . VRE ) ) {
bean = bean . enclosingScope ( ) ;
}
* /
String name = bean . name ( ) ;
File fallbackFile = new File ( fallbackLocation , String . format ( " %s.%s " , name , ACCOUTING_FALLBACK_FILENAME ) ) ;
fallbackPersistence = new FallbackPersistence ( fallbackFile ) ;
// set only to avoid deadlock
persistencePersistenceBackends . put ( scope , fallbackPersistence ) ;
} finally {
persistenceLock . unlock ( ) ;
2015-10-12 18:03:39 +02:00
}
2015-10-30 16:56:38 +01:00
2015-10-12 18:03:39 +02:00
try {
ServiceLoader < AccountingPersistenceBackend > serviceLoader = ServiceLoader . load ( AccountingPersistenceBackend . class ) ;
for ( AccountingPersistenceBackend foundPersistence : serviceLoader ) {
if ( foundPersistence . getClass ( ) . isInstance ( FallbackPersistence . class ) ) {
continue ;
}
try {
String foundPersistenceClassName = foundPersistence . getClass ( ) . getSimpleName ( ) ;
logger . debug ( " Testing {} " , foundPersistenceClassName ) ;
AccountingPersistenceConfiguration configuration = new AccountingPersistenceConfiguration ( foundPersistenceClassName ) ;
foundPersistence . prepareConnection ( configuration ) ;
/ *
* Uncomment the following line of code if you want to try
* to create a test UsageRecord before setting the
* foundPersistence as default
*
* foundPersistence . accountWithFallback ( TestUsageRecord . createTestServiceUsageRecord ( ) ) ;
* /
persistence = foundPersistence ;
logger . debug ( " {} will be used. " , foundPersistenceClassName ) ;
break ;
} catch ( Exception e ) {
logger . error ( String . format ( " %s not initialized correctly. It will not be used. Trying the next one if any. " , foundPersistence . getClass ( ) . getSimpleName ( ) ) , e ) ;
}
} if ( persistence = = null ) {
persistence = fallbackPersistence ;
}
} catch ( Exception e ) {
logger . error ( " Unable to instance a Persistence Implementation. Using fallback as default " ,
e ) ;
persistence = fallbackPersistence ;
}
2015-10-14 10:46:13 +02:00
persistence . setAggregationScheduler ( AggregationScheduler . newInstance ( ) ) ;
2015-10-12 18:03:39 +02:00
persistence . setFallback ( fallbackPersistence ) ;
persistencePersistenceBackends . put ( scope , persistence ) ;
2015-10-30 16:56:38 +01:00
} else {
persistenceLock . unlock ( ) ;
2015-10-12 18:03:39 +02:00
}
2015-10-30 16:56:38 +01:00
2015-10-12 18:03:39 +02:00
return persistence ;
}
2015-10-14 10:46:13 +02:00
/ * *
* @param timeout
* @param timeUnit
* @throws Exception
* /
public static void flush ( long timeout , TimeUnit timeUnit ) {
for ( String scope : persistencePersistenceBackends . keySet ( ) ) {
AccountingPersistenceBackend apb =
persistencePersistenceBackends . get ( scope ) ;
try {
logger . debug ( " Flushing records in scope {} " , scope ) ;
apb . flush ( timeout , timeUnit ) ;
} catch ( Exception e ) {
logger . error ( " Unable to flush records in scope {} with {} " , scope , apb ) ;
}
}
}
2015-10-30 16:56:38 +01:00
2015-10-12 18:03:39 +02:00
}