mirror of
https://github.com/apache/lucene.git
synced 2025-02-24 11:16:35 +00:00
SOLR-10446: Making HttpClusterStateProvider work with server that doesn't have LISTALIASES
This commit is contained in:
parent
66715a4761
commit
fd4125ea41
@ -164,8 +164,8 @@ New Features
|
||||
* SOLR-10446: CloudSolrClient can now be initialized using the base URL of a Solr instance instead of
|
||||
ZooKeeper hosts. This is possible through the use of newly introduced HttpClusterStateProvider.
|
||||
To fetch a list of collection aliases, this depends on LISTALIASES command, and hence this way of
|
||||
initializing CloudSolrClient would not work with older versions of Solr that doesn't support LISTALIASES.
|
||||
(Ishan Chattopadhyaya, Noble Paul)
|
||||
initializing CloudSolrClient would not work if you have collection aliases on older versions of Solr
|
||||
server that doesn't support LISTALIASES. (Ishan Chattopadhyaya, Noble Paul)
|
||||
|
||||
Optimizations
|
||||
----------------------
|
||||
|
@ -16,7 +16,6 @@
|
||||
*/
|
||||
package org.apache.solr.client.solrj.impl;
|
||||
|
||||
import java.io.Closeable;
|
||||
import java.io.IOException;
|
||||
import java.lang.invoke.MethodHandles;
|
||||
import java.net.ConnectException;
|
||||
@ -1783,34 +1782,4 @@ public class CloudSolrClient extends SolrClient {
|
||||
shardLeadersOnly, directUpdatesToLeadersOnly, stateProvider);
|
||||
}
|
||||
}
|
||||
|
||||
interface ClusterStateProvider extends Closeable {
|
||||
|
||||
/**
|
||||
* Obtain the state of the collection (cluster status).
|
||||
* @return the collection state, or null is collection doesn't exist
|
||||
*/
|
||||
ClusterState.CollectionRef getState(String collection);
|
||||
|
||||
/**
|
||||
* Obtain set of live_nodes for the cluster.
|
||||
*/
|
||||
Set<String> liveNodes();
|
||||
|
||||
String getAlias(String collection);
|
||||
|
||||
String getCollectionName(String name);
|
||||
|
||||
/**
|
||||
* Obtain a cluster property, or null if it doesn't exist.
|
||||
*/
|
||||
Object getClusterProperty(String propertyName);
|
||||
|
||||
/**
|
||||
* Obtain a cluster property, or the default value if it doesn't exist.
|
||||
*/
|
||||
Object getClusterProperty(String propertyName, String def);
|
||||
|
||||
void connect();
|
||||
}
|
||||
}
|
||||
|
@ -0,0 +1,59 @@
|
||||
/*
|
||||
* Licensed to the Apache Software Foundation (ASF) under one or more
|
||||
* contributor license agreements. See the NOTICE file distributed with
|
||||
* this work for additional information regarding copyright ownership.
|
||||
* The ASF licenses this file to You under the Apache License, Version 2.0
|
||||
* (the "License"); you may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.apache.solr.client.solrj.impl;
|
||||
|
||||
import java.io.Closeable;
|
||||
import java.util.Set;
|
||||
|
||||
import org.apache.solr.common.cloud.ClusterState;
|
||||
|
||||
public interface ClusterStateProvider extends Closeable {
|
||||
|
||||
/**
|
||||
* Obtain the state of the collection (cluster status).
|
||||
* @return the collection state, or null is collection doesn't exist
|
||||
*/
|
||||
ClusterState.CollectionRef getState(String collection);
|
||||
|
||||
/**
|
||||
* Obtain set of live_nodes for the cluster.
|
||||
*/
|
||||
Set<String> liveNodes();
|
||||
|
||||
/**
|
||||
* Given an alias, returns the collection name that this alias points to
|
||||
*/
|
||||
String getAlias(String alias);
|
||||
|
||||
/**
|
||||
* Given a name, returns the collection name if an alias by that name exists, or
|
||||
* returns the name itself, if no alias exists.
|
||||
*/
|
||||
String getCollectionName(String name);
|
||||
|
||||
/**
|
||||
* Obtain a cluster property, or null if it doesn't exist.
|
||||
*/
|
||||
Object getClusterProperty(String propertyName);
|
||||
|
||||
/**
|
||||
* Obtain a cluster property, or the default value if it doesn't exist.
|
||||
*/
|
||||
Object getClusterProperty(String propertyName, String def);
|
||||
|
||||
void connect();
|
||||
}
|
@ -40,7 +40,7 @@ import org.apache.solr.common.util.SimpleOrderedMap;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
public class HttpClusterStateProvider implements CloudSolrClient.ClusterStateProvider {
|
||||
public class HttpClusterStateProvider implements ClusterStateProvider {
|
||||
private static final Logger log = LoggerFactory.getLogger(MethodHandles.lookup().lookupClass());
|
||||
|
||||
private String urlScheme;
|
||||
@ -72,8 +72,8 @@ public class HttpClusterStateProvider implements CloudSolrClient.ClusterStatePro
|
||||
throw new RuntimeException("Tried fetching live_nodes using Solr URLs provided, i.e. " + solrUrls + ". However, "
|
||||
+ "succeeded in obtaining the cluster state from none of them."
|
||||
+ "If you think your Solr cluster is up and is accessible,"
|
||||
+ " you could try re-creating a new CloudSolrClient using a working"
|
||||
+ " solrUrl or zkUrl.");
|
||||
+ " you could try re-creating a new CloudSolrClient using working"
|
||||
+ " solrUrl(s) or zkHost(s).");
|
||||
}
|
||||
}
|
||||
|
||||
@ -106,8 +106,8 @@ public class HttpClusterStateProvider implements CloudSolrClient.ClusterStatePro
|
||||
throw new RuntimeException("Tried fetching cluster state using the node names we knew of, i.e. " + liveNodes +". However, "
|
||||
+ "succeeded in obtaining the cluster state from none of them."
|
||||
+ "If you think your Solr cluster is up and is accessible,"
|
||||
+ " you could try re-creating a new CloudSolrClient using a working"
|
||||
+ " solrUrl or zkUrl.");
|
||||
+ " you could try re-creating a new CloudSolrClient using working"
|
||||
+ " solrUrl(s) or zkHost(s).");
|
||||
}
|
||||
|
||||
@SuppressWarnings({"rawtypes", "unchecked"})
|
||||
@ -118,7 +118,8 @@ public class HttpClusterStateProvider implements CloudSolrClient.ClusterStatePro
|
||||
QueryRequest request = new QueryRequest(params);
|
||||
request.setPath("/admin/collections");
|
||||
NamedList cluster = (SimpleOrderedMap) client.request(request).get("cluster");
|
||||
Map<String, Object> collectionsMap = ((NamedList) cluster.get("collections")).asShallowMap();
|
||||
Map<String, Object> collectionsMap = Collections.singletonMap(collection,
|
||||
((NamedList) cluster.get("collections")).get(collection));
|
||||
int znodeVersion = (int)((Map<String, Object>)(collectionsMap).get(collection)).get("znodeVersion");
|
||||
Set<String> liveNodes = new HashSet((List<String>)(cluster.get("live_nodes")));
|
||||
this.liveNodes = liveNodes;
|
||||
@ -133,8 +134,8 @@ public class HttpClusterStateProvider implements CloudSolrClient.ClusterStatePro
|
||||
throw new RuntimeException("We don't know of any live_nodes to fetch the"
|
||||
+ " latest live_nodes information from. "
|
||||
+ "If you think your Solr cluster is up and is accessible,"
|
||||
+ " you could try re-creating a new CloudSolrClient using a working"
|
||||
+ " solrUrl or zkUrl.");
|
||||
+ " you could try re-creating a new CloudSolrClient using working"
|
||||
+ " solrUrl(s) or zkHost(s).");
|
||||
}
|
||||
if (TimeUnit.SECONDS.convert((System.nanoTime() - liveNodesTimestamp), TimeUnit.NANOSECONDS) > getCacheTimeout()) {
|
||||
for (String nodeName: liveNodes) {
|
||||
@ -153,8 +154,8 @@ public class HttpClusterStateProvider implements CloudSolrClient.ClusterStatePro
|
||||
throw new RuntimeException("Tried fetching live_nodes using all the node names we knew of, i.e. " + liveNodes +". However, "
|
||||
+ "succeeded in obtaining the cluster state from none of them."
|
||||
+ "If you think your Solr cluster is up and is accessible,"
|
||||
+ " you could try re-creating a new CloudSolrClient using a working"
|
||||
+ " solrUrl or zkUrl.");
|
||||
+ " you could try re-creating a new CloudSolrClient using working"
|
||||
+ " solrUrl(s) or zkHost(s).");
|
||||
} else {
|
||||
return liveNodes; // cached copy is fresh enough
|
||||
}
|
||||
@ -171,9 +172,9 @@ public class HttpClusterStateProvider implements CloudSolrClient.ClusterStatePro
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getAlias(String collection) {
|
||||
public String getAlias(String alias) {
|
||||
Map<String, String> aliases = getAliases(false);
|
||||
return aliases.get(collection);
|
||||
return aliases.get(alias);
|
||||
}
|
||||
|
||||
private Map<String, String> getAliases(boolean forceFetch) {
|
||||
@ -181,8 +182,8 @@ public class HttpClusterStateProvider implements CloudSolrClient.ClusterStatePro
|
||||
throw new RuntimeException("We don't know of any live_nodes to fetch the"
|
||||
+ " latest aliases information from. "
|
||||
+ "If you think your Solr cluster is up and is accessible,"
|
||||
+ " you could try re-creating a new CloudSolrClient using a working"
|
||||
+ " solrUrl or zkUrl.");
|
||||
+ " you could try re-creating a new CloudSolrClient using working"
|
||||
+ " solrUrl(s) or zkHost(s).");
|
||||
}
|
||||
|
||||
if (forceFetch || this.aliases == null ||
|
||||
@ -197,6 +198,14 @@ public class HttpClusterStateProvider implements CloudSolrClient.ClusterStatePro
|
||||
this.aliasesTimestamp = System.nanoTime();
|
||||
return Collections.unmodifiableMap(aliases);
|
||||
} catch (SolrServerException | RemoteSolrException | IOException e) {
|
||||
// Situation where we're hitting an older Solr which doesn't have LISTALIASES
|
||||
if (e instanceof RemoteSolrException && ((RemoteSolrException)e).code()==400) {
|
||||
log.warn("LISTALIASES not found, possibly using older Solr server. Aliases won't work"
|
||||
+ " unless you re-create the CloudSolrClient using zkHost(s) or upgrade Solr server", e);
|
||||
this.aliases = Collections.emptyMap();
|
||||
this.aliasesTimestamp = System.nanoTime();
|
||||
return aliases;
|
||||
}
|
||||
log.warn("Attempt to fetch cluster state from " +
|
||||
ZkStateReader.getBaseUrlForNodeName(nodeName, urlScheme) + " failed.", e);
|
||||
}
|
||||
@ -206,7 +215,7 @@ public class HttpClusterStateProvider implements CloudSolrClient.ClusterStatePro
|
||||
+ "succeeded in obtaining the cluster state from none of them."
|
||||
+ "If you think your Solr cluster is up and is accessible,"
|
||||
+ " you could try re-creating a new CloudSolrClient using a working"
|
||||
+ " solrUrl or zkUrl.");
|
||||
+ " solrUrl or zkHost.");
|
||||
} else {
|
||||
return Collections.unmodifiableMap(this.aliases); // cached copy is fresh enough
|
||||
}
|
||||
|
@ -34,7 +34,7 @@ import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
|
||||
public class ZkClientClusterStateProvider implements CloudSolrClient.ClusterStateProvider {
|
||||
public class ZkClientClusterStateProvider implements ClusterStateProvider {
|
||||
private static final Logger log = LoggerFactory.getLogger(MethodHandles.lookup().lookupClass());
|
||||
|
||||
|
||||
@ -63,9 +63,9 @@ public class ZkClientClusterStateProvider implements CloudSolrClient.ClusterStat
|
||||
|
||||
|
||||
@Override
|
||||
public String getAlias(String collection) {
|
||||
public String getAlias(String alias) {
|
||||
Aliases aliases = zkStateReader.getAliases();
|
||||
return aliases.getCollectionAlias(collection);
|
||||
return aliases.getCollectionAlias(alias);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -117,9 +117,9 @@ public class CloudSolrClientCacheTest extends SolrTestCaseJ4 {
|
||||
return mockLbclient;
|
||||
}
|
||||
|
||||
private CloudSolrClient.ClusterStateProvider getStateProvider(Set<String> livenodes,
|
||||
private ClusterStateProvider getStateProvider(Set<String> livenodes,
|
||||
Map<String, ClusterState.CollectionRef> colls) {
|
||||
return new CloudSolrClient.ClusterStateProvider() {
|
||||
return new ClusterStateProvider() {
|
||||
@Override
|
||||
public ClusterState.CollectionRef getState(String collection) {
|
||||
return colls.get(collection);
|
||||
|
Loading…
x
Reference in New Issue
Block a user