Merge remote-tracking branch 'origin/dev-1.1.0' into development
This commit is contained in:
commit
1796ff4a7a
9 changed files with 193 additions and 46 deletions
|
@ -68,9 +68,19 @@ public class SEBExamConfigImportPopup {
|
||||||
this.pageService = pageService;
|
this.pageService = pageService;
|
||||||
}
|
}
|
||||||
|
|
||||||
public Function<PageAction, PageAction> importFunction(final boolean newConfig) {
|
public Function<PageAction, PageAction> importFunction() {
|
||||||
|
return importFunction(null);
|
||||||
|
}
|
||||||
|
|
||||||
|
public Function<PageAction, PageAction> importFunction(final Supplier<String> tabSelectionSupplier) {
|
||||||
return action -> {
|
return action -> {
|
||||||
|
|
||||||
|
final boolean newConfig = tabSelectionSupplier == null || tabSelectionSupplier.get() == null;
|
||||||
|
final PageContext context = (tabSelectionSupplier != null)
|
||||||
|
? action.pageContext()
|
||||||
|
.withAttribute(SEBSettingsForm.ATTR_VIEW_INDEX, tabSelectionSupplier.get())
|
||||||
|
: action.pageContext();
|
||||||
|
|
||||||
final ModalInputDialog<FormHandle<ConfigurationNode>> dialog =
|
final ModalInputDialog<FormHandle<ConfigurationNode>> dialog =
|
||||||
new ModalInputDialog<FormHandle<ConfigurationNode>>(
|
new ModalInputDialog<FormHandle<ConfigurationNode>>(
|
||||||
action.pageContext().getParent().getShell(),
|
action.pageContext().getParent().getShell(),
|
||||||
|
@ -79,7 +89,7 @@ public class SEBExamConfigImportPopup {
|
||||||
|
|
||||||
final ImportFormContext importFormContext = new ImportFormContext(
|
final ImportFormContext importFormContext = new ImportFormContext(
|
||||||
this.pageService,
|
this.pageService,
|
||||||
action.pageContext(),
|
context,
|
||||||
newConfig);
|
newConfig);
|
||||||
|
|
||||||
dialog.open(
|
dialog.open(
|
||||||
|
@ -147,18 +157,6 @@ public class SEBExamConfigImportPopup {
|
||||||
|
|
||||||
if (!configuration.hasError()) {
|
if (!configuration.hasError()) {
|
||||||
context.publishInfo(SEBExamConfigForm.FORM_IMPORT_CONFIRM_TEXT_KEY);
|
context.publishInfo(SEBExamConfigForm.FORM_IMPORT_CONFIRM_TEXT_KEY);
|
||||||
final PageAction action = (newConfig)
|
|
||||||
? this.pageService.pageActionBuilder(context)
|
|
||||||
.newAction(ActionDefinition.SEB_EXAM_CONFIG_IMPORT_TO_NEW_CONFIG)
|
|
||||||
.create()
|
|
||||||
: this.pageService.pageActionBuilder(context)
|
|
||||||
.newAction(ActionDefinition.SEB_EXAM_CONFIG_MODIFY)
|
|
||||||
.create();
|
|
||||||
|
|
||||||
this.pageService.firePageEvent(
|
|
||||||
new ActionEvent(action),
|
|
||||||
action.pageContext());
|
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
final Exception error = configuration.getError();
|
final Exception error = configuration.getError();
|
||||||
if (error instanceof RestCallError) {
|
if (error instanceof RestCallError) {
|
||||||
|
@ -177,14 +175,15 @@ public class SEBExamConfigImportPopup {
|
||||||
.notifyImportError(EntityType.CONFIGURATION_NODE, error);
|
.notifyImportError(EntityType.CONFIGURATION_NODE, error);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
} else {
|
||||||
formHandle.getContext().notifyError(
|
formHandle.getContext().notifyError(
|
||||||
SEBExamConfigForm.FORM_TITLE,
|
SEBExamConfigForm.FORM_TITLE,
|
||||||
configuration.getError());
|
configuration.getError());
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
reloadPage(newConfig, context);
|
||||||
return true;
|
return true;
|
||||||
} else {
|
} else {
|
||||||
formHandle.getContext().publishPageMessage(
|
formHandle.getContext().publishPageMessage(
|
||||||
|
@ -194,11 +193,26 @@ public class SEBExamConfigImportPopup {
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
} catch (final Exception e) {
|
} catch (final Exception e) {
|
||||||
|
reloadPage(newConfig, formHandle.getContext());
|
||||||
formHandle.getContext().notifyError(SEBExamConfigForm.FORM_TITLE, e);
|
formHandle.getContext().notifyError(SEBExamConfigForm.FORM_TITLE, e);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void reloadPage(final boolean newConfig, final PageContext context) {
|
||||||
|
final PageAction action = (newConfig)
|
||||||
|
? this.pageService.pageActionBuilder(context)
|
||||||
|
.newAction(ActionDefinition.SEB_EXAM_CONFIG_IMPORT_TO_NEW_CONFIG)
|
||||||
|
.create()
|
||||||
|
: this.pageService.pageActionBuilder(context)
|
||||||
|
.newAction(ActionDefinition.SEB_EXAM_CONFIG_MODIFY)
|
||||||
|
.create();
|
||||||
|
|
||||||
|
this.pageService.firePageEvent(
|
||||||
|
new ActionEvent(action),
|
||||||
|
action.pageContext());
|
||||||
|
}
|
||||||
|
|
||||||
private boolean checkInput(final FormHandle<ConfigurationNode> formHandle, final boolean newConfig,
|
private boolean checkInput(final FormHandle<ConfigurationNode> formHandle, final boolean newConfig,
|
||||||
final Form form) {
|
final Form form) {
|
||||||
if (newConfig) {
|
if (newConfig) {
|
||||||
|
|
|
@ -170,7 +170,7 @@ public class SEBExamConfigList implements TemplateComposer {
|
||||||
.newAction(ActionDefinition.SEB_EXAM_CONFIG_IMPORT_TO_NEW_CONFIG)
|
.newAction(ActionDefinition.SEB_EXAM_CONFIG_IMPORT_TO_NEW_CONFIG)
|
||||||
.withSelect(
|
.withSelect(
|
||||||
configTable.getGrantedSelection(this.currentUser, NO_MODIFY_PRIVILEGE_ON_OTHER_INSTITUTION),
|
configTable.getGrantedSelection(this.currentUser, NO_MODIFY_PRIVILEGE_ON_OTHER_INSTITUTION),
|
||||||
this.sebExamConfigImportPopup.importFunction(true),
|
this.sebExamConfigImportPopup.importFunction(),
|
||||||
EMPTY_SELECTION_TEXT_KEY)
|
EMPTY_SELECTION_TEXT_KEY)
|
||||||
.noEventPropagation()
|
.noEventPropagation()
|
||||||
.publishIf(examConfigGrant::im);
|
.publishIf(examConfigGrant::im);
|
||||||
|
|
|
@ -69,6 +69,8 @@ public class SEBSettingsForm implements TemplateComposer {
|
||||||
|
|
||||||
private static final Logger log = LoggerFactory.getLogger(SEBSettingsForm.class);
|
private static final Logger log = LoggerFactory.getLogger(SEBSettingsForm.class);
|
||||||
|
|
||||||
|
public static final String ATTR_VIEW_INDEX = "VIEW_INDEX";
|
||||||
|
|
||||||
private static final String VIEW_TEXT_KEY_PREFIX =
|
private static final String VIEW_TEXT_KEY_PREFIX =
|
||||||
"sebserver.examconfig.props.form.views.";
|
"sebserver.examconfig.props.form.views.";
|
||||||
private static final String KEY_SAVE_TO_HISTORY_SUCCESS =
|
private static final String KEY_SAVE_TO_HISTORY_SUCCESS =
|
||||||
|
@ -194,7 +196,7 @@ public class SEBSettingsForm implements TemplateComposer {
|
||||||
}
|
}
|
||||||
|
|
||||||
// set selection if available
|
// set selection if available
|
||||||
final String viewIndex = pageContext.getAttribute("VIEW_INDEX");
|
final String viewIndex = pageContext.getAttribute(ATTR_VIEW_INDEX);
|
||||||
if (StringUtils.isNotBlank(viewIndex)) {
|
if (StringUtils.isNotBlank(viewIndex)) {
|
||||||
try {
|
try {
|
||||||
tabFolder.setSelection(Integer.parseInt(viewIndex));
|
tabFolder.setSelection(Integer.parseInt(viewIndex));
|
||||||
|
@ -217,7 +219,7 @@ public class SEBSettingsForm implements TemplateComposer {
|
||||||
.call()
|
.call()
|
||||||
.onError(t -> notifyErrorOnSave(t, pageContext));
|
.onError(t -> notifyErrorOnSave(t, pageContext));
|
||||||
return action.withAttribute(
|
return action.withAttribute(
|
||||||
"VIEW_INDEX",
|
ATTR_VIEW_INDEX,
|
||||||
String.valueOf(tabFolder.getSelectionIndex()));
|
String.valueOf(tabFolder.getSelectionIndex()));
|
||||||
})
|
})
|
||||||
.withSuccess(KEY_SAVE_TO_HISTORY_SUCCESS)
|
.withSuccess(KEY_SAVE_TO_HISTORY_SUCCESS)
|
||||||
|
@ -232,7 +234,7 @@ public class SEBSettingsForm implements TemplateComposer {
|
||||||
.call()
|
.call()
|
||||||
.getOrThrow();
|
.getOrThrow();
|
||||||
return action.withAttribute(
|
return action.withAttribute(
|
||||||
"VIEW_INDEX",
|
ATTR_VIEW_INDEX,
|
||||||
String.valueOf(tabFolder.getSelectionIndex()));
|
String.valueOf(tabFolder.getSelectionIndex()));
|
||||||
})
|
})
|
||||||
.withSuccess(KEY_UNDO_SUCCESS)
|
.withSuccess(KEY_UNDO_SUCCESS)
|
||||||
|
@ -254,7 +256,9 @@ public class SEBSettingsForm implements TemplateComposer {
|
||||||
|
|
||||||
.newAction(ActionDefinition.SEB_EXAM_CONFIG_IMPORT_TO_EXISTING_CONFIG)
|
.newAction(ActionDefinition.SEB_EXAM_CONFIG_IMPORT_TO_EXISTING_CONFIG)
|
||||||
.withEntityKey(entityKey)
|
.withEntityKey(entityKey)
|
||||||
.withExec(this.sebExamConfigImportPopup.importFunction(false))
|
.withExec(this.sebExamConfigImportPopup.importFunction(
|
||||||
|
() -> String.valueOf(tabFolder.getSelectionIndex())))
|
||||||
|
.noEventPropagation()
|
||||||
.publishIf(() -> examConfigGrant.iw() && !readonly && !isAttachedToExam)
|
.publishIf(() -> examConfigGrant.iw() && !readonly && !isAttachedToExam)
|
||||||
|
|
||||||
.newAction(ActionDefinition.SEB_EXAM_CONFIG_VIEW_PROP)
|
.newAction(ActionDefinition.SEB_EXAM_CONFIG_VIEW_PROP)
|
||||||
|
|
|
@ -35,13 +35,16 @@ public class WebserviceInfoDAOImpl implements WebserviceInfoDAO {
|
||||||
|
|
||||||
private final WebserviceServerInfoRecordMapper webserviceServerInfoRecordMapper;
|
private final WebserviceServerInfoRecordMapper webserviceServerInfoRecordMapper;
|
||||||
private final long masterDelayTimeThreshold;
|
private final long masterDelayTimeThreshold;
|
||||||
|
private final boolean forceMaster;
|
||||||
|
|
||||||
public WebserviceInfoDAOImpl(
|
public WebserviceInfoDAOImpl(
|
||||||
final WebserviceServerInfoRecordMapper webserviceServerInfoRecordMapper,
|
final WebserviceServerInfoRecordMapper webserviceServerInfoRecordMapper,
|
||||||
|
@Value("${sebserver.webservice.forceMaster:false}") final boolean forceMaster,
|
||||||
@Value("${sebserver.webservice.master.delay.threshold:10000}") final long masterDelayTimeThreshold) {
|
@Value("${sebserver.webservice.master.delay.threshold:10000}") final long masterDelayTimeThreshold) {
|
||||||
|
|
||||||
this.webserviceServerInfoRecordMapper = webserviceServerInfoRecordMapper;
|
this.webserviceServerInfoRecordMapper = webserviceServerInfoRecordMapper;
|
||||||
this.masterDelayTimeThreshold = masterDelayTimeThreshold;
|
this.masterDelayTimeThreshold = masterDelayTimeThreshold;
|
||||||
|
this.forceMaster = forceMaster;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Transactional
|
@Transactional
|
||||||
|
@ -68,18 +71,24 @@ public class WebserviceInfoDAOImpl implements WebserviceInfoDAO {
|
||||||
|
|
||||||
if (masters != null && !masters.isEmpty()) {
|
if (masters != null && !masters.isEmpty()) {
|
||||||
if (masters.size() > 1) {
|
if (masters.size() > 1) {
|
||||||
|
|
||||||
log.error("There are more then one master registered: ", masters);
|
log.error("There are more then one master registered: ", masters);
|
||||||
log.info("Reset masters and set this webservice as new master");
|
log.info("Reset masters and set this webservice as new master");
|
||||||
masters.stream()
|
|
||||||
.forEach(masterRec -> this.webserviceServerInfoRecordMapper.updateByPrimaryKeySelective(
|
masters.stream().forEach(masterRec -> this.webserviceServerInfoRecordMapper
|
||||||
new WebserviceServerInfoRecord(masterRec.getId(), null, null, 0, 0L)));
|
.updateByPrimaryKeySelective(
|
||||||
this.setMasterTo(uuid);
|
new WebserviceServerInfoRecord(
|
||||||
return true;
|
masterRec.getId(),
|
||||||
|
null,
|
||||||
|
null,
|
||||||
|
0,
|
||||||
|
0L)));
|
||||||
|
return this.setMasterTo(uuid);
|
||||||
}
|
}
|
||||||
|
|
||||||
final WebserviceServerInfoRecord masterRec = masters.get(0);
|
final WebserviceServerInfoRecord masterRec = masters.get(0);
|
||||||
if (masterRec.getUuid().equals(uuid)) {
|
if (masterRec.getUuid().equals(uuid)) {
|
||||||
// this webservice was the master and update time to remain being master
|
// This webservice is the master. Update time-stamp to remain being master
|
||||||
final long now = Utils.getMillisecondsNow();
|
final long now = Utils.getMillisecondsNow();
|
||||||
this.webserviceServerInfoRecordMapper.updateByPrimaryKeySelective(
|
this.webserviceServerInfoRecordMapper.updateByPrimaryKeySelective(
|
||||||
new WebserviceServerInfoRecord(masterRec.getId(), null, null, null, now));
|
new WebserviceServerInfoRecord(masterRec.getId(), null, null, null, now));
|
||||||
|
@ -91,20 +100,18 @@ public class WebserviceInfoDAOImpl implements WebserviceInfoDAO {
|
||||||
return true;
|
return true;
|
||||||
} else {
|
} else {
|
||||||
// Another webservice is master. Check if still alive...
|
// Another webservice is master. Check if still alive...
|
||||||
|
// Force this service to become master if the other master is not alive anymore
|
||||||
|
// Or if this service is forced to be the master service
|
||||||
final long now = Utils.getMillisecondsNow();
|
final long now = Utils.getMillisecondsNow();
|
||||||
final long lastUpdateSince = now - masterRec.getUpdateTime();
|
final long lastUpdateSince = now - masterRec.getUpdateTime();
|
||||||
if (lastUpdateSince > this.masterDelayTimeThreshold) {
|
if (lastUpdateSince > this.masterDelayTimeThreshold || this.forceMaster) {
|
||||||
log.info("Change webservice master form uuid: {} to uuid: {}", masterRec.getUuid(), uuid);
|
forceMaster(uuid, masterRec.getUuid(), masterRec.getId());
|
||||||
this.webserviceServerInfoRecordMapper.updateByPrimaryKeySelective(
|
|
||||||
new WebserviceServerInfoRecord(masterRec.getId(), null, null, 0, 0L));
|
|
||||||
setMasterTo(uuid);
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
// if we have no master yet
|
// We have no master yet so set this as master service
|
||||||
setMasterTo(uuid);
|
return setMasterTo(uuid);
|
||||||
return true;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
|
@ -115,14 +122,41 @@ public class WebserviceInfoDAOImpl implements WebserviceInfoDAO {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void setMasterTo(final String uuid) {
|
private void forceMaster(final String uuid, final String otherUUID, final Long otherId) {
|
||||||
|
|
||||||
|
log.info("Change webservice master form uuid: {} to uuid: {}", otherUUID, uuid);
|
||||||
|
|
||||||
|
this.webserviceServerInfoRecordMapper.updateByPrimaryKeySelective(
|
||||||
|
new WebserviceServerInfoRecord(otherId, null, null, 0, 0L));
|
||||||
|
setMasterTo(uuid);
|
||||||
|
}
|
||||||
|
|
||||||
|
private boolean setMasterTo(final String uuid) {
|
||||||
log.info("Set webservice {} as master", uuid);
|
log.info("Set webservice {} as master", uuid);
|
||||||
final long now = Utils.getMillisecondsNow();
|
final long now = Utils.getMillisecondsNow();
|
||||||
this.webserviceServerInfoRecordMapper.updateByExampleSelective(
|
|
||||||
|
// check if this is registered
|
||||||
|
final List<WebserviceServerInfoRecord> entries = this.webserviceServerInfoRecordMapper.selectByExample()
|
||||||
|
.where(WebserviceServerInfoRecordDynamicSqlSupport.uuid, SqlBuilder.isEqualTo(uuid))
|
||||||
|
.build()
|
||||||
|
.execute();
|
||||||
|
|
||||||
|
if (entries == null || entries.isEmpty()) {
|
||||||
|
log.warn("The webservice with uuid: {} is not registered and cannot become a master", uuid);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
final Integer execute = this.webserviceServerInfoRecordMapper.updateByExampleSelective(
|
||||||
new WebserviceServerInfoRecord(null, null, null, 1, now))
|
new WebserviceServerInfoRecord(null, null, null, 1, now))
|
||||||
.where(WebserviceServerInfoRecordDynamicSqlSupport.uuid, SqlBuilder.isEqualTo(uuid))
|
.where(WebserviceServerInfoRecordDynamicSqlSupport.uuid, SqlBuilder.isEqualTo(uuid))
|
||||||
.build()
|
.build()
|
||||||
.execute();
|
.execute();
|
||||||
|
if (execute == null || execute.intValue() <= 0) {
|
||||||
|
log.error("Failed to update webservice with uuid: {} to become master", uuid);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Transactional
|
@Transactional
|
||||||
|
|
|
@ -49,12 +49,6 @@ class ExamSessionControlTask implements DisposableBean {
|
||||||
private final String examTaskCron;
|
private final String examTaskCron;
|
||||||
private final long pingUpdateRate;
|
private final long pingUpdateRate;
|
||||||
|
|
||||||
// TODO considering to have some caching of running exams end dates here to improve performance
|
|
||||||
// the end check task has than only to first update missing running exams and then
|
|
||||||
// check the exam ending within the cached end date of the exam. if an exam has ended by
|
|
||||||
// applying the check to the cached value, the process can double-check if the end date has
|
|
||||||
// no change and update if needed or end the exam and remove from cache.
|
|
||||||
|
|
||||||
protected ExamSessionControlTask(
|
protected ExamSessionControlTask(
|
||||||
final ExamDAO examDAO,
|
final ExamDAO examDAO,
|
||||||
final SEBClientConnectionService sebClientConnectionService,
|
final SEBClientConnectionService sebClientConnectionService,
|
||||||
|
|
|
@ -32,6 +32,7 @@ sebserver.webservice.api.admin.clientSecret=${sebserver.password}
|
||||||
sebserver.webservice.internalSecret=${sebserver.password}
|
sebserver.webservice.internalSecret=${sebserver.password}
|
||||||
|
|
||||||
### webservice networking
|
### webservice networking
|
||||||
|
sebserver.webservice.forceMaster=false
|
||||||
sebserver.webservice.distributed=false
|
sebserver.webservice.distributed=false
|
||||||
sebserver.webservice.http.external.scheme=https
|
sebserver.webservice.http.external.scheme=https
|
||||||
sebserver.webservice.http.external.servername=
|
sebserver.webservice.http.external.servername=
|
||||||
|
|
|
@ -36,6 +36,8 @@ import ch.ethz.seb.sebserver.gui.service.remote.webservice.api.RestServiceImpl;
|
||||||
import ch.ethz.seb.sebserver.gui.service.remote.webservice.auth.OAuth2AuthorizationContextHolder;
|
import ch.ethz.seb.sebserver.gui.service.remote.webservice.auth.OAuth2AuthorizationContextHolder;
|
||||||
import ch.ethz.seb.sebserver.gui.service.remote.webservice.auth.SEBServerAuthorizationContext;
|
import ch.ethz.seb.sebserver.gui.service.remote.webservice.auth.SEBServerAuthorizationContext;
|
||||||
import ch.ethz.seb.sebserver.gui.service.remote.webservice.auth.WebserviceURIService;
|
import ch.ethz.seb.sebserver.gui.service.remote.webservice.auth.WebserviceURIService;
|
||||||
|
import ch.ethz.seb.sebserver.webservice.WebserviceInfo;
|
||||||
|
import ch.ethz.seb.sebserver.webservice.servicelayer.dao.WebserviceInfoDAO;
|
||||||
|
|
||||||
@RunWith(SpringRunner.class)
|
@RunWith(SpringRunner.class)
|
||||||
@SpringBootTest(
|
@SpringBootTest(
|
||||||
|
@ -59,13 +61,19 @@ public abstract class GuiIntegrationTest {
|
||||||
protected JSONMapper jsonMapper;
|
protected JSONMapper jsonMapper;
|
||||||
@Autowired
|
@Autowired
|
||||||
protected FilterChainProxy springSecurityFilterChain;
|
protected FilterChainProxy springSecurityFilterChain;
|
||||||
|
@Autowired
|
||||||
|
private WebserviceInfoDAO webserviceInfoDAO;
|
||||||
|
@Autowired
|
||||||
|
private WebserviceInfo webserviceInfo;
|
||||||
|
|
||||||
protected MockMvc mockMvc;
|
protected MockMvc mockMvc;
|
||||||
|
|
||||||
@Before
|
@Before
|
||||||
public void setup() {
|
public void setup() {
|
||||||
|
this.webserviceInfoDAO.unregister(this.webserviceInfo.getWebserviceUUID());
|
||||||
this.mockMvc = MockMvcBuilders.webAppContextSetup(this.wac)
|
this.mockMvc = MockMvcBuilders.webAppContextSetup(this.wac)
|
||||||
.addFilter(this.springSecurityFilterChain).build();
|
.addFilter(this.springSecurityFilterChain).build();
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
protected OAuth2AuthorizationContextHolder getAuthorizationContextHolder() {
|
protected OAuth2AuthorizationContextHolder getAuthorizationContextHolder() {
|
||||||
|
|
|
@ -0,0 +1,85 @@
|
||||||
|
/*
|
||||||
|
* Copyright (c) 2021 ETH Zürich, Educational Development and Technology (LET)
|
||||||
|
*
|
||||||
|
* This Source Code Form is subject to the terms of the Mozilla Public
|
||||||
|
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||||
|
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package ch.ethz.seb.sebserver.webservice.integration.api.admin;
|
||||||
|
|
||||||
|
import static org.junit.Assert.assertFalse;
|
||||||
|
import static org.junit.Assert.assertTrue;
|
||||||
|
|
||||||
|
import org.junit.After;
|
||||||
|
import org.junit.Before;
|
||||||
|
import org.junit.Test;
|
||||||
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
|
|
||||||
|
import ch.ethz.seb.sebserver.webservice.WebserviceInfo;
|
||||||
|
import ch.ethz.seb.sebserver.webservice.servicelayer.dao.WebserviceInfoDAO;
|
||||||
|
|
||||||
|
public class WebserviceTest extends AdministrationAPIIntegrationTester {
|
||||||
|
|
||||||
|
private static final String WEBSERVICE_1 = "WEBSERVICE_1";
|
||||||
|
private static final String WEBSERVICE_2 = "WEBSERVICE_2";
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
private WebserviceInfoDAO webserviceInfoDAO;
|
||||||
|
@Autowired
|
||||||
|
private WebserviceInfo webserviceInfo;
|
||||||
|
|
||||||
|
@Before
|
||||||
|
public void init() {
|
||||||
|
this.webserviceInfoDAO.unregister(this.webserviceInfo.getWebserviceUUID());
|
||||||
|
this.webserviceInfoDAO.register(WEBSERVICE_1, "0.0.0.1");
|
||||||
|
this.webserviceInfoDAO.register(WEBSERVICE_2, "0.0.0.1");
|
||||||
|
}
|
||||||
|
|
||||||
|
@After
|
||||||
|
public void cleanup() {
|
||||||
|
this.webserviceInfoDAO.unregister(WEBSERVICE_1);
|
||||||
|
this.webserviceInfoDAO.unregister(WEBSERVICE_2);
|
||||||
|
this.webserviceInfoDAO.register(
|
||||||
|
this.webserviceInfo.getWebserviceUUID(),
|
||||||
|
this.webserviceInfo.getLocalHostAddress());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testFistBecomeMaster() {
|
||||||
|
assertTrue(this.webserviceInfoDAO.isMaster(WEBSERVICE_1));
|
||||||
|
assertFalse(this.webserviceInfoDAO.isMaster(WEBSERVICE_2));
|
||||||
|
assertTrue(this.webserviceInfoDAO.isMaster(WEBSERVICE_1));
|
||||||
|
assertTrue(this.webserviceInfoDAO.isMaster(WEBSERVICE_1));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testUnregister_OtherBecomeMaster() {
|
||||||
|
assertTrue(this.webserviceInfoDAO.isMaster(WEBSERVICE_1));
|
||||||
|
assertTrue(this.webserviceInfoDAO.unregister(WEBSERVICE_1));
|
||||||
|
assertFalse(this.webserviceInfoDAO.isMaster(WEBSERVICE_1));
|
||||||
|
assertTrue(this.webserviceInfoDAO.isMaster(WEBSERVICE_2));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testOtherBecomeMasterAfterTimout() {
|
||||||
|
assertTrue(this.webserviceInfoDAO.isMaster(WEBSERVICE_1));
|
||||||
|
assertFalse(this.webserviceInfoDAO.isMaster(WEBSERVICE_2));
|
||||||
|
|
||||||
|
try {
|
||||||
|
Thread.sleep(5000);
|
||||||
|
} catch (final InterruptedException e) {
|
||||||
|
}
|
||||||
|
|
||||||
|
// Still not master
|
||||||
|
assertFalse(this.webserviceInfoDAO.isMaster(WEBSERVICE_2));
|
||||||
|
|
||||||
|
try {
|
||||||
|
Thread.sleep(6000);
|
||||||
|
} catch (final InterruptedException e) {
|
||||||
|
}
|
||||||
|
|
||||||
|
assertTrue(this.webserviceInfoDAO.isMaster(WEBSERVICE_2));
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -51,6 +51,8 @@ import ch.ethz.seb.sebserver.SEBServer;
|
||||||
import ch.ethz.seb.sebserver.WebSecurityConfig;
|
import ch.ethz.seb.sebserver.WebSecurityConfig;
|
||||||
import ch.ethz.seb.sebserver.gbl.api.API;
|
import ch.ethz.seb.sebserver.gbl.api.API;
|
||||||
import ch.ethz.seb.sebserver.gbl.api.JSONMapper;
|
import ch.ethz.seb.sebserver.gbl.api.JSONMapper;
|
||||||
|
import ch.ethz.seb.sebserver.webservice.WebserviceInfo;
|
||||||
|
import ch.ethz.seb.sebserver.webservice.servicelayer.dao.WebserviceInfoDAO;
|
||||||
import ch.ethz.seb.sebserver.webservice.servicelayer.sebconfig.ClientConfigService;
|
import ch.ethz.seb.sebserver.webservice.servicelayer.sebconfig.ClientConfigService;
|
||||||
import ch.ethz.seb.sebserver.webservice.weblayer.oauth.AdminAPIClientDetails;
|
import ch.ethz.seb.sebserver.webservice.weblayer.oauth.AdminAPIClientDetails;
|
||||||
import ch.ethz.seb.sebserver.webservice.weblayer.oauth.WebserviceResourceConfiguration;
|
import ch.ethz.seb.sebserver.webservice.weblayer.oauth.WebserviceResourceConfiguration;
|
||||||
|
@ -74,6 +76,10 @@ public abstract class ExamAPIIntegrationTester {
|
||||||
protected JSONMapper jsonMapper;
|
protected JSONMapper jsonMapper;
|
||||||
@Autowired
|
@Autowired
|
||||||
protected FilterChainProxy springSecurityFilterChain;
|
protected FilterChainProxy springSecurityFilterChain;
|
||||||
|
@Autowired
|
||||||
|
private WebserviceInfoDAO webserviceInfoDAO;
|
||||||
|
@Autowired
|
||||||
|
private WebserviceInfo webserviceInfo;
|
||||||
|
|
||||||
protected MockMvc mockMvc;
|
protected MockMvc mockMvc;
|
||||||
|
|
||||||
|
@ -82,6 +88,7 @@ public abstract class ExamAPIIntegrationTester {
|
||||||
|
|
||||||
@Before
|
@Before
|
||||||
public void setup() {
|
public void setup() {
|
||||||
|
this.webserviceInfoDAO.unregister(this.webserviceInfo.getWebserviceUUID());
|
||||||
this.mockMvc = MockMvcBuilders.webAppContextSetup(this.wac)
|
this.mockMvc = MockMvcBuilders.webAppContextSetup(this.wac)
|
||||||
.addFilter(this.springSecurityFilterChain).build();
|
.addFilter(this.springSecurityFilterChain).build();
|
||||||
// clear all caches before a test
|
// clear all caches before a test
|
||||||
|
|
Loading…
Reference in a new issue