Merge pull request #7 from 30x/XAPID-794

Xapid 794
diff --git a/api.go b/api.go
index 3d47d52..b2b21f0 100644
--- a/api.go
+++ b/api.go
@@ -13,9 +13,10 @@
 	ExpiresAt       int64  `json:"expiresAt"`
 	IssuedAt        int64  `json:"issuedAt"`
 	Status          string `json:"status"`
+	Type            string `json:"cType"`
 	RedirectionURIs string `json:"redirectionURIs"`
-	DeveloperAppId  string `json:"developerId"`
-	DeveloperAppNam string `json:"developerAppName"`
+	AppId           string `json:"appId"`
+	AppName         string `json:"appName"`
 }
 
 type errResultDetail struct {
@@ -75,7 +76,6 @@
 // returns []byte to be written to client
 func verifyAPIKey(f url.Values) ([]byte, error) {
 
-
 	key := f.Get("key")
 	scopeuuid := f.Get("scopeuuid")
 	path := f.Get("uriPath")
@@ -105,21 +105,66 @@
 		return errorResponse(reason, errorCode)
 	}
 
-	log.Debug("Found tenant_id='", tenantId, "' with env='", env, "' for scopeuuid='", scopeuuid,"'")
+	log.Debug("Found tenant_id='", tenantId, "' with env='", env, "' for scopeuuid='", scopeuuid, "'")
 
-	sSql := "SELECT ap.api_resources, ap.environments, c.issued_at, c.status, a.callback_url, d.username, d.id " +
-		"FROM APP_CREDENTIAL AS c INNER JOIN APP AS a ON c.app_id = a.id " +
-		"INNER JOIN DEVELOPER AS d ON a.developer_id = d.id " +
-		"INNER JOIN APP_CREDENTIAL_APIPRODUCT_MAPPER as mp ON mp.appcred_id = c.id " +
-		"INNER JOIN API_PRODUCT as ap ON ap.id = mp.apiprdt_id " +
-		"WHERE (UPPER(d.status) = 'ACTIVE' AND mp.apiprdt_id = ap.id AND mp.app_id = a.id " +
-		"AND mp.appcred_id = c.id AND UPPER(mp.status) = 'APPROVED' AND UPPER(a.status) = 'APPROVED' " +
-		"AND c.id = $1 AND c.tenant_id = $2);"
+	sSql := `
+		SELECT
+			ap.api_resources, 
+			ap.environments, 
+			c.issued_at,
+			c.status,
+			a.callback_url,
+			ad.email,
+			ad.id,
+			"developer" as ctype
+		FROM
+			APP_CREDENTIAL AS c 
+			INNER JOIN APP AS a ON c.app_id = a.id
+			INNER JOIN DEVELOPER AS ad 
+				ON ad.id = a.developer_id
+			INNER JOIN APP_CREDENTIAL_APIPRODUCT_MAPPER as mp 
+				ON mp.appcred_id = c.id 
+			INNER JOIN API_PRODUCT as ap ON ap.id = mp.apiprdt_id
+		WHERE (UPPER(ad.status) = 'ACTIVE' 
+			AND mp.apiprdt_id = ap.id 
+			AND mp.app_id = a.id
+			AND mp.appcred_id = c.id 
+			AND UPPER(mp.status) = 'APPROVED' 
+			AND UPPER(a.status) = 'APPROVED'
+			AND c.id = $1 
+			AND c.tenant_id = $2)
+		UNION ALL
+		SELECT
+			ap.api_resources,
+			ap.environments,
+			c.issued_at,
+			c.status,
+			a.callback_url,
+			ad.name,
+			ad.id,
+			"company" as ctype
+		FROM
+			APP_CREDENTIAL AS c
+			INNER JOIN APP AS a ON c.app_id = a.id
+			INNER JOIN COMPANY AS ad
+				ON ad.id = a.company_id
+			INNER JOIN APP_CREDENTIAL_APIPRODUCT_MAPPER as mp
+				ON mp.appcred_id = c.id
+			INNER JOIN API_PRODUCT as ap ON ap.id = mp.apiprdt_id
+		WHERE (UPPER(ad.status) = 'ACTIVE'
+			AND mp.apiprdt_id = ap.id
+			AND mp.app_id = a.id
+			AND mp.appcred_id = c.id
+			AND UPPER(mp.status) = 'APPROVED'
+			AND UPPER(a.status) = 'APPROVED'
+			AND c.id = $1
+			AND c.tenant_id = $2)
+	;`
 
-	var status, redirectionURIs, developerAppName, developerId, resName, resEnv string
+	var status, redirectionURIs, appName, appId, resName, resEnv, cType string
 	var issuedAt int64
 	err := db.QueryRow(sSql, key, tenantId).Scan(&resName, &resEnv, &issuedAt, &status,
-		&redirectionURIs, &developerAppName, &developerId)
+		&redirectionURIs, &appName, &appId, &cType)
 	switch {
 	case err == sql.ErrNoRows:
 		reason := "API Key verify failed for (" + key + ", " + scopeuuid + ", " + path + ")"
@@ -161,8 +206,9 @@
 			IssuedAt:        issuedAt,
 			Status:          status,
 			RedirectionURIs: redirectionURIs,
-			DeveloperAppId:  developerId,
-			DeveloperAppNam: developerAppName},
+			Type:            cType,
+			AppId:           appId,
+			AppName:         appName},
 	}
 	return json.Marshal(resp)
 }
diff --git a/api_test.go b/api_test.go
index 87430a8..7222341 100644
--- a/api_test.go
+++ b/api_test.go
@@ -32,25 +32,12 @@
 				res := insertDevelopers([]common.Row{row}, txn)
 				Expect(res).Should(BeTrue())
 			}
-			// companies
-			for i := 0; i < 10; i++ {
-				row := generateTestCompany(i)
-				res := insertCompanies([]common.Row{row}, txn)
-				Expect(res).Should(BeTrue())
-			}
-
-			// company developers
-			for i := 0; i < 10; i++ {
-				row := generateTestCompanyDeveloper(i);
-				res := insertCompanyDevelopers([]common.Row{row}, txn)
-				Expect(res).Should(BeTrue())
-			}
 
 			// application
 			var j, k int
 			for i := 0; i < 10; i++ {
 				for j = k; j < 10+k; j++ {
-					row := generateTestApp(j, i);
+					row := generateTestApp(j, i)
 					res := insertApplications([]common.Row{row}, txn)
 					Expect(res).Should(BeTrue())
 				}
@@ -69,6 +56,51 @@
 				Expect(res).Should(BeTrue())
 			}
 
+			// Following are data for company
+			// api products
+			for i := 100; i < 110; i++ {
+				row := generateTestApiProduct(i)
+				res := insertAPIproducts([]common.Row{row}, txn)
+				Expect(res).Should(BeTrue())
+			}
+
+			// companies
+			for i := 100; i < 110; i++ {
+				row := generateTestCompany(i)
+				res := insertCompanies([]common.Row{row}, txn)
+				Expect(res).Should(BeTrue())
+			}
+
+			// company developers
+			for i := 100; i < 110; i++ {
+				row := generateTestCompanyDeveloper(i)
+				res := insertCompanyDevelopers([]common.Row{row}, txn)
+				Expect(res).Should(BeTrue())
+			}
+
+			// application
+			k = 100
+			for i := 100; i < 110; i++ {
+				for j = k; j < 100+k; j++ {
+					row := generateTestAppCompany(j, i)
+					res := insertApplications([]common.Row{row}, txn)
+					Expect(res).Should(BeTrue())
+				}
+				k = j
+			}
+			// app credentials
+			for i := 100; i < 110; i++ {
+				row := generateTestAppCreds(i)
+				res := insertCredentials([]common.Row{row}, txn)
+				Expect(res).Should(BeTrue())
+			}
+			// api product mapper
+			for i := 100; i < 110; i++ {
+				row := generateTestApiProductMapper(i)
+				res := insertAPIProductMappers([]common.Row{row}, txn)
+				Expect(res).Should(BeTrue())
+			}
+
 			txn.Commit()
 			var count int64
 			db.QueryRow("select count(*) from data_scope").Scan(&count)
@@ -93,7 +125,7 @@
 
 		})
 
-		It("should successfully verify good keys", func() {
+		It("should successfully verify good Developer keys", func() {
 			for i := 1; i < 10; i++ {
 				resulti := strconv.FormatInt(int64(i), 10)
 				v := url.Values{
@@ -108,6 +140,27 @@
 				var respj kmsResponseSuccess
 				json.Unmarshal(rsp, &respj)
 				Expect(respj.Type).Should(Equal("APIKeyContext"))
+				Expect(respj.RspInfo.Type).Should(Equal("developer"))
+				Expect(respj.RspInfo.Key).Should(Equal("app_credential_" + resulti))
+			}
+		})
+
+		It("should successfully verify good Company keys", func() {
+			for i := 100; i < 110; i++ {
+				resulti := strconv.FormatInt(int64(i), 10)
+				v := url.Values{
+					"key":       []string{"app_credential_" + resulti},
+					"uriPath":   []string{"/test"},
+					"scopeuuid": []string{"ABCDE"},
+					"action":    []string{"verify"},
+				}
+				rsp, err := verifyAPIKey(v)
+				Expect(err).ShouldNot(HaveOccurred())
+
+				var respj kmsResponseSuccess
+				json.Unmarshal(rsp, &respj)
+				Expect(respj.Type).Should(Equal("APIKeyContext"))
+				Expect(respj.RspInfo.Type).Should(Equal("company"))
 				Expect(respj.RspInfo.Key).Should(Equal("app_credential_" + resulti))
 			}
 		})
@@ -118,7 +171,7 @@
 			Expect(err).ShouldNot(HaveOccurred())
 
 			for i := 0; i < 10; i++ {
-				row := generateTestApiProductMapper(i);
+				row := generateTestApiProductMapper(i)
 				res := deleteAPIproductMapper(row, txn)
 				Expect(res).Should(BeTrue())
 			}
@@ -146,7 +199,7 @@
 				Expect(res).Should(BeTrue())
 			}
 
-			for i := 0; i < 10; i++ {
+			for i := 100; i < 110; i++ {
 				row := generateTestCompanyDeveloper(i)
 				res := deleteCompanyDeveloper(row, txn)
 				Expect(res).Should(BeTrue())
diff --git a/apidVerifyAPIKey-api.yaml b/apidVerifyAPIKey-api.yaml
index f0a1841..b351771 100644
--- a/apidVerifyAPIKey-api.yaml
+++ b/apidVerifyAPIKey-api.yaml
@@ -62,8 +62,9 @@
                 issuedAt: 1234567890
                 status: abc123
                 redirectionURIs: abc123
-                developerAppName: abc123
-                developerId: abc123
+                appName: abc123
+                appId: abc123
+                cType: "developer"
         default:
           description: 4xx or 5xx errors
           schema:
@@ -132,9 +133,11 @@
                 type: string
               redirectionURIs:
                 type: string
-              developerAppName:
+              appName:
                 type: string
-              developerId:
+              appId:
+                type: string
+              cType:
                 type: string
     example:
       type: "APIKeyContext"
@@ -144,8 +147,9 @@
         issuedAt: 1234567890
         status: "abc123"
         redirectionURIs: "abc123"
-        developerAppName: "abc123"
-        developerId: "abc123"
+        appName: "abc123"
+        appId: "abc123"
+        cType: "company OR developer"
 
   VerifyAPIKeyResponseFailed:
     allOf:
diff --git a/init.go b/init.go
index 823158f..7a1ad38 100644
--- a/init.go
+++ b/init.go
@@ -124,6 +124,7 @@
     status text,
     app_family text,
     company_id text,
+    parent_id text,
     developer_id text,
     type int,
     created_at int64,
@@ -155,6 +156,7 @@
     status text,
     PRIMARY KEY (appcred_id, app_id, apiprdt_id,tenant_id)
 );
+CREATE INDEX IF NOT EXISTS company_id ON company (id);
 CREATE INDEX IF NOT EXISTS developer_id ON developer (id);
 CREATE INDEX IF NOT EXISTS api_product_id ON api_product (id);
 CREATE INDEX IF NOT EXISTS app_id ON app (id);
diff --git a/listener.go b/listener.go
index 749160f..da921ab 100644
--- a/listener.go
+++ b/listener.go
@@ -65,6 +65,10 @@
 				ok = insertAPIproducts(payload.Rows, txn)
 			case "kms.app_credential_apiproduct_mapper":
 				ok = insertAPIProductMappers(payload.Rows, txn)
+			case "kms.company":
+				ok = insertCompanies(payload.Rows, txn)
+			case "kms.company_developer":
+				ok = insertCompanyDevelopers(payload.Rows, txn)
 			}
 			if !ok {
 				log.Error("Error encountered in Downloading Snapshot for VerifyApiKey")
@@ -134,10 +138,10 @@
  */
 func insertApplications(rows []common.Row, txn *sql.Tx) bool {
 
-	var scope, EntityIdentifier, DeveloperId, CallbackUrl, Status, AppName, AppFamily, tenantId, CreatedBy, LastModifiedBy string
+	var scope, EntityIdentifier, DeveloperId, CompanyId, ParentId, CallbackUrl, Status, AppName, AppFamily, tenantId, CreatedBy, LastModifiedBy string
 	var CreatedAt, LastModifiedAt int64
 
-	prep, err := txn.Prepare("INSERT INTO APP (_change_selector, id, developer_id,callback_url,status, name, app_family, created_at, created_by,updated_at, updated_by,tenant_id) VALUES($1,$2,$3,$4,$5,$6,$7,$8,$9,$10,$11,$12);")
+	prep, err := txn.Prepare("INSERT INTO APP (_change_selector, id, developer_id, company_id, parent_id, callback_url,status, name, app_family, created_at, created_by,updated_at, updated_by,tenant_id) VALUES($1,$2,$3,$4,$5,$6,$7,$8,$9,$10,$11,$12,$13,$14);")
 	if err != nil {
 		log.Error("INSERT APP Failed: ", err)
 		return false
@@ -149,6 +153,8 @@
 		ele.Get("_change_selector", &scope)
 		ele.Get("id", &EntityIdentifier)
 		ele.Get("developer_id", &DeveloperId)
+		ele.Get("company_id", &CompanyId)
+		ele.Get("parent_id", &ParentId)
 		ele.Get("callback_url", &CallbackUrl)
 		ele.Get("status", &Status)
 		ele.Get("name", &AppName)
@@ -168,6 +174,8 @@
 			scope,
 			EntityIdentifier,
 			DeveloperId,
+			CompanyId,
+			ParentId,
 			CallbackUrl,
 			Status,
 			AppName,
diff --git a/listener_test.go b/listener_test.go
index 03641b2..72e76f2 100644
--- a/listener_test.go
+++ b/listener_test.go
@@ -11,7 +11,7 @@
 
 var _ = Describe("listener", func() {
 
-	Context("KMS create/updates verification via changes", func() {
+	Context("KMS create/updates verification via changes for Developer", func() {
 		It("Create KMS tables via changes, and Verify via verifyApiKey", func(done Done) {
 			var event = common.ChangeList{}
 			closed := 0
@@ -50,45 +50,6 @@
 				},
 			}
 
-			companyItems := common.Row{
-				"id": {
-					Value: "ch_company_id_2",
-				},
-				"status": {
-					Value: "Active",
-				},
-				"tenant_id": {
-					Value: "tenant_id_0",
-				},
-				"_change_selector": {
-					Value: "test_org0",
-				},
-				"name": {
-					Value: "test_company_name0",
-				},
-				"display_name": {
-					Value: "test_company_display_name0",
-				},
-			}
-
-			companyDeveloperItems := common.Row{
-				"id": {
-					Value: "ch_developer_id_2",
-				},
-				"tenant_id": {
-					Value: "tenant_id_0",
-				},
-				"_change_selector": {
-					Value: "test_org0",
-				},
-				"company_id": {
-					Value: "ch_company_id_2",
-				},
-				"developer_id": {
-					Value: "ch_developer_id_2",
-				},
-			}
-
 			/* APP */
 			appItems := common.Row{
 				"id": {
@@ -106,6 +67,9 @@
 				"_change_selector": {
 					Value: "test_org0",
 				},
+				"parent_id": {
+					Value: "ch_developer_id_2",
+				},
 			}
 
 			/* CRED */
@@ -175,16 +139,6 @@
 					NewRow:    mpItems,
 					Operation: 1,
 				},
-				{
-					Table:     "kms.company",
-					NewRow:    companyItems,
-					Operation: 1,
-				},
-				{
-					Table:     "kms.company_developer",
-					NewRow:    companyDeveloperItems,
-					Operation: 1,
-				},
 			}
 
 			h := &test_handler{
@@ -209,6 +163,7 @@
 					json.Unmarshal(rsp, &respj)
 					Expect(respj.Type).Should(Equal("APIKeyContext"))
 					Expect(respj.RspInfo.Key).Should(Equal("ch_app_credential_2"))
+					Expect(respj.RspInfo.Type).Should(Equal("developer"))
 					closed = 1
 					close(done)
 				},
@@ -220,7 +175,201 @@
 		})
 	})
 
-	It("Modify tables in KMS tables, and verify via verifyApiKey", func(done Done) {
+	Context("KMS create/updates verification via changes for Company", func() {
+		It("Create KMS tables via changes, and Verify via verifyApiKey", func(done Done) {
+			var event = common.ChangeList{}
+			closed := 0
+			/* API Product */
+			srvItems := common.Row{
+				"id": {
+					Value: "ch_api_product_5",
+				},
+				"api_resources": {
+					Value: "{}",
+				},
+				"environments": {
+					Value: "{Env_0, Env_1}",
+				},
+				"tenant_id": {
+					Value: "tenant_id_0",
+				},
+				"_change_selector": {
+					Value: "test_org0",
+				},
+			}
+
+			/* COMPANY */
+			companyItems := common.Row{
+				"id": {
+					Value: "ch_company_id_5",
+				},
+				"status": {
+					Value: "Active",
+				},
+				"tenant_id": {
+					Value: "tenant_id_0",
+				},
+				"_change_selector": {
+					Value: "test_org0",
+				},
+				"name": {
+					Value: "test_company_name0",
+				},
+				"display_name": {
+					Value: "test_company_display_name0",
+				},
+			}
+			/* COMPANY_DEVELOPER */
+			companyDeveloperItems := common.Row{
+				"id": {
+					Value: "ch_developer_id_5",
+				},
+				"tenant_id": {
+					Value: "tenant_id_0",
+				},
+				"_change_selector": {
+					Value: "test_org0",
+				},
+				"company_id": {
+					Value: "ch_company_id_5",
+				},
+				"developer_id": {
+					Value: "ch_developer_id_5",
+				},
+			}
+
+			/* APP */
+			appItems := common.Row{
+				"id": {
+					Value: "ch_application_id_5",
+				},
+				"company_id": {
+					Value: "ch_company_id_5",
+				},
+				"status": {
+					Value: "Approved",
+				},
+				"tenant_id": {
+					Value: "tenant_id_0",
+				},
+				"_change_selector": {
+					Value: "test_org0",
+				},
+				"parent_id": {
+					Value: "ch_company_id_5",
+				},
+			}
+
+			/* CRED */
+			credItems := common.Row{
+				"id": {
+					Value: "ch_app_credential_5",
+				},
+				"app_id": {
+					Value: "ch_application_id_5",
+				},
+				"tenant_id": {
+					Value: "tenant_id_0",
+				},
+				"status": {
+					Value: "Approved",
+				},
+				"_change_selector": {
+					Value: "test_org0",
+				},
+			}
+
+			/* APP_CRED_APIPRD_MAPPER */
+			mpItems := common.Row{
+				"apiprdt_id": {
+					Value: "ch_api_product_5",
+				},
+				"app_id": {
+					Value: "ch_application_id_5",
+				},
+				"appcred_id": {
+					Value: "ch_app_credential_5",
+				},
+				"status": {
+					Value: "Approved",
+				},
+				"_change_selector": {
+					Value: "test_org0",
+				},
+				"tenant_id": {
+					Value: "tenant_id_0",
+				},
+			}
+
+			event.Changes = []common.Change{
+				{
+					Table:     "kms.api_product",
+					NewRow:    srvItems,
+					Operation: 1,
+				},
+
+				{
+					Table:     "kms.app",
+					NewRow:    appItems,
+					Operation: 1,
+				},
+				{
+					Table:     "kms.app_credential",
+					NewRow:    credItems,
+					Operation: 1,
+				},
+				{
+					Table:     "kms.app_credential_apiproduct_mapper",
+					NewRow:    mpItems,
+					Operation: 1,
+				},
+				{
+					Table:     "kms.company",
+					NewRow:    companyItems,
+					Operation: 1,
+				},
+				{
+					Table:     "kms.company_developer",
+					NewRow:    companyDeveloperItems,
+					Operation: 1,
+				},
+			}
+
+			h := &test_handler{
+				"checkDatabase post Insertion",
+				func(e apid.Event) {
+					defer GinkgoRecover()
+
+					// ignore the first event, let standard listener process it
+					changeSet := e.(*common.ChangeList)
+					if len(changeSet.Changes) > 0 || closed == 1 {
+						return
+					}
+					v := url.Values{
+						"key":       []string{"ch_app_credential_5"},
+						"uriPath":   []string{"/test"},
+						"scopeuuid": []string{"XYZ"},
+						"action":    []string{"verify"},
+					}
+					rsp, err := verifyAPIKey(v)
+					Expect(err).ShouldNot(HaveOccurred())
+					var respj kmsResponseSuccess
+					json.Unmarshal(rsp, &respj)
+					Expect(respj.RspInfo.Type).Should(Equal("company"))
+					Expect(respj.Type).Should(Equal("APIKeyContext"))
+					Expect(respj.RspInfo.Key).Should(Equal("ch_app_credential_5"))
+					closed = 1
+					close(done)
+				},
+			}
+
+			apid.Events().Listen("ApigeeSync", h)
+			apid.Events().Emit("ApigeeSync", &event)
+			apid.Events().Emit("ApigeeSync", &common.ChangeList{})
+		})
+	})
+
+	It("Modify tables in KMS tables, and verify via verifyApiKey for Developer", func(done Done) {
 		closed := 0
 		var event = common.ChangeList{}
 		var event2 = common.ChangeList{}
@@ -278,8 +427,311 @@
 			"_change_selector": {
 				Value: "test_org0",
 			},
+			"parent_id": {
+				Value: "ch_developer_id_0",
+			},
 		}
 
+		/* CRED */
+		credItemsOld := common.Row{
+			"id": {
+				Value: "ch_app_credential_0",
+			},
+			"app_id": {
+				Value: "ch_application_id_0",
+			},
+			"tenant_id": {
+				Value: "tenant_id_0",
+			},
+			"status": {
+				Value: "Approved",
+			},
+			"_change_selector": {
+				Value: "test_org0",
+			},
+		}
+
+		/* APP_CRED_APIPRD_MAPPER */
+		mpItemsOld := common.Row{
+			"apiprdt_id": {
+				Value: "ch_api_product_0",
+			},
+			"app_id": {
+				Value: "ch_application_id_0",
+			},
+			"appcred_id": {
+				Value: "ch_app_credential_0",
+			},
+			"status": {
+				Value: "Approved",
+			},
+			"_change_selector": {
+				Value: "test_org0",
+			},
+			"tenant_id": {
+				Value: "tenant_id_0",
+			},
+		}
+
+		/* New to be replaced data */
+		/* API PRODUCT */
+		srvItemsNew := common.Row{
+			"id": {
+				Value: "ch_api_product_1",
+			},
+			"api_resources": {
+				Value: "{}",
+			},
+			"environments": {
+				Value: "{Env_0, Env_1}",
+			},
+			"tenant_id": {
+				Value: "tenant_id_0",
+			},
+			"_change_selector": {
+				Value: "test_org0",
+			},
+		}
+
+		/* DEVELOPER */
+		devItemsNew := common.Row{
+			"id": {
+				Value: "ch_developer_id_1",
+			},
+			"status": {
+				Value: "Active",
+			},
+			"tenant_id": {
+				Value: "tenant_id_0",
+			},
+			"_change_selector": {
+				Value: "test_org0",
+			},
+		}
+
+		/* APP */
+		appItemsNew := common.Row{
+			"id": {
+				Value: "ch_application_id_1",
+			},
+			"developer_id": {
+				Value: "ch_developer_id_1",
+			},
+			"status": {
+				Value: "Approved",
+			},
+			"tenant_id": {
+				Value: "tenant_id_0",
+			},
+			"_change_selector": {
+				Value: "test_org0",
+			},
+			"parent_id": {
+				Value: "ch_developer_id_1",
+			},
+		}
+
+		/* CRED */
+		credItemsNew := common.Row{
+			"id": {
+				Value: "ch_app_credential_1",
+			},
+			"app_id": {
+				Value: "ch_application_id_1",
+			},
+			"tenant_id": {
+				Value: "tenant_id_0",
+			},
+			"status": {
+				Value: "Approved",
+			},
+			"_change_selector": {
+				Value: "test_org0",
+			},
+		}
+
+		/* APP_CRED_APIPRD_MAPPER */
+		mpItemsNew := common.Row{
+			"apiprdt_id": {
+				Value: "ch_api_product_1",
+			},
+			"app_id": {
+				Value: "ch_application_id_1",
+			},
+			"appcred_id": {
+				Value: "ch_app_credential_1",
+			},
+			"status": {
+				Value: "Approved",
+			},
+			"_change_selector": {
+				Value: "test_org0",
+			},
+			"tenant_id": {
+				Value: "tenant_id_0",
+			},
+		}
+
+		event.Changes = []common.Change{
+			{
+				Table:     "kms.api_product",
+				NewRow:    srvItemsOld,
+				Operation: 1,
+			},
+			{
+				Table:     "kms.developer",
+				NewRow:    devItemsOld,
+				Operation: 1,
+			},
+
+			{
+				Table:     "kms.app",
+				NewRow:    appItemsOld,
+				Operation: 1,
+			},
+			{
+				Table:     "kms.app_credential",
+				NewRow:    credItemsOld,
+				Operation: 1,
+			},
+			{
+				Table:     "kms.app_credential_apiproduct_mapper",
+				NewRow:    mpItemsOld,
+				Operation: 1,
+			},
+		}
+
+		event2.Changes = []common.Change{
+			{
+				Table:     "kms.api_product",
+				OldRow:    srvItemsOld,
+				NewRow:    srvItemsNew,
+				Operation: 2,
+			},
+			{
+				Table:     "kms.developer",
+				OldRow:    devItemsOld,
+				NewRow:    devItemsNew,
+				Operation: 2,
+			},
+			{
+				Table:     "kms.app",
+				OldRow:    appItemsOld,
+				NewRow:    appItemsNew,
+				Operation: 2,
+			},
+			{
+				Table:     "kms.app_credential",
+				OldRow:    credItemsOld,
+				NewRow:    credItemsNew,
+				Operation: 2,
+			},
+			{
+				Table:     "kms.app_credential_apiproduct_mapper",
+				OldRow:    mpItemsOld,
+				NewRow:    mpItemsNew,
+				Operation: 2,
+			},
+		}
+
+		h := &test_handler{
+			"checkDatabase post Insertion",
+			func(e apid.Event) {
+				defer GinkgoRecover()
+
+				// ignore the first event, let standard listener process it
+				changeSet := e.(*common.ChangeList)
+				if len(changeSet.Changes) > 0 || closed == 1 {
+					return
+				}
+				v := url.Values{
+					"key":       []string{"ch_app_credential_1"},
+					"uriPath":   []string{"/test"},
+					"scopeuuid": []string{"XYZ"},
+					"action":    []string{"verify"},
+				}
+				rsp, err := verifyAPIKey(v)
+				Expect(err).ShouldNot(HaveOccurred())
+				var respj kmsResponseSuccess
+				json.Unmarshal(rsp, &respj)
+				Expect(respj.Type).Should(Equal("APIKeyContext"))
+				Expect(respj.RspInfo.Key).Should(Equal("ch_app_credential_1"))
+				Expect(respj.RspInfo.Type).Should(Equal("developer"))
+				closed = 1
+				close(done)
+			},
+		}
+
+		apid.Events().Listen("ApigeeSync", h)
+		apid.Events().Emit("ApigeeSync", &event)
+		apid.Events().Emit("ApigeeSync", &event2)
+		apid.Events().Emit("ApigeeSync", &common.ChangeList{})
+	})
+
+	It("Modify tables in KMS tables, and verify via verifyApiKey for Company", func(done Done) {
+		closed := 0
+		var event = common.ChangeList{}
+		var event2 = common.ChangeList{}
+
+		/* Orig data */
+		/* API Product */
+		srvItemsOld := common.Row{
+			"id": {
+				Value: "ch_api_product_0",
+			},
+			"api_resources": {
+				Value: "{}",
+			},
+			"environments": {
+				Value: "{Env_0, Env_1}",
+			},
+			"tenant_id": {
+				Value: "tenant_id_0",
+			},
+			"_change_selector": {
+				Value: "test_org0",
+			},
+		}
+
+		/* DEVELOPER */
+		devItemsOld := common.Row{
+			"id": {
+				Value: "ch_developer_id_0",
+			},
+			"status": {
+				Value: "Active",
+			},
+			"tenant_id": {
+				Value: "tenant_id_0",
+			},
+			"_change_selector": {
+				Value: "test_org0",
+			},
+		}
+
+		/* APP */
+		appItemsOld := common.Row{
+			"id": {
+				Value: "ch_application_id_0",
+			},
+			"company_id": {
+				Value: "ch_company_id_0",
+			},
+			"status": {
+				Value: "Approved",
+			},
+			"tenant_id": {
+				Value: "tenant_id_0",
+			},
+			"_change_selector": {
+				Value: "test_org0",
+			},
+			"parent_id": {
+				Value: "ch_company_id_0",
+			},
+		}
+
+		/* COMPANY */
 		companyItemsOld := common.Row{
 			"id": {
 				Value: "ch_company_id_0",
@@ -301,6 +753,7 @@
 			},
 		}
 
+		/* COMPANY_DEVELOPER */
 		companyDeveloperItemsOld := common.Row{
 			"id": {
 				Value: "ch_developer_id_0",
@@ -396,6 +849,7 @@
 			},
 		}
 
+		/* COMPANY */
 		companyItemsNew := common.Row{
 			"id": {
 				Value: "ch_company_id_1",
@@ -417,6 +871,7 @@
 			},
 		}
 
+		/* COMPANY_DEVELOPER */
 		companyDeveloperItemsNew := common.Row{
 			"id": {
 				Value: "ch_developer_id_1",
@@ -440,8 +895,8 @@
 			"id": {
 				Value: "ch_application_id_1",
 			},
-			"developer_id": {
-				Value: "ch_developer_id_1",
+			"company_id": {
+				Value: "ch_company_id_1",
 			},
 			"status": {
 				Value: "Approved",
@@ -452,6 +907,9 @@
 			"_change_selector": {
 				Value: "test_org0",
 			},
+			"parent_id": {
+				Value: "ch_company_id_1",
+			},
 		}
 
 		/* CRED */
@@ -600,6 +1058,7 @@
 				json.Unmarshal(rsp, &respj)
 				Expect(respj.Type).Should(Equal("APIKeyContext"))
 				Expect(respj.RspInfo.Key).Should(Equal("ch_app_credential_1"))
+
 				closed = 1
 				close(done)
 			},
@@ -610,6 +1069,7 @@
 		apid.Events().Emit("ApigeeSync", &event2)
 		apid.Events().Emit("ApigeeSync", &common.ChangeList{})
 	})
+
 })
 
 type test_handler struct {
diff --git a/test_helper.go b/test_helper.go
index 61f8f00..44a341b 100644
--- a/test_helper.go
+++ b/test_helper.go
@@ -5,11 +5,11 @@
 	"strconv"
 )
 
-func convertSuffix(i int) string{
+func convertSuffix(i int) string {
 	return strconv.FormatInt(int64(i), 10)
 }
 
-func generateTestApiProduct(suffix int) common.Row{
+func generateTestApiProduct(suffix int) common.Row {
 	return common.Row{
 		"id": {
 			Value: "api_product_" + convertSuffix(suffix),
@@ -30,7 +30,7 @@
 }
 
 func generateTestDeveloper(suffix int) common.Row {
-	 return common.Row{
+	return common.Row{
 		"id": {
 			Value: "developer_id_" + convertSuffix(suffix),
 		},
@@ -115,6 +115,35 @@
 		"_change_selector": {
 			Value: "Org_0",
 		},
+		"parent_id": {
+			Value: "developer_id_" + convertSuffix(suffix2),
+		},
+	}
+}
+
+func generateTestAppCompany(suffix1, suffix2 int) common.Row {
+	return common.Row{
+		"id": {
+			Value: "application_id_" + convertSuffix(suffix1),
+		},
+		"company_id": {
+			Value: "company_id_" + convertSuffix(suffix2),
+		},
+		"status": {
+			Value: "Approved",
+		},
+		"tenant_id": {
+			Value: "tenant_id_xxxx",
+		},
+		"callback_url": {
+			Value: "http://apigee.com",
+		},
+		"_change_selector": {
+			Value: "Org_0",
+		},
+		"parent_id": {
+			Value: "company_id_" + convertSuffix(suffix2),
+		},
 	}
 }
 
@@ -163,5 +192,3 @@
 		},
 	}
 }
-
-