From 8070bd0d1a0cd0eda908cc32fc2506d247ec2f67 Mon Sep 17 00:00:00 2001 From: Henning Baldersheim Date: Mon, 23 Sep 2019 16:18:40 +0200 Subject: Revert "Revert "Balder/remove tld from config model rebased"" --- .../model/builder/xml/dom/VespaDomBuilder.java | 36 +- .../model/container/search/ContainerSearch.java | 9 +- .../com/yahoo/vespa/model/content/Content.java | 17 - .../model/content/cluster/ContentCluster.java | 8 - .../com/yahoo/vespa/model/search/Dispatch.java | 247 ------------- .../yahoo/vespa/model/search/DispatchGroup.java | 38 +- .../vespa/model/search/DispatchGroupBuilder.java | 29 +- .../vespa/model/search/IndexedSearchCluster.java | 78 +---- .../java/com/yahoo/vespa/model/search/Tuning.java | 44 +-- .../model/provision/ModelProvisioningTest.java | 111 ------ .../model/builder/xml/dom/ContentBuilderTest.java | 62 +--- .../vespa/model/content/ContentClusterTest.java | 44 +-- .../content/IndexedHierarchicDistributionTest.java | 47 +-- .../vespa/model/content/cluster/ClusterTest.java | 130 ++++--- .../vespa/model/search/MultilevelDispatchTest.java | 382 --------------------- .../java/com/yahoo/vespa/model/search/TldTest.java | 146 -------- .../vespa/model/search/utils/DispatchUtils.java | 35 -- 17 files changed, 143 insertions(+), 1320 deletions(-) delete mode 100644 config-model/src/main/java/com/yahoo/vespa/model/search/Dispatch.java delete mode 100644 config-model/src/test/java/com/yahoo/vespa/model/search/MultilevelDispatchTest.java delete mode 100644 config-model/src/test/java/com/yahoo/vespa/model/search/TldTest.java delete mode 100644 config-model/src/test/java/com/yahoo/vespa/model/search/utils/DispatchUtils.java (limited to 'config-model') diff --git a/config-model/src/main/java/com/yahoo/vespa/model/builder/xml/dom/VespaDomBuilder.java b/config-model/src/main/java/com/yahoo/vespa/model/builder/xml/dom/VespaDomBuilder.java index a4f2ecd6675..ee4879f2203 100644 --- a/config-model/src/main/java/com/yahoo/vespa/model/builder/xml/dom/VespaDomBuilder.java +++ b/config-model/src/main/java/com/yahoo/vespa/model/builder/xml/dom/VespaDomBuilder.java @@ -3,7 +3,6 @@ package com.yahoo.vespa.model.builder.xml.dom; import com.yahoo.config.application.api.DeployLogger; import com.yahoo.config.model.ApplicationConfigProducerRoot; -import com.yahoo.config.model.ConfigModel; import com.yahoo.config.model.ConfigModelRepo; import com.yahoo.config.model.deploy.DeployState; import com.yahoo.config.model.builder.xml.XmlHelper; @@ -181,7 +180,7 @@ public class VespaDomBuilder extends VespaModelBuilder { if (port > 0) { t.setBasePort(port); } - allocateHost(t, hostSystem, producerSpec, deployState.getDeployLogger()); + allocateHost(t, hostSystem, producerSpec); } // This depends on which constructor in AbstractService is used, but the best way // is to let this method do initialize. @@ -199,7 +198,7 @@ public class VespaDomBuilder extends VespaModelBuilder { * @param producerSpec xml element for the service */ private void allocateHost(final AbstractService service, HostSystem hostSystem, - Element producerSpec, DeployLogger deployLogger) + Element producerSpec) { // TODO store service on something else than HostSystem, to not make that overloaded service.setHostResource(hostSystem.getHost(producerSpec.getAttribute("hostalias"))); @@ -207,15 +206,15 @@ public class VespaDomBuilder extends VespaModelBuilder { } /** - * The SimpleConfigProducer is the producer for elements such as qrservers, topleveldispatchers, gateways. + * The SimpleConfigProducer is the producer for elements such as qrservers, gateways. * Must support overrides for that too, hence this builder * * @author vegardh */ - public static class DomSimpleConfigProducerBuilder extends DomConfigProducerBuilder { - private String configId = null; + static class DomSimpleConfigProducerBuilder extends DomConfigProducerBuilder { + private String configId; - public DomSimpleConfigProducerBuilder(String configId) { + DomSimpleConfigProducerBuilder(String configId) { this.configId = configId; } @@ -231,7 +230,7 @@ public class VespaDomBuilder extends VespaModelBuilder { /** * @param name The name of the Vespa to create. Usually 'root' when there is only one. */ - public DomRootBuilder(String name) { + DomRootBuilder(String name) { this.name = name; } @@ -248,16 +247,6 @@ public class VespaDomBuilder extends VespaModelBuilder { } } - /** - * Gets the index from a service's spec - * - * @param spec The element containing the xml specification for this Service. - * @return the index of the service, which is retrieved from the xml spec. - */ - static int getIndex(Element spec) { - return getXmlIntegerAttribute(spec, "index"); - } - /** * Gets an integer attribute value from a service's spec * @@ -265,7 +254,7 @@ public class VespaDomBuilder extends VespaModelBuilder { * @param attributeName nam of attribute to get value from * @return value of attribute, or 0 if it does not exist or is empty */ - static int getXmlIntegerAttribute(Element spec, String attributeName) { + private static int getXmlIntegerAttribute(Element spec, String attributeName) { String value = (spec == null) ? null : spec.getAttribute(attributeName); if (value == null || value.equals("")) { return 0; @@ -287,7 +276,6 @@ public class VespaDomBuilder extends VespaModelBuilder { * @param configModelRepo a {@link ConfigModelRepo} */ public void postProc(DeployLogger deployLogger, AbstractConfigProducer root, ConfigModelRepo configModelRepo) { - createTlds(deployLogger, configModelRepo); setContentSearchClusterIndexes(configModelRepo); createDocprocMBusServersAndClients(configModelRepo); } @@ -303,14 +291,6 @@ public class VespaDomBuilder extends VespaModelBuilder { docproc.getChains().addServersAndClientsForChains(); } - private void createTlds(DeployLogger deployLogger, ConfigModelRepo pc) { - for (ConfigModel p : pc.asMap().values()) { - if (p instanceof Content) { - ((Content)p).createTlds(deployLogger, pc); - } - } - } - /** * For some reason, search clusters need to be enumerated. * @param configModelRepo a {@link ConfigModelRepo} diff --git a/config-model/src/main/java/com/yahoo/vespa/model/container/search/ContainerSearch.java b/config-model/src/main/java/com/yahoo/vespa/model/container/search/ContainerSearch.java index 84e8cdf144f..5266fc46f6e 100644 --- a/config-model/src/main/java/com/yahoo/vespa/model/container/search/ContainerSearch.java +++ b/config-model/src/main/java/com/yahoo/vespa/model/container/search/ContainerSearch.java @@ -12,7 +12,6 @@ import com.yahoo.vespa.model.container.component.ContainerSubsystem; import com.yahoo.vespa.model.container.search.searchchain.LocalProvider; import com.yahoo.vespa.model.container.search.searchchain.SearchChains; import com.yahoo.vespa.model.search.AbstractSearchCluster; -import com.yahoo.vespa.model.search.Dispatch; import com.yahoo.vespa.model.search.IndexedSearchCluster; import com.yahoo.vespa.model.search.StreamingSearchCluster; @@ -124,13 +123,7 @@ public class ContainerSearch extends ContainerSubsystem } scB.rankprofiles(new QrSearchersConfig.Searchcluster.Rankprofiles.Builder().configid(sys.getConfigId())); scB.indexingmode(QrSearchersConfig.Searchcluster.Indexingmode.Enum.valueOf(sys.getIndexingModeName())); - if (sys instanceof IndexedSearchCluster) { - for (Dispatch tld: ((IndexedSearchCluster)sys).getTLDs()) { - scB.dispatcher(new QrSearchersConfig.Searchcluster.Dispatcher.Builder(). - host(tld.getHostname()). - port(tld.getDispatchPort())); - } - } else { + if ( ! (sys instanceof IndexedSearchCluster)) { scB.storagecluster(new QrSearchersConfig.Searchcluster.Storagecluster.Builder(). routespec(((StreamingSearchCluster)sys).getStorageRouteSpec())); } diff --git a/config-model/src/main/java/com/yahoo/vespa/model/content/Content.java b/config-model/src/main/java/com/yahoo/vespa/model/content/Content.java index 74caf2d8026..8533c8d430f 100644 --- a/config-model/src/main/java/com/yahoo/vespa/model/content/Content.java +++ b/config-model/src/main/java/com/yahoo/vespa/model/content/Content.java @@ -81,23 +81,6 @@ public class Content extends ConfigModel { */ public Optional ownedIndexingCluster() { return ownedIndexingCluster; } - public void createTlds(DeployLogger deployLogger, ConfigModelRepo modelRepo) { - IndexedSearchCluster indexedCluster = cluster.getSearch().getIndexed(); - if (indexedCluster == null) return; - - SimpleConfigProducer tldParent = new SimpleConfigProducer(indexedCluster, "tlds"); - for (ConfigModel model : modelRepo.asMap().values()) { - if ( ! (model instanceof ContainerModel)) continue; - - ContainerCluster containerCluster = ((ContainerModel) model).getCluster(); - if (containerCluster.getSearch() == null) continue; // this is not a qrs cluster - - log.log(LogLevel.DEBUG, "Adding tlds for indexed cluster " + indexedCluster.getClusterName() + ", container cluster " + containerCluster.getName()); - indexedCluster.addTldsWithSameIdsAsContainers(deployLogger, tldParent, containerCluster); - } - indexedCluster.setupDispatchGroups(deployLogger); - } - private static boolean containsIndexingChain(ComponentRegistry allChains, ChainSpecification chainSpec) { if (IndexingDocprocChain.NAME.equals(chainSpec.componentId.stringValue())) return true; diff --git a/config-model/src/main/java/com/yahoo/vespa/model/content/cluster/ContentCluster.java b/config-model/src/main/java/com/yahoo/vespa/model/content/cluster/ContentCluster.java index fc79a3f4bbf..fdf88124012 100644 --- a/config-model/src/main/java/com/yahoo/vespa/model/content/cluster/ContentCluster.java +++ b/config-model/src/main/java/com/yahoo/vespa/model/content/cluster/ContentCluster.java @@ -186,11 +186,6 @@ public class ContentCluster extends AbstractConfigProducer implements } index.setSearchCoverage(DomSearchCoverageBuilder.build(element)); index.setDispatchSpec(DomDispatchBuilder.build(element)); - if (index.useMultilevelDispatchSetup()) { - // We must validate this before we add tlds and setup the dispatch groups. - // This must therefore happen before the regular validate() step. - new MultilevelDispatchValidator(index.getClusterName(), index.getDispatchSpec(), index.getSearchNodes()).validate(); - } // TODO: This should be cleaned up to avoid having to change code in 100 places // every time we add a dispatch option. @@ -656,9 +651,6 @@ public class ContentCluster extends AbstractConfigProducer implements if (search.usesHierarchicDistribution() && !isHosted) { // validate manually configured groups new IndexedHierarchicDistributionValidator(search.getClusterName(), rootGroup, redundancy, search.getIndexed().getTuning().dispatch.policy).validate(); - if (search.getIndexed().useMultilevelDispatchSetup()) { - throw new IllegalArgumentException("In indexed content cluster '" + search.getClusterName() + "': Using multi-level dispatch setup is not supported when using hierarchical distribution."); - } } new ReservedDocumentTypeNameValidator().validate(documentDefinitions); new GlobalDistributionValidator().validate(documentDefinitions, globallyDistributedDocuments); diff --git a/config-model/src/main/java/com/yahoo/vespa/model/search/Dispatch.java b/config-model/src/main/java/com/yahoo/vespa/model/search/Dispatch.java deleted file mode 100644 index 2e821a67cb2..00000000000 --- a/config-model/src/main/java/com/yahoo/vespa/model/search/Dispatch.java +++ /dev/null @@ -1,247 +0,0 @@ -// Copyright 2017 Yahoo Holdings. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root. -package com.yahoo.vespa.model.search; - -import com.yahoo.vespa.config.search.core.FdispatchrcConfig; -import com.yahoo.vespa.config.search.core.PartitionsConfig; -import com.yahoo.config.model.producer.AbstractConfigProducer; -import com.yahoo.vespa.model.AbstractService; -import com.yahoo.vespa.model.PortAllocBridge; -import com.yahoo.vespa.model.application.validation.RestartConfigs; -import com.yahoo.vespa.model.content.SearchCoverage; - -import java.util.ArrayList; -import java.util.List; - -/** - * Represents a dispatch (top-level (tld) or mid-level). - * There must be one or more tld instances in a search cluster. - * - * @author arnej27959 - */ -@RestartConfigs({FdispatchrcConfig.class, PartitionsConfig.class}) -public class Dispatch extends AbstractService implements SearchInterface, - FdispatchrcConfig.Producer, - PartitionsConfig.Producer { - - private static final String TLD_NAME = "tld"; - private static final String DISPATCH_NAME = "dispatch"; - - private static final long serialVersionUID = 1L; - private final DispatchGroup dispatchGroup; - private final NodeSpec nodeSpec; - private final int dispatchLevel; - private final boolean preferLocalRow; - private final boolean isTopLevel; - private boolean useAdaptiveDispatch; - - private Dispatch(DispatchGroup dispatchGroup, AbstractConfigProducer parent, String subConfigId, - NodeSpec nodeSpec, int dispatchLevel, boolean preferLocalRow, boolean isTopLevel) { - super(parent, subConfigId); - this.dispatchGroup = dispatchGroup; - this.nodeSpec = nodeSpec; - this.dispatchLevel = dispatchLevel; - this.preferLocalRow = preferLocalRow; - this.isTopLevel = isTopLevel; - this.useAdaptiveDispatch = false; - portsMeta.on(0).tag("rpc").tag("admin"); - portsMeta.on(1).tag("fs4"); - portsMeta.on(2).tag("http").tag("json").tag("health").tag("state"); - setProp("clustertype", "search") - .setProp("clustername", dispatchGroup.getClusterName()) - .setProp("index", nodeSpec.groupIndex()); - } - - public Dispatch useAdaptiveDispatch(boolean useAdaptiveDispatch) { - this.useAdaptiveDispatch = useAdaptiveDispatch; - return this; - } - - public static Dispatch createTld(DispatchGroup dispatchGroup, AbstractConfigProducer parent, int rowId) { - return createTld(dispatchGroup, parent, rowId, false); - } - - public static Dispatch createTld(DispatchGroup dispatchGroup, AbstractConfigProducer parent, int rowId, boolean preferLocalRow) { - String subConfigId = TLD_NAME + "." + rowId; - return new Dispatch(dispatchGroup, parent, subConfigId, new NodeSpec(rowId, 0), 0, preferLocalRow, true); - } - - public static Dispatch createTldWithContainerIdInName(DispatchGroup dispatchGroup, AbstractConfigProducer parent, String containerName, int containerIndex) { - String subConfigId = containerName + "." + containerIndex + "." + TLD_NAME + "." + containerIndex; - return new Dispatch(dispatchGroup, parent, subConfigId, new NodeSpec(containerIndex, 0), 0, false, true); - } - - public static Dispatch createDispatchWithStableConfigId(DispatchGroup dispatchGroup, AbstractConfigProducer parent, NodeSpec nodeSpec, int distributionKey, int dispatchLevel) { - String subConfigId = DISPATCH_NAME + "." + distributionKey; - return new Dispatch(dispatchGroup, parent, subConfigId, nodeSpec, dispatchLevel, false, false); - } - - /** - * Override the default service-type - * @return String "topleveldispatch" - */ - public String getServiceType() { - return "topleveldispatch"; - } - - /** - * @return the startup command - */ - public String getStartupCommand() { - return "exec sbin/vespa-dispatch -c $VESPA_CONFIG_ID"; - } - - private int getFrtPort() { return getRelativePort(0); } - public int getDispatchPort() { return getRelativePort(1); } - @Override - public int getHealthPort() { return getRelativePort(2); } - - /** - * Twice the default of the number of threads in the container. - * Could have been unbounded if it was not roundrobin, but stack based usage in dispatch. - * We are not putting to much magic into this one as this will disappear as soon as - * dispatch is implemented in Java. - */ - public int getMaxThreads() { return 500*2; } - - public String getHostname() { - return getHost().getHostname(); - } - - @Override - public NodeSpec getNodeSpec() { - return nodeSpec; - } - - public String getDispatcherConnectSpec() { - return "tcp/" + getHost().getHostname() + ":" + getDispatchPort(); - } - - public DispatchGroup getDispatchGroup() { - return dispatchGroup; - } - - @Override - public void getConfig(FdispatchrcConfig.Builder builder) { - builder.ptport(getDispatchPort()). - frtport(getFrtPort()). - healthport(getHealthPort()). - maxthreads(getMaxThreads()); - if (!isTopLevel) { - builder.partition(getNodeSpec().partitionId()); - builder.dispatchlevel(dispatchLevel); - } - } - - @Override - public void getConfig(PartitionsConfig.Builder builder) { - int rowbits = dispatchGroup.getRowBits(); - final PartitionsConfig.Dataset.Builder datasetBuilder = new PartitionsConfig.Dataset.Builder(). - id(0). - searchablecopies(dispatchGroup.getSearchableCopies()). - refcost(1). - rowbits(rowbits). - numparts(dispatchGroup.getNumPartitions()). - mpp(dispatchGroup.getMinNodesPerColumn()); - if (dispatchGroup.useFixedRowInDispatch()) { - datasetBuilder.querydistribution(PartitionsConfig.Dataset.Querydistribution.Enum.FIXEDROW); - datasetBuilder.maxnodesdownperfixedrow(dispatchGroup.getMaxNodesDownPerFixedRow()); - } - if (useAdaptiveDispatch) { - datasetBuilder.useroundrobinforfixedrow(false); - } - SearchCoverage coverage = dispatchGroup.getSearchCoverage(); - if (coverage != null) { - if (coverage.getMinimum() != null) { - datasetBuilder.minimal_searchcoverage(coverage.getMinimum() * 100); // as percentage - } - if (coverage.getMinWaitAfterCoverageFactor() != null) { - datasetBuilder.higher_coverage_minsearchwait(coverage.getMinWaitAfterCoverageFactor()); - } - if (coverage.getMaxWaitAfterCoverageFactor() != null) { - datasetBuilder.higher_coverage_maxsearchwait(coverage.getMaxWaitAfterCoverageFactor()); - } - } - - Tuning tuning = dispatchGroup.getTuning(); - boolean useLocalNode = false; - if (tuning != null && tuning.dispatch != null) { - useLocalNode = tuning.dispatch.useLocalNode; - } - final List allEngines = new ArrayList<>(); - for (SearchInterface searchNode : dispatchGroup.getSearchersIterable()) { - final PartitionsConfig.Dataset.Engine.Builder engineBuilder = new PartitionsConfig.Dataset.Engine.Builder(). - name_and_port(searchNode.getDispatcherConnectSpec()). - rowid(searchNode.getNodeSpec().groupIndex()). - partid(searchNode.getNodeSpec().partitionId()); - allEngines.add(engineBuilder); - if (preferLocalRow) { - if (getHostname().equals(searchNode.getHostName())) { - engineBuilder.refcost(1); - } else { - engineBuilder.refcost(Integer.MAX_VALUE); - } - } - - if (!useLocalNode || getHostname().equals(searchNode.getHostName())) { - if (useLocalNode) { - engineBuilder.rowid(0); - } - datasetBuilder.engine.add(engineBuilder); - - } - } - //Do not create empty engine list for a dataset if no local search nodes found - if(datasetBuilder.engine.isEmpty() && useLocalNode) { - for(PartitionsConfig.Dataset.Engine.Builder engineBuilder: allEngines) { - datasetBuilder.engine.add(engineBuilder); - } - } - - builder.dataset.add(datasetBuilder); - - if (tuning != null) { - tuning.getConfig(builder); - scaleMaxHitsPerPartitions(builder, tuning); - } - } - - private int getNumLeafNodesInGroup() { - int numSearchers = 0; - for (SearchInterface search : dispatchGroup.getSearchersIterable()) { - if (search instanceof Dispatch) { - numSearchers += ((Dispatch) search).getNumLeafNodesInGroup(); - } else { - numSearchers++; - } - } - if (numSearchers > 0) { - // Divide by number of partitions, otherwise we would count the same leaf node partition number of times. - return numSearchers / dispatchGroup.getNumPartitions(); - } - return 0; - } - - private void scaleMaxHitsPerPartitions(PartitionsConfig.Builder builder, Tuning tuning) { - if (tuning == null || tuning.dispatch == null || tuning.dispatch.maxHitsPerPartition == null) { - return; - } - int numLeafNodes = getNumLeafNodesInGroup(); - for (PartitionsConfig.Dataset.Builder dataset : builder.dataset) { - dataset.maxhitspernode(tuning.dispatch.maxHitsPerPartition * numLeafNodes); - } - } - - @Override - public void allocatePorts(int start, PortAllocBridge from) { - // NB: ignore "start" - from.allocatePort("rpc"); - from.allocatePort("fs4"); - from.allocatePort("health"); - } - - /** - * @return the number of ports needed - */ - public int getPortCount() { return 3; } - -} diff --git a/config-model/src/main/java/com/yahoo/vespa/model/search/DispatchGroup.java b/config-model/src/main/java/com/yahoo/vespa/model/search/DispatchGroup.java index 3d57732efde..384f77737c1 100644 --- a/config-model/src/main/java/com/yahoo/vespa/model/search/DispatchGroup.java +++ b/config-model/src/main/java/com/yahoo/vespa/model/search/DispatchGroup.java @@ -1,9 +1,8 @@ // Copyright 2017 Yahoo Holdings. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root. package com.yahoo.vespa.model.search; -import com.yahoo.vespa.model.content.SearchCoverage; - -import java.util.*; +import java.util.Map; +import java.util.TreeMap; /** * Class representing a group of @link{SearchInterface} nodes and a set of @link{Dispatch} nodes. @@ -14,8 +13,7 @@ import java.util.*; */ public class DispatchGroup { - private final List dispatchers = new ArrayList<>(); - private final Map > searchers = new TreeMap<>(); + private final Map> searchers = new TreeMap<>(); final private IndexedSearchCluster sc; @@ -23,11 +21,6 @@ public class DispatchGroup { this.sc = sc; } - DispatchGroup addDispatcher(Dispatch dispatch) { - dispatchers.add(dispatch); - return this; - } - DispatchGroup addSearcher(SearchInterface search) { Map rows = searchers.get(search.getNodeSpec().partitionId()); if (rows == null) { @@ -43,15 +36,6 @@ public class DispatchGroup { return this; } - DispatchGroup clearSearchers() { - searchers.clear(); - return this; - } - - List getDispatchers() { - return Collections.unmodifiableList(dispatchers); - } - public Iterable getSearchersIterable() { return new Iterable(searchers); } @@ -68,28 +52,12 @@ public class DispatchGroup { return sc.useFixedRowInDispatch(); } - public int getMinNodesPerColumn() { - return sc.getMinNodesPerColumn(); - } - public int getSearchableCopies() { return sc.getSearchableCopies(); } public int getMaxNodesDownPerFixedRow() { return sc.getMaxNodesDownPerFixedRow(); } - SearchCoverage getSearchCoverage() { - return sc.getSearchCoverage(); - } - - Tuning getTuning() { - return sc.getTuning(); - } - - String getClusterName() { - return sc.getClusterName(); - } - static class Iterator implements java.util.Iterator { private java.util.Iterator> it1; private java.util.Iterator it2; diff --git a/config-model/src/main/java/com/yahoo/vespa/model/search/DispatchGroupBuilder.java b/config-model/src/main/java/com/yahoo/vespa/model/search/DispatchGroupBuilder.java index 4ff5fcab347..b489c5b9242 100644 --- a/config-model/src/main/java/com/yahoo/vespa/model/search/DispatchGroupBuilder.java +++ b/config-model/src/main/java/com/yahoo/vespa/model/search/DispatchGroupBuilder.java @@ -1,8 +1,6 @@ // Copyright 2017 Yahoo Holdings. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root. package com.yahoo.vespa.model.search; -import com.yahoo.config.application.api.DeployLogger; -import com.yahoo.vespa.model.HostResource; import com.yahoo.vespa.model.SimpleConfigProducer; import com.yahoo.vespa.model.content.DispatchSpec; @@ -30,49 +28,28 @@ public class DispatchGroupBuilder { this.searchCluster = searchCluster; } - public void build(DeployLogger deployLogger, List groupsSpec, List searchNodes) { + public void build(List groupsSpec, List searchNodes) { Map searchNodeMap = buildSearchNodeMap(searchNodes); for (int partId = 0; partId < groupsSpec.size(); ++partId) { DispatchSpec.Group groupSpec = groupsSpec.get(partId); DispatchGroup group = new DispatchGroup(searchCluster); - populateDispatchGroup(deployLogger, group, groupSpec.getNodes(), searchNodeMap, partId); + populateDispatchGroup(group, groupSpec.getNodes(), searchNodeMap, partId); } } - private void populateDispatchGroup(DeployLogger deployLogger, - DispatchGroup group, + private void populateDispatchGroup(DispatchGroup group, List nodeList, Map searchNodesMap, int partId) { for (int rowId = 0; rowId < nodeList.size(); ++rowId) { int distributionKey = nodeList.get(rowId).getDistributionKey(); SearchNode searchNode = searchNodesMap.get(distributionKey); - Dispatch dispatch = buildDispatch(deployLogger, group, new NodeSpec(rowId, partId), distributionKey, searchNode.getHostResource()); - group.addDispatcher(dispatch); - rootDispatch.addSearcher(dispatch); // Note: the rowId in this context will be the partId for the underlying search node. group.addSearcher(buildSearchInterface(searchNode, rowId)); } } - /** - * Builds a mid-level dispatcher with a configId containing the same stable distribution-key as the search node it - * is located on. - * - * If this.dispatchParent has subConfigId 'dispatchers', the config ids of the mid-level - * dispatchers are '../dispatchers/dispatch.X' where X is the distribution-key of the search node. - * - * The dispatch group that will contain this mid-level dispatcher is no longer part of the config producer tree, - * but only contains information about the dispatchers and searchers in this group. - */ - private Dispatch buildDispatch(DeployLogger deployLogger, DispatchGroup group, NodeSpec nodeSpec, int distributionKey, HostResource hostResource) { - Dispatch dispatch = Dispatch.createDispatchWithStableConfigId(group, dispatchParent, nodeSpec, distributionKey, 1); - dispatch.setHostResource(hostResource); - dispatch.initService(deployLogger); - return dispatch; - } - private static SearchInterface buildSearchInterface(SearchNode searchNode, int partId) { searchNode.updatePartition(partId); // ensure that search node uses the same partId as dispatch sees return new SearchNodeWrapper(new NodeSpec(0, partId), searchNode); diff --git a/config-model/src/main/java/com/yahoo/vespa/model/search/IndexedSearchCluster.java b/config-model/src/main/java/com/yahoo/vespa/model/search/IndexedSearchCluster.java index 76617bf1b9f..40cc09938e2 100644 --- a/config-model/src/main/java/com/yahoo/vespa/model/search/IndexedSearchCluster.java +++ b/config-model/src/main/java/com/yahoo/vespa/model/search/IndexedSearchCluster.java @@ -1,10 +1,8 @@ // Copyright 2017 Yahoo Holdings. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root. package com.yahoo.vespa.model.search; -import com.yahoo.config.application.api.DeployLogger; import com.yahoo.config.model.deploy.DeployState; import com.yahoo.config.model.producer.AbstractConfigProducer; -import com.yahoo.log.LogLevel; import com.yahoo.prelude.fastsearch.DocumentdbInfoConfig; import com.yahoo.search.config.IndexInfoConfig; import com.yahoo.searchdefinition.DocumentOnlySearch; @@ -15,10 +13,6 @@ import com.yahoo.vespa.config.search.DispatchConfig.DistributionPolicy; import com.yahoo.vespa.config.search.RankProfilesConfig; import com.yahoo.vespa.config.search.core.ProtonConfig; import com.yahoo.vespa.configdefinition.IlscriptsConfig; -import com.yahoo.vespa.model.HostResource; -import com.yahoo.vespa.model.SimpleConfigProducer; -import com.yahoo.vespa.model.container.Container; -import com.yahoo.vespa.model.container.ContainerCluster; import com.yahoo.vespa.model.container.docproc.DocprocChain; import com.yahoo.vespa.model.content.DispatchSpec; import com.yahoo.vespa.model.content.SearchCoverage; @@ -29,7 +23,6 @@ import java.util.Collections; import java.util.Iterator; import java.util.LinkedList; import java.util.List; -import java.util.logging.Logger; /** * @author baldersheim @@ -85,8 +78,6 @@ public class IndexedSearchCluster extends SearchCluster } } - private static final Logger log = Logger.getLogger(IndexedSearchCluster.class.getName()); - private String indexingClusterName = null; // The name of the docproc cluster to run indexing, by config. private String indexingChainName = null; @@ -103,7 +94,6 @@ public class IndexedSearchCluster extends SearchCluster private int searchableCopies = 1; - private final SimpleConfigProducer dispatchParent; private final DispatchGroup rootDispatch; private DispatchSpec dispatchSpec; private final boolean useAdaptiveDispatch; @@ -122,7 +112,6 @@ public class IndexedSearchCluster extends SearchCluster public IndexedSearchCluster(AbstractConfigProducer parent, String clusterName, int index, DeployState deployState) { super(parent, clusterName, index); unionCfg = new UnionConfiguration(this, documentDbs); - dispatchParent = new SimpleConfigProducer(this, "dispatchers"); rootDispatch = new DispatchGroup(this); useAdaptiveDispatch = deployState.getProperties().useAdaptiveDispatch(); } @@ -183,46 +172,6 @@ public class IndexedSearchCluster extends SearchCluster return this; } - public Dispatch addTld(DeployLogger deployLogger, AbstractConfigProducer tldParent, HostResource hostResource) { - int index = rootDispatch.getDispatchers().size(); - Dispatch tld = Dispatch.createTld(rootDispatch, tldParent, index); - tld.useAdaptiveDispatch(useAdaptiveDispatch); - tld.setHostResource(hostResource); - tld.initService(deployLogger); - rootDispatch.addDispatcher(tld); - return tld; - } - - /** - * Make sure to allocate tld with same id as container (i.e if container cluster name is 'foo', with containers - * with index 0,1,2 the tlds created will get names ../foo.0.tld.0, ../foo.1.tld.1, ../foo.2.tld.2, so that tld config id is - * stable no matter what changes are done to the number of containers in a container cluster - * @param tldParent the indexed search cluster the tlds to add should be connected to - * @param containerCluster the container cluster that should use the tlds created for searching the indexed search cluster above - */ - public void addTldsWithSameIdsAsContainers(DeployLogger deployLogger, AbstractConfigProducer tldParent, ContainerCluster containerCluster) { - for (Container container : containerCluster.getContainers()) { - String containerSubId = container.getSubId(); - if ( ! containerSubId.contains(".")) { - throw new RuntimeException("Expected container sub id to be of the form string.number"); - } - int containerIndex = Integer.parseInt(containerSubId.split("\\.")[1]); - String containerClusterName = containerCluster.getName(); - log.log(LogLevel.DEBUG, "Adding tld with index " + containerIndex + " for content cluster " + this.getClusterName() + - ", container cluster " + containerClusterName + " (container id " + containerSubId + - ") on host " + container.getHostResource().getHostname()); - rootDispatch.addDispatcher(createTld(deployLogger, tldParent, container.getHostResource(), containerClusterName, containerIndex).useAdaptiveDispatch(useAdaptiveDispatch)); - } - } - - private Dispatch createTld(DeployLogger deployLogger, AbstractConfigProducer tldParent, HostResource hostResource, String containerClusterName, int containerIndex) { - Dispatch tld = Dispatch.createTldWithContainerIdInName(rootDispatch, tldParent, containerClusterName, containerIndex); - tld.useAdaptiveDispatch(useAdaptiveDispatch); - tld.setHostResource(hostResource); - tld.initService(deployLogger); - return tld; - } - public DispatchGroup getRootDispatch() { return rootDispatch; } public void addSearcher(SearchNode searcher) { @@ -230,8 +179,6 @@ public class IndexedSearchCluster extends SearchCluster rootDispatch.addSearcher(searcher); } - public List getTLDs() { return rootDispatch.getDispatchers(); } - public List getSearchNodes() { return Collections.unmodifiableList(searchNodes); } public int getSearchNodeCount() { return searchNodes.size(); } public SearchNode getSearchNode(int index) { return searchNodes.get(index); } @@ -327,10 +274,6 @@ public class IndexedSearchCluster extends SearchCluster this.searchCoverage = searchCoverage; } - SearchCoverage getSearchCoverage() { - return searchCoverage; - } - @Override public DerivedConfiguration getSdConfig() { return null; } @@ -357,8 +300,6 @@ public class IndexedSearchCluster extends SearchCluster @Override protected void exportSdFiles(File toDir) { } - int getMinNodesPerColumn() { return 0; } - boolean useFixedRowInDispatch() { for (SearchNode node : getSearchNodes()) { if (node.getNodeSpec().groupIndex() > 0) { @@ -397,18 +338,6 @@ public class IndexedSearchCluster extends SearchCluster return dispatchSpec; } - public boolean useMultilevelDispatchSetup() { - return dispatchSpec != null && dispatchSpec.getGroups() != null && !dispatchSpec.getGroups().isEmpty(); - } - - public void setupDispatchGroups(DeployLogger deployLogger) { - if (!useMultilevelDispatchSetup()) { - return; - } - rootDispatch.clearSearchers(); - new DispatchGroupBuilder(dispatchParent, rootDispatch, this).build(deployLogger, dispatchSpec.getGroups(), getSearchNodes()); - } - @Override public void getConfig(DispatchConfig.Builder builder) { for (SearchNode node : getSearchNodes()) { @@ -420,6 +349,9 @@ public class IndexedSearchCluster extends SearchCluster nodeBuilder.fs4port(node.getDispatchPort()); builder.node(nodeBuilder); } + if (useAdaptiveDispatch) + builder.distributionPolicy(DistributionPolicy.ADAPTIVE); + if (tuning.dispatch.minActiveDocsCoverage != null) builder.minActivedocsPercentage(tuning.dispatch.minActiveDocsCoverage); if (tuning.dispatch.minGroupCoverage != null) @@ -434,8 +366,10 @@ public class IndexedSearchCluster extends SearchCluster break; } } + if (tuning.dispatch.maxHitsPerPartition != null) + builder.maxHitsPerNode(tuning.dispatch.maxHitsPerPartition); + builder.maxNodesDownPerGroup(rootDispatch.getMaxNodesDownPerFixedRow()); - builder.useMultilevelDispatch(useMultilevelDispatchSetup()); builder.useLocalNode(tuning.dispatch.useLocalNode); builder.searchableCopies(rootDispatch.getSearchableCopies()); if (searchCoverage != null) { diff --git a/config-model/src/main/java/com/yahoo/vespa/model/search/Tuning.java b/config-model/src/main/java/com/yahoo/vespa/model/search/Tuning.java index b0fe2877386..fac641bd714 100644 --- a/config-model/src/main/java/com/yahoo/vespa/model/search/Tuning.java +++ b/config-model/src/main/java/com/yahoo/vespa/model/search/Tuning.java @@ -2,7 +2,6 @@ package com.yahoo.vespa.model.search; import com.yahoo.config.model.producer.AbstractConfigProducer; -import com.yahoo.vespa.config.search.core.PartitionsConfig; import com.yahoo.vespa.config.search.core.ProtonConfig; import com.yahoo.vespa.model.content.TuningDispatch; @@ -14,47 +13,15 @@ import static com.yahoo.text.Lowercase.toLowerCase; * * @author geirst */ -public class Tuning extends AbstractConfigProducer implements PartitionsConfig.Producer, ProtonConfig.Producer { +public class Tuning extends AbstractConfigProducer implements ProtonConfig.Producer { - public static class Dispatch implements PartitionsConfig.Producer { + public static class Dispatch { public Integer maxHitsPerPartition = null; public TuningDispatch.DispatchPolicy policy = null; public boolean useLocalNode = false; public Double minGroupCoverage = null; public Double minActiveDocsCoverage = null; - - @Override - public void getConfig(PartitionsConfig.Builder builder) { - if (maxHitsPerPartition != null) { - for (PartitionsConfig.Dataset.Builder dataset : builder.dataset) { - dataset.maxhitspernode(maxHitsPerPartition); - } - } - if (minGroupCoverage != null) { - for (PartitionsConfig.Dataset.Builder dataset : builder.dataset) { - dataset.min_group_coverage(minGroupCoverage); - } - } - if (minActiveDocsCoverage != null) { - for (PartitionsConfig.Dataset.Builder dataset : builder.dataset) { - dataset.min_activedocs_coverage(minActiveDocsCoverage); - } - } - if (policy != null) { - for (PartitionsConfig.Dataset.Builder dataset : builder.dataset) { - switch (policy) { - case ADAPTIVE: - dataset.useroundrobinforfixedrow(false); - break; - case ROUNDROBIN: - default: - dataset.useroundrobinforfixedrow(true); - break; - } - } - } - } } public static class SearchNode implements ProtonConfig.Producer { @@ -431,13 +398,6 @@ public class Tuning extends AbstractConfigProducer implements PartitionsConfig.P super(parent, "tuning"); } - @Override - public void getConfig(PartitionsConfig.Builder builder) { - if (dispatch != null) { - dispatch.getConfig(builder); - } - } - @Override public void getConfig(ProtonConfig.Builder builder) { if (searchNode != null) searchNode.getConfig(builder); diff --git a/config-model/src/test/java/com/yahoo/config/model/provision/ModelProvisioningTest.java b/config-model/src/test/java/com/yahoo/config/model/provision/ModelProvisioningTest.java index 535048eafa3..dfd2fe00d46 100644 --- a/config-model/src/test/java/com/yahoo/config/model/provision/ModelProvisioningTest.java +++ b/config-model/src/test/java/com/yahoo/config/model/provision/ModelProvisioningTest.java @@ -7,13 +7,10 @@ import com.yahoo.config.model.api.container.ContainerServiceType; import com.yahoo.config.model.deploy.DeployState; import com.yahoo.config.model.deploy.TestProperties; import com.yahoo.config.provision.ClusterMembership; -import com.yahoo.config.provision.Flavor; import com.yahoo.config.provision.NodeResources; import com.yahoo.config.provision.Zone; -import com.yahoo.config.provisioning.FlavorsConfig; import com.yahoo.container.core.ApplicationMetadataConfig; import com.yahoo.search.config.QrStartConfig; -import com.yahoo.vespa.config.search.core.PartitionsConfig; import com.yahoo.vespa.config.search.core.ProtonConfig; import com.yahoo.vespa.model.HostResource; import com.yahoo.vespa.model.HostSystem; @@ -22,14 +19,12 @@ import com.yahoo.vespa.model.admin.Admin; import com.yahoo.vespa.model.admin.Logserver; import com.yahoo.vespa.model.admin.Slobrok; import com.yahoo.vespa.model.admin.clustercontroller.ClusterControllerContainerCluster; -import com.yahoo.vespa.model.container.ApplicationContainer; import com.yahoo.vespa.model.container.ApplicationContainerCluster; import com.yahoo.vespa.model.container.Container; import com.yahoo.vespa.model.container.ContainerCluster; import com.yahoo.vespa.model.content.ContentSearchCluster; import com.yahoo.vespa.model.content.StorageNode; import com.yahoo.vespa.model.content.cluster.ContentCluster; -import com.yahoo.vespa.model.search.Dispatch; import com.yahoo.vespa.model.search.SearchNode; import com.yahoo.vespa.model.test.VespaModelTester; import com.yahoo.vespa.model.test.utils.ApplicationPackageUtils; @@ -38,7 +33,6 @@ import org.junit.Ignore; import org.junit.Test; import java.io.StringReader; -import java.util.Collection; import java.util.List; import java.util.Map; import java.util.Optional; @@ -1019,10 +1013,6 @@ public class ModelProvisioningTest { assertThat(cluster.getRootGroup().getNodes().get(2).getConfigId(), is("bar/storage/2")); assertThat(cluster.getRootGroup().getNodes().get(3).getDistributionKey(), is(3)); assertThat(cluster.getRootGroup().getNodes().get(3).getConfigId(), is("bar/storage/3")); - PartitionsConfig.Builder partBuilder = new PartitionsConfig.Builder(); - cluster.getSearch().getIndexed().getTLDs().get(0).getConfig(partBuilder); - PartitionsConfig partCFg = partBuilder.build(); - assertEquals(4, partCFg.dataset(0).searchablecopies()); } @Test @@ -1605,97 +1595,6 @@ public class ModelProvisioningTest { return modelCreatorWithMockPkg.create(false, deployState); } - @Test - public void testThatTldConfigIdsAreDeterministic() { - String services = - "\n" + - "" + - " " + - " " + - " " + - " " + - " " + - " " + - " " + - " " + - " " + - " " + - " 2" + - " " + - " " + - " " + - " " + - " " + - " " + - " 2" + - " " + - " " + - " " + - " " + - " " + - ""; - - int numberOfHosts = 8; - - { - VespaModelTester tester = new VespaModelTester(); - tester.addHosts(numberOfHosts); - // Nodes used will be default0, default1, .. and so on. - VespaModel model = tester.createModel(services, true); - assertThat(model.getRoot().getHostSystem().getHosts().size(), is(numberOfHosts)); - - Map contentClusters = model.getContentClusters(); - assertEquals(2, contentClusters.size()); - - checkThatTldAndContainerRunningOnSameHostHaveSameId( - model.getContainerClusters().values(), - model.getContentClusters().values(), - 0); - } - - { - VespaModelTester tester = new VespaModelTester(); - tester.addHosts(numberOfHosts + 1); - // Start numbering nodes with index 1 and retire first node - // Nodes used will be default1, default2, .. and so on. Containers will start with index 1, not 0 as they are in the test above - VespaModel model = tester.createModel(services, true, 1, "default0"); - assertThat(model.getRoot().getHostSystem().getHosts().size(), is(numberOfHosts)); - - Map contentClusters = model.getContentClusters(); - assertEquals(2, contentClusters.size()); - - checkThatTldAndContainerRunningOnSameHostHaveSameId( - model.getContainerClusters().values(), - model.getContentClusters().values(), - 1); - } - } - - private void checkThatTldAndContainerRunningOnSameHostHaveSameId(Collection containerClusters, - Collection contentClusters, - int startIndexForContainerIds) { - for (ContentCluster contentCluster : contentClusters) { - String contentClusterName = contentCluster.getName(); - int i = 0; - for (ApplicationContainerCluster containerCluster : containerClusters) { - String containerClusterName = containerCluster.getName(); - for (int j = 0; j < 2; j++) { - Dispatch tld = contentCluster.getSearch().getIndexed().getTLDs().get(2 * i + j); - ApplicationContainer container = containerCluster.getContainers().get(j); - int containerConfigIdIndex = j + startIndexForContainerIds; - - assertEquals(container.getHostName(), tld.getHostname()); - assertEquals(contentClusterName + "/search/cluster." + contentClusterName + "/tlds/" + - containerClusterName + "." + containerConfigIdIndex + ".tld." + containerConfigIdIndex, - tld.getConfigId()); - assertEquals(containerClusterName + "/" + "container." + containerConfigIdIndex, - container.getConfigId()); - } - i++; - } - } - } - private int physicalMemoryPercentage(ContainerCluster cluster) { QrStartConfig.Builder b = new QrStartConfig.Builder(); cluster.getConfig(b); @@ -1725,11 +1624,6 @@ public class ModelProvisioningTest { assertEquals(40, getProtonConfig(cluster, 1).hwinfo().disk().writespeed(), 0.001); } - private static Flavor createFlavorFromDiskSetting(String name, boolean fastDisk) { - return new Flavor(new FlavorsConfig.Flavor(new FlavorsConfig.Flavor.Builder(). - name(name).fastDisk(fastDisk))); - } - private static ProtonConfig getProtonConfig(ContentSearchCluster cluster, int searchNodeIdx) { ProtonConfig.Builder builder = new ProtonConfig.Builder(); List searchNodes = cluster.getSearchNodes(); @@ -1787,11 +1681,6 @@ public class ModelProvisioningTest { private static long GB = 1024 * 1024 * 1024; - private static Flavor createFlavorFromMemoryAndDisk(String name, int memoryGb, int diskGb) { - return new Flavor(new FlavorsConfig.Flavor(new FlavorsConfig.Flavor.Builder(). - name(name).minMainMemoryAvailableGb(memoryGb).minDiskAvailableGb(diskGb))); - } - private static ProtonConfig getProtonConfig(VespaModel model, String configId) { ProtonConfig.Builder builder = new ProtonConfig.Builder(); model.getConfig(builder, configId); diff --git a/config-model/src/test/java/com/yahoo/vespa/model/builder/xml/dom/ContentBuilderTest.java b/config-model/src/test/java/com/yahoo/vespa/model/builder/xml/dom/ContentBuilderTest.java index 567e54ed4c4..a7ab9e02a79 100644 --- a/config-model/src/test/java/com/yahoo/vespa/model/builder/xml/dom/ContentBuilderTest.java +++ b/config-model/src/test/java/com/yahoo/vespa/model/builder/xml/dom/ContentBuilderTest.java @@ -12,7 +12,6 @@ import com.yahoo.text.StringUtilities; import com.yahoo.vespa.config.ConfigDefinitionKey; import com.yahoo.vespa.config.ConfigPayloadBuilder; import com.yahoo.vespa.config.GenericConfig; -import com.yahoo.vespa.config.search.core.PartitionsConfig; import com.yahoo.vespa.config.search.core.ProtonConfig; import com.yahoo.vespa.model.HostResource; import com.yahoo.vespa.model.Service; @@ -21,7 +20,6 @@ import com.yahoo.vespa.model.content.ContentSearchCluster; import com.yahoo.vespa.model.content.cluster.ContentCluster; import com.yahoo.vespa.model.content.engines.ProtonEngine; import com.yahoo.vespa.model.search.AbstractSearchCluster; -import com.yahoo.vespa.model.search.Dispatch; import com.yahoo.vespa.model.search.IndexedSearchCluster; import com.yahoo.vespa.model.search.SearchNode; import com.yahoo.vespa.model.search.StreamingSearchCluster; @@ -172,25 +170,11 @@ public class ContentBuilderTest extends DomBuilderTest { assertEquals("clu/storage/0", c.getRootGroup().getNodes().get(0).getConfigId()); // Due to reuse. assertEquals(1, c.getRoot().getHostSystem().getHosts().size()); HostResource h = c.getRoot().getHostSystem().getHost("mockhost"); - String [] expectedServices = {"logd", "configproxy","config-sentinel", "qrserver", "storagenode", "searchnode", "distributor", "topleveldispatch", "transactionlogserver"}; -// TODO assertServices(h, expectedServices); + String [] expectedServices = {"configserver", "logserver", "logd", "container-clustercontroller", "metricsproxy-container", "slobrok", "configproxy","config-sentinel", "qrserver", "storagenode", "searchnode", "distributor", "transactionlogserver"}; + assertServices(h, expectedServices); assertEquals("clu/storage/0", h.getService("storagenode").getConfigId()); assertEquals("clu/search/cluster.clu/0", h.getService("searchnode").getConfigId()); assertEquals("clu/distributor/0", h.getService("distributor").getConfigId()); - assertEquals("clu/search/cluster.clu/tlds/qrc.0.tld.0", h.getService("topleveldispatch").getConfigId()); - //assertEquals("tcp/node0:19104", h.getService("topleveldispatch").getConfig("partitions", "").innerArray("dataset").value("0").innerArray("engine").value("0").getString("name_and_port")); - PartitionsConfig partitionsConfig = new PartitionsConfig((PartitionsConfig.Builder) - m.getConfig(new PartitionsConfig.Builder(), "clu/search/cluster.clu/tlds/qrc.0.tld.0")); - assertTrue(partitionsConfig.dataset(0).engine(0).name_and_port().startsWith("tcp/node0:191")); - } - - @Test - public void testConfigIdLookup() { - VespaModel m = new VespaModelCreatorWithMockPkg(createAppWithMusic(getHosts(), getBasicServices())).create(); - - PartitionsConfig partitionsConfig = new PartitionsConfig((PartitionsConfig.Builder) - m.getConfig(new PartitionsConfig.Builder(), "clu/search/cluster.clu/tlds/qrc.0.tld.0")); - assertTrue(partitionsConfig.dataset(0).engine(0).name_and_port().startsWith("tcp/node0:191")); } @Test @@ -198,9 +182,6 @@ public class ContentBuilderTest extends DomBuilderTest { String services = getServices("" + ""); VespaModel m = new VespaModelCreatorWithMockPkg(createAppWithMusic(getHosts(), services)).create(); - PartitionsConfig partitionsConfig = new PartitionsConfig((PartitionsConfig.Builder) - m.getConfig(new PartitionsConfig.Builder(), "clu/search/cluster.clu/tlds/qrc.0.tld.0")); - assertTrue(partitionsConfig.dataset(0).engine(0).name_and_port().startsWith("tcp/node0:191")); IndexedSearchCluster sc = m.getContentClusters().get("clu").getSearch().getIndexed(); assertEquals(2, sc.getSearchNodeCount()); } @@ -710,45 +691,6 @@ public class ContentBuilderTest extends DomBuilderTest { } } - @Test - public void requireOneTldPerSearchContainer() { - ContentCluster content = createContent( - " \n" + - " 1\n" + - " " + - " " + - " " + - " \n" + - " \n" + - " \n" + - " \n" + - " " + - " " + - " " + - " " + - " " + - " " + - " " + - " " + - " " + - " " + - " " + - " " + - " " + - " " + - " " + - " " - - ); - List tlds = content.getSearch().getIndexed().getTLDs(); - - assertThat(tlds.get(0).getHostname(), is("node0")); - assertThat(tlds.get(1).getHostname(), is("node0")); - assertThat(tlds.get(2).getHostname(), is("node1")); - - assertThat(tlds.size(), is(3)); - } - @Test @Ignore public void ensureOverrideAppendedOnlyOnce() { diff --git a/config-model/src/test/java/com/yahoo/vespa/model/content/ContentClusterTest.java b/config-model/src/test/java/com/yahoo/vespa/model/content/ContentClusterTest.java index d98d1da9d2a..d6579ba88d4 100644 --- a/config-model/src/test/java/com/yahoo/vespa/model/content/ContentClusterTest.java +++ b/config-model/src/test/java/com/yahoo/vespa/model/content/ContentClusterTest.java @@ -18,7 +18,7 @@ import com.yahoo.vespa.config.content.StorDistributionConfig; import com.yahoo.vespa.config.content.StorFilestorConfig; import com.yahoo.vespa.config.content.core.StorDistributormanagerConfig; import com.yahoo.vespa.config.content.core.StorServerConfig; -import com.yahoo.vespa.config.search.core.PartitionsConfig; +import com.yahoo.vespa.config.search.DispatchConfig; import com.yahoo.vespa.config.search.core.ProtonConfig; import com.yahoo.vespa.model.VespaModel; import com.yahoo.vespa.model.container.ContainerCluster; @@ -271,25 +271,6 @@ public class ContentClusterTest extends ContentBaseTest { assertEquals(1, cluster.getContainers().size()); } - private void verifyRoundRobinPropertiesControl(boolean useAdaptiveDispatch) { - VespaModel model = createEnd2EndOneNode(new TestProperties().setUseAdaptiveDispatch(useAdaptiveDispatch)); - - ContentCluster cc = model.getContentClusters().get("storage"); - PartitionsConfig.Builder partBuilder = new PartitionsConfig.Builder(); - assertNotNull(cc.getSearch()); - assertNotNull(cc.getSearch().getIndexed()); - assertEquals(1, cc.getSearch().getIndexed().getTLDs().size()); - cc.getSearch().getIndexed().getTLDs().get(0).getConfig(partBuilder); - PartitionsConfig partitionsConfig = new PartitionsConfig(partBuilder); - assertFalse(useAdaptiveDispatch == partitionsConfig.dataset(0).useroundrobinforfixedrow()); - } - - @Test - public void default_dispatch_controlled_by_properties() { - verifyRoundRobinPropertiesControl(false); - verifyRoundRobinPropertiesControl(true); - } - @Test public void testSearchTuning() { String xml = @@ -950,4 +931,27 @@ public class ContentClusterTest extends ContentBaseTest { assertEquals(distributionBits, storDistributormanagerConfig.minsplitcount()); } + private void verifyRoundRobinPropertiesControl(boolean useAdaptiveDispatch) { + VespaModel model = createEnd2EndOneNode(new TestProperties().setUseAdaptiveDispatch(useAdaptiveDispatch)); + + ContentCluster cc = model.getContentClusters().get("storage"); + DispatchConfig.Builder builder = new DispatchConfig.Builder(); + cc.getSearch().getConfig(builder); + + DispatchConfig cfg = new DispatchConfig(builder); + if (useAdaptiveDispatch) { + assertEquals(DispatchConfig.DistributionPolicy.ADAPTIVE, cfg.distributionPolicy()); + } else { + assertEquals(DispatchConfig.DistributionPolicy.ROUNDROBIN, cfg.distributionPolicy()); + } + + } + + @Test + public void default_dispatch_controlled_by_properties() { + verifyRoundRobinPropertiesControl(false); + verifyRoundRobinPropertiesControl(true); + } + + } diff --git a/config-model/src/test/java/com/yahoo/vespa/model/content/IndexedHierarchicDistributionTest.java b/config-model/src/test/java/com/yahoo/vespa/model/content/IndexedHierarchicDistributionTest.java index afedbaea779..d290d4ec953 100644 --- a/config-model/src/test/java/com/yahoo/vespa/model/content/IndexedHierarchicDistributionTest.java +++ b/config-model/src/test/java/com/yahoo/vespa/model/content/IndexedHierarchicDistributionTest.java @@ -2,7 +2,6 @@ package com.yahoo.vespa.model.content; import com.yahoo.vespa.config.content.StorDistributionConfig; -import com.yahoo.vespa.config.search.core.PartitionsConfig; import com.yahoo.config.model.test.MockRoot; import com.yahoo.vespa.model.Host; import com.yahoo.vespa.model.HostResource; @@ -21,8 +20,6 @@ import static com.yahoo.config.model.test.TestUtil.joinLines; import static org.hamcrest.Matchers.containsString; import static com.yahoo.vespa.model.content.utils.ContentClusterUtils.createCluster; import static com.yahoo.vespa.model.content.utils.ContentClusterUtils.createClusterXml; -import static com.yahoo.vespa.model.search.utils.DispatchUtils.assertEngine; -import static com.yahoo.vespa.model.search.utils.DispatchUtils.getDataset; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertFalse; import static org.junit.Assert.assertThat; @@ -35,19 +32,13 @@ import static org.junit.Assert.assertTrue; */ public class IndexedHierarchicDistributionTest { - private ContentCluster addDispatcher(ContentCluster c) { - MockRoot root = new MockRoot(""); - c.getSearch().getIndexed().addTld(root.deployLogger(), new SimpleConfigProducer(root, ""), new HostResource(new Host(root, "mockhost"))); - return c; - } - private ContentCluster getOneGroupCluster() throws Exception { String groupXml = joinLines(" ", " ", " ", " ", " ", ""); - return addDispatcher(createCluster(createClusterXml(groupXml, 2, 2))); + return createCluster(createClusterXml(groupXml, 2, 2)); } private String getTwoGroupsXml(String partitions) { @@ -67,11 +58,11 @@ public class IndexedHierarchicDistributionTest { } private ContentCluster getTwoGroupsCluster() throws Exception { - return addDispatcher(createCluster(createClusterXml(getTwoGroupsXml("3|*"), 6, 6))); + return createCluster(createClusterXml(getTwoGroupsXml("3|*"), 6, 6)); } private ContentCluster getTwoGroupsCluster(int redundancy, int searchableCopies, String partitions) throws Exception { - return addDispatcher(createCluster(createClusterXml(getTwoGroupsXml(partitions), redundancy, searchableCopies))); + return createCluster(createClusterXml(getTwoGroupsXml(partitions), redundancy, searchableCopies)); } private void assertSearchNode(int expRowId, int expPartitionId, int expDistibutionKey, SearchNode node) { @@ -97,20 +88,6 @@ public class IndexedHierarchicDistributionTest { assertSearchNode(0, 2, 2, searchNodes.get(2)); } - @Test - public void requireThatDispatcherIsCorrectWithOneGroup() throws Exception { - ContentCluster c = getOneGroupCluster(); - PartitionsConfig.Dataset dataset = getDataset(c.getSearch().getIndexed().getTLDs().get(0)); - - assertEquals(3, dataset.numparts()); - assertEquals(PartitionsConfig.Dataset.Querydistribution.AUTOMATIC, dataset.querydistribution()); - List engines = dataset.engine(); - assertEquals(3, engines.size()); - assertEngine(0, 0, engines.get(0)); - assertEngine(0, 1, engines.get(1)); - assertEngine(0, 2, engines.get(2)); - } - @Test public void requireThatActivePerLeafGroupIsDefaultWithOneGroup() throws Exception { ContentCluster c = getOneGroupCluster(); @@ -131,24 +108,6 @@ public class IndexedHierarchicDistributionTest { assertSearchNode(1, 2, 5, searchNodes.get(5)); } - @Test - public void requireThatDispatcherIsCorrectWithTwoGroups() throws Exception { - ContentCluster c = getTwoGroupsCluster(); - PartitionsConfig.Dataset dataset = getDataset(c.getSearch().getIndexed().getTLDs().get(0)); - - assertEquals(3, dataset.numparts()); - assertEquals(2, dataset.maxnodesdownperfixedrow()); - assertEquals(PartitionsConfig.Dataset.Querydistribution.FIXEDROW, dataset.querydistribution()); - List engines = dataset.engine(); - assertEquals(6, engines.size()); - assertEngine(0, 0, engines.get(0)); - assertEngine(1, 0, engines.get(1)); - assertEngine(0, 1, engines.get(2)); - assertEngine(1, 1, engines.get(3)); - assertEngine(0, 2, engines.get(4)); - assertEngine(1, 2, engines.get(5)); - } - @Test public void requireThatActivePerLeafGroupIsSetWithTwoGroups() throws Exception { ContentCluster c = getTwoGroupsCluster(); diff --git a/config-model/src/test/java/com/yahoo/vespa/model/content/cluster/ClusterTest.java b/config-model/src/test/java/com/yahoo/vespa/model/content/cluster/ClusterTest.java index 4fadea74feb..4291c68eff8 100644 --- a/config-model/src/test/java/com/yahoo/vespa/model/content/cluster/ClusterTest.java +++ b/config-model/src/test/java/com/yahoo/vespa/model/content/cluster/ClusterTest.java @@ -4,10 +4,9 @@ package com.yahoo.vespa.model.content.cluster; import com.yahoo.config.application.api.ApplicationPackage; import com.yahoo.config.model.test.MockApplicationPackage; import com.yahoo.config.model.test.TestDriver; -import com.yahoo.vespa.config.search.core.PartitionsConfig; +import com.yahoo.vespa.config.search.DispatchConfig; import com.yahoo.vespa.config.search.core.ProtonConfig; import com.yahoo.vespa.model.content.Content; -import com.yahoo.vespa.model.search.Dispatch; import com.yahoo.vespa.model.search.IndexedSearchCluster; import com.yahoo.vespa.model.test.utils.ApplicationPackageUtils; import org.junit.Test; @@ -16,6 +15,7 @@ import java.util.List; import static com.yahoo.config.model.test.TestUtil.joinLines; import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertFalse; import static org.junit.Assert.assertNotNull; import static org.junit.Assert.assertTrue; @@ -24,6 +24,7 @@ import static org.junit.Assert.assertTrue; */ public class ClusterTest { + static final double DELTA = 1E-12; @Test public void requireThatContentSearchIsApplied() { ContentCluster cluster = newContentCluster(joinLines("", @@ -32,10 +33,19 @@ public class ClusterTest { "")); IndexedSearchCluster searchCluster = cluster.getSearch().getIndexed(); assertNotNull(searchCluster); - assertEquals(1.1, searchCluster.getQueryTimeout(), 1E-6); - assertEquals(2.3, searchCluster.getVisibilityDelay(), 1E-6); + assertEquals(1.1, searchCluster.getQueryTimeout(), DELTA); + assertEquals(2.3, searchCluster.getVisibilityDelay(), DELTA); ProtonConfig proton = getProtonConfig(cluster); - assertEquals(searchCluster.getVisibilityDelay(), proton.documentdb(0).visibilitydelay(), 1E-6); + assertEquals(searchCluster.getVisibilityDelay(), proton.documentdb(0).visibilitydelay(), DELTA); + } + + @Test + public void requireThatVisibilityDelayIsZeroForGlobalDocumentType() { + ContentCluster cluster = newContentCluster(joinLines("", + " 2.3", + ""), true); + ProtonConfig proton = getProtonConfig(cluster); + assertEquals(0.0, proton.documentdb(0).visibilitydelay(), DELTA); } @Test @@ -47,56 +57,93 @@ public class ClusterTest { " 0.58", " ", "")); - assertEquals(1, cluster.getSearch().getIndexed().getTLDs().size()); - for (Dispatch tld : cluster.getSearch().getIndexed().getTLDs()) { - PartitionsConfig.Builder builder = new PartitionsConfig.Builder(); - tld.getConfig(builder); - PartitionsConfig config = new PartitionsConfig(builder); - assertEquals(11.0, config.dataset(0).minimal_searchcoverage(), 1E-6); - assertEquals(0.23, config.dataset(0).higher_coverage_minsearchwait(), 1E-6); - assertEquals(0.58, config.dataset(0).higher_coverage_maxsearchwait(), 1E-6); - assertEquals(2, config.dataset(0).searchablecopies()); - assertTrue(config.dataset(0).useroundrobinforfixedrow()); - } + DispatchConfig.Builder builder = new DispatchConfig.Builder(); + cluster.getSearch().getConfig(builder); + DispatchConfig config = new DispatchConfig(builder); + assertEquals(11.0, config.minSearchCoverage(), DELTA); + assertEquals(0.23, config.minWaitAfterCoverageFactor(), DELTA); + assertEquals(0.58, config.maxWaitAfterCoverageFactor(), DELTA); + assertEquals(2, config.searchableCopies()); + assertEquals(DispatchConfig.DistributionPolicy.ROUNDROBIN, config.distributionPolicy()); } @Test - public void requireThatDispatchTuningIsApplied() { + public void requireThatDispatchTuningIsApplied() { ContentCluster cluster = newContentCluster(joinLines("", ""), - joinLines("", - "")); - assertEquals(1, cluster.getSearch().getIndexed().getTLDs().size()); - for (Dispatch tld : cluster.getSearch().getIndexed().getTLDs()) { - PartitionsConfig.Builder builder = new PartitionsConfig.Builder(); - tld.getConfig(builder); - PartitionsConfig config = new PartitionsConfig(builder); - assertEquals(2, config.dataset(0).searchablecopies()); - assertTrue(config.dataset(0).useroundrobinforfixedrow()); - } + "", + joinLines( + "77", + "adaptive", + "13", + "93", + "true"), + false); + DispatchConfig.Builder builder = new DispatchConfig.Builder(); + cluster.getSearch().getConfig(builder); + DispatchConfig config = new DispatchConfig(builder); + assertEquals(2, config.searchableCopies()); + assertEquals(93.0, config.minActivedocsPercentage(), DELTA); + assertEquals(13.0, config.minGroupCoverage(), DELTA); + assertTrue(config.useLocalNode()); + assertEquals(DispatchConfig.DistributionPolicy.ADAPTIVE, config.distributionPolicy()); + assertEquals(77, config.maxHitsPerNode()); } @Test - public void requireThatVisibilityDelayIsZeroForGlobalDocumentType() { - ContentCluster cluster = newContentCluster(joinLines("", - " 2.3", - ""), true); - ProtonConfig proton = getProtonConfig(cluster); - assertEquals(0.0, proton.documentdb(0).visibilitydelay(), 1E-6); - } + public void requireThatDefaultDispatchConfigIsCorrect() { + ContentCluster cluster = newContentCluster(joinLines("", ""), + joinLines("", "")); + DispatchConfig.Builder builder = new DispatchConfig.Builder(); + cluster.getSearch().getConfig(builder); + DispatchConfig config = new DispatchConfig(builder); + assertEquals(2, config.searchableCopies()); + assertEquals(DispatchConfig.DistributionPolicy.ROUNDROBIN, config.distributionPolicy()); + assertEquals(0, config.maxNodesDownPerGroup()); + assertEquals(1.0, config.maxWaitAfterCoverageFactor(), DELTA); + assertEquals(0, config.minWaitAfterCoverageFactor(), DELTA); + assertEquals(8, config.numJrtConnectionsPerNode()); + assertEquals(8, config.numJrtTransportThreads()); + assertEquals(100.0, config.minSearchCoverage(), DELTA); + assertEquals(97.0, config.minActivedocsPercentage(), DELTA); + assertEquals(100.0, config.minGroupCoverage(), DELTA); + assertFalse(config.useLocalNode()); + assertEquals(3, config.node().size()); + assertEquals(0, config.node(0).key()); + assertEquals(1, config.node(1).key()); + assertEquals(2, config.node(2).key()); - private static ContentCluster newContentCluster(String contentSearchXml) { - return newContentCluster(contentSearchXml, "", false); + assertEquals(19106, config.node(0).port()); + assertEquals(19118, config.node(1).port()); + assertEquals(19130, config.node(2).port()); + + assertEquals(19107, config.node(0).fs4port()); + assertEquals(19119, config.node(1).fs4port()); + assertEquals(19131, config.node(2).fs4port()); + + assertEquals(0, config.node(0).group()); + assertEquals(0, config.node(1).group()); + assertEquals(0, config.node(2).group()); + + assertEquals("localhost", config.node(0).host()); + assertEquals("localhost", config.node(1).host()); + assertEquals("localhost", config.node(2).host()); } private static ContentCluster newContentCluster(String contentSearchXml, String searchNodeTuningXml) { - return newContentCluster(contentSearchXml, searchNodeTuningXml, false); + return newContentCluster(contentSearchXml, searchNodeTuningXml, "", false); + } + + private static ContentCluster newContentCluster(String contentSearchXml) { + return newContentCluster(contentSearchXml, false); } private static ContentCluster newContentCluster(String contentSearchXml, boolean globalDocType) { - return newContentCluster(contentSearchXml, "", globalDocType); + return newContentCluster(contentSearchXml, "", "", globalDocType); } - private static ContentCluster newContentCluster(String contentSearchXml, String searchNodeTuningXml, boolean globalDocType) { + private static ContentCluster newContentCluster(String contentSearchXml, String searchNodeTuningXml, + String dispatchTuning, boolean globalDocType) + { ApplicationPackage app = new MockApplicationPackage.Builder() .withHosts(joinLines( "", @@ -128,6 +175,11 @@ public class ClusterTest { " ", " ", contentSearchXml, + " ", + " ", + dispatchTuning, + " ", + " ", " ", "")) .withSearchDefinitions(ApplicationPackageUtils.generateSearchDefinition("my_document")) diff --git a/config-model/src/test/java/com/yahoo/vespa/model/search/MultilevelDispatchTest.java b/config-model/src/test/java/com/yahoo/vespa/model/search/MultilevelDispatchTest.java deleted file mode 100644 index c87774cf692..00000000000 --- a/config-model/src/test/java/com/yahoo/vespa/model/search/MultilevelDispatchTest.java +++ /dev/null @@ -1,382 +0,0 @@ -// Copyright 2017 Yahoo Holdings. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root. -package com.yahoo.vespa.model.search; - -import com.yahoo.config.model.producer.AbstractConfigProducer; -import com.yahoo.config.model.test.MockApplicationPackage; -import com.yahoo.config.model.test.MockRoot; -import com.yahoo.config.model.test.TestDriver; -import com.yahoo.config.model.test.TestRoot; -import com.yahoo.vespa.config.search.core.PartitionsConfig; -import com.yahoo.vespa.model.Host; -import com.yahoo.vespa.model.HostResource; -import com.yahoo.vespa.model.SimpleConfigProducer; -import com.yahoo.vespa.model.content.DispatchSpec; -import com.yahoo.vespa.model.content.cluster.ContentCluster; -import com.yahoo.vespa.model.content.utils.ContentClusterUtils; -import com.yahoo.vespa.model.search.utils.DispatchUtils; -import org.junit.Test; - -import java.util.ArrayList; -import java.util.List; -import java.util.Optional; - -import static com.yahoo.vespa.model.content.utils.ContentClusterUtils.createClusterXml; -import static com.yahoo.vespa.model.search.utils.DispatchUtils.getDataset; -import static com.yahoo.vespa.model.search.utils.DispatchUtils.getFdispatchrcConfig; -import static org.hamcrest.core.Is.is; -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertFalse; -import static org.junit.Assert.assertThat; -import static org.hamcrest.Matchers.containsString; - -/** - * Unit tests for multi-level dispatchers in an indexed content cluster. - * - * @author geirst - */ -public class MultilevelDispatchTest { - - private static class EngineAsserter { - private List engines; - private int engineIdx = 0; - public EngineAsserter(int numParts, int numEngines, Dispatch dispatch) { - PartitionsConfig.Dataset dataset = getDataset(dispatch); - assertEquals(numParts, dataset.numparts()); - assertEquals(PartitionsConfig.Dataset.Querydistribution.AUTOMATIC, dataset.querydistribution()); - engines = dataset.engine(); - assertEquals(numEngines, engines.size()); - } - EngineAsserter assertEngine(int rowId, int partitionId, String connectSpec) { - DispatchUtils.assertEngine(rowId, partitionId, connectSpec, engines.get(engineIdx++)); - return this; - } - } - - private String getGroupXml() { - return " \n" + - " \n" + - " \n" + - " \n" + - " \n" + - " \n" + - " \n" + - " \n"; - } - - private String getSimpleDispatchXml() { - return " \n" + - " 2\n" + - " \n"; - } - - private String getDispatchXml() { - return " \n" + - " \n" + - " \n" + - " \n" + - " \n" + - " \n" + - " \n" + - " \n" + - " \n" + - " \n" + - " \n" + - " \n"; - } - - private ContentCluster createCluster(String dispatchXml) throws Exception { - String[] hosts = {"mh0", "mh1", "mh2", "mh3", "mh4", "mh5"}; - MockRoot root = ContentClusterUtils.createMockRoot(hosts); - ContentCluster cluster = ContentClusterUtils.createCluster(createClusterXml(getGroupXml(), Optional.of(dispatchXml), 1, 1), root); - - AbstractConfigProducer dispatchParent = new SimpleConfigProducer<>(root, "tlds"); - HostResource hostResource = new HostResource(new Host(root, "mockhost")); - IndexedSearchCluster index = cluster.getSearch().getIndexed(); - index.addTld(root.deployLogger(), dispatchParent, hostResource); - index.setupDispatchGroups(root.deployLogger()); - - root.freezeModelTopology(); - cluster.validate(); - return cluster; - } - - private List getDispatchers(Dispatch tld) { - DispatchGroup group = tld.getDispatchGroup(); - List dispatchers = new ArrayList<>(); - for (SearchInterface dispatch : group.getSearchersIterable()) { - dispatchers.add((Dispatch)dispatch); - } - return dispatchers; - } - - private void assertDispatchAndSearchNodes(int partId, Dispatch[] dispatchers, String[] connectSpecs, SearchNode[] searchNodes) { - assertEquals(dispatchers.length, connectSpecs.length); - assertEquals(connectSpecs.length, searchNodes.length); - int searchNodeIdx = 0; - for (int rowId = 0; rowId < dispatchers.length; ++rowId) { - assertDispatchAndSearchNodes(rowId, partId, searchNodes[searchNodeIdx++].getDistributionKey(), - dispatchers[rowId], connectSpecs, searchNodes); - } - } - - private void assertDispatchAndSearchNodes(int expRowId, int expPartId, int expDistributionKey, Dispatch dispatch, String[] connectSpecs, SearchNode[] searchNodes) { - assertEquals(expRowId, dispatch.getNodeSpec().groupIndex()); - assertEquals(expPartId, dispatch.getNodeSpec().partitionId()); - assertEquals("mycluster/search/cluster.mycluster/dispatchers/dispatch." + expDistributionKey, dispatch.getConfigId()); - assertEquals(expPartId, getFdispatchrcConfig(dispatch).partition()); - assertEquals(1, getFdispatchrcConfig(dispatch).dispatchlevel()); - - int numEngines = connectSpecs.length; - EngineAsserter ea = new EngineAsserter(numEngines, numEngines, dispatch); - for (int i = 0; i < numEngines; ++i) { - ea.assertEngine(0, i, connectSpecs[i]); - assertEquals(i, searchNodes[i].getNodeSpec().partitionId()); - } - } - - @Test - public void requireThatDispatchGroupsCanBeAutomaticallySetup() throws Exception { - ContentCluster cr = createCluster(getSimpleDispatchXml()); - IndexedSearchCluster ix = cr.getSearch().getIndexed(); - Dispatch tld = cr.getSearch().getIndexed().getTLDs().get(0); - - assertEquals("tlds/tld.0", tld.getConfigId()); - assertEquals(0, getFdispatchrcConfig(tld).dispatchlevel()); - new EngineAsserter(2, 6, tld). - assertEngine(0, 0, "tcp/mh0:19113"). - assertEngine(1, 0, "tcp/mh1:19113"). - assertEngine(2, 0, "tcp/mh2:19113"). - assertEngine(0, 1, "tcp/mh3:19113"). - assertEngine(1, 1, "tcp/mh4:19113"). - assertEngine(2, 1, "tcp/mh5:19113"); - - List ds = getDispatchers(tld); - assertEquals(6, ds.size()); - { // dispatch group 1 - Dispatch[] dispatchers = {ds.get(0), ds.get(1), ds.get(2)}; - String[] specs = {"tcp/mh0:19104", "tcp/mh1:19104", "tcp/mh2:19104"}; - SearchNode[] searchNodes = {ix.getSearchNode(0), ix.getSearchNode(1), ix.getSearchNode(2)}; - assertDispatchAndSearchNodes(0, dispatchers, specs, searchNodes); - } - { // dispatch group 2 - Dispatch[] dispatchers = {ds.get(3), ds.get(4), ds.get(5)}; - String[] specs = {"tcp/mh3:19104", "tcp/mh4:19104", "tcp/mh5:19104"}; - SearchNode[] searchNodes = {ix.getSearchNode(3), ix.getSearchNode(4), ix.getSearchNode(5)}; - assertDispatchAndSearchNodes(1, dispatchers, specs, searchNodes); - } - } - - @Test - public void requireThatMaxHitsIsScaled() throws Exception { - ContentCluster cr = createCluster(getSimpleDispatchXml() + getMaxhitsTuning()); - Dispatch tld = cr.getSearch().getIndexed().getTLDs().get(0); - PartitionsConfig.Builder builder = new PartitionsConfig.Builder(); - tld.getConfig(builder); - PartitionsConfig config = new PartitionsConfig(builder); - assertThat(config.dataset().size(), is(1)); - assertThat(config.dataset(0).maxhitspernode(), is(300)); - for (Dispatch dispatch : getDispatchers(tld)) { - PartitionsConfig.Builder b = new PartitionsConfig.Builder(); - dispatch.getConfig(b); - PartitionsConfig c= new PartitionsConfig(b); - assertThat(c.dataset().size(), is(1)); - assertThat(c.dataset(0).maxhitspernode(), is(100)); - } - } - - private String getMaxhitsTuning() { - return "" + - " " + - " 100" + - " " + - ""; - } - - - @Test - public void requireThatSearchCoverageIsSetInMultilevelSetup() throws Exception { - ContentCluster cr = createCluster(getSimpleDispatchXml() + getCoverage()); - Dispatch tld = cr.getSearch().getIndexed().getTLDs().get(0); - PartitionsConfig.Builder builder = new PartitionsConfig.Builder(); - tld.getConfig(builder); - PartitionsConfig config = new PartitionsConfig(builder); - assertThat(config.dataset().size(), is(1)); - assertEquals(95.0, config.dataset(0).minimal_searchcoverage(), 0.1); - for (Dispatch dispatch : getDispatchers(tld)) { - PartitionsConfig.Builder b = new PartitionsConfig.Builder(); - dispatch.getConfig(b); - PartitionsConfig c= new PartitionsConfig(b); - assertThat(c.dataset().size(), is(1)); - assertEquals(95.0, c.dataset(0).minimal_searchcoverage(), 0.1); - } - } - - @Test - public void requireThatSearchCoverageIsSetInSingleLevelSetup() { - TestRoot root = new TestDriver(true).buildModel(new MockApplicationPackage.Builder() - .withServices("" + - "" + - " 1" + - " " + - " " + - " " + - " " + - " 0.95" + - "" + - "" + - " " + - " " + - "" + - "") - .withSearchDefinition(MockApplicationPackage.MUSIC_SEARCHDEFINITION) - .build()); - PartitionsConfig config = root.getConfig(PartitionsConfig.class, "stateful/search/cluster.stateful/tlds/foo.0.tld.0"); - assertThat(config.dataset().size(), is(1)); - assertEquals(95.0, config.dataset(0).minimal_searchcoverage(), 0.1); - } - - private String getCoverage() { - return "" + - " " + - " 0.95" + - " " + - ""; - } - - @Test - public void requireThatDispatchGroupsCanBeExplicitlySpecified() throws Exception { - ContentCluster cr = createCluster(getDispatchXml()); - IndexedSearchCluster ix = cr.getSearch().getIndexed(); - Dispatch tld = cr.getSearch().getIndexed().getTLDs().get(0); - - assertEquals("tlds/tld.0", tld.getConfigId()); - assertEquals(0, getFdispatchrcConfig(tld).dispatchlevel()); - new EngineAsserter(2, 6, tld). - assertEngine(0, 0, "tcp/mh0:19113"). - assertEngine(1, 0, "tcp/mh2:19113"). - assertEngine(2, 0, "tcp/mh4:19113"). - assertEngine(0, 1, "tcp/mh1:19113"). - assertEngine(1, 1, "tcp/mh3:19113"). - assertEngine(2, 1, "tcp/mh5:19113"); - - List ds = getDispatchers(tld); - assertEquals(6, ds.size()); - { // dispatch group 1 - Dispatch[] dispatchers = {ds.get(0), ds.get(1), ds.get(2)}; - String[] specs = {"tcp/mh0:19104", "tcp/mh2:19104", "tcp/mh4:19104"}; - SearchNode[] searchNodes = {ix.getSearchNode(0), ix.getSearchNode(2), ix.getSearchNode(4)}; - assertDispatchAndSearchNodes(0, dispatchers, specs, searchNodes); - } - { // dispatch group 2 - Dispatch[] dispatchers = {ds.get(3), ds.get(4), ds.get(5)}; - String[] specs = {"tcp/mh1:19104", "tcp/mh3:19104", "tcp/mh5:19104"}; - SearchNode[] searchNodes = {ix.getSearchNode(1), ix.getSearchNode(3), ix.getSearchNode(5)}; - assertDispatchAndSearchNodes(1, dispatchers, specs, searchNodes); - } - } - - @Test - public void requireThatUnevenDispatchGroupsCanBeCreated() { - List searchNodes = createSearchNodes(5); - List groups = DispatchGroupBuilder.createDispatchGroups(searchNodes, 3); - assertEquals(3, groups.size()); - assertGroup(new int[]{0, 1}, groups.get(0)); - assertGroup(new int[]{2, 3}, groups.get(1)); - assertGroup(new int[]{4}, groups.get(2)); - } - - private List createSearchNodes(int numNodes) { - List searchNodes = new ArrayList<>(); - MockRoot root = new MockRoot(""); - for (int i = 0; i < numNodes; ++i) { - searchNodes.add(SearchNode.create(root, "mynode" + i, i, new NodeSpec(0, i), "mycluster", null, false, - Optional.empty(), Optional.empty(), root.getDeployState().isHosted())); - } - return searchNodes; - } - - private void assertGroup(int[] nodes, DispatchSpec.Group group) { - assertEquals(nodes.length, group.getNodes().size()); - for (int i = 0; i < nodes.length; ++i) { - assertEquals(nodes[i], group.getNodes().get(i).getDistributionKey()); - } - } - - private ContentCluster createIllegalSetupWithMultipleNodeReferences() throws Exception { - String dispatchXml = " \n" + - " \n" + - " \n" + - " \n" + - " \n" + - " \n" + - " \n" + - " \n" + - " \n" + - " \n" + - " \n" + - " \n"; - return createCluster(dispatchXml); - } - - private ContentCluster createIllegalSetupWithMissingNodeReferences() throws Exception { - String dispatchXml = " \n" + - " \n" + - " \n" + - " \n" + - " \n" + - " \n" + - " \n" + - " \n" + - " \n" + - " \n"; - return createCluster(dispatchXml); - } - - private ContentCluster createIllegalSetupWithIllegalNodeReference() throws Exception { - String dispatchXml = " \n" + - " \n" + - " \n" + - " \n" + - " \n" + - " \n" + - " \n" + - " \n" + - " \n" + - " \n" + - " \n" + - " \n" + - " \n"; - return createCluster(dispatchXml); - } - - @Test - public void requireThatWeReferenceNodesOnlyOnceWhenSettingUpDispatchGroups() { - try { - createIllegalSetupWithMultipleNodeReferences(); - assertFalse("Did not get expected Exception", true); - } catch (Exception e) { - assertThat(e.getMessage(), containsString("node with distribution key '12' is referenced multiple times")); - } - } - - @Test - public void requireThatWeReferenceAllNodesWhenSettingUpDispatchGroups() { - try { - createIllegalSetupWithMissingNodeReferences(); - assertFalse("Did not get expected Exception", true); - } catch (Exception e) { - assertThat(e.getMessage(), containsString("2 node(s) with distribution keys [12, 15] are not referenced")); - } - } - - @Test - public void requireThatWeReferenceValidNodesWhenSettingUpDispatchGroups() { - try { - createIllegalSetupWithIllegalNodeReference(); - assertFalse("Did not get expected Exception", true); - } catch (Exception e) { - assertThat(e.getMessage(), containsString("node with distribution key '19' does not exists")); - } - } - -} diff --git a/config-model/src/test/java/com/yahoo/vespa/model/search/TldTest.java b/config-model/src/test/java/com/yahoo/vespa/model/search/TldTest.java deleted file mode 100644 index 227ad9c6be1..00000000000 --- a/config-model/src/test/java/com/yahoo/vespa/model/search/TldTest.java +++ /dev/null @@ -1,146 +0,0 @@ -// Copyright 2017 Yahoo Holdings. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root. -package com.yahoo.vespa.model.search; - -import com.yahoo.config.application.api.ApplicationPackage; -import com.yahoo.config.model.test.MockApplicationPackage; -import com.yahoo.config.model.test.TestDriver; -import com.yahoo.vespa.config.search.core.PartitionsConfig; -import org.junit.Test; - -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertTrue; - -/** - * @author Simon Thoresen Hult - */ -public class TldTest { - - @Test - public void requireThatServicesIsParsed() { - ApplicationPackage app = new MockApplicationPackage.Builder() - .withHosts("mockhostmockhost2") - .withServices( - "" + - " " + - " " + - " " + - " " + - " " + - " " + - " " + - " " + - " " + - " " + - " 1" + - " " + - " " + - " " + - " " + - " " + - " " + - " " + - " " + - " " + - " 69" + - " true" + - " " + - " " + - " " + - "") - .withSearchDefinition(MockApplicationPackage.MUSIC_SEARCHDEFINITION) - .build(); - - PartitionsConfig.Builder builder = new PartitionsConfig.Builder(); - new TestDriver(true).buildModel(app).getConfig(builder, "foo/search/cluster.foo/tlds/default.0.tld.0"); - PartitionsConfig config = new PartitionsConfig(builder); - - assertEquals(1, config.dataset().size()); - assertEquals(69, config.dataset(0).maxhitspernode()); - assertEquals(1, config.dataset(0).engine().size()); - } - - @Test - public void requireThatUseLocalPolicyIsOk() { - ApplicationPackage app = new MockApplicationPackage.Builder() - .withHosts( - "" + - " search1" + - " search2" + - " gateway" + - "") - .withServices( - "" + - " " + - " " + - " " + - " " + - " " + - " " + - " " + - " " + - " " + - " " + - " " + - " " + - " " + - " " + - " " + - " " + - " " + - " 2" + - " " + - " " + - " " + - " " + - " " + - " " + - " " + - " " + - " " + - " " + - " " + - " " + - " " + - " " + - " true" + - " " + - " " + - " " + - "") - .withSearchDefinition(MockApplicationPackage.MUSIC_SEARCHDEFINITION) - .build(); - - PartitionsConfig.Builder builder = new PartitionsConfig.Builder(); - new TestDriver(true).buildModel(app).getConfig(builder, "foo/search/cluster.foo/tlds/gw.0.tld.0"); - PartitionsConfig config = new PartitionsConfig(builder); - - // No tld if no search - assertEquals(0, config.dataset().size()); - - // First container with a local search node - builder = new PartitionsConfig.Builder(); - new TestDriver(true).buildModel(app).getConfig(builder, "foo/search/cluster.foo/tlds/default.0.tld.0"); - config = new PartitionsConfig(builder); - - assertEquals(1, config.dataset().size()); - assertEquals(1, config.dataset(0).engine().size()); - assertEquals(0,config.dataset(0).engine(0).rowid()); - assertEquals(0,config.dataset(0).engine(0).partid()); - assertTrue("Configured with local search node as engine", - config.dataset(0).engine(0).name_and_port().contains("search.node1")); - - // Second container with a local search node - builder = new PartitionsConfig.Builder(); - new TestDriver(true).buildModel(app).getConfig(builder, "foo/search/cluster.foo/tlds/default.1.tld.1"); - config = new PartitionsConfig(builder); - - assertEquals(1, config.dataset().size()); - assertEquals(1, config.dataset(0).engine().size()); - - assertEquals("rowid equals 0",0, config.dataset(0).engine(0).rowid()); // Load Balance row 0 - assertEquals("partid equals 0",0, config.dataset(0).engine(0).partid()); - assertTrue("Configured with correct search node", - config.dataset(0).engine(0).name_and_port().contains("search.node2")); - } - -} diff --git a/config-model/src/test/java/com/yahoo/vespa/model/search/utils/DispatchUtils.java b/config-model/src/test/java/com/yahoo/vespa/model/search/utils/DispatchUtils.java deleted file mode 100644 index 0185770037f..00000000000 --- a/config-model/src/test/java/com/yahoo/vespa/model/search/utils/DispatchUtils.java +++ /dev/null @@ -1,35 +0,0 @@ -// Copyright 2017 Yahoo Holdings. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root. -package com.yahoo.vespa.model.search.utils; - -import com.yahoo.vespa.config.search.core.FdispatchrcConfig; -import com.yahoo.vespa.config.search.core.PartitionsConfig; -import com.yahoo.vespa.model.search.Dispatch; - -import static org.junit.Assert.assertEquals; - -public class DispatchUtils { - - public static PartitionsConfig.Dataset getDataset(Dispatch dispatch) { - PartitionsConfig.Builder builder = new PartitionsConfig.Builder(); - dispatch.getConfig(builder); - PartitionsConfig cfg = new PartitionsConfig(builder); - assertEquals(1, cfg.dataset().size()); - return cfg.dataset(0); - } - - public static FdispatchrcConfig getFdispatchrcConfig(Dispatch dispatch) { - FdispatchrcConfig.Builder builder = new FdispatchrcConfig.Builder(); - dispatch.getConfig(builder); - return new FdispatchrcConfig(builder); - } - - public static void assertEngine(int rowId, int partitionId, PartitionsConfig.Dataset.Engine engine) { - assertEquals(rowId, engine.rowid()); - assertEquals(partitionId, engine.partid()); - } - - public static void assertEngine(int rowId, int partitionId, String connectSpec, PartitionsConfig.Dataset.Engine engine) { - assertEngine(rowId, partitionId, engine); - assertEquals(connectSpec, engine.name_and_port()); - } -} -- cgit v1.2.3