@@ -49,7 +49,7 @@ public class Order {
|
||||
* @param orderDate
|
||||
*/
|
||||
public Order(String customerId, Date orderDate) {
|
||||
this(null, customerId, orderDate, new ArrayList<LineItem>());
|
||||
this(null, customerId, orderDate, new ArrayList<>());
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -15,9 +15,6 @@
|
||||
*/
|
||||
package example.springdata.multistore;
|
||||
|
||||
import static org.hamcrest.Matchers.*;
|
||||
import static org.junit.Assert.*;
|
||||
|
||||
import example.springdata.multistore.customer.Customer;
|
||||
import example.springdata.multistore.shop.Order;
|
||||
|
||||
@@ -31,6 +28,8 @@ import org.springframework.data.mongodb.repository.query.MongoEntityInformation;
|
||||
import org.springframework.data.repository.support.Repositories;
|
||||
import org.springframework.test.context.junit4.SpringRunner;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
|
||||
/**
|
||||
* Integration test to check repository interfaces are assigned to the correct store modules.
|
||||
*
|
||||
@@ -45,9 +44,9 @@ public class ApplicationConfigurationTest {
|
||||
@Test
|
||||
public void repositoriesAreAssignedToAppropriateStores() {
|
||||
|
||||
Repositories repositories = new Repositories(context);
|
||||
var repositories = new Repositories(context);
|
||||
|
||||
assertThat(repositories.getEntityInformationFor(Customer.class), is(instanceOf(JpaEntityInformation.class)));
|
||||
assertThat(repositories.getEntityInformationFor(Order.class), is(instanceOf(MongoEntityInformation.class)));
|
||||
assertThat(repositories.getEntityInformationFor(Customer.class)).isInstanceOf(JpaEntityInformation.class);
|
||||
assertThat(repositories.getEntityInformationFor(Order.class)).isInstanceOf(MongoEntityInformation.class);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -62,7 +62,7 @@ public class Customer {
|
||||
this.gender = null;
|
||||
}
|
||||
|
||||
static enum Gender {
|
||||
MALE, FEMALE;
|
||||
enum Gender {
|
||||
MALE, FEMALE
|
||||
}
|
||||
}
|
||||
|
||||
@@ -15,14 +15,13 @@
|
||||
*/
|
||||
package example.springdata.rest.headers;
|
||||
|
||||
import static org.hamcrest.Matchers.*;
|
||||
import static org.hamcrest.MatcherAssert.assertThat;
|
||||
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.boot.test.context.SpringBootTest;
|
||||
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
|
||||
/**
|
||||
* Integration tests to bootstrap the application.
|
||||
*
|
||||
@@ -37,9 +36,9 @@ public class ApplicationIntegrationTests {
|
||||
@Test
|
||||
public void initializesRepositoryWithSampleData() {
|
||||
|
||||
Iterable<Customer> result = repository.findAll();
|
||||
var result = repository.findAll();
|
||||
|
||||
assertThat(result, is(iterableWithSize(1)));
|
||||
assertThat(result.iterator().next().getLastModifiedDate(), is(notNullValue()));
|
||||
assertThat(result).hasSize(1);
|
||||
assertThat(result.iterator().next().getLastModifiedDate()).isNotNull();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -41,7 +41,7 @@ public class CrossOriginIntegrationTests {
|
||||
@Autowired WebApplicationContext context;
|
||||
@Autowired CustomerRepository customers;
|
||||
|
||||
MockMvc mvc;
|
||||
private MockMvc mvc;
|
||||
|
||||
@BeforeEach
|
||||
public void setUp() {
|
||||
@@ -51,8 +51,8 @@ public class CrossOriginIntegrationTests {
|
||||
@Test
|
||||
public void executePreflightRequest() throws Exception {
|
||||
|
||||
String origin = "http://localhost:1234";
|
||||
URI uri = URI.create("/customers");
|
||||
var origin = "http://localhost:1234";
|
||||
var uri = URI.create("/customers");
|
||||
|
||||
mvc.perform(options(uri).header(ORIGIN, origin).header(ACCESS_CONTROL_REQUEST_METHOD, "POST")) //
|
||||
.andExpect(header().string(ACCESS_CONTROL_ALLOW_ORIGIN, is(origin))) //
|
||||
@@ -63,8 +63,8 @@ public class CrossOriginIntegrationTests {
|
||||
@Test
|
||||
public void executeCrossOriginRequest() throws Exception {
|
||||
|
||||
String origin = "http://localhost:1234";
|
||||
URI uri = URI.create("/customers");
|
||||
var origin = "http://localhost:1234";
|
||||
var uri = URI.create("/customers");
|
||||
|
||||
mvc.perform(get(uri).header(ORIGIN, origin)) //
|
||||
.andExpect(status().isOk()) //
|
||||
@@ -74,8 +74,8 @@ public class CrossOriginIntegrationTests {
|
||||
@Test
|
||||
public void rejectCrossOriginRequest() throws Exception {
|
||||
|
||||
String origin = "http://foo.bar";
|
||||
URI uri = URI.create("/customers");
|
||||
var origin = "http://foo.bar";
|
||||
var uri = URI.create("/customers");
|
||||
|
||||
mvc.perform(get(uri).header(ORIGIN, origin)) //
|
||||
.andExpect(status().isForbidden());
|
||||
|
||||
@@ -44,7 +44,7 @@ public class WebIntegrationTests {
|
||||
@Autowired WebApplicationContext context;
|
||||
@Autowired CustomerRepository customers;
|
||||
|
||||
MockMvc mvc;
|
||||
private MockMvc mvc;
|
||||
|
||||
@BeforeEach
|
||||
public void setUp() {
|
||||
@@ -57,10 +57,10 @@ public class WebIntegrationTests {
|
||||
@Test
|
||||
public void executeConditionalGetRequests() throws Exception {
|
||||
|
||||
Customer customer = customers.findAll().iterator().next();
|
||||
URI uri = new UriTemplate("/customers/{id}").expand(customer.getId());
|
||||
var customer = customers.findAll().iterator().next();
|
||||
var uri = new UriTemplate("/customers/{id}").expand(customer.getId());
|
||||
|
||||
MockHttpServletResponse response = mvc.perform(get(uri)).//
|
||||
var response = mvc.perform(get(uri)).//
|
||||
andExpect(header().string(ETAG, is(notNullValue()))).//
|
||||
andExpect(header().string(LAST_MODIFIED, is(notNullValue()))).//
|
||||
andReturn().getResponse();
|
||||
|
||||
@@ -43,7 +43,7 @@ public class ApplicationIntegrationTests {
|
||||
personRepository.save(new Person("Frodo", "Baggins"));
|
||||
personRepository.save(new Person("Bilbo", "Baggins"));
|
||||
|
||||
for (Person person : personRepository.findAll()) {
|
||||
for (var person : personRepository.findAll()) {
|
||||
log.info("Hello " + person.toString());
|
||||
}
|
||||
|
||||
@@ -51,7 +51,7 @@ public class ApplicationIntegrationTests {
|
||||
treasureRepository.save(new Treasure("Sting", "Made by the Elves"));
|
||||
treasureRepository.save(new Treasure("Sauron's ring", "One ring to rule them all"));
|
||||
|
||||
for (Treasure treasure : treasureRepository.findAll()) {
|
||||
for (var treasure : treasureRepository.findAll()) {
|
||||
log.info("Found treasure " + treasure.toString());
|
||||
}
|
||||
}
|
||||
|
||||
@@ -40,10 +40,10 @@ public class Application {
|
||||
|
||||
public @PostConstruct void init() {
|
||||
|
||||
Customer dave = customers.save(new Customer("Dave", "Matthews", Gender.MALE, //
|
||||
var dave = customers.save(new Customer("Dave", "Matthews", Gender.MALE, //
|
||||
new Address("4711 Some Place", "54321", "Charlottesville", "VA")));
|
||||
|
||||
Order order = new Order();
|
||||
var order = new Order();
|
||||
|
||||
order.setCustomer(dave);
|
||||
order.add(new LineItem("Lakewood guitar", new BigDecimal(1299.0)));
|
||||
|
||||
@@ -46,7 +46,7 @@ public class Customer {
|
||||
this.gender = null;
|
||||
}
|
||||
|
||||
static enum Gender {
|
||||
MALE, FEMALE;
|
||||
enum Gender {
|
||||
MALE, FEMALE
|
||||
}
|
||||
}
|
||||
|
||||
@@ -15,13 +15,12 @@
|
||||
*/
|
||||
package example.springdata.rest.projections;
|
||||
|
||||
import static org.hamcrest.Matchers.*;
|
||||
import static org.hamcrest.MatcherAssert.assertThat;
|
||||
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.boot.test.context.SpringBootTest;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
|
||||
/**
|
||||
* Integration tests to bootstrap the application.
|
||||
*
|
||||
@@ -35,8 +34,8 @@ public class ApplicationIntegrationTests {
|
||||
@Test
|
||||
public void initializesRepositoryWithSampleData() {
|
||||
|
||||
Iterable<Order> result = repository.findAll();
|
||||
var result = repository.findAll();
|
||||
|
||||
assertThat(result, is(iterableWithSize(1)));
|
||||
assertThat(result).hasSize(1);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -15,9 +15,6 @@
|
||||
*/
|
||||
package example.springdata.rest.projections;
|
||||
|
||||
import static org.hamcrest.CoreMatchers.*;
|
||||
import static org.hamcrest.MatcherAssert.*;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
@@ -27,6 +24,8 @@ import org.springframework.beans.factory.annotation.Value;
|
||||
import org.springframework.data.projection.ProjectionFactory;
|
||||
import org.springframework.data.projection.SpelAwareProxyProjectionFactory;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
|
||||
/**
|
||||
* Test cases showing the programatic use of a {@link ProjectionFactory}.
|
||||
*
|
||||
@@ -40,16 +39,16 @@ class SimpleProjectionTests {
|
||||
@Test
|
||||
void createMapBackedProjection() {
|
||||
|
||||
Customer customer = factory.createProjection(Customer.class);
|
||||
var customer = factory.createProjection(Customer.class);
|
||||
customer.setFirstname("Dave");
|
||||
customer.setLastname("Matthews");
|
||||
|
||||
// Verify accessors work
|
||||
assertThat(customer.getFirstname(), is("Dave"));
|
||||
assertThat(customer.getLastname(), is("Matthews"));
|
||||
assertThat(customer.getFirstname()).isEqualTo("Dave");
|
||||
assertThat(customer.getLastname()).isEqualTo("Matthews");
|
||||
|
||||
// Verify evaluating a SpEL expression
|
||||
assertThat(customer.getFullName(), is("Dave Matthews"));
|
||||
assertThat(customer.getFullName()).isEqualTo("Dave Matthews");
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -59,11 +58,11 @@ class SimpleProjectionTests {
|
||||
backingMap.put("firstname", "Dave");
|
||||
backingMap.put("lastname", "Matthews");
|
||||
|
||||
Customer customer = factory.createProjection(Customer.class, backingMap);
|
||||
var customer = factory.createProjection(Customer.class, backingMap);
|
||||
|
||||
// Verify accessors work
|
||||
assertThat(customer.getFirstname(), is("Dave"));
|
||||
assertThat(customer.getLastname(), is("Matthews"));
|
||||
assertThat(customer.getFirstname()).isEqualTo("Dave");
|
||||
assertThat(customer.getLastname()).isEqualTo("Matthews");
|
||||
}
|
||||
|
||||
interface Customer {
|
||||
|
||||
@@ -31,6 +31,7 @@ import org.springframework.security.core.context.SecurityContextHolder;
|
||||
import org.springframework.security.core.userdetails.User;
|
||||
import org.springframework.security.core.userdetails.User.UserBuilder;
|
||||
import org.springframework.security.core.userdetails.UserDetails;
|
||||
import org.springframework.security.crypto.factory.PasswordEncoderFactories;
|
||||
import org.springframework.security.provisioning.InMemoryUserDetailsManager;
|
||||
|
||||
/**
|
||||
@@ -88,10 +89,10 @@ public class Application {
|
||||
@Bean
|
||||
InMemoryUserDetailsManager userDetailsManager() {
|
||||
|
||||
UserBuilder builder = User.withDefaultPasswordEncoder();
|
||||
var builder = User.builder().passwordEncoder(PasswordEncoderFactories.createDelegatingPasswordEncoder()::encode);
|
||||
|
||||
UserDetails greg = builder.username("greg").password("turnquist").roles("USER").build();
|
||||
UserDetails ollie = builder.username("ollie").password("gierke").roles("USER", "ADMIN").build();
|
||||
var greg = builder.username("greg").password("turnquist").roles("USER").build();
|
||||
var ollie = builder.username("ollie").password("gierke").roles("USER", "ADMIN").build();
|
||||
|
||||
return new InMemoryUserDetailsManager(greg, ollie);
|
||||
}
|
||||
|
||||
@@ -26,6 +26,9 @@ import org.springframework.security.access.AccessDeniedException;
|
||||
import org.springframework.security.authentication.AuthenticationCredentialsNotFoundException;
|
||||
import org.springframework.security.core.context.SecurityContextHolder;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
import static org.assertj.core.api.Assertions.fail;
|
||||
|
||||
/**
|
||||
* Collection of test cases used to verify method-level security.
|
||||
*
|
||||
@@ -96,7 +99,7 @@ class MethodLevelSecurityTests {
|
||||
|
||||
itemRepository.findAll();
|
||||
|
||||
Item item = itemRepository.save(new Item("MacBook Pro"));
|
||||
var item = itemRepository.save(new Item("MacBook Pro"));
|
||||
|
||||
itemRepository.deleteById(item.getId());
|
||||
}
|
||||
|
||||
@@ -15,8 +15,7 @@
|
||||
*/
|
||||
package example.springdata.rest.security;
|
||||
|
||||
import static org.hamcrest.CoreMatchers.*;
|
||||
import static org.hamcrest.MatcherAssert.*;
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.*;
|
||||
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.*;
|
||||
import static org.springframework.test.web.servlet.setup.MockMvcBuilders.*;
|
||||
@@ -85,7 +84,7 @@ class UrlLevelSecurityTests {
|
||||
@Test
|
||||
void allowsGetRequestsButRejectsPostForUser() throws Exception {
|
||||
|
||||
HttpHeaders headers = new HttpHeaders();
|
||||
var headers = new HttpHeaders();
|
||||
headers.add(HttpHeaders.ACCEPT, MediaTypes.HAL_JSON_VALUE);
|
||||
headers.add(HttpHeaders.AUTHORIZATION,
|
||||
"Basic " + new String(Base64.getEncoder().encodeToString(("greg:turnquist").getBytes())));
|
||||
@@ -103,7 +102,7 @@ class UrlLevelSecurityTests {
|
||||
@Test
|
||||
void allowsPostRequestForAdmin() throws Exception {
|
||||
|
||||
HttpHeaders headers = new HttpHeaders();
|
||||
var headers = new HttpHeaders();
|
||||
headers.set(HttpHeaders.ACCEPT, MediaTypes.HAL_JSON_VALUE);
|
||||
headers.set(HttpHeaders.AUTHORIZATION,
|
||||
"Basic " + new String(Base64.getEncoder().encodeToString(("ollie:gierke").getBytes())));
|
||||
@@ -115,20 +114,20 @@ class UrlLevelSecurityTests {
|
||||
|
||||
headers.set(HttpHeaders.CONTENT_TYPE, MediaType.APPLICATION_JSON_VALUE);
|
||||
|
||||
String location = mvc.perform(post("/employees").//
|
||||
var location = mvc.perform(post("/employees").//
|
||||
content(PAYLOAD).//
|
||||
headers(headers)).//
|
||||
andExpect(status().isCreated()).//
|
||||
andReturn().getResponse().getHeader(HttpHeaders.LOCATION);
|
||||
|
||||
ObjectMapper mapper = new ObjectMapper();
|
||||
var mapper = new ObjectMapper();
|
||||
|
||||
String content = mvc.perform(get(location)).//
|
||||
var content = mvc.perform(get(location)).//
|
||||
andReturn().getResponse().getContentAsString();
|
||||
Employee employee = mapper.readValue(content, Employee.class);
|
||||
var employee = mapper.readValue(content, Employee.class);
|
||||
|
||||
assertThat(employee.getFirstName(), is("Saruman"));
|
||||
assertThat(employee.getLastName(), is("the White"));
|
||||
assertThat(employee.getTitle(), is("Wizard"));
|
||||
assertThat(employee.getFirstName()).isEqualTo("Saruman");
|
||||
assertThat(employee.getLastName()).isEqualTo("the White");
|
||||
assertThat(employee.getTitle()).isEqualTo("Wizard");
|
||||
}
|
||||
}
|
||||
|
||||
@@ -53,13 +53,13 @@ public class StoreInitializer {
|
||||
return;
|
||||
}
|
||||
|
||||
Iterable<? extends IndexDefinition> indexDefinitions = IndexResolver
|
||||
var indexDefinitions = IndexResolver
|
||||
.create(operations.getConverter().getMappingContext())
|
||||
.resolveIndexFor(Store.class);
|
||||
|
||||
indexDefinitions.forEach(operations.indexOps(Store.class)::ensureIndex);
|
||||
|
||||
List<Store> stores = readStores();
|
||||
var stores = readStores();
|
||||
log.info("Importing {} stores into MongoDB…", stores.size());
|
||||
repository.saveAll(stores);
|
||||
log.info("Successfully imported {} stores.", repository.count());
|
||||
@@ -72,26 +72,26 @@ public class StoreInitializer {
|
||||
* @return
|
||||
* @throws Exception
|
||||
*/
|
||||
public static List<Store> readStores() throws Exception {
|
||||
private static List<Store> readStores() throws Exception {
|
||||
|
||||
ClassPathResource resource = new ClassPathResource("starbucks.csv");
|
||||
Scanner scanner = new Scanner(resource.getInputStream());
|
||||
String line = scanner.nextLine();
|
||||
var resource = new ClassPathResource("starbucks.csv");
|
||||
var scanner = new Scanner(resource.getInputStream());
|
||||
var line = scanner.nextLine();
|
||||
scanner.close();
|
||||
|
||||
FlatFileItemReader<Store> itemReader = new FlatFileItemReader<Store>();
|
||||
var itemReader = new FlatFileItemReader<Store>();
|
||||
itemReader.setResource(resource);
|
||||
|
||||
// DelimitedLineTokenizer defaults to comma as its delimiter
|
||||
DelimitedLineTokenizer tokenizer = new DelimitedLineTokenizer();
|
||||
var tokenizer = new DelimitedLineTokenizer();
|
||||
tokenizer.setNames(line.split(","));
|
||||
tokenizer.setStrict(false);
|
||||
|
||||
DefaultLineMapper<Store> lineMapper = new DefaultLineMapper<Store>();
|
||||
var lineMapper = new DefaultLineMapper<Store>();
|
||||
lineMapper.setFieldSetMapper(fields -> {
|
||||
|
||||
Point location = new Point(fields.readDouble("Longitude"), fields.readDouble("Latitude"));
|
||||
Address address = new Address(fields.readString("Street Address"), fields.readString("City"),
|
||||
var location = new Point(fields.readDouble("Longitude"), fields.readDouble("Latitude"));
|
||||
var address = new Address(fields.readString("Street Address"), fields.readString("City"),
|
||||
fields.readString("Zip"), location);
|
||||
|
||||
return new Store(UUID.randomUUID(), fields.readString("Name"), address);
|
||||
|
||||
@@ -23,9 +23,11 @@ import org.springframework.data.geo.Distance;
|
||||
import org.springframework.data.geo.Point;
|
||||
import org.springframework.data.querydsl.QuerydslPredicateExecutor;
|
||||
import org.springframework.data.querydsl.binding.QuerydslBindings;
|
||||
import org.springframework.data.querydsl.binding.SingleValueBinding;
|
||||
import org.springframework.data.repository.PagingAndSortingRepository;
|
||||
import org.springframework.data.rest.core.annotation.RestResource;
|
||||
|
||||
import com.querydsl.core.types.dsl.StringExpression;
|
||||
import com.querydsl.core.types.dsl.StringPath;
|
||||
|
||||
/**
|
||||
@@ -47,7 +49,7 @@ public interface StoreRepository extends PagingAndSortingRepository<Store, UUID>
|
||||
*/
|
||||
default void customize(QuerydslBindings bindings, QStore store) {
|
||||
|
||||
bindings.bind(store.address.city).first((path, value) -> path.endsWith(value));
|
||||
bindings.bind(String.class).first((StringPath path, String value) -> path.contains(value));
|
||||
bindings.bind(store.address.city).first(StringExpression::endsWith);
|
||||
bindings.bind(String.class).first((SingleValueBinding<StringPath, String>) StringExpression::contains);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -57,12 +57,8 @@ class StoresController {
|
||||
|
||||
static {
|
||||
|
||||
Map<String, Point> locations = new HashMap<>();
|
||||
|
||||
locations.put("Pivotal SF", new Point(-122.4041764, 37.7819286));
|
||||
locations.put("Timesquare NY", new Point(-73.995146, 40.740337));
|
||||
|
||||
KNOWN_LOCATIONS = Collections.unmodifiableMap(locations);
|
||||
KNOWN_LOCATIONS = Map.of("Pivotal SF", new Point(-122.4041764, 37.7819286), "Timesquare NY",
|
||||
new Point(-73.995146, 40.740337));
|
||||
}
|
||||
|
||||
private final StoreRepository repository;
|
||||
@@ -81,9 +77,9 @@ class StoresController {
|
||||
String index(Model model, @RequestParam Optional<Point> location, @RequestParam Optional<Distance> distance,
|
||||
Pageable pageable) {
|
||||
|
||||
Point point = location.orElse(KNOWN_LOCATIONS.get("Timesquare NY"));
|
||||
var point = location.orElse(KNOWN_LOCATIONS.get("Timesquare NY"));
|
||||
|
||||
Page<Store> stores = repository.findByAddressLocationNear(point, distance.orElse(DEFAULT_DISTANCE), pageable);
|
||||
var stores = repository.findByAddressLocationNear(point, distance.orElse(DEFAULT_DISTANCE), pageable);
|
||||
|
||||
model.addAttribute("stores", stores);
|
||||
model.addAttribute("distances", DISTANCES);
|
||||
|
||||
@@ -31,15 +31,9 @@ import org.springframework.boot.test.context.SpringBootTest;
|
||||
import org.springframework.boot.test.context.SpringBootTest.WebEnvironment;
|
||||
import org.springframework.boot.web.server.LocalServerPort;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.hateoas.CollectionModel;
|
||||
import org.springframework.hateoas.EntityModel;
|
||||
import org.springframework.hateoas.Link;
|
||||
import org.springframework.hateoas.Links;
|
||||
import org.springframework.hateoas.MediaTypes;
|
||||
import org.springframework.hateoas.PagedModel;
|
||||
import org.springframework.hateoas.PagedModel.PageMetadata;
|
||||
import org.springframework.hateoas.client.Traverson;
|
||||
import org.springframework.hateoas.client.Traverson.TraversalBuilder;
|
||||
import org.springframework.hateoas.server.core.TypeReferences.CollectionModelType;
|
||||
import org.springframework.hateoas.server.core.TypeReferences.EntityModelType;
|
||||
import org.springframework.hateoas.server.core.TypeReferences.PagedModelType;
|
||||
@@ -68,15 +62,17 @@ class StarbucksClient {
|
||||
|
||||
@LocalServerPort int port;
|
||||
|
||||
@Autowired RestOperations restOperations;
|
||||
|
||||
private static final String SERVICE_URI = "http://localhost:%s/api";
|
||||
|
||||
@Test
|
||||
void discoverStoreSearch() {
|
||||
|
||||
Traverson traverson = new Traverson(URI.create(String.format(SERVICE_URI, port)), MediaTypes.HAL_JSON);
|
||||
var traverson = new Traverson(URI.create(String.format(SERVICE_URI, port)), MediaTypes.HAL_JSON);
|
||||
|
||||
// Set up path traversal
|
||||
TraversalBuilder builder = traverson. //
|
||||
var builder = traverson. //
|
||||
follow("stores", "search", "by-location");
|
||||
|
||||
// Log discovered
|
||||
@@ -88,11 +84,11 @@ class StarbucksClient {
|
||||
parameters.put("location", "40.740337,-73.995146");
|
||||
parameters.put("distance", "0.5miles");
|
||||
|
||||
PagedModel<EntityModel<Store>> resources = builder.//
|
||||
var resources = builder.//
|
||||
withTemplateParameters(parameters).//
|
||||
toObject(new PagedModelType<EntityModel<Store>>() {});
|
||||
|
||||
PageMetadata metadata = resources.getMetadata();
|
||||
var metadata = resources.getMetadata();
|
||||
|
||||
log.info("Got {} of {} stores: ", resources.getContent().size(), metadata.getTotalElements());
|
||||
|
||||
@@ -101,45 +97,37 @@ class StarbucksClient {
|
||||
forEach(store -> log.info("{} - {}", store.name, store.address));
|
||||
}
|
||||
|
||||
@Autowired RestOperations restOperations;
|
||||
|
||||
@Test
|
||||
void accessServiceUsingRestTemplate() {
|
||||
|
||||
// Access root resource
|
||||
|
||||
URI uri = URI.create(String.format(SERVICE_URI, port));
|
||||
RequestEntity<Void> request = RequestEntity.get(uri).accept(HAL_JSON).build();
|
||||
EntityModel<Object> rootLinks = restOperations.exchange(request, new EntityModelType<Object>() {}).getBody();
|
||||
Links links = rootLinks.getLinks();
|
||||
var uri = URI.create(String.format(SERVICE_URI, port));
|
||||
var request = RequestEntity.get(uri).accept(HAL_JSON).build();
|
||||
var rootLinks = restOperations.exchange(request, new EntityModelType<>() {}).getBody();
|
||||
var links = rootLinks.getLinks();
|
||||
|
||||
// Follow stores link
|
||||
|
||||
Link storesLink = links.getRequiredLink("stores").expand();
|
||||
var storesLink = links.getRequiredLink("stores").expand();
|
||||
|
||||
request = RequestEntity.get(URI.create(storesLink.getHref())).accept(HAL_JSON).build();
|
||||
CollectionModel<Store> stores = restOperations.exchange(request, new CollectionModelType<Store>() {}).getBody();
|
||||
var stores = restOperations.exchange(request, new CollectionModelType<Store>() {}).getBody();
|
||||
|
||||
stores.getContent().forEach(store -> log.info("{} - {}", store.name, store.address));
|
||||
}
|
||||
|
||||
static class Store {
|
||||
record Store(String name, StarbucksClient.Store.Address address) {
|
||||
|
||||
public String name;
|
||||
Address address;
|
||||
|
||||
static class Address {
|
||||
|
||||
String city, zip, street;
|
||||
Location location;
|
||||
record Address(String city, String zip, String street, Store.Address.Location location) {
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return String.format("%s, %s %s - lat: %s, long: %s", street, zip, city, location.y, location.x);
|
||||
}
|
||||
|
||||
static class Location {
|
||||
double x, y;
|
||||
record Location(double x, double y) {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -15,9 +15,6 @@
|
||||
*/
|
||||
package example.springdata.rest.stores;
|
||||
|
||||
import static org.hamcrest.MatcherAssert.assertThat;
|
||||
import static org.hamcrest.Matchers.*;
|
||||
|
||||
import example.springdata.rest.stores.Store.Address;
|
||||
|
||||
import java.util.UUID;
|
||||
@@ -33,6 +30,8 @@ import org.springframework.data.geo.Distance;
|
||||
import org.springframework.data.geo.Metrics;
|
||||
import org.springframework.data.geo.Point;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
|
||||
/**
|
||||
* Integration tests for {@link StoreRepository}.
|
||||
*
|
||||
@@ -53,15 +52,15 @@ public class StoreRepositoryIntegrationTests {
|
||||
@Test
|
||||
public void findsStoresByLocation() {
|
||||
|
||||
Point location = new Point(-73.995146, 40.740337);
|
||||
Store store = new Store(UUID.randomUUID(), "Foo", new Address("street", "city", "zip", location));
|
||||
var location = new Point(-73.995146, 40.740337);
|
||||
var store = new Store(UUID.randomUUID(), "Foo", new Address("street", "city", "zip", location));
|
||||
|
||||
store = repository.save(store);
|
||||
|
||||
Page<Store> stores = repository.findByAddressLocationNear(location, new Distance(1.0, Metrics.KILOMETERS),
|
||||
var stores = repository.findByAddressLocationNear(location, new Distance(1.0, Metrics.KILOMETERS),
|
||||
PageRequest.of(0, 10));
|
||||
|
||||
assertThat(stores.getContent(), hasSize(1));
|
||||
assertThat(stores.getContent(), hasItem(store));
|
||||
assertThat(stores.getContent()).hasSize(1);
|
||||
assertThat(stores.getContent()).contains(store);
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user