/** * Get the name of the method including the package path built from {@link Class#getCanonicalName()} and * {@link Method#getName()}. e.g. {@code com.fnproject.fn.api.MethodWrapper::getLongName} for this method. * * @return long method name */ default String getLongName() { return getTargetClass().getCanonicalName() + "::" + getTargetMethod().getName(); }
private void validateConfigurationMethods(MethodWrapper function) { // Function configuration methods must have a void return type. Arrays.stream(function.getTargetClass().getMethods()) .filter(this::isConfigurationMethod) .filter((m) -> !m.getReturnType().equals(Void.TYPE)) .forEach((m) -> { throw new FunctionConfigurationException("Configuration method '" + m.getName() + "' does not have a void return type"); }); // If target method is static, configuration methods cannot be non-static. if (Modifier.isStatic(function.getTargetMethod().getModifiers())) { Arrays.stream(function.getTargetClass().getMethods()) .filter(this::isConfigurationMethod) .filter((m) -> !(Modifier.isStatic(m.getModifiers()))) .forEach((m) -> { throw new FunctionConfigurationException("Configuration method '" + m.getName() + "' cannot be an instance method if the function method is a static method"); }); } }
static Class<?> resolveType(Type type, MethodWrapper src) { if (type instanceof Class) { return PrimitiveTypeResolver.resolve((Class<?>) type); } else if (type instanceof ParameterizedType) { return (Class<?>) ((ParameterizedType) type).getRawType(); } Class<?> resolvedType = TypeResolver.resolveRawArgument(type, src.getTargetClass()); if (resolvedType == TypeResolver.Unknown.class) { // TODO: Decide what exception to throw here throw new RuntimeException("Cannot infer type of method parameter"); } else { return resolvedType; } }
private void applyUserConfigurationMethod(MethodWrapper targetClass, FunctionRuntimeContext runtimeContext) { Arrays.stream(targetClass.getTargetClass().getMethods()) .filter(this::isConfigurationMethod) .sorted(Comparator.<Method>comparingInt((m) -> Modifier.isStatic(m.getModifiers()) ? 0 : 1) // run static methods first .thenComparing(Comparator.<Method>comparingInt((m) -> { // depth first in implementation int depth = 0; Class<?> cc = m.getDeclaringClass(); while (null != cc) { depth++; cc = cc.getSuperclass(); } return depth; }))) .forEach(configMethod -> { try { Optional<Object> fnInstance = runtimeContext.getInvokeInstance(); // Allow the runtime context parameter to be optional if (configMethod.getParameterCount() == 0) { configMethod.invoke(fnInstance.orElse(null)); } else { configMethod.invoke(fnInstance.orElse(null), runtimeContext); } } catch ( InvocationTargetException e){ throw new FunctionConfigurationException("Error invoking configuration method: " + configMethod.getName(), e.getCause()); } catch (IllegalAccessException e) { throw new FunctionConfigurationException("Error invoking configuration method: " + configMethod.getName(), e); } }); }
if (instance == null) { try { Constructor<?> constructors[] = getMethod().getTargetClass().getConstructors(); if (constructors.length == 1) { Constructor<?> ctor = constructors[0]; instance = ctor.newInstance(FunctionRuntimeContext.this); } else { if (getMethod().getTargetClass().getEnclosingClass() != null && !Modifier.isStatic(getMethod().getTargetClass().getModifiers())) { throw new FunctionClassInstantiationException("The function " + getMethod().getTargetClass() + " cannot be instantiated as it is a non-static inner class"); } else { throw new FunctionClassInstantiationException("The function " + getMethod().getTargetClass() + " cannot be instantiated as its constructor takes an unrecognized argument of type " + constructors[0].getParameterTypes()[0] + ". Function classes should have a single public constructor that takes either no arguments or a RuntimeContext argument"); throw new FunctionClassInstantiationException("The function " + getMethod().getTargetClass() + " cannot be instantiated as its constructor takes more than one argument. Function classes should have a single public constructor that takes either no arguments or a RuntimeContext argument"); throw new FunctionClassInstantiationException("The function " + getMethod().getTargetClass() + " cannot be instantiated as it has no public constructors. Function classes should have a single public constructor that takes either no arguments or a RuntimeContext argument"); } else { throw new FunctionClassInstantiationException("The function " + getMethod().getTargetClass() + " cannot be instantiated as it has multiple public constructors. Function classes should have a single public constructor that takes either no arguments or a RuntimeContext argument"); throw new FunctionClassInstantiationException("An error occurred in the function constructor while instantiating " + getMethod().getTargetClass(), e.getCause()); } catch (InstantiationException | IllegalAccessException e) { throw new FunctionClassInstantiationException("The function class " + getMethod().getTargetClass() + " could not be instantiated", e);
@Override public void initialize(RuntimeContext ctx) { ctx.addInvoker(new SpringCloudFunctionInvoker(ctx.getMethod().getTargetClass()),FunctionInvoker.Phase.Call); } }
FnFeature f = method.getTargetClass().getAnnotation(FnFeature.class); if (f != null) { enableFeature(runtimeContext, f); FnFeatures fs = method.getTargetClass().getAnnotation(FnFeatures.class); if (fs != null) { for (FnFeature fnFeature : fs.value()) {