github.com/Axway/agent-sdk@v1.1.101/samples/watchclient/pkg/client/client.go (about) 1 package client 2 3 import ( 4 "crypto/tls" 5 "fmt" 6 "time" 7 8 "github.com/Axway/agent-sdk/pkg/apic/auth" 9 "github.com/Axway/agent-sdk/pkg/cache" 10 corecfg "github.com/Axway/agent-sdk/pkg/config" 11 "github.com/Axway/agent-sdk/pkg/harvester" 12 "github.com/Axway/agent-sdk/pkg/util" 13 14 "github.com/sirupsen/logrus" 15 16 wm "github.com/Axway/agent-sdk/pkg/watchmanager" 17 "github.com/Axway/agent-sdk/pkg/watchmanager/proto" 18 ) 19 20 // WatchClient - stream client for connecting to the Watch Controller 21 type WatchClient struct { 22 config *Config 23 logger logrus.FieldLogger 24 wm wm.Manager 25 } 26 27 type sequenceManager struct { 28 seqCache cache.Cache 29 } 30 31 func (s *sequenceManager) GetSequence() int64 { 32 cachedSeqID, err := s.seqCache.Get("watchSequenceID") 33 if err == nil { 34 if seqID, ok := cachedSeqID.(int64); ok { 35 return seqID 36 } else if seqID, ok := cachedSeqID.(float64); ok { 37 return int64(seqID) 38 } 39 } 40 return 0 41 } 42 43 func (s *sequenceManager) SetSequence(sequenceID int64) { 44 s.seqCache.Set("watchSequenceID", sequenceID) 45 s.seqCache.Save("sample.sequence") 46 } 47 48 // Todo - To be updated after cache persistence story 49 func getSequenceManager() *sequenceManager { 50 seqCache := cache.New() 51 err := seqCache.Load("sample.sequence") 52 if err != nil { 53 seqCache.Set("watchSequenceID", int64(1)) 54 seqCache.Save("sample.sequence") 55 } 56 57 return &sequenceManager{seqCache: seqCache} 58 } 59 60 func defaultTLSConfig() *tls.Config { 61 return &tls.Config{ 62 MinVersion: tls.VersionTLS12, 63 CipherSuites: []uint16{ 64 tls.TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384, 65 tls.TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384, 66 tls.TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305, 67 tls.TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305, 68 tls.TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256, 69 tls.TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256, 70 tls.TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256, 71 tls.TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256, 72 }, 73 } 74 } 75 76 // NewWatchClient creates a WatchClient 77 func NewWatchClient(config *Config, logger logrus.FieldLogger) (*WatchClient, error) { 78 entry := logger.WithField("package", "client") 79 80 var watchOptions []wm.Option 81 watchOptions = []wm.Option{ 82 wm.WithLogger(entry), 83 } 84 85 if config.Insecure { 86 watchOptions = append(watchOptions, wm.WithTLSConfig(nil)) 87 } else { 88 watchOptions = append(watchOptions, wm.WithTLSConfig(defaultTLSConfig())) 89 } 90 91 harvesterHost := config.HarvesterHost 92 harvesterPort := config.HarvesterPort 93 harvesterProtocol := config.HarvesterProtocol 94 if harvesterProtocol == "" { 95 harvesterProtocol = "https" 96 } 97 98 if harvesterHost == "" { 99 harvesterHost = config.Host 100 harvesterPort = config.Port 101 } 102 103 harvesterUrl := fmt.Sprintf("%s://%s:%d", harvesterProtocol, harvesterHost, harvesterPort) 104 ccfg := &corecfg.CentralConfiguration{ 105 URL: harvesterUrl, 106 ClientTimeout: 30 * time.Second, 107 ProxyURL: "", 108 TenantID: config.TenantID, 109 TLS: corecfg.NewTLSConfig(), 110 GRPCCfg: corecfg.GRPCConfig{ 111 Enabled: true, 112 Insecure: config.Insecure, 113 Host: config.Host, 114 Port: int(config.Port), 115 }, 116 Auth: &corecfg.AuthConfiguration{ 117 URL: config.Auth.URL, 118 PrivateKey: config.Auth.PrivateKey, 119 PublicKey: config.Auth.PublicKey, 120 KeyPwd: config.Auth.KeyPassword, 121 Realm: "Broker", 122 ClientID: config.Auth.ClientID, 123 Timeout: config.Auth.Timeout, 124 }, 125 } 126 sm := getSequenceManager() 127 ta := auth.NewPlatformTokenGetterWithCentralConfig(ccfg) 128 if config.UseHarvester { 129 hCfg := harvester.NewConfig(ccfg, ta, sm) 130 hClient := harvester.NewClient(hCfg) 131 seqID, err := hClient.ReceiveSyncEvents(config.TopicSelfLink, 0, nil) 132 if err != nil { 133 return nil, err 134 } 135 sm.SetSequence(seqID) 136 watchOptions = append(watchOptions, wm.WithHarvester(hClient, sm)) 137 } 138 139 cfg := &wm.Config{ 140 Host: ccfg.GRPCCfg.Host, 141 Port: uint32(ccfg.GRPCCfg.Port), 142 TenantID: config.TenantID, 143 TokenGetter: ta.GetToken, 144 UserAgent: util.FormatUserAgent("SampleClient", "0.0.1-sha1", "0.0.1", "testenvironment", "testagent", false, true), 145 } 146 147 w, err := wm.New(cfg, watchOptions...) 148 if err != nil { 149 return nil, err 150 } 151 152 return &WatchClient{ 153 config: config, 154 logger: entry, 155 wm: w, 156 }, nil 157 } 158 159 // Watch starts a two-way stream with the Watch Controller 160 func (w WatchClient) Watch() { 161 log := w.logger 162 log.Info("starting to watch events") 163 164 eventChannel, errCh := make(chan *proto.Event), make(chan error) 165 subscriptionID, err := w.wm.RegisterWatch(w.config.TopicSelfLink, eventChannel, errCh) 166 if err != nil { 167 log.Error(err) 168 return 169 } 170 171 log = log.WithField("subscription-id", subscriptionID) 172 log.Infof("watch registered successfully") 173 174 for { 175 select { 176 case err = <-errCh: 177 log.Error(err) 178 w.wm.CloseWatch(subscriptionID) 179 return 180 case event := <-eventChannel: 181 log. 182 WithField("type", event.Type). 183 WithField("group", event.Payload.Group). 184 WithField("kind", event.Payload.Kind). 185 WithField("scopeKind", event.Payload.Metadata.Scope.Kind). 186 WithField("scopeName", event.Payload.Metadata.Scope.Name). 187 WithField("id", event.Payload.Metadata.Id). 188 WithField("name", event.Payload.Name). 189 Info("event received") 190 } 191 } 192 }