From: Duarte Meneses Date: Mon, 30 Jan 2017 09:41:40 +0000 (+0100) Subject: SONAR-8386 Fetch all usernames in a single request in preview mode X-Git-Tag: 6.3-RC1~346 X-Git-Url: https://source.dussan.org/?a=commitdiff_plain;h=refs%2Fpull%2F1586%2Fhead;p=sonarqube.git SONAR-8386 Fetch all usernames in a single request in preview mode --- diff --git a/sonar-scanner-engine/src/main/java/org/sonar/scanner/issue/DefaultIssueCallback.java b/sonar-scanner-engine/src/main/java/org/sonar/scanner/issue/DefaultIssueCallback.java index 20f628c4216..d6afff29173 100644 --- a/sonar-scanner-engine/src/main/java/org/sonar/scanner/issue/DefaultIssueCallback.java +++ b/sonar-scanner-engine/src/main/java/org/sonar/scanner/issue/DefaultIssueCallback.java @@ -28,6 +28,8 @@ import java.util.HashMap; import java.util.HashSet; import java.util.Map; import java.util.Set; +import java.util.stream.Collectors; + import org.sonar.scanner.issue.tracking.TrackedIssue; import org.sonar.scanner.protocol.input.ScannerInput.User; import org.sonar.scanner.repository.user.UserRepositoryLoader; @@ -104,12 +106,10 @@ public class DefaultIssueCallback implements IssueCallback { } private void getUsers() { - for (String loginName : userLoginNames) { - User user = userRepository.load(loginName); - if (user != null) { - userMap.put(user.getLogin(), user.getName()); - } - } + Map map = userRepository.map(userLoginNames); + + userMap = map.entrySet().stream() + .collect(Collectors.toMap(Map.Entry::getKey, e -> e.getValue().getName())); } private String getRuleName(RuleKey ruleKey) { diff --git a/sonar-scanner-engine/src/main/java/org/sonar/scanner/repository/settings/SettingsLoader.java b/sonar-scanner-engine/src/main/java/org/sonar/scanner/repository/settings/SettingsLoader.java index eeebeb6b52b..e4e1fda927f 100644 --- a/sonar-scanner-engine/src/main/java/org/sonar/scanner/repository/settings/SettingsLoader.java +++ b/sonar-scanner-engine/src/main/java/org/sonar/scanner/repository/settings/SettingsLoader.java @@ -21,6 +21,7 @@ package org.sonar.scanner.repository.settings; import java.util.Map; +@FunctionalInterface public interface SettingsLoader { Map load(String componentKey); } diff --git a/sonar-scanner-engine/src/main/java/org/sonar/scanner/repository/user/UserRepositoryLoader.java b/sonar-scanner-engine/src/main/java/org/sonar/scanner/repository/user/UserRepositoryLoader.java index 54dabf622ff..ab65d6ac35d 100644 --- a/sonar-scanner-engine/src/main/java/org/sonar/scanner/repository/user/UserRepositoryLoader.java +++ b/sonar-scanner-engine/src/main/java/org/sonar/scanner/repository/user/UserRepositoryLoader.java @@ -19,20 +19,22 @@ */ package org.sonar.scanner.repository.user; -import org.apache.commons.io.IOUtils; -import com.google.common.collect.Lists; -import com.google.common.base.Joiner; -import org.sonar.scanner.bootstrap.ScannerWsClient; -import org.sonar.scanner.protocol.input.ScannerInput; -import org.sonar.scanner.util.ScannerUtils; -import org.sonarqube.ws.client.GetRequest; -import com.google.common.base.Function; import java.io.IOException; import java.io.InputStream; import java.util.ArrayList; import java.util.Collection; import java.util.Collections; +import java.util.HashMap; import java.util.List; +import java.util.Map; +import java.util.function.Function; +import java.util.stream.Collectors; + +import org.apache.commons.io.IOUtils; +import org.sonar.scanner.bootstrap.ScannerWsClient; +import org.sonar.scanner.protocol.input.ScannerInput; +import org.sonar.scanner.util.ScannerUtils; +import org.sonarqube.ws.client.GetRequest; public class UserRepositoryLoader { private final ScannerWsClient wsClient; @@ -46,15 +48,29 @@ public class UserRepositoryLoader { return parseUser(is); } - public Collection load(List userLogins) { + public Collection load(Collection userLogins) { if (userLogins.isEmpty()) { return Collections.emptyList(); } - InputStream is = loadQuery(Joiner.on(',').join(Lists.transform(userLogins, new UserEncodingFunction()))); + UserEncodingFunction userEncodingFunction = new UserEncodingFunction(); + String encodedUserLogins = userLogins.stream() + .map(userEncodingFunction::apply) + .collect(Collectors.joining(",")); + InputStream is = loadQuery(encodedUserLogins); return parseUsers(is); } + public Map map(Collection userLogins) { + Collection users = load(userLogins); + Map map = new HashMap<>(); + + for (ScannerInput.User user : users) { + map.put(user.getLogin(), user); + } + return map; + } + private InputStream loadQuery(String loginsQuery) { GetRequest getRequest = new GetRequest("/batch/users?logins=" + loginsQuery); return wsClient.call(getRequest).contentStream(); diff --git a/sonar-scanner-engine/src/main/java/org/sonar/scanner/scan/report/JSONReport.java b/sonar-scanner-engine/src/main/java/org/sonar/scanner/scan/report/JSONReport.java index 6551ddb2dc7..68c2c20f9b2 100644 --- a/sonar-scanner-engine/src/main/java/org/sonar/scanner/scan/report/JSONReport.java +++ b/sonar-scanner-engine/src/main/java/org/sonar/scanner/scan/report/JSONReport.java @@ -29,8 +29,6 @@ import java.io.Writer; import java.nio.charset.StandardCharsets; import java.util.Collection; import java.util.LinkedHashSet; -import java.util.LinkedList; -import java.util.List; import java.util.Set; import org.apache.commons.lang.StringUtils; import org.slf4j.Logger; @@ -214,13 +212,7 @@ public class JSONReport implements Reporter { } private void writeUsers(JsonWriter json, Collection userLogins) throws IOException { - List users = new LinkedList<>(); - for (String userLogin : userLogins) { - User user = userRepository.load(userLogin); - if (user != null) { - users.add(user); - } - } + Collection users = userRepository.load(userLogins); json.name("users").beginArray(); for (ScannerInput.User user : users) { diff --git a/sonar-scanner-engine/src/test/java/org/sonar/scanner/issue/DefaultIssueCallbackTest.java b/sonar-scanner-engine/src/test/java/org/sonar/scanner/issue/DefaultIssueCallbackTest.java index 6bde07dd80a..326e534af3a 100644 --- a/sonar-scanner-engine/src/test/java/org/sonar/scanner/issue/DefaultIssueCallbackTest.java +++ b/sonar-scanner-engine/src/test/java/org/sonar/scanner/issue/DefaultIssueCallbackTest.java @@ -37,6 +37,7 @@ import org.sonar.scanner.repository.user.UserRepositoryLoader; import org.junit.Before; import com.google.common.collect.ImmutableList; +import java.util.Collections; import java.util.LinkedList; import java.util.List; @@ -69,7 +70,8 @@ public class DefaultIssueCallbackTest { ScannerInput.User.Builder userBuilder = ScannerInput.User.newBuilder(); userBuilder.setLogin("user"); userBuilder.setName("name"); - when(userRepository.load("user")).thenReturn(userBuilder.build()); + when(userRepository.map(Collections.singleton("user"))) + .thenReturn(Collections.singletonMap("user", userBuilder.build())); Rule r = mock(Rule.class); when(r.name()).thenReturn("rule name"); diff --git a/sonar-scanner-engine/src/test/java/org/sonar/scanner/repository/user/UserRepositoryLoaderTest.java b/sonar-scanner-engine/src/test/java/org/sonar/scanner/repository/user/UserRepositoryLoaderTest.java index 40c944ee8d8..11db8fc231a 100644 --- a/sonar-scanner-engine/src/test/java/org/sonar/scanner/repository/user/UserRepositoryLoaderTest.java +++ b/sonar-scanner-engine/src/test/java/org/sonar/scanner/repository/user/UserRepositoryLoaderTest.java @@ -22,6 +22,7 @@ package org.sonar.scanner.repository.user; import org.assertj.core.util.Lists; import org.sonar.scanner.bootstrap.ScannerWsClient; import org.sonar.scanner.protocol.input.ScannerInput; +import org.sonar.scanner.protocol.input.ScannerInput.User; import org.sonar.scanner.repository.user.UserRepositoryLoader; import org.sonar.scanner.WsTestUtil; import org.junit.Before; @@ -67,6 +68,26 @@ public class UserRepositoryLoaderTest { assertThat(userRepo.load(Arrays.asList("fmallet", "sbrandhof"))).extracting("login", "name").containsOnly(tuple("fmallet", "Freddy Mallet"), tuple("sbrandhof", "Simon")); } + @Test + public void testLoadListWithSingleUser() throws IOException { + Map userMap = ImmutableMap.of("fmallet", "Freddy Mallet"); + InputStream is = createUsersMock(userMap); + WsTestUtil.mockStream(wsClient, "/batch/users?logins=fmallet", is); + assertThat(userRepo.load(Arrays.asList("fmallet"))).extracting("login", "name").containsOnly(tuple("fmallet", "Freddy Mallet")); + } + + @Test + public void testMapUsers() throws IOException { + Map userMap = ImmutableMap.of("fmallet", "Freddy Mallet"); + InputStream is = createUsersMock(userMap); + WsTestUtil.mockStream(wsClient, "/batch/users?logins=fmallet,sbrandhof", is); + Map map = userRepo.map(Arrays.asList("fmallet", "sbrandhof")); + + // one user doesn't exist + assertThat(map).hasSize(1); + assertThat(map.values().iterator().next().getLogin()).isEqualTo("fmallet"); + } + @Test public void testLoadSingleUser() throws IOException { InputStream is = createUsersMock(ImmutableMap.of("fmallet", "Freddy Mallet")); diff --git a/sonar-scanner-engine/src/test/java/org/sonar/scanner/scan/report/JSONReportTest.java b/sonar-scanner-engine/src/test/java/org/sonar/scanner/scan/report/JSONReportTest.java index e464770bb66..c86b5ada7e7 100644 --- a/sonar-scanner-engine/src/test/java/org/sonar/scanner/scan/report/JSONReportTest.java +++ b/sonar-scanner-engine/src/test/java/org/sonar/scanner/scan/report/JSONReportTest.java @@ -123,7 +123,7 @@ public class JSONReportTest { issue.setNew(false); when(issueCache.all()).thenReturn(Collections.singleton(issue)); ScannerInput.User user = ScannerInput.User.newBuilder().setLogin("simon").setName("Simon").build(); - when(userRepository.load("simon")).thenReturn(user); + when(userRepository.load(Collections.singleton("simon"))).thenReturn(Collections.singleton(user)); StringWriter writer = new StringWriter(); jsonReport.writeJson(writer);