From 57ec03afc736b0e06e4967398e8f7223810d883d Mon Sep 17 00:00:00 2001
From: Daniel Gerhardt <code@dgerhardt.net>
Date: Thu, 20 Apr 2017 12:23:44 +0200
Subject: [PATCH] Separate MotD persistance code and migrate it to Ektorp

---
 .../java/de/thm/arsnova/config/AppConfig.java |   8 +
 .../java/de/thm/arsnova/dao/CouchDBDao.java   | 166 ++----------------
 .../java/de/thm/arsnova/dao/IDatabaseDao.java |  21 ---
 .../java/de/thm/arsnova/entities/Motd.java    |  44 +++--
 .../CouchDbTypeFieldConverter.java            |   3 +
 .../arsnova/persistance/MotdRepository.java   |  34 ++++
 .../couchdb/CouchDbMotdRepository.java        | 121 +++++++++++++
 .../de/thm/arsnova/services/MotdService.java  |  32 ++--
 .../de/thm/arsnova/dao/StubDatabaseDao.java   |  58 ------
 9 files changed, 231 insertions(+), 256 deletions(-)
 create mode 100644 src/main/java/de/thm/arsnova/persistance/MotdRepository.java
 create mode 100644 src/main/java/de/thm/arsnova/persistance/couchdb/CouchDbMotdRepository.java

diff --git a/src/main/java/de/thm/arsnova/config/AppConfig.java b/src/main/java/de/thm/arsnova/config/AppConfig.java
index 985ce0651..2572cd512 100644
--- a/src/main/java/de/thm/arsnova/config/AppConfig.java
+++ b/src/main/java/de/thm/arsnova/config/AppConfig.java
@@ -25,12 +25,15 @@ import de.thm.arsnova.connector.client.ConnectorClient;
 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.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.UserRepository;
 import de.thm.arsnova.persistance.couchdb.CouchDbLogEntryRepository;
+import de.thm.arsnova.persistance.couchdb.CouchDbMotdRepository;
 import de.thm.arsnova.persistance.couchdb.CouchDbUserRepository;
 import de.thm.arsnova.persistance.couchdb.InitializingCouchDbConnector;
 import de.thm.arsnova.socket.ARSnovaSocket;
@@ -276,6 +279,11 @@ public class AppConfig extends WebMvcConfigurerAdapter {
 		return new CouchDbLogEntryRepository(LogEntry.class, couchDbConnector(), false);
 	}
 
+	@Bean
+	public MotdRepository motdRepository() throws Exception {
+		return new CouchDbMotdRepository(Motd.class, couchDbConnector(), false);
+	}
+
 	@Bean
 	public UserRepository userRepository() throws Exception {
 		return new CouchDbUserRepository(DbUser.class, couchDbConnector(), false);
diff --git a/src/main/java/de/thm/arsnova/dao/CouchDBDao.java b/src/main/java/de/thm/arsnova/dao/CouchDBDao.java
index 62dc149f4..f46f074be 100644
--- a/src/main/java/de/thm/arsnova/dao/CouchDBDao.java
+++ b/src/main/java/de/thm/arsnova/dao/CouchDBDao.java
@@ -33,6 +33,7 @@ import de.thm.arsnova.entities.transport.ImportExportSession.ImportExportQuestio
 import de.thm.arsnova.events.NewAnswerEvent;
 import de.thm.arsnova.exceptions.NotFoundException;
 import de.thm.arsnova.persistance.LogEntryRepository;
+import de.thm.arsnova.persistance.MotdRepository;
 import de.thm.arsnova.services.ISessionService;
 import net.sf.ezmorph.Morpher;
 import net.sf.ezmorph.MorpherRegistry;
@@ -59,8 +60,16 @@ import org.springframework.transaction.annotation.Isolation;
 import org.springframework.transaction.annotation.Transactional;
 
 import java.io.IOException;
-import java.util.*;
+import java.util.AbstractMap;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Map;
 import java.util.Map.Entry;
+import java.util.Queue;
+import java.util.Set;
 import java.util.concurrent.ConcurrentLinkedQueue;
 
 /**
@@ -90,9 +99,12 @@ public class CouchDBDao implements IDatabaseDao, ApplicationEventPublisherAware
 	@Autowired
 	private ISessionService sessionService;
 
+	@Autowired
 	private LogEntryRepository dbLogger;
 
 	@Autowired
+	private MotdRepository motdRepo;
+
 	private String databaseHost;
 	private int databasePort;
 	private String databaseName;
@@ -2439,7 +2451,7 @@ public class CouchDBDao implements IDatabaseDao, ApplicationEventPublisherAware
 		if (withAnswers) {
 			importExportSession.setSessionInfo(this.calculateSessionInfo(importExportSession, session));
 		}
-		importExportSession.setMotds(getDatabaseDao().getMotdsForSession(session.getKeyword()));
+		importExportSession.setMotds(motdRepository.getMotdsForSession(session.getKeyword()));
 		return importExportSession;
 	}
 
@@ -2553,156 +2565,6 @@ public class CouchDBDao implements IDatabaseDao, ApplicationEventPublisherAware
 		return result;
 	}
 
-	@Override
-	public List<Motd> getAdminMotds() {
-		final View view = new View("motd/doc_by_audience_for_global");
-		return getMotds(view);
-	}
-
-	@Override
-	@Cacheable(cacheNames = "motds", key = "'all'")
-	public List<Motd> getMotdsForAll() {
-		final View view = new View("motd/doc_by_audience_for_global");
-		return getMotds(view);
-	}
-
-	@Override
-	@Cacheable(cacheNames = "motds", key = "'loggedIn'")
-	public List<Motd> getMotdsForLoggedIn() {
-		final View view = new View("motd/doc_by_audience_for_global");
-		view.setKey("loggedIn");
-		return getMotds(view);
-	}
-
-	@Override
-	@Cacheable(cacheNames = "motds", key = "'tutors'")
-	public List<Motd> getMotdsForTutors() {
-		final View view1 = new View("motd/doc_by_audience_for_global");
-		final View view2 = new View("motd/doc_by_audience_for_global");
-		view1.setKey("loggedIn");
-		view2.setKey("tutors");
-		final List<Motd> union = new ArrayList<>();
-		union.addAll(getMotds(view1));
-		union.addAll(getMotds(view2));
-
-		return union;
-	}
-
-	@Override
-	@Cacheable(cacheNames = "motds", key = "'students'")
-	public List<Motd> getMotdsForStudents() {
-		final View view1 = new View("motd/doc_by_audience_for_global");
-		final View view2 = new View("motd/doc_by_audience_for_global");
-		view1.setKey("loggedIn");
-		view2.setKey("students");
-		final List<Motd> union = new ArrayList<>();
-		union.addAll(getMotds(view1));
-		union.addAll(getMotds(view2));
-
-		return union;
-	}
-
-	@Override
-	@Cacheable(cacheNames = "motds", key = "('session').concat(#p0)")
-	public List<Motd> getMotdsForSession(final String sessionkey) {
-		final View view = new View("motd/doc_by_sessionkey");
-		view.setKey(sessionkey);
-		return getMotds(view);
-	}
-
-	@Override
-	public List<Motd> getMotds(View view) {
-		final ViewResults motddocs = this.getDatabase().view(view);
-		List<Motd> motdlist = new ArrayList<>();
-		for (final Document d : motddocs.getResults()) {
-			Motd motd = new Motd();
-			motd.set_id(d.getId());
-			motd.set_rev(d.getJSONObject("value").getString("_rev"));
-			motd.setMotdkey(d.getJSONObject("value").getString("motdkey"));
-			Date start = new Date(Long.parseLong(d.getJSONObject("value").getString("startdate")));
-			motd.setStartdate(start);
-			Date end = new Date(Long.parseLong(d.getJSONObject("value").getString("enddate")));
-			motd.setEnddate(end);
-			motd.setTitle(d.getJSONObject("value").getString("title"));
-			motd.setText(d.getJSONObject("value").getString("text"));
-			motd.setAudience(d.getJSONObject("value").getString("audience"));
-			motd.setSessionkey(d.getJSONObject("value").getString("sessionkey"));
-			motdlist.add(motd);
-		}
-		return motdlist;
-	}
-
-	@Override
-	public Motd getMotdByKey(String key) {
-		final View view = new View("motd/by_motdkey");
-		view.setIncludeDocs(true);
-		view.setKey(key);
-		Motd motd = new Motd();
-
-		ViewResults results = this.getDatabase().view(view);
-
-		for (final Document d : results.getResults()) {
-			motd.set_id(d.getId());
-			motd.set_rev(d.getJSONObject("doc").getString("_rev"));
-			motd.setMotdkey(d.getJSONObject("doc").getString("motdkey"));
-			Date start = new Date(Long.parseLong(d.getJSONObject("doc").getString("startdate")));
-			motd.setStartdate(start);
-			Date end = new Date(Long.parseLong(d.getJSONObject("doc").getString("enddate")));
-			motd.setEnddate(end);
-			motd.setTitle(d.getJSONObject("doc").getString("title"));
-			motd.setText(d.getJSONObject("doc").getString("text"));
-			motd.setAudience(d.getJSONObject("doc").getString("audience"));
-			motd.setSessionkey(d.getJSONObject("doc").getString("sessionkey"));
-		}
-
-		return motd;
-	}
-
-	@Override
-	@CacheEvict(cacheNames = "motds", key = "#p0.audience.concat(#p0.sessionkey)")
-	public Motd createOrUpdateMotd(Motd motd) {
-		try {
-			String id = motd.get_id();
-			String rev = motd.get_rev();
-			Document d = new Document();
-
-			if (null != id) {
-				d = database.getDocument(id, rev);
-			} else {
-				motd.setMotdkey(sessionService.generateKeyword());
-				d.put("motdkey", motd.getMotdkey());
-			}
-			d.put("type", "motd");
-			d.put("startdate", String.valueOf(motd.getStartdate().getTime()));
-			d.put("enddate", String.valueOf(motd.getEnddate().getTime()));
-			d.put("title", motd.getTitle());
-			d.put("text", motd.getText());
-			d.put("audience", motd.getAudience());
-			d.put("sessionId", motd.getSessionId());
-			d.put("sessionkey", motd.getSessionkey());
-
-			database.saveDocument(d, id);
-			motd.set_id(d.getId());
-			motd.set_rev(d.getRev());
-
-			return motd;
-		} catch (IOException e) {
-			logger.error("Could not save MotD {}.", motd, e);
-		}
-
-		return null;
-	}
-
-	@Override
-	@CacheEvict(cacheNames = "motds", key = "#p0.audience.concat(#p0.sessionkey)")
-	public void deleteMotd(Motd motd) {
-		try {
-			this.deleteDocument(motd.get_id());
-		} catch (IOException e) {
-			logger.error("Could not delete MotD {}.", motd.get_id(), e);
-		}
-	}
-
 	@Override
 	@Cacheable(cacheNames = "motdlist", key = "#p0")
 	public MotdList getMotdListForUser(final String username) {
diff --git a/src/main/java/de/thm/arsnova/dao/IDatabaseDao.java b/src/main/java/de/thm/arsnova/dao/IDatabaseDao.java
index 70f0a4395..25847e531 100644
--- a/src/main/java/de/thm/arsnova/dao/IDatabaseDao.java
+++ b/src/main/java/de/thm/arsnova/dao/IDatabaseDao.java
@@ -17,7 +17,6 @@
  */
 package de.thm.arsnova.dao;
 
-import com.fourspaces.couchdb.View;
 import de.thm.arsnova.connector.model.Course;
 import de.thm.arsnova.domain.CourseScore;
 import de.thm.arsnova.entities.*;
@@ -215,26 +214,6 @@ public interface IDatabaseDao {
 
 	<T> T getObjectFromId(String documentId, Class<T> klass);
 
-	List<Motd> getAdminMotds();
-
-	List<Motd> getMotdsForAll();
-
-	List<Motd> getMotdsForLoggedIn();
-
-	List<Motd> getMotdsForTutors();
-
-	List<Motd> getMotdsForStudents();
-
-	List<Motd> getMotdsForSession(final String sessionkey);
-
-	List<Motd> getMotds(View view);
-
-	Motd getMotdByKey(String key);
-
-	Motd createOrUpdateMotd(Motd motd);
-
-	void deleteMotd(Motd motd);
-
 	MotdList getMotdListForUser(final String username);
 
 	MotdList createOrUpdateMotdList(MotdList motdlist);
diff --git a/src/main/java/de/thm/arsnova/entities/Motd.java b/src/main/java/de/thm/arsnova/entities/Motd.java
index 35864703d..1b4ea1d73 100644
--- a/src/main/java/de/thm/arsnova/entities/Motd.java
+++ b/src/main/java/de/thm/arsnova/entities/Motd.java
@@ -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;
 
@@ -26,7 +28,7 @@ import java.util.Date;
  * This class represents a message of the day.
  */
 @ApiModel(value = "motd", description = "the message of the day entity")
-public class Motd {
+public class Motd implements Entity {
 
 	private String motdkey; //ID
 	private Date startdate;
@@ -36,95 +38,115 @@ public class Motd {
 	private String audience;
 	private String sessionId;
 	private String sessionkey;
-	private String _id;
-	private String _rev;
+	private String id;
+	private String rev;
 
 	@ApiModelProperty(required = true, value = "the identification string")
+	@JsonView({View.Persistence.class, View.Public.class})
 	public String getMotdkey() {
 		return motdkey;
 	}
 
+	@JsonView({View.Persistence.class, View.Public.class})
 	public void setMotdkey(final String key) {
 		motdkey = key;
 	}
 
 	@ApiModelProperty(required = true, value = "startdate for showing this message (timestamp format)")
+	@JsonView({View.Persistence.class, View.Public.class})
 	public Date getStartdate() {
 		return startdate;
 	}
 
+	@JsonView({View.Persistence.class, View.Public.class})
 	public void setStartdate(final Date timestamp) {
 		startdate = timestamp;
 	}
 
 	@ApiModelProperty(required = true, value = "enddate for showing this message (timestamp format)")
+	@JsonView({View.Persistence.class, View.Public.class})
 	public Date getEnddate() {
 		return enddate;
 	}
 
+	@JsonView({View.Persistence.class, View.Public.class})
 	public void setEnddate(final Date timestamp) {
 		enddate = timestamp;
 	}
 
 	@ApiModelProperty(required = true, value = "tite of the message")
+	@JsonView({View.Persistence.class, View.Public.class})
 	public String getTitle() {
 		return title;
 	}
 
+	@JsonView({View.Persistence.class, View.Public.class})
 	public void setTitle(final String ttitle) {
 		title = ttitle;
 	}
 
 	@ApiModelProperty(required = true, value = "text of the message")
+	@JsonView({View.Persistence.class, View.Public.class})
 	public String getText() {
 		return text;
 	}
 
+	@JsonView({View.Persistence.class, View.Public.class})
 	public void setText(final String ttext) {
 		text = ttext;
 	}
 
 	@ApiModelProperty(required = true, value = "defines the target audience for this motd (one of the following: 'student', 'tutor', 'loggedIn', 'all')")
+	@JsonView({View.Persistence.class, View.Public.class})
 	public String getAudience() {
 		return audience;
 	}
 
+	@JsonView({View.Persistence.class, View.Public.class})
 	public void setAudience(String a) {
 		audience = a;
 	}
 
+	@JsonView({View.Persistence.class, View.Public.class})
 	public String getSessionId() {
 		return sessionId;
 	}
 
+	@JsonView({View.Persistence.class, View.Public.class})
 	public void setSessionId(String sessionId) {
 		this.sessionId = sessionId;
 	}
 
 	@ApiModelProperty(required = true, value = "when audience equals session, the sessionkey referes to the session the messages belong to")
+	@JsonView({View.Persistence.class, View.Public.class})
 	public String getSessionkey() {
 		return sessionkey;
 	}
 
+	@JsonView({View.Persistence.class, View.Public.class})
 	public void setSessionkey(String a) {
 		sessionkey = a;
 	}
 
 	@ApiModelProperty(required = true, value = "the couchDB ID")
-	public String get_id() {
-		return _id;
+	@JsonView({View.Persistence.class, View.Public.class})
+	public String getId() {
+		return id;
 	}
 
-	public void set_id(final String id) {
-		_id = id;
+	@JsonView({View.Persistence.class, View.Public.class})
+	public void setId(final String id) {
+		this.id = id;
 	}
 
-	public void set_rev(final String rev) {
-		_rev = rev;
+	@JsonView({View.Persistence.class, View.Public.class})
+	public void setRevision(final String rev) {
+		this.rev = rev;
 	}
 
-	public String get_rev() {
-		return _rev;
+	@JsonView({View.Persistence.class, View.Public.class})
+	public String getRevision() {
+		return rev;
 	}
 
 	@Override
diff --git a/src/main/java/de/thm/arsnova/entities/serialization/CouchDbTypeFieldConverter.java b/src/main/java/de/thm/arsnova/entities/serialization/CouchDbTypeFieldConverter.java
index fdc84a7f7..0151654ef 100644
--- a/src/main/java/de/thm/arsnova/entities/serialization/CouchDbTypeFieldConverter.java
+++ b/src/main/java/de/thm/arsnova/entities/serialization/CouchDbTypeFieldConverter.java
@@ -23,6 +23,8 @@ import com.fasterxml.jackson.databind.util.Converter;
 import de.thm.arsnova.entities.DbUser;
 import de.thm.arsnova.entities.Entity;
 import de.thm.arsnova.entities.LogEntry;
+import de.thm.arsnova.entities.Motd;
+
 import java.util.HashMap;
 import java.util.Map;
 
@@ -32,6 +34,7 @@ public class CouchDbTypeFieldConverter implements Converter<Class<? extends Enti
 	{
 		typeMapping.put(LogEntry.class, "log");
 		typeMapping.put(DbUser.class, "userdetails");
+		typeMapping.put(Motd.class, "motd");
 	}
 
 	@Override
diff --git a/src/main/java/de/thm/arsnova/persistance/MotdRepository.java b/src/main/java/de/thm/arsnova/persistance/MotdRepository.java
new file mode 100644
index 000000000..9c783165d
--- /dev/null
+++ b/src/main/java/de/thm/arsnova/persistance/MotdRepository.java
@@ -0,0 +1,34 @@
+/*
+ * This file is part of ARSnova Backend.
+ * Copyright (C) 2012-2017 The ARSnova Team
+ *
+ * ARSnova Backend is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * ARSnova Backend is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program.  If not, see <http://www.gnu.org/licenses/>.
+ */
+package de.thm.arsnova.persistance;
+
+import de.thm.arsnova.entities.Motd;
+
+import java.util.List;
+
+public interface MotdRepository {
+	List<Motd> getAdminMotds();
+	List<Motd> getMotdsForAll();
+	List<Motd> getMotdsForLoggedIn();
+	List<Motd> getMotdsForTutors();
+	List<Motd> getMotdsForStudents();
+	List<Motd> getMotdsForSession(final String sessionkey);
+	Motd getMotdByKey(String key);
+	Motd createOrUpdateMotd(Motd motd);
+	boolean deleteMotd(Motd motd);
+}
diff --git a/src/main/java/de/thm/arsnova/persistance/couchdb/CouchDbMotdRepository.java b/src/main/java/de/thm/arsnova/persistance/couchdb/CouchDbMotdRepository.java
new file mode 100644
index 000000000..4aafdb068
--- /dev/null
+++ b/src/main/java/de/thm/arsnova/persistance/couchdb/CouchDbMotdRepository.java
@@ -0,0 +1,121 @@
+/*
+ * This file is part of ARSnova Backend.
+ * Copyright (C) 2012-2017 The ARSnova Team
+ *
+ * ARSnova Backend is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * ARSnova Backend is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program.  If not, see <http://www.gnu.org/licenses/>.
+ */
+package de.thm.arsnova.persistance.couchdb;
+
+import de.thm.arsnova.entities.Motd;
+import de.thm.arsnova.persistance.MotdRepository;
+import de.thm.arsnova.services.ISessionService;
+import org.ektorp.CouchDbConnector;
+import org.ektorp.support.CouchDbRepositorySupport;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.cache.annotation.CacheEvict;
+import org.springframework.cache.annotation.Cacheable;
+
+import java.util.ArrayList;
+import java.util.List;
+
+public class CouchDbMotdRepository extends CouchDbRepositorySupport<Motd> implements MotdRepository {
+	private static final Logger logger = LoggerFactory.getLogger(CouchDbMotdRepository.class);
+
+	@Autowired
+	private ISessionService sessionService;
+
+	public CouchDbMotdRepository(Class<Motd> type, CouchDbConnector db, boolean createIfNotExists) {
+		super(type, db, createIfNotExists);
+	}
+
+	@Override
+	public List<Motd> getAdminMotds() {
+		return getMotds("by_audience_for_global", null);
+	}
+
+	@Override
+	@Cacheable(cacheNames = "motds", key = "'all'")
+	public List<Motd> getMotdsForAll() {
+		return getMotds("by_audience_for_global", "all");
+	}
+
+	@Override
+	@Cacheable(cacheNames = "motds", key = "'loggedIn'")
+	public List<Motd> getMotdsForLoggedIn() {
+		return getMotds("by_audience_for_global", "loggedIn");
+	}
+
+	@Override
+	@Cacheable(cacheNames = "motds", key = "'tutors'")
+	public List<Motd> getMotdsForTutors() {
+		final List<Motd> union = new ArrayList<>();
+		union.addAll(getMotds("by_audience_for_global", "loggedIn"));
+		union.addAll(getMotds("by_audience_for_global", "tutors"));
+
+		return union;
+	}
+
+	@Override
+	@Cacheable(cacheNames = "motds", key = "'students'")
+	public List<Motd> getMotdsForStudents() {
+		final List<Motd> union = new ArrayList<>();
+		union.addAll(getMotds("by_audience_for_global", "loggedIn"));
+		union.addAll(getMotds("by_audience_for_global", "students"));
+
+		return union;
+	}
+
+	@Override
+	@Cacheable(cacheNames = "motds", key = "('session').concat(#p0)")
+	public List<Motd> getMotdsForSession(final String sessionkey) {
+		return getMotds("by_sessionkey", sessionkey);
+	}
+
+	private List<Motd> getMotds(String viewName, String key) {
+		return queryView(viewName, key);
+	}
+
+	@Override
+	public Motd getMotdByKey(String key) {
+		List<Motd> motd = queryView("by_motdkey", key);
+
+		return motd.get(0);
+	}
+
+	@Override
+	@CacheEvict(cacheNames = "motds", key = "#p0.audience.concat(#p0.sessionkey)")
+	public Motd createOrUpdateMotd(Motd motd) {
+		String id = motd.getId();
+		String rev = motd.getRevision();
+
+		if (null != id) {
+			Motd oldMotd = get(id);
+			motd.setMotdkey(oldMotd.getMotdkey());
+			update(motd);
+		} else {
+			motd.setMotdkey(sessionService.generateKeyword());
+			add(motd);
+		}
+
+		return motd;
+	}
+
+	@Override
+	@CacheEvict(cacheNames = "motds", key = "#p0.audience.concat(#p0.sessionkey)")
+	public boolean deleteMotd(Motd motd) {
+		return db.delete(motd) != null;
+	}
+}
diff --git a/src/main/java/de/thm/arsnova/services/MotdService.java b/src/main/java/de/thm/arsnova/services/MotdService.java
index ecda86638..62ae8937f 100644
--- a/src/main/java/de/thm/arsnova/services/MotdService.java
+++ b/src/main/java/de/thm/arsnova/services/MotdService.java
@@ -23,6 +23,7 @@ import de.thm.arsnova.entities.MotdList;
 import de.thm.arsnova.entities.Session;
 import de.thm.arsnova.entities.User;
 import de.thm.arsnova.exceptions.BadRequestException;
+import de.thm.arsnova.persistance.MotdRepository;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.security.access.prepost.PreAuthorize;
 import org.springframework.stereotype.Service;
@@ -47,6 +48,9 @@ public class MotdService implements IMotdService {
 	@Autowired
 	private ISessionService sessionService;
 
+	@Autowired
+	private MotdRepository motdRepository;
+
 	public void setDatabaseDao(final IDatabaseDao databaseDao) {
 		this.databaseDao = databaseDao;
 	}
@@ -54,31 +58,31 @@ public class MotdService implements IMotdService {
   @Override
   @PreAuthorize("isAuthenticated()")
   public Motd getMotd(final String key) {
-    return databaseDao.getMotdByKey(key);
+    return motdRepository.getMotdByKey(key);
   }
 
   @Override
   @PreAuthorize("isAuthenticated() and hasPermission(1,'motd','admin')")
   public List<Motd> getAdminMotds() {
-    return databaseDao.getAdminMotds();
+    return motdRepository.getAdminMotds();
   }
 
 	@Override
 	@PreAuthorize("isAuthenticated() and hasPermission(#sessionkey, 'session', 'owner')")
 	public List<Motd> getAllSessionMotds(final String sessionkey) {
-		return databaseDao.getMotdsForSession(sessionkey);
+		return motdRepository.getMotdsForSession(sessionkey);
 	}
 
 	@Override
 	public List<Motd> getCurrentMotds(final Date clientdate, final String audience, final String sessionkey) {
 		final List<Motd> motds;
 		switch (audience) {
-			case "all": motds = databaseDao.getMotdsForAll(); break;
-			case "loggedIn": motds = databaseDao.getMotdsForLoggedIn(); break;
-			case "students": motds = databaseDao.getMotdsForStudents(); break;
-			case "tutors": motds = databaseDao.getMotdsForTutors(); break;
-			case "session": motds = databaseDao.getMotdsForSession(sessionkey); break;
-			default: motds = databaseDao.getMotdsForAll(); break;
+			case "all": motds = motdRepository.getMotdsForAll(); break;
+			case "loggedIn": motds = motdRepository.getMotdsForLoggedIn(); break;
+			case "students": motds = motdRepository.getMotdsForStudents(); break;
+			case "tutors": motds = motdRepository.getMotdsForTutors(); break;
+			case "session": motds = motdRepository.getMotdsForSession(sessionkey); break;
+			default: motds = motdRepository.getMotdsForAll(); break;
 		}
 		return filterMotdsByDate(motds, clientdate);
 	}
@@ -144,26 +148,26 @@ public class MotdService implements IMotdService {
 
 	private Motd createOrUpdateMotd(final Motd motd) {
 		if (motd.getMotdkey() != null) {
-			Motd oldMotd = databaseDao.getMotdByKey(motd.getMotdkey());
-			if (!(motd.get_id().equals(oldMotd.get_id()) && motd.getSessionkey().equals(oldMotd.getSessionkey())
+			Motd oldMotd = motdRepository.getMotdByKey(motd.getMotdkey());
+			if (!(motd.getId().equals(oldMotd.getId()) && motd.getSessionkey().equals(oldMotd.getSessionkey())
 					&& motd.getAudience().equals(oldMotd.getAudience()))) {
 				throw new BadRequestException();
 			}
 		}
 
-		return databaseDao.createOrUpdateMotd(motd);
+		return motdRepository.createOrUpdateMotd(motd);
 	}
 
 	@Override
 	@PreAuthorize("isAuthenticated() and hasPermission(1,'motd','admin')")
 	public void deleteMotd(Motd motd) {
-		databaseDao.deleteMotd(motd);
+		motdRepository.deleteMotd(motd);
 	}
 
 	@Override
 	@PreAuthorize("isAuthenticated() and hasPermission(#sessionkey, 'session', 'owner')")
 	public void deleteSessionMotd(final String sessionkey, Motd motd) {
-		databaseDao.deleteMotd(motd);
+		motdRepository.deleteMotd(motd);
 	}
 
 	@Override
diff --git a/src/test/java/de/thm/arsnova/dao/StubDatabaseDao.java b/src/test/java/de/thm/arsnova/dao/StubDatabaseDao.java
index daf18a59a..f6b0b176f 100644
--- a/src/test/java/de/thm/arsnova/dao/StubDatabaseDao.java
+++ b/src/test/java/de/thm/arsnova/dao/StubDatabaseDao.java
@@ -632,64 +632,6 @@ public class StubDatabaseDao implements IDatabaseDao {
 		return null;
 	}
 
-	@Override
-	public List<Motd> getAdminMotds() {
-		// TODO Auto-generated method stub
-		return null;
-	}
-
-	@Override
-	public List<Motd> getMotdsForAll() {
-		// TODO Auto-generated method stub
-		return null;
-	}
-
-	@Override
-	public List<Motd> getMotdsForLoggedIn() {
-		// TODO Auto-generated method stub
-		return null;
-	}
-
-	@Override
-	public List<Motd> getMotdsForTutors() {
-		// TODO Auto-generated method stub
-		return null;
-	}
-
-	@Override
-	public List<Motd> getMotdsForStudents() {
-		// TODO Auto-generated method stub
-		return null;
-	}
-
-	@Override
-	public List<Motd> getMotdsForSession(final String sessionkey) {
-		// TODO Auto-generated method stub
-		return null;
-	}
-
-	@Override
-	public List<Motd> getMotds(View view) {
-		return null;
-	}
-
-	@Override
-	public Motd getMotdByKey(String key) {
-		// TODO Auto-generated method stub
-		return null;
-	}
-
-	@Override
-	public Motd createOrUpdateMotd(Motd motd) {
-		// TODO Auto-generated method stub
-		return null;
-	}
-
-	@Override
-	public void deleteMotd(Motd motd) {
-		// TODO Auto-generated method stub
-	}
-
 	@Override
 	public MotdList getMotdListForUser(final String username) {
 		// TODO Auto-generated method stub
-- 
GitLab