go.temporal.io/server@v1.23.0/common/persistence/visibility/store/standard/query_interceptors.go (about) 1 // The MIT License 2 // 3 // Copyright (c) 2021 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 standard 26 27 import ( 28 "time" 29 30 "go.temporal.io/server/common/namespace" 31 "go.temporal.io/server/common/searchattribute" 32 33 "go.temporal.io/api/enums/v1" 34 35 "go.temporal.io/server/common/convert" 36 "go.temporal.io/server/common/persistence/sql/sqlplugin" 37 "go.temporal.io/server/common/persistence/visibility/store/elasticsearch" 38 "go.temporal.io/server/common/persistence/visibility/store/query" 39 ) 40 41 var allowedFilters = []string{ 42 searchattribute.WorkflowID, 43 searchattribute.WorkflowType, 44 searchattribute.ExecutionStatus, 45 searchattribute.StartTime, 46 } 47 48 type ( 49 nameInterceptor struct{} 50 valuesInterceptor struct { 51 filter *sqlplugin.VisibilitySelectFilter 52 nextInterceptor query.FieldValuesInterceptor 53 } 54 ) 55 56 func newNameInterceptor() *nameInterceptor { 57 return &nameInterceptor{} 58 } 59 60 func newValuesInterceptor( 61 namespaceName namespace.Name, 62 searchAttributesTypeMap searchattribute.NameTypeMap, 63 searchAttributesMapperProvider searchattribute.MapperProvider, 64 ) *valuesInterceptor { 65 return &valuesInterceptor{ 66 filter: &sqlplugin.VisibilitySelectFilter{}, 67 nextInterceptor: elasticsearch.NewValuesInterceptor( 68 namespaceName, 69 searchAttributesTypeMap, 70 searchAttributesMapperProvider, 71 ), 72 } 73 } 74 75 func (ni *nameInterceptor) Name(name string, usage query.FieldNameUsage) (string, error) { 76 if usage == query.FieldNameSorter { 77 return "", query.NewConverterError("order by not allowed for standard visibility") 78 } 79 80 for _, filter := range allowedFilters { 81 if filter == name { 82 return name, nil 83 } 84 } 85 86 return "", query.NewConverterError("filter by '%v' not supported for standard visibility", name) 87 } 88 89 func (vi *valuesInterceptor) Values(name string, values ...interface{}) ([]interface{}, error) { 90 switch name { 91 case searchattribute.WorkflowID: 92 values, err := vi.nextInterceptor.Values(name, values...) 93 if err == nil { 94 vi.filter.WorkflowID = convert.StringPtr(values[0].(string)) 95 } 96 return values, err 97 case searchattribute.WorkflowType: 98 values, err := vi.nextInterceptor.Values(name, values...) 99 if err == nil { 100 vi.filter.WorkflowTypeName = convert.StringPtr(values[0].(string)) 101 } 102 return values, err 103 case searchattribute.ExecutionStatus: 104 values, err := vi.nextInterceptor.Values(name, values...) 105 if err == nil { 106 statusStr := values[0].(string) 107 e, err := enums.WorkflowExecutionStatusFromString(statusStr) 108 if err != nil { 109 return nil, query.NewConverterError("invalid ExecutionStatus %q", statusStr) 110 } 111 vi.filter.Status = int32(e) 112 } 113 return values, err 114 case searchattribute.StartTime: 115 if len(values) != 2 { 116 return nil, query.NewConverterError("StartTime only supports BETWEEN ... AND ... filter") 117 } 118 119 values, err := vi.nextInterceptor.Values(name, values...) 120 if err == nil { 121 minTime, err := time.Parse(time.RFC3339Nano, values[0].(string)) 122 if err != nil { 123 return nil, query.NewConverterError("invalid StartTime format: %v", minTime) 124 } 125 vi.filter.MinTime = &minTime 126 127 maxTime, err := time.Parse(time.RFC3339Nano, values[1].(string)) 128 if err != nil { 129 return nil, query.NewConverterError("invalid StartTime format: %v", maxTime) 130 } 131 vi.filter.MaxTime = &maxTime 132 } 133 return values, err 134 default: 135 return nil, query.NewConverterError("filter by '%v' not supported for standard visibility", name) 136 } 137 }