CPS-393 - Getting issue details... STATUS

Spike Description

Investigate A&AI interface, especially how to register and receive DMaaP Events from A&AI. Investigate filter-options and consider some PoC code.

Issues & Decisions

#DescriptionNotesDecision
1AAI failed to send DMaaP notification after xNF was created

AAI-3350 - Getting issue details... STATUS  

The bug causing this error was fixed and changes have been merged.
2DMaap Client failed because of dependency Issues

DMAAP-1627 - Getting issue details... STATUS

The bug causing this error was fixed and changes have been submitted.
3

setFilter() is not documented

Fiachra Corcoran (DMaaP) advised any existing documentation is out of date and this should not be used

Toine Siebelink  

Based on input from (DMaaP) team and possible lack of future support we will do filtering on client side

4Decide on which property to filter onWhich property from the DMaaP event should we filter on?
5Update Events for address informationis it possible for address information to change ie. does CPS need to  listen to these?Address information might change but we don't need to worry about it for our use case as we use SDN-C and only the pnf-id to identify the resource

Background

When a xNF object is added to A&AI, a DMaaP event, AAI-EVENT is created. A&AI handles the publishing of this event. To be notified of the AAI-EVENT, CPS will need to register on DMaaP Message Router.

DMaaP offers a client plugin called DMaaP Client, which can be found here. This Client can be used to register to a DMaaP event. The PoC code will use this client to show that CPS can listen for and receive DMaaP events.

Filtering of AAI-EVENT

Based on input from the DMaaP team, the filtering will be done on client side. From looking at the DMaaP event that is created when a xNF is created, we can filter on the following properties: 

  • equip-type
  • equip-vendor
  • equip-model

AAI-EVENT received from DMaaP

AAI-EVENT received from DMaaP can have different event-header.action values. These are:

  1. CREATE
  2. UPDATE
  3. DELETE

Each action value refers to the type of operation happening to a xNF on A&AI. When a xNF is added to A&AI, the event-header.action value is CREATE. When a xNF is updated in A&AI, the event-header.action value is UPDATE. When a xNF is deleted in A&AI, the event-header.action value is DELETE.

Example of DMaaP Event when a xNF is added to A&AI:

DMaaP Event: action=CREATE
{
	"cambria.partition":"AAI",
	"event-header":{
        "severity":"NORMAL",
        "entity-type":"pnf",
        "top-entity-type":"pnf",
        "entity-link":"/aai/v23/network/pnfs/pnf/dummyTest30",
        "event-type":"AAI-EVENT",
        "domain":"dev",
        "action":"CREATE",
        "sequence-number":"0","id":"577eb229-7c74-4cf8-84ab-79f66f4899b2",
        "source-name":"SO",
        "version":"v23",
        "timestamp":"20210701-12:45:09:351"
    },
    "entity":{
        "ipaddress-v4-oam":"100.10.20.20",
        "equip-type":"example-equip-type-val-20348",
        "equip-vendor":"example-equip-vendor-val-52182",
        "ipaddress-v6-oam":"",
        "orchestration-status":"Active",
        "pnf-name2":"dummypnf-1597953056126",
        "equip-model":"example-equip-model-val-8370",
        "in-maint":false,
        "resource-version":"1625143508438",
        "pnf-id":"927b2580-36d9-4f13-8421-3c9d43b7a75e",
        "management-option":"example-management-option-val-72881",
        "spare-equipment-indicator":false,
        "pnf-name":"dummyTest30"
	}
}

Example of DMaaP Event when a xNF is updated in A&AI:

DMaaP Event: action=UPDATE
{
	"cambria.partition":"AAI",
	"event-header":{
		"severity":"NORMAL",
		"entity-type":"pnf",
		"top-entity-type":"pnf",
		"entity-link":"/aai/v23/network/pnfs/pnf/dummyTest16",
		"event-type":"AAI-EVENT","domain":"dev","action":"UPDATE",
		"sequence-number":"0","id":"51a99267-83ec-4f4f-a676-690ba527bf78",
		"source-name":"SO","version":"v23","timestamp":"20210705-15:18:37:452"
	},
	"entity":{
		"ipaddress-v4-oam":"100.10.20.20",
		"equip-type":"example-equip-type-val-20348",
		"equip-vendor":"example-equip-vendor-val-52182",
		"ipaddress-v6-oam":"",
		"orchestration-status":"Active",
		"pnf-name2":"dummypnf-1597953056126",
		"equip-model":"example-equip-model-val-8370",
		"in-maint":false,
		"resource-version":"1625498316100",
		"pnf-id":"927b2580-36d9-4f13-8421-3c9d43b7a75e",
		"management-option":"example-management-option-val-72881",
		"spare-equipment-indicator":false,
		"pnf-name":"dummyTest16"
	}
}

Example of DMaaP Event when a xNF is deleted in A&AI:

DMaaP Event: action=DELETE
{
	"cambria.partition":"AAI",
	"event-header":{
		"severity":"NORMAL",
		"entity-type":"pnf",
		"top-entity-type":"pnf",
		"entity-link":"/aai/v23/network/pnfs/pnf/dummyTest15",
		"event-type":"AAI-EVENT",
		"domain":"dev",
		"action":"DELETE",
		"sequence-number":"0",
		"id":"bd5eabee-24fa-4567-999a-f35814e8c6c2",
		"source-name":"SO",
		"version":"v23",
		"timestamp":"20210705-13:34:08:464"
	},
	"entity":{
		"ipaddress-v4-oam":"100.10.20.20",
		"equip-type":"example-equip-type-val-20348",
		"equip-vendor":"example-equip-vendor-val-52182",
		"ipaddress-v6-oam":"",
		"orchestration-status":"Active",
		"pnf-name2":"dummypnf-1597953056126",
		"equip-model":"example-equip-model-val-8370",
		"in-maint":false,
		"resource-version":"1623155630173",
		"pnf-id":"927b2580-36d9-4f13-8421-3c9d43b7a75e",
		"management-option":"example-management-option-val-72881",
		"spare-equipment-indicator":false,
		"pnf-name":"dummyTest15"
	}
}


Proof Of Concept Code

Adding DMaaP Client dependency

To use the DMaaP Client we need the following dependency in our pom.xml file.

DMaaP Client dependency in pom.xml
    <dependency>
        <groupId>org.onap.dmaap.messagerouter.dmaapclient</groupId>
        <artifactId>dmaapClient</artifactId>
        <version>1.1.12</version>
    </dependency>

Creating DMaaP consumer client 

The following builder method is used to create an instance of a DMaaP Consumer Client:

Example DMaaP Consumer Client
final MRConsumerImpl mrConsumer = new MRConsumerImpl.MRConsumerImplBuilder().setHostPart(hosts)
                .setTopic("AAI-EVENT").setConsumerGroup("onap-cps").setConsumerId("cps-ncmp").setTimeoutMs(10000)
                .setLimit(1000).setFilter("").setApiKey_username(null)
                .setApiSecret_password(null).createMRConsumerImpl();

*Note setFilter() method is not documented and we have been advised by DMaaP team not to use it. So all filtering as to be done on client side. See also issue #2

For the Consumer client to be created we need to pass in the values for the following attributes:

Attribute nameAttribute DescriptionExample
setHostPart

The host and port of the DMaaP server in the format <host:port>. This method takes a collection of strings, check example.

Example of HostPart
final Collection<String> hosts = new ArrayList<>();
hosts.add("message-router.onap:3904");
setTopicThe topic name to consume from"AAI-EVENT"
setConsumerGroupA name that uniquely identifies the subscriber's group"onap-cps"
setConsumerIdWithin the subscriber's group, a name that uniquely identifies the subscriber's process"cps-ncmp"
setTimeoutMsTime in ms to wait for messages on the server before returning10000
setLimitMaximum number of messages that is returned per fetch1000
setFilterA customizable message filter, or null if no filtering is requirednull
setApiKey_usernameThe username of the client applicationnull
setApiSecret_passwordThe password for the usernamenull

Adding required properties to the consumer

The consumer also takes in the following properties:

Setting the Protocol Flag
# This Specifies the request header type used in the request to DMaaP server.
# Valid types:
#   DME2
#   HTTPAAF
#   HTTPAUTH
#   HTTPNOAUTH
# For this POC we use the HTTPNOAUTH, this supports both https and http protocols.

mrConsumer.setProtocolFlag("HTTPNOAUTH");
Setting the Protocol property
# The http protocol to use:
# http
# https

final Properties props = new Properties();
props.setProperty("Protocol", "http");
mrConsumer.setProps(props);

Fetching DMaaP event using the consumer object

To fetch, the following method needs to be called on the consumer object:

Fetch Method Example
mrConsumer.fetch()

POC code used in the demo

Demo POC code
public static void main(String[] args) throws Exception {
	final Collection<String> hosts = new ArrayList<>();
    hosts.add("message-router.onap:3904");
    final MRConsumerImpl mrConsumer = new MRConsumerImpl.MRConsumerImplBuilder().setHostPart(hosts)
    	.setTopic("AAI-EVENT").setConsumerGroup("cg").setConsumerId("cid").setTimeoutMs(10000)
        .setLimit(1000).setFilter("").setApiKey_username(null)
        .setApiSecret_password(null).createMRConsumerImpl();
	mrConsumer.setProtocolFlag("HTTPNOAUTH");
    final Properties props = new Properties();
    props.setProperty("Protocol", "http");
    mrConsumer.setProps(props);
    log.info("fetch {}", mrConsumer.fetch());
}


  • No labels