Skip to content
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
Show all changes
26 commits
Select commit Hold shift + click to select a range
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
Prev Previous commit
Next Next commit
WIP response header validation: schema, config, builder, adapter
  • Loading branch information
attilakreiner committed Jan 18, 2024
commit 83a3562ee9c52966088e31ebeb29daf392817179
Original file line number Diff line number Diff line change
Expand Up @@ -25,15 +25,18 @@ public class HttpResponseConfig
{
public final List<String> status;
public final List<String> contentType;
public final List<HttpParamConfig> headers;
public final ValidatorConfig content;

public HttpResponseConfig(
List<String> status,
List<String> contentType,
List<HttpParamConfig> headers,
ValidatorConfig content)
{
this.status = status;
this.contentType = contentType;
this.headers = headers;
this.content = content;
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@ public class HttpResponseConfigBuilder<T> extends ConfigBuilder<T, HttpResponseC

private List<String> status;
private List<String> contentType;
private List<HttpParamConfig> headers;
private ValidatorConfig content;

HttpResponseConfigBuilder(
Expand Down Expand Up @@ -65,6 +66,30 @@ public HttpResponseConfigBuilder<T> contentType(
return this;
}

public HttpResponseConfigBuilder<T> headers(
List<HttpParamConfig> headers)
{
this.headers = headers;
return this;
}

public HttpResponseConfigBuilder<T> header(
HttpParamConfig header)
{
if (this.headers == null)
{
this.headers = new LinkedList<>();
}
this.headers.add(header);
return this;
}

public HttpParamConfigBuilder<HttpResponseConfigBuilder<T>> header()
{
return new HttpParamConfigBuilder<>(this::header);
}


public HttpResponseConfigBuilder<T> content(
ValidatorConfig content)
{
Expand All @@ -81,6 +106,6 @@ public <C extends ConfigBuilder<HttpResponseConfigBuilder<T>, C>> C content(
@Override
public T build()
{
return mapper.apply(new HttpResponseConfig(status, contentType, content));
return mapper.apply(new HttpResponseConfig(status, contentType, headers, content));
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,9 @@
*/
package io.aklivity.zilla.runtime.binding.http.internal.config;

import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

import jakarta.json.Json;
Expand All @@ -27,6 +29,7 @@
import jakarta.json.JsonValue;
import jakarta.json.bind.adapter.JsonbAdapter;

import io.aklivity.zilla.runtime.binding.http.config.HttpParamConfig;
import io.aklivity.zilla.runtime.binding.http.config.HttpResponseConfig;
import io.aklivity.zilla.runtime.engine.config.ValidatorConfig;
import io.aklivity.zilla.runtime.engine.config.ValidatorConfigAdapter;
Expand All @@ -35,6 +38,7 @@ public class HttpResponseConfigAdapter implements JsonbAdapter<HttpResponseConfi
{
private static final String STATUS_NAME = "status";
private static final String CONTENT_TYPE_NAME = "content-type";
private static final String HEADERS_NAME = "headers";
private static final String CONTENT_NAME = "content";

private final ValidatorConfigAdapter validator = new ValidatorConfigAdapter();
Expand Down Expand Up @@ -63,6 +67,16 @@ public JsonObject adaptToJson(
response.contentType.forEach(contentType::add);
object.add(CONTENT_TYPE_NAME, contentType);
}
if (response.headers != null)
{
JsonObjectBuilder headers = Json.createObjectBuilder();
for (HttpParamConfig header : response.headers)
{
validator.adaptType(header.validator.type);
headers.add(header.name, validator.adaptToJson(header.validator));
}
object.add(HEADERS_NAME, headers);
}
if (response.content != null)
{
validator.adaptType(response.content.type);
Expand Down Expand Up @@ -101,12 +115,26 @@ else if (status0.getValueType() == JsonValue.ValueType.ARRAY)
.map(JsonString::getString)
.collect(Collectors.toList());
}
List<HttpParamConfig> headers = null;
if (object.containsKey(HEADERS_NAME))
{
JsonObject headersJson = object.getJsonObject(HEADERS_NAME);
headers = new LinkedList<>();
for (Map.Entry<String, JsonValue> entry : headersJson.entrySet())
{
HttpParamConfig header = HttpParamConfig.builder()
.name(entry.getKey())
.validator(validator.adaptFromJson(entry.getValue()))
.build();
headers.add(header);
}
}
ValidatorConfig content = null;
if (object.containsKey(CONTENT_NAME))
{
JsonValue contentJson = object.get(CONTENT_NAME);
content = validator.adaptFromJson(contentJson);
}
return new HttpResponseConfig(status, contentType, content);
return new HttpResponseConfig(status, contentType, headers, content);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -79,6 +79,10 @@ public void shouldReadOptions()
"[" +
"\"application/json\"" +
"]," +
"\"headers\": " +
"{" +
"\"content-type\": \"test\"" +
"}," +
"\"content\": \"test\"" +
"}," +
"{" +
Expand Down Expand Up @@ -112,6 +116,8 @@ public void shouldReadOptions()
assertThat(request.content.type, equalTo("test"));
assertThat(request.responses.get(0).status.get(0), equalTo("200"));
assertThat(request.responses.get(0).contentType.get(0), equalTo("application/json"));
assertThat(request.responses.get(0).headers.get(0).name, equalTo("content-type"));
assertThat(request.responses.get(0).headers.get(0).validator.type, equalTo("test"));
assertThat(request.responses.get(0).content.type, equalTo("test"));
assertThat(request.responses.get(1).status.get(0), equalTo("401"));
assertThat(request.responses.get(1).status.get(1), equalTo("404"));
Expand Down Expand Up @@ -154,6 +160,10 @@ public void shouldWriteOptions()
"[" +
"\"application/json\"" +
"]," +
"\"headers\":" +
"{" +
"\"content-type\":\"test\"" +
"}," +
"\"content\":\"test\"" +
"}," +
"{" +
Expand Down Expand Up @@ -190,6 +200,11 @@ public void shouldWriteOptions()
.response()
.status(200)
.contentType("application/json")
.header()
.name("content-type")
.validator(TestValidatorConfig::builder)
.build()
.build()
.content(TestValidatorConfig::builder)
.build()
.build()
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -350,6 +350,17 @@
"type": "string"
}
},
"headers":
{
"type": "object",
"patternProperties":
{
"^[a-zA-Z]+[a-zA-Z0-9\\._\\-]*$":
{
"$ref": "#/$defs/validator/type"
}
}
},
"content":
{
"$ref": "#/$defs/validator/type"
Expand All @@ -358,7 +369,8 @@
"required":
[
"content"
]
],
"additionalProperties": false
}
}
},
Expand Down