Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions solr/CHANGES.txt
Original file line number Diff line number Diff line change
Expand Up @@ -338,6 +338,8 @@ Improvements

* SOLR-15155: Let CloudHttp2SolrClient accept an external Http2SolrClient Builder (Tomás Fernández Löbbe)

* SOLR-15337: Avoid XPath in solrconfig.xml parsing (noble)

Optimizations
---------------------
* SOLR-15079: Block Collapse - Faster collapse code when groups are co-located via Block Join style nested doc indexing.
Expand Down
25 changes: 22 additions & 3 deletions solr/core/src/java/org/apache/solr/core/ConfigOverlay.java
Original file line number Diff line number Diff line change
Expand Up @@ -16,12 +16,12 @@
*/
package org.apache.solr.core;

import java.util.ArrayList;
import java.util.Collections;
import java.util.LinkedHashMap;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;

import org.apache.solr.common.MapSerializable;
import org.apache.solr.common.SolrException;
import org.apache.solr.common.params.CoreAdminParams;
Expand Down Expand Up @@ -62,6 +62,12 @@ public Object getXPathProperty(String xpath, boolean onlyPrimitive) {
return Utils.getObjectByPath(props, onlyPrimitive, hierarchy);
}

public Object getXPathProperty(List<String> path) {
List<String> hierarchy = new ArrayList<>();
if(isEditable(true, hierarchy, path) == null) return null;
return Utils.getObjectByPath(props, true, hierarchy);
}

@SuppressWarnings({"unchecked"})
public ConfigOverlay setUserProperty(String key, Object val) {
@SuppressWarnings({"rawtypes"})
Expand Down Expand Up @@ -180,11 +186,20 @@ public static boolean isEditableProp(String path, boolean isXpath, List<String>

@SuppressWarnings({"rawtypes"})
public static Class checkEditable(String path, boolean isXpath, List<String> hierarchy) {
List<String> parts = StrUtils.splitSmart(path, isXpath ? '/' : '.');
return isEditable(isXpath, hierarchy, StrUtils.splitSmart(path, isXpath ? '/' : '.'));
}

@SuppressWarnings("rawtypes")
private static Class isEditable(boolean isXpath, List<String> hierarchy, List<String> parts) {
Object obj = editable_prop_map;
for (int i = 0; i < parts.size(); i++) {
String part = parts.get(i);
boolean isAttr = isXpath && part.startsWith("@");
boolean isAttr = false;
try {
isAttr = isXpath && part.startsWith("@");
} catch (RuntimeException e) {
throw e;
}
if (isAttr) {
part = part.substring(1);
}
Expand Down Expand Up @@ -247,6 +262,10 @@ public Map<String, Map> getNamedPlugins(String typ) {
return Collections.unmodifiableMap(reqHandlers);
}

boolean hasKey(String key) {
return props.containsKey(key);
}


@SuppressWarnings({"unchecked", "rawtypes"})
public ConfigOverlay addNamedPlugin(Map<String, Object> info, String typ) {
Expand Down
7 changes: 7 additions & 0 deletions solr/core/src/java/org/apache/solr/core/ConfigSetService.java
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@
import org.apache.solr.cloud.ZkConfigSetService;
import org.apache.solr.cloud.ZkController;
import org.apache.solr.cloud.ZkSolrResourceLoader;
import org.apache.solr.common.ConfigNode;
import org.apache.solr.common.SolrException;
import org.apache.solr.common.StringUtils;
import org.apache.solr.common.util.NamedList;
Expand Down Expand Up @@ -435,4 +436,10 @@ protected NamedList loadConfigSetFlags(CoreDescriptor cd, SolrResourceLoader loa
*/
public abstract List<String> getAllConfigFiles(String configName) throws IOException;

public interface ConfigResource {

ConfigNode get() throws Exception;

}

}
92 changes: 92 additions & 0 deletions solr/core/src/java/org/apache/solr/core/OverlaidConfigNode.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,92 @@
package org.apache.solr.core;

import java.util.ArrayList;
import java.util.List;
import java.util.function.Function;
import java.util.function.Predicate;

import org.apache.solr.cluster.api.SimpleMap;
import org.apache.solr.common.ConfigNode;

/**A config node impl which has an overlay
*
*/
class OverlaidConfigNode implements ConfigNode {

private final ConfigOverlay overlay;
private final String _name;
private final ConfigNode delegate;
private final OverlaidConfigNode parent;

OverlaidConfigNode(ConfigOverlay overlay, String name, OverlaidConfigNode parent, ConfigNode delegate) {
this.overlay = overlay;
this._name = name;
this.delegate = delegate;
this.parent = parent;
}

private List<String> path(List<String> path) {
if(path== null) path = new ArrayList<>(5);
try {
if (parent != null) return parent.path(path);
} finally {
path.add(_name);
}
return path;
}

@Override
public ConfigNode get(String name) {
return wrap(delegate.get(name), name);
}

private ConfigNode wrap(ConfigNode n, String name) {
return new OverlaidConfigNode(overlay, name,this, n);
}

@Override
public ConfigNode get(String name, Predicate<ConfigNode> test) {
return wrap(delegate.get(name, test), name);
}

@Override
public String txt() {
return overlayText(delegate.txt(), null);
}

@Override
public ConfigNode get(String name, int idx) {
return wrap(delegate.get(name, idx), name);
}

@Override
public String name() {
return delegate.name();
}
@Override
public SimpleMap<String> attributes() {
return delegate.attributes();
}

@Override
public boolean exists() {
return delegate.exists();
}

@Override
public String attr(String name) {
return overlayText(delegate.attr(name),name);
}

private String overlayText(String def, String appendToPath) {
List<String> path = path(null);
if(appendToPath !=null) path.add(appendToPath);
Object val = overlay.getXPathProperty(path);
return val ==null? def: val.toString();
}

@Override
public void forEachChild(Function<ConfigNode, Boolean> fun) {
delegate.forEachChild(fun);
}
}
24 changes: 24 additions & 0 deletions solr/core/src/java/org/apache/solr/core/PluginInfo.java
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@
import java.util.List;
import java.util.Map;

import org.apache.solr.common.ConfigNode;
import org.apache.solr.common.MapSerializable;
import org.apache.solr.common.util.DOMUtil;
import org.apache.solr.common.util.NamedList;
Expand Down Expand Up @@ -99,6 +100,18 @@ public String toString() {
}


public PluginInfo(ConfigNode node, String err,boolean requireName, boolean requireClass) {
type = node.name();
name = node.requiredStrAttr(NAME,requireName? () -> new RuntimeException(err + ": missing mandatory attribute 'name'"):null);
cName = parseClassName(node.requiredStrAttr(CLASS_NAME, requireClass? () -> new RuntimeException(err + ": missing mandatory attribute 'class'"):null ));
className = cName.className;
pkgName = cName.pkg;
initArgs = DOMUtil.childNodesToNamedList(node);
attributes = node.attributes().asMap();
children = loadSubPlugins(node);
isFromSolrConfig = true;

}
public PluginInfo(Node node, String err, boolean requireName, boolean requireClass) {
type = node.getNodeName();
name = DOMUtil.getAttr(node, NAME, requireName ? err : null);
Expand Down Expand Up @@ -143,6 +156,17 @@ public PluginInfo(String type, Map<String,Object> map) {
isFromSolrConfig = true;
}

private List<PluginInfo> loadSubPlugins(ConfigNode node) {
List<PluginInfo> children = new ArrayList<>();
//if there is another sub tag with a non namedlist tag that has to be another plugin
node.forEachChild(nd -> {
if (NL_TAGS.contains(nd.name())) return null;
PluginInfo pluginInfo = new PluginInfo(nd, null, false, false);
if (pluginInfo.isEnabled()) children.add(pluginInfo);
return null;
});
return children.isEmpty() ? Collections.<PluginInfo>emptyList() : unmodifiableList(children);
}
private List<PluginInfo> loadSubPlugins(Node node) {
List<PluginInfo> children = new ArrayList<>();
//if there is another sub tag with a non namedlist tag that has to be another plugin
Expand Down
Loading