Coding Test - Sudhakara- Spring Boot
Coding Test - Sudhakara- Spring Boot
Scenario:
You're building a microservices-based application for an e-commerce platform. One
microservice is responsible for managing product information (Product Service),
another manages orders (Order Service).
package com.hms.hms.dao;
import jakarta.persistence.*;
import lombok.AccessLevel;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
import lombok.experimental.FieldDefaults;
@Entity
@Data
@AllArgsConstructor
@NoArgsConstructor
@Table(name = "product")
@FieldDefaults(level = AccessLevel.PRIVATE)
public class Product {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
Long id;
String name;
String description;
}
----------
package com.hms.hms.repository;
import com.hms.hms.dao.Product;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.stereotype.Repository;
@Repository
public interface ProductRepository extends JpaRepository <Product, Long> {
}
------------
package com.hms.hms.service;
import com.hms.hms.dao.Product;
import com.hms.hms.repository.ProductRepository;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import java.util.List;
import java.util.Optional;
@Service
public class ProductService {
@Autowired
private ProductRepository productRepository;
public List<Product> listProducts() {
try {
return productRepository.findAll();
} catch (Exception e) {
throw new RuntimeException("Getting DB error while fetching records");
}
}
public Product getProductById(Long id) {
Optional<Product> productInfo = productRepository.findById(id);
if(!productInfo.isPresent()) {
throw new RuntimeException("Product Id info not found" + id);
}
return productInfo.get();
}
}
----------
package com.hms.hms.controller;
import com.hms.hms.dao.Product;
import com.hms.hms.service.ProductService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import java.util.List;
@RequestMapping("/api/")
@RestController
public class ProductController {
@Autowired
private ProductService productService;
@GetMapping("/products")
public List<Product> getList() {
return productService.listProducts();
}
@GetMapping("/products/{id}")
public Product getProductId(@PathVariable Long id) {
return productService.getProductById(id);
}
}
---------------
Order
____________
package com.hms.hms.dao;
import jakarta.persistence.*;
import lombok.AccessLevel;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
import lombok.experimental.FieldDefaults;
import java.time.LocalDate;
import java.util.List;
@Entity
@Data
@AllArgsConstructor
@NoArgsConstructor
@Table(name = "order")
@FieldDefaults(level = AccessLevel.PRIVATE)
public class Order {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
Long id;
String customerName;
LocalDate orderDate;
List<Long> productIds;
}
package com.hms.hms.repository;
import com.hms.hms.dao.Order;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.stereotype.Repository;
@Repository
public interface OrderRepository extends JpaRepository<Order, Long> {
}
------------
package com.hms.hms.service;
import com.hms.hms.dao.Order;
import com.hms.hms.dao.Product;
import com.hms.hms.repository.OrderRepository;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpMethod;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.stereotype.Service;
import org.springframework.web.client.RestClientException;
import org.springframework.web.client.RestTemplate;
@Service
public class OrderService {
@Autowired
private OrderRepository orderRepository;
@Autowired
private RestTemplate restTemplate;
private static final Logger log = LoggerFactory.getLogger(OrderService.class);
public Order createOrder(Order order) {
for (Long productId : order.getProductIds()) {
try {
ResponseEntity<Product> productResponse =
restTemplate.exchange("https://PRODUCT-URL/products"+ productId,
HttpMethod.GET, null, Product.class);
if(!productResponse.getStatusCode().is2xxSuccessful()) {
log.error("Product id not found "+ productId);
}
} catch (RestClientException e) {
log.error("Error:internal server error "+ e.getMessage());
throw new
RuntimeException(String.valueOf(HttpStatus.INTERNAL_SERVER_ERROR));
}
}
return orderRepository.save(order);
}
}
package com.hms.hms.controller;
import com.hms.hms.dao.Order;
import com.hms.hms.service.OrderService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
@RequestMapping("/api/")
@RestController
public class OrderController {
@Autowired
private OrderService orderService;
@PostMapping("/order")
public Order upsert(@Valid @RequestBody Order order) {
return orderService.createOrder(order);
}
}
----------
plugins {
id 'java'
id 'org.springframework.boot' version '3.3.0'
id 'io.spring.dependency-management' version '1.1.5'
id 'com.netflix.dgs.codegen' version '6.2.1'
}
group = 'com.hms'
version = '0.0.1-SNAPSHOT'
java {
toolchain {
languageVersion = JavaLanguageVersion.of(17)
}
}
configurations {
compileOnly {
extendsFrom annotationProcessor
}
}
repositories {
mavenCentral()
}
dependencies {
implementation 'org.springframework.boot:spring-boot-starter-web'
implementation 'org.springframework.boot:spring-boot-starter-data-jpa'
compileOnly 'org.projectlombok:lombok'
runtimeOnly 'com.mysql:mysql-connector-j'
annotationProcessor 'org.projectlombok:lombok'
testImplementation 'org.springframework.boot:spring-boot-starter-test'
testRuntimeOnly 'org.junit.platform:junit-platform-launcher'
implementation 'org.apache.kafka:kafka-clients:3.4.0'
implementation 'com.sun.mail:javax.mail:1.6.2'
implementation 'org.slf4j:slf4j-api:2.0.9'
}
generateJava {
schemaPaths = ["${projectDir}/src/main/resources/graphql-client"]
packageName = 'com.hms.hms.codegen'
generateClient = true
}
tasks.named('test') {
useJUnitPlatform()
}