/*
* ProActive Parallel Suite(TM):
* The Open Source library for parallel and distributed
* Workflows & Scheduling, Orchestration, Cloud Automation
* and Big Data Analysis on Enterprise Grids & Clouds.
*
* Copyright (c) 2007 - 2017 ActiveEon
* Contact: contact@activeeon.com
*
* This library is free software: you can redistribute it and/or
* modify it under the terms of the GNU Affero 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 Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
* If needed, contact us to obtain a release under GPL Version 2 or 3
* or a different license than the AGPL.
*/
package org.ow2.proactive.account;
import java.util.HashMap;
import java.util.Map;
import org.apache.log4j.Logger;
/**
* Sub classes may use the logger of this class.
*
* @author The ProActive Team
* @since ProActive Scheduling 2.1
* @param <E> The specific Account implementation
*/
public abstract class AbstractAccountsManager<E extends Account> {
/** The logger provided by sub-classes */
protected final Logger logger;
/** The map that contains all statistics */
protected volatile Map<String, E> accountsMap;
/** Cache valid time in seconds */
private volatile int cacheValidTimeInSeconds;
/** Last refresh duration */
private volatile long lastCacheClearTimeStamp;
/** Last refresh duration */
private volatile long lastRefreshDurationInMilliseconds;
protected AbstractAccountsManager(final String refreshThreadName, final Logger logger) {
this.accountsMap = new HashMap<>();
this.cacheValidTimeInSeconds = this.getDefaultCacheValidityTimeInSeconds();
this.logger = logger;
}
/**
* Reads account information from the data base
* @param username the name of the user for which account is read
* @return account
*/
protected abstract E readAccount(final String username);
/**
* Returns the accounts for the user specified by its username
*
* @param username the name of the user
* @return The accounts of the user, can be null if the user is unknown
*
*/
public E getAccount(final String username) {
if (cacheValidTimeInSeconds == 0) {
// the mean to disable the accounting
throw new RuntimeException("The accounting is disabled.");
}
synchronized (accountsMap) {
if (System.currentTimeMillis() - lastCacheClearTimeStamp > cacheValidTimeInSeconds * 1000) {
clearCache();
} else if (accountsMap.containsKey(username)) {
return accountsMap.get(username);
}
}
final long refreshStartTime = System.currentTimeMillis();
E account = readAccount(username);
lastRefreshDurationInMilliseconds = System.currentTimeMillis() - refreshStartTime;
if (account != null) {
synchronized (accountsMap) {
accountsMap.put(username, account);
}
}
return account;
}
/**
* This methods performs a full refresh from database.
*/
public synchronized void clearCache() {
synchronized (accountsMap) {
// clearing the map contained all the records
// it will provoke the data base access next time the client request
// an accounting information
this.accountsMap.clear();
lastCacheClearTimeStamp = System.currentTimeMillis();
}
}
/**
* Sets the refresh rate of the accounts refresher.
*
* @param cacheValidTimeInSeconds the refresh rate
*/
public void setCacheValidityTimeInSeconds(final int cacheValidTimeInSeconds) {
this.cacheValidTimeInSeconds = cacheValidTimeInSeconds;
}
/**
* Returns the refresh rate of the accounts refresher.
*
* @return the current value of the refresh rate in seconds
*/
public int getCacheValidityTimeInSeconds() {
return this.cacheValidTimeInSeconds;
}
/**
* Returns the default value of the accounts refresher.
*
* @return the default value of the refresh rate in seconds
*/
public abstract int getDefaultCacheValidityTimeInSeconds();
/**
* Returns the duration of the last refresh performed by the account refresher.
*
* @return the duration of the last refresh
*/
public long getLastRefreshDurationInMilliseconds() {
return this.lastRefreshDurationInMilliseconds;
}
}