Programmatic Control over entry-time-to-live in Ge

2020-05-01 09:32发布

问题:

Is it possible to have a ClientCache with ClientRegionShortcut.PROXY along with programmatic control over entry TTL settings (i.e. entries present in the server)?

I see the entry expiration ttl settings working fine with ClientRegionShortcut.CACHING_PROXY_HEAP_LRU. In this case I can see the entries getting invalidated in server after the configured timeout in seconds, but that is not the case for ClientRegionShortcut.PROXY settings

Is it NOT possible to dynamically control the entry-ttl settings for a ClientCache?

Below code/config works with ClientRegionShortcut.CACHING_PROXY_HEAP_LRU and NOT with ClientRegionShortcut.PROXY.

The Gemfire version is : 9.0.x The pom looks like below

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>

<groupId>com.springboot.gemfire</groupId>
<artifactId>app</artifactId>
<version>0.0.1-SNAPSHOT</version>
<packaging>jar</packaging>

<name>MyGemfireProject</name>
<description>Test Concepts project for Spring Boot with Gemfire</description>

<parent>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-parent</artifactId>
    <version>1.5.3.RELEASE</version>
    <relativePath/> <!-- lookup parent from repository -->
</parent>

<properties>
    <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
    <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
    <java.version>1.8</java.version>
</properties>

<dependencies>
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-web</artifactId>
    </dependency>
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-actuator</artifactId>
    </dependency>
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-cache</artifactId>
    </dependency>
    <dependency>
        <groupId>org.springframework.data</groupId>
        <artifactId>spring-data-gemfire</artifactId>
    </dependency>

    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-test</artifactId>
        <scope>test</scope>
    </dependency>
    <dependency>
        <groupId>org.modelmapper</groupId>
        <artifactId>modelmapper</artifactId>
        <version>0.7.4</version>
    </dependency>
    <dependency>
        <groupId>com.gemstone.gemfire</groupId>
        <artifactId>gemfire</artifactId>
        <version>8.2.6</version>
    </dependency>


</dependencies>

<repositories>
    <repository>
        <id>org.springframework.maven.milestone</id>
        <name>Spring Maven Milestone Repository</name>
        <url>http://repo.springsource.org/libs-milestone</url>
        <snapshots><enabled>false</enabled></snapshots>
    </repository>
</repositories>

<build>
    <plugins>
        <plugin>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-maven-plugin</artifactId>
        </plugin>
    </plugins>
</build>

The Gemfire Configuration looks like below:

import java.util.Properties;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Primary;
import org.springframework.context.annotation.Profile;
import org.springframework.data.gemfire.ExpirationActionType;
import org.springframework.data.gemfire.support.GemfireCacheManager;

import com.gemstone.gemfire.cache.AttributesMutator;
import com.gemstone.gemfire.cache.ExpirationAttributes;
import com.gemstone.gemfire.cache.Region;
import com.gemstone.gemfire.cache.client.ClientCache;
import com.gemstone.gemfire.cache.client.ClientCacheFactory;
import com.gemstone.gemfire.cache.client.ClientRegionFactory;
import com.gemstone.gemfire.cache.client.ClientRegionShortcut;
import com.gemstone.gemfire.pdx.ReflectionBasedAutoSerializer;

/**
 * The Class NativeGemfireConfig.
 */
@Configuration
@Profile("local")
public class NativeGemfireConfig {

    /** The Constant log. */
    private static final Logger log = LoggerFactory.getLogger(NativeGemfireConfig.class);
    protected static final String DEFAULT_MANAGER_PORT = "1099";

    /** The region name. */
    @Value("${spring.gemfire.region.name:test}")
    private String regionName;

    @Bean
    Properties gemfireProperties(@Value("${spring.gemfire.log-level}") String logLevel,
            @Value("${spring.gemfire.mcast-port}") String mcastPort,
            @Value("${spring.gemfire.jmx-manager}") String jmxManager,
            @Value("${spring.gemfire.jmx-manager-start}") String jmxManagerStart,
            @Value("${spring.gemfire.username}") String gemfireuser,
            @Value("${spring.gemfire.password}") String gemfirepassword) {

        Properties gemfireProperties = new Properties();

        gemfireProperties.setProperty("name", NativeGemfireConfig.class.getSimpleName());
        gemfireProperties.setProperty("mcast-port", mcastPort);
        gemfireProperties.setProperty("log-level", logLevel);
        gemfireProperties.setProperty("jmx-manager", jmxManager);
        gemfireProperties.setProperty("jmx-manager-port", DEFAULT_MANAGER_PORT);
        gemfireProperties.setProperty("jmx-manager-start", jmxManagerStart);
        gemfireProperties.setProperty("security-username", gemfireuser);
        gemfireProperties.setProperty("security-password", gemfirepassword);
        gemfireProperties.setProperty("security-client-auth-init",
                "com.springboot.gemfire.config.GemFireAuthInitializor.create");

        return gemfireProperties;
    }

    @Bean
    @Primary
    ReflectionBasedAutoSerializer reflectionBasedAutoSerializer() {
        return new ReflectionBasedAutoSerializer("com.springboot.gemfire.model.*");
    }

    @Bean
    @Primary
    ClientCacheFactory clientCacheFactory(@Value("${spring.gemfire.host}") String gemFirehost,
            @Value("${spring.gemfire.port}") int gemfirePort, Properties gemfireProperties,
            ReflectionBasedAutoSerializer reflectionBasedAutoSerializer) {

        ClientCacheFactory cachefactory = new ClientCacheFactory(gemfireProperties);
        cachefactory.addPoolLocator(gemFirehost, gemfirePort);
        cachefactory.setPdxSerializer(reflectionBasedAutoSerializer);
        cachefactory.setPdxReadSerialized(false);
        cachefactory.setPdxIgnoreUnreadFields(true);

        return cachefactory;
    }

    /**
     * Gemfire cache.
     *
     * @return the client cache
     */
     @Bean
     @Primary 
     ClientCache gemfireCache(@Qualifier("gemfireProperties")Properties gemfireProperties, 
             ClientCacheFactory clientCacheFactory, 
             @Value("${spring.gemfire.username}") String gemfireuser,
             @Value("${spring.gemfire.password}") String gemfirepassword) 
     {

     return 
             clientCacheFactory
                 .set("security-username", gemfireuser)
                 .set("security-password", gemfirepassword)
                 .set("security-client-auth-init", 
                         "com.springboot.gemfire.config.GemFireAuthInitializor.create")
                 .create(); 
     }


    @Bean
    public ExpirationAttributes entryTtlExpirationAttributes(
            @Value("${spring.gemfire.region.expiration.entry.ttl.timeout}") int timeout) {

        return new ExpirationAttributes(timeout,
                ExpirationActionType.INVALIDATE.getExpirationAction());
    }

    @Bean
    @Primary
    Region<Object, Object> tokenRegionBean(ClientCache gemfireCache,
            @Qualifier("entryTtlExpirationAttributes") ExpirationAttributes expirationAttributes) {

        ClientRegionFactory<Object, Object> tokenRegionFactory = gemfireCache
                .createClientRegionFactory(ClientRegionShortcut.CACHING_PROXY_HEAP_LRU);
        tokenRegionFactory.setStatisticsEnabled(true);

        Region<Object, Object> region = tokenRegionFactory.create(regionName);

        AttributesMutator<Object, Object> mutator = region.getAttributesMutator();
        mutator.setEntryTimeToLive(expirationAttributes);

        return region;
    }


    @Bean
    GemfireCacheManager cacheManager(ClientCache gemfireCache) {
        GemfireCacheManager cacheManager = new GemfireCacheManager();
        cacheManager.setCache(gemfireCache);

        return cacheManager;
    }


    /**
     * Gets the region name.
     *
     * @return the region name
     */
    public String getRegionName() {
        return regionName;
    }

    /**
     * Sets the region name.
     *
     * @param regionName
     *            the new region name
     */
    public void setRegionName(final String regionName) {
        this.regionName = regionName;
    }
}

The application-local.yml relevant entries are

spring:
  gemfire:
    log-level: config
    region: 
      name: myRegion
      expiration:
        entry:
          ttl:
            timeout: 120
    host: remote-server
    port: port-to-connect
    mcast-port: 0
    jmx-manager: false
    jmx-manager-start: false
    username: uname
    password: passwd