Commit 2954323c authored by Imalka L.A.'s avatar Imalka L.A.

Create Get Solutions API

parent 31fa6a5c
...@@ -12,9 +12,15 @@ ...@@ -12,9 +12,15 @@
<artifactId>ceylon-e-agro-backend-service</artifactId> <artifactId>ceylon-e-agro-backend-service</artifactId>
<version>0.0.1-SNAPSHOT</version> <version>0.0.1-SNAPSHOT</version>
<name>ceylon-e-agro-backend-service</name> <name>ceylon-e-agro-backend-service</name>
<description>Farming through Technology Driven Solution App </description> <description>Farming through Technology Driven Solution App</description>
<properties> <properties>
<java.version>1.8</java.version> <java.version>1.8</java.version>
<!-- JaCoCo Properties -->
<jacoco.version>0.8.6</jacoco.version>
<sonar.java.coveragePlugin>jacoco</sonar.java.coveragePlugin>
<sonar.dynamicAnalysis>reuseReports</sonar.dynamicAnalysis>
<sonar.jacoco.reportPath>${project.basedir}/../target/jacoco.exec</sonar.jacoco.reportPath>
<sonar.language>java</sonar.language>
</properties> </properties>
<dependencies> <dependencies>
<dependency> <dependency>
...@@ -25,6 +31,28 @@ ...@@ -25,6 +31,28 @@
<groupId>org.springframework.boot</groupId> <groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId> <artifactId>spring-boot-starter-web</artifactId>
</dependency> </dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-jpa</artifactId>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<optional>true</optional>
</dependency>
<dependency>
<groupId>org.modelmapper</groupId>
<artifactId>modelmapper</artifactId>
<version>2.4.4</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-devtools</artifactId>
</dependency>
<dependency>
<groupId>org.hibernate.validator</groupId>
<artifactId>hibernate-validator</artifactId>
</dependency>
<dependency> <dependency>
<groupId>org.postgresql</groupId> <groupId>org.postgresql</groupId>
...@@ -36,6 +64,16 @@ ...@@ -36,6 +64,16 @@
<artifactId>spring-boot-starter-test</artifactId> <artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope> <scope>test</scope>
</dependency> </dependency>
<dependency>
<groupId>io.springfox</groupId>
<artifactId>springfox-boot-starter</artifactId>
<version>3.0.0</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-configuration-processor</artifactId>
<optional>true</optional>
</dependency>
</dependencies> </dependencies>
<build> <build>
......
...@@ -2,8 +2,11 @@ package com.ceyloneagro.ceyloneagrobackendservice; ...@@ -2,8 +2,11 @@ package com.ceyloneagro.ceyloneagrobackendservice;
import org.springframework.boot.SpringApplication; import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication; import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
@SpringBootApplication @SpringBootApplication
@EnableConfigurationProperties
public class CeylonEAgroBackendServiceApplication { public class CeylonEAgroBackendServiceApplication {
public static void main(String[] args) { public static void main(String[] args) {
......
package com.ceyloneagro.ceyloneagrobackendservice.config;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.cors.CorsConfiguration;
import org.springframework.web.cors.UrlBasedCorsConfigurationSource;
import org.springframework.web.filter.CorsFilter;
import java.util.Arrays;
import java.util.Collections;
@Configuration
public class ApplicationConfig {
@Bean
public CorsFilter corsFilter() {
final UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();
final CorsConfiguration config = new CorsConfiguration();
config.setAllowCredentials(true);
config.setAllowedOriginPatterns(Collections.singletonList("*"));
config.setAllowedHeaders(Arrays.asList("Origin", "Content-Type", "Accept","Authorization"));
config.setAllowedMethods(Arrays.asList("GET", "POST", "PUT", "DELETE", "OPTIONS"));
source.registerCorsConfiguration("/**", config);
return new CorsFilter(source);
}
}
\ No newline at end of file
package com.ceyloneagro.ceyloneagrobackendservice.config;
import ch.qos.logback.classic.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.http.HttpRequest;
import org.springframework.http.client.ClientHttpRequestExecution;
import org.springframework.http.client.ClientHttpRequestInterceptor;
import org.springframework.http.client.ClientHttpResponse;
import org.springframework.util.StreamUtils;
import java.io.IOException;
import java.nio.charset.Charset;
import java.nio.charset.StandardCharsets;
public class RequestResponseLoggingInterceptor implements ClientHttpRequestInterceptor {
private final Logger log = (Logger) LoggerFactory.getLogger(this.getClass());
private long requestTime;
private long responseTime;
@Override
public ClientHttpResponse intercept(HttpRequest request, byte[] body, ClientHttpRequestExecution execution)
throws IOException {
logRequest(request, body);
ClientHttpResponse response = execution.execute(request, body);
logResponse(response);
logInfo(request, response);
return response;
}
private void logInfo(HttpRequest request, ClientHttpResponse response) throws IOException {
if (!log.isDebugEnabled()) {
log.info("================================= begin ================================================");
log.info("Requested URI : {}", request.getURI());
log.info("Requested Method : {}", request.getMethod());
log.info("Response Status : {}", response.getStatusCode());
log.info("Response Time : {} ms", (responseTime - requestTime));
log.info("================================= end ================================================");
}
}
private void logRequest(HttpRequest request, byte[] body) {
requestTime = System.currentTimeMillis();
log.debug("===========================request begin================================================");
log.debug("URI : {}", request.getURI());
log.debug("Method : {}", request.getMethod());
log.debug("Headers : {}", request.getHeaders());
String requestBody = new String(body, StandardCharsets.UTF_8);
log.debug("Request body: {}", requestBody);
log.debug("==========================request end================================================");
}
private void logResponse(ClientHttpResponse response) throws IOException {
responseTime = System.currentTimeMillis();
log.debug("============================response begin==========================================");
log.debug("Status code : {}", response.getStatusCode());
log.debug("Headers : {}", response.getHeaders());
String responseBody = StreamUtils.copyToString(response.getBody(), Charset.defaultCharset());
log.debug("Response body: {}", responseBody);
log.debug("Response Time : {} ms", (responseTime - requestTime));
log.debug("=======================response end=================================================");
}
}
package com.ceyloneagro.ceyloneagrobackendservice.config;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.boot.web.client.RestTemplateBuilder;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.http.client.BufferingClientHttpRequestFactory;
import org.springframework.http.client.ClientHttpRequestFactory;
import org.springframework.http.client.SimpleClientHttpRequestFactory;
import org.springframework.web.client.RestTemplate;
import java.util.Collections;
@Configuration
public class RestTemplateConfig {
@Value("${rest-template.default.time-out}")
private int timeOut;
@Bean
public RestTemplate restTemplate(final RestTemplateBuilder builder) {
SimpleClientHttpRequestFactory simpleFactory = new SimpleClientHttpRequestFactory();
simpleFactory.setOutputStreaming(false);
simpleFactory.setConnectTimeout(timeOut);
simpleFactory.setReadTimeout(timeOut);
ClientHttpRequestFactory factory = new BufferingClientHttpRequestFactory(simpleFactory);
RestTemplate restTemplate = new RestTemplate(factory);
restTemplate.setInterceptors(Collections.singletonList(new RequestResponseLoggingInterceptor()));
return restTemplate;
}
}
package com.ceyloneagro.ceyloneagrobackendservice.config;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Profile;
import springfox.documentation.builders.PathSelectors;
import springfox.documentation.builders.RequestHandlerSelectors;
import springfox.documentation.spi.DocumentationType;
import springfox.documentation.spring.web.plugins.Docket;
import springfox.documentation.swagger2.annotations.EnableSwagger2;
@Configuration
@EnableSwagger2
@Profile({"!prod && swagger"})
public class SwaggerConfig {
@Bean
public Docket api() {
return new Docket(DocumentationType.SWAGGER_2).select().apis(RequestHandlerSelectors.any())
.paths(PathSelectors.any()).build();
}
}
package com.ceyloneagro.ceyloneagrobackendservice.config;
import org.modelmapper.ModelMapper;
import org.springframework.context.annotation.Bean;
import org.springframework.stereotype.Component;
@Component
public class UtilityConfig {
@Bean
public ModelMapper modelMapper() {
return new ModelMapper();
}
}
\ No newline at end of file
package com.ceyloneagro.ceyloneagrobackendservice.controller;
import com.ceyloneagro.ceyloneagrobackendservice.dto.response.BaseResponse;
import com.ceyloneagro.ceyloneagrobackendservice.dto.response.SolutionsResponse;
import com.ceyloneagro.ceyloneagrobackendservice.enumeration.ApplicationStatus;
import com.ceyloneagro.ceyloneagrobackendservice.service.SolutionService;
import org.springframework.http.HttpStatus;
import org.springframework.http.MediaType;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.*;
import javax.servlet.http.HttpServletRequest;
@RestController
@CrossOrigin(origins = "*")
@RequestMapping(value = "/api/v1/")
public class SolutionController {
private final SolutionService solutionService;
public SolutionController(SolutionService solutionService) {
this.solutionService = solutionService;
}
@GetMapping(value = "/solutions", produces = {MediaType.APPLICATION_JSON_VALUE})
public ResponseEntity<BaseResponse<SolutionsResponse>> getSolutionList(HttpServletRequest request, @RequestParam
(value = "page", defaultValue = "0") int page, @RequestParam(value = "limit", defaultValue = "25") int limit,
@RequestParam String disease) {
SolutionsResponse response=solutionService.getSolutionList(page,limit,disease);
BaseResponse<SolutionsResponse> baseResponse = new BaseResponse<>(ApplicationStatus.TOKEN_GENERATION_SUCCESS, response);
return new ResponseEntity<>(baseResponse, HttpStatus.OK);
}
}
\ No newline at end of file
package com.ceyloneagro.ceyloneagrobackendservice.dto;
import com.fasterxml.jackson.annotation.JsonInclude;
import com.fasterxml.jackson.annotation.JsonInclude.Include;
import lombok.Getter;
import lombok.Setter;
import lombok.ToString;
import java.util.HashMap;
import java.util.Map;
@Getter
@Setter
@ToString
@JsonInclude(Include.NON_NULL)
public class ErrorDetails {
private String message;
private Map<String,String> fieldErrors = new HashMap<>();
public ErrorDetails(String message) {
super();
this.message = message;
this.fieldErrors = null;
}
public ErrorDetails(Map<String,String> fieldErrors) {
super();
this.fieldErrors = fieldErrors;
this.message = null;
}
}
package com.ceyloneagro.ceyloneagrobackendservice.dto.response;
import com.ceyloneagro.ceyloneagrobackendservice.dto.ErrorDetails;
import com.ceyloneagro.ceyloneagrobackendservice.enumeration.ApplicationStatus;
import com.fasterxml.jackson.annotation.JsonInclude;
import com.fasterxml.jackson.annotation.JsonInclude.Include;
import lombok.Getter;
import lombok.Setter;
import lombok.ToString;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
@Setter
@Getter
@ToString
@JsonInclude(Include.NON_NULL)
public class BaseResponse<T> {
private String timestamp;
private String statusCode;
private String statusMessage;
private ErrorDetails errorDetails;
private T responseBody;
public BaseResponse() {
DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
timestamp = LocalDateTime.now().format(formatter);
}
public BaseResponse(ApplicationStatus status) {
this();
this.statusMessage = status.getMessage();
this.statusCode = status.getCode();
this.errorDetails = null;
this.responseBody =null;
}
public BaseResponse(ApplicationStatus status, T responseBody) {
this();
this.statusMessage = status.getMessage();
this.statusCode = status.getCode();
this.responseBody = responseBody;
this.errorDetails = null;
}
public BaseResponse(ApplicationStatus status, ErrorDetails errorDetails) {
this();
this.statusMessage = status.getMessage();
this.statusCode = status.getCode();
this.errorDetails = errorDetails;
this.responseBody =null;
}
public BaseResponse(String statusCode, String statusMessage, ErrorDetails errorDetails) {
this();
this.statusMessage = statusMessage;
this.statusCode = statusCode;
this.errorDetails = errorDetails;
this.responseBody =null;
}
public BaseResponse(String statusCode, String statusMessage, T responseBody) {
this();
this.statusMessage = statusMessage;
this.statusCode = statusCode;
this.responseBody = responseBody;
this.errorDetails = null;
}
public BaseResponse(String statusCode, String statusMessage) {
this();
this.statusMessage = statusMessage;
this.statusCode = statusCode;
this.errorDetails = null;
this.responseBody =null;
}
}
package com.ceyloneagro.ceyloneagrobackendservice.dto.response;
import com.fasterxml.jackson.annotation.JsonProperty;
import lombok.Data;
@Data
public class SolutionResponse {
@JsonProperty("solution_id")
private String solutionId;
@JsonProperty("solution_code")
private String solutionCode;
@JsonProperty("solution")
private String solution;
@JsonProperty("solution_description")
private String solutionDescription;
@JsonProperty("rate_score")
private Integer rateScore;
@JsonProperty("solution_type")
private Integer solutionType;
}
package com.ceyloneagro.ceyloneagrobackendservice.dto.response;
import com.fasterxml.jackson.annotation.JsonProperty;
import lombok.Data;
@Data
public class SolutionsResponse<T> {
@JsonProperty("disease")
private String disease;
@JsonProperty("solution")
private T solution;
@JsonProperty("currentPage")
private Integer currentPage;
@JsonProperty("totalItems")
private Long totalItems;
@JsonProperty("totalPages")
private Integer totalPages;
}
package com.ceyloneagro.ceyloneagrobackendservice.enumeration;
import lombok.Getter;
@Getter
public enum ApplicationStatus {
TOKEN_GENERATION_SUCCESS("S-000", "New user token generated."),
TOKEN_GENERATION_FAILED("F-000", "User token generation failed."),
USER_REGISTRATION_SUCCESS("S-001", "New user has been successfully created."),
USER_REGISTRATION_FAILED("F-001", "User registration failed.");
private String code;
private String message;
private ApplicationStatus(String code, String message) {
this.code = code;
this.message = message;
}
}
package com.ceyloneagro.ceyloneagrobackendservice.repository;
import com.ceyloneagro.ceyloneagrobackendservice.repository.domain.SolutionList;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.Pageable;
import org.springframework.data.repository.PagingAndSortingRepository;
import org.springframework.stereotype.Repository;
@Repository
public interface SolutionListRepository extends PagingAndSortingRepository<SolutionList, Long> {
Page<SolutionList> findByDiseaseName(String disease,Pageable pageableRequest);
}
package com.ceyloneagro.ceyloneagrobackendservice.repository.domain;
import lombok.AccessLevel;
import lombok.Getter;
import lombok.NoArgsConstructor;
import lombok.Setter;
import javax.persistence.*;
@Getter
@Setter
@NoArgsConstructor
@Entity
@Table(name = "corn_disease_solution_details")
public class SolutionList {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
@Setter(AccessLevel.NONE)
@Column(name = "solution_id")
private Long id;
@Column(name = "solution_code", length = 10, nullable = false, unique = true, updatable = true)
private String solutionCode;
@Column(name = "disease_name", length = 100, nullable = false,updatable = true)
private String diseaseName;
@Column(name = "solution", length = 100, nullable = false, unique = true, updatable = true)
private String solution;
@Column(name = "solution_description", length = 100, nullable = false, unique = true, updatable = true)
private String solutionDescription;
@Column(name = "solution_type", length = 100, nullable = false,updatable = true)
private String solutionType;
@Column(name = "rate_score", length = 10, nullable = false,updatable = false)
private Integer rateScore;
@Column(name = "rate_count", length = 10, nullable = false,updatable = false)
private Integer rateCount;
}
package com.ceyloneagro.ceyloneagrobackendservice.service;
import com.ceyloneagro.ceyloneagrobackendservice.dto.response.SolutionsResponse;
public interface SolutionService {
SolutionsResponse getSolutionList(int page, int limit,String disease);
//SolutionsResponse getSolutionListByName(int page, int limit,String disease);
}
package com.ceyloneagro.ceyloneagrobackendservice.service.impl;
import com.ceyloneagro.ceyloneagrobackendservice.dto.response.SolutionResponse;
import com.ceyloneagro.ceyloneagrobackendservice.dto.response.SolutionsResponse;
import com.ceyloneagro.ceyloneagrobackendservice.repository.SolutionListRepository;
import com.ceyloneagro.ceyloneagrobackendservice.repository.domain.SolutionList;
import com.ceyloneagro.ceyloneagrobackendservice.service.SolutionService;
import org.modelmapper.ModelMapper;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Pageable;
import org.springframework.stereotype.Service;
import java.util.ArrayList;
import java.util.List;
@Service
public class SolutionServiceImpl implements SolutionService {
@Autowired
ModelMapper mapper;
@Autowired
SolutionListRepository repository;
@Override
public SolutionsResponse<List<SolutionResponse>> getSolutionList(int page, int limit, String disease) {
List<SolutionResponse> solutionResponse = new ArrayList<>();
SolutionsResponse returnValue = new SolutionsResponse();
if (page > 0)
page = page - 1;
Pageable pageableRequest = PageRequest.of(page, limit);
Page<SolutionList> resourcePage = repository.findByDiseaseName(disease, pageableRequest);
List<SolutionList> resource = resourcePage.getContent();
for (SolutionList entity : resource) {
solutionResponse.add(mapper.map(entity, SolutionResponse.class));
}
returnValue.setDisease(disease);
returnValue.setSolution(solutionResponse);
returnValue.setCurrentPage(resourcePage.getNumber() + 1);
returnValue.setTotalItems(resourcePage.getTotalElements());
returnValue.setTotalPages(resourcePage.getTotalPages());
return returnValue;
}
}
#Application Config------------------------------------------
server:
port: 8081
servlet:
context-path: /ceylon-e-agro
spring:
application:
name: Ceylon E Agro
datasource:
url: jdbc:postgresql://ec2-3-212-143-188.compute-1.amazonaws.com:5432/dbla5n3qrcf5am
username: rgzlayunhmjzmu
password: 4862eb22efbd3054e330140b061fea249f6f37ceda3fa992f79ffa8750c9e18d
jpa:
hibernate.ddl-auto: update
generate-ddl: true
show-sql: true
#Rest Template Configuration---------------------------------
rest-template:
default:
time-out: 5000
#------------------------------------------------------------
\ No newline at end of file
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