go.uber.org/cadence@v1.2.9/internal/encoded.go (about) 1 // Copyright (c) 2017 Uber Technologies, Inc. 2 // 3 // Permission is hereby granted, free of charge, to any person obtaining a copy 4 // of this software and associated documentation files (the "Software"), to deal 5 // in the Software without restriction, including without limitation the rights 6 // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 7 // copies of the Software, and to permit persons to whom the Software is 8 // furnished to do so, subject to the following conditions: 9 // 10 // The above copyright notice and this permission notice shall be included in 11 // all copies or substantial portions of the Software. 12 // 13 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 14 // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 15 // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 16 // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 17 // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 18 // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 19 // THE SOFTWARE. 20 21 package internal 22 23 import ( 24 "reflect" 25 26 "go.uber.org/cadence/internal/common" 27 "go.uber.org/cadence/internal/common/util" 28 ) 29 30 type ( 31 // Value is used to encapsulate/extract encoded value from workflow/activity. 32 Value interface { 33 // HasValue return whether there is value encoded. 34 HasValue() bool 35 // Get extract the encoded value into strong typed value pointer. 36 Get(valuePtr interface{}) error 37 } 38 39 // Values is used to encapsulate/extract encoded one or more values from workflow/activity. 40 Values interface { 41 // HasValues return whether there are values encoded. 42 HasValues() bool 43 // Get extract the encoded values into strong typed value pointers. 44 Get(valuePtr ...interface{}) error 45 } 46 47 // DataConverter is used by the framework to serialize/deserialize input and output of activity/workflow 48 // that need to be sent over the wire. 49 // To encode/decode workflow arguments, one should set DataConverter in two places: 50 // 1. Workflow worker, through worker.Options 51 // 2. Client, through client.Options 52 // To encode/decode Activity/ChildWorkflow arguments, one should set DataConverter in two places: 53 // 1. Inside workflow code, use workflow.WithDataConverter to create new Context, 54 // and pass that context to ExecuteActivity/ExecuteChildWorkflow calls. 55 // Cadence support using different DataConverters for different activity/childWorkflow in same workflow. 56 // 2. Activity/Workflow worker that run these activity/childWorkflow, through worker.Options. 57 DataConverter interface { 58 // ToData implements conversion of a list of values. 59 ToData(value ...interface{}) ([]byte, error) 60 // FromData implements conversion of an array of values of different types. 61 // Useful for deserializing arguments of function invocations. 62 FromData(input []byte, valuePtr ...interface{}) error 63 } 64 65 // defaultDataConverter uses thrift encoder/decoder when possible, for everything else use json. 66 defaultDataConverter struct{} 67 ) 68 69 var defaultJSONDataConverter = &defaultDataConverter{} 70 71 // DefaultDataConverter is default data converter used by Cadence worker 72 var DefaultDataConverter = getDefaultDataConverter() 73 74 // getDefaultDataConverter return default data converter used by Cadence worker 75 func getDefaultDataConverter() DataConverter { 76 return defaultJSONDataConverter 77 } 78 79 func (dc *defaultDataConverter) ToData(r ...interface{}) ([]byte, error) { 80 if len(r) == 1 && util.IsTypeByteSlice(reflect.TypeOf(r[0])) { 81 return r[0].([]byte), nil 82 } 83 84 var encoder encoding 85 if common.IsUseThriftEncoding(r) { 86 encoder = &thriftEncoding{} 87 } else { 88 encoder = &jsonEncoding{} 89 } 90 91 data, err := encoder.Marshal(r) 92 if err != nil { 93 return nil, err 94 } 95 return data, nil 96 } 97 98 func (dc *defaultDataConverter) FromData(data []byte, to ...interface{}) error { 99 if len(to) == 1 && util.IsTypeByteSlice(reflect.TypeOf(to[0])) { 100 reflect.ValueOf(to[0]).Elem().SetBytes(data) 101 return nil 102 } 103 104 var encoder encoding 105 if common.IsUseThriftDecoding(to) { 106 encoder = &thriftEncoding{} 107 } else { 108 encoder = &jsonEncoding{} 109 } 110 111 return encoder.Unmarshal(data, to) 112 }