
io.nosqlbench.engine.api.activityconfig.yaml.OpTemplate Maven / Gradle / Ivy
package io.nosqlbench.engine.api.activityconfig.yaml;
import io.nosqlbench.engine.api.activityconfig.ParsedStmt;
import io.nosqlbench.engine.api.util.Tagged;
import java.util.Map;
import java.util.Optional;
import java.util.function.Function;
/**
* The OpTemplate is the developer's view of the operational templates that users
* provide in YAML or some other structured format.
*
* Terms
* Within this documentation, the word OpTemplate will refer to the template API and
* semantics. The word user template will refer to the configuration data as provided
* by a user.
*
* OpTemplates are the native Java representation of the user templates that specify how to
* make an executable operation. OpTemplates are not created for each operation, but are used
* to create an mostly-baked intermediate form commonly known as a ready op.
* It is the intermediate form which is used to create an instance of an executable
* op in whichever way is the most appropriate and efficient for a given driver.
*
* This class serves as the canonical documentation and API for how user templates
* are mapped into a fully resolved OpTemplate. User-provided op templates can be
* any basic data structure, and are often provided as part of a YAML workload file.
* The description below will focus on structural rules rather than any particular
* encoding format. The types used are fairly universal and easy to map from one
* format to another.
*
*
* A long-form introduction to this format is included in the main NoSQLBench docs
* at docs.nosqlbench.io
* under the Designing Workloads section.
*
* A few structural variations are allowed -- No specific form enforced. The reasons for this are:
* 1) It is generally obvious what as user wants to do from a given layout. 2) Data structure
* markup is generally frustrating and difficult to troubleshoot. 3) The conceptual domain of
* NB op construction is well-defined enough to avoid ambiguity.
*
* Type Conventions
*
* For the purposes of simple interoperability, the types used at this interface boundary should
* be limited to common scalar types -- numbers and strings, and simple structures like maps and lists.
* The basic types defined for ECMAScript should eventually be supported, but no domain-specific
* objects which would require special encoding or decoding rules should be used.
*
* Standard Properties
*
* Each op template can have these standard properties:
*
* - name - every op template has a name, even if it is auto generated for you. This is used to
* name errors in the log, to name metrics in telemetry, and so on.
* - description - an optional description, defaulted to "".
* - statement - An optional string value which represents an opaque form of the body of
* an op template
* - params - A string-object map of zero or more named parameters, where the key is taken as the parameter
* name and the value is any simple object form as limited by type conventions above.
*
- bindings - A map of binding definitions, where the string key is taken as the anchor name, and the
* string value is taken as the binding recipe.
* - tags - A map of tags, with string names and values
*
*
* The user-provided definition of an op template should capture a blueprint of an operation to be executed by
* a native driver. As such, you need either a statement or a set of params which can describe what
* specific type should be constructed. The rules on building an executable operation are not enforced
* by this API. Yet, responsible NB driver developers will clearly document what the rules
* are for specifying each specific type of operation supported by an NB driver with examples in YAML format.
*
* OpTemplate Construction Rules
*
* The available structural forms follow a basic set of rules for constructing the OpTemplate in a consistent way.
*
* - A collection of user-provided op templates is provided as a string, a list or a map.
* - All maps are order-preserving, like {@link java.util.LinkedHashMap}
* - For maps, the keys are taken as the names of the op template instances.
* - The content of each op template can be provided as a string or as a map.
*
* - If the op template entry is provided as a string, then the OpTemplate is constructed as having only a single
* statement property (in addition to defaults within scope).
* as provided by OpTemplate API.
* - If the op template entry is provided as a map, then the OpTemplate is constructed as having all of the
* named properties defined in the standard properties above.
* Any entry in the template which is not a reserved word is assigned to the params map as a parameter, in whatever structured
* type is appropriate (scalar, lists, maps).
*
*
*
*
* Example Forms
* The valid forms are shown below as examples.
*
* One String Statement
* {@code
* statement: statement
* }
*
* List of Templates
* {@code
* statements:
* - statement1
* - statement2
* }
*
* List of Maps
* {@code
* statements:
* - name: name1
* stmt: statement body
* params:
* p1: v1
* p2: v2
* }
*
* List Of Condensed Maps
* {@code
* statements:
* - name1: statement body
* p1: v1
* p2: v2
* }
*/
public interface OpTemplate extends Tagged {
String getName();
String getStmt();
Map getBindings();
Map getParams();
Map getParamsAsValueType(Class extends T> type);
V removeParamOrDefault(String name, V defaultValue);
@SuppressWarnings("unchecked")
V getParamOrDefault(String name, V defaultValue);
V getParam(String name, Class extends V> type);
@SuppressWarnings("unchecked")
Optional getOptionalStringParam(String name, Class extends V> type);
Optional getOptionalStringParam(String name);
Map getTags();
/**
* Parse the statement for anchors and return a richer view of the StmtDef which
* is simpler to use for most statement configuration needs.
*
* @return a new {@link ParsedStmt}
*/
ParsedStmt getParsed(Function... transforms);
String getDesc();
}