Java源码示例:org.springframework.cloud.function.context.FunctionRegistration

示例1
private void registerExport(GenericApplicationContext context) {
	context.registerBean(ExporterProperties.class, () -> new ExporterProperties());
	context.registerBean(FunctionExporterAutoConfiguration.class,
			() -> new FunctionExporterAutoConfiguration(context.getBean(ExporterProperties.class)));
	if (context.getBeanFactory().getBeanNamesForType(DestinationResolver.class, false, false).length == 0) {
		context.registerBean(DestinationResolver.class,
				() -> context.getBean(FunctionExporterAutoConfiguration.class).simpleDestinationResolver());
	}
	if (context.getBeanFactory().getBeanNamesForType(RequestBuilder.class, false, false).length == 0) {
		context.registerBean(RequestBuilder.class, () -> context.getBean(FunctionExporterAutoConfiguration.class)
				.simpleRequestBuilder(context.getEnvironment()));
	}
	if (context.getEnvironment().getProperty("spring.cloud.function.web.export.source.url") != null) {
		context.registerBean("origin", FunctionRegistration.class, () -> context
				.getBean(FunctionExporterAutoConfiguration.class).origin(context.getBean(WebClient.Builder.class)));
	}
	if (context.getEnvironment().getProperty("spring.cloud.function.web.export.sink.url") != null) {
		context.registerBean(SupplierExporter.class,
				() -> context.getBean(FunctionExporterAutoConfiguration.class).sourceForwarder(
						context.getBean(RequestBuilder.class), context.getBean(DestinationResolver.class),
						context.getBean(FunctionCatalog.class), context.getBean(WebClient.Builder.class)));
	}
}
 
示例2
@Override
Object locateFunction(String name) {
	Object function = super.locateFunction(name);
	if (function == null) {
		try {
			function = BeanFactoryAnnotationUtils.qualifiedBeanOfType(this.applicationContext.getBeanFactory(), Object.class, name);
		}
		catch (Exception e) {
			// ignore
		}
	}
	if (function == null && this.applicationContext.containsBean(name)) {
		function = this.applicationContext.getBean(name);
	}

	if (function != null && this.notFunction(function.getClass())
		&& this.applicationContext
		.containsBean(name + FunctionRegistration.REGISTRATION_NAME_SUFFIX)) { // e.g., Kotlin lambdas
		function = this.applicationContext
			.getBean(name + FunctionRegistration.REGISTRATION_NAME_SUFFIX, FunctionRegistration.class);
	}
	return function;
}
 
示例3
private static void assertSupportedTypes(Type type) {
	if (type instanceof ParameterizedType) {
		type = ((ParameterizedType) type).getRawType();
		Assert.isTrue(type instanceof Class<?>, "Must be one of Supplier, Function, Consumer"
				+ " or FunctionRegistration. Was " + type);
	}

	Class<?> candidateType = (Class<?>) type;

	Assert.isTrue(Supplier.class.isAssignableFrom(candidateType)
			|| Function.class.isAssignableFrom(candidateType)
			|| Consumer.class.isAssignableFrom(candidateType)
			|| FunctionRegistration.class.isAssignableFrom(candidateType)
			|| type.getTypeName().startsWith("org.springframework.context.annotation.ConfigurationClassEnhancer"), "Must be one of Supplier, Function, Consumer"
					+ " or FunctionRegistration. Was " + type);
}
 
示例4
@Override
public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
	if (bean instanceof FunctionRegistry) {
		FunctionRegistry catalog = (FunctionRegistry) bean;
		for (FunctionRegistration<?> registration : this.functions) {
			Assert.notEmpty(registration.getNames(),
					"FunctionRegistration must define at least one name. Was empty");
			if (registration.getType() == null) {
				throw new IllegalStateException(
						"You need an explicit type for the function: " + registration.getNames());
				// TODO: in principle Spring could know how to extract this
				// from the supplier, but in practice there is no functional
				// bean registration with parametric types.
			}
			catalog.register(registration);
		}
	}
	return bean;
}
 
示例5
@Test
public void testFunctionLookup() {

	TestFunction function = new TestFunction();
	FunctionRegistration<TestFunction> registration = new FunctionRegistration<>(
			function, "foo").type(FunctionType.of(TestFunction.class));
	SimpleFunctionRegistry catalog = new SimpleFunctionRegistry(this.conversionService, this.messageConverter);
	catalog.register(registration);

	FunctionInvocationWrapper lookedUpFunction = catalog.lookup("hello");
	assertThat(lookedUpFunction).isNotNull(); // because we only have one and can look it up with any name
	FunctionRegistration<TestFunction> registration2 = new FunctionRegistration<>(
			function, "foo2").type(FunctionType.of(TestFunction.class));
	catalog.register(registration2);
	lookedUpFunction = catalog.lookup("hello");
	assertThat(lookedUpFunction).isNull();
}
 
示例6
@Test
public void testFunctionComposition() {
	FunctionRegistration<UpperCase> upperCaseRegistration = new FunctionRegistration<>(
			new UpperCase(), "uppercase").type(FunctionType.of(UpperCase.class));
	FunctionRegistration<Reverse> reverseRegistration = new FunctionRegistration<>(
			new Reverse(), "reverse").type(FunctionType.of(Reverse.class));
	SimpleFunctionRegistry catalog = new SimpleFunctionRegistry(this.conversionService, this.messageConverter);
	catalog.register(upperCaseRegistration);
	catalog.register(reverseRegistration);

	Function<Flux<String>, Flux<String>> lookedUpFunction = catalog
			.lookup("uppercase|reverse");
	assertThat(lookedUpFunction).isNotNull();
	assertThat(lookedUpFunction.apply(Flux.just("star")).blockFirst())
			.isEqualTo("RATS");
}
 
示例7
@Test
public void testFunctionCompositionImplicit() {
	FunctionRegistration<Words> wordsRegistration = new FunctionRegistration<>(
			new Words(), "words").type(FunctionType.of(Words.class));
	FunctionRegistration<Reverse> reverseRegistration = new FunctionRegistration<>(
			new Reverse(), "reverse").type(FunctionType.of(Reverse.class));
	FunctionRegistry catalog = new SimpleFunctionRegistry(this.conversionService, this.messageConverter);
	catalog.register(wordsRegistration);
	catalog.register(reverseRegistration);

	// There's only one function, we should be able to leave that blank
	Supplier<String> lookedUpFunction = catalog.lookup("words|");

	assertThat(lookedUpFunction).isNotNull();
	assertThat(lookedUpFunction.get()).isEqualTo("olleh");
}
 
示例8
@Test
@Disabled
public void testFunctionCompletelyImplicitComposition() {
	FunctionRegistration<Words> wordsRegistration = new FunctionRegistration<>(
			new Words(), "words").type(FunctionType.of(Words.class));
	FunctionRegistration<Reverse> reverseRegistration = new FunctionRegistration<>(
			new Reverse(), "reverse").type(FunctionType.of(Reverse.class));
	SimpleFunctionRegistry catalog = new SimpleFunctionRegistry(this.conversionService, this.messageConverter);
	catalog.register(wordsRegistration);
	catalog.register(reverseRegistration);

	// There's only one function, we should be able to leave that blank
	Supplier<Flux<String>> lookedUpFunction = catalog.lookup("|");

	assertThat(lookedUpFunction).isNotNull();
	assertThat(lookedUpFunction.get().blockFirst()).isEqualTo("olleh");
}
 
示例9
@Test
public void testFunctionCompositionWithMessages() {
	FunctionRegistration<UpperCaseMessage> upperCaseRegistration = new FunctionRegistration<>(
			new UpperCaseMessage(), "uppercase")
					.type(FunctionType.of(UpperCaseMessage.class));
	FunctionRegistration<ReverseMessage> reverseRegistration = new FunctionRegistration<>(
			new ReverseMessage(), "reverse")
					.type(FunctionType.of(ReverseMessage.class));
	SimpleFunctionRegistry catalog = new SimpleFunctionRegistry(this.conversionService, this.messageConverter);
	catalog.register(upperCaseRegistration);
	catalog.register(reverseRegistration);

	Function<Flux<Message<String>>, Flux<Message<String>>> lookedUpFunction = catalog
			.lookup("uppercase|reverse");

	assertThat(lookedUpFunction).isNotNull();
	assertThat(lookedUpFunction
			.apply(Flux.just(MessageBuilder.withPayload("star").build())).blockFirst()
			.getPayload()).isEqualTo("RATS");
}
 
示例10
@Test
public void testFunctionCompositionMixedMessages() {
	FunctionRegistration<UpperCaseMessage> upperCaseRegistration = new FunctionRegistration<>(
			new UpperCaseMessage(), "uppercase")
					.type(FunctionType.of(UpperCaseMessage.class));
	FunctionRegistration<Reverse> reverseRegistration = new FunctionRegistration<>(
			new Reverse(), "reverse").type(FunctionType.of(Reverse.class));
	SimpleFunctionRegistry catalog = new SimpleFunctionRegistry(this.conversionService, this.messageConverter);
	catalog.register(upperCaseRegistration);
	catalog.register(reverseRegistration);

	Function<Message<String>, String> lookedUpFunction = catalog
			.lookup("uppercase|reverse");

	assertThat(lookedUpFunction).isNotNull();
	String result = lookedUpFunction.apply(MessageBuilder.withPayload("star").setHeader("foo", "bar").build());
	assertThat(result).isEqualTo("RATS");
}
 
示例11
@SuppressWarnings({ "rawtypes", "unchecked" })
@Test
public void testReactiveFunctionMessages() {
	FunctionRegistration<ReactiveFunction> registration = new FunctionRegistration<>(new ReactiveFunction(), "reactive")
		.type(FunctionType.of(ReactiveFunction.class));

	SimpleFunctionRegistry catalog = new SimpleFunctionRegistry(this.conversionService, this.messageConverter);
	catalog.register(registration);

	Function lookedUpFunction = catalog.lookup("reactive");

	assertThat(lookedUpFunction).isNotNull();
	Flux<List<String>> result = (Flux<List<String>>) lookedUpFunction
		.apply(Flux.just(MessageBuilder
			.withPayload("[{\"name\":\"item1\"},{\"name\":\"item2\"}]")
			.setHeader(MessageHeaders.CONTENT_TYPE, "application/json")
			.build()
		));
	Assertions.assertIterableEquals(result.blockFirst(), Arrays.asList("item1", "item2"));
}
 
示例12
/**
 * Will transform all discovered Kotlin's Function lambdas to java
 * Supplier, Function and Consumer, retaining the original Kotlin type
 * characteristics.
 *
 * @return the bean factory post processor
 */
@Bean
public BeanFactoryPostProcessor kotlinToFunctionTransformer() {
	return new BeanFactoryPostProcessor() {

		@Override
		public void postProcessBeanFactory(
				ConfigurableListableBeanFactory beanFactory) throws BeansException {

			String[] beanDefinitionNames = beanFactory.getBeanDefinitionNames();
			for (String beanDefinitionName : beanDefinitionNames) {
				BeanDefinition beanDefinition = beanFactory.getBeanDefinition(beanDefinitionName);

				ResolvableType rt = beanDefinition.getResolvableType();
				if (rt.getType().getTypeName().startsWith("kotlin.jvm.functions.Function")) {
					RootBeanDefinition cbd = new RootBeanDefinition(KotlinFunctionWrapper.class);
					ConstructorArgumentValues ca = new ConstructorArgumentValues();
					ca.addGenericArgumentValue(beanDefinition);
					cbd.setConstructorArgumentValues(ca);
					((BeanDefinitionRegistry) beanFactory).registerBeanDefinition(beanDefinitionName + FunctionRegistration.REGISTRATION_NAME_SUFFIX, cbd);
				}
			}
		}
	};
}
 
示例13
@Override
public FunctionRegistration getObject() throws Exception {
	String name = this.name.endsWith(FunctionRegistration.REGISTRATION_NAME_SUFFIX)
			? this.name.replace(FunctionRegistration.REGISTRATION_NAME_SUFFIX, "")
					: this.name;
	Type functionType = FunctionContextUtils.findType(name, this.beanFactory);
	FunctionRegistration<?> registration = new FunctionRegistration<>(this, name);
	Type[] types = ((ParameterizedType) functionType).getActualTypeArguments();

	if (functionType.getTypeName().contains("Function0")) {
		functionType = ResolvableType.forClassWithGenerics(Supplier.class, ResolvableType.forType(types[0]))
				.getType();
	}
	else if (functionType.getTypeName().contains("Function1")) {
		functionType = ResolvableType.forClassWithGenerics(Function.class, ResolvableType.forType(types[0]),
				ResolvableType.forType(types[1])).getType();
	}
	else {
		throw new UnsupportedOperationException("Multi argument Kotlin functions are not currently supported");
	}
	registration = registration.type(functionType);
	return registration;
}
 
示例14
@Bean
@ConditionalOnProperty(prefix = "spring.cloud.function.web.export.source", name = "url")
public FunctionRegistration<Supplier<Flux<?>>> origin(WebClient.Builder builder) {
	HttpSupplier supplier = new HttpSupplier(builder.build(), this.props);
	FunctionRegistration<Supplier<Flux<?>>> registration = new FunctionRegistration<>(supplier);
	FunctionType type = FunctionType.supplier(this.props.getSource().getType()).wrap(Flux.class);
	if (this.props.getSource().isIncludeHeaders()) {
		type = type.message();
	}
	registration = registration.type(type);
	return registration;
}
 
示例15
@Override
public void initialize(GenericApplicationContext applicationContext) {
	applicationContext.registerBean("uppercase", FunctionRegistration.class,
			() -> new FunctionRegistration<>(uppercase())
				.type(FunctionType.from(String.class).to(String.class)));
	applicationContext.registerBean("reverse", FunctionRegistration.class,
			() -> new FunctionRegistration<>(reverse())
				.type(FunctionType.from(String.class).to(String.class)));
	applicationContext.registerBean("lowercase", FunctionRegistration.class,
			() -> new FunctionRegistration<>(lowercase())
				.type(FunctionType.from(String.class).to(String.class)));
	applicationContext.registerBean("supplier", FunctionRegistration.class,
			() -> new FunctionRegistration<>(supplier())
				.type(FunctionType.supplier(String.class)));
}
 
示例16
@Override
public FunctionRegistration<?> getRegistration(Object function) {
	String functionName = function == null ? null
			: this.lookupFunctionName(function);
	if (StringUtils.hasText(functionName)) {
		FunctionRegistration<?> registration = new FunctionRegistration<Object>(
				function, functionName);
		FunctionType functionType = this.findType(registration, functionName);
		return registration.type(functionType.getType());
	}
	return null;
}
 
示例17
private FunctionRegistration<?> find(String name, boolean supplierFound) {
	Object result = this.functions.get(name);
	if (result == null && !StringUtils.hasText(name)) {
		if (supplierFound && this.getFunctionNames().size() == 1) {
			result = this.functions.get(this.getFunctionNames().iterator().next());
		}
		else if (!supplierFound && this.getSupplierNames().size() == 1) {
			result = this.functions.get(this.getSupplierNames().iterator().next());
		}
	}

	return getRegistration(result);
}
 
示例18
@Override
Type discoverFunctionType(Object function, String... names) {
	if (function instanceof RoutingFunction) {
		return FunctionType.of(FunctionContextUtils.findType(applicationContext.getBeanFactory(), names)).getType();
	}
	else if (function instanceof FunctionRegistration) {
		return ((FunctionRegistration) function).getType().getType();
	}
	boolean beanDefinitionExists = false;
	for (int i = 0; i < names.length && !beanDefinitionExists; i++) {
		beanDefinitionExists = this.applicationContext.getBeanFactory().containsBeanDefinition(names[i]);
		if (this.applicationContext.containsBean("&" + names[i])) {
			Class<?> objectType = this.applicationContext.getBean("&" + names[i], FactoryBean.class)
				.getObjectType();
			return FunctionTypeUtils.discoverFunctionTypeFromClass(objectType);
		}
	}
	if (!beanDefinitionExists) {
		logger.info("BeanDefinition for function name(s) '" + Arrays.asList(names) +
			"' can not be located. FunctionType will be based on " + function.getClass());
	}

	Type type = FunctionTypeUtils.discoverFunctionTypeFromClass(function.getClass());
	if (beanDefinitionExists) {
		Type t = FunctionTypeUtils.getImmediateGenericType(type, 0);
		if (t == null || t == Object.class) {
			type = FunctionType.of(FunctionContextUtils.findType(this.applicationContext.getBeanFactory(), names)).getType();
		}
	}
	return type;
}
 
示例19
private static Type extractReactiveType(Type type) {
	if (type instanceof ParameterizedType && FunctionRegistration.class.isAssignableFrom(((Class<?>) ((ParameterizedType) type).getRawType()))) {
		type = getImmediateGenericType(type, 0);
		if (type instanceof ParameterizedType) {
			type = getImmediateGenericType(type, 0);
		}
	}
	return type;
}
 
示例20
FunctionTypeConversionHelper(FunctionRegistration<?> functionRegistration, ConversionService conversionService,
		MessageConverter messageConverter) {
	this.conversionService = conversionService;
	this.messageConverter = messageConverter;
	this.functionRegistration = functionRegistration;
	if ((this.functionRegistration.getType().getType()) instanceof ParameterizedType) {
		this.functionArgumentTypes = ((ParameterizedType) this.functionRegistration.getType().getType())
				.getActualTypeArguments();
	}
	else {
		this.functionArgumentTypes = new Type[] { this.functionRegistration.getType().getInputType() };
	}
}
 
示例21
default boolean isMessage(Object function) {
	FunctionRegistration<?> registration = getRegistration(function);
	if (registration != null && registration.getTarget() instanceof FunctionInvocationWrapper
			&& ((FunctionInvocationWrapper) registration.getTarget()).getTarget() instanceof RoutingFunction) {
		// we always want to give routing function as much information as possible
		return true;
	}
	return registration == null ? false : registration.getType().isMessage();
}
 
示例22
@SuppressWarnings("unchecked")
@Override
public <T> void register(FunctionRegistration<T> registration) {
	this.registrationsByFunction.put(registration.getTarget(), (FunctionRegistration<Object>) registration);
	for (String name : registration.getNames()) {
		this.registrationsByName.put(name, (FunctionRegistration<Object>) registration);
	}
}
 
示例23
@Override
public FunctionRegistration<?> getRegistration(Object function) {
	FunctionRegistration<?> registration = this.registrationsByFunction.get(function);
	// need to do this due to the deployer not wrapping the actual target into FunctionInvocationWrapper
	// hence the lookup would need to be made by the actual target
	if (registration == null && function instanceof FunctionInvocationWrapper) {
		function = ((FunctionInvocationWrapper) function).target;
	}
	return this.registrationsByFunction.get(function);
}
 
示例24
@Test
public void testFunctionCompositionExplicit() {
	FunctionRegistration<Words> wordsRegistration = new FunctionRegistration<>(
			new Words(), "words").type(FunctionType.of(Words.class));
	FunctionRegistration<Reverse> reverseRegistration = new FunctionRegistration<>(
			new Reverse(), "reverse").type(FunctionType.of(Reverse.class));
	SimpleFunctionRegistry catalog = new SimpleFunctionRegistry(this.conversionService, this.messageConverter);
	catalog.register(wordsRegistration);
	catalog.register(reverseRegistration);

	Supplier<String> lookedUpFunction = catalog.lookup("words|reverse");

	assertThat(lookedUpFunction).isNotNull();
	assertThat(lookedUpFunction.get()).isEqualTo("olleh");
}
 
示例25
@Test
public void lookUps() {
	create(SimpleConfiguration.class);
	assertThat(this.context.getBean("function"))
			.isInstanceOf(FunctionRegistration.class);
	assertThat((Function<?, ?>) this.catalog.lookup(Function.class, "function"))
			.isInstanceOf(Function.class);
}
 
示例26
@Test
public void properties() {
	create(PropertiesConfiguration.class, "app.greeting=hello");
	assertThat(this.context.getBean("function"))
			.isInstanceOf(FunctionRegistration.class);
	@SuppressWarnings("unchecked")
	Function<Flux<String>, Flux<String>> function = (Function<Flux<String>, Flux<String>>) this.catalog
			.lookup(Function.class, "function");
	assertThat(function).isInstanceOf(Function.class);
	assertThat(function.apply(Flux.just("foo")).blockFirst()).isEqualTo("hello foo");
}
 
示例27
@Test
public void value() {
	create(ValueConfiguration.class, "app.greeting=hello");
	assertThat(this.context.getBean("function"))
			.isInstanceOf(FunctionRegistration.class);
	@SuppressWarnings("unchecked")
	Function<Flux<String>, Flux<String>> function = (Function<Flux<String>, Flux<String>>) this.catalog
			.lookup(Function.class, "function");
	assertThat(function).isInstanceOf(Function.class);
	assertThat(function.apply(Flux.just("foo")).blockFirst()).isEqualTo("hello foo");
}
 
示例28
@Test
@Disabled
public void compose() {
	create(SimpleConfiguration.class);
	assertThat(this.context.getBean("function"))
			.isInstanceOf(FunctionRegistration.class);
	@SuppressWarnings("unchecked")
	Supplier<Flux<String>> supplier = (Supplier<Flux<String>>) this.catalog
			.lookup(Supplier.class, "supplier|function");
	assertThat(supplier).isInstanceOf(Supplier.class);
	assertThat(supplier.get().blockFirst()).isEqualTo("HELLO");
	// TODO: support for function composition
}
 
示例29
@Test
public void missingType() {
	Assertions.assertThrows(BeanCreationException.class, () -> {
		create(MissingTypeConfiguration.class);
		assertThat(this.context.getBean("function"))
			.isInstanceOf(FunctionRegistration.class);
		assertThat((Function<?, ?>) this.catalog.lookup(Function.class, "function"))
			.isInstanceOf(Function.class);
		// TODO: support for type inference from functional bean registrations
	});
}
 
示例30
@Test
public void dependencyInjection() {
	create(DependencyInjectionConfiguration.class);
	assertThat(this.context.getBean("foos")).isInstanceOf(FunctionRegistration.class);
	assertThat((Function<?, ?>) this.catalog.lookup(Function.class, "foos"))
			.isInstanceOf(Function.class);
	assertThat(
			this.inspector.getInputType(this.catalog.lookup(Function.class, "foos")))
					.isEqualTo(String.class);
}