aboutsummaryrefslogtreecommitdiffstats
path: root/docs/development/actors
diff options
context:
space:
mode:
Diffstat (limited to 'docs/development/actors')
-rw-r--r--docs/development/actors/aai/aai.rst150
-rw-r--r--docs/development/actors/aai/classHierarchy.pngbin0 -> 38398 bytes
-rw-r--r--docs/development/actors/aai/classHierarchy.pptxbin0 -> 36745 bytes
-rw-r--r--docs/development/actors/actors.rst13
-rw-r--r--docs/development/actors/appc-legacy/appc-legacy.rst195
-rw-r--r--docs/development/actors/appclcm/appclcm.rst227
-rw-r--r--docs/development/actors/guard/guard.rst128
-rw-r--r--docs/development/actors/overview.rst197
-rw-r--r--docs/development/actors/sdnc/sdnc.rst165
-rw-r--r--docs/development/actors/sdnr/sdnr.rst193
-rw-r--r--docs/development/actors/so/so.rst452
-rw-r--r--docs/development/actors/topview.pngbin0 -> 57667 bytes
-rw-r--r--docs/development/actors/topview.pptxbin0 -> 39894 bytes
-rw-r--r--docs/development/actors/vfc/vfc.rst169
14 files changed, 1887 insertions, 2 deletions
diff --git a/docs/development/actors/aai/aai.rst b/docs/development/actors/aai/aai.rst
new file mode 100644
index 00000000..a418f440
--- /dev/null
+++ b/docs/development/actors/aai/aai.rst
@@ -0,0 +1,150 @@
+.. This work is licensed under a
+.. Creative Commons Attribution 4.0 International License.
+.. http://creativecommons.org/licenses/by/4.0
+
+.. _aai-label:
+
+##########
+A&AI Actor
+##########
+
+.. contents::
+ :depth: 3
+
+Overview of A&AI Actor
+######################
+ONAP Policy Framework enables various actors, several of which require additional
+data to be gathered from A&AI via a REST call. Previously, the request was built,
+and the REST call made, by the application. However, A&AI queries have now been
+implemented using the new Actor framework.
+
+Each operation supported by the actor is associated with its own java class, which is
+responsible for populating the request structure and invoking the REST service. The
+class hierarchy is shown below.
+
+.. image:: classHierarchy.png
+
+Currently, the following operations are supported:
+
+- Tenant
+- Pnf
+- CustomQuery
+
+One thing that sets the A&AI Actor implementation apart from the other Actor
+implementations is that it is typically used to gather data for input to the
+other actors. Consequently, when an A&AI operation completes, it places its
+response into the *properties* field of the *context*, which is passed via the
+*ControlLoopOperationParams*. The names of the keys within the *properties*
+field are typically of the form, "AAI.<operation>.<targetEntity>", where
+"operation" is the name of the operation, and "targetEntity" is the *targetEntity*
+passed via the *ControlLoopOperationParams*. For example, the response for
+the Tenant query for a target entity named "ozVserver" would be stored as a
+*properties* named "AAI.Tenant.ozVserver".
+
+On the other hand, as there is only one "custom query" for a given ONSET, the
+*Custom Query* operation deviates from this, in that it always stores its response
+using the key, "AAI.AaiCqResponse".
+
+
+Request
+#######
+
+Most of the the A&AI operations use "GET" requests and thus do not populate
+a request structure. However, for those that do, the request structure is
+described in the table below.
+
+Note: the Custom Query Operation requires tenant data, thus it performs a *Tenant*
+operation before sending its request. The tenant data is gathered for the vserver
+whose name is found in the "vserver.vserver-name" field of the enrichment data provided
+by DCAE with the ONSET event.
+
++----------------------------------+---------+----------------------------------------------------------------------+
+| Field Name | Type | Description |
++----------------------------------+---------+----------------------------------------------------------------------+
++----------------------------------+---------+----------------------------------------------------------------------+
+| Custom Query: | | |
++----------------------------------+---------+----------------------------------------------------------------------+
+| *start* | string | Extracted from the *result-data[0].resource-link* field of the |
+| | | Tenant query response. |
++----------------------------------+---------+----------------------------------------------------------------------+
+
+
+Examples
+########
+
+Suppose the *ControlLoopOperationParams* were populated as follows, with the tenant
+query having already been performed:
+
+.. code-block:: bash
+
+ {
+ "actor": "AAI",
+ "operation": "CustomQuery",
+ "context": {
+ "enrichment": {
+ "vserver.vserver-name": "Ete_vFWCLvFWSNK_7ba1fbde_0"
+ },
+ "properties": {
+ "AAI.Tenant.Ete_vFWCLvFWSNK_7ba1fbde_0": {
+ "result-data": [
+ {
+ "resource-type": "vserver",
+ "resource-link": "/aai/v15/cloud-infrastructure/cloud-regions/cloud-region/CloudOwner/RegionOne/tenants/tenant/3f2aaef74ecb4b19b35e26d0849fe9a2/vservers/vserver/6c3b3714-e36c-45af-9f16-7d3a73d99497"
+ }
+ ]
+ }
+ }
+ }
+ }
+
+An example of a Custom Query request constructed by the actor using the above
+parameters, sent to the A&AI REST server:
+
+.. code-block:: bash
+
+ {
+ "start": "/aai/v15/cloud-infrastructure/cloud-regions/cloud-region/CloudOwner/RegionOne/tenants/tenant/3f2aaef74ecb4b19b35e26d0849fe9a2/vservers/vserver/6c3b3714-e36c-45af-9f16-7d3a73d99497",
+ "query": "query/closed-loop"
+ }
+
+
+An example response received from the A&AI REST service:
+
+.. code-block:: bash
+
+ {
+ "results": [
+ {
+ "vserver": {
+ "vserver-id": "f953c499-4b1e-426b-8c6d-e9e9f1fc730f",
+ "vserver-name": "Ete_vFWCLvFWSNK_7ba1fbde_0",
+ "vserver-name2": "Ete_vFWCLvFWSNK_7ba1fbde_0",
+ "prov-status": "ACTIVE",
+ "vserver-selflink": "http://10.12.25.2:8774/v2.1/41d6d38489bd40b09ea8a6b6b852dcbd/servers/f953c499-4b1e-426b-8c6d-e9e9f1fc730f",
+ "in-maint": false,
+ "is-closed-loop-disabled": false,
+ ...
+ }
+
+
+Configuration of the A&AI Actor
+###############################
+
+The following table specifies the fields that should be provided to configure the A&AI
+actor.
+
+=============================== ==================== ==================================================================
+Field name type Description
+=============================== ==================== ==================================================================
+clientName string Name of the HTTP client to use to send the request to the
+ A&AI REST server.
+timeoutSec integer (optional) Maximum time, in seconds, to wait for a response to be received
+ from the REST server. Defaults to 90s.
+path string URI appended to the URL. This field only applies to individual
+ operations; it does not apply at the actor level. Note: the
+ *path* should not include a leading or trailing slash.
+=============================== ==================== ==================================================================
+
+The individual operations are configured using these same field names. However, all
+of them, except the *path*, are optional, as they inherit their values from the
+corresponding actor-level fields.
diff --git a/docs/development/actors/aai/classHierarchy.png b/docs/development/actors/aai/classHierarchy.png
new file mode 100644
index 00000000..162b1da3
--- /dev/null
+++ b/docs/development/actors/aai/classHierarchy.png
Binary files differ
diff --git a/docs/development/actors/aai/classHierarchy.pptx b/docs/development/actors/aai/classHierarchy.pptx
new file mode 100644
index 00000000..e320c49a
--- /dev/null
+++ b/docs/development/actors/aai/classHierarchy.pptx
Binary files differ
diff --git a/docs/development/actors/actors.rst b/docs/development/actors/actors.rst
index 7005489c..77210883 100644
--- a/docs/development/actors/actors.rst
+++ b/docs/development/actors/actors.rst
@@ -6,6 +6,15 @@ Policy Platform Actor Development Guidelines
--------------------------------------------
.. toctree::
- :maxdepth: 1
+ :maxdepth: 1
- cds/cds.rst
+ overview.rst
+ aai/aai.rst
+ appc-legacy/appc-legacy.rst
+ appclcm/appclcm.rst
+ cds/cds.rst
+ guard/guard.rst
+ sdnc/sdnc.rst
+ sdnr/sdnr.rst
+ so/so.rst
+ vfc/vfc.rst
diff --git a/docs/development/actors/appc-legacy/appc-legacy.rst b/docs/development/actors/appc-legacy/appc-legacy.rst
new file mode 100644
index 00000000..5d1bd7c0
--- /dev/null
+++ b/docs/development/actors/appc-legacy/appc-legacy.rst
@@ -0,0 +1,195 @@
+.. This work is licensed under a
+.. Creative Commons Attribution 4.0 International License.
+.. http://creativecommons.org/licenses/by/4.0
+
+.. _appc-legacy-label:
+
+#################
+APPC Legacy Actor
+#################
+
+.. contents::
+ :depth: 3
+
+Overview of APPC Legacy Actor
+#############################
+ONAP Policy Framework enables APPC Legacy as one of the supported actors.
+APPC Legacy uses a single DMaaP topic for both requests and responses. As a result, the
+actor implementation must cope with the fact that requests may appear on the same
+stream from which it is reading responses, thus it must use the message content to
+distinguish responses from requests. This particular implementation uses the *Status*
+field to identify responses.
+
+In addition, APPC may generate more than one response for a particular request, the
+first response simply indicating that the request was accepted, while the second
+response indicates completion of the request. For each request, a unique sub-request
+ID is generated. This is used to match the received responses with the published
+requests.
+
+Each operation supported by the actor is associated with its own java class, which is
+responsible for populating the request structure appropriately. The operation-specific
+classes are all derived from the *AppcOperation* class, which is, itself, derived from
+*BidirectionalTopicOperation*.
+
+
+Request
+#######
+
+CommonHeader
+************
+
+The "CommonHeader" field in the request is built by policy.
+
+=============================== =========== ==================================================================
+ "CommonHeader" field name type Description
+=============================== =========== ==================================================================
+SubRequestID string Generated by Policy. Is a UUID and used internally by policy
+ to match the response with the request.
+RequestID string Inserted by Policy. Maps to the UUID sent by DCAE i.e. the ID
+ used throughout the closed loop lifecycle to identify a request.
+=============================== =========== ==================================================================
+
+Action
+******
+
+The "Action" field uniquely identifies the operation to perform. Currently, only
+"ModifyConfig" is supported.
+
+Payload
+*******
+
+=============================== =========== ==================================================================
+ "Payload" field name type Description
+=============================== =========== ==================================================================
+generic-vnf.vnf-id string The ID of the VNF selected from the A&AI Custom Query response
+ using the Target resource ID specified in the
+ *ControlLoopOperationParams*.
+=============================== =========== ==================================================================
+
+Additional fields are populated based on the *payload* specified within the
+*ControlLoopOperationParams*. Each value found within the *payload* is treated as a
+JSON string and is decoded into a POJO, which is then inserted into the request payload
+using the same key.
+
+
+Examples
+########
+
+Suppose the *ControlLoopOperationParams* were populated as follows:
+
+.. code-block:: bash
+
+ {
+ "actor": "APPC",
+ "operation": "ModifyConfig",
+ "target": {
+ "resourceID": "2246ebc9-9b9f-42d0-a5e4-0248324fb884"
+ },
+ "payload": {
+ "my-key-A": "{\"input\":\"hello\"}",
+ "my-key-B": "{\"output\":\"world\"}"
+ },
+ "context": {
+ "event": {
+ "requestId": "c7c6a4aa-bb61-4a15-b831-ba1472dd4a65"
+ },
+ "cqdata": {
+ "generic-vnf": [
+ {
+ "vnfId": "my-vnf",
+ "vf-modules": [
+ {
+ "model-invariant-id": "2246ebc9-9b9f-42d0-a5e4-0248324fb884"
+ }
+ ]
+ }
+ ]
+ }
+ }
+ }
+
+An example of a request constructed by the actor using the above parameters, published
+to the APPC topic:
+
+.. code-block:: bash
+
+ {
+ "CommonHeader": {
+ "TimeStamp": 1589400050910,
+ "APIver": "1.01",
+ "RequestID": "c7c6a4aa-bb61-4a15-b831-ba1472dd4a65",
+ "SubRequestID": "ee3f2dc0-a2e0-4ae8-98c3-478c784b8eb5",
+ "RequestTrack": [],
+ "Flags": []
+ },
+ "Action": "ModifyConfig",
+ "Payload": {
+ "my-key-B": {
+ "output": "world"
+ },
+ "my-key-A": {
+ "input": "hello"
+ },
+ "generic-vnf.vnf-id": "my-vnf"
+ }
+ }
+
+
+An example initial response received from APPC on the same topic:
+
+.. code-block:: bash
+
+ {
+ "CommonHeader": {
+ "TimeStamp": 1589400050923,
+ "APIver": "1.01",
+ "RequestID": "c7c6a4aa-bb61-4a15-b831-ba1472dd4a65",
+ "SubRequestID": "ee3f2dc0-a2e0-4ae8-98c3-478c784b8eb5",
+ "RequestTrack": [],
+ "Flags": []
+ },
+ "Status": {
+ "Code": 100,
+ "Value": "ACCEPTED"
+ }
+ }
+
+
+An example final response received from APPC on the same topic:
+
+.. code-block:: bash
+
+ {
+ "CommonHeader": {
+ "TimeStamp": 1589400050934,
+ "APIver": "1.01",
+ "RequestID": "c7c6a4aa-bb61-4a15-b831-ba1472dd4a65",
+ "SubRequestID": "ee3f2dc0-a2e0-4ae8-98c3-478c784b8eb5",
+ "RequestTrack": [],
+ "Flags": []
+ },
+ "Status": {
+ "Code": 400,
+ "Value": "SUCCESS"
+ }
+ }
+
+
+Configuration of the APPC Legacy Actor
+######################################
+
+The following table specifies the fields that should be provided to configure the APPC
+Legacy actor.
+
+=============================== ==================== ==================================================================
+Field name type Description
+=============================== ==================== ==================================================================
+sinkTopic string Name of the topic to which the request should be published.
+sourceTopic string Name of the topic from which the response should be read.
+timeoutSec integer (optional) Maximum time, in seconds, to wait for a response to be received
+ on the topic.
+=============================== ==================== ==================================================================
+
+The individual operations are configured using these same field names. However, all
+of them are optional, as they inherit their values from the corresponding actor-level
+fields.
diff --git a/docs/development/actors/appclcm/appclcm.rst b/docs/development/actors/appclcm/appclcm.rst
new file mode 100644
index 00000000..e9ea684f
--- /dev/null
+++ b/docs/development/actors/appclcm/appclcm.rst
@@ -0,0 +1,227 @@
+.. This work is licensed under a
+.. Creative Commons Attribution 4.0 International License.
+.. http://creativecommons.org/licenses/by/4.0
+
+.. _appclcm-label:
+
+##############
+APPC LCM Actor
+##############
+
+.. contents::
+ :depth: 3
+
+Overview of APPC LCM Actor
+##########################
+ONAP Policy Framework enables APPC as one of the supported actors. The APPC LCM Actor
+contains operations supporting both the LCM interface and the legacy interface.
+As such, this actor supersedes the APPC Legacy actor. Its sequence number is lower
+than the APPC Legacy actor's sequence number, which ensures that it is loaded
+first.
+
+APPC Legacy uses a single DMaaP topic for both requests and responses. The class(es)
+supporting this interface are described in :ref:`appc-legacy-label`. The APPC LCM
+Actor only supports the APPC Legacy operation, *ModifyConfig*.
+
+The APPC LCM interface, on the other hand, uses two DMaaP topics, one to which requests
+are published, and another from which responses are received. Similar to the legacy
+interface, APPC LCM may generate more than one response for a particular request, the
+first response simply indicating that the request was accepted, while the second
+response indicates completion of the request.
+
+For each request, a unique sub-request ID is generated. This is used to match the
+received responses with the published requests. (APPC LCM also has a "correlation-id"
+field, which could potentially be used to match the response to the request, but
+apparently APPC LCM has not implemented that capability yet.)
+
+All APPC LCM operations are currently supported by a single java class,
+*AppcLcmOperation*, which is responsible for populating the request structure
+appropriately. This class is derived from *BidirectionalTopicOperation*.
+
+
+**The remainder of this discussion describes the operations that are specific to APPC
+LCM.**
+
+
+Request
+#######
+
+CommonHeader
+************
+
+The "common-header" field in the request is built by policy.
+
+=============================== =========== ==================================================================
+ "common-header" field name type Description
+=============================== =========== ==================================================================
+sub-request-id string Generated by Policy. Is a UUID and used internally by policy
+ to match the response with the request.
+request-id string Inserted by Policy. Maps to the UUID sent by DCAE i.e. the ID
+ used throughout the closed loop lifecycle to identify a request.
+originator-id string Copy of the request-id.
+=============================== =========== ==================================================================
+
+
+Action
+******
+
+The "action" field uniquely identifies the operation to perform. Currently, the
+following operations are supported:
+
+- Restart
+- Rebuild
+- Migrate
+- ConfigModify
+
+The valid operations are listed in *AppcLcmConstants*. These are the values that must
+be specified in the policy. However, before being stuffed into the "action" field,
+they are converted to camel case, stripping any hyphens, and translating the first
+character to upper case, if it isn't already.
+
+
+Action Identifiers
+******************
+
+Currently, the "action-identifiers" field contains only the VNF ID, which should be the
+*targetEntity* specified within the *ControlLoopOperationParams*.
+
+
+Payload
+*******
+
+The "payload" field is populated based on the *payload* specified within the
+*ControlLoopOperationParams*. Unlike the APPC Legacy operations, which inject POJOs
+into the "payload" field, the APPC LCM operations simply encode the entire
+parameter *payload* into a JSON string, and then place the encoded string into the
+"payload" field of the request.
+
+
+Examples
+########
+
+Suppose the *ControlLoopOperationParams* were populated as follows:
+
+.. code-block:: bash
+
+ {
+ "actor": "APPC",
+ "operation": "Restart",
+ "targetEntity": "my-target",
+ "payload": {
+ "my-key-A": "hello",
+ "my-key-B": "world"
+ },
+ "context": {
+ "event": {
+ "requestId": "664be3d2-6c12-4f4b-a3e7-c349acced200"
+ }
+ }
+ }
+
+An example of a request constructed by the actor using the above parameters, published
+to the APPC LCM request topic:
+
+.. code-block:: bash
+
+ {
+ "version": "2.0",
+ "rpc-name": "restart",
+ "correlation-id": "664be3d2-6c12-4f4b-a3e7-c349acced200-8c4c1914-00ed-4be0-ae3b-49dd22e8f461",
+ "type": "request",
+ "body": {
+ "input": {
+ "common-header": {
+ "timestamp": "2020-05-14T19:19:32.619890900Z",
+ "api-ver": "2.00",
+ "originator-id": "664be3d2-6c12-4f4b-a3e7-c349acced200",
+ "request-id": "664be3d2-6c12-4f4b-a3e7-c349acced200",
+ "sub-request-id": "8c4c1914-00ed-4be0-ae3b-49dd22e8f461",
+ "flags": {}
+ },
+ "action": "Restart",
+ "action-identifiers": {
+ "vnf-id": "my-target"
+ },
+ "payload": "{\"my-key-A\":\"hello\", \"my-key-B\":\"world\"}"
+ }
+ }
+ }
+
+
+An example initial response received from the APPC LCM response topic:
+
+.. code-block:: bash
+
+ {
+ "body": {
+ "output": {
+ "common-header": {
+ "timestamp": "2020-05-14T19:19:32.619897000Z",
+ "api-ver": "5.00",
+ "originator-id": "664be3d2-6c12-4f4b-a3e7-c349acced200",
+ "request-id": "664be3d2-6c12-4f4b-a3e7-c349acced200",
+ "sub-request-id": "8c4c1914-00ed-4be0-ae3b-49dd22e8f461",
+ "flags": {}
+ },
+ "status": {
+ "code": 100,
+ "message": "Restart accepted"
+ }
+ }
+ },
+ "version": "2.0",
+ "rpc-name": "restart",
+ "correlation-id": "664be3d2-6c12-4f4b-a3e7-c349acced200-1",
+ "type": "response"
+ }
+
+
+An example final response received from the APPC LCM on the same response topic:
+
+.. code-block:: bash
+
+ {
+ "body": {
+ "output": {
+ "common-header": {
+ "timestamp": "2020-05-14T19:19:32.619898000Z",
+ "api-ver": "5.00",
+ "originator-id": "664be3d2-6c12-4f4b-a3e7-c349acced200",
+ "request-id": "664be3d2-6c12-4f4b-a3e7-c349acced200",
+ "sub-request-id": "8c4c1914-00ed-4be0-ae3b-49dd22e8f461",
+ "flags": {}
+ },
+ "status": {
+ "code": 400,
+ "message": "Restart Successful"
+ }
+ }
+ },
+ "version": "2.0",
+ "rpc-name": "restart",
+ "correlation-id": "664be3d2-6c12-4f4b-a3e7-c349acced200-1",
+ "type": "response"
+ }
+
+
+Configuration of the APPC LCM Actor
+###################################
+
+The following table specifies the fields that should be provided to configure the APPC
+LCM actor.
+
+=============================== ==================== ==================================================================
+Field name type Description
+=============================== ==================== ==================================================================
+sinkTopic string Name of the topic to which the request should be published.
+sourceTopic string Name of the topic from which the response should be read.
+ This must not be the same as the *sinkTopic*.
+timeoutSec integer (optional) Maximum time, in seconds, to wait for a response to be received
+ on the topic.
+=============================== ==================== ==================================================================
+
+The individual operations are configured using these same field names. However, all
+of them are optional, as they inherit their values from the corresponding actor-level
+fields. That being said, the APPC Legacy operation(s) use a different topic than the
+APPC LCM operations. As a result, the sink and source topics should be specified for
+each APPC Legacy operation supported by this actor.
diff --git a/docs/development/actors/guard/guard.rst b/docs/development/actors/guard/guard.rst
new file mode 100644
index 00000000..2c7f2611
--- /dev/null
+++ b/docs/development/actors/guard/guard.rst
@@ -0,0 +1,128 @@
+.. This work is licensed under a
+.. Creative Commons Attribution 4.0 International License.
+.. http://creativecommons.org/licenses/by/4.0
+
+###########
+GUARD Actor
+###########
+
+.. contents::
+ :depth: 3
+
+Overview of GUARD Actor
+#######################
+
+Within ONAP Policy Framework, a GUARD is typically an implicit check performed at the
+start of each operation and is performed by making a REST call to the XACML-PDP.
+Previously, the request was built, and the REST call made, by the application. However,
+Guard checks have now been implemented using the new Actor framework.
+
+Currently, there is a single operation, *Decision*, which is implemented by the java
+class, *GuardOperation*. This class is derived from *HttpOperation*.
+
+
+Request
+#######
+
+A number of the request fields are populated from values specified in the
+actor/operation's configuration parameters (e.g., "onapName"). Additional fields
+are specified below.
+
+Request ID
+**********
+
+The "requestId" field is set to a UUID.
+
+
+Resource
+********
+
+The "resource" field is populated with a *Map* containing a single item, "guard". The
+value of the item is set to the contents of the *payload* specified within the
+*ControlLoopOperationParams*.
+
+
+Examples
+########
+
+Suppose the *ControlLoopOperationParams* were populated as follows:
+
+.. code-block:: bash
+
+ {
+ "actor": "GUARD",
+ "operation": "Decision",
+ "payload": {
+ "actor": "SO",
+ "operation": "VF Module Create",
+ "target": "OzVServer",
+ "requestId": "c7c6a4aa-bb61-4a15-b831-ba1472dd4a65",
+ "clname": "ControlLoop-vDNS-6f37f56d-a87d-4b85-b6a9-cc953cf779b3",
+ "vfCount": 2
+ }
+ }
+
+An example of a request constructed by the actor using the above parameters, sent to the
+GUARD REST server:
+
+.. code-block:: bash
+
+ {
+ "ONAPName": "Policy",
+ "ONAPComponent": "Drools PDP",
+ "ONAPInstance": "Usecases",
+ "requestId": "90ee99d2-f2d8-4d90-b162-605203c30180",
+ "action": "guard",
+ "resource": {
+ "guard": {
+ "actor": "SO",
+ "operation": "VF Module Create",
+ "target": "OzVServer",
+ "requestId": "c7c6a4aa-bb61-4a15-b831-ba1472dd4a65",
+ "clname": "ControlLoop-vDNS-6f37f56d-a87d-4b85-b6a9-cc953cf779b3",
+ "vfCount": 2
+ }
+ }
+ }
+
+
+An example response received from the GUARD REST service:
+
+.. code-block:: bash
+
+ {
+ "status": "Permit",
+ "advice": {},
+ "obligations": {},
+ "policies": {}
+ }
+
+
+Configuration of the GUARD Actor
+################################
+
+The following table specifies the fields that should be provided to configure the GUARD
+actor.
+
+=============================== ===================== ==================================================================
+Field name type Description
+=============================== ===================== ==================================================================
+clientName string Name of the HTTP client to use to send the request to the
+ GUARD REST server.
+timeoutSec integer (optional) Maximum time, in seconds, to wait for a response to be received
+ from the REST server. Defaults to 90s.
+path string URI appended to the URL. This field only applies to individual
+ operations; it does not apply at the actor level. Note: the
+ *path* should not include a leading or trailing slash.
+onapName string ONAP Name (e.g., "Policy")
+onapComponent string ONAP Component (e.g., "Drools PDP")
+onapInstance string ONAP Instance (e.g., "Usecases")
+action string (optional) Used to populate the "action" request field.
+ Defaults to "guard".
+disabled boolean (optional) **True**, to disable guard checks, **false** otherwise.
+ Defaults to *false*.
+=============================== ===================== ==================================================================
+
+The individual operations are configured using these same field names. However, all
+of them, except the path, are optional, as they inherit their values from the
+corresponding actor-level fields.
diff --git a/docs/development/actors/overview.rst b/docs/development/actors/overview.rst
new file mode 100644
index 00000000..f1ca0d68
--- /dev/null
+++ b/docs/development/actors/overview.rst
@@ -0,0 +1,197 @@
+.. This work is licensed under a Creative Commons Attribution 4.0 International License.
+
+.. _actors-overview-label:
+
+#####################
+Actor Design Overview
+#####################
+
+.. contents::
+
+Intro
+#####
+
+An actor/operation is any ONAP component that an Operational Policy can use to control
+a VNF/VM/etc. during execution of a control loop operational policy when a Control Loop
+Event is triggered.
+
+.. image:: topview.png
+
+An Actor Service object contains one or more Actor objects, which are found and created
+using *ServiceLoader*. Each Actor object, in turn, creates one or more Operator objects.
+All of these components, the Actor Service, the Actor, and the Operator are typically
+singletons that are created once, at start-up (or on the first request).
+The Actor Service includes several methods, *configure()*, *start()*, and *stop()*,
+which are cascaded to the Actors and then to the Operators.
+
+Operation objects, on the other hand, are not singletons; a new Operation object is
+created for each operation that an application wishes to perform. For instance, if an
+application wishes to use the "SO" Actor to add two new modules, then two separate
+Operation objects would be created, one for each module.
+
+Actors are configured by invoking the Actor Service *configure()* method, passing it
+a set of properties. The *configure()* method extracts the properties that are relevant
+to each Actor and passes them to the Actor's *configure()* method. Similarly, the
+Actor's *configure()* method extracts the properties that are relevant
+to each Operator and passes them to the Operator's *configure()* method. Note:
+Actors typically extract "default" properties from their respective property sets
+and include those when invoking each Operator's *configure()* method.
+
+Once the Actor Service has been configured, it can be started via *start()*. It will
+then continue to run until no longer needed, at which point *stop()* can be invoked.
+
+Note: it is possible to create separate instances of an Actor Service, each with its
+own set of properties. In that case, each Actor Service will get its own instances of
+Actors and Operators.
+
+Components
+##########
+
+This section describes things to consider when creating a new Actor/Operator.
+
+Actor
+*****
+
+- The constructor should use addOperator() to add operators
+- By convention, the name of the actor is specified by a static field, "NAME"
+- An actor is registered via the Java ServiceLoader by including its jar on the
+ classpath and adding its class name to this file, typically contained within the jar:
+
+ onap.policy.controlloop.actorServiceProvider.spi
+
+- Actor loading is ordered, so that those having a lower (i.e., earlier) sequence number
+ are loaded first. If a later actor has the same name as one that has already been
+ loaded, a warning will be generated and the later actor discarded. This makes it
+ possible for an organization to override an actor implementation
+- An implementation for a specific Actor will typically be derived from
+ *HttpActor* or *BidirectionalTopicActor*, depending whether it is HTTP/REST-based
+ or DMaaP-topic-based. These super classes provide most of the functionality needed
+ to configure the operators, extracting operator-specific properties and adding
+ default, actor-level properties
+
+Operator
+********
+
+- Typically, developers don’t have to implement any Operator classes; they just use
+ *HttpOperator* or *BidirectionalTopicOperator*
+
+Operation
+*********
+
+- Most operations require guard checks to be performed first. Thus, at a minimum, they
+ should override *startPreprocessorAsync()* and have it invoke *startGuardAsync()*
+- In addition, if the operation depends on data being previously gathered and placed
+ into the context, then it should override *startPreprocessorAsync()* and have it
+ invoke *obtain()*. Note: *obtain()*
+ and the guard can be performed in parallel by using the *allOf()* method. If the
+ guard
+ happens to depend on the same data, then it will block until the data is available,
+ and then continue; the invoker need not deal with the dependency
+- Subclasses will typically derive from *HttpOperation* or *BidirectionalTopicOperation*,
+ though if neither of those suffice, then they can extend *OperationPartial*, or
+ even just implement a raw *Operation*. *OperationPartial* is the super class of
+ *HttpOperation* and *BidirectionalTopicOperation* and provides most of the methods
+ used by the Operation subclasses, including a number of utility methods (e.g.,
+ cancellable *allOf*)
+- Operation subclasses should be written in a way so-as to avoid any blocking I/O. If
+ this proves too difficult, then the implementation should override *doOperation()*
+ instead of *startOperationAsync()*
+- Operations return a "future" when *start()* is invoked. Typically, if the "future" is
+ canceled, then any outstanding operation should be canceled. For instance, HTTP
+ connections should be closed without waiting for a response
+- If an operation sets the outcome to "FAILURE", it will be automatically retried; other
+ failure types are not retried
+
+ControlLoopParams
+*****************
+
+- Identifies the operation to be performed
+- Includes timeout and retry information, though the actors typically provide default
+ values if they are not specified in the parameters
+- Includes the event "context"
+- Includes “Policy” fields (e.g., "actor" and "operation")
+
+Context (aka, Event Context)
+****************************
+
+- Includes:
+
+ - the original onset event
+ - enrichment data associated with the event
+ - results of A&AI queries
+
+XxxParams and XxxConfig
+***********************
+
+- XxxParams objects are POJOs into which the property Maps are decoded when configuring
+ actors or operators
+- XxxConfig objects contain a single Operator's (or Actor's) configuration information,
+ based on what was in the XxxParams. For instance, the HttpConfig contains a reference
+ to the HttpClient that is used to perform HTTP
+ operations, while the associated HttpParams just contains the name of the HttpClient.
+ XxxConfig objects are
+ shared by all operations created by a single Operator. As a result, it should not
+ contain any data associated with an individual operation; such data should be stored
+ within the Operation object, itself
+
+Junit tests
+***********
+
+- Operation Tests may choose to subclass from *BasicHttpOperation*, which provides some
+ supporting utilities and mock objects
+- Should include a test to verify that the Actor, and possibly each Operator, can be
+ retrieved via an Actor Service
+- Tests with an actual REST server are performed within *HttpOperationTest*, so need not
+ be repeated in subclasses. Instead, they can catch the callback to the *get()*,
+ *post()*, etc., methods and pass the rawResponse to it there. That being said, a
+ number of actors spin up a simulator to verify end-to-end request/response processing
+
+Clients (e.g., drools-applications)
+***********************************
+
+- When using callbacks, a client may want to use the *isFor()* method to verify that the
+ outcome is for the desired operation, as callbacks are invoked with the outcome of all
+ operations performed, including any preprocessor steps
+
+Flow of operation
+#################
+
+- PDP:
+
+ - Populates a *ControlLoopParams* using *ControlLoopParams.builder()*
+ - Invokes *start()* on the *ControlLoopParams*
+
+- ControlLoopParams:
+
+ - Finds the actor/operator
+ - Uses it to invoke *buildOperation()*
+ - Invokes *start()* on the Operation
+
+- Operation:
+
+ - *start()* invokes *startPreprocessorAsync()* and then *startOperationAsync()*
+ - Exceptions that occur while **constructing** the operation pipeline propagate back
+ to the client that invoked *start()*
+ - Exceptions that occur while **executing** the operation pipeline are caught and
+ turned into an *OperationOutcome* whose result is FAILURE_EXCEPTION. In addition,
+ the "start" callback (i.e., specified via the *ControlLoopParams*) will be invoked,
+ if it hasn't been invoked yet, and then the "complete" callback will be invoked
+ - By default, *startPreprocessorAsync()* does nothing, thus most subclasses will override it to:
+
+ - Do any A&AI query that is needed (beyond enrichment, which is already available in
+ the *Context*)
+ - Use *Context obtain()* to request the data asynchronously
+ - Invoke *startGuardAsync()*
+
+ - By default, *startGuardAsync()* will simply perform a guard check, passing it the
+ "standard" payload
+ - Subclasses may override *makeGuardPayload()* to add extra fields to the payload
+ (e.g., some SO operations add the VF count)
+ - If any preprocessing step fails, then the "start" and "complete" callbacks will be
+ invoked to indicate a failure of the operation as a whole. Otherwise, the flow will
+ continue on to *startOperationAsync()*, after the "start" callback is invoked
+ - *StartOperationAsync()* will perform whatever needs to be done to start the operation
+ - Once it completes, the "complete" callback will be invoked with the outcome of the
+ operation. *StartOperationAsync()* should not invoke the callback, as that is
+ handled automatically by *OperationPartial*, which is the superclass of most
+ Operations
diff --git a/docs/development/actors/sdnc/sdnc.rst b/docs/development/actors/sdnc/sdnc.rst
new file mode 100644
index 00000000..95998daf
--- /dev/null
+++ b/docs/development/actors/sdnc/sdnc.rst
@@ -0,0 +1,165 @@
+.. This work is licensed under a
+.. Creative Commons Attribution 4.0 International License.
+.. http://creativecommons.org/licenses/by/4.0
+
+.. _sdnc-label:
+
+##########
+SDNC Actor
+##########
+
+.. contents::
+ :depth: 3
+
+Overview of SDNC Actor
+######################
+ONAP Policy Framework enables SDNC as one of the supported actors.
+SDNC uses a REST-based interface, and supports the following operations:
+*BandwidthOnDemand*, *Reroute*.
+
+Each operation supported by the actor is associated with its own java class, which is
+responsible for populating the request structure appropriately. The operation-specific
+classes are all derived from the *SdncOperation* class, which is, itself, derived from
+*HttpOperation*. Each operation class implements its own *makeRequest()* method to
+construct a request appropriate to the operation.
+
+
+Request
+#######
+
+A number of nested structures are populated within the request. The following table
+lists the contents of some of the fields that appear within these structures.
+
++----------------------------------+---------+----------------------------------------------------------------------+
+| Field Name | Type | Description |
++----------------------------------+---------+----------------------------------------------------------------------+
++----------------------------------+---------+----------------------------------------------------------------------+
+| top level: | | |
++----------------------------------+---------+----------------------------------------------------------------------+
+| *requestId* | string | Inserted by Policy. Maps to the UUID sent by DCAE i.e. the ID |
+| | | used throughout the closed loop lifecycle to identify a request. |
++----------------------------------+---------+----------------------------------------------------------------------+
++----------------------------------+---------+----------------------------------------------------------------------+
+| sdnc-request-header: | | |
++----------------------------------+---------+----------------------------------------------------------------------+
+| *svc-action* | string | Set by Policy, based on the operation. |
++----------------------------------+---------+----------------------------------------------------------------------+
+| *svc-request-id* | string | Generated by Policy. Is a UUID. |
++----------------------------------+---------+----------------------------------------------------------------------+
++----------------------------------+---------+----------------------------------------------------------------------+
+| request-information: | | |
++----------------------------------+---------+----------------------------------------------------------------------+
+| *request-action* | string | Set by Policy, based on the operation. |
++----------------------------------+---------+----------------------------------------------------------------------+
++----------------------------------+---------+----------------------------------------------------------------------+
+| network-information: | | Applicable to *Reroute*. |
++----------------------------------+---------+----------------------------------------------------------------------+
+| *network-id* | string | Set by Policy, using the |
+| | | "network-information.network-id" property |
+| | | found within the enrichment data provided by DCAE |
+| | | with the ONSET event. |
++----------------------------------+---------+----------------------------------------------------------------------+
++----------------------------------+---------+----------------------------------------------------------------------+
+| vnf-information: | | Applicable to *BandwidthOnDemand*. |
++----------------------------------+---------+----------------------------------------------------------------------+
+| *vnf-id* | string | Set by Policy, using the |
+| | | "vnfId" property |
+| | | found within the enrichment data provided by DCAE |
+| | | with the ONSET event. |
++----------------------------------+---------+----------------------------------------------------------------------+
++----------------------------------+---------+----------------------------------------------------------------------+
+| vf-module-input-parameters: | | Applicable to *BandwidthOnDemand*. |
++----------------------------------+---------+----------------------------------------------------------------------+
+| *param[0]* | string | Set by Policy, using the |
+| | | "bandwidth" property |
+| | | found within the enrichment data provided by DCAE |
+| | | with the ONSET event. |
++----------------------------------+---------+----------------------------------------------------------------------+
+| *param[1]* | string | Set by Policy, using the |
+| | | "bandwidth-change-time" property |
+| | | found within the enrichment data provided by DCAE |
+| | | with the ONSET event. |
++----------------------------------+---------+----------------------------------------------------------------------+
++----------------------------------+---------+----------------------------------------------------------------------+
+| vf-module-information: | | Applicable to *BandwidthOnDemand*. |
++----------------------------------+---------+----------------------------------------------------------------------+
+| *vf-module-id* | string | Set by Policy to "". |
++----------------------------------+---------+----------------------------------------------------------------------+
+
+
+Examples
+########
+
+Suppose the *ControlLoopOperationParams* were populated as follows:
+
+.. code-block:: bash
+
+ {
+ "actor": "SDNC",
+ "operation": "Reroute",
+ "context": {
+ "enrichment": {
+ "service-instance.service-instance-id": "c7c6a4aa-bb61-4a15-b831-ba1472dd4a65",
+ "network-information.network-id": "2246ebc9-9b9f-42d0-a5e4-0248324fb884"
+ }
+ }
+ }
+
+An example of a request constructed by the actor using the above parameters, sent to the
+SDNC REST server:
+
+.. code-block:: bash
+
+ {
+ "input": {
+ "sdnc-request-header": {
+ "svc-request-id": "2612653e-d946-423b-96d9-a8d5e8e39618",
+ "svc-action": "reoptimize"
+ },
+ "request-information": {
+ "request-action": "ReoptimizeSOTNInstance"
+ },
+ "service-information": {
+ "service-instance-id": "c7c6a4aa-bb61-4a15-b831-ba1472dd4a65"
+ },
+ "network-information": {
+ "network-id": "2246ebc9-9b9f-42d0-a5e4-0248324fb884"
+ }
+ }
+ }
+
+
+An example response received from the SDNC REST service:
+
+.. code-block:: bash
+
+ {
+ "output": {
+ "svc-request-id": "2612653e-d946-423b-96d9-a8d5e8e39618",
+ "response-code": "200",
+ "ack-final-indicator": "Y"
+ }
+ }
+
+
+Configuration of the SDNC Actor
+###############################
+
+The following table specifies the fields that should be provided to configure the SDNC
+actor.
+
+=============================== ==================== ==================================================================
+Field name type Description
+=============================== ==================== ==================================================================
+clientName string Name of the HTTP client to use to send the request to the
+ SDNC REST server.
+timeoutSec integer (optional) Maximum time, in seconds, to wait for a response to be received
+ from the REST server. Defaults to 90s.
+path string URI appended to the URL. This field only applies to individual
+ operations; it does not apply at the actor level. Note: the
+ *path* should not include a leading or trailing slash.
+=============================== ==================== ==================================================================
+
+The individual operations are configured using these same field names. However, all
+of them, except the *path*, are optional, as they inherit their values from the
+corresponding actor-level fields.
diff --git a/docs/development/actors/sdnr/sdnr.rst b/docs/development/actors/sdnr/sdnr.rst
new file mode 100644
index 00000000..13d91940
--- /dev/null
+++ b/docs/development/actors/sdnr/sdnr.rst
@@ -0,0 +1,193 @@
+.. This work is licensed under a
+.. Creative Commons Attribution 4.0 International License.
+.. http://creativecommons.org/licenses/by/4.0
+
+.. _sdnr-label:
+
+##########
+SDNR Actor
+##########
+
+.. contents::
+ :depth: 3
+
+Overview of SDNR Actor
+######################
+ONAP Policy Framework enables SDNR as one of the supported actors. SDNR uses two
+DMaaP topics, one to which requests are published, and another from which responses
+are received. SDNR may generate more than one response for a particular request,
+the first response simply indicating that the request was accepted, while the second
+response indicates completion of the request. For each request, a unique sub-request
+ID is generated. This is used to match the received responses with the published
+requests.
+
+When an SDNR request completes, whether successfully or unsuccessfully, the actor
+populates the *controlLoopResponse* within the *OperationOutcome*. The application
+will typically publish this to a notification topic so that downstream systems can
+take appropriate action.
+
+All SDNR operations are currently supported by a single java class,
+*SdnrOperation*, which is responsible for populating the request structure
+appropriately. This class is derived from *BidirectionalTopicOperation*.
+
+
+Request
+#######
+
+CommonHeader
+************
+
+The "CommonHeader" field in the request is built by policy.
+
+=============================== =========== ==================================================================
+ "CommonHeader" field name type Description
+=============================== =========== ==================================================================
+SubRequestID string Generated by Policy. Is a UUID and used internally by policy
+ to match the response with the request.
+RequestID string Inserted by Policy. Maps to the UUID sent by DCAE i.e. the ID
+ used throughout the closed loop lifecycle to identify a request.
+=============================== =========== ==================================================================
+
+
+Action
+******
+
+The "action" field uniquely identifies the operation to perform. Operation names are
+not validated. Instead, they are passed to SDNR, untouched.
+
+
+RPC Name
+********
+
+The "rpc-name" field is the same as the "action" field, with everything mapped to lower
+case.
+
+
+Payload
+*******
+
+The "payload" field is populated with the *payload* text that is provided within the
+ONSET event; no additional transformation is applied.
+
+
+Examples
+########
+
+Suppose the *ControlLoopOperationParams* were populated as follows:
+
+.. code-block:: bash
+
+ {
+ "actor": "SDNR",
+ "operation": "ModifyConfig",
+ "context": {
+ "event": {
+ "requestId": "664be3d2-6c12-4f4b-a3e7-c349acced200",
+ "payload": "some text"
+ }
+ }
+ }
+
+An example of a request constructed by the actor using the above parameters, published
+to the SDNR request topic:
+
+.. code-block:: bash
+
+ {
+ "body": {
+ "input": {
+ "CommonHeader": {
+ "TimeStamp": "2020-05-18T14:43:58.550499700Z",
+ "APIVer": "1.0",
+ "RequestID": "664be3d2-6c12-4f4b-a3e7-c349acced200",
+ "SubRequestID": "848bfd15-b189-43a1-bdea-80982b41fa24",
+ "RequestTrack": {},
+ "Flags": {}
+ },
+ "Action": "ModifyConfig",
+ "Payload": "some text"
+ }
+ },
+ "version": "1.0",
+ "rpc-name": "modifyconfig",
+ "correlation-id": "664be3d2-6c12-4f4b-a3e7-c349acced200-848bfd15-b189-43a1-bdea-80982b41fa24",
+ "type": "request"
+ }
+
+
+An example initial response received from the SDNR response topic:
+
+.. code-block:: bash
+
+ {
+ "body": {
+ "output": {
+ "CommonHeader": {
+ "TimeStamp": "2020-05-18T14:44:10.000Z",
+ "APIver": "1.0",
+ "RequestID": "664be3d2-6c12-4f4b-a3e7-c349acced200",
+ "SubRequestID": "848bfd15-b189-43a1-bdea-80982b41fa24",
+ "RequestTrack": [],
+ "Flags": []
+ },
+ "Status": {
+ "Code": 100,
+ "Value": "ACCEPTED"
+ }
+ }
+ },
+ "version": "1.0",
+ "rpc-name": "modifyconfig",
+ "correlation-id": "664be3d2-6c12-4f4b-a3e7-c349acced200-848bfd15-b189-43a1-bdea-80982b41fa24",
+ "type": "response"
+ }
+
+
+An example final response received from the SDNR on the same response topic:
+
+.. code-block:: bash
+
+ {
+ "body": {
+ "output": {
+ "CommonHeader": {
+ "TimeStamp": "2020-05-18T14:44:20.000Z",
+ "APIver": "1.0",
+ "RequestID": "664be3d2-6c12-4f4b-a3e7-c349acced200",
+ "SubRequestID": "848bfd15-b189-43a1-bdea-80982b41fa24",
+ "RequestTrack": [],
+ "Flags": []
+ },
+ "Status": {
+ "Code": 200,
+ "Value": "SUCCESS"
+ },
+ "Payload": "{ \"Configurations\":[ { \"Status\": { \"Code\": 200, \"Value\": \"SUCCESS\" }, \"data\":{\"FAPService\":{\"alias\":\"Chn0330\",\"X0005b9Lte\":{\"phyCellIdInUse\":6,\"pnfName\":\"ncserver23\"},\"CellConfig\":{\"LTE\":{\"RAN\":{\"Common\":{\"CellIdentity\":\"Chn0330\"}}}}}} } ] }"
+ }
+ },
+ "version": "1.0",
+ "rpc-name": "modifyconfig",
+ "correlation-id": "664be3d2-6c12-4f4b-a3e7-c349acced200-848bfd15-b189-43a1-bdea-80982b41fa24",
+ "type": "response"
+ }
+
+
+Configuration of the SDNR Actor
+###############################
+
+The following table specifies the fields that should be provided to configure the SNDR
+actor.
+
+=============================== ==================== ==================================================================
+Field name type Description
+=============================== ==================== ==================================================================
+sinkTopic string Name of the topic to which the request should be published.
+sourceTopic string Name of the topic from which the response should be read.
+ This must not be the same as the *sinkTopic*.
+timeoutSec integer (optional) Maximum time, in seconds, to wait for a response to be received
+ on the topic.
+=============================== ==================== ==================================================================
+
+The individual operations are configured using these same field names. However, all
+of them are optional, as they inherit their values from the corresponding actor-level
+fields.
diff --git a/docs/development/actors/so/so.rst b/docs/development/actors/so/so.rst
new file mode 100644
index 00000000..c7663d8b
--- /dev/null
+++ b/docs/development/actors/so/so.rst
@@ -0,0 +1,452 @@
+.. This work is licensed under a
+.. Creative Commons Attribution 4.0 International License.
+.. http://creativecommons.org/licenses/by/4.0
+
+.. _so-label:
+
+##########
+SO Actor
+##########
+
+.. contents::
+ :depth: 3
+
+Overview of SO Actor
+######################
+ONAP Policy Framework enables SO as one of the supported actors. SO uses a REST-based
+interface. However, as requests may not complete right away, a REST-based polling
+interface is used to check the status of the request. The *requestId* is extracted
+from the initial response and is appended to the *pathGet* configuration parameter to
+generate the URL used to poll for completion.
+
+Each operation supported by the actor is associated with its own java class, which is
+responsible for populating the request structure appropriately and sending the request.
+Note: the request may be issued via POST, DELETE, etc., depending on the operation.
+The operation-specific classes are all derived from the *SoOperation* class, which is,
+itself, derived from *HttpOperation*. The following operations are currently supported:
+
+- VF Module Create
+- VF Module Delete
+
+
+Request
+#######
+
+A number of nested structures are populated within the request. Several of them are
+populated with data extracted from the A&AI Custom Query response that is retrieved
+using the Target resource ID specified in the *ControlLoopOperationParams*. The
+following table lists the contents of some of the fields that appear within these
+structures.
+
++----------------------------------+---------+----------------------------------------------------------------------+
+| Field Name | Type | Description |
++----------------------------------+---------+----------------------------------------------------------------------+
++----------------------------------+---------+----------------------------------------------------------------------+
+| top level: | | |
++----------------------------------+---------+----------------------------------------------------------------------+
+| *operationType* | string | Inserted by Policy. Name of the operation. |
++----------------------------------+---------+----------------------------------------------------------------------+
++----------------------------------+---------+----------------------------------------------------------------------+
+| requestDetails: | | |
++----------------------------------+---------+----------------------------------------------------------------------+
+| requestParameters | | Applicable to *VF Module Create*. |
+| | | Set by Policy from the *requestParameters* specified in the |
+| | | *payload* of the *ControlLoopOperationParams*. |
+| | | The value is treated as a JSON string and decoded into an |
+| | | *SoRequestParameters* object that is placed into this field. |
++----------------------------------+---------+----------------------------------------------------------------------+
+| configurationParameters | | Applicable to *VF Module Create*. |
+| | | Set by Policy from the *configurationParameters* specified in the |
+| | | *payload* of the *ControlLoopOperationParams*. |
+| | | The value is treated as a JSON string and decoded into a |
+| | | *List* of *Maps* that is placed into this field. |
++----------------------------------+---------+----------------------------------------------------------------------+
++----------------------------------+---------+----------------------------------------------------------------------+
+| modelInfo: | | Set by Policy. Copied from the *target* specified in the |
+| | | *ControlLoopOperationParams*. |
++----------------------------------+---------+----------------------------------------------------------------------+
++----------------------------------+---------+----------------------------------------------------------------------+
+| cloudConfiguration: | | |
++----------------------------------+---------+----------------------------------------------------------------------+
+| *tenantId* | string | The ID of the "default" Tenant selected from the A&AI Custom Query |
+| | | response. |
++----------------------------------+---------+----------------------------------------------------------------------+
+| *lcpCloudRegionId* | string | The ID of the "default" Cloud Region selected from the A&AI Custom |
+| | | Query response. |
++----------------------------------+---------+----------------------------------------------------------------------+
++----------------------------------+---------+----------------------------------------------------------------------+
+| relatedInstanceList[0]: | | Applicable to *VF Module Create*. |
+| | | The "default" Service Instance selected from the A&AI Custom Query |
+| | | response. |
++----------------------------------+---------+----------------------------------------------------------------------+
++----------------------------------+---------+----------------------------------------------------------------------+
+| relatedInstanceList[1]: | | Applicable to *VF Module Create*. |
+| | | The VNF selected from the A&AI Custom Query |
+| | | response. |
++----------------------------------+---------+----------------------------------------------------------------------+
+
+
+Examples
+########
+
+Suppose the *ControlLoopOperationParams* were populated as follows:
+
+.. code-block:: bash
+
+ {
+ "actor": "SO",
+ "operation": "Reroute",
+ "target": {
+ "modelInvariantId": "2246ebc9-9b9f-42d0-a5e4-0248324fb884",
+ "modelName": "VlbCdsSb00..vdns..module-3",
+ "modelVersion": "1",
+ "modelCustomizationUuid": "3a74410a-6c74-4a32-94b2-71488be6da1a",
+ "modelVersionId": "1f94cedb-f656-4ddb-9f55-60ba1fc7d4b1",
+ "modelCustomizationId": "3a74410a-6c74-4a32-94b2-71488be6da1a",
+ "modelUuid": "1f94cedb-f656-4ddb-9f55-60ba1fc7d4b1",
+ "modelInvariantUuid": "2246ebc9-9b9f-42d0-a5e4-0248324fb884"
+ },
+ "context": {
+ "cqdata": {
+ "tenant": {
+ "id": "41d6d38489bd40b09ea8a6b6b852dcbd"
+ },
+ "cloud-region": {
+ "id": "RegionOne"
+ },
+ "service-instance": {
+ "id": "c14e61b5-1ee6-4925-b4a9-b9c8dbfe3f34",
+ "modelInvariantId": "6418bb39-61e1-45fc-a36b-3f211bb846c7",
+ "modelName": "vLB_CDS_SB00_02",
+ "modelVersion": "1.0",
+ "modelVersionId": "d01d9dec-afb6-4a53-bd9e-2eb10ca07a51",
+ "modelUuid": "d01d9dec-afb6-4a53-bd9e-2eb10ca07a51",
+ "modelInvariantUuid": "6418bb39-61e1-45fc-a36b-3f211bb846c7"
+ },
+ "generic-vnf": [
+ {
+ "vnfId": "6636c4d5-f608-4376-b6d8-7977e98cb16d",
+ "vf-modules": [
+ {
+ "modelInvariantId": "827356a9-cb60-4976-9713-c30b4f850b41",
+ "modelName": "vLB_CDS_SB00",
+ "modelVersion": "1.0",
+ "modelCustomizationUuid": "6478f94b-0b20-4b44-afc0-94e48070586a",
+ "modelVersionId": "ca3c4797-0cdd-4797-8bec-9a3ce78ac4da",
+ "modelCustomizationId": "6478f94b-0b20-4b44-afc0-94e48070586a",
+ "modelUuid": "ca3c4797-0cdd-4797-8bec-9a3ce78ac4da",
+ "modelInvariantUuid": "827356a9-cb60-4976-9713-c30b4f850b41"
+ }
+ ]
+ }
+ ]
+ }
+ },
+ "payload": {
+ "requestParameters": "{\"usePreload\": false}",
+ "configurationParameters": "[{\"ip-addr\": \"$.vf-module-topology.vf-module-parameters.param[16].value\", \"oam-ip-addr\": \"$.vf-module-topology.vf-module-parameters.param[30].value\"}]"
+ }
+ }
+
+An example of a request constructed by the actor using the above parameters, sent to the
+SO REST server:
+
+.. code-block:: bash
+
+ {
+ "requestDetails": {
+ "modelInfo": {
+ "modelInvariantId": "2246ebc9-9b9f-42d0-a5e4-0248324fb884",
+ "modelType": "vfModule",
+ "modelName": "VlbCdsSb00..vdns..module-3",
+ "modelVersion": "1",
+ "modelCustomizationUuid": "3a74410a-6c74-4a32-94b2-71488be6da1a",
+ "modelVersionId": "1f94cedb-f656-4ddb-9f55-60ba1fc7d4b1",
+ "modelCustomizationId": "3a74410a-6c74-4a32-94b2-71488be6da1a",
+ "modelUuid": "1f94cedb-f656-4ddb-9f55-60ba1fc7d4b1",
+ "modelInvariantUuid": "2246ebc9-9b9f-42d0-a5e4-0248324fb884"
+ },
+ "cloudConfiguration": {
+ "tenantId": "41d6d38489bd40b09ea8a6b6b852dcbd",
+ "lcpCloudRegionId": "RegionOne"
+ },
+ "requestInfo": {
+ "instanceName": "vfModuleName",
+ "source": "POLICY",
+ "suppressRollback": false,
+ "requestorId": "policy"
+ },
+ "relatedInstanceList": [
+ {
+ "relatedInstance": {
+ "instanceId": "c14e61b5-1ee6-4925-b4a9-b9c8dbfe3f34",
+ "modelInfo": {
+ "modelInvariantId": "6418bb39-61e1-45fc-a36b-3f211bb846c7",
+ "modelType": "service",
+ "modelName": "vLB_CDS_SB00_02",
+ "modelVersion": "1.0",
+ "modelVersionId": "d01d9dec-afb6-4a53-bd9e-2eb10ca07a51",
+ "modelUuid": "d01d9dec-afb6-4a53-bd9e-2eb10ca07a51",
+ "modelInvariantUuid": "6418bb39-61e1-45fc-a36b-3f211bb846c7"
+ }
+ }
+ },
+ {
+ "relatedInstance": {
+ "instanceId": "6636c4d5-f608-4376-b6d8-7977e98cb16d",
+ "modelInfo": {
+ "modelInvariantId": "827356a9-cb60-4976-9713-c30b4f850b41",
+ "modelType": "vnf",
+ "modelName": "vLB_CDS_SB00",
+ "modelVersion": "1.0",
+ "modelCustomizationUuid": "6478f94b-0b20-4b44-afc0-94e48070586a",
+ "modelVersionId": "ca3c4797-0cdd-4797-8bec-9a3ce78ac4da",
+ "modelCustomizationId": "6478f94b-0b20-4b44-afc0-94e48070586a",
+ "modelUuid": "ca3c4797-0cdd-4797-8bec-9a3ce78ac4da",
+ "modelInvariantUuid": "827356a9-cb60-4976-9713-c30b4f850b41"
+ }
+ }
+ }
+ ],
+ "requestParameters": {
+ "usePreload": false
+ },
+ "configurationParameters": [
+ {
+ "ip-addr": "$.vf-module-topology.vf-module-parameters.param[16].value",
+ "oam-ip-addr": "$.vf-module-topology.vf-module-parameters.param[30].value"
+ }
+ ]
+ }
+ }
+
+An example response received to the initial request, from the SO REST service:
+
+.. code-block:: bash
+
+ {
+ "requestReferences": {
+ "requestId": "70f28791-c271-4cae-b090-0c2a359e26d9",
+ "instanceId": "68804843-18e0-41a3-8838-a6d90a035e1a",
+ "requestSelfLink": "http://so.onap:8080/orchestrationRequests/v7/b789e4e6-0b92-42c3-a723-1879af9c799d"
+ }
+ }
+
+An example URL used for the "get" (i.e., poll) request subsequently sent to SO:
+
+.. code-block:: bash
+
+ GET https://so.onap:6969/orchestrationRequests/v5/70f28791-c271-4cae-b090-0c2a359e26d9
+
+An example response received to the poll request, when SO has not completed the request:
+
+.. code-block:: bash
+
+ {
+ "request": {
+ "requestId": "70f28791-c271-4cae-b090-0c2a359e26d9",
+ "startTime": "Fri, 15 May 2020 12:12:50 GMT",
+ "requestScope": "vfModule",
+ "requestType": "scaleOut",
+ "requestDetails": {
+ "modelInfo": {
+ "modelInvariantId": "2246ebc9-9b9f-42d0-a5e4-0248324fb884",
+ "modelType": "vfModule",
+ "modelName": "VlbCdsSb00..vdns..module-3",
+ "modelVersion": "1",
+ "modelCustomizationUuid": "3a74410a-6c74-4a32-94b2-71488be6da1a",
+ "modelVersionId": "1f94cedb-f656-4ddb-9f55-60ba1fc7d4b1",
+ "modelCustomizationId": "3a74410a-6c74-4a32-94b2-71488be6da1a",
+ "modelUuid": "1f94cedb-f656-4ddb-9f55-60ba1fc7d4b1",
+ "modelInvariantUuid": "2246ebc9-9b9f-42d0-a5e4-0248324fb884"
+ },
+ "requestInfo": {
+ "source": "POLICY",
+ "instanceName": "vfModuleName",
+ "suppressRollback": false,
+ "requestorId": "policy"
+ },
+ "relatedInstanceList": [
+ {
+ "relatedInstance": {
+ "instanceId": "c14e61b5-1ee6-4925-b4a9-b9c8dbfe3f34",
+ "modelInfo": {
+ "modelInvariantId": "6418bb39-61e1-45fc-a36b-3f211bb846c7",
+ "modelType": "service",
+ "modelName": "vLB_CDS_SB00_02",
+ "modelVersion": "1.0",
+ "modelVersionId": "d01d9dec-afb6-4a53-bd9e-2eb10ca07a51",
+ "modelUuid": "d01d9dec-afb6-4a53-bd9e-2eb10ca07a51",
+ "modelInvariantUuid": "6418bb39-61e1-45fc-a36b-3f211bb846c7"
+ }
+ }
+ },
+ {
+ "relatedInstance": {
+ "instanceId": "6636c4d5-f608-4376-b6d8-7977e98cb16d",
+ "modelInfo": {
+ "modelInvariantId": "827356a9-cb60-4976-9713-c30b4f850b41",
+ "modelType": "vnf",
+ "modelName": "vLB_CDS_SB00",
+ "modelVersion": "1.0",
+ "modelCustomizationUuid": "6478f94b-0b20-4b44-afc0-94e48070586a",
+ "modelVersionId": "ca3c4797-0cdd-4797-8bec-9a3ce78ac4da",
+ "modelCustomizationId": "6478f94b-0b20-4b44-afc0-94e48070586a",
+ "modelUuid": "ca3c4797-0cdd-4797-8bec-9a3ce78ac4da",
+ "modelInvariantUuid": "827356a9-cb60-4976-9713-c30b4f850b41"
+ }
+ }
+ }
+ ],
+ "cloudConfiguration": {
+ "tenantId": "41d6d38489bd40b09ea8a6b6b852dcbd",
+ "tenantName": "Integration-SB-00",
+ "cloudOwner": "CloudOwner",
+ "lcpCloudRegionId": "RegionOne"
+ },
+ "requestParameters": {
+ "usePreload": false
+ },
+ "configurationParameters": [
+ {
+ "ip-addr": "$.vf-module-topology.vf-module-parameters.param[16].value",
+ "oam-ip-addr": "$.vf-module-topology.vf-module-parameters.param[30].value"
+ }
+ ]
+ },
+ "instanceReferences": {
+ "serviceInstanceId": "c14e61b5-1ee6-4925-b4a9-b9c8dbfe3f34",
+ "vnfInstanceId": "6636c4d5-f608-4376-b6d8-7977e98cb16d",
+ "vfModuleInstanceId": "68804843-18e0-41a3-8838-a6d90a035e1a",
+ "vfModuleInstanceName": "vfModuleName"
+ },
+ "requestStatus": {
+ "requestState": "IN_PROGRESS",
+ "statusMessage": "FLOW STATUS: Execution of ActivateVfModuleBB has completed successfully, next invoking ConfigurationScaleOutBB (Execution Path progress: BBs completed = 4; BBs remaining = 2). TASK INFORMATION: Last task executed: Call SDNC RESOURCE STATUS: The vf module was found to already exist, thus no new vf module was created in the cloud via this request",
+ "percentProgress": 68,
+ "timestamp": "Fri, 15 May 2020 12:13:41 GMT"
+ }
+ }
+ }
+
+An example response received to the poll request, when SO has completed the request:
+
+.. code-block:: bash
+
+ {
+ "request": {
+ "requestId": "70f28791-c271-4cae-b090-0c2a359e26d9",
+ "startTime": "Fri, 15 May 2020 12:12:50 GMT",
+ "finishTime": "Fri, 15 May 2020 12:14:21 GMT",
+ "requestScope": "vfModule",
+ "requestType": "scaleOut",
+ "requestDetails": {
+ "modelInfo": {
+ "modelInvariantId": "2246ebc9-9b9f-42d0-a5e4-0248324fb884",
+ "modelType": "vfModule",
+ "modelName": "VlbCdsSb00..vdns..module-3",
+ "modelVersion": "1",
+ "modelCustomizationUuid": "3a74410a-6c74-4a32-94b2-71488be6da1a",
+ "modelVersionId": "1f94cedb-f656-4ddb-9f55-60ba1fc7d4b1",
+ "modelCustomizationId": "3a74410a-6c74-4a32-94b2-71488be6da1a",
+ "modelUuid": "1f94cedb-f656-4ddb-9f55-60ba1fc7d4b1",
+ "modelInvariantUuid": "2246ebc9-9b9f-42d0-a5e4-0248324fb884"
+ },
+ "requestInfo": {
+ "source": "POLICY",
+ "instanceName": "vfModuleName",
+ "suppressRollback": false,
+ "requestorId": "policy"
+ },
+ "relatedInstanceList": [
+ {
+ "relatedInstance": {
+ "instanceId": "c14e61b5-1ee6-4925-b4a9-b9c8dbfe3f34",
+ "modelInfo": {
+ "modelInvariantId": "6418bb39-61e1-45fc-a36b-3f211bb846c7",
+ "modelType": "service",
+ "modelName": "vLB_CDS_SB00_02",
+ "modelVersion": "1.0",
+ "modelVersionId": "d01d9dec-afb6-4a53-bd9e-2eb10ca07a51",
+ "modelUuid": "d01d9dec-afb6-4a53-bd9e-2eb10ca07a51",
+ "modelInvariantUuid": "6418bb39-61e1-45fc-a36b-3f211bb846c7"
+ }
+ }
+ },
+ {
+ "relatedInstance": {
+ "instanceId": "6636c4d5-f608-4376-b6d8-7977e98cb16d",
+ "modelInfo": {
+ "modelInvariantId": "827356a9-cb60-4976-9713-c30b4f850b41",
+ "modelType": "vnf",
+ "modelName": "vLB_CDS_SB00",
+ "modelVersion": "1.0",
+ "modelCustomizationUuid": "6478f94b-0b20-4b44-afc0-94e48070586a",
+ "modelVersionId": "ca3c4797-0cdd-4797-8bec-9a3ce78ac4da",
+ "modelCustomizationId": "6478f94b-0b20-4b44-afc0-94e48070586a",
+ "modelUuid": "ca3c4797-0cdd-4797-8bec-9a3ce78ac4da",
+ "modelInvariantUuid": "827356a9-cb60-4976-9713-c30b4f850b41"
+ }
+ }
+ }
+ ],
+ "cloudConfiguration": {
+ "tenantId": "41d6d38489bd40b09ea8a6b6b852dcbd",
+ "tenantName": "Integration-SB-00",
+ "cloudOwner": "CloudOwner",
+ "lcpCloudRegionId": "RegionOne"
+ },
+ "requestParameters": {
+ "usePreload": false
+ },
+ "configurationParameters": [
+ {
+ "ip-addr": "$.vf-module-topology.vf-module-parameters.param[16].value",
+ "oam-ip-addr": "$.vf-module-topology.vf-module-parameters.param[30].value"
+ }
+ ]
+ },
+ "instanceReferences": {
+ "serviceInstanceId": "c14e61b5-1ee6-4925-b4a9-b9c8dbfe3f34",
+ "vnfInstanceId": "6636c4d5-f608-4376-b6d8-7977e98cb16d",
+ "vfModuleInstanceId": "68804843-18e0-41a3-8838-a6d90a035e1a",
+ "vfModuleInstanceName": "vfModuleName"
+ },
+ "requestStatus": {
+ "requestState": "COMPLETE",
+ "statusMessage": "STATUS: ALaCarte-VfModule-scaleOut request was executed correctly. FLOW STATUS: Successfully completed all Building Blocks RESOURCE STATUS: The vf module was found to already exist, thus no new vf module was created in the cloud via this request",
+ "percentProgress": 100,
+ "timestamp": "Fri, 15 May 2020 12:14:21 GMT"
+ }
+ }
+ }
+
+
+Configuration of the SO Actor
+###############################
+
+The following table specifies the fields that should be provided to configure the SO
+actor.
+
+=============================== ==================== ==================================================================
+Field name type Description
+=============================== ==================== ==================================================================
+clientName string Name of the HTTP client to use to send the request to the
+ SO REST server.
+timeoutSec integer (optional) Maximum time, in seconds, to wait for a response to be received
+ from the REST server. Defaults to 90s.
+path string URI appended to the URL. This field only applies to individual
+ operations; it does not apply at the actor level. Note: the
+ *path* should not include a leading or trailing slash.
+maxGets integer (optional) Maximum number of get/poll requests to make to determine the
+ final outcome of the request. Defaults to 20.
+waitSecGet integer (optional) Time, in seconds, to wait between issuing "get" requests.
+ Defaults to 20s.
+pathGet string (optional) Path to use when polling (i.e., issuing "get" requests).
+ Note: this should include a trailing slash, but no leading
+ slash.
+=============================== ==================== ==================================================================
+
+The individual operations are configured using these same field names. However, all
+of them, except the *path*, are optional, as they inherit their values from the
+corresponding actor-level fields.
diff --git a/docs/development/actors/topview.png b/docs/development/actors/topview.png
new file mode 100644
index 00000000..a7e5b166
--- /dev/null
+++ b/docs/development/actors/topview.png
Binary files differ
diff --git a/docs/development/actors/topview.pptx b/docs/development/actors/topview.pptx
new file mode 100644
index 00000000..16ff2249
--- /dev/null
+++ b/docs/development/actors/topview.pptx
Binary files differ
diff --git a/docs/development/actors/vfc/vfc.rst b/docs/development/actors/vfc/vfc.rst
new file mode 100644
index 00000000..e7d8d3e7
--- /dev/null
+++ b/docs/development/actors/vfc/vfc.rst
@@ -0,0 +1,169 @@
+.. This work is licensed under a
+.. Creative Commons Attribution 4.0 International License.
+.. http://creativecommons.org/licenses/by/4.0
+
+.. _vfc-label:
+
+##########
+VFC Actor
+##########
+
+.. contents::
+ :depth: 3
+
+Overview of VFC Actor
+######################
+ONAP Policy Framework enables VFC as one of the supported actors.
+
+.. note::
+There has not been any support given to the Policy Framework project for the VFC Actor
+in several releases. Thus, the code and information provided is to the best of the
+knowledge of the team. If there are any questions or problems, please consult the VFC
+Project to help provide guidance.
+
+VFC uses a REST-based
+interface. However, as requests may not complete right away, a REST-based polling
+interface is used to check the status of the request. The *jobId* is extracted
+from each response and is appended to the *pathGet* configuration parameter to
+generate the URL used to poll for completion.
+
+Each operation supported by the actor is associated with its own java class, which is
+responsible for populating the request structure appropriately and sending the request.
+The operation-specific classes are all derived from the *VfcOperation* class, which is,
+itself, derived from *HttpOperation*. The following operations are currently supported:
+
+- Restart
+
+
+Request
+#######
+
+A number of nested structures are populated within the request. Several of them are
+populated from items found within the A&AI "enrichment" data provided by DCAE with
+the ONSET event. The following table lists the contents of some of the fields that
+appear within these structures.
+
++----------------------------------+---------+----------------------------------------------------------------------+
+| Field Name | Type | Description |
++----------------------------------+---------+----------------------------------------------------------------------+
++----------------------------------+---------+----------------------------------------------------------------------+
+| top level: | | |
++----------------------------------+---------+----------------------------------------------------------------------+
+| *requestId* | string | Inserted by Policy. Maps to the UUID sent by DCAE i.e. the ID |
+| | | used throughout the closed loop lifecycle to identify a request. |
++----------------------------------+---------+----------------------------------------------------------------------+
+| *nsInstanceId* | string | Set by Policy, using the |
+| | | "service-instance.service-instance-id" property |
+| | | found within the enrichment data. |
++----------------------------------+---------+----------------------------------------------------------------------+
++----------------------------------+---------+----------------------------------------------------------------------+
+| healVnfData: | | |
++----------------------------------+---------+----------------------------------------------------------------------+
+| *cause* | string | Set by Policy to the name of the operation. |
++----------------------------------+---------+----------------------------------------------------------------------+
+| *vnfInstanceId* | string | Set by Policy, using the |
+| | | "generic-vnf.vnf-id" property |
+| | | found within the enrichment data. |
++----------------------------------+---------+----------------------------------------------------------------------+
++----------------------------------+---------+----------------------------------------------------------------------+
+| additionalParams: | | |
++----------------------------------+---------+----------------------------------------------------------------------+
+| *action* | | Set by Policy to the name of the operation. |
++----------------------------------+---------+----------------------------------------------------------------------+
++----------------------------------+---------+----------------------------------------------------------------------+
+| actionvminfo: | | |
++----------------------------------+---------+----------------------------------------------------------------------+
+| *vmid* | string | Set by Policy, using the |
+| | | "vserver.vserver-id" property |
+| | | found within the enrichment data. |
++----------------------------------+---------+----------------------------------------------------------------------+
+| *vmname* | string | Set by Policy, using the |
+| | | "vserver.vserver-name" property |
+| | | found within the enrichment data. |
++----------------------------------+---------+----------------------------------------------------------------------+
+
+
+Examples
+########
+
+Suppose the *ControlLoopOperationParams* were populated as follows:
+
+.. code-block:: bash
+
+ {
+ TBD
+ }
+
+An example of a request constructed by the actor using the above parameters, sent to the
+VFC REST server:
+
+.. code-block:: bash
+
+ {
+ TBD
+ }
+
+An example response received to the initial request, from the VFC REST service:
+
+.. code-block:: bash
+
+ {
+ TBD
+ }
+
+An example URL used for the "get" (i.e., poll) request subsequently sent to VFC:
+
+.. code-block:: bash
+
+ TBD
+
+An example response received to the poll request, when VFC has not completed the request:
+
+.. code-block:: bash
+
+ {
+ TBD
+ }
+
+An example response received to the poll request, when VFC has completed the request:
+
+.. code-block:: bash
+
+ {
+ TBD
+ }
+
+
+Configuration of the VFC Actor
+###############################
+
+The following table specifies the fields that should be provided to configure the VFC
+actor.
+
+=============================== ==================== ==================================================================
+Field name type Description
+=============================== ==================== ==================================================================
+clientName string Name of the HTTP client to use to send the request to the
+ VFC REST server.
+timeoutSec integer (optional) Maximum time, in seconds, to wait for a response to be received
+ from the REST server. Defaults to 90s.
+=============================== ==================== ==================================================================
+
+The individual operations are configured using these same field names. However, all
+of them are optional, as they inherit their values from the
+corresponding actor-level fields. The following additional fields are specified at
+the individual operation level.
+
+=============================== ==================== ===================================================================
+Field name type Description
+=============================== ==================== ===================================================================
+path string URI appended to the URL. Note: this
+ should not include a leading or trailing slash.
+maxGets integer (optional) Maximum number of get/poll requests to make to determine the
+ final outcome of the request. Defaults to 0 (i.e., no polling).
+waitSecGet integer Time, in seconds, to wait between issuing "get" requests.
+ Defaults to 20s.
+pathGet string Path to use when polling (i.e., issuing "get" requests).
+ Note: this should include a trailing slash, but no leading
+ slash.
+=============================== ==================== ===================================================================