* 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)) | |||
} |