/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
package org.apache.ambari.logfeeder.common;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import org.apache.ambari.logfeeder.metrics.MetricData;
import org.apache.ambari.logfeeder.util.LogFeederUtil;
import org.apache.commons.collections.MapUtils;
import org.apache.commons.lang3.StringUtils;
import org.apache.log4j.Logger;
import org.apache.log4j.Priority;
public abstract class ConfigBlock {
private static final Logger LOG = Logger.getLogger(ConfigBlock.class);
private boolean drain = false;
protected Map<String, Object> configs;
protected Map<String, String> contextFields = new HashMap<String, String>();
public MetricData statMetric = new MetricData(getStatMetricName(), false);
protected String getStatMetricName() {
return null;
}
public ConfigBlock() {
}
/**
* Used while logging. Keep it short and meaningful
*/
public abstract String getShortDescription();
/**
* Every implementor need to give name to the thread they create
*/
public String getNameForThread() {
return this.getClass().getSimpleName();
}
public void addMetricsContainers(List<MetricData> metricsList) {
metricsList.add(statMetric);
}
/**
* This method needs to be overwritten by deriving classes.
*/
public void init() throws Exception {
}
public void loadConfig(Map<String, Object> map) {
configs = LogFeederUtil.cloneObject(map);
Map<String, String> nvList = getNVList("add_fields");
if (nvList != null) {
contextFields.putAll(nvList);
}
}
public Map<String, Object> getConfigs() {
return configs;
}
@SuppressWarnings("unchecked")
public boolean isEnabled() {
boolean isEnabled = getBooleanValue("is_enabled", true);
if (isEnabled) {
// Let's check for static conditions
Map<String, Object> conditions = (Map<String, Object>) configs.get("conditions");
boolean allow = true;
if (MapUtils.isNotEmpty(conditions)) {
allow = false;
for (String conditionType : conditions.keySet()) {
if (conditionType.equalsIgnoreCase("fields")) {
Map<String, Object> fields = (Map<String, Object>) conditions.get("fields");
for (String fieldName : fields.keySet()) {
Object values = fields.get(fieldName);
if (values instanceof String) {
allow = isFieldConditionMatch(fieldName, (String) values);
} else {
List<String> listValues = (List<String>) values;
for (String stringValue : listValues) {
allow = isFieldConditionMatch(fieldName, stringValue);
if (allow) {
break;
}
}
}
if (allow) {
break;
}
}
}
if (allow) {
break;
}
}
isEnabled = allow;
}
}
return isEnabled;
}
public boolean isFieldConditionMatch(String fieldName, String stringValue) {
boolean allow = false;
String fieldValue = (String) configs.get(fieldName);
if (fieldValue != null && fieldValue.equalsIgnoreCase(stringValue)) {
allow = true;
} else {
@SuppressWarnings("unchecked")
Map<String, Object> addFields = (Map<String, Object>) configs.get("add_fields");
if (addFields != null && addFields.get(fieldName) != null) {
String addFieldValue = (String) addFields.get(fieldName);
if (stringValue.equalsIgnoreCase(addFieldValue)) {
allow = true;
}
}
}
return allow;
}
@SuppressWarnings("unchecked")
public Map<String, String> getNVList(String key) {
return (Map<String, String>) configs.get(key);
}
public String getStringValue(String key) {
Object value = configs.get(key);
if (value != null && value.toString().equalsIgnoreCase("none")) {
value = null;
}
if (value != null) {
return value.toString();
}
return null;
}
public String getStringValue(String key, String defaultValue) {
Object value = configs.get(key);
if (value != null && value.toString().equalsIgnoreCase("none")) {
value = null;
}
if (value != null) {
return value.toString();
}
return defaultValue;
}
public Object getConfigValue(String key) {
return configs.get(key);
}
public boolean getBooleanValue(String key, boolean defaultValue) {
String strValue = getStringValue(key);
boolean retValue = defaultValue;
if (!StringUtils.isEmpty(strValue)) {
retValue = (strValue.equalsIgnoreCase("true") || strValue.equalsIgnoreCase("yes"));
}
return retValue;
}
public int getIntValue(String key, int defaultValue) {
String strValue = getStringValue(key);
int retValue = defaultValue;
if (!StringUtils.isEmpty(strValue)) {
try {
retValue = Integer.parseInt(strValue);
} catch (Throwable t) {
LOG.error("Error parsing integer value. key=" + key + ", value=" + strValue);
}
}
return retValue;
}
public long getLongValue(String key, long defaultValue) {
String strValue = getStringValue(key);
Long retValue = defaultValue;
if (!StringUtils.isEmpty(strValue)) {
try {
retValue = Long.parseLong(strValue);
} catch (Throwable t) {
LOG.error("Error parsing long value. key=" + key + ", value=" + strValue);
}
}
return retValue;
}
public Map<String, String> getContextFields() {
return contextFields;
}
public void incrementStat(int count) {
statMetric.value += count;
}
public void logStatForMetric(MetricData metric, String prefixStr) {
LogFeederUtil.logStatForMetric(metric, prefixStr, ", key=" + getShortDescription());
}
public synchronized void logStat() {
logStatForMetric(statMetric, "Stat");
}
public boolean logConfigs(Priority level) {
if (level.toInt() == Priority.INFO_INT && !LOG.isInfoEnabled()) {
return false;
}
if (level.toInt() == Priority.DEBUG_INT && !LOG.isDebugEnabled()) {
return false;
}
LOG.log(level, "Printing configuration Block=" + getShortDescription());
LOG.log(level, "configs=" + configs);
LOG.log(level, "contextFields=" + contextFields);
return true;
}
public boolean isDrain() {
return drain;
}
public void setDrain(boolean drain) {
this.drain = drain;
}
}