This topic discusses using GemFire properties with Spring Boot for Tanzu GemFire.
As of Spring Boot for Tanzu GemFire 1.0.0, you can declare VMware GemFire properties from gemfire.properties
in Spring Boot application.properties
.
Tip | See the User Guide for a complete list of valid VMware GemFire properties. |
Note that you can declare only valid GemFire properties in gemfire.properties
or, alternatively, gfsecurity.properties
.
The following example shows how to declare properties in gemfire.properties
:
Example 1. Valid gemfire.properties
# GemFire Properties in gemfire.properties
name=ExampleCacheName
log-level=TRACE
enable-time-statistics=true
durable-client-id=123
# ...
All the properties declared in the preceding example correspond to valid GemFire properties. It is illegal to declare properties in gemfire.properties
that are not valid GemFire properties, even if those properties are prefixed with a different qualifier (such as spring.*
). VMware GemFire throws an IllegalArgumentException
for invalid properties.
Consider the following gemfire.properties
file with an invalid-property
:
Example 2. Invalid gemfire.properties
# GemFire Properties in gemfire.properties
name=ExampleCacheName
invalid-property=TEST
VMware GemFire throws an IllegalArgumentException
:
Example 3. IllegalArgumentException
thrown by VMware GemFire for Invalid Property (Full Text Omitted)
Exception in thread "main" java.lang.IllegalArgumentException: Unknown configuration attribute name invalid-property.
Valid attribute names are: ack-severe-alert-threshold ack-wait-threshold archive-disk-space-limit ...
at o.a.g.internal.AbstractConfig.checkAttributeName(AbstractConfig.java:333)
at o.a.g.distributed.internal.AbstractDistributionConfig.checkAttributeName(AbstractDistributionConfig.java:725)
at o.a.g.distributed.internal.AbstractDistributionConfig.getAttributeType(AbstractDistributionConfig.java:887)
at o.a.g.internal.AbstractConfig.setAttribute(AbstractConfig.java:222)
at o.a.g.distributed.internal.DistributionConfigImpl.initialize(DistributionConfigImpl.java:1632)
at o.a.g.distributed.internal.DistributionConfigImpl.<init>(DistributionConfigImpl.java:994)
at o.a.g.distributed.internal.DistributionConfigImpl.<init>(DistributionConfigImpl.java:903)
at o.a.g.distributed.internal.ConnectionConfigImpl.lambda$new$2(ConnectionConfigImpl.java:37)
at o.a.g.distributed.internal.ConnectionConfigImpl.convert(ConnectionConfigImpl.java:73)
at o.a.g.distributed.internal.ConnectionConfigImpl.<init>(ConnectionConfigImpl.java:36)
at o.a.g.distributed.internal.InternalDistributedSystem$Builder.build(InternalDistributedSystem.java:3004)
at o.a.g.distributed.internal.InternalDistributedSystem.connectInternal(InternalDistributedSystem.java:269)
at o.a.g.cache.client.ClientCacheFactory.connectInternalDistributedSystem(ClientCacheFactory.java:280)
at o.a.g.cache.client.ClientCacheFactory.basicCreate(ClientCacheFactory.java:250)
at o.a.g.cache.client.ClientCacheFactory.create(ClientCacheFactory.java:216)
at org.example.app.ApacheGeodeClientCacheApplication.main(...)
It is inconvenient to have to separate VMware GemFire properties from other application properties, or to have to declare only VMware GemFire properties in a gemfire.properties
file and application properties in a separate properties file, such as Spring Boot application.properties
.
Additionally, because of VMware GemFire’s constraint on properties, you cannot use the full power of Spring Boot when you compose application.properties
.
You can include certain properties based on a Spring profile while excluding other properties. This is essential when properties are environment- or context-specific.
Spring Data for VMware GemFire already provides a wide range of properties mapping to VMware GemFire properties.
For example, the Spring Data for VMware GemFire spring.data.gemfire.locators
property maps to the gemfire.locators
property (locators
in gemfire.properties
) from VMware GemFire. Likewise, there are a full set of Spring Data for VMware GemFire properties that map to the corresponding VMware GemFire properties in the Appendix.
You can express the GemFire properties shown earlier as Spring Data for VMware GemFire properties in Spring Boot application.properties
, as follows:
Example 4. Configuring GemFire Properties using Spring Data for VMware GemFire Properties
# Spring Data for VMware GemFire properties in application.properties
spring.data.gemfire.name=ExampleCacheName
spring.data.gemfire.cache.log-level=TRACE
spring.data.gemfire.cache.client.durable-client-id=123
spring.data.gemfire.stats.enable-time-statistics=true
# ...
However, some VMware GemFire properties have no equivalent Spring Data for VMware GemFire property, such as gemfire.groups
(groups
in gemfire.properties
). This is partly due to the fact that many VMware GemFire properties are applicable only when configured on the server (such as groups
or enforce-unique-host
).
Furthermore, many of the Spring Data for VMware GemFire properties also correspond to API calls.
For example, spring.data.gemfire.cache.client.keep-alive
translates to the ClientCache.close(boolean keepAlive)
API call (see VMware GemFire Java API Reference).
Still, it would be convenient to be able to declare application and VMware GemFire properties together, in a single properties file, such as Spring Boot application.properties
. After all, it is not uncommon to declare JDBC Connection properties in a Spring Boot application.properties
file.
Therefore, as of Spring Boot for Tanzu GemFire 1.0.0, you can now declare VMware GemFire properties in Spring Boot application.properties
directly, as follows:
Example 5. GemFire Properties declared in Spring Boot application.properties
# Spring Boot application.properties
server.port=8181
spring.application.name=ExampleApp
gemfire.durable-client-id=123
gemfire.enable-time-statistics=true
This is convenient and ideal for several reasons:
-
If you already have a large number of VMware GemFire properties declared as
gemfire.
properties (either ingemfire.properties
orgfsecurity.properties
) or declared on the Java command-line as JVM System properties (such as-Dgemfire.name=ExampleCacheName
), you can reuse these property declarations. -
If you are unfamiliar with Spring Data for VMware GemFire’s corresponding properties, you can declare GemFire properties instead.
-
You can take advantage of Spring features, such as Spring profiles.
-
You can also use property placeholders with GemFire properties (such as
gemfire.log-level=${external.log-level.property}
).
Tip | We encourage you to use the Spring Data for VMware GemFire properties, which cover more than VMware GemFire properties. |
However, Spring Boot for Tanzu GemFire requires that the GemFire property must have the gemfire.
prefix in Spring Boot application.properties
. This indicates that the property belongs to VMware GemFire. Without the gemfire.
prefix, the property is not appropriately applied to the VMware GemFire cache instance.
It would be ambiguous if your Spring Boot applications integrated with several technologies, including VMware GemFire, and they too had matching properties, such as bind-address
or log-file
.
Spring Boot for Tanzu GemFire makes a best attempt to log warnings when a GemFire property is invalid or is not set. For example, the following GemFire property would result in logging a warning:
Example 6. Invalid VMware GemFire Property
# Spring Boot application.properties
spring.application.name=ExampleApp
gemfire.non-existing-property=TEST
The resulting warning in the log would read:
Example 7. Invalid GemFire Property Warning Message
[gemfire.non-existing-property] is not a valid VMware GemFire property
If a GemFire Property is not properly set, the following warning is logged:
Example 8. Invalid GemFire Property Value Warning Message
VMware GemFire Property [gemfire.security-manager] was not set
In regard to the third point mentioned earlier, you can now compose and declare GemFire properties based on a context (such as your application environment) using Spring profiles.
For example, you might start with a base set of properties in Spring Boot application.properties
:
Example 9. Base Properties
server.port=8181
spring.application.name=ExampleApp
gemfire.durable-client-id=123
gemfire.enable-time-statistics=false
Then you can vary the properties by environment, as the next two listings (for QA and production) show:
Example 10. QA Properties
# Spring Boot application-qa.properties
server.port=9191
spring.application.name=TestApp
gemfire.enable-time-statistics=true
gemfire.enable-network-partition-detection=true
gemfire.groups=QA
# ...
Example 11. Production Properties
# Spring Boot application-prod.properties
server.port=80
spring.application.name=ProductionApp
gemfire.archive-disk-space-limit=1000
gemfire.archive-file-size-limit=50
gemfire.enforce-unique-host=true
gemfire.groups=PROD
# ...
You can then apply the appropriate set of properties by configuring the Spring profile with -Dspring.profiles.active=prod
. You can also enable more than one profile at a time with -Dspring.profiles.active=profile1,profile2,…,profileN
If both spring.data.gemfire.*
properties and the matching VMware GemFire properties are declared in Spring Boot application.properties
, the Spring Data for VMware GemFire properties take precedence.
If a property is specified more than once, as would potentially be the case when composing multiple Spring Boot application.properties
files and you enable more than one Spring profile at time, the last property declaration wins. In the example shown earlier, the value for gemfire.groups
would be PROD
when -Dspring.profiles.active=qa,prod
is configured.
Consider the following Spring Boot application.properties
:
Example 12. Property Precedence
# Spring Boot application.properties
gemfire.durable-client-id=123
spring.data.gemfire.cache.client.durable-client-id=987
The durable-client-id
is 987
. It does not matter which order the Spring Data for VMware GemFire or VMware GemFire properties are declared in Spring Boot application.properties
. The matching Spring Data for VMware GemFire property overrides the VMware GemFire property when duplicates are found.
Finally, you cannot refer to GemFire properties declared in Spring Boot application.properties
with the Spring Boot for Tanzu GemFire GemFireProperties
class.
Consider the following example:
Example 13. GemFire Properties declared in Spring Boot application.properties
# Spring Boot application.properties
gemfire.name=TestCacheName
Given the preceding property, the following assertion holds:
import org.springframework.geode.boot.auto-configure.configuration.GemFireProperties;
@RunWith(SpringRunner.class)
@SpringBootTest
class GemFirePropertiesTestSuite {
@Autowired
private GemFireProperties gemfireProperties;
@Test
public void gemfirePropertiesTestCase() {
assertThat(this.gemfireProperties.getCache().getName()).isNotEqualTo("TestCacheName");
}
}
Tip | You can declare application.properties
in the @SpringBootTest annotation. For example, you could
have declared gemfire.name in the annotation by setting
@SpringBootTest(properties = { "gemfire.name=TestCacheName" })
for testing purposes instead of declaring the property in a separate
Spring Boot application.properties file. |
Only spring.data.gemfire.*
prefixed properties are mapped to the Spring Boot for Tanzu GemFire GemFireProperties
class hierarchy.
Content feedback and comments