blob: 69290368417778667e9add2c91252e3c28bac97c [file] [log] [blame]
/**
* 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.metrics.core.timeline.aggregators;
import org.apache.ambari.metrics.webapp.TimelineWebServices;
import java.util.Arrays;
/**
* Is used to determine metrics aggregate table.
*
* @see org.apache.ambari.metrics.webapp.TimelineWebServices#getTimelineMetrics
*/
public class Function {
public static Function DEFAULT_VALUE_FUNCTION = new Function(ReadFunction.VALUE, null);
private static final String SUFFIX_SEPARATOR = "\\._";
private ReadFunction readFunction = ReadFunction.VALUE;
private PostProcessingFunction postProcessingFunction = null;
public Function() {
}
public Function(ReadFunction readFunction,
PostProcessingFunction ppFunction){
if (readFunction!=null){
this.readFunction = readFunction ;
}
this.postProcessingFunction = ppFunction;
}
/**
* Segregate post processing function eg: rate from aggregate function,
* example: avg, in any order
* @param metricName metric name from request
* @return @Function
*/
public static Function fromMetricName(String metricName) {
// gets postprocessing, and aggregation function
// ex. Metric._rate._avg
String[] parts = metricName.split(SUFFIX_SEPARATOR);
ReadFunction readFunction = ReadFunction.VALUE;
PostProcessingFunction ppFunction = null;
if (parts.length <= 1) {
return new Function(readFunction, null);
}
if (parts.length > 3) {
throw new IllegalArgumentException("Invalid number of functions specified.");
}
// Parse functions
boolean isSuccessful = false; // Best effort
for (String part : parts) {
if (ReadFunction.isPresent(part)) {
readFunction = ReadFunction.getFunction(part);
isSuccessful = true;
}
if (PostProcessingFunction.isPresent(part)) {
ppFunction = PostProcessingFunction.getFunction(part);
isSuccessful = true;
}
}
// Throw exception if parsing failed
if (!isSuccessful) {
throw new FunctionFormatException("Could not parse provided functions: " +
"" + Arrays.asList(parts));
}
return new Function(readFunction, ppFunction);
}
public String getSuffix(){
return (postProcessingFunction == null)? readFunction.getSuffix() :
postProcessingFunction.getSuffix() + readFunction.getSuffix();
}
public ReadFunction getReadFunction() {
return readFunction;
}
@Override
public String toString() {
return "Function{" +
"readFunction=" + readFunction +
", postProcessingFunction=" + postProcessingFunction +
'}';
}
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (!(o instanceof Function)) return false;
Function function = (Function) o;
return postProcessingFunction == function.postProcessingFunction
&& readFunction == function.readFunction;
}
@Override
public int hashCode() {
int result = readFunction.hashCode();
result = 31 * result + (postProcessingFunction != null ?
postProcessingFunction.hashCode() : 0);
return result;
}
public enum PostProcessingFunction {
NONE(""),
RATE("._rate"),
DIFF("._diff");
PostProcessingFunction(String suffix){
this.suffix = suffix;
}
private String suffix = "";
public String getSuffix(){
return suffix;
}
public static boolean isPresent(String functionName) {
try {
PostProcessingFunction.valueOf(functionName.toUpperCase());
} catch (IllegalArgumentException e) {
return false;
}
return true;
}
public static PostProcessingFunction getFunction(String functionName) throws FunctionFormatException {
if (functionName == null) {
return NONE;
}
try {
return PostProcessingFunction.valueOf(functionName.toUpperCase());
} catch (IllegalArgumentException e) {
throw new FunctionFormatException("Function should be ._rate", e);
}
}
}
public enum ReadFunction {
VALUE(""),
AVG("._avg"),
MIN("._min"),
MAX("._max"),
SUM("._sum");
private final String suffix;
ReadFunction(String suffix){
this.suffix = suffix;
}
public String getSuffix() {
return suffix;
}
public static boolean isPresent(String functionName) {
try {
ReadFunction.valueOf(functionName.toUpperCase());
} catch (IllegalArgumentException e) {
return false;
}
return true;
}
public static ReadFunction getFunction(String functionName) throws FunctionFormatException {
if (functionName == null) {
return VALUE;
}
try {
return ReadFunction.valueOf(functionName.toUpperCase());
} catch (IllegalArgumentException e) {
throw new FunctionFormatException(
"Function should be sum, avg, min, max. Got " + functionName, e);
}
}
}
public static class FunctionFormatException extends IllegalArgumentException {
public FunctionFormatException(String message) {
super(message);
}
public FunctionFormatException(String message, Throwable cause) {
super(message, cause);
}
}
}