From: Simon Brandhof Date: Wed, 4 Mar 2015 15:29:33 +0000 (+0100) Subject: SONAR-6229 improve performance of ES indexing at startup X-Git-Tag: 5.1-RC1~16 X-Git-Url: https://source.dussan.org/?a=commitdiff_plain;h=d09c8de89e75245a72bc85c844825c37eee714d7;p=sonarqube.git SONAR-6229 improve performance of ES indexing at startup --- diff --git a/server/sonar-server/src/main/java/org/sonar/server/activity/index/ActivityIndexDefinition.java b/server/sonar-server/src/main/java/org/sonar/server/activity/index/ActivityIndexDefinition.java index 9fd5756c51b..bac57c04233 100644 --- a/server/sonar-server/src/main/java/org/sonar/server/activity/index/ActivityIndexDefinition.java +++ b/server/sonar-server/src/main/java/org/sonar/server/activity/index/ActivityIndexDefinition.java @@ -50,7 +50,6 @@ public class ActivityIndexDefinition implements IndexDefinition { @Override public void define(IndexDefinitionContext context) { NewIndex index = context.create(INDEX); - // refresh is always handled by ActivityIndexer index.getSettings().put("index.refresh_interval", "-1"); index.getSettings().put("analysis.analyzer.default.type", "keyword"); diff --git a/server/sonar-server/src/main/java/org/sonar/server/activity/index/ActivityIndexer.java b/server/sonar-server/src/main/java/org/sonar/server/activity/index/ActivityIndexer.java index 2b4ba6e678e..8a179f99fd5 100644 --- a/server/sonar-server/src/main/java/org/sonar/server/activity/index/ActivityIndexer.java +++ b/server/sonar-server/src/main/java/org/sonar/server/activity/index/ActivityIndexer.java @@ -19,7 +19,6 @@ */ package org.sonar.server.activity.index; -import org.elasticsearch.action.support.replication.ReplicationType; import org.elasticsearch.action.update.UpdateRequest; import org.sonar.core.persistence.DbSession; import org.sonar.server.db.DbClient; @@ -34,7 +33,6 @@ import java.util.Iterator; * Add to Elasticsearch index {@link org.sonar.server.activity.index.ActivityIndexDefinition} the rows of * db table ACTIVITIES that are not indexed yet *

- * TODO idea of improvement - index asynchronously with UpdateRequest#replicationType(ReplicationType.ASYNC) */ public class ActivityIndexer extends BaseIndexer { @@ -47,7 +45,7 @@ public class ActivityIndexer extends BaseIndexer { @Override protected long doIndex(long lastUpdatedAt) { - final BulkIndexer bulk = new BulkIndexer(esClient, ActivityIndexDefinition.INDEX); + BulkIndexer bulk = new BulkIndexer(esClient, ActivityIndexDefinition.INDEX); bulk.setLarge(lastUpdatedAt == 0L); DbSession dbSession = dbClient.openSession(false); @@ -64,7 +62,7 @@ public class ActivityIndexer extends BaseIndexer { } public long index(Iterator activities) { - final BulkIndexer bulk = new BulkIndexer(esClient, ActivityIndexDefinition.INDEX); + BulkIndexer bulk = new BulkIndexer(esClient, ActivityIndexDefinition.INDEX); return doIndex(bulk, activities); } @@ -85,7 +83,6 @@ public class ActivityIndexer extends BaseIndexer { private UpdateRequest newUpsertRequest(ActivityDoc doc) { return new UpdateRequest(ActivityIndexDefinition.INDEX, ActivityIndexDefinition.TYPE, doc.getKey()) .doc(doc.getFields()) - .upsert(doc.getFields()) - .replicationType(ReplicationType.ASYNC); + .upsert(doc.getFields()); } } diff --git a/server/sonar-server/src/main/java/org/sonar/server/es/BaseIndexer.java b/server/sonar-server/src/main/java/org/sonar/server/es/BaseIndexer.java index 5f88f181b3c..5f5f564058d 100644 --- a/server/sonar-server/src/main/java/org/sonar/server/es/BaseIndexer.java +++ b/server/sonar-server/src/main/java/org/sonar/server/es/BaseIndexer.java @@ -37,6 +37,17 @@ public abstract class BaseIndexer implements ServerComponent, Startable { protected final EsClient esClient; private volatile long lastUpdatedAt = 0L; + /** + * Indexers are disabled during server startup, to avoid too many consecutive refreshes of the same index + * An example is RegisterQualityProfiles. If {@link org.sonar.server.activity.index.ActivityIndexer} is enabled by + * default during startup, then each new activated rule generates a bulk request with a single document and then + * asks for index refresh -> big performance hit. + * + * Indices are populated and refreshed when all startup components have been executed. See + * {@link org.sonar.server.search.IndexSynchronizer} + */ + private boolean enabled = false; + protected BaseIndexer(EsClient client, long threadKeepAliveSeconds, String indexName, String typeName) { this.indexName = indexName; this.typeName = typeName; @@ -46,26 +57,33 @@ public abstract class BaseIndexer implements ServerComponent, Startable { } public void index() { - final long requestedAt = System.currentTimeMillis(); - Future submit = executor.submit(new Runnable() { - @Override - public void run() { - if (requestedAt > lastUpdatedAt) { - long l = doIndex(lastUpdatedAt); - // l can be 0 if no documents were indexed - lastUpdatedAt = Math.max(l, lastUpdatedAt); + if (enabled) { + final long requestedAt = System.currentTimeMillis(); + Future submit = executor.submit(new Runnable() { + @Override + public void run() { + if (requestedAt > lastUpdatedAt) { + long l = doIndex(lastUpdatedAt); + // l can be 0 if no documents were indexed + lastUpdatedAt = Math.max(l, lastUpdatedAt); + } } + }); + try { + Uninterruptibles.getUninterruptibly(submit); + } catch (ExecutionException e) { + Throwables.propagate(e); } - }); - try { - Uninterruptibles.getUninterruptibly(submit); - } catch (ExecutionException e) { - Throwables.propagate(e); } } protected abstract long doIndex(long lastUpdatedAt); + public BaseIndexer setEnabled(boolean b) { + this.enabled = b; + return this; + } + @Override public void start() { lastUpdatedAt = esClient.getLastUpdatedAt(indexName, typeName); diff --git a/server/sonar-server/src/main/java/org/sonar/server/es/IndexCreator.java b/server/sonar-server/src/main/java/org/sonar/server/es/IndexCreator.java index 909fd00bcba..1ef1d9ce3b8 100644 --- a/server/sonar-server/src/main/java/org/sonar/server/es/IndexCreator.java +++ b/server/sonar-server/src/main/java/org/sonar/server/es/IndexCreator.java @@ -45,17 +45,17 @@ public class IndexCreator implements ServerComponent, Startable { private static final String SETTING_HASH = "sonar_hash"; private final EsClient client; - private final IndexRegistry registry; + private final IndexDefinitions definitions; - public IndexCreator(EsClient client, IndexRegistry registry) { + public IndexCreator(EsClient client, IndexDefinitions definitions) { this.client = client; - this.registry = registry; + this.definitions = definitions; } @Override public void start() { // create indices that do not exist or that have a new definition (different mapping, cluster enabled, ...) - for (IndexRegistry.Index index : registry.getIndices().values()) { + for (IndexDefinitions.Index index : definitions.getIndices().values()) { boolean exists = client.prepareIndicesExist(index.getName()).get().isExists(); if (exists && needsToDeleteIndex(index)) { LOGGER.info(String.format("Delete index %s (settings changed)", index.getName())); @@ -73,7 +73,7 @@ public class IndexCreator implements ServerComponent, Startable { // nothing to do } - private void createIndex(IndexRegistry.Index index) { + private void createIndex(IndexDefinitions.Index index) { LOGGER.info(String.format("Create index %s", index.getName())); ImmutableSettings.Builder settings = ImmutableSettings.builder(); settings.put(index.getSettings()); @@ -88,7 +88,7 @@ public class IndexCreator implements ServerComponent, Startable { client.waitForStatus(ClusterHealthStatus.YELLOW); // create types - for (Map.Entry entry : index.getTypes().entrySet()) { + for (Map.Entry entry : index.getTypes().entrySet()) { LOGGER.info(String.format("Create type %s/%s", index.getName(), entry.getKey())); PutMappingResponse mappingResponse = client.preparePutMapping(index.getName()) .setType(entry.getKey()) @@ -106,7 +106,7 @@ public class IndexCreator implements ServerComponent, Startable { client.nativeClient().admin().indices().prepareDelete(indexName).get(); } - private boolean needsToDeleteIndex(IndexRegistry.Index index) { + private boolean needsToDeleteIndex(IndexDefinitions.Index index) { boolean toBeDeleted = false; String hash = client.nativeClient().admin().indices().prepareGetSettings(index.getName()).get().getSetting(index.getName(), "index." + SETTING_HASH); if (hash != null) { diff --git a/server/sonar-server/src/main/java/org/sonar/server/es/IndexDefinitionHash.java b/server/sonar-server/src/main/java/org/sonar/server/es/IndexDefinitionHash.java index 6df309abaa2..6b2c208d022 100644 --- a/server/sonar-server/src/main/java/org/sonar/server/es/IndexDefinitionHash.java +++ b/server/sonar-server/src/main/java/org/sonar/server/es/IndexDefinitionHash.java @@ -37,7 +37,7 @@ class IndexDefinitionHash { private static final char DELIMITER = ','; - String of(IndexRegistry.Index index) { + String of(IndexDefinitions.Index index) { return of(index.getSettings().getAsMap(), index.getTypes()); } @@ -50,8 +50,8 @@ class IndexDefinitionHash { } private void appendObject(StringBuilder sb, Object value) { - if (value instanceof IndexRegistry.IndexType) { - appendIndexType(sb, (IndexRegistry.IndexType) value); + if (value instanceof IndexDefinitions.IndexType) { + appendIndexType(sb, (IndexDefinitions.IndexType) value); } else if (value instanceof Map) { appendMap(sb, (Map) value); } else if (value instanceof Iterable) { @@ -61,7 +61,7 @@ class IndexDefinitionHash { } } - private void appendIndexType(StringBuilder sb, IndexRegistry.IndexType type) { + private void appendIndexType(StringBuilder sb, IndexDefinitions.IndexType type) { appendMap(sb, type.getAttributes()); } diff --git a/server/sonar-server/src/main/java/org/sonar/server/es/IndexDefinitions.java b/server/sonar-server/src/main/java/org/sonar/server/es/IndexDefinitions.java new file mode 100644 index 00000000000..771f9b8ed31 --- /dev/null +++ b/server/sonar-server/src/main/java/org/sonar/server/es/IndexDefinitions.java @@ -0,0 +1,116 @@ +/* + * SonarQube, open source software quality management tool. + * Copyright (C) 2008-2014 SonarSource + * mailto:contact AT sonarsource DOT com + * + * SonarQube is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 3 of the License, or (at your option) any later version. + * + * SonarQube 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ +package org.sonar.server.es; + +import com.google.common.collect.ImmutableMap; +import com.google.common.collect.Maps; +import org.elasticsearch.common.settings.Settings; +import org.picocontainer.Startable; +import org.sonar.api.ServerComponent; + +import java.util.Map; + +/** + * This class collects definitions of all Elasticsearch indices during server startup + */ +public class IndexDefinitions implements ServerComponent, Startable { + + /** + * Immutable copy of {@link org.sonar.server.es.NewIndex} + */ + public static class Index { + private final String name; + private final Settings settings; + private final Map types; + + Index(NewIndex newIndex) { + this.name = newIndex.getName(); + this.settings = newIndex.getSettings().build(); + ImmutableMap.Builder builder = ImmutableMap.builder(); + for (NewIndex.NewIndexType newIndexType : newIndex.getTypes().values()) { + IndexType type = new IndexType(newIndexType); + builder.put(type.getName(), type); + } + this.types = builder.build(); + } + + public String getName() { + return name; + } + + public Settings getSettings() { + return settings; + } + + public Map getTypes() { + return types; + } + } + + /** + * Immutable copy of {@link org.sonar.server.es.NewIndex.NewIndexType} + */ + public static class IndexType { + private final String name; + private final Map attributes; + + private IndexType(NewIndex.NewIndexType newType) { + this.name = newType.getName(); + this.attributes = ImmutableMap.copyOf(newType.getAttributes()); + } + + public String getName() { + return name; + } + + public Map getAttributes() { + return attributes; + } + } + + private final Map byKey = Maps.newHashMap(); + private final IndexDefinition[] defs; + + public IndexDefinitions(IndexDefinition[] defs) { + this.defs = defs; + } + + public Map getIndices() { + return byKey; + } + + @Override + public void start() { + // collect definitions + IndexDefinition.IndexDefinitionContext context = new IndexDefinition.IndexDefinitionContext(); + for (IndexDefinition definition : defs) { + definition.define(context); + } + + for (Map.Entry entry : context.getIndices().entrySet()) { + byKey.put(entry.getKey(), new Index(entry.getValue())); + } + } + + @Override + public void stop() { + // nothing to do + } +} diff --git a/server/sonar-server/src/main/java/org/sonar/server/es/IndexRegistry.java b/server/sonar-server/src/main/java/org/sonar/server/es/IndexRegistry.java deleted file mode 100644 index 972830067be..00000000000 --- a/server/sonar-server/src/main/java/org/sonar/server/es/IndexRegistry.java +++ /dev/null @@ -1,116 +0,0 @@ -/* - * SonarQube, open source software quality management tool. - * Copyright (C) 2008-2014 SonarSource - * mailto:contact AT sonarsource DOT com - * - * SonarQube is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 3 of the License, or (at your option) any later version. - * - * SonarQube 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 - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with this program; if not, write to the Free Software Foundation, - * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - */ -package org.sonar.server.es; - -import com.google.common.collect.ImmutableMap; -import com.google.common.collect.Maps; -import org.elasticsearch.common.settings.Settings; -import org.picocontainer.Startable; -import org.sonar.api.ServerComponent; - -import java.util.Map; - -/** - * This class collects definitions of all Elasticsearch indices during server startup - */ -public class IndexRegistry implements ServerComponent, Startable { - - /** - * Immutable copy of {@link org.sonar.server.es.NewIndex} - */ - public static class Index { - private final String name; - private final Settings settings; - private final Map types; - - Index(NewIndex newIndex) { - this.name = newIndex.getName(); - this.settings = newIndex.getSettings().build(); - ImmutableMap.Builder builder = ImmutableMap.builder(); - for (NewIndex.NewIndexType newIndexType : newIndex.getTypes().values()) { - IndexType type = new IndexType(newIndexType); - builder.put(type.getName(), type); - } - this.types = builder.build(); - } - - public String getName() { - return name; - } - - public Settings getSettings() { - return settings; - } - - public Map getTypes() { - return types; - } - } - - /** - * Immutable copy of {@link org.sonar.server.es.NewIndex.NewIndexType} - */ - public static class IndexType { - private final String name; - private final Map attributes; - - private IndexType(NewIndex.NewIndexType newType) { - this.name = newType.getName(); - this.attributes = ImmutableMap.copyOf(newType.getAttributes()); - } - - public String getName() { - return name; - } - - public Map getAttributes() { - return attributes; - } - } - - private final Map byKey = Maps.newHashMap(); - private final IndexDefinition[] defs; - - public IndexRegistry(IndexDefinition[] defs) { - this.defs = defs; - } - - public Map getIndices() { - return byKey; - } - - @Override - public void start() { - // collect definitions - IndexDefinition.IndexDefinitionContext context = new IndexDefinition.IndexDefinitionContext(); - for (IndexDefinition definition : defs) { - definition.define(context); - } - - for (Map.Entry entry : context.getIndices().entrySet()) { - byKey.put(entry.getKey(), new Index(entry.getValue())); - } - } - - @Override - public void stop() { - // nothing to do - } -} diff --git a/server/sonar-server/src/main/java/org/sonar/server/platform/ServerComponents.java b/server/sonar-server/src/main/java/org/sonar/server/platform/ServerComponents.java index dd409d3e8ae..66c8d2ff0ec 100644 --- a/server/sonar-server/src/main/java/org/sonar/server/platform/ServerComponents.java +++ b/server/sonar-server/src/main/java/org/sonar/server/platform/ServerComponents.java @@ -136,7 +136,7 @@ import org.sonar.server.duplication.ws.DuplicationsParser; import org.sonar.server.duplication.ws.DuplicationsWs; import org.sonar.server.es.EsClient; import org.sonar.server.es.IndexCreator; -import org.sonar.server.es.IndexRegistry; +import org.sonar.server.es.IndexDefinitions; import org.sonar.server.issue.ActionService; import org.sonar.server.issue.AddTagsAction; import org.sonar.server.issue.AssignAction; @@ -485,7 +485,7 @@ class ServerComponents { pico.addSingleton(Periods.class); pico.addSingleton(ServerWs.class); pico.addSingleton(BackendCleanup.class); - pico.addSingleton(IndexRegistry.class); + pico.addSingleton(IndexDefinitions.class); pico.addSingleton(IndexCreator.class); // Activity @@ -847,8 +847,8 @@ class ServerComponents { DoPrivileged.execute(new DoPrivileged.Task() { @Override protected void doPrivileged() { - startupContainer.getComponentsByType(IndexSynchronizer.class).get(0).execute(); startupContainer.startComponents(); + startupContainer.getComponentByType(IndexSynchronizer.class).execute(); startupContainer.getComponentByType(ServerLifecycleNotifier.class).notifyStart(); } }); diff --git a/server/sonar-server/src/main/java/org/sonar/server/search/IndexSynchronizer.java b/server/sonar-server/src/main/java/org/sonar/server/search/IndexSynchronizer.java index b4499a4d20c..6e0a4dca98a 100644 --- a/server/sonar-server/src/main/java/org/sonar/server/search/IndexSynchronizer.java +++ b/server/sonar-server/src/main/java/org/sonar/server/search/IndexSynchronizer.java @@ -49,6 +49,11 @@ public class IndexSynchronizer { private final ViewIndexer viewIndexer; private final ActivityIndexer activityIndexer; + /** + * Limitation - {@link org.sonar.server.es.BaseIndexer} are not injected through an array or a collection + * because we need {@link org.sonar.server.issue.index.IssueAuthorizationIndexer} to be executed before + * {@link org.sonar.server.issue.index.IssueIndexer} + */ public IndexSynchronizer(DbClient db, IndexClient index, SourceLineIndexer sourceLineIndexer, IssueAuthorizationIndexer issueAuthorizationIndexer, IssueIndexer issueIndexer, UserIndexer userIndexer, ViewIndexer viewIndexer, ActivityIndexer activityIndexer) { @@ -73,30 +78,29 @@ public class IndexSynchronizer { } LOG.info("Index activities"); - activityIndexer.index(); + activityIndexer.setEnabled(true).index(); LOG.info("Index issues"); - issueAuthorizationIndexer.index(); - issueIndexer.index(); + issueAuthorizationIndexer.setEnabled(true).index(); + issueIndexer.setEnabled(true).index(); - LOG.info("Index source files"); - sourceLineIndexer.index(); + LOG.info("Index source lines"); + sourceLineIndexer.setEnabled(true).index(); LOG.info("Index users"); - userIndexer.index(); + userIndexer.setEnabled(true).index(); LOG.info("Index views"); - viewIndexer.index(); + viewIndexer.setEnabled(true).index(); } void synchronize(DbSession session, Dao dao, Index index) { long count = index.getIndexStat().getDocumentCount(); Date lastSynch = index.getLastSynchronization(); + LOG.info("Index {}s", index.getIndexType()); if (count <= 0) { - LOG.info("Index {}s", index.getIndexType()); dao.synchronizeAfter(session); } else { - LOG.info("Index {}s for updates after {}", index.getIndexType(), lastSynch); dao.synchronizeAfter(session, lastSynch); } } diff --git a/server/sonar-server/src/test/java/org/sonar/server/activity/ActivityServiceTest.java b/server/sonar-server/src/test/java/org/sonar/server/activity/ActivityServiceTest.java index 14807cdde9c..d12d072f1f3 100644 --- a/server/sonar-server/src/test/java/org/sonar/server/activity/ActivityServiceTest.java +++ b/server/sonar-server/src/test/java/org/sonar/server/activity/ActivityServiceTest.java @@ -57,7 +57,10 @@ public class ActivityServiceTest { ActivityDao activityDao = new ActivityDao(db.myBatis(), system); IssueDao issueDao = new IssueDao(db.myBatis()); DbClient dbClient = new DbClient(db.database(), db.myBatis(), issueDao, activityDao); - service = new ActivityService(dbClient, new ActivityIndexer(dbClient, es.client())); + ActivityIndexer indexer = new ActivityIndexer(dbClient, es.client()); + // indexers are disabled by default + indexer.setEnabled(true); + service = new ActivityService(dbClient, indexer); } @Test diff --git a/server/sonar-server/src/test/java/org/sonar/server/es/EsTester.java b/server/sonar-server/src/test/java/org/sonar/server/es/EsTester.java index 09aaf8cd403..5c49de4aef1 100644 --- a/server/sonar-server/src/test/java/org/sonar/server/es/EsTester.java +++ b/server/sonar-server/src/test/java/org/sonar/server/es/EsTester.java @@ -103,7 +103,7 @@ public class EsTester extends ExternalResource { ComponentContainer container = new ComponentContainer(); container.addSingletons(definitions); container.addSingleton(client); - container.addSingleton(IndexRegistry.class); + container.addSingleton(IndexDefinitions.class); container.addSingleton(IndexCreator.class); container.startComponents(); } diff --git a/server/sonar-server/src/test/java/org/sonar/server/es/IndexCreatorTest.java b/server/sonar-server/src/test/java/org/sonar/server/es/IndexCreatorTest.java index 06ba9d18d4a..ac55e4e4c53 100644 --- a/server/sonar-server/src/test/java/org/sonar/server/es/IndexCreatorTest.java +++ b/server/sonar-server/src/test/java/org/sonar/server/es/IndexCreatorTest.java @@ -41,7 +41,7 @@ public class IndexCreatorTest { public void create_index() throws Exception { assertThat(mappings()).isEmpty(); - IndexRegistry registry = new IndexRegistry(new IndexDefinition[] {new FakeIndexDefinition()}); + IndexDefinitions registry = new IndexDefinitions(new IndexDefinition[] {new FakeIndexDefinition()}); registry.start(); IndexCreator creator = new IndexCreator(es.client(), registry); creator.start(); @@ -66,7 +66,7 @@ public class IndexCreatorTest { assertThat(mappings()).isEmpty(); // v1 - IndexRegistry registry = new IndexRegistry(new IndexDefinition[] {new FakeIndexDefinition()}); + IndexDefinitions registry = new IndexDefinitions(new IndexDefinition[] {new FakeIndexDefinition()}); registry.start(); IndexCreator creator = new IndexCreator(es.client(), registry); creator.start(); @@ -75,7 +75,7 @@ public class IndexCreatorTest { assertThat(hashV1).isNotEmpty(); // v2 - registry = new IndexRegistry(new IndexDefinition[] {new FakeIndexDefinitionV2()}); + registry = new IndexDefinitions(new IndexDefinition[] {new FakeIndexDefinitionV2()}); registry.start(); creator = new IndexCreator(es.client(), registry); creator.start(); diff --git a/server/sonar-server/src/test/java/org/sonar/server/es/IndexDefinitionHashTest.java b/server/sonar-server/src/test/java/org/sonar/server/es/IndexDefinitionHashTest.java index 958247d87a5..20cff8f8548 100644 --- a/server/sonar-server/src/test/java/org/sonar/server/es/IndexDefinitionHashTest.java +++ b/server/sonar-server/src/test/java/org/sonar/server/es/IndexDefinitionHashTest.java @@ -29,7 +29,7 @@ public class IndexDefinitionHashTest { @Test public void of() throws Exception { - IndexRegistry.Index indexV1 = new IndexRegistry.Index(createIndex()); + IndexDefinitions.Index indexV1 = new IndexDefinitions.Index(createIndex()); String hashV1 = new IndexDefinitionHash().of(indexV1); assertThat(hashV1).isNotEmpty(); // always the same @@ -37,7 +37,7 @@ public class IndexDefinitionHashTest { NewIndex newIndexV2 = createIndex(); newIndexV2.getTypes().get("fake").createIntegerField("max"); - String hashV2 = new IndexDefinitionHash().of(new IndexRegistry.Index(newIndexV2)); + String hashV2 = new IndexDefinitionHash().of(new IndexDefinitions.Index(newIndexV2)); assertThat(hashV2).isNotEmpty().isNotEqualTo(hashV1); } diff --git a/server/sonar-server/src/test/java/org/sonar/server/issue/index/IssueIndexerTest.java b/server/sonar-server/src/test/java/org/sonar/server/issue/index/IssueIndexerTest.java index cc87af2c9a8..f32df80aa98 100644 --- a/server/sonar-server/src/test/java/org/sonar/server/issue/index/IssueIndexerTest.java +++ b/server/sonar-server/src/test/java/org/sonar/server/issue/index/IssueIndexerTest.java @@ -57,6 +57,15 @@ public class IssueIndexerTest { assertThat(esTester.countDocuments(IssueIndexDefinition.INDEX, IssueIndexDefinition.TYPE_ISSUE)).isEqualTo(0L); } + @Test + public void index_nothing_if_disabled() throws Exception { + dbTester.prepareDbUnit(getClass(), "index.xml"); + + createIndexer().setEnabled(false).index(); + + assertThat(esTester.countDocuments("issues", "issue")).isEqualTo(0); + } + @Test public void index() throws Exception { dbTester.prepareDbUnit(getClass(), "index.xml"); @@ -82,6 +91,8 @@ public class IssueIndexerTest { } private IssueIndexer createIndexer() { - return new IssueIndexer(new DbClient(dbTester.database(), dbTester.myBatis()), esTester.client()); + IssueIndexer indexer = new IssueIndexer(new DbClient(dbTester.database(), dbTester.myBatis()), esTester.client()); + indexer.setEnabled(true); + return indexer; } } diff --git a/server/sonar-server/src/test/java/org/sonar/server/source/index/SourceLineIndexerTest.java b/server/sonar-server/src/test/java/org/sonar/server/source/index/SourceLineIndexerTest.java index 5ba75c5f6ec..a9b87db14d5 100644 --- a/server/sonar-server/src/test/java/org/sonar/server/source/index/SourceLineIndexerTest.java +++ b/server/sonar-server/src/test/java/org/sonar/server/source/index/SourceLineIndexerTest.java @@ -68,6 +68,7 @@ public class SourceLineIndexerTest { es.truncateIndices(); db.truncateTables(); indexer = new SourceLineIndexer(new DbClient(db.database(), db.myBatis()), es.client()); + indexer.setEnabled(true); } @Test diff --git a/server/sonar-server/src/test/java/org/sonar/server/user/index/UserIndexerTest.java b/server/sonar-server/src/test/java/org/sonar/server/user/index/UserIndexerTest.java index fdbcefb81ac..812b703252a 100644 --- a/server/sonar-server/src/test/java/org/sonar/server/user/index/UserIndexerTest.java +++ b/server/sonar-server/src/test/java/org/sonar/server/user/index/UserIndexerTest.java @@ -74,7 +74,17 @@ public class UserIndexerTest { assertThat(doc.updatedAt()).isEqualTo(1500000000000L); } + @Test + public void do_nothing_if_disabled() throws Exception { + dbTester.prepareDbUnit(getClass(), "index.xml"); + + createIndexer().setEnabled(false).index(); + assertThat(esTester.countDocuments("users", "user")).isEqualTo(0); + } + private UserIndexer createIndexer() { - return new UserIndexer(new DbClient(dbTester.database(), dbTester.myBatis()), esTester.client()); + UserIndexer indexer = new UserIndexer(new DbClient(dbTester.database(), dbTester.myBatis()), esTester.client()); + indexer.setEnabled(true); + return indexer; } } diff --git a/server/sonar-server/src/test/java/org/sonar/server/view/index/ViewIndexerTest.java b/server/sonar-server/src/test/java/org/sonar/server/view/index/ViewIndexerTest.java index b809a46922e..9656c199948 100644 --- a/server/sonar-server/src/test/java/org/sonar/server/view/index/ViewIndexerTest.java +++ b/server/sonar-server/src/test/java/org/sonar/server/view/index/ViewIndexerTest.java @@ -55,6 +55,7 @@ public class ViewIndexerTest { dbTester.truncateTables(); esTester.truncateIndices(); indexer = new ViewIndexer(new DbClient(dbTester.database(), dbTester.myBatis(), new ComponentDao()), esTester.client()); + indexer.setEnabled(true); } @Test diff --git a/server/sonar-web/src/main/webapp/WEB-INF/app/controllers/profiles_controller.rb b/server/sonar-web/src/main/webapp/WEB-INF/app/controllers/profiles_controller.rb index 2b107edfefb..79b88b22bb0 100644 --- a/server/sonar-web/src/main/webapp/WEB-INF/app/controllers/profiles_controller.rb +++ b/server/sonar-web/src/main/webapp/WEB-INF/app/controllers/profiles_controller.rb @@ -268,6 +268,7 @@ class ProfilesController < ApplicationController require_parameters 'key' @profile = Internal.qprofile_loader.getByKey(params[:key]) + not_found('Quality profile does not exist') unless @profile search = {'profileKey' => @profile.key().to_s, 'since' => params[:since], 'to' => params[:to], 'p' => params[:p]} result = Internal.component(Java::OrgSonarServerActivity::RubyQProfileActivityService.java_class).search(search) @changes = result.activities diff --git a/server/sonar-web/src/main/webapp/WEB-INF/app/views/profiles/changelog.html.erb b/server/sonar-web/src/main/webapp/WEB-INF/app/views/profiles/changelog.html.erb index 035bf52d2d5..f807ae791c2 100644 --- a/server/sonar-web/src/main/webapp/WEB-INF/app/views/profiles/changelog.html.erb +++ b/server/sonar-web/src/main/webapp/WEB-INF/app/views/profiles/changelog.html.erb @@ -37,19 +37,19 @@ %> <% - action = change.action() + action = change.getAction() action_message = message('quality_profiles.changelog.' + action.downcase) if action if change.authorName() && !change.authorName().empty?() author = change.authorName() - elsif change.login() && !change.login().empty?() - author = change.login() + elsif change.login() && !change.getLogin().empty?() + author = change.getLogin() else author = 'System' end rule = change.ruleName() ? change.ruleName() : change.ruleKey() %> - <%= Internal.i18n.formatDateTime(change.time()) -%> + <%= Internal.i18n.formatDateTime(change.getCreatedAt()) -%> <%= author %> <%= action_message %> <%= rule %>