summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--.gitignore5
-rw-r--r--.gitreview4
-rw-r--r--Gopkg.lock75
-rw-r--r--Gopkg.toml42
-rw-r--r--README.md4
-rw-r--r--api/consulConnection.go113
-rw-r--r--api/consulConnection_test.go19
-rw-r--r--api/endpointViews.go108
-rw-r--r--api/endpointViews_test.go58
-rw-r--r--api/propertiesReader.go73
-rw-r--r--api/propertiesReader_test.go19
-rw-r--r--api/utils.go101
-rw-r--r--api/utils_test.go19
-rw-r--r--configurations/sampleAAIConfig.properties94
-rw-r--r--configurations/sampleAPPCConfig.properties113
-rw-r--r--main.go32
16 files changed, 879 insertions, 0 deletions
diff --git a/.gitignore b/.gitignore
new file mode 100644
index 0000000..879e9b6
--- /dev/null
+++ b/.gitignore
@@ -0,0 +1,5 @@
+.idea/
+*.iml
+consul
+.DS_Store
+vendor/
diff --git a/.gitreview b/.gitreview
new file mode 100644
index 0000000..dd44c66
--- /dev/null
+++ b/.gitreview
@@ -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
index 0000000..33c42f6
--- /dev/null
+++ b/Gopkg.lock
@@ -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
index 0000000..3f608e7
--- /dev/null
+++ b/Gopkg.toml
@@ -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
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
index 0000000..b8074e2
--- /dev/null
+++ b/api/consulConnection.go
@@ -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
index 0000000..342542a
--- /dev/null
+++ b/api/consulConnection_test.go
@@ -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
index 0000000..3c47ee5
--- /dev/null
+++ b/api/endpointViews.go
@@ -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
index 0000000..f603af4
--- /dev/null
+++ b/api/endpointViews_test.go
@@ -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
index 0000000..018dabe
--- /dev/null
+++ b/api/propertiesReader.go
@@ -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
index 0000000..c564be5
--- /dev/null
+++ b/api/propertiesReader_test.go
@@ -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
index 0000000..8b87848
--- /dev/null
+++ b/api/utils.go
@@ -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
index 0000000..c564be5
--- /dev/null
+++ b/api/utils_test.go
@@ -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
index 0000000..6052315
--- /dev/null
+++ b/configurations/sampleAAIConfig.properties
@@ -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
index 0000000..484337f
--- /dev/null
+++ b/configurations/sampleAPPCConfig.properties
@@ -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
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))
+}