diff --git a/pom.xml b/pom.xml index ba0b9671..06ac6e77 100644 --- a/pom.xml +++ b/pom.xml @@ -34,10 +34,12 @@ spring-libs-snapshot https://repo.spring.io/libs-snapshot + @@ -243,6 +245,7 @@ + diff --git a/src/main/asciidoc/reference/bootstrap-annotations-quickstart.adoc b/src/main/asciidoc/reference/bootstrap-annotations-quickstart.adoc index f7377850..b6dce8c5 100644 --- a/src/main/asciidoc/reference/bootstrap-annotations-quickstart.adoc +++ b/src/main/asciidoc/reference/bootstrap-annotations-quickstart.adoc @@ -627,20 +627,21 @@ See {sdg-javadoc}/org/springframework/data/gemfire/listener/annotation/Continuou See <> and <> for more details. [[bootstap-annotations-quickstart-gatewayreceiver]] -== Configure Gateway Receivers +== Configure `GatewayReceivers` -The replication of data between different {data-store-name} clusters is an increasingly important fault-tolerance and high availability mechanism. -{data-store-name} WAN Replication is a mechanism that allows one {data-store-name} cluster to replicate its data to another -{data-store-name} cluster in a reliable, fault-tolerant manner. +The replication of data between different {data-store-name} clusters is an increasingly important fault-tolerance +and high availability mechanism. {data-store-name} WAN Replication is a mechanism that allows one {data-store-name} +cluster to replicate its data to another {data-store-name} cluster in a reliable, fault-tolerant manner. {data-store-name} WAN replication requires two components to be configured: -* Gateway Receiver - The WAN replication component that receives data from a remote {data-store-name} cluster's Gateway Sender -* Gateway Senders - The WAN replication component that sends data to a remote {data-store-name} cluster's Gateway Receiver -To enable a Gateway Receiver the application class needs to be annotated with `@EnableGatewayReceiver` as follows: +* `GatewayReceiver` - The WAN replication component that receives data from a remote {data-store-name} cluster's `GatewaySender`. +* `GatewaySender` - The WAN replication component that sends data to a remote {data-store-name} cluster's `GatewayReceiver`. + +To enable a `GatewayReceiver`, the application class needs to be annotated with `@EnableGatewayReceiver` as follows: + [source,java] ---- -@Configuration @CacheServerApplication @EnableGatewayReceiver(manualStart = false, startPort = 10000, endPort = 11000, maximumTimeBetweenPings = 1000, socketBufferSize = 16384, bindAddress = "localhost",transportFilters = {"transportBean1", "transportBean2"}, @@ -649,17 +650,22 @@ To enable a Gateway Receiver the application class needs to be annotated with `@ ... } } +class MySpringApplication { .. } ---- -NOTE: {data-store-name} GatewayReceiver is a server-side feature only and can only be configured on a CacheServer or PeerServer + +NOTE: {data-store-name} `GatewayReceiver` is a server-side feature only and can only be configured on a `CacheServer` +or peer `Cache` node. See {sdg-javadoc}/org/springframework/data/gemfire/wan/annotation/EnableGatewayReceiver.html[`@EnableGatewayReceiver` Javadoc]. [[bootstap-annotations-quickstart-gatewaysenders]] +== Configure `GatewaySenders` + +To enable `GatewaySender`, the application class needs to be annotated with `@EnableGatewaySenders` +and `@EnableGatewaySender` as follows: -To enable Gateway Senders in the application class needs to be annotated with `@EnableGatewaySenders` and `@EnableGatewaySender` as follows: [source,java] ---- -@Configuration @CacheServerApplication @EnableGatewaySenders(gatewaySenders = { @EnableGatewaySender(name = "GatewaySender", manualStart = true, @@ -677,16 +683,25 @@ To enable Gateway Senders in the application class needs to be annotated with `@ maximumQueueMemory = 400, socketBufferSize = 16384,socketReadTimeout = 4000, regions = { "Region2" }) }){ -.... +class MySpringApplication { .. } } ---- -NOTE: {data-store-name} GatewaySender is a server-side feature only and can only be configured on a CacheServer or PeerServer +NOTE: {data-store-name} `GatewaySender` is a server-side feature only and can only be configured on a `CacheServer` +or a peer `Cache` node. -In the above example, the application is configured with 2 Regions, `Region1` and `Region2`. In addition 2 GatewaySenders will be configured for service both Regions. `GatewaySender1` will be configured to replicate `Region1`'s data and `GatewaySender2` will be configured to replicate `Region2`'s data. As demonstrated each GatewaySender property can be configured on each `EnableGatewaySender` annotation. +In the above example, the application is configured with 2 Regions, `Region1` and `Region2`. In addition, +two `GatewaySenders` will be configured to service both Regions. `GatewaySender1` will be configured to replicate +`Region1`'s data and `GatewaySender2` will be configured to replicate `Region2`'s data. + +As demonstrated each `GatewaySender` property can be configured on each `EnableGatewaySender` annotation. + +It is also possible to have a more generic, "defaulted" properties approach, where all properties are configured on +the `EnableGatewaySenders` annotation. This way, a set of generic, defaulted values can be set on the parent annotation +and then overridden on the child if required, as demonstrated below: -It is also possible to have a more generic, "defaulted" properties approach, where all properties are configured on the `EnableGatewaySenders` annotation. This way a set of generic, defaulted values can be set on the parent annotation and then overridden on the child if required, as demonstrated below: [source,java] ---- +@CacheServerApplication @EnableGatewaySenders(gatewaySenders = { @EnableGatewaySender(name = "GatewaySender", transportFilters = "transportBean1", regions = "Region2"), @EnableGatewaySender(name = "GatewaySender2")}, @@ -696,9 +711,11 @@ It is also possible to have a more generic, "defaulted" properties approach, whe eventFilters = "SomeEventFilter", batchTimeInterval = 2000, dispatcherThreads = 22, maximumQueueMemory = 400, socketBufferSize = 16384, socketReadTimeout = 4000, regions = { "Region1", "Region2" }, transportFilters = { "transportBean2", "transportBean1" }) +class MySpringApplication { .. } ---- -NOTE: When the `regions` property is left empty or not populated, the GatewaySender(s) will automatically attach itself to every -configured Region within the application +NOTE: When the `regions` attribute is left empty or not populated, the `GatewaySender`(s) will automatically attach +itself to every configured `Region` within the application. -See {sdg-javadoc}/org/springframework/data/gemfire/wan/annotation/EnableGatewaySenders.html[`@EnableGatewaySenders` Javadoc] and {sdg-javadoc}/org/springframework/data/gemfire/wan/annotation/EnableGatewaySender.html[`@EnableGatewaySender` Javadoc]. \ No newline at end of file +See {sdg-javadoc}/org/springframework/data/gemfire/wan/annotation/EnableGatewaySenders.html[`@EnableGatewaySenders` Javadoc] +and {sdg-javadoc}/org/springframework/data/gemfire/wan/annotation/EnableGatewaySender.html[`@EnableGatewaySender` Javadoc]. diff --git a/src/main/java/org/springframework/data/gemfire/config/annotation/EnableGatewaySender.java b/src/main/java/org/springframework/data/gemfire/config/annotation/EnableGatewaySender.java index 2c0ed6fc..5a7c907a 100644 --- a/src/main/java/org/springframework/data/gemfire/config/annotation/EnableGatewaySender.java +++ b/src/main/java/org/springframework/data/gemfire/config/annotation/EnableGatewaySender.java @@ -1,5 +1,21 @@ +/* + * Copyright 2010-2019 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ package org.springframework.data.gemfire.config.annotation; +import java.lang.annotation.Annotation; import java.lang.annotation.Documented; import java.lang.annotation.ElementType; import java.lang.annotation.Inherited; @@ -7,22 +23,38 @@ import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; import java.lang.annotation.Target; +import org.apache.geode.cache.DiskStore; +import org.apache.geode.cache.Region; +import org.apache.geode.cache.server.CacheServer; +import org.apache.geode.cache.wan.GatewayEventFilter; +import org.apache.geode.cache.wan.GatewayEventSubstitutionFilter; +import org.apache.geode.cache.wan.GatewayReceiver; +import org.apache.geode.cache.wan.GatewaySender; +import org.apache.geode.cache.wan.GatewayTransportFilter; + import org.springframework.context.annotation.Import; import org.springframework.data.gemfire.config.support.GatewaySenderBeanFactoryPostProcessor; import org.springframework.data.gemfire.wan.OrderPolicyType; /** - * This annotation is responsible for the configuration of a single {@link org.apache.geode.cache.wan.GatewaySender}. - * All properties configured on this annotation will be be overrides from the defaults set on the {@link EnableGatewaySenders}. + * This {@link Annotation} is responsible for configuring a single {@link GatewaySender}. + * + * All properties set with this annotation override the defaults set on {@link EnableGatewaySenders}. * * @author Udo Kohlmeyer - * @see EnableGatewaySenders - * @see org.apache.geode.cache.wan.GatewaySender - * @see org.apache.geode.cache.wan.GatewayReceiver + * @author John Blum + * @see java.lang.annotation.Annotation + * @see java.lang.annotation.Documented + * @see java.lang.annotation.Inherited + * @see java.lang.annotation.Retention + * @see java.lang.annotation.Target * @see org.apache.geode.cache.wan.GatewayEventFilter - * @see org.apache.geode.cache.wan.GatewayTransportFilter - * @see org.apache.geode.cache.wan.GatewaySender.OrderPolicy * @see org.apache.geode.cache.wan.GatewayEventSubstitutionFilter + * @see org.apache.geode.cache.wan.GatewayReceiver + * @see org.apache.geode.cache.wan.GatewaySender + * @see org.apache.geode.cache.wan.GatewaySender.OrderPolicy + * @see org.apache.geode.cache.wan.GatewayTransportFilter + * @see org.springframework.data.gemfire.config.annotation.EnableGatewaySenders * @since 2.2.0 */ @Target(ElementType.TYPE) @@ -34,172 +66,251 @@ import org.springframework.data.gemfire.wan.OrderPolicyType; public @interface EnableGatewaySender { /** - * This property configures the time, in milliseconds, that an object can be in the queue to be replicated before the - * {@link org.apache.geode.cache.wan.GatewaySender} logs an alert. - *

This property can also be configured using the {@literal spring.data.gemfire.gateway.sender..alert-threshold} - *

Default value is {@link GatewaySenderConfiguration#DEFAULT_ALERT_THRESHOLD} + * Configures the time, in milliseconds, that an object can be in the queue to be replicated before the + * {@link GatewaySender} logs an alert. + * + * Defaults to {@link GatewaySenderConfiguration#DEFAULT_ALERT_THRESHOLD}. + * + * Alternatively use the {@literal spring.data.gemfire.gateway.sender..alert-threshold} property + * in {@literal application.properties}. */ int alertThreshold() default GatewaySenderConfiguration.DEFAULT_ALERT_THRESHOLD; /** - * A boolean flag to indicate if the configured GatewaySender(s) should use conflate entries in each batch. This means, - * that a batch will never contain duplicate entries, as the batch will always only contain the latest value for a key. - *

This property can also be configured using the {@literal spring.data.gemfire.gateway.sender..batch-conflation-enabled} - *

Default value is {@value GatewaySenderConfiguration#DEFAULT_BATCH_CONFLATION_ENABLED} + * A {@literal boolean} flag to indicate if the configured {@link GatewaySender GatewaySenders} should use conflate + * entries in each batch. This means, that a batch will never contain duplicate entries, as the batch will always + * only contain the latest value for a key. + * + * Defaults to {@value GatewaySenderConfiguration#DEFAULT_BATCH_CONFLATION_ENABLED}. + * + * Alternatively use the {@literal spring.data.gemfire.gateway.sender..batch-conflation-enabled} property + * in {@literal application.properties}. */ boolean batchConflationEnabled() default GatewaySenderConfiguration.DEFAULT_BATCH_CONFLATION_ENABLED; /** - * This property configures the maximum batch size that the {@link org.apache.geode.cache.wan.GatewaySender} send to the - * remote site. This property works in conjunction with the {@link EnableGatewaySenders#batchTimeInterval()} setting. - * The {@link org.apache.geode.cache.wan.GatewaySender} will send when either the {@literal batch-size} or {@literal batch-time-interval} - * is met. - *

This property can also be configured using the {@literal spring.data.gemfire.gateway.sender..batch-size} - *

Default value is {@value GatewaySenderConfiguration#DEFAULT_BATCH_SIZE} + * Configures the maximum batch size that the {@link GatewaySender} sends to the remote site. + * + * This property works in conjunction with the {@link EnableGatewaySenders#batchTimeInterval()} setting. + * A {@link GatewaySender} will send when either the {@literal batch-size} or {@literal batch-time-interval} + * is reached. + * + * Defaults to {@value GatewaySenderConfiguration#DEFAULT_BATCH_SIZE}. + * + * Alternatively use the {@literal spring.data.gemfire.gateway.sender..batch-size} property + * in {@literal application.properties}. */ int batchSize() default GatewaySenderConfiguration.DEFAULT_BATCH_SIZE; /** - * This property configures the maximum batch time interval, in milliseconds, that the {@link org.apache.geode.cache.wan.GatewaySender} wait before - * attempting to send a batch of queued object to the remote {@link org.apache.geode.cache.wan.GatewayReceiver}. - *

This property works in conjunction with the {@link EnableGatewaySenders#batchSize()} setting. - * The {@link org.apache.geode.cache.wan.GatewaySender} will send when either the {@literal batch-size} or {@literal batch-time-interval} - * is met. - *

This property can also be configured using the {@literal spring.data.gemfire.gateway.sender..batch-time-interval} - *

Default value is {@value GatewaySenderConfiguration#DEFAULT_BATCH_TIME_INTERVAL} + * Configures the maximum batch time interval in milliseconds that the {@link GatewaySender} waits before + * attempting to send a batch of queued objects to the remote {@link GatewayReceiver}. + * + * This property works in conjunction with the {@link EnableGatewaySenders#batchSize()} setting. + * A {@link GatewaySender} will send when either the {@literal batch-size} or {@literal batch-time-interval} + * is reached. + * + * Defaults to {@value GatewaySenderConfiguration#DEFAULT_BATCH_TIME_INTERVAL}. + * + * Alternatively use the {@literal spring.data.gemfire.gateway.sender..batch-time-interval} property + * in {@literal application.properties}. */ int batchTimeInterval() default GatewaySenderConfiguration.DEFAULT_BATCH_TIME_INTERVAL; /** - * This property configures what {@link org.apache.geode.cache.DiskStore} the GatewaySender(s) are to use when persisting - * the GatewaySender(s) queues. This setting should be set when the {@literal persistent} property is set to {@literal true}. - *

This property can also be configured using the {@literal spring.data.gemfire.gateway.sender..diskstore-reference} - *

Default value is {@value GatewaySenderConfiguration#DEFAULT_DISK_STORE_REFERENCE} + * Configures the {@link DiskStore} used by a {@link }GatewaySender} when persisting the {@link GatewaySender} + * queue's data. + * + * This setting should be set when the {@link EnableGatewaySender#persistent()} property is set to {@literal true}. + * + * Defaults to {@value GatewaySenderConfiguration#DEFAULT_DISK_STORE_REFERENCE}. + * + * Alternatively use the {@literal spring.data.gemfire.gateway.sender..diskstore-reference} property + * in {@literal application.properties}. */ String diskStoreReference() default GatewaySenderConfiguration.DEFAULT_DISK_STORE_REFERENCE; /** - * A boolean flag to indicate if the configured GatewaySender(s) should use synchronous diskstore writes. - *

This property can also be configured using the {@literal spring.data.gemfire.gateway.sender..disk-synchronous} - *

Default value is {@value GatewaySenderConfiguration#DEFAULT_DISK_SYNCHRONOUS} + * A {@literal boolean} flag to indicate if the configured {@link GatewaySender} should use synchronous + * {@link DiskStore} writes. + * + * Defaults to {@value GatewaySenderConfiguration#DEFAULT_DISK_SYNCHRONOUS}. + * + * Alternatively use the {@literal spring.data.gemfire.gateway.sender..disk-synchronous} property + * in {@literal application.properties}. */ boolean diskSynchronous() default GatewaySenderConfiguration.DEFAULT_DISK_SYNCHRONOUS; /** - * This property configures the number of dispatcher threads that the {@link org.apache.geode.cache.wan.GatewaySender} - * will try to use to dispatch the queuing object. - *

This property can also be configured using the {@literal spring.data.gemfire.gateway.sender..dispatcher-threads} - *

Default value is {@value GatewaySenderConfiguration#DEFAULT_DISPATCHER_THREADS} + * Configures the number of dispatcher threads that the {@link GatewaySender} will try to use to dispatch + * the queued events. + * + * Defaults to {@value GatewaySenderConfiguration#DEFAULT_DISPATCHER_THREADS}. + * + * Alternatively use the {@literal spring.data.gemfire.gateway.sender..dispatcher-threads} property + * in {@literal application.properties}. */ int dispatcherThreads() default GatewaySenderConfiguration.DEFAULT_DISPATCHER_THREADS; /** - * A list of {@link org.apache.geode.cache.wan.GatewayEventFilter} to be applied to the {@link org.apache.geode.cache.wan.GatewaySender}. - * {@link org.apache.geode.cache.wan.GatewayEventFilter} are used to filter out objects from the sending queue before dispatching - * them to the remote {@link org.apache.geode.cache.wan.GatewayReceiver}. - *

This property can also be configured using the {@literal spring.data.gemfire.gateway.sender..event-filters} property. - *

Default value is and empty list + * Configures the list of {@link GatewayEventFilter GatewayEventFilters} to be applied to this {@link GatewaySender}. + * + * {@link GatewayEventFilter GatewayEventFilters} are used to filter out objects from the sending queue before + * dispatching them to the remote {@link GatewayReceiver}. + * + * Defaults to empty list. + * + * Alternatively use the {@literal spring.data.gemfire.gateway.sender..event-filters} property + * in {@literal application.properties}. */ String[] eventFilters() default {}; /** - * This property configures the {@link org.apache.geode.cache.wan.GatewayEventSubstitutionFilter} to be used by the GatewaySender(s). - * The {@link org.apache.geode.cache.wan.GatewayEventSubstitutionFilter} is used to replace values on objects before they - * are enqueue for remote replication. - *

This property can also be configured using the {@literal spring.data.gemfire.gateway.sender..event-substitution-filter} - *

Default value is {@link GatewaySenderConfiguration#DEFAULT_EVENT_SUBSTITUTION_FILTER} + * Configures the {@link GatewayEventSubstitutionFilter} used by this {@link GatewaySender}. + * + * The {@link GatewayEventSubstitutionFilter} is used to replace values on objects before they are enqueued + * for remote replication. + * + * Defaults to {@link GatewaySenderConfiguration#DEFAULT_EVENT_SUBSTITUTION_FILTER}. + * + * Alternatively use the {@literal spring.data.gemfire.gateway.sender..event-substitution-filter} property + * in {@literal application.properties}. */ String eventSubstitutionFilter() default GatewaySenderConfiguration.DEFAULT_EVENT_SUBSTITUTION_FILTER; /** - * A boolean to indicate if a configured {@link org.apache.geode.cache.wan.GatewaySender} should be started automatically - *

This property can also be configured using the {@literal spring.data.gemfire.gateway.sender..manual-start} - *

Default is {@value @EnableGatewaySenderConfiguration.DEFAULT_MANUAL_START} + * A {@literal boolean} flag indicating whether the configured {@link GatewaySender} should be started automatically. + * + *

Defaults to {@value @EnableGatewaySenderConfiguration.DEFAULT_MANUAL_START}. + * + * Alternatively use the {@literal spring.data.gemfire.gateway.sender..manual-start} property + * in {@literal application.properties}. */ boolean manualStart() default GatewaySenderConfiguration.DEFAULT_MANUAL_START; /** - * This property configures the maximum size, in MB, that the {@link org.apache.geode.cache.wan.GatewaySender} that the queue - * may take on heap memory, before overflowing to disk. - *

This property can also be configured using the {@literal spring.data.gemfire.gateway.sender..maximum-queue-memory} - *

Default value is {@value GatewaySenderConfiguration#DEFAULT_MAXIMUM_QUEUE_MEMORY} + * Configures the maximum size in megabytes that the {@link GatewaySender GatewaySender's} queue may take in heap + * memory before overflowing to disk. + * + * Defaults to {@value GatewaySenderConfiguration#DEFAULT_MAXIMUM_QUEUE_MEMORY}. + * + * Alternatively use the {@literal spring.data.gemfire.gateway.sender..maximum-queue-memory} property + * in {@literal application.properties}. */ int maximumQueueMemory() default GatewaySenderConfiguration.DEFAULT_MAXIMUM_QUEUE_MEMORY; /** - * Specifies the {@link String name} of the {@link org.apache.geode.cache.wan.GatewaySender}. - * This name is also used as the name of the bean registered in the Spring container as well as the name used in the resolution - * {@link org.apache.geode.cache.wan.GatewaySender} properties from {@literal application.properties} - * (e.g. {@literal spring.data.gemfire.gateway.sender..manual-start}), that are specific to this {@link org.apache.geode.cache.wan.GatewaySender} + * Configures the required {@link String name} of this {@link GatewaySender}. + * + * This name is also used as the name of the bean registered in the Spring Container as well as the name used + * in the resolution of {@link GatewaySender} properties from {@literal application.properties}. + * + * For example, {@literal spring.data.gemfire.gateway.sender..manual-start} that is specific to + * this {@link GatewaySender}. */ String name(); /** - * This property sets the ordering policy that the GatewaySender(s) will use when queueing entries to be replicated to - * a remote {@link org.apache.geode.cache.wan.GatewayReceiver}. + * Configures the ordering policy that this {@link GatewaySender} will use when queueing entries to be replicated to + * a remote {@link GatewayReceiver}. + * *

There are three different ordering policies: + * *

    *
  • {@link OrderPolicyType#KEY} - Order of events preserved on a per key basis
  • *
  • {@link OrderPolicyType#THREAD} - Order of events preserved by the thread that added the event
  • *
  • {@link OrderPolicyType#PARTITION} - Order of events is preserved in order that they arrived in partitioned Region
  • *
- *

This property can also be configured using the {@literal spring.data.gemfire.gateway.sender..order-policy}

- *

Default value is an empty list + * + * Defaults to {@link OrderPolicyType#KEY}. + * + * Alternatively use the {@literal spring.data.gemfire.gateway.sender..order-policy} property + * in {@literal application.properties}. */ OrderPolicyType orderPolicy() default OrderPolicyType.KEY; /** - * A boolean flag to indicate if the configured GatewaySender(s) should use parallel GatewaySender replication. - * Parallel replication means that each {@link org.apache.geode.cache.server.CacheServer} that defines a {@link org.apache.geode.cache.wan.GatewaySender} - * will send data to a remote {@link org.apache.geode.cache.wan.GatewayReceiver}. - *

This property can also be configured using the {@literal spring.data.gemfire.gateway.sender..parallel} - *

Default value is {@value GatewaySenderConfiguration#DEFAULT_PARALLEL} + * A {@literal }boolean} flag indicating whether the configured {@link GatewaySender} should use + * parallel replication. + * + * Parallel replication means that each {@link CacheServer} that defines a {@link GatewaySender} will send data + * to a remote {@link GatewayReceiver}. + * + * Defaults to {@value GatewaySenderConfiguration#DEFAULT_PARALLEL}. + * + * Alternatively use the {@literal spring.data.gemfire.gateway.sender..parallel} property + * in {@literal application.properties}. */ boolean parallel() default GatewaySenderConfiguration.DEFAULT_PARALLEL; /** - * A boolean flag to indicate if the configured GatewaySender(s) should use persistence. This setting should be used - * in conjunction with the {@literal disk-store-reference} property. - *

This property can also be configured using the {@literal spring.data.gemfire.gateway.sender..persistent} - *

Default value is {@value GatewaySenderConfiguration#DEFAULT_PERSISTENT} + * A {@literal boolean} flag indicating whether the configured {@link GatewaySender} should use persistence. + * + * This setting should be used in conjunction with the {@literal disk-store-reference} property. + * + * Defaults to {@value GatewaySenderConfiguration#DEFAULT_PERSISTENT}. + * + * Alternatively use the {@literal spring.data.gemfire.gateway.sender..persistent} property + * in {@literal application.properties}. */ boolean persistent() default GatewaySenderConfiguration.DEFAULT_PERSISTENT; /** - * A list of {@link org.apache.geode.cache.Region} names that are to be configured with {@link org.apache.geode.cache.wan.GatewaySender} replication. - * An empty list will denote that ALL regions are to be replicated to the remote {@link org.apache.geode.cache.wan.GatewayReceiver}. - *

This property can also be configured using the {@literal spring.data.gemfire.gateway.sender..region-names} property. - *

Default value is an empty list + * Configures the list of {@link Region} names that will be configured with this {@link GatewaySender} + * for replication. + * + * An empty list denotes that ALL {@link Region Regions} are to be replicated to the remote {@link GatewayReceiver}. + * + * Defaults to empty list. + * + * Alternatively use the {@literal spring.data.gemfire.gateway.sender..region-names} property + * in {@literal application.properties}. */ String[] regions() default {}; /** - * The id of the distributed system (cluster) that the GatewaySender(s) would send their data to. - *

This property can also be configured using the {@literal spring.data.gemfire.gateway.sender..remote-distributed-system-id} - *

Default is {@value @EnableGatewaySenderConfiguration.DEFAULT_REMOTE_DISTRIBUTED_SYSTEM_ID} + * Configures the id of the remote distributed system (cluster) that this {@link GatewaySender} will send + * its data to. + * + * Defaults to {@value @EnableGatewaySenderConfiguration.DEFAULT_REMOTE_DISTRIBUTED_SYSTEM_ID}. + * + * Alternatively use the {@literal spring.data.gemfire.gateway.sender..remote-distributed-system-id} property + * in {@literal application.properties}. */ int remoteDistributedSystemId() default GatewaySenderConfiguration.DEFAULT_REMOTE_DISTRIBUTED_SYSTEM_ID; /** - * The socket buffer size for the {@link org.apache.geode.cache.wan.GatewaySender}. This setting is in bytes. - *

This property can also be configured using the {@literal spring.data.gemfire.gateway.sender..socket-buffer-size} property. - *

Default value is {@value GatewaySenderConfiguration#DEFAULT_SOCKET_BUFFER_SIZE} + * Configures the socket buffer size in bytes for this {@link GatewaySender}. + * + * Defaults to {@value GatewaySenderConfiguration#DEFAULT_SOCKET_BUFFER_SIZE}. + * + * Alternatively use the {@literal spring.data.gemfire.gateway.sender..socket-buffer-size} property + * in {@literal application.properties}. */ int socketBufferSize() default GatewaySenderConfiguration.DEFAULT_SOCKET_BUFFER_SIZE; /** - * Amount of time in milliseconds that the gateway sender will wait to receive an acknowledgment from a remote site. - * By default this is set to 0, which means there is no timeout. The minimum allowed timeout is 30000 (milliseconds). - *

This property can also be configured using the {@literal spring.data.gemfire.gateway.sender..socket-read-timeout} property. - *

Default value is {@value GatewaySenderConfiguration#DEFAULT_SOCKET_READ_TIMEOUT} + * Configures the amount of time in milliseconds that this {@link GatewaySender} will wait to receive + * an acknowledgment from a remote site. + * + * By default this is set to {@literal 0}, which means there is no timeout. The minimum allowed timeout + * is {@literal 30000 (milliseconds)}. + * + * Defaults to {@value GatewaySenderConfiguration#DEFAULT_SOCKET_READ_TIMEOUT}. + * + * Alternatively use the {@literal spring.data.gemfire.gateway.sender..socket-read-timeout} property + * in {@literal application.properties}. */ int socketReadTimeout() default GatewaySenderConfiguration.DEFAULT_SOCKET_READ_TIMEOUT; /** - * An in-order list of {@link org.apache.geode.cache.wan.GatewayTransportFilter} to be applied to - * {@link org.apache.geode.cache.wan.GatewaySender} - *

This property can also be configured using the {@literal spring.data.gemfire.gateway.sender..transport-filters}s property - *

Default value is an empty list + * Configures an in-order list of {@link GatewayTransportFilter} objects to be applied to this {@link GatewaySender}. + * + * Defaults to empty list. + * + * Alternatively use the {@literal spring.data.gemfire.gateway.sender..transport-filters} property + * in {@literal application.properties}. */ String[] transportFilters() default {}; + } diff --git a/src/main/java/org/springframework/data/gemfire/config/annotation/EnableGatewaySenders.java b/src/main/java/org/springframework/data/gemfire/config/annotation/EnableGatewaySenders.java index 4be7ce8d..c99ca775 100644 --- a/src/main/java/org/springframework/data/gemfire/config/annotation/EnableGatewaySenders.java +++ b/src/main/java/org/springframework/data/gemfire/config/annotation/EnableGatewaySenders.java @@ -1,5 +1,21 @@ +/* + * Copyright 2010-2019 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ package org.springframework.data.gemfire.config.annotation; +import java.lang.annotation.Annotation; import java.lang.annotation.Documented; import java.lang.annotation.ElementType; import java.lang.annotation.Inherited; @@ -7,22 +23,39 @@ import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; import java.lang.annotation.Target; +import org.apache.geode.cache.DiskStore; +import org.apache.geode.cache.Region; +import org.apache.geode.cache.server.CacheServer; +import org.apache.geode.cache.wan.GatewayEventFilter; +import org.apache.geode.cache.wan.GatewayEventSubstitutionFilter; +import org.apache.geode.cache.wan.GatewayReceiver; +import org.apache.geode.cache.wan.GatewaySender; +import org.apache.geode.cache.wan.GatewayTransportFilter; + import org.springframework.context.annotation.Import; import org.springframework.data.gemfire.config.support.GatewaySenderBeanFactoryPostProcessor; import org.springframework.data.gemfire.wan.OrderPolicyType; /** - * This annotation is responsible for the configuration of {@link org.apache.geode.cache.wan.GatewaySender}. - * All properties configured on this annotation will be used as default value for all {@link org.apache.geode.cache.wan.GatewaySender} - * configured within the gatewaySenders property. + * This {@link Annotation} is responsible for the configuration of multiple {@link GatewaySender GatewaySenders}. + * + * All properties set with this {@link Annotation} will be used as the default values for all + * {@link GatewaySender GatewaySenders} configured within the gatewaySenders property. * * @author Udo Kohlmeyer - * @see org.apache.geode.cache.wan.GatewaySender - * @see org.apache.geode.cache.wan.GatewayReceiver + * @author John Blum + * @see java.lang.annotation.Annotation + * @see java.lang.annotation.Documented + * @see java.lang.annotation.Inherited + * @see java.lang.annotation.Retention + * @see java.lang.annotation.Target * @see org.apache.geode.cache.wan.GatewayEventFilter - * @see org.apache.geode.cache.wan.GatewayTransportFilter - * @see org.apache.geode.cache.wan.GatewaySender.OrderPolicy * @see org.apache.geode.cache.wan.GatewayEventSubstitutionFilter + * @see org.apache.geode.cache.wan.GatewayReceiver + * @see org.apache.geode.cache.wan.GatewaySender + * @see org.apache.geode.cache.wan.GatewaySender.OrderPolicy + * @see org.apache.geode.cache.wan.GatewayTransportFilter + * @see org.springframework.data.gemfire.config.annotation.EnableGatewaySender * @since 2.2.0 */ @Target(ElementType.TYPE) @@ -32,171 +65,253 @@ import org.springframework.data.gemfire.wan.OrderPolicyType; @Import({ GatewaySenderBeanFactoryPostProcessor.class, GatewaySendersConfiguration.class }) @SuppressWarnings("unused") public @interface EnableGatewaySenders { + /** - * This property configures the time, in milliseconds, that an object can be in the queue to be replicated before the - * {@link org.apache.geode.cache.wan.GatewaySender} logs an alert. - *

This property can also be configured using the spring.data.gemfire.gateway.sender.alert-threshold - *

Default value is {@link GatewaySenderConfiguration#DEFAULT_ALERT_THRESHOLD} + * Configures the time, in milliseconds, that an object can be in the queue to be replicated before the + * configured {@link GatewaySender GatewwaySenders} log an alert. + * + * Defaults to {@link GatewaySenderConfiguration#DEFAULT_ALERT_THRESHOLD}. + * + * Alternatively use the {@literal spring.data.gemfire.gateway.sender.alert-threshold} property + * in {@literal application.properties}. */ int alertThreshold() default GatewaySenderConfiguration.DEFAULT_ALERT_THRESHOLD; /** - * A boolean flag to indicate if the configured GatewaySender(s) should use conflate entries in each batch. This means, - * that a batch will never contain duplicate entries, as the batch will always only contain the latest value for a key. - *

This property can also be configured using the spring.data.gemfire.gateway.sender.batch-conflation-enabled - *

Default value is {@value GatewaySenderConfiguration#DEFAULT_BATCH_CONFLATION_ENABLED} + * A {@literal boolean} flag to indicate if the configured {@link GatewaySender GatewaySenders} should use conflate + * entries in each batch. This means, that a batch will never contain duplicate entries, as the batch will always + * only contain the latest value for a key. + * + * Defaults to {@value GatewaySenderConfiguration#DEFAULT_BATCH_CONFLATION_ENABLED}. + * + * Alternatively use the {@literal spring.data.gemfire.gateway.sender.batch-conflation-enabled} property + * in {@literal application.properties}. */ boolean batchConflationEnabled() default GatewaySenderConfiguration.DEFAULT_BATCH_CONFLATION_ENABLED; /** - * This property configures the maximum batch size that the {@link org.apache.geode.cache.wan.GatewaySender} send to the - * remote site. This property works in conjunction with the {@link EnableGatewaySenders#batchTimeInterval()} setting. - * The {@link org.apache.geode.cache.wan.GatewaySender} will send when either the batchSize or batchTimeInterval - * is met. - *

This property can also be configured using the spring.data.gemfire.gateway.sender.batch-size - *

Default value is {@value GatewaySenderConfiguration#DEFAULT_BATCH_SIZE} + * Configures the maximum batch size that all configured {@link GatewaySender GatewaySenders} sends to + * the remote site. + * + * This property works in conjunction with the {@link EnableGatewaySenders#batchTimeInterval()} setting. + * A {@link GatewaySender} will send when either the {@literal batch-size} or {@literal batch-time-interval} + * is reached. + * + * Defaults to {@value GatewaySenderConfiguration#DEFAULT_BATCH_SIZE}. + * + * Alternatively use the {@literal spring.data.gemfire.gateway.sender.batch-size} property + * in {@literal application.properties}. */ int batchSize() default GatewaySenderConfiguration.DEFAULT_BATCH_SIZE; /** - * This property configures the maximum batch time interval, in milliseconds, that the {@link org.apache.geode.cache.wan.GatewaySender} wait before - * attempting to send a batch of queued object to the remote {@link org.apache.geode.cache.wan.GatewayReceiver}. - *

This property works in conjunction with the {@link EnableGatewaySenders#batchSize()} setting. - * The {@link org.apache.geode.cache.wan.GatewaySender} will send when either the batchSize or batchTimeInterval - * is met. - *

This property can also be configured using the spring.data.gemfire.gateway.sender.batch-time-interval - *

Default value is {@value GatewaySenderConfiguration#DEFAULT_BATCH_TIME_INTERVAL} + * Configures the maximum batch time interval in milliseconds that all configured {@link GatewaySender GatewaySenders} + * wait before attempting to send a batch of queued objects to the remote {@link GatewayReceiver GatewayReceivers}. + * + * This property works in conjunction with the {@link EnableGatewaySenders#batchSize()} setting. + * A {@link GatewaySender} will send when either the {@literal batch-size} or {@literal batch-time-interval} + * is reached. + * + * Defaults to {@value GatewaySenderConfiguration#DEFAULT_BATCH_TIME_INTERVAL}. + * + * Alternatively use the {@literal spring.data.gemfire.gateway.sender.batch-time-interval} property + * in {@literal application.properties}. */ int batchTimeInterval() default GatewaySenderConfiguration.DEFAULT_BATCH_TIME_INTERVAL; /** - * This property configures what {@link org.apache.geode.cache.DiskStore} the GatewaySender(s) are to use when persisting - * the GatewaySender(s) queues. This setting should be set when the persistent property is set to true. - *

This property can also be configured using the spring.data.gemfire.gateway.sender.diskstore-reference - *

Default value is {@value GatewaySenderConfiguration#DEFAULT_DISK_STORE_REFERENCE} + * Configures the {@link DiskStore} used by all configured {@link }GatewaySender GatewaySenders} when persisting + * the {@link GatewaySender GatewaySenders} queue data. + * + * This setting should be set when the {@link EnableGatewaySender#persistent()} property is set to {@literal true}. + * + * Defaults to {@value GatewaySenderConfiguration#DEFAULT_DISK_STORE_REFERENCE}. + * + * Alternatively use the {@literal spring.data.gemfire.gateway.sender.diskstore-reference} property + * in {@literal application.properties}. */ String diskStoreReference() default GatewaySenderConfiguration.DEFAULT_DISK_STORE_REFERENCE; /** - * A boolean flag to indicate if the configured GatewaySender(s) should use synchronous diskstore writes. - *

This property can also be configured using the spring.data.gemfire.gateway.sender.disk-synchronous - *

Default value is {@value GatewaySenderConfiguration#DEFAULT_DISK_SYNCHRONOUS} + * A {@literal boolean} flag indicating whether all configured {@link GatewaySender GatewaySenders} should use + * synchronous {@link DiskStore} writes. + * + * Defaults to {@value GatewaySenderConfiguration#DEFAULT_DISK_SYNCHRONOUS}. + * + * Alternatively use the {@literal spring.data.gemfire.gateway.sender.disk-synchronous} property + * in {@literal application.properties}. */ boolean diskSynchronous() default GatewaySenderConfiguration.DEFAULT_DISK_SYNCHRONOUS; /** - * This property configures the number of dispatcher threads that the {@link org.apache.geode.cache.wan.GatewaySender} - * will try to use to dispatch the queuing object. - *

This property can also be configured using the spring.data.gemfire.gateway.sender.dispatcher-threads - *

Default value is {@value GatewaySenderConfiguration#DEFAULT_DISPATCHER_THREADS} + * Configures the number of dispatcher threads that all configured {@link GatewaySender GatewaySenders} will try + * to use to dispatch the queued events. + * + * Defaults to {@value GatewaySenderConfiguration#DEFAULT_DISPATCHER_THREADS}. + * + * Alternatively use the {@literal spring.data.gemfire.gateway.sender.dispatcher-threads} property + * in {@literal application.properties}. */ int dispatcherThreads() default GatewaySenderConfiguration.DEFAULT_DISPATCHER_THREADS; /** - * A list of {@link org.apache.geode.cache.wan.GatewayEventFilter} to be applied to the {@link org.apache.geode.cache.wan.GatewaySender}. - * {@link org.apache.geode.cache.wan.GatewayEventFilter} are used to filter out objects from the sending queue before dispatching - * them to the remote {@link org.apache.geode.cache.wan.GatewayReceiver}. - *

This property can also be configured using the spring.data.gemfire.gateway.sender.event-filters property. - *

Default value is and empty list + * Configures the list of {@link GatewayEventFilter GatewayEventFilters} to be applied to all configured + * {@link GatewaySender GatewaySenders}. + * + * {@link GatewayEventFilter GatewayEventFilters} are used to filter out objects from the sending queue before + * dispatching them to remote {@link GatewayReceiver GatewayReceivers}. + * + * Defaults to empty list. + * + * Alternatively use the {@literal spring.data.gemfire.gateway.sender.event-filters} property + * in {@literal application.properties}. */ String[] eventFilters() default {}; /** - * This property configures the {@link org.apache.geode.cache.wan.GatewayEventSubstitutionFilter} to be used by the GatewaySender(s). - * The {@link org.apache.geode.cache.wan.GatewayEventSubstitutionFilter} is used to replace values on objects before they - * are enqueue for remote replication. - *

This property can also be configured using the spring.data.gemfire.gateway.sender.event-substitution-filter - *

Default value is {@link GatewaySenderConfiguration#DEFAULT_EVENT_SUBSTITUTION_FILTER} + * Configures the {@link GatewayEventSubstitutionFilter} used by all configured {@link GatewaySender GatewaySenders}. + * + * The {@link GatewayEventSubstitutionFilter} is used to replace values on objects before they are enqueued + * for remote replication. + * + * Defaults to {@link GatewaySenderConfiguration#DEFAULT_EVENT_SUBSTITUTION_FILTER}. + * + * Alternatively use the {@literal spring.data.gemfire.gateway.sender.event-substitution-filter} property + * in {@literal application.properties}. */ String eventSubstitutionFilter() default GatewaySenderConfiguration.DEFAULT_EVENT_SUBSTITUTION_FILTER; /** - * A list of {@link org.apache.geode.cache.wan.GatewaySender} to be configured. If no GatewaySenders are configured, - * a default GatewaySender will be created using the properties provided. + * The list of {@link GatewaySender GatewaySenders} to be configured. + * + * If no {@link GatewaySender GatewaySenders) are configured, a default {@link GatewaySender} will be created + * using the properties provided. */ EnableGatewaySender[] gatewaySenders() default {}; /** - * A boolean to indicate if a configured {@link org.apache.geode.cache.wan.GatewaySender} should be started automatically - *

This property can also be configured using the spring.data.gemfire.gateway.sender.manual-start - *

Default is {@value @EnableGatewaySenderConfiguration.DEFAULT_MANUAL_START} + * A {@literal boolean} flag indicating whether all configured {@link GatewaySender GatewaySenders} should be + * started automatically. + * + *

Defaults to {@value @EnableGatewaySenderConfiguration.DEFAULT_MANUAL_START}. + * + * Alternatively use the {@literal spring.data.gemfire.gateway.sender.manual-start} property + * in {@literal application.properties}. */ boolean manualStart() default GatewaySenderConfiguration.DEFAULT_MANUAL_START; /** - * This property configures the maximum size, in MB, that the {@link org.apache.geode.cache.wan.GatewaySender} that the queue - * may take on heap memory, before overflowing to disk. - *

This property can also be configured using the spring.data.gemfire.gateway.sender.maximum-queue-memory - *

Default value is {@value GatewaySenderConfiguration#DEFAULT_MAXIMUM_QUEUE_MEMORY} - */ + * Configures the maximum size in megabytes that all configured {@link GatewaySender GatewaySenders} queue may take + * in heap memory before overflowing to disk. + * + * Defaults to {@value GatewaySenderConfiguration#DEFAULT_MAXIMUM_QUEUE_MEMORY}. + * + * Alternatively use the {@literal spring.data.gemfire.gateway.sender.maximum-queue-memory} property + * in {@literal application.properties}. */ int maximumQueueMemory() default GatewaySenderConfiguration.DEFAULT_MAXIMUM_QUEUE_MEMORY; /** - * The id of the distributed system (cluster) that the GatewaySender(s) would send their data to. - *

This property can also be configured using the spring.data.gemfire.gateway.sender.remote-distributed-system-id - *

Default is {@value @EnableGatewaySenderConfiguration.DEFAULT_REMOTE_DISTRIBUTED_SYSTEM_ID} - */ - int remoteDistributedSystemId() default GatewaySenderConfiguration.DEFAULT_REMOTE_DISTRIBUTED_SYSTEM_ID; - - /** - * This property sets the ordering policy that the GatewaySender(s) will use when queueing entries to be replicated to - * a remote {@link org.apache.geode.cache.wan.GatewayReceiver}. + * Configures the ordering policy that all configured {@link GatewaySender GatewaySenders} will use when queueing + * entries to be replicated to a remote {@link GatewayReceiver}. + * *

There are three different ordering policies: + * *

    *
  • {@link OrderPolicyType#KEY} - Order of events preserved on a per key basis
  • *
  • {@link OrderPolicyType#THREAD} - Order of events preserved by the thread that added the event
  • *
  • {@link OrderPolicyType#PARTITION} - Order of events is preserved in order that they arrived in partitioned Region
  • *
- *

This property can also be configured using the spring.data.gemfire.gateway.sender.order-policy

- *

Default value is an empty list + * + * Defaults to {@link OrderPolicyType#KEY}. + * + * Alternatively use the {@literal spring.data.gemfire.gateway.sender.order-policy} property + * in {@literal application.properties}. */ OrderPolicyType orderPolicy() default OrderPolicyType.KEY; /** - * A boolean flag to indicate if the configured GatewaySender(s) should use parallel GatewaySender replication. - * Parallel replication means that each {@link org.apache.geode.cache.server.CacheServer} that defines a {@link org.apache.geode.cache.wan.GatewaySender} - * will send data to a remote {@link org.apache.geode.cache.wan.GatewayReceiver}. - *

This property can also be configured using the spring.data.gemfire.gateway.sender.parallel - *

Default value is {@value GatewaySenderConfiguration#DEFAULT_PARALLEL} + * A {@literal }boolean} flag indicating whether all configured {@link GatewaySender GatewaySenders} should use + * parallel replication. + * + * Parallel replication means that each {@link CacheServer} that defines a {@link GatewaySender} will send data + * to a remote {@link GatewayReceiver}. + * + * Defaults to {@value GatewaySenderConfiguration#DEFAULT_PARALLEL}. + * + * Alternatively use the {@literal spring.data.gemfire.gateway.sender.parallel} property + * in {@literal application.properties}. */ boolean parallel() default GatewaySenderConfiguration.DEFAULT_PARALLEL; /** - * A boolean flag to indicate if the configured GatewaySender(s) should use persistence. This setting should be used - * in conjunction with the diskStoreReference property. - *

This property can also be configured using the spring.data.gemfire.gateway.sender.persistent - *

Default value is {@value GatewaySenderConfiguration#DEFAULT_PERSISTENT} + * A {@literal boolean} flag indicating whether all configured {@link GatewaySender GatewaySenders} should use + * persistence. + * + * This setting should be used in conjunction with the {@literal disk-store-reference} property. + * + * Defaults to {@value GatewaySenderConfiguration#DEFAULT_PERSISTENT}. + * + * Alternatively use the {@literal spring.data.gemfire.gateway.sender.persistent} property + * in {@literal application.properties}. */ boolean persistent() default GatewaySenderConfiguration.DEFAULT_PERSISTENT; /** - * A list of {@link org.apache.geode.cache.Region} names that are to be configured with {@link org.apache.geode.cache.wan.GatewaySender} replication. - * An empty list will denote that ALL regions are to be replicated to the remote {@link org.apache.geode.cache.wan.GatewayReceiver}. - *

This property can also be configured using the spring.data.gemfire.gateway.sender.region-names property. - *

Default value is an empty list + * Configures the list of {@link Region} names that will be configured for all {@link GatewaySender GatewaySenders}. + * + * An empty list denotes that ALL {@link Region Regions} are to be replicated to the remote {@link GatewayReceiver}. + * + * Defaults to empty list. + * + * Alternatively use the {@literal spring.data.gemfire.gateway.sender.region-names} property + * in {@literal application.properties}. */ String[] regions() default {}; /** - * The socket buffer size for the {@link org.apache.geode.cache.wan.GatewaySender}. This setting is in bytes. - *

This property can also be configured using the spring.data.gemfire.gateway.sender.socket-buffer-size property. - *

Default value is {@value GatewaySenderConfiguration#DEFAULT_SOCKET_BUFFER_SIZE} + * Configures the id of the remote distributed system (cluster) that all configured + * {@link GatewaySender GatewaySenders} will send their data to. + * + * Defaults to {@value @EnableGatewaySenderConfiguration.DEFAULT_REMOTE_DISTRIBUTED_SYSTEM_ID}. + * + * Alternatively use the {@literal spring.data.gemfire.gateway.sender.remote-distributed-system-id} property + * in {@literal application.properties}. + */ + int remoteDistributedSystemId() default GatewaySenderConfiguration.DEFAULT_REMOTE_DISTRIBUTED_SYSTEM_ID; + + /** + * Configures the socket buffer size in bytes for all configured {@link GatewaySender GatewaySenders}. + * + * Defaults to {@value GatewaySenderConfiguration#DEFAULT_SOCKET_BUFFER_SIZE}. + * + * Alternatively use the {@literal spring.data.gemfire.gateway.sender.socket-buffer-size} property + * in {@literal application.properties}. */ int socketBufferSize() default GatewaySenderConfiguration.DEFAULT_SOCKET_BUFFER_SIZE; /** - * Amount of time in milliseconds that the gateway sender will wait to receive an acknowledgment from a remote site. - * By default this is set to 0, which means there is no timeout. The minimum allowed timeout is 30000 (milliseconds). - *

This property can also be configured using the spring.data.gemfire.gateway.sender.socket-read-timeout property. - *

Default value is {@value GatewaySenderConfiguration#DEFAULT_SOCKET_READ_TIMEOUT} + * Configures the amount of time in milliseconds that all configured {@link GatewaySender GatewaySenders} will wait + * to receive an acknowledgment from a remote site. + * + * By default this is set to {@literal 0}, which means there is no timeout. The minimum allowed timeout + * is {@literal 30000 (milliseconds)}. + * + * Defaults to {@value GatewaySenderConfiguration#DEFAULT_SOCKET_READ_TIMEOUT}. + * + * Alternatively use the {@literal spring.data.gemfire.gateway.sender.socket-read-timeout} property + * in {@literal application.properties}. */ int socketReadTimeout() default GatewaySenderConfiguration.DEFAULT_SOCKET_READ_TIMEOUT; /** - * An in-order list of {@link org.apache.geode.cache.wan.GatewayTransportFilter} to be applied to - * {@link org.apache.geode.cache.wan.GatewaySender} - *

This property can also be configured using the spring.data.gemfire.gateway.sender.transport-filterss property - *

Default value is an empty list + * Configures an in-order list of {@link GatewayTransportFilter} objects to be applied to all configured + * {@link GatewaySender GatewaySenders}. + * + * Defaults to empty list. + * + * Alternatively use the {@literal spring.data.gemfire.gateway.sender.transport-filters} property + * in {@literal application.properties}. */ String[] transportFilters() default {}; + } diff --git a/src/main/java/org/springframework/data/gemfire/config/annotation/GatewaySenderConfiguration.java b/src/main/java/org/springframework/data/gemfire/config/annotation/GatewaySenderConfiguration.java index 54d6118e..216854dd 100644 --- a/src/main/java/org/springframework/data/gemfire/config/annotation/GatewaySenderConfiguration.java +++ b/src/main/java/org/springframework/data/gemfire/config/annotation/GatewaySenderConfiguration.java @@ -1,213 +1,237 @@ +/* + * Copyright 2010-2019 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ package org.springframework.data.gemfire.config.annotation; import java.lang.annotation.Annotation; import java.util.Arrays; import java.util.Collections; import java.util.List; -import java.util.Map; import java.util.Optional; +import java.util.Properties; import java.util.function.Supplier; import org.apache.geode.cache.wan.GatewaySender; -import org.springframework.beans.MutablePropertyValues; + +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.beans.factory.config.BeanDefinition; import org.springframework.beans.factory.config.BeanReference; import org.springframework.beans.factory.config.RuntimeBeanReference; import org.springframework.beans.factory.support.BeanDefinitionBuilder; import org.springframework.beans.factory.support.BeanDefinitionRegistry; import org.springframework.beans.factory.support.ManagedList; import org.springframework.context.annotation.Configuration; -import org.springframework.context.annotation.ImportAware; import org.springframework.context.annotation.ImportBeanDefinitionRegistrar; import org.springframework.core.annotation.AnnotationAttributes; import org.springframework.core.type.AnnotationMetadata; import org.springframework.data.gemfire.config.annotation.support.AbstractAnnotationConfigSupport; +import org.springframework.data.gemfire.util.ArrayUtils; import org.springframework.data.gemfire.wan.GatewaySenderFactoryBean; import org.springframework.data.gemfire.wan.OrderPolicyType; import org.springframework.util.StringUtils; @Configuration public class GatewaySenderConfiguration extends AbstractAnnotationConfigSupport - implements ImportBeanDefinitionRegistrar, ImportAware { + implements ImportBeanDefinitionRegistrar { + + static final int DEFAULT_SOCKET_BUFFER_SIZE = GatewaySender.DEFAULT_SOCKET_BUFFER_SIZE; - public static final String DEFAULT_NAME = "GatewaySender"; - public static final int DEFAULT_SOCKET_BUFFER_SIZE = GatewaySender.DEFAULT_SOCKET_BUFFER_SIZE; static final boolean DEFAULT_MANUAL_START = GatewaySender.DEFAULT_MANUAL_START; - static final int DEFAULT_REMOTE_DISTRIBUTED_SYSTEM_ID = GatewaySender.DEFAULT_DISTRIBUTED_SYSTEM_ID; static final boolean DEFAULT_DISK_SYNCHRONOUS = GatewaySender.DEFAULT_DISK_SYNCHRONOUS; static final boolean DEFAULT_BATCH_CONFLATION_ENABLED = GatewaySender.DEFAULT_BATCH_CONFLATION; static final boolean DEFAULT_PARALLEL = GatewaySender.DEFAULT_IS_PARALLEL; static final boolean DEFAULT_PERSISTENT = GatewaySender.DEFAULT_PERSISTENCE_ENABLED; + static final int DEFAULT_ALERT_THRESHOLD = GatewaySender.DEFAULT_ALERT_THRESHOLD; static final int DEFAULT_BATCH_SIZE = GatewaySender.DEFAULT_BATCH_SIZE; static final int DEFAULT_BATCH_TIME_INTERVAL = GatewaySender.DEFAULT_BATCH_TIME_INTERVAL; static final int DEFAULT_DISPATCHER_THREADS = GatewaySender.DEFAULT_DISPATCHER_THREADS; static final int DEFAULT_MAXIMUM_QUEUE_MEMORY = GatewaySender.DEFAULT_MAXIMUM_QUEUE_MEMORY; + static final int DEFAULT_REMOTE_DISTRIBUTED_SYSTEM_ID = GatewaySender.DEFAULT_DISTRIBUTED_SYSTEM_ID; static final int DEFAULT_SOCKET_READ_TIMEOUT = 0; + static final OrderPolicyType DEFAULT_ORDER_POLICY = OrderPolicyType.KEY; + + static final String DEFAULT_DISK_STORE_REFERENCE = ""; static final String DEFAULT_EVENT_SUBSTITUTION_FILTER = ""; + static final String DEFAULT_NAME = "GatewaySender"; + static final String[] DEFAULT_EVENT_FILTERS = {}; static final String[] DEFAULT_TRANSPORT_FILTERS = {}; static final String[] DEFAULT_REGION_NAMES = {}; - static final String DEFAULT_DISK_STORE_REFERENCE = ""; static final String REGION_NAMES_LITERAL = "regions"; - private static final String NAME_LITERAL = "name"; - private static final String MANUAL_START_LITERAL = "manualStart"; - private static final String REMOTE_DIST_SYSTEM_ID_LITERAL = "remoteDistributedSystemId"; - private static final String DISK_SYNCHRONOUS_LITERAL = "diskSynchronous"; - private static final String BATCH_CONFLATION_ENABLED_LITERAL = "batchConflationEnabled"; - private static final String PARALLEL_LITERAL = "parallel"; - private static final String PERSISTENT_LITERAL = "persistent"; - private static final String ORDER_POLICY_LITERAL = "orderPolicy"; - private static final String EVENT_SUBSTITUTION_FILTER_LITERAL = "eventSubstitutionFilter"; + private static final String ALERT_THRESHOLD_LITERAL = "alertThreshold"; + private static final String BATCH_CONFLATION_ENABLED_LITERAL = "batchConflationEnabled"; private static final String BATCH_SIZE_LITERAL = "batchSize"; private static final String BATCH_TIME_INTERVAL_LITERAL = "batchTimeInterval"; + private static final String DISK_STORE_REFERENCE_LITERAL = "diskStoreReference"; + private static final String DISK_SYNCHRONOUS_LITERAL = "diskSynchronous"; private static final String DISPATCHER_THREAD_LITERAL = "dispatcherThreads"; + private static final String EVENT_FILTERS_LITERAL = "eventFilters"; + private static final String EVENT_SUBSTITUTION_FILTER_LITERAL = "eventSubstitutionFilter"; + private static final String MANUAL_START_LITERAL = "manualStart"; private static final String MAXIMUM_QUEUE_MEMORY_LITERAL = "maximumQueueMemory"; + private static final String NAME_LITERAL = "name"; + private static final String ORDER_POLICY_LITERAL = "orderPolicy"; + private static final String PARALLEL_LITERAL = "parallel"; + private static final String PERSISTENT_LITERAL = "persistent"; + private static final String REMOTE_DIST_SYSTEM_ID_LITERAL = "remoteDistributedSystemId"; private static final String SOCKET_BUFFER_SIZE_LITERAL = "socketBufferSize"; private static final String SOCKET_READ_TIMEOUT_LITERAL = "socketReadTimeout"; - private static final String DISK_STORE_REFERENCE_LITERAL = "diskStoreReference"; - private static final String EVENT_FILTERS_LITERAL = "eventFilters"; private static final String TRANSPORT_FILTERS_LITERAL = "transportFilters"; - private static final String MANUAL_START_PROPERTY_NAME = "manual-start"; - private static final String REMOTE_DIST_SYSTEM_ID_PROPERTY_NAME = "remote-distributed-system-id"; - private static final String DISK_SYNCHRONOUS_PROPERTY_NAME = "disk-synchronous"; - private static final String BATCH_CONFLATION_ENABLED_PROPERTY_NAME = "batch-conflation-enabled"; - private static final String PARALLEL_PROPERTY_NAME = "parallel"; - private static final String PERSISTENT_PROPERTY_NAME = "persistent"; - private static final String ORDER_POLICY_PROPERTY_NAME = "order-policy"; - private static final String EVENT_SUBSTITUTION_FILTER_PROPERTY_NAME = "event-substitution-filter"; private static final String ALERT_THRESHOLD_PROPERTY_NAME = "alert-threshold"; + private static final String BATCH_CONFLATION_ENABLED_PROPERTY_NAME = "batch-conflation-enabled"; private static final String BATCH_SIZE_PROPERTY_NAME = "batch-size"; private static final String BATCH_TIME_INTERVAL_PROPERTY_NAME = "batch-time-interval"; + private static final String DISK_STORE_REFERENCE_PROPERTY_NAME = "disk-store-reference"; + private static final String DISK_SYNCHRONOUS_PROPERTY_NAME = "disk-synchronous"; private static final String DISPATCHER_THREAD_PROPERTY_NAME = "dispatcher-threads"; + private static final String EVENT_FILTERS_PROPERTY_NAME = "event-filters"; + private static final String EVENT_SUBSTITUTION_FILTER_PROPERTY_NAME = "event-substitution-filter"; + private static final String MANUAL_START_PROPERTY_NAME = "manual-start"; private static final String MAXIMUM_QUEUE_MEMORY_PROPERTY_NAME = "maximum-queue-memory"; + private static final String ORDER_POLICY_PROPERTY_NAME = "order-policy"; + private static final String PARALLEL_PROPERTY_NAME = "parallel"; + private static final String PERSISTENT_PROPERTY_NAME = "persistent"; + private static final String REGION_NAMES_PROPERTY_NAME = "regions"; + private static final String REMOTE_DIST_SYSTEM_ID_PROPERTY_NAME = "remote-distributed-system-id"; private static final String SOCKET_BUFFER_SIZE_PROPERTY_NAME = "socket-buffer-size"; private static final String SOCKET_READ_TIMEOUT_PROPERTY_NAME = "socket-read-timeout"; - private static final String DISK_STORE_REFERENCE_PROPERTY_NAME = "disk-store-reference"; - private static final String EVENT_FILTERS_PROPERTY_NAME = "event-filters"; private static final String TRANSPORT_FILTERS_PROPERTY_NAME = "transport-filters"; - private static final String REGION_NAMES_PROPERTY_NAME = "regions"; - private String gatewaySenderBeanName; + @Autowired(required = false) private List gatewaySenderConfigurers = Collections.emptyList(); - /** - * Processes the {@link EnableGatewaySender} annotation and registers the configured BeanDefinition - * - * @param annotationMetadata - * @param beanDefinitionRegistry - */ + private String gatewaySenderBeanName; + @Override - public void registerBeanDefinitions(AnnotationMetadata annotationMetadata, - BeanDefinitionRegistry beanDefinitionRegistry) { - - if (annotationMetadata.hasAnnotation(EnableGatewaySender.class.getName())) { - Map annotationAttributesMap = annotationMetadata - .getAnnotationAttributes(EnableGatewaySender.class.getName()); - - AnnotationAttributes gatewaySenderAnnotation = AnnotationAttributes.fromMap(annotationAttributesMap); - - registerGatewaySender(gatewaySenderAnnotation, beanDefinitionRegistry, null); - } - } - - @Override protected Class getAnnotationType() { + protected Class getAnnotationType() { return EnableGatewaySender.class; } + protected void setGatewaySenderBeanName(String gatewaySenderBeanName) { + this.gatewaySenderBeanName = gatewaySenderBeanName; + } /** - * This method processes a defined {@link EnableGatewaySender} on the {@link EnableGatewaySenders} annotation. - * It will process properties defined in either annotation or application.properties. + * Processes the {@link EnableGatewaySender} annotation by configuring and registerig a {@link BeanDefinition} + * for a {@link GatewaySender}. * - * @param gatewaySenderAnnotation - * @param registry - * @param parentGatewaySenderAnnotation + * @see #registerGatewaySender(AnnotationAttributes, AnnotationAttributes, BeanDefinitionRegistry) + */ + @Override + public void registerBeanDefinitions(AnnotationMetadata annotationMetadata, + BeanDefinitionRegistry beanDefinitionRegistry) { + + if (isAnnotationPresent(annotationMetadata)) { + + AnnotationAttributes gatewaySenderAnnotation = getAnnotationAttributes(annotationMetadata); + + registerGatewaySender(gatewaySenderAnnotation, null, beanDefinitionRegistry); + } + } + + /** + * Processes a defined {@link EnableGatewaySender} on the {@link EnableGatewaySenders} annotation. + * Processes properties defined in either the {@link Annotation} or {@literal application.properties}. + * + * @see #registerGatewaySender(String, AnnotationAttributes, AnnotationAttributes, BeanDefinitionRegistry) + */ + protected void registerGatewaySender(AnnotationAttributes gatewaySenderAnnotation, + AnnotationAttributes parentGatewaySenderAnnotation, BeanDefinitionRegistry registry) { + + String gatewaySenderName = getStringFromAnnotation(gatewaySenderAnnotation, NAME_LITERAL); + + registerGatewaySender(gatewaySenderName, gatewaySenderAnnotation, parentGatewaySenderAnnotation, registry); + } + + /** + * Processes a defined {@link EnableGatewaySender} on the {@link EnableGatewaySenders} annotation. + * Processes properties defined in either the {@link Annotation} or {@literal application.properties{@literal}. */ protected void registerGatewaySender(String gatewaySenderName, AnnotationAttributes gatewaySenderAnnotation, - BeanDefinitionRegistry registry, AnnotationAttributes parentGatewaySenderAnnotation) { + AnnotationAttributes parentGatewaySenderAnnotation, BeanDefinitionRegistry registry) { - BeanDefinitionBuilder gatewaySenderBuilder = BeanDefinitionBuilder.genericBeanDefinition( - GatewaySenderFactoryBean.class); + BeanDefinitionBuilder gatewaySenderBuilder = + BeanDefinitionBuilder.genericBeanDefinition(GatewaySenderFactoryBean.class); - configureGatewaySenderFromAnnotation(gatewaySenderName, gatewaySenderAnnotation, gatewaySenderBuilder, - parentGatewaySenderAnnotation); + configureGatewaySenderFromAnnotation(gatewaySenderName, gatewaySenderAnnotation, + parentGatewaySenderAnnotation, gatewaySenderBuilder); configureGatewaySenderFromProperties(gatewaySenderName, gatewaySenderBuilder); - configureGatewaySenderArguments(gatewaySenderName, gatewaySenderAnnotation, gatewaySenderBuilder, - parentGatewaySenderAnnotation); + configureGatewaySenderArguments(gatewaySenderName, gatewaySenderAnnotation, + parentGatewaySenderAnnotation, gatewaySenderBuilder); registry.registerBeanDefinition(gatewaySenderName, gatewaySenderBuilder.getBeanDefinition()); } private void configureGatewaySenderArguments(String gatewaySenderName, - AnnotationAttributes gatewaySenderAnnotation, BeanDefinitionBuilder gatewaySenderBuilder, - AnnotationAttributes parentGatewaySenderAnnotation) { + AnnotationAttributes gatewaySenderAnnotation, AnnotationAttributes parentGatewaySenderAnnotation, + BeanDefinitionBuilder gatewaySenderBuilder) { - String[] resolveValue = Optional - .ofNullable(getStringArrayFromAnnotation(gatewaySenderAnnotation, REGION_NAMES_LITERAL)) - .filter(childValue -> !childValue.equals(DEFAULT_REGION_NAMES)) - .orElse( + String[] annotationRegionNames = + Optional.ofNullable(getStringArrayFromAnnotation(gatewaySenderAnnotation, REGION_NAMES_LITERAL)) + .filter(ArrayUtils::isNotEmpty) + .orElseGet(() -> Optional.ofNullable(getStringArrayFromAnnotation(parentGatewaySenderAnnotation, REGION_NAMES_LITERAL)) + .filter(ArrayUtils::isNotEmpty) .orElse(DEFAULT_REGION_NAMES)); - String[] resolvedPropertyValue = Optional - .ofNullable(resolveValueFromProperty(gatewaySenderName, REGION_NAMES_PROPERTY_NAME, resolveValue)) - .orElse(resolveValue); + String[] resolvedRegionNames = Optional + .ofNullable(resolveValueFromProperty(gatewaySenderName, REGION_NAMES_PROPERTY_NAME, annotationRegionNames)) + .filter(ArrayUtils::isNotEmpty) + .orElse(annotationRegionNames); - setPropertyValueOrUseParent(gatewaySenderBuilder, REGION_NAMES_LITERAL, resolvedPropertyValue, null, + setPropertyValueOrUseParent(gatewaySenderBuilder, REGION_NAMES_LITERAL, resolvedRegionNames, null, DEFAULT_REGION_NAMES); } /** - * This method processes a defined {@link EnableGatewaySender} on the {@link EnableGatewaySenders} annotation. - * It will process properties defined in either annotation or application.properties. - * - * @param gatewaySenderAnnotation - * @param registry - * @param parentGatewaySenderAnnotation - */ - protected void registerGatewaySender(AnnotationAttributes gatewaySenderAnnotation, - BeanDefinitionRegistry registry, AnnotationAttributes parentGatewaySenderAnnotation) { - - String gatewaySenderName = getStringFromAnnotation(gatewaySenderAnnotation, NAME_LITERAL); - - registerGatewaySender(gatewaySenderName, gatewaySenderAnnotation, registry, parentGatewaySenderAnnotation); - } - - public void setGatewaySenderBeanName(String gatewaySenderBeanName) { - this.gatewaySenderBeanName = gatewaySenderBeanName; - } - - /** - * In this method a {@link GatewaySender} is configured from properties defined on the {@link EnableGatewaySender} - * annotation - * - * @param gatewaySenderAnnotation - * @param gatewaySenderBuilder - * @param parentGatewaySenderAnnotation + * Configures a {@link GatewaySender} from attributes set with the {@link EnableGatewaySender} annotation. */ private void configureGatewaySenderFromAnnotation(String gatewaySenderName, - AnnotationAttributes gatewaySenderAnnotation, - BeanDefinitionBuilder gatewaySenderBuilder, - AnnotationAttributes parentGatewaySenderAnnotation) { + AnnotationAttributes gatewaySenderAnnotation, AnnotationAttributes parentGatewaySenderAnnotation, + BeanDefinitionBuilder gatewaySenderBuilder) { setGatewaySenderBeanName(Optional.ofNullable(gatewaySenderName).orElse(DEFAULT_NAME)); - setPropertyValueIfNotDefault(gatewaySenderBuilder, NAME_LITERAL, - gatewaySenderName, DEFAULT_NAME); - setPropertyValueOrUseParent(gatewaySenderBuilder, MANUAL_START_LITERAL, - getBooleanFromAnnotation(gatewaySenderAnnotation, MANUAL_START_LITERAL), - getBooleanFromAnnotation(parentGatewaySenderAnnotation, MANUAL_START_LITERAL), DEFAULT_MANUAL_START); + setPropertyValueIfNotDefault(gatewaySenderBuilder, NAME_LITERAL, gatewaySenderName, DEFAULT_NAME); - setPropertyValueOrUseParent(gatewaySenderBuilder, REMOTE_DIST_SYSTEM_ID_LITERAL, - getNumberFromAnnotation(gatewaySenderAnnotation, REMOTE_DIST_SYSTEM_ID_LITERAL), - getNumberFromAnnotation(parentGatewaySenderAnnotation, REMOTE_DIST_SYSTEM_ID_LITERAL), - DEFAULT_REMOTE_DISTRIBUTED_SYSTEM_ID); + setPropertyValueOrUseParent(gatewaySenderBuilder, ALERT_THRESHOLD_LITERAL, + getNumberFromAnnotation(gatewaySenderAnnotation, ALERT_THRESHOLD_LITERAL), + getNumberFromAnnotation(parentGatewaySenderAnnotation, ALERT_THRESHOLD_LITERAL), + DEFAULT_ALERT_THRESHOLD); + + setPropertyValueOrUseParent(gatewaySenderBuilder, BATCH_CONFLATION_ENABLED_LITERAL, + getBooleanFromAnnotation(gatewaySenderAnnotation, BATCH_CONFLATION_ENABLED_LITERAL), + getBooleanFromAnnotation(parentGatewaySenderAnnotation, BATCH_CONFLATION_ENABLED_LITERAL), + DEFAULT_BATCH_CONFLATION_ENABLED); + + setPropertyValueOrUseParent(gatewaySenderBuilder, BATCH_SIZE_LITERAL, + getNumberFromAnnotation(gatewaySenderAnnotation, BATCH_SIZE_LITERAL), + getNumberFromAnnotation(parentGatewaySenderAnnotation, BATCH_SIZE_LITERAL), + DEFAULT_BATCH_SIZE); + + setPropertyValueOrUseParent(gatewaySenderBuilder, BATCH_TIME_INTERVAL_LITERAL, + getNumberFromAnnotation(gatewaySenderAnnotation, BATCH_TIME_INTERVAL_LITERAL), + getNumberFromAnnotation(parentGatewaySenderAnnotation, BATCH_TIME_INTERVAL_LITERAL), + DEFAULT_BATCH_TIME_INTERVAL); setPropertyValueOrUseParent(gatewaySenderBuilder, DISK_STORE_REFERENCE_LITERAL, getStringFromAnnotation(gatewaySenderAnnotation, DISK_STORE_REFERENCE_LITERAL), @@ -219,56 +243,51 @@ public class GatewaySenderConfiguration extends AbstractAnnotationConfigSupport getBooleanFromAnnotation(parentGatewaySenderAnnotation, DISK_SYNCHRONOUS_LITERAL), DEFAULT_DISK_SYNCHRONOUS); - setPropertyValueOrUseParent(gatewaySenderBuilder, BATCH_CONFLATION_ENABLED_LITERAL, - getBooleanFromAnnotation(gatewaySenderAnnotation, BATCH_CONFLATION_ENABLED_LITERAL), - getBooleanFromAnnotation(parentGatewaySenderAnnotation, BATCH_CONFLATION_ENABLED_LITERAL), - DEFAULT_BATCH_CONFLATION_ENABLED); - - setPropertyValueOrUseParent(gatewaySenderBuilder, BATCH_SIZE_LITERAL, - getNumberFromAnnotation(gatewaySenderAnnotation, BATCH_SIZE_LITERAL), - getNumberFromAnnotation(parentGatewaySenderAnnotation, BATCH_SIZE_LITERAL), DEFAULT_BATCH_SIZE); - - setPropertyValueOrUseParent(gatewaySenderBuilder, BATCH_TIME_INTERVAL_LITERAL, - getNumberFromAnnotation(gatewaySenderAnnotation, BATCH_TIME_INTERVAL_LITERAL), - getNumberFromAnnotation(parentGatewaySenderAnnotation, BATCH_TIME_INTERVAL_LITERAL), - DEFAULT_BATCH_TIME_INTERVAL); - - setPropertyValueOrUseParent(gatewaySenderBuilder, PARALLEL_LITERAL, - getBooleanFromAnnotation(gatewaySenderAnnotation, PARALLEL_LITERAL), - getBooleanFromAnnotation(parentGatewaySenderAnnotation, PARALLEL_LITERAL), DEFAULT_PARALLEL); - - setPropertyValueOrUseParent(gatewaySenderBuilder, PERSISTENT_LITERAL, - getBooleanFromAnnotation(gatewaySenderAnnotation, PERSISTENT_LITERAL), - getBooleanFromAnnotation(parentGatewaySenderAnnotation, PERSISTENT_LITERAL), DEFAULT_PERSISTENT); - - setPropertyValueOrUseParent(gatewaySenderBuilder, ORDER_POLICY_LITERAL, - getEnumFromAnnotation(gatewaySenderAnnotation, ORDER_POLICY_LITERAL, DEFAULT_ORDER_POLICY).toString(), - getEnumFromAnnotation(parentGatewaySenderAnnotation, ORDER_POLICY_LITERAL, DEFAULT_ORDER_POLICY).toString(), - DEFAULT_ORDER_POLICY.toString()); + setPropertyValueOrUseParent(gatewaySenderBuilder, DISPATCHER_THREAD_LITERAL, + getNumberFromAnnotation(gatewaySenderAnnotation, DISPATCHER_THREAD_LITERAL), + getNumberFromAnnotation(parentGatewaySenderAnnotation, DISPATCHER_THREAD_LITERAL), + DEFAULT_DISPATCHER_THREADS); setPropertyValueOrUseParentAsBeanReferenceList(gatewaySenderBuilder, EVENT_FILTERS_LITERAL, getStringArrayFromAnnotation(gatewaySenderAnnotation, EVENT_FILTERS_LITERAL), - getStringArrayFromAnnotation(parentGatewaySenderAnnotation, EVENT_FILTERS_LITERAL), DEFAULT_EVENT_FILTERS); + getStringArrayFromAnnotation(parentGatewaySenderAnnotation, EVENT_FILTERS_LITERAL), + DEFAULT_EVENT_FILTERS); setPropertyValueIfNotDefaultAsBeanReference(gatewaySenderBuilder, EVENT_SUBSTITUTION_FILTER_LITERAL, getStringFromAnnotation(gatewaySenderAnnotation, EVENT_SUBSTITUTION_FILTER_LITERAL), getStringFromAnnotation(parentGatewaySenderAnnotation, EVENT_SUBSTITUTION_FILTER_LITERAL), DEFAULT_EVENT_SUBSTITUTION_FILTER); - setPropertyValueOrUseParent(gatewaySenderBuilder, ALERT_THRESHOLD_LITERAL, - getNumberFromAnnotation(gatewaySenderAnnotation, ALERT_THRESHOLD_LITERAL), - getNumberFromAnnotation(parentGatewaySenderAnnotation, ALERT_THRESHOLD_LITERAL), DEFAULT_ALERT_THRESHOLD); - - setPropertyValueOrUseParent(gatewaySenderBuilder, DISPATCHER_THREAD_LITERAL, - getNumberFromAnnotation(gatewaySenderAnnotation, DISPATCHER_THREAD_LITERAL), - getNumberFromAnnotation(parentGatewaySenderAnnotation, DISPATCHER_THREAD_LITERAL), - DEFAULT_DISPATCHER_THREADS); + setPropertyValueOrUseParent(gatewaySenderBuilder, MANUAL_START_LITERAL, + getBooleanFromAnnotation(gatewaySenderAnnotation, MANUAL_START_LITERAL), + getBooleanFromAnnotation(parentGatewaySenderAnnotation, MANUAL_START_LITERAL), + DEFAULT_MANUAL_START); setPropertyValueOrUseParent(gatewaySenderBuilder, MAXIMUM_QUEUE_MEMORY_LITERAL, getNumberFromAnnotation(gatewaySenderAnnotation, MAXIMUM_QUEUE_MEMORY_LITERAL), getNumberFromAnnotation(parentGatewaySenderAnnotation, MAXIMUM_QUEUE_MEMORY_LITERAL), DEFAULT_MAXIMUM_QUEUE_MEMORY); + setPropertyValueOrUseParent(gatewaySenderBuilder, ORDER_POLICY_LITERAL, + getEnumFromAnnotation(gatewaySenderAnnotation, ORDER_POLICY_LITERAL, DEFAULT_ORDER_POLICY).toString(), + getEnumFromAnnotation(parentGatewaySenderAnnotation, ORDER_POLICY_LITERAL, DEFAULT_ORDER_POLICY).toString(), + DEFAULT_ORDER_POLICY.toString()); + + setPropertyValueOrUseParent(gatewaySenderBuilder, PARALLEL_LITERAL, + getBooleanFromAnnotation(gatewaySenderAnnotation, PARALLEL_LITERAL), + getBooleanFromAnnotation(parentGatewaySenderAnnotation, PARALLEL_LITERAL), + DEFAULT_PARALLEL); + + setPropertyValueOrUseParent(gatewaySenderBuilder, PERSISTENT_LITERAL, + getBooleanFromAnnotation(gatewaySenderAnnotation, PERSISTENT_LITERAL), + getBooleanFromAnnotation(parentGatewaySenderAnnotation, PERSISTENT_LITERAL), + DEFAULT_PERSISTENT); + + setPropertyValueOrUseParent(gatewaySenderBuilder, REMOTE_DIST_SYSTEM_ID_LITERAL, + getNumberFromAnnotation(gatewaySenderAnnotation, REMOTE_DIST_SYSTEM_ID_LITERAL), + getNumberFromAnnotation(parentGatewaySenderAnnotation, REMOTE_DIST_SYSTEM_ID_LITERAL), + DEFAULT_REMOTE_DISTRIBUTED_SYSTEM_ID); + setPropertyValueOrUseParent(gatewaySenderBuilder, SOCKET_BUFFER_SIZE_LITERAL, getNumberFromAnnotation(gatewaySenderAnnotation, SOCKET_BUFFER_SIZE_LITERAL), getNumberFromAnnotation(parentGatewaySenderAnnotation, SOCKET_BUFFER_SIZE_LITERAL), @@ -283,33 +302,90 @@ public class GatewaySenderConfiguration extends AbstractAnnotationConfigSupport getStringArrayFromAnnotation(gatewaySenderAnnotation, TRANSPORT_FILTERS_LITERAL), getStringArrayFromAnnotation(parentGatewaySenderAnnotation, TRANSPORT_FILTERS_LITERAL), DEFAULT_TRANSPORT_FILTERS); - } - private Enum getEnumFromAnnotation(AnnotationAttributes gatewaySenderAnnotation, String annotationLabel, - Enum defaultValue) { - Enum returnValue = defaultValue; - if (gatewaySenderAnnotation != null) { - returnValue = getValueFromAnnotation(gatewaySenderAnnotation, () -> - gatewaySenderAnnotation.getEnum(annotationLabel)); + /** + * Configures a {@link GatewaySender} from {@link Properties} defined in {@literal application.properties}. + * + * These properties are "named" properties and will follow the following pattern: + * {@literal spring.data.gemfire.gateway.sender..manual-start} + */ + private void configureGatewaySenderFromProperties(String gatewaySenderName, + BeanDefinitionBuilder gatewaySenderBuilder) { + + gatewaySenderBuilder.addPropertyValue("gatewaySenderConfigurers", resolveGatewaySenderConfigurers()); + + configureGatewaySenderFromProperty(gatewaySenderBuilder, gatewaySenderName, + ALERT_THRESHOLD_PROPERTY_NAME, ALERT_THRESHOLD_LITERAL, DEFAULT_ALERT_THRESHOLD); + + configureGatewaySenderFromProperty(gatewaySenderBuilder, gatewaySenderName, + BATCH_CONFLATION_ENABLED_PROPERTY_NAME, BATCH_CONFLATION_ENABLED_LITERAL, DEFAULT_BATCH_CONFLATION_ENABLED); + + configureGatewaySenderFromProperty(gatewaySenderBuilder, gatewaySenderName, + BATCH_SIZE_PROPERTY_NAME, BATCH_SIZE_LITERAL, DEFAULT_BATCH_SIZE); + + configureGatewaySenderFromProperty(gatewaySenderBuilder, gatewaySenderName, + BATCH_TIME_INTERVAL_PROPERTY_NAME, BATCH_TIME_INTERVAL_LITERAL, DEFAULT_BATCH_TIME_INTERVAL); + + configureGatewaySenderFromProperty(gatewaySenderBuilder, gatewaySenderName, + DISK_STORE_REFERENCE_PROPERTY_NAME, DISK_STORE_REFERENCE_LITERAL, new String[0]); + + configureGatewaySenderFromProperty(gatewaySenderBuilder, gatewaySenderName, + DISK_SYNCHRONOUS_PROPERTY_NAME, DISK_SYNCHRONOUS_LITERAL, DEFAULT_DISK_SYNCHRONOUS); + + configureGatewaySenderFromProperty(gatewaySenderBuilder, gatewaySenderName, + DISPATCHER_THREAD_PROPERTY_NAME, DISPATCHER_THREAD_LITERAL, DEFAULT_DISPATCHER_THREADS); + + configureBeanReferenceListFromProperty(gatewaySenderBuilder, gatewaySenderName, + EVENT_FILTERS_PROPERTY_NAME, EVENT_FILTERS_LITERAL, DEFAULT_EVENT_FILTERS); + + configureBeanReferenceFromProperty(gatewaySenderBuilder, gatewaySenderName, + EVENT_SUBSTITUTION_FILTER_PROPERTY_NAME, EVENT_SUBSTITUTION_FILTER_LITERAL, + DEFAULT_EVENT_SUBSTITUTION_FILTER); + + configureGatewaySenderFromProperty(gatewaySenderBuilder, gatewaySenderName, + MANUAL_START_PROPERTY_NAME, MANUAL_START_LITERAL, DEFAULT_MANUAL_START); + + configureGatewaySenderFromProperty(gatewaySenderBuilder, gatewaySenderName, + MAXIMUM_QUEUE_MEMORY_PROPERTY_NAME, MAXIMUM_QUEUE_MEMORY_LITERAL, DEFAULT_MAXIMUM_QUEUE_MEMORY); + + configureGatewaySenderFromProperty(gatewaySenderBuilder, gatewaySenderName, + ORDER_POLICY_PROPERTY_NAME, ORDER_POLICY_LITERAL, DEFAULT_ORDER_POLICY.toString()); + + configureGatewaySenderFromProperty(gatewaySenderBuilder, gatewaySenderName, + PARALLEL_PROPERTY_NAME, PARALLEL_LITERAL, DEFAULT_PARALLEL); + + configureGatewaySenderFromProperty(gatewaySenderBuilder, gatewaySenderName, + PERSISTENT_PROPERTY_NAME, PERSISTENT_LITERAL, DEFAULT_PERSISTENT); + + configureGatewaySenderFromProperty(gatewaySenderBuilder, gatewaySenderName, + REMOTE_DIST_SYSTEM_ID_PROPERTY_NAME, REMOTE_DIST_SYSTEM_ID_LITERAL, DEFAULT_REMOTE_DISTRIBUTED_SYSTEM_ID); + + configureGatewaySenderFromProperty(gatewaySenderBuilder, gatewaySenderName, + SOCKET_BUFFER_SIZE_PROPERTY_NAME, SOCKET_BUFFER_SIZE_LITERAL, DEFAULT_SOCKET_BUFFER_SIZE); + + configureGatewaySenderFromProperty(gatewaySenderBuilder, gatewaySenderName, + SOCKET_READ_TIMEOUT_PROPERTY_NAME, SOCKET_READ_TIMEOUT_LITERAL, DEFAULT_SOCKET_READ_TIMEOUT); + + configureBeanReferenceListFromProperty(gatewaySenderBuilder, gatewaySenderName, + TRANSPORT_FILTERS_PROPERTY_NAME, TRANSPORT_FILTERS_LITERAL, DEFAULT_TRANSPORT_FILTERS); + } + + /** + * Configures a {@link GatewaySender} from {@link Properties} defined in {@literal application.properties}. + * + * These properties are {@literal "named"} properties and will follow the following pattern: + * {@literal spring.data.gemfire.gateway.sender..manual-start}. + */ + private void configureGatewaySenderFromProperty(BeanDefinitionBuilder gatewaySenderBuilder, + String gatewaySenderName, String propertyName, String fieldName, T defaultValue) { + + T resolvedPropertyValue = resolveValueFromProperty(gatewaySenderName, propertyName, defaultValue); + + if (resolvedPropertyValue != null) { + setPropertyValueOrUseParent(gatewaySenderBuilder, fieldName, resolvedPropertyValue, null, + defaultValue); } - return returnValue; - } - - private String getStringFromAnnotation(AnnotationAttributes gatewaySenderAnnotation, String annotationLabel) { - return getValueFromAnnotation(gatewaySenderAnnotation, - () -> gatewaySenderAnnotation.getString(annotationLabel)); - } - - private Integer getNumberFromAnnotation(AnnotationAttributes gatewaySenderAnnotation, String annotationLabel) { - return getValueFromAnnotation(gatewaySenderAnnotation, - () -> gatewaySenderAnnotation.getNumber(annotationLabel)); - } - - private String[] getStringArrayFromAnnotation(AnnotationAttributes gatewaySenderAnnotation, - String annotationLabel) { - return getValueFromAnnotation(gatewaySenderAnnotation, - () -> gatewaySenderAnnotation.getStringArray(annotationLabel)); } private Boolean getBooleanFromAnnotation(AnnotationAttributes gatewaySenderAnnotation, String annotationLabel) { @@ -317,130 +393,58 @@ public class GatewaySenderConfiguration extends AbstractAnnotationConfigSupport () -> gatewaySenderAnnotation.getBoolean(annotationLabel)); } - private T getValueFromAnnotation(AnnotationAttributes gatewaySenderAnnotation, Supplier supplier) { - if (gatewaySenderAnnotation == null) { - return null; - } - else { - return supplier.get(); - } - } + private Enum getEnumFromAnnotation(AnnotationAttributes gatewaySenderAnnotation, String annotationLabel, + Enum defaultValue) { - /** - * In this method a {@link GatewaySender} is configured from properties defined within an application.properties - * file. - * These properties are "named" properties and will follow the following pattern: - * {@literal spring.data.gemfire.gateway.sender..manual-start} - * - * @param gatewaySenderBeanBuilder - */ - private void configureGatewaySenderFromProperties(String gatewaySenderName, - BeanDefinitionBuilder gatewaySenderBeanBuilder) { - MutablePropertyValues beanPropertyValues = gatewaySenderBeanBuilder.getRawBeanDefinition().getPropertyValues(); - - gatewaySenderBeanBuilder.addPropertyValue("gatewaySenderConfigurers", resolveGatewaySenderConfigurers()); - - configureGatewaySenderFromProperty(gatewaySenderBeanBuilder, gatewaySenderName, - MANUAL_START_PROPERTY_NAME, MANUAL_START_LITERAL, DEFAULT_MANUAL_START); - - configureGatewaySenderFromProperty(gatewaySenderBeanBuilder, gatewaySenderName, - REMOTE_DIST_SYSTEM_ID_PROPERTY_NAME, REMOTE_DIST_SYSTEM_ID_LITERAL, DEFAULT_REMOTE_DISTRIBUTED_SYSTEM_ID); - - configureGatewaySenderFromProperty(gatewaySenderBeanBuilder, gatewaySenderName, - DISK_STORE_REFERENCE_PROPERTY_NAME, DISK_STORE_REFERENCE_LITERAL, new String[0]); - - configureGatewaySenderFromProperty(gatewaySenderBeanBuilder, gatewaySenderName, - DISK_SYNCHRONOUS_PROPERTY_NAME, DISK_SYNCHRONOUS_LITERAL, DEFAULT_DISK_SYNCHRONOUS); - - configureGatewaySenderFromProperty(gatewaySenderBeanBuilder, gatewaySenderName, - BATCH_CONFLATION_ENABLED_PROPERTY_NAME, BATCH_CONFLATION_ENABLED_LITERAL, DEFAULT_BATCH_CONFLATION_ENABLED); - - configureGatewaySenderFromProperty(gatewaySenderBeanBuilder, gatewaySenderName, - BATCH_SIZE_PROPERTY_NAME, BATCH_SIZE_LITERAL, DEFAULT_BATCH_SIZE); - - configureGatewaySenderFromProperty(gatewaySenderBeanBuilder, gatewaySenderName, - BATCH_TIME_INTERVAL_PROPERTY_NAME, BATCH_TIME_INTERVAL_LITERAL, DEFAULT_BATCH_TIME_INTERVAL); - - configureGatewaySenderFromProperty(gatewaySenderBeanBuilder, gatewaySenderName, - PARALLEL_PROPERTY_NAME, PARALLEL_LITERAL, DEFAULT_PARALLEL); - - configureGatewaySenderFromProperty(gatewaySenderBeanBuilder, gatewaySenderName, - PERSISTENT_PROPERTY_NAME, PERSISTENT_LITERAL, DEFAULT_PERSISTENT); - - configureGatewaySenderFromProperty(gatewaySenderBeanBuilder, gatewaySenderName, - ORDER_POLICY_PROPERTY_NAME, ORDER_POLICY_LITERAL, DEFAULT_ORDER_POLICY.toString()); - - configureBeanReferenceListFromProperty(gatewaySenderBeanBuilder, gatewaySenderName, - EVENT_FILTERS_PROPERTY_NAME, EVENT_FILTERS_LITERAL, DEFAULT_EVENT_FILTERS); - - configureBeanReferenceFromProperty(gatewaySenderBeanBuilder, gatewaySenderName, - EVENT_SUBSTITUTION_FILTER_PROPERTY_NAME, EVENT_SUBSTITUTION_FILTER_LITERAL, - DEFAULT_EVENT_SUBSTITUTION_FILTER); - - configureGatewaySenderFromProperty(gatewaySenderBeanBuilder, gatewaySenderName, - ALERT_THRESHOLD_PROPERTY_NAME, ALERT_THRESHOLD_LITERAL, DEFAULT_ALERT_THRESHOLD); - - configureGatewaySenderFromProperty(gatewaySenderBeanBuilder, gatewaySenderName, - DISPATCHER_THREAD_PROPERTY_NAME, DISPATCHER_THREAD_LITERAL, DEFAULT_DISPATCHER_THREADS); - - configureGatewaySenderFromProperty(gatewaySenderBeanBuilder, gatewaySenderName, - MAXIMUM_QUEUE_MEMORY_PROPERTY_NAME, MAXIMUM_QUEUE_MEMORY_LITERAL, DEFAULT_MAXIMUM_QUEUE_MEMORY); - - configureGatewaySenderFromProperty(gatewaySenderBeanBuilder, gatewaySenderName, - SOCKET_BUFFER_SIZE_PROPERTY_NAME, SOCKET_BUFFER_SIZE_LITERAL, DEFAULT_SOCKET_BUFFER_SIZE); - - configureGatewaySenderFromProperty(gatewaySenderBeanBuilder, gatewaySenderName, - SOCKET_READ_TIMEOUT_PROPERTY_NAME, SOCKET_READ_TIMEOUT_LITERAL, DEFAULT_SOCKET_READ_TIMEOUT); - - configureBeanReferenceListFromProperty(gatewaySenderBeanBuilder, gatewaySenderName, - TRANSPORT_FILTERS_PROPERTY_NAME, TRANSPORT_FILTERS_LITERAL, DEFAULT_TRANSPORT_FILTERS); - } - - /** - * In this method a {@link GatewaySender} is configured from properties defined within an application.properties - * file. - * These properties are "named" properties and will follow the following pattern: - * {@literal spring.data.gemfire.gateway.sender..manual-start} - * - * @param gatewaySenderBeanBuilder - * @param gatewaySenderName - * @param propertyName - * @param defaultValue - */ - private void configureGatewaySenderFromProperty(BeanDefinitionBuilder gatewaySenderBeanBuilder, - String gatewaySenderName, String propertyName, String fieldName, T defaultValue) { - - T resolvedPropertyValue = resolveValueFromProperty(gatewaySenderName, propertyName, defaultValue); - if (resolvedPropertyValue == null) { - return; - } - - setPropertyValueOrUseParent(gatewaySenderBeanBuilder, fieldName, resolvedPropertyValue, null, defaultValue); - } - - private void configureBeanReferenceListFromProperty(BeanDefinitionBuilder gatewaySenderBeanBuilder, - String gatewaySenderName, String propertyName, String fieldName, String[] defaultValue) { - - String[] resolvedPropertyValue = resolveValueFromProperty(gatewaySenderName, propertyName, defaultValue); - if (resolvedPropertyValue == null) { - return; - } - - setPropertyValueOrUseParentAsBeanReferenceList(gatewaySenderBeanBuilder, fieldName, resolvedPropertyValue, - new String[] {}, + return getValueFromAnnotation(gatewaySenderAnnotation, () -> gatewaySenderAnnotation.getEnum(annotationLabel), defaultValue); } + private Integer getNumberFromAnnotation(AnnotationAttributes gatewaySenderAnnotation, String annotationLabel) { + return getValueFromAnnotation(gatewaySenderAnnotation, + () -> gatewaySenderAnnotation.getNumber(annotationLabel)); + } + + private String getStringFromAnnotation(AnnotationAttributes gatewaySenderAnnotation, String annotationLabel) { + return getValueFromAnnotation(gatewaySenderAnnotation, + () -> gatewaySenderAnnotation.getString(annotationLabel)); + } + + private String[] getStringArrayFromAnnotation(AnnotationAttributes gatewaySenderAnnotation, String annotationLabel) { + return getValueFromAnnotation(gatewaySenderAnnotation, + () -> gatewaySenderAnnotation.getStringArray(annotationLabel)); + } + + private T getValueFromAnnotation(AnnotationAttributes gatewaySenderAnnotation, Supplier supplier) { + return gatewaySenderAnnotation != null ? supplier.get() : null; + } + + private T getValueFromAnnotation(AnnotationAttributes gatewaySenderAnnotation, Supplier supplier, + T defaultValue) { + + return gatewaySenderAnnotation != null ? supplier.get() : defaultValue; + } + private void configureBeanReferenceFromProperty(BeanDefinitionBuilder gatewaySenderBeanBuilder, - String gatewaySenderName, String propertyName, String fieldName, String defaultValue) { + String gatewaySenderName, String propertyName, String fieldName, String defaultValue) { String resolvedPropertyValue = resolveValueFromProperty(gatewaySenderName, propertyName, defaultValue); - if (resolvedPropertyValue == null) { - return; - } - setPropertyValueIfNotDefaultAsBeanReference(gatewaySenderBeanBuilder, fieldName, resolvedPropertyValue, null, - defaultValue); + if (resolvedPropertyValue != null) { + setPropertyValueIfNotDefaultAsBeanReference(gatewaySenderBeanBuilder, fieldName, resolvedPropertyValue, + null, defaultValue); + } + } + + private void configureBeanReferenceListFromProperty(BeanDefinitionBuilder gatewaySenderBeanBuilder, + String gatewaySenderName, String propertyName, String fieldName, String[] defaultValue) { + + String[] resolvedPropertyValue = resolveValueFromProperty(gatewaySenderName, propertyName, defaultValue); + + if (resolvedPropertyValue != null) { + setPropertyValueOrUseParentAsBeanReferenceList(gatewaySenderBeanBuilder, fieldName, resolvedPropertyValue, + new String[0], defaultValue); + } } private List resolveGatewaySenderConfigurers() { @@ -451,37 +455,40 @@ public class GatewaySenderConfiguration extends AbstractAnnotationConfigSupport Collections.singletonList(LazyResolvingComposableGatewaySenderConfigurer.create(getBeanFactory()))); } - private T resolveValueFromProperty(String gatewaySenderName, String propertyName, - T defaultValue) { - Class clazz = (Class) defaultValue.getClass(); + @SuppressWarnings("unchecked") + private T resolveValueFromProperty(String gatewaySenderName, String propertyName, T defaultValue) { - Optional gatewaySenderProperty = Optional - .ofNullable(resolveProperty(gatewaySenderProperty(propertyName), clazz, null)); + Class type = (Class) defaultValue.getClass(); - Optional namedGatewaySenderProperty = Optional.ofNullable( - resolveProperty(namedGatewaySenderProperty(gatewaySenderName, propertyName), clazz, null)); + T gatewaySenderProperty = resolveProperty(gatewaySenderProperty(propertyName), type, null); - return namedGatewaySenderProperty.orElse(gatewaySenderProperty.orElse(null)); + T namedGatewaySenderProperty = + resolveProperty(namedGatewaySenderProperty(gatewaySenderName, propertyName), type, null); + + return namedGatewaySenderProperty != null ? namedGatewaySenderProperty : gatewaySenderProperty; } private BeanDefinitionBuilder setPropertyValueIfNotDefault(BeanDefinitionBuilder beanDefinitionBuilder, - String propertyName, T value, T defaultValue) { + String propertyName, T value, T defaultValue) { return beanDefinitionBuilder.addPropertyValue(propertyName, Optional.ofNullable(value).orElse(defaultValue)); } private BeanDefinitionBuilder setPropertyValueOrUseParent(BeanDefinitionBuilder beanDefinitionBuilder, - String propertyName, T value, T parentValue, T defaultValue) { + String propertyName, T value, T parentValue, T defaultValue) { - T resolveValue = Optional.ofNullable(value).filter(childValue -> !childValue.equals(defaultValue)) - .orElse(Optional.ofNullable(parentValue).orElse(defaultValue)); - return beanDefinitionBuilder.addPropertyValue(propertyName, resolveValue); + T resolvedValue = Optional.ofNullable(value) + .filter(childValue -> !childValue.equals(defaultValue)) + .orElseGet(() -> Optional.ofNullable(parentValue).orElse(defaultValue)); + + return beanDefinitionBuilder.addPropertyValue(propertyName, resolvedValue); } private BeanDefinitionBuilder setPropertyValueIfNotDefaultAsBeanReference( - BeanDefinitionBuilder beanDefinitionBuilder, - String propertyName, String value, String parentValue, String defaultValue) { + BeanDefinitionBuilder beanDefinitionBuilder, String propertyName, String value, String parentValue, + String defaultValue) { + if (!StringUtils.isEmpty(value)) { return beanDefinitionBuilder.addPropertyReference(propertyName, value); } @@ -493,25 +500,24 @@ public class GatewaySenderConfiguration extends AbstractAnnotationConfigSupport beanDefinitionBuilder.addPropertyReference(propertyName, defaultValue); } } + return beanDefinitionBuilder; } - private BeanDefinitionBuilder setPropertyValueOrUseParentAsBeanReferenceList( - BeanDefinitionBuilder beanDefinitionBuilder, String propertyName, String[] values, String[] parentValues, - String[] defaultList) { + BeanDefinitionBuilder beanDefinitionBuilder, String propertyName, String[] values, String[] parentValues, + String[] defaultList) { + + String[] resolvedList = Optional.ofNullable(values) + .filter(it -> !Arrays.equals(it, defaultList)) + .orElseGet(() -> Optional.ofNullable(parentValues).orElse(defaultList)); + ManagedList beanReferences = new ManagedList<>(); - String[] resolvedList = Optional.ofNullable(values).filter(t -> !Arrays.equals(t, defaultList)) - .orElse(Optional.ofNullable(parentValues).orElse(defaultList)); Arrays.stream(resolvedList) .map(RuntimeBeanReference::new) .forEach(beanReferences::add); return beanDefinitionBuilder.addPropertyValue(propertyName, beanReferences); } - - @Override public void setImportMetadata(AnnotationMetadata annotationMetadata) { - - } } diff --git a/src/main/java/org/springframework/data/gemfire/config/annotation/GatewaySendersConfiguration.java b/src/main/java/org/springframework/data/gemfire/config/annotation/GatewaySendersConfiguration.java index d0424cee..de0c07a4 100644 --- a/src/main/java/org/springframework/data/gemfire/config/annotation/GatewaySendersConfiguration.java +++ b/src/main/java/org/springframework/data/gemfire/config/annotation/GatewaySendersConfiguration.java @@ -1,74 +1,85 @@ +/* + * Copyright 2010-2019 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ package org.springframework.data.gemfire.config.annotation; import java.lang.annotation.Annotation; -import java.util.Map; + +import org.apache.geode.cache.wan.GatewaySender; import org.springframework.beans.factory.support.BeanDefinitionRegistry; import org.springframework.context.annotation.Configuration; import org.springframework.core.annotation.AnnotationAttributes; import org.springframework.core.type.AnnotationMetadata; +import org.springframework.data.gemfire.util.ArrayUtils; /** - * Spring {@link Configuration} class used to construct, configure and initialize {@link org.apache.geode.cache.wan.GatewaySender} instances + * Spring {@link Configuration} class used to construct, configure and initialize {@link GatewaySender} instances * in a Spring application context. * * @author Udo Kohlmeyer * @author John Blum - * @see EnableGatewaySender - * @see EnableGatewaySenders + * @see java.lang.annotation.Annotation * @see org.apache.geode.cache.wan.GatewayReceiver - * @see org.springframework.context.annotation.Bean + * @see org.apache.geode.cache.wan.GatewaySender * @see org.springframework.context.annotation.Configuration + * @see org.springframework.core.annotation.AnnotationAttributes + * @see org.springframework.core.type.AnnotationMetadata + * @see org.springframework.data.gemfire.config.annotation.EnableGatewaySender + * @see org.springframework.data.gemfire.config.annotation.EnableGatewaySenders * @since 2.2.0 */ @Configuration public class GatewaySendersConfiguration extends GatewaySenderConfiguration { - /** - * @param annotationMetadata - * @param beanDefinitionRegistry - */ @Override - public void registerBeanDefinitions(AnnotationMetadata annotationMetadata, - BeanDefinitionRegistry beanDefinitionRegistry) { - - if (annotationMetadata.hasAnnotation(EnableGatewaySenders.class.getName())) { - Map annotationAttributesMap = annotationMetadata - .getAnnotationAttributes(EnableGatewaySenders.class.getName()); - - AnnotationAttributes annotationAttributes = AnnotationAttributes.fromMap(annotationAttributesMap); - - registerGatewaySenders(annotationAttributes, beanDefinitionRegistry); - } - } - - /** - * @param gatewaySendersAnnotation - * @param registry - */ - private void registerGatewaySenders(AnnotationAttributes gatewaySendersAnnotation, - BeanDefinitionRegistry registry) { - - AnnotationAttributes[] gatewaySenders = gatewaySendersAnnotation.getAnnotationArray("gatewaySenders"); - if (gatewaySenders.length == 0) { - registerDefaultGatewaySender(registry, gatewaySendersAnnotation); - } - else { - for (AnnotationAttributes gatewaySender : gatewaySenders) { - registerGatewaySender(gatewaySender, registry, gatewaySendersAnnotation); - } - } - } - - - @Override protected Class getAnnotationType() { + protected Class getAnnotationType() { return EnableGatewaySenders.class; } - private void registerDefaultGatewaySender(BeanDefinitionRegistry registry, - AnnotationAttributes parentGatewaySendersAnnotation) { - registerGatewaySender("GatewaySender", parentGatewaySendersAnnotation, registry, - parentGatewaySendersAnnotation); + @Override + public void registerBeanDefinitions(AnnotationMetadata annotationMetadata, BeanDefinitionRegistry registry) { + if (isAnnotationPresent(annotationMetadata)) { + + AnnotationAttributes parentGatewaySendersAnnotation = getAnnotationAttributes(annotationMetadata); + + registerGatewaySenders(parentGatewaySendersAnnotation, registry); + } + } + + private void registerGatewaySenders(AnnotationAttributes parentGatewaySendersAnnotation, + BeanDefinitionRegistry registry) { + + AnnotationAttributes[] gatewaySenderAnnotations = + parentGatewaySendersAnnotation.getAnnotationArray("gatewaySenders"); + + if (ArrayUtils.isNotEmpty(gatewaySenderAnnotations)) { + for (AnnotationAttributes gatewaySenderAnnotation : gatewaySenderAnnotations) { + registerGatewaySender(gatewaySenderAnnotation, parentGatewaySendersAnnotation, registry); + } + } + else { + registerDefaultGatewaySender(parentGatewaySendersAnnotation, registry); + } + } + + private void registerDefaultGatewaySender(AnnotationAttributes parentGatewaySendersAnnotation, + BeanDefinitionRegistry registry) { + + registerGatewaySender("GatewaySender", parentGatewaySendersAnnotation, + parentGatewaySendersAnnotation, registry); } } diff --git a/src/main/java/org/springframework/data/gemfire/config/annotation/LazyResolvingComposableGatewaySenderConfigurer.java b/src/main/java/org/springframework/data/gemfire/config/annotation/LazyResolvingComposableGatewaySenderConfigurer.java index 9e4cbafe..de274966 100644 --- a/src/main/java/org/springframework/data/gemfire/config/annotation/LazyResolvingComposableGatewaySenderConfigurer.java +++ b/src/main/java/org/springframework/data/gemfire/config/annotation/LazyResolvingComposableGatewaySenderConfigurer.java @@ -13,7 +13,6 @@ * See the License for the specific language governing permissions and * limitations under the License. */ - package org.springframework.data.gemfire.config.annotation; import org.springframework.beans.factory.BeanFactory; @@ -31,8 +30,8 @@ import org.springframework.lang.Nullable; * @since 2.2.0 */ public class LazyResolvingComposableGatewaySenderConfigurer - extends AbstractLazyResolvingComposableConfigurer - implements GatewaySenderConfigurer { + extends AbstractLazyResolvingComposableConfigurer + implements GatewaySenderConfigurer { public static LazyResolvingComposableGatewaySenderConfigurer create() { return create(null); diff --git a/src/main/java/org/springframework/data/gemfire/config/annotation/support/AbstractAnnotationConfigSupport.java b/src/main/java/org/springframework/data/gemfire/config/annotation/support/AbstractAnnotationConfigSupport.java index 6cc976d0..976f9186 100644 --- a/src/main/java/org/springframework/data/gemfire/config/annotation/support/AbstractAnnotationConfigSupport.java +++ b/src/main/java/org/springframework/data/gemfire/config/annotation/support/AbstractAnnotationConfigSupport.java @@ -30,6 +30,9 @@ import java.util.Optional; import java.util.Set; import java.util.function.Supplier; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + import org.springframework.beans.BeansException; import org.springframework.beans.factory.BeanClassLoaderAware; import org.springframework.beans.factory.BeanFactory; @@ -57,9 +60,6 @@ import org.springframework.expression.spel.support.StandardTypeLocator; import org.springframework.util.ClassUtils; import org.springframework.util.StringUtils; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - /** * The {@link AbstractAnnotationConfigSupport} class is an abstract base class encapsulating functionality * common to all Annotations and configuration classes used to configure Pivotal GemFire/Apache Geode objects @@ -779,14 +779,14 @@ public abstract class AbstractAnnotationConfigSupport return String.format("%1$s%2$s", propertyName("gateway.receiver."), propertyNameSuffix); } - protected String namedGatewaySenderProperty(String name, String propertyNameSuffix) { - return String.format("%1$s%2$s.%3$s", propertyName("gateway.sender."), name, propertyNameSuffix); - } - protected String gatewaySenderProperty(String propertyNameSuffix) { return String.format("%1$s%2$s", propertyName("gateway.sender."), propertyNameSuffix); } + protected String namedGatewaySenderProperty(String name, String propertyNameSuffix) { + return String.format("%1$s%2$s.%3$s", propertyName("gateway.sender."), name, propertyNameSuffix); + } + /** * Returns the fully-qualified {@link String property name}. * diff --git a/src/main/java/org/springframework/data/gemfire/config/support/GatewaySenderBeanFactoryPostProcessor.java b/src/main/java/org/springframework/data/gemfire/config/support/GatewaySenderBeanFactoryPostProcessor.java index c510cd81..9225bbb5 100644 --- a/src/main/java/org/springframework/data/gemfire/config/support/GatewaySenderBeanFactoryPostProcessor.java +++ b/src/main/java/org/springframework/data/gemfire/config/support/GatewaySenderBeanFactoryPostProcessor.java @@ -1,8 +1,21 @@ +/* + * Copyright 2010-2019 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ package org.springframework.data.gemfire.config.support; -import static java.util.Arrays.stream; -import static org.springframework.data.gemfire.util.ArrayUtils.nullSafeArray; - +import java.lang.annotation.Annotation; import java.util.ArrayList; import java.util.Arrays; import java.util.Collection; @@ -13,9 +26,11 @@ import java.util.Map; import java.util.Optional; import java.util.stream.Collectors; +import org.apache.geode.cache.Region; +import org.apache.geode.cache.wan.GatewaySender; + import org.springframework.beans.BeansException; import org.springframework.beans.PropertyValue; -import org.springframework.beans.factory.annotation.AnnotatedBeanDefinition; import org.springframework.beans.factory.config.BeanDefinition; import org.springframework.beans.factory.config.BeanFactoryPostProcessor; import org.springframework.beans.factory.config.ConfigurableListableBeanFactory; @@ -23,149 +38,171 @@ import org.springframework.beans.factory.config.RuntimeBeanReference; import org.springframework.beans.factory.support.ManagedList; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; -import org.springframework.core.type.MethodMetadata; import org.springframework.data.gemfire.PeerRegionFactoryBean; -import org.springframework.data.gemfire.util.SpringUtils; +import org.springframework.data.gemfire.config.annotation.support.AbstractAnnotationConfigSupport; +import org.springframework.data.gemfire.util.ArrayUtils; import org.springframework.data.gemfire.wan.GatewaySenderFactoryBean; -import org.springframework.util.StringUtils; /** * A {@link BeanFactoryPostProcessor} to associate the configured {@link org.apache.geode.cache.wan.GatewaySender} * onto the corresponding {@link org.apache.geode.cache.Region}. * * @author Udo Kohlmeyer + * @author John Blum + * @see org.apache.geode.cache.Region + * @see org.apache.geode.cache.wan.GatewaySender + * @see org.springframework.beans.factory.config.BeanDefinition + * @see org.springframework.beans.factory.config.BeanFactoryPostProcessor + * @see org.springframework.beans.factory.config.ConfigurableListableBeanFactory + * @see org.springframework.beans.factory.config.RuntimeBeanReference + * @see org.springframework.beans.factory.support.ManagedList + * @see org.springframework.context.annotation.Bean + * @see org.springframework.context.annotation.Configuration + * @see org.springframework.data.gemfire.PeerRegionFactoryBean + * @see org.springframework.data.gemfire.config.annotation.support.AbstractAnnotationConfigSupport + * @see org.springframework.data.gemfire.wan.GatewaySenderFactoryBean * @since 2.2.0 */ @Configuration -public class GatewaySenderBeanFactoryPostProcessor { +public class GatewaySenderBeanFactoryPostProcessor extends AbstractAnnotationConfigSupport { + + @Override + protected Class getAnnotationType() { + return null; + } /** - * BeanFactory PostProcessor to map {@link GatewaySenderFactoryBean} to {@link org.apache.geode.cache.Region} + * {@link BeanFactoryPostProcessor} assigning {@link GatewaySender GatewaySenders} to {@link Region Regions}. * - * @return BeanFactoryPostProcessor for the GatewaySenderFactoryBean - * @throws BeansException + * @return {@link BeanFactoryPostProcessor} for the {@link GatewaySenderFactoryBean}. + * @throws BeansException {@link org.springframework.beans.factory.BeanFactory} post processing fails. + * @see #populateBeanDefinitionCache(ConfigurableListableBeanFactory) + * @see #groupGatewaySenderPerRegion(Map, Map) + * @see #addGatewaySendersToRegionFactory(ConfigurableListableBeanFactory, Map) */ @Bean public BeanFactoryPostProcessor postProcessBeanFactory() throws BeansException { + return beanFactory -> { - //Create a map of cached BeanDefinitions. Mapped under 'regions' and 'gatewaySenders' for easier lookups + + // Create a map of cached BeanDefinitions. Mapped under 'regions' and 'gatewaySenders' for easier lookups Map> cachedBeanDefinitions = populateBeanDefinitionCache(beanFactory); - //Create a list of gatewaySender to Regions mapping - Map> gatewaySenderToRegions = groupGatewaySenderPerRegion(cachedBeanDefinitions, - new HashMap<>()); + // Create a list of gatewaySender to Regions mapping + Map> gatewaySenderToRegions = + groupGatewaySenderPerRegion(cachedBeanDefinitions, new HashMap<>()); - //Add + // Add addGatewaySendersToRegionFactory(beanFactory, gatewaySenderToRegions); }; } + /** + * Caches BeanDefinitions for GatewaySenders and Regions. Maps the beandefinitions under the keys of + * `regions` and `gatewaySenders` + * + * @return {@link Map} containing all {@link BeanDefinition BeanDefinitions} for {@link Region Regions} + * and {@link GatewaySender GatewaySenders}. + */ + private Map> populateBeanDefinitionCache( + ConfigurableListableBeanFactory beanFactory) { + + Map> cachedBeanDefinitions = new LinkedHashMap<>(); + + Arrays.stream(ArrayUtils.nullSafeArray(beanFactory.getBeanDefinitionNames(), String.class)) + .forEach(beanName -> { + + BeanDefinition beanDefinition = beanFactory.getBeanDefinition(beanName); + + if (isRegionBean(beanDefinition, beanFactory)) { + addBeanDefinitionToList(beanName, beanDefinition, cachedBeanDefinitions, "regions"); + } + else if (isGatewaySenderFactoryBean(beanDefinition)) { + addBeanDefinitionToList(beanName, beanDefinition, cachedBeanDefinitions, "gatewaySenders"); + } + }); + + return cachedBeanDefinitions; + } + /** * Determines if a {@link BeanDefinition} is of type {@link PeerRegionFactoryBean}, which means it is - * effectively of type {@link org.apache.geode.cache.Region} - * @param beanDefinition - * @param beanFactory - * @return {@literal boolean} + * effectively of type {@link Region}. + * + * @return {@literal boolean} indicating whether the Spring bean represents a {@link Region}. */ private boolean isRegionBean(BeanDefinition beanDefinition, ConfigurableListableBeanFactory beanFactory) { return Optional.ofNullable(beanDefinition) - .map(it -> resolveBeanClass(beanDefinition, beanFactory)) - .filter(beanClass -> beanClass.isPresent()) - .filter(beanClass -> PeerRegionFactoryBean.class.isAssignableFrom(beanClass.get())) + .flatMap(it -> resolveBeanClass(beanDefinition, beanFactory)) + .filter(PeerRegionFactoryBean.class::isAssignableFrom) .isPresent(); } - private void addGatewaySendersToRegionFactory(ConfigurableListableBeanFactory beanFactory, - Map> gatewaySenderToRegions) { - gatewaySenderToRegions.entrySet().forEach(entry -> { - List beanReferenceList = entry.getValue().stream() - .map(RuntimeBeanReference::new).collect(Collectors.toList()); - ManagedList runtimeBeanReferences = new ManagedList<>(); - runtimeBeanReferences.addAll(beanReferenceList); - Optional.ofNullable(beanFactory.getBeanDefinition(entry.getKey())).ifPresent(regionBeanDefinition -> - regionBeanDefinition.getPropertyValues().addPropertyValue("gatewaySenders", runtimeBeanReferences)); - }); + private boolean isGatewaySenderFactoryBean(BeanDefinition beanDefinition) { + return GatewaySenderFactoryBean.class.getName().equals(beanDefinition.getBeanClassName()); } /** - * Mapping of GatewaySender to Regions. - * @param cachedBeanDefinitions - * @param gatewaySendersPerRegion - * @return + * Creates a {@link Map} of {@literal <, List>} grouped by the {@literal key}. + */ + private Map> addBeanDefinitionToList(String beanName, + BeanDefinition beanDefinition, Map> cachedBeanDefinitions, String key) { + + Map beanDefinitions = cachedBeanDefinitions.computeIfAbsent(key, k -> new HashMap<>()); + + beanDefinitions.put(beanName, beanDefinition); + + return cachedBeanDefinitions; + } + + /** + * Mapping of {@link GatewaySender} to {@link Region Regions}. */ private Map> groupGatewaySenderPerRegion( - Map> cachedBeanDefinitions, - Map> gatewaySendersPerRegion) { + Map> cachedBeanDefinitions, + Map> gatewaySendersPerRegion) { - Optional> gatewaySenders = Optional - .ofNullable(cachedBeanDefinitions.get("gatewaySenders")); + Optional> gatewaySenders = + Optional.ofNullable(cachedBeanDefinitions.get("gatewaySenders")); - gatewaySenders.ifPresent(gatewaySendersMap -> gatewaySendersMap.forEach((key, gatewaySenderEntryValue) -> { + gatewaySenders.ifPresent(gatewaySendersMap -> gatewaySendersMap.forEach((key, gatewaySenderBean) -> { - PropertyValue regions = gatewaySenderEntryValue.getPropertyValues().getPropertyValue("regions"); - Optional regionsOptional = Optional.ofNullable(regions); + PropertyValue regions = gatewaySenderBean.getPropertyValues() + .getPropertyValue("regions"); - Collection regionNames; List namedRegions = new ArrayList<>(); - regionsOptional.ifPresent(valueHolder -> namedRegions.addAll(Arrays.asList((String[]) valueHolder.getValue()))); - if (namedRegions.size() == 0) { - //Add gatewaySender to all Regions - regionNames = cachedBeanDefinitions.get("regions").keySet(); - } - else { - //Add gatewaySender to named Regions - regionNames = namedRegions; - } - addGatewaySendersToRegion(gatewaySendersPerRegion, key, - regionNames); + Optional.ofNullable(regions) + .map(PropertyValue::getValue) + .filter(String[].class::isInstance) + .map(String[].class::cast) + .map(Arrays::asList) + .ifPresent(namedRegions::addAll); + + Collection regionNames = !namedRegions.isEmpty() + ? namedRegions // Add GatewaySender to named Regions + : cachedBeanDefinitions.get("regions").keySet(); // Add GatewaySender to all Regions + + addGatewaySendersToRegion(gatewaySendersPerRegion, key, regionNames); })); return gatewaySendersPerRegion; } - /** - * Caches BeanDefinitions for GatewaySenders and Regions. Maps the beandefinitions under the keys of - * `regions` and `gatewaySenders` - * @param beanFactory - * @return Map containing all BeanDefinitions for Regions and GatewaySenders - */ - private Map> populateBeanDefinitionCache( - ConfigurableListableBeanFactory beanFactory) { - Map> cachedBeanDefinitions = new LinkedHashMap<>(); - stream(nullSafeArray(beanFactory.getBeanDefinitionNames(), String.class)) - .forEach(beanName -> Optional.of(beanFactory.getBeanDefinition(beanName)) - .ifPresent(beanDefinition -> { - if (isRegionBean(beanDefinition, beanFactory)) { - addBeanDefinitionToList(beanName, beanDefinition, cachedBeanDefinitions, "regions"); - } - else if (isGatewaySenderFactoryBean(beanDefinition)) { - addBeanDefinitionToList(beanName, beanDefinition, cachedBeanDefinitions, "gatewaySenders"); - } - })); - return cachedBeanDefinitions; - } + private void addGatewaySendersToRegionFactory(ConfigurableListableBeanFactory beanFactory, + Map> gatewaySenderToRegions) { - /** - * Creates a map of <,List> grouped by the `key` - * - * @param beanName - * @param beanDefinition - * @param cachedBeanDefinitions - * @param key - * @return - */ - private Map> addBeanDefinitionToList(String beanName, - BeanDefinition beanDefinition, - Map> cachedBeanDefinitions, String key) { - Map beanDefinitions = cachedBeanDefinitions.get(key); - if (beanDefinitions == null) { - beanDefinitions = new HashMap<>(); - } - beanDefinitions.put(beanName, beanDefinition); - cachedBeanDefinitions.put(key, beanDefinitions); - return cachedBeanDefinitions; + gatewaySenderToRegions.forEach((key, value) -> { + + ManagedList runtimeBeanReferences = value.stream() + .map(RuntimeBeanReference::new) + .collect(Collectors.toCollection(() -> new ManagedList<>())); + + Optional.ofNullable(beanFactory.getBeanDefinition(key)).ifPresent(regionBeanDefinition -> + regionBeanDefinition.getPropertyValues() + .addPropertyValue("gatewaySenders", runtimeBeanReferences)); + }); } /** @@ -174,58 +211,14 @@ public class GatewaySenderBeanFactoryPostProcessor { * @param gatewaySenderName The GatewaySender that is to be mapped to the regions * @param regionNames Collection of defined regions that need to have gatewaySenders mapped to them. */ - private void addGatewaySendersToRegion(Map> regionMapping, - String gatewaySenderName, Collection regionNames) { + private void addGatewaySendersToRegion(Map> regionMapping, String gatewaySenderName, + Collection regionNames) { + regionNames.forEach(regionName -> { - List gatewaySenders = regionMapping.get(regionName); - if (gatewaySenders == null) { - gatewaySenders = new ArrayList<>(); - } + + List gatewaySenders = regionMapping.computeIfAbsent(regionName, k -> new ArrayList<>()); + gatewaySenders.add(gatewaySenderName); - regionMapping.put(regionName, gatewaySenders); - }); - } - - private boolean isGatewaySenderFactoryBean(BeanDefinition beanDefinition) { - return GatewaySenderFactoryBean.class.getName() - .equals(beanDefinition.getBeanClassName()); - } - - protected Optional getPropertyValue(BeanDefinition beanDefinition, String propertyName) { - return SpringUtils.getPropertyValue(beanDefinition, propertyName); - } - - /** - * Resolves the class type name of the bean defined by the given {@link BeanDefinition}. - * - * @param beanDefinition {@link BeanDefinition} defining the bean from which to resolve the class type name. - * @return an {@link Optional} {@link String} containing the resolved class type name of the bean defined - * by the given {@link BeanDefinition}. - * @see org.springframework.beans.factory.config.BeanDefinition#getBeanClassName() - */ - protected Optional resolveBeanClass(BeanDefinition beanDefinition, - ConfigurableListableBeanFactory beanFactory) { - - Optional beanClassName = Optional.ofNullable(beanDefinition) - .map(BeanDefinition::getBeanClassName) - .filter(StringUtils::hasText); - - if (!beanClassName.isPresent()) { - beanClassName = Optional.ofNullable(beanDefinition) - .filter(it -> it instanceof AnnotatedBeanDefinition) - .filter(it -> StringUtils.hasText(it.getFactoryMethodName())) - .map(it -> ((AnnotatedBeanDefinition) it).getFactoryMethodMetadata()) - .map(MethodMetadata::getReturnTypeName); - } - - return beanClassName.map(className -> { - try { - return beanFactory.getBeanClassLoader().loadClass(className); - } - catch (ClassNotFoundException e) { - e.printStackTrace(); - } - return null; }); } } diff --git a/src/main/java/org/springframework/data/gemfire/util/ArrayUtils.java b/src/main/java/org/springframework/data/gemfire/util/ArrayUtils.java index cad96aed..03961808 100644 --- a/src/main/java/org/springframework/data/gemfire/util/ArrayUtils.java +++ b/src/main/java/org/springframework/data/gemfire/util/ArrayUtils.java @@ -10,7 +10,6 @@ * 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.data.gemfire.util; import java.lang.reflect.Array; @@ -125,6 +124,17 @@ public abstract class ArrayUtils { return length(array) == 0; } + /** + * Determines whether the given array is empty or not. + * + * @param array the array to evaluate for emptiness. + * @return a boolean value indicating whether the given array is empty. + * @see #isEmpty(Object[]) + */ + public static boolean isNotEmpty(Object[] array) { + return !isEmpty(array); + } + /** * Null-safe operation to determine an array's length. * diff --git a/src/main/java/org/springframework/data/gemfire/wan/AbstractWANComponentFactoryBean.java b/src/main/java/org/springframework/data/gemfire/wan/AbstractWANComponentFactoryBean.java index d839e450..649a2533 100644 --- a/src/main/java/org/springframework/data/gemfire/wan/AbstractWANComponentFactoryBean.java +++ b/src/main/java/org/springframework/data/gemfire/wan/AbstractWANComponentFactoryBean.java @@ -17,8 +17,10 @@ package org.springframework.data.gemfire.wan; import org.apache.geode.cache.Cache; import org.apache.geode.cache.GemFireCache; + import org.slf4j.Logger; import org.slf4j.LoggerFactory; + import org.springframework.beans.factory.DisposableBean; import org.springframework.beans.factory.InitializingBean; import org.springframework.beans.factory.annotation.Autowired; @@ -31,6 +33,7 @@ import org.springframework.util.StringUtils; * * @author David Turanski * @author John Blum + * @author Udo Kohlmeyer * @see org.apache.geode.cache.Cache * @see org.springframework.beans.factory.DisposableBean * @see org.springframework.beans.factory.FactoryBean @@ -50,8 +53,7 @@ public abstract class AbstractWANComponentFactoryBean extends AbstractFactory private String beanName; private String name; - protected AbstractWANComponentFactoryBean() { - } + protected AbstractWANComponentFactoryBean() { } protected AbstractWANComponentFactoryBean(GemFireCache cache) { this.cache = (Cache) cache; @@ -62,6 +64,10 @@ public abstract class AbstractWANComponentFactoryBean extends AbstractFactory this.beanName = beanName; } + public void setCache(Cache cache) { + this.cache = cache; + } + public void setFactory(Object factory) { this.factory = factory; } @@ -70,10 +76,6 @@ public abstract class AbstractWANComponentFactoryBean extends AbstractFactory this.name = name; } - public void setCache(Cache cache) { - this.cache = cache; - } - public String getName() { return StringUtils.hasText(this.name) diff --git a/src/main/java/org/springframework/data/gemfire/wan/GatewaySenderFactoryBean.java b/src/main/java/org/springframework/data/gemfire/wan/GatewaySenderFactoryBean.java index 87fb76d1..b6c90dd4 100644 --- a/src/main/java/org/springframework/data/gemfire/wan/GatewaySenderFactoryBean.java +++ b/src/main/java/org/springframework/data/gemfire/wan/GatewaySenderFactoryBean.java @@ -13,12 +13,12 @@ * See the License for the specific language governing permissions and * limitations under the License. */ - package org.springframework.data.gemfire.wan; import static java.util.stream.StreamSupport.stream; import static org.springframework.data.gemfire.util.CollectionUtils.nullSafeIterable; +import java.util.ArrayList; import java.util.Arrays; import java.util.Collections; import java.util.List; @@ -31,9 +31,12 @@ import org.apache.geode.cache.wan.GatewayEventSubstitutionFilter; import org.apache.geode.cache.wan.GatewaySender; import org.apache.geode.cache.wan.GatewaySenderFactory; import org.apache.geode.cache.wan.GatewayTransportFilter; + import org.apache.shiro.util.StringUtils; + import org.springframework.beans.factory.FactoryBean; import org.springframework.data.gemfire.config.annotation.GatewaySenderConfigurer; +import org.springframework.data.gemfire.util.ArrayUtils; import org.springframework.data.gemfire.util.CollectionUtils; /** @@ -42,10 +45,11 @@ import org.springframework.data.gemfire.util.CollectionUtils; * @author David Turanski * @author John Blum * @author Udo Kohlmeyer - * @see org.springframework.data.gemfire.wan.AbstractWANComponentFactoryBean * @see org.apache.geode.cache.Cache + * @see org.apache.geode.cache.GemFireCache * @see org.apache.geode.cache.wan.GatewaySender * @see org.apache.geode.cache.wan.GatewaySenderFactory + * @see org.springframework.data.gemfire.wan.AbstractWANComponentFactoryBean * @since 1.2.2 */ @SuppressWarnings("unused") @@ -78,11 +82,14 @@ public class GatewaySenderFactoryBean extends AbstractWANComponentFactoryBean gatewaySenderConfigurers = Collections.emptyList(); - private List regions; + // TODO: Come of with better association and remove. + private List regions = new ArrayList<>(); + + private String diskStoreReference; + + public GatewaySenderFactoryBean() { } /** * Constructs an instance of the {@link GatewaySenderFactoryBean} class initialized with a reference to @@ -93,10 +100,6 @@ public class GatewaySenderFactoryBean extends AbstractWANComponentFactoryBean gatewaySenderConfigurer1.configure(getName(), this)); + stream(nullSafeIterable(this.gatewaySenderConfigurers).spliterator(), false) + .forEach(it -> it.configure(getName(), this)); - Optional.ofNullable(this.alertThreshold).ifPresent(gatewaySenderFactory::setAlertThreshold); - Optional.ofNullable(this.batchConflationEnabled).ifPresent(gatewaySenderFactory::setBatchConflationEnabled); - Optional.ofNullable(this.batchSize).ifPresent(gatewaySenderFactory::setBatchSize); - Optional.ofNullable(this.batchTimeInterval).ifPresent(gatewaySenderFactory::setBatchTimeInterval); + Optional.ofNullable(getAlertThreshold()).ifPresent(gatewaySenderFactory::setAlertThreshold); + Optional.ofNullable(getBatchConflationEnabled()).ifPresent(gatewaySenderFactory::setBatchConflationEnabled); + Optional.ofNullable(getBatchSize()).ifPresent(gatewaySenderFactory::setBatchSize); + Optional.ofNullable(getBatchTimeInterval()).ifPresent(gatewaySenderFactory::setBatchTimeInterval); - Optional.ofNullable(this.diskStoreReference) + Optional.ofNullable(getDiskStoreReference()) .filter(StringUtils::hasText) .ifPresent(gatewaySenderFactory::setDiskStoreName); - Optional.ofNullable(this.diskSynchronous).ifPresent(gatewaySenderFactory::setDiskSynchronous); - Optional.ofNullable(this.dispatcherThreads).ifPresent(gatewaySenderFactory::setDispatcherThreads); + Optional.ofNullable(getDiskSynchronous()).ifPresent(gatewaySenderFactory::setDiskSynchronous); + Optional.ofNullable(getDispatcherThreads()).ifPresent(gatewaySenderFactory::setDispatcherThreads); - CollectionUtils.nullSafeList(this.eventFilters).forEach(gatewaySenderFactory::addGatewayEventFilter); + CollectionUtils.nullSafeList(getEventFilters()).forEach(gatewaySenderFactory::addGatewayEventFilter); - Optional.ofNullable(this.eventSubstitutionFilter) + Optional.ofNullable(getEventSubstitutionFilter()) .ifPresent(gatewaySenderFactory::setGatewayEventSubstitutionFilter); - gatewaySenderFactory.setManualStart(this.manualStart); + gatewaySenderFactory.setManualStart(isManualStart()); - Optional.ofNullable(this.maximumQueueMemory).ifPresent(gatewaySenderFactory::setMaximumQueueMemory); - Optional.ofNullable(this.orderPolicy).ifPresent(gatewaySenderFactory::setOrderPolicy); + Optional.ofNullable(getMaximumQueueMemory()).ifPresent(gatewaySenderFactory::setMaximumQueueMemory); + Optional.ofNullable(getOrderPolicy()).ifPresent(gatewaySenderFactory::setOrderPolicy); gatewaySenderFactory.setParallel(isParallelGatewaySender()); gatewaySenderFactory.setPersistenceEnabled(isPersistent()); - Optional.ofNullable(this.socketBufferSize).ifPresent(gatewaySenderFactory::setSocketBufferSize); - Optional.ofNullable(this.socketReadTimeout).ifPresent(gatewaySenderFactory::setSocketReadTimeout); + Optional.ofNullable(getSocketBufferSize()).ifPresent(gatewaySenderFactory::setSocketBufferSize); + Optional.ofNullable(getSocketReadTimeout()).ifPresent(gatewaySenderFactory::setSocketReadTimeout); - CollectionUtils.nullSafeList(this.transportFilters).forEach(gatewaySenderFactory::addGatewayTransportFilter); + CollectionUtils.nullSafeList(getTransportFilters()).forEach(gatewaySenderFactory::addGatewayTransportFilter); GatewaySenderWrapper wrapper = - new GatewaySenderWrapper(gatewaySenderFactory.create(getName(), this.remoteDistributedSystemId)); + new GatewaySenderWrapper(gatewaySenderFactory.create(getName(), getRemoteDistributedSystemId())); - wrapper.setManualStart(this.manualStart); + wrapper.setManualStart(isManualStart()); this.gatewaySender = wrapper; } @@ -173,183 +176,191 @@ public class GatewaySenderFactoryBean extends AbstractWANComponentFactoryBean getEventFilters() { - return eventFilters; - } - - public void setEventFilters(List eventFilters) { - this.eventFilters = eventFilters; - } - - public List getTransportFilters() { - return transportFilters; - } - - public void setTransportFilters(List transportFilters) { - this.transportFilters = transportFilters; - } - - public Boolean getDiskSynchronous() { - return diskSynchronous; - } - - public void setDiskSynchronous(Boolean diskSynchronous) { - this.diskSynchronous = diskSynchronous; - } - - public void setManualStart(Boolean manualStart) { - this.manualStart = Boolean.TRUE.equals(manualStart); - } - - public void setBatchConflationEnabled(Boolean batchConflationEnabled) { - this.batchConflationEnabled = batchConflationEnabled; - } - - public void setParallel(Boolean parallel) { - this.parallel = parallel; - } - - public boolean isSerialGatewaySender() { - return !isParallelGatewaySender(); - } - - public boolean isParallelGatewaySender() { - return Boolean.TRUE.equals(this.parallel); - } - - public boolean isNotPersistent() { - return !isPersistent(); - } - - public boolean isPersistent() { - return Boolean.TRUE.equals(this.persistent); - } - - public void setPersistent(Boolean persistent) { - this.persistent = persistent; - } - - public GatewaySender.OrderPolicy getOrderPolicy() { - return orderPolicy; - } - - public void setOrderPolicy(GatewaySender.OrderPolicy orderPolicy) { - this.orderPolicy = orderPolicy; - } - - public GatewayEventSubstitutionFilter getEventSubstitutionFilter() { - return eventSubstitutionFilter; - } - - public void setEventSubstitutionFilter(GatewayEventSubstitutionFilter eventSubstitutionFilter) { - this.eventSubstitutionFilter = eventSubstitutionFilter; - } - - public Integer getAlertThreshold() { - return alertThreshold; - } - - public void setAlertThreshold(Integer alertThreshold) { - this.alertThreshold = alertThreshold; - } - - public Integer getBatchSize() { - return batchSize; - } - - public void setBatchSize(Integer batchSize) { - this.batchSize = batchSize; - } - - public Integer getBatchTimeInterval() { - return batchTimeInterval; - } - - public void setBatchTimeInterval(Integer batchTimeInterval) { - this.batchTimeInterval = batchTimeInterval; - } - - public Integer getDispatcherThreads() { - return dispatcherThreads; - } - - public void setDispatcherThreads(Integer dispatcherThreads) { - this.dispatcherThreads = dispatcherThreads; - } - - public Integer getMaximumQueueMemory() { - return maximumQueueMemory; - } - - public void setMaximumQueueMemory(Integer maximumQueueMemory) { - this.maximumQueueMemory = maximumQueueMemory; - } - - public Integer getSocketBufferSize() { - return socketBufferSize; - } - - public void setSocketBufferSize(Integer socketBufferSize) { - this.socketBufferSize = socketBufferSize; - } - - public Integer getSocketReadTimeout() { - return socketReadTimeout; - } - - public void setSocketReadTimeout(Integer socketReadTimeout) { - this.socketReadTimeout = socketReadTimeout; - } - - public String getDiskStoreReference() { - return diskStoreReference; - } - - public void setDiskStoreReference(String diskStoreReference) { - this.diskStoreReference = diskStoreReference; + public GatewaySender getGatewaySender() { + return this.gatewaySender; } public void setGatewaySenderConfigurers(List gatewaySenderConfigurers) { this.gatewaySenderConfigurers = gatewaySenderConfigurers; } + public void setAlertThreshold(Integer alertThreshold) { + this.alertThreshold = alertThreshold; + } + + public Integer getAlertThreshold() { + return this.alertThreshold; + } + + public void setBatchConflationEnabled(Boolean batchConflationEnabled) { + this.batchConflationEnabled = batchConflationEnabled; + } + + public Boolean getBatchConflationEnabled() { + return this.batchConflationEnabled; + } + + public void setBatchSize(Integer batchSize) { + this.batchSize = batchSize; + } + + public Integer getBatchSize() { + return this.batchSize; + } + + public void setBatchTimeInterval(Integer batchTimeInterval) { + this.batchTimeInterval = batchTimeInterval; + } + + public Integer getBatchTimeInterval() { + return this.batchTimeInterval; + } + public void setDiskStoreRef(String diskStoreRef) { - this.diskStoreReference = diskStoreRef; + setDiskStoreReference(diskStoreRef); } - private List getRegions() { - return regions; + public void setDiskStoreReference(String diskStoreReference) { + this.diskStoreReference = diskStoreReference; } - public void setRegions(List regions) { - this.regions = regions; + public String getDiskStoreReference() { + return this.diskStoreReference; + } + + public void setDiskSynchronous(Boolean diskSynchronous) { + this.diskSynchronous = diskSynchronous; + } + + public Boolean getDiskSynchronous() { + return this.diskSynchronous; + } + + public void setDispatcherThreads(Integer dispatcherThreads) { + this.dispatcherThreads = dispatcherThreads; + } + + public Integer getDispatcherThreads() { + return this.dispatcherThreads; + } + + public void setEventFilters(List eventFilters) { + this.eventFilters = eventFilters; + } + + public List getEventFilters() { + return this.eventFilters; + } + + public void setEventSubstitutionFilter(GatewayEventSubstitutionFilter eventSubstitutionFilter) { + this.eventSubstitutionFilter = eventSubstitutionFilter; + } + + public GatewayEventSubstitutionFilter getEventSubstitutionFilter() { + return this.eventSubstitutionFilter; + } + + public void setManualStart(boolean manualStart) { + this.manualStart = manualStart; + } + + public void setManualStart(Boolean manualStart) { + setManualStart(Boolean.TRUE.equals(manualStart)); + } + + public boolean isManualStart() { + return this.manualStart; + } + + public void setMaximumQueueMemory(Integer maximumQueueMemory) { + this.maximumQueueMemory = maximumQueueMemory; + } + + public Integer getMaximumQueueMemory() { + return this.maximumQueueMemory; + } + + public void setOrderPolicy(GatewaySender.OrderPolicy orderPolicy) { + this.orderPolicy = orderPolicy; + } + + public void setOrderPolicy(OrderPolicyType orderPolicy) { + setOrderPolicy(orderPolicy != null ? orderPolicy.getOrderPolicy() : null); + } + + public GatewaySender.OrderPolicy getOrderPolicy() { + return this.orderPolicy; + } + + public void setParallel(Boolean parallel) { + this.parallel = parallel; + } + + public boolean isParallelGatewaySender() { + return Boolean.TRUE.equals(this.parallel); + } + + public boolean isSerialGatewaySender() { + return !isParallelGatewaySender(); + } + + public void setPersistent(Boolean persistent) { + this.persistent = persistent; + } + + public boolean isPersistent() { + return Boolean.TRUE.equals(this.persistent); + } + + public boolean isNotPersistent() { + return !isPersistent(); + } + + public void setRemoteDistributedSystemId(int remoteDistributedSystemId) { + this.remoteDistributedSystemId = remoteDistributedSystemId; } public void setRegions(String[] regions) { - this.regions = Arrays.asList(regions); + setRegions(Arrays.asList(ArrayUtils.nullSafeArray(regions, String.class))); + } + + public void setRegions(List regions) { + this.regions.addAll(CollectionUtils.nullSafeList(regions)); + } + + public List getRegions() { + return Collections.unmodifiableList(this.regions); + } + + public int getRemoteDistributedSystemId() { + return this.remoteDistributedSystemId; + } + + public void setSocketBufferSize(Integer socketBufferSize) { + this.socketBufferSize = socketBufferSize; + } + + public Integer getSocketBufferSize() { + return this.socketBufferSize; + } + + public void setSocketReadTimeout(Integer socketReadTimeout) { + this.socketReadTimeout = socketReadTimeout; + } + + public Integer getSocketReadTimeout() { + return this.socketReadTimeout; + } + + public void setTransportFilters(List transportFilters) { + this.transportFilters = transportFilters; + } + + public List getTransportFilters() { + return this.transportFilters; } } diff --git a/src/main/java/org/springframework/data/gemfire/wan/OrderPolicyConverter.java b/src/main/java/org/springframework/data/gemfire/wan/OrderPolicyConverter.java index 3535506f..01a074d7 100644 --- a/src/main/java/org/springframework/data/gemfire/wan/OrderPolicyConverter.java +++ b/src/main/java/org/springframework/data/gemfire/wan/OrderPolicyConverter.java @@ -13,20 +13,23 @@ * See the License for the specific language governing permissions and * limitations under the License. */ - package org.springframework.data.gemfire.wan; +import java.beans.PropertyEditor; + import org.apache.geode.cache.wan.GatewaySender; + +import org.springframework.core.convert.converter.Converter; import org.springframework.data.gemfire.support.AbstractPropertyEditorConverterSupport; /** - * The OrderPolicyConverter class is a Spring Converter and JavaBeans PropertyEditor used to convert a String value - * into an appropriate GemFire Gateway.OrderPolicy enum. + * The {@link OrderPolicyConverter} class is a Spring {@link Converter} and JavaBeans {@link PropertyEditor} used to + * convert a {@link String} into an appropriate {@link GatewaySender.OrderPolicy} enum. * * @author John Blum + * @see org.apache.geode.cache.wan.GatewaySender.OrderPolicy * @see org.springframework.data.gemfire.support.AbstractPropertyEditorConverterSupport * @see org.springframework.data.gemfire.wan.OrderPolicyType - * @see org.apache.geode.cache.wan.GatewaySender.OrderPolicy * @since 1.7.0 */ @SuppressWarnings({ "deprecation", "unused" }) @@ -43,9 +46,9 @@ public class OrderPolicyConverter extends AbstractPropertyEditorConverterSupport * @see org.apache.geode.cache.util.Gateway.OrderPolicy */ @Override - public GatewaySender.OrderPolicy convert(final String source) { + public GatewaySender.OrderPolicy convert(String source) { + return assertConverted(source, OrderPolicyType.getOrderPolicy(OrderPolicyType.valueOfIgnoreCase(source)), GatewaySender.OrderPolicy.class); - } - + } } diff --git a/src/test/java/org/springframework/data/gemfire/config/annotation/GatewaySenderConfigurationTests.java b/src/test/java/org/springframework/data/gemfire/config/annotation/GatewaySenderConfigurationTests.java index 4ff98782..8b27b3f1 100644 --- a/src/test/java/org/springframework/data/gemfire/config/annotation/GatewaySenderConfigurationTests.java +++ b/src/test/java/org/springframework/data/gemfire/config/annotation/GatewaySenderConfigurationTests.java @@ -1,3 +1,18 @@ +/* + * Copyright 2010-2019 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ package org.springframework.data.gemfire.config.annotation; import static org.assertj.core.api.Assertions.assertThat; @@ -19,9 +34,10 @@ import org.apache.geode.cache.wan.GatewayEventSubstitutionFilter; import org.apache.geode.cache.wan.GatewayQueueEvent; import org.apache.geode.cache.wan.GatewaySender; import org.apache.geode.cache.wan.GatewayTransportFilter; + import org.junit.After; -import org.junit.Before; import org.junit.Test; + import org.springframework.context.ConfigurableApplicationContext; import org.springframework.context.annotation.AnnotationConfigApplicationContext; import org.springframework.context.annotation.Bean; @@ -49,10 +65,6 @@ public class GatewaySenderConfigurationTests { private ConfigurableApplicationContext applicationContext; - @Before - public void setup() { - } - @After public void shutdown() { Optional.ofNullable(this.applicationContext).ifPresent(ConfigurableApplicationContext::close); @@ -60,20 +72,24 @@ public class GatewaySenderConfigurationTests { @Test public void annotationConfigurationOfMultipleGatewaySendersWithDefaultsFromParent() { + this.applicationContext = newApplicationContext(BaseGatewaySenderTestConfiguration.class, TestConfigurationOfMultipleGatewaySenderAnnotationsButWithDefaultsFromParent.class); - TestGatewaySenderConfigurer gatewaySenderConfigurer = this.applicationContext - .getBean(TestGatewaySenderConfigurer.class); + TestGatewaySenderConfigurer gatewaySenderConfigurer = + this.applicationContext.getBean(TestGatewaySenderConfigurer.class); Map beansOfType = this.applicationContext.getBeansOfType(GatewaySender.class); - assertThat(beansOfType.size()).isEqualTo(2); String[] senders = new String[] { "TestGatewaySender", "TestGatewaySender2" }; - assertThat(beansOfType.keySet().toArray()).containsExactly(senders); + + assertThat(beansOfType).hasSize(2); + assertThat(beansOfType.keySet()).containsExactlyInAnyOrder(senders); for (String sender : senders) { + GatewaySender gatewaySender = this.applicationContext.getBean(sender, GatewaySender.class); + assertThat(gatewaySender.isManualStart()).isEqualTo(true); assertThat(gatewaySender.getRemoteDSId()).isEqualTo(2); assertThat(gatewaySender.getId()).isEqualTo(sender); @@ -99,8 +115,8 @@ public class GatewaySenderConfigurationTests { assertThat(gatewaySenderConfigurer.beanNames.get(gatewaySender.getId()).toArray()) .isEqualTo(new String[] { "transportBean2", "transportBean1" }); - Region region1 = (Region) this.applicationContext.getBean("Region1"); - Region region2 = (Region) this.applicationContext.getBean("Region2"); + Region region1 = this.applicationContext.getBean("Region1", Region.class); + Region region2 = this.applicationContext.getBean("Region2", Region.class); assertThat(region1.getAttributes().getGatewaySenderIds()) .containsExactlyInAnyOrder("TestGatewaySender", "TestGatewaySender2"); @@ -111,22 +127,26 @@ public class GatewaySenderConfigurationTests { @Test public void annotationConfiguredMultipleGatewaySenders() { + this.applicationContext = newApplicationContext(BaseGatewaySenderTestConfiguration.class, TestConfigurationWithMultipleGatewaySenderAnnotations.class); + Map beansOfType = this.applicationContext.getBeansOfType(GatewaySender.class); assertThat(beansOfType.keySet().toArray()).containsExactlyInAnyOrder("TestGatewaySender", "TestGatewaySender2"); - } @Test public void annotationConfiguredGatewaySender() { + this.applicationContext = newApplicationContext(BaseGatewaySenderTestConfiguration.class, TestConfigurationWithAnnotations.class); - TestGatewaySenderConfigurer gatewaySenderConfigurer = this.applicationContext - .getBean(TestGatewaySenderConfigurer.class); + + TestGatewaySenderConfigurer gatewaySenderConfigurer = + this.applicationContext.getBean(TestGatewaySenderConfigurer.class); GatewaySender gatewaySender = this.applicationContext.getBean("TestGatewaySender", GatewaySender.class); + assertThat(gatewaySender.isManualStart()).isEqualTo(true); assertThat(gatewaySender.getRemoteDSId()).isEqualTo(2); assertThat(gatewaySender.getId()).isEqualTo("TestGatewaySender"); @@ -151,8 +171,8 @@ public class GatewaySenderConfigurationTests { assertThat(gatewaySenderConfigurer.beanNames.get(gatewaySender.getId()).toArray()) .isEqualTo(new String[] { "transportBean2", "transportBean1" }); - Region region1 = (Region) this.applicationContext.getBean("Region1"); - Region region2 = (Region) this.applicationContext.getBean("Region2"); + Region region1 = this.applicationContext.getBean("Region1", Region.class); + Region region2 = this.applicationContext.getBean("Region2", Region.class); assertThat(region1.getAttributes().getGatewaySenderIds()).containsExactlyInAnyOrder("TestGatewaySender"); assertThat(region2.getAttributes().getGatewaySenderIds()).containsExactlyInAnyOrder("TestGatewaySender"); @@ -160,20 +180,24 @@ public class GatewaySenderConfigurationTests { @Test public void annotationConfigurationOfMultipleGatewaySendersWithOverrides() { + this.applicationContext = newApplicationContext(BaseGatewaySenderTestConfiguration.class, TestConfigurationOfMultipleGatewaySenderAnnotationsWithOverrides.class); - TestGatewaySenderConfigurer gatewaySenderConfigurer = this.applicationContext - .getBean("gatewayConfigurer", TestGatewaySenderConfigurer.class); + TestGatewaySenderConfigurer gatewaySenderConfigurer = + this.applicationContext.getBean("gatewayConfigurer", TestGatewaySenderConfigurer.class); Map beansOfType = this.applicationContext.getBeansOfType(GatewaySender.class); - assertThat(beansOfType.size()).isEqualTo(2); String[] senders = new String[] { "TestGatewaySender", "TestGatewaySender2" }; - assertThat(beansOfType.keySet().toArray()).containsExactly(senders); + + assertThat(beansOfType).hasSize(2); + assertThat(beansOfType.keySet()).containsExactlyInAnyOrder(senders); for (String sender : senders) { + GatewaySender gatewaySender = this.applicationContext.getBean(sender, GatewaySender.class); + assertThat(gatewaySender.isManualStart()).isEqualTo(true); assertThat(gatewaySender.getRemoteDSId()).isEqualTo(2); assertThat(gatewaySender.getId()).isEqualTo(sender); @@ -191,18 +215,21 @@ public class GatewaySenderConfigurationTests { assertThat(gatewaySender.getSocketReadTimeout()).isEqualTo(4000); assertThat(gatewaySender.getSocketBufferSize()).isEqualTo(16384); } + GatewaySender gatewaySender = this.applicationContext.getBean("TestGatewaySender", GatewaySender.class); + assertThat(gatewaySender.getGatewayTransportFilters().size()).isEqualTo(1); assertThat(((GatewaySenderConfigurationTests.TestGatewayTransportFilter) gatewaySender .getGatewayTransportFilters().get(0)).name).isEqualTo("transportBean1"); gatewaySender = this.applicationContext.getBean("TestGatewaySender2", GatewaySender.class); + assertThat(gatewaySender.getGatewayTransportFilters().size()).isEqualTo(2); assertThat(gatewaySenderConfigurer.beanNames.get(gatewaySender.getId()).toArray()) .isEqualTo(new String[] { "transportBean2", "transportBean1" }); - Region region1 = (Region) this.applicationContext.getBean("Region1"); - Region region2 = (Region) this.applicationContext.getBean("Region2"); + Region region1 = this.applicationContext.getBean("Region1", Region.class); + Region region2 = this.applicationContext.getBean("Region2", Region.class); assertThat(region1.getAttributes().getGatewaySenderIds()).containsExactlyInAnyOrder("TestGatewaySender2"); assertThat(region2.getAttributes().getGatewaySenderIds()) @@ -211,8 +238,8 @@ public class GatewaySenderConfigurationTests { private ConfigurableApplicationContext newApplicationContext(Class... annotatedClasses) { - AnnotationConfigApplicationContext applicationContext = new AnnotationConfigApplicationContext( - annotatedClasses); + AnnotationConfigApplicationContext applicationContext = + new AnnotationConfigApplicationContext(annotatedClasses); applicationContext.registerShutdownHook(); @@ -266,10 +293,7 @@ public class GatewaySenderConfigurationTests { eventFilters = "SomeEventFilter", batchTimeInterval = 2000, dispatcherThreads = 22, maximumQueueMemory = 400, socketBufferSize = 16384, socketReadTimeout = 4000, regions = { "Region1", "Region2" }, transportFilters = { "transportBean2", "transportBean1" }) - static class TestConfigurationOfMultipleGatewaySenderAnnotationsButWithDefaultsFromParent { - - - } + static class TestConfigurationOfMultipleGatewaySenderAnnotationsButWithDefaultsFromParent { } @EnableGatewaySenders(gatewaySenders = { @EnableGatewaySender(name = "TestGatewaySender", transportFilters = "transportBean1", regions = "Region2"), @@ -281,9 +305,7 @@ public class GatewaySenderConfigurationTests { eventFilters = "SomeEventFilter", batchTimeInterval = 2000, dispatcherThreads = 22, maximumQueueMemory = 400, socketBufferSize = 16384, socketReadTimeout = 4000, regions = { "Region1", "Region2" }, transportFilters = { "transportBean2", "transportBean1" }) - static class TestConfigurationOfMultipleGatewaySenderAnnotationsWithOverrides { - - } + static class TestConfigurationOfMultipleGatewaySenderAnnotationsWithOverrides { } private static class TestGatewaySenderConfigurer implements GatewaySenderConfigurer { @@ -297,6 +319,29 @@ public class GatewaySenderConfigurationTests { } } + private static class TestGatewayEventFilter implements GatewayEventFilter { + + private String name; + + public TestGatewayEventFilter(String name) { + this.name = name; + } + + @Override + public boolean beforeEnqueue(GatewayQueueEvent gatewayQueueEvent) { + return false; + } + + @Override + public boolean beforeTransmit(GatewayQueueEvent gatewayQueueEvent) { + return false; + } + + @Override + public void afterAcknowledgement(GatewayQueueEvent gatewayQueueEvent) { } + + } + private static class TestGatewayEventSubstitutionFilter implements GatewayEventSubstitutionFilter { private String name; @@ -305,13 +350,14 @@ public class GatewaySenderConfigurationTests { this.name = name; } - @Override public Object getSubstituteValue(EntryEvent entryEvent) { + @Override + public Object getSubstituteValue(EntryEvent entryEvent) { return null; } - @Override public void close() { + @Override + public void close() { } - } } private static class TestGatewayTransportFilter implements GatewayTransportFilter { @@ -332,36 +378,17 @@ public class GatewaySenderConfigurationTests { return null; } - @Override public int hashCode() { + @Override + public int hashCode() { return name.hashCode(); } - @Override public boolean equals(Object obj) { + @Override + public boolean equals(Object obj) { return this.name.equals(((TestGatewayTransportFilter) obj).name); } } - private static class TestGatewayEventFilter implements GatewayEventFilter { - - private String name; - - public TestGatewayEventFilter(String name) { - this.name = name; - } - - @Override public boolean beforeEnqueue(GatewayQueueEvent gatewayQueueEvent) { - return false; - } - - @Override public boolean beforeTransmit(GatewayQueueEvent gatewayQueueEvent) { - return false; - } - - @Override public void afterAcknowledgement(GatewayQueueEvent gatewayQueueEvent) { - - } - } - @PeerCacheApplication @EnableGemFireMockObjects static class BaseGatewaySenderTestConfiguration { diff --git a/src/test/java/org/springframework/data/gemfire/config/annotation/GatewaySenderConfigurerTests.java b/src/test/java/org/springframework/data/gemfire/config/annotation/GatewaySenderConfigurerTests.java index f4479f38..c647ac61 100644 --- a/src/test/java/org/springframework/data/gemfire/config/annotation/GatewaySenderConfigurerTests.java +++ b/src/test/java/org/springframework/data/gemfire/config/annotation/GatewaySenderConfigurerTests.java @@ -1,3 +1,18 @@ +/* + * Copyright 2010-2019 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ package org.springframework.data.gemfire.config.annotation; import static org.assertj.core.api.Assertions.assertThat; @@ -16,9 +31,10 @@ import org.apache.geode.cache.wan.GatewayEventSubstitutionFilter; import org.apache.geode.cache.wan.GatewayQueueEvent; import org.apache.geode.cache.wan.GatewaySender; import org.apache.geode.cache.wan.GatewayTransportFilter; + import org.junit.After; -import org.junit.Before; import org.junit.Test; + import org.springframework.context.ConfigurableApplicationContext; import org.springframework.context.annotation.AnnotationConfigApplicationContext; import org.springframework.context.annotation.Bean; @@ -48,17 +64,13 @@ public class GatewaySenderConfigurerTests { private ConfigurableApplicationContext applicationContext; - @Before - public void setup() { - } - @After public void shutdown() { Optional.ofNullable(this.applicationContext).ifPresent(ConfigurableApplicationContext::close); } private ConfigurableApplicationContext newApplicationContext(PropertySource testPropertySource, - Class... annotatedClasses) { + Class... annotatedClasses) { AnnotationConfigApplicationContext applicationContext = new AnnotationConfigApplicationContext(); @@ -75,16 +87,16 @@ public class GatewaySenderConfigurerTests { @Test public void annotationConfigurationOfMultipleGatewaySendersWithConfigurersAndProperties() { + MockPropertySource testPropertySource = new MockPropertySource(); + testPropertySource.setProperty("spring.data.gemfire.gateway.sender.alert-threshold", 1234); testPropertySource.setProperty("spring.data.gemfire.gateway.sender.TestGatewaySender.batch-size", 1002); testPropertySource.setProperty("spring.data.gemfire.gateway.sender.TestGatewaySender2.batch-size", 1002); testPropertySource.setProperty("spring.data.gemfire.gateway.sender.batch-time-interval", 2000); testPropertySource.setProperty("spring.data.gemfire.gateway.sender.maximum-queue-memory", 400); - testPropertySource - .setProperty("spring.data.gemfire.gateway.sender.TestGatewaySender.socket-read-timeout", 4000); - testPropertySource - .setProperty("spring.data.gemfire.gateway.sender.TestGatewaySender2.socket-read-timeout", 4000); + testPropertySource.setProperty("spring.data.gemfire.gateway.sender.TestGatewaySender.socket-read-timeout", 4000); + testPropertySource.setProperty("spring.data.gemfire.gateway.sender.TestGatewaySender2.socket-read-timeout", 4000); testPropertySource.setProperty("spring.data.gemfire.gateway.sender.socket-buffer-size", 16384); this.applicationContext = newApplicationContext(testPropertySource, @@ -93,12 +105,15 @@ public class GatewaySenderConfigurerTests { Map beansOfType = this.applicationContext.getBeansOfType(GatewaySender.class); - assertThat(beansOfType.size()).isEqualTo(2); String[] senders = new String[] { "TestGatewaySender", "TestGatewaySender2" }; - assertThat(beansOfType.keySet().toArray()).containsExactly(senders); + + assertThat(beansOfType).hasSize(2); + assertThat(beansOfType.keySet()).containsExactlyInAnyOrder(senders); for (String sender : senders) { + GatewaySender gatewaySender = this.applicationContext.getBean(sender, GatewaySender.class); + assertThat(gatewaySender.isManualStart()).isEqualTo(false); assertThat(gatewaySender.getRemoteDSId()).isEqualTo(2); assertThat(gatewaySender.getId()).isEqualTo(sender); @@ -117,8 +132,8 @@ public class GatewaySenderConfigurerTests { assertThat(gatewaySender.getGatewayTransportFilters().size()).isEqualTo(0); - Region region1 = (Region) this.applicationContext.getBean("Region1"); - Region region2 = (Region) this.applicationContext.getBean("Region2"); + Region region1 = this.applicationContext.getBean("Region1", Region.class); + Region region2 = this.applicationContext.getBean("Region2", Region.class); assertThat(region1.getAttributes().getGatewaySenderIds()) .containsExactlyInAnyOrder("TestGatewaySender", "TestGatewaySender2"); @@ -165,6 +180,29 @@ public class GatewaySenderConfigurerTests { } } + private static class TestGatewayEventFilter implements GatewayEventFilter { + + private String name; + + public TestGatewayEventFilter(String name) { + this.name = name; + } + + @Override + public boolean beforeEnqueue(GatewayQueueEvent gatewayQueueEvent) { + return false; + } + + @Override + public boolean beforeTransmit(GatewayQueueEvent gatewayQueueEvent) { + return false; + } + + @Override + public void afterAcknowledgement(GatewayQueueEvent gatewayQueueEvent) { } + + } + private static class TestGatewayEventSubstitutionFilter implements GatewayEventSubstitutionFilter { private String name; @@ -173,13 +211,14 @@ public class GatewaySenderConfigurerTests { this.name = name; } - @Override public Object getSubstituteValue(EntryEvent entryEvent) { + @Override + public Object getSubstituteValue(EntryEvent entryEvent) { return null; } - @Override public void close() { + @Override + public void close() { } - } } private static class TestGatewayTransportFilter implements GatewayTransportFilter { @@ -209,27 +248,6 @@ public class GatewaySenderConfigurerTests { } } - private static class TestGatewayEventFilter implements GatewayEventFilter { - - private String name; - - public TestGatewayEventFilter(String name) { - this.name = name; - } - - @Override public boolean beforeEnqueue(GatewayQueueEvent gatewayQueueEvent) { - return false; - } - - @Override public boolean beforeTransmit(GatewayQueueEvent gatewayQueueEvent) { - return false; - } - - @Override public void afterAcknowledgement(GatewayQueueEvent gatewayQueueEvent) { - - } - } - @Configuration @EnableGatewaySenders(gatewaySenders = { @EnableGatewaySender(name = "TestGatewaySender", regions = "Region1"), @@ -239,12 +257,13 @@ public class GatewaySenderConfigurerTests { @Bean GatewaySenderConfigurer gatewaySenderConfigurer() { - return ((beanName, gatewaySenderFactoryBean) -> { + + return (beanName, gatewaySenderFactoryBean) -> { gatewaySenderFactoryBean.setRemoteDistributedSystemId(2); gatewaySenderFactoryBean.setDispatcherThreads(22); gatewaySenderFactoryBean.setParallel(true); gatewaySenderFactoryBean.setOrderPolicy(GatewaySender.OrderPolicy.PARTITION); - }); + }; } } } diff --git a/src/test/java/org/springframework/data/gemfire/config/annotation/GatewaySenderPropertiesTests.java b/src/test/java/org/springframework/data/gemfire/config/annotation/GatewaySenderPropertiesTests.java index e8771649..c11b9151 100644 --- a/src/test/java/org/springframework/data/gemfire/config/annotation/GatewaySenderPropertiesTests.java +++ b/src/test/java/org/springframework/data/gemfire/config/annotation/GatewaySenderPropertiesTests.java @@ -1,3 +1,18 @@ +/* + * Copyright 2010-2019 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ package org.springframework.data.gemfire.config.annotation; import static org.assertj.core.api.Assertions.assertThat; @@ -22,9 +37,10 @@ import org.apache.geode.cache.wan.GatewayTransportFilter; import org.apache.geode.distributed.internal.DistributionAdvisor; import org.apache.geode.internal.cache.EntryEventImpl; import org.apache.geode.internal.cache.wan.AbstractGatewaySender; + import org.junit.After; -import org.junit.Before; import org.junit.Test; + import org.springframework.context.ConfigurableApplicationContext; import org.springframework.context.annotation.AnnotationConfigApplicationContext; import org.springframework.context.annotation.Bean; @@ -56,11 +72,6 @@ public class GatewaySenderPropertiesTests { private ConfigurableApplicationContext applicationContext; - @Before - public void setup() { - - } - @After public void shutdown() { Optional.ofNullable(this.applicationContext).ifPresent(ConfigurableApplicationContext::close); @@ -68,6 +79,7 @@ public class GatewaySenderPropertiesTests { @Test public void gatewayReceiverPropertiesConfigurationOnMultipleChildren() { + MockPropertySource testPropertySource = new MockPropertySource() .withProperty("spring.data.gemfire.gateway.sender.TestGatewaySender.manual-start", true) .withProperty("spring.data.gemfire.gateway.sender.TestGatewaySender.remote-distributed-system-id", 2) @@ -115,10 +127,11 @@ public class GatewaySenderPropertiesTests { this.applicationContext = newApplicationContext(testPropertySource, BaseGatewaySenderTestConfiguration.class, TestConfigurationWithPropertiesMultipleGatewaySenders.class); - TestGatewaySenderConfigurer gatewaySenderConfigurer = this.applicationContext - .getBean(TestGatewaySenderConfigurer.class); + TestGatewaySenderConfigurer gatewaySenderConfigurer = + this.applicationContext.getBean(TestGatewaySenderConfigurer.class); GatewaySender gatewaySender = this.applicationContext.getBean("TestGatewaySender", GatewaySender.class); + assertThat(gatewaySender.isManualStart()).isEqualTo(true); assertThat(gatewaySender.getRemoteDSId()).isEqualTo(2); assertThat(gatewaySender.getId()).isEqualTo("TestGatewaySender"); @@ -142,6 +155,7 @@ public class GatewaySenderPropertiesTests { .isEqualTo(new String[] { "transportBean2", "transportBean1" }); gatewaySender = this.applicationContext.getBean("TestGatewaySender2", GatewaySender.class); + assertThat(gatewaySender.isManualStart()).isEqualTo(false); assertThat(gatewaySender.getRemoteDSId()).isEqualTo(3); assertThat(gatewaySender.getId()).isEqualTo("TestGatewaySender2"); @@ -164,8 +178,8 @@ public class GatewaySenderPropertiesTests { assertThat(gatewaySenderConfigurer.beanNames.get(gatewaySender.getId()).toArray()) .isEqualTo(new String[] { "transportBean1" }); - Region region1 = (Region) this.applicationContext.getBean("Region1"); - Region region2 = (Region) this.applicationContext.getBean("Region2"); + Region region1 = this.applicationContext.getBean("Region1", Region.class); + Region region2 = this.applicationContext.getBean("Region2", Region.class); assertThat(region1.getAttributes().getGatewaySenderIds()) .containsExactlyInAnyOrder("TestGatewaySender", "TestGatewaySender2"); @@ -176,6 +190,7 @@ public class GatewaySenderPropertiesTests { @Test public void gatewayReceiverPropertiesConfigurationOnMultipleChildrenAndAnnotations() { + MockPropertySource testPropertySource = new MockPropertySource() .withProperty("spring.data.gemfire.gateway.sender.socket-read-timeout", 4000) .withProperty("spring.data.gemfire.gateway.sender.TestGatewaySender.manual-start", true) @@ -223,10 +238,11 @@ public class GatewaySenderPropertiesTests { this.applicationContext = newApplicationContext(testPropertySource, BaseGatewaySenderTestConfiguration.class, TestConfigurationWithMultipleGatewaySenderAnnotations.class); - TestGatewaySenderConfigurer gatewaySenderConfigurer = this.applicationContext - .getBean(TestGatewaySenderConfigurer.class); + TestGatewaySenderConfigurer gatewaySenderConfigurer = + this.applicationContext.getBean(TestGatewaySenderConfigurer.class); GatewaySender gatewaySender = this.applicationContext.getBean("TestGatewaySender", GatewaySender.class); + assertThat(gatewaySender.isManualStart()).isEqualTo(true); assertThat(gatewaySender.getRemoteDSId()).isEqualTo(2); assertThat(gatewaySender.getId()).isEqualTo("TestGatewaySender"); @@ -250,6 +266,7 @@ public class GatewaySenderPropertiesTests { .isEqualTo(new String[] { "transportBean2", "transportBean1" }); gatewaySender = this.applicationContext.getBean("TestGatewaySender2", GatewaySender.class); + assertThat(gatewaySender.isManualStart()).isEqualTo(false); assertThat(gatewaySender.getRemoteDSId()).isEqualTo(3); assertThat(gatewaySender.getId()).isEqualTo("TestGatewaySender2"); @@ -272,8 +289,8 @@ public class GatewaySenderPropertiesTests { assertThat(gatewaySenderConfigurer.beanNames.get(gatewaySender.getId()).toArray()) .isEqualTo(new String[] { "transportBean1" }); - Region region1 = (Region) this.applicationContext.getBean("Region1"); - Region region2 = (Region) this.applicationContext.getBean("Region2"); + Region region1 = this.applicationContext.getBean("Region1", Region.class); + Region region2 = this.applicationContext.getBean("Region2", Region.class); assertThat(region1.getAttributes().getGatewaySenderIds()) .containsExactlyInAnyOrder("TestGatewaySender", "TestGatewaySender2"); @@ -284,6 +301,7 @@ public class GatewaySenderPropertiesTests { @Test public void gatewayReceiverPropertiesConfigurationOnChild() { + MockPropertySource testPropertySource = new MockPropertySource() .withProperty("spring.data.gemfire.gateway.sender.TestGatewaySender.manual-start", true) .withProperty("spring.data.gemfire.gateway.sender.TestGatewaySender.remote-distributed-system-id", 2) @@ -310,10 +328,11 @@ public class GatewaySenderPropertiesTests { this.applicationContext = newApplicationContext(testPropertySource, BaseGatewaySenderTestConfiguration.class, TestConfigurationWithProperties.class); - TestGatewaySenderConfigurer gatewaySenderConfigurer = this.applicationContext - .getBean(TestGatewaySenderConfigurer.class); + TestGatewaySenderConfigurer gatewaySenderConfigurer = + this.applicationContext.getBean(TestGatewaySenderConfigurer.class); GatewaySender gatewaySender = this.applicationContext.getBean("TestGatewaySender", GatewaySender.class); + assertThat(gatewaySender.isManualStart()).isEqualTo(true); assertThat(gatewaySender.getRemoteDSId()).isEqualTo(2); assertThat(gatewaySender.getId()).isEqualTo("TestGatewaySender"); @@ -336,8 +355,8 @@ public class GatewaySenderPropertiesTests { assertThat(gatewaySenderConfigurer.beanNames.get(gatewaySender.getId()).toArray()) .isEqualTo(new String[] { "transportBean2", "transportBean1" }); - Region region1 = (Region) this.applicationContext.getBean("Region1"); - Region region2 = (Region) this.applicationContext.getBean("Region2"); + Region region1 = this.applicationContext.getBean("Region1", Region.class); + Region region2 = this.applicationContext.getBean("Region2", Region.class); assertThat(region1.getAttributes().getGatewaySenderIds()) .containsExactlyInAnyOrder("TestGatewaySender"); @@ -348,6 +367,7 @@ public class GatewaySenderPropertiesTests { @Test public void gatewayReceiverPropertiesConfigurationOnParent() { + MockPropertySource testPropertySource = new MockPropertySource() .withProperty("spring.data.gemfire.gateway.sender.manual-start", true) .withProperty("spring.data.gemfire.gateway.sender.remote-distributed-system-id", 2) @@ -374,10 +394,11 @@ public class GatewaySenderPropertiesTests { this.applicationContext = newApplicationContext(testPropertySource, BaseGatewaySenderTestConfiguration.class, TestConfigurationWithProperties.class); - TestGatewaySenderConfigurer gatewaySenderConfigurer = this.applicationContext - .getBean(TestGatewaySenderConfigurer.class); + TestGatewaySenderConfigurer gatewaySenderConfigurer = + this.applicationContext.getBean(TestGatewaySenderConfigurer.class); GatewaySender gatewaySender = this.applicationContext.getBean("TestGatewaySender", GatewaySender.class); + assertThat(gatewaySender.isManualStart()).isEqualTo(true); assertThat(gatewaySender.getRemoteDSId()).isEqualTo(2); assertThat(gatewaySender.getId()).isEqualTo("TestGatewaySender"); @@ -400,8 +421,8 @@ public class GatewaySenderPropertiesTests { assertThat(gatewaySenderConfigurer.beanNames.get(gatewaySender.getId()).toArray()) .isEqualTo(new String[] { "transportBean2", "transportBean1" }); - Region region1 = (Region) this.applicationContext.getBean("Region1"); - Region region2 = (Region) this.applicationContext.getBean("Region2"); + Region region1 = this.applicationContext.getBean("Region1", Region.class); + Region region2 = this.applicationContext.getBean("Region2", Region.class); assertThat(region1.getAttributes().getGatewaySenderIds()) .containsExactlyInAnyOrder("TestGatewaySender"); @@ -412,6 +433,7 @@ public class GatewaySenderPropertiesTests { @Test public void gatewayReceiverPropertiesConfigurationOnParentWithChildOverride() { + MockPropertySource testPropertySource = new MockPropertySource() .withProperty("spring.data.gemfire.gateway.sender.manual-start", true) .withProperty("spring.data.gemfire.gateway.sender.TestGatewaySender.manual-start", false) @@ -439,10 +461,11 @@ public class GatewaySenderPropertiesTests { this.applicationContext = newApplicationContext(testPropertySource, BaseGatewaySenderTestConfiguration.class, TestConfigurationWithProperties.class); - TestGatewaySenderConfigurer gatewaySenderConfigurer = this.applicationContext - .getBean(TestGatewaySenderConfigurer.class); + TestGatewaySenderConfigurer gatewaySenderConfigurer = + this.applicationContext.getBean(TestGatewaySenderConfigurer.class); GatewaySender gatewaySender = this.applicationContext.getBean("TestGatewaySender", GatewaySender.class); + assertThat(gatewaySender.isManualStart()).isEqualTo(false); assertThat(gatewaySender.getRemoteDSId()).isEqualTo(2); assertThat(gatewaySender.getId()).isEqualTo("TestGatewaySender"); @@ -465,8 +488,8 @@ public class GatewaySenderPropertiesTests { assertThat(gatewaySenderConfigurer.beanNames.get(gatewaySender.getId()).toArray()) .isEqualTo(new String[] { "transportBean2", "transportBean1" }); - Region region1 = (Region) this.applicationContext.getBean("Region1"); - Region region2 = (Region) this.applicationContext.getBean("Region2"); + Region region1 = this.applicationContext.getBean("Region1", Region.class); + Region region2 = this.applicationContext.getBean("Region2", Region.class); assertThat(region1.getAttributes().getGatewaySenderIds()) .containsExactlyInAnyOrder("TestGatewaySender"); @@ -476,7 +499,7 @@ public class GatewaySenderPropertiesTests { } private ConfigurableApplicationContext newApplicationContext(PropertySource testPropertySource, - Class... annotatedClasses) { + Class... annotatedClasses) { AnnotationConfigApplicationContext applicationContext = new AnnotationConfigApplicationContext(); @@ -503,9 +526,7 @@ public class GatewaySenderPropertiesTests { batchTimeInterval = 2000, dispatcherThreads = 22, maximumQueueMemory = 400, socketBufferSize = 16384, socketReadTimeout = 4000, regions = { "Region1", "Region2" }) }) - static class TestConfigurationWithMultipleGatewaySenderAnnotations { - - } + static class TestConfigurationWithMultipleGatewaySenderAnnotations { } @EnableGatewaySender(name = "TestGatewaySender") static class TestConfigurationWithProperties { @@ -520,10 +541,7 @@ public class GatewaySenderPropertiesTests { @EnableGatewaySender(name = "TestGatewaySender"), @EnableGatewaySender(name = "TestGatewaySender2") }) - static class TestConfigurationWithPropertiesMultipleGatewaySenders { - - - } + static class TestConfigurationWithPropertiesMultipleGatewaySenders { } private static class TestGatewaySenderConfigurer implements GatewaySenderConfigurer { @@ -545,13 +563,14 @@ public class GatewaySenderPropertiesTests { this.name = name; } - @Override public Object getSubstituteValue(EntryEvent entryEvent) { + @Override + public Object getSubstituteValue(EntryEvent entryEvent) { return null; } - @Override public void close() { + @Override + public void close() { } - } } private static class TestGatewayEventFilter implements GatewayEventFilter { @@ -562,17 +581,19 @@ public class GatewaySenderPropertiesTests { this.name = name; } - @Override public boolean beforeEnqueue(GatewayQueueEvent gatewayQueueEvent) { + @Override + public boolean beforeEnqueue(GatewayQueueEvent gatewayQueueEvent) { return false; } - @Override public boolean beforeTransmit(GatewayQueueEvent gatewayQueueEvent) { + @Override + public boolean beforeTransmit(GatewayQueueEvent gatewayQueueEvent) { return false; } - @Override public void afterAcknowledgement(GatewayQueueEvent gatewayQueueEvent) { + @Override + public void afterAcknowledgement(GatewayQueueEvent gatewayQueueEvent) { } - } } private static class TestGatewayTransportFilter implements GatewayTransportFilter { @@ -593,32 +614,31 @@ public class GatewaySenderPropertiesTests { return null; } - @Override public int hashCode() { - return name.hashCode(); + @Override + public int hashCode() { + return this.name.hashCode(); } - @Override public boolean equals(Object obj) { + @Override + public boolean equals(Object obj) { return this.name.equals(((TestGatewayTransportFilter) obj).name); } } private static class TestGatewaySender extends AbstractGatewaySender implements GatewaySender { - @Override public void start() { + @Override + public void start() { } - } + @Override + public void stop() { } - @Override public void stop() { + @Override + public void setModifiedEventId(EntryEventImpl entryEvent) { } - } + @Override + public void fillInProfile(DistributionAdvisor.Profile profile) { } - @Override public void setModifiedEventId(EntryEventImpl entryEvent) { - - } - - @Override public void fillInProfile(DistributionAdvisor.Profile profile) { - - } } @PeerCacheApplication diff --git a/src/test/java/org/springframework/data/gemfire/wan/GatewaySenderFactoryBeanTest.java b/src/test/java/org/springframework/data/gemfire/wan/GatewaySenderFactoryBeanTest.java index 0636230e..3b6a2e75 100644 --- a/src/test/java/org/springframework/data/gemfire/wan/GatewaySenderFactoryBeanTest.java +++ b/src/test/java/org/springframework/data/gemfire/wan/GatewaySenderFactoryBeanTest.java @@ -23,12 +23,12 @@ import static org.mockito.Mockito.never; import static org.mockito.Mockito.verify; import static org.mockito.Mockito.when; -import org.junit.Test; - import org.apache.geode.cache.Cache; import org.apache.geode.cache.wan.GatewaySender; import org.apache.geode.cache.wan.GatewaySenderFactory; +import org.junit.Test; + import org.springframework.data.gemfire.TestUtils; /** @@ -46,14 +46,17 @@ import org.springframework.data.gemfire.TestUtils; */ public class GatewaySenderFactoryBeanTest { - private Cache mockCacheWithGatewayInfrastructure(final GatewaySenderFactory gatewaySenderFactory) { + private Cache mockCacheWithGatewayInfrastructure(GatewaySenderFactory gatewaySenderFactory) { + Cache mockCache = mock(Cache.class); + when(mockCache.createGatewaySenderFactory()).thenReturn(gatewaySenderFactory); + return mockCache; } - private GatewaySenderFactory mockGatewaySenderFactory(final String gatewaySenderName, - final int remoteDistributedSystemId) { + private GatewaySenderFactory mockGatewaySenderFactory(String gatewaySenderName, int remoteDistributedSystemId) { + GatewaySenderFactory mockGatewaySenderFactory = mock(GatewaySenderFactory.class); GatewaySender mockGatewaySender = mock(GatewaySender.class);