You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@lucene.apache.org by no...@apache.org on 2020/07/10 03:44:01 UTC

[lucene-solr] 01/01: SOLR-14404 test fix

This is an automated email from the ASF dual-hosted git repository.

noble pushed a commit to branch jira/solr14404_fix
in repository https://gitbox.apache.org/repos/asf/lucene-solr.git

commit ea7fcb905dae6d8e68d5da668507cea081b62e82
Author: noblepaul <no...@gmail.com>
AuthorDate: Fri Jul 10 13:43:22 2020 +1000

    SOLR-14404 test fix
---
 .../apache/solr/api/CustomContainerPlugins.java    | 28 ++++++++++++++----
 .../solr/handler/admin/ContainerPluginsApi.java    |  9 ++++--
 .../src/java/org/apache/solr/pkg/PackageAPI.java   | 33 ++++++++++++++++++++--
 3 files changed, 59 insertions(+), 11 deletions(-)

diff --git a/solr/core/src/java/org/apache/solr/api/CustomContainerPlugins.java b/solr/core/src/java/org/apache/solr/api/CustomContainerPlugins.java
index 6536276..3ce0acb 100644
--- a/solr/core/src/java/org/apache/solr/api/CustomContainerPlugins.java
+++ b/solr/core/src/java/org/apache/solr/api/CustomContainerPlugins.java
@@ -27,6 +27,7 @@ import java.util.HashMap;
 import java.util.List;
 import java.util.Map;
 import java.util.Objects;
+import java.util.concurrent.atomic.AtomicInteger;
 
 import com.fasterxml.jackson.databind.ObjectMapper;
 import org.apache.lucene.analysis.util.ResourceLoaderAware;
@@ -60,6 +61,8 @@ public class CustomContainerPlugins implements ClusterPropertiesListener, MapWri
   final CoreContainer coreContainer;
   final ApiBag containerApiBag;
 
+  private int znodeVersion = 0;
+
   private final Map<String, ApiInfo> currentPlugins = new HashMap<>();
 
   @Override
@@ -79,8 +82,9 @@ public class CustomContainerPlugins implements ClusterPropertiesListener, MapWri
 
   public synchronized void refresh() {
     Map<String, Object> pluginInfos = null;
+    AtomicInteger znodeVersion = new AtomicInteger(0);
     try {
-      pluginInfos = ContainerPluginsApi.plugins(coreContainer.zkClientSupplier);
+      pluginInfos = ContainerPluginsApi.plugins(coreContainer.zkClientSupplier, znodeVersion);
     } catch (IOException e) {
       log.error("Could not read plugins data", e);
       return;
@@ -160,6 +164,9 @@ public class CustomContainerPlugins implements ClusterPropertiesListener, MapWri
       }
 
     }
+    if(znodeVersion.get() >0) {
+      this.znodeVersion = znodeVersion.get();
+    }
   }
 
   private static String getActualPath(ApiInfo apiInfo, String path) {
@@ -230,13 +237,24 @@ public class CustomContainerPlugins implements ClusterPropertiesListener, MapWri
       if (pkg != null) {
         PackageLoader.Package p = coreContainer.getPackageLoader().getPackage(pkg);
         if (p == null) {
-          errs.add("Invalid package " + klassInfo.first());
-          return;
+          if (coreContainer.getPackageLoader().getPackageAPI().refreshState()) {
+            p = coreContainer.getPackageLoader().getPackage(pkg);
+          }
+          if (p == null) {
+            errs.add("Invalid package " + klassInfo.first());
+            return;
+          }
         }
         this.pkgVersion = p.getVersion(info.version);
         if (pkgVersion == null) {
-          errs.add("No such package version:" + pkg + ":" + info.version + " . available versions :" + p.allVersions());
-          return;
+          if (coreContainer.getPackageLoader().getPackageAPI().refreshState()) {
+            p = coreContainer.getPackageLoader().getPackage(pkg);
+            if (p != null) pkgVersion = p.getVersion(info.version);
+          }
+          if (pkgVersion == null) {
+            errs.add("No such package version:" + pkg + ":" + info.version + " . available versions :" + p.allVersions());
+            return;
+          }
         }
         try {
           klas = pkgVersion.getLoader().findClass(klassInfo.second(), Object.class);
diff --git a/solr/core/src/java/org/apache/solr/handler/admin/ContainerPluginsApi.java b/solr/core/src/java/org/apache/solr/handler/admin/ContainerPluginsApi.java
index 21c16e3..b5107a3 100644
--- a/solr/core/src/java/org/apache/solr/handler/admin/ContainerPluginsApi.java
+++ b/solr/core/src/java/org/apache/solr/handler/admin/ContainerPluginsApi.java
@@ -23,6 +23,7 @@ import java.util.ArrayList;
 import java.util.LinkedHashMap;
 import java.util.List;
 import java.util.Map;
+import java.util.concurrent.atomic.AtomicInteger;
 import java.util.function.Function;
 import java.util.function.Supplier;
 
@@ -67,7 +68,7 @@ public class ContainerPluginsApi {
         path = "/cluster/plugin",
         permission = PermissionNameProvider.Name.COLL_READ_PERM)
     public void list(SolrQueryRequest req, SolrQueryResponse rsp) throws IOException {
-      rsp.add(PLUGIN, plugins(zkClientSupplier));
+      rsp.add(PLUGIN, plugins(zkClientSupplier, null));
     }
   }
 
@@ -147,10 +148,12 @@ public class ContainerPluginsApi {
   }
 
   @SuppressWarnings("unchecked")
-  public static Map<String, Object> plugins(Supplier<SolrZkClient> zkClientSupplier) throws IOException {
+  public static Map<String, Object> plugins(Supplier<SolrZkClient> zkClientSupplier, AtomicInteger znodeVersion) throws IOException {
     SolrZkClient zkClient = zkClientSupplier.get();
     try {
-      Map<String, Object> clusterPropsJson = (Map<String, Object>) Utils.fromJSON(zkClient.getData(ZkStateReader.CLUSTER_PROPS, null, new Stat(), true));
+      Stat stat = new Stat();
+      Map<String, Object> clusterPropsJson = (Map<String, Object>) Utils.fromJSON(zkClient.getData(ZkStateReader.CLUSTER_PROPS, null, stat, true));
+      if(znodeVersion != null) znodeVersion.set(stat.getVersion());
       return (Map<String, Object>) clusterPropsJson.computeIfAbsent(PLUGIN, Utils.NEW_LINKED_HASHMAP_FUN);
     } catch (KeeperException.NoNodeException e) {
       return new LinkedHashMap<>();
diff --git a/solr/core/src/java/org/apache/solr/pkg/PackageAPI.java b/solr/core/src/java/org/apache/solr/pkg/PackageAPI.java
index ecc344c..9513074 100644
--- a/solr/core/src/java/org/apache/solr/pkg/PackageAPI.java
+++ b/solr/core/src/java/org/apache/solr/pkg/PackageAPI.java
@@ -20,6 +20,7 @@ package org.apache.solr.pkg;
 import java.io.IOException;
 import java.io.StringWriter;
 import java.lang.invoke.MethodHandles;
+import java.time.OffsetDateTime;
 import java.util.ArrayList;
 import java.util.Collections;
 import java.util.LinkedHashMap;
@@ -91,6 +92,28 @@ public class PackageAPI {
     }
   }
 
+  public boolean refreshState()  {
+    try {
+      SolrZkClient zkClient = coreContainer.getZkController().getZkClient();
+      Stat stat = zkClient.exists(SOLR_PKGS_PATH, null, true);
+      if(stat != null && stat.getVersion() > pkgs.znodeVersion){
+        //the version is updated and we have missed an update
+        reloadPackageData(null, stat, zkClient, SOLR_PKGS_PATH);
+        return true;
+      }
+    } catch (KeeperException e) {
+      //could not read
+      return false;
+
+    } catch (InterruptedException e) {
+      Thread.currentThread().interrupt();
+      log.warn("Interrupted", e);
+      return false;
+    }
+    return false;
+
+  }
+
   private void registerListener(SolrZkClient zkClient)
       throws KeeperException, InterruptedException {
     String path = SOLR_PKGS_PATH;
@@ -110,9 +133,7 @@ public class PackageAPI {
                 // remake watch
                 final Watcher thisWatch = this;
                 final Stat stat = new Stat();
-                final byte[] data = zkClient.getData(path, thisWatch, stat, true);
-                pkgs = readPkgsFromZk(data, stat);
-                packageLoader.refreshPackageConf();
+                reloadPackageData(thisWatch, stat, zkClient, path);
               }
             } catch (KeeperException.ConnectionLossException | KeeperException.SessionExpiredException e) {
               log.warn("ZooKeeper watch triggered, but Solr cannot talk to ZK: ", e);
@@ -129,6 +150,12 @@ public class PackageAPI {
         }, true);
   }
 
+  private synchronized void reloadPackageData(Watcher thisWatch, Stat stat, SolrZkClient zkClient, String path)
+          throws KeeperException, InterruptedException {
+    final byte[] data = zkClient.getData(path, thisWatch, stat, true);
+    pkgs = readPkgsFromZk(data, stat);
+    packageLoader.refreshPackageConf();
+  }
 
   private Packages readPkgsFromZk(byte[] data, Stat stat) throws KeeperException, InterruptedException {