github.com/Jeffail/benthos/v3@v3.65.0/public/bloblang/example_plugins_v2_test.go (about) 1 package bloblang_test 2 3 import ( 4 "encoding/json" 5 "fmt" 6 "math/rand" 7 8 "github.com/Jeffail/benthos/v3/public/bloblang" 9 ) 10 11 // This example demonstrates how to create Bloblang methods and functions and 12 // execute them with a Bloblang mapping using the new V2 methods, which adds 13 // support to our functions and methods for optional named parameters. 14 func Example_bloblangFunctionPluginV2() { 15 multiplyWrongSpec := bloblang.NewPluginSpec(). 16 Description("Multiplies two numbers together but gets it slightly wrong. Whoops."). 17 Param(bloblang.NewFloat64Param("left").Description("The first of two numbers to multiply.")). 18 Param(bloblang.NewFloat64Param("right").Description("The second of two numbers to multiply.")) 19 20 if err := bloblang.RegisterFunctionV2( 21 "multiply_but_always_slightly_wrong", multiplyWrongSpec, 22 func(args *bloblang.ParsedParams) (bloblang.Function, error) { 23 left, err := args.GetFloat64("left") 24 if err != nil { 25 return nil, err 26 } 27 28 right, err := args.GetFloat64("right") 29 if err != nil { 30 return nil, err 31 } 32 33 return func() (interface{}, error) { 34 return left*right + 0.02, nil 35 }, nil 36 }); err != nil { 37 panic(err) 38 } 39 40 // Our function now optionally supports named parameters, when a function is 41 // instantiated with unamed parameters they must follow the order in which 42 // the parameters are registered. 43 mapping := ` 44 root.num_ab = multiply_but_always_slightly_wrong(left: this.a, right: this.b) 45 root.num_cd = multiply_but_always_slightly_wrong(this.c, this.d) 46 ` 47 48 exe, err := bloblang.Parse(mapping) 49 if err != nil { 50 panic(err) 51 } 52 53 res, err := exe.Query(map[string]interface{}{ 54 "a": 1.2, "b": 2.6, "c": 5.3, "d": 8.2, 55 }) 56 if err != nil { 57 panic(err) 58 } 59 60 jsonBytes, err := json.Marshal(res) 61 if err != nil { 62 panic(err) 63 } 64 65 fmt.Println(string(jsonBytes)) 66 // Output: {"num_ab":3.14,"num_cd":43.48} 67 } 68 69 // This example demonstrates how to create Bloblang methods and functions and 70 // execute them with a Bloblang mapping using the new V2 methods, which adds 71 // support to our functions and methods for optional named parameters. 72 func Example_bloblangMethodPluginV2() { 73 hugStringSpec := bloblang.NewPluginSpec(). 74 Description("Wraps a string with a prefix and suffix."). 75 Param(bloblang.NewStringParam("prefix").Description("The prefix to insert.")). 76 Param(bloblang.NewStringParam("suffix").Description("The suffix to append.")) 77 78 if err := bloblang.RegisterMethodV2("hug_string", hugStringSpec, func(args *bloblang.ParsedParams) (bloblang.Method, error) { 79 prefix, err := args.GetString("prefix") 80 if err != nil { 81 return nil, err 82 } 83 84 suffix, err := args.GetString("suffix") 85 if err != nil { 86 return nil, err 87 } 88 89 return bloblang.StringMethod(func(s string) (interface{}, error) { 90 return prefix + s + suffix, nil 91 }), nil 92 }); err != nil { 93 panic(err) 94 } 95 96 reverseSpec := bloblang.NewPluginSpec(). 97 Description("Reverses the order of an array target, but sometimes it randomly doesn't. Whoops.") 98 99 if err := bloblang.RegisterMethodV2("sometimes_reverse", reverseSpec, func(*bloblang.ParsedParams) (bloblang.Method, error) { 100 rand := rand.New(rand.NewSource(0)) 101 return bloblang.ArrayMethod(func(in []interface{}) (interface{}, error) { 102 if rand.Int()%3 == 0 { 103 // Whoopsie 104 return in, nil 105 } 106 out := make([]interface{}, len(in)) 107 copy(out, in) 108 for i, j := 0, len(out)-1; i < j; i, j = i+1, j-1 { 109 out[i], out[j] = out[j], out[i] 110 } 111 return out, nil 112 }), nil 113 }); err != nil { 114 panic(err) 115 } 116 117 // Our methods now optionally support named parameters, when a method is 118 // instantiated with unamed parameters they must follow the order in which 119 // the parameters are registered. 120 mapping := ` 121 root.new_summary = this.summary.hug_string(prefix: "meow", suffix: "woof") 122 root.reversed = this.names.sometimes_reverse() 123 ` 124 125 exe, err := bloblang.Parse(mapping) 126 if err != nil { 127 panic(err) 128 } 129 130 res, err := exe.Query(map[string]interface{}{ 131 "summary": "quack", 132 "names": []interface{}{"denny", "pixie", "olaf", "jen", "spuz"}, 133 }) 134 if err != nil { 135 panic(err) 136 } 137 138 jsonBytes, err := json.Marshal(res) 139 if err != nil { 140 panic(err) 141 } 142 143 fmt.Println(string(jsonBytes)) 144 // Output: {"new_summary":"meowquackwoof","reversed":["spuz","jen","olaf","pixie","denny"]} 145 }