diff --git a/.mvn/maven.config b/.mvn/maven.config
index 3b8cf46e..4f6803e2 100644
--- a/.mvn/maven.config
+++ b/.mvn/maven.config
@@ -1 +1 @@
--DaltSnapshotDeploymentRepository=repo.spring.io::default::https://repo.spring.io/libs-snapshot-local -P spring
+-DaltSnapshotDeploymentRepository=repo.spring.io::default::https://repo.spring.io/libs-snapshot-local
diff --git a/README.adoc b/README.adoc
index 675a6b82..bd52422e 100644
--- a/README.adoc
+++ b/README.adoc
@@ -36,7 +36,7 @@ The following are the various components of this repository.
|link:functions/supplier/ftp-supplier/README.adoc[FTP]
|link:functions/function/header-enricher-function/README.adoc[Header-Enricher]
|link:functions/consumer/elasticsearch-consumer/README.adoc[Elasticsearch]
-|link:functions/supplier/geode-supplier/README.adoc[Geode]
+// |link:functions/supplier/geode-supplier/README.adoc[Geode]
|link:functions/function/http-request-function/README.adoc[HTTP Request]
|link:functions/consumer/file-consumer/README.adoc[File]
|link:functions/supplier/http-supplier/README.adoc[HTTP]
@@ -44,7 +44,7 @@ The following are the various components of this repository.
|link:functions/consumer/ftp-consumer/README.adoc[FTP]
|link:functions/supplier/jdbc-supplier/README.adoc[JDBC]
|link:functions/function/object-detection-function/README.adoc[Object Detection(Tensorflow)]
-|link:functions/consumer/geode-consumer/README.adoc[Geode]
+// |link:functions/consumer/geode-consumer/README.adoc[Geode]
|link:functions/supplier/jms-supplier/README.adoc[JMS]
|link:functions/function/semantic-segmentation-function/README.adoc[Semantic Segmentation(Tensorflow)]
|link:functions/consumer/jdbc-consumer/README.adoc[JDBC]
diff --git a/functions/common/pom.xml b/functions/common/pom.xml
index 03de6d9b..945a29b1 100644
--- a/functions/common/pom.xml
+++ b/functions/common/pom.xml
@@ -25,6 +25,7 @@
tensorflow-common
cdc-debezium-common
cdc-debezium-boot-starter
+ xmpp-common
diff --git a/functions/common/xmpp-common/pom.xml b/functions/common/xmpp-common/pom.xml
new file mode 100644
index 00000000..8876264d
--- /dev/null
+++ b/functions/common/xmpp-common/pom.xml
@@ -0,0 +1,24 @@
+
+
+ 4.0.0
+
+
+ org.springframework.cloud.fn
+ spring-functions-parent
+ 4.0.0-SNAPSHOT
+ ../../spring-functions-parent/pom.xml
+
+
+ xmpp-common
+ xmpp-common
+ XMPP common
+
+
+
+ org.springframework.integration
+ spring-integration-xmpp
+
+
+
+
diff --git a/functions/common/xmpp-common/src/main/java/org/springframework/cloud/fn/common/xmpp/XmppConnectionFactoryConfiguration.java b/functions/common/xmpp-common/src/main/java/org/springframework/cloud/fn/common/xmpp/XmppConnectionFactoryConfiguration.java
new file mode 100644
index 00000000..1918f59c
--- /dev/null
+++ b/functions/common/xmpp-common/src/main/java/org/springframework/cloud/fn/common/xmpp/XmppConnectionFactoryConfiguration.java
@@ -0,0 +1,63 @@
+/*
+ * Copyright 2014-2022 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.fn.common.xmpp;
+
+import org.jivesoftware.smack.tcp.XMPPTCPConnectionConfiguration;
+import org.jxmpp.stringprep.XmppStringprepException;
+import org.jxmpp.util.XmppStringUtils;
+
+import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
+import org.springframework.boot.context.properties.EnableConfigurationProperties;
+import org.springframework.context.annotation.Bean;
+import org.springframework.context.annotation.Configuration;
+import org.springframework.integration.xmpp.config.XmppConnectionFactoryBean;
+import org.springframework.util.StringUtils;
+
+@Configuration
+@EnableConfigurationProperties(XmppConnectionFactoryProperties.class)
+public class XmppConnectionFactoryConfiguration {
+
+ @Bean
+ @ConditionalOnMissingBean
+ public XmppConnectionFactoryBean xmppConnectionFactoryBean(XmppConnectionFactoryProperties properties) throws XmppStringprepException {
+
+ XmppConnectionFactoryBean xmppConnectionFactoryBean = new XmppConnectionFactoryBean();
+ xmppConnectionFactoryBean.setSubscriptionMode(properties.getSubscriptionMode());
+
+ XMPPTCPConnectionConfiguration.Builder builder = XMPPTCPConnectionConfiguration.builder();
+ builder.setSecurityMode(properties.getSecurityMode());
+ builder.setHost(properties.getHost());
+ builder.setPort(properties.getPort());
+ if (StringUtils.hasText(properties.getResource())) {
+ builder.setResource(properties.getResource());
+ }
+
+ if (StringUtils.hasText(properties.getServiceName())) {
+ builder.setUsernameAndPassword(properties.getUser(), properties.getPassword())
+ .setXmppDomain(properties.getServiceName());
+ }
+ else {
+ builder.setUsernameAndPassword(XmppStringUtils.parseLocalpart(properties.getUser()), properties.getPassword())
+ .setXmppDomain(properties.getUser());
+ }
+
+ xmppConnectionFactoryBean.setConnectionConfiguration(builder.build());
+
+ return xmppConnectionFactoryBean;
+ }
+
+}
diff --git a/functions/common/xmpp-common/src/main/java/org/springframework/cloud/fn/common/xmpp/XmppConnectionFactoryProperties.java b/functions/common/xmpp-common/src/main/java/org/springframework/cloud/fn/common/xmpp/XmppConnectionFactoryProperties.java
new file mode 100644
index 00000000..aaf0e958
--- /dev/null
+++ b/functions/common/xmpp-common/src/main/java/org/springframework/cloud/fn/common/xmpp/XmppConnectionFactoryProperties.java
@@ -0,0 +1,138 @@
+/*
+ * Copyright 2014-2022 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.fn.common.xmpp;
+
+import jakarta.validation.constraints.NotEmpty;
+import org.jivesoftware.smack.ConnectionConfiguration;
+import org.jivesoftware.smack.roster.Roster;
+
+import org.springframework.boot.context.properties.ConfigurationProperties;
+import org.springframework.validation.annotation.Validated;
+
+/**
+ *
+ * @author Daniel Frey
+ * @since 4.0.0
+ */
+@ConfigurationProperties("xmpp.factory")
+@Validated
+public class XmppConnectionFactoryProperties {
+
+ /**
+ * The Resource to bind to on the XMPP Host.
+ * - Can be empty, server will generate one if not set
+ */
+ private String resource;
+
+ /**
+ * The User the connection should connect as.
+ */
+ private String user;
+
+ /**
+ * The Password for the connected user.
+ */
+ private String password;
+
+ /**
+ * The Service Name to set for the XMPP Domain.
+ */
+ private String serviceName;
+
+ /**
+ * XMPP Host server to connect to.
+ */
+ private String host;
+
+ /**
+ * Port for connecting to the host.
+ * - Default Client Port: 5222
+ */
+ private int port = 5222;
+
+ private Roster.SubscriptionMode subscriptionMode = Roster.getDefaultSubscriptionMode();
+
+ private ConnectionConfiguration.SecurityMode securityMode = ConnectionConfiguration.SecurityMode.required;
+
+ public void setResource(String resource) {
+ this.resource = resource;
+ }
+
+ public String getResource() {
+ return resource;
+ }
+
+ public void setUser(String user) {
+ this.user = user;
+ }
+
+ @NotEmpty(message = "user is required")
+ public String getUser() {
+ return user;
+ }
+
+ public void setPassword(String password) {
+ this.password = password;
+ }
+
+ @NotEmpty(message = "port is required")
+ public String getPassword() {
+ return password;
+ }
+
+ public void setServiceName(String serviceName) {
+ this.serviceName = serviceName;
+ }
+
+ public String getServiceName() {
+ return serviceName;
+ }
+
+ public void setHost(String host) {
+ this.host = host;
+ }
+
+ @NotEmpty(message = "host is required")
+ public String getHost() {
+ return host;
+ }
+
+ public void setPort(int port) {
+ this.port = port;
+ }
+
+ public int getPort() {
+ return port;
+ }
+
+ public void setSubscriptionMode(Roster.SubscriptionMode subscriptionMode) {
+ this.subscriptionMode = subscriptionMode;
+ }
+
+ public Roster.SubscriptionMode getSubscriptionMode() {
+ return subscriptionMode;
+ }
+
+ public void setSecurityMode(ConnectionConfiguration.SecurityMode securityMode) {
+ this.securityMode = securityMode;
+ }
+
+ public ConnectionConfiguration.SecurityMode getSecurityMode() {
+ return securityMode;
+ }
+
+}
diff --git a/functions/consumer/pom.xml b/functions/consumer/pom.xml
index f7265299..4e1aa926 100644
--- a/functions/consumer/pom.xml
+++ b/functions/consumer/pom.xml
@@ -30,6 +30,7 @@
twitter-consumer
wavefront-consumer
rsocket-consumer
+ xmpp-consumer
zeromq-consumer
diff --git a/functions/consumer/xmpp-consumer/README.adoc b/functions/consumer/xmpp-consumer/README.adoc
new file mode 100644
index 00000000..69fb6848
--- /dev/null
+++ b/functions/consumer/xmpp-consumer/README.adoc
@@ -0,0 +1,30 @@
+# XMPP Consumer
+
+A consumer that allows you to send messages through a XMPP server.
+
+## Beans for injection
+
+You can import the `XmppConsumerConfiguration` in the application and then inject the following bean.
+
+`Consumer xmppConsumer`
+
+You need to inject this as `Consumer xmppConsumer`.
+
+You can use `xmppConsumer` as a qualifier when injecting.
+
+**NOTE:** This is a functional endpoint. One will need to subscribe to this endpoint in order to start accepting data
+on it.
+
+## Configuration Options
+
+All configuration properties are prefixed with `xmpp.consumer`.
+
+For more information on the various options available, please see link:src/main/java/org/springframework/cloud/fn/consumer/xmpp/XmppConsumerProperties.java[XmppConsumerProperties].
+
+## Tests
+
+See this link:src/test/java/org/springframework/cloud/fn/consumer/xmpp/[test suite] for the various ways, this consumer is used.
+
+## Other usage
+
+See this https://github.com/spring-cloud/stream-applications/blob/master/applications/sink/xmpp-sink/README.adoc[README] where this consumer is used to create a Spring Cloud Stream application where it makes a XMPP Sink.
diff --git a/functions/consumer/xmpp-consumer/pom.xml b/functions/consumer/xmpp-consumer/pom.xml
new file mode 100644
index 00000000..91204ed0
--- /dev/null
+++ b/functions/consumer/xmpp-consumer/pom.xml
@@ -0,0 +1,34 @@
+
+
+ 4.0.0
+
+
+ org.springframework.cloud.fn
+ spring-functions-parent
+ 4.0.0-SNAPSHOT
+ ../../spring-functions-parent/pom.xml
+
+
+ xmpp-consumer
+ xmpp-consumer
+ XMPP consumer
+
+
+
+
+ org.springframework.cloud.fn
+ xmpp-common
+ ${project.version}
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/functions/consumer/xmpp-consumer/src/main/java/org/springframework/cloud/fn/consumer/xmpp/XmppConsumerConfiguration.java b/functions/consumer/xmpp-consumer/src/main/java/org/springframework/cloud/fn/consumer/xmpp/XmppConsumerConfiguration.java
new file mode 100644
index 00000000..48f6f719
--- /dev/null
+++ b/functions/consumer/xmpp-consumer/src/main/java/org/springframework/cloud/fn/consumer/xmpp/XmppConsumerConfiguration.java
@@ -0,0 +1,63 @@
+/*
+ * Copyright 2014-2022 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.fn.consumer.xmpp;
+
+import java.util.function.Consumer;
+
+import org.jivesoftware.smack.XMPPConnection;
+
+import org.springframework.boot.context.properties.EnableConfigurationProperties;
+import org.springframework.cloud.fn.common.xmpp.XmppConnectionFactoryConfiguration;
+import org.springframework.context.annotation.Bean;
+import org.springframework.context.annotation.Configuration;
+import org.springframework.context.annotation.Import;
+import org.springframework.integration.xmpp.XmppHeaders;
+import org.springframework.integration.xmpp.outbound.ChatMessageSendingMessageHandler;
+import org.springframework.messaging.Message;
+import org.springframework.messaging.support.MessageBuilder;
+
+/**
+ *
+ * @author Daniel Frey
+ * @since 4.0.0
+ */
+@Configuration
+@EnableConfigurationProperties(XmppConsumerProperties.class)
+@Import(XmppConnectionFactoryConfiguration.class)
+public class XmppConsumerConfiguration {
+
+ @Bean
+ public ChatMessageSendingMessageHandler chatMessageSendingMessageHandler(XMPPConnection xmppConnection) {
+
+ return new ChatMessageSendingMessageHandler(xmppConnection);
+ }
+
+ @Bean
+ public Consumer> xmppConsumer(ChatMessageSendingMessageHandler chatMessageSendingMessageHandler, XmppConsumerProperties properties) {
+ return message -> {
+
+ Message> send = MessageBuilder
+ .fromMessage(message)
+ .setHeaderIfAbsent(XmppHeaders.TO, properties.getChatTo())
+ .build();
+
+ chatMessageSendingMessageHandler.handleMessage(send);
+
+ };
+ }
+
+}
diff --git a/functions/consumer/xmpp-consumer/src/main/java/org/springframework/cloud/fn/consumer/xmpp/XmppConsumerProperties.java b/functions/consumer/xmpp-consumer/src/main/java/org/springframework/cloud/fn/consumer/xmpp/XmppConsumerProperties.java
new file mode 100644
index 00000000..32a44dfb
--- /dev/null
+++ b/functions/consumer/xmpp-consumer/src/main/java/org/springframework/cloud/fn/consumer/xmpp/XmppConsumerProperties.java
@@ -0,0 +1,44 @@
+/*
+ * Copyright 2014-2022 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.fn.consumer.xmpp;
+
+import org.springframework.boot.context.properties.ConfigurationProperties;
+import org.springframework.validation.annotation.Validated;
+
+/**
+ *
+ * @author Daniel Frey
+ * @since 4.0.0
+ */
+@ConfigurationProperties("xmpp.consumer")
+@Validated
+public class XmppConsumerProperties {
+
+ /**
+ * XMPP handle to send message to.
+ */
+ private String chatTo;
+
+ public void setChatTo(String chatTo) {
+ this.chatTo = chatTo;
+ }
+
+ public String getChatTo() {
+ return chatTo;
+ }
+
+}
diff --git a/functions/consumer/xmpp-consumer/src/test/docker-compose/xmpp/_data/openfire/conf/available-plugins.xml b/functions/consumer/xmpp-consumer/src/test/docker-compose/xmpp/_data/openfire/conf/available-plugins.xml
new file mode 100755
index 00000000..b070cec2
--- /dev/null
+++ b/functions/consumer/xmpp-consumer/src/test/docker-compose/xmpp/_data/openfire/conf/available-plugins.xml
@@ -0,0 +1,59 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/functions/consumer/xmpp-consumer/src/test/docker-compose/xmpp/_data/openfire/conf/crowd.properties b/functions/consumer/xmpp-consumer/src/test/docker-compose/xmpp/_data/openfire/conf/crowd.properties
new file mode 100755
index 00000000..d43a8ba4
--- /dev/null
+++ b/functions/consumer/xmpp-consumer/src/test/docker-compose/xmpp/_data/openfire/conf/crowd.properties
@@ -0,0 +1,42 @@
+#
+# This file defines the configuration properties required
+# when using the Atlassian Crowd integration for Openfire.
+#
+# https://confluence.atlassian.com/display/CROWD/The+crowd.properties+file
+#
+# To activate the Crowd integration for Openfire, you must define
+# the following Openfire system properties:
+#
+# provider.admin.className org.jivesoftware.openfire.crowd.CrowdAdminProvider
+# provider.auth.className org.jivesoftware.openfire.crowd.CrowdAuthProvider
+# provider.group.className org.jivesoftware.openfire.crowd.CrowdGroupProvider
+# provider.user.className org.jivesoftware.openfire.crowd.CrowdUserProvider
+# provider.vcard.className org.jivesoftware.openfire.crowd.CrowdVCardProvider
+#
+# In addition, you may customize the Crowd provider using the following Openfire
+# system properties:
+#
+# admin.authorizedGroups
+# crowd.groups.cache.ttl.seconds 3600
+# crowd.users.cache.ttl.seconds 3600
+#
+
+# The REST URL for your Crowd server.
+crowd.server.url=https://YOUR-CROWD-SERVER:8095/crowd/
+
+# These properties are required to authenticate with the Crowd server.
+# They must match the values specified in the Crowd configuration.
+application.name=openfire
+application.password=
+
+# Other optional configuration properties.
+
+#http.proxy.host=
+#http.proxy.port=
+#http.proxy.username=
+#http.proxy.password=
+
+# These properties can be used to tune the Crowd integration.
+#http.max.connections=20
+#http.timeout=5000
+#http.socket.timeout=20000
diff --git a/functions/consumer/xmpp-consumer/src/test/docker-compose/xmpp/_data/openfire/conf/openfire-demoboot.xml b/functions/consumer/xmpp-consumer/src/test/docker-compose/xmpp/_data/openfire/conf/openfire-demoboot.xml
new file mode 100755
index 00000000..8855c30b
--- /dev/null
+++ b/functions/consumer/xmpp-consumer/src/test/docker-compose/xmpp/_data/openfire/conf/openfire-demoboot.xml
@@ -0,0 +1,54 @@
+
+
+
+ 9090
+ 9091
+
+
+ org.jivesoftware.database.EmbeddedConnectionProvider
+
+
+ true
+ en
+
+
+ true
+
+ localhost
+ localhost
+
+
+ embedded
+
+
+ admin@example.com
+ admin
+
+
+
+ john
+ secret
+ John Doe
+ john.doe@example.com
+
+
+ jane@localhost
+ Jane
+
+
+
+
+ jane
+ secret
+ Jane Doe
+ jane.doe@example.com
+
+
+ john@localhost
+ John
+
+
+
+
+
+
diff --git a/functions/consumer/xmpp-consumer/src/test/docker-compose/xmpp/_data/openfire/conf/openfire.xml b/functions/consumer/xmpp-consumer/src/test/docker-compose/xmpp/_data/openfire/conf/openfire.xml
new file mode 100644
index 00000000..2c9f7e3d
--- /dev/null
+++ b/functions/consumer/xmpp-consumer/src/test/docker-compose/xmpp/_data/openfire/conf/openfire.xml
@@ -0,0 +1,14 @@
+
+
+
+
+ 9090
+ 9091
+
+
+ org.jivesoftware.database.DefaultConnectionProvider
+
+ true
+ en
+ localhost
+
diff --git a/functions/consumer/xmpp-consumer/src/test/docker-compose/xmpp/_data/openfire/conf/security.xml b/functions/consumer/xmpp-consumer/src/test/docker-compose/xmpp/_data/openfire/conf/security.xml
new file mode 100644
index 00000000..41850216
--- /dev/null
+++ b/functions/consumer/xmpp-consumer/src/test/docker-compose/xmpp/_data/openfire/conf/security.xml
@@ -0,0 +1,66 @@
+
+
+
+
+
+
+ Blowfish
+
+
+
+
+
+
+ database.defaultProvider.username
+ database.defaultProvider.password
+
+
+
+
diff --git a/functions/consumer/xmpp-consumer/src/test/docker-compose/xmpp/_data/openfire/conf/security/archive/readme.txt b/functions/consumer/xmpp-consumer/src/test/docker-compose/xmpp/_data/openfire/conf/security/archive/readme.txt
new file mode 100755
index 00000000..62573a55
--- /dev/null
+++ b/functions/consumer/xmpp-consumer/src/test/docker-compose/xmpp/_data/openfire/conf/security/archive/readme.txt
@@ -0,0 +1 @@
+This directory is used as a default location in which Openfire stores backups of keystore files.
diff --git a/functions/consumer/xmpp-consumer/src/test/docker-compose/xmpp/_data/openfire/conf/security/client.truststore b/functions/consumer/xmpp-consumer/src/test/docker-compose/xmpp/_data/openfire/conf/security/client.truststore
new file mode 100755
index 00000000..c4084655
Binary files /dev/null and b/functions/consumer/xmpp-consumer/src/test/docker-compose/xmpp/_data/openfire/conf/security/client.truststore differ
diff --git a/functions/consumer/xmpp-consumer/src/test/docker-compose/xmpp/_data/openfire/conf/security/keystore b/functions/consumer/xmpp-consumer/src/test/docker-compose/xmpp/_data/openfire/conf/security/keystore
new file mode 100755
index 00000000..1405b0f0
Binary files /dev/null and b/functions/consumer/xmpp-consumer/src/test/docker-compose/xmpp/_data/openfire/conf/security/keystore differ
diff --git a/functions/consumer/xmpp-consumer/src/test/docker-compose/xmpp/_data/openfire/conf/security/truststore b/functions/consumer/xmpp-consumer/src/test/docker-compose/xmpp/_data/openfire/conf/security/truststore
new file mode 100755
index 00000000..cc04a653
Binary files /dev/null and b/functions/consumer/xmpp-consumer/src/test/docker-compose/xmpp/_data/openfire/conf/security/truststore differ
diff --git a/functions/consumer/xmpp-consumer/src/test/docker-compose/xmpp/_data/openfire/conf/server-update.xml b/functions/consumer/xmpp-consumer/src/test/docker-compose/xmpp/_data/openfire/conf/server-update.xml
new file mode 100755
index 00000000..c8b65634
--- /dev/null
+++ b/functions/consumer/xmpp-consumer/src/test/docker-compose/xmpp/_data/openfire/conf/server-update.xml
@@ -0,0 +1,4 @@
+
+
+
+
\ No newline at end of file
diff --git a/functions/consumer/xmpp-consumer/src/test/docker-compose/xmpp/docker-compose.yml b/functions/consumer/xmpp-consumer/src/test/docker-compose/xmpp/docker-compose.yml
new file mode 100644
index 00000000..d7e38c47
--- /dev/null
+++ b/functions/consumer/xmpp-consumer/src/test/docker-compose/xmpp/docker-compose.yml
@@ -0,0 +1,10 @@
+version: "3.7"
+services:
+ Openfire:
+ image: fishbowler/openfire:latest
+ ports:
+ - "5222:5222"
+ volumes:
+ - ./_data/openfire/conf:/var/lib/openfire/conf
+ command:
+ - -demoboot
diff --git a/functions/consumer/xmpp-consumer/src/test/java/org/springframework/cloud/fn/consumer/xmpp/XmppConsumerConfigurationTests.java b/functions/consumer/xmpp-consumer/src/test/java/org/springframework/cloud/fn/consumer/xmpp/XmppConsumerConfigurationTests.java
new file mode 100644
index 00000000..fab99faa
--- /dev/null
+++ b/functions/consumer/xmpp-consumer/src/test/java/org/springframework/cloud/fn/consumer/xmpp/XmppConsumerConfigurationTests.java
@@ -0,0 +1,181 @@
+/*
+ * Copyright 2014-2022 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.fn.consumer.xmpp;
+
+import java.io.File;
+import java.io.IOException;
+import java.time.Duration;
+import java.util.function.Consumer;
+
+import org.jivesoftware.smack.ConnectionConfiguration;
+import org.jivesoftware.smack.SmackException;
+import org.jivesoftware.smack.StanzaCollector;
+import org.jivesoftware.smack.XMPPException;
+import org.jivesoftware.smack.filter.StanzaTypeFilter;
+import org.jivesoftware.smack.packet.Stanza;
+import org.jivesoftware.smack.tcp.XMPPTCPConnection;
+import org.jivesoftware.smack.tcp.XMPPTCPConnectionConfiguration;
+import org.junit.jupiter.api.AfterEach;
+import org.junit.jupiter.api.BeforeEach;
+import org.junit.jupiter.api.Test;
+import org.jxmpp.stringprep.XmppStringprepException;
+import org.testcontainers.containers.DockerComposeContainer;
+import org.testcontainers.junit.jupiter.Container;
+import org.testcontainers.junit.jupiter.Testcontainers;
+
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.boot.SpringBootConfiguration;
+import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
+import org.springframework.boot.test.context.SpringBootTest;
+import org.springframework.context.annotation.Import;
+import org.springframework.integration.xmpp.XmppHeaders;
+import org.springframework.messaging.Message;
+import org.springframework.messaging.support.MessageBuilder;
+import org.springframework.test.annotation.DirtiesContext;
+
+import static org.assertj.core.api.Assertions.assertThat;
+import static org.awaitility.Awaitility.await;
+
+/**
+ * @author Daniel Frey
+ *
+ * @since 4.0.0
+ */
+@SpringBootTest(
+ properties = {
+ "xmpp.factory.user=john",
+ "xmpp.factory.password=secret",
+ "xmpp.factory.host=localhost",
+ "xmpp.factory.service-name=localhost",
+ "xmpp.factory.security-mode=disabled"
+ }
+)
+@DirtiesContext
+@Testcontainers
+public class XmppConsumerConfigurationTests {
+
+ private static final String XMPP_HOST = "localhost";
+ private static final int XMPP_PORT = 5222;
+ private static final String FROM = "john";
+ private static final String TO = "jane";
+ private static final String TO_PW = "secret";
+ private static final String SERVICE_NAME = "localhost";
+
+ @Container
+ private static final DockerComposeContainer XMPP_CONTAINER =
+ new DockerComposeContainer(new File("src/test/docker-compose/xmpp/docker-compose.yml"))
+ .withExposedService("Openfire", XMPP_PORT);
+
+ @Autowired
+ private Consumer> xmppConsumer;
+
+ // A client connection is needed to receive the message from the xmpp server
+ // to verify it was received successfully
+ private XMPPTCPConnection clientConnection;
+
+ @BeforeEach
+ void setup() throws IOException, SmackException, XMPPException, InterruptedException {
+
+ XMPPTCPConnectionConfiguration.Builder builder = XMPPTCPConnectionConfiguration.builder();
+ builder.setSecurityMode(ConnectionConfiguration.SecurityMode.disabled);
+ builder.setHost(XMPP_HOST);
+ builder.setPort(XMPP_PORT);
+ builder.setResource(SERVICE_NAME);
+ builder.setUsernameAndPassword(TO, TO_PW)
+ .setXmppDomain(SERVICE_NAME);
+
+ this.clientConnection = new XMPPTCPConnection(builder.build());
+ this.clientConnection.connect();
+ this.clientConnection.login();
+
+ }
+
+ @AfterEach
+ void teardown() {
+
+ this.clientConnection.instantShutdown();
+
+ }
+
+ @Test
+ void messageHandlerConfiguration() {
+
+ StanzaCollector collector
+ = this.clientConnection.createStanzaCollector(StanzaTypeFilter.MESSAGE);
+
+ Message> testMessage =
+ MessageBuilder.withPayload("test")
+ .setHeader(XmppHeaders.TO, TO + "@" + SERVICE_NAME)
+ .build();
+
+ await().atMost(Duration.ofSeconds(20)).pollDelay(Duration.ofMillis(100))
+ .untilAsserted(() -> {
+
+ xmppConsumer.accept(testMessage);
+
+ Stanza stanza = collector.nextResult();
+ assertStanza(stanza);
+
+ });
+
+ }
+
+ @Test
+ void xmppMessageHandlerConfiguration() throws XmppStringprepException {
+
+ StanzaCollector collector
+ = this.clientConnection.createStanzaCollector(StanzaTypeFilter.MESSAGE);
+
+ Message> testMessage =
+ MessageBuilder.withPayload(org.jivesoftware.smack.packet.MessageBuilder.buildMessage().addBody("en_us", "test").to(TO + "@" + SERVICE_NAME).build())
+ .build();
+
+ await().atMost(Duration.ofSeconds(20)).pollDelay(Duration.ofMillis(100))
+ .untilAsserted(() -> {
+
+ xmppConsumer.accept(testMessage);
+
+ Stanza stanza = collector.nextResult();
+ assertStanza(stanza);
+
+ });
+
+ }
+
+ private void assertStanza(Stanza stanza) {
+ assertTo(stanza);
+ assertFrom(stanza);
+ }
+
+ private void assertTo(Stanza stanza) {
+
+ assertThat(stanza.getTo().asBareJid().asUnescapedString()).isEqualTo(TO + "@" + SERVICE_NAME);
+
+ }
+
+ private void assertFrom(Stanza stanza) {
+
+ assertThat(stanza.getFrom().asBareJid().asUnescapedString()).isEqualTo(FROM + "@" + SERVICE_NAME);
+
+ }
+
+ @SpringBootConfiguration
+ @EnableAutoConfiguration
+ @Import(XmppConsumerConfiguration.class)
+ static class XmppConsumerTestApplication { }
+
+}
diff --git a/functions/function-dependencies/pom.xml b/functions/function-dependencies/pom.xml
index ae520ad9..6e685ac0 100644
--- a/functions/function-dependencies/pom.xml
+++ b/functions/function-dependencies/pom.xml
@@ -42,11 +42,6 @@
ftp-supplier
${project.version}
-
- org.springframework.cloud.fn
- geode-supplier
- ${project.version}
-
org.springframework.cloud.fn
http-supplier
@@ -142,11 +137,6 @@
ftp-consumer
${project.version}
-
- org.springframework.cloud.fn
- geode-consumer
- ${project.version}
-
org.springframework.cloud.fn
jdbc-consumer
@@ -197,6 +187,11 @@
twitter-consumer
${project.version}
+
+ org.springframework.cloud.fn
+ xmpp-consumer
+ ${project.version}
+
org.springframework.cloud.fn
wavefront-consumer
diff --git a/stream-applications-release-train/stream-applications-docs/pom.xml b/stream-applications-release-train/stream-applications-docs/pom.xml
index 5806401e..b8d1845b 100644
--- a/stream-applications-release-train/stream-applications-docs/pom.xml
+++ b/stream-applications-release-train/stream-applications-docs/pom.xml
@@ -44,7 +44,8 @@
org.springframework.cloud.fn
geode-common
- ${java-functions.version}
+
+ 1.2.1
org.springframework.cloud.fn
@@ -82,11 +83,11 @@
ftp-supplier
${java-functions.version}
-
- org.springframework.cloud.fn
- geode-supplier
- ${java-functions.version}
-
+
+
+
+
+
org.springframework.cloud.fn
http-supplier
@@ -193,11 +194,11 @@
ftp-consumer
${java-functions.version}
-
- org.springframework.cloud.fn
- geode-consumer
- ${java-functions.version}
-
+
+
+
+
+
org.springframework.cloud.fn
jdbc-consumer