]> source.dussan.org Git - sonarqube.git/commitdiff
SONAR-10223 add optional organization to PostProjectAnalysisTask
authorSébastien Lesaint <sebastien.lesaint@sonarsource.com>
Wed, 27 Dec 2017 14:50:23 +0000 (15:50 +0100)
committerJanos Gyerik <janos.gyerik@sonarsource.com>
Fri, 5 Jan 2018 14:49:51 +0000 (15:49 +0100)
server/sonar-ce/src/main/java/org/sonar/ce/container/ComputeEngineContainerImpl.java
server/sonar-ce/src/test/java/org/sonar/ce/container/ComputeEngineContainerImplTest.java
server/sonar-server/src/main/java/org/sonar/server/computation/task/projectanalysis/api/posttask/PostProjectAnalysisTasksExecutor.java
server/sonar-server/src/test/java/org/sonar/server/computation/task/projectanalysis/api/posttask/PostProjectAnalysisTasksExecutorTest.java
sonar-plugin-api/src/main/java/org/sonar/api/ce/posttask/Organization.java [new file with mode: 0644]
sonar-plugin-api/src/main/java/org/sonar/api/ce/posttask/PostProjectAnalysisTask.java
sonar-plugin-api/src/main/java/org/sonar/api/ce/posttask/PostProjectAnalysisTaskTester.java
sonar-plugin-api/src/test/java/org/sonar/api/ce/posttask/PostProjectAnalysisTaskTesterTest.java

index 30f22461dd960ca97d02795191328c05c12509c6..5387324ec120ae293505184c21cc9609797618ca 100644 (file)
@@ -109,6 +109,7 @@ import org.sonar.server.notification.email.AlertsEmailTemplate;
 import org.sonar.server.notification.email.EmailNotificationChannel;
 import org.sonar.server.organization.BillingValidationsProxyImpl;
 import org.sonar.server.organization.DefaultOrganizationProviderImpl;
+import org.sonar.server.organization.OrganizationFlagsImpl;
 import org.sonar.server.permission.GroupPermissionChanger;
 import org.sonar.server.permission.PermissionTemplateService;
 import org.sonar.server.permission.PermissionUpdater;
@@ -312,7 +313,8 @@ public class ComputeEngineContainerImpl implements ComputeEngineContainer {
       UriReader.class,
       ServerImpl.class,
       DefaultOrganizationProviderImpl.class,
-      SynchronousAsyncExecution.class);
+      SynchronousAsyncExecution.class,
+      OrganizationFlagsImpl.class);
   }
 
   private static void populateLevel4(ComponentContainer container, Props props) {
index 950cbde71b7e19a2cec704f0fe51fc9f157dc13d..76da867464e05669d6f9aca221d54640ff52760b 100644 (file)
@@ -65,7 +65,7 @@ public class ComputeEngineContainerImplTest {
   private ComputeEngineContainerImpl underTest;
 
   @Before
-  public void setUp() throws Exception {
+  public void setUp() {
     underTest = new ComputeEngineContainerImpl();
     underTest.setComputeEngineStatus(mock(ComputeEngineStatus.class));
   }
@@ -105,7 +105,7 @@ public class ComputeEngineContainerImplTest {
     );
     assertThat(picoContainer.getParent().getComponentAdapters()).hasSize(
       CONTAINER_ITSELF
-        + 6 // level 3
+        + 7 // level 3
     );
     assertThat(picoContainer.getParent().getParent().getComponentAdapters()).hasSize(
       CONTAINER_ITSELF
index 6f016550ace4ead9944bdf0e38b1b9bdf9f5506b..0bbbae931730356d4f2c26cad8977c9f9b64ae69 100644 (file)
@@ -29,6 +29,7 @@ import javax.annotation.Nullable;
 import org.sonar.api.ce.posttask.Analysis;
 import org.sonar.api.ce.posttask.Branch;
 import org.sonar.api.ce.posttask.CeTask;
+import org.sonar.api.ce.posttask.Organization;
 import org.sonar.api.ce.posttask.PostProjectAnalysisTask;
 import org.sonar.api.ce.posttask.Project;
 import org.sonar.api.ce.posttask.QualityGate;
@@ -116,6 +117,7 @@ public class PostProjectAnalysisTasksExecutor implements ComputationStepExecutor
 
   private ProjectAnalysisImpl createProjectAnalysis(CeTask.Status status) {
     return new ProjectAnalysisImpl(
+      createOrganization(),
       new CeTaskImpl(this.ceTask.getUuid(), status),
       createProject(this.ceTask),
       getAnalysis().orElse(null),
@@ -125,6 +127,15 @@ public class PostProjectAnalysisTasksExecutor implements ComputationStepExecutor
       createBranch());
   }
 
+  @CheckForNull
+  private Organization createOrganization() {
+    org.sonar.server.computation.task.projectanalysis.analysis.Organization organization = analysisMetadataHolder.getOrganization();
+    if (organization.isOrganizationsEnabled()) {
+      return new OrganizationImpl(organization.getName(), organization.getKey());
+    }
+    return null;
+  }
+
   private Optional<Analysis> getAnalysis() {
     Long analysisDate = getAnalysisDate();
 
@@ -196,6 +207,8 @@ public class PostProjectAnalysisTasksExecutor implements ComputationStepExecutor
   }
 
   private static class ProjectAnalysisImpl implements PostProjectAnalysisTask.ProjectAnalysis {
+    @Nullable
+    private final Organization organization;
     private final CeTask ceTask;
     private final Project project;
     private final long date;
@@ -207,9 +220,10 @@ public class PostProjectAnalysisTasksExecutor implements ComputationStepExecutor
     @Nullable
     private final Analysis analysis;
 
-    private ProjectAnalysisImpl(CeTask ceTask, Project project,
+    private ProjectAnalysisImpl(@Nullable Organization organization, CeTask ceTask, Project project,
       @Nullable Analysis analysis, long date,
       ScannerContext scannerContext, @Nullable QualityGate qualityGate, @Nullable Branch branch) {
+      this.organization = organization;
       this.ceTask = requireNonNull(ceTask, "ceTask can not be null");
       this.project = requireNonNull(project, "project can not be null");
       this.analysis = analysis;
@@ -219,6 +233,11 @@ public class PostProjectAnalysisTasksExecutor implements ComputationStepExecutor
       this.branch = branch;
     }
 
+    @Override
+    public Optional<Organization> getOrganization() {
+      return Optional.ofNullable(organization);
+    }
+
     @Override
     public CeTask getCeTask() {
       return ceTask;
@@ -293,4 +312,24 @@ public class PostProjectAnalysisTasksExecutor implements ComputationStepExecutor
       return new Date(date);
     }
   }
+
+  private static class OrganizationImpl implements Organization {
+    private final String name;
+    private final String key;
+
+    private OrganizationImpl(String name, String key) {
+      this.name = requireNonNull(name, "name can't be null");
+      this.key = requireNonNull(key, "key can't be null");
+    }
+
+    @Override
+    public String getName() {
+      return name;
+    }
+
+    @Override
+    public String getKey() {
+      return key;
+    }
+  }
 }
index 484180fabb25ad158fa4b7d802854f46fdc8caf6..6f7ca22c791ac18ce84d586c5bf2edb0c881849f 100644 (file)
@@ -26,6 +26,7 @@ import com.tngtech.java.junit.dataprovider.UseDataProvider;
 import java.util.Date;
 import java.util.List;
 import java.util.Optional;
+import java.util.Random;
 import javax.annotation.Nullable;
 import org.apache.commons.lang.RandomStringUtils;
 import org.junit.Before;
@@ -39,9 +40,11 @@ import org.sonar.api.ce.posttask.Project;
 import org.sonar.api.utils.System2;
 import org.sonar.ce.queue.CeTask;
 import org.sonar.db.component.BranchType;
+import org.sonar.db.organization.OrganizationDto;
 import org.sonar.scanner.protocol.output.ScannerReport;
 import org.sonar.server.computation.task.projectanalysis.analysis.AnalysisMetadataHolderRule;
 import org.sonar.server.computation.task.projectanalysis.analysis.Branch;
+import org.sonar.server.computation.task.projectanalysis.analysis.Organization;
 import org.sonar.server.computation.task.projectanalysis.batch.BatchReportReaderRule;
 import org.sonar.server.computation.task.projectanalysis.component.DefaultBranchImpl;
 import org.sonar.server.computation.task.projectanalysis.metric.Metric;
@@ -79,10 +82,13 @@ public class PostProjectAnalysisTasksExecutorTest {
   @Rule
   public BatchReportReaderRule reportReader = new BatchReportReaderRule();
 
+  private String organizationUuid = "org1";
+  private String organizationKey = organizationUuid + "_key";
+  private String organizationName = organizationUuid + "_name";
   private System2 system2 = mock(System2.class);
   private ArgumentCaptor<PostProjectAnalysisTask.ProjectAnalysis> projectAnalysisArgumentCaptor = ArgumentCaptor.forClass(PostProjectAnalysisTask.ProjectAnalysis.class);
   private CeTask ceTask = new CeTask.Builder()
-    .setOrganizationUuid("org1")
+    .setOrganizationUuid(organizationUuid)
     .setType("type")
     .setUuid("uuid")
     .setComponentKey("component key")
@@ -104,6 +110,9 @@ public class PostProjectAnalysisTasksExecutorTest {
     Branch branch = mock(Branch.class);
     when(branch.getType()).thenReturn(BranchType.LONG);
     analysisMetadataHolder.setBranch(branch);
+    analysisMetadataHolder.setOrganization(Organization.from(
+      new OrganizationDto().setKey(organizationKey).setName(organizationName).setUuid(organizationUuid).setDefaultQualityGateUuid("foo"),
+      new Random().nextBoolean()));
   }
 
   @Test
@@ -123,7 +132,7 @@ public class PostProjectAnalysisTasksExecutorTest {
     new PostProjectAnalysisTasksExecutor(
       ceTask, analysisMetadataHolder, qualityGateHolder, qualityGateStatusHolder, reportReader,
       system2, new PostProjectAnalysisTask[] {postProjectAnalysisTask1, postProjectAnalysisTask2})
-        .finished(allStepsExecuted);
+      .finished(allStepsExecuted);
 
     inOrder.verify(postProjectAnalysisTask1).finished(projectAnalysisArgumentCaptor.capture());
     inOrder.verify(postProjectAnalysisTask2).finished(projectAnalysisArgumentCaptor.capture());
@@ -134,6 +143,34 @@ public class PostProjectAnalysisTasksExecutorTest {
     assertThat(allValues.get(0)).isSameAs(allValues.get(1));
   }
 
+  @Test
+  @UseDataProvider("booleanValues")
+  public void organization_is_null_when_organization_are_disabled(boolean allStepsExecuted) {
+    analysisMetadataHolder.setOrganization(Organization.from(
+      new OrganizationDto().setKey(organizationKey).setName(organizationName).setUuid(organizationUuid).setDefaultQualityGateUuid("foo"),
+      false));
+    underTest.finished(allStepsExecuted);
+
+    verify(postProjectAnalysisTask).finished(projectAnalysisArgumentCaptor.capture());
+
+    assertThat(projectAnalysisArgumentCaptor.getValue().getOrganization()).isEmpty();
+  }
+
+  @Test
+  @UseDataProvider("booleanValues")
+  public void organization_is_not_null_when_organization_are_enabled(boolean allStepsExecuted) {
+    analysisMetadataHolder.setOrganization(Organization.from(
+      new OrganizationDto().setKey(organizationKey).setName(organizationName).setUuid(organizationUuid).setDefaultQualityGateUuid("foo"),
+      true));
+    underTest.finished(allStepsExecuted);
+
+    verify(postProjectAnalysisTask).finished(projectAnalysisArgumentCaptor.capture());
+
+    org.sonar.api.ce.posttask.Organization organization = projectAnalysisArgumentCaptor.getValue().getOrganization().get();
+    assertThat(organization.getKey()).isEqualTo(organizationKey);
+    assertThat(organization.getName()).isEqualTo(organizationName);
+  }
+
   @Test
   @UseDataProvider("booleanValues")
   public void CeTask_status_depends_on_finished_method_argument_is_true_or_false(boolean allStepsExecuted) {
@@ -325,7 +362,7 @@ public class PostProjectAnalysisTasksExecutorTest {
     new PostProjectAnalysisTasksExecutor(
       ceTask, analysisMetadataHolder, qualityGateHolder, qualityGateStatusHolder, reportReader,
       system2, new PostProjectAnalysisTask[] {postProjectAnalysisTask1, postProjectAnalysisTask2, postProjectAnalysisTask3})
-        .finished(allStepsExecuted);
+      .finished(allStepsExecuted);
 
     inOrder.verify(postProjectAnalysisTask1).finished(projectAnalysisArgumentCaptor.capture());
     inOrder.verify(postProjectAnalysisTask2).finished(projectAnalysisArgumentCaptor.capture());
diff --git a/sonar-plugin-api/src/main/java/org/sonar/api/ce/posttask/Organization.java b/sonar-plugin-api/src/main/java/org/sonar/api/ce/posttask/Organization.java
new file mode 100644 (file)
index 0000000..48d9bf7
--- /dev/null
@@ -0,0 +1,26 @@
+/*
+ * SonarQube
+ * Copyright (C) 2009-2017 SonarSource SA
+ * mailto:info AT sonarsource DOT com
+ *
+ * This program 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.
+ *
+ * This program 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.api.ce.posttask;
+
+public interface Organization {
+  String getName();
+
+  String getKey();
+}
index d8c2a07640bfae8fd681580baef57d2d5e46ab0d..1e3d05b734aac7b5b3814d24be02aead876b7985 100644 (file)
@@ -52,6 +52,14 @@ public interface PostProjectAnalysisTask {
    * @since 5.5
    */
   interface ProjectAnalysis {
+    /**
+     * When organizations are enabled in SonarQube, the organization the project belongs to.
+     *
+     * @since 7.0
+     * @return a non empty value when organizations are enabled, otherwise empty
+     */
+    Optional<Organization> getOrganization();
+
     /**
      * Details of the Compute Engine task in which the project analysis was run.
      */
index 3d0e678190a0191f429c9c4af84e7904e2bf5f24..1db5724b668a924af88626ff578f8fced5a5f5c4 100644 (file)
@@ -99,8 +99,12 @@ public class PostProjectAnalysisTaskTester {
   private static final String CE_TASK_CAN_NOT_BE_NULL = "ceTask cannot be null";
   private static final String STATUS_CAN_NOT_BE_NULL = "status cannot be null";
   private static final String SCANNER_CONTEXT_CAN_NOT_BE_NULL = "scannerContext cannot be null";
+  private static final String KEY_CAN_NOT_BE_NULL = "key cannot be null";
+  private static final String NAME_CAN_NOT_BE_NULL = "name cannot be null";
 
   private final PostProjectAnalysisTask underTest;
+  @Nullable
+  private Organization organization;
   @CheckForNull
   private CeTask ceTask;
   @CheckForNull
@@ -122,6 +126,13 @@ public class PostProjectAnalysisTaskTester {
     return new PostProjectAnalysisTaskTester(underTest);
   }
 
+  /**
+   * @since 7.0
+   */
+  public static OrganizationBuilder newOrganizationBuilder() {
+    return new OrganizationBuilder();
+  }
+
   public static CeTaskBuilder newCeTaskBuilder() {
     return new CeTaskBuilder();
   }
@@ -146,6 +157,14 @@ public class PostProjectAnalysisTaskTester {
     return new ScannerContextBuilder();
   }
 
+  /**
+   * @since 7.0
+   */
+  public PostProjectAnalysisTaskTester withOrganization(@Nullable Organization organization) {
+    this.organization = organization;
+    return this;
+  }
+
   public PostProjectAnalysisTaskTester withCeTask(CeTask ceTask) {
     this.ceTask = requireNonNull(ceTask, CE_TASK_CAN_NOT_BE_NULL);
     return this;
@@ -201,6 +220,7 @@ public class PostProjectAnalysisTaskTester {
     }
 
     PostProjectAnalysisTask.ProjectAnalysis projectAnalysis = new ProjectAnalysisBuilder()
+      .setOrganization(organization)
       .setCeTask(ceTask)
       .setProject(project)
       .setBranch(branch)
@@ -216,6 +236,51 @@ public class PostProjectAnalysisTaskTester {
     return projectAnalysis;
   }
 
+  public static final class OrganizationBuilder {
+    @CheckForNull
+    private String name;
+    @CheckForNull
+    private String key;
+
+    private OrganizationBuilder() {
+      // prevents instantiation
+    }
+
+    public OrganizationBuilder setName(String name) {
+      this.name = requireNonNull(name, NAME_CAN_NOT_BE_NULL);
+      return this;
+    }
+
+    public OrganizationBuilder setKey(String key) {
+      this.key = requireNonNull(key, KEY_CAN_NOT_BE_NULL);
+      return this;
+    }
+
+    public Organization build() {
+      requireNonNull(this.name, NAME_CAN_NOT_BE_NULL);
+      requireNonNull(this.key, KEY_CAN_NOT_BE_NULL);
+      return new Organization() {
+        @Override
+        public String getName() {
+          return name;
+        }
+
+        @Override
+        public String getKey() {
+          return key;
+        }
+
+        @Override
+        public String toString() {
+          return "Organization{" +
+            "name='" + name + '\'' +
+            ", key='" + key + '\'' +
+            '}';
+        }
+      };
+    }
+  }
+
   public static final class CeTaskBuilder {
     private static final String ID_CAN_NOT_BE_NULL = "id cannot be null";
 
@@ -265,8 +330,6 @@ public class PostProjectAnalysisTaskTester {
 
   public static final class ProjectBuilder {
     private static final String UUID_CAN_NOT_BE_NULL = "uuid cannot be null";
-    private static final String KEY_CAN_NOT_BE_NULL = "key cannot be null";
-    private static final String NAME_CAN_NOT_BE_NULL = "name cannot be null";
     private String uuid;
     private String key;
     private String name;
@@ -350,7 +413,6 @@ public class PostProjectAnalysisTaskTester {
     public Branch build() {
       return new Branch() {
 
-
         @Override
         public boolean isMain() {
           return isMain;
@@ -618,6 +680,7 @@ public class PostProjectAnalysisTaskTester {
   }
 
   public static final class ProjectAnalysisBuilder {
+    private Organization organization;
     private CeTask ceTask;
     private Project project;
     private Branch branch;
@@ -630,6 +693,11 @@ public class PostProjectAnalysisTaskTester {
       // prevents instantiation outside PostProjectAnalysisTaskTester
     }
 
+    public ProjectAnalysisBuilder setOrganization(@Nullable Organization organization) {
+      this.organization = organization;
+      return this;
+    }
+
     public ProjectAnalysisBuilder setCeTask(CeTask ceTask) {
       this.ceTask = ceTask;
       return this;
@@ -667,6 +735,11 @@ public class PostProjectAnalysisTaskTester {
 
     public PostProjectAnalysisTask.ProjectAnalysis build() {
       return new PostProjectAnalysisTask.ProjectAnalysis() {
+        @Override
+        public Optional<Organization> getOrganization() {
+          return Optional.ofNullable(organization);
+        }
+
         @Override
         public CeTask getCeTask() {
           return ceTask;
@@ -711,7 +784,8 @@ public class PostProjectAnalysisTaskTester {
         @Override
         public String toString() {
           return "ProjectAnalysis{" +
-            "ceTask=" + ceTask +
+            "organization=" + organization +
+            ", ceTask=" + ceTask +
             ", project=" + project +
             ", date=" + date.getTime() +
             ", analysisDate=" + date.getTime() +
index baec1f163e733550f2c618acf3324ea146ff33d4..d8aa08d6466710f5654faba0f4765e7d0318f8a0 100644 (file)
@@ -33,6 +33,7 @@ public class PostProjectAnalysisTaskTesterTest {
   @Rule
   public ExpectedException expectedException = ExpectedException.none();
 
+  private Organization organization = mock(Organization.class);
   private CeTask ceTask = mock(CeTask.class);
   private Project project = mock(Project.class);
   private long someDateAsLong = 846351351684351L;
@@ -101,12 +102,13 @@ public class PostProjectAnalysisTaskTesterTest {
 
   @Test
   public void verify_getters_of_ProjectAnalysis_object_passed_to_PostProjectAnalysisTask() {
-    underTest.withCeTask(ceTask).withProject(project).withQualityGate(qualityGate).withAnalysisUuid(analysisUuid).at(someDate);
+    underTest.withOrganization(organization).withCeTask(ceTask).withProject(project).withQualityGate(qualityGate).withAnalysisUuid(analysisUuid).at(someDate);
 
     underTest.execute();
 
     PostProjectAnalysisTask.ProjectAnalysis projectAnalysis = captorPostProjectAnalysisTask.projectAnalysis;
     assertThat(projectAnalysis).isNotNull();
+    assertThat(projectAnalysis.getOrganization().get()).isSameAs(organization);
     assertThat(projectAnalysis.getCeTask()).isSameAs(ceTask);
     assertThat(projectAnalysis.getProject()).isSameAs(project);
     assertThat(projectAnalysis.getDate()).isSameAs(someDate);
@@ -116,15 +118,16 @@ public class PostProjectAnalysisTaskTesterTest {
 
   @Test
   public void verify_toString_of_ProjectAnalysis_object_passed_to_PostProjectAnalysisTask() {
+    when(organization.toString()).thenReturn("Organization");
     when(ceTask.toString()).thenReturn("CeTask");
     when(project.toString()).thenReturn("Project");
     when(qualityGate.toString()).thenReturn("QualityGate");
-    underTest.withCeTask(ceTask).withProject(project).withQualityGate(qualityGate).at(someDate);
+    underTest.withOrganization(organization).withCeTask(ceTask).withProject(project).withQualityGate(qualityGate).at(someDate);
 
     underTest.execute();
 
     assertThat(captorPostProjectAnalysisTask.projectAnalysis.toString())
-      .isEqualTo("ProjectAnalysis{ceTask=CeTask, project=Project, date=846351351684351, analysisDate=846351351684351, qualityGate=QualityGate}");
+      .isEqualTo("ProjectAnalysis{organization=Organization, ceTask=CeTask, project=Project, date=846351351684351, analysisDate=846351351684351, qualityGate=QualityGate}");
 
   }