| /* |
| * 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.routing; |
| |
| import org.apache.solr.common.params.CommonParams; |
| import org.apache.solr.common.params.ShardParams; |
| import org.apache.solr.common.params.SolrParams; |
| import org.apache.solr.common.util.NamedList; |
| |
| /** |
| * Factory for constructing an {@link AffinityReplicaListTransformer} that reorders replica routing |
| * preferences deterministically, based on request parameters. |
| * |
| * Default names of params that contain the values by which routing is determined may be configured |
| * at the time of {@link AffinityReplicaListTransformerFactory} construction, and may be |
| * overridden by the config spec passed to {@link #getInstance(String, SolrParams, ReplicaListTransformerFactory)} |
| * |
| * If no defaultHashParam name is specified at time of factory construction, the routing dividend will |
| * be derived by hashing the {@link String} value of the {@link CommonParams#Q} param. |
| */ |
| public class AffinityReplicaListTransformerFactory implements ReplicaListTransformerFactory { |
| private final String defaultDividendParam; |
| private final String defaultHashParam; |
| |
| public AffinityReplicaListTransformerFactory() { |
| this.defaultDividendParam = null; |
| this.defaultHashParam = CommonParams.Q; |
| } |
| |
| public AffinityReplicaListTransformerFactory(String defaultDividendParam, String defaultHashParam) { |
| this.defaultDividendParam = defaultDividendParam; |
| this.defaultHashParam = defaultHashParam; |
| } |
| |
| public AffinityReplicaListTransformerFactory(NamedList<?> c) { |
| this((String)c.get(ShardParams.ROUTING_DIVIDEND), translateHashParam((String)c.get(ShardParams.ROUTING_HASH))); |
| } |
| |
| /** |
| * Null arg indicates no configuration, which should be translated to the default value {@link CommonParams#Q}. |
| * Empty String is translated to null, allowing users to explicitly disable hash-based stable routing. |
| * |
| * @param hashParam configured hash param (null indicates unconfigured). |
| * @return translated value to be used as default hash param in RLT. |
| */ |
| private static String translateHashParam(String hashParam) { |
| if (hashParam == null) { |
| return CommonParams.Q; |
| } else if (hashParam.isEmpty()) { |
| return null; |
| } else { |
| return hashParam; |
| } |
| } |
| |
| @Override |
| public ReplicaListTransformer getInstance(String configSpec, SolrParams requestParams, ReplicaListTransformerFactory fallback) { |
| ReplicaListTransformer rlt; |
| if (configSpec == null) { |
| rlt = AffinityReplicaListTransformer.getInstance(defaultDividendParam, defaultHashParam, requestParams); |
| } else { |
| String[] parts = configSpec.split(":", 2); |
| switch (parts[0]) { |
| case ShardParams.ROUTING_DIVIDEND: |
| rlt = AffinityReplicaListTransformer.getInstance(parts.length == 1 ? defaultDividendParam : parts[1], defaultHashParam, requestParams); |
| break; |
| case ShardParams.ROUTING_HASH: |
| rlt = AffinityReplicaListTransformer.getInstance(null, parts.length == 1 ? defaultHashParam : parts[1], requestParams); |
| break; |
| default: |
| throw new IllegalArgumentException("Invalid routing spec: \"" + configSpec + '"'); |
| } |
| } |
| return rlt != null ? rlt : fallback.getInstance(null, requestParams, null); |
| } |
| |
| } |