Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

SOLR-17381 SolrJ fix to fetch entire ClusterState if asked #2853

Merged
merged 10 commits into from
Dec 9, 2024
Original file line number Diff line number Diff line change
@@ -98,8 +98,8 @@ public ClusterState.CollectionRef getState(String collection) {
for (String nodeName : liveNodes) {
String baseUrl = Utils.getBaseUrlForNodeName(nodeName, urlScheme);
try (SolrClient client = getSolrClient(baseUrl)) {
ClusterState cs = fetchClusterState(client, collection, null);
return cs.getCollectionRef(collection);
DocCollection docCollection = fetchCollectionState(client, collection);
return new ClusterState.CollectionRef(docCollection);
} catch (SolrServerException | IOException e) {
log.warn(
"Attempt to fetch cluster state from {} failed.",
@@ -128,30 +128,12 @@ public ClusterState.CollectionRef getState(String collection) {
}

@SuppressWarnings("unchecked")
private ClusterState fetchClusterState(
SolrClient client, String collection, Map<String, Object> clusterProperties)
private ClusterState fetchClusterState(SolrClient client, Map<String, Object> clusterProperties)
throws SolrServerException, IOException, NotACollectionException {
SimpleOrderedMap<?> cluster =
submitClusterStateRequest(client, collection, ClusterStateRequestType.FETCH_COLLECTION);
submitClusterStateRequest(client, null, ClusterStateRequestType.FETCH_CLUSTER_STATE);

Map<String, Object> collectionsMap;
if (collection != null) {
collectionsMap =
Collections.singletonMap(
collection, ((NamedList<?>) cluster.get("collections")).get(collection));
} else {
collectionsMap = ((NamedList<?>) cluster.get("collections")).asMap(10);
}
int znodeVersion;
Map<String, Object> collFromStatus = (Map<String, Object>) (collectionsMap).get(collection);
if (collection != null && collFromStatus == null) {
throw new NotACollectionException(); // probably an alias
}
if (collection != null) { // can be null if alias
znodeVersion = (int) collFromStatus.get("znodeVersion");
} else {
znodeVersion = -1;
}
Map<String, Object> collectionsMap = ((NamedList<?>) cluster.get("collections")).asMap(10);

ClusterState cs = new ClusterState(this.liveNodes, new HashMap<>());
List<String> liveNodesList = (List<String>) cluster.get("live_nodes");
@@ -163,14 +145,7 @@ private ClusterState fetchClusterState(
}

for (Map.Entry<String, Object> e : collectionsMap.entrySet()) {
@SuppressWarnings("rawtypes")
Map m = (Map) e.getValue();
Long creationTimeMillisFromClusterStatus = (Long) m.get("creationTimeMillis");
Instant creationTime =
creationTimeMillisFromClusterStatus == null
? Instant.EPOCH
: Instant.ofEpochMilli(creationTimeMillisFromClusterStatus);
cs = cs.copyWith(e.getKey(), fillPrs(znodeVersion, e, creationTime, m));
cs = cs.copyWith(e.getKey(), getDocCollectionFromObjects(e, -1));
}

if (clusterProperties != null) {
@@ -182,6 +157,37 @@ private ClusterState fetchClusterState(
return cs;
}

private DocCollection getDocCollectionFromObjects(Map.Entry<String, Object> e, int zNodeVersion) {
@SuppressWarnings("rawtypes")
Map m = (Map) e.getValue();
Long creationTimeMillisFromClusterStatus = (Long) m.get("creationTimeMillis");
Instant creationTime =
creationTimeMillisFromClusterStatus == null
? Instant.EPOCH
: Instant.ofEpochMilli(creationTimeMillisFromClusterStatus);
return fillPrs(zNodeVersion, e, creationTime, m);
}

private DocCollection fetchCollectionState(SolrClient client, String collection)
throws SolrServerException, IOException, NotACollectionException {

SimpleOrderedMap<?> cluster =
submitClusterStateRequest(client, collection, ClusterStateRequestType.FETCH_COLLECTION);

Map<String, Object> collectionsMap =
Collections.singletonMap(
collection, ((NamedList<?>) cluster.get("collections")).get(collection));

int znodeVersion = -1;
@SuppressWarnings("unchecked")
Map<String, Object> collFromStatus = (Map<String, Object>) (collectionsMap).get(collection);
if (collFromStatus == null) {
throw new NotACollectionException(); // probably an alias
}
znodeVersion = (int) collFromStatus.get("znodeVersion");
return getDocCollectionFromObjects(Map.entry(collection, collFromStatus), znodeVersion);
}

private SimpleOrderedMap<?> submitClusterStateRequest(
SolrClient client, String collection, ClusterStateRequestType requestType)
throws SolrServerException, IOException {
@@ -198,8 +204,11 @@ private SimpleOrderedMap<?> submitClusterStateRequest(
} else if (requestType == ClusterStateRequestType.FETCH_NODE_ROLES) {
params.set("roles", "true");
}

params.set("includeAll", "false");
if (requestType == ClusterStateRequestType.FETCH_CLUSTER_STATE) {
params.set("includeAll", "true");
} else {
params.set("includeAll", "false");
}
params.set("prs", "true");
QueryRequest request = new QueryRequest(params);
request.setPath("/admin/collections");
@@ -346,8 +355,8 @@ public ClusterState getClusterState() {
for (String nodeName : liveNodes) {
String baseUrl = Utils.getBaseUrlForNodeName(nodeName, urlScheme);
try (SolrClient client = getSolrClient(baseUrl)) {
return fetchClusterState(client, null, null);
} catch (SolrServerException | SolrClient.RemoteSolrException | IOException e) {
return fetchClusterState(client, null);
} catch (SolrServerException | RemoteSolrException | IOException e) {
log.warn("Attempt to fetch cluster state from {} failed.", baseUrl, e);
} catch (NotACollectionException e) {
// not possible! (we passed in null for collection, so it can't be an alias)
@@ -376,7 +385,7 @@ public Map<String, Object> getClusterProperties() {
SimpleOrderedMap<?> cluster =
submitClusterStateRequest(client, null, ClusterStateRequestType.FETCH_CLUSTER_PROP);
return (Map<String, Object>) cluster.get("properties");
} catch (SolrServerException | SolrClient.RemoteSolrException | IOException e) {
} catch (SolrServerException | RemoteSolrException | IOException e) {
log.warn("Attempt to fetch cluster state from {} failed.", baseUrl, e);
}
}
@@ -428,6 +437,7 @@ private enum ClusterStateRequestType {
FETCH_LIVE_NODES,
FETCH_CLUSTER_PROP,
FETCH_NODE_ROLES,
FETCH_COLLECTION
FETCH_COLLECTION,
FETCH_CLUSTER_STATE
}
}