diff --git a/pom.xml b/pom.xml index ad64a1e5..786c79a4 100644 --- a/pom.xml +++ b/pom.xml @@ -5,7 +5,7 @@ org.springframework.boot spring-boot-starter-parent - 2.2.0.M2 + 2.1.4.RELEASE guru.springframework @@ -34,6 +34,11 @@ lombok true + + org.apache.httpcomponents + httpasyncclient + 4.1.4 + org.springframework.boot spring-boot-starter-test @@ -70,7 +75,7 @@ maven-surefire-plugin 3.0.0-M3 - + org.apache.maven.plugins maven-enforcer-plugin diff --git a/src/main/java/guru/springframework/msscbreweryclient/web/client/BreweryClient.java b/src/main/java/guru/springframework/msscbreweryclient/web/client/BreweryClient.java new file mode 100644 index 00000000..706de81b --- /dev/null +++ b/src/main/java/guru/springframework/msscbreweryclient/web/client/BreweryClient.java @@ -0,0 +1,65 @@ +package guru.springframework.msscbreweryclient.web.client; + +import guru.springframework.msscbreweryclient.web.model.BeerDto; +import guru.springframework.msscbreweryclient.web.model.CustomerDto; +import org.springframework.boot.context.properties.ConfigurationProperties; +import org.springframework.boot.web.client.RestTemplateBuilder; +import org.springframework.stereotype.Component; +import org.springframework.web.client.RestTemplate; + +import java.net.URI; +import java.util.UUID; + +/** + * Created by jt on 2019-04-23. + */ +@ConfigurationProperties(prefix = "sfg.brewery", ignoreUnknownFields = false) +@Component +public class BreweryClient { + + public final String BEER_PATH_V1 = "/api/v1/beer/"; + public final String CUSTOMER_PATH_V1 = "/api/v1/customer/"; + private String apihost; + + private final RestTemplate restTemplate; + + public BreweryClient(RestTemplateBuilder restTemplateBuilder) { + this.restTemplate = restTemplateBuilder.build(); + } + + public BeerDto getBeerById(UUID uuid){ + return restTemplate.getForObject(apihost + BEER_PATH_V1 + uuid.toString(), BeerDto.class); + } + + public URI saveNewBeer(BeerDto beerDto){ + return restTemplate.postForLocation(apihost + BEER_PATH_V1, beerDto); + } + + public void updateBeer(UUID uuid, BeerDto beerDto){ + restTemplate.put(apihost + BEER_PATH_V1 + uuid, beerDto); + } + + public void deleteBeer(UUID uuid){ + restTemplate.delete(apihost + BEER_PATH_V1 + uuid ); + } + + public void setApihost(String apihost) { + this.apihost = apihost; + } + + public CustomerDto getCustomerById(UUID customerId) { + return restTemplate.getForObject(apihost+ CUSTOMER_PATH_V1 + customerId.toString(), CustomerDto.class); + } + + public URI saveNewCustomer(CustomerDto customerDto) { + return restTemplate.postForLocation(apihost + CUSTOMER_PATH_V1, customerDto); + } + + public void updateCustomer(UUID customerId, CustomerDto customerDto) { + restTemplate.put(apihost + CUSTOMER_PATH_V1 + customerId, customerDto); + } + + public void deleteCustomer(UUID customerId) { + restTemplate.delete(apihost + CUSTOMER_PATH_V1 + customerId); + } +} diff --git a/src/main/java/guru/springframework/msscbreweryclient/web/config/BlockingRestTemplateCustomizer.java b/src/main/java/guru/springframework/msscbreweryclient/web/config/BlockingRestTemplateCustomizer.java new file mode 100644 index 00000000..a42d0c4e --- /dev/null +++ b/src/main/java/guru/springframework/msscbreweryclient/web/config/BlockingRestTemplateCustomizer.java @@ -0,0 +1,60 @@ +package guru.springframework.msscbreweryclient.web.config; + +import org.apache.http.client.config.RequestConfig; +import org.apache.http.impl.client.CloseableHttpClient; +import org.apache.http.impl.client.DefaultConnectionKeepAliveStrategy; +import org.apache.http.impl.client.HttpClients; +import org.apache.http.impl.conn.PoolingHttpClientConnectionManager; +import org.springframework.beans.factory.annotation.Value; +import org.springframework.boot.web.client.RestTemplateCustomizer; +import org.springframework.http.client.ClientHttpRequestFactory; +import org.springframework.http.client.HttpComponentsClientHttpRequestFactory; +import org.springframework.stereotype.Component; +import org.springframework.web.client.RestTemplate; + +/** + * Created by jt on 2019-08-08. + */ +@Component +public class BlockingRestTemplateCustomizer implements RestTemplateCustomizer { + private final Integer maxTotalConnections; + private final Integer defaultMaxTotalConnections; + private final Integer connectionRequestTimeout; + private final Integer socketTimeout; + + public BlockingRestTemplateCustomizer(@Value("${sfg.maxtotlaconnections}") Integer maxTotalConnections, + @Value("${sfg.defaultmaxtotalconnections}") Integer defaultMaxTotalConnections, + @Value("${sfg.connectionrequesttimeout}") Integer connectionRequestTimeout, + @Value("${sfg.sockettimeout}") Integer socketTimeout) { + this.maxTotalConnections = maxTotalConnections; + this.defaultMaxTotalConnections = defaultMaxTotalConnections; + this.connectionRequestTimeout = connectionRequestTimeout; + this.socketTimeout = socketTimeout; + } + + public ClientHttpRequestFactory clientHttpRequestFactory(){ + PoolingHttpClientConnectionManager connectionManager = new PoolingHttpClientConnectionManager(); + connectionManager.setMaxTotal(maxTotalConnections); + connectionManager.setDefaultMaxPerRoute(defaultMaxTotalConnections); + + RequestConfig requestConfig = RequestConfig + .custom() + .setConnectionRequestTimeout(connectionRequestTimeout) + .setSocketTimeout(socketTimeout) + .build(); + + CloseableHttpClient httpClient = HttpClients + .custom() + .setConnectionManager(connectionManager) + .setKeepAliveStrategy(new DefaultConnectionKeepAliveStrategy()) + .setDefaultRequestConfig(requestConfig) + .build(); + + return new HttpComponentsClientHttpRequestFactory(httpClient); + } + + @Override + public void customize(RestTemplate restTemplate) { + restTemplate.setRequestFactory(this.clientHttpRequestFactory()); + } +} diff --git a/src/main/java/guru/springframework/msscbreweryclient/web/config/NIORestTemplateCustomizer.java b/src/main/java/guru/springframework/msscbreweryclient/web/config/NIORestTemplateCustomizer.java new file mode 100644 index 00000000..3d2cd425 --- /dev/null +++ b/src/main/java/guru/springframework/msscbreweryclient/web/config/NIORestTemplateCustomizer.java @@ -0,0 +1,47 @@ +package guru.springframework.msscbreweryclient.web.config; + +import org.apache.http.impl.nio.client.CloseableHttpAsyncClient; +import org.apache.http.impl.nio.client.HttpAsyncClients; +import org.apache.http.impl.nio.conn.PoolingNHttpClientConnectionManager; +import org.apache.http.impl.nio.reactor.DefaultConnectingIOReactor; +import org.apache.http.impl.nio.reactor.IOReactorConfig; +import org.apache.http.nio.reactor.IOReactorException; +import org.springframework.boot.web.client.RestTemplateCustomizer; +import org.springframework.http.client.ClientHttpRequestFactory; +import org.springframework.http.client.HttpComponentsAsyncClientHttpRequestFactory; +import org.springframework.web.client.RestTemplate; + +/** + * Created by jt on 2019-08-07. + */ +//@Component +public class NIORestTemplateCustomizer implements RestTemplateCustomizer { + + public ClientHttpRequestFactory clientHttpRequestFactory() throws IOReactorException { + final DefaultConnectingIOReactor ioreactor = new DefaultConnectingIOReactor(IOReactorConfig.custom(). + setConnectTimeout(3000). + setIoThreadCount(4). + setSoTimeout(3000). + build()); + + final PoolingNHttpClientConnectionManager connectionManager = new PoolingNHttpClientConnectionManager(ioreactor); + connectionManager.setDefaultMaxPerRoute(100); + connectionManager.setMaxTotal(1000); + + CloseableHttpAsyncClient httpAsyncClient = HttpAsyncClients.custom() + .setConnectionManager(connectionManager) + .build(); + + return new HttpComponentsAsyncClientHttpRequestFactory(httpAsyncClient); + + } + + @Override + public void customize(RestTemplate restTemplate) { + try { + restTemplate.setRequestFactory(clientHttpRequestFactory()); + } catch (IOReactorException e) { + e.printStackTrace(); + } + } +} diff --git a/src/main/resources/application.properties b/src/main/resources/application.properties index 8b137891..06f48575 100644 --- a/src/main/resources/application.properties +++ b/src/main/resources/application.properties @@ -1 +1,7 @@ +sfg.brewery.apihost=http://localhost:8080 +logging.level.org.apache.http=debug +sfg.maxtotlaconnections=100 +sfg.defaultmaxtotalconnections=20 +sfg.connectionrequesttimeout=3000 +sfg.sockettimeout=3000 \ No newline at end of file diff --git a/src/test/java/guru/springframework/msscbreweryclient/web/client/BreweryClientTest.java b/src/test/java/guru/springframework/msscbreweryclient/web/client/BreweryClientTest.java new file mode 100644 index 00000000..93773f1d --- /dev/null +++ b/src/test/java/guru/springframework/msscbreweryclient/web/client/BreweryClientTest.java @@ -0,0 +1,89 @@ +package guru.springframework.msscbreweryclient.web.client; + +import guru.springframework.msscbreweryclient.web.model.BeerDto; +import guru.springframework.msscbreweryclient.web.model.CustomerDto; +import org.junit.jupiter.api.Test; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.test.context.SpringBootTest; + +import java.net.URI; +import java.util.UUID; + +import static org.junit.jupiter.api.Assertions.assertNotNull; + +@SpringBootTest +class BreweryClientTest { + + @Autowired + BreweryClient client; + + @Test + void getBeerById() { + BeerDto dto = client.getBeerById(UUID.randomUUID()); + + assertNotNull(dto); + + } + + @Test + void testSaveNewBeer() { + //given + BeerDto beerDto = BeerDto.builder().beerName("New Beer").build(); + + URI uri = client.saveNewBeer(beerDto); + + assertNotNull(uri); + + System.out.println(uri.toString()); + + } + + @Test + void testUpdateBeer() { + //given + BeerDto beerDto = BeerDto.builder().beerName("New Beer").build(); + + client.updateBeer(UUID.randomUUID(), beerDto); + + } + + @Test + void testDeleteBeer() { + client.deleteBeer(UUID.randomUUID()); + } + + @Test + void getCustomerById() { + CustomerDto dto = client.getCustomerById(UUID.randomUUID()); + + assertNotNull(dto); + + } + + @Test + void testSaveNewCustomer() { + //given + CustomerDto customerDto = CustomerDto.builder().name("Joe").build(); + + URI uri = client.saveNewCustomer(customerDto); + + assertNotNull(uri); + + System.out.println(uri.toString()); + + } + + @Test + void testUpdateCustomer() { + //given + CustomerDto customerDto = CustomerDto.builder().name("Jim").build(); + + client.updateCustomer(UUID.randomUUID(), customerDto); + + } + + @Test + void testDeleteCustomer() { + client.deleteCustomer(UUID.randomUUID()); + } +} \ No newline at end of file