aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorBruno Sakoto <bruno.sakoto@bell.ca>2021-10-07 09:11:48 -0400
committerRenu Kumari <renu.kumari@bell.ca>2021-10-12 12:52:44 -0400
commita43a13b39050de41fd24e11d16a3a280af088527 (patch)
treeac9ab11b8f864c435256faa5371485eea6095817
parent3c8fbebbe03798d5747fc02f1eda96d7fa5f1056 (diff)
Finalize design and modeling documentation
Issue-ID: CPS-447 Signed-off-by: Bruno Sakoto <bruno.sakoto@bell.ca> Change-Id: I58181dd7018319c46d465c78b8299c3f316f455e
-rw-r--r--docs/_static/event-schema/cps-data-updated-event-schema-v1.json87
-rw-r--r--docs/_static/openapi/swagger/openapi.yml255
-rw-r--r--docs/_static/postman-collections/cps-temporal-postman-collection.json288
-rw-r--r--docs/content/design.rst36
-rw-r--r--docs/content/modeling.rst32
5 files changed, 691 insertions, 7 deletions
diff --git a/docs/_static/event-schema/cps-data-updated-event-schema-v1.json b/docs/_static/event-schema/cps-data-updated-event-schema-v1.json
new file mode 100644
index 0000000..2057955
--- /dev/null
+++ b/docs/_static/event-schema/cps-data-updated-event-schema-v1.json
@@ -0,0 +1,87 @@
+{
+
+ "$schema": "https://json-schema.org/draft/2019-09/schema",
+ "$id": "urn:cps:org.onap.cps:data-updated-event-schema:v1",
+
+ "$ref": "#/definitions/CpsDataUpdatedEvent",
+
+ "definitions": {
+
+ "CpsDataUpdatedEvent": {
+ "description": "The payload for CPS data updated event.",
+ "type": "object",
+ "properties": {
+ "schema": {
+ "description": "The schema, including its version, that this event adheres to. E.g. 'urn:cps:org.onap.cps:data-updated-event-schema:v99'.",
+ "type": "string",
+ "format": "uri"
+ },
+ "id": {
+ "description": "The unique id identifying the event for the specified source. Producer must ensure that source + id is unique for each distinct event.",
+ "type": "string"
+ },
+ "source": {
+ "description": "The source of the event. Producer must ensure that source + id is unique for each distinct event.",
+ "type": "string",
+ "format": "uri"
+ },
+ "type": {
+ "description": "The type of the event.",
+ "type": "string"
+ },
+ "content": {
+ "$ref": "#/definitions/Content"
+ }
+ },
+ "required": [
+ "schema",
+ "id",
+ "source",
+ "type",
+ "content"
+ ],
+ "additionalProperties": false
+ },
+
+ "Content": {
+ "description": "The event content.",
+ "type": "object",
+ "properties": {
+ "observedTimestamp": {
+ "description": "The timestamp when the data has been observed. The expected format is 'yyyy-MM-dd'T'HH:mm:ss.SSSZ'. Ex: '2020-12-01T00:00:00.000+0000' ",
+ "type": "string"
+ },
+ "dataspaceName": {
+ "description": "The name of CPS Core dataspace the data belongs to.",
+ "type": "string"
+ },
+ "schemaSetName": {
+ "description": "The name of CPS Core schema set the data adheres to.",
+ "type": "string"
+ },
+ "anchorName": {
+ "description": "The name of CPS Core anchor the data is attached to.",
+ "type": "string"
+ },
+ "data": {
+ "$ref": "#/definitions/Data"
+ }
+ },
+ "required": [
+ "observedTimestamp",
+ "dataspaceName",
+ "schemaSetName",
+ "anchorName",
+ "data"
+ ],
+ "additionalProperties": false
+ },
+
+ "Data": {
+ "description": "Data as json object.",
+ "type": "object"
+ }
+
+ }
+
+} \ No newline at end of file
diff --git a/docs/_static/openapi/swagger/openapi.yml b/docs/_static/openapi/swagger/openapi.yml
new file mode 100644
index 0000000..991d807
--- /dev/null
+++ b/docs/_static/openapi/swagger/openapi.yml
@@ -0,0 +1,255 @@
+# ============LICENSE_START=======================================================
+# Copyright (c) 2021 Bell Canada.
+# ================================================================================
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
+# SPDX-License-Identifier: Apache-2.0
+# ============LICENSE_END=========================================================
+
+openapi: 3.0.1
+info:
+ title: ONAP Open API v3 Configuration Persistence Service - Temporal
+ description: CPS-Temporal is time-series database for network data
+ version: 1.0.0
+ contact:
+ name: ONAP
+ url: 'https://onap.readthedocs.io'
+ email: onap-discuss@lists.onap.org
+ license:
+ name: Apache 2.0
+ url: 'http://www.apache.org/licenses/LICENSE-2.0'
+ x-planned-retirement-date: '202212'
+ x-component: Modeling
+servers:
+ - url: '/cps-temporal/api'
+tags:
+ - name: cps-temporal-query
+ description: CPS Temporal Query
+paths:
+ '/v1/dataspaces/{dataspace-name}/anchors/{anchor-name}/history':
+ get:
+ description: 'Read the data for the specified anchor based on filter criteria provided in query parameters'
+ tags:
+ - cps-temporal-query
+ summary: Get anchor data by name
+ operationId: getAnchorDataByName
+ parameters:
+ - $ref: '#/components/parameters/dataspaceName'
+ - name: anchor-name
+ in: path
+ description: Anchor Name
+ required: true
+ schema:
+ type: string
+ - $ref: '#/components/parameters/observedTimestampAfter'
+ - $ref: '#/components/parameters/simplePayloadFilter'
+ - $ref: '#/components/parameters/pointInTime'
+ - $ref: '#/components/parameters/pageNumber'
+ - $ref: '#/components/parameters/pageLimit'
+ - $ref: '#/components/parameters/sort'
+ responses:
+ '200':
+ description: OK
+ content:
+ application/json:
+ schema:
+ $ref: '#/components/schemas/AnchorHistory'
+ example:
+ nextRecordsLink: /v1/dataspace/my-dataspace/anchors/my-anchor/history?pageLimit=20&pageNumber=2
+ previousRecordsLink: /v1/dataspace/my-dataspace/anchors/my-anchor/history?pageLimit=20&pageNumber=0
+ records:
+ - timestamp: '2021-03-21T00:00:00.000-0000'
+ dataspace: my-dataspace
+ schemaSet: my-schema-set
+ anchor: my-anchor
+ data:
+ status: UP
+
+
+ '400':
+ $ref: '#/components/responses/BadRequest'
+ '401':
+ $ref: '#/components/responses/Unauthorized'
+ '403':
+ $ref: '#/components/responses/Forbidden'
+ '/v1/dataspaces/{dataspace-name}/anchors/history':
+ get:
+ description: 'Read anchors data based on filter criteria provided in query parameters'
+ tags:
+ - cps-temporal-query
+ summary: Get anchors data based on filter criteria
+ operationId: getAnchorsDataByFilter
+ parameters:
+ - $ref: '#/components/parameters/dataspaceName'
+ - name: schema-set-name
+ in: query
+ description: Schema-set name
+ required: true
+ schema:
+ type: string
+ - $ref: '#/components/parameters/observedTimestampAfter'
+ - $ref: '#/components/parameters/simplePayloadFilter'
+ - $ref: '#/components/parameters/pointInTime'
+ - $ref: '#/components/parameters/pageNumber'
+ - $ref: '#/components/parameters/pageLimit'
+ - $ref: '#/components/parameters/sort'
+ responses:
+ '200':
+ description: OK
+ content:
+ application/json:
+ schema:
+ $ref: '#/components/schemas/AnchorHistory'
+ example:
+ nextRecordsLink: /v1/dataspace/my-dataspace/anchors/history?pageLimit=20&pageNumber=2
+ previousRecordsLink: /v1/dataspace/my-dataspace/anchors/history?pageLimit=20&pageNumber=0
+ records:
+ - timestamp: '2021-03-21T00:00:00.000-0000'
+ dataspace: my-dataspace
+ schemaSet: my-schema-set
+ anchor: my-anchor
+ data:
+ status: UP
+
+ '400':
+ $ref: '#/components/responses/BadRequest'
+ '401':
+ $ref: '#/components/responses/Unauthorized'
+ '403':
+ $ref: '#/components/responses/Forbidden'
+components:
+ parameters:
+ dataspaceName:
+ name: dataspace-name
+ in: path
+ description: Dataspace Name
+ required: true
+ schema:
+ type: string
+ observedTimestampAfter:
+ name: observedTimestampAfter
+ in: query
+ description: Fetch data with observed timestamp after <br/> Format - 'yyyy-MM-ddTHH:mm:ss.SSSZ'
+ required: false
+ schema:
+ type: string
+ example: '2021-03-21T00:00:00.000-0000'
+ simplePayloadFilter:
+ name: simplePayloadFilter
+ in: query
+ description: Payload filter
+ required: false
+ schema:
+ type: string
+ pointInTime:
+ name: pointInTime
+ in: query
+ description: Consider data modified before <br/> Format - 'yyyy-MM-ddTHH:mm:ss.SSSZ'
+ required: false
+ schema:
+ type: string
+ example: '2021-03-21T00:00:00.000-0000'
+ pageLimit:
+ in: query
+ name: pageLimit
+ required: false
+ schema:
+ type: integer
+ minimum: 0
+ default: 1000
+ description: The numbers of items to return
+ pageNumber:
+ name: pageNumber
+ in: query
+ description: Page number
+ required: false
+ schema:
+ type: integer
+ minimum: 0
+ default: 0
+ sort:
+ in: query
+ name: sort
+ required: false
+ schema:
+ type: string
+ default: observed_timestamp:desc
+ description: "Sort by timestamp in 'asc' or 'desc' order. Supported values: <br/>observed_timestamp:desc<br/>anchor:asc,observed_timestamp:desc"
+ responses:
+ BadRequest:
+ description: Bad Request
+ content:
+ application/json:
+ schema:
+ $ref: '#/components/schemas/ErrorMessage'
+ Unauthorized:
+ description: Unauthorized
+ content:
+ application/json:
+ schema:
+ $ref: '#/components/schemas/ErrorMessage'
+ Forbidden:
+ description: Forbidden
+ content:
+ application/json:
+ schema:
+ $ref: '#/components/schemas/ErrorMessage'
+ schemas:
+ AnchorDetails:
+ type: object
+ title: AnchorDetails
+ properties:
+ observedTimestamp:
+ type: string
+ example: '2021-03-21T00:00:00.000-0000'
+ dataspace:
+ type: string
+ example: 'my-dataspace'
+ schemaSet:
+ type: string
+ example: 'my-schema-set'
+ anchor:
+ type: string
+ example: 'my-anchor'
+ data:
+ type: object
+ example: { "status" : "UP" }
+ AnchorHistory:
+ type: object
+ title: AnchorHistory
+ properties:
+ nextRecordsLink:
+ type: string
+ example: /v1/dataspace/dataspace-name/anchors/history?pageLimit=20&pageNumber=2
+ previousRecordsLink:
+ type: string
+ example: /v1/dataspace/dataspace-name/anchors/history?pageLimit=20&pageNumber=0
+ records:
+ type: array
+ items:
+ $ref: '#/components/schemas/AnchorDetails'
+ required:
+ - records
+ ErrorMessage:
+ type: object
+ title: Error
+ properties:
+ status:
+ type: string
+ example: 400
+ message:
+ type: string
+ example: Data could not be fetched
+ details:
+ type: string
+ example: "after parameter should have datetime value in ISO format yyyy-MM-ddTHH:mm:ss.SSSZ"
diff --git a/docs/_static/postman-collections/cps-temporal-postman-collection.json b/docs/_static/postman-collections/cps-temporal-postman-collection.json
new file mode 100644
index 0000000..cd23d16
--- /dev/null
+++ b/docs/_static/postman-collections/cps-temporal-postman-collection.json
@@ -0,0 +1,288 @@
+{
+ "info": {
+ "_postman_id": "9ef134f9-0f80-4a1c-92af-51da658c228b",
+ "name": "CPS Temporal",
+ "schema": "https://schema.getpostman.com/json/collection/v2.1.0/collection.json"
+ },
+ "item": [
+ {
+ "name": "Actuator",
+ "item": [
+ {
+ "name": "Get Health",
+ "protocolProfileBehavior": {
+ "disableCookies": true
+ },
+ "request": {
+ "auth": {
+ "type": "noauth"
+ },
+ "method": "GET",
+ "header": [],
+ "url": {
+ "raw": "{{protocol}}://{{temporal-host}}:{{temporal-management-port}}/manage/health",
+ "protocol": "{{protocol}}",
+ "host": [
+ "{{temporal-host}}"
+ ],
+ "port": "{{temporal-management-port}}",
+ "path": [
+ "manage",
+ "health"
+ ]
+ }
+ },
+ "response": []
+ },
+ {
+ "name": "Get Metrics",
+ "protocolProfileBehavior": {
+ "disableCookies": true
+ },
+ "request": {
+ "auth": {
+ "type": "noauth"
+ },
+ "method": "GET",
+ "header": [],
+ "url": {
+ "raw": "{{protocol}}://{{temporal-host}}:{{temporal-management-port}}/manage/prometheus",
+ "protocol": "{{protocol}}",
+ "host": [
+ "{{temporal-host}}"
+ ],
+ "port": "{{temporal-management-port}}",
+ "path": [
+ "manage",
+ "prometheus"
+ ]
+ }
+ },
+ "response": []
+ },
+ {
+ "name": "Get Info",
+ "protocolProfileBehavior": {
+ "disableCookies": true
+ },
+ "request": {
+ "auth": {
+ "type": "noauth"
+ },
+ "method": "GET",
+ "header": [],
+ "url": {
+ "raw": "{{protocol}}://{{temporal-host}}:{{temporal-management-port}}/manage/info",
+ "protocol": "{{protocol}}",
+ "host": [
+ "{{temporal-host}}"
+ ],
+ "port": "{{temporal-management-port}}",
+ "path": [
+ "manage",
+ "info"
+ ]
+ }
+ },
+ "response": []
+ }
+ ]
+ },
+ {
+ "name": "Specifications",
+ "item": [
+ {
+ "name": "Swagger UI",
+ "request": {
+ "method": "GET",
+ "header": [],
+ "url": {
+ "raw": "{{protocol}}://{{temporal-host}}:{{temporal-port}}/swagger-ui.html",
+ "protocol": "{{protocol}}",
+ "host": [
+ "{{temporal-host}}"
+ ],
+ "port": "{{temporal-port}}",
+ "path": [
+ "swagger-ui.html"
+ ]
+ }
+ },
+ "response": []
+ },
+ {
+ "name": "Open API",
+ "request": {
+ "auth": {
+ "type": "noauth"
+ },
+ "method": "GET",
+ "header": [],
+ "url": {
+ "raw": "{{protocol}}://{{temporal-host}}:{{temporal-port}}/swagger/openapi.yml",
+ "protocol": "{{protocol}}",
+ "host": [
+ "{{temporal-host}}"
+ ],
+ "port": "{{temporal-port}}",
+ "path": [
+ "swagger",
+ "openapi.yml"
+ ]
+ }
+ },
+ "response": []
+ }
+ ]
+ },
+ {
+ "name": "Data",
+ "item": [
+ {
+ "name": "Get Anchor Data",
+ "request": {
+ "method": "GET",
+ "header": [],
+ "url": {
+ "raw": "{{protocol}}://{{temporal-host}}:{{temporal-port}}/cps-temporal/api/v1/dataspaces/{{dataspace-name}}/anchors/{{anchor-name}}/history",
+ "protocol": "{{protocol}}",
+ "host": [
+ "{{temporal-host}}"
+ ],
+ "port": "{{temporal-port}}",
+ "path": [
+ "cps-temporal",
+ "api",
+ "v1",
+ "dataspaces",
+ "{{dataspace-name}}",
+ "anchors",
+ "{{anchor-name}}",
+ "history"
+ ],
+ "query": [
+ {
+ "key": "sort",
+ "value": "observed_timestamp:desc,anchor:asc",
+ "disabled": true
+ },
+ {
+ "key": "observedTimestampAfter",
+ "value": "2021-08-01T00:00:00.000-0000",
+ "disabled": true
+ },
+ {
+ "key": "pointInTime",
+ "value": "2021-08-17T14:35:00.000-0400",
+ "disabled": true
+ },
+ {
+ "key": "pageNumber",
+ "value": "0",
+ "disabled": true
+ },
+ {
+ "key": "pageLimit",
+ "value": "1",
+ "disabled": true
+ }
+ ]
+ }
+ },
+ "response": []
+ },
+ {
+ "name": "Get Schema Set Data",
+ "request": {
+ "method": "GET",
+ "header": [],
+ "url": {
+ "raw": "{{protocol}}://{{temporal-host}}:{{temporal-port}}/cps-temporal/api/v1/dataspaces/{{dataspace-name}}/anchors/history?schema-set-name={{schema-set-name}}",
+ "protocol": "{{protocol}}",
+ "host": [
+ "{{temporal-host}}"
+ ],
+ "port": "{{temporal-port}}",
+ "path": [
+ "cps-temporal",
+ "api",
+ "v1",
+ "dataspaces",
+ "{{dataspace-name}}",
+ "anchors",
+ "history"
+ ],
+ "query": [
+ {
+ "key": "schema-set-name",
+ "value": "{{schema-set-name}}"
+ },
+ {
+ "key": "sort",
+ "value": "observed_timestamp:desc,anchor:asc",
+ "disabled": true
+ },
+ {
+ "key": "observedTimestampAfter",
+ "value": "2021-08-01T00:00:00.000%2B0100",
+ "disabled": true
+ },
+ {
+ "key": "pointInTime",
+ "value": "2021-08-17T14:35:00.000-0400",
+ "disabled": true
+ },
+ {
+ "key": "pageNumber",
+ "value": "0",
+ "disabled": true
+ },
+ {
+ "key": "pageLimit",
+ "value": "1",
+ "disabled": true
+ }
+ ]
+ }
+ },
+ "response": []
+ }
+ ]
+ }
+ ],
+ "auth": {
+ "type": "basic",
+ "basic": [
+ {
+ "key": "password",
+ "value": "{{temporal-password}}",
+ "type": "string"
+ },
+ {
+ "key": "username",
+ "value": "{{temporal-username}}",
+ "type": "string"
+ }
+ ]
+ },
+ "event": [
+ {
+ "listen": "prerequest",
+ "script": {
+ "type": "text/javascript",
+ "exec": [
+ ""
+ ]
+ }
+ },
+ {
+ "listen": "test",
+ "script": {
+ "type": "text/javascript",
+ "exec": [
+ ""
+ ]
+ }
+ }
+ ]
+} \ No newline at end of file
diff --git a/docs/content/design.rst b/docs/content/design.rst
index 7a6590d..c414e6d 100644
--- a/docs/content/design.rst
+++ b/docs/content/design.rst
@@ -8,13 +8,37 @@
CPS Temporal Design
===================
-.. warning:: Draft
+Exposed APIs
+============
-* REST API
+CPS Temporal is providing a REST HTTP API to query historical CPS data.
+Its OPEN API Specification can be found either:
- * Specification
- * Postman Collection
+* In :download:`openapi.yml <../_static/openapi/swagger/openapi.yml>`
+ file
+* At ``https://<cps-temporal-host>:<cps-temporal-port>/swagger/openapi.yml``
+ endpoint available on CPS Temporal running instance
-* Event Schema
+Swagger UI is also available at:
- * Json Schema
+* ``https://<cps-temporal-host>:<cps-temporal-port>/swagger-ui.html``
+
+And following Postman collection can be used to send requests to any running
+instance:
+
+* :download:`CPS Temporal Postman Collection <../_static/postman-collections/cps-temporal-postman-collection.json>`
+
+Event Integration
+=================
+
+CPS Core and CPS Temporal are integrated with an event driven architecture.
+Integration between these two components is event notification based.
+
+For each data modification handled by CPS Core,
+
+* CPS Core is publishing, to a dedicated Kafka topic, an event representing
+ the data configuration or state.
+* CPS Temporal is listening to the same topic for the event and is responsible
+ to keep track of all data over time.
+
+Refer to :doc:`modeling` for more details on the event structure.
diff --git a/docs/content/modeling.rst b/docs/content/modeling.rst
index b8bf91e..8871a81 100644
--- a/docs/content/modeling.rst
+++ b/docs/content/modeling.rst
@@ -8,4 +8,34 @@
CPS Temporal Modeling
=====================
-.. warning:: Draft
+Event Structure
+===============
+
+Data manipulated by both CPS Core and CPS Temporal to represent a Data Updated
+Event is a JSON structure that is defined by following Json Schema:
+
+* :download:`cps-data-updated-event-schema.json <../_static/event-schema/cps-data-updated-event-schema-v1.json>`
+
+And following is an example of an event compliant with this schema:
+
+.. code:: json
+
+ {
+ "schema": "urn:cps:org.onap.cps:data-updated-event-schema:v1",
+ "id": "38aa6cc6-264d-4ede-b534-18f5c1f403ea",
+ "source": "urn:cps:org.onap.cps",
+ "type": "org.onap.cps.data-updated-event",
+ "content": {
+ "observedTimestamp": "2021-06-09T13:00:00.123-0400",
+ "dataspaceName": "my-dataspace",
+ "schemaSetName": "my-schema-set",
+ "anchorName": "my-anchor",
+ "data": {
+ "interface": {
+ "name": "itf-1",
+ "status": "up"
+ }
+ }
+ }
+ }
+