Add Sample Code for Near Caching.

This commit is contained in:
John Blum
2019-08-12 18:12:45 -07:00
parent 9df9f0fe80
commit 0acf8c85cb
15 changed files with 805 additions and 0 deletions

View File

@@ -0,0 +1,36 @@
plugins {
id "io.freefair.lombok" version "3.2.1"
}
apply plugin: 'io.spring.convention.spring-sample-boot'
description = "Spring Geode Sample demonstrating Spring's Cache Abstraction using Apache Geode as the caching provider with Near Caching."
dependencies {
compile project(":spring-geode-starter")
compile project(":apache-geode-extensions")
compile ("org.springframework.boot:spring-boot-starter-web") {
exclude group: "org.apache.logging.log4j", module: "log4j-to-slf4j"
}
compile "org.assertj:assertj-core"
compile "org.projectlombok:lombok"
runtime "javax.cache:cache-api"
runtime "org.springframework.boot:spring-boot-starter-jetty"
runtime "org.springframework.shell:spring-shell"
testCompile "org.springframework.boot:spring-boot-starter-test"
testCompile("org.springframework.data:spring-data-geode-test") {
exclude group: "org.apache.logging.log4j", module: "log4j-core"
}
}
bootJar {
mainClassName = 'example.app.caching.near.BootGeodeNearCachingClientCacheApplication'
}

View File

@@ -0,0 +1,70 @@
/*
* Copyright 2019 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* https://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
* or implied. See the License for the specific language governing
* permissions and limitations under the License.
*/
package example.app.near.caching.client;
import static org.assertj.core.api.Assertions.assertThat;
import org.apache.geode.cache.DataPolicy;
import org.apache.geode.cache.Region;
import org.apache.geode.cache.client.Pool;
import org.apache.geode.cache.client.PoolManager;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.boot.ApplicationRunner;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.annotation.Bean;
/**
* Spring Boot application demonstrating Spring's Cache Abstraction with Apache Geode as the caching provider
* for {@literal Near Caching}.
*
* @author John Blum
* @see org.springframework.boot.SpringApplication
* @see org.springframework.boot.autoconfigure.SpringBootApplication
* @since 1.1.0
*/
// tag::class[]
@SpringBootApplication
public class BootGeodeNearCachingClientCacheApplication {
public static void main(String[] args) {
SpringApplication.run(BootGeodeNearCachingClientCacheApplication.class, args);
}
// tag::application-runner[]
@Bean
public ApplicationRunner runner(@Qualifier("YellowPages") Region<?, ?> yellowPages) {
return args -> {
assertThat(yellowPages).isNotNull();
assertThat(yellowPages.getName()).isEqualTo("YellowPages");
assertThat(yellowPages.getInterestListRegex()).containsAnyOf(".*");
assertThat(yellowPages.getAttributes()).isNotNull();
assertThat(yellowPages.getAttributes().getDataPolicy()).isEqualTo(DataPolicy.NORMAL);
assertThat(yellowPages.getAttributes().getPoolName()).isEqualTo("DEFAULT");
Pool defaultPool = PoolManager.find("DEFAULT");
assertThat(defaultPool).isNotNull();
assertThat(defaultPool.getSubscriptionEnabled()).isTrue();
};
}
// end::application-runner[]
}
// end::class[]

View File

@@ -0,0 +1,120 @@
/*
* Copyright 2019 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* https://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
* or implied. See the License for the specific language governing
* permissions and limitations under the License.
*/
package example.app.near.caching.client.config;
import org.apache.geode.cache.CacheListener;
import org.apache.geode.cache.EntryEvent;
import org.apache.geode.cache.GemFireCache;
import org.apache.geode.cache.InterestResultPolicy;
import org.apache.geode.cache.Region;
import org.apache.geode.cache.client.ClientRegionShortcut;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.data.gemfire.client.ClientRegionFactoryBean;
import org.springframework.data.gemfire.client.Interest;
import org.springframework.data.gemfire.client.RegexInterest;
import org.springframework.data.gemfire.config.annotation.RegionConfigurer;
import org.springframework.data.gemfire.util.ArrayUtils;
import org.springframework.geode.cache.AbstractCommonEventProcessingCacheListener;
/**
* Spring {@link Configuration} class to configure Apache Geode client {@link Region Regions}
* with interest registration on all keys.
*
* @author John Blum
* @see org.apache.geode.cache.Region
* @see org.springframework.context.annotation.Configuration
* @see org.springframework.data.gemfire.client.ClientRegionFactoryBean
* @see org.springframework.data.gemfire.client.Interest
* @see org.springframework.data.gemfire.config.annotation.EnableCachingDefinedRegions
* @see org.springframework.data.gemfire.config.annotation.RegionConfigurer
* @since 1.1.0
*/
// tag::class[]
@Configuration
//@EnableCachingDefinedRegions(clientRegionShortcut = ClientRegionShortcut.CACHING_PROXY)
public class GeodeConfiguration {
// TODO: Replace with the SDG `@EnableCachingDefineRegions annotation declared above (and currently commented out,
// because...) once DATAGEODE-219 is resolved. :(
// tag::region[]
@Bean("YellowPages")
public ClientRegionFactoryBean<Object, Object> yellowPagesRegion(GemFireCache gemfireCache) {
ClientRegionFactoryBean<Object, Object> clientRegion = new ClientRegionFactoryBean<>();
clientRegion.setCache(gemfireCache);
clientRegion.setClose(false);
clientRegion.setShortcut(ClientRegionShortcut.CACHING_PROXY);
clientRegion.setRegionConfigurers(
interestRegisteringRegionConfigurer(),
subscriptionCacheListenerRegionConfigurer()
);
return clientRegion;
}
// end::region[]
// tag::interest-registration[]
@Bean
RegionConfigurer interestRegisteringRegionConfigurer() {
return new RegionConfigurer() {
@Override
@SuppressWarnings("unchecked")
public void configure(String beanName, ClientRegionFactoryBean<?, ?> clientRegion) {
Interest interest = new RegexInterest(".*", InterestResultPolicy.NONE,
false, true);
clientRegion.setInterests(ArrayUtils.asArray(interest));
}
};
}
// end::interest-registration[]
// tag::subscription-cache-listener[]
@Bean
RegionConfigurer subscriptionCacheListenerRegionConfigurer() {
return new RegionConfigurer() {
@Override
@SuppressWarnings("unchecked")
public void configure(String beanName, ClientRegionFactoryBean<?, ?> clientRegion) {
CacheListener subscriptionCacheListener = new AbstractCommonEventProcessingCacheListener() {
@Override
protected void processEntryEvent(EntryEvent event, EntryEventType eventType) {
if (event.isOriginRemote()) {
System.err.printf("[%1$s] EntryEvent for [%2$s] with value [%3$s]%n",
event.getKey(), event.getOperation(), event.getNewValue());
}
}
};
clientRegion.setCacheListeners(ArrayUtils.asArray(subscriptionCacheListener));
}
};
}
// end::subscription-cache-listener[]
}
// end::class[]

View File

@@ -0,0 +1,90 @@
/*
* Copyright 2019 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* https://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
* or implied. See the License for the specific language governing
* permissions and limitations under the License.
*/
package example.app.near.caching.client.controller;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
import example.app.near.caching.client.model.Person;
import example.app.near.caching.client.service.YellowPagesService;
/**
* Spring {@link RestController} class for implementing the UI to the Yellow Pages application.
*
* @author John Blum
* @see org.springframework.web.bind.annotation.GetMapping
* @see org.springframework.web.bind.annotation.RestController
* @see example.app.near.caching.client.model.Person
* @see example.app.near.caching.client.service.YellowPagesService
* @since 1.1.0
*/
// tag::class[]
@RestController
public class YellowPagesController {
private static final String HTML =
"<html><title>Yellow Pages</title><body bgcolor=\"#F5FC1D\" text=\"black\"><h1>%s</h1><body><html>";
@Autowired
private YellowPagesService yellowPages;
@GetMapping("/")
public String home() {
return format("Near Caching Example");
}
@GetMapping("/ping")
public String ping() {
return format("PONG");
}
@GetMapping("/yellow-pages/{name}")
public String find(@PathVariable("name") String name) {
long t0 = System.currentTimeMillis();
Person person = this.yellowPages.find(name);
return format(String.format("{ person: %s, cacheMiss: %s, latency: %d ms }",
person, this.yellowPages.isCacheMiss(), (System.currentTimeMillis() - t0)));
}
@GetMapping("/yellow-pages/{name}/update")
public String update(@PathVariable("name") String name,
@RequestParam(name = "email", required = false) String email,
@RequestParam(name = "phoneNumber", required = false) String phoneNumber) {
Person person = this.yellowPages.save(this.yellowPages.find(name), email, phoneNumber);
return format(String.format("{ person: %s }", person));
}
@GetMapping("/yellow-pages/{name}/evict")
public String evict(@PathVariable("name") String name) {
this.yellowPages.evict(name);
return format(String.format("Evicted %s", name));
}
private String format(String value) {
return String.format(HTML, value);
}
}
// end::class[]

View File

@@ -0,0 +1,53 @@
/*
* Copyright 2019 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* https://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
* or implied. See the License for the specific language governing
* permissions and limitations under the License.
*/
package example.app.near.caching.client.model;
import lombok.EqualsAndHashCode;
import lombok.Getter;
import lombok.NonNull;
import lombok.RequiredArgsConstructor;
import lombok.ToString;
/**
* {@link Person} models a person (human being).
*
* @author John Blum
* @since 1.1.0
*/
// tag::class[]
@Getter
@EqualsAndHashCode(of = "name")
@ToString(of = { "name", "email", "phoneNumber" })
@RequiredArgsConstructor(staticName = "newPerson")
public class Person {
@NonNull
private String name;
private String email;
private String phoneNumber;
public Person withEmail(String email) {
this.email = email;
return this;
}
public Person withPhoneNumber(String phoneNumber) {
this.phoneNumber = phoneNumber;
return this;
}
}
// end::class[]

View File

@@ -0,0 +1,78 @@
/*
* Copyright 2019 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* https://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
* or implied. See the License for the specific language governing
* permissions and limitations under the License.
*/
package example.app.near.caching.client.service;
import org.springframework.cache.annotation.CacheEvict;
import org.springframework.cache.annotation.CachePut;
import org.springframework.cache.annotation.Cacheable;
import org.springframework.stereotype.Service;
import org.springframework.util.StringUtils;
import example.app.near.caching.client.model.Person;
import example.app.near.caching.client.service.support.AbstractCacheableService;
import example.app.near.caching.client.service.support.EmailGenerator;
import example.app.near.caching.client.service.support.PhoneNumberGenerator;
/**
* Spring {@link Service} class implementing the Yellow Pages.
*
* @author John Blum
* @see org.springframework.cache.annotation.Cacheable
* @see org.springframework.stereotype.Service
* @see example.app.near.caching.client.model.Person
* @see example.app.near.caching.client.service.support.AbstractCacheableService
* @see example.app.near.caching.client.service.support.EmailGenerator
* @see example.app.near.caching.client.service.support.PhoneNumberGenerator
* @since 1.1.0
*/
// tag::class[]
@Service
public class YellowPagesService extends AbstractCacheableService {
@Cacheable(cacheNames = "YellowPages", key = "#name")
public Person find(String name) {
this.cacheMiss.set(true);
Person person = Person.newPerson(name)
.withEmail(EmailGenerator.generate(name, null))
.withPhoneNumber(PhoneNumberGenerator.generate(null));
simulateLatency();
return person;
}
@CachePut(cacheNames = "YellowPages", key = "#person.name")
public Person save(Person person, String email, String phoneNumber) {
if (StringUtils.hasText(email)) {
person.withEmail(email);
}
if (StringUtils.hasText(phoneNumber)) {
person.withPhoneNumber(phoneNumber);
}
return person;
}
@CacheEvict(cacheNames = "YellowPages")
public boolean evict(String name) {
return true;
}
}
// end::class[]

View File

@@ -0,0 +1,71 @@
/*
* Copyright 2019 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* https://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
* or implied. See the License for the specific language governing
* permissions and limitations under the License.
*/
package example.app.near.caching.client.service.support;
import java.util.Random;
import java.util.concurrent.atomic.AtomicBoolean;
import org.springframework.stereotype.Service;
/**
* Abstract base class for implementing cacheable {@link Service services} along with additional functionality to
* ascertain whether a cacheable operation led to a cache hit or a cache miss.
*
* @author John Blum
* @since 1.1.0
*/
@SuppressWarnings("unused")
// tag::class[]
public abstract class AbstractCacheableService {
protected static final int BOUNDED_MULTIPLIER = 3;
protected static final long BASE_MILLISECONDS = 2000L;
protected static final long ONE_SECOND_IN_MILLISECONDS = 1000L;
protected final AtomicBoolean cacheMiss = new AtomicBoolean(false);
protected final Random multiplier = new Random(System.currentTimeMillis());
public boolean isCacheHit() {
return !isCacheMiss();
}
public boolean isCacheMiss() {
return this.cacheMiss.compareAndSet(true,false);
}
protected long delayInMilliseconds() {
return BASE_MILLISECONDS + (ONE_SECOND_IN_MILLISECONDS * this.multiplier.nextInt(BOUNDED_MULTIPLIER));
}
protected boolean simulateLatency() {
return simulateLatency(delayInMilliseconds());
}
protected boolean simulateLatency(long milliseconds) {
try {
Thread.sleep(milliseconds);
return true;
}
catch (InterruptedException ignore) {
Thread.currentThread().interrupt();
return false;
}
}
}
// end::class[]

View File

@@ -0,0 +1,71 @@
/*
* Copyright 2019 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* https://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
* or implied. See the License for the specific language governing
* permissions and limitations under the License.
*/
package example.app.near.caching.client.service.support;
import java.util.Arrays;
import java.util.List;
import java.util.Random;
import org.springframework.util.Assert;
import org.springframework.util.StringUtils;
/**
* Generates {@link String email addresses} given a person's {@link String name}.
*
* @author John Blum
* @since 1.1.0
*/
// tag::class[]
public class EmailGenerator {
private static final String AT_APPLE_COM = "@apple.com";
private static final String AT_COMCAST_NET = "@comcast.net";
private static final String AT_GMAIL_COM = "@gmail.com";
private static final String AT_HOME_ORG = "@home.org";
private static final String AT_MICROSOFT_COM = "@microsoft.com";
private static final String AT_NASA_GOV = "@nasa.gov";
private static final String AT_PIVOTAL_IO = "@pivotal.io";
private static final String AT_YAHOO_COM = "@yahoo.com";
private static final List<String> AT_EMAIL_ADDRESSES = Arrays.asList(
AT_APPLE_COM,
AT_COMCAST_NET,
AT_GMAIL_COM,
AT_HOME_ORG,
AT_MICROSOFT_COM,
AT_NASA_GOV,
AT_PIVOTAL_IO,
AT_YAHOO_COM
);
private static final Random index = new Random(System.currentTimeMillis());
public static String generate(String name, String email) {
Assert.hasText(name, "Name is required");
if (!StringUtils.hasText(email)) {
name = name.toLowerCase();
name = StringUtils.trimAllWhitespace(name);
email = String.format("%1$s%2$s", name,
AT_EMAIL_ADDRESSES.get(index.nextInt(AT_EMAIL_ADDRESSES.size())));
}
return email;
}
}
// end::class[]

View File

@@ -0,0 +1,72 @@
/*
* Copyright 2019 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* https://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
* or implied. See the License for the specific language governing
* permissions and limitations under the License.
*/
package example.app.near.caching.client.service.support;
import java.util.Arrays;
import java.util.List;
import java.util.Random;
import org.apache.shiro.util.StringUtils;
/**
* Generates random phone number using a few well-defined area codes.
*
* @author John Blum
* @since 1.1.0
*/
// tag::class[]
public class PhoneNumberGenerator {
private static int CALIFORNIA_AREA_CODE = 707;
private static int IOWA_AREA_CODE = 319;
private static int MONTANA_AREA_CODE = 406;
private static int NEW_YORK_AREA_CODE = 914;
private static int OREGON_AREA_CODE = 503;
private static int WASHINGTON_AREA_CODE = 206;
private static int WISCONSIN_AREA_CODE = 608;
private static final List<Integer> PHONE_NUMBER_AREA_CODES = Arrays.asList(
CALIFORNIA_AREA_CODE,
IOWA_AREA_CODE,
MONTANA_AREA_CODE,
NEW_YORK_AREA_CODE,
OREGON_AREA_CODE,
WASHINGTON_AREA_CODE,
WISCONSIN_AREA_CODE
);
private static final Random index = new Random(System.currentTimeMillis());
public static String generate(String phoneNumber) {
if (!StringUtils.hasText(phoneNumber)) {
phoneNumber = String.valueOf(PHONE_NUMBER_AREA_CODES.get(index.nextInt(PHONE_NUMBER_AREA_CODES.size())))
.concat("-")
.concat(String.valueOf(index.nextInt(9)))
.concat(String.valueOf(index.nextInt(9)))
.concat(String.valueOf(index.nextInt(9)))
.concat("-")
.concat(String.valueOf(index.nextInt(9)))
.concat(String.valueOf(index.nextInt(9)))
.concat(String.valueOf(index.nextInt(9)))
.concat(String.valueOf(index.nextInt(9)));
}
return phoneNumber;
}
}
// end::class[]

View File

@@ -0,0 +1,126 @@
/*
* Copyright 2019 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* https://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
* or implied. See the License for the specific language governing
* permissions and limitations under the License.
*/
package example.app.near.caching.server;
import static org.assertj.core.api.Assertions.assertThat;
import org.apache.geode.cache.DataPolicy;
import org.apache.geode.cache.GemFireCache;
import org.apache.geode.cache.Region;
import org.apache.geode.cache.RegionAttributes;
import org.apache.geode.cache.server.CacheServer;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.boot.ApplicationRunner;
import org.springframework.boot.WebApplicationType;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.builder.SpringApplicationBuilder;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Profile;
import org.springframework.data.gemfire.RegionAttributesFactoryBean;
import org.springframework.data.gemfire.ReplicatedRegionFactoryBean;
import org.springframework.data.gemfire.config.annotation.CacheServerApplication;
import org.springframework.data.gemfire.config.annotation.EnableLocator;
import org.springframework.data.gemfire.config.annotation.EnableManager;
import example.app.near.caching.client.model.Person;
/**
* Spring Boot application that configures and bootstraps an Apache Geode {@link CacheServer} application.
*
* @author John Blum
* @see org.apache.geode.cache.GemFireCache
* @see org.apache.geode.cache.server.CacheServer
* @see org.springframework.boot.autoconfigure.SpringBootApplication
* @see org.springframework.boot.builder.SpringApplicationBuilder
* @see org.springframework.data.gemfire.config.annotation.CacheServerApplication
* @see org.springframework.data.gemfire.config.annotation.EnableLocator
* @see org.springframework.data.gemfire.config.annotation.EnableManager
* @since 1.1.0
*/
// tag::class[]
@SpringBootApplication
@CacheServerApplication
@SuppressWarnings("unused")
public class BootGeodeNearCachingCacheServerApplication {
public static void main(String[] args) {
new SpringApplicationBuilder(BootGeodeNearCachingCacheServerApplication.class)
.web(WebApplicationType.NONE)
.build()
.run(args);
}
// tag::application-runner[]
@Bean
ApplicationRunner runner(@Qualifier("YellowPages") Region<String, Person> yellowPagesRegion) {
return args -> {
assertThat(yellowPagesRegion).isNotNull();
assertThat(yellowPagesRegion.getName()).isEqualTo("YellowPages");
assertThat(yellowPagesRegion.getAttributes()).isNotNull();
assertThat(yellowPagesRegion.getAttributes().getDataPolicy()).isEqualTo(DataPolicy.REPLICATE);
assertThat(yellowPagesRegion.getAttributes().getEnableSubscriptionConflation()).isTrue();
};
}
// end::application-runner[]
// tag::geode-configuration[]
@Configuration
static class GeodeConfiguration {
@Bean("YellowPages")
public ReplicatedRegionFactoryBean<Object, Object> yellowPagesRegion(GemFireCache gemfireCache,
@Qualifier("YellowPagesAttributes") RegionAttributes<Object, Object> exampleAttributes) {
ReplicatedRegionFactoryBean<Object, Object> yellowPagesRegion =
new ReplicatedRegionFactoryBean<>();
yellowPagesRegion.setAttributes(exampleAttributes);
yellowPagesRegion.setCache(gemfireCache);
yellowPagesRegion.setClose(false);
yellowPagesRegion.setPersistent(false);
return yellowPagesRegion;
}
@Bean("YellowPagesAttributes")
public RegionAttributesFactoryBean<Object, Object> exampleRegionAttributes() {
RegionAttributesFactoryBean<Object, Object> yellowPagesRegionAttributes =
new RegionAttributesFactoryBean<>();
yellowPagesRegionAttributes.setEnableSubscriptionConflation(true);
return yellowPagesRegionAttributes;
}
}
// end::geode-configuration[]
// tag::locator-manager[]
@Configuration
@EnableLocator
@EnableManager(start = true)
@Profile("locator-manager")
static class LocatorManagerConfiguration { }
// end::locator-manager[]
}
// end::class[]

View File

@@ -0,0 +1,4 @@
# Spring Boot application.properties for the Apache Geode ClientCache One application.
server.port=8181
spring.application.name=ClientApplicationOne

View File

@@ -0,0 +1,4 @@
# Spring Boot application.properties for the Apache Geode ClientCache Two application.
server.port=8282
spring.application.name=ClientApplicationTwo

View File

@@ -0,0 +1,4 @@
# Spring Boot application.properties for the Apache Geode ClientCache application
spring.application.name=ClientApplication
spring.data.gemfire.pool.subscription-enabled=true

View File

@@ -0,0 +1,3 @@
# Spring Boot application.properties for the Apache Geode CacheServer application.
spring.application.name=YellowPagesServer

View File

@@ -0,0 +1,3 @@
# Spring Boot application.properties for both the Apache Geode ClientCache and CacheServer applications.
spring.data.gemfire.cache.log-level=config