Browse Source

SONAR-13941 Move and adapt application CE processor

tags/8.6.0.39681
Zipeng WU 3 years ago
parent
commit
7ce287cb9e

+ 7
- 7
server/sonar-ce-task-projectanalysis/src/main/java/org/sonar/ce/task/projectanalysis/step/TriggerViewRefreshStep.java View File

@@ -30,8 +30,8 @@ import org.sonar.ce.task.step.ComputationStep;
*/
public class TriggerViewRefreshStep implements ComputationStep {

@Nullable
private final TriggerViewRefreshDelegate triggerViewRefreshDelegate;
private final TriggerViewRefreshDelegate[] triggerViewRefreshDelegates;
private final AnalysisMetadataHolder analysisMetadata;

/**
@@ -39,15 +39,15 @@ public class TriggerViewRefreshStep implements ComputationStep {
*/
public TriggerViewRefreshStep(AnalysisMetadataHolder analysisMetadata) {
this.analysisMetadata = analysisMetadata;
this.triggerViewRefreshDelegate = null;
this.triggerViewRefreshDelegates = new TriggerViewRefreshDelegate[0];
}

/**
* Constructor used by Pico when an implementation of {@link TriggerViewRefreshDelegate} is available
*/
public TriggerViewRefreshStep(AnalysisMetadataHolder analysisMetadata, @Nullable TriggerViewRefreshDelegate triggerViewRefreshDelegate) {
public TriggerViewRefreshStep(AnalysisMetadataHolder analysisMetadata, TriggerViewRefreshDelegate[] triggerViewRefreshDelegates) {
this.analysisMetadata = analysisMetadata;
this.triggerViewRefreshDelegate = triggerViewRefreshDelegate;
this.triggerViewRefreshDelegates = triggerViewRefreshDelegates;
}

@Override
@@ -57,9 +57,9 @@ public class TriggerViewRefreshStep implements ComputationStep {

@Override
public void execute(ComputationStep.Context context) {
if (triggerViewRefreshDelegate != null) {
for (TriggerViewRefreshDelegate triggerViewRefreshDelegate : this.triggerViewRefreshDelegates) {
OptionalInt count = triggerViewRefreshDelegate.triggerFrom(analysisMetadata.getProject());
count.ifPresent(i -> context.getStatistics().add("refreshes", i));
count.ifPresent(i -> context.getStatistics().add("refreshes" + triggerViewRefreshDelegate.getQualifier(), i));
}
}
}

+ 2
- 0
server/sonar-ce-task-projectanalysis/src/main/java/org/sonar/ce/task/projectanalysis/view/TriggerViewRefreshDelegate.java View File

@@ -33,4 +33,6 @@ public interface TriggerViewRefreshDelegate {
*/
OptionalInt triggerFrom(Project project);

String getQualifier();

}

+ 2
- 2
server/sonar-ce-task-projectanalysis/src/test/java/org/sonar/ce/task/projectanalysis/step/TriggerViewRefreshStepTest.java View File

@@ -44,7 +44,7 @@ public class TriggerViewRefreshStepTest {

@Test
public void execute_has_no_effect_if_constructor_with_null_delegate() {
TriggerViewRefreshStep underTest = new TriggerViewRefreshStep(analysisMetadataHolder, null);
TriggerViewRefreshStep underTest = new TriggerViewRefreshStep(analysisMetadataHolder);

underTest.execute(new TestComputationStepContext());

@@ -56,7 +56,7 @@ public class TriggerViewRefreshStepTest {
TriggerViewRefreshDelegate delegate = mock(TriggerViewRefreshDelegate.class);
Project project = mock(Project.class);
when(analysisMetadataHolder.getProject()).thenReturn(project);
TriggerViewRefreshStep underTest = new TriggerViewRefreshStep(analysisMetadataHolder, delegate);
TriggerViewRefreshStep underTest = new TriggerViewRefreshStep(analysisMetadataHolder, new TriggerViewRefreshDelegate[]{delegate});

underTest.execute(new TestComputationStepContext());


+ 38
- 0
server/sonar-ce-task-projectanalysis/src/testFixtures/java/org/sonar/ce/task/projectanalysis/component/TreeRootHolderRule.java View File

@@ -19,12 +19,22 @@
*/
package org.sonar.ce.task.projectanalysis.component;

import com.google.common.collect.ImmutableMap;
import java.util.Map;
import java.util.Optional;
import javax.annotation.CheckForNull;
import org.junit.rules.ExternalResource;

import static com.google.common.base.Preconditions.checkArgument;
import static java.util.Objects.requireNonNull;
import static org.sonar.ce.task.projectanalysis.component.ComponentVisitor.Order.POST_ORDER;

public class TreeRootHolderRule extends ExternalResource implements TreeRootHolder {
protected TreeRootHolderImpl delegate = new TreeRootHolderImpl();

@CheckForNull
private Map<String, Component> componentsByKey;

@Override
protected void after() {
this.delegate = null;
@@ -40,6 +50,34 @@ public class TreeRootHolderRule extends ExternalResource implements TreeRootHold
return this;
}

public Component getComponentByKey(String key) {
checkKeyArgument(key);
ensureComponentByKeyIsPopulated();
Component component = componentsByKey.get(key);
checkArgument(component != null, "Component with key '%s' can't be found", key);
return component;
}

private static void checkKeyArgument(String key) {
requireNonNull(key, "key can not be null");
}

private void ensureComponentByKeyIsPopulated() {
if (componentsByKey != null) {
return;
}

final ImmutableMap.Builder<String, Component> builder = ImmutableMap.builder();
new DepthTraversalTypeAwareCrawler(
new TypeAwareVisitorAdapter(CrawlerDepthLimit.LEAVES, POST_ORDER) {
@Override
public void visitAny(Component component) {
builder.put(component.getDbKey(), component);
}
}).visit(getRoot());
this.componentsByKey = builder.build();
}

@Override
public boolean isEmpty() {
return delegate.isEmpty();

+ 10
- 2
server/sonar-db-dao/src/testFixtures/java/org/sonar/db/component/ComponentTesting.java View File

@@ -195,9 +195,17 @@ public class ComponentTesting {
return newApplication(organizationDto.getUuid());
}

public static ComponentDto newApplication(OrganizationDto organizationDto, String uuid) {
return newApplication(organizationDto.getUuid(), uuid);
}


public static ComponentDto newApplication(String organizationUuid) {
return newView(organizationUuid, Uuids.createFast())
.setQualifier(Qualifiers.APP);
return newApplication(organizationUuid, Uuids.createFast());
}

public static ComponentDto newApplication(String organizationUuid, String uuid) {
return newView(organizationUuid, uuid).setQualifier(Qualifiers.APP);
}

public static ComponentDto newProjectCopy(ComponentDto project, ComponentDto view) {

+ 1
- 0
server/sonar-webserver-webapi/src/main/java/org/sonar/server/component/ws/SearchProjectsAction.java View File

@@ -334,6 +334,7 @@ public class SearchProjectsAction implements ComponentsWsAction {
switch (edition.get()) {
case ENTERPRISE:
case DATACENTER:
case DEVELOPER:
return Sets.newHashSet(Qualifiers.PROJECT, Qualifiers.APP);
default:
return Sets.newHashSet(Qualifiers.PROJECT);

+ 18
- 7
server/sonar-webserver-webapi/src/main/java/org/sonar/server/permission/DefaultTemplatesResolverImpl.java View File

@@ -41,20 +41,31 @@ public class DefaultTemplatesResolverImpl implements DefaultTemplatesResolver {
String defaultProjectTemplate = dbClient.internalPropertiesDao().selectByKey(dbSession, InternalProperties.DEFAULT_PROJECT_TEMPLATE).orElseThrow(() -> {
throw new IllegalStateException("Default template for project is missing");
});
if (!isPortfolioEnabled(resourceTypes)) {
return new ResolvedDefaultTemplates(defaultProjectTemplate, null, null);
} else {
String defaultPortfolioTemplate = dbClient.internalPropertiesDao().selectByKey(dbSession, InternalProperties.DEFAULT_PORTFOLIO_TEMPLATE).orElse(defaultProjectTemplate);
String defaultApplicationTemplate = dbClient.internalPropertiesDao().selectByKey(dbSession, InternalProperties.DEFAULT_APPLICATION_TEMPLATE).orElse(defaultProjectTemplate);
return new ResolvedDefaultTemplates(defaultProjectTemplate, defaultApplicationTemplate, defaultPortfolioTemplate);

String defaultPortfolioTemplate = null;
String defaultApplicationTemplate = null;

if (isPortfolioEnabled(resourceTypes)) {
defaultPortfolioTemplate = dbClient.internalPropertiesDao().selectByKey(dbSession, InternalProperties.DEFAULT_PORTFOLIO_TEMPLATE).orElse(defaultProjectTemplate);
}
if (isApplicationEnabled(resourceTypes)) {
defaultApplicationTemplate = dbClient.internalPropertiesDao().selectByKey(dbSession, InternalProperties.DEFAULT_APPLICATION_TEMPLATE).orElse(defaultProjectTemplate);
}
return new ResolvedDefaultTemplates(defaultProjectTemplate, defaultApplicationTemplate, defaultPortfolioTemplate);
}

private static boolean isPortfolioEnabled(ResourceTypes resourceTypes) {
return resourceTypes.getRoots()
.stream()
.map(ResourceType::getQualifier)
.anyMatch(qualifier -> Qualifiers.VIEW.equals(qualifier) || Qualifiers.APP.equals(qualifier));
.anyMatch(qualifier -> Qualifiers.VIEW.equals(qualifier));
}

private static boolean isApplicationEnabled(ResourceTypes resourceTypes) {
return resourceTypes.getRoots()
.stream()
.map(ResourceType::getQualifier)
.anyMatch(qualifier -> Qualifiers.APP.equals(qualifier));
}

}

+ 1
- 1
server/sonar-webserver-webapi/src/test/java/org/sonar/server/component/ws/SearchProjectsActionTest.java View File

@@ -142,7 +142,7 @@ public class SearchProjectsActionTest {
public static Object[][] component_qualifiers_for_valid_editions() {
return new Object[][] {
{new String[] {Qualifiers.PROJECT}, Edition.COMMUNITY},
{new String[] {Qualifiers.PROJECT}, Edition.DEVELOPER},
{new String[] {Qualifiers.APP, Qualifiers.PROJECT}, Edition.DEVELOPER},
{new String[] {Qualifiers.APP, Qualifiers.PROJECT}, Edition.ENTERPRISE},
{new String[] {Qualifiers.APP, Qualifiers.PROJECT}, Edition.DATACENTER},
};

+ 20
- 0
server/sonar-webserver-webapi/src/test/java/org/sonar/server/permission/DefaultTemplatesResolverImplTest.java View File

@@ -38,9 +38,11 @@ public class DefaultTemplatesResolverImplTest {
public DbTester db = DbTester.create(System2.INSTANCE);

private ResourceTypesRule resourceTypesWithPortfoliosInstalled = new ResourceTypesRule().setRootQualifiers(PROJECT, APP, VIEW);
private ResourceTypesRule resourceTypesWithApplicationInstalled = new ResourceTypesRule().setRootQualifiers(PROJECT, APP);
private ResourceTypesRule resourceTypes = new ResourceTypesRule().setRootQualifiers(PROJECT);

private DefaultTemplatesResolverImpl underTestWithPortfoliosInstalled = new DefaultTemplatesResolverImpl(db.getDbClient(), resourceTypesWithPortfoliosInstalled);
private DefaultTemplatesResolverImpl underTestWithApplicationInstalled = new DefaultTemplatesResolverImpl(db.getDbClient(), resourceTypesWithApplicationInstalled);
private DefaultTemplatesResolverImpl underTest = new DefaultTemplatesResolverImpl(db.getDbClient(), resourceTypes);

@Test
@@ -79,6 +81,24 @@ public class DefaultTemplatesResolverImplTest {
assertThat(underTestWithPortfoliosInstalled.resolve(db.getSession()).getPortfolio()).contains("port");
}

@Test
public void get_default_templates_always_return_project_template_when_only_project_template_and_application_is_installed_() {
db.permissionTemplates().setDefaultTemplates("prj", null, null);

assertThat(underTestWithApplicationInstalled.resolve(db.getSession()).getProject()).contains("prj");
assertThat(underTestWithApplicationInstalled.resolve(db.getSession()).getApplication()).contains("prj");
assertThat(underTestWithApplicationInstalled.resolve(db.getSession()).getPortfolio()).isEmpty();
}

@Test
public void get_default_templates_for_all_components_when_application_is_installed() {
db.permissionTemplates().setDefaultTemplates("prj", "app", null);

assertThat(underTestWithApplicationInstalled.resolve(db.getSession()).getProject()).contains("prj");
assertThat(underTestWithApplicationInstalled.resolve(db.getSession()).getApplication()).contains("app");
assertThat(underTestWithApplicationInstalled.resolve(db.getSession()).getPortfolio()).isEmpty();
}

@Test
public void fail_when_default_template_for_project_is_missing() {
DbSession session = db.getSession();

Loading…
Cancel
Save