GitLab wurde erfolgreich aktualisiert. Dank regelmäßiger Updates bleibt das THM GitLab sicher und Sie profitieren von den neuesten Funktionen. Danke für Ihre Geduld.

Commit ef299621 authored by Daniel Gerhardt's avatar Daniel Gerhardt

Separate session persistance code and migrate it to Ektorp

LoggedIn documents are also handled by the SessionRepository for now.
parent 57ec03af
......@@ -26,14 +26,17 @@ import de.thm.arsnova.connector.client.ConnectorClientImpl;
import de.thm.arsnova.entities.DbUser;
import de.thm.arsnova.entities.LogEntry;
import de.thm.arsnova.entities.Motd;
import de.thm.arsnova.entities.Session;
import de.thm.arsnova.entities.serialization.CouchDbDocumentModule;
import de.thm.arsnova.entities.serialization.CouchDbObjectMapperFactory;
import de.thm.arsnova.entities.serialization.View;
import de.thm.arsnova.persistance.LogEntryRepository;
import de.thm.arsnova.persistance.MotdRepository;
import de.thm.arsnova.persistance.SessionRepository;
import de.thm.arsnova.persistance.UserRepository;
import de.thm.arsnova.persistance.couchdb.CouchDbLogEntryRepository;
import de.thm.arsnova.persistance.couchdb.CouchDbMotdRepository;
import de.thm.arsnova.persistance.couchdb.CouchDbSessionRepository;
import de.thm.arsnova.persistance.couchdb.CouchDbUserRepository;
import de.thm.arsnova.persistance.couchdb.InitializingCouchDbConnector;
import de.thm.arsnova.socket.ARSnovaSocket;
......@@ -284,6 +287,11 @@ public class AppConfig extends WebMvcConfigurerAdapter {
return new CouchDbMotdRepository(Motd.class, couchDbConnector(), false);
}
@Bean
public SessionRepository sessionRepository() throws Exception {
return new CouchDbSessionRepository(Session.class, couchDbConnector(), false);
}
@Bean
public UserRepository userRepository() throws Exception {
return new CouchDbUserRepository(DbUser.class, couchDbConnector(), false);
......
......@@ -17,32 +17,15 @@
*/
package de.thm.arsnova.dao;
import de.thm.arsnova.connector.model.Course;
import de.thm.arsnova.domain.CourseScore;
import de.thm.arsnova.entities.*;
import de.thm.arsnova.entities.transport.ImportExportSession;
import java.util.List;
import java.util.Map;
/**
* All methods the database must support.
*/
public interface IDatabaseDao {
Session getSessionFromKeyword(String keyword);
List<Session> getMySessions(User user, final int start, final int limit);
List<Session> getSessionsForUsername(String username, final int start, final int limit);
List<Session> getPublicPoolSessions();
List<Session> getMyPublicPoolSessions(User user);
Session saveSession(User user, Session session);
boolean sessionKeyAvailable(String keyword);
Question saveQuestion(Session session, Question question);
InterposedQuestion saveQuestion(Session session, InterposedQuestion question, User user);
......@@ -55,10 +38,6 @@ public interface IDatabaseDao {
int getSkillQuestionCount(Session session);
LoggedIn registerAsOnlineUser(User u, Session s);
Session updateSessionOwnerActivity(Session session);
List<String> getQuestionIds(Session session, User user);
int deleteQuestionWithAnswers(Question question);
......@@ -101,10 +80,6 @@ public interface IDatabaseDao {
void markInterposedQuestionAsRead(InterposedQuestion question);
List<Session> getMyVisitedSessions(User user, final int start, final int limit);
List<Session> getVisitedSessionsForUsername(String username, final int start, final int limit);
Question updateQuestion(Question question);
int deleteAnswers(Question question);
......@@ -113,27 +88,10 @@ public interface IDatabaseDao {
Answer updateAnswer(Answer answer);
Session getSessionFromId(String sessionId);
void deleteAnswer(String answerId);
void deleteInterposedQuestion(InterposedQuestion question);
List<Session> getCourseSessions(List<Course> courses);
Session updateSession(Session session);
Session changeSessionCreator(Session session, String newCreator);
/**
* Deletes a session and related data.
*
* @param session the session for deletion
*/
int[] deleteSession(Session session);
int[] deleteInactiveGuestSessions(long lastActivityBefore);
int deleteInactiveGuestVisitedSessionLists(long lastActivityBefore);
List<Question> getLectureQuestionsForUsers(Session session);
......@@ -182,22 +140,10 @@ public interface IDatabaseDao {
CourseScore getLearningProgress(Session session);
List<SessionInfo> getMySessionsInfo(User user, final int start, final int limit);
List<SessionInfo> getPublicPoolSessionsInfo();
List<SessionInfo> getMyPublicPoolSessionsInfo(final User user);
List<SessionInfo> getMyVisitedSessionsInfo(User currentUser, final int start, final int limit);
int deleteAllPreparationAnswers(Session session);
int deleteAllLectureAnswers(Session session);
SessionInfo importSession(User user, ImportExportSession importSession);
ImportExportSession exportSession(String sessionkey, Boolean withAnswer, Boolean withFeedbackQuestions);
Statistics getStatistics();
List<String> getSubjects(Session session, String questionVariant);
......
......@@ -17,6 +17,8 @@
*/
package de.thm.arsnova.entities;
import com.fasterxml.jackson.annotation.JsonView;
import de.thm.arsnova.entities.serialization.View;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
......@@ -41,19 +43,23 @@ public class LearningProgressOptions implements Serializable {
public LearningProgressOptions() { }
@ApiModelProperty(required = true, value = "the type")
@JsonView({View.Persistence.class, View.Public.class})
public String getType() {
return type;
}
@JsonView({View.Persistence.class, View.Public.class})
public void setType(String learningProgressType) {
this.type = learningProgressType;
}
@ApiModelProperty(required = true, value = "either lecture or preparation")
@JsonView({View.Persistence.class, View.Public.class})
public String getQuestionVariant() {
return questionVariant;
}
@JsonView({View.Persistence.class, View.Public.class})
public void setQuestionVariant(String questionVariant) {
this.questionVariant = questionVariant;
}
......
......@@ -17,25 +17,24 @@
*/
package de.thm.arsnova.entities;
import com.fasterxml.jackson.annotation.JsonView;
import de.thm.arsnova.entities.serialization.View;
import java.util.ArrayList;
import java.util.List;
/**
* Once a user joins a session, this class is used to identify a returning user.
*/
public class LoggedIn {
private String _id;
private String _rev;
private String type;
public class LoggedIn implements Entity {
private String id;
private String rev;
private String user;
private String sessionId;
private long timestamp;
private List<VisitedSession> visitedSessions = new ArrayList<>();
private List<String> _conflicts;
public LoggedIn() {
this.type = "logged_in";
this.updateTimestamp();
}
......@@ -47,88 +46,80 @@ public class LoggedIn {
private boolean isAlreadyVisited(Session s) {
for (VisitedSession vs : this.visitedSessions) {
if (vs.get_id().equals(s.get_id())) {
if (vs.getId().equals(s.getId())) {
return true;
}
}
return false;
}
public void updateTimestamp() {
this.timestamp = System.currentTimeMillis();
}
public String get_id() {
return _id;
}
public void set_id(String _id) {
this._id = _id;
@JsonView(View.Persistence.class)
public String getId() {
return id;
}
public String get_rev() {
return _rev;
@JsonView(View.Persistence.class)
public void setId(final String id) {
this.id = id;
}
public void set_rev(String _rev) {
this._rev = _rev;
@JsonView(View.Persistence.class)
public String getRevision() {
return rev;
}
public String getType() {
return type;
@JsonView(View.Persistence.class)
public void setRevision(final String rev) {
this.rev = rev;
}
public void setType(String type) {
this.type = type;
public void updateTimestamp() {
this.timestamp = System.currentTimeMillis();
}
@JsonView(View.Persistence.class)
public String getUser() {
return user;
}
@JsonView(View.Persistence.class)
public void setUser(String user) {
this.user = user;
}
@JsonView(View.Persistence.class)
public String getSessionId() {
return sessionId;
}
@JsonView(View.Persistence.class)
public void setSessionId(String sessionId) {
this.sessionId = sessionId;
}
@JsonView(View.Persistence.class)
public long getTimestamp() {
return timestamp;
}
@JsonView(View.Persistence.class)
public void setTimestamp(long timestamp) {
this.timestamp = timestamp;
}
@JsonView(View.Persistence.class)
public List<VisitedSession> getVisitedSessions() {
return visitedSessions;
}
@JsonView(View.Persistence.class)
public void setVisitedSessions(List<VisitedSession> visitedSessions) {
this.visitedSessions = visitedSessions;
}
public List<String> get_conflicts() {
return _conflicts;
}
public void set_conflicts(List<String> _conflicts) {
this._conflicts = _conflicts;
}
public boolean hasConflicts() {
return !(_conflicts == null || _conflicts.isEmpty());
}
@Override
public String toString() {
return "LoggedIn [_id=" + _id + ", _rev=" + _rev + ", type=" + type
return "LoggedIn [id=" + id + ", rev=" + rev + ", type=" + getType()
+ ", user=" + user + ", sessionId=" + sessionId
+ ", timestamp=" + timestamp + ", visitedSessions="
+ visitedSessions + "]";
......
......@@ -18,21 +18,18 @@
package de.thm.arsnova.entities;
import com.fasterxml.jackson.annotation.JsonIgnore;
import com.fasterxml.jackson.annotation.JsonView;
import de.thm.arsnova.entities.serialization.View;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import java.io.Serializable;
import java.util.List;
/**
* Represents an ARSnova session.
*/
@ApiModel(value = "session", description = "the session entity")
public class Session implements Serializable {
private static final long serialVersionUID = 1L;
private String type;
public class Session implements Entity {
private String id;
private String rev;
private String name;
private String shortName;
private String keyword;
......@@ -41,7 +38,6 @@ public class Session implements Serializable {
private long lastOwnerActivity;
private String courseType;
private String courseId;
private List<String> _conflicts;
private long creationTime;
private LearningProgressOptions learningProgressOptions = new LearningProgressOptions();
private SessionFeature features = new SessionFeature();
......@@ -59,9 +55,6 @@ public class Session implements Serializable {
private boolean feedbackLock;
private boolean flipFlashcards;
private String _id;
private String _rev;
/**
* Returns a copy of the given session without any information that identifies a person.
* @param original The session to create a anonymized copy of
......@@ -69,7 +62,6 @@ public class Session implements Serializable {
*/
public static Session anonymizedCopy(final Session original) {
final Session copy = new Session();
copy.type = original.type;
copy.name = original.name;
copy.shortName = original.shortName;
copy.keyword = original.keyword;
......@@ -95,118 +87,119 @@ public class Session implements Serializable {
copy.feedbackLock = original.feedbackLock;
copy.flipFlashcards = original.flipFlashcards;
copy._id = original._id;
copy._rev = original._rev;
copy.id = original.id;
copy.rev = original.rev;
return copy;
}
@ApiModelProperty(required = true, value = "\"session\" - used to filter in the couchDB")
public String getType() {
return type;
@JsonView({View.Persistence.class, View.Public.class})
public String getId() {
return id;
}
@JsonView({View.Persistence.class, View.Public.class})
public void setId(final String id) {
this.id = id;
}
@JsonView({View.Persistence.class, View.Public.class})
public String getRevision() {
return rev;
}
public void setType(final String type) {
this.type = type;
@JsonView({View.Persistence.class, View.Public.class})
public void setRevision(final String rev) {
this.rev = rev;
}
@ApiModelProperty(required = true, value = "the name")
@JsonView({View.Persistence.class, View.Public.class})
public String getName() {
return name;
}
@JsonView({View.Persistence.class, View.Public.class})
public void setName(final String name) {
this.name = name;
}
@ApiModelProperty(required = true, value = "the short name")
@JsonView({View.Persistence.class, View.Public.class})
public String getShortName() {
return shortName;
}
@JsonView({View.Persistence.class, View.Public.class})
public void setShortName(final String shortName) {
this.shortName = shortName;
}
@ApiModelProperty(required = true, value = "the keyword")
@JsonView({View.Persistence.class, View.Public.class})
public String getKeyword() {
return keyword;
}
@JsonView({View.Persistence.class, View.Public.class})
public void setKeyword(final String keyword) {
this.keyword = keyword;
}
@ApiModelProperty(required = true, value = "the session creator")
@JsonView(View.Persistence.class)
public String getCreator() {
return creator;
}
@JsonView(View.Persistence.class)
public void setCreator(final String creator) {
this.creator = creator;
}
@ApiModelProperty(required = true, value = "true for active session")
@JsonView({View.Persistence.class, View.Public.class})
public boolean isActive() {
return active;
}
@JsonView({View.Persistence.class, View.Public.class})
public void setActive(final boolean active) {
this.active = active;
}
@ApiModelProperty(required = true, value = "timestamp from the last activity of the owner")
@JsonView(View.Persistence.class)
public long getLastOwnerActivity() {
return lastOwnerActivity;
}
@JsonView(View.Persistence.class)
public void setLastOwnerActivity(final long lastOwnerActivity) {
this.lastOwnerActivity = lastOwnerActivity;
}
public void set_id(final String id) {
_id = id;
}
@ApiModelProperty(required = true, value = "the couchDB ID")
public String get_id() {
return _id;
}
public void set_rev(final String rev) {
_rev = rev;
}
public String get_rev() {
return _rev;
}
public void set_conflicts(final List<String> conflicts) {
_conflicts = conflicts;
}
@ApiModelProperty(required = true, value = "potential couchDB conflicts")
public List<String> get_conflicts() {
return _conflicts;
}
public boolean isCreator(final User user) {
return user.getUsername().equals(creator);
}
@ApiModelProperty(required = true, value = "the source the course comes from (example: moodle)")
@JsonView({View.Persistence.class, View.Public.class})
public String getCourseType() {
return courseType;
}
@JsonView({View.Persistence.class, View.Public.class})
public void setCourseType(final String courseType) {
this.courseType = courseType;
}
@ApiModelProperty(required = true, value = "the course ID")
@JsonView({View.Persistence.class, View.Public.class})
public String getCourseId() {
return courseId;
}
@JsonView({View.Persistence.class, View.Public.class})
public void setCourseId(final String courseId) {
this.courseId = courseId;
}
......@@ -217,143 +210,173 @@ public class Session implements Serializable {
}
@ApiModelProperty(required = true, value = "creation timestamp")
@JsonView({View.Persistence.class, View.Public.class})
public long getCreationTime() {
return creationTime;
}
@JsonView(View.Persistence.class)
public void setCreationTime(long creationTime) {
this.creationTime = creationTime;
}
@ApiModelProperty(required = true, value = "the learning progress options")
@JsonView({View.Persistence.class, View.Public.class})
public LearningProgressOptions getLearningProgressOptions() {
return learningProgressOptions;
}
@JsonView({View.Persistence.class, View.Public.class})
public void setLearningProgressOptions(LearningProgressOptions learningProgressOptions) {
this.learningProgressOptions = learningProgressOptions;
}
@ApiModelProperty(required = true, value = "the enabled features (e.g. feedback, interposed, learning Progress, lecture)")
@JsonView({View.Persistence.class, View.Public.class})
public SessionFeature getFeatures() {
return features;
}
@JsonView({View.Persistence.class, View.Public.class})
public void setFeatures(SessionFeature features) {
this.features = features;
}
@ApiModelProperty(required = true, value = "the public pool author name")
@JsonView({View.Persistence.class, View.Public.class})
public String getPpAuthorName() {
return ppAuthorName;
}
@JsonView({View.Persistence.class, View.Public.class})
public void setPpAuthorName(final String ppAuthorName) {
this.ppAuthorName = ppAuthorName;
}
@ApiModelProperty(required = true, value = "the public pool author email")
@JsonView({View.Persistence.class, View.Public.class})
public String getPpAuthorMail() {
return ppAuthorMail;
}
@JsonView({View.Persistence.class, View.Public.class})
public void setPpAuthorMail(final String ppAuthorMail) {
this.ppAuthorMail = ppAuthorMail;
}
@ApiModelProperty(required = true, value = "the public pool university")
@JsonView({View.Persistence.class, View.Public.class})
public String getPpUniversity() {
return ppUniversity;
}
@JsonView({View.Persistence.class, View.Public.class})
public void setPpUniversity(final String ppUniversity) {
this.ppUniversity = ppUniversity;
}
@ApiModelProperty(required = true, value = "the public pool logo")
@JsonView({View.Persistence.class, View.Public.class})
public String getPpLogo() {
return ppLogo;
}
@JsonView({View.Persistence.class, View.Public.class})
public void setPpLogo(final String ppLogo) {
this.ppLogo = ppLogo;
}