SOLR-15135: Use DocCollection to generate state.json format expected by UI to work with perReplicaState collections. (#2383)

This commit is contained in:
Timothy Potter 2021-02-16 14:40:50 -07:00 committed by GitHub
parent 0671ef5e5f
commit 75fd9ef785
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 11 additions and 21 deletions

View File

@ -264,6 +264,8 @@ Bug Fixes
* SOLR-15138: Collection creation for PerReplicaStates does not scale to large collections as well as regular collections
(Mike Drob, Ilan Ginzburg, noble, Ishan Chattopadhyaya)
* SOLR-15135: Admin UI display collections with perReplicaState=true in graph view (Timothy Potter)
================== 8.8.0 ==================
Consult the LUCENE_CHANGES.txt file for additional, low level, changes in this release.

View File

@ -42,6 +42,8 @@ import org.apache.lucene.util.BytesRef;
import org.apache.solr.cloud.ZkController;
import org.apache.solr.common.SolrException;
import org.apache.solr.common.SolrException.ErrorCode;
import org.apache.solr.common.cloud.ClusterState;
import org.apache.solr.common.cloud.DocCollection;
import org.apache.solr.common.cloud.OnReconnect;
import org.apache.solr.common.cloud.Replica;
import org.apache.solr.common.cloud.SolrZkClient;
@ -516,31 +518,17 @@ public final class ZookeeperInfoHandler extends RequestHandlerBase {
pagingSupport.fetchPage(page, zkClient);
// keep track of how many collections match the filter
boolean applyStatusFilter = (page.filterType == FilterType.status && page.filter != null);
List<String> matchesStatusFilter = applyStatusFilter ? new ArrayList<String>() : null;
Set<String> liveNodes = applyStatusFilter ?
zkController.getZkStateReader().getClusterState().getLiveNodes() : null;
List<String> matchesStatusFilter = applyStatusFilter ? new ArrayList<>() : null;
ClusterState cs = zkController.getZkStateReader().getClusterState();
Set<String> liveNodes = applyStatusFilter ? cs.getLiveNodes() : null;
collectionStates = new TreeMap<>(pagingSupport);
for (String collection : page.selected) {
// Get collection state from ZK
String collStatePath = String.format(Locale.ROOT, "/collections/%s/state.json", collection);
String childDataStr = null;
try {
byte[] childData = zkClient.getData(collStatePath, null, null, true);
if (childData != null)
childDataStr = (new BytesRef(childData)).utf8ToString();
} catch (KeeperException.NoNodeException nne) {
log.warn("State for collection {} not found.", collection);
} catch (Exception childErr) {
log.error("Failed to get {} due to", collStatePath, childErr);
}
if (childDataStr != null) {
Map<String, Object> extColl = (Map<String, Object>) Utils.fromJSONString(childDataStr);
// add the base_url to replica props
DocCollection dc = cs.getCollectionOrNull(collection);
if (dc != null) {
// TODO: for collections with perReplicaState, a ser/deser to JSON was needed to get the state to render correctly for the UI?
@SuppressWarnings("unchecked")
Map<String, Object> collectionState = (Map<String, Object>)extColl.get(collection);
Map<String, Object> collectionState = dc.isPerReplicaState() ? (Map<String, Object>)Utils.fromJSONString(Utils.toJSONString(dc)) : dc.getProperties();
if (applyStatusFilter) {
// verify this collection matches the filtered state
if (page.matchesStatusFilter(collectionState, liveNodes)) {