Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Refactoring event logs #821

Merged
merged 40 commits into from
Mar 5, 2024
Merged

Refactoring event logs #821

merged 40 commits into from
Mar 5, 2024

Conversation

attilakreiner
Copy link
Contributor

Description

This change refactors the event definitions and introduces *EventFormatter classes.

DirectBuffer buffer,
int index,
int length);
}
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please add

public final class EventFomatter
{
    public static EventFomatter instantiate()
    {
        ... use service loader to discover event formatter spis and return an event formatter that can delegate
    }

    public String format(
        int msgTypeId,
        DirectBuffer buffer,
        int index,
        int length)
    {
        ... lookup event formatter spi by type id and return formatted event
    }
}

Comment on lines 24 to 28
String formatEventEx(
int msgTypeId,
DirectBuffer buffer,
int index,
int length);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
String formatEventEx(
int msgTypeId,
DirectBuffer buffer,
int index,
int length);
String format(
DirectBuffer buffer,
int index,
int length);

We already advertised our required type, so we don't need to pass it again here.

Comment on lines 40 to 45
Map<String, EventFormatterSpi> formatters = ServiceLoader.load(EventFormatterSpi.class)
.stream()
.collect(Collectors.toMap(
provider -> provider.get().type(),
provider -> provider.get()
));
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please move this service loader code to the engine, exposed as an EventFormatter obtained from EngineContext.

See comments on EventFormatterSpi for more details.

(normally we don't expose the spis outside of the engine except as interfaces for implementation classes)

@@ -48,7 +53,7 @@ public ExporterHandler attach(
LongFunction<KindConfig> resolveKind)
{
StdoutExporterConfig stdoutExporter = new StdoutExporterConfig(exporter);
return new StdoutExporterHandler(config, context, stdoutExporter);
return new StdoutExporterHandler(config, formatters, context, stdoutExporter);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
return new StdoutExporterHandler(config, formatters, context, stdoutExporter);
return new StdoutExporterHandler(config, formatter, context, stdoutExporter);

where formatter is an EventFormatter provided by the engine

Comment on lines +34 to +35
private static final String FORMAT = "%s [%s] %s%n"; // qname [timestamp] extension\n
private static final DateTimeFormatter FORMATTER = DateTimeFormatter.ofPattern("dd/MMM/yyyy:HH:mm:ss Z");
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Prefer we use a single format and avoid the supplementary date time formatter.
See https://stackoverflow.com/a/61502608

Suggested change
private static final String FORMAT = "%s [%s] %s%n"; // qname [timestamp] extension\n
private static final DateTimeFormatter FORMATTER = DateTimeFormatter.ofPattern("dd/MMM/yyyy:HH:mm:ss Z");
private static final String FORMAT = "%s [%2$tD:%2$tT] %s%n"; // qname [timestamp] extension\n

@@ -63,6 +63,6 @@ public class Http2EventsIT
public void connectionHeaders() throws Exception
{
k3po.finish();
output.expect(Pattern.compile("test.net0 - \\[[^\\]]+\\] REQUEST_ACCEPTED http GET localhost:8080 /\n"));
output.expect(Pattern.compile("ephemeral.net0 \\[[^\\]]+\\] REQUEST_ACCEPTED - http GET localhost:8080 /\n"));
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This seems to be the wrong binding id on the event.

We need to change this test to use test binding and break dependency on http binding, then additional type-specific tests in the stdout exporter are no longer needed.

import io.aklivity.zilla.runtime.binding.http.internal.types.event.HttpRequestAcceptedExFW;
import io.aklivity.zilla.runtime.engine.event.EventFormatterSpi;

public class HttpEventFormatter implements EventFormatterSpi
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Given that formatters are not thread-safe, we'll need to switch up the spi strategy to use an EventFormatterFactorySpi that creates an EventFormatterSpi when needed to instantiate an EventFormatter per worker, instead of one instance of each EventFormatterSpi shared across all workers.

import io.aklivity.zilla.runtime.binding.http.internal.types.event.EventFW;
import io.aklivity.zilla.runtime.binding.http.internal.types.event.HttpEventExFW;

public class HttpEventFormatterTest
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I realize you prefer to write this as a unit test, but now I think we don't actually have an IT that proves the event is written when the scenario occurs, say like authorization failed.

Suggest we instead convert these unit tests to ITs and configure test exporter to have a list of expected events, so we can verify binding id, formatted event text and throw an exception if they don't match so the IT will fail.

That approach should give us good clarity in the scenarios both that the event has occurred and how it is formatted.

This feedback applies to all event formatter unit tests -> ITs.

{
case AUTHORIZATION_FAILED:
{
result = AUTHORIZATION_FAILED_FORMAT;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suspect we'd like to have attempted identity here, much like guard auth failed, agree?

@@ -108,6 +108,7 @@ scope core
int64 timestamp;
int64 traceId;
int64 namespacedId;
octets extension;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We do this in frames because extension is optional, but it is required for events (agree?) so perhaps it would be more convenient to put Extension as the type here instead of octets?

Copy link
Contributor

@jfallows jfallows left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looking good so far, needs the ITs now instead of the Tests.

jfallows
jfallows previously approved these changes Mar 4, 2024
Copy link
Contributor

@jfallows jfallows left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks good so far.

Make sure to add tls client tests, and verify minimal dependencies on stdout exporter pom now that we only need the engine apis and test binding with test events.

@Specification({
"${app}/client.handshake.timeout/client",
"${net}/client.handshake.timeout/server" })
@Configure(name = "zilla.binding.tls.handshake.timeout", value = "1")
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

These strings should be constants on TlsConfigurationTest, and TlsConfigurationTest test method should verify that the constant string matches the config property name.

Please apply the same feedback about constants (plus tests) to any new tests you've added that use @Configure.

// THEN
assertThat(result, equalTo("REMOTE_ACCESS_REJECTED GET http://localhost:8080/hello 500"));
}
}
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This should be replaced by an IT, right?

import java.util.function.Function;

import io.aklivity.zilla.runtime.engine.config.OptionsConfig;

public final class TestBindingOptionsConfig extends OptionsConfig
{
public final String mode;
public final List<String> catalogs;
public final List<Guard> guards;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Let's change guards of type List<Guard> to authorization (one, not list) of type TestAuthorizationConfig with a String name (of the referenced guard) and credentials (the token). This is more or less how we do it for HTTP binding with HttpAuthorizationConfig except that one is extracting the token from a patterned string, and here we can just specify the token directly instead.

The syntax in yaml should also follow the same approach as other binding authorization syntax.

bindings:
  test0:
    type: test
    kind: server
    options:
        authorization:
            jwt0:
                credentials: token

// THEN
assertThat(result, equalTo("AUTHORIZATION_FAILED user"));
}
}
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can be removed as we have an IT instead that exercises the event formatter via declarative test.

Please remove all the other event formatter tests as they are also covered by their ITs instead.

Comment on lines 82 to 100
"guards":
{
"type": "array",
"items":
{
"type": "object",
"properties":
{
"guard":
{
"type": "string"
},
"token":
{
"type": "string"
}
}
}
},
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please change to authorization with patternProperties and credentials as described in other feedback comment.

Comment on lines 38 to 46
bindings:
net0:
type: test
kind: server
options:
guards:
- guard: jwt0
token: eyJ0eXAiOiJKV1QiLCJhbGciOiJSUzI1NiIsImtpZCI6ImV4YW1wbGUifQ.eyJhdWQiOiJodHRwczovL2FwaS5leGFtcGxlLmNvbSIsImV4cCI6MTcwODk0MDQ0MCwiaXNzIjoiaHR0cHM6Ly9hdXRoLmV4YW1wbGUuY29tIiwic3ViIjoidXNlciJ9.KwZt_rDTDEOQ33URwZ8Gd1WqQjAIJESbt5Et309Yz7AJm1wWWyFhWm7AV6lt1rkX-eD-jVh0wHAsy7L4kdzBOErCdwFcdaB4u2jFDGn_9IK28lCedxIYmYtI4qn6eY916IIqRpwZcqzw08OEljfYUKo4UeX7JPAtha0GQmfZY1-NNcncg06xw3xkKSZ1SnIh9MZM1FNH_5QPZPL4NHP7DRXtaMn2w6YpO7n695Sc_3LuSDlfDDMVIUWuEreOzOXem6jheGIbJ-eDKhIXXPrOz1NBAJmvizbugMR7m_bodiEzzqt5ttKDs1974alrR_sYP8OYmR_rCqXc5N3lp_SW3A
exit: app0
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
bindings:
net0:
type: test
kind: server
options:
guards:
- guard: jwt0
token: eyJ0eXAiOiJKV1QiLCJhbGciOiJSUzI1NiIsImtpZCI6ImV4YW1wbGUifQ.eyJhdWQiOiJodHRwczovL2FwaS5leGFtcGxlLmNvbSIsImV4cCI6MTcwODk0MDQ0MCwiaXNzIjoiaHR0cHM6Ly9hdXRoLmV4YW1wbGUuY29tIiwic3ViIjoidXNlciJ9.KwZt_rDTDEOQ33URwZ8Gd1WqQjAIJESbt5Et309Yz7AJm1wWWyFhWm7AV6lt1rkX-eD-jVh0wHAsy7L4kdzBOErCdwFcdaB4u2jFDGn_9IK28lCedxIYmYtI4qn6eY916IIqRpwZcqzw08OEljfYUKo4UeX7JPAtha0GQmfZY1-NNcncg06xw3xkKSZ1SnIh9MZM1FNH_5QPZPL4NHP7DRXtaMn2w6YpO7n695Sc_3LuSDlfDDMVIUWuEreOzOXem6jheGIbJ-eDKhIXXPrOz1NBAJmvizbugMR7m_bodiEzzqt5ttKDs1974alrR_sYP8OYmR_rCqXc5N3lp_SW3A
exit: app0
bindings:
net0:
type: test
kind: server
options:
authorization:
jwt0:
credentials: eyJ0eXAiOiJKV1QiLCJhbGciOiJSUzI1NiIsImtpZCI6ImV4YW1wbGUifQ.eyJhdWQiOiJodHRwczovL2FwaS5leGFtcGxlLmNvbSIsImV4cCI6MTcwODk0MDQ0MCwiaXNzIjoiaHR0cHM6Ly9hdXRoLmV4YW1wbGUuY29tIiwic3ViIjoidXNlciJ9.KwZt_rDTDEOQ33URwZ8Gd1WqQjAIJESbt5Et309Yz7AJm1wWWyFhWm7AV6lt1rkX-eD-jVh0wHAsy7L4kdzBOErCdwFcdaB4u2jFDGn_9IK28lCedxIYmYtI4qn6eY916IIqRpwZcqzw08OEljfYUKo4UeX7JPAtha0GQmfZY1-NNcncg06xw3xkKSZ1SnIh9MZM1FNH_5QPZPL4NHP7DRXtaMn2w6YpO7n695Sc_3LuSDlfDDMVIUWuEreOzOXem6jheGIbJ-eDKhIXXPrOz1NBAJmvizbugMR7m_bodiEzzqt5ttKDs1974alrR_sYP8OYmR_rCqXc5N3lp_SW3A
exit: app0

@jfallows jfallows merged commit e966f88 into aklivity:develop Mar 5, 2024
5 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants