com.yahoo.vespa.model.container.search.searchchain.SearchChains Maven / Gradle / Ivy
// Copyright Vespa.ai. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root.
package com.yahoo.vespa.model.container.search.searchchain;
import com.yahoo.collections.CollectionUtil;
import com.yahoo.component.provider.ComponentRegistry;
import com.yahoo.config.model.producer.TreeConfigProducer;
import com.yahoo.vespa.model.container.component.chain.Chains;
import com.yahoo.vespa.model.search.SearchCluster;
import com.yahoo.vespa.model.container.search.searchchain.defaultsearchchains.LocalClustersCreator;
import com.yahoo.vespa.model.container.search.searchchain.defaultsearchchains.VespaSearchChainsCreator;
import java.util.Collection;
import java.util.Map;
/**
* Root config producer of the whole search chains model (contains searchchains and searchers).
*
* @author Tony Vaagenes
*/
public class SearchChains extends Chains {
private final SourceGroupRegistry sourceGroups = new SourceGroupRegistry();
public SearchChains(TreeConfigProducer super Chains> parent, String subId) {
super(parent, subId);
}
public void initialize(Map searchClustersByName) {
LocalClustersCreator.addDefaultLocalProviders(this, searchClustersByName.keySet());
VespaSearchChainsCreator.addVespaSearchChains(this);
validateSourceGroups(); // must be done before initializing searchers since they are used by FederationSearchers
initializeComponents(searchClustersByName);
}
private void initializeComponents(Map searchClustersByName) {
setSearchClusterForLocalProvider(searchClustersByName);
initializeComponents();
}
private void setSearchClusterForLocalProvider(Map clusterIndexByName) {
for (LocalProvider provider : localProviders()) {
String clusterName = provider.getClusterName();
SearchCluster cluster = clusterIndexByName.get(clusterName);
if (cluster == null) {
if (clusterName.contains(".")) { // Is there a super cluster ...
String prefix = clusterName.substring(0, clusterName.indexOf('.'));
cluster = clusterIndexByName.get(prefix);
}
if (cluster == null) {
throw new IllegalArgumentException("No searchable content cluster with id '" + provider.getClusterName() + "'");
}
}
provider.setSearchCluster(cluster);
}
}
private void validateSourceGroups() {
for (SourceGroup sourceGroup : sourceGroups.groups()) {
sourceGroup.validate();
if (getChainGroup().getComponentMap().containsKey(sourceGroup.getComponentId())) {
throw new IllegalArgumentException("Id '" + sourceGroup.getComponentId() +
"' is used both for a source and another search chain/provider");
}
}
}
@Override
public void validate() throws Exception {
validateSourceGroups();
super.validate();
}
SourceGroupRegistry allSourceGroups() {
return sourceGroups;
}
public Collection localProviders() {
return CollectionUtil.filter(allChains().allComponents(), LocalProvider.class);
}
/*
* If searchChain is a provider, its sources must already have been attached.
*/
@Override
public void add(SearchChain searchChain) {
assert !(searchChain instanceof Source);
super.add(searchChain);
if (searchChain instanceof Provider) {
sourceGroups.addSources((Provider)searchChain);
}
}
@Override
public ComponentRegistry allChains() {
ComponentRegistry allChains = new ComponentRegistry<>();
for (SearchChain chain : getChainGroup().getComponents()) {
allChains.register(chain.getId(), chain);
if (chain instanceof Provider)
addSources(allChains, (Provider)chain);
}
allChains.freeze();
return allChains;
}
private static void addSources(ComponentRegistry chains, Provider provider) {
for (Source source : provider.getSources()) {
chains.register(source.getId(), source);
}
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy