com.inteligr8.alfresco.attrclean.AbstractBootstrapService Maven / Gradle / Ivy
/*
* This program is free software: you can redistribute it and/or modify it
* under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or (at your
* option) any later version.
*
* 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 .
*/
package com.inteligr8.alfresco.attrclean;
import java.io.Serializable;
import java.util.Arrays;
import java.util.Collection;
import java.util.LinkedHashMap;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import org.alfresco.service.cmr.attributes.AttributeService;
import org.alfresco.service.cmr.attributes.AttributeService.AttributeQueryCallback;
import org.alfresco.util.PropertyCheck;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.slf4j.event.Level;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.ApplicationEvent;
import org.springframework.extensions.surf.util.AbstractLifecycleBean;
public abstract class AbstractBootstrapService extends AbstractLifecycleBean implements BootstrapService {
public enum Scope {
None,
JMX,
ShardRegistry,
Custom;
static Scope caseInsensitiveValueOf(String value) {
for (Scope scope : Scope.values())
if (scope.toString().equalsIgnoreCase(value))
return scope;
return null;
}
}
private final Logger logger = LoggerFactory.getLogger(this.getClass());
private final Pattern rootKeyPattern = Pattern.compile("(.+)/.*");
@Autowired
@Qualifier("attributeService")
private AttributeService attributeService;
@Value("${inteligr8.attrcleaner.enabled}")
private boolean enabled;
@Value("${inteligr8.attrcleaner.log-level}")
private String logLevelRaw;
protected Level logLevel;
protected Scope scope;
protected Map> keyPatterns;
protected abstract String getRawScope();
protected abstract String getRawKeys();
@Override
protected void onBootstrap(ApplicationEvent aevent) {
if (!this.enabled) {
this.logger.info("Inteligr8 Attribute Cleaner module is disabled");
return;
}
this.logger.info("Inteligr8 Attribute Cleaner {} bootstrapping", this.getClass().getSimpleName());
if (this.validateAndNormalize())
this.execute();
}
@Override
protected void onShutdown(ApplicationEvent aevent) {
// do nothing
}
@Override
public boolean validateAndNormalize() {
this.logLevel = Level.valueOf(this.logLevelRaw.toUpperCase());
PropertyCheck.mandatory(this, "inteligr8.attrcleaner.log-level", this.logLevel);
this.scope = Scope.caseInsensitiveValueOf(this.getRawScope().replace("-", ""));
this.logger.trace("Attribute cleaner {} scope is {}", this.getClass().getSimpleName(), this.scope);
if (this.scope == null)
throw new IllegalArgumentException();
if (Scope.None.equals(this.scope)) {
this.logger.debug("Attribute cleaner {} feature is off", this.getClass().getSimpleName());
return false;
}
this.keyPatterns = new LinkedHashMap<>();
for (String keyRaw : this.getRawKeys().split(",")) {
this.logger.trace("Attribute cleaner {} key: {}", this.getClass().getSimpleName(), keyRaw);
if (keyRaw.length() == 0) {
this.logger.debug("Skipping empty key");
continue;
}
Matcher matcher = this.rootKeyPattern.matcher(keyRaw);
if (!matcher.find()) {
this.logger.warn("Key must have a root element; skipping: {}", keyRaw);
continue;
}
String rootKey = matcher.group(1).replace("\\.", ".");
Pattern keyPattern = Pattern.compile(keyRaw);
this.logger.debug("Validated key pattern: {} => {}", rootKey, keyPattern);
this.putAddToList(this.keyPatterns, rootKey, keyPattern);
}
return true;
}
@Override
public void execute() {
Map attributes = null;
switch (this.scope) {
case None:
throw new IllegalArgumentException();
case JMX:
attributes = this.queryJmx();
break;
case ShardRegistry:
attributes = this.queryShardRegistry();
break;
case Custom:
attributes = this.queryCustom();
break;
default:
throw new IllegalArgumentException();
}
this.logger.atLevel(this.logLevel).log("Queried {} Attributes: ", attributes.size());
for (Entry entry : attributes.entrySet()) {
this.execute(entry);
}
}
public abstract void execute(Entry entry);
private Map queryJmx() {
return this.queryAttrs(".PropertyBackedBeans");
}
private Map queryShardRegistry() {
Map attributes = new LinkedHashMap<>();
attributes.putAll(this.queryAttrs(".SHARD_STATE"));
attributes.putAll(this.queryAttrs(".SHARD_SUBSCRIPTION"));
return attributes;
}
private Map queryCustom() {
Map attributes = new LinkedHashMap<>();
AttributeQueryCallback aqc = new AttributeQueryCallback() {
@Override
public boolean handleAttribute(Long attrId, Serializable value, Serializable[] keys) {
String keysAsStr = StringUtils.stripEnd(StringUtils.join(keys, "/"), "/");
for (Entry> patterns : keyPatterns.entrySet()) {
for (Pattern pattern : patterns.getValue()) {
if (pattern.matcher(keysAsStr).matches()) {
logger.debug("{} matches attribute: {}", pattern, keysAsStr);
attributes.put(keys, value);
} else {
logger.trace("{} does not match attribute: {}", pattern, keysAsStr);
}
}
}
return true;
}
};
for (String rootKey : this.keyPatterns.keySet()) {
this.logger.debug("Querying for attributes with root key: {}", rootKey);
this.attributeService.getAttributes(aqc, rootKey);
}
return attributes;
}
private Map queryAttrs(Serializable... selectKeys) {
Map attributes = new LinkedHashMap<>();
AttributeQueryCallback aqc = new AttributeQueryCallback() {
@Override
public boolean handleAttribute(Long attrId, Serializable value, Serializable[] keys) {
logger.trace("Found attribute: {}", Arrays.toString(keys));
attributes.put(keys, value);
return true;
}
};
this.logger.debug("Querying for attributes with keys: {}", Arrays.toString(selectKeys));
this.attributeService.getAttributes(aqc, selectKeys);
return attributes;
}
@SuppressWarnings("unchecked")
private , V> void putAddToList(Map map, K key, V value) {
CV c = map.get(key);
if (c == null) {
c = (CV) new LinkedList();
map.put(key, c);
}
c.add(value);
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy