This is an automated email from the ASF dual-hosted git repository. zfeng pushed a commit to branch feature/saga in repository https://gitbox.apache.org/repos/asf/incubator-seata-go.git
The following commit(s) were added to refs/heads/feature/saga by this push: new 8e84b0ef Feat cel expression (#788) 8e84b0ef is described below commit 8e84b0ef2cdc66bb552bd4f9e46f6b57f6c1db00 Author: marsevilspirit <marsevilspi...@gmail.com> AuthorDate: Sat May 10 18:55:42 2025 +0800 Feat cel expression (#788) * implement cel expression * move sequence expression into a new file * mv expression factory into a new file * move expression factory manager into a new file * implement cel expression factory and add test * move expression resolver into a new file * add parse expression struct test * update * update go.mod --------- Co-authored-by: FengZhang <zfc...@qq.com> --- go.mod | 25 +++-- go.sum | 43 ++++++--- .../statemachine/engine/expr/cel_expression.go | 96 +++++++++++++++++++ .../engine/expr/cel_expression_factory.go | 36 +++++++ .../engine/expr/cel_expression_factory_test.go | 31 ++++++ .../engine/expr/cel_expression_test.go | 42 +++++++++ pkg/saga/statemachine/engine/expr/expression.go | 92 ++---------------- .../statemachine/engine/expr/expression_factory.go | 22 +++++ ...expression.go => expression_factory_manager.go} | 66 +------------ .../engine/expr/expression_resolver.go | 105 +++++++++++++++++++++ .../engine/expr/expression_resolver_test.go | 53 +++++++++++ .../expr/{expression.go => sequence_expression.go} | 48 +--------- 12 files changed, 438 insertions(+), 221 deletions(-) diff --git a/go.mod b/go.mod index c927882f..feb9bfb8 100644 --- a/go.mod +++ b/go.mod @@ -25,7 +25,7 @@ require ( github.com/stretchr/testify v1.8.3 go.uber.org/atomic v1.9.0 go.uber.org/zap v1.21.0 - google.golang.org/grpc v1.51.0 + google.golang.org/grpc v1.57.0 gopkg.in/yaml.v2 v2.4.0 vimagination.zapto.org/byteio v0.0.0-20200222190125-d27cba0f0b10 ) @@ -33,20 +33,23 @@ require ( require ( github.com/agiledragon/gomonkey v2.0.2+incompatible github.com/agiledragon/gomonkey/v2 v2.9.0 + github.com/google/cel-go v0.18.0 github.com/mattn/go-sqlite3 v1.14.19 golang.org/x/sync v0.6.0 - google.golang.org/protobuf v1.30.0 + google.golang.org/protobuf v1.33.0 + gopkg.in/yaml.v3 v3.0.1 ) require ( github.com/RoaringBitmap/roaring v1.2.0 // indirect github.com/Workiva/go-datastructures v1.0.52 // indirect + github.com/antlr/antlr4/runtime/Go/antlr/v4 v4.0.0-20230305170008-8188dc5388df // indirect github.com/apache/dubbo-go-hessian2 v1.11.4 // indirect github.com/benbjohnson/clock v1.1.0 // indirect github.com/beorn7/perks v1.0.1 // indirect github.com/bits-and-blooms/bitset v1.2.0 // indirect github.com/bytedance/sonic v1.9.1 // indirect - github.com/cespare/xxhash/v2 v2.1.2 // indirect + github.com/cespare/xxhash/v2 v2.3.0 // indirect github.com/chenzhuoyu/base64x v0.0.0-20221115062448-fe3a3abad311 // indirect github.com/creasty/defaults v1.5.2 // indirect github.com/davecgh/go-spew v1.1.1 // indirect @@ -55,7 +58,7 @@ require ( github.com/go-ole/go-ole v1.2.6 // indirect github.com/go-playground/locales v0.14.1 // indirect github.com/go-playground/universal-translator v0.18.1 // indirect - github.com/golang/protobuf v1.5.2 // indirect + github.com/golang/protobuf v1.5.4 // indirect github.com/golang/snappy v0.0.4 // indirect github.com/gorilla/websocket v1.4.2 // indirect github.com/jinzhu/copier v0.3.5 // indirect @@ -76,10 +79,11 @@ require ( github.com/pingcap/errors v0.11.5-0.20210425183316-da1aaba5fb63 // indirect github.com/pmezard/go-difflib v1.0.0 // indirect github.com/power-devops/perfstat v0.0.0-20210106213030-5aafc221ea8c // indirect - github.com/prometheus/client_model v0.2.0 // indirect + github.com/prometheus/client_model v0.3.0 // indirect github.com/prometheus/procfs v0.7.3 // indirect github.com/satori/go.uuid v1.2.1-0.20181028125025-b2ce2384e17b // indirect github.com/shirou/gopsutil/v3 v3.22.2 // indirect + github.com/stoewer/go-strcase v1.2.0 // indirect github.com/tklauser/go-sysconf v0.3.10 // indirect github.com/tklauser/numcpus v0.4.0 // indirect github.com/twitchyliquid64/golang-asm v0.15.1 // indirect @@ -87,9 +91,11 @@ require ( github.com/yusufpapurcu/wmi v1.2.2 // indirect go.uber.org/multierr v1.8.0 // indirect golang.org/x/arch v0.3.0 // indirect + golang.org/x/exp v0.0.0-20220827204233-334a2380cb91 // indirect golang.org/x/text v0.14.0 // indirect + google.golang.org/genproto/googleapis/api v0.0.0-20230803162519-f966b187b2e5 // indirect + google.golang.org/genproto/googleapis/rpc v0.0.0-20230803162519-f966b187b2e5 // indirect gopkg.in/natefinch/lumberjack.v2 v2.0.0 // indirect - gopkg.in/yaml.v3 v3.0.1 // indirect ) require ( @@ -100,10 +106,9 @@ require ( github.com/mattn/go-isatty v0.0.19 // indirect github.com/pelletier/go-toml v1.9.3 // indirect github.com/pingcap/log v0.0.0-20210906054005-afc726e70354 // indirect - golang.org/x/crypto v0.17.0 // indirect - golang.org/x/net v0.10.0 // indirect - golang.org/x/sys v0.15.0 // indirect - google.golang.org/genproto v0.0.0-20220630174209-ad1d48641aa7 // indirect + golang.org/x/crypto v0.19.0 // indirect + golang.org/x/net v0.21.0 // indirect + golang.org/x/sys v0.17.0 // indirect vimagination.zapto.org/memio v0.0.0-20200222190306-588ebc67b97d // indirect ) diff --git a/go.sum b/go.sum index e269c87d..fae6c71b 100644 --- a/go.sum +++ b/go.sum @@ -67,6 +67,8 @@ github.com/alecthomas/units v0.0.0-20190924025748-f65c72e2690d/go.mod h1:rBZYJk5 github.com/alibaba/sentinel-golang v1.0.4/go.mod h1:Lag5rIYyJiPOylK8Kku2P+a23gdKMMqzQS7wTnjWEpk= github.com/aliyun/alibaba-cloud-sdk-go v1.61.18/go.mod h1:v8ESoHo4SyHmuB4b1tJqDHxfTGEciD+yhvOU/5s1Rfk= github.com/antihax/optional v1.0.0/go.mod h1:uupD/76wgC+ih3iEmQUL+0Ugr19nfwCT1kdvxnR2qWY= +github.com/antlr/antlr4/runtime/Go/antlr/v4 v4.0.0-20230305170008-8188dc5388df h1:7RFfzj4SSt6nnvCPbCqijJi1nWCd+TqAT3bYCStRC18= +github.com/antlr/antlr4/runtime/Go/antlr/v4 v4.0.0-20230305170008-8188dc5388df/go.mod h1:pSwJ0fSY5KhvocuWSx4fz3BA8OrA1bQn+K1Eli3BRwM= github.com/apache/dubbo-getty v1.4.9-0.20221022181821-4dc6252ce98c/go.mod h1:6qmrqBSPGs3B35zwEuGhEYNVsx1nfGT/xzV2yOt2amM= github.com/apache/dubbo-getty v1.4.10-0.20230731065302-7c0f0039e59c h1:e1pJKY0lFvO6rik7m3qmpMRA98cc9Zkg6AJeB1/7QFQ= github.com/apache/dubbo-getty v1.4.10-0.20230731065302-7c0f0039e59c/go.mod h1:TqHfi87Ufv7wpwI7nER5Kx8FCb/jjwlyazxiYwEmTs8= @@ -119,8 +121,9 @@ github.com/census-instrumentation/opencensus-proto v0.2.1/go.mod h1:f6KPmirojxKA github.com/certifi/gocertifi v0.0.0-20191021191039-0944d244cd40/go.mod h1:sGbDF6GwGcLpkNXPUTkMRoywsNa/ol15pxFe6ERfguA= github.com/cespare/xxhash v1.1.0/go.mod h1:XrSqR1VqqWfGrhpAt58auRo0WTKS1nRRg3ghfAqPWnc= github.com/cespare/xxhash/v2 v2.1.1/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs= -github.com/cespare/xxhash/v2 v2.1.2 h1:YRXhKfTDauu4ajMg1TPgFO5jnlC2HCbmLXMcTG5cbYE= github.com/cespare/xxhash/v2 v2.1.2/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs= +github.com/cespare/xxhash/v2 v2.3.0 h1:UL815xU9SqsFlibzuggzjXhog7bL6oX9BbNZnL2UFvs= +github.com/cespare/xxhash/v2 v2.3.0/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs= github.com/chenzhuoyu/base64x v0.0.0-20211019084208-fb5309c8db06/go.mod h1:DH46F32mSOjUmXrMHnKwZdA8wcEefY7UVqBKYGjpdQY= github.com/chenzhuoyu/base64x v0.0.0-20221115062448-fe3a3abad311 h1:qSGYFH7+jGhDF8vLC+iwCD4WpbV1EBDSzWkJODFLams= github.com/chenzhuoyu/base64x v0.0.0-20221115062448-fe3a3abad311/go.mod h1:b583jCggY9gE99b6G5LEC39OIiVsWj+R97kbl5odCEk= @@ -304,14 +307,17 @@ github.com/golang/protobuf v1.4.1/go.mod h1:U8fpvMrcmy5pZrNK1lt4xCsGvpyWQ/VVv6QD github.com/golang/protobuf v1.4.2/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw735rRwI= github.com/golang/protobuf v1.4.3/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw735rRwI= github.com/golang/protobuf v1.5.0/go.mod h1:FsONVRAS9T7sI+LIUmWTfcYkHO4aIWwzhcaSAoJOfIk= -github.com/golang/protobuf v1.5.2 h1:ROPKBNFfQgOUMifHyP+KYbvpjbdoFNs+aK7DXlji0Tw= github.com/golang/protobuf v1.5.2/go.mod h1:XVQd3VNwM+JqD3oG2Ue2ip4fOMUkwXdXDdiuN0vRsmY= +github.com/golang/protobuf v1.5.4 h1:i7eJL8qZTpSEXOPTxNKhASYpMn+8e5Q6AdndVa1dWek= +github.com/golang/protobuf v1.5.4/go.mod h1:lnTiLA8Wa4RWRcIUkrtSVa5nRhsEGBg48fD6rSs7xps= github.com/golang/snappy v0.0.0-20180518054509-2e65f85255db/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q= github.com/golang/snappy v0.0.1/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q= github.com/golang/snappy v0.0.4 h1:yAGX7huGHXlcLOEtBnF4w7FQwA26wojNCwOYAEhLjQM= github.com/golang/snappy v0.0.4/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q= github.com/google/btree v0.0.0-20180813153112-4030bb1f1f0c/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ= github.com/google/btree v1.0.0/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ= +github.com/google/cel-go v0.18.0 h1:u74MPiEC8mejBrkXqrTWT102g5IFEUjxOngzQIijMzU= +github.com/google/cel-go v0.18.0/go.mod h1:PVAybmSnWkNMUZR/tEWFUiJ1Np4Hz0MHsZJcgC4zln4= github.com/google/go-cmp v0.2.0/go.mod h1:oXzfMopK8JAjlY9xF4vHSVASa0yLyX7SntLO5aqRK0M= github.com/google/go-cmp v0.3.0/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU= github.com/google/go-cmp v0.3.1/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU= @@ -637,8 +643,9 @@ github.com/prometheus/client_model v0.0.0-20190115171406-56726106282f/go.mod h1: github.com/prometheus/client_model v0.0.0-20190129233127-fd36f4220a90/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA= github.com/prometheus/client_model v0.0.0-20190812154241-14fe0d1b01d4/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA= github.com/prometheus/client_model v0.1.0/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA= -github.com/prometheus/client_model v0.2.0 h1:uq5h0d+GuxiXLJLNABMgp2qUWDPiLvgCzz2dUR+/W/M= github.com/prometheus/client_model v0.2.0/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA= +github.com/prometheus/client_model v0.3.0 h1:UBgGFHqYdG/TPFD1B1ogZywDqEkwp3fBMvqdiQ7Xew4= +github.com/prometheus/client_model v0.3.0/go.mod h1:LDGWKZIo7rky3hgvBe+caln+Dr3dPggB5dvjtD7w9+w= github.com/prometheus/common v0.0.0-20181113130724-41aa239b4cce/go.mod h1:daVV7qP5qjZbuso7PdcryaAu0sAZbrN9i7WWcTMWvro= github.com/prometheus/common v0.2.0/go.mod h1:TNfzLD0ON7rHzMJeJkieUDPYmFC7Snx/y86RQel1bk4= github.com/prometheus/common v0.4.0/go.mod h1:TNfzLD0ON7rHzMJeJkieUDPYmFC7Snx/y86RQel1bk4= @@ -708,6 +715,8 @@ github.com/spf13/pflag v1.0.3/go.mod h1:DYY7MBk1bdzusC3SYhjObp+wFpr4gzcvqqNjLnIn github.com/spf13/pflag v1.0.5 h1:iy+VFUOCP1a+8yFto/drg2CJ5u0yRoB7fZw3DKv/JXA= github.com/spf13/pflag v1.0.5/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg= github.com/spf13/viper v1.7.0/go.mod h1:8WkrPz2fc9jxqZNCJI/76HCieCp4Q8HaLFoCha5qpdg= +github.com/stoewer/go-strcase v1.2.0 h1:Z2iHWqGXH00XYgqDmNgQbIBxf3wrNq0F3feEy0ainaU= +github.com/stoewer/go-strcase v1.2.0/go.mod h1:IBiWB2sKIp3wVVQ3Y035++gc+knqhUQag1KpM8ahLw8= github.com/streadway/amqp v0.0.0-20190404075320-75d898a42a94/go.mod h1:AZpEONHx3DKn8O/DFsRAY58/XVQiIPMTMB1SddzLXVw= github.com/streadway/amqp v0.0.0-20190827072141-edfb9018d271/go.mod h1:AZpEONHx3DKn8O/DFsRAY58/XVQiIPMTMB1SddzLXVw= github.com/streadway/handy v0.0.0-20190108123426-d5acb3125c2a/go.mod h1:qNTQ5P5JnDBl6z3cMAg/SywNDC5ABu5ApDIw6lUbRmI= @@ -831,8 +840,8 @@ golang.org/x/crypto v0.0.0-20201002170205-7f63de1d35b0/go.mod h1:LzIPMQfyMNhhGPh golang.org/x/crypto v0.0.0-20210711020723-a769d52b0f97/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= golang.org/x/crypto v0.0.0-20211215153901-e495a2d5b3d3/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4= -golang.org/x/crypto v0.17.0 h1:r8bRNjWL3GshPW3gkd+RpvzWrZAwPS49OmTGZ/uhM4k= -golang.org/x/crypto v0.17.0/go.mod h1:gCAAfMLgwOJRpTjQ2zCCt2OcSfYMTeZVSRtQlPC7Nq4= +golang.org/x/crypto v0.19.0 h1:ENy+Az/9Y1vSrlrvBSyna3PITt4tiZLf7sgCjZBX7Wo= +golang.org/x/crypto v0.19.0/go.mod h1:Iy9bg/ha4yyC70EfRS8jz+B6ybOBKMaSxLj6P6oBDfU= golang.org/x/exp v0.0.0-20180321215751-8460e604b9de/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= golang.org/x/exp v0.0.0-20180807140117-3d87b88a115f/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= golang.org/x/exp v0.0.0-20181106170214-d68db9428509/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= @@ -848,6 +857,8 @@ golang.org/x/exp v0.0.0-20200119233911-0405dc783f0a/go.mod h1:2RIsYlXP63K8oxa1u0 golang.org/x/exp v0.0.0-20200207192155-f17229e696bd/go.mod h1:J/WKrq2StrnmMY6+EHIKF9dgMWnmCNThgcyBT1FY9mM= golang.org/x/exp v0.0.0-20200224162631-6cc2880d07d6/go.mod h1:3jZMyOhIsHpP37uCMkUooju7aAi5cS1Q23tOzKc+0MU= golang.org/x/exp v0.0.0-20200331195152-e8c3332aa8e5/go.mod h1:4M0jN8W1tt0AVLNr8HDosyJCDCDuyL9N9+3m7wDWgKw= +golang.org/x/exp v0.0.0-20220827204233-334a2380cb91 h1:tnebWN09GYg9OLPss1KXj8txwZc6X6uMr6VFdcGNbHw= +golang.org/x/exp v0.0.0-20220827204233-334a2380cb91/go.mod h1:cyybsKvd6eL0RnXn6p/Grxp8F5bW7iYuBgsNCOHpMYE= golang.org/x/image v0.0.0-20180708004352-c73c2afc3b81/go.mod h1:ux5Hcp/YLpHSI86hEcLt0YII63i6oz57MZXIpbrjZUs= golang.org/x/image v0.0.0-20190227222117-0694c2d4d067/go.mod h1:kZ7UVZpmo3dzQBMxlp+ypCbDeSB+sBbTgSJuh5dn5js= golang.org/x/image v0.0.0-20190802002840-cff245a6509b/go.mod h1:FeLwcggjj3mMvU+oOTbSwawSJRM1uh48EjtB4UJZlP0= @@ -921,8 +932,8 @@ golang.org/x/net v0.0.0-20211029224645-99673261e6eb/go.mod h1:9nx3DQGgdP8bBQD5qx golang.org/x/net v0.0.0-20211105192438-b53810dc28af/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= golang.org/x/net v0.0.0-20211112202133-69e39bad7dc2/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= golang.org/x/net v0.0.0-20220722155237-a158d28d115b/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c= -golang.org/x/net v0.10.0 h1:X2//UzNDwYmtCLn7To6G58Wr6f5ahEAQgKNzv9Y951M= -golang.org/x/net v0.10.0/go.mod h1:0qNGK6F8kojg2nk9dLZ2mShWaEBan6FAoqfSigmmuDg= +golang.org/x/net v0.21.0 h1:AQyQV4dYCvJ7vGmJyKki9+PBdyvhkSd8EIx/qb0AYv4= +golang.org/x/net v0.21.0/go.mod h1:bIjVDfnllIU7BJ2DNgfnXvpSvtn8VRwhlsaeUTyUS44= golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= golang.org/x/oauth2 v0.0.0-20190226205417-e64efc72b421/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= golang.org/x/oauth2 v0.0.0-20190604053449-0f29369cfe45/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= @@ -1021,8 +1032,8 @@ golang.org/x/sys v0.0.0-20220704084225-05e143d24a9e/go.mod h1:oPkhp1MJrh7nUepCBc golang.org/x/sys v0.0.0-20220722155257-8c9f86f7a55f/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220908164124-27713097b956/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.15.0 h1:h48lPFYpsTvQJZF4EKyI4aLHaev3CxivZmv7yZig9pc= -golang.org/x/sys v0.15.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= +golang.org/x/sys v0.17.0 h1:25cE3gD+tdBA7lp7QfhuV+rJiE9YXTcS3VG1SqssI/Y= +golang.org/x/sys v0.17.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= golang.org/x/text v0.0.0-20170915032832-14c0d48ead0c/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= @@ -1171,8 +1182,10 @@ google.golang.org/genproto v0.0.0-20210106152847-07624b53cd92/go.mod h1:FWY/as6D google.golang.org/genproto v0.0.0-20210602131652-f16073e35f0c/go.mod h1:UODoCrxHCcBojKKwX1terBiRUaqAsFqJiF615XL43r0= google.golang.org/genproto v0.0.0-20211104193956-4c6863e31247/go.mod h1:5CzLGKJ67TSI2B9POpiiyGha0AjJvZIUgRMt1dSmuhc= google.golang.org/genproto v0.0.0-20220504150022-98cd25cafc72/go.mod h1:RAyBrSAP7Fh3Nc84ghnVLDPuV51xc9agzmm4Ph6i0Q4= -google.golang.org/genproto v0.0.0-20220630174209-ad1d48641aa7 h1:q4zUJDd0+knPFB9x20S3vnxzlYNBbt8Yd7zBMVMteeM= -google.golang.org/genproto v0.0.0-20220630174209-ad1d48641aa7/go.mod h1:KEWEmljWE5zPzLBa/oHl6DaEt9LmfH6WtH1OHIvleBA= +google.golang.org/genproto/googleapis/api v0.0.0-20230803162519-f966b187b2e5 h1:nIgk/EEq3/YlnmVVXVnm14rC2oxgs1o0ong4sD/rd44= +google.golang.org/genproto/googleapis/api v0.0.0-20230803162519-f966b187b2e5/go.mod h1:5DZzOUPCLYL3mNkQ0ms0F3EuUNZ7py1Bqeq6sxzI7/Q= +google.golang.org/genproto/googleapis/rpc v0.0.0-20230803162519-f966b187b2e5 h1:eSaPbMR4T7WfH9FvABk36NBMacoTUKdWCvV0dx+KfOg= +google.golang.org/genproto/googleapis/rpc v0.0.0-20230803162519-f966b187b2e5/go.mod h1:zBEcrKX2ZOcEkHWxBPAIvYUWOKKMIhYcmNiUIu2ji3I= google.golang.org/grpc v1.8.0/go.mod h1:yo6s7OP7yaDglbqo1J04qKzAhqBH6lvTonzMVmEdcZw= google.golang.org/grpc v1.14.0/go.mod h1:yo6s7OP7yaDglbqo1J04qKzAhqBH6lvTonzMVmEdcZw= google.golang.org/grpc v1.17.0/go.mod h1:6QZJwpn2B+Zp71q/5VxRsJ6NXXVCE5NRUHRo+f3cWCs= @@ -1201,10 +1214,10 @@ google.golang.org/grpc v1.38.0/go.mod h1:NREThFqKR1f3iQ6oBuvc5LadQuXVGo9rkm5ZGrQ google.golang.org/grpc v1.40.0/go.mod h1:ogyxbiOoUXAkP+4+xa6PZSE9DZgIHtSpzjDTB9KAK34= google.golang.org/grpc v1.41.0/go.mod h1:U3l9uK9J0sini8mHphKoXyaqDA/8VyGnDee1zzIUK6k= google.golang.org/grpc v1.46.0/go.mod h1:vN9eftEi1UMyUsIF80+uQXhHjbXYbm0uXoFCACuMGWk= -google.golang.org/grpc v1.47.0/go.mod h1:vN9eftEi1UMyUsIF80+uQXhHjbXYbm0uXoFCACuMGWk= google.golang.org/grpc v1.48.0/go.mod h1:vN9eftEi1UMyUsIF80+uQXhHjbXYbm0uXoFCACuMGWk= -google.golang.org/grpc v1.51.0 h1:E1eGv1FTqoLIdnBCZufiSHgKjlqG6fKFf6pPWtMTh8U= google.golang.org/grpc v1.51.0/go.mod h1:wgNDFcnuBGmxLKI/qn4T+m5BtEBYXJPvibbUPsAIPww= +google.golang.org/grpc v1.57.0 h1:kfzNeI/klCGD2YPMUlaGNT3pxvYfga7smW3Vth8Zsiw= +google.golang.org/grpc v1.57.0/go.mod h1:Sd+9RMTACXwmub0zcNY2c4arhtrbBYD1AUHI/dt16Mo= google.golang.org/protobuf v0.0.0-20200109180630-ec00e32a8dfd/go.mod h1:DFci5gLYBciE7Vtevhsrf46CRTquxDuWsQurQQe4oz8= google.golang.org/protobuf v0.0.0-20200221191635-4d8936d0db64/go.mod h1:kwYJMbMJ01Woi6D6+Kah6886xMZcty6N08ah7+eCXa0= google.golang.org/protobuf v0.0.0-20200228230310-ab0ca4ff8a60/go.mod h1:cfTl7dwQJ+fmap5saPgwCLgHXTUD7jkjRqWcaiX5VyM= @@ -1220,8 +1233,8 @@ google.golang.org/protobuf v1.26.0/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQ google.golang.org/protobuf v1.27.1/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc= google.golang.org/protobuf v1.28.0/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqwMG9pJV4I= google.golang.org/protobuf v1.28.1/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqwMG9pJV4I= -google.golang.org/protobuf v1.30.0 h1:kPPoIgf3TsEvrm0PFe15JQ+570QVxYzEvvHqChK+cng= -google.golang.org/protobuf v1.30.0/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqwMG9pJV4I= +google.golang.org/protobuf v1.33.0 h1:uNO2rsAINq/JlFpSdYEKIZ0uKD/R9cpdv0T+yoGwGmI= +google.golang.org/protobuf v1.33.0/go.mod h1:c6P6GXX6sHbq/GpV6MGZEdwhWPcYBgnhAHhKbcUYpos= gopkg.in/alecthomas/kingpin.v2 v2.2.6/go.mod h1:FMv+mEhP44yOT+4EoQTLFTRgOQ1FBLkstjWtayDeSgw= gopkg.in/asn1-ber.v1 v1.0.0-20181015200546-f715ec2f112d/go.mod h1:cuepJuh7vyXfUyUwEgHQXw849cJrilpS5NeIjOWESAw= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= diff --git a/pkg/saga/statemachine/engine/expr/cel_expression.go b/pkg/saga/statemachine/engine/expr/cel_expression.go new file mode 100644 index 00000000..675e0c72 --- /dev/null +++ b/pkg/saga/statemachine/engine/expr/cel_expression.go @@ -0,0 +1,96 @@ +/* + * 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 expr + +import ( + "github.com/google/cel-go/cel" +) + +type CELExpression struct { + env *cel.Env + program cel.Program + expression string +} + +// This is used to make sure that the CELExpression implements the Expression interface. +var _ Expression = (*CELExpression)(nil) + +// NewCELExpression creates a new CELExpression instance +// by compiling the provided expression. +// how to use cel: https://codelabs.developers.google.com/codelabs/cel-go +func NewCELExpression(expression string) (*CELExpression, error) { + // Create the standard environment. + env, err := cel.NewEnv( + cel.Variable( + "elContext", cel.DynType, + ), + ) + + if err != nil { + return nil, err + } + + // Check that the expression compiles and returns a String. + ast, issues := env.Compile(expression) + // Report syntax errors, if present. + if issues != nil && issues.Err() != nil { + return nil, issues.Err() + } + + // Type-check the expression ofr correctness. + checkedAst, issues := env.Check(ast) + if issues.Err() != nil { + return nil, issues.Err() + } + + program, err := env.Program(checkedAst) + if err != nil { + return nil, err + } + + CELExpression := &CELExpression{ + env: env, + program: program, + expression: expression, + } + + return CELExpression, nil +} + +// Value evaluates the expression with the provided context and returns the result. +func (c *CELExpression) Value(elContext any) any { + result, _, err := c.program.Eval(map[string]any{ + "elContext": elContext, + }) + if err != nil { + return err + } + return result.Value() +} + +// TODO: I think this is not needed. +// I see seata-java doesn't use this method. +// Do we need to implement this? +func (c *CELExpression) SetValue(val any, elContext any) { + panic("implement me") +} + +// ExpressionString returns the expression string. +func (c *CELExpression) ExpressionString() string { + return c.expression +} diff --git a/pkg/saga/statemachine/engine/expr/cel_expression_factory.go b/pkg/saga/statemachine/engine/expr/cel_expression_factory.go new file mode 100644 index 00000000..dcdc7d67 --- /dev/null +++ b/pkg/saga/statemachine/engine/expr/cel_expression_factory.go @@ -0,0 +1,36 @@ +/* + * 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 expr + +type CELExpressionFactory struct { + expr *CELExpression +} + +// This is used to make sure that CELExpressionFactory implements ExpressionFactory +var _ ExpressionFactory = (*CELExpressionFactory)(nil) + +// NewCELExpressionFactory creates a new instance of CELExpressionFactory +func NewCELExpressionFactory() *CELExpressionFactory { + return &CELExpressionFactory{} +} + +// CreateExpression creates a new instance of CELExpression +func (f *CELExpressionFactory) CreateExpression(expression string) Expression { + f.expr, _ = NewCELExpression(expression) + return f.expr +} diff --git a/pkg/saga/statemachine/engine/expr/cel_expression_factory_test.go b/pkg/saga/statemachine/engine/expr/cel_expression_factory_test.go new file mode 100644 index 00000000..a84fe48c --- /dev/null +++ b/pkg/saga/statemachine/engine/expr/cel_expression_factory_test.go @@ -0,0 +1,31 @@ +/* + * 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 expr + +import ( + "testing" + + "github.com/stretchr/testify/assert" +) + +func TestCelExpressionFactory(t *testing.T) { + factory := NewCELExpressionFactory() + expression := factory.CreateExpression("'Hello' + ' World!'") + value := expression.Value(nil) + assert.Equal(t, "Hello World!", value, "Expected 'Hello World!'") +} diff --git a/pkg/saga/statemachine/engine/expr/cel_expression_test.go b/pkg/saga/statemachine/engine/expr/cel_expression_test.go new file mode 100644 index 00000000..1c3f05da --- /dev/null +++ b/pkg/saga/statemachine/engine/expr/cel_expression_test.go @@ -0,0 +1,42 @@ +/* + * 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 expr + +import ( + "testing" + + "github.com/stretchr/testify/assert" +) + +func TestValueWithNil(t *testing.T) { + expr, err := NewCELExpression("'Hello' + ' World!'") + assert.NoError(t, err, "Error creating expression") + value := expr.Value(nil) + assert.Equal(t, "Hello World!", value, "Expected 'Hello World!'") +} + +func TestValue(t *testing.T) { + expr, err := NewCELExpression("elContext['name'] + ' World!'") + assert.NoError(t, err, "Error creating expression") + elContext := map[string]any{ + "name": "Hello", + } + + value := expr.Value(elContext) + assert.Equal(t, "Hello World!", value, "Expected 'Hello World!'") +} diff --git a/pkg/saga/statemachine/engine/expr/expression.go b/pkg/saga/statemachine/engine/expr/expression.go index 00441d1f..343ea1be 100644 --- a/pkg/saga/statemachine/engine/expr/expression.go +++ b/pkg/saga/statemachine/engine/expr/expression.go @@ -17,94 +17,14 @@ package expr -import ( - "github.com/seata/seata-go/pkg/saga/statemachine/engine/sequence" - "strings" -) - -const DefaultExpressionType string = "Default" - -type ExpressionResolver interface { - Expression(expressionStr string) Expression - ExpressionFactoryManager() ExpressionFactoryManager - SetExpressionFactoryManager(expressionFactoryManager ExpressionFactoryManager) -} - +// expression interface type Expression interface { + // get the value of the expression + // elContext is the el context Value(elContext any) any - SetValue(value any, elContext any) - ExpressionString() string -} - -type ExpressionFactory interface { - CreateExpression(expression string) Expression -} - -type ExpressionFactoryManager struct { - expressionFactoryMap map[string]ExpressionFactory -} - -func NewExpressionFactoryManager() *ExpressionFactoryManager { - return &ExpressionFactoryManager{ - expressionFactoryMap: make(map[string]ExpressionFactory), - } -} - -func (e *ExpressionFactoryManager) GetExpressionFactory(expressionType string) ExpressionFactory { - if strings.TrimSpace(expressionType) == "" { - expressionType = DefaultExpressionType - } - return e.expressionFactoryMap[expressionType] -} -func (e *ExpressionFactoryManager) SetExpressionFactoryMap(expressionFactoryMap map[string]ExpressionFactory) { - for k, v := range expressionFactoryMap { - e.expressionFactoryMap[k] = v - } -} - -func (e *ExpressionFactoryManager) PutExpressionFactory(expressionType string, factory ExpressionFactory) { - e.expressionFactoryMap[expressionType] = factory -} - -type SequenceExpression struct { - seqGenerator sequence.SeqGenerator - entity string - rule string -} - -func (s *SequenceExpression) SeqGenerator() sequence.SeqGenerator { - return s.seqGenerator -} - -func (s *SequenceExpression) SetSeqGenerator(seqGenerator sequence.SeqGenerator) { - s.seqGenerator = seqGenerator -} - -func (s *SequenceExpression) Entity() string { - return s.entity -} - -func (s *SequenceExpression) SetEntity(entity string) { - s.entity = entity -} - -func (s *SequenceExpression) Rule() string { - return s.rule -} - -func (s *SequenceExpression) SetRule(rule string) { - s.rule = rule -} - -func (s SequenceExpression) Value(elContext any) any { - return s.seqGenerator.GenerateId(s.entity, s.rule) -} - -func (s SequenceExpression) SetValue(value any, elContext any) { - -} + SetValue(value any, elContext any) -func (s SequenceExpression) ExpressionString() string { - return s.entity + "|" + s.rule + // return the expression string + ExpressionString() string } diff --git a/pkg/saga/statemachine/engine/expr/expression_factory.go b/pkg/saga/statemachine/engine/expr/expression_factory.go new file mode 100644 index 00000000..b785775a --- /dev/null +++ b/pkg/saga/statemachine/engine/expr/expression_factory.go @@ -0,0 +1,22 @@ +/* + * 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 expr + +type ExpressionFactory interface { + CreateExpression(expression string) Expression +} diff --git a/pkg/saga/statemachine/engine/expr/expression.go b/pkg/saga/statemachine/engine/expr/expression_factory_manager.go similarity index 52% copy from pkg/saga/statemachine/engine/expr/expression.go copy to pkg/saga/statemachine/engine/expr/expression_factory_manager.go index 00441d1f..82e3f04d 100644 --- a/pkg/saga/statemachine/engine/expr/expression.go +++ b/pkg/saga/statemachine/engine/expr/expression_factory_manager.go @@ -18,27 +18,11 @@ package expr import ( - "github.com/seata/seata-go/pkg/saga/statemachine/engine/sequence" + "maps" "strings" ) -const DefaultExpressionType string = "Default" - -type ExpressionResolver interface { - Expression(expressionStr string) Expression - ExpressionFactoryManager() ExpressionFactoryManager - SetExpressionFactoryManager(expressionFactoryManager ExpressionFactoryManager) -} - -type Expression interface { - Value(elContext any) any - SetValue(value any, elContext any) - ExpressionString() string -} - -type ExpressionFactory interface { - CreateExpression(expression string) Expression -} +const DefaultExpressionType = "Default" type ExpressionFactoryManager struct { expressionFactoryMap map[string]ExpressionFactory @@ -58,53 +42,9 @@ func (e *ExpressionFactoryManager) GetExpressionFactory(expressionType string) E } func (e *ExpressionFactoryManager) SetExpressionFactoryMap(expressionFactoryMap map[string]ExpressionFactory) { - for k, v := range expressionFactoryMap { - e.expressionFactoryMap[k] = v - } + maps.Copy(e.expressionFactoryMap, expressionFactoryMap) } func (e *ExpressionFactoryManager) PutExpressionFactory(expressionType string, factory ExpressionFactory) { e.expressionFactoryMap[expressionType] = factory } - -type SequenceExpression struct { - seqGenerator sequence.SeqGenerator - entity string - rule string -} - -func (s *SequenceExpression) SeqGenerator() sequence.SeqGenerator { - return s.seqGenerator -} - -func (s *SequenceExpression) SetSeqGenerator(seqGenerator sequence.SeqGenerator) { - s.seqGenerator = seqGenerator -} - -func (s *SequenceExpression) Entity() string { - return s.entity -} - -func (s *SequenceExpression) SetEntity(entity string) { - s.entity = entity -} - -func (s *SequenceExpression) Rule() string { - return s.rule -} - -func (s *SequenceExpression) SetRule(rule string) { - s.rule = rule -} - -func (s SequenceExpression) Value(elContext any) any { - return s.seqGenerator.GenerateId(s.entity, s.rule) -} - -func (s SequenceExpression) SetValue(value any, elContext any) { - -} - -func (s SequenceExpression) ExpressionString() string { - return s.entity + "|" + s.rule -} diff --git a/pkg/saga/statemachine/engine/expr/expression_resolver.go b/pkg/saga/statemachine/engine/expr/expression_resolver.go new file mode 100644 index 00000000..d7841021 --- /dev/null +++ b/pkg/saga/statemachine/engine/expr/expression_resolver.go @@ -0,0 +1,105 @@ +/* + * 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 expr + +import ( + "errors" + "strings" +) + +type ExpressionResolver interface { + Expression(expressionStr string) Expression + ExpressionFactoryManager() ExpressionFactoryManager + SetExpressionFactoryManager(expressionFactoryManager ExpressionFactoryManager) +} + +type DefaultExpressionResolver struct { + expressionFactoryManager ExpressionFactoryManager +} + +func (resolver *DefaultExpressionResolver) Expression(expressionStr string) Expression { + expressionStruct, err := parseExpressionStruct(expressionStr) + if err != nil { + return nil + } + expressionFactory := resolver.expressionFactoryManager.GetExpressionFactory(expressionStruct.typ) + if expressionFactory == nil { + return nil + } + return expressionFactory.CreateExpression(expressionStruct.content) +} + +func (resolver *DefaultExpressionResolver) ExpressionFactoryManager() ExpressionFactoryManager { + return resolver.expressionFactoryManager +} + +func (resolver *DefaultExpressionResolver) SetExpressionFactoryManager(expressionFactoryManager ExpressionFactoryManager) { + resolver.expressionFactoryManager = expressionFactoryManager +} + +type ExpressionStruct struct { + typeStart int + typeEnd int + end int + typ string + content string +} + +// old style: $type{content} +// new style: $type.content +func parseExpressionStruct(expressionStr string) (*ExpressionStruct, error) { + eStruct := &ExpressionStruct{} + eStruct.typeStart = strings.Index(expressionStr, "$") + if eStruct.typeStart == -1 { + return nil, errors.New("invalid expression") + } + + dot := strings.Index(expressionStr, ".") + leftBracket := strings.Index(expressionStr, "{") + + isOldEvaluatorStyle := false + if eStruct.typeStart == 0 { + if leftBracket < 0 && dot < 0 { + return nil, errors.New("invalid expression") + } + // Backward compatible for structure: $expressionType{expressionContent} + if leftBracket > 0 && (leftBracket < dot || dot < 0) { + eStruct.typeEnd = leftBracket + isOldEvaluatorStyle = true + } + if dot > 0 && (dot < leftBracket || leftBracket < 0) { + eStruct.typeEnd = dot + } + } + + if eStruct.typeStart == 0 && leftBracket != -1 && leftBracket < dot { + // Backward compatible for structure: $expressionType{expressionContent} + eStruct.typeEnd = strings.Index(expressionStr, "{") + isOldEvaluatorStyle = true + } + + eStruct.typ = expressionStr[eStruct.typeStart+1 : eStruct.typeEnd] + + if isOldEvaluatorStyle { + eStruct.end = strings.Index(expressionStr, "}") + } else { + eStruct.end = len(expressionStr) + } + eStruct.content = expressionStr[eStruct.typeEnd+1 : eStruct.end] + return eStruct, nil +} diff --git a/pkg/saga/statemachine/engine/expr/expression_resolver_test.go b/pkg/saga/statemachine/engine/expr/expression_resolver_test.go new file mode 100644 index 00000000..f518a425 --- /dev/null +++ b/pkg/saga/statemachine/engine/expr/expression_resolver_test.go @@ -0,0 +1,53 @@ +package expr + +import ( + "testing" + + "github.com/stretchr/testify/assert" +) + +func TestParseExpressionStruct(t *testing.T) { + tests := []struct { + expressionStr string + expected *ExpressionStruct + expectError bool + }{ + { + expressionStr: "$type{content}", + expected: &ExpressionStruct{ + typeStart: 0, + typeEnd: 5, + typ: "type", + end: 13, + content: "content", + }, + expectError: false, + }, + { + expressionStr: "$type.content", + expected: &ExpressionStruct{ + typeStart: 0, + typeEnd: 5, + typ: "type", + end: 13, + content: "content", + }, + expectError: false, + }, + { + expressionStr: "invalid expression", + expected: nil, + expectError: true, + }, + } + for _, test := range tests { + result, err := parseExpressionStruct(test.expressionStr) + if test.expectError { + assert.Error(t, err, "Expected an error for input '%s'", test.expressionStr) + } else { + assert.NoError(t, err, "Did not expect an error for input '%s'", test.expressionStr) + assert.NotNil(t, result, "Expected a non-nil result for input '%s'", test.expressionStr) + assert.Equal(t, *test.expected, *result, "Expected result %+v, got %+v for input '%s'", test.expected, result, test.expressionStr) + } + } +} diff --git a/pkg/saga/statemachine/engine/expr/expression.go b/pkg/saga/statemachine/engine/expr/sequence_expression.go similarity index 55% copy from pkg/saga/statemachine/engine/expr/expression.go copy to pkg/saga/statemachine/engine/expr/sequence_expression.go index 00441d1f..d6509252 100644 --- a/pkg/saga/statemachine/engine/expr/expression.go +++ b/pkg/saga/statemachine/engine/expr/sequence_expression.go @@ -19,54 +19,8 @@ package expr import ( "github.com/seata/seata-go/pkg/saga/statemachine/engine/sequence" - "strings" ) -const DefaultExpressionType string = "Default" - -type ExpressionResolver interface { - Expression(expressionStr string) Expression - ExpressionFactoryManager() ExpressionFactoryManager - SetExpressionFactoryManager(expressionFactoryManager ExpressionFactoryManager) -} - -type Expression interface { - Value(elContext any) any - SetValue(value any, elContext any) - ExpressionString() string -} - -type ExpressionFactory interface { - CreateExpression(expression string) Expression -} - -type ExpressionFactoryManager struct { - expressionFactoryMap map[string]ExpressionFactory -} - -func NewExpressionFactoryManager() *ExpressionFactoryManager { - return &ExpressionFactoryManager{ - expressionFactoryMap: make(map[string]ExpressionFactory), - } -} - -func (e *ExpressionFactoryManager) GetExpressionFactory(expressionType string) ExpressionFactory { - if strings.TrimSpace(expressionType) == "" { - expressionType = DefaultExpressionType - } - return e.expressionFactoryMap[expressionType] -} - -func (e *ExpressionFactoryManager) SetExpressionFactoryMap(expressionFactoryMap map[string]ExpressionFactory) { - for k, v := range expressionFactoryMap { - e.expressionFactoryMap[k] = v - } -} - -func (e *ExpressionFactoryManager) PutExpressionFactory(expressionType string, factory ExpressionFactory) { - e.expressionFactoryMap[expressionType] = factory -} - type SequenceExpression struct { seqGenerator sequence.SeqGenerator entity string @@ -97,7 +51,7 @@ func (s *SequenceExpression) SetRule(rule string) { s.rule = rule } -func (s SequenceExpression) Value(elContext any) any { +func (s SequenceExpression) Value(vars map[string]any) any { return s.seqGenerator.GenerateId(s.entity, s.rule) } --------------------------------------------------------------------- To unsubscribe, e-mail: notifications-unsubscr...@seata.apache.org For additional commands, e-mail: notifications-h...@seata.apache.org