accounting-lib/src/main/java/org/gcube/accounting/aggregator/RegexRulesAggregator.java

169 lines
4.6 KiB
Java

package org.gcube.accounting.aggregator;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.ScheduledFuture;
import java.util.concurrent.ThreadFactory;
import java.util.concurrent.TimeUnit;
import org.gcube.accounting.datamodel.validations.validators.MatcherReplace;
import org.gcube.accounting.persistence.AccountingPersistenceConfiguration;
import org.gcube.com.fasterxml.jackson.databind.JavaType;
import org.gcube.com.fasterxml.jackson.databind.ObjectMapper;
import org.gcube.documentstore.persistence.ExecutorUtils;
import org.gcube.documentstore.records.DSMapper;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
public class RegexRulesAggregator implements Runnable {
private static final Logger logger = LoggerFactory.getLogger(RegexRulesAggregator.class);
public static final ScheduledExecutorService REGEX_REDISCOVERY_POOL;
protected static final String DELAY = "delay";
protected static final String TIME_UNIT = "timeUnit";
protected static final String MATCHER_REPLACE_RULES = "MatcherReplaceRules";
static {
REGEX_REDISCOVERY_POOL = Executors.newScheduledThreadPool(50, new ThreadFactory() {
private int counter = 0;
private static final String prefix = "AggregationRegexRediscoveryThread";
public Thread newThread(Runnable r) {
return new Thread(r, prefix + "-" + counter++);
}
});
}
protected TimeUnit timeUnit = TimeUnit.MINUTES;
protected long delay = TimeUnit.MINUTES.toMinutes(15);
protected ScheduledFuture<?> rulesReloader;
protected List<MatcherReplace> matcherReplaceList;
protected AccountingPersistenceConfiguration accountingPersistenceConfiguration;
protected static RegexRulesAggregator instance;
protected boolean changeRate;
protected ScheduledFuture<?> reloadAggregatorRules;
public synchronized static RegexRulesAggregator getInstance() {
if(instance==null) {
instance = new RegexRulesAggregator();
}
return instance;
}
protected RegexRulesAggregator() {
matcherReplaceList = new ArrayList<>();
changeRate = false;
readConfiguration();
}
public List<MatcherReplace> getMatcherReplaceList() {
synchronized(matcherReplaceList) {
return matcherReplaceList;
}
}
public MatcherReplace addMatcherReplace(MatcherReplace matcherReplace) {
synchronized(matcherReplaceList) {
matcherReplaceList.add(matcherReplace);
}
return matcherReplace;
}
public void vacumRules() {
synchronized(matcherReplaceList) {
matcherReplaceList = new ArrayList<>();
}
}
public void readConfiguration() {
try {
accountingPersistenceConfiguration = new AccountingPersistenceConfiguration(this.getClass());
try {
long oldDelay = delay;
String delayString = accountingPersistenceConfiguration.getProperty(DELAY);
delay = Long.parseLong(delayString);
if(oldDelay!=delay) {
changeRate = true;
}
TimeUnit oldTimeUnit = timeUnit;
String timeUnitString = accountingPersistenceConfiguration.getProperty(TIME_UNIT);
timeUnit = TimeUnit.valueOf(timeUnitString.toUpperCase());
if(oldTimeUnit.ordinal() != timeUnit.ordinal()) {
changeRate = true;
}
}catch (Exception e) {
logger.warn("Unable to retrieve regex reload delay. Goign to use last known delay {} {}", delay, timeUnit.name().toLowerCase());
}
String rulesString = accountingPersistenceConfiguration.getProperty(MATCHER_REPLACE_RULES);
ObjectMapper mapper = DSMapper.getObjectMapper();
JavaType type = mapper.getTypeFactory().constructCollectionType(List.class, MatcherReplace.class);
List<MatcherReplace> rules = mapper.readValue(rulesString, type);
synchronized(matcherReplaceList) {
matcherReplaceList = rules;
}
} catch(Exception e) {
logger.error("Unable to properly load RegexRules", e);
}
}
@Override
public void run() {
readConfiguration();
if(changeRate) {
stop();
}
if(reloadAggregatorRules == null) {
reloadAggregatorRules = REGEX_REDISCOVERY_POOL.scheduleAtFixedRate(this, delay, delay, timeUnit);
}
}
/**
* Stop rule reloader. Use only if you really know what you do.
*/
public void stop() {
if(reloadAggregatorRules != null) {
try {
reloadAggregatorRules.cancel(true);
reloadAggregatorRules = null;
}catch (Throwable t) {
logger.error("Unable to properly stop {} reloader", this.getClass().getSimpleName(), t);
}
}
}
@Deprecated
public void start() {
}
public static void shutdown() {
RegexRulesAggregator.getInstance().stop();
ExecutorUtils.shutDownPool(RegexRulesAggregator.REGEX_REDISCOVERY_POOL);
}
}