go.temporal.io/server@v1.23.0/common/persistence/visibility/store/elasticsearch/visibility_store_write_test.go (about) 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 elasticsearch 26 27 import ( 28 "context" 29 "fmt" 30 "strings" 31 "time" 32 33 "github.com/golang/mock/gomock" 34 commonpb "go.temporal.io/api/common/v1" 35 enumspb "go.temporal.io/api/enums/v1" 36 37 "go.temporal.io/server/common/future" 38 "go.temporal.io/server/common/payload" 39 "go.temporal.io/server/common/persistence" 40 "go.temporal.io/server/common/persistence/visibility/manager" 41 "go.temporal.io/server/common/persistence/visibility/store" 42 "go.temporal.io/server/common/persistence/visibility/store/elasticsearch/client" 43 "go.temporal.io/server/common/searchattribute" 44 ) 45 46 func (s *ESVisibilitySuite) TestRecordWorkflowExecutionStarted() { 47 // test non-empty request fields match 48 request := &store.InternalRecordWorkflowExecutionStartedRequest{ 49 InternalVisibilityRequestBase: &store.InternalVisibilityRequestBase{ 50 NamespaceID: "namespaceID", 51 WorkflowID: "wid", 52 RunID: "rid", 53 WorkflowTypeName: "wfType", 54 StartTime: time.Unix(0, 123).UTC(), 55 ExecutionTime: time.Unix(0, 321).UTC(), 56 TaskID: int64(111), 57 ShardID: 2208, 58 Memo: persistence.NewDataBlob([]byte("test bytes"), enumspb.ENCODING_TYPE_PROTO3.String()), 59 Status: enumspb.WORKFLOW_EXECUTION_STATUS_RUNNING, 60 TaskQueue: "task-queue-name", 61 SearchAttributes: &commonpb.SearchAttributes{ 62 IndexedFields: map[string]*commonpb.Payload{ 63 "CustomTextField": payload.EncodeString("alex"), 64 }, 65 }, 66 }, 67 } 68 69 s.mockProcessor.EXPECT().Add(gomock.Any(), gomock.Any()). 70 DoAndReturn(func(bulkRequest *client.BulkableRequest, visibilityTaskKey string) future.Future[bool] { 71 s.Equal("2208~111", visibilityTaskKey) 72 73 body := bulkRequest.Doc 74 75 s.Equal(request.NamespaceID, body[searchattribute.NamespaceID]) 76 s.Equal(request.WorkflowID, body[searchattribute.WorkflowID]) 77 s.Equal(request.RunID, body[searchattribute.RunID]) 78 s.Equal(request.WorkflowTypeName, body[searchattribute.WorkflowType]) 79 s.EqualValues(request.StartTime, body[searchattribute.StartTime]) 80 s.EqualValues(request.ExecutionTime, body[searchattribute.ExecutionTime]) 81 s.Equal(request.TaskQueue, body[searchattribute.TaskQueue]) 82 s.EqualValues(request.Status.String(), body[searchattribute.ExecutionStatus]) 83 84 s.Equal(request.Memo.Data, body[searchattribute.Memo]) 85 s.Equal(enumspb.ENCODING_TYPE_PROTO3.String(), body[searchattribute.MemoEncoding]) 86 87 CustomTextField := body["CustomTextField"].(string) 88 // %q because request has JSON encoded string. 89 s.EqualValues(request.SearchAttributes.GetIndexedFields()["CustomTextField"].Data, fmt.Sprintf("%q", CustomTextField)) 90 91 s.Equal(client.BulkableRequestTypeIndex, bulkRequest.RequestType) 92 s.EqualValues(request.TaskID, bulkRequest.Version) 93 s.Equal("wid~rid", bulkRequest.ID) 94 s.Equal("test-index", bulkRequest.Index) 95 96 f := future.NewFuture[bool]() 97 f.Set(true, nil) 98 return f 99 }) 100 101 err := s.visibilityStore.RecordWorkflowExecutionStarted(context.Background(), request) 102 s.NoError(err) 103 } 104 105 func (s *ESVisibilitySuite) TestRecordWorkflowExecutionStarted_EmptyRequest() { 106 // test empty request 107 request := &store.InternalRecordWorkflowExecutionStartedRequest{ 108 InternalVisibilityRequestBase: &store.InternalVisibilityRequestBase{ 109 Memo: &commonpb.DataBlob{}, 110 }, 111 } 112 113 s.mockProcessor.EXPECT().Add(gomock.Any(), gomock.Any()). 114 DoAndReturn(func(bulkRequest *client.BulkableRequest, visibilityTaskKey string) future.Future[bool] { 115 s.Equal("0~0", visibilityTaskKey) 116 117 body := bulkRequest.Doc 118 119 _, ok := body[searchattribute.Memo] 120 s.False(ok) 121 _, ok = body[searchattribute.MemoEncoding] 122 s.False(ok) 123 124 s.Equal(client.BulkableRequestTypeIndex, bulkRequest.RequestType) 125 s.EqualValues(request.TaskID, bulkRequest.Version) 126 s.Equal("~", bulkRequest.ID) 127 s.Equal("test-index", bulkRequest.Index) 128 129 f := future.NewFuture[bool]() 130 f.Set(true, nil) 131 return f 132 }) 133 134 err := s.visibilityStore.RecordWorkflowExecutionStarted(context.Background(), request) 135 s.NoError(err) 136 } 137 138 func (s *ESVisibilitySuite) TestRecordWorkflowExecutionClosed() { 139 // test non-empty request fields match 140 request := &store.InternalRecordWorkflowExecutionClosedRequest{ 141 InternalVisibilityRequestBase: &store.InternalVisibilityRequestBase{ 142 NamespaceID: "namespaceID", 143 WorkflowID: "wid", 144 RunID: "rid", 145 WorkflowTypeName: "wfType", 146 StartTime: time.Date(2020, 8, 2, 1, 2, 3, 4, time.UTC), 147 ExecutionTime: time.Date(2020, 8, 2, 2, 2, 3, 4, time.UTC), 148 TaskID: int64(111), 149 ShardID: 2208, 150 Memo: persistence.NewDataBlob([]byte("test bytes"), enumspb.ENCODING_TYPE_PROTO3.String()), 151 Status: enumspb.WORKFLOW_EXECUTION_STATUS_TERMINATED, 152 TaskQueue: "task-queue-name", 153 SearchAttributes: &commonpb.SearchAttributes{ 154 IndexedFields: map[string]*commonpb.Payload{ 155 "CustomTextField": payload.EncodeString("alex"), 156 }, 157 }, 158 }, 159 CloseTime: time.Unix(0, 1978).UTC(), 160 HistoryLength: int64(20), 161 } 162 163 s.mockProcessor.EXPECT().Add(gomock.Any(), gomock.Any()). 164 DoAndReturn(func(bulkRequest *client.BulkableRequest, visibilityTaskKey string) future.Future[bool] { 165 s.Equal("2208~111", visibilityTaskKey) 166 167 body := bulkRequest.Doc 168 169 s.Equal(request.NamespaceID, body[searchattribute.NamespaceID]) 170 s.Equal(request.WorkflowID, body[searchattribute.WorkflowID]) 171 s.Equal(request.RunID, body[searchattribute.RunID]) 172 s.Equal(request.WorkflowTypeName, body[searchattribute.WorkflowType]) 173 s.EqualValues(request.StartTime, body[searchattribute.StartTime]) 174 s.EqualValues(request.ExecutionTime, body[searchattribute.ExecutionTime]) 175 s.Equal(request.Memo.Data, body[searchattribute.Memo]) 176 s.Equal(enumspb.ENCODING_TYPE_PROTO3.String(), body[searchattribute.MemoEncoding]) 177 s.EqualValues(request.CloseTime, body[searchattribute.CloseTime]) 178 s.EqualValues(request.Status.String(), body[searchattribute.ExecutionStatus]) 179 s.EqualValues(request.HistoryLength, body[searchattribute.HistoryLength]) 180 181 s.Equal(client.BulkableRequestTypeIndex, bulkRequest.RequestType) 182 s.EqualValues(request.TaskID, bulkRequest.Version) 183 s.Equal("wid~rid", bulkRequest.ID) 184 s.Equal("test-index", bulkRequest.Index) 185 186 f := future.NewFuture[bool]() 187 f.Set(true, nil) 188 return f 189 }) 190 191 err := s.visibilityStore.RecordWorkflowExecutionClosed(context.Background(), request) 192 s.NoError(err) 193 } 194 195 func (s *ESVisibilitySuite) TestRecordWorkflowExecutionClosed_EmptyRequest() { 196 // test empty request 197 request := &store.InternalRecordWorkflowExecutionClosedRequest{ 198 InternalVisibilityRequestBase: &store.InternalVisibilityRequestBase{ 199 Memo: &commonpb.DataBlob{}, 200 }, 201 } 202 203 s.mockProcessor.EXPECT().Add(gomock.Any(), gomock.Any()). 204 DoAndReturn(func(bulkRequest *client.BulkableRequest, visibilityTaskKey string) future.Future[bool] { 205 s.Equal("0~0", visibilityTaskKey) 206 207 body := bulkRequest.Doc 208 209 _, ok := body[searchattribute.Memo] 210 s.False(ok) 211 _, ok = body[searchattribute.MemoEncoding] 212 s.False(ok) 213 214 s.Equal(client.BulkableRequestTypeIndex, bulkRequest.RequestType) 215 s.EqualValues(request.TaskID, bulkRequest.Version) 216 s.Equal("~", bulkRequest.ID) 217 s.Equal("test-index", bulkRequest.Index) 218 219 f := future.NewFuture[bool]() 220 f.Set(true, nil) 221 return f 222 }) 223 224 err := s.visibilityStore.RecordWorkflowExecutionClosed(context.Background(), request) 225 s.NoError(err) 226 } 227 228 func (s *ESVisibilitySuite) TestDeleteExecution() { 229 // test non-empty request fields match 230 request := &manager.VisibilityDeleteWorkflowExecutionRequest{ 231 NamespaceID: "namespaceID", 232 RunID: "rid", 233 WorkflowID: "wid", 234 TaskID: int64(111), 235 } 236 237 s.mockProcessor.EXPECT().Add(gomock.Any(), gomock.Any()). 238 DoAndReturn(func(bulkRequest *client.BulkableRequest, visibilityTaskKey string) future.Future[bool] { 239 s.Equal("wid~rid", visibilityTaskKey) 240 241 s.Equal(client.BulkableRequestTypeDelete, bulkRequest.RequestType) 242 s.EqualValues(request.TaskID, bulkRequest.Version) 243 s.Equal("wid~rid", bulkRequest.ID) 244 s.Equal("test-index", bulkRequest.Index) 245 246 f := future.NewFuture[bool]() 247 f.Set(true, nil) 248 return f 249 }) 250 251 err := s.visibilityStore.DeleteWorkflowExecution(context.Background(), request) 252 s.NoError(err) 253 } 254 255 func (s *ESVisibilitySuite) TestDeleteExecution_EmptyRequest() { 256 // test empty request 257 request := &manager.VisibilityDeleteWorkflowExecutionRequest{} 258 259 s.mockProcessor.EXPECT().Add(gomock.Any(), gomock.Any()). 260 DoAndReturn(func(bulkRequest *client.BulkableRequest, visibilityTaskKey string) future.Future[bool] { 261 s.Equal("~", visibilityTaskKey) 262 263 s.Equal(client.BulkableRequestTypeDelete, bulkRequest.RequestType) 264 s.Equal("~", bulkRequest.ID) 265 s.Equal("test-index", bulkRequest.Index) 266 267 f := future.NewFuture[bool]() 268 f.Set(true, nil) 269 return f 270 }) 271 272 err := s.visibilityStore.DeleteWorkflowExecution(context.Background(), request) 273 s.NoError(err) 274 } 275 276 func (s *ESVisibilitySuite) Test_getDocID() { 277 s.Equal("wid~rid", getDocID("wid", "rid")) 278 279 s.Equal(strings.Repeat("a", 512), getDocID("wid", strings.Repeat("a", 1000))) 280 s.Equal(strings.Repeat("a", 512), getDocID("wid", strings.Repeat("a", 513))) 281 s.Equal(strings.Repeat("a", 512), getDocID("wid", strings.Repeat("a", 512))) 282 s.Equal(strings.Repeat("a", 511), getDocID("wid", strings.Repeat("a", 511))) 283 s.Equal("w~"+strings.Repeat("a", 510), getDocID("wid", strings.Repeat("a", 510))) 284 s.Equal("wi~"+strings.Repeat("a", 509), getDocID("wid", strings.Repeat("a", 509))) 285 s.Equal("wid~"+strings.Repeat("a", 508), getDocID("wid", strings.Repeat("a", 508))) 286 s.Equal("wid~"+strings.Repeat("a", 507), getDocID("wid", strings.Repeat("a", 507))) 287 288 s.Equal(strings.Repeat("a", 512-1-36)+"~fd86a520-741e-4fd3-a788-165c445ea6f3", getDocID(strings.Repeat("a", 1000), "fd86a520-741e-4fd3-a788-165c445ea6f3")) 289 s.Equal(strings.Repeat("a", 512-1-36)+"~fd86a520-741e-4fd3-a788-165c445ea6f3", getDocID(strings.Repeat("a", 477), "fd86a520-741e-4fd3-a788-165c445ea6f3")) 290 s.Equal(strings.Repeat("a", 512-1-36)+"~fd86a520-741e-4fd3-a788-165c445ea6f3", getDocID(strings.Repeat("a", 476), "fd86a520-741e-4fd3-a788-165c445ea6f3")) 291 s.Equal(strings.Repeat("a", 475)+"~fd86a520-741e-4fd3-a788-165c445ea6f3", getDocID(strings.Repeat("a", 475), "fd86a520-741e-4fd3-a788-165c445ea6f3")) 292 s.Equal(strings.Repeat("a", 474)+"~fd86a520-741e-4fd3-a788-165c445ea6f3", getDocID(strings.Repeat("a", 474), "fd86a520-741e-4fd3-a788-165c445ea6f3")) 293 s.Equal(strings.Repeat("a", 400)+"~fd86a520-741e-4fd3-a788-165c445ea6f3", getDocID(strings.Repeat("a", 400), "fd86a520-741e-4fd3-a788-165c445ea6f3")) 294 } 295 296 func (s *ESVisibilitySuite) Test_getVisibilityTaskKey() { 297 s.Equal("22~8", getVisibilityTaskKey(22, 8)) 298 s.Equal("228~1978", getVisibilityTaskKey(228, 1978)) 299 }