--- /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.core.cluster;
+
+import java.util.concurrent.CountDownLatch;
+
+public abstract class ClusterAction implements Runnable {
+
+ private CountDownLatch latch;
+
+ public ClusterAction(CountDownLatch latch){
+ this.latch = latch;
+ }
+
+ public ClusterAction() {
+ this.latch = null;
+ }
+
+ public void setLatch(CountDownLatch latch){
+ this.latch = latch;
+ }
+
+ public abstract void doExecute();
+
+ @Override
+ public void run(){
+ this.doExecute();
+ if(latch != null){
+ latch.countDown();
+ }
+ }
+}
+++ /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.core.cluster;
-
-import java.io.Serializable;
-
-public class IndexAction<K extends Serializable> {
-
- public enum Method {
- INSERT, UPDATE, DELETE
- }
-
- String indexName;
- K key;
- Method method;
-
- public IndexAction(String indexName, Method method, K key){
- this.indexName = indexName;
- this.method = method;
- this.key = key;
- }
-
- public String getIndexName() {
- return indexName;
- }
-
- public void setIndexName(String indexName) {
- this.indexName = indexName;
- }
-
- public K getKey() {
- return key;
- }
-
- public void setKey(K key) {
- this.key = key;
- }
-
- public Method getMethod() {
- return method;
- }
-
- public void setMethod(Method method) {
- this.method = method;
- }
-}
*/
package org.sonar.core.cluster;
-import javax.annotation.CheckForNull;
+
public class NullQueue implements WorkQueue {
@Override
- public void enqueue(IndexAction<?> action) {
+ public void enqueue(ClusterAction action) {
}
@Override
- public void enqueue(Iterable<IndexAction<?>> actions) {
-
- }
+ public void enqueue(Iterable<ClusterAction> actions) {
- @CheckForNull
- @Override
- public IndexAction<?> dequeue() {
- return null;
}
}
*/
package org.sonar.core.cluster;
-import javax.annotation.CheckForNull;
+import org.sonar.core.db.Dto;
+
+import java.io.Serializable;
+
+
public interface WorkQueue {
- void enqueue(IndexAction<?> action);
+ void enqueue(ClusterAction action);
- void enqueue(Iterable<IndexAction<?>> actions);
+ void enqueue(Iterable<ClusterAction> actions);
- @CheckForNull
- IndexAction<?> dequeue();
+ /* This is because of core vs server packages... */
+// void enqueue(ClusterAction.Type type, ClusterAction.Method method, String ref, Serializable key);
+// void enqueue(ClusterAction.Type type, ClusterAction.Method method, String ref, Dto dto);
}
+++ /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.core.db;
-
-import org.apache.ibatis.session.SqlSession;
-import org.sonar.core.cluster.IndexAction;
-import org.sonar.core.persistence.DbSession;
-import org.sonar.core.persistence.MyBatis;
-
-import java.io.Serializable;
-
-public abstract class BaseDao<E extends Dto<K>, K extends Serializable>
- implements Dao<E, K> {
-
- protected MyBatis mybatis;
-
- protected BaseDao(MyBatis myBatis) {
- this.mybatis = myBatis;
- }
-
- protected abstract String getIndexName();
-
- protected abstract E doGetByKey(K key, SqlSession session);
-
- protected abstract E doInsert(E item, SqlSession session);
-
- protected abstract E doUpdate(E item, SqlSession session);
-
- protected abstract void doDelete(E item, SqlSession session);
-
- protected abstract void doDeleteByKey(K key, SqlSession session);
-
- protected MyBatis getMyBatis() {
- return this.mybatis;
- }
-
- @Override
- public E getByKey(K key) {
- DbSession session = getMyBatis().openSession(false);
- E item = this.doGetByKey(key, session);
- MyBatis.closeQuietly(session);
- return item;
- }
-
- @Override
- public E update(E item, DbSession session) {
- session.enqueue(new IndexAction(this.getIndexName(),
- IndexAction.Method.UPDATE, item.getKey()));
- return this.doUpdate(item, session);
- }
-
- @Override
- public E update(E item) {
- DbSession session = getMyBatis().openSession(false);
- try {
- this.update(item, session);
- session.commit();
- return item;
- } finally {
- MyBatis.closeQuietly(session);
- }
- }
-
- @Override
- public E insert(E item, DbSession session) {
- session.enqueue(new IndexAction(this.getIndexName(),
- IndexAction.Method.INSERT, item.getKey()));
- return this.doInsert(item, session);
- }
-
- @Override
- public E insert(E item) {
- DbSession session = getMyBatis().openSession(false);
- try {
- this.insert(item, session);
- session.commit();
- return item;
- } finally {
- MyBatis.closeQuietly(session);
- }
- }
-
- @Override
- public void delete(E item, DbSession session) {
- session.enqueue(new IndexAction(this.getIndexName(),
- IndexAction.Method.DELETE, item.getKey()));
- this.doDelete(item, session);
- }
-
- @Override
- public void delete(E item) {
- DbSession session = getMyBatis().openSession(false);
- try {
- this.delete(item, session);
- session.commit();
- } finally {
- MyBatis.closeQuietly(session);
- }
- }
-
- @Override
- public void deleteByKey(K key, DbSession session) {
- session.enqueue(new IndexAction(this.getIndexName(),
- IndexAction.Method.DELETE, key));
- this.doDeleteByKey(key, session);
- }
-
- @Override
- public void deleteByKey(K key) {
- DbSession session = getMyBatis().openSession(false);
- try {
- this.doDeleteByKey(key, session);
- session.commit();
- } finally {
- MyBatis.closeQuietly(session);
- }
- }
-}
*/
package org.sonar.core.persistence;
-import org.apache.ibatis.session.SqlSession;
-
import org.apache.ibatis.executor.BatchResult;
import org.apache.ibatis.session.Configuration;
import org.apache.ibatis.session.ResultHandler;
import org.apache.ibatis.session.RowBounds;
-import org.sonar.core.cluster.IndexAction;
+import org.apache.ibatis.session.SqlSession;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.sonar.core.cluster.ClusterAction;
import org.sonar.core.cluster.WorkQueue;
import java.sql.Connection;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
+import java.util.concurrent.CountDownLatch;
public class DbSession implements SqlSession {
- private List<IndexAction<?>> actions;
+ private static final Logger LOG = LoggerFactory.getLogger(DbSession.class);
+
+ private List<ClusterAction> actions;
private WorkQueue queue;
private SqlSession session;
DbSession(WorkQueue queue, SqlSession session) {
this.session = session;
this.queue = queue;
- this.actions = new ArrayList<IndexAction<?>>();
+ this.actions = new ArrayList<ClusterAction>();
}
- public void enqueue(IndexAction action) {
+ public void enqueue(ClusterAction action) {
this.actions.add(action);
}
+ private void enqueueActions(){
+ CountDownLatch latch = new CountDownLatch(actions.size());
+ for(ClusterAction action:actions){
+ action.setLatch(latch);
+ queue.enqueue(action);
+ }
+ try {
+ latch.await();
+ } catch (InterruptedException e) {
+ LOG.error("ES update has been interrupted: {}",e.getMessage());
+ }
+ }
+
@Override
public void commit() {
session.commit();
- queue.enqueue(actions);
+ enqueueActions();
}
@Override
public void commit(boolean force) {
session.commit(force);
- queue.enqueue(actions);
+ enqueueActions();
}
/**
package org.sonar.core.rule;
import com.google.common.collect.Lists;
-import org.apache.ibatis.session.ResultContext;
-import org.apache.ibatis.session.ResultHandler;
import org.apache.ibatis.session.SqlSession;
import org.sonar.api.BatchComponent;
import org.sonar.api.ServerComponent;
import org.sonar.api.rule.RuleKey;
-import org.sonar.core.db.BaseDao;
-import org.sonar.core.db.UnsuportedException;
-import org.sonar.core.persistence.DbSession;
import org.sonar.core.persistence.MyBatis;
import javax.annotation.CheckForNull;
-import java.sql.Timestamp;
import java.util.Collection;
import java.util.List;
-import java.util.Map;
import static com.google.common.collect.Lists.newArrayList;
-public class RuleDao extends BaseDao<RuleDto, RuleKey>
- implements BatchComponent, ServerComponent {
+public class RuleDao implements BatchComponent, ServerComponent {
- public RuleDao(MyBatis mybatis) {
- super(mybatis);
- }
-
- @Override
- protected String getIndexName() {
- return RuleConstants.INDEX_NAME;
- }
-
- @Override
- @CheckForNull
- protected RuleDto doGetByKey(RuleKey key, SqlSession session) {
- return getMapper(session).selectByKey(key);
- }
-
- @Override
- protected RuleDto doInsert(RuleDto item, SqlSession session) {
- session.getMapper(RuleMapper.class).insert(item);
- return item;
- }
-
- @Override
- protected RuleDto doUpdate(RuleDto item, SqlSession session) {
- session.getMapper(RuleMapper.class).update(item);
- return item;
- }
-
- @Override
- protected void doDelete(RuleDto item, SqlSession session) {
- throw new UnsuportedException("Rules cannot be deleted");
- }
+ private MyBatis mybatis;
- @Override
- protected void doDeleteByKey(RuleKey key, SqlSession session) {
- throw new UnsuportedException("Rules cannot be deleted");
+ public RuleDao(MyBatis mybatis) {
+ this.mybatis = mybatis;
}
public List<RuleDto> selectAll() {
- SqlSession session = mybatis.openSession(false);
+ SqlSession session = mybatis.openSession();
try {
return selectAll(session);
} finally {
}
public List<RuleDto> selectEnablesAndNonManual() {
- SqlSession session = mybatis.openSession(false);
+ SqlSession session = mybatis.openSession();
try {
return selectEnablesAndNonManual(session);
} finally {
}
public List<RuleDto> selectBySubCharacteristicId(Integer characteristicOrSubCharacteristicId) {
- SqlSession session = mybatis.openSession(false);
+ SqlSession session = mybatis.openSession();
try {
return selectBySubCharacteristicId(characteristicOrSubCharacteristicId, session);
} finally {
@CheckForNull
public RuleDto selectById(Integer id) {
- SqlSession session = mybatis.openSession(false);
+ SqlSession session = mybatis.openSession();
try {
return selectById(id, session);
} finally {
return getMapper(session).selectByKey(ruleKey);
}
-
@CheckForNull
public RuleDto selectByKey(RuleKey ruleKey) {
- SqlSession session = mybatis.openSession(false);
+ SqlSession session = mybatis.openSession();
try {
return selectByKey(ruleKey, session);
} finally {
@CheckForNull
public RuleDto selectByName(String name) {
- SqlSession session = mybatis.openSession(false);
+ SqlSession session = mybatis.openSession();
try {
return getMapper(session).selectByName(name);
} finally {
}
}
+ public void update(RuleDto rule, SqlSession session) {
+ getMapper(session).update(rule);
+ }
+
+ public void update(RuleDto rule) {
+ SqlSession session = mybatis.openSession();
+ try {
+ update(rule, session);
+ session.commit();
+ } finally {
+ MyBatis.closeQuietly(session);
+ }
+ }
+
+ public void insert(RuleDto ruleToInsert, SqlSession session) {
+ getMapper(session).insert(ruleToInsert);
+ }
+
+ public void insert(RuleDto ruleToInsert) {
+ SqlSession session = mybatis.openSession();
+ try {
+ insert(ruleToInsert, session);
+ session.commit();
+ } finally {
+ MyBatis.closeQuietly(session);
+ }
+ }
+
public void insert(Collection<RuleDto> rules) {
- DbSession session = mybatis.openSession(true);
+ SqlSession session = mybatis.openBatchSession();
try {
for (RuleDto rule : rules) {
getMapper(session).batchInsert(rule);
}
}
- // ******************************
+ //******************************
// Methods for Rule Parameters
- // ******************************
+ //******************************
public List<RuleParamDto> selectParameters() {
- SqlSession session = mybatis.openSession(false);
+ SqlSession session = mybatis.openSession();
try {
return selectParameters(session);
} finally {
}
public List<RuleParamDto> selectParametersByRuleId(Integer ruleId) {
- SqlSession session = mybatis.openSession(false);
+ SqlSession session = mybatis.openSession();
try {
return selectParametersByRuleId(ruleId, session);
} finally {
}
public List<RuleParamDto> selectParametersByRuleIds(List<Integer> ruleIds) {
- SqlSession session = mybatis.openSession(false);
+ SqlSession session = mybatis.openSession();
try {
return selectParametersByRuleIds(ruleIds, session);
} finally {
}
public void insert(RuleParamDto param) {
- SqlSession session = mybatis.openSession(false);
+ SqlSession session = mybatis.openSession();
try {
insert(param, session);
session.commit();
}
public void update(RuleParamDto param) {
- SqlSession session = mybatis.openSession(false);
+ SqlSession session = mybatis.openSession();
try {
update(param, session);
session.commit();
return session.getMapper(RuleMapper.class);
}
- // ***************************
+ //***************************
// Methods for Rule Tags
- // ***************************
+ //***************************
+
public void insert(RuleRuleTagDto newTag, SqlSession session) {
getMapper(session).insertTag(newTag);
}
public List<RuleRuleTagDto> selectTagsByRuleId(Integer ruleId) {
- SqlSession session = mybatis.openSession(false);
+ SqlSession session = mybatis.openSession();
try {
return selectTagsByRuleIds(ruleId, session);
} finally {
}
public List<RuleRuleTagDto> selectTagsByRuleIds(List<Integer> ruleIds) {
- SqlSession session = mybatis.openSession(false);
+ SqlSession session = mybatis.openSession();
try {
return selectTagsByRuleIds(ruleIds, session);
} finally {
}
return dtos;
}
-
- @Override
- public Collection<RuleKey> keysOfRowsUpdatedAfter(long timestamp) {
- SqlSession session = mybatis.openSession(false);
- try {
- final List<RuleKey> keys = Lists.newArrayList();
- session.select("selectKeysOfRulesUpdatedSince", new Timestamp(timestamp), new ResultHandler() {
- @Override
- public void handleResult(ResultContext context) {
- Map<String, String> map = (Map) context.getResultObject();
- keys.add(RuleKey.of(map.get("repo"), map.get("rule")));
- }
- });
- return keys;
- } finally {
- MyBatis.closeQuietly(session);
- }
- }
}
import org.sonar.check.Cardinality;
import org.sonar.core.persistence.AbstractDaoTestCase;
-import java.util.Arrays;
import java.util.List;
import static com.google.common.collect.Lists.newArrayList;
assertThat(dao.selectTagsByRuleIds(newArrayList(3, 4))).hasSize(3);
}
- @Test
- public void keysOfRowsUpdatedAfter() throws Exception {
- setupData("empty");
-
- RuleDto rule1 = new RuleDto()
- .setId(1)
- .setRepositoryKey("foo")
- .setRuleKey("R1")
- .setName("ROne")
- .setCreatedAt(DateUtils.parseDate("2013-12-16"))
- .setUpdatedAt(DateUtils.parseDate("2013-12-16"));
- RuleDto rule2 = new RuleDto()
- .setId(2)
- .setRepositoryKey("foo")
- .setRuleKey("R2")
- .setName("RTwo")
- .setCreatedAt(DateUtils.parseDate("2014-01-28"))
- .setUpdatedAt(DateUtils.parseDate("2014-05-19"));
- dao.insert(Arrays.asList(rule1, rule2));
-
- assertThat(dao.keysOfRowsUpdatedAfter(DateUtils.parseDate("2014-06-01").getTime())).isEmpty();
- assertThat(dao.keysOfRowsUpdatedAfter(DateUtils.parseDate("2012-01-01").getTime())).hasSize(2);
- Iterable<RuleKey> keys = dao.keysOfRowsUpdatedAfter(DateUtils.parseDate("2014-05-17").getTime());
- assertThat(keys).hasSize(1);
- assertThat(Iterables.getFirst(keys, null).rule()).isEqualTo("R2");
- }
-
private List<Integer> idsFromRuleDtos(List<RuleDto> ruleDtos){
return newArrayList(Iterables.transform(ruleDtos, new Function<RuleDto, Integer>() {
@Override
*/
package org.sonar.server.cluster;
-import org.sonar.core.cluster.IndexAction;
+import org.sonar.api.ServerComponent;
+import org.sonar.core.cluster.ClusterAction;
import org.sonar.core.cluster.WorkQueue;
-import javax.annotation.CheckForNull;
-import java.util.concurrent.ConcurrentLinkedQueue;
+import java.util.concurrent.LinkedBlockingQueue;
+import java.util.concurrent.TimeUnit;
-public class LocalNonBlockingWorkQueue implements WorkQueue {
+public class LocalNonBlockingWorkQueue extends LinkedBlockingQueue<Runnable>
+ implements ServerComponent, WorkQueue{
- private final ConcurrentLinkedQueue<IndexAction<?>> actions = new ConcurrentLinkedQueue<IndexAction<?>>();
-
- @Override
- public void enqueue(IndexAction<?> indexAction) {
- actions.offer(indexAction);
+ public LocalNonBlockingWorkQueue(){
+ super();
}
@Override
- public void enqueue(Iterable<IndexAction<?>> indexActions) {
- for (IndexAction<?> action : indexActions) {
- enqueue(action);
+ public void enqueue(ClusterAction action) {
+ try {
+ this.offer(action, 1000,TimeUnit.SECONDS);
+ } catch (InterruptedException e) {
+ //TODO throw a runtime error here.
}
}
- @CheckForNull
@Override
- public IndexAction<?> dequeue() {
- IndexAction<?> out = actions.poll();
- return out;
+ public void enqueue(Iterable<ClusterAction> actions) {
+ for (ClusterAction action : actions) {
+ enqueue(action);
+ }
}
}
*/
package org.sonar.server.cluster;
-import org.jfree.util.Log;
import org.picocontainer.Startable;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.sonar.api.ServerComponent;
-import org.sonar.core.cluster.IndexAction;
-import org.sonar.core.cluster.WorkQueue;
import org.sonar.server.search.Index;
+import org.sonar.server.search.IndexAction;
import java.util.HashMap;
import java.util.Map;
+import java.util.concurrent.ThreadPoolExecutor;
+import java.util.concurrent.TimeUnit;
-public class LocalQueueWorker implements ServerComponent, Startable {
+public class LocalQueueWorker extends ThreadPoolExecutor
+ implements ServerComponent, Startable {
- private static final Logger LOG = LoggerFactory.getLogger(LocalNonBlockingWorkQueue.class);
+ private static final Logger LOG = LoggerFactory.getLogger(LocalQueueWorker.class);
- private WorkQueue queue;
-
- private volatile Thread worker;
private Map<String, Index<?>> indexes;
- class Worker implements Runnable {
-
- @Override
- @SuppressWarnings("unchecked")
- public void run() {
- LOG.info("Starting Worker Thread");
- Thread thisThread = Thread.currentThread();
- while (worker == thisThread) {
- try {
- Thread.sleep(20);
- } catch (InterruptedException e) {
- Log.error("Oops");
- }
+ public LocalQueueWorker(LocalNonBlockingWorkQueue queue, Index<?>... allIndexes) {
+ super(10, 10, 500l, TimeUnit.MILLISECONDS, queue);
- @SuppressWarnings("rawtypes")
- IndexAction action = queue.dequeue();
-
- if (action != null && indexes.containsKey(action.getIndexName())) {
- LOG.info("Dequeued action {}",action);
- indexes.get(action.getIndexName()).executeAction(action);
- }
- }
- LOG.info("Stoping Worker Thread");
+ // Save all instances of Index<?>
+ this.indexes = new HashMap<String, Index<?>>();
+ for (Index<?> index : allIndexes) {
+ this.indexes.put(index.getIndexName(), index);
}
}
- public LocalQueueWorker(WorkQueue queue, Index<?>... indexes) {
- this.queue = queue;
- this.worker = new Thread(new Worker());
- this.indexes = new HashMap<String, Index<?>>();
- for(Index<?> index:indexes){
- this.indexes.put(index.getIndexName(), index);
+ protected void beforeExecute(Thread t, Runnable r) {
+ LOG.debug("Starting task: {}",r);
+ super.beforeExecute(t, r);
+ if(r.getClass().isAssignableFrom(IndexAction.class)){
+ IndexAction<?> ia = (IndexAction<?>)r;
+ LOG.trace("Task is an IndexAction for {}",ia.getIndexName());
+ ia.setIndex(indexes.get(ia.getIndexName()));
}
}
+ protected void afterExecute(Runnable r, Throwable t) {
+ super.afterExecute(r, t);
+ }
@Override
public void start() {
- this.worker.start();
+ this.prestartCoreThread();
}
@Override
public void stop() {
- this.worker = null;
+ this.shutdown();
}
}
--- /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.db;
+
+import org.apache.ibatis.session.SqlSession;
+import org.sonar.core.db.Dao;
+import org.sonar.core.db.Dto;
+import org.sonar.core.persistence.DbSession;
+import org.sonar.core.persistence.MyBatis;
+import org.sonar.server.search.IndexAction;
+
+import java.io.Serializable;
+
+public abstract class BaseDao<E extends Dto<K>, K extends Serializable>
+ implements Dao<E, K> {
+
+ protected MyBatis mybatis;
+
+ protected BaseDao(MyBatis myBatis) {
+ this.mybatis = myBatis;
+ }
+
+ protected abstract String getIndexName();
+
+ protected abstract E doGetByKey(K key, SqlSession session);
+
+ protected abstract E doInsert(E item, SqlSession session);
+
+ protected abstract E doUpdate(E item, SqlSession session);
+
+ protected abstract void doDelete(E item, SqlSession session);
+
+ protected abstract void doDeleteByKey(K key, SqlSession session);
+
+ protected MyBatis getMyBatis() {
+ return this.mybatis;
+ }
+
+ @Override
+ public E getByKey(K key) {
+ DbSession session = getMyBatis().openSession(false);
+ E item = this.doGetByKey(key, session);
+ MyBatis.closeQuietly(session);
+ return item;
+ }
+
+ @Override
+ public E update(E item, DbSession session) {
+ session.enqueue(new IndexAction(this.getIndexName(),
+ IndexAction.Method.UPDATE, item.getKey()));
+ return this.doUpdate(item, session);
+ }
+
+ @Override
+ public E update(E item) {
+ DbSession session = getMyBatis().openSession(false);
+ try {
+ this.update(item, session);
+ session.commit();
+ return item;
+ } finally {
+ MyBatis.closeQuietly(session);
+ }
+ }
+
+ @Override
+ public E insert(E item, DbSession session) {
+ IndexAction action = new IndexAction(this.getIndexName(),
+ IndexAction.Method.INSERT, item.getKey());
+ session.enqueue(action);
+ this.doInsert(item, session);
+ return item;
+ }
+
+ @Override
+ public E insert(E item) {
+ DbSession session = getMyBatis().openSession(false);
+ try {
+ this.insert(item, session);
+ session.commit();
+ return item;
+ } finally {
+ MyBatis.closeQuietly(session);
+ }
+ }
+
+ @Override
+ public void delete(E item, DbSession session) {
+ session.enqueue(new IndexAction(this.getIndexName(),
+ IndexAction.Method.DELETE, item.getKey()));
+ this.doDelete(item, session);
+ }
+
+ @Override
+ public void delete(E item) {
+ DbSession session = getMyBatis().openSession(false);
+ try {
+ this.delete(item, session);
+ session.commit();
+ } finally {
+ MyBatis.closeQuietly(session);
+ }
+ }
+
+ @Override
+ public void deleteByKey(K key, DbSession session) {
+ session.enqueue(new IndexAction(this.getIndexName(),
+ IndexAction.Method.DELETE, key));
+ this.doDeleteByKey(key, session);
+ }
+
+ @Override
+ public void deleteByKey(K key) {
+ DbSession session = getMyBatis().openSession(false);
+ try {
+ this.doDeleteByKey(key, session);
+ session.commit();
+ } finally {
+ MyBatis.closeQuietly(session);
+ }
+ }
+}
*/
package org.sonar.server.platform;
+import org.sonar.server.cluster.LocalNonBlockingWorkQueue;
+
+import org.sonar.server.rule2.RuleDao;
+import org.sonar.server.rule2.RuleService;
import com.google.common.collect.Lists;
import org.apache.commons.configuration.BaseConfiguration;
import org.sonar.api.config.EmailSettings;
import org.sonar.jpa.session.ThreadLocalDatabaseSessionFactory;
import org.sonar.server.authentication.ws.AuthenticationWs;
import org.sonar.server.charts.ChartFactory;
-import org.sonar.server.cluster.LocalNonBlockingWorkQueue;
import org.sonar.server.component.DefaultComponentFinder;
import org.sonar.server.component.DefaultRubyComponentService;
import org.sonar.server.db.EmbeddedDatabaseFactory;
SemaphoresImpl.class,
TempFolderCleaner.class,
new TempFolderProvider(),
- System2.INSTANCE
+ System2.INSTANCE,
+
+ /* new RuleDao working with ES */
+ RuleDao.class
));
components.addAll(CorePropertyDefinitions.all());
components.addAll(DatabaseMigrations.CLASSES);
pico.addSingleton(AddTagsWsHandler.class);
pico.addSingleton(RemoveTagsWsHandler.class);
pico.addSingleton(RulesDefinitionXmlLoader.class);
+ pico.addSingleton(RuleService.class);
// rule tags
pico.addSingleton(ESRuleTags.class);
--- /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;
+
+import com.google.common.collect.Lists;
+import org.apache.ibatis.session.ResultContext;
+import org.apache.ibatis.session.ResultHandler;
+import org.apache.ibatis.session.SqlSession;
+import org.sonar.api.BatchComponent;
+import org.sonar.api.ServerComponent;
+import org.sonar.api.rule.RuleKey;
+import org.sonar.core.db.UnsuportedException;
+import org.sonar.core.persistence.DbSession;
+import org.sonar.core.persistence.MyBatis;
+import org.sonar.core.rule.RuleConstants;
+import org.sonar.core.rule.RuleDto;
+import org.sonar.core.rule.RuleMapper;
+import org.sonar.core.rule.RuleParamDto;
+import org.sonar.core.rule.RuleRuleTagDto;
+import org.sonar.server.db.BaseDao;
+
+import javax.annotation.CheckForNull;
+
+import java.sql.Timestamp;
+import java.util.Collection;
+import java.util.List;
+import java.util.Map;
+
+import static com.google.common.collect.Lists.newArrayList;
+
+public class RuleDao extends BaseDao<RuleDto, RuleKey>
+ implements BatchComponent, ServerComponent {
+
+ public RuleDao(MyBatis mybatis) {
+ super(mybatis);
+ }
+
+ @Override
+ protected String getIndexName() {
+ return RuleConstants.INDEX_NAME;
+ }
+
+ @Override
+ @CheckForNull
+ protected RuleDto doGetByKey(RuleKey key, SqlSession session) {
+ return getMapper(session).selectByKey(key);
+ }
+
+ @Override
+ protected RuleDto doInsert(RuleDto item, SqlSession session) {
+ session.getMapper(RuleMapper.class).insert(item);
+ return item;
+ }
+
+ @Override
+ protected RuleDto doUpdate(RuleDto item, SqlSession session) {
+ session.getMapper(RuleMapper.class).update(item);
+ return item;
+ }
+
+ @Override
+ protected void doDelete(RuleDto item, SqlSession session) {
+ throw new UnsuportedException("Rules cannot be deleted");
+ }
+
+ @Override
+ protected void doDeleteByKey(RuleKey key, SqlSession session) {
+ throw new UnsuportedException("Rules cannot be deleted");
+ }
+
+ public List<RuleDto> selectAll() {
+ SqlSession session = mybatis.openSession(false);
+ try {
+ return selectAll(session);
+ } finally {
+ MyBatis.closeQuietly(session);
+ }
+ }
+
+ public List<RuleDto> selectAll(SqlSession session) {
+ return getMapper(session).selectAll();
+ }
+
+ public List<RuleDto> selectEnablesAndNonManual() {
+ SqlSession session = mybatis.openSession(false);
+ try {
+ return selectEnablesAndNonManual(session);
+ } finally {
+ MyBatis.closeQuietly(session);
+ }
+ }
+
+ public List<RuleDto> selectEnablesAndNonManual(SqlSession session) {
+ return getMapper(session).selectEnablesAndNonManual();
+ }
+
+ public List<RuleDto> selectNonManual(SqlSession session) {
+ return getMapper(session).selectNonManual();
+ }
+
+ public List<RuleDto> selectBySubCharacteristicId(Integer characteristicOrSubCharacteristicId) {
+ SqlSession session = mybatis.openSession(false);
+ try {
+ return selectBySubCharacteristicId(characteristicOrSubCharacteristicId, session);
+ } finally {
+ MyBatis.closeQuietly(session);
+ }
+ }
+
+ /**
+ * Return all rules (even the REMOVED ones) linked on to a sub characteristic
+ */
+ public List<RuleDto> selectBySubCharacteristicId(Integer subCharacteristicId, SqlSession session) {
+ return getMapper(session).selectBySubCharacteristicId(subCharacteristicId);
+ }
+
+ @CheckForNull
+ public RuleDto selectById(Integer id, SqlSession session) {
+ return getMapper(session).selectById(id);
+ }
+
+ @CheckForNull
+ public RuleDto selectById(Integer id) {
+ SqlSession session = mybatis.openSession(false);
+ try {
+ return selectById(id, session);
+ } finally {
+ MyBatis.closeQuietly(session);
+ }
+ }
+
+ @CheckForNull
+ public RuleDto selectByKey(RuleKey ruleKey, SqlSession session) {
+ return getMapper(session).selectByKey(ruleKey);
+ }
+
+
+ @CheckForNull
+ public RuleDto selectByKey(RuleKey ruleKey) {
+ SqlSession session = mybatis.openSession(false);
+ try {
+ return selectByKey(ruleKey, session);
+ } finally {
+ MyBatis.closeQuietly(session);
+ }
+ }
+
+ @CheckForNull
+ public RuleDto selectByName(String name) {
+ SqlSession session = mybatis.openSession(false);
+ try {
+ return getMapper(session).selectByName(name);
+ } finally {
+ MyBatis.closeQuietly(session);
+ }
+ }
+
+ public void insert(Collection<RuleDto> rules) {
+ DbSession session = mybatis.openSession(true);
+ try {
+ for (RuleDto rule : rules) {
+ getMapper(session).batchInsert(rule);
+ }
+ session.commit();
+ } finally {
+ MyBatis.closeQuietly(session);
+ }
+ }
+
+ // ******************************
+ // Methods for Rule Parameters
+ // ******************************
+
+ public List<RuleParamDto> selectParameters() {
+ SqlSession session = mybatis.openSession(false);
+ try {
+ return selectParameters(session);
+ } finally {
+ MyBatis.closeQuietly(session);
+ }
+ }
+
+ public List<RuleParamDto> selectParameters(SqlSession session) {
+ return getMapper(session).selectAllParams();
+ }
+
+ public List<RuleParamDto> selectParametersByRuleId(Integer ruleId) {
+ SqlSession session = mybatis.openSession(false);
+ try {
+ return selectParametersByRuleId(ruleId, session);
+ } finally {
+ MyBatis.closeQuietly(session);
+ }
+ }
+
+ public List<RuleParamDto> selectParametersByRuleId(Integer ruleId, SqlSession session) {
+ return selectParametersByRuleIds(newArrayList(ruleId));
+ }
+
+ public List<RuleParamDto> selectParametersByRuleIds(List<Integer> ruleIds) {
+ SqlSession session = mybatis.openSession(false);
+ try {
+ return selectParametersByRuleIds(ruleIds, session);
+ } finally {
+ MyBatis.closeQuietly(session);
+ }
+ }
+
+ public List<RuleParamDto> selectParametersByRuleIds(List<Integer> ruleIds, SqlSession session) {
+ List<RuleParamDto> dtos = newArrayList();
+ List<List<Integer>> partitionList = Lists.partition(newArrayList(ruleIds), 1000);
+ for (List<Integer> partition : partitionList) {
+ dtos.addAll(getMapper(session).selectParamsByRuleIds(partition));
+ }
+ return dtos;
+ }
+
+ public void insert(RuleParamDto param, SqlSession session) {
+ getMapper(session).insertParameter(param);
+ }
+
+ public void insert(RuleParamDto param) {
+ SqlSession session = mybatis.openSession(false);
+ try {
+ insert(param, session);
+ session.commit();
+ } finally {
+ MyBatis.closeQuietly(session);
+ }
+ }
+
+ public void update(RuleParamDto param, SqlSession session) {
+ getMapper(session).updateParameter(param);
+ }
+
+ public void update(RuleParamDto param) {
+ SqlSession session = mybatis.openSession(false);
+ try {
+ update(param, session);
+ session.commit();
+ } finally {
+ MyBatis.closeQuietly(session);
+ }
+ }
+
+ @CheckForNull
+ public RuleParamDto selectParamByRuleAndKey(Integer ruleId, String key, SqlSession session) {
+ return getMapper(session).selectParamByRuleAndKey(ruleId, key);
+ }
+
+ private RuleMapper getMapper(SqlSession session) {
+ return session.getMapper(RuleMapper.class);
+ }
+
+ // ***************************
+ // Methods for Rule Tags
+ // ***************************
+
+ public void insert(RuleRuleTagDto newTag, SqlSession session) {
+ getMapper(session).insertTag(newTag);
+ }
+
+ public void deleteParam(RuleParamDto persistedParam, SqlSession sqlSession) {
+ getMapper(sqlSession).deleteParameter(persistedParam.getId());
+ }
+
+ public void deleteTag(RuleRuleTagDto tagToDelete, SqlSession session) {
+ getMapper(session).deleteTag(tagToDelete.getId().intValue());
+ }
+
+ public void update(RuleRuleTagDto existingTag, SqlSession session) {
+ getMapper(session).updateTag(existingTag);
+ }
+
+ public List<RuleRuleTagDto> selectTags(SqlSession session) {
+ return getMapper(session).selectAllTags();
+ }
+
+ public List<RuleRuleTagDto> selectTagsByRuleId(Integer ruleId) {
+ SqlSession session = mybatis.openSession(false);
+ try {
+ return selectTagsByRuleIds(ruleId, session);
+ } finally {
+ MyBatis.closeQuietly(session);
+ }
+ }
+
+ public List<RuleRuleTagDto> selectTagsByRuleIds(Integer ruleId, SqlSession session) {
+ return selectTagsByRuleIds(newArrayList(ruleId), session);
+ }
+
+ public List<RuleRuleTagDto> selectTagsByRuleIds(List<Integer> ruleIds) {
+ SqlSession session = mybatis.openSession(false);
+ try {
+ return selectTagsByRuleIds(ruleIds, session);
+ } finally {
+ MyBatis.closeQuietly(session);
+ }
+ }
+
+ public List<RuleRuleTagDto> selectTagsByRuleIds(List<Integer> ruleIds, SqlSession session) {
+ List<RuleRuleTagDto> dtos = newArrayList();
+ List<List<Integer>> partitionList = Lists.partition(newArrayList(ruleIds), 1000);
+ for (List<Integer> partition : partitionList) {
+ dtos.addAll(getMapper(session).selectTagsByRuleIds(partition));
+ }
+ return dtos;
+ }
+
+ @Override
+ public Collection<RuleKey> keysOfRowsUpdatedAfter(long timestamp) {
+ SqlSession session = mybatis.openSession(false);
+ try {
+ final List<RuleKey> keys = Lists.newArrayList();
+ session.select("selectKeysOfRulesUpdatedSince", new Timestamp(timestamp), new ResultHandler() {
+ @Override
+ public void handleResult(ResultContext context) {
+ Map<String, String> map = (Map) context.getResultObject();
+ keys.add(RuleKey.of(map.get("repo"), map.get("rule")));
+ }
+ });
+ return keys;
+ } finally {
+ MyBatis.closeQuietly(session);
+ }
+ }
+}
--- /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;
+
+import org.sonar.api.rule.RuleKey;
+import org.sonar.api.rule.Severity;
+import org.sonar.api.server.debt.DebtRemediationFunction;
+import org.sonar.server.search.Hit;
+
+import java.util.Collections;
+import java.util.Date;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+public class RuleImpl implements Rule {
+
+ private Map<String, Object> fields;
+
+ public RuleImpl(){
+ this.fields = new HashMap<String, Object>();
+ }
+
+ private RuleImpl(Map<String, Object> fields){
+ this.fields = fields;
+ }
+
+ @Override
+ public RuleKey key() {
+ return RuleKey.of((String)this.fields.get("repositoryKey"),
+ (String)this.fields.get("ruleKey"));
+ }
+
+ @Override
+ public String language() {
+ return (String) this.fields.get("language");
+ }
+
+ @Override
+ public String name() {
+ return (String) this.fields.get("name");
+ }
+
+ @Override
+ public String description() {
+ return (String) this.fields.get("description");
+ }
+
+ @Override
+ public Severity severity() {
+ //FIXME missign Severity.of(String) or Severity.of(int);
+ return null;
+ }
+
+ @Override
+ public String status() {
+ return (String) this.fields.get("status");
+ }
+
+ @Override
+ public boolean template() {
+ //FIXME missign information in map.
+ return false;
+ }
+
+ @Override
+ @SuppressWarnings("unchecked")
+ public List<String> tags() {
+ return (List<String>) this.fields.get("tags");
+ }
+
+ @Override
+ public List<RuleParam> params() {
+ //FIXME not yet Implemented in ES
+ return Collections.emptyList();
+ }
+
+ @Override
+ public String debtCharacteristicKey() {
+ return (String) this.fields.get("debtCharacteristicKey");
+ }
+
+ @Override
+ public String debtSubCharacteristicKey() {
+ return (String) this.fields.get("debtSubCharacteristicKey");
+ }
+
+ @Override
+ public DebtRemediationFunction debtRemediationFunction() {
+ //FIXME how to construct from string "defaultRemediationFunction"
+ return null;
+ }
+
+ @Override
+ public Date createdAt() {
+ return (Date) this.fields.get("createdAt");
+ }
+
+ @Override
+ public Date updatedAt() {
+ return (Date) this.fields.get("updatedAt");
+ }
+
+ public static Rule fromHit(Hit hit) {
+ return new RuleImpl(hit.getFields());
+ }
+
+}
*/
package org.sonar.server.rule2;
-import org.sonar.core.qualityprofile.db.ActiveRuleDto;
-import org.sonar.core.qualityprofile.db.ActiveRuleDao;
import org.apache.commons.beanutils.BeanUtils;
import org.elasticsearch.common.xcontent.XContentBuilder;
import org.slf4j.Logger;
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.RuleDao;
+import org.sonar.server.rule2.RuleDao;
import org.sonar.core.rule.RuleDto;
import org.sonar.server.es.ESNode;
import org.sonar.server.search.BaseIndex;
private ActiveRuleDao activeRuleDao;
- public RuleIndex(WorkQueue queue, RuleDao dao, ActiveRuleDao ActiveRuleDao, Profiling profiling, ESNode node) {
- super(queue, dao, profiling, node);
+ public RuleIndex(WorkQueue workQueue, RuleDao dao, ActiveRuleDao ActiveRuleDao, Profiling profiling, ESNode node) {
+ super(workQueue, dao, profiling, node);
this.activeRuleDao = ActiveRuleDao;
}
try {
- long start = System.currentTimeMillis();
RuleDto rule = dao.getByKey(key);
- LOG.info("Action dao.getByKey(key) in {} took {}ms",
- this.getIndexName(), (System.currentTimeMillis() - start));
XContentBuilder document = jsonBuilder().startObject();
document.field(property.getKey(), property.getValue());
}
- start = System.currentTimeMillis();
-
document.startArray("active");
for (ActiveRuleDto activeRule : activeRuleDao.selectByRuleId(rule.getId())) {
document.startObject();
}
document.endArray();
- LOG.info("Action activeRuleDao.selectByRuleId(rule.getId()) in {} took {}ms",
- this.getIndexName(), (System.currentTimeMillis() - start));
-
return document.endObject();
} catch (IOException e) {
LOG.error("Could not normalize {} in {} because {}",
import org.sonar.api.ServerComponent;
import org.sonar.api.rule.RuleKey;
import org.sonar.core.rule.RuleDao;
+import org.sonar.core.rule.RuleDto;
import org.sonar.server.search.Hit;
import org.sonar.server.search.QueryOptions;
import org.sonar.server.search.Results;
import javax.annotation.CheckForNull;
+import java.util.Collection;
+import java.util.Collections;
+
/**
* @since 4.4
*/
public Results search(RuleQuery query, QueryOptions options) {
throw new UnsupportedOperationException("TODO");
}
+
+ public Collection<Hit> search(RuleQuery query) {
+ return Collections.emptyList();
+ }
+
+ public static Rule toRule(RuleDto ruleDto) {
+ return new RuleImpl();
+ }
+
+ public static Rule toRule(Hit hit) {
+ return RuleImpl.fromHit(hit);
+ }
}
import org.elasticsearch.common.xcontent.XContentBuilder;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
-import org.sonar.core.cluster.IndexAction;
-import org.sonar.core.cluster.IndexAction.Method;
+import org.sonar.server.search.IndexAction;
+import org.sonar.server.search.IndexAction.Method;
import org.sonar.core.cluster.WorkQueue;
import org.sonar.core.db.Dao;
import org.sonar.core.db.Dto;
private final Profiling profiling;
private Client client;
private final ESNode node;
- private WorkQueue workQueue;
private IndexSynchronizer<K> synchronizer;
protected Dao<E, K> dao;
public BaseIndex(WorkQueue workQueue, Dao<E, K> dao, Profiling profiling, ESNode node) {
this.profiling = profiling;
- this.workQueue = workQueue;
- this.synchronizer = new IndexSynchronizer<K>(this, dao, this.workQueue);
+ this.synchronizer = new IndexSynchronizer<K>(this, dao, workQueue);
this.dao = dao;
this.node = node;
}
/* Index Action Methods */
@Override
- public void executeAction(IndexAction<K> action) {
- StopWatch watch = this.createWatch();
+ public boolean executeAction(IndexAction<K> action) {
long start = System.currentTimeMillis();
if (action.getMethod().equals(Method.DELETE)) {
this.delete(action.getKey());
} else if (action.getMethod().equals(Method.UPDATE)) {
this.update(action.getKey());
}
- LOG.info("Action {} in {} took {}ms", action.getMethod(),
+ LOG.debug("Action {} in {} took {}ms", action.getMethod(),
this.getIndexName(), (System.currentTimeMillis() - start));
- watch.stop("Action {} in {}", action.getMethod(), this.getIndexName());
+ return true;
}
/* Index management methods */
XContentBuilder doc = this.normalize(key);
String keyvalue = this.getKeyValue(key);
if (doc != null && keyvalue != null && !keyvalue.isEmpty()) {
- LOG.info("Update document with key {}", key);
+ LOG.debug("Update document with key {}", key);
IndexResponse result = getClient().index(
new IndexRequest(this.getIndexName(),
this.getType(), keyvalue)
import org.elasticsearch.common.xcontent.XContentBuilder;
import org.picocontainer.Startable;
-import org.sonar.core.cluster.IndexAction;
import javax.annotation.CheckForNull;
import java.io.Serializable;
String getIndexName();
- void executeAction(IndexAction<K> action);
+ boolean executeAction(IndexAction<K> action);
@CheckForNull
Hit getByKey(K key);
--- /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.search;
+
+import org.sonar.core.cluster.ClusterAction;
+
+import java.io.Serializable;
+
+public class IndexAction<K extends Serializable> extends ClusterAction {
+
+ public enum Method {
+ INSERT, UPDATE, DELETE
+ }
+
+ private String indexName;
+ private K key;
+ private Method method;
+ private Index<K> index;
+
+
+ public IndexAction(String indexName, Method method, K key){
+ super();
+ this.indexName = indexName;
+ this.method = method;
+ this.key = key;
+ }
+
+ public Method getMethod(){
+ return this.method;
+ }
+
+ public String getIndexName() {
+ return indexName;
+ }
+
+ public void setIndexName(String indexName) {
+ this.indexName = indexName;
+ }
+
+ public K getKey() {
+ return key;
+ }
+
+ public void setKey(K key) {
+ this.key = key;
+ }
+
+ public void setMethod(Method method) {
+ this.method = method;
+ }
+
+ @Override
+ public void doExecute() {
+ index.executeAction(this);
+ }
+
+ @SuppressWarnings("unchecked")
+ public void setIndex(Index<?> index) {
+ this.index = (Index<K>) index;
+ }
+
+ @Override
+ public String toString(){
+ return "{IndexAction {key: " + getKey()+"}";
+ }
+}
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
-import org.sonar.core.cluster.IndexAction;
import org.sonar.core.cluster.WorkQueue;
import org.sonar.core.db.Dao;
if (LOG.isTraceEnabled()) {
LOG.trace("Adding {} to workQueue for {}", key, index.getClass().getSimpleName());
}
- workQueue.enqueue(new IndexAction(index.getIndexName(), IndexAction.Method.INSERT, key));
+ workQueue.enqueue(new IndexAction<K>(index.getIndexName(), IndexAction.Method.INSERT, key));
}
return this;
package org.sonar.server.search;
import com.google.common.collect.ImmutableList;
-
-import org.sonar.server.rule2.RuleIndex;
import org.sonar.server.cluster.LocalQueueWorker;
+import org.sonar.server.rule2.RuleIndex;
import java.util.List;
public final class IndexUtils {
- private IndexUtils() {
- }
@SuppressWarnings("unchecked")
public static List<Class> getIndexClasses() {
+++ /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.cluster;
-
-import org.sonar.core.cluster.IndexAction;
-import org.junit.Test;
-import static org.fest.assertions.Assertions.assertThat;
-
-public class LocalNonBlockingWorkQueueTest {
-
- private static final String WORKING_IDNEX = "working_index";
-
- @Test
- public void test_enqueue_dequeue_indexAction(){
- LocalNonBlockingWorkQueue queue = new LocalNonBlockingWorkQueue();
- queue.enqueue(new IndexAction(WORKING_IDNEX, IndexAction.Method.INSERT,new Integer(33)));
- IndexAction action = queue.dequeue();
- assertThat(action.getIndexName()).isEqualTo(WORKING_IDNEX);
- assertThat(action.getKey()).isEqualTo(new Integer(33));
- }
-
- @Test
- public void test_enqueue_dequeue_to_null(){
- LocalNonBlockingWorkQueue queue = new LocalNonBlockingWorkQueue();
- queue.enqueue(new IndexAction<Integer>(WORKING_IDNEX, IndexAction.Method.INSERT,new Integer(33)));
- queue.enqueue(new IndexAction(WORKING_IDNEX, IndexAction.Method.INSERT,new Integer(33)));
- assertThat(queue.dequeue()).isNotNull();
- assertThat(queue.dequeue()).isNotNull();
- assertThat(queue.dequeue()).isNull();
- }
-}
+++ /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.cluster;
-
-import org.sonar.core.cluster.IndexAction;
-import org.junit.Test;
-import static org.fest.assertions.Assertions.assertThat;
-
-public class LocalQueueWorkerTest {
-
- private static final String WORKING_IDNEX = "working_index";
-
- @Test
- public void test_worker_dequeue(){
- LocalNonBlockingWorkQueue queue = new LocalNonBlockingWorkQueue();
- LocalQueueWorker worker = new LocalQueueWorker(queue);
- worker.start();
- queue.enqueue(new IndexAction(WORKING_IDNEX, IndexAction.Method.INSERT,new Integer(33)));
- queue.enqueue(new IndexAction(WORKING_IDNEX, IndexAction.Method.INSERT,new Integer(33)));
- try {
- Thread.sleep(500);
- } catch (InterruptedException e) {
- // TODO Auto-generated catch block
- e.printStackTrace();
- }
- assertThat(queue.dequeue()).isNull();
- queue = null;
- }
-}
--- /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;
+
+import com.google.common.base.Function;
+import com.google.common.collect.ImmutableList;
+import com.google.common.collect.Iterables;
+import org.apache.ibatis.session.SqlSession;
+import org.junit.Before;
+import org.junit.Test;
+import org.sonar.api.rule.RuleKey;
+import org.sonar.api.rule.Severity;
+import org.sonar.api.rules.Rule;
+import org.sonar.api.utils.DateUtils;
+import org.sonar.check.Cardinality;
+import org.sonar.core.persistence.AbstractDaoTestCase;
+import org.sonar.core.rule.RuleDto;
+import org.sonar.core.rule.RuleParamDto;
+
+import java.util.Arrays;
+import java.util.List;
+
+import static com.google.common.collect.Lists.newArrayList;
+import static org.fest.assertions.Assertions.assertThat;
+
+public class RuleDaoTest extends AbstractDaoTestCase {
+
+ private static RuleDao dao;
+
+ @Before
+ public void createDao() throws Exception {
+ dao = new RuleDao(getMyBatis());
+ }
+
+ @Test
+ public void select_all() throws Exception {
+ setupData("selectAll");
+ List<RuleDto> ruleDtos = dao.selectAll();
+
+ assertThat(ruleDtos).hasSize(1);
+
+ RuleDto ruleDto = ruleDtos.get(0);
+ assertThat(ruleDto.getId()).isEqualTo(1);
+ assertThat(ruleDto.getName()).isEqualTo("Avoid Null");
+ assertThat(ruleDto.getDescription()).isEqualTo("Should avoid NULL");
+ assertThat(ruleDto.getStatus()).isEqualTo(Rule.STATUS_READY);
+ assertThat(ruleDto.getRepositoryKey()).isEqualTo("checkstyle");
+ assertThat(ruleDto.getNoteData()).isEqualTo("Rule note with accents \u00e9\u00e8\u00e0");
+ assertThat(ruleDto.getSubCharacteristicId()).isEqualTo(100);
+ assertThat(ruleDto.getDefaultSubCharacteristicId()).isEqualTo(101);
+ assertThat(ruleDto.getRemediationFunction()).isEqualTo("linear");
+ assertThat(ruleDto.getDefaultRemediationFunction()).isEqualTo("linear_offset");
+ assertThat(ruleDto.getRemediationCoefficient()).isEqualTo("1h");
+ assertThat(ruleDto.getDefaultRemediationCoefficient()).isEqualTo("5d");
+ assertThat(ruleDto.getRemediationOffset()).isEqualTo("5min");
+ assertThat(ruleDto.getDefaultRemediationOffset()).isEqualTo("10h");
+ assertThat(ruleDto.getEffortToFixDescription()).isEqualTo("squid.S115.effortToFix");
+ }
+
+ @Test
+ public void select_enables_and_non_manual() throws Exception {
+ setupData("select_enables_and_non_manual");
+ List<RuleDto> ruleDtos = dao.selectEnablesAndNonManual();
+
+ assertThat(ruleDtos.size()).isEqualTo(1);
+ RuleDto ruleDto = ruleDtos.get(0);
+ assertThat(ruleDto.getId()).isEqualTo(1);
+ assertThat(ruleDto.getName()).isEqualTo("Avoid Null");
+ assertThat(ruleDto.getDescription()).isEqualTo("Should avoid NULL");
+ assertThat(ruleDto.getStatus()).isEqualTo(Rule.STATUS_READY);
+ assertThat(ruleDto.getRepositoryKey()).isEqualTo("checkstyle");
+ assertThat(ruleDto.getNoteData()).isEqualTo("Rule note with accents \u00e9\u00e8\u00e0");
+ assertThat(ruleDto.getSubCharacteristicId()).isEqualTo(100);
+ assertThat(ruleDto.getDefaultSubCharacteristicId()).isEqualTo(101);
+ assertThat(ruleDto.getRemediationFunction()).isEqualTo("LINEAR");
+ assertThat(ruleDto.getDefaultRemediationFunction()).isEqualTo("LINEAR_OFFSET");
+ assertThat(ruleDto.getRemediationCoefficient()).isEqualTo("1h");
+ assertThat(ruleDto.getDefaultRemediationCoefficient()).isEqualTo("5d");
+ assertThat(ruleDto.getRemediationOffset()).isEqualTo("5min");
+ assertThat(ruleDto.getDefaultRemediationOffset()).isEqualTo("10h");
+ assertThat(ruleDto.getEffortToFixDescription()).isEqualTo("squid.S115.effortToFix");
+ }
+
+ @Test
+ public void select_by_id() throws Exception {
+ setupData("selectById");
+ RuleDto ruleDto = dao.selectById(2);
+
+ assertThat(ruleDto.getId()).isEqualTo(2);
+ assertThat(ruleDto.getName()).isEqualTo("Avoid Null");
+ assertThat(ruleDto.getDescription()).isEqualTo("Should avoid NULL");
+ assertThat(ruleDto.getStatus()).isEqualTo(Rule.STATUS_READY);
+ assertThat(ruleDto.getRepositoryKey()).isEqualTo("checkstyle");
+ }
+
+ @Test
+ public void select_by_rule_key() throws Exception {
+ setupData("select_by_rule_key");
+ assertThat(dao.selectByKey(RuleKey.of("checkstyle", "AvoidComparison"))).isNotNull();
+ assertThat(dao.selectByKey(RuleKey.of("checkstyle", "Unknown"))).isNull();
+ assertThat(dao.selectByKey(RuleKey.of("Unknown", "AvoidComparison"))).isNull();
+ }
+
+ @Test
+ public void select_by_name() throws Exception {
+ setupData("select_by_name");
+ RuleDto ruleDto = dao.selectByName("Avoid Null");
+
+ assertThat(ruleDto.getId()).isEqualTo(2);
+ assertThat(ruleDto.getName()).isEqualTo("Avoid Null");
+ assertThat(ruleDto.getDescription()).isEqualTo("Should avoid NULL");
+ assertThat(ruleDto.getStatus()).isEqualTo(Rule.STATUS_READY);
+ assertThat(ruleDto.getRepositoryKey()).isEqualTo("checkstyle");
+ }
+
+ @Test
+ public void select_non_manual() throws Exception {
+ setupData("selectNonManual");
+ SqlSession session = getMyBatis().openSession();
+ List<RuleDto> ruleDtos = dao.selectNonManual(session);
+ session.commit();
+ session.close();
+
+ assertThat(ruleDtos.size()).isEqualTo(1);
+ RuleDto ruleDto = ruleDtos.get(0);
+ assertThat(ruleDto.getId()).isEqualTo(1);
+ assertThat(ruleDto.getName()).isEqualTo("Avoid Null");
+ assertThat(ruleDto.getDescription()).isEqualTo("Should avoid NULL");
+ assertThat(ruleDto.getStatus()).isEqualTo(Rule.STATUS_READY);
+ assertThat(ruleDto.getRepositoryKey()).isEqualTo("checkstyle");
+ }
+
+ @Test
+ public void select_by_sub_characteristic_id(){
+ setupData("select_by_sub_characteristic_id");
+
+ // Rules from sub characteristic (even REMOVED ones are returned)
+ List<RuleDto> ruleDtos = dao.selectBySubCharacteristicId(3);
+ assertThat(ruleDtos).hasSize(3);
+ assertThat(idsFromRuleDtos(ruleDtos)).containsExactly(2, 4, 5);
+
+ // Nothing on root characteristic
+ ruleDtos = dao.selectBySubCharacteristicId(1);
+ assertThat(ruleDtos).isEmpty();
+
+ // Rules from disabled characteristic
+ ruleDtos = dao.selectBySubCharacteristicId(11);
+ assertThat(idsFromRuleDtos(ruleDtos)).containsExactly(3);
+ }
+
+ @Test
+ public void update() {
+ setupData("update");
+
+ RuleDto ruleToUpdate = new RuleDto()
+ .setId(1)
+ .setRuleKey("NewRuleKey")
+ .setRepositoryKey("plugin")
+ .setName("new name")
+ .setDescription("new description")
+ .setStatus(Rule.STATUS_DEPRECATED)
+ .setConfigKey("NewConfigKey")
+ .setSeverity(Severity.INFO)
+ .setCardinality(Cardinality.MULTIPLE)
+ .setLanguage("dart")
+ .setParentId(3)
+ .setNoteData("My note")
+ .setNoteUserLogin("admin")
+ .setNoteCreatedAt(DateUtils.parseDate("2013-12-19"))
+ .setNoteUpdatedAt(DateUtils.parseDate("2013-12-20"))
+ .setSubCharacteristicId(100)
+ .setDefaultSubCharacteristicId(101)
+ .setRemediationFunction("linear")
+ .setDefaultRemediationFunction("linear_offset")
+ .setRemediationCoefficient("1h")
+ .setDefaultRemediationCoefficient("5d")
+ .setRemediationOffset("5min")
+ .setDefaultRemediationOffset("10h")
+ .setEffortToFixDescription("squid.S115.effortToFix")
+ .setUpdatedAt(DateUtils.parseDate("2013-12-17"));
+
+ dao.update(ruleToUpdate);
+
+ checkTables("update", "rules");
+ }
+
+ @Test
+ public void insert() {
+ setupData("empty");
+
+ RuleDto ruleToInsert = new RuleDto()
+ .setId(1)
+ .setRuleKey("NewRuleKey")
+ .setRepositoryKey("plugin")
+ .setName("new name")
+ .setDescription("new description")
+ .setStatus(Rule.STATUS_DEPRECATED)
+ .setConfigKey("NewConfigKey")
+ .setSeverity(Severity.INFO)
+ .setCardinality(Cardinality.MULTIPLE)
+ .setLanguage("dart")
+ .setParentId(3)
+ .setSubCharacteristicId(100)
+ .setDefaultSubCharacteristicId(101)
+ .setRemediationFunction("linear")
+ .setDefaultRemediationFunction("linear_offset")
+ .setRemediationCoefficient("1h")
+ .setDefaultRemediationCoefficient("5d")
+ .setRemediationOffset("5min")
+ .setDefaultRemediationOffset("10h")
+ .setEffortToFixDescription("squid.S115.effortToFix")
+ .setCreatedAt(DateUtils.parseDate("2013-12-16"))
+ .setUpdatedAt(DateUtils.parseDate("2013-12-17"));
+
+ dao.insert(ruleToInsert);
+
+ checkTables("insert", "rules");
+ }
+
+ @Test
+ public void insert_all() {
+ setupData("empty");
+
+ RuleDto ruleToInsert1 = new RuleDto()
+ .setId(1)
+ .setRuleKey("NewRuleKey")
+ .setRepositoryKey("plugin")
+ .setName("new name")
+ .setDescription("new description")
+ .setStatus(Rule.STATUS_DEPRECATED)
+ .setConfigKey("NewConfigKey")
+ .setSeverity(Severity.INFO)
+ .setCardinality(Cardinality.MULTIPLE)
+ .setLanguage("dart")
+ .setParentId(3)
+ .setSubCharacteristicId(100)
+ .setDefaultSubCharacteristicId(101)
+ .setRemediationFunction("linear")
+ .setDefaultRemediationFunction("linear_offset")
+ .setRemediationCoefficient("1h")
+ .setDefaultRemediationCoefficient("5d")
+ .setRemediationOffset("5min")
+ .setDefaultRemediationOffset("10h")
+ .setEffortToFixDescription("squid.S115.effortToFix")
+ .setCreatedAt(DateUtils.parseDate("2013-12-16"))
+ .setUpdatedAt(DateUtils.parseDate("2013-12-17"));
+
+ RuleDto ruleToInsert2 = new RuleDto()
+ .setId(2)
+ .setRuleKey("NewRuleKey2")
+ .setRepositoryKey("plugin2")
+ .setName("new name2")
+ .setDescription("new description2")
+ .setStatus(Rule.STATUS_BETA)
+ .setConfigKey("NewConfigKey2")
+ .setSeverity(Severity.MAJOR)
+ .setCardinality(Cardinality.SINGLE)
+ .setLanguage("js")
+ .setParentId(null)
+ .setSubCharacteristicId(102)
+ .setDefaultSubCharacteristicId(103)
+ .setRemediationFunction("linear_offset")
+ .setDefaultRemediationFunction("linear")
+ .setRemediationCoefficient("5d")
+ .setDefaultRemediationCoefficient("1h")
+ .setRemediationOffset("10h")
+ .setDefaultRemediationOffset("5min")
+ .setEffortToFixDescription("squid.S115.effortToFix2")
+ .setCreatedAt(DateUtils.parseDate("2013-12-14"))
+ .setUpdatedAt(DateUtils.parseDate("2013-12-15"));
+
+ dao.insert(ImmutableList.of(ruleToInsert1, ruleToInsert2));
+
+ checkTables("insert_all", "rules");
+ }
+
+ @Test
+ public void select_parameters() throws Exception {
+ setupData("selectParameters");
+ List<RuleParamDto> ruleDtos = dao.selectParameters();
+
+ assertThat(ruleDtos.size()).isEqualTo(1);
+ RuleParamDto ruleDto = ruleDtos.get(0);
+ assertThat(ruleDto.getId()).isEqualTo(1);
+ assertThat(ruleDto.getName()).isEqualTo("myParameter");
+ assertThat(ruleDto.getDescription()).isEqualTo("My Parameter");
+ assertThat(ruleDto.getType()).isEqualTo("plop");
+ assertThat(ruleDto.getDefaultValue()).isEqualTo("plouf");
+ }
+
+ @Test
+ public void select_parameters_by_rule_id() throws Exception {
+ setupData("select_parameters_by_rule_id");
+ int ruleId = 1;
+ List<RuleParamDto> ruleDtos = dao.selectParametersByRuleId(ruleId);
+
+ assertThat(ruleDtos.size()).isEqualTo(1);
+ RuleParamDto ruleDto = ruleDtos.get(0);
+ assertThat(ruleDto.getId()).isEqualTo(1);
+ assertThat(ruleDto.getName()).isEqualTo("myParameter");
+ assertThat(ruleDto.getDescription()).isEqualTo("My Parameter");
+ assertThat(ruleDto.getType()).isEqualTo("plop");
+ assertThat(ruleDto.getRuleId()).isEqualTo(ruleId);
+ }
+
+ @Test
+ public void select_parameters_by_rule_ids() throws Exception {
+ setupData("select_parameters_by_rule_ids");
+
+ assertThat(dao.selectParametersByRuleIds(newArrayList(1, 2))).hasSize(2);
+ assertThat(dao.selectParametersByRuleIds(newArrayList(1))).hasSize(1);
+ }
+
+ @Test
+ public void insert_parameter() {
+ setupData("insert_parameter");
+
+ RuleParamDto param = new RuleParamDto()
+ .setRuleId(1)
+ .setName("max")
+ .setType("INTEGER")
+ .setDefaultValue("30")
+ .setDescription("My Parameter");
+
+ dao.insert(param);
+
+ checkTables("insert_parameter", "rules_parameters");
+ }
+
+ @Test
+ public void update_parameter() {
+ setupData("update_parameter");
+
+ RuleParamDto param = new RuleParamDto()
+ .setId(1)
+ .setName("format")
+ .setType("STRING")
+ .setDefaultValue("^[a-z]+(\\.[a-z][a-z0-9]*)*$")
+ .setDescription("Regular expression used to check the package names against.");
+
+ dao.update(param);
+
+ checkTables("update_parameter", "rules_parameters");
+ }
+
+ @Test
+ public void select_tags_by_rule_id() throws Exception {
+ setupData("select_tags_by_rule_id");
+
+ assertThat(dao.selectTagsByRuleId(3)).hasSize(2);
+ }
+
+ @Test
+ public void select_tags_by_rule_ids() throws Exception {
+ setupData("select_tags_by_rule_ids");
+
+ assertThat(dao.selectTagsByRuleIds(newArrayList(3, 4))).hasSize(3);
+ }
+
+ @Test
+ public void keysOfRowsUpdatedAfter() throws Exception {
+ setupData("empty");
+
+ RuleDto rule1 = new RuleDto()
+ .setId(1)
+ .setRepositoryKey("foo")
+ .setRuleKey("R1")
+ .setName("ROne")
+ .setCreatedAt(DateUtils.parseDate("2013-12-16"))
+ .setUpdatedAt(DateUtils.parseDate("2013-12-16"));
+ RuleDto rule2 = new RuleDto()
+ .setId(2)
+ .setRepositoryKey("foo")
+ .setRuleKey("R2")
+ .setName("RTwo")
+ .setCreatedAt(DateUtils.parseDate("2014-01-28"))
+ .setUpdatedAt(DateUtils.parseDate("2014-05-19"));
+ dao.insert(Arrays.asList(rule1, rule2));
+
+ assertThat(dao.keysOfRowsUpdatedAfter(DateUtils.parseDate("2014-06-01").getTime())).isEmpty();
+ assertThat(dao.keysOfRowsUpdatedAfter(DateUtils.parseDate("2012-01-01").getTime())).hasSize(2);
+ Iterable<RuleKey> keys = dao.keysOfRowsUpdatedAfter(DateUtils.parseDate("2014-05-17").getTime());
+ assertThat(keys).hasSize(1);
+ assertThat(Iterables.getFirst(keys, null).rule()).isEqualTo("R2");
+ }
+
+ private List<Integer> idsFromRuleDtos(List<RuleDto> ruleDtos){
+ return newArrayList(Iterables.transform(ruleDtos, new Function<RuleDto, Integer>() {
+ @Override
+ public Integer apply(RuleDto input) {
+ return input.getId();
+ }
+ }));
+ }
+}
*/
package org.sonar.server.rule2;
+import org.junit.After;
import org.junit.Before;
import org.junit.Rule;
import org.junit.Test;
import org.sonar.api.rule.Severity;
import org.sonar.api.utils.DateUtils;
import org.sonar.check.Cardinality;
+import org.sonar.core.persistence.DbSession;
+import org.sonar.core.persistence.MyBatis;
import org.sonar.core.qualityprofile.db.ActiveRuleDao;
import org.sonar.core.qualityprofile.db.ActiveRuleDto;
-import org.sonar.core.rule.RuleDao;
import org.sonar.core.rule.RuleDto;
import org.sonar.server.search.Hit;
import org.sonar.server.tester.ServerTester;
@Rule
public ServerTester tester = new ServerTester()
- //.setProperty("sonar.log.profilingLevel", "FULL")
- .setProperty("sonar.es.http.port", "8888");
+ // .setProperty("sonar.log.profilingLevel", "FULL")
+ .setProperty("sonar.es.http.port", "8888");
private RuleDto dto;
private ActiveRuleDto adto;
@Before
- public void setup(){
+ public void setup() {
dto = getRuleDto(1);
adto = getActiveRuleDto(dto);
}
- private ActiveRuleDto getActiveRuleDto(RuleDto dto){
+ @After
+ public void teardown() {
+ tester.stop();
+ }
+
+ private ActiveRuleDto getActiveRuleDto(RuleDto dto) {
return new ActiveRuleDto()
.setId(1)
.setNoteCreatedAt(new Date())
.setProfileId(1)
.setParentId(0)
.setSeverity(3);
- }
+ }
private RuleDto getRuleDto(int id) {
return new RuleDto()
- .setId(id)
- .setRuleKey("NewRuleKey="+id)
+ // .setId(id)
+ .setRuleKey("NewRuleKey=" + id)
.setRepositoryKey("plugin")
.setName("new name")
.setDescription("new description")
RuleIndex index = tester.get(RuleIndex.class);
dao.insert(dto);
- adao.insert(adto);
-
- try {
- Thread.sleep(200);
- } catch (InterruptedException e) {
- ;
- }
Hit hit = index.getByKey(dto.getKey());
assertThat(hit.getFields().get("ruleKey")).isEqualTo(dto.getRuleKey());
dao.insert(dto);
- //org.sonar.server.rule2.Rule rule = service.getByKey(dto.getKey());
-
- //assertThat(rule.key()).isEqualTo(dto.getKey());
+ org.sonar.server.rule2.Rule rule = service.getByKey(dto.getKey());
+ assertThat(rule.key()).isEqualTo(dto.getKey());
}
}