diff --git a/pom.xml b/pom.xml
index d4499cb6..e77e72a1 100644
--- a/pom.xml
+++ b/pom.xml
@@ -35,6 +35,10 @@
spring-boot-starter-test
test
+
+ org.springframework.data
+ spring-data-commons
+
diff --git a/src/main/java/guru/springframework/spring6resttemplate/client/BeerClient.java b/src/main/java/guru/springframework/spring6resttemplate/client/BeerClient.java
new file mode 100644
index 00000000..e9659d7e
--- /dev/null
+++ b/src/main/java/guru/springframework/spring6resttemplate/client/BeerClient.java
@@ -0,0 +1,20 @@
+package guru.springframework.spring6resttemplate.client;
+
+import guru.springframework.spring6resttemplate.model.BeerDTO;
+import org.springframework.data.domain.Page;
+
+import java.util.UUID;
+
+public interface BeerClient {
+ Page listBeers();
+
+ Page listBeers(String beerName, String beerStyle,
+ Boolean showInventory, Integer pageNumber, Integer pageSize);
+ BeerDTO getBeerById(UUID beerId);
+
+ void deleteBeer(UUID beerId);
+
+ BeerDTO saveNewBeer(BeerDTO beer);
+
+ BeerDTO updateBeerById(BeerDTO savedBeer);
+}
\ No newline at end of file
diff --git a/src/main/java/guru/springframework/spring6resttemplate/client/BeerClientImpl.java b/src/main/java/guru/springframework/spring6resttemplate/client/BeerClientImpl.java
new file mode 100644
index 00000000..0378801b
--- /dev/null
+++ b/src/main/java/guru/springframework/spring6resttemplate/client/BeerClientImpl.java
@@ -0,0 +1,71 @@
+package guru.springframework.spring6resttemplate.client;
+
+import guru.springframework.spring6resttemplate.model.BeerDTO;
+import guru.springframework.spring6resttemplate.model.BeerDTOPageImpl;
+import lombok.RequiredArgsConstructor;
+import org.springframework.boot.web.client.RestTemplateBuilder;
+import org.springframework.data.domain.Page;
+import org.springframework.http.ResponseEntity;
+import org.springframework.stereotype.Service;
+import org.springframework.web.client.RestTemplate;
+import org.springframework.web.util.UriComponentsBuilder;
+
+import java.net.URI;
+import java.util.UUID;
+
+@Service
+@RequiredArgsConstructor
+public class BeerClientImpl implements BeerClient {
+ public static final String GET_BEER_PATH = "/api/v1/beer";
+ public static final String GET_BEER_BY_ID_PATH = "/api/v1/beer/{beerId}";
+
+ private final RestTemplateBuilder restTemplateBuilder;
+
+ @Override
+ public void deleteBeer(UUID beerId) {
+ RestTemplate restTemplate = restTemplateBuilder.build();
+ restTemplate.delete(GET_BEER_BY_ID_PATH, beerId);
+ }
+ @Override
+ public BeerDTO saveNewBeer(BeerDTO newBeer) {
+ RestTemplate restTemplate = restTemplateBuilder.build();
+ URI uri = restTemplate.postForLocation(GET_BEER_PATH, newBeer);
+ return restTemplate.getForObject(uri.getPath(), BeerDTO.class);
+ }
+
+ @Override
+ public BeerDTO updateBeerById(BeerDTO savedBeer) {
+ RestTemplate restTemplate = restTemplateBuilder.build();
+ restTemplate.put(GET_BEER_BY_ID_PATH, savedBeer, savedBeer.getId());
+ return this.getBeerById(savedBeer.getId());
+ }
+
+ @Override
+ public Page listBeers() {
+ return this.listBeers(null, null, null, null, null);
+ }
+ @Override
+ public Page listBeers(String beerName, String beerStyle,
+ Boolean showInventory, Integer pageNumber, Integer pageSize) {
+ RestTemplate restTemplate = restTemplateBuilder.build();
+ UriComponentsBuilder uriBuilder = UriComponentsBuilder.fromPath(GET_BEER_PATH);
+ //setting query params in uri path
+ if (beerName != null) uriBuilder.queryParam("beerName", beerName);
+ if (beerStyle != null) uriBuilder.queryParam("beerStyle", beerStyle);
+ if (showInventory != null) uriBuilder.queryParam("showInventory", showInventory);
+ if (pageNumber != null) uriBuilder.queryParam("pageNumber", pageNumber);
+ if (pageSize != null) uriBuilder.queryParam("pageSize", pageSize);
+
+ ResponseEntity response = restTemplate.getForEntity(uriBuilder.toUriString(), BeerDTOPageImpl.class);
+
+ return response.getBody();
+ }
+
+ @Override
+ public BeerDTO getBeerById(UUID beerId) {
+ RestTemplate restTemplate = restTemplateBuilder.build();
+ //UriComponentsBuilder uriBuilder = UriComponentsBuilder.fromPath(GET_BEER_BY_ID_PATH);
+ return restTemplate.getForObject(GET_BEER_BY_ID_PATH, BeerDTO.class, beerId);
+ }
+
+}
\ No newline at end of file
diff --git a/src/main/java/guru/springframework/spring6resttemplate/config/RestTemplateBuilderConfig.java b/src/main/java/guru/springframework/spring6resttemplate/config/RestTemplateBuilderConfig.java
new file mode 100644
index 00000000..81f495db
--- /dev/null
+++ b/src/main/java/guru/springframework/spring6resttemplate/config/RestTemplateBuilderConfig.java
@@ -0,0 +1,25 @@
+package guru.springframework.spring6resttemplate.config;
+
+import org.springframework.beans.factory.annotation.Value;
+import org.springframework.boot.autoconfigure.web.client.RestTemplateBuilderConfigurer;
+import org.springframework.boot.web.client.RestTemplateBuilder;
+import org.springframework.context.annotation.Bean;
+import org.springframework.context.annotation.Configuration;
+import org.springframework.web.client.RestTemplate;
+import org.springframework.web.util.DefaultUriBuilderFactory;
+
+@Configuration
+public class RestTemplateBuilderConfig {
+
+ @Value("${rest.template.url}")
+ String rootUrl;
+ @Bean
+ RestTemplateBuilder restTemplateBuilder(RestTemplateBuilderConfigurer configurer) {
+ assert rootUrl != null : "Root URL must not be null.";
+ RestTemplateBuilder builder = configurer.configure(new RestTemplateBuilder());
+ DefaultUriBuilderFactory uriBuilderFactory = new DefaultUriBuilderFactory(rootUrl);
+
+ return builder.uriTemplateHandler(uriBuilderFactory);
+ }
+
+}
diff --git a/src/main/java/guru/springframework/spring6resttemplate/model/BeerDTOPageImpl.java b/src/main/java/guru/springframework/spring6resttemplate/model/BeerDTOPageImpl.java
new file mode 100644
index 00000000..a97b3c0e
--- /dev/null
+++ b/src/main/java/guru/springframework/spring6resttemplate/model/BeerDTOPageImpl.java
@@ -0,0 +1,28 @@
+package guru.springframework.spring6resttemplate.model;
+
+import com.fasterxml.jackson.annotation.JsonCreator;
+import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
+import com.fasterxml.jackson.annotation.JsonProperty;
+import org.springframework.data.domain.PageImpl;
+import org.springframework.data.domain.PageRequest;
+import org.springframework.data.domain.Pageable;
+
+import java.util.List;
+
+@JsonIgnoreProperties(ignoreUnknown = true, value = "pageable")
+public class BeerDTOPageImpl extends PageImpl {
+ @JsonCreator(mode = JsonCreator.Mode.PROPERTIES)
+ public BeerDTOPageImpl(@JsonProperty("content") List content,
+ @JsonProperty("number") int page,
+ @JsonProperty("size") int size,
+ @JsonProperty("totalElements") long total) {
+ super((List) content, PageRequest.of(page, size), total);
+ }
+ public BeerDTOPageImpl(List content, Pageable pageable, long total) {
+ super((List) content, pageable, total);
+ }
+
+ public BeerDTOPageImpl(List content) {
+ super((List) content);
+ }
+}
diff --git a/src/main/resources/application.properties b/src/main/resources/application.properties
index 8b137891..c86a640a 100644
--- a/src/main/resources/application.properties
+++ b/src/main/resources/application.properties
@@ -1 +1 @@
-
+rest.template.url=http://localhost:9000
diff --git a/src/test/java/guru/springframework/spring6resttemplate/client/BeerClientImplTest.java b/src/test/java/guru/springframework/spring6resttemplate/client/BeerClientImplTest.java
new file mode 100644
index 00000000..36b2c905
--- /dev/null
+++ b/src/test/java/guru/springframework/spring6resttemplate/client/BeerClientImplTest.java
@@ -0,0 +1,71 @@
+package guru.springframework.spring6resttemplate.client;
+
+import guru.springframework.spring6resttemplate.model.BeerDTO;
+import guru.springframework.spring6resttemplate.model.BeerStyle;
+import org.junit.jupiter.api.Test;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.boot.test.context.SpringBootTest;
+import org.springframework.data.domain.Page;
+import org.springframework.web.client.HttpClientErrorException;
+
+import java.math.BigDecimal;
+
+import static org.junit.jupiter.api.Assertions.*;
+@SpringBootTest
+class BeerClientImplTest {
+ @Autowired
+ BeerClientImpl beerClientImpl;
+ @Test
+ void listBeersNullBeerName() {
+ beerClientImpl.listBeers(null, null, null, null, null);
+ }
+ @Test
+ void listBeers() {
+ beerClientImpl.listBeers("ALE", null, null, null, null);
+ }
+ @Test
+ void getBeerById() {
+ Page beerDTOS = beerClientImpl.listBeers();
+ BeerDTO dto = beerDTOS.getContent().get(0);
+ BeerDTO byId = beerClientImpl.getBeerById(dto.getId());
+
+ assertNotNull(byId);
+ }
+ @Test
+ void createBeerTest() {
+ BeerDTO beerDTO = BeerDTO.builder()
+ .price(new BigDecimal("12.99"))
+ .beerName("Test Beer")
+ .beerStyle(BeerStyle.ALE)
+ .upc("123456789012")
+ .build();
+ BeerDTO savedBeer = beerClientImpl.saveNewBeer(beerDTO);
+ assertNotNull(savedBeer);
+ }
+ @Test
+ void updateBeer() {
+ BeerDTO beerDTO = BeerDTO.builder()
+ .price(new BigDecimal("12.99"))
+ .beerName("Test Beer")
+ .beerStyle(BeerStyle.ALE)
+ .upc("123456789012")
+ .build();
+ BeerDTO savedBeer = beerClientImpl.saveNewBeer(beerDTO);
+
+ final String beerName = "Indian Beer";
+ savedBeer.setBeerName(beerName);
+ BeerDTO updatedBeer = beerClientImpl.updateBeerById(savedBeer);
+ assertEquals(beerName, updatedBeer.getBeerName());
+
+ }
+ @Test
+ void deleteBeer() {
+ Page beerDTOS = beerClientImpl.listBeers();
+ BeerDTO dto = beerDTOS.getContent().get(0);
+ beerClientImpl.deleteBeer(dto.getId());
+ assertThrows(HttpClientErrorException.class,
+ () -> beerClientImpl.getBeerById(dto.getId())
+ );
+
+ }
+}
\ No newline at end of file