Skip to content

Commit

Permalink
Add more tests and DevelocityClient builder
Browse files Browse the repository at this point in the history
  • Loading branch information
erichaagdev committed Jun 30, 2024
1 parent 90c164c commit f31415a
Show file tree
Hide file tree
Showing 17 changed files with 802 additions and 104 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -25,13 +25,14 @@ public final class AccessKeyProvider {
private AccessKeyProvider() {
}

public static Optional<String> lookupAccessKey(URI serverUrl) {
public static String lookupAccessKey(URI serverUrl) {
return fromEnvVar(accessKey, serverUrl)
.or(() -> fromEnvVar(legacyAccessKey, serverUrl))
.or(() -> fromGradleHome("develocity", serverUrl))
.or(() -> fromMavenHome("develocity", serverUrl))
.or(() -> fromGradleHome("enterprise", serverUrl))
.or(() -> fromMavenHome("gradle-enterprise", serverUrl));
.or(() -> fromMavenHome("gradle-enterprise", serverUrl))
.orElseThrow(() -> new RuntimeException("No access key found for server " + serverUrl.getHost()));
}

private static Optional<String> fromGradleHome(String baseDir, URI serverUrl) {
Expand Down
14 changes: 12 additions & 2 deletions src/main/java/dev/erichaag/develocity/api/DevelocityClient.java
Original file line number Diff line number Diff line change
@@ -1,13 +1,15 @@
package dev.erichaag.develocity.api;

import java.net.URI;
import java.util.List;
import java.util.Optional;
import java.util.Set;

public interface DevelocityClient {

Build getBuild(String id, Set<BuildModel> buildModels);
Optional<Build> getBuild(String id, Set<BuildModel> buildModels);

default Build getBuild(String id, BuildModel... buildModels) {
default Optional<Build> getBuild(String id, BuildModel... buildModels) {
return getBuild(id, Set.of(buildModels));
}

Expand All @@ -17,4 +19,12 @@ default List<? extends Build> getBuilds(String query, Integer maxBuilds, String
return getBuilds(query, maxBuilds, fromBuild, Set.of(buildModels));
}

static HttpClientDevelocityClientBuilder forServer(URI serverUrl) {
return new HttpClientDevelocityClientBuilder(serverUrl);
}

static HttpClientDevelocityClientBuilder forServer(String serverUrl) {
return forServer(URI.create(serverUrl));
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -15,11 +15,13 @@
import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import java.util.Optional;
import java.util.Set;
import java.util.concurrent.TimeUnit;
import java.util.function.Supplier;

import static java.net.http.HttpResponse.BodyHandlers.ofByteArray;
import static java.util.Optional.empty;

public final class HttpClientDevelocityClient implements DevelocityClient {

Expand All @@ -30,17 +32,20 @@ public final class HttpClientDevelocityClient implements DevelocityClient {

private static final int maxRetries = 5;

public HttpClientDevelocityClient(URI serverUrl) {
public HttpClientDevelocityClient(URI serverUrl, String accessKey, HttpClient httpClient) {
this.serverUrl = serverUrl;
this.accessKey = AccessKeyProvider.lookupAccessKey(serverUrl).orElse(null);
this.httpClient = HttpClient.newBuilder().followRedirects(HttpClient.Redirect.NORMAL).build();
this.accessKey = accessKey;
this.httpClient = httpClient;
this.objectMapper = new JsonMapper().configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);
}

@Override
public Build getBuild(String id, Set<BuildModel> buildModels) {
public Optional<Build> getBuild(String id, Set<BuildModel> buildModels) {
final var response = sendRequest("/api/builds/" + id, null, false, null, null, buildModels);
return Build.from(handleResponse(response, new TypeReference<>() {}));
if (response.statusCode() == 404) {
return empty();
}
return Optional.of(Build.from(handleResponse(response, new TypeReference<>() {})));
}

@Override
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
package dev.erichaag.develocity.api;

import java.net.URI;
import java.net.http.HttpClient;

import static dev.erichaag.develocity.api.AccessKeyProvider.lookupAccessKey;

public final class HttpClientDevelocityClientBuilder {

private final URI serverUrl;
private final HttpClient.Builder httpClientBuilder = HttpClient.newBuilder();

private boolean useAnonymousAccess = false;

HttpClientDevelocityClientBuilder(URI serverUrl) {
this.serverUrl = serverUrl;
}

public HttpClientDevelocityClient build() {
final var accessKey = useAnonymousAccess ? null : lookupAccessKey(serverUrl);
return new HttpClientDevelocityClient(serverUrl, accessKey, httpClientBuilder.build());
}

public HttpClientDevelocityClientBuilder withAnonymousAccess() {
this.useAnonymousAccess = true;
return this;
}

public HttpClientDevelocityClientBuilder followingRedirects() {
this.httpClientBuilder.followRedirects(HttpClient.Redirect.ALWAYS);
return this;
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -64,51 +64,51 @@ public BuildListenerBuilder requiredBuildModels(BuildModel... buildModels) {
return this;
}

public BuildListenerBuilder onBuild(Consumer<Build> consumer) {
public BuildListenerBuilder onBuild(Consumer<Build> onBuild) {
listeners.add(new BuildListener() {
@Override
public void onBuild(Build build) {
consumer.accept(build);
onBuild.accept(build);
}
});
return this;
}

public BuildListenerBuilder onGradleBuild(Consumer<GradleBuild> consumer) {
public BuildListenerBuilder onGradleBuild(Consumer<GradleBuild> onGradleBuild) {
listeners.add(new BuildListener() {
@Override
public void onGradleBuild(GradleBuild build) {
consumer.accept(build);
onGradleBuild.accept(build);
}
});
return this;
}

public BuildListenerBuilder onMavenBuild(Consumer<MavenBuild> consumer) {
public BuildListenerBuilder onMavenBuild(Consumer<MavenBuild> onMavenBuild) {
listeners.add(new BuildListener() {
@Override
public void onMavenBuild(MavenBuild build) {
consumer.accept(build);
onMavenBuild.accept(build);
}
});
return this;
}

public BuildListenerBuilder onBazelBuild(Consumer<BazelBuild> consumer) {
public BuildListenerBuilder onBazelBuild(Consumer<BazelBuild> onBazelBuild) {
listeners.add(new BuildListener() {
@Override
public void onBazelBuild(BazelBuild build) {
consumer.accept(build);
onBazelBuild.accept(build);
}
});
return this;
}

public BuildListenerBuilder onSbtBuild(Consumer<SbtBuild> consumer) {
public BuildListenerBuilder onSbtBuild(Consumer<SbtBuild> onSbtBuild) {
listeners.add(new BuildListener() {
@Override
public void onSbtBuild(SbtBuild build) {
consumer.accept(build);
onSbtBuild.accept(build);
}
});
return this;
Expand Down
Original file line number Diff line number Diff line change
@@ -1,13 +1,18 @@
package dev.erichaag.develocity.processing;

import dev.erichaag.develocity.api.Build;
import dev.erichaag.develocity.api.BuildModel;
import dev.erichaag.develocity.api.DevelocityClient;
import dev.erichaag.develocity.processing.cache.ProcessorCache;

import java.time.Instant;
import java.util.List;
import java.util.Optional;
import java.util.Set;

import static java.util.Objects.requireNonNullElse;
import static java.util.Objects.requireNonNullElseGet;
import static java.util.Optional.empty;
import static java.util.stream.Collectors.toUnmodifiableSet;

public final class BuildProcessor {
Expand All @@ -28,8 +33,8 @@ public final class BuildProcessor {
List<BuildListener> buildListeners,
List<ProcessListener> processListeners) {
this.develocity = develocity;
this.processorCache = processorCache;
this.maxBuildsPerRequest = maxBuildsPerRequest == null ? defaultMaxBuildsPerRequest : maxBuildsPerRequest;
this.processorCache = requireNonNullElseGet(processorCache, NoCache::new);
this.maxBuildsPerRequest = requireNonNullElse(maxBuildsPerRequest, defaultMaxBuildsPerRequest);
this.buildListeners = buildListeners;
this.processListeners = processListeners;
this.requiredBuildModels = buildListeners.stream()
Expand Down Expand Up @@ -57,4 +62,18 @@ public void process(Instant since, String query) {
requiredBuildModels).process();
}

private static final class NoCache implements ProcessorCache {

@Override
public Optional<Build> load(String id, Set<BuildModel> requiredBuildModels) {
return empty();
}

@Override
public void save(Build build) {

}

}

}
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ public final class BuildProcessorBuilder {
private ProcessorCache processorCache;
private int maxBuildsPerRequest;

public BuildProcessorBuilder(DevelocityClient develocity) {
BuildProcessorBuilder(DevelocityClient develocity) {
this.develocity = develocity;
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -103,7 +103,9 @@ private void processCachedBuild(Build cachedBuild) {
notifyListenersCachedBuild(cachedBuild);
return;
}
final var build = develocity.getBuild(cachedBuild.getId(), requiredBuildModels);
// The build has to exist given that it was previously discovered.
//noinspection OptionalGetWithoutIsPresent
final var build = develocity.getBuild(cachedBuild.getId(), requiredBuildModels).get();
processorCache.save(build);
notifyListenersFetchedBuild(build);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,10 @@

public interface ProcessListener {

static ProcessListenerBuilder builder() {
return new ProcessListenerBuilder();
}

default void onCachedBuild(CachedBuildEvent event) {
}

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,117 @@
package dev.erichaag.develocity.processing;

import dev.erichaag.develocity.processing.event.CachedBuildEvent;
import dev.erichaag.develocity.processing.event.DiscoveryFinishedEvent;
import dev.erichaag.develocity.processing.event.DiscoveryStartedEvent;
import dev.erichaag.develocity.processing.event.FetchedBuildEvent;
import dev.erichaag.develocity.processing.event.ProcessingFinishedEvent;
import dev.erichaag.develocity.processing.event.ProcessingStartedEvent;

import java.util.ArrayList;
import java.util.List;
import java.util.function.Consumer;

public final class ProcessListenerBuilder {

private final List<ProcessListener> listeners = new ArrayList<>();

ProcessListenerBuilder() {
}

public ProcessListener build() {
return new ProcessListener() {

@Override
public void onCachedBuild(CachedBuildEvent event) {
listeners.forEach(it -> it.onCachedBuild(event));
}

@Override
public void onFetchedBuild(FetchedBuildEvent event) {
listeners.forEach(it -> it.onFetchedBuild(event));
}

@Override
public void onDiscoveryStarted(DiscoveryStartedEvent event) {
listeners.forEach(it -> it.onDiscoveryStarted(event));
}

@Override
public void onDiscoveryFinished(DiscoveryFinishedEvent event) {
listeners.forEach(it -> it.onDiscoveryFinished(event));
}

@Override
public void onProcessingStarted(ProcessingStartedEvent event) {
listeners.forEach(it -> it.onProcessingStarted(event));
}

@Override
public void onProcessingFinished(ProcessingFinishedEvent event) {
listeners.forEach(it -> it.onProcessingFinished(event));
}

};
}

public ProcessListenerBuilder onCachedBuild(Consumer<CachedBuildEvent> onCachedBuild) {
listeners.add(new ProcessListener() {
@Override
public void onCachedBuild(CachedBuildEvent event) {
onCachedBuild.accept(event);
}
});
return this;
}

public ProcessListenerBuilder onFetchedBuild(Consumer<FetchedBuildEvent> onFetchedBuild) {
listeners.add(new ProcessListener() {
@Override
public void onFetchedBuild(FetchedBuildEvent event) {
onFetchedBuild.accept(event);
}
});
return this;
}

public ProcessListenerBuilder onDiscoveryStarted(Consumer<DiscoveryStartedEvent> onDiscoveryStarted) {
listeners.add(new ProcessListener() {
@Override
public void onDiscoveryStarted(DiscoveryStartedEvent event) {
onDiscoveryStarted.accept(event);
}
});
return this;
}

public ProcessListenerBuilder onDiscoveryFinished(Consumer<DiscoveryFinishedEvent> onDiscoveryFinished) {
listeners.add(new ProcessListener() {
@Override
public void onDiscoveryFinished(DiscoveryFinishedEvent event) {
onDiscoveryFinished.accept(event);
}
});
return this;
}

public ProcessListenerBuilder onProcessingStarted(Consumer<ProcessingStartedEvent> onProcessingStarted) {
listeners.add(new ProcessListener() {
@Override
public void onProcessingStarted(ProcessingStartedEvent event) {
onProcessingStarted.accept(event);
}
});
return this;
}

public ProcessListenerBuilder onProcessingFinished(Consumer<ProcessingFinishedEvent> onProcessingFinished) {
listeners.add(new ProcessListener() {
@Override
public void onProcessingFinished(ProcessingFinishedEvent event) {
onProcessingFinished.accept(event);
}
});
return this;
}

}
Loading

0 comments on commit f31415a

Please sign in to comment.