GH-199 Added support for typeless lookup in FunctionCatalog

Updated both the interface as well as InMemoryFunctionCatalog BeanFactoryFunctionCatalog and SingleEntryFunctionRegistry implementations
Added tests

Resolves #199
This commit is contained in:
Oleg Zhurakousky
2018-08-15 17:55:22 +02:00
parent fffe67cdcf
commit 30187b583b
9 changed files with 138 additions and 68 deletions

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2016-2017 the original author or authors.
* Copyright 2016-2018 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -20,10 +20,30 @@ import java.util.Set;
/**
* @author Dave Syer
* @author Oleg Zhurakousky
*/
public interface FunctionCatalog {
<T> T lookup(Class<?> type, String name);
/**
* Will look up the instance of the functional interface by name only
*
* @param name the name of the functional interface. Must not be null;
* @return instance of the functional interface registered with this catalog
*/
default public <T> T lookup(String name) {
return this.lookup(null, name);
}
/**
* Will look up the instance of the functional interface by name and type
* which can only be Supplier, Consumer or Function. If type is not provided, the lookup
* will be made based on name only
*
* @param type the type of functional interface. Can be null
* @param name the name of the functional interface. Must not be null;
* @return instance of the functional interface registered with this catalog
*/
<T> T lookup(Class<T> type, String name);
Set<String> getNames(Class<?> type);

View File

@@ -31,6 +31,7 @@ import org.springframework.cloud.function.core.FluxConsumer;
import org.springframework.cloud.function.core.FluxFunction;
import org.springframework.cloud.function.core.FluxSupplier;
import org.springframework.util.Assert;
import org.springframework.util.ObjectUtils;
import reactor.core.publisher.Flux;
import reactor.core.publisher.Mono;
@@ -58,6 +59,7 @@ public class FunctionRegistration<T> {
this.target = target;
}
/**
* Creates instance of FunctionRegistration.
*
@@ -66,11 +68,11 @@ public class FunctionRegistration<T> {
* @param names additional set of names for this registration. Additional names
* can be provided {@link #name(String)} or {@link #names(String...)} operations.
*/
public FunctionRegistration(T target, String name, String... additionalNames) {
public FunctionRegistration(T target, String... names) {
Assert.notNull(target, "'target' must not be null");
Assert.notEmpty(names, "'names' must not be null or empty");
this.target = target;
this.names(name);
this.names(additionalNames);
this.names(names);
}
public Map<String, String> getProperties() {

View File

@@ -19,6 +19,7 @@ package org.springframework.cloud.function.context.catalog;
import java.util.Collections;
import java.util.HashMap;
import java.util.Map;
import java.util.Optional;
import java.util.Set;
import java.util.function.Consumer;
import java.util.function.Function;
@@ -117,9 +118,15 @@ public class InMemoryFunctionCatalog
@Override
@SuppressWarnings("unchecked")
public <T> T lookup(Class<?> type, String name) {
Map<String, Object> map = this.extractTypeMap(type);
return (T) map.get(name);
public <T> T lookup(Class<T> type, String name) {
T function = null;
if (type == null) {
function = (T) functions.values().stream().filter(map -> map.get(name) != null).map(map -> map.get(name)).findFirst().orElse(null);
}
else {
function = (T) this.extractTypeMap(type).get(name);
}
return function;
}
@Override

View File

@@ -135,17 +135,27 @@ public class ContextFunctionCatalogAutoConfiguration {
@Override
@SuppressWarnings("unchecked")
public <T> T lookup(Class<?> type, String name) {
if (Supplier.class.isAssignableFrom(type)) {
return (T) processor.lookupSupplier(name);
public <T> T lookup(Class<T> type, String name) {
T function = null;
if (type == null) {
function = (T) processor.lookupFunction(name);
if (function == null) {
function = (T) processor.lookupConsumer(name);
}
if (function == null) {
function = (T) processor.lookupSupplier(name);
}
}
if (Consumer.class.isAssignableFrom(type)) {
return (T) processor.lookupConsumer(name);
else if (Supplier.class.isAssignableFrom(type)) {
function = (T) processor.lookupSupplier(name);
}
if (Function.class.isAssignableFrom(type)) {
return (T) processor.lookupFunction(name);
else if (Consumer.class.isAssignableFrom(type)) {
function = (T) processor.lookupConsumer(name);
}
return null;
else if (Function.class.isAssignableFrom(type)) {
function = (T) processor.lookupFunction(name);
}
return function;
}
@Override
@@ -233,7 +243,7 @@ public class ContextFunctionCatalogAutoConfiguration {
if (function == null || !names.containsKey(function)) {
return null;
}
return new FunctionRegistration<>(function).name(names.get(function))
return new FunctionRegistration<>(function, names.get(function))
.type(findType(function).getType());
}
@@ -390,7 +400,7 @@ public class ContextFunctionCatalogAutoConfiguration {
.forEach(entry -> {
if (!targets.containsKey(entry.getValue())) {
FunctionRegistration<Object> target = new FunctionRegistration<Object>(
entry.getValue()).names(getAliases(entry.getKey()));
entry.getValue(), getAliases(entry.getKey()).toArray(new String[] {}));
targets.put(target.getTarget(), entry.getKey());
registrations.add(target);
}