SEBSERV-163 back-end and fixed tests
This commit is contained in:
		
							parent
							
								
									cea166f065
								
							
						
					
					
						commit
						65b81af1eb
					
				
					 5 changed files with 97 additions and 7 deletions
				
			
		|  | @ -9,8 +9,10 @@ | |||
| package ch.ethz.seb.sebserver.gbl.model.session; | ||||
| 
 | ||||
| import java.util.Collection; | ||||
| import java.util.HashSet; | ||||
| import java.util.Iterator; | ||||
| import java.util.List; | ||||
| import java.util.Set; | ||||
| 
 | ||||
| import com.fasterxml.jackson.annotation.JsonCreator; | ||||
| import com.fasterxml.jackson.annotation.JsonIgnore; | ||||
|  | @ -20,6 +22,7 @@ import com.fasterxml.jackson.annotation.JsonProperty; | |||
| import ch.ethz.seb.sebserver.gbl.Constants; | ||||
| import ch.ethz.seb.sebserver.gbl.api.EntityType; | ||||
| import ch.ethz.seb.sebserver.gbl.model.GrantEntity; | ||||
| import ch.ethz.seb.sebserver.gbl.model.exam.ClientGroup; | ||||
| import ch.ethz.seb.sebserver.gbl.model.exam.Indicator; | ||||
| import ch.ethz.seb.sebserver.gbl.monitoring.IndicatorValue; | ||||
| import ch.ethz.seb.sebserver.gbl.monitoring.SimpleIndicatorValue; | ||||
|  | @ -41,6 +44,8 @@ public class ClientConnectionData implements GrantEntity { | |||
|     public final Boolean missingPing; | ||||
|     public final Boolean pendingNotification; | ||||
| 
 | ||||
|     private Set<Long> groups = null; | ||||
| 
 | ||||
|     @JsonCreator | ||||
|     public ClientConnectionData( | ||||
|             @JsonProperty(ATTR_MISSING_PING) final Boolean missingPing, | ||||
|  | @ -64,6 +69,19 @@ public class ClientConnectionData implements GrantEntity { | |||
|         this.indicatorValues = Utils.immutableListOf(indicatorValues); | ||||
|     } | ||||
| 
 | ||||
|     @JsonIgnore | ||||
|     public void addToClientGroup(final ClientGroup group) { | ||||
|         if (this.groups == null) { | ||||
|             this.groups = new HashSet<>(1); | ||||
|         } | ||||
|         this.groups.add(group.id); | ||||
|     } | ||||
| 
 | ||||
|     @JsonIgnore | ||||
|     public boolean isInClientGroup(final Long clientGroupId) { | ||||
|         return this.groups != null && this.groups.contains(clientGroupId); | ||||
|     } | ||||
| 
 | ||||
|     @Override | ||||
|     public EntityType entityType() { | ||||
|         return this.clientConnection.entityType(); | ||||
|  |  | |||
|  | @ -10,6 +10,9 @@ package ch.ethz.seb.sebserver.webservice.servicelayer.dao; | |||
| 
 | ||||
| import java.util.Collection; | ||||
| 
 | ||||
| import org.springframework.cache.annotation.CacheEvict; | ||||
| import org.springframework.cache.annotation.Cacheable; | ||||
| 
 | ||||
| import ch.ethz.seb.sebserver.gbl.model.exam.ClientGroup; | ||||
| import ch.ethz.seb.sebserver.gbl.util.Result; | ||||
| import ch.ethz.seb.sebserver.webservice.servicelayer.bulkaction.BulkActionSupportDAO; | ||||
|  | @ -17,10 +20,24 @@ import ch.ethz.seb.sebserver.webservice.servicelayer.bulkaction.BulkActionSuppor | |||
| /** Concrete EntityDAO interface of ClientGroup entities */ | ||||
| public interface ClientGroupDAO extends EntityDAO<ClientGroup, ClientGroup>, BulkActionSupportDAO<ClientGroup> { | ||||
| 
 | ||||
|     public static final String CACHE_NAME_RUNNING_EXAM_CLIENT_GROUP_CACHE = "RUNNING_EXAM_CLIENT_GROUP_CACHE"; | ||||
| 
 | ||||
|     /** Get a collection of all ClientGroup entities for a specified exam. | ||||
|      * | ||||
|      * @param examId the Exam identifier to get the ClientGroups for | ||||
|      * @return Result referring to the collection of ClientGroups of an Exam or to an error if happened */ | ||||
|     @Cacheable( | ||||
|             cacheNames = CACHE_NAME_RUNNING_EXAM_CLIENT_GROUP_CACHE, | ||||
|             key = "#examId", | ||||
|             condition = "#examId!=null", | ||||
|             unless = "#result.hasError()") | ||||
|     Result<Collection<ClientGroup>> allForExam(Long examId); | ||||
| 
 | ||||
|     @CacheEvict( | ||||
|             cacheNames = CACHE_NAME_RUNNING_EXAM_CLIENT_GROUP_CACHE, | ||||
|             key = "#examId") | ||||
|     default void evictCacheForExam(final Long examId) { | ||||
|         // just evict the cache | ||||
|     } | ||||
| 
 | ||||
| } | ||||
|  |  | |||
|  | @ -23,6 +23,7 @@ import ch.ethz.seb.sebserver.gbl.model.session.ClientConnection; | |||
| import ch.ethz.seb.sebserver.gbl.profile.WebServiceProfile; | ||||
| import ch.ethz.seb.sebserver.gbl.util.Result; | ||||
| import ch.ethz.seb.sebserver.webservice.servicelayer.dao.ClientConnectionDAO; | ||||
| import ch.ethz.seb.sebserver.webservice.servicelayer.dao.ClientGroupDAO; | ||||
| import ch.ethz.seb.sebserver.webservice.servicelayer.dao.ExamDAO; | ||||
| import ch.ethz.seb.sebserver.webservice.servicelayer.dao.RemoteProctoringRoomDAO; | ||||
| import ch.ethz.seb.sebserver.webservice.servicelayer.sebconfig.ExamConfigService; | ||||
|  | @ -45,6 +46,7 @@ public class ExamSessionCacheService { | |||
|     private static final Logger log = LoggerFactory.getLogger(ExamSessionCacheService.class); | ||||
| 
 | ||||
|     private final ExamDAO examDAO; | ||||
|     private final ClientGroupDAO clientGroupDAO; | ||||
|     private final ClientConnectionDAO clientConnectionDAO; | ||||
|     private final InternalClientConnectionDataFactory internalClientConnectionDataFactory; | ||||
|     private final ExamConfigService sebExamConfigService; | ||||
|  | @ -52,6 +54,7 @@ public class ExamSessionCacheService { | |||
| 
 | ||||
|     protected ExamSessionCacheService( | ||||
|             final ExamDAO examDAO, | ||||
|             final ClientGroupDAO clientGroupDAO, | ||||
|             final ClientConnectionDAO clientConnectionDAO, | ||||
|             final InternalClientConnectionDataFactory internalClientConnectionDataFactory, | ||||
|             final ExamConfigService sebExamConfigService, | ||||
|  | @ -59,6 +62,7 @@ public class ExamSessionCacheService { | |||
|             final RemoteProctoringRoomDAO remoteProctoringRoomDAO) { | ||||
| 
 | ||||
|         this.examDAO = examDAO; | ||||
|         this.clientGroupDAO = clientGroupDAO; | ||||
|         this.clientConnectionDAO = clientConnectionDAO; | ||||
|         this.internalClientConnectionDataFactory = internalClientConnectionDataFactory; | ||||
|         this.sebExamConfigService = sebExamConfigService; | ||||
|  | @ -98,6 +102,7 @@ public class ExamSessionCacheService { | |||
|             log.trace("Conditional eviction of running Exam from cache: {}", isRunning(exam)); | ||||
|         } | ||||
| 
 | ||||
|         this.clientGroupDAO.evictCacheForExam(exam.id); | ||||
|         return exam; | ||||
|     } | ||||
| 
 | ||||
|  | @ -110,6 +115,7 @@ public class ExamSessionCacheService { | |||
|             log.trace("Conditional eviction of running Exam from cache: {}", examId); | ||||
|         } | ||||
| 
 | ||||
|         this.clientGroupDAO.evictCacheForExam(examId); | ||||
|         return examId; | ||||
|     } | ||||
| 
 | ||||
|  |  | |||
|  | @ -8,12 +8,20 @@ | |||
| 
 | ||||
| package ch.ethz.seb.sebserver.webservice.servicelayer.session.impl; | ||||
| 
 | ||||
| import java.util.Collection; | ||||
| import java.util.Collections; | ||||
| 
 | ||||
| import org.slf4j.Logger; | ||||
| import org.slf4j.LoggerFactory; | ||||
| import org.springframework.context.annotation.Lazy; | ||||
| import org.springframework.stereotype.Service; | ||||
| 
 | ||||
| import ch.ethz.seb.sebserver.gbl.model.exam.ClientGroup; | ||||
| import ch.ethz.seb.sebserver.gbl.model.session.ClientConnection; | ||||
| import ch.ethz.seb.sebserver.gbl.model.session.ClientConnection.ConnectionStatus; | ||||
| import ch.ethz.seb.sebserver.gbl.monitoring.ClientGroupMatcherService; | ||||
| import ch.ethz.seb.sebserver.gbl.profile.WebServiceProfile; | ||||
| import ch.ethz.seb.sebserver.webservice.servicelayer.dao.ClientGroupDAO; | ||||
| import ch.ethz.seb.sebserver.webservice.servicelayer.session.SEBClientNotificationService; | ||||
| 
 | ||||
| @Lazy | ||||
|  | @ -21,34 +29,64 @@ import ch.ethz.seb.sebserver.webservice.servicelayer.session.SEBClientNotificati | |||
| @WebServiceProfile | ||||
| public class InternalClientConnectionDataFactory { | ||||
| 
 | ||||
|     private static final Logger log = LoggerFactory.getLogger(InternalClientConnectionDataFactory.class); | ||||
| 
 | ||||
|     private final ClientIndicatorFactory clientIndicatorFactory; | ||||
|     private final SEBClientNotificationService sebClientNotificationService; | ||||
|     private final ClientGroupDAO clientGroupDAO; | ||||
|     private final ClientGroupMatcherService clientGroupMatcherService; | ||||
| 
 | ||||
|     public InternalClientConnectionDataFactory( | ||||
|             final ClientIndicatorFactory clientIndicatorFactory, | ||||
|             final SEBClientNotificationService sebClientNotificationService) { | ||||
|             final SEBClientNotificationService sebClientNotificationService, | ||||
|             final ClientGroupDAO clientGroupDAO, | ||||
|             final ClientGroupMatcherService clientGroupMatcherService) { | ||||
| 
 | ||||
|         this.clientIndicatorFactory = clientIndicatorFactory; | ||||
|         this.sebClientNotificationService = sebClientNotificationService; | ||||
|         this.clientGroupDAO = clientGroupDAO; | ||||
|         this.clientGroupMatcherService = clientGroupMatcherService; | ||||
|     } | ||||
| 
 | ||||
|     public ClientConnectionDataInternal createClientConnectionData(final ClientConnection clientConnection) { | ||||
| 
 | ||||
|         ClientConnectionDataInternal result; | ||||
|         if (clientConnection.status == ConnectionStatus.CLOSED | ||||
|                 || clientConnection.status == ConnectionStatus.DISABLED) { | ||||
| 
 | ||||
|             // dispose notification indication for closed or disabled connection | ||||
|             return new ClientConnectionDataInternal( | ||||
|             result = new ClientConnectionDataInternal( | ||||
|                     clientConnection, | ||||
|                     () -> false, | ||||
|                     this.clientIndicatorFactory.createFor(clientConnection)); | ||||
|         } else { | ||||
| 
 | ||||
|             result = new ClientConnectionDataInternal( | ||||
|                     clientConnection, | ||||
|                     () -> this.sebClientNotificationService | ||||
|                             .hasAnyPendingNotification(clientConnection), | ||||
|                     this.clientIndicatorFactory.createFor(clientConnection)); | ||||
|         } | ||||
| 
 | ||||
|         return new ClientConnectionDataInternal( | ||||
|                 clientConnection, | ||||
|                 () -> this.sebClientNotificationService | ||||
|                         .hasAnyPendingNotification(clientConnection), | ||||
|                 this.clientIndicatorFactory.createFor(clientConnection)); | ||||
|         // set client groups for connection | ||||
|         if (clientConnection.examId != null) { | ||||
|             final Collection<ClientGroup> clientGroups = this.clientGroupDAO | ||||
|                     .allForExam(clientConnection.examId) | ||||
|                     .onError( | ||||
|                             error -> log.error("Failed to get client groups for clientConnection: {}", clientConnection, | ||||
|                                     error)) | ||||
|                     .getOr(Collections.emptyList()); | ||||
| 
 | ||||
|             if (!clientGroups.isEmpty()) { | ||||
|                 clientGroups.forEach(clientGroup -> { | ||||
|                     if (this.clientGroupMatcherService.isInGroup(clientConnection, clientGroup)) { | ||||
|                         result.addToClientGroup(clientGroup); | ||||
|                     } | ||||
|                 }); | ||||
|             } | ||||
|         } | ||||
| 
 | ||||
|         return result; | ||||
|     } | ||||
| 
 | ||||
| } | ||||
|  |  | |||
|  | @ -16,6 +16,17 @@ | |||
|         </resources> | ||||
|     </cache> | ||||
| 
 | ||||
|     <cache alias="RUNNING_EXAM_CLIENT_GROUP_CACHE"> | ||||
|         <key-type>java.lang.Long</key-type> | ||||
|         <value-type>ch.ethz.seb.sebserver.gbl.util.Result</value-type> | ||||
|         <expiry> | ||||
|             <ttl unit="hours">24</ttl> | ||||
|         </expiry> | ||||
|         <resources> | ||||
|             <heap unit="entries">10</heap> | ||||
|         </resources> | ||||
|     </cache> | ||||
|      | ||||
|     <cache alias="ACTIVE_CLIENT_CONNECTION"> | ||||
|         <key-type>java.lang.String</key-type> | ||||
|         <value-type>ch.ethz.seb.sebserver.webservice.servicelayer.session.impl.ClientConnectionDataInternal</value-type> | ||||
|  |  | |||
		Loading…
	
	Add table
		
		Reference in a new issue
	
	 anhefti
						anhefti