diff --git a/src/main/java/ch/ethz/seb/sebserver/ClientHttpRequestFactoryService.java b/src/main/java/ch/ethz/seb/sebserver/ClientHttpRequestFactoryService.java index a31418de..3f0b8ba2 100644 --- a/src/main/java/ch/ethz/seb/sebserver/ClientHttpRequestFactoryService.java +++ b/src/main/java/ch/ethz/seb/sebserver/ClientHttpRequestFactoryService.java @@ -11,7 +11,6 @@ package ch.ethz.seb.sebserver; import java.io.File; import java.io.FileNotFoundException; import java.io.IOException; -import java.net.HttpURLConnection; import java.security.KeyManagementException; import java.security.KeyStoreException; import java.security.NoSuchAlgorithmException; @@ -39,7 +38,6 @@ import org.slf4j.LoggerFactory; import org.springframework.core.env.Environment; import org.springframework.http.client.ClientHttpRequestFactory; import org.springframework.http.client.HttpComponentsClientHttpRequestFactory; -import org.springframework.http.client.SimpleClientHttpRequestFactory; import org.springframework.stereotype.Service; import org.springframework.util.CollectionUtils; import org.springframework.util.ResourceUtils; @@ -95,11 +93,18 @@ public class ClientHttpRequestFactoryService { final HttpComponentsClientHttpRequestFactory factory = new HttpComponentsClientHttpRequestFactory(); factory.setHttpClient(this.createProxiedClient(proxy, null)); + factory.setBufferRequestBody(false); return factory; } else { - final DevClientHttpRequestFactory devClientHttpRequestFactory = new DevClientHttpRequestFactory(); - devClientHttpRequestFactory.setOutputStreaming(false); + final HttpComponentsClientHttpRequestFactory devClientHttpRequestFactory = + new HttpComponentsClientHttpRequestFactory(); + + devClientHttpRequestFactory.setBufferRequestBody(false); + +// final HttpClient httpClient = devClientHttpRequestFactory.getHttpClient(); +// httpClient.setInstanceFollowRedirects(false); +// httpClient.setOutputStreaming(false); return devClientHttpRequestFactory; } } @@ -204,17 +209,17 @@ public class ClientHttpRequestFactoryService { } // TODO set connection and read timeout!? configurable!? - private static class DevClientHttpRequestFactory extends SimpleClientHttpRequestFactory { - - @Override - protected void prepareConnection( - final HttpURLConnection connection, - final String httpMethod) throws IOException { - - super.prepareConnection(connection, httpMethod); - super.setBufferRequestBody(false); - connection.setInstanceFollowRedirects(false); - } - } +// private static class DevClientHttpRequestFactory extends HttpComponentsClientHttpRequestFactory { +// +// @Override +// protected void prepareConnection( +// final HttpURLConnection connection, +// final String httpMethod) throws IOException { +// +// super.prepareConnection(connection, httpMethod); +// super.setBufferRequestBody(false); +// connection.setInstanceFollowRedirects(false); +// } +// } } 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 bfea404f..72d112a3 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 @@ -27,6 +27,7 @@ public final class API { public static final String PARAM_ENTITY_TYPE = "entityType"; public static final String PARAM_BULK_ACTION_TYPE = "bulkActionType"; public static final String PARAM_CLIENT_CONFIG_SECRET = "client_config_secret"; + public static final String PARAM_VIEW_ID = "viewId"; public static final String DEFAULT_CONFIG_TEMPLATE_ID = String.valueOf(ConfigurationNode.DEFAULT_TEMPLATE_ID); public static final String INSTITUTION_VAR_PATH_SEGMENT = "/{" + PARAM_INSTITUTION_ID + "}"; @@ -128,6 +129,9 @@ public final class API { public static final String IMPORT_FILE_ATTR_NAME = "importFile"; public static final String TEMPLATE_ATTRIBUTE_ENDPOINT = "/template-attribute"; + public static final String TEMPLATE_ATTRIBUTE_RESET_VALUES = "/reset"; + public static final String TEMPLATE_ATTRIBUTE_REMOVE_ORIENTATION = "remove-orientation"; + public static final String TEMPLATE_ATTRIBUTE_ATTACH_DEFAUL_ORIENTATION = "attach-default-orientation"; 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/model/sebconfig/Orientation.java b/src/main/java/ch/ethz/seb/sebserver/gbl/model/sebconfig/Orientation.java index 3b810a1a..f7c67ead 100644 --- a/src/main/java/ch/ethz/seb/sebserver/gbl/model/sebconfig/Orientation.java +++ b/src/main/java/ch/ethz/seb/sebserver/gbl/model/sebconfig/Orientation.java @@ -23,6 +23,7 @@ import ch.ethz.seb.sebserver.gbl.model.Entity; @JsonIgnoreProperties(ignoreUnknown = true) public final class Orientation implements Entity { + public static final String FILTER_ATTR_ATTRIBUTE_ID = "attributeId"; public static final String FILTER_ATTR_TEMPLATE_ID = "templateId"; public static final String FILTER_ATTR_VIEW_ID = "viewId"; public static final String FILTER_ATTR_GROUP_ID = "groupId"; diff --git a/src/main/java/ch/ethz/seb/sebserver/gui/content/ConfigTemplateAttributeForm.java b/src/main/java/ch/ethz/seb/sebserver/gui/content/ConfigTemplateAttributeForm.java index 93b2f2ed..bf384c63 100644 --- a/src/main/java/ch/ethz/seb/sebserver/gui/content/ConfigTemplateAttributeForm.java +++ b/src/main/java/ch/ethz/seb/sebserver/gui/content/ConfigTemplateAttributeForm.java @@ -10,6 +10,9 @@ package ch.ethz.seb.sebserver.gui.content; import java.util.Arrays; +import org.eclipse.swt.SWT; +import org.eclipse.swt.layout.GridData; +import org.eclipse.swt.layout.GridLayout; import org.eclipse.swt.widgets.Composite; import org.springframework.context.annotation.Lazy; import org.springframework.stereotype.Component; @@ -36,13 +39,13 @@ import ch.ethz.seb.sebserver.gui.service.examconfig.impl.ViewContext; import ch.ethz.seb.sebserver.gui.service.i18n.LocTextKey; 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.PageService.PageActionBuilder; import ch.ethz.seb.sebserver.gui.service.page.TemplateComposer; import ch.ethz.seb.sebserver.gui.service.remote.webservice.api.RestService; import ch.ethz.seb.sebserver.gui.service.remote.webservice.api.seb.examconfig.GetConfigurations; import ch.ethz.seb.sebserver.gui.service.remote.webservice.api.seb.examconfig.GetTemplateAttribute; import ch.ethz.seb.sebserver.gui.service.remote.webservice.auth.CurrentUser; import ch.ethz.seb.sebserver.gui.widget.WidgetFactory; +import ch.ethz.seb.sebserver.gui.widget.WidgetFactory.CustomVariant; @Lazy @Component @@ -142,10 +145,17 @@ public class ConfigTemplateAttributeForm implements TemplateComposer { attribute.getGroupId())) .build(); - widgetFactory.labelLocalizedTitle( + widgetFactory.labelLocalized( content, + CustomVariant.TEXT_H2, FORM_VALUE_TEXT_KEY); + final Composite grid = new Composite(content, SWT.NONE); + grid.setLayoutData(new GridData(SWT.FILL, SWT.TOP, true, false)); + grid.setLayout(new GridLayout(6, true)); + + final PageContext valueContext = formContext.copyOf(grid); + final InputFieldBuilder inputFieldBuilder = this.examConfigurationService.getInputFieldBuilder( attribute.getConfigAttribute(), attribute.getOrientation()); @@ -154,7 +164,7 @@ public class ConfigTemplateAttributeForm implements TemplateComposer { .getOrThrow(); final ViewContext viewContext = this.examConfigurationService.createViewContext( - formContext, + valueContext, configuration, new View(-1L, "template", 10, 0, templateId), attributeMapping, @@ -171,9 +181,7 @@ public class ConfigTemplateAttributeForm implements TemplateComposer { configuration.id, Arrays.asList(viewContext)); - final PageActionBuilder pageActionBuilder = this.pageService - .pageActionBuilder(formContext.clearEntityKeys()); - pageActionBuilder + this.pageService.pageActionBuilder(formContext.clearEntityKeys()) .newAction(ActionDefinition.SEB_EXAM_CONFIG_TEMPLATE_ATTR_FORM_SET_DEFAULT) .withEntityKey(attributeKey) diff --git a/src/main/java/ch/ethz/seb/sebserver/gui/content/ConfigTemplateForm.java b/src/main/java/ch/ethz/seb/sebserver/gui/content/ConfigTemplateForm.java index 9332565b..7bc4abc3 100644 --- a/src/main/java/ch/ethz/seb/sebserver/gui/content/ConfigTemplateForm.java +++ b/src/main/java/ch/ethz/seb/sebserver/gui/content/ConfigTemplateForm.java @@ -282,7 +282,7 @@ public class ConfigTemplateForm implements TemplateComposer { final PageAction action, final EntityTable attrTable) { - final PageAction removeFormView = this.examConfigurationService.removeFormView(action); + final PageAction removeFormView = this.examConfigurationService.removeFromView(action); // reload the list attrTable.applyFilter(); return removeFormView; diff --git a/src/main/java/ch/ethz/seb/sebserver/gui/service/examconfig/ExamConfigurationService.java b/src/main/java/ch/ethz/seb/sebserver/gui/service/examconfig/ExamConfigurationService.java index 2414dc36..60422aec 100644 --- a/src/main/java/ch/ethz/seb/sebserver/gui/service/examconfig/ExamConfigurationService.java +++ b/src/main/java/ch/ethz/seb/sebserver/gui/service/examconfig/ExamConfigurationService.java @@ -61,7 +61,9 @@ public interface ExamConfigurationService { PageAction resetToDefaults(PageAction action); - PageAction removeFormView(PageAction action); + PageAction removeFromView(PageAction action); + + PageAction attachToDefaultView(final PageAction action); static String attributeNameKey(final ConfigurationAttribute attribute) { if (attribute == null) { diff --git a/src/main/java/ch/ethz/seb/sebserver/gui/service/examconfig/impl/ExamConfigurationServiceImpl.java b/src/main/java/ch/ethz/seb/sebserver/gui/service/examconfig/impl/ExamConfigurationServiceImpl.java index ade45dd6..fe391f9d 100644 --- a/src/main/java/ch/ethz/seb/sebserver/gui/service/examconfig/impl/ExamConfigurationServiceImpl.java +++ b/src/main/java/ch/ethz/seb/sebserver/gui/service/examconfig/impl/ExamConfigurationServiceImpl.java @@ -11,6 +11,7 @@ package ch.ethz.seb.sebserver.gui.service.examconfig.impl; import java.util.Collection; import java.util.Collections; import java.util.List; +import java.util.Set; import java.util.stream.Collectors; import org.apache.tomcat.util.buf.StringUtils; @@ -46,12 +47,16 @@ import ch.ethz.seb.sebserver.gui.service.i18n.LocTextKey; import ch.ethz.seb.sebserver.gui.service.page.FieldValidationError; import ch.ethz.seb.sebserver.gui.service.page.PageContext; import ch.ethz.seb.sebserver.gui.service.page.impl.PageAction; +import ch.ethz.seb.sebserver.gui.service.remote.webservice.api.RestCall; import ch.ethz.seb.sebserver.gui.service.remote.webservice.api.RestCallError; import ch.ethz.seb.sebserver.gui.service.remote.webservice.api.RestService; +import ch.ethz.seb.sebserver.gui.service.remote.webservice.api.seb.examconfig.AttchDefaultOrientation; import ch.ethz.seb.sebserver.gui.service.remote.webservice.api.seb.examconfig.GetConfigAttributes; import ch.ethz.seb.sebserver.gui.service.remote.webservice.api.seb.examconfig.GetConfigurationValues; import ch.ethz.seb.sebserver.gui.service.remote.webservice.api.seb.examconfig.GetOrientations; import ch.ethz.seb.sebserver.gui.service.remote.webservice.api.seb.examconfig.GetViewList; +import ch.ethz.seb.sebserver.gui.service.remote.webservice.api.seb.examconfig.RemoveOrientation; +import ch.ethz.seb.sebserver.gui.service.remote.webservice.api.seb.examconfig.ResetTemplateValues; import ch.ethz.seb.sebserver.gui.service.remote.webservice.api.seb.examconfig.SaveExamConfigTableValues; import ch.ethz.seb.sebserver.gui.service.remote.webservice.api.seb.examconfig.SaveExamConfigValue; import ch.ethz.seb.sebserver.gui.widget.WidgetFactory; @@ -213,21 +218,82 @@ public class ExamConfigurationServiceImpl implements ExamConfigurationService { @Override public final PageAction resetToDefaults(final PageAction action) { - final EntityKey singleSelection = action.getSingleSelection(); + final EntityKey parentEntityKey = action.pageContext().getParentEntityKey(); + final Set selection = action.getMultiSelection(); + if (selection != null && !selection.isEmpty()) { + selection.stream().forEach(entityKey -> { + callTemplateAction( + ResetTemplateValues.class, + parentEntityKey.modelId, + entityKey.modelId); + }); + } else { + final EntityKey entityKey = action.getEntityKey(); + callTemplateAction( + ResetTemplateValues.class, + parentEntityKey.modelId, + entityKey.modelId); + } - // TODO return action; } @Override - public final PageAction removeFormView(final PageAction action) { - final EntityKey singleSelection = action.getSingleSelection(); - - // TODO + public final PageAction removeFromView(final PageAction action) { + final EntityKey parentEntityKey = action.pageContext().getParentEntityKey(); + final Set selection = action.getMultiSelection(); + if (selection != null && !selection.isEmpty()) { + selection.stream().forEach(entityKey -> { + callTemplateAction( + RemoveOrientation.class, + parentEntityKey.modelId, + entityKey.modelId); + }); + } else { + final EntityKey entityKey = action.getEntityKey(); + callTemplateAction( + RemoveOrientation.class, + parentEntityKey.modelId, + entityKey.modelId); + } return action; } + @Override + public final PageAction attachToDefaultView(final PageAction action) { + final EntityKey parentEntityKey = action.pageContext().getParentEntityKey(); + final Set selection = action.getMultiSelection(); + if (selection != null && !selection.isEmpty()) { + selection.stream().forEach(entityKey -> { + callTemplateAction( + AttchDefaultOrientation.class, + parentEntityKey.modelId, + entityKey.modelId); + }); + } else { + final EntityKey entityKey = action.getEntityKey(); + callTemplateAction( + AttchDefaultOrientation.class, + parentEntityKey.modelId, + entityKey.modelId); + } + + return action; + } + + private void callTemplateAction( + final Class> actionType, + final String templateId, + final String attributeId) { + + this.restService.getBuilder(actionType) + .withURIVariable(API.PARAM_PARENT_MODEL_ID, templateId) + .withURIVariable(API.PARAM_MODEL_ID, attributeId) + .call() + .getOrThrow(); + } + private static final class ValueChangeListenerImpl implements ValueChangeListener { public static final String VALIDATION_ERROR_KEY_PREFIX = "sebserver.examconfig.props.validation."; diff --git a/src/main/java/ch/ethz/seb/sebserver/gui/service/remote/webservice/api/seb/examconfig/AttchDefaultOrientation.java b/src/main/java/ch/ethz/seb/sebserver/gui/service/remote/webservice/api/seb/examconfig/AttchDefaultOrientation.java new file mode 100644 index 00000000..f7c10956 --- /dev/null +++ b/src/main/java/ch/ethz/seb/sebserver/gui/service/remote/webservice/api/seb/examconfig/AttchDefaultOrientation.java @@ -0,0 +1,44 @@ +/* + * 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.gui.service.remote.webservice.api.seb.examconfig; + +import org.springframework.context.annotation.Lazy; +import org.springframework.http.HttpMethod; +import org.springframework.http.MediaType; +import org.springframework.stereotype.Component; + +import com.fasterxml.jackson.core.type.TypeReference; + +import ch.ethz.seb.sebserver.gbl.api.API; +import ch.ethz.seb.sebserver.gbl.api.EntityType; +import ch.ethz.seb.sebserver.gbl.model.sebconfig.TemplateAttribute; +import ch.ethz.seb.sebserver.gbl.profile.GuiProfile; +import ch.ethz.seb.sebserver.gui.service.remote.webservice.api.RestCall; + +@Lazy +@Component +@GuiProfile +public class AttchDefaultOrientation extends RestCall { + + public AttchDefaultOrientation() { + super(new TypeKey<>( + CallType.SAVE, + EntityType.CONFIGURATION_NODE, + new TypeReference() { + }), + HttpMethod.PATCH, + MediaType.APPLICATION_FORM_URLENCODED, + API.CONFIGURATION_NODE_ENDPOINT + + API.PARENT_MODEL_ID_VAR_PATH_SEGMENT + + API.TEMPLATE_ATTRIBUTE_ENDPOINT + + API.MODEL_ID_VAR_PATH_SEGMENT + + API.TEMPLATE_ATTRIBUTE_ATTACH_DEFAUL_ORIENTATION); + } + +} diff --git a/src/main/java/ch/ethz/seb/sebserver/gui/service/remote/webservice/api/seb/examconfig/RemoveOrientation.java b/src/main/java/ch/ethz/seb/sebserver/gui/service/remote/webservice/api/seb/examconfig/RemoveOrientation.java new file mode 100644 index 00000000..01dd2433 --- /dev/null +++ b/src/main/java/ch/ethz/seb/sebserver/gui/service/remote/webservice/api/seb/examconfig/RemoveOrientation.java @@ -0,0 +1,44 @@ +/* + * 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.gui.service.remote.webservice.api.seb.examconfig; + +import org.springframework.context.annotation.Lazy; +import org.springframework.http.HttpMethod; +import org.springframework.http.MediaType; +import org.springframework.stereotype.Component; + +import com.fasterxml.jackson.core.type.TypeReference; + +import ch.ethz.seb.sebserver.gbl.api.API; +import ch.ethz.seb.sebserver.gbl.api.EntityType; +import ch.ethz.seb.sebserver.gbl.model.sebconfig.TemplateAttribute; +import ch.ethz.seb.sebserver.gbl.profile.GuiProfile; +import ch.ethz.seb.sebserver.gui.service.remote.webservice.api.RestCall; + +@Lazy +@Component +@GuiProfile +public class RemoveOrientation extends RestCall { + + public RemoveOrientation() { + super(new TypeKey<>( + CallType.SAVE, + EntityType.CONFIGURATION_NODE, + new TypeReference() { + }), + HttpMethod.PATCH, + MediaType.APPLICATION_FORM_URLENCODED, + API.CONFIGURATION_NODE_ENDPOINT + + API.PARENT_MODEL_ID_VAR_PATH_SEGMENT + + API.TEMPLATE_ATTRIBUTE_ENDPOINT + + API.MODEL_ID_VAR_PATH_SEGMENT + + API.TEMPLATE_ATTRIBUTE_REMOVE_ORIENTATION); + } + +} diff --git a/src/main/java/ch/ethz/seb/sebserver/gui/service/remote/webservice/api/seb/examconfig/ResetTemplateValues.java b/src/main/java/ch/ethz/seb/sebserver/gui/service/remote/webservice/api/seb/examconfig/ResetTemplateValues.java new file mode 100644 index 00000000..ba19d60b --- /dev/null +++ b/src/main/java/ch/ethz/seb/sebserver/gui/service/remote/webservice/api/seb/examconfig/ResetTemplateValues.java @@ -0,0 +1,44 @@ +/* + * 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.gui.service.remote.webservice.api.seb.examconfig; + +import org.springframework.context.annotation.Lazy; +import org.springframework.http.HttpMethod; +import org.springframework.http.MediaType; +import org.springframework.stereotype.Component; + +import com.fasterxml.jackson.core.type.TypeReference; + +import ch.ethz.seb.sebserver.gbl.api.API; +import ch.ethz.seb.sebserver.gbl.api.EntityType; +import ch.ethz.seb.sebserver.gbl.model.sebconfig.TemplateAttribute; +import ch.ethz.seb.sebserver.gbl.profile.GuiProfile; +import ch.ethz.seb.sebserver.gui.service.remote.webservice.api.RestCall; + +@Lazy +@Component +@GuiProfile +public class ResetTemplateValues extends RestCall { + + public ResetTemplateValues() { + super(new TypeKey<>( + CallType.SAVE, + EntityType.CONFIGURATION_NODE, + new TypeReference() { + }), + HttpMethod.PATCH, + MediaType.APPLICATION_FORM_URLENCODED, + API.CONFIGURATION_NODE_ENDPOINT + + API.PARENT_MODEL_ID_VAR_PATH_SEGMENT + + API.TEMPLATE_ATTRIBUTE_ENDPOINT + + API.MODEL_ID_VAR_PATH_SEGMENT + + API.TEMPLATE_ATTRIBUTE_RESET_VALUES); + } + +} diff --git a/src/main/java/ch/ethz/seb/sebserver/webservice/WebserviceInfo.java b/src/main/java/ch/ethz/seb/sebserver/webservice/WebserviceInfo.java index b3aebfd3..2023ea7a 100644 --- a/src/main/java/ch/ethz/seb/sebserver/webservice/WebserviceInfo.java +++ b/src/main/java/ch/ethz/seb/sebserver/webservice/WebserviceInfo.java @@ -36,6 +36,7 @@ public class WebserviceInfo { private static final String WEB_SERVICE_TEST_PROPERTY = "sebserver.test.property"; private static final String WEB_SERVICE_SERVER_NAME_KEY = "sebserver.webservice.http.server.name"; private static final String WEB_SERVICE_HTTP_SCHEME_KEY = "sebserver.webservice.http.scheme"; + private static final String WEB_SERVICE_HTTP_PORT = "sebserver.webservice.http.port"; private static final String WEB_SERVICE_HOST_ADDRESS_KEY = "server.address"; private static final String WEB_SERVICE_SERVER_PORT_KEY = "server.port"; private static final String WEB_SERVICE_EXAM_API_DISCOVERY_ENDPOINT_KEY = @@ -45,8 +46,9 @@ public class WebserviceInfo { private final String testProperty; private final String httpScheme; private final String hostAddress; // internal - private final String serverName; // external - private final String serverPort; + private final String webserverName; // external + private final String serverPort; // internal + private final String webserverPort; // external private final String discoveryEndpoint; private final String serverURLPrefix; @@ -58,17 +60,21 @@ public class WebserviceInfo { this.testProperty = environment.getProperty(WEB_SERVICE_TEST_PROPERTY, "NOT_AVAILABLE"); this.httpScheme = environment.getRequiredProperty(WEB_SERVICE_HTTP_SCHEME_KEY); this.hostAddress = environment.getRequiredProperty(WEB_SERVICE_HOST_ADDRESS_KEY); - this.serverName = environment.getProperty(WEB_SERVICE_SERVER_NAME_KEY, ""); + this.webserverName = environment.getProperty(WEB_SERVICE_SERVER_NAME_KEY, ""); this.serverPort = environment.getRequiredProperty(WEB_SERVICE_SERVER_PORT_KEY); + this.webserverPort = environment.getProperty(WEB_SERVICE_HTTP_PORT); this.discoveryEndpoint = environment.getRequiredProperty(WEB_SERVICE_EXAM_API_DISCOVERY_ENDPOINT_KEY); - this.serverURLPrefix = UriComponentsBuilder.newInstance() + final UriComponentsBuilder builder = UriComponentsBuilder.newInstance() .scheme(this.httpScheme) - .host((StringUtils.isNotBlank(this.serverName)) - ? this.serverName - : this.hostAddress) - .port(this.serverPort) - .toUriString(); + .host((StringUtils.isNotBlank(this.webserverName)) + ? this.webserverName + : this.hostAddress); + if (StringUtils.isNotBlank(this.webserverPort)) { + builder.port(this.webserverPort); + } + + this.serverURLPrefix = builder.toUriString(); this.isDistributed = BooleanUtils.toBoolean(environment.getProperty( "sebserver.webservice.distributed", @@ -106,14 +112,18 @@ public class WebserviceInfo { return this.hostAddress; } - public String getServerName() { - return this.serverName; + public String getWebserviceDomainName() { + return this.webserverName; } public String getServerPort() { return this.serverPort; } + public String getServerExternalPort() { + return this.webserverPort; + } + public String getDiscoveryEndpoint() { return this.discoveryEndpoint; } @@ -183,18 +193,20 @@ public class WebserviceInfo { builder.append(this.httpScheme); builder.append(", hostAddress="); builder.append(this.hostAddress); - builder.append(", serverName="); - builder.append(this.serverName); + builder.append(", webserverName="); + builder.append(this.webserverName); builder.append(", serverPort="); builder.append(this.serverPort); + builder.append(", webserverPort="); + builder.append(this.webserverPort); builder.append(", discoveryEndpoint="); builder.append(this.discoveryEndpoint); - builder.append(", externalAddressAlias="); - builder.append(this.externalAddressAlias); builder.append(", serverURLPrefix="); builder.append(this.serverURLPrefix); builder.append(", isDistributed="); builder.append(this.isDistributed); + builder.append(", externalAddressAlias="); + builder.append(this.externalAddressAlias); builder.append("]"); return builder.toString(); } diff --git a/src/main/java/ch/ethz/seb/sebserver/webservice/servicelayer/dao/FilterMap.java b/src/main/java/ch/ethz/seb/sebserver/webservice/servicelayer/dao/FilterMap.java index 9306af3c..d6352590 100644 --- a/src/main/java/ch/ethz/seb/sebserver/webservice/servicelayer/dao/FilterMap.java +++ b/src/main/java/ch/ethz/seb/sebserver/webservice/servicelayer/dao/FilterMap.java @@ -8,6 +8,8 @@ package ch.ethz.seb.sebserver.webservice.servicelayer.dao; +import java.util.Arrays; + import org.apache.commons.lang3.StringUtils; import org.joda.time.DateTime; import org.springframework.util.LinkedMultiValueMap; @@ -119,6 +121,10 @@ public class FilterMap extends POSTMapper { return getLong(Orientation.FILTER_ATTR_TEMPLATE_ID); } + public Long getOrientationAttributeId() { + return getLong(Orientation.FILTER_ATTR_ATTRIBUTE_ID); + } + public Long getOrientationViewId() { return getLong(Orientation.FILTER_ATTR_VIEW_ID); } @@ -284,4 +290,23 @@ public class FilterMap extends POSTMapper { return null; } + public static final class Builder { + + private final FilterMap filterMap = new FilterMap(); + + public Builder add(final String name, final String value) { + this.filterMap.params.add(name, value); + return this; + } + + public Builder put(final String name, final String value) { + this.filterMap.params.put(name, Arrays.asList(value)); + return this; + } + + public FilterMap create() { + return new FilterMap(this.filterMap.params); + } + } + } diff --git a/src/main/java/ch/ethz/seb/sebserver/webservice/servicelayer/dao/ViewDAO.java b/src/main/java/ch/ethz/seb/sebserver/webservice/servicelayer/dao/ViewDAO.java index 07bc0066..4dcd9012 100644 --- a/src/main/java/ch/ethz/seb/sebserver/webservice/servicelayer/dao/ViewDAO.java +++ b/src/main/java/ch/ethz/seb/sebserver/webservice/servicelayer/dao/ViewDAO.java @@ -8,6 +8,7 @@ package ch.ethz.seb.sebserver.webservice.servicelayer.dao; +import java.util.List; import java.util.Map; import ch.ethz.seb.sebserver.gbl.model.sebconfig.ConfigurationNode; @@ -18,4 +19,8 @@ public interface ViewDAO extends EntityDAO { Result> copyDefaultViewsForTemplate(ConfigurationNode node); + Result> getDefaultTemplateViews(); + + Result getDefaultViewForTemplate(Long templateId, Long defaultViewId); + } diff --git a/src/main/java/ch/ethz/seb/sebserver/webservice/servicelayer/dao/impl/OrientationDAOImpl.java b/src/main/java/ch/ethz/seb/sebserver/webservice/servicelayer/dao/impl/OrientationDAOImpl.java index 0006a402..83342892 100644 --- a/src/main/java/ch/ethz/seb/sebserver/webservice/servicelayer/dao/impl/OrientationDAOImpl.java +++ b/src/main/java/ch/ethz/seb/sebserver/webservice/servicelayer/dao/impl/OrientationDAOImpl.java @@ -91,6 +91,9 @@ public class OrientationDAOImpl implements OrientationDAO { .where( OrientationRecordDynamicSqlSupport.templateId, SqlBuilder.isEqualToWhenPresent(filterMap.getOrientationTemplateId())) + .and( + OrientationRecordDynamicSqlSupport.configAttributeId, + SqlBuilder.isEqualToWhenPresent(filterMap.getOrientationAttributeId())) .and( OrientationRecordDynamicSqlSupport.viewId, SqlBuilder.isEqualToWhenPresent(filterMap.getOrientationViewId())) diff --git a/src/main/java/ch/ethz/seb/sebserver/webservice/servicelayer/dao/impl/ViewDAOImpl.java b/src/main/java/ch/ethz/seb/sebserver/webservice/servicelayer/dao/impl/ViewDAOImpl.java index 3368c47b..3da3c74c 100644 --- a/src/main/java/ch/ethz/seb/sebserver/webservice/servicelayer/dao/impl/ViewDAOImpl.java +++ b/src/main/java/ch/ethz/seb/sebserver/webservice/servicelayer/dao/impl/ViewDAOImpl.java @@ -100,6 +100,47 @@ public class ViewDAOImpl implements ViewDAO { .collect(Collectors.toList())); } + @Override + @Transactional(readOnly = true) + public Result> getDefaultTemplateViews() { + return Result.tryCatch(() -> this.viewRecordMapper + .selectByExample() + .where( + ViewRecordDynamicSqlSupport.templateId, + SqlBuilder.isEqualTo(ConfigurationNode.DEFAULT_TEMPLATE_ID)) + .build() + .execute() + .stream() + .map(ViewDAOImpl::toDomainModel) + .flatMap(DAOLoggingSupport::logAndSkipOnError) + .collect(Collectors.toList())); + } + + @Override + @Transactional(readOnly = true) + public Result getDefaultViewForTemplate(final Long templateId, final Long defaultViewId) { + return Result.tryCatch(() -> { + // get all views of template + final List templateViews = this.viewRecordMapper + .selectByExample() + .where( + ViewRecordDynamicSqlSupport.templateId, + SqlBuilder.isEqualTo(templateId)) + .build() + .execute(); + // get default view + final ViewRecord defView = this.viewRecordMapper.selectByPrimaryKey(defaultViewId); + final ViewRecord result = templateViews + .stream() + .filter(view -> view.getName().equals(defView.getName())) + .findFirst() + .orElseThrow(); + + return result; + }) + .flatMap(ViewDAOImpl::toDomainModel); + } + @Override @Transactional public Result createNew(final View data) { diff --git a/src/main/java/ch/ethz/seb/sebserver/webservice/servicelayer/sebconfig/SebExamConfigTemplateService.java b/src/main/java/ch/ethz/seb/sebserver/webservice/servicelayer/sebconfig/SebExamConfigTemplateService.java index d08399e6..1c6eeaa1 100644 --- a/src/main/java/ch/ethz/seb/sebserver/webservice/servicelayer/sebconfig/SebExamConfigTemplateService.java +++ b/src/main/java/ch/ethz/seb/sebserver/webservice/servicelayer/sebconfig/SebExamConfigTemplateService.java @@ -9,9 +9,7 @@ package ch.ethz.seb.sebserver.webservice.servicelayer.sebconfig; import java.util.List; -import java.util.Set; -import ch.ethz.seb.sebserver.gbl.model.EntityKey; import ch.ethz.seb.sebserver.gbl.model.sebconfig.TemplateAttribute; import ch.ethz.seb.sebserver.gbl.util.Result; import ch.ethz.seb.sebserver.webservice.servicelayer.dao.FilterMap; @@ -29,9 +27,20 @@ public interface SebExamConfigTemplateService { final Long templateId, final Long attributeId); - Result> setDefaultValues( + Result setDefaultValues( final Long institutionId, final Long templateId, final Long attributeId); + Result removeOrientation( + final Long institutionId, + final Long templateId, + final Long attributeId); + + Result attachDefaultOrientation( + final Long institutionId, + final Long templateId, + final Long attributeId, + Long viewId); + } diff --git a/src/main/java/ch/ethz/seb/sebserver/webservice/servicelayer/sebconfig/impl/SebExamConfigTemplateServiceImpl.java b/src/main/java/ch/ethz/seb/sebserver/webservice/servicelayer/sebconfig/impl/SebExamConfigTemplateServiceImpl.java index 52a1086d..5c66e0c8 100644 --- a/src/main/java/ch/ethz/seb/sebserver/webservice/servicelayer/sebconfig/impl/SebExamConfigTemplateServiceImpl.java +++ b/src/main/java/ch/ethz/seb/sebserver/webservice/servicelayer/sebconfig/impl/SebExamConfigTemplateServiceImpl.java @@ -8,33 +8,34 @@ package ch.ethz.seb.sebserver.webservice.servicelayer.sebconfig.impl; +import java.util.Arrays; import java.util.Collections; +import java.util.HashSet; import java.util.List; import java.util.Map; -import java.util.Set; import java.util.function.Function; import java.util.stream.Collectors; import org.apache.commons.lang3.StringUtils; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; import org.springframework.context.annotation.Lazy; import org.springframework.stereotype.Service; import ch.ethz.seb.sebserver.gbl.model.Domain; -import ch.ethz.seb.sebserver.gbl.model.EntityKey; import ch.ethz.seb.sebserver.gbl.model.PageSortOrder; import ch.ethz.seb.sebserver.gbl.model.sebconfig.ConfigurationAttribute; +import ch.ethz.seb.sebserver.gbl.model.sebconfig.ConfigurationNode; import ch.ethz.seb.sebserver.gbl.model.sebconfig.Orientation; import ch.ethz.seb.sebserver.gbl.model.sebconfig.TemplateAttribute; import ch.ethz.seb.sebserver.gbl.profile.WebServiceProfile; import ch.ethz.seb.sebserver.gbl.util.Result; import ch.ethz.seb.sebserver.webservice.servicelayer.dao.ConfigurationAttributeDAO; import ch.ethz.seb.sebserver.webservice.servicelayer.dao.ConfigurationDAO; -import ch.ethz.seb.sebserver.webservice.servicelayer.dao.ConfigurationNodeDAO; import ch.ethz.seb.sebserver.webservice.servicelayer.dao.ConfigurationValueDAO; import ch.ethz.seb.sebserver.webservice.servicelayer.dao.FilterMap; import ch.ethz.seb.sebserver.webservice.servicelayer.dao.OrientationDAO; import ch.ethz.seb.sebserver.webservice.servicelayer.dao.ViewDAO; -import ch.ethz.seb.sebserver.webservice.servicelayer.sebconfig.SebExamConfigService; import ch.ethz.seb.sebserver.webservice.servicelayer.sebconfig.SebExamConfigTemplateService; @Lazy @@ -42,28 +43,26 @@ import ch.ethz.seb.sebserver.webservice.servicelayer.sebconfig.SebExamConfigTemp @WebServiceProfile public class SebExamConfigTemplateServiceImpl implements SebExamConfigTemplateService { - private final ConfigurationNodeDAO ConfigurationNodeDAO; - private final ConfigurationDAO configurationDAO; + private static final Logger log = LoggerFactory.getLogger(SebExamConfigTemplateServiceImpl.class); + private final ViewDAO viewDAO; + private final ConfigurationDAO configurationDAO; private final OrientationDAO orientationDAO; private final ConfigurationAttributeDAO configurationAttributeDAO; private final ConfigurationValueDAO configurationValueDAO; - private final SebExamConfigService sebExamConfigService; protected SebExamConfigTemplateServiceImpl( - final ch.ethz.seb.sebserver.webservice.servicelayer.dao.ConfigurationNodeDAO configurationNodeDAO, - final ConfigurationDAO configurationDAO, final ViewDAO viewDAO, final OrientationDAO orientationDAO, + final ViewDAO viewDAO, + final ConfigurationDAO configurationDAO, + final OrientationDAO orientationDAO, final ConfigurationAttributeDAO configurationAttributeDAO, - final ConfigurationValueDAO configurationValueDAO, - final SebExamConfigService sebExamConfigService) { - super(); - this.ConfigurationNodeDAO = configurationNodeDAO; - this.configurationDAO = configurationDAO; + final ConfigurationValueDAO configurationValueDAO) { + this.viewDAO = viewDAO; + this.configurationDAO = configurationDAO; this.orientationDAO = orientationDAO; this.configurationAttributeDAO = configurationAttributeDAO; this.configurationValueDAO = configurationValueDAO; - this.sebExamConfigService = sebExamConfigService; } @Override @@ -127,7 +126,7 @@ public class SebExamConfigTemplateServiceImpl implements SebExamConfigTemplateSe } @Override - public Result> setDefaultValues( + public Result setDefaultValues( final Long institutionId, final Long templateId, final Long attributeId) { @@ -137,7 +136,102 @@ public class SebExamConfigTemplateServiceImpl implements SebExamConfigTemplateSe .setDefaultValues( institutionId, config.id, - attributeId)); + attributeId)) + .flatMap(vals -> getAttribute( + institutionId, + templateId, + attributeId)); + } + + @Override + public Result removeOrientation( + final Long institutionId, + final Long templateId, + final Long attributeId) { + + return Result.tryCatch(() -> { + final Orientation orientation = getOrientation(templateId, attributeId); + + this.orientationDAO.delete(new HashSet<>(Arrays.asList(orientation.getEntityKey()))) + .getOrThrow(); + + final TemplateAttribute attribute = getAttribute(institutionId, templateId, attributeId) + .getOrThrow(); + + if (attribute.getOrientation() != null) { + throw new IllegalStateException( + "Failed to remove Orientation, expecting no Orientatoin for attribute: " + attribute); + } + + return attribute; + }); + } + + @Override + public Result attachDefaultOrientation( + final Long institutionId, + final Long templateId, + final Long attributeId, + final Long viewId) { + + return Result.tryCatch(() -> { + final Orientation orientation = getOrientation(templateId, attributeId); + final Orientation devOrientation = getOrientation(ConfigurationNode.DEFAULT_TEMPLATE_ID, attributeId); + + if (orientation != null) { + this.orientationDAO.delete(new HashSet<>(Arrays.asList(orientation.getEntityKey()))) + .getOrThrow(); + } + + final Long _viewId; + if (viewId == null) { + _viewId = this.viewDAO.getDefaultViewForTemplate(templateId, devOrientation.viewId) + .getOrThrow().id; + } else { + _viewId = viewId; + } + + final Orientation newOrientation = new Orientation( + null, + attributeId, + templateId, + _viewId, + devOrientation.groupId, + devOrientation.xPosition, + devOrientation.yPosition, + devOrientation.width, + devOrientation.height, + devOrientation.title); + + this.orientationDAO.save(newOrientation) + .getOrThrow(); + + final TemplateAttribute attribute = getAttribute(institutionId, templateId, attributeId) + .getOrThrow(); + + if (attribute.getOrientation() == null) { + throw new IllegalStateException( + "Failed to attach default Orientation, expecting Orientatoin for attribute: " + attribute); + } + + return attribute; + }); + } + + private Orientation getOrientation(final Long templateId, final Long attributeId) { + final FilterMap filterMap = new FilterMap.Builder() + .put(Orientation.FILTER_ATTR_TEMPLATE_ID, String.valueOf(templateId)) + .put(Orientation.FILTER_ATTR_ATTRIBUTE_ID, String.valueOf(attributeId)) + .create(); + + return this.orientationDAO.allMatching(filterMap) + .get(error -> { + log.warn("Unexpecrted error while get Orientation: ", error); + return Collections.emptyList(); + }) + .stream() + .findFirst() + .orElse(null); } } diff --git a/src/main/java/ch/ethz/seb/sebserver/webservice/servicelayer/session/impl/SebClientConnectionServiceImpl.java b/src/main/java/ch/ethz/seb/sebserver/webservice/servicelayer/session/impl/SebClientConnectionServiceImpl.java index 325f13fa..5ce63692 100644 --- a/src/main/java/ch/ethz/seb/sebserver/webservice/servicelayer/session/impl/SebClientConnectionServiceImpl.java +++ b/src/main/java/ch/ethz/seb/sebserver/webservice/servicelayer/session/impl/SebClientConnectionServiceImpl.java @@ -14,6 +14,7 @@ import java.util.UUID; import org.apache.commons.lang3.StringUtils; import org.slf4j.Logger; import org.slf4j.LoggerFactory; +import org.springframework.boot.logging.LogLevel; import org.springframework.context.annotation.Lazy; import org.springframework.stereotype.Service; @@ -31,6 +32,7 @@ import ch.ethz.seb.sebserver.webservice.servicelayer.session.ExamSessionService; import ch.ethz.seb.sebserver.webservice.servicelayer.session.PingHandlingStrategy; import ch.ethz.seb.sebserver.webservice.servicelayer.session.SebClientConnectionService; import ch.ethz.seb.sebserver.webservice.weblayer.api.APIConstraintViolationException; +import ch.ethz.seb.sebserver.webservice.weblayer.api.OnlyMessageLogExceptionWrapper; @Lazy @Service @@ -392,7 +394,9 @@ public class SebClientConnectionServiceImpl implements SebClientConnectionServic if (activeClientConnection != null) { if (activeClientConnection.clientConnection.status != ConnectionStatus.ESTABLISHED) { - throw new IllegalStateException("No established SEB client connection"); + throw new OnlyMessageLogExceptionWrapper( + new IllegalStateException("No established SEB client connection"), + LogLevel.WARN); } // store event @@ -404,6 +408,8 @@ public class SebClientConnectionServiceImpl implements SebClientConnectionServic activeClientConnection.getindicatorMapping(event.eventType) .stream() .forEach(indicator -> indicator.notifyValueChange(event)); + } else { + log.warn("No active ClientConnection found for connectionToken: {}", connectionToken); } } diff --git a/src/main/java/ch/ethz/seb/sebserver/webservice/weblayer/api/APIExceptionHandler.java b/src/main/java/ch/ethz/seb/sebserver/webservice/weblayer/api/APIExceptionHandler.java index 26834e07..f0502abc 100644 --- a/src/main/java/ch/ethz/seb/sebserver/webservice/weblayer/api/APIExceptionHandler.java +++ b/src/main/java/ch/ethz/seb/sebserver/webservice/weblayer/api/APIExceptionHandler.java @@ -53,6 +53,9 @@ public class APIExceptionHandler extends ResponseEntityExceptionHandler { if (ex instanceof AccessDeniedException) { log.warn("Access denied: ", ex); + } else if (ex instanceof OnlyMessageLogExceptionWrapper) { + ((OnlyMessageLogExceptionWrapper) ex).log(log); + return new ResponseEntity<>(status); } else { log.error("Unexpected generic error catched at the API endpoint: ", ex); } @@ -83,6 +86,15 @@ public class APIExceptionHandler extends ResponseEntityExceptionHandler { HttpStatus.BAD_REQUEST); } + @ExceptionHandler(OnlyMessageLogExceptionWrapper.class) + public ResponseEntity onlyMessageLogExceptionWrapper( + final OnlyMessageLogExceptionWrapper ex, + final WebRequest request) { + + ex.log(log); + return new ResponseEntity<>(HttpStatus.BAD_REQUEST); + } + @ExceptionHandler(OAuth2Exception.class) public ResponseEntity handleOAuth2Exception( final OAuth2Exception ex, 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 6c9f94bb..eaec0516 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 @@ -13,7 +13,6 @@ import java.io.IOException; import java.io.InputStream; import java.util.Arrays; import java.util.List; -import java.util.Set; import javax.servlet.ServletOutputStream; import javax.servlet.http.HttpServletRequest; @@ -39,13 +38,13 @@ import ch.ethz.seb.sebserver.gbl.api.APIMessage; import ch.ethz.seb.sebserver.gbl.api.POSTMapper; import ch.ethz.seb.sebserver.gbl.api.authorization.PrivilegeType; import ch.ethz.seb.sebserver.gbl.model.Domain.EXAM; -import ch.ethz.seb.sebserver.gbl.model.EntityKey; import ch.ethz.seb.sebserver.gbl.model.Page; 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.sebconfig.TemplateAttribute; +import ch.ethz.seb.sebserver.gbl.model.user.UserLogActivityType; import ch.ethz.seb.sebserver.gbl.profile.WebServiceProfile; import ch.ethz.seb.sebserver.gbl.util.Result; import ch.ethz.seb.sebserver.gbl.util.Utils; @@ -305,11 +304,12 @@ public class ConfigurationNodeController extends EntityController resetTemplateAttribute( + public TemplateAttribute resetTemplateAttributeValues( @PathVariable(name = API.PARAM_PARENT_MODEL_ID, required = true) final Long parentModelId, @PathVariable(name = API.PARAM_MODEL_ID, required = true) final Long modelId, @RequestParam( @@ -323,6 +323,62 @@ public class ConfigurationNodeController extends EntityController this.userActivityLogDAO.log(UserLogActivityType.MODIFY, entity)) + .getOrThrow(); + } + + @RequestMapping( + path = API.PARENT_MODEL_ID_VAR_PATH_SEGMENT + + API.TEMPLATE_ATTRIBUTE_ENDPOINT + + API.MODEL_ID_VAR_PATH_SEGMENT + + API.TEMPLATE_ATTRIBUTE_ATTACH_DEFAUL_ORIENTATION, + method = RequestMethod.PATCH, + consumes = MediaType.APPLICATION_FORM_URLENCODED_VALUE, + produces = MediaType.APPLICATION_JSON_UTF8_VALUE) + public TemplateAttribute attachDefaultTemplateAttributeOrientation( + @PathVariable(name = API.PARAM_PARENT_MODEL_ID, required = true) final Long parentModelId, + @PathVariable(name = API.PARAM_MODEL_ID, required = true) final Long modelId, + @RequestParam( + name = API.PARAM_INSTITUTION_ID, + required = true, + defaultValue = UserService.USERS_INSTITUTION_AS_DEFAULT) final Long institutionId, + @RequestParam(name = API.PARAM_VIEW_ID) final Long viewId) { + + checkModifyPrivilege(institutionId); + + return this.sebExamConfigTemplateService + .attachDefaultOrientation( + institutionId, + parentModelId, + modelId, + viewId) + .flatMap(entity -> this.userActivityLogDAO.log(UserLogActivityType.MODIFY, entity)) + .getOrThrow(); + } + + @RequestMapping( + path = API.PARENT_MODEL_ID_VAR_PATH_SEGMENT + + API.TEMPLATE_ATTRIBUTE_ENDPOINT + + API.MODEL_ID_VAR_PATH_SEGMENT + + API.TEMPLATE_ATTRIBUTE_REMOVE_ORIENTATION, + method = RequestMethod.PATCH, + consumes = MediaType.APPLICATION_FORM_URLENCODED_VALUE, + produces = MediaType.APPLICATION_JSON_UTF8_VALUE) + public TemplateAttribute removeTemplateAttributeOrientation( + @PathVariable(name = API.PARAM_PARENT_MODEL_ID, required = true) final Long parentModelId, + @PathVariable(name = API.PARAM_MODEL_ID, required = true) final Long modelId, + @RequestParam( + name = API.PARAM_INSTITUTION_ID, + required = true, + defaultValue = UserService.USERS_INSTITUTION_AS_DEFAULT) final Long institutionId) { + + checkModifyPrivilege(institutionId); + return this.sebExamConfigTemplateService + .removeOrientation( + institutionId, + parentModelId, + modelId) + .flatMap(entity -> this.userActivityLogDAO.log(UserLogActivityType.MODIFY, entity)) .getOrThrow(); } diff --git a/src/main/java/ch/ethz/seb/sebserver/webservice/weblayer/api/ExamAPI_V1_Controller.java b/src/main/java/ch/ethz/seb/sebserver/webservice/weblayer/api/ExamAPI_V1_Controller.java index 9ab91c26..a702136c 100644 --- a/src/main/java/ch/ethz/seb/sebserver/webservice/weblayer/api/ExamAPI_V1_Controller.java +++ b/src/main/java/ch/ethz/seb/sebserver/webservice/weblayer/api/ExamAPI_V1_Controller.java @@ -326,7 +326,8 @@ public class ExamAPI_V1_Controller { @RequestHeader(name = API.EXAM_API_SEB_CONNECTION_TOKEN, required = true) final String connectionToken, @RequestBody(required = true) final ClientEvent event) { - this.sebClientConnectionService.notifyClientEvent(connectionToken, event); + this.sebClientConnectionService + .notifyClientEvent(connectionToken, event); } private Long getInstitutionId(final Principal principal) { diff --git a/src/main/java/ch/ethz/seb/sebserver/webservice/weblayer/api/OnlyMessageLogExceptionWrapper.java b/src/main/java/ch/ethz/seb/sebserver/webservice/weblayer/api/OnlyMessageLogExceptionWrapper.java new file mode 100644 index 00000000..06cc55e6 --- /dev/null +++ b/src/main/java/ch/ethz/seb/sebserver/webservice/weblayer/api/OnlyMessageLogExceptionWrapper.java @@ -0,0 +1,51 @@ +/* + * 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.weblayer.api; + +import org.slf4j.Logger; +import org.springframework.boot.logging.LogLevel; + +public class OnlyMessageLogExceptionWrapper extends RuntimeException { + + private static final long serialVersionUID = 4177915563660228494L; + public final LogLevel logLevel; + + public OnlyMessageLogExceptionWrapper(final Exception cause) { + super(cause); + this.logLevel = LogLevel.WARN; + } + + public OnlyMessageLogExceptionWrapper(final Exception cause, final LogLevel logLevel) { + super(cause); + this.logLevel = logLevel; + } + + public final void log(final Logger logger) { + final String message = this.getCause().getMessage(); + switch (this.logLevel) { + case ERROR: + case FATAL: + logger.error(message); + break; + case INFO: + logger.info(message); + break; + case TRACE: + logger.trace(message); + break; + case WARN: + logger.warn(message); + break; + default: + logger.debug(message); + break; + } + } + +} diff --git a/src/main/resources/config/application-demo.properties b/src/main/resources/config/application-demo.properties deleted file mode 100644 index d977a91f..00000000 --- a/src/main/resources/config/application-demo.properties +++ /dev/null @@ -1,62 +0,0 @@ -# overall server configuration -server.address=0.0.0.0 -server.port=8080 -server.servlet.context-path=/ -server.servlet.session.cookie.http-only=true -server.servlet.session.tracking-modes=cookie - -# database server -datastore.mariadb.server.address=seb-server-mariadb -datastore.mariadb.server.port=3306 - -# data source configuration -spring.datasource.username=root -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.platform=demo -spring.datasource.hikari.initializationFailTimeout=30000 -spring.datasource.hikari.connectionTimeout=30000 -spring.datasource.hikari.idleTimeout=600000 -spring.datasource.hikari.maxLifetime=1800000 - - -# webservice configuration -sebserver.test.property=DEMO SOURCE CONFIG -sebserver.webservice.distributed=false -sebserver.webservice.http.scheme=http -sebserver.webservice.http.server.name=ralph.ethz.ch -sebserver.webservice.http.redirect.gui=${sebserver.gui.entrypoint} -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=-1 -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=86400 -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 -# write logs to -logging.file=log/sebserver.log - -# actuator configuration -management.endpoints.web.base-path=/actuator -management.endpoints.web.exposure.include=logfile,loggers - -# GUI server configuration -sebserver.gui.entrypoint=/gui -sebserver.gui.webservice.protocol=http -sebserver.gui.webservice.address=${server.address} -sebserver.gui.webservice.port=8080 -sebserver.gui.webservice.apipath=/admin-api/v1 -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.multilingual=false -sebserver.gui.languages=en -sebserver.gui.seb.client.config.download.filename=SEBClientSettings.seb -sebserver.gui.seb.exam.config.download.filename=SEBExamSettings.seb diff --git a/src/main/resources/config/application-dev-ws.properties b/src/main/resources/config/application-dev-ws.properties index d8fef63b..88786d0b 100644 --- a/src/main/resources/config/application-dev-ws.properties +++ b/src/main/resources/config/application-dev-ws.properties @@ -22,7 +22,7 @@ spring.quartz.properties.org.quartz.threadPool.threadCount=2 sebserver.webservice.distributed=false sebserver.webservice.http.scheme=http sebserver.webservice.http.server.name=${server.address} - +sebserver.webservice.http.port=${server.port} sebserver.webservice.http.redirect.gui=/gui sebserver.webservice.api.admin.endpoint=/admin-api/v1 sebserver.webservice.api.admin.accessTokenValiditySeconds=3600