package org.sonar.server.rule2;
import com.google.common.collect.ImmutableSet;
-import org.apache.commons.beanutils.BeanUtils;
import org.elasticsearch.common.xcontent.XContentBuilder;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.sonar.api.rule.RuleKey;
import org.sonar.core.cluster.WorkQueue;
import org.sonar.core.profiling.Profiling;
-import org.sonar.core.qualityprofile.db.ActiveRuleDao;
-import org.sonar.core.qualityprofile.db.ActiveRuleDto;
import org.sonar.core.rule.RuleConstants;
import org.sonar.core.rule.RuleDto;
import org.sonar.server.es.ESNode;
import org.sonar.server.search.Results;
import java.io.IOException;
-import java.lang.reflect.InvocationTargetException;
-import java.util.Map;
-import java.util.Map.Entry;
import java.util.Set;
import static org.elasticsearch.common.xcontent.XContentFactory.jsonBuilder;
public static final Set<String> PUBLIC_FIELDS = ImmutableSet.of("repositoryKey", "key", "name", "desc",
"lang", "severity", "status", "tags", "sysTags", "createdAt", "updatedAt");
- private final ActiveRuleDao activeRuleDao;
-
- public RuleIndex(WorkQueue workQueue, RuleDao dao, ActiveRuleDao ActiveRuleDao, Profiling profiling, ESNode node) {
- super(workQueue, dao, profiling, node);
- this.activeRuleDao = ActiveRuleDao;
+ public RuleIndex(RuleNormalizer normalizer, WorkQueue workQueue,
+ Profiling profiling, ESNode node) {
+ super(normalizer, workQueue, profiling, node);
}
@Override
return mapping.endObject()
.endObject().endObject();
- // return jsonBuilder().startObject()
- // .startObject("issue")
- // .startObject("properties")
- // .startObject("component.path")
- // .field("type", "string")
- // .field("index_analyzer", "path_analyzer")
- // .field("search_analyzer", "keyword")
- // .endObject()
- // .startObject("rule.name")
- // .field("type", "string")
- // .field("analyzer", "keyword")
- // .endObject()
- // .startObject("root.id")
- // .field("type", "multi_field")
- // .startObject("fields")
- // .startObject("str")
- // .field("type", "string")
- // .field("index","analyzed")
- // .field("analyzer", "default")
- // .endObject()
- // .startObject("num")
- // .field("type", "long")
- // .field("index","analyzed")
- // .endObject()
- // .endObject()
- // .endObject()
- // .endObject().endObject();
} catch (IOException e) {
LOG.error("Could not create mapping for {}", this.getIndexName());
return null;
}
}
- @Override
- public XContentBuilder normalize(RuleKey key) {
-
- try {
-
- RuleDto rule = dao.getByKey(key);
-
- XContentBuilder document = jsonBuilder().startObject();
-
- Map<String, Object> properties = BeanUtils.describe(rule);
-
- for (Entry<String, Object> property : properties.entrySet()) {
- LOG.trace("NORMALIZING: {} -> {}", property.getKey(), property.getValue());
- document.field(property.getKey(), property.getValue());
- }
-
- document.startArray("active");
- for (ActiveRuleDto activeRule : activeRuleDao.selectByRuleId(rule.getId())) {
- document.startObject();
- Map<String, Object> activeRuleProperties = BeanUtils.describe(activeRule);
- for (Entry<String, Object> activeRuleProp : activeRuleProperties.entrySet()) {
- LOG.trace("NORMALIZING: --- {} -> {}", activeRuleProp.getKey(), activeRuleProp.getValue());
- document.field(activeRuleProp.getKey(), activeRuleProp.getValue());
- }
- document.endObject();
- }
- document.endArray();
-
- return document.endObject();
- } catch (IOException e) {
- LOG.error("Could not normalize {} in {} because {}",
- key, this.getClass().getSimpleName(), e.getMessage());
- } catch (IllegalAccessException e) {
- LOG.error("Could not normalize {} in {} because {}",
- key, this.getClass().getSimpleName(), e.getMessage());
- } catch (InvocationTargetException e) {
- LOG.error("Could not normalize {} in {} because {}",
- key, this.getClass().getSimpleName(), e.getMessage());
- } catch (NoSuchMethodException e) {
- LOG.error("Could not normalize {} in {} because {}",
- key, this.getClass().getSimpleName(), e.getMessage());
- }
- return null;
- }
-
public Results search(RuleQuery query, QueryOptions options) {
+
throw new UnsupportedOperationException("TODO");
}
-
}
--- /dev/null
+package org.sonar.server.rule2;
+
+import org.elasticsearch.common.xcontent.XContentBuilder;
+import org.sonar.api.rule.RuleKey;
+import org.sonar.core.qualityprofile.db.ActiveRuleDao;
+import org.sonar.core.rule.RuleDto;
+import org.sonar.server.search.BaseNormalizer;
+
+import java.io.IOException;
+import java.lang.reflect.InvocationTargetException;
+import java.lang.reflect.Method;
+
+import static org.elasticsearch.common.xcontent.XContentFactory.jsonBuilder;
+
+public class RuleNormalizer extends BaseNormalizer<RuleDto, RuleKey> {
+
+ private RuleDao ruleDao;
+ private ActiveRuleDao activeRuleDao;
+
+ public enum RuleFields {
+ KEY("key"),
+ RULE_KEY("ruleKey"),
+ REPOSITORY_KEY("repositoryKey"),
+ NAME("name"),
+ CREATED_AT("createdAt");
+
+ private final String key;
+
+ private RuleFields(final String key) {
+ this.key = key;
+ }
+
+ public String key() {
+ return key;
+ }
+
+ public String toString() {
+ return key;
+ }
+ }
+
+ public RuleNormalizer(RuleDao ruleDao, ActiveRuleDao activeRuleDao) {
+ this.ruleDao = ruleDao;
+ this.activeRuleDao = activeRuleDao;
+ }
+
+ @Override
+ public XContentBuilder normalize(RuleKey key) throws IOException {
+ return normalize(ruleDao.getByKey(key));
+ }
+
+ @Override
+ public XContentBuilder normalize(RuleDto rule) throws IOException {
+
+ XContentBuilder document = jsonBuilder().startObject();
+
+ indexField(RuleFields.KEY.key(), rule.getKey(), document);
+ indexField(RuleFields.NAME.key(), rule.getName(), document);
+ indexField(RuleFields.CREATED_AT.key(), rule.getCreatedAt(), document);
+ indexField(RuleFields.RULE_KEY.key(), rule.getRuleKey(), document);
+ indexField(RuleFields.REPOSITORY_KEY.key(), rule.getRepositoryKey(), document);
+
+ // document.startArray("active");
+ // for (ActiveRuleDto activeRule : activeRuleDao.selectByRuleId(rule.getId())) {
+ // document.startObject();
+ // Map<String, Object> activeRuleProperties = BeanUtils.describe(activeRule);
+ // for (Entry<String, Object> activeRuleProp : activeRuleProperties.entrySet()) {
+ // LOG.trace("NORMALIZING: --- {} -> {}", activeRuleProp.getKey(), activeRuleProp.getValue());
+ // document.field(activeRuleProp.getKey(), activeRuleProp.getValue());
+ // }
+ // document.endObject();
+ // }
+ // document.endArray();
+
+ return document.endObject();
+ }
+
+}
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.sonar.core.cluster.WorkQueue;
-import org.sonar.core.db.Dao;
import org.sonar.core.db.Dto;
import org.sonar.core.profiling.Profiling;
import org.sonar.core.profiling.Profiling.Level;
private final Profiling profiling;
private Client client;
private final ESNode node;
- private IndexSynchronizer<K> synchronizer;
- protected Dao<E, K> dao;
+ protected BaseNormalizer<E,K> normalizer;
- public BaseIndex(WorkQueue workQueue, Dao<E, K> dao, Profiling profiling, ESNode node) {
+ public BaseIndex(BaseNormalizer<E,K> normalizer, WorkQueue workQueue,
+ Profiling profiling, ESNode node) {
+ this.normalizer = normalizer;
this.profiling = profiling;
- this.synchronizer = new IndexSynchronizer<K>(this, dao, workQueue);
- this.dao = dao;
this.node = node;
}
- protected Dao<?, K> getDao() {
- return this.dao;
- }
-
protected Client getClient() {
return this.client;
}
/* Setup the index if necessary */
this.intializeIndex();
-
- /* Launch synchronization */
-// synchronizer.start();
}
@Override
public void connect() {
this.client = this.node.client();
- // /* Settings to access our local ES node */
- // Settings settings = ImmutableSettings.settingsBuilder()
- // .put("client.transport.sniff", true)
- // .put("cluster.name", ES_CLUSTER_NAME)
- // .put("node.name", "localclient_")
- // .build();
- //
- // this.client = new TransportClient(settings)
- // .addTransportAddress(new InetSocketTransportAddress(LOCAL_ES_NODE_HOST, LOCAL_ES_NODE_PORT));
- //
- // /*
- // * Cannot do that yet, need version >= 1.0
- // * ImmutableList<DiscoveryNode> nodes = client.connectedNodes();
- // * if (nodes.isEmpty()) {
- // * throw new ElasticSearchUnavailableException("No nodes available. Verify ES is running!");
- // * } else {
- // * log.info("connected to nodes: " + nodes.toString());
- // * }
- // */
}
/* Cluster And ES Stats/Client methods */
@Override
public void insert(K key) {
try {
- XContentBuilder doc = this.normalize(key);
+ XContentBuilder doc = normalizer.normalize(key);
String keyvalue = this.getKeyValue(key);
if (doc != null && keyvalue != null && !keyvalue.isEmpty()) {
LOG.debug("Update document with key {}", key);
IndexResponse result = getClient().index(
new IndexRequest(this.getIndexName(),
this.getType(), keyvalue)
- .source(this.normalize(key))).get();
+ .source(doc)).get();
} else {
LOG.error("Could not normalize document {} for insert in ",
key, this.getIndexName());
public void update(K key) {
try {
LOG.info("Update document with key {}", key);
+ XContentBuilder doc = normalizer.normalize(key);
UpdateResponse result = getClient().update(
new UpdateRequest(this.getIndexName(),
this.getType(), this.getKeyValue(key))
- .doc(this.normalize(key))).get();
+ .doc(doc)).get();
} catch (Exception e) {
LOG.error("Could not update documet for index {}: {}",
this.getIndexName(), e.getMessage());
--- /dev/null
+package org.sonar.server.search;
+
+import org.elasticsearch.common.xcontent.XContentBuilder;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.sonar.core.db.Dto;
+
+import java.io.IOException;
+import java.io.Serializable;
+
+public abstract class BaseNormalizer<E extends Dto<K>, K extends Serializable> {
+
+ public abstract XContentBuilder normalize(K key) throws IOException;
+
+ public abstract XContentBuilder normalize(E dto) throws IOException;
+
+ private static final Logger LOG = LoggerFactory.getLogger(BaseNormalizer.class);
+
+ 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);
+ }
+ }
+
+// protected void indexField(Fields field, Object dto, XContentBuilder document) {
+// try {
+// document.field(field.key(), field.method.invoke(dto));
+// } catch (IllegalArgumentException e) {
+// // TODO Auto-generated catch block
+// e.printStackTrace();
+// } catch (IOException e) {
+// // TODO Auto-generated catch block
+// e.printStackTrace();
+// } catch (IllegalAccessException e) {
+// // TODO Auto-generated catch block
+// e.printStackTrace();
+// } catch (InvocationTargetException e) {
+// // TODO Auto-generated catch block
+// e.printStackTrace();
+// }
+// }
+//
+//
+//
+//private static Method getReadMethod(String method){
+// try {
+// return RuleDto.class.getDeclaredMethod(method);
+// } catch (SecurityException e) {
+// // TODO Auto-generated catch block
+// e.printStackTrace();
+// } catch (NoSuchMethodException e) {
+// // TODO Auto-generated catch block
+// e.printStackTrace();
+// }
+// return null;
+//}
+
+
+
+
+}
*/
package org.sonar.server.search;
-import org.elasticsearch.common.xcontent.XContentBuilder;
import org.picocontainer.Startable;
import javax.annotation.CheckForNull;
+
import java.io.Serializable;
public interface Index<K extends Serializable> extends Startable {
void delete(K key);
- XContentBuilder normalize(K key);
-
Long getLastSynchronization();
void setLastSynchronization(Long time);
import com.google.common.collect.ImmutableList;
import org.sonar.server.cluster.LocalQueueWorker;
import org.sonar.server.rule2.RuleIndex;
+import org.sonar.server.rule2.RuleNormalizer;
import java.util.List;
@SuppressWarnings("unchecked")
public static List<Class> getIndexClasses() {
return ImmutableList.<Class>of(
+ RuleNormalizer.class,
RuleIndex.class,
LocalQueueWorker.class
);
dao.insert(dto);
Hit hit = index.getByKey(dto.getKey());
- assertThat(hit.getFields().get("ruleKey")).isEqualTo(dto.getRuleKey());
+ assertThat(hit.getFields().get(RuleNormalizer.RuleFields.RULE_KEY.key())).isEqualTo(dto.getRuleKey().toString());
}
@Test