]> source.dussan.org Git - sonarqube.git/commitdiff
SONAR-5329 - Added Loggable interface and updated LogDao & tests
authorStephane Gamard <stephane.gamard@searchbox.com>
Tue, 10 Jun 2014 13:31:55 +0000 (15:31 +0200)
committerStephane Gamard <stephane.gamard@searchbox.com>
Tue, 10 Jun 2014 14:21:21 +0000 (16:21 +0200)
16 files changed:
sonar-core/src/main/java/org/sonar/core/log/Activity.java [deleted file]
sonar-core/src/main/java/org/sonar/core/log/Log.java
sonar-core/src/main/java/org/sonar/core/log/Loggable.java [new file with mode: 0644]
sonar-core/src/main/java/org/sonar/core/log/db/LogDto.java
sonar-core/src/main/java/org/sonar/core/log/db/LogKey.java
sonar-core/src/main/resources/org/sonar/core/log/db/LogMapper.xml
sonar-core/src/main/resources/org/sonar/core/persistence/schema-h2.ddl
sonar-server/src/main/java/org/sonar/server/log/LogService.java
sonar-server/src/main/java/org/sonar/server/log/index/LogDoc.java
sonar-server/src/main/java/org/sonar/server/log/index/LogNormalizer.java
sonar-server/src/main/java/org/sonar/server/qualityprofile/ActiveRuleChange.java
sonar-server/src/main/java/org/sonar/server/qualityprofile/RuleActivator.java
sonar-server/src/test/java/org/sonar/server/log/db/LogDaoTest.java
sonar-server/src/test/java/org/sonar/server/log/db/TestActivity.java [deleted file]
sonar-server/src/test/java/org/sonar/server/log/db/TestLog.java [new file with mode: 0644]
sonar-server/src/test/java/org/sonar/server/qualityprofile/ActiveRuleChangeLogTest.java [deleted file]

diff --git a/sonar-core/src/main/java/org/sonar/core/log/Activity.java b/sonar-core/src/main/java/org/sonar/core/log/Activity.java
deleted file mode 100644 (file)
index 0a0e06d..0000000
+++ /dev/null
@@ -1,37 +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.log;
-
-/**
- * @since 4.4
- */
-
-public abstract class Activity {
-
-  public Activity(){}
-
-  public String getName(){
-    return this.getClass().getSimpleName();
-  }
-
-  public abstract String serialize();
-
-  public abstract Activity deSerialize(String data);
-}
index 11802175886bb0ba7762382df84c7548f4a70920..2ca1e041b53b50254253f52335844d5355506b77 100644 (file)
  */
 package org.sonar.core.log;
 
-import java.util.Date;
+import java.util.Map;
 
 /**
  * @since 4.4
  */
 public interface Log {
 
-  Date time();
+  public static enum Type {
+    NONE, ACTIVE_RULE, SERVER
+  }
+
+  Long timestamp();
 
   String author();
 
   Long executionTime();
 
-  <K extends Activity> K getActivity();
+  Map<String, String> details();
 
 }
diff --git a/sonar-core/src/main/java/org/sonar/core/log/Loggable.java b/sonar-core/src/main/java/org/sonar/core/log/Loggable.java
new file mode 100644 (file)
index 0000000..8c29c28
--- /dev/null
@@ -0,0 +1,33 @@
+/*
+ * 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.log;
+
+import java.util.Map;
+
+/**
+ * @since 4.4
+ */
+public interface Loggable {
+
+  Map<String, String> getDetails();
+
+  Long getExecutionTime();
+
+}
index b9464b3c57c7e48ec7f43fae1b4a4684a87c7180..8466151089f89b8652e04d24f2b1461c5ad2b3c8 100644 (file)
@@ -21,61 +21,53 @@ package org.sonar.core.log.db;
 
 import org.apache.commons.lang.builder.ReflectionToStringBuilder;
 import org.apache.commons.lang.builder.ToStringStyle;
-import org.sonar.core.log.Activity;
+import org.sonar.api.utils.KeyValueFormat;
+import org.sonar.core.log.Log;
+import org.sonar.core.log.Loggable;
 import org.sonar.core.persistence.Dto;
 
-import java.util.Date;
-
 /**
  * @since 4.4
  */
 public final class LogDto extends Dto<LogKey> {
 
-
-  public static enum Payload {
-    TEST_ACTIVITY("org.sonar.server.log.db.TestActivity"),
-    ACTIVE_RULE_CHANGE("org.sonar.server.qualityprofile.ActiveRuleChange");
-
-    private final String clazz;
-
-    private Payload(String ActiveClass) {
-      clazz = ActiveClass;
-    }
-
-    public static Payload forClassName(String className){
-      for(Payload payload:Payload.values()){
-        if(payload.clazz.equals(className))
-          return payload;
-      }
-      return null;
-    }
-  }
-
-  private Date time;
-  private Payload payload;
+  private String message;
+  private Log.Type type;
   private String author;
 
   private Long executionTime;
+
   private String data;
 
   protected LogDto(){
-
   }
 
-  public LogDto(String user, Activity activity) {
-    this.time = new Date();
-    this.author = user;
-    this.payload = Payload.forClassName(activity.getClass().getCanonicalName());
-    this.data = activity.serialize();
+  @Override
+  public LogKey getKey() {
+    return LogKey.of(this.getCreatedAt(), type, author);
   }
 
   @Override
-  public LogKey getKey() {
-    return LogKey.of(time, payload, author);
+  public String toString() {
+    return ReflectionToStringBuilder.toString(this, ToStringStyle.MULTI_LINE_STYLE);
   }
 
-  public Date getTime() {
-    return time;
+  public Log.Type getType() {
+    return type;
+  }
+
+  public LogDto setType(Log.Type type) {
+    this.type = type;
+    return this;
+  }
+
+  public String getAuthor() {
+    return author;
+  }
+
+  public LogDto setAuthor(String author) {
+    this.author = author;
+    return this;
   }
 
   public Long getExecutionTime() {
@@ -87,22 +79,32 @@ public final class LogDto extends Dto<LogKey> {
     return this;
   }
 
-  public String getAuthor() {
-    return author;
+  public String getData() {
+    return data;
   }
 
-  public <K extends Activity> K getActivity() {
-    try {
-      Activity activity = ((Activity) Class.forName(this.payload.clazz, true, ClassLoader.getSystemClassLoader()).newInstance());
-      return (K) activity.deSerialize(this.data);
-    } catch (Exception e) {
-      throw new IllegalStateException("Could not read Activity from DB. '" + this.payload
-        + "' is most likely missing a public no-args ctor", e);
-    }
+  public LogDto setData(String data) {
+    this.data = data;
+    return this;
   }
 
-  @Override
-  public String toString() {
-    return ReflectionToStringBuilder.toString(this, ToStringStyle.MULTI_LINE_STYLE);
+  public String getMessage() {
+    return message;
+  }
+
+  public LogDto setMessage(String message) {
+    this.message = message;
+    return this;
+  }
+
+  public static LogDto createFor(String message) {
+    return new LogDto()
+      .setMessage(message);
+  }
+
+  public static LogDto createFor(Loggable loggable) {
+    return new LogDto()
+      .setData(KeyValueFormat.format(loggable.getDetails()))
+      .setExecutionTime(loggable.getExecutionTime());
   }
 }
index 24814e2ff92d9c92d3e29b63b0a7d7dfea56b76d..3077ce3b4991216149fa1270f599b2b977a5c59f 100644 (file)
@@ -20,6 +20,7 @@
 package org.sonar.core.log.db;
 
 import com.google.common.base.Preconditions;
+import org.sonar.core.log.Log;
 
 import java.io.Serializable;
 import java.util.Date;
@@ -29,24 +30,24 @@ import java.util.Date;
  */
 public class LogKey implements Serializable {
 
-  private Date time;
-  private LogDto.Payload payload;
+  private Date createdAt;
+  private Log.Type type;
   private String author;
 
-  public LogKey(Date time, LogDto.Payload payload, String author) {
-    this.time = time;
-    this.payload = payload;
+  public LogKey(Date createdAt, Log.Type type, String author) {
+    this.createdAt = createdAt;
+    this.type = type;
     this.author = author;
   }
 
   /**
    * Create a key. Parameters are NOT null.
    */
-  public static LogKey of(Date time, LogDto.Payload payload, String author) {
-    Preconditions.checkArgument(time != null, "Time must be set");
-    Preconditions.checkArgument(payload != null, "Payload must be set");
+  public static LogKey of(Date createdAt, Log.Type type, String author) {
+    Preconditions.checkArgument(createdAt != null, "Time must be set");
+    Preconditions.checkArgument(type != null, "Type must be set");
     Preconditions.checkArgument(author != null, "Author must be set");
-    return new LogKey(time, payload, author);
+    return new LogKey(createdAt, type, author);
   }
 
   /**
@@ -57,33 +58,39 @@ public class LogKey implements Serializable {
     String[] split = s.split(":");
     Preconditions.checkArgument(split.length == 3, "Invalid log key: " + s);
     return LogKey.of(new Date(Long.getLong(split[0])),
-      LogDto.Payload.valueOf(split[1]), split[2]);
+      Log.Type.valueOf(split[1]), split[2]);
   }
 
-  public Date getTime() {
-    return time;
+  public Date getCreatedAt() {
+    return createdAt;
   }
 
-  public LogKey setTime(Date time) {
-    this.time = time;
-    return this;
+  public void setCreatedAt(Date createdAt) {
+    this.createdAt = createdAt;
   }
 
-  public LogDto.Payload getPayload() {
-    return payload;
+  public String getAuthor() {
+    return author;
   }
 
-  public LogKey setPayload(LogDto.Payload payload) {
-    this.payload = payload;
+  public LogKey setAuthor(String author) {
+    this.author = author;
     return this;
   }
 
-  public String getAuthor() {
-    return author;
+  public Log.Type getType() {
+    return type;
   }
 
-  public LogKey setAuthor(String author) {
-    this.author = author;
+  public LogKey setType(Log.Type type) {
+    this.type = type;
     return this;
   }
+
+  @Override
+  public String toString() {
+    return this.createdAt.getTime() +
+      ":" + this.type +
+      ":" + this.getAuthor();
+  }
 }
index ad772e18fa5436d68590b1f728b95656130641c3..b4d0ca1cac9e1bfa89bdc70e071e3b6a65abc1de 100644 (file)
@@ -4,21 +4,22 @@
 <mapper namespace="org.sonar.core.log.db.LogMapper">
     <insert id="insert" parameterType="Log" useGeneratedKeys="false">
         insert into logs
-        (payload_field, created_at,execution_time_field,user_login,data_field)
-        values (#{payload}, #{time}, #{executionTime}, #{author}, #{data})
+      (created_at, log_type,execution_time_field,user_login,data_field, log_message)
+      values (#{createdAt}, #{type}, #{executionTime}, #{author}, #{data}, #{message})
     </insert>
 
     <select id="selectByKey" parameterType="map" resultType="Log">
       SELECT
-        l.payload_field as "payload",
-        l.created_at as "time",
+      l.created_at as "createdAt",
+      l.log_type as "type",
         l.execution_time_field as "executionTime",
         l.user_login as "author",
-        l.data_field as "data"
+      l.data_field as "data",
+      l.log_message as "message"
       FROM logs l
-      WHERE l.created_at=#{key.time}
-        AND l.payload_field=#{key.payload}
+      WHERE l.created_at=#{key.createdAt}
         AND l.user_login=#{key.author}
+      AND l.log_type=#{key.type}
 
     </select>
 </mapper>
index 34ea99f7bba65b06e7b61776851e77134c765e51..111378341b2f8ddb682b87faa9f312439e5e7a9d 100644 (file)
@@ -556,7 +556,8 @@ CREATE TABLE "LOGS" (
   "CREATED_AT" TIMESTAMP,
   "EXECUTION_TIME_FIELD" LONG,
   "USER_LOGIN" VARCHAR(30),
-  "PAYLOAD_FIELD" VARCHAR(250),
+  "LOG_TYPE" VARCHAR(250),
+  "LOG_MESSAGE" VARCHAR(250),
   "DATA_FIELD" CLOB(2147483647)
 );
 
index 7ff85d339479bf0a51fb25376932afb34da8331b..a397ce5fc6fcd144b9c701b487ddef84d085a51a 100644 (file)
@@ -19,7 +19,8 @@
  */
 package org.sonar.server.log;
 
-import org.sonar.core.log.Activity;
+import org.sonar.core.log.Log;
+import org.sonar.core.log.Loggable;
 import org.sonar.core.log.db.LogDto;
 import org.sonar.core.persistence.DbSession;
 import org.sonar.server.db.DbClient;
@@ -30,7 +31,7 @@ import java.util.List;
 /**
  * Log service is used to log Activity classes which represents an event to DB and Index.
  *
- * @see org.sonar.core.log.Activity
+ * @see org.sonar.core.log.Loggable
  * @since 4.4
  */
 public class LogService {
@@ -41,24 +42,33 @@ public class LogService {
     this.dbClient = dbClient;
   }
 
-  public void write(Activity activity) {
-    DbSession session = dbClient.openSession(false);
-    try {
-      this.write(session, activity);
-    } finally {
-      session.close();
-    }
+  private String getAuthor() {
+    return (UserSession.get().login() != null) ? UserSession.get().login() : "UNKNOWN";
+  }
+
+  private void save(DbSession session, LogDto log) {
+    dbClient.logDao().insert(session,
+      log.setAuthor(getAuthor()));
   }
 
-  public <K extends Activity> void write(DbSession session, K activity) {
-    dbClient.logDao().insert(session, new LogDto(
-      (UserSession.get().login() != null) ? UserSession.get().login() : "UNKNOWN",
-      activity));
+  public void write(DbSession session, Log.Type type, String message) {
+    this.write(session, type, message, null);
   }
 
-  public <K extends Activity> void write(DbSession session, List<K> activities) {
-    for(Activity activity:activities){
-      write(session, activity);
+  public void write(DbSession session, Log.Type type, String message, Long time) {
+    this.save(session, LogDto.createFor(message)
+      .setType(type)
+      .setExecutionTime(time));
+  }
+
+  public <L extends Loggable> void write(DbSession session, Log.Type type, List<L> logs) {
+    for (Loggable log : logs) {
+      this.write(session, type, log);
     }
   }
+
+  public <L extends Loggable> void write(DbSession session, Log.Type type, L log) {
+    this.save(session, LogDto.createFor(log)
+      .setType(type));
+  }
 }
index ec38ff5f9e54877d528925283bc8a00f60b65e0c..258ba8f0a5974fad5cadd88c6fe7be1df76df9a3 100644 (file)
  */
 package org.sonar.server.log.index;
 
-import org.sonar.core.log.Activity;
 import org.sonar.core.log.Log;
 import org.sonar.server.search.BaseDoc;
 
-import java.util.Date;
 import java.util.Map;
 
 /**
@@ -36,8 +34,8 @@ public class LogDoc extends BaseDoc implements Log {
   }
 
   @Override
-  public Date time() {
-    return this.getField(LogNormalizer.LogFields.TIME.field());
+  public Long timestamp() {
+    return this.getField(LogNormalizer.LogFields.TIMESTAMP.field());
   }
 
   @Override
@@ -51,7 +49,7 @@ public class LogDoc extends BaseDoc implements Log {
   }
 
   @Override
-  public <K extends Activity> K getActivity() {
-   return null;
+  public Map<String, String> details() {
+    return this.getField(LogNormalizer.LogFields.DETAILS.field());
   }
 }
index 0fca7905efdf371021ce9185a4ce0a5a20c0e0f7..9438d5892a500e4c0837df4c39242126220cf352 100644 (file)
@@ -21,6 +21,7 @@ package org.sonar.server.log.index;
 
 import com.google.common.collect.ImmutableList;
 import org.elasticsearch.action.update.UpdateRequest;
+import org.sonar.api.utils.KeyValueFormat;
 import org.sonar.core.log.db.LogDto;
 import org.sonar.core.log.db.LogKey;
 import org.sonar.core.persistence.DbSession;
@@ -48,9 +49,10 @@ public class LogNormalizer extends BaseNormalizer<LogDto, LogKey> {
   public static final class LogFields extends Indexable {
 
     public final static IndexField KEY = addSortableAndSearchable(IndexField.Type.STRING, "key");
-    public final static IndexField TIME = addSortable(IndexField.Type.DATE, "time");
+    public final static IndexField TIMESTAMP = addSortable(IndexField.Type.DATE, "timestamp");
     public final static IndexField EXECUTION = add(IndexField.Type.NUMERIC, "executionTime");
-    public final static IndexField AUTHOR = addSearchable(IndexField.Type.STRING, "executionTime");
+    public final static IndexField AUTHOR = addSearchable(IndexField.Type.STRING, "author");
+    public final static IndexField DETAILS = addSearchable(IndexField.Type.OBJECT, "details");
 
     public static Set<IndexField> ALL_FIELDS = getAllFields();
 
@@ -93,9 +95,8 @@ public class LogNormalizer extends BaseNormalizer<LogDto, LogKey> {
     logDoc.put(LogFields.KEY.field(), dto.getKey());
     logDoc.put(LogFields.AUTHOR.field(), dto.getAuthor());
     logDoc.put(LogFields.EXECUTION.field(), dto.getExecutionTime());
-    logDoc.put(LogFields.TIME.field(), dto.getTime());
-
-
+    logDoc.put(LogFields.TIMESTAMP.field(), dto.getCreatedAt());
+    logDoc.put(LogFields.DETAILS.field(), KeyValueFormat.parse(dto.getData()));
 
    /* Creating updateRequest */
     return ImmutableList.of(new UpdateRequest()
index 5180caf80bd10464d1c7044196e3baeb33fe0f98..68c3691300d3f3c6165f7c0b029459ea51e93833 100644 (file)
 package org.sonar.server.qualityprofile;
 
 import com.google.common.collect.Maps;
-import org.sonar.core.log.Activity;
+import org.sonar.core.log.Loggable;
 import org.sonar.core.qualityprofile.db.ActiveRuleKey;
-import org.yaml.snakeyaml.external.biz.base64Coder.Base64Coder;
 
 import javax.annotation.CheckForNull;
 import javax.annotation.Nullable;
-import java.io.ByteArrayInputStream;
-import java.io.ByteArrayOutputStream;
-import java.io.ObjectInputStream;
-import java.io.ObjectOutputStream;
-import java.io.Serializable;
 import java.util.Map;
 
-public class ActiveRuleChange extends Activity implements Serializable {
+public class ActiveRuleChange implements Loggable {
 
   static enum Type {
     ACTIVATED, DEACTIVATED, UPDATED
@@ -46,7 +40,7 @@ public class ActiveRuleChange extends Activity implements Serializable {
   private ActiveRule.Inheritance previousInheritance = null, inheritance = null;
   private Map<String, String> parameters = Maps.newHashMap();
 
-  public ActiveRuleChange(){
+  public ActiveRuleChange() {
     type = null;
     key = null;
   }
@@ -97,7 +91,7 @@ public class ActiveRuleChange extends Activity implements Serializable {
   }
 
   @CheckForNull
-  public ActiveRule.Inheritance getInheritance(){
+  public ActiveRule.Inheritance getInheritance() {
     return this.inheritance;
   }
 
@@ -111,31 +105,12 @@ public class ActiveRuleChange extends Activity implements Serializable {
   }
 
   @Override
-  public String serialize() {
-    //TODO do not use JDK's serialization
-    try {
-      ByteArrayOutputStream baos = new ByteArrayOutputStream();
-      ObjectOutputStream oos = new ObjectOutputStream(baos);
-      oos.writeObject(this);
-      oos.close();
-      return new String(Base64Coder.encode(baos.toByteArray()));
-    } catch (Exception e) {
-      throw new IllegalStateException("Could not serialize.",e);
-    }
+  public Map<String, String> getDetails() {
+    return null;
   }
 
   @Override
-  public ActiveRuleChange deSerialize(String data) {
-    //TODO do not use JDK's deserialization
-    try {
-    byte [] bytes = Base64Coder.decode(data);
-    ObjectInputStream ois = new ObjectInputStream(
-      new ByteArrayInputStream(bytes));
-      ActiveRuleChange o  = (ActiveRuleChange) ois.readObject();
-    ois.close();
-    return o;
-    } catch (Exception e) {
-      throw new IllegalStateException("Could not serialize.",e);
-    }
+  public Long getExecutionTime() {
+    return null;
   }
 }
index ebc507aa31f9261eb535ee85fb0b697ed467b7e9..7fe1b275f360900870b4211f030f558a71625d45 100644 (file)
@@ -27,9 +27,14 @@ import com.google.common.collect.Multimap;
 import org.apache.commons.lang.StringUtils;
 import org.sonar.api.ServerComponent;
 import org.sonar.api.server.rule.RuleParamType;
+import org.sonar.core.log.Log;
 import org.sonar.core.persistence.DbSession;
 import org.sonar.core.preview.PreviewCache;
-import org.sonar.core.qualityprofile.db.*;
+import org.sonar.core.qualityprofile.db.ActiveRuleDto;
+import org.sonar.core.qualityprofile.db.ActiveRuleKey;
+import org.sonar.core.qualityprofile.db.ActiveRuleParamDto;
+import org.sonar.core.qualityprofile.db.QualityProfileDto;
+import org.sonar.core.qualityprofile.db.QualityProfileKey;
 import org.sonar.core.rule.RuleDto;
 import org.sonar.core.rule.RuleParamDto;
 import org.sonar.server.db.DbClient;
@@ -46,7 +51,6 @@ import org.sonar.server.search.QueryOptions;
 import org.sonar.server.util.TypeValidations;
 
 import javax.annotation.Nullable;
-
 import java.util.Iterator;
 import java.util.List;
 import java.util.Map;
@@ -144,7 +148,7 @@ public class RuleActivator implements ServerComponent {
     changes.addAll(cascadeActivation(dbSession, activation));
 
     if (!changes.isEmpty()) {
-      log.write(dbSession, changes);
+      log.write(dbSession, Log.Type.ACTIVE_RULE, changes);
       dbSession.commit();
       previewCache.reportGlobalModification();
     }
@@ -298,7 +302,7 @@ public class RuleActivator implements ServerComponent {
     }
 
     if (!changes.isEmpty()) {
-      log.write(dbSession, changes);
+      log.write(dbSession, Log.Type.ACTIVE_RULE, changes);
       dbSession.commit();
       previewCache.reportGlobalModification();
     }
index 6eeb79ad1e3cd6c594cba0ed44213023fb7e2497..ac41444ceb2d36a746fc8977a012a83f5d2dcc86 100644 (file)
 package org.sonar.server.log.db;
 
 
+import com.google.common.collect.ImmutableMap;
 import org.junit.After;
 import org.junit.Before;
 import org.junit.Test;
+import org.sonar.api.utils.KeyValueFormat;
 import org.sonar.api.utils.System2;
+import org.sonar.core.log.Log;
+import org.sonar.core.log.Loggable;
 import org.sonar.core.log.db.LogDto;
 import org.sonar.core.persistence.AbstractDaoTestCase;
 import org.sonar.core.persistence.DbSession;
 
+import java.util.Map;
+
 import static org.fest.assertions.Assertions.assertThat;
 import static org.mockito.Mockito.mock;
 
-public class LogDaoTest extends AbstractDaoTestCase{
+public class LogDaoTest extends AbstractDaoTestCase {
 
 
   private LogDao dao;
@@ -46,24 +52,72 @@ public class LogDaoTest extends AbstractDaoTestCase{
   }
 
   @After
-  public void after(){
+  public void after() {
     session.close();
   }
 
   @Test
-  public void insert_log(){
+  public void fail_insert_missing_type() {
+    String testValue = "hello world";
+    LogDto log = LogDto.createFor(testValue);
+    try {
+      dao.insert(session, log);
+    } catch (IllegalArgumentException e) {
+      assertThat(e.getMessage()).isEqualTo("Type must be set");
+    }
+  }
 
-    TestActivity activity = new TestActivity("hello world");
+  @Test
+  public void fail_insert_missing_author() {
+    String testValue = "hello world";
+    LogDto log = LogDto.createFor(testValue)
+      .setType(Log.Type.ACTIVE_RULE);
+    try {
+      dao.insert(session, log);
+    } catch (IllegalArgumentException e) {
+      assertThat(e.getMessage()).isEqualTo("Type must be set");
+    }
+  }
 
-    LogDto log = new LogDto("SYSTEM_USER", activity);
+  @Test
+  public void insert_text_log() {
+    String testValue = "hello world";
+    LogDto log = LogDto.createFor(testValue)
+      .setType(Log.Type.ACTIVE_RULE)
+      .setAuthor("jUnit");
+    dao.insert(session, log);
+    LogDto newDto = dao.getByKey(session, log.getKey());
+    assertThat(newDto.getAuthor()).isEqualTo(log.getAuthor());
+    assertThat(newDto.getMessage()).isEqualTo(testValue);
+  }
+
+  @Test
+  public void insert_loggable_log() {
+    final String testKey = "message";
+    final String testValue = "hello world";
+    LogDto log = LogDto.createFor(new Loggable() {
+
+      @Override
+      public Map<String, String> getDetails() {
+        return ImmutableMap.of(testKey, testValue);
+      }
+
+      @Override
+      public Long getExecutionTime() {
+        return 12L;
+      }
+    })
+      .setAuthor("jUnit")
+      .setType(Log.Type.ACTIVE_RULE);
 
     dao.insert(session, log);
 
     LogDto newDto = dao.getByKey(session, log.getKey());
     assertThat(newDto.getAuthor()).isEqualTo(log.getAuthor());
 
-    TestActivity newActivity = newDto.getActivity();
-    assertThat(newActivity.test).isEqualTo("hello world");
-
+    assertThat(newDto.getData()).isNotNull();
+    Map<String, String> details = KeyValueFormat.parse(newDto.getData());
+    assertThat(details.get(testKey)).isEqualTo(testValue);
   }
+
 }
\ No newline at end of file
diff --git a/sonar-server/src/test/java/org/sonar/server/log/db/TestActivity.java b/sonar-server/src/test/java/org/sonar/server/log/db/TestActivity.java
deleted file mode 100644 (file)
index 7a9b000..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.server.log.db;
-
-import org.sonar.core.log.Activity;
-
-/**
- * @since 4.4
- */
-public class TestActivity extends Activity {
-
-  public String test;
-
-  public TestActivity(){}
-
-  public TestActivity(String test){
-    this.test = test;
-  }
-
-  @Override
-  public String serialize() {
-    return test;
-  }
-
-  @Override
-  public Activity deSerialize(String data) {
-    test = data;
-    return this;
-  }
-}
\ No newline at end of file
diff --git a/sonar-server/src/test/java/org/sonar/server/log/db/TestLog.java b/sonar-server/src/test/java/org/sonar/server/log/db/TestLog.java
new file mode 100644 (file)
index 0000000..38ee107
--- /dev/null
@@ -0,0 +1,50 @@
+/*
+ * 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.log.db;
+
+import org.sonar.core.log.Loggable;
+
+import java.util.Map;
+
+/**
+ * @since 4.4
+ */
+public class TestLog implements Loggable {
+
+  public String test;
+
+  public TestLog() {
+  }
+
+  public TestLog(String test) {
+    this.test = test;
+  }
+
+
+  @Override
+  public Map<String, String> getDetails() {
+    return null;
+  }
+
+  @Override
+  public Long getExecutionTime() {
+    return null;
+  }
+}
\ No newline at end of file
diff --git a/sonar-server/src/test/java/org/sonar/server/qualityprofile/ActiveRuleChangeLogTest.java b/sonar-server/src/test/java/org/sonar/server/qualityprofile/ActiveRuleChangeLogTest.java
deleted file mode 100644 (file)
index 6987fe7..0000000
+++ /dev/null
@@ -1,77 +0,0 @@
-/*
- * SonarQube, open source software quality management tool.
- * Copyright (C) 2008-2014 SonarSource
- * mailto:contact AT sonarsource DOT com
- *
- * SonarQube is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 3 of the License, or (at your option) any later version.
- *
- * SonarQube is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public License
- * along with this program; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
- */
-package org.sonar.server.qualityprofile;
-
-
-import org.junit.After;
-import org.junit.Before;
-import org.junit.Test;
-import org.sonar.api.rule.RuleKey;
-import org.sonar.api.utils.System2;
-import org.sonar.core.log.db.LogDto;
-import org.sonar.core.persistence.AbstractDaoTestCase;
-import org.sonar.core.persistence.DbSession;
-import org.sonar.core.qualityprofile.db.ActiveRuleKey;
-import org.sonar.core.qualityprofile.db.QualityProfileKey;
-import org.sonar.server.log.db.LogDao;
-
-import static org.fest.assertions.Assertions.assertThat;
-import static org.mockito.Mockito.mock;
-
-public class ActiveRuleChangeLogTest extends AbstractDaoTestCase {
-
-  private LogDao dao;
-  private DbSession session;
-  private System2 system2;
-
-  @Before
-  public void before() throws Exception {
-    this.session = getMyBatis().openSession(false);
-    this.system2 = mock(System2.class);
-    this.dao = new LogDao(system2);
-  }
-
-  @After
-  public void after() {
-    session.close();
-  }
-
-  @Test
-  public void insert_log() {
-
-    ActiveRuleKey ruleKey = ActiveRuleKey.of(
-      QualityProfileKey.of("name", "java"),
-      RuleKey.of("repository", "S001"));
-    ActiveRuleChange ruleChange = new ActiveRuleChange(ActiveRuleChange.Type.ACTIVATED, ruleKey)
-      .setInheritance(ActiveRule.Inheritance.INHERITED);
-
-    LogDto log = new LogDto("SYSTEM_USER", ruleChange);
-
-    dao.insert(session, log);
-
-    LogDto newDto = dao.getByKey(session, log.getKey());
-    assertThat(newDto.getAuthor()).isEqualTo(log.getAuthor());
-
-    ActiveRuleChange loggedRuleChange = newDto.getActivity();
-    assertThat(loggedRuleChange.getKey()).isEqualTo(ruleKey);
-    assertThat(ruleChange.getInheritance()).isEqualTo(ActiveRule.Inheritance.INHERITED);
-
-  }
-}
\ No newline at end of file