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

Config builders #330

Merged
merged 5 commits into from
Aug 10, 2023
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 @@ -141,8 +141,14 @@ private JsonArrayBuilder attributes(
MetricRecord record)
{
return attributesToJson(List.of(
new AttributeConfig("namespace", record.namespace()),
new AttributeConfig("binding", record.binding())
AttributeConfig.builder()
.name("namespace")
.value(record.namespace())
.build(),
AttributeConfig.builder()
.name("binding")
.value(record.binding())
.build()
));
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,11 @@ public void shouldCreateDefaultMetricsUrl()
OtlpOverridesConfig overrides = new OtlpOverridesConfig(null);
OtlpEndpointConfig endpoint = new OtlpEndpointConfig("http", URI.create("http://example.com"), overrides);
OtlpOptionsConfig options = new OtlpOptionsConfig(30L, Set.of(METRICS), endpoint);
ExporterConfig exporter = new ExporterConfig("oltp0", "oltp", options);
ExporterConfig exporter = ExporterConfig.builder()
.name("oltp0")
.type("oltp")
.options(options)
.build();
OtlpExporterConfig oltpExporter = new OtlpExporterConfig(exporter);

// WHEN
Expand All @@ -54,7 +58,11 @@ public void shouldOverrideAbsoluteMetricsUrl()
OtlpOverridesConfig overrides = new OtlpOverridesConfig(URI.create("http://overridden.com/metrics"));
OtlpEndpointConfig endpoint = new OtlpEndpointConfig("http", URI.create("http://example.com"), overrides);
OtlpOptionsConfig options = new OtlpOptionsConfig(30L, Set.of(METRICS), endpoint);
ExporterConfig exporter = new ExporterConfig("oltp0", "oltp", options);
ExporterConfig exporter = ExporterConfig.builder()
.name("oltp0")
.type("oltp")
.options(options)
.build();
OtlpExporterConfig oltpExporter = new OtlpExporterConfig(exporter);

// WHEN
Expand All @@ -71,7 +79,11 @@ public void shouldOverrideRelativeMetricsUrl()
OtlpOverridesConfig overrides = new OtlpOverridesConfig(URI.create("/v42/metrix"));
OtlpEndpointConfig endpoint = new OtlpEndpointConfig("http", URI.create("http://example.com"), overrides);
OtlpOptionsConfig options = new OtlpOptionsConfig(30L, Set.of(METRICS), endpoint);
ExporterConfig exporter = new ExporterConfig("oltp0", "oltp", options);
ExporterConfig exporter = ExporterConfig.builder()
.name("oltp0")
.type("oltp")
.options(options)
.build();
OtlpExporterConfig oltpExporter = new OtlpExporterConfig(exporter);

// WHEN
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,10 +15,11 @@
*/
package io.aklivity.zilla.runtime.binding.http.config;

import static io.aklivity.zilla.runtime.binding.http.config.HttpAccessControlConfig.HttpPolicyConfig.CROSS_ORIGIN;
import static io.aklivity.zilla.runtime.binding.http.config.HttpAccessControlConfig.HttpPolicyConfig.SAME_ORIGIN;
import static io.aklivity.zilla.runtime.binding.http.config.HttpPolicyConfig.CROSS_ORIGIN;
import static io.aklivity.zilla.runtime.binding.http.config.HttpPolicyConfig.SAME_ORIGIN;
import static java.lang.ThreadLocal.withInitial;
import static java.util.Collections.unmodifiableSet;
import static java.util.function.Function.identity;
import static java.util.regex.Pattern.CASE_INSENSITIVE;

import java.net.URI;
Expand All @@ -42,7 +43,7 @@ public final class HttpAccessControlConfig
private static final Pattern HEADERS_PATTERN = Pattern.compile("([^,\\s]+)(:?,\\s*([^,\\\\s]+))*", CASE_INSENSITIVE);

private static final ThreadLocal<Matcher> ORIGIN_MATCHER = withInitial(() -> ORIGIN_PATTERN.matcher(""));
private static final ThreadLocal<Matcher> HEADERS_MATCHER = withInitial(() -> HEADERS_PATTERN.matcher(""));
static final ThreadLocal<Matcher> HEADERS_MATCHER = withInitial(() -> HEADERS_PATTERN.matcher(""));

private static final ThreadLocal<HttpHeaderFW.Builder> HEADER_BUILDER = ThreadLocal.withInitial(HttpHeaderFW.Builder::new);

Expand Down Expand Up @@ -82,33 +83,23 @@ public final class HttpAccessControlConfig
EXPOSED_RESPONSE_HEADERS = unmodifiableSet(headers);
}

public enum HttpPolicyConfig
{
SAME_ORIGIN,
CROSS_ORIGIN
}

public final HttpPolicyConfig policy;
public final HttpAllowConfig allow;
public final Duration maxAge;
public final HttpExposeConfig expose;

public HttpAccessControlConfig(
HttpPolicyConfig policy)
public static HttpAccessControlConfigBuilder<HttpAccessControlConfig> builder()
{
this.policy = policy;
this.allow = null;
this.maxAge = null;
this.expose = null;
return new HttpAccessControlConfigBuilder<>(identity());
}

public HttpAccessControlConfig(
HttpAccessControlConfig(
HttpPolicyConfig policy,
HttpAllowConfig allow,
Duration maxAge,
HttpExposeConfig expose)
{
this.policy = CROSS_ORIGIN;
this.policy = policy;
this.allow = allow;
this.maxAge = maxAge;
this.expose = expose;
Expand Down Expand Up @@ -296,127 +287,15 @@ private boolean matchesAuthority(
return matches;
}

public static final class HttpAllowConfig
{
public final Set<String> origins;
public final Set<String> methods;
public final Set<String> headers;
public final boolean credentials;

private final Set<String> implicitOrigins;

public HttpAllowConfig(
Set<String> origins,
Set<String> methods,
Set<String> headers,
boolean credentials)
{
this.origins = origins;
this.implicitOrigins = origins != null ? asImplicitOrigins(origins) : null;
this.methods = methods;
this.headers = headers != null ? asCaseless(headers) : null;
this.credentials = credentials;
}

private boolean origin(
String origin)
{
return origins == null ||
origins.contains(origin) ||
implicitOrigins.contains(origin);
}

private boolean method(
String method)
{
return methods == null ||
methods.contains(method);
}

private boolean headers(
String headers)
{
return headers == null ||
headersMatch(headers);
}

private boolean headersMatch(
String headers)
{
int match = 0;

Matcher matchHeaders = HEADERS_MATCHER.get().reset(headers);
while (matchHeaders.find())
{
if (header(matchHeaders.group(1)))
{
match++;
}
}

return match > 0;
}

private boolean header(
String header)
{
return headers == null ||
headers.contains(header);
}

private boolean originExplicit()
{
return credentials || origins != null;
}

private boolean methodsExplicit()
{
return credentials || methods != null;
}

private boolean headersExplicit()
{
return credentials || headers != null;
}

public boolean credentialsExplicit()
{
return credentials;
}
}

public static final class HttpExposeConfig
{
public final Set<String> headers;

public HttpExposeConfig(
Set<String> headers)
{
this.headers = headers;
}

private boolean header(
String header)
{
return headers == null ||
headers.contains(header);
}

private boolean headersExplicit()
{
return headers != null;
}
}

private static Set<String> asCaseless(
static Set<String> asCaseless(
Set<String> cased)
{
final Set<String> caseless = new TreeSet<String>(String::compareToIgnoreCase);
caseless.addAll(cased);
return caseless;
}

private static Set<String> asImplicitOrigins(
static Set<String> asImplicitOrigins(
Set<String> origins)
{
Set<String> implicit = new LinkedHashSet<>();
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,81 @@
/*
* Copyright 2021-2023 Aklivity Inc.
*
* Aklivity licenses this file to you under the Apache License,
* version 2.0 (the "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at:
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
* License for the specific language governing permissions and limitations
* under the License.
*/
package io.aklivity.zilla.runtime.binding.http.config;

import java.time.Duration;
import java.util.function.Function;

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

public final class HttpAccessControlConfigBuilder<T> implements ConfigBuilder<T>
{
private final Function<HttpAccessControlConfig, T> mapper;

private HttpPolicyConfig policy;
private HttpAllowConfig allow;
private Duration maxAge;
private HttpExposeConfig expose;

HttpAccessControlConfigBuilder(
Function<HttpAccessControlConfig, T> mapper)
{
this.mapper = mapper;
}

public HttpAccessControlConfigBuilder<T> policy(
HttpPolicyConfig policy)
{
this.policy = policy;
return this;
}

public HttpAllowConfigBuilder<HttpAccessControlConfigBuilder<T>> allow()
{
return new HttpAllowConfigBuilder<>(this::allow);
}

public HttpAccessControlConfigBuilder<T> maxAge(
Duration maxAge)
{
this.maxAge = maxAge;
return this;
}

public HttpExposeConfigBuilder<HttpAccessControlConfigBuilder<T>> expose()
{
return new HttpExposeConfigBuilder<>(this::expose);
}

@Override
public T build()
{
return mapper.apply(new HttpAccessControlConfig(policy, allow, maxAge, expose));
}

private HttpAccessControlConfigBuilder<T> allow(
HttpAllowConfig allow)
{
this.allow = allow;
return this;
}

private HttpAccessControlConfigBuilder<T> expose(
HttpExposeConfig expose)
{
this.expose = expose;
return this;
}
}
Loading