import org.sonar.core.qualityprofile.db.QualityProfileKey;
import org.sonar.server.es.ESNode;
import org.sonar.server.qualityprofile.ActiveRule;
-import org.sonar.server.rule2.index.RuleIndexDefinition;
import org.sonar.server.search.BaseIndex;
+import org.sonar.server.search.IndexDefinition;
import java.io.IOException;
import java.util.ArrayList;
public class ActiveRuleIndex extends BaseIndex<ActiveRule, ActiveRuleDto, ActiveRuleKey> {
public ActiveRuleIndex(ActiveRuleNormalizer normalizer, WorkQueue workQueue, ESNode node) {
- super(new ActiveRuleIndexDefinition(), normalizer, workQueue, node);
+ super(IndexDefinition.ACTIVE_RULE, normalizer, workQueue, node);
}
@Override
.startObject(this.indexDefinition.getIndexType())
.field("dynamic", "strict")
.startObject("_parent")
- .field("type", new RuleIndexDefinition().getIndexType())
+ .field("type", this.getParentType())
.endObject()
.startObject("_id")
.field("path", ActiveRuleNormalizer.ActiveRuleField.KEY.key())
}
private String getParentType() {
- return new RuleIndexDefinition().getIndexType();
+ return IndexDefinition.RULE.getIndexType();
}
+++ /dev/null
-/*
- * 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.qualityprofile.index;
-
-import org.sonar.server.search.IndexDefinition;
-
-public class ActiveRuleIndexDefinition implements IndexDefinition {
-
- private static final String INDEX_NAME = "rules2";
- private static final String INDEX_TYPE = "activeRule2";
-
- @Override
- public String getIndexName() {
- return ActiveRuleIndexDefinition.INDEX_NAME;
- }
-
- @Override
- public String getIndexType() {
- return ActiveRuleIndexDefinition.INDEX_TYPE;
- }
-}
package org.sonar.server.qualityprofile.index;
import com.google.common.base.Preconditions;
+import com.google.common.collect.ImmutableList;
import org.elasticsearch.action.update.UpdateRequest;
import org.sonar.core.persistence.DbSession;
import org.sonar.core.qualityprofile.db.ActiveRuleDto;
import org.sonar.core.qualityprofile.db.QualityProfileDto;
import org.sonar.server.db.DbClient;
import org.sonar.server.search.BaseNormalizer;
+import org.sonar.server.search.IndexDefinition;
import java.util.ArrayList;
import java.util.HashMap;
+import java.util.List;
import java.util.Map;
public class ActiveRuleNormalizer extends BaseNormalizer<ActiveRuleDto, ActiveRuleKey> {
}
public ActiveRuleNormalizer(DbClient db) {
- super(db);
+ super(IndexDefinition.ACTIVE_RULE, db);
}
@Override
- public UpdateRequest normalize(ActiveRuleKey key) {
- DbSession dbSession = db().openSession(false);
+ public List<UpdateRequest> normalize(ActiveRuleKey key) {
+ DbSession dbSession = db.openSession(false);
+ List<UpdateRequest> requests = new ArrayList<UpdateRequest>();
try {
- return normalize(db().activeRuleDao().getByKey(key, dbSession));
+ requests.addAll(normalize(db.activeRuleDao().getByKey(key, dbSession)));
+ for (ActiveRuleParamDto param : db.activeRuleDao().findParamsByKey(key, dbSession)) {
+ requests.addAll(this.normalize(param, key));
+ }
} finally {
dbSession.close();
}
+ return requests;
}
- public UpdateRequest normalize(ActiveRuleParamDto param, ActiveRuleKey key) {
+ public List<UpdateRequest> normalize(ActiveRuleParamDto param, ActiveRuleKey key) {
Preconditions.checkArgument(key != null, "Cannot normalize ActiveRuleParamDto for null key of ActiveRule");
Map<String, Object> newParam = new HashMap<String, Object>();
newParam.put(ActiveRuleParamField.NAME.key(), param.getKey());
newParam.put(ActiveRuleParamField.VALUE.key(), param.getValue());
- return this.nestedUpsert(ActiveRuleField.PARAMS.key(), param.getKey(), newParam)
- .routing(key.ruleKey().toString());
+ return ImmutableList.of(this.nestedUpsert(ActiveRuleField.PARAMS.key(), param.getKey(), newParam)
+ .routing(key.ruleKey().toString()));
}
@Override
- public UpdateRequest normalize(ActiveRuleDto activeRuleDto) {
+ public List<UpdateRequest> normalize(ActiveRuleDto activeRuleDto) {
ActiveRuleKey key = activeRuleDto.getKey();
Preconditions.checkArgument(key != null, "Cannot normalize ActiveRuleDto with null key");
upsert.put(ActiveRuleField.PARAMS.key(), new ArrayList());
/* Creating updateRequest */
- return new UpdateRequest()
+ return ImmutableList.of(new UpdateRequest()
.routing(key.ruleKey().toString())
.id(activeRuleDto.getKey().toString())
.parent(activeRuleDto.getKey().ruleKey().toString())
.doc(newRule)
- .upsert(upsert);
+ .upsert(upsert));
}
}
import org.sonar.server.db.DbClient;
import org.sonar.server.qualityprofile.ProfilesManager;
import org.sonar.server.rule.RuleDefinitionsLoader;
-import org.sonar.server.rule2.index.RuleIndexDefinition;
+import org.sonar.server.search.IndexDefinition;
import org.sonar.server.search.action.EmbeddedIndexAction;
import org.sonar.server.search.action.IndexAction;
import org.sonar.server.search.action.KeyIndexAction;
dbClient.ruleDao().update(rule, session);
} else {
// TODO replace this hack by index synchronizer
- session.enqueue(new KeyIndexAction<RuleKey>(RuleIndexDefinition.INDEX_TYPE, IndexAction.Method.UPSERT, rule.getKey()));
+ session.enqueue(new KeyIndexAction<RuleKey>(IndexDefinition.RULE.getIndexType(),
+ IndexAction.Method.UPSERT, rule.getKey()));
}
mergeParams(ruleDef, rule, session);
dbClient.ruleDao().updateRuleParam(rule, paramDto, session);
} else {
// TODO to be replaced by synchronizer
- session.enqueue(new EmbeddedIndexAction<RuleKey>(RuleIndexDefinition.INDEX_TYPE, IndexAction.Method.UPSERT, paramDto, rule.getKey()));
+ session.enqueue(new EmbeddedIndexAction<RuleKey>(IndexDefinition.RULE.getIndexType(),
+ IndexAction.Method.UPSERT, paramDto, rule.getKey()));
}
existingParamDtoNames.add(paramDto.getName());
}
import org.sonar.core.cluster.WorkQueue;
import org.sonar.core.rule.RuleDto;
import org.sonar.server.es.ESNode;
-import org.sonar.server.qualityprofile.index.ActiveRuleIndexDefinition;
import org.sonar.server.qualityprofile.index.ActiveRuleNormalizer;
import org.sonar.server.rule2.Rule;
import org.sonar.server.search.BaseIndex;
+import org.sonar.server.search.IndexDefinition;
import org.sonar.server.search.QueryOptions;
import java.io.IOException;
public class RuleIndex extends BaseIndex<Rule, RuleDto, RuleKey> {
public RuleIndex(RuleNormalizer normalizer, WorkQueue workQueue, ESNode node) {
- super(new RuleIndexDefinition(), normalizer, workQueue, node);
+ super(IndexDefinition.RULE, normalizer, workQueue, node);
}
protected String getKeyValue(RuleKey key) {
if (query.getActivation() == Boolean.TRUE) {
if (query.getQProfileKey() == null) {
// the rules that are activated at least once
- fb.must(FilterBuilders.hasChildFilter(new ActiveRuleIndexDefinition().getIndexType(),
+ fb.must(FilterBuilders.hasChildFilter(IndexDefinition.ACTIVE_RULE.getIndexType(),
QueryBuilders.matchAllQuery()));
} else {
// the rules that are activated on this profile
- fb.must(FilterBuilders.hasChildFilter(new ActiveRuleIndexDefinition().getIndexType(),
+ fb.must(FilterBuilders.hasChildFilter(IndexDefinition.ACTIVE_RULE.getIndexType(),
QueryBuilders.termQuery(ActiveRuleNormalizer.ActiveRuleField.PROFILE_KEY.key(),
query.getQProfileKey())
));
} else if (query.getActivation() == Boolean.FALSE) {
if (query.getQProfileKey() == null) {
// the rules that are never activated, on any profile
- fb.mustNot(FilterBuilders.hasChildFilter(new ActiveRuleIndexDefinition().getIndexType(),
+ fb.mustNot(FilterBuilders.hasChildFilter(IndexDefinition.ACTIVE_RULE.getIndexType(),
QueryBuilders.matchAllQuery()));
} else {
// the rules that are not activated on this profile
- fb.mustNot(FilterBuilders.hasChildFilter(new ActiveRuleIndexDefinition().getIndexType(),
+ fb.mustNot(FilterBuilders.hasChildFilter(IndexDefinition.ACTIVE_RULE.getIndexType(),
QueryBuilders.termQuery(ActiveRuleNormalizer.ActiveRuleField.PROFILE_KEY.key(),
query.getQProfileKey())
));
+++ /dev/null
-/*
- * 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.rule2.index;
-
-import org.sonar.server.search.IndexDefinition;
-
-public final class RuleIndexDefinition implements IndexDefinition {
-
- public static final String INDEX_NAME = "rules2";
- public static final String INDEX_TYPE = "rule2";
-
- @Override
- public String getIndexName() {
- return RuleIndexDefinition.INDEX_NAME;
- }
-
- @Override
- public String getIndexType() {
- return RuleIndexDefinition.INDEX_TYPE;
- }
-}
import com.google.common.base.Function;
import com.google.common.collect.Collections2;
+import com.google.common.collect.ImmutableList;
import com.google.common.collect.ImmutableSet;
import com.google.common.collect.Lists;
import com.google.common.collect.Sets;
import org.sonar.core.technicaldebt.db.CharacteristicDto;
import org.sonar.server.db.DbClient;
import org.sonar.server.search.BaseNormalizer;
+import org.sonar.server.search.IndexDefinition;
import javax.annotation.Nullable;
import java.util.ArrayList;
import java.util.HashMap;
+import java.util.List;
import java.util.Map;
import java.util.Set;
}
public RuleNormalizer(DbClient db) {
- super(db);
+ super(IndexDefinition.RULE, db);
}
@Override
- public UpdateRequest normalize(RuleKey key) {
- DbSession dbSession = db().openSession(false);
+ public List<UpdateRequest> normalize(RuleKey key) {
+ DbSession dbSession = db.openSession(false);
+ List<UpdateRequest> requests = new ArrayList<UpdateRequest>();
try {
- return normalize(db().ruleDao().getByKey(key, dbSession));
+ requests.addAll(normalize(db.ruleDao().getByKey(key, dbSession)));
+ for(RuleParamDto param : db.ruleDao().findRuleParamsByRuleKey(key, dbSession)){
+ requests.addAll(normalize(param, key));
+ }
} finally {
dbSession.close();
}
+ return requests;
}
@Override
- public UpdateRequest normalize(RuleDto rule) {
+ public List<UpdateRequest> normalize(RuleDto rule) {
/** Update Fields */
Map<String, Object> update = new HashMap<String, Object>();
/** Creating updateRequest */
- return new UpdateRequest()
+ return ImmutableList.of(new UpdateRequest()
.doc(update)
- .upsert(upsert);
-
+ .upsert(upsert));
}
- public UpdateRequest normalize(RuleParamDto param, RuleKey key) {
+ public List<UpdateRequest> normalize(RuleParamDto param, RuleKey key) {
Map<String, Object> newParam = new HashMap<String, Object>();
newParam.put("_id", param.getName());
newParam.put(RuleParamField.NAME.key(), param.getName());
newParam.put(RuleParamField.DESCRIPTION.key(), param.getDescription());
newParam.put(RuleParamField.DEFAULT_VALUE.key(), param.getDefaultValue());
- return this.nestedUpsert(RuleField.PARAMS.key(),
- param.getName(), newParam).id(key.toString());
+ return ImmutableList.of(this.nestedUpsert(RuleField.PARAMS.key(),
+ param.getName(), newParam).id(key.toString()));
}
}
import org.sonar.core.rule.RuleMapper;
import org.sonar.core.rule.RuleParamDto;
import org.sonar.server.db.BaseDao;
-import org.sonar.server.rule2.index.RuleIndexDefinition;
+import org.sonar.server.search.IndexDefinition;
import org.sonar.server.search.action.IndexAction;
import org.sonar.server.search.action.KeyIndexAction;
@VisibleForTesting
public RuleDao(System2 system) {
- super(new RuleIndexDefinition(), RuleMapper.class, system);
+ super(IndexDefinition.RULE, RuleMapper.class, system);
}
@CheckForNull
package org.sonar.server.search;
import org.elasticsearch.action.admin.indices.exists.indices.IndicesExistsResponse;
+import org.elasticsearch.action.bulk.BulkRequestBuilder;
import org.elasticsearch.action.get.GetResponse;
import org.elasticsearch.action.search.SearchRequestBuilder;
import org.elasticsearch.action.search.SearchResponse;
return null;
}
- protected void updateDocument(UpdateRequest request, K key) throws Exception {
+ protected void updateDocument(Collection<UpdateRequest> requests, K key) throws Exception {
LOG.debug("UPDATE _id:{} in index {}", key, this.getIndexName());
- getClient().update(request
+ BulkRequestBuilder bulkRequest = getClient().prepareBulk();
+ for(UpdateRequest request : requests){
+ bulkRequest.add(request
.index(this.getIndexName())
.id(this.getKeyValue(key))
- .type(this.getIndexType())).get();
+ .type(this.getIndexType()));
+ }
+ bulkRequest.get();
}
@Override
public void upsertByDto(E item) {
try {
- UpdateRequest doc = normalizer.normalize(item);
- this.updateDocument(doc, item.getKey());
+ this.updateDocument(normalizer.normalize(item), item.getKey());
} catch (Exception e) {
LOG.error("Could not update document for index {}: {}",
this.getIndexName(), e.getMessage());
@Override
public void upsertByKey(K key) {
try {
- UpdateRequest doc = normalizer.normalize(key);
- this.updateDocument(doc, key);
+ this.updateDocument(normalizer.normalize(key), key);
} catch (Exception e) {
LOG.error("Could not update document for index {}: {}",
this.getIndexName(), e.getMessage());
package org.sonar.server.search;
import org.elasticsearch.action.update.UpdateRequest;
-import org.elasticsearch.common.xcontent.XContentBuilder;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.sonar.core.persistence.Dto;
import org.sonar.server.db.DbClient;
-import java.io.IOException;
import java.io.Serializable;
+import java.util.List;
import java.util.Map;
public abstract class BaseNormalizer<E extends Dto<K>, K extends Serializable> {
private static final Logger LOG = LoggerFactory.getLogger(BaseNormalizer.class);
protected final DbClient db;
+ protected final IndexDefinition definition;
- protected BaseNormalizer(DbClient db) {
+ protected BaseNormalizer(IndexDefinition definition, DbClient db) {
this.db = db;
- }
-
- protected DbClient db() {
- return db;
+ this.definition = definition;
}
public boolean canNormalize(Class<?> objectClass, Class<?> keyClass) {
}
}
- public UpdateRequest normalizeOther(Object object, Object key) {
+ public List<UpdateRequest> normalizeOther(Object object, Object key) {
try {
- return (UpdateRequest) this.getClass()
+ return (List<UpdateRequest>) this.getClass()
.getMethod("normalize", object.getClass(), key.getClass())
.invoke(this, object, key);
} catch (Exception e) {
}
}
- public abstract UpdateRequest normalize(K key);
-
- public abstract UpdateRequest normalize(E dto);
-
- protected void indexField(String field, Object value, XContentBuilder document) {
- try {
- document.field(field, value);
- } catch (IOException e) {
- LOG.error("Could not set {} to {} in ESDocument", field, value);
- }
- }
+ public abstract java.util.List<UpdateRequest> normalize(K key);
+ public abstract java.util.List<UpdateRequest> normalize(E dto);
protected UpdateRequest nestedUpsert(String field, String key, Map<String, Object> item) {
return new UpdateRequest()
*/
package org.sonar.server.search;
-public interface IndexDefinition {
+public class IndexDefinition {
- String getIndexName();
+ private final String indexName;
+ private final String indexType;
- String getIndexType();
+ private IndexDefinition(String indexName, String indexType) {
+ this.indexName = indexName;
+ this.indexType = indexType;
+ }
+
+ public String getIndexName() {
+ return indexName;
+ }
+
+ public String getIndexType() {
+ return indexType;
+ }
+
+ public static IndexDefinition RULE = new IndexDefinition("rules","rules");
+ public static IndexDefinition ACTIVE_RULE = new IndexDefinition("rules","activeRules");
}
package org.sonar.server.qualityprofile;
import org.junit.Before;
-import org.junit.Ignore;
import org.junit.Rule;
import org.junit.Test;
import org.sonar.api.rule.RuleKey;
}
}
+ @Test
+ public void synchronize_index() throws Exception {
+ QualityProfileDto profile1 = QualityProfileDto.createFor("p1", "java");
+ dbClient.qualityProfileDao().insert(dbSession, profile1);
+
+ RuleDto rule1 = RuleDto.createFor(RuleKey.of("java", "r1")).setSeverity(Severity.MAJOR);
+ dbClient.ruleDao().insert(rule1, dbSession);
+
+ ActiveRuleDto activeRule = ActiveRuleDto.createFor(profile1, rule1).setSeverity("BLOCKER");
+ dbClient.activeRuleDao().insert(activeRule, dbSession);
+ dbSession.commit();
+
+ tester.clearIndexes();
+
+ // 0. Assert that we have no rules in Is.
+ assertThat(index.getByKey(activeRule.getKey())).isNull();
+
+
+ // 1. Synchronize since 0
+ dbClient.activeRuleDao().synchronizeAfter(0,dbSession);
+
+ // 2. Assert that we have the rule in Index
+ assertThat(index.getByKey(activeRule.getKey())).isNotNull();
+
+ }
+
@Test
public void find_active_rules() throws Exception {
QualityProfileDto profile1 = QualityProfileDto.createFor("p1", "java");
import org.sonar.core.template.LoadedTemplateDto;
import org.sonar.server.db.DbClient;
import org.sonar.server.platform.Platform;
+import org.sonar.server.qualityprofile.index.ActiveRuleIndex;
import org.sonar.server.qualityprofile.persistence.ActiveRuleDao;
import org.sonar.server.tester.ServerTester;
}
}
+ @Test
+ public void register_existing_profile_definitions() throws Exception {
+ tester = new ServerTester().addComponents(XooRulesDefinition.class, XooProfileDefinition.class);
+ tester.start();
+ dbSession = dbClient().openSession(false);
+ QualityProfileKey qualityProfileKey = QualityProfileKey.of("Basic", "xoo");
+
+ // Check Profile in DB
+ QualityProfileDao qualityProfileDao = dbClient().qualityProfileDao();
+ assertThat(qualityProfileDao.findAll(dbSession)).hasSize(1);
+ assertThat(qualityProfileDao.getByKey(qualityProfileKey, dbSession)).isNotNull();
+
+ // Check ActiveRules in DB
+ ActiveRuleDao activeRuleDao = dbClient().activeRuleDao();
+ assertThat(activeRuleDao.findByProfileKey(qualityProfileKey, dbSession)).hasSize(2);
+ RuleKey ruleKey = RuleKey.of("xoo", "x1");
+
+ ActiveRuleKey activeRuleKey = ActiveRuleKey.of(qualityProfileKey, ruleKey);
+
+ // 0. Check and clear ES
+ assertThat(tester.get(ActiveRuleIndex.class).getByKey(activeRuleKey)).isNotNull();
+ tester.clearIndexes();
+ assertThat(tester.get(ActiveRuleIndex.class).getByKey(activeRuleKey)).isNull();
+ tester.get(Platform.class).restart();
+ assertThat(tester.get(ActiveRuleIndex.class).getByKey(activeRuleKey)).isNotNull();
+
+
+ // Check ActiveRules in ES
+ org.sonar.server.qualityprofile.ActiveRule activeRule = tester.get(ActiveRuleIndex.class).getByKey(activeRuleKey);
+ assertThat(activeRule.key().qProfile()).isEqualTo(qualityProfileKey);
+ assertThat(activeRule.key().ruleKey()).isEqualTo(ruleKey);
+ assertThat(activeRule.severity()).isEqualTo(Severity.CRITICAL);
+
+// // Check ActiveRuleParameters in DB
+// Map<String, ActiveRuleParamDto> params = ActiveRuleParamDto.groupByKey(activeRuleDao.findParamsByActiveRule(activeRule, dbSession));
+// assertThat(params).hasSize(2);
+// // set by profile
+// assertThat(params.get("acceptWhitespace").getValue()).isEqualTo("true");
+// // default value
+// assertThat(params.get("max").getValue()).isEqualTo("10");
+ }
+
@Test
public void register_profile_definitions() throws Exception {
tester = new ServerTester().addComponents(XooRulesDefinition.class, XooProfileDefinition.class);