From 3ce025c4b1ba9d79e0b10f9d9032c418199fa65e Mon Sep 17 00:00:00 2001 From: anhefti Date: Fri, 2 Jun 2023 10:52:52 +0200 Subject: [PATCH 1/4] SEBSERV-449 better timeouts and name search on moodle side --- .../ClientHttpRequestFactoryService.java | 2 +- .../lms/impl/QuizLookupServiceImpl.java | 28 +++++++++++++------ .../plugin/MoodlePluginCourseAccess.java | 18 +++++++++--- .../config/application-dev-ws.properties | 4 +-- .../config/application-ws.properties | 1 + 5 files changed, 38 insertions(+), 15 deletions(-) diff --git a/src/main/java/ch/ethz/seb/sebserver/ClientHttpRequestFactoryService.java b/src/main/java/ch/ethz/seb/sebserver/ClientHttpRequestFactoryService.java index 5272843e..3fd16e75 100644 --- a/src/main/java/ch/ethz/seb/sebserver/ClientHttpRequestFactoryService.java +++ b/src/main/java/ch/ethz/seb/sebserver/ClientHttpRequestFactoryService.java @@ -76,7 +76,7 @@ public class ClientHttpRequestFactoryService { final ClientCredentialService clientCredentialService, @Value("${sebserver.http.client.connect-timeout:15000}") final int connectTimeout, @Value("${sebserver.http.client.connection-request-timeout:20000}") final int connectionRequestTimeout, - @Value("${sebserver.http.client.read-timeout:20000}") final int readTimeout) { + @Value("${sebserver.http.client.read-timeout:30000}") final int readTimeout) { this.environment = environment; this.clientCredentialService = clientCredentialService; diff --git a/src/main/java/ch/ethz/seb/sebserver/webservice/servicelayer/lms/impl/QuizLookupServiceImpl.java b/src/main/java/ch/ethz/seb/sebserver/webservice/servicelayer/lms/impl/QuizLookupServiceImpl.java index e74deed9..cc83fe2e 100644 --- a/src/main/java/ch/ethz/seb/sebserver/webservice/servicelayer/lms/impl/QuizLookupServiceImpl.java +++ b/src/main/java/ch/ethz/seb/sebserver/webservice/servicelayer/lms/impl/QuizLookupServiceImpl.java @@ -22,6 +22,7 @@ import java.util.stream.Collectors; import org.joda.time.DateTime; import org.slf4j.Logger; import org.slf4j.LoggerFactory; +import org.springframework.beans.factory.annotation.Value; import org.springframework.context.annotation.Lazy; import org.springframework.core.env.Environment; import org.springframework.stereotype.Service; @@ -53,16 +54,19 @@ public class QuizLookupServiceImpl implements QuizLookupService { private final UserService userService; private final LmsSetupDAO lmsSetupDAO; private final AsyncRunner asyncRunner; + private final long fetchedDataValiditySeconds; public QuizLookupServiceImpl( final UserService userService, final LmsSetupDAO lmsSetupDAO, final AsyncService asyncService, - final Environment environment) { + final Environment environment, + @Value("${sebserver.webservice.lms.datafetch.validity.seconds:600}") final long fetchedDataValiditySeconds) { this.userService = userService; this.lmsSetupDAO = lmsSetupDAO; this.asyncRunner = asyncService.getAsyncRunner(); + this.fetchedDataValiditySeconds = fetchedDataValiditySeconds; } @Override @@ -158,7 +162,10 @@ public class QuizLookupServiceImpl implements QuizLookupService { } if (!asyncLookup.isValid(filterMap)) { - this.lookups.remove(userId); + final AsyncLookup removed = this.lookups.remove(userId); + if (removed != null) { + removed.cancel(); + } this.createNewAsyncLookup(userId, filterMap, lmsAPITemplateSupplier); } @@ -198,7 +205,12 @@ public class QuizLookupServiceImpl implements QuizLookupService { } final LookupFilterCriteria criteria = new LookupFilterCriteria(filterMap); - final AsyncLookup asyncLookup = new AsyncLookup(userInstitutionId, userId, criteria, buffers); + final AsyncLookup asyncLookup = new AsyncLookup( + userInstitutionId, + userId, + criteria, + buffers, + this.fetchedDataValiditySeconds); if (log.isDebugEnabled()) { log.debug("Create new AsyncLookup: user={} criteria={}", userId, criteria); @@ -278,18 +290,21 @@ public class QuizLookupServiceImpl implements QuizLookupService { final Collection asyncBuffers; final long timeCreated; long timeCompleted = Long.MAX_VALUE; + private final long fetchedDataValiditySeconds; public AsyncLookup( final long institutionId, final String userId, final LookupFilterCriteria lookupFilterCriteria, - final Collection asyncBuffers) { + final Collection asyncBuffers, + final long fetchedDataValiditySeconds) { this.institutionId = institutionId; this.userId = userId; this.lookupFilterCriteria = lookupFilterCriteria; this.asyncBuffers = asyncBuffers; this.timeCreated = Utils.getMillisecondsNow(); + this.fetchedDataValiditySeconds = fetchedDataValiditySeconds; } LookupResult getAvailable() { @@ -307,10 +322,7 @@ public class QuizLookupServiceImpl implements QuizLookupService { boolean isUpToDate() { final long now = Utils.getMillisecondsNow(); - if (now - this.timeCreated > 5 * Constants.MINUTE_IN_MILLIS) { - return false; - } - if (now - this.timeCompleted > Constants.MINUTE_IN_MILLIS) { + if (now - this.timeCreated > this.fetchedDataValiditySeconds * Constants.SECOND_IN_MILLIS) { return false; } return true; diff --git a/src/main/java/ch/ethz/seb/sebserver/webservice/servicelayer/lms/impl/moodle/plugin/MoodlePluginCourseAccess.java b/src/main/java/ch/ethz/seb/sebserver/webservice/servicelayer/lms/impl/moodle/plugin/MoodlePluginCourseAccess.java index 2e3a464e..9148964e 100644 --- a/src/main/java/ch/ethz/seb/sebserver/webservice/servicelayer/lms/impl/moodle/plugin/MoodlePluginCourseAccess.java +++ b/src/main/java/ch/ethz/seb/sebserver/webservice/servicelayer/lms/impl/moodle/plugin/MoodlePluginCourseAccess.java @@ -61,6 +61,7 @@ import ch.ethz.seb.sebserver.webservice.servicelayer.lms.impl.moodle.MoodleUtils import ch.ethz.seb.sebserver.webservice.servicelayer.lms.impl.moodle.MoodleUtils.Courses; import ch.ethz.seb.sebserver.webservice.servicelayer.lms.impl.moodle.MoodleUtils.CoursesPlugin; import ch.ethz.seb.sebserver.webservice.servicelayer.lms.impl.moodle.MoodleUtils.MoodleUserDetails; +import io.micrometer.core.instrument.util.StringUtils; public class MoodlePluginCourseAccess extends AbstractCachedCourseAccess implements CourseAccessAPI { @@ -118,7 +119,7 @@ public class MoodlePluginCourseAccess extends AbstractCachedCourseAccess impleme environment.getProperty( "sebserver.webservice.circuitbreaker.moodleRestCall.blockingTime", Long.class, - Constants.SECOND_IN_MILLIS * 20), + Constants.SECOND_IN_MILLIS * 30), environment.getProperty( "sebserver.webservice.circuitbreaker.moodleRestCall.timeToRecover", Long.class, @@ -184,10 +185,11 @@ public class MoodlePluginCourseAccess extends AbstractCachedCourseAccess impleme quizFromTime = DateTime.now(DateTimeZone.UTC).minusYears(this.cutoffTimeOffset); } final Predicate quizFilter = LmsAPIService.quizFilterPredicate(filterMap); + final String quizName = filterMap.getQuizName(); while (!asyncQuizFetchBuffer.finished && !asyncQuizFetchBuffer.canceled) { try { - fetchQuizzesPage(page, quizFromTime, asyncQuizFetchBuffer, quizFilter); + fetchQuizzesPage(page, quizFromTime, quizName, asyncQuizFetchBuffer, quizFilter); page++; } catch (final Exception e) { log.error("Unexpected error while trying to fetch moodle quiz page: {}", page, e); @@ -371,6 +373,7 @@ public class MoodlePluginCourseAccess extends AbstractCachedCourseAccess impleme private void fetchQuizzesPage( final int page, final DateTime quizFromTime, + final String nameCondition, final AsyncQuizFetchBuffer asyncQuizFetchBuffer, final Predicate quizFilter) throws JsonParseException, JsonMappingException, IOException { @@ -382,7 +385,7 @@ public class MoodlePluginCourseAccess extends AbstractCachedCourseAccess impleme : lmsSetup.lmsApiUrl + Constants.URL_PATH_SEPARATOR + MOODLE_QUIZ_START_URL_PATH; final Collection fetchCoursesPage = - fetchCoursesPage(restTemplate, quizFromTime, page, this.pageSize); + fetchCoursesPage(restTemplate, quizFromTime, nameCondition, page, this.pageSize); // finish if page is empty (no courses left if (fetchCoursesPage.isEmpty()) { asyncQuizFetchBuffer.finish(); @@ -408,6 +411,7 @@ public class MoodlePluginCourseAccess extends AbstractCachedCourseAccess impleme private Collection fetchCoursesPage( final MoodleAPIRestTemplate restTemplate, final DateTime quizFromTime, + final String nameCondition, final int page, final int size) throws JsonParseException, JsonMappingException, IOException { @@ -422,13 +426,19 @@ public class MoodlePluginCourseAccess extends AbstractCachedCourseAccess impleme final long defaultCutOff = Utils.toUnixTimeInSeconds( DateTime.now(DateTimeZone.UTC).minusYears(this.cutoffTimeOffset)); final long cutoffDate = (filterDate < defaultCutOff) ? filterDate : defaultCutOff; - final String sqlCondition = String.format( + String sqlCondition = String.format( SQL_CONDITION_TEMPLATE, String.valueOf(cutoffDate), String.valueOf(filterDate)); final String fromElement = String.valueOf(page * size); final LinkedMultiValueMap attributes = new LinkedMultiValueMap<>(); + if (StringUtils.isNotBlank(nameCondition)) { + sqlCondition = sqlCondition + " AND (m.name LIKE '" + + Utils.toSQLWildcard(nameCondition) + + "')"; + } + // Note: courseid[]=0 means all courses. Moodle don't like empty parameter attributes.add(PARAM_COURSE_ID_ARRAY, "0"); attributes.add(PARAM_SQL_CONDITIONS, sqlCondition); diff --git a/src/main/resources/config/application-dev-ws.properties b/src/main/resources/config/application-dev-ws.properties index 25b871d9..b49bad3b 100644 --- a/src/main/resources/config/application-dev-ws.properties +++ b/src/main/resources/config/application-dev-ws.properties @@ -18,7 +18,7 @@ spring.datasource.hikari.leakDetectionThreshold=2000 sebserver.http.client.connect-timeout=15000 sebserver.http.client.connection-request-timeout=10000 -sebserver.http.client.read-timeout=20000 +sebserver.http.client.read-timeout=30000 sebserver.webservice.distributed.updateInterval=1000 sebserver.webservice.distributed.connectionUpdate=2000 sebserver.webservice.clean-db-on-startup=false @@ -52,7 +52,7 @@ sebserver.webservice.api.pagination.maxPageSize=500 sebserver.webservice.lms.openedx.api.token.request.paths=/oauth2/access_token sebserver.webservice.lms.moodle.api.token.request.paths= sebserver.webservice.lms.address.alias=lms.mockup.com=lms.address.alias -sebserver.webservice.cache.moodle.course.pageSize=10 +sebserver.webservice.cache.moodle.course.pageSize=250 springdoc.api-docs.enabled=true springdoc.swagger-ui.enabled=true diff --git a/src/main/resources/config/application-ws.properties b/src/main/resources/config/application-ws.properties index acafe27a..f215b762 100644 --- a/src/main/resources/config/application-ws.properties +++ b/src/main/resources/config/application-ws.properties @@ -83,6 +83,7 @@ sebserver.webservice.lms.moodle.prependShortCourseName=true sebserver.webservice.lms.moodle.fetch.cutoffdate.yearsBeforeNow=2 sebserver.webservice.lms.olat.sendAdditionalAttributesWithRestriction=false sebserver.webservice.lms.address.alias= +sebserver.webservice.lms.datafetch.validity.seconds=600 sebserver.webservice.proctoring.resetBroadcastOnLeav=true sebserver.webservice.proctoring.zoom.enableWaitingRoom=false From 0d650f9fb62de9ccb5968b255c7c5eba42f84a57 Mon Sep 17 00:00:00 2001 From: anhefti Date: Mon, 5 Jun 2023 16:15:37 +0200 Subject: [PATCH 2/4] SEBSERV-449 improved reload action --- .../gui/content/exam/QuizLookupList.java | 15 +++++++++------ src/main/resources/messages.properties | 1 + 2 files changed, 10 insertions(+), 6 deletions(-) diff --git a/src/main/java/ch/ethz/seb/sebserver/gui/content/exam/QuizLookupList.java b/src/main/java/ch/ethz/seb/sebserver/gui/content/exam/QuizLookupList.java index c95b2c99..374c6704 100644 --- a/src/main/java/ch/ethz/seb/sebserver/gui/content/exam/QuizLookupList.java +++ b/src/main/java/ch/ethz/seb/sebserver/gui/content/exam/QuizLookupList.java @@ -59,6 +59,7 @@ import ch.ethz.seb.sebserver.gui.table.ColumnDefinition.TableFilterAttribute; import ch.ethz.seb.sebserver.gui.table.EntityTable; import ch.ethz.seb.sebserver.gui.table.TableFilter.CriteriaType; import ch.ethz.seb.sebserver.gui.widget.WidgetFactory; +import ch.ethz.seb.sebserver.gui.widget.WidgetFactory.ImageIcon; @Lazy @Component @@ -109,6 +110,8 @@ public class QuizLookupList implements TemplateComposer { new LocTextKey("sebserver.quizdiscovery.quiz.import.existing"); private final static LocTextKey TEXT_FETCH_NOTE = new LocTextKey("sebserver.quizdiscovery.list.fetchnote"); + private final static LocTextKey TEXT_FETCH_NOTE_TOOLTIP = + new LocTextKey("sebserver.quizdiscovery.list.fetchnote.tooltip"); private final static String TEXT_KEY_ADDITIONAL_ATTR_PREFIX = "sebserver.quizdiscovery.quiz.details.additional."; @@ -464,12 +467,12 @@ public class QuizLookupList implements TemplateComposer { gridData.heightHint = 28; gridData.widthHint = 25; gridData.verticalIndent = 5; - final Label action = new Label(warningPanel, SWT.NONE); - action.setImage(WidgetFactory.ImageIcon.SWITCH.getImage(notePanel.getDisplay())); - action.setLayoutData(gridData); - action.addListener(SWT.MouseDown, event -> { - table.applyFilter(); - }); + + this.widgetFactory.imageButton( + ImageIcon.SWITCH, + warningPanel, + TEXT_FETCH_NOTE_TOOLTIP, + event -> table.applyFilter()); final Label text = new Label(warningPanel, SWT.NONE); text.setData(RWT.MARKUP_ENABLED, Boolean.TRUE); diff --git a/src/main/resources/messages.properties b/src/main/resources/messages.properties index 9ebacb9a..2fdf79e6 100644 --- a/src/main/resources/messages.properties +++ b/src/main/resources/messages.properties @@ -448,6 +448,7 @@ sebserver.quizdiscovery.list.column.endtime.tooltip=The end time of the LMS exam sebserver.quizdiscovery.info.pleaseSelect=At first please select an LMS exam from the list sebserver.quizdiscovery.list.action.no.modify.privilege=No Access: A LMS exam from other institution cannot be imported. sebserver.quizdiscovery.list.fetchnote=Note: This list is not complete yet since the service is still fetching data from LMS.
            Use the reload button on the left or the search icon from the list for update. +sebserver.quizdiscovery.list.fetchnote.tooltip=Click to reload the list and get all currently fetched results. sebserver.quizdiscovery.action.list=LMS Exam Lookup sebserver.quizdiscovery.action.import=Import as Exam From a62f06781cd2b685b778721c1f08d73a9d8795e6 Mon Sep 17 00:00:00 2001 From: anhefti Date: Thu, 8 Jun 2023 08:47:55 +0200 Subject: [PATCH 3/4] tomcat settings --- src/main/resources/config/application.properties | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/src/main/resources/config/application.properties b/src/main/resources/config/application.properties index 2f6bd64a..bb56358d 100644 --- a/src/main/resources/config/application.properties +++ b/src/main/resources/config/application.properties @@ -15,6 +15,12 @@ server.servlet.context-path=/ # Tomcat server.tomcat.max-threads=2000 server.tomcat.accept-count=300 +server.tomcat.socket.soKeepAlive=true +server.tomcat.socket.performanceConnectionTime=1 +server.tomcat.socket.performanceLatency=2 +server.tomcat.socket.performanceBandwidth=0 +server.tomcat.keepAliveTimeout(3000); +server.tomcat.maxKeepAliveRequests(3000); server.tomcat.uri-encoding=UTF-8 ### encoding From b2f7337019a3555156704367fd0d115066a606e9 Mon Sep 17 00:00:00 2001 From: anhefti Date: Thu, 8 Jun 2023 15:05:41 +0200 Subject: [PATCH 4/4] SEBSERV-449 fixes --- .../gui/content/exam/QuizLookupList.java | 45 +++++++++---------- .../monitoring/MonitoringRunningExam.java | 2 +- .../i18n/impl/PolyglotPageServiceImpl.java | 11 ++++- .../lms/impl/mockup/MockCourseAccessAPI.java | 3 +- .../plugin/MoodlePluginCourseAccess.java | 9 +++- .../MooldePluginLmsAPITemplateFactory.java | 8 +++- .../config/application-ws.properties | 1 + .../plugin/MoodlePluginCourseAccessTest.java | 3 +- 8 files changed, 51 insertions(+), 31 deletions(-) diff --git a/src/main/java/ch/ethz/seb/sebserver/gui/content/exam/QuizLookupList.java b/src/main/java/ch/ethz/seb/sebserver/gui/content/exam/QuizLookupList.java index 374c6704..4ba77093 100644 --- a/src/main/java/ch/ethz/seb/sebserver/gui/content/exam/QuizLookupList.java +++ b/src/main/java/ch/ethz/seb/sebserver/gui/content/exam/QuizLookupList.java @@ -451,7 +451,7 @@ public class QuizLookupList implements TemplateComposer { } } - private boolean showingFetchNote = false; + private Composite warningPanel = null; private void handelPageReload( final Composite notePanel, @@ -459,29 +459,28 @@ public class QuizLookupList implements TemplateComposer { if (table.isComplete()) { PageService.clearComposite(notePanel); - this.showingFetchNote = false; - } else { - if (!this.showingFetchNote) { - final Composite warningPanel = this.widgetFactory.createWarningPanel(notePanel, 15, true); - GridData gridData = new GridData(SWT.CENTER, SWT.CENTER, false, true); - gridData.heightHint = 28; - gridData.widthHint = 25; - gridData.verticalIndent = 5; - - this.widgetFactory.imageButton( - ImageIcon.SWITCH, - warningPanel, - TEXT_FETCH_NOTE_TOOLTIP, - event -> table.applyFilter()); - - final Label text = new Label(warningPanel, SWT.NONE); - text.setData(RWT.MARKUP_ENABLED, Boolean.TRUE); - text.setText(this.pageService.getI18nSupport().getText(TEXT_FETCH_NOTE)); - gridData = new GridData(SWT.LEFT, SWT.FILL, true, true); - gridData.heightHint = 16; - text.setLayoutData(gridData); - this.showingFetchNote = true; + if (this.warningPanel != null) { + this.warningPanel.dispose(); } + this.warningPanel = null; + } else { + if (this.warningPanel != null && !this.warningPanel.isDisposed()) { + this.warningPanel.dispose(); + } + + this.warningPanel = this.widgetFactory.createWarningPanel(notePanel, 15, true); + this.widgetFactory.imageButton( + ImageIcon.SWITCH, + this.warningPanel, + TEXT_FETCH_NOTE_TOOLTIP, + event -> table.applyFilter()); + + final Label text = new Label(this.warningPanel, SWT.NONE); + text.setData(RWT.MARKUP_ENABLED, Boolean.TRUE); + text.setText(this.pageService.getI18nSupport().getText(TEXT_FETCH_NOTE)); + final GridData gridData = new GridData(SWT.LEFT, SWT.FILL, true, true); + gridData.heightHint = 28; + text.setLayoutData(gridData); } notePanel.getParent().layout(true, true); } diff --git a/src/main/java/ch/ethz/seb/sebserver/gui/content/monitoring/MonitoringRunningExam.java b/src/main/java/ch/ethz/seb/sebserver/gui/content/monitoring/MonitoringRunningExam.java index ea3664ac..c33c5e50 100644 --- a/src/main/java/ch/ethz/seb/sebserver/gui/content/monitoring/MonitoringRunningExam.java +++ b/src/main/java/ch/ethz/seb/sebserver/gui/content/monitoring/MonitoringRunningExam.java @@ -154,7 +154,7 @@ public class MonitoringRunningExam implements TemplateComposer { pageContext.getParent(), new LocTextKey( "sebserver.monitoring.exam", - StringEscapeUtils.escapeHtml4(exam.name))); + StringEscapeUtils.escapeXml11(exam.name))); final Composite tablePane = new Composite(content, SWT.NONE); tablePane.setLayout(new GridLayout()); diff --git a/src/main/java/ch/ethz/seb/sebserver/gui/service/i18n/impl/PolyglotPageServiceImpl.java b/src/main/java/ch/ethz/seb/sebserver/gui/service/i18n/impl/PolyglotPageServiceImpl.java index 1ddf4989..bc1beaf2 100644 --- a/src/main/java/ch/ethz/seb/sebserver/gui/service/i18n/impl/PolyglotPageServiceImpl.java +++ b/src/main/java/ch/ethz/seb/sebserver/gui/service/i18n/impl/PolyglotPageServiceImpl.java @@ -270,7 +270,16 @@ public final class PolyglotPageServiceImpl implements PolyglotPageService { return label -> { if (locTextKey != null) { - label.setText(i18nSupport.getText(locTextKey)); + try { + label.setText(i18nSupport.getText(locTextKey)); + } catch (final Exception e) { + label.setData(RWT.MARKUP_ENABLED, false); + try { + label.setText(i18nSupport.getText(locTextKey)); + } catch (final Exception ee) { + label.setText(locTextKey.name); + } + } } if (i18nSupport.hasText(locToolTipKey)) { label.setToolTipText(Utils.formatLineBreaks(i18nSupport.getText(locToolTipKey))); diff --git a/src/main/java/ch/ethz/seb/sebserver/webservice/servicelayer/lms/impl/mockup/MockCourseAccessAPI.java b/src/main/java/ch/ethz/seb/sebserver/webservice/servicelayer/lms/impl/mockup/MockCourseAccessAPI.java index c8bf545a..e5db1a9b 100644 --- a/src/main/java/ch/ethz/seb/sebserver/webservice/servicelayer/lms/impl/mockup/MockCourseAccessAPI.java +++ b/src/main/java/ch/ethz/seb/sebserver/webservice/servicelayer/lms/impl/mockup/MockCourseAccessAPI.java @@ -63,7 +63,8 @@ public class MockCourseAccessAPI implements CourseAccessAPI { "quiz1", institutionId, lmsSetupId, lmsType, "Demo Quiz 1 (MOCKUP)", "

Demo Quiz Mockup

", "2020-01-01T09:00:00Z", null, "http://lms.mockup.com/api/")); this.mockups.add(new QuizData( - "quiz2", institutionId, lmsSetupId, lmsType, "Demo Quiz 2 (MOCKUP)", "

Demo Quiz Mockup

", + "quiz2", institutionId, lmsSetupId, lmsType, "Demo Quiz 2 (MOCKUP) äöüèÜÄÖ ?< ", + "

Demo Quiz Mockup

", "2020-01-01T09:00:00Z", "2025-01-01T09:00:00Z", "http://lms.mockup.com/api/")); this.mockups.add(new QuizData( "quiz3", institutionId, lmsSetupId, lmsType, "Demo Quiz 3 (MOCKUP)", "

Demo Quiz Mockup

", diff --git a/src/main/java/ch/ethz/seb/sebserver/webservice/servicelayer/lms/impl/moodle/plugin/MoodlePluginCourseAccess.java b/src/main/java/ch/ethz/seb/sebserver/webservice/servicelayer/lms/impl/moodle/plugin/MoodlePluginCourseAccess.java index 9148964e..2321adeb 100644 --- a/src/main/java/ch/ethz/seb/sebserver/webservice/servicelayer/lms/impl/moodle/plugin/MoodlePluginCourseAccess.java +++ b/src/main/java/ch/ethz/seb/sebserver/webservice/servicelayer/lms/impl/moodle/plugin/MoodlePluginCourseAccess.java @@ -93,6 +93,7 @@ public class MoodlePluginCourseAccess extends AbstractCachedCourseAccess impleme private final int pageSize; private final int maxSize; private final int cutoffTimeOffset; + private final boolean applyNameCriteria; private MoodleAPIRestTemplate restTemplate; @@ -101,11 +102,13 @@ public class MoodlePluginCourseAccess extends AbstractCachedCourseAccess impleme final AsyncService asyncService, final MoodleRestTemplateFactory restTemplateFactory, final CacheManager cacheManager, - final Environment environment) { + final Environment environment, + final boolean applyNameCriteria) { super(cacheManager); this.jsonMapper = jsonMapper; this.restTemplateFactory = restTemplateFactory; + this.applyNameCriteria = applyNameCriteria; this.prependShortCourseName = BooleanUtils.toBoolean(environment.getProperty( "sebserver.webservice.lms.moodle.prependShortCourseName", @@ -433,7 +436,9 @@ public class MoodlePluginCourseAccess extends AbstractCachedCourseAccess impleme final String fromElement = String.valueOf(page * size); final LinkedMultiValueMap attributes = new LinkedMultiValueMap<>(); - if (StringUtils.isNotBlank(nameCondition)) { + // TODO clarify with Amr and Luca if this is OK + // and if it is possible to apply the nameCondition also the the course name (shortname) + if (this.applyNameCriteria && StringUtils.isNotBlank(nameCondition)) { sqlCondition = sqlCondition + " AND (m.name LIKE '" + Utils.toSQLWildcard(nameCondition) + "')"; diff --git a/src/main/java/ch/ethz/seb/sebserver/webservice/servicelayer/lms/impl/moodle/plugin/MooldePluginLmsAPITemplateFactory.java b/src/main/java/ch/ethz/seb/sebserver/webservice/servicelayer/lms/impl/moodle/plugin/MooldePluginLmsAPITemplateFactory.java index b455e7b8..7b027a1e 100644 --- a/src/main/java/ch/ethz/seb/sebserver/webservice/servicelayer/lms/impl/moodle/plugin/MooldePluginLmsAPITemplateFactory.java +++ b/src/main/java/ch/ethz/seb/sebserver/webservice/servicelayer/lms/impl/moodle/plugin/MooldePluginLmsAPITemplateFactory.java @@ -46,6 +46,7 @@ public class MooldePluginLmsAPITemplateFactory implements LmsAPITemplateFactory private final ExamConfigurationValueService examConfigurationValueService; private final ClientHttpRequestFactoryService clientHttpRequestFactoryService; private final String[] alternativeTokenRequestPaths; + private final boolean applyNameCriteria; protected MooldePluginLmsAPITemplateFactory( final JSONMapper jsonMapper, @@ -55,7 +56,8 @@ public class MooldePluginLmsAPITemplateFactory implements LmsAPITemplateFactory final ClientCredentialService clientCredentialService, final ExamConfigurationValueService examConfigurationValueService, final ClientHttpRequestFactoryService clientHttpRequestFactoryService, - @Value("${sebserver.webservice.lms.moodle.api.token.request.paths:}") final String alternativeTokenRequestPaths) { + @Value("${sebserver.webservice.lms.moodle.api.token.request.paths:}") final String alternativeTokenRequestPaths, + @Value("${sebserver.webservice.lms.moodle.fetch.applyNameCriteria:false}") final boolean applyNameCriteria) { this.jsonMapper = jsonMapper; this.cacheManager = cacheManager; @@ -67,6 +69,7 @@ public class MooldePluginLmsAPITemplateFactory implements LmsAPITemplateFactory this.alternativeTokenRequestPaths = (alternativeTokenRequestPaths != null) ? StringUtils.split(alternativeTokenRequestPaths, Constants.LIST_SEPARATOR) : null; + this.applyNameCriteria = applyNameCriteria; } @Override @@ -90,7 +93,8 @@ public class MooldePluginLmsAPITemplateFactory implements LmsAPITemplateFactory this.asyncService, moodleRestTemplateFactory, this.cacheManager, - this.environment); + this.environment, + this.applyNameCriteria); final MoodlePluginCourseRestriction moodlePluginCourseRestriction = new MoodlePluginCourseRestriction( this.jsonMapper, diff --git a/src/main/resources/config/application-ws.properties b/src/main/resources/config/application-ws.properties index f215b762..f3568646 100644 --- a/src/main/resources/config/application-ws.properties +++ b/src/main/resources/config/application-ws.properties @@ -81,6 +81,7 @@ sebserver.webservice.lms.openedx.api.token.request.paths=/oauth2/access_token sebserver.webservice.lms.moodle.api.token.request.paths=/login/token.php sebserver.webservice.lms.moodle.prependShortCourseName=true sebserver.webservice.lms.moodle.fetch.cutoffdate.yearsBeforeNow=2 +sebserver.webservice.lms.moodle.fetch.applyNameCriteria=false sebserver.webservice.lms.olat.sendAdditionalAttributesWithRestriction=false sebserver.webservice.lms.address.alias= sebserver.webservice.lms.datafetch.validity.seconds=600 diff --git a/src/test/java/ch/ethz/seb/sebserver/webservice/servicelayer/lms/impl/moodle/plugin/MoodlePluginCourseAccessTest.java b/src/test/java/ch/ethz/seb/sebserver/webservice/servicelayer/lms/impl/moodle/plugin/MoodlePluginCourseAccessTest.java index 924b8875..75a659be 100644 --- a/src/test/java/ch/ethz/seb/sebserver/webservice/servicelayer/lms/impl/moodle/plugin/MoodlePluginCourseAccessTest.java +++ b/src/test/java/ch/ethz/seb/sebserver/webservice/servicelayer/lms/impl/moodle/plugin/MoodlePluginCourseAccessTest.java @@ -324,7 +324,8 @@ public class MoodlePluginCourseAccessTest { asyncService, moodleMockupRestTemplateFactory, new NoOpCacheManager(), - mockEnvironment); + mockEnvironment, + false); } }