]> source.dussan.org Git - sonarqube.git/commitdiff
SONAR-4602 Evict dryRun cache when changing issues
authorJulien HENRY <julien.henry@sonarsource.com>
Wed, 4 Sep 2013 13:06:41 +0000 (15:06 +0200)
committerJulien HENRY <julien.henry@sonarsource.com>
Wed, 4 Sep 2013 13:07:29 +0000 (15:07 +0200)
sonar-core/src/main/java/org/sonar/core/dryrun/DryRunCache.java
sonar-server/src/main/java/org/sonar/server/issue/IssueBulkChangeService.java
sonar-server/src/main/java/org/sonar/server/issue/IssueService.java
sonar-server/src/test/java/org/sonar/server/issue/IssueBulkChangeServiceTest.java
sonar-server/src/test/java/org/sonar/server/issue/IssueServiceTest.java

index 277e73ba8f76771f07832a73d367ca8be22d081b..104234b1f28703937b9d8be468b0011d60adaf89 100644 (file)
@@ -19,9 +19,8 @@
  */
 package org.sonar.core.dryrun;
 
-import org.sonar.api.ServerExtension;
-
 import org.apache.commons.io.FileUtils;
+import org.sonar.api.ServerExtension;
 import org.sonar.api.platform.ServerFileSystem;
 import org.sonar.core.properties.PropertiesDao;
 import org.sonar.core.properties.PropertyDto;
@@ -93,11 +92,8 @@ public class DryRunCache implements ServerExtension {
     propertiesDao.setProperty(new PropertyDto().setKey(SONAR_DRY_RUN_CACHE_LAST_UPDATE_KEY).setValue(String.valueOf(System.nanoTime())));
   }
 
-  public void reportResourceModification(long projectId) {
-    // Delete folder where dryRun DB are stored
-    FileUtils.deleteQuietly(getCacheLocation(projectId));
-
-    ResourceDto rootProject = resourceDao.getRootProjectByComponentId(projectId);
+  public void reportResourceModification(String resourceKey) {
+    ResourceDto rootProject = resourceDao.getRootProjectByComponentKey(resourceKey);
     propertiesDao.setProperty(new PropertyDto().setKey(SONAR_DRY_RUN_CACHE_LAST_UPDATE_KEY).setResourceId(rootProject.getId())
       .setValue(String.valueOf(System.nanoTime())));
   }
index 7fbbc7efc42058ee9282d60e34545edb81a4df71..94cbc26300d80b20cdb28ca375190be1d9f55def 100644 (file)
@@ -30,13 +30,16 @@ import org.sonar.api.issue.IssueQueryResult;
 import org.sonar.api.issue.internal.DefaultIssue;
 import org.sonar.api.issue.internal.IssueChangeContext;
 import org.sonar.api.web.UserRole;
+import org.sonar.core.dryrun.DryRunCache;
 import org.sonar.core.issue.IssueNotifications;
 import org.sonar.core.issue.db.IssueStorage;
 import org.sonar.server.exceptions.BadRequestException;
 import org.sonar.server.user.UserSession;
 
 import java.util.Date;
+import java.util.HashSet;
 import java.util.List;
+import java.util.Set;
 
 import static com.google.common.collect.Lists.newArrayList;
 
@@ -47,13 +50,15 @@ public class IssueBulkChangeService {
   private final DefaultIssueFinder issueFinder;
   private final IssueStorage issueStorage;
   private final IssueNotifications issueNotifications;
+  private final DryRunCache dryRunCache;
   private final List<Action> actions;
 
-  public IssueBulkChangeService(DefaultIssueFinder issueFinder, IssueStorage issueStorage, IssueNotifications issueNotifications, List<Action> actions) {
+  public IssueBulkChangeService(DefaultIssueFinder issueFinder, IssueStorage issueStorage, IssueNotifications issueNotifications, List<Action> actions, DryRunCache dryRunCache) {
     this.issueFinder = issueFinder;
     this.issueStorage = issueStorage;
     this.issueNotifications = issueNotifications;
     this.actions = actions;
+    this.dryRunCache = dryRunCache;
   }
 
   public IssueBulkChangeResult execute(IssueBulkChangeQuery issueBulkChangeQuery, UserSession userSession) {
@@ -67,6 +72,7 @@ public class IssueBulkChangeService {
     List<Action> bulkActions = getActionsToApply(issueBulkChangeQuery, issues, userSession);
 
     IssueChangeContext issueChangeContext = IssueChangeContext.createUser(new Date(), userSession.login());
+    Set<String> concernedProjects = new HashSet<String>();
     for (Issue issue : issues) {
       ActionContext actionContext = new ActionContext(issue, issueChangeContext);
       for (Action action : bulkActions) {
@@ -79,8 +85,13 @@ public class IssueBulkChangeService {
         }
         issueStorage.save((DefaultIssue) issue);
         issueNotifications.sendChanges((DefaultIssue) issue, issueChangeContext, issueQueryResult);
+        concernedProjects.add(((DefaultIssue) issue).projectKey());
       }
     }
+    // Purge dryRun cache
+    for (String projectKey : concernedProjects) {
+      dryRunCache.reportResourceModification(projectKey);
+    }
     LOG.debug("BulkChange execution time : {} ms", System.currentTimeMillis() - start);
     return result;
   }
@@ -118,7 +129,7 @@ public class IssueBulkChangeService {
       }
     }, null);
     if (action == null) {
-      throw new BadRequestException("The action : '"+ actionKey + "' is unknown");
+      throw new BadRequestException("The action : '" + actionKey + "' is unknown");
     }
     return action;
   }
index c14ff25cf1e20a3a0ba2710dd025332ae4cc29b0..33016fbd782fe2faab8ad8c0417ed32190324bb3 100644 (file)
@@ -32,6 +32,7 @@ import org.sonar.api.rules.RuleFinder;
 import org.sonar.api.user.User;
 import org.sonar.api.user.UserFinder;
 import org.sonar.api.web.UserRole;
+import org.sonar.core.dryrun.DryRunCache;
 import org.sonar.core.issue.IssueNotifications;
 import org.sonar.core.issue.IssueUpdater;
 import org.sonar.core.issue.db.IssueStorage;
@@ -44,6 +45,7 @@ import org.sonar.core.user.AuthorizationDao;
 import org.sonar.server.user.UserSession;
 
 import javax.annotation.Nullable;
+
 import java.util.Arrays;
 import java.util.Collections;
 import java.util.Date;
@@ -64,17 +66,19 @@ public class IssueService implements ServerComponent {
   private final ResourceDao resourceDao;
   private final AuthorizationDao authorizationDao;
   private final UserFinder userFinder;
+  private final DryRunCache dryRunCache;
 
   public IssueService(DefaultIssueFinder finder,
-                      IssueWorkflow workflow,
-                      IssueStorage issueStorage,
-                      IssueUpdater issueUpdater,
-                      IssueNotifications issueNotifications,
-                      ActionPlanService actionPlanService,
-                      RuleFinder ruleFinder,
-                      ResourceDao resourceDao,
-                      AuthorizationDao authorizationDao,
-                      UserFinder userFinder) {
+    IssueWorkflow workflow,
+    IssueStorage issueStorage,
+    IssueUpdater issueUpdater,
+    IssueNotifications issueNotifications,
+    ActionPlanService actionPlanService,
+    RuleFinder ruleFinder,
+    ResourceDao resourceDao,
+    AuthorizationDao authorizationDao,
+    UserFinder userFinder,
+    DryRunCache dryRunCache) {
     this.finder = finder;
     this.workflow = workflow;
     this.issueStorage = issueStorage;
@@ -85,6 +89,7 @@ public class IssueService implements ServerComponent {
     this.resourceDao = resourceDao;
     this.authorizationDao = authorizationDao;
     this.userFinder = userFinder;
+    this.dryRunCache = dryRunCache;
   }
 
   /**
@@ -116,6 +121,7 @@ public class IssueService implements ServerComponent {
     if (workflow.doTransition(issue, transition, context)) {
       issueStorage.save(issue);
       issueNotifications.sendChanges(issue, context, queryResult);
+      dryRunCache.reportResourceModification(issue.componentKey());
     }
     return issue;
   }
@@ -127,7 +133,7 @@ public class IssueService implements ServerComponent {
     User user = null;
     if (!Strings.isNullOrEmpty(assignee)) {
       user = userFinder.findByLogin(assignee);
-      if(user == null) {
+      if (user == null) {
         throw new IllegalArgumentException("Unknown user: " + assignee);
       }
     }
@@ -135,6 +141,7 @@ public class IssueService implements ServerComponent {
     if (issueUpdater.assign(issue, user, context)) {
       issueStorage.save(issue);
       issueNotifications.sendChanges(issue, context, queryResult);
+      dryRunCache.reportResourceModification(issue.componentKey());
     }
     return issue;
   }
@@ -144,7 +151,7 @@ public class IssueService implements ServerComponent {
     ActionPlan actionPlan = null;
     if (!Strings.isNullOrEmpty(actionPlanKey)) {
       actionPlan = actionPlanService.findByKey(actionPlanKey, userSession);
-      if(actionPlan == null) {
+      if (actionPlan == null) {
         throw new IllegalArgumentException("Unknown action plan: " + actionPlanKey);
       }
     }
@@ -155,6 +162,7 @@ public class IssueService implements ServerComponent {
     if (issueUpdater.plan(issue, actionPlan, context)) {
       issueStorage.save(issue);
       issueNotifications.sendChanges(issue, context, queryResult);
+      dryRunCache.reportResourceModification(issue.componentKey());
     }
     return issue;
   }
@@ -168,6 +176,7 @@ public class IssueService implements ServerComponent {
     if (issueUpdater.setManualSeverity(issue, severity, context)) {
       issueStorage.save(issue);
       issueNotifications.sendChanges(issue, context, queryResult);
+      dryRunCache.reportResourceModification(issue.componentKey());
     }
     return issue;
   }
@@ -195,6 +204,7 @@ public class IssueService implements ServerComponent {
     issue.setCreationDate(now);
     issue.setUpdateDate(now);
     issueStorage.save(issue);
+    dryRunCache.reportResourceModification(issue.componentKey());
     return issue;
   }
 
index 7bd22ea1711863b38f885b9cbf727cdc18a411d2..331a623bc668d507d59a5205f186c59e2cd8d0f6 100644 (file)
@@ -30,6 +30,7 @@ import org.sonar.api.issue.condition.Condition;
 import org.sonar.api.issue.internal.DefaultIssue;
 import org.sonar.api.issue.internal.IssueChangeContext;
 import org.sonar.api.web.UserRole;
+import org.sonar.core.dryrun.DryRunCache;
 import org.sonar.core.issue.IssueNotifications;
 import org.sonar.core.issue.db.IssueStorage;
 import org.sonar.server.exceptions.BadRequestException;
@@ -45,8 +46,16 @@ import static com.google.common.collect.Maps.newHashMap;
 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.anyListOf;
+import static org.mockito.Matchers.anyMap;
 import static org.mockito.Matchers.eq;
-import static org.mockito.Mockito.*;
+import static org.mockito.Mockito.doThrow;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.times;
+import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.verifyNoMoreInteractions;
+import static org.mockito.Mockito.verifyZeroInteractions;
+import static org.mockito.Mockito.when;
 
 public class IssueBulkChangeServiceTest {
 
@@ -69,7 +78,7 @@ public class IssueBulkChangeServiceTest {
 
     actions = newArrayList();
 
-    service = new IssueBulkChangeService(finder, issueStorage, issueNotifications, actions);
+    service = new IssueBulkChangeService(finder, issueStorage, issueNotifications, actions, mock(DryRunCache.class));
   }
 
   @Test
@@ -300,7 +309,6 @@ public class IssueBulkChangeServiceTest {
     verifyZeroInteractions(issueNotifications);
   }
 
-
   class MockAction extends Action {
 
     private boolean verify;
index 4132c7a63ce4bcaccb0880074affa70e2e81c7a8..dbb42117b2e56bfa6ebb58b141cb449f70310550 100644 (file)
@@ -35,6 +35,7 @@ import org.sonar.api.rules.RuleFinder;
 import org.sonar.api.user.User;
 import org.sonar.api.user.UserFinder;
 import org.sonar.api.web.UserRole;
+import org.sonar.core.dryrun.DryRunCache;
 import org.sonar.core.issue.DefaultActionPlan;
 import org.sonar.core.issue.IssueNotifications;
 import org.sonar.core.issue.IssueUpdater;
@@ -59,7 +60,11 @@ import static org.mockito.Matchers.anyInt;
 import static org.mockito.Matchers.anyLong;
 import static org.mockito.Matchers.anyString;
 import static org.mockito.Matchers.eq;
-import static org.mockito.Mockito.*;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.never;
+import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.verifyZeroInteractions;
+import static org.mockito.Mockito.when;
 
 public class IssueServiceTest {
 
@@ -90,7 +95,8 @@ public class IssueServiceTest {
     when(issueQueryResult.issues()).thenReturn(newArrayList((Issue) issue));
     when(issueQueryResult.first()).thenReturn(issue);
 
-    issueService = new IssueService(finder, workflow, issueStorage, issueUpdater, issueNotifications, actionPlanService, ruleFinder, resourceDao, authorizationDao, userFinder);
+    issueService = new IssueService(finder, workflow, issueStorage, issueUpdater, issueNotifications, actionPlanService, ruleFinder, resourceDao, authorizationDao, userFinder,
+      mock(DryRunCache.class));
   }
 
   @Test
@@ -101,7 +107,7 @@ public class IssueServiceTest {
 
   @Test
   public void should_fail_to_load_issue() {
-    when(issueQueryResult.issues()).thenReturn(Collections.<Issue>emptyList());
+    when(issueQueryResult.issues()).thenReturn(Collections.<Issue> emptyList());
     when(finder.find(any(IssueQuery.class))).thenReturn(issueQueryResult);
 
     try {
@@ -166,7 +172,6 @@ public class IssueServiceTest {
     verifyZeroInteractions(issueNotifications);
   }
 
-
   @Test
   public void should_fail_do_transition_if_not_logged() {
     when(userSession.isLoggedIn()).thenReturn(false);
@@ -201,7 +206,6 @@ public class IssueServiceTest {
     verify(issueNotifications).sendChanges(eq(issue), eq(issueChangeContext), eq(issueQueryResult));
   }
 
-
   @Test
   public void should_unassign() {
     when(issueUpdater.assign(eq(issue), eq((User) null), any(IssueChangeContext.class))).thenReturn(true);
@@ -439,5 +443,4 @@ public class IssueServiceTest {
     verifyZeroInteractions(issueStorage);
   }
 
-
 }