Browse Source

SONAR-12398 make schedule refresh of porfolios work

tags/8.0
Sébastien Lesaint 4 years ago
parent
commit
bb7e74da6d

+ 15
- 4
server/sonar-db-dao/src/main/java/org/sonar/db/property/InternalPropertiesDao.java View File

@@ -46,9 +46,11 @@ public class InternalPropertiesDao implements Dao {
/**
* A common prefix used by locks. {@see InternalPropertiesDao#tryLock}
*/
public static final String LOCK_PREFIX = "lock.";
private static final String LOCK_PREFIX = "lock.";

private static final int KEY_MAX_LENGTH = 20;
public static final int LOCK_NAME_MAX_LENGTH = KEY_MAX_LENGTH - LOCK_PREFIX.length();

static final int KEY_MAX_LENGTH = 20;
private static final int TEXT_VALUE_MAX_LENGTH = 4000;
private static final Optional<String> OPTIONAL_OF_EMPTY_STRING = Optional.of("");

@@ -190,13 +192,22 @@ public class InternalPropertiesDao implements Dao {
* and the atomic replacement of the timestamp succeeds.
*
* The lock is considered released when the specified duration has elapsed.
*
* @throws IllegalArgumentException if name's length is > {@link #LOCK_NAME_MAX_LENGTH}
* @throws IllegalArgumentException if maxAgeInSeconds is <= 0
*/
public boolean tryLock(DbSession dbSession, String name, int maxAgeInSeconds) {
String key = LOCK_PREFIX + '.' + name;
if (key.length() > KEY_MAX_LENGTH) {
if (name.isEmpty()) {
throw new IllegalArgumentException("lock name can't be empty");
}
if (name.length() > LOCK_NAME_MAX_LENGTH) {
throw new IllegalArgumentException("lock name is too long");
}
if (maxAgeInSeconds <= 0) {
throw new IllegalArgumentException("maxAgeInSeconds must be > 0");
}

String key = LOCK_PREFIX + name;
long now = system2.now();

Optional<String> timestampAsStringOpt = selectByKey(dbSession, key);

+ 25
- 18
server/sonar-db-dao/src/test/java/org/sonar/db/property/InternalPropertiesDaoTest.java View File

@@ -54,8 +54,6 @@ import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.verifyNoMoreInteractions;
import static org.mockito.Mockito.when;
import static org.sonar.db.property.InternalPropertiesDao.KEY_MAX_LENGTH;
import static org.sonar.db.property.InternalPropertiesDao.LOCK_PREFIX;

public class InternalPropertiesDaoTest {

@@ -409,7 +407,7 @@ public class InternalPropertiesDaoTest {
when(system2.now()).thenReturn(now);
assertThat(underTest.tryLock(dbSession, A_KEY, 60)).isTrue();

assertThat(underTest.selectByKey(dbSession, key(A_KEY))).contains(String.valueOf(now));
assertThat(underTest.selectByKey(dbSession, propertyKeyOf(A_KEY))).contains(String.valueOf(now));
}

@Test
@@ -424,7 +422,7 @@ public class InternalPropertiesDaoTest {
when(system2.now()).thenReturn(now);
assertThat(underTest.tryLock(dbSession, A_KEY, lockDurationSeconds)).isTrue();

assertThat(underTest.selectByKey(dbSession, key(A_KEY))).contains(String.valueOf(now));
assertThat(underTest.selectByKey(dbSession, propertyKeyOf(A_KEY))).contains(String.valueOf(now));
}

@Test
@@ -434,13 +432,13 @@ public class InternalPropertiesDaoTest {
assertThat(underTest.tryLock(dbSession, A_KEY, 60)).isTrue();
assertThat(underTest.tryLock(dbSession, A_KEY, 60)).isFalse();

assertThat(underTest.selectByKey(dbSession, key(A_KEY))).contains(String.valueOf(now));
assertThat(underTest.selectByKey(dbSession, propertyKeyOf(A_KEY))).contains(String.valueOf(now));
}

@Test
public void tryLock_fails_if_it_would_insert_concurrently() {
String name = randomAlphabetic(5);
String key = key(name);
String propertyKey = propertyKeyOf(name);

long now = new Random().nextInt();
when(system2.now()).thenReturn(now);
@@ -449,22 +447,22 @@ public class InternalPropertiesDaoTest {
InternalPropertiesMapper mapperMock = mock(InternalPropertiesMapper.class);
DbSession dbSessionMock = mock(DbSession.class);
when(dbSessionMock.getMapper(InternalPropertiesMapper.class)).thenReturn(mapperMock);
when(mapperMock.selectAsText(ImmutableList.of(key)))
when(mapperMock.selectAsText(ImmutableList.of(propertyKey)))
.thenReturn(ImmutableList.of());
doThrow(RuntimeException.class).when(mapperMock).insertAsText(eq(key), anyString(), anyLong());
doThrow(RuntimeException.class).when(mapperMock).insertAsText(eq(propertyKey), anyString(), anyLong());

assertThat(underTest.tryLock(dbSessionMock, name, 60)).isFalse();

assertThat(underTest.selectByKey(dbSession, key)).contains(String.valueOf(now));
assertThat(underTest.selectByKey(dbSession, propertyKey)).contains(String.valueOf(now));
}

@Test
public void tryLock_fails_if_concurrent_caller_succeeded_first() {
int lockDurationSeconds = 60;
String name = randomAlphabetic(5);
String key = key(name);
String propertyKey = propertyKeyOf(name);

long now = 123456;//new Random().nextInt();
long now = new Random().nextInt(4_889_989);
long oldTimestamp = now - lockDurationSeconds * 1000;
when(system2.now()).thenReturn(oldTimestamp);
assertThat(underTest.tryLock(dbSession, name, lockDurationSeconds)).isTrue();
@@ -474,27 +472,36 @@ public class InternalPropertiesDaoTest {
DbSession dbSessionMock = mock(DbSession.class);
when(dbSessionMock.getMapper(InternalPropertiesMapper.class)).thenReturn(mapperMock);
InternalPropertyDto dto = new InternalPropertyDto();
dto.setKey(key);
dto.setKey(propertyKey);
dto.setValue(String.valueOf(oldTimestamp - 1));
when(mapperMock.selectAsText(ImmutableList.of(key)))
when(mapperMock.selectAsText(ImmutableList.of(propertyKey)))
.thenReturn(ImmutableList.of(dto));

assertThat(underTest.tryLock(dbSessionMock, name, lockDurationSeconds)).isFalse();

assertThat(underTest.selectByKey(dbSession, key)).contains(String.valueOf(oldTimestamp));
assertThat(underTest.selectByKey(dbSession, propertyKey)).contains(String.valueOf(oldTimestamp));
}

@Test
public void tryLock_throws_if_lock_name_would_produce_too_long_key() {
String tooLongName = randomAlphabetic(KEY_MAX_LENGTH - LOCK_PREFIX.length());
public void tryLock_throws_IAE_if_lock_name_is_empty() {
expectedException.expect(IllegalArgumentException.class);
expectedException.expectMessage("lock name can't be empty");

underTest.tryLock(dbSession, "", 60);
}

@Test
public void tryLock_throws_IAE_if_lock_name_length_is_16_or_more() {
String tooLongName = randomAlphabetic(16 + new Random().nextInt(30));

expectedException.expect(IllegalArgumentException.class);
expectedException.expectMessage("lock name is too long");

underTest.tryLock(dbSession, tooLongName, 60);
}

private String key(String name) {
return LOCK_PREFIX + '.' + name;
private static String propertyKeyOf(String lockName) {
return "lock." + lockName;
}

private void expectKeyNullOrEmptyIAE() {

+ 4
- 0
server/sonar-webserver-api/build.gradle View File

@@ -37,4 +37,8 @@ dependencies {
testCompile 'org.mockito:mockito-core'
testCompile testFixtures(project(':server:sonar-server-common'))
testCompile project(':sonar-testing-harness')

testFixturesApi 'junit:junit'

testFixturesCompileOnly 'com.google.code.findbugs:jsr305'
}

+ 15
- 30
server/sonar-webserver-api/src/main/java/org/sonar/server/util/GlobalLockManager.java View File

@@ -19,41 +19,26 @@
*/
package org.sonar.server.util;

import org.sonar.api.ce.ComputeEngineSide;
import org.sonar.api.server.ServerSide;
import org.sonar.db.DbClient;
import org.sonar.db.DbSession;
import org.sonar.db.property.InternalPropertiesDao;

/**
* Provide a simple mechanism to manage global locks across multiple nodes running in a cluster.
* In the target use case multiple nodes try to execute something at around the same time,
* and only the first should succeed, and the rest do nothing.
*/
@ComputeEngineSide
@ServerSide
public class GlobalLockManager {

static final int DEFAULT_LOCK_DURATION_SECONDS = 180;

private final DbClient dbClient;
public interface GlobalLockManager {

public GlobalLockManager(DbClient dbClient) {
this.dbClient = dbClient;
}
int LOCK_NAME_MAX_LENGTH = InternalPropertiesDao.LOCK_NAME_MAX_LENGTH;
int DEFAULT_LOCK_DURATION_SECONDS = 180;

/**
* Try to acquire a lock on the given name in the default namespace,
* Try to acquire a lock on the given name for the {@link #DEFAULT_LOCK_DURATION_SECONDS default duration},
* using the generic locking mechanism of {@see org.sonar.db.property.InternalPropertiesDao}.
*
* @throws IllegalArgumentException if name's length is > {@link #LOCK_NAME_MAX_LENGTH} or empty
*/
public boolean tryLock(String name) {
return tryLock(name, DEFAULT_LOCK_DURATION_SECONDS);
}
boolean tryLock(String name);

public boolean tryLock(String name, int durationSecond) {
try (DbSession dbSession = dbClient.openSession(false)) {
boolean success = dbClient.internalPropertiesDao().tryLock(dbSession, name, durationSecond);
dbSession.commit();
return success;
}
}
/**
* Try to acquire a lock on the given name for the specified duration,
* using the generic locking mechanism of {@see org.sonar.db.property.InternalPropertiesDao}.
*
* @throws IllegalArgumentException if name's length is > {@link #LOCK_NAME_MAX_LENGTH} or empty
*/
boolean tryLock(String name, int durationSecond);
}

+ 63
- 0
server/sonar-webserver-api/src/main/java/org/sonar/server/util/GlobalLockManagerImpl.java View File

@@ -0,0 +1,63 @@
/*
* SonarQube
* Copyright (C) 2009-2019 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.server.util;

import org.sonar.api.ce.ComputeEngineSide;
import org.sonar.api.server.ServerSide;
import org.sonar.db.DbClient;
import org.sonar.db.DbSession;
import org.sonar.db.property.InternalPropertiesDao;

import static org.sonar.api.utils.Preconditions.checkArgument;

/**
* Provide a simple mechanism to manage global locks across multiple nodes running in a cluster.
* In the target use case multiple nodes try to execute something at around the same time,
* and only the first should succeed, and the rest do nothing.
*/
@ComputeEngineSide
@ServerSide
public class GlobalLockManagerImpl implements GlobalLockManager {

private final DbClient dbClient;

public GlobalLockManagerImpl(DbClient dbClient) {
this.dbClient = dbClient;
}

@Override
public boolean tryLock(String name) {
return tryLock(name, DEFAULT_LOCK_DURATION_SECONDS);
}

@Override
public boolean tryLock(String name, int durationSecond) {
checkArgument(
!name.isEmpty() && name.length() <= LOCK_NAME_MAX_LENGTH,
"name's length must be > 0 and <= %s: '%s'", LOCK_NAME_MAX_LENGTH, name);
checkArgument(durationSecond > 0, "duration must be > 0: %s", durationSecond);

try (DbSession dbSession = dbClient.openSession(false)) {
boolean success = dbClient.internalPropertiesDao().tryLock(dbSession, name, durationSecond);
dbSession.commit();
return success;
}
}
}

+ 189
- 0
server/sonar-webserver-api/src/test/java/org/sonar/server/util/GlobalLockManagerImplTest.java View File

@@ -0,0 +1,189 @@
/*
* SonarQube
* Copyright (C) 2009-2019 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.server.util;

import com.tngtech.java.junit.dataprovider.DataProvider;
import com.tngtech.java.junit.dataprovider.DataProviderRunner;
import com.tngtech.java.junit.dataprovider.UseDataProvider;
import java.util.Random;
import org.apache.commons.lang.RandomStringUtils;
import org.junit.Before;
import org.junit.Rule;
import org.junit.Test;
import org.junit.rules.ExpectedException;
import org.junit.runner.RunWith;
import org.sonar.db.DbClient;
import org.sonar.db.DbSession;
import org.sonar.db.property.InternalPropertiesDao;

import static org.apache.commons.lang.RandomStringUtils.randomAlphabetic;
import static org.assertj.core.api.Assertions.assertThat;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.verifyNoMoreInteractions;
import static org.mockito.Mockito.when;
import static org.sonar.server.util.GlobalLockManager.DEFAULT_LOCK_DURATION_SECONDS;

@RunWith(DataProviderRunner.class)
public class GlobalLockManagerImplTest {

private static final int LOCK_NAME_MAX_LENGTH = 15;

@Rule
public ExpectedException expectedException = ExpectedException.none();

private final DbClient dbClient = mock(DbClient.class);
private final InternalPropertiesDao internalPropertiesDao = mock(InternalPropertiesDao.class);
private final DbSession dbSession = mock(DbSession.class);
private final GlobalLockManager underTest = new GlobalLockManagerImpl(dbClient);

@Before
public void wire_db_mocks() {
when(dbClient.openSession(false)).thenReturn(dbSession);
when(dbClient.internalPropertiesDao()).thenReturn(internalPropertiesDao);
}

@Test
public void tryLock_fails_with_IAE_if_name_is_empty() {
String badLockName = "";

expectBadLockNameIAE(badLockName);

underTest.tryLock(badLockName);
}

@Test
public void tryLock_fails_with_IAE_if_name_length_is_16_or_more() {
String badLockName = RandomStringUtils.random(LOCK_NAME_MAX_LENGTH + 1 + new Random().nextInt(96));

expectBadLockNameIAE(badLockName);

underTest.tryLock(badLockName);
}

@Test
public void tryLock_accepts_name_with_length_15_or_less() {
for (int i = 1; i <= LOCK_NAME_MAX_LENGTH; i++) {
underTest.tryLock(RandomStringUtils.random(i));
}
}

@Test
@UseDataProvider("randomValidLockName")
public void tryLock_delegates_to_internalPropertiesDao_and_commits(String randomValidLockName) {
boolean expected = new Random().nextBoolean();
when(internalPropertiesDao.tryLock(dbSession, randomValidLockName, DEFAULT_LOCK_DURATION_SECONDS))
.thenReturn(expected);

assertThat(underTest.tryLock(randomValidLockName)).isEqualTo(expected);

verify(dbClient).openSession(false);
verify(internalPropertiesDao).tryLock(dbSession, randomValidLockName, DEFAULT_LOCK_DURATION_SECONDS);
verify(dbSession).commit();
verifyNoMoreInteractions(internalPropertiesDao);
}

@Test
@UseDataProvider("randomValidDuration")
public void tryLock_with_duration_fails_with_IAE_if_name_is_empty(int randomValidDuration) {
String badLockName = "";

expectBadLockNameIAE(badLockName);

underTest.tryLock(badLockName, randomValidDuration);
}

@Test
@UseDataProvider("randomValidDuration")
public void tryLock_with_duration_accepts_name_with_length_15_or_less(int randomValidDuration) {
for (int i = 1; i <= 15; i++) {
underTest.tryLock(RandomStringUtils.random(i), randomValidDuration);
}
}

@Test
@UseDataProvider("randomValidDuration")
public void tryLock_with_duration_fails_with_IAE_if_name_length_is_16_or_more(int randomValidDuration) {
String badLockName = RandomStringUtils.random(LOCK_NAME_MAX_LENGTH + 1 + new Random().nextInt(65));

expectBadLockNameIAE(badLockName);

underTest.tryLock(badLockName, randomValidDuration);
}

@Test
@UseDataProvider("randomValidLockName")
public void tryLock_with_duration_fails_with_IAE_if_duration_is_0(String randomValidLockName) {
expectBadDuration(0);

underTest.tryLock(randomValidLockName, 0);
}

@Test
@UseDataProvider("randomValidLockName")
public void tryLock_with_duration_fails_with_IAE_if_duration_is_less_than_0(String randomValidLockName) {
int negativeDuration = -1 - new Random().nextInt(100);

expectBadDuration(negativeDuration);

underTest.tryLock(randomValidLockName, negativeDuration);
}

@Test
@UseDataProvider("randomValidDuration")
public void tryLock_with_duration_delegates_to_InternalPropertiesDao_and_commits(int randomValidDuration) {
String lockName = "foo";
boolean expected = new Random().nextBoolean();
when(internalPropertiesDao.tryLock(dbSession, lockName, randomValidDuration))
.thenReturn(expected);

assertThat(underTest.tryLock(lockName, randomValidDuration)).isEqualTo(expected);

verify(dbClient).openSession(false);
verify(internalPropertiesDao).tryLock(dbSession, lockName, randomValidDuration);
verify(dbSession).commit();
verifyNoMoreInteractions(internalPropertiesDao);
}

@DataProvider
public static Object[][] randomValidLockName() {
return new Object[][] {
{randomAlphabetic(1 + new Random().nextInt(LOCK_NAME_MAX_LENGTH))}
};
}

@DataProvider
public static Object[][] randomValidDuration() {
return new Object[][] {
{1+ new Random().nextInt(2_00)}
};
}

private void expectBadLockNameIAE(String badLockName) {
expectedException.expect(IllegalArgumentException.class);
expectedException.expectMessage("name's length must be > 0 and <= " + LOCK_NAME_MAX_LENGTH + ": '" + badLockName + "'");
}

private void expectBadDuration(int badDuration) {
expectedException.expect(IllegalArgumentException.class);
expectedException.expectMessage("duration must be > 0: " + badDuration);
}

}

+ 0
- 76
server/sonar-webserver-api/src/test/java/org/sonar/server/util/GlobalLockManagerTest.java View File

@@ -1,76 +0,0 @@
/*
* SonarQube
* Copyright (C) 2009-2019 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.server.util;

import org.junit.Rule;
import org.junit.Test;
import org.sonar.api.utils.System2;
import org.sonar.db.DbTester;

import static org.assertj.core.api.Assertions.assertThat;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.when;
import static org.sonar.server.util.GlobalLockManager.DEFAULT_LOCK_DURATION_SECONDS;

public class GlobalLockManagerTest {

private final System2 system2 = mock(System2.class);

@Rule
public final DbTester dbTester = DbTester.create(system2);

private final GlobalLockManager underTest = new GlobalLockManager(dbTester.getDbClient());

@Test
public void tryLock_succeeds_when_created_for_the_first_time() {
assertThat(underTest.tryLock("newName")).isTrue();
}

@Test
public void tryLock_fails_when_previous_lock_is_too_recent() {
String name = "newName";
assertThat(underTest.tryLock(name)).isTrue();
assertThat(underTest.tryLock(name)).isFalse();
}

@Test
public void tryLock_succeeds_when_previous_lock_is_old_enough() {
String name = "newName";
long firstLock = 0;
long longEnoughAfterFirstLock = firstLock + DEFAULT_LOCK_DURATION_SECONDS * 1000;
long notLongEnoughAfterFirstLock = longEnoughAfterFirstLock - 1;

when(system2.now()).thenReturn(firstLock);
assertThat(underTest.tryLock(name)).isTrue();

when(system2.now()).thenReturn(notLongEnoughAfterFirstLock);
assertThat(underTest.tryLock(name)).isFalse();

when(system2.now()).thenReturn(longEnoughAfterFirstLock);
assertThat(underTest.tryLock(name)).isTrue();
}

@Test
public void locks_with_different_name_are_independent() {
assertThat(underTest.tryLock("newName1")).isTrue();
assertThat(underTest.tryLock("newName2")).isTrue();
}

}

+ 66
- 0
server/sonar-webserver-api/src/testFixtures/java/org/sonar/server/util/GlobalLockManagerRule.java View File

@@ -0,0 +1,66 @@
/*
* SonarQube
* Copyright (C) 2009-2019 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.server.util;

import java.util.ArrayDeque;
import java.util.Deque;
import java.util.HashMap;
import java.util.Map;
import org.junit.Test;
import org.junit.rules.ExternalResource;

import static org.sonar.api.utils.Preconditions.checkArgument;

/**
* {@link org.junit.Rule} implementing {@link GlobalLockManager} to test against this interface without consideration
* of time, only attempts to acquire a given lock.
*/
public class GlobalLockManagerRule extends ExternalResource implements GlobalLockManager {
private final Map<String, Deque<Boolean>> lockAttemptsByLockName = new HashMap<>();

@Test
public GlobalLockManagerRule addAttempt(String lockName, boolean success) {
lockAttemptsByLockName.compute(lockName, (k, v) -> {
Deque<Boolean> queue = v == null ? new ArrayDeque<>() : v;
queue.push(success);
return queue;
});
return this;
}

@Override
public boolean tryLock(String name) {
checkArgument(!name.isEmpty() && name.length() <= LOCK_NAME_MAX_LENGTH, "invalid lock name");

Deque<Boolean> deque = lockAttemptsByLockName.get(name);
Boolean res = deque == null ? null : deque.pop();
if (res == null) {
throw new IllegalStateException("No more attempt value available");
}
return res;
}

@Override
public boolean tryLock(String name, int durationSecond) {
checkArgument(durationSecond > 0, "negative duration not allowed");

return tryLock(name);
}
}

+ 2
- 1
server/sonar-webserver-core/src/test/java/org/sonar/server/qualitygate/ProjectsInWarningDaemonTest.java View File

@@ -39,6 +39,7 @@ import org.sonar.server.measure.index.ProjectMeasuresIndexer;
import org.sonar.server.permission.index.PermissionIndexerTester;
import org.sonar.server.permission.index.WebAuthorizationTypeSupport;
import org.sonar.server.util.GlobalLockManager;
import org.sonar.server.util.GlobalLockManagerImpl;

import static org.assertj.core.api.Assertions.assertThat;
import static org.mockito.ArgumentMatchers.any;
@@ -65,7 +66,7 @@ public class ProjectsInWarningDaemonTest {
private ProjectMeasuresIndex projectMeasuresIndex = new ProjectMeasuresIndex(es.client(), new WebAuthorizationTypeSupport(null), System2.INSTANCE);

private MapSettings settings = new MapSettings();
private GlobalLockManager lockManager = mock(GlobalLockManager.class);
private GlobalLockManager lockManager = mock(GlobalLockManagerImpl.class);
private ProjectsInWarning projectsInWarning = new ProjectsInWarning();

private ProjectsInWarningDaemon underTest = new ProjectsInWarningDaemon(db.getDbClient(), projectMeasuresIndex, settings.asConfig(), lockManager, projectsInWarning);

+ 2
- 1
server/sonar-webserver-core/src/test/java/org/sonar/server/telemetry/TelemetryDaemonTest.java View File

@@ -51,6 +51,7 @@ import org.sonar.server.tester.UserSessionRule;
import org.sonar.server.user.index.UserIndex;
import org.sonar.server.user.index.UserIndexer;
import org.sonar.server.util.GlobalLockManager;
import org.sonar.server.util.GlobalLockManagerImpl;
import org.sonar.updatecenter.common.Version;

import static java.util.Arrays.asList;
@@ -96,7 +97,7 @@ public class TelemetryDaemonTest {

private TelemetryClient client = mock(TelemetryClient.class);
private InternalProperties internalProperties = spy(new MapInternalProperties());
private final GlobalLockManager lockManager = mock(GlobalLockManager.class);
private final GlobalLockManager lockManager = mock(GlobalLockManagerImpl.class);
private FakeServer server = new FakeServer();
private PluginRepository pluginRepository = mock(PluginRepository.class);
private TestSystem2 system2 = new TestSystem2().setNow(System.currentTimeMillis());

+ 2
- 2
server/sonar-webserver/src/main/java/org/sonar/server/platform/platformlevel/PlatformLevel1.java View File

@@ -29,6 +29,7 @@ import org.sonar.api.internal.MetadataLoader;
import org.sonar.api.internal.SonarRuntimeImpl;
import org.sonar.api.utils.System2;
import org.sonar.api.utils.Version;
import org.sonar.server.util.GlobalLockManagerImpl;
import org.sonar.server.util.TempFolderCleaner;
import org.sonar.core.config.CorePropertyDefinitions;
import org.sonar.core.extension.CoreExtensionRepositoryImpl;
@@ -61,7 +62,6 @@ import org.sonar.server.rule.index.RuleIndex;
import org.sonar.server.setting.ThreadLocalSettings;
import org.sonar.server.user.SystemPasscodeImpl;
import org.sonar.server.user.ThreadLocalUserSession;
import org.sonar.server.util.GlobalLockManager;
import org.sonar.server.util.OkHttpClientProvider;

import static org.sonar.core.extension.CoreExtensionsInstaller.noAdditionalSideFilter;
@@ -129,7 +129,7 @@ public class PlatformLevel1 extends PlatformLevel {
// issues
IssueIndex.class,

GlobalLockManager.class,
GlobalLockManagerImpl.class,

new OkHttpClientProvider(),


Loading…
Cancel
Save