Commit d1b90555 authored by Kali Padhi's avatar Kali Padhi

Validation and Exception added

parents e5751176 75bd2ac8
......@@ -23,6 +23,7 @@ repositories {
dependencies {
implementation 'org.springframework.boot:spring-boot-starter-web'
implementation 'org.springframework.boot:spring-boot-starter-webflux'
//compile group: 'org.springframework', name: 'spring-context', version: '5.2.5.RELEASE'
compile group: 'com.google.guava', name: 'guava', version: '28.2-jre'
compileOnly 'org.projectlombok:lombok'
......@@ -33,15 +34,22 @@ dependencies {
exclude group: 'org.junit.vintage', module: 'junit-vintage-engine'
}
compile 'com.nisum:exceptionservice:0.0.1'
implementation group: 'junit', name: 'junit', version: '4.12'
testImplementation('org.springframework.boot:spring-boot-starter-test')
testImplementation group: 'org.springframework.boot', name: 'spring-boot-starter-test', version: '2.0.3.RELEASE'
testImplementation group: 'junit', name: 'junit', version: '4.12'
testImplementation 'org.junit.platform:junit-platform-commons:1.5.2'
compile group: 'org.apache.commons', name: 'commons-lang3', version: '3.0'
testImplementation 'io.projectreactor:reactor-test'
}
tasks.withType(Test){
scanForTestClasses = false
include "**/*Test.class"
}
test {
useJUnitPlatform()
}
......@@ -2,10 +2,12 @@ package com.nisum.offertransactionservice;
import com.nisum.offertransactionservice.dao.OfferLookupRepo;
import com.nisum.offertransactionservice.model.OfferLookup;
import com.safeway.epe.exception.ExceptionResponseHandlerImpl;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.CommandLineRunner;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.annotation.Bean;
@SpringBootApplication
public class OffertransactionserviceApplication {
......@@ -14,4 +16,10 @@ public class OffertransactionserviceApplication {
SpringApplication.run(OffertransactionserviceApplication.class, args);
}
@Bean
public ExceptionResponseHandlerImpl getExceptionService(){
return new ExceptionResponseHandlerImpl();
}
}
package com.nisum.offertransactionservice.config;
import com.nisum.offertransactionservice.handler.MyResponseErrorHandler;
import org.springframework.boot.web.client.RestTemplateBuilder;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.PropertySource;
import org.springframework.web.client.*;
@Configuration
public class OfferTransactionConfig {
@Bean
public RestTemplate getRestTemplate() {
return new RestTemplateBuilder()
.errorHandler(new MyResponseErrorHandler())
.build();
}
}
......@@ -8,6 +8,8 @@ import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RestController;
import javax.validation.Valid;
@RestController
public class OfferTransactionController {
......@@ -15,8 +17,7 @@ public class OfferTransactionController {
private OfferCallingPEService offerCallingPEService;
@PostMapping("offerTransactionCall")
public OfferTransactionResponse getOfferTransactionResponse(@RequestBody OfferTransactionRequest offerTransactionRequest){
//TODO: validate the offerRequest
public OfferTransactionResponse getOfferTransactionResponse(@Valid @RequestBody OfferTransactionRequest offerTransactionRequest){
return offerCallingPEService.getDiscountedItemList(offerTransactionRequest);
}
......
......@@ -8,6 +8,7 @@ import java.util.function.Function;
@Component
public class PEResponseToOfferTransactionResConverter implements Function<PEResponse, OfferTransactionResponse> {
@Override
public OfferTransactionResponse apply(PEResponse peResponse) {
OfferTransactionResponse offerTransactionResponse = new OfferTransactionResponse();
......
package com.nisum.offertransactionservice.genericexception;
public class GlobalApiGenericException extends Exception {
import com.safeway.epe.model.Response;
public class GlobalApiGenericException extends RuntimeException {
private static final long serialVersionUID = -3841677326659278730L;
......@@ -9,6 +11,19 @@ public class GlobalApiGenericException extends Exception {
private boolean isHttpError;
private Response response;
public GlobalApiGenericException(Response response,String statusCode){
this.response=response;
this.statusCode= statusCode;
}
public GlobalApiGenericException(String debugMessage){
this.statusCode=debugMessage;
}
public GlobalApiGenericException(String debugMessage, Throwable ex, String statuCode, boolean isHttpError) {
super(debugMessage, ex);
this.statusCode =statuCode;
......@@ -30,4 +45,12 @@ public class GlobalApiGenericException extends Exception {
public void setHttpError(boolean httpError) {
isHttpError = httpError;
}
public Response getResponse() {
return response;
}
public void setResponse(Response response) {
this.response = response;
}
}
......@@ -28,17 +28,20 @@ public class GlobalExceptionHandler extends ResponseEntityExceptionHandler {
@ExceptionHandler(GlobalApiGenericException.class)
protected ResponseEntity<Response> handleEntityNotFound(GlobalApiGenericException ex, WebRequest webRequest) {
Response ErrorResponse;
if(ex.isHttpError()){
ErrorResponse = exceptionResponseHandler.
Response errorResponse;
if(ex.getResponse()!=null){
errorResponse= ex.getResponse();
}
else if(ex.isHttpError()){
errorResponse = exceptionResponseHandler.
createHttpErrorResponse(ex.getStatusCode(), "Http Error In Application",
ex, getUri((ServletWebRequest) webRequest), getHttpStatus(ex.getStatusCode()));
}else{
ErrorResponse = exceptionResponseHandler.
errorResponse = exceptionResponseHandler.
createApiErrorResponse(ex.getStatusCode(), "Search Result Not Found On Database",
ex, getUri((ServletWebRequest) webRequest), getHttpStatus(ex.getStatusCode()));
}
return new ResponseEntity<>(ErrorResponse,getHttpStatus(ex.getStatusCode()));
return new ResponseEntity<>(errorResponse,getHttpStatus(ex.getStatusCode()));
}
@Override
......
package com.nisum.offertransactionservice.handler;
import org.springframework.http.HttpMethod;
import org.springframework.http.HttpStatus;
import org.springframework.http.client.ClientHttpResponse;
import org.springframework.stereotype.Component;
import org.springframework.web.client.ResponseErrorHandler;
import java.io.IOException;
import java.io.InputStream;
import java.net.URI;
import java.util.Scanner;
@Component
public class MyResponseErrorHandler implements ResponseErrorHandler {
@Override
public boolean hasError(ClientHttpResponse clientHttpResponse) throws IOException {
HttpStatus status = clientHttpResponse.getStatusCode();
return status.is4xxClientError() || status.is5xxServerError();
}
@Override
public void handleError(ClientHttpResponse clientHttpResponse) throws IOException {
String responseAsString = toString(clientHttpResponse.getBody());
throw new CustomException(responseAsString);
}
@Override
public void handleError(URI url, HttpMethod method, ClientHttpResponse response) throws IOException {
String responseAsString = toString(response.getBody());
throw new CustomException(responseAsString);
}
String toString(InputStream inputStream) {
Scanner s = new Scanner(inputStream).useDelimiter("\\A");
return s.hasNext() ? s.next() : "";
}
static class CustomException extends IOException {
public CustomException(String message) {
super(message);
}
}
}
......@@ -6,13 +6,23 @@ import lombok.Data;
import lombok.NoArgsConstructor;
import lombok.experimental.FieldDefaults;
import javax.validation.constraints.NotNull;
@Data
@NoArgsConstructor
@AllArgsConstructor
@FieldDefaults(level = AccessLevel.PRIVATE, makeFinal = false)
public class Item {
@NotNull
String itemName;
@NotNull
String itemId;
@NotNull
Double price;
@NotNull
String cmsCoupouns;
}
......@@ -6,6 +6,7 @@ import lombok.Data;
import lombok.NoArgsConstructor;
import lombok.experimental.FieldDefaults;
import javax.validation.Valid;
import javax.validation.constraints.NotNull;
import java.util.List;
......@@ -19,5 +20,7 @@ public class OfferTransactionRequest {
@NotNull
String hhId;
@Valid
List<Item> itemList = newArrayList();
}
......@@ -3,22 +3,37 @@ package com.nisum.offertransactionservice.service;
import com.nisum.offertransactionservice.converter.OfferConverter;
import com.nisum.offertransactionservice.converter.PEResponseToOfferTransactionResConverter;
import com.nisum.offertransactionservice.dao.OfferLookupRepo;
import com.nisum.offertransactionservice.genericexception.GlobalApiGenericException;
import com.nisum.offertransactionservice.model.*;
import com.safeway.epe.model.Response;
import lombok.extern.log4j.Log4j;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.exception.ExceptionUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.PropertySource;
import org.springframework.http.ResponseEntity;
import org.springframework.core.NestedExceptionUtils;
import org.springframework.http.*;
import org.springframework.stereotype.Service;
import org.springframework.web.client.RestClientResponseException;
import org.springframework.web.client.RestTemplate;
import org.springframework.web.reactive.function.client.*;
import reactor.core.publisher.Flux;
import reactor.core.publisher.Mono;
import javax.annotation.PostConstruct;
import java.nio.charset.Charset;
import java.time.ZonedDateTime;
import java.util.ArrayList;
import java.util.List;
import static com.google.common.collect.Lists.newArrayList;
@Service
@PropertySource("classpath:application.properties")
@Slf4j
public class OfferCallingPEService {
@Autowired
private OfferConverter offerConverter;
......@@ -28,38 +43,74 @@ public class OfferCallingPEService {
@Autowired
private PEResponseToOfferTransactionResConverter peResponseToOfferTransactionResConverter;
@Autowired
private RestTemplate restTemplate;
private WebClient webClient;
@Value("${promotion.engine.calculate.discount.url}")
private String promotionEngineUrl ;
private String promotionEngineUrl;
@Value("${promotion.engine.baseUrl}")
private String baseUrl;
@PostConstruct
public void init() {
webClient = WebClient.builder().baseUrl(baseUrl).
defaultHeader(HttpHeaders.CONTENT_TYPE, MediaType.APPLICATION_JSON_VALUE).
filter(logRequest()).
filter(logResponse()).
build();
}
private ExchangeFilterFunction logRequest() {
return ExchangeFilterFunction.ofRequestProcessor(clientRequest -> {
log.info("Promotional Request {}",clientRequest);
return Mono.just(clientRequest);
});
}
private ExchangeFilterFunction logResponse() {
return ExchangeFilterFunction.ofResponseProcessor(clientResponse -> {
log.info("Promotional Request {}",clientResponse);
return Mono.just(clientResponse);
});
}
public OfferTransactionResponse getDiscountedItemList(OfferTransactionRequest offerTransactionRequest) {
List<OfferLookup> eligibleOffer = newArrayList();
log.info("Inside getDiscountedItemList Method");
List<OfferLookup> eligibleOffer = new ArrayList();
offerLookupRepo.findAll().forEach(eligibleOffer::add);
OfferTransactionResponse offerTransactionResponse =null;
//TODO validate whether we got the offers from DB or not
//TODO DB call success or not
if(eligibleOffer.isEmpty()){
log.error("Offer lookup Object is empty");
throw new GlobalApiGenericException("Unable to get the Offer Response ",new Exception("exception e"),"400",false);
}
log.debug("Offer lookup Object {}",offerLookupRepo);
OfferTransactionResponse offerTransactionResponse;
PERequest peRequest = offerConverter.apply(offerTransactionRequest);
peRequest.setEligibleOffers(eligibleOffer);
ResponseEntity<Object> peResponse = getPeResponseResponseEntity(peRequest);
if(peResponse.getBody() instanceof PEResponse){
offerTransactionResponse = peResponseToOfferTransactionResConverter.apply((PEResponse)peResponse.getBody());
}
log.info("Promotional Engine WebClient call Start");
Flux<PEResponse> peResponseFlux = webClient.post().
uri(promotionEngineUrl).
accept(MediaType.APPLICATION_JSON).
contentType(MediaType.APPLICATION_JSON).
body(Mono.just(peRequest), PERequest.class).
retrieve().
onStatus(HttpStatus::is4xxClientError, clientResponse -> handleError(clientResponse)).
onStatus(HttpStatus::is5xxServerError, clientResponse -> handleError(clientResponse)).
bodyToFlux(PEResponse.class);
log.debug("Promotional Engine WebClient call End");
offerTransactionResponse = peResponseToOfferTransactionResConverter.apply(peResponseFlux.toStream().findFirst().get());
log.debug("Offer Transaction Response {}",offerTransactionResponse);
return offerTransactionResponse;
}
private ResponseEntity<Object> getPeResponseResponseEntity(PERequest peRequest) {
try{
restTemplate.postForEntity("http://localhost:8081"+promotionEngineUrl,peRequest,PEResponse.class);
}catch(RestClientResponseException e){
return ResponseEntity
.status(e.getRawStatusCode())
.body(e.getResponseBodyAsString());
}
return null;
private Mono<? extends Throwable> handleError(ClientResponse clientResponse)throws GlobalApiGenericException {
final Mono<Response> responseMono = clientResponse.bodyToMono(Response.class);
return responseMono.flatMap(response -> {
log.error("Error Response While Calling PE Service {}",response);
throw new GlobalApiGenericException(response, response.getHttpStatusCode());
});
}
}
......@@ -6,3 +6,6 @@ spring.datasource.password=password123
promotion.engine.calculate.discount.url=/promotionEngine/calculateDiscount
promotion.engine.baseUrl=http://localhost:8081
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment