diff options
author | Shashank Kumar Shankar <shashank.kumar.shankar@intel.com> | 2018-03-20 16:48:05 -0700 |
---|---|---|
committer | Shashank Kumar Shankar <shashank.kumar.shankar@intel.com> | 2018-03-22 16:42:43 -0700 |
commit | 7dd6e2f9e3725427c628b214cb31bda1dbe95234 (patch) | |
tree | 3d76c2aed17003fb13d7ca734ff63e2ff99d63b6 | |
parent | 1f99187b2ec49a132bd82b40bc4cd02d79cbd416 (diff) |
Make datastore generic to support Consul/Cassandra
This patch makes the backend datastore to be generic so that the
backend datastore can be either Consul or Cassandra. This way,
MUSIC's core functionality can be used and makes other minor fixes.
Change-Id: Iba4eaa751fe60a293d6f2fd60ad06a8c4be1dd1e
Issue-ID: MUSIC-55
Signed-off-by: Shashank Kumar Shankar <shashank.kumar.shankar@intel.com>
-rw-r--r-- | README.rst (renamed from README.md) | 0 | ||||
-rwxr-xr-x | deployment/docker-entrypoint.sh | 8 | ||||
-rwxr-xr-x | deployment/run.sh | 6 | ||||
-rwxr-xr-x | deployment/setup-dependency.sh | 7 | ||||
-rw-r--r-- | src/dkv/api/backendCassandraDatastore.go | 45 | ||||
-rw-r--r-- | src/dkv/api/backendConsulDatastore.go (renamed from src/dkv/api/backendConsulConnection.go) | 34 | ||||
-rw-r--r-- | src/dkv/api/backendDatastoreConnection.go | 27 | ||||
-rw-r--r-- | src/dkv/api/backendFilesystemConnection.go | 2 | ||||
-rw-r--r-- | src/dkv/api/backendPropertiesConnection.go | 4 | ||||
-rw-r--r-- | src/dkv/api/backendfakes.go | 16 | ||||
-rw-r--r-- | src/dkv/api/configHandlers_test.go | 36 | ||||
-rw-r--r-- | src/dkv/api/initialise.go | 24 | ||||
-rw-r--r-- | src/dkv/api/initialise_test.go | 39 | ||||
-rw-r--r-- | src/dkv/api/queryDatastoreHandlers.go (renamed from src/dkv/api/queryConsulHandlers.go) | 6 | ||||
-rw-r--r-- | src/dkv/api/queryDatastoreHandlers_test.go (renamed from src/dkv/api/queryConsulHandlers_test.go) | 36 |
15 files changed, 193 insertions, 97 deletions
diff --git a/deployment/docker-entrypoint.sh b/deployment/docker-entrypoint.sh index 62cf23b..bc442b4 100755 --- a/deployment/docker-entrypoint.sh +++ b/deployment/docker-entrypoint.sh @@ -9,8 +9,10 @@ function start_api_server { ./dkv } -if [ "$CONSUL_IP" = "localhost" ]; then - start_consul_server - sleep 5 +if [ "$DATASTORE_IP" = "localhost" ]; then + if [ "$DATASTORE" = "consul" ]; then + start_consul_server + sleep 5 + fi fi start_api_server diff --git a/deployment/run.sh b/deployment/run.sh index 1be2ef2..996b70e 100755 --- a/deployment/run.sh +++ b/deployment/run.sh @@ -1,10 +1,12 @@ #!/bin/bash -CONSUL_IP="localhost" +DATASTORE="consul" +DATASTORE_IP="localhost" + MOUNTPATH="/dkv_mount_path/configs/" DEFAULT_CONFIGS=$(pwd)/../mountpath/default # TODO(sshank): Change this to think from Kubernetes Volumes perspective. -docker run -e CONSUL_IP=$CONSUL_IP -e MOUNTPATH=$MOUNTPATH -it \ +docker run -e DATASTORE=$DATASTORE -e DATASTORE_IP=$DATASTORE_IP -e MOUNTPATH=$MOUNTPATH -it \ --name dkv \ -v $DEFAULT_CONFIGS:/dkv_mount_path/configs/default \ -p 8200:8200 -p 8080:8080 nexus3.onap.org:10003/onap/music/distributed-kv-store diff --git a/deployment/setup-dependency.sh b/deployment/setup-dependency.sh deleted file mode 100755 index f1ca4c2..0000000 --- a/deployment/setup-dependency.sh +++ /dev/null @@ -1,7 +0,0 @@ -#!/bin/bash - -function create_mountpath { - cp -r mountpath/ /configs -} - -create_mountpath diff --git a/src/dkv/api/backendCassandraDatastore.go b/src/dkv/api/backendCassandraDatastore.go new file mode 100644 index 0000000..555ad0f --- /dev/null +++ b/src/dkv/api/backendCassandraDatastore.go @@ -0,0 +1,45 @@ +/* + * Copyright 2018 Intel Corporation, Inc + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package api + +// (TODO)sahank: Complete MUSIC Cassandra Connections. + +type CassandraStruct struct{} + +func (c *CassandraStruct) InitializeDatastoreClient() error { + return nil +} + +func (c *CassandraStruct) CheckDatastoreHealth() error { + return nil +} + +func (c *CassandraStruct) RequestPUT(key string, value string) error { + return nil +} + +func (c *CassandraStruct) RequestGET(key string) (string, error) { + return "", nil +} + +func (c *CassandraStruct) RequestGETS() ([]string, error) { + return []string{"", ""}, nil +} + +func (c *CassandraStruct) RequestDELETE(key string) error { + return nil +} diff --git a/src/dkv/api/backendConsulConnection.go b/src/dkv/api/backendConsulDatastore.go index 9c2f8d6..231980c 100644 --- a/src/dkv/api/backendConsulConnection.go +++ b/src/dkv/api/backendConsulDatastore.go @@ -22,38 +22,16 @@ import ( "os" ) -// Interface to have all signature methods. -type ConsulRequester interface { - InitializeConsulClient() error - CheckConsulHealth() error - RequestPUT(string, string) error - RequestGET(string) (string, error) - RequestGETS() ([]string, error) - RequestDELETE(string) error -} - type ConsulStruct struct { consulClient *consulapi.Client } -/* -This var is an interface used to initialize ConsulStruct when the who API is brought up. This is done this way so -that a fake Consul can be created which satisfies the interface and we can use that fake Consul in unit testing. -*/ -var Consul ConsulRequester - -/* -The following functions seems like they are not used. But since they are following the ConsulRequest interface, -they can be visible to any Struct which is initiated using the ConsulRequest. This is done for this project in -the initialise.go file where we are creating a ConsulStruct and assigning it to Consul var which is declared -above. -*/ -func (c *ConsulStruct) InitializeConsulClient() error { - if os.Getenv("CONSUL_IP") == "" { - return errors.New("CONSUL_IP environment variable not set.") +func (c *ConsulStruct) InitializeDatastoreClient() error { + if os.Getenv("DATASTORE_IP") == "" { + return errors.New("DATASTORE_IP environment variable not set.") } config := consulapi.DefaultConfig() - config.Address = os.Getenv("CONSUL_IP") + ":8500" + config.Address = os.Getenv("DATASTORE_IP") + ":8500" client, err := consulapi.NewClient(config) if err != nil { @@ -64,11 +42,11 @@ func (c *ConsulStruct) InitializeConsulClient() error { return nil } -func (c *ConsulStruct) CheckConsulHealth() error { +func (c *ConsulStruct) CheckDatastoreHealth() error { kv := c.consulClient.KV() _, _, err := kv.Get("test", nil) if err != nil { - return errors.New("[ERROR] Cannot talk to Consul. Check if it is running/reachable.") + return errors.New("[ERROR] Cannot talk to Datastore. Check if it is running/reachable.") } return nil } diff --git a/src/dkv/api/backendDatastoreConnection.go b/src/dkv/api/backendDatastoreConnection.go new file mode 100644 index 0000000..ebfcc4b --- /dev/null +++ b/src/dkv/api/backendDatastoreConnection.go @@ -0,0 +1,27 @@ +/* + * Copyright 2018 Intel Corporation, Inc + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package api + +// Interface to have Data Store signature methods. +type DatastoreConnector interface { + InitializeDatastoreClient() error + CheckDatastoreHealth() error + RequestPUT(string, string) error + RequestGET(string) (string, error) + RequestGETS() ([]string, error) + RequestDELETE(string) error +} diff --git a/src/dkv/api/backendFilesystemConnection.go b/src/dkv/api/backendFilesystemConnection.go index e6c37ab..519022c 100644 --- a/src/dkv/api/backendFilesystemConnection.go +++ b/src/dkv/api/backendFilesystemConnection.go @@ -49,8 +49,6 @@ const ( var MOUNTPATH = "" -var Directory DirectoryOperationer - func (d *DirectoryStruct) CreateService(body CreateRegisterServiceBody) (string, error) { // Having same name is prohibited? diff --git a/src/dkv/api/backendPropertiesConnection.go b/src/dkv/api/backendPropertiesConnection.go index d485b40..df9683b 100644 --- a/src/dkv/api/backendPropertiesConnection.go +++ b/src/dkv/api/backendPropertiesConnection.go @@ -34,8 +34,6 @@ type KeyValuesInterface interface { type KeyValuesStruct struct{} -var KeyValues KeyValuesInterface - func (kvStruct *KeyValuesStruct) WriteKVsToConsul(token string, subdomain string, kvs map[string]string) error { var prefix = "" if subdomain != "" { @@ -45,7 +43,7 @@ func (kvStruct *KeyValuesStruct) WriteKVsToConsul(token string, subdomain string } for key, value := range kvs { key = prefix + key - err := Consul.RequestPUT(key, value) + err := Datastore.RequestPUT(key, value) if err != nil { return err } diff --git a/src/dkv/api/backendfakes.go b/src/dkv/api/backendfakes.go index c5ca39a..8c8b8a9 100644 --- a/src/dkv/api/backendfakes.go +++ b/src/dkv/api/backendfakes.go @@ -31,6 +31,14 @@ type FakeConsul struct { ConsulStruct } +func (f *FakeConsul) InitializeDatastoreClient() error { + return nil +} + +func (f *FakeConsul) CheckDatastoreHealth() error { + return nil +} + func (f *FakeConsul) RequestGETS() ([]string, error) { return []string{"key1", "key2"}, nil } @@ -52,6 +60,14 @@ type FakeConsulErr struct { ConsulStruct } +func (f *FakeConsulErr) InitializeDatastoreClient() error { + return errors.New("Internal Server Error") +} + +func (f *FakeConsulErr) CheckDatastoreHealth() error { + return errors.New("Internal Server Error") +} + func (f *FakeConsulErr) RequestGETS() ([]string, error) { return []string{"", ""}, errors.New("Internal Server Error") } diff --git a/src/dkv/api/configHandlers_test.go b/src/dkv/api/configHandlers_test.go index e2f796a..bb11eb1 100644 --- a/src/dkv/api/configHandlers_test.go +++ b/src/dkv/api/configHandlers_test.go @@ -75,14 +75,14 @@ func TestHandleConfigDelete_err(t *testing.T) { } func TestHandleConfigPOST(t *testing.T) { - oldConsul := Consul + oldDatastore := Datastore oldKeyValues := KeyValues - Consul = &FakeConsul{} + Datastore = &FakeConsul{} KeyValues = &FakeKeyValues{} defer func() { - Consul = oldConsul + Datastore = oldDatastore KeyValues = oldKeyValues }() @@ -104,14 +104,14 @@ func TestHandleConfigPOST(t *testing.T) { } func TestHandleConfigPOST_only_token(t *testing.T) { - oldConsul := Consul + oldDatastore := Datastore oldKeyValues := KeyValues - Consul = &FakeConsul{} + Datastore = &FakeConsul{} KeyValues = &FakeKeyValues{} defer func() { - Consul = oldConsul + Datastore = oldDatastore KeyValues = oldKeyValues }() @@ -133,14 +133,14 @@ func TestHandleConfigPOST_only_token(t *testing.T) { } func TestHandleConfigPOST_no_body(t *testing.T) { - oldConsul := Consul + oldDatastore := Datastore oldKeyValues := KeyValues - Consul = &FakeConsul{} + Datastore = &FakeConsul{} KeyValues = &FakeKeyValues{} defer func() { - Consul = oldConsul + Datastore = oldDatastore KeyValues = oldKeyValues }() @@ -156,14 +156,14 @@ func TestHandleConfigPOST_no_body(t *testing.T) { } func TestHandleConfigPOST_ConsulError(t *testing.T) { - oldConsul := Consul + oldDatastore := Datastore oldKeyValues := KeyValues - Consul = &FakeConsulErr{} + Datastore = &FakeConsulErr{} KeyValues = &FakeKeyValuesErr{} defer func() { - Consul = oldConsul + Datastore = oldDatastore KeyValues = oldKeyValues }() @@ -196,14 +196,14 @@ func TestHandleConfigUpload_err(t *testing.T) { } func TestHandleDefaultConfigLoad(t *testing.T) { - oldConsul := Consul + oldDatastore := Datastore oldKeyValues := KeyValues - Consul = &FakeConsul{} + Datastore = &FakeConsul{} KeyValues = &FakeKeyValues{} defer func() { - Consul = oldConsul + Datastore = oldDatastore KeyValues = oldKeyValues }() @@ -215,14 +215,14 @@ func TestHandleDefaultConfigLoad(t *testing.T) { } func TestHandleDefaultConfigLoad_err(t *testing.T) { - oldConsul := Consul + oldDatastore := Datastore oldKeyValues := KeyValues - Consul = &FakeConsul{} + Datastore = &FakeConsul{} KeyValues = &FakeKeyValuesErr{} defer func() { - Consul = oldConsul + Datastore = oldDatastore KeyValues = oldKeyValues }() diff --git a/src/dkv/api/initialise.go b/src/dkv/api/initialise.go index f4edc6c..20a5df4 100644 --- a/src/dkv/api/initialise.go +++ b/src/dkv/api/initialise.go @@ -16,19 +16,35 @@ package api -import "os" +import ( + "errors" + "os" +) + +var ( + Datastore DatastoreConnector + KeyValues KeyValuesInterface + Directory DirectoryOperationer +) func Initialise() error { - Consul = &ConsulStruct{} + if os.Getenv("DATASTORE") == "" { + return errors.New("DATASTORE environment variable not set.") + } + if os.Getenv("DATASTORE") == "consul" { + Datastore = &ConsulStruct{} + } else if os.Getenv("DATASTORE") == "cassandra" { + Datastore = &CassandraStruct{} + } KeyValues = &KeyValuesStruct{} Directory = &DirectoryStruct{directory: ""} - err := Consul.InitializeConsulClient() + err := Datastore.InitializeDatastoreClient() if err != nil { return err } - err = Consul.CheckConsulHealth() + err = Datastore.CheckDatastoreHealth() if err != nil { return err } diff --git a/src/dkv/api/initialise_test.go b/src/dkv/api/initialise_test.go index 3063201..363edce 100644 --- a/src/dkv/api/initialise_test.go +++ b/src/dkv/api/initialise_test.go @@ -22,20 +22,41 @@ import ( "testing" ) -func TestInitialise_errorIP(t *testing.T) { - consul_ip := os.Getenv("CONSUL_IP") - os.Unsetenv("CONSUL_IP") - defer os.Setenv("CONSUL_IP", consul_ip) +func TestInitialise_cassandra(t *testing.T) { + oldDatastore_ip := os.Getenv("DATASTORE_IP") + oldDatastore_type := os.Getenv("DATASTORE") + + os.Setenv("DATASTORE_IP", "localhost") + os.Setenv("DATASTORE", "cassandra") + + defer func() { + os.Setenv("DATASTORE_IP", oldDatastore_ip) + os.Setenv("DATASTORE", oldDatastore_type) + }() + + err := Initialise() + assert.Nil(t, err) +} +func TestInitialise_consulError(t *testing.T) { + oldDatastore_ip := os.Getenv("DATASTORE_IP") + oldDatastore_type := os.Getenv("DATASTORE") + + os.Setenv("DATASTORE_IP", "localhost") + os.Setenv("DATASTORE", "consul") + + defer func() { + os.Setenv("DATASTORE_IP", oldDatastore_ip) + os.Setenv("DATASTORE", oldDatastore_type) + }() err := Initialise() assert.NotNil(t, err) } -func TestInitialise_errorConsul(t *testing.T) { - // This is done this way cause the Consul interface with Fake Struct will get - // overridden with real Struct during runtime. - os.Setenv("CONSUL_IP", "test") - defer os.Unsetenv("CONSUL_IP") +func TestInitialise_datastoreEmptyError(t *testing.T) { + datastore := os.Getenv("DATASTORE") + os.Unsetenv("DATASTORE") + defer os.Setenv("DATASTORE", datastore) err := Initialise() assert.NotNil(t, err) diff --git a/src/dkv/api/queryConsulHandlers.go b/src/dkv/api/queryDatastoreHandlers.go index fb63b6d..4197ac0 100644 --- a/src/dkv/api/queryConsulHandlers.go +++ b/src/dkv/api/queryDatastoreHandlers.go @@ -38,7 +38,7 @@ func HandleGET(w http.ResponseWriter, r *http.Request) { vars := mux.Vars(r) key := vars["token"] + "/" + vars["key"] - value, err := Consul.RequestGET(key) + value, err := Datastore.RequestGET(key) if err != nil { req := ResponseStringStruct{Response: string(err.Error())} @@ -54,7 +54,7 @@ func HandleGET(w http.ResponseWriter, r *http.Request) { func HandleGETS(w http.ResponseWriter, r *http.Request) { - values, err := Consul.RequestGETS() + values, err := Datastore.RequestGETS() if err != nil { req := ResponseStringStruct{Response: string(err.Error())} @@ -72,7 +72,7 @@ func HandleDELETE(w http.ResponseWriter, r *http.Request) { vars := mux.Vars(r) key := vars["key"] - err := Consul.RequestDELETE(key) + err := Datastore.RequestDELETE(key) if err != nil { req := ResponseStringStruct{Response: string(err.Error())} diff --git a/src/dkv/api/queryConsulHandlers_test.go b/src/dkv/api/queryDatastoreHandlers_test.go index 38f3acd..c6211bc 100644 --- a/src/dkv/api/queryConsulHandlers_test.go +++ b/src/dkv/api/queryDatastoreHandlers_test.go @@ -33,9 +33,9 @@ func RouterConsul() *mux.Router { } func TestHandleGETS(t *testing.T) { - oldConsul := Consul - Consul = &FakeConsul{} - defer func() { Consul = oldConsul }() + oldDataStore := Datastore + Datastore = &FakeConsul{} + defer func() { Datastore = oldDataStore }() request, _ := http.NewRequest("GET", "/v1/getconfigs", nil) response := httptest.NewRecorder() @@ -45,9 +45,9 @@ func TestHandleGETS(t *testing.T) { } func TestHandleGETS_err(t *testing.T) { - oldConsul := Consul - Consul = &FakeConsulErr{} - defer func() { Consul = oldConsul }() + oldDataStore := Datastore + Datastore = &FakeConsulErr{} + defer func() { Datastore = oldDataStore }() request, _ := http.NewRequest("GET", "/v1/getconfigs", nil) response := httptest.NewRecorder() @@ -57,9 +57,9 @@ func TestHandleGETS_err(t *testing.T) { } func TestHandleGET(t *testing.T) { - oldConsul := Consul - Consul = &FakeConsul{} - defer func() { Consul = oldConsul }() + oldDataStore := Datastore + Datastore = &FakeConsul{} + defer func() { Datastore = oldDataStore }() request, _ := http.NewRequest("GET", "/v1/getconfig/key1", nil) response := httptest.NewRecorder() @@ -69,9 +69,9 @@ func TestHandleGET(t *testing.T) { } func TestHandleGET_err(t *testing.T) { - oldConsul := Consul - Consul = &FakeConsulErr{} - defer func() { Consul = oldConsul }() + oldDataStore := Datastore + Datastore = &FakeConsulErr{} + defer func() { Datastore = oldDataStore }() request, _ := http.NewRequest("GET", "/v1/getconfig/key1", nil) response := httptest.NewRecorder() @@ -81,9 +81,9 @@ func TestHandleGET_err(t *testing.T) { } func TestHandleDELETE(t *testing.T) { - oldConsul := Consul - Consul = &FakeConsul{} - defer func() { Consul = oldConsul }() + oldDataStore := Datastore + Datastore = &FakeConsul{} + defer func() { Datastore = oldDataStore }() request, _ := http.NewRequest("DELETE", "/v1/deleteconfig/key1", nil) response := httptest.NewRecorder() @@ -93,9 +93,9 @@ func TestHandleDELETE(t *testing.T) { } func TestHandleDELETE_err(t *testing.T) { - oldConsul := Consul - Consul = &FakeConsulErr{} - defer func() { Consul = oldConsul }() + oldDataStore := Datastore + Datastore = &FakeConsulErr{} + defer func() { Datastore = oldDataStore }() request, _ := http.NewRequest("DELETE", "/v1/deleteconfig/key1", nil) response := httptest.NewRecorder() |