make server HTTP request serializable in json
This commit is contained in:
parent
9c551e3c34
commit
e3adbd4369
8 changed files with 144 additions and 11 deletions
|
@ -1,5 +1,5 @@
|
||||||
group = org.xbib
|
group = org.xbib
|
||||||
name = net-http
|
name = net-http
|
||||||
version = 3.6.1
|
version = 3.6.2
|
||||||
|
|
||||||
org.gradle.warning.mode = ALL
|
org.gradle.warning.mode = ALL
|
||||||
|
|
|
@ -5,6 +5,7 @@ import io.netty.buffer.ByteBufUtil;
|
||||||
import io.netty.handler.codec.http.FullHttpRequest;
|
import io.netty.handler.codec.http.FullHttpRequest;
|
||||||
import io.netty.handler.codec.http.multipart.FileUpload;
|
import io.netty.handler.codec.http.multipart.FileUpload;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
|
import java.util.Map;
|
||||||
import java.util.logging.Level;
|
import java.util.logging.Level;
|
||||||
import java.util.logging.Logger;
|
import java.util.logging.Logger;
|
||||||
import org.xbib.net.Parameter;
|
import org.xbib.net.Parameter;
|
||||||
|
@ -33,6 +34,11 @@ public class HttpRequestBuilder extends BaseHttpRequestBuilder {
|
||||||
protected HttpRequestBuilder() {
|
protected HttpRequestBuilder() {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public HttpRequestBuilder parse(Map<String, Object> map) {
|
||||||
|
super.parse(map);
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
public HttpRequestBuilder setHttpRequest(io.netty.handler.codec.http.HttpRequest httpRequest) {
|
public HttpRequestBuilder setHttpRequest(io.netty.handler.codec.http.HttpRequest httpRequest) {
|
||||||
if (httpRequest != null) {
|
if (httpRequest != null) {
|
||||||
setVersion(HttpVersion.valueOf(httpRequest.protocolVersion().text()));
|
setVersion(HttpVersion.valueOf(httpRequest.protocolVersion().text()));
|
||||||
|
|
|
@ -52,9 +52,7 @@ public class NettyHttp2ServerTest {
|
||||||
.header(HttpHeaderNames.CONTENT_TYPE, HttpHeaderValues.TEXT_PLAIN)
|
.header(HttpHeaderNames.CONTENT_TYPE, HttpHeaderValues.TEXT_PLAIN)
|
||||||
.charset(StandardCharsets.UTF_8)
|
.charset(StandardCharsets.UTF_8)
|
||||||
.body("Hello, here is my response: " +
|
.body("Hello, here is my response: " +
|
||||||
ctx.getRequest().getParameter() + " " +
|
ctx.getRequest().asJson())
|
||||||
ctx.getRequest().getLocalAddress() + " " +
|
|
||||||
ctx.getRequest().getRemoteAddress())
|
|
||||||
.done();
|
.done();
|
||||||
})
|
})
|
||||||
.build())
|
.build())
|
||||||
|
|
|
@ -1,6 +1,9 @@
|
||||||
package org.xbib.net.http.netty.test;
|
package org.xbib.net.http.netty.test;
|
||||||
|
|
||||||
import io.netty.bootstrap.Bootstrap;
|
import io.netty.bootstrap.Bootstrap;
|
||||||
|
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.util.Map;
|
||||||
import java.util.concurrent.atomic.AtomicBoolean;
|
import java.util.concurrent.atomic.AtomicBoolean;
|
||||||
import java.util.logging.Level;
|
import java.util.logging.Level;
|
||||||
import org.junit.jupiter.api.Test;
|
import org.junit.jupiter.api.Test;
|
||||||
|
@ -9,7 +12,9 @@ import org.xbib.net.URL;
|
||||||
import org.xbib.net.http.HttpAddress;
|
import org.xbib.net.http.HttpAddress;
|
||||||
import org.xbib.net.http.HttpHeaderNames;
|
import org.xbib.net.http.HttpHeaderNames;
|
||||||
import org.xbib.net.http.HttpHeaderValues;
|
import org.xbib.net.http.HttpHeaderValues;
|
||||||
|
import org.xbib.net.http.HttpMethod;
|
||||||
import org.xbib.net.http.HttpResponseStatus;
|
import org.xbib.net.http.HttpResponseStatus;
|
||||||
|
import org.xbib.net.http.client.HttpRequestBuilder;
|
||||||
import org.xbib.net.http.client.netty.HttpRequest;
|
import org.xbib.net.http.client.netty.HttpRequest;
|
||||||
import org.xbib.net.http.client.netty.NettyHttpClient;
|
import org.xbib.net.http.client.netty.NettyHttpClient;
|
||||||
import org.xbib.net.http.client.netty.NettyHttpClientConfig;
|
import org.xbib.net.http.client.netty.NettyHttpClientConfig;
|
||||||
|
@ -22,6 +27,7 @@ import org.xbib.net.http.server.route.HttpRouter;
|
||||||
import org.xbib.net.http.server.service.BaseHttpService;
|
import org.xbib.net.http.server.service.BaseHttpService;
|
||||||
import org.xbib.net.http.server.netty.NettyHttpServer;
|
import org.xbib.net.http.server.netty.NettyHttpServer;
|
||||||
import org.xbib.net.http.server.netty.NettyHttpServerConfig;
|
import org.xbib.net.http.server.netty.NettyHttpServerConfig;
|
||||||
|
import org.xbib.net.util.JsonUtil;
|
||||||
|
|
||||||
import java.nio.charset.StandardCharsets;
|
import java.nio.charset.StandardCharsets;
|
||||||
import java.util.logging.Logger;
|
import java.util.logging.Logger;
|
||||||
|
@ -50,11 +56,7 @@ public class NettyHttpServerTest {
|
||||||
ctx.status(HttpResponseStatus.OK)
|
ctx.status(HttpResponseStatus.OK)
|
||||||
.header(HttpHeaderNames.CONTENT_TYPE, HttpHeaderValues.TEXT_PLAIN)
|
.header(HttpHeaderNames.CONTENT_TYPE, HttpHeaderValues.TEXT_PLAIN)
|
||||||
.charset(StandardCharsets.UTF_8)
|
.charset(StandardCharsets.UTF_8)
|
||||||
.body("domain" +
|
.body(ctx.getRequest().asJson())
|
||||||
" parameter = " + ctx.getRequest().getParameter().toString() +
|
|
||||||
" local address = " + ctx.getRequest().getLocalAddress() +
|
|
||||||
" remote address = " + ctx.getRequest().getRemoteAddress() +
|
|
||||||
" attributes = " + ctx.getAttributes())
|
|
||||||
.done();
|
.done();
|
||||||
})
|
})
|
||||||
.build())
|
.build())
|
||||||
|
@ -81,10 +83,19 @@ public class NettyHttpServerTest {
|
||||||
HttpRequest request = HttpRequest.get()
|
HttpRequest request = HttpRequest.get()
|
||||||
.setURL(url)
|
.setURL(url)
|
||||||
.setResponseListener(resp -> {
|
.setResponseListener(resp -> {
|
||||||
|
String body = resp.getBodyAsChars(StandardCharsets.UTF_8).toString();
|
||||||
logger.log(Level.INFO, "got response:" +
|
logger.log(Level.INFO, "got response:" +
|
||||||
" status = " + resp.getStatus() +
|
" status = " + resp.getStatus() +
|
||||||
" header = " + resp.getHeaders() +
|
" header = " + resp.getHeaders() +
|
||||||
" body = " + resp.getBodyAsChars(StandardCharsets.UTF_8));
|
" body = " + body);
|
||||||
|
try {
|
||||||
|
Map<String, Object> map = JsonUtil.toMap(body);
|
||||||
|
org.xbib.net.http.server.netty.HttpRequest httpRequest = org.xbib.net.http.server.netty.HttpRequest.builder()
|
||||||
|
.parse(map).build();
|
||||||
|
logger.log(Level.INFO, "parsed http request = " + httpRequest.asJson());
|
||||||
|
} catch (IOException e) {
|
||||||
|
throw new RuntimeException(e);
|
||||||
|
}
|
||||||
received.set(true);
|
received.set(true);
|
||||||
})
|
})
|
||||||
.build();
|
.build();
|
||||||
|
|
|
@ -1,9 +1,19 @@
|
||||||
package org.xbib.net.http.server;
|
package org.xbib.net.http.server;
|
||||||
|
|
||||||
|
import java.io.IOException;
|
||||||
import java.net.InetSocketAddress;
|
import java.net.InetSocketAddress;
|
||||||
|
import java.nio.charset.StandardCharsets;
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.LinkedHashMap;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
|
import java.util.stream.Collectors;
|
||||||
|
|
||||||
|
import org.xbib.datastructures.common.Pair;
|
||||||
|
import org.xbib.datastructures.json.tiny.JsonBuilder;
|
||||||
import org.xbib.net.Attributes;
|
import org.xbib.net.Attributes;
|
||||||
import org.xbib.net.Parameter;
|
import org.xbib.net.Parameter;
|
||||||
|
import org.xbib.net.ParameterException;
|
||||||
import org.xbib.net.URL;
|
import org.xbib.net.URL;
|
||||||
import org.xbib.net.http.HttpHeaders;
|
import org.xbib.net.http.HttpHeaders;
|
||||||
import org.xbib.net.http.HttpMethod;
|
import org.xbib.net.http.HttpMethod;
|
||||||
|
@ -101,4 +111,59 @@ public abstract class BaseHttpRequest implements HttpRequest {
|
||||||
public Attributes getAttributes() {
|
public Attributes getAttributes() {
|
||||||
return attributes;
|
return attributes;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String asJson() {
|
||||||
|
JsonBuilder jsonBuilder = JsonBuilder.builder();
|
||||||
|
try {
|
||||||
|
jsonBuilder.beginMap();
|
||||||
|
Map<String, Object> local = Map.of("host", builder.localAddress.getHostString(), "port", builder.localAddress.getPort());
|
||||||
|
jsonBuilder.buildKey("local").buildMap(local);
|
||||||
|
Map<String, Object> remote = Map.of("host", builder.remoteAddress.getHostString(), "port", builder.remoteAddress.getPort());
|
||||||
|
jsonBuilder.buildKey("remote").buildMap(remote);
|
||||||
|
jsonBuilder.buildKey("baseurl").buildValue(builder.baseURL.toString());
|
||||||
|
jsonBuilder.buildKey("version").buildValue(builder.getVersion().toString());
|
||||||
|
jsonBuilder.buildKey("method").buildValue(builder.getMethod().toString());
|
||||||
|
Map<String, Object> headerMap = builder.getHeaders().entries().stream()
|
||||||
|
.collect(Collectors.toMap(Pair::getKey, Pair::getValue, (x, y) -> y, LinkedHashMap::new));
|
||||||
|
jsonBuilder.buildKey("header").buildMap(headerMap);
|
||||||
|
jsonBuilder.buildKey("requesturi").buildValue(builder.getRequestURI());
|
||||||
|
jsonBuilder.buildKey("requestpath").buildValue(builder.getRequestPath());
|
||||||
|
Parameter queryParameter = builder.parameter.get(Parameter.Domain.QUERY);
|
||||||
|
Map<String, Object> queryParameterMap = queryParameter != null ?
|
||||||
|
queryParameter.asMultiMap().asMap().entrySet().stream()
|
||||||
|
.collect(Collectors.toMap(Map.Entry::getKey, Map.Entry::getValue, (x, y) -> y, LinkedHashMap::new)) : Map.of();
|
||||||
|
Parameter pathParameter = builder.parameter.get(Parameter.Domain.PATH);
|
||||||
|
Map<String, Object> pathParameterMap = pathParameter != null ?
|
||||||
|
pathParameter.asMultiMap().asMap().entrySet().stream()
|
||||||
|
.collect(Collectors.toMap(Map.Entry::getKey, Map.Entry::getValue, (x, y) -> y, LinkedHashMap::new)) : Map.of();
|
||||||
|
Parameter formParameter = builder.parameter.get(Parameter.Domain.FORM);
|
||||||
|
Map<String, Object> formParameterMap = formParameter != null ?
|
||||||
|
formParameter.asMultiMap().asMap().entrySet().stream()
|
||||||
|
.collect(Collectors.toMap(Map.Entry::getKey, Map.Entry::getValue, (x, y) -> y, LinkedHashMap::new)) : Map.of();
|
||||||
|
Parameter cookieParameter = builder.parameter.get(Parameter.Domain.COOKIE);
|
||||||
|
Map<String, Object> cookieParameterMap = cookieParameter != null ?
|
||||||
|
cookieParameter.asMultiMap().asMap().entrySet().stream()
|
||||||
|
.collect(Collectors.toMap(Map.Entry::getKey, Map.Entry::getValue, (x, y) -> y, LinkedHashMap::new)) : Map.of();
|
||||||
|
Parameter headerParameter = builder.parameter.get(Parameter.Domain.HEADER);
|
||||||
|
Map<String, Object> headerParameterMap = headerParameter != null ?
|
||||||
|
headerParameter.asMultiMap().asMap().entrySet().stream()
|
||||||
|
.collect(Collectors.toMap(Map.Entry::getKey, Map.Entry::getValue, (x, y) -> y, LinkedHashMap::new)) : Map.of();
|
||||||
|
jsonBuilder.buildKey("parameter").buildMap(Map.of("query", queryParameterMap,
|
||||||
|
"path", pathParameterMap,
|
||||||
|
"form", formParameterMap,
|
||||||
|
"cookie", cookieParameterMap,
|
||||||
|
"header", headerParameterMap));
|
||||||
|
jsonBuilder.buildKey("sequenceid").buildValue(builder.sequenceId);
|
||||||
|
jsonBuilder.buildKey("streamid").buildValue(builder.streamId);
|
||||||
|
jsonBuilder.buildKey("requestid").buildValue(builder.requestId);
|
||||||
|
// body may be large
|
||||||
|
//jsonBuilder.buildKey("encoding").buildValue("ISO-8859-1");
|
||||||
|
//jsonBuilder.buildKey("body").buildValue(StandardCharsets.ISO_8859_1.decode(builder.getBody()).toString());
|
||||||
|
jsonBuilder.endMap();
|
||||||
|
} catch (IOException | ParameterException e) {
|
||||||
|
// ignore
|
||||||
|
}
|
||||||
|
return jsonBuilder.build();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,13 +1,20 @@
|
||||||
package org.xbib.net.http.server;
|
package org.xbib.net.http.server;
|
||||||
|
|
||||||
|
import java.net.InetAddress;
|
||||||
import java.net.InetSocketAddress;
|
import java.net.InetSocketAddress;
|
||||||
import java.nio.ByteBuffer;
|
import java.nio.ByteBuffer;
|
||||||
import java.nio.CharBuffer;
|
import java.nio.CharBuffer;
|
||||||
import java.nio.charset.Charset;
|
import java.nio.charset.Charset;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
|
import java.util.Arrays;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
import java.util.Locale;
|
||||||
|
import java.util.Map;
|
||||||
import java.util.Objects;
|
import java.util.Objects;
|
||||||
|
|
||||||
|
import org.xbib.datastructures.common.Maps;
|
||||||
import org.xbib.net.Parameter;
|
import org.xbib.net.Parameter;
|
||||||
|
import org.xbib.net.ParameterBuilder;
|
||||||
import org.xbib.net.URL;
|
import org.xbib.net.URL;
|
||||||
import org.xbib.net.URLBuilder;
|
import org.xbib.net.URLBuilder;
|
||||||
import org.xbib.net.http.HttpAddress;
|
import org.xbib.net.http.HttpAddress;
|
||||||
|
@ -59,6 +66,50 @@ public abstract class BaseHttpRequestBuilder implements HttpRequestBuilder {
|
||||||
this.messages = new ArrayList<>();
|
this.messages = new ArrayList<>();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@SuppressWarnings("unchecked")
|
||||||
|
public BaseHttpRequestBuilder parse(Map<String, Object> map) {
|
||||||
|
Map<String, Object> localMap = (Map<String, Object>) map.get("local");
|
||||||
|
String localHost = Maps.getString(localMap, "host");
|
||||||
|
int localPort = Maps.getInteger(localMap, "port", -1);
|
||||||
|
setLocalAddress(new InetSocketAddress(localHost, localPort));
|
||||||
|
Map<String, Object> remoteMap = (Map<String, Object>) map.get("remote");
|
||||||
|
String remoteHost = Maps.getString(remoteMap, "host");
|
||||||
|
int remotePort = Maps.getInteger(remoteMap, "port", -1);
|
||||||
|
setRemoteAddress(new InetSocketAddress(remoteHost, remotePort));
|
||||||
|
setBaseURL(URL.from(Maps.getString(map, "baseurl")));
|
||||||
|
setVersion(HttpVersion.valueOf(Maps.getString(map, "version")));
|
||||||
|
setMethod(HttpMethod.valueOf(Maps.getString(map, "method")));
|
||||||
|
HttpHeaders httpHeaders = new HttpHeaders();
|
||||||
|
Map<String, Object> headerMap = (Map<String, Object>) map.get("header");
|
||||||
|
if (headerMap != null) {
|
||||||
|
headerMap.forEach((k, v) -> {
|
||||||
|
if (v instanceof Iterable<?> ) {
|
||||||
|
httpHeaders.add(k, (Iterable<?>) v);
|
||||||
|
} else {
|
||||||
|
httpHeaders.add(k, v.toString());
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
setHeaders(httpHeaders);
|
||||||
|
setRequestURI(Maps.getString(map, "requesturi"));
|
||||||
|
setRequestPath(Maps.getString(map, "requestpath"));
|
||||||
|
ParameterBuilder parameterBuilder = Parameter.builder().domain(Parameter.Domain.QUERY);
|
||||||
|
Map<String, Object> parameterMap = (Map<String, Object>) map.get("parameter");
|
||||||
|
Arrays.asList(Parameter.Domain.QUERY, Parameter.Domain.PATH, Parameter.Domain.FORM, Parameter.Domain.COOKIE, Parameter.Domain.HEADER).forEach(d -> {
|
||||||
|
Map<String, Object> m = (Map<String, Object>) parameterMap.get(d.name().toLowerCase(Locale.ROOT));
|
||||||
|
if (m != null) {
|
||||||
|
ParameterBuilder p = Parameter.builder().domain(d);
|
||||||
|
m.forEach(p::add);
|
||||||
|
parameterBuilder.add(p.build());
|
||||||
|
}
|
||||||
|
});
|
||||||
|
setParameter(parameterBuilder.build());
|
||||||
|
setSequenceId(Maps.getInteger(map, "sequenceid", 0));
|
||||||
|
setStreamId(Maps.getInteger(map, "streamid", -1));
|
||||||
|
setRequestId(Maps.getLong(map, "requestid", -1L));
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public BaseHttpRequestBuilder setContext(HttpRouterContext httpRouterContext) {
|
public BaseHttpRequestBuilder setContext(HttpRouterContext httpRouterContext) {
|
||||||
if (done) {
|
if (done) {
|
||||||
|
|
|
@ -43,4 +43,6 @@ public interface HttpRequest extends Request {
|
||||||
List<Message> getMessages();
|
List<Message> getMessages();
|
||||||
|
|
||||||
Attributes getAttributes();
|
Attributes getAttributes();
|
||||||
|
|
||||||
|
String asJson();
|
||||||
}
|
}
|
||||||
|
|
|
@ -6,7 +6,7 @@ dependencyResolutionManagement {
|
||||||
version('groovy', '4.0.13')
|
version('groovy', '4.0.13')
|
||||||
version('netty', '4.1.96.Final')
|
version('netty', '4.1.96.Final')
|
||||||
version('netty-tcnative', '2.0.61.Final')
|
version('netty-tcnative', '2.0.61.Final')
|
||||||
version('datastructures', '2.3.0')
|
version('datastructures', '2.3.1')
|
||||||
version('config', '5.0.3')
|
version('config', '5.0.3')
|
||||||
version('net', '3.3.3')
|
version('net', '3.3.3')
|
||||||
library('junit-jupiter-api', 'org.junit.jupiter', 'junit-jupiter-api').versionRef('junit')
|
library('junit-jupiter-api', 'org.junit.jupiter', 'junit-jupiter-api').versionRef('junit')
|
||||||
|
|
Loading…
Reference in a new issue