aboutsummaryrefslogtreecommitdiffstats
path: root/docs/cm-notification-subscriptions.rst
blob: e1d1c2f8004f6463c8eda6bc12019a6fd25af613 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
.. This work is licensed under a Creative Commons Attribution 4.0 International License.
.. http://creativecommons.org/licenses/by/4.0
.. Copyright (C) 2024 Nordix Foundation

.. DO NOT CHANGE THIS LABEL FOR RELEASE NOTES - EVEN THOUGH IT GIVES A WARNING
.. _cmNotificationSubscriptions:


CM Data Subscriptions and Notifications
#######################################

.. toctree::
   :maxdepth: 1

CM Data Subscriptions
=====================
CM Subscriptions are created to subscribe to notifications for CM related changes that happened in the network based on predicates.
Predicates can be used to filter on CM Handle (id), Datastore and Xpath.

The CM Subscription flow is event driven and adheres to the CNCF Cloud Events Specifications.

Event to create and delete a subscription.

:download:`CM Subscription Event Schema <schemas/ncmp-in-event-schema-1.0.0.json>`

Event to receive status of participants in a subscription.

:download:`CM Subscription Response Event Schema <schemas/ncmp-out-event-schema-1.0.0.json>`

CM Subscriptions Creation
-------------------------
To create a subscription, a client sends an event to a configured topic to register its interest with NCMP allowing the client to receive notifications based on the subscription.

CM Subscriptions Deletion
-------------------------
If a client no longer wishes to receive notifications based on a registered subscription, the client can delete the subscription by providing the subscription id.

CM Subscriptions Response
-------------------------
The response for the involved subscription participants for the Create and Delete flow can be as follows based on how the DMI Plugin responds back to NCMP.
    - **ACCEPTED:** DMI Plugin successfully applied the subscription.
    - **REJECTED:** DMI Plugin failed to apply the subscription.
    - **PENDING:** DMI Plugin failed to respond within a configured time.

**Note.** The Cm Subscription feature relies on the DMI Plugin support for applying the subscriptions. This support is currently not implemented in the ONAP DMI Plugin.

CM Data Notifications
=====================
CM Notifications are triggered by any change in the network, provided the client has already set up a CM Subscription to receive such notifications. Once the events are generated, they are processed by NCMP and forwarded to the client in the same format.

**Note.** Currently, CM Notifications are sent regardless of the CM Subscriptions. Notifications controlled by CM Subscription have not yet been delivered.

The CM Notification Event follows the structure outlined in the schema below:

:download:`CM Data Notification Event Schema <schemas/dmidataavc/avc-event-schema-1.0.0.json>`

**Note.** NCMP uses the CM Notification event key from the source topic to forward notifications to the client, ensuring that the order of notifications within a topic partition is maintained during forwarding.
**Note.** If the notification key from the source topic is null, NCMP cannot guarantee the order of events within a topic partition when forwarding.
f8f2 } /* Name.Variable.Magic */ .highlight .il { color: #ae81ff } /* Literal.Number.Integer.Long */ } @media (prefers-color-scheme: light) { .highlight .hll { background-color: #ffffcc } .highlight .c { color: #888888 } /* Comment */ .highlight .err { color: #a61717; background-color: #e3d2d2 } /* Error */ .highlight .k { color: #008800; font-weight: bold } /* Keyword */ .highlight .ch { color: #888888 } /* Comment.Hashbang */ .highlight .cm { color: #888888 } /* Comment.Multiline */ .highlight .cp { color: #cc0000; font-weight: bold } /* Comment.Preproc */ .highlight .cpf { color: #888888 } /* Comment.PreprocFile */ .highlight .c1 { color: #888888 } /* Comment.Single */ .highlight .cs { color: #cc0000; font-weight: bold; background-color: #fff0f0 } /* Comment.Special */ .highlight .gd { color: #000000; background-color: #ffdddd } /* Generic.Deleted */ .highlight .ge { font-style: italic } /* Generic.Emph */ .highlight .gr { color: #aa0000 } /* Generic.Error */ .highlight .gh { color: #333333 } /* Generic.Heading */ .highlight .gi { color: #000000; background-color: #ddffdd } /* Generic.Inserted */ .highlight .go { color: #888888 } /* Generic.Output */ .highlight .gp { color: #555555 } /* Generic.Prompt */ .highlight .gs { font-weight: bold } /* Generic.Strong */ .highlight .gu { color: #666666 } /* Generic.Subheading */ .highlight .gt { color: #aa0000 } /* Generic.Traceback */ .highlight .kc { color: #008800; font-weight: bold } /* Keyword.Constant */ .highlight .kd { color: #008800; font-weight: bold } /* Keyword.Declaration */ .highlight .kn { color: #008800; font-weight: bold } /* Keyword.Namespace */ .highlight .kp { color: #008800 } /* Keyword.Pseudo */ .highlight .kr { color: #008800; font-weight: bold } /* Keyword.Reserved */ .highlight .kt { color: #888888; font-weight: bold } /* Keyword.Type */ .highlight .m { color: #0000DD; font-weight: bold } /* Literal.Number */ .highlight .s { color: #dd2200; background-color: #fff0f0 } /* Literal.String */ .highlight .na { color: #336699 } /* Name.Attribute */ .highlight .nb { color: #003388 } /* Name.Builtin */ .highlight .nc { color: #bb0066; font-weight: bold } /* Name.Class */ .highlight .no { color: #003366; font-weight: bold } /* Name.Constant */ .highlight .nd { color: #555555 } /* Name.Decorator */ .highlight .ne { color: #bb0066; font-weight: bold } /* Name.Exception */ .highlight .nf { color: #0066bb; font-weight: bold } /* Name.Function */ .highlight .nl { color: #336699; font-style: italic } /* Name.Label */ .highlight .nn { color: #bb0066; font-weight: bold } /* Name.Namespace */ .highlight .py { color: #336699; font-weight: bold } /* Name.Property */ .highlight .nt { color: #bb0066; font-weight: bold } /* Name.Tag */ .highlight .nv { color: #336699 } /* Name.Variable */ .highlight .ow { color: #008800 } /* Operator.Word */ .highlight .w { color: #bbbbbb } /* Text.Whitespace */ .highlight .mb { color: #0000DD; font-weight: bold } /* Literal.Number.Bin */ .highlight .mf { color: #0000DD; font-weight: bold } /* Literal.Number.Float */ .highlight .mh { color: #0000DD; font-weight: bold } /* Literal.Number.Hex */ .highlight .mi { color: #0000DD; font-weight: bold } /* Literal.Number.Integer */ .highlight .mo { color: #0000DD; font-weight: bold } /* Literal.Number.Oct */ .highlight .sa { color: #dd2200; background-color: #fff0f0 } /* Literal.String.Affix */ .highlight .sb { color: #dd2200; background-color: #fff0f0 } /* Literal.String.Backtick */ .highlight .sc { color: #dd2200; background-color: #fff0f0 } /* Literal.String.Char */ .highlight .dl { color: #dd2200; background-color: #fff0f0 } /* Literal.String.Delimiter */ .highlight .sd { color: #dd2200; background-color: #fff0f0 } /* Literal.String.Doc */ .highlight .s2 { color: #dd2200; background-color: #fff0f0 } /* Literal.String.Double */ .highlight .se { color: #0044dd; background-color: #fff0f0 } /* Literal.String.Escape */ .highlight .sh { color: #dd2200; background-color: #fff0f0 } /* Literal.String.Heredoc */ .highlight .si { color: #3333bb; background-color: #fff0f0 } /* Literal.String.Interpol */ .highlight .sx { color: #22bb22; background-color: #f0fff0 } /* Literal.String.Other */ .highlight .sr { color: #008800; background-color: #fff0ff } /* Literal.String.Regex */ .highlight .s1 { color: #dd2200; background-color: #fff0f0 } /* Literal.String.Single */ .highlight .ss { color: #aa6600; background-color: #fff0f0 } /* Literal.String.Symbol */ .highlight .bp { color: #003388 } /* Name.Builtin.Pseudo */ .highlight .fm { color: #0066bb; font-weight: bold } /* Name.Function.Magic */ .highlight .vc { color: #336699 } /* Name.Variable.Class */ .highlight .vg { color: #dd7700 } /* Name.Variable.Global */ .highlight .vi { color: #3333bb } /* Name.Variable.Instance */ .highlight .vm { color: #336699 } /* Name.Variable.Magic */ .highlight .il { color: #0000DD; font-weight: bold } /* Literal.Number.Integer.Long */ }
<!DOCTYPE html>
<html>
<head>
  <meta charset="UTF-8">
  <title>API Docs</title>
  <link rel="SHORTCUT ICON" href="images/favicon.ico"/>
  <link href='css/typography.css' media='screen' rel='stylesheet' type='text/css'/>
  <link href='css/reset.css' media='screen' rel='stylesheet' type='text/css'/>
  <link href='css/screen.css' media='screen' rel='stylesheet' type='text/css'/>
  <link href='css/reset.css' media='print' rel='stylesheet' type='text/css'/>
  <link href='css/print.css' media='print' rel='stylesheet' type='text/css'/>
  <!--Custom: Take from application\frontend\nfv-client\dist\optimize\resources\nfv\css\style.css-->
  <link href='css/ncso-style.css' rel='stylesheet' type='text/css'/>
  <!--/Custom: Take from application\frontend\nfv-client\dist\optimize\resources\nfv\css\style.css-->

  <script src='lib/jquery-1.8.0.min.js' type='text/javascript'></script>
  <script src='lib/jquery.slideto.min.js' type='text/javascript'></script>
  <script src='lib/jquery.wiggle.min.js' type='text/javascript'></script>
  <script src='lib/jquery.ba-bbq.min.js' type='text/javascript'></script>
  <script src='lib/handlebars-2.0.0.js' type='text/javascript'></script>
  <script src='lib/underscore-min.js' type='text/javascript'></script>
  <script src='lib/backbone-min.js' type='text/javascript'></script>
  <script src='swagger-ui.js' type='text/javascript'></script>
  <script src='lib/highlight.7.3.pack.js' type='text/javascript'></script>
  <script src='lib/marked.js' type='text/javascript'></script>
  <script src='lib/swagger-oauth.js' type='text/javascript'></script>

  <!-- Some basic translations -->
  <!-- <script src='lang/translator.js' type='text/javascript'></script> -->
  <!-- <script src='lang/ru.js' type='text/javascript'></script> -->
  <!-- <script src='lang/en.js' type='text/javascript'></script> -->

  <script type="text/javascript">
    $(function () {
      var url = window.location.protocol + "//" + window.location.host;
      if (window.location.pathname.indexOf('/api-docs') > 0) {
        url += window.location.pathname.substring(0, window.location.pathname.indexOf('/api-docs'))
      }
      url += "/api-docs/api.json";
      log('API URL: ' + url);

      // Pre load translate...
      if(window.SwaggerTranslator) {
        window.SwaggerTranslator.translate();
      }
      window.swaggerUi = new SwaggerUi({
        url: url,
        dom_id: "swagger-ui-container",
        supportedSubmitMethods: ['get', 'post', 'put', 'delete', 'patch'],
        onComplete: function(swaggerApi, swaggerUi){
          if(typeof initOAuth == "function") {
            initOAuth({
              clientId: "your-client-id",
              clientSecret: "your-client-secret",
              realm: "your-realms",
              appName: "your-app-name", 
              scopeSeparator: ","
            });
          }

          if(window.SwaggerTranslator) {
            window.SwaggerTranslator.translate();
          }

          $('pre code').each(function(i, e) {
            hljs.highlightBlock(e)
          });

        },
        onFailure: function(data) {
          log("Unable to Load SwaggerUI");
        },
        docExpansion: "none",
        apisSorter: "alpha",
        showRequestHeaders: false
      });


      window.swaggerUi.load();

      function log() {
        if ('console' in window) {
          console.log.apply(console, arguments);
        }
      }
  });
  </script>

    <!-- Hide the swagger io  -->
    <style>
        .footer a, .footer img{
            display: none !important;
        }
    </style>
</head>

<body class="swagger-section">

<!--NCSO script-->
<script>

  //SET TITLE - START
  function pollData() {
    if(!(document.querySelector('#api_info .info_title') && document.querySelector('#api_info .info_title').innerText)) {
      setTimeout(pollData, 50);
    }
    else {
      setData();
    }
  }

  function setData() {
    document.querySelector('[data-uxf-point="main-title"]').innerText = document.querySelector('#api_info .info_title').innerText;
    document.querySelector('#api_info .info_title').innerText = '';
  }

  pollData();
  //SET TITLE - END

  var __LOGIN_REST_STATUS = {OPEN: 'OPEN', SEND: 'SEND'};
  var __loginPath = '/auth/tokens', __isLoginInProcess, __xAuthToken;

  function isAuthanticationRest(path) {
      return path.endsWith(__loginPath);
  }

  //Proxy requests - START

  //Proxy Open Method
  (function() {
      var proxiedOpen = window.XMLHttpRequest.prototype.open;
      window.XMLHttpRequest.prototype.open = function(method, path) {
          if(isAuthanticationRest(path)) {
              __isLoginInProcess = true;
          }
          else {
              __isLoginInProcess = false;
          }
          return proxiedOpen.apply(this, Array.prototype.slice.call(arguments));
      };
  })();

  //Proxy Send Method - X-AUTH-STUFF
  (function() {
      var proxiedSend = window.XMLHttpRequest.prototype.send;
      window.XMLHttpRequest.prototype.send = function() {
          if(__isLoginInProcess) {
              proxyAuthanticationCallback(this);
          }
          return proxiedSend.apply(this, Array.prototype.slice.call(arguments));
      };
  })();

  //Proxy Authantication Callback Method - X-AUTH-STUFF
  function proxyAuthanticationCallback(xhrObject) {
      var proxy = xhrObject.onreadystatechange;
      xhrObject.onreadystatechange = function() {
          if (xhrObject.readyState == 4) {
              if(xhrObject.status == 200 || xhrObject.status == 401) {
                  window.swaggerUi.api.clientAuthorizations.remove('X-AUTH-TOKEN');
                  if(xhrObject.status == 200) {
                      var key = xhrObject.getResponseHeader('x-auth-token');
                      if(key && key.trim() != "") {
                          var apiKeyAuth = new SwaggerClient.ApiKeyAuthorization("X-AUTH-TOKEN", key, "header");
                          window.swaggerUi.api.clientAuthorizations.add("X-AUTH-TOKEN", apiKeyAuth);
                          console.log("added x-auth-key ", key);
                      }
                  }
              }
          }
          return proxy.apply(xhrObject, Array.prototype.slice.call(arguments));
      }
  }

  //Proxy Send Method - CUSTOM HEADERS STUFF
  (function () {
      var proxiedSend = window.XMLHttpRequest.prototype.send;
      window.XMLHttpRequest.prototype.send = function () {
          var headerItems = document.querySelectorAll('.custom-headers .headers-list .header-item');
          if (headerItems) {
              Array.prototype.forEach.call(headerItems, function (header) {
                  var headerName = header.querySelector('.header-name').value;
                  var headerValue = header.querySelector('.header-value').value;
                  if (headerName && headerValue) {
                      this.setRequestHeader(headerName, headerValue);
                  }
              }, this);
          }
          return proxiedSend.apply(this, Array.prototype.slice.call(arguments));
      };
  })();

  //Proxy requests - END

</script>

<div data-uxf-point="nfv-header" class="nfv-header">
  <div class="header-content-wrapper">
    <div data-uxf-point="nfv-logo" class="nfv-logo"><a href="../ncso/landingpage.html">VENDOR</a></div>
    <div data-uxf-point="header-title" class="header-title">
      <div data-uxf-point="main-title" class="main-title"></div>
      <div data-uxf-point="version-controller" class="version-select"></div>
      <div data-uxf-point="sub-title" class="sub-title"></div>
    </div>
  </div>
</div>

<div class="custom-headers">
    <style>
        .custom-headers {
            margin-left: 124px;
            width: 500px;
            border: 1px solid #419EF1;
        }

        .custom-headers .headers-title {
            background-color: #0F6AB4;
            height: 24px;
            color: white;
            text-align: center;
            font-size: 1.2em;
        }

        .custom-headers .headers-list .header-item {
            display: flex;
            justify-content: space-around;
            padding: 10px 5px 0 5px;
        }

        .custom-headers .headers-list .header-item.default-item .header-col.header-delete {
            visibility: hidden;
        }

        .custom-headers .headers-list .header-item.default-item .header-col.header-name {
            pointer-events: none;
        }

        .custom-headers .headers-list .header-item .header-col.header-delete {
            cursor: pointer;
            align-self: center;
        }

        .custom-headers .add-header {
            text-align: right;
            padding: 5px;
            border-top: 1px solid #0F6AB4;
            margin-top: 10px;
            background-color: #E7F6EC;
        }

        .custom-headers .add-header .add-header-button, .custom-headers .add-header .reset-header-button {

            text-decoration: none;
            color: white;
            display: inline-block;
            width: 50px;
            font-size: 0.9em;
            text-align: center;
            padding: 7px 0 4px;
            -moz-border-radius: 2px;
            -webkit-border-radius: 2px;
            -o-border-radius: 2px;
            -ms-border-radius: 2px;
            -khtml-border-radius: 2px;
            border-radius: 2px;
            background-color: #0f6ab4;
            cursor: pointer;
        }

        .custom-headers .add-header .reset-header-button {

        }
    </style>
    <div class="headers-title">Custom Headers</div>
    <div class="headers-list">
        <!--Dynamically add headers using addHeaderItem function-->
    </div>
    <div class="add-header">
        <span class="reset-header-button" onclick="resetHeaderItems();">Reset</span>
        <span class="add-header-button" onclick="addHeaderItem();">Add</span>
    </div>
    <script>
        function addHeaderItem(defaultName, defaultValue) {

            var headerItemName = document.createElement('input');
            headerItemName.type = 'text';
            headerItemName.value = defaultName || '';
            headerItemName.classList.add('header-col', 'header-name');

            var headerItemValue = document.createElement('input');
            headerItemValue.type = 'text';
            headerItemValue.value = defaultValue || '';
            headerItemValue.classList.add('header-col', 'header-value');

            var headerItemDelete = document.createElement('div');
            headerItemDelete.innerHTML = '&#10006;';
            headerItemDelete.classList.add('header-col', 'header-delete');

            var headerItem = document.createElement('div');
            headerItem.classList.add('header-item');
            headerItem.appendChild(headerItemName);
            headerItem.appendChild(headerItemValue);
            headerItem.appendChild(headerItemDelete);

            headerItemDelete.onclick = function () {
                headersList.removeChild(headerItem);
            };

            var headersList = document.querySelector('.custom-headers .headers-list');
            headersList.appendChild(headerItem);

            return headerItem;
        }
        function resetHeaderItems() {
            var headersList = document.querySelector('.custom-headers .headers-list');
            while (headersList.firstChild) {
                headersList.removeChild(headersList.firstChild);
            }
            var defaultHeaderItem = addHeaderItem('USER_ID');
            defaultHeaderItem.classList.add('default-item');
        }
        resetHeaderItems();
    </script>
</div>
<div id="message-bar" class="swagger-ui-wrap" data-sw-translate>&nbsp;</div>
<div id="swagger-ui-container" class="swagger-ui-wrap"></div>
</body>
</html>