#539 - Polishing.

Add author tags. Simplify dependency setup. Replace logger declarations with Lombok's CommonsLog. Simplify test annotations.

Disable WAN module as the WAN server does not stop after running tests. Reformat code.
This commit is contained in:
Mark Paluch
2020-02-27 10:21:46 +01:00
parent fa0021cffb
commit 54f7146e0f
121 changed files with 1160 additions and 1092 deletions

View File

@@ -2,16 +2,14 @@
<project xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns="http://maven.apache.org/POM/4.0.0"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<parent>
<groupId>example.springdata.geode</groupId>
<artifactId>spring-data-geode-examples</artifactId>
<version>1.0-SNAPSHOT</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<artifactId>events</artifactId>
<modelVersion>4.0.0</modelVersion>
<dependencies>
<parent>
<groupId>org.springframework.data.examples</groupId>
<artifactId>spring-data-geode-examples</artifactId>
<version>2.0.0.BUILD-SNAPSHOT</version>
</parent>
</dependencies>
<artifactId>events</artifactId>
</project>
</project>

View File

@@ -13,7 +13,6 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package example.springdata.geode.server.events;
import lombok.Data;
@@ -29,6 +28,7 @@ import java.io.Serializable;
*/
@Data
public class Address implements Serializable {
private String street;
private String city;
private String country;

View File

@@ -13,7 +13,6 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package example.springdata.geode.server.events;
import lombok.Data;
@@ -48,4 +47,4 @@ public class Customer implements Serializable {
this.lastName = lastName;
this.addresses = Arrays.asList(addresses);
}
}
}

View File

@@ -13,7 +13,6 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package example.springdata.geode.server.events;
import org.apache.geode.cache.CacheWriterException;
@@ -22,6 +21,9 @@ import org.apache.geode.cache.util.CacheWriterAdapter;
import org.apache.geode.internal.cache.EntryEventImpl;
import org.springframework.stereotype.Component;
/**
* @author Patrick Johnson
*/
@Component
public class CustomerCacheWriter extends CacheWriterAdapter<Long, Customer> {

View File

@@ -13,10 +13,12 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package example.springdata.geode.server.events;
import org.springframework.data.repository.CrudRepository;
/**
* @author Patrick Johnson
*/
public interface CustomerRepository extends CrudRepository<Customer, Long> {
}

View File

@@ -13,7 +13,6 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package example.springdata.geode.server.events;
import lombok.Data;
@@ -28,10 +27,11 @@ import java.io.Serializable;
*/
@Data
public class EmailAddress implements Serializable {
private String value;
public EmailAddress(String value) {
this.value = value;
}
}
}

View File

@@ -13,40 +13,41 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package example.springdata.geode.server.events;
import org.apache.geode.cache.Region;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
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 java.math.BigDecimal;
import java.util.List;
import java.util.Random;
import java.util.stream.IntStream;
import java.util.stream.LongStream;
@SpringBootApplication(scanBasePackageClasses = EventServerConfig.class)
import lombok.extern.apachecommons.CommonsLog;
import org.apache.geode.cache.Region;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
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;
/**
* @author Patrick Johnson
*/
@SpringBootApplication
@CommonsLog
public class EventServer {
private Logger logger = LoggerFactory.getLogger(this.getClass());
public static void main(String[] args) {
new SpringApplicationBuilder(EventServer.class)
.web(WebApplicationType.NONE)
.build()
.run(args);
new SpringApplicationBuilder(EventServer.class).web(WebApplicationType.NONE).build().run(args);
}
@Bean
public ApplicationRunner runner(CustomerRepository customerRepository, OrderRepository orderRepository,
ProductRepository productRepository, OrderProductSummaryRepository orderProductSummaryRepository, @Qualifier("Products") Region<Long, Product> products) {
ProductRepository productRepository, OrderProductSummaryRepository orderProductSummaryRepository,
@Qualifier("Products") Region<Long, Product> products) {
return args -> {
createCustomerData(customerRepository);
@@ -54,43 +55,37 @@ public class EventServer {
createOrders(productRepository, orderRepository);
logger.info("Completed creating orders ");
log.info("Completed creating orders ");
final List<OrderProductSummary> allForProductID = orderProductSummaryRepository.findAllForProductID(3L);
allForProductID.forEach(orderProductSummary -> logger.info("orderProductSummary = " + orderProductSummary));
List<OrderProductSummary> allForProductID = orderProductSummaryRepository.findAllForProductID(3L);
allForProductID.forEach(orderProductSummary -> log.info("orderProductSummary = " + orderProductSummary));
};
}
private void createOrders(ProductRepository productRepository, OrderRepository orderRepository) {
Random random = new Random(System.nanoTime());
Address address = new Address("it", "doesn't", "matter");
LongStream.rangeClosed(1, 10).forEach((orderId) ->
LongStream.rangeClosed(1, 300).forEach((customerId) -> {
Order order = new Order(orderId, customerId, address);
IntStream.rangeClosed(0, random.nextInt(3) + 1).forEach((lineItemCount) -> {
int quantity = random.nextInt(3) + 1;
long productId = random.nextInt(3) + 1;
order.add(new LineItem(productRepository.findById(productId).get(), quantity));
});
orderRepository.save(order);
}));
LongStream.rangeClosed(1, 10).forEach((orderId) -> LongStream.rangeClosed(1, 300).forEach((customerId) -> {
Order order = new Order(orderId, customerId, address);
IntStream.rangeClosed(0, random.nextInt(3) + 1).forEach((lineItemCount) -> {
int quantity = random.nextInt(3) + 1;
long productId = random.nextInt(3) + 1;
order.add(new LineItem(productRepository.findById(productId).get(), quantity));
});
orderRepository.save(order);
}));
}
private void createProducts(ProductRepository productRepository) {
productRepository.save(new Product(1L, "Apple iPod", new BigDecimal("99.99"),
"An Apple portable music player"));
productRepository.save(new Product(2L, "Apple iPad", new BigDecimal("499.99"),
"An Apple tablet device"));
Product macbook = new Product(3L, "Apple macBook", new BigDecimal("899.99"),
"An Apple notebook computer");
productRepository.save(new Product(1L, "Apple iPod", new BigDecimal("99.99"), "An Apple portable music player"));
productRepository.save(new Product(2L, "Apple iPad", new BigDecimal("499.99"), "An Apple tablet device"));
Product macbook = new Product(3L, "Apple macBook", new BigDecimal("899.99"), "An Apple notebook computer");
macbook.addAttribute("warranty", "included");
productRepository.save(macbook);
}
private void createCustomerData(CustomerRepository customerRepository) {
LongStream.rangeClosed(0, 300)
.parallel()
.forEach(customerId ->
customerRepository.save(new Customer(customerId, new EmailAddress(customerId + "@2.com"), "John" + customerId, "Smith" + customerId)));
LongStream.rangeClosed(0, 300).parallel().forEach(customerId -> customerRepository.save(
new Customer(customerId, new EmailAddress(customerId + "@2.com"), "John" + customerId, "Smith" + customerId)));
}
}
}

View File

@@ -13,7 +13,6 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package example.springdata.geode.server.events;
import org.apache.geode.cache.Cache;
@@ -48,7 +47,7 @@ public class EventServerConfig {
@Bean
AsyncEventQueueFactoryBean orderAsyncEventQueue(GemFireCache gemFireCache, AsyncEventListener orderAsyncEventListener) {
final AsyncEventQueueFactoryBean asyncEventQueueFactoryBean = new AsyncEventQueueFactoryBean((Cache) gemFireCache);
AsyncEventQueueFactoryBean asyncEventQueueFactoryBean = new AsyncEventQueueFactoryBean((Cache) gemFireCache);
asyncEventQueueFactoryBean.setBatchTimeInterval(1000);
asyncEventQueueFactoryBean.setBatchSize(5);
asyncEventQueueFactoryBean.setAsyncEventListener(orderAsyncEventListener);
@@ -57,7 +56,7 @@ public class EventServerConfig {
@Bean(name = "OrderProductSummary")
PartitionedRegionFactoryBean<Long, Order> createOrderProductSummaryRegion(GemFireCache gemFireCache) {
final PartitionedRegionFactoryBean<Long, Order> partitionedRegionFactoryBean = new PartitionedRegionFactoryBean<>();
PartitionedRegionFactoryBean<Long, Order> partitionedRegionFactoryBean = new PartitionedRegionFactoryBean<>();
partitionedRegionFactoryBean.setCache(gemFireCache);
partitionedRegionFactoryBean.setRegionName("OrderProductSummary");
partitionedRegionFactoryBean.setDataPolicy(DataPolicy.PARTITION);
@@ -66,7 +65,7 @@ public class EventServerConfig {
@Bean("Orders")
PartitionedRegionFactoryBean<Long, Order> createOrderRegion(GemFireCache gemFireCache, AsyncEventQueue orderAsyncEventQueue) {
final PartitionedRegionFactoryBean<Long, Order> partitionedRegionFactoryBean = new PartitionedRegionFactoryBean<>();
PartitionedRegionFactoryBean<Long, Order> partitionedRegionFactoryBean = new PartitionedRegionFactoryBean<>();
partitionedRegionFactoryBean.setCache(gemFireCache);
partitionedRegionFactoryBean.setRegionName("Orders");
partitionedRegionFactoryBean.setDataPolicy(DataPolicy.PARTITION);
@@ -77,7 +76,7 @@ public class EventServerConfig {
@Bean("Products")
ReplicatedRegionFactoryBean<Long, Product> createProductRegion(GemFireCache gemFireCache, CacheListener<Long, Product> loggingCacheListener,
CacheLoader<Long, Product> productCacheLoader) {
final ReplicatedRegionFactoryBean<Long, Product> replicatedRegionFactoryBean = new ReplicatedRegionFactoryBean<>();
ReplicatedRegionFactoryBean<Long, Product> replicatedRegionFactoryBean = new ReplicatedRegionFactoryBean<>();
replicatedRegionFactoryBean.setCache(gemFireCache);
replicatedRegionFactoryBean.setRegionName("Products");
replicatedRegionFactoryBean.setDataPolicy(DataPolicy.REPLICATE);
@@ -90,7 +89,7 @@ public class EventServerConfig {
ReplicatedRegionFactoryBean<Long, Customer> createCustomerRegion(GemFireCache gemFireCache,
CacheWriter<Long, Customer> customerCacheWriter,
CacheListener<Long, Customer> loggingCacheListener) {
final ReplicatedRegionFactoryBean<Long, Customer> replicatedRegionFactoryBean = new ReplicatedRegionFactoryBean<>();
ReplicatedRegionFactoryBean<Long, Customer> replicatedRegionFactoryBean = new ReplicatedRegionFactoryBean<>();
replicatedRegionFactoryBean.setCache(gemFireCache);
replicatedRegionFactoryBean.setRegionName("Customers");
replicatedRegionFactoryBean.setDataPolicy(DataPolicy.REPLICATE);
@@ -98,4 +97,4 @@ public class EventServerConfig {
replicatedRegionFactoryBean.setCacheWriter(customerCacheWriter);
return replicatedRegionFactoryBean;
}
}
}

View File

@@ -13,7 +13,6 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package example.springdata.geode.server.events;
import lombok.Data;
@@ -45,4 +44,4 @@ public class LineItem implements Serializable {
public Long getProductId() {
return product.getId();
}
}
}

View File

@@ -13,32 +13,37 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package example.springdata.geode.server.events;
import lombok.extern.apachecommons.CommonsLog;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.apache.geode.cache.EntryEvent;
import org.apache.geode.cache.util.CacheListenerAdapter;
import org.springframework.stereotype.Component;
/**
* @author Patrick Johnson
*/
@Component
@CommonsLog
public class LoggingCacheListener<K, V> extends CacheListenerAdapter<K, V> {
private Log logger = LogFactory.getLog(LoggingCacheListener.class);
@Override
public void afterCreate(EntryEvent<K, V> event) {
logger.info("In region [" + event.getRegion().getName() + "] created key [" + event.getKey() + "] value [" + event.getNewValue() + "]");
log.info("In region [" + event.getRegion().getName() + "] created key [" + event.getKey() + "] value ["
+ event.getNewValue() + "]");
}
@Override
public void afterDestroy(EntryEvent<K, V> event) {
logger.info("In region [" + event.getRegion().getName() + "] destroyed key [" + event.getKey() + "] ");
log.info("In region [" + event.getRegion().getName() + "] destroyed key [" + event.getKey() + "] ");
}
@Override
public void afterUpdate(EntryEvent<K, V> event) {
logger.info("In region [" + event.getRegion().getName() + "] updated key [" + event.getNewValue() + "] [oldValue [" + event.getOldValue() + "]] new value [" + event.getNewValue() + "]");
log.info("In region [" + event.getRegion().getName() + "] updated key [" + event.getNewValue() + "] [oldValue ["
+ event.getOldValue() + "]] new value [" + event.getNewValue() + "]");
}
}
}

View File

@@ -13,7 +13,6 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package example.springdata.geode.server.events;
import lombok.Data;
@@ -34,6 +33,7 @@ import java.util.List;
@Data
@Region("Orders")
public class Order implements Serializable {
@Id
private Long id;
private Long customerId;
@@ -69,4 +69,4 @@ public class Order implements Serializable {
public void add(LineItem lineItem) {
lineItems.add(lineItem);
}
}
}

View File

@@ -13,17 +13,20 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package example.springdata.geode.server.events;
import java.math.BigDecimal;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import org.apache.geode.cache.Region;
import org.apache.geode.cache.asyncqueue.AsyncEvent;
import org.apache.geode.cache.asyncqueue.AsyncEventListener;
import java.math.BigDecimal;
import java.util.HashMap;
import java.util.List;
/**
* @author Patrick Johnson
*/
public class OrderAsyncQueueListener implements AsyncEventListener {
private Region<Long, OrderProductSummary> summaryRegion;
@@ -34,9 +37,9 @@ public class OrderAsyncQueueListener implements AsyncEventListener {
@Override
public boolean processEvents(List<AsyncEvent> list) {
HashMap<Long, OrderProductSummary> summaryMap = new HashMap<>();
Map<Long, OrderProductSummary> summaryMap = new HashMap<>();
list.forEach(asyncEvent -> {
final Order order = (Order) asyncEvent.getDeserializedValue();
Order order = (Order) asyncEvent.getDeserializedValue();
if (order != null) {
order.getLineItems().forEach(lineItem -> {
OrderProductSummary orderProductSummary = summaryMap.get(lineItem.getProductId());
@@ -50,14 +53,15 @@ public class OrderAsyncQueueListener implements AsyncEventListener {
});
summaryMap.forEach((orderProductSummaryKey, orderProductSummary) -> {
final OrderProductSummary productSummary = summaryRegion.get(orderProductSummaryKey);
OrderProductSummary productSummary = summaryRegion.get(orderProductSummaryKey);
if (productSummary != null) {
final BigDecimal newSummaryAmount = productSummary.getSummaryAmount().add(orderProductSummary.getSummaryAmount());
BigDecimal newSummaryAmount = productSummary.getSummaryAmount().add(orderProductSummary.getSummaryAmount());
summaryRegion.put(orderProductSummaryKey, new OrderProductSummary(orderProductSummaryKey, newSummaryAmount));
} else {
summaryRegion.put(orderProductSummaryKey, orderProductSummary);
}
});
return true;
}
}
}

View File

@@ -13,7 +13,6 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package example.springdata.geode.server.events;
import lombok.Data;
@@ -43,4 +42,4 @@ public class OrderProductSummary implements Serializable {
this.summaryKey = summaryKey;
this.summaryAmount = summaryAmount;
}
}
}

View File

@@ -13,16 +13,18 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package example.springdata.geode.server.events;
import java.util.List;
import org.springframework.data.gemfire.mapping.annotation.Region;
import org.springframework.data.gemfire.repository.Query;
import org.springframework.data.gemfire.repository.query.annotation.Hint;
import org.springframework.data.repository.CrudRepository;
import java.util.List;
/**
* @author Patrick Johnson
*/
@Region("OrderProductSummary")
public interface OrderProductSummaryRepository extends CrudRepository<OrderProductSummary, Long> {
@Hint("emailAddressIndex")

View File

@@ -13,10 +13,11 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package example.springdata.geode.server.events;
import org.springframework.data.repository.CrudRepository;
public interface OrderRepository extends CrudRepository<Order, Long> {
}
/**
* @author Patrick Johnson
*/
public interface OrderRepository extends CrudRepository<Order, Long> {}

View File

@@ -13,7 +13,6 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package example.springdata.geode.server.events;
import lombok.Data;

View File

@@ -13,17 +13,24 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package example.springdata.geode.server.events;
import com.github.javafaker.Faker;
import lombok.SneakyThrows;
import java.math.BigDecimal;
import java.text.DecimalFormat;
import org.apache.geode.cache.CacheLoader;
import org.apache.geode.cache.CacheLoaderException;
import org.apache.geode.cache.LoaderHelper;
import org.springframework.stereotype.Component;
import java.math.BigDecimal;
import com.github.javafaker.Faker;
/**
* @author Patrick Johnson
*/
@Component
public class ProductCacheLoader implements CacheLoader<Long, Product> {
private Faker faker = new Faker();
@@ -33,8 +40,9 @@ public class ProductCacheLoader implements CacheLoader<Long, Product> {
return new Product((long) loaderHelper.getKey(), randomStringName(), randomPrice(), "");
}
@SneakyThrows
private BigDecimal randomPrice() {
return new BigDecimal(faker.commerce().price());
return new BigDecimal(new DecimalFormat("#0.00").parse(faker.commerce().price()).toString());
}
private String randomStringName() {

View File

@@ -13,10 +13,11 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package example.springdata.geode.server.events;
import org.springframework.data.repository.CrudRepository;
public interface ProductRepository extends CrudRepository<Product, Long> {
}
/**
* @author Patrick Johnson
*/
public interface ProductRepository extends CrudRepository<Product, Long> {}

View File

@@ -13,32 +13,30 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package example.springdata.geode.server.events;
import static org.assertj.core.api.Assertions.*;
import org.apache.geode.cache.Cache;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.test.annotation.DirtiesContext;
import org.springframework.test.context.junit4.SpringRunner;
import static org.assertj.core.api.Assertions.assertThat;
/**
* @author Patrick Johnson
*/
@RunWith(SpringRunner.class)
@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.NONE, classes = EventServer.class)
@DirtiesContext(classMode = DirtiesContext.ClassMode.AFTER_CLASS)
@SpringBootTest
public class EventServerTests {
@Autowired
Cache cache;
@Autowired Cache cache;
@Autowired
private ProductRepository productRepository;
@Autowired private ProductRepository productRepository;
@Autowired
private OrderProductSummaryRepository orderProductSummaryRepository;
@Autowired private OrderProductSummaryRepository orderProductSummaryRepository;
@Test
public void asyncEventQueueEasConfiguredCorrectly() {
@@ -47,9 +45,12 @@ public class EventServerTests {
@Test
public void productCacheLoaderWorks() {
long size = productRepository.count();
assertThat(this.productRepository.findById(777L)).isNotNull();
assertThat(productRepository.count()).isEqualTo(size + 1);
productRepository.deleteById(777L);
}
}
}