CPS-731 Query Based on Public CM Properties

CPS-731 Query Based on Public CM Properties

 

https://lf-onap.atlassian.net/browse/CPS-731

Scope


It should be able to query all cm handles with a given set of public cm handle properties.

Requirements

  • We want all cm-Handles where both things are true.

  • If name is empty silently ignore, if value is empty (edge case test?)

  • Those properties also need to exist.

  • If query body does not follow supported structure return 400.

  • Empty query will return all cm-Handles.

A/C:

  1. Demo - with "and" behavior

  2. CI Test - two attributes

 

Issues/Decisions


Issue

Notes

Decision

Issue

Notes

Decision

1

1

Does request body need to declare "publicCmHandleProperties"?

Do we need to explicitly declare "publicCmHandleProperties"? 

Will there be another possible variation to this in the future?

{ "publicCmHandleProperties" : { "Colour": "red", "Size": "large" } }

Yes

2

2

Are public properties always stored (in postgress) in the format of "name" : x, "value": y?

(does NOT affect implementation)

In the fragment table there are example that follow this format 

{ "name": "Colour", "value": "red" }, { "name": "Size", "value": "large" }

Yes. But all this is hidden when using CpsPath type query

 

3

3

Will there only ever be 1 KV pairs in public properties (in the DB)?

 

Yes, as each property is stored in a separate list-item Fragment
But all this is hidden when using CpsPath type query

4

4

Does the order matter?

Does

{ "publicCmHandleProperties" : { "Colour" : "green", "Size" : "small" } }

==

{ "publicCmHandleProperties" : {          "Size" : "small" "Colour" : "green",    } }

No
But all this is hidden when using CpsPath type query

5

5

Should search be case sensitive?

depend on CPSPath functionality - may be case-sensitive

https://docs.onap.org/projects/onap-cps/en/latest/cps-path.html

Yes, that is the currently implement as such CpsPath type query. Given it is mostly machine-to-machine type queries this is good enough and performs better

6

6

What format should the response take?

We have two options currently:

 

  1. Return List<String>

[ "cmHandle1", "cmHandle2", ..., "cmHandleN" ]

 

2. Return CM Handle Objects

  1.  

    1. Already defined in CPS

    2. <Example Pending>

Contact @Tony Finnerty & @kieran mccarthy regarding this.
@Tony Finnerty Has no opinion on this matter

It has been decided to implement this using a list of cm handles

7

7

what if we have valid entries and one entry  is empty?

We would return all cm handles and others that match would be included in this list anyway.

→ To avoid this should we first check the entries int map for empty entries as further processing is unnecessary in this case.

Discussed with @Toine Siebelink and implementation changes are required for handling edges cases. we will handle empty and unknown properties separately.

8

8

Regarding empty/missing property in request

e.g.

{

    "publicCmHandleProperties": {
        """doesnt matter "
    }
}

Do we want to throw an exception if there is an empty property?

Do we silently ignore them and move on?

should we send two lists back... one with matching cm handles and one with those that failed processing?

We will throw a DataValidationException if an entry contains an empty property

 

Analysis/Implementation Proposal


High level Jiras:

  1. https://lf-onap.atlassian.net/browse/CPS-901

  2. https://lf-onap.atlassian.net/browse/CPS-902

  3. https://lf-onap.atlassian.net/browse/CPS-903

  4. https://lf-onap.atlassian.net/browse/CPS-904

 

Possible High-Level Implementation Steps:

  1. Match all xpaths using CPS Path Query

  2. Iterate over the list and retrieve all attributes

  3. Iterate over the attributes and collect those instances that match

  4. Return collected list of cm handles

Interface Proposal

URI

Design Notes

Comment(s)

URI

Design Notes

Comment(s)

1

POST /ncmp/v1/data/ch/searches

Scenario :  Request received to return all cm handles matching properties given
Method   : POST
URI          : {ncmpRoot}/ncmp/v1/data/ch/searches 
Header    : Content-Type: application/json

Request Body

{ "publicCmHandleProperties" : { "Colour" : "green", "Size" : "small" } }

Response Body Example 1

[ "cmHandle1", "cmHandle2", ..., "cmHandleN" ]

 

Below is a sample yaml for OpenAPI.

Sample OpenAPI yAML
executeSearchForMatchingPublicProperties: post: description: Execute search to get all cm handles for the given public properties tags: - network-cm-proxy summary: Execute cm handle search using operationId: executeSearchForMatchingPublicProperties requestBody: required: true content: application/json: schema: $ref: 'components.yaml#/components/schemas/PublicProperties' responses: 200: description: OK content: application/json: schema: type: array items: type: string 400: $ref: 'components.yaml#/components/responses/BadRequest' 401: $ref: 'components.yaml#/components/responses/Unauthorized' 403: $ref: 'components.yaml#/components/responses/Forbidden' 404: $ref: 'components.yaml#/components/responses/NotFound' 500: $ref: 'components.yaml#/components/responses/InternalServerError'

Testing


Gerrit Link

https://gerrit.onap.org/r/c/cps/+/127541

Data Used for Testing

xpath

attributes

xpath

attributes

1

/dmi-registry/cm-handles[@id='PNFDemo']/public-properties[@name='Contact2']

{"name": "Contact2", "value": "storeemail2@bookstore.com"}

2

/dmi-registry/cm-handles[@id='PNFDemo']/public-properties[@name='Contact'] 

{"name": "Contact", "value": "newemailforstore@bookstore.com"}

3

/dmi-registry/cm-handles[@id='Bookstore5']/public-properties[@name='color']

{"name": "color", "value": "won't match"}

4

/dmi-registry/cm-handles[@id='Bookstore4']/public-properties[@name='color']

{"name": "color", "value": ""}

5

/dmi-registry/cm-handles[@id='Bookstore3']/public-properties[@name='color']

{"name": "color", "value": "red"}

6

/dmi-registry/cm-handles[@id='Bookstore2']/public-properties[@name='Contact']

{"name": "Contact", "value": "newemailforstore2@bookstore.com"}

7

/dmi-registry/cm-handles[@id='Bookstore1']/public-properties[@name='Contact']

{"name": "Contact", "value": "newemailforstore@bookstore.com"}

8

/dmi-registry/cm-handles[@id='Bookstore6']/public-properties[@name='color']

{"name": "color", "value": "12345"}

9

/dmi-registry/cm-handles[@id='Bookstore7']/public-properties[@name='color']

{"name": "color", "value": "12345"}

10

/dmi-registry/cm-handles[@id='Bookstore8']/public-properties[@name='size']

{"name": "size", "value": "large"}

11

/dmi-registry/cm-handles[@id='Bookstore8']/public-properties[@name='color']

{"name": "color", "value": "red"}

 

Create CM Handles JSON
{ "dmiPlugin": "http://172.24.170.77:8783", "createdCmHandles": [ { "cmHandle": "Bookstore1", "publicCmHandleProperties": { "Contact": "newemailforstore@bookstore.com" } }, { "cmHandle": "Bookstore2", "publicCmHandleProperties": { "Contact": "newemailforstore2@bookstore.com" } }, { "cmHandle": "Bookstore3", "publicCmHandleProperties": { "color": "red" } }, { "cmHandle": "Bookstore4", "publicCmHandleProperties": { "color": "" } }, { "cmHandle": "Bookstore5", "publicCmHandleProperties": { "color": "won't match" } }, { "cmHandle": "Bookstore6", "publicCmHandleProperties": { "color": 12345 } }, { "cmHandle": "Bookstore7", "publicCmHandleProperties": { "color": "12345" } }, { "cmHandle": "Bookstore8", "publicCmHandleProperties": { "color": "red", "size": "large" } } ] }              

 

 

URL Used for all Requessts

http://localhost:8883/ncmp/v1/data/ch/searches

Results - Happy Path

Scenario

Request

Response

Notes/Decisions

Scenario

Request

Response

Notes/Decisions

1

Both properties match

(Return CM Handles that Match

{
    "publicCmHandleProperties": {
        "Contact""newemailforstore@bookstore.com"
    }
}

[
    "Bookstore1",
    "PNFDemo"
]

 

2

Multiple Entries - both properties match

(Return CM Handles that Match

{
    "publicCmHandleProperties": {
        "color" : "red",
        "size" : "large"
    }
}

[
    "Bookstore8"
]

 

3

No properties given

(Return All CM Handles which contain public properties

{

    "publicCmHandleProperties": {
    }
}

[
    "Bookstore4",
    "Bookstore5",
    "Bookstore6",
    "Bookstore7",
    "Bookstore1",
    "Bookstore2",
    "Bookstore3",
    "PNFDemo",
    "Bookstore8"
]

 

Results - Edge Cases

Scenario

Request

Response

Notes/Decisions

Scenario

Request

Response

Notes/Decisions

1

Value doesn't match 

(Return Empty Response

{
    "publicCmHandleProperties": {
        "Contact""wont match"
    }
}

[ ]

 

2

Unknown properties given

(Return Empty Response)

{
    "publicCmHandleProperties": {
        "UnknwnProperty""doesnt matter"
    }
}

[ ]

 

3

Empty value (valid)

(Return CM Handles Returned that Match

{

    "publicCmHandleProperties": {
        "color"""
    }
}

[
    "Bookstore4"
]

 

4

Empty property (invalid)

(BAD_REQUEST)

{

    "publicCmHandleProperties": {
        """doesnt matter "
    }
}

{
    "status""400 BAD_REQUEST",
    "message""Invalid data.",
    "details""Missing public property name - please supply a valid name."
}

 

5

Multiple entries with one empty property (invalid)

(BAD_REQUEST)

{
    "publicCmHandleProperties": {
        "color" : "",
        "" : "doesnt matter",
        "Contact""newemailforstore@bookstore.com"
    }
}

{
    "status""400 BAD_REQUEST",
    "message""Invalid data.",
    "details""Missing public property name - please supply a valid name."
}

 

6

6

 

 

 

 

7

7

Apostrophe in cm handle 

(Exception)

*** CPS can create a cm handle with a public property value that has an apostrophe but throws exception when queried ***

{
    "publicCmHandleProperties": {
        "color" : "won't match"
    }
}

{
    "status""500 INTERNAL_SERVER_ERROR",
    "message""Error while parsing cpsPath expression",
    "details""failed to parse at line 1 due to extraneous input 't' expecting {']', 'and'}"
}

Will handle this as and when it arises

8

8

CPS stores Integers as Strings.

Given the public properties below

{     "cmHandle": "Bookstore6",     publicCmHandleProperties": {         "color": 12345         } }, {     "cmHandle": "Bookstore7",     "publicCmHandleProperties": {         "color": "12345"         } }

 

When stored in CPS Integers are stored as Strings.

xpath

attributes

/dmi-registry/cm-handles[@id='Bookstore6']/public-properties[@name='color']

{"name": "color", "value": "12345"}

/dmi-registry/cm-handles[@id='Bookstore7']/public-properties[@name='color']

{"name": "color", "value": "12345"}

Therefore the two requests below return both cm handles regardless of wanting Integer or String.

{
    "publicCmHandleProperties": {
        "color" : "12345"
    }
}

 

{
    "publicCmHandleProperties": {
        "color"12345
    }
}

[
    "Bookstore6",
    "Bookstore7"
]

 

 

Future Example (Out-of-scope)


 

POST /ncmp/v1/data/ch/searches

{   "publicCmHandleProperties" : {      "publicPropertyName-1" : "publicPropertyValue-1",      "publicPropertyName-2" : "publicPropertyValue-2"    },   "modules": [     {            "moduleName": "", (Mandatory)            "revision": "" (Optional)         }   ] }

Modules in the example are to demonstrate future intentions but is out of scope for this user story.

References


 

CPS Swagger: http://localhost:8883/swagger-ui/index.html?configUrl=%2Fv3%2Fapi-docs%2Fswagger-config

https://docs.onap.org/projects/onap-cps/en/latest/cps-path.html

https://www.freeformatter.com/xpath-tester.html#ad-output

//public-properties[@name='Contact' and @value='xyz']/ancestor::cm-handles

org.onap.cps.spi.impl.CpsDataPersistenceQueryDataNodeSpec#Query for attribute by cps path of type ancestor with #scenario.