commit
bce5ea7f58
16 changed files with 83 additions and 76 deletions
|
@ -46,7 +46,6 @@ public final class Exam implements GrantEntity {
|
||||||
ExamType.UNDEFINED,
|
ExamType.UNDEFINED,
|
||||||
null,
|
null,
|
||||||
null,
|
null,
|
||||||
null,
|
|
||||||
ExamStatus.FINISHED,
|
ExamStatus.FINISHED,
|
||||||
// Boolean.FALSE,
|
// Boolean.FALSE,
|
||||||
null,
|
null,
|
||||||
|
@ -104,9 +103,6 @@ public final class Exam implements GrantEntity {
|
||||||
@NotNull
|
@NotNull
|
||||||
public final ExamType type;
|
public final ExamType type;
|
||||||
|
|
||||||
@JsonProperty(EXAM.ATTR_QUIT_PASSWORD)
|
|
||||||
public final String quitPassword;
|
|
||||||
|
|
||||||
@JsonProperty(EXAM.ATTR_OWNER)
|
@JsonProperty(EXAM.ATTR_OWNER)
|
||||||
public final String owner;
|
public final String owner;
|
||||||
|
|
||||||
|
@ -138,7 +134,6 @@ public final class Exam implements GrantEntity {
|
||||||
@JsonProperty(QuizData.QUIZ_ATTR_END_TIME) final DateTime endTime,
|
@JsonProperty(QuizData.QUIZ_ATTR_END_TIME) final DateTime endTime,
|
||||||
@JsonProperty(QuizData.QUIZ_ATTR_START_URL) final String startURL,
|
@JsonProperty(QuizData.QUIZ_ATTR_START_URL) final String startURL,
|
||||||
@JsonProperty(EXAM.ATTR_TYPE) final ExamType type,
|
@JsonProperty(EXAM.ATTR_TYPE) final ExamType type,
|
||||||
@JsonProperty(EXAM.ATTR_QUIT_PASSWORD) final String quitPassword,
|
|
||||||
@JsonProperty(EXAM.ATTR_OWNER) final String owner,
|
@JsonProperty(EXAM.ATTR_OWNER) final String owner,
|
||||||
@JsonProperty(EXAM.ATTR_SUPPORTER) final Collection<String> supporter,
|
@JsonProperty(EXAM.ATTR_SUPPORTER) final Collection<String> supporter,
|
||||||
@JsonProperty(EXAM.ATTR_STATUS) final ExamStatus status,
|
@JsonProperty(EXAM.ATTR_STATUS) final ExamStatus status,
|
||||||
|
@ -156,7 +151,6 @@ public final class Exam implements GrantEntity {
|
||||||
this.endTime = endTime;
|
this.endTime = endTime;
|
||||||
this.startURL = startURL;
|
this.startURL = startURL;
|
||||||
this.type = type;
|
this.type = type;
|
||||||
this.quitPassword = quitPassword;
|
|
||||||
this.owner = owner;
|
this.owner = owner;
|
||||||
this.status = (status != null) ? status : getStatusFromDate(startTime, endTime);
|
this.status = (status != null) ? status : getStatusFromDate(startTime, endTime);
|
||||||
this.browserExamKeys = browserExamKeys;
|
this.browserExamKeys = browserExamKeys;
|
||||||
|
@ -180,7 +174,6 @@ public final class Exam implements GrantEntity {
|
||||||
this.endTime = quizData.endTime;
|
this.endTime = quizData.endTime;
|
||||||
this.startURL = quizData.startURL;
|
this.startURL = quizData.startURL;
|
||||||
this.type = mapper.getEnum(EXAM.ATTR_TYPE, ExamType.class, ExamType.UNDEFINED);
|
this.type = mapper.getEnum(EXAM.ATTR_TYPE, ExamType.class, ExamType.UNDEFINED);
|
||||||
this.quitPassword = mapper.getString(EXAM.ATTR_QUIT_PASSWORD);
|
|
||||||
this.owner = mapper.getString(EXAM.ATTR_OWNER);
|
this.owner = mapper.getString(EXAM.ATTR_OWNER);
|
||||||
this.status = mapper.getEnum(
|
this.status = mapper.getEnum(
|
||||||
EXAM.ATTR_STATUS,
|
EXAM.ATTR_STATUS,
|
||||||
|
@ -208,7 +201,6 @@ public final class Exam implements GrantEntity {
|
||||||
this.endTime = null;
|
this.endTime = null;
|
||||||
this.startURL = null;
|
this.startURL = null;
|
||||||
this.type = null;
|
this.type = null;
|
||||||
this.quitPassword = null;
|
|
||||||
this.owner = null;
|
this.owner = null;
|
||||||
this.status = (status != null) ? status : getStatusFromDate(this.startTime, this.endTime);
|
this.status = (status != null) ? status : getStatusFromDate(this.startTime, this.endTime);
|
||||||
this.browserExamKeys = null;
|
this.browserExamKeys = null;
|
||||||
|
@ -300,10 +292,6 @@ public final class Exam implements GrantEntity {
|
||||||
return this.startURL;
|
return this.startURL;
|
||||||
}
|
}
|
||||||
|
|
||||||
public String getQuitPassword() {
|
|
||||||
return this.quitPassword;
|
|
||||||
}
|
|
||||||
|
|
||||||
public ExamStatus getStatus() {
|
public ExamStatus getStatus() {
|
||||||
return this.status;
|
return this.status;
|
||||||
}
|
}
|
||||||
|
@ -339,8 +327,6 @@ public final class Exam implements GrantEntity {
|
||||||
builder.append(this.startURL);
|
builder.append(this.startURL);
|
||||||
builder.append(", type=");
|
builder.append(", type=");
|
||||||
builder.append(this.type);
|
builder.append(this.type);
|
||||||
builder.append(", quitPassword=");
|
|
||||||
builder.append(this.quitPassword);
|
|
||||||
builder.append(", owner=");
|
builder.append(", owner=");
|
||||||
builder.append(this.owner);
|
builder.append(this.owner);
|
||||||
builder.append(", supporter=");
|
builder.append(", supporter=");
|
||||||
|
|
|
@ -36,7 +36,7 @@ public final class Institution implements GrantEntity, Activatable {
|
||||||
public final String name;
|
public final String name;
|
||||||
|
|
||||||
@JsonProperty(INSTITUTION.ATTR_URL_SUFFIX)
|
@JsonProperty(INSTITUTION.ATTR_URL_SUFFIX)
|
||||||
@Pattern(regexp = "(^$|.{3,255})", message = "institution:urlSuffix:size:3:255:${validatedValue}")
|
@Pattern(regexp = "(^$|.{3,45})", message = "institution:urlSuffix:size:3:45:${validatedValue}")
|
||||||
public final String urlSuffix;
|
public final String urlSuffix;
|
||||||
|
|
||||||
@JsonProperty(INSTITUTION.ATTR_LOGO_IMAGE)
|
@JsonProperty(INSTITUTION.ATTR_LOGO_IMAGE)
|
||||||
|
|
|
@ -186,7 +186,7 @@ public class LmsSetupList implements TemplateComposer {
|
||||||
action -> LmsSetupForm.testLmsSetup(action, null, restService)),
|
action -> LmsSetupForm.testLmsSetup(action, null, restService)),
|
||||||
EMPTY_SELECTION_TEXT_KEY)
|
EMPTY_SELECTION_TEXT_KEY)
|
||||||
.withConfirm(this.pageService.confirmDeactivation(table))
|
.withConfirm(this.pageService.confirmDeactivation(table))
|
||||||
.publishIf(() -> userGrant.im() && table.hasAnyContent(), false);
|
.publishIf(() -> userGrant.iw() && table.hasAnyContent(), false);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -137,11 +137,11 @@ public class MonitoringRunningExam implements TemplateComposer {
|
||||||
|
|
||||||
clientTable
|
clientTable
|
||||||
.withDefaultAction(
|
.withDefaultAction(
|
||||||
actionBuilder
|
actionBuilder
|
||||||
.newAction(ActionDefinition.MONITOR_EXAM_CLIENT_CONNECTION)
|
.newAction(ActionDefinition.MONITOR_EXAM_CLIENT_CONNECTION)
|
||||||
.withParentEntityKey(entityKey)
|
.withParentEntityKey(entityKey)
|
||||||
.create(),
|
.create(),
|
||||||
this.pageService)
|
this.pageService)
|
||||||
.withSelectionListener(this.pageService.getSelectionPublisher(
|
.withSelectionListener(this.pageService.getSelectionPublisher(
|
||||||
pageContext,
|
pageContext,
|
||||||
ActionDefinition.MONITOR_EXAM_CLIENT_CONNECTION,
|
ActionDefinition.MONITOR_EXAM_CLIENT_CONNECTION,
|
||||||
|
@ -324,6 +324,7 @@ public class MonitoringRunningExam implements TemplateComposer {
|
||||||
action.pageContext());
|
action.pageContext());
|
||||||
|
|
||||||
clientTable.removeSelection();
|
clientTable.removeSelection();
|
||||||
|
clientTable.forceUpdateAll();
|
||||||
return action;
|
return action;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -340,6 +341,7 @@ public class MonitoringRunningExam implements TemplateComposer {
|
||||||
action.pageContext());
|
action.pageContext());
|
||||||
|
|
||||||
clientTable.removeSelection();
|
clientTable.removeSelection();
|
||||||
|
clientTable.forceUpdateAll();
|
||||||
return action;
|
return action;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -8,17 +8,10 @@
|
||||||
|
|
||||||
package ch.ethz.seb.sebserver.gui.content.action;
|
package ch.ethz.seb.sebserver.gui.content.action;
|
||||||
|
|
||||||
import ch.ethz.seb.sebserver.gui.service.i18n.LocTextKey;
|
import java.util.ArrayList;
|
||||||
import ch.ethz.seb.sebserver.gui.service.i18n.PolyglotPageService;
|
import java.util.HashMap;
|
||||||
import ch.ethz.seb.sebserver.gui.service.page.PageContext;
|
import java.util.Map;
|
||||||
import ch.ethz.seb.sebserver.gui.service.page.PageService;
|
|
||||||
import ch.ethz.seb.sebserver.gui.service.page.TemplateComposer;
|
|
||||||
import ch.ethz.seb.sebserver.gui.service.page.event.ActionActivationEventListener;
|
|
||||||
import ch.ethz.seb.sebserver.gui.service.page.event.ActionPublishEventListener;
|
|
||||||
import ch.ethz.seb.sebserver.gui.service.page.event.PageEventListener;
|
|
||||||
import ch.ethz.seb.sebserver.gui.service.page.impl.PageAction;
|
|
||||||
import ch.ethz.seb.sebserver.gui.widget.WidgetFactory;
|
|
||||||
import ch.ethz.seb.sebserver.gui.widget.WidgetFactory.CustomVariant;
|
|
||||||
import org.apache.commons.lang3.StringUtils;
|
import org.apache.commons.lang3.StringUtils;
|
||||||
import org.eclipse.rap.rwt.RWT;
|
import org.eclipse.rap.rwt.RWT;
|
||||||
import org.eclipse.rap.rwt.template.ImageCell;
|
import org.eclipse.rap.rwt.template.ImageCell;
|
||||||
|
@ -38,9 +31,17 @@ import org.eclipse.swt.widgets.TreeItem;
|
||||||
import org.springframework.context.annotation.Lazy;
|
import org.springframework.context.annotation.Lazy;
|
||||||
import org.springframework.stereotype.Component;
|
import org.springframework.stereotype.Component;
|
||||||
|
|
||||||
import java.util.ArrayList;
|
import ch.ethz.seb.sebserver.gui.service.i18n.LocTextKey;
|
||||||
import java.util.HashMap;
|
import ch.ethz.seb.sebserver.gui.service.i18n.PolyglotPageService;
|
||||||
import java.util.Map;
|
import ch.ethz.seb.sebserver.gui.service.page.PageContext;
|
||||||
|
import ch.ethz.seb.sebserver.gui.service.page.PageService;
|
||||||
|
import ch.ethz.seb.sebserver.gui.service.page.TemplateComposer;
|
||||||
|
import ch.ethz.seb.sebserver.gui.service.page.event.ActionActivationEventListener;
|
||||||
|
import ch.ethz.seb.sebserver.gui.service.page.event.ActionPublishEventListener;
|
||||||
|
import ch.ethz.seb.sebserver.gui.service.page.event.PageEventListener;
|
||||||
|
import ch.ethz.seb.sebserver.gui.service.page.impl.PageAction;
|
||||||
|
import ch.ethz.seb.sebserver.gui.widget.WidgetFactory;
|
||||||
|
import ch.ethz.seb.sebserver.gui.widget.WidgetFactory.CustomVariant;
|
||||||
|
|
||||||
@Lazy
|
@Lazy
|
||||||
@Component
|
@Component
|
||||||
|
@ -52,8 +53,6 @@ public class ActionPane implements TemplateComposer {
|
||||||
private final PageService pageService;
|
private final PageService pageService;
|
||||||
private final WidgetFactory widgetFactory;
|
private final WidgetFactory widgetFactory;
|
||||||
|
|
||||||
private final Map<String, Tree> actionTrees = new HashMap<>();
|
|
||||||
|
|
||||||
protected ActionPane(final PageService pageService) {
|
protected ActionPane(final PageService pageService) {
|
||||||
this.pageService = pageService;
|
this.pageService = pageService;
|
||||||
this.widgetFactory = pageService.getWidgetFactory();
|
this.widgetFactory = pageService.getWidgetFactory();
|
||||||
|
@ -61,7 +60,7 @@ public class ActionPane implements TemplateComposer {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void compose(final PageContext pageContext) {
|
public void compose(final PageContext pageContext) {
|
||||||
|
final Map<String, Tree> actionTrees = new HashMap<>();
|
||||||
final Label label = this.widgetFactory.labelLocalized(
|
final Label label = this.widgetFactory.labelLocalized(
|
||||||
pageContext.getParent(),
|
pageContext.getParent(),
|
||||||
CustomVariant.TEXT_H2,
|
CustomVariant.TEXT_H2,
|
||||||
|
@ -79,7 +78,7 @@ public class ActionPane implements TemplateComposer {
|
||||||
PageEventListener.LISTENER_ATTRIBUTE_KEY,
|
PageEventListener.LISTENER_ATTRIBUTE_KEY,
|
||||||
(ActionPublishEventListener) event -> {
|
(ActionPublishEventListener) event -> {
|
||||||
final Composite parent = pageContext.getParent();
|
final Composite parent = pageContext.getParent();
|
||||||
final Tree treeForGroup = getTreeForGroup(parent, event.action.definition, true);
|
final Tree treeForGroup = getTreeForGroup(actionTrees, parent, event.action.definition, true);
|
||||||
final TreeItem actionItem = ActionPane.this.widgetFactory.treeItemLocalized(
|
final TreeItem actionItem = ActionPane.this.widgetFactory.treeItemLocalized(
|
||||||
treeForGroup,
|
treeForGroup,
|
||||||
event.action.definition.title);
|
event.action.definition.title);
|
||||||
|
@ -110,7 +109,7 @@ public class ActionPane implements TemplateComposer {
|
||||||
(ActionActivationEventListener) event -> {
|
(ActionActivationEventListener) event -> {
|
||||||
final Composite parent = pageContext.getParent();
|
final Composite parent = pageContext.getParent();
|
||||||
for (final ActionDefinition ad : event.actions) {
|
for (final ActionDefinition ad : event.actions) {
|
||||||
final TreeItem actionItem = findAction(parent, ad);
|
final TreeItem actionItem = findAction(actionTrees, parent, ad);
|
||||||
if (actionItem == null) {
|
if (actionItem == null) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
@ -128,7 +127,7 @@ public class ActionPane implements TemplateComposer {
|
||||||
}
|
}
|
||||||
|
|
||||||
if (event.decoration != null) {
|
if (event.decoration != null) {
|
||||||
final TreeItem actionItemToDecorate = findAction(parent, event.decoration._1);
|
final TreeItem actionItemToDecorate = findAction(actionTrees, parent, event.decoration._1);
|
||||||
if (actionItemToDecorate != null && event.decoration._2 != null) {
|
if (actionItemToDecorate != null && event.decoration._2 != null) {
|
||||||
actionItemToDecorate.setImage(0,
|
actionItemToDecorate.setImage(0,
|
||||||
event.decoration._2.icon.getImage(parent.getDisplay()));
|
event.decoration._2.icon.getImage(parent.getDisplay()));
|
||||||
|
@ -140,8 +139,11 @@ public class ActionPane implements TemplateComposer {
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
private TreeItem findAction(final Composite parent, final ActionDefinition actionDefinition) {
|
private TreeItem findAction(
|
||||||
final Tree treeForGroup = getTreeForGroup(parent, actionDefinition, false);
|
final Map<String, Tree> actionTrees,
|
||||||
|
final Composite parent,
|
||||||
|
final ActionDefinition actionDefinition) {
|
||||||
|
final Tree treeForGroup = getTreeForGroup(actionTrees, parent, actionDefinition, false);
|
||||||
if (treeForGroup == null) {
|
if (treeForGroup == null) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
@ -166,19 +168,20 @@ public class ActionPane implements TemplateComposer {
|
||||||
}
|
}
|
||||||
|
|
||||||
private Tree getTreeForGroup(
|
private Tree getTreeForGroup(
|
||||||
|
final Map<String, Tree> actionTrees,
|
||||||
final Composite parent,
|
final Composite parent,
|
||||||
final ActionDefinition actionDefinition,
|
final ActionDefinition actionDefinition,
|
||||||
boolean create) {
|
final boolean create) {
|
||||||
|
|
||||||
clearDisposedTrees();
|
clearDisposedTrees(actionTrees);
|
||||||
|
|
||||||
final ActionCategory category = actionDefinition.category;
|
final ActionCategory category = actionDefinition.category;
|
||||||
if (!this.actionTrees.containsKey(category.name()) && create) {
|
if (!actionTrees.containsKey(category.name()) && create) {
|
||||||
final Tree actionTree = createActionTree(parent, actionDefinition.category);
|
final Tree actionTree = createActionTree(parent, actionDefinition.category);
|
||||||
this.actionTrees.put(category.name(), actionTree);
|
actionTrees.put(category.name(), actionTree);
|
||||||
}
|
}
|
||||||
|
|
||||||
return this.actionTrees.get(category.name());
|
return actionTrees.get(category.name());
|
||||||
}
|
}
|
||||||
|
|
||||||
private Tree createActionTree(final Composite parent, final ActionCategory category) {
|
private Tree createActionTree(final Composite parent, final ActionCategory category) {
|
||||||
|
@ -257,19 +260,19 @@ public class ActionPane implements TemplateComposer {
|
||||||
return actions;
|
return actions;
|
||||||
}
|
}
|
||||||
|
|
||||||
private void clearDisposedTrees() {
|
private void clearDisposedTrees(final Map<String, Tree> actionTrees) {
|
||||||
new ArrayList<>(this.actionTrees.entrySet())
|
new ArrayList<>(actionTrees.entrySet())
|
||||||
.forEach(entry -> {
|
.forEach(entry -> {
|
||||||
final Control c = entry.getValue();
|
final Control c = entry.getValue();
|
||||||
// of tree is already disposed.. remove it
|
// of tree is already disposed.. remove it
|
||||||
if (c.isDisposed()) {
|
if (c.isDisposed()) {
|
||||||
this.actionTrees.remove(entry.getKey());
|
actionTrees.remove(entry.getKey());
|
||||||
}
|
}
|
||||||
// check access from current thread
|
// check access from current thread
|
||||||
try {
|
try {
|
||||||
c.getBounds();
|
c.getBounds();
|
||||||
} catch (final Exception e) {
|
} catch (final Exception e) {
|
||||||
this.actionTrees.remove(entry.getKey());
|
actionTrees.remove(entry.getKey());
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
|
@ -191,8 +191,8 @@ public abstract class RestCall<T> {
|
||||||
}
|
}
|
||||||
|
|
||||||
log.debug(
|
log.debug(
|
||||||
"Webservice answered with well defined error- or validation-failure-response: ",
|
"Webservice answered with well defined error- or validation-failure-response: {}",
|
||||||
restCallError);
|
restCallError.toString());
|
||||||
|
|
||||||
return Result.ofError(restCallError);
|
return Result.ofError(restCallError);
|
||||||
}
|
}
|
||||||
|
|
|
@ -106,6 +106,8 @@ public final class ClientConnectionTable {
|
||||||
private final Color darkFontColor;
|
private final Color darkFontColor;
|
||||||
private final Color lightFontColor;
|
private final Color lightFontColor;
|
||||||
|
|
||||||
|
private boolean forceUpdateAll = false;
|
||||||
|
|
||||||
public ClientConnectionTable(
|
public ClientConnectionTable(
|
||||||
final PageService pageService,
|
final PageService pageService,
|
||||||
final Composite tableRoot,
|
final Composite tableRoot,
|
||||||
|
@ -289,13 +291,17 @@ public final class ClientConnectionTable {
|
||||||
updatableTableItem.connectionData.clientConnection.connectionToken);
|
updatableTableItem.connectionData.clientConnection.connectionToken);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void forceUpdateAll() {
|
||||||
|
this.forceUpdateAll = true;
|
||||||
|
}
|
||||||
|
|
||||||
public void updateValues() {
|
public void updateValues() {
|
||||||
if (this.statusFilterChanged) {
|
if (this.statusFilterChanged) {
|
||||||
this.toDelete.clear();
|
this.toDelete.clear();
|
||||||
this.toDelete.addAll(this.tableMapping.keySet());
|
this.toDelete.addAll(this.tableMapping.keySet());
|
||||||
}
|
}
|
||||||
this.restCallBuilder
|
this.restCallBuilder
|
||||||
.withHeader(API.EXAM_MONITORING_STATE_FILTER, this.statusFilterParam)
|
.withHeader(API.EXAM_MONITORING_STATE_FILTER, (this.forceUpdateAll) ? "" : this.statusFilterParam)
|
||||||
.call()
|
.call()
|
||||||
.get(error -> {
|
.get(error -> {
|
||||||
log.error("Error poll connection data: ", error);
|
log.error("Error poll connection data: ", error);
|
||||||
|
@ -321,6 +327,8 @@ public final class ClientConnectionTable {
|
||||||
});
|
});
|
||||||
this.statusFilterChanged = false;
|
this.statusFilterChanged = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
this.forceUpdateAll = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void updateGUI() {
|
public void updateGUI() {
|
||||||
|
@ -554,7 +562,7 @@ public final class ClientConnectionTable {
|
||||||
if (getClass() != obj.getClass())
|
if (getClass() != obj.getClass())
|
||||||
return false;
|
return false;
|
||||||
final UpdatableTableItem other = (UpdatableTableItem) obj;
|
final UpdatableTableItem other = (UpdatableTableItem) obj;
|
||||||
if (!getOuterType().equals(other.getOuterType()))
|
if (getOuterType() != other.getOuterType())
|
||||||
return false;
|
return false;
|
||||||
return compareTo(other) == 0;
|
return compareTo(other) == 0;
|
||||||
}
|
}
|
||||||
|
|
|
@ -11,6 +11,7 @@ package ch.ethz.seb.sebserver.webservice;
|
||||||
import org.cryptonode.jncryptor.AES256JNCryptor;
|
import org.cryptonode.jncryptor.AES256JNCryptor;
|
||||||
import org.cryptonode.jncryptor.JNCryptor;
|
import org.cryptonode.jncryptor.JNCryptor;
|
||||||
import org.flywaydb.core.Flyway;
|
import org.flywaydb.core.Flyway;
|
||||||
|
import org.springframework.beans.factory.annotation.Value;
|
||||||
import org.springframework.boot.autoconfigure.flyway.FlywayMigrationStrategy;
|
import org.springframework.boot.autoconfigure.flyway.FlywayMigrationStrategy;
|
||||||
import org.springframework.context.annotation.Bean;
|
import org.springframework.context.annotation.Bean;
|
||||||
import org.springframework.context.annotation.Configuration;
|
import org.springframework.context.annotation.Configuration;
|
||||||
|
@ -24,6 +25,9 @@ import ch.ethz.seb.sebserver.gbl.profile.WebServiceProfile;
|
||||||
@WebServiceProfile
|
@WebServiceProfile
|
||||||
public class WebserviceConfig {
|
public class WebserviceConfig {
|
||||||
|
|
||||||
|
@Value("${sebserver.webservice.clean-db-on-startup:false}")
|
||||||
|
boolean cleanDBOnStartup;
|
||||||
|
|
||||||
@Lazy
|
@Lazy
|
||||||
@Bean
|
@Bean
|
||||||
public JNCryptor jnCryptor() {
|
public JNCryptor jnCryptor() {
|
||||||
|
@ -42,7 +46,9 @@ public class WebserviceConfig {
|
||||||
final FlywayMigrationStrategy strategy = new FlywayMigrationStrategy() {
|
final FlywayMigrationStrategy strategy = new FlywayMigrationStrategy() {
|
||||||
@Override
|
@Override
|
||||||
public void migrate(final Flyway flyway) {
|
public void migrate(final Flyway flyway) {
|
||||||
flyway.clean();
|
if (WebserviceConfig.this.cleanDBOnStartup) {
|
||||||
|
flyway.clean();
|
||||||
|
}
|
||||||
flyway.migrate();
|
flyway.migrate();
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
|
@ -53,7 +53,15 @@ public interface PaginationService {
|
||||||
|
|
||||||
/** Get a Page of specified domain models from given pagination attributes within collection supplier delegate.
|
/** Get a Page of specified domain models from given pagination attributes within collection supplier delegate.
|
||||||
*
|
*
|
||||||
*
|
* NOTE: Paging always depends on SQL level. It depends on the collection given by the SQL select statement
|
||||||
|
* that is executed within MyBatis by using the MyBatis page service.
|
||||||
|
* Be aware that if the delegate that is given here applies an additional filter to the filtering done
|
||||||
|
* on SQL level, this will lead to paging with not fully filled pages or even to empty pages if the filter
|
||||||
|
* filters a lot of the entries given by the SQL statement away.
|
||||||
|
* So we recommend to apply as much of the filtering as possible on the SQL level and only if necessary and
|
||||||
|
* not avoidable, apply a additional filter on software-level that eventually filter one or two entities
|
||||||
|
* for a page.
|
||||||
|
*
|
||||||
* @param pageNumber the current page number
|
* @param pageNumber the current page number
|
||||||
* @param pageSize the (full) size of the page
|
* @param pageSize the (full) size of the page
|
||||||
* @param sort the name of the sort column with a leading '-' for descending sort order
|
* @param sort the name of the sort column with a leading '-' for descending sort order
|
||||||
|
|
|
@ -224,7 +224,7 @@ public class ExamDAOImpl implements ExamDAO {
|
||||||
(exam.type != null)
|
(exam.type != null)
|
||||||
? exam.type.name()
|
? exam.type.name()
|
||||||
: null,
|
: null,
|
||||||
exam.quitPassword,
|
null,
|
||||||
exam.browserExamKeys,
|
exam.browserExamKeys,
|
||||||
(exam.status != null)
|
(exam.status != null)
|
||||||
? exam.status.name()
|
? exam.status.name()
|
||||||
|
@ -769,11 +769,9 @@ public class ExamDAOImpl implements ExamDAO {
|
||||||
(quizData != null) ? quizData.endTime : null,
|
(quizData != null) ? quizData.endTime : null,
|
||||||
(quizData != null) ? quizData.startURL : Constants.EMPTY_NOTE,
|
(quizData != null) ? quizData.startURL : Constants.EMPTY_NOTE,
|
||||||
ExamType.valueOf(record.getType()),
|
ExamType.valueOf(record.getType()),
|
||||||
record.getQuitPassword(),
|
|
||||||
record.getOwner(),
|
record.getOwner(),
|
||||||
supporter,
|
supporter,
|
||||||
status,
|
status,
|
||||||
// BooleanUtils.toBooleanObject((quizData != null) ? record.getLmsSebRestriction() : null),
|
|
||||||
record.getBrowserKeys(),
|
record.getBrowserKeys(),
|
||||||
BooleanUtils.toBooleanObject((quizData != null) ? record.getActive() : null),
|
BooleanUtils.toBooleanObject((quizData != null) ? record.getActive() : null),
|
||||||
record.getLastupdate());
|
record.getLastupdate());
|
||||||
|
|
|
@ -294,7 +294,7 @@ public class UserActivityLogDAOImpl implements UserActivityLogDAO {
|
||||||
|
|
||||||
return all(
|
return all(
|
||||||
filterMap.getInstitutionId(),
|
filterMap.getInstitutionId(),
|
||||||
filterMap.getString(UserActivityLog.FILTER_ATTR_USER_NAME),
|
filterMap.getSQLWildcard(UserActivityLog.FILTER_ATTR_USER_NAME),
|
||||||
filterMap.getUserLogFrom(),
|
filterMap.getUserLogFrom(),
|
||||||
filterMap.getUserLofTo(),
|
filterMap.getUserLofTo(),
|
||||||
filterMap.getString(UserActivityLog.FILTER_ATTR_ACTIVITY_TYPES),
|
filterMap.getString(UserActivityLog.FILTER_ATTR_ACTIVITY_TYPES),
|
||||||
|
@ -321,14 +321,6 @@ public class UserActivityLogDAOImpl implements UserActivityLogDAO {
|
||||||
? Arrays.asList(StringUtils.split(entityTypes, Constants.LIST_SEPARATOR))
|
? Arrays.asList(StringUtils.split(entityTypes, Constants.LIST_SEPARATOR))
|
||||||
: null;
|
: null;
|
||||||
|
|
||||||
Predicate<UserActivityLog> _predicate = (predicate != null)
|
|
||||||
? predicate
|
|
||||||
: model -> true;
|
|
||||||
|
|
||||||
if (StringUtils.isNotBlank(userName)) {
|
|
||||||
_predicate = _predicate.and(model -> model.getUsername().contains(userName));
|
|
||||||
}
|
|
||||||
|
|
||||||
final List<UserActivityLogRecord> records = this.userLogRecordMapper
|
final List<UserActivityLogRecord> records = this.userLogRecordMapper
|
||||||
.selectByExample()
|
.selectByExample()
|
||||||
.leftJoin(UserRecordDynamicSqlSupport.userRecord)
|
.leftJoin(UserRecordDynamicSqlSupport.userRecord)
|
||||||
|
@ -338,6 +330,9 @@ public class UserActivityLogDAOImpl implements UserActivityLogDAO {
|
||||||
.where(
|
.where(
|
||||||
UserRecordDynamicSqlSupport.institutionId,
|
UserRecordDynamicSqlSupport.institutionId,
|
||||||
SqlBuilder.isEqualToWhenPresent(institutionId))
|
SqlBuilder.isEqualToWhenPresent(institutionId))
|
||||||
|
.and(
|
||||||
|
UserRecordDynamicSqlSupport.username,
|
||||||
|
SqlBuilder.isLikeWhenPresent(userName))
|
||||||
.and(
|
.and(
|
||||||
UserActivityLogRecordDynamicSqlSupport.timestamp,
|
UserActivityLogRecordDynamicSqlSupport.timestamp,
|
||||||
SqlBuilder.isGreaterThanOrEqualToWhenPresent(from))
|
SqlBuilder.isGreaterThanOrEqualToWhenPresent(from))
|
||||||
|
@ -355,7 +350,7 @@ public class UserActivityLogDAOImpl implements UserActivityLogDAO {
|
||||||
|
|
||||||
return this.toDomainModel(institutionId, records)
|
return this.toDomainModel(institutionId, records)
|
||||||
.stream()
|
.stream()
|
||||||
.filter(_predicate)
|
.filter(predicate)
|
||||||
.collect(Collectors.toList());
|
.collect(Collectors.toList());
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
|
@ -131,7 +131,7 @@ public class SebRestrictionServiceImpl implements SebRestrictionService {
|
||||||
final Collection<String> browserExamKeys = sebRestriction.getBrowserExamKeys();
|
final Collection<String> browserExamKeys = sebRestriction.getBrowserExamKeys();
|
||||||
final Exam newExam = new Exam(
|
final Exam newExam = new Exam(
|
||||||
exam.id,
|
exam.id,
|
||||||
null, null, null, null, null, null, null, null, null, null, null,
|
null, null, null, null, null, null, null, null, null, null,
|
||||||
exam.supporter,
|
exam.supporter,
|
||||||
exam.status,
|
exam.status,
|
||||||
(browserExamKeys != null && !browserExamKeys.isEmpty())
|
(browserExamKeys != null && !browserExamKeys.isEmpty())
|
||||||
|
|
|
@ -10,7 +10,7 @@ spring.datasource.url=jdbc:mariadb://localhost:3306/SEBServer?createDatabaseIfNo
|
||||||
spring.datasource.driver-class-name=org.mariadb.jdbc.Driver
|
spring.datasource.driver-class-name=org.mariadb.jdbc.Driver
|
||||||
spring.flyway.enabled=true
|
spring.flyway.enabled=true
|
||||||
spring.flyway.locations=classpath:config/sql/base,classpath:config/sql/dev
|
spring.flyway.locations=classpath:config/sql/base,classpath:config/sql/dev
|
||||||
spring.flyway.baselineOnMigrate=true
|
spring.flyway.cleanDisabled=false
|
||||||
spring.datasource.hikari.initializationFailTimeout=30000
|
spring.datasource.hikari.initializationFailTimeout=30000
|
||||||
spring.datasource.hikari.connectionTimeout=30000
|
spring.datasource.hikari.connectionTimeout=30000
|
||||||
spring.datasource.hikari.idleTimeout=600000
|
spring.datasource.hikari.idleTimeout=600000
|
||||||
|
@ -20,6 +20,8 @@ sebserver.http.client.connect-timeout=15000
|
||||||
sebserver.http.client.connection-request-timeout=10000
|
sebserver.http.client.connection-request-timeout=10000
|
||||||
sebserver.http.client.read-timeout=20000
|
sebserver.http.client.read-timeout=20000
|
||||||
|
|
||||||
|
sebserver.webservice.clean-db-on-startup=false
|
||||||
|
|
||||||
# webservice configuration
|
# webservice configuration
|
||||||
sebserver.init.adminaccount.gen-on-init=false
|
sebserver.init.adminaccount.gen-on-init=false
|
||||||
sebserver.webservice.distributed=false
|
sebserver.webservice.distributed=false
|
||||||
|
|
|
@ -72,6 +72,7 @@ spring.datasource.initialization-mode=always
|
||||||
spring.datasource.url=jdbc:mariadb://${datastore.mariadb.server.address}:${datastore.mariadb.server.port}/SEBServer?useSSL=false&createDatabaseIfNotExist=true
|
spring.datasource.url=jdbc:mariadb://${datastore.mariadb.server.address}:${datastore.mariadb.server.port}/SEBServer?useSSL=false&createDatabaseIfNotExist=true
|
||||||
spring.flyway.enabled=true
|
spring.flyway.enabled=true
|
||||||
spring.flyway.locations=classpath:config/sql/base
|
spring.flyway.locations=classpath:config/sql/base
|
||||||
|
spring.flyway.cleanDisabled=true
|
||||||
spring.datasource.driver-class-name=org.mariadb.jdbc.Driver
|
spring.datasource.driver-class-name=org.mariadb.jdbc.Driver
|
||||||
spring.datasource.hikari.initializationFailTimeout=3000
|
spring.datasource.hikari.initializationFailTimeout=3000
|
||||||
spring.datasource.hikari.connectionTimeout=30000
|
spring.datasource.hikari.connectionTimeout=30000
|
||||||
|
|
|
@ -806,7 +806,7 @@ public class UseCasesIntegrationTest extends GuiIntegrationTest {
|
||||||
newExam.endTime,
|
newExam.endTime,
|
||||||
newExam.startURL,
|
newExam.startURL,
|
||||||
ExamType.MANAGED,
|
ExamType.MANAGED,
|
||||||
null, null,
|
null,
|
||||||
Utils.immutableCollectionOf(userId),
|
Utils.immutableCollectionOf(userId),
|
||||||
ExamStatus.RUNNING,
|
ExamStatus.RUNNING,
|
||||||
null,
|
null,
|
||||||
|
|
|
@ -61,7 +61,6 @@ public class ExamAPITest extends AdministrationAPIIntegrationTester {
|
||||||
exam.endTime,
|
exam.endTime,
|
||||||
exam.startURL,
|
exam.startURL,
|
||||||
exam.type,
|
exam.type,
|
||||||
exam.quitPassword,
|
|
||||||
exam.owner,
|
exam.owner,
|
||||||
Arrays.asList("user5"),
|
Arrays.asList("user5"),
|
||||||
null,
|
null,
|
||||||
|
@ -92,7 +91,6 @@ public class ExamAPITest extends AdministrationAPIIntegrationTester {
|
||||||
exam.endTime,
|
exam.endTime,
|
||||||
exam.startURL,
|
exam.startURL,
|
||||||
exam.type,
|
exam.type,
|
||||||
exam.quitPassword,
|
|
||||||
exam.owner,
|
exam.owner,
|
||||||
Arrays.asList("user2"),
|
Arrays.asList("user2"),
|
||||||
null,
|
null,
|
||||||
|
|
Loading…
Reference in a new issue