github.com/thiagoyeds/go-cloud@v0.26.0/runtimevar/example_test.go (about) 1 // Copyright 2018 The Go Cloud Development Kit Authors 2 // 3 // Licensed under the Apache License, Version 2.0 (the "License"); 4 // you may not use this file except in compliance with the License. 5 // You may obtain a copy of the License at 6 // 7 // https://www.apache.org/licenses/LICENSE-2.0 8 // 9 // Unless required by applicable law or agreed to in writing, software 10 // distributed under the License is distributed on an "AS IS" BASIS, 11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 // See the License for the specific language governing permissions and 13 // limitations under the License. 14 15 package runtimevar_test 16 17 import ( 18 "context" 19 "fmt" 20 "log" 21 22 "gocloud.dev/runtimevar" 23 "gocloud.dev/runtimevar/constantvar" 24 "gocloud.dev/secrets" 25 26 _ "gocloud.dev/runtimevar/gcpruntimeconfig" 27 runtimeconfig "google.golang.org/genproto/googleapis/cloud/runtimeconfig/v1beta1" 28 "google.golang.org/grpc/status" 29 ) 30 31 func Example_jsonDecoder() { 32 // PRAGMA: This example is used on gocloud.dev; PRAGMA comments adjust how it is shown and can be ignored. 33 // PRAGMA: On gocloud.dev, hide lines until the next blank line. 34 ctx := context.Background() 35 36 // Config is the sample config struct we're going to parse our JSON into. 37 type Config struct { 38 Host string 39 Port int 40 } 41 42 // A sample JSON config that will decode into Config. 43 const jsonConfig = `{"Host": "gocloud.dev", "Port": 8080}` 44 45 // Construct a Decoder that decodes raw bytes into our config. 46 decoder := runtimevar.NewDecoder(Config{}, runtimevar.JSONDecode) 47 48 // Next, a construct a *Variable using a constructor or URL opener. 49 // This example uses constantvar. 50 // If you're using a URL opener, you can't decode JSON into a struct, but 51 // you can use the query parameter "decoder=jsonmap" to decode into a map. 52 v := constantvar.NewBytes([]byte(jsonConfig), decoder) 53 defer v.Close() 54 // snapshot.Value will be of type Config. 55 56 // PRAGMA: On gocloud.dev, hide the rest of the function. 57 snapshot, err := v.Latest(ctx) 58 if err != nil { 59 log.Fatalf("Error in retrieving variable: %v", err) 60 } 61 fmt.Printf("Config: %+v\n", snapshot.Value.(Config)) 62 63 // Output: 64 // Config: {Host:gocloud.dev Port:8080} 65 } 66 67 func Example_stringDecoder() { 68 // Construct a *Variable using a constructor from one of the 69 // runtimevar subpackages. This example uses constantvar. 70 // The variable value is of type string, so we use StringDecoder. 71 v := constantvar.NewBytes([]byte("hello world"), runtimevar.StringDecoder) 72 defer v.Close() 73 74 // Call Latest to retrieve the value. 75 snapshot, err := v.Latest(context.Background()) 76 if err != nil { 77 log.Fatalf("Error in retrieving variable: %v", err) 78 } 79 // snapshot.Value will be of type string. 80 fmt.Printf("%q\n", snapshot.Value.(string)) 81 82 // Output: 83 // "hello world" 84 } 85 86 func ExampleVariable_Latest() { 87 // PRAGMA: This example is used on gocloud.dev; PRAGMA comments adjust how it is shown and can be ignored. 88 // PRAGMA: On gocloud.dev, hide lines until the next blank line. 89 var v *runtimevar.Variable 90 91 snapshot, err := v.Latest(context.Background()) 92 if err != nil { 93 log.Fatalf("Error in retrieving variable: %v", err) 94 } 95 // PRAGMA: On gocloud.dev, hide the rest of the function. 96 _ = snapshot 97 } 98 99 func ExampleSnapshot_As() { 100 // This example is specific to the gcpruntimeconfig implementation; it 101 // demonstrates access to the underlying 102 // google.golang.org/genproto/googleapis/cloud/runtimeconfig.Variable type. 103 // The types exposed for As by gcpruntimeconfig are documented in 104 // https://godoc.org/gocloud.dev/runtimevar/gcpruntimeconfig#hdr-As 105 ctx := context.Background() 106 107 const url = "gcpruntimeconfig://proj/config/key" 108 v, err := runtimevar.OpenVariable(ctx, url) 109 if err != nil { 110 log.Fatal(err) 111 } 112 113 s, err := v.Latest(ctx) 114 if err != nil { 115 log.Fatal(err) 116 } 117 118 var rcv *runtimeconfig.Variable 119 if s.As(&rcv) { 120 fmt.Println(rcv.UpdateTime) 121 } 122 } 123 124 func ExampleVariable_ErrorAs() { 125 // This example is specific to the gcpruntimeconfig implementation; it 126 // demonstrates access to the underlying google.golang.org/grpc/status.Status 127 // type. 128 // The types exposed for As by gcpruntimeconfig are documented in 129 // https://godoc.org/gocloud.dev/runtimevar/gcpruntimeconfig#hdr-As 130 ctx := context.Background() 131 132 const url = "gcpruntimeconfig://proj/wrongconfig/key" 133 v, err := runtimevar.OpenVariable(ctx, url) 134 if err != nil { 135 log.Fatal(err) 136 } 137 138 _, err = v.Watch(ctx) 139 if err != nil { 140 var s *status.Status 141 if v.ErrorAs(err, &s) { 142 fmt.Println(s.Code()) 143 } 144 } 145 } 146 147 func ExampleVariable_Watch() { 148 // Construct a *Variable using a constructor from one of the 149 // runtimevar subpackages. This example uses constantvar. 150 // The variable value is of type string, so we use StringDecoder. 151 v := constantvar.NewBytes([]byte("hello world"), runtimevar.StringDecoder) 152 defer v.Close() 153 154 // Call Watch in a loop from a background goroutine to see all changes, 155 // including errors. 156 // 157 // You can use this for logging, or to trigger behaviors when the 158 // config changes. 159 // 160 // Note that Latest always returns the latest "good" config, so seeing 161 // an error from Watch doesn't mean that Latest will return one. 162 go func() { 163 for { 164 snapshot, err := v.Watch(context.Background()) 165 if err == runtimevar.ErrClosed { 166 // v has been closed; exit. 167 return 168 } 169 if err == nil { 170 // Casting to a string here because we used StringDecoder. 171 log.Printf("New config: %v", snapshot.Value.(string)) 172 } else { 173 log.Printf("Error loading config: %v", err) 174 // Even though there's been an error loading the config, 175 // v.Latest will continue to return the latest "good" value. 176 } 177 } 178 }() 179 } 180 181 func ExampleDecryptDecode() { 182 // PRAGMA: This example is used on gocloud.dev; PRAGMA comments adjust how it is shown and can be ignored. 183 // PRAGMA: On gocloud.dev, hide lines until the next blank line. 184 var keeper *secrets.Keeper 185 186 decodeFunc := runtimevar.DecryptDecode(keeper, runtimevar.StringDecode) 187 decoder := runtimevar.NewDecoder("", decodeFunc) 188 189 // PRAGMA: On gocloud.dev, hide the rest of the function. 190 _ = decoder 191 }