Skip to content

Commit

Permalink
Merge pull request #17 from ADPRO-C11/staging
Browse files Browse the repository at this point in the history
Staging
  • Loading branch information
sdikyarts authored May 25, 2024
2 parents a5c15e1 + bf9e606 commit 042f2bb
Show file tree
Hide file tree
Showing 10 changed files with 212 additions and 85 deletions.
Original file line number Diff line number Diff line change
@@ -1,22 +1,22 @@
package snackscription.subscriptionadmin.config;

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.core.task.AsyncTaskExecutor;
import org.springframework.scheduling.annotation.AsyncConfigurer;
import org.springframework.scheduling.annotation.EnableAsync;
import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor;

import java.util.concurrent.Executor;

@Configuration
@EnableAsync
public class AsyncConfiguration {
@Bean("asyncTaskExecutor")
public Executor asyncTaskExecutor(){
ThreadPoolTaskExecutor taskExecutor = new ThreadPoolTaskExecutor();
taskExecutor.setCorePoolSize(4);
taskExecutor.setQueueCapacity(150);
taskExecutor.setThreadNamePrefix("AsyncTaskThread-");
taskExecutor.initialize();
return taskExecutor;
public class AsyncConfiguration implements AsyncConfigurer {
@Override
public AsyncTaskExecutor getAsyncExecutor() {
ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor();
executor.setCorePoolSize(5);
executor.setMaxPoolSize(10);
executor.setQueueCapacity(100);
executor.setThreadNamePrefix("Async-Executor-");
executor.initialize();
return executor;
}
}
}
Original file line number Diff line number Diff line change
@@ -1,13 +1,15 @@
package snackscription.subscriptionadmin.controller;

import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.*;
import snackscription.subscriptionadmin.dto.AdminDTO;
import snackscription.subscriptionadmin.model.AdminSubscription;
import snackscription.subscriptionadmin.service.AdminService;

import java.util.List;
import java.util.Optional;
import java.util.UUID;
import java.util.concurrent.CompletableFuture;

@RestController
@RequestMapping("/admin")
Expand All @@ -20,32 +22,46 @@ public AdminController(AdminService adminService) {
}

@PostMapping("/create")
public ResponseEntity<AdminSubscription> create(@RequestBody AdminDTO adminDTO) {
AdminSubscription adminSubscription = adminService.create(adminDTO);
return new ResponseEntity<>(adminSubscription, HttpStatus.CREATED);
public CompletableFuture<ResponseEntity<AdminSubscription>> create(@RequestBody AdminDTO adminDTO) {
return adminService.create(adminDTO).thenApply(ResponseEntity::ok)
.exceptionally(ex -> ResponseEntity.badRequest().build());

}

@GetMapping("/list")
public ResponseEntity<List<AdminDTO>> findAll() {
List<AdminDTO> adminDTOList = adminService.findAll();
return new ResponseEntity<>(adminDTOList, HttpStatus.OK);
public CompletableFuture<ResponseEntity<List<AdminDTO>>> findAll() {
return adminService.findAll().thenApply(ResponseEntity::ok);
}

@GetMapping("/{subscriptionId}")
public ResponseEntity<AdminDTO> findById(@PathVariable String subscriptionId) {
AdminDTO adminDTO = adminService.findById(subscriptionId);
return new ResponseEntity<>(adminDTO, HttpStatus.OK);
public CompletableFuture<ResponseEntity<AdminDTO>> findById(@PathVariable String subscriptionId) {
try {
UUID.fromString(subscriptionId);
} catch (IllegalArgumentException e) {
return CompletableFuture.completedFuture(ResponseEntity.badRequest().build());
}
return adminService.findById(subscriptionId).thenApply(ResponseEntity::ok)
.exceptionally(ex -> ResponseEntity.notFound().build());
}

@PutMapping("/update")
public ResponseEntity<AdminSubscription> update(@RequestBody AdminDTO adminDTO) {
AdminSubscription adminSubscription = adminService.update(adminDTO);
return new ResponseEntity<>(adminSubscription, HttpStatus.OK);
public CompletableFuture<ResponseEntity<AdminSubscription>> update(@RequestBody AdminDTO adminDTO) {
if (adminDTO.getSubscriptionId() == null) {
return CompletableFuture.completedFuture(ResponseEntity.badRequest().build());
}

return adminService.update(adminDTO).thenApply(ResponseEntity::ok)
.exceptionally(ex -> ResponseEntity.notFound().build());
}

@DeleteMapping("/{subscriptionId}")
public ResponseEntity<Void> delete(@PathVariable String subscriptionId) {
adminService.delete(subscriptionId);
return new ResponseEntity<>(HttpStatus.NO_CONTENT);
public CompletableFuture<ResponseEntity<String>> delete(@PathVariable String subscriptionId) {
try {
UUID.fromString(subscriptionId);
} catch (IllegalArgumentException e) {
return CompletableFuture.completedFuture(ResponseEntity.badRequest().build());
}
return adminService.delete(subscriptionId).thenApply(deleted -> ResponseEntity.ok("DELETE SUCCESS"))
.exceptionally(ex -> ResponseEntity.notFound().build());
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -10,14 +10,15 @@
public class DTOMapper {

public static AdminDTO convertModelToDto(AdminSubscription adminSubscription) {
return new AdminDTO(
adminSubscription.getSubscriptionId(),
adminSubscription.getUniqueCode(),
adminSubscription.getSubscriberName(),
adminSubscription.getSubscriberId(),
adminSubscription.getSubscriptionBoxId(),
adminSubscription.getSubscriptionStatus()
);
AdminDTO adminDTO = new AdminDTO();
adminDTO.setSubscriptionId(adminSubscription.getSubscriptionId());
adminDTO.setSubscriptionType(adminSubscription.getSubscriptionType());
adminDTO.setSubscriberName(adminSubscription.getSubscriberName());
adminDTO.setSubscriberId(adminSubscription.getSubscriberId());
adminDTO.setSubscriptionBoxId(adminSubscription.getSubscriptionBoxId());
adminDTO.setSubscriptionStatus(adminSubscription.getSubscriptionStatus());
adminDTO.setUniqueCode(adminSubscription.getUniqueCode());
return adminDTO;
}

public static AdminSubscription convertDTOtoModel(AdminDTO adminDTO) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,12 +3,15 @@
import snackscription.subscriptionadmin.dto.AdminDTO;
import snackscription.subscriptionadmin.model.AdminSubscription;

import java.util.Optional;
import java.util.concurrent.CompletableFuture;

import java.util.List;

public interface AdminService {
AdminSubscription create(AdminDTO adminDTO);
List<AdminDTO> findAll();
AdminDTO findById(String subscriptionId);
AdminSubscription update(AdminDTO adminDTO);
void delete(String subscriptionId);
CompletableFuture<AdminSubscription> create(AdminDTO adminDTO);
CompletableFuture<List<AdminDTO>> findAll();
CompletableFuture<AdminDTO> findById(String subscriptionId);
CompletableFuture<AdminSubscription> update(AdminDTO adminDTO);
CompletableFuture<Void> delete(String subscriptionId);
}
Original file line number Diff line number Diff line change
Expand Up @@ -5,66 +5,76 @@
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import snackscription.subscriptionadmin.dto.AdminDTO;
import org.springframework.scheduling.annotation.Async;

import java.util.List;
import java.util.concurrent.CompletableFuture;
import java.util.stream.Collectors;

import snackscription.subscriptionadmin.dto.DTOMapper;


@Service
public class AdminServiceImpl implements AdminService{

@Autowired
private AdminRepository adminRepository;

@Override
public AdminSubscription create(AdminDTO adminDTO) {
@Async
public CompletableFuture<AdminSubscription> create(AdminDTO adminDTO) {
AdminSubscription adminSubscription = DTOMapper.convertDTOtoModel(adminDTO);
return adminRepository.create(adminSubscription);
return CompletableFuture.completedFuture(adminRepository.create(adminSubscription));
}

@Override
public List<AdminDTO> findAll() {
return adminRepository.findAll()
.stream()
@Async
public CompletableFuture<List<AdminDTO>> findAll() {
List<AdminSubscription> adminSubscriptions = adminRepository.findAll();
List<AdminDTO> adminDtos = adminSubscriptions.stream()
.map(DTOMapper::convertModelToDto)
.toList();
.collect(Collectors.toList());
return CompletableFuture.completedFuture(adminDtos);
}

@Override
public AdminDTO findById(String subscriptionId) {
@Async
public CompletableFuture<AdminDTO> findById(String subscriptionId) {
if(subscriptionId == null || subscriptionId.isBlank()){
throw new IllegalArgumentException("ID cannot be null or empty");
}

AdminSubscription adminSubscription = adminRepository.findById(subscriptionId)
return adminRepository.findById(subscriptionId)
.map(DTOMapper::convertModelToDto)
.map(CompletableFuture::completedFuture)
.orElseThrow(() -> new IllegalArgumentException("Subscription not found"));

return DTOMapper.convertModelToDto(adminSubscription);
}

@Override
public AdminSubscription update(AdminDTO adminDTO) {
@Async
public CompletableFuture<AdminSubscription> update(AdminDTO adminDTO) {
if(adminDTO == null) {
throw new IllegalArgumentException("AdminDTO cannot be null");
}

AdminSubscription adminSubscription = adminRepository.findById(adminDTO.getSubscriptionId())
.orElseThrow(() -> new IllegalArgumentException("Subscription not found"));

DTOMapper.updateAdminSubscription(adminSubscription, adminDTO);
return adminRepository.update(adminSubscription);
return adminRepository.findById(adminDTO.getSubscriptionId()).
map(adminSubscription -> {
DTOMapper.updateAdminSubscription(adminSubscription, adminDTO);
return CompletableFuture.completedFuture(adminRepository.update(adminSubscription));
}).orElseThrow(() -> new IllegalArgumentException("Subscription not found"));
}

@Override
public void delete(String subscriptionId) {
@Async
public CompletableFuture<Void> delete(String subscriptionId) {
if(subscriptionId == null || subscriptionId.isBlank()){
throw new IllegalArgumentException("ID cannot be null or empty");
}

if(adminRepository.findById(subscriptionId).isEmpty()){
if (adminRepository.findById(subscriptionId).isEmpty()) {
throw new IllegalArgumentException("Subscription not found");
}

adminRepository.delete(subscriptionId);
return CompletableFuture.completedFuture(null);
}
}
2 changes: 1 addition & 1 deletion src/main/resources/application-dev.properties
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
spring.datasource.url=jdbc:postgresql://localhost:5432/subscription-admin/
spring.datasource.url=jdbc:postgresql://postgres:5432/subscription-admin/
spring.datasource.username=postgres
spring.datasource.password=postgres
spring.jpa.hibernate.ddl-auto=create-drop
Expand Down
2 changes: 1 addition & 1 deletion src/main/resources/application-prod.properties
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
spring.datasource.url=jdbc:postgresql://aws-0-ap-southeast-1.pooler.supabase.com:5432/postgres?user=postgres.thnfvhxtvcbfxndlxdze&password=YouMakeStrayKidsStay
spring.datasource.url=jdbc:postgresql://aws-0-ap-southeast-1.pooler.supabase.com:5432/postgres
spring.datasource.username=postgres.thnfvhxtvcbfxndlxdze
spring.datasource.password=YouMakeStrayKidsStay
spring.jpa.hibernate.ddl-auto=update
Expand Down
2 changes: 1 addition & 1 deletion src/main/resources/application-test.properties
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
spring.datasource.url=jdbc:postgresql://postgres:5432/subscription-admin
spring.datasource.url=jdbc:postgresql://postgres:5432/subscription-admin/
spring.datasource.username=postgres
spring.datasource.password=postgres
spring.jpa.hibernate.ddl-auto=create
Expand Down
Original file line number Diff line number Diff line change
@@ -1,19 +1,20 @@
package snackscription.subscriptionadmin.controller;

import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.*;
import org.mockito.InjectMocks;
import org.mockito.Mock;
import org.mockito.MockitoAnnotations;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import snackscription.subscriptionadmin.dto.AdminDTO;
import snackscription.subscriptionadmin.model.AdminSubscription;
import snackscription.subscriptionadmin.service.AdminService;

import java.util.Collections;
import java.util.List;
import java.util.Optional;
import java.util.concurrent.CompletableFuture;

import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.*;
import static org.mockito.Mockito.*;

public class AdminControllerTest {
Expand All @@ -24,16 +25,79 @@ public class AdminControllerTest {
@InjectMocks
private AdminController adminController;

public AdminControllerTest() {
private AdminDTO adminDTO;
private AdminSubscription adminSubscription;

@BeforeEach
void setUp(){
MockitoAnnotations.openMocks(this);

adminDTO = new AdminDTO();
adminDTO.setSubscriptionId("1");
adminDTO.setSubscriptionType("MONTHLY");
adminDTO.setSubscriberName("Stray Kids");
adminDTO.setSubscriberId("0325");
adminDTO.setSubscriptionBoxId("143ily");
adminDTO.setSubscriptionStatus("PENDING");

adminSubscription = new AdminSubscription();
adminSubscription.setSubscriptionId("1");
adminSubscription.setSubscriptionType("MONTHLY");
adminSubscription.setSubscriberName("Stray Kids");
adminSubscription.setSubscriberId("0325");
adminSubscription.setSubscriptionBoxId("143ily");
adminSubscription.setSubscriptionStatus("PENDING");
}

@Test
void testCreate(){
when(adminService.create(adminDTO)).thenReturn(CompletableFuture.completedFuture(adminSubscription));

CompletableFuture<ResponseEntity<AdminSubscription>> response = adminController.create(adminDTO);
assertNotNull(response);
assertEquals(ResponseEntity.ok(adminSubscription), response.join());
}

@Test
void testCreate() {
List<AdminDTO> adminDTOList = Collections.singletonList(new AdminDTO());
void testFindAll(){
List<AdminDTO> adminDTOList = Collections.singletonList(adminDTO);
when(adminService.findAll()).thenReturn(CompletableFuture.completedFuture(adminDTOList));

when(adminService.findAll()).thenReturn(adminDTOList);
CompletableFuture<ResponseEntity<List<AdminDTO>>> response = adminController.findAll();
assertNotNull(response);
assertEquals(ResponseEntity.ok(adminDTOList), response.join());
}

@Test
void testFindById(){
String validUUID = "8a56e04b-d0c8-4e43-b2e0-fdf43e304d9e";
adminDTO.setSubscriptionId(validUUID);
adminSubscription.setSubscriptionId(validUUID);
when(adminService.findById(validUUID)).thenReturn(CompletableFuture.completedFuture(adminDTO));

CompletableFuture<ResponseEntity<AdminDTO>> result = adminController.findById(validUUID);

assertNotNull(result);
assertTrue(result.isDone());
assertEquals(ResponseEntity.ok(adminDTO), result.join());
}

@Test
void testUpdate(){
when(adminService.update(adminDTO)).thenReturn(CompletableFuture.completedFuture(adminSubscription));

CompletableFuture<ResponseEntity<AdminSubscription>> response = adminController.update(adminDTO);
assertNotNull(response);
assertEquals(ResponseEntity.ok(adminSubscription), response.join());
}

@Test
void testDelete(){
String validUUID = "8a56e04b-d0c8-4e43-b2e0-fdf43e304d9e";
when(adminService.delete(validUUID)).thenReturn(CompletableFuture.completedFuture(null));

ResponseEntity<List<AdminDTO>> responseEntity = adminController.findAll();
CompletableFuture<ResponseEntity<String>> response = adminController.delete(validUUID);
assertNotNull(response);
assertEquals(ResponseEntity.ok("DELETE SUCCESS"), response.join());
}
}
Loading

0 comments on commit 042f2bb

Please sign in to comment.