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