Я новичок в игре, и у меня возникла проблема, связанная с извлечением данных из нескольких URL-адресов, и я жду всех этих запросов.
Наверное, я что-то упускаю из-за асинхронных c действий, потому что когда я жду Примерно через полминуты для ответа в сеансе отладки я получаю желаемый результат, что означает, что он не ожидает запросов.
Я пытался сделать это с CompletableFuture.allOf, но я не знаю, почему это терпит неудачу. Кстати, я заметил, что этот метод возвращает CompletableFuture, поэтому мне интересно, как я могу затем ApplyAsyn c результат.
Я считаю, что проблема в retrieveCommitsForUser (одна из перегрузок) ... Я добавляю код здесь .
Заранее всем спасибо!
package controllers;
import com.fasterxml.jackson.databind.JsonNode;
import play.libs.Json;
import play.mvc.*;
import utils.BBService;
import javax.inject.Inject;
import java.util.List;
import java.util.concurrent.CompletionStage;
import java.util.stream.Collectors;
/**
* Commits controller is handling in and out http traffic regarding bitbucket commits.
* Supporting get but can be expanded to other crud operations.
*/
public class CommitsController extends Controller {
final private String BB_BASE_URL = "https://api.bitbucket.org/2.0/";
final private String URL = BB_BASE_URL + "********************/";
final private String COMMITS = "commits";
private BBService bbService;
@Inject
public CommitsController(BBService bbService) {
this.bbService = bbService;
}
public CompletionStage<Result> showCommits(String username) {
return bbService.getAsync(URL)
.thenApplyAsync(wsResponse -> bbService.extractRepos(wsResponse))
.thenApplyAsync(repos -> {
List<String> reposURL = repos.stream().map(repo -> URL + repo + "/" + COMMITS).collect(Collectors.toList());
return bbService.retrieveCommitsForUser(reposURL, username);
})
.thenApplyAsync(allCommits -> {
JsonNode commitsResult = Json.toJson(allCommits);
return bbService.withFullAccess(ok(commitsResult));
});
}
}
package utils;
import com.fasterxml.jackson.databind.JsonNode;
import models.Commit;
import play.libs.ws.*;
import play.mvc.Result;
import javax.inject.Inject;
import java.util.List;
import java.util.Vector;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.CompletionStage;
import java.util.stream.Collectors;
public class BBService {
private final String bbUsername = "*******";
private final String bbPassword = "***********";
private final WSClient ws;
@Inject
public BBService(WSClient ws) {
this.ws = ws;
}
public CompletionStage<WSResponse> getAsync(String url) {
WSRequest req = ws.url(url).setAuth(bbUsername, bbPassword);
return req.get();
}
public List<String> extractNames(WSResponse wsResponse) {
Vector<String> usersNames = new Vector<>();
JsonNode users = wsResponse.asJson().findValue("values");
for (JsonNode user : users) {
String userName = user.findValue("display_name").asText();
usersNames.add(userName);
}
return usersNames;
}
public CompletionStage<List<Commit>> retrieveCommitsForUser(String repoURL, String username) {
return getAsync(repoURL)
.thenApplyAsync(wsResponse -> extractCommits(wsResponse).stream()
.filter(commit -> commit.getAuthor() == username)
.collect(Collectors.toList()));
}
private List<Commit> extractCommits(WSResponse wsResponse) {
Vector<Commit> allCommits = new Vector<>();
JsonNode commits = wsResponse.asJson().findValue("values");
for (JsonNode commit : commits) {
String HASH = commit.findValue("hash").asText();
String date = commit.findValue("date").asText();
String repo = commit.findValue("repository").findValue("name").asText();
String message = commit.findValue("message").asText();
String author = commit.findValue("author").findValue("user").findValue("display_name").asText();
Commit currCommit = new Commit(HASH, date, repo, message, author);
allCommits.add(currCommit);
}
return allCommits;
}
public CompletableFuture<Void> retrieveCommitsForUser(List<String> reposURL, String username) {
Vector<CompletableFuture<List<Commit>>> allCommits = new Vector<>();
// reposURL.stream().forEach(repoURL -> allCommits.add(retrieveCommitsForUser(repoURL, username).toCompletableFuture()));
for (String url: reposURL) {
allCommits.add(retrieveCommitsForUser(url, username).toCompletableFuture());
}
return CompletableFuture.allOf(allCommits.toArray(new CompletableFuture[allCommits.size()]));
}
public List<String> extractRepos(WSResponse wsResponse) {
Vector<String> repos = new Vector<>();
JsonNode reposAsJson = wsResponse.asJson().findValue("values");
for (JsonNode repo : reposAsJson) {
String repoName = repo.findValue("slug").asText();
repos.add(repoName);
}
return repos;
}
public Result withFullAccess(Result noAccessibleRes) {
return noAccessibleRes.withHeader("Access-Control-Allow-Origin", "*");
}
}