Fix cache eviction for projects cache

When the project name contains a slash, the cache eviction router
throws a MalformedJsonException.

For projects cache pass the key without JSON transcoding, preventing
the problem of breakage when the string value is not a valid JSON
element.

Also rename the CacheKeyJsonParser.fromJson method to
CacheKeyJsonParser.from to reflect the fact that cache key value is not
always a JSON element.

Bug: Issue 14564
Change-Id: I6ce9471bd96456c0950e321d0c694ec2f9ac254c
diff --git a/src/main/java/com/googlesource/gerrit/plugins/multisite/forwarder/CacheKeyJsonParser.java b/src/main/java/com/googlesource/gerrit/plugins/multisite/forwarder/CacheKeyJsonParser.java
index 80b2445..ef14a8e 100644
--- a/src/main/java/com/googlesource/gerrit/plugins/multisite/forwarder/CacheKeyJsonParser.java
+++ b/src/main/java/com/googlesource/gerrit/plugins/multisite/forwarder/CacheKeyJsonParser.java
@@ -33,38 +33,41 @@
   }
 
   @SuppressWarnings("cast")
-  public Object fromJson(String cacheName, Object json) {
-    Object key;
+  public Object from(String cacheName, Object cacheKeyValue) {
+    Object parsedKey;
     // Need to add a case for 'adv_bases'
     switch (cacheName) {
       case Constants.ACCOUNTS:
-        key = Account.id(jsonElement(json).getAsJsonObject().get("id").getAsInt());
+        parsedKey = Account.id(jsonElement(cacheKeyValue).getAsJsonObject().get("id").getAsInt());
         break;
       case Constants.GROUPS:
-        key = AccountGroup.id(jsonElement(json).getAsJsonObject().get("id").getAsInt());
+        parsedKey =
+            AccountGroup.id(jsonElement(cacheKeyValue).getAsJsonObject().get("id").getAsInt());
         break;
       case Constants.GROUPS_BYINCLUDE:
       case Constants.GROUPS_MEMBERS:
-        key = AccountGroup.uuid(jsonElement(json).getAsJsonObject().get("uuid").getAsString());
+        parsedKey =
+            AccountGroup.uuid(
+                jsonElement(cacheKeyValue).getAsJsonObject().get("uuid").getAsString());
         break;
       case Constants.PROJECTS:
-        key = Project.nameKey(jsonElement(json).getAsString());
+        parsedKey = Project.nameKey(nullToEmpty(cacheKeyValue));
         break;
       case Constants.PROJECT_LIST:
-        key = gson.fromJson(nullToEmpty(json).toString(), Object.class);
+        parsedKey = gson.fromJson(nullToEmpty(cacheKeyValue).toString(), Object.class);
         break;
       default:
-        if (json instanceof String) {
-          key = (String) json;
+        if (cacheKeyValue instanceof String) {
+          parsedKey = (String) cacheKeyValue;
         } else {
           try {
-            key = gson.fromJson(nullToEmpty(json).toString().trim(), String.class);
+            parsedKey = gson.fromJson(nullToEmpty(cacheKeyValue).toString().trim(), String.class);
           } catch (Exception e) {
-            key = gson.fromJson(nullToEmpty(json).toString(), Object.class);
+            parsedKey = gson.fromJson(nullToEmpty(cacheKeyValue).toString(), Object.class);
           }
         }
     }
-    return key;
+    return parsedKey;
   }
 
   private JsonElement jsonElement(Object json) {
diff --git a/src/main/java/com/googlesource/gerrit/plugins/multisite/forwarder/router/CacheEvictionEventRouter.java b/src/main/java/com/googlesource/gerrit/plugins/multisite/forwarder/router/CacheEvictionEventRouter.java
index a77e168..a44da29 100644
--- a/src/main/java/com/googlesource/gerrit/plugins/multisite/forwarder/router/CacheEvictionEventRouter.java
+++ b/src/main/java/com/googlesource/gerrit/plugins/multisite/forwarder/router/CacheEvictionEventRouter.java
@@ -34,7 +34,7 @@
 
   @Override
   public void route(CacheEvictionEvent cacheEvictionEvent) throws CacheNotFoundException {
-    Object parsedKey = gsonParser.fromJson(cacheEvictionEvent.cacheName, cacheEvictionEvent.key);
+    Object parsedKey = gsonParser.from(cacheEvictionEvent.cacheName, cacheEvictionEvent.key);
     cacheEvictionHanlder.evict(CacheEntry.from(cacheEvictionEvent.cacheName, parsedKey));
   }
 }
diff --git a/src/test/java/com/googlesource/gerrit/plugins/multisite/forwarder/CacheKeyJsonParserTest.java b/src/test/java/com/googlesource/gerrit/plugins/multisite/forwarder/CacheKeyJsonParserTest.java
index e29c8cd..e42b4e5 100644
--- a/src/test/java/com/googlesource/gerrit/plugins/multisite/forwarder/CacheKeyJsonParserTest.java
+++ b/src/test/java/com/googlesource/gerrit/plugins/multisite/forwarder/CacheKeyJsonParserTest.java
@@ -34,35 +34,34 @@
   public void accountIDParse() {
     Account.Id accountId = Account.id(1);
     String json = gson.toJson(accountId);
-    assertThat(accountId).isEqualTo(gsonParser.fromJson(Constants.ACCOUNTS, json));
+    assertThat(accountId).isEqualTo(gsonParser.from(Constants.ACCOUNTS, json));
   }
 
   @Test
   public void accountGroupIDParse() {
     AccountGroup.Id accountGroupId = AccountGroup.id(1);
     String json = gson.toJson(accountGroupId);
-    assertThat(accountGroupId).isEqualTo(gsonParser.fromJson(Constants.GROUPS, json));
+    assertThat(accountGroupId).isEqualTo(gsonParser.from(Constants.GROUPS, json));
   }
 
   @Test
   public void accountGroupUUIDParse() {
     AccountGroup.UUID accountGroupUuid = AccountGroup.uuid("abc123");
     String json = gson.toJson(accountGroupUuid);
-    assertThat(accountGroupUuid).isEqualTo(gsonParser.fromJson(Constants.GROUPS_BYINCLUDE, json));
+    assertThat(accountGroupUuid).isEqualTo(gsonParser.from(Constants.GROUPS_BYINCLUDE, json));
   }
 
   @Test
   public void projectNameKeyParse() {
     String projectNameString = "foo";
     Project.NameKey projectNameKey = Project.nameKey(projectNameString);
-    assertThat(projectNameKey)
-        .isEqualTo(gsonParser.fromJson(Constants.PROJECTS, projectNameString));
+    assertThat(projectNameKey).isEqualTo(gsonParser.from(Constants.PROJECTS, projectNameString));
   }
 
   @Test
   public void stringParse() {
     String key = "key";
-    assertThat(key).isEqualTo(gsonParser.fromJson("any-cache-with-string-key", key));
+    assertThat(key).isEqualTo(gsonParser.from("any-cache-with-string-key", key));
   }
 
   @Test