]> source.dussan.org Git - sonarqube.git/commitdiff
SONAR-5007 add RuleService#setNote
authorSimon Brandhof <simon.brandhof@sonarsource.com>
Thu, 15 May 2014 15:05:32 +0000 (17:05 +0200)
committerSimon Brandhof <simon.brandhof@sonarsource.com>
Thu, 15 May 2014 15:05:41 +0000 (17:05 +0200)
18 files changed:
sonar-core/src/main/java/org/sonar/core/db/Dao.java [deleted file]
sonar-core/src/main/java/org/sonar/core/db/Dto.java [deleted file]
sonar-core/src/main/java/org/sonar/core/db/package-info.java [deleted file]
sonar-core/src/main/java/org/sonar/core/persistence/Dto.java [new file with mode: 0644]
sonar-core/src/main/java/org/sonar/core/qualityprofile/db/ActiveRuleDto.java
sonar-core/src/main/java/org/sonar/core/qualityprofile/db/QualityProfileDto.java
sonar-core/src/main/java/org/sonar/core/rule/RuleDto.java
sonar-server/src/main/java/org/sonar/server/db/BaseDao.java
sonar-server/src/main/java/org/sonar/server/db/Dao.java [new file with mode: 0644]
sonar-server/src/main/java/org/sonar/server/rule2/RuleService.java
sonar-server/src/main/java/org/sonar/server/search/BaseIndex.java
sonar-server/src/main/java/org/sonar/server/search/BaseNormalizer.java
sonar-server/src/main/java/org/sonar/server/search/Index.java
sonar-server/src/main/java/org/sonar/server/search/NestedIndex.java
sonar-server/src/main/java/org/sonar/server/search/action/DtoIndexAction.java
sonar-server/src/test/java/org/sonar/server/db/BaseDaoTest.java [new file with mode: 0644]
sonar-server/src/test/java/org/sonar/server/rule2/RuleDataMediumTest.java [new file with mode: 0644]
sonar-server/src/test/java/org/sonar/server/rule2/RuleServiceMediumTest.java

diff --git a/sonar-core/src/main/java/org/sonar/core/db/Dao.java b/sonar-core/src/main/java/org/sonar/core/db/Dao.java
deleted file mode 100644 (file)
index f19951d..0000000
+++ /dev/null
@@ -1,51 +0,0 @@
-/*
- * SonarQube, open source software quality management tool.
- * Copyright (C) 2008-2014 SonarSource
- * mailto:contact AT sonarsource DOT com
- *
- * SonarQube is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 3 of the License, or (at your option) any later version.
- *
- * SonarQube is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public License
- * along with this program; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
- */
-package org.sonar.core.db;
-
-import org.sonar.api.ServerComponent;
-import org.sonar.core.persistence.DbSession;
-
-import javax.annotation.CheckForNull;
-import java.io.Serializable;
-import java.util.Collection;
-import java.util.List;
-
-public interface Dao<E extends Dto<K>, K extends Serializable> extends ServerComponent {
-
-  @CheckForNull
-  E getByKey(K key, DbSession session);
-
-  E update(E item, DbSession session);
-
-  List<E> update(List<E> items, DbSession session);
-
-  E insert(E item, DbSession session);
-
-  List<E> insert(List<E> items, DbSession session);
-
-  void delete(E item, DbSession session);
-
-  void delete(Collection<E> items, DbSession session);
-
-  void deleteByKey(K key, DbSession session);
-
-  Iterable<K> keysOfRowsUpdatedAfter(long timestamp, DbSession session);
-
-}
diff --git a/sonar-core/src/main/java/org/sonar/core/db/Dto.java b/sonar-core/src/main/java/org/sonar/core/db/Dto.java
deleted file mode 100644 (file)
index ba29f7a..0000000
+++ /dev/null
@@ -1,47 +0,0 @@
-/*
- * SonarQube, open source software quality management tool.
- * Copyright (C) 2008-2014 SonarSource
- * mailto:contact AT sonarsource DOT com
- *
- * SonarQube is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 3 of the License, or (at your option) any later version.
- *
- * SonarQube is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public License
- * along with this program; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
- */
-package org.sonar.core.db;
-
-import java.io.Serializable;
-import java.util.Date;
-
-public abstract class Dto<K extends Serializable> {
-
-  private Date createdAt;
-  private Date updatedAt;
-
-  public abstract K getKey();
-
-  public void setCreatedAt(Date datetime){
-    this.createdAt = datetime;
-  }
-
-  public void setUpdatedAt(Date datetime){
-    this.updatedAt = datetime;
-  }
-
-  public Date getCreatedAt(){
-    return this.createdAt;
-  }
-
-  public Date getUpdatedAt(){
-    return this.updatedAt;
-  }
-}
diff --git a/sonar-core/src/main/java/org/sonar/core/db/package-info.java b/sonar-core/src/main/java/org/sonar/core/db/package-info.java
deleted file mode 100644 (file)
index cb50b64..0000000
+++ /dev/null
@@ -1,23 +0,0 @@
-/*
- * SonarQube, open source software quality management tool.
- * Copyright (C) 2008-2014 SonarSource
- * mailto:contact AT sonarsource DOT com
- *
- * SonarQube is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 3 of the License, or (at your option) any later version.
- *
- * SonarQube is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public License
- * along with this program; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
- */
-@ParametersAreNonnullByDefault
-package org.sonar.core.db;
-
-import javax.annotation.ParametersAreNonnullByDefault;
diff --git a/sonar-core/src/main/java/org/sonar/core/persistence/Dto.java b/sonar-core/src/main/java/org/sonar/core/persistence/Dto.java
new file mode 100644 (file)
index 0000000..d604962
--- /dev/null
@@ -0,0 +1,47 @@
+/*
+ * 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.persistence;
+
+import java.io.Serializable;
+import java.util.Date;
+
+public abstract class Dto<K extends Serializable> {
+
+  private Date createdAt;
+  private Date updatedAt;
+
+  public abstract K getKey();
+
+  public void setCreatedAt(Date datetime){
+    this.createdAt = datetime;
+  }
+
+  public void setUpdatedAt(Date datetime){
+    this.updatedAt = datetime;
+  }
+
+  public Date getCreatedAt(){
+    return this.createdAt;
+  }
+
+  public Date getUpdatedAt(){
+    return this.updatedAt;
+  }
+}
index 1b0039b84ca902e70a652739c570526a0a67ed04..47e14519a825c6530cdf0a813a474f46a401430a 100644 (file)
@@ -23,7 +23,7 @@ package org.sonar.core.qualityprofile.db;
 import org.apache.commons.lang.StringUtils;
 import org.apache.commons.lang.builder.ReflectionToStringBuilder;
 import org.apache.commons.lang.builder.ToStringStyle;
-import org.sonar.core.db.Dto;
+import org.sonar.core.persistence.Dto;
 import org.sonar.core.rule.RuleDto;
 import org.sonar.core.rule.SeverityUtil;
 
index 643c9762abbf147ef3f0d199976fea82c4c855d5..cdf29be0e56f92ac079cc6ceb71b92a0aa22575c 100644 (file)
@@ -20,7 +20,7 @@
 
 package org.sonar.core.qualityprofile.db;
 
-import org.sonar.core.db.Dto;
+import org.sonar.core.persistence.Dto;
 
 import javax.annotation.CheckForNull;
 import javax.annotation.Nullable;
index e50615d49c63e6203e6589d36577d83cb122f746..87fb8803b2fc9046669d61b1b06e66074b67de25 100644 (file)
@@ -26,7 +26,7 @@ import org.apache.commons.lang.builder.ReflectionToStringBuilder;
 import org.apache.commons.lang.builder.ToStringStyle;
 import org.sonar.api.rule.RuleKey;
 import org.sonar.check.Cardinality;
-import org.sonar.core.db.Dto;
+import org.sonar.core.persistence.Dto;
 
 import javax.annotation.CheckForNull;
 import javax.annotation.Nullable;
index ba83f6fc1bee41fc4d8c4fdbe13d3db9dea0df11..c30c6b6401532e1645ad2ff05f505a22f43fc8ff 100644 (file)
@@ -21,9 +21,9 @@ package org.sonar.server.db;
 
 import com.google.common.base.Preconditions;
 import org.sonar.api.utils.System2;
-import org.sonar.core.db.Dao;
-import org.sonar.core.db.Dto;
+import org.sonar.core.persistence.Dto;
 import org.sonar.core.persistence.DbSession;
+import org.sonar.server.exceptions.NotFoundException;
 import org.sonar.server.search.IndexDefinition;
 import org.sonar.server.search.action.DtoIndexAction;
 import org.sonar.server.search.action.EmbeddedIndexAction;
@@ -136,6 +136,14 @@ public abstract class BaseDao<M, E extends Dto<K>, K extends Serializable> imple
     return doGetByKey(key, session);
   }
 
+  public E getNonNullByKey(K key, DbSession session) {
+    E value = doGetByKey(key, session);
+    if (value == null) {
+      throw new NotFoundException(String.format("Key '%s' not found", key));
+    }
+    return value;
+  }
+
   @Override
   public E update(E item, DbSession session) {
     item.setUpdatedAt(new Date(system2.now()));
@@ -175,7 +183,7 @@ public abstract class BaseDao<M, E extends Dto<K>, K extends Serializable> imple
 
   @Override
   public void delete(E item, DbSession session) {
-    Preconditions.checkNotNull(item.getKey(),"Dto does not have a valid Key");
+    Preconditions.checkNotNull(item.getKey(), "Dto does not have a valid Key");
     deleteByKey(item.getKey(), session);
   }
 
@@ -195,16 +203,16 @@ public abstract class BaseDao<M, E extends Dto<K>, K extends Serializable> imple
 
   protected void enqueueUpdate(Object nestedItem, K key, DbSession session) {
     session.enqueue(new EmbeddedIndexAction<K>(
-      this.getIndexType(), IndexAction.Method.UPDATE, nestedItem,  key));
+      this.getIndexType(), IndexAction.Method.UPDATE, nestedItem, key));
   }
 
   public void enqueueDelete(Object nestedItem, K key, DbSession session) {
     session.enqueue(new EmbeddedIndexAction<K>(
-      this.getIndexType(), IndexAction.Method.DELETE, nestedItem,  key));
+      this.getIndexType(), IndexAction.Method.DELETE, nestedItem, key));
   }
 
   public void enqueueInsert(Object nestedItem, K key, DbSession session) {
     session.enqueue(new EmbeddedIndexAction<K>(
-      this.getIndexType(), IndexAction.Method.INSERT, nestedItem,  key));
+      this.getIndexType(), IndexAction.Method.INSERT, nestedItem, key));
   }
 }
diff --git a/sonar-server/src/main/java/org/sonar/server/db/Dao.java b/sonar-server/src/main/java/org/sonar/server/db/Dao.java
new file mode 100644 (file)
index 0000000..b061a10
--- /dev/null
@@ -0,0 +1,54 @@
+/*
+ * 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.sonar.api.ServerComponent;
+import org.sonar.core.persistence.Dto;
+import org.sonar.core.persistence.DbSession;
+
+import javax.annotation.CheckForNull;
+import java.io.Serializable;
+import java.util.Collection;
+import java.util.List;
+
+public interface Dao<E extends Dto<K>, K extends Serializable> extends ServerComponent {
+
+  @CheckForNull
+  E getByKey(K key, DbSession session);
+
+  E getNonNullByKey(K key, DbSession session);
+
+  E update(E item, DbSession session);
+
+  List<E> update(List<E> items, DbSession session);
+
+  E insert(E item, DbSession session);
+
+  List<E> insert(List<E> items, DbSession session);
+
+  void delete(E item, DbSession session);
+
+  void delete(Collection<E> items, DbSession session);
+
+  void deleteByKey(K key, DbSession session);
+
+  Iterable<K> keysOfRowsUpdatedAfter(long timestamp, DbSession session);
+
+}
index 9e4735c4e26bf0e6ccf3f6a75adb0abd23c4d4eb..123ae3142c900f67c7619ae39bacbcf6127c250b 100644 (file)
  */
 package org.sonar.server.rule2;
 
+import org.apache.commons.lang.StringUtils;
 import org.sonar.api.ServerComponent;
 import org.sonar.api.rule.RuleKey;
 import org.sonar.core.permission.GlobalPermissions;
 import org.sonar.core.persistence.DbSession;
 import org.sonar.core.rule.RuleDto;
 import org.sonar.server.db.DbClient;
-import org.sonar.server.exceptions.NotFoundException;
 import org.sonar.server.rule2.index.RuleIndex;
 import org.sonar.server.rule2.index.RuleNormalizer;
 import org.sonar.server.rule2.index.RuleQuery;
@@ -34,6 +34,8 @@ import org.sonar.server.search.QueryOptions;
 import org.sonar.server.user.UserSession;
 
 import javax.annotation.CheckForNull;
+import javax.annotation.Nullable;
+import java.util.Date;
 import java.util.Set;
 
 /**
@@ -77,10 +79,7 @@ public class RuleService implements ServerComponent {
 
     DbSession dbSession = db.openSession(false);
     try {
-      RuleDto rule = db.ruleDao().getByKey(ruleKey, dbSession);
-      if (rule == null) {
-        throw new NotFoundException(String.format("Rule %s not found", ruleKey));
-      }
+      RuleDto rule = db.ruleDao().getNonNullByKey(ruleKey, dbSession);
       boolean changed = RuleTagHelper.applyTags(rule, tags);
       if (changed) {
         db.ruleDao().update(rule, dbSession);
@@ -91,6 +90,35 @@ public class RuleService implements ServerComponent {
     }
   }
 
+  /**
+   * Extend rule description by adding a note.
+   * @param ruleKey the required key
+   * @param markdownNote markdown text. <code>null</code> to remove current note.
+   */
+  public void setNote(RuleKey ruleKey, @Nullable String markdownNote) {
+    UserSession userSession = UserSession.get();
+    checkAdminPermission(userSession);
+    DbSession dbSession = db.openSession(false);
+    try {
+      RuleDto rule = db.ruleDao().getNonNullByKey(ruleKey, dbSession);
+      if (StringUtils.isBlank(markdownNote)) {
+        rule.setNoteData(null);
+        rule.setNoteCreatedAt(null);
+        rule.setNoteUpdatedAt(null);
+        rule.setNoteUserLogin(null);
+      } else {
+        rule.setNoteData(markdownNote);
+        rule.setNoteCreatedAt(rule.getNoteCreatedAt() != null ? rule.getNoteCreatedAt() : new Date());
+        rule.setNoteUpdatedAt(new Date());
+        rule.setNoteUserLogin(userSession.login());
+      }
+      db.ruleDao().update(rule, dbSession);
+      dbSession.commit();
+    } finally {
+      dbSession.close();
+    }
+  }
+
   private void checkAdminPermission(UserSession userSession) {
     userSession.checkGlobalPermission(GlobalPermissions.QUALITY_PROFILE_ADMIN);
   }
index 6546a6d59c6baebf17fa528aee26f400dd805c83..15176dbf1a9a47e47b3a849c8361e2b3c8fffbef 100644 (file)
@@ -34,7 +34,7 @@ import org.elasticsearch.index.query.QueryBuilders;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 import org.sonar.core.cluster.WorkQueue;
-import org.sonar.core.db.Dto;
+import org.sonar.core.persistence.Dto;
 import org.sonar.server.es.ESNode;
 
 import java.io.IOException;
index fe72e8d11a93183070fd49ed64abf7da9aec28f2..fa30e98922d26ca65fd8493c11dfb06da5b03bb7 100644 (file)
@@ -23,7 +23,7 @@ import org.elasticsearch.action.update.UpdateRequest;
 import org.elasticsearch.common.xcontent.XContentBuilder;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
-import org.sonar.core.db.Dto;
+import org.sonar.core.persistence.Dto;
 import org.sonar.server.db.DbClient;
 
 import java.io.IOException;
index 972339c295d6b5f6898426d20d45f22905312c6e..31cd1a92fa7de7702a91343f5ba38d80dfdc2d79 100644 (file)
@@ -25,7 +25,7 @@ import org.elasticsearch.index.query.FilterBuilder;
 import org.elasticsearch.index.query.QueryBuilder;
 import org.picocontainer.Startable;
 import org.sonar.api.ServerComponent;
-import org.sonar.core.db.Dto;
+import org.sonar.core.persistence.Dto;
 
 import javax.annotation.CheckForNull;
 import java.io.Serializable;
index af3d7d8fd870fab14e234e2d426e2693f014ea4b..42c5f2a6979ac603a34965e1e94f6d0e5e94a160 100644 (file)
@@ -24,7 +24,7 @@ import org.elasticsearch.client.Client;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 import org.sonar.core.cluster.WorkQueue;
-import org.sonar.core.db.Dto;
+import org.sonar.core.persistence.Dto;
 
 import java.io.Serializable;
 
index c4bf640e7360b32b5594bea2294873cfd72a1c01..1c486ac627802f8db89f70b9ee8691858c715c51 100644 (file)
@@ -19,7 +19,7 @@
  */
 package org.sonar.server.search.action;
 
-import org.sonar.core.db.Dto;
+import org.sonar.core.persistence.Dto;
 
 public class DtoIndexAction<E extends Dto> extends IndexAction {
 
diff --git a/sonar-server/src/test/java/org/sonar/server/db/BaseDaoTest.java b/sonar-server/src/test/java/org/sonar/server/db/BaseDaoTest.java
new file mode 100644 (file)
index 0000000..d3af1d5
--- /dev/null
@@ -0,0 +1,68 @@
+/*
+ * 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.junit.Test;
+import org.sonar.core.persistence.Dto;
+import org.sonar.core.persistence.DbSession;
+import org.sonar.server.exceptions.NotFoundException;
+
+import static org.fest.assertions.Assertions.assertThat;
+import static org.fest.assertions.Fail.fail;
+import static org.mockito.Matchers.any;
+import static org.mockito.Matchers.anyString;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.when;
+
+public class BaseDaoTest {
+
+  DbSession dbSession = mock(DbSession.class);
+
+  @Test
+  public void getNonNullByKey() throws Exception {
+    BaseDao dao = mock(BaseDao.class);
+    FakeDto dto = new FakeDto("ki");
+    when(dao.doGetByKey("ki", dbSession)).thenReturn(dto);
+    when(dao.getNonNullByKey(anyString(), any(DbSession.class))).thenCallRealMethod();
+
+    assertThat(dao.getNonNullByKey("ki", dbSession)).isSameAs(dto);
+
+    try {
+      dao.getNonNullByKey("unknown", dbSession);
+      fail();
+    } catch (NotFoundException e) {
+      assertThat(e).hasMessage("Key 'unknown' not found");
+    }
+  }
+
+
+  static class FakeDto extends Dto<String> {
+    private final String key;
+
+    public FakeDto(String key) {
+      this.key = key;
+    }
+
+    @Override
+    public String getKey() {
+      return key;
+    }
+  }
+}
diff --git a/sonar-server/src/test/java/org/sonar/server/rule2/RuleDataMediumTest.java b/sonar-server/src/test/java/org/sonar/server/rule2/RuleDataMediumTest.java
new file mode 100644 (file)
index 0000000..5bce314
--- /dev/null
@@ -0,0 +1,254 @@
+/*
+ * 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.ImmutableSet;
+import com.google.common.collect.Iterables;
+import org.junit.After;
+import org.junit.Before;
+import org.junit.ClassRule;
+import org.junit.Test;
+import org.sonar.api.rule.RuleKey;
+import org.sonar.api.rule.RuleStatus;
+import org.sonar.api.rule.Severity;
+import org.sonar.api.server.rule.RuleParamType;
+import org.sonar.check.Cardinality;
+import org.sonar.core.persistence.DbSession;
+import org.sonar.core.persistence.MyBatis;
+import org.sonar.core.rule.RuleDto;
+import org.sonar.core.rule.RuleParamDto;
+import org.sonar.server.rule2.index.RuleIndex;
+import org.sonar.server.rule2.persistence.RuleDao;
+import org.sonar.server.tester.ServerTester;
+
+import java.util.List;
+
+import static org.fest.assertions.Assertions.assertThat;
+
+/**
+ * Test persistence in db and indexation in es (--> integration of daos and indexes)
+ */
+public class RuleDataMediumTest {
+
+  @ClassRule
+  public static ServerTester tester = new ServerTester();
+
+  RuleDao dao = tester.get(RuleDao.class);
+  RuleIndex index = tester.get(RuleIndex.class);
+  DbSession dbSession;
+
+  @Before
+  public void before() {
+    tester.clearDataStores();
+    dbSession = tester.get(MyBatis.class).openSession(false);
+  }
+
+  @After
+  public void after() {
+    dbSession.close();
+  }
+
+  @Test
+  public void insert_in_db_and_index_in_es() throws InterruptedException {
+    // insert db
+    RuleKey ruleKey = RuleKey.of("javascript", "S001");
+    dao.insert(newRuleDto(ruleKey), dbSession);
+    dbSession.commit();
+
+    // verify that rule is persisted in db
+    RuleDto persistedDto = dao.getByKey(ruleKey, dbSession);
+    assertThat(persistedDto).isNotNull();
+    assertThat(persistedDto.getId()).isGreaterThanOrEqualTo(0);
+    assertThat(persistedDto.getRuleKey()).isEqualTo(ruleKey.rule());
+    assertThat(persistedDto.getLanguage()).isEqualTo("js");
+    assertThat(persistedDto.getTags()).containsOnly("tag1", "tag2");
+    assertThat(persistedDto.getSystemTags()).containsOnly("systag1", "systag2");
+    assertThat(persistedDto.getCreatedAt()).isNotNull();
+    assertThat(persistedDto.getUpdatedAt()).isNotNull();
+
+    // verify that rule is indexed in es
+    index.refresh();
+    Rule hit = index.getByKey(ruleKey);
+    assertThat(hit).isNotNull();
+    assertThat(hit.key().repository()).isEqualTo(ruleKey.repository());
+    assertThat(hit.key().rule()).isEqualTo(ruleKey.rule());
+    assertThat(hit.language()).isEqualTo("js");
+    assertThat(hit.name()).isEqualTo("Rule S001");
+    assertThat(hit.htmlDescription()).isEqualTo("Description S001");
+    assertThat(hit.status()).isEqualTo(RuleStatus.READY);
+    assertThat(hit.createdAt()).isNotNull();
+    assertThat(hit.updatedAt()).isNotNull();
+    assertThat(hit.internalKey()).isEqualTo("InternalKeyS001");
+    assertThat(hit.severity()).isEqualTo("INFO");
+    assertThat(hit.template()).isFalse();
+    assertThat(hit.tags()).containsOnly("tag1", "tag2");
+    assertThat(hit.systemTags()).containsOnly("systag1", "systag2");
+  }
+
+  @Test
+  public void insert_and_index_rule_parameters() {
+    // insert db
+    RuleKey ruleKey = RuleKey.of("javascript", "S001");
+    RuleDto ruleDto = newRuleDto(ruleKey);
+    dao.insert(ruleDto, dbSession);
+    dbSession.commit();
+
+    RuleParamDto minParamDto = new RuleParamDto()
+      .setName("min")
+      .setType(RuleParamType.INTEGER.type())
+      .setDefaultValue("2")
+      .setDescription("Minimum");
+    dao.addRuleParam(ruleDto, minParamDto, dbSession);
+    RuleParamDto maxParamDto = new RuleParamDto()
+      .setName("max")
+      .setType(RuleParamType.INTEGER.type())
+      .setDefaultValue("10")
+      .setDescription("Maximum");
+    dao.addRuleParam(ruleDto, maxParamDto, dbSession);
+    dbSession.commit();
+
+    //Verify that RuleDto has date from insertion
+    RuleDto theRule = dao.getByKey(ruleKey, dbSession);
+    assertThat(theRule.getCreatedAt()).isNotNull();
+    assertThat(theRule.getUpdatedAt()).isNotNull();
+
+    // verify that parameters are persisted in db
+    List<RuleParamDto> persistedDtos = dao.findRuleParamsByRuleKey(theRule.getKey(), dbSession);
+    assertThat(persistedDtos).hasSize(2);
+
+    // verify that parameters are indexed in es
+    index.refresh();
+    Rule hit = index.getByKey(ruleKey);
+    assertThat(hit).isNotNull();
+    assertThat(hit.key()).isNotNull();
+
+    RuleService service = tester.get(RuleService.class);
+    Rule rule = service.getByKey(ruleKey);
+
+    assertThat(rule.params()).hasSize(2);
+    assertThat(Iterables.getLast(rule.params(), null).key()).isEqualTo("max");
+  }
+
+  @Test
+  public void insert_and_update_rule() {
+    // insert db
+    RuleKey ruleKey = RuleKey.of("javascript", "S001");
+    RuleDto ruleDto = newRuleDto(ruleKey)
+      .setTags(ImmutableSet.of("hello"))
+      .setName("first name");
+    dao.insert(ruleDto, dbSession);
+    dbSession.commit();
+
+    // verify that parameters are indexed in es
+    index.refresh();
+    Rule hit = index.getByKey(ruleKey);
+    assertThat(hit.tags()).containsExactly("hello");
+    assertThat(hit.name()).isEqualTo("first name");
+
+    //Update in DB
+    ruleDto.setTags(ImmutableSet.of("world"))
+      .setName("second name");
+    dao.update(ruleDto, dbSession);
+    dbSession.commit();
+
+    // verify that parameters are updated in es
+    index.refresh();
+    hit = index.getByKey(ruleKey);
+    assertThat(hit.tags()).containsExactly("world");
+    assertThat(hit.name()).isEqualTo("second name");
+  }
+
+  @Test
+  public void insert_and_update_rule_param() {
+
+    // insert db
+    RuleKey ruleKey = RuleKey.of("javascript", "S001");
+    RuleDto ruleDto = newRuleDto(ruleKey)
+      .setTags(ImmutableSet.of("hello"))
+      .setName("first name");
+    dao.insert(ruleDto, dbSession);
+    dbSession.commit();
+
+    RuleParamDto minParamDto = new RuleParamDto()
+      .setName("min")
+      .setType(RuleParamType.INTEGER.type())
+      .setDefaultValue("2")
+      .setDescription("Minimum");
+    dao.addRuleParam(ruleDto, minParamDto, dbSession);
+
+    RuleParamDto maxParamDto = new RuleParamDto()
+      .setName("max")
+      .setType(RuleParamType.INTEGER.type())
+      .setDefaultValue("10")
+      .setDescription("Maximum");
+    dao.addRuleParam(ruleDto, maxParamDto, dbSession);
+    dbSession.commit();
+
+    // verify that parameters are indexed in es
+    index.refresh();
+    Rule hit = index.getByKey(ruleKey);
+    assertThat(hit.params()).hasSize(2);
+
+    RuleParam param = hit.params().get(0);
+    assertThat(param.key()).isEqualTo("min");
+    assertThat(param.defaultValue()).isEqualTo("2");
+    assertThat(param.description()).isEqualTo("Minimum");
+
+
+    //Update in DB
+    minParamDto
+      .setDefaultValue("0.5")
+      .setDescription("new description");
+    dao.updateRuleParam(ruleDto, minParamDto, dbSession);
+    dbSession.commit();
+
+    // verify that parameters are updated in es
+    index.refresh();
+    hit = index.getByKey(ruleKey);
+    assertThat(hit.params()).hasSize(2);
+
+    param = hit.params().get(0);
+    assertThat(param.key()).isEqualTo("min");
+    assertThat(param.defaultValue()).isEqualTo("0.5");
+    assertThat(param.description()).isEqualTo("new description");
+  }
+
+  private RuleDto newRuleDto(RuleKey ruleKey) {
+    return new RuleDto()
+      .setRuleKey(ruleKey.rule())
+      .setRepositoryKey(ruleKey.repository())
+      .setName("Rule " + ruleKey.rule())
+      .setDescription("Description " + ruleKey.rule())
+      .setStatus(RuleStatus.READY.toString())
+      .setConfigKey("InternalKey" + ruleKey.rule())
+      .setSeverity(Severity.INFO)
+      .setCardinality(Cardinality.SINGLE)
+      .setLanguage("js")
+      .setTags(ImmutableSet.of("tag1", "tag2"))
+      .setSystemTags(ImmutableSet.of("systag1", "systag2"))
+      .setRemediationFunction("linear")
+      .setDefaultRemediationFunction("linear_offset")
+      .setRemediationCoefficient("1h")
+      .setDefaultRemediationCoefficient("5d")
+      .setRemediationOffset("5min")
+      .setDefaultRemediationOffset("10h")
+      .setEffortToFixDescription(ruleKey.repository() + "." + ruleKey.rule() + ".effortToFix");
+  }
+}
index 9202b27b22e83706359cc8775e1b8dae1e249271..5a781f8d45231ca3375223700acc21aebff0a334 100644 (file)
@@ -20,7 +20,6 @@
 package org.sonar.server.rule2;
 
 import com.google.common.collect.ImmutableSet;
-import com.google.common.collect.Iterables;
 import com.google.common.collect.Sets;
 import org.junit.After;
 import org.junit.Before;
@@ -29,13 +28,11 @@ import org.junit.Test;
 import org.sonar.api.rule.RuleKey;
 import org.sonar.api.rule.RuleStatus;
 import org.sonar.api.rule.Severity;
-import org.sonar.api.server.rule.RuleParamType;
 import org.sonar.check.Cardinality;
 import org.sonar.core.permission.GlobalPermissions;
 import org.sonar.core.persistence.DbSession;
 import org.sonar.core.persistence.MyBatis;
 import org.sonar.core.rule.RuleDto;
-import org.sonar.core.rule.RuleParamDto;
 import org.sonar.server.exceptions.ForbiddenException;
 import org.sonar.server.exceptions.NotFoundException;
 import org.sonar.server.rule2.index.RuleIndex;
@@ -44,7 +41,6 @@ import org.sonar.server.tester.ServerTester;
 import org.sonar.server.user.MockUserSession;
 
 import java.util.Collections;
-import java.util.List;
 import java.util.Set;
 
 import static org.fest.assertions.Assertions.assertThat;
@@ -55,7 +51,6 @@ public class RuleServiceMediumTest {
   @ClassRule
   public static ServerTester tester = new ServerTester();
 
-  MyBatis myBatis = tester.get(MyBatis.class);
   RuleDao dao = tester.get(RuleDao.class);
   RuleIndex index = tester.get(RuleIndex.class);
   RuleService service = tester.get(RuleService.class);
@@ -64,7 +59,7 @@ public class RuleServiceMediumTest {
   @Before
   public void before() {
     tester.clearDataStores();
-    dbSession = myBatis.openSession(false);
+    dbSession = tester.get(MyBatis.class).openSession(false);
   }
 
   @After
@@ -72,172 +67,6 @@ public class RuleServiceMediumTest {
     dbSession.close();
   }
 
-  @Test
-  public void insert_in_db_and_index_in_es() throws InterruptedException {
-    // insert db
-    RuleKey ruleKey = RuleKey.of("javascript", "S001");
-    dao.insert(newRuleDto(ruleKey), dbSession);
-    dbSession.commit();
-
-    // verify that rule is persisted in db
-    RuleDto persistedDto = dao.getByKey(ruleKey, dbSession);
-    assertThat(persistedDto).isNotNull();
-    assertThat(persistedDto.getId()).isGreaterThanOrEqualTo(0);
-    assertThat(persistedDto.getRuleKey()).isEqualTo(ruleKey.rule());
-    assertThat(persistedDto.getLanguage()).isEqualTo("js");
-    assertThat(persistedDto.getTags()).containsOnly("tag1", "tag2");
-    assertThat(persistedDto.getSystemTags()).containsOnly("systag1", "systag2");
-    assertThat(persistedDto.getCreatedAt()).isNotNull();
-    assertThat(persistedDto.getUpdatedAt()).isNotNull();
-
-    // verify that rule is indexed in es
-    index.refresh();
-    Rule hit = index.getByKey(ruleKey);
-    assertThat(hit).isNotNull();
-    assertThat(hit.key().repository()).isEqualTo(ruleKey.repository());
-    assertThat(hit.key().rule()).isEqualTo(ruleKey.rule());
-    assertThat(hit.language()).isEqualTo("js");
-    assertThat(hit.name()).isEqualTo("Rule S001");
-    assertThat(hit.htmlDescription()).isEqualTo("Description S001");
-    assertThat(hit.status()).isEqualTo(RuleStatus.READY);
-    assertThat(hit.createdAt()).isNotNull();
-    assertThat(hit.updatedAt()).isNotNull();
-    assertThat(hit.internalKey()).isEqualTo("InternalKeyS001");
-    assertThat(hit.severity()).isEqualTo("INFO");
-    assertThat(hit.template()).isFalse();
-    assertThat(hit.tags()).containsOnly("tag1", "tag2");
-    assertThat(hit.systemTags()).containsOnly("systag1", "systag2");
-  }
-
-  @Test
-  public void insert_and_index_rule_parameters() {
-    // insert db
-    RuleKey ruleKey = RuleKey.of("javascript", "S001");
-    RuleDto ruleDto = newRuleDto(ruleKey);
-    dao.insert(ruleDto, dbSession);
-    dbSession.commit();
-
-    RuleParamDto minParamDto = new RuleParamDto()
-      .setName("min")
-      .setType(RuleParamType.INTEGER.type())
-      .setDefaultValue("2")
-      .setDescription("Minimum");
-    dao.addRuleParam(ruleDto, minParamDto, dbSession);
-    RuleParamDto maxParamDto = new RuleParamDto()
-      .setName("max")
-      .setType(RuleParamType.INTEGER.type())
-      .setDefaultValue("10")
-      .setDescription("Maximum");
-    dao.addRuleParam(ruleDto, maxParamDto, dbSession);
-    dbSession.commit();
-
-    //Verify that RuleDto has date from insertion
-    RuleDto theRule = dao.getByKey(ruleKey, dbSession);
-    assertThat(theRule.getCreatedAt()).isNotNull();
-    assertThat(theRule.getUpdatedAt()).isNotNull();
-
-    // verify that parameters are persisted in db
-    List<RuleParamDto> persistedDtos = dao.findRuleParamsByRuleKey(theRule.getKey(), dbSession);
-    assertThat(persistedDtos).hasSize(2);
-
-    // verify that parameters are indexed in es
-    index.refresh();
-    Rule hit = index.getByKey(ruleKey);
-    assertThat(hit).isNotNull();
-    assertThat(hit.key()).isNotNull();
-
-    RuleService service = tester.get(RuleService.class);
-    Rule rule = service.getByKey(ruleKey);
-
-    assertThat(rule.params()).hasSize(2);
-    assertThat(Iterables.getLast(rule.params(), null).key()).isEqualTo("max");
-  }
-
-  @Test
-  public void insert_and_update_rule() {
-
-    // insert db
-    RuleKey ruleKey = RuleKey.of("javascript", "S001");
-    RuleDto ruleDto = newRuleDto(ruleKey)
-      .setTags(ImmutableSet.of("hello"))
-      .setName("first name");
-    dao.insert(ruleDto, dbSession);
-    dbSession.commit();
-
-    // verify that parameters are indexed in es
-    index.refresh();
-    Rule hit = index.getByKey(ruleKey);
-    assertThat(hit.tags()).containsExactly("hello");
-    assertThat(hit.name()).isEqualTo("first name");
-
-    //Update in DB
-    ruleDto.setTags(ImmutableSet.of("world"))
-      .setName("second name");
-    dao.update(ruleDto, dbSession);
-    dbSession.commit();
-
-    // verify that parameters are updated in es
-    index.refresh();
-    hit = index.getByKey(ruleKey);
-    assertThat(hit.tags()).containsExactly("world");
-    assertThat(hit.name()).isEqualTo("second name");
-  }
-
-  @Test
-  public void insert_and_update_rule_param() {
-
-    // insert db
-    RuleKey ruleKey = RuleKey.of("javascript", "S001");
-    RuleDto ruleDto = newRuleDto(ruleKey)
-      .setTags(ImmutableSet.of("hello"))
-      .setName("first name");
-    dao.insert(ruleDto, dbSession);
-    dbSession.commit();
-
-    RuleParamDto minParamDto = new RuleParamDto()
-      .setName("min")
-      .setType(RuleParamType.INTEGER.type())
-      .setDefaultValue("2")
-      .setDescription("Minimum");
-    dao.addRuleParam(ruleDto, minParamDto, dbSession);
-
-    RuleParamDto maxParamDto = new RuleParamDto()
-      .setName("max")
-      .setType(RuleParamType.INTEGER.type())
-      .setDefaultValue("10")
-      .setDescription("Maximum");
-    dao.addRuleParam(ruleDto, maxParamDto, dbSession);
-    dbSession.commit();
-
-    // verify that parameters are indexed in es
-    index.refresh();
-    Rule hit = index.getByKey(ruleKey);
-    assertThat(hit.params()).hasSize(2);
-
-    RuleParam param = hit.params().get(0);
-    assertThat(param.key()).isEqualTo("min");
-    assertThat(param.defaultValue()).isEqualTo("2");
-    assertThat(param.description()).isEqualTo("Minimum");
-
-
-    //Update in DB
-    minParamDto
-      .setDefaultValue("0.5")
-      .setDescription("new description");
-    dao.updateRuleParam(ruleDto, minParamDto, dbSession);
-    dbSession.commit();
-
-    // verify that parameters are updated in es
-    index.refresh();
-    hit = index.getByKey(ruleKey);
-    assertThat(hit.params()).hasSize(2);
-
-    param = hit.params().get(0);
-    assertThat(param.key()).isEqualTo("min");
-    assertThat(param.defaultValue()).isEqualTo("0.5");
-    assertThat(param.description()).isEqualTo("new description");
-  }
-
   @Test
   public void setTags() throws InterruptedException {
     MockUserSession.set().setGlobalPermissions(GlobalPermissions.QUALITY_PROFILE_ADMIN);
@@ -247,8 +76,7 @@ public class RuleServiceMediumTest {
     dao.insert(newRuleDto(rule1)
         .setTags(Sets.newHashSet("security"))
         .setSystemTags(Collections.<String>emptySet()),
-      dbSession
-    );
+      dbSession);
 
     RuleKey rule2 = RuleKey.of("java", "S001");
     dao.insert(newRuleDto(rule2)
@@ -273,7 +101,7 @@ public class RuleServiceMediumTest {
       service.setTags(RuleKey.of("java", "S001"), Sets.newHashSet("bug", "security"));
       fail();
     } catch (NotFoundException e) {
-      assertThat(e).hasMessage("Rule java:S001 not found");
+      assertThat(e).hasMessage("Key 'java:S001' not found");
     }
   }
 
@@ -288,6 +116,49 @@ public class RuleServiceMediumTest {
     }
   }
 
+  @Test
+  public void setNote() throws Exception {
+    MockUserSession.set().setGlobalPermissions(GlobalPermissions.QUALITY_PROFILE_ADMIN).setLogin("marius");
+    RuleKey ruleKey = RuleKey.of("javascript", "S001");
+    dao.insert(newRuleDto(ruleKey), dbSession);
+    dbSession.commit();
+
+    // 1. CREATE NOTE
+    service.setNote(ruleKey, "my *note*");
+
+    // verify db
+    RuleDto dto = dao.getNonNullByKey(ruleKey, dbSession);
+    assertThat(dto.getNoteData()).isEqualTo("my *note*");
+    assertThat(dto.getNoteCreatedAt()).isNotNull();
+    assertThat(dto.getNoteUpdatedAt()).isNotNull();
+    assertThat(dto.getNoteUserLogin()).isEqualTo("marius");
+
+    // verify es
+    index.refresh();
+    Rule rule = index.getByKey(ruleKey);
+    // TODO
+//    assertThat(rule.getNote()).isEqualTo("my *note*");
+//    assertThat(rule.getNoteCreatedAt()).isNotNull();
+//    assertThat(rule.getNoteUpdatedAt()).isNotNull();
+//    assertThat(rule.getNoteUserLogin()).isEqualTo("marius");
+
+    // 2. DELETE NOTE
+    service.setNote(ruleKey, null);
+    dto = dao.getNonNullByKey(ruleKey, dbSession);
+    assertThat(dto.getNoteData()).isNull();
+    assertThat(dto.getNoteCreatedAt()).isNull();
+    assertThat(dto.getNoteUpdatedAt()).isNull();
+    assertThat(dto.getNoteUserLogin()).isNull();
+    index.refresh();
+    rule = index.getByKey(ruleKey);
+    // TODO
+    //    assertThat(rule.getNote()).isNull();
+//    assertThat(rule.getNoteCreatedAt()).isNull();
+//    assertThat(rule.getNoteUpdatedAt()).isNull();
+//    assertThat(rule.getNoteUserLogin()).isNull();
+
+  }
+
   private RuleDto newRuleDto(RuleKey ruleKey) {
     return new RuleDto()
       .setRuleKey(ruleKey.rule())