Skip to content
Snippets Groups Projects
Commit 6ebdb3d5 authored by Daniel Gerhardt's avatar Daniel Gerhardt
Browse files

Add caching for CRUD operations of DefaultEntityServiceImpl

See #2.
parent 7407aa8d
Branches
1 merge request!113Add caching for CRUD operations of DefaultEntityServiceImpl
Pipeline #22086 passed with warnings with stages
in 1 minute and 42 seconds
......@@ -24,6 +24,7 @@ import de.thm.arsnova.event.AfterCreationEvent;
import de.thm.arsnova.event.AfterDeletionEvent;
import de.thm.arsnova.event.AfterFullUpdateEvent;
import de.thm.arsnova.event.AfterPatchEvent;
import de.thm.arsnova.event.AfterUpdateEvent;
import de.thm.arsnova.event.BeforeCreationEvent;
import de.thm.arsnova.event.BeforeDeletionEvent;
import de.thm.arsnova.event.BeforeFullUpdateEvent;
......@@ -31,10 +32,16 @@ import de.thm.arsnova.event.BeforePatchEvent;
import de.thm.arsnova.model.Entity;
import de.thm.arsnova.model.serialization.View;
import de.thm.arsnova.persistence.CrudRepository;
import org.springframework.cache.annotation.CacheEvict;
import org.springframework.cache.annotation.CachePut;
import org.springframework.cache.annotation.Cacheable;
import org.springframework.context.ApplicationEventPublisher;
import org.springframework.context.ApplicationEventPublisherAware;
import org.springframework.context.event.EventListener;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.security.access.prepost.PreFilter;
import org.springframework.stereotype.Component;
import java.io.IOException;
import java.util.Date;
......@@ -63,17 +70,16 @@ public class DefaultEntityServiceImpl<T extends Entity> implements EntityService
@Override
@PreAuthorize("hasPermission(#id, #this.this.getTypeName(), 'read')")
public T get(final String id) {
return repository.findOne(id);
return get(id, false);
}
@Override
@Cacheable(cacheNames = "entity", key = "#root.target.getTypeName() + '-' + #id", condition = "#internal == false")
public T get(final String id, final boolean internal) {
T entity;
entity = repository.findOne(id);
if (internal) {
entity = repository.findOne(id);
entity.setInternal(true);
} else {
entity = get(id);
}
modifyRetrieved(entity);
......@@ -260,4 +266,25 @@ public class DefaultEntityServiceImpl<T extends Entity> implements EntityService
public void setApplicationEventPublisher(final ApplicationEventPublisher applicationEventPublisher) {
this.eventPublisher = applicationEventPublisher;
}
@Component
public static class EntityCacheHandler {
@CachePut(cacheNames = "entity", key = "#event.entity.class.simpleName.toLowerCase() + '-' + #event.entity.id")
@EventListener
public Entity handleCreate(AfterCreationEvent event) {
return event.getEntity();
}
@CachePut(cacheNames = "entity", key = "#event.entity.class.simpleName.toLowerCase() + '-' + #event.entity.id")
@EventListener
public Entity handleUpdate(AfterUpdateEvent event) {
return event.getEntity();
}
@CacheEvict(cacheNames = "entity", key = "#event.entity.class.simpleName.toLowerCase() + '-' + #event.entity.id")
@EventListener
public void handleDelete(AfterDeletionEvent event) {
}
}
}
......@@ -12,6 +12,7 @@ import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.cache.CacheManager;
import org.springframework.context.ApplicationEventPublisher;
import org.springframework.http.converter.json.MappingJackson2HttpMessageConverter;
import org.springframework.test.context.ActiveProfiles;
......@@ -24,8 +25,9 @@ import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Optional;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.*;
import static org.mockito.AdditionalAnswers.returnsFirstArg;
import static org.mockito.Matchers.anyListOf;
import static org.mockito.Mockito.any;
......@@ -44,6 +46,9 @@ public class DefaultEntityServiceImplTest {
@Autowired
private ApplicationEventPublisher eventPublisher;
@Autowired
private CacheManager cacheManager;
@Autowired
private RoomRepository roomRepository;
......@@ -130,4 +135,40 @@ public class DefaultEntityServiceImplTest {
assertEquals(patchedClosed, room2.isClosed());
assertEquals(originalOwnerId2, room2.getOwnerId());
}
@Test
@WithMockUser("TestUser")
public void testCaching() {
final ObjectMapper objectMapper = jackson2HttpMessageConverter.getObjectMapper();
final DefaultEntityServiceImpl<Room> entityService = new DefaultEntityServiceImpl<>(Room.class, roomRepository, objectMapper);
entityService.setApplicationEventPublisher(eventPublisher);
final Room room1 = new Room();
room1.setId("a34876427c634a9b9cb56789d73607f0");
room1.setOwnerId("TestUser");
final Room room2 = new Room();
room2.setId("4638748d89884ff7936d7fe994a4090c");
room2.setOwnerId("TestUser");
final Room room3 = new Room();
room3.setId("c9651db0a67b49789a354e90e0401032");
room3.setOwnerId("TestUser");
final Room room4 = new Room();
room4.setId("66c1673056b2410b87335b9f317da5aa");
room4.setOwnerId("TestUser");
when(roomRepository.findById(any(String.class))).thenReturn(Optional.of(room1));
when(roomRepository.findOne(any(String.class))).thenReturn(room1);
assertSame(room1, entityService.get(room1.getId()));
/* room1 should now be cached for room1.id */
assertSame(room1, cacheManager.getCache("entity").get("room-" + room1.getId()).get());
when(roomRepository.findById(any(String.class))).thenReturn(Optional.of(room2));
when(roomRepository.findOne(any(String.class))).thenReturn(room2);
assertSame(room1, entityService.get(room1.getId()));
assertSame("Cache should not be used if internal == true.", room2, entityService.get(room1.getId(), true));
entityService.delete(room1);
/* room1 should no longer be cached for room1.id */
assertSame("Entity should not be cached.", null, cacheManager.getCache("entity").get("room-" + room1.getId()));
assertSame(room2, entityService.get(room1.getId()));
}
}
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment