From 43fb9afb176f3c138cbb389b7f1c3712a7f4dd3b Mon Sep 17 00:00:00 2001 From: Stephen Lawrence Date: Tue, 27 Feb 2024 17:59:04 +0000 Subject: [PATCH] Apache IoTDB: add runtime configuration file support for connector Currently the ServiceManager connector code that supports Apache IoTDB as a State Storage backend is configured at build-time. This commit extends the support to allow runtime configuration through a config file. The config file is named iotdb-config.json and placed in the vissv2server directory. The file is in JSON format to follow the pattern set by existing config files within the VISS server. The contents of the file are not validated and are assumed to be both complete and correct. Example file: { "host": "localhost", "port": "6667", "username": "root", "password": "root", "queryPrefixPath": "root.test2.dev1", "queryTimeout(ms)": 5000 } host, port, username and password are the client configuration to be used to create a session (connection) with the IoTDB Server. queryPrefixPath is the IoTDB database timeseries prefix to be used to access VSS nodes/keys in get/set operations. queryTimeout(ms) is the timeout to be used in milliseconds when querying the database. If no config file is found on server startup the default (build-time) configuration is used. Signed-off-by: Stephen Lawrence --- server/vissv2server/iotdb-config.json | 8 +++ server/vissv2server/serviceMgr/serviceMgr.go | 71 +++++++++++++++----- 2 files changed, 64 insertions(+), 15 deletions(-) create mode 100644 server/vissv2server/iotdb-config.json diff --git a/server/vissv2server/iotdb-config.json b/server/vissv2server/iotdb-config.json new file mode 100644 index 00000000..99edefb7 --- /dev/null +++ b/server/vissv2server/iotdb-config.json @@ -0,0 +1,8 @@ +{ + "host": "iotdb-service", + "port": "6667", + "username": "root", + "password": "root", + "queryPrefixPath": "root.test2.dev1", + "queryTimeout(ms)": 5000 +} diff --git a/server/vissv2server/serviceMgr/serviceMgr.go b/server/vissv2server/serviceMgr/serviceMgr.go index d1ed6377..07932480 100644 --- a/server/vissv2server/serviceMgr/serviceMgr.go +++ b/server/vissv2server/serviceMgr/serviceMgr.go @@ -79,16 +79,33 @@ var historySupport bool // Apache IoTDB var IoTDBsession client.Session -var IoTDbPrefixPath string = "root.test2.dev1" // DB prefix used for get/set -var IoTDbTimeout int64 = 3000 -var IoTDBconfig = &client.Config{ - // Host: "127.0.0.1", - Host: "iotdb-service", +var IoTDBClientConfig = &client.Config { + Host: "127.0.0.1", Port: "6667", UserName: "root", Password: "root", } +type IoTDBConfiguration struct { + Host string `json:"host"` + Port string `json:"port"` + UserName string `json:"username"` + Password string `json:"password"` + PrefixPath string `json:"queryPrefixPath"` + Timeout int64 `json:"queryTimeout(ms)"` +} + +// Default IoTDB connector configuration +var IoTDBConfig = IoTDBConfiguration { + "127.0.0.1", + "6667", + "root", + "root", + "root.test2.dev1", + 5000, +} + + var dummyValue int // dummy value returned when DB configured to none. Counts from 0 to 999, wrap around, updated every 47 msec func initDataServer(serviceMgrChan chan string, clientChannel chan string, backendChannel chan string) { @@ -495,12 +512,12 @@ func getVehicleData(path string) string { // returns {"value":"Y", "ts":"Z"} case "apache-iotdb": var ( // Back-quote the VSS node for the DB query, e.g. `Vehicle.CurrentLocation.Longitude` - selectLastSQL = fmt.Sprintf("select last `%v` from %v", path, IoTDbPrefixPath) - value = "" - ts = "" + selectLastSQL = fmt.Sprintf("select last `%v` from %v", path, IoTDBConfig.PrefixPath) + value = "" + ts = "" ) - // utils.Info.Printf("IoTDB: query using: %v", selectLastSQL) - sessionDataSet, err := IoTDBsession.ExecuteQueryStatement(selectLastSQL, &IoTDbTimeout) +// utils.Info.Printf("IoTDB: query using: %v", selectLastSQL) + sessionDataSet, err := IoTDBsession.ExecuteQueryStatement(selectLastSQL, &IoTDBConfig.Timeout) if err == nil { var success bool success, err = sessionDataSet.Next() @@ -573,8 +590,8 @@ func setVehicleData(path string, value string) string { IoTDBts := time.Now().UTC().UnixNano() / 1000000 // IoTDB will automatically convert the value string to the native data type in the timeseries schema for basic types - // utils.Info.Printf("IoTDB: DB insert with prefixPath: %v vssKey: %v, vssValue: %v, ts: %v", IoTDbPrefixPath, vssKey, vssValue, IoTDBts) - if status, err := IoTDBsession.InsertStringRecord(IoTDbPrefixPath, vssKey, vssValue, IoTDBts); err != nil { +// utils.Info.Printf("IoTDB: DB insert with prefixPath: %v vssKey: %v, vssValue: %v, ts: %v", IoTDBConfig.PrefixPath, vssKey, vssValue, IoTDBts) + if status, err := IoTDBsession.InsertStringRecord(IoTDBConfig.PrefixPath, vssKey, vssValue, IoTDBts); err != nil { utils.Error.Printf("IoTDB: DB insert using InsertStringRecord failed with: %v", err) return "" } else { @@ -983,10 +1000,34 @@ func ServiceMgrInit(mgrId int, serviceMgrChan chan string, stateStorageType stri } utils.Info.Printf("Redis state storage initialised.") case "apache-iotdb": - utils.Info.Printf("IoTDB: creating new session with host:%v port:%v user:%v pass:%v", IoTDBconfig.Host, IoTDBconfig.Port, IoTDBconfig.UserName, IoTDBconfig.Password) - IoTDBsession = client.NewSession(IoTDBconfig) + // Read configuration from file if present else use defaults + IoTDBConfigFilename := "iotdb-config.json" + utils.Info.Printf("IoTDB: Default configuration before config file read = %+v", IoTDBConfig) + data, err := os.ReadFile(IoTDBConfigFilename) + if err != nil { + utils.Error.Printf("IoTDB: Failed to read configuration from %v with error = %+v", IoTDBConfigFilename, err) + } else { + var IoTDBJSONConfig IoTDBConfiguration + err = json.Unmarshal(data, &IoTDBJSONConfig) + if err != nil { + utils.Error.Printf("IoTDB: Failed to unmarshal the JSON config data from %v with error = %+v", IoTDBConfigFilename, err) + } else { + utils.Info.Printf("IoTDB: Configuration read from config file %v = %+v", IoTDBConfigFilename, IoTDBJSONConfig) + // Success. Copy config read from the file. + IoTDBConfig = IoTDBJSONConfig + } + } + + IoTDBClientConfig.Host = IoTDBConfig.Host + IoTDBClientConfig.Port = IoTDBConfig.Port + IoTDBClientConfig.UserName = IoTDBConfig.UserName + IoTDBClientConfig.Password = IoTDBConfig.Password + + // Create new client session with IoTDB server + utils.Info.Printf("IoTDB: Creating new session with client config = %+v", *IoTDBClientConfig) + IoTDBsession = client.NewSession(IoTDBClientConfig) if err := IoTDBsession.Open(false, 0); err != nil { - utils.Error.Printf("IoTDB: Failed to open session with error=%s", err) + utils.Error.Printf("IoTDB: Failed to open server session with error=%s", err) os.Exit(1) } defer IoTDBsession.Close()