diff --git a/src/main/java/ch/ethz/seb/sebserver/webservice/servicelayer/lms/FullLmsIntegrationAPI.java b/src/main/java/ch/ethz/seb/sebserver/webservice/servicelayer/lms/FullLmsIntegrationAPI.java index 0cec3bc0..ffb6817b 100644 --- a/src/main/java/ch/ethz/seb/sebserver/webservice/servicelayer/lms/FullLmsIntegrationAPI.java +++ b/src/main/java/ch/ethz/seb/sebserver/webservice/servicelayer/lms/FullLmsIntegrationAPI.java @@ -31,7 +31,7 @@ public interface FullLmsIntegrationAPI { Result applyExamData(ExamData examData); - Result applyConnectionConfiguration(Exam exam, byte[] configData); + //Result applyConnectionConfiguration(Exam exam, byte[] configData); Result deleteConnectionDetails(); diff --git a/src/main/java/ch/ethz/seb/sebserver/webservice/servicelayer/lms/impl/FullLmsIntegrationServiceImpl.java b/src/main/java/ch/ethz/seb/sebserver/webservice/servicelayer/lms/impl/FullLmsIntegrationServiceImpl.java index 32b27a46..c71d4da1 100644 --- a/src/main/java/ch/ethz/seb/sebserver/webservice/servicelayer/lms/impl/FullLmsIntegrationServiceImpl.java +++ b/src/main/java/ch/ethz/seb/sebserver/webservice/servicelayer/lms/impl/FullLmsIntegrationServiceImpl.java @@ -8,10 +8,7 @@ package ch.ethz.seb.sebserver.webservice.servicelayer.lms.impl; -import java.io.ByteArrayOutputStream; import java.io.OutputStream; -import java.io.PipedInputStream; -import java.io.PipedOutputStream; import java.nio.charset.StandardCharsets; import java.util.Arrays; import java.util.Collection; @@ -53,7 +50,6 @@ import ch.ethz.seb.sebserver.webservice.servicelayer.sebconfig.ConnectionConfigu import ch.ethz.seb.sebserver.webservice.servicelayer.sebconfig.ConnectionConfigurationService; import ch.ethz.seb.sebserver.webservice.servicelayer.session.ExamConfigUpdateEvent; import ch.ethz.seb.sebserver.webservice.servicelayer.session.ScreenProctoringService; -import org.apache.commons.io.IOUtils; import org.apache.commons.lang3.StringUtils; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -152,11 +148,9 @@ public class FullLmsIntegrationServiceImpl implements FullLmsIntegrationService return Result.tryCatch(() -> { if (hasFullIntegration(exam.lmsSetupId)) { this.applyExamData(exam, !exam.active); - this.applyConnectionConfiguration(exam); } return exam; }); - } @Override @@ -245,7 +239,7 @@ public class FullLmsIntegrationServiceImpl implements FullLmsIntegrationService .getOr(Collections.emptyList()) .stream() .filter(exam -> this.needsConnectionConfigurationChange(exam, event.configId)) - .forEach(this::applyConnectionConfiguration); + .forEach(exam -> applyExamData(exam, false)); } @Override @@ -332,8 +326,7 @@ public class FullLmsIntegrationServiceImpl implements FullLmsIntegrationService .map(template -> getQuizData(template, courseId, quizId, examData)) .map(createExam(examTemplateId, showQuitLink, quitPassword)) .map(exam -> applyExamData(exam, false)) - .map(this::applySEBClientRestrictionIfRunning) - .map(this::applyConnectionConfiguration); + .map(this::applySEBClientRestrictionIfRunning); } private Exam applySEBClientRestrictionIfRunning(final Exam exam) { @@ -502,7 +495,6 @@ public class FullLmsIntegrationServiceImpl implements FullLmsIntegrationService .byModelId(examTemplateId) .getOrThrow(); - // import exam final POSTMapper post = new POSTMapper(null, null); post.putIfAbsent(Domain.EXAM.ATTR_EXAM_TEMPLATE_ID, examTemplateId); @@ -526,12 +518,11 @@ public class FullLmsIntegrationServiceImpl implements FullLmsIntegrationService } private Exam checkDeletion(final Exam exam) { - // TODO check if Exam can be deleted according to the Spec - if (exam.status != Exam.ExamStatus.RUNNING) { return exam; } + // if exam is running and has active SEB client connections, it cannot be deleted final Integer active = this.clientConnectionDAO .getAllActiveConnectionTokens(exam.id) .map(Collection::size) @@ -545,15 +536,6 @@ public class FullLmsIntegrationServiceImpl implements FullLmsIntegrationService throw new APIMessage.APIMessageException( APIMessage.ErrorMessage.INTEGRITY_VALIDATION .of("Exam currently has active SEB Client connections.")); - - // check if there are no active SEB client connections -// if (this.examSessionService.hasActiveSEBClientConnections(exam.id)) { -// throw new APIMessage.APIMessageException( -// APIMessage.ErrorMessage.INTEGRITY_VALIDATION -// .of("Exam currently has active SEB Client connections.")); -// } -// -// return exam; } @@ -637,38 +619,37 @@ public class FullLmsIntegrationServiceImpl implements FullLmsIntegrationService } } - private Exam applyConnectionConfiguration(final Exam exam) { - return lmsAPITemplateCacheService - .getLmsAPITemplate(exam.lmsSetupId) - .flatMap(template -> { - final String connectionConfigId = getConnectionConfigurationId(exam); - - final ByteArrayOutputStream out = new ByteArrayOutputStream(); - final PipedOutputStream pout; - final PipedInputStream pin; - try { - pout = new PipedOutputStream(); - pin = new PipedInputStream(pout); - - this.connectionConfigurationService - .exportSEBClientConfiguration(pout, connectionConfigId, exam.id); - - out.flush(); - - IOUtils.copyLarge(pin, out); - - // TODO check if this works as expected - return template.applyConnectionConfiguration(exam, out.toByteArray()); - - } catch (final Exception e) { - throw new RuntimeException("Failed to stream output", e); - } finally { - IOUtils.closeQuietly(out); - } - }) - .onError(error -> log.error("Failed to apply ConnectionConfiguration for exam: {} error: ", exam, error)) - .getOr(exam); - } +// private Exam applyConnectionConfiguration(final Exam exam) { +// return lmsAPITemplateCacheService +// .getLmsAPITemplate(exam.lmsSetupId) +// .flatMap(template -> { +// final String connectionConfigId = getConnectionConfigurationId(exam); +// +// final ByteArrayOutputStream out = new ByteArrayOutputStream(); +// final PipedOutputStream pout; +// final PipedInputStream pin; +// try { +// pout = new PipedOutputStream(); +// pin = new PipedInputStream(pout); +// +// this.connectionConfigurationService +// .exportSEBClientConfiguration(pout, connectionConfigId, exam.id); +// +// out.flush(); +// +// IOUtils.copyLarge(pin, out); +// +// return template.applyConnectionConfiguration(exam, out.toByteArray()); +// +// } catch (final Exception e) { +// throw new RuntimeException("Failed to stream output", e); +// } finally { +// IOUtils.closeQuietly(out); +// } +// }) +// .onError(error -> log.error("Failed to apply ConnectionConfiguration for exam: {} error: ", exam, error)) +// .getOr(exam); +// } private boolean hasFullIntegration(final Long lmsSetupId) { // no LMS diff --git a/src/main/java/ch/ethz/seb/sebserver/webservice/servicelayer/lms/impl/LmsAPITemplateAdapter.java b/src/main/java/ch/ethz/seb/sebserver/webservice/servicelayer/lms/impl/LmsAPITemplateAdapter.java index b08ae3b9..c74558da 100644 --- a/src/main/java/ch/ethz/seb/sebserver/webservice/servicelayer/lms/impl/LmsAPITemplateAdapter.java +++ b/src/main/java/ch/ethz/seb/sebserver/webservice/servicelayer/lms/impl/LmsAPITemplateAdapter.java @@ -546,23 +546,6 @@ public class LmsAPITemplateAdapter implements LmsAPITemplate { .getOrThrow()); } - @Override - public Result applyConnectionConfiguration(final Exam exam, final byte[] configData) { - if (this.lmsIntegrationAPI == null) { - return Result.ofError( - new UnsupportedOperationException("LMS Integration API Not Supported For: " + getType().name())); - } - - if (log.isDebugEnabled()) { - log.debug("Apply Connection Configuration for exam: {} for LMSSetup: {}", exam, lmsSetup()); - } - - return this.examRequest.protectedRun(() -> this.lmsIntegrationAPI - .applyConnectionConfiguration(exam, configData) - .getOrThrow()); - } - - @Override public Result deleteConnectionDetails() { if (this.lmsIntegrationAPI == null) { diff --git a/src/main/java/ch/ethz/seb/sebserver/webservice/servicelayer/lms/impl/ans/AnsLmsAPITemplate.java b/src/main/java/ch/ethz/seb/sebserver/webservice/servicelayer/lms/impl/ans/AnsLmsAPITemplate.java index 7ab90bd5..fc759fae 100644 --- a/src/main/java/ch/ethz/seb/sebserver/webservice/servicelayer/lms/impl/ans/AnsLmsAPITemplate.java +++ b/src/main/java/ch/ethz/seb/sebserver/webservice/servicelayer/lms/impl/ans/AnsLmsAPITemplate.java @@ -444,11 +444,6 @@ public class AnsLmsAPITemplate extends AbstractCachedCourseAccess implements Lms return Result.ofRuntimeError("Not Supported"); } - @Override - public Result applyConnectionConfiguration(final Exam exam, final byte[] configData) { - return Result.ofRuntimeError("Not Supported"); - } - @Override public Result deleteConnectionDetails() { return Result.ofRuntimeError("Not Supported"); diff --git a/src/main/java/ch/ethz/seb/sebserver/webservice/servicelayer/lms/impl/mockup/MockupFullIntegration.java b/src/main/java/ch/ethz/seb/sebserver/webservice/servicelayer/lms/impl/mockup/MockupFullIntegration.java index 4bc628fc..7dff68df 100644 --- a/src/main/java/ch/ethz/seb/sebserver/webservice/servicelayer/lms/impl/mockup/MockupFullIntegration.java +++ b/src/main/java/ch/ethz/seb/sebserver/webservice/servicelayer/lms/impl/mockup/MockupFullIntegration.java @@ -39,11 +39,6 @@ public class MockupFullIntegration implements FullLmsIntegrationAPI { return Result.ofRuntimeError("Not Supported"); } - @Override - public Result applyConnectionConfiguration(final Exam exam, final byte[] configData) { - return Result.ofRuntimeError("Not Supported"); - } - @Override public Result deleteConnectionDetails() { return Result.ofRuntimeError("TODO"); diff --git a/src/main/java/ch/ethz/seb/sebserver/webservice/servicelayer/lms/impl/moodle/MoodleRestTemplateFactoryImpl.java b/src/main/java/ch/ethz/seb/sebserver/webservice/servicelayer/lms/impl/moodle/MoodleRestTemplateFactoryImpl.java index 92d0f861..cac3094d 100644 --- a/src/main/java/ch/ethz/seb/sebserver/webservice/servicelayer/lms/impl/moodle/MoodleRestTemplateFactoryImpl.java +++ b/src/main/java/ch/ethz/seb/sebserver/webservice/servicelayer/lms/impl/moodle/MoodleRestTemplateFactoryImpl.java @@ -452,32 +452,12 @@ public class MoodleRestTemplateFactoryImpl implements MoodleRestTemplateFactory new HttpEntity<>(body, headers); final ResponseEntity exchange = super.exchange( - uri.toString(), + uri.append("?token=").append(this.accessToken).toString(), HttpMethod.POST, requestEntity, String.class); return exchange.getBody(); - -// multiPartAttributes.add("token", this.accessToken.toString()); -// -// queryAttributes.forEach((key, values) -> { -// if (values.isEmpty()) { -// return; -// } -// if (uri.toString().contains("?")) { -// uri.append("&").append(key).append("=").append(values.get(0)); -// } else { -// uri.append("?").append(key).append("=").append(values.get(0)); -// } -// }); -// -// log.info("Upload to Moodle url: {}", uri.toString()); -// -// return super.postForObject( -// uri.toString(), -// multiPartAttributes, -// String.class); } private String doRequest( diff --git a/src/main/java/ch/ethz/seb/sebserver/webservice/servicelayer/lms/impl/moodle/plugin/MoodlePluginFullIntegration.java b/src/main/java/ch/ethz/seb/sebserver/webservice/servicelayer/lms/impl/moodle/plugin/MoodlePluginFullIntegration.java index abcc41c8..e7667050 100644 --- a/src/main/java/ch/ethz/seb/sebserver/webservice/servicelayer/lms/impl/moodle/plugin/MoodlePluginFullIntegration.java +++ b/src/main/java/ch/ethz/seb/sebserver/webservice/servicelayer/lms/impl/moodle/plugin/MoodlePluginFullIntegration.java @@ -239,43 +239,43 @@ public class MoodlePluginFullIntegration implements FullLmsIntegrationAPI { }); } - @Override - public Result applyConnectionConfiguration(final Exam exam, final byte[] configData) { - return Result.tryCatch(() -> { - - final String quizId = MoodleUtils.getQuizId(exam.externalId); - final String fileName = getConnectionConfigFileName(exam); - -// final MultiValueMap multiPartAttributes = new LinkedMultiValueMap<>(); -// multiPartAttributes.add("quizid", quizId); -// multiPartAttributes.add("name", fileName); -// multiPartAttributes.add("filename", fileName); - -// final MultiValueMap queryAttributes = new LinkedMultiValueMap<>(); -// //queryAttributes.add("quizid", quizId); -// final ByteArrayResource contentsAsResource = new ByteArrayResource(configData) { -// @Override -// public String getFilename() { -// return fileName; // Filename has to be returned in order to be able to post. -// } -// }; +// @Override +// public Result applyConnectionConfiguration(final Exam exam, final byte[] configData) { +// return Result.tryCatch(() -> { // -// multiPartAttributes.add("file", contentsAsResource); - - final MoodleAPIRestTemplate rest = getRestTemplate().getOrThrow(); - final String response = rest.uploadMultiPart( - UPLOAD_ENDPOINT, - quizId, - fileName, - configData); - - if (response != null) { - log.info("Upload Connection Configuration to Moodle: quizid: {}, fileName: {} response: {}", quizId, fileName, response ); - } - - return exam; - }); - } +// final String quizId = MoodleUtils.getQuizId(exam.externalId); +// final String fileName = getConnectionConfigFileName(exam); +// +//// final MultiValueMap multiPartAttributes = new LinkedMultiValueMap<>(); +//// multiPartAttributes.add("quizid", quizId); +//// multiPartAttributes.add("name", fileName); +//// multiPartAttributes.add("filename", fileName); +// +//// final MultiValueMap queryAttributes = new LinkedMultiValueMap<>(); +//// //queryAttributes.add("quizid", quizId); +//// final ByteArrayResource contentsAsResource = new ByteArrayResource(configData) { +//// @Override +//// public String getFilename() { +//// return fileName; // Filename has to be returned in order to be able to post. +//// } +//// }; +//// +//// multiPartAttributes.add("file", contentsAsResource); +// +// final MoodleAPIRestTemplate rest = getRestTemplate().getOrThrow(); +// final String response = rest.uploadMultiPart( +// UPLOAD_ENDPOINT, +// quizId, +// fileName, +// configData); +// +// if (response != null) { +// log.info("Upload Connection Configuration to Moodle: quizid: {}, fileName: {} response: {}", quizId, fileName, response ); +// } +// +// return exam; +// }); +// } private String getConnectionConfigFileName(final Exam exam) { return "SEBServerConnectionConfiguration-" + exam.id + ".seb"; @@ -317,7 +317,9 @@ public class MoodlePluginFullIntegration implements FullLmsIntegrationAPI { public Result getQuizDataForRemoteImport(final String examData) { return Result.tryCatch(() -> { - log.info("****** Try to parse import exam data sent by Moodle on Exam import: {}", examData); + if (log.isDebugEnabled()) { + log.debug("Try to parse import exam data sent by Moodle on Exam import: {}", examData); + } final LmsSetup lmsSetup = this.restTemplateFactory.getApiTemplateDataSupplier().getLmsSetup(); final String urlPrefix = (lmsSetup.lmsApiUrl.endsWith(Constants.URL_PATH_SEPARATOR)) diff --git a/src/main/java/ch/ethz/seb/sebserver/webservice/servicelayer/lms/impl/olat/OlatLmsAPITemplate.java b/src/main/java/ch/ethz/seb/sebserver/webservice/servicelayer/lms/impl/olat/OlatLmsAPITemplate.java index 16787900..c928b610 100644 --- a/src/main/java/ch/ethz/seb/sebserver/webservice/servicelayer/lms/impl/olat/OlatLmsAPITemplate.java +++ b/src/main/java/ch/ethz/seb/sebserver/webservice/servicelayer/lms/impl/olat/OlatLmsAPITemplate.java @@ -431,11 +431,6 @@ public class OlatLmsAPITemplate extends AbstractCachedCourseAccess implements Lm return Result.ofRuntimeError("Not Supported"); } - @Override - public Result applyConnectionConfiguration(final Exam exam, final byte[] configData) { - return Result.ofRuntimeError("Not Supported"); - } - @Override public Result deleteConnectionDetails() { return Result.ofRuntimeError("Not Supported");