Versions Compared

Key

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

...

  1. Demo - with "and" behavior
  2. CI Test - two attributes


Issues/Decisions

...


IssueNotesDecision
1Does request body need to declare "publicCmHandleProperties"?

Do we need to

explcitly

explicitly declare "publicCmHandleProperties"? 

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

Code Block
languageyml
{
  "publicCmHandleProperties" : {
          "Name-1" : "some-value",
          "Name-2" : "other-value"
   }
}
Not another variation but there will be "modules" included in future implementations.2Do we need to consider if cm handle exists?3


Yes
2Are public properties always be in the format of "name" : x, "value": y?

In the fragment table there are example that follow this format 

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


Yes.


Image Modified

4
3Will there only ever be 1 kv pairs in public properties?
Yes
5
4Does the order matter?

Does

Code Block
languageyml
{
  "publicCmHandleProperties" : {
          "Name-1" : "some-value",
          "Name-2" : "other-value"
   }
}

==

Code Block
languageyml
{
  "publicCmHandleProperties" : {
          "Name-2" : "other-value",
          "Name-1" : "some-value"
   }
}


No
6
5Should search be case sensitive?depend on CPSPath functionality - may be case-sensitiveInvestigation Pending
6What format should the response take?

We have two options currently:

  1. Return List<String>
    1. ["cmHandle1",  "cmHandle2"]
  2. Return CM Handle Objects
    1. Already defined in CPS
    2. <Example Pending>

Contact Tony Finnerty & kieran mccarthy regarding this.



Analysis/Implementation Proposal

...

Possible High-Level Implementation Steps:

  1. Match all xpaths that contain "public"  in fragment table

...

languagesql

...

  1. 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

...

...

/**
     * Retrieve public properties for given cm handle.
     *
     * @param publicProperties the public properties to match
     * @return lit of cm handles that match
     */
    @Override
    public List<String> getCmHandlesForMatchingPublicProperties(final Map<String, String> publicProperties) {
        final String retrievePublicFragments =
            "SELECT xpath, attributes #>> '{}' AS attributes FROM fragment WHERE fragment.xpath LIKE '%public%';";

        final List<Object[]> resultsAsObjects =
            entityManager.createNativeQuery(retrievePublicFragments).getResultList();
        final Set<String> cmHandlesThatMatch = new TreeSet<>();
        final Set<String> allCmHandles = new TreeSet<>();

        for (final Object[] row : resultsAsObjects) {
            final String xpath = (String) row[0];
            final String attributes = (String) row[1];
            allCmHandles.add(getCmHandle(xpath));

            try {
                final String attributesAsJsonString = getAttributesAsJsonString(attributes);
                final JsonObject attributesAsJsonObject = new JsonParser().parse(attributesAsJsonString)
                    .getAsJsonObject();

                if (nameAndValueMatch(publicProperties, attributesAsJsonObject)) {
                    cmHandlesThatMatch.add(getCmHandle(xpath));
                }
            } catch (final JsonProcessingException jsonProcessingException) {
                jsonProcessingException.getMessage();
            }
        }

        if (publicProperties.get("name").isEmpty() && publicProperties.get("value").isEmpty()) {
            return List.copyOf(allCmHandles);
        }

        return List.copyOf(cmHandlesThatMatch);
    }

    private String getAttributesAsJsonString(final String attributes) throws JsonProcessingException {
        final ObjectMapper objectMapper = new ObjectMapper();
        String attributesAsJsonString = objectMapper.writeValueAsString(attributes);
        attributesAsJsonString = attributesAsJsonString.replace("\\", "");
        attributesAsJsonString = attributesAsJsonString.replaceFirst("\"", "");
        attributesAsJsonString = attributesAsJsonString.substring(0, attributesAsJsonString.length() - 1);
        return attributesAsJsonString;
    }

    private boolean nameAndValueMatch(final Map<String, String> publicProperties,
                                      final JsonObject attributesAsJsonObject) {
        return attributesAsJsonObject.get("value").getAsString().equals(publicProperties.get("value"))
            && attributesAsJsonObject.get("name").getAsString().equals(publicProperties.get("name"));
    }

    private String getCmHandle(final String xpath) {
        if (xpath.indexOf("\'") > - 1) {
            return xpath.substring(xpath.indexOf("\'") + 1, xpath.indexOf("]") - 1);
        }

        return xpath.substring(xpath.indexOf("\"") + 1, xpath.indexOf("]") - 1);
    }

Interface Proposal

#URIDesign NotesComment(s)
1POST /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

Code Block
languageyml
{
  "publicCmHandleProperties" : {
     "Name-1" : "some-value",
     "Name-2" : "other-value"
   }
}


Code Block
languageyml
{
  "publicCmHandleProperties": {
    "name": "Contact",
    "value": "newemailforstore@bookstore.com"
  }
}


Response Body

Code Block
languageyml
[
	"cmHandle1",
	"cmHandle2",
	...,
	"cmHandleN"
]




Below is a sample yaml for OpenAPI.

...

A PoC has been coded and can be found here: https://gerrit.onap.org/r/c/cps/+/127541



#ScenarioScreenshot
1

Both properties match

(CM Handles Returned that Match)

Image Modified

2

One property doesn't match 

(Nothing Returned)

Image Modified

3

No properties given - all cm handles returned

(that contain public properties)

Image Modified

4

Return 400

(BAD_REQUEST)

Image Modified



Testing

...


Edge Cases

  • Null name, Value
  • Empty name, Value

Future Example (Out-of-scope)

...