spring-data-gemfirespring-boot-data-geode

spring data geode pool is not resolvable as a Pool in the application context


I've come back to a @SpringBootApplication project that uses spring-geode-starter with version 1.2.4 although the same error happens with upgrades to 1.5.6 version.

It sets up a Geode client using

@Component
@EnableClusterDefinedRegions(clientRegionShortcut=ClientRegionShortcut.PROXY)

and in order to register interest subscriptions over HTTP, also

@Configuration
@EnableGemFireHttpSession

with a bean

@Bean
public ReactiveSessionRepository<?> reactiveSessionRepository() {
    return new ReactiveMapSessionRepository(new ConcurrentHashMap<>());
}

On starting the application the spring data geode client connects to the server (Geode version 1.14) and auto copies regions back to the client, which is great.

However, after all the region handles are copied over, there's an error with the @EnableGemFireHttpSession which is

Error creating bean with name 'ClusteredSpringSessions' defined in class path resource [org/springframework/session/data/gemfire/config/annotation/web/http/GemFireHttpSessionConfiguration.class] and [gemfirePool] is not resolvable as a Pool in the application context

The first info message in the logs is:

org.springframework.session.data.gemfire.config.annotation.web.http.GemFireHttpSessionConfiguration 1109 sessionRegionAttributes: Expiration is not allowed on Regions with a data management policy of PROXY
org.springframework.data.gemfire.support.AbstractFactoryBeanSupport 277 lambda$logInfo$3: Falling back to creating Region [ClusteredSpringSessions] in Cache [Web]

So the client is trying to create a region ClusteredSpringSessions but it can't. The problem appears to resolve itself if I define a connection pool for HTTP, with a pool connection bean like this

@Configuration
@EnableGemFireHttpSession(poolName="devPool")
public class SessionConfig {

@Bean
public ReactiveSessionRepository<?> reactiveSessionRepository() {
    return new ReactiveMapSessionRepository(new ConcurrentHashMap<>());
}

@Bean("devPool")
PoolFactoryBean sessionPool() {
    PoolFactoryBean pool = new PoolFactoryBean();
    ConnectionEndpoint ce = new ConnectionEndpoint("1.2.3.4", 10334);       
    pool.setSubscriptionEnabled(true);
    pool.addLocators(ce);
    return pool;
} 

}

There is still the Expiration is not allowed on Regions with a data management policy of PROXY info message in the log, but this time the Falling back to creating Region [ClusteredSpringSessions] in Cache [Web] appears to work.

I don't understand why a default pool can't connect.

If a pool is defined then in version 1.2.4 that can cause this issue.


Solution

  • Since you are using Spring Boot for Apache Geode (SBDG), which is an excellent choice (thank you), then you can simply include the spring-geode-starter-session dependency on your @SpringBootApplication classpath, which removes the need to explicitly annotate your Spring Boot application with SSDG's @EnableGemFireHttpSession annotation.

    See here for more details. I also have a Sample application demonstrating the use of SSDG, here. The guide and source code for this example, along with other examples, can be found here).

    Also, I would generally advise that users drive the GemFire/Geode cluster configuration from the application and not let the cluster dictate the Regions (and/or other components/configuration) that the client gets. However, SDG's @EnableClusterDefinedRegions annotation is provided and generally useful in the case you do not have control over the GemFire/Geode cluster your application is using. Still, in the (HTTP) Session UC, the GemFire/Geode cluster would need a Session Region (which defaults to "ClusteredSpringSessions" as determined by Spring Session for Apache Geode (SSDG) itself) anyway.

    OK, now to the problem at hand...

    I think what is happening here is, due to backwards compatibility and legacy reasons, Spring Data for Apache Geode (SDG), on which both SSDG and SBDG are based; SBDG additionally pulls in SSDG as well, defined a GemFire/Geode Pool by the name of "gemfirePool", specifically when using the SDG XML space and using/defining a DataSource configuration.

    So, it is somewhat naively assumed users would be explicitly defining a Pool and calling it "gemfirePool", and not simply relying on a "default" Pool connection to the GemFire/Geode cache server (namely "localhost", 40404, or if using Locators (recommended), "localhost" and 10334).

    However, for development purposes, and in SBDG specifically, I rely on the fact that GemFire/Geode creates a "DEFAULT" Pool anyway (when no explicit Pool is defined), and forgo the strict requirement that a "gemfirePool" should exist. But, SBDG builds on SSDG and SDG and they still rely on the legacy arrangement (for example).

    I have filed an Issue ticket in SSDG to change this and better align SSDG with what SBDG prefers going forward, but I simply have not gotten around to it yet. My apologies for your inconvenience.

    Anyway, it is a simple change you can make externally from your Spring Boot application, in application.properties like so (see here from the HTTP Session Sample I referenced from SBDG above). This will allow you to configure the Session Region Pool "name".

    Also note, it is possible to change the name of the Session Region used by the client if what comes down from the cluster when you are using SDG's @EnableClusterDefinedRegions and the Region definition pulled down from the cluster is named differently on the server-side using this property.

    Additionally, you can also configure the client Session Region data policy using properties as well (for example).

    Regarding the Expiration "info" message you are seeing in the logs...

    Since the client Session Region is a PROXY by default, then Expiration, Eviction and other Region data management policies (e.g. Compression, etc), do not actually make much sense.

    In fact, SSDG is smart about whether to apply additional Region data management policies locally or not (see here, and specifically, this logic).

    The message you are seeing in your application logs is in fact coming from SSDG, specifically. This message really serves as a reminder that your Session state management is actually "managed" on the server-side (when the application client is using a PROXY or even a CACHING_PROXY Region for that matter) and that the corresponding server-side, or cluster Sessions Region should be configured manually and appropriately, with Expiration policies as well as other things if necessary. Otherwise, no Session expiration would actually happen!

    I hope all this makes since.

    If you continue to have problems, feel free to file an Issue ticket and provide an example test or small application replicating your problem.