Skip to content

Simplifies the messy logics on paramter resolving #730

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 1 commit into
base: feature/sdk-binding
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion endtoendtests/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<java.version>1.8</java.version>
<azure.functions.maven.plugin.version>1.18.0</azure.functions.maven.plugin.version>
<azure.functions.java.library.version>3.0.0-SNAPSHOT</azure.functions.java.library.version>
<azure.functions.java.library.version>3.0.0</azure.functions.java.library.version>
<durabletask.azure.functions>1.0.0-beta.1</durabletask.azure.functions>
<functionAppName>azure-functions-java-endtoendtests</functionAppName>
<functionAppRegion>westus</functionAppRegion>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@

import com.microsoft.azure.functions.worker.broker.*;
import com.microsoft.azure.functions.worker.handler.*;
import com.microsoft.azure.functions.worker.reflect.*;
import com.microsoft.azure.functions.worker.classloader.*;
import com.microsoft.azure.functions.rpc.messages.*;

/**
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,12 +6,11 @@
import java.util.List;
import java.util.Map;
import java.util.Optional;
import java.util.UUID;

import com.microsoft.azure.functions.ExecutionContext;
import com.microsoft.azure.functions.rpc.messages.ParameterBinding;
import com.microsoft.azure.functions.rpc.messages.TypedData;
import com.microsoft.azure.functions.worker.broker.CoreTypeResolver;
import com.microsoft.azure.functions.worker.converter.CoreTypeConverter;

import org.apache.commons.lang3.exception.ExceptionUtils;

Expand All @@ -21,16 +20,22 @@
* Thread-safety: Single thread.
*/
public final class BindingDataStore {

private final Map<String, DataTarget> targets;
private final Map<String, DataSource<?>> inputSources;
private final Map<Type, DataSource<?>> otherSources;
private final Map<String, DataSource<?>> metadataSources;
private Map<String, BindingDefinition> definitions;
public static final String RETURN_NAME = "$return";

public BindingDataStore() {
this.targets = new HashMap<>();
this.inputSources = new HashMap<>();
this.otherSources = new HashMap<>();
this.metadataSources = new HashMap<>();
this.promotedTargets = null;
}

///////////////////////// region Input Binding Data

//Logics for input Binding Data
public void addParameterSources(List<ParameterBinding> parameters) {
assert parameters != null;
for (ParameterBinding parameter : parameters) {
Expand Down Expand Up @@ -92,24 +97,21 @@ private static DataSource<?> rpcSourceFromParameter(ParameterBinding parameter)
return rpcSourceFromTypedData(parameter.getName(), parameter.getData());
}

///////////////////////// end region Input Binding Data

///////////////////////// region Output Binding Data

public List<ParameterBinding> getOutputParameterBindings(boolean excludeReturn) throws Exception {
//Logics for output Binding Data
public List<ParameterBinding> getOutputParameterBindings() throws Exception {
List<ParameterBinding> bindings = new ArrayList<>();
for (Map.Entry<String, DataTarget> entry : this.getTarget(this.promotedTargets).entrySet()) {
if (!excludeReturn || !entry.getKey().equals(RETURN_NAME)) {
entry.getValue().computeFromValue().ifPresent(data ->
bindings.add(ParameterBinding.newBuilder().setName(entry.getKey()).setData(data).build())
);
}
for (String key : this.targets.keySet()) {
if (key.equals(RETURN_NAME)) continue;
DataTarget dataTarget = this.targets.get(key);
dataTarget.computeFromValue().ifPresent(data ->
bindings.add(ParameterBinding.newBuilder().setName(key).setData(data).build()));
}
return bindings;
}

public Optional<TypedData> getDataTargetTypedValue(String name) throws Exception{
return Optional.ofNullable(this.getTarget(this.promotedTargets).get(name)).map(o -> {
return Optional.ofNullable(this.targets.get(name)).map(o -> {
try {
return o.computeFromValue().orElse(null);
} catch (Exception ex) {
Expand All @@ -119,48 +121,37 @@ public Optional<TypedData> getDataTargetTypedValue(String name) throws Exception
});
}

public Optional<BindingData> getOrAddDataTarget(UUID outputId, String name, Type target, boolean hasImplicitOutput) {
public Optional<BindingData> getOrAddDataTarget(String name, Type target, boolean hasImplicitOutput) {
DataTarget output = null;
if (this.isDataTargetValid(name, target)) {
output = this.getTarget(outputId).get(name);
output = this.targets.get(name);
if (output == null && (this.isDefinitionOutput(name) || hasImplicitOutput)) {
this.getTarget(outputId).put(name, output = rpcDataTargetFromType(target));
this.targets.put(name, output = rpcDataTargetFromType(target));
}
}
return Optional.ofNullable(output).map(out -> new BindingData(out));
return Optional.ofNullable(output).map(BindingData::new);
}

public void setDataTargetValue(String name, Object value) {
Optional.ofNullable(this.getTarget(this.promotedTargets).get(name)).ifPresent(out -> out.setValue(value));
}

public void promoteDataTargets(UUID outputId) {
this.promotedTargets = outputId;
}

private Map<String, DataTarget> getTarget(UUID outputId) {
return this.targets.computeIfAbsent(outputId, m -> new HashMap<>());
Optional.ofNullable(this.targets.get(name)).ifPresent(out -> out.setValue(value));
}

private boolean isDataTargetValid(String name, Type target) {
if (!name.equals(RETURN_NAME)) {
if (!CoreTypeResolver.isValidOutputType(target)) { return false; }
target = CoreTypeResolver.getParameterizedActualTypeArgumentsType(target);
if (!CoreTypeConverter.isValidOutputType(target)) { return false; }
target = CoreTypeConverter.getParameterizedActualTypeArgumentsType(target);
}
return true;
}

private static DataTarget rpcDataTargetFromType(Type target) {
if (CoreTypeResolver.isHttpResponse(target)) {
if (CoreTypeConverter.isHttpResponse(target)) {
return new RpcHttpDataTarget();
}
return new RpcUnspecifiedDataTarget();
}

///////////////////////// end region Output Binding Data

///////////////////////// region Binding Definitions

//Logics for binding Definitions
public void setBindingDefinitions(Map<String, BindingDefinition> definitions) {
this.definitions = definitions;
}
Expand All @@ -172,14 +163,4 @@ private boolean isDefinitionOutput(String name) {
private Optional<BindingDefinition> getDefinition(String name) {
return Optional.ofNullable(this.definitions.get(name));
}

///////////////////////// endregion Binding Definitions

private UUID promotedTargets;
private final Map<UUID, Map<String, DataTarget>> targets;
private final Map<String, DataSource<?>> inputSources;
private final Map<Type, DataSource<?>> otherSources;
private final Map<String, DataSource<?>> metadataSources;
private Map<String, BindingDefinition> definitions;
public static final String RETURN_NAME = "$return";
}
Original file line number Diff line number Diff line change
@@ -1,10 +1,7 @@
package com.microsoft.azure.functions.worker.binding;

import java.io.IOException;
import java.lang.reflect.Type;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Base64;
import java.util.Collection;
import java.util.HashMap;
import java.util.List;
Expand All @@ -15,13 +12,11 @@
import org.apache.commons.lang3.exception.ExceptionUtils;
import org.apache.commons.lang3.reflect.TypeUtils;

import com.google.gson.Gson;
import com.google.gson.JsonArray;
import com.google.gson.JsonParser;
import com.google.gson.JsonSyntaxException;
import com.google.gson.reflect.*;
import com.microsoft.azure.functions.worker.WorkerLogManager;
import com.microsoft.azure.functions.worker.broker.CoreTypeResolver;
import com.microsoft.azure.functions.worker.converter.CoreTypeConverter;

@FunctionalInterface
interface CheckedFunction<T, R> {
Expand Down Expand Up @@ -101,7 +96,7 @@ Optional<R> apply(T sourceValue, Type targetType) {

// Try POJO
if (Collection.class.isAssignableFrom(TypeUtils.getRawType(targetType, null))) {
Class<?> collectionItemType = (Class<?>) CoreTypeResolver
Class<?> collectionItemType = (Class<?>) CoreTypeConverter
.getParameterizedActualTypeArgumentsType(targetType);

try {
Expand Down Expand Up @@ -185,7 +180,7 @@ static Object generalAssignment(Object value, Type target) {
if (value == null) {
return ObjectUtils.NULL;
}
if (CoreTypeResolver.getRuntimeClass(target).isAssignableFrom(value.getClass())) {
if (CoreTypeConverter.getRuntimeClass(target).isAssignableFrom(value.getClass())) {
return value;
}
throw new ClassCastException("Cannot convert " + value + "to type " + target.getTypeName());
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
import com.microsoft.azure.functions.rpc.messages.BindingInfo;
import com.microsoft.azure.functions.worker.binding.BindingDefinition;
import com.microsoft.azure.functions.worker.description.FunctionMethodDescriptor;
import com.microsoft.azure.functions.worker.reflect.ClassLoaderProvider;
import com.microsoft.azure.functions.worker.classloader.ClassLoaderProvider;

import java.lang.reflect.Method;
import java.util.ArrayList;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@
import com.microsoft.azure.functions.worker.chain.FunctionExecutionMiddleware;
import com.microsoft.azure.functions.worker.chain.InvocationChainFactory;
import com.microsoft.azure.functions.worker.description.FunctionMethodDescriptor;
import com.microsoft.azure.functions.worker.reflect.ClassLoaderProvider;
import com.microsoft.azure.functions.worker.classloader.ClassLoaderProvider;
import org.apache.commons.lang3.exception.ExceptionUtils;
import org.apache.commons.lang3.tuple.ImmutablePair;

Expand Down Expand Up @@ -122,7 +122,7 @@ public Optional<TypedData> invokeMethod(String id, InvocationRequest request, Li
throws Exception {
ExecutionContextDataSource executionContextDataSource = buildExecutionContext(id, request);
invoke(executionContextDataSource);
outputs.addAll(executionContextDataSource.getDataStore().getOutputParameterBindings(true));
outputs.addAll(executionContextDataSource.getDataStore().getOutputParameterBindings());
return executionContextDataSource.getDataStore().getDataTargetTypedValue(BindingDataStore.RETURN_NAME);
}

Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package com.microsoft.azure.functions.worker.broker;

import com.microsoft.azure.functions.worker.binding.*;
import com.microsoft.azure.functions.worker.converter.ParameterConverter;

/**
* Used to executor of arbitrary Java method in any JAR using reflection.
Expand All @@ -17,9 +18,9 @@ public static JavaMethodExecutor getInstance(){
private JavaMethodExecutor() {}

public void execute(ExecutionContextDataSource executionContextDataSource) throws Exception {
Object retValue = ParameterResolver.resolveArguments(executionContextDataSource)
Object retValue = ParameterConverter.resolveArguments(executionContextDataSource)
.orElseThrow(() -> new NoSuchMethodException("Cannot locate the method signature with the given input"))
.invoke(executionContextDataSource::getFunctionInstance);
.invoke(executionContextDataSource.getFunctionInstance());
executionContextDataSource.updateReturnValue(retValue);
}
}

This file was deleted.

Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
package com.microsoft.azure.functions.worker.broker;

import com.microsoft.azure.functions.worker.converter.CoreTypeConverter;

import java.lang.reflect.Parameter;
import java.lang.reflect.Type;

Expand All @@ -11,10 +13,10 @@ public final class ParamBindInfo {
private final boolean isImplicitOutput;
private final Parameter parameter;
ParamBindInfo(Parameter param) {
this.name = CoreTypeResolver.getAnnotationName(param);
this.name = CoreTypeConverter.getAnnotationName(param);
this.type = param.getParameterizedType();
this.bindingNameAnnotation = CoreTypeResolver.getBindingNameAnnotation(param);
this.isImplicitOutput = CoreTypeResolver.checkImplicitOutput(param);
this.bindingNameAnnotation = CoreTypeConverter.getBindingNameAnnotation(param);
this.isImplicitOutput = CoreTypeConverter.checkImplicitOutput(param);
this.parameter = param;
}

Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
package com.microsoft.azure.functions.worker.reflect;
package com.microsoft.azure.functions.worker.classloader;

import java.io.*;
import java.net.*;
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
package com.microsoft.azure.functions.worker.reflect;
package com.microsoft.azure.functions.worker.classloader;

import java.io.*;
import java.lang.reflect.*;
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
package com.microsoft.azure.functions.worker.reflect;
package com.microsoft.azure.functions.worker.classloader;

import java.io.*;
import java.net.*;
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
package com.microsoft.azure.functions.worker.reflect;
package com.microsoft.azure.functions.worker.classloader;

import org.apache.commons.lang3.SystemUtils;

Expand Down
Original file line number Diff line number Diff line change
@@ -1,12 +1,12 @@
package com.microsoft.azure.functions.worker.broker;
package com.microsoft.azure.functions.worker.converter;

import java.lang.annotation.*;
import java.lang.reflect.*;

import com.microsoft.azure.functions.*;
import com.microsoft.azure.functions.worker.Constants;

public class CoreTypeResolver {
public class CoreTypeConverter {
private static boolean isOutputParameter(Type target) {
if (target instanceof ParameterizedType) {
target = ((ParameterizedType) target).getRawType();
Expand Down Expand Up @@ -108,7 +108,7 @@ private static String getBindingNameFromCustomBindingAnnotation(Annotation custo
}
}

static String getBindingNameAnnotation(Parameter param) {
public static String getBindingNameAnnotation(Parameter param) {
Annotation bindingNameAnnotation = null;
for (Annotation item : param.getAnnotations()){
if (item.annotationType().getName().equals("com.microsoft.azure.functions.annotation.BindingName")){
Expand All @@ -129,7 +129,7 @@ static String getBindingNameAnnotation(Parameter param) {
return new String("");
}

static boolean checkImplicitOutput(Parameter parameter) {
public static boolean checkImplicitOutput(Parameter parameter) {
Annotation[] annotations = parameter.getAnnotations();
for (Annotation annotation : annotations) {
for (Annotation item : annotation.annotationType().getAnnotations()) {
Expand Down
Loading