Versions Compared

Key

  • This line was added.
  • This line was removed.
  • Formatting was changed.

...

  • Query data node using cps-path

  • Implementation of OR Operator
  • Limitations

References

Jira
serverONAP Jira
serverId425b2b0a-557c-3c0c-b515-579789cceedb
keyCPS-1215

Issues & Decisions

...

#

...

Issue

...

Notes 

...

Decision

...


...

Query data node using cps-path

...

Adding OR operator to the antlr grammer file 

PATH : cps-path-parser/src/main/antlr4/org/onap/cps/cpspath/parser/antlr4/CpsPath.g4

Solution : listElementRef :  OB leafCondition ( ( KW_AND | KW_OR) leafCondition)* CB 
                multipleLeafConditions : OB leafCondition ( ( KW_AND | KW_OR) leafCondition)* CB 

It is tested by antlr test

...

Code changes made to recognise the operatoe i.e., and ,or

PATH:cps-path-parser/src/main/java/org/onap/cps/cpspath/parser/CpsPathBuilder.java

Solution:

String parent = ctx.getParent().getText();
        String payload = ctx.getPayload().getText();
        payloads.add(payload);
        String operator = findOperator(parent, payloads);
        appendCondition(normalizedXpathBuilder, ctx.leafName().getText(), comparisonValue, operator);
        if (processingAncestorAxis) {
            appendCondition(normalizedAncestorPathBuilder, ctx.leafName().getText(), comparisonValue, operator);
        }
    }
    private String findOperator(String parent, List<String> payloads) {
        StringBuilder parentStringBuilder = new StringBuilder(parent);
        try {
            payloads.forEach(payload -> parentStringBuilder.delete(parentStringBuilder.indexOf(payload), parentStringBuilder.indexOf(payload) + payload.length()));
            parentStringBuilder.delete(0, parentStringBuilder.indexOf("[") + 1);
            return parentStringBuilder.toString().trim();
        } catch (RuntimeException e) {
            return null;
        }
    }
 private void appendCondition(final StringBuilder currentNormalizedPathBuilder, final String name,
                                 final Object value, String operator) {
        final char lastCharacter = currentNormalizedPathBuilder.charAt(currentNormalizedPathBuilder.length() - 1);
        currentNormalizedPathBuilder.append(lastCharacter == '[' ? "" : " " + operator + " ");
        currentNormalizedPathBuilder.append("@");
        currentNormalizedPathBuilder.append(name);
        currentNormalizedPathBuilder.append("='");
        currentNormalizedPathBuilder.append(value);
        currentNormalizedPathBuilder.append("'");
    }
}

...

PATH:cps-path-parser/src/test/groovy/org/onap/cps/cpspath/parser/CpsPathQuerySpec.groovy

1. def 'Parse cps path having OR operator containing #scenario.'() {
        when: 'the given cps path is parsed'

       def result = CpsPathUtil.getCpsPathQuery(cpsPath)
        then: 'the query has the right normalized xpath type'
        assert result.normalizedXpath == expectedNormalizedXPath
        where: 'the following data is used'
        scenario                                              | cpsPath                                         || expectedNormalizedXPath
        'parent & child with more than one attribute'         | '/parent/child[@key1=1 or @key2="abc"]/child2'  || "/parent/child[@key1='1' or @key2='abc']/child2"
    }

...

1.Using AND condition

In query of data node, when we can combine two leaf elements using “AND” condition this would give result only if both leaf values are under same list. Below are the examples:

  • Here cps-path  //books[@pub_year=1994 and @price=895]
    • Since, pub_year=1994 and price=895 are under same list it gives the response

          Image Added

  • Similarly when cps-path  //books[@pub_year=1994 and @price=1099]
    • Since, pub_year=1994 and price=1099 are under different list it gives the empty response

        

2.Using OR condition

In order to search across given json data here OR condition support this implementation

we combine two leaf elements using “OR” condition this would give result. Below are the examples:

  • Here cps-path //books[@pub_year=1994 or @price=1099]]
    • Since, pub_year=1994 and price=1099 are under different list it gives the required response

Image Added

  • Here cps-path //books[@pub_year=1994 or @price=895 or @title="Far Horizons"]
    • pub_year=1994 and price=895 and title=Far Horizons  are under different list it gives the required response                                                        

Image Added

  • Also cps-path //books[@price=895 or @title="xyz"]
    •  price=895 and title=xyz  which non-json value 

//books[@pub_year=1994 or @price=895 or @title="Far Horizons"]

Image Added

Implementation of OR Operator

1.Update antlr parser to recognize OR in leaf-condition
2.Implement required (native) query
3.Add Integration tests for
     a.filter on  mix of string and integer leaf-values
     b.filter on non-json data
     c.filter on combination of multiple AND's as well as OR's
4.Update documentation
5.demo to team 

  Query used  : SELECT * FROM FRAGMENT WHERE anchor_id = :anchorId AND xpath ~ :xpathRegex AND ( attributes @> '{"price":895}' or  attributes @> '{"title":"Far Horizons"}')

Limitations:

1.Since leaf are stored in Hashmap same keys are not supported, unique keys only supports.

2.Only leaves can be used, leaf-list are not supported

3.Only string and integer values are supported, boolean and float values are not supported.

4.Multiple attributes can only be combined using AND, OR , multiple AND's , multiple OR's and bracketing is not supported.

5.Also the order of leaf elements in the map is not preserved , so combination of And/Or  would not give expected result. Currently working on the ordering of leaf elements to give proper support for combination of and/or  CPS-1629.