| /** |
| * 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); |
| } |
| } |
| |
| } |