Merge remote-tracking branch 'origin/dev-1.2' into development
This commit is contained in:
commit
e3ac612fb3
5 changed files with 77 additions and 18 deletions
|
@ -36,6 +36,14 @@ public interface ClientEventDAO extends EntityDAO<ClientEvent, ClientEvent> {
|
|||
* @return Result refer to the specified ClientNotification or to an error when happened */
|
||||
Result<ClientNotification> getPendingNotification(Long notificationId);
|
||||
|
||||
/** Get a pending notification by the notification value identifier (sent by SEB)
|
||||
*
|
||||
* @param notificationValueId notification value identifier (sent by SEB)
|
||||
* @return Result refer to the specified ClientNotification or to an error when happened */
|
||||
Result<ClientNotification> getPendingNotificationByValue(
|
||||
Long clientConnectionId,
|
||||
Long notificationValueId);
|
||||
|
||||
/** Get all pending notifications for a given client connection.
|
||||
*
|
||||
* @param clientConnectionId The client connection identifier
|
||||
|
@ -51,9 +59,8 @@ public interface ClientEventDAO extends EntityDAO<ClientEvent, ClientEvent> {
|
|||
/** Used to confirm a pending notification so that the notification is not pending anymore
|
||||
*
|
||||
* @param notificationId the notification identifier
|
||||
* @param clientConnectionId the client connection identifier
|
||||
* @return Result refer to the confirmed notification or to en error when happened */
|
||||
Result<ClientNotification> confirmPendingNotification(Long notificationId, Long clientConnectionId);
|
||||
Result<ClientNotification> confirmPendingNotification(Long notificationId);
|
||||
|
||||
Result<ClientEventRecord> initPingEvent(Long connectionId);
|
||||
|
||||
|
|
|
@ -198,6 +198,43 @@ public class ClientEventDAOImpl implements ClientEventDAO {
|
|||
.flatMap(ClientEventDAOImpl::toClientNotificationModel);
|
||||
}
|
||||
|
||||
@Override
|
||||
@Transactional(readOnly = true)
|
||||
public Result<ClientNotification> getPendingNotificationByValue(
|
||||
final Long clientConnectionId,
|
||||
final Long notificationValueId) {
|
||||
|
||||
return Result.tryCatch(() -> {
|
||||
|
||||
final List<ClientEventRecord> records = this.clientEventRecordMapper
|
||||
.selectByExample()
|
||||
.where(ClientEventRecordDynamicSqlSupport.clientConnectionId, isEqualTo(clientConnectionId))
|
||||
.and(ClientEventRecordDynamicSqlSupport.type, isEqualTo(EventType.NOTIFICATION.id))
|
||||
.build()
|
||||
.execute();
|
||||
|
||||
if (log.isDebugEnabled()) {
|
||||
log.debug("Found notification for clientConnectionId: {} notification: {}",
|
||||
clientConnectionId,
|
||||
records);
|
||||
}
|
||||
|
||||
return records.stream()
|
||||
.filter(rec -> {
|
||||
final BigDecimal numericValue = rec.getNumericValue();
|
||||
if (numericValue == null) {
|
||||
return false;
|
||||
}
|
||||
return numericValue.longValue() == notificationValueId;
|
||||
})
|
||||
.findFirst()
|
||||
.orElseThrow(() -> new IllegalStateException(
|
||||
"Failed to find pending notification event for confirm:" + notificationValueId));
|
||||
|
||||
})
|
||||
.flatMap(ClientEventDAOImpl::toClientNotificationModel);
|
||||
}
|
||||
|
||||
@Override
|
||||
@Transactional(readOnly = true)
|
||||
public Result<List<ClientNotification>> getPendingNotifications(final Long clientConnectionId) {
|
||||
|
@ -240,8 +277,8 @@ public class ClientEventDAOImpl implements ClientEventDAO {
|
|||
|
||||
@Override
|
||||
@Transactional
|
||||
public Result<ClientNotification> confirmPendingNotification(final Long notificationId,
|
||||
final Long clientConnectionId) {
|
||||
public Result<ClientNotification> confirmPendingNotification(final Long notificationId) {
|
||||
|
||||
return Result.tryCatch(() -> {
|
||||
final Long pk = this.clientEventRecordMapper
|
||||
.selectIdsByExample()
|
||||
|
|
|
@ -10,10 +10,12 @@ package ch.ethz.seb.sebserver.webservice.servicelayer.dao.impl;
|
|||
|
||||
import java.util.Collection;
|
||||
import java.util.Collections;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
import org.joda.time.DateTime;
|
||||
import org.joda.time.DateTimeZone;
|
||||
import org.mybatis.dynamic.sql.SqlBuilder;
|
||||
|
@ -153,10 +155,12 @@ public class ClientInstructionDAOImpl implements ClientInstructionDAO {
|
|||
|
||||
if (needsConfirmation) {
|
||||
|
||||
final Map<String, String> attrs = this.jsonMapper.readValue(
|
||||
attributes,
|
||||
new TypeReference<Map<String, String>>() {
|
||||
});
|
||||
final Map<String, String> attrs = (StringUtils.isNotBlank(attributes))
|
||||
? this.jsonMapper.readValue(
|
||||
attributes,
|
||||
new TypeReference<Map<String, String>>() {
|
||||
})
|
||||
: new HashMap<>();
|
||||
attrs.put(API.EXAM_API_PING_INSTRUCTION_CONFIRM, String.valueOf(clientInstructionRecord.getId()));
|
||||
|
||||
this.clientInstructionRecordMapper.updateByPrimaryKeySelective(
|
||||
|
|
|
@ -115,12 +115,17 @@ public class SEBClientInstructionServiceImpl implements SEBClientInstructionServ
|
|||
|
||||
if (isActive) {
|
||||
try {
|
||||
final String attributesString = this.jsonMapper.writeValueAsString(attributes);
|
||||
|
||||
final String attributesString = (attributes != null && !attributes.isEmpty())
|
||||
? this.jsonMapper.writeValueAsString(attributes)
|
||||
: null;
|
||||
|
||||
this.clientInstructionDAO
|
||||
.insert(examId, type, attributesString, connectionToken, needsConfirm)
|
||||
.map(this::putToCache)
|
||||
.onError(error -> log.error("Failed to register instruction: {}", error.getMessage()))
|
||||
.getOrThrow();
|
||||
|
||||
} catch (final Exception e) {
|
||||
throw new RuntimeException("Unexpected: ", e);
|
||||
}
|
||||
|
|
|
@ -29,6 +29,7 @@ import ch.ethz.seb.sebserver.gbl.model.session.ClientInstruction.InstructionType
|
|||
import ch.ethz.seb.sebserver.gbl.model.session.ClientNotification;
|
||||
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.ClientEventDAO;
|
||||
import ch.ethz.seb.sebserver.webservice.servicelayer.session.SEBClientInstructionService;
|
||||
import ch.ethz.seb.sebserver.webservice.servicelayer.session.SEBClientNotificationService;
|
||||
|
@ -44,6 +45,7 @@ public class SEBClientNotificationServiceImpl implements SEBClientNotificationSe
|
|||
private static final String CONFIRM_INSTRUCTION_ATTR_TYPE = "type";
|
||||
|
||||
private final ClientEventDAO clientEventDAO;
|
||||
private final ClientConnectionDAO clientConnectionDAO;
|
||||
private final SEBClientInstructionService sebClientInstructionService;
|
||||
private final Set<Long> pendingNotifications = new HashSet<>();
|
||||
private final Set<Long> examUpdate = new HashSet<>();
|
||||
|
@ -52,9 +54,11 @@ public class SEBClientNotificationServiceImpl implements SEBClientNotificationSe
|
|||
|
||||
public SEBClientNotificationServiceImpl(
|
||||
final ClientEventDAO clientEventDAO,
|
||||
final ClientConnectionDAO clientConnectionDAO,
|
||||
final SEBClientInstructionService sebClientInstructionService) {
|
||||
|
||||
this.clientEventDAO = clientEventDAO;
|
||||
this.clientConnectionDAO = clientConnectionDAO;
|
||||
this.sebClientInstructionService = sebClientInstructionService;
|
||||
}
|
||||
|
||||
|
@ -75,13 +79,16 @@ public class SEBClientNotificationServiceImpl implements SEBClientNotificationSe
|
|||
@Override
|
||||
public void confirmPendingNotification(final ClientEvent event, final String connectionToken) {
|
||||
try {
|
||||
|
||||
final ClientConnection clientConnection = this.clientConnectionDAO
|
||||
.byConnectionToken(connectionToken)
|
||||
.getOrThrow();
|
||||
final Long notificationId = (long) event.getValue();
|
||||
|
||||
this.clientEventDAO.getPendingNotification(notificationId)
|
||||
.flatMap(notification -> this.clientEventDAO.confirmPendingNotification(
|
||||
notificationId,
|
||||
notification.connectionId))
|
||||
.map(this::removeFromCache);
|
||||
this.clientEventDAO.getPendingNotificationByValue(clientConnection.id, notificationId)
|
||||
.flatMap(notification -> this.clientEventDAO.confirmPendingNotification(notification.id))
|
||||
.map(this::removeFromCache)
|
||||
.onError(error -> log.error("Failed to confirm pending notification: {}", event, error));
|
||||
|
||||
} catch (final Exception e) {
|
||||
log.error(
|
||||
|
@ -98,10 +105,9 @@ public class SEBClientNotificationServiceImpl implements SEBClientNotificationSe
|
|||
|
||||
return this.clientEventDAO.getPendingNotification(notificationId)
|
||||
.map(notification -> this.confirmClientSide(notification, examId, connectionToken))
|
||||
.flatMap(notification -> this.clientEventDAO.confirmPendingNotification(
|
||||
notificationId,
|
||||
notification.connectionId))
|
||||
.map(this::removeFromCache);
|
||||
.flatMap(notification -> this.clientEventDAO.confirmPendingNotification(notificationId))
|
||||
.map(this::removeFromCache)
|
||||
.onError(error -> log.error("Failed to confirm pending notification: {}", notificationId, error));
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
Loading…
Reference in a new issue