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

feature: seata-server support http protocol #6801

Merged
merged 76 commits into from
Oct 27, 2024
Merged
Show file tree
Hide file tree
Changes from 75 commits
Commits
Show all changes
76 commits
Select commit Hold shift + click to select a range
e96ea17
grpc protocol
PleaseGiveMeTheCoke Aug 14, 2024
2e9d232
grpc protocol
PleaseGiveMeTheCoke Aug 16, 2024
be0448a
grpc protocol
PleaseGiveMeTheCoke Aug 16, 2024
6cbbac0
grpc protocol
PleaseGiveMeTheCoke Aug 16, 2024
bea5592
grpc protocol
PleaseGiveMeTheCoke Aug 16, 2024
c970d20
Merge branch '2.x' into grpc_support
PleaseGiveMeTheCoke Aug 22, 2024
899f490
delete no need change
PleaseGiveMeTheCoke Aug 22, 2024
44675d9
Merge remote-tracking branch 'origin/grpc_support' into grpc_support
PleaseGiveMeTheCoke Aug 22, 2024
5bf5038
cr
PleaseGiveMeTheCoke Aug 22, 2024
548fa42
1. mock test
PleaseGiveMeTheCoke Aug 25, 2024
1e9a0c2
cr
PleaseGiveMeTheCoke Aug 25, 2024
c4e0bc4
cr
PleaseGiveMeTheCoke Aug 25, 2024
24c0d23
Delete seata-test-grpc/src/main/java/org/apache/seata/grpc/generated/…
PleaseGiveMeTheCoke Aug 25, 2024
4e2fe65
Delete seata-test-grpc/src/main/java/org/apache/seata/grpc/generated/…
PleaseGiveMeTheCoke Aug 25, 2024
022b9cb
Delete seata-test-grpc/src/main/java/org/apache/seata/grpc/generated/…
PleaseGiveMeTheCoke Aug 25, 2024
a7762a2
Delete serializer/seata-serializer-protobuf/src/main/java/org/apache/…
PleaseGiveMeTheCoke Aug 25, 2024
0ba622c
Delete seata-test-grpc/src/main/java/org/apache/seata/grpc/generated/…
PleaseGiveMeTheCoke Aug 25, 2024
397b90c
cr
PleaseGiveMeTheCoke Aug 25, 2024
4d36883
Merge remote-tracking branch 'origin/grpc_support' into grpc_support
PleaseGiveMeTheCoke Aug 25, 2024
f71391b
Merge branch '2.x' into grpc_support
funky-eyes Aug 28, 2024
05552c0
cr
PleaseGiveMeTheCoke Aug 31, 2024
6dbefc3
Merge remote-tracking branch 'origin/grpc_support' into grpc_support
PleaseGiveMeTheCoke Aug 31, 2024
c7da0ff
cr
PleaseGiveMeTheCoke Aug 31, 2024
6b04158
Merge branch '2.x' into grpc_support
PleaseGiveMeTheCoke Aug 31, 2024
b93add1
cr
PleaseGiveMeTheCoke Aug 31, 2024
e1b7409
Merge remote-tracking branch 'origin/grpc_support' into grpc_support
PleaseGiveMeTheCoke Aug 31, 2024
e45049c
cr
PleaseGiveMeTheCoke Aug 31, 2024
0621acd
cr
PleaseGiveMeTheCoke Aug 31, 2024
06dfe34
cr
PleaseGiveMeTheCoke Aug 31, 2024
c701a79
cr
PleaseGiveMeTheCoke Aug 31, 2024
ad8bf75
cr
PleaseGiveMeTheCoke Aug 31, 2024
706eb0b
cr
PleaseGiveMeTheCoke Aug 31, 2024
ebbf0f5
cr
PleaseGiveMeTheCoke Aug 31, 2024
29da916
cr
PleaseGiveMeTheCoke Aug 31, 2024
8a51486
cr
PleaseGiveMeTheCoke Aug 31, 2024
725d4b2
cr
PleaseGiveMeTheCoke Aug 31, 2024
c35f31d
cr
PleaseGiveMeTheCoke Aug 31, 2024
1e41528
cr
PleaseGiveMeTheCoke Aug 31, 2024
e643912
http support
PleaseGiveMeTheCoke Aug 31, 2024
2fe8542
http
PleaseGiveMeTheCoke Sep 7, 2024
97be3cc
http
PleaseGiveMeTheCoke Sep 8, 2024
c02d8b6
http
PleaseGiveMeTheCoke Sep 8, 2024
2892e92
Merge remote-tracking branch 'origin/2.x' into http_support
PleaseGiveMeTheCoke Oct 6, 2024
850694a
Merge remote-tracking branch 'origin/2.x' into http_support
PleaseGiveMeTheCoke Oct 6, 2024
5799ed0
Merge remote-tracking branch 'origin/2.x' into http_support
PleaseGiveMeTheCoke Oct 6, 2024
f76eb5a
resolve conflict
PleaseGiveMeTheCoke Oct 6, 2024
af5e002
delete httpController
PleaseGiveMeTheCoke Oct 6, 2024
2175e7b
delete httpController
PleaseGiveMeTheCoke Oct 6, 2024
461bf1a
http2 watch
PleaseGiveMeTheCoke Oct 7, 2024
a937346
http2 watch
PleaseGiveMeTheCoke Oct 7, 2024
6d0d252
http2 watch
PleaseGiveMeTheCoke Oct 7, 2024
c909cc2
http2 watch
PleaseGiveMeTheCoke Oct 10, 2024
02d732c
http2 watch
PleaseGiveMeTheCoke Oct 11, 2024
094a82c
http2 watch
PleaseGiveMeTheCoke Oct 12, 2024
6a950fa
Merge branch '2.x' into http_support
funky-eyes Oct 12, 2024
b718a5a
http2 watch
PleaseGiveMeTheCoke Oct 12, 2024
cd23d21
Merge remote-tracking branch 'origin/http_support' into http_support
PleaseGiveMeTheCoke Oct 12, 2024
c503e32
http2 watch
PleaseGiveMeTheCoke Oct 13, 2024
6d94a2c
http2 watch
PleaseGiveMeTheCoke Oct 13, 2024
8b68d8a
http2 watch
PleaseGiveMeTheCoke Oct 13, 2024
5d77fd9
http2 watch
PleaseGiveMeTheCoke Oct 15, 2024
1a3a6fa
http2 watch
PleaseGiveMeTheCoke Oct 17, 2024
1f75bd2
Merge branch '2.x' of https://github.com/PleaseGiveMeTheCoke/seata in…
PleaseGiveMeTheCoke Oct 18, 2024
d578520
http2 watch
PleaseGiveMeTheCoke Oct 18, 2024
7eb6530
http2 watch
PleaseGiveMeTheCoke Oct 18, 2024
62f1279
http2 watch
PleaseGiveMeTheCoke Oct 18, 2024
5d24f0e
http2 watch
PleaseGiveMeTheCoke Oct 18, 2024
1b7ecb5
http2 watch
PleaseGiveMeTheCoke Oct 18, 2024
c1da7ad
http2 watch
PleaseGiveMeTheCoke Oct 18, 2024
986418d
http2 watch
PleaseGiveMeTheCoke Oct 19, 2024
8db87a0
http2 watch
PleaseGiveMeTheCoke Oct 19, 2024
95ec3e2
http2 watch
PleaseGiveMeTheCoke Oct 19, 2024
5fff774
http2 watch
PleaseGiveMeTheCoke Oct 20, 2024
043df21
Merge branch '2.x' into http_support
PleaseGiveMeTheCoke Oct 20, 2024
40dd863
Merge branch 'summer-code-http2' into http_support
funky-eyes Oct 27, 2024
07897ee
Update common/pom.xml
funky-eyes Oct 27, 2024
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
1 change: 1 addition & 0 deletions changes/en-us/2.x.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ Add changes here for all PR submitted to the 2.x branch.
- [[#6876](https://github.com/apache/incubator-seata/pull/6876)] support kingbase
- [[#6881](https://github.com/apache/incubator-seata/pull/6881)] support grpc
- [[#6864](https://github.com/apache/incubator-seata/pull/6864)] support shentong database
- [[#6801](https://github.com/apache/incubator-seata/pull/6801)] seata-server support http protocol

### bugfix:
- [[#6899](https://github.com/apache/incubator-seata/pull/6899)] fix file.conf read failed after package
Expand Down
2 changes: 1 addition & 1 deletion changes/zh-cn/2.x.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
- [[#6876](https://github.com/apache/incubator-seata/pull/6876)] 支持人大金仓数据库(kingbase)
- [[#6881](https://github.com/apache/incubator-seata/pull/6881)] client和server支持grpc协议
- [[#6864](https://github.com/apache/incubator-seata/pull/6864)] 支持神通数据库(oscar)

- [[#6801](https://github.com/apache/incubator-seata/pull/6801)] seata-server 支持HTTP协议的解析

### bugfix:
- [[#6899](https://github.com/apache/incubator-seata/pull/6899)] 修复file.conf打包后的读取
Expand Down
6 changes: 6 additions & 0 deletions common/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -52,5 +52,11 @@
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-databind</artifactId>
</dependency>
<!-- https://mvnrepository.com/artifact/com.squareup.okhttp3/okhttp -->
funky-eyes marked this conversation as resolved.
Show resolved Hide resolved
<dependency>
<groupId>com.squareup.okhttp3</groupId>
<artifactId>okhttp</artifactId>
funky-eyes marked this conversation as resolved.
Show resolved Hide resolved
<scope>provided</scope>
</dependency>
</dependencies>
</project>
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,7 @@ public interface DefaultValues {
String DEFAULT_NIO_WORKER_THREAD_PREFIX = "NettyServerNIOWorker";
String DEFAULT_EXECUTOR_THREAD_PREFIX = "NettyServerBizHandler";
String DEFAULT_PROTOCOL = "seata";
String DEFAULT_HTTP_VERSION = "http";

boolean DEFAULT_TRANSPORT_HEARTBEAT = true;
boolean DEFAULT_TRANSACTION_UNDO_DATA_VALIDATION = true;
Expand Down
4 changes: 4 additions & 0 deletions core/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -69,6 +69,10 @@
<artifactId>fastjson</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-databind</artifactId>
</dependency>
<dependency>
<groupId>com.google.protobuf</groupId>
<artifactId>protobuf-java</artifactId>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -24,8 +24,7 @@
import io.netty.handler.codec.http2.Http2MultiplexHandler;
import io.netty.handler.codec.http2.Http2StreamChannel;
import io.netty.util.CharsetUtil;
import org.apache.seata.core.rpc.netty.grpc.GrpcDecoder;
import org.apache.seata.core.rpc.netty.grpc.GrpcEncoder;
import org.apache.seata.core.rpc.netty.http2.Http2DetectHandler;

public class Http2Detector implements ProtocolDetector {
private static final byte[] HTTP2_PREFIX_BYTES = "PRI * HTTP/2.0\r\n\r\nSM\r\n\r\n".getBytes(CharsetUtil.UTF_8);
Expand Down Expand Up @@ -56,9 +55,7 @@ public ChannelHandler[] getHandlers() {
@Override
protected void initChannel(Http2StreamChannel ch) {
final ChannelPipeline p = ch.pipeline();
p.addLast(new GrpcDecoder());
p.addLast(new GrpcEncoder());
p.addLast(serverHandlers);
p.addLast(new Http2DetectHandler(serverHandlers));
}
})
};
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF 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 org.apache.seata.core.protocol.detector;

import io.netty.buffer.ByteBuf;
import io.netty.channel.ChannelHandler;
import io.netty.handler.codec.http.HttpObjectAggregator;
import io.netty.handler.codec.http.HttpServerCodec;
import org.apache.seata.core.rpc.netty.http.HttpDispatchHandler;

public class HttpDetector implements ProtocolDetector {
private static final String[] HTTP_METHODS = {"GET", "POST", "PUT", "DELETE", "HEAD", "OPTIONS", "PATCH"};

@Override
public boolean detect(ByteBuf in) {
if (in.readableBytes() < 8) {
return false;
}

for (String method : HTTP_METHODS) {
if (startsWith(in, method)) {
return true;
}
}

return false;
}

private boolean startsWith(ByteBuf buffer, String prefix) {
for (int i = 0; i < prefix.length(); i++) {
if (buffer.getByte(i) != (byte) prefix.charAt(i)) {
return false;
}
}

return true;
}

@Override
public ChannelHandler[] getHandlers() {
return new ChannelHandler[]{
new HttpServerCodec(),
new HttpObjectAggregator(1048576),
new HttpDispatchHandler()
};
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@
import io.netty.channel.ChannelHandlerContext;
import io.netty.handler.codec.ByteToMessageDecoder;
import org.apache.seata.core.protocol.detector.Http2Detector;
import org.apache.seata.core.protocol.detector.HttpDetector;
import org.apache.seata.core.protocol.detector.ProtocolDetector;
import org.apache.seata.core.protocol.detector.SeataDetector;
import org.slf4j.Logger;
Expand All @@ -35,7 +36,7 @@ public class ProtocolDetectHandler extends ByteToMessageDecoder {

public ProtocolDetectHandler(NettyServerBootstrap nettyServerBootstrap) {
this.nettyServerBootstrap = nettyServerBootstrap;
this.supportedProtocolDetectors = new ProtocolDetector[]{new Http2Detector(nettyServerBootstrap.getChannelHandlers()), new SeataDetector(nettyServerBootstrap.getChannelHandlers())};
this.supportedProtocolDetectors = new ProtocolDetector[]{new Http2Detector(nettyServerBootstrap.getChannelHandlers()), new SeataDetector(nettyServerBootstrap.getChannelHandlers()), new HttpDetector()};
}

@Override
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF 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 org.apache.seata.core.rpc.netty.http;

import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;

public class ControllerManager {

private static final Map<String, HttpInvocation> HTTP_CONTROLLER_MAP = new ConcurrentHashMap<>();

public static HttpInvocation getHttpInvocation(String path) {
return HTTP_CONTROLLER_MAP.get(path);
}

public static void addHttpInvocation(HttpInvocation httpInvocation) {
HTTP_CONTROLLER_MAP.put(httpInvocation.getPath(), httpInvocation);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,81 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF 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 org.apache.seata.core.rpc.netty.http;

import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.node.ObjectNode;
import io.netty.buffer.Unpooled;
import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.SimpleChannelInboundHandler;
import io.netty.handler.codec.http.DefaultFullHttpResponse;
import io.netty.handler.codec.http.FullHttpResponse;
import io.netty.handler.codec.http.HttpHeaderNames;
import io.netty.handler.codec.http.HttpMethod;
import io.netty.handler.codec.http.HttpRequest;
import io.netty.handler.codec.http.HttpResponseStatus;
import io.netty.handler.codec.http.HttpVersion;
import io.netty.handler.codec.http.QueryStringDecoder;
import io.netty.handler.codec.http.multipart.Attribute;
import io.netty.handler.codec.http.multipart.HttpPostRequestDecoder;
import io.netty.handler.codec.http.multipart.InterfaceHttpData;

import java.lang.reflect.Method;

public class HttpDispatchHandler extends SimpleChannelInboundHandler<HttpRequest> {
funky-eyes marked this conversation as resolved.
Show resolved Hide resolved

@Override
protected void channelRead0(ChannelHandlerContext ctx, HttpRequest httpRequest) throws Exception {
QueryStringDecoder queryStringDecoder = new QueryStringDecoder(httpRequest.uri());
String path = queryStringDecoder.path();
ObjectMapper objectMapper = new ObjectMapper();
ObjectNode requestDataNode = objectMapper.createObjectNode();
requestDataNode.putIfAbsent("param", ParameterParser.convertParamMap(queryStringDecoder.parameters()));
requestDataNode.putPOJO("channel", ctx.channel());

if (httpRequest.method() == HttpMethod.POST) {
ObjectNode bodyDataNode = objectMapper.createObjectNode();
HttpPostRequestDecoder httpPostRequestDecoder = new HttpPostRequestDecoder(httpRequest);
for (InterfaceHttpData interfaceHttpData : httpPostRequestDecoder.getBodyHttpDatas()) {
if (interfaceHttpData.getHttpDataType() != InterfaceHttpData.HttpDataType.Attribute) {
continue;
}
Attribute attribute = (Attribute) interfaceHttpData;
bodyDataNode.put(attribute.getName(), attribute.getValue());
}
requestDataNode.putIfAbsent("body", bodyDataNode);
}

HttpInvocation httpInvocation = ControllerManager.getHttpInvocation(path);
if (httpInvocation != null) {
Object httpController = httpInvocation.getController();
Method handleMethod = httpInvocation.getMethod();
handleMethod.setAccessible(true);
Object[] args = ParameterParser.getArgValues(httpInvocation.getParamMetaData(), handleMethod, requestDataNode);
Object result = handleMethod.invoke(httpController, args);
if (requestDataNode.get("channel") == null) {
return;
}
FullHttpResponse response = new DefaultFullHttpResponse(HttpVersion.HTTP_1_1, HttpResponseStatus.OK, Unpooled.wrappedBuffer(objectMapper.writeValueAsBytes(result)));
response.headers().set(HttpHeaderNames.CONTENT_LENGTH, response.content().readableBytes());
ctx.writeAndFlush(response);
return;
}

FullHttpResponse response = new DefaultFullHttpResponse(HttpVersion.HTTP_1_1, HttpResponseStatus.NOT_FOUND, Unpooled.wrappedBuffer(Unpooled.EMPTY_BUFFER));
ctx.writeAndFlush(response);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF 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 org.apache.seata.core.rpc.netty.http;

import java.lang.reflect.Method;

public class HttpInvocation {

private Object controller;

private Method method;

private String path;

private ParamMetaData[] paramMetaData;

public Method getMethod() {
return method;
}

public void setMethod(Method method) {
this.method = method;
}

public String getPath() {
return path;
}

public void setPath(String path) {
this.path = path;
}

public Object getController() {
return controller;
}

public void setController(Object controller) {
this.controller = controller;
}

public ParamMetaData[] getParamMetaData() {
return paramMetaData;
}

public void setParamMetaData(ParamMetaData[] paramMetaData) {
this.paramMetaData = paramMetaData;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF 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 org.apache.seata.core.rpc.netty.http;

public class ParamMetaData {

private ParamConvertType paramConvertType;

public ParamConvertType getParamConvertType() {
return paramConvertType;
}

public void setParamConvertType(ParamConvertType paramConvertType) {
this.paramConvertType = paramConvertType;
}

public enum ParamConvertType {

/**
* convert like Spring @RequestBody
*/
REQUEST_BODY,

/**
* convert like Spring @RequestParam
*/
REQUEST_PARAM,

/**
* convert like Spring @ModelAttribute
*/
MODEL_ATTRIBUTE
}
}
Loading