diff --git a/src/main/java/ch/ethz/seb/sebserver/gbl/Constants.java b/src/main/java/ch/ethz/seb/sebserver/gbl/Constants.java index 7de5838d..1296128a 100644 --- a/src/main/java/ch/ethz/seb/sebserver/gbl/Constants.java +++ b/src/main/java/ch/ethz/seb/sebserver/gbl/Constants.java @@ -67,6 +67,7 @@ public final class Constants { public static final String XML_PLIST_BOOLEAN_TRUE = "true"; public static final String XML_PLIST_BOOLEAN_FALSE = "false"; public static final String XML_PLIST_STRING = "string"; + public static final String XML_PLIST_DATA = "data"; public static final String XML_PLIST_INTEGER = "integer"; public static final String OAUTH2_GRANT_TYPE_PASSWORD = "password"; diff --git a/src/main/java/ch/ethz/seb/sebserver/gbl/api/API.java b/src/main/java/ch/ethz/seb/sebserver/gbl/api/API.java index 02197401..34a28ad6 100644 --- a/src/main/java/ch/ethz/seb/sebserver/gbl/api/API.java +++ b/src/main/java/ch/ethz/seb/sebserver/gbl/api/API.java @@ -121,6 +121,8 @@ public final class API { public static final String CONFIGURATION_ATTRIBUTE_ENDPOINT = "/configuration_attribute"; public static final String CONFIGURATION_PLAIN_XML_DOWNLOAD_PATH_SEGMENT = "/downloadxml"; public static final String CONFIGURATION_IMPORT_PATH_SEGMENT = "/import"; + public static final String IMPORT_PASSWORD_ATTR_NAME = "importFilePassword"; + public static final String IMPORT_FILE_ATTR_NAME = "importFile"; public static final String ORIENTATION_ENDPOINT = "/orientation"; public static final String VIEW_ENDPOINT = ORIENTATION_ENDPOINT + "/view"; diff --git a/src/main/java/ch/ethz/seb/sebserver/gbl/api/APIMessage.java b/src/main/java/ch/ethz/seb/sebserver/gbl/api/APIMessage.java index 73da6000..44e378cc 100644 --- a/src/main/java/ch/ethz/seb/sebserver/gbl/api/APIMessage.java +++ b/src/main/java/ch/ethz/seb/sebserver/gbl/api/APIMessage.java @@ -18,6 +18,7 @@ import org.apache.commons.lang3.StringUtils; import org.springframework.http.HttpStatus; import org.springframework.http.ResponseEntity; import org.springframework.validation.FieldError; +import org.springframework.web.util.HtmlUtils; import com.fasterxml.jackson.annotation.JsonCreator; import com.fasterxml.jackson.annotation.JsonProperty; @@ -189,18 +190,19 @@ public class APIMessage implements Serializable { public static String toHTML(final Collection messages) { final StringBuilder builder = new StringBuilder(); builder.append("Messages:

"); - messages.stream().forEach(message -> { - builder - .append("  code : ") - .append(message.messageCode) - .append("
") - .append("  system message : ") - .append(message.systemMessage) - .append("
") - .append("  details : ") - .append(StringUtils.abbreviate(message.details, 100)) - .append("

"); - }); + messages.stream() + .forEach(message -> { + builder + .append("  code : ") + .append(message.messageCode) + .append("
") + .append("  system message : ") + .append(HtmlUtils.htmlEscape(message.systemMessage)) + .append("
") + .append("  details : ") + .append(HtmlUtils.htmlEscape(StringUtils.abbreviate(message.details, 100))) + .append("

"); + }); return builder.toString(); } diff --git a/src/main/java/ch/ethz/seb/sebserver/gbl/async/AsyncExceptionHandler.java b/src/main/java/ch/ethz/seb/sebserver/gbl/async/AsyncExceptionHandler.java index 1135adba..5e78be99 100644 --- a/src/main/java/ch/ethz/seb/sebserver/gbl/async/AsyncExceptionHandler.java +++ b/src/main/java/ch/ethz/seb/sebserver/gbl/async/AsyncExceptionHandler.java @@ -18,10 +18,6 @@ public class AsyncExceptionHandler implements AsyncUncaughtExceptionHandler { private static final Logger log = LoggerFactory.getLogger(AsyncExceptionHandler.class); - public AsyncExceptionHandler() { - // TODO Auto-generated constructor stub - } - @Override public void handleUncaughtException(final Throwable ex, final Method method, final Object... params) { log.error("Unexpected error while async processing. method: {}", method, ex); diff --git a/src/main/java/ch/ethz/seb/sebserver/gui/content/SebExamConfigPropForm.java b/src/main/java/ch/ethz/seb/sebserver/gui/content/SebExamConfigPropForm.java index 3b0a9f80..7c98f7c5 100644 --- a/src/main/java/ch/ethz/seb/sebserver/gui/content/SebExamConfigPropForm.java +++ b/src/main/java/ch/ethz/seb/sebserver/gui/content/SebExamConfigPropForm.java @@ -28,6 +28,7 @@ import ch.ethz.seb.sebserver.gbl.api.API; import ch.ethz.seb.sebserver.gbl.model.Domain; import ch.ethz.seb.sebserver.gbl.model.EntityKey; import ch.ethz.seb.sebserver.gbl.model.sebconfig.ConfigKey; +import ch.ethz.seb.sebserver.gbl.model.sebconfig.Configuration; import ch.ethz.seb.sebserver.gbl.model.sebconfig.ConfigurationNode; import ch.ethz.seb.sebserver.gbl.model.sebconfig.ConfigurationNode.ConfigurationType; import ch.ethz.seb.sebserver.gbl.model.user.UserInfo; @@ -66,8 +67,6 @@ public class SebExamConfigPropForm implements TemplateComposer { private static final Logger log = LoggerFactory.getLogger(SebExamConfigPropForm.class); - private static final String PASSWORD_ATTR_NAME = "importFilePassword"; - private static final String IMPORT_FILE_ATTR_NAME = "importFile"; private static final LocTextKey FORM_TITLE_NEW = new LocTextKey("sebserver.examconfig.form.title.new"); private static final LocTextKey FORM_TITLE = @@ -86,6 +85,8 @@ public class SebExamConfigPropForm implements TemplateComposer { new LocTextKey("sebserver.examconfig.action.import-file-password"); private static final LocTextKey CONFIG_KEY_TITLE_TEXT_KEY = new LocTextKey("sebserver.examconfig.form.config-key.title"); + private static final LocTextKey FORM_IMPORT_CONFIRM_TEXT_KEY = + new LocTextKey("sebserver.examconfig.action.import-config.confirm"); private final PageService pageService; private final RestService restService; @@ -298,16 +299,21 @@ public class SebExamConfigPropForm implements TemplateComposer { final Form form = formHandle.getForm(); final EntityKey entityKey = formHandle.getContext().getEntityKey(); - final Control fieldControl = form.getFieldControl(IMPORT_FILE_ATTR_NAME); + final Control fieldControl = form.getFieldControl(API.IMPORT_FILE_ATTR_NAME); + final PageContext context = formHandle.getContext(); if (fieldControl != null && fieldControl instanceof FileUploadSelection) { final InputStream inputStream = ((FileUploadSelection) fieldControl).getInputStream(); if (inputStream != null) { - pageService.getRestService() + final Configuration configuration = pageService.getRestService() .getBuilder(ImportExamConfig.class) .withURIVariable(API.PARAM_MODEL_ID, entityKey.modelId) .withBody(inputStream) .call() - .getOrThrow(); + .get(context::notifyError); + + if (configuration != null) { + context.publishInfo(FORM_IMPORT_CONFIRM_TEXT_KEY); + } } else { formHandle.getContext().publishPageMessage( new LocTextKey("sebserver.error.unexpected"), @@ -333,12 +339,12 @@ public class SebExamConfigPropForm implements TemplateComposer { this.pageContext.copyOf(parent), 4) .readonly(false) .addField(FormBuilder.fileUpload( - IMPORT_FILE_ATTR_NAME, + API.IMPORT_FILE_ATTR_NAME, FORM_IMPORT_SELECT_TEXT_KEY, null, API.SEB_FILE_EXTENSION)) .addField(FormBuilder.text( - PASSWORD_ATTR_NAME, + API.IMPORT_PASSWORD_ATTR_NAME, FORM_IMPORT_PASSWORD_TEXT_KEY, "").asPasswordField()) .build(); diff --git a/src/main/java/ch/ethz/seb/sebserver/gui/service/remote/webservice/api/RestCall.java b/src/main/java/ch/ethz/seb/sebserver/gui/service/remote/webservice/api/RestCall.java index f247d080..291c6375 100644 --- a/src/main/java/ch/ethz/seb/sebserver/gui/service/remote/webservice/api/RestCall.java +++ b/src/main/java/ch/ethz/seb/sebserver/gui/service/remote/webservice/api/RestCall.java @@ -19,6 +19,7 @@ import java.util.function.Function; import org.apache.commons.lang3.StringUtils; import org.slf4j.Logger; import org.slf4j.LoggerFactory; +import org.springframework.core.io.InputStreamResource; import org.springframework.http.HttpEntity; import org.springframework.http.HttpHeaders; import org.springframework.http.HttpMethod; @@ -334,7 +335,7 @@ public abstract class RestCall { public HttpEntity buildRequestEntity() { if (this.streamingBody != null) { - return new HttpEntity<>(this.streamingBody, this.httpHeaders); + return new HttpEntity<>(new InputStreamResource(this.streamingBody), this.httpHeaders); } else if (this.body != null) { return new HttpEntity<>(this.body, this.httpHeaders); } else { diff --git a/src/main/java/ch/ethz/seb/sebserver/gui/service/remote/webservice/api/seb/examconfig/ImportExamConfig.java b/src/main/java/ch/ethz/seb/sebserver/gui/service/remote/webservice/api/seb/examconfig/ImportExamConfig.java index 317ae669..2619aff8 100644 --- a/src/main/java/ch/ethz/seb/sebserver/gui/service/remote/webservice/api/seb/examconfig/ImportExamConfig.java +++ b/src/main/java/ch/ethz/seb/sebserver/gui/service/remote/webservice/api/seb/examconfig/ImportExamConfig.java @@ -33,7 +33,7 @@ public class ImportExamConfig extends RestCall { new TypeReference() { }), HttpMethod.POST, - MediaType.APPLICATION_FORM_URLENCODED, + MediaType.APPLICATION_OCTET_STREAM, API.CONFIGURATION_NODE_ENDPOINT + API.MODEL_ID_VAR_PATH_SEGMENT + API.CONFIGURATION_IMPORT_PATH_SEGMENT); diff --git a/src/main/java/ch/ethz/seb/sebserver/gui/widget/FileUploadSelection.java b/src/main/java/ch/ethz/seb/sebserver/gui/widget/FileUploadSelection.java index db8b6267..4cc1f298 100644 --- a/src/main/java/ch/ethz/seb/sebserver/gui/widget/FileUploadSelection.java +++ b/src/main/java/ch/ethz/seb/sebserver/gui/widget/FileUploadSelection.java @@ -10,11 +10,14 @@ package ch.ethz.seb.sebserver.gui.widget; import java.io.IOException; import java.io.InputStream; +import java.io.PipedInputStream; +import java.io.PipedOutputStream; import java.util.ArrayList; import java.util.List; import java.util.Locale; import java.util.function.Consumer; +import org.apache.commons.io.IOUtils; import org.eclipse.rap.fileupload.FileDetails; import org.eclipse.rap.fileupload.FileUploadHandler; import org.eclipse.rap.fileupload.FileUploadReceiver; @@ -77,6 +80,11 @@ public class FileUploadSelection extends Composite { this.fileUpload.setLayoutData(new GridData(SWT.LEFT, SWT.CENTER, false, false)); this.fileUpload.setToolTipText(this.i18nSupport.getText(PLEASE_SELECT_TEXT)); final FileUploadHandler uploadHandler = new FileUploadHandler(new InputReceiver()); + + this.fileName = new Label(this, SWT.NONE); + this.fileName.setText(i18nSupport.getText(PLEASE_SELECT_TEXT)); + this.fileName.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, true, false)); + this.fileUpload.addListener(SWT.Selection, event -> { final String fileName = FileUploadSelection.this.fileUpload.getFileName(); if (fileName == null || !fileSupported(fileName)) { @@ -90,11 +98,10 @@ public class FileUploadSelection extends Composite { return; } FileUploadSelection.this.fileUpload.submit(uploadHandler.getUploadUrl()); + FileUploadSelection.this.fileName.setText(fileName); + FileUploadSelection.this.errorHandler.accept(null); }); - this.fileName = new Label(this, SWT.NONE); - this.fileName.setText(i18nSupport.getText(PLEASE_SELECT_TEXT)); - this.fileName.setLayoutData(new GridData(SWT.LEFT, SWT.CENTER, true, false)); } } @@ -148,7 +155,18 @@ public class FileUploadSelection extends Composite { private final class InputReceiver extends FileUploadReceiver { @Override public void receive(final InputStream stream, final FileDetails details) throws IOException { - FileUploadSelection.this.inputStream = stream; + final PipedInputStream pIn = new PipedInputStream(); + final PipedOutputStream pOut = new PipedOutputStream(pIn); + + FileUploadSelection.this.inputStream = pIn; + + try { + IOUtils.copyLarge(stream, pOut); + } catch (final Exception e) { + e.printStackTrace(); + } finally { + IOUtils.closeQuietly(pOut); + } } } diff --git a/src/main/java/ch/ethz/seb/sebserver/gui/widget/Message.java b/src/main/java/ch/ethz/seb/sebserver/gui/widget/Message.java index 52e3e0fc..a562b456 100644 --- a/src/main/java/ch/ethz/seb/sebserver/gui/widget/Message.java +++ b/src/main/java/ch/ethz/seb/sebserver/gui/widget/Message.java @@ -19,7 +19,12 @@ public final class Message extends MessageBox { private static final int NORMAL_WIDTH = 400; private static final long serialVersionUID = 6973272221493264432L; - public Message(final Shell parent, final String title, final String message, final int type) { + public Message( + final Shell parent, + final String title, + final String message, + final int type) { + super(parent, type); super.setText(title); super.setMessage(message); diff --git a/src/main/java/ch/ethz/seb/sebserver/webservice/servicelayer/dao/impl/ConfigurationDAOBatchService.java b/src/main/java/ch/ethz/seb/sebserver/webservice/servicelayer/dao/impl/ConfigurationDAOBatchService.java index 2dc3a73c..271fbe23 100644 --- a/src/main/java/ch/ethz/seb/sebserver/webservice/servicelayer/dao/impl/ConfigurationDAOBatchService.java +++ b/src/main/java/ch/ethz/seb/sebserver/webservice/servicelayer/dao/impl/ConfigurationDAOBatchService.java @@ -234,7 +234,7 @@ class ConfigurationDAOBatchService { .forEach(newValRec -> this.batchConfigurationValueRecordMapper.insert(newValRec)); return this.batchConfigurationRecordMapper - .selectByPrimaryKey(configUpdate.getId()); + .selectByPrimaryKey(newFollowup.getId()); }) .flatMap(ConfigurationDAOImpl::toDomainModel); diff --git a/src/main/java/ch/ethz/seb/sebserver/webservice/servicelayer/dao/impl/ConfigurationValueDAOImpl.java b/src/main/java/ch/ethz/seb/sebserver/webservice/servicelayer/dao/impl/ConfigurationValueDAOImpl.java index b60394cc..f863fbd2 100644 --- a/src/main/java/ch/ethz/seb/sebserver/webservice/servicelayer/dao/impl/ConfigurationValueDAOImpl.java +++ b/src/main/java/ch/ethz/seb/sebserver/webservice/servicelayer/dao/impl/ConfigurationValueDAOImpl.java @@ -24,6 +24,8 @@ import java.util.stream.Collectors; import org.apache.commons.lang3.BooleanUtils; import org.mybatis.dynamic.sql.SqlBuilder; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; import org.springframework.context.annotation.Lazy; import org.springframework.stereotype.Component; import org.springframework.transaction.annotation.Transactional; @@ -53,6 +55,8 @@ import ch.ethz.seb.sebserver.webservice.servicelayer.dao.TransactionHandler; @WebServiceProfile public class ConfigurationValueDAOImpl implements ConfigurationValueDAO { + private static final Logger log = LoggerFactory.getLogger(ConfigurationValueDAOImpl.class); + private final ConfigurationValueRecordMapper configurationValueRecordMapper; private final ConfigurationAttributeRecordMapper configurationAttributeRecordMapper; private final ConfigurationRecordMapper configurationRecordMapper; @@ -192,9 +196,9 @@ public class ConfigurationValueDAOImpl implements ConfigurationValueDAO { id = getByProperties(data) .orElseGet(() -> { - log.warn("Missing SEB exam configuration attrribute value for: {}", data); - log.info("Use self-healing strategy to recover from missing SEB exam configuration " - + "attrribute value\n**** Create new AttributeValue for: {}", + log.debug("Missing SEB exam configuration attrribute value for: {}", data); + log.debug("Use self-healing strategy to recover from missing SEB exam " + + "configuration attrribute value\n**** Create new AttributeValue for: {}", data); createNew(data); diff --git a/src/main/java/ch/ethz/seb/sebserver/webservice/servicelayer/sebconfig/impl/ExamConfigIO.java b/src/main/java/ch/ethz/seb/sebserver/webservice/servicelayer/sebconfig/impl/ExamConfigIO.java index a7e16691..278e374f 100644 --- a/src/main/java/ch/ethz/seb/sebserver/webservice/servicelayer/sebconfig/impl/ExamConfigIO.java +++ b/src/main/java/ch/ethz/seb/sebserver/webservice/servicelayer/sebconfig/impl/ExamConfigIO.java @@ -162,7 +162,7 @@ public class ExamConfigIO { /** This parses the XML from given InputStream with a SAX parser to avoid keeping the * whole XML file in memory and keep up with the streaming approach of SEB Exam Configuration * to avoid trouble with big SEB Exam Configuration in the future. - * + * * @param in The InputString to constantly read the XML from * @param institutionId the institionId of the import * @param configurationId the identifier of the internal configuration to apply the imported values to */ @@ -181,7 +181,9 @@ public class ExamConfigIO { final ExamConfigImportHandler examConfigImportHandler = new ExamConfigImportHandler( institutionId, configurationId, - value -> this.configurationValueDAO.save(value), + value -> this.configurationValueDAO + .save(value) + .getOrThrow(), attributeMap::get); // SAX parsing diff --git a/src/main/java/ch/ethz/seb/sebserver/webservice/servicelayer/sebconfig/impl/ExamConfigImportHandler.java b/src/main/java/ch/ethz/seb/sebserver/webservice/servicelayer/sebconfig/impl/ExamConfigImportHandler.java index 41cf63f2..2ca8e41c 100644 --- a/src/main/java/ch/ethz/seb/sebserver/webservice/servicelayer/sebconfig/impl/ExamConfigImportHandler.java +++ b/src/main/java/ch/ethz/seb/sebserver/webservice/servicelayer/sebconfig/impl/ExamConfigImportHandler.java @@ -15,6 +15,8 @@ import java.util.Stack; import java.util.function.Consumer; import java.util.function.Function; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; import org.xml.sax.Attributes; import org.xml.sax.SAXException; import org.xml.sax.helpers.DefaultHandler; @@ -25,10 +27,13 @@ import ch.ethz.seb.sebserver.webservice.servicelayer.sebconfig.impl.ExamConfigIm public class ExamConfigImportHandler extends DefaultHandler { + private static final Logger log = LoggerFactory.getLogger(ExamConfigImportHandler.class); + private static final Set VALUE_ELEMENTS = new HashSet<>(Arrays.asList( Constants.XML_PLIST_BOOLEAN_FALSE, Constants.XML_PLIST_BOOLEAN_TRUE, Constants.XML_PLIST_STRING, + Constants.XML_PLIST_DATA, Constants.XML_PLIST_INTEGER)); private final Consumer valueConsumer; @@ -51,6 +56,16 @@ public class ExamConfigImportHandler extends DefaultHandler { this.configId = configId; } + @Override + public void startDocument() throws SAXException { + log.debug("Start parsing document"); + } + + @Override + public void endDocument() throws SAXException { + log.debug("End parsing document"); + } + @Override public void startElement( final String uri, @@ -58,6 +73,8 @@ public class ExamConfigImportHandler extends DefaultHandler { final String qName, final Attributes attributes) throws SAXException { + log.debug("start element: {}", qName); + final Type type = Type.getType(qName); final PListNode top = (this.stack.isEmpty()) ? null : this.stack.peek(); @@ -77,6 +94,7 @@ public class ExamConfigImportHandler extends DefaultHandler { case VALUE_BOOLEAN_FALSE: case VALUE_BOOLEAN_TRUE: case VALUE_STRING: + case VALUE_DATA: case VALUE_INTEGER: startValueElement(type, top); break; @@ -196,13 +214,30 @@ public class ExamConfigImportHandler extends DefaultHandler { ? parent.name + "." + top.name : top.name; - this.valueConsumer.accept(new ConfigurationValue( - null, - this.institutionId, - this.configId, - this.attributeNameIdResolver.apply(attrName), - top.listIndex, - top.value)); + final Long attributeId = this.attributeNameIdResolver.apply(attrName); + if (attributeId == null) { + + if (log.isDebugEnabled()) { + log.debug("Skip unknown configuration attribute: {}", attrName); + } + + } else { + + // TODO use AttributeValueConverterService here. Extend the converters with fromXML functionality + final ConfigurationValue configurationValue = new ConfigurationValue( + null, + this.institutionId, + this.configId, + attributeId, + top.listIndex, + top.value); + + if (log.isDebugEnabled()) { + log.debug("Save imported value: {} : {}", attrName, configurationValue); + } + + this.valueConsumer.accept(configurationValue); + } } } else if (!Constants.XML_PLIST_KEY_NAME.equals(qName)) { this.stack.pop(); @@ -215,13 +250,16 @@ public class ExamConfigImportHandler extends DefaultHandler { final int start, final int length) throws SAXException { + final char[] valueChar = new char[length]; + System.arraycopy(ch, start, valueChar, 0, length); + final String value = String.valueOf(valueChar); final PListNode top = this.stack.peek(); if (top.type == Type.VALUE_STRING) { - top.value = String.valueOf(ch); + top.value = value; } else if (top.type == Type.VALUE_INTEGER) { - top.value = String.valueOf(ch); + top.value = value; } else if (top.type == Type.KEY) { - top.name = String.valueOf(ch); + top.name = value; } } @@ -235,6 +273,7 @@ public class ExamConfigImportHandler extends DefaultHandler { VALUE_BOOLEAN_TRUE(true, Constants.XML_PLIST_BOOLEAN_TRUE), VALUE_BOOLEAN_FALSE(true, Constants.XML_PLIST_BOOLEAN_FALSE), VALUE_STRING(true, Constants.XML_PLIST_STRING), + VALUE_DATA(true, Constants.XML_PLIST_DATA), VALUE_INTEGER(true, Constants.XML_PLIST_INTEGER); private final boolean isValueType; diff --git a/src/main/java/ch/ethz/seb/sebserver/webservice/servicelayer/sebconfig/impl/SebExamConfigServiceImpl.java b/src/main/java/ch/ethz/seb/sebserver/webservice/servicelayer/sebconfig/impl/SebExamConfigServiceImpl.java index 9c0b6bfe..d5ca0f90 100644 --- a/src/main/java/ch/ethz/seb/sebserver/webservice/servicelayer/sebconfig/impl/SebExamConfigServiceImpl.java +++ b/src/main/java/ch/ethz/seb/sebserver/webservice/servicelayer/sebconfig/impl/SebExamConfigServiceImpl.java @@ -336,12 +336,19 @@ public class SebExamConfigServiceImpl implements SebExamConfigService { final byte[] header = new byte[4]; input.read(header); - final Strategy strategy = SebConfigEncryptionService.Strategy.getStrategy(header); - if (strategy == null) { + Strategy strategy = null; + try { + strategy = SebConfigEncryptionService.Strategy.getStrategy(header); + } catch (final IllegalArgumentException iae) { + + log.info("{} : Trying to import as unzipped plain text configuration", iae.getMessage()); + importPlainOnly(input, newConfig, header); - } else { + return newConfig; + } + if (strategy != null) { final InputStream cryptIn = this.unzip(input); final PipedInputStream plainIn = new PipedInputStream(); final PipedOutputStream cryptOut = new PipedOutputStream(plainIn); @@ -369,9 +376,11 @@ public class SebExamConfigServiceImpl implements SebExamConfigService { } catch (final Exception e) { log.error("Unexpected error while trying to import SEB Exam Configuration: ", e); log.debug("Make an undo on the ConfigurationNode to rollback the changes"); - return this.configurationDAO + this.configurationDAO .undo(configNodeId) .getOrThrow(); + + throw new RuntimeException("Failed to import SEB configuration. Cause is: " + e.getMessage(), e); } }); } @@ -412,16 +421,18 @@ public class SebExamConfigServiceImpl implements SebExamConfigService { plainIn = new PipedInputStream(); out = new PipedOutputStream(plainIn); - this.examConfigIO.importPlainXML(plainIn, newConfig.institutionId, newConfig.id); + this.examConfigIO.importPlainXML( + plainIn, + newConfig.institutionId, + newConfig.id); + out.write(header); IOUtils.copyLarge(input, out); - IOUtils.closeQuietly(out); } catch (final Exception e) { log.error("Error while stream plain text SEB Configuration import data: ", e); throw e; } finally { IOUtils.closeQuietly(out); - IOUtils.closeQuietly(plainIn); } } diff --git a/src/main/java/ch/ethz/seb/sebserver/webservice/weblayer/api/ConfigurationNodeController.java b/src/main/java/ch/ethz/seb/sebserver/webservice/weblayer/api/ConfigurationNodeController.java index dfa052e8..e372e1b9 100644 --- a/src/main/java/ch/ethz/seb/sebserver/webservice/weblayer/api/ConfigurationNodeController.java +++ b/src/main/java/ch/ethz/seb/sebserver/webservice/weblayer/api/ConfigurationNodeController.java @@ -164,11 +164,12 @@ public class ConfigurationNodeController extends EntityController