github.com/moby/docker@v26.1.3+incompatible/libnetwork/cmd/networkdb-test/dummyclient/dummyClient.go (about)

     1  package dummyclient
     2  
     3  import (
     4  	"context"
     5  	"fmt"
     6  	"net/http"
     7  
     8  	"github.com/containerd/log"
     9  	"github.com/docker/docker/libnetwork/diagnostic"
    10  	"github.com/docker/docker/libnetwork/networkdb"
    11  	events "github.com/docker/go-events"
    12  )
    13  
    14  type Mux interface {
    15  	HandleFunc(pattern string, handler func(http.ResponseWriter, *http.Request))
    16  }
    17  
    18  func RegisterDiagnosticHandlers(mux Mux, nDB *networkdb.NetworkDB) {
    19  	mux.HandleFunc("/watchtable", watchTable(nDB))
    20  	mux.HandleFunc("/watchedtableentries", watchTableEntries)
    21  }
    22  
    23  const (
    24  	missingParameter = "missing parameter"
    25  )
    26  
    27  type tableHandler struct {
    28  	cancelWatch func()
    29  	entries     map[string]string
    30  }
    31  
    32  var clientWatchTable = map[string]tableHandler{}
    33  
    34  func watchTable(nDB *networkdb.NetworkDB) func(w http.ResponseWriter, r *http.Request) {
    35  	return func(w http.ResponseWriter, r *http.Request) {
    36  		r.ParseForm() //nolint:errcheck
    37  		diagnostic.DebugHTTPForm(r)
    38  		if len(r.Form["tname"]) < 1 {
    39  			rsp := diagnostic.WrongCommand(missingParameter, fmt.Sprintf("%s?tname=table_name", r.URL.Path))
    40  			diagnostic.HTTPReply(w, rsp, &diagnostic.JSONOutput{}) //nolint:errcheck
    41  			return
    42  		}
    43  
    44  		tableName := r.Form["tname"][0]
    45  		if _, ok := clientWatchTable[tableName]; ok {
    46  			fmt.Fprintf(w, "OK\n")
    47  			return
    48  		}
    49  
    50  		ch, cancel := nDB.Watch(tableName, "")
    51  		clientWatchTable[tableName] = tableHandler{cancelWatch: cancel, entries: make(map[string]string)}
    52  		go handleTableEvents(tableName, ch)
    53  
    54  		fmt.Fprintf(w, "OK\n")
    55  	}
    56  }
    57  
    58  func watchTableEntries(w http.ResponseWriter, r *http.Request) {
    59  	r.ParseForm() //nolint:errcheck
    60  	diagnostic.DebugHTTPForm(r)
    61  	if len(r.Form["tname"]) < 1 {
    62  		rsp := diagnostic.WrongCommand(missingParameter, fmt.Sprintf("%s?tname=table_name", r.URL.Path))
    63  		diagnostic.HTTPReply(w, rsp, &diagnostic.JSONOutput{}) //nolint:errcheck
    64  		return
    65  	}
    66  
    67  	tableName := r.Form["tname"][0]
    68  	table, ok := clientWatchTable[tableName]
    69  	if !ok {
    70  		fmt.Fprintf(w, "Table %s not watched\n", tableName)
    71  		return
    72  	}
    73  
    74  	fmt.Fprintf(w, "total elements: %d\n", len(table.entries))
    75  	i := 0
    76  	for k, v := range table.entries {
    77  		fmt.Fprintf(w, "%d) k:`%s` -> v:`%s`\n", i, k, v)
    78  		i++
    79  	}
    80  }
    81  
    82  func handleTableEvents(tableName string, ch *events.Channel) {
    83  	var (
    84  		// nid   string
    85  		eid   string
    86  		value []byte
    87  		isAdd bool
    88  	)
    89  
    90  	log.G(context.TODO()).Infof("Started watching table:%s", tableName)
    91  	for {
    92  		select {
    93  		case <-ch.Done():
    94  			log.G(context.TODO()).Infof("End watching %s", tableName)
    95  			return
    96  
    97  		case evt := <-ch.C:
    98  			log.G(context.TODO()).Infof("Recevied new event on:%s", tableName)
    99  			switch event := evt.(type) {
   100  			case networkdb.CreateEvent:
   101  				// nid = event.NetworkID
   102  				eid = event.Key
   103  				value = event.Value
   104  				isAdd = true
   105  			case networkdb.DeleteEvent:
   106  				// nid = event.NetworkID
   107  				eid = event.Key
   108  				value = event.Value
   109  				isAdd = false
   110  			default:
   111  				log.G(context.TODO()).Fatalf("Unexpected table event = %#v", event)
   112  			}
   113  			if isAdd {
   114  				// log.G(ctx).Infof("Add %s %s", tableName, eid)
   115  				clientWatchTable[tableName].entries[eid] = string(value)
   116  			} else {
   117  				// log.G(ctx).Infof("Del %s %s", tableName, eid)
   118  				delete(clientWatchTable[tableName].entries, eid)
   119  			}
   120  		}
   121  	}
   122  }