/** * 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.falcon.util; import org.apache.falcon.monitors.Monitored; import org.apache.falcon.monitors.TimeTaken; import java.awt.*; import java.lang.annotation.Annotation; import java.lang.reflect.Method; import java.util.Collections; import java.util.HashMap; import java.util.Map; /** * Builds a cached of methods annotated with Monitored and params of methods * annotated with Dimension. */ public final class ResourcesReflectionUtil { private static final Map<String, MethodAnnotation> METHODS = new HashMap<String, MethodAnnotation>(); private ResourcesReflectionUtil() { } static { //TODO load these classes from properties file buildAnnotationsMapForClass("org.apache.falcon.resource.proxy.SchedulableEntityManagerProxy"); buildAnnotationsMapForClass("org.apache.falcon.resource.proxy.InstanceManagerProxy"); buildAnnotationsMapForClass("org.apache.falcon.resource.AbstractInstanceManager"); buildAnnotationsMapForClass("org.apache.falcon.service.FalconTopicSubscriber"); buildAnnotationsMapForClass("org.apache.falcon.aspect.GenericAlert"); } public static Map<Integer, String> getResourceDimensionsName(String methodName) { return METHODS.get(methodName) != null ? Collections.unmodifiableMap(METHODS.get(methodName).params) : null; } public static String getResourceMonitorName(String methodName) { return METHODS.get(methodName) != null ? METHODS.get(methodName).monitoredName : null; } public static Integer getResourceTimeTakenName(String methodName) { return METHODS.get(methodName) != null ? METHODS.get(methodName).timeTakenArgIndex : null; } /** * Holder class for method annotation. */ public static class MethodAnnotation { private String monitoredName; // argument <index,DimensionValue> private Map<Integer, String> params = new HashMap<Integer, String>(); //to override time taken by an api private Integer timeTakenArgIndex; @Override public String toString() { return "{" + monitoredName + "[" + params.toString() + "]" + "}"; } } private static void buildAnnotationsMapForClass(String className) { Class clazz; try { clazz = ResourcesReflectionUtil.class. getClassLoader().loadClass(className); } catch (ClassNotFoundException e) { throw new RuntimeException("Unable to load class " + className, e); } Method[] declMethods = clazz.getMethods(); // scan every method for (Method declMethod : declMethods) { Annotation[] methodAnnots = declMethod.getDeclaredAnnotations(); // scan every annotation on method for (Annotation methodAnnot : methodAnnots) { if (methodAnnot.annotationType().getSimpleName() .equals(Monitored.class.getSimpleName())) { MethodAnnotation annotation = new MethodAnnotation(); annotation.monitoredName = getAnnotationValue( methodAnnot, "event"); Annotation[][] paramAnnots = declMethod .getParameterAnnotations(); // scan every param annotation.params = getDeclaredParamAnnots(paramAnnots, annotation); METHODS.put( clazz.getSimpleName() + "." + declMethod.getName(), annotation); } } } } private static Map<Integer, String> getDeclaredParamAnnots( Annotation[][] paramAnnots, MethodAnnotation annotation) { Map<Integer, String> params = new HashMap<Integer, String>(); for (int i = 0; i < paramAnnots.length; i++) { for (int j = 0; j < paramAnnots[i].length; j++) { if (paramAnnots[i][j].annotationType().getSimpleName() .equals(Dimension.class.getSimpleName())) { params.put(i, getAnnotationValue(paramAnnots[i][j], "value")); } if (paramAnnots[i][j].annotationType().getSimpleName() .equals(TimeTaken.class.getSimpleName())) { annotation.timeTakenArgIndex = i; } } } return params; } private static String getAnnotationValue(Annotation annotation, String attributeName) { String value = null; if (annotation != null) { try { value = (String) annotation.annotationType() .getMethod(attributeName).invoke(annotation); } catch (Exception ignore) { ignore.printStackTrace(); } } return value; } }