From 33eb71c3f1f5610b3b62129532513897765a17a5 Mon Sep 17 00:00:00 2001 From: "Konstantin.Nosach" Date: Tue, 26 Jan 2021 12:50:33 +0200 Subject: [PATCH] Document usage of Binding Query Language Adds documentation specific to the developer guide: - Compears two approaches for retrieving data from storage - Read-like operation (old one approach) - Query-like operation (new one approach) JIRA: MDSAL-656 Change-Id: Ie84224a584256f411d63b0ecb900f341f9fa3d35 Signed-off-by: Kostiantyn Nosach --- docs/index.rst | 1 + ...query-binding-language-developer-guide.rst | 108 ++++++++++++++++++ 2 files changed, 109 insertions(+) create mode 100644 docs/query-binding-language-developer-guide.rst diff --git a/docs/index.rst b/docs/index.rst index a80c860b20..12dd301539 100644 --- a/docs/index.rst +++ b/docs/index.rst @@ -125,3 +125,4 @@ Table of Contents architecture conceptual-data-tree incremental-backup + query-binding-language-developer-guide diff --git a/docs/query-binding-language-developer-guide.rst b/docs/query-binding-language-developer-guide.rst new file mode 100644 index 0000000000..dedfabed4e --- /dev/null +++ b/docs/query-binding-language-developer-guide.rst @@ -0,0 +1,108 @@ +.. _mdsal-binding-dev-guide: + +MD-SAL Binding Query Language Developer Guide +============================================= + +.. note:: + + Reading this section is likely useful as it contains an overview + of MD-SAL Binding query language in OpenDaylight and a how-to use it for + retrieving data from data storage. + +Retrieving data from storage +---------------------------- + +MD-SAL has two ways (operations) of retrieving data from storage: read-like and query-like operations. + +Read-like operation +~~~~~~~~~~~~~~~~~~~ + +The method **read** of ReadTransaction interface. + +:: + + FluentFuture> read(LogicalDatastoreType store, InstanceIdentifier path); + +The method reads data from the provided logical data store located at the provided path. +If the target is a subtree, then the whole subtree is read (and will be accessible from the returned DataObject). +So we are getting DataObject which we need to process in code for getting relevant data: + +:: + + FluentFuture> future; + try (ReadTransaction rtx = getDataBroker().newReadOnlyTransaction()) { + future = rtx.read(LogicalDatastoreType.CONFIGURATION, InstanceIdentifier.create(Foo.class)); + } + Foo haystack = future.get().orElseThrow(); + Object result = null; + for (System system : haystack.nonnullSystem().values()) { + if (needle.equals(system.getAlias())) { + result = system; + break; + } + } + +.. note:: + + The structure of the Foo container is `here`_. + +.. _here: https://github.com/opendaylight/mdsal/blob/master/binding/mdsal-binding-test-model/src/main/yang/mdsal-query.yang + +Query-like operation +~~~~~~~~~~~~~~~~~~~~ + +The method **execute** of QueryReadTransaction interface. + +:: + + FluentFuture> execute(LogicalDatastoreType store, QueryExpression query); + +The method executes a query on the provided logical data store for getting relevant data. +So we are getting result which we need for future business logic processing. +Before running the method execute we need to prepare a query with the match predicates. +For example, we want to find in Foo container the System with alias **target-needle**: + +:: + + String needle = "target-needle"; + QueryExpression query = factory.querySubtree(InstanceIdentifier.create(Foo.class)) + .extractChild(System.class) + .matching() + .leaf(System::getAlias).valueEquals(needle) + .build(); + +The method **querySubtree** creates a new **DescendantQueryBuilder** for a specified root path. It's intermediate query builder stage, +which allows the specification of the query result type to be built up via **extractChild(Class)** and +**extractChild(Class, Class)** methods. They used to specify which object type to select from the root path. +Once completed, use either **build()** to create a simple query, or **matching()** to transition to specify predicates. +There is a bunch of overloaded methods **leaf** which based on the type of arguments returns specific match builders: + +- ValueMatchBuilder methods: + +| **ValueMatch nonNull();** +| **ValueMatch isNull();** +| **ValueMatch valueEquals(V value);** + +- ComparableMatchBuilder extends ValueMatchBuilder and adds methods: + +| **ValueMatch lessThan(V value);** +| **ValueMatch lessThanOrEqual(V value);** +| **ValueMatch greaterThan(V value);** +| **ValueMatch greaterThanOrEqual(V value);** + +- StringMatchBuilder extends ValueMatchBuilder and adds methods: + +| **ValueMatch startsWith(String str);** +| **ValueMatch endsWith(String str);** +| **ValueMatch contains(String str);** +| **ValueMatch matchesPattern(Pattern pattern);** + +After creation of query, we can use it in the method execute of QueryReadTransaction interface: + +:: + + FluentFuture> future; + try (ReadTransaction rtx = getDataBroker().newReadOnlyTransaction()) { + future = ((QueryReadTransaction) rtx).execute(LogicalDatastoreType.CONFIGURATION, query); + } + QueryResult result = future.get(); \ No newline at end of file -- 2.36.6