From 67566602c90268d4a6b5f549eb7badbd5dbad37f Mon Sep 17 00:00:00 2001 From: Daniel Gerhardt <code@dgerhardt.net> Date: Tue, 20 Feb 2018 00:00:00 +0100 Subject: [PATCH] Improve CouchDB view initialization Views are now checked for existence instead of creating them on every startup. --- .../couchdb/CouchDbInitializer.java | 44 +++++++++++++------ 1 file changed, 31 insertions(+), 13 deletions(-) diff --git a/src/main/java/de/thm/arsnova/persistance/couchdb/CouchDbInitializer.java b/src/main/java/de/thm/arsnova/persistance/couchdb/CouchDbInitializer.java index 6788d3a73..a9c9c8e78 100644 --- a/src/main/java/de/thm/arsnova/persistance/couchdb/CouchDbInitializer.java +++ b/src/main/java/de/thm/arsnova/persistance/couchdb/CouchDbInitializer.java @@ -29,7 +29,10 @@ import javax.script.ScriptException; import java.io.IOException; import java.io.InputStreamReader; import java.util.ArrayList; +import java.util.HashMap; import java.util.List; +import java.util.Map; +import java.util.stream.Collectors; @Component public class CouchDbInitializer implements ResourceLoaderAware { @@ -41,6 +44,7 @@ public class CouchDbInitializer implements ResourceLoaderAware { private CouchDbConnector connector; private ObjectMapper objectMapper; private StatusService statusService; + private boolean migrationStarted = false; public CouchDbInitializer(final CouchDbConnector couchDbConnector, final ObjectMapperFactory objectMapperFactory, final StatusService statusService) { @@ -66,22 +70,30 @@ public class CouchDbInitializer implements ResourceLoaderAware { } protected void createDesignDocs() { - docs.forEach(doc -> { - if (logger.isDebugEnabled()) { - try { - logger.debug("Creating design doc:\n{}", objectMapper.writeValueAsString(doc)); - } catch (JsonProcessingException e) { - logger.warn("Failed to serialize design doc.", e); - } - } + connector.executeBulk(docs.stream().filter(doc -> { try { - final String rev = connector.getCurrentRevision((String) doc.get("_id")); - doc.put("_rev", rev); - connector.update(doc); + if (logger.isDebugEnabled()) { + logger.debug("Checking design doc {}:\n{}", doc.get("_id"), objectMapper.writeValueAsString(doc)); + } + final Map<String, Object> existingDoc = connector.get(HashMap.class, doc.get("_id").toString()); + final String existingViews = objectMapper.writeValueAsString(existingDoc.get("views")); + final String currentViews = objectMapper.writeValueAsString(doc.get("views")); + if (existingViews.equals(currentViews)) { + logger.debug("Design doc {} already exists.", doc.get("_id")); + return false; + } else { + logger.debug("Design doc {} will be updated.", doc.get("_id")); + doc.put("_rev", existingDoc.get("_rev")); + return true; + } } catch (final DocumentNotFoundException e) { - connector.create(doc); + logger.debug("Design doc {} will be created.", doc.get("_id")); + return true; + } catch (JsonProcessingException e) { + logger.warn("Failed to serialize design doc {}.", doc.get("_id"), e); + return false; } - }); + }).collect(Collectors.toList())); } protected void migrate() { @@ -104,6 +116,12 @@ public class CouchDbInitializer implements ResourceLoaderAware { @EventListener private void onApplicationEvent(ContextRefreshedEvent event) throws IOException, ScriptException { + /* Event is triggered more than once */ + if (migrationStarted) { + return; + } + migrationStarted = true; + statusService.putMaintenanceReason(this.getClass(), "Data migration active"); loadDesignDocFiles(); createDesignDocs(); -- GitLab