[ISSUE-67869881] add more test cases
diff --git a/common/cipher.go b/common/cipher.go
index 5e727a2..9235937 100644
--- a/common/cipher.go
+++ b/common/cipher.go
@@ -74,7 +74,7 @@
 }
 
 func (c *KmsCipherManager) startRetrieve(org string, interval time.Duration, timeout time.Duration) {
-
+	timeoutChan := time.After(timeout)
 	if err := c.retrieveKey(org); err != nil {
 		log.Error(err)
 	} else {
@@ -83,7 +83,7 @@
 	ticker := time.NewTicker(interval)
 	for {
 		select {
-		case <-time.After(timeout):
+		case <-timeoutChan:
 			log.Error("timeout when retrieving key")
 			return
 		case <-ticker.C:
@@ -116,7 +116,7 @@
 	if res.StatusCode == http.StatusNotFound {
 		e, err := parseErrorResponse(res)
 		if err != nil {
-			log.Errorf("Failed to parse error response: %v", err)
+			log.Errorf("Failed to parse 404 error response for org %s: %v", org, err)
 			return err
 		}
 		// is this org has no key, stop retrying
@@ -251,8 +251,8 @@
 }
 
 type KeyErrorResponse struct {
-	Code    string
-	Message string
+	Code    string `json:"code"`
+	Message string `json:"message"`
 }
 
 func parseErrorResponse(res *http.Response) (*KeyErrorResponse, error) {
diff --git a/common/cipher_test.go b/common/cipher_test.go
index 62162ad..71ff7d4 100644
--- a/common/cipher_test.go
+++ b/common/cipher_test.go
@@ -15,6 +15,8 @@
 
 import (
 	"encoding/base64"
+	"encoding/json"
+	"encoding/xml"
 	"fmt"
 	"github.com/apid/apid-core/cipher"
 	. "github.com/onsi/ginkgo"
@@ -61,47 +63,155 @@
 
 	Context("Retrieve new key", func() {
 		var server *httptest.Server
-		BeforeEach(func() {
-			// set key server
-			server = httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
-				defer GinkgoRecover()
-				Expect(r.URL.Path).Should(Equal(retrieveEncryptKeyPath))
-				Expect(r.URL.Query().Get(parameterOrganization)).Should(Equal(testOrg))
-				Expect(w.Write([]byte(base64.StdEncoding.EncodeToString(key)))).Should(Equal(24))
-			}))
-			time.Sleep(100 * time.Millisecond)
-			testCipherMan = CreateCipherManager(&http.Client{}, server.URL)
-		})
-
-		AfterEach(func() {
-			server.Close()
-		})
-
-		It("Encryption", func() {
-			Expect(testCipherMan.EncryptBase64(plaingtext, testOrg, cipher.ModeEcb, cipher.PaddingPKCS5)).
-				Should(Equal(cipher64))
-		})
-
-		It("Decryption", func() {
-			Expect(testCipherMan.TryDecryptBase64(cipher64, testOrg)).Should(Equal(plaingtext))
-		})
-
-		It("Retrieve Key", func() {
-			testCipherMan.AddOrgs([]string{testOrg})
-			for {
+		Context("Retrieve new key with lazy method", func() {
+			BeforeEach(func() {
+				// set key server
+				server = httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
+					defer GinkgoRecover()
+					Expect(r.URL.Path).Should(Equal(retrieveEncryptKeyPath))
+					Expect(r.URL.Query().Get(parameterOrganization)).Should(Equal(testOrg))
+					Expect(w.Write([]byte(base64.StdEncoding.EncodeToString(key)))).Should(Equal(24))
+				}))
 				time.Sleep(100 * time.Millisecond)
-				testCipherMan.mutex.RLock()
-				aesCipher := testCipherMan.aes[testOrg]
-				testCipherMan.mutex.RUnlock()
-				if aesCipher != nil {
-					//close server to make sure key was retrieved by "AddOrgs"
-					server.Close()
-					Expect(testCipherMan.EncryptBase64(plaingtext, testOrg, cipher.ModeEcb, cipher.PaddingPKCS5)).
-						Should(Equal(cipher64))
-					return
+				testCipherMan = CreateCipherManager(&http.Client{}, server.URL)
+			})
+
+			AfterEach(func() {
+				server.Close()
+			})
+
+			It("Encryption", func() {
+				Expect(testCipherMan.EncryptBase64(plaingtext, testOrg, cipher.ModeEcb, cipher.PaddingPKCS5)).
+					Should(Equal(cipher64))
+			})
+
+			It("Decryption", func() {
+				Expect(testCipherMan.TryDecryptBase64(cipher64, testOrg)).Should(Equal(plaingtext))
+			})
+		})
+
+		Context("Retrieve new keys during initialization", func() {
+
+			AfterEach(func() {
+				server.Close()
+			})
+
+			It("Retrieve Key happy path", func() {
+				// set key server
+				server = httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
+					defer GinkgoRecover()
+					Expect(r.URL.Path).Should(Equal(retrieveEncryptKeyPath))
+					Expect(r.URL.Query().Get(parameterOrganization)).Should(HavePrefix(testOrg))
+					Expect(w.Write([]byte(base64.StdEncoding.EncodeToString(key)))).Should(Equal(24))
+				}))
+				time.Sleep(100 * time.Millisecond)
+				testCipherMan = CreateCipherManager(&http.Client{}, server.URL)
+
+				//test 2 orgs
+				testOrg1 := testOrg + "_1"
+				testCipherMan.AddOrgs([]string{testOrg, testOrg1})
+				for {
+					time.Sleep(100 * time.Millisecond)
+					testCipherMan.mutex.RLock()
+					l := len(testCipherMan.aes)
+					testCipherMan.mutex.RUnlock()
+					if l == 2 {
+						//close server to make sure key was retrieved by "AddOrgs"
+						server.Close()
+						Expect(testCipherMan.EncryptBase64(plaingtext, testOrg, cipher.ModeEcb, cipher.PaddingPKCS5)).
+							Should(Equal(cipher64))
+						Expect(testCipherMan.EncryptBase64(plaingtext, testOrg1, cipher.ModeEcb, cipher.PaddingPKCS5)).
+							Should(Equal(cipher64))
+						return
+					}
 				}
-			}
-		}, 2)
+			}, 2)
+
+			It("Retrieve Key should retry for internal server error", func() {
+				// set key server
+				count := 0
+				server = httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
+					defer GinkgoRecover()
+					Expect(r.URL.Path).Should(Equal(retrieveEncryptKeyPath))
+					Expect(r.URL.Query().Get(parameterOrganization)).Should(Equal(testOrg))
+					count++
+					if count == 1 {
+						w.WriteHeader(http.StatusInternalServerError)
+						return
+					}
+					if count == 2 {
+						w.WriteHeader(http.StatusNotFound)
+						return
+					}
+					Expect(w.Write([]byte(base64.StdEncoding.EncodeToString(key)))).Should(Equal(24))
+				}))
+				time.Sleep(100 * time.Millisecond)
+				testCipherMan = CreateCipherManager(&http.Client{}, server.URL)
+				testCipherMan.interval = 100 * time.Millisecond
+				//should retry in case of error
+				testCipherMan.AddOrgs([]string{testOrg})
+				for {
+					time.Sleep(100 * time.Millisecond)
+					testCipherMan.mutex.RLock()
+					aes := testCipherMan.aes[testOrg]
+					testCipherMan.mutex.RUnlock()
+					if aes != nil {
+						//close server to make sure key was retrieved by "AddOrgs"
+						server.Close()
+						Expect(testCipherMan.EncryptBase64(plaingtext, testOrg, cipher.ModeEcb, cipher.PaddingPKCS5)).
+							Should(Equal(cipher64))
+						return
+					}
+				}
+			}, 2)
+
+			It("Retrieve Key should stop retrying for JSON organizations.EncryptionKeyDoesNotExist", func() {
+				// set key server
+				server = httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
+					defer GinkgoRecover()
+					Expect(r.URL.Path).Should(Equal(retrieveEncryptKeyPath))
+					Expect(r.URL.Query().Get(parameterOrganization)).Should(Equal(testOrg))
+
+					response := KeyErrorResponse{
+						Code:    errorCodeNoKey,
+						Message: fmt.Sprintf("Encryption key does not exist for the org [%s].", testOrg),
+					}
+					bytes, err := json.Marshal(response)
+					Expect(err).Should(Succeed())
+					w.Header().Set(headerContentType, typeJson)
+					w.WriteHeader(http.StatusNotFound)
+					Expect(w.Write(bytes)).Should(Equal(len(bytes)))
+				}))
+				time.Sleep(100 * time.Millisecond)
+				testCipherMan = CreateCipherManager(&http.Client{}, server.URL)
+				//should stop retrying after one try
+				testCipherMan.startRetrieve(testOrg, 100*time.Millisecond, 10*time.Minute)
+			}, 2)
+
+			It("Retrieve Key should stop retrying for XML organizations.EncryptionKeyDoesNotExist", func() {
+				// set key server
+				server = httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
+					defer GinkgoRecover()
+					Expect(r.URL.Path).Should(Equal(retrieveEncryptKeyPath))
+					Expect(r.URL.Query().Get(parameterOrganization)).Should(Equal(testOrg))
+
+					response := KeyErrorResponse{
+						Code:    errorCodeNoKey,
+						Message: fmt.Sprintf("Encryption key does not exist for the org [%s].", testOrg),
+					}
+					bytes, err := xml.Marshal(response)
+					Expect(err).Should(Succeed())
+					w.Header().Set(headerContentType, typeXml)
+					w.WriteHeader(http.StatusNotFound)
+					Expect(w.Write(bytes)).Should(Equal(len(bytes)))
+				}))
+				time.Sleep(100 * time.Millisecond)
+				testCipherMan = CreateCipherManager(&http.Client{}, server.URL)
+				//should stop retrying after one try
+				testCipherMan.startRetrieve(testOrg, 100*time.Millisecond, 10*time.Minute)
+			}, 2)
+		})
+
 	})
 
 	Context("IsEncrypted", func() {