* feat: add xa branch xid Co-authored-by: 王瑞 <wangrui5@songguo7.com>tags/v1.0.3
| @@ -28,6 +28,7 @@ require ( | |||
| google.golang.org/grpc v1.49.0 | |||
| google.golang.org/protobuf v1.28.1 | |||
| gopkg.in/yaml.v2 v2.4.0 | |||
| gotest.tools v2.2.0+incompatible | |||
| vimagination.zapto.org/byteio v0.0.0-20200222190125-d27cba0f0b10 | |||
| ) | |||
| @@ -73,6 +74,7 @@ require ( | |||
| github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da // indirect | |||
| github.com/golang/protobuf v1.5.2 // indirect | |||
| github.com/golang/snappy v0.0.4 // indirect | |||
| github.com/google/go-cmp v0.5.9 // indirect | |||
| github.com/gorilla/websocket v1.4.2 // indirect | |||
| github.com/grpc-ecosystem/grpc-opentracing v0.0.0-20180507213350-8e809c8a8645 // indirect | |||
| github.com/hashicorp/errwrap v1.1.0 // indirect | |||
| @@ -1425,6 +1425,7 @@ gopkg.in/yaml.v3 v3.0.0-20210107192922-496545a6307b/go.mod h1:K4uyk7z7BCEPqu6E+C | |||
| gopkg.in/yaml.v3 v3.0.0/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= | |||
| gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= | |||
| gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= | |||
| gotest.tools v2.2.0+incompatible h1:VsBPFP1AI068pPrMxtb/S8Zkgf9xEmTLJjfM+P5UIEo= | |||
| gotest.tools v2.2.0+incompatible/go.mod h1:DsYFclhRJ6vuDpmuTbkuFWG+y2sxOXAzmJt81HFBacw= | |||
| honnef.co/go/tools v0.0.0-20180728063816-88497007e858/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= | |||
| honnef.co/go/tools v0.0.0-20190102054323-c2f93a96b099/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= | |||
| @@ -0,0 +1,129 @@ | |||
| /* | |||
| * 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 xa | |||
| import ( | |||
| "strconv" | |||
| "strings" | |||
| ) | |||
| const ( | |||
| BranchIdPrefix = "-" | |||
| SeataXaXidFormatId = 9752 | |||
| ) | |||
| type XABranchXid struct { | |||
| xid string | |||
| branchId int64 | |||
| globalTransactionId []byte | |||
| branchQualifier []byte | |||
| } | |||
| type Option func(*XABranchXid) | |||
| func NewXABranchXid(opt ...Option) *XABranchXid { | |||
| xABranchXid := &XABranchXid{} | |||
| for _, fn := range opt { | |||
| fn(xABranchXid) | |||
| } | |||
| // encode | |||
| if (xABranchXid.xid != "" || xABranchXid.branchId != 0) && | |||
| len(xABranchXid.globalTransactionId) == 0 && | |||
| len(xABranchXid.branchQualifier) == 0 { | |||
| encode(xABranchXid) | |||
| } | |||
| // decode | |||
| if xABranchXid.xid == "" && xABranchXid.branchId == 0 && | |||
| (len(xABranchXid.globalTransactionId) > 0 || len(xABranchXid.branchQualifier) > 0) { | |||
| decode(xABranchXid) | |||
| } | |||
| return xABranchXid | |||
| } | |||
| func (x *XABranchXid) GetGlobalXid() string { | |||
| return x.xid | |||
| } | |||
| func (x *XABranchXid) GetBranchId() int64 { | |||
| return x.branchId | |||
| } | |||
| func (x *XABranchXid) GetFormatId() int { | |||
| return SeataXaXidFormatId | |||
| } | |||
| func (x *XABranchXid) GetGlobalTransactionId() []byte { | |||
| return x.globalTransactionId | |||
| } | |||
| func (x *XABranchXid) GetBranchQualifier() []byte { | |||
| return x.branchQualifier | |||
| } | |||
| func (x *XABranchXid) String() string { | |||
| return x.xid + BranchIdPrefix + strconv.FormatInt(x.branchId, 10) | |||
| } | |||
| func WithXid(xid string) Option { | |||
| return func(x *XABranchXid) { | |||
| x.xid = xid | |||
| } | |||
| } | |||
| func WithBranchId(branchId int64) Option { | |||
| return func(x *XABranchXid) { | |||
| x.branchId = branchId | |||
| } | |||
| } | |||
| func WithGlobalTransactionId(globalTransactionId []byte) Option { | |||
| return func(x *XABranchXid) { | |||
| x.globalTransactionId = globalTransactionId | |||
| } | |||
| } | |||
| func WithBranchQualifier(branchQualifier []byte) Option { | |||
| return func(x *XABranchXid) { | |||
| x.branchQualifier = branchQualifier | |||
| } | |||
| } | |||
| func encode(x *XABranchXid) { | |||
| if x.xid != "" { | |||
| x.globalTransactionId = []byte(x.xid) | |||
| } | |||
| if x.branchId != 0 { | |||
| x.branchQualifier = []byte(BranchIdPrefix + strconv.FormatInt(x.branchId, 10)) | |||
| } | |||
| } | |||
| func decode(x *XABranchXid) { | |||
| if len(x.globalTransactionId) > 0 { | |||
| x.xid = string(x.globalTransactionId) | |||
| } | |||
| if len(x.branchQualifier) > 0 { | |||
| branchId := strings.TrimLeft(string(x.branchQualifier), BranchIdPrefix) | |||
| x.branchId, _ = strconv.ParseInt(branchId, 10, 64) | |||
| } | |||
| } | |||
| @@ -0,0 +1,46 @@ | |||
| /* | |||
| * 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 xa | |||
| import ( | |||
| "testing" | |||
| "github.com/stretchr/testify/assert" | |||
| ) | |||
| func TestXABranchXidBuild(t *testing.T) { | |||
| xid := "111" | |||
| branchId := int64(222) | |||
| x := Build(xid, branchId) | |||
| assert.Equal(t, x.GetGlobalXid(), xid) | |||
| assert.Equal(t, x.GetBranchId(), branchId) | |||
| assert.Equal(t, x.GetGlobalTransactionId(), []byte(xid)) | |||
| assert.Equal(t, x.GetBranchQualifier(), []byte("-222")) | |||
| } | |||
| func TestXABranchXidBuildWithByte(t *testing.T) { | |||
| xid := []byte("111") | |||
| branchId := []byte(BranchIdPrefix + "222") | |||
| x := BuildWithByte(xid, branchId) | |||
| assert.Equal(t, x.GetGlobalTransactionId(), xid) | |||
| assert.Equal(t, x.GetBranchQualifier(), branchId) | |||
| assert.Equal(t, x.GetGlobalXid(), "111") | |||
| assert.Equal(t, x.GetBranchId(), int64(222)) | |||
| } | |||
| @@ -0,0 +1,30 @@ | |||
| /* | |||
| * 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 xa | |||
| type Xid interface { | |||
| GetFormatId() int | |||
| GetGlobalTransactionId() []byte | |||
| GetBranchQualifier() []byte | |||
| } | |||
| type XAXid interface { | |||
| Xid | |||
| GetGlobalXid() string | |||
| GetBranchId() int64 | |||
| } | |||
| @@ -0,0 +1,26 @@ | |||
| /* | |||
| * 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 xa | |||
| func Build(xid string, branchId int64) *XABranchXid { | |||
| return NewXABranchXid(WithXid(xid), WithBranchId(branchId)) | |||
| } | |||
| func BuildWithByte(globalTransactionId []byte, branchQualifier []byte) *XABranchXid { | |||
| return NewXABranchXid(WithGlobalTransactionId(globalTransactionId), WithBranchQualifier(branchQualifier)) | |||
| } | |||