Skip to content

Commit b6de7d5

Browse files
authored
Delete namespace workflow (#2569)
1 parent e60d6bd commit b6de7d5

File tree

17 files changed

+2014
-7
lines changed

17 files changed

+2014
-7
lines changed

common/log/tag/tags.go

Lines changed: 13 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -50,7 +50,7 @@ const (
5050
errorPrefix = "*"
5151
)
5252

53-
/////////////////// Common tags defined here ///////////////////
53+
// ========== Common tags defined here ==========
5454

5555
// Operation returns tag for Operation
5656
func Operation(operation string) ZapTag {
@@ -87,7 +87,7 @@ func TimestampPtr(t *time.Time) ZapTag {
8787
return NewTimeTag("timestamp", timestamp.TimeValue(t))
8888
}
8989

90-
/////////////////// Workflow tags defined here: ( wf is short for workflow) ///////////////////
90+
// ========== Workflow tags defined here: ( wf is short for workflow) ==========
9191

9292
// WorkflowAction returns tag for WorkflowAction
9393
func workflowAction(action string) ZapTag {
@@ -326,7 +326,7 @@ func WorkflowEventCount(eventCount int) ZapTag {
326326
return NewInt("wf-event-count", eventCount)
327327
}
328328

329-
/////////////////// System tags defined here: ///////////////////
329+
// ========== System tags defined here: ==========
330330
// Tags with pre-define values
331331

332332
// Component returns tag for Component
@@ -672,7 +672,7 @@ func TokenLastEventID(id int64) ZapTag {
672672
return NewInt64("token-last-event-id", id)
673673
}
674674

675-
/////////////////// XDC tags defined here: xdc- ///////////////////
675+
// ========== XDC tags defined here: xdc- ==========
676676

677677
// SourceCluster returns tag for SourceCluster
678678
func SourceCluster(sourceCluster string) ZapTag {
@@ -719,7 +719,7 @@ func TokenLastEventVersion(version int64) ZapTag {
719719
return NewInt64("xdc-token-last-event-version", version)
720720
}
721721

722-
/////////////////// Archival tags defined here: archival- ///////////////////
722+
// ========== Archival tags defined here: archival- ==========
723723
// archival request tags
724724

725725
// ArchivalCallerServiceName returns tag for the service name calling archival client
@@ -884,3 +884,11 @@ func TLSCertFiles(filePaths []string) ZapTag {
884884
func Timeout(timeoutValue string) ZapTag {
885885
return NewStringTag("timeout", timeoutValue)
886886
}
887+
888+
func DeletedExecutionsCount(count int) ZapTag {
889+
return NewInt("deleted-executions-count", count)
890+
}
891+
892+
func DeletedExecutionsErrorCount(count int) ZapTag {
893+
return NewInt("delete-executions-error-count", count)
894+
}

common/metrics/defs.go

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1190,6 +1190,10 @@ const (
11901190
// MigrationWorkflowScope is scope used by metrics emitted by migration related workflows
11911191
MigrationWorkflowScope
11921192

1193+
DeleteNamespaceWorkflowScope
1194+
ReclaimResourcesWorkflowScope
1195+
DeleteExecutionsWorkflowScope
1196+
11931197
NumWorkerScopes
11941198
)
11951199

@@ -1730,6 +1734,9 @@ var ScopeDefs = map[ServiceIdx]map[int]scopeDefinition{
17301734
ParentClosePolicyProcessorScope: {operation: "ParentClosePolicyProcessor"},
17311735
AddSearchAttributesWorkflowScope: {operation: "AddSearchAttributesWorkflow"},
17321736
MigrationWorkflowScope: {operation: "MigrationWorkflow"},
1737+
DeleteNamespaceWorkflowScope: {operation: "DeleteNamespaceWorkflow"},
1738+
ReclaimResourcesWorkflowScope: {operation: "ReclaimResourcesWorkflow"},
1739+
DeleteExecutionsWorkflowScope: {operation: "DeleteExecutionsWorkflow"},
17331740
},
17341741
Server: {
17351742
ServerTlsScope: {operation: "ServerTls"},
@@ -2193,6 +2200,18 @@ const (
21932200
CatchUpReadyShardCountGauge
21942201
HandoverReadyShardCountGauge
21952202

2203+
DeleteNamespaceSuccessCount
2204+
RenameNamespaceSuccessCount
2205+
DeleteExecutionsSuccessCount
2206+
DeleteNamespaceFailuresCount
2207+
UpdateNamespaceFailuresCount
2208+
RenameNamespaceFailuresCount
2209+
ReadNamespaceFailuresCount
2210+
ListExecutionsFailuresCount
2211+
TerminateExecutionFailuresCount
2212+
DeleteExecutionFailuresCount
2213+
RateLimiterFailuresCount
2214+
21962215
NumWorkerMetrics
21972216
)
21982217

@@ -2646,6 +2665,18 @@ var MetricDefs = map[ServiceIdx]map[int]metricDefinition{
26462665
AddSearchAttributesFailuresCount: NewCounterDef("add_search_attributes_failures"),
26472666
CatchUpReadyShardCountGauge: NewGaugeDef("catchup_ready_shard_count"),
26482667
HandoverReadyShardCountGauge: NewGaugeDef("handover_ready_shard_count"),
2668+
2669+
DeleteNamespaceSuccessCount: NewCounterDef("delete_namespace_success"),
2670+
RenameNamespaceSuccessCount: NewCounterDef("rename_namespace_success"),
2671+
DeleteExecutionsSuccessCount: NewCounterDef("delete_executions_success"),
2672+
DeleteNamespaceFailuresCount: NewCounterDef("delete_namespace_failures"),
2673+
UpdateNamespaceFailuresCount: NewCounterDef("update_namespace_failures"),
2674+
RenameNamespaceFailuresCount: NewCounterDef("rename_namespace_failures"),
2675+
ReadNamespaceFailuresCount: NewCounterDef("read_namespace_failures"),
2676+
ListExecutionsFailuresCount: NewCounterDef("list_executions_failures"),
2677+
TerminateExecutionFailuresCount: NewCounterDef("terminate_executions_failures"),
2678+
DeleteExecutionFailuresCount: NewCounterDef("delete_execution_failures"),
2679+
RateLimiterFailuresCount: NewCounterDef("rate_limiter_failures"),
26492680
},
26502681
Server: {
26512682
TlsCertsExpired: NewGaugeDef("certificates_expired"),

host/onebox.go

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -708,6 +708,7 @@ func (c *temporalImpl) startWorker(hosts map[string][]string, startWG *sync.Wait
708708
fx.Provide(func() dynamicconfig.Client { return newIntegrationConfigClient(dynamicconfig.NewNoopClient()) }),
709709
fx.Provide(func() log.Logger { return c.logger }),
710710
fx.Provide(func() esclient.Client { return c.esClient }),
711+
fx.Provide(func() *esclient.Config { return c.esConfig }),
711712

712713
worker.Module,
713714
fx.Populate(&workerService, &clientBean, &namespaceRegistry),
Lines changed: 162 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,162 @@
1+
// The MIT License
2+
//
3+
// Copyright (c) 2020 Temporal Technologies Inc. All rights reserved.
4+
//
5+
// Copyright (c) 2020 Uber Technologies, Inc.
6+
//
7+
// Permission is hereby granted, free of charge, to any person obtaining a copy
8+
// of this software and associated documentation files (the "Software"), to deal
9+
// in the Software without restriction, including without limitation the rights
10+
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
11+
// copies of the Software, and to permit persons to whom the Software is
12+
// furnished to do so, subject to the following conditions:
13+
//
14+
// The above copyright notice and this permission notice shall be included in
15+
// all copies or substantial portions of the Software.
16+
//
17+
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
18+
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
19+
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
20+
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
21+
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
22+
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
23+
// THE SOFTWARE.
24+
25+
package deletenamespace
26+
27+
import (
28+
"context"
29+
"fmt"
30+
"math/rand"
31+
"time"
32+
33+
enumspb "go.temporal.io/api/enums/v1"
34+
"go.temporal.io/api/serviceerror"
35+
36+
"go.temporal.io/server/common/log"
37+
"go.temporal.io/server/common/log/tag"
38+
"go.temporal.io/server/common/metrics"
39+
"go.temporal.io/server/common/namespace"
40+
"go.temporal.io/server/common/persistence"
41+
)
42+
43+
type (
44+
activities struct {
45+
metadataManager persistence.MetadataManager
46+
metricsClient metrics.Client
47+
logger log.Logger
48+
}
49+
)
50+
51+
func NewActivities(
52+
metadataManager persistence.MetadataManager,
53+
metricsClient metrics.Client,
54+
logger log.Logger,
55+
) *activities {
56+
return &activities{
57+
metadataManager: metadataManager,
58+
metricsClient: metricsClient,
59+
logger: logger,
60+
}
61+
}
62+
63+
func (a *activities) GetNamespaceIDActivity(_ context.Context, nsName namespace.Name) (namespace.ID, error) {
64+
getNamespaceRequest := &persistence.GetNamespaceRequest{
65+
Name: nsName.String(),
66+
}
67+
68+
getNamespaceResponse, err := a.metadataManager.GetNamespace(getNamespaceRequest)
69+
if err != nil {
70+
return namespace.EmptyID, err
71+
}
72+
73+
if getNamespaceResponse.Namespace == nil || getNamespaceResponse.Namespace.Info == nil || getNamespaceResponse.Namespace.Info.Id == "" {
74+
return namespace.EmptyID, serviceerror.NewInternal("namespace info is corrupted")
75+
}
76+
77+
return namespace.ID(getNamespaceResponse.Namespace.Info.Id), nil
78+
}
79+
80+
func (a *activities) MarkNamespaceDeletedActivity(_ context.Context, nsName namespace.Name) error {
81+
getNamespaceRequest := &persistence.GetNamespaceRequest{
82+
Name: nsName.String(),
83+
}
84+
85+
metadata, err := a.metadataManager.GetMetadata()
86+
if err != nil {
87+
a.metricsClient.IncCounter(metrics.DeleteNamespaceWorkflowScope, metrics.ReadNamespaceFailuresCount)
88+
a.logger.Error("Unable to get cluster metadata.", tag.WorkflowNamespace(nsName.String()), tag.Error(err))
89+
return err
90+
}
91+
92+
ns, err := a.metadataManager.GetNamespace(getNamespaceRequest)
93+
if err != nil {
94+
a.metricsClient.IncCounter(metrics.DeleteNamespaceWorkflowScope, metrics.ReadNamespaceFailuresCount)
95+
a.logger.Error("Unable to get namespace details.", tag.WorkflowNamespace(nsName.String()), tag.Error(err))
96+
return err
97+
}
98+
99+
ns.Namespace.Info.State = enumspb.NAMESPACE_STATE_DELETED
100+
101+
updateRequest := &persistence.UpdateNamespaceRequest{
102+
Namespace: ns.Namespace,
103+
IsGlobalNamespace: ns.IsGlobalNamespace,
104+
NotificationVersion: metadata.NotificationVersion,
105+
}
106+
107+
err = a.metadataManager.UpdateNamespace(updateRequest)
108+
if err != nil {
109+
a.metricsClient.IncCounter(metrics.DeleteNamespaceWorkflowScope, metrics.UpdateNamespaceFailuresCount)
110+
a.logger.Error("Unable to update namespace state to Deleted.", tag.WorkflowNamespace(nsName.String()), tag.Error(err))
111+
return err
112+
}
113+
return nil
114+
}
115+
116+
func (a *activities) GenerateDeletedNamespaceNameActivity(_ context.Context, nsName namespace.Name) (namespace.Name, error) {
117+
var letters = []rune("1234567890abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ")
118+
const suffixLength = 5
119+
rand.Seed(time.Now().UnixNano())
120+
121+
for { // Just in case. Generated name should always be unique after first attempt.
122+
b := make([]rune, suffixLength)
123+
for i := range b {
124+
b[i] = letters[rand.Intn(len(letters))]
125+
}
126+
127+
newName := fmt.Sprintf("%s-deleted-%s", nsName, string(b))
128+
129+
_, err := a.metadataManager.GetNamespace(&persistence.GetNamespaceRequest{
130+
Name: newName,
131+
})
132+
switch err.(type) {
133+
case nil:
134+
a.logger.Warn("Regenerate namespace name due to collision.", tag.WorkflowNamespace(nsName.String()), tag.WorkflowNamespace(newName))
135+
case *serviceerror.NotFound:
136+
a.logger.Info("Generated new name for deleted namespace.", tag.WorkflowNamespace(nsName.String()), tag.WorkflowNamespace(newName))
137+
return namespace.Name(newName), nil
138+
default:
139+
a.metricsClient.IncCounter(metrics.DeleteNamespaceWorkflowScope, metrics.ReadNamespaceFailuresCount)
140+
a.logger.Error("Unable to get namespace details.", tag.WorkflowNamespace(nsName.String()), tag.Error(err))
141+
return namespace.EmptyName, err
142+
}
143+
}
144+
}
145+
146+
func (a *activities) RenameNamespaceActivity(_ context.Context, previousName namespace.Name, newName namespace.Name) error {
147+
renameNamespaceRequest := &persistence.RenameNamespaceRequest{
148+
PreviousName: previousName.String(),
149+
NewName: newName.String(),
150+
}
151+
152+
err := a.metadataManager.RenameNamespace(renameNamespaceRequest)
153+
if err != nil {
154+
a.metricsClient.IncCounter(metrics.DeleteNamespaceWorkflowScope, metrics.RenameNamespaceFailuresCount)
155+
a.logger.Error("Unable to rename namespace.", tag.WorkflowNamespace(previousName.String()), tag.Error(err))
156+
return err
157+
}
158+
159+
a.metricsClient.IncCounter(metrics.DeleteNamespaceWorkflowScope, metrics.RenameNamespaceSuccessCount)
160+
a.logger.Info("Namespace renamed successfully.", tag.WorkflowNamespace(previousName.String()), tag.WorkflowNamespace(newName.String()))
161+
return nil
162+
}

0 commit comments

Comments
 (0)