diff --git a/applications/processor/header-enricher-processor/README.adoc b/applications/processor/header-enricher-processor/README.adoc index b2e5f8f3..ee3972d6 100644 --- a/applications/processor/header-enricher-processor/README.adoc +++ b/applications/processor/header-enricher-processor/README.adoc @@ -12,7 +12,7 @@ The **$$header-enricher$$** $$processor$$ has the following options: //tag::configuration-properties[] $$header.enricher.headers$$:: $$\n separated properties representing headers in which values are SpEL expressions, e.g foo='bar' \n baz=payload.baz.$$ *($$Properties$$, default: `$$$$`)* -$$header.enricher.overwrite$$:: $$set to true to overwrite any existing message headers.$$ *($$Boolean$$, default: `$$false$$`)* +$$header.enricher.overwrite$$:: $$set to true to overwrite any existing message headers.$$ *($$Boolean$$, default: `$$$$`)* //end::configuration-properties[] //end::ref-doc[] diff --git a/applications/processor/http-request-processor/README.adoc b/applications/processor/http-request-processor/README.adoc index 44a8b477..b4ef1306 100644 --- a/applications/processor/http-request-processor/README.adoc +++ b/applications/processor/http-request-processor/README.adoc @@ -53,7 +53,7 @@ $$expected-response-type$$:: $$The type used to interpret the response.$$ *($$Cl $$headers-expression$$:: $$A SpEL expression used to derive the http headers map to use.$$ *($$Expression$$, default: `$$$$`)* $$http-method-expression$$:: $$A SpEL expression to derive the request method from the incoming message.$$ *($$Expression$$, default: `$$$$`)* $$reply-expression$$:: $$A SpEL expression used to compute the final result, applied against the whole http {@link org.springframework.http.ResponseEntity}.$$ *($$Expression$$, default: `$$$$`)* -$$timeout$$:: $$Request timeout in milliseconds.$$ *($$Long$$, default: `$$30000$$`)* +$$timeout$$:: $$Request timeout in milliseconds.$$ *($$Long$$, default: `$$$$`)* $$url-expression$$:: $$A SpEL expression against incoming message to determine the URL to use.$$ *($$Expression$$, default: `$$$$`)* === spring.codec diff --git a/applications/processor/image-recognition-processor/README.adoc b/applications/processor/image-recognition-processor/README.adoc index 7fb79c0b..71a84301 100644 --- a/applications/processor/image-recognition-processor/README.adoc +++ b/applications/processor/image-recognition-processor/README.adoc @@ -41,13 +41,13 @@ If the incoming type is `byte[]` and the content type is set to `application/oct == Options //tag::configuration-properties[] -$$image.recognition.cache-model$$:: $$cache the pre-trained tensorflow model.$$ *($$Boolean$$, default: `$$true$$`)* -$$image.recognition.debug-output$$:: $$$$ *($$Boolean$$, default: `$$false$$`)* -$$image.recognition.debug-output-path$$:: $$$$ *($$String$$, default: `$$image-recognition-result.png$$`)* -$$image.recognition.model$$:: $$pre-trained tensorflow image recognition model. Note that the model must match the selected model type!$$ *($$String$$, default: `$$https://storage.googleapis.com/mobilenet_v2/checkpoints/mobilenet_v2_1.4_224.tgz#mobilenet_v2_1.4_224_frozen.pb$$`)* +$$image.recognition.cache-model$$:: $$cache the pre-trained tensorflow model.$$ *($$Boolean$$, default: `$$$$`)* +$$image.recognition.debug-output$$:: $$$$ *($$Boolean$$, default: `$$$$`)* +$$image.recognition.debug-output-path$$:: $$$$ *($$String$$, default: `$$$$`)* +$$image.recognition.model$$:: $$pre-trained tensorflow image recognition model. Note that the model must match the selected model type!$$ *($$String$$, default: `$$$$`)* $$image.recognition.model-type$$:: $$Supports three different pre-trained tensorflow image recognition models: Inception, MobileNetV1 and MobileNetV2 1. Inception graph uses 'input' as input and 'output' as output. 2. MobileNetV2 pre-trained models: https://github.com/tensorflow/models/tree/master/research/slim/nets/mobilenet#pretrained-models - normalized image size is always square (e.g. H=W) - graph uses 'input' as input and 'MobilenetV2/Predictions/Reshape_1' as output. 3. MobileNetV1 pre-trained models: https://github.com/tensorflow/models/blob/master/research/slim/nets/mobilenet_v1.md#pre-trained-models - graph uses 'input' as input and 'MobilenetV1/Predictions/Reshape_1' as output.$$ *($$ModelType$$, default: `$$$$`, possible values: `inception`,`mobilenetv1`,`mobilenetv2`)* -$$image.recognition.normalized-image-size$$:: $$Normalized image size.$$ *($$Integer$$, default: `$$224$$`)* -$$image.recognition.response-size$$:: $$number of recognized images.$$ *($$Integer$$, default: `$$5$$`)* +$$image.recognition.normalized-image-size$$:: $$Normalized image size.$$ *($$Integer$$, default: `$$$$`)* +$$image.recognition.response-size$$:: $$number of recognized images.$$ *($$Integer$$, default: `$$$$`)* //end::configuration-properties[] //end::ref-doc[] diff --git a/applications/processor/object-detection-processor/README.adoc b/applications/processor/object-detection-processor/README.adoc index 345fa79c..eba703b3 100644 --- a/applications/processor/object-detection-processor/README.adoc +++ b/applications/processor/object-detection-processor/README.adoc @@ -43,14 +43,14 @@ The incoming type is `byte[]`, and the content type is `application/octet-stream == Options //tag::configuration-properties[] -$$object.detection.cache-model$$:: $$$$ *($$Boolean$$, default: `$$true$$`)* -$$object.detection.confidence$$:: $$$$ *($$Float$$, default: `$$0.4$$`)* -$$object.detection.debug-output$$:: $$$$ *($$Boolean$$, default: `$$false$$`)* -$$object.detection.debug-output-path$$:: $$$$ *($$String$$, default: `$$object-detection-result.png$$`)* -$$object.detection.labels$$:: $$Labels URI.$$ *($$String$$, default: `$$https://storage.googleapis.com/scdf-tensorflow-models/object-detection/mscoco_label_map.pbtxt$$`)* -$$object.detection.model$$:: $$pre-trained tensorflow object detection model.$$ *($$String$$, default: `$$https://download.tensorflow.org/models/object_detection/ssdlite_mobilenet_v2_coco_2018_05_09.tar.gz#frozen_inference_graph.pb$$`)* +$$object.detection.cache-model$$:: $$$$ *($$Boolean$$, default: `$$$$`)* +$$object.detection.confidence$$:: $$$$ *($$Float$$, default: `$$$$`)* +$$object.detection.debug-output$$:: $$$$ *($$Boolean$$, default: `$$$$`)* +$$object.detection.debug-output-path$$:: $$$$ *($$String$$, default: `$$$$`)* +$$object.detection.labels$$:: $$Labels URI.$$ *($$String$$, default: `$$$$`)* +$$object.detection.model$$:: $$pre-trained tensorflow object detection model.$$ *($$String$$, default: `$$$$`)* $$object.detection.response-size$$:: $$$$ *($$Integer$$, default: `$$$$`)* -$$object.detection.with-masks$$:: $$$$ *($$Boolean$$, default: `$$false$$`)* +$$object.detection.with-masks$$:: $$$$ *($$Boolean$$, default: `$$$$`)* //end::configuration-properties[] //end::ref-doc[] diff --git a/applications/processor/semantic-segmentation-processor/README.adoc b/applications/processor/semantic-segmentation-processor/README.adoc index 2a8ba95a..c2f6228b 100644 --- a/applications/processor/semantic-segmentation-processor/README.adoc +++ b/applications/processor/semantic-segmentation-processor/README.adoc @@ -30,11 +30,11 @@ The output header json format represents the color pixel map computed from the i == Options //tag::configuration-properties[] -$$semantic.segmentation.color-map-uri$$:: $$Every pre-trained model is based on certain object color maps. The pre-defined options are: - classpath:/colormap/citymap_colormap.json - classpath:/colormap/ade20k_colormap.json - classpath:/colormap/black_white_colormap.json - classpath:/colormap/mapillary_colormap.json$$ *($$String$$, default: `$$classpath:/colormap/citymap_colormap.json$$`)* -$$semantic.segmentation.debug-output$$:: $$save output image inn the local debugOutputPath path.$$ *($$Boolean$$, default: `$$false$$`)* -$$semantic.segmentation.debug-output-path$$:: $$$$ *($$String$$, default: `$$semantic-segmentation-result.png$$`)* -$$semantic.segmentation.mask-transparency$$:: $$The alpha color of the computed segmentation mask image.$$ *($$Float$$, default: `$$0.45$$`)* -$$semantic.segmentation.model$$:: $$pre-trained tensorflow semantic segmentation model.$$ *($$String$$, default: `$$https://download.tensorflow.org/models/deeplabv3_mnv2_cityscapes_train_2018_02_05.tar.gz#frozen_inference_graph.pb$$`)* +$$semantic.segmentation.color-map-uri$$:: $$Every pre-trained model is based on certain object color maps. The pre-defined options are: - classpath:/colormap/citymap_colormap.json - classpath:/colormap/ade20k_colormap.json - classpath:/colormap/black_white_colormap.json - classpath:/colormap/mapillary_colormap.json$$ *($$String$$, default: `$$$$`)* +$$semantic.segmentation.debug-output$$:: $$save output image inn the local debugOutputPath path.$$ *($$Boolean$$, default: `$$$$`)* +$$semantic.segmentation.debug-output-path$$:: $$$$ *($$String$$, default: `$$$$`)* +$$semantic.segmentation.mask-transparency$$:: $$The alpha color of the computed segmentation mask image.$$ *($$Float$$, default: `$$$$`)* +$$semantic.segmentation.model$$:: $$pre-trained tensorflow semantic segmentation model.$$ *($$String$$, default: `$$$$`)* $$semantic.segmentation.output-type$$:: $$Specifies the output image type. You can return either the input image with the computed mask overlay, or the mask alone.$$ *($$OutputType$$, default: `$$$$`, possible values: `blended`,`mask`)* //end::configuration-properties[] diff --git a/applications/processor/splitter-processor/README.adoc b/applications/processor/splitter-processor/README.adoc index 08834790..2dc0d4bd 100644 --- a/applications/processor/splitter-processor/README.adoc +++ b/applications/processor/splitter-processor/README.adoc @@ -17,12 +17,12 @@ If the incoming type is `byte[]` and the content type is set to `text/plain` or == Options //tag::configuration-properties[] -$$splitter.apply-sequence$$:: $$Add correlation/sequence information in headers to facilitate later aggregation.$$ *($$Boolean$$, default: `$$true$$`)* +$$splitter.apply-sequence$$:: $$Add correlation/sequence information in headers to facilitate later aggregation.$$ *($$Boolean$$, default: `$$$$`)* $$splitter.charset$$:: $$The charset to use when converting bytes in text-based files to String.$$ *($$String$$, default: `$$$$`)* $$splitter.delimiters$$:: $$When expression is null, delimiters to use when tokenizing {@link String} payloads.$$ *($$String$$, default: `$$$$`)* $$splitter.expression$$:: $$A SpEL expression for splitting payloads.$$ *($$String$$, default: `$$$$`)* $$splitter.file-markers$$:: $$Set to true or false to use a {@code FileSplitter} (to split text-based files by line) that includes (or not) beginning/end of file markers.$$ *($$Boolean$$, default: `$$$$`)* -$$splitter.markers-json$$:: $$When 'fileMarkers == true', specify if they should be produced as FileSplitter.FileMarker objects or JSON.$$ *($$Boolean$$, default: `$$true$$`)* +$$splitter.markers-json$$:: $$When 'fileMarkers == true', specify if they should be produced as FileSplitter.FileMarker objects or JSON.$$ *($$Boolean$$, default: `$$$$`)* //end::configuration-properties[] //end::ref-doc[] diff --git a/applications/processor/twitter-trend-processor/README.adoc b/applications/processor/twitter-trend-processor/README.adoc index 691466f8..dbf84aac 100644 --- a/applications/processor/twitter-trend-processor/README.adoc +++ b/applications/processor/twitter-trend-processor/README.adoc @@ -36,7 +36,7 @@ $$lon$$:: $$If provided with a lat parameter the available trend locations will === twitter.trend -$$location-id$$:: $$The Yahoo! Where On Earth ID of the location to return trending information for. Global information is available by using 1 as the WOEID.$$ *($$Expression$$, default: `$$payload$$`)* +$$location-id$$:: $$The Yahoo! Where On Earth ID of the location to return trending information for. Global information is available by using 1 as the WOEID.$$ *($$Expression$$, default: `$$$$`)* $$trend-query-type$$:: $$$$ *($$TrendQueryType$$, default: `$$$$`, possible values: `trend`,`trendLocation`)* //end::configuration-properties[] diff --git a/applications/sink/elasticsearch-sink/README.adoc b/applications/sink/elasticsearch-sink/README.adoc index 967225e1..0dc53a69 100644 --- a/applications/sink/elasticsearch-sink/README.adoc +++ b/applications/sink/elasticsearch-sink/README.adoc @@ -15,13 +15,13 @@ This is provided mainly for direct invocation of the consumer. The **$$Elasticsearch$$** $$sink$$ has the following options: //tag::configuration-properties[] -$$elasticsearch.consumer.async$$:: $$Indicates whether the indexing operation is async or not. By default indexing is done synchronously.$$ *($$Boolean$$, default: `$$false$$`)* -$$elasticsearch.consumer.batch-size$$:: $$Number of items to index for each request. It defaults to 1. For values greater than 1 bulk indexing API will be used.$$ *($$Integer$$, default: `$$1$$`)* -$$elasticsearch.consumer.group-timeout$$:: $$Timeout in milliseconds after which message group is flushed when bulk indexing is active. It defaults to -1, meaning no automatic flush of idle message groups occurs.$$ *($$Long$$, default: `$$-1$$`)* +$$elasticsearch.consumer.async$$:: $$Indicates whether the indexing operation is async or not. By default indexing is done synchronously.$$ *($$Boolean$$, default: `$$$$`)* +$$elasticsearch.consumer.batch-size$$:: $$Number of items to index for each request. It defaults to 1. For values greater than 1 bulk indexing API will be used.$$ *($$Integer$$, default: `$$$$`)* +$$elasticsearch.consumer.group-timeout$$:: $$Timeout in milliseconds after which message group is flushed when bulk indexing is active. It defaults to -1, meaning no automatic flush of idle message groups occurs.$$ *($$Long$$, default: `$$$$`)* $$elasticsearch.consumer.id$$:: $$The id of the document to index. If set, the INDEX_ID header value overrides this property on a per message basis.$$ *($$Expression$$, default: `$$$$`)* $$elasticsearch.consumer.index$$:: $$Name of the index. If set, the INDEX_NAME header value overrides this property on a per message basis.$$ *($$String$$, default: `$$$$`)* $$elasticsearch.consumer.routing$$:: $$Indicates the shard to route to. If not provided, Elasticsearch will default to a hash of the document id.$$ *($$String$$, default: `$$$$`)* -$$elasticsearch.consumer.timeout-seconds$$:: $$Timeout for the shard to be available. If not set, it defaults to 1 minute set by the Elasticsearch client.$$ *($$Long$$, default: `$$0$$`)* +$$elasticsearch.consumer.timeout-seconds$$:: $$Timeout for the shard to be available. If not set, it defaults to 1 minute set by the Elasticsearch client.$$ *($$Long$$, default: `$$$$`)* //end::configuration-properties[] == Examples of running this sink diff --git a/applications/sink/file-sink/README.adoc b/applications/sink/file-sink/README.adoc index d09c637a..de4922ca 100644 --- a/applications/sink/file-sink/README.adoc +++ b/applications/sink/file-sink/README.adoc @@ -15,14 +15,14 @@ The file sink app writes each message it receives to a file. The `file-sink` has the following options: //tag::configuration-properties[] -$$file.consumer.binary$$:: $$A flag to indicate whether adding a newline after the write should be suppressed.$$ *($$Boolean$$, default: `$$false$$`)* -$$file.consumer.charset$$:: $$The charset to use when writing text content.$$ *($$String$$, default: `$$UTF-8$$`)* +$$file.consumer.binary$$:: $$A flag to indicate whether adding a newline after the write should be suppressed.$$ *($$Boolean$$, default: `$$$$`)* +$$file.consumer.charset$$:: $$The charset to use when writing text content.$$ *($$String$$, default: `$$$$`)* $$file.consumer.directory$$:: $$The parent directory of the target file.$$ *($$File$$, default: `$$$$`)* $$file.consumer.directory-expression$$:: $$The expression to evaluate for the parent directory of the target file.$$ *($$String$$, default: `$$$$`)* $$file.consumer.mode$$:: $$The FileExistsMode to use if the target file already exists.$$ *($$FileExistsMode$$, default: `$$$$`, possible values: `APPEND`,`APPEND_NO_FLUSH`,`FAIL`,`IGNORE`,`REPLACE`,`REPLACE_IF_MODIFIED`)* -$$file.consumer.name$$:: $$The name of the target file.$$ *($$String$$, default: `$$file-consumer$$`)* +$$file.consumer.name$$:: $$The name of the target file.$$ *($$String$$, default: `$$$$`)* $$file.consumer.name-expression$$:: $$The expression to evaluate for the name of the target file.$$ *($$String$$, default: `$$$$`)* -$$file.consumer.suffix$$:: $$The suffix to append to file name.$$ *($$String$$, default: `$$$$`)* +$$file.consumer.suffix$$:: $$The suffix to append to file name.$$ *($$String$$, default: `$$$$`)* //end::configuration-properties[] //end::ref-doc[] diff --git a/applications/sink/ftp-sink/README.adoc b/applications/sink/ftp-sink/README.adoc index fae1cadd..3fc09b39 100644 --- a/applications/sink/ftp-sink/README.adoc +++ b/applications/sink/ftp-sink/README.adoc @@ -37,22 +37,22 @@ Properties grouped by prefix: === ftp.consumer -$$auto-create-dir$$:: $$Whether or not to create the remote directory.$$ *($$Boolean$$, default: `$$true$$`)* +$$auto-create-dir$$:: $$Whether or not to create the remote directory.$$ *($$Boolean$$, default: `$$$$`)* $$filename-expression$$:: $$A SpEL expression to generate the remote file name.$$ *($$String$$, default: `$$$$`)* $$mode$$:: $$Action to take if the remote file already exists.$$ *($$FileExistsMode$$, default: `$$$$`, possible values: `APPEND`,`APPEND_NO_FLUSH`,`FAIL`,`IGNORE`,`REPLACE`,`REPLACE_IF_MODIFIED`)* -$$remote-dir$$:: $$The remote FTP directory.$$ *($$String$$, default: `$$/$$`)* -$$remote-file-separator$$:: $$The remote file separator.$$ *($$String$$, default: `$$/$$`)* -$$temporary-remote-dir$$:: $$A temporary directory where the file will be written if '#isUseTemporaryFilename()' is true.$$ *($$String$$, default: `$$/$$`)* -$$tmp-file-suffix$$:: $$The suffix to use while the transfer is in progress.$$ *($$String$$, default: `$$.tmp$$`)* -$$use-temporary-filename$$:: $$Whether or not to write to a temporary file and rename.$$ *($$Boolean$$, default: `$$true$$`)* +$$remote-dir$$:: $$The remote FTP directory.$$ *($$String$$, default: `$$$$`)* +$$remote-file-separator$$:: $$The remote file separator.$$ *($$String$$, default: `$$$$`)* +$$temporary-remote-dir$$:: $$A temporary directory where the file will be written if '#isUseTemporaryFilename()' is true.$$ *($$String$$, default: `$$$$`)* +$$tmp-file-suffix$$:: $$The suffix to use while the transfer is in progress.$$ *($$String$$, default: `$$$$`)* +$$use-temporary-filename$$:: $$Whether or not to write to a temporary file and rename.$$ *($$Boolean$$, default: `$$$$`)* === ftp.factory $$cache-sessions$$:: $$Cache sessions.$$ *($$Boolean$$, default: `$$$$`)* $$client-mode$$:: $$The client mode to use for the FTP session.$$ *($$ClientMode$$, default: `$$$$`, possible values: `ACTIVE`,`PASSIVE`)* -$$host$$:: $$The host name of the server.$$ *($$String$$, default: `$$localhost$$`)* +$$host$$:: $$The host name of the server.$$ *($$String$$, default: `$$$$`)* $$password$$:: $$The password to use to connect to the server.$$ *($$String$$, default: `$$$$`)* -$$port$$:: $$The port of the server.$$ *($$Integer$$, default: `$$21$$`)* +$$port$$:: $$The port of the server.$$ *($$Integer$$, default: `$$$$`)* $$username$$:: $$The username to use to connect to the server.$$ *($$String$$, default: `$$$$`)* //end::configuration-properties[] diff --git a/applications/sink/geode-sink/README.adoc b/applications/sink/geode-sink/README.adoc deleted file mode 100644 index d599fd50..00000000 --- a/applications/sink/geode-sink/README.adoc +++ /dev/null @@ -1,46 +0,0 @@ -//tag::ref-doc[] -= Geode Sink - -The Geode sink will write Message contents to a Geode region. - -== Options - -The **$$geode$$** $$sink$$ has the following options: - -//tag::configuration-properties[] -Properties grouped by prefix: - - -=== geode.consumer - -$$json$$:: $$Indicates if the Geode region stores json objects as PdxInstance.$$ *($$Boolean$$, default: `$$false$$`)* -$$key-expression$$:: $$SpEL expression to use as a cache key.$$ *($$String$$, default: `$$$$`)* - -=== geode.pool - -$$connect-type$$:: $$Specifies connection type: 'server' or 'locator'.$$ *($$ConnectType$$, default: `$$$$`, possible values: `locator`,`server`)* -$$host-addresses$$:: $$Specifies one or more Gemfire locator or server addresses formatted as [host]:[port].$$ *($$InetSocketAddress[]$$, default: `$$$$`)* -$$subscription-enabled$$:: $$Set to true to enable subscriptions for the client pool. Required to sync updates to the client cache.$$ *($$Boolean$$, default: `$$false$$`)* - -=== geode.region - -$$region-name$$:: $$The region name.$$ *($$String$$, default: `$$$$`)* - -=== geode.security - -$$password$$:: $$The cache password.$$ *($$String$$, default: `$$$$`)* -$$username$$:: $$The cache username.$$ *($$String$$, default: `$$$$`)* - -=== geode.security.ssl - -$$ciphers$$:: $$Configures the SSL ciphers used for secure Socket connections as an array of valid cipher names.$$ *($$String$$, default: `$$any$$`)* -$$keystore-type$$:: $$Identifies the type of Keystore used for SSL communications (e.g. JKS, PKCS11, etc.).$$ *($$String$$, default: `$$JKS$$`)* -$$keystore-uri$$:: $$Location of the pre-created Keystore URI to be used for connecting to the Geode cluster.$$ *($$Resource$$, default: `$$$$`)* -$$ssl-keystore-password$$:: $$Password for accessing the keys truststore.$$ *($$String$$, default: `$$$$`)* -$$ssl-truststore-password$$:: $$Password for accessing the trust store.$$ *($$String$$, default: `$$$$`)* -$$truststore-type$$:: $$Identifies the type of truststore used for SSL communications (e.g. JKS, PKCS11, etc.).$$ *($$String$$, default: `$$JKS$$`)* -$$truststore-uri$$:: $$Location of the pre-created truststore URI to be used for connecting to the Geode cluster.$$ *($$Resource$$, default: `$$$$`)* -$$user-home-directory$$:: $$Local directory to cache the truststore and keystore files downloaded form the truststoreUri and keystoreUri locations.$$ *($$String$$, default: `$$user.home$$`)* -//end::configuration-properties[] - -//end::ref-doc[] diff --git a/applications/sink/geode-sink/pom.xml b/applications/sink/geode-sink/pom.xml deleted file mode 100644 index 237e3257..00000000 --- a/applications/sink/geode-sink/pom.xml +++ /dev/null @@ -1,70 +0,0 @@ - - - 4.0.0 - geode-sink - geode-sink - Geode sink app - jar - - - org.springframework.cloud.stream.app - stream-applications-core - 4.0.0-SNAPSHOT - ../../stream-applications-core/pom.xml - - - - - org.springframework.cloud.fn - geode-consumer - - - org.projectlombok - lombok - test - - - org.springframework.geode - spring-geode-starter-logging - test - - - org.springframework.geode - spring-geode-starter-test - test - - - - - - - org.springframework.cloud - spring-cloud-dataflow-apps-docs-plugin - - - org.springframework.cloud - spring-cloud-dataflow-apps-generator-plugin - - - geode - sink - ${project.version} - org.springframework.cloud.fn.consumer.geode.GeodeConsumerConfiguration.class - geodeConsumer - - - - - org.springframework.cloud.fn - geode-consumer - - - - - - - - - - diff --git a/applications/sink/geode-sink/src/main/resources/META-INF/dataflow-configuration-metadata-whitelist.properties b/applications/sink/geode-sink/src/main/resources/META-INF/dataflow-configuration-metadata-whitelist.properties deleted file mode 100644 index cbd99548..00000000 --- a/applications/sink/geode-sink/src/main/resources/META-INF/dataflow-configuration-metadata-whitelist.properties +++ /dev/null @@ -1,5 +0,0 @@ -configuration-properties.classes=org.springframework.cloud.fn.consumer.geode.GeodeConsumerProperties,\ -org.springframework.cloud.fn.common.geode.GeodeRegionProperties,\ -org.springframework.cloud.fn.common.geode.GeodePoolProperties,\ -org.springframework.cloud.fn.common.geode.GeodeSecurityProperties,\ -org.springframework.cloud.fn.common.geode.GeodeSslProperties diff --git a/applications/sink/geode-sink/src/main/resources/META-INF/dataflow-configuration-metadata.properties b/applications/sink/geode-sink/src/main/resources/META-INF/dataflow-configuration-metadata.properties deleted file mode 100644 index cbd99548..00000000 --- a/applications/sink/geode-sink/src/main/resources/META-INF/dataflow-configuration-metadata.properties +++ /dev/null @@ -1,5 +0,0 @@ -configuration-properties.classes=org.springframework.cloud.fn.consumer.geode.GeodeConsumerProperties,\ -org.springframework.cloud.fn.common.geode.GeodeRegionProperties,\ -org.springframework.cloud.fn.common.geode.GeodePoolProperties,\ -org.springframework.cloud.fn.common.geode.GeodeSecurityProperties,\ -org.springframework.cloud.fn.common.geode.GeodeSslProperties diff --git a/applications/sink/geode-sink/src/test/java/org/springframework/cloud/stream/app/sink/geode/GeodeSinkTests.java b/applications/sink/geode-sink/src/test/java/org/springframework/cloud/stream/app/sink/geode/GeodeSinkTests.java deleted file mode 100644 index 7f5435ff..00000000 --- a/applications/sink/geode-sink/src/test/java/org/springframework/cloud/stream/app/sink/geode/GeodeSinkTests.java +++ /dev/null @@ -1,124 +0,0 @@ -/* - * Copyright 2020-2020 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.stream.app.sink.geode; - -import java.io.IOException; - -import com.fasterxml.jackson.databind.ObjectMapper; -import lombok.AllArgsConstructor; -import lombok.Data; -import lombok.NoArgsConstructor; -import org.apache.geode.cache.Region; -import org.apache.geode.pdx.PdxInstance; -import org.junit.jupiter.api.AfterAll; -import org.junit.jupiter.api.BeforeAll; -import org.junit.jupiter.api.Tag; -import org.junit.jupiter.api.Test; - -import org.springframework.boot.autoconfigure.SpringBootApplication; -import org.springframework.boot.test.context.runner.ApplicationContextRunner; -import org.springframework.cloud.fn.consumer.geode.GeodeConsumerConfiguration; -import org.springframework.cloud.stream.app.sink.geodeserver.GeodeServerTestConfiguration; -import org.springframework.cloud.stream.binder.test.InputDestination; -import org.springframework.cloud.stream.binder.test.TestChannelBinderConfiguration; -import org.springframework.context.annotation.Import; -import org.springframework.data.gemfire.tests.integration.ForkingClientServerIntegrationTestsSupport; -import org.springframework.messaging.support.GenericMessage; - -import static org.assertj.core.api.Assertions.assertThat; - -@Tag("integration") -public class GeodeSinkTests { - - private static ApplicationContextRunner applicationContextRunner; - - private ObjectMapper objectMapper = new ObjectMapper(); - - @BeforeAll - static void setup() throws IOException { - ForkingClientServerIntegrationTestsSupport.startGemFireServer( - GeodeServerTestConfiguration.class); - - applicationContextRunner = new ApplicationContextRunner() - .withUserConfiguration( - TestChannelBinderConfiguration.getCompleteConfiguration(GeodeSinkTestApplication.class)); - } - - @AfterAll - static void stopServer() { - ForkingClientServerIntegrationTestsSupport.stopGemFireServer(); - ForkingClientServerIntegrationTestsSupport.clearCacheServerPortAndPoolPortProperties(); - } - - @Test - void consumeWithJsonEnabled() { - applicationContextRunner - .withPropertyValues( - "spring.cloud.function.definition=geodeConsumer", - "geode.region.regionName=Stocks", - "geode.consumer.json=true", - "geode.consumer.key-expression=payload.getField('symbol')", - "geode.pool.connectType=server", - "geode.pool.hostAddresses=" + "localhost:" + System.getProperty("spring.data.gemfire.cache.server.port")) - .run(context -> { - InputDestination inputDestination = context.getBean(InputDestination.class); - - byte[] json = objectMapper.writeValueAsBytes(new Stock("XXX", 100.00)); - inputDestination.send(new GenericMessage<>(json)); - - Region region = context.getBean(Region.class); - PdxInstance instance = region.get("XXX"); - assertThat(instance.getField("price")).isEqualTo(100.00); - region.close(); - }); - } - - @Test - void consumeWithoutJsonEnabled() { - applicationContextRunner - .withPropertyValues( - "spring.cloud.function.definition=geodeConsumer", - "geode.region.regionName=Stocks", - "geode.consumer.key-expression='key'", - "geode.pool.connectType=server", - "geode.pool.hostAddresses=" + "localhost:" + System.getProperty("spring.data.gemfire.cache.server.port")) - .run(context -> { - InputDestination inputDestination = context.getBean(InputDestination.class); - inputDestination.send(new GenericMessage<>("value")); - - Region region = context.getBean(Region.class); - String value = region.get("key"); - assertThat(value).isEqualTo("value"); - region.close(); - }); - } - - @Data - @AllArgsConstructor - @NoArgsConstructor - static class Stock { - private String symbol; - - private double price; - } - - @SpringBootApplication - @Import(GeodeConsumerConfiguration.class) - static class GeodeSinkTestApplication { - - } -} diff --git a/applications/sink/geode-sink/src/test/java/org/springframework/cloud/stream/app/sink/geodeserver/GeodeServerTestConfiguration.java b/applications/sink/geode-sink/src/test/java/org/springframework/cloud/stream/app/sink/geodeserver/GeodeServerTestConfiguration.java deleted file mode 100644 index 82664ea9..00000000 --- a/applications/sink/geode-sink/src/test/java/org/springframework/cloud/stream/app/sink/geodeserver/GeodeServerTestConfiguration.java +++ /dev/null @@ -1,46 +0,0 @@ -/* - * Copyright 2020-2020 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.stream.app.sink.geodeserver; - -import org.apache.geode.cache.GemFireCache; - -import org.springframework.context.annotation.AnnotationConfigApplicationContext; -import org.springframework.context.annotation.Bean; -import org.springframework.data.gemfire.ReplicatedRegionFactoryBean; -import org.springframework.data.gemfire.config.annotation.CacheServerApplication; - -@CacheServerApplication -public class GeodeServerTestConfiguration { - - public static void main(String[] args) { - - AnnotationConfigApplicationContext applicationContext = - new AnnotationConfigApplicationContext(GeodeServerTestConfiguration.class); - - applicationContext.registerShutdownHook(); - } - - @Bean("Stocks") - public ReplicatedRegionFactoryBean stocksRegion(GemFireCache gemfireCache) { - - ReplicatedRegionFactoryBean regionFactoryBean = new ReplicatedRegionFactoryBean<>(); - - regionFactoryBean.setCache(gemfireCache); - - return regionFactoryBean; - } -} diff --git a/applications/sink/geode-sink/src/test/resources/logback-include.xml b/applications/sink/geode-sink/src/test/resources/logback-include.xml deleted file mode 100644 index ae330ab3..00000000 --- a/applications/sink/geode-sink/src/test/resources/logback-include.xml +++ /dev/null @@ -1,16 +0,0 @@ - - - - - - %d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n - - - - - - - - - - diff --git a/applications/sink/jdbc-sink/README.adoc b/applications/sink/jdbc-sink/README.adoc index 745ff19d..7e2e663f 100644 --- a/applications/sink/jdbc-sink/README.adoc +++ b/applications/sink/jdbc-sink/README.adoc @@ -46,11 +46,11 @@ Properties grouped by prefix: === jdbc.consumer -$$batch-size$$:: $$Threshold in number of messages when data will be flushed to database table.$$ *($$Integer$$, default: `$$1$$`)* -$$columns$$:: $$The comma separated colon-based pairs of column names and SpEL expressions for values to insert/update. Names are used at initialization time to issue the DDL.$$ *($$String$$, default: `$$payload:payload.toString()$$`)* -$$idle-timeout$$:: $$Idle timeout in milliseconds when data is automatically flushed to database table.$$ *($$Long$$, default: `$$-1$$`)* -$$initialize$$:: $$'true', 'false' or the location of a custom initialization script for the table.$$ *($$String$$, default: `$$false$$`)* -$$table-name$$:: $$The name of the table to write into.$$ *($$String$$, default: `$$messages$$`)* +$$batch-size$$:: $$Threshold in number of messages when data will be flushed to database table.$$ *($$Integer$$, default: `$$$$`)* +$$columns$$:: $$The comma separated colon-based pairs of column names and SpEL expressions for values to insert/update. Names are used at initialization time to issue the DDL.$$ *($$String$$, default: `$$$$`)* +$$idle-timeout$$:: $$Idle timeout in milliseconds when data is automatically flushed to database table.$$ *($$Long$$, default: `$$$$`)* +$$initialize$$:: $$'true', 'false' or the location of a custom initialization script for the table.$$ *($$String$$, default: `$$$$`)* +$$table-name$$:: $$The name of the table to write into.$$ *($$String$$, default: `$$$$`)* === spring.datasource diff --git a/applications/sink/log-sink/README.adoc b/applications/sink/log-sink/README.adoc index 44b7671e..d63e5ea0 100644 --- a/applications/sink/log-sink/README.adoc +++ b/applications/sink/log-sink/README.adoc @@ -13,7 +13,7 @@ The **$$log$$** $$sink$$ has the following options: //tag::configuration-properties[] -$$log.expression$$:: $$A SpEL expression (against the incoming message) to evaluate as the logged message.$$ *($$String$$, default: `$$payload$$`)* +$$log.expression$$:: $$A SpEL expression (against the incoming message) to evaluate as the logged message.$$ *($$String$$, default: `$$$$`)* $$log.level$$:: $$The level at which to log messages.$$ *($$Level$$, default: `$$$$`, possible values: `FATAL`,`ERROR`,`WARN`,`INFO`,`DEBUG`,`TRACE`)* $$log.name$$:: $$The name of the logger to use.$$ *($$String$$, default: `$$$$`)* //end::configuration-properties[] diff --git a/applications/sink/mqtt-sink/README.adoc b/applications/sink/mqtt-sink/README.adoc index 61ccba5b..a27dd110 100644 --- a/applications/sink/mqtt-sink/README.adoc +++ b/applications/sink/mqtt-sink/README.adoc @@ -18,24 +18,24 @@ Properties grouped by prefix: === mqtt -$$clean-session$$:: $$whether the client and server should remember state across restarts and reconnects.$$ *($$Boolean$$, default: `$$true$$`)* -$$connection-timeout$$:: $$the connection timeout in seconds.$$ *($$Integer$$, default: `$$30$$`)* -$$keep-alive-interval$$:: $$the ping interval in seconds.$$ *($$Integer$$, default: `$$60$$`)* -$$password$$:: $$the password to use when connecting to the broker.$$ *($$String$$, default: `$$guest$$`)* -$$persistence$$:: $$'memory' or 'file'.$$ *($$String$$, default: `$$memory$$`)* -$$persistence-directory$$:: $$Persistence directory.$$ *($$String$$, default: `$$/tmp/paho$$`)* +$$clean-session$$:: $$whether the client and server should remember state across restarts and reconnects.$$ *($$Boolean$$, default: `$$$$`)* +$$connection-timeout$$:: $$the connection timeout in seconds.$$ *($$Integer$$, default: `$$$$`)* +$$keep-alive-interval$$:: $$the ping interval in seconds.$$ *($$Integer$$, default: `$$$$`)* +$$password$$:: $$the password to use when connecting to the broker.$$ *($$String$$, default: `$$$$`)* +$$persistence$$:: $$'memory' or 'file'.$$ *($$String$$, default: `$$$$`)* +$$persistence-directory$$:: $$Persistence directory.$$ *($$String$$, default: `$$$$`)* $$ssl-properties$$:: $$MQTT Client SSL properties.$$ *($$Map$$, default: `$$$$`)* -$$url$$:: $$location of the mqtt broker(s) (comma-delimited list).$$ *($$String[]$$, default: `$$[tcp://localhost:1883]$$`)* -$$username$$:: $$the username to use when connecting to the broker.$$ *($$String$$, default: `$$guest$$`)* +$$url$$:: $$location of the mqtt broker(s) (comma-delimited list).$$ *($$String[]$$, default: `$$$$`)* +$$username$$:: $$the username to use when connecting to the broker.$$ *($$String$$, default: `$$$$`)* === mqtt.consumer -$$async$$:: $$whether or not to use async sends.$$ *($$Boolean$$, default: `$$false$$`)* -$$charset$$:: $$the charset used to convert a String payload to byte[].$$ *($$String$$, default: `$$UTF-8$$`)* -$$client-id$$:: $$identifies the client.$$ *($$String$$, default: `$$stream.client.id.sink$$`)* -$$qos$$:: $$the quality of service to use.$$ *($$Integer$$, default: `$$1$$`)* -$$retained$$:: $$whether to set the 'retained' flag.$$ *($$Boolean$$, default: `$$false$$`)* -$$topic$$:: $$the topic to which the sink will publish.$$ *($$String$$, default: `$$stream.mqtt$$`)* +$$async$$:: $$whether or not to use async sends.$$ *($$Boolean$$, default: `$$$$`)* +$$charset$$:: $$the charset used to convert a String payload to byte[].$$ *($$String$$, default: `$$$$`)* +$$client-id$$:: $$identifies the client.$$ *($$String$$, default: `$$$$`)* +$$qos$$:: $$the quality of service to use.$$ *($$Integer$$, default: `$$$$`)* +$$retained$$:: $$whether to set the 'retained' flag.$$ *($$Boolean$$, default: `$$$$`)* +$$topic$$:: $$the topic to which the sink will publish.$$ *($$String$$, default: `$$$$`)* //end::configuration-properties[] //end::ref-doc[] diff --git a/applications/sink/pom.xml b/applications/sink/pom.xml index 1c702839..c4f162a8 100644 --- a/applications/sink/pom.xml +++ b/applications/sink/pom.xml @@ -14,7 +14,6 @@ cassandra-sink file-sink ftp-sink - geode-sink log-sink mongodb-sink mqtt-sink diff --git a/applications/sink/rabbit-sink/README.adoc b/applications/sink/rabbit-sink/README.adoc index 6aba9f75..2716cc70 100644 --- a/applications/sink/rabbit-sink/README.adoc +++ b/applications/sink/rabbit-sink/README.adoc @@ -16,12 +16,12 @@ Properties grouped by prefix: === rabbit $$converter-bean-name$$:: $$The bean name for a custom message converter; if omitted, a SimpleMessageConverter is used. If 'jsonConverter', a Jackson2JsonMessageConverter bean will be created for you.$$ *($$String$$, default: `$$$$`)* -$$exchange$$:: $$Exchange name - overridden by exchangeNameExpression, if supplied.$$ *($$String$$, default: `$$$$`)* +$$exchange$$:: $$Exchange name - overridden by exchangeNameExpression, if supplied.$$ *($$String$$, default: `$$$$`)* $$exchange-expression$$:: $$A SpEL expression that evaluates to an exchange name.$$ *($$Expression$$, default: `$$$$`)* -$$headers-mapped-last$$:: $$When mapping headers for the outbound message, determine whether the headers are mapped before the message is converted, or afterwards.$$ *($$Boolean$$, default: `$$true$$`)* -$$mapped-request-headers$$:: $$Headers that will be mapped.$$ *($$String[]$$, default: `$$[*]$$`)* -$$own-connection$$:: $$When true, use a separate connection based on the boot properties.$$ *($$Boolean$$, default: `$$false$$`)* -$$persistent-delivery-mode$$:: $$Default delivery mode when 'amqp_deliveryMode' header is not present, true for PERSISTENT.$$ *($$Boolean$$, default: `$$false$$`)* +$$headers-mapped-last$$:: $$When mapping headers for the outbound message, determine whether the headers are mapped before the message is converted, or afterwards.$$ *($$Boolean$$, default: `$$$$`)* +$$mapped-request-headers$$:: $$Headers that will be mapped.$$ *($$String[]$$, default: `$$$$`)* +$$own-connection$$:: $$When true, use a separate connection based on the boot properties.$$ *($$Boolean$$, default: `$$$$`)* +$$persistent-delivery-mode$$:: $$Default delivery mode when 'amqp_deliveryMode' header is not present, true for PERSISTENT.$$ *($$Boolean$$, default: `$$$$`)* $$routing-key$$:: $$Routing key - overridden by routingKeyExpression, if supplied.$$ *($$String$$, default: `$$$$`)* $$routing-key-expression$$:: $$A SpEL expression that evaluates to a routing key.$$ *($$Expression$$, default: `$$$$`)* diff --git a/applications/sink/router-sink/README.adoc b/applications/sink/router-sink/README.adoc index 4b8b3853..4a5dfc67 100644 --- a/applications/sink/router-sink/README.adoc +++ b/applications/sink/router-sink/README.adoc @@ -8,11 +8,11 @@ This application routes messages to named channels. The **$$router$$** $$sink$$ has the following options: //tag::configuration-properties[] -$$router.default-output-channel$$:: $$Where to send un-routable messages.$$ *($$String$$, default: `$$nullChannel$$`)* +$$router.default-output-channel$$:: $$Where to send un-routable messages.$$ *($$String$$, default: `$$$$`)* $$router.destination-mappings$$:: $$Destination mappings as a new line delimited string of name-value pairs, e.g. 'foo=bar\n baz=car'.$$ *($$Properties$$, default: `$$$$`)* $$router.expression$$:: $$The expression to be applied to the message to determine the channel(s) to route to. Note that the payload wire format for content types such as text, json or xml is byte[] not String!. Consult the documentation for how to handle byte array payload content.$$ *($$Expression$$, default: `$$$$`)* -$$router.refresh-delay$$:: $$How often to check for script changes in ms (if present); < 0 means don't refresh.$$ *($$Integer$$, default: `$$60000$$`)* -$$router.resolution-required$$:: $$Whether or not channel resolution is required.$$ *($$Boolean$$, default: `$$false$$`)* +$$router.refresh-delay$$:: $$How often to check for script changes in ms (if present); < 0 means don't refresh.$$ *($$Integer$$, default: `$$$$`)* +$$router.resolution-required$$:: $$Whether or not channel resolution is required.$$ *($$Boolean$$, default: `$$$$`)* $$router.script$$:: $$The location of a groovy script that returns channels or channel mapping resolution keys.$$ *($$Resource$$, default: `$$$$`)* $$router.variables$$:: $$Variable bindings as a new line delimited string of name-value pairs, e.g. 'foo=bar\n baz=car'.$$ *($$Properties$$, default: `$$$$`)* $$router.variables-location$$:: $$The location of a properties file containing custom script variable bindings.$$ *($$Resource$$, default: `$$$$`)* diff --git a/applications/sink/rsocket-sink/README.adoc b/applications/sink/rsocket-sink/README.adoc index fe5359b9..73c00a15 100644 --- a/applications/sink/rsocket-sink/README.adoc +++ b/applications/sink/rsocket-sink/README.adoc @@ -8,8 +8,8 @@ RSocket sink to send data using RSocket protocols' fire and forget strategy. The **$$rsocket$$** $$sink$$ has the following options: //tag::configuration-properties[] -$$rsocket.consumer.host$$:: $$RSocket host.$$ *($$String$$, default: `$$localhost$$`)* -$$rsocket.consumer.port$$:: $$RSocket port.$$ *($$Integer$$, default: `$$7000$$`)* +$$rsocket.consumer.host$$:: $$RSocket host.$$ *($$String$$, default: `$$$$`)* +$$rsocket.consumer.port$$:: $$RSocket port.$$ *($$Integer$$, default: `$$$$`)* $$rsocket.consumer.route$$:: $$Route used for RSocket.$$ *($$String$$, default: `$$$$`)* $$rsocket.consumer.uri$$:: $$URI that can be used for websocket based transport.$$ *($$URI$$, default: `$$$$`)* //end::configuration-properties[] diff --git a/applications/sink/s3-sink/README.adoc b/applications/sink/s3-sink/README.adoc index be85aaec..0469c487 100644 --- a/applications/sink/s3-sink/README.adoc +++ b/applications/sink/s3-sink/README.adoc @@ -21,7 +21,7 @@ Properties grouped by prefix: === s3.common $$endpoint-url$$:: $$Optional endpoint url to connect to s3 compatible storage.$$ *($$String$$, default: `$$$$`)* -$$path-style-access$$:: $$Use path style access.$$ *($$Boolean$$, default: `$$false$$`)* +$$path-style-access$$:: $$Use path style access.$$ *($$Boolean$$, default: `$$$$`)* === s3.consumer diff --git a/applications/sink/sftp-sink/README.adoc b/applications/sink/sftp-sink/README.adoc index 8555e786..7d90f1cd 100644 --- a/applications/sink/sftp-sink/README.adoc +++ b/applications/sink/sftp-sink/README.adoc @@ -41,14 +41,14 @@ Properties grouped by prefix: === sftp.consumer -$$auto-create-dir$$:: $$Whether or not to create the remote directory.$$ *($$Boolean$$, default: `$$true$$`)* +$$auto-create-dir$$:: $$Whether to create the remote directory.$$ *($$Boolean$$, default: `$$true$$`)* $$filename-expression$$:: $$A SpEL expression to generate the remote file name.$$ *($$String$$, default: `$$$$`)* $$mode$$:: $$Action to take if the remote file already exists.$$ *($$FileExistsMode$$, default: `$$$$`, possible values: `APPEND`,`APPEND_NO_FLUSH`,`FAIL`,`IGNORE`,`REPLACE`,`REPLACE_IF_MODIFIED`)* $$remote-dir$$:: $$The remote FTP directory.$$ *($$String$$, default: `$$/$$`)* $$remote-file-separator$$:: $$The remote file separator.$$ *($$String$$, default: `$$/$$`)* $$temporary-remote-dir$$:: $$A temporary directory where the file will be written if 'isUseTemporaryFilename()' is true.$$ *($$String$$, default: `$$/$$`)* $$tmp-file-suffix$$:: $$The suffix to use while the transfer is in progress.$$ *($$String$$, default: `$$.tmp$$`)* -$$use-temporary-filename$$:: $$Whether or not to write to a temporary file and rename.$$ *($$Boolean$$, default: `$$true$$`)* +$$use-temporary-filename$$:: $$Whether to write to a temporary file and rename.$$ *($$Boolean$$, default: `$$true$$`)* === sftp.consumer.factory diff --git a/applications/sink/tcp-sink/README.adoc b/applications/sink/tcp-sink/README.adoc index 5f940b24..d30b4d92 100644 --- a/applications/sink/tcp-sink/README.adoc +++ b/applications/sink/tcp-sink/README.adoc @@ -16,18 +16,18 @@ Properties grouped by prefix: === tcp.consumer -$$charset$$:: $$The charset used when converting from bytes to String.$$ *($$String$$, default: `$$UTF-8$$`)* -$$close$$:: $$Whether to close the socket after each message.$$ *($$Boolean$$, default: `$$false$$`)* +$$charset$$:: $$The charset used when converting from bytes to String.$$ *($$String$$, default: `$$$$`)* +$$close$$:: $$Whether to close the socket after each message.$$ *($$Boolean$$, default: `$$$$`)* $$encoder$$:: $$The encoder to use when sending messages.$$ *($$Encoding$$, default: `$$$$`, possible values: `CRLF`,`LF`,`NULL`,`STXETX`,`RAW`,`L1`,`L2`,`L4`)* $$host$$:: $$The host to which this sink will connect.$$ *($$String$$, default: `$$$$`)* === tcp -$$nio$$:: $$Whether or not to use NIO.$$ *($$Boolean$$, default: `$$false$$`)* -$$port$$:: $$The port on which to listen; 0 for the OS to choose a port.$$ *($$Integer$$, default: `$$1234$$`)* -$$reverse-lookup$$:: $$Perform a reverse DNS lookup on the remote IP Address; if false, just the IP address is included in the message headers.$$ *($$Boolean$$, default: `$$false$$`)* -$$socket-timeout$$:: $$The timeout (ms) before closing the socket when no data is received.$$ *($$Integer$$, default: `$$120000$$`)* -$$use-direct-buffers$$:: $$Whether or not to use direct buffers.$$ *($$Boolean$$, default: `$$false$$`)* +$$nio$$:: $$Whether or not to use NIO.$$ *($$Boolean$$, default: `$$$$`)* +$$port$$:: $$The port on which to listen; 0 for the OS to choose a port.$$ *($$Integer$$, default: `$$$$`)* +$$reverse-lookup$$:: $$Perform a reverse DNS lookup on the remote IP Address; if false, just the IP address is included in the message headers.$$ *($$Boolean$$, default: `$$$$`)* +$$socket-timeout$$:: $$The timeout (ms) before closing the socket when no data is received.$$ *($$Integer$$, default: `$$$$`)* +$$use-direct-buffers$$:: $$Whether or not to use direct buffers.$$ *($$Boolean$$, default: `$$$$`)* //end::configuration-properties[] == Available Encoders diff --git a/applications/sink/throughput-sink/README.adoc b/applications/sink/throughput-sink/README.adoc index 1a077a49..b7589fa8 100644 --- a/applications/sink/throughput-sink/README.adoc +++ b/applications/sink/throughput-sink/README.adoc @@ -8,7 +8,7 @@ Sink that will count messages and log the observed throughput at a selected inte The **$$throughput$$** $$sink$$ has the following options: //tag::configuration-properties[] -$$throughput.report-every-ms$$:: $$how often to report.$$ *($$Integer$$, default: `$$1000$$`)* +$$throughput.report-every-ms$$:: $$how often to report.$$ *($$Integer$$, default: `$$$$`)* //end::configuration-properties[] //end::ref-doc[] diff --git a/applications/sink/twitter-message-sink/README.adoc b/applications/sink/twitter-message-sink/README.adoc index db22224a..10c7599a 100644 --- a/applications/sink/twitter-message-sink/README.adoc +++ b/applications/sink/twitter-message-sink/README.adoc @@ -19,7 +19,7 @@ For fixed target userId use `userId='666'`. //tag::configuration-properties[] $$twitter.message.update.media-id$$:: $$A media id to associate with the message. A Direct Message may only reference a single media id.$$ *($$Expression$$, default: `$$$$`)* $$twitter.message.update.screen-name$$:: $$The screen name of the user to whom send the direct message.$$ *($$Expression$$, default: `$$$$`)* -$$twitter.message.update.text$$:: $$The direct message text. URL encode as necessary. Max length of 10,000 characters.$$ *($$Expression$$, default: `$$payload$$`)* +$$twitter.message.update.text$$:: $$The direct message text. URL encode as necessary. Max length of 10,000 characters.$$ *($$Expression$$, default: `$$$$`)* $$twitter.message.update.user-id$$:: $$The user id of the user to whom send the direct message.$$ *($$Expression$$, default: `$$$$`)* //end::configuration-properties[] diff --git a/applications/sink/twitter-update-sink/README.adoc b/applications/sink/twitter-update-sink/README.adoc index 076390d2..b8c82580 100644 --- a/applications/sink/twitter-update-sink/README.adoc +++ b/applications/sink/twitter-update-sink/README.adoc @@ -26,7 +26,7 @@ $$display-coordinates$$:: $$(SpEL expression) Whether or not to put a pin on the $$in-reply-to-status-id$$:: $$(SpEL expression) The ID of an existing text that the update is in reply to. Note: This parameter will be ignored unless the author of the Tweet this parameter references is mentioned within the text text. Therefore, you must include @username, where username is the author of the referenced Tweet, within the update. When inReplyToStatusId is set the auto_populate_reply_metadata is automatically set as well. Later ensures that leading @mentions will be looked up from the original Tweet, and added to the new Tweet from there. This wil append @mentions into the metadata of an extended Tweet as a reply chain grows, until the limit on @mentions is reached. In cases where the original Tweet has been deleted, the reply will fail.$$ *($$Expression$$, default: `$$$$`)* $$media-ids$$:: $$(SpEL expression) A comma-delimited list of media_ids to associate with the Tweet. You may include up to 4 photos or 1 animated GIF or 1 video in a Tweet. See Uploading Media for further details on uploading media.$$ *($$Expression$$, default: `$$$$`)* $$place-id$$:: $$(SpEL expression) A place in the world.$$ *($$Expression$$, default: `$$$$`)* -$$text$$:: $$(SpEL expression) The text of the text update. URL encode as necessary. t.co link wrapping will affect character counts. Defaults to message's payload$$ *($$Expression$$, default: `$$payload$$`)* +$$text$$:: $$(SpEL expression) The text of the text update. URL encode as necessary. t.co link wrapping will affect character counts. Defaults to message's payload$$ *($$Expression$$, default: `$$$$`)* === twitter.update.location diff --git a/applications/sink/websocket-sink/README.adoc b/applications/sink/websocket-sink/README.adoc index 9a99b02e..89bd3f77 100644 --- a/applications/sink/websocket-sink/README.adoc +++ b/applications/sink/websocket-sink/README.adoc @@ -8,10 +8,10 @@ The following options are supported: //tag::configuration-properties[] $$websocket.consumer.log-level$$:: $$the logLevel for netty channels. Default is WARN$$ *($$String$$, default: `$$$$`)* -$$websocket.consumer.path$$:: $$the path on which a WebsocketSink consumer needs to connect. Default is /websocket$$ *($$String$$, default: `$$/websocket$$`)* -$$websocket.consumer.port$$:: $$the port on which the Netty server listens. Default is 9292$$ *($$Integer$$, default: `$$9292$$`)* -$$websocket.consumer.ssl$$:: $$whether or not to create a {@link io.netty.handler.ssl.SslContext}.$$ *($$Boolean$$, default: `$$false$$`)* -$$websocket.consumer.threads$$:: $$the number of threads for the Netty {@link io.netty.channel.EventLoopGroup}. Default is 1$$ *($$Integer$$, default: `$$1$$`)* +$$websocket.consumer.path$$:: $$the path on which a WebsocketSink consumer needs to connect. Default is /websocket$$ *($$String$$, default: `$$$$`)* +$$websocket.consumer.port$$:: $$the port on which the Netty server listens. Default is 9292$$ *($$Integer$$, default: `$$$$`)* +$$websocket.consumer.ssl$$:: $$whether or not to create a {@link io.netty.handler.ssl.SslContext}.$$ *($$Boolean$$, default: `$$$$`)* +$$websocket.consumer.threads$$:: $$the number of threads for the Netty {@link io.netty.channel.EventLoopGroup}. Default is 1$$ *($$Integer$$, default: `$$$$`)* //end::configuration-properties[] == Examples diff --git a/applications/source/cdc-debezium-source/README.adoc b/applications/source/cdc-debezium-source/README.adoc index d635293a..2f9fa715 100644 --- a/applications/source/cdc-debezium-source/README.adoc +++ b/applications/source/cdc-debezium-source/README.adoc @@ -25,49 +25,45 @@ Properties grouped by prefix: $$config$$:: $$Spring pass-trough wrapper for debezium configuration properties. All properties with a 'cdc.config.' prefix are native Debezium properties. The prefix is removed, converting them into Debezium io.debezium.config.Configuration.$$ *($$Map$$, default: `$$$$`)* $$connector$$:: $$Shortcut for the cdc.config.connector.class property. Either of those can be used as long as they do not contradict with each other.$$ *($$ConnectorType$$, default: `$$$$`, possible values: `mysql`,`postgres`,`mongodb`,`oracle`,`sqlserver`)* $$name$$:: $$Unique name for this sourceConnector instance.$$ *($$String$$, default: `$$$$`)* -$$schema$$:: $$Include the schema's as part of the outbound message.$$ *($$Boolean$$, default: `$$false$$`)* +$$schema$$:: $$Include the schema's as part of the outbound message.$$ *($$Boolean$$, default: `$$$$`)* === cdc.flattening $$add-fields$$:: $$Comma separated list of metadata fields to add to the flattened message. The fields will be prefixed with "__" or "__[<]struct]__", depending on the specification of the struct.$$ *($$String$$, default: `$$$$`)* $$add-headers$$:: $$Comma separated list specify a list of metadata fields to add to the header of the flattened message. The fields will be prefixed with "__" or "__[struct]__".$$ *($$String$$, default: `$$$$`)* $$delete-handling-mode$$:: $$Options for handling deleted records: (1) none - pass the records through, (2) drop - remove the records and (3) rewrite - add a '__deleted' field to the records.$$ *($$DeleteHandlingMode$$, default: `$$$$`, possible values: `drop`,`rewrite`,`none`)* -$$drop-tombstones$$:: $$By default Debezium generates tombstone records to enable Kafka compaction on deleted records. The dropTombstones can suppress the tombstone records.$$ *($$Boolean$$, default: `$$true$$`)* -$$enabled$$:: $$Enable flattening the source record events (https://debezium.io/docs/configuration/event-flattening).$$ *($$Boolean$$, default: `$$true$$`)* +$$drop-tombstones$$:: $$By default Debezium generates tombstone records to enable Kafka compaction on deleted records. The dropTombstones can suppress the tombstone records.$$ *($$Boolean$$, default: `$$$$`)* +$$enabled$$:: $$Enable flattening the source record events (https://debezium.io/docs/configuration/event-flattening).$$ *($$Boolean$$, default: `$$$$`)* === cdc.offset -$$commit-timeout$$:: $$Maximum number of milliseconds to wait for records to flush and partition offset data to be committed to offset storage before cancelling the process and restoring the offset data to be committed in a future attempt.$$ *($$Duration$$, default: `$$5000ms$$`)* -$$flush-interval$$:: $$Interval at which to try committing offsets. The default is 1 minute.$$ *($$Duration$$, default: `$$60000ms$$`)* +$$commit-timeout$$:: $$Maximum number of milliseconds to wait for records to flush and partition offset data to be committed to offset storage before cancelling the process and restoring the offset data to be committed in a future attempt.$$ *($$Duration$$, default: `$$$$`)* +$$flush-interval$$:: $$Interval at which to try committing offsets. The default is 1 minute.$$ *($$Duration$$, default: `$$$$`)* $$policy$$:: $$Offset storage commit policy.$$ *($$OffsetPolicy$$, default: `$$$$`)* $$storage$$:: $$Kafka connector tracks the number processed records and regularly stores the count (as "offsets") in a preconfigured metadata storage. On restart the connector resumes the reading from the last recorded source offset.$$ *($$OffsetStorageType$$, default: `$$$$`, possible values: `memory`,`file`,`kafka`,`metadata`)* === cdc.stream.header -$$convert-connect-headers$$:: $$When true the {@link org.apache.kafka.connect.header.Header} are converted into message headers with the {@link org.apache.kafka.connect.header.Header#key()} as name and {@link org.apache.kafka.connect.header.Header#value()}.$$ *($$Boolean$$, default: `$$true$$`)* -$$offset$$:: $$Serializes the source record's offset metadata into the outbound message header under cdc.offset.$$ *($$Boolean$$, default: `$$false$$`)* +$$convert-connect-headers$$:: $$When true the {@link org.apache.kafka.connect.header.Header} are converted into message headers with the {@link org.apache.kafka.connect.header.Header#key()} as name and {@link org.apache.kafka.connect.header.Header#value()}.$$ *($$Boolean$$, default: `$$$$`)* +$$offset$$:: $$Serializes the source record's offset metadata into the outbound message header under cdc.offset.$$ *($$Boolean$$, default: `$$$$`)* === metadata.store.dynamo-db -$$create-delay$$:: $$Delay between create table retries.$$ *($$Integer$$, default: `$$1$$`)* -$$create-retries$$:: $$Retry number for create table request.$$ *($$Integer$$, default: `$$25$$`)* -$$read-capacity$$:: $$Read capacity on the table.$$ *($$Long$$, default: `$$1$$`)* +$$create-delay$$:: $$Delay between create table retries.$$ *($$Integer$$, default: `$$$$`)* +$$create-retries$$:: $$Retry number for create table request.$$ *($$Integer$$, default: `$$$$`)* +$$read-capacity$$:: $$Read capacity on the table.$$ *($$Long$$, default: `$$$$`)* $$table$$:: $$Table name for metadata.$$ *($$String$$, default: `$$$$`)* $$time-to-live$$:: $$TTL for table entries.$$ *($$Integer$$, default: `$$$$`)* -$$write-capacity$$:: $$Write capacity on the table.$$ *($$Long$$, default: `$$1$$`)* - -=== metadata.store.gemfire - -$$region$$:: $$Gemfire region name for metadata.$$ *($$String$$, default: `$$$$`)* +$$write-capacity$$:: $$Write capacity on the table.$$ *($$Long$$, default: `$$$$`)* === metadata.store.jdbc -$$region$$:: $$Unique grouping identifier for messages persisted with this store.$$ *($$String$$, default: `$$DEFAULT$$`)* +$$region$$:: $$Unique grouping identifier for messages persisted with this store.$$ *($$String$$, default: `$$$$`)* $$table-prefix$$:: $$Prefix for the custom table name.$$ *($$String$$, default: `$$$$`)* === metadata.store.mongo-db -$$collection$$:: $$MongoDB collection name for metadata.$$ *($$String$$, default: `$$metadataStore$$`)* +$$collection$$:: $$MongoDB collection name for metadata.$$ *($$String$$, default: `$$$$`)* === metadata.store.redis @@ -75,14 +71,14 @@ $$key$$:: $$Redis key for metadata.$$ *($$String$$, default: `$$$$`)* === metadata.store -$$type$$:: $$Indicates the type of metadata store to configure (default is 'memory'). You must include the corresponding Spring Integration dependency to use a persistent store.$$ *($$StoreType$$, default: `$$$$`, possible values: `mongodb`,`gemfire`,`redis`,`dynamodb`,`jdbc`,`zookeeper`,`hazelcast`,`memory`)* +$$type$$:: $$Indicates the type of metadata store to configure (default is 'memory'). You must include the corresponding Spring Integration dependency to use a persistent store.$$ *($$StoreType$$, default: `$$$$`, possible values: `mongodb`,`redis`,`dynamodb`,`jdbc`,`zookeeper`,`hazelcast`,`memory`)* === metadata.store.zookeeper -$$connect-string$$:: $$Zookeeper connect string in form HOST:PORT.$$ *($$String$$, default: `$$127.0.0.1:2181$$`)* -$$encoding$$:: $$Encoding to use when storing data in Zookeeper.$$ *($$Charset$$, default: `$$UTF-8$$`)* -$$retry-interval$$:: $$Retry interval for Zookeeper operations in milliseconds.$$ *($$Integer$$, default: `$$1000$$`)* -$$root$$:: $$Root node - store entries are children of this node.$$ *($$String$$, default: `$$/SpringIntegration-MetadataStore$$`)* +$$connect-string$$:: $$Zookeeper connect string in form HOST:PORT.$$ *($$String$$, default: `$$$$`)* +$$encoding$$:: $$Encoding to use when storing data in Zookeeper.$$ *($$Charset$$, default: `$$$$`)* +$$retry-interval$$:: $$Retry interval for Zookeeper operations in milliseconds.$$ *($$Integer$$, default: `$$$$`)* +$$root$$:: $$Root node - store entries are children of this node.$$ *($$String$$, default: `$$$$`)* //end::configuration-properties[] ==== Debezium property Shortcut mapping diff --git a/applications/source/file-source/README.adoc b/applications/source/file-source/README.adoc index c624d1d5..2a7d196b 100644 --- a/applications/source/file-source/README.adoc +++ b/applications/source/file-source/README.adoc @@ -25,39 +25,35 @@ Properties grouped by prefix: === file.consumer -$$markers-json$$:: $$When 'fileMarkers == true', specify if they should be produced as FileSplitter.FileMarker objects or JSON.$$ *($$Boolean$$, default: `$$true$$`)* +$$markers-json$$:: $$When 'fileMarkers == true', specify if they should be produced as FileSplitter.FileMarker objects or JSON.$$ *($$Boolean$$, default: `$$$$`)* $$mode$$:: $$The FileReadingMode to use for file reading sources. Values are 'ref' - The File object, 'lines' - a message per line, or 'contents' - the contents as bytes.$$ *($$FileReadingMode$$, default: `$$$$`, possible values: `ref`,`lines`,`contents`)* $$with-markers$$:: $$Set to true to emit start of file/end of file marker messages before/after the data. Only valid with FileReadingMode 'lines'.$$ *($$Boolean$$, default: `$$$$`)* === file.supplier -$$delay-when-empty$$:: $$Duration of delay when no new files are detected.$$ *($$Duration$$, default: `$$1s$$`)* +$$delay-when-empty$$:: $$Duration of delay when no new files are detected.$$ *($$Duration$$, default: `$$$$`)* $$directory$$:: $$The directory to poll for new files.$$ *($$File$$, default: `$$$$`)* $$filename-pattern$$:: $$A simple ant pattern to match files.$$ *($$String$$, default: `$$$$`)* $$filename-regex$$:: $$A regex pattern to match files.$$ *($$Pattern$$, default: `$$$$`)* -$$prevent-duplicates$$:: $$Set to true to include an AcceptOnceFileListFilter which prevents duplicates.$$ *($$Boolean$$, default: `$$true$$`)* +$$prevent-duplicates$$:: $$Set to true to include an AcceptOnceFileListFilter which prevents duplicates.$$ *($$Boolean$$, default: `$$$$`)* === metadata.store.dynamo-db -$$create-delay$$:: $$Delay between create table retries.$$ *($$Integer$$, default: `$$1$$`)* -$$create-retries$$:: $$Retry number for create table request.$$ *($$Integer$$, default: `$$25$$`)* -$$read-capacity$$:: $$Read capacity on the table.$$ *($$Long$$, default: `$$1$$`)* +$$create-delay$$:: $$Delay between create table retries.$$ *($$Integer$$, default: `$$$$`)* +$$create-retries$$:: $$Retry number for create table request.$$ *($$Integer$$, default: `$$$$`)* +$$read-capacity$$:: $$Read capacity on the table.$$ *($$Long$$, default: `$$$$`)* $$table$$:: $$Table name for metadata.$$ *($$String$$, default: `$$$$`)* $$time-to-live$$:: $$TTL for table entries.$$ *($$Integer$$, default: `$$$$`)* -$$write-capacity$$:: $$Write capacity on the table.$$ *($$Long$$, default: `$$1$$`)* - -=== metadata.store.gemfire - -$$region$$:: $$Gemfire region name for metadata.$$ *($$String$$, default: `$$$$`)* +$$write-capacity$$:: $$Write capacity on the table.$$ *($$Long$$, default: `$$$$`)* === metadata.store.jdbc -$$region$$:: $$Unique grouping identifier for messages persisted with this store.$$ *($$String$$, default: `$$DEFAULT$$`)* +$$region$$:: $$Unique grouping identifier for messages persisted with this store.$$ *($$String$$, default: `$$$$`)* $$table-prefix$$:: $$Prefix for the custom table name.$$ *($$String$$, default: `$$$$`)* === metadata.store.mongo-db -$$collection$$:: $$MongoDB collection name for metadata.$$ *($$String$$, default: `$$metadataStore$$`)* +$$collection$$:: $$MongoDB collection name for metadata.$$ *($$String$$, default: `$$$$`)* === metadata.store.redis @@ -65,14 +61,14 @@ $$key$$:: $$Redis key for metadata.$$ *($$String$$, default: `$$$$`)* === metadata.store -$$type$$:: $$Indicates the type of metadata store to configure (default is 'memory'). You must include the corresponding Spring Integration dependency to use a persistent store.$$ *($$StoreType$$, default: `$$$$`, possible values: `mongodb`,`gemfire`,`redis`,`dynamodb`,`jdbc`,`zookeeper`,`hazelcast`,`memory`)* +$$type$$:: $$Indicates the type of metadata store to configure (default is 'memory'). You must include the corresponding Spring Integration dependency to use a persistent store.$$ *($$StoreType$$, default: `$$$$`, possible values: `mongodb`,`redis`,`dynamodb`,`jdbc`,`zookeeper`,`hazelcast`,`memory`)* === metadata.store.zookeeper -$$connect-string$$:: $$Zookeeper connect string in form HOST:PORT.$$ *($$String$$, default: `$$127.0.0.1:2181$$`)* -$$encoding$$:: $$Encoding to use when storing data in Zookeeper.$$ *($$Charset$$, default: `$$UTF-8$$`)* -$$retry-interval$$:: $$Retry interval for Zookeeper operations in milliseconds.$$ *($$Integer$$, default: `$$1000$$`)* -$$root$$:: $$Root node - store entries are children of this node.$$ *($$String$$, default: `$$/SpringIntegration-MetadataStore$$`)* +$$connect-string$$:: $$Zookeeper connect string in form HOST:PORT.$$ *($$String$$, default: `$$$$`)* +$$encoding$$:: $$Encoding to use when storing data in Zookeeper.$$ *($$Charset$$, default: `$$$$`)* +$$retry-interval$$:: $$Retry interval for Zookeeper operations in milliseconds.$$ *($$Integer$$, default: `$$$$`)* +$$root$$:: $$Root node - store entries are children of this node.$$ *($$String$$, default: `$$$$`)* //end::configuration-properties[] //end::ref-doc[] diff --git a/applications/source/ftp-source/README.adoc b/applications/source/ftp-source/README.adoc index 93b5f496..305d16fb 100644 --- a/applications/source/ftp-source/README.adoc +++ b/applications/source/ftp-source/README.adoc @@ -73,7 +73,7 @@ Properties grouped by prefix: === file.consumer -$$markers-json$$:: $$When 'fileMarkers == true', specify if they should be produced as FileSplitter.FileMarker objects or JSON.$$ *($$Boolean$$, default: `$$true$$`)* +$$markers-json$$:: $$When 'fileMarkers == true', specify if they should be produced as FileSplitter.FileMarker objects or JSON.$$ *($$Boolean$$, default: `$$$$`)* $$mode$$:: $$The FileReadingMode to use for file reading sources. Values are 'ref' - The File object, 'lines' - a message per line, or 'contents' - the contents as bytes.$$ *($$FileReadingMode$$, default: `$$$$`, possible values: `ref`,`lines`,`contents`)* $$with-markers$$:: $$Set to true to emit start of file/end of file marker messages before/after the data. Only valid with FileReadingMode 'lines'.$$ *($$Boolean$$, default: `$$$$`)* @@ -81,45 +81,41 @@ $$with-markers$$:: $$Set to true to emit start of file/end of file marker messag $$cache-sessions$$:: $$Cache sessions.$$ *($$Boolean$$, default: `$$$$`)* $$client-mode$$:: $$The client mode to use for the FTP session.$$ *($$ClientMode$$, default: `$$$$`, possible values: `ACTIVE`,`PASSIVE`)* -$$host$$:: $$The host name of the server.$$ *($$String$$, default: `$$localhost$$`)* +$$host$$:: $$The host name of the server.$$ *($$String$$, default: `$$$$`)* $$password$$:: $$The password to use to connect to the server.$$ *($$String$$, default: `$$$$`)* -$$port$$:: $$The port of the server.$$ *($$Integer$$, default: `$$21$$`)* +$$port$$:: $$The port of the server.$$ *($$Integer$$, default: `$$$$`)* $$username$$:: $$The username to use to connect to the server.$$ *($$String$$, default: `$$$$`)* === ftp.supplier -$$auto-create-local-dir$$:: $$Set to true to create the local directory if it does not exist.$$ *($$Boolean$$, default: `$$true$$`)* -$$delay-when-empty$$:: $$Duration of delay when no new files are detected.$$ *($$Duration$$, default: `$$1s$$`)* -$$delete-remote-files$$:: $$Set to true to delete remote files after successful transfer.$$ *($$Boolean$$, default: `$$false$$`)* +$$auto-create-local-dir$$:: $$Set to true to create the local directory if it does not exist.$$ *($$Boolean$$, default: `$$$$`)* +$$delay-when-empty$$:: $$Duration of delay when no new files are detected.$$ *($$Duration$$, default: `$$$$`)* +$$delete-remote-files$$:: $$Set to true to delete remote files after successful transfer.$$ *($$Boolean$$, default: `$$$$`)* $$filename-pattern$$:: $$A filter pattern to match the names of files to transfer.$$ *($$String$$, default: `$$$$`)* $$filename-regex$$:: $$A filter regex pattern to match the names of files to transfer.$$ *($$Pattern$$, default: `$$$$`)* $$local-dir$$:: $$The local directory to use for file transfers.$$ *($$File$$, default: `$$$$`)* -$$preserve-timestamp$$:: $$Set to true to preserve the original timestamp.$$ *($$Boolean$$, default: `$$true$$`)* -$$remote-dir$$:: $$The remote FTP directory.$$ *($$String$$, default: `$$/$$`)* -$$remote-file-separator$$:: $$The remote file separator.$$ *($$String$$, default: `$$/$$`)* -$$tmp-file-suffix$$:: $$The suffix to use while the transfer is in progress.$$ *($$String$$, default: `$$.tmp$$`)* +$$preserve-timestamp$$:: $$Set to true to preserve the original timestamp.$$ *($$Boolean$$, default: `$$$$`)* +$$remote-dir$$:: $$The remote FTP directory.$$ *($$String$$, default: `$$$$`)* +$$remote-file-separator$$:: $$The remote file separator.$$ *($$String$$, default: `$$$$`)* +$$tmp-file-suffix$$:: $$The suffix to use while the transfer is in progress.$$ *($$String$$, default: `$$$$`)* === metadata.store.dynamo-db -$$create-delay$$:: $$Delay between create table retries.$$ *($$Integer$$, default: `$$1$$`)* -$$create-retries$$:: $$Retry number for create table request.$$ *($$Integer$$, default: `$$25$$`)* -$$read-capacity$$:: $$Read capacity on the table.$$ *($$Long$$, default: `$$1$$`)* +$$create-delay$$:: $$Delay between create table retries.$$ *($$Integer$$, default: `$$$$`)* +$$create-retries$$:: $$Retry number for create table request.$$ *($$Integer$$, default: `$$$$`)* +$$read-capacity$$:: $$Read capacity on the table.$$ *($$Long$$, default: `$$$$`)* $$table$$:: $$Table name for metadata.$$ *($$String$$, default: `$$$$`)* $$time-to-live$$:: $$TTL for table entries.$$ *($$Integer$$, default: `$$$$`)* -$$write-capacity$$:: $$Write capacity on the table.$$ *($$Long$$, default: `$$1$$`)* - -=== metadata.store.gemfire - -$$region$$:: $$Gemfire region name for metadata.$$ *($$String$$, default: `$$$$`)* +$$write-capacity$$:: $$Write capacity on the table.$$ *($$Long$$, default: `$$$$`)* === metadata.store.jdbc -$$region$$:: $$Unique grouping identifier for messages persisted with this store.$$ *($$String$$, default: `$$DEFAULT$$`)* +$$region$$:: $$Unique grouping identifier for messages persisted with this store.$$ *($$String$$, default: `$$$$`)* $$table-prefix$$:: $$Prefix for the custom table name.$$ *($$String$$, default: `$$$$`)* === metadata.store.mongo-db -$$collection$$:: $$MongoDB collection name for metadata.$$ *($$String$$, default: `$$metadataStore$$`)* +$$collection$$:: $$MongoDB collection name for metadata.$$ *($$String$$, default: `$$$$`)* === metadata.store.redis @@ -127,14 +123,14 @@ $$key$$:: $$Redis key for metadata.$$ *($$String$$, default: `$$$$`)* === metadata.store -$$type$$:: $$Indicates the type of metadata store to configure (default is 'memory'). You must include the corresponding Spring Integration dependency to use a persistent store.$$ *($$StoreType$$, default: `$$$$`, possible values: `mongodb`,`gemfire`,`redis`,`dynamodb`,`jdbc`,`zookeeper`,`hazelcast`,`memory`)* +$$type$$:: $$Indicates the type of metadata store to configure (default is 'memory'). You must include the corresponding Spring Integration dependency to use a persistent store.$$ *($$StoreType$$, default: `$$$$`, possible values: `mongodb`,`redis`,`dynamodb`,`jdbc`,`zookeeper`,`hazelcast`,`memory`)* === metadata.store.zookeeper -$$connect-string$$:: $$Zookeeper connect string in form HOST:PORT.$$ *($$String$$, default: `$$127.0.0.1:2181$$`)* -$$encoding$$:: $$Encoding to use when storing data in Zookeeper.$$ *($$Charset$$, default: `$$UTF-8$$`)* -$$retry-interval$$:: $$Retry interval for Zookeeper operations in milliseconds.$$ *($$Integer$$, default: `$$1000$$`)* -$$root$$:: $$Root node - store entries are children of this node.$$ *($$String$$, default: `$$/SpringIntegration-MetadataStore$$`)* +$$connect-string$$:: $$Zookeeper connect string in form HOST:PORT.$$ *($$String$$, default: `$$$$`)* +$$encoding$$:: $$Encoding to use when storing data in Zookeeper.$$ *($$Charset$$, default: `$$$$`)* +$$retry-interval$$:: $$Retry interval for Zookeeper operations in milliseconds.$$ *($$Integer$$, default: `$$$$`)* +$$root$$:: $$Root node - store entries are children of this node.$$ *($$String$$, default: `$$$$`)* //end::configuration-properties[] == Examples diff --git a/applications/source/geode-source/README.adoc b/applications/source/geode-source/README.adoc deleted file mode 100644 index 9008602b..00000000 --- a/applications/source/geode-source/README.adoc +++ /dev/null @@ -1,50 +0,0 @@ -//tag::ref-doc[] -= Geode Source - -The Geode source will emit a stream of Objects extracted from Apache Geode EntryEvents or CqEvents. - -== Options - -The **$$geode$$** $$source$$ has the following options: - -//tag::configuration-properties[] -Properties grouped by prefix: - - -=== geode.client - -$$pdx-read-serialized$$:: $$Deserialize the Geode objects into PdxInstance instead of the domain class.$$ *($$Boolean$$, default: `$$false$$`)* - -=== geode.pool - -$$connect-type$$:: $$Specifies connection type: 'server' or 'locator'.$$ *($$ConnectType$$, default: `$$$$`, possible values: `locator`,`server`)* -$$host-addresses$$:: $$Specifies one or more Gemfire locator or server addresses formatted as [host]:[port].$$ *($$InetSocketAddress[]$$, default: `$$$$`)* -$$subscription-enabled$$:: $$Set to true to enable subscriptions for the client pool. Required to sync updates to the client cache.$$ *($$Boolean$$, default: `$$false$$`)* - -=== geode.region - -$$region-name$$:: $$The region name.$$ *($$String$$, default: `$$$$`)* - -=== geode.security - -$$password$$:: $$The cache password.$$ *($$String$$, default: `$$$$`)* -$$username$$:: $$The cache username.$$ *($$String$$, default: `$$$$`)* - -=== geode.security.ssl - -$$ciphers$$:: $$Configures the SSL ciphers used for secure Socket connections as an array of valid cipher names.$$ *($$String$$, default: `$$any$$`)* -$$keystore-type$$:: $$Identifies the type of Keystore used for SSL communications (e.g. JKS, PKCS11, etc.).$$ *($$String$$, default: `$$JKS$$`)* -$$keystore-uri$$:: $$Location of the pre-created Keystore URI to be used for connecting to the Geode cluster.$$ *($$Resource$$, default: `$$$$`)* -$$ssl-keystore-password$$:: $$Password for accessing the keys truststore.$$ *($$String$$, default: `$$$$`)* -$$ssl-truststore-password$$:: $$Password for accessing the trust store.$$ *($$String$$, default: `$$$$`)* -$$truststore-type$$:: $$Identifies the type of truststore used for SSL communications (e.g. JKS, PKCS11, etc.).$$ *($$String$$, default: `$$JKS$$`)* -$$truststore-uri$$:: $$Location of the pre-created truststore URI to be used for connecting to the Geode cluster.$$ *($$Resource$$, default: `$$$$`)* -$$user-home-directory$$:: $$Local directory to cache the truststore and keystore files downloaded form the truststoreUri and keystoreUri locations.$$ *($$String$$, default: `$$user.home$$`)* - -=== geode.supplier - -$$event-expression$$:: $$SpEL expression to extract data from an {@link org.apache.geode.cache.EntryEvent} or {@link org.apache.geode.cache.query.CqEvent}.$$ *($$Expression$$, default: `$$$$`)* -$$query$$:: $$An OQL query. This will enable continuous query if provided.$$ *($$String$$, default: `$$$$`)* -//end::configuration-properties[] - -//end::ref-doc[] diff --git a/applications/source/geode-source/pom.xml b/applications/source/geode-source/pom.xml deleted file mode 100644 index ff099daa..00000000 --- a/applications/source/geode-source/pom.xml +++ /dev/null @@ -1,74 +0,0 @@ - - - 4.0.0 - geode-source - geode-source - Geode source app - jar - - - org.springframework.cloud.stream.app - stream-applications-core - 4.0.0-SNAPSHOT - ../../stream-applications-core/pom.xml - - - - org.springframework.cloud.fn - geode-supplier - - - org.projectlombok - lombok - test - - - org.springframework.geode - spring-geode-starter-test - test - - - org.springframework.geode - spring-geode-starter-logging - test - - - - - - - org.springframework.cloud - spring-cloud-dataflow-apps-docs-plugin - - - org.springframework.cloud - spring-cloud-dataflow-apps-generator-plugin - - - geode - source - ${project.version} - org.springframework.cloud.fn.supplier.geode.GeodeSupplierConfiguration.class - geodeSupplier - - - - - org.springframework.cloud.fn - geode-supplier - - - org.springframework.cloud.stream.app - stream-applications-composite-function-support - ${stream-apps-core.version} - - - - - - - - - - diff --git a/applications/source/geode-source/src/main/resources/META-INF/dataflow-configuration-metadata-whitelist.properties b/applications/source/geode-source/src/main/resources/META-INF/dataflow-configuration-metadata-whitelist.properties deleted file mode 100644 index b0650cc8..00000000 --- a/applications/source/geode-source/src/main/resources/META-INF/dataflow-configuration-metadata-whitelist.properties +++ /dev/null @@ -1,6 +0,0 @@ -configuration-properties.classes=org.springframework.cloud.fn.supplier.geode.GeodeSupplierProperties,\ -org.springframework.cloud.fn.common.geode.GeodeClientCacheProperties,\ -org.springframework.cloud.fn.common.geode.GeodeRegionProperties,\ -org.springframework.cloud.fn.common.geode.GeodePoolProperties,\ -org.springframework.cloud.fn.common.geode.GeodeSecurityProperties,\ -org.springframework.cloud.fn.common.geode.GeodeSslProperties diff --git a/applications/source/geode-source/src/main/resources/META-INF/dataflow-configuration-metadata.properties b/applications/source/geode-source/src/main/resources/META-INF/dataflow-configuration-metadata.properties deleted file mode 100644 index b0650cc8..00000000 --- a/applications/source/geode-source/src/main/resources/META-INF/dataflow-configuration-metadata.properties +++ /dev/null @@ -1,6 +0,0 @@ -configuration-properties.classes=org.springframework.cloud.fn.supplier.geode.GeodeSupplierProperties,\ -org.springframework.cloud.fn.common.geode.GeodeClientCacheProperties,\ -org.springframework.cloud.fn.common.geode.GeodeRegionProperties,\ -org.springframework.cloud.fn.common.geode.GeodePoolProperties,\ -org.springframework.cloud.fn.common.geode.GeodeSecurityProperties,\ -org.springframework.cloud.fn.common.geode.GeodeSslProperties diff --git a/applications/source/geode-source/src/test/java/org/springframework/cloud/stream/app/source/geode/GeodeSourceTests.java b/applications/source/geode-source/src/test/java/org/springframework/cloud/stream/app/source/geode/GeodeSourceTests.java deleted file mode 100644 index 12b4d7ce..00000000 --- a/applications/source/geode-source/src/test/java/org/springframework/cloud/stream/app/source/geode/GeodeSourceTests.java +++ /dev/null @@ -1,149 +0,0 @@ -/* - * Copyright 2020-2020 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.stream.app.source.geode; - -import java.io.IOException; -import java.time.Duration; -import java.util.ArrayList; -import java.util.List; - -import com.fasterxml.jackson.core.JsonProcessingException; -import com.fasterxml.jackson.databind.ObjectMapper; -import lombok.AllArgsConstructor; -import lombok.Data; -import lombok.NoArgsConstructor; -import org.apache.geode.cache.Region; -import org.apache.geode.pdx.PdxInstance; -import org.junit.jupiter.api.AfterAll; -import org.junit.jupiter.api.BeforeAll; -import org.junit.jupiter.api.Tag; -import org.junit.jupiter.api.Test; - -import org.springframework.boot.autoconfigure.SpringBootApplication; -import org.springframework.boot.test.context.runner.ApplicationContextRunner; -import org.springframework.cloud.fn.common.geode.JsonPdxFunctions; -import org.springframework.cloud.fn.supplier.geode.GeodeSupplierConfiguration; -import org.springframework.cloud.stream.app.source.geodeserver.GeodeServerTestConfiguration; -import org.springframework.cloud.stream.binder.test.OutputDestination; -import org.springframework.cloud.stream.binder.test.TestChannelBinderConfiguration; -import org.springframework.context.annotation.Import; -import org.springframework.data.gemfire.tests.integration.ForkingClientServerIntegrationTestsSupport; -import org.springframework.messaging.Message; - -import static org.assertj.core.api.Assertions.assertThat; - -@Tag("integration") -public class GeodeSourceTests { - - private static ApplicationContextRunner applicationContextRunner; - - - private ObjectMapper objectMapper = new ObjectMapper(); - - @BeforeAll - static void setup() throws IOException { - ForkingClientServerIntegrationTestsSupport.startGemFireServer( - GeodeServerTestConfiguration.class, "-Dspring.data.gemfire.logging.level=warn"); - - applicationContextRunner = new ApplicationContextRunner() - .withUserConfiguration( - TestChannelBinderConfiguration.getCompleteConfiguration(GeodeSourceTestApplication.class)); - - } - - @AfterAll - static void stopServer() { - ForkingClientServerIntegrationTestsSupport.stopGemFireServer(); - ForkingClientServerIntegrationTestsSupport.clearCacheServerPortAndPoolPortProperties(); - } - - @Test - void getCacheEvents() { - applicationContextRunner - .withPropertyValues("geode.region.regionName=myRegion", - "geode.supplier.event-expression=key+':'+newValue", - "geode.pool.connectType=server", - "geode.pool.hostAddresses=" + "localhost:" + System.getProperty("spring.data.gemfire.cache.server.port"), - "spring.cloud.function.definition=geodeSupplier") - .run(context -> { - - // Using local region here since it's faster - Region region = context.getBean(Region.class); - - region.put("foo", "bar"); - region.put("name", "dave"); - region.put("hello", "world"); - OutputDestination outputDestination = context.getBean(OutputDestination.class); - - List values = new ArrayList(); - for (int i = 0; i < 3; i++) { - Message message = outputDestination.receive(Duration.ofSeconds(3).toMillis(), "geodeSupplier-out-0"); - assertThat(message).isNotNull(); - values.add(new String(message.getPayload())); - } - - assertThat(values).containsExactly("foo:bar", "name:dave", "hello:world"); - }); - } - - @Test - void pdxReadSerialized() { - applicationContextRunner - .withPropertyValues( - "spring.cloud.function.definition=geodeSupplier", - "geode.region.regionName=myRegion", - "geode.client.pdx-read-serialized=true", - "geode.supplier.query=Select * from /myRegion where symbol='XXX' and price > 140", - "geode.pool.connectType=server", - "geode.pool.hostAddresses=" + "localhost:" + System.getProperty("spring.data.gemfire.cache.server.port")) - .run(context -> { - OutputDestination outputDestination = context.getBean(OutputDestination.class); - // Using local region here - Region region = context.getBean(Region.class); - putStockEvent(region, new Stock("XXX", 140.00)); - putStockEvent(region, new Stock("XXX", 140.20)); - putStockEvent(region, new Stock("YYY", 110.00)); - putStockEvent(region, new Stock("YYY", 110.01)); - putStockEvent(region, new Stock("XXX", 139.80)); - - Message message = outputDestination.receive(Duration.ofSeconds(3).toMillis(), "geodeSupplier-out-0"); - assertThat(message).isNotNull(); - Stock result = objectMapper.readValue(message.getPayload(), Stock.class); - assertThat(result).isEqualTo(new Stock("XXX", 140.20)); - }); - } - - private void putStockEvent(Region region, Stock stock) throws JsonProcessingException { - String json = objectMapper.writeValueAsString(stock); - region.put(stock.getSymbol(), JsonPdxFunctions.jsonToPdx().apply(json)); - } - - @Data - @AllArgsConstructor - @NoArgsConstructor - static class Stock { - private String symbol; - - private double price; - } - - @SpringBootApplication - @Import(GeodeSupplierConfiguration.class) - static class GeodeSourceTestApplication { - - } -} diff --git a/applications/source/geode-source/src/test/java/org/springframework/cloud/stream/app/source/geodeserver/GeodeServerTestConfiguration.java b/applications/source/geode-source/src/test/java/org/springframework/cloud/stream/app/source/geodeserver/GeodeServerTestConfiguration.java deleted file mode 100644 index 266868ef..00000000 --- a/applications/source/geode-source/src/test/java/org/springframework/cloud/stream/app/source/geodeserver/GeodeServerTestConfiguration.java +++ /dev/null @@ -1,47 +0,0 @@ -/* - * Copyright 2020-2020 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.stream.app.source.geodeserver; - -import org.apache.geode.cache.GemFireCache; -import org.apache.geode.cache.Scope; - -import org.springframework.context.annotation.AnnotationConfigApplicationContext; -import org.springframework.context.annotation.Bean; -import org.springframework.data.gemfire.ReplicatedRegionFactoryBean; -import org.springframework.data.gemfire.config.annotation.CacheServerApplication; - -@CacheServerApplication -public class GeodeServerTestConfiguration { - - public static void main(String[] args) { - - AnnotationConfigApplicationContext applicationContext = - new AnnotationConfigApplicationContext(GeodeServerTestConfiguration.class); - - applicationContext.registerShutdownHook(); - } - - @Bean("myRegion") - public ReplicatedRegionFactoryBean myRegion(GemFireCache gemfireCache) { - - ReplicatedRegionFactoryBean regionFactoryBean = new ReplicatedRegionFactoryBean<>(); - regionFactoryBean.setScope(Scope.DISTRIBUTED_ACK); - regionFactoryBean.setCache(gemfireCache); - - return regionFactoryBean; - } -} diff --git a/applications/source/geode-source/src/test/resources/logback-include.xml b/applications/source/geode-source/src/test/resources/logback-include.xml deleted file mode 100644 index ae330ab3..00000000 --- a/applications/source/geode-source/src/test/resources/logback-include.xml +++ /dev/null @@ -1,16 +0,0 @@ - - - - - - %d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n - - - - - - - - - - diff --git a/applications/source/http-source/README.adoc b/applications/source/http-source/README.adoc index 2bb03088..cae0807e 100644 --- a/applications/source/http-source/README.adoc +++ b/applications/source/http-source/README.adoc @@ -32,7 +32,7 @@ $$allowed-origins$$:: $$List of allowed origins, e.g. https://domain1.com.$$ *($ === http $$mapped-request-headers$$:: $$Headers that will be mapped.$$ *($$String[]$$, default: `$$$$`)* -$$path-pattern$$:: $$HTTP endpoint path mapping.$$ *($$String$$, default: `$$/$$`)* +$$path-pattern$$:: $$HTTP endpoint path mapping.$$ *($$String$$, default: `$$$$`)* === server diff --git a/applications/source/jdbc-source/README.adoc b/applications/source/jdbc-source/README.adoc index 0a59e162..4a6d3258 100644 --- a/applications/source/jdbc-source/README.adoc +++ b/applications/source/jdbc-source/README.adoc @@ -18,9 +18,9 @@ Properties grouped by prefix: === jdbc.supplier -$$max-rows$$:: $$Max numbers of rows to process for query.$$ *($$Integer$$, default: `$$0$$`)* +$$max-rows$$:: $$Max numbers of rows to process for query.$$ *($$Integer$$, default: `$$$$`)* $$query$$:: $$The query to use to select data.$$ *($$String$$, default: `$$$$`)* -$$split$$:: $$Whether to split the SQL result as individual messages.$$ *($$Boolean$$, default: `$$true$$`)* +$$split$$:: $$Whether to split the SQL result as individual messages.$$ *($$Boolean$$, default: `$$$$`)* $$update$$:: $$An SQL update statement to execute for marking polled messages as 'seen'.$$ *($$String$$, default: `$$$$`)* === spring.datasource diff --git a/applications/source/jms-source/README.adoc b/applications/source/jms-source/README.adoc index d709e604..4efd0203 100644 --- a/applications/source/jms-source/README.adoc +++ b/applications/source/jms-source/README.adoc @@ -16,7 +16,7 @@ Properties grouped by prefix: $$client-id$$:: $$Client id for durable subscriptions.$$ *($$String$$, default: `$$$$`)* $$destination$$:: $$The destination from which to receive messages (queue or topic).$$ *($$String$$, default: `$$$$`)* $$message-selector$$:: $$A selector for messages.$$ *($$String$$, default: `$$$$`)* -$$session-transacted$$:: $$True to enable transactions and select a DefaultMessageListenerContainer, false to select a SimpleMessageListenerContainer.$$ *($$Boolean$$, default: `$$true$$`)* +$$session-transacted$$:: $$True to enable transactions and select a DefaultMessageListenerContainer, false to select a SimpleMessageListenerContainer.$$ *($$Boolean$$, default: `$$$$`)* $$subscription-durable$$:: $$True for a durable subscription.$$ *($$Boolean$$, default: `$$$$`)* $$subscription-name$$:: $$The name of a durable or shared subscription.$$ *($$String$$, default: `$$$$`)* $$subscription-shared$$:: $$True for a shared subscription.$$ *($$Boolean$$, default: `$$$$`)* diff --git a/applications/source/load-generator-source/README.adoc b/applications/source/load-generator-source/README.adoc index 4ea48e26..1a3fd572 100644 --- a/applications/source/load-generator-source/README.adoc +++ b/applications/source/load-generator-source/README.adoc @@ -8,10 +8,10 @@ A source that sends generated data and dispatches it to the stream. The **$$load-generator$$** $$source$$ has the following options: //tag::configuration-properties[] -$$load-generator.generate-timestamp$$:: $$Whether timestamp generated.$$ *($$Boolean$$, default: `$$false$$`)* -$$load-generator.message-count$$:: $$Message count.$$ *($$Integer$$, default: `$$1000$$`)* -$$load-generator.message-size$$:: $$Message size.$$ *($$Integer$$, default: `$$1000$$`)* -$$load-generator.producers$$:: $$Number of producers.$$ *($$Integer$$, default: `$$1$$`)* +$$load-generator.generate-timestamp$$:: $$Whether timestamp generated.$$ *($$Boolean$$, default: `$$$$`)* +$$load-generator.message-count$$:: $$Message count.$$ *($$Integer$$, default: `$$$$`)* +$$load-generator.message-size$$:: $$Message size.$$ *($$Integer$$, default: `$$$$`)* +$$load-generator.producers$$:: $$Number of producers.$$ *($$Integer$$, default: `$$$$`)* //end::configuration-properties[] //end::ref-doc[] diff --git a/applications/source/mail-source/README.adoc b/applications/source/mail-source/README.adoc index a0873759..48f8673c 100644 --- a/applications/source/mail-source/README.adoc +++ b/applications/source/mail-source/README.adoc @@ -8,12 +8,12 @@ A source application that listens for Emails and emits the message body as a mes The **$$mail$$** $$source$$ has the following options: //tag::configuration-properties[] -$$mail.supplier.charset$$:: $$The charset for byte[] mail-to-string transformation.$$ *($$String$$, default: `$$UTF-8$$`)* -$$mail.supplier.delete$$:: $$Set to true to delete email after download.$$ *($$Boolean$$, default: `$$false$$`)* -$$mail.supplier.expression$$:: $$Configure a SpEL expression to select messages.$$ *($$String$$, default: `$$true$$`)* -$$mail.supplier.idle-imap$$:: $$Set to true to use IdleImap Configuration.$$ *($$Boolean$$, default: `$$false$$`)* +$$mail.supplier.charset$$:: $$The charset for byte[] mail-to-string transformation.$$ *($$String$$, default: `$$$$`)* +$$mail.supplier.delete$$:: $$Set to true to delete email after download.$$ *($$Boolean$$, default: `$$$$`)* +$$mail.supplier.expression$$:: $$Configure a SpEL expression to select messages.$$ *($$String$$, default: `$$$$`)* +$$mail.supplier.idle-imap$$:: $$Set to true to use IdleImap Configuration.$$ *($$Boolean$$, default: `$$$$`)* $$mail.supplier.java-mail-properties$$:: $$JavaMail properties as a new line delimited string of name-value pairs, e.g. 'foo=bar\n baz=car'.$$ *($$Properties$$, default: `$$$$`)* -$$mail.supplier.mark-as-read$$:: $$Set to true to mark email as read.$$ *($$Boolean$$, default: `$$false$$`)* +$$mail.supplier.mark-as-read$$:: $$Set to true to mark email as read.$$ *($$Boolean$$, default: `$$$$`)* $$mail.supplier.url$$:: $$Mail connection URL for connection to Mail server e.g. 'imaps://username:password@imap.server.com:993/Inbox'.$$ *($$URLName$$, default: `$$$$`)* $$mail.supplier.user-flag$$:: $$The flag to mark messages when the server does not support \Recent.$$ *($$String$$, default: `$$$$`)* //end::configuration-properties[] diff --git a/applications/source/mongodb-source/README.adoc b/applications/source/mongodb-source/README.adoc index 466abcf8..ba5914a0 100644 --- a/applications/source/mongodb-source/README.adoc +++ b/applications/source/mongodb-source/README.adoc @@ -19,9 +19,9 @@ Properties grouped by prefix: === mongodb.supplier $$collection$$:: $$The MongoDB collection to query.$$ *($$String$$, default: `$$$$`)* -$$query$$:: $$The MongoDB query.$$ *($$String$$, default: `$${ }$$`)* +$$query$$:: $$The MongoDB query.$$ *($$String$$, default: `$$$$`)* $$query-expression$$:: $$The SpEL expression in MongoDB query DSL style.$$ *($$Expression$$, default: `$$$$`)* -$$split$$:: $$Whether to split the query result as individual messages.$$ *($$Boolean$$, default: `$$true$$`)* +$$split$$:: $$Whether to split the query result as individual messages.$$ *($$Boolean$$, default: `$$$$`)* $$update-expression$$:: $$The SpEL expression in MongoDB update DSL style.$$ *($$Expression$$, default: `$$$$`)* === spring.data.mongodb diff --git a/applications/source/mqtt-source/README.adoc b/applications/source/mqtt-source/README.adoc index ed098c9b..9b9c1dd1 100644 --- a/applications/source/mqtt-source/README.adoc +++ b/applications/source/mqtt-source/README.adoc @@ -18,23 +18,23 @@ Properties grouped by prefix: === mqtt -$$clean-session$$:: $$whether the client and server should remember state across restarts and reconnects.$$ *($$Boolean$$, default: `$$true$$`)* -$$connection-timeout$$:: $$the connection timeout in seconds.$$ *($$Integer$$, default: `$$30$$`)* -$$keep-alive-interval$$:: $$the ping interval in seconds.$$ *($$Integer$$, default: `$$60$$`)* -$$password$$:: $$the password to use when connecting to the broker.$$ *($$String$$, default: `$$guest$$`)* -$$persistence$$:: $$'memory' or 'file'.$$ *($$String$$, default: `$$memory$$`)* -$$persistence-directory$$:: $$Persistence directory.$$ *($$String$$, default: `$$/tmp/paho$$`)* +$$clean-session$$:: $$whether the client and server should remember state across restarts and reconnects.$$ *($$Boolean$$, default: `$$$$`)* +$$connection-timeout$$:: $$the connection timeout in seconds.$$ *($$Integer$$, default: `$$$$`)* +$$keep-alive-interval$$:: $$the ping interval in seconds.$$ *($$Integer$$, default: `$$$$`)* +$$password$$:: $$the password to use when connecting to the broker.$$ *($$String$$, default: `$$$$`)* +$$persistence$$:: $$'memory' or 'file'.$$ *($$String$$, default: `$$$$`)* +$$persistence-directory$$:: $$Persistence directory.$$ *($$String$$, default: `$$$$`)* $$ssl-properties$$:: $$MQTT Client SSL properties.$$ *($$Map$$, default: `$$$$`)* -$$url$$:: $$location of the mqtt broker(s) (comma-delimited list).$$ *($$String[]$$, default: `$$[tcp://localhost:1883]$$`)* -$$username$$:: $$the username to use when connecting to the broker.$$ *($$String$$, default: `$$guest$$`)* +$$url$$:: $$location of the mqtt broker(s) (comma-delimited list).$$ *($$String[]$$, default: `$$$$`)* +$$username$$:: $$the username to use when connecting to the broker.$$ *($$String$$, default: `$$$$`)* === mqtt.supplier -$$binary$$:: $$true to leave the payload as bytes.$$ *($$Boolean$$, default: `$$false$$`)* -$$charset$$:: $$the charset used to convert bytes to String (when binary is false).$$ *($$String$$, default: `$$UTF-8$$`)* -$$client-id$$:: $$identifies the client.$$ *($$String$$, default: `$$stream.client.id.source$$`)* -$$qos$$:: $$the qos; a single value for all topics or a comma-delimited list to match the topics.$$ *($$Integer[]$$, default: `$$[0]$$`)* -$$topics$$:: $$the topic(s) (comma-delimited) to which the source will subscribe.$$ *($$String[]$$, default: `$$[stream.mqtt]$$`)* +$$binary$$:: $$true to leave the payload as bytes.$$ *($$Boolean$$, default: `$$$$`)* +$$charset$$:: $$the charset used to convert bytes to String (when binary is false).$$ *($$String$$, default: `$$$$`)* +$$client-id$$:: $$identifies the client.$$ *($$String$$, default: `$$$$`)* +$$qos$$:: $$the qos; a single value for all topics or a comma-delimited list to match the topics.$$ *($$Integer[]$$, default: `$$$$`)* +$$topics$$:: $$the topic(s) (comma-delimited) to which the source will subscribe.$$ *($$String[]$$, default: `$$$$`)* //end::configuration-properties[] //end::ref-doc[] diff --git a/applications/source/pom.xml b/applications/source/pom.xml index 324b8326..29f8de2a 100644 --- a/applications/source/pom.xml +++ b/applications/source/pom.xml @@ -10,7 +10,6 @@ pom - geode-source file-source ftp-source jdbc-source diff --git a/applications/source/rabbit-source/README.adoc b/applications/source/rabbit-source/README.adoc index d58758da..92fd94af 100644 --- a/applications/source/rabbit-source/README.adoc +++ b/applications/source/rabbit-source/README.adoc @@ -26,16 +26,16 @@ Properties grouped by prefix: === rabbit.supplier -$$enable-retry$$:: $$true to enable retry.$$ *($$Boolean$$, default: `$$false$$`)* -$$initial-retry-interval$$:: $$Initial retry interval when retry is enabled.$$ *($$Integer$$, default: `$$1000$$`)* -$$mapped-request-headers$$:: $$Headers that will be mapped.$$ *($$String[]$$, default: `$$[STANDARD_REQUEST_HEADERS]$$`)* -$$max-attempts$$:: $$The maximum delivery attempts when retry is enabled.$$ *($$Integer$$, default: `$$3$$`)* -$$max-retry-interval$$:: $$Max retry interval when retry is enabled.$$ *($$Integer$$, default: `$$30000$$`)* -$$own-connection$$:: $$When true, use a separate connection based on the boot properties.$$ *($$Boolean$$, default: `$$false$$`)* +$$enable-retry$$:: $$true to enable retry.$$ *($$Boolean$$, default: `$$$$`)* +$$initial-retry-interval$$:: $$Initial retry interval when retry is enabled.$$ *($$Integer$$, default: `$$$$`)* +$$mapped-request-headers$$:: $$Headers that will be mapped.$$ *($$String[]$$, default: `$$$$`)* +$$max-attempts$$:: $$The maximum delivery attempts when retry is enabled.$$ *($$Integer$$, default: `$$$$`)* +$$max-retry-interval$$:: $$Max retry interval when retry is enabled.$$ *($$Integer$$, default: `$$$$`)* +$$own-connection$$:: $$When true, use a separate connection based on the boot properties.$$ *($$Boolean$$, default: `$$$$`)* $$queues$$:: $$The queues to which the source will listen for messages.$$ *($$String[]$$, default: `$$$$`)* -$$requeue$$:: $$Whether rejected messages should be requeued.$$ *($$Boolean$$, default: `$$true$$`)* -$$retry-multiplier$$:: $$Retry backoff multiplier when retry is enabled.$$ *($$Double$$, default: `$$2$$`)* -$$transacted$$:: $$Whether the channel is transacted.$$ *($$Boolean$$, default: `$$false$$`)* +$$requeue$$:: $$Whether rejected messages should be requeued.$$ *($$Boolean$$, default: `$$$$`)* +$$retry-multiplier$$:: $$Retry backoff multiplier when retry is enabled.$$ *($$Double$$, default: `$$$$`)* +$$transacted$$:: $$Whether the channel is transacted.$$ *($$Boolean$$, default: `$$$$`)* === spring.rabbitmq diff --git a/applications/source/s3-source/README.adoc b/applications/source/s3-source/README.adoc index 76880905..744f8abc 100644 --- a/applications/source/s3-source/README.adoc +++ b/applications/source/s3-source/README.adoc @@ -58,31 +58,27 @@ Properties grouped by prefix: === file.consumer -$$markers-json$$:: $$When 'fileMarkers == true', specify if they should be produced as FileSplitter.FileMarker objects or JSON.$$ *($$Boolean$$, default: `$$true$$`)* +$$markers-json$$:: $$When 'fileMarkers == true', specify if they should be produced as FileSplitter.FileMarker objects or JSON.$$ *($$Boolean$$, default: `$$$$`)* $$mode$$:: $$The FileReadingMode to use for file reading sources. Values are 'ref' - The File object, 'lines' - a message per line, or 'contents' - the contents as bytes.$$ *($$FileReadingMode$$, default: `$$$$`, possible values: `ref`,`lines`,`contents`)* $$with-markers$$:: $$Set to true to emit start of file/end of file marker messages before/after the data. Only valid with FileReadingMode 'lines'.$$ *($$Boolean$$, default: `$$$$`)* === metadata.store.dynamo-db -$$create-delay$$:: $$Delay between create table retries.$$ *($$Integer$$, default: `$$1$$`)* -$$create-retries$$:: $$Retry number for create table request.$$ *($$Integer$$, default: `$$25$$`)* -$$read-capacity$$:: $$Read capacity on the table.$$ *($$Long$$, default: `$$1$$`)* +$$create-delay$$:: $$Delay between create table retries.$$ *($$Integer$$, default: `$$$$`)* +$$create-retries$$:: $$Retry number for create table request.$$ *($$Integer$$, default: `$$$$`)* +$$read-capacity$$:: $$Read capacity on the table.$$ *($$Long$$, default: `$$$$`)* $$table$$:: $$Table name for metadata.$$ *($$String$$, default: `$$$$`)* $$time-to-live$$:: $$TTL for table entries.$$ *($$Integer$$, default: `$$$$`)* -$$write-capacity$$:: $$Write capacity on the table.$$ *($$Long$$, default: `$$1$$`)* - -=== metadata.store.gemfire - -$$region$$:: $$Gemfire region name for metadata.$$ *($$String$$, default: `$$$$`)* +$$write-capacity$$:: $$Write capacity on the table.$$ *($$Long$$, default: `$$$$`)* === metadata.store.jdbc -$$region$$:: $$Unique grouping identifier for messages persisted with this store.$$ *($$String$$, default: `$$DEFAULT$$`)* +$$region$$:: $$Unique grouping identifier for messages persisted with this store.$$ *($$String$$, default: `$$$$`)* $$table-prefix$$:: $$Prefix for the custom table name.$$ *($$String$$, default: `$$$$`)* === metadata.store.mongo-db -$$collection$$:: $$MongoDB collection name for metadata.$$ *($$String$$, default: `$$metadataStore$$`)* +$$collection$$:: $$MongoDB collection name for metadata.$$ *($$String$$, default: `$$$$`)* === metadata.store.redis @@ -90,32 +86,32 @@ $$key$$:: $$Redis key for metadata.$$ *($$String$$, default: `$$$$`)* === metadata.store -$$type$$:: $$Indicates the type of metadata store to configure (default is 'memory'). You must include the corresponding Spring Integration dependency to use a persistent store.$$ *($$StoreType$$, default: `$$$$`, possible values: `mongodb`,`gemfire`,`redis`,`dynamodb`,`jdbc`,`zookeeper`,`hazelcast`,`memory`)* +$$type$$:: $$Indicates the type of metadata store to configure (default is 'memory'). You must include the corresponding Spring Integration dependency to use a persistent store.$$ *($$StoreType$$, default: `$$$$`, possible values: `mongodb`,`redis`,`dynamodb`,`jdbc`,`zookeeper`,`hazelcast`,`memory`)* === metadata.store.zookeeper -$$connect-string$$:: $$Zookeeper connect string in form HOST:PORT.$$ *($$String$$, default: `$$127.0.0.1:2181$$`)* -$$encoding$$:: $$Encoding to use when storing data in Zookeeper.$$ *($$Charset$$, default: `$$UTF-8$$`)* -$$retry-interval$$:: $$Retry interval for Zookeeper operations in milliseconds.$$ *($$Integer$$, default: `$$1000$$`)* -$$root$$:: $$Root node - store entries are children of this node.$$ *($$String$$, default: `$$/SpringIntegration-MetadataStore$$`)* +$$connect-string$$:: $$Zookeeper connect string in form HOST:PORT.$$ *($$String$$, default: `$$$$`)* +$$encoding$$:: $$Encoding to use when storing data in Zookeeper.$$ *($$Charset$$, default: `$$$$`)* +$$retry-interval$$:: $$Retry interval for Zookeeper operations in milliseconds.$$ *($$Integer$$, default: `$$$$`)* +$$root$$:: $$Root node - store entries are children of this node.$$ *($$String$$, default: `$$$$`)* === s3.common $$endpoint-url$$:: $$Optional endpoint url to connect to s3 compatible storage.$$ *($$String$$, default: `$$$$`)* -$$path-style-access$$:: $$Use path style access.$$ *($$Boolean$$, default: `$$false$$`)* +$$path-style-access$$:: $$Use path style access.$$ *($$Boolean$$, default: `$$$$`)* === s3.supplier -$$auto-create-local-dir$$:: $$Create or not the local directory.$$ *($$Boolean$$, default: `$$true$$`)* -$$delete-remote-files$$:: $$Delete or not remote files after processing.$$ *($$Boolean$$, default: `$$false$$`)* +$$auto-create-local-dir$$:: $$Create or not the local directory.$$ *($$Boolean$$, default: `$$$$`)* +$$delete-remote-files$$:: $$Delete or not remote files after processing.$$ *($$Boolean$$, default: `$$$$`)* $$filename-pattern$$:: $$The pattern to filter remote files.$$ *($$String$$, default: `$$$$`)* $$filename-regex$$:: $$The regexp to filter remote files.$$ *($$Pattern$$, default: `$$$$`)* -$$list-only$$:: $$Set to true to return s3 object metadata without copying file to a local directory.$$ *($$Boolean$$, default: `$$false$$`)* +$$list-only$$:: $$Set to true to return s3 object metadata without copying file to a local directory.$$ *($$Boolean$$, default: `$$$$`)* $$local-dir$$:: $$The local directory to store files.$$ *($$File$$, default: `$$$$`)* -$$preserve-timestamp$$:: $$To transfer or not the timestamp of the remote file to the local one.$$ *($$Boolean$$, default: `$$true$$`)* -$$remote-dir$$:: $$AWS S3 bucket resource.$$ *($$String$$, default: `$$bucket$$`)* -$$remote-file-separator$$:: $$Remote File separator.$$ *($$String$$, default: `$$/$$`)* -$$tmp-file-suffix$$:: $$Temporary file suffix.$$ *($$String$$, default: `$$.tmp$$`)* +$$preserve-timestamp$$:: $$To transfer or not the timestamp of the remote file to the local one.$$ *($$Boolean$$, default: `$$$$`)* +$$remote-dir$$:: $$AWS S3 bucket resource.$$ *($$String$$, default: `$$$$`)* +$$remote-file-separator$$:: $$Remote File separator.$$ *($$String$$, default: `$$$$`)* +$$tmp-file-suffix$$:: $$Temporary file suffix.$$ *($$String$$, default: `$$$$`)* //end::configuration-properties[] == Amazon AWS common options diff --git a/applications/source/syslog-source/README.adoc b/applications/source/syslog-source/README.adoc index 74f6ab2f..882bb05c 100644 --- a/applications/source/syslog-source/README.adoc +++ b/applications/source/syslog-source/README.adoc @@ -6,13 +6,13 @@ The syslog source receives SYSLOG packets over UDP, TCP, or both. RFC3164 (BSD) == Options //tag::configuration-properties[] -$$syslog.supplier.buffer-size$$:: $$the buffer size used when decoding messages; larger messages will be rejected.$$ *($$Integer$$, default: `$$2048$$`)* -$$syslog.supplier.nio$$:: $$whether or not to use NIO (when supporting a large number of connections).$$ *($$Boolean$$, default: `$$false$$`)* -$$syslog.supplier.port$$:: $$The port to listen on.$$ *($$Integer$$, default: `$$1514$$`)* +$$syslog.supplier.buffer-size$$:: $$the buffer size used when decoding messages; larger messages will be rejected.$$ *($$Integer$$, default: `$$$$`)* +$$syslog.supplier.nio$$:: $$whether or not to use NIO (when supporting a large number of connections).$$ *($$Boolean$$, default: `$$$$`)* +$$syslog.supplier.port$$:: $$The port to listen on.$$ *($$Integer$$, default: `$$$$`)* $$syslog.supplier.protocol$$:: $$Protocol used for SYSLOG (tcp or udp).$$ *($$Protocol$$, default: `$$$$`, possible values: `tcp`,`udp`,`both`)* -$$syslog.supplier.reverse-lookup$$:: $$whether or not to perform a reverse lookup on the incoming socket.$$ *($$Boolean$$, default: `$$false$$`)* -$$syslog.supplier.rfc$$:: $$'5424' or '3164' - the syslog format according to the RFC; 3164 is aka 'BSD' format.$$ *($$String$$, default: `$$3164$$`)* -$$syslog.supplier.socket-timeout$$:: $$the socket timeout.$$ *($$Integer$$, default: `$$0$$`)* +$$syslog.supplier.reverse-lookup$$:: $$whether or not to perform a reverse lookup on the incoming socket.$$ *($$Boolean$$, default: `$$$$`)* +$$syslog.supplier.rfc$$:: $$'5424' or '3164' - the syslog format according to the RFC; 3164 is aka 'BSD' format.$$ *($$String$$, default: `$$$$`)* +$$syslog.supplier.socket-timeout$$:: $$the socket timeout.$$ *($$Integer$$, default: `$$$$`)* //end::configuration-properties[] //end::ref-doc[] diff --git a/applications/source/tcp-source/README.adoc b/applications/source/tcp-source/README.adoc index 6fb00232..fcb4496b 100644 --- a/applications/source/tcp-source/README.adoc +++ b/applications/source/tcp-source/README.adoc @@ -15,15 +15,15 @@ Properties grouped by prefix: === tcp -$$nio$$:: $$Whether or not to use NIO.$$ *($$Boolean$$, default: `$$false$$`)* -$$port$$:: $$The port on which to listen; 0 for the OS to choose a port.$$ *($$Integer$$, default: `$$1234$$`)* -$$reverse-lookup$$:: $$Perform a reverse DNS lookup on the remote IP Address; if false, just the IP address is included in the message headers.$$ *($$Boolean$$, default: `$$false$$`)* -$$socket-timeout$$:: $$The timeout (ms) before closing the socket when no data is received.$$ *($$Integer$$, default: `$$120000$$`)* -$$use-direct-buffers$$:: $$Whether or not to use direct buffers.$$ *($$Boolean$$, default: `$$false$$`)* +$$nio$$:: $$Whether or not to use NIO.$$ *($$Boolean$$, default: `$$$$`)* +$$port$$:: $$The port on which to listen; 0 for the OS to choose a port.$$ *($$Integer$$, default: `$$$$`)* +$$reverse-lookup$$:: $$Perform a reverse DNS lookup on the remote IP Address; if false, just the IP address is included in the message headers.$$ *($$Boolean$$, default: `$$$$`)* +$$socket-timeout$$:: $$The timeout (ms) before closing the socket when no data is received.$$ *($$Integer$$, default: `$$$$`)* +$$use-direct-buffers$$:: $$Whether or not to use direct buffers.$$ *($$Boolean$$, default: `$$$$`)* === tcp.supplier -$$buffer-size$$:: $$The buffer size used when decoding messages; larger messages will be rejected.$$ *($$Integer$$, default: `$$2048$$`)* +$$buffer-size$$:: $$The buffer size used when decoding messages; larger messages will be rejected.$$ *($$Integer$$, default: `$$$$`)* $$decoder$$:: $$The decoder to use when receiving messages.$$ *($$Encoding$$, default: `$$$$`, possible values: `CRLF`,`LF`,`NULL`,`STXETX`,`RAW`,`L1`,`L2`,`L4`)* //end::configuration-properties[] diff --git a/applications/source/time-source/README.adoc b/applications/source/time-source/README.adoc index 824d079d..ffa08cf9 100644 --- a/applications/source/time-source/README.adoc +++ b/applications/source/time-source/README.adoc @@ -14,7 +14,7 @@ $$spring.integration.poller.fixed-rate$$:: $$Polling rate period. Mutually exclu $$spring.integration.poller.initial-delay$$:: $$Polling initial delay. Applied for 'fixedDelay' and 'fixedRate'; ignored for 'cron'.$$ *($$Duration$$, default: `$$$$`)* $$spring.integration.poller.max-messages-per-poll$$:: $$Maximum number of messages to poll per polling cycle.$$ *($$Integer$$, default: `$$$$`)* $$spring.integration.poller.receive-timeout$$:: $$How long to wait for messages on poll.$$ *($$Duration$$, default: `$$1s$$`)* -$$time.date-format$$:: $$Format for the date value.$$ *($$String$$, default: `$$MM/dd/yy HH:mm:ss$$`)* +$$time.date-format$$:: $$Format for the date value.$$ *($$String$$, default: `$$$$`)* //end::configuration-properties[] //end::ref-doc[] diff --git a/applications/source/twitter-message-source/README.adoc b/applications/source/twitter-message-source/README.adoc index c5e734be..84af985f 100644 --- a/applications/source/twitter-message-source/README.adoc +++ b/applications/source/twitter-message-source/README.adoc @@ -31,12 +31,12 @@ $$access-token$$:: $$Your Twitter token.$$ *($$String$$, default: `$$$$`)* $$access-token-secret$$:: $$Your Twitter token secret.$$ *($$String$$, default: `$$$$`)* $$consumer-key$$:: $$Your Twitter key.$$ *($$String$$, default: `$$$$`)* $$consumer-secret$$:: $$Your Twitter secret.$$ *($$String$$, default: `$$$$`)* -$$debug-enabled$$:: $$Enables Twitter4J debug mode.$$ *($$Boolean$$, default: `$$false$$`)* -$$raw-json$$:: $$Enable caching the original (raw) JSON objects as returned by the Twitter APIs. When set to False the result will use the Twitter4J's json representations. When set to True the result will use the original Twitter APISs json representations.$$ *($$Boolean$$, default: `$$true$$`)* +$$debug-enabled$$:: $$Enables Twitter4J debug mode.$$ *($$Boolean$$, default: `$$$$`)* +$$raw-json$$:: $$Enable caching the original (raw) JSON objects as returned by the Twitter APIs. When set to False the result will use the Twitter4J's json representations. When set to True the result will use the original Twitter APISs json representations.$$ *($$Boolean$$, default: `$$$$`)* === twitter.message.source -$$count$$:: $$Max number of events to be returned. 20 default. 50 max.$$ *($$Integer$$, default: `$$20$$`)* +$$count$$:: $$Max number of events to be returned. 20 default. 50 max.$$ *($$Integer$$, default: `$$$$`)* //end::configuration-properties[] //end::ref-doc[] diff --git a/applications/source/twitter-search-source/README.adoc b/applications/source/twitter-search-source/README.adoc index 306de4d2..f180b2e2 100644 --- a/applications/source/twitter-search-source/README.adoc +++ b/applications/source/twitter-search-source/README.adoc @@ -34,24 +34,24 @@ $$access-token$$:: $$Your Twitter token.$$ *($$String$$, default: `$$$$`)* $$access-token-secret$$:: $$Your Twitter token secret.$$ *($$String$$, default: `$$$$`)* $$consumer-key$$:: $$Your Twitter key.$$ *($$String$$, default: `$$$$`)* $$consumer-secret$$:: $$Your Twitter secret.$$ *($$String$$, default: `$$$$`)* -$$debug-enabled$$:: $$Enables Twitter4J debug mode.$$ *($$Boolean$$, default: `$$false$$`)* -$$raw-json$$:: $$Enable caching the original (raw) JSON objects as returned by the Twitter APIs. When set to False the result will use the Twitter4J's json representations. When set to True the result will use the original Twitter APISs json representations.$$ *($$Boolean$$, default: `$$true$$`)* +$$debug-enabled$$:: $$Enables Twitter4J debug mode.$$ *($$Boolean$$, default: `$$$$`)* +$$raw-json$$:: $$Enable caching the original (raw) JSON objects as returned by the Twitter APIs. When set to False the result will use the Twitter4J's json representations. When set to True the result will use the original Twitter APISs json representations.$$ *($$Boolean$$, default: `$$$$`)* === twitter.search -$$count$$:: $$Number of tweets to return per page (e.g. per single request), up to a max of 100.$$ *($$Integer$$, default: `$$100$$`)* +$$count$$:: $$Number of tweets to return per page (e.g. per single request), up to a max of 100.$$ *($$Integer$$, default: `$$$$`)* $$lang$$:: $$Restricts searched tweets to the given language, given by an http://en.wikipedia.org/wiki/ISO_639-1 .$$ *($$String$$, default: `$$$$`)* -$$page$$:: $$Number of pages (e.g. requests) to search backwards (from most recent to the oldest tweets) before start the search from the most recent tweets again. The total amount of tweets searched backwards is (page * count)$$ *($$Integer$$, default: `$$3$$`)* +$$page$$:: $$Number of pages (e.g. requests) to search backwards (from most recent to the oldest tweets) before start the search from the most recent tweets again. The total amount of tweets searched backwards is (page * count)$$ *($$Integer$$, default: `$$$$`)* $$query$$:: $$Search tweets by search query string.$$ *($$String$$, default: `$$$$`)* -$$restart-from-most-recent-on-empty-response$$:: $$Restart search from the most recent tweets on empty response. Applied only after the first restart (e.g. when since_id != UNBOUNDED)$$ *($$Boolean$$, default: `$$false$$`)* +$$restart-from-most-recent-on-empty-response$$:: $$Restart search from the most recent tweets on empty response. Applied only after the first restart (e.g. when since_id != UNBOUNDED)$$ *($$Boolean$$, default: `$$$$`)* $$result-type$$:: $$Specifies what type of search results you would prefer to receive. The current default is "mixed." Valid values include: mixed : Include both popular and real time results in the response. recent : return only the most recent results in the response popular : return only the most popular results in the response$$ *($$ResultType$$, default: `$$$$`, possible values: `popular`,`mixed`,`recent`)* $$since$$:: $$If specified, returns tweets with since the given date. Date should be formatted as YYYY-MM-DD.$$ *($$String$$, default: `$$$$`)* === twitter.search.geocode -$$latitude$$:: $$User's latitude.$$ *($$Double$$, default: `$$-1$$`)* -$$longitude$$:: $$User's longitude.$$ *($$Double$$, default: `$$-1$$`)* -$$radius$$:: $$Radius (in kilometers) around the (latitude, longitude) point.$$ *($$Double$$, default: `$$-1$$`)* +$$latitude$$:: $$User's latitude.$$ *($$Double$$, default: `$$$$`)* +$$longitude$$:: $$User's longitude.$$ *($$Double$$, default: `$$$$`)* +$$radius$$:: $$Radius (in kilometers) around the (latitude, longitude) point.$$ *($$Double$$, default: `$$$$`)* //end::configuration-properties[] //end::ref-doc[] diff --git a/applications/source/twitter-stream-source/README.adoc b/applications/source/twitter-stream-source/README.adoc index 6fb96b03..8d8d8417 100644 --- a/applications/source/twitter-stream-source/README.adoc +++ b/applications/source/twitter-stream-source/README.adoc @@ -25,12 +25,12 @@ $$access-token$$:: $$Your Twitter token.$$ *($$String$$, default: `$$$$`)* $$access-token-secret$$:: $$Your Twitter token secret.$$ *($$String$$, default: `$$$$`)* $$consumer-key$$:: $$Your Twitter key.$$ *($$String$$, default: `$$$$`)* $$consumer-secret$$:: $$Your Twitter secret.$$ *($$String$$, default: `$$$$`)* -$$debug-enabled$$:: $$Enables Twitter4J debug mode.$$ *($$Boolean$$, default: `$$false$$`)* -$$raw-json$$:: $$Enable caching the original (raw) JSON objects as returned by the Twitter APIs. When set to False the result will use the Twitter4J's json representations. When set to True the result will use the original Twitter APISs json representations.$$ *($$Boolean$$, default: `$$true$$`)* +$$debug-enabled$$:: $$Enables Twitter4J debug mode.$$ *($$Boolean$$, default: `$$$$`)* +$$raw-json$$:: $$Enable caching the original (raw) JSON objects as returned by the Twitter APIs. When set to False the result will use the Twitter4J's json representations. When set to True the result will use the original Twitter APISs json representations.$$ *($$Boolean$$, default: `$$$$`)* === twitter.stream.filter -$$count$$:: $$Indicates the number of previous statuses to stream before transitioning to the live stream.$$ *($$Integer$$, default: `$$0$$`)* +$$count$$:: $$Indicates the number of previous statuses to stream before transitioning to the live stream.$$ *($$Integer$$, default: `$$$$`)* $$filter-level$$:: $$The filter level limits what tweets appear in the stream to those with a minimum filterLevel attribute value. One of either none, low, or medium.$$ *($$FilterLevel$$, default: `$$$$`)* $$follow$$:: $$Specifies the users, by ID, to receive public tweets from.$$ *($$List$$, default: `$$$$`)* $$language$$:: $$Specifies the tweets language of the stream.$$ *($$List$$, default: `$$$$`)* diff --git a/applications/source/websocket-source/README.adoc b/applications/source/websocket-source/README.adoc index 3df4f069..a644428f 100644 --- a/applications/source/websocket-source/README.adoc +++ b/applications/source/websocket-source/README.adoc @@ -10,12 +10,12 @@ Properties grouped by prefix: === websocket.supplier -$$allowed-origins$$:: $$The allowed origins.$$ *($$String$$, default: `$$*$$`)* -$$path$$:: $$The path on which server WebSocket handler is exposed.$$ *($$String$$, default: `$$/websocket$$`)* +$$allowed-origins$$:: $$The allowed origins.$$ *($$String$$, default: `$$$$`)* +$$path$$:: $$The path on which server WebSocket handler is exposed.$$ *($$String$$, default: `$$$$`)* === websocket.supplier.sock-js -$$enable$$:: $$Enable SockJS service on the server. Default is 'false'$$ *($$Boolean$$, default: `$$false$$`)* +$$enable$$:: $$Enable SockJS service on the server. Default is 'false'$$ *($$Boolean$$, default: `$$$$`)* //end::configuration-properties[] == Examples diff --git a/applications/source/zeromq-source/README.adoc b/applications/source/zeromq-source/README.adoc index e63ea85a..7daa1bd2 100644 --- a/applications/source/zeromq-source/README.adoc +++ b/applications/source/zeromq-source/README.adoc @@ -18,11 +18,11 @@ N/A The **$$zeromq$$** $$source$$ has the following options: //tag::configuration-properties[] -$$zeromq.supplier.bind-port$$:: $$Bind Port for creating a ZeroMQ Socket; 0 selects a random port.$$ *($$Integer$$, default: `$$0$$`)* +$$zeromq.supplier.bind-port$$:: $$Bind Port for creating a ZeroMQ Socket; 0 selects a random port.$$ *($$Integer$$, default: `$$$$`)* $$zeromq.supplier.connect-url$$:: $$Connection URL for to the ZeroMQ Socket.$$ *($$String$$, default: `$$$$`)* -$$zeromq.supplier.consume-delay$$:: $$The delay to consume from the ZeroMQ Socket when no data received.$$ *($$Duration$$, default: `$$1s$$`)* +$$zeromq.supplier.consume-delay$$:: $$The delay to consume from the ZeroMQ Socket when no data received.$$ *($$Duration$$, default: `$$$$`)* $$zeromq.supplier.socket-type$$:: $$The Socket Type the connection should make.$$ *($$SocketType$$, default: `$$$$`, possible values: `PAIR`,`PUB`,`SUB`,`REQ`,`REP`,`DEALER`,`ROUTER`,`PULL`,`PUSH`,`XPUB`,`XSUB`,`STREAM`)* -$$zeromq.supplier.topics$$:: $$The Topics to subscribe to.$$ *($$String[]$$, default: `$$[]$$`)* +$$zeromq.supplier.topics$$:: $$The Topics to subscribe to.$$ *($$String[]$$, default: `$$$$`)* //end::configuration-properties[] Also see the https://docs.spring.io/spring-boot/docs/current/reference/html/common-application-properties.html[Spring Boot Documentation] diff --git a/applications/stream-applications-core/.settings.xml b/applications/stream-applications-core/.settings.xml index c77ffbe3..9f3eacf9 100644 --- a/applications/stream-applications-core/.settings.xml +++ b/applications/stream-applications-core/.settings.xml @@ -44,19 +44,6 @@ false - - - gemstone-release - GemStone Maven Release Repository - http://dist.gemstone.com/maven/release - - true - always - - diff --git a/applications/stream-applications-integration-tests/pom.xml b/applications/stream-applications-integration-tests/pom.xml index ccb861a6..765d7d61 100644 --- a/applications/stream-applications-integration-tests/pom.xml +++ b/applications/stream-applications-integration-tests/pom.xml @@ -74,17 +74,6 @@ function-test-support test - - org.springframework.data - spring-data-geode - - - org.apache.logging.log4j - log4j - - - test - com.amazonaws aws-java-sdk-s3 diff --git a/applications/stream-applications-integration-tests/src/test/java/org/springframework/cloud/stream/app/integration/test/source/geode/GeodeSourceTests.java b/applications/stream-applications-integration-tests/src/test/java/org/springframework/cloud/stream/app/integration/test/source/geode/GeodeSourceTests.java deleted file mode 100644 index 8bdf60be..00000000 --- a/applications/stream-applications-integration-tests/src/test/java/org/springframework/cloud/stream/app/integration/test/source/geode/GeodeSourceTests.java +++ /dev/null @@ -1,119 +0,0 @@ -/* - * Copyright 2020-2020 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.stream.app.integration.test.source.geode; - -import java.time.Duration; -import java.util.UUID; -import java.util.function.Consumer; - -import com.github.dockerjava.api.command.CreateContainerCmd; -import com.github.dockerjava.api.model.ExposedPort; -import com.github.dockerjava.api.model.HostConfig; -import com.github.dockerjava.api.model.PortBinding; -import com.github.dockerjava.api.model.Ports; -import org.apache.geode.cache.Region; -import org.apache.geode.cache.client.ClientCache; -import org.apache.geode.cache.client.ClientCacheFactory; -import org.apache.geode.cache.client.ClientRegionShortcut; -import org.junit.jupiter.api.AfterAll; -import org.junit.jupiter.api.BeforeAll; -import org.junit.jupiter.api.Tag; -import org.junit.jupiter.api.Test; -import org.junit.jupiter.api.extension.ExtendWith; -import org.testcontainers.containers.wait.strategy.Wait; -import org.testcontainers.images.builder.ImageFromDockerfile; -import org.testcontainers.junit.jupiter.Container; - -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.cloud.fn.test.support.geode.GeodeContainer; -import org.springframework.cloud.stream.app.test.integration.OutputMatcher; -import org.springframework.cloud.stream.app.test.integration.StreamAppContainer; -import org.springframework.cloud.stream.app.test.integration.StreamAppContainerTestUtils; -import org.springframework.cloud.stream.app.test.integration.junit.jupiter.BaseContainerExtension; - -import static org.awaitility.Awaitility.await; -import static org.springframework.cloud.stream.app.integration.test.common.Configuration.DEFAULT_DURATION; -@Tag("integration") -@ExtendWith(BaseContainerExtension.class) -abstract class GeodeSourceTests { - private static int locatorPort = StreamAppContainerTestUtils.findAvailablePort(); - - private static int cacheServerPort = StreamAppContainerTestUtils.findAvailablePort(); - - private static Region clientRegion; - - private static ClientCache clientCache; - - protected static StreamAppContainer source; - - @Autowired - private OutputMatcher outputMatcher; - - @Container - private static final GeodeContainer geode = (GeodeContainer) new GeodeContainer(new ImageFromDockerfile() - .withFileFromClasspath("Dockerfile", "geode-test/Dockerfile") - .withBuildArg("CACHE_SERVER_PORT", String.valueOf(cacheServerPort)) - .withBuildArg("LOCATOR_PORT", String.valueOf(locatorPort)), - locatorPort, cacheServerPort) - .withCreateContainerCmdModifier( - (Consumer) createContainerCmd -> createContainerCmd - .withHostName("geode").withHostConfig(new HostConfig().withPortBindings( - new PortBinding(Ports.Binding.bindPort(cacheServerPort), - new ExposedPort(cacheServerPort)), - new PortBinding(Ports.Binding.bindPort(locatorPort), - new ExposedPort(locatorPort))))) - .withCommand("tail", "-f", "/dev/null") - .withStartupTimeout(DEFAULT_DURATION.multipliedBy(2)); - - @BeforeAll - static void initializeGeodeCacheThenStartSource() { - // Not using locator is faster. - System.out.println(geode.execGfsh( - "start server --name=Server1 " + "--hostname-for-clients=geode" + " --server-port=" - + cacheServerPort + " --J=-Dgemfire.jmx-manager=true --J=-Dgemfire.jmx-manager-start=true") - .getStdout()); - System.out.println(geode.execGfsh("connect --jmx-manager=localhost[1099]", - "create region --name=myRegion --type=REPLICATE").getStdout()); - clientCache = new ClientCacheFactory().addPoolServer("localhost", cacheServerPort) - .create(); - clientCache.readyForEvents(); - clientRegion = clientCache - .createClientRegionFactory(ClientRegionShortcut.PROXY) - .create("myRegion"); - - source = BaseContainerExtension.containerInstance().withEnv("GEODE_POOL_CONNECT_TYPE", "server") - .withEnv("GEODE_REGION_REGION_NAME", "myRegion") - .withEnv("GEODE_POOL_HOST_ADDRESSES", - StreamAppContainerTestUtils.localHostAddress() + ":" + cacheServerPort) - .waitingFor(Wait.forLogMessage(".*Started GeodeSource.*", 1)); - source.start(); - } - - @Test - void test() throws InterruptedException { - String random = UUID.randomUUID().toString(); - clientRegion.put(random, random); - await().atMost(Duration.ofSeconds(30)) - .until(outputMatcher.payloadMatches((String s) -> s.contains(random))); - } - - @AfterAll - static void cleanup() { - source.stop(); - clientCache.close(); - } -} diff --git a/applications/stream-applications-integration-tests/src/test/java/org/springframework/cloud/stream/app/integration/test/source/geode/KafkaGeodeSourceTests.java b/applications/stream-applications-integration-tests/src/test/java/org/springframework/cloud/stream/app/integration/test/source/geode/KafkaGeodeSourceTests.java deleted file mode 100644 index 75a2c3e5..00000000 --- a/applications/stream-applications-integration-tests/src/test/java/org/springframework/cloud/stream/app/integration/test/source/geode/KafkaGeodeSourceTests.java +++ /dev/null @@ -1,26 +0,0 @@ -/* - * Copyright 2020-2020 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.stream.app.integration.test.source.geode; - -import org.springframework.cloud.stream.app.integration.test.common.Configuration; -import org.springframework.cloud.stream.app.test.integration.junit.jupiter.KafkaBaseContainer; -import org.springframework.cloud.stream.app.test.integration.junit.jupiter.KafkaStreamAppTest; - -@KafkaStreamAppTest -@KafkaBaseContainer(name = "geode-source-kafka", versionSupplier = Configuration.VersionSupplier.class) -public class KafkaGeodeSourceTests extends GeodeSourceTests { -} diff --git a/applications/stream-applications-integration-tests/src/test/java/org/springframework/cloud/stream/app/integration/test/source/geode/RabbitMQGeodeSourceTests.java b/applications/stream-applications-integration-tests/src/test/java/org/springframework/cloud/stream/app/integration/test/source/geode/RabbitMQGeodeSourceTests.java deleted file mode 100644 index ea465837..00000000 --- a/applications/stream-applications-integration-tests/src/test/java/org/springframework/cloud/stream/app/integration/test/source/geode/RabbitMQGeodeSourceTests.java +++ /dev/null @@ -1,26 +0,0 @@ -/* - * Copyright 2020-2020 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.stream.app.integration.test.source.geode; - -import org.springframework.cloud.stream.app.integration.test.common.Configuration; -import org.springframework.cloud.stream.app.test.integration.junit.jupiter.RabbitMQBaseContainer; -import org.springframework.cloud.stream.app.test.integration.junit.jupiter.RabbitMQStreamAppTest; - -@RabbitMQStreamAppTest -@RabbitMQBaseContainer(name = "geode-source-rabbit", versionSupplier = Configuration.VersionSupplier.class) -public class RabbitMQGeodeSourceTests extends GeodeSourceTests { -} diff --git a/functions/common/function-test-support/src/main/java/org/springframework/cloud/fn/test/support/geode/GeodeContainer.java b/functions/common/function-test-support/src/main/java/org/springframework/cloud/fn/test/support/geode/GeodeContainer.java deleted file mode 100644 index b00ff406..00000000 --- a/functions/common/function-test-support/src/main/java/org/springframework/cloud/fn/test/support/geode/GeodeContainer.java +++ /dev/null @@ -1,197 +0,0 @@ -/* - * Copyright 2020-2020 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.test.support.geode; - -import java.io.IOException; -import java.util.ArrayList; -import java.util.Arrays; -import java.util.LinkedList; -import java.util.List; -import java.util.concurrent.Future; - -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; -import org.testcontainers.containers.GenericContainer; - -import org.springframework.lang.NonNull; -import org.springframework.util.Assert; -import org.springframework.util.StringUtils; - -/** - * A Test Container that starts a Geode Locator and Server on configured ports. This also - * provides methods for executing one or more Gfsh commands. - */ -public class GeodeContainer extends GenericContainer { - private static Logger logger = LoggerFactory.getLogger(GeodeContainer.class); - - private final int locatorPort; - - private final int cacheServerPort; - - private final boolean useLocator; - - /** - * Create a Geode container from a Docker image. - * @param dockerImageName the name of the image. - * @param locatorPort the locator port. - * @param cacheServerPort the cache server port. - * @param useLocator set to use a locator. - */ - public GeodeContainer(@NonNull String dockerImageName, int locatorPort, int cacheServerPort, boolean useLocator) { - super(dockerImageName); - this.locatorPort = locatorPort; - this.cacheServerPort = cacheServerPort; - this.useLocator = useLocator; - } - - public GeodeContainer(@NonNull String dockerImageName, int locatorPort, int cacheServerPort) { - this(dockerImageName, locatorPort, cacheServerPort, false); - } - - /** - * Create a Geode Container from a {@code Future}. Test containers provides some - * implementations as image builders, such as - * {@link org.testcontainers.images.builder.ImageFromDockerfile}. - * @param image the image builder. - * @param locatorPort the locator port. - * @param cacheServerPort the server port. - * @param useLocator set to use a locator. - */ - public GeodeContainer(@NonNull Future image, int locatorPort, int cacheServerPort, boolean useLocator) { - super(image); - this.locatorPort = locatorPort; - this.cacheServerPort = cacheServerPort; - this.useLocator = useLocator; - } - - public GeodeContainer(@NonNull Future image, int locatorPort, int cacheServerPort) { - this(image, locatorPort, cacheServerPort, false); - } - - /** - * A convenience method to connect to a locator with Gfsh. - * @return the connect command String. - */ - public String connect() { - return useLocator ? "connect --locator=" + locators() : "connect --jmx-manager=localhost[1099]"; - } - - /** - * Get the locator port. - * @return the locator port. - */ - public int getLocatorPort() { - return locatorPort; - } - - /** - * Get the cache server port. - * @return the cache server port. - */ - public int getCacheServerPort() { - return cacheServerPort; - } - - /** - * - * @return Geode locators as host[port],... - */ - public String locators() { - return "localhost[" + locatorPort + "]"; - } - - /** - * Invoke the `gfsh` shell, Connect to the locator and execute the commands. - * @param command a list of commands to execute in a single `gfsh` invocation. - * @return the {@link org.testcontainers.containers.Container.ExecResult} - */ - public ExecResult connectAndExecGfsh(String... command) { - ArrayList args = new ArrayList<>(Arrays.asList(command)); - args.add(0, connect()); - return execInContainer(Gfsh.command(args.toArray(new String[args.size()])).commandParts()); - } - - /** - * Invoke the `gfsh` shell, and execute the commands. - * @param command a list of commands to execute in a single `gfsh` invocation. - * @return the {@link org.testcontainers.containers.Container.ExecResult} - */ - public ExecResult execGfsh(String... command) { - return execInContainer(Gfsh.command(command).commandParts()); - } - - /** - * Executes a command in the container, logging stdout and stderr and wrapping checked - * exceptions. - * @see GenericContainer#execInContainer(String...) - * @param command the command to execute. - * @return the {@link org.testcontainers.containers.Container.ExecResult} - */ - @Override - public ExecResult execInContainer(String... command) { - try { - ExecResult execResult = super.execInContainer(command); - logger.debug("stdout: {}", execResult.getStdout()); - if (execResult.getExitCode() != 0) { - logger.warn("stdout: {}", execResult.getStdout()); - logger.warn("stderr: {}", execResult.getStderr()); - } - return execResult; - } - catch (IOException e) { - throw new RuntimeException(e.getMessage(), e); - } - catch (InterruptedException e) { - throw new RuntimeException(e.getMessage(), e); - } - } - - /** - * Builds a Gfsh command. - */ - public final static class Gfsh { - - public static Command command(String... gfshCommands) { - return new Command(gfshCommands); - } - - public final static class Command { - private final List commandParts = new LinkedList<>(); - - private Command(String... gfshCommands) { - Assert.notEmpty(gfshCommands, "at least one command is required"); - for (String gfshCommand : gfshCommands) { - Assert.hasText(gfshCommand, "command must contain text"); - if (commandParts.size() == 0) { - commandParts.add("gfsh"); - } - commandParts.add("-e"); - commandParts.add(gfshCommand); - } - } - - public String[] commandParts() { - return commandParts.toArray(new String[commandParts.size()]); - } - - public String toString() { - return StringUtils.collectionToDelimitedString(commandParts, ","); - } - } - } - -} diff --git a/functions/common/function-test-support/src/main/java/org/springframework/cloud/fn/test/support/geode/GeodeContainerIntializer.java b/functions/common/function-test-support/src/main/java/org/springframework/cloud/fn/test/support/geode/GeodeContainerIntializer.java deleted file mode 100644 index 6186c119..00000000 --- a/functions/common/function-test-support/src/main/java/org/springframework/cloud/fn/test/support/geode/GeodeContainerIntializer.java +++ /dev/null @@ -1,112 +0,0 @@ -/* - * Copyright 2020-2020 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.test.support.geode; - -import java.util.Optional; -import java.util.function.Consumer; - -import com.github.dockerjava.api.command.CreateContainerCmd; -import com.github.dockerjava.api.model.ExposedPort; -import com.github.dockerjava.api.model.HostConfig; -import com.github.dockerjava.api.model.PortBinding; -import com.github.dockerjava.api.model.Ports; -import org.testcontainers.images.builder.ImageFromDockerfile; - -/** - * Creates and starts a {@link GeodeContainer} using available random ports for locator - * and server. Runs a {@code Consumer} post processor if provided. - * @author David Turanski - */ -public class GeodeContainerIntializer { - - private int locatorPort; - - private int cacheServerPort; - - private GeodeContainer geode; - - private Optional> postProcessor; - - private final boolean useLocator; - - /** - * Create, start, and perform post processing on a {@link GeodeContainer}. - * @param postProcessor a {@code Consumer} to run after the container is - * started. - */ - public GeodeContainerIntializer(Consumer postProcessor) { - this(postProcessor, false); - } - - public GeodeContainerIntializer(Consumer postProcessor, boolean useLocator) { - this.useLocator = useLocator; - - cacheServerPort = SocketUtils.findAvailableTcpPort(); - - locatorPort = SocketUtils.findAvailableTcpPort(); - - this.postProcessor = Optional.ofNullable(postProcessor); - - geode = new GeodeContainer(new ImageFromDockerfile() - .withFileFromClasspath("Dockerfile", "geode/Dockerfile") - .withBuildArg("CACHE_SERVER_PORT", String.valueOf(cacheServerPort)) - .withBuildArg("LOCATOR_PORT", String.valueOf(locatorPort)), - locatorPort, cacheServerPort, useLocator); - startContainer(); - } - - /** - * Create and start a {@link GeodeContainer}. - */ - public GeodeContainerIntializer() { - this(null, false); - } - - private void startContainer() { - // There is apparently no way to initialize Geode with random port mapping. Ports - // must be the same on client and server. - Consumer cmd = e -> { - e.withHostConfig(new HostConfig().withPortBindings( - new PortBinding(Ports.Binding.bindPort(cacheServerPort), new ExposedPort(cacheServerPort)), - new PortBinding(Ports.Binding.bindPort(locatorPort), new ExposedPort(locatorPort)))); - }; - - // Wait forever - - geode.withCommand("tail", "-f", "/dev/null").withCreateContainerCmdModifier(cmd).start(); - - if (useLocator) { - geode.execGfsh("start locator --name=Locator1 --hostname-for-clients=localhost --port=" + locatorPort); - geode.execGfsh(geode.connect(), - "start server --name=Server1 --hostname-for-clients=localhost --server-port=" + cacheServerPort); - } - else { - geode.execGfsh( - "start server --name=Server1 --hostname-for-clients=localhost --server-port=" + cacheServerPort + - " --J=-Dgemfire.jmx-manager=true --J=-Dgemfire.jmx-manager-start=true"); - } - postProcessor.ifPresent(geodeContainerConsumer -> geodeContainerConsumer.accept(geode)); - } - - /** - * @return the {@link GeodeContainer} instance. - */ - public GeodeContainer geodeContainer() { - return geode; - } - -} diff --git a/functions/common/function-test-support/src/main/java/org/springframework/cloud/fn/test/support/geode/SocketUtils.java b/functions/common/function-test-support/src/main/java/org/springframework/cloud/fn/test/support/geode/SocketUtils.java deleted file mode 100644 index 7c83b76d..00000000 --- a/functions/common/function-test-support/src/main/java/org/springframework/cloud/fn/test/support/geode/SocketUtils.java +++ /dev/null @@ -1,302 +0,0 @@ -/* - * Copyright 2002-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.test.support.geode; - -import java.net.DatagramSocket; -import java.net.InetAddress; -import java.net.ServerSocket; -import java.util.Random; -import java.util.SortedSet; -import java.util.TreeSet; - -import javax.net.ServerSocketFactory; - -import org.springframework.util.Assert; - -/** - * Simple utility methods for working with network sockets — for example, - * for finding available ports on {@code localhost}. - * - *

Within this class, a TCP port refers to a port for a {@link ServerSocket}; - * whereas, a UDP port refers to a port for a {@link DatagramSocket}. - * - *

{@code SocketUtils} was introduced in Spring Framework 4.0, primarily to - * assist in writing integration tests which start an external server on an - * available random port. However, these utilities make no guarantee about the - * subsequent availability of a given port and are therefore unreliable. Instead - * of using {@code SocketUtils} to find an available local port for a server, it - * is recommended that you rely on a server's ability to start on a random port - * that it selects or is assigned by the operating system. To interact with that - * server, you should query the server for the port it is currently using. - * - * @author Sam Brannen - * @author Ben Hale - * @author Arjen Poutsma - * @author Gunnar Hillert - * @author Gary Russell - * @since 4.0 - * @deprecated as of Spring Framework 5.3.16, to be removed in 6.0; see - * {@link SocketUtils class-level Javadoc} for details. - */ -@Deprecated -public final class SocketUtils { - - /** - * The default minimum value for port ranges used when finding an available - * socket port. - */ - public static final int PORT_RANGE_MIN = 1024; - - /** - * The default maximum value for port ranges used when finding an available - * socket port. - */ - public static final int PORT_RANGE_MAX = 65535; - - private static final Random random = new Random(System.nanoTime()); - - private SocketUtils() { - } - - /** - * Find an available TCP port randomly selected from the range - * [{@value #PORT_RANGE_MIN}, {@value #PORT_RANGE_MAX}]. - * @return an available TCP port number - * @throws IllegalStateException if no available port could be found - */ - public static int findAvailableTcpPort() { - return findAvailableTcpPort(PORT_RANGE_MIN); - } - - /** - * Find an available TCP port randomly selected from the range - * [{@code minPort}, {@value #PORT_RANGE_MAX}]. - * @param minPort the minimum port number - * @return an available TCP port number - * @throws IllegalStateException if no available port could be found - */ - public static int findAvailableTcpPort(int minPort) { - return findAvailableTcpPort(minPort, PORT_RANGE_MAX); - } - - /** - * Find an available TCP port randomly selected from the range - * [{@code minPort}, {@code maxPort}]. - * @param minPort the minimum port number - * @param maxPort the maximum port number - * @return an available TCP port number - * @throws IllegalStateException if no available port could be found - */ - public static int findAvailableTcpPort(int minPort, int maxPort) { - return SocketType.TCP.findAvailablePort(minPort, maxPort); - } - - /** - * Find the requested number of available TCP ports, each randomly selected - * from the range [{@value #PORT_RANGE_MIN}, {@value #PORT_RANGE_MAX}]. - * @param numRequested the number of available ports to find - * @return a sorted set of available TCP port numbers - * @throws IllegalStateException if the requested number of available ports could not be found - */ - public static SortedSet findAvailableTcpPorts(int numRequested) { - return findAvailableTcpPorts(numRequested, PORT_RANGE_MIN, PORT_RANGE_MAX); - } - - /** - * Find the requested number of available TCP ports, each randomly selected - * from the range [{@code minPort}, {@code maxPort}]. - * @param numRequested the number of available ports to find - * @param minPort the minimum port number - * @param maxPort the maximum port number - * @return a sorted set of available TCP port numbers - * @throws IllegalStateException if the requested number of available ports could not be found - */ - public static SortedSet findAvailableTcpPorts(int numRequested, int minPort, int maxPort) { - return SocketType.TCP.findAvailablePorts(numRequested, minPort, maxPort); - } - - /** - * Find an available UDP port randomly selected from the range - * [{@value #PORT_RANGE_MIN}, {@value #PORT_RANGE_MAX}]. - * @return an available UDP port number - * @throws IllegalStateException if no available port could be found - */ - public static int findAvailableUdpPort() { - return findAvailableUdpPort(PORT_RANGE_MIN); - } - - /** - * Find an available UDP port randomly selected from the range - * [{@code minPort}, {@value #PORT_RANGE_MAX}]. - * @param minPort the minimum port number - * @return an available UDP port number - * @throws IllegalStateException if no available port could be found - */ - public static int findAvailableUdpPort(int minPort) { - return findAvailableUdpPort(minPort, PORT_RANGE_MAX); - } - - /** - * Find an available UDP port randomly selected from the range - * [{@code minPort}, {@code maxPort}]. - * @param minPort the minimum port number - * @param maxPort the maximum port number - * @return an available UDP port number - * @throws IllegalStateException if no available port could be found - */ - public static int findAvailableUdpPort(int minPort, int maxPort) { - return SocketType.UDP.findAvailablePort(minPort, maxPort); - } - - /** - * Find the requested number of available UDP ports, each randomly selected - * from the range [{@value #PORT_RANGE_MIN}, {@value #PORT_RANGE_MAX}]. - * @param numRequested the number of available ports to find - * @return a sorted set of available UDP port numbers - * @throws IllegalStateException if the requested number of available ports could not be found - */ - public static SortedSet findAvailableUdpPorts(int numRequested) { - return findAvailableUdpPorts(numRequested, PORT_RANGE_MIN, PORT_RANGE_MAX); - } - - /** - * Find the requested number of available UDP ports, each randomly selected - * from the range [{@code minPort}, {@code maxPort}]. - * @param numRequested the number of available ports to find - * @param minPort the minimum port number - * @param maxPort the maximum port number - * @return a sorted set of available UDP port numbers - * @throws IllegalStateException if the requested number of available ports could not be found - */ - public static SortedSet findAvailableUdpPorts(int numRequested, int minPort, int maxPort) { - return SocketType.UDP.findAvailablePorts(numRequested, minPort, maxPort); - } - - - private enum SocketType { - - TCP { - @Override - protected boolean isPortAvailable(int port) { - try { - ServerSocket serverSocket = ServerSocketFactory.getDefault().createServerSocket( - port, 1, InetAddress.getByName("localhost")); - serverSocket.close(); - return true; - } - catch (Exception ex) { - return false; - } - } - }, - - UDP { - @Override - protected boolean isPortAvailable(int port) { - try { - DatagramSocket socket = new DatagramSocket(port, InetAddress.getByName("localhost")); - socket.close(); - return true; - } - catch (Exception ex) { - return false; - } - } - }; - - /** - * Determine if the specified port for this {@code SocketType} is - * currently available on {@code localhost}. - */ - protected abstract boolean isPortAvailable(int port); - - /** - * Find a pseudo-random port number within the range - * [{@code minPort}, {@code maxPort}]. - * @param minPort the minimum port number - * @param maxPort the maximum port number - * @return a random port number within the specified range - */ - private int findRandomPort(int minPort, int maxPort) { - int portRange = maxPort - minPort; - return minPort + random.nextInt(portRange + 1); - } - - /** - * Find an available port for this {@code SocketType}, randomly selected - * from the range [{@code minPort}, {@code maxPort}]. - * @param minPort the minimum port number - * @param maxPort the maximum port number - * @return an available port number for this socket type - * @throws IllegalStateException if no available port could be found - */ - int findAvailablePort(int minPort, int maxPort) { - Assert.isTrue(minPort > 0, "'minPort' must be greater than 0"); - Assert.isTrue(maxPort >= minPort, "'maxPort' must be greater than or equal to 'minPort'"); - Assert.isTrue(maxPort <= PORT_RANGE_MAX, "'maxPort' must be less than or equal to " + PORT_RANGE_MAX); - - int portRange = maxPort - minPort; - int candidatePort; - int searchCounter = 0; - do { - if (searchCounter > portRange) { - throw new IllegalStateException(String.format( - "Could not find an available %s port in the range [%d, %d] after %d attempts", - name(), minPort, maxPort, searchCounter)); - } - candidatePort = findRandomPort(minPort, maxPort); - searchCounter++; - } - while (!isPortAvailable(candidatePort)); - - return candidatePort; - } - - /** - * Find the requested number of available ports for this {@code SocketType}, - * each randomly selected from the range [{@code minPort}, {@code maxPort}]. - * @param numRequested the number of available ports to find - * @param minPort the minimum port number - * @param maxPort the maximum port number - * @return a sorted set of available port numbers for this socket type - * @throws IllegalStateException if the requested number of available ports could not be found - */ - SortedSet findAvailablePorts(int numRequested, int minPort, int maxPort) { - Assert.isTrue(minPort > 0, "'minPort' must be greater than 0"); - Assert.isTrue(maxPort > minPort, "'maxPort' must be greater than 'minPort'"); - Assert.isTrue(maxPort <= PORT_RANGE_MAX, "'maxPort' must be less than or equal to " + PORT_RANGE_MAX); - Assert.isTrue(numRequested > 0, "'numRequested' must be greater than 0"); - Assert.isTrue((maxPort - minPort) >= numRequested, - "'numRequested' must not be greater than 'maxPort' - 'minPort'"); - - SortedSet availablePorts = new TreeSet<>(); - int attemptCount = 0; - while ((++attemptCount <= numRequested + 100) && availablePorts.size() < numRequested) { - availablePorts.add(findAvailablePort(minPort, maxPort)); - } - - if (availablePorts.size() != numRequested) { - throw new IllegalStateException(String.format( - "Could not find %d available %s ports in the range [%d, %d]", - numRequested, name(), minPort, maxPort)); - } - - return availablePorts; - } - } - -} diff --git a/functions/common/geode-common/pom.xml b/functions/common/geode-common/pom.xml deleted file mode 100644 index ea83d16a..00000000 --- a/functions/common/geode-common/pom.xml +++ /dev/null @@ -1,32 +0,0 @@ - - - 4.0.0 - - - org.springframework.cloud.fn - spring-functions-parent - 4.0.0-SNAPSHOT - ../../spring-functions-parent/pom.xml - - - geode-common - geode-common - Geode Common Components - - - 20200518 - - - - - org.springframework.data - spring-data-geode - - - org.json - json - ${org-json.version} - - - - diff --git a/functions/common/geode-common/src/main/java/org/springframework/cloud/fn/common/geode/GeodeClientCacheConfiguration.java b/functions/common/geode-common/src/main/java/org/springframework/cloud/fn/common/geode/GeodeClientCacheConfiguration.java deleted file mode 100644 index b64035c9..00000000 --- a/functions/common/geode-common/src/main/java/org/springframework/cloud/fn/common/geode/GeodeClientCacheConfiguration.java +++ /dev/null @@ -1,147 +0,0 @@ -/* - * Copyright 2016-2020 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.geode; - -import java.io.File; -import java.io.FileOutputStream; -import java.io.IOException; -import java.net.InetSocketAddress; -import java.util.Properties; - -import org.apache.geode.cache.client.ClientCache; -import org.apache.geode.cache.client.ClientCacheFactory; -import org.apache.geode.pdx.ReflectionBasedAutoSerializer; - -import org.springframework.boot.context.properties.EnableConfigurationProperties; -import org.springframework.context.annotation.Bean; -import org.springframework.context.annotation.Import; -import org.springframework.core.io.Resource; -import org.springframework.data.gemfire.util.PropertiesBuilder; -import org.springframework.util.FileCopyUtils; -import org.springframework.util.StringUtils; - -/** - * @author David Turanski - * @author Christian Tzolov - */ -@EnableConfigurationProperties({ GeodeClientCacheProperties.class, GeodeSecurityProperties.class, - GeodeSslProperties.class, GeodePoolProperties.class }) -@Import(InetSocketAddressConverterConfiguration.class) -public class GeodeClientCacheConfiguration { - - private static final String SECURITY_CLIENT = "security-client-auth-init"; - - private static final String SECURITY_USERNAME = "security-username"; - - private static final String SECURITY_PASSWORD = "security-password"; - - @Bean - public ClientCache clientCache(GeodeClientCacheProperties clientCacheProperties, - GeodeSecurityProperties securityProperties, GeodeSslProperties sslProperties, - GeodePoolProperties geodePoolProperties) { - - Properties properties = new Properties(); - PropertiesBuilder pb = new PropertiesBuilder(); - if (StringUtils.hasText(securityProperties.getUsername()) - && StringUtils.hasText(securityProperties.getPassword())) { - - properties - .setProperty(SECURITY_CLIENT, - GeodeSecurityProperties.UserAuthInitialize.class.getName() + ".create"); - properties.setProperty(SECURITY_USERNAME, securityProperties.getUsername()); - properties.setProperty(SECURITY_PASSWORD, securityProperties.getPassword()); - - } - - if (sslProperties.isSslEnabled()) { - pb.add(properties); - pb.add(this.toGeodeSslProperties(sslProperties)); - } - - ClientCacheFactory clientCacheFactory = new ClientCacheFactory(pb.build()); - - if (clientCacheProperties.isPdxReadSerialized()) { - clientCacheFactory.setPdxSerializer(new ReflectionBasedAutoSerializer(".*")); - clientCacheFactory.setPdxReadSerialized(true); - } - - if (geodePoolProperties.getConnectType().equals(GeodePoolProperties.ConnectType.locator)) { - for (InetSocketAddress address : geodePoolProperties.getHostAddresses()) { - clientCacheFactory.addPoolLocator(address.getHostName(), address.getPort()); - } - } - else { - for (InetSocketAddress address : geodePoolProperties.getHostAddresses()) { - clientCacheFactory.addPoolServer(address.getHostName(), address.getPort()); - } - } - - clientCacheFactory.setPoolSubscriptionEnabled(geodePoolProperties.isSubscriptionEnabled()); - ClientCache clientCache = clientCacheFactory.create(); - clientCache.readyForEvents(); - return clientCache; - } - - /** - * Converts the App Starter properties into Geode native SSL properties. - * @param sslProperties App starter properties. - * @return Returns the geode native SSL properties. - */ - private Properties toGeodeSslProperties(GeodeSslProperties sslProperties) { - - PropertiesBuilder pb = new PropertiesBuilder(); - - // locator - SSL communication with and between locators - // server - SSL communication between clients and servers - pb.setProperty("ssl-enabled-components", "server,locator"); - - pb.setProperty("ssl-keystore", this.resolveRemoteStore(sslProperties.getKeystoreUri(), - sslProperties.getUserHomeDirectory(), GeodeSslProperties.LOCAL_KEYSTORE_FILE_NAME)); - pb.setProperty("ssl-keystore-password", sslProperties.getSslKeystorePassword()); - pb.setProperty("ssl-keystore-type", sslProperties.getKeystoreType()); - - pb.setProperty("ssl-truststore", this.resolveRemoteStore(sslProperties.getTruststoreUri(), - sslProperties.getUserHomeDirectory(), GeodeSslProperties.LOCAL_TRUSTSTORE_FILE_NAME)); - pb.setProperty("ssl-truststore-password", sslProperties.getSslTruststorePassword()); - pb.setProperty("ssl-truststore-type", sslProperties.getTruststoreType()); - - pb.setProperty("ssl-ciphers", sslProperties.getCiphers()); - - return pb.build(); - } - - /** - * Copy the Trust store specified in the URI into a local accessible file. - * - * @param storeUri Either Keystore or Truststore remote resource URI - * @param userHomeDirectory local root directory to store the keystore and localsore files - * @param localStoreFileName local keystore or truststore file name - * @return Returns the absolute path of the local trust or keys store file copy - */ - private String resolveRemoteStore(Resource storeUri, String userHomeDirectory, String localStoreFileName) { - - File localStoreFile = new File(userHomeDirectory, localStoreFileName); - try { - FileCopyUtils.copy(storeUri.getInputStream(), new FileOutputStream(localStoreFile)); - return localStoreFile.getAbsolutePath(); - } - catch (IOException e) { - throw new IllegalStateException(String.format("Failed to copy the store from [%s] into %s", - storeUri.getDescription(), localStoreFile.getAbsolutePath()), e); - } - } -} diff --git a/functions/common/geode-common/src/main/java/org/springframework/cloud/fn/common/geode/GeodeClientCacheProperties.java b/functions/common/geode-common/src/main/java/org/springframework/cloud/fn/common/geode/GeodeClientCacheProperties.java deleted file mode 100644 index 9a36c63b..00000000 --- a/functions/common/geode-common/src/main/java/org/springframework/cloud/fn/common/geode/GeodeClientCacheProperties.java +++ /dev/null @@ -1,43 +0,0 @@ -/* - * Copyright 2019-2020 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.geode; - -import org.springframework.boot.context.properties.ConfigurationProperties; -import org.springframework.validation.annotation.Validated; - -/** - * Geode client pool configuration properties. - * - * @author Christian Tzolov - */ -@ConfigurationProperties("geode.client") -@Validated -public class GeodeClientCacheProperties { - - /** - * Deserialize the Geode objects into PdxInstance instead of the domain class. - */ - private boolean pdxReadSerialized = false; - - public boolean isPdxReadSerialized() { - return pdxReadSerialized; - } - - public void setPdxReadSerialized(boolean pdxReadSerialized) { - this.pdxReadSerialized = pdxReadSerialized; - } -} diff --git a/functions/common/geode-common/src/main/java/org/springframework/cloud/fn/common/geode/GeodeClientRegionConfiguration.java b/functions/common/geode-common/src/main/java/org/springframework/cloud/fn/common/geode/GeodeClientRegionConfiguration.java deleted file mode 100644 index 879f24ac..00000000 --- a/functions/common/geode-common/src/main/java/org/springframework/cloud/fn/common/geode/GeodeClientRegionConfiguration.java +++ /dev/null @@ -1,68 +0,0 @@ -/* - * Copyright 2015-2020 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.geode; - -import java.util.List; - -import org.apache.geode.cache.DataPolicy; -import org.apache.geode.cache.client.ClientCache; - -import org.springframework.beans.factory.BeanCreationException; -import org.springframework.boot.context.properties.EnableConfigurationProperties; -import org.springframework.context.annotation.Bean; -import org.springframework.context.annotation.Configuration; -import org.springframework.context.annotation.Import; -import org.springframework.data.gemfire.client.ClientRegionFactoryBean; -import org.springframework.data.gemfire.client.Interest; -import org.springframework.lang.Nullable; -import org.springframework.util.CollectionUtils; - -/** - * Client region configuration common to Geode functions. This configures the - * 'regionName', 'spring.application.name' by default and injects the pool. Also, any - * beans of type {@link Interest} will be registered to the client region to control which - * keys will be automatically synced to the client. At least one of these is required for - * Geode Suppliers. - * - * @author David Turanski - */ -@Configuration -@Import(GeodeClientCacheConfiguration.class) -@EnableConfigurationProperties(GeodeRegionProperties.class) -public class GeodeClientRegionConfiguration { - - @Bean(name = "clientRegion") - @SuppressWarnings({ "rawtype", "unchecked" }) - public ClientRegionFactoryBean clientRegionFactoryBean(ClientCache clientCache, - @Nullable List keyInterests, GeodeRegionProperties properties) { - ClientRegionFactoryBean clientRegionFactoryBean = new ClientRegionFactoryBean(); - clientRegionFactoryBean.setRegionName(properties.getRegionName()); - clientRegionFactoryBean.setDataPolicy(DataPolicy.EMPTY); - if (!CollectionUtils.isEmpty(keyInterests)) { - clientRegionFactoryBean.setInterests(keyInterests.toArray(new Interest[keyInterests.size()])); - } - - try { - clientRegionFactoryBean.setCache(clientCache); - } - catch (Exception e) { - throw new BeanCreationException(e.getMessage(), e); - } - return clientRegionFactoryBean; - } - -} diff --git a/functions/common/geode-common/src/main/java/org/springframework/cloud/fn/common/geode/GeodePoolProperties.java b/functions/common/geode-common/src/main/java/org/springframework/cloud/fn/common/geode/GeodePoolProperties.java deleted file mode 100644 index a1b2be03..00000000 --- a/functions/common/geode-common/src/main/java/org/springframework/cloud/fn/common/geode/GeodePoolProperties.java +++ /dev/null @@ -1,90 +0,0 @@ -/* - * Copyright 2015-2020 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.geode; - -import java.net.InetSocketAddress; - -import jakarta.validation.constraints.NotEmpty; - -import org.springframework.boot.context.properties.ConfigurationProperties; -import org.springframework.validation.annotation.Validated; - -/** - * Geode client pool configuration properties. - * - * @author David Turanski - */ -@ConfigurationProperties("geode.pool") -@Validated -public class GeodePoolProperties { - - /** - * Connection Type locator or server. - */ - public enum ConnectType { - /** - * use locator. - */ - locator, - /** - * use server. - */ - server - } - - /** - * Specifies one or more Gemfire locator or server addresses formatted as [host]:[port]. - */ - private InetSocketAddress[] hostAddresses = { new InetSocketAddress("localhost", 10334) }; - - /** - * Specifies connection type: 'server' or 'locator'. - */ - private ConnectType connectType = ConnectType.locator; - - /** - * Set to true to enable subscriptions for the client pool. Required to sync updates to - * the client cache. - */ - private boolean subscriptionEnabled; - - @NotEmpty - public InetSocketAddress[] getHostAddresses() { - return hostAddresses; - } - - public void setHostAddresses(InetSocketAddress[] hostAddresses) { - this.hostAddresses = hostAddresses; - } - - public ConnectType getConnectType() { - return connectType; - } - - public void setConnectType(ConnectType connectType) { - this.connectType = connectType; - } - - public boolean isSubscriptionEnabled() { - return subscriptionEnabled; - } - - public void setSubscriptionEnabled(boolean subscriptionEnabled) { - this.subscriptionEnabled = subscriptionEnabled; - } - -} diff --git a/functions/common/geode-common/src/main/java/org/springframework/cloud/fn/common/geode/GeodeRegionProperties.java b/functions/common/geode-common/src/main/java/org/springframework/cloud/fn/common/geode/GeodeRegionProperties.java deleted file mode 100644 index 727891dc..00000000 --- a/functions/common/geode-common/src/main/java/org/springframework/cloud/fn/common/geode/GeodeRegionProperties.java +++ /dev/null @@ -1,45 +0,0 @@ -/* - * Copyright 2015-2020 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.geode; - -import jakarta.validation.constraints.NotBlank; - -import org.springframework.boot.context.properties.ConfigurationProperties; -import org.springframework.validation.annotation.Validated; - -/** - * Region configuration properties. - * @author David Turanski - */ -@ConfigurationProperties("geode.region") -@Validated -public class GeodeRegionProperties { - /** - * The region name. - */ - private String regionName; - - @NotBlank(message = "Region name is required") - public String getRegionName() { - return regionName; - } - - public void setRegionName(String regionName) { - this.regionName = regionName; - } - -} diff --git a/functions/common/geode-common/src/main/java/org/springframework/cloud/fn/common/geode/GeodeSecurityProperties.java b/functions/common/geode-common/src/main/java/org/springframework/cloud/fn/common/geode/GeodeSecurityProperties.java deleted file mode 100644 index 07c9c72c..00000000 --- a/functions/common/geode-common/src/main/java/org/springframework/cloud/fn/common/geode/GeodeSecurityProperties.java +++ /dev/null @@ -1,100 +0,0 @@ -/* - * Copyright 2017-2020 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.geode; - -import java.util.Properties; - -import org.apache.geode.LogWriter; -import org.apache.geode.distributed.DistributedMember; -import org.apache.geode.security.AuthInitialize; -import org.apache.geode.security.AuthenticationFailedException; - -import org.springframework.boot.context.properties.ConfigurationProperties; - -/** - * Configuration properties for Geode username/password authentication. - * @author David Turanski - **/ -@ConfigurationProperties("geode.security") -public class GeodeSecurityProperties { - - /** - * The cache username. - */ - private String username; - - /** - * The cache password. - */ - private String password; - - public String getUsername() { - return username; - } - - public void setUsername(String username) { - this.username = username; - } - - public String getPassword() { - return password; - } - - public void setPassword(String password) { - this.password = password; - } - - @SuppressWarnings("unused") - public static class UserAuthInitialize implements AuthInitialize { - - private LogWriter securitylog; - private LogWriter systemlog; - - public static AuthInitialize create() { - return new UserAuthInitialize(); - } - - @Override - public void init(LogWriter systemLogger, LogWriter securityLogger) throws AuthenticationFailedException { - this.systemlog = systemLogger; - this.securitylog = securityLogger; - } - - @Override - public Properties getCredentials(Properties props, DistributedMember server, boolean isPeer) throws AuthenticationFailedException { - - String username = props.getProperty(SECURITY_USERNAME); - if (username == null) { - throw new AuthenticationFailedException("UserAuthInitialize: username not set."); - } - - String password = props.getProperty(SECURITY_PASSWORD); - if (password == null) { - throw new AuthenticationFailedException("UserAuthInitialize: password not set."); - } - - Properties properties = new Properties(); - properties.setProperty(SECURITY_USERNAME, username); - properties.setProperty(SECURITY_PASSWORD, password); - return properties; - } - - @Override - public void close() { - } - } -} diff --git a/functions/common/geode-common/src/main/java/org/springframework/cloud/fn/common/geode/GeodeSslProperties.java b/functions/common/geode-common/src/main/java/org/springframework/cloud/fn/common/geode/GeodeSslProperties.java deleted file mode 100644 index 2544ff04..00000000 --- a/functions/common/geode-common/src/main/java/org/springframework/cloud/fn/common/geode/GeodeSslProperties.java +++ /dev/null @@ -1,170 +0,0 @@ -/* - * Copyright 2018-2020 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.geode; - -import jakarta.validation.constraints.AssertTrue; -import jakarta.validation.constraints.NotBlank; - -import org.springframework.boot.context.properties.ConfigurationProperties; -import org.springframework.core.io.Resource; -import org.springframework.validation.annotation.Validated; - -/** - * SSL configuration for Geode client applications. - * @see Implementing SSL in Geode - * - * @author Christian Tzolov - */ -@ConfigurationProperties("geode.security.ssl") -@Validated -public class GeodeSslProperties { - - private static final String USER_HOME_DIRECTORY = System.getProperty("user.home"); - /** - * Name of the local trust store file copied in the local file system. - */ - public static final String LOCAL_TRUSTSTORE_FILE_NAME = "trusted.keystore"; - /** - * Name of the local trust store file copied in the local file system. - */ - public static final String LOCAL_KEYSTORE_FILE_NAME = "keystore.keystore"; - - /** - * Local directory to cache the truststore and keystore files downloaded form the truststoreUri and keystoreUri locations. - */ - @NotBlank - private String userHomeDirectory = USER_HOME_DIRECTORY; - - /** - * Location of the pre-created truststore URI to be used for connecting to the Geode cluster. - */ - private Resource truststoreUri; - - /** - * Password for accessing the trust store. - */ - private String sslTruststorePassword; - - /** - * Identifies the type of truststore used for SSL communications (e.g. JKS, PKCS11, etc.). - */ - @NotBlank - private String truststoreType = "JKS"; - - /** - * Location of the pre-created Keystore URI to be used for connecting to the Geode cluster. - */ - private Resource keystoreUri; - - /** - * Password for accessing the keys truststore. - */ - private String sslKeystorePassword; - - /** - * Identifies the type of Keystore used for SSL communications (e.g. JKS, PKCS11, etc.). - */ - @NotBlank - private String keystoreType = "JKS"; - - /** - * Configures the SSL ciphers used for secure Socket connections as an array of valid cipher names. - */ - @NotBlank - private String ciphers = "any"; - - public Resource getTruststoreUri() { - return truststoreUri; - } - - public void setTruststoreUri(Resource truststoreUri) { - this.truststoreUri = truststoreUri; - } - - public String getSslKeystorePassword() { - return sslKeystorePassword; - } - - public void setSslKeystorePassword(String sslKeystorePassword) { - this.sslKeystorePassword = sslKeystorePassword; - } - - public String getSslTruststorePassword() { - return sslTruststorePassword; - } - - public void setSslTruststorePassword(String sslTruststorePassword) { - this.sslTruststorePassword = sslTruststorePassword; - } - - public String getUserHomeDirectory() { - return userHomeDirectory; - } - - public void setUserHomeDirectory(String userHomeDirectory) { - this.userHomeDirectory = userHomeDirectory; - } - - public String getTruststoreType() { - return truststoreType; - } - - public void setTruststoreType(String truststoreType) { - this.truststoreType = truststoreType; - } - - public Resource getKeystoreUri() { - return keystoreUri; - } - - public void setKeystoreUri(Resource keystoreUri) { - this.keystoreUri = keystoreUri; - } - - public String getKeystoreType() { - return keystoreType; - } - - public void setKeystoreType(String keystoreType) { - this.keystoreType = keystoreType; - } - - public String getCiphers() { - return ciphers; - } - - public void setCiphers(String ciphers) { - this.ciphers = ciphers; - } - - public boolean isSslEnabled() { - return this.truststoreUri != null && this.keystoreUri != null; - } - - @AssertTrue(message = "The truststoreUri and keystoreUri should together be either empty or not!") - private boolean isStoreUrisConsistent() { - return ((this.truststoreUri == null) && (this.keystoreUri == null)) || - ((this.truststoreUri != null) && (this.keystoreUri != null)); - } - - @AssertTrue(message = "The sslKeystorePassword and sslKeystorePassword must not be empty for non empty store URIs!") - private boolean isStorePasswordRequiredForValidStoreUri() { - return (!this.isSslEnabled()) || - ((this.sslKeystorePassword != null) && (this.sslTruststorePassword != null)); - } - -} diff --git a/functions/common/geode-common/src/main/java/org/springframework/cloud/fn/common/geode/InetSocketAddressConverterConfiguration.java b/functions/common/geode-common/src/main/java/org/springframework/cloud/fn/common/geode/InetSocketAddressConverterConfiguration.java deleted file mode 100644 index 407781af..00000000 --- a/functions/common/geode-common/src/main/java/org/springframework/cloud/fn/common/geode/InetSocketAddressConverterConfiguration.java +++ /dev/null @@ -1,49 +0,0 @@ -/* - * Copyright 2018-2020 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.geode; - -import java.net.InetSocketAddress; -import java.util.regex.Matcher; -import java.util.regex.Pattern; - -import org.springframework.boot.context.properties.ConfigurationPropertiesBinding; -import org.springframework.context.annotation.Bean; -import org.springframework.core.convert.converter.Converter; - -public class InetSocketAddressConverterConfiguration { - @Bean - @ConfigurationPropertiesBinding - public Converter inetSocketAddressConverter() { - return new InetSocketAddressConverter(); - } - - public static class InetSocketAddressConverter implements Converter { - - private static final Pattern HOST_AND_PORT_PATTERN = Pattern.compile("^\\s*(.*?):(\\d+)\\s*$"); - - @Override - public InetSocketAddress convert(String hostAddress) { - Matcher m = HOST_AND_PORT_PATTERN.matcher(hostAddress); - if (m.matches()) { - String host = m.group(1); - int port = Integer.parseInt(m.group(2)); - return new InetSocketAddress(host, port); - } - throw new IllegalArgumentException(String.format("%s is not a valid [host]:[port] value.", hostAddress)); - } - } -} diff --git a/functions/common/geode-common/src/main/java/org/springframework/cloud/fn/common/geode/JsonPdxFunctions.java b/functions/common/geode-common/src/main/java/org/springframework/cloud/fn/common/geode/JsonPdxFunctions.java deleted file mode 100644 index f637824c..00000000 --- a/functions/common/geode-common/src/main/java/org/springframework/cloud/fn/common/geode/JsonPdxFunctions.java +++ /dev/null @@ -1,49 +0,0 @@ -/* - * Copyright 2016-2020 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.geode; - -import java.util.function.Function; - -import org.apache.geode.pdx.JSONFormatter; -import org.apache.geode.pdx.PdxInstance; - -/** - * @author David Turanski - * @author Christian Tzolov - * - */ -public abstract class JsonPdxFunctions { - - public static Function jsonToPdx() { - return JSONFormatter::fromJSON; - } - - public static Function pdxToJson() { - return obj -> { - if (obj == null) { - return null; - } - if (obj instanceof PdxInstance) { - String json = JSONFormatter.toJSON(obj); - // de-pretty - return json.replaceAll("\\r\\n\\s*", "").replaceAll("\\n\\s*", "") - .replaceAll("\\s*:\\s*", ":").trim(); - } - return obj.toString(); - }; - } -} diff --git a/functions/common/metadata-store-common/pom.xml b/functions/common/metadata-store-common/pom.xml index bc7a7f97..1345d692 100644 --- a/functions/common/metadata-store-common/pom.xml +++ b/functions/common/metadata-store-common/pom.xml @@ -51,7 +51,6 @@ test - org.springframework.boot spring-boot-starter-logging @@ -63,22 +62,6 @@ - - org.springframework.integration - spring-integration-gemfire - true - - - org.springframework.data - spring-data-gemfire - - - - - org.springframework.data - spring-data-geode - true - diff --git a/functions/common/metadata-store-common/src/main/java/org/springframework/cloud/fn/common/metadata/store/ClientCacheAutoConfiguration.java b/functions/common/metadata-store-common/src/main/java/org/springframework/cloud/fn/common/metadata/store/ClientCacheAutoConfiguration.java deleted file mode 100644 index 22aed185..00000000 --- a/functions/common/metadata-store-common/src/main/java/org/springframework/cloud/fn/common/metadata/store/ClientCacheAutoConfiguration.java +++ /dev/null @@ -1,44 +0,0 @@ -/* - * Copyright 2018-2020 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.metadata.store; - -import org.apache.geode.cache.GemFireCache; -import org.apache.geode.cache.client.ClientCache; - -import org.springframework.boot.autoconfigure.condition.ConditionalOnClass; -import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean; -import org.springframework.context.annotation.Configuration; -import org.springframework.data.gemfire.client.ClientCacheFactoryBean; -import org.springframework.data.gemfire.config.annotation.ClientCacheApplication; -import org.springframework.data.gemfire.config.annotation.EnablePdx; - -/** - * TODO - *

- * This is the copy of {@code org.springframework.boot.data.geode.autoconfigure.ClientCacheAutoConfiguration} - * until {@code geode-spring-boot-starter} is released. - * - * @author John Blum - */ -@Configuration -@ConditionalOnClass({ClientCacheFactoryBean.class, ClientCache.class}) -@ConditionalOnMissingBean(GemFireCache.class) -@ClientCacheApplication -@EnablePdx -public class ClientCacheAutoConfiguration { - -} diff --git a/functions/common/metadata-store-common/src/main/java/org/springframework/cloud/fn/common/metadata/store/MetadataStoreAutoConfiguration.java b/functions/common/metadata-store-common/src/main/java/org/springframework/cloud/fn/common/metadata/store/MetadataStoreAutoConfiguration.java index f6ab135f..e92489f3 100644 --- a/functions/common/metadata-store-common/src/main/java/org/springframework/cloud/fn/common/metadata/store/MetadataStoreAutoConfiguration.java +++ b/functions/common/metadata-store-common/src/main/java/org/springframework/cloud/fn/common/metadata/store/MetadataStoreAutoConfiguration.java @@ -24,8 +24,6 @@ import io.awspring.cloud.core.region.RegionProvider; import org.apache.curator.framework.CuratorFramework; import org.apache.curator.framework.CuratorFrameworkFactory; import org.apache.curator.retry.RetryForever; -import org.apache.geode.cache.GemFireCache; -import org.apache.geode.cache.Region; import org.springframework.beans.factory.ObjectProvider; import org.springframework.boot.autoconfigure.AutoConfiguration; @@ -34,12 +32,9 @@ import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty; import org.springframework.boot.context.properties.EnableConfigurationProperties; import org.springframework.context.annotation.Bean; -import org.springframework.context.annotation.Import; -import org.springframework.data.gemfire.client.ClientRegionFactoryBean; import org.springframework.data.mongodb.core.MongoTemplate; import org.springframework.data.redis.core.RedisTemplate; import org.springframework.integration.aws.metadata.DynamoDbMetadataStore; -import org.springframework.integration.gemfire.metadata.GemfireMetadataStore; import org.springframework.integration.hazelcast.metadata.HazelcastMetadataStore; import org.springframework.integration.jdbc.metadata.JdbcMetadataStore; import org.springframework.integration.metadata.ConcurrentMetadataStore; @@ -53,6 +48,7 @@ import org.springframework.jdbc.core.JdbcTemplate; /** * @author Artem Bilan * @author David Turanski + * @author Corneil du Plessis * @since 2.0.2 */ @AutoConfiguration @@ -93,35 +89,6 @@ public class MetadataStoreAutoConfiguration { } - @ConditionalOnProperty(prefix = "metadata.store", name = "type", havingValue = "gemfire") - @Import(ClientCacheAutoConfiguration.class) - static class Gemfire { - - @Bean - @ConditionalOnMissingBean - public ClientRegionFactoryBean gemfireRegion(GemFireCache cache, - MetadataStoreProperties metadataStoreProperties) { - - ClientRegionFactoryBean clientRegionFactoryBean = new ClientRegionFactoryBean<>(); - clientRegionFactoryBean.setCache(cache); - clientRegionFactoryBean.setName(metadataStoreProperties.getGemfire().getRegion()); - return clientRegionFactoryBean; - } - - @Bean - @ConditionalOnMissingBean - public ConcurrentMetadataStore gemfireMetadataStore(Region region, - ObjectProvider metadataStoreListenerObjectProvider) { - - @SuppressWarnings("unchecked") - GemfireMetadataStore gemfireMetadataStore = new GemfireMetadataStore((Region) region); - metadataStoreListenerObjectProvider.ifAvailable(gemfireMetadataStore::addListener); - - return gemfireMetadataStore; - } - - } - @ConditionalOnProperty(prefix = "metadata.store", name = "type", havingValue = "hazelcast") static class Hazelcast { diff --git a/functions/common/metadata-store-common/src/main/java/org/springframework/cloud/fn/common/metadata/store/MetadataStoreProperties.java b/functions/common/metadata-store-common/src/main/java/org/springframework/cloud/fn/common/metadata/store/MetadataStoreProperties.java index ac030cd7..85b0c4d9 100644 --- a/functions/common/metadata-store-common/src/main/java/org/springframework/cloud/fn/common/metadata/store/MetadataStoreProperties.java +++ b/functions/common/metadata-store-common/src/main/java/org/springframework/cloud/fn/common/metadata/store/MetadataStoreProperties.java @@ -21,20 +21,19 @@ import java.nio.charset.StandardCharsets; import org.springframework.boot.context.properties.ConfigurationProperties; import org.springframework.integration.aws.metadata.DynamoDbMetadataStore; -import org.springframework.integration.gemfire.metadata.GemfireMetadataStore; import org.springframework.integration.jdbc.metadata.JdbcMetadataStore; import org.springframework.integration.redis.metadata.RedisMetadataStore; /** * @author Artem Bilan * @author David Turanski + * @author Corneil du Plessis * @since 2.0.2 */ @ConfigurationProperties("metadata.store") public class MetadataStoreProperties { enum StoreType { mongodb, - gemfire, redis, dynamodb, jdbc, @@ -51,8 +50,6 @@ public class MetadataStoreProperties { private final Mongo mongoDb = new Mongo(); - private final Gemfire gemfire = new Gemfire(); - private final Redis redis = new Redis(); private final DynamoDb dynamoDb = new DynamoDb(); @@ -73,10 +70,6 @@ public class MetadataStoreProperties { return this.mongoDb; } - public Gemfire getGemfire() { - return this.gemfire; - } - public Redis getRedis() { return this.redis; } @@ -110,23 +103,6 @@ public class MetadataStoreProperties { } - public static class Gemfire { - - /** - * Gemfire region name for metadata. - */ - private String region = GemfireMetadataStore.KEY; - - public String getRegion() { - return this.region; - } - - public void setRegion(String region) { - this.region = region; - } - - } - public static class Redis { /** diff --git a/functions/common/metadata-store-common/src/test/java/org/springframework/cloud/fn/common/metadata/store/MetadataStoreAutoConfigurationTests.java b/functions/common/metadata-store-common/src/test/java/org/springframework/cloud/fn/common/metadata/store/MetadataStoreAutoConfigurationTests.java index c92e12e9..7c08cc66 100644 --- a/functions/common/metadata-store-common/src/test/java/org/springframework/cloud/fn/common/metadata/store/MetadataStoreAutoConfigurationTests.java +++ b/functions/common/metadata-store-common/src/test/java/org/springframework/cloud/fn/common/metadata/store/MetadataStoreAutoConfigurationTests.java @@ -40,7 +40,6 @@ import org.springframework.boot.test.context.runner.ApplicationContextRunner; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.integration.aws.metadata.DynamoDbMetadataStore; -import org.springframework.integration.gemfire.metadata.GemfireMetadataStore; import org.springframework.integration.hazelcast.metadata.HazelcastMetadataStore; import org.springframework.integration.jdbc.metadata.JdbcMetadataStore; import org.springframework.integration.metadata.ConcurrentMetadataStore; @@ -57,6 +56,7 @@ import static org.mockito.Mockito.mock; /** * @author Artem Bilan + * @author Corneil du Plessis * @since 2.0.2 */ @RunWith(Parameterized.class) @@ -67,7 +67,6 @@ public class MetadataStoreAutoConfigurationTests { Arrays.asList( RedisMetadataStore.class, MongoDbMetadataStore.class, - GemfireMetadataStore.class, JdbcMetadataStore.class, ZookeeperMetadataStore.class, HazelcastMetadataStore.class, diff --git a/functions/common/pom.xml b/functions/common/pom.xml index 80c5e784..c3f4a275 100644 --- a/functions/common/pom.xml +++ b/functions/common/pom.xml @@ -16,7 +16,6 @@ file-common ftp-common function-test-support - geode-common metadata-store-common mqtt-common redis-common diff --git a/functions/consumer/geode-consumer/README.adoc b/functions/consumer/geode-consumer/README.adoc deleted file mode 100644 index 3cfce0bb..00000000 --- a/functions/consumer/geode-consumer/README.adoc +++ /dev/null @@ -1,48 +0,0 @@ -# Geode Consumer - -This module provides a `java.util.function.Consumer` that can be reused and composed in other applications. -The `Consumer` configures an Apache Geode client that connects to an external Apache Geode cache server or locator to write Message contents to an existing region. -The consumer uses the `CacheWritingMessageHandler` from `Spring Integration` which writes entries, as key-value pairs to the given region. -A SpEl Expression, given by the property `geode.consumer.key-expression` is used to derive the desired key from the inbound Message. -The value is the message payload. - -## PDX Serialization - -The supplier works with PDX serialized cache objects of type https://geode.apache.org/releases/latest/javadoc/org/apache/geode/pdx/PdxInstance.html[PdxInstance], which Geode uses to store objects that can be represented as JSON. -If the target region uses PDX serialization ,you should set `geode.consumer.json` to `true`. -In this case, the expected payload is Json, serialized as a byte[] or String, and will be converted to PdxInstance before writing to the region. -The root object for evaluating `key-expression` will be of type PDXInstance so values are referenced using the `getField(...)` method. - - -## Beans for injection - -You can import the `GeodeConsumerConfiguration` configuration in a Spring Boot application and then inject the `geodeConsumer` bean as type `Consumer>`. -If necessary, can use the bean name `geodeCqSupplier` as a qualifier. - -Once injected, you can invoke the `accept` method of the `Consumer`. - -## Configuration Options - -Required properties: - -* `geode.region.region-name` - The name of the existing remote region. -* `geode.pool.host-addresses` - A comma delimited list of `host:port` pairs. By default these are locator addresses but are cache server addresses if you set `geode.pool.connect-type=server`. - -For more information on the various options available, please see: - -* link:src/main/java/org/springframework/cloud/fn/consumer/geode/cq/GeodeConsumerProperties.java[GeodeConsumerProperties.java] (`geode.consumer`) - -Many of the options, common to functions that use Apache Geode, are configured by several `@ConfigurationProperties` classes which are included as needed: - -* link:../../common/geode-common/src/main/java/org/springframework/cloud/fn/common/geode/GeodeRegionProperties.java[GeodeRegionProperties.java] (`geode.region`) -* link:../../common/geode-common/src/main/java/org/springframework/cloud/fn/common/geode/GeodePoolProperties.java[GeodePoolProperties.java] (`geode.pool`) -* link:../../common/geode-common/src/main/java/org/springframework/cloud/fn/common/geode/GeodeSecurityProperties.java[GeodeSecurityProperties.java] (`geode.security`) -* link:../../common/geode-common/src/main/java/org/springframework/cloud/fn/common/geode/GeodeSslProperties.java[GeodeSslProperties.java] (`geode.security.ssl`) - -## Examples - -See this link:src/test/java/org/springframework/cloud/fn/consumer/geode/GeodeConsumerApplicationTests.java[test suite] for examples of how this consumer is used. - -## Other usage - -See this link:../../../applications/sink/geode-sink/README.adoc[README] where this consumer is used to create a Spring Cloud Stream application to write to a Geode region. \ No newline at end of file diff --git a/functions/consumer/geode-consumer/pom.xml b/functions/consumer/geode-consumer/pom.xml deleted file mode 100644 index 1f14e5ce..00000000 --- a/functions/consumer/geode-consumer/pom.xml +++ /dev/null @@ -1,44 +0,0 @@ - - - 4.0.0 - - - org.springframework.cloud.fn - spring-functions-parent - 4.0.0-SNAPSHOT - ../../spring-functions-parent/pom.xml - - - geode-consumer - geode-consumer - Geode consumer - - - - org.springframework.integration - spring-integration-gemfire - - - org.springframework.cloud.fn - geode-common - ${project.version} - - - org.springframework.geode - spring-geode-starter-test - test - - - org.springframework.geode - spring-geode-starter-logging - test - - - org.projectlombok - lombok - test - - - - diff --git a/functions/consumer/geode-consumer/src/main/java/org/springframework/cloud/fn/consumer/geode/GeodeConsumerConfiguration.java b/functions/consumer/geode-consumer/src/main/java/org/springframework/cloud/fn/consumer/geode/GeodeConsumerConfiguration.java deleted file mode 100644 index 474c0c7a..00000000 --- a/functions/consumer/geode-consumer/src/main/java/org/springframework/cloud/fn/consumer/geode/GeodeConsumerConfiguration.java +++ /dev/null @@ -1,68 +0,0 @@ -/* - * Copyright 2020-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.geode; - -import java.util.Collections; -import java.util.function.Consumer; -import java.util.function.Function; - -import org.apache.geode.cache.Region; - -import org.springframework.boot.context.properties.EnableConfigurationProperties; -import org.springframework.cloud.fn.common.config.ComponentCustomizer; -import org.springframework.cloud.fn.common.geode.GeodeClientRegionConfiguration; -import org.springframework.context.annotation.Bean; -import org.springframework.context.annotation.Configuration; -import org.springframework.context.annotation.Import; -import org.springframework.integration.gemfire.outbound.CacheWritingMessageHandler; -import org.springframework.lang.Nullable; -import org.springframework.messaging.Message; - -/** - * Configuration for Geode consumer that writes an entry to a {@link Region} for a - * Message, using a SpEL expression for a key, and the payload for the value. - * @author David Turanski - */ -@Configuration(proxyBeanMethods = false) -@EnableConfigurationProperties(GeodeConsumerProperties.class) -@Import(GeodeClientRegionConfiguration.class) -public class GeodeConsumerConfiguration { - - @Bean - public Consumer> geodeConsumer(Function, Message> geodeConsumerHandler, - CacheWritingMessageHandler cacheWriter) { - return message -> cacheWriter.handleMessage(geodeConsumerHandler.apply(message)); - } - - @Bean - Function, Message> geodeConsumerHandler(GeodeConsumerProperties properties) { - return new GeodeConsumerHandler(properties.isJson()); - } - - @Bean - CacheWritingMessageHandler cacheWriter(Region region, GeodeConsumerProperties properties, - @Nullable ComponentCustomizer cacheWritingMessageHandlerCustomizer) { - - CacheWritingMessageHandler messageHandler = new CacheWritingMessageHandler(region); - messageHandler.setCacheEntries(Collections.singletonMap(properties.getKeyExpression(), "payload")); - if (cacheWritingMessageHandlerCustomizer != null) { - cacheWritingMessageHandlerCustomizer.customize(messageHandler); - } - return messageHandler; - } - -} diff --git a/functions/consumer/geode-consumer/src/main/java/org/springframework/cloud/fn/consumer/geode/GeodeConsumerHandler.java b/functions/consumer/geode-consumer/src/main/java/org/springframework/cloud/fn/consumer/geode/GeodeConsumerHandler.java deleted file mode 100644 index d7c5e660..00000000 --- a/functions/consumer/geode-consumer/src/main/java/org/springframework/cloud/fn/consumer/geode/GeodeConsumerHandler.java +++ /dev/null @@ -1,68 +0,0 @@ -/* - * Copyright 2016-2020 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.geode; - -import java.util.function.Function; - -import org.apache.geode.pdx.PdxInstance; - -import org.springframework.cloud.fn.common.geode.JsonPdxFunctions; -import org.springframework.integration.support.MessageBuilder; -import org.springframework.messaging.Message; -import org.springframework.messaging.converter.MessageConversionException; - -/** - * @author David Turanski - * @author Christian Tzolov - **/ -class GeodeConsumerHandler implements Function, Message> { - - private final Boolean convertToJson; - - private final Function transformer = JsonPdxFunctions.jsonToPdx(); - - GeodeConsumerHandler(Boolean convertToJson) { - this.convertToJson = convertToJson; - } - - @Override - public Message apply(Message message) { - Message transformedMessage = message; - Object transformedPayload = message.getPayload(); - if (convertToJson) { - - Object payload = message.getPayload(); - - if (payload instanceof byte[]) { - transformedPayload = transformer.apply(new String((byte[]) payload)); - } - else if (payload instanceof String) { - transformedPayload = transformer.apply((String) payload); - } - else { - throw new MessageConversionException(String.format( - "Cannot convert object of type %s", payload.getClass() - .getName())); - } - } - - return MessageBuilder - .fromMessage(message) - .withPayload(transformedPayload) - .build(); - } -} diff --git a/functions/consumer/geode-consumer/src/main/java/org/springframework/cloud/fn/consumer/geode/GeodeConsumerProperties.java b/functions/consumer/geode-consumer/src/main/java/org/springframework/cloud/fn/consumer/geode/GeodeConsumerProperties.java deleted file mode 100644 index 555e80a6..00000000 --- a/functions/consumer/geode-consumer/src/main/java/org/springframework/cloud/fn/consumer/geode/GeodeConsumerProperties.java +++ /dev/null @@ -1,57 +0,0 @@ -/* - * Copyright 2015-2020 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.geode; - -import jakarta.validation.constraints.NotEmpty; - -import org.springframework.boot.context.properties.ConfigurationProperties; -import org.springframework.validation.annotation.Validated; - -/** - * @author David Turanski - */ -@ConfigurationProperties("geode.consumer") -@Validated -public class GeodeConsumerProperties { - - /** - * SpEL expression to use as a cache key. - */ - private String keyExpression; - - /** - * Indicates if the Geode region stores json objects as PdxInstance. - */ - private boolean json; - - @NotEmpty(message = "A valid key expression is required") - public String getKeyExpression() { - return keyExpression; - } - - public void setKeyExpression(String keyExpression) { - this.keyExpression = keyExpression; - } - - public boolean isJson() { - return json; - } - - public void setJson(boolean json) { - this.json = json; - } -} diff --git a/functions/consumer/geode-consumer/src/test/java/org/springframework/cloud/fn/consumer/geode/GeodeConsumerApplicationTests.java b/functions/consumer/geode-consumer/src/test/java/org/springframework/cloud/fn/consumer/geode/GeodeConsumerApplicationTests.java deleted file mode 100644 index cc551a07..00000000 --- a/functions/consumer/geode-consumer/src/test/java/org/springframework/cloud/fn/consumer/geode/GeodeConsumerApplicationTests.java +++ /dev/null @@ -1,118 +0,0 @@ -/* - * Copyright 2020-2020 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.geode; - -import java.io.IOException; -import java.util.function.Consumer; - -import com.fasterxml.jackson.databind.ObjectMapper; -import lombok.AllArgsConstructor; -import lombok.Data; -import lombok.NoArgsConstructor; -import org.apache.geode.cache.Region; -import org.apache.geode.pdx.PdxInstance; -import org.junit.jupiter.api.AfterAll; -import org.junit.jupiter.api.BeforeAll; -import org.junit.jupiter.api.Tag; -import org.junit.jupiter.api.Test; - -import org.springframework.boot.autoconfigure.SpringBootApplication; -import org.springframework.boot.test.context.runner.ApplicationContextRunner; -import org.springframework.cloud.fn.consumer.geodeserver.GeodeServerTestConfiguration; -import org.springframework.data.gemfire.tests.integration.ForkingClientServerIntegrationTestsSupport; -import org.springframework.messaging.Message; -import org.springframework.messaging.support.GenericMessage; - -import static org.assertj.core.api.Assertions.assertThat; - -@Tag("integration") -public class GeodeConsumerApplicationTests { - private static ApplicationContextRunner applicationContextRunner; - - private ObjectMapper objectMapper = new ObjectMapper(); - - @BeforeAll - static void setup() throws IOException { - ForkingClientServerIntegrationTestsSupport.startGemFireServer( - GeodeServerTestConfiguration.class); - - applicationContextRunner = new ApplicationContextRunner() - .withUserConfiguration(GeodeConsumerTestApplication.class); - } - - @AfterAll - static void stopServer() { - ForkingClientServerIntegrationTestsSupport.stopGemFireServer(); - ForkingClientServerIntegrationTestsSupport.clearCacheServerPortAndPoolPortProperties(); - } - - @Test - void consumeWithJsonEnabled() { - applicationContextRunner - .withPropertyValues( - "geode.region.regionName=Stocks", - "geode.consumer.json=true", - "geode.consumer.key-expression=payload.getField('symbol')", - "geode.pool.connectType=server", - "geode.pool.hostAddresses=" + "localhost:" + System.getProperty("spring.data.gemfire.cache.server.port")) - .run(context -> { - Consumer> geodeConsumer = context.getBean("geodeConsumer", Consumer.class); - - String json = objectMapper.writeValueAsString(new Stock("XXX", 100.00)); - geodeConsumer.accept(new GenericMessage<>(json)); - - Region region = context.getBean(Region.class); - PdxInstance instance = region.get("XXX"); - assertThat(instance.getField("price")).isEqualTo(100.00); - region.close(); - }); - } - - @Test - void consumeWithoutJsonEnabled() { - applicationContextRunner - .withPropertyValues( - "geode.region.regionName=Stocks", - "geode.consumer.key-expression='key'", - "geode.pool.connectType=server", - "geode.pool.hostAddresses=" + "localhost:" + System.getProperty("spring.data.gemfire.cache.server.port")) - .run(context -> { - Consumer> geodeConsumer = context.getBean("geodeConsumer", Consumer.class); - - geodeConsumer.accept(new GenericMessage<>("value")); - - Region region = context.getBean(Region.class); - String value = region.get("key"); - assertThat(value).isEqualTo("value"); - region.close(); - }); - } - - @Data - @AllArgsConstructor - @NoArgsConstructor - static class Stock { - private String symbol; - - private double price; - } - - @SpringBootApplication - static class GeodeConsumerTestApplication { - } - -} diff --git a/functions/consumer/geode-consumer/src/test/java/org/springframework/cloud/fn/consumer/geodeserver/GeodeServerTestConfiguration.java b/functions/consumer/geode-consumer/src/test/java/org/springframework/cloud/fn/consumer/geodeserver/GeodeServerTestConfiguration.java deleted file mode 100644 index 4ad3a629..00000000 --- a/functions/consumer/geode-consumer/src/test/java/org/springframework/cloud/fn/consumer/geodeserver/GeodeServerTestConfiguration.java +++ /dev/null @@ -1,45 +0,0 @@ -/* - * Copyright 2020-2020 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.geodeserver; - -import org.apache.geode.cache.GemFireCache; - -import org.springframework.context.annotation.AnnotationConfigApplicationContext; -import org.springframework.context.annotation.Bean; -import org.springframework.data.gemfire.ReplicatedRegionFactoryBean; -import org.springframework.data.gemfire.config.annotation.CacheServerApplication; - -@CacheServerApplication -public class GeodeServerTestConfiguration { - - public static void main(String[] args) { - - AnnotationConfigApplicationContext applicationContext = - new AnnotationConfigApplicationContext(GeodeServerTestConfiguration.class); - - applicationContext.registerShutdownHook(); - } - - @Bean("Stocks") - public ReplicatedRegionFactoryBean stocksRegion(GemFireCache gemfireCache) { - - ReplicatedRegionFactoryBean regionFactoryBean = new ReplicatedRegionFactoryBean<>(); - regionFactoryBean.setCache(gemfireCache); - - return regionFactoryBean; - } -} diff --git a/functions/consumer/geode-consumer/src/test/resources/logback-include.xml b/functions/consumer/geode-consumer/src/test/resources/logback-include.xml deleted file mode 100644 index ae330ab3..00000000 --- a/functions/consumer/geode-consumer/src/test/resources/logback-include.xml +++ /dev/null @@ -1,16 +0,0 @@ - - - - - - %d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n - - - - - - - - - - diff --git a/functions/consumer/pom.xml b/functions/consumer/pom.xml index a7d7c04c..08bbba41 100644 --- a/functions/consumer/pom.xml +++ b/functions/consumer/pom.xml @@ -17,7 +17,6 @@ analytics-consumer file-consumer ftp-consumer - geode-consumer jdbc-consumer log-consumer mongodb-consumer diff --git a/functions/consumer/redis-consumer/src/test/java/org/springframework/cloud/fn/consumer/redis/RedisConsumerTopicTests.java b/functions/consumer/redis-consumer/src/test/java/org/springframework/cloud/fn/consumer/redis/RedisConsumerTopicTests.java index f559f882..d2af40dc 100644 --- a/functions/consumer/redis-consumer/src/test/java/org/springframework/cloud/fn/consumer/redis/RedisConsumerTopicTests.java +++ b/functions/consumer/redis-consumer/src/test/java/org/springframework/cloud/fn/consumer/redis/RedisConsumerTopicTests.java @@ -23,15 +23,11 @@ import java.util.concurrent.TimeUnit; import org.awaitility.Awaitility; import org.junit.jupiter.api.Test; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.data.redis.connection.RedisConnection; -import org.springframework.data.redis.connection.RedisConnectionFactory; import org.springframework.data.redis.listener.ChannelTopic; import org.springframework.data.redis.listener.RedisMessageListenerContainer; import org.springframework.data.redis.listener.Topic; import org.springframework.data.redis.listener.adapter.MessageListenerAdapter; import org.springframework.data.redis.serializer.StringRedisSerializer; -import org.springframework.integration.test.util.TestUtils; import org.springframework.messaging.Message; import org.springframework.messaging.support.MessageBuilder; import org.springframework.test.context.TestPropertySource; @@ -40,6 +36,7 @@ import static org.assertj.core.api.Assertions.assertThat; /** * @author Soby Chacko + * @author Corneil du Plessis */ @TestPropertySource(properties = "redis.consumer.topic = foo-topic") public class RedisConsumerTopicTests extends AbstractRedisConsumerTests { diff --git a/functions/consumer/sftp-consumer/src/main/java/org/springframework/cloud/fn/consumer/sftp/SftpConsumerConfiguration.java b/functions/consumer/sftp-consumer/src/main/java/org/springframework/cloud/fn/consumer/sftp/SftpConsumerConfiguration.java index 520419d4..4c267b0b 100644 --- a/functions/consumer/sftp-consumer/src/main/java/org/springframework/cloud/fn/consumer/sftp/SftpConsumerConfiguration.java +++ b/functions/consumer/sftp-consumer/src/main/java/org/springframework/cloud/fn/consumer/sftp/SftpConsumerConfiguration.java @@ -18,7 +18,7 @@ package org.springframework.cloud.fn.consumer.sftp; import java.util.function.Consumer; -import com.jcraft.jsch.ChannelSftp; +import org.apache.sshd.sftp.client.SftpClient; import org.springframework.boot.context.properties.EnableConfigurationProperties; import org.springframework.cloud.fn.common.config.ComponentCustomizer; @@ -35,6 +35,11 @@ import org.springframework.integration.sftp.session.SftpRemoteFileTemplate; import org.springframework.lang.Nullable; import org.springframework.messaging.Message; +/** + * Configuration for SFTP Consumer. + * @author Soby Chacko + * @author Corneil du Plessis + */ @Configuration(proxyBeanMethods = false) @EnableConfigurationProperties(SftpConsumerProperties.class) @Import(SftpConsumerSessionFactoryConfiguration.class) @@ -42,7 +47,7 @@ public class SftpConsumerConfiguration { @Bean public IntegrationFlow ftpOutboundFlow(SftpConsumerProperties properties, - SessionFactory ftpSessionFactory, + SessionFactory ftpSessionFactory, @Nullable ComponentCustomizer sftpMessageHandlerSpecCustomizer) { IntegrationFlowBuilder integrationFlowBuilder = diff --git a/functions/consumer/sftp-consumer/src/main/java/org/springframework/cloud/fn/consumer/sftp/SftpConsumerProperties.java b/functions/consumer/sftp-consumer/src/main/java/org/springframework/cloud/fn/consumer/sftp/SftpConsumerProperties.java index 34553057..57ecdcd2 100644 --- a/functions/consumer/sftp-consumer/src/main/java/org/springframework/cloud/fn/consumer/sftp/SftpConsumerProperties.java +++ b/functions/consumer/sftp-consumer/src/main/java/org/springframework/cloud/fn/consumer/sftp/SftpConsumerProperties.java @@ -29,6 +29,7 @@ import org.springframework.validation.annotation.Validated; /** * @author Gary Russell * @author Artem Bilan + * @author Corneil du Plessis */ @ConfigurationProperties("sftp.consumer") @Validated @@ -42,7 +43,7 @@ public class SftpConsumerProperties { private String temporaryRemoteDir = "/"; /** - * Whether or not to create the remote directory. + * Whether to create the remote directory. */ private boolean autoCreateDir = true; @@ -52,7 +53,7 @@ public class SftpConsumerProperties { private FileExistsMode mode = FileExistsMode.REPLACE; /** - * Whether or not to write to a temporary file and rename. + * Whether to write to a temporary file and rename. */ private boolean useTemporaryFilename = true; diff --git a/functions/consumer/sftp-consumer/src/main/java/org/springframework/cloud/fn/consumer/sftp/SftpConsumerSessionFactoryConfiguration.java b/functions/consumer/sftp-consumer/src/main/java/org/springframework/cloud/fn/consumer/sftp/SftpConsumerSessionFactoryConfiguration.java index 9986b635..92e826b6 100644 --- a/functions/consumer/sftp-consumer/src/main/java/org/springframework/cloud/fn/consumer/sftp/SftpConsumerSessionFactoryConfiguration.java +++ b/functions/consumer/sftp-consumer/src/main/java/org/springframework/cloud/fn/consumer/sftp/SftpConsumerSessionFactoryConfiguration.java @@ -18,7 +18,7 @@ package org.springframework.cloud.fn.consumer.sftp; import java.nio.charset.StandardCharsets; -import com.jcraft.jsch.ChannelSftp; +import org.apache.sshd.sftp.client.SftpClient; import org.springframework.beans.factory.BeanFactory; import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean; @@ -33,13 +33,14 @@ import org.springframework.integration.sftp.session.DefaultSftpSessionFactory; * Session factory configuration. * * @author Gary Russell + * @author Corneil du Plessis * */ public class SftpConsumerSessionFactoryConfiguration { @Bean @ConditionalOnMissingBean - public SessionFactory sftpSessionFactory(SftpConsumerProperties properties, BeanFactory beanFactory) { + public SessionFactory sftpSessionFactory(SftpConsumerProperties properties, BeanFactory beanFactory) { DefaultSftpSessionFactory sftpSessionFactory = new DefaultSftpSessionFactory(); SftpConsumerProperties.Factory factory = properties.getFactory(); sftpSessionFactory.setHost(factory.getHost()); @@ -57,7 +58,7 @@ public class SftpConsumerSessionFactoryConfiguration { sftpSessionFactory.setKnownHostsResource(knownHostsResource); } if (factory.getCacheSessions() != null) { - CachingSessionFactory csf = new CachingSessionFactory<>(sftpSessionFactory); + CachingSessionFactory csf = new CachingSessionFactory<>(sftpSessionFactory); return csf; } else { diff --git a/functions/function/aggregator-function/pom.xml b/functions/function/aggregator-function/pom.xml index a2cd72aa..6cdfd88a 100644 --- a/functions/function/aggregator-function/pom.xml +++ b/functions/function/aggregator-function/pom.xml @@ -40,15 +40,6 @@ spring-boot-starter-data-redis runtime - - - org.springframework.integration - spring-integration-gemfire - - - org.springframework.geode - spring-geode-starter - org.springframework.integration diff --git a/functions/function/aggregator-function/src/main/java/org/springframework/cloud/fn/aggregator/AggregatorFunctionConfiguration.java b/functions/function/aggregator-function/src/main/java/org/springframework/cloud/fn/aggregator/AggregatorFunctionConfiguration.java index 6bc87f85..1f28ce76 100644 --- a/functions/function/aggregator-function/src/main/java/org/springframework/cloud/fn/aggregator/AggregatorFunctionConfiguration.java +++ b/functions/function/aggregator-function/src/main/java/org/springframework/cloud/fn/aggregator/AggregatorFunctionConfiguration.java @@ -49,6 +49,7 @@ import org.springframework.messaging.MessageChannel; /** * @author Artem Bilan + * @author Corneil du Plessis */ @AutoConfiguration @EnableConfigurationProperties(AggregatorFunctionProperties.class) @@ -61,11 +62,12 @@ public class AggregatorFunctionConfiguration { private BeanFactory beanFactory; @Bean - public Function>, Flux>> aggregatorFunction(FluxMessageChannel inputChannel, - FluxMessageChannel outputChannel) { - + public Function>, Flux>> aggregatorFunction( + FluxMessageChannel inputChannel, + FluxMessageChannel outputChannel + ) { return input -> Flux.from(outputChannel) - .doOnRequest((request) -> inputChannel.subscribeTo(input)); + .doOnRequest((request) -> inputChannel.subscribeTo(input)); } @Bean @@ -81,12 +83,12 @@ public class AggregatorFunctionConfiguration { @Bean @ServiceActivator(inputChannel = "inputChannel") public AggregatorFactoryBean aggregator( - @Nullable CorrelationStrategy correlationStrategy, - @Nullable ReleaseStrategy releaseStrategy, - @Nullable MessageGroupProcessor messageGroupProcessor, - @Nullable MessageGroupStore messageStore, - @Qualifier("outputChannel") MessageChannel outputChannel, - @Nullable ComponentCustomizer aggregatorCustomizer) { + @Nullable CorrelationStrategy correlationStrategy, + @Nullable ReleaseStrategy releaseStrategy, + @Nullable MessageGroupProcessor messageGroupProcessor, + @Nullable MessageGroupStore messageStore, + @Qualifier("outputChannel") MessageChannel outputChannel, + @Nullable ComponentCustomizer aggregatorCustomizer) { AggregatorFactoryBean aggregator = new AggregatorFactoryBean(); aggregator.setExpireGroupsUponCompletion(true); @@ -144,8 +146,11 @@ public class AggregatorFunctionConfiguration { @Configuration @ConditionalOnMissingBean(MessageGroupStore.class) - @Import({ MessageStoreConfiguration.Mongo.class, MessageStoreConfiguration.Redis.class, - MessageStoreConfiguration.Gemfire.class, MessageStoreConfiguration.Jdbc.class }) + @Import({ + MessageStoreConfiguration.Mongo.class, + MessageStoreConfiguration.Redis.class, + MessageStoreConfiguration.Jdbc.class + }) protected static class MessageStoreAutoConfiguration { } diff --git a/functions/function/aggregator-function/src/main/java/org/springframework/cloud/fn/aggregator/ExcludeStoresAutoConfigurationEnvironmentPostProcessor.java b/functions/function/aggregator-function/src/main/java/org/springframework/cloud/fn/aggregator/ExcludeStoresAutoConfigurationEnvironmentPostProcessor.java index 5743a0d4..60614059 100644 --- a/functions/function/aggregator-function/src/main/java/org/springframework/cloud/fn/aggregator/ExcludeStoresAutoConfigurationEnvironmentPostProcessor.java +++ b/functions/function/aggregator-function/src/main/java/org/springframework/cloud/fn/aggregator/ExcludeStoresAutoConfigurationEnvironmentPostProcessor.java @@ -30,14 +30,13 @@ import org.springframework.boot.env.EnvironmentPostProcessor; import org.springframework.core.env.ConfigurableEnvironment; import org.springframework.core.env.MutablePropertySources; import org.springframework.core.env.PropertiesPropertySource; -import org.springframework.geode.boot.autoconfigure.ClientCacheAutoConfiguration; -import org.springframework.geode.boot.autoconfigure.SslAutoConfiguration; /** * An {@link EnvironmentPostProcessor} to add {@code spring.autoconfigure.exclude} property * since we can't use {@code application.properties} from the library perspective. * * @author Artem Bilan + * @author Corneil du Plessis */ public class ExcludeStoresAutoConfigurationEnvironmentPostProcessor implements EnvironmentPostProcessor { @@ -52,18 +51,10 @@ public class ExcludeStoresAutoConfigurationEnvironmentPostProcessor implements E MongoAutoConfiguration.class.getName() + ", " + MongoDataAutoConfiguration.class.getName() + ", " + MongoRepositoriesAutoConfiguration.class.getName() + ", " + - ClientCacheAutoConfiguration.class.getName() + ", " + RedisAutoConfiguration.class.getName() + ", " + RedisRepositoriesAutoConfiguration.class.getName()); - String messageStoreType = environment.getProperty(AggregatorFunctionProperties.PREFIX + ".message-store-type"); - if (!AggregatorFunctionProperties.MessageStoreType.GEMFIRE.equals(messageStoreType)) { - properties.setProperty(SslAutoConfiguration.SECURITY_SSL_ENVIRONMENT_POST_PROCESSOR_ENABLED_PROPERTY, - "false"); - } - - propertySources.addLast( - new PropertiesPropertySource("aggregator.exclude.stores.auto-configuration", properties)); + propertySources.addLast(new PropertiesPropertySource("aggregator.exclude.stores.auto-configuration", properties)); } } diff --git a/functions/function/aggregator-function/src/main/java/org/springframework/cloud/fn/aggregator/MessageStoreConfiguration.java b/functions/function/aggregator-function/src/main/java/org/springframework/cloud/fn/aggregator/MessageStoreConfiguration.java index 460ea914..c823a8c3 100644 --- a/functions/function/aggregator-function/src/main/java/org/springframework/cloud/fn/aggregator/MessageStoreConfiguration.java +++ b/functions/function/aggregator-function/src/main/java/org/springframework/cloud/fn/aggregator/MessageStoreConfiguration.java @@ -18,11 +18,7 @@ package org.springframework.cloud.fn.aggregator; import java.util.Arrays; -import org.apache.geode.cache.GemFireCache; -import org.apache.geode.cache.Region; - import org.springframework.boot.autoconfigure.condition.ConditionalOnClass; -import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean; import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty; import org.springframework.boot.autoconfigure.data.mongo.MongoDataAutoConfiguration; import org.springframework.boot.autoconfigure.data.redis.RedisAutoConfiguration; @@ -32,13 +28,9 @@ import org.springframework.boot.autoconfigure.mongo.MongoAutoConfiguration; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Import; import org.springframework.context.annotation.Primary; -import org.springframework.data.gemfire.client.ClientRegionFactoryBean; -import org.springframework.data.gemfire.config.annotation.EnablePdx; import org.springframework.data.mongodb.core.MongoTemplate; import org.springframework.data.mongodb.core.convert.MongoCustomConversions; import org.springframework.data.redis.core.RedisTemplate; -import org.springframework.geode.boot.autoconfigure.ClientCacheAutoConfiguration; -import org.springframework.integration.gemfire.store.GemfireMessageStore; import org.springframework.integration.jdbc.store.JdbcMessageStore; import org.springframework.integration.mongodb.store.ConfigurableMongoDbMessageStore; import org.springframework.integration.mongodb.support.BinaryToMessageConverter; @@ -55,6 +47,7 @@ import org.springframework.util.StringUtils; * via matched configuration properties. * * @author Artem Bilan + * @author Corneil du Plessis */ class MessageStoreConfiguration { @@ -99,30 +92,6 @@ class MessageStoreConfiguration { } - @ConditionalOnClass(GemfireMessageStore.class) - @ConditionalOnProperty(prefix = AggregatorFunctionProperties.PREFIX, - name = "message-store-type", - havingValue = AggregatorFunctionProperties.MessageStoreType.GEMFIRE) - @Import(ClientCacheAutoConfiguration.class) - @EnablePdx - static class Gemfire { - - @Bean - @ConditionalOnMissingBean - public ClientRegionFactoryBean gemfireRegion(GemFireCache cache, AggregatorFunctionProperties properties) { - ClientRegionFactoryBean clientRegionFactoryBean = new ClientRegionFactoryBean<>(); - clientRegionFactoryBean.setCache(cache); - clientRegionFactoryBean.setName(properties.getMessageStoreEntity()); - return clientRegionFactoryBean; - } - - @Bean - public MessageGroupStore messageStore(Region region) { - return new GemfireMessageStore(region); - } - - } - @ConditionalOnClass(JdbcMessageStore.class) @ConditionalOnProperty(prefix = AggregatorFunctionProperties.PREFIX, name = "message-store-type", diff --git a/functions/function/aggregator-function/src/test/java/org/springframework/cloud/fn/aggregator/AbstractAggregatorFunctionTests.java b/functions/function/aggregator-function/src/test/java/org/springframework/cloud/fn/aggregator/AbstractAggregatorFunctionTests.java index e4e65721..05e6f8c5 100644 --- a/functions/function/aggregator-function/src/test/java/org/springframework/cloud/fn/aggregator/AbstractAggregatorFunctionTests.java +++ b/functions/function/aggregator-function/src/test/java/org/springframework/cloud/fn/aggregator/AbstractAggregatorFunctionTests.java @@ -21,10 +21,8 @@ import java.util.function.Function; import reactor.core.publisher.Flux; import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.beans.factory.annotation.Value; import org.springframework.boot.autoconfigure.SpringBootApplication; import org.springframework.boot.test.context.SpringBootTest; -import org.springframework.geode.boot.autoconfigure.SslAutoConfiguration; import org.springframework.integration.aggregator.AggregatingMessageHandler; import org.springframework.integration.store.MessageGroupStore; import org.springframework.messaging.Message; @@ -32,6 +30,7 @@ import org.springframework.test.annotation.DirtiesContext; /** * @author Artem Bilan + * @author Corneil du Plessis */ @SpringBootTest @DirtiesContext @@ -46,9 +45,6 @@ public abstract class AbstractAggregatorFunctionTests { @Autowired protected AggregatingMessageHandler aggregatingMessageHandler; - @Value("${" + SslAutoConfiguration.SECURITY_SSL_ENVIRONMENT_POST_PROCESSOR_ENABLED_PROPERTY + ":true}") - protected Boolean geodeSslEnable; - @SpringBootApplication static class AggregatorFunctionTestApplication { diff --git a/functions/function/aggregator-function/src/test/java/org/springframework/cloud/fn/aggregator/DefaultAggregatorTests.java b/functions/function/aggregator-function/src/test/java/org/springframework/cloud/fn/aggregator/DefaultAggregatorTests.java index 7af1cdad..32a8e997 100644 --- a/functions/function/aggregator-function/src/test/java/org/springframework/cloud/fn/aggregator/DefaultAggregatorTests.java +++ b/functions/function/aggregator-function/src/test/java/org/springframework/cloud/fn/aggregator/DefaultAggregatorTests.java @@ -32,6 +32,7 @@ import static org.assertj.core.api.Assertions.assertThat; /** * @author Artem Bilan + * @author Corneil du Plessis */ public class DefaultAggregatorTests extends AbstractAggregatorFunctionTests { @@ -65,8 +66,6 @@ public class DefaultAggregatorTests extends AbstractAggregatorFunctionTests { assertThat(this.messageGroupStore).isNull(); assertThat(this.aggregatingMessageHandler.getMessageStore()).isInstanceOf(SimpleMessageStore.class); - // Also verify geode ssl flag not enabled for default message store (non-geode) - assertThat(this.geodeSslEnable).isFalse(); } } diff --git a/functions/function/aggregator-function/src/test/java/org/springframework/cloud/fn/aggregator/GroupTimeOutAndGemfireMessageStoreAggregatorTests.java b/functions/function/aggregator-function/src/test/java/org/springframework/cloud/fn/aggregator/GroupTimeOutAndGemfireMessageStoreAggregatorTests.java deleted file mode 100644 index 850a9ded..00000000 --- a/functions/function/aggregator-function/src/test/java/org/springframework/cloud/fn/aggregator/GroupTimeOutAndGemfireMessageStoreAggregatorTests.java +++ /dev/null @@ -1,69 +0,0 @@ -/* - * Copyright 2020-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.aggregator; - -import java.time.Duration; -import java.util.List; - -import org.junit.jupiter.api.Test; -import reactor.core.publisher.Flux; -import reactor.test.StepVerifier; - -import org.springframework.integration.IntegrationMessageHeaderAccessor; -import org.springframework.integration.gemfire.store.GemfireMessageStore; -import org.springframework.integration.support.MessageBuilder; -import org.springframework.messaging.Message; -import org.springframework.test.context.TestPropertySource; - -import static org.assertj.core.api.Assertions.assertThat; - -/** - * @author Artem Bilan - */ -@TestPropertySource(properties = { - "aggregator.message-store-type=gemfire", - "aggregator.groupTimeout=10" }) -public class GroupTimeOutAndGemfireMessageStoreAggregatorTests extends AbstractAggregatorFunctionTests { - - @Test - public void test() { - Flux> input = - Flux.just(MessageBuilder.withPayload("1") - .setHeader(IntegrationMessageHeaderAccessor.CORRELATION_ID, "my_correlation") - .build()); - - Flux> output = this.aggregatorFunction.apply(input); - - output.as(StepVerifier::create) - .assertNext((message) -> - assertThat(message) - .extracting(Message::getPayload) - .isInstanceOf(List.class) - .asList() - .hasSize(1) - .contains("1")) - .thenCancel() - .verify(Duration.ofSeconds(10)); - - assertThat(this.messageGroupStore).isInstanceOf(GemfireMessageStore.class); - assertThat(this.aggregatingMessageHandler.getMessageStore()).isSameAs(this.messageGroupStore); - - // Also verify geode ssl flag enabled for geode message stores - assertThat(this.geodeSslEnable).isTrue(); - } - -} diff --git a/functions/function/aggregator-function/src/test/java/org/springframework/cloud/fn/aggregator/JdbcMessageStoreAggregatorTests.java b/functions/function/aggregator-function/src/test/java/org/springframework/cloud/fn/aggregator/JdbcMessageStoreAggregatorTests.java index ac87a5c5..d009270f 100644 --- a/functions/function/aggregator-function/src/test/java/org/springframework/cloud/fn/aggregator/JdbcMessageStoreAggregatorTests.java +++ b/functions/function/aggregator-function/src/test/java/org/springframework/cloud/fn/aggregator/JdbcMessageStoreAggregatorTests.java @@ -33,6 +33,7 @@ import static org.assertj.core.api.Assertions.assertThat; /** * @author Artem Bilan + * @author Corneil du Plessis */ @TestPropertySource(properties = "aggregator.message-store-type=jdbc") public class JdbcMessageStoreAggregatorTests extends AbstractAggregatorFunctionTests { @@ -67,9 +68,6 @@ public class JdbcMessageStoreAggregatorTests extends AbstractAggregatorFunctionT assertThat(this.messageGroupStore).isInstanceOf(JdbcMessageStore.class); assertThat(this.aggregatingMessageHandler.getMessageStore()).isSameAs(this.messageGroupStore); - - // Also verify geode ssl flag not enabled for non-geode message stores - assertThat(this.geodeSslEnable).isFalse(); } } diff --git a/functions/supplier/geode-supplier/README.adoc b/functions/supplier/geode-supplier/README.adoc deleted file mode 100644 index b1a5208b..00000000 --- a/functions/supplier/geode-supplier/README.adoc +++ /dev/null @@ -1,68 +0,0 @@ -# Geode Supplier - -This module provides a `java.util.function.Supplier` that can be reused and composed in other applications. -The `Supplier` configures an Apache Geode client that connects to an external Apache Geode cache server or locator to monitor an existing region. -If `geode.supplier.query` is provided, the supplier will create a continuous query on the region and publish any events that meet the select criteria. -If no query is provided, the supplier will publish all create and update events on the region. - -## Continuous Query -If a query is provided, the supplier uses the `ContinuousQueryMessageProducer` from `Spring Integration` which wraps a https://docs.spring.io/spring-data/gemfire/docs/current/api/org/springframework/data/gemfire/listener/ContinuousQueryListenerContainer.html[ContinuousQueryListenerContainer] -and emits a reactive stream of objects, extracted from a Geode https://geode.apache.org/releases/latest/javadoc/org/apache/geode/cache/CqEvent.html[CqEvent], which holds all of the -event details. -A SpEl Expression, given by the property `geode.cq.supplier.event-expression` is used to extract desired fields from the CQEvent payload. -The default expression is `newValue` which returns the current value from the configured Region. - -## Cache Listener - -If no query is provided, the supplier uses the `CacheListeningMessageProducer` from `Spring Integration` which wraps a https://geode.apache.org/releases/latest/javadoc/org/apache/geode/cache/CacheListener.html[CacheListener] -and emits a reactive stream of objects, extracted from a Geode https://geode.apache.org/releases/latest/javadoc/org/apache/geode/cache/EntryEvent.html[EntryEvent], which holds all of the -event details. -A SpEl Expression, given by the property `geode.supplier.entry-event-expression` is used to extract desired fields from the EntryEvent payload. -The default expression is `newValue` which returns the current value from the configured Region. - -NOTE: Retrieving the value by itself is not always sufficient, especially if it does not contain the key value, or any additional context. -The key is referenced by the field `key`. -If the cached key and value types are primitives, a simple expression like `key + ':' +newValue` may be useful. -To access the entire EntryEvent, set the expression to `#root` or `#this`. - -The configured MessageProducer emits objects to the supplier implemented as `Supplier>`. -Users have to subscribe to the returned `Flux` to receive the data. - -## PDX Serialization - -The supplier works with PDX serialized cache objects of type https://geode.apache.org/releases/latest/javadoc/org/apache/geode/pdx/PdxInstance.html[PdxInstance], which Geode uses to store objects that can be represented as JSON. -If the target region uses PDX serialization and you set `geode.client.pdx-read-serialized` to `true`, PdxInstance objects will be returned as JSON strings. - -## Beans for injection - -You can import the `GeodeSupplierConfiguration` configuration in a Spring Boot application and then inject the `geodeSupplier` bean as type `Supplier>`, where `T` is the expected return type. -If necessary, can use the bean name `geodeSupplier` as a qualifier. - -Once injected, you can invoke the `get` method of the `Supplier` and then subscribe to the returned `Flux` to initiate the stream. - -## Configuration Options - -Required properties: - -* `geode.region.region-name` - The name of the existing remote region. -* `geode.pool.host-addresses` - A comma delimited list of `host:port` pairs. By default these are locator addresses but are cache server addresses if you set `geode.pool.connect-type=server`. - -For more information on the various options available, please see: - -* link:src/main/java/org/springframework/cloud/fn/supplier/geode/GeodeSupplierProperties.java[GeodeSupplierProperties.java] (`geode.supplier`) - -Many of the options, common to functions that use Apache Geode, are configured by several `@ConfigurationProperties` classes which are included as needed: - -* link:../../common/geode-common/src/main/java/org/springframework/cloud/fn/common/geode/GeodeClientCacheProperties.java[GeodeClientCacheProperties.java] (`geode.client`) -* link:../../common/geode-common/src/main/java/org/springframework/cloud/fn/common/geode/GeodeRegionProperties.java[GeodeRegionProperties.java] (`geode.region`) -* link:../../common/geode-common/src/main/java/org/springframework/cloud/fn/common/geode/GeodePoolProperties.java[GeodePoolProperties.java] (`geode.pool`) -* link:../../common/geode-common/src/main/java/org/springframework/cloud/fn/common/geode/GeodeSecurityProperties.java[GeodeSecurityProperties.java] (`geode.security`) -* link:../../common/geode-common/src/main/java/org/springframework/cloud/fn/common/geode/GeodeSslProperties.java[GeodeSslProperties.java] (`geode.security.ssl`) - -## Examples - -See this link:src/test/java/org/springframework/cloud/fn/supplier/geode/GeodeSupplierApplicationTests.java[test suite] for examples of how this supplier is used. - -## Other usage - -See this link:../../../applications/source/geode-source/README.adoc[README] where this supplier is used to create a Spring Cloud Stream application to emit entry event data. \ No newline at end of file diff --git a/functions/supplier/geode-supplier/pom.xml b/functions/supplier/geode-supplier/pom.xml deleted file mode 100644 index 2c91f6dd..00000000 --- a/functions/supplier/geode-supplier/pom.xml +++ /dev/null @@ -1,44 +0,0 @@ - - - 4.0.0 - - - org.springframework.cloud.fn - spring-functions-parent - 4.0.0-SNAPSHOT - ../../spring-functions-parent/pom.xml - - - geode-supplier - geode-supplier - geode supplier - - - - org.springframework.integration - spring-integration-gemfire - - - org.springframework.cloud.fn - geode-common - ${project.version} - - - org.springframework.geode - spring-geode-starter-logging - test - - - org.springframework.geode - spring-geode-starter-test - test - - - org.projectlombok - lombok - test - - - - diff --git a/functions/supplier/geode-supplier/src/main/java/org/springframework/cloud/fn/supplier/geode/GeodeSupplierConfiguration.java b/functions/supplier/geode-supplier/src/main/java/org/springframework/cloud/fn/supplier/geode/GeodeSupplierConfiguration.java deleted file mode 100644 index af27f90f..00000000 --- a/functions/supplier/geode-supplier/src/main/java/org/springframework/cloud/fn/supplier/geode/GeodeSupplierConfiguration.java +++ /dev/null @@ -1,194 +0,0 @@ -/* - * Copyright 2015-2020 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.supplier.geode; - -import java.util.function.Function; -import java.util.function.Supplier; - -import org.apache.geode.cache.Region; -import org.apache.geode.cache.client.ClientCache; -import org.apache.geode.pdx.PdxInstance; -import reactor.core.publisher.EmitterProcessor; -import reactor.core.publisher.Flux; - -import org.springframework.beans.factory.BeanCreationException; -import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean; -import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty; -import org.springframework.boot.context.properties.EnableConfigurationProperties; -import org.springframework.cloud.fn.common.geode.GeodeClientRegionConfiguration; -import org.springframework.cloud.fn.common.geode.JsonPdxFunctions; -import org.springframework.context.annotation.Bean; -import org.springframework.context.annotation.Condition; -import org.springframework.context.annotation.ConditionContext; -import org.springframework.context.annotation.Conditional; -import org.springframework.context.annotation.Configuration; -import org.springframework.context.annotation.Import; -import org.springframework.context.annotation.PropertySource; -import org.springframework.core.type.AnnotatedTypeMetadata; -import org.springframework.data.gemfire.client.Interest; -import org.springframework.data.gemfire.listener.ContinuousQueryListenerContainer; -import org.springframework.integration.channel.DirectChannel; -import org.springframework.integration.channel.FluxMessageChannel; -import org.springframework.integration.core.MessageProducer; -import org.springframework.integration.dsl.IntegrationFlow; -import org.springframework.integration.dsl.IntegrationFlows; -import org.springframework.integration.gemfire.inbound.CacheListeningMessageProducer; -import org.springframework.integration.gemfire.inbound.ContinuousQueryMessageProducer; -import org.springframework.integration.router.PayloadTypeRouter; -import org.springframework.messaging.Message; -import org.springframework.messaging.MessageChannel; -import org.springframework.util.StringUtils; - -/** - * The Geode Supplier which publishes a message for each event matching the criteria for a - * configured Region. If a query is provided, this will use a - * {@link ContinuousQueryMessageProducer} to publish - * {@link org.apache.geode.cache.query.CqEvent}s that match the query selection criteria. - * If no query is provided, this will use a {@link CacheListeningMessageProducer} to - * publsh {@link org.apache.geode.cache.EntryEvent}s. - * - * A SpEl Expression, given by the property 'eventExpression' is evaluated to extract - * desired information from the payload. The default expression is 'newValue' which - * returns the current object value. This may not be ideal for every use case especially - * if it does not provide the key value. The key is referenced by the field 'key'. If the - * cached key and value types are primitives, an simple expression like "key + ':' + - * newValue" will work. Additional available depend on the specific event type. - * - * More complex transformations, such as Json, will require customization. To access the - * original object, set 'entryExpression' to '#root' or "#this'. - * - * This converts payloads of type {@link PdxInstance}, which Geode uses to store JSON - * content (the type of 'newValue' for instance), to a JSON String. - * - * - * @author David Turanski - */ - -@Import(GeodeClientRegionConfiguration.class) -@Configuration -@PropertySource("classpath:geode-client.properties") -@EnableConfigurationProperties(GeodeSupplierProperties.class) -public class GeodeSupplierConfiguration { - - private EmitterProcessor> cacheEvents = EmitterProcessor.create(); - - @Bean - public Supplier> geodeSupplier() { - return () -> cacheEvents.map(Message::getPayload); - } - - @Bean - FluxMessageChannel fluxChannel() { - FluxMessageChannel fluxChannel = new FluxMessageChannel(); - fluxChannel.subscribe(cacheEvents); - return fluxChannel; - } - - @Bean - MessageChannel convertToStringChannel() { - return new DirectChannel(); - } - - @Bean - MessageChannel routerChannel() { - return new DirectChannel(); - } - - @Bean - PayloadTypeRouter payloadTypeRouter(FluxMessageChannel fluxChannel) { - PayloadTypeRouter router = new PayloadTypeRouter(); - router.setDefaultOutputChannel(fluxChannel); - router.setChannelMapping(PdxInstance.class.getName(), "convertToStringChannel"); - - return router; - } - - @ConditionalOnMissingBean(Interest.class) - @Bean - public Interest allKeysInterest() { - return new Interest<>(Interest.ALL_KEYS); - } - - @Bean - IntegrationFlow startFlow(MessageChannel routerChannel, PayloadTypeRouter payloadTypeRouter) { - return IntegrationFlows.from(routerChannel) - .route(payloadTypeRouter) - .get(); - } - - @Bean - Function pdxToJson() { - return JsonPdxFunctions.pdxToJson(); - } - - @Bean - IntegrationFlow convertToString(MessageChannel convertToStringChannel, FluxMessageChannel fluxChannel, - Function pdxToJson) { - return IntegrationFlows.from(convertToStringChannel) - .transform(pdxToJson) - .channel(fluxChannel) - .get(); - } - - @Bean - @Conditional({ CQNotEnabled.class }) // ConditionalOnExpression causing SpEL errors. - public MessageProducer cacheListeningMessageProducer( - MessageChannel routerChannel, - GeodeSupplierProperties properties, Region region) { - CacheListeningMessageProducer cacheListeningMessageProducer = new CacheListeningMessageProducer(region); - cacheListeningMessageProducer.setOutputChannel(routerChannel); - cacheListeningMessageProducer.setPayloadExpression( - properties.getEventExpression()); - return cacheListeningMessageProducer; - } - - @ConditionalOnProperty(prefix = "geode.supplier", name = "query") - static class CQConfiguration { - @Bean - MessageProducer continuousQueryListener( - MessageChannel routerChannel, - ContinuousQueryListenerContainer continuousQueryListenerContainer, - GeodeSupplierProperties properties) { - ContinuousQueryMessageProducer continuousQueryMessageProducer = new ContinuousQueryMessageProducer( - continuousQueryListenerContainer, - properties.getQuery()); - continuousQueryMessageProducer.setPayloadExpression(properties.getEventExpression()); - continuousQueryMessageProducer.setOutputChannel(routerChannel); - return continuousQueryMessageProducer; - } - - @Bean - ContinuousQueryListenerContainer continuousQueryListenerContainer(ClientCache clientCache) { - ContinuousQueryListenerContainer continuousQueryListenerContainer = new ContinuousQueryListenerContainer(); - try { - continuousQueryListenerContainer.setCache(clientCache); - } - catch (Exception e) { - throw new BeanCreationException(e.getLocalizedMessage(), e); - } - return continuousQueryListenerContainer; - } - } - - static class CQNotEnabled implements Condition { - - @Override - public boolean matches(ConditionContext context, AnnotatedTypeMetadata metadata) { - return StringUtils.isEmpty(context.getEnvironment().getProperty("geode.supplier.query")); - } - } -} diff --git a/functions/supplier/geode-supplier/src/main/java/org/springframework/cloud/fn/supplier/geode/GeodeSupplierProperties.java b/functions/supplier/geode-supplier/src/main/java/org/springframework/cloud/fn/supplier/geode/GeodeSupplierProperties.java deleted file mode 100644 index 9e08f86e..00000000 --- a/functions/supplier/geode-supplier/src/main/java/org/springframework/cloud/fn/supplier/geode/GeodeSupplierProperties.java +++ /dev/null @@ -1,61 +0,0 @@ -/* - * Copyright 2020-2020 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.supplier.geode; - -import org.springframework.boot.context.properties.ConfigurationProperties; -import org.springframework.expression.Expression; -import org.springframework.expression.spel.standard.SpelExpressionParser; - -/** - * This represents the configuration properties for the Gemfire Supplier. - * - * @author David Turanski - */ -@ConfigurationProperties("geode.supplier") -public class GeodeSupplierProperties { - - private static final String DEFAULT_EXPRESSION = "newValue"; - - private final SpelExpressionParser parser = new SpelExpressionParser(); - - /** - * SpEL expression to extract data from an {@link org.apache.geode.cache.EntryEvent} or - * {@link org.apache.geode.cache.query.CqEvent}. - */ - private Expression eventExpression = parser.parseExpression(DEFAULT_EXPRESSION); - - /** - * An OQL query. This will enable continuous query if provided. - */ - private String query; - - public Expression getEventExpression() { - return eventExpression; - } - - public void setEventExpression(Expression eventExpression) { - this.eventExpression = eventExpression; - } - - public String getQuery() { - return query; - } - - public void setQuery(String query) { - this.query = query; - } -} diff --git a/functions/supplier/geode-supplier/src/main/resources/geode-client.properties b/functions/supplier/geode-supplier/src/main/resources/geode-client.properties deleted file mode 100644 index d4de889e..00000000 --- a/functions/supplier/geode-supplier/src/main/resources/geode-client.properties +++ /dev/null @@ -1,4 +0,0 @@ -# -# Geode client pool must be configured with subscriptions enabled for this component. -# -geode.pool.subscriptionEnabled=true diff --git a/functions/supplier/geode-supplier/src/test/java/org/springframework/cloud/fn/supplier/geode/GeodeSupplierApplicationTests.java b/functions/supplier/geode-supplier/src/test/java/org/springframework/cloud/fn/supplier/geode/GeodeSupplierApplicationTests.java deleted file mode 100644 index e07e0816..00000000 --- a/functions/supplier/geode-supplier/src/test/java/org/springframework/cloud/fn/supplier/geode/GeodeSupplierApplicationTests.java +++ /dev/null @@ -1,176 +0,0 @@ -/* - * Copyright 2020-2020 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.supplier.geode; - -import java.io.IOException; -import java.time.Duration; -import java.util.function.Supplier; - -import com.fasterxml.jackson.core.JsonProcessingException; -import com.fasterxml.jackson.databind.ObjectMapper; -import lombok.AllArgsConstructor; -import lombok.Data; -import lombok.NoArgsConstructor; -import org.apache.geode.cache.EntryEvent; -import org.apache.geode.cache.Region; -import org.apache.geode.pdx.PdxInstance; -import org.junit.jupiter.api.AfterAll; -import org.junit.jupiter.api.BeforeAll; -import org.junit.jupiter.api.Tag; -import org.junit.jupiter.api.Test; -import reactor.core.publisher.Flux; -import reactor.test.StepVerifier; - -import org.springframework.boot.autoconfigure.SpringBootApplication; -import org.springframework.boot.test.context.runner.ApplicationContextRunner; -import org.springframework.cloud.fn.common.geode.JsonPdxFunctions; -import org.springframework.cloud.fn.supplier.geodeserver.GeodeServerTestConfiguration; -import org.springframework.data.gemfire.tests.integration.ForkingClientServerIntegrationTestsSupport; - -import static org.assertj.core.api.Assertions.assertThat; -import static org.assertj.core.api.Assertions.fail; - -@Tag("integration") -public class GeodeSupplierApplicationTests { - - private static ApplicationContextRunner applicationContextRunner; - - private final ObjectMapper objectMapper = new ObjectMapper(); - - @BeforeAll - static void setup() throws IOException { - ForkingClientServerIntegrationTestsSupport.startGemFireServer( - GeodeServerTestConfiguration.class); - - applicationContextRunner = new ApplicationContextRunner() - .withUserConfiguration(GeodeSupplierTestApplication.class); - } - - @AfterAll - static void stopServer() { - ForkingClientServerIntegrationTestsSupport.stopGemFireServer(); - ForkingClientServerIntegrationTestsSupport.clearCacheServerPortAndPoolPortProperties(); - } - - @Test - void getServerEntryEvents() { - applicationContextRunner - .withPropertyValues("geode.region.regionName=myRegion", - "geode.supplier.event-expression=#root", - "geode.pool.connectType=server", - "geode.pool.hostAddresses=" + "localhost:" + System.getProperty("spring.data.gemfire.cache.server.port")) - .run(context -> { - Region region = context.getBean(Region.class); - region.put("hello", "world"); - region.put("foo", "bar"); - region.replace("hello", "dave"); - - Supplier> geodeSupplier = context.getBean("geodeSupplier", Supplier.class); - - StepVerifier.create(geodeSupplier.get()).assertNext(cacheEvent -> { - assertThat(cacheEvent.getOperation().isCreate()).isTrue(); - assertThat(cacheEvent.getKey()).isEqualTo("hello"); - assertThat(cacheEvent.getNewValue()).isEqualTo("world"); - }).assertNext(cacheEvent -> { - assertThat(cacheEvent.getOperation().isCreate()).isTrue(); - assertThat(cacheEvent.getKey()).isEqualTo("foo"); - assertThat(cacheEvent.getNewValue()).isEqualTo("bar"); - }).assertNext(cacheEvent -> { - assertThat(cacheEvent.getOperation().isUpdate()).isTrue(); - assertThat(cacheEvent.getKey()).isEqualTo("hello"); - assertThat(cacheEvent.getNewValue()).isEqualTo("dave"); - - }).thenCancel().verify(Duration.ofSeconds(10)); - }); - } - - @Test - void pdxReadSerialized() { - applicationContextRunner - .withPropertyValues( - "geode.region.regionName=myRegion", - "geode.client.pdx-read-serialized=true", - "geode.pool.connectType=server", - "geode.pool.hostAddresses=" + "localhost:" + System.getProperty("spring.data.gemfire.cache.server.port")) - .run(context -> { - Supplier> geodeSupplier = context.getBean("geodeSupplier", Supplier.class); - // Using local region here - Region region = context.getBean(Region.class); - Stock stock = new Stock("XXX", 140.00); - ObjectMapper objectMapper = new ObjectMapper(); - String json = objectMapper.writeValueAsString(stock); - region.put(stock.getSymbol(), JsonPdxFunctions.jsonToPdx().apply(json)); - - StepVerifier.create(geodeSupplier.get()).assertNext(val -> { - try { - assertThat(objectMapper.readValue(val, Stock.class)).isEqualTo(stock); - } - catch (JsonProcessingException e) { - fail(e.getMessage()); - } - }).thenCancel().verify(Duration.ofSeconds(10)); - }); - } - - @Test - void continuousQuery() { - applicationContextRunner - .withPropertyValues( - "geode.region.regionName=myRegion", - "geode.client.pdx-read-serialized=true", - "geode.supplier.query=Select * from /myRegion where symbol='XXX' and price > 140", - "geode.pool.connectType=server", - "geode.pool.hostAddresses=" + "localhost:" + System.getProperty("spring.data.gemfire.cache.server.port")) - .run(context -> { - Supplier> geodeCqSupplier = context.getBean("geodeSupplier", Supplier.class); - // Using local region here - Region region = context.getBean(Region.class); - putStockEvent(region, new Stock("XXX", 140.00)); - putStockEvent(region, new Stock("XXX", 140.20)); - putStockEvent(region, new Stock("YYY", 110.00)); - putStockEvent(region, new Stock("YYY", 110.01)); - putStockEvent(region, new Stock("XXX", 139.80)); - - StepVerifier.create(geodeCqSupplier.get()).assertNext(val -> { - try { - assertThat(objectMapper.readValue(val, Stock.class)).isEqualTo(new Stock("XXX", 140.20)); - } - catch (JsonProcessingException e) { - fail(e.getMessage()); - } - }).thenCancel().verify(Duration.ofSeconds(10)); - }); - } - - private void putStockEvent(Region region, Stock stock) throws JsonProcessingException { - String json = objectMapper.writeValueAsString(stock); - region.put(stock.getSymbol(), JsonPdxFunctions.jsonToPdx().apply(json)); - } - - @Data - @AllArgsConstructor - @NoArgsConstructor - static class Stock { - private String symbol; - - private double price; - } - - @SpringBootApplication - static class GeodeSupplierTestApplication { - } -} diff --git a/functions/supplier/geode-supplier/src/test/java/org/springframework/cloud/fn/supplier/geodeserver/GeodeServerTestConfiguration.java b/functions/supplier/geode-supplier/src/test/java/org/springframework/cloud/fn/supplier/geodeserver/GeodeServerTestConfiguration.java deleted file mode 100644 index f517b42e..00000000 --- a/functions/supplier/geode-supplier/src/test/java/org/springframework/cloud/fn/supplier/geodeserver/GeodeServerTestConfiguration.java +++ /dev/null @@ -1,47 +0,0 @@ -/* - * Copyright 2020-2020 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.supplier.geodeserver; - -import org.apache.geode.cache.GemFireCache; -import org.apache.geode.cache.Scope; - -import org.springframework.context.annotation.AnnotationConfigApplicationContext; -import org.springframework.context.annotation.Bean; -import org.springframework.data.gemfire.ReplicatedRegionFactoryBean; -import org.springframework.data.gemfire.config.annotation.CacheServerApplication; - -@CacheServerApplication -public class GeodeServerTestConfiguration { - - public static void main(String[] args) { - - AnnotationConfigApplicationContext applicationContext = - new AnnotationConfigApplicationContext(GeodeServerTestConfiguration.class); - - applicationContext.registerShutdownHook(); - } - - @Bean("myRegion") - public ReplicatedRegionFactoryBean myRegion(GemFireCache gemfireCache) { - - ReplicatedRegionFactoryBean regionFactoryBean = new ReplicatedRegionFactoryBean<>(); - regionFactoryBean.setScope(Scope.DISTRIBUTED_ACK); - regionFactoryBean.setCache(gemfireCache); - - return regionFactoryBean; - } -} diff --git a/functions/supplier/geode-supplier/src/test/resources/logback-include.xml b/functions/supplier/geode-supplier/src/test/resources/logback-include.xml deleted file mode 100644 index ae330ab3..00000000 --- a/functions/supplier/geode-supplier/src/test/resources/logback-include.xml +++ /dev/null @@ -1,16 +0,0 @@ - - - - - - %d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n - - - - - - - - - - diff --git a/functions/supplier/pom.xml b/functions/supplier/pom.xml index 34cd96ff..53edf497 100644 --- a/functions/supplier/pom.xml +++ b/functions/supplier/pom.xml @@ -13,7 +13,6 @@ file-supplier ftp-supplier - geode-supplier http-supplier jdbc-supplier jms-supplier diff --git a/functions/supplier/sftp-supplier/src/main/java/org/springframework/cloud/fn/supplier/sftp/SftpSupplierConfiguration.java b/functions/supplier/sftp-supplier/src/main/java/org/springframework/cloud/fn/supplier/sftp/SftpSupplierConfiguration.java index 5d537096..67b118c8 100644 --- a/functions/supplier/sftp-supplier/src/main/java/org/springframework/cloud/fn/supplier/sftp/SftpSupplierConfiguration.java +++ b/functions/supplier/sftp-supplier/src/main/java/org/springframework/cloud/fn/supplier/sftp/SftpSupplierConfiguration.java @@ -23,7 +23,7 @@ import java.util.function.Supplier; import java.util.regex.Pattern; import java.util.stream.Stream; -import com.jcraft.jsch.ChannelSftp.LsEntry; +import org.apache.sshd.sftp.client.SftpClient; import org.reactivestreams.Publisher; import reactor.core.publisher.Flux; import reactor.core.publisher.MonoProcessor; @@ -84,6 +84,7 @@ import org.springframework.util.StringUtils; * @author Chris Schaefer * @author Christian Tzolov * @author David Turanski + * @author Corneil du Plessis */ @Configuration @@ -140,10 +141,12 @@ public class SftpSupplierConfiguration { * Configure the standard filters for SFTP inbound adapters. */ @Bean - public FileListFilter chainFilter(SftpSupplierProperties sftpSupplierProperties, - ConcurrentMetadataStore metadataStore) { + public FileListFilter chainFilter( + SftpSupplierProperties sftpSupplierProperties, + ConcurrentMetadataStore metadataStore + ) { - ChainFileListFilter chainFilter = new ChainFileListFilter<>(); + ChainFileListFilter chainFilter = new ChainFileListFilter<>(); if (StringUtils.hasText(sftpSupplierProperties.getFilenamePattern())) { chainFilter.addFilter(new SftpSimplePatternFileListFilter(sftpSupplierProperties.getFilenamePattern())); @@ -192,7 +195,7 @@ public class SftpSupplierConfiguration { @Bean public MessageSource targetMessageSource(SftpRemoteFileTemplate sftpTemplate, SftpSupplierProperties sftpSupplierProperties, - FileListFilter fileListFilter) { + FileListFilter fileListFilter) { return Sftp.inboundStreamingAdapter(sftpTemplate) .remoteDirectory(remoteDirectory(sftpSupplierProperties)) @@ -279,7 +282,7 @@ public class SftpSupplierConfiguration { @Bean public SftpInboundChannelAdapterSpec targetMessageSource(SftpSupplierProperties sftpSupplierProperties, SftpSupplierFactoryConfiguration.DelegatingFactoryWrapper delegatingFactoryWrapper, - FileListFilter fileListFilter) { + FileListFilter fileListFilter) { return Sftp .inboundAdapter(delegatingFactoryWrapper.getFactory()) @@ -377,13 +380,13 @@ public class SftpSupplierConfiguration { public MessageProcessor> lsEntryToStringTransformer() { return (Message message) -> { - LsEntry lsEntry = (LsEntry) message.getPayload(); + SftpClient.DirEntry dirEntry = (SftpClient.DirEntry) message.getPayload(); - String fileName = message.getHeaders().get(FileHeaders.REMOTE_DIRECTORY) + lsEntry.getFilename(); + String fileName = message.getHeaders().get(FileHeaders.REMOTE_DIRECTORY) + dirEntry.getFilename(); return MessageBuilder.withPayload(fileName) .copyHeaders(message.getHeaders()) - .setHeader(FILE_MODIFIED_TIME_HEADER, String.valueOf(lsEntry.getAttrs().getMTime())) + .setHeader(FILE_MODIFIED_TIME_HEADER, String.valueOf(dirEntry.getAttributes().getModifyTime())) .setHeader(MessageHeaders.CONTENT_TYPE, MediaType.TEXT_PLAIN) .build(); }; @@ -415,13 +418,13 @@ public class SftpSupplierConfiguration { private final String remoteDirectory; - private final SessionFactory sessionFactory; + private final SessionFactory sessionFactory; private final String remoteFileSeparator; private final SftpSupplierProperties.SortSpec sort; - SftpListingMessageProducer(SessionFactory sessionFactory, String remoteDirectory, + SftpListingMessageProducer(SessionFactory sessionFactory, String remoteDirectory, String remoteFileSeparator, SftpSupplierProperties.SortSpec sort) { this.sessionFactory = sessionFactory; @@ -431,10 +434,10 @@ public class SftpSupplierConfiguration { } public void listNames() { - Stream stream; + Stream stream; try { stream = Stream.of(this.sessionFactory.getSession().list(this.remoteDirectory)) - .filter(x -> !(x.getAttrs().isDir() || x.getAttrs().isLink())); + .filter(x -> !(x.getAttributes().isDirectory() || x.getAttributes().isSymbolicLink())); if (sort != null) { stream = stream.sorted(sort.comparator()); diff --git a/functions/supplier/sftp-supplier/src/main/java/org/springframework/cloud/fn/supplier/sftp/SftpSupplierFactoryConfiguration.java b/functions/supplier/sftp-supplier/src/main/java/org/springframework/cloud/fn/supplier/sftp/SftpSupplierFactoryConfiguration.java index 868617fb..3068bb6d 100644 --- a/functions/supplier/sftp-supplier/src/main/java/org/springframework/cloud/fn/supplier/sftp/SftpSupplierFactoryConfiguration.java +++ b/functions/supplier/sftp-supplier/src/main/java/org/springframework/cloud/fn/supplier/sftp/SftpSupplierFactoryConfiguration.java @@ -19,7 +19,7 @@ package org.springframework.cloud.fn.supplier.sftp; import java.util.HashMap; import java.util.Map; -import com.jcraft.jsch.ChannelSftp.LsEntry; +import org.apache.sshd.sftp.client.SftpClient; import org.springframework.beans.factory.BeanFactory; import org.springframework.beans.factory.DisposableBean; @@ -40,19 +40,20 @@ import org.springframework.lang.Nullable; * @author Gary Russell * @author Artem Bilan * @author David Turanski + * @author Corneil du Plessis * */ public class SftpSupplierFactoryConfiguration { @Bean @ConditionalOnMissingBean - public SessionFactory sftpSessionFactory(SftpSupplierProperties properties, BeanFactory beanFactory) { + public SessionFactory sftpSessionFactory(SftpSupplierProperties properties, BeanFactory beanFactory) { return buildFactory(beanFactory, properties.getFactory()); } @Bean public DelegatingFactoryWrapper delegatingFactoryWrapper(SftpSupplierProperties properties, - SessionFactory defaultFactory, BeanFactory beanFactory) { + SessionFactory defaultFactory, BeanFactory beanFactory) { return new DelegatingFactoryWrapper(properties, defaultFactory, beanFactory); } @@ -73,7 +74,7 @@ public class SftpSupplierFactoryConfiguration { : null; } - static SessionFactory buildFactory(BeanFactory beanFactory, SftpSupplierProperties.Factory factory) { + static SessionFactory buildFactory(BeanFactory beanFactory, SftpSupplierProperties.Factory factory) { DefaultSftpSessionFactory sftpSessionFactory = new DefaultSftpSessionFactory(true); sftpSessionFactory.setHost(factory.getHost()); sftpSessionFactory.setPort(factory.getPort()); @@ -93,11 +94,11 @@ public class SftpSupplierFactoryConfiguration { public final static class DelegatingFactoryWrapper implements DisposableBean { - private final DelegatingSessionFactory delegatingSessionFactory; + private final DelegatingSessionFactory delegatingSessionFactory; - private final Map> factories = new HashMap<>(); + private final Map> factories = new HashMap<>(); - DelegatingFactoryWrapper(SftpSupplierProperties properties, SessionFactory defaultFactory, + DelegatingFactoryWrapper(SftpSupplierProperties properties, SessionFactory defaultFactory, BeanFactory beanFactory) { properties.getFactories().forEach((key, factory) -> { this.factories.put(key, SftpSupplierFactoryConfiguration.buildFactory(beanFactory, factory)); @@ -105,7 +106,7 @@ public class SftpSupplierFactoryConfiguration { this.delegatingSessionFactory = new DelegatingSessionFactory<>(this.factories, defaultFactory); } - public DelegatingSessionFactory getFactory() { + public DelegatingSessionFactory getFactory() { return this.delegatingSessionFactory; } diff --git a/functions/supplier/sftp-supplier/src/main/java/org/springframework/cloud/fn/supplier/sftp/SftpSupplierProperties.java b/functions/supplier/sftp-supplier/src/main/java/org/springframework/cloud/fn/supplier/sftp/SftpSupplierProperties.java index 547e3ec3..f81f4904 100644 --- a/functions/supplier/sftp-supplier/src/main/java/org/springframework/cloud/fn/supplier/sftp/SftpSupplierProperties.java +++ b/functions/supplier/sftp-supplier/src/main/java/org/springframework/cloud/fn/supplier/sftp/SftpSupplierProperties.java @@ -25,11 +25,11 @@ import java.util.List; import java.util.Map; import java.util.regex.Pattern; -import com.jcraft.jsch.ChannelSftp; import jakarta.validation.Valid; import jakarta.validation.constraints.AssertTrue; import jakarta.validation.constraints.NotBlank; import jakarta.validation.constraints.NotNull; +import org.apache.sshd.sftp.client.SftpClient; import org.hibernate.validator.constraints.Range; import org.springframework.boot.context.properties.ConfigurationProperties; @@ -44,6 +44,7 @@ import org.springframework.validation.annotation.Validated; * @author Artem Bilan * @author Chris Schaefer * @author David Turanski + * @author Corneil du Plessis */ @ConfigurationProperties("sftp.supplier") @Validated @@ -495,21 +496,21 @@ public class SftpSupplierProperties { DESC } - private Comparator getAttributeComparator() { + private Comparator getAttributeComparator() { switch (attribute) { case FILENAME: - return Comparator.comparing(ChannelSftp.LsEntry::getFilename); + return Comparator.comparing(SftpClient.DirEntry::getFilename); case ATIME: - return Comparator.comparing(x -> x.getAttrs().getATime()); + return Comparator.comparing(x -> x.getAttributes().getAccessTime()); case MTIME: - return Comparator.comparing(x -> x.getAttrs().getMTime()); + return Comparator.comparing(x -> x.getAttributes().getModifyTime()); } throw new UnsupportedOperationException("Unsupported sortBy attribute: " + attribute); } - public Comparator comparator() { - Comparator comparator = getAttributeComparator(); + public Comparator comparator() { + Comparator comparator = getAttributeComparator(); return dir == Dir.ASC ? comparator : comparator.reversed(); } }