blob: 9e6e92b603a3e77b1a60447c1f1d667e2cba3905 [file] [log] [blame]
/*
* 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.rya.indexing.accumulo;
import java.util.HashSet;
import java.util.Properties;
import java.util.Set;
import org.apache.commons.lang3.StringUtils;
import org.apache.hadoop.conf.Configuration;
import org.apache.rya.accumulo.AbstractAccumuloRdfConfigurationBuilder;
import org.apache.rya.accumulo.AccumuloRdfConfiguration;
import org.apache.rya.accumulo.AccumuloRdfConfigurationBuilder;
import org.apache.rya.api.domain.RyaURI;
import org.apache.rya.indexing.accumulo.entity.EntityCentricIndex;
import org.apache.rya.indexing.accumulo.freetext.AccumuloFreeTextIndexer;
import org.apache.rya.indexing.accumulo.temporal.AccumuloTemporalIndexer;
import org.apache.rya.indexing.external.PrecomputedJoinIndexer;
import org.apache.rya.indexing.statement.metadata.matching.StatementMetadataOptimizer;
import org.eclipse.rdf4j.sail.Sail;
import com.google.common.base.Preconditions;
import com.google.common.collect.Lists;
/**
* This class is an extension of the AccumuloRdfConfiguration object used to to
* create a {@link Sail} connection to an Accumulo backed instance of Rya. This
* configuration object is designed to create Accumulo Rya Sail connections
* where one or more of the Accumulo Rya Indexes are enabled. These indexes
* include the {@link AccumuloFreeTextIndexer}, {@link AccumuloTemporalIndexer},
* {@link EntityCentricIndex}, and the {@link PrecomputedJoinIndexer}.
*
*/
public class AccumuloIndexingConfiguration extends AccumuloRdfConfiguration {
private AccumuloIndexingConfiguration() {
}
public static AccumuloIndexingConfigBuilder builder() {
return new AccumuloIndexingConfigBuilder();
}
/**
* Creates an AccumuloIndexingConfiguration object from a Properties file.
* This method assumes that all values in the Properties file are Strings
* and that the Properties file uses the keys below.
*
* <br>
* <ul>
* <li>"accumulo.auths" - String of Accumulo authorizations. Default is
* empty String.
* <li>"accumulo.visibilities" - String of Accumulo visibilities assigned to
* ingested triples.
* <li>"accumulo.instance" - Accumulo instance name (required)
* <li>"accumulo.user" - Accumulo user (required)
* <li>"accumulo.password" - Accumulo password (required)
* <li>"accumulo.rya.prefix" - Prefix for Accumulo backed Rya instance.
* Default is "rya_"
* <li>"accumulo.zookeepers" - Zookeepers for underlying Accumulo instance
* (required if not using Mock)
* <li>"use.mock" - Use a MockAccumulo instance as back-end for Rya
* instance. Default is false.
* <li>"use.prefix.hashing" - Use prefix hashing for triples. Helps avoid
* hot-spotting. Default is false.
* <li>"use.count.stats" - Use triple pattern cardinalities for query
* optimization. Default is false.
* <li>"use.join.selectivity" - Use join selectivity for query optimization.
* Default is false.
* <li>"use.display.plan" - Display query plan during evaluation. Useful for
* debugging. Default is true.
* <li>"use.inference" - Use backward chaining inference during query
* evaluation. Default is false.
* <li>"use.freetext" - Use Accumulo Freetext Indexer for querying and
* ingest. Default is false.
* <li>"use.temporal" - Use Accumulo Temporal Indexer for querying and
* ingest. Default is false.
* <li>"use.entity" - Use Accumulo Entity Index for querying and ingest.
* Default is false.
* <li>"fluo.app.name" - Set name of Fluo App to update PCJs.
* <li>"use.pcj" - Use PCJs for query optimization. Default is false.
* <li>"use.optimal.pcj" - Use optimal PCJ for query optimization. Default
* is false.
* <li>"pcj.tables" - PCJ tables to be used, specified as comma delimited
* Strings with no spaces between. If no tables are specified, all
* registered tables are used.
* <li>"freetext.predicates" - Freetext predicates used for ingest. Specify
* as comma delimited Strings with no spaces between. Empty by default.
* <li>"temporal.predicates" - Temporal predicates used for ingest. Specify
* as comma delimited Strings with no spaces between. Empty by default.
* </ul>
* <br>
*
* @param props
* - Properties file containing Accumulo specific configuration
* parameters
* @return AccumumuloIndexingConfiguration with properties set
*/
public static AccumuloIndexingConfiguration fromProperties(final Properties props) {
return AccumuloIndexingConfigBuilder.fromProperties(props);
}
/**
*
* Specify whether to use use {@link EntitCentricIndex} for ingest and at
* query time. The default value is false, and if useEntity is set to true
* and the EntityIndex does not exist, then useEntity will default to false.
*
* @param useEntity
* - use entity indexing
*/
public void setUseEntity(final boolean useEntity) {
setBoolean(ConfigUtils.USE_ENTITY, useEntity);
}
/**
* @return boolean indicating whether or not {@link EntityCentricIndex} is enabled
*/
public boolean getUseEntity() {
return getBoolean(ConfigUtils.USE_ENTITY, false);
}
/**
*
* Specify whether to use use {@link AccumuloTemproalIndexer} for ingest and
* at query time. The default value is false, and if useTemporal is set to
* true and the TemporalIndex does not exist, then useTemporal will default
* to false.
*
* @param useTemporal
* - use temporal indexing
*/
public void setUseTemporal(final boolean useTemporal) {
setBoolean(ConfigUtils.USE_TEMPORAL, useTemporal);
}
/**
* @return boolean indicating whether or not {@link AccumuloTemporalIndexer} is enabled
*/
public boolean getUseTemporal() {
return getBoolean(ConfigUtils.USE_TEMPORAL, false);
}
/**
* @return boolean indicating whether or not {@link AccumuloFreeTextIndexer} is enabled
*/
public boolean getUseFreetext() {
return getBoolean(ConfigUtils.USE_FREETEXT, false);
}
/**
*
* Specify whether to use use {@link AccumuloFreeTextIndexer} for ingest and
* at query time. The default value is false, and if useFreeText is set to
* true and the FreeTextIndex does not exist, then useFreeText will default
* to false.
*
* @param useFreeText
* - use freetext indexing
*/
public void setUseFreetext(final boolean useFreetext) {
setBoolean(ConfigUtils.USE_FREETEXT, useFreetext);
}
/**
* @return boolean indicating whether or not {@link PrecomputedJoinIndexer} is enabled
*/
public boolean getUsePCJUpdater() {
return getBoolean(ConfigUtils.USE_PCJ_UPDATER_INDEX, false);
}
public void setUsePCJUpdater(final boolean usePCJUpdater) {
setBoolean(ConfigUtils.USE_PCJ_UPDATER_INDEX, usePCJUpdater);
if (usePCJUpdater) {
set(ConfigUtils.PCJ_STORAGE_TYPE, "ACCUMULO");
set(ConfigUtils.PCJ_UPDATER_TYPE, "FLUO");
}
}
/**
*
* Specify the name of the PCJ Fluo updater application. A non-null
* application results in the {@link PrecomputedJoinIndexer} being activated
* so that all triples ingested into Rya are also ingested into Fluo to
* update any registered PCJs. PreomputedJoinIndexer is turned off by
* default. If no fluo application of the specified name exists, a
* RuntimeException will occur.
*
* @param fluoAppName
* - use entity indexing
*/
public void setFluoAppUpdaterName(final String fluoAppName) {
Preconditions.checkNotNull(fluoAppName, "Fluo app name cannot be null.");
setUsePCJUpdater(true);
set(ConfigUtils.FLUO_APP_NAME, fluoAppName);
}
/**
* @return name of the Fluo PCJ Updater application
*/
public String getFluoAppUpdaterName() {
return get(ConfigUtils.FLUO_APP_NAME);
}
/**
* Use Precomputed Joins as a query optimization.
*
* @param usePcj
* - use PCJ
*/
public void setUsePCJ(final boolean usePCJ) {
setBoolean(ConfigUtils.USE_PCJ, usePCJ);
}
/**
* @return boolean indicating whether or not PCJs are enabled for querying
*/
public boolean getUsePCJ() {
return getBoolean(ConfigUtils.USE_PCJ, false);
}
/**
* Use Precomputed Joins as a query optimization and attempt to find the
* best combination of PCJ in the query plan
*
* @param useOptimalPcj
* - use optimal pcj plan
*/
public void setUseOptimalPCJ(final boolean useOptimalPCJ) {
setBoolean(ConfigUtils.USE_OPTIMAL_PCJ, useOptimalPCJ);
}
/**
* @return boolean indicating whether or not query planner will look for optimal
* combinations of PCJs when forming the query plan.
*/
public boolean getUseOptimalPCJ() {
return getBoolean(ConfigUtils.USE_OPTIMAL_PCJ, false);
}
/**
* Sets the predicates used for freetext indexing
* @param predicates - Array of predicate URI strings used for freetext indexing
*/
public void setAccumuloFreeTextPredicates(final String[] predicates) {
Preconditions.checkNotNull(predicates, "Freetext predicates cannot be null.");
setStrings(ConfigUtils.FREETEXT_PREDICATES_LIST, predicates);
}
/**
* Gets the predicates used for freetext indexing
* @return Array of predicate URI strings used for freetext indexing
*/
public String[] getAccumuloFreeTextPredicates() {
return getStrings(ConfigUtils.FREETEXT_PREDICATES_LIST);
}
/**
* Sets the predicates used for temporal indexing
* @param predicates - Array of predicate URI strings used for temporal indexing
*/
public void setAccumuloTemporalPredicates(final String[] predicates) {
Preconditions.checkNotNull(predicates, "Freetext predicates cannot be null.");
setStrings(ConfigUtils.TEMPORAL_PREDICATES_LIST, predicates);
}
/**
* Gets the predicates used for temporal indexing
* @return Array of predicate URI strings used for temporal indexing
*/
public String[] getAccumuloTemporalPredicates() {
return getStrings(ConfigUtils.TEMPORAL_PREDICATES_LIST);
}
private static Set<RyaURI> getPropURIFromStrings(final String... props) {
final Set<RyaURI> properties = new HashSet<>();
if (props != null) {
for(final String prop : props) {
if (StringUtils.isNotBlank(prop)) {
properties.add(new RyaURI(prop));
}
}
}
return properties;
}
/**
* Concrete extension of {@link AbstractAccumuloRdfConfigurationBuilder}
* that adds setter methods to configure Accumulo Rya Indexers in addition
* the core Accumulo Rya configuration. This builder should be used instead
* of {@link AccumuloRdfConfigurationBuilder} to configure a query client to
* use one or more Accumulo Indexers.
*
*/
public static class AccumuloIndexingConfigBuilder extends
AbstractAccumuloRdfConfigurationBuilder<AccumuloIndexingConfigBuilder, AccumuloIndexingConfiguration> {
private String fluoAppName;
private boolean useFreetext = false;
private boolean useTemporal = false;
private boolean useEntity = false;
private boolean useMetadata = false;
private String[] freetextPredicates;
private String[] temporalPredicates;
private boolean usePcj = false;
private boolean useOptimalPcj = false;
private String[] pcjs = new String[0];
private Set<RyaURI> metadataProps = new HashSet<>();
private static final String USE_FREETEXT = "use.freetext";
private static final String USE_TEMPORAL = "use.temporal";
private static final String USE_ENTITY = "use.entity";
private static final String FLUO_APP_NAME = "fluo.app.name";
private static final String USE_PCJ = "use.pcj";
private static final String USE_OPTIMAL_PCJ = "use.optimal.pcj";
private static final String TEMPORAL_PREDICATES = "temporal.predicates";
private static final String FREETEXT_PREDICATES = "freetext.predicates";
private static final String PCJ_TABLES = "pcj.tables";
private static final String USE_STATEMENT_METADATA = "use.metadata";
private static final String STATEMENT_METADATA_PROPERTIES = "metadata.properties";
/**
* Creates an AccumuloIndexingConfiguration object from a Properties
* file. This method assumes that all values in the Properties file are
* Strings and that the Properties file uses the keys below.
*
* <br>
* <ul>
* <li>"accumulo.auths" - String of Accumulo authorizations. Default is
* empty String.
* <li>"accumulo.visibilities" - String of Accumulo visibilities
* assigned to ingested triples.
* <li>"accumulo.instance" - Accumulo instance name (required)
* <li>"accumulo.user" - Accumulo user (required)
* <li>"accumulo.password" - Accumulo password (required)
* <li>"accumulo.rya.prefix" - Prefix for Accumulo backed Rya instance.
* Default is "rya_"
* <li>"accumulo.zookeepers" - Zookeepers for underlying Accumulo
* instance (required if not using Mock)
* <li>"use.mock" - Use a MockAccumulo instance as back-end for Rya
* instance. Default is false.
* <li>"use.prefix.hashing" - Use prefix hashing for triples. Helps
* avoid hot-spotting. Default is false.
* <li>"use.count.stats" - Use triple pattern cardinalities for query
* optimization. Default is false.
* <li>"use.join.selectivity" - Use join selectivity for query
* optimization. Default is false.
* <li>"use.display.plan" - Display query plan during evaluation. Useful
* for debugging. Default is true.
* <li>"use.inference" - Use backward chaining inference during query
* evaluation. Default is false.
* <li>"use.freetext" - Use Accumulo Freetext Indexer for querying and
* ingest. Default is false.
* <li>"use.temporal" - Use Accumulo Temporal Indexer for querying and
* ingest. Default is false.
* <li>"use.entity" - Use Accumulo Entity Index for querying and ingest.
* Default is false.
* <li>"use.metadata" - Use Accumulo StatementMetadata index for querying Statement Properties.
* Default is false.
* <li>"metadata.properties" - Set Statement Properties that can be queried using the StatementMetadataOptimizer.
* Default is empty.
* <li>"fluo.app.name" - Set name of Fluo App to update PCJs
* <li>"use.pcj" - Use PCJs for query optimization. Default is false.
* <li>"use.optimal.pcj" - Use optimal PCJ for query optimization.
* Default is false.
* <li>"pcj.tables" - PCJ tables to be used, specified as comma
* delimited Strings with no spaces between. If no tables are specified,
* all registered tables are used.
* <li>"freetext.predicates" - Freetext predicates used for ingest.
* Specify as comma delimited Strings with no spaces between. Empty by
* default.
* <li>"temporal.predicates" - Temporal predicates used for ingest.
* Specify as comma delimited Strings with no spaces between. Empty by
* default.
* </ul>
* <br>
*
* @param props
* - Properties file containing Accumulo specific
* configuration parameters
* @return AccumumuloIndexingConfiguration with properties set
*/
public static AccumuloIndexingConfiguration fromProperties(final Properties props) {
Preconditions.checkNotNull(props);
try {
final AccumuloIndexingConfigBuilder builder = new AccumuloIndexingConfigBuilder() //
.setAuths(props.getProperty(AbstractAccumuloRdfConfigurationBuilder.ACCUMULO_AUTHS, "")) //
.setRyaPrefix(
props.getProperty(AbstractAccumuloRdfConfigurationBuilder.ACCUMULO_RYA_PREFIX, "rya_"))//
.setVisibilities(
props.getProperty(AbstractAccumuloRdfConfigurationBuilder.ACCUMULO_VISIBILITIES, ""))
.setUseInference(getBoolean(
props.getProperty(AbstractAccumuloRdfConfigurationBuilder.USE_INFERENCE, "false")))//
.setDisplayQueryPlan(getBoolean(props
.getProperty(AbstractAccumuloRdfConfigurationBuilder.USE_DISPLAY_QUERY_PLAN, "true")))//
.setAccumuloUser(props.getProperty(AbstractAccumuloRdfConfigurationBuilder.ACCUMULO_USER)) //
.setAccumuloInstance(
props.getProperty(AbstractAccumuloRdfConfigurationBuilder.ACCUMULO_INSTANCE))//
.setAccumuloZooKeepers(
props.getProperty(AbstractAccumuloRdfConfigurationBuilder.ACCUMULO_ZOOKEEPERS))//
.setAccumuloPassword(
props.getProperty(AbstractAccumuloRdfConfigurationBuilder.ACCUMULO_PASSWORD))//
.setUseMockAccumulo(getBoolean(
props.getProperty(AbstractAccumuloRdfConfigurationBuilder.USE_MOCK_ACCUMULO, "false")))//
.setUseAccumuloPrefixHashing(getBoolean(
props.getProperty(AbstractAccumuloRdfConfigurationBuilder.USE_PREFIX_HASHING, "false")))//
.setUseCompositeCardinality(getBoolean(
props.getProperty(AbstractAccumuloRdfConfigurationBuilder.USE_COUNT_STATS, "false")))//
.setUseJoinSelectivity(getBoolean(props
.getProperty(AbstractAccumuloRdfConfigurationBuilder.USE_JOIN_SELECTIVITY, "false")))//
.setUseAccumuloFreetextIndex(getBoolean(props.getProperty(USE_FREETEXT, "false")))//
.setUseAccumuloTemporalIndex(getBoolean(props.getProperty(USE_TEMPORAL, "false")))//
.setUseAccumuloEntityIndex(getBoolean(props.getProperty(USE_ENTITY, "false")))//
.setAccumuloFreeTextPredicates(StringUtils.split(props.getProperty(FREETEXT_PREDICATES), ","))//
.setAccumuloTemporalPredicates(StringUtils.split(props.getProperty(TEMPORAL_PREDICATES), ","))//
.setUsePcj(getBoolean(props.getProperty(USE_PCJ, "false")))//
.setUseOptimalPcj(getBoolean(props.getProperty(USE_OPTIMAL_PCJ, "false")))//
.setPcjTables(StringUtils.split(props.getProperty(PCJ_TABLES), ","))//
.setPcjUpdaterFluoAppName(props.getProperty(FLUO_APP_NAME))
.setUseStatementMetadata(getBoolean(props.getProperty(USE_STATEMENT_METADATA)))
.setStatementMetadataProperties(getPropURIFromStrings(StringUtils.split(props.getProperty(STATEMENT_METADATA_PROPERTIES), ",")));
return builder.build();
} catch (final Exception e) {
throw new RuntimeException(e);
}
}
/**
*
* Specify whether to use use {@link AccumuloFreeTextIndexer} for ingest
* and at query time. The default value is false, and if useFreeText is
* set to true and the FreeTextIndex does not exist, then useFreeText
* will default to false.
*
* @param useFreeText
* - use freetext indexing
* @return AccumuloIndexingConfigBuilder for chaining method invocations
*/
public AccumuloIndexingConfigBuilder setUseAccumuloFreetextIndex(final boolean useFreeText) {
this.useFreetext = useFreeText;
return this;
}
/**
*
* Specify whether to use use {@link AccumuloTemporalIndexer} for ingest
* and at query time. The default value is false, and if useTemporal is
* set to true and the TemporalIndex does not exist, then useTemporal
* will default to false.
*
* @param useTemporal
* - use temporal indexing
* @return AccumuloIndexingConfigBuilder for chaining method invocations
*/
public AccumuloIndexingConfigBuilder setUseAccumuloTemporalIndex(final boolean useTemporal) {
this.useTemporal = useTemporal;
return this;
}
/**
*
* Specify whether to use use {@link EntitCentricIndex} for ingest and
* at query time. The default value is false, and if useEntity is set to
* true and the EntityIndex does not exist, then useEntity will default
* to false.
*
* @param useEntity
* - use entity indexing
* @return AccumuloIndexingConfigBuilder for chaining method invocations
*/
public AccumuloIndexingConfigBuilder setUseAccumuloEntityIndex(final boolean useEntity) {
this.useEntity = useEntity;
return this;
}
/**
*
* Specify the name of the PCJ Fluo updater application. A non-null
* application results in the {@link PrecomputedJoinIndexer} being
* activated so that all triples ingested into Rya are also ingested
* into Fluo to update any registered PCJs. PreomputedJoinIndexer is
* turned off by default. If no fluo application of the specified name
* exists, a RuntimeException will be thrown.
*
* @param fluoAppName
* - use entity indexing
* @return AccumuloIndexingConfigBuilder for chaining method invocations
*/
public AccumuloIndexingConfigBuilder setPcjUpdaterFluoAppName(final String fluoAppName) {
this.fluoAppName = fluoAppName;
return this;
}
/**
*
* @param predicates
* - String of comma delimited predicates used by the
* FreetextIndexer to determine which triples to index
* @return AccumuloIndexingConfigBuilder for chaining method invocations
*/
public AccumuloIndexingConfigBuilder setAccumuloFreeTextPredicates(final String... predicates) {
this.freetextPredicates = predicates;
return this;
}
/**
*
* @param predicates
* - String of comma delimited predicates used by the
* TemporalIndexer to determine which triples to index
* @return AccumuloIndexingConfigBuilder for chaining method invocations
*/
public AccumuloIndexingConfigBuilder setAccumuloTemporalPredicates(final String... predicates) {
this.temporalPredicates = predicates;
return this;
}
/**
* Use Precomputed Joins as a query optimization.
*
* @param usePcj
* - use PCJ
* @return AccumuloIndexingConfigBuilder for chaining method invocations
*/
public AccumuloIndexingConfigBuilder setUsePcj(final boolean usePcj) {
this.usePcj = usePcj;
return this;
}
/**
* Use Precomputed Joins as a query optimization and attempt to find the
* best combination of PCJs in the query plan
*
* @param useOptimalPcj
* - use optimal pcj plan
* @return AccumuloIndexingConfigBuilder for chaining method invocations
*/
public AccumuloIndexingConfigBuilder setUseOptimalPcj(final boolean useOptimalPcj) {
this.useOptimalPcj = useOptimalPcj;
return this;
}
/**
* Specify a collection of PCJ tables to use for query optimization. If
* no tables are specified and PCJs are enabled for query evaluation,
* then all registered PCJs will be considered when optimizing the
* query.
*
* @param pcjs
* - array of PCJs to be used for query evaluation
* @return AccumuloIndexingConfigBuilder for chaining method invocations
*/
public AccumuloIndexingConfigBuilder setPcjTables(final String... pcjs) {
this.pcjs = pcjs;
return this;
}
/**
* Specify whether or not to use {@link StatementMetadataOptimizer} to query on Statement
* properties.
* @param useMetadata
* @return AccumuloIndexingConfigBuilder for chaining method invocations
*/
public AccumuloIndexingConfigBuilder setUseStatementMetadata(final boolean useMetadata) {
this.useMetadata = useMetadata;
return this;
}
/**
* Specify properties that the {@link StatementMetadataOptimizer} will use to query
* @param useMetadata
* @return AccumuloIndexingConfigBuilder for chaining method invocations
*/
public AccumuloIndexingConfigBuilder setStatementMetadataProperties(final Set<RyaURI> metadataProps) {
this.metadataProps = metadataProps;
return this;
}
/**
* @return {@link AccumuloIndexingConfiguration} object with specified parameters set
*/
@Override
public AccumuloIndexingConfiguration build() {
final AccumuloIndexingConfiguration conf = getConf(super.build());
return conf;
}
/**
* Assigns builder values to appropriate parameters within the {@link Configuration} object.
*
* @param conf - Configuration object
* @return - Configuration object with parameters set
*/
private AccumuloIndexingConfiguration getConf(final AccumuloIndexingConfiguration conf) {
Preconditions.checkNotNull(conf);
if (fluoAppName != null) {
conf.setFluoAppUpdaterName(fluoAppName);
}
if (useFreetext) {
conf.setUseFreetext(useFreetext);
if (freetextPredicates != null) {
conf.setAccumuloFreeTextPredicates(freetextPredicates);
}
}
if (useTemporal) {
conf.setUseTemporal(useTemporal);
if (temporalPredicates != null) {
conf.setAccumuloTemporalPredicates(temporalPredicates);
}
}
if (usePcj || useOptimalPcj) {
conf.setUsePCJ(usePcj);
conf.setUseOptimalPCJ(useOptimalPcj);
if (pcjs.length > 1 || (pcjs.length == 1 && pcjs[0] != null)) {
conf.setPcjTables(Lists.newArrayList(pcjs));
}
}
if(useMetadata) {
conf.setUseStatementMetadata(useMetadata);
conf.setStatementMetadataProperties(metadataProps);
}
conf.setBoolean(ConfigUtils.USE_ENTITY, useEntity);
return conf;
}
@Override
protected AccumuloIndexingConfigBuilder confBuilder() {
return this;
}
@Override
protected AccumuloIndexingConfiguration createConf() {
return new AccumuloIndexingConfiguration();
}
}
}