Rename modules.
Rename geode-spring-boot to spring-geode. Rename geode-spring-boot-autoconfigure to spring-geode-autoconfigure. Rename geode-spring-boot-starter to spring-geode-starter. Rename gemfire-spring-boot-starter to spring-gemfire-starter. Resolves GitHub Issue #6.
This commit is contained in:
@@ -0,0 +1,27 @@
|
||||
/*
|
||||
* Copyright 2018 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
|
||||
*
|
||||
* http://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;
|
||||
|
||||
/**
|
||||
* The {@link NonBeanType} class is a non-Spring bean, placeholder reference type for classpath component scanning.
|
||||
*
|
||||
* @author John Blum
|
||||
* @since 1.0.0
|
||||
*/
|
||||
public class NonBeanType {
|
||||
|
||||
}
|
||||
@@ -0,0 +1,55 @@
|
||||
/*
|
||||
* Copyright 2018 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
|
||||
*
|
||||
* http://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.model;
|
||||
|
||||
import org.springframework.data.annotation.Id;
|
||||
import org.springframework.data.gemfire.mapping.annotation.Region;
|
||||
|
||||
import lombok.Data;
|
||||
import lombok.NonNull;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
|
||||
/**
|
||||
* The {@link Author} class is an Abstract Data Type (ADT) modeling a book author.
|
||||
*
|
||||
* @author John Blum
|
||||
* @see lombok
|
||||
* @see org.springframework.data.annotation.Id
|
||||
* @see org.springframework.data.gemfire.mapping.annotation.Region
|
||||
* @since 1.0.0
|
||||
*/
|
||||
@Data
|
||||
@Region("Authors")
|
||||
@RequiredArgsConstructor(staticName = "newAuthor")
|
||||
@SuppressWarnings("unused")
|
||||
public class Author {
|
||||
|
||||
@Id
|
||||
private Long id;
|
||||
|
||||
@NonNull
|
||||
private String name;
|
||||
|
||||
public boolean isNew() {
|
||||
return getId() == null;
|
||||
}
|
||||
|
||||
public Author identifiedBy(Long id) {
|
||||
setId(id);
|
||||
return this;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,62 @@
|
||||
/*
|
||||
* Copyright 2018 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
|
||||
*
|
||||
* http://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.model;
|
||||
|
||||
import java.time.LocalDate;
|
||||
|
||||
import org.springframework.data.annotation.Id;
|
||||
import org.springframework.data.gemfire.mapping.annotation.Region;
|
||||
|
||||
import lombok.Data;
|
||||
import lombok.NonNull;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
|
||||
/**
|
||||
* The {@link Book} class is an Abstract Data Type (ADT) modeling a book.
|
||||
*
|
||||
* @author John Blum
|
||||
* @see lombok
|
||||
* @see org.springframework.data.annotation.Id
|
||||
* @see org.springframework.data.gemfire.mapping.annotation.Region
|
||||
* @see example.app.model.Author
|
||||
* @see example.app.model.ISBN
|
||||
* @since 1.0.0
|
||||
*/
|
||||
@Region("Books")
|
||||
@Data
|
||||
@RequiredArgsConstructor(staticName = "newBook")
|
||||
public class Book {
|
||||
|
||||
private Author author;
|
||||
|
||||
@Id
|
||||
private ISBN isbn;
|
||||
|
||||
private LocalDate publishedDate;
|
||||
|
||||
@NonNull
|
||||
private String title;
|
||||
|
||||
public boolean isNew() {
|
||||
return getIsbn() == null;
|
||||
}
|
||||
|
||||
public Book identifiedBy(ISBN isbn) {
|
||||
setIsbn(isbn);
|
||||
return this;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,90 @@
|
||||
/*
|
||||
* Copyright 2018 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
|
||||
*
|
||||
* http://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.model;
|
||||
|
||||
import java.util.UUID;
|
||||
|
||||
import org.apache.shiro.util.Assert;
|
||||
|
||||
/**
|
||||
* The {@link ISBN} class is a Abstract Data Type (ADT) modeling either a {@link Book} ISBN-10 or ISBN-13 number.
|
||||
*
|
||||
* @author John Blum
|
||||
* @see java.lang.Comparable
|
||||
* @since 1.0.0
|
||||
*/
|
||||
@SuppressWarnings("unused")
|
||||
public class ISBN implements Comparable<ISBN> {
|
||||
|
||||
public static ISBN autoGenerated() {
|
||||
return of(UUID.randomUUID().toString());
|
||||
}
|
||||
|
||||
public static ISBN of(String number) {
|
||||
|
||||
Assert.hasText(number, String.format("Number [%s] is required", number));
|
||||
|
||||
return new ISBN(number);
|
||||
}
|
||||
|
||||
private String number;
|
||||
|
||||
private ISBN(String number) {
|
||||
this.number = number;
|
||||
}
|
||||
|
||||
public String getNumber() {
|
||||
return number;
|
||||
}
|
||||
|
||||
@Override
|
||||
@SuppressWarnings("all")
|
||||
public int compareTo(ISBN other) {
|
||||
return this.getNumber().compareTo(other.getNumber());
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object obj) {
|
||||
|
||||
if (this == obj) {
|
||||
return true;
|
||||
}
|
||||
|
||||
if (!(obj instanceof ISBN)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
ISBN that = (ISBN) obj;
|
||||
|
||||
return this.getNumber().equals(that.getNumber());
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
|
||||
int hashValue = 17;
|
||||
|
||||
hashValue = 37 * hashValue + getNumber().hashCode();
|
||||
|
||||
return hashValue;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return getNumber();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,46 @@
|
||||
/*
|
||||
* Copyright 2018 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
|
||||
*
|
||||
* http://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.repo;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import org.springframework.data.repository.CrudRepository;
|
||||
|
||||
import example.app.model.Author;
|
||||
import example.app.model.Book;
|
||||
import example.app.model.ISBN;
|
||||
|
||||
/**
|
||||
* The {@link BookRepository} interface is a Spring Data {@link CrudRepository} defining basic CRUD
|
||||
* and simple query data access operations on {@link Book} objects to the backing data store.
|
||||
*
|
||||
* @author John Blum
|
||||
* @see example.app.model.Book
|
||||
* @see example.app.model.ISBN
|
||||
* @see org.springframework.data.repository.CrudRepository
|
||||
* @since 1.0.0
|
||||
*/
|
||||
@SuppressWarnings("unused")
|
||||
public interface BookRepository extends CrudRepository<Book, ISBN> {
|
||||
|
||||
List<Book> findByAuthorOrderByAuthorNameAscTitleAsc(Author author);
|
||||
|
||||
Book findByIsbn(ISBN isbn);
|
||||
|
||||
Book findByTitle(String title);
|
||||
|
||||
}
|
||||
@@ -0,0 +1,79 @@
|
||||
/*
|
||||
* Copyright 2018 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
|
||||
*
|
||||
* http://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.service;
|
||||
|
||||
import static org.springframework.data.gemfire.util.RuntimeExceptionFactory.newIllegalStateException;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Optional;
|
||||
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
import example.app.model.Author;
|
||||
import example.app.model.Book;
|
||||
import example.app.model.ISBN;
|
||||
import example.app.repo.BookRepository;
|
||||
|
||||
/**
|
||||
* The {@link BookService} class is an application {@link Service service} class for managing {@link Book Books}.
|
||||
*
|
||||
* @author John Blum
|
||||
* @see example.app.model.Author
|
||||
* @see example.app.model.Book
|
||||
* @see example.app.model.ISBN
|
||||
* @see example.app.repo.BookRepository
|
||||
* @see org.springframework.stereotype.Service
|
||||
* @since 1.0.0
|
||||
*/
|
||||
@Service
|
||||
@SuppressWarnings("unused")
|
||||
public class BookService {
|
||||
|
||||
private final BookRepository bookRepository;
|
||||
|
||||
public BookService(@Autowired(required = false) BookRepository bookRepository) {
|
||||
this.bookRepository = bookRepository;
|
||||
}
|
||||
|
||||
protected BookRepository getBookRepository() {
|
||||
|
||||
return Optional.ofNullable(this.bookRepository)
|
||||
.orElseThrow(() -> newIllegalStateException("BookRepository was not properly configured"));
|
||||
}
|
||||
|
||||
public List<Book> findByAuthor(Author author) {
|
||||
return getBookRepository().findByAuthorOrderByAuthorNameAscTitleAsc(author);
|
||||
}
|
||||
|
||||
public Book findByIsbn(ISBN isbn) {
|
||||
return getBookRepository().findByIsbn(isbn);
|
||||
}
|
||||
|
||||
public Book findByTitle(String title) {
|
||||
return getBookRepository().findByTitle(title);
|
||||
}
|
||||
|
||||
public Book stock(Book book) {
|
||||
|
||||
if (book.isNew()) {
|
||||
book.identifiedBy(ISBN.autoGenerated());
|
||||
}
|
||||
|
||||
return getBookRepository().save(book);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,62 @@
|
||||
/*
|
||||
* Copyright 2018 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
|
||||
*
|
||||
* http://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.service.support;
|
||||
|
||||
import java.util.concurrent.atomic.AtomicBoolean;
|
||||
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.cache.annotation.Cacheable;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
import example.app.model.Book;
|
||||
import example.app.model.ISBN;
|
||||
import example.app.repo.BookRepository;
|
||||
import example.app.service.BookService;
|
||||
|
||||
/**
|
||||
* The {@link CachingBookService} class is an implementation and extension of {@link BookService}
|
||||
* with caching capabilities.
|
||||
*
|
||||
* @author John Blum
|
||||
* @see example.app.model.Book
|
||||
* @see example.app.model.ISBN
|
||||
* @see example.app.repo.BookRepository
|
||||
* @see example.app.service.BookService
|
||||
* @see org.springframework.cache.annotation.Cacheable
|
||||
* @see org.springframework.stereotype.Service
|
||||
* @since 1.0.0
|
||||
*/
|
||||
@Service
|
||||
public class CachingBookService extends BookService {
|
||||
|
||||
private final AtomicBoolean cacheMiss = new AtomicBoolean(false);
|
||||
|
||||
public CachingBookService(@Autowired(required = false) BookRepository bookRepository) {
|
||||
super(bookRepository);
|
||||
}
|
||||
|
||||
public boolean isCacheMiss() {
|
||||
return this.cacheMiss.getAndSet(false);
|
||||
}
|
||||
|
||||
@Override
|
||||
@Cacheable(value = "CachedBooks")
|
||||
public Book findByTitle(String title) {
|
||||
this.cacheMiss.set(true);
|
||||
return Book.newBook(title).identifiedBy(ISBN.autoGenerated());
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,65 @@
|
||||
/*
|
||||
* Copyright 2018 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
|
||||
*
|
||||
* http://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.echo.config;
|
||||
|
||||
import org.apache.geode.cache.GemFireCache;
|
||||
import org.apache.geode.cache.Region;
|
||||
import org.apache.geode.cache.client.ClientCache;
|
||||
import org.apache.geode.cache.client.ClientRegionShortcut;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
import org.springframework.data.gemfire.GemfireTemplate;
|
||||
import org.springframework.data.gemfire.client.ClientRegionFactoryBean;
|
||||
import org.springframework.data.gemfire.util.RegionUtils;
|
||||
|
||||
/**
|
||||
* The {@link EchoClientConfiguration} class is a Spring {@link Configuration} class used to configure
|
||||
* a {@link ClientCache} {@link Region} for echo messages.
|
||||
*
|
||||
* @author John Blum
|
||||
* @see org.apache.geode.cache.GemFireCache
|
||||
* @see org.apache.geode.cache.Region
|
||||
* @see org.apache.geode.cache.client.ClientCache
|
||||
* @see org.springframework.context.annotation.Bean
|
||||
* @see org.springframework.context.annotation.Configuration
|
||||
* @see org.springframework.data.gemfire.GemfireTemplate
|
||||
* @see org.springframework.data.gemfire.client.ClientRegionFactoryBean
|
||||
* @since 1.0.0
|
||||
*/
|
||||
@Configuration
|
||||
@SuppressWarnings("unused")
|
||||
public class EchoClientConfiguration {
|
||||
|
||||
protected static final String REGION_NAME = "Echo";
|
||||
|
||||
@Bean(REGION_NAME)
|
||||
public ClientRegionFactoryBean<String, String> echoRegion(GemFireCache gemfireCache) {
|
||||
|
||||
ClientRegionFactoryBean<String, String> echoRegion = new ClientRegionFactoryBean<>();
|
||||
|
||||
echoRegion.setCache(gemfireCache);
|
||||
echoRegion.setClose(false);
|
||||
echoRegion.setShortcut(ClientRegionShortcut.PROXY);
|
||||
|
||||
return echoRegion;
|
||||
}
|
||||
|
||||
@Bean
|
||||
public GemfireTemplate echoTemplate(GemFireCache gemfireCache) {
|
||||
return new GemfireTemplate(gemfireCache.getRegion(RegionUtils.toRegionPath(REGION_NAME)));
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,68 @@
|
||||
/*
|
||||
* Copyright 2018 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
|
||||
*
|
||||
* http://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.echo.config;
|
||||
|
||||
import org.apache.geode.cache.Cache;
|
||||
import org.apache.geode.cache.GemFireCache;
|
||||
import org.apache.geode.cache.Region;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
import org.springframework.data.gemfire.GemfireTemplate;
|
||||
import org.springframework.data.gemfire.PartitionedRegionFactoryBean;
|
||||
import org.springframework.data.gemfire.util.RegionUtils;
|
||||
|
||||
import example.geode.cache.EchoCacheLoader;
|
||||
|
||||
/**
|
||||
* The {@link EchoClientConfiguration} class is a Spring {@link Configuration} class used to configure
|
||||
* a peer {@link Cache} {@link Region} for echo messages.
|
||||
*
|
||||
* @author John Blum
|
||||
* @see org.apache.geode.cache.Cache
|
||||
* @see org.apache.geode.cache.GemFireCache
|
||||
* @see org.apache.geode.cache.Region
|
||||
* @see org.springframework.context.annotation.Bean
|
||||
* @see org.springframework.context.annotation.Configuration
|
||||
* @see org.springframework.data.gemfire.GemfireTemplate
|
||||
* @see org.springframework.data.gemfire.PartitionedRegionFactoryBean
|
||||
* @see example.geode.cache.EchoCacheLoader
|
||||
* @since 1.0.0
|
||||
*/
|
||||
@Configuration
|
||||
@SuppressWarnings("unused")
|
||||
public class EchoServerConfiguration {
|
||||
|
||||
@Bean(EchoClientConfiguration.REGION_NAME)
|
||||
public PartitionedRegionFactoryBean<String, String> echoRegion(GemFireCache gemfireCache) {
|
||||
|
||||
PartitionedRegionFactoryBean<String, String> echoRegion = new PartitionedRegionFactoryBean<>();
|
||||
|
||||
echoRegion.setCache(gemfireCache);
|
||||
echoRegion.setCacheLoader(EchoCacheLoader.INSTANCE);
|
||||
echoRegion.setClose(false);
|
||||
echoRegion.setPersistent(false);
|
||||
|
||||
return echoRegion;
|
||||
}
|
||||
|
||||
@Bean
|
||||
public GemfireTemplate echoTemplate(GemFireCache gemfireCache) {
|
||||
|
||||
return new GemfireTemplate(gemfireCache.getRegion(
|
||||
RegionUtils.toRegionPath(EchoClientConfiguration.REGION_NAME)));
|
||||
}
|
||||
}
|
||||
41
spring-geode-autoconfigure/src/test/java/example/geode/cache/EchoCacheLoader.java
vendored
Normal file
41
spring-geode-autoconfigure/src/test/java/example/geode/cache/EchoCacheLoader.java
vendored
Normal file
@@ -0,0 +1,41 @@
|
||||
/*
|
||||
* Copyright 2018 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
|
||||
*
|
||||
* http://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.geode.cache;
|
||||
|
||||
import org.apache.geode.cache.CacheLoader;
|
||||
import org.apache.geode.cache.CacheLoaderException;
|
||||
import org.apache.geode.cache.LoaderHelper;
|
||||
import org.springframework.geode.cache.support.CacheLoaderSupport;
|
||||
|
||||
/**
|
||||
* The {@link EchoCacheLoader} class is an implementation of {@link CacheLoader} that echos the key as the value.
|
||||
*
|
||||
* @author John Blum
|
||||
* @see org.apache.geode.cache.CacheLoader
|
||||
* @see org.springframework.geode.cache.support.CacheLoaderSupport
|
||||
* @since 1.0.0
|
||||
*/
|
||||
@SuppressWarnings("unused")
|
||||
public class EchoCacheLoader implements CacheLoaderSupport<String, String> {
|
||||
|
||||
public static final EchoCacheLoader INSTANCE = new EchoCacheLoader();
|
||||
|
||||
@Override
|
||||
public String load(LoaderHelper<String, String> helper) throws CacheLoaderException {
|
||||
return helper.getKey();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,62 @@
|
||||
/*
|
||||
* Copyright 2018 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
|
||||
*
|
||||
* http://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.geode.query.cq.event;
|
||||
|
||||
import java.time.LocalDateTime;
|
||||
|
||||
import lombok.Data;
|
||||
import lombok.EqualsAndHashCode;
|
||||
import lombok.NonNull;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
|
||||
/**
|
||||
* The {@link TemperatureReading} class is an Abstract Data Type (ADT) modeling a temperature event,
|
||||
* tracking the recorded temperature, unit and timestamp of the event.
|
||||
*
|
||||
* @author John Blum
|
||||
* @see java.time.LocalDateTime
|
||||
* @see lombok
|
||||
* @see example.geode.query.cq.event.TemperatureUnit
|
||||
* @since 1.0.0
|
||||
*/
|
||||
@Data
|
||||
@EqualsAndHashCode(of = { "temperature", "temperatureUnit" })
|
||||
@RequiredArgsConstructor(staticName = "of")
|
||||
public class TemperatureReading {
|
||||
|
||||
@NonNull
|
||||
private Integer temperature;
|
||||
|
||||
private LocalDateTime timestamp = LocalDateTime.now();
|
||||
|
||||
private TemperatureUnit temperatureUnit = TemperatureUnit.defaultTemperatureUnit();
|
||||
|
||||
public TemperatureReading at(LocalDateTime timestamp) {
|
||||
setTimestamp(timestamp);
|
||||
return this;
|
||||
}
|
||||
|
||||
public TemperatureReading in(TemperatureUnit temperatureUnit) {
|
||||
setTemperatureUnit(temperatureUnit);
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return String.format("%d %s", getTemperature(), getTemperatureUnit());
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,90 @@
|
||||
/*
|
||||
* Copyright 2018 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
|
||||
*
|
||||
* http://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.geode.query.cq.event;
|
||||
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
import java.util.concurrent.CopyOnWriteArrayList;
|
||||
import java.util.concurrent.atomic.AtomicInteger;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
import org.apache.geode.cache.query.CqEvent;
|
||||
import org.springframework.data.gemfire.listener.annotation.ContinuousQuery;
|
||||
|
||||
/**
|
||||
* The {@link TemperatureReadingsContinuousQueriesHandler} class is a POJO containing Apache Geode/Pivotal GemFire
|
||||
* Continuous Query (CQ) definitions.
|
||||
*
|
||||
* @author John Blum
|
||||
* @see org.apache.geode.cache.query.CqEvent
|
||||
* @see org.springframework.data.gemfire.listener.annotation.ContinuousQuery
|
||||
* @since 1.0.0
|
||||
*/
|
||||
@SuppressWarnings("unused")
|
||||
public final class TemperatureReadingsContinuousQueriesHandler {
|
||||
|
||||
private final AtomicInteger temperatureReadingsCounter = new AtomicInteger(0);
|
||||
|
||||
private final List<TemperatureReading> boilingTemperatureReadings = new CopyOnWriteArrayList<>();
|
||||
private final List<TemperatureReading> freezingTemperatureReadings = new CopyOnWriteArrayList<>();
|
||||
|
||||
public List<TemperatureReading> getBoilingTemperatureReadings() {
|
||||
return Collections.unmodifiableList(this.boilingTemperatureReadings);
|
||||
}
|
||||
|
||||
public List<Integer> getBoilingTemperatures() {
|
||||
|
||||
return getBoilingTemperatureReadings().stream()
|
||||
.map(TemperatureReading::getTemperature)
|
||||
.collect(Collectors.toList());
|
||||
}
|
||||
|
||||
public List<TemperatureReading> getFreezingTemperatureReadings() {
|
||||
return Collections.unmodifiableList(this.freezingTemperatureReadings);
|
||||
}
|
||||
|
||||
public List<Integer> getFreezingTemperatures() {
|
||||
|
||||
return getFreezingTemperatureReadings().stream()
|
||||
.map(TemperatureReading::getTemperature)
|
||||
.collect(Collectors.toList());
|
||||
}
|
||||
|
||||
public int getTemperatureReadingCount() {
|
||||
return this.temperatureReadingsCounter.get();
|
||||
}
|
||||
|
||||
@ContinuousQuery(name = "BoilingTemperatures",
|
||||
query = "SELECT * FROM /TemperatureReadings r WHERE r.temperature >= 212")
|
||||
public void boilingTemperatures(CqEvent event) {
|
||||
|
||||
TemperatureReading temperatureReading = (TemperatureReading) event.getNewValue();
|
||||
|
||||
this.boilingTemperatureReadings.add(temperatureReading);
|
||||
this.temperatureReadingsCounter.incrementAndGet();
|
||||
}
|
||||
|
||||
@ContinuousQuery(name = "FreezingTemperatures",
|
||||
query = "SELECT * FROM /TemperatureReadings r WHERE r.temperature <= 32")
|
||||
public void freezingTemperatures(CqEvent event) {
|
||||
|
||||
TemperatureReading temperatureReading = (TemperatureReading) event.getNewValue();
|
||||
|
||||
this.freezingTemperatureReadings.add(temperatureReading);
|
||||
this.temperatureReadingsCounter.incrementAndGet();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,59 @@
|
||||
/*
|
||||
* Copyright 2018 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
|
||||
*
|
||||
* http://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.geode.query.cq.event;
|
||||
|
||||
import java.util.Locale;
|
||||
import java.util.Optional;
|
||||
|
||||
/**
|
||||
* The {@link TemperatureUnit} enum is an enumeration of different temperature units
|
||||
* as defined by International System of Units (SI).
|
||||
*
|
||||
* @author John Blum
|
||||
* @since 1.0.0
|
||||
*/
|
||||
@SuppressWarnings("unused")
|
||||
public enum TemperatureUnit {
|
||||
|
||||
CELSIUS("°C"),
|
||||
FAHRENHEIT("°F"),
|
||||
KELVIN("K");
|
||||
|
||||
public static TemperatureUnit defaultTemperatureUnit() {
|
||||
|
||||
return Optional.of(Locale.getDefault())
|
||||
.map(Locale::getISO3Country)
|
||||
.filter(Locale.US.getISO3Country()::equalsIgnoreCase)
|
||||
.map(it -> TemperatureUnit.FAHRENHEIT)
|
||||
.orElse(TemperatureUnit.CELSIUS);
|
||||
}
|
||||
|
||||
private final String symbol;
|
||||
|
||||
TemperatureUnit(String symbol) {
|
||||
this.symbol = symbol;
|
||||
}
|
||||
|
||||
public String getSymbol() {
|
||||
return this.symbol;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return getSymbol();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,41 @@
|
||||
/*
|
||||
* Copyright 2018 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
|
||||
*
|
||||
* http://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.java.net;
|
||||
|
||||
import java.net.URL;
|
||||
|
||||
import org.springframework.core.io.ClassPathResource;
|
||||
|
||||
/**
|
||||
* The {@link UrlRevealed} class is a disclosure of Java's {@link URL} class.
|
||||
*
|
||||
* @author John Blum
|
||||
* @see java.net.URL
|
||||
* @since 1.0.0
|
||||
*/
|
||||
public class UrlRevealed {
|
||||
|
||||
public static void main(String[] args) throws Exception {
|
||||
|
||||
URL url = new URL("jar:file:///www.foo.com/bar/jar.jar!/baz/entry.txt");
|
||||
|
||||
System.out.printf("URL [%s] {%n \tfile [%s],%n \tpath [%s],%n \tport [%s],%n \tprotocol [%s],%n \tquery [%s]%n}%n%n",
|
||||
url, url.getFile(), url.getPath(), url.getPort(), url.getProtocol(), url.getQuery());
|
||||
|
||||
System.out.printf("URI [%s]%n", new ClassPathResource("trusted.keystore").getURL().toURI());
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,102 @@
|
||||
/*
|
||||
* Copyright 2018 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
|
||||
*
|
||||
* http://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 org.springframework.geode.boot.autoconfigure.cache.client;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
import static org.springframework.data.gemfire.util.RuntimeExceptionFactory.newIllegalStateException;
|
||||
|
||||
import java.util.Optional;
|
||||
|
||||
import org.apache.geode.cache.GemFireCache;
|
||||
import org.apache.geode.cache.Region;
|
||||
import org.apache.geode.cache.client.ClientCache;
|
||||
import org.apache.geode.cache.client.ClientRegionShortcut;
|
||||
import org.apache.geode.internal.cache.GemFireCacheImpl;
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.boot.autoconfigure.SpringBootApplication;
|
||||
import org.springframework.boot.test.context.SpringBootTest;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.data.gemfire.client.ClientRegionFactoryBean;
|
||||
import org.springframework.data.gemfire.config.annotation.EnableLogging;
|
||||
import org.springframework.data.gemfire.tests.integration.IntegrationTestsSupport;
|
||||
import org.springframework.data.gemfire.util.RegionUtils;
|
||||
import org.springframework.test.context.junit4.SpringRunner;
|
||||
|
||||
/**
|
||||
* Integration test testing the auto-configuration of an Apache Geode {@link ClientCache} instance.
|
||||
*
|
||||
* @author John Blum
|
||||
* @see org.junit.Test
|
||||
* @see org.apache.geode.cache.GemFireCache
|
||||
* @see org.apache.geode.cache.Region
|
||||
* @see org.apache.geode.cache.client.ClientCache
|
||||
* @see org.springframework.boot.autoconfigure.SpringBootApplication
|
||||
* @see org.springframework.boot.test.context.SpringBootTest
|
||||
* @see org.springframework.data.gemfire.tests.integration.IntegrationTestsSupport
|
||||
* @see org.springframework.geode.boot.autoconfigure.ClientCacheAutoConfiguration
|
||||
* @see org.springframework.test.context.junit4.SpringRunner
|
||||
* @since 1.0.0
|
||||
*/
|
||||
@RunWith(SpringRunner.class)
|
||||
@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.NONE)
|
||||
@SuppressWarnings("unused")
|
||||
public class SpringBootApacheGeodeClientCacheApplicationIntegrationTests extends IntegrationTestsSupport {
|
||||
|
||||
private static final String GEMFIRE_LOG_LEVEL = "error";
|
||||
|
||||
@Autowired
|
||||
private ClientCache clientCache;
|
||||
|
||||
@Test
|
||||
public void clientCacheAndClientRegionAreAvailable() {
|
||||
|
||||
Optional.ofNullable(this.clientCache)
|
||||
.filter(it -> it instanceof GemFireCacheImpl)
|
||||
.map(it -> (GemFireCacheImpl) it)
|
||||
.map(it -> assertThat(it.isClient()).isTrue())
|
||||
.orElseThrow(() -> newIllegalStateException("ClientCache was null"));
|
||||
|
||||
Region<Object, Object> example = this.clientCache.getRegion("Example");
|
||||
|
||||
assertThat(example).isNotNull();
|
||||
assertThat(example.getName()).isEqualTo("Example");
|
||||
assertThat(example.getFullPath()).isEqualTo(RegionUtils.toRegionPath("Example"));
|
||||
|
||||
example.put(1, "test");
|
||||
|
||||
assertThat(example.get(1)).isEqualTo("test");
|
||||
}
|
||||
|
||||
@SpringBootApplication
|
||||
@EnableLogging(logLevel = GEMFIRE_LOG_LEVEL)
|
||||
static class TestConfiguration {
|
||||
|
||||
@Bean("Example")
|
||||
public ClientRegionFactoryBean<Object, Object> exampleRegion(GemFireCache gemfireCache) {
|
||||
|
||||
ClientRegionFactoryBean<Object, Object> clientRegion = new ClientRegionFactoryBean<>();
|
||||
|
||||
clientRegion.setCache(gemfireCache);
|
||||
clientRegion.setClose(false);
|
||||
clientRegion.setShortcut(ClientRegionShortcut.LOCAL);
|
||||
|
||||
return clientRegion;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,103 @@
|
||||
/*
|
||||
* Copyright 2018 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
|
||||
*
|
||||
* http://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 org.springframework.geode.boot.autoconfigure.cache.peer;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
import static org.springframework.data.gemfire.util.RuntimeExceptionFactory.newIllegalStateException;
|
||||
|
||||
import java.util.Optional;
|
||||
|
||||
import org.apache.geode.cache.Cache;
|
||||
import org.apache.geode.cache.GemFireCache;
|
||||
import org.apache.geode.cache.Region;
|
||||
import org.apache.geode.cache.client.ClientCache;
|
||||
import org.apache.geode.internal.cache.GemFireCacheImpl;
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.boot.autoconfigure.SpringBootApplication;
|
||||
import org.springframework.boot.test.context.SpringBootTest;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.data.gemfire.LocalRegionFactoryBean;
|
||||
import org.springframework.data.gemfire.config.annotation.PeerCacheApplication;
|
||||
import org.springframework.data.gemfire.tests.integration.IntegrationTestsSupport;
|
||||
import org.springframework.data.gemfire.util.RegionUtils;
|
||||
import org.springframework.test.context.junit4.SpringRunner;
|
||||
|
||||
/**
|
||||
* Integration test testing the auto-configuration of an Apache Geode peer {@link Cache} instance, overriding
|
||||
* the default {@link ClientCache} instance.
|
||||
*
|
||||
* @author John Blum
|
||||
* @see org.junit.Test
|
||||
* @see org.apache.geode.cache.Cache
|
||||
* @see org.apache.geode.cache.GemFireCache
|
||||
* @see org.apache.geode.cache.Region
|
||||
* @see org.springframework.boot.autoconfigure.SpringBootApplication
|
||||
* @see org.springframework.boot.test.context.SpringBootTest
|
||||
* @see org.springframework.data.gemfire.config.annotation.PeerCacheApplication
|
||||
* @see org.springframework.data.gemfire.tests.integration.IntegrationTestsSupport
|
||||
* @see org.springframework.test.context.junit4.SpringRunner
|
||||
* @since 1.0.0
|
||||
*/
|
||||
@RunWith(SpringRunner.class)
|
||||
@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.NONE)
|
||||
@SuppressWarnings("unused")
|
||||
public class SpringBootApacheGeodePeerCacheApplicationIntegrationTests extends IntegrationTestsSupport {
|
||||
|
||||
private static final String GEMFIRE_LOG_LEVEL = "error";
|
||||
|
||||
@Autowired
|
||||
private GemFireCache peerCache;
|
||||
|
||||
@Test
|
||||
public void peerCacheWithPeerLocalRegionAreAvailable() {
|
||||
|
||||
Optional.ofNullable(this.peerCache)
|
||||
.filter(it -> it instanceof GemFireCacheImpl)
|
||||
.map(it -> (GemFireCacheImpl) it)
|
||||
.map(it -> assertThat(it.isClient()).isFalse())
|
||||
.orElseThrow(() -> newIllegalStateException("Peer cache was null"));
|
||||
|
||||
Region<Object, Object> example = peerCache.getRegion("/Example");
|
||||
|
||||
assertThat(example).isNotNull();
|
||||
assertThat(example.getName()).isEqualTo("Example");
|
||||
assertThat(example.getFullPath()).isEqualTo(RegionUtils.toRegionPath("Example"));
|
||||
|
||||
example.put(1, "test");
|
||||
|
||||
assertThat(example.get(1)).isEqualTo("test");
|
||||
}
|
||||
|
||||
@SpringBootApplication
|
||||
@PeerCacheApplication(logLevel = GEMFIRE_LOG_LEVEL)
|
||||
static class TestConfiguration {
|
||||
|
||||
@Bean("Example")
|
||||
public LocalRegionFactoryBean<Object, Object> exampleRegion(GemFireCache gemfireCache) {
|
||||
|
||||
LocalRegionFactoryBean<Object, Object> exampleRegion = new LocalRegionFactoryBean<>();
|
||||
|
||||
exampleRegion.setCache(gemfireCache);
|
||||
exampleRegion.setClose(false);
|
||||
exampleRegion.setPersistent(false);
|
||||
|
||||
return exampleRegion;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,128 @@
|
||||
/*
|
||||
* Copyright 2018 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
|
||||
*
|
||||
* http://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 org.springframework.geode.boot.autoconfigure.caching;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
|
||||
import javax.annotation.Resource;
|
||||
|
||||
import org.apache.geode.cache.Region;
|
||||
import org.apache.geode.cache.client.ClientRegionShortcut;
|
||||
import org.assertj.core.api.Assertions;
|
||||
import org.junit.FixMethodOrder;
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
import org.junit.runners.MethodSorters;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.boot.autoconfigure.SpringBootApplication;
|
||||
import org.springframework.boot.test.context.SpringBootTest;
|
||||
import org.springframework.data.gemfire.config.annotation.EnableCachingDefinedRegions;
|
||||
import org.springframework.data.gemfire.config.annotation.EnableLogging;
|
||||
import org.springframework.data.gemfire.tests.integration.IntegrationTestsSupport;
|
||||
import org.springframework.data.gemfire.util.RegionUtils;
|
||||
import org.springframework.test.context.junit4.SpringRunner;
|
||||
|
||||
import example.app.NonBeanType;
|
||||
import example.app.model.Book;
|
||||
import example.app.service.support.CachingBookService;
|
||||
|
||||
/**
|
||||
* Integration tests testing the auto-configuration of Spring's Cache Abstraction with Apache Geode
|
||||
* or Pivotal GemFire as the caching provider.
|
||||
*
|
||||
* @author John Blum
|
||||
* @see org.junit.Test
|
||||
* @see org.apache.geode.cache.Region
|
||||
* @see org.springframework.boot.autoconfigure.SpringBootApplication
|
||||
* @see org.springframework.boot.test.context.SpringBootTest
|
||||
* @see org.springframework.data.gemfire.config.annotation.EnableCachingDefinedRegions
|
||||
* @see org.springframework.data.gemfire.tests.integration.IntegrationTestsSupport
|
||||
* @see org.springframework.geode.boot.autoconfigure.CachingProviderAutoConfiguration
|
||||
* @see org.springframework.test.context.junit4.SpringRunner
|
||||
* @since 1.0.0
|
||||
*/
|
||||
@RunWith(SpringRunner.class)
|
||||
@FixMethodOrder(MethodSorters.NAME_ASCENDING)
|
||||
@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.NONE)
|
||||
@SuppressWarnings("unused")
|
||||
public class AutoConfiguredCachingIntegrationTests extends IntegrationTestsSupport {
|
||||
|
||||
private static final String GEMFIRE_LOG_LEVEL = "error";
|
||||
|
||||
@Autowired
|
||||
private CachingBookService bookService;
|
||||
|
||||
@Resource(name = "CachedBooks")
|
||||
private Region<String, Book> cachedBooks;
|
||||
|
||||
private void assertBook(Book book, String title) {
|
||||
|
||||
Assertions.assertThat(book).isNotNull();
|
||||
Assertions.assertThat(book.isNew()).isFalse();
|
||||
Assertions.assertThat(book.getTitle()).isEqualTo(title);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void bookServiceWasConfiguredCorrectly() {
|
||||
|
||||
Assertions.assertThat(this.bookService).isNotNull();
|
||||
Assertions.assertThat(this.bookService.isCacheMiss()).isFalse();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void cachedBooksRegionWasConfiguredCorrectly() {
|
||||
|
||||
Assertions.assertThat(this.cachedBooks).isNotNull();
|
||||
assertThat(this.cachedBooks.getName()).isEqualTo("CachedBooks");
|
||||
assertThat(this.cachedBooks.getFullPath()).isEqualTo(RegionUtils.toRegionPath("CachedBooks"));
|
||||
Assertions.assertThat(this.cachedBooks).isEmpty();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void geodeAsTheCachingProviderWasAutoConfiguredCorrectly() {
|
||||
|
||||
Assertions.assertThat(this.cachedBooks).isEmpty();
|
||||
|
||||
Book bookOne = this.bookService.findByTitle("Star Wars 3 - Revenge of the Sith");
|
||||
|
||||
assertBook(bookOne, "Star Wars 3 - Revenge of the Sith");
|
||||
Assertions.assertThat(this.bookService.isCacheMiss()).isTrue();
|
||||
Assertions.assertThat(this.cachedBooks).hasSize(1);
|
||||
Assertions.assertThat(this.cachedBooks.get(bookOne.getTitle())).isEqualTo(bookOne);
|
||||
|
||||
Book bookOneAgain = this.bookService.findByTitle(bookOne.getTitle());
|
||||
|
||||
Assertions.assertThat(bookOneAgain).isEqualTo(bookOne);
|
||||
Assertions.assertThat(this.bookService.isCacheMiss()).isFalse();
|
||||
Assertions.assertThat(this.cachedBooks).hasSize(1);
|
||||
Assertions.assertThat(this.cachedBooks.get(bookOne.getTitle())).isEqualTo(bookOne);
|
||||
|
||||
Book bookTwo = this.bookService.findByTitle("Star Wars 6 - Return of the Jedi");
|
||||
|
||||
assertBook(bookTwo, "Star Wars 6 - Return of the Jedi");
|
||||
Assertions.assertThat(this.bookService.isCacheMiss()).isTrue();
|
||||
Assertions.assertThat(this.cachedBooks).hasSize(2);
|
||||
Assertions.assertThat(this.cachedBooks.get(bookOne.getTitle())).isEqualTo(bookOne);
|
||||
Assertions.assertThat(this.cachedBooks.get(bookTwo.getTitle())).isEqualTo(bookTwo);
|
||||
}
|
||||
|
||||
@SpringBootApplication(scanBasePackageClasses = NonBeanType.class)
|
||||
@EnableLogging(logLevel = GEMFIRE_LOG_LEVEL)
|
||||
@EnableCachingDefinedRegions(clientRegionShortcut = ClientRegionShortcut.LOCAL)
|
||||
static class TestConfiguration { }
|
||||
|
||||
}
|
||||
@@ -0,0 +1,218 @@
|
||||
/*
|
||||
* Copyright 2018 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
|
||||
*
|
||||
* http://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 org.springframework.geode.boot.autoconfigure.cq;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
|
||||
import java.io.IOException;
|
||||
|
||||
import javax.annotation.Resource;
|
||||
|
||||
import org.apache.geode.cache.CacheLoader;
|
||||
import org.apache.geode.cache.CacheLoaderException;
|
||||
import org.apache.geode.cache.GemFireCache;
|
||||
import org.apache.geode.cache.LoaderHelper;
|
||||
import org.apache.geode.cache.Region;
|
||||
import org.apache.geode.cache.client.ClientRegionShortcut;
|
||||
import org.assertj.core.api.Assertions;
|
||||
import org.junit.Before;
|
||||
import org.junit.BeforeClass;
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.boot.autoconfigure.SpringBootApplication;
|
||||
import org.springframework.boot.test.context.SpringBootTest;
|
||||
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.DependsOn;
|
||||
import org.springframework.data.gemfire.GemfireTemplate;
|
||||
import org.springframework.data.gemfire.PartitionedRegionFactoryBean;
|
||||
import org.springframework.data.gemfire.client.ClientRegionFactoryBean;
|
||||
import org.springframework.data.gemfire.config.annotation.CacheServerApplication;
|
||||
import org.springframework.data.gemfire.config.annotation.EnableLogging;
|
||||
import org.springframework.data.gemfire.config.annotation.EnablePdx;
|
||||
import org.springframework.data.gemfire.tests.integration.ForkingClientServerIntegrationTestsSupport;
|
||||
import org.springframework.data.gemfire.tests.integration.config.SubscriptionEnabledClientServerIntegrationTestsConfiguration;
|
||||
import org.springframework.test.context.junit4.SpringRunner;
|
||||
|
||||
import example.geode.query.cq.event.TemperatureReading;
|
||||
import example.geode.query.cq.event.TemperatureReadingsContinuousQueriesHandler;
|
||||
|
||||
/**
|
||||
* Integration tests testing the auto-configuration of Apache Geode/Pivotal GemFire Continuous Query.
|
||||
*
|
||||
* @author John Blum
|
||||
* @see org.junit.Test
|
||||
* @see org.apache.geode.cache.GemFireCache
|
||||
* @see org.apache.geode.cache.Region
|
||||
* @see org.springframework.boot.autoconfigure.SpringBootApplication
|
||||
* @see org.springframework.boot.test.context.SpringBootTest
|
||||
* @see org.springframework.context.annotation.AnnotationConfigApplicationContext
|
||||
* @see org.springframework.context.annotation.Bean
|
||||
* @see org.springframework.data.gemfire.config.annotation.CacheServerApplication
|
||||
* @see org.springframework.data.gemfire.tests.integration.ForkingClientServerIntegrationTestsSupport
|
||||
* @see org.springframework.data.gemfire.tests.integration.config.SubscriptionEnabledClientServerIntegrationTestsConfiguration
|
||||
* @see org.springframework.geode.boot.autoconfigure.ContinuousQueryAutoConfiguration
|
||||
* @see org.springframework.test.context.junit4.SpringRunner
|
||||
* @see example.geode.query.cq.event.TemperatureReading
|
||||
* @see example.geode.query.cq.event.TemperatureReadingsContinuousQueriesHandler
|
||||
* @since 1.0.0
|
||||
*/
|
||||
@RunWith(SpringRunner.class)
|
||||
@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.NONE,
|
||||
classes = AutoConfiguredContinuousQueryIntegrationTests.GemFireClientConfiguration.class)
|
||||
@SuppressWarnings("unused")
|
||||
public class AutoConfiguredContinuousQueryIntegrationTests extends ForkingClientServerIntegrationTestsSupport {
|
||||
|
||||
private static final String GEMFIRE_LOG_LEVEL = "error";
|
||||
|
||||
@BeforeClass
|
||||
public static void startGemFireServer() throws IOException {
|
||||
startGemFireServer(GemFireServerConfiguration.class);
|
||||
}
|
||||
|
||||
@Autowired
|
||||
private GemfireTemplate temperatureReadingsTemplate;
|
||||
|
||||
@SuppressWarnings("all")
|
||||
@Resource(name = "TemperatureReadings")
|
||||
private Region<Long, TemperatureReading> temperatureReadings;
|
||||
|
||||
@Autowired
|
||||
private TemperatureReadingsContinuousQueriesHandler temperatureReadingsHandler;
|
||||
|
||||
@Before
|
||||
public void setup() {
|
||||
|
||||
Assertions.assertThat(this.temperatureReadingsTemplate.<Long, TemperatureReading>get(1L))
|
||||
.isEqualTo(TemperatureReading.of(99));
|
||||
|
||||
assertThat(this.temperatureReadings.sizeOnServer()).isEqualTo(8);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void assertTemperatureReadingsAreCorrect() {
|
||||
|
||||
Assertions.assertThat(this.temperatureReadingsHandler.getTemperatureReadingCount()).isEqualTo(4);
|
||||
Assertions.assertThat(this.temperatureReadingsHandler.getBoilingTemperatures()).contains(300, 242);
|
||||
Assertions.assertThat(this.temperatureReadingsHandler.getFreezingTemperatures()).contains(16, -51);
|
||||
}
|
||||
|
||||
@SpringBootApplication
|
||||
@EnableLogging(logLevel = GEMFIRE_LOG_LEVEL)
|
||||
public static class GemFireClientConfiguration
|
||||
extends SubscriptionEnabledClientServerIntegrationTestsConfiguration {
|
||||
|
||||
@Bean("TemperatureReadings")
|
||||
public ClientRegionFactoryBean<Long, TemperatureReading> temperatureReadingsRegion(GemFireCache gemfireCache) {
|
||||
|
||||
ClientRegionFactoryBean<Long, TemperatureReading> temperatureReadingsRegion =
|
||||
new ClientRegionFactoryBean<>();
|
||||
|
||||
temperatureReadingsRegion.setCache(gemfireCache);
|
||||
temperatureReadingsRegion.setClose(false);
|
||||
temperatureReadingsRegion.setShortcut(ClientRegionShortcut.PROXY);
|
||||
|
||||
return temperatureReadingsRegion;
|
||||
}
|
||||
|
||||
@Bean
|
||||
@DependsOn("TemperatureReadings")
|
||||
GemfireTemplate temperatureReadingsTemplate(GemFireCache gemfireCache) {
|
||||
return new GemfireTemplate(gemfireCache.getRegion("/TemperatureReadings"));
|
||||
}
|
||||
|
||||
@Bean
|
||||
@DependsOn("TemperatureReadings")
|
||||
TemperatureReadingsContinuousQueriesHandler temperatureReadingsHandler() {
|
||||
return new TemperatureReadingsContinuousQueriesHandler();
|
||||
}
|
||||
}
|
||||
|
||||
@EnablePdx
|
||||
@CacheServerApplication(name = "AutoConfiguredContinuousQueryIntegrationTests", logLevel = GEMFIRE_LOG_LEVEL)
|
||||
public static class GemFireServerConfiguration {
|
||||
|
||||
public static void main(String[] args) {
|
||||
|
||||
AnnotationConfigApplicationContext applicationContext =
|
||||
new AnnotationConfigApplicationContext(GemFireServerConfiguration.class);
|
||||
|
||||
applicationContext.registerShutdownHook();
|
||||
}
|
||||
|
||||
@Bean("TemperatureReadings")
|
||||
public PartitionedRegionFactoryBean<Long, TemperatureReading> temperatureReadingsRegion(GemFireCache gemfireCache) {
|
||||
|
||||
PartitionedRegionFactoryBean<Long, TemperatureReading> temperatureReadingsRegion =
|
||||
new PartitionedRegionFactoryBean<>();
|
||||
|
||||
temperatureReadingsRegion.setCache(gemfireCache);
|
||||
temperatureReadingsRegion.setCacheLoader(temperatureReadingsLoader());
|
||||
temperatureReadingsRegion.setClose(false);
|
||||
temperatureReadingsRegion.setPersistent(false);
|
||||
|
||||
return temperatureReadingsRegion;
|
||||
}
|
||||
|
||||
private CacheLoader<Long, TemperatureReading> temperatureReadingsLoader() {
|
||||
|
||||
return new CacheLoader<Long, TemperatureReading>() {
|
||||
|
||||
@Override
|
||||
public TemperatureReading load(LoaderHelper<Long, TemperatureReading> helper)
|
||||
throws CacheLoaderException {
|
||||
|
||||
long key = helper.getKey();
|
||||
|
||||
Region<Long, TemperatureReading> temperatureReadings = helper.getRegion();
|
||||
|
||||
recordTemperature(temperatureReadings, ++key, 72);
|
||||
recordTemperature(temperatureReadings, ++key, 16);
|
||||
recordTemperature(temperatureReadings, ++key, 101);
|
||||
recordTemperature(temperatureReadings, ++key, 300);
|
||||
recordTemperature(temperatureReadings, ++key, -51);
|
||||
recordTemperature(temperatureReadings, ++key, 242);
|
||||
recordTemperature(temperatureReadings, ++key, 112);
|
||||
|
||||
return TemperatureReading.of(99);
|
||||
}
|
||||
|
||||
private void recordTemperature(Region<Long, TemperatureReading> temperatureReadings,
|
||||
long key, int temperature) {
|
||||
|
||||
sleep(50);
|
||||
temperatureReadings.put(key, TemperatureReading.of(temperature));
|
||||
}
|
||||
|
||||
@SuppressWarnings("all")
|
||||
private void sleep(long milliseconds) {
|
||||
|
||||
try {
|
||||
Thread.sleep(milliseconds);
|
||||
}
|
||||
catch (InterruptedException ignore) {
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void close() { }
|
||||
|
||||
};
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,176 @@
|
||||
/*
|
||||
* Copyright 2018 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
|
||||
*
|
||||
* http://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 org.springframework.geode.boot.autoconfigure.function;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
|
||||
import java.lang.reflect.Method;
|
||||
import java.util.Arrays;
|
||||
import java.util.Iterator;
|
||||
import java.util.Optional;
|
||||
|
||||
import org.apache.geode.cache.GemFireCache;
|
||||
import org.apache.geode.cache.execute.FunctionService;
|
||||
import org.apache.shiro.util.Assert;
|
||||
import org.junit.FixMethodOrder;
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
import org.junit.runners.MethodSorters;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.boot.autoconfigure.SpringBootApplication;
|
||||
import org.springframework.boot.test.context.SpringBootTest;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.data.gemfire.config.annotation.EnableGemFireProperties;
|
||||
import org.springframework.data.gemfire.config.annotation.EnableLogging;
|
||||
import org.springframework.data.gemfire.function.annotation.GemfireFunction;
|
||||
import org.springframework.data.gemfire.tests.integration.IntegrationTestsSupport;
|
||||
import org.springframework.geode.boot.autoconfigure.function.executions.Calculator;
|
||||
import org.springframework.test.context.junit4.SpringRunner;
|
||||
|
||||
/**
|
||||
* Integration tests testing the auto-configuration of Spring Data for Apache Geode/Pivotal GemFire
|
||||
* Function implementations and executions support.
|
||||
*
|
||||
* @author John Blum
|
||||
* @see org.junit.Test
|
||||
* @see org.apache.geode.cache.GemFireCache
|
||||
* @see org.apache.geode.cache.execute.FunctionService
|
||||
* @see org.springframework.boot.autoconfigure.SpringBootApplication
|
||||
* @see org.springframework.boot.test.context.SpringBootTest
|
||||
* @see org.springframework.context.annotation.Bean
|
||||
* @see org.springframework.data.gemfire.function.annotation.GemfireFunction
|
||||
* @see org.springframework.data.gemfire.tests.integration.IntegrationTestsSupport
|
||||
* @see org.springframework.geode.boot.autoconfigure.function.executions.Calculator
|
||||
* @see org.springframework.geode.boot.autoconfigure.FunctionExecutionAutoConfiguration
|
||||
* @see org.springframework.test.context.junit4.SpringRunner
|
||||
* @since 1.0.0
|
||||
*/
|
||||
@RunWith(SpringRunner.class)
|
||||
@FixMethodOrder(MethodSorters.NAME_ASCENDING)
|
||||
@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.NONE)
|
||||
@SuppressWarnings("unused")
|
||||
public class AutoConfiguredFunctionExecutionsIntegrationTests extends IntegrationTestsSupport {
|
||||
|
||||
private static final String GEMFIRE_LOG_LEVEL = "error";
|
||||
|
||||
@Autowired
|
||||
private GemFireCache gemfireCache;
|
||||
|
||||
@Autowired
|
||||
private Calculator calculator;
|
||||
|
||||
@Test
|
||||
public void cacheClientIsInGroupTest() {
|
||||
|
||||
assertThat(this.gemfireCache).isNotNull();
|
||||
assertThat(this.gemfireCache.getDistributedSystem().getGroupMembers("test"))
|
||||
.contains(this.gemfireCache.getDistributedSystem().getDistributedMember());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void firstFunctionsMustBeRegistered() {
|
||||
|
||||
Arrays.stream(CalculatorFunctions.class.getMethods())
|
||||
.filter(method -> !Object.class.equals(method.getDeclaringClass()))
|
||||
.map(Method::getName)
|
||||
.forEach(methodName -> assertThat(FunctionService.isRegistered(methodName))
|
||||
.describedAs("Function [%s] was not registered", methodName)
|
||||
.isTrue());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void thenCalculationsAreCorrect() {
|
||||
|
||||
assertThat(this.calculator).isNotNull();
|
||||
assertThat(extractResult(this.calculator.add(8.0d, 8.0d))).isEqualTo(16.0d);
|
||||
assertThat(extractResult(this.calculator.divide(16.0d, 4.0d))).isEqualTo(4.0d);
|
||||
assertThat(extractResult(this.calculator.factorial(5L))).isEqualTo(120L);
|
||||
assertThat(extractResult(this.calculator.multiply(4.0d, 4.0d))).isEqualTo(16.0d);
|
||||
assertThat(extractResult(this.calculator.squared(4.0d))).isEqualTo(16.0d);
|
||||
assertThat(extractResult(this.calculator.squareRoot(16.0d))).isEqualTo(4.0d);
|
||||
assertThat(extractResult(this.calculator.subtract(16.0d, 8.0d))).isEqualTo(8.0d);
|
||||
}
|
||||
|
||||
private Object extractResult(Object result) {
|
||||
|
||||
return Optional.ofNullable(result)
|
||||
.filter(it -> it instanceof Iterable)
|
||||
.map(it -> ((Iterable) it).iterator())
|
||||
.filter(Iterator::hasNext)
|
||||
.map(Iterator::next)
|
||||
.map(this::extractResult)
|
||||
.orElse(result);
|
||||
}
|
||||
|
||||
@SpringBootApplication
|
||||
@EnableGemFireProperties(groups = "test")
|
||||
@EnableLogging(logLevel = GEMFIRE_LOG_LEVEL)
|
||||
static class TestConfiguration {
|
||||
|
||||
@Bean
|
||||
public CalculatorFunctions calculatorFunctions(GemFireCache gemfireCache) {
|
||||
return new CalculatorFunctions();
|
||||
}
|
||||
}
|
||||
|
||||
public static class CalculatorFunctions {
|
||||
|
||||
@GemfireFunction(id = "add", hasResult = true)
|
||||
public double add(double operandOne, double operandTwo) {
|
||||
return operandOne + operandTwo;
|
||||
}
|
||||
|
||||
@GemfireFunction(id = "divide", hasResult = true)
|
||||
public double divide(double numerator, double divisor) {
|
||||
return numerator / divisor;
|
||||
}
|
||||
|
||||
@GemfireFunction(id = "factorial", hasResult = true)
|
||||
public long factorial(long number) {
|
||||
|
||||
Assert.isTrue(number > -1, "Number be greater than -1");
|
||||
|
||||
long result = number == 2 ? 2 : 1;
|
||||
|
||||
while (number > 1) {
|
||||
result *= number--;
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
@GemfireFunction(id = "multiply", hasResult = true)
|
||||
public double multiply(double operandOne, double operandTwo) {
|
||||
return operandOne * operandTwo;
|
||||
}
|
||||
|
||||
@GemfireFunction(id = "squareRoot", hasResult = true)
|
||||
public double squareRoot(double number) {
|
||||
return Math.sqrt(number);
|
||||
}
|
||||
|
||||
@GemfireFunction(id = "squared", hasResult = true)
|
||||
public double squared(double number) {
|
||||
return number * number;
|
||||
}
|
||||
|
||||
@GemfireFunction(id = "subtract", hasResult = true)
|
||||
public double subtract(double operandOne, double operandTwo) {
|
||||
return operandOne - operandTwo;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,47 @@
|
||||
/*
|
||||
* Copyright 2018 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
|
||||
*
|
||||
* http://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 org.springframework.geode.boot.autoconfigure.function.executions;
|
||||
|
||||
import org.springframework.data.gemfire.function.annotation.OnMember;
|
||||
|
||||
/**
|
||||
* The {@link Calculator} interface defines Apache Geode/Pivotal GemFire Functions.
|
||||
*
|
||||
* @author John Blum
|
||||
* @see org.springframework.data.gemfire.function.annotation.OnRegion
|
||||
* @since 1.0.0
|
||||
*/
|
||||
@OnMember(groups = "test")
|
||||
@SuppressWarnings("all")
|
||||
// TODO change Function returns type when SDG properly handles Function method return types/values
|
||||
public interface Calculator {
|
||||
|
||||
Object add(double operandOne, double operandTwo);
|
||||
|
||||
Object divide(double numerator, double divisor);
|
||||
|
||||
Object factorial(long number);
|
||||
|
||||
Object multiply(double operandOne, double operandTwo);
|
||||
|
||||
Object squareRoot(double number);
|
||||
|
||||
Object squared(double number);
|
||||
|
||||
Object subtract(double operandOne, double operandTwo);
|
||||
|
||||
}
|
||||
@@ -0,0 +1,108 @@
|
||||
/*
|
||||
* Copyright 2018 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
|
||||
*
|
||||
* http://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 org.springframework.geode.boot.autoconfigure.repository;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
|
||||
import javax.annotation.Resource;
|
||||
|
||||
import org.apache.geode.cache.Region;
|
||||
import org.apache.geode.cache.client.ClientRegionShortcut;
|
||||
import org.junit.FixMethodOrder;
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
import org.junit.runners.MethodSorters;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.boot.autoconfigure.SpringBootApplication;
|
||||
import org.springframework.boot.test.context.SpringBootTest;
|
||||
import org.springframework.data.gemfire.config.annotation.EnableEntityDefinedRegions;
|
||||
import org.springframework.data.gemfire.config.annotation.EnableLogging;
|
||||
import org.springframework.data.gemfire.tests.integration.IntegrationTestsSupport;
|
||||
import org.springframework.data.gemfire.util.RegionUtils;
|
||||
import org.springframework.geode.boot.autoconfigure.repository.model.Customer;
|
||||
import org.springframework.geode.boot.autoconfigure.repository.service.CustomerService;
|
||||
import org.springframework.test.context.junit4.SpringRunner;
|
||||
|
||||
/**
|
||||
* Integration tests testing the auto-configuration of Spring Data Repositories backed by either Apache Geode
|
||||
* or Pivotal GemFire.
|
||||
*
|
||||
* @author John Blum
|
||||
* @see org.junit.Test
|
||||
* @see org.apache.geode.cache.Region
|
||||
* @see org.springframework.boot.autoconfigure.SpringBootApplication
|
||||
* @see org.springframework.boot.test.context.SpringBootTest
|
||||
* @see org.springframework.data.gemfire.config.annotation.EnableEntityDefinedRegions
|
||||
* @see org.springframework.data.gemfire.tests.integration.IntegrationTestsSupport
|
||||
* @see org.springframework.geode.boot.autoconfigure.RepositoriesAutoConfiguration
|
||||
* @see org.springframework.test.context.junit4.SpringRunner
|
||||
* @since 1.0.0
|
||||
*/
|
||||
@RunWith(SpringRunner.class)
|
||||
@FixMethodOrder(MethodSorters.NAME_ASCENDING)
|
||||
@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.NONE)
|
||||
@SuppressWarnings("unused")
|
||||
public class AutoConfiguredRepositoriesIntegrationTests extends IntegrationTestsSupport {
|
||||
|
||||
private static final String GEMFIRE_LOG_LEVEL = "error";
|
||||
|
||||
@Autowired
|
||||
private CustomerService customerService;
|
||||
|
||||
@Resource(name = "Customers")
|
||||
private Region<Long, Customer> customers;
|
||||
|
||||
@Test
|
||||
public void customerServiceWasConfiguredCorrectly() {
|
||||
|
||||
assertThat(this.customerService).isNotNull();
|
||||
assertThat(this.customerService.getCustomerRepository()).isNotNull();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void customersRegionWasConfiguredCorrectly() {
|
||||
|
||||
assertThat(this.customers).isNotNull();
|
||||
assertThat(this.customers.getName()).isEqualTo("Customers");
|
||||
assertThat(this.customers.getFullPath()).isEqualTo(RegionUtils.toRegionPath("Customers"));
|
||||
assertThat(this.customers).isEmpty();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void repositoryWasAutoConfiguredCorrectly() {
|
||||
|
||||
Customer jonDoe = Customer.newCustomer("Jon Doe");
|
||||
|
||||
assertThat(jonDoe).isNotNull();
|
||||
assertThat(jonDoe.getName()).isEqualTo("Jon Doe");
|
||||
assertThat(jonDoe.isNew()).isTrue();
|
||||
|
||||
jonDoe = this.customerService.save(jonDoe);
|
||||
|
||||
assertThat(jonDoe.isNew()).isFalse();
|
||||
assertThat(this.customers.get(jonDoe.getId())).isEqualTo(jonDoe);
|
||||
assertThat(this.customerService.findBy(jonDoe.getName()).orElse(null)).isEqualTo(jonDoe);
|
||||
|
||||
}
|
||||
|
||||
@SpringBootApplication
|
||||
@EnableLogging(logLevel = GEMFIRE_LOG_LEVEL)
|
||||
@EnableEntityDefinedRegions(basePackageClasses = Customer.class,
|
||||
clientRegionShortcut = ClientRegionShortcut.LOCAL)
|
||||
static class TestConfiguration { }
|
||||
|
||||
}
|
||||
@@ -0,0 +1,54 @@
|
||||
/*
|
||||
* Copyright 2018 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
|
||||
*
|
||||
* http://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 org.springframework.geode.boot.autoconfigure.repository.model;
|
||||
|
||||
import org.springframework.data.annotation.Id;
|
||||
import org.springframework.data.gemfire.mapping.annotation.Region;
|
||||
|
||||
import lombok.Data;
|
||||
import lombok.NonNull;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
|
||||
/**
|
||||
* {@link Customer} class and Abstract Data Type (ADT) modeling a customer.
|
||||
*
|
||||
* @author John Blum
|
||||
* @see lombok
|
||||
* @see org.springframework.data.annotation.Id
|
||||
* @see org.springframework.data.gemfire.mapping.annotation.Region
|
||||
* @since 1.0.0
|
||||
*/
|
||||
@Data
|
||||
@Region("Customers")
|
||||
@RequiredArgsConstructor(staticName = "newCustomer")
|
||||
public class Customer {
|
||||
|
||||
@Id
|
||||
private Long id;
|
||||
|
||||
@NonNull
|
||||
private String name;
|
||||
|
||||
public boolean isNew() {
|
||||
return getId() == null;
|
||||
}
|
||||
|
||||
public Customer identifiedBy(Long id) {
|
||||
setId(id);
|
||||
return this;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,35 @@
|
||||
/*
|
||||
* Copyright 2018 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
|
||||
*
|
||||
* http://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 org.springframework.geode.boot.autoconfigure.repository.repo;
|
||||
|
||||
import org.springframework.data.repository.CrudRepository;
|
||||
import org.springframework.geode.boot.autoconfigure.repository.model.Customer;
|
||||
|
||||
/**
|
||||
* The {@link CustomerRepository} interface defines a Spring Data {@link CrudRepository} for performing basic CRUD
|
||||
* and simple query data access operations on {@link Customer} objects stored in Apache Geode or Pivotal GemFire.
|
||||
*
|
||||
* @author John Blum
|
||||
* @see org.springframework.data.repository.CrudRepository
|
||||
* @see org.springframework.geode.boot.autoconfigure.repository.model.Customer
|
||||
* @since 1.0.0
|
||||
*/
|
||||
public interface CustomerRepository extends CrudRepository<Customer, Long> {
|
||||
|
||||
Customer findByName(String name);
|
||||
|
||||
}
|
||||
@@ -0,0 +1,76 @@
|
||||
/*
|
||||
* Copyright 2018 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
|
||||
*
|
||||
* http://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 org.springframework.geode.boot.autoconfigure.repository.service;
|
||||
|
||||
import static org.springframework.data.gemfire.util.RuntimeExceptionFactory.newIllegalArgumentException;
|
||||
import static org.springframework.data.gemfire.util.RuntimeExceptionFactory.newIllegalStateException;
|
||||
|
||||
import java.util.Optional;
|
||||
import java.util.concurrent.atomic.AtomicLong;
|
||||
|
||||
import org.springframework.geode.boot.autoconfigure.repository.model.Customer;
|
||||
import org.springframework.geode.boot.autoconfigure.repository.repo.CustomerRepository;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
/**
|
||||
* The {@link CustomerService} class is an application service for managing {@link Customer Customers}.
|
||||
*
|
||||
* @author John Blum
|
||||
* @see org.springframework.geode.boot.autoconfigure.repository.model.Customer
|
||||
* @see org.springframework.geode.boot.autoconfigure.repository.repo.CustomerRepository
|
||||
* @see org.springframework.stereotype.Service
|
||||
* @since 1.0.0
|
||||
*/
|
||||
@Service
|
||||
public class CustomerService {
|
||||
|
||||
private final CustomerRepository customerRepository;
|
||||
|
||||
private final AtomicLong identifierSequence = new AtomicLong(0L);
|
||||
|
||||
public CustomerService(CustomerRepository customerRepository) {
|
||||
this.customerRepository = customerRepository;
|
||||
}
|
||||
|
||||
public CustomerRepository getCustomerRepository() {
|
||||
|
||||
return Optional.ofNullable(this.customerRepository)
|
||||
.orElseThrow(() -> newIllegalStateException("CustomerRepository was not properly configured"));
|
||||
}
|
||||
|
||||
public Optional<Customer> findBy(String name) {
|
||||
return Optional.ofNullable(getCustomerRepository().findByName(name));
|
||||
}
|
||||
|
||||
protected Long nextId() {
|
||||
return identifierSequence.incrementAndGet();
|
||||
}
|
||||
|
||||
public Customer save(Customer customer) {
|
||||
|
||||
return Optional.ofNullable(customer)
|
||||
.map(it -> {
|
||||
|
||||
if (customer.isNew()) {
|
||||
customer.identifiedBy(nextId());
|
||||
}
|
||||
|
||||
return getCustomerRepository().save(customer);
|
||||
})
|
||||
.orElseThrow(() -> newIllegalArgumentException("Customer is required"));
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,175 @@
|
||||
/*
|
||||
* Copyright 2018 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
|
||||
*
|
||||
* http://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 org.springframework.geode.boot.autoconfigure.security.auth;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
import static org.springframework.data.gemfire.config.annotation.support.AutoConfiguredAuthenticationInitializer.SECURITY_PASSWORD_PROPERTY;
|
||||
import static org.springframework.data.gemfire.config.annotation.support.AutoConfiguredAuthenticationInitializer.SECURITY_USERNAME_PROPERTY;
|
||||
import static org.springframework.data.gemfire.util.ArrayUtils.nullSafeArray;
|
||||
import static org.springframework.data.gemfire.util.RuntimeExceptionFactory.newIllegalArgumentException;
|
||||
import static org.springframework.data.gemfire.util.RuntimeExceptionFactory.newIllegalStateException;
|
||||
|
||||
import java.io.Serializable;
|
||||
import java.security.Principal;
|
||||
import java.util.Arrays;
|
||||
import java.util.Optional;
|
||||
import java.util.Properties;
|
||||
|
||||
import org.apache.geode.security.AuthenticationFailedException;
|
||||
import org.apache.geode.security.ResourcePermission;
|
||||
import org.junit.Test;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
import org.springframework.context.annotation.Import;
|
||||
import org.springframework.core.env.Environment;
|
||||
import org.springframework.core.io.ClassPathResource;
|
||||
import org.springframework.data.gemfire.GemfireTemplate;
|
||||
import org.springframework.data.gemfire.tests.integration.ForkingClientServerIntegrationTestsSupport;
|
||||
import org.springframework.util.Assert;
|
||||
import org.springframework.util.StringUtils;
|
||||
|
||||
import example.echo.config.EchoClientConfiguration;
|
||||
import example.echo.config.EchoServerConfiguration;
|
||||
import lombok.Data;
|
||||
import lombok.EqualsAndHashCode;
|
||||
import lombok.NonNull;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import lombok.ToString;
|
||||
|
||||
/**
|
||||
* The {@link AbstractAutoConfiguredSecurityContextIntegrationTests} class is an abstract security context integration test class
|
||||
* encapsulating configuration and functionality common to both cloud and local security context integration tests.
|
||||
*
|
||||
* @author John Blum
|
||||
* @see java.security.Principal
|
||||
* @see org.apache.geode.cache.GemFireCache
|
||||
* @see org.apache.geode.security.ResourcePermission
|
||||
* @see org.springframework.core.env.Environment
|
||||
* @see org.springframework.data.gemfire.GemfireTemplate
|
||||
* @see org.springframework.data.gemfire.tests.integration.ForkingClientServerIntegrationTestsSupport
|
||||
* @since 1.0.0
|
||||
*/
|
||||
@SuppressWarnings("unused")
|
||||
public abstract class AbstractAutoConfiguredSecurityContextIntegrationTests
|
||||
extends ForkingClientServerIntegrationTestsSupport {
|
||||
|
||||
private static final String SECURITY_CONTEXT_USERNAME_PROPERTY = "security.context.username.property";
|
||||
private static final String SECURITY_CONTEXT_PASSWORD_PROPERTY = "security.context.password.property";
|
||||
|
||||
@Autowired
|
||||
private GemfireTemplate echoTemplate;
|
||||
|
||||
@Test
|
||||
public void clientServerAuthWasSuccessful() {
|
||||
|
||||
assertThat(this.echoTemplate.<String, String>get("Hello")).isEqualTo("Hello");
|
||||
assertThat(this.echoTemplate.<String, String>get("Test")).isEqualTo("Test");
|
||||
assertThat(this.echoTemplate.<String, String>get("Good-Bye")).isEqualTo("Good-Bye");
|
||||
}
|
||||
|
||||
@Configuration
|
||||
@Import(EchoClientConfiguration.class)
|
||||
protected static abstract class BaseGemFireClientConfiguration { }
|
||||
|
||||
@Configuration
|
||||
@Import(EchoServerConfiguration.class)
|
||||
protected static abstract class BaseGemFireServerConfiguration {
|
||||
|
||||
@Bean
|
||||
TestSecurityManager testSecurityManager(Environment environment) {
|
||||
return new TestSecurityManager(environment);
|
||||
}
|
||||
}
|
||||
|
||||
public static class TestSecurityManager implements org.apache.geode.security.SecurityManager {
|
||||
|
||||
private final String username;
|
||||
private final String password;
|
||||
|
||||
public TestSecurityManager(Environment environment) {
|
||||
|
||||
this.username = Optional.ofNullable(environment.getProperty(SECURITY_CONTEXT_USERNAME_PROPERTY))
|
||||
.filter(StringUtils::hasText)
|
||||
.orElseThrow(() -> newIllegalArgumentException("Username is required"));
|
||||
|
||||
this.password = Optional.ofNullable(environment.getProperty(SECURITY_CONTEXT_PASSWORD_PROPERTY))
|
||||
.filter(StringUtils::hasText)
|
||||
.orElseThrow(() -> newIllegalArgumentException("Password is required"));
|
||||
}
|
||||
|
||||
private ClassPathResource resolveApplicationProperties(Environment environment) {
|
||||
|
||||
Assert.notNull(environment, "Environment must not be null");
|
||||
|
||||
return Arrays.stream(nullSafeArray(environment.getActiveProfiles(), String.class))
|
||||
.filter(StringUtils::hasText)
|
||||
.filter(it -> !"default".equalsIgnoreCase(it))
|
||||
.map(it -> String.format("application-%s.properties", it))
|
||||
.map(ClassPathResource::new)
|
||||
.filter(ClassPathResource::exists)
|
||||
.findFirst()
|
||||
.orElseThrow(() ->
|
||||
newIllegalStateException("Unable to resolve application.properties from Environment [%s]",
|
||||
environment));
|
||||
|
||||
}
|
||||
|
||||
String getUsername() {
|
||||
return username;
|
||||
}
|
||||
|
||||
String getPassword() {
|
||||
return password;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object authenticate(Properties credentials) throws AuthenticationFailedException {
|
||||
|
||||
String username = credentials.getProperty(SECURITY_USERNAME_PROPERTY);
|
||||
String password = credentials.getProperty(SECURITY_PASSWORD_PROPERTY);
|
||||
|
||||
if (!(getUsername().equals(username) && getPassword().equals(password))) {
|
||||
throw new AuthenticationFailedException(String.format("Failed to authenticate user [%s]", username));
|
||||
}
|
||||
|
||||
return User.with(username).having(password);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean authorize(Object principal, ResourcePermission permission) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
@Data
|
||||
@ToString(of = "name")
|
||||
@EqualsAndHashCode(of = "name")
|
||||
@RequiredArgsConstructor(staticName = "with")
|
||||
static class User implements Principal, Serializable {
|
||||
|
||||
@NonNull
|
||||
private String name;
|
||||
|
||||
private String password;
|
||||
|
||||
User having(String password) {
|
||||
setPassword(password);
|
||||
return this;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,108 @@
|
||||
/*
|
||||
* Copyright 2018 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
|
||||
*
|
||||
* http://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 org.springframework.geode.boot.autoconfigure.security.auth.cloud;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.Properties;
|
||||
|
||||
import org.junit.AfterClass;
|
||||
import org.junit.BeforeClass;
|
||||
import org.junit.runner.RunWith;
|
||||
import org.springframework.boot.SpringApplication;
|
||||
import org.springframework.boot.autoconfigure.SpringBootApplication;
|
||||
import org.springframework.boot.test.context.SpringBootTest;
|
||||
import org.springframework.core.io.ClassPathResource;
|
||||
import org.springframework.data.gemfire.config.annotation.CacheServerApplication;
|
||||
import org.springframework.data.gemfire.config.annotation.EnableLocator;
|
||||
import org.springframework.data.gemfire.config.annotation.EnableLogging;
|
||||
import org.springframework.data.gemfire.support.GemfireBeanFactoryLocator;
|
||||
import org.springframework.geode.boot.autoconfigure.security.auth.AbstractAutoConfiguredSecurityContextIntegrationTests;
|
||||
import org.springframework.test.annotation.DirtiesContext;
|
||||
import org.springframework.test.context.junit4.SpringRunner;
|
||||
|
||||
/**
|
||||
* Integration test testing the auto-configuration of Apache Geode/Pivotal GemFire Security
|
||||
* authentication/authorization in a cloud, managed context (e.g. Pivotal CloudFoundry)
|
||||
*
|
||||
* @author John Blum
|
||||
* @see java.security.Principal
|
||||
* @see java.util.Properties
|
||||
* @see org.junit.Test
|
||||
* @see org.apache.geode.cache.GemFireCache
|
||||
* @see org.springframework.boot.SpringApplication
|
||||
* @see org.springframework.boot.autoconfigure.SpringBootApplication
|
||||
* @see org.springframework.boot.test.context.SpringBootTest
|
||||
* @see org.springframework.data.gemfire.config.annotation.CacheServerApplication
|
||||
* @see org.springframework.data.gemfire.config.annotation.EnableLocator
|
||||
* @see org.springframework.data.gemfire.config.annotation.EnableSecurity
|
||||
* @see org.springframework.geode.boot.autoconfigure.ClientSecurityAutoConfiguration
|
||||
* @see org.springframework.geode.boot.autoconfigure.PeerSecurityAutoConfiguration
|
||||
* @see org.springframework.geode.boot.autoconfigure.security.auth.AbstractAutoConfiguredSecurityContextIntegrationTests
|
||||
* @see org.springframework.test.annotation.DirtiesContext
|
||||
* @see org.springframework.test.context.junit4.SpringRunner
|
||||
* @since 1.0.0
|
||||
*/
|
||||
@DirtiesContext
|
||||
@RunWith(SpringRunner.class)
|
||||
@SpringBootTest(classes = AutoConfiguredCloudSecurityContextIntegrationTests.GemFireClientConfiguration.class,
|
||||
webEnvironment = SpringBootTest.WebEnvironment.NONE)
|
||||
@SuppressWarnings("unused")
|
||||
public class AutoConfiguredCloudSecurityContextIntegrationTests
|
||||
extends AbstractAutoConfiguredSecurityContextIntegrationTests {
|
||||
|
||||
private static final String GEMFIRE_LOG_LEVEL = "error";
|
||||
private static final String VCAP_APPLICATION_PROPERTIES = "application-vcap.properties";
|
||||
|
||||
private static Properties vcapApplicationProperties = new Properties();
|
||||
|
||||
@BeforeClass
|
||||
public static void startGemFireServer() throws IOException {
|
||||
|
||||
startGemFireServer(GemFireServerConfiguration.class, "-Dspring.profiles.active=security-cloud");
|
||||
|
||||
loadVcapApplicationProperties();
|
||||
|
||||
GemfireBeanFactoryLocator.clear();
|
||||
}
|
||||
|
||||
public static void loadVcapApplicationProperties() throws IOException {
|
||||
|
||||
vcapApplicationProperties.load(new ClassPathResource(VCAP_APPLICATION_PROPERTIES).getInputStream());
|
||||
|
||||
vcapApplicationProperties.stringPropertyNames().forEach(property ->
|
||||
System.setProperty(property, vcapApplicationProperties.getProperty(property)));
|
||||
}
|
||||
|
||||
@AfterClass
|
||||
public static void cleanUpUsedResources() {
|
||||
vcapApplicationProperties.stringPropertyNames().forEach(System::clearProperty);
|
||||
}
|
||||
|
||||
@SpringBootApplication
|
||||
@EnableLogging(logLevel = GEMFIRE_LOG_LEVEL)
|
||||
static class GemFireClientConfiguration extends BaseGemFireClientConfiguration { }
|
||||
|
||||
@SpringBootApplication
|
||||
@CacheServerApplication(name = "AutoConfiguredCloudSecurityContextIntegrationTests", logLevel = GEMFIRE_LOG_LEVEL)
|
||||
@EnableLocator(port = 55221)
|
||||
static class GemFireServerConfiguration extends BaseGemFireServerConfiguration {
|
||||
|
||||
public static void main(String[] args) {
|
||||
SpringApplication.run(GemFireServerConfiguration.class, args);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,92 @@
|
||||
/*
|
||||
* Copyright 2018 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
|
||||
*
|
||||
* http://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 org.springframework.geode.boot.autoconfigure.security.auth.local;
|
||||
|
||||
import java.io.IOException;
|
||||
|
||||
import org.junit.BeforeClass;
|
||||
import org.junit.runner.RunWith;
|
||||
import org.springframework.boot.SpringApplication;
|
||||
import org.springframework.boot.autoconfigure.SpringBootApplication;
|
||||
import org.springframework.boot.test.context.SpringBootTest;
|
||||
import org.springframework.context.annotation.Import;
|
||||
import org.springframework.data.gemfire.config.annotation.CacheServerApplication;
|
||||
import org.springframework.data.gemfire.config.annotation.EnableLogging;
|
||||
import org.springframework.data.gemfire.support.GemfireBeanFactoryLocator;
|
||||
import org.springframework.data.gemfire.tests.integration.config.ClientServerIntegrationTestsConfiguration;
|
||||
import org.springframework.geode.boot.autoconfigure.security.auth.AbstractAutoConfiguredSecurityContextIntegrationTests;
|
||||
import org.springframework.test.annotation.DirtiesContext;
|
||||
import org.springframework.test.context.ActiveProfiles;
|
||||
import org.springframework.test.context.junit4.SpringRunner;
|
||||
|
||||
/**
|
||||
* Integration test testing the auto-configuration of Apache Geode/Pivotal GemFire Security
|
||||
* authentication/authorization in a local, non-managed context.
|
||||
*
|
||||
* @author John Blum
|
||||
* @see java.security.Principal
|
||||
* @see org.junit.Test
|
||||
* @see org.apache.geode.cache.GemFireCache
|
||||
* @see org.springframework.boot.SpringApplication
|
||||
* @see org.springframework.boot.autoconfigure.SpringBootApplication
|
||||
* @see org.springframework.boot.test.context.SpringBootTest
|
||||
* @see org.springframework.context.annotation.Import
|
||||
* @see org.springframework.data.gemfire.config.annotation.CacheServerApplication
|
||||
* @see org.springframework.data.gemfire.config.annotation.EnableSecurity
|
||||
* @see org.springframework.data.gemfire.tests.integration.config.ClientServerIntegrationTestsConfiguration
|
||||
* @see org.springframework.geode.boot.autoconfigure.ClientSecurityAutoConfiguration
|
||||
* @see org.springframework.geode.boot.autoconfigure.PeerSecurityAutoConfiguration
|
||||
* @see org.springframework.geode.boot.autoconfigure.security.auth.AbstractAutoConfiguredSecurityContextIntegrationTests
|
||||
* @see org.springframework.test.annotation.DirtiesContext
|
||||
* @see org.springframework.test.context.ActiveProfiles
|
||||
* @see org.springframework.test.context.junit4.SpringRunner
|
||||
* @since 1.0.0
|
||||
*/
|
||||
@ActiveProfiles("security-local-client")
|
||||
@DirtiesContext
|
||||
@RunWith(SpringRunner.class)
|
||||
@SpringBootTest(classes = AutoConfiguredLocalSecurityContextIntegrationTests.GemFireClientConfiguration.class,
|
||||
webEnvironment = SpringBootTest.WebEnvironment.NONE)
|
||||
@SuppressWarnings("unused")
|
||||
public class AutoConfiguredLocalSecurityContextIntegrationTests
|
||||
extends AbstractAutoConfiguredSecurityContextIntegrationTests {
|
||||
|
||||
private static final String GEMFIRE_LOG_LEVEL = "error";
|
||||
|
||||
@BeforeClass
|
||||
public static void startGemFireServer() throws IOException {
|
||||
|
||||
GemfireBeanFactoryLocator.clear();
|
||||
|
||||
startGemFireServer(GemFireServerConfiguration.class,
|
||||
"-Dspring.profiles.active=security-local-server");
|
||||
}
|
||||
|
||||
@SpringBootApplication
|
||||
@EnableLogging(logLevel = GEMFIRE_LOG_LEVEL)
|
||||
@Import(ClientServerIntegrationTestsConfiguration.class)
|
||||
static class GemFireClientConfiguration extends BaseGemFireClientConfiguration { }
|
||||
|
||||
@SpringBootApplication
|
||||
@CacheServerApplication(name = "AutoConfiguredLocalSecurityContextIntegrationTests", logLevel = GEMFIRE_LOG_LEVEL)
|
||||
static class GemFireServerConfiguration extends BaseGemFireServerConfiguration {
|
||||
|
||||
public static void main(String[] args) {
|
||||
SpringApplication.run(GemFireServerConfiguration.class, args);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,119 @@
|
||||
/*
|
||||
* Copyright 2018 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
|
||||
*
|
||||
* http://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 org.springframework.geode.boot.autoconfigure.security.ssl;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.List;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
import org.junit.AfterClass;
|
||||
import org.junit.BeforeClass;
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.boot.SpringApplication;
|
||||
import org.springframework.boot.autoconfigure.SpringBootApplication;
|
||||
import org.springframework.boot.test.context.SpringBootTest;
|
||||
import org.springframework.context.annotation.Import;
|
||||
import org.springframework.data.gemfire.GemfireTemplate;
|
||||
import org.springframework.data.gemfire.config.annotation.CacheServerApplication;
|
||||
import org.springframework.data.gemfire.config.annotation.EnableLogging;
|
||||
import org.springframework.data.gemfire.tests.integration.ForkingClientServerIntegrationTestsSupport;
|
||||
import org.springframework.data.gemfire.tests.integration.config.ClientServerIntegrationTestsConfiguration;
|
||||
import org.springframework.test.context.ActiveProfiles;
|
||||
import org.springframework.test.context.junit4.SpringRunner;
|
||||
|
||||
import example.echo.config.EchoClientConfiguration;
|
||||
import example.echo.config.EchoServerConfiguration;
|
||||
|
||||
/**
|
||||
* Integration tests testing the auto-configuration of Apache Geode/Pivotal GemFire SSL.
|
||||
*
|
||||
* @author John Blum
|
||||
* @see org.junit.Test
|
||||
* @see org.apache.geode.cache.GemFireCache
|
||||
* @see org.apache.geode.cache.Region
|
||||
* @see org.springframework.boot.autoconfigure.SpringBootApplication
|
||||
* @see org.springframework.boot.test.context.SpringBootTest
|
||||
* @see org.springframework.context.annotation.Import
|
||||
* @see org.springframework.data.gemfire.GemfireTemplate
|
||||
* @see org.springframework.data.gemfire.config.annotation.CacheServerApplication
|
||||
* @see org.springframework.data.gemfire.config.annotation.EnableSsl
|
||||
* @see org.springframework.data.gemfire.tests.integration.ForkingClientServerIntegrationTestsSupport
|
||||
* @see org.springframework.data.gemfire.tests.integration.config.ClientServerIntegrationTestsConfiguration
|
||||
* @see org.springframework.test.context.ActiveProfiles
|
||||
* @see org.springframework.test.context.junit4.SpringRunner
|
||||
* @since 1.0.0
|
||||
*/
|
||||
@ActiveProfiles("ssl")
|
||||
@RunWith(SpringRunner.class)
|
||||
@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.NONE,
|
||||
classes = AutoConfiguredSslIntegrationTests.GemFireClientConfiguration.class)
|
||||
@SuppressWarnings("unused")
|
||||
public class AutoConfiguredSslIntegrationTests extends ForkingClientServerIntegrationTestsSupport {
|
||||
|
||||
private static final String GEMFIRE_LOG_LEVEL = "error";
|
||||
private static final String TRUSTED_KEYSTORE_FILENAME = "test-trusted.keystore";
|
||||
|
||||
@BeforeClass
|
||||
public static void startGemFireServer() throws IOException {
|
||||
startGemFireServer(GemFireServerConfiguration.class, "-Dspring.profiles.active=ssl");
|
||||
}
|
||||
|
||||
@AfterClass
|
||||
public static void clearSslSystemProperties() {
|
||||
|
||||
List<String> sslSystemProperties = System.getProperties().keySet().stream()
|
||||
.map(String::valueOf)
|
||||
.map(String::toLowerCase)
|
||||
.filter(property -> property.contains("ssl"))
|
||||
.collect(Collectors.toList());
|
||||
|
||||
//System.err.printf("SSL System Properties [%s]%n", sslSystemProperties);
|
||||
|
||||
sslSystemProperties.forEach(System::clearProperty);
|
||||
}
|
||||
|
||||
@Autowired
|
||||
private GemfireTemplate echoTemplate;
|
||||
|
||||
@Test
|
||||
public void clientServerCommunicationsSuccessful() {
|
||||
|
||||
assertThat(this.echoTemplate).isNotNull();
|
||||
assertThat(this.echoTemplate.<String, String>get("Hello")).isEqualTo("Hello");
|
||||
assertThat(this.echoTemplate.<String, String>get("Test")).isEqualTo("Test");
|
||||
assertThat(this.echoTemplate.<String, String>get("Good-Bye")).isEqualTo("Good-Bye");
|
||||
}
|
||||
|
||||
@SpringBootApplication
|
||||
@EnableLogging(logLevel = GEMFIRE_LOG_LEVEL)
|
||||
@Import(EchoClientConfiguration.class)
|
||||
static class GemFireClientConfiguration extends ClientServerIntegrationTestsConfiguration { }
|
||||
|
||||
@SpringBootApplication
|
||||
@CacheServerApplication(name = "AutoConfiguredSslIntegrationTests", logLevel = GEMFIRE_LOG_LEVEL)
|
||||
@Import(EchoServerConfiguration.class)
|
||||
static class GemFireServerConfiguration {
|
||||
|
||||
public static void main(String[] args) {
|
||||
SpringApplication.run(GemFireServerConfiguration.class, args);
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user