/*
* Copyright 2012 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
*
* http://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.util.Map;
import java.util.concurrent.atomic.AtomicBoolean;
import org.springframework.beans.factory.config.BeanDefinition;
import org.springframework.beans.factory.support.BeanDefinitionBuilder;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.core.annotation.AnnotationAttributes;
import org.springframework.core.type.AnnotationMetadata;
import org.springframework.data.gemfire.CacheFactoryBean;
import org.springframework.data.gemfire.client.ClientCacheFactoryBean;
import org.springframework.data.gemfire.config.support.ClientRegionPoolBeanFactoryPostProcessor;
import org.springframework.data.gemfire.support.ConnectionEndpoint;
import org.springframework.data.gemfire.support.ConnectionEndpointList;
/**
* Spring {@link Configuration} class used to configure, construct and initialize
* a GemFire {@link org.apache.geode.cache.client.ClientCache} instance in a Spring application context.
*
* @author John Blum
* @see org.springframework.context.annotation.Bean
* @see org.springframework.context.annotation.Configuration
* @see org.springframework.data.gemfire.config.annotation.AbstractCacheConfiguration
* @see org.apache.geode.cache.client.ClientCache
* @since 1.0.0
*/
@Configuration
@SuppressWarnings("unused")
public class ClientCacheConfiguration extends AbstractCacheConfiguration {
private static final AtomicBoolean CLIENT_REGION_POOL_BEAN_FACTORY_POST_PROCESSOR_REGISTERED =
new AtomicBoolean(false);
protected static final boolean DEFAULT_READY_FOR_EVENTS = false;
protected static final String DEFAULT_NAME = "SpringBasedCacheClientApplication";
private boolean readyForEvents = DEFAULT_READY_FOR_EVENTS;
private Boolean keepAlive;
private Boolean multiUserAuthentication;
private Boolean prSingleHopEnabled;
private Boolean subscriptionEnabled;
private Boolean threadLocalConnections;
private Integer durableClientTimeout;
private Integer freeConnectionTimeout;
private Integer loadConditioningInterval;
private Integer maxConnections;
private Integer minConnections;
private Integer readTimeout;
private Integer retryAttempts;
private Integer socketBufferSize;
private Integer statisticsInterval;
private Integer subscriptionAckInterval;
private Integer subscriptionMessageTrackingTimeout;
private Integer subscriptionRedundancy;
private Iterable<ConnectionEndpoint> locators;
private Iterable<ConnectionEndpoint> servers;
private Long idleTimeout;
private Long pingInterval;
private String durableClientId;
private String serverGroup;
@Bean
public ClientCacheFactoryBean gemfireCache() {
ClientCacheFactoryBean gemfireCache = constructCacheFactoryBean();
gemfireCache.setDurableClientId(durableClientId());
gemfireCache.setDurableClientTimeout(durableClientTimeout());
gemfireCache.setFreeConnectionTimeout(freeConnectionTimeout());
gemfireCache.setIdleTimeout(idleTimeout());
gemfireCache.setKeepAlive(keepAlive());
gemfireCache.setLocators(poolLocators());
gemfireCache.setLoadConditioningInterval(loadConditioningInterval());
gemfireCache.setMaxConnections(maxConnections());
gemfireCache.setMinConnections(minConnections());
gemfireCache.setMultiUserAuthentication(multiUserAuthentication());
gemfireCache.setPingInterval(pingInterval());
gemfireCache.setPrSingleHopEnabled(prSingleHopEnabled());
gemfireCache.setReadTimeout(readTimeout());
gemfireCache.setReadyForEvents(readyForEvents());
gemfireCache.setRetryAttempts(retryAttempts());
gemfireCache.setServerGroup(serverGroup());
gemfireCache.setServers(poolServers());
gemfireCache.setSocketBufferSize(socketBufferSize());
gemfireCache.setStatisticsInterval(statisticsInterval());
gemfireCache.setSubscriptionAckInterval(subscriptionAckInterval());
gemfireCache.setSubscriptionEnabled(subscriptionEnabled());
gemfireCache.setSubscriptionMessageTrackingTimeout(subscriptionMessageTrackingTimeout());
gemfireCache.setSubscriptionRedundancy(subscriptionRedundancy());
gemfireCache.setThreadLocalConnections(threadLocalConnections());
return gemfireCache;
}
/**
* {@inheritDoc}
*/
@Override
@SuppressWarnings("unchecked")
protected <T extends CacheFactoryBean> T newCacheFactoryBean() {
return (T) new ClientCacheFactoryBean();
}
/**
* {@inheritDoc}
*/
@Override
protected void configureInfrastructure(AnnotationMetadata importMetadata) {
super.configureInfrastructure(importMetadata);
registerClientRegionPoolBeanFactoryPostProcessor(importMetadata);
}
/* (non-Javadoc) */
protected void registerClientRegionPoolBeanFactoryPostProcessor(AnnotationMetadata importMetadata) {
if (CLIENT_REGION_POOL_BEAN_FACTORY_POST_PROCESSOR_REGISTERED.compareAndSet(false, true)) {
register(BeanDefinitionBuilder.rootBeanDefinition(ClientRegionPoolBeanFactoryPostProcessor.class)
.setRole(BeanDefinition.ROLE_INFRASTRUCTURE).getBeanDefinition());
}
}
/**
* Configures GemFire {@link org.apache.geode.cache.client.ClientCache} specific settings.
*
* @param importMetadata {@link AnnotationMetadata} containing client cache meta-data used to configure
* the GemFire {@link org.apache.geode.cache.client.ClientCache}.
* @see org.springframework.core.type.AnnotationMetadata
*/
@Override
protected void configureCache(AnnotationMetadata importMetadata) {
super.configureCache(importMetadata);
if (isClientCacheApplication(importMetadata)) {
Map<String, Object> clientCacheApplicationAttributes =
importMetadata.getAnnotationAttributes(getAnnotationTypeName());
setDurableClientId((String) clientCacheApplicationAttributes.get("durableClientId"));
setDurableClientTimeout((Integer) clientCacheApplicationAttributes.get("durableClientTimeout"));
setFreeConnectionTimeout((Integer) clientCacheApplicationAttributes.get("freeConnectionTimeout"));
setIdleTimeout((Long) clientCacheApplicationAttributes.get("idleTimeout"));
setKeepAlive(Boolean.TRUE.equals(clientCacheApplicationAttributes.get("keepAlive")));
setLoadConditioningInterval((Integer) clientCacheApplicationAttributes.get("loadConditioningInterval"));
setMaxConnections((Integer) clientCacheApplicationAttributes.get("maxConnections"));
setMinConnections((Integer) clientCacheApplicationAttributes.get("minConnections"));
setMultiUserAuthentication(Boolean.TRUE.equals(clientCacheApplicationAttributes.get("multiUserAuthentication")));
setPingInterval((Long) clientCacheApplicationAttributes.get("pingInterval"));
setPrSingleHopEnabled(Boolean.TRUE.equals(clientCacheApplicationAttributes.get("prSingleHopEnabled")));
setReadTimeout((Integer) clientCacheApplicationAttributes.get("readTimeout"));
setReadyForEvents(Boolean.TRUE.equals(clientCacheApplicationAttributes.get("readyForEvents")));
setRetryAttempts((Integer) clientCacheApplicationAttributes.get("retryAttempts"));
setServerGroup((String) clientCacheApplicationAttributes.get("serverGroup"));
setSocketBufferSize((Integer) clientCacheApplicationAttributes.get("socketBufferSize"));
setStatisticsInterval((Integer) clientCacheApplicationAttributes.get("statisticInterval"));
setSubscriptionAckInterval((Integer) clientCacheApplicationAttributes.get("subscriptionAckInterval"));
setSubscriptionEnabled(Boolean.TRUE.equals(clientCacheApplicationAttributes.get("subscriptionEnabled")));
setSubscriptionMessageTrackingTimeout((Integer) clientCacheApplicationAttributes.get("subscriptionMessageTrackingTimeout"));
setSubscriptionRedundancy((Integer) clientCacheApplicationAttributes.get("subscriptionRedundancy"));
setThreadLocalConnections(Boolean.TRUE.equals(clientCacheApplicationAttributes.get("threadLocalConnections")));
configureLocatorsAndServers(clientCacheApplicationAttributes);
}
}
/**
* Uses the list of GemFire Locator and Server connection endpoint definitions and meta-data to configure
* the GemFire client {@link org.apache.geode.cache.client.Pool} used to communicate with the servers
* in the GemFire cluster.
*
* @param clientCacheApplicationAttributes {@link ClientCacheApplication} annotation containing
* {@link org.apache.geode.cache.client.Pool} Locator/Server connection endpoint meta-data.
* @see org.springframework.data.gemfire.config.annotation.ClientCacheApplication
* @see java.util.Map
*/
protected void configureLocatorsAndServers(Map<String, Object> clientCacheApplicationAttributes) {
ConnectionEndpointList poolLocators = new ConnectionEndpointList();
AnnotationAttributes[] locators = (AnnotationAttributes[]) clientCacheApplicationAttributes.get("locators");
for (AnnotationAttributes locator : locators) {
poolLocators.add(newConnectionEndpoint((String) locator.get("host"), (Integer) locator.get("port")));
}
setPoolLocators(poolLocators);
ConnectionEndpointList poolServers = new ConnectionEndpointList();
AnnotationAttributes[] servers = (AnnotationAttributes[]) clientCacheApplicationAttributes.get("servers");
for (AnnotationAttributes server : servers) {
poolServers.add(newConnectionEndpoint((String) server.get("host"), (Integer) server.get("port")));
}
setPoolServers(poolServers);
}
/* (non-Javadoc) */
protected ConnectionEndpoint newConnectionEndpoint(String host, Integer port) {
return new ConnectionEndpoint(host, port);
}
/**
* {@inheritDoc}
*/
@Override
protected Class getAnnotationType() {
return ClientCacheApplication.class;
}
/* (non-Javadoc) */
void setDurableClientId(String durableClientId) {
this.durableClientId = durableClientId;
}
protected String durableClientId() {
return this.durableClientId;
}
/* (non-Javadoc) */
void setDurableClientTimeout(Integer durableClientTimeout) {
this.durableClientTimeout = durableClientTimeout;
}
protected Integer durableClientTimeout() {
return this.durableClientTimeout;
}
/* (non-Javadoc) */
void setFreeConnectionTimeout(Integer freeConnectionTimeout) {
this.freeConnectionTimeout = freeConnectionTimeout;
}
protected Integer freeConnectionTimeout() {
return this.freeConnectionTimeout;
}
/* (non-Javadoc) */
void setIdleTimeout(Long idleTimeout) {
this.idleTimeout = idleTimeout;
}
protected Long idleTimeout() {
return this.idleTimeout;
}
/* (non-Javadoc) */
void setKeepAlive(Boolean keepAlive) {
this.keepAlive = keepAlive;
}
protected Boolean keepAlive() {
return this.keepAlive;
}
/* (non-Javadoc) */
void setLoadConditioningInterval(Integer loadConditioningInterval) {
this.loadConditioningInterval = loadConditioningInterval;
}
protected Integer loadConditioningInterval() {
return this.loadConditioningInterval;
}
/* (non-Javadoc) */
void setMaxConnections(Integer maxConnections) {
this.maxConnections = maxConnections;
}
protected Integer maxConnections() {
return this.maxConnections;
}
/* (non-Javadoc) */
void setMinConnections(Integer minConnections) {
this.minConnections = minConnections;
}
protected Integer minConnections() {
return this.minConnections;
}
/* (non-Javadoc) */
void setMultiUserAuthentication(Boolean multiUserAuthentication) {
this.multiUserAuthentication = multiUserAuthentication;
}
protected Boolean multiUserAuthentication() {
return this.multiUserAuthentication;
}
/* (non-Javadoc) */
void setPingInterval(Long pingInterval) {
this.pingInterval = pingInterval;
}
protected Long pingInterval() {
return this.pingInterval;
}
/* (non-Javadoc) */
void setPoolLocators(Iterable<ConnectionEndpoint> locators) {
this.locators = locators;
}
protected Iterable<ConnectionEndpoint> poolLocators() {
return this.locators;
}
/* (non-Javadoc) */
void setPoolServers(Iterable<ConnectionEndpoint> servers) {
this.servers = servers;
}
protected Iterable<ConnectionEndpoint> poolServers() {
return this.servers;
}
/* (non-Javadoc) */
void setPrSingleHopEnabled(Boolean prSingleHopEnabled) {
this.prSingleHopEnabled = prSingleHopEnabled;
}
protected Boolean prSingleHopEnabled() {
return this.prSingleHopEnabled;
}
/* (non-Javadoc) */
void setReadTimeout(Integer readTimeout) {
this.readTimeout = readTimeout;
}
protected Integer readTimeout() {
return this.readTimeout;
}
/* (non-Javadoc) */
void setReadyForEvents(boolean readyForEvents) {
this.readyForEvents = readyForEvents;
}
protected boolean readyForEvents() {
return this.readyForEvents;
}
/* (non-Javadoc) */
void setRetryAttempts(Integer retryAttempts) {
this.retryAttempts = retryAttempts;
}
protected Integer retryAttempts() {
return this.retryAttempts;
}
/* (non-Javadoc) */
void setServerGroup(String serverGroup) {
this.serverGroup = serverGroup;
}
protected String serverGroup() {
return this.serverGroup;
}
/* (non-Javadoc) */
void setSocketBufferSize(Integer socketBufferSize) {
this.socketBufferSize = socketBufferSize;
}
protected Integer socketBufferSize() {
return this.socketBufferSize;
}
/* (non-Javadoc) */
void setStatisticsInterval(Integer statisticsInterval) {
this.statisticsInterval = statisticsInterval;
}
protected Integer statisticsInterval() {
return this.statisticsInterval;
}
/* (non-Javadoc) */
void setSubscriptionAckInterval(Integer subscriptionAckInterval) {
this.subscriptionAckInterval = subscriptionAckInterval;
}
protected Integer subscriptionAckInterval() {
return this.subscriptionAckInterval;
}
/* (non-Javadoc) */
void setSubscriptionEnabled(Boolean subscriptionEnabled) {
this.subscriptionEnabled = subscriptionEnabled;
}
protected Boolean subscriptionEnabled() {
return this.subscriptionEnabled;
}
/* (non-Javadoc) */
void setSubscriptionMessageTrackingTimeout(Integer subscriptionMessageTrackingTimeout) {
this.subscriptionMessageTrackingTimeout = subscriptionMessageTrackingTimeout;
}
protected Integer subscriptionMessageTrackingTimeout() {
return this.subscriptionMessageTrackingTimeout;
}
/* (non-Javadoc) */
void setSubscriptionRedundancy(Integer subscriptionRedundancy) {
this.subscriptionRedundancy = subscriptionRedundancy;
}
protected Integer subscriptionRedundancy() {
return this.subscriptionRedundancy;
}
/* (non-Javadoc) */
void setThreadLocalConnections(Boolean threadLocalConnections) {
this.threadLocalConnections = threadLocalConnections;
}
protected Boolean threadLocalConnections() {
return this.threadLocalConnections;
}
@Override
public String toString() {
return DEFAULT_NAME;
}
}