DATAGEODE-169 - Polish.

Resolves gh-22.
This commit is contained in:
John Blum
2019-08-05 00:18:50 -07:00
parent ae13997f8b
commit 3ebefb4f10
17 changed files with 1424 additions and 1074 deletions

View File

@@ -34,10 +34,12 @@
<id>spring-libs-snapshot</id>
<url>https://repo.spring.io/libs-snapshot</url>
</repository>
<!--
<repository>
<id>apache-snapshots</id>
<url>https://repository.apache.org/content/repositories/snapshots</url>
</repository>
-->
</repositories>
<pluginRepositories>
@@ -243,6 +245,7 @@
</exclusion>
</exclusions>
</dependency>
</dependencies>
<build>

View File

@@ -627,20 +627,21 @@ See {sdg-javadoc}/org/springframework/data/gemfire/listener/annotation/Continuou
See <<apis:continuous-query>> and <<bootstrap-annotation-config-continuous-queries>> 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].
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].

View File

@@ -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.
* <p> This property can also be configured using the {@literal spring.data.gemfire.gateway.sender.<name>.alert-threshold}
* <p>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.<name>.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.
* <p> This property can also be configured using the {@literal spring.data.gemfire.gateway.sender.<name>.batch-conflation-enabled}
* <p>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.<name>.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.
* <p> This property can also be configured using the {@literal spring.data.gemfire.gateway.sender.<name>.batch-size}
* <p>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.<name>.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}.
* <p>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.
* <p> This property can also be configured using the {@literal spring.data.gemfire.gateway.sender.<name>.batch-time-interval}
* <p>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.<name>.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}.
* <p> This property can also be configured using the {@literal spring.data.gemfire.gateway.sender.<name>.diskstore-reference}
* <p>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.<name>.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.
* <p> This property can also be configured using the {@literal spring.data.gemfire.gateway.sender.<name>.disk-synchronous}
* <p>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.<name>.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.
* <p>This property can also be configured using the {@literal spring.data.gemfire.gateway.sender.<name>.dispatcher-threads}
* <p>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.<name>.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}.
* <p>This property can also be configured using the {@literal spring.data.gemfire.gateway.sender.<name>.event-filters} property.
* <p>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.<name>.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.
* <p> This property can also be configured using the {@literal spring.data.gemfire.gateway.sender.<name>.event-substitution-filter}
* <p>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.<name>.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
* <p>This property can also be configured using the {@literal spring.data.gemfire.gateway.sender.<name>.manual-start}
* <p>Default is {@value @EnableGatewaySenderConfiguration.DEFAULT_MANUAL_START}
* A {@literal boolean} flag indicating whether the configured {@link GatewaySender} should be started automatically.
*
* <p>Defaults to {@value @EnableGatewaySenderConfiguration.DEFAULT_MANUAL_START}.
*
* Alternatively use the {@literal spring.data.gemfire.gateway.sender.<name>.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.
* <p>This property can also be configured using the {@literal spring.data.gemfire.gateway.sender.<name>.maximum-queue-memory}
* <p>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.<name>.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.<name>.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.<name>.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}.
*
* <p>There are three different ordering policies:
*
* <ul>
* <li>{@link OrderPolicyType#KEY} - Order of events preserved on a per key basis</li>
* <li>{@link OrderPolicyType#THREAD} - Order of events preserved by the thread that added the event</li>
* <li>{@link OrderPolicyType#PARTITION} - Order of events is preserved in order that they arrived in partitioned Region</li>
* </ul>
* <p>This property can also be configured using the {@literal spring.data.gemfire.gateway.sender.<name>.order-policy}</p>
* <p>Default value is an empty list
*
* Defaults to {@link OrderPolicyType#KEY}.
*
* Alternatively use the {@literal spring.data.gemfire.gateway.sender.<name>.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}.
* <p> This property can also be configured using the {@literal spring.data.gemfire.gateway.sender.<name>.parallel}
* <p>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.<name>.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.
* <p> This property can also be configured using the {@literal spring.data.gemfire.gateway.sender.<name>.persistent}
* <p>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.<name>.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}.
* <p>This property can also be configured using the {@literal spring.data.gemfire.gateway.sender.<name>.region-names} property.
* <p>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.<name>.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.
* <p>This property can also be configured using the {@literal spring.data.gemfire.gateway.sender.<name>.remote-distributed-system-id}
* <p>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.<name>.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.
* <p>This property can also be configured using the {@literal spring.data.gemfire.gateway.sender.<name>.socket-buffer-size} property.
* <p>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.<name>.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).
* <p>This property can also be configured using the {@literal spring.data.gemfire.gateway.sender.<name>.socket-read-timeout} property.
* <p>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.<name>.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}
* <p>This property can also be configured using the {@literal spring.data.gemfire.gateway.sender.<name>.transport-filters}s property
* <p>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.<name>.transport-filters} property
* in {@literal application.properties}.
*/
String[] transportFilters() default {};
}

View File

@@ -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 <b><i>gatewaySenders</i></b> 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 <b><i>gatewaySenders</i></b> 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.
* <p> This property can also be configured using the <b><i>spring.data.gemfire.gateway.sender.alert-threshold</i></b>
* <p>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.
* <p> This property can also be configured using the <b><i>spring.data.gemfire.gateway.sender.batch-conflation-enabled</i></b>
* <p>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 <b><i>batchSize</i></b> or <b><i>batchTimeInterval</i></b>
* is met.
* <p> This property can also be configured using the <b><i>spring.data.gemfire.gateway.sender.batch-size</i></b>
* <p>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}.
* <p>This property works in conjunction with the {@link EnableGatewaySenders#batchSize()} setting.
* The {@link org.apache.geode.cache.wan.GatewaySender} will send when either the <b><i>batchSize</i></b> or <b><i>batchTimeInterval</i></b>
* is met.
* <p> This property can also be configured using the <b><i>spring.data.gemfire.gateway.sender.batch-time-interval</i></b>
* <p>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 <b><i>persistent</i></b> property is set to <b><i>true</i></b>.
* <p> This property can also be configured using the <b><i>spring.data.gemfire.gateway.sender.diskstore-reference</i></b>
* <p>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.
* <p> This property can also be configured using the <b><i>spring.data.gemfire.gateway.sender.disk-synchronous</i></b>
* <p>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.
* <p>This property can also be configured using the <b><i>spring.data.gemfire.gateway.sender.dispatcher-threads</i></b>
* <p>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}.
* <p>This property can also be configured using the <b><i>spring.data.gemfire.gateway.sender.event-filters</i></b> property.
* <p>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.
* <p> This property can also be configured using the <b><i>spring.data.gemfire.gateway.sender.event-substitution-filter</i></b>
* <p>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
* <p>This property can also be configured using the <b><i>spring.data.gemfire.gateway.sender.manual-start</i></b>
* <p>Default is {@value @EnableGatewaySenderConfiguration.DEFAULT_MANUAL_START}
* A {@literal boolean} flag indicating whether all configured {@link GatewaySender GatewaySenders} should be
* started automatically.
*
* <p>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.
* <p>This property can also be configured using the <b><i>spring.data.gemfire.gateway.sender.maximum-queue-memory</i></b>
* <p>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.
* <p>This property can also be configured using the <b><i>spring.data.gemfire.gateway.sender.remote-distributed-system-id</i></b>
* <p>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}.
*
* <p>There are three different ordering policies:
*
* <ul>
* <li>{@link OrderPolicyType#KEY} - Order of events preserved on a per key basis</li>
* <li>{@link OrderPolicyType#THREAD} - Order of events preserved by the thread that added the event</li>
* <li>{@link OrderPolicyType#PARTITION} - Order of events is preserved in order that they arrived in partitioned Region</li>
* </ul>
* <p>This property can also be configured using the <b><i>spring.data.gemfire.gateway.sender.order-policy</i></b></p>
* <p>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}.
* <p> This property can also be configured using the <b><i>spring.data.gemfire.gateway.sender.parallel</i></b>
* <p>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 <b><i>diskStoreReference</i></b> property.
* <p> This property can also be configured using the <b><i>spring.data.gemfire.gateway.sender.persistent</i></b>
* <p>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}.
* <p>This property can also be configured using the <b><i>spring.data.gemfire.gateway.sender.region-names</i></b> property.
* <p>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.
* <p>This property can also be configured using the <b><i>spring.data.gemfire.gateway.sender.socket-buffer-size</i></b> property.
* <p>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).
* <p>This property can also be configured using the <b><i>spring.data.gemfire.gateway.sender.socket-read-timeout</i></b> property.
* <p>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}
* <p>This property can also be configured using the <b><i>spring.data.gemfire.gateway.sender.transport-filters</i></b>s property
* <p>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 {};
}

View File

@@ -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<GatewaySenderConfigurer> 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<String, Object> annotationAttributesMap = annotationMetadata
.getAnnotationAttributes(EnableGatewaySender.class.getName());
AnnotationAttributes gatewaySenderAnnotation = AnnotationAttributes.fromMap(annotationAttributesMap);
registerGatewaySender(gatewaySenderAnnotation, beanDefinitionRegistry, null);
}
}
@Override protected Class<? extends Annotation> getAnnotationType() {
protected Class<? extends Annotation> 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 <b><i>application.properties</i></b>.
* 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 <b><i>application.properties</i></b>.
*
* @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 <i>"named"</i> properties and will follow the following pattern:
* <b><i>{@literal spring.data.gemfire.gateway.sender.<name>.manual-start}</i></b>
*/
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.<name>.manual-start}.
*/
private <T> 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> T getValueFromAnnotation(AnnotationAttributes gatewaySenderAnnotation, Supplier<T> 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 <b><i>application.properties</i></b>
* file.
* These properties are <i>"named"</i> properties and will follow the following pattern:
* <b><i>{@literal spring.data.gemfire.gateway.sender.<name>.manual-start}</i></b>
*
* @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 <b><i>application.properties</i></b>
* file.
* These properties are <i>"named"</i> properties and will follow the following pattern:
* <b><i>{@literal spring.data.gemfire.gateway.sender.<name>.manual-start}</i></b>
*
* @param gatewaySenderBeanBuilder
* @param gatewaySenderName
* @param propertyName
* @param defaultValue
*/
private <T extends Object> 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> T getValueFromAnnotation(AnnotationAttributes gatewaySenderAnnotation, Supplier<T> supplier) {
return gatewaySenderAnnotation != null ? supplier.get() : null;
}
private <T> T getValueFromAnnotation(AnnotationAttributes gatewaySenderAnnotation, Supplier<T> 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<GatewaySenderConfigurer> resolveGatewaySenderConfigurers() {
@@ -451,37 +455,40 @@ public class GatewaySenderConfiguration extends AbstractAnnotationConfigSupport
Collections.singletonList(LazyResolvingComposableGatewaySenderConfigurer.create(getBeanFactory())));
}
private <T extends Object> T resolveValueFromProperty(String gatewaySenderName, String propertyName,
T defaultValue) {
Class<T> clazz = (Class<T>) defaultValue.getClass();
@SuppressWarnings("unchecked")
private <T> T resolveValueFromProperty(String gatewaySenderName, String propertyName, T defaultValue) {
Optional<T> gatewaySenderProperty = Optional
.ofNullable(resolveProperty(gatewaySenderProperty(propertyName), clazz, null));
Class<T> type = (Class<T>) defaultValue.getClass();
Optional<T> 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 <T> 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 <T> 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<BeanReference> 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) {
}
}

View File

@@ -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<String, Object> 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<? extends Annotation> getAnnotationType() {
protected Class<? extends Annotation> 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);
}
}

View File

@@ -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<GatewaySenderFactoryBean, GatewaySenderConfigurer>
implements GatewaySenderConfigurer {
extends AbstractLazyResolvingComposableConfigurer<GatewaySenderFactoryBean, GatewaySenderConfigurer>
implements GatewaySenderConfigurer {
public static LazyResolvingComposableGatewaySenderConfigurer create() {
return create(null);

View File

@@ -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}.
*

View File

@@ -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<? extends Annotation> 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<String, Map<String, BeanDefinition>> cachedBeanDefinitions = populateBeanDefinitionCache(beanFactory);
//Create a list of gatewaySender to Regions mapping
Map<String, List<String>> gatewaySenderToRegions = groupGatewaySenderPerRegion(cachedBeanDefinitions,
new HashMap<>());
// Create a list of gatewaySender to Regions mapping
Map<String, List<String>> 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<String, Map<String, BeanDefinition>> populateBeanDefinitionCache(
ConfigurableListableBeanFactory beanFactory) {
Map<String, Map<String, BeanDefinition>> 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<String, List<String>> gatewaySenderToRegions) {
gatewaySenderToRegions.entrySet().forEach(entry -> {
List<RuntimeBeanReference> beanReferenceList = entry.getValue().stream()
.map(RuntimeBeanReference::new).collect(Collectors.toList());
ManagedList<RuntimeBeanReference> 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 <<String>, List<BeanDefinitions>>} grouped by the {@literal key}.
*/
private Map<String, Map<String, BeanDefinition>> addBeanDefinitionToList(String beanName,
BeanDefinition beanDefinition, Map<String, Map<String, BeanDefinition>> cachedBeanDefinitions, String key) {
Map<String, BeanDefinition> beanDefinitions = cachedBeanDefinitions.computeIfAbsent(key, k -> new HashMap<>());
beanDefinitions.put(beanName, beanDefinition);
return cachedBeanDefinitions;
}
/**
* Mapping of {@link GatewaySender} to {@link Region Regions}.
*/
private Map<String, List<String>> groupGatewaySenderPerRegion(
Map<String, Map<String, BeanDefinition>> cachedBeanDefinitions,
Map<String, List<String>> gatewaySendersPerRegion) {
Map<String, Map<String, BeanDefinition>> cachedBeanDefinitions,
Map<String, List<String>> gatewaySendersPerRegion) {
Optional<Map<String, BeanDefinition>> gatewaySenders = Optional
.ofNullable(cachedBeanDefinitions.get("gatewaySenders"));
Optional<Map<String, BeanDefinition>> 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<PropertyValue> regionsOptional = Optional.ofNullable(regions);
PropertyValue regions = gatewaySenderBean.getPropertyValues()
.getPropertyValue("regions");
Collection<String> regionNames;
List<String> 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<String> 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<String, Map<String, BeanDefinition>> populateBeanDefinitionCache(
ConfigurableListableBeanFactory beanFactory) {
Map<String, Map<String, BeanDefinition>> 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<String, List<String>> gatewaySenderToRegions) {
/**
* Creates a map of <<String>,List<BeanDefinitions>> grouped by the `key`
*
* @param beanName
* @param beanDefinition
* @param cachedBeanDefinitions
* @param key
* @return
*/
private Map<String, Map<String, BeanDefinition>> addBeanDefinitionToList(String beanName,
BeanDefinition beanDefinition,
Map<String, Map<String, BeanDefinition>> cachedBeanDefinitions, String key) {
Map<String, BeanDefinition> 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<RuntimeBeanReference> 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<String, List<String>> regionMapping,
String gatewaySenderName, Collection<String> regionNames) {
private void addGatewaySendersToRegion(Map<String, List<String>> regionMapping, String gatewaySenderName,
Collection<String> regionNames) {
regionNames.forEach(regionName -> {
List<String> gatewaySenders = regionMapping.get(regionName);
if (gatewaySenders == null) {
gatewaySenders = new ArrayList<>();
}
List<String> 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<Object> 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<Class> resolveBeanClass(BeanDefinition beanDefinition,
ConfigurableListableBeanFactory beanFactory) {
Optional<String> 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;
});
}
}

View File

@@ -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.
*

View File

@@ -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<T> 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<T> 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<T> extends AbstractFactory
this.name = name;
}
public void setCache(Cache cache) {
this.cache = cache;
}
public String getName() {
return StringUtils.hasText(this.name)

View File

@@ -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<Ga
private Integer socketBufferSize;
private Integer socketReadTimeout;
private String diskStoreReference;
private List<GatewaySenderConfigurer> gatewaySenderConfigurers = Collections.emptyList();
private List<String> regions;
// TODO: Come of with better association and remove.
private List<String> 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<Ga
*/
public GatewaySenderFactoryBean(GemFireCache cache) {
super(cache);
this.regions = Arrays.asList(new String[] {});
}
public GatewaySenderFactoryBean() {
}
/**
@@ -107,43 +110,43 @@ public class GatewaySenderFactoryBean extends AbstractWANComponentFactoryBean<Ga
GatewaySenderFactory gatewaySenderFactory = resolveGatewaySenderFactory();
stream(nullSafeIterable(gatewaySenderConfigurers).spliterator(), false)
.forEach(gatewaySenderConfigurer1 -> 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<Ga
: GatewaySender.class;
}
public boolean isManualStart() {
return manualStart;
}
public void setManualStart(boolean manualStart) {
this.manualStart = manualStart;
}
public int getRemoteDistributedSystemId() {
return remoteDistributedSystemId;
}
public void setRemoteDistributedSystemId(int remoteDistributedSystemId) {
this.remoteDistributedSystemId = remoteDistributedSystemId;
}
public GatewaySender getGatewaySender() {
return gatewaySender;
}
public void setGatewaySender(GatewaySender gatewaySender) {
this.gatewaySender = gatewaySender;
}
public List<GatewayEventFilter> getEventFilters() {
return eventFilters;
}
public void setEventFilters(List<GatewayEventFilter> eventFilters) {
this.eventFilters = eventFilters;
}
public List<GatewayTransportFilter> getTransportFilters() {
return transportFilters;
}
public void setTransportFilters(List<GatewayTransportFilter> 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<GatewaySenderConfigurer> 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<String> getRegions() {
return regions;
public void setDiskStoreReference(String diskStoreReference) {
this.diskStoreReference = diskStoreReference;
}
public void setRegions(List<String> 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<GatewayEventFilter> eventFilters) {
this.eventFilters = eventFilters;
}
public List<GatewayEventFilter> 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<String> regions) {
this.regions.addAll(CollectionUtils.nullSafeList(regions));
}
public List<String> 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<GatewayTransportFilter> transportFilters) {
this.transportFilters = transportFilters;
}
public List<GatewayTransportFilter> getTransportFilters() {
return this.transportFilters;
}
}

View File

@@ -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);
}
}
}

View File

@@ -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<String, GatewaySender> 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<String, GatewaySender> 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<String, GatewaySender> 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 {

View File

@@ -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<String, GatewaySender> 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);
});
};
}
}
}

View File

@@ -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

View File

@@ -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);