aboutsummaryrefslogtreecommitdiffstats
path: root/sonar-batch
diff options
context:
space:
mode:
authorJulien HENRY <julien.henry@sonarsource.com>2015-03-13 21:53:40 +0100
committerJulien Lancelot <julien.lancelot@sonarsource.com>2015-03-17 12:16:34 +0100
commit874614a2c6ba28185879abc248748ae087a23b46 (patch)
treeba9eb832765e8d3a7b3879e581fae2468facbe89 /sonar-batch
parent7485c34dead228336791067e3a6b03cbb3dcaaa2 (diff)
downloadsonarqube-874614a2c6ba28185879abc248748ae087a23b46.tar.gz
sonarqube-874614a2c6ba28185879abc248748ae087a23b46.zip
SONAR-6276 SONAR-6288 Feed events and version in analysis report and drop ability to create custom event on batch side
Diffstat (limited to 'sonar-batch')
-rw-r--r--sonar-batch/src/main/java/org/sonar/batch/bootstrap/BatchComponents.java2
-rw-r--r--sonar-batch/src/main/java/org/sonar/batch/deprecated/DeprecatedSensorContext.java20
-rw-r--r--sonar-batch/src/main/java/org/sonar/batch/deprecated/components/PastSnapshotFinderByPreviousVersion.java28
-rw-r--r--sonar-batch/src/main/java/org/sonar/batch/deprecated/decorator/DefaultDecoratorContext.java24
-rw-r--r--sonar-batch/src/main/java/org/sonar/batch/index/DefaultIndex.java47
-rw-r--r--sonar-batch/src/main/java/org/sonar/batch/index/EventPersister.java67
-rw-r--r--sonar-batch/src/main/java/org/sonar/batch/qualitygate/GenerateQualityGateEvents.java10
-rw-r--r--sonar-batch/src/main/java/org/sonar/batch/report/ComponentsPublisher.java46
-rw-r--r--sonar-batch/src/main/java/org/sonar/batch/report/EventCache.java67
-rw-r--r--sonar-batch/src/main/java/org/sonar/batch/rule/QProfileEventsDecorator.java33
-rw-r--r--sonar-batch/src/main/java/org/sonar/batch/scan/ModuleScanContainer.java4
-rw-r--r--sonar-batch/src/main/java/org/sonar/batch/scan/ProjectScanContainer.java9
-rw-r--r--sonar-batch/src/main/java/org/sonar/batch/scan/sensor/VersionEventsSensor.java70
-rw-r--r--sonar-batch/src/main/java/org/sonar/batch/scan/sensor/package-info.java23
-rw-r--r--sonar-batch/src/test/java/org/sonar/batch/deprecated/components/PastSnapshotFinderByPreviousVersionTest.java16
-rw-r--r--sonar-batch/src/test/java/org/sonar/batch/index/DefaultIndexTest.java2
-rw-r--r--sonar-batch/src/test/java/org/sonar/batch/index/ResourcePersisterTest.java2
-rw-r--r--sonar-batch/src/test/java/org/sonar/batch/qualitygate/GenerateQualityGateEventsTest.java37
-rw-r--r--sonar-batch/src/test/java/org/sonar/batch/report/ComponentsPublisherTest.java68
-rw-r--r--sonar-batch/src/test/java/org/sonar/batch/rule/QProfileEventsDecoratorTest.java45
-rw-r--r--sonar-batch/src/test/java/org/sonar/batch/scan/sensor/VersionEventsSensorTest.java119
21 files changed, 248 insertions, 491 deletions
diff --git a/sonar-batch/src/main/java/org/sonar/batch/bootstrap/BatchComponents.java b/sonar-batch/src/main/java/org/sonar/batch/bootstrap/BatchComponents.java
index 666a6d1a95e..0358d1428f6 100644
--- a/sonar-batch/src/main/java/org/sonar/batch/bootstrap/BatchComponents.java
+++ b/sonar-batch/src/main/java/org/sonar/batch/bootstrap/BatchComponents.java
@@ -27,7 +27,6 @@ import org.sonar.batch.maven.MavenProjectBootstrapper;
import org.sonar.batch.maven.MavenProjectBuilder;
import org.sonar.batch.maven.MavenProjectConverter;
import org.sonar.batch.scan.report.*;
-import org.sonar.batch.scan.sensor.VersionEventsSensor;
import org.sonar.batch.scm.ScmConfiguration;
import org.sonar.batch.scm.ScmSensor;
import org.sonar.batch.source.LinesSensor;
@@ -60,7 +59,6 @@ public class BatchComponents {
ScmSensor.class,
LinesSensor.class,
- VersionEventsSensor.class,
// Issues tracking
IssueTracking.class,
diff --git a/sonar-batch/src/main/java/org/sonar/batch/deprecated/DeprecatedSensorContext.java b/sonar-batch/src/main/java/org/sonar/batch/deprecated/DeprecatedSensorContext.java
index 0e421a788e0..2a70c13ac9d 100644
--- a/sonar-batch/src/main/java/org/sonar/batch/deprecated/DeprecatedSensorContext.java
+++ b/sonar-batch/src/main/java/org/sonar/batch/deprecated/DeprecatedSensorContext.java
@@ -23,7 +23,6 @@ import org.apache.commons.lang.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.sonar.api.batch.AnalysisMode;
-import org.sonar.api.batch.Event;
import org.sonar.api.batch.SensorContext;
import org.sonar.api.batch.SonarIndex;
import org.sonar.api.batch.fs.FileSystem;
@@ -43,12 +42,8 @@ import org.sonar.api.utils.SonarException;
import org.sonar.batch.sensor.DefaultSensorContext;
import org.sonar.batch.sensor.coverage.CoverageExclusions;
-import javax.annotation.Nullable;
-
import java.io.Serializable;
import java.util.Collection;
-import java.util.Date;
-import java.util.List;
import java.util.Set;
public class DeprecatedSensorContext extends DefaultSensorContext implements SensorContext {
@@ -234,21 +229,6 @@ public class DeprecatedSensorContext extends DefaultSensorContext implements Sen
// useless since 4.2.
}
- @Override
- public List<Event> getEvents(Resource resource) {
- return index.getEvents(resource);
- }
-
- @Override
- public Event createEvent(Resource resource, String name, String description, String category, @Nullable Date date) {
- return index.addEvent(resource, name, description, category, date);
- }
-
- @Override
- public void deleteEvent(Event event) {
- index.deleteEvent(event);
- }
-
private Resource resourceOrProject(Resource resource) {
if (resource == null) {
return project;
diff --git a/sonar-batch/src/main/java/org/sonar/batch/deprecated/components/PastSnapshotFinderByPreviousVersion.java b/sonar-batch/src/main/java/org/sonar/batch/deprecated/components/PastSnapshotFinderByPreviousVersion.java
index fcb0fce8ffb..5b71a2c457d 100644
--- a/sonar-batch/src/main/java/org/sonar/batch/deprecated/components/PastSnapshotFinderByPreviousVersion.java
+++ b/sonar-batch/src/main/java/org/sonar/batch/deprecated/components/PastSnapshotFinderByPreviousVersion.java
@@ -21,42 +21,38 @@ package org.sonar.batch.deprecated.components;
import org.sonar.api.BatchExtension;
import org.sonar.api.CoreProperties;
-import org.sonar.api.batch.Event;
import org.sonar.api.database.DatabaseSession;
import org.sonar.api.database.model.Snapshot;
import org.sonar.batch.components.PastSnapshot;
-
-import java.util.List;
+import org.sonar.core.event.db.EventMapper;
+import org.sonar.core.persistence.DbSession;
+import org.sonar.core.persistence.MyBatis;
import static org.sonar.api.utils.DateUtils.longToDate;
public class PastSnapshotFinderByPreviousVersion implements BatchExtension {
private final DatabaseSession session;
+ private final MyBatis mybatis;
- public PastSnapshotFinderByPreviousVersion(DatabaseSession session) {
+ public PastSnapshotFinderByPreviousVersion(DatabaseSession session, MyBatis mybatis) {
this.session = session;
+ this.mybatis = mybatis;
}
public PastSnapshot findByPreviousVersion(Snapshot projectSnapshot) {
String currentVersion = projectSnapshot.getVersion();
Integer resourceId = projectSnapshot.getResourceId();
+ Long snapshotId;
+ try (DbSession dbSession = mybatis.openSession(false)) {
+ snapshotId = dbSession.getMapper(EventMapper.class).findSnapshotIdOfPreviousVersion(resourceId, currentVersion);
+ }
- String hql = "select e from " + Event.class.getSimpleName() + " e " +
- " join e.resource component where e.name<>:version AND e.category='Version' AND component.id=:resourceId ORDER BY e.date DESC";
-
- List<Event> events = session.createQuery(hql)
- .setParameter("version", currentVersion)
- .setParameter("resourceId", resourceId)
- .setMaxResults(1)
- .getResultList();
-
- if (events.isEmpty()) {
+ if (snapshotId == null) {
return new PastSnapshot(CoreProperties.TIMEMACHINE_MODE_PREVIOUS_VERSION);
}
- Event previousVersionEvent = events.get(0);
- Snapshot snapshot = session.getSingleResult(Snapshot.class, "id", previousVersionEvent.getSnapshot().getId());
+ Snapshot snapshot = session.getSingleResult(Snapshot.class, "id", snapshotId.intValue());
return new PastSnapshot(CoreProperties.TIMEMACHINE_MODE_PREVIOUS_VERSION, longToDate(snapshot.getCreatedAtMs()), snapshot).setModeParameter(snapshot.getVersion());
}
diff --git a/sonar-batch/src/main/java/org/sonar/batch/deprecated/decorator/DefaultDecoratorContext.java b/sonar-batch/src/main/java/org/sonar/batch/deprecated/decorator/DefaultDecoratorContext.java
index 67bd33d7a29..47d75f4434d 100644
--- a/sonar-batch/src/main/java/org/sonar/batch/deprecated/decorator/DefaultDecoratorContext.java
+++ b/sonar-batch/src/main/java/org/sonar/batch/deprecated/decorator/DefaultDecoratorContext.java
@@ -23,16 +23,10 @@ import com.google.common.collect.ArrayListMultimap;
import com.google.common.collect.ListMultimap;
import com.google.common.collect.Lists;
import org.sonar.api.batch.DecoratorContext;
-import org.sonar.api.batch.Event;
import org.sonar.api.batch.SonarIndex;
import org.sonar.api.batch.sensor.duplication.internal.DefaultDuplication;
import org.sonar.api.design.Dependency;
-import org.sonar.api.measures.CoreMetrics;
-import org.sonar.api.measures.Measure;
-import org.sonar.api.measures.MeasuresFilter;
-import org.sonar.api.measures.MeasuresFilters;
-import org.sonar.api.measures.Metric;
-import org.sonar.api.measures.MetricFinder;
+import org.sonar.api.measures.*;
import org.sonar.api.resources.Project;
import org.sonar.api.resources.Resource;
import org.sonar.api.rules.Violation;
@@ -44,7 +38,6 @@ import org.sonar.batch.sensor.coverage.CoverageExclusions;
import java.util.Arrays;
import java.util.Collection;
-import java.util.Date;
import java.util.List;
import java.util.Set;
@@ -223,21 +216,6 @@ public class DefaultDecoratorContext implements DecoratorContext {
}
@Override
- public List<Event> getEvents() {
- return sonarIndex.getEvents(resource);
- }
-
- @Override
- public Event createEvent(String name, String description, String category, Date date) {
- return sonarIndex.addEvent(resource, name, description, category, date);
- }
-
- @Override
- public void deleteEvent(Event event) {
- sonarIndex.deleteEvent(event);
- }
-
- @Override
public DefaultDecoratorContext saveViolation(Violation violation, boolean force) {
if (violation.getResource() == null) {
violation.setResource(resource);
diff --git a/sonar-batch/src/main/java/org/sonar/batch/index/DefaultIndex.java b/sonar-batch/src/main/java/org/sonar/batch/index/DefaultIndex.java
index d2f26e4cecf..ff223b4b9f4 100644
--- a/sonar-batch/src/main/java/org/sonar/batch/index/DefaultIndex.java
+++ b/sonar-batch/src/main/java/org/sonar/batch/index/DefaultIndex.java
@@ -28,7 +28,6 @@ import org.apache.commons.lang.ObjectUtils;
import org.apache.commons.lang.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
-import org.sonar.api.batch.Event;
import org.sonar.api.batch.SonarIndex;
import org.sonar.api.batch.bootstrap.ProjectDefinition;
import org.sonar.api.batch.measure.Metric;
@@ -90,7 +89,6 @@ public class DefaultIndex extends SonarIndex {
private final MeasureCache measureCache;
private final ResourceKeyMigration migration;
private final DependencyPersister dependencyPersister;
- private final EventPersister eventPersister;
// caches
private Project currentProject;
private Map<Resource, Bucket> buckets = Maps.newLinkedHashMap();
@@ -101,11 +99,10 @@ public class DefaultIndex extends SonarIndex {
private ModuleIssues moduleIssues;
public DefaultIndex(ResourceCache resourceCache, DependencyPersister dependencyPersister,
- EventPersister eventPersister, ProjectTree projectTree, MetricFinder metricFinder,
+ ProjectTree projectTree, MetricFinder metricFinder,
ResourceKeyMigration migration, MeasureCache measureCache) {
this.resourceCache = resourceCache;
this.dependencyPersister = dependencyPersister;
- this.eventPersister = eventPersister;
this.projectTree = projectTree;
this.metricFinder = metricFinder;
this.migration = migration;
@@ -115,7 +112,6 @@ public class DefaultIndex extends SonarIndex {
public DefaultIndex(ResourceCache resourceCache, DependencyPersister dependencyPersister, ProjectTree projectTree, MetricFinder metricFinder, MeasureCache measureCache) {
this.resourceCache = resourceCache;
this.dependencyPersister = dependencyPersister;
- this.eventPersister = null;
this.projectTree = projectTree;
this.metricFinder = metricFinder;
this.migration = null;
@@ -407,47 +403,6 @@ public class DefaultIndex extends SonarIndex {
moduleIssues.initAndAddViolation(violation);
}
- //
- //
- //
- // EVENTS
- //
- //
- //
-
- @Override
- public List<Event> getEvents(Resource resource) {
- // currently events are not cached in memory
- Resource reload = getResource(resource);
- if (reload == null) {
- return Collections.emptyList();
- }
- if (eventPersister == null) {
- throw new UnsupportedOperationException("Event are not available in preview mode");
- }
- return eventPersister.getEvents(reload);
- }
-
- @Override
- public void deleteEvent(Event event) {
- if (eventPersister != null) {
- eventPersister.deleteEvent(event);
- }
- }
-
- @Override
- public Event addEvent(Resource resource, String name, String description, String category, @Nullable Date date) {
- Event event = new Event(name, description, category);
- if (date != null) {
- event.setDate(date);
- }
-
- if (eventPersister != null) {
- eventPersister.saveEvent(resource, event);
- }
- return null;
- }
-
@Override
public String getSource(Resource reference) {
Resource resource = getResource(reference);
diff --git a/sonar-batch/src/main/java/org/sonar/batch/index/EventPersister.java b/sonar-batch/src/main/java/org/sonar/batch/index/EventPersister.java
deleted file mode 100644
index 3b68e8cda48..00000000000
--- a/sonar-batch/src/main/java/org/sonar/batch/index/EventPersister.java
+++ /dev/null
@@ -1,67 +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.batch.index;
-
-import org.sonar.api.batch.Event;
-import org.sonar.api.database.DatabaseSession;
-import org.sonar.api.resources.Resource;
-import org.sonar.api.utils.System2;
-
-import java.util.Date;
-import java.util.List;
-
-import static com.google.common.base.Preconditions.checkState;
-
-public class EventPersister {
- private final System2 system2;
- private DatabaseSession session;
- private ResourceCache resourceCache;
-
- public EventPersister(DatabaseSession session, ResourceCache resourceCache, System2 system2) {
- this.session = session;
- this.resourceCache = resourceCache;
- this.system2 = system2;
- }
-
- public List<Event> getEvents(Resource resource) {
- return session.getResults(Event.class, "componentUuid", resource.getUuid());
- }
-
- public void deleteEvent(Event event) {
- session.removeWithoutFlush(event);
- session.commit();
- }
-
- public void saveEvent(Resource resource, Event event) {
- BatchResource batchResource = resourceCache.get(resource.getEffectiveKey());
- checkState(batchResource != null, "Unknown component: " + resource);
-
- event.setCreatedAt(new Date(system2.now()));
- if (event.getDate() == null) {
- event.setSnapshot(batchResource.snapshot());
- event.setComponentUuid(batchResource.resource().getUuid());
- } else {
- event.setComponentUuid(batchResource.resource().getUuid());
- }
-
- session.save(event);
- session.commit();
- }
-}
diff --git a/sonar-batch/src/main/java/org/sonar/batch/qualitygate/GenerateQualityGateEvents.java b/sonar-batch/src/main/java/org/sonar/batch/qualitygate/GenerateQualityGateEvents.java
index 824610b5d01..ee3f9f34a76 100644
--- a/sonar-batch/src/main/java/org/sonar/batch/qualitygate/GenerateQualityGateEvents.java
+++ b/sonar-batch/src/main/java/org/sonar/batch/qualitygate/GenerateQualityGateEvents.java
@@ -29,6 +29,8 @@ import org.sonar.api.notifications.NotificationManager;
import org.sonar.api.resources.Project;
import org.sonar.api.resources.Resource;
import org.sonar.api.resources.ResourceUtils;
+import org.sonar.batch.protocol.Constants.EventCategory;
+import org.sonar.batch.report.EventCache;
import java.util.List;
@@ -36,12 +38,14 @@ public class GenerateQualityGateEvents implements Decorator {
private final QualityGate qualityGate;
private final TimeMachine timeMachine;
- private NotificationManager notificationManager;
+ private final NotificationManager notificationManager;
+ private final EventCache eventCache;
- public GenerateQualityGateEvents(QualityGate qualityGate, TimeMachine timeMachine, NotificationManager notificationManager) {
+ public GenerateQualityGateEvents(QualityGate qualityGate, TimeMachine timeMachine, NotificationManager notificationManager, EventCache eventCache) {
this.qualityGate = qualityGate;
this.timeMachine = timeMachine;
this.notificationManager = notificationManager;
+ this.eventCache = eventCache;
}
@Override
@@ -122,6 +126,6 @@ public class GenerateQualityGateEvents implements Decorator {
}
private void createEvent(DecoratorContext context, String name, String description) {
- context.createEvent(name, description, Event.CATEGORY_ALERT, null);
+ eventCache.createEvent(context.getResource(), name, description, EventCategory.ALERT, null);
}
}
diff --git a/sonar-batch/src/main/java/org/sonar/batch/report/ComponentsPublisher.java b/sonar-batch/src/main/java/org/sonar/batch/report/ComponentsPublisher.java
index 4f93d6fbcaf..506a7f23765 100644
--- a/sonar-batch/src/main/java/org/sonar/batch/report/ComponentsPublisher.java
+++ b/sonar-batch/src/main/java/org/sonar/batch/report/ComponentsPublisher.java
@@ -30,9 +30,10 @@ import org.sonar.batch.index.BatchResource;
import org.sonar.batch.index.ResourceCache;
import org.sonar.batch.protocol.Constants;
import org.sonar.batch.protocol.Constants.ComponentLinkType;
-import org.sonar.batch.protocol.output.BatchReport;
+import org.sonar.batch.protocol.output.*;
+import org.sonar.batch.protocol.output.BatchReport.Component.Builder;
import org.sonar.batch.protocol.output.BatchReport.ComponentLink;
-import org.sonar.batch.protocol.output.BatchReportWriter;
+import org.sonar.batch.protocol.output.BatchReport.Event;
import javax.annotation.CheckForNull;
@@ -43,10 +44,12 @@ public class ComponentsPublisher implements ReportPublisher {
private final ResourceCache resourceCache;
private final ProjectReactor reactor;
+ private final EventCache eventCache;
- public ComponentsPublisher(ProjectReactor reactor, ResourceCache resourceCache) {
+ public ComponentsPublisher(ProjectReactor reactor, ResourceCache resourceCache, EventCache eventCache) {
this.reactor = reactor;
this.resourceCache = resourceCache;
+ this.eventCache = eventCache;
}
@Override
@@ -91,6 +94,38 @@ public class ComponentsPublisher implements ReportPublisher {
for (BatchResource child : batchResource.children()) {
builder.addChildRef(child.batchId());
}
+ writeLinks(r, builder);
+ writeVersion(r, builder);
+ writeEvents(batchResource, builder);
+ writer.writeComponent(builder.build());
+
+ for (BatchResource child : batchResource.children()) {
+ recursiveWriteComponent(child, writer);
+ }
+ }
+
+ private void writeEvents(BatchResource batchResource, Builder builder) {
+ if (isRealProjectOrModule(batchResource.resource())) {
+ for (Event event : eventCache.getEvents(batchResource.batchId())) {
+ builder.addEvent(event);
+ }
+ }
+ }
+
+ private void writeVersion(Resource r, BatchReport.Component.Builder builder) {
+ if (isRealProjectOrModule(r)) {
+ ProjectDefinition def = getProjectDefinition(reactor, r.getKey());
+ String version = getVersion(def);
+ builder.setVersion(version);
+ }
+ }
+
+ private String getVersion(ProjectDefinition def) {
+ String version = def.getVersion();
+ return StringUtils.isNotBlank(version) ? version : getVersion(def.getParent());
+ }
+
+ private void writeLinks(Resource r, BatchReport.Component.Builder builder) {
if (isRealProjectOrModule(r)) {
ProjectDefinition def = getProjectDefinition(reactor, r.getKey());
ComponentLink.Builder linkBuilder = ComponentLink.newBuilder();
@@ -101,11 +136,6 @@ public class ComponentsPublisher implements ReportPublisher {
writeProjectLink(builder, def, linkBuilder, CoreProperties.LINKS_SOURCES, ComponentLinkType.SCM);
writeProjectLink(builder, def, linkBuilder, CoreProperties.LINKS_SOURCES_DEV, ComponentLinkType.SCM_DEV);
}
- writer.writeComponent(builder.build());
-
- for (BatchResource child : batchResource.children()) {
- recursiveWriteComponent(child, writer);
- }
}
// Exclude views
diff --git a/sonar-batch/src/main/java/org/sonar/batch/report/EventCache.java b/sonar-batch/src/main/java/org/sonar/batch/report/EventCache.java
new file mode 100644
index 00000000000..2cb2814d2ee
--- /dev/null
+++ b/sonar-batch/src/main/java/org/sonar/batch/report/EventCache.java
@@ -0,0 +1,67 @@
+/*
+ * 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.batch.report;
+
+import org.sonar.api.BatchComponent;
+import org.sonar.api.resources.Resource;
+import org.sonar.batch.index.ResourceCache;
+import org.sonar.batch.protocol.Constants.EventCategory;
+import org.sonar.batch.protocol.output.BatchReport.Event;
+
+import javax.annotation.Nullable;
+
+import java.util.*;
+
+public class EventCache implements BatchComponent {
+
+ private final Map<Integer, List<Event>> eventsByComponentBatchId = new HashMap<>();
+ private final ResourceCache resourceCache;
+
+ public EventCache(ResourceCache resourceCache) {
+ this.resourceCache = resourceCache;
+ }
+
+ public void createEvent(Resource resource, String name, String description, EventCategory category, @Nullable String data) {
+ org.sonar.batch.protocol.output.BatchReport.Event.Builder eventBuilder = org.sonar.batch.protocol.output.BatchReport.Event.newBuilder();
+ eventBuilder.setName(name);
+ eventBuilder.setDescription(description);
+ eventBuilder.setCategory(category);
+ if (data != null) {
+ eventBuilder.setEventData(data);
+ }
+ int componentBatchId = resourceCache.get(resource).batchId();
+ eventBuilder.setComponentRef(componentBatchId);
+ addEvent(componentBatchId, eventBuilder.build());
+ }
+
+ private void addEvent(int componentBatchId, Event e) {
+ if (!eventsByComponentBatchId.containsKey(componentBatchId)) {
+ eventsByComponentBatchId.put(componentBatchId, new ArrayList<Event>());
+ }
+ eventsByComponentBatchId.get(componentBatchId).add(e);
+ }
+
+ public List<Event> getEvents(int componentBatchId) {
+ if (eventsByComponentBatchId.containsKey(componentBatchId)) {
+ return eventsByComponentBatchId.get(componentBatchId);
+ }
+ return Collections.emptyList();
+ }
+}
diff --git a/sonar-batch/src/main/java/org/sonar/batch/rule/QProfileEventsDecorator.java b/sonar-batch/src/main/java/org/sonar/batch/rule/QProfileEventsDecorator.java
index f3d7bffc035..4ebc91e489b 100644
--- a/sonar-batch/src/main/java/org/sonar/batch/rule/QProfileEventsDecorator.java
+++ b/sonar-batch/src/main/java/org/sonar/batch/rule/QProfileEventsDecorator.java
@@ -21,22 +21,14 @@ package org.sonar.batch.rule;
import com.google.common.collect.ImmutableSortedMap;
import org.apache.commons.lang.time.DateUtils;
-import org.sonar.api.batch.Decorator;
-import org.sonar.api.batch.DecoratorContext;
-import org.sonar.api.batch.DependsUpon;
-import org.sonar.api.batch.Event;
-import org.sonar.api.batch.TimeMachine;
-import org.sonar.api.batch.TimeMachineQuery;
+import org.sonar.api.batch.*;
import org.sonar.api.measures.CoreMetrics;
import org.sonar.api.measures.Measure;
import org.sonar.api.measures.Metric;
-import org.sonar.api.resources.Language;
-import org.sonar.api.resources.Languages;
-import org.sonar.api.resources.Project;
-import org.sonar.api.resources.Qualifiers;
-import org.sonar.api.resources.Resource;
+import org.sonar.api.resources.*;
import org.sonar.api.utils.KeyValueFormat;
-import org.sonar.batch.index.EventPersister;
+import org.sonar.batch.protocol.Constants.EventCategory;
+import org.sonar.batch.report.EventCache;
import org.sonar.core.UtcDateUtils;
import javax.annotation.CheckForNull;
@@ -49,12 +41,12 @@ public class QProfileEventsDecorator implements Decorator {
private final TimeMachine timeMachine;
private final Languages languages;
- private final EventPersister eventPersister;
+ private final EventCache eventCache;
- public QProfileEventsDecorator(TimeMachine timeMachine, Languages languages, EventPersister eventPersister) {
+ public QProfileEventsDecorator(TimeMachine timeMachine, Languages languages, EventCache eventCache) {
this.timeMachine = timeMachine;
this.languages = languages;
- this.eventPersister = eventPersister;
+ this.eventCache = eventCache;
}
@DependsUpon
@@ -112,18 +104,13 @@ public class QProfileEventsDecorator implements Decorator {
}
private void markAsChanged(DecoratorContext context, QProfile previousProfile, QProfile profile) {
- // DecoratorContext does not allow to set event data, so SonarIndex must be used
- Event event = new Event();
- event.setName(String.format("Changes in %s", profileLabel(profile)));
- event.setCategory(Event.CATEGORY_PROFILE);
Date from = previousProfile.getRulesUpdatedAt();
String data = KeyValueFormat.format(ImmutableSortedMap.of(
"key", profile.getKey(),
"from", UtcDateUtils.formatDateTime(fixDate(from)),
"to", UtcDateUtils.formatDateTime(fixDate(profile.getRulesUpdatedAt()))));
- event.setData(data);
- eventPersister.saveEvent(context.getResource(), event);
+ eventCache.createEvent(context.getResource(), String.format("Changes in %s", profileLabel(profile)), null, EventCategory.PROFILE, data);
}
/**
@@ -134,11 +121,11 @@ public class QProfileEventsDecorator implements Decorator {
}
private void markAsRemoved(DecoratorContext context, QProfile profile) {
- context.createEvent(String.format("Stop using %s", profileLabel(profile)), null, Event.CATEGORY_PROFILE, null);
+ eventCache.createEvent(context.getResource(), String.format("Stop using %s", profileLabel(profile)), null, EventCategory.PROFILE, null);
}
private void markAsAdded(DecoratorContext context, QProfile profile) {
- context.createEvent(String.format("Use %s", profileLabel(profile)), null, Event.CATEGORY_PROFILE, null);
+ eventCache.createEvent(context.getResource(), String.format("Use %s", profileLabel(profile)), null, EventCategory.PROFILE, null);
}
@CheckForNull
diff --git a/sonar-batch/src/main/java/org/sonar/batch/scan/ModuleScanContainer.java b/sonar-batch/src/main/java/org/sonar/batch/scan/ModuleScanContainer.java
index 2e7a68eb8da..a092c3a9f36 100644
--- a/sonar-batch/src/main/java/org/sonar/batch/scan/ModuleScanContainer.java
+++ b/sonar-batch/src/main/java/org/sonar/batch/scan/ModuleScanContainer.java
@@ -54,7 +54,6 @@ import org.sonar.batch.issue.tracking.IssueTrackingDecorator;
import org.sonar.batch.language.LanguageDistributionDecorator;
import org.sonar.batch.phases.*;
import org.sonar.batch.qualitygate.GenerateQualityGateEvents;
-import org.sonar.batch.qualitygate.QualityGateProvider;
import org.sonar.batch.qualitygate.QualityGateVerifier;
import org.sonar.batch.report.ComponentsPublisher;
import org.sonar.batch.report.IssuesPublisher;
@@ -179,8 +178,7 @@ public class ModuleScanContainer extends ComponentContainer {
private void addDataBaseComponents() {
add(DecoratorsExecutor.class,
- // quality gates
- new QualityGateProvider(),
+ // Quality Gate
QualityGateVerifier.class,
GenerateQualityGateEvents.class,
diff --git a/sonar-batch/src/main/java/org/sonar/batch/scan/ProjectScanContainer.java b/sonar-batch/src/main/java/org/sonar/batch/scan/ProjectScanContainer.java
index 89b5aed9596..8c4f5e6272d 100644
--- a/sonar-batch/src/main/java/org/sonar/batch/scan/ProjectScanContainer.java
+++ b/sonar-batch/src/main/java/org/sonar/batch/scan/ProjectScanContainer.java
@@ -50,6 +50,8 @@ import org.sonar.batch.issue.tracking.ServerIssueRepository;
import org.sonar.batch.mediumtest.ScanTaskObservers;
import org.sonar.batch.phases.GraphPersister;
import org.sonar.batch.profiling.PhasesSumUpTimeProfiler;
+import org.sonar.batch.qualitygate.QualityGateProvider;
+import org.sonar.batch.report.EventCache;
import org.sonar.batch.repository.ProjectRepositoriesProvider;
import org.sonar.batch.repository.ProjectScmRepositoryLoader;
import org.sonar.batch.repository.language.DefaultLanguagesRepository;
@@ -177,6 +179,12 @@ public class ProjectScanContainer extends ComponentContainer {
DependencyPersister.class,
DependencyCache.class,
+ // Quality Gate
+ new QualityGateProvider(),
+
+ // Events
+ EventCache.class,
+
ProjectSettings.class,
ScanTaskObservers.class);
@@ -184,7 +192,6 @@ public class ProjectScanContainer extends ComponentContainer {
private void addDataBaseComponents() {
add(
- EventPersister.class,
MeasurePersister.class,
DuplicationPersister.class,
ResourcePersister.class,
diff --git a/sonar-batch/src/main/java/org/sonar/batch/scan/sensor/VersionEventsSensor.java b/sonar-batch/src/main/java/org/sonar/batch/scan/sensor/VersionEventsSensor.java
deleted file mode 100644
index 351eca3facd..00000000000
--- a/sonar-batch/src/main/java/org/sonar/batch/scan/sensor/VersionEventsSensor.java
+++ /dev/null
@@ -1,70 +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.batch.scan.sensor;
-
-import org.apache.commons.lang.StringUtils;
-import org.sonar.api.batch.AnalysisMode;
-import org.sonar.api.batch.Event;
-import org.sonar.api.batch.RequiresDB;
-import org.sonar.api.batch.Sensor;
-import org.sonar.api.batch.SensorContext;
-import org.sonar.api.resources.Project;
-
-import java.util.Iterator;
-
-@RequiresDB
-public class VersionEventsSensor implements Sensor {
-
- private final AnalysisMode analysisMode;
-
- public VersionEventsSensor(AnalysisMode analysisMode) {
- this.analysisMode = analysisMode;
- }
-
- @Override
- public boolean shouldExecuteOnProject(Project project) {
- return !analysisMode.isPreview();
- }
-
- @Override
- public void analyse(Project project, SensorContext context) {
- if (StringUtils.isBlank(project.getAnalysisVersion())) {
- return;
- }
- deleteDeprecatedEvents(project, context);
- context.createEvent(project, project.getAnalysisVersion(), null, Event.CATEGORY_VERSION, null);
- }
-
- private void deleteDeprecatedEvents(Project project, SensorContext context) {
- String version = project.getAnalysisVersion();
- for (Iterator<Event> it = context.getEvents(project).iterator(); it.hasNext();) {
- Event event = it.next();
- if (event.isVersionCategory() && version.equals(event.getName())) {
- it.remove();
- context.deleteEvent(event);
- }
- }
- }
-
- @Override
- public String toString() {
- return getClass().getSimpleName();
- }
-}
diff --git a/sonar-batch/src/main/java/org/sonar/batch/scan/sensor/package-info.java b/sonar-batch/src/main/java/org/sonar/batch/scan/sensor/package-info.java
deleted file mode 100644
index b8fb1b58126..00000000000
--- a/sonar-batch/src/main/java/org/sonar/batch/scan/sensor/package-info.java
+++ /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.batch.scan.sensor;
-
-import javax.annotation.ParametersAreNonnullByDefault;
diff --git a/sonar-batch/src/test/java/org/sonar/batch/deprecated/components/PastSnapshotFinderByPreviousVersionTest.java b/sonar-batch/src/test/java/org/sonar/batch/deprecated/components/PastSnapshotFinderByPreviousVersionTest.java
index d932060914a..83c8b98a8b9 100644
--- a/sonar-batch/src/test/java/org/sonar/batch/deprecated/components/PastSnapshotFinderByPreviousVersionTest.java
+++ b/sonar-batch/src/test/java/org/sonar/batch/deprecated/components/PastSnapshotFinderByPreviousVersionTest.java
@@ -19,21 +19,27 @@
*/
package org.sonar.batch.deprecated.components;
-import org.sonar.batch.components.PastSnapshot;
-
-import org.sonar.batch.deprecated.components.PastSnapshotFinderByPreviousVersion;
+import org.junit.Before;
import org.junit.Test;
import org.sonar.api.CoreProperties;
import org.sonar.api.database.model.Snapshot;
+import org.sonar.batch.components.PastSnapshot;
import org.sonar.jpa.test.AbstractDbUnitTestCase;
+
import static org.assertj.core.api.Assertions.assertThat;
public class PastSnapshotFinderByPreviousVersionTest extends AbstractDbUnitTestCase {
+ private PastSnapshotFinderByPreviousVersion finder;
+
+ @Before
+ public void before() throws Exception {
+ finder = new PastSnapshotFinderByPreviousVersion(getSession(), getMyBatis());
+ }
+
@Test
public void shouldFindByPreviousVersion() {
setupData("with-previous-version");
- PastSnapshotFinderByPreviousVersion finder = new PastSnapshotFinderByPreviousVersion(getSession());
Snapshot currentProjectSnapshot = getSession().getSingleResult(Snapshot.class, "id", 1003);
PastSnapshot foundSnapshot = finder.findByPreviousVersion(currentProjectSnapshot);
@@ -45,7 +51,6 @@ public class PastSnapshotFinderByPreviousVersionTest extends AbstractDbUnitTestC
@Test
public void shouldFindByPreviousVersionWhenPreviousVersionDeleted() {
setupData("with-previous-version-deleted");
- PastSnapshotFinderByPreviousVersion finder = new PastSnapshotFinderByPreviousVersion(getSession());
Snapshot currentProjectSnapshot = getSession().getSingleResult(Snapshot.class, "id", 1003);
PastSnapshot foundSnapshot = finder.findByPreviousVersion(currentProjectSnapshot);
@@ -57,7 +62,6 @@ public class PastSnapshotFinderByPreviousVersionTest extends AbstractDbUnitTestC
@Test
public void testWithNoPreviousVersion() {
setupData("no-previous-version");
- PastSnapshotFinderByPreviousVersion finder = new PastSnapshotFinderByPreviousVersion(getSession());
Snapshot currentProjectSnapshot = getSession().getSingleResult(Snapshot.class, "id", 1003);
PastSnapshot foundSnapshot = finder.findByPreviousVersion(currentProjectSnapshot);
diff --git a/sonar-batch/src/test/java/org/sonar/batch/index/DefaultIndexTest.java b/sonar-batch/src/test/java/org/sonar/batch/index/DefaultIndexTest.java
index 0c62cc64ac4..908a8194c93 100644
--- a/sonar-batch/src/test/java/org/sonar/batch/index/DefaultIndexTest.java
+++ b/sonar-batch/src/test/java/org/sonar/batch/index/DefaultIndexTest.java
@@ -65,7 +65,7 @@ public class DefaultIndexTest {
ProjectTree projectTree = mock(ProjectTree.class);
ResourceCache resourceCache = new ResourceCache();
- index = new DefaultIndex(resourceCache, null, null, projectTree, metricFinder,
+ index = new DefaultIndex(resourceCache, null, projectTree, metricFinder,
mock(ResourceKeyMigration.class),
mock(MeasureCache.class));
diff --git a/sonar-batch/src/test/java/org/sonar/batch/index/ResourcePersisterTest.java b/sonar-batch/src/test/java/org/sonar/batch/index/ResourcePersisterTest.java
index 92299c87f20..0d9be3369a4 100644
--- a/sonar-batch/src/test/java/org/sonar/batch/index/ResourcePersisterTest.java
+++ b/sonar-batch/src/test/java/org/sonar/batch/index/ResourcePersisterTest.java
@@ -221,7 +221,7 @@ public class ResourcePersisterTest extends AbstractDbUnitTestCase {
when(projectTree.getProjectDefinition(moduleB)).thenReturn(ProjectDefinition.create().setBaseDir(new java.io.File(baseDir, "moduleB")));
when(projectTree.getProjectDefinition(moduleB1)).thenReturn(ProjectDefinition.create().setBaseDir(new java.io.File(baseDir, "moduleB/moduleB1")));
- DefaultIndex index = new DefaultIndex(resourceCache, null, null, projectTree, mock(MetricFinder.class),
+ DefaultIndex index = new DefaultIndex(resourceCache, null, projectTree, mock(MetricFinder.class),
mock(ResourceKeyMigration.class),
mock(MeasureCache.class));
diff --git a/sonar-batch/src/test/java/org/sonar/batch/qualitygate/GenerateQualityGateEventsTest.java b/sonar-batch/src/test/java/org/sonar/batch/qualitygate/GenerateQualityGateEventsTest.java
index e7e2c332838..0385d0796ae 100644
--- a/sonar-batch/src/test/java/org/sonar/batch/qualitygate/GenerateQualityGateEventsTest.java
+++ b/sonar-batch/src/test/java/org/sonar/batch/qualitygate/GenerateQualityGateEventsTest.java
@@ -22,7 +22,6 @@ package org.sonar.batch.qualitygate;
import org.junit.Before;
import org.junit.Test;
import org.sonar.api.batch.DecoratorContext;
-import org.sonar.api.batch.Event;
import org.sonar.api.batch.TimeMachine;
import org.sonar.api.batch.TimeMachineQuery;
import org.sonar.api.measures.CoreMetrics;
@@ -32,21 +31,18 @@ import org.sonar.api.notifications.Notification;
import org.sonar.api.notifications.NotificationManager;
import org.sonar.api.resources.File;
import org.sonar.api.resources.Project;
+import org.sonar.api.resources.Resource;
import org.sonar.api.test.ProjectTestBuilder;
+import org.sonar.batch.protocol.Constants.EventCategory;
+import org.sonar.batch.report.EventCache;
import java.util.Arrays;
-import java.util.Date;
import static org.assertj.core.api.Assertions.assertThat;
import static org.mockito.Matchers.any;
import static org.mockito.Matchers.anyString;
import static org.mockito.Matchers.eq;
-import static org.mockito.Matchers.isNull;
-import static org.mockito.Mockito.mock;
-import static org.mockito.Mockito.never;
-import static org.mockito.Mockito.times;
-import static org.mockito.Mockito.verify;
-import static org.mockito.Mockito.when;
+import static org.mockito.Mockito.*;
public class GenerateQualityGateEventsTest {
private GenerateQualityGateEvents decorator;
@@ -55,6 +51,7 @@ public class GenerateQualityGateEventsTest {
private TimeMachine timeMachine;
private NotificationManager notificationManager;
private Project project;
+ private EventCache eventCache;
@Before
public void setup() {
@@ -62,8 +59,10 @@ public class GenerateQualityGateEventsTest {
timeMachine = mock(TimeMachine.class);
qualityGate = mock(QualityGate.class);
notificationManager = mock(NotificationManager.class);
- decorator = new GenerateQualityGateEvents(qualityGate, timeMachine, notificationManager);
+ eventCache = mock(EventCache.class);
+ decorator = new GenerateQualityGateEvents(qualityGate, timeMachine, notificationManager, eventCache);
project = new ProjectTestBuilder().build();
+ when(context.getResource()).thenReturn(project);
}
@Test
@@ -85,7 +84,7 @@ public class GenerateQualityGateEventsTest {
@Test
public void shouldNotDecorateIfNotRootProject() {
decorator.decorate(File.create("Foo"), context);
- verify(context, never()).createEvent(anyString(), anyString(), anyString(), (Date) isNull());
+ verify(eventCache, never()).createEvent(any(Resource.class), anyString(), anyString(), any(EventCategory.class), anyString());
}
@Test
@@ -94,7 +93,7 @@ public class GenerateQualityGateEventsTest {
decorator.decorate(project, context);
- verify(context).createEvent(Metric.Level.ERROR.getColorName(), "desc", Event.CATEGORY_ALERT, null);
+ verify(eventCache).createEvent(project, Metric.Level.ERROR.getColorName(), "desc", EventCategory.ALERT, null);
verifyNotificationSent("Red", "desc", "ERROR", "true");
}
@@ -104,7 +103,7 @@ public class GenerateQualityGateEventsTest {
decorator.decorate(project, context);
- verify(context).createEvent(Metric.Level.WARN.getColorName(), "desc", Event.CATEGORY_ALERT, null);
+ verify(eventCache).createEvent(project, Metric.Level.WARN.getColorName(), "desc", EventCategory.ALERT, null);
verifyNotificationSent("Orange", "desc", "WARN", "true");
}
@@ -115,7 +114,7 @@ public class GenerateQualityGateEventsTest {
decorator.decorate(project, context);
- verify(context).createEvent("Red (was Orange)", "desc", Event.CATEGORY_ALERT, null);
+ verify(eventCache).createEvent(project, "Red (was Orange)", "desc", EventCategory.ALERT, null);
verifyNotificationSent("Red (was Orange)", "desc", "ERROR", "false");
}
@@ -126,7 +125,7 @@ public class GenerateQualityGateEventsTest {
decorator.decorate(project, context);
- verify(context).createEvent("Green (was Red)", null, Event.CATEGORY_ALERT, null);
+ verify(eventCache).createEvent(project, "Green (was Red)", null, EventCategory.ALERT, null);
verifyNotificationSent("Green (was Red)", null, "OK", "false");
}
@@ -137,7 +136,7 @@ public class GenerateQualityGateEventsTest {
decorator.decorate(project, context);
- verify(context).createEvent("Red (was Green)", "desc", Event.CATEGORY_ALERT, null);
+ verify(eventCache).createEvent(project, "Red (was Green)", "desc", EventCategory.ALERT, null);
verifyNotificationSent("Red (was Green)", "desc", "ERROR", "true");
}
@@ -148,7 +147,7 @@ public class GenerateQualityGateEventsTest {
decorator.decorate(project, context);
- verify(context).createEvent("Orange (was Red)", "desc", Event.CATEGORY_ALERT, null);
+ verify(eventCache).createEvent(project, "Orange (was Red)", "desc", EventCategory.ALERT, null);
verifyNotificationSent("Orange (was Red)", "desc", "WARN", "false");
}
@@ -156,7 +155,7 @@ public class GenerateQualityGateEventsTest {
public void shouldNotCreateEventWhenNoAlertStatus() {
decorator.decorate(project, context);
- verify(context, never()).createEvent(anyString(), anyString(), anyString(), (Date) isNull());
+ verify(eventCache, never()).createEvent(any(Resource.class), anyString(), anyString(), any(EventCategory.class), anyString());
verify(notificationManager, never()).scheduleForSending(any(Notification.class));
}
@@ -167,7 +166,7 @@ public class GenerateQualityGateEventsTest {
decorator.decorate(project, context);
- verify(context, never()).createEvent(anyString(), anyString(), anyString(), (Date) isNull());
+ verify(eventCache, never()).createEvent(any(Resource.class), anyString(), anyString(), any(EventCategory.class), anyString());
verify(notificationManager, never()).scheduleForSending(any(Notification.class));
}
@@ -178,7 +177,7 @@ public class GenerateQualityGateEventsTest {
decorator.decorate(project, context);
- verify(context, never()).createEvent(anyString(), anyString(), anyString(), (Date) isNull());
+ verify(eventCache, never()).createEvent(any(Resource.class), anyString(), anyString(), any(EventCategory.class), anyString());
verify(notificationManager, never()).scheduleForSending(any(Notification.class));
}
diff --git a/sonar-batch/src/test/java/org/sonar/batch/report/ComponentsPublisherTest.java b/sonar-batch/src/test/java/org/sonar/batch/report/ComponentsPublisherTest.java
index 43c2e697baa..fb0c2aa4b5f 100644
--- a/sonar-batch/src/test/java/org/sonar/batch/report/ComponentsPublisherTest.java
+++ b/sonar-batch/src/test/java/org/sonar/batch/report/ComponentsPublisherTest.java
@@ -33,14 +33,17 @@ import org.sonar.api.resources.Project;
import org.sonar.api.utils.DateUtils;
import org.sonar.batch.index.ResourceCache;
import org.sonar.batch.protocol.Constants.ComponentLinkType;
+import org.sonar.batch.protocol.Constants.EventCategory;
import org.sonar.batch.protocol.output.BatchReport.Component;
-import org.sonar.batch.protocol.output.BatchReportReader;
-import org.sonar.batch.protocol.output.BatchReportWriter;
-import org.sonar.batch.protocol.output.FileStructure;
+import org.sonar.batch.protocol.output.BatchReport.Event;
+import org.sonar.batch.protocol.output.*;
import java.io.File;
+import java.util.Arrays;
import static org.assertj.core.api.Assertions.assertThat;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.when;
public class ComponentsPublisherTest {
@@ -50,12 +53,15 @@ public class ComponentsPublisherTest {
private ProjectReactor reactor;
private ResourceCache resourceCache;
private ComponentsPublisher publisher;
+ private EventCache eventCache;
@Before
public void prepare() {
reactor = new ProjectReactor(ProjectDefinition.create().setKey("foo"));
+ reactor.getRoot().properties().put(CoreProperties.PROJECT_VERSION_PROPERTY, "1.0");
resourceCache = new ResourceCache();
- publisher = new ComponentsPublisher(reactor, resourceCache);
+ eventCache = mock(EventCache.class);
+ publisher = new ComponentsPublisher(reactor, resourceCache, eventCache);
}
@Test
@@ -73,22 +79,22 @@ public class ComponentsPublisherTest {
reactor.getRoot().addSubProject(ProjectDefinition.create().setKey("module1"));
Directory dir = Directory.create("src");
- dir.setEffectiveKey("foo:src");
+ dir.setEffectiveKey("module1:src");
dir.setId(3).setUuid("DIR_UUID");
resourceCache.add(dir, module1).setSnapshot(new Snapshot().setId(13));
org.sonar.api.resources.File file = org.sonar.api.resources.File.create("src/Foo.java", Java.INSTANCE, false);
- file.setEffectiveKey("foo:src/Foo.java");
+ file.setEffectiveKey("module1:src/Foo.java");
file.setId(4).setUuid("FILE_UUID");
resourceCache.add(file, dir).setSnapshot(new Snapshot().setId(14));
org.sonar.api.resources.File fileWithoutLang = org.sonar.api.resources.File.create("src/make", null, false);
- fileWithoutLang.setEffectiveKey("foo:src/make");
+ fileWithoutLang.setEffectiveKey("module1:src/make");
fileWithoutLang.setId(5).setUuid("FILE_WITHOUT_LANG_UUID");
resourceCache.add(fileWithoutLang, dir).setSnapshot(new Snapshot().setId(15));
org.sonar.api.resources.File testFile = org.sonar.api.resources.File.create("test/FooTest.java", Java.INSTANCE, true);
- testFile.setEffectiveKey("foo:test/FooTest.java");
+ testFile.setEffectiveKey("module1:test/FooTest.java");
testFile.setId(6).setUuid("TEST_FILE_UUID");
resourceCache.add(testFile, dir).setSnapshot(new Snapshot().setId(16));
@@ -108,8 +114,11 @@ public class ComponentsPublisherTest {
BatchReportReader reader = new BatchReportReader(outputDir);
Component rootProtobuf = reader.readComponent(1);
+ assertThat(rootProtobuf.getVersion()).isEqualTo("1.0");
assertThat(rootProtobuf.getLinkCount()).isEqualTo(0);
+ Component module1Protobuf = reader.readComponent(2);
+ assertThat(module1Protobuf.getVersion()).isEqualTo("1.0");
}
@Test
@@ -131,12 +140,12 @@ public class ComponentsPublisherTest {
reactor.getRoot().addSubProject(moduleDef);
Directory dir = Directory.create("src");
- dir.setEffectiveKey("foo:src");
+ dir.setEffectiveKey("module1:my_branch:my_branch:src");
dir.setId(3).setUuid("DIR_UUID");
resourceCache.add(dir, module1).setSnapshot(new Snapshot().setId(13));
org.sonar.api.resources.File file = org.sonar.api.resources.File.create("src/Foo.java", Java.INSTANCE, false);
- file.setEffectiveKey("foo:src/Foo.java");
+ file.setEffectiveKey("module1:my_branch:my_branch:src/Foo.java");
file.setId(4).setUuid("FILE_UUID");
resourceCache.add(file, dir).setSnapshot(new Snapshot().setId(14));
@@ -146,13 +155,52 @@ public class ComponentsPublisherTest {
BatchReportReader reader = new BatchReportReader(outputDir);
Component rootProtobuf = reader.readComponent(1);
+ assertThat(rootProtobuf.getVersion()).isEqualTo("1.0");
assertThat(rootProtobuf.getLinkCount()).isEqualTo(1);
assertThat(rootProtobuf.getLink(0).getType()).isEqualTo(ComponentLinkType.HOME);
assertThat(rootProtobuf.getLink(0).getHref()).isEqualTo("http://home");
Component module1Protobuf = reader.readComponent(2);
+ assertThat(module1Protobuf.getVersion()).isEqualTo("1.0");
assertThat(module1Protobuf.getLinkCount()).isEqualTo(1);
assertThat(module1Protobuf.getLink(0).getType()).isEqualTo(ComponentLinkType.CI);
assertThat(module1Protobuf.getLink(0).getHref()).isEqualTo("http://ci");
}
+
+ @Test
+ public void add_components_with_events() throws Exception {
+ // inputs
+ Project root = new Project("foo").setName("Root project")
+ .setAnalysisDate(DateUtils.parseDate(("2012-12-12")));
+ root.setId(1).setUuid("PROJECT_UUID");
+ resourceCache.add(root, null).setSnapshot(new Snapshot().setId(11));
+
+ Project module1 = new Project("module1").setName("Module1");
+ module1.setParent(root);
+ module1.setId(2).setUuid("MODULE_UUID");
+ resourceCache.add(module1, root).setSnapshot(new Snapshot().setId(12));
+ ProjectDefinition moduleDef = ProjectDefinition.create().setKey("module1");
+ reactor.getRoot().addSubProject(moduleDef);
+
+ when(eventCache.getEvents(2)).thenReturn(Arrays.asList(Event.newBuilder().setName("name").setCategory(EventCategory.ALERT).setComponentRef(2).build()));
+
+ Directory dir = Directory.create("src");
+ dir.setEffectiveKey("module1:src");
+ dir.setId(3).setUuid("DIR_UUID");
+ resourceCache.add(dir, module1).setSnapshot(new Snapshot().setId(13));
+
+ File outputDir = temp.newFolder();
+ BatchReportWriter writer = new BatchReportWriter(outputDir);
+ publisher.publish(writer);
+
+ BatchReportReader reader = new BatchReportReader(outputDir);
+ Component rootProtobuf = reader.readComponent(1);
+ assertThat(rootProtobuf.getVersion()).isEqualTo("1.0");
+ assertThat(rootProtobuf.getEventCount()).isEqualTo(0);
+
+ Component module1Protobuf = reader.readComponent(2);
+ assertThat(module1Protobuf.getVersion()).isEqualTo("1.0");
+ assertThat(module1Protobuf.getEventCount()).isEqualTo(1);
+ assertThat(module1Protobuf.getEvent(0).getCategory()).isEqualTo(EventCategory.ALERT);
+ }
}
diff --git a/sonar-batch/src/test/java/org/sonar/batch/rule/QProfileEventsDecoratorTest.java b/sonar-batch/src/test/java/org/sonar/batch/rule/QProfileEventsDecoratorTest.java
index 9142cf4da6d..b2c1ca57dcb 100644
--- a/sonar-batch/src/test/java/org/sonar/batch/rule/QProfileEventsDecoratorTest.java
+++ b/sonar-batch/src/test/java/org/sonar/batch/rule/QProfileEventsDecoratorTest.java
@@ -38,11 +38,9 @@
*/
package org.sonar.batch.rule;
-import org.hamcrest.BaseMatcher;
-import org.hamcrest.Description;
+import org.junit.Before;
import org.junit.Test;
import org.sonar.api.batch.DecoratorContext;
-import org.sonar.api.batch.Event;
import org.sonar.api.batch.TimeMachine;
import org.sonar.api.batch.TimeMachineQuery;
import org.sonar.api.measures.CoreMetrics;
@@ -51,17 +49,14 @@ import org.sonar.api.resources.Java;
import org.sonar.api.resources.Languages;
import org.sonar.api.resources.Project;
import org.sonar.api.resources.Resource;
-import org.sonar.batch.index.EventPersister;
+import org.sonar.batch.protocol.Constants.EventCategory;
+import org.sonar.batch.report.EventCache;
import java.util.Arrays;
-import java.util.Date;
import static org.assertj.core.api.Assertions.assertThat;
import static org.mockito.Matchers.any;
import static org.mockito.Matchers.anyString;
-import static org.mockito.Matchers.argThat;
-import static org.mockito.Matchers.eq;
-import static org.mockito.Matchers.same;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.never;
import static org.mockito.Mockito.verify;
@@ -77,8 +72,13 @@ public class QProfileEventsDecoratorTest {
DecoratorContext decoratorContext = mock(DecoratorContext.class);
TimeMachine timeMachine = mock(TimeMachine.class);
Languages languages = mock(Languages.class);
- EventPersister eventPersister = mock(EventPersister.class);
- QProfileEventsDecorator decorator = new QProfileEventsDecorator(timeMachine, languages, eventPersister);
+ EventCache eventCache = mock(EventCache.class);
+ QProfileEventsDecorator decorator = new QProfileEventsDecorator(timeMachine, languages, eventCache);
+
+ @Before
+ public void prepare() {
+ when(decoratorContext.getResource()).thenReturn(project);
+ }
@Test
public void basic_tests() {
@@ -98,7 +98,7 @@ public class QProfileEventsDecoratorTest {
decorator.decorate(project, decoratorContext);
- verify(decoratorContext, never()).createEvent(anyString(), anyString(), anyString(), any(Date.class));
+ verify(eventCache, never()).createEvent(any(Resource.class), anyString(), anyString(), any(EventCategory.class), anyString());
}
@Test
@@ -115,20 +115,8 @@ public class QProfileEventsDecoratorTest {
decorator.decorate(project, decoratorContext);
- verify(eventPersister).saveEvent(any(Resource.class), argThat(new BaseMatcher<Event>() {
- @Override
- public void describeTo(Description description) {
- }
-
- @Override
- public boolean matches(Object item) {
- Event event = (Event) item;
- return event.getCategory().equals(Event.CATEGORY_PROFILE) &&
- "Changes in 'Java One' (Java)".equals(event.getName()) &&
- // "from" and "to" must have one second more because of lack of ms precision
- "from=2014-01-15T12:00:01+0000;key=J1;to=2014-02-20T12:00:01+0000".equals(event.getData());
- }
- }));
+ // "from" and "to" must have one second more because of lack of ms precision
+ verify(eventCache).createEvent(project, "Changes in 'Java One' (Java)", null, EventCategory.PROFILE, "from=2014-01-15T12:00:01+0000;key=J1;to=2014-02-20T12:00:01+0000");
}
@Test
@@ -145,10 +133,7 @@ public class QProfileEventsDecoratorTest {
decorator.decorate(project, decoratorContext);
- verify(decoratorContext).createEvent(
- eq("Stop using 'Java One' (Java)"),
- eq((String) null),
- same(Event.CATEGORY_PROFILE), any(Date.class));
+ verify(eventCache).createEvent(project, "Stop using 'Java One' (Java)", null, EventCategory.PROFILE, null);
}
@Test
@@ -161,6 +146,6 @@ public class QProfileEventsDecoratorTest {
decorator.decorate(project, decoratorContext);
- verify(decoratorContext, never()).createEvent(anyString(), anyString(), anyString(), any(Date.class));
+ verify(eventCache, never()).createEvent(any(Resource.class), anyString(), anyString(), any(EventCategory.class), anyString());
}
}
diff --git a/sonar-batch/src/test/java/org/sonar/batch/scan/sensor/VersionEventsSensorTest.java b/sonar-batch/src/test/java/org/sonar/batch/scan/sensor/VersionEventsSensorTest.java
deleted file mode 100644
index d70932f673c..00000000000
--- a/sonar-batch/src/test/java/org/sonar/batch/scan/sensor/VersionEventsSensorTest.java
+++ /dev/null
@@ -1,119 +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.batch.scan.sensor;
-
-import org.sonar.batch.scan.sensor.VersionEventsSensor;
-
-import com.google.common.collect.Lists;
-import org.junit.Rule;
-import org.junit.Test;
-import org.junit.rules.ExpectedException;
-import org.sonar.api.batch.AnalysisMode;
-import org.sonar.api.batch.Event;
-import org.sonar.api.batch.SensorContext;
-import org.sonar.api.resources.Project;
-import org.sonar.api.resources.Resource;
-
-import java.util.Date;
-
-import static org.assertj.core.api.Assertions.assertThat;
-import static org.hamcrest.Matchers.is;
-import static org.junit.Assert.assertThat;
-import static org.mockito.Matchers.any;
-import static org.mockito.Matchers.anyString;
-import static org.mockito.Matchers.eq;
-import static org.mockito.Matchers.isNull;
-import static org.mockito.Mockito.mock;
-import static org.mockito.Mockito.never;
-import static org.mockito.Mockito.verify;
-import static org.mockito.Mockito.when;
-
-public class VersionEventsSensorTest {
-
- @Rule
- public ExpectedException thrown = ExpectedException.none();
-
- @Test
- public void shouldExecuteOnProject() throws Exception {
- AnalysisMode analysisMode = mock(AnalysisMode.class);
- assertThat(new VersionEventsSensor(analysisMode).shouldExecuteOnProject(null)).isTrue();
- when(analysisMode.isPreview()).thenReturn(true);
- assertThat(new VersionEventsSensor(analysisMode).shouldExecuteOnProject(null)).isFalse();
- }
-
- @Test
- public void testToString() throws Exception {
- assertThat(new VersionEventsSensor(null).toString(), is("VersionEventsSensor"));
- }
-
- @Test
- public void shouldDoNothingIfNoVersion() {
- VersionEventsSensor sensor = new VersionEventsSensor(null);
- SensorContext context = mock(SensorContext.class);
- Project project = mock(Project.class);
- when(project.getAnalysisVersion()).thenReturn(null);
-
- sensor.analyse(project, context);
-
- verify(context, never()).createEvent(any(Resource.class), anyString(), anyString(), anyString(), any(Date.class));
- verify(context, never()).deleteEvent(any(Event.class));
- }
-
- @Test
- public void shouldCreateVersionEvent() {
- VersionEventsSensor sensor = new VersionEventsSensor(null);
- SensorContext context = mock(SensorContext.class);
-
- Project project = mock(Project.class);
- when(project.getAnalysisVersion()).thenReturn("1.5-SNAPSHOT");
-
- sensor.analyse(project, context);
-
- verify(context).createEvent(eq(project), eq("1.5-SNAPSHOT"), (String) isNull(), eq(Event.CATEGORY_VERSION), (Date) isNull());
- }
-
- @Test
- public void shouldHaveOnlyOneEventByVersion() {
- Event sameVersionEvent = mockVersionEvent("1.5-SNAPSHOT");
- Event otherEvent = mockVersionEvent("1.4");
- Event anotherEvent = mockVersionEvent("1.3-SNAPSHOT");
-
- VersionEventsSensor sensor = new VersionEventsSensor(null);
- SensorContext context = mock(SensorContext.class);
-
- Project project = mock(Project.class);
- when(project.getAnalysisVersion()).thenReturn("1.5-SNAPSHOT");
-
- when(context.getEvents(project)).thenReturn(Lists.newArrayList(sameVersionEvent, otherEvent, anotherEvent));
-
- sensor.analyse(project, context);
-
- verify(context).deleteEvent(sameVersionEvent);
- verify(context).createEvent(eq(project), eq("1.5-SNAPSHOT"), (String) isNull(), eq(Event.CATEGORY_VERSION), (Date) isNull());
- }
-
- private Event mockVersionEvent(String version) {
- Event event = mock(Event.class);
- when(event.isVersionCategory()).thenReturn(true);
- when(event.getName()).thenReturn(version);
- return event;
- }
-
-}