You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@nifi.apache.org by mc...@apache.org on 2015/01/26 15:19:58 UTC

[34/48] incubator-nifi git commit: NIFI-6: Rebase from develop to include renaming of directory structure

http://git-wip-us.apache.org/repos/asf/incubator-nifi/blob/716e03b5/nifi/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-framework-core/src/main/java/org/apache/nifi/util/ReflectionUtils.java
----------------------------------------------------------------------
diff --cc nifi/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-framework-core/src/main/java/org/apache/nifi/util/ReflectionUtils.java
index 0000000,e15e00a..a8a4596
mode 000000,100644..100644
--- a/nifi/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-framework-core/src/main/java/org/apache/nifi/util/ReflectionUtils.java
+++ b/nifi/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-framework-core/src/main/java/org/apache/nifi/util/ReflectionUtils.java
@@@ -1,0 -1,157 +1,285 @@@
+ /*
+  * 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.nifi.util;
+ 
+ import java.lang.annotation.Annotation;
+ import java.lang.reflect.InvocationTargetException;
+ import java.lang.reflect.Method;
++import java.util.ArrayList;
++import java.util.List;
++
++import org.apache.nifi.logging.ProcessorLog;
+ import org.slf4j.Logger;
+ import org.slf4j.LoggerFactory;
+ 
+ public class ReflectionUtils {
+ 
+     private final static Logger LOG = LoggerFactory.getLogger(ReflectionUtils.class);
+ 
+     /**
+      * Invokes all methods on the given instance that have been annotated with
+      * the given Annotation. If the signature of the method that is defined in
+      * <code>instance</code> uses 1 or more parameters, those parameters must be
+      * specified by the <code>args</code> parameter. However, if more arguments
+      * are supplied by the <code>args</code> parameter than needed, the extra
+      * arguments will be ignored.
+      *
+      * @param annotation
+      * @param instance
+      * @param args
+      * @throws InvocationTargetException
+      * @throws IllegalArgumentException
+      * @throws IllegalAccessException
+      */
+     public static void invokeMethodsWithAnnotation(final Class<? extends Annotation> annotation, final Object instance, final Object... args) throws IllegalAccessException, IllegalArgumentException, InvocationTargetException {
 -        try {
 -            for (final Method method : instance.getClass().getMethods()) {
 -                if (method.isAnnotationPresent(annotation)) {
 -                    final boolean isAccessible = method.isAccessible();
 -                    method.setAccessible(true);
 -    
 -                    try {
 -                        final Class<?>[] argumentTypes = method.getParameterTypes();
 -                        if (argumentTypes.length > args.length) {
 -                            throw new IllegalArgumentException(String.format("Unable to invoke method %1$s on %2$s because method expects %3$s parameters but only %4$s were given",
 -                                    method.getName(), instance, argumentTypes.length, args.length));
 -                        }
++        invokeMethodsWithAnnotation(annotation, null, instance, args);
++    }
++
+     
 -                        for (int i = 0; i < argumentTypes.length; i++) {
 -                            final Class<?> argType = argumentTypes[i];
 -                            if (!argType.isAssignableFrom(args[i].getClass())) {
 -                                throw new IllegalArgumentException(String.format(
 -                                        "Unable to invoke method %1$s on %2$s because method parameter %3$s is expected to be of type %4$s but argument passed was of type %5$s",
 -                                        method.getName(), instance, i, argType, args[i].getClass()));
++    /**
++     * Invokes all methods on the given instance that have been annotated with
++     * the given preferredAnnotation and if no such method exists will invoke all
++     * methods on the given instance that have been annotated with the given
++     * alternateAnnotation, if any exists. If the signature of the method that is defined in
++     * <code>instance</code> uses 1 or more parameters, those parameters must be
++     * specified by the <code>args</code> parameter. However, if more arguments
++     * are supplied by the <code>args</code> parameter than needed, the extra
++     * arguments will be ignored.
++     *
++     * @param preferredAnnotation
++     * @param alternateAnnotation
++     * @param instance
++     * @param args
++     * @throws InvocationTargetException
++     * @throws IllegalArgumentException
++     * @throws IllegalAccessException
++     */
++    public static void invokeMethodsWithAnnotation(final Class<? extends Annotation> preferredAnnotation, final Class<? extends Annotation> alternateAnnotation, final Object instance, final Object... args) throws IllegalAccessException, IllegalArgumentException, InvocationTargetException {
++        final List<Class<? extends Annotation>> annotationClasses = new ArrayList<>(alternateAnnotation == null ? 1 : 2);
++        annotationClasses.add(preferredAnnotation);
++        if ( alternateAnnotation != null ) {
++            annotationClasses.add(alternateAnnotation);
++        }
++        
++        boolean annotationFound = false;
++        for ( final Class<? extends Annotation> annotationClass : annotationClasses ) {
++            if ( annotationFound ) {
++                break;
++            }
++            
++            try {
++                for (final Method method : instance.getClass().getMethods()) {
++                    if (method.isAnnotationPresent(annotationClass)) {
++                        annotationFound = true;
++                        final boolean isAccessible = method.isAccessible();
++                        method.setAccessible(true);
++        
++                        try {
++                            final Class<?>[] argumentTypes = method.getParameterTypes();
++                            if (argumentTypes.length > args.length) {
++                                throw new IllegalArgumentException(String.format("Unable to invoke method %1$s on %2$s because method expects %3$s parameters but only %4$s were given",
++                                        method.getName(), instance, argumentTypes.length, args.length));
+                             }
 -                        }
 -    
 -                        if (argumentTypes.length == args.length) {
 -                            method.invoke(instance, args);
 -                        } else {
 -                            final Object[] argsToPass = new Object[argumentTypes.length];
 -                            for (int i = 0; i < argsToPass.length; i++) {
 -                                argsToPass[i] = args[i];
++        
++                            for (int i = 0; i < argumentTypes.length; i++) {
++                                final Class<?> argType = argumentTypes[i];
++                                if (!argType.isAssignableFrom(args[i].getClass())) {
++                                    throw new IllegalArgumentException(String.format(
++                                            "Unable to invoke method %1$s on %2$s because method parameter %3$s is expected to be of type %4$s but argument passed was of type %5$s",
++                                            method.getName(), instance, i, argType, args[i].getClass()));
++                                }
++                            }
++        
++                            if (argumentTypes.length == args.length) {
++                                method.invoke(instance, args);
++                            } else {
++                                final Object[] argsToPass = new Object[argumentTypes.length];
++                                for (int i = 0; i < argsToPass.length; i++) {
++                                    argsToPass[i] = args[i];
++                                }
++        
++                                method.invoke(instance, argsToPass);
++                            }
++                        } finally {
++                            if (!isAccessible) {
++                                method.setAccessible(false);
+                             }
 -    
 -                            method.invoke(instance, argsToPass);
 -                        }
 -                    } finally {
 -                        if (!isAccessible) {
 -                            method.setAccessible(false);
+                         }
+                     }
+                 }
 -            }
 -        } catch (final InvocationTargetException ite) {
 -            if ( ite.getCause() instanceof RuntimeException ) {
 -                throw (RuntimeException) ite.getCause();
 -            } else {
 -                throw ite;
++            } catch (final InvocationTargetException ite) {
++                if ( ite.getCause() instanceof RuntimeException ) {
++                    throw (RuntimeException) ite.getCause();
++                } else {
++                    throw ite;
++                }
+             }
+         }
+     }
+ 
++    
+     /**
+      * Invokes all methods on the given instance that have been annotated with
+      * the given Annotation. If the signature of the method that is defined in
+      * <code>instance</code> uses 1 or more parameters, those parameters must be
+      * specified by the <code>args</code> parameter. However, if more arguments
+      * are supplied by the <code>args</code> parameter than needed, the extra
+      * arguments will be ignored.
+      *
+      * @param annotation
+      * @param instance
+      * @param args
+      * @return <code>true</code> if all appropriate methods were invoked and
+      * returned without throwing an Exception, <code>false</code> if one of the
+      * methods threw an Exception or could not be invoked; if <code>false</code>
+      * is returned, an error will have been logged.
+      */
+     public static boolean quietlyInvokeMethodsWithAnnotation(final Class<? extends Annotation> annotation, final Object instance, final Object... args) {
 -        for (final Method method : instance.getClass().getMethods()) {
 -            if (method.isAnnotationPresent(annotation)) {
 -                final boolean isAccessible = method.isAccessible();
 -                method.setAccessible(true);
 -
 -                try {
 -                    final Class<?>[] argumentTypes = method.getParameterTypes();
 -                    if (argumentTypes.length > args.length) {
 -                        LOG.error("Unable to invoke method {} on {} because method expects {} parameters but only {} were given",
 -                                new Object[]{method.getName(), instance, argumentTypes.length, args.length});
 -                        return false;
 -                    }
 -
 -                    for (int i = 0; i < argumentTypes.length; i++) {
 -                        final Class<?> argType = argumentTypes[i];
 -                        if (!argType.isAssignableFrom(args[i].getClass())) {
 -                            LOG.error("Unable to invoke method {} on {} because method parameter {} is expected to be of type {} but argument passed was of type {}",
 -                                    new Object[]{method.getName(), instance, i, argType, args[i].getClass()});
++        return quietlyInvokeMethodsWithAnnotation(annotation, null, instance, null, args);
++    }
++    
++    
++    /**
++     * Invokes all methods on the given instance that have been annotated with
++     * the given Annotation. If the signature of the method that is defined in
++     * <code>instance</code> uses 1 or more parameters, those parameters must be
++     * specified by the <code>args</code> parameter. However, if more arguments
++     * are supplied by the <code>args</code> parameter than needed, the extra
++     * arguments will be ignored.
++     *
++     * @param annotation
++     * @param instance
++     * @param args
++     * @return <code>true</code> if all appropriate methods were invoked and
++     * returned without throwing an Exception, <code>false</code> if one of the
++     * methods threw an Exception or could not be invoked; if <code>false</code>
++     * is returned, an error will have been logged.
++     */
++    public static boolean quietlyInvokeMethodsWithAnnotation(final Class<? extends Annotation> annotation, final Object instance, final ProcessorLog logger, final Object... args) {
++        return quietlyInvokeMethodsWithAnnotation(annotation, null, instance, logger, args);
++    }
++    
++    
++    /**
++     * Invokes all methods on the given instance that have been annotated with
++     * the given preferredAnnotation and if no such method exists will invoke all methods
++     * on the given instance that have been annotated with the given
++     * alternateAnnotation, if any exists. If the signature of the method that is defined in
++     * <code>instance</code> uses 1 or more parameters, those parameters must be
++     * specified by the <code>args</code> parameter. However, if more arguments
++     * are supplied by the <code>args</code> parameter than needed, the extra
++     * arguments will be ignored.
++     *
++     * @param preferredAnnotation
++     * @param alternateAnnotation
++     * @param instance
++     * @param logger the ProcessorLog to use for logging any errors. If null, will use own logger, but that will not generate bulletins
++     *          or easily tie to the Processor's log messages.
++     * @param args
++     * @return <code>true</code> if all appropriate methods were invoked and
++     * returned without throwing an Exception, <code>false</code> if one of the
++     * methods threw an Exception or could not be invoked; if <code>false</code>
++     * is returned, an error will have been logged.
++     */
++    public static boolean quietlyInvokeMethodsWithAnnotation(final Class<? extends Annotation> preferredAnnotation, final Class<? extends Annotation> alternateAnnotation, final Object instance, final ProcessorLog logger, final Object... args) {
++        final List<Class<? extends Annotation>> annotationClasses = new ArrayList<>(alternateAnnotation == null ? 1 : 2);
++        annotationClasses.add(preferredAnnotation);
++        if ( alternateAnnotation != null ) {
++            annotationClasses.add(alternateAnnotation);
++        }
++        
++        boolean annotationFound = false;
++        for ( final Class<? extends Annotation> annotationClass : annotationClasses ) {
++            if ( annotationFound ) {
++                break;
++            }
++            
++            for (final Method method : instance.getClass().getMethods()) {
++                if (method.isAnnotationPresent(annotationClass)) {
++                    annotationFound = true;
++                    
++                    final boolean isAccessible = method.isAccessible();
++                    method.setAccessible(true);
++    
++                    try {
++                        final Class<?>[] argumentTypes = method.getParameterTypes();
++                        if (argumentTypes.length > args.length) {
++                            if ( logger == null ) {
++                                LOG.error("Unable to invoke method {} on {} because method expects {} parameters but only {} were given",
++                                    new Object[]{method.getName(), instance, argumentTypes.length, args.length});
++                            } else {
++                                logger.error("Unable to invoke method {} on {} because method expects {} parameters but only {} were given",
++                                        new Object[]{method.getName(), instance, argumentTypes.length, args.length});
++                            }
++                            
+                             return false;
+                         }
 -                    }
 -
 -                    try {
 -                        if (argumentTypes.length == args.length) {
 -                            method.invoke(instance, args);
 -                        } else {
 -                            final Object[] argsToPass = new Object[argumentTypes.length];
 -                            for (int i = 0; i < argsToPass.length; i++) {
 -                                argsToPass[i] = args[i];
++    
++                        for (int i = 0; i < argumentTypes.length; i++) {
++                            final Class<?> argType = argumentTypes[i];
++                            if (!argType.isAssignableFrom(args[i].getClass())) {
++                                if ( logger == null ) {
++                                    LOG.error("Unable to invoke method {} on {} because method parameter {} is expected to be of type {} but argument passed was of type {}",
++                                        new Object[]{method.getName(), instance, i, argType, args[i].getClass()});
++                                } else {
++                                    logger.error("Unable to invoke method {} on {} because method parameter {} is expected to be of type {} but argument passed was of type {}",
++                                            new Object[]{method.getName(), instance, i, argType, args[i].getClass()});
++                                }
++                                
++                                return false;
+                             }
 -
 -                            method.invoke(instance, argsToPass);
+                         }
 -                    } catch (final IllegalAccessException | IllegalArgumentException | InvocationTargetException t) {
 -                        LOG.error("Unable to invoke method {} on {} due to {}", new Object[]{method.getName(), instance, t});
 -                        LOG.error("", t);
 -                        return false;
 -                    }
 -                } finally {
 -                    if (!isAccessible) {
 -                        method.setAccessible(false);
++    
++                        try {
++                            if (argumentTypes.length == args.length) {
++                                method.invoke(instance, args);
++                            } else {
++                                final Object[] argsToPass = new Object[argumentTypes.length];
++                                for (int i = 0; i < argsToPass.length; i++) {
++                                    argsToPass[i] = args[i];
++                                }
++    
++                                method.invoke(instance, argsToPass);
++                            }
++                        } catch (final InvocationTargetException ite) {
++                            if ( logger == null ) {
++                                LOG.error("Unable to invoke method {} on {} due to {}", new Object[]{method.getName(), instance, ite.getCause()});
++                                LOG.error("", ite.getCause());
++                            } else {
++                                logger.error("Unable to invoke method {} on {} due to {}", new Object[]{method.getName(), instance, ite.getCause()});
++                            }
++                        } catch (final IllegalAccessException | IllegalArgumentException t) {
++                            if ( logger == null ) {
++                                LOG.error("Unable to invoke method {} on {} due to {}", new Object[]{method.getName(), instance, t});
++                                LOG.error("", t);
++                            } else {
++                                logger.error("Unable to invoke method {} on {} due to {}", new Object[]{method.getName(), instance, t});
++                            }
++                            
++                            return false;
++                        }
++                    } finally {
++                        if (!isAccessible) {
++                            method.setAccessible(false);
++                        }
+                     }
+                 }
+             }
+         }
+         return true;
+     }
+ }

http://git-wip-us.apache.org/repos/asf/incubator-nifi/blob/716e03b5/nifi/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-framework-core/src/test/java/org/apache/nifi/test/processors/StubAttributeLoggerProcessor.java
----------------------------------------------------------------------
diff --cc nifi/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-framework-core/src/test/java/org/apache/nifi/test/processors/StubAttributeLoggerProcessor.java
index 0000000,73d38e8..d49db29
mode 000000,100644..100644
--- a/nifi/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-framework-core/src/test/java/org/apache/nifi/test/processors/StubAttributeLoggerProcessor.java
+++ b/nifi/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-framework-core/src/test/java/org/apache/nifi/test/processors/StubAttributeLoggerProcessor.java
@@@ -1,0 -1,111 +1,111 @@@
+ /*
+  * 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.nifi.test.processors;
+ 
+ import java.util.ArrayList;
+ import java.util.Collections;
+ import java.util.HashSet;
+ import java.util.List;
+ import java.util.Set;
+ 
++import org.apache.nifi.annotation.behavior.SideEffectFree;
+ import org.apache.nifi.components.PropertyDescriptor;
+ import org.apache.nifi.processor.AbstractProcessor;
+ import org.apache.nifi.processor.ProcessContext;
+ import org.apache.nifi.processor.ProcessSession;
+ import org.apache.nifi.processor.ProcessorInitializationContext;
+ import org.apache.nifi.processor.Relationship;
 -import org.apache.nifi.processor.annotation.SideEffectFree;
+ 
+ @SideEffectFree
+ public class StubAttributeLoggerProcessor extends AbstractProcessor {
+ 
+     //@formatter:off
+     public static final PropertyDescriptor LOG_LEVEL = new PropertyDescriptor.Builder()
+             .required(false)
+             .description("log.level")
+             .defaultValue("debug")
+             .name("log.level")
+             .allowableValues("trace", "info", "warn", "debug", "error")
+             .sensitive(false)
+             .build();
+     public static final PropertyDescriptor ATTRIBUTES_TO_LOG_CSV = new PropertyDescriptor.Builder()
+             .required(false)
+             .description("attributes.to.log.csv")
+             .name("attributes.to.log.csv")
+             .sensitive(false)
+             .build();
+     public static final PropertyDescriptor ATTRIBUTES_TO_IGNORE_CSV = new PropertyDescriptor.Builder()
+             .required(false)
+             .description("attributes.to.ignore.csv")
+             .name("attributes.to.ignore.csv")
+             .sensitive(false)
+             .build();
+     public static final PropertyDescriptor LOG_PAYLOAD = new PropertyDescriptor.Builder()
+             .required(false)
+             .description("log.payload")
+             .defaultValue("false")
+             .allowableValues("true", "false")
+             .name("log.payload")
+             .sensitive(false)
+             .build();
+     // @formatter:on
+ 
+     public static enum DebugLevels {
+ 
+         trace, info, warn, debug, error
+     }
+ 
+     public static final long ONE_MB = 1024 * 1024;
+     private final Set<Relationship> relationships;
+     public static final Relationship REL_SUCCESS = new Relationship.Builder().description("success").name("success").build();
+ 
+     private final List<PropertyDescriptor> supportedDescriptors;
+ 
+     public StubAttributeLoggerProcessor() {
+         // relationships
+         final Set<Relationship> procRels = new HashSet<>();
+         procRels.add(REL_SUCCESS);
+         relationships = Collections.unmodifiableSet(procRels);
+ 
+         // descriptors
+         final List<PropertyDescriptor> supDescriptors = new ArrayList<>();
+         supDescriptors.add(ATTRIBUTES_TO_IGNORE_CSV);
+         supDescriptors.add(ATTRIBUTES_TO_LOG_CSV);
+         supDescriptors.add(LOG_PAYLOAD);
+         supDescriptors.add(LOG_LEVEL);
+         supportedDescriptors = Collections.unmodifiableList(supDescriptors);
+     }
+ 
+     @Override
+     public Set<Relationship> getRelationships() {
+         return relationships;
+     }
+ 
+     @Override
+     protected List<PropertyDescriptor> getSupportedPropertyDescriptors() {
+         return supportedDescriptors;
+     }
+ 
+     @Override
+     public void onTrigger(final ProcessContext context, final ProcessSession session) {
+     }
+ 
+     @Override
+     protected void init(final ProcessorInitializationContext context) {
+     }
+ 
+ }