Skip to content

Getting Started

There is no standardized way to query TOSCA repositories or instance data. Therefore, we introduce Queries4TOSCA which defined a query language for TOSCA. This language provides a graph-based query language which includes path expressions, filters, and pattern matching. This section will give a quick introduction to Queries4TOSCA.

Preparation

To run the example queries, we need to install OpenTOSCA Vintner and have a resolved instance of the "Getting Started" template. First, clone the repository.

1
2
3
4
5
6
7
git clone https://github.com/OpenTOSCA/opentosca-vintner.git
cd opentosca-vintner
git lfs install
git lfs pull
./task install
./task tasks:build
./task examples:pull:link

Then import the template, create an instance, and resolve the variability.

1
2
3
vintner templates import --template getting-started --path examples/xopera-getting-started
vintner instances init --instance getting-started --template getting-started
vintner instances resolve --instance getting-started --presets first

Example Queries

Queries start with a FROM statement, followed by either templates or instances and the name of the template or the name of the instance, respectively. Inside a SELECT statement, we can enter a path to the data that we want to return.

To get the entire contents of the template, run the following command.

1
2
3
vintner query --query "\
    FROM templates.getting-started \
    SELECT ."
tosca_definitions_version: tosca_simple_yaml_1_3
node_types:
  textfile:
    derived_from: tosca.nodes.SoftwareComponent
    properties:
      content:
        type: string
    interfaces:
      Standard:
        inputs:
          content:
            value:
              get_property:
                - SELF
                - content
            type: string
        operations:
          create: create.yaml
          delete: delete.yaml
topology_template:
  node_templates:
    localhost:
      type: tosca.nodes.Compute
      attributes:
        private_address: localhost
        public_address: localhost
    first:
      type: textfile
      properties:
        content: First Textfile has been selected!
      requirements:
        - host:
            node: localhost

We can return specific elements by specifying their path. Note, that topology_template can be omitted at the start. The following command returns the contents of the localhost node.

1
2
3
vintner query --query "\
    FROM templates.getting-started \
    SELECT node_templates.localhost"
1
2
3
4
type: tosca.nodes.Compute
attributes:
    private_address: localhost
    public_address: localhost

We can use an asterisk as a wildcard operator to get all child elements. The following command returns a list of all nodes.

1
2
3
vintner query --query "\
    FROM templates.getting-started \
    SELECT node_templates.*"
- type: tosca.nodes.Compute
  attributes:
    private_address: localhost
    public_address: localhost
- type: textfile
  properties:
    content: First Textfile has been selected!
  requirements:
    - host:
        node: localhost

We can also specify a predicate in square brackets after any part of the path expression to filter elements. The following command will return only nodes of type textfile.

1
2
3
vintner query --query "\
    FROM templates.getting-started \
    SELECT node_templates.*[type='textfile']"
1
2
3
4
5
6
type: textfile
properties:
  content: First Textfile has been selected!
requirements:
  - host:
      node: localhost

In cases where we are only interested in some elements of a node, we can use a return structure to restrict the output to certain variables. To do this, put curly braces with key-value pairs behind your path expression. The following command will return only the content property of the first node.

1
2
3
vintner query --query "\
    FROM templates.getting-started \
    SELECT node_templates.first{'Type': type, 'Text': properties.content}"
Type: textfile
Text: First Textfile has been selected!

This also works on arrays. The following command returns an array that consists of the name and type of each node. Note the lack of quotation marks - we are using a value from the template for both key and value of the return object.

1
2
3
vintner query --query "\
    FROM templates.getting-started \
    SELECT node_templates.*{name: type}"
- localhost: tosca.nodes.Compute
- first: textfile

MATCH statements are used to match patterns in the topology of a template. We can "draw" the pattern by surrounding nodes with parentheses and connect them to other nodes via arrows. The following statement will return all nodes that have a requirement fulfilled by localhost.

1
2
3
4
vintner query --query "\
    FROM templates.getting-started \
    MATCH ([name='localhost'])<--(node) \
    SELECT node"
1
2
3
4
5
6
7
first:
  type: textfile
  properties:
    content: First Textfile has been selected!
  requirements:
    - host:
        node: localhost

This is just a simple example. In a more complex scenario, it would be possible, e.g., to dynamically access the public address of a virtual machine which hosts a database to which a specific component connects.


Last update: December 13, 2024