prepare for installation

This commit is contained in:
anhefti 2019-12-11 11:02:31 +01:00
parent 4023e0ac4d
commit 25bd3a1a56
13 changed files with 180 additions and 175 deletions

View file

@ -149,7 +149,7 @@ public class ResourceService {
final List<Tuple<String>> result = new ArrayList<>();
result.add(new Tuple<>(Constants.TRUE_STRING, this.i18nSupport.getText("sebserver.overall.status.active")));
result.add(new Tuple<>(Constants.FALSE_STRING, this.i18nSupport.getText("sebserver.overall.status.inactive")));
result.add(new Tuple<>(StringUtils.EMPTY, StringUtils.EMPTY));
result.add(new Tuple<>(StringUtils.EMPTY, this.i18nSupport.getText("sebserver.overall.status.all")));
return result;
}

View file

@ -56,7 +56,7 @@ public class WebserviceInfo {
private final String serverURLPrefix;
private final boolean isDistributed;
private Map<String, String> externalAddressAlias;
private Map<String, String> lmsExternalAddressAlias;
public WebserviceInfo(final Environment environment) {
this.sebServerVersion = environment.getRequiredProperty(VERSION_KEY);
@ -93,13 +93,13 @@ public class WebserviceInfo {
StringUtils.split(alias, Constants.FORM_URL_ENCODED_NAME_VALUE_SEPARATOR);
mapping.put(nameValue[0], nameValue[1]);
}
this.externalAddressAlias = Collections.unmodifiableMap(mapping);
this.lmsExternalAddressAlias = Collections.unmodifiableMap(mapping);
} catch (final Exception e) {
log.error("Failed to parse sebserver.webservice.lms.address.alias: ", e);
this.externalAddressAlias = Collections.emptyMap();
this.lmsExternalAddressAlias = Collections.emptyMap();
}
} else {
this.externalAddressAlias = Collections.emptyMap();
this.lmsExternalAddressAlias = Collections.emptyMap();
}
}
@ -177,12 +177,12 @@ public class WebserviceInfo {
return this.isDistributed;
}
public Map<String, String> getExternalAddressAlias() {
return this.externalAddressAlias;
public Map<String, String> getLmsExternalAddressAlias() {
return this.lmsExternalAddressAlias;
}
public String getExternalAddressAlias(final String internalAddress) {
return this.externalAddressAlias
public String getLmsExternalAddressAlias(final String internalAddress) {
return this.lmsExternalAddressAlias
.entrySet()
.stream()
.filter(entry -> internalAddress.contains(entry.getKey()))
@ -212,8 +212,8 @@ public class WebserviceInfo {
builder.append(this.serverURLPrefix);
builder.append(", isDistributed=");
builder.append(this.isDistributed);
builder.append(", externalAddressAlias=");
builder.append(this.externalAddressAlias);
builder.append(", lmsExternalAddressAlias=");
builder.append(this.lmsExternalAddressAlias);
builder.append("]");
return builder.toString();
}

View file

@ -17,45 +17,66 @@ import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.boot.autoconfigure.jdbc.DataSourceAutoConfiguration;
import org.springframework.boot.context.event.ApplicationReadyEvent;
import org.springframework.context.ApplicationEventPublisher;
import org.springframework.context.ApplicationListener;
import org.springframework.context.annotation.Import;
import org.springframework.core.env.Environment;
import org.springframework.stereotype.Component;
import ch.ethz.seb.sebserver.gbl.profile.WebServiceProfile;
import ch.ethz.seb.sebserver.webservice.servicelayer.session.impl.EventHandlingInit;
@Component
@WebServiceProfile
@Import(DataSourceAutoConfiguration.class)
public class WebserviceInit implements ApplicationListener<ApplicationReadyEvent> {
private static final Logger log = LoggerFactory.getLogger(WebserviceInit.class);
static final Logger INIT_LOGGER = LoggerFactory.getLogger("SEB SERVER INIT");
private final Environment environment;
private final WebserviceInfo webserviceInfo;
private final AdminUserInitializer adminUserInitializer;
private final ApplicationEventPublisher applicationEventPublisher;
protected WebserviceInit(
final Environment environment,
final WebserviceInfo webserviceInfo,
final AdminUserInitializer adminUserInitializer) {
final AdminUserInitializer adminUserInitializer,
final ApplicationEventPublisher applicationEventPublisher) {
this.environment = environment;
this.webserviceInfo = webserviceInfo;
this.adminUserInitializer = adminUserInitializer;
this.applicationEventPublisher = applicationEventPublisher;
}
@Override
public void onApplicationEvent(final ApplicationReadyEvent event) {
log.info("Initialize SEB-Server Web-Service Component");
INIT_LOGGER.info("----> ___ ___ ___ ___ ");
INIT_LOGGER.info("----> / __|| __|| _ ) / __| ___ _ _ __ __ ___ _ _ ");
INIT_LOGGER.info("----> \\__ \\| _| | _ \\ \\__ \\/ -_)| '_|\\ V // -_)| '_|");
INIT_LOGGER.info("----> |___/|___||___/ |___/\\___||_| \\_/ \\___||_| ");
INIT_LOGGER.info("---->");
INIT_LOGGER.info("----> Starting up...");
INIT_LOGGER.info("----> ");
INIT_LOGGER.info("----> Init Databse with flyway...");
INIT_LOGGER.info("----> TODO ");
// TODO integration of Flyway for database initialization and migration: https://flywaydb.org
// see also https://flywaydb.org/getstarted/firststeps/api
INIT_LOGGER.info("----> ");
INIT_LOGGER.info("----> Init SEB Server Administrator account if needed...");
// Create an initial admin account if requested and not already in the data-base
this.adminUserInitializer.initAdminAccount();
INIT_LOGGER.info("----> ");
INIT_LOGGER.info("----> Start Services...");
INIT_LOGGER.info("----> ");
this.applicationEventPublisher.publishEvent(new EventHandlingInit(this));
INIT_LOGGER.info("----> ");
INIT_LOGGER.info("----> SEB Server successfully started up!");
INIT_LOGGER.info("---->");
INIT_LOGGER.info("----> Version: {}", this.webserviceInfo.getSebServerVersion());
@ -70,23 +91,23 @@ public class WebserviceInit implements ApplicationListener<ApplicationReadyEvent
INIT_LOGGER.info("----> Remote-Host address: {}", InetAddress.getLoopbackAddress().getHostAddress());
INIT_LOGGER.info("----> Remote-Host name: {}", InetAddress.getLoopbackAddress().getHostName());
} catch (final UnknownHostException e) {
log.error("Unknown Host: ", e);
INIT_LOGGER.error("Unknown Host: ", e);
}
INIT_LOGGER.info("---->");
INIT_LOGGER.info("----> External-Host URL: {}", this.webserviceInfo.getExternalServerURL());
INIT_LOGGER.info("----> LMS-External-Address-Alias: {}", this.webserviceInfo.getLmsExternalAddressAlias());
INIT_LOGGER.info("---->");
INIT_LOGGER.info("----> HTTP Scheme {}", this.webserviceInfo.getHttpScheme());
INIT_LOGGER.info("---->");
INIT_LOGGER.info("----> Property Override Test: {}", this.webserviceInfo.getTestProperty());
// TODO integration of Flyway for database initialization and migration: https://flywaydb.org
// see also https://flywaydb.org/getstarted/firststeps/api
// Create an initial admin account if requested and not already in the data-base
this.adminUserInitializer.initAdminAccount();
}
@PreDestroy
public void gracefulShutdown() {
log.info("**** Gracefully Shutdown of SEB Server instance {} ****", this.webserviceInfo.getHostAddress());
INIT_LOGGER.info("**** Gracefully Shutdown of SEB Server instance {} ****",
this.webserviceInfo.getHostAddress());
}
}

View file

@ -195,7 +195,7 @@ final class MockupLmsAPITemplate implements LmsAPITemplate {
}
private QuizData getExternalAddressAlias(final QuizData quizData) {
final String externalAddressAlias = this.webserviceInfo.getExternalAddressAlias("lms.mockup.com");
final String externalAddressAlias = this.webserviceInfo.getLmsExternalAddressAlias("lms.mockup.com");
if (StringUtils.isNoneBlank(externalAddressAlias)) {
try {

View file

@ -142,7 +142,7 @@ final class OpenEdxCourseAccess {
}
private String getExternalLMSServerAddress(final LmsSetup lmsSetup) {
final String externalAddressAlias = this.webserviceInfo.getExternalAddressAlias(lmsSetup.lmsApiUrl);
final String externalAddressAlias = this.webserviceInfo.getLmsExternalAddressAlias(lmsSetup.lmsApiUrl);
String _externalStartURI = lmsSetup.lmsApiUrl + OPEN_EDX_DEFAULT_COURSE_START_URL_PREFIX;
if (StringUtils.isNoneBlank(externalAddressAlias)) {
try {

View file

@ -21,7 +21,6 @@ import org.apache.ibatis.session.SqlSessionFactory;
import org.mybatis.spring.SqlSessionTemplate;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.boot.context.event.ApplicationReadyEvent;
import org.springframework.context.annotation.Lazy;
import org.springframework.context.event.EventListener;
import org.springframework.scheduling.annotation.AsyncConfigurer;
@ -84,7 +83,7 @@ public class AsyncBatchEventSaveStrategy implements EventHandlingStrategy {
}
@EventListener(ApplicationReadyEvent.class)
@EventListener(EventHandlingInit.class)
protected void recover() {
if (this.enabled) {
runWorkers();

View file

@ -0,0 +1,20 @@
/*
* Copyright (c) 2019 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.servicelayer.session.impl;
import org.springframework.context.ApplicationEvent;
public class EventHandlingInit extends ApplicationEvent {
private static final long serialVersionUID = -3608628289559324471L;
public EventHandlingInit(final Object source) {
super(source);
}
}

View file

@ -16,7 +16,6 @@ import org.joda.time.DateTimeZone;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.scheduling.annotation.Async;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Service;
@ -61,7 +60,6 @@ class ExamSessionControlTask {
this.examTimeSuffix = examTimeSuffix;
}
@Async
@Scheduled(cron = "${sebserver.webservice.api.exam.update-interval:1 * * * * *}")
public void examRunUpdateTask() {
@ -75,7 +73,6 @@ class ExamSessionControlTask {
controlExamEnd(updateId);
}
@Async
@Scheduled(fixedRate = Constants.SECOND_IN_MILLIS)
public void pingEventUpdateTask() {
this.sebClientConnectionService.updatePingEvents();

View file

@ -38,7 +38,7 @@ public class SingleEventSaveStrategy implements EventHandlingStrategy {
}
@Override
@Transactional
@Transactional(rollbackFor = Exception.class)
public void accept(final ClientEventRecord record) {
if (record.getId() == null) {
this.clientEventRecordMapper.insert(record);

View file

@ -1,16 +1,126 @@
spring.application.name=SEB Server
spring.profiles.active=dev
##########################################################
### Global Server Settings
# Server address (set for docker internal)
server.address=0.0.0.0
# Server http port
server.port=8080
# The servlet context path
server.servlet.context-path=/
### encoding
file.encoding=UTF-8
spring.mandatory-file-encoding=UTF-8
spring.http.encoding.charset=UTF-8
spring.http.encoding.enabled=true
### servlet session handling
server.servlet.session.cookie.http-only=true
server.servlet.session.tracking-modes=cookie
### Logging
# Default logging level in the form "logging.level" + namespace=LEVEL
logging.level.ch=DEBUG
# Log file name and location
logging.file=/sebserver/log/sebserver.log
### spring actuator configuration
management.endpoints.web.base-path=/mprofile
management.endpoints.web.exposure.include=metrics,logfile,loggers,heapdump
##########################################################
### Overall Security Settings
security.require-ssl=false
#server.ssl.key-store-type=PKCS12
#server.ssl.key-store=/certs/seb-server-keystore.pkcs12
#server.ssl.key-store-password=${sebserver.certs.password}
#server.ssl.key-password=${sebserver.certs.password}
#server.ssl.trust-store=/certs/seb-server-truststore.pkcs12
#server.ssl.trust-store-password=${sebserver.certs.password}
#server.ssl.enabled-protocols=TLSv1,TLSv1.1,TLSv1.2
# If webservice or gui runs on ssl and this flag is true, an integrated redirect from http to https is activated
# Disable this if a redirect is done by a reverse proxy for example
sebserver.ssl.redirect.enabled=false
sebserver.ssl.redirect.html.port=8080
##########################################################
### SEB Server Webservice configuration
sebserver.test.property=This is the default/root configuration
sebserver.version=0.5.1 beta
sebserver.init.organisation.name=ETHZ
sebserver.init.adminaccount.gen-on-init=true
sebserver.init.adminaccount.username=super-admin
### data source configuration
spring.datasource.initialize=true
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.driver-class-name=org.mariadb.jdbc.Driver
spring.datasource.hikari.initializationFailTimeout=30000
spring.datasource.hikari.connectionTimeout=30000
spring.datasource.hikari.idleTimeout=600000
spring.datasource.hikari.maxLifetime=1800000
### webservice security
spring.datasource.password=${sebserver.mariadb.password}
sebserver.webservice.api.admin.clientSecret=${sebserver.password}
sebserver.webservice.internalSecret=${sebserver.password}
### webservice networking
sebserver.webservice.distributed=false
sebserver.webservice.http.scheme=http
sebserver.webservice.http.external.servername=${server.address}
sebserver.webservice.http.external.port=${server.port}
sebserver.webservice.http.redirect.gui=/gui
### webservice API
sebserver.webservice.api.admin.clientId=guiClient
sebserver.webservice.api.admin.endpoint=/admin-api/v1
sebserver.webservice.api.admin.accessTokenValiditySeconds=3600
sebserver.webservice.api.admin.refreshTokenValiditySeconds=25200
sebserver.webservice.api.exam.config.init.permittedProcesses=config/initialPermittedProcesses.xml
sebserver.webservice.api.exam.config.init.prohibitedProcesses=config/initialProhibitedProcesses.xml
sebserver.webservice.api.exam.endpoint=/exam-api
sebserver.webservice.api.exam.endpoint.discovery=${sebserver.webservice.api.exam.endpoint}/discovery
sebserver.webservice.api.exam.endpoint.v1=${sebserver.webservice.api.exam.endpoint}/v1
sebserver.webservice.api.exam.accessTokenValiditySeconds=3600
sebserver.webservice.api.exam.event-handling-strategy=SINGLE_EVENT_STORE_STRATEGY
sebserver.webservice.api.exam.enable-indicator-cache=true
sebserver.webservice.api.pagination.maxPageSize=500
# comma separated list of known possible OpenEdX API access token request endpoints
sebserver.webservice.lms.openedx.api.token.request.paths=/oauth2/access_token
sebserver.webservice.lms.address.alias=
##########################################################
### SEB Server GUI configuration
sebserver.gui.multilingual=false
sebserver.gui.supported.languages=en
sebserver.gui.entrypoint=/gui
sebserver.gui.webservice.protocol=http
sebserver.gui.webservice.address=localhost
sebserver.gui.webservice.port=8080
sebserver.gui.webservice.apipath=/admin-api/v1
# defines the polling interval that is used to poll the webservice for client connection data on a monitored exam page
sebserver.gui.webservice.poll-interval=500
sebserver.gui.webservice.mock-lms-enabled=true
sebserver.gui.theme=css/sebserver.css
sebserver.gui.list.page.size=20
sebserver.gui.date.displayformat=MM/dd/yyyy HH:mm
sebserver.gui.date.displayformat.timezone=|ZZ
sebserver.gui.seb.client.config.download.filename=SEBClientSettings.seb
sebserver.gui.seb.exam.config.download.filename=SEBExamSettings.seb

View file

@ -21,6 +21,7 @@ sebserver.overall.action.category.varia=Varia
sebserver.overall.status.active=Active
sebserver.overall.status.inactive=Inactive
sebserver.overall.status.all=All
sebserver.overall.date.from=From
sebserver.overall.date.to=To

View file

@ -1,144 +0,0 @@
################################
# Overall
################################
sebserver.overall.version=SEB Server Version : {0}
sebserver.overall.imprint=
sebserver.overall.imprint.markup=
sebserver.overall.about=
sebserver.overall.about.markup=
sebserver.overall.help=Dokumentation
sebserver.overall.help.link=https://www.safeexambrowser.org/news_de.html
sebserver.overall.message.leave.without.save=You are leaving this page without saved changes!\nThe unsaved changes will be lost.\Are you sure to leave the page?
sebserver.overall.upload=Bitte Ausw\u00E4hlen
sebserver.overall.action.modify.cancel=Abbrechen
sebserver.overall.action.modify.cancel.confirm=Nicht gespeicherte Daten gehen verloren. Wirklich abbrechen?
sebserver.overall.action.filter=Filtern
sebserver.overall.action.filter.clear=Filter Zur\u00FCcksetzen
################################
# Form validation and messages
################################
sebserver.form.validation.error.title=Validierung
sebserver.form.validation.error.message=Einige Daten fehlen oder sind nicht korrekt.
sebserver.form.validation.fieldError.size=Der Text muss mindestens {3} und kann h\u00F6chstens {4} Zeichen beinhalten
sebserver.form.validation.fieldError.name=Name is mandatory and must have a size between {3} and {4} character
sebserver.form.validation.fieldError.urlSuffix=URL Suffix must have a size between {3} and {4} character
sebserver.form.validation.fieldError.notNull=Dies ist ein Pflichtfeld
sebserver.form.validation.fieldError.username.notunique=Dieser Username ist schon in Gebrauch. Bitte w\u00E4hlen Sie einen anderen.
sebserver.form.validation.fieldError.password.wrong=Das (aktuelle) Passwort stimmt nicht
sebserver.form.validation.fieldError.password.mismatch=Passwort, neues Passwort und Best\u00E4tigung stimmen nicht \u00FCberein
sebserver.error.unexpected=Unerwarteter Fehler
sebserver.page.message=Information
sebserver.dialog.confirm.title=Best\u00E4tigung
sebserver.dialog.confirm.deactivation=Es gibt {0} weitere Objekte die zu diesem Objeckt geh\u00F6ren.<br/>Diese werden bei einer Deaktivierung ebenfalls deaktiviert.<br/><br/>Sollen alle deaktiviert weden?
sebserver.dialog.confirm.deactivation.noDependencies=Soll dieses Object wirklich deaktiviert werden?
################################
# Login Page
################################
sebserver.login.username=Benutzer Name
sebserver.login.pwd=Passwort
sebserver.login.login=Anmelden
sebserver.login.failed.title=Anmelden Fehlgeschlagen
sebserver.login.failed.message=Zugang verweigert: Falscher Benutzer Name oder Passwort
sebserver.logout=Abmelden
sebserver.logout.success.message=Sie wurden erfolgreich abgemeldet
sebserver.login.password.change=Information
sebserver.login.password.change.success=Das Passwort wurde erfoglreich ge\u00E4ndert. Bitte melden Sie sich mit dem neuen Passwort an.
################################
# Main Page
################################
sebserver.logout=Abmelden
sebserver.mainpage.maximize.tooltip=Maximieren
sebserver.mainpage.minimize.tooltip=Minimieren
sebserver.activitiespane.title=Aktivit\u00E4ten
sebserver.actionpane.title=Aktionen
################################
# Institution
################################
sebserver.institution.list.title=Institutionen
sebserver.institution.list.column.name=Name
sebserver.institution.list.column.urlSuffix=URL Suffix
sebserver.institution.list.column.active=Aktiv
sebserver.institution.action.list=Institution
sebserver.institution.action.form=Institution
sebserver.institution.action.new=Neue Institution
sebserver.institution.action.list.view=Ausgew\u00E4hlte Ansehen
sebserver.institution.action.modify=Institution Editieren
sebserver.institution.action.list.modify=Ausgew\u00E4hlte Editieren
sebserver.institution.action.save=Institution Speichern
sebserver.institution.action.activate=Aktiv
sebserver.institution.action.deactivate=Aktiv
sebserver.institution.action.delete=Institution L\u00F6schen
sebserver.institution.info.pleaseSelect=Bitte zuerst eine Instiiution aus der List ausw\u00E4hlen.
sebserver.institution.form.title.new=Neue Institution
sebserver.institution.form.title=Institution : {0}
sebserver.institution.form.name=Name
sebserver.institution.form.urlSuffix=URL Suffix
sebserver.institution.form.logoImage=Logo Bild
################################
# User Account
################################
sebserver.useraccount.role.SEB_SERVER_ADMIN=SEB Server Administrator
sebserver.useraccount.role.INSTITUTIONAL_ADMIN=Institution Administrator
sebserver.useraccount.role.EXAM_ADMIN=Examen Administrator
sebserver.useraccount.role.EXAM_SUPPORTER=Examen Supporter
sebserver.useraccount.list.title=Benutzer Konto
sebserver.useraccount.list.column.name=Name
sebserver.useraccount.list.column.username=Benutzer Name
sebserver.useraccount.list.column.email=E-Mail
sebserver.useraccount.list.column.language=Sprache
sebserver.useraccount.list.column.active=Aktiv
sebserver.useraccount.action.list=Benutzer Konto
sebserver.useraccount.action.form=Benutzer Konto
sebserver.useraccount.action.new=Neues Benutzer Konto
sebserver.useraccount.action.view=Ausgew\u00E4hlter Ansehen
sebserver.useraccount.action.list.modify=Ausgew\u00E4hlter Editieren
sebserver.useraccount.action.modify=Editieren
sebserver.useraccount.action.save=Benutzer Konto Speichern
sebserver.useraccount.action.activate=Aktiv
sebserver.useraccount.action.deactivate=Aktiv
sebserver.useraccount.action.delete=Benutzer Konto L\u00F6schen
sebserver.useraccount.action.change.password=Passwort Ändern
sebserver.useraccount.action.change.password.save=Passwort Speichern
sebserver.useraccount.info.pleaseSelect=Bitte zuerst ein Benutzer Konto aus der List ausw\u00E4hlen.
sebserver.useraccount.form.title=Benutzer Konto : {0}
sebserver.useraccount.form.title.new=Neues Benutzer Konto
sebserver.useraccount.form.institution=Institution
sebserver.useraccount.form.name=Name
sebserver.useraccount.form.username=Benutzer Name
sebserver.useraccount.form.mail=E-Mail
sebserver.useraccount.form.language=Sprache
sebserver.useraccount.form.timezone=Zeit Zone
sebserver.useraccount.form.roles=Benutzer Rollen
sebserver.useraccount.form.password=Passwort
sebserver.useraccount.form.password.confirm=Passwort Best\u00E4tigen
sebserver.useraccount.form.pwchange.title=Passwort \u00C4ndern : {0}
sebserver.useraccount.form.password.old=Altes Passwort
sebserver.useraccount.form.password.new=Neues Passwort
sebserver.useraccount.form.password.new.confirm=Neues Password Best\u00E4tigen

View file

@ -3,6 +3,7 @@ server.port=8080
server.servlet.context-path=/
spring.main.allow-bean-definition-overriding=true
sebserver.password=test-password
spring.h2.console.enabled=true
spring.datasource.platform=h2