Saturday, May 28, 2022

Docker : Docker, DockerCompose and DockerRun and params

Docker : Plugins comparison : palantir VS bmuschko

 https://plugins.gradle.org/search?term=com.palantir.docker


https://palantir.github.io/

https://tomgregory.com/bmuschko-docker-gradle-plugin-review/


https://tomgregory.com/automating-docker-builds-with-gradle/



Thursday, May 26, 2022

RestControllerAdvice VS ControllerAdvice VS ExceptionHandler - Interrupt the StackTraces, LOG.ERROR

 @ExceptionHandler can be used at the local level or at the global level. Local level would mean using this annotation within the controller itself to handle the exceptions within that controller only. All error thrown by that controller would be caught by that @ExceptionHandler. But this would mean that if there is a similar exception in a different controller you would have to rewrite the corresponding code again in that controller again locally.

In order to prevent repeating this style of exception handling per controller we can write the @ExceptionHanlder at the global level with the help of another annotation called @ControllerAdvice.

@ControllerAdvice is not specific to the exception handling , its also used for handling property, validation or formatter bindings at the global level. @ControllerAdvice in the context of exception handling is just another way of doing exception handling at a global level using @Exceptionhandler annotation.

Now coming to the HandlerExceptionResolver - this is an interface at a more lower level. Spring provides 2 implementations of this:

  • ResponseStatusExceptionResolver :This supports the support the @ResponseStatus annotation
  • ExceptionHandlerExceptionResolver : This supports the @ExceptionHandler annotation

Example : So when you want to handle exceptions and choose an exception handling strategy you will need to think of choosing between using a local or global exception handling via the annotations. How you need to provide the HTTP status codes, how to wrap it in the @Response entity etc, how you want to redirect to handler pages , carry the data via flash attributes or get params etc etc. Or maybe skip the annotations and use the SimpleMappingExceptionResolver and start mapping the specific exceptions to the error handler page urls

Here we are not be considering the lower level underlying HandlerExceptionResolver at this stage since we are dealing with its implementation at a higher level and building the strategy based on these options.

With the above context to answer your query - @ControllerAdvice was not introduced for exception handling, it's a mechanism you can leverage to handle exceptions globally using the @ExceptionHandler. HandlerExceptionResolver is an interface whose implementation helps support the @ResponseStatus and the @Exceptionhandler annotations. Unless you want to handle the exceptions related to the MVC system because the Spring framework does not provide any proper exception handling. So if you need to hand;e issues related to incorrect @Requestmapping etc which would not be caught by a controller as it would not even reach it in the 1st place then an implementation of the HandlerExceptionResolver would be useful

Order Service API - Simple Microservice for Order Creation

Git Repo:

https://github.com/balajimathu/beer-order-service





Create Below APIs using Spring Webflux.

 1. Order Service -  will invoke below APIs use  spring-boot-starter-validation

2. Inventory Service -  search and confirm availability, if not available Order Service will return message.

3. Price Service - Search and get latest price, Store actual prices in DB,  implement Spring Data to apply seasonal offers, configurable

4. Shipment Service - On successful creation Send mail.  @Email - -Validation

5. Payment Service - Insert data in DB and return an transaction id. 

6. Implement @ControllerAdvice - Reactive


Implement CommandLineRunner to check the availability of DependencyAPIs on startup..

Database:

Postgres


Platform:

Create Docker Images for REST APIs and Postgres DB

Run Jenkins on AWS EC2

CI and CD Pipelines

Deploy all these in Containers, separately, 

Authentication - NO Auth as of now.




Wednesday, May 25, 2022

Redis : Spring Data Redis

Spring Data Reactive : R2DBC Entity Callback AfterConvertCallback

 

R2DBC Entity Callback – AfterConvert:

Lets implement the other requirement – to apply seasonal global discounts to all products when we select records from DB. Here we do not want to touch the database. We still want to keep the original price as it is. We just want to update the price once it is retrieved from DB.

AfterConvertCallback hook would be a good choice here.

\BeforeConvertCallback. In this case our implementation should implement Ordered as well as shown here to return the order in which it should be executed.



R2DBC Entity Callback – BeforeSave:

Sometimes the actual table might have more columns and entity object might not contain all the fields. For ex: fields like created_bycreated_date etc. But we might want to update these fields. In this case, BeforeConvertCallback will not help much! But we could achieve with BeforeSaveCallback.

Spring Data VS Spring Reactive Data

 With JPA 2.2, you no longer need to use converter it added support for the mapping of the following java.time types:


CrudRepository VS ReactiveCrudRepository

PagingAndSortingRepository VS  ReactiveSortingRepository

Flux<Person> findByLastname(Mono<String> lastname);
// insert

this.repository.save(product)
              .subscribe(p -> System.out.println("After inserting : " + p));


spring-boot-starter-data-r2dbc



@EnableTransactionManagement

@EnableJpaRepositories(basePackages = "com.baeldung.spring.data.persistence.repository")


 @Transactional annotation at the class level, which is then overridden for tRhe non-read-only methods.


Exception translation is still enabled by the use of the @Repository annotation on the DAO. This annotation enables a Spring bean postprocessor to advise all @Repository beans with all the PersistenceExceptionTranslator instances found in the container, and provide exception translation just as before.

java.time.LocalDate
java.time.LocalTime
java.time.LocalDateTime
java.time.OffsetTime
java.time.OffsetDateTime
@Column(columnDefinition = "DATE")
private LocalDate date;
@Column(columnDefinition = "TIMESTAMP")
private LocalDateTime dateTime;
@Column(columnDefinition = "TIME")
private LocalTime localTime;


@GenerateValue
@GenericGenerator

@CreationTimestamp
@UpdateTimestamp

@Entity

Logging in Microservices : Spring Boot

LEVEL

application.properties
logging.level.org.springframework=DEBUG
logging.level.com.howtodoinjava=DEBUG
 
#output to a temp_folder/file
logging.file=${java.io.tmpdir}/application.log
 
# Logging pattern for the console
logging.pattern.console= %d{yyyy-MM-dd HH:mm:ss} - %msg%n

TRACEID


ELK:



Http Client: RestTemplate, Java11-HttpClient, Apache-HttpClient, WebClient

 HTTPClient replaces the legacy HttpUrlConnection class present in the JDK since the early versions of Java.

Some of its features include:

  1. Support for HTTP/1.1, HTTP/2, and Web Socket.
  2. Support for synchronous and asynchronous programming models.
  3. Handling of request and response bodies as reactive streams.
  4. Support for cookies.
Use of HttpClient is preferred if our application is built using Java 11 and above.

sendAsync VS send


Apache HttpClient


Spring WebClient is an asynchronous, reactive HTTP client introduced in Spring 5 in the Spring WebFlux project to replace the older RestTemplate for making REST API calls in applications built with the Spring Boot framework. It supports synchronous, asynchronous, and streaming scenarios.


If you call Block- then it became synchronous. 

Spring WebClient is the preferred choice for Spring Boot applications more importantly if we are using reactive APIs.

WebClient client = WebClient.create();

  client
  .get()
  .uri(URLConstants.URL)
  .header(URLConstants.API_KEY_NAME, URLConstants.API_KEY_VALUE)
  .retrieve()
  .bodyToMono(String.class)
  .subscribe(result->System.out.println(result));


WebClient client = WebClient.create();

    String result = client
            .post()
            .uri("https://reqbin.com/echo/post/json")
            .body(BodyInserters.fromValue(prepareRequest()))
            .exchange()
            .flatMap(response -> response.bodyToMono(String.class))
            .block();
    System.out.println("result::" + result);




CloseableHttpAsyncClient client = 
      HttpAsyncClients.createDefault();) {
   client.start();
    
    final SimpleHttpRequest request = 

CloseableHttpClient httpClient = HttpClients.createDefault();
      
      CloseableHttpResponse response = httpClient.execute(httpPost)


HttpClient client = HttpClient.newBuilder()
      .version(Version.HTTP_2)
      .followRedirects(Redirect.NORMAL)
      .build();
  
  HttpRequest request = HttpRequest.newBuilder()
     .uri(new URI(URLConstants.URL))
     .GET()
     .header(URLConstants.API_KEY_NAME, URLConstants.API_KEY_VALUE)
     .timeout(Duration.ofSeconds(10))
     .build();
  
  
  client.sendAsync(request, BodyHandlers.ofString())
    .thenApply(HttpResponse::body)
    .thenAccept(System.out::println)
    .join();

Tuesday, May 24, 2022

Simple REST API using Spring Webflux, WebClient and Junit

 Dear Java Developers,

we will look into an sample REST API created using Spring Boot, Spring Webflux (Reactive) and integrated with another API using Webclient. 

Also we will add unit test cases to test Controller, Service and Webclient classes. 


OrderService - Receives inputs and checks inventory and create order.

InventoryService checks and confirms products available in inventory. Secured with JWT Token. 


@ResponseStatus