Made Exam API asynchronous a, fix tests and fix monitoring activity
This commit is contained in:
parent
a360bfffc8
commit
43578d3e1c
5 changed files with 294 additions and 195 deletions
|
@ -335,10 +335,14 @@ public class ActivitiesPane implements TemplateComposer {
|
||||||
.create());
|
.create());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (monitoring.getItemCount() > 0) {
|
||||||
monitoring.setExpanded(
|
monitoring.setExpanded(
|
||||||
this.currentUser
|
this.currentUser
|
||||||
.get()
|
.get()
|
||||||
.hasAnyRole(UserRole.EXAM_SUPPORTER));
|
.hasAnyRole(UserRole.EXAM_SUPPORTER));
|
||||||
|
} else {
|
||||||
|
monitoring.dispose();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// ---- MONITORING ---------------------------------------------------------------------
|
// ---- MONITORING ---------------------------------------------------------------------
|
||||||
|
|
|
@ -11,6 +11,7 @@ package ch.ethz.seb.sebserver.webservice.weblayer.api;
|
||||||
import java.util.Arrays;
|
import java.util.Arrays;
|
||||||
import java.util.Collection;
|
import java.util.Collection;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
import java.util.concurrent.CompletionException;
|
||||||
import java.util.stream.Collectors;
|
import java.util.stream.Collectors;
|
||||||
|
|
||||||
import org.slf4j.Logger;
|
import org.slf4j.Logger;
|
||||||
|
@ -205,4 +206,24 @@ public class APIExceptionHandler extends ResponseEntityExceptionHandler {
|
||||||
HttpStatus.BAD_REQUEST);
|
HttpStatus.BAD_REQUEST);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ExceptionHandler(CompletionException.class)
|
||||||
|
public ResponseEntity<Object> handleCompletionException(
|
||||||
|
final CompletionException ex,
|
||||||
|
final WebRequest request) {
|
||||||
|
|
||||||
|
final Throwable cause = ex.getCause();
|
||||||
|
if (cause instanceof APIMessageException) {
|
||||||
|
return handleAPIMessageException((APIMessageException) cause, request);
|
||||||
|
} else if (cause instanceof APIConstraintViolationException) {
|
||||||
|
return handleIllegalAPIArgumentException((APIConstraintViolationException) cause, request);
|
||||||
|
} else if (cause instanceof ResourceNotFoundException) {
|
||||||
|
return APIMessage.ErrorMessage.RESOURCE_NOT_FOUND.createErrorResponse(cause.getMessage());
|
||||||
|
} else if (cause instanceof RuntimeException) {
|
||||||
|
return APIMessage.ErrorMessage.UNEXPECTED.createErrorResponse(cause.getMessage());
|
||||||
|
}
|
||||||
|
|
||||||
|
return APIMessage.ErrorMessage.GENERIC.createErrorResponse(cause.getMessage());
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -13,6 +13,7 @@ import java.security.Principal;
|
||||||
import java.util.Arrays;
|
import java.util.Arrays;
|
||||||
import java.util.Collection;
|
import java.util.Collection;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
import java.util.concurrent.CompletableFuture;
|
||||||
import java.util.concurrent.Executor;
|
import java.util.concurrent.Executor;
|
||||||
import java.util.stream.Collectors;
|
import java.util.stream.Collectors;
|
||||||
|
|
||||||
|
@ -86,7 +87,7 @@ public class ExamAPI_V1_Controller {
|
||||||
method = RequestMethod.POST,
|
method = RequestMethod.POST,
|
||||||
consumes = MediaType.APPLICATION_FORM_URLENCODED_VALUE,
|
consumes = MediaType.APPLICATION_FORM_URLENCODED_VALUE,
|
||||||
produces = MediaType.APPLICATION_JSON_UTF8_VALUE)
|
produces = MediaType.APPLICATION_JSON_UTF8_VALUE)
|
||||||
public Collection<RunningExamInfo> handshakeCreate(
|
public CompletableFuture<Collection<RunningExamInfo>> handshakeCreate(
|
||||||
@RequestParam(name = API.PARAM_INSTITUTION_ID, required = false) final Long instIdRequestParam,
|
@RequestParam(name = API.PARAM_INSTITUTION_ID, required = false) final Long instIdRequestParam,
|
||||||
@RequestParam(name = API.EXAM_API_PARAM_EXAM_ID, required = false) final Long examIdRequestParam,
|
@RequestParam(name = API.EXAM_API_PARAM_EXAM_ID, required = false) final Long examIdRequestParam,
|
||||||
@RequestBody(required = false) final MultiValueMap<String, String> formParams,
|
@RequestBody(required = false) final MultiValueMap<String, String> formParams,
|
||||||
|
@ -94,6 +95,9 @@ public class ExamAPI_V1_Controller {
|
||||||
final HttpServletRequest request,
|
final HttpServletRequest request,
|
||||||
final HttpServletResponse response) {
|
final HttpServletResponse response) {
|
||||||
|
|
||||||
|
return CompletableFuture.supplyAsync(
|
||||||
|
() -> {
|
||||||
|
|
||||||
final POSTMapper mapper = new POSTMapper(formParams);
|
final POSTMapper mapper = new POSTMapper(formParams);
|
||||||
|
|
||||||
final String remoteAddr = request.getRemoteAddr();
|
final String remoteAddr = request.getRemoteAddr();
|
||||||
|
@ -129,25 +133,31 @@ public class ExamAPI_V1_Controller {
|
||||||
}
|
}
|
||||||
|
|
||||||
if (result.isEmpty()) {
|
if (result.isEmpty()) {
|
||||||
log.warn("There are no currently running exams for institution: {}. SEB connection creation denied",
|
log.warn(
|
||||||
|
"There are no currently running exams for institution: {}. SEB connection creation denied",
|
||||||
institutionId);
|
institutionId);
|
||||||
throw new IllegalStateException("There are no currently running exams");
|
throw new IllegalStateException("There are no currently running exams");
|
||||||
}
|
}
|
||||||
|
|
||||||
return result;
|
return result;
|
||||||
|
},
|
||||||
|
this.executor);
|
||||||
}
|
}
|
||||||
|
|
||||||
@RequestMapping(
|
@RequestMapping(
|
||||||
path = API.EXAM_API_HANDSHAKE_ENDPOINT,
|
path = API.EXAM_API_HANDSHAKE_ENDPOINT,
|
||||||
method = RequestMethod.PATCH,
|
method = RequestMethod.PATCH,
|
||||||
consumes = MediaType.APPLICATION_FORM_URLENCODED_VALUE)
|
consumes = MediaType.APPLICATION_FORM_URLENCODED_VALUE)
|
||||||
public void handshakeUpdate(
|
public CompletableFuture<Void> handshakeUpdate(
|
||||||
@RequestHeader(name = API.EXAM_API_SEB_CONNECTION_TOKEN, required = true) final String connectionToken,
|
@RequestHeader(name = API.EXAM_API_SEB_CONNECTION_TOKEN, required = true) final String connectionToken,
|
||||||
@RequestParam(name = API.EXAM_API_PARAM_EXAM_ID, required = false) final Long examId,
|
@RequestParam(name = API.EXAM_API_PARAM_EXAM_ID, required = false) final Long examId,
|
||||||
@RequestParam(name = API.EXAM_API_USER_SESSION_ID, required = false) final String userSessionId,
|
@RequestParam(name = API.EXAM_API_USER_SESSION_ID, required = false) final String userSessionId,
|
||||||
final Principal principal,
|
final Principal principal,
|
||||||
final HttpServletRequest request) {
|
final HttpServletRequest request) {
|
||||||
|
|
||||||
|
return CompletableFuture.runAsync(
|
||||||
|
() -> {
|
||||||
|
|
||||||
final String remoteAddr = request.getRemoteAddr();
|
final String remoteAddr = request.getRemoteAddr();
|
||||||
final Long institutionId = getInstitutionId(principal);
|
final Long institutionId = getInstitutionId(principal);
|
||||||
|
|
||||||
|
@ -170,19 +180,24 @@ public class ExamAPI_V1_Controller {
|
||||||
remoteAddr,
|
remoteAddr,
|
||||||
userSessionId)
|
userSessionId)
|
||||||
.getOrThrow();
|
.getOrThrow();
|
||||||
|
},
|
||||||
|
this.executor);
|
||||||
}
|
}
|
||||||
|
|
||||||
@RequestMapping(
|
@RequestMapping(
|
||||||
path = API.EXAM_API_HANDSHAKE_ENDPOINT,
|
path = API.EXAM_API_HANDSHAKE_ENDPOINT,
|
||||||
method = RequestMethod.PUT,
|
method = RequestMethod.PUT,
|
||||||
consumes = MediaType.APPLICATION_FORM_URLENCODED_VALUE)
|
consumes = MediaType.APPLICATION_FORM_URLENCODED_VALUE)
|
||||||
public void handshakeEstablish(
|
public CompletableFuture<Void> handshakeEstablish(
|
||||||
@RequestHeader(name = API.EXAM_API_SEB_CONNECTION_TOKEN, required = true) final String connectionToken,
|
@RequestHeader(name = API.EXAM_API_SEB_CONNECTION_TOKEN, required = true) final String connectionToken,
|
||||||
@RequestParam(name = API.EXAM_API_PARAM_EXAM_ID, required = false) final Long examId,
|
@RequestParam(name = API.EXAM_API_PARAM_EXAM_ID, required = false) final Long examId,
|
||||||
@RequestParam(name = API.EXAM_API_USER_SESSION_ID, required = false) final String userSessionId,
|
@RequestParam(name = API.EXAM_API_USER_SESSION_ID, required = false) final String userSessionId,
|
||||||
final Principal principal,
|
final Principal principal,
|
||||||
final HttpServletRequest request) {
|
final HttpServletRequest request) {
|
||||||
|
|
||||||
|
return CompletableFuture.runAsync(
|
||||||
|
() -> {
|
||||||
|
|
||||||
final String remoteAddr = request.getRemoteAddr();
|
final String remoteAddr = request.getRemoteAddr();
|
||||||
final Long institutionId = getInstitutionId(principal);
|
final Long institutionId = getInstitutionId(principal);
|
||||||
|
|
||||||
|
@ -203,17 +218,22 @@ public class ExamAPI_V1_Controller {
|
||||||
remoteAddr,
|
remoteAddr,
|
||||||
userSessionId)
|
userSessionId)
|
||||||
.getOrThrow();
|
.getOrThrow();
|
||||||
|
},
|
||||||
|
this.executor);
|
||||||
}
|
}
|
||||||
|
|
||||||
@RequestMapping(
|
@RequestMapping(
|
||||||
path = API.EXAM_API_HANDSHAKE_ENDPOINT,
|
path = API.EXAM_API_HANDSHAKE_ENDPOINT,
|
||||||
method = RequestMethod.DELETE,
|
method = RequestMethod.DELETE,
|
||||||
consumes = MediaType.APPLICATION_FORM_URLENCODED_VALUE)
|
consumes = MediaType.APPLICATION_FORM_URLENCODED_VALUE)
|
||||||
public void handshakeDelete(
|
public CompletableFuture<Void> handshakeDelete(
|
||||||
@RequestHeader(name = API.EXAM_API_SEB_CONNECTION_TOKEN, required = true) final String connectionToken,
|
@RequestHeader(name = API.EXAM_API_SEB_CONNECTION_TOKEN, required = true) final String connectionToken,
|
||||||
final Principal principal,
|
final Principal principal,
|
||||||
final HttpServletRequest request) {
|
final HttpServletRequest request) {
|
||||||
|
|
||||||
|
return CompletableFuture.runAsync(
|
||||||
|
() -> {
|
||||||
|
|
||||||
final String remoteAddr = request.getRemoteAddr();
|
final String remoteAddr = request.getRemoteAddr();
|
||||||
final Long institutionId = getInstitutionId(principal);
|
final Long institutionId = getInstitutionId(principal);
|
||||||
|
|
||||||
|
@ -230,19 +250,91 @@ public class ExamAPI_V1_Controller {
|
||||||
institutionId,
|
institutionId,
|
||||||
remoteAddr)
|
remoteAddr)
|
||||||
.getOrThrow();
|
.getOrThrow();
|
||||||
|
},
|
||||||
|
this.executor);
|
||||||
}
|
}
|
||||||
|
|
||||||
@RequestMapping(
|
@RequestMapping(
|
||||||
path = API.EXAM_API_CONFIGURATION_REQUEST_ENDPOINT,
|
path = API.EXAM_API_CONFIGURATION_REQUEST_ENDPOINT,
|
||||||
method = RequestMethod.GET,
|
method = RequestMethod.GET,
|
||||||
produces = MediaType.APPLICATION_OCTET_STREAM_VALUE)
|
produces = MediaType.APPLICATION_OCTET_STREAM_VALUE)
|
||||||
public void getConfig(
|
public CompletableFuture<Void> getConfig(
|
||||||
@RequestHeader(name = API.EXAM_API_SEB_CONNECTION_TOKEN, required = true) final String connectionToken,
|
@RequestHeader(name = API.EXAM_API_SEB_CONNECTION_TOKEN, required = true) final String connectionToken,
|
||||||
@RequestParam(required = false) final MultiValueMap<String, String> formParams,
|
@RequestParam(required = false) final MultiValueMap<String, String> formParams,
|
||||||
final Principal principal,
|
final Principal principal,
|
||||||
final HttpServletRequest request,
|
final HttpServletRequest request,
|
||||||
final HttpServletResponse response) throws IOException {
|
final HttpServletResponse response) throws IOException {
|
||||||
|
|
||||||
|
return CompletableFuture.runAsync(
|
||||||
|
() -> streamExamConfig(connectionToken, formParams, principal, response),
|
||||||
|
this.executor);
|
||||||
|
}
|
||||||
|
|
||||||
|
private static final ResponseEntity<String> EMPTY_PING_RESPONSE = ResponseEntity
|
||||||
|
.ok()
|
||||||
|
.build();
|
||||||
|
|
||||||
|
@RequestMapping(
|
||||||
|
path = API.EXAM_API_PING_ENDPOINT,
|
||||||
|
method = RequestMethod.POST,
|
||||||
|
consumes = MediaType.APPLICATION_FORM_URLENCODED_VALUE,
|
||||||
|
produces = MediaType.APPLICATION_JSON_UTF8_VALUE)
|
||||||
|
public CompletableFuture<ResponseEntity<String>> ping(
|
||||||
|
@RequestHeader(name = API.EXAM_API_SEB_CONNECTION_TOKEN, required = true) final String connectionToken,
|
||||||
|
@RequestParam(name = API.EXAM_API_PING_TIMESTAMP, required = true) final long timestamp,
|
||||||
|
@RequestParam(name = API.EXAM_API_PING_NUMBER, required = false) final int pingNumber) {
|
||||||
|
|
||||||
|
return CompletableFuture.supplyAsync(
|
||||||
|
() -> {
|
||||||
|
final String notifyPing = this.sebClientConnectionService
|
||||||
|
.notifyPing(connectionToken, timestamp, pingNumber);
|
||||||
|
if (notifyPing == null) {
|
||||||
|
return EMPTY_PING_RESPONSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
return ResponseEntity
|
||||||
|
.ok()
|
||||||
|
.body(notifyPing);
|
||||||
|
},
|
||||||
|
this.executor);
|
||||||
|
}
|
||||||
|
|
||||||
|
@RequestMapping(
|
||||||
|
path = API.EXAM_API_EVENT_ENDPOINT,
|
||||||
|
method = RequestMethod.POST,
|
||||||
|
consumes = MediaType.APPLICATION_JSON_UTF8_VALUE)
|
||||||
|
public CompletableFuture<Void> event(
|
||||||
|
@RequestHeader(name = API.EXAM_API_SEB_CONNECTION_TOKEN, required = true) final String connectionToken,
|
||||||
|
@RequestBody(required = true) final ClientEvent event) {
|
||||||
|
|
||||||
|
return CompletableFuture.runAsync(
|
||||||
|
() -> this.sebClientConnectionService
|
||||||
|
.notifyClientEvent(connectionToken, event),
|
||||||
|
this.executor);
|
||||||
|
}
|
||||||
|
|
||||||
|
private Long getInstitutionId(final Principal principal) {
|
||||||
|
final String clientId = principal.getName();
|
||||||
|
return this.sebClientConfigDAO.byClientName(clientId)
|
||||||
|
.getOrThrow().institutionId;
|
||||||
|
}
|
||||||
|
|
||||||
|
private RunningExamInfo createRunningExamInfo(final Exam exam) {
|
||||||
|
return new RunningExamInfo(
|
||||||
|
exam,
|
||||||
|
this.lmsSetupDAO.byPK(exam.lmsSetupId)
|
||||||
|
.map(lms -> lms.lmsType)
|
||||||
|
.getOr(null));
|
||||||
|
}
|
||||||
|
|
||||||
|
private void streamExamConfig(
|
||||||
|
final String connectionToken,
|
||||||
|
final MultiValueMap<String, String> formParams,
|
||||||
|
final Principal principal,
|
||||||
|
final HttpServletResponse response) {
|
||||||
|
|
||||||
|
try {
|
||||||
|
|
||||||
// if an examId is provided with the request, update the connection first
|
// if an examId is provided with the request, update the connection first
|
||||||
if (formParams != null && formParams.containsKey(API.EXAM_API_PARAM_EXAM_ID)) {
|
if (formParams != null && formParams.containsKey(API.EXAM_API_PARAM_EXAM_ID)) {
|
||||||
final String examId = formParams.getFirst(API.EXAM_API_PARAM_EXAM_ID);
|
final String examId = formParams.getFirst(API.EXAM_API_PARAM_EXAM_ID);
|
||||||
|
@ -272,8 +364,9 @@ public class ExamAPI_V1_Controller {
|
||||||
if (connection.clientConnection.examId == null ||
|
if (connection.clientConnection.examId == null ||
|
||||||
!this.examSessionService.isExamRunning(connection.clientConnection.examId)) {
|
!this.examSessionService.isExamRunning(connection.clientConnection.examId)) {
|
||||||
|
|
||||||
log.error("Missing exam identifer or requested exam is not running for connection: {}", connection);
|
log.error("Missing exam identifier or requested exam is not running for connection: {}",
|
||||||
throw new IllegalStateException("Missing exam identider or requested exam is not running");
|
connection);
|
||||||
|
throw new IllegalStateException("Missing exam identifier or requested exam is not running");
|
||||||
}
|
}
|
||||||
} catch (final Exception e) {
|
} catch (final Exception e) {
|
||||||
|
|
||||||
|
@ -305,74 +398,20 @@ public class ExamAPI_V1_Controller {
|
||||||
outputStream.flush();
|
outputStream.flush();
|
||||||
outputStream.close();
|
outputStream.close();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
} catch (final Exception e) {
|
||||||
|
log.error("Unexpected error while trying to stream SEB Exam Configuration to client with connection: {}",
|
||||||
|
connectionToken,
|
||||||
|
e);
|
||||||
|
|
||||||
|
final APIMessage errorMessage = APIMessage.ErrorMessage.GENERIC.of(e.getMessage());
|
||||||
|
response.setStatus(HttpStatus.INTERNAL_SERVER_ERROR.value());
|
||||||
|
try {
|
||||||
|
response.getOutputStream().write(Utils.toByteArray(this.jsonMapper.writeValueAsString(errorMessage)));
|
||||||
|
} catch (final Exception e1) {
|
||||||
|
log.error("Failed to write error to response: ", e1);
|
||||||
}
|
}
|
||||||
|
|
||||||
private static final ResponseEntity<String> EMPTY_PING_RESPONSE = ResponseEntity
|
|
||||||
.ok()
|
|
||||||
.build();
|
|
||||||
|
|
||||||
@RequestMapping(
|
|
||||||
path = API.EXAM_API_PING_ENDPOINT,
|
|
||||||
method = RequestMethod.POST,
|
|
||||||
consumes = MediaType.APPLICATION_FORM_URLENCODED_VALUE,
|
|
||||||
produces = MediaType.APPLICATION_JSON_UTF8_VALUE)
|
|
||||||
public ResponseEntity<String> ping(
|
|
||||||
@RequestHeader(name = API.EXAM_API_SEB_CONNECTION_TOKEN, required = true) final String connectionToken,
|
|
||||||
@RequestParam(name = API.EXAM_API_PING_TIMESTAMP, required = true) final long timestamp,
|
|
||||||
@RequestParam(name = API.EXAM_API_PING_NUMBER, required = false) final int pingNumber) {
|
|
||||||
|
|
||||||
final String notifyPing = this.sebClientConnectionService
|
|
||||||
.notifyPing(connectionToken, timestamp, pingNumber);
|
|
||||||
|
|
||||||
if (notifyPing == null) {
|
|
||||||
return EMPTY_PING_RESPONSE;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return ResponseEntity
|
|
||||||
.ok()
|
|
||||||
.body(notifyPing);
|
|
||||||
}
|
|
||||||
|
|
||||||
// @RequestMapping(
|
|
||||||
// path = API.EXAM_API_PING_ENDPOINT,
|
|
||||||
// method = RequestMethod.POST,
|
|
||||||
// consumes = MediaType.APPLICATION_FORM_URLENCODED_VALUE,
|
|
||||||
// produces = MediaType.APPLICATION_JSON_UTF8_VALUE)
|
|
||||||
// public CompletableFuture<String> ping(
|
|
||||||
// @RequestHeader(name = API.EXAM_API_SEB_CONNECTION_TOKEN, required = true) final String connectionToken,
|
|
||||||
// @RequestParam(name = API.EXAM_API_PING_TIMESTAMP, required = true) final long timestamp,
|
|
||||||
// @RequestParam(name = API.EXAM_API_PING_NUMBER, required = false) final int pingNumber) {
|
|
||||||
//
|
|
||||||
// return CompletableFuture.supplyAsync(
|
|
||||||
// () -> this.sebClientConnectionService
|
|
||||||
// .notifyPing(connectionToken, timestamp, pingNumber),
|
|
||||||
// this.executor);
|
|
||||||
// }
|
|
||||||
|
|
||||||
@RequestMapping(
|
|
||||||
path = API.EXAM_API_EVENT_ENDPOINT,
|
|
||||||
method = RequestMethod.POST,
|
|
||||||
consumes = MediaType.APPLICATION_JSON_UTF8_VALUE)
|
|
||||||
public void event(
|
|
||||||
@RequestHeader(name = API.EXAM_API_SEB_CONNECTION_TOKEN, required = true) final String connectionToken,
|
|
||||||
@RequestBody(required = true) final ClientEvent event) {
|
|
||||||
|
|
||||||
this.sebClientConnectionService
|
|
||||||
.notifyClientEvent(connectionToken, event);
|
|
||||||
}
|
|
||||||
|
|
||||||
private Long getInstitutionId(final Principal principal) {
|
|
||||||
final String clientId = principal.getName();
|
|
||||||
return this.sebClientConfigDAO.byClientName(clientId)
|
|
||||||
.getOrThrow().institutionId;
|
|
||||||
}
|
|
||||||
|
|
||||||
private RunningExamInfo createRunningExamInfo(final Exam exam) {
|
|
||||||
return new RunningExamInfo(
|
|
||||||
exam,
|
|
||||||
this.lmsSetupDAO.byPK(exam.lmsSetupId)
|
|
||||||
.map(lms -> lms.lmsType)
|
|
||||||
.getOr(null));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -11,6 +11,7 @@ package ch.ethz.seb.sebserver.webservice.integration.api.exam;
|
||||||
import static org.springframework.security.test.web.servlet.request.SecurityMockMvcRequestPostProcessors.httpBasic;
|
import static org.springframework.security.test.web.servlet.request.SecurityMockMvcRequestPostProcessors.httpBasic;
|
||||||
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.*;
|
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.*;
|
||||||
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.content;
|
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.content;
|
||||||
|
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.request;
|
||||||
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;
|
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;
|
||||||
|
|
||||||
import java.util.Collections;
|
import java.util.Collections;
|
||||||
|
@ -39,8 +40,10 @@ import org.springframework.security.web.FilterChainProxy;
|
||||||
import org.springframework.test.context.ActiveProfiles;
|
import org.springframework.test.context.ActiveProfiles;
|
||||||
import org.springframework.test.context.junit4.SpringRunner;
|
import org.springframework.test.context.junit4.SpringRunner;
|
||||||
import org.springframework.test.web.servlet.MockMvc;
|
import org.springframework.test.web.servlet.MockMvc;
|
||||||
|
import org.springframework.test.web.servlet.MvcResult;
|
||||||
import org.springframework.test.web.servlet.ResultActions;
|
import org.springframework.test.web.servlet.ResultActions;
|
||||||
import org.springframework.test.web.servlet.request.MockHttpServletRequestBuilder;
|
import org.springframework.test.web.servlet.request.MockHttpServletRequestBuilder;
|
||||||
|
import org.springframework.test.web.servlet.result.MockMvcResultHandlers;
|
||||||
import org.springframework.test.web.servlet.setup.MockMvcBuilders;
|
import org.springframework.test.web.servlet.setup.MockMvcBuilders;
|
||||||
import org.springframework.util.LinkedMultiValueMap;
|
import org.springframework.util.LinkedMultiValueMap;
|
||||||
import org.springframework.util.MultiValueMap;
|
import org.springframework.util.MultiValueMap;
|
||||||
|
@ -153,7 +156,12 @@ public abstract class ExamAPIIntegrationTester {
|
||||||
|
|
||||||
builder.content(body);
|
builder.content(body);
|
||||||
|
|
||||||
final ResultActions result = this.mockMvc.perform(builder)
|
final MvcResult mvcResult = this.mockMvc.perform(builder)
|
||||||
|
.andExpect(request().asyncStarted())
|
||||||
|
.andDo(MockMvcResultHandlers.log())
|
||||||
|
.andReturn();
|
||||||
|
|
||||||
|
final ResultActions result = this.mockMvc.perform(asyncDispatch(mvcResult))
|
||||||
.andExpect(content().contentType(MediaType.APPLICATION_JSON_UTF8_VALUE));
|
.andExpect(content().contentType(MediaType.APPLICATION_JSON_UTF8_VALUE));
|
||||||
|
|
||||||
return result.andReturn().getResponse();
|
return result.andReturn().getResponse();
|
||||||
|
@ -209,7 +217,13 @@ public abstract class ExamAPIIntegrationTester {
|
||||||
}
|
}
|
||||||
builder.content(body);
|
builder.content(body);
|
||||||
|
|
||||||
final ResultActions result = this.mockMvc.perform(builder);
|
final MvcResult mvcResult = this.mockMvc
|
||||||
|
.perform(builder)
|
||||||
|
.andExpect(request().asyncStarted())
|
||||||
|
.andDo(MockMvcResultHandlers.log())
|
||||||
|
.andReturn();
|
||||||
|
|
||||||
|
final ResultActions result = this.mockMvc.perform(asyncDispatch(mvcResult));
|
||||||
|
|
||||||
return result.andReturn().getResponse();
|
return result.andReturn().getResponse();
|
||||||
}
|
}
|
||||||
|
@ -221,7 +235,13 @@ public abstract class ExamAPIIntegrationTester {
|
||||||
.header("Authorization", "Bearer " + accessToken)
|
.header("Authorization", "Bearer " + accessToken)
|
||||||
.header(API.EXAM_API_SEB_CONNECTION_TOKEN, connectionToken)
|
.header(API.EXAM_API_SEB_CONNECTION_TOKEN, connectionToken)
|
||||||
.accept(MediaType.APPLICATION_JSON_UTF8_VALUE);
|
.accept(MediaType.APPLICATION_JSON_UTF8_VALUE);
|
||||||
final ResultActions result = this.mockMvc.perform(builder);
|
|
||||||
|
final MvcResult mvcResult = this.mockMvc
|
||||||
|
.perform(builder)
|
||||||
|
.andExpect(request().asyncStarted())
|
||||||
|
.andDo(MockMvcResultHandlers.log())
|
||||||
|
.andReturn();
|
||||||
|
final ResultActions result = this.mockMvc.perform(asyncDispatch(mvcResult));
|
||||||
return result.andReturn().getResponse();
|
return result.andReturn().getResponse();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -239,7 +259,12 @@ public abstract class ExamAPIIntegrationTester {
|
||||||
+ "&" + API.EXAM_API_PING_NUMBER + "=" + num;
|
+ "&" + API.EXAM_API_PING_NUMBER + "=" + num;
|
||||||
builder.content(body);
|
builder.content(body);
|
||||||
|
|
||||||
final ResultActions result = this.mockMvc.perform(builder);
|
final MvcResult mvcResult = this.mockMvc
|
||||||
|
.perform(builder)
|
||||||
|
.andExpect(request().asyncStarted())
|
||||||
|
.andDo(MockMvcResultHandlers.log())
|
||||||
|
.andReturn();
|
||||||
|
final ResultActions result = this.mockMvc.perform(asyncDispatch(mvcResult));
|
||||||
return result.andReturn().getResponse();
|
return result.andReturn().getResponse();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -259,7 +284,12 @@ public abstract class ExamAPIIntegrationTester {
|
||||||
|
|
||||||
final String body = "{ \"type\": \"%s\", \"timestamp\": %s, \"numericValue\": %s, \"text\": \"%s\" }";
|
final String body = "{ \"type\": \"%s\", \"timestamp\": %s, \"numericValue\": %s, \"text\": \"%s\" }";
|
||||||
builder.content(String.format(body, type, timestamp, value, text));
|
builder.content(String.format(body, type, timestamp, value, text));
|
||||||
final ResultActions result = this.mockMvc.perform(builder);
|
final MvcResult mvcResult = this.mockMvc
|
||||||
|
.perform(builder)
|
||||||
|
.andExpect(request().asyncStarted())
|
||||||
|
.andDo(MockMvcResultHandlers.log())
|
||||||
|
.andReturn();
|
||||||
|
final ResultActions result = this.mockMvc.perform(asyncDispatch(mvcResult));
|
||||||
return result.andReturn().getResponse();
|
return result.andReturn().getResponse();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -278,8 +308,13 @@ public abstract class ExamAPIIntegrationTester {
|
||||||
builder.content("examId=" + examId);
|
builder.content("examId=" + examId);
|
||||||
}
|
}
|
||||||
|
|
||||||
final ResultActions result = this.mockMvc
|
final MvcResult mvcResult = this.mockMvc
|
||||||
.perform(builder);
|
.perform(builder)
|
||||||
|
.andExpect(request().asyncStarted())
|
||||||
|
.andDo(MockMvcResultHandlers.log())
|
||||||
|
.andReturn();
|
||||||
|
|
||||||
|
final ResultActions result = this.mockMvc.perform(asyncDispatch(mvcResult));
|
||||||
|
|
||||||
return result.andReturn().getResponse();
|
return result.andReturn().getResponse();
|
||||||
}
|
}
|
||||||
|
|
|
@ -210,7 +210,7 @@ public class SebExamConfigurationRequestTest extends ExamAPIIntegrationTester {
|
||||||
// check error
|
// check error
|
||||||
final String contentAsString = configResponse.getContentAsString();
|
final String contentAsString = configResponse.getContentAsString();
|
||||||
assertEquals(
|
assertEquals(
|
||||||
"{\"messageCode\":\"0\",\"systemMessage\":\"Generic error message\",\"details\":\"Missing exam identider or requested exam is not running\",\"attributes\":[]}",
|
"{\"messageCode\":\"0\",\"systemMessage\":\"Generic error message\",\"details\":\"Missing exam identifier or requested exam is not running\",\"attributes\":[]}",
|
||||||
contentAsString);
|
contentAsString);
|
||||||
|
|
||||||
// check connection cache
|
// check connection cache
|
||||||
|
@ -253,7 +253,7 @@ public class SebExamConfigurationRequestTest extends ExamAPIIntegrationTester {
|
||||||
assertTrue(HttpStatus.OK.value() != configResponse.getStatus());
|
assertTrue(HttpStatus.OK.value() != configResponse.getStatus());
|
||||||
final String contentAsString = configResponse.getContentAsString();
|
final String contentAsString = configResponse.getContentAsString();
|
||||||
assertEquals(
|
assertEquals(
|
||||||
"{\"messageCode\":\"0\",\"systemMessage\":\"Generic error message\",\"details\":\"Missing exam identider or requested exam is not running\",\"attributes\":[]}",
|
"{\"messageCode\":\"0\",\"systemMessage\":\"Generic error message\",\"details\":\"Missing exam identifier or requested exam is not running\",\"attributes\":[]}",
|
||||||
contentAsString);
|
contentAsString);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue