Renamed deployer-new to deployer, removed old deployer

This commit is contained in:
Oleg Zhurakousky
2019-08-12 17:26:22 +02:00
parent 17ef359b60
commit ed2fa9bb7a
75 changed files with 462 additions and 463 deletions

View File

@@ -60,7 +60,6 @@
<module>spring-cloud-starter-function-webflux</module>
<module>spring-cloud-function-samples</module>
<module>spring-cloud-function-deployer</module>
<module>spring-cloud-function-deployer-new</module>
<module>spring-cloud-function-adapters</module>
<module>spring-cloud-function-kotlin</module>
<module>docs</module>

View File

@@ -1,117 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<artifactId>spring-cloud-function-deployer-new</artifactId>
<packaging>jar</packaging>
<name>spring-cloud-function-deployer-new</name>
<description>Spring Cloud Function Web Support</description>
<parent>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-function-parent</artifactId>
<version>3.0.0.BUILD-SNAPSHOT</version>
</parent>
<properties>
<java.version>1.8</java.version>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-loader</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-function-context</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-configuration-processor</artifactId>
<optional>true</optional>
</dependency>
</dependencies>
<build>
<plugins>
<!-- <plugin> -->
<!-- <groupId>org.springframework.boot</groupId> -->
<!-- <artifactId>spring-boot-maven-plugin</artifactId> -->
<!-- <dependencies> -->
<!-- <dependency> -->
<!-- <groupId>org.springframework.boot.experimental</groupId> -->
<!-- <artifactId>spring-boot-thin-layout</artifactId> -->
<!-- <version>${wrapper.version}</version> -->
<!-- </dependency> -->
<!-- </dependencies> -->
<!-- </plugin> -->
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-invoker-plugin</artifactId>
<version>3.0.1</version>
<configuration>
<localRepositoryPath>${project.build.directory}/local-repo
</localRepositoryPath>
</configuration>
<executions>
<execution>
<id>prepare-test</id>
<phase>test-compile</phase>
<goals>
<goal>run</goal>
</goals>
<configuration>
<cloneProjectsTo>${project.build.directory}/it
</cloneProjectsTo>
<settingsFile>src/it/settings.xml</settingsFile>
<addTestClassPath>true</addTestClassPath>
<streamLogs>true</streamLogs>
</configuration>
</execution>
</executions>
</plugin>
</plugins>
</build>
<repositories>
<repository>
<id>spring-milestones</id>
<name>Spring Milestones</name>
<url>https://repo.spring.io/milestone</url>
</repository>
<repository>
<id>spring-snapshots</id>
<name>Spring Snapshots</name>
<url>https://repo.spring.io/snapshot</url>
<snapshots>
<enabled>true</enabled>
</snapshots>
</repository>
</repositories>
<pluginRepositories>
<pluginRepository>
<id>spring-milestones</id>
<name>Spring Milestones</name>
<url>https://repo.spring.io/milestone</url>
</pluginRepository>
<pluginRepository>
<id>spring-snapshots</id>
<name>Spring Snapshots</name>
<url>https://repo.spring.io/snapshot</url>
<snapshots>
<enabled>true</enabled>
</snapshots>
</pluginRepository>
</pluginRepositories>
</project>

View File

@@ -1,95 +0,0 @@
/*
* Copyright 2017-2019 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.
* You may obtain a copy of the License at
*
* https://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.springframework.cloud.function.deployer;
import java.io.File;
import java.io.IOException;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.springframework.boot.ApplicationArguments;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.boot.loader.archive.Archive;
import org.springframework.boot.loader.archive.JarFileArchive;
import org.springframework.cloud.function.context.FunctionRegistry;
import org.springframework.context.SmartLifecycle;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
/**
*
* @author Oleg Zhurakousky
*
* @since 3.0
*
*/
@Configuration(proxyBeanMethods = false)
@EnableConfigurationProperties(FunctionProperties.class)
public class FunctionDeployerConfiguration {
private static Log logger = LogFactory.getLog(FunctionDeployerConfiguration.class);
@Bean
SmartLifecycle functionArchiveDeployer(FunctionProperties functionProperties,
FunctionRegistry functionRegistry, ApplicationArguments arguments) {
Archive archive = null;
try {
archive = new JarFileArchive(new File(functionProperties.getLocation()));
}
catch (IOException e) {
throw new IllegalStateException("Failed to create archive: " + functionProperties.getLocation(), e);
}
FunctionArchiveDeployer deployer = new FunctionArchiveDeployer(archive);
return new SmartLifecycle() {
private boolean running;
@Override
public void stop() {
if (logger.isInfoEnabled()) {
logger.info("Undeploying archive: " + functionProperties.getLocation());
}
deployer.undeploy();
if (logger.isInfoEnabled()) {
logger.info("Successfully undeployed archive: " + functionProperties.getLocation());
}
this.running = false;
}
@Override
public void start() {
if (logger.isInfoEnabled()) {
logger.info("Deploying archive: " + functionProperties.getLocation());
}
deployer.deploy(functionRegistry, functionProperties, arguments.getSourceArgs());
this.running = true;
if (logger.isInfoEnabled()) {
logger.info("Successfully deployed archive: " + functionProperties.getLocation());
}
}
@Override
public boolean isRunning() {
return this.running;
}
};
}
}

View File

@@ -1,78 +0,0 @@
/*
* Copyright 2017-2019 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.
* You may obtain a copy of the License at
*
* https://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.springframework.cloud.function.deployer;
import javax.annotation.PostConstruct;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.util.Assert;
import org.springframework.util.StringUtils;
/**
* Configuration properties for deciding how to locate the functional class to execute.
*
* @author Eric Bottard
*/
@ConfigurationProperties("spring.cloud.function")
public class FunctionProperties {
/**
* Location of jar archive containing the supplier/function/consumer class or bean to run.
*/
private String location;
/**
* The name of the function to be looked up from the FunctionCatalog (e.g., bean name).
*/
private String functionName;
/**
* The name of the function class tyo be instantiated and loaded into FunctionCatalog. The name of the
* function will be decapitalized simple name of this class.
*/
private String functionClass;
public void setFunctionClass(String functionClass) {
this.functionClass = functionClass;
}
public String getFunctionClass() {
return this.functionClass;
}
public void setFunctionName(String functionName) {
this.functionName = StringUtils.hasText(functionName) ? functionName : "";
}
public String getFunctionName() {
return this.functionName;
}
public String getLocation() {
return this.location;
}
public void setLocation(String location) {
this.location = location;
}
@PostConstruct
public void init() {
Assert.notNull(this.location, "No archive location provided, please configure spring.cloud.function.location as a jar or directory.");
}
}

View File

@@ -0,0 +1,155 @@
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns="http://maven.apache.org/POM/4.0.0"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<artifactId>spring-cloud-function-deployer-old</artifactId>
<packaging>jar</packaging>
<name>spring-cloud-function-deployer</name>
<description>Spring Cloud Function Web Support</description>
<parent>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-function-parent</artifactId>
<version>3.0.0.BUILD-SNAPSHOT</version>
</parent>
<properties>
<wrapper.version>1.0.10.RELEASE</wrapper.version>
<spring.cloud.deployer.version>2.0.2.BUILD-SNAPSHOT</spring.cloud.deployer.version>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-function-context</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-configuration-processor</artifactId>
<optional>true</optional>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-loader</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-deployer-resource-maven</artifactId>
<version>${spring.cloud.deployer.version}</version>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-deployer-resource-support</artifactId>
<version>${spring.cloud.deployer.version}</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-logging</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>javax.annotation</groupId>
<artifactId>javax.annotation-api</artifactId>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<dependencies>
<dependency>
<groupId>org.springframework.boot.experimental</groupId>
<artifactId>spring-boot-thin-layout</artifactId>
<version>${wrapper.version}</version>
</dependency>
</dependencies>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-invoker-plugin</artifactId>
<version>3.0.1</version>
<configuration>
<localRepositoryPath>${project.build.directory}/local-repo
</localRepositoryPath>
</configuration>
<executions>
<execution>
<id>prepare-test</id>
<phase>test-compile</phase>
<goals>
<goal>run</goal>
</goals>
<configuration>
<cloneProjectsTo>${project.build.directory}/it
</cloneProjectsTo>
<settingsFile>src/it/settings.xml</settingsFile>
<addTestClassPath>true</addTestClassPath>
<streamLogs>true</streamLogs>
</configuration>
</execution>
</executions>
</plugin>
</plugins>
<pluginManagement>
<plugins>
<!--This plugin's configuration is used to store Eclipse m2e settings
only. It has no influence on the Maven build itself. -->
<plugin>
<groupId>org.eclipse.m2e</groupId>
<artifactId>lifecycle-mapping</artifactId>
<version>1.0.0</version>
<configuration>
<lifecycleMappingMetadata>
<pluginExecutions>
<pluginExecution>
<pluginExecutionFilter>
<groupId>
org.apache.maven.plugins
</groupId>
<artifactId>
maven-invoker-plugin
</artifactId>
<versionRange>
[1.10,)
</versionRange>
<goals>
<goal>run</goal>
</goals>
</pluginExecutionFilter>
<action>
<ignore></ignore>
</action>
</pluginExecution>
</pluginExecutions>
</lifecycleMappingMetadata>
</configuration>
</plugin>
</plugins>
</pluginManagement>
</build>
<profiles>
<profile>
<id>invoke</id>
<activation>
<file>
<missing>target/it/flux/pom.xml</missing>
</file>
</activation>
<properties>
<skip.invoke>false</skip.invoke>
</properties>
</profile>
</profiles>
</project>

View File

@@ -0,0 +1,66 @@
/*
* Copyright 2012-2019 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.
* You may obtain a copy of the License at
*
* https://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.springframework.cloud.function.deployer;
import java.util.HashMap;
import java.util.Map;
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.cloud.deployer.resource.maven.MavenProperties;
import org.springframework.cloud.deployer.resource.maven.MavenResource;
import org.springframework.cloud.deployer.resource.maven.MavenResourceLoader;
import org.springframework.cloud.deployer.resource.support.DelegatingResourceLoader;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Import;
import org.springframework.core.io.ResourceLoader;
/**
* @author Dave Syer
*
*/
@Configuration
@ConditionalOnProperty(prefix = "function.deployer", name = "enabled", matchIfMissing = true)
@EnableConfigurationProperties
@Import(FunctionCreatorConfiguration.class)
public class FunctionDeployerConfiguration {
@Bean
@ConfigurationProperties("maven")
public MavenProperties mavenProperties() {
return new MavenProperties();
}
@Bean
@ConfigurationProperties("function")
public FunctionProperties functionProperties() {
return new FunctionProperties();
}
@Bean
@ConditionalOnMissingBean(DelegatingResourceLoader.class)
public DelegatingResourceLoader delegatingResourceLoader(
MavenProperties mavenProperties) {
Map<String, ResourceLoader> loaders = new HashMap<>();
loaders.put(MavenResource.URI_SCHEME, new MavenResourceLoader(mavenProperties));
return new DelegatingResourceLoader(loaders);
}
}

View File

@@ -0,0 +1,100 @@
/*
* Copyright 2012-2019 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.
* You may obtain a copy of the License at
*
* https://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.springframework.cloud.function.deployer;
import java.util.ArrayList;
import java.util.List;
import javax.annotation.PostConstruct;
import org.springframework.util.StringUtils;
/**
* Configuration properties for deciding how to locate the functional class to execute.
*
* @author Eric Bottard
*/
public class FunctionProperties {
/**
* Location(s) of jar archives containing the supplier/function/consumer class to run.
*/
private String[] location = new String[0];
/**
* The bean name or fully qualified class name of the supplier/function/consumer to
* run.
*/
private String[] bean = new String[0];
/**
* Optional main class from which to build a Spring application context.
*/
private String main;
public static String functionName(String name) {
if (!name.contains(",")) {
return "function0";
}
List<String> names = new ArrayList<>();
for (int i = 0; i <= StringUtils.countOccurrencesOf(name, ","); i++) {
names.add("function" + i);
}
return StringUtils.collectionToDelimitedString(names, "|");
}
public static String functionName(int value) {
return "function" + value;
}
public String getName() {
return functionName(StringUtils.arrayToDelimitedString(this.bean, ","));
}
public String[] getBean() {
return this.bean;
}
public void setBean(String[] bean) {
this.bean = bean;
}
public String[] getLocation() {
return this.location;
}
public void setLocation(String[] location) {
this.location = location;
}
public String getMain() {
return this.main;
}
public void setMain(String main) {
this.main = main;
}
@PostConstruct
public void init() {
if (this.location.length == 0) {
throw new IllegalStateException(
"No archive location provided, please configure function.location as a jar or directory.");
}
}
}

View File

@@ -1,48 +1,34 @@
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns="http://maven.apache.org/POM/4.0.0"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<artifactId>spring-cloud-function-deployer</artifactId>
<packaging>jar</packaging>
<name>spring-cloud-function-deployer</name>
<description>Spring Cloud Function Web Support</description>
<packaging>jar</packaging>
<name>spring-cloud-function-deployer-new</name>
<description>Spring Cloud Function Web Support</description>
<parent>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-function-parent</artifactId>
<version>3.0.0.BUILD-SNAPSHOT</version>
</parent>
<parent>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-function-parent</artifactId>
<version>3.0.0.BUILD-SNAPSHOT</version>
</parent>
<properties>
<wrapper.version>1.0.10.RELEASE</wrapper.version>
<spring.cloud.deployer.version>2.0.2.BUILD-SNAPSHOT</spring.cloud.deployer.version>
<java.version>1.8</java.version>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-function-context</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-configuration-processor</artifactId>
<optional>true</optional>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-loader</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-deployer-resource-maven</artifactId>
<version>${spring.cloud.deployer.version}</version>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-deployer-resource-support</artifactId>
<version>${spring.cloud.deployer.version}</version>
<artifactId>spring-cloud-function-context</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
@@ -51,29 +37,24 @@
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-logging</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>javax.annotation</groupId>
<artifactId>javax.annotation-api</artifactId>
<artifactId>spring-boot-configuration-processor</artifactId>
<optional>true</optional>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<dependencies>
<dependency>
<groupId>org.springframework.boot.experimental</groupId>
<artifactId>spring-boot-thin-layout</artifactId>
<version>${wrapper.version}</version>
</dependency>
</dependencies>
</plugin>
<!-- <plugin> -->
<!-- <groupId>org.springframework.boot</groupId> -->
<!-- <artifactId>spring-boot-maven-plugin</artifactId> -->
<!-- <dependencies> -->
<!-- <dependency> -->
<!-- <groupId>org.springframework.boot.experimental</groupId> -->
<!-- <artifactId>spring-boot-thin-layout</artifactId> -->
<!-- <version>${wrapper.version}</version> -->
<!-- </dependency> -->
<!-- </dependencies> -->
<!-- </plugin> -->
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-invoker-plugin</artifactId>
@@ -100,56 +81,37 @@
</executions>
</plugin>
</plugins>
<pluginManagement>
<plugins>
<!--This plugin's configuration is used to store Eclipse m2e settings
only. It has no influence on the Maven build itself. -->
<plugin>
<groupId>org.eclipse.m2e</groupId>
<artifactId>lifecycle-mapping</artifactId>
<version>1.0.0</version>
<configuration>
<lifecycleMappingMetadata>
<pluginExecutions>
<pluginExecution>
<pluginExecutionFilter>
<groupId>
org.apache.maven.plugins
</groupId>
<artifactId>
maven-invoker-plugin
</artifactId>
<versionRange>
[1.10,)
</versionRange>
<goals>
<goal>run</goal>
</goals>
</pluginExecutionFilter>
<action>
<ignore></ignore>
</action>
</pluginExecution>
</pluginExecutions>
</lifecycleMappingMetadata>
</configuration>
</plugin>
</plugins>
</pluginManagement>
</build>
<profiles>
<profile>
<id>invoke</id>
<activation>
<file>
<missing>target/it/flux/pom.xml</missing>
</file>
</activation>
<properties>
<skip.invoke>false</skip.invoke>
</properties>
</profile>
</profiles>
<repositories>
<repository>
<id>spring-milestones</id>
<name>Spring Milestones</name>
<url>https://repo.spring.io/milestone</url>
</repository>
<repository>
<id>spring-snapshots</id>
<name>Spring Snapshots</name>
<url>https://repo.spring.io/snapshot</url>
<snapshots>
<enabled>true</enabled>
</snapshots>
</repository>
</repositories>
<pluginRepositories>
<pluginRepository>
<id>spring-milestones</id>
<name>Spring Milestones</name>
<url>https://repo.spring.io/milestone</url>
</pluginRepository>
<pluginRepository>
<id>spring-snapshots</id>
<name>Spring Snapshots</name>
<url>https://repo.spring.io/snapshot</url>
<snapshots>
<enabled>true</enabled>
</snapshots>
</pluginRepository>
</pluginRepositories>
</project>

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2012-2019 the original author or authors.
* Copyright 2017-2019 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.
@@ -16,51 +16,80 @@
package org.springframework.cloud.function.deployer;
import java.util.HashMap;
import java.util.Map;
import java.io.File;
import java.io.IOException;
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.springframework.boot.ApplicationArguments;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.cloud.deployer.resource.maven.MavenProperties;
import org.springframework.cloud.deployer.resource.maven.MavenResource;
import org.springframework.cloud.deployer.resource.maven.MavenResourceLoader;
import org.springframework.cloud.deployer.resource.support.DelegatingResourceLoader;
import org.springframework.boot.loader.archive.Archive;
import org.springframework.boot.loader.archive.JarFileArchive;
import org.springframework.cloud.function.context.FunctionRegistry;
import org.springframework.context.SmartLifecycle;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Import;
import org.springframework.core.io.ResourceLoader;
/**
* @author Dave Syer
*
* @author Oleg Zhurakousky
*
* @since 3.0
*
*/
@Configuration
@ConditionalOnProperty(prefix = "function.deployer", name = "enabled", matchIfMissing = true)
@EnableConfigurationProperties
@Import(FunctionCreatorConfiguration.class)
@Configuration(proxyBeanMethods = false)
@EnableConfigurationProperties(FunctionProperties.class)
public class FunctionDeployerConfiguration {
@Bean
@ConfigurationProperties("maven")
public MavenProperties mavenProperties() {
return new MavenProperties();
}
private static Log logger = LogFactory.getLog(FunctionDeployerConfiguration.class);
@Bean
@ConfigurationProperties("function")
public FunctionProperties functionProperties() {
return new FunctionProperties();
}
SmartLifecycle functionArchiveDeployer(FunctionProperties functionProperties,
FunctionRegistry functionRegistry, ApplicationArguments arguments) {
@Bean
@ConditionalOnMissingBean(DelegatingResourceLoader.class)
public DelegatingResourceLoader delegatingResourceLoader(
MavenProperties mavenProperties) {
Map<String, ResourceLoader> loaders = new HashMap<>();
loaders.put(MavenResource.URI_SCHEME, new MavenResourceLoader(mavenProperties));
return new DelegatingResourceLoader(loaders);
Archive archive = null;
try {
archive = new JarFileArchive(new File(functionProperties.getLocation()));
}
catch (IOException e) {
throw new IllegalStateException("Failed to create archive: " + functionProperties.getLocation(), e);
}
FunctionArchiveDeployer deployer = new FunctionArchiveDeployer(archive);
return new SmartLifecycle() {
private boolean running;
@Override
public void stop() {
if (logger.isInfoEnabled()) {
logger.info("Undeploying archive: " + functionProperties.getLocation());
}
deployer.undeploy();
if (logger.isInfoEnabled()) {
logger.info("Successfully undeployed archive: " + functionProperties.getLocation());
}
this.running = false;
}
@Override
public void start() {
if (logger.isInfoEnabled()) {
logger.info("Deploying archive: " + functionProperties.getLocation());
}
deployer.deploy(functionRegistry, functionProperties, arguments.getSourceArgs());
this.running = true;
if (logger.isInfoEnabled()) {
logger.info("Successfully deployed archive: " + functionProperties.getLocation());
}
}
@Override
public boolean isRunning() {
return this.running;
}
};
}
}

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2012-2019 the original author or authors.
* Copyright 2017-2019 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.
@@ -16,11 +16,10 @@
package org.springframework.cloud.function.deployer;
import java.util.ArrayList;
import java.util.List;
import javax.annotation.PostConstruct;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.util.Assert;
import org.springframework.util.StringUtils;
/**
@@ -28,73 +27,52 @@ import org.springframework.util.StringUtils;
*
* @author Eric Bottard
*/
@ConfigurationProperties("spring.cloud.function")
public class FunctionProperties {
/**
* Location(s) of jar archives containing the supplier/function/consumer class to run.
* Location of jar archive containing the supplier/function/consumer class or bean to run.
*/
private String[] location = new String[0];
private String location;
/**
* The bean name or fully qualified class name of the supplier/function/consumer to
* run.
* The name of the function to be looked up from the FunctionCatalog (e.g., bean name).
*/
private String[] bean = new String[0];
private String functionName;
/**
* Optional main class from which to build a Spring application context.
* The name of the function class tyo be instantiated and loaded into FunctionCatalog. The name of the
* function will be decapitalized simple name of this class.
*/
private String main;
private String functionClass;
public static String functionName(String name) {
if (!name.contains(",")) {
return "function0";
}
List<String> names = new ArrayList<>();
for (int i = 0; i <= StringUtils.countOccurrencesOf(name, ","); i++) {
names.add("function" + i);
}
return StringUtils.collectionToDelimitedString(names, "|");
public void setFunctionClass(String functionClass) {
this.functionClass = functionClass;
}
public static String functionName(int value) {
return "function" + value;
public String getFunctionClass() {
return this.functionClass;
}
public String getName() {
return functionName(StringUtils.arrayToDelimitedString(this.bean, ","));
public void setFunctionName(String functionName) {
this.functionName = StringUtils.hasText(functionName) ? functionName : "";
}
public String[] getBean() {
return this.bean;
public String getFunctionName() {
return this.functionName;
}
public void setBean(String[] bean) {
this.bean = bean;
}
public String[] getLocation() {
public String getLocation() {
return this.location;
}
public void setLocation(String[] location) {
public void setLocation(String location) {
this.location = location;
}
public String getMain() {
return this.main;
}
public void setMain(String main) {
this.main = main;
}
@PostConstruct
public void init() {
if (this.location.length == 0) {
throw new IllegalStateException(
"No archive location provided, please configure function.location as a jar or directory.");
}
Assert.notNull(this.location, "No archive location provided, please configure spring.cloud.function.location as a jar or directory.");
}
}