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  }