Add MongoDB integration
This commit is contained in:
parent
3a3f488841
commit
b4c8aaa4e8
@ -1,20 +1,71 @@
|
||||
package com.aselimov.NS.controller;
|
||||
|
||||
import com.aselimov.NS.model.Notification;
|
||||
import java.util.List;
|
||||
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.http.HttpStatus;
|
||||
import org.springframework.http.ResponseEntity;
|
||||
import org.springframework.web.bind.annotation.*;
|
||||
import org.springframework.web.bind.annotation.DeleteMapping;
|
||||
import org.springframework.web.bind.annotation.GetMapping;
|
||||
import org.springframework.web.bind.annotation.PathVariable;
|
||||
import org.springframework.web.bind.annotation.PostMapping;
|
||||
import org.springframework.web.bind.annotation.PutMapping;
|
||||
import org.springframework.web.bind.annotation.RequestBody;
|
||||
import org.springframework.web.bind.annotation.RequestMapping;
|
||||
import org.springframework.web.bind.annotation.RequestParam;
|
||||
import org.springframework.web.bind.annotation.RestController;
|
||||
|
||||
import com.aselimov.NS.model.Notification;
|
||||
import com.aselimov.NS.service.NotificationService;
|
||||
|
||||
@RestController
|
||||
@RequestMapping("/api/notifications")
|
||||
public class NotificationController {
|
||||
|
||||
private final NotificationService notificationService;
|
||||
|
||||
@Autowired
|
||||
public NotificationController(final NotificationService notificationService) {
|
||||
this.notificationService = notificationService;
|
||||
}
|
||||
|
||||
@PostMapping
|
||||
public ResponseEntity<String> createNotification(@RequestBody Notification notification) {
|
||||
return ResponseEntity.ok("Notification received: " + notification.getSubject());
|
||||
public ResponseEntity<Notification> createNotification(@RequestBody final Notification notification) {
|
||||
final Notification savedNotification = notificationService.saveNotification(notification);
|
||||
return new ResponseEntity<Notification>(savedNotification, HttpStatus.CREATED);
|
||||
}
|
||||
|
||||
@GetMapping("/health")
|
||||
public ResponseEntity<String> healthCheck() {
|
||||
return ResponseEntity.ok("Notification service running...");
|
||||
}
|
||||
|
||||
@GetMapping
|
||||
public ResponseEntity<List<Notification>> getAllNotifications() {
|
||||
return ResponseEntity.ok(notificationService.getAllNotifications());
|
||||
}
|
||||
|
||||
@GetMapping("/{id}")
|
||||
public ResponseEntity<Notification> getNotificationById(@PathVariable final String id) {
|
||||
return ResponseEntity.ok(notificationService.getNotificationByIdOrThrow(id));
|
||||
}
|
||||
|
||||
@GetMapping("/status/{status}")
|
||||
public ResponseEntity<List<Notification>> getNotificationsByStatus(
|
||||
@PathVariable final Notification.NotificationStatus status) {
|
||||
return ResponseEntity.ok(notificationService.getNotificationsByStatus(status));
|
||||
}
|
||||
|
||||
@PutMapping("/{id}/status")
|
||||
public ResponseEntity<Void> updateNotificationStatus(@PathVariable final String id,
|
||||
@RequestParam final Notification.NotificationStatus status) {
|
||||
notificationService.updateNotificationStatus(id, status);
|
||||
return ResponseEntity.ok().build();
|
||||
}
|
||||
|
||||
@DeleteMapping("/{id}")
|
||||
public ResponseEntity<Void> deleteNotification(@PathVariable String id) {
|
||||
notificationService.deleteNotification(id);
|
||||
return ResponseEntity.noContent().build();
|
||||
}
|
||||
}
|
||||
|
@ -0,0 +1,32 @@
|
||||
package com.aselimov.NS.exception;
|
||||
|
||||
import java.time.LocalDateTime;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
import org.springframework.http.HttpStatus;
|
||||
import org.springframework.http.ResponseEntity;
|
||||
import org.springframework.web.bind.annotation.ControllerAdvice;
|
||||
import org.springframework.web.bind.annotation.ExceptionHandler;
|
||||
|
||||
@ControllerAdvice
|
||||
public class GlobalExceptionHandler {
|
||||
@ExceptionHandler(NotificationNotFoundException.class)
|
||||
public ResponseEntity<Object> handleNotificationNotFoundException(NotificationNotFoundException ex) {
|
||||
Map<String, Object> body = new HashMap<>();
|
||||
body.put("timestamp", LocalDateTime.now());
|
||||
body.put("message", ex.getMessage());
|
||||
|
||||
return new ResponseEntity<>(body, HttpStatus.NOT_FOUND);
|
||||
}
|
||||
|
||||
@ExceptionHandler(Exception.class)
|
||||
public ResponseEntity<Object> handleGlobalException(Exception ex) {
|
||||
Map<String, Object> body = new HashMap<>();
|
||||
body.put("timestamp", LocalDateTime.now());
|
||||
body.put("message", "An unexpected error occured");
|
||||
body.put("error", ex.getMessage());
|
||||
|
||||
return new ResponseEntity<>(body, HttpStatus.INTERNAL_SERVER_ERROR);
|
||||
}
|
||||
}
|
@ -0,0 +1,7 @@
|
||||
package com.aselimov.NS.exception;
|
||||
|
||||
public class NotificationNotFoundException extends RuntimeException {
|
||||
public NotificationNotFoundException(String id) {
|
||||
super("Notification not found with id:" + id);
|
||||
}
|
||||
}
|
@ -0,0 +1,19 @@
|
||||
package com.aselimov.NS.repository;
|
||||
|
||||
import com.aselimov.NS.model.Notification;
|
||||
import org.springframework.data.mongodb.repository.MongoRepository;
|
||||
import org.springframework.stereotype.Repository;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
@Repository
|
||||
public interface NotificationRepository extends MongoRepository<Notification, String> {
|
||||
// Find notifications by status
|
||||
List<Notification> findByStatus(Notification.NotificationStatus status);
|
||||
|
||||
// Find notifications by type
|
||||
List<Notification> findByType(Notification.NotificationType type);
|
||||
|
||||
// Find notifications by recipient
|
||||
List<Notification> findByRecipient(String recipient);
|
||||
}
|
@ -0,0 +1,68 @@
|
||||
package com.aselimov.NS.service;
|
||||
|
||||
import java.time.LocalDateTime;
|
||||
import java.util.List;
|
||||
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
import com.aselimov.NS.exception.NotificationNotFoundException;
|
||||
import com.aselimov.NS.model.Notification;
|
||||
import com.aselimov.NS.repository.NotificationRepository;
|
||||
|
||||
@Service
|
||||
public class NotificationService {
|
||||
private final NotificationRepository notificationRepository;
|
||||
|
||||
@Autowired
|
||||
public NotificationService(NotificationRepository notificationRepository) {
|
||||
this.notificationRepository = notificationRepository;
|
||||
}
|
||||
|
||||
public Notification saveNotification(Notification notification) {
|
||||
// Set timestamps if not present
|
||||
if (notification.getCreatedAt() == null) {
|
||||
notification.setCreatedAt(LocalDateTime.now());
|
||||
}
|
||||
notification.setUpdatedAt(LocalDateTime.now());
|
||||
|
||||
// Ensure status is set
|
||||
if (notification.getStatus() == null) {
|
||||
notification.setStatus(Notification.NotificationStatus.PENDING);
|
||||
}
|
||||
|
||||
return notificationRepository.save(notification);
|
||||
}
|
||||
|
||||
public List<Notification> getAllNotifications() {
|
||||
return notificationRepository.findAll();
|
||||
}
|
||||
|
||||
public Notification getNotificationByIdOrThrow(String id) {
|
||||
return notificationRepository.findById(id).orElseThrow(() -> new NotificationNotFoundException(id));
|
||||
}
|
||||
|
||||
public List<Notification> getNotificationsByStatus(Notification.NotificationStatus status) {
|
||||
return notificationRepository.findByStatus(status);
|
||||
}
|
||||
|
||||
public List<Notification> getNotificationsByType(Notification.NotificationType type) {
|
||||
return notificationRepository.findByType(type);
|
||||
}
|
||||
|
||||
public List<Notification> getNotificationsByRecipient(String recipient) {
|
||||
return notificationRepository.findByRecipient(recipient);
|
||||
}
|
||||
|
||||
public void updateNotificationStatus(String id, Notification.NotificationStatus status) {
|
||||
notificationRepository.findById(id).ifPresent(notification -> {
|
||||
notification.setStatus(status);
|
||||
notification.setUpdatedAt(LocalDateTime.now());
|
||||
notificationRepository.save(notification);
|
||||
});
|
||||
}
|
||||
|
||||
public void deleteNotification(String id) {
|
||||
notificationRepository.deleteById(id);
|
||||
}
|
||||
}
|
@ -1,6 +1,10 @@
|
||||
spring.application.name=NS
|
||||
|
||||
server.port=8080
|
||||
spring.data.mongodb.uri=mongodb://localhost:27017/notification-system
|
||||
|
||||
spring.data.mongodb.host=localhost
|
||||
spring.data.mongodb.port=27017
|
||||
spring.data.mongodb.database=notification-system
|
||||
|
||||
spring.kafka.bootstrap-servers=localhost:9092
|
||||
spring.kafka.consumer.group-id=notification-group
|
||||
|
@ -0,0 +1,101 @@
|
||||
package com.aselimov.NS.repository;
|
||||
|
||||
import static org.junit.jupiter.api.Assertions.assertEquals;
|
||||
|
||||
import java.time.LocalDateTime;
|
||||
import java.util.List;
|
||||
|
||||
import org.junit.jupiter.api.BeforeEach;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.boot.test.autoconfigure.data.mongo.DataMongoTest;
|
||||
import org.springframework.test.context.ActiveProfiles;
|
||||
|
||||
import com.aselimov.NS.model.Notification;
|
||||
import com.aselimov.NS.model.Notification.NotificationType;
|
||||
|
||||
@DataMongoTest
|
||||
@ActiveProfiles("test")
|
||||
public class NotificationRepositoryTest {
|
||||
|
||||
@BeforeEach
|
||||
public void setup() {
|
||||
notificationRepository.deleteAll();
|
||||
}
|
||||
|
||||
public NotificationRepository getNotificationRepository() {
|
||||
return notificationRepository;
|
||||
}
|
||||
|
||||
@Autowired
|
||||
private NotificationRepository notificationRepository;
|
||||
|
||||
@Test
|
||||
public void shouldSaveNotification() {
|
||||
// Given
|
||||
final Notification notification = new Notification();
|
||||
notification.setType(Notification.NotificationType.EMAIL);
|
||||
notification.setRecipient("test@example.com");
|
||||
notification.setSubject("Test Subject");
|
||||
notification.setContent("Test Content");
|
||||
notification.setStatus(Notification.NotificationStatus.PENDING);
|
||||
notification.setCreatedAt(LocalDateTime.now());
|
||||
notification.setUpdatedAt(LocalDateTime.now());
|
||||
|
||||
// When
|
||||
Notification savedNotification = notificationRepository.save(notification);
|
||||
|
||||
// Then
|
||||
assert (savedNotification.getId() != null) : "Notification shouldn't be null";
|
||||
assertEquals(Notification.NotificationType.EMAIL, savedNotification.getType());
|
||||
assertEquals("test@example.com", savedNotification.getRecipient());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void shouldFindByStatus() {
|
||||
// Given
|
||||
Notification notification1 = new Notification();
|
||||
notification1.setType(Notification.NotificationType.EMAIL);
|
||||
notification1.setRecipient("test1@example.com");
|
||||
notification1.setStatus(Notification.NotificationStatus.PENDING);
|
||||
notification1.setCreatedAt(LocalDateTime.now());
|
||||
notification1.setUpdatedAt(LocalDateTime.now());
|
||||
|
||||
Notification notification2 = new Notification();
|
||||
notification2.setType(Notification.NotificationType.SMS);
|
||||
notification2.setRecipient("test2@example.com");
|
||||
notification2.setStatus(Notification.NotificationStatus.SENT);
|
||||
notification2.setCreatedAt(LocalDateTime.now());
|
||||
notification2.setUpdatedAt(LocalDateTime.now());
|
||||
|
||||
notificationRepository.saveAll(List.of(notification1, notification2));
|
||||
|
||||
// When
|
||||
List<Notification> pendingNotifications = notificationRepository
|
||||
.findByStatus(Notification.NotificationStatus.PENDING);
|
||||
|
||||
// Then
|
||||
assertEquals(1, pendingNotifications.size());
|
||||
assertEquals("test1@example.com", pendingNotifications.get(0).getRecipient());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void shouldFindByType() {
|
||||
// Given
|
||||
Notification notification = new Notification();
|
||||
notification.setType(Notification.NotificationType.PUSH);
|
||||
notification.setRecipient("test@example.com");
|
||||
notification.setStatus(Notification.NotificationStatus.PENDING);
|
||||
notification.setCreatedAt(LocalDateTime.now());
|
||||
notification.setUpdatedAt(LocalDateTime.now());
|
||||
|
||||
notificationRepository.save(notification);
|
||||
|
||||
// When
|
||||
List<Notification> pushNotifications = notificationRepository.findByType(NotificationType.PUSH);
|
||||
|
||||
// Then
|
||||
assertEquals(1, pushNotifications.size());
|
||||
assertEquals(NotificationType.PUSH, pushNotifications.get(0).getType());
|
||||
}
|
||||
}
|
1
src/test/resources/application-test.properties
Normal file
1
src/test/resources/application-test.properties
Normal file
@ -0,0 +1 @@
|
||||
spring.data.mongodb.database=notification-system-test
|
Loading…
x
Reference in New Issue
Block a user