code cleanup
This commit is contained in:
		
							parent
							
								
									0b86af5859
								
							
						
					
					
						commit
						ae9fd0636a
					
				
					 27 changed files with 40 additions and 229 deletions
				
			
		| 
						 | 
				
			
			@ -29,7 +29,7 @@ public enum PrivilegeType {
 | 
			
		|||
     * and so on.
 | 
			
		||||
     *
 | 
			
		||||
     * @param type the PrivilegeType
 | 
			
		||||
     * @return true if given PrivilegeType is implicit form this PrivilegeType */
 | 
			
		||||
     * @return true if given PrivilegeType is implicit from this PrivilegeType */
 | 
			
		||||
    public boolean hasImplicit(final PrivilegeType type) {
 | 
			
		||||
        if (type == null) {
 | 
			
		||||
            return false;
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -36,7 +36,7 @@ public class AsyncService {
 | 
			
		|||
     *
 | 
			
		||||
     * @param maxFailingAttempts maximal number of attempts the CircuitBreaker allows before going onto open state.
 | 
			
		||||
     * @param maxBlockingTime maximal time since call CircuitBreaker waits for a response before going onto open state.
 | 
			
		||||
     * @param timeToRecover the time the CircuitBreaker takes to recover form open state.
 | 
			
		||||
     * @param timeToRecover the time the CircuitBreaker takes to recover from open state.
 | 
			
		||||
     * @param <T> the type of the CircuitBreaker
 | 
			
		||||
     * @return a CircuitBreaker of specified type */
 | 
			
		||||
    public <T> CircuitBreaker<T> createCircuitBreaker(
 | 
			
		||||
| 
						 | 
				
			
			@ -57,7 +57,7 @@ public class AsyncService {
 | 
			
		|||
     * @param blockingSupplier the blocking result supplier that the MemoizingCircuitBreaker must call
 | 
			
		||||
     * @param maxFailingAttempts maximal number of attempts the CircuitBreaker allows before going onto open state.
 | 
			
		||||
     * @param maxBlockingTime maximal time since call CircuitBreaker waits for a response before going onto open state.
 | 
			
		||||
     * @param timeToRecover the time the CircuitBreaker takes to recover form open state.
 | 
			
		||||
     * @param timeToRecover the time the CircuitBreaker takes to recover from open state.
 | 
			
		||||
     * @param momoized whether the memoizing functionality is on or off
 | 
			
		||||
     * @param maxMemoizingTime the maximal time memorized data is valid
 | 
			
		||||
     * @param <T> the type of the CircuitBreaker
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -94,7 +94,7 @@ public final class MemoizingCircuitBreaker<T> implements Supplier<Result<T>> {
 | 
			
		|||
     *
 | 
			
		||||
     * @param asyncRunner the AsyncRunner used to create asynchronous calls on the given supplier function
 | 
			
		||||
     * @param supplier The Supplier function that can fail or block for a long time
 | 
			
		||||
     * @param maxFailingAttempts the number of maximal failing attempts before go form CLOSE into HALF_OPEN state
 | 
			
		||||
     * @param maxFailingAttempts the number of maximal failing attempts before go from CLOSE into HALF_OPEN state
 | 
			
		||||
     * @param maxBlockingTime the maximal time that an call attempt can block until an error is responded
 | 
			
		||||
     * @param timeToRecover the time the circuit breaker needs to cool-down on OPEN-STATE before going back to HALF_OPEN
 | 
			
		||||
     *            state
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -55,13 +55,13 @@ public interface ClientCredentialService {
 | 
			
		|||
        return encryptClientCredentials(clientIdPlaintext, secretPlaintext, null);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /** Use this to get a decrypted plain text secret form given ClientCredentials
 | 
			
		||||
    /** Use this to get a decrypted plain text secret from given ClientCredentials
 | 
			
		||||
     *
 | 
			
		||||
     * @param credentials ClientCredentials containing the secret to decrypt
 | 
			
		||||
     * @return decrypted plain text secret */
 | 
			
		||||
    Result<CharSequence> getPlainClientSecret(ClientCredentials credentials);
 | 
			
		||||
 | 
			
		||||
    /** Use this to get a decrypted plain text accessToken form given ClientCredentials
 | 
			
		||||
    /** Use this to get a decrypted plain text accessToken from given ClientCredentials
 | 
			
		||||
     *
 | 
			
		||||
     * @param credentials ClientCredentials containing the accessToken to decrypt
 | 
			
		||||
     * @return decrypted plain text accessToken */
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -48,7 +48,7 @@ public interface Entity extends ModelIdAware {
 | 
			
		|||
 | 
			
		||||
    /** Creates an EntityName instance from this Entity instance.
 | 
			
		||||
     *
 | 
			
		||||
     * @return EntityName instance created form given Entity */
 | 
			
		||||
     * @return EntityName instance created from given Entity */
 | 
			
		||||
    default EntityName toName() {
 | 
			
		||||
        return new EntityName(
 | 
			
		||||
                this.getModelId(),
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -231,7 +231,7 @@ public final class InstitutionalAuthenticationEntryPoint implements Authenticati
 | 
			
		|||
            final Object attribute = RWT.getUISession().getHttpSession().getAttribute(INST_SUFFIX_ATTRIBUTE);
 | 
			
		||||
            return (attribute != null) ? String.valueOf(attribute) : null;
 | 
			
		||||
        } catch (final Exception e) {
 | 
			
		||||
            log.warn("Failed to extract institutional endpoint form user session: {}", e.getMessage());
 | 
			
		||||
            log.warn("Failed to extract institutional endpoint from user session: {}", e.getMessage());
 | 
			
		||||
            return null;
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -108,7 +108,7 @@ public class SEBExamConfigBatchStateChangePopup extends AbstractBatchActionWizar
 | 
			
		|||
 | 
			
		||||
        final String targetStateName = pageContext.getAttribute(ATTR_SELECTED_TARGET_STATE);
 | 
			
		||||
        if (StringUtils.isBlank(targetStateName)) {
 | 
			
		||||
            throw new IllegalArgumentException("missing " + ATTR_SELECTED_TARGET_STATE + " form pageContext");
 | 
			
		||||
            throw new IllegalArgumentException("missing " + ATTR_SELECTED_TARGET_STATE + " from pageContext");
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        batchActionRequestBuilder.withFormParam(BatchAction.ACTION_ATTRIBUT_TARGET_STATE, targetStateName);
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -70,7 +70,7 @@ public final class Form implements FormBinding {
 | 
			
		|||
            flush();
 | 
			
		||||
            return this.jsonMapper.writeValueAsString(this.objectRoot);
 | 
			
		||||
        } catch (final Exception e) {
 | 
			
		||||
            throw new RuntimeException("Unexpected error while trying to create json form Form post: ", e);
 | 
			
		||||
            throw new RuntimeException("Unexpected error while trying to create json from form post: ", e);
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -168,7 +168,7 @@ public class TableFieldBuilder extends AbstractTableFieldBuilder {
 | 
			
		|||
 | 
			
		||||
        private void addRow() {
 | 
			
		||||
            final int index = this.values.size();
 | 
			
		||||
            // create new values form default values
 | 
			
		||||
            // create new values from default values
 | 
			
		||||
            final Map<Long, TableValue> rowValues = this.tableContext.getRowAttributes()
 | 
			
		||||
                    .stream()
 | 
			
		||||
                    .map(attr -> new TableValue(attr.id, index, attr.defaultValue))
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -43,7 +43,7 @@ public interface I18nSupport {
 | 
			
		|||
     * This uses the date-format defined by either the attribute 'sebserver.gui.date.display format'
 | 
			
		||||
     * or the Constants.DEFAULT_DISPLAY_DATE_FORMAT
 | 
			
		||||
     *
 | 
			
		||||
     * Adds time-zone offset information if the currents user time-zone is different form UTC
 | 
			
		||||
     * Adds time-zone offset information if the currents user time-zone is different from UTC
 | 
			
		||||
     *
 | 
			
		||||
     * @param date the DateTime instance
 | 
			
		||||
     * @return date formatted date String to display */
 | 
			
		||||
| 
						 | 
				
			
			@ -53,7 +53,7 @@ public interface I18nSupport {
 | 
			
		|||
     * This uses the date-format defined by either the attribute 'sebserver.gui.date.display format'
 | 
			
		||||
     * or the Constants.DEFAULT_DISPLAY_DATE_FORMAT
 | 
			
		||||
     *
 | 
			
		||||
     * Adds time-zone offset information if the currents user time-zone is different form UTC
 | 
			
		||||
     * Adds time-zone offset information if the currents user time-zone is different from UTC
 | 
			
		||||
     *
 | 
			
		||||
     * @param date the DateTime instance
 | 
			
		||||
     * @return date formatted date String to display */
 | 
			
		||||
| 
						 | 
				
			
			@ -65,7 +65,7 @@ public interface I18nSupport {
 | 
			
		|||
     * This uses the date-format defined by either the attribute 'sebserver.gui.date.display format'
 | 
			
		||||
     * or the Constants.DEFAULT_DISPLAY_DATE_FORMAT
 | 
			
		||||
     *
 | 
			
		||||
     * Adds time-zone information if the currents user time-zone is different form UTC
 | 
			
		||||
     * Adds time-zone information if the currents user time-zone is different from UTC
 | 
			
		||||
     *
 | 
			
		||||
     * @param timestamp the unix-timestamp in milliseconds
 | 
			
		||||
     * @return date formatted date String to display */
 | 
			
		||||
| 
						 | 
				
			
			@ -77,7 +77,7 @@ public interface I18nSupport {
 | 
			
		|||
     * This uses the date-format defined by either the attribute 'sebserver.gui.datetime.display format'
 | 
			
		||||
     * or the Constants.DEFAULT_DISPLAY_DATE_TIME_FORMAT
 | 
			
		||||
     *
 | 
			
		||||
     * Adds time-zone information if the currents user time-zone is different form UTC
 | 
			
		||||
     * Adds time-zone information if the currents user time-zone is different from UTC
 | 
			
		||||
     *
 | 
			
		||||
     * @param date the DateTime instance
 | 
			
		||||
     * @return date formatted date time String to display */
 | 
			
		||||
| 
						 | 
				
			
			@ -87,7 +87,7 @@ public interface I18nSupport {
 | 
			
		|||
     * This uses the date-format defined by either the attribute 'sebserver.gui.datetime.display format'
 | 
			
		||||
     * or the Constants.DEFAULT_DISPLAY_DATE_TIME_FORMAT
 | 
			
		||||
     *
 | 
			
		||||
     * Adds time-zone information if the currents user time-zone is different form UTC
 | 
			
		||||
     * Adds time-zone information if the currents user time-zone is different from UTC
 | 
			
		||||
     *
 | 
			
		||||
     * @param timestamp the unix-timestamp in milliseconds
 | 
			
		||||
     * @return date formatted date time String to display */
 | 
			
		||||
| 
						 | 
				
			
			@ -99,7 +99,7 @@ public interface I18nSupport {
 | 
			
		|||
     * This uses the date-format defined by either the attribute 'sebserver.gui.time.display format'
 | 
			
		||||
     * or the Constants.DEFAULT_DISPLAY_TIME_FORMAT
 | 
			
		||||
     *
 | 
			
		||||
     * Adds time-zone information if the currents user time-zone is different form UTC
 | 
			
		||||
     * Adds time-zone information if the currents user time-zone is different from UTC
 | 
			
		||||
     *
 | 
			
		||||
     * @param date the DateTime instance
 | 
			
		||||
     * @return date formatted time String to display */
 | 
			
		||||
| 
						 | 
				
			
			@ -109,7 +109,7 @@ public interface I18nSupport {
 | 
			
		|||
     * This uses the date-format defined by either the attribute 'sebserver.gui.time.display format'
 | 
			
		||||
     * or the Constants.DEFAULT_DISPLAY_TIME_FORMAT
 | 
			
		||||
     *
 | 
			
		||||
     * Adds time-zone information if the currents user time-zone is different form UTC
 | 
			
		||||
     * Adds time-zone information if the currents user time-zone is different from UTC
 | 
			
		||||
     *
 | 
			
		||||
     * @param timestamp the unix-timestamp in milliseconds
 | 
			
		||||
     * @return date formatted time String to display */
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -716,7 +716,7 @@ public class EntityTable<ROW extends ModelIdAware> {
 | 
			
		|||
                return 1;
 | 
			
		||||
            }
 | 
			
		||||
        } catch (final Exception e) {
 | 
			
		||||
            log.error("Failed to get sort attribute form current user attributes", e);
 | 
			
		||||
            log.error("Failed to get sort attribute from current user attributes", e);
 | 
			
		||||
            return 1;
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
| 
						 | 
				
			
			@ -757,7 +757,7 @@ public class EntityTable<ROW extends ModelIdAware> {
 | 
			
		|||
            setTableSort();
 | 
			
		||||
 | 
			
		||||
        } catch (final Exception e) {
 | 
			
		||||
            log.error("Failed to get sort attribute form current user attributes", e);
 | 
			
		||||
            log.error("Failed to get sort attribute from current user attributes", e);
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -794,7 +794,7 @@ public class EntityTable<ROW extends ModelIdAware> {
 | 
			
		|||
                                .getCurrentUser()
 | 
			
		||||
                                .getAttribute(this.filterAttrName));
 | 
			
		||||
            } catch (final Exception e) {
 | 
			
		||||
                log.error("Failed to get filter attributes form current user attributes", e);
 | 
			
		||||
                log.error("Failed to get filter attributes from current user attributes", e);
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -233,7 +233,7 @@ public class WebserviceInfo {
 | 
			
		|||
        return InetAddress.getLoopbackAddress().getHostAddress();
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /** Get the server URL prefix in form of;
 | 
			
		||||
    /** Get the server URL prefix in the form of;
 | 
			
		||||
     * [scheme{http|https}]://[server-address{DNS-name|IP}]:[port]
 | 
			
		||||
     *
 | 
			
		||||
     * E.g.: https://seb.server.ch:8080
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -19,7 +19,7 @@ import ch.ethz.seb.sebserver.gbl.model.Entity;
 | 
			
		|||
import ch.ethz.seb.sebserver.gbl.model.Page;
 | 
			
		||||
import ch.ethz.seb.sebserver.gbl.util.Result;
 | 
			
		||||
 | 
			
		||||
/** A service to apply pagination functionality within collection results form data access layer.
 | 
			
		||||
/** A service to apply pagination functionality within collection results from data access layer.
 | 
			
		||||
 * The default implementation uses Mybatis-PageHelper to apply the pagination on SQL level where possible:
 | 
			
		||||
 * https://github.com/pagehelper/Mybatis-PageHelper */
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -56,7 +56,7 @@ public interface BulkActionService {
 | 
			
		|||
     * If the given BulkAction has not already been executed, it will be executed first
 | 
			
		||||
     *
 | 
			
		||||
     * @param action the BulkAction of a concrete type
 | 
			
		||||
     * @return EntityProcessingReport extracted form an executed BulkAction */
 | 
			
		||||
     * @return EntityProcessingReport extracted from an executed BulkAction */
 | 
			
		||||
    Result<EntityProcessingReport> createReport(BulkAction action);
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			@ -45,7 +45,7 @@ public interface ClientInstructionDAO {
 | 
			
		|||
     * @return Collection of all active instructions for specified connection token */
 | 
			
		||||
    Result<Collection<ClientInstructionRecord>> getAllActive(String connectionToken);
 | 
			
		||||
 | 
			
		||||
    /** Deletes all old instructions form the persistent storage to clean-up.
 | 
			
		||||
    /** Deletes all old instructions from the persistent storage to clean-up.
 | 
			
		||||
     * Old in this case means the timestamp is older then one minute or a configured time interval
 | 
			
		||||
     *
 | 
			
		||||
     * @param timestamp the time-stamp (milliseconds) of the time in the past from that earlier instructions are
 | 
			
		||||
| 
						 | 
				
			
			@ -53,7 +53,7 @@ public interface ClientInstructionDAO {
 | 
			
		|||
     * @return Result collection of keys of deleted entities or refer to an error when happened */
 | 
			
		||||
    Result<Collection<EntityKey>> deleteAllInactive(long timestamp);
 | 
			
		||||
 | 
			
		||||
    /** Deletes the specified instruction form the data base
 | 
			
		||||
    /** Deletes the specified instruction from the data base
 | 
			
		||||
     *
 | 
			
		||||
     * @param id the identifier (PK) if the ClientInstruction to delete
 | 
			
		||||
     * @return Void Result refer to an error if happened */
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -38,7 +38,7 @@ public interface ConfigurationDAO extends EntityDAO<Configuration, Configuration
 | 
			
		|||
    /** Saves the current follow-up Configuration of the ConfigurationNode of given id
 | 
			
		||||
     * as a point in history and creates new new follow-up Configuration.
 | 
			
		||||
     *
 | 
			
		||||
     * @param configurationNodeId the identifier of the ConfigurationNode to create a new history entry form current
 | 
			
		||||
     * @param configurationNodeId the identifier of the ConfigurationNode to create a new history entry from current
 | 
			
		||||
     *            follow-up
 | 
			
		||||
     * @return the new follow-up Configuration model */
 | 
			
		||||
    Result<Configuration> saveToHistory(Long configurationNodeId);
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -148,14 +148,14 @@ public interface EntityDAO<T extends Entity, M extends ModelIdAware> {
 | 
			
		|||
     * @return Result referring to collection of all matching entities or an error if happened */
 | 
			
		||||
    Result<Collection<T>> allMatching(FilterMap filterMap, Predicate<T> predicate);
 | 
			
		||||
 | 
			
		||||
    /** Context based utility method to extract an expected single resource entry form a Collection of specified type.
 | 
			
		||||
     * Gets a Result refer to an expected single resource entry form a Collection of specified type or refer
 | 
			
		||||
    /** Context based utility method to extract an expected single resource entry from a Collection of specified type.
 | 
			
		||||
     * Gets a Result refer to an expected single resource entry from a Collection of specified type or refer
 | 
			
		||||
     * to a ResourceNotFoundException if specified collection is null or empty or refer to a
 | 
			
		||||
     * unexpected RuntimeException if there are more then the expected single element in the given collection
 | 
			
		||||
     *
 | 
			
		||||
     * @param id The resource id to wrap within a ResourceNotFoundException if needed
 | 
			
		||||
     * @param resources the collection of resource entries
 | 
			
		||||
     * @return Result refer to an expected single resource entry form a Collection of specified type or refer to an
 | 
			
		||||
     * @return Result refer to an expected single resource entry from a Collection of specified type or refer to an
 | 
			
		||||
     *         error if happened */
 | 
			
		||||
    default <R> Result<R> getSingleResource(final String id, final Collection<R> resources) {
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -89,7 +89,7 @@ public interface ExamDAO extends ActivatableEntityDAO<Exam, Exam>, BulkActionSup
 | 
			
		|||
            final Predicate<Exam> predicate,
 | 
			
		||||
            final ExamStatus... status);
 | 
			
		||||
 | 
			
		||||
    /** Gets all for active and none archived exams within the system, independently form institution and LMSSetup.
 | 
			
		||||
    /** Gets all for active and none archived exams within the system, independently from institution and LMSSetup.
 | 
			
		||||
     *
 | 
			
		||||
     * @return Result refer to all exams for LMS update or to an error when happened */
 | 
			
		||||
    Result<Collection<Exam>> allForLMSUpdate();
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -239,7 +239,7 @@ public class CertificateDAOImpl implements CertificateDAO {
 | 
			
		|||
                return dn.replace(" ", "_").toLowerCase();
 | 
			
		||||
            }
 | 
			
		||||
        } catch (final CertificateEncodingException e) {
 | 
			
		||||
            log.warn("Error while trying to get alias form certificate subject name. Use serial number as alias");
 | 
			
		||||
            log.warn("Error while trying to get alias from certificate subject name. Use serial number as alias");
 | 
			
		||||
            return String.valueOf(certificate.getSerialNumber());
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -187,9 +187,9 @@ public class ExamDAOImpl implements ExamDAO {
 | 
			
		|||
    public void markLMSAvailability(final String externalQuizId, final boolean available, final String updateId) {
 | 
			
		||||
 | 
			
		||||
        if (!available) {
 | 
			
		||||
            log.info("Mark exam quiz data not available form LMS: {}", externalQuizId);
 | 
			
		||||
            log.info("Mark exam quiz data not available from LMS: {}", externalQuizId);
 | 
			
		||||
        } else {
 | 
			
		||||
            log.info("Mark exam quiz data back again form LMS: {}", externalQuizId);
 | 
			
		||||
            log.info("Mark exam quiz data back again from LMS: {}", externalQuizId);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        this.examRecordDAO.idByExternalQuizId(externalQuizId)
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -127,7 +127,7 @@ public class ExamTemplateServiceImpl implements ExamTemplateService {
 | 
			
		|||
                    if (exam.examTemplateId != null) {
 | 
			
		||||
 | 
			
		||||
                        if (log.isDebugEnabled()) {
 | 
			
		||||
                            log.debug("Init exam: {} with additional attributes form exam template: {}",
 | 
			
		||||
                            log.debug("Init exam: {} with additional attributes from exam template: {}",
 | 
			
		||||
                                    exam.externalId,
 | 
			
		||||
                                    exam.examTemplateId);
 | 
			
		||||
                        }
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -60,7 +60,7 @@ public interface LmsAPIService {
 | 
			
		|||
     * @param pageSize the page size
 | 
			
		||||
     * @param sort the sort parameter
 | 
			
		||||
     * @param filterMap the FilterMap containing all filter criteria
 | 
			
		||||
     * @return the specified Page of QuizData form all active LMS Setups of the current users institution */
 | 
			
		||||
     * @return the specified Page of QuizData from all active LMS Setups of the current users institution */
 | 
			
		||||
    Result<Page<QuizData>> requestQuizDataPage(
 | 
			
		||||
            final int pageNumber,
 | 
			
		||||
            final int pageSize,
 | 
			
		||||
| 
						 | 
				
			
			@ -139,7 +139,7 @@ public interface LmsAPIService {
 | 
			
		|||
     * @param sortAttribute the sort attribute for the new Page
 | 
			
		||||
     * @param pageNumber the number of the Page to build
 | 
			
		||||
     * @param pageSize the size of the Page to build
 | 
			
		||||
     * @return A Page of QuizData extracted form a given list of QuizData */
 | 
			
		||||
     * @return A Page of QuizData extracted from a given list of QuizData */
 | 
			
		||||
    static Function<List<QuizData>, Page<QuizData>> quizzesToPageFunction(
 | 
			
		||||
            final String sortAttribute,
 | 
			
		||||
            final int pageNumber,
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -12,7 +12,6 @@ import ch.ethz.seb.sebserver.gbl.async.CircuitBreaker;
 | 
			
		|||
import ch.ethz.seb.sebserver.gbl.model.institution.LmsSetup;
 | 
			
		||||
import ch.ethz.seb.sebserver.gbl.model.institution.LmsSetupTestResult;
 | 
			
		||||
import ch.ethz.seb.sebserver.webservice.servicelayer.lms.impl.AbstractCachedCourseAccess;
 | 
			
		||||
import ch.ethz.seb.sebserver.webservice.servicelayer.lms.impl.AbstractCourseAccess;
 | 
			
		||||
 | 
			
		||||
/** Defines an LMS API access template to build SEB Server LMS integration.
 | 
			
		||||
 * </p>
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -23,7 +23,7 @@ public interface SEBRestrictionAPI {
 | 
			
		|||
     * @return {@link LmsSetupTestResult } instance with the test result report */
 | 
			
		||||
    LmsSetupTestResult testCourseRestrictionAPI();
 | 
			
		||||
 | 
			
		||||
    /** Get SEB restriction data form LMS within a {@link SEBRestrictionData } instance. The available restriction
 | 
			
		||||
    /** Get SEB restriction data from LMS within a {@link SEBRestrictionData } instance. The available restriction
 | 
			
		||||
     * details
 | 
			
		||||
     * depends on the type of LMS but shall at least contains the config-key(s) and the browser-exam-key(s).
 | 
			
		||||
     *
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -1,188 +0,0 @@
 | 
			
		|||
/*
 | 
			
		||||
 * Copyright (c) 2020 ETH Zürich, Educational Development and Technology (LET)
 | 
			
		||||
 *
 | 
			
		||||
 * This Source Code Form is subject to the terms of the Mozilla Public
 | 
			
		||||
 * License, v. 2.0. If a copy of the MPL was not distributed with this
 | 
			
		||||
 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
package ch.ethz.seb.sebserver.webservice.servicelayer.lms.impl;
 | 
			
		||||
 | 
			
		||||
import java.util.Collection;
 | 
			
		||||
import java.util.List;
 | 
			
		||||
import java.util.Set;
 | 
			
		||||
import java.util.function.Supplier;
 | 
			
		||||
 | 
			
		||||
import org.slf4j.Logger;
 | 
			
		||||
import org.slf4j.LoggerFactory;
 | 
			
		||||
import org.springframework.core.env.Environment;
 | 
			
		||||
 | 
			
		||||
import ch.ethz.seb.sebserver.gbl.Constants;
 | 
			
		||||
import ch.ethz.seb.sebserver.gbl.async.AsyncService;
 | 
			
		||||
import ch.ethz.seb.sebserver.gbl.async.CircuitBreaker;
 | 
			
		||||
import ch.ethz.seb.sebserver.gbl.model.exam.Chapters;
 | 
			
		||||
import ch.ethz.seb.sebserver.gbl.model.exam.QuizData;
 | 
			
		||||
import ch.ethz.seb.sebserver.gbl.model.user.ExamineeAccountDetails;
 | 
			
		||||
import ch.ethz.seb.sebserver.gbl.util.Result;
 | 
			
		||||
import ch.ethz.seb.sebserver.webservice.servicelayer.dao.FilterMap;
 | 
			
		||||
 | 
			
		||||
/** A partial course access API implementation that uses CircuitBreaker to apply LMS
 | 
			
		||||
 * API requests in a protected environment.
 | 
			
		||||
 *
 | 
			
		||||
 * Extend this to implement a concrete course access API for a given type of LMS. */
 | 
			
		||||
public abstract class AbstractCourseAccess {
 | 
			
		||||
 | 
			
		||||
    private static final Logger log = LoggerFactory.getLogger(AbstractCourseAccess.class);
 | 
			
		||||
 | 
			
		||||
    /** CircuitBreaker for protected quiz and course data requests */
 | 
			
		||||
    protected final CircuitBreaker<List<QuizData>> allQuizzesRequest;
 | 
			
		||||
    /** CircuitBreaker for protected quiz and course data requests */
 | 
			
		||||
    protected final CircuitBreaker<Collection<QuizData>> quizzesRequest;
 | 
			
		||||
    /** CircuitBreaker for protected quiz and course data requests */
 | 
			
		||||
    protected final CircuitBreaker<QuizData> quizRequest;
 | 
			
		||||
    /** CircuitBreaker for protected chapter data requests */
 | 
			
		||||
    protected final CircuitBreaker<Chapters> chaptersRequest;
 | 
			
		||||
    /** CircuitBreaker for protected examinee account details requests */
 | 
			
		||||
    protected final CircuitBreaker<ExamineeAccountDetails> accountDetailRequest;
 | 
			
		||||
 | 
			
		||||
    protected AbstractCourseAccess(
 | 
			
		||||
            final AsyncService asyncService,
 | 
			
		||||
            final Environment environment) {
 | 
			
		||||
 | 
			
		||||
        this.allQuizzesRequest = asyncService.createCircuitBreaker(
 | 
			
		||||
                environment.getProperty(
 | 
			
		||||
                        "sebserver.webservice.circuitbreaker.quizzesRequest.attempts",
 | 
			
		||||
                        Integer.class,
 | 
			
		||||
                        3),
 | 
			
		||||
                environment.getProperty(
 | 
			
		||||
                        "sebserver.webservice.circuitbreaker.quizzesRequest.blockingTime",
 | 
			
		||||
                        Long.class,
 | 
			
		||||
                        Constants.MINUTE_IN_MILLIS),
 | 
			
		||||
                environment.getProperty(
 | 
			
		||||
                        "sebserver.webservice.circuitbreaker.quizzesRequest.timeToRecover",
 | 
			
		||||
                        Long.class,
 | 
			
		||||
                        Constants.MINUTE_IN_MILLIS));
 | 
			
		||||
 | 
			
		||||
        this.quizzesRequest = asyncService.createCircuitBreaker(
 | 
			
		||||
                environment.getProperty(
 | 
			
		||||
                        "sebserver.webservice.circuitbreaker.quizzesRequest.attempts",
 | 
			
		||||
                        Integer.class,
 | 
			
		||||
                        3),
 | 
			
		||||
                environment.getProperty(
 | 
			
		||||
                        "sebserver.webservice.circuitbreaker.quizzesRequest.blockingTime",
 | 
			
		||||
                        Long.class,
 | 
			
		||||
                        Constants.SECOND_IN_MILLIS * 10),
 | 
			
		||||
                environment.getProperty(
 | 
			
		||||
                        "sebserver.webservice.circuitbreaker.quizzesRequest.timeToRecover",
 | 
			
		||||
                        Long.class,
 | 
			
		||||
                        Constants.MINUTE_IN_MILLIS));
 | 
			
		||||
 | 
			
		||||
        this.quizRequest = asyncService.createCircuitBreaker(
 | 
			
		||||
                environment.getProperty(
 | 
			
		||||
                        "sebserver.webservice.circuitbreaker.quizzesRequest.attempts",
 | 
			
		||||
                        Integer.class,
 | 
			
		||||
                        3),
 | 
			
		||||
                environment.getProperty(
 | 
			
		||||
                        "sebserver.webservice.circuitbreaker.quizzesRequest.blockingTime",
 | 
			
		||||
                        Long.class,
 | 
			
		||||
                        Constants.SECOND_IN_MILLIS * 10),
 | 
			
		||||
                environment.getProperty(
 | 
			
		||||
                        "sebserver.webservice.circuitbreaker.quizzesRequest.timeToRecover",
 | 
			
		||||
                        Long.class,
 | 
			
		||||
                        Constants.MINUTE_IN_MILLIS));
 | 
			
		||||
 | 
			
		||||
        this.chaptersRequest = asyncService.createCircuitBreaker(
 | 
			
		||||
                environment.getProperty(
 | 
			
		||||
                        "sebserver.webservice.circuitbreaker.chaptersRequest.attempts",
 | 
			
		||||
                        Integer.class,
 | 
			
		||||
                        3),
 | 
			
		||||
                environment.getProperty(
 | 
			
		||||
                        "sebserver.webservice.circuitbreaker.chaptersRequest.blockingTime",
 | 
			
		||||
                        Long.class,
 | 
			
		||||
                        Constants.SECOND_IN_MILLIS * 10),
 | 
			
		||||
                environment.getProperty(
 | 
			
		||||
                        "sebserver.webservice.circuitbreaker.chaptersRequest.timeToRecover",
 | 
			
		||||
                        Long.class,
 | 
			
		||||
                        Constants.SECOND_IN_MILLIS * 30));
 | 
			
		||||
 | 
			
		||||
        this.accountDetailRequest = asyncService.createCircuitBreaker(
 | 
			
		||||
                environment.getProperty(
 | 
			
		||||
                        "sebserver.webservice.circuitbreaker.accountDetailRequest.attempts",
 | 
			
		||||
                        Integer.class,
 | 
			
		||||
                        2),
 | 
			
		||||
                environment.getProperty(
 | 
			
		||||
                        "sebserver.webservice.circuitbreaker.accountDetailRequest.blockingTime",
 | 
			
		||||
                        Long.class,
 | 
			
		||||
                        Constants.SECOND_IN_MILLIS * 10),
 | 
			
		||||
                environment.getProperty(
 | 
			
		||||
                        "sebserver.webservice.circuitbreaker.accountDetailRequest.timeToRecover",
 | 
			
		||||
                        Long.class,
 | 
			
		||||
                        Constants.SECOND_IN_MILLIS * 30));
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public Result<List<QuizData>> protectedQuizzesRequest(final FilterMap filterMap) {
 | 
			
		||||
        return this.allQuizzesRequest.protectedRun(allQuizzesSupplier(filterMap))
 | 
			
		||||
                .onError(error -> log.error(
 | 
			
		||||
                        "Failed to run protectedQuizzesRequest: {}",
 | 
			
		||||
                        error.getMessage()));
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public Result<Collection<QuizData>> protectedQuizzesRequest(final Set<String> ids) {
 | 
			
		||||
        return this.quizzesRequest.protectedRun(quizzesSupplier(ids))
 | 
			
		||||
                .onError(error -> log.error(
 | 
			
		||||
                        "Failed to run protectedQuizzesRequest: {}",
 | 
			
		||||
                        error.getMessage()));
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public Result<QuizData> protectedQuizRequest(final String id) {
 | 
			
		||||
        return this.quizRequest.protectedRun(quizSupplier(id))
 | 
			
		||||
                .onError(error -> log.error(
 | 
			
		||||
                        "Failed to run protectedQuizRequest: {}",
 | 
			
		||||
                        error.getMessage()));
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public Result<ExamineeAccountDetails> getExamineeAccountDetails(final String examineeSessionId) {
 | 
			
		||||
        final Supplier<ExamineeAccountDetails> accountDetailsSupplier = accountDetailsSupplier(examineeSessionId);
 | 
			
		||||
        return this.accountDetailRequest.protectedRun(() -> {
 | 
			
		||||
            try {
 | 
			
		||||
                return accountDetailsSupplier.get();
 | 
			
		||||
            } catch (final Exception e) {
 | 
			
		||||
                log.error("Unexpected error while trying to get examinee account details: ", e);
 | 
			
		||||
                throw e;
 | 
			
		||||
            }
 | 
			
		||||
        });
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /** Default implementation that uses getExamineeAccountDetails to geht the examinee name
 | 
			
		||||
     *
 | 
			
		||||
     * @param examineeSessionId
 | 
			
		||||
     * @return The examinee account name for the given examineeSessionId */
 | 
			
		||||
    public String getExamineeName(final String examineeSessionId) {
 | 
			
		||||
        return getExamineeAccountDetails(examineeSessionId)
 | 
			
		||||
                .map(ExamineeAccountDetails::getDisplayName)
 | 
			
		||||
                .onError(error -> log.warn("Failed to request user-name for ID: {}", error.getMessage(), error))
 | 
			
		||||
                .getOr(examineeSessionId);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public Result<Chapters> getCourseChapters(final String courseId) {
 | 
			
		||||
        return this.chaptersRequest.protectedRun(getCourseChaptersSupplier(courseId))
 | 
			
		||||
                .onError(error -> log.error(
 | 
			
		||||
                        "Failed to run getCourseChapters: {}",
 | 
			
		||||
                        error.getMessage()));
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    protected abstract Supplier<ExamineeAccountDetails> accountDetailsSupplier(final String examineeSessionId);
 | 
			
		||||
 | 
			
		||||
    /** Provides a supplier to supply request to use within the circuit breaker */
 | 
			
		||||
    protected abstract Supplier<List<QuizData>> allQuizzesSupplier(final FilterMap filterMap);
 | 
			
		||||
 | 
			
		||||
    /** Provides a supplier for the quiz data request to use within the circuit breaker */
 | 
			
		||||
    protected abstract Supplier<Collection<QuizData>> quizzesSupplier(final Set<String> ids);
 | 
			
		||||
 | 
			
		||||
    /** Provides a supplier for the quiz data request to use within the circuit breaker */
 | 
			
		||||
    protected abstract Supplier<QuizData> quizSupplier(final String id);
 | 
			
		||||
 | 
			
		||||
    /** Provides a supplier for the course chapter data request to use within the circuit breaker */
 | 
			
		||||
    protected abstract Supplier<Chapters> getCourseChaptersSupplier(final String courseId);
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			@ -151,7 +151,7 @@ public class ExamSessionControlTask implements DisposableBean {
 | 
			
		|||
 | 
			
		||||
    private void controlExamLMSUpdate() {
 | 
			
		||||
        if (log.isTraceEnabled()) {
 | 
			
		||||
            log.trace("Start update exams form LMS");
 | 
			
		||||
            log.trace("Start update exams from LMS");
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        try {
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -91,7 +91,7 @@ class ExamUpdateHandler {
 | 
			
		|||
                    .getLmsAPITemplate(lmsSetupId)
 | 
			
		||||
                    .flatMap(template -> template.getQuizzes(new HashSet<>(exams.keySet())))
 | 
			
		||||
                    .onError(error -> log.warn(
 | 
			
		||||
                            "Failed to get quizzes form LMS Setup: {} cause: {}",
 | 
			
		||||
                            "Failed to get quizzes from LMS Setup: {} cause: {}",
 | 
			
		||||
                            lmsSetupId,
 | 
			
		||||
                            error.getMessage()))
 | 
			
		||||
                    .getOr(Collections.emptyList())
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
		Loading…
	
	Add table
		
		Reference in a new issue