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.
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 theRegion
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.