From 0fa019897cb79de1def349b8fd0b660d1951681a Mon Sep 17 00:00:00 2001 From: efiacor Date: Mon, 8 Apr 2019 14:52:08 +0000 Subject: [PATCH] Adding docs for CADI Change-Id: If3324973a2e41ca0d98804cb8e6520fc1beccfe9 Issue-ID: DMAAP-1016 Signed-off-by: efiacor --- .../src/main/resources/database/sql_init_01.sql | 2 +- .../src/main/resources/misc/sql_init_01.sql | 2 +- datarouter-prov/src/test/resources/create.sql | 2 +- docs/architecture.rst | 56 + docs/configuration.rst | 43 + docs/data-router/DataRouterUserGuide.rst | 25 - docs/data-router/administration.rst | 14 - docs/data-router/architecture.rst | 25 - docs/data-router/configuration.rst | 7 - docs/data-router/consumedapis.rst | 7 - docs/data-router/data-router.rst | 1176 ----------------- docs/data-router/dr_arch.png | Bin 35750 -> 0 bytes docs/data-router/humaninterfaces.rst | 10 - docs/{data-router => }/delivery.rst | 2 +- docs/images/dr_arch_only.png | Bin 0 -> 17291 bytes docs/images/dr_bc_prov.png | Bin 0 -> 51556 bytes docs/images/dr_pub_flow.png | Bin 0 -> 72010 bytes docs/index.rst | 35 +- docs/installation.rst | 51 + docs/{data-router => }/logging.rst | 6 +- docs/offered-apis.rst | 1350 ++++++++++++++++++++ docs/{data-router => }/release-notes.rst | 67 +- 22 files changed, 1551 insertions(+), 1329 deletions(-) create mode 100644 docs/architecture.rst create mode 100644 docs/configuration.rst delete mode 100644 docs/data-router/DataRouterUserGuide.rst delete mode 100644 docs/data-router/administration.rst delete mode 100644 docs/data-router/architecture.rst delete mode 100644 docs/data-router/configuration.rst delete mode 100644 docs/data-router/consumedapis.rst delete mode 100755 docs/data-router/data-router.rst delete mode 100644 docs/data-router/dr_arch.png delete mode 100644 docs/data-router/humaninterfaces.rst rename docs/{data-router => }/delivery.rst (80%) create mode 100644 docs/images/dr_arch_only.png create mode 100644 docs/images/dr_bc_prov.png create mode 100644 docs/images/dr_pub_flow.png create mode 100644 docs/installation.rst rename docs/{data-router => }/logging.rst (91%) create mode 100755 docs/offered-apis.rst rename docs/{data-router => }/release-notes.rst (99%) diff --git a/datarouter-docker-compose/src/main/resources/database/sql_init_01.sql b/datarouter-docker-compose/src/main/resources/database/sql_init_01.sql index 83dfd0bc..88434180 100644 --- a/datarouter-docker-compose/src/main/resources/database/sql_init_01.sql +++ b/datarouter-docker-compose/src/main/resources/database/sql_init_01.sql @@ -3,7 +3,7 @@ use datarouter; CREATE TABLE FEEDS ( FEEDID INT UNSIGNED NOT NULL PRIMARY KEY, GROUPID INT(10) UNSIGNED NOT NULL DEFAULT 0, - NAME VARCHAR(255) NOT NULL, + NAME VARCHAR(256) NOT NULL, VERSION VARCHAR(20) NULL, DESCRIPTION VARCHAR(1000), BUSINESS_DESCRIPTION VARCHAR(1000) DEFAULT NULL, diff --git a/datarouter-prov/src/main/resources/misc/sql_init_01.sql b/datarouter-prov/src/main/resources/misc/sql_init_01.sql index 55f0aee9..a1980d29 100755 --- a/datarouter-prov/src/main/resources/misc/sql_init_01.sql +++ b/datarouter-prov/src/main/resources/misc/sql_init_01.sql @@ -1,7 +1,7 @@ CREATE TABLE FEEDS ( FEEDID INT UNSIGNED NOT NULL PRIMARY KEY, GROUPID INT(10) UNSIGNED NOT NULL DEFAULT 0, - NAME VARCHAR(255) NOT NULL, + NAME VARCHAR(256) NOT NULL, VERSION VARCHAR(20) NULL, DESCRIPTION VARCHAR(1000), BUSINESS_DESCRIPTION VARCHAR(1000) DEFAULT NULL, diff --git a/datarouter-prov/src/test/resources/create.sql b/datarouter-prov/src/test/resources/create.sql index 1fb30c90..7c106723 100755 --- a/datarouter-prov/src/test/resources/create.sql +++ b/datarouter-prov/src/test/resources/create.sql @@ -1,7 +1,7 @@ CREATE TABLE FEEDS ( FEEDID INT UNSIGNED NOT NULL PRIMARY KEY, GROUPID INT(10) UNSIGNED NOT NULL DEFAULT 0, - NAME VARCHAR(255) NOT NULL, + NAME VARCHAR(256) NOT NULL, VERSION VARCHAR(20) NULL, DESCRIPTION VARCHAR(1000), BUSINESS_DESCRIPTION VARCHAR(1000) DEFAULT NULL, diff --git a/docs/architecture.rst b/docs/architecture.rst new file mode 100644 index 00000000..6f29e5d4 --- /dev/null +++ b/docs/architecture.rst @@ -0,0 +1,56 @@ +.. This work is licensed under a Creative Commons Attribution 4.0 International License. +.. http://creativecommons.org/licenses/by/4.0 + +Architecture +============ + +Capabilities +------------ +The DMaaP Data Router (DR) provisioning API is an HTTPS-based, REST-like API for creating and managing +DR feeds and subscriptions, which provides a pub/sub architectural model for the transfer of data. + +The DR API also supports `AAF CADI authorization `_. + +To use this feature, the API client must provide a valid AAF AppID / MechID with each request. +To enable this feature, see the :ref:`configuration` section. + +.. note:: In future releases, AAF CADI auth will be enabled by default. + +Usage Scenarios +--------------- +Typically, DR pub clients request the provisioning of a new DR feed. +Once created, DR sub clients can then subscribe to the feed to receive all data published to that feed. + + .. image:: images/dr_pub_flow.png + + +The DR provisioning API is not meant to be used directly by DR end users (publishers and subscribers) +for feed / subscription CRUD (create, read, update, delete) operations. + +Instead, prospective publishers and subscribers should use the DMaaP Bus Controller API, which will call +the DR provisioning API to manage feeds and subscriptions. + + .. image:: images/dr_bc_prov.png + + +See DMaaP Bus Controller API docs for more information: + +`Bus Controller Feeds API `_ + +`Bus Controller Subs API `_ + + +High level Architecture +----------------------- +The following diagram shows the high-level relationship between the system components: + + .. image:: images/dr_arch_only.png + + +DMaaP DR architecture uses the Eclipse Jetty server as an application server to service it's front-end. + * dmaap-dr-prov services all provisioning requests. + * dmaap-dr-node services the publishing of data to feed subscribers. + +DMaaP DR uses MariaDB as it's storage component for the following: + * DR Provisioning data. (feeds, subscribers, etc.) + * Historical logging data related to feed activity. (Publish, Delivery, etc.) \ No newline at end of file diff --git a/docs/configuration.rst b/docs/configuration.rst new file mode 100644 index 00000000..f7fa4bcf --- /dev/null +++ b/docs/configuration.rst @@ -0,0 +1,43 @@ +.. This work is licensed under a Creative Commons Attribution 4.0 International License. +.. http://creativecommons.org/licenses/by/4.0 + +.. _configuration: + +Configuration +============= + +Configuration properties for both Data Router Provisioning server and Data Router Node server should remain as default values. + +The only exception to this, is when enabling the AAF CADI framework to authorize the DR provisioning requests. + +.. note:: The AAF CADI filtering feature is disabled by default. When AAF CADI auth is enabled, all DR API calls must provide an AAF AppID to access the relevant API endpoint. + +To enable DR AAF CADI authorization, the following steps are required: + +DR CADI Prerequisites: + * AAF deployment + +Update the following properties at deployment time. + + +**DMaaP DR Prov AAF properties** + +:: + + # AAF config + org.onap.dmaap.datarouter.provserver.cadi.enabled = true + + # AAF URL to connect to AAF server + org.onap.dmaap.datarouter.provserver.cadi.aaf.url = https://:8095 + + +**DMaaP DR Node AAF properties** + +:: + + # AAF URL to connect to AAF server + AafUrl = https://:8095 + + # AAF CADI enabled flag + CadiEnabled = true + diff --git a/docs/data-router/DataRouterUserGuide.rst b/docs/data-router/DataRouterUserGuide.rst deleted file mode 100644 index 8f7b9ef1..00000000 --- a/docs/data-router/DataRouterUserGuide.rst +++ /dev/null @@ -1,25 +0,0 @@ -=========================== -Data Router (DR) User Guide -=========================== - -Standalone Mode ---------------- - -Installation -============ - -1. Find the datarouter project on the gerrit website: https://gerrit.onap.org/r/#/admin/projects/dmaap/datarouter - -2. Clone the repo onto your server using the clone command found on the datarouter page on gerrit. - -3. cd into the docker-compose directory and run docker-compose up. - -Configurations -============== - -Using the Data Router ---------------------- - -For information on how to use the Data Router refer to the Data Router API guide at: - - :ref:`data_router_api_guide` \ No newline at end of file diff --git a/docs/data-router/administration.rst b/docs/data-router/administration.rst deleted file mode 100644 index b050a1fe..00000000 --- a/docs/data-router/administration.rst +++ /dev/null @@ -1,14 +0,0 @@ -.. This work is licensed under a Creative Commons Attribution 4.0 International License. -.. http://creativecommons.org/licenses/by/4.0 - -Administration -============== - - -Processes ---------- -NA - -Actions -------- -NA diff --git a/docs/data-router/architecture.rst b/docs/data-router/architecture.rst deleted file mode 100644 index b18f7bb3..00000000 --- a/docs/data-router/architecture.rst +++ /dev/null @@ -1,25 +0,0 @@ -.. This work is licensed under a Creative Commons Attribution 4.0 International License. -.. http://creativecommons.org/licenses/by/4.0 - -Architecture -============ - - -Capabilities ------------- -Data Router is a RESTful web service used for the transfer of data across networks any larger than a Message Router message (> 1Mb). - -Usage Scenarios ---------------- - Data Router endpoints are used to create/view/delete Feeds, Subscribers and Published files. Clients can use the Data Router endpoints - to publish a file to a feed and subscribe to this feed to receive the file. - -Interactions ------------- -Data Router REST service uses the Data Router API to allow users to publish to and subscribe to a feed, in order to send and receive files. - - - - |image0| - - .. |image0| image:: dr_arch.png diff --git a/docs/data-router/configuration.rst b/docs/data-router/configuration.rst deleted file mode 100644 index 2a7096a1..00000000 --- a/docs/data-router/configuration.rst +++ /dev/null @@ -1,7 +0,0 @@ -.. This work is licensed under a Creative Commons Attribution 4.0 International License. -.. http://creativecommons.org/licenses/by/4.0 - -Configuration -============= - -NA \ No newline at end of file diff --git a/docs/data-router/consumedapis.rst b/docs/data-router/consumedapis.rst deleted file mode 100644 index aa1a8bd1..00000000 --- a/docs/data-router/consumedapis.rst +++ /dev/null @@ -1,7 +0,0 @@ -.. This work is licensed under a Creative Commons Attribution 4.0 International License. -.. http://creativecommons.org/licenses/by/4.0 - -Consumed APIs -============= - -Data Router does not consume any API diff --git a/docs/data-router/data-router.rst b/docs/data-router/data-router.rst deleted file mode 100755 index 66e13bf5..00000000 --- a/docs/data-router/data-router.rst +++ /dev/null @@ -1,1176 +0,0 @@ -.. _data_router_api_guide: - -========================== -Data Router (DR) API Guide -========================== -Introduction ------------- - -The DataRouter(DR) provisioning API is an HTTPS-based, REST-like API for creating and managing DR feeds -and subscriptions. The DMaaP Data Router System project is intended to provide a common framework by which -data producers can make data available to data consumers and a way for potential consumers to find feeds -with the data they require. - - -HTTP Service APIs ------------------ - -DMaaP Data Router utilizes an HTTP REST API to service all transactions. HTTP and REST standards are followed so -clients as varied as CURL, Java applications and even Web Browsers will work to interact with the Data Router. - -General HTTP Requirements -========================= - -A DMaaP Data Router transactions consists of 4 distinct segments, HTTP URL, HTTP Header, HTTP Body (POST/PUT) -and HTTP Response. The general considerations for each segment are as follows and are required for each -of the specific transactions described in this section. - -HTTP URL -======== - -http[s]://{serverBaseURL}/{resourcePath} - -* The serverBaseURL points to DMaaP Data Router host:port that will service the request. -* The resourcePath specifies the service that the client is attempting to reach. - - -HTTP Header -=========== - -Specifies HTTP Headers, such as Content-Type, that define the parameters of the HTTP Transaction - -HTTP Body -========= - -The HTTP Body contains the feed content when creating a feed. - -Create a Feed -------------- - -**Description**: Creates a unique feed URL to service the publisher/subscriber model. - -Sample Request -============== - -``curl -k -X POST -H "Content-Type:application/vnd.dmaap-dr.feed" -H "X-DMAAP-DR-ON-BEHALF-OF:{user}" --data-ascii @createFeed.json https://{host}:{port}`` - -Request Parameters: -=================== - -+------------------------+---------------------------------+------------------+------------+--------------+-------------+--------------------------------------+ -| Name | Description | Param Type | Data Type | MaxLen | Required | Valid/Example Values | -+========================+=================================+==================+============+==============+=============+======================================+ -| name | Feed name | Body | String | <=20 | Y | | -+------------------------+---------------------------------+------------------+------------+--------------+-------------+--------------------------------------+ -| version | Feed version | Body | String | <=20 | Y | | -+------------------------+---------------------------------+------------------+------------+--------------+-------------+--------------------------------------+ -| description | Feed description | Body | String | <=256 | Y | | -+------------------------+---------------------------------+------------------+------------+--------------+-------------+--------------------------------------+ -| business description | Business description | Body | String | <=256 | Y | | -+------------------------+---------------------------------+------------------+------------+--------------+-------------+--------------------------------------+ -| Authorization | Information for authorizing | Body | Object | | Y | | -| | publishing requests | | | | | | -+------------------------+---------------------------------+------------------+------------+--------------+-------------+--------------------------------------+ -| suspend | Set to true if the feed is in | Body | Boolean | | N | * true | -| | the suspended state | | | | | * false | -+------------------------+---------------------------------+------------------+------------+--------------+-------------+--------------------------------------+ -| group-id | | Body | Integer | | Y | | -| | | | | | | | -+------------------------+---------------------------------+------------------+------------+--------------+-------------+--------------------------------------+ -| content-type | To specify type of message | Header | String | | Y | application/vnd.dmaap-dr.feed | -| | (feed,subscriber,publisher) | | | | | | -+------------------------+---------------------------------+------------------+------------+--------------+-------------+--------------------------------------+ -| X-DMAAP-DR-ON-BEHALF-OF| User id of owner of feed | Header | String | <=8 | Y | username | -+------------------------+---------------------------------+------------------+------------+--------------+-------------+--------------------------------------+ - -Response/Error Codes -==================== - -+------------------------+-------------------------------------------+ -| Response statusCode | Response Description | -+========================+===========================================+ -| 201 | Successful query | -+------------------------+-------------------------------------------+ -| 400 | Bad request - The request is defective in | -| | some way. Possible causes: | -| | | -| | * JSON object in request body does not | -| | conform to the spec. | -| | * Invalid parameter value in query string | -+------------------------+-------------------------------------------+ -| 401 | Indicates that the request was missing the| -| | Authorization header or, if the header | -| | was presented, the credentials were not | -| | acceptable | -+------------------------+-------------------------------------------+ -| 403 | The request failed authorization. | -| | Possible causes: | -| | | -| | * Request originated from an unauthorized | -| | IP address | -| | * Client certificate subject is not on | -| | the API’s authorized list. | -| | * X-DMAAP-DR-ON-BEHALF-OF identity is not | -| | authorized to perform | -+------------------------+-------------------------------------------+ -| 404 | Not Found - The Request-URI does not point| -| | to a resource that is known to the API. | -+------------------------+-------------------------------------------+ -| 405 | Method Not Allowed - The HTTP method in | -| | the request is not supported for the | -| | resource addressed by the Request-URI. | -+------------------------+-------------------------------------------+ -| 415 | Unsupported Media Type - The media type in| -| | the requests Content-Type header is not | -| | appropriate for the request. | -+------------------------+-------------------------------------------+ -| 500 | Internal Server Error - The DR API server | -| | encountered an internal error and could | -| | not complete the request. | -+------------------------+-------------------------------------------+ -| 503 | Service Unavailable - The DR API service | -| | is currently unavailable | -+------------------------+-------------------------------------------+ -| -1 | Failed Delivery | -+------------------------+-------------------------------------------+ - -Sample Body -=========== -.. code-block:: json - - { - "name": "Jettydemo", - "version": "v1.0.0", - "description": "Jettydemo", - "business_description": "Jettydemo", - "suspend": false, - "changeowner": true, - "authorization": { - "classification": "unclassified", - "endpoint_addrs": ["172.18.0.3","192.167.3.42"], - "endpoint_ids": [ - { - "password": "password", - "id": "user" - } - ] - } - } - - -Updating a Feed ---------------- - -**Description**: Update a feed with new parameters. - -Sample Request -============== - -``curl -k -X PUT -H "Content-Type: application/vnd.dmaap-dr.feed" -H "X-DMAAP-DR-ON-BEHALF-OF: {user}" --data-ascii @updateFeed.json --location-trusted https://{host}:{port}/feed/{feedId}`` - -Request Parameters: -=================== - -+------------------------+---------------------------------+------------------+------------+--------------+-------------+--------------------------------------+ -| Name | Description | Param Type | Data Type | MaxLen | Required | Valid/Example Values | -+========================+=================================+==================+============+==============+=============+======================================+ -| description | Feed description | Body | String | <=256 | Y | | -+------------------------+---------------------------------+------------------+------------+--------------+-------------+--------------------------------------+ -| business description | Business description | Body | String | <=256 | Y | | -+------------------------+---------------------------------+------------------+------------+--------------+-------------+--------------------------------------+ -| Authorization | Information for authorizing | Body | Object | | Y | | -| | publishing requests | | | | | | -+------------------------+---------------------------------+------------------+------------+--------------+-------------+--------------------------------------+ -| suspend | Set to true if the feed is in | Body | Boolean | | N | * true | -| | the suspended state | | | | | * false | -+------------------------+---------------------------------+------------------+------------+--------------+-------------+--------------------------------------+ -| group-id | | Body | Integer | | Y | | -| | | | | | | | -+------------------------+---------------------------------+------------------+------------+--------------+-------------+--------------------------------------+ -| content-type | To specify type of message | Header | String | | Y | application/vnd.dmaap-dr.feed | -| | (feed,subscriber,publisher) | | | | | | -+------------------------+---------------------------------+------------------+------------+--------------+-------------+--------------------------------------+ -| X-DMAAP-DR-ON-BEHALF-OF| User id of owner of feed | Header | String | <=8 | Y | username | -+------------------------+---------------------------------+------------------+------------+--------------+-------------+--------------------------------------+ - -Response/Error Codes -==================== - -+------------------------+-------------------------------------------+ -| Response statusCode | Response Description | -+========================+===========================================+ -| 200 | Successful query | -+------------------------+-------------------------------------------+ -| 400 | Bad request - The request is defective in | -| | some way. Possible causes: | -| | | -| | * JSON object in request body does not | -| | conform to the spec. | -| | * Invalid parameter value in query string | -+------------------------+-------------------------------------------+ -| 401 | Indicates that the request was missing the| -| | Authorization header or, if the header | -| | was presented, the credentials were not | -| | acceptable | -+------------------------+-------------------------------------------+ -| 403 | The request failed authorization. | -| | Possible causes: | -| | | -| | * Request originated from an unauthorized | -| | IP address | -| | * Client certificate subject is not on | -| | the API’s authorized list. | -| | * X-DMAAP-DR-ON-BEHALF-OF identity is not | -| | authorized to perform | -+------------------------+-------------------------------------------+ -| 404 | Not Found - The Request-URI does not point| -| | to a resource that is known to the API. | -+------------------------+-------------------------------------------+ -| 405 | Method Not Allowed - The HTTP method in | -| | the request is not supported for the | -| | resource addressed by the Request-URI. | -+------------------------+-------------------------------------------+ -| 415 | Unsupported Media Type - The media type in| -| | the request’s Content-Type header is not | -| | appropriate for the request. | -+------------------------+-------------------------------------------+ -| 500 | Internal Server Error - The DR API server | -| | encountered an internal error and could | -| | not complete the request. | -+------------------------+-------------------------------------------+ -| 503 | Service Unavailable - The DR API service | -| | is currently unavailable | -+------------------------+-------------------------------------------+ -| -1 | Failed Delivery | -+------------------------+-------------------------------------------+ - -Sample Body -=========== -.. code-block:: json - - { - "name": "Jettydemo", - "version": "v1.0.0", - "description": "Updated decription", - "business_description": "Updated business description", - "suspend": false, - "changeowner": true, - "authorization": { - "classification": "unclassified", - "endpoint_addrs": ["172.18.0.3","192.167.3.42"], - "endpoint_ids": [ - { - "password": "password", - "id": "user" - } - ] - } - } - - -Get a Feed ----------- - -**Description**: Retrieves a representation of the specified feed. - -Request URL -=========== - -http[s]://{host}:{port}/feed/{feedId} - -* {feedId}: Id of the feed you want to see a representation of - -Sample Request -============== - -``curl -k -H "X-DMAAP-DR-ON-BEHALF-OF: {user}" https://{host}:{port}/feed/{feedId}`` - -Response/Error Codes -==================== - -+------------------------+-------------------------------------------+ -| Response statusCode | Response Description | -+========================+===========================================+ -| 200 | Successful query | -+------------------------+-------------------------------------------+ -| 401 | Indicates that the request was missing the| -| | Authorization header or, if the header | -| | was presented, the credentials were not | -| | acceptable | -+------------------------+-------------------------------------------+ -| 403 | The request failed authorization. | -| | Possible causes: | -| | | -| | * Request originated from an unauthorized | -| | IP address | -| | * Client certificate subject is not on | -| | the API’s authorized list. | -| | * X-DMAAP-DR-ON-BEHALF-OF identity is not | -| | authorized to perform | -+------------------------+-------------------------------------------+ -| 404 | Not Found - The Request-URI does not point| -| | to a resource that is known to the API. | -+------------------------+-------------------------------------------+ -| 405 | Method Not Allowed - The HTTP method in | -| | the request is not supported for the | -| | resource addressed by the Request-URI. | -+------------------------+-------------------------------------------+ -| 415 | Unsupported Media Type - The media type in| -| | the request’s Content-Type header is not | -| | appropriate for the request. | -+------------------------+-------------------------------------------+ -| 500 | Internal Server Error - The DR API server | -| | encountered an internal error and could | -| | not complete the request. | -+------------------------+-------------------------------------------+ -| 503 | Service Unavailable - The DR API service | -| | is currently unavailable | -+------------------------+-------------------------------------------+ -| -1 | Failed Delivery | -+------------------------+-------------------------------------------+ - -Delete a Feed -------------- - -**Description**: Deletes a specified feed - -Request URL -=========== - -http[s]://{host}:{port}/feed/{feedId} - -* {feedId}: Id of the feed you want to delete - -Sample Request -============== - -``curl -k -X DELETE -H "X-DMAAP-DR-ON-BEHALF-OF: {user}" https://{host}:{port}/feed/{feedId}`` - -Response/Error Codes -==================== - -+------------------------+-------------------------------------------+ -| Response statusCode | Response Description | -+========================+===========================================+ -| 204 | Successful query | -+------------------------+-------------------------------------------+ -| 401 | Indicates that the request was missing the| -| | Authorization header or, if the header | -| | was presented, the credentials were not | -| | acceptable | -+------------------------+-------------------------------------------+ -| 403 | The request failed authorization. | -| | Possible causes: | -| | | -| | * Request originated from an unauthorized | -| | IP address | -| | * Client certificate subject is not on | -| | the API’s authorized list. | -| | * X-DMAAP-DR-ON-BEHALF-OF identity is not | -| | authorized to perform | -+------------------------+-------------------------------------------+ -| 404 | Not Found - The Request-URI does not point| -| | to a resource that is known to the API. | -+------------------------+-------------------------------------------+ -| 405 | Method Not Allowed - The HTTP method in | -| | the request is not supported for the | -| | resource addressed by the Request-URI. | -+------------------------+-------------------------------------------+ -| 415 | Unsupported Media Type - The media type in| -| | the request’s Content-Type header is not | -| | appropriate for the request. | -+------------------------+-------------------------------------------+ -| 500 | Internal Server Error - The DR API server | -| | encountered an internal error and could | -| | not complete the request. | -+------------------------+-------------------------------------------+ -| 503 | Service Unavailable - The DR API service | -| | is currently unavailable | -+------------------------+-------------------------------------------+ -| -1 | Failed Delivery | -+------------------------+-------------------------------------------+ - - -Subscribe to Feed ------------------ - -**Description**: Subscribes to a created feed to receive files published to that feed. - -Request URL -=========== - -http[s]://{host}:{port}/subscribe/{feedId} - -* {feedId}: Id of the feed to subscribe to - -Sample Request -============== - -``curl -k -X POST -H "Content-Type:application/vnd.dmaap-dr.subscription" -H "X-DMAAP-DR-ON-BEHALF-OF:{user}" --data-ascii @addSubscriber.json https://{host}:{port}/subscribe/{feedId}`` - -Request Parameters: -=================== - -+------------------------+---------------------------------+------------------+------------+--------------+-------------+--------------------------------------+ -| Name | Description | Param Type | Data Type | MaxLen | Required | Valid/Example Values | -+========================+=================================+==================+============+==============+=============+======================================+ -| feedId | ID for the feed you are | Path | String | | Y | | -| | subscribing to | | | | | | -+------------------------+---------------------------------+------------------+------------+--------------+-------------+--------------------------------------+ -| delivery | Address and credentials for | Body | Object | | Y | | -| | delivery | | | | | | -+------------------------+---------------------------------+------------------+------------+--------------+-------------+--------------------------------------+ -| follow_redirect | Set to true if feed redirection | Body | Boolean | | Y | * true | -| | is expected | | | | | * false | -+------------------------+---------------------------------+------------------+------------+--------------+-------------+--------------------------------------+ -| metadata_only | Set to true if subscription is | Body | Boolean | | Y | * true | -| | to receive per-file metadata | | | | | * false | -+------------------------+---------------------------------+------------------+------------+--------------+-------------+--------------------------------------+ -| suspend | Set to true if the subscription | Body | Boolean | | N | * true | -| | is in the suspended state | | | | | * false | -+------------------------+---------------------------------+------------------+------------+--------------+-------------+--------------------------------------+ -| decompress | Set to true if the data is to | Body | Boolean | | N | * true | -| | be decompressed for subscriber | | | | | * false | -+------------------------+---------------------------------+------------------+------------+--------------+-------------+--------------------------------------+ -| group-id | | Body | Integer | | Y | | -| | | | | | | | -+------------------------+---------------------------------+------------------+------------+--------------+-------------+--------------------------------------+ -| content-type | To specify type of message | Header | String | | Y | application/vnd.dmaap-dr.subscription| -| | (feed,subscriber,publisher) | | | | | | -+------------------------+---------------------------------+------------------+------------+--------------+-------------+--------------------------------------+ -| X-DMAAP-DR-ON-BEHALF-OF| User id of subscriber | Header | String | <=8 | Y | username | -+------------------------+---------------------------------+------------------+------------+--------------+-------------+--------------------------------------+ - -Response/Error Codes -==================== - -+------------------------+-------------------------------------------+ -| Response statusCode | Response Description | -+========================+===========================================+ -| 201 | Successful query | -+------------------------+-------------------------------------------+ -| 400 | Bad request - The request is defective in | -| | some way. Possible causes: | -| | | -| | * JSON object in request body does not | -| | conform to the spec. | -| | * Invalid parameter value in query string | -+------------------------+-------------------------------------------+ -| 401 | Indicates that the request was missing the| -| | Authorization header or, if the header | -| | was presented, the credentials were not | -| | acceptable | -+------------------------+-------------------------------------------+ -| 403 | The request failed authorization. | -| | Possible causes: | -| | | -| | * Request originated from an unauthorized | -| | IP address | -| | * Client certificate subject is not on | -| | the API’s authorized list. | -| | * X-DMAAP-DR-ON-BEHALF-OF identity is not | -| | authorized to perform | -+------------------------+-------------------------------------------+ -| 404 | Not Found - The Request-URI does not point| -| | to a resource that is known to the API. | -+------------------------+-------------------------------------------+ -| 405 | Method Not Allowed - The HTTP method in | -| | the request is not supported for the | -| | resource addressed by the Request-URI. | -+------------------------+-------------------------------------------+ -| 415 | Unsupported Media Type - The media type in| -| | the requests Content-Type header is not | -| | appropriate for the request. | -+------------------------+-------------------------------------------+ -| 500 | Internal Server Error - The DR API server | -| | encountered an internal error and could | -| | not complete the request. | -+------------------------+-------------------------------------------+ -| 503 | Service Unavailable - The DR API service | -| | is currently unavailable | -+------------------------+-------------------------------------------+ -| -1 | Failed Delivery | -+------------------------+-------------------------------------------+ - -Sample Body -=========== -.. code-block:: json - - { - "delivery" :{ - "url" : "http://172.18.0.3:7070/", - "user" : "LOGIN", - "password" : "PASSWORD", - "use100" : true - }, - "metadataOnly" : false, - "groupid" : 1, - "subscriber" : "subuser" - } - -Update subscription -------------------- - -**Description**: Update a subscription to a feed. - -Request URL -=========== - -http[s]://{host}:{port}/subs/{subId} - -* {subId}: Id of the subscription to be updated - -Sample Request -============== - -``curl -k -X PUT -H "Content-Type:application/vnd.dmaap-dr.subscription" -H "X-DMAAP-DR-ON-BEHALF-OF:{user}" --data-ascii @updateSubscriber.json https://{host}:{port}/subs/{subId}`` - -Request Parameters: -=================== - -+------------------------+---------------------------------+------------------+------------+--------------+-------------+--------------------------------------+ -| Name | Description | Param Type | Data Type | MaxLen | Required | Valid/Example Values | -+========================+=================================+==================+============+==============+=============+======================================+ -| subId | ID for the subscription you are | Path | String | | Y | | -| | updating | | | | | | -+------------------------+---------------------------------+------------------+------------+--------------+-------------+--------------------------------------+ -| delivery | Address and credentials for | Body | Object | | Y | | -| | delivery | | | | | | -+------------------------+---------------------------------+------------------+------------+--------------+-------------+--------------------------------------+ -| follow_redirect | Set to true if feed redirection | Body | Boolean | | Y | * true | -| | is expected | | | | | * false | -+------------------------+---------------------------------+------------------+------------+--------------+-------------+--------------------------------------+ -| metadata_only | Set to true if subscription is | Body | Boolean | | Y | * true | -| | to receive per-file metadata | | | | | * false | -+------------------------+---------------------------------+------------------+------------+--------------+-------------+--------------------------------------+ -| suspend | Set to true if the subscription | Body | Boolean | | N | * true | -| | is in the suspended state | | | | | * false | -+------------------------+---------------------------------+------------------+------------+--------------+-------------+--------------------------------------+ -| decompress | Set to true if the data is to | Body | Boolean | | N | * true | -| | be decompressed for subscriber | | | | | * false | -+------------------------+---------------------------------+------------------+------------+--------------+-------------+--------------------------------------+ -| group-id | | Body | Integer | | Y | | -| | | | | | | | -+------------------------+---------------------------------+------------------+------------+--------------+-------------+--------------------------------------+ -| content-type | To specify type of message | Header | String | | Y | application/vnd.dmaap-dr.subscription| -| | (feed,subscriber,publisher) | | | | | | -+------------------------+---------------------------------+------------------+------------+--------------+-------------+--------------------------------------+ -| X-DMAAP-DR-ON-BEHALF-OF| User id of subscriber | Header | String | 8 | Y | username | -+------------------------+---------------------------------+------------------+------------+--------------+-------------+--------------------------------------+ - -Response/Error Codes -==================== - -+------------------------+-------------------------------------------+ -| Response statusCode | Response Description | -+========================+===========================================+ -| 200 | Successful query | -+------------------------+-------------------------------------------+ -| 400 | Bad request - The request is defective in | -| | some way. Possible causes: | -| | | -| | * JSON object in request body does not | -| | conform to the spec. | -| | * Invalid parameter value in query string | -+------------------------+-------------------------------------------+ -| 401 | Indicates that the request was missing the| -| | Authorization header or, if the header | -| | was presented, the credentials were not | -| | acceptable | -+------------------------+-------------------------------------------+ -| 403 | The request failed authorization. | -| | Possible causes: | -| | | -| | * Request originated from an unauthorized | -| | IP address | -| | * Client certificate subject is not on | -| | the API’s authorized list. | -| | * X-DMAAP-DR-ON-BEHALF-OF identity is not | -| | authorized to perform | -+------------------------+-------------------------------------------+ -| 404 | Not Found - The Request-URI does not point| -| | to a resource that is known to the API. | -+------------------------+-------------------------------------------+ -| 405 | Method Not Allowed - The HTTP method in | -| | the request is not supported for the | -| | resource addressed by the Request-URI. | -+------------------------+-------------------------------------------+ -| 415 | Unsupported Media Type - The media type in| -| | the request’s Content-Type header is not | -| | appropriate for the request. | -+------------------------+-------------------------------------------+ -| 500 | Internal Server Error - The DR API server | -| | encountered an internal error and could | -| | not complete the request. | -+------------------------+-------------------------------------------+ -| 503 | Service Unavailable - The DR API service | -| | is currently unavailable | -+------------------------+-------------------------------------------+ -| -1 | Failed Delivery | -+------------------------+-------------------------------------------+ - -Sample Body -=========== -.. code-block:: json - - { - "delivery" :{ - "url" : "http://192.0.0.1:7070/", - "user" : "NEW_LOGIN", - "password" : "NEW_PASSWORD", - "use100" : true - }, - "metadataOnly" : false, - "groupid" : 2, - "subscriber" : "subuser" - } - - -Get a Subscription ------------------- - -**Description**: Retrieves a representation of the specified subscription. - -Request URL -=========== - -http[s]://{host}:{port}/subs/{subId} - -* {subId}: Id of the subscription you want to see a representation of - -Sample Request -============== - -``curl -k -H "X-DMAAP-DR-ON-BEHALF-OF:{user}" https://{host}:{port}/subs/{subId}`` - -Response/Error Codes -==================== - -+------------------------+-------------------------------------------+ -| Response statusCode | Response Description | -+========================+===========================================+ -| 200 | Successful query | -+------------------------+-------------------------------------------+ -| 401 | Indicates that the request was missing the| -| | Authorization header or, if the header | -| | was presented, the credentials were not | -| | acceptable | -+------------------------+-------------------------------------------+ -| 403 | The request failed authorization. | -| | Possible causes: | -| | | -| | * Request originated from an unauthorized | -| | IP address | -| | * Client certificate subject is not on | -| | the API’s authorized list. | -| | * X-DMAAP-DR-ON-BEHALF-OF identity is not | -| | authorized to perform | -+------------------------+-------------------------------------------+ -| 404 | Not Found - The Request-URI does not point| -| | to a resource that is known to the API. | -+------------------------+-------------------------------------------+ -| 405 | Method Not Allowed - The HTTP method in | -| | the request is not supported for the | -| | resource addressed by the Request-URI. | -+------------------------+-------------------------------------------+ -| 415 | Unsupported Media Type - The media type in| -| | the request’s Content-Type header is not | -| | appropriate for the request. | -+------------------------+-------------------------------------------+ -| 500 | Internal Server Error - The DR API server | -| | encountered an internal error and could | -| | not complete the request. | -+------------------------+-------------------------------------------+ -| 503 | Service Unavailable - The DR API service | -| | is currently unavailable | -+------------------------+-------------------------------------------+ -| -1 | Failed Delivery | -+------------------------+-------------------------------------------+ - -Delete a subscription ---------------------- - -**Description**: Deletes a specified subscription - -Request URL -=========== - -http[s]://{host}:{port}/subs/{subId} - -* {subId}: Id of the subscription you want to delete - -Sample Request -============== - -``curl -k -X DELETE -H "X-DMAAP-DR-ON-BEHALF-OF:{user}" https://{host}:{port}/subs/{subId}`` - -Response/Error Codes -==================== - -+------------------------+-------------------------------------------+ -| Response statusCode | Response Description | -+========================+===========================================+ -| 204 | Successful query | -+------------------------+-------------------------------------------+ -| 401 | Indicates that the request was missing the| -| | Authorization header or, if the header | -| | was presented, the credentials were not | -| | acceptable | -+------------------------+-------------------------------------------+ -| 403 | The request failed authorization. | -| | Possible causes: | -| | | -| | * Request originated from an unauthorized | -| | IP address | -| | * Client certificate subject is not on | -| | the API’s authorized list. | -| | * X-DMAAP-DR-ON-BEHALF-OF identity is not | -| | authorized to perform | -+------------------------+-------------------------------------------+ -| 404 | Not Found - The Request-URI does not point| -| | to a resource that is known to the API. | -+------------------------+-------------------------------------------+ -| 405 | Method Not Allowed - The HTTP method in | -| | the request is not supported for the | -| | resource addressed by the Request-URI. | -+------------------------+-------------------------------------------+ -| 415 | Unsupported Media Type - The media type in| -| | the request’s Content-Type header is not | -| | appropriate for the request. | -+------------------------+-------------------------------------------+ -| 500 | Internal Server Error - The DR API server | -| | encountered an internal error and could | -| | not complete the request. | -+------------------------+-------------------------------------------+ -| 503 | Service Unavailable - The DR API service | -| | is currently unavailable | -+------------------------+-------------------------------------------+ -| -1 | Failed Delivery | -+------------------------+-------------------------------------------+ - -Publish to Feed ---------------- - -**Description**: Publish data to a given feed - -Request URL -=========== - -http[s]://{host}:{port}/publish/{feedId}/{fileName} - -* {feedId} The id of the feed you are publishing to. -* {fileId} The name of the file you are publishing to the feed. - -Sample Request -============== - -``curl -k -X PUT --user {user}:{password} -H "Content-Type:application/octet-stream" -H "X-DMAAP-DR-META:{\"filetype\":\"txt\"}" --data-binary @sampleFile.txt --post301 --location-trusted https://{host}:{port}/publish/{feedId}/sampleFile`` - -Request parameters -================== - -+------------------------+---------------------------------+------------------+------------+--------------+-------------+--------------------------------------------------------------------------+ -| Name | Description | Param Type | Data Type | MaxLen | Required | Valid/Example Values | -+========================+=================================+==================+============+==============+=============+==========================================================================+ -| feedId | ID of the feed you are | Path | String | | Y | | -| | publishing to | | | | | | -+------------------------+---------------------------------+------------------+------------+--------------+-------------+--------------------------------------------------------------------------+ -| fileId | Name of the file when it is | Path | String | | Y | | -| | published to subscribers | | | | | | -+------------------------+---------------------------------+------------------+------------+--------------+-------------+--------------------------------------------------------------------------+ -| content-type | To specify type of message | Header | String | | Y | application/octet-stream | -| | format | | | | | | -+------------------------+---------------------------------+------------------+------------+--------------+-------------+--------------------------------------------------------------------------+ -| X-DMAAP-DR-META | Metadata for the file. Accepts | Header | String | 4096 | N | '{"compressionType":"gzip","id": 1234, "transferred":true, "size":null}' | -| | only non nested json objects | | | | | | -| | of the following type : | | | | | | -| | -Numbers | | | | | | -| | -Strings | | | | | | -| | -Lowercase boolean | | | | | | -| | -null | | | | | | -+------------------------+---------------------------------+------------------+------------+--------------+-------------+--------------------------------------------------------------------------+ - -Response/Error Codes -==================== - -+------------------------+---------------------------------+ -| Response statusCode | Response Description | -+========================+=================================+ -| 204 | Successful PUT or DELETE | -+------------------------+---------------------------------+ -| 400 | Failure - Malformed request | -+------------------------+---------------------------------+ -| 401 | Failure - Request was missing | -| | authorization header, or | -| | credentials were not accepted | -+------------------------+---------------------------------+ -| 403 | Failure - User could not be | -| | authenticated, or was not | -| | authorized to make the request | -+------------------------+---------------------------------+ -| 404 | Failure - Path in the request | -| | URL did not point to a valid | -| | feed publishing URL | -+------------------------+---------------------------------+ -| 500 | Failure - DR experienced an | -| | internal problem | -+------------------------+---------------------------------+ -| 503 | Failure - DR is not currently | -| | available | -+------------------------+---------------------------------+ - - -Delete a Published file ------------------------ - -**Description**: Deletes a specified published file - -Request URL -=========== - -http[s]://{host}:{port}/publish/{feedId}/{fileId} - -* {feedId}: Id of the feed you want to delete a published file from -* {fileId}: Id of the published file you want to delete - -Sample Request -============== - -``curl -k -X DELETE --user {user}:{password} --location-trusted https://{host}:{port}/publish/{feedId}/{fileId}`` - -Response/Error Codes -==================== - -+------------------------+---------------------------------+ -| Response statusCode | Response Description | -+========================+=================================+ -| 204 | Successful PUT or DELETE | -+------------------------+---------------------------------+ -| 400 | Failure - Malformed request | -+------------------------+---------------------------------+ -| 401 | Failure - Request was missing | -| | authorization header, or | -| | credentials were not accepted | -+------------------------+---------------------------------+ -| 403 | Failure - User could not be | -| | authenticated, or was not | -| | authorized to make the request | -+------------------------+---------------------------------+ -| 404 | Failure - Path in the request | -| | URL did not point to a valid | -| | feed publishing URL | -+------------------------+---------------------------------+ -| 500 | Failure - DR experienced an | -| | internal problem | -+------------------------+---------------------------------+ -| 503 | Failure - DR is not currently | -| | available | -+------------------------+---------------------------------+ - -Feed logging ------------- - -**Description**: View logging information for specified feeds, which can be narrowed down with further parameters - -Request URL -=========== - -http[s]://{host}:{port}/feedlog/{feedId}?{queryParameter} - -* {feedId} : The id of the feed you want to get logs for -* {queryParameter}: A parameter passed through to narrow the returned logs. Multiple parameters can be passed. - - -Sample Request -============== - -``curl -k https://{host}:{port}/feedlog/{feedId}?statusCode=204`` - -Request parameters -================== - -+------------------------+---------------------------------+------------------+------------+--------------+-------------+--------------------------------------+ -| Name | Description | Param Type | Data Type | MaxLen | Required | Valid/Example Values | -+========================+=================================+==================+============+==============+=============+======================================+ -| feedId | Id of the feed you want | Path | String | | Y | 1 | -| | logs for | | | | | | -+------------------------+---------------------------------+------------------+------------+--------------+-------------+--------------------------------------+ -| type | Select records of the | Path | String | | N | * pub: Publish attempt | -| | specified type | | | | | * del: Delivery attempt | -| | | | | | | * exp: Delivery expiry | -+------------------------+---------------------------------+------------------+------------+--------------+-------------+--------------------------------------+ -| publishId | Select records with specified | Path | String | | N | | -| | publish id, carried in the | | | | | | -| | X-DMAAP-DR-PUBLISH-ID header | | | | | | -| | from original publish request | | | | | | -+------------------------+---------------------------------+------------------+------------+--------------+-------------+--------------------------------------+ -| start | Select records created at or | Path | String | | N | A date-time expressed in the format | -| | after specified date | | | | | specified by RFC 3339 | -+------------------------+---------------------------------+------------------+------------+--------------+-------------+--------------------------------------+ -| end | Select records created at or | Path | String | | N | A date-time expressed in the format | -| | before specified date | | | | | specified by RFC 3339 | -+------------------------+---------------------------------+------------------+------------+--------------+-------------+--------------------------------------+ -| statusCode | Select records with the | Path | String | | N | An HTTP Integer status code or one | -| | specified statusCode field | | | | | of the following special values: | -| | | | | | | | -| | | | | | | * Success: Any code between 200-299 | -| | | | | | | * Redirect: Any code between 300-399 | -| | | | | | | * Failure: Any code > 399 | -+------------------------+---------------------------------+------------------+------------+--------------+-------------+--------------------------------------+ -| expiryReason | Select records with the | Path | String | | N | | -| | specified expiry reason | | | | | | -+------------------------+---------------------------------+------------------+------------+--------------+-------------+--------------------------------------+ -| filename | Select published records with | Path | String | | N | | -| | the specified filename | | | | | | -+------------------------+---------------------------------+------------------+------------+--------------+-------------+--------------------------------------+ - -Response Parameters -=================== - -+------------------------+----------------------------------------------+ -| Name | Description | -+========================+==============================================+ -| type | Record type: | -| | | -| | * pub: publication attempt | -| | * del: delivery attempt | -| | * exp: delivery expiry | -+------------------------+----------------------------------------------+ -| date | The UTC date and time at which the record | -| | was generated, with millisecond resolution | -| | in the format specified by RFC 3339 | -+------------------------+----------------------------------------------+ -| publishId | The unique identifier assigned by the DR | -| | at the time of the initial publication | -| | request (carried in the X-DMAAP-DR-PUBLISH-ID| -| | header in the response to the original | -| | publish request) | -+------------------------+----------------------------------------------+ -| requestURI | The Request-URI associated with the | -| | request | -+------------------------+----------------------------------------------+ -| method | The HTTP method (PUT or DELETE) for the | -| | request | -+------------------------+----------------------------------------------+ -| contentType | The media type of the payload of the | -| | request | -+------------------------+----------------------------------------------+ -| contentLength | The size (in bytes) of the payload of | -| | the request | -+------------------------+----------------------------------------------+ -| sourceIp | The IP address from which the request | -| | originated | -+------------------------+----------------------------------------------+ -| endpointId | The identity used to submit a publish | -| | request to the DR | -+------------------------+----------------------------------------------+ -| deliveryId | The identity used to submit a delivery | -| | request to a subscriber endpoint | -+------------------------+----------------------------------------------+ -| statusCode | The HTTP status code in the response to | -| | the request. A value of -1 indicates that | -| | the DR was not able to obtain an HTTP | -| | status code | -+------------------------+----------------------------------------------+ -| expiryReason | The reason that delivery attempts were | -| | discontinued: | -| | | -| | * notRetryable: The last delivery attempt | -| | encountered an error condition for which | -| | the DR does not make retries. | -| | * retriesExhausted: The DR reached its | -| | limit for making further retry attempts | -+------------------------+----------------------------------------------+ -| attempts | Total number of attempts made before | -| | delivery attempts were discontinued | -+------------------------+----------------------------------------------+ -| filename | File name associated with a publish record | -+------------------------+----------------------------------------------+ - -Response/Error Codes -==================== - -+------------------------+-------------------------------------------+ -| Response statusCode | Response Description | -+========================+===========================================+ -| 200 | Successful query | -+------------------------+-------------------------------------------+ -| 400 | Bad request - The request is defective in | -| | some way. Possible causes: | -| | | -| | * Unrecognized parameter name in query | -| | string | -| | * Invalid parameter value in query string | -+------------------------+-------------------------------------------+ -| 404 | Not Found - The request was not directed | -| | to a feed log URL or subscription log URL | -| | known to the system | -+------------------------+-------------------------------------------+ -| 405 | Method not allowed - The HTTP method in | -| | the request was something other than GET | -+------------------------+-------------------------------------------+ -| 406 | Not Acceptable - The request has an Accept| -| | header indicating that the requester will | -| | not accept a response with | -| | application/vnd.dmaap-dr.log-list content.| -+------------------------+-------------------------------------------+ -| 500 | Internal Server Error - The DR API server | -| | encountered an internal error and could | -| | not complete the request | -+------------------------+-------------------------------------------+ -| 503 | Service Unavailable - The DR API service | -| | is currently unavailable | -+------------------------+-------------------------------------------+ - - -Subscription logging ------------------- - -**Description**: View logging information for specified subscriptions, which can be narrowed down with further parameters - -Request URL -=========== - -http[s]://{host}:{port}/sublog/{subId}?{queryParameter} - -* {subId}: The id of the feed you want to get logs from -* {queryParameter}: A parameter passed through to narrow the returned logs. Multiple parameters can be passed. - - -Sample Request -============== - -``curl -k https://{host}:{port}/sublog/{subId}?statusCode=204`` - -Request parameters -================== - -+------------------------+---------------------------------+------------------+------------+--------------+-------------+--------------------------------------+ -| Name | Description | Param Type | Data Type | MaxLen | Required | Valid/Example Values | -+========================+=================================+==================+============+==============+=============+======================================+ -| subId | Id of the subscription you want | Path | String | | N | 1 | -| | logs for | | | | | | -+------------------------+---------------------------------+------------------+------------+--------------+-------------+--------------------------------------+ -| type | Select records of the | Path | String | | N | * pub: Publish attempt | -| | specified type | | | | | * del: Delivery attempt | -| | | | | | | * exp: Delivery expiry | -+------------------------+---------------------------------+------------------+------------+--------------+-------------+--------------------------------------+ -| publishId | Select records with specified | Path | String | | N | | -| | publish id, carried in the | | | | | | -| | X-DMAAP-DR-PUBLISH-ID header | | | | | | -| | from original publish request | | | | | | -+------------------------+---------------------------------+------------------+------------+--------------+-------------+--------------------------------------+ -| start | Select records created at or | Path | String | | N | A date-time expressed in the format | -| | after specified date | | | | | specified by RFC 3339 | -+------------------------+---------------------------------+------------------+------------+--------------+-------------+--------------------------------------+ -| end | Select records created at or | Path | String | | N | A date-time expressed in the format | -| | before specified date | | | | | specified by RFC 3339 | -+------------------------+---------------------------------+------------------+------------+--------------+-------------+--------------------------------------+ -| statusCode | Select records with the | Path | String | | N | An Http Integer status code or one | -| | specified statusCode field | | | | | of the following special values: | -| | | | | | | | -| | | | | | | * Success: Any code between 200-299 | -| | | | | | | * Redirect: Any code between 300-399 | -| | | | | | | * Failure: Any code > 399 | -| | | | | | | | -+------------------------+---------------------------------+------------------+------------+--------------+-------------+--------------------------------------+ -| expiryReason | Select records with the | Path | String | | N | | -| | specified expiry reason | | | | | | -+------------------------+---------------------------------+------------------+------------+--------------+-------------+--------------------------------------+ - -Response Parameters -=================== - -+------------------------+---------------------------------------------+ -| Name | Description | -+========================+=============================================+ -| type | Record type: | -| | | -| | * pub: publication attempt | -| | * del: delivery attempt | -| | * exp: delivery expiry | -+------------------------+---------------------------------------------+ -| date | The UTC date and time at which the record | -| | was generated, with millisecond resolution | -| | in the format specified by RFC 3339 | -+------------------------+---------------------------------------------+ -| publishId | The unique identifier assigned by the DR | -| | at the time of the initial publication | -| | request(carried in the X-DMAAP-DR-PUBLISH-ID| -| | header in the response to the original | -| | publish request) to a feed log URL or | -| | subscription log URL known to the system | -+------------------------+---------------------------------------------+ -| requestURI | The Request-URI associated with the | -| | request | -+------------------------+---------------------------------------------+ -| method | The HTTP method (PUT or DELETE) for the | -| | request | -+------------------------+---------------------------------------------+ -| contentType | The media type of the payload of the | -| | request | -+------------------------+---------------------------------------------+ -| contentLength | The size (in bytes) of the payload of | -| | the request | -+------------------------+---------------------------------------------+ -| sourceIp | The IP address from which the request | -| | originated | -+------------------------+---------------------------------------------+ -| endpointId | The identity used to submit a publish | -| | request to the DR | -+------------------------+---------------------------------------------+ -| deliveryId | The identity used to submit a delivery | -| | request to a subscriber endpoint | -+------------------------+---------------------------------------------+ -| statusCode | The HTTP status code in the response to | -| | the request. A value of -1 indicates that | -| | the DR was not able to obtain an HTTP | -| | status code | -+------------------------+---------------------------------------------+ -| expiryReason | The reason that delivery attempts were | -| | discontinued: | -| | | -| | * notRetryable: The last delivery attempt | -| | encountered an error condition for which | -| | the DR does not make retries. | -| | * retriesExhausted: The DR reached its | -| | limit for making further retry attempts | -+------------------------+---------------------------------------------+ -| attempts | Total number of attempts made before | -| | delivery attempts were discontinued | -+------------------------+---------------------------------------------+ - -Response/Error Codes -==================== - -+------------------------+-------------------------------------------+ -| Response statusCode | Response Description | -+========================+===========================================+ -| 200 | Successful query | -+------------------------+-------------------------------------------+ -| 400 | Bad request - The request is defective in | -| | some way. Possible causes: | -| | | -| | * Unrecognized parameter name in query | -| | string | -| | * Invalid parameter value in query string | -+------------------------+-------------------------------------------+ -| 404 | Not Found - The request was not directed | -| | to a feed log URL or subscription log URL | -| | known to the system | -+------------------------+-------------------------------------------+ -| 405 | Method not allowed - The HTTP method in | -| | the request was something other than GET | -+------------------------+-------------------------------------------+ -| 406 | Not Acceptable - The request has an Accept| -| | header indicating that the requester will | -| | not accept a response with | -| | application/vnd.dmaap-dr.log-list content.| -+------------------------+-------------------------------------------+ -| 500 | Internal Server Error - The DR API server | -| | encountered an internal error and could | -| | could not complete the request | -+------------------------+-------------------------------------------+ -| 503 | Service Unavailable - The DR API service | -| | is currently unavailable | -+------------------------+-------------------------------------------+ diff --git a/docs/data-router/dr_arch.png b/docs/data-router/dr_arch.png deleted file mode 100644 index 54cd7e8daaf093885e232249e9b1d3be2278e1d0..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 35750 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 wOECUF&X68{Z~{m0m5vGaH>C<8?82eU`0`!}CNQ zdj7~z^hsjGN4u!Ve!Ogy&zLYXu~9&E92QpB%p znF<4v{{Qf&!ndz!r)NIGBG9k$W3F+vxL=M%fZuwm(h_+?C~!QXEFy1B=`$(C*~W8o z6hCTk5E6VKG+Zcf{o~h=)cN=_x5sQO+U8zC#M8{jkwNv_i^_EY{#>8tl`<9)p%zMA?GGkO^_m#HJe#GAR0}Fwqmb#?2XB&l` zu!lf&#}*Du%=w8jdFfXiWQIUs{Tb(&=TaoBnqwWO(}ME-ZSJm|f&?=%a;~-|wqH+U z;gq!SaT2}*fg}cGuQlGt)>Q@CD_@b4dG=)-A`d53(`W5l4f>eALLB!njK; zTSFkr-P>xU8@)yX(+%^wN|4|{8pgWR7s2}=Uj#?$U20Y7xgn65mab2RmgBc&Z|#G~ zof%^8MHmL0(jn78CJJ(m@yU)QIZBGOb$X1DcD>!YteyN_wG6|Rw>!1byW|=H87ayux1ixA z%t45Xan$Y){I z4Zpo(9L5LpN7tBrK;~*!T>w*)t6h{cWgytZhR*gzr)e*yRt7DOZ|CUx;IC6aMG&mb z3ZIGG$+iiLs#!|2tT?-=!~jf(06EXj@{OU?xOKoTttIqAx2Br<2fJiHg3KehVGZWWAK&yBT;2T( z;=_v^i#814=a0ChdnQF$^oYA49~(zev^Y843PE%Z3>$h z>zd$&^|eC*tAS#VpoJ_A@~BOmICJWO}}Z$DaNwxAOkyvx>7V;aXyc^C4$nD}2+%o;Vc9iw@;wk~Ng;P50WnrTdHXonDo ze8|b##OhdoRiT9qqveq`9Tg5d#cyvq*ye@}D=7R&@(UG0Uo7=;Rhiz*| z2B2K(Rh(Yk%1h*L6lN0;deg4+u}=%9uGy4ikC?AIL%xy& z>*eAMKa?u66pn;W&Ek29s`WLyuj^iud3Kh+7oYo)tJ*MLAr})=MxmpQFtXE1ZgG1u zz0q9z{B6A%RS>S5oUZ@3Qsy)oNMA@iDg^k_ubRIh60IqLI~md}l&| ziVKEDyL_?l3=y`^Ry!D#zNgB^;g#$cMi}&MV=HqNd?h2*EJpsqDShwIb!kiUwqjG> zH9w#}UU5+?Bn+_+(q4=xoNPc3e1ab1Oi5rPSupb1@tibTxa75(Lc$S$Hm?2(3{=fWa7kfKeZEG+4+(5q+iXm2dnEXkAV5`tfi8*tuXtp=DbmZnHsta8;3SQz83F zY*dQn7XK5rlR(lCLOS_;&L&OHmkuqjl%{~Ek?tpfy+=k`X;b$io4*tekrDM8AKQ`q zNaZHmaGA}3&uvkAvmNW@_#rKwE6#LHGz-E)b6(mbfxf3z>XRdzgspK|q+p%H5EZnn z#gnGezGLhvt>vpW5+0M2!v&K86A0E&AezS&zB>z&pIK3%B`YXr_1q zn;cr{tI#A|tT<4B2)};`sL3JNi^DML18fXNq*2HZWqeCLh3YB51_(iw9_Tq8^cv-X z3Dc(@A&sI0|7p1jTK5_N3m#zIf3y4qu;EAGqLjyPu;8(`iSqbO(r+q48UN4am<9*l zhsuR(by#BH=o2|(WpY@8wq*LKrw4Mkexsvp`#zvf#S7D5w!6Ojc{crA(6)RM9n>7B ztjEMnrAs|bd40~(^C;XSo_Y|yu2T`)^-(ci1XU^ptw-PryFJQ^4(Ld=;!sAw2f*?W z#DYA2t2j11T2}Hp`Ve4SXtV?!6u-SxqhvaIk>%@@9F<||_YKZ!ZW8kS|15H6fM&h% z>R4Il+C#20Ztf9KO}Wv*h>mv4tseYqH;Q9B0xuaA;R>?0ESf75UD zNsU)`z~Q(roG_|IYaFFX99AcDdsK@ZFN6K-L9TtEjS*tRE#JHtmd zg<&YH4E00}f=XL2-30C^`)@emxqegk9Mce2vy&7u6Cty+=7*si_Xr$B0VUfT5r7+H z|7e@e6Nx*_JV}=pT*F{7B^&60pp( zO~tv=%cokMNqGyHln~<+SW=pcvtU z9L8x=oq)Efz3YGs1+>{HDW#-eUpiZaJ+=qnJiJ7a=@izW;QFVFH^j_q_f%aLfwo_| zkJ|iRVej|AXJdw$syZWI2uE22rZAP!tUv~N2Af^|s?~?u z&j4)07ntUz$d^A==i2J`DX%>YT3@-&0CidAmrU|PK8jeU-1oTA@z8z8%#iXLalP&x z?X!fLo*OD^`yr>6+gJ-l)m@X$o~doKT{ckypg$ z{*Z7~`Vs4A4rjejiuhyI$zb-&sc?;ki(DZdYA|tly`#Yl{rjcW(kgw!8G6d$UJG3` zxe+ZrreCMdukSJA19efd$(T{3#ELB!uYrG*XTpd-8%0m; z4-cl4C=Q`)z{Yyb{wD9a%h=eaJsCx^f9N|)6FseK1CZ*$k(zyKZ58(J1K1pbG0@#F zzf8vd3f+~Nk#_JKY@{*wMSIW2^wje01T7c`xtBZ~rL3{#j@bHTov*f}iOndLp6aYq zcRnt3uUQ`)D=OTADkfVV!Pb|NYH!|ruYFxsr57g%8=Nz}Dq<$IX%#>LvCc>QD{Qt{ zlqPNHeD;E{^bNGVm-c1M_?D@--b5@~MB8(- z$O0JIdD1DVRY_hQpC*DXC@tR}nr#A*&TVO0nt)f5Z!X=7+X3i~2YmEsfN$sSj`QN+$C2&5(QVW0G; zi^oq#EvZtiHQHGwZRn{eVWggL)CfNHDLN{7>nvr@E3iiwJ>d$}wJhzd<<5rJ-g?C7 z{QSe8Nyp#{?@QwzyIfCXJqibQ_lxcI6mul5A%+81?Nbmj^yx$^EgQwY4Hx}*ju2;u zl?%Z}p68nvwcw9XSeRlvv3AFmFk;nk!m{Fc>jCQ8V2`)ig@}%A1Y4Z{?DG_ptu(5I z?hf=$Ms%csgax)eco4aB1-hC`;m-!5Lle_bw~^$wV=97C|H<;(C;9TjMmqD&=eLY^ zZ~pc^N)f=`J3;H$g{bEBJcFWla54fpNaGt%^>4md%6%E-5g}Ngf-j4~>rdR)nQXD# zef--+5D&pd4i{u`5CiC-Ky<+fBn^dM4CI^Tm6p`4yeA3PXW`4|;FSwaczMl&NRk+Z zFA!6s=qVp`UYkI>N21hkiSOM;P@Fq@8t3At{sk)#;5uP9R;t zaqEbv>lnc76Wvf6{@`PSy|Q*9Z3?Q z;x;6VTtiP-qGgS26gOf?JGO46#^7?x=J_0k-NmRY*HNtc&?`sfKebmR&&Xhnt=*Soe6Fpy7C--Vc1MB!oB2FP^QMo9u5W~0-L z6y~VJFPlOS5YkfsBsT2I341D_QU(Fb$42OEY77$M>f|3lWre7FQfTyhL`NHfZMq_8 zr;m1^b*(&Lkcz+|Q%vJ*X!K5aG$k&f&QK4lJK)JGU@3kLooy+!^R0}fC}{yjb-JnF z&MPE#11U(tx2T>M%VTLw)qp7zAlc*aWeGUHb;4#r424XuGqDJ9HdwO4x}3B=tKq^5 zc4!=(V~~LDA3v?vG?-sFIOjq!uv3~MsJ1X_s27|xNJ^`VEf1r{TFY0mL{N;>h-@Ox zLw^-5#z#JOZg(>%qc#U zbe?lRem7;OY&W|jXG5Q~zDAn*46gN%EIpJmx4J#%WZ7qL81SBw##3%QrcM)=vo${yT>NSkea}?`GAk-~$ zCDB8@m`h2UU)yjy&CxaaY`Jo#K}5A0Pa$gZ)zld=`LUb>_7_u61U2(gkfviLnln{! zz~-hYnSJ}Ysx-Y^Iq{|uN-aa@ASK!veh9SkhCCD|EwwX%@BU&ak}I^JM zX+R)?*NNtdTRu>Af;Bdpjn9X-V#*?#OOqE;W1&nvFLjZY zZPnhRlKUa^^>Xywqac(7`Qk_Cc3ag(e8P6ACO+q76h4Fd)~M=!R85FDlYAHiqJRXt zw0=rv+?=%8U*L&uz6q~ws$1=baYC6Qbp~N?4D^gBg@uO(bdWFXvB%+w{;!)P+Nve- zCvH3YNm#3OFc{<*rJ^^hXSU4!$Zy|v(L%m-g%b$ROG08@J2I|>P^ukO?iuIkc`1@| z)Xm*Y{#bRO!Be&yx4INB6l68Fybm(pewrRCA~c0mR+t)qx{+D9L*qtFVW2grQ4>5xwB%!N`6aj#b;A`B`*q>TQMXW+2D@De2*?IjBmh z=p>EBF5i)S-S&)G2uY{otYSHc$aO(PRw-cv3UM+KZ=k|Afz7uVdR~&`25(4yB+FHu z8`E7beB3BexxgjZ%}=dUuIKV(Nf9=lnaP}$nX@j%NW6rB69Snd(qhabI<9D-NX``+@p<(fZ z1lKk5@%BthZIg`SqplAK&iL@;h^Qs^?x&crw`v*V#Knk)!sXRmEycMW69eWn#cWhY<$IqdQMk+kP*^2Wp``rF{|poAS$FAm@uZ8 zK`{?XX=ziQSV-_wF1a?}{|Ra>pEzTZjutzA`?(Zwz@J&dH3ZIvRvG}J%3UIr>5eDJ8IhXhs~9wG%iQGQ z4rb%Z5XjS}_H2pt4ptCW{$h?PFEWEbg3UA4GPpeHA&`P-5Bu&x*gl|`R`whaNIS1u z2ADVE<^?%w$z1`a7?9`QDxeG3087rI8TOvylAy_8AC{&EQY*2}G`&I^Pmml_Vb#MX zGds*uXksoC<~PEvk&lj(x+$$Sl3?=}M45GXSro7im6Mz)ekotuYu z$4j7gy=gT|CWNDILE}A+#ac^0NHZH{-99Pm?HM$XcD?{X-j{vcLvL4YpD)RoGeDQL zGW>mp+p=8ISDmT`8s%y|K9Bl+@T9u{f$*EAL}+kIg(tLLH}O<}CprcVIg{&3UvUzS zgg?rq+4Ozs^Fw{S=A64KiM(=F4xHO6qaB~72dvfLuvGZLd|~*DRSvkz{@T-$d~bU1 zME2cbN1TZVif}Bqy)8{|pmAPn5kLJVEQ^%M2wlOb_Z}6w{RpI^J_NT(1SpP{`b-eP z**YgGTenE%xh%E^8Wbceas!jtzn7}{=Y-$2jew|!WIn6Dp_C%$4%0~JyGkOvMF^Qo z^`~fI)GfZ4eByw0;y39;TzFhn1& zCg`MYVYOn!LCCN*&_G^K|AZxsI+-MDW@`Ut$sNQja@}TJD>)h==&uaMw#*@6yo{=AxV>c2HNU+0340552JS49L^Ld~(lXk20FrvlRW&GFBj!49OW%oo4uPS=%&c~~!1*1NQ$n$-TEyOgOo{<&@X^yqtu@`f^FfvXW0@2PqrR|AK*kw(=4R$h>w3>Kj5@D(jvy~u={EXmNP~4m>dlk0X@&PVASyaz%rR5e zHhHJvmj{xgd>ZfuT(F#zr=e1*(Y)I(q0y2|FPJT_6YrPsz&iV2e$~x+griB*puqG5 zn5%O1U-n4|@gMZpWTbe%7Dv%6XWvz;u*VCe6VqpEgB(WvKY^H)Ak4ztVs_D~FDnLm z5T_n<8yMaQEw$pTt6oxYCO*l)7EFU^)_wVFrMB?{#xk0(c?6HZLyt>-z;wA^()fzM zxv~|5)E4Enb1d?yDthZpWZro-bImCB`?OsO>e;GFRazZ8B-L``ykw3xn(kr@p_YYk zltVJd_+kvcL@%W*)X@ywr+Fm@ordEg3YjU>vXVi*o}S8&oc!;$DB|lRK=9+6Gp&{} z6&^h!aW3zAAm9emY2K#X8)^ZE7E_cvJkfM%Tl;*c=RMpSk8&uFxy2!n?BC+XT#mud z$OwO1EC!YJ-jy`Hy7}dTH@a;6cR88Yk##98N|~J(6U1zU(^1 zL)=hZHKxA$(k=>mdQw!&|MC1kEWgv9bJ+763{=0-yXQAB)GeHKx2Z1WdBWcFfy3VJ z`&7T-1pJ0U#a|Fezq*{{R3p^|J(H1iv@ZjF;fjCa5!=IKLj@LPx;IrTx`*lx=icmj z);-q*T)$Mo9~XD>Zx{E;9Gq@ukFNjeC{ek;=|=rVb#xEa5jP42U$gw^;xppePseM<&-m?-37STA*7uE$VAKXo4^evRMT$9qN- z_|TFgZkmJlaTH>$Ie)(~f9`1&M_~&38m8gf9zIHh{%D2^0=W%s0fG4JVajOodC7Gu zM;k;H_$dy&AQp8P*0@LO^l|w28S1ie5HmtPo+kk$_Ax#nOHdK}UIAX+de&NjE~N_p z5lHm*MsH)wuj~P^Jq&xdH!|JZTMJSaF)BVoIg+(KmBgz=^Ba3umH@szvOwH@W^a@+ zj~D`EebH99!Ac1rG;tKN;~_m-7Dl}RA0+6za1?M-%S;{GsOfA#y`;k7Ugd-AmA z|G-U&Q*Lt$YEyvpYx2Tq_GqLe&3j1uK!`hdf+CN*wf9N@LdKJ|QIyDqu@NMNkoIto zi-UXMz7>Pp85|PI*j5hM;aS9#i~>;)C8t+0KJ$Qfk`e;VA5jGV1vxdOoDVj>hYLCX z!u9t{N|}*5dzJY)0_jBM38hR1q0}%bnGbb9SrI%gsOT%X*3)NEvC(rb5J?uxuc_YZ zv0Q(-VvalAlR4r=T8cGw7MQfv3IWeJf^_rwP%p~1`tFGf!I~$*zLgl_NSN9N=ch?Ium_%ez z%$NO>bnJ#mqGA#Pi2pWPbvbW#-SK1eg2mV zNmCrSPud<|-jYqwEZH{3i3cVp>Tv9+Ig#?PV~5bk7v4ps=}z6W?S{~n@v!^~Hpt2a z$GdlYf85a_Mb9~74Q51j71v2bE=%GB|HEKD-)jPs7ndI zf7`1U?8IQSQ%4LMgZJ}C2i|sF@(EA<_?@WGeUC%l2%YN)U z0dpFxS=pHGdwg|xCcmO}^;_gV&?kAk)a`oZIJKp+*H@wRQ&d2O0Ffm2&Fdwm*8mxu}*^n4D(sO_IW zSSSS^Dztxr-0K`s_E5>AHjRccmfw0ZMW&5xjo;)a+^koB7ja%?g3qfBVa@s1C_=c#2nlkgn^0| zWkjh6?M+e_gH8$M9c2S`K-qvf7))JE9sdK~AK1ZwbyOsK@W6q8!=?_XVCbM9`|{6n zt;QJi;GC@+C3gfdb#PzRI^g#8o+q$~t~{{ipM zSOt(kMY0FwZ`je!+g+BsD_9x4zrhN6#7-0rSw05$pIr@X`;^NE zhyGih{F@>I*8b}b{F|O$N~sHrnDB`Noe4xGf*|ZGm@WcG^b$t?zoBl|k}^XX!8Mxl zrruWy^Fbe$`h#+v{}(Ph75qOz?)z;5PQd@%W*`-+O#Yk8PMrqzy5IH#s4{iqzwF1q zYylvgI{RM;r^2Sr04bt}=QX^fhPv$|@IrQuuh(}YzShi|rTyx=UWPK#?^0aVyE^1_ z&v>cg*4-)JC5r_`n(9}7BUTq`Xq)gfsPMNai+^LgvunEOwrOO)zH(Pn#c^X(CZUg8 znvS#OO@7r-=##YktiP?LFg!5`-Ar@ep+V`*%);O?OTFJZc#1I6S=S)@f>r9)_?D|_ z7_YK>!q!<^WqBAqbnUGC<9`cu797e?66p{X~1Q_Tb+) zK}3mvL{nP(k@@FMF*yGbIFr-zwV84)WOKLSd1Crhg$TYOF@XKr4TiwHiHp$b;jcfNK>mIyqX$9!vx^NzX6C>& zSn=As%#4D*2eLIV_l=JD`+*kE;>l-SDzaN%UR48qezeTLY3{)x#GS>dM8gQy@soP} zO0sUB-y2>!k}WZIm+w`aR7m3mle1GMcwE(k@TIE5zPvnL@Ua1;{$;gX2i1r0Yha)-y+h2p)XzMEVLQE|aM!4^*qV0QCB+@D@+%VQl z8xh{67{gX^E`;1DT(xwa@o7trl3ItXrOY5vbY(r!y8<%MyoO(cAuapB)781lbh>2`P+-<xETPJX)QDl=#b&h&H%(n^YKq9R? zss==iGX1LzmkpevZ|ZO3baPcG-K#m3;-i~bpjJx(Fvk*$6J8^B!a;-sF=3-&(Ft1l zdKnQ=Is6{Qb4qD`xwD4vfP)#~ARHyRxm++^`)0g6Ot9t?^|bKpUk8m*aA{D=@Dc$@ z%Bq`$qt3i}D8FB&ihSX!0x2+3awnE9iae6UW9TR4$GMkoT5YgQi){t18@sxPUb zgIhrJot}g84jfgEgwW#z)X26Wkh?Et=Dim;HOJq}{yx(Z3)B>w6=H^>ZEYzLYx?wC zC(9H6Qi)Oh&coZ)}+cC@em(@MZu zDvbXV5GB6(?P~Y#A&|sx6ZfAE`5(jbq)dz55h&i{^8P=f@#{MmH0K^P7Wo%d^1d^l z+5*XO{I_!$SH6km`}eWY1O5nPDJ?wI*?RK$>aErHIssEbUcv9RL!;v?cao1C{zL9y zh0^w<&Mx$K0@7~Nro6l5#B#nTY-6oSdFKj9Ret^;x)c3-9{SFGCN@%lrLhJ~1bGI( zhjm|3-ssrHve742==hJYx2{i(tt_^jV}$ZI(kjj0A0S%#{kZ>5+d_G}OL_Jp^vl5J z=akKhM1R!cMuX*+I^jWGShP;SVl0a!YEfPka}YtVv_)W*C*{WWwe4=T0XQ(YY{z?p zzAH+L;9CteozT`Wts8TUe%6P!z;TJP1wTLbaz%_N#O9#w#V$_|7KeJ>T;M&p4h%Vo?w z;Fj)xQN8#$Ds z@3Q@{{a>)*H}c3;azA2<@0Xc{lfoTwD7TaIPWaee%%VPe!X}y z(#5Na6Vfn3We?25N-%S9<)lUBTqC8tz(b>cPTOC6pO~THLd8hrzWyiE4|B|1he287 zfBw@h6H>uzH+85eUwPtd;N+pvkK1)@*dI&cBU5Cj~k*%=h9@2PvY&CC21LOdhQQ>aPL0NH0 z-f_vFqnE+Qv~Fno&g4TNSNCqxYN(BCHH(a`EUFT0c^=|hy}mlzmM638XMtGMBx-gi zu@^LNwSE}>6vZT66U)LEy?c?;aKOrauWUM9oFA9ql47(Ku#~vU;~GekD-JT2Dt+sm zAQB&xaA(M_XrR?_@nY}iVCORT&CT2&K{X6ICz&2gkmS8Y4#+E3;8^6uvKrd`W53}vMzi_tGLbqB23Zf9HjZ{UhkTs=@#<1DF|7b9k7|7=#rVk z5Xh$paWUD*;?Cr!-Ve%$w&qaxFy9icD(M84eI@7f{VaU_E3v%@Yig%-t>Gx60@q6EAhq6`&JV)4z1l=H>AVnTJsMJm7=xeOKC{c?8e$Qis^1E%UIrYxghl zrYso7q!c>xsK{W{eIHvyEXuEHxs~Fa^Yk))pnjcJsJt(Aj_%ZS;vwIP{tlH$h+to07CR??PZx61TqPeAH^_+>C zXWV(4QG8Q|B=L`H1Gd>UJKlz9r^B#UQfj!Okul}mbw$}eyFAFUI6RZMSl*Y6Y>-O( zV4Qxs{f26lut_v8A$^Xyqa^Fj$n*n*o_|5+!>TE5uYvP#OT>c=N4JZWl|}8H-ls*a#4bTj1)#?XnIEOfiP(Uy@(Af$;AIw>`AH)5J_L6UEyT+|^!^0VtX)hae7R9@F;yK}R2BJN?Drs2o$x~qAM zFtME%0{sKxu|8fqS2&po$cC?ravVCPf~3#ehFGrC+C$Nb+TV*`Vbl#px%-%)E#W~G z^f(BP0b0lFa=)CAu1#A0aO67^uk?IN9{A!RRAIWk%Fah63)4X6VXULcHX0WE8#5<|7nz_*BbQ*HyTLjWQ9nrB|fdHTBdMLp| zbt`W=5BP_^Ye8FpuJku9!T9j)LAoPweqnefZ9va_ZaHg<*{`kdIgO+kGg)M2J`#5u zFDYPC&ah$>4f?BO)2Pyq2)$4DOnB=<8H4A-qtopy&(v9+^f(v0>e|WJNe*>A1bfU6 zG=i^t=?!zc&%MJf;m=RD;jZqw=({Vw)Vk^BG+8BSZ@!`chlgz_%7EX1N|hlT4c)S{ zd;$8oZcSP-eKmPLxFn;>R;}zBj*nK_?X`$!Ui*1o{9HHb`8lMw_-5&i$g848HyrUa z)9JucXZ#~R$%1^b{RVi9dij&M6DhN|(2xm3Ai(P~oPgsNOk#NzwlO>9?#rEg$%bvD z>~iuW=^#62T9Z=@g!G2KkLA~&3VxS4C=%~nU=lGUd{ahqw4#+h=fgsRl8Ie%aZ<+o zyeT(|2zP!PL^ND1V{tFF^*>2C8t@vA@-DhHfN-xhv8xsVrQ9IU@E@(3Lw%SSA3Z|! zO?lI8AD5YLu370zYkI@Rz=l zITSaoI||aOnMJ1`1Uy^aZFBl5Jaru{I@si+qmgpa;lT1~cxK^NYhL7S+r#F}j;V(lOS62J%*7CH37oHgIEgn8r$1&~(^@ zr=taU-3&d({AV<&v!3)E5P?DgH9kN4obs}1C3f%&k7$)ic(mrFf@W>BL_8k^;(f&J za3Fs%FY)H1x;jIR8!x~b2F|kvuZ;z-fllU&!8|7Y((j~xSJ3R48q8xTGLQ1+SBRwh zzlKK>8Ec{AYxUy|=D43dF7JB1K2_$LdT&YEK~e=Weyn)CdcQDU&eVQARx23&(Nx?Y zKHvfxdsg2568Teu6@#J7mkvzC_|($7V9g58T%6RJQG(dt;hn;NcmHwF_t$9=-TK(R z^F+I*gO~2u%j{P<8~aq5_jciW*}_SGc*K?k^S%QUB_+nzMx$Px!G#5U`%+(_>I$Bc z?|qn6O>HqEOv;O(aG_Zd+J+Bp)SD7w$DG|S2uQ6}xwtUb#cH~dGy~twp}Y0Qy}p&& zqSxbRH_gL*tE566^tDyLvJeVx5!ZfzDHJwoK3GgAwB8CRkox6r z7C}WmF}5M+X=jAx&o~MUn#YWs?zX%?^=`PT>7vNUvR9c%`bov}8BrQLXS!2vmt_~u zw#*{}qe0Qz^dxOH%_G$n<|?d~P1S_2^7Xv@(L}sXz8y;AXlAYBQ}-Vqy6(R2bMAV? znD^_;Gg3OdjN|;G>K91`o|7J&f~~72J#RP$rf0()|RoXlnb?-QLS1?>l)i`;v}S>fqYc0B3zqnYrVGPVqPFbLmXq5raAk6T<~UrdbD~@6McdFFT_b8s6e%@ymez%Q;W@vDF@XMVl9x{4sIJ0$vHT7N))nJh-*S;( zAKJkStGc2pWE{A;Z~k1dzhw)$zl-%WtH%{gl}cyEEi4WwFbfw)eY2P*Pu2>BPbJvf zs>OFskEJ)3<~xQnvaW>*hQ)ZO_Lu*n*-!#s3qkMbAxAzlgLXBJj=w9>$+5h>`F7j1 zktsS`!uULv@wv>0Q+zZhIs3l8GvtDuN!_m~A@&9S0Ur|Ba$%2OsS9yRR_ht%X zoOoBVYUOvHMT{5kP+-z4`%wFOsg*hMLjR{0NkuCudM1==U#2w{)S;sCu50br@WoZN zewOYN;C)#&H*P-a$qZc@+wLmRlktdg+?hE|1YfaF3@5#q!R`2nT0rHoYcM&7pJSEd zXE>B)GO{CV`Vivh`iFATwCm;(F$=Q>`uWoNeg>oaL38#g$`DbN!~st@DI9ca&?*LU zLC3tz{PNfW{F&lGaUG8 z*N1r4CsAxaUm+t^7NA!|`Nf9LFS_KXl||DF0@on%?(9&TRS`_ALQ}#qV2GhnK*Pu9lIMwa8yl u*=5c<$Crj|EYJO4eeVC(q}=2#ZMRTaE$u5D`1B3}(Nx#IoTqyG!T$p{+4-da literal 0 HcmV?d00001 diff --git a/docs/images/dr_bc_prov.png b/docs/images/dr_bc_prov.png new file mode 100644 index 0000000000000000000000000000000000000000..9e2f7e47fc308d7ebde2ef4a1b4b67a5b2f17cda GIT binary patch literal 51556 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 literal 0 HcmV?d00001 diff --git a/docs/images/dr_pub_flow.png b/docs/images/dr_pub_flow.png new file mode 100644 index 0000000000000000000000000000000000000000..83af9bd2c76a3d5c99668a5bd7077a020911ffbf GIT binary patch literal 72010 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≷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 TIUIF!WH_oS8V}I-OyB%3Ryy6b literal 0 HcmV?d00001 diff --git a/docs/index.rst b/docs/index.rst index 99f0f281..fa1a250c 100644 --- a/docs/index.rst +++ b/docs/index.rst @@ -2,36 +2,19 @@ .. http://creativecommons.org/licenses/by/4.0 .. Copyright © 2017 AT&T Intellectual Property. All rights reserved. +DMaaP Data Router ============================================ -Data Router (DR) API Guide -============================================ -Introduction ------------------- - -The DataRouter(DR)provisioning API is an HTTPS-based,REST-like API for creating and managing DR feeds and subscriptions. The Data Routing System project is intended to provide a common framework by which data producers can make data available to data consumers and a way for potential consumers to find feeds with the data they require. - - -HTTP Service APIs ------------------- - -DMaaP Data Router utilizes an HTTPS REST API to service all transactions. HTTPS and REST standards are followed so -clients as varied as CURL, Java applications and even Web Browsers will work to interact with the Data Router. - - .. toctree:: :maxdepth: 1 - - data-router/data-router.rst - data-router/administration.rst - data-router/architecture.rst - data-router/configuration.rst - data-router/consumedapis.rst - data-router/DataRouterUserGuide.rst - data-router/delivery.rst - data-router/humaninterfaces.rst - data-router/logging.rst - data-router/release-notes.rst + + architecture.rst + offered-apis.rst + delivery.rst + logging.rst + installation.rst + configuration.rst + release-notes.rst diff --git a/docs/installation.rst b/docs/installation.rst new file mode 100644 index 00000000..95cda4e1 --- /dev/null +++ b/docs/installation.rst @@ -0,0 +1,51 @@ +.. This work is licensed under a Creative Commons Attribution 4.0 International License. +.. http://creativecommons.org/licenses/by/4.0 + +Installation +============= + +**Standalone** +Pre-requisites: + +* docker 18.09.3 or higher. +* docker-compose 1.17.1 or higher. +* Ensure port 8080 is not already in use. + +1. Clone the DMaaP Data Router project from ONAP gerrit: + +.. code-block:: bash + + git clone https://gerrit.onap.org/r/dmaap/datarouter + +2. Move/cd to the docker-compose directory and execute the following: + +.. code-block:: bash + + cd datarouter/datarouter-docker-compose/src/main/resources/ + + docker-compose up -d + + +The following docker containers should be deployed successfully: + +.. code-block:: bash + + docker ps --format '{{.Image}}' + + nexus3.onap.org:10001/onap/dmaap/datarouter-node + nexus3.onap.org:10001/onap/dmaap/datarouter-prov + nexus3.onap.org:10001/onap/dmaap/datarouter-subscriber + mariadb:10.2.14 + + +To verify that the provisioning API is active, get the IP of the datarouter-prov container: + +.. code-block:: bash + + docker inspect --format '{{ .NetworkSettings.Networks.resources_testing_net.IPAddress }}' datarouter-prov + +and execute the following CURL command: + +.. code-block:: bash + + curl -k https://{DR_PROV_CONTAINER_IP}:8443/internal/prov \ No newline at end of file diff --git a/docs/data-router/logging.rst b/docs/logging.rst similarity index 91% rename from docs/data-router/logging.rst rename to docs/logging.rst index 6ac7a0a3..140c265f 100644 --- a/docs/data-router/logging.rst +++ b/docs/logging.rst @@ -5,12 +5,10 @@ Logging ======= -Where to Access Information ---------------------------- +**Where to Access Information** Data Router uses logback framework to generate logs. -Error / Warning Messages ------------------------- +**Error / Warning Messages** Currently Data Router does not have any unique error codes. However the following are the common HTTP error codes that could possibly occur in Data Router: diff --git a/docs/offered-apis.rst b/docs/offered-apis.rst new file mode 100755 index 00000000..a3a12139 --- /dev/null +++ b/docs/offered-apis.rst @@ -0,0 +1,1350 @@ +.. This work is licensed under a Creative Commons Attribution 4.0 International License. +.. http://creativecommons.org/licenses/by/4.0 + +.. _data_router_api_guide: + +.. toctree:: + :maxdepth: 2 + +Offered APIs +============ + +**The API Provisioning Model** + +The DMaaP Data Router (DR) provisioning API defines two resource types - the feed and the subscription, each with JSON +representations. The API models the provisioning data as a collection of feeds that are known to the DR +(the feeds collection), with each feed containing a collection of the subscriptions to the feed. +The standard HTTP operations (POST, GET, PUT, and DELETE), used in conjunction with these resource +representations, allow an API user to create, get information about, modify, and delete feeds and +subscriptions. + +**HTTP Service APIs** + +DMaaP Data Router utilizes an HTTPS REST API to service all transactions. HTTPS and REST standards are followed so +clients as varied as CURL, Java applications and even Web Browsers will work to interact with the Data Router. + +**General HTTP Requirements** + +A DMaaP Data Router transactions consists of 4 distinct segments, HTTP URL, HTTP Header, HTTP Body (POST/PUT) +and HTTP Response. The general considerations for each segment are as follows and are required for each +of the specific transactions described in this section. + +**HTTP URL** + +http[s]://{serverBaseURL}/{resourcePath} + +* The serverBaseURL points to DMaaP Data Router host:port that will service the request. +* The resourcePath specifies the service that the client is attempting to reach. + + +**HTTP Header** + +Specifies HTTP Headers, such as Content-Type, that define the parameters of the HTTP Transaction + +**HTTP Body** + +The HTTP Body contains the feed content when creating a feed. + +**HTTP Authorization** + +The user-id:password pair: + +* If AAF enabled: A valid AAF AppId to be authenticated and authorized by the AAF CADI framework. +* If Non AAF : When publishing or retracting a file, a valid `EID Object`_ with publish permissions. + +Create a Feed +------------- + +**Description**: Creates a unique feed URL to service the publisher/subscriber model. + +.. code-block:: bash + + POST / + +**Request Parameters:** + ++----------------------+--------------------------------+------------+------------------+--------+--------+------------+----------+-------------------------------+ +| Field | Description | Param Type | Data Type | MaxLen | Set By | Updatable? | Required | Valid/Example Values | ++======================+================================+============+==================+========+========+============+==========+===============================+ +| name | Feed name | Body | String | <=20 | Client | N | Y | | ++----------------------+--------------------------------+------------+------------------+--------+--------+------------+----------+-------------------------------+ +| version | Feed version | Body | String | <=20 | Client | N | Y | v1.0.0 | ++----------------------+--------------------------------+------------+------------------+--------+--------+------------+----------+-------------------------------+ +| description | Feed description | Body | String | <=256 | Client | Y | N | | ++----------------------+--------------------------------+------------+------------------+--------+--------+------------+----------+-------------------------------+ +| business description | Business description | Body | String | <=256 | Client | Y | N | | ++----------------------+--------------------------------+------------+------------------+--------+--------+------------+----------+-------------------------------+ +| authorization | Information for authorizing | Body |`Auth Object`_ | | Client | Y | Y | | +| | publishing requests | | | | | | | | ++----------------------+--------------------------------+------------+------------------+--------+--------+------------+----------+-------------------------------+ +| suspend | Set to true if the feed is in | Body | Boolean | | Client | Y | N | * true | +| | the suspended state | | | | | | | * false (default) | ++----------------------+--------------------------------+------------+------------------+--------+--------+------------+----------+-------------------------------+ +| group-id | Auth group for feed management | Body | Integer | | Client | Y | N | 0 (default) | ++----------------------+--------------------------------+------------+------------------+--------+--------+------------+----------+-------------------------------+ +| aaf_instance | The instance passed to aaf | Body | String | <=256 | Client | N | N | legacy (default) | +| | during permission checks | | | | | | | | ++----------------------+--------------------------------+------------+------------------+--------+--------+------------+----------+-------------------------------+ +| Content-Type | To specify type of message | Header | String | | Client | N | Y | application/vnd.dmaap-dr.feed | ++----------------------+--------------------------------+------------+------------------+--------+--------+------------+----------+-------------------------------+ +| publisher | Publisher identity as passed | Header | String | <=8 | DR | N | Y | username | +| | in X-DMAAP-DR-ON-BEHALF-OF at | | | | | | | | +| | creation time | | | | | | | | ++----------------------+--------------------------------+------------+------------------+--------+--------+------------+----------+-------------------------------+ +| Authorization | The user / AppId to be | Header | String | | Client | N | Y if AAF | dcae@dcae.onap.org:{password} | +| | authorized by the AAF CADI | | | | | | enabled | | +| | framework | | | | | | | | ++----------------------+--------------------------------+------------+------------------+--------+--------+------------+----------+-------------------------------+ +| X-EXCLUDE-AAF | To determine if the feed to | Header | Boolean | | Client | N | Y if AAF | * true (for legacy feed) | +| | create is legacy or AAF | | | | | | enabled | * false (for AAF feed) | ++----------------------+--------------------------------+------------+------------------+--------+--------+------------+----------+-------------------------------+ +| Links | URLs related to this feed | Body |`Feed Links Obj`_ | | DR | N | N | | ++----------------------+--------------------------------+------------+------------------+--------+--------+------------+----------+-------------------------------+ + +**Response Codes** + +* Success: + 200 + +* Error: + See `Response Codes`_ + +**Consumes** + application/json + +**Produces** + application/json + + +**Sample Request** + +.. code-block:: bash + + curl -k -X POST -H "Content-Type:application/vnd.dmaap-dr.feed" -H "X-DMAAP-DR-ON-BEHALF-OF:{user}" --data-ascii @createFeed.json https://{host}:{port} + +**Sample Body** + +.. code-block:: json + + { + "name": "ONAP Data Feed", + "version": "v1.0", + "authorization": { + "classification": "unclassified", + "endpoint_addrs": [ + ], + "endpoint_ids": [ + { + "id": "dradmin", + "password": "dradmin" + } + ] + } + } + +**Sample Response** + +.. code-block:: json + + { + "suspend": false, + "groupid": 0, + "description": "", + "version": "v1.0", + "authorization": { + "endpoint_addrs": [ + ], + "classification": "unclassified", + "endpoint_ids": [ + { + "password": "dradmin", + "id": "dradmin" + }, + { + "password": "demo123456!", + "id": "onap" + } + ] + }, + "name": "ONAP Data Feed", + "business_description": "", + "aaf_instance": "legacy", + "publisher": "dradmin", + "links": { + "subscribe": "https://dmaap-dr-prov/subscribe/1", + "log": "https://dmaap-dr-prov/feedlog/1", + "publish": "https://dmaap-dr-prov/publish/1", + "self": "https://dmaap-dr-prov/feed/1" + } + } + + + +Update a Feed +------------- + +**Description**: Update a feed with new parameters. + +.. code-block:: bash + + PUT /feed/{feedId} + + +**Request Parameters:** + ++------------------------+---------------------------------+-------------+---------------+------------+-------------+ +| Field | Description | Param Type | Data Type | MaxLen | Required | ++========================+=================================+=============+===============+============+=============+ +| name | Feed name | Body | String | <=20 | Y | ++------------------------+---------------------------------+-------------+---------------+------------+-------------+ +| description | Feed description | Body | String | <=256 | N | ++------------------------+---------------------------------+-------------+---------------+------------+-------------+ +| business description | Business description | Body | String | <=256 | N | ++------------------------+---------------------------------+-------------+---------------+------------+-------------+ +| authorization | Information for authorizing | Body |`Auth Object`_ | | Y | +| | publishing requests | | | | | ++------------------------+---------------------------------+-------------+---------------+------------+-------------+ +| suspend | Set to true if the feed is in | Body | Boolean | | N | +| | the suspended state | | | | | ++------------------------+---------------------------------+-------------+---------------+------------+-------------+ +| group-id | Auth group for feed management | Body | Integer | | N | +| | | | | | | ++------------------------+---------------------------------+-------------+---------------+------------+-------------+ +| Content-type | To specify type of message | Header | String | | Y | +| | (feed,subscriber,publisher) | | | | | ++------------------------+---------------------------------+-------------+---------------+------------+-------------+ +| publisher | Publisher identity as passed | Header | String | <=8 | Y | +| | in X-DMAAP-DR-ON-BEHALF-OF at | | | | | +| | creation time | | | | | ++------------------------+---------------------------------+-------------+---------------+------------+-------------+ +| Authorization | The user / AppId to be | Header | String | | Y if AAF | +| | authorized by the AAF CADI | | | | enabled | +| | framework | | | | | ++------------------------+---------------------------------+-------------+---------------+------------+-------------+ + +**Response Codes** + +* Success: + 200 + +* Error: + See `Response Codes`_ + +**Consumes** + application/json + +**Produces** + application/json + + +**Sample Request** + +.. code-block:: bash + + curl -k -X PUT -H "Content-Type: application/vnd.dmaap-dr.feed" -H "X-DMAAP-DR-ON-BEHALF-OF: {user}" --data-ascii @updateFeed.json --location-trusted https://{host}:{port}/feed/{feedId} + +**Sample Body** + +.. code-block:: json + + { + "name": "ONAP Data Feed", + "business_description": "Updated ONAP Feed", + "groupid": 33, + "description": "Updated ONAP Feed", + "authorization": { + "endpoint_addrs": [ + "10.1.2.3" + ], + "classification": "unclassified", + "endpoint_ids": [ + { + "password": "dradmin", + "id": "dradmin" + }, + { + "password": "demo123456!", + "id": "onap" + } + ] + } + } + +**Sample Response** + +.. code-block:: json + + { + "suspend": false, + "groupid": 33, + "description": "Updated ONAP Feed", + "authorization": { + "endpoint_addrs": [ + "10.1.2.3" + ], + "classification": "unclassified", + "endpoint_ids": [ + { + "password": "dradmin", + "id": "dradmin" + }, + { + "password": "demo123456!", + "id": "onap" + } + ] + }, + "name": "ONAP Data Feed1", + "business_description": "Updated ONAP Feed", + "aaf_instance": "legacy", + "publisher": "dradmin", + "links": { + "subscribe": "https://dmaap-dr-prov/subscribe/1", + "log": "https://dmaap-dr-prov/feedlog/1", + "publish": "https://dmaap-dr-prov/publish/1", + "self": "https://dmaap-dr-prov/feed/1" + } + } + + + +Get a Feed +---------- + +**Description**: Retrieves a representation of the specified feed. + +.. code-block:: bash + + GET /feed/{feedId} + + +**Request Parameters:** + ++------------------------+---------------------------------+-------------+---------------+------------+-------------+ +| Field | Description | Param Type | Data Type | MaxLen | Required | ++========================+=================================+=============+===============+============+=============+ +| publisher | Publisher identity as passed | Header | String | <=8 | Y | +| | in X-DMAAP-DR-ON-BEHALF-OF at | | | | | +| | creation time | | | | | ++------------------------+---------------------------------+-------------+---------------+------------+-------------+ +| Authorization | The user / AppId to be | Header | String | | Y if AAF | +| | authorized by the AAF CADI | | | | enabled | +| | framework | | | | | ++------------------------+---------------------------------+-------------+---------------+------------+-------------+ + +**Response Codes** + +* Success: + 200 + +* Error: + See `Response Codes`_ + +**Produces** + application/json + +**Sample Request** + +.. code-block:: bash + + curl -k -H "X-DMAAP-DR-ON-BEHALF-OF: {user}" https://{host}:{port}/feed/{feedId} + +**Sample Response** + +.. code-block:: json + + { + "suspend": false, + "groupid": 33, + "description": "Updated ONAP Feed", + "version": "v1.0", + "authorization": { + "endpoint_addrs": [ + "10.1.2.3", + "173.2.33.4" + ], + "classification": "unclassified", + "endpoint_ids": [ + { + "password": "dradmin", + "id": "dradmin" + }, + { + "password": "demo123456!", + "id": "onap" + } + ] + }, + "name": "ONAP Data Feed", + "business_description": "Updated ONAP Feed", + "aaf_instance": "legacy", + "publisher": "dradmin", + "links": { + "subscribe": "https://dmaap-dr-prov/subscribe/1", + "log": "https://dmaap-dr-prov/feedlog/1", + "publish": "https://dmaap-dr-prov/publish/1", + "self": "https://dmaap-dr-prov/feed/1" + } + } + + +Delete a Feed +------------- + +**Description**: Deletes a specified feed + +.. code-block:: bash + + DELETE /feed/{feedId} + + +**Request Parameters:** + ++------------------------+---------------------------------+-------------+---------------+------------+-------------+ +| Field | Description | Param Type | Data Type | MaxLen | Required | ++========================+=================================+=============+===============+============+=============+ +| publisher | Publisher identity as passed | Header | String | <=8 | Y | +| | in X-DMAAP-DR-ON-BEHALF-OF at | | | | | +| | creation time | | | | | ++------------------------+---------------------------------+-------------+---------------+------------+-------------+ +| Authorization | The user / AppId to be | Header | String | | Y if AAF | +| | authorized by the AAF CADI | | | | enabled | +| | framework | | | | | ++------------------------+---------------------------------+-------------+---------------+------------+-------------+ + +**Response Codes** + +* Success: + 204 + +* Error: + See `Response Codes`_ + +**Sample Request** + +.. code-block:: bash + + curl -k -X DELETE -H "X-DMAAP-DR-ON-BEHALF-OF: {user}" https://{host}:{port}/feed/{feedId} + + +Subscribe to Feed +----------------- + +**Description**: Subscribes to a created feed to receive files published to that feed. + +.. code-block:: bash + + POST /subscribe/{feedId} + + +**Request Parameters:** + ++-----------------+---------------------------------+---------------+-----------------+--------+--------+------------+----------+--------------------------------------+ +| Field | Description | Param Type | Data Type | MaxLen | Set By | Updatable? | Required | Valid/Example Values | ++=================+=================================+===============+=================+========+========+============+==========+======================================+ +| feedId | ID for the feed you are | Path | String | | Client | N | Y | 1 | +| | subscribing to | | | | | | | | ++-----------------+---------------------------------+---------------+-----------------+--------+--------+------------+----------+--------------------------------------+ +| delivery | Address and credentials for | Body | `Del Object`_ | | Client | Y | Y | | +| | delivery | | | | | | | | ++-----------------+---------------------------------+---------------+-----------------+--------+--------+------------+----------+--------------------------------------+ +| follow_redirect | Set to true if feed redirection | Body | Boolean | | Client | Y | N | * true | +| | is expected | | | | | | | * false (default) | ++-----------------+---------------------------------+---------------+-----------------+--------+--------+------------+----------+--------------------------------------+ +| metadata_only | Set to true if subscription is | Body | Boolean | | Client | Y | Y | * true | +| | to receive per-file metadata | | | | | | | * false | ++-----------------+---------------------------------+---------------+-----------------+--------+--------+------------+----------+--------------------------------------+ +| suspend | Set to true if the subscription | Body | Boolean | | Client | Y | N | * true | +| | is in the suspended state | | | | | | | * false (default) | ++-----------------+---------------------------------+---------------+-----------------+--------+--------+------------+----------+--------------------------------------+ +| decompress | Set to true if the data is to | Body | Boolean | | Client | Y | N | * true | +| | be decompressed for subscriber | | | | | | | * false (default) | ++-----------------+---------------------------------+---------------+-----------------+--------+--------+------------+----------+--------------------------------------+ +| group-id | Auth group for sub management | Body | Integer | | Client | Y | Y | 22 | +| | | | | | | | | | ++-----------------+---------------------------------+---------------+-----------------+--------+--------+------------+----------+--------------------------------------+ +| aaf_instance | The instance passed to aaf | Body | String | <=256 | Client | N | N | * legacy (default) | +| | during permission checks | | | | | | | | +| | | | | | | | | | ++-----------------+---------------------------------+---------------+-----------------+--------+--------+------------+----------+--------------------------------------+ +| Content-type | To specify type of message | Header | String | | Client | N | Y | application/vnd.dmaap-dr.subscription| +| | (feed,subscriber,publisher) | | | | | | | | ++-----------------+---------------------------------+---------------+-----------------+--------+--------+------------+----------+--------------------------------------+ +| subscriber | Subscriber identity as passed | Header | String | <=8 | DR | N | Y | username | +| | in X-DMAAP-DR-ON-BEHALF-OF at | | | | | | | | +| | creation time | | | | | | | | ++-----------------+---------------------------------+---------------+-----------------+--------+--------+------------+----------+--------------------------------------+ +| Authorization | The user / AppId to be | Header | String | | Client | N | Y if AAF | dcae@dcae.onap.org:{password} | +| | authorized by the AAF CADI | | | | | | enabled | | +| | framework | | | | | | | | ++-----------------+---------------------------------+---------------+-----------------+--------+--------+------------+----------+--------------------------------------+ +| X-EXCLUDE-AAF | To determine if the feed to | Header | Boolean | | Client | N | Y if AAF | * true (for legacy feed) | +| | create is legacy or AAF | | | | | | enabled | * false (for AAF feed) | ++-----------------+---------------------------------+---------------+-----------------+--------+--------+------------+----------+--------------------------------------+ +| Links | URLs related to this | Body |`Sub Links Obj`_ | | DR | N | N | | +| | subscription | | | | | | | | ++-----------------+---------------------------------+---------------+-----------------+--------+--------+------------+----------+--------------------------------------+ + +**Response Codes** + +* Success: + 201 + +* Error: + See `Response Codes`_ + +**Consumes** + application/json + +**Produces** + application/json + + +**Sample Request** + +.. code-block:: bash + + curl -k -X POST -H "Content-Type:application/vnd.dmaap-dr.subscription" -H "X-DMAAP-DR-ON-BEHALF-OF:{user}" --data-ascii @addSubscriber.json https://{host}:{port}/subscribe/{feedId} + +**Sample Body** + +.. code-block:: json + + { + "delivery": { + "url": "http://dmaap-dr-subscriber:7070/", + "user": "LOGIN", + "password": "PASSWORD", + "use100": true + }, + "metadataOnly": false, + "groupid": 22, + "follow_redirect": true, + "suspend": false, + "decompress": true + } + +**Sample Response** + +.. code-block:: json + + { + "suspend": false, + "delivery": { + "use100": true, + "password": "PASSWORD", + "user": "LOGIN", + "url": "http://dmaap-dr-subscriber:7070/" + }, + "subscriber": "onap", + "groupid": 1, + "metadataOnly": false, + "follow_redirect": true, + "decompress": true, + "aaf_instance": "legacy", + "links": { + "feed": "https://dmaap-dr-prov/feed/1", + "log": "https://dmaap-dr-prov/sublog/1", + "self": "https://dmaap-dr-prov/subs/1" + }, + "created_date": 1553707279509 + } + + + +Update subscription +------------------- + +**Description**: Update a subscription to a feed. + +.. code-block:: bash + + PUT /subs/{subId} + + +**Request Parameters:** + ++-----------------+---------------------------------+--------------+---------------+--------+-------------+ +| Field | Description | Param Type | Data Type | MaxLen | Required | ++=================+=================================+==============+===============+========+=============+ +| subId | ID for the subscription you are | Path | String | | Y | +| | updating | | | | | ++-----------------+---------------------------------+--------------+---------------+--------+-------------+ +| delivery | Address and credentials for | Body | `Del Object`_ | | Y | +| | delivery | | | | | ++-----------------+---------------------------------+--------------+---------------+--------+-------------+ +| follow_redirect | Set to true if feed redirection | Body | Boolean | | N | +| | is expected | | | | | ++-----------------+---------------------------------+--------------+---------------+--------+-------------+ +| metadata_only | Set to true if subscription is | Body | Boolean | | Y | +| | to receive per-file metadata | | | | | ++-----------------+---------------------------------+--------------+---------------+--------+-------------+ +| suspend | Set to true if the subscription | Body | Boolean | | N | +| | is in the suspended state | | | | | ++-----------------+---------------------------------+--------------+---------------+--------+-------------+ +| decompress | Set to true if the data is to | Body | Boolean | | N | +| | be decompressed for subscriber | | | | | ++-----------------+---------------------------------+--------------+---------------+--------+-------------+ +| group-id | Auth group for sub management | Body | Integer | | Y | +| | | | | | | ++-----------------+---------------------------------+--------------+---------------+--------+-------------+ +| Content-type | To specify type of message | Header | String | | Y | +| | (feed,subscriber,publisher) | | | | | ++-----------------+---------------------------------+--------------+---------------+--------+-------------+ +| subscriber | Subscriber identity as passed | Header | String | <=8 | Y | +| | in X-DMAAP-DR-ON-BEHALF-OF at | | | | | +| | creation time | | | | | ++-----------------+---------------------------------+--------------+---------------+--------+-------------+ +| Authorization | The user / AppId to be | Header | String | | Y if AAF | +| | authorized by the AAF CADI | | | | enabled | +| | framework | | | | | ++-----------------+---------------------------------+--------------+---------------+--------+-------------+ +| X-EXCLUDE-AAF | To determine if the feed to | Header | Boolean | | Y if AAF | +| | create is legacy or AAF | | | | enabled | ++-----------------+---------------------------------+--------------+---------------+--------+-------------+ + +**Response Codes** + +* Success: + 200 + +* Error: + See `Response Codes`_ + +**Consumes** + application/json + +**Produces** + application/json + +**Sample Request** + +.. code-block:: bash + + curl -k -X PUT -H "Content-Type:application/vnd.dmaap-dr.subscription" -H "X-DMAAP-DR-ON-BEHALF-OF:{user}" --data-ascii @updateSubscriber.json https://{host}:{port}/subs/{subId} + +**Sample Body** + +.. code-block:: json + + { + "delivery": { + "url": "http://dmaap-dr-subscriber:7070/", + "user": "NEW_LOGIN", + "password": "NEW_PASSWORD", + "use100": false + }, + "metadataOnly": true, + "groupid": 67, + "follow_redirect": false, + "decompress": false + } + + +**Sample Response** + +.. code-block:: json + + { + "suspend": false, + "delivery": { + "use100": false, + "password": "NEW_PASSWORD", + "user": "NEW_LOGIN", + "url": "http://dmaap-dr-subscriber:7070/" + }, + "subscriber": "onap", + "groupid": 67, + "metadataOnly": true, + "follow_redirect": false, + "decompress": false, + "aaf_instance": "legacy", + "links": { + "feed": "https://dmaap-dr-prov/feed/1", + "log": "https://dmaap-dr-prov/sublog/1", + "self": "https://dmaap-dr-prov/subs/1" + }, + "created_date": 1553714446614 + } + + + +Get a Subscription +------------------ + +**Description**: Retrieves a representation of the specified subscription. + +.. code-block:: bash + + GET /subs/{subId} + + +**Request Parameters:** + ++-----------------+---------------------------------+--------------+---------------+--------+-------------+ +| Field | Description | Param Type | Data Type | MaxLen | Required | ++=================+=================================+==============+===============+========+=============+ +| subscriber | Subscriber identity as passed | Header | String | <=8 | Y | +| | in X-DMAAP-DR-ON-BEHALF-OF at | | | | | +| | creation time | | | | | ++-----------------+---------------------------------+--------------+---------------+--------+-------------+ +| Authorization | The user / AppId to be | Header | String | | Y if AAF | +| | authorized by the AAF CADI | | | | enabled | +| | framework | | | | | ++-----------------+---------------------------------+--------------+---------------+--------+-------------+ + +**Response Codes** + +* Success: + 200 + +* Error: + See `Response Codes`_ + +**Produces** + application/json + +**Sample Request** + +.. code-block:: bash + + curl -k -H "X-DMAAP-DR-ON-BEHALF-OF:{user}" https://{host}:{port}/subs/{subId} + +**Sample Response** + +.. code-block:: json + + { + "suspend": false, + "delivery": { + "use100": false, + "password": "NEW_PASSWORD", + "user": "NEW_LOGIN", + "url": "http://dmaap-dr-subscriber:7070/" + }, + "subscriber": "onap", + "groupid": 67, + "metadataOnly": true, + "privilegedSubscriber": false, + "follow_redirect": false, + "decompress": false, + "aaf_instance": "legacy", + "links": { + "feed": "https://dmaap-dr-prov/feed/2", + "log": "https://dmaap-dr-prov/sublog/6", + "self": "https://dmaap-dr-prov/subs/6" + } + } + + + +Delete a subscription +--------------------- + +**Description**: Deletes a specified subscription + +.. code-block:: bash + + DELETE /subs/{subId} + + +**Request Parameters:** + ++-----------------+---------------------------------+--------------+---------------+--------+-------------+ +| Field | Description | Param Type | Data Type | MaxLen | Required | ++=================+=================================+==============+===============+========+=============+ +| subscriber | Subscriber identity as passed | Header | String | <=8 | Y | +| | in X-DMAAP-DR-ON-BEHALF-OF at | | | | | +| | creation time | | | | | ++-----------------+---------------------------------+--------------+---------------+--------+-------------+ +| Authorization | The user / AppId to be | Header | String | | Y if AAF | +| | authorized by the AAF CADI | | | | enabled | +| | framework | | | | | ++-----------------+---------------------------------+--------------+---------------+--------+-------------+ + +**Response Codes** + +* Success: + 204 + +* Error: + See `Response Codes`_ + +**Sample Request** + +.. code-block:: bash + + curl -k -X DELETE -H "X-DMAAP-DR-ON-BEHALF-OF:{user}" https://{host}:{port}/subs/{subId} + + +Publish to Feed +--------------- + +**Description**: Publish data to a given feed + +.. code-block:: bash + + PUT /publish/{feedId}/{fileId} + + +**Request parameters** + ++------------------------+---------------------------------+------------------+------------+--------------+-------------+-------------------------------------------+ +| Name | Description | Param Type | Data Type | MaxLen | Required | Valid/Example Values | ++========================+=================================+==================+============+==============+=============+===========================================+ +| feedId | ID of the feed you are | Path | String | | Y | | +| | publishing to | | | | | | ++------------------------+---------------------------------+------------------+------------+--------------+-------------+-------------------------------------------+ +| fileId | Name of the file when it is | Path | String | | Y | | +| | published to subscribers | | | | | | ++------------------------+---------------------------------+------------------+------------+--------------+-------------+-------------------------------------------+ +| Content-type | To specify type of message | Header | String | | Y | application/octet-stream | +| | format | | | | | | ++------------------------+---------------------------------+------------------+------------+--------------+-------------+-------------------------------------------+ +| X-DMAAP-DR-META | Metadata for the file. Accepts | Header | String | <=4096 | N | '{“compressionType”: ”gzip”, | +| | only non nested json objects | | | | | ”id”: 1234, | +| | of the following type: | | | | | “transferred”: true, | +| | | | | | | “size”: null }’ | +| | * Numbers | | | | | | +| | * Strings | | | | | | +| | * Lowercase boolean | | | | | | +| | * null | | | | | | ++------------------------+---------------------------------+------------------+------------+--------------+-------------+-------------------------------------------+ +| Authorization | An `EID Object`_ with publish | Header | String | | Y | * (legacy Feed) dradmin:dradmin | +| | permissions. | | | | | * (AAF Feed) dcae@dcae.onap.org:{password}| +| | If AAF CADI is enabled, use a | | | | | | +| | valid AAF user/AppId instead. | | | | | | ++------------------------+---------------------------------+------------------+------------+--------------+-------------+-------------------------------------------+ + +**Response Codes** + +* Success: + 204 + +* Error: + See `Response Codes`_ + +**Sample Request** + +.. code-block:: bash + + curl -k -X PUT --user {user}:{password} -H "Content-Type:application/octet-stream" -H "X-DMAAP-DR-META:{\"filetype\":\"txt\"}" --data-binary @sampleFile.txt --post301 --location-trusted https://{host}:{port}/publish/{feedId}/{fileId} + + + +Delete/Retract a Published file +------------------------------- + +**Description**: Deletes/retracts a specified published file + +.. code-block:: bash + + DELETE /publish/{feedId}/{fileId} + + +**Request Parameters:** + ++-----------------+---------------------------------+--------------+---------------+------------+-------------------------------------------+ +| Field | Description | Param Type | Data Type | Required | Valid/Example Values | ++=================+=================================+==============+===============+============+===========================================+ +| Authorization | An `EID Object`_ with publish | Header | String | Y | * (legacy Feed) dradmin:dradmin | +| | permissions. | | | | * (AAF Feed) dcae@dcae.onap.org:{password}| +| | If AAF CADI is enabled, use a | | | | | +| | valid AAF user/AppId instead. | | | | | ++-----------------+---------------------------------+--------------+---------------+------------+-------------------------------------------+ +| feedId | ID of the feed that was | Path | String | Y | | +| | publishing to | | | | | ++-----------------+---------------------------------+--------------+---------------+------------+-------------------------------------------+ +| fileId | Name of the file when it was | Path | String | Y | | +| | published to subscribers | | | | | ++-----------------+---------------------------------+--------------+---------------+------------+-------------------------------------------+ + +**Response Codes** + +* Success: + 204 + +* Error: + See `Response Codes`_ + + +**Sample Request** + +.. code-block:: bash + + curl -k -X DELETE --user {user}:{password} --location-trusted https://{host}:{port}/publish/{feedId}/{fileId} + + + +Feed logging +------------ + +**Description**: View logging information for specified feeds, which can be narrowed down with further parameters + +.. code-block:: bash + + GET /feedlog/{feedId}?{queryParam} + + +**Request parameters** + ++------------------------+---------------------------------+------------------+------------+-------------+--------------------------------------+ +| Name | Description | Param Type | Data Type | Required | Valid/Example Values | ++========================+=================================+==================+============+=============+======================================+ +| feedId | Id of the feed you want | Path | String | Y | 1 | +| | logs for | | | | | ++------------------------+---------------------------------+------------------+------------+-------------+--------------------------------------+ +| type | Select records of the | Path | String | N | * pub: Publish attempt | +| | specified type | | | | * del: Delivery attempt | +| | | | | | * exp: Delivery expiry | ++------------------------+---------------------------------+------------------+------------+-------------+--------------------------------------+ +| publishId | Select records with specified | Path | String | N | | +| | publish id, carried in the | | | | | +| | X-DMAAP-DR-PUBLISH-ID header | | | | | +| | from original publish request | | | | | ++------------------------+---------------------------------+------------------+------------+-------------+--------------------------------------+ +| start | Select records created at or | Path | String | N | A date-time expressed in the format | +| | after specified date | | | | specified by RFC 3339 | ++------------------------+---------------------------------+------------------+------------+-------------+--------------------------------------+ +| end | Select records created at or | Path | String | N | A date-time expressed in the format | +| | before specified date | | | | specified by RFC 3339 | ++------------------------+---------------------------------+------------------+------------+-------------+--------------------------------------+ +| statusCode | Select records with the | Path | String | N | An HTTP Integer status code or one | +| | specified statusCode field | | | | of the following special values: | +| | | | | | | +| | | | | | * Success: Any code between 200-299 | +| | | | | | * Redirect: Any code between 300-399 | +| | | | | | * Failure: Any code > 399 | ++------------------------+---------------------------------+------------------+------------+-------------+--------------------------------------+ +| expiryReason | Select records with the | Path | String | N | | +| | specified expiry reason | | | | | ++------------------------+---------------------------------+------------------+------------+-------------+--------------------------------------+ +| filename | Select published records with | Path | String | N | | +| | the specified filename | | | | | ++------------------------+---------------------------------+------------------+------------+-------------+--------------------------------------+ + +**Response Parameters** + ++------------------------+----------------------------------------------+ +| Name | Description | ++========================+==============================================+ +| type | Record type: | +| | | +| | * pub: publication attempt | +| | * del: delivery attempt | +| | * exp: delivery expiry | ++------------------------+----------------------------------------------+ +| date | The UTC date and time at which the record | +| | was generated, with millisecond resolution | +| | in the format specified by RFC 3339 | ++------------------------+----------------------------------------------+ +| publishId | The unique identifier assigned by the DR | +| | at the time of the initial publication | +| | request (carried in the X-DMAAP-DR-PUBLISH-ID| +| | header in the response to the original | +| | publish request) | ++------------------------+----------------------------------------------+ +| requestURI | The Request-URI associated with the | +| | request | ++------------------------+----------------------------------------------+ +| method | The HTTP method (PUT or DELETE) for the | +| | request | ++------------------------+----------------------------------------------+ +| contentType | The media type of the payload of the | +| | request | ++------------------------+----------------------------------------------+ +| contentLength | The size (in bytes) of the payload of | +| | the request | ++------------------------+----------------------------------------------+ +| sourceIp | The IP address from which the request | +| | originated | ++------------------------+----------------------------------------------+ +| endpointId | The identity used to submit a publish | +| | request to the DR | ++------------------------+----------------------------------------------+ +| deliveryId | The identity used to submit a delivery | +| | request to a subscriber endpoint | ++------------------------+----------------------------------------------+ +| statusCode | The HTTP status code in the response to | +| | the request. A value of -1 indicates that | +| | the DR was not able to obtain an HTTP | +| | status code | ++------------------------+----------------------------------------------+ +| expiryReason | The reason that delivery attempts were | +| | discontinued: | +| | | +| | * notRetryable: The last delivery attempt | +| | encountered an error condition for which | +| | the DR does not make retries. | +| | * retriesExhausted: The DR reached its | +| | limit for making further retry attempts | ++------------------------+----------------------------------------------+ +| attempts | Total number of attempts made before | +| | delivery attempts were discontinued | ++------------------------+----------------------------------------------+ +| filename | File name associated with a publish record | ++------------------------+----------------------------------------------+ + +**Response Codes** + +* Success: + 200 + +* Error: + See `Response Codes`_ + +**Produces** + application/json + + +**Sample Request** + +.. code-block:: bash + + curl -k https://{host}:{port}/feedlog/{feedId}?statusCode=204`` + +**Sample Response** + +.. code-block:: json + + [ + { + "statusCode": 204, + "publishId": "1553715307322.dmaap-dr-node", + "requestURI": "https://dmaap-dr-node/publish/1/hello", + "sourceIP": "172.19.0.1", + "method": "PUT", + "contentType": "application/octet-stream", + "endpointId": "dradmin", + "type": "pub", + "date": "2019-03-27T19:35:07.324Z", + "contentLength": 14, + "fileName": "hello" + }, + { + "statusCode": 204, + "publishId": "1553715312071.dmaap-dr-node", + "requestURI": "https://dmaap-dr-node/publish/2/hello", + "sourceIP": "172.19.0.1", + "method": "PUT", + "contentType": "application/octet-stream", + "endpointId": "onap", + "type": "pub", + "date": "2019-03-27T19:35:12.072Z", + "contentLength": 14, + "fileName": "hello2" + } + ] + + +Subscription logging +-------------------- + +**Description**: View logging information for specified subscriptions, which can be narrowed down with further parameters + +.. code-block:: bash + + GET /sublog/{subId}?{queryParam} + + +**Request parameters** + ++------------------------+---------------------------------+------------------+------------+-------------+--------------------------------------+ +| Name | Description | Param Type | Data Type | Required | Valid/Example Values | ++========================+=================================+==================+============+=============+======================================+ +| subId | Id of the subscription you want | Path | String | Y | 1 | +| | logs for | | | | | ++------------------------+---------------------------------+------------------+------------+-------------+--------------------------------------+ +| type | Select records of the | Path | String | N | * pub: Publish attempt | +| | specified type | | | | * del: Delivery attempt | +| | | | | | * exp: Delivery expiry | ++------------------------+---------------------------------+------------------+------------+-------------+--------------------------------------+ +| publishId | Select records with specified | Path | String | N | | +| | publish id, carried in the | | | | | +| | X-DMAAP-DR-PUBLISH-ID header | | | | | +| | from original publish request | | | | | ++------------------------+---------------------------------+------------------+------------+-------------+--------------------------------------+ +| start | Select records created at or | Path | String | N | A date-time expressed in the format | +| | after specified date | | | | specified by RFC 3339 | ++------------------------+---------------------------------+------------------+------------+-------------+--------------------------------------+ +| end | Select records created at or | Path | String | N | A date-time expressed in the format | +| | before specified date | | | | specified by RFC 3339 | ++------------------------+---------------------------------+------------------+------------+-------------+--------------------------------------+ +| statusCode | Select records with the | Path | String | N | An Http Integer status code or one | +| | specified statusCode field | | | | of the following special values: | +| | | | | | | +| | | | | | * Success: Any code between 200-299 | +| | | | | | * Redirect: Any code between 300-399 | +| | | | | | * Failure: Any code > 399 | ++------------------------+---------------------------------+------------------+------------+-------------+--------------------------------------+ +| expiryReason | Select records with the | Path | String | N | | +| | specified expiry reason | | | | | ++------------------------+---------------------------------+------------------+------------+-------------+--------------------------------------+ + +Response Parameters +------------------- + ++------------------------+---------------------------------------------+ +| Name | Description | ++========================+=============================================+ +| type | Record type: | +| | | +| | * pub: publication attempt | +| | * del: delivery attempt | +| | * exp: delivery expiry | ++------------------------+---------------------------------------------+ +| date | The UTC date and time at which the record | +| | was generated, with millisecond resolution | +| | in the format specified by RFC 3339 | ++------------------------+---------------------------------------------+ +| publishId | The unique identifier assigned by the DR | +| | at the time of the initial publication | +| | request(carried in the X-DMAAP-DR-PUBLISH-ID| +| | header in the response to the original | +| | publish request) to a feed log URL or | +| | subscription log URL known to the system | ++------------------------+---------------------------------------------+ +| requestURI | The Request-URI associated with the | +| | request | ++------------------------+---------------------------------------------+ +| method | The HTTP method (PUT or DELETE) for the | +| | request | ++------------------------+---------------------------------------------+ +| contentType | The media type of the payload of the | +| | request | ++------------------------+---------------------------------------------+ +| contentLength | The size (in bytes) of the payload of | +| | the request | ++------------------------+---------------------------------------------+ +| sourceIp | The IP address from which the request | +| | originated | ++------------------------+---------------------------------------------+ +| endpointId | The identity used to submit a publish | +| | request to the DR | ++------------------------+---------------------------------------------+ +| deliveryId | The identity used to submit a delivery | +| | request to a subscriber endpoint | ++------------------------+---------------------------------------------+ +| statusCode | The HTTP status code in the response to | +| | the request. A value of -1 indicates that | +| | the DR was not able to obtain an HTTP | +| | status code | ++------------------------+---------------------------------------------+ +| expiryReason | The reason that delivery attempts were | +| | discontinued: | +| | | +| | * notRetryable: The last delivery attempt | +| | encountered an error condition for which | +| | the DR does not make retries. | +| | * retriesExhausted: The DR reached its | +| | limit for making further retry attempts | ++------------------------+---------------------------------------------+ +| attempts | Total number of attempts made before | +| | delivery attempts were discontinued | ++------------------------+---------------------------------------------+ + +**Response Codes** + +* Success: + 200 + +* Error: + See `Response Codes`_ + +**Produces** + application/json + +**Sample Request** + +.. code-block:: bash + + curl -k https://{host}:{port}/sublog/{subId}?statusCode=204 + +**Sample Response** + +.. code-block:: json + + [ + { + "statusCode": 204, + "publishId": "1553715307322.dmaap-dr-node", + "requestURI": "https://dmaap-dr-node/publish/1/hello", + "sourceIP": "172.19.0.1", + "method": "PUT", + "contentType": "application/octet-stream", + "endpointId": "dradmin", + "type": "pub", + "date": "2019-03-27T19:35:07.324Z", + "contentLength": 14, + "fileName": "hello" + }, + { + "statusCode": 204, + "publishId": "1553715312071.dmaap-dr-node", + "requestURI": "https://dmaap-dr-node/publish/2/hello", + "sourceIP": "172.19.0.1", + "method": "PUT", + "contentType": "application/octet-stream", + "endpointId": "onap", + "type": "pub", + "date": "2019-03-27T19:35:12.072Z", + "contentLength": 14, + "fileName": "hello2" + } + ] + + +**Feed Authorization Object** + +.. _`Auth Object`: + ++----------------+-----------------+--------------------------------+------------------------------+ +| Field | Type | Description | Restrictions | ++================+=================+================================+==============================+ +| classification | string | An indicator of the feed’s | Length <=32 | +| | | data security classification | | ++----------------+-----------------+--------------------------------+------------------------------+ +| endpoint_ids |`EID Object`_ [] | Array of objects defining the | At least 1 id in the array | +| | | identities that are allowed | | +| | | to publish to this feed | | ++----------------+-----------------+--------------------------------+------------------------------+ +| endpoint_addrs | string[] | Array of IP addresses or IP | Each string must be a valid | +| | | subnetwork addresses that | textual representation of | +| | | are allowed to publish to this | IPv4 or IPv6 host address or | +| | | feed; an empty array indicates | subnetwork address. | +| | | that publish requests are | | +| | | permitted from any IP address | | ++----------------+-----------------+--------------------------------+------------------------------+ + + +**Endpoint Identity Object** + +.. _`EID Object`: + ++----------+--------+--------------------------+--------------+ +| Field | Type | Description | Restrictions | ++==========+========+==========================+==============+ +| id | string | Publishing endpoint | Length <= 20 | +| | | identifier | | ++----------+--------+--------------------------+--------------+ +| password | string | Password associated with | Length <= 32 | +| | | id | | ++----------+--------+--------------------------+--------------+ + + +**Feed Links Object** + +.. _`Feed Links Obj`: + ++-----------+---------------------------------------------------+----------------+ +| Field | Description | Symbolic Name | ++===========+===================================================+================+ +| self | URL pointing to this feed, used for updating and | | +| | deleting the feed. | | ++-----------+---------------------------------------------------+----------------+ +| publish | URL for publishing requests for this feed | | ++-----------+---------------------------------------------------+----------------+ +| subscribe | URL for subscribing to this feed | | ++-----------+---------------------------------------------------+----------------+ +| log | URL for accessing log information about this feed | | ++-----------+---------------------------------------------------+----------------+ + + +**Delivery Object** + +.. _`Del Object`: + ++----------+---------+-----------------------------------------------+-------------------------------------+ +| Field | Type | Description | Restrictions | ++==========+=========+===============================================+=====================================+ +| url | string | URL to which deliveries for this subscription | length <= 256 | +| | | should be directed Valid HTTPS URL | | ++----------+---------+-----------------------------------------------+-------------------------------------+ +| user | string | User ID to be passed in the Authorization | Length <= 20 | +| | | header when deliveries are made | | ++----------+---------+-----------------------------------------------+-------------------------------------+ +| password | string | Password to be passed in the Authorization | Length <= 32 | +| | | header when deliveries are made | | ++----------+---------+-----------------------------------------------+-------------------------------------+ +| use100 | boolean | Flag indicating whether the DR should use | Must be: true to use 100-continue | +| | | the HTTP 100-continue feature | | +| | | | false to disable using 100-continue | ++----------+---------+-----------------------------------------------+-------------------------------------+ + + +**Sub Links Object** + +.. _`Sub Links Obj`: + ++-----------+---------------------------------------------------+-------------------+ +| Field | Description | Symbolic Name | ++===========+===================================================+===================+ +| self | URL pointing to this subscription, used for | | +| | updating and deleting the subscription. | | ++-----------+---------------------------------------------------+-------------------+ +| feed | URL of the feed to which this subscription | | +| | applies; the same URL as the in the | | +| | representation of the feed | | ++-----------+---------------------------------------------------+-------------------+ +| log | URL for accessing log information about this | | +| | subscription | | ++-----------+---------------------------------------------------+-------------------+ + + +**Response/Error Codes** + +.. _`Response Codes`: + ++------------------------+-------------------------------------------+ +| Response statusCode | Response Description | ++========================+===========================================+ +| 200 to 299 | Success Response | ++------------------------+-------------------------------------------+ +| 400 | Bad request - The request is defective in | +| | some way. Possible causes: | +| | | +| | * JSON object in request body does not | +| | conform to the spec. | +| | * Invalid parameter value in query string | ++------------------------+-------------------------------------------+ +| 401 | Indicates that the request was missing the| +| | Authorization header or, if the header | +| | was presented, the credentials were not | +| | acceptable | ++------------------------+-------------------------------------------+ +| 403 | Forbidden - The request failed | +| | authorization. | +| | Possible causes: | +| | | +| | * Request originated from an unauthorized | +| | IP address | +| | * Client certificate subject is not on | +| | the API’s authorized list. | +| | * X-DMAAP-DR-ON-BEHALF-OF identity is not | +| | authorized to perform | ++------------------------+-------------------------------------------+ +| 404 | Not Found - The Request-URI does not point| +| | to a resource that is known to the API. | ++------------------------+-------------------------------------------+ +| 405 | Method Not Allowed - The HTTP method in | +| | the request is not supported for the | +| | resource addressed by the Request-URI. | ++------------------------+-------------------------------------------+ +| 406 | Not Acceptable - The request has an Accept| +| | header indicating that the requester will | +| | not accept a response with | +| | application/vnd.dmaap-dr.log-list content.| ++------------------------+-------------------------------------------+ +| 415 | Unsupported Media Type - The media type in| +| | the requests Content-Type header is not | +| | appropriate for the request. | ++------------------------+-------------------------------------------+ +| 500 | Internal Server Error - The DR API server | +| | encountered an internal error and could | +| | not complete the request. | ++------------------------+-------------------------------------------+ +| 503 | Service Unavailable - The DR API service | +| | is currently unavailable | ++------------------------+-------------------------------------------+ +| -1 | Failed Delivery | ++------------------------+-------------------------------------------+ \ No newline at end of file diff --git a/docs/data-router/release-notes.rst b/docs/release-notes.rst similarity index 99% rename from docs/data-router/release-notes.rst rename to docs/release-notes.rst index b879c6bc..12014e69 100644 --- a/docs/data-router/release-notes.rst +++ b/docs/release-notes.rst @@ -1,12 +1,16 @@ .. This work is licensed under a Creative Commons Attribution 4.0 International License. .. http://creativecommons.org/licenses/by/4.0 +.. toctree:: + :maxdepth: 2 + Release-notes ============== -Version: 1.0.3 (Casablanca) + +Version: 2.0.1 (Dublin) --------------------------- -:Release Date: 2018-11-30 +:Release Date: 2019-02-28 The DataRouter(DR) provisioning API is a HTTPS-based, REST-like API for creating and managing DR feeds and subscriptions. @@ -16,24 +20,22 @@ New Features: +--------------+------------------------------------------------------------------+ | JIRA ID | Description | +==============+==================================================================+ -| DMAAP-20 | REST api for publishing data to DR | -+--------------+------------------------------------------------------------------+ -| DMAAP-21 | REST api for subscribing to data in DR | +| DMAAP-988 | Update to new oparent | +--------------+------------------------------------------------------------------+ Bug Fixes: -+----------------+---------------------------------------------------------------------------------------------------------------------------------+ -| JIRA ID | Description | -+================+=================================================================================================================================+ -| DMAAP-877 | DR Logging API not storing Feed/Sub data | -+----------------+---------------------------------------------------------------------------------------------------------------------------------+ -| DMAAP-850 | Second subscriber not receiving the published file | -+----------------+---------------------------------------------------------------------------------------------------------------------------------+ -| DMAAP-596 | DR - datarouter-prov container fails to come up successfully | -+----------------+---------------------------------------------------------------------------------------------------------------------------------+ -| DMAAP-565 | Incorrect nexusUrl parameter in datarouter pom files | -+----------------+---------------------------------------------------------------------------------------------------------------------------------+ ++----------------+--------------------------------------------------------------------------------------------------+ +| JIRA ID | Description | ++================+==================================================================================================+ +| DMAAP-964 | DMAAP deployment failures starting 20190115 on casablanca branch | ++----------------+--------------------------------------------------------------------------------------------------+ +| DMAAP-1047 | Data Router docker version missing explicit version number | ++----------------+--------------------------------------------------------------------------------------------------+ +| DMAAP-1048 | [DR] AAF certs expired on dmaap-dr-prov and dmaap-dr-node | ++----------------+--------------------------------------------------------------------------------------------------+ +| DMAAP-1064 | [DR] Update datarouter POM version following AAF cert updates | ++----------------+--------------------------------------------------------------------------------------------------+ Known Issues N/A @@ -56,6 +58,7 @@ N/A Other N/A + Version: 1.0.8 (Casablanca) --------------------------- @@ -101,10 +104,10 @@ Other N/A -Version: 2.0.1 (Dublin) +Version: 1.0.3 (Casablanca) --------------------------- -:Release Date: 2019-02-28 +:Release Date: 2018-11-30 The DataRouter(DR) provisioning API is a HTTPS-based, REST-like API for creating and managing DR feeds and subscriptions. @@ -114,22 +117,24 @@ New Features: +--------------+------------------------------------------------------------------+ | JIRA ID | Description | +==============+==================================================================+ -| DMAAP-988 | Update to new oparent | +| DMAAP-20 | REST api for publishing data to DR | ++--------------+------------------------------------------------------------------+ +| DMAAP-21 | REST api for subscribing to data in DR | +--------------+------------------------------------------------------------------+ Bug Fixes: -+----------------+--------------------------------------------------------------------------------------------------+ -| JIRA ID | Description | -+================+==================================================================================================+ -| DMAAP-964 | DMAAP deployment failures starting 20190115 on casablanca branch | -+----------------+--------------------------------------------------------------------------------------------------+ -| DMAAP-1047 | Data Router docker version missing explicit version number | -+----------------+--------------------------------------------------------------------------------------------------+ -| DMAAP-1048 | [DR] AAF certs expired on dmaap-dr-prov and dmaap-dr-node | -+----------------+--------------------------------------------------------------------------------------------------+ -| DMAAP-1064 | [DR] Update datarouter POM version following AAF cert updates | -+----------------+--------------------------------------------------------------------------------------------------+ ++----------------+---------------------------------------------------------------------------------------------------------------------------------+ +| JIRA ID | Description | ++================+=================================================================================================================================+ +| DMAAP-877 | DR Logging API not storing Feed/Sub data | ++----------------+---------------------------------------------------------------------------------------------------------------------------------+ +| DMAAP-850 | Second subscriber not receiving the published file | ++----------------+---------------------------------------------------------------------------------------------------------------------------------+ +| DMAAP-596 | DR - datarouter-prov container fails to come up successfully | ++----------------+---------------------------------------------------------------------------------------------------------------------------------+ +| DMAAP-565 | Incorrect nexusUrl parameter in datarouter pom files | ++----------------+---------------------------------------------------------------------------------------------------------------------------------+ Known Issues N/A @@ -150,4 +155,4 @@ Deprecation Notes N/A Other -N/A \ No newline at end of file +N/A -- 2.16.6