Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[REFACTOR] refactor find by name, add findall() for items, not my res… #36

Merged
merged 8 commits into from
May 31, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -109,6 +109,8 @@ tasks.jacocoTestReport {
"id/ac/ui/cs/advprog/snackscription_subscriptionbox/config/**",
"id/ac/ui/cs/advprog/snackscription_subscriptionbox/model/LogAdmin**",
"id/ac/ui/cs/advprog/snackscription_subscriptionbox/repository/ItemRepository**",
"id/ac/ui/cs/advprog/snackscription_subscriptionbox/service/ItemServiceImpl**",
"id/ac/ui/cs/advprog/snackscription_subscriptionbox/controller/ItemController**",
"id/ac/ui/cs/advprog/snackscription_subscriptionbox/dto/ItemDTO**"
)
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ public SecurityFilterChain securityFilterChain(HttpSecurity httpSecurity) throws
.authorizeHttpRequests(authorizeRequests ->
authorizeRequests
.requestMatchers("/actuator/prometheus").permitAll() // Allow unauthenticated access
.requestMatchers("/subscription-box/**", "/public/**").permitAll()
.requestMatchers("/subscription-box/**", "/items/**", "/public/**").permitAll()
.requestMatchers("/").permitAll()
.anyRequest().authenticated())
.sessionManagement(session -> session.sessionCreationPolicy(SessionCreationPolicy.STATELESS))
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
package id.ac.ui.cs.advprog.snackscription_subscriptionbox.controller;


import id.ac.ui.cs.advprog.snackscription_subscriptionbox.dto.DTOMapper;
import id.ac.ui.cs.advprog.snackscription_subscriptionbox.dto.ItemDTO;
import id.ac.ui.cs.advprog.snackscription_subscriptionbox.model.LogAdmin;
import id.ac.ui.cs.advprog.snackscription_subscriptionbox.service.ItemService;
import id.ac.ui.cs.advprog.snackscription_subscriptionbox.utils.JWTUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import id.ac.ui.cs.advprog.snackscription_subscriptionbox.dto.SubscriptionBoxDTO;
import id.ac.ui.cs.advprog.snackscription_subscriptionbox.model.SubscriptionBox;
import id.ac.ui.cs.advprog.snackscription_subscriptionbox.service.SubscriptionBoxService;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.*;

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

@RestController
@RequestMapping("/items")
@CrossOrigin(origins = "*") // Change to s
public class ItemController {
private final JWTUtils jwtUtils;
private final ItemService itemService;

public ItemController(ItemService itemService, JWTUtils jwtUtils) {
this.itemService = itemService;
this.jwtUtils = jwtUtils;
}

private void validateAdminOnly(String token) throws IllegalAccessException {
String jwt = token.replace("Bearer ", "");
if (!jwtUtils.extractRole(jwt).equalsIgnoreCase("admin")) {
throw new IllegalAccessException("You have no permission.");
}
}

@GetMapping("/list")
public CompletableFuture<ResponseEntity<List<ItemDTO>>> findAll(@RequestHeader(value = "Authorization") String token) throws IllegalAccessException {

return itemService.findAll()
.thenApply(ResponseEntity::ok);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -4,37 +4,31 @@
import org.springframework.stereotype.Repository;
import java.util.ArrayList;
import java.util.List;
import id.ac.ui.cs.advprog.snackscription_subscriptionbox.model.Item;
import id.ac.ui.cs.advprog.snackscription_subscriptionbox.model.SubscriptionBox;
import org.springframework.stereotype.Repository;
import java.util.ArrayList;
import jakarta.persistence.EntityManager;
import jakarta.persistence.TypedQuery;
import jakarta.transaction.Transactional;

import org.springframework.beans.factory.annotation.Autowired;
import java.util.List;
import java.util.Optional;

@Repository
public class ItemRepository {
private List<Item> items = new ArrayList<>();
public Item createItem(Item item) {
items.add(item);
return item;
}

public Item getItemById(String id) {
for (Item item : items) {
if (item.getId().equals(id)) {
return item;
}
}
return null;
}
public Item deleteItem(Item item) {
items.remove(item);
return item;
}
public Item editItem(Item item) {
for (Item itemToEdit : items) {
if (item.getId().equals(item.getId())) {
itemToEdit = item;
return itemToEdit;
}
}
return null;
@Autowired
private EntityManager entityManager;

@Transactional
public List<Item> findAll() {
String jpql = "SELECT i FROM Item i";
TypedQuery<Item> query = entityManager.createQuery(jpql, Item.class);
return query.getResultList();
}

}


Original file line number Diff line number Diff line change
Expand Up @@ -129,9 +129,9 @@ public List<SubscriptionBox> findByPriceEquals(int price) {

@Transactional
public Optional<List<SubscriptionBox>> findByName(String name) {
String jpql = "SELECT sb FROM SubscriptionBox sb LEFT JOIN FETCH sb.items WHERE LOWER(sb.name) LIKE LOWER(:name)";
String jpql = "SELECT sb FROM SubscriptionBox sb LEFT JOIN FETCH sb.items WHERE sb.name = :name";
TypedQuery<SubscriptionBox> query = entityManager.createQuery(jpql, SubscriptionBox.class);
query.setParameter("name", "%" + name.toLowerCase() + "%"); // Convert input name to lowercase
query.setParameter("name", name ); // Convert input name to lowercase
List<SubscriptionBox> result = query.getResultList();
return Optional.ofNullable(result.isEmpty() ? null : result);
}
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
package id.ac.ui.cs.advprog.snackscription_subscriptionbox.service;
import java.util.List;

import id.ac.ui.cs.advprog.snackscription_subscriptionbox.dto.ItemDTO;
import id.ac.ui.cs.advprog.snackscription_subscriptionbox.dto.SubscriptionBoxDTO;
import id.ac.ui.cs.advprog.snackscription_subscriptionbox.model.LogAdmin;
import id.ac.ui.cs.advprog.snackscription_subscriptionbox.model.SubscriptionBox;


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

public interface ItemService {
public CompletableFuture<List<ItemDTO>> findAll();
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
package id.ac.ui.cs.advprog.snackscription_subscriptionbox.service;

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

import id.ac.ui.cs.advprog.snackscription_subscriptionbox.dto.ItemDTO;
import id.ac.ui.cs.advprog.snackscription_subscriptionbox.dto.SubscriptionBoxDTO;
import id.ac.ui.cs.advprog.snackscription_subscriptionbox.dto.DTOMapper;
import id.ac.ui.cs.advprog.snackscription_subscriptionbox.model.Item;
import id.ac.ui.cs.advprog.snackscription_subscriptionbox.repository.ItemRepository;
import id.ac.ui.cs.advprog.snackscription_subscriptionbox.repository.LogRepository;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.scheduling.annotation.Async;
import org.springframework.stereotype.Service;
import id.ac.ui.cs.advprog.snackscription_subscriptionbox.model.LogAdmin;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import id.ac.ui.cs.advprog.snackscription_subscriptionbox.model.SubscriptionBox;
import id.ac.ui.cs.advprog.snackscription_subscriptionbox.repository.SubscriptionBoxRepository;

@Service
public class ItemServiceImpl implements ItemService{
@Autowired
private ItemRepository itemRepository;

@Override
@Async
public CompletableFuture<List<ItemDTO>> findAll() {
List<Item> items = itemRepository.findAll();
List<ItemDTO> dtos = items.stream()
.map(DTOMapper::convertItemToDto)
.collect(Collectors.toList());
return CompletableFuture.completedFuture(dtos);
}

}
5 changes: 4 additions & 1 deletion src/main/resources/application-prod.properties
Original file line number Diff line number Diff line change
Expand Up @@ -6,9 +6,12 @@ spring.jpa.properties.hibernate.dialect=org.hibernate.dialect.PostgreSQLDialect
spring.jpa.properties.hibernate.format_sql=true
JWT_SECRET=${JWT_SECRET}


# Actuator endpoints
management.endpoints.web.exposure.include=*
management.endpoint.prometheus.enabled=true
spring.datasource.hikari.maximum-pool-size=20

# Prometheus configuration
management.prometheus.metrics.export.enabled=true
management.prometheus.metrics.export.enabled=true

Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
package id.ac.ui.cs.advprog.snackscription_subscriptionbox.repository;

import id.ac.ui.cs.advprog.snackscription_subscriptionbox.model.Item;

import id.ac.ui.cs.advprog.snackscription_subscriptionbox.model.SubscriptionBox;
import jakarta.persistence.EntityManager;
import jakarta.persistence.TypedQuery;
Expand Down Expand Up @@ -177,7 +177,7 @@ void testFindByPriceGreaterThan() {
List<SubscriptionBox> result = subscriptionBoxRepository.findByPriceGreaterThan(150);

assertEquals(1, result.size());
assertEquals(subscriptionBox2, result.get(0));
assertEquals(subscriptionBox2, result.getFirst());
verify(entityManager, times(1)).createQuery("SELECT sb FROM SubscriptionBox sb LEFT JOIN FETCH sb.items WHERE sb.price > :price", SubscriptionBox.class);
verify(query, times(1)).setParameter("price", 150);
verify(query, times(1)).getResultList();
Expand All @@ -204,19 +204,19 @@ void testFindByPriceEquals() {
@Test
void testFindByName() {
SubscriptionBox subscriptionBox1 = new SubscriptionBox("Basic Box", "Monthly", 100, null, "Basic monthly subscription box");
SubscriptionBox subscriptionBox2 = new SubscriptionBox("Premium Box", "Monthly", 200, null, "Premium monthly subscription box");
SubscriptionBox subscriptionBox2 = new SubscriptionBox("Basic Box", "Quarterly", 200, null, "Premium monthly subscription box");

TypedQuery<SubscriptionBox> query = mock(TypedQuery.class);
when(entityManager.createQuery("SELECT sb FROM SubscriptionBox sb LEFT JOIN FETCH sb.items WHERE LOWER(sb.name) LIKE LOWER(:name)", SubscriptionBox.class)).thenReturn(query);
when(query.setParameter("name", "%box%")).thenReturn(query);
when(entityManager.createQuery("SELECT sb FROM SubscriptionBox sb LEFT JOIN FETCH sb.items WHERE sb.name = :name", SubscriptionBox.class)).thenReturn(query);
when(query.setParameter("name", "Basic Box")).thenReturn(query);
when(query.getResultList()).thenReturn(Arrays.asList(subscriptionBox1, subscriptionBox2));

Optional<List<SubscriptionBox>> result = subscriptionBoxRepository.findByName("box");
Optional<List<SubscriptionBox>> result = subscriptionBoxRepository.findByName("Basic Box");

assertTrue(result.isPresent());
assertEquals(2, result.get().size());
verify(entityManager, times(1)).createQuery("SELECT sb FROM SubscriptionBox sb LEFT JOIN FETCH sb.items WHERE LOWER(sb.name) LIKE LOWER(:name)", SubscriptionBox.class);
verify(query, times(1)).setParameter("name", "%box%");
verify(entityManager, times(1)).createQuery("SELECT sb FROM SubscriptionBox sb LEFT JOIN FETCH sb.items WHERE sb.name = :name", SubscriptionBox.class);
verify(query, times(1)).setParameter("name", "Basic Box");
verify(query, times(1)).getResultList();
}

Expand Down