diff --git a/qkdnManager-simulator/client/httpClient.go b/qkdnManager-simulator/client/httpControllerClient.go similarity index 65% rename from qkdnManager-simulator/client/httpClient.go rename to qkdnManager-simulator/client/httpControllerClient.go index fdc7724050f6d1d7107e75bc932b14cca7777a7f..b8096c0a314c54efae069649367602ea81c1c9b0 100644 --- a/qkdnManager-simulator/client/httpClient.go +++ b/qkdnManager-simulator/client/httpControllerClient.go @@ -1,12 +1,10 @@ package managerClient import ( - "fmt" "io" "math/rand/v2" "net/http" "net/url" - "strings" "time" "code.fbi.h-da.de/danet/quant/qkdnManager-simulator/config" @@ -17,7 +15,7 @@ import ( const securityAlert = "securityAlert" const linkQuality = "linkQuality" -func SetupHTTPClients(conf *config.Config) { +func SetupControllerHTTPClients(conf *config.ControllerClients) { httpCli := &http.Client{ Timeout: time.Duration(5) * time.Second, } @@ -25,8 +23,8 @@ func SetupHTTPClients(conf *config.Config) { go func() { for { var randNumber int - if conf.ManagerClients.RandDuration > 0 { - randNumber = conf.ManagerClients.RandDuration + if conf.RandDuration > 0 { + randNumber = conf.RandDuration } else { randNumber = 1 } @@ -40,7 +38,7 @@ func SetupHTTPClients(conf *config.Config) { }() } -func doUrlEncodedSecurityAlert(httpCli *http.Client, conf *config.Config) { +func doUrlEncodedSecurityAlert(httpCli *http.Client, conf *config.ControllerClients) { status := getStatusSlice()[rand.IntN(len(getStatusSlice()))] formBody := url.Values{ @@ -49,7 +47,7 @@ func doUrlEncodedSecurityAlert(httpCli *http.Client, conf *config.Config) { "KMS_ID": []string{"ID HERE"}, // TODO: think of way to add real IDs here } - req, err := buildUrlEncodedRequest(conf.QkdnAppAddress, conf.ManagerClients.ClientTargets[securityAlert], formBody) + req, err := buildUrlEncodedRequest(conf.QkdnAppAddress, conf.ClientTargets[securityAlert], formBody) if err != nil { logrus.Error(err) return @@ -64,7 +62,7 @@ func doUrlEncodedSecurityAlert(httpCli *http.Client, conf *config.Config) { } } -func doUrlEncodedLinkQuality(httpCli *http.Client, conf *config.Config) { +func doUrlEncodedLinkQuality(httpCli *http.Client, conf *config.ControllerClients) { quality := getQualityString()[rand.IntN(len(getQualityString()))] formBody := url.Values{ @@ -74,7 +72,7 @@ func doUrlEncodedLinkQuality(httpCli *http.Client, conf *config.Config) { "quality": []string{quality}, } - req, err := buildUrlEncodedRequest(conf.QkdnAppAddress, conf.ManagerClients.ClientTargets[linkQuality], formBody) + req, err := buildUrlEncodedRequest(conf.QkdnAppAddress, conf.ClientTargets[linkQuality], formBody) if err != nil { logrus.Error(err) return @@ -89,28 +87,6 @@ func doUrlEncodedLinkQuality(httpCli *http.Client, conf *config.Config) { } } -func buildUrlEncodedRequest(qkdnAppAddress, clientTarget string, formBody url.Values) (*http.Request, error) { - address := formatTargetAddress(qkdnAppAddress, clientTarget) - dataReader := formBody.Encode() - - req, err := http.NewRequest( - http.MethodPost, - address, - strings.NewReader(dataReader), - ) - if err != nil { - return nil, err - } - - // set the content-type header - req.Header.Add("Content-Type", "application/x-www-form-urlencoded") - return req, nil -} - -func formatTargetAddress(address, resource string) string { - return fmt.Sprintf("http://%s%s%s", address, config.APIPrefix, resource) -} - func getStatusSlice() []string { return []string{"issue", "resolved"} } diff --git a/qkdnManager-simulator/client/httpKmsClient.go b/qkdnManager-simulator/client/httpKmsClient.go new file mode 100644 index 0000000000000000000000000000000000000000..0818b89a9bcdc673c92b16757950dc18859b96a6 --- /dev/null +++ b/qkdnManager-simulator/client/httpKmsClient.go @@ -0,0 +1,133 @@ +package managerClient + +import ( + "encoding/json" + "net/http" + "time" + + "code.fbi.h-da.de/danet/quant/qkdnManager-simulator/config" + "github.com/google/uuid" + "github.com/sirupsen/logrus" +) + +const operationalState = "operationalState" +const qkdInterface = "qkdInterface" +const interCKMSInterface = "interCKMSInterface" +const akmsInterface = "akmsInterface" + +type KmsRequestBody struct { + KMS_ID uuid.UUID `json:"KMS_ID"` + Peers []Peer `json:"peers,omitempty"` + Running bool `json:"running,omitempty"` +} + +type Peer struct { + Peer_ID uuid.UUID `json:"peer_ID"` + Running bool `json:"running"` +} + +func SetupKmsHTTPClients(conf *config.KMSClients) { + httpCli := &http.Client{ + Timeout: time.Duration(5) * time.Second, + } + + go func() { + for { + time.Sleep(time.Second * 10) + + for _, kmsAddress := range conf.KmsAddresses { + doOperationalStateRequest(httpCli, kmsAddress, conf.Endpoints[operationalState]) + doQkdInterfaceRequest(httpCli, kmsAddress, conf.Endpoints[qkdInterface]) + doInterCkmsInterfaceRequest(httpCli, kmsAddress, conf.Endpoints[interCKMSInterface]) + doAkmsInterfaceRequest(httpCli, kmsAddress, conf.Endpoints[akmsInterface]) + } + } + }() +} + +func doOperationalStateRequest(httpCli *http.Client, kmsAddress, resourcePath string) { + resourceRequest := formatTargetAddress(kmsAddress, resourcePath) + + resp, err := httpCli.Get(resourceRequest) + if err != nil { + logrus.Errorf("Error requesting operational state: %v", err) + return + } + + defer checkCloseResponseBodyError(resp.Body) + + var data KmsRequestBody + err = json.NewDecoder(resp.Body).Decode(&data) + if err != nil { + logrus.Error(err) + return + } + + logrus.Infof("Operational state for ID: %s, running: %t", data.KMS_ID, data.Running) +} + +func doQkdInterfaceRequest(httpCli *http.Client, kmsAddress, resourcePath string) { + resourceRequest := formatTargetAddress(kmsAddress, resourcePath) + + resp, err := httpCli.Get(resourceRequest) + if err != nil { + logrus.Errorf("Error requesting qkd interface: %v", err) + return + } + + defer checkCloseResponseBodyError(resp.Body) + + var data KmsRequestBody + err = json.NewDecoder(resp.Body).Decode(&data) + if err != nil { + logrus.Error(err) + return + } + + logrus.Infof("Qkd interface for ID: %s, running: %t", data.KMS_ID, data.Running) +} + +func doInterCkmsInterfaceRequest(httpCli *http.Client, kmsAddress, resourcePath string) { + resourceRequest := formatTargetAddress(kmsAddress, resourcePath) + + resp, err := httpCli.Get(resourceRequest) + if err != nil { + logrus.Errorf("Error requesting operational state: %v", err) + return + } + + defer checkCloseResponseBodyError(resp.Body) + + var data KmsRequestBody + err = json.NewDecoder(resp.Body).Decode(&data) + if err != nil { + logrus.Error(err) + return + } + + logrus.Infof("Inter CKMS interfaces for ID: %s", data.KMS_ID) + for _, peer := range data.Peers { + logrus.Infof("peerID:%s, running: %t", peer.Peer_ID, peer.Running) + } +} + +func doAkmsInterfaceRequest(httpCli *http.Client, kmsAddress, resourcePath string) { + resourceRequest := formatTargetAddress(kmsAddress, resourcePath) + + resp, err := httpCli.Get(resourceRequest) + if err != nil { + logrus.Errorf("Error requesting operational state: %v", err) + return + } + + defer checkCloseResponseBodyError(resp.Body) + + var data KmsRequestBody + err = json.NewDecoder(resp.Body).Decode(&data) + if err != nil { + logrus.Error(err) + return + } + + logrus.Infof("Akms interface for ID: %s, running: %t", data.KMS_ID, data.Running) +} diff --git a/qkdnManager-simulator/client/util.go b/qkdnManager-simulator/client/util.go new file mode 100644 index 0000000000000000000000000000000000000000..02fc3aa0407e5f8a98706b9f568cc793fcc3e0d1 --- /dev/null +++ b/qkdnManager-simulator/client/util.go @@ -0,0 +1,40 @@ +package managerClient + +import ( + "fmt" + "io" + "net/http" + "net/url" + "strings" + + "code.fbi.h-da.de/danet/quant/qkdnManager-simulator/config" + "github.com/sirupsen/logrus" +) + +func buildUrlEncodedRequest(qkdnAppAddress, clientTarget string, formBody url.Values) (*http.Request, error) { + address := formatTargetAddress(qkdnAppAddress, clientTarget) + dataReader := formBody.Encode() + + req, err := http.NewRequest( + http.MethodPost, + address, + strings.NewReader(dataReader), + ) + if err != nil { + return nil, err + } + + // set the content-type header + req.Header.Add("Content-Type", "application/x-www-form-urlencoded") + return req, nil +} + +func formatTargetAddress(address, resource string) string { + return fmt.Sprintf("http://%s%s%s", address, config.APIPrefix, resource) +} + +func checkCloseResponseBodyError(body io.ReadCloser) { + if err := body.Close(); err != nil { + logrus.Error(err) + } +} diff --git a/qkdnManager-simulator/config/config.go b/qkdnManager-simulator/config/config.go index c28734598aacc51b448d4ca785f560b8440b9907..d3a1118f027fdb1f2441f0fffe9ce075505c3294 100644 --- a/qkdnManager-simulator/config/config.go +++ b/qkdnManager-simulator/config/config.go @@ -3,18 +3,18 @@ package config const APIPrefix = "/api/v1" type Config struct { - QkdnAppAddress string `yaml:"QkdnAppAddress"` - ManagerClients ManagerClients `yaml:"ManagerClients"` - ManagerServer ManagerServer `yaml:"ManagerServer"` + ControllerClients ControllerClients `yaml:"ControllerClients"` + KMSClients KMSClients `yaml:"KMSClients"` } -type ManagerClients struct { - TestMode bool `yaml:"TestMode"` - RandDuration int `yaml:"RandDuration"` - ClientTargets map[string]string `yaml:"ClientTargets,omitempty"` +type ControllerClients struct { + QkdnAppAddress string `yaml:"QkdnAppAddress"` + TestMode bool `yaml:"TestMode"` + RandDuration int `yaml:"RandDuration"` + ClientTargets map[string]string `yaml:"ClientTargets,omitempty"` } -type ManagerServer struct { - Address string `yaml:"Address"` - Endpoints map[string]string `yaml:"Endpoints,omitempty"` +type KMSClients struct { + KmsAddresses []string `yaml:"KmsAddresses"` + Endpoints map[string]string `yaml:"Endpoints,omitempty"` } diff --git a/qkdnManager-simulator/config/example/qkdnManagerConfig.yaml.example b/qkdnManager-simulator/config/example/qkdnManagerConfig.yaml.example index 5a39c708f417819d90b9789cb2a10729ffc3e11a..e102335769514cf2d82bf1666f954d818d118b85 100644 --- a/qkdnManager-simulator/config/example/qkdnManagerConfig.yaml.example +++ b/qkdnManager-simulator/config/example/qkdnManagerConfig.yaml.example @@ -1,12 +1,16 @@ -QkdnAppAddress: "172.100.20.99:55555" -ManagerClients: +ControllerClients: + QkdnAppAddress: "172.100.20.99:55555" TestMode: true # Set this as true, to have the simulator randomly send alerts to the QKDN-App RandDuration: 10 # Set this duration, to define in which interval the Manager simulation sends random events to the QKDN-App ClientTargets: securityAlert: /security/alert linkQuality: /link/quality -ManagerServer: - Address: ":8090" +KMSClients: + KmsAddresses: [ + "172.100.20.10:8090", + "172.100.20.11:8090", + "172.100.20.12:8090", + "172.100.20.13:8090"] Endpoints: operationalState: /operationalState qkdInterface: /qkdInterface diff --git a/qkdnManager-simulator/main.go b/qkdnManager-simulator/main.go index 1d91eeb8c858d10cacd2eb6a0063f4124f0c869d..63e6677195ad634477fb01a297d61950ebcb68dc 100644 --- a/qkdnManager-simulator/main.go +++ b/qkdnManager-simulator/main.go @@ -1,7 +1,6 @@ package main import ( - "context" "flag" "os" "os/signal" @@ -9,7 +8,6 @@ import ( managerClient "code.fbi.h-da.de/danet/quant/qkdnManager-simulator/client" "code.fbi.h-da.de/danet/quant/qkdnManager-simulator/config" - managerServer "code.fbi.h-da.de/danet/quant/qkdnManager-simulator/server" "github.com/sirupsen/logrus" "gopkg.in/yaml.v3" ) @@ -42,30 +40,16 @@ func main() { logrus.Infof("Config: %v", *config) - // start server with all the required handlers - srv := managerServer.SetupHTTPServer(config.ManagerServer) - - ctx, cancel := context.WithCancel(context.Background()) stopChannel := make(chan os.Signal, 1) signal.Notify(stopChannel, syscall.SIGINT) - defer func() { - logrus.Info("Shutting down server...") - if err := srv.Shutdown(ctx); err != nil { - logrus.Errorf("Error shutting down server: %v", err) - _ = srv.Close() - return - } - logrus.Info("Gracefully shutdown server completed.") - }() - // start random requester towards app based on mode - if config.ManagerClients.TestMode { + if config.ControllerClients.TestMode { logrus.Info("Setting up HTTP clients... ") - managerClient.SetupHTTPClients(config) + managerClient.SetupControllerHTTPClients(&config.ControllerClients) } - <-stopChannel + managerClient.SetupKmsHTTPClients(&config.KMSClients) - cancel() + <-stopChannel }