Initial seed code for distributed KV store 79/30779/1
authorShashank Kumar Shankar <shashank.kumar.shankar@intel.com>
Thu, 8 Feb 2018 01:50:55 +0000 (17:50 -0800)
committerShashank Kumar Shankar <shashank.kumar.shankar@intel.com>
Thu, 8 Feb 2018 01:53:10 +0000 (17:53 -0800)
This patch includes the initial seed code for KV store.

Subsequent patches will include documentation, API ref and
unit tests.

Change-Id: I6296215b6b796400947ba925a2d8c46380e16992
Issue-ID: MUSIC-23
Signed-off-by: Shashank Kumar Shankar <shashank.kumar.shankar@intel.com>
16 files changed:
.gitignore [new file with mode: 0644]
.gitreview [new file with mode: 0644]
Gopkg.lock [new file with mode: 0644]
Gopkg.toml [new file with mode: 0644]
README.md [new file with mode: 0644]
api/consulConnection.go [new file with mode: 0644]
api/consulConnection_test.go [new file with mode: 0644]
api/endpointViews.go [new file with mode: 0644]
api/endpointViews_test.go [new file with mode: 0644]
api/propertiesReader.go [new file with mode: 0644]
api/propertiesReader_test.go [new file with mode: 0644]
api/utils.go [new file with mode: 0644]
api/utils_test.go [new file with mode: 0644]
configurations/sampleAAIConfig.properties [new file with mode: 0644]
configurations/sampleAPPCConfig.properties [new file with mode: 0644]
main.go [new file with mode: 0644]

diff --git a/.gitignore b/.gitignore
new file mode 100644 (file)
index 0000000..879e9b6
--- /dev/null
@@ -0,0 +1,5 @@
+.idea/
+*.iml
+consul
+.DS_Store
+vendor/
diff --git a/.gitreview b/.gitreview
new file mode 100644 (file)
index 0000000..dd44c66
--- /dev/null
@@ -0,0 +1,4 @@
+[gerrit]
+host=gerrit.onap.org
+port=29418
+project=music/distributed-kv-store.git
diff --git a/Gopkg.lock b/Gopkg.lock
new file mode 100644 (file)
index 0000000..33c42f6
--- /dev/null
@@ -0,0 +1,75 @@
+# This file is autogenerated, do not edit; changes may be undone by the next 'dep ensure'.
+
+
+[[projects]]
+  name = "github.com/davecgh/go-spew"
+  packages = ["spew"]
+  revision = "346938d642f2ec3594ed81d874461961cd0faa76"
+  version = "v1.1.0"
+
+[[projects]]
+  name = "github.com/gorilla/context"
+  packages = ["."]
+  revision = "1ea25387ff6f684839d82767c1733ff4d4d15d0a"
+  version = "v1.1"
+
+[[projects]]
+  name = "github.com/gorilla/mux"
+  packages = ["."]
+  revision = "53c1911da2b537f792e7cafcb446b05ffe33b996"
+  version = "v1.6.1"
+
+[[projects]]
+  name = "github.com/hashicorp/consul"
+  packages = ["api"]
+  revision = "48f3dd5642374d079f5a64359023fb8318eb81cc"
+  version = "v1.0.3"
+
+[[projects]]
+  branch = "master"
+  name = "github.com/hashicorp/go-cleanhttp"
+  packages = ["."]
+  revision = "d5fe4b57a186c716b0e00b8c301cbd9b4182694d"
+
+[[projects]]
+  branch = "master"
+  name = "github.com/hashicorp/go-rootcerts"
+  packages = ["."]
+  revision = "6bb64b370b90e7ef1fa532be9e591a81c3493e00"
+
+[[projects]]
+  name = "github.com/hashicorp/serf"
+  packages = ["coordinate"]
+  revision = "d6574a5bb1226678d7010325fb6c985db20ee458"
+  version = "v0.8.1"
+
+[[projects]]
+  name = "github.com/magiconair/properties"
+  packages = ["."]
+  revision = "d419a98cdbed11a922bf76f257b7c4be79b50e73"
+  version = "v1.7.4"
+
+[[projects]]
+  branch = "master"
+  name = "github.com/mitchellh/go-homedir"
+  packages = ["."]
+  revision = "b8bc1bf767474819792c23f32d8286a45736f1c6"
+
+[[projects]]
+  name = "github.com/pmezard/go-difflib"
+  packages = ["difflib"]
+  revision = "792786c7400a136282c1664665ae0a8db921c6c2"
+  version = "v1.0.0"
+
+[[projects]]
+  name = "github.com/stretchr/testify"
+  packages = ["assert"]
+  revision = "12b6f73e6084dad08a7c6e575284b177ecafbc71"
+  version = "v1.2.1"
+
+[solve-meta]
+  analyzer-name = "dep"
+  analyzer-version = 1
+  inputs-digest = "b980f85326f4b80746ec5b571cb1d39ebd88faba4028d4000bb84775aef0470f"
+  solver-name = "gps-cdcl"
+  solver-version = 1
diff --git a/Gopkg.toml b/Gopkg.toml
new file mode 100644 (file)
index 0000000..3f608e7
--- /dev/null
@@ -0,0 +1,42 @@
+# Gopkg.toml example
+#
+# Refer to https://github.com/golang/dep/blob/master/docs/Gopkg.toml.md
+# for detailed Gopkg.toml documentation.
+#
+# required = ["github.com/user/thing/cmd/thing"]
+# ignored = ["github.com/user/project/pkgX", "bitbucket.org/user/project/pkgA/pkgY"]
+#
+# [[constraint]]
+#   name = "github.com/user/project"
+#   version = "1.0.0"
+#
+# [[constraint]]
+#   name = "github.com/user/project2"
+#   branch = "dev"
+#   source = "github.com/myfork/project2"
+#
+# [[override]]
+#   name = "github.com/x/y"
+#   version = "2.4.0"
+#
+# [prune]
+#   non-go = false
+#   go-tests = true
+#   unused-packages = true
+
+
+[[constraint]]
+  name = "github.com/gorilla/mux"
+  version = "1.6.1"
+
+[[constraint]]
+  name = "github.com/hashicorp/consul"
+  version = "1.0.3"
+
+[[constraint]]
+  name = "github.com/magiconair/properties"
+  version = "1.7.4"
+
+[prune]
+  go-tests = true
+  unused-packages = true
diff --git a/README.md b/README.md
new file mode 100644 (file)
index 0000000..0273978
--- /dev/null
+++ b/README.md
@@ -0,0 +1,4 @@
+Distributed Key Value Store using Consul to store application configuration data.
+
+# TODO
+# Add documentation on how to run.
diff --git a/api/consulConnection.go b/api/consulConnection.go
new file mode 100644 (file)
index 0000000..b8074e2
--- /dev/null
@@ -0,0 +1,113 @@
+/*
+ * 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
+
+import (
+       "errors"
+       "fmt"
+       "github.com/hashicorp/consul/api"
+       "os"
+)
+
+func (kvStruct *KeyValue) WriteKVsToConsul() error {
+       for key, value := range kvStruct.kv {
+               if os.Getenv("CONSUL_IP") == "" {
+                       return errors.New("CONSUL_IP environment variable not set.")
+               }
+               err := requestPUT(os.Getenv("CONSUL_IP"), key, value)
+               if err != nil {
+                       return err
+               }
+               fmt.Println("key:", key, "value", value)
+       }
+       fmt.Println("Wrote KVs to Consul")
+       return nil
+}
+
+func GetKVFromConsul(key string) (string, error) {
+       if os.Getenv("CONSUL_IP") == "" {
+               return "", errors.New("CONSUL_IP environment variable not set.")
+       }
+       resp, err := requestGET(os.Getenv("CONSUL_IP"), key)
+       return resp, err
+}
+
+func GetKVsFromConsul() ([]string, error) {
+       if os.Getenv("CONSUL_IP") == "" {
+               return []string{""}, errors.New("CONSUL_IP environment variable not set.")
+       }
+       resp, err := requestGETS(os.Getenv("CONSUL_IP"))
+       return resp, err
+}
+
+func requestPUT(url string, key string, value string) error {
+       config := api.DefaultConfig()
+       config.Address = url + ":8500"
+       client, err := api.NewClient(config)
+
+       if err != nil {
+               return err
+       }
+
+       kv := client.KV()
+
+       p := &api.KVPair{Key: key, Value: []byte(value)}
+       _, err = kv.Put(p, nil)
+       if err != nil {
+               return err
+       }
+
+       return nil
+}
+
+func requestGET(url string, key string) (string, error) {
+       config := api.DefaultConfig()
+       config.Address = url + ":8500"
+       client, err := api.NewClient(config)
+
+       kv := client.KV()
+
+       pair, _, err := kv.Get(key, nil)
+
+       if pair == nil {
+               return string("No value found for key."), err
+       }
+       return string(pair.Value), err
+
+}
+
+func requestGETS(url string) ([]string, error) {
+       config := api.DefaultConfig()
+       config.Address = url + ":8500"
+       client, err := api.NewClient(config)
+
+       kv := client.KV()
+
+       pairs, _, err := kv.List("", nil)
+
+       if len(pairs) == 0 {
+               return []string{"No keys found."}, err
+       }
+
+       var res []string
+
+       for _, keypair := range pairs {
+               res = append(res, keypair.Key)
+       }
+
+       return res, err
+}
diff --git a/api/consulConnection_test.go b/api/consulConnection_test.go
new file mode 100644 (file)
index 0000000..342542a
--- /dev/null
@@ -0,0 +1,19 @@
+/*
+ * 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(sshank)
diff --git a/api/endpointViews.go b/api/endpointViews.go
new file mode 100644 (file)
index 0000000..3c47ee5
--- /dev/null
@@ -0,0 +1,108 @@
+/*
+ * 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
+
+import (
+       "encoding/json"
+       "github.com/gorilla/mux"
+       "net/http"
+)
+
+var getkvs = GetKVsFromConsul
+
+func HandlePOST(w http.ResponseWriter, r *http.Request) {
+
+       var body LoadStruct
+
+       decoder := json.NewDecoder(r.Body)
+       err := decoder.Decode(&body)
+
+       if err != nil {
+               req := ResponseStringStruct{Response: "Empty body."}
+               w.Header().Set("Content-Type", "application/json")
+               w.WriteHeader(http.StatusBadRequest)
+               json.NewEncoder(w).Encode(&req)
+               return
+       }
+
+       err = ValidateBody(body)
+
+       if err != nil {
+               req := ResponseStringStruct{Response: string(err.Error())}
+               w.Header().Set("Content-Type", "application/json")
+               w.WriteHeader(http.StatusBadRequest)
+               json.NewEncoder(w).Encode(req)
+               return
+       }
+
+       err = KVStruct.ReadConfigs(body)
+
+       if err != nil {
+               req := ResponseStringStruct{Response: string(err.Error())}
+               w.Header().Set("Content-Type", "application/json")
+               w.WriteHeader(http.StatusInternalServerError)
+               json.NewEncoder(w).Encode(req)
+               return
+       }
+
+       err = KVStruct.WriteKVsToConsul()
+
+       if err != nil {
+               req := ResponseStringStruct{Response: string(err.Error())}
+               w.Header().Set("Content-Type", "application/json")
+               w.WriteHeader(http.StatusInternalServerError)
+               json.NewEncoder(w).Encode(req)
+       } else {
+               req := ResponseStringStruct{Response: "Configuration read and default Key Values loaded to Consul"}
+               w.Header().Set("Content-Type", "application/json")
+               json.NewEncoder(w).Encode(&req)
+       }
+}
+
+func HandleGET(w http.ResponseWriter, r *http.Request) {
+       vars := mux.Vars(r)
+       key := vars["key"]
+
+       value, err := GetKVFromConsul(key)
+
+       if err != nil {
+               req := ResponseStringStruct{Response: string(err.Error())}
+               w.Header().Set("Content-Type", "application/json")
+               w.WriteHeader(http.StatusBadRequest)
+               json.NewEncoder(w).Encode(req)
+       } else {
+               req := ResponseGETStruct{Response: map[string]string{key: value}}
+               w.Header().Set("Content-Type", "application/json")
+               json.NewEncoder(w).Encode(req)
+       }
+}
+
+func HandleGETS(w http.ResponseWriter, r *http.Request) {
+
+       values, err := getkvs()
+
+       if err != nil {
+               req := ResponseStringStruct{Response: string(err.Error())}
+               w.Header().Set("Content-Type", "application/json")
+               w.WriteHeader(http.StatusBadRequest)
+               json.NewEncoder(w).Encode(req)
+       } else {
+               req := ResponseGETSStruct{Response: values}
+               w.Header().Set("Content-Type", "application/json")
+               json.NewEncoder(w).Encode(req)
+       }
+}
diff --git a/api/endpointViews_test.go b/api/endpointViews_test.go
new file mode 100644 (file)
index 0000000..f603af4
--- /dev/null
@@ -0,0 +1,58 @@
+/*
+ * 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
+
+import (
+       //"encoding/json"
+       "github.com/gorilla/mux"
+       "github.com/stretchr/testify/assert"
+       "net/http"
+       "net/http/httptest"
+       "testing"
+)
+
+func Router() *mux.Router {
+       router := mux.NewRouter()
+       router.HandleFunc("/getconfigs", HandleGETS).Methods("GET")
+       router.HandleFunc("/loadconfigs", HandlePOST).Methods("POST")
+       return router
+}
+
+func TestHandlePOST(t *testing.T) {
+       // TODO(sshank)
+       assert.Equal(t, 0, 0, "Not passed.")
+}
+
+func TestHandleGET(t *testing.T) {
+       // TODO(sshank)
+       assert.Equal(t, 0, 0, "Not passed.")
+}
+
+func TestHandleGETS(t *testing.T) {
+       getkvOld := getkvs
+       defer func() { getkvs = getkvOld }()
+
+       getkvs = func() ([]string, error) {
+               return nil, nil
+       }
+
+       request, _ := http.NewRequest("GET", "/getconfigs", nil)
+       response := httptest.NewRecorder()
+       Router().ServeHTTP(response, request)
+
+       assert.Equal(t, 200, response.Code, "OK response is expected")
+}
diff --git a/api/propertiesReader.go b/api/propertiesReader.go
new file mode 100644 (file)
index 0000000..018dabe
--- /dev/null
@@ -0,0 +1,73 @@
+/*
+ * 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
+
+import (
+       "errors"
+       "github.com/magiconair/properties"
+       "io/ioutil"
+       "path"
+       "runtime"
+)
+
+func PropertiesFilesToKV(directory string) (map[string]string, error) {
+       if directory == "default" {
+               kvs := make(map[string]string)
+
+               _, filename, _, ok := runtime.Caller(0)
+
+               if !ok {
+                       return nil, errors.New("No caller")
+               }
+
+               configDir := path.Dir(filename) + "/../configurations/"
+               err := ReadMultipleProperties(configDir, kvs)
+               if err != nil {
+                       return nil, err
+               }
+               return kvs, nil
+       } else {
+               // Add case if directory is not there.
+               kvs := make(map[string]string)
+               directory += "/"
+               err := ReadMultipleProperties(directory, kvs)
+               if err != nil {
+                       return nil, err
+               }
+               return kvs, nil
+       }
+}
+
+func ReadProperty(path string, kvs map[string]string) {
+       p := properties.MustLoadFile(path, properties.UTF8)
+       for _, key := range p.Keys() {
+               kvs[key] = p.MustGet(key)
+       }
+}
+
+func ReadMultipleProperties(path string, kvs map[string]string) error {
+       files, err := ioutil.ReadDir(path)
+       if err != nil {
+               return err
+       }
+
+       for _, f := range files {
+               ReadProperty(path+f.Name(), kvs)
+       }
+
+       return nil
+}
diff --git a/api/propertiesReader_test.go b/api/propertiesReader_test.go
new file mode 100644 (file)
index 0000000..c564be5
--- /dev/null
@@ -0,0 +1,19 @@
+/*
+ * 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(sshank)
\ No newline at end of file
diff --git a/api/utils.go b/api/utils.go
new file mode 100644 (file)
index 0000000..8b87848
--- /dev/null
@@ -0,0 +1,101 @@
+/*
+ * 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
+
+import (
+       "errors"
+       "sync"
+)
+
+type KeyValue struct {
+       sync.RWMutex
+       kv map[string]string
+}
+
+type ResponseStringStruct struct {
+       Response string `json:"response"`
+}
+
+type ResponseGETStruct struct {
+       Response map[string]string `json:"response"`
+}
+
+type ResponseGETSStruct struct {
+       Response []string `json:"response"`
+}
+
+type LoadStruct struct {
+       Type *TypeStruct `json:"type"`
+}
+
+type TypeStruct struct {
+       FilePath string `json:"file_path"`
+}
+
+var KVStruct = &KeyValue{kv: make(map[string]string)}
+
+func (kvStruct *KeyValue) ReadConfigs(body LoadStruct) error {
+       if body.Type.FilePath == "default" {
+               err := kvStruct.FileReader("default")
+               if err != nil {
+                       return err
+               }
+               return nil
+       } else {
+               err := kvStruct.FileReader(body.Type.FilePath)
+               if err != nil {
+                       return err
+               }
+               return nil
+       }
+}
+
+func (kvStruct *KeyValue) FileReader(directory string) error {
+       defer kvStruct.Unlock()
+
+       kvStruct.Lock()
+
+       if directory == "default" {
+               propertiesValues, err := PropertiesFilesToKV("default")
+               if err != nil {
+                       return err
+               }
+               for key, value := range propertiesValues {
+                       kvStruct.kv[key] = value
+               }
+               return nil
+       } else {
+               propertiesValues, err := PropertiesFilesToKV(directory)
+               if err != nil {
+                       return err
+               }
+               for key, value := range propertiesValues {
+                       kvStruct.kv[key] = value
+               }
+               return nil
+       }
+}
+
+func ValidateBody(body LoadStruct) error {
+       if body.Type == nil {
+               return errors.New("Type not set. Recheck POST data.")
+       } else if body.Type.FilePath == "" {
+               return errors.New("file_path not set")
+       } else {
+               return nil
+       }
+}
diff --git a/api/utils_test.go b/api/utils_test.go
new file mode 100644 (file)
index 0000000..c564be5
--- /dev/null
@@ -0,0 +1,19 @@
+/*
+ * 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(sshank)
\ No newline at end of file
diff --git a/configurations/sampleAAIConfig.properties b/configurations/sampleAAIConfig.properties
new file mode 100644 (file)
index 0000000..6052315
--- /dev/null
@@ -0,0 +1,94 @@
+####################################################################
+#  REMEMBER TO THINK ABOUT ENVIRONMENTAL DIFFERENCES AND CHANGE THE
+#  TEMPLATE AND *ALL* DATAFILES
+####################################################################
+
+aai.config.checktime=1000
+
+# this could come from siteconfig.pl?
+aai.config.nodename=AutomaticallyOverwritten
+
+
+
+aai.auth.cspcookies_on=false
+aai.dbmodel.filename=ex5.json
+
+aai.server.url.base=<%= @AAI_SERVER_URL_BASE %>
+aai.server.url=<%= @AAI_SERVER_URL %>
+aai.global.callback.url=<%= @AAI_GLOBAL_CALLBACK_URL %>
+
+aai.tools.enableBasicAuth=true
+aai.tools.username=AAI
+aai.tools.password=AAI
+
+aai.truststore.filename=<%= @AAI_TRUSTSTORE_FILENAME %>
+aai.truststore.passwd.x=<%= @AAI_TRUSTSTORE_PASSWD_X %>
+aai.keystore.filename=<%= @AAI_KEYSTORE_FILENAME %>
+aai.keystore.passwd.x=<%= @AAI_KEYSTORE_PASSWD_X %>
+
+
+aai.notification.current.version=<%= @AAI_NOTIFICATION_CURRENT_VERSION %>
+aai.notificationEvent.default.status=<%= @AAI_NOTIFICATION_EVENT_DEFAULT_EVENT_STATUS %>
+aai.notificationEvent.default.eventType=<%= @AAI_NOTIFICATION_EVENT_DEFAULT_EVENT_TYPE %>
+aai.notificationEvent.default.domain=<%= @AAI_NOTIFICATION_EVENT_DEFAULT_DOMAIN %>
+aai.notificationEvent.default.sourceName=<%= @AAI_NOTIFICATION_EVENT_DEFAULT_SOURCE_NAME %>
+aai.notificationEvent.default.sequenceNumber=<%= @AAI_NOTIFICATION_EVENT_DEFAULT_SEQUENCE_NUMBER %>
+aai.notificationEvent.default.severity=<%= @AAI_NOTIFICATION_EVENT_DEFAULT_SEVERITY %>
+aai.notificationEvent.default.version=<%= @AAI_NOTIFICATION_EVENT_DEFAULT_VERSION %>
+# This one lets us enable/disable resource-version checking on updates/deletes
+aai.resourceversion.enableflag=<%= @RESOURCE_VERSION_ENABLE_FLAG %>
+aai.logging.maxStackTraceEntries=10
+aai.default.api.version=<%= @AAI_DEFAULT_API_VERSION %>
+
+
+
+# Used by Model-processing code
+aai.model.delete.sleep.per.vtx.msec=500
+aai.model.query.resultset.maxcount=50
+aai.model.query.timeout.sec=90
+
+# Used by Data Grooming
+aai.grooming.default.max.file=150
+aai.grooming.default.sleep.minutes=7
+
+aai.model.proc.max.levels=50
+aai.edgeTag.proc.max.levels=50
+
+# for transaction log
+aai.logging.hbase.interceptor=true
+aai.logging.hbase.enabled=true
+aai.logging.hbase.logrequest=true
+aai.logging.hbase.logresponse=true
+
+# for gremlin server
+aai.server.rebind=g
+hbase.table.name=<%= @TXN_HBASE_TABLE_NAME %>
+hbase.table.timestamp.format=YYYYMMdd-HH:mm:ss:SSS
+hbase.zookeeper.quorum=<%= @TXN_ZOOKEEPER_QUORUM %>
+hbase.zookeeper.property.clientPort=<%= @TXN_ZOOKEEPER_PROPERTY_CLIENTPORT %>
+hbase.zookeeper.znode.parent=<%= @TXN_HBASE_ZOOKEEPER_ZNODE_PARENT %>
+
+aai.logging.trace.enabled=true
+aai.logging.trace.logrequest=false
+aai.logging.trace.logresponse=false
+
+
+aai.transaction.logging=true
+aai.transaction.logging.get=false
+aai.transaction.logging.post=false
+
+#limit set for bulk consumer APIS
+aai.bulkconsumer.payloadlimit=30
+
+#uncomment and use header X-OverrideLimit with the value to override the bulk api limit
+#aai.bulkconsumer.payloadoverride=AAI-OVERRIDE-KEY
+aai.bulkconsumer.payloadoverride=false
+
+#timeout for crud enabled flag
+aai.crud.timeoutenabled=true
+
+#timeout app specific
+aai.crud.timeout.appspecific=JUNITTESTAPP1,1|JUNITTESTAPP2,-1|DCAE-CCS,-1|DCAES,-1|AAI-FILEGEN-GFPIP,-1
+
+#default timeout limit added for traversal if not overridden (in ms)
+aai.crud.timeoutlimit=180000
\ No newline at end of file
diff --git a/configurations/sampleAPPCConfig.properties b/configurations/sampleAPPCConfig.properties
new file mode 100644 (file)
index 0000000..484337f
--- /dev/null
@@ -0,0 +1,113 @@
+###                                            ###
+### Properties for demo  ###
+###                                            ###
+appc.demo.poolMembers=10.0.11.1:3904
+appc.demo.topic.read=APPC-CL
+appc.demo.topic.write=APPC-CL
+appc.demo.client.name=appcDemoEventListener
+appc.demo.threads.queuesize.min=1
+appc.demo.threads.queuesize.max=1000
+appc.demo.threads.poolsize.min=1
+appc.demo.threads.poolsize.max=2
+appc.demo.provider.user=admin
+appc.demo.provider.pass=Kp8bJ4SXszM0WXlhak3eHlcse2gAw84vaoGGmJvUy2U
+appc.demo.provider.url=http://localhost:8181/restconf/operations/appc-provider
+appc.provider.vfodl.url=http://admin:Kp8bJ4SXszM0WXlhak3eHlcse2gAw84vaoGGmJvUy2U@10.0.2.1:8282/restconf/config/network-topology:network-topology/topology/topology-netconf/node/NODE_NAME/yang-ext:mount/sample-plugin:sample-plugin/pg-streams/
+
+# The properties right below are needed to properly call the Master DG to serve demo purposes
+appc.service.logic.module.name=APPC
+appc.topology.dg.method=topology-operation-all
+appc.topology.dg.version=2.0.0
+
+# TEMP - Properties that might be needed to make the AAI-APPC connection
+org.onap.appc.db.url.appcctl=jdbc:mysql://dbhost:3306/appcctl
+org.onap.appc.db.user.appcctl=appcctl
+org.onap.appc.db.pass.appcctl=appcctl
+
+org.onap.appc.db.url.sdnctl=jdbc:mysql://dbhost:3306/sdnctl
+org.onap.appc.db.user.sdnctl=sdnctl
+org.onap.appc.db.pass.sdnctl=gamma
+
+
+###                                                                                                                                               ###
+### OpenStack credentials (these properties also are used in appc-rest-adapter-bundle, appc-chef-adapter-bundle, appc-iaas-adapter-bundle) ###
+###                                                                                                                                               ###
+provider1.type=OpenStackProvider
+provider1.name=OpenStack
+provider1.identity=http://localhost:8181/apidoc/explorer/index.html
+provider1.tenant1.name=default
+provider1.tenant1.domain=default
+provider1.tenant1.userid=admin
+provider1.tenant1.password=Kp8bJ4SXszM0WXlhak3eHlcse2gAw84vaoGGmJvUy2U
+
+
+
+
+
+###                                                                                                                                                                                                 ###
+### Properties that are not covered or being replaced from default.properties files. Default value for DMaaP IP is 10.0.11.1:3904                     ###
+### which is what the Master HEAT Template to instantiate ONAP is pointing to (version R1).  All other default values are                     ###
+### left there since these are pre-defined as part of APP-C/ONAP default instantiation with Master HEAT Template                              ###
+###                                                                                                                                                                                                     ###
+
+
+# Property below is valid in appc-command-executor-core,  appc-license-manager-core, appc-lifecycle-management-core,
+# appc-request-handler-core, appc-workflow-management-core (all from the appc-dispatcher package).
+dmaap.poolMembers=10.0.11.1:3904
+
+
+# appc-event-listener-bundle properties (only defined in src/test of default.properties)
+appc.LCM.poolMembers=10.0.11.1:3904
+appc.LCM.topic.read=APPC-LCM-READ
+appc.LCM.topic.write=APPC-LCM-WRITE
+appc.LCM.client.name=APPC-EVENT-LISTENER-TEST
+appc.LCM.provider.user=admin
+appc.LCM.provider.pass=Kp8bJ4SXszM0WXlhak3eHlcse2gAw84vaoGGmJvUy2U
+appc.LCM.provider.url=http://localhost:8181/restconf/operations/appc-provider-lcm
+
+
+# properties from appc-netconf-adapter-bundle, appc-dg-common, appc-dmaap-adapter-bundle
+poolMembers=10.0.11.1:3904
+event.pool.members=10.0.11.1:3904
+restconf.user=admin
+restconf.pass=Kp8bJ4SXszM0WXlhak3eHlcse2gAw84vaoGGmJvUy2U
+
+
+# properties found in appc-rest-adapter-bundle, appc-chef-adapter-bundle, appc-iaas-adapter-bundle)
+#Your OpenStack IP
+test.ip=10.0.11.100
+# Your OpenStack Platform's Keystone Port (default is 5000)
+test.port=5000
+test.tenantid=test
+test.vmid=test
+# Port 8774 below is default port for OpenStack's Nova API Service
+test.url=http://api.appc.local/vm/9999999/test/99999999-9999-9999-9999-999999999999
+#skips hypervisor check which usually occurs during iaas-adapter-bundle startup
+org.onap.appc.iaas.skiphypervisorcheck=true
+
+
+# Properties from default.properties in the src/test and src/main paths of appc-asdc-listener-bundle
+appc.sdc.host=10.0.3.1:8443
+appc.sdc.env=APPC-ASDC-ENV
+appc.sdc.user=test
+appc.sdc.pass=test
+appc.sdc.consumer=APPC-ASDC-CONSUMER
+appc.sdc.consumer.id=APPC-ASDC-CONSUMER-ID
+appc.sdc.provider.url=http://localhost:8181/restconf/operations/AsdcMessage:configuration-document-request
+
+# Properties used by EventSenderDmaapImpl.java
+DCAE.dmaap.event.topic.write=EventSenderTest
+DCAE.dmaap.appc.username=test
+DCAE.dmaap.appc.password=test
+DCAE.dmaap.event.pool.members=10.0.11.1:3904
+
+# OAM Listener
+appc.OAM.disabled=true
+appc.OAM.provider.url=http://localhost:8181/restconf/operations/appc-oam
+appc.OAM.poolMembers=10.0.11.1:3904
+appc.OAM.service=ueb
+appc.OAM.topic.read=testOAM
+appc.OAM.topic.write=testOAM
+appc.OAM.client.name=testOAM
+appc.OAM.provider.user=admin
+appc.OAM.provider.pass=Kp8bJ4SXszM0WXlhak3eHlcse2gAw84vaoGGmJvUy2U
\ No newline at end of file
diff --git a/main.go b/main.go
new file mode 100644 (file)
index 0000000..59d9634
--- /dev/null
+++ b/main.go
@@ -0,0 +1,32 @@
+/*
+ * 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 main
+
+import (
+       "github.com/gorilla/mux"
+       "distributed-kv-store/api"
+       "log"
+       "net/http"
+)
+
+func main() {
+       router := mux.NewRouter()
+       router.HandleFunc("/loadconfigs", api.HandlePOST).Methods("POST")
+       router.HandleFunc("/getconfig/{key}", api.HandleGET).Methods("GET")
+       router.HandleFunc("/getconfigs", api.HandleGETS).Methods("GET")
+       log.Fatal(http.ListenAndServe(":8080", router))
+}