You are viewing an old version of this page. View the current version.
Compare with Current
View Page History
« Previous
Version 30
Next »
CPS-731
-
Getting issue details...
STATUS
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.
- 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:
- Demo - with "and" behavior
- CI Test - two attributes
Issues/Decisions
| Issue | Notes | Decision |
---|
1 | Does request body need to declare "publicCmHandleProperties"? | Do we need to explcitly declare "publicCmHandleProperties"? Will there be another possible variation to this in the future?
{
"publicCmHandleProperties" : {
"Name-1" : "some-value",
"Name-2" : "other-value"
}
}
| Not another variation but there will be "modules" included in future implementations. |
2 | Do we need to consider if cm handle exists? |
|
|
3 | Are public properties always be in the format of "name" : x, "value": y? | In the fragment table there are example that follow this format
{
"name": "Contact",
"value": "newemailforstore@bookstore.com"
}
| Yes.
![](/download/attachments/128090286/image2022-3-3_15-45-13.png?version=1&modificationDate=1646322313000&api=v2)
|
4 | Will there only ever be 2 kv pairs in public properties? |
| Yes |
5 | Does the order matter? | Does
{
"publicCmHandleProperties" : {
"Name-1" : "some-value",
"Name-2" : "other-value"
}
}
==
{
"publicCmHandleProperties" : {
"Name-2" : "other-value",
"Name-1" : "some-value"
}
}
| No, they are independent but they however will need to in this order in the database. |
6 | Should search be case sensitive? |
|
|
Analysis/Implementation Proposal
High level Jiras:
-
CPS-901
-
Getting issue details...
STATUS
-
CPS-902
-
Getting issue details...
STATUS
-
CPS-903
-
Getting issue details...
STATUS
-
CPS-904
-
Getting issue details...
STATUS
Possible High-Level Implementation Steps:
Match all xpaths that contain "public" in fragment table
SELECT xpath, attributes #>> '{}' AS attributes
FROM fragment
WHERE fragment.xpath LIKE '%public%'
Iterate over the list and retrieve all attributes
- Iterate over the attributes and collect those instances that match
- 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
# | 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" : {
"Name-1" : "some-value",
"Name-2" : "other-value"
}
}
{
"publicCmHandleProperties": {
"name": "Contact",
"value": "newemailforstore@bookstore.com"
}
}
Response Body
[
"cmHandle1",
"cmHandle2",
...,
"cmHandleN"
]
|
|
Below is a sample yaml for OpenAPI.
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'
Public Properties are stored in the fragment table in CPS as seen below:
![](/download/attachments/128090286/image2022-3-2_17-55-20.png?version=1&modificationDate=1646243722000&api=v2)
PoC Gerrit Review
A PoC has been coded and can be found here: https://gerrit.onap.org/r/c/cps/+/127541
![](/download/attachments/128090286/image2022-3-8_11-37-6.png?version=1&modificationDate=1646739427000&api=v2)
# | Scenario | Screenshot |
---|
1 | Both properties match (CM Handles Returned that Match) | |
2 | One property doesn't match (Nothing Returned) | |
3 | No properties given - all cm handles returned (that contain public properties) | |
4 | Return 400 (BAD_REQUEST) | |
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