Skip to content

Commit 1f9ec0e

Browse files
authored
Merge pull request #21 from deepflowio/enhance_dubbo
2 parents 0d59087 + 61ce8cc commit 1f9ec0e

File tree

3 files changed

+129
-3
lines changed

3 files changed

+129
-3
lines changed

example/dubbo/dubbo.go

Lines changed: 120 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,120 @@
1+
/*
2+
* Copyright (c) 2024 Yunshan Networks
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* http://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
17+
package main
18+
19+
import (
20+
"github.com/deepflowio/deepflow-wasm-go-sdk/sdk"
21+
"github.com/valyala/fastjson"
22+
_ "github.com/wasilibs/nottinygc"
23+
)
24+
25+
func main() {
26+
sdk.Info("dubbo-plugin loaded")
27+
parser := DubboParser{}
28+
parser.Parser = interface{}(parser).(sdk.Parser)
29+
sdk.SetParser(parser)
30+
}
31+
32+
type DubboParser struct {
33+
sdk.DefaultParser
34+
}
35+
36+
func (p DubboParser) HookIn() []sdk.HookBitmap {
37+
return []sdk.HookBitmap{
38+
sdk.HOOK_POINT_CUSTOM_MESSAGE,
39+
}
40+
}
41+
42+
func (p DubboParser) CustomMessageHookIn() uint64 {
43+
return sdk.CustomMessageHookProtocol(sdk.PROTOCOL_DUBBO, true)
44+
}
45+
46+
func (p DubboParser) OnCustomReq(ctx *sdk.CustomMessageCtx) sdk.Action {
47+
baseCtx := &ctx.BaseCtx
48+
payload, err := baseCtx.GetPayload() // The content of the Dubbo protocol, for reference: https://cn.dubbo.apache.org/zh/blog/2018/10/05/dubbo-%e5%8d%8f%e8%ae%ae%e8%af%a6%e8%a7%a3/#%E5%8D%8F%E8%AE%AE%E6%A6%82%E8%A7%88
49+
if err != nil {
50+
return sdk.ActionAbortWithErr(err)
51+
}
52+
_ = payload
53+
// Do something, such as parsing the payload to obtain Dubbo's Dubbo version, Service name, Service version, Method name, and so on.
54+
// return sdk.ParseActionAbortWithL7Info([]*sdk.L7ProtocolInfo{{
55+
56+
// Req: &sdk.Request{
57+
// Domain: "custom_service_name", // Rewrite service_name
58+
// ReqType: "custom_req_type", // Rewrite req_type
59+
// },
60+
// Kv: []sdk.KeyVal{{
61+
// Key: "custom_extra_info_key", // Add extra information
62+
// Val: "custom_extra_info_value",
63+
// }},
64+
// }})
65+
return sdk.ActionAbort()
66+
}
67+
68+
func (p DubboParser) OnCustomResp(ctx *sdk.CustomMessageCtx) sdk.Action {
69+
baseCtx := &ctx.BaseCtx
70+
payload, err := baseCtx.GetPayload() // The content of the Dubbo protocol, for reference: https://cn.dubbo.apache.org/zh/blog/2018/10/05/dubbo-%e5%8d%8f%e8%ae%ae%e8%af%a6%e8%a7%a3/#%E5%8D%8F%E8%AE%AE%E6%A6%82%E8%A7%88
71+
if err != nil {
72+
return sdk.ActionAbortWithErr(err)
73+
}
74+
if len(payload) < 17 { // dubbo headers(16bytes) + return value's type (1byte)
75+
sdk.Warn("empty return value")
76+
return sdk.ActionAbort()
77+
}
78+
dubboReturnValue := payload[17:]
79+
status := sdk.RespStatusOk
80+
status_code := int32(0)
81+
exception := ""
82+
// Assuming the returned value bytes are data serialized in JSON format, the content is: {"status code": 500, "exception": "internal error"}
83+
// Extract the status_code and exception from the data
84+
if fastjson.Exists(dubboReturnValue, "status_code") {
85+
code := fastjson.GetInt(dubboReturnValue, "status_code")
86+
status_code = int32(code)
87+
if status_code >= 500 {
88+
status = sdk.RespStatusServerErr
89+
} else if status_code >= 400 && status_code < 500 {
90+
status = sdk.RespStatusClientErr
91+
}
92+
}
93+
if fastjson.Exists(dubboReturnValue, "exception") {
94+
exception = fastjson.GetString(dubboReturnValue, "exception")
95+
}
96+
97+
return sdk.ParseActionAbortWithL7Info([]*sdk.L7ProtocolInfo{
98+
{
99+
Resp: &sdk.Response{
100+
Code: &status_code, // Overwrite the status code in the response message, for example, if the original Dubbo status code is 20, override it with a custom status code
101+
Status: &status, // Rewrite the response status to a custom status
102+
Result: string(dubboReturnValue), // The entire payload can be placed into Response.Result for easier troubleshooting
103+
Exception: exception, // Rewrite exception
104+
},
105+
Kv: []sdk.KeyVal{{
106+
Key: "custom_exception", // Add extra information
107+
Val: exception,
108+
}},
109+
},
110+
})
111+
}
112+
113+
func (p DubboParser) OnCustomMessage(ctx *sdk.CustomMessageCtx) sdk.Action {
114+
baseCtx := &ctx.BaseCtx
115+
if baseCtx.Direction == sdk.DirectionRequest {
116+
return p.OnCustomReq(ctx)
117+
} else {
118+
return p.OnCustomResp(ctx)
119+
}
120+
}

go.mod

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,8 +3,13 @@ module github.com/deepflowio/deepflow-wasm-go-sdk
33
go 1.19
44

55
require (
6-
github.com/valyala/fastjson v1.6.4
76
github.com/planetscale/vtprotobuf v0.6.0
7+
github.com/valyala/fastjson v1.6.4
88
golang.org/x/net v0.22.0
99
google.golang.org/protobuf v1.33.0
1010
)
11+
12+
require (
13+
github.com/magefile/mage v1.14.0 // indirect
14+
github.com/wasilibs/nottinygc v0.7.1 // indirect
15+
)

sdk/parser.go

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -53,8 +53,9 @@ var (
5353
)
5454

5555
var (
56-
PROTOCOL_NATS uint16 = 104
57-
PROTOCOL_ZMTP uint16 = 106
56+
PROTOCOL_DUBBO uint16 = 40
57+
PROTOCOL_NATS uint16 = 104
58+
PROTOCOL_ZMTP uint16 = 106
5859
)
5960

6061
var CUSTOM_MESSAGE_HOOK_ALL uint64 = 0xff << 48

0 commit comments

Comments
 (0)