The following Spring Framework, Spring Data for Apache Geode & Pivotal GemFire (SDG) and Spring Session for Apache Geode & Pivotal GemFire (SSDG) Annotations are implicitly declared by Spring Boot for Apache Geode & Pivotal GemFire’s (SBDG) Auto-configuration.
@ClientCacheApplication
@EnableGemfireCaching
(or alternatively, Spring Framework’s @EnableCaching
)
@EnableContinuousQueries
@EnableGemfireFunctionExecutions
@EnableGemfireFunctions
@EnableGemfireRepositories
@EnableLogging
@EnablePdx
@EnableSecurity
@EnableSsl
@EnableGemFireHttpSession
![]() | Note |
---|---|
This means you DO NOT need to explicitly declare any of these Annotations on your |
![]() | Tip |
---|---|
You should read the chapter in Spring Boot’s Reference Guide on Auto-configuration. |
![]() | Tip |
---|---|
You should review the chapter in Spring Data for Apache Geode and Pivotal GemFire’s (SDG) Reference Guide on Annotation-based Configuration. For a quick reference, or an overview of Annotation-based Configuration, see here. |
You might ask how I can customize the Auto-configuration provided by SBDG if I do not explicitly declare the annotation?
For example, you mat want to customize the member’s "name". You know that the
@ClientCacheApplication
annotation
provides the name
attribute
so you can set the client member’s "name". But SBDG has already implicitly declared the @ClientCacheApplication
annotation via Auto-configuration on your behalf. What do you do?
Well, SBDG supplies a few very useful Annotations in this case.
For example, to set the (client or peer) member’s name, you can use the @UseMemberName
annotation, like so:
Setting the member’s name using @UseMemberName
.
@SpringBootApplication @UseMemberName("MyMemberName") class SpringBootClientCacheApplication { ... }
Alternatively, you could set the spring.application.name
or the spring.data.gemfire.name
property in Spring Boot
application.properties
Setting the member’s name using the spring.application.name
property.
# Spring Boot application.properties spring.application.name = MyMemberName
Or:
Setting the member’s name using the spring.data.gemfire.cache.name
property.
# Spring Boot application.properties spring.data.gemfire.cache.name = MyMemberName
In general, there are 3 ways to customize configuration, even in the context of SBDG’s Auto-configuration:
@UseMemberName
, or enabling
durable clients with @EnableDurableClient
).
spring.application.name
, or spring.data.gemfire.name
, or spring.data.gemfire.cache.name
).
ClientCacheConfigurer
).
![]() | Tip |
---|---|
For the complete list of documented Properties, see here. |
Disabling Spring Boot Auto-configuration is explained in detail in Spring Boot’s Reference Guide.
Disabling SBDG Auto-confiugration was also explained in detail.
In a nutshell, if you want to disable any Auto-configuration provided by either Spring Boot or SBDG,
then you can declare your intent in the @SpringBootApplication
annotation, like so:
Disabling Specific Auto-configuration Classes.
@SpringBootApplication( exclude = { DataSourceAutoConfiguration.class, PdxAutoConfiguration.class } ) class SpringBootClientCacheApplication { ... }
![]() | Warning |
---|---|
Make sure you understand what you are doing when you are "disabling" Auto-configuration. |
Overriding SBDG Auto-configuration was explained in detail as well.
In a nutshell, if you want to override the default Auto-configuration provided by SBDG then you must annotate
your @SpringBootApplication
class with your intent.
For example, say you want to configure and bootstrap an Apache Geode or Pivotal GemFire CacheServer
application
(a peer; not a client), then you would:
Overriding the default ClientCache
Auto-Configuration by configuring & bootstrapping a CacheServer
application.
@SpringBootApplication @CacheServerApplication class SpringBootCacheServerApplication { ... }
Even when you explicitly declare the @ClientCacheApplication
annotation on your @SpringBootApplication
class,
like so:
Overriding by explicitly declaring @ClientCacheApplication
.
@SpringBootApplication @ClientCacheApplication class SpringBootClientCacheApplication { ... }
You are overriding SBDG’s Auto-configuration of the ClientCache
instance. As a result, you now have also implicitly
consented to being responsible for other aspects of the configuration (e.g. Security)! Why?
This is because in certain cases, like Security, certain aspects of Security configuration (e.g. SSL) must be configured before the cache instance is created. And, Spring Boot always applies user configuration before Auto-configuration partially to determine what needs to be auto-configured in the first place.
![]() | Warning |
---|---|
Especially make sure you understand what you are doing when you are "overriding" Auto-configuration. |
We will simply refer you to the Spring Boot Reference Guide on replacing Auto-configuration. See here.
This section covers the SBDG provided Auto-configuration classes corresponding to the SDG Annotations in more detail.
To review the complete list of SBDG Auto-confiugration classes, see here.
![]() | Note |
---|---|
The |
SBDG starts with the opinion that application developers will primarily be building Apache Geode or Pivotal GemFire client applications using Spring Boot.
Technically, this means building Spring Boot applications with either an Apache Geode or Pivotal GemFire ClientCache
instance connected to a dedicated cluster of Apache Geode or Pivotal GemFire servers that manage the data as part of a
client/server topology.
By way of example, this means you do not need to explicitly declare and annotate your @SpringBootApplication
class
with SDG’s @ClientCacheApplication
annotation, like so:
Do Not Do This.
@SpringBootApplication @ClientCacheApplication class SpringBootClientCacheApplication { ... }
This is because SBDG’s provided Auto-configuration class is already meta-annotated with SDG’s
@ClientCacheApplication
annotation. Therefore, you simply need:
Do This.
@SpringBootApplication class SpringBootClientCacheApplication { ... }
![]() | Tip |
---|---|
Refer to SDG’s Referene Guide for more details on Apache Geode or Pivotal GemFire cache applications, and client/server applications in particular. |
![]() | Note |
---|---|
The |
If you simply used the core Spring Framework to configure either Apache Geode or Pivotal GemFire as a caching provider in Spring’s Cache Abstraction, you would need to do this:
Configuring caching using the Spring Framework.
@SpringBootApplication @EnableCaching class CachingUsingApacheGeodeConfiguration { @Bean GemfireCacheManager cacheManager(GemFireCache cache) { GemfireCacheManager cacheManager = new GemfireCacheManager(); cacheManager.setCache(cache); return cacheManager; } }
If you were using Spring Data for Apache Geode’s @EnableGemfireCaching
annotation, then the above configuration
could be simplified to:
Configuring caching using Spring Data Geode.
@SpringBootApplication @EnableGemfireCaching class CachingUsingApacheGeodeConfiguration { }
And, if you use SBDG, then you only need to do this:
Configuring caching using Spring Data Geode.
@SpringBootApplication class CachingUsingApacheGeodeConfiguration { }
This allows you to focus on the areas in your application that would benefit from caching without having to enable the plumbing. Simply demarcate the service methods in your application that are good candidates for caching:
Using caching in your application.
@Service class CustomerService { @Caching("CustomersByName") Customer findBy(String name) { ... } }
![]() | Tip |
---|---|
Refer to the documentation for more details. |
![]() | Note |
---|---|
The |
Without having to enable anything, you simply annotate your application (POJO) component method(s) with the SDG
@ContinuousQuery
annotation to register a CQ and start receiving events. The method acts as a CqEvent
handler, or in Apache Geode and
Pivotal GemFire’s case, the method would be an implementation of
CqListener
.
Declare application CQs.
@Component class MyCustomerApplicationContinuousQueries @ContinuousQuery("SELECT customer.* FROM /Customers customers" + " WHERE customer.getSentiment().name().equalsIgnoreCase('UNHAPPY')") public void handleUnhappyCustomers(CqEvent event) { ... } }
As shown above, you define the events you are interested in receiving by using a OQL query with a finely tuned query predicate describing the events of interests and implement the handler method to process the events (e.g. apply a credit to the customer’s account and follow up in email).
![]() | Tip |
---|---|
Refer to the documentation for more details. |
![]() | Note |
---|---|
The |
Whether you need to execute a Function
or implement a Function
, SBDG will detect the Function
definition and auto-configure it appropriately for use in your Spring Boot application. You only need to define
the Function execution or implementation in a package below the main @SpringBootApplication
class.
Declare a Function Execution.
package example.app.functions; @OnRegion("Accounts") interface MyCustomerApplicationFunctions { void applyCredit(Customer customer); }
Then you can inject the Function execution into any application component and use it:
Use the Function.
package example.app.service; @Service interface CustomerService { @Autowired private MyCustomerapplicationFunctions customerFunctions; public void analyzeCustomerSentiment(Customer customer) { ... this.customerFunctions.applyCredit(customer); ... } }
The same pattern basically applies to Function implementations, except in the implementation case, SBDG "registers" the Function implementation for use (i.e. to be called by a Function execution).
The point is, you are simply focusing on defining the logic required by your application, and not worrying about how Functions are registered, called, etc. SBDG is handling this concern for you!
![]() | Note |
---|---|
Function implementations are typically defined and registered on the server-side. |
![]() | Tip |
---|---|
Refer to the documentation for more details. |
![]() | Note |
---|---|
The |
Like Functions, you are only concerned with the data access operations (e.g. basic CRUD and simple Queries) required by
your application to carry out its functions, not how to create and perform them (e.g. Region.get(key)
& Region.put(key, obj)
) or execute (e.g. Query.execute(arguments)
).
Simply define your Spring Data Repository:
Define an application-specific Repository.
package example.app.repo; interface CustomerRepository extends CrudRepository<Customer, Long> { List<Customer> findBySentimentEqualTo(Sentiment sentiment); }
And use it:
Using the application-specific Repository.
package example.app.sevice; @Service class CustomerService { @Autowired private CustomerRepository repository; public void processCustomersWithSentiment(Sentiment sentiment) { this.repository.findBySentimentEqualTo(sentiment).forEach(customer -> { ... }); ... } }
Your application-specific Repository simply needs to be declared in a package below the main @SpringBootApplication
class. Again, you are only focusing on the data access operations and queries required to carry out the functions
of your application, nothing more.
![]() | Tip |
---|---|
Refer to the documentation for more details. |
![]() | Note |
---|---|
The |
Logging is an essential application concern to understand what is happening in the system along with when and where the event occurred. As such, SBDG auto-configures logging for Apache Geode and Pivotal GemFire by default, using the default log-level, "config".
If you wish to change an aspect of logging, such as the log-level, you would typically do this in Spring Boot
application.properties
:
Change the log-level for Apache Geode.
# Spring Boot application.properites. spring.data.gemfire.cache.log-level=debug
Other aspects may be configured as well, such as the log file size and disk space limits for the file system location used to store the Apache Geode log files at runtime.
Under-the-hood, Apache Geode’s logging is based on Log4j. Therefore, you can configure Apache Geode logging using
any logging provider (e.g. Logback) and configuration metadata appropriate for that logging provider so long as you
supply the necessary adapter between Log4j and whatever logging system you are using. For instance, if you include
org.springframework.boot:spring-boot-starter-logging
then you will be using Logback and you will need the
org.apache.logging.log4j:log4j-to-slf4j
adapter.
![]() | Note |
---|---|
The |
Anytime you need to send an object over the network, overflow or persist an object to disk, then your application domain
object must be serializable. It would be painful to have to implement java.io.Serializable
in everyone of your
application domain objects (e.g. Customer
) that would potentially need to be serialized.
Furthermore, using Java Serialization may not be ideal (e.g. the most portable or efficient) in all cases, or even possible in other cases (e.g. when you are using a 3rd party library for which you have no control over).
In these situations, you need to be able to send your object anywhere without unduly requiring the class type to be serializable as well as to exist on the classpath for every place it is sent. Indeed, the final destination may not even be a Java application! This is where Apache Geode PDX Serialization steps into help.
However, you don’t have to figure out how to configure PDX to identify the application class types that will need to be serialized. You simply define your class type:
Customer class.
@Region("Customers") class Customer { @Id private Long id; @Indexed private String name; ... }
And, SBDG’s Auto-configuration will handle the rest!
![]() | Tip |
---|---|
Refer to the documentation for more details. |
![]() | Note |
---|---|
The |
Configuring your Spring Boot, Apache Geode ClientCache
application to properly authenticate with a cluster of secure
Apache Geode or Pivotal GemFire servers is as simple as setting a username and password in Spring Boot
application.properties
:
Supplying Authentication Credentials.
# Spring Boot application.properties spring.data.gemfire.security.username=Batman spring.data.gemfire.security.password=r0b!n5ucks
![]() | Note |
---|---|
Authentication is even easier to configure in a managed environment like PCF when using PCC; you don’t have to do anything! |
Authorization is configured on the server-side and is made simple with SBDG and the help of Apache Shiro. Of course, this assumes you are using SBDG to configure and bootstrap your Apache Geode cluster in the first place, which is possible, and made even easier with SBDG.
![]() | Tip |
---|---|
Refer to the documentation for more details. |
![]() | Note |
---|---|
The |
Configuring SSL for secure transport (TLS) between your Spring Boot, Apache Geode ClientCache
application
and the cluster can be a real problematic task, especially to get correct from the start. So, it is something
that SBDG makes simple to do out-of-the-box.
Simply supply a trusted.keystore
file containing the certificates in a well-known location (e.g. root of your
application classpath) and SBDG’s Auto-configuration will kick in and handle of the rest.
This is useful during development, but we highly recommend using a more secure procedure (e.g. integrating with a secure credential store like LDAP, CredHub or Vault) when deploying your Spring Boot application to production.
![]() | Tip |
---|---|
Refer to the documentation for more details. |
![]() | Note |
---|---|
The |
Configuring Apache Geode or Pivotal GemFire to serve as the (HTTP) Session state caching provider using Spring Session
is as simple as including the correct starter, e.g. spring-geode-starter-session
.
Using Spring Session.
<dependency> <groupId>org.springframework.geode</groupId> <artifactId>spring-geode-starter-session</artifactId> <version>1.3.0.M2</version> </dependency>
With Spring Session, and specifically Spring Session for Apache Geode or Pivotal GemFire (SSDG), on the classpath of
your Spring Boot, Apache Geode ClientCache
Web application, you can manage your (HTTP) Session state with either
Apache Geode or Pivotal GemFire. No further configuration is needed. SBDG Auto-configuration detects Spring Session
on the application classpath and does the right thing.
![]() | Tip |
---|---|
Refer to the documentation for more details. |
The SBDG RegionTemplateAutoConfiguration
class
has no corresponding SDG Annotation. However, the Auto-configuration of a GemfireTemplate
for every single
Apache Geode Region
defined and declared in your Spring Boot application is supplied by SBDG never-the-less.
For example, if you defined a Region using:
Region definition using JavaConfig.
@Configuration class GeodeConfiguration { @Bean("Customers") ClientRegionFactoryBean<Long, Customer> customersRegion(GemFireCache cache) { ClientRegionFactoryBean<Long, Customer> customersRegion = new ClientRegionFactoryBean<>(); customersRegion.setCache(cache); customersRegion.setShortcut(ClientRegionShortcut.PROXY); return customersRegion; } }
Alternatively, you could define the "Customers" Region using:
Region definition using @EnableEntityDefinedRegions
.
@Configuration @EnableEntityDefinedRegion(basePackageClasses = Customer.class) class GeodeConfiguration { }
Then, SBDG will supply a GemfireTemplate
instance that you can use to perform low-level, data access operations
(indirectly) on the "Customers" Region:
Use the GemfireTemplate
to access the "Customers" Region.
@Repository class CustomersDao { @Autowired @Qualifier("customersTemplate") private GemfireTemplate customersTemplate; Customer findById(Long id) { return this.customerTemplate.get(id); } }
You do not need to explicitly configure GemfireTemplates
for each Region you need to have low-level data access to
(e.g. such as when you are not using the Spring Data Repository abstraction).
Be careful to "qualify" the GemfireTemplate
for the Region you need data access to, especially given that you will
probably have more than 1 Region defined in your Spring Boot application.
![]() | Tip |
---|---|
Refer to the documentation for more details. |