Skip to content

Commit

Permalink
Implement transactional method for InboxProductCreationService with r…
Browse files Browse the repository at this point in the history
…ollback support
  • Loading branch information
ZribiMaram committed Dec 14, 2024
1 parent 41b176d commit 950e216
Show file tree
Hide file tree
Showing 5 changed files with 91 additions and 18 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -16,15 +16,13 @@
import org.springframework.kafka.core.DefaultKafkaProducerFactory;
import org.springframework.kafka.core.KafkaTemplate;
import org.springframework.kafka.core.ProducerFactory;
import org.springframework.kafka.listener.CommonErrorHandler;
import org.springframework.kafka.listener.DefaultErrorHandler;

import org.springframework.kafka.support.serializer.ErrorHandlingDeserializer;
import org.springframework.kafka.support.serializer.JsonDeserializer;
import org.springframework.retry.annotation.EnableRetry;
import org.springframework.scheduling.annotation.EnableScheduling;

import enit.ecomerce.search_product.consumer.ProductListed;
import enit.ecomerce.search_product.emitter.EventsEmitter;

import org.apache.kafka.common.errors.SerializationException;
import org.slf4j.Logger;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,35 +8,30 @@
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import java.util.List;

@Service
public class InboxProductCreationService {
@Autowired
private ProducteEntityRepository productEntityRepository;
@Autowired
private ProductRepository productRepository;
@Scheduled(fixedRate = 300000)
private ProducteEntityRepository productEntityRepository;
@Autowired
private ProductRepository productRepository;

@Scheduled(fixedRate = 300000)
@Transactional
public void treatInbox() {

List<ProductEntity> unindexedProducts = productEntityRepository.findUnindexedProducts();

for (ProductEntity product : unindexedProducts) {
try {
//we should see how to make these operation a transaction ,
//i dont want to save a product annd not set it in the inbox
productRepository.save(new Product(product));


product.setIndex(true);
productEntityRepository.save(product);

} catch (Exception e) {
System.err.println("Error processing product: " + product.getId() + " - " + e.getMessage());
throw e; // Rethrow the exception to trigger transaction rollback
}
}
}
}


}
5 changes: 4 additions & 1 deletion search/src/main/resources/application.properties
Original file line number Diff line number Diff line change
Expand Up @@ -21,4 +21,7 @@ spring.jpa.properties.hibernate.dialect=org.hibernate.dialect.PostgreSQLDialect

# Other Hibernate properties (optional but recommended)
spring.jpa.hibernate.ddl-auto=update
spring.jpa.show-sql=true
spring.jpa.show-sql=true
logging.level.root: info
logging.level.enit.ecomerce.search_product: debug

Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@
import enit.ecomerce.search_product.product.Product;
import enit.ecomerce.search_product.product.ProductEntity;
import enit.ecomerce.search_product.repository.ProductRepository;
import enit.ecomerce.search_product.repository.ProducteEntityRepository;
import enit.ecomerce.search_product.service.InboxProductCreationService;
import jakarta.transaction.Transactional;

import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.ExtendWith;
import org.mockito.InjectMocks;
import org.mockito.Mock;
import org.mockito.MockitoAnnotations;
import org.mockito.junit.jupiter.MockitoExtension;
import org.mockito.Mockito;
import static org.mockito.Mockito.*;

import org.springframework.boot.test.context.SpringBootTest;

import java.util.Arrays;
import java.util.List;

@ExtendWith(MockitoExtension.class)
@Transactional
class InboxProductCreationServiceTest {

@InjectMocks
private InboxProductCreationService inboxProductCreationService;

@Mock
private ProducteEntityRepository productEntityRepository;

@Mock
private ProductRepository productRepository;

@Test
@Transactional
void testTransactional_RollbackOnError() {
// Arrange
ProductEntity validProduct = new ProductEntity();
validProduct.setId("1");
validProduct.setName("Valid Product");
validProduct.setPrice(100.0f);
validProduct.setIndex(false);

ProductEntity invalidProduct = new ProductEntity();
invalidProduct.setId("2");
invalidProduct.setName("Invalid Product");
invalidProduct.setPrice(null); // This will cause an exception

when(productEntityRepository.findUnindexedProducts()).thenReturn(List.of(validProduct, invalidProduct));

doThrow(new IllegalArgumentException("Invalid product price"))
.when(productRepository).save(any(Product.class));

// Act
try {
inboxProductCreationService.treatInbox();
} catch (Exception e) {
// Exception expected
}

// Assert
// Verify that the valid product was not saved because of rollback
verify(productEntityRepository, never()).save(validProduct);
verify(productRepository, times(1)).save(any(Product.class)); // Attempt to save was made
}
}
10 changes: 10 additions & 0 deletions search/src/test/ressources/logback-test.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
<configuration>
<root level="info">
<appender-ref ref="CONSOLE" />
</root>
<appender name="CONSOLE" class="ch.qos.logback.core.ConsoleAppender">
<encoder>
<pattern>%d{yyyy-MM-dd HH:mm:ss} [%thread] %-5level %logger{36} - %msg%n</pattern>
</encoder>
</appender>
</configuration>

0 comments on commit 950e216

Please sign in to comment.