Recoded the code redesign. Recoded the function which retrieve the AccountingPersistenceBackend class to use.

git-svn-id: https://svn.d4science.research-infrastructures.eu/gcube/trunk/accounting/accounting-lib@120270 82a268e6-3cf1-43bd-a215-b396298e98cf
This commit is contained in:
Luca Frosini 2015-11-13 10:43:18 +00:00
parent e55ab7f5b7
commit 92f5d42e48
3 changed files with 94 additions and 73 deletions

View File

@ -47,6 +47,13 @@ public abstract class AccountingPersistenceBackend {
this.fallback = fallback; this.fallback = fallback;
} }
/**
* @return the aggregationScheduler
*/
public AggregationScheduler getAggregationScheduler() {
return aggregationScheduler;
}
/** /**
* @param aggregationScheduler the aggregationScheduler to set * @param aggregationScheduler the aggregationScheduler to set
*/ */
@ -156,7 +163,6 @@ public abstract class AccountingPersistenceBackend {
} }
public abstract void close() throws Exception; public abstract void close() throws Exception;
} }

View File

@ -34,7 +34,7 @@ public abstract class AccountingPersistenceBackendFactory {
public static final long FALLBACK_RETRY_TIME = 1000*60*10; // 10 min public static final long FALLBACK_RETRY_TIME = 1000*60*10; // 10 min
private static Map<String,Long> fallbackLastCheck; protected static Map<String,Long> fallbackLastCheck;
static { static {
persistencePersistenceBackends = new HashMap<String, AccountingPersistenceBackend>(); persistencePersistenceBackends = new HashMap<String, AccountingPersistenceBackend>();
@ -62,86 +62,99 @@ public abstract class AccountingPersistenceBackendFactory {
} }
} }
protected static AccountingPersistenceBackend discoverAccountingPersistenceBackend(String scope){
ServiceLoader<AccountingPersistenceBackend> serviceLoader = ServiceLoader.load(AccountingPersistenceBackend.class);
for (AccountingPersistenceBackend foundPersistence : serviceLoader) {
if(foundPersistence instanceof FallbackPersistence){
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());
*/
logger.debug("{} will be used.", foundPersistenceClassName);
foundPersistence.setAggregationScheduler(AggregationScheduler.newInstance());
return foundPersistence;
} 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);
}
}
return null;
};
protected static FallbackPersistence createFallback(String scope){
File fallbackFile = null;
if(scope!=null){
ScopeBean bean = new ScopeBean(scope);
/* if(bean.is(Type.VRE)){ bean = bean.enclosingScope(); } */
String name = bean.name();
fallbackFile = new File(fallbackLocation, String.format("%s.%s", name, ACCOUTING_FALLBACK_FILENAME));
}else{
fallbackFile = new File(fallbackLocation, ACCOUTING_FALLBACK_FILENAME);
}
FallbackPersistence fallbackPersistence = new FallbackPersistence(fallbackFile);
fallbackPersistence.setAggregationScheduler(AggregationScheduler.newInstance());
return fallbackPersistence;
}
protected static synchronized AccountingPersistenceBackend getPersistenceBackend() { protected static synchronized AccountingPersistenceBackend getPersistenceBackend() {
String scope = ScopeProvider.instance.get(); String scope = ScopeProvider.instance.get();
if(scope==null){ if(scope==null){
logger.error("No Scope available. FallbackPersistence will be used"); logger.error("No Scope available. FallbackPersistence will be used");
File fallbackFile = new File(fallbackLocation, ACCOUTING_FALLBACK_FILENAME); return createFallback(null);
return new FallbackPersistence(fallbackFile);
} }
AccountingPersistenceBackend persistence = persistencePersistenceBackends.get(scope); AccountingPersistenceBackend persistence = persistencePersistenceBackends.get(scope);
if(persistence!=null && persistence instanceof FallbackPersistence && fallbackLastCheck.get(scope)!=null){
long now = Calendar.getInstance().getTimeInMillis();
Long lastCheckTimestamp = fallbackLastCheck.get(scope);
if(lastCheckTimestamp <= (now + FALLBACK_RETRY_TIME)){
// Setting persistence to null so that the
// AccountingPersistenceBackend is rechecked
logger.debug("The {} for scope {} is {}. Is time to rediscover if there is another possibility.",
AccountingPersistenceBackend.class.getSimpleName(), scope, persistence.getClass().getSimpleName());
persistence = null;
}
}
if(persistence==null){ if(persistence==null){
persistence = discoverAccountingPersistenceBackend(scope);
ScopeBean bean = new ScopeBean(scope); if(persistence==null){
/* logger.warn("Unable to find a usable {}. {} will be used.", AccountingPersistenceBackend.class.getSimpleName(), FallbackPersistence.class.getSimpleName());
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 fallbackPersistence = new FallbackPersistence(fallbackFile);
try {
ServiceLoader<AccountingPersistenceBackend> serviceLoader = ServiceLoader.load(AccountingPersistenceBackend.class);
for (AccountingPersistenceBackend foundPersistence : serviceLoader) {
if(foundPersistence instanceof FallbackPersistence){
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){
logger.error("Unable to instatiate a {}. {} will be used.", AccountingPersistenceBackend.class.getSimpleName(), FallbackPersistence.class.getSimpleName());
persistence = fallbackPersistence;
}
} catch(Exception e){
//logger.error("Unable to instance a Persistence Implementation. Using fallback as default", e);
logger.error("Unable to instantiate a {}. {} will be used.", AccountingPersistenceBackend.class.getSimpleName(), FallbackPersistence.class.getSimpleName(), e);
persistence = fallbackPersistence;
}
persistence.setAggregationScheduler(AggregationScheduler.newInstance());
persistence.setFallback(fallbackPersistence);
if(persistence instanceof FallbackPersistence){
long now = Calendar.getInstance().getTimeInMillis(); long now = Calendar.getInstance().getTimeInMillis();
fallbackLastCheck.put(scope, now); fallbackLastCheck.put(scope, now);
persistence = createFallback(scope);
} }
persistencePersistenceBackends.put(scope, persistence); persistencePersistenceBackends.put(scope, persistence);
} else {
if(persistence instanceof FallbackPersistence && fallbackLastCheck.get(scope)!=null){
long now = Calendar.getInstance().getTimeInMillis();
Long lastCheckTimestamp = fallbackLastCheck.get(scope);
if(lastCheckTimestamp <= (now + FALLBACK_RETRY_TIME)){
// Setting persistence to null so that the
// AccountingPersistenceBackend is rechecked
logger.debug("The {} for scope {} is {}. Is time to rediscover if there is another possibility.",
AccountingPersistenceBackend.class.getSimpleName(), scope, persistence.getClass().getSimpleName());
AccountingPersistenceBackend discoveredPersistenceBackend = discoverAccountingPersistenceBackend(scope);
if(discoveredPersistenceBackend!=null){
discoveredPersistenceBackend.setAggregationScheduler(persistence.getAggregationScheduler());
fallbackLastCheck.remove(scope);
persistencePersistenceBackends.put(scope, discoveredPersistenceBackend);
try {
persistence.close();
} catch (Exception e) {
logger.error("Error closing {} for scope {} which has been substituted with {}.",
persistence.getClass().getSimpleName(), scope,
discoveredPersistenceBackend.getClass().getSimpleName(), e);
}
persistence = discoveredPersistenceBackend;
}else{
fallbackLastCheck.put(scope, now);
}
}
}
} }
return persistence; return persistence;

View File

@ -103,8 +103,9 @@ public class AccountingPersistenceBackendTest {
@Test @Test
public void testScopeRecheck() throws Exception { public void testScopeRecheck() throws Exception {
ScopeProvider.instance.set("/fakeScope"); ScopeProvider.instance.set("/fakeScope");
AccountingPersistenceBackend first = AccountingPersistenceBackendFactory.getPersistenceBackend(); AccountingPersistenceBackendFactory.getPersistenceBackend();
logger.debug("First {} : {}", AccountingPersistenceBackend.class.getSimpleName(), first); Long firstCheck = AccountingPersistenceBackendFactory.fallbackLastCheck.get(ScopeProvider.instance.get());
logger.debug("First Check Time {}", firstCheck);
long startTime = Calendar.getInstance().getTimeInMillis(); long startTime = Calendar.getInstance().getTimeInMillis();
long endTime = startTime; long endTime = startTime;
@ -113,10 +114,11 @@ public class AccountingPersistenceBackendTest {
endTime = Calendar.getInstance().getTimeInMillis(); endTime = Calendar.getInstance().getTimeInMillis();
} }
AccountingPersistenceBackend second = AccountingPersistenceBackendFactory.getPersistenceBackend(); AccountingPersistenceBackendFactory.getPersistenceBackend();
logger.debug("Second {} : {}", AccountingPersistenceBackend.class.getSimpleName(), second); Long secondCheck = AccountingPersistenceBackendFactory.fallbackLastCheck.get(ScopeProvider.instance.get());
logger.debug("Second Check Time {}", secondCheck);
Assert.assertNotEquals(first, second); Assert.assertNotEquals(firstCheck, secondCheck);
} }
} }