]> source.dussan.org Git - sonarqube.git/commitdiff
SONAR-8594 enforce report has same organization key as component 1507/head
authorSébastien Lesaint <sebastien.lesaint@sonarsource.com>
Mon, 9 Jan 2017 14:17:08 +0000 (15:17 +0100)
committerSébastien Lesaint <sebastien.lesaint@sonarsource.com>
Mon, 16 Jan 2017 10:38:43 +0000 (11:38 +0100)
14 files changed:
server/sonar-server/src/main/java/org/sonar/server/computation/task/projectanalysis/analysis/AnalysisMetadataHolder.java
server/sonar-server/src/main/java/org/sonar/server/computation/task/projectanalysis/analysis/AnalysisMetadataHolderImpl.java
server/sonar-server/src/main/java/org/sonar/server/computation/task/projectanalysis/analysis/MutableAnalysisMetadataHolder.java
server/sonar-server/src/main/java/org/sonar/server/computation/task/projectanalysis/analysis/Organization.java [new file with mode: 0644]
server/sonar-server/src/main/java/org/sonar/server/computation/task/projectanalysis/step/LoadReportAnalysisMetadataHolderStep.java
server/sonar-server/src/main/java/org/sonar/server/computation/task/projectanalysis/step/PersistComponentsStep.java
server/sonar-server/src/test/java/org/sonar/server/computation/task/projectanalysis/analysis/AnalysisMetadataHolderImplTest.java
server/sonar-server/src/test/java/org/sonar/server/computation/task/projectanalysis/analysis/AnalysisMetadataHolderRule.java
server/sonar-server/src/test/java/org/sonar/server/computation/task/projectanalysis/analysis/MutableAnalysisMetadataHolderRule.java
server/sonar-server/src/test/java/org/sonar/server/computation/task/projectanalysis/analysis/OrganizationTest.java [new file with mode: 0644]
server/sonar-server/src/test/java/org/sonar/server/computation/task/projectanalysis/step/LoadReportAnalysisMetadataHolderStepTest.java
server/sonar-server/src/test/java/org/sonar/server/computation/task/projectanalysis/step/ReportPersistComponentsStepTest.java
server/sonar-server/src/test/java/org/sonar/server/computation/task/projectanalysis/step/ViewsPersistComponentsStepTest.java
sonar-db/src/test/java/org/sonar/db/DbTester.java

index ac17a20999533b8a863477084f62380209ba839a..597afc557891f5be47ad3ea681d08322edd43e11 100644 (file)
@@ -26,10 +26,10 @@ import org.sonar.server.qualityprofile.QualityProfile;
 public interface AnalysisMetadataHolder {
 
   /**
-   * Returns the UUID of the organization the analysis belongs to.
-   * @throws IllegalStateException if organization uuid has not been set
+   * Returns the organization the analysis belongs to.
+   * @throws IllegalStateException if organization has not been set
    */
-  String getOrganizationUuid();
+  Organization getOrganization();
 
   /**
    * Returns the UUID generated for this analysis.
index a7cbc2b0c11a5a4c1c181d3965577899ddefaa6e..5e8f2480c8e7119ec200ee25d0dfea03254a6ea5 100644 (file)
@@ -31,7 +31,7 @@ import static java.util.Objects.requireNonNull;
 
 public class AnalysisMetadataHolderImpl implements MutableAnalysisMetadataHolder {
 
-  private final InitializedProperty<String> organizationUuid = new InitializedProperty<>();
+  private final InitializedProperty<Organization> organization = new InitializedProperty<>();
   private final InitializedProperty<String> uuid = new InitializedProperty<>();
   private final InitializedProperty<Long> analysisDate = new InitializedProperty<>();
   private final InitializedProperty<Analysis> baseProjectSnapshot = new InitializedProperty<>();
@@ -41,17 +41,17 @@ public class AnalysisMetadataHolderImpl implements MutableAnalysisMetadataHolder
   private final InitializedProperty<Map<String, QualityProfile>> qProfilesPerLanguage = new InitializedProperty<>();
 
   @Override
-  public MutableAnalysisMetadataHolder setOrganizationUuid(String organizationUuid) {
-    checkState(!this.organizationUuid.isInitialized(), "Organization uuid has already been set");
-    requireNonNull(organizationUuid, "Organization uuid can't be null");
-    this.organizationUuid.setProperty(organizationUuid);
+  public MutableAnalysisMetadataHolder setOrganization(Organization organization) {
+    checkState(!this.organization.isInitialized(), "Organization has already been set");
+    requireNonNull(organization, "Organization can't be null");
+    this.organization.setProperty(organization);
     return this;
   }
 
   @Override
-  public String getOrganizationUuid() {
-    checkState(organizationUuid.isInitialized(), "Organization uuid has not been set");
-    return organizationUuid.getProperty();
+  public Organization getOrganization() {
+    checkState(organization.isInitialized(), "Organization has not been set");
+    return organization.getProperty();
   }
 
   @Override
index a2eb10b33624374a7e979490a5f50116bc028a22..0f235618d9c051cb0f99d9fbcd8f7d774ceb6e71 100644 (file)
@@ -28,7 +28,7 @@ public interface MutableAnalysisMetadataHolder extends AnalysisMetadataHolder {
   /**
    * @throws IllegalStateException if the organization uuid has already been set
    */
-  MutableAnalysisMetadataHolder setOrganizationUuid(String organizationUuid);
+  MutableAnalysisMetadataHolder setOrganization(Organization organization);
 
   /**
    * @throws IllegalStateException if the analysis uuid has already been set
diff --git a/server/sonar-server/src/main/java/org/sonar/server/computation/task/projectanalysis/analysis/Organization.java b/server/sonar-server/src/main/java/org/sonar/server/computation/task/projectanalysis/analysis/Organization.java
new file mode 100644 (file)
index 0000000..14c3047
--- /dev/null
@@ -0,0 +1,81 @@
+/*
+ * SonarQube
+ * Copyright (C) 2009-2016 SonarSource SA
+ * mailto:contact 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.server.computation.task.projectanalysis.analysis;
+
+import javax.annotation.concurrent.Immutable;
+import org.sonar.db.organization.OrganizationDto;
+
+import static java.util.Objects.requireNonNull;
+
+@Immutable
+public class Organization {
+  private final String uuid;
+  private final String key;
+  private final String name;
+
+  private Organization(String uuid, String key, String name) {
+    this.uuid = requireNonNull(uuid, "uuid can't be null");
+    this.key = requireNonNull(key, "key can't be null");
+    this.name = requireNonNull(name, "name can't be null");
+  }
+
+  public String getUuid() {
+    return uuid;
+  }
+
+  public String getKey() {
+    return key;
+  }
+
+  public String getName() {
+    return name;
+  }
+
+  @Override
+  public boolean equals(Object o) {
+    if (this == o) {
+      return true;
+    }
+    if (o == null || getClass() != o.getClass()) {
+      return false;
+    }
+    Organization that = (Organization) o;
+    return uuid.equals(that.uuid);
+  }
+
+  @Override
+  public int hashCode() {
+    return uuid.hashCode();
+  }
+
+  @Override
+  public String toString() {
+    return "Organization{" +
+      "uuid='" + uuid + '\'' +
+      ", key='" + key + '\'' +
+      ", name='" + name + '\'' +
+      '}';
+  }
+
+  public static Organization from(OrganizationDto organizationDto) {
+    return new Organization(organizationDto.getUuid(), organizationDto.getKey(), organizationDto.getName());
+  }
+
+}
index a462ea286af39453e7f6481a449cfd9b1ad587dd..7e5688c3aa66c0f5e60c55ee3f445f1bacebef99 100644 (file)
@@ -21,15 +21,23 @@ package org.sonar.server.computation.task.projectanalysis.step;
 
 import com.google.common.base.Function;
 import java.util.Date;
+import java.util.Optional;
+import javax.annotation.Nullable;
 import org.sonar.api.utils.MessageException;
 import org.sonar.ce.queue.CeTask;
+import org.sonar.db.DbClient;
+import org.sonar.db.DbSession;
+import org.sonar.db.organization.OrganizationDto;
 import org.sonar.scanner.protocol.output.ScannerReport;
 import org.sonar.scanner.protocol.output.ScannerReport.Metadata.QProfile;
 import org.sonar.server.computation.task.projectanalysis.analysis.MutableAnalysisMetadataHolder;
+import org.sonar.server.computation.task.projectanalysis.analysis.Organization;
 import org.sonar.server.computation.task.projectanalysis.batch.BatchReportReader;
 import org.sonar.server.computation.task.step.ComputationStep;
+import org.sonar.server.organization.DefaultOrganizationProvider;
 import org.sonar.server.qualityprofile.QualityProfile;
 
+import static com.google.common.base.Preconditions.checkState;
 import static com.google.common.collect.Maps.transformValues;
 import static java.lang.String.format;
 import static org.apache.commons.lang.StringUtils.isNotEmpty;
@@ -51,11 +59,16 @@ public class LoadReportAnalysisMetadataHolderStep implements ComputationStep {
   private final CeTask ceTask;
   private final BatchReportReader reportReader;
   private final MutableAnalysisMetadataHolder mutableAnalysisMetadataHolder;
+  private final DefaultOrganizationProvider defaultOrganizationProvider;
+  private final DbClient dbClient;
 
-  public LoadReportAnalysisMetadataHolderStep(CeTask ceTask, BatchReportReader reportReader, MutableAnalysisMetadataHolder mutableAnalysisMetadataHolder) {
+  public LoadReportAnalysisMetadataHolderStep(CeTask ceTask, BatchReportReader reportReader, MutableAnalysisMetadataHolder mutableAnalysisMetadataHolder,
+    DefaultOrganizationProvider defaultOrganizationProvider, DbClient dbClient) {
     this.ceTask = ceTask;
     this.reportReader = reportReader;
     this.mutableAnalysisMetadataHolder = mutableAnalysisMetadataHolder;
+    this.defaultOrganizationProvider = defaultOrganizationProvider;
+    this.dbClient = dbClient;
   }
 
   @Override
@@ -64,12 +77,14 @@ public class LoadReportAnalysisMetadataHolderStep implements ComputationStep {
     mutableAnalysisMetadataHolder.setAnalysisDate(reportMetadata.getAnalysisDate());
 
     checkProjectKeyConsistency(reportMetadata);
+    Organization organization = toOrganization(ceTask.getOrganizationUuid());
+    checkOrganizationKeyConsistency(reportMetadata, organization);
 
     mutableAnalysisMetadataHolder.setRootComponentRef(reportMetadata.getRootComponentRef());
     mutableAnalysisMetadataHolder.setBranch(isNotEmpty(reportMetadata.getBranch()) ? reportMetadata.getBranch() : null);
     mutableAnalysisMetadataHolder.setCrossProjectDuplicationEnabled(reportMetadata.getCrossProjectDuplicationActivated());
     mutableAnalysisMetadataHolder.setQProfilesByLanguage(transformValues(reportMetadata.getQprofilesPerLanguage(), TO_COMPUTE_QPROFILE));
-    mutableAnalysisMetadataHolder.setOrganizationUuid(ceTask.getOrganizationUuid());
+    mutableAnalysisMetadataHolder.setOrganization(organization);
   }
 
   private void checkProjectKeyConsistency(ScannerReport.Metadata reportMetadata) {
@@ -88,6 +103,43 @@ public class LoadReportAnalysisMetadataHolderStep implements ComputationStep {
     }
   }
 
+  private void checkOrganizationKeyConsistency(ScannerReport.Metadata reportMetadata, Organization organization) {
+    String organizationKey = reportMetadata.getOrganizationKey();
+    String resolveReportOrganizationKey = resolveReportOrganizationKey(organizationKey);
+    if (!resolveReportOrganizationKey.equals(organization.getKey())) {
+      if (reportBelongsToDefaultOrganization(organizationKey)) {
+        throw MessageException.of(format(
+          "Report does not specify an OrganizationKey but it has been submitted to another organization (%s) than the default one (%s)",
+          organization.getKey(),
+          defaultOrganizationProvider.get().getKey()));
+      } else {
+        throw MessageException.of(format(
+          "OrganizationKey in report (%s) is not consistent with organizationKey under which the report as been submitted (%s)",
+          resolveReportOrganizationKey,
+          organization.getKey()));
+      }
+    }
+  }
+
+  private String resolveReportOrganizationKey(@Nullable String organizationKey) {
+    if (reportBelongsToDefaultOrganization(organizationKey)) {
+      return defaultOrganizationProvider.get().getKey();
+    }
+    return organizationKey;
+  }
+
+  private static boolean reportBelongsToDefaultOrganization(@Nullable String organizationKey) {
+    return organizationKey == null || organizationKey.isEmpty();
+  }
+
+  private Organization toOrganization(String organizationUuid) {
+    try (DbSession dbSession = dbClient.openSession(false)) {
+      Optional<OrganizationDto> organizationDto = dbClient.organizationDao().selectByUuid(dbSession, organizationUuid);
+      checkState(organizationDto.isPresent(), "Organization with uuid '{}' can't be found", organizationUuid);
+      return Organization.from(organizationDto.get());
+    }
+  }
+
   private static String projectKeyFromReport(ScannerReport.Metadata reportMetadata) {
     if (isNotEmpty(reportMetadata.getBranch())) {
       return reportMetadata.getProjectKey() + ":" + reportMetadata.getBranch();
index f2aca095f74d0c0c256bcb6d8cb3803aba74be8f..d37be056897c42534f6d749437420da85a097d16 100644 (file)
@@ -348,7 +348,7 @@ public class PersistComponentsStep implements ComputationStep {
     String componentUuid = component.getUuid();
 
     ComponentDto componentDto = new ComponentDto();
-    componentDto.setOrganizationUuid(analysisMetadataHolder.getOrganizationUuid());
+    componentDto.setOrganizationUuid(analysisMetadataHolder.getOrganization().getUuid());
     componentDto.setUuid(componentUuid);
     componentDto.setKey(componentKey);
     componentDto.setDeprecatedKey(componentKey);
index cbf7871a050ed1ce531adb8b51dc334e707de394..d5cf696cc17b0fa2f8de6d42b3c0e13911d3edd5 100644 (file)
@@ -22,6 +22,7 @@ package org.sonar.server.computation.task.projectanalysis.analysis;
 import org.junit.Rule;
 import org.junit.Test;
 import org.junit.rules.ExpectedException;
+import org.sonar.db.organization.OrganizationDto;
 
 import static org.assertj.core.api.Assertions.assertThat;
 
@@ -40,29 +41,30 @@ public class AnalysisMetadataHolderImplTest {
   private AnalysisMetadataHolderImpl underTest = new AnalysisMetadataHolderImpl();
 
   @Test
-  public void getOrganizationUuid_throws_ISE_if_organization_uuid_is_not_set() {
+  public void getOrganization_throws_ISE_if_organization_is_not_set() {
     expectedException.expect(IllegalStateException.class);
-    expectedException.expectMessage("Organization uuid has not been set");
+    expectedException.expectMessage("Organization has not been set");
 
-    underTest.getOrganizationUuid();
+    underTest.getOrganization();
   }
 
   @Test
-  public void setOrganizationUuid_throws_NPE_is_parameter_is_null() {
+  public void setOrganization_throws_NPE_is_parameter_is_null() {
     expectedException.expect(NullPointerException.class);
-    expectedException.expectMessage("Organization uuid can't be null");
+    expectedException.expectMessage("Organization can't be null");
 
-    underTest.setOrganizationUuid(null);
+    underTest.setOrganization(null);
   }
 
   @Test
-  public void setOrganizationUuid_throws_ISE_if_called_twice() {
-    underTest.setOrganizationUuid("org1");
+  public void setOrganization_throws_ISE_if_called_twice() {
+    Organization organization = Organization.from(new OrganizationDto().setUuid("uuid").setKey("key").setName("name"));
+    underTest.setOrganization(organization);
 
     expectedException.expect(IllegalStateException.class);
-    expectedException.expectMessage("Organization uuid has already been set");
+    expectedException.expectMessage("Organization has already been set");
 
-    underTest.setOrganizationUuid("org1");
+    underTest.setOrganization(organization);
   }
 
   @Test
index da9e4cf68c6c9c16dca6c37205ed07daf50d0a72..5762e130723621cb0a60e35f892a1f350bffd169 100644 (file)
@@ -21,19 +21,20 @@ package org.sonar.server.computation.task.projectanalysis.analysis;
 
 import java.util.Date;
 import java.util.Map;
-import java.util.Objects;
 import javax.annotation.CheckForNull;
 import javax.annotation.Nullable;
 import org.junit.rules.ExternalResource;
+import org.sonar.db.organization.OrganizationDto;
 import org.sonar.server.computation.util.InitializedProperty;
 import org.sonar.server.qualityprofile.QualityProfile;
 
 import static com.google.common.base.Preconditions.checkNotNull;
 import static com.google.common.base.Preconditions.checkState;
+import static java.util.Objects.requireNonNull;
 
 public class AnalysisMetadataHolderRule extends ExternalResource implements MutableAnalysisMetadataHolder {
 
-  private final InitializedProperty<String> organizationUuid = new InitializedProperty<>();
+  private final InitializedProperty<Organization> organization = new InitializedProperty<>();
 
   private final InitializedProperty<String> uuid = new InitializedProperty<>();
 
@@ -50,16 +51,22 @@ public class AnalysisMetadataHolderRule extends ExternalResource implements Muta
   private final InitializedProperty<Map<String, QualityProfile>> qProfilesPerLanguage = new InitializedProperty<>();
 
   @Override
-  public AnalysisMetadataHolderRule setOrganizationUuid(String organizationUuid) {
-    Objects.requireNonNull(organizationUuid, "organizationUuid can't be null");
-    this.organizationUuid.setProperty(organizationUuid);
+  public AnalysisMetadataHolderRule setOrganization(Organization organization) {
+    requireNonNull(organization, "organization can't be null");
+    this.organization.setProperty(organization);
+    return this;
+  }
+
+  public AnalysisMetadataHolderRule setOrganizationUuid(String uuid) {
+    requireNonNull(uuid, "organization uuid can't be null");
+    this.organization.setProperty(Organization.from(new OrganizationDto().setUuid(uuid).setKey("key_" + uuid).setName("name_" + uuid)));
     return this;
   }
 
   @Override
-  public String getOrganizationUuid() {
-    checkState(organizationUuid.isInitialized(), "Organization UUID has not been set");
-    return this.organizationUuid.getProperty();
+  public Organization getOrganization() {
+    checkState(organization.isInitialized(), "Organization has not been set");
+    return this.organization.getProperty();
   }
 
   @Override
index 46a2a4b017bb2722c91341d05a86f620b387ba9f..b94948895d110e0bd732e2f78fe2a18a29429c71 100644 (file)
@@ -35,13 +35,13 @@ public class MutableAnalysisMetadataHolderRule extends ExternalResource implemen
   }
 
   @Override
-  public MutableAnalysisMetadataHolder setOrganizationUuid(String organizationUuid) {
-    return delegate.setOrganizationUuid(organizationUuid);
+  public MutableAnalysisMetadataHolder setOrganization(Organization organization) {
+    return delegate.setOrganization(organization);
   }
 
   @Override
-  public String getOrganizationUuid() {
-    return delegate.getOrganizationUuid();
+  public Organization getOrganization() {
+    return delegate.getOrganization();
   }
 
   public MutableAnalysisMetadataHolderRule setUuid(String s) {
diff --git a/server/sonar-server/src/test/java/org/sonar/server/computation/task/projectanalysis/analysis/OrganizationTest.java b/server/sonar-server/src/test/java/org/sonar/server/computation/task/projectanalysis/analysis/OrganizationTest.java
new file mode 100644 (file)
index 0000000..b0e9136
--- /dev/null
@@ -0,0 +1,104 @@
+/*
+ * SonarQube
+ * Copyright (C) 2009-2016 SonarSource SA
+ * mailto:contact 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.server.computation.task.projectanalysis.analysis;
+
+import org.junit.Rule;
+import org.junit.Test;
+import org.junit.rules.ExpectedException;
+import org.sonar.db.organization.OrganizationDto;
+
+import static org.assertj.core.api.Assertions.assertThat;
+
+public class OrganizationTest {
+  @Rule
+  public ExpectedException expectedException = ExpectedException.none();
+
+  private OrganizationDto underTest = new OrganizationDto();
+
+  @Test
+  public void build_throws_NPE_if_dto_is_null() {
+    expectedException.expect(NullPointerException.class);
+
+    Organization.from(null);
+  }
+
+  @Test
+  public void build_throws_NPE_if_uuid_is_null() {
+    expectedException.expect(NullPointerException.class);
+    expectedException.expectMessage("uuid can't be null");
+
+    Organization.from(underTest);
+  }
+
+  @Test
+  public void build_throws_NPE_if_key_is_null() {
+    underTest.setUuid("uuid");
+    
+    expectedException.expect(NullPointerException.class);
+    expectedException.expectMessage("key can't be null");
+
+    Organization.from(underTest);
+  }
+
+  @Test
+  public void build_throws_NPE_if_name_is_null() {
+    underTest.setUuid("uuid").setKey("key");
+    
+    expectedException.expect(NullPointerException.class);
+    expectedException.expectMessage("name can't be null");
+
+    Organization.from(underTest);
+  }
+
+  @Test
+  public void verify_getters() {
+    Organization organization = Organization.from(underTest.setUuid("uuid").setKey("key").setName("name"));
+
+    assertThat(organization.getUuid()).isEqualTo("uuid");
+    assertThat(organization.getKey()).isEqualTo("key");
+    assertThat(organization.getName()).isEqualTo("name");
+  }
+
+  @Test
+  public void verify_toString() {
+    Organization organization = Organization.from(underTest.setUuid("uuid").setKey("key").setName("name"));
+
+    assertThat(organization.toString()).isEqualTo("Organization{uuid='uuid', key='key', name='name'}");
+  }
+
+  @Test
+  public void equals_is_based_on_uuid_only() {
+    Organization organization = Organization.from(underTest.setUuid("uuid").setKey("key").setName("name"));
+
+    assertThat(organization).isEqualTo(Organization.from(underTest.setUuid("uuid").setKey("key").setName("name")));
+    assertThat(organization).isEqualTo(Organization.from(underTest.setUuid("uuid").setKey("other key").setName("name")));
+    assertThat(organization).isEqualTo(Organization.from(underTest.setUuid("uuid").setKey("key").setName("other name")));
+    assertThat(organization).isNotEqualTo(Organization.from(underTest.setUuid("other uuid").setKey("key").setName("name")));
+    assertThat(organization).isNotEqualTo(null);
+    assertThat(organization).isNotEqualTo("toto");
+  }
+
+  @Test
+  public void hashcode_is_based_on_uuid_only() {
+    Organization organization = Organization.from(underTest.setUuid("uuid").setKey("key").setName("name"));
+
+    assertThat(organization.hashCode()).isEqualTo("uuid".hashCode());
+  }
+}
index d8447d71b5f70f2d268aa3c2253168c90439bcbc..fd19dbb75ba18e856048be5c7da049be6f1b1067 100644 (file)
  */
 package org.sonar.server.computation.task.projectanalysis.step;
 
+import org.junit.Before;
 import org.junit.Rule;
 import org.junit.Test;
 import org.junit.rules.ExpectedException;
 import org.sonar.api.utils.MessageException;
+import org.sonar.api.utils.System2;
 import org.sonar.ce.queue.CeTask;
+import org.sonar.db.DbClient;
+import org.sonar.db.DbTester;
+import org.sonar.db.organization.OrganizationDto;
 import org.sonar.scanner.protocol.output.ScannerReport;
 import org.sonar.server.computation.task.projectanalysis.analysis.MutableAnalysisMetadataHolderRule;
+import org.sonar.server.computation.task.projectanalysis.analysis.Organization;
 import org.sonar.server.computation.task.projectanalysis.batch.BatchReportReaderRule;
 import org.sonar.server.computation.task.step.ComputationStep;
+import org.sonar.server.organization.DefaultOrganizationProvider;
+import org.sonar.server.organization.TestDefaultOrganizationProvider;
 
 import static org.assertj.core.api.Assertions.assertThat;
 import static org.mockito.Mockito.mock;
@@ -39,6 +47,8 @@ public class LoadReportAnalysisMetadataHolderStepTest {
   private static final String BRANCH = "origin/master";
   private static final long ANALYSIS_DATE = 123456789L;
 
+  @Rule
+  public DbTester dbTester = DbTester.create(System2.INSTANCE);
   @Rule
   public BatchReportReaderRule reportReader = new BatchReportReaderRule();
   @Rule
@@ -46,8 +56,15 @@ public class LoadReportAnalysisMetadataHolderStepTest {
   @Rule
   public ExpectedException expectedException = ExpectedException.none();
 
-  private CeTask ceTask = createCeTask(PROJECT_KEY);
-  private ComputationStep underTest = new LoadReportAnalysisMetadataHolderStep(ceTask, reportReader, analysisMetadataHolder);
+  private DbClient dbClient = dbTester.getDbClient();
+  private DefaultOrganizationProvider defaultOrganizationProvider = TestDefaultOrganizationProvider.from(dbTester);
+  private ComputationStep underTest;
+
+  @Before
+  public void setUp() throws Exception {
+    CeTask defaultOrgCeTask = createCeTask(PROJECT_KEY, dbTester.getDefaultOrganization().getUuid());
+    underTest = createStep(defaultOrgCeTask);
+  }
 
   @Test
   public void set_root_component_ref() throws Exception {
@@ -80,8 +97,8 @@ public class LoadReportAnalysisMetadataHolderStepTest {
         .setBranch(BRANCH)
         .build());
 
-    CeTask ceTask = createCeTask(PROJECT_KEY + ":" + BRANCH);
-    ComputationStep underTest = new LoadReportAnalysisMetadataHolderStep(ceTask, reportReader, analysisMetadataHolder);
+    CeTask ceTask = createCeTask(PROJECT_KEY + ":" + BRANCH, dbTester.getDefaultOrganization().getUuid());
+    ComputationStep underTest = createStep(ceTask);
 
     underTest.execute();
 
@@ -140,7 +157,7 @@ public class LoadReportAnalysisMetadataHolderStepTest {
     when(res.getComponentUuid()).thenReturn("prj_uuid");
     reportReader.setMetadata(ScannerReport.Metadata.newBuilder().build());
 
-    ComputationStep underTest = new LoadReportAnalysisMetadataHolderStep(res, reportReader, analysisMetadataHolder);
+    ComputationStep underTest = createStep(res);
 
     expectedException.expect(MessageException.class);
     expectedException.expectMessage("Compute Engine task component key is null. Project with UUID prj_uuid must have been deleted since report was uploaded. Can not proceed.");
@@ -177,14 +194,73 @@ public class LoadReportAnalysisMetadataHolderStepTest {
   }
 
   @Test
-  public void execute_set_organization_uuid_from_ce_task() {
+  public void execute_fails_with_MessageException_when_report_has_no_organizationKey_but_does_not_belong_to_the_default_organization() {
+    reportReader.setMetadata(
+      newBatchReportBuilder()
+        .build());
+    OrganizationDto nonDefaultOrganizationDto = dbTester.organizations().insert();
+
+    ComputationStep underTest = createStep(createCeTask(PROJECT_KEY, nonDefaultOrganizationDto.getUuid()));
+
+    expectedException.expect(MessageException.class);
+    expectedException.expectMessage("Report does not specify an OrganizationKey but it has been submitted to another organization (" +
+      nonDefaultOrganizationDto.getKey() + ") than the default one (" + dbTester.getDefaultOrganization().getKey() + ")");
+
+    underTest.execute();
+
+  }
+
+  @Test
+  public void execute_set_organization_from_ce_task_when_organizationKey_is_not_set_in_report() {
+    reportReader.setMetadata(
+      newBatchReportBuilder()
+        .build());
+
+    underTest.execute();
+
+    Organization organization = analysisMetadataHolder.getOrganization();
+    OrganizationDto defaultOrganization = dbTester.getDefaultOrganization();
+    assertThat(organization.getUuid()).isEqualTo(defaultOrganization.getUuid());
+    assertThat(organization.getKey()).isEqualTo(defaultOrganization.getKey());
+    assertThat(organization.getName()).isEqualTo(defaultOrganization.getName());
+  }
+
+  @Test
+  public void execute_set_organization_from_ce_task_when_organizationKey_is_set_in_report() {
+    reportReader.setMetadata(
+      newBatchReportBuilder()
+        .setOrganizationKey(dbTester.getDefaultOrganization().getKey())
+        .build());
+
+    underTest.execute();
+
+    Organization organization = analysisMetadataHolder.getOrganization();
+    OrganizationDto defaultOrganization = dbTester.getDefaultOrganization();
+    assertThat(organization.getUuid()).isEqualTo(defaultOrganization.getUuid());
+    assertThat(organization.getKey()).isEqualTo(defaultOrganization.getKey());
+    assertThat(organization.getName()).isEqualTo(defaultOrganization.getName());
+  }
+
+  @Test
+  public void execute_set_non_default_organization_from_ce_task() {
+    OrganizationDto nonDefaultOrganizationDto = dbTester.organizations().insert();
     reportReader.setMetadata(
       newBatchReportBuilder()
+        .setOrganizationKey(nonDefaultOrganizationDto.getKey())
         .build());
 
+    ComputationStep underTest = createStep(createCeTask(PROJECT_KEY, nonDefaultOrganizationDto.getUuid()));
+
     underTest.execute();
 
-    assertThat(analysisMetadataHolder.getOrganizationUuid()).isEqualTo(ceTask.getOrganizationUuid());
+    Organization organization = analysisMetadataHolder.getOrganization();
+    assertThat(organization.getUuid()).isEqualTo(nonDefaultOrganizationDto.getUuid());
+    assertThat(organization.getKey()).isEqualTo(nonDefaultOrganizationDto.getKey());
+    assertThat(organization.getName()).isEqualTo(nonDefaultOrganizationDto.getName());
+  }
+
+  private LoadReportAnalysisMetadataHolderStep createStep(CeTask ceTask) {
+    return new LoadReportAnalysisMetadataHolderStep(ceTask, reportReader, analysisMetadataHolder, defaultOrganizationProvider, dbClient);
   }
 
   private static ScannerReport.Metadata.Builder newBatchReportBuilder() {
@@ -192,9 +268,9 @@ public class LoadReportAnalysisMetadataHolderStepTest {
       .setProjectKey(PROJECT_KEY);
   }
 
-  private CeTask createCeTask(String projectKey) {
+  private CeTask createCeTask(String projectKey, String organizationUuid) {
     CeTask res = mock(CeTask.class);
-    when(res.getOrganizationUuid()).thenReturn("org1");
+    when(res.getOrganizationUuid()).thenReturn(organizationUuid);
     when(res.getComponentKey()).thenReturn(projectKey);
     return res;
   }
index 11cbcef29aeca39daf9f13bf2101b076beaa142e..3c6c83ddea89342ba316876564f57a714f1e14f9 100644 (file)
@@ -56,6 +56,7 @@ public class ReportPersistComponentsStepTest extends BaseStepTest {
   private static final SimpleDateFormat DATE_FORMAT = new SimpleDateFormat("yyyy-MM-dd");
   private static final String PROJECT_KEY = "PROJECT_KEY";
   private static final String MODULE_KEY = "MODULE_KEY";
+  private static final String ORGANIZATION_UUID = "org1";
 
   @Rule
   public DbTester dbTester = DbTester.create(System2.INSTANCE);
@@ -65,7 +66,7 @@ public class ReportPersistComponentsStepTest extends BaseStepTest {
   public MutableDbIdsRepositoryRule dbIdsRepository = MutableDbIdsRepositoryRule.create(treeRootHolder);
   @Rule
   public AnalysisMetadataHolderRule analysisMetadataHolder = new AnalysisMetadataHolderRule()
-    .setOrganizationUuid("org1");
+    .setOrganizationUuid(ORGANIZATION_UUID);
 
   private System2 system2 = mock(System2.class);
   private DbClient dbClient = dbTester.getDbClient();
@@ -114,7 +115,7 @@ public class ReportPersistComponentsStepTest extends BaseStepTest {
     assertThat(dbTester.countRowsOfTable("projects")).isEqualTo(4);
 
     ComponentDto projectDto = dbClient.componentDao().selectByKey(dbTester.getSession(), PROJECT_KEY).get();
-    assertThat(projectDto.getOrganizationUuid()).isEqualTo(analysisMetadataHolder.getOrganizationUuid());
+    assertThat(projectDto.getOrganizationUuid()).isEqualTo(ORGANIZATION_UUID);
     assertThat(projectDto.name()).isEqualTo("Project");
     assertThat(projectDto.description()).isEqualTo("Project description");
     assertThat(projectDto.path()).isNull();
@@ -129,7 +130,7 @@ public class ReportPersistComponentsStepTest extends BaseStepTest {
     assertThat(projectDto.getCreatedAt()).isEqualTo(now);
 
     ComponentDto moduleDto = dbClient.componentDao().selectByKey(dbTester.getSession(), MODULE_KEY).get();
-    assertThat(moduleDto.getOrganizationUuid()).isEqualTo(analysisMetadataHolder.getOrganizationUuid());
+    assertThat(moduleDto.getOrganizationUuid()).isEqualTo(ORGANIZATION_UUID);
     assertThat(moduleDto.name()).isEqualTo("Module");
     assertThat(moduleDto.description()).isEqualTo("Module description");
     assertThat(moduleDto.path()).isEqualTo("module");
@@ -144,7 +145,7 @@ public class ReportPersistComponentsStepTest extends BaseStepTest {
     assertThat(moduleDto.getCreatedAt()).isEqualTo(now);
 
     ComponentDto directoryDto = dbClient.componentDao().selectByKey(dbTester.getSession(), "MODULE_KEY:src/main/java/dir").get();
-    assertThat(directoryDto.getOrganizationUuid()).isEqualTo(analysisMetadataHolder.getOrganizationUuid());
+    assertThat(directoryDto.getOrganizationUuid()).isEqualTo(ORGANIZATION_UUID);
     assertThat(directoryDto.name()).isEqualTo("src/main/java/dir");
     assertThat(directoryDto.description()).isNull();
     assertThat(directoryDto.path()).isEqualTo("src/main/java/dir");
@@ -159,7 +160,7 @@ public class ReportPersistComponentsStepTest extends BaseStepTest {
     assertThat(directoryDto.getCreatedAt()).isEqualTo(now);
 
     ComponentDto fileDto = dbClient.componentDao().selectByKey(dbTester.getSession(), "MODULE_KEY:src/main/java/dir/Foo.java").get();
-    assertThat(fileDto.getOrganizationUuid()).isEqualTo(analysisMetadataHolder.getOrganizationUuid());
+    assertThat(fileDto.getOrganizationUuid()).isEqualTo(ORGANIZATION_UUID);
     assertThat(fileDto.name()).isEqualTo("Foo.java");
     assertThat(fileDto.description()).isNull();
     assertThat(fileDto.path()).isEqualTo("src/main/java/dir/Foo.java");
index 9ae3035e18b80c0835885ab3d5476364fcb735a2..d8fd3c2df603b594add3e8ab714ef78e0035b9d0 100644 (file)
@@ -65,6 +65,7 @@ public class ViewsPersistComponentsStepTest extends BaseStepTest {
   private static final String PROJECT_VIEW_1_KEY = "PV1_KEY";
   private static final String PROJECT_VIEW_1_NAME = "PV1_NAME";
   private static final String PROJECT_VIEW_1_UUID = "PV1_UUID";
+  private static final String ORGANIZATION_UUID = "org1";
 
   @Rule
   public DbTester dbTester = DbTester.create(System2.INSTANCE);
@@ -74,7 +75,7 @@ public class ViewsPersistComponentsStepTest extends BaseStepTest {
   public MutableDbIdsRepositoryRule dbIdsRepository = MutableDbIdsRepositoryRule.create(treeRootHolder);
   @Rule
   public AnalysisMetadataHolderRule analysisMetadataHolder = new AnalysisMetadataHolderRule()
-      .setOrganizationUuid("org1");
+      .setOrganizationUuid(ORGANIZATION_UUID);
 
   private System2 system2 = mock(System2.class);
   private DbClient dbClient = dbTester.getDbClient();
@@ -250,7 +251,7 @@ public class ViewsPersistComponentsStepTest extends BaseStepTest {
     ComponentDto project = newProjectDto();
     persistComponents(view, project);
     ComponentDto projectView = ComponentTesting.newProjectCopy(PROJECT_VIEW_1_UUID, project, view)
-      .setOrganizationUuid(analysisMetadataHolder.getOrganizationUuid())
+      .setOrganizationUuid(ORGANIZATION_UUID)
       .setKey(PROJECT_VIEW_1_KEY)
       .setName("Old name")
       .setCreatedAt(now);
@@ -336,7 +337,7 @@ public class ViewsPersistComponentsStepTest extends BaseStepTest {
 
   private ComponentDto newViewDto() {
     return ComponentTesting.newView(VIEW_UUID)
-      .setOrganizationUuid(analysisMetadataHolder.getOrganizationUuid())
+      .setOrganizationUuid(ORGANIZATION_UUID)
       .setKey(VIEW_KEY)
       .setName(VIEW_NAME);
   }
@@ -345,7 +346,7 @@ public class ViewsPersistComponentsStepTest extends BaseStepTest {
    * Assertions to verify the DTO created from {@link #createViewBuilder()}
    */
   private void assertDtoIsView(ComponentDto projectDto) {
-    assertThat(projectDto.getOrganizationUuid()).isEqualTo(analysisMetadataHolder.getOrganizationUuid());
+    assertThat(projectDto.getOrganizationUuid()).isEqualTo(ORGANIZATION_UUID);
     assertThat(projectDto.name()).isEqualTo(VIEW_NAME);
     assertThat(projectDto.longName()).isEqualTo(VIEW_NAME);
     assertThat(projectDto.description()).isEqualTo(VIEW_DESCRIPTION);
@@ -365,7 +366,7 @@ public class ViewsPersistComponentsStepTest extends BaseStepTest {
    * Assertions to verify the DTO created from {@link #createProjectView1Builder(ComponentDto, Long)}
    */
   private void assertDtoIsSubView1(ComponentDto viewDto, ComponentDto sv1Dto) {
-    assertThat(sv1Dto.getOrganizationUuid()).isEqualTo(analysisMetadataHolder.getOrganizationUuid());
+    assertThat(sv1Dto.getOrganizationUuid()).isEqualTo(ORGANIZATION_UUID);
     assertThat(sv1Dto.name()).isEqualTo(SUBVIEW_1_NAME);
     assertThat(sv1Dto.longName()).isEqualTo(SUBVIEW_1_NAME);
     assertThat(sv1Dto.description()).isEqualTo(SUBVIEW_1_DESCRIPTION);
@@ -382,7 +383,7 @@ public class ViewsPersistComponentsStepTest extends BaseStepTest {
   }
 
   private void assertDtoIsProjectView1(ComponentDto pv1Dto, ComponentDto viewDto, ComponentDto parentViewDto, ComponentDto project) {
-    assertThat(pv1Dto.getOrganizationUuid()).isEqualTo(analysisMetadataHolder.getOrganizationUuid());
+    assertThat(pv1Dto.getOrganizationUuid()).isEqualTo(ORGANIZATION_UUID);
     assertThat(pv1Dto.name()).isEqualTo(PROJECT_VIEW_1_NAME);
     assertThat(pv1Dto.longName()).isEqualTo(PROJECT_VIEW_1_NAME);
     assertThat(pv1Dto.description()).isNull();
index 970e8756171db6416de98a0a51af2dc407892f3e..b17260ca654b30feb74f7b83c8c28567a486be18 100644 (file)
@@ -84,6 +84,7 @@ import static com.google.common.collect.Lists.newArrayList;
 import static com.google.common.collect.Maps.newHashMap;
 import static java.sql.ResultSetMetaData.columnNoNulls;
 import static java.sql.ResultSetMetaData.columnNullable;
+import static org.apache.commons.lang.RandomStringUtils.randomAlphanumeric;
 import static org.assertj.core.api.Assertions.assertThat;
 import static org.junit.Assert.fail;
 
@@ -100,6 +101,7 @@ public class DbTester extends ExternalResource {
   private DbSession session = null;
   private boolean disableDefaultOrganization = false;
   private boolean started = false;
+  private String defaultOrganizationUuid = randomAlphanumeric(40);
   private OrganizationDto defaultOrganization;
 
   private final UserDbTester userTester;
@@ -163,6 +165,12 @@ public class DbTester extends ExternalResource {
     return this;
   }
 
+  public DbTester setDefaultOrganizationUuid(String uuid) {
+    checkState(!started, "DbTester is already started");
+    this.defaultOrganizationUuid = uuid;
+    return this;
+  }
+
   @Override
   protected void before() throws Throwable {
     db.start();
@@ -175,7 +183,7 @@ public class DbTester extends ExternalResource {
   }
 
   private void insertDefaultOrganization() {
-    defaultOrganization = OrganizationTesting.newOrganizationDto();
+    defaultOrganization = OrganizationTesting.newOrganizationDto().setUuid(defaultOrganizationUuid);
     try (DbSession dbSession = db.getMyBatis().openSession(false)) {
       client.organizationDao().insert(dbSession, defaultOrganization);
       client.internalPropertiesDao().save(dbSession, "organization.default", defaultOrganization.getUuid());