Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,9 @@
import build.base.option.Email;
import build.base.option.Password;
import build.base.option.Username;
import build.base.telemetry.TelemetryRecorder;
import build.base.telemetry.TelemetryRecorderFactory;
import build.base.telemetry.foundation.SystemTelemetryRecorder;
import build.codemodel.dependency.injection.ConfigurationResolver;
import build.codemodel.dependency.injection.Context;
import build.codemodel.dependency.injection.InjectionFramework;
Expand All @@ -53,6 +56,7 @@
import build.spawn.docker.option.DockerRegistry;
import build.spawn.docker.option.IdentityToken;

import java.net.URI;
import java.nio.charset.StandardCharsets;
import java.nio.file.Path;
import java.util.Base64;
Expand Down Expand Up @@ -110,22 +114,46 @@ public class AbstractSession
private final GetSystemEvents systemEvents;

/**
* Constructs an {@link AbstractSession} using the specified {@link HttpTransport} and {@link Configuration}.
* Constructs an {@link AbstractSession} using the specified {@link HttpTransport} and {@link Configuration},
* recording telemetry via a {@link SystemTelemetryRecorder}.
*
* @param injectionFramework the {@link InjectionFramework} to use for {@link build.codemodel.dependency.injection.Dependency} injection
* @param transport the {@link HttpTransport} for communicating with the Docker Engine
* @param configuration the {@link Configuration}
*/
@SuppressWarnings("unchecked")
protected AbstractSession(final InjectionFramework injectionFramework,
final HttpTransport transport,
final Configuration configuration) {

this(injectionFramework, transport, configuration, SystemTelemetryRecorder::of);
}

/**
* Constructs an {@link AbstractSession} using the specified {@link HttpTransport}, {@link Configuration}
* and {@link TelemetryRecorderFactory}.
*
* @param injectionFramework the {@link InjectionFramework} to use for
* {@link build.codemodel.dependency.injection.Dependency} injection
* @param transport the {@link HttpTransport} for communicating with the Docker Engine
* @param configuration the {@link Configuration}
* @param telemetryRecorderFactory the {@link TelemetryRecorderFactory} used to create the
* {@link TelemetryRecorder} for the {@link Session}
*/
@SuppressWarnings("unchecked")
protected AbstractSession(final InjectionFramework injectionFramework,
final HttpTransport transport,
final Configuration configuration,
final TelemetryRecorderFactory telemetryRecorderFactory) {

Objects.requireNonNull(injectionFramework, "The InjectionFramework must not be null");
Objects.requireNonNull(transport, "The HttpTransport must not be null");
Objects.requireNonNull(telemetryRecorderFactory, "The TelemetryRecorderFactory must not be null");

this.transport = transport;

final TelemetryRecorder recorder = telemetryRecorderFactory
.apply(URI.create("spawn://" + getClass().getSimpleName()));

this.configuration = configuration == null
? Configuration.empty()
: configuration;
Expand Down Expand Up @@ -156,6 +184,7 @@ protected AbstractSession(final InjectionFramework injectionFramework,
this.context.bind(Publicist.class).to(this.publicist);
this.context.bind(Publisher.class).to(this.publicist);
this.context.bind(CompletingSubscriber.class).to(this.eventSubscriber);
this.context.bind(TelemetryRecorder.class).to(recorder);

// attempt to authenticate (when there's a Username, Password, and DockerRegistry) and capture an IdentityToken
final Optional<String> xRegistryAuth;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@
*/

import build.base.configuration.Configuration;
import build.base.telemetry.TelemetryRecorderFactory;
import build.codemodel.dependency.injection.InjectionFramework;
import build.spawn.docker.Session;
import jakarta.inject.Inject;
Expand Down Expand Up @@ -57,6 +58,13 @@ public class DockerHostVariableBasedSessionFactory
@Inject
private InjectionFramework injectionFramework;

/**
* The {@link TelemetryRecorderFactory} used to create the {@link build.base.telemetry.TelemetryRecorder}
* for {@link Session}s produced by this {@link Session.Factory}.
*/
@Inject
private TelemetryRecorderFactory telemetryRecorderFactory;

/**
* Constructs a {@link DockerHostVariableBasedSessionFactory}.
*/
Expand Down Expand Up @@ -108,7 +116,8 @@ public boolean isOperational() {
@Override
public Optional<Session> create(final Configuration configuration) {
return isOperational()
? Optional.of(new TCPSocketBasedSession(this.injectionFramework, this.address.get(), configuration))
? Optional.of(new TCPSocketBasedSession(
this.injectionFramework, this.address.get(), configuration, this.telemetryRecorderFactory))
: Optional.empty();
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@
*/

import build.base.configuration.Configuration;
import build.base.telemetry.TelemetryRecorderFactory;
import build.codemodel.dependency.injection.InjectionFramework;
import build.spawn.docker.Session;
import jakarta.inject.Inject;
Expand Down Expand Up @@ -50,6 +51,13 @@ public class InternalDockerHostBasedSessionFactory
@Inject
private InjectionFramework injectionFramework;

/**
* The {@link TelemetryRecorderFactory} used to create the {@link build.base.telemetry.TelemetryRecorder}
* for {@link Session}s produced by this {@link Session.Factory}.
*/
@Inject
private TelemetryRecorderFactory telemetryRecorderFactory;

@Override
public boolean isOperational() {
try (Socket socket = new Socket()) {
Expand All @@ -66,7 +74,8 @@ public boolean isOperational() {
public Optional<Session> create(final Configuration configuration) {

return isOperational()
? Optional.of(new TCPSocketBasedSession(this.injectionFramework, ADDRESS, configuration))
? Optional.of(new TCPSocketBasedSession(
this.injectionFramework, ADDRESS, configuration, this.telemetryRecorderFactory))
: Optional.empty();
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@
*/

import build.base.configuration.Configuration;
import build.base.telemetry.TelemetryRecorderFactory;
import build.codemodel.dependency.injection.InjectionFramework;
import build.spawn.docker.Session;
import jakarta.inject.Inject;
Expand Down Expand Up @@ -50,6 +51,13 @@ public class LocalHostBasedSessionFactory
@Inject
private InjectionFramework injectionFramework;

/**
* The {@link TelemetryRecorderFactory} used to create the {@link build.base.telemetry.TelemetryRecorder}
* for {@link Session}s produced by this {@link Session.Factory}.
*/
@Inject
private TelemetryRecorderFactory telemetryRecorderFactory;

@Override
public boolean isOperational() {
try (Socket socket = new Socket()) {
Expand All @@ -66,7 +74,8 @@ public boolean isOperational() {
public Optional<Session> create(final Configuration configuration) {

return isOperational()
? Optional.of(new TCPSocketBasedSession(this.injectionFramework, ADDRESS, configuration))
? Optional.of(new TCPSocketBasedSession(
this.injectionFramework, ADDRESS, configuration, this.telemetryRecorderFactory))
: Optional.empty();
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,8 @@
*/

import build.base.configuration.Configuration;
import build.base.telemetry.TelemetryRecorderFactory;
import build.base.telemetry.foundation.SystemTelemetryRecorder;
import build.codemodel.dependency.injection.InjectionFramework;

import java.net.InetSocketAddress;
Expand All @@ -37,7 +39,8 @@ public class TCPSocketBasedSession
extends AbstractSession {

/**
* Constructs a {@link TCPSocketBasedSession} for the specified {@link InetSocketAddress}.
* Constructs a {@link TCPSocketBasedSession} for the specified {@link InetSocketAddress}, recording
* telemetry via a {@link SystemTelemetryRecorder}.
*
* @param injectionFramework the {@link InjectionFramework}
* @param socketAddress the {@link InetSocketAddress}
Expand All @@ -47,12 +50,33 @@ public TCPSocketBasedSession(final InjectionFramework injectionFramework,
final InetSocketAddress socketAddress,
final Configuration configuration) {

this(injectionFramework, socketAddress, configuration, SystemTelemetryRecorder::of);
}

/**
* Constructs a {@link TCPSocketBasedSession} for the specified {@link InetSocketAddress}, recording
* telemetry via the {@link build.base.telemetry.TelemetryRecorder} produced by the specified
* {@link TelemetryRecorderFactory}.
*
* @param injectionFramework the {@link InjectionFramework}
* @param socketAddress the {@link InetSocketAddress}
* @param configuration the {@link Configuration}
* @param telemetryRecorderFactory the {@link TelemetryRecorderFactory} used to create the
* {@link build.base.telemetry.TelemetryRecorder} for the
* {@link build.spawn.docker.Session}
*/
public TCPSocketBasedSession(final InjectionFramework injectionFramework,
final InetSocketAddress socketAddress,
final Configuration configuration,
final TelemetryRecorderFactory telemetryRecorderFactory) {

super(injectionFramework,
new JavaHttpClientTransport(
HttpClient.newBuilder()
.connectTimeout(Duration.ofSeconds(10))
.build(),
"http://" + socketAddress.getHostString() + ":" + socketAddress.getPort()),
configuration);
configuration,
telemetryRecorderFactory);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,8 @@
*/

import build.base.configuration.Configuration;
import build.base.telemetry.TelemetryRecorderFactory;
import build.base.telemetry.foundation.SystemTelemetryRecorder;
import build.codemodel.dependency.injection.InjectionFramework;
import build.spawn.docker.Session;
import jakarta.inject.Inject;
Expand Down Expand Up @@ -66,7 +68,8 @@ private static File resolveDockerSockFile() {
}

/**
* Constructs a {@link UnixDomainSocketBasedSession} using the default {@code docker.sock} file.
* Constructs a {@link UnixDomainSocketBasedSession} using the default {@code docker.sock} file, recording
* telemetry via a {@link SystemTelemetryRecorder}.
*
* @param injectionFramework the {@link InjectionFramework} for Dependency Injection
* @param configuration the {@link Configuration}
Expand All @@ -78,7 +81,25 @@ public UnixDomainSocketBasedSession(final InjectionFramework injectionFramework,
}

/**
* Constructs a {@link UnixDomainSocketBasedSession} for the specified Unix socket {@link File}.
* Constructs a {@link UnixDomainSocketBasedSession} using the default {@code docker.sock} file, recording
* telemetry via the {@link build.base.telemetry.TelemetryRecorder} produced by the specified
* {@link TelemetryRecorderFactory}.
*
* @param injectionFramework the {@link InjectionFramework} for Dependency Injection
* @param configuration the {@link Configuration}
* @param telemetryRecorderFactory the {@link TelemetryRecorderFactory} used to create the
* {@link build.base.telemetry.TelemetryRecorder} for the {@link Session}
*/
public UnixDomainSocketBasedSession(final InjectionFramework injectionFramework,
final Configuration configuration,
final TelemetryRecorderFactory telemetryRecorderFactory) {

this(injectionFramework, DOCKER_SOCK_FILE, configuration, telemetryRecorderFactory);
}

/**
* Constructs a {@link UnixDomainSocketBasedSession} for the specified Unix socket {@link File}, recording
* telemetry via a {@link SystemTelemetryRecorder}.
*
* @param injectionFramework the {@link InjectionFramework} for Dependency Injection
* @param socketFile the Unix socket {@link File}
Expand All @@ -88,7 +109,26 @@ public UnixDomainSocketBasedSession(final InjectionFramework injectionFramework,
final File socketFile,
final Configuration configuration) {

super(injectionFramework, new UnixSocketHttpTransport(socketFile), configuration);
this(injectionFramework, socketFile, configuration, SystemTelemetryRecorder::of);
}

/**
* Constructs a {@link UnixDomainSocketBasedSession} for the specified Unix socket {@link File}, recording
* telemetry via the {@link build.base.telemetry.TelemetryRecorder} produced by the specified
* {@link TelemetryRecorderFactory}.
*
* @param injectionFramework the {@link InjectionFramework} for Dependency Injection
* @param socketFile the Unix socket {@link File}
* @param configuration the {@link Configuration}
* @param telemetryRecorderFactory the {@link TelemetryRecorderFactory} used to create the
* {@link build.base.telemetry.TelemetryRecorder} for the {@link Session}
*/
public UnixDomainSocketBasedSession(final InjectionFramework injectionFramework,
final File socketFile,
final Configuration configuration,
final TelemetryRecorderFactory telemetryRecorderFactory) {

super(injectionFramework, new UnixSocketHttpTransport(socketFile), configuration, telemetryRecorderFactory);
}

/**
Expand All @@ -103,6 +143,13 @@ public static class Factory
@Inject
private InjectionFramework injectionFramework;

/**
* The {@link TelemetryRecorderFactory} used to create the {@link build.base.telemetry.TelemetryRecorder}
* for {@link Session}s produced by this {@link Session.Factory}.
*/
@Inject
private TelemetryRecorderFactory telemetryRecorderFactory;

@Override
public boolean isOperational() {
try (var _ = SocketChannel.open(UnixDomainSocketAddress.of(DOCKER_SOCK_FILE.toPath()))) {
Expand All @@ -115,7 +162,8 @@ public boolean isOperational() {
@Override
public Optional<Session> create(final Configuration configuration) {
return isOperational()
? Optional.of(new UnixDomainSocketBasedSession(this.injectionFramework, configuration))
? Optional.of(new UnixDomainSocketBasedSession(
this.injectionFramework, configuration, this.telemetryRecorderFactory))
: Optional.empty();
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@
* #L%
*/

import build.base.telemetry.TelemetryRecorder;
import build.codemodel.dependency.injection.Context;
import build.spawn.docker.jdk.HttpTransport;
import jakarta.inject.Inject;
Expand Down Expand Up @@ -49,6 +50,12 @@ public abstract class AbstractCommand<T>
@Inject
private Context context;

/**
* The {@link TelemetryRecorder} used to record diagnostics for the {@link Command}.
*/
@Inject
private TelemetryRecorder recorder;

/**
* Obtains the {@link HttpTransport} to use for executing {@link Command}s.
*
Expand All @@ -58,6 +65,15 @@ protected HttpTransport transport() {
return this.transport;
}

/**
* Obtains the {@link TelemetryRecorder} to use for recording diagnostics for the {@link Command}.
*
* @return the {@link TelemetryRecorder}
*/
protected TelemetryRecorder recorder() {
return this.recorder;
}

/**
* Creates a new dependency injection {@link Context}, based on the {@link Context} used to create the
* {@link Command}.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -99,7 +99,7 @@ protected Optional<String> createResult(final HttpTransport.Response response)
json -> json.getString("stream").contains("Successful"));

// process the entire InputStream from the Response to essentially wait for the image to be created
final var processor = new JsonNodeInputStreamProcessor();
final var processor = new JsonNodeInputStreamProcessor(recorder());
processor.process(response.bodyStream(), completingSubscriber);

// we've completed building when the ImageId is available and "Successful" has been observed
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -88,7 +88,7 @@ public void onComplete() {
};

// process the entire InputStream from the Response to essentially wait for the image to be created
final var processor = new JsonNodeInputStreamProcessor();
final var processor = new JsonNodeInputStreamProcessor(recorder());
try {
processor.process(response.bodyStream(), jsonSubscriber);
} catch (final IOException e) {
Expand Down
10 changes: 10 additions & 0 deletions spawn-docker/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,16 @@
<artifactId>codemodel-dependency-injection</artifactId>
</dependency>

<dependency>
<groupId>build.base</groupId>
<artifactId>base-telemetry</artifactId>
</dependency>

<dependency>
<groupId>build.base</groupId>
<artifactId>base-telemetry-foundation</artifactId>
</dependency>

<!-- Test Dependencies -->
<dependency>
<groupId>org.junit.jupiter</groupId>
Expand Down
Loading
Loading