Skip to content

Commit 9a5b2d5

Browse files
committed
bdl requests to pass internationalized information
1 parent cddbc81 commit 9a5b2d5

File tree

9 files changed

+141
-14
lines changed

9 files changed

+141
-14
lines changed

conf/core-services/i18n/i18n.yaml

+6
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,9 @@ zh:
1414
Mem: ' 内存 '
1515
CPUQuotaIsLessThanRequest: '调整后的%s环境的 CPU 配额(%.3f 核)不得小于当前使用量(%.3f 核),请重新设置'
1616
MemQuotaIsLessThanRequest: '调整后的%s环境的内存配额(%.3f G)不得小于当前使用量(%.3f G),请重新设置'
17+
DeleteProjectErrorApplicationExist: '删除项目失败(项目中还存在应用)'
18+
FailedGetProject: "获取项目失败"
19+
FailedDeleteProject: "删除项目失败"
1720
en:
1821
AvailableIsLessThanQuota: The actual available resource on this workspace in the cluster is less than the quota. Please ask the Ops to allocate project resources reasonably
1922
NoResourceForTheWorkspace: No allocatable resources on this workspace in the cluster, please check the workspace labels for the nodes
@@ -30,3 +33,6 @@ en:
3033
Mem: ' Mem '
3134
CPUQuotaIsLessThanRequest: "The env %s's new CPU quota (%.3f Core) cannot be less than the actual request (%.3f Core), please reset it"
3235
MemQuotaIsLessThanRequest: "The env %s's new Mem quota (%.3f G) cannot be less than the actual request (%.3f G), please reset it"
36+
DeleteProjectErrorApplicationExist: 'failed to delete project(there exists applications)'
37+
FailedGetProject: "failed to get project"
38+
FailedDeleteProject: "failed to delete project"

go.mod

+1-1
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,6 @@ require (
88
github.com/DATA-DOG/go-sqlmock v1.5.0
99
github.com/GoogleCloudPlatform/spark-on-k8s-operator v0.0.0-20201215015655-2e8b733f5ad0
1010
github.com/Masterminds/semver v1.5.0
11-
github.com/Shopify/sarama v1.19.0
1211
github.com/ahmetb/go-linq/v3 v3.2.0
1312
github.com/alecthomas/assert v0.0.0-20170929043011-405dbfeb8e38
1413
github.com/alecthomas/colour v0.1.0 // indirect
@@ -53,6 +52,7 @@ require (
5352
github.com/ghodss/yaml v1.0.1-0.20190212211648-25d852aebe32
5453
github.com/gin-gonic/gin v1.7.0
5554
github.com/go-echarts/go-echarts/v2 v2.2.4
55+
github.com/go-eden/routine v0.0.2
5656
github.com/go-openapi/loads v0.19.4
5757
github.com/go-openapi/spec v0.19.8
5858
github.com/go-openapi/strfmt v0.19.5

go.sum

+2-7
Original file line numberDiff line numberDiff line change
@@ -135,9 +135,7 @@ github.com/PuerkitoBio/urlesc v0.0.0-20170810143723-de5bf2ad4578 h1:d+Bc7a5rLufV
135135
github.com/PuerkitoBio/urlesc v0.0.0-20170810143723-de5bf2ad4578/go.mod h1:uGdkoq3SwY9Y+13GIhn11/XLaGBb4BfwItxLd5jeuXE=
136136
github.com/Shopify/logrus-bugsnag v0.0.0-20171204204709-577dee27f20d h1:UrqY+r/OJnIp5u0s1SbQ8dVfLCZJsnvazdBP5hS4iRs=
137137
github.com/Shopify/logrus-bugsnag v0.0.0-20171204204709-577dee27f20d/go.mod h1:HI8ITrYtUY+O+ZhtlqUnD8+KwNPOyugEhfP9fdUIaEQ=
138-
github.com/Shopify/sarama v1.19.0 h1:9oksLxC6uxVPHPVYUmq6xhr1BOF/hHobWH2UzO67z1s=
139138
github.com/Shopify/sarama v1.19.0/go.mod h1:FVkBWblsNy7DGZRfXLU0O9RCGt5g3g3yEuWXgklEdEo=
140-
github.com/Shopify/toxiproxy v2.1.4+incompatible h1:TKdv8HiTLgE5wdJuEML90aBgNWsokNbMijUGhmcoBJc=
141139
github.com/Shopify/toxiproxy v2.1.4+incompatible/go.mod h1:OXgGpZ6Cli1/URJOF1DMxUHB2q5Ap20/P/eIdh4G0pI=
142140
github.com/StackExchange/wmi v0.0.0-20190523213315-cbe66965904d h1:G0m3OIz70MZUWq3EgK3CesDbo8upS2Vm9/P3FtgI+Jk=
143141
github.com/StackExchange/wmi v0.0.0-20190523213315-cbe66965904d/go.mod h1:3eOhrUMpNV+6aFIbp5/iudMxNCF27Vw2OZgy4xEx0Fg=
@@ -457,11 +455,8 @@ github.com/dustin/go-humanize v0.0.0-20180421182945-02af3965c54e/go.mod h1:Htrtb
457455
github.com/dustin/go-humanize v1.0.0 h1:VSnTsYCnlFHaM2/igO1h6X3HA71jcobQuxemgkq4zYo=
458456
github.com/dustin/go-humanize v1.0.0/go.mod h1:HtrtbFcZ19U5GC7JDqmcUSB87Iq5E25KnS6fMYU6eOk=
459457
github.com/dustmop/soup v1.1.2-0.20190516214245-38228baa104e/go.mod h1:CgNC6SGbT+Xb8wGGvzilttZL1mc5sQ/5KkcxsZttMIk=
460-
github.com/eapache/go-resiliency v1.1.0 h1:1NtRmCAqadE2FN4ZcN6g90TP3uk8cg9rn9eNK2197aU=
461458
github.com/eapache/go-resiliency v1.1.0/go.mod h1:kFI+JgMyC7bLPUVY133qvEBtVayf5mFgVsvEsIPBvNs=
462-
github.com/eapache/go-xerial-snappy v0.0.0-20180814174437-776d5712da21 h1:YEetp8/yCZMuEPMUDHG0CW/brkkEp8mzqk2+ODEitlw=
463459
github.com/eapache/go-xerial-snappy v0.0.0-20180814174437-776d5712da21/go.mod h1:+020luEh2TKB4/GOp8oxxtq0Daoen/Cii55CzbTV6DU=
464-
github.com/eapache/queue v1.1.0 h1:YOEu7KNc61ntiQlcEeUIoDTJ2o8mQznoNvUhiigpIqc=
465460
github.com/eapache/queue v1.1.0/go.mod h1:6eCeP0CKFpHLu8blIFXhExK/dRa7WDZfr6jVFPTqq+I=
466461
github.com/edsrzf/mmap-go v1.0.0/go.mod h1:YO35OhQPt3KJa3ryjFM5Bs14WD66h8eGKpfaBNrHW5M=
467462
github.com/eknkc/amber v0.0.0-20171010120322-cdade1c07385/go.mod h1:0vRUJqYpeSZifjYj7uP3BG/gKcuzL9xWVV/Y+cK33KM=
@@ -574,8 +569,9 @@ github.com/go-bindata/go-bindata/v3 v3.1.3/go.mod h1:1/zrpXsLD8YDIbhZRqXzm1Ghc7N
574569
github.com/go-chi/chi v4.0.2+incompatible/go.mod h1:eB3wogJHnLi3x/kFX2A+IbTBlXxmMeXJVKy9tTv1XzQ=
575570
github.com/go-echarts/go-echarts/v2 v2.2.4 h1:SKJpdyNIyD65XjbUZjzg6SwccTNXEgmh+PlaO23g2H0=
576571
github.com/go-echarts/go-echarts/v2 v2.2.4/go.mod h1:6TOomEztzGDVDkOSCFBq3ed7xOYfbOqhaBzD0YV771A=
577-
github.com/go-eden/routine v0.0.1 h1:EFzGtHcxmv2gAcdoG7vMESe+26nuIl0/vTMtc030m/4=
578572
github.com/go-eden/routine v0.0.1/go.mod h1:R+sklWRKa0GPYXW5Opyr1nSb9KbwpEF9AXBARb7r1XI=
573+
github.com/go-eden/routine v0.0.2 h1:jcRSRZEKX0R1OqYqfbBRXxpaDxANUJn2m7liPe7KzQI=
574+
github.com/go-eden/routine v0.0.2/go.mod h1:R+sklWRKa0GPYXW5Opyr1nSb9KbwpEF9AXBARb7r1XI=
579575
github.com/go-errors/errors v1.0.1 h1:LUHzmkK3GUKUrL/1gfBUxAHzcev3apQlezX/+O7ma6w=
580576
github.com/go-errors/errors v1.0.1/go.mod h1:f4zRHt4oKfwPJE5k8C9vpYG+aDHdBFUsgrm6/TyX73Q=
581577
github.com/go-gl/glfw v0.0.0-20190409004039-e6da0acd62b1/go.mod h1:vR7hzQXu2zJy9AVAgeJqvqgH9Q5CA+iKCZ2gyEVpxRU=
@@ -1525,7 +1521,6 @@ github.com/rancher/wrangler v0.6.2-0.20200714200521-c61fae623942/go.mod h1:8LdIq
15251521
github.com/rancher/wrangler v0.6.2-0.20200820173016-2068de651106/go.mod h1:iKqQcYs4YSDjsme52OZtQU4jHPmLlIiM93aj2c8c/W8=
15261522
github.com/rancher/wrangler v0.8.1-0.20210423003607-f71a90542852 h1:HMvBxqM0edSRzRZSWg0uDPaKy0NJhIoePmkln4ta4bs=
15271523
github.com/rancher/wrangler v0.8.1-0.20210423003607-f71a90542852/go.mod h1:zSV5oh3+YZboilwcJmFHO3J6FZba82BTQft1b6ijx2I=
1528-
github.com/rcrowley/go-metrics v0.0.0-20181016184325-3113b8401b8a h1:9ZKAASQSHhDYGoxY8uLVpewe1GDZ2vu2Tr/vTdVAkFQ=
15291524
github.com/rcrowley/go-metrics v0.0.0-20181016184325-3113b8401b8a/go.mod h1:bCqnVzQkZxMG4s8nGwiZ5l3QUCyqpo9Y+/ZMZ9VjZe4=
15301525
github.com/recallsong/go-utils v1.1.2-0.20210826100715-fce05eefa294 h1:1CONHJOaZVu3fJv11U+/KSstXi4KK3PvdFNPyf6MjYA=
15311526
github.com/recallsong/go-utils v1.1.2-0.20210826100715-fce05eefa294/go.mod h1:NARLokMUOzyJ55oYXvPcxQh3rBoTBAbolNfqou6AqdY=

modules/core-services/endpoints/project.go

+1-1
Original file line numberDiff line numberDiff line change
@@ -245,7 +245,7 @@ func (e *Endpoints) DeleteProject(ctx context.Context, r *http.Request, vars map
245245
orgIDStr := r.Header.Get(httputil.OrgHeader)
246246
orgID, err := strutil.Atoi64(orgIDStr)
247247
if err != nil {
248-
return apierrors.ErrUpdateProject.InvalidParameter(err).ToResp(), nil
248+
return apierrors.ErrDeleteProject.InvalidParameter(err).ToResp(), nil
249249
}
250250

251251
// 获取当前用户

modules/core-services/services/project/project.go

+5-3
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,7 @@ import (
3737
"github.com/erda-project/erda/modules/core-services/types"
3838
"github.com/erda-project/erda/pkg/crypto/uuid"
3939
"github.com/erda-project/erda/pkg/filehelper"
40+
local "github.com/erda-project/erda/pkg/i18n"
4041
"github.com/erda-project/erda/pkg/numeral"
4142
calcu "github.com/erda-project/erda/pkg/resourcecalculator"
4243
"github.com/erda-project/erda/pkg/ucauth"
@@ -631,14 +632,15 @@ func (p *Project) DeleteWithEvent(projectID int64) error {
631632

632633
// Delete 删除项目
633634
func (p *Project) Delete(projectID int64) (*model.Project, error) {
635+
langCodes, _ := i18n.ParseLanguageCode(local.GetGoroutineBindLang())
634636
// check if application exists
635637
if count, err := p.db.GetApplicationCountByProjectID(projectID); err != nil || count > 0 {
636-
return nil, errors.Errorf("failed to delete project(there exists applications)")
638+
return nil, errors.Errorf(p.trans.Text(langCodes, "DeleteProjectErrorApplicationExist"))
637639
}
638640

639641
project, err := p.db.GetProjectByID(projectID)
640642
if err != nil {
641-
return nil, errors.Errorf("failed to get project, (%v)", err)
643+
return nil, errors.Errorf(p.trans.Text(langCodes, "FailedGetProject")+"(%v)", err)
642644
}
643645

644646
// TODO We need to turn this check on after adding the delete portal to the UI
@@ -652,7 +654,7 @@ func (p *Project) Delete(projectID int64) (*model.Project, error) {
652654
// }
653655

654656
if err = p.db.DeleteProject(projectID); err != nil {
655-
return nil, errors.Errorf("failed to delete project, (%v)", err)
657+
return nil, errors.Errorf(p.trans.Text(langCodes, "FailedDeleteProject")+"(%v)", err)
656658
}
657659
_ = p.db.DeleteProjectQutoa(projectID)
658660
logrus.Infof("deleted project %d", projectID)

pkg/goroutine_context/context.go

+77
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,77 @@
1+
// Copyright (c) 2021 Terminus, Inc.
2+
//
3+
// Licensed under the Apache License, Version 2.0 (the "License");
4+
// you may not use this file except in compliance with the License.
5+
// You may obtain a copy of the License at
6+
//
7+
// http://www.apache.org/licenses/LICENSE-2.0
8+
//
9+
// Unless required by applicable law or agreed to in writing, software
10+
// distributed under the License is distributed on an "AS IS" BASIS,
11+
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12+
// See the License for the specific language governing permissions and
13+
// limitations under the License.
14+
15+
package goroutine_context
16+
17+
import (
18+
"context"
19+
"sync"
20+
21+
"github.com/go-eden/routine"
22+
)
23+
24+
const LocaleNameContextKey = "locale_name_context_key"
25+
26+
const bucketsSize = 128
27+
28+
type (
29+
contextBucket struct {
30+
lock sync.RWMutex
31+
data map[int64]context.Context
32+
}
33+
contextBuckets struct {
34+
buckets [bucketsSize]*contextBucket
35+
}
36+
)
37+
38+
var goroutineContext contextBuckets
39+
40+
func init() {
41+
for i := range goroutineContext.buckets {
42+
goroutineContext.buckets[i] = &contextBucket{
43+
data: make(map[int64]context.Context),
44+
}
45+
}
46+
}
47+
48+
// GetContext .
49+
func GetContext() context.Context {
50+
goid := routine.Goid()
51+
idx := goid % bucketsSize
52+
bucket := goroutineContext.buckets[idx]
53+
bucket.lock.RLock()
54+
ctx := bucket.data[goid]
55+
bucket.lock.RUnlock()
56+
return ctx
57+
}
58+
59+
// SetContext .
60+
func SetContext(ctx context.Context) {
61+
goid := routine.Goid()
62+
idx := goid % bucketsSize
63+
bucket := goroutineContext.buckets[idx]
64+
bucket.lock.Lock()
65+
defer bucket.lock.Unlock()
66+
bucket.data[goid] = ctx
67+
}
68+
69+
// ClearContext .
70+
func ClearContext() {
71+
goid := routine.Goid()
72+
idx := goid % bucketsSize
73+
bucket := goroutineContext.buckets[idx]
74+
bucket.lock.Lock()
75+
defer bucket.lock.Unlock()
76+
delete(bucket.data, goid)
77+
}

pkg/http/httpclient/request.go

+8
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,7 @@ import (
3232
"github.com/pkg/errors"
3333

3434
"github.com/erda-project/erda/pkg/http/customhttp"
35+
"github.com/erda-project/erda/pkg/i18n"
3536
"github.com/erda-project/erda/pkg/terminal/loading"
3637
)
3738

@@ -105,6 +106,13 @@ func (r *Request) Do() AfterDo {
105106
for k, v := range r.header {
106107
req.Header.Set(k, v)
107108
}
109+
110+
// get goroutine context il8n header to bdl request
111+
localeName := i18n.GetGoroutineBindLang()
112+
if localeName != "" {
113+
req.Header.Set(i18n.LangHeader, localeName)
114+
}
115+
108116
for _, v := range r.cookie {
109117
req.AddCookie(v)
110118
}

pkg/http/httpserver/server.go

+6
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,7 @@ import (
3232

3333
"github.com/erda-project/erda/apistructs"
3434
"github.com/erda-project/erda/pkg/crypto/uuid"
35+
"github.com/erda-project/erda/pkg/goroutine_context"
3536
"github.com/erda-project/erda/pkg/http/httpserver/ierror"
3637
"github.com/erda-project/erda/pkg/i18n"
3738
"github.com/erda-project/erda/pkg/strutil"
@@ -148,6 +149,11 @@ func (s *Server) internal(handler func(context.Context, *http.Request, map[strin
148149
locale = s.localeLoader.Locale(localeName)
149150
}
150151

152+
// set global context bind goroutine id
153+
i18n.SetGoroutineBindLang(localeName)
154+
// clear all global context
155+
defer goroutine_context.ClearContext()
156+
151157
// Manual decoding url var
152158
muxVars := mux.Vars(r)
153159
for k, v := range muxVars {

pkg/i18n/helper.go

+35-2
Original file line numberDiff line numberDiff line change
@@ -14,21 +14,54 @@
1414

1515
package i18n
1616

17-
import "net/http"
17+
import (
18+
"context"
19+
"net/http"
20+
21+
"github.com/erda-project/erda/pkg/goroutine_context"
22+
)
1823

1924
const ZH = "zh-CN"
2025
const EN = "en-US"
2126

27+
const LangHeader = "Lang"
28+
2229
// GetLocaleNameByRequest 从request获取语言名称
2330
func GetLocaleNameByRequest(request *http.Request) string {
2431
// 优先querystring 其次header
2532
lang := request.URL.Query().Get("lang")
2633
if lang != "" {
2734
return lang
2835
}
29-
lang = request.Header.Get("Lang")
36+
lang = request.Header.Get(LangHeader)
3037
if lang != "" {
3138
return lang
3239
}
3340
return ""
3441
}
42+
43+
func GetGoroutineBindLang() string {
44+
globalContext := goroutine_context.GetContext()
45+
if globalContext == nil {
46+
return ""
47+
}
48+
key := globalContext.Value(goroutine_context.LocaleNameContextKey)
49+
if key == nil {
50+
return ""
51+
}
52+
localeName, ok := key.(string)
53+
if !ok {
54+
return ""
55+
}
56+
57+
return localeName
58+
}
59+
60+
func SetGoroutineBindLang(localeName string) {
61+
ctx := goroutine_context.GetContext()
62+
if ctx == nil {
63+
ctx = context.Background()
64+
}
65+
66+
goroutine_context.SetContext(context.WithValue(ctx, goroutine_context.LocaleNameContextKey, localeName))
67+
}

0 commit comments

Comments
 (0)