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 f24626bbf08..ef33c3e2a4c 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.Optional; import com.fasterxml.jackson.databind.ObjectMapper; import org.apache.lucene.analysis.util.ResourceLoaderAware; @@ -228,16 +229,23 @@ public class CustomContainerPlugins implements ClusterPropertiesListener, MapWri PluginInfo.ClassName klassInfo = new PluginInfo.ClassName(info.klass); pkg = klassInfo.pkg; if (pkg != null) { - PackageLoader.Package p = coreContainer.getPackageLoader().getPackage(pkg); - if (p == null) { - errs.add("Invalid package " + klassInfo.pkg); - return; + Optional ver = coreContainer.getPackageLoader().getPackageVersion(pkg, info.version); + if (ver.isEmpty()) { + //may be we are a bit early. Do a refresh and try again + coreContainer.getPackageLoader().getPackageAPI().refreshPackages(null); + ver = coreContainer.getPackageLoader().getPackageVersion(pkg, info.version); } - this.pkgVersion = p.getVersion(info.version); - if (pkgVersion == null) { - errs.add("No such package version:" + pkg + ":" + info.version + " . available versions :" + p.allVersions()); - return; + if (ver.isEmpty()) { + PackageLoader.Package p = coreContainer.getPackageLoader().getPackage(pkg); + if (p == null) { + errs.add("Invalid package " + klassInfo.pkg); + return; + } else { + errs.add("No such package version:" + pkg + ":" + info.version + " . available versions :" + p.allVersions()); + return; + } } + this.pkgVersion = ver.get(); try { klas = pkgVersion.getLoader().findClass(klassInfo.className, Object.class); } catch (Exception e) { 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 5fe3aaa3043..62d73e9eebf 100644 --- a/solr/core/src/java/org/apache/solr/pkg/PackageAPI.java +++ b/solr/core/src/java/org/apache/solr/pkg/PackageAPI.java @@ -93,8 +93,7 @@ public class PackageAPI { private void registerListener(SolrZkClient zkClient) throws KeeperException, InterruptedException { - String path = SOLR_PKGS_PATH; - zkClient.exists(path, + zkClient.exists(SOLR_PKGS_PATH, new Watcher() { @Override @@ -103,32 +102,33 @@ public class PackageAPI { if (Event.EventType.None.equals(event.getType())) { return; } - try { - synchronized (this) { - log.debug("Updating [{}] ... ", path); - - // 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(); - } - } catch (KeeperException.ConnectionLossException | KeeperException.SessionExpiredException e) { - log.warn("ZooKeeper watch triggered, but Solr cannot talk to ZK: ", e); - } catch (KeeperException e) { - log.error("A ZK error has occurred", e); - throw new ZooKeeperException(SolrException.ErrorCode.SERVER_ERROR, "", e); - } catch (InterruptedException e) { - // Restore the interrupted status - Thread.currentThread().interrupt(); - log.warn("Interrupted", e); + synchronized (this) { + log.debug("Updating [{}] ... ", SOLR_PKGS_PATH); + // remake watch + final Watcher thisWatch = this; + refreshPackages(thisWatch); } } - }, true); } + public void refreshPackages(Watcher watcher) { + final Stat stat = new Stat(); + try { + final byte[] data = coreContainer.getZkController().getZkClient().getData(SOLR_PKGS_PATH, watcher, stat, true); + pkgs = readPkgsFromZk(data, stat); + packageLoader.refreshPackageConf(); + } catch (KeeperException.ConnectionLossException | KeeperException.SessionExpiredException e) { + log.warn("ZooKeeper watch triggered, but Solr cannot talk to ZK: ", e); + } catch (KeeperException e) { + log.error("A ZK error has occurred", e); + throw new ZooKeeperException(SolrException.ErrorCode.SERVER_ERROR, "", e); + } catch (InterruptedException e) { + // Restore the interrupted status + Thread.currentThread().interrupt(); + log.warn("Interrupted", e); + } + } private Packages readPkgsFromZk(byte[] data, Stat stat) throws KeeperException, InterruptedException { diff --git a/solr/core/src/java/org/apache/solr/pkg/PackageLoader.java b/solr/core/src/java/org/apache/solr/pkg/PackageLoader.java index 1e2fc574adb..e3ad675e9a9 100644 --- a/solr/core/src/java/org/apache/solr/pkg/PackageLoader.java +++ b/solr/core/src/java/org/apache/solr/pkg/PackageLoader.java @@ -31,6 +31,7 @@ import java.util.HashSet; import java.util.List; import java.util.Map; import java.util.Objects; +import java.util.Optional; import java.util.Set; import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.CopyOnWriteArrayList; @@ -61,6 +62,12 @@ public class PackageLoader implements Closeable { private PackageAPI packageAPI; + public Optional getPackageVersion(String pkg, String version) { + Package p = packageClassLoaders.get(pkg); + if(p == null) return Optional.empty(); + return Optional.ofNullable(p.getVersion(version)); + } + public PackageLoader(CoreContainer coreContainer) { this.coreContainer = coreContainer; packageAPI = new PackageAPI(coreContainer, this); @@ -227,6 +234,7 @@ public class PackageLoader implements Closeable { } public Version getVersion(String version) { + if(version == null) return getLatest(); return myVersions.get(version); }