[ISSUE-67869881] update url path
diff --git a/common/cipher.go b/common/cipher.go
index 0b665df..f67b893 100644
--- a/common/cipher.go
+++ b/common/cipher.go
@@ -15,6 +15,8 @@
 
 import (
 	"encoding/base64"
+	"encoding/json"
+	"encoding/xml"
 	"fmt"
 	"github.com/apid/apid-core/cipher"
 	"io/ioutil"
@@ -26,12 +28,21 @@
 )
 
 const RegEncrypted = `^\{[0-9A-Za-z]+/[0-9A-Za-z]+/[0-9A-Za-z]+\}.`
-const retrieveEncryptKeyPath = "/encryptionkey"
+const retrieveEncryptKeyPath = "/config/organizations/{org}/kmsencryptionkey"
 const EncryptAes = "AES"
-const retrieveKeyRetryInterval = time.Duration(5 * time.Second)
-const retrieveKeyTimeout = time.Duration(5 * time.Minute)
+
+const (
+	retrieveKeyRetryInterval = time.Duration(5 * time.Second)
+	retrieveKeyTimeout       = time.Duration(5 * time.Minute)
+)
 const parameterOrganization = "organization"
 const configBearerToken = "apigeesync_bearer_token"
+const headerContentType = "Content-Type"
+const (
+	typeJson = "application/json"
+	typeXml  = "text/xml"
+)
+const errorCodeNoKey = "organizations.EncryptionKeyDoesNotExist"
 
 var RegexpEncrypted = regexp.MustCompile(RegEncrypted)
 
@@ -80,6 +91,7 @@
 			return
 		case <-ticker.C:
 			if err := c.retrieveKey(org); err != nil {
+
 				log.Error(err)
 			} else {
 				return
@@ -90,10 +102,11 @@
 
 func (c *KmsCipherManager) retrieveKey(org string) error {
 	var key []byte
-	req, err := http.NewRequest(http.MethodGet, c.serverUrlBase+retrieveEncryptKeyPath, nil)
-	pars := req.URL.Query()
-	pars[parameterOrganization] = []string{org}
-	req.URL.RawQuery = pars.Encode()
+	path := strings.Replace(retrieveEncryptKeyPath, "{org}", org, 1)
+	req, err := http.NewRequest(http.MethodGet, c.serverUrlBase+path, nil)
+	//pars := req.URL.Query()
+	//pars[parameterOrganization] = []string{org}
+	//req.URL.RawQuery = pars.Encode()
 	req.Header.Set("Authorization", "Bearer "+services.Config().GetString(configBearerToken))
 	log.Debugf("Retrieving key: %s", req.URL.String())
 	if err != nil {
@@ -103,6 +116,21 @@
 	if err != nil {
 		return fmt.Errorf("failed to retrieve key for org=%s : %v", org, err)
 	}
+
+	// if 404
+	if res.StatusCode == http.StatusNotFound {
+		e, err := parseErrorResponse(res)
+		if err != nil {
+			log.Errorf("Failed to parse error response: %v", err)
+			return err
+		}
+		// is this org has no key, stop retrying
+		if e.Code == errorCodeNoKey {
+			log.Debugf("No key is associated with org %v", org)
+			return nil
+		}
+	}
+
 	if res.StatusCode != http.StatusOK {
 		err = fmt.Errorf("failed to retrieve key for org [%v] with status: %v", org, res.Status)
 		return fmt.Errorf("failed to retrieve key for org [%v] with status: %v", org, res.Status)
@@ -130,6 +158,7 @@
 	return nil
 }
 
+// return val is nullable
 func (c *KmsCipherManager) getAesCipher(org string) *cipher.AesCipher {
 	// if exists
 	c.mutex.RLock()
@@ -139,7 +168,10 @@
 	}
 	// if not exists
 	c.mutex.RUnlock()
-	c.startRetrieve(org, c.interval, c.timeout)
+	if err := c.retrieveKey(org); err != nil {
+		log.Errorf("Failed to get encryption key for org=%s : %v", org, err)
+		return nil
+	}
 	c.mutex.RLock()
 	defer c.mutex.RUnlock()
 	return c.aes[org]
@@ -165,7 +197,12 @@
 		log.Errorf("Decode base64 of [%v] failed: [%v], considered as unencrypted!", text, err)
 		return
 	}
-	plaintext, err := c.getAesCipher(org).Decrypt(bytes, mode, padding)
+	aes := c.getAesCipher(org)
+	if aes == nil {
+		err = fmt.Errorf("failed to get decryption key for org: %s", org)
+		return
+	}
+	plaintext, err := aes.Decrypt(bytes, mode, padding)
 	if err != nil {
 		log.Errorf("Decrypt of [%v] failed: [%v], considered as unencrypted!", bytes, err)
 		return
@@ -178,7 +215,13 @@
 // The returned string is the base64 encoding of the encrypted input, prepended with algorithm.
 // An example output is "{AES/ECB/PKCS5Padding}2jX3V3dQ5xB9C9Zl9sqyo8pmkvVP10rkEVPVhmnLHw4="
 func (c *KmsCipherManager) EncryptBase64(input string, org string, mode cipher.Mode, padding cipher.Padding) (output string, err error) {
-	ciphertext, err := c.getAesCipher(org).Encrypt([]byte(input), mode, padding)
+	aes := c.getAesCipher(org)
+	// TODO: make sure this logic is expected
+	// if failed to get key and cipher, considered this org as unencrypted
+	if aes == nil {
+		return input, nil
+	}
+	ciphertext, err := aes.Encrypt([]byte(input), mode, padding)
 	if err != nil {
 		return
 	}
@@ -214,3 +257,25 @@
 	padding = cipher.Padding(l[2])
 	return
 }
+
+type ErrorRes struct {
+	Code    string
+	Message string
+}
+
+func parseErrorResponse(res *http.Response) (*ErrorRes, error) {
+	contentType := res.Header.Get("Content-Type")
+	defer res.Body.Close()
+	body, err := ioutil.ReadAll(res.Body)
+	if err != nil {
+		return nil, err
+	}
+	ret := &ErrorRes{}
+	if contentType == typeJson {
+		return ret, json.Unmarshal(body, ret)
+	} else if contentType == typeXml {
+		return ret, xml.Unmarshal(body, ret)
+	} else {
+		return nil, fmt.Errorf("unknown error: %v", string(body))
+	}
+}
diff --git a/common/data_test.go b/common/data_test.go
index 4a3ecdc..7070890 100644
--- a/common/data_test.go
+++ b/common/data_test.go
@@ -19,6 +19,7 @@
 	. "github.com/onsi/gomega"
 	"io/ioutil"
 	"reflect"
+	"sort"
 	"sync"
 )
 
@@ -53,6 +54,13 @@
 			Expect(len(attributes["test-invalid"])).Should(BeEquivalentTo(0))
 		})
 
+		It("Should get all orgs", func() {
+			orgs, err := testDbMan.GetOrgs()
+			Expect(err).Should(Succeed())
+			sort.Strings(orgs)
+			Expect(orgs).Should(Equal([]string{"apid-haoming", "apid-test"}))
+		})
+
 	})
 
 	Context("Validate common.JsonToStringArray", func() {
diff --git a/common/data_test.sql b/common/data_test.sql
index 1a12c2f..1b5349b 100644
--- a/common/data_test.sql
+++ b/common/data_test.sql
@@ -24,4 +24,9 @@
 INSERT INTO "kms_attributes" VALUES('bc811169','50321842-d6ee-4e92-91b9-37234a7920c1','','','','','50321842-d6ee-4e92-91b9-37234a7920c1','','','Threshold','APIPRODUCT','TX100','bc811169');
 INSERT INTO "kms_attributes" VALUES('bc811169','40753e12-a50a-429d-9121-e571eb4e43a9','','','','','40753e12-a50a-429d-9121-e571eb4e43a9','','','access','APIPRODUCT','public','bc811169');
 INSERT INTO "kms_attributes" VALUES('bc811169','2d373ed6-e38f-453b-bb34-6d731d9c4815','','','','','','2d373ed6-e38f-453b-bb34-6d731d9c4815','','DisplayName','APP','demo-app','bc811169');
+CREATE TABLE kms_organization (id text,name text,display_name text,type text,tenant_id text,customer_id text,description text,created_at blob,created_by text,updated_at blob,updated_by text,_change_selector text, primary key (id,tenant_id));
+INSERT INTO "kms_organization" VALUES('e2cc4caf-40d6-4ecb-8149-ed32d04184b2','apid-haoming','apid-haoming','paid','515211e9','94cd5075-7f33-4afb-9545-a53a254277a1','','2017-08-16 22:16:06.544+00:00','foobar@google.com','2017-08-16 22:29:23.046+00:00','foobar@google.com','515211e9');
+CREATE TABLE edgex_data_scope (id text,apid_cluster_id text,scope text,org text,env text,created blob,created_by text,updated blob,updated_by text,_change_selector text,org_scope text,env_scope text, primary key (id));
+INSERT INTO "edgex_data_scope" VALUES('cc066263-6355-416d-9d59-7f3135d64953','543230f1-8c41-4bf5-94a3-f10c104ff5d4','155211e9','apid-haoming','test','2017-08-27 22:53:33.859+00:00','foobar@google.com','2017-08-27 22:53:33.859+00:00','foobar@google.com','543230f1-8c41-4bf5-94a3-f10c104ff5d4','12344caf-40d6-4ecb-8149-ed32d04184b2','1234203e-ba88-4cd5-967d-4caa88f64909');
+INSERT INTO "edgex_data_scope" VALUES('08c81eeb-57ec-43fe-8fed-cdff5494406f','123430f1-8c41-4bf5-94a3-f10c104ff5d4','165211e9','apid-test','prod','2017-08-29 02:39:34.093+00:00','foobar@google.com','2017-08-29 02:39:34.093+00:00','foobar@google.com','123430f1-8c41-4bf5-94a3-f10c104ff5d4','43214caf-40d6-4ecb-8149-ed32d04184b2','43211cae-f2a6-4663-9f36-eb17d76e6c32');
 COMMIT;