Versions Compared

Key

  • This line was added.
  • This line was removed.
  • Formatting was changed.


Warning

This spike is a WIP



Table of Contents


Jira
serverONAP Jira
serverId425b2b0a-557c-3c0c-b515-579789cceedb
keyCPS-821


Description/Scope


The scope of this spike is to ascertain:

  • How to use messaging (producer, agree topic etc))
  • Using existing rest endpoint with additional flag indicating async response
  • Also consider asynchronous request option using messaging in the proposal


Associated Jira Created for Implementation

Jira
serverONAP Jira
columnIdsissuekey,summary,issuetype,created,updated,duedate,assignee,reporter,priority,status,resolution
columnskey,summary,type,created,updated,due,assignee,reporter,priority,status,resolution
maximumIssues20
jqlQuerykey = CPS-828
serverId425b2b0a-557c-3c0c-b515-579789cceedb

Issues/Decisions


#IssueDecisionNotes/Jira
1What topic to use? proposed ncmp-async-xxx

2Are adding a new REST endpoint for async or modifying an existing endpoint?

Jira
serverONAP Jira
serverId425b2b0a-557c-3c0c-b515-579789cceedb
keyCPS-830

3Agree URL for async once #2 is clarified

4passthrough request need to be able to handle different response types (using accept header) but the async option would have a fixed and possibly different response type.

5How many messages are we expecting at peak time?

6Should we create a standalone app to demo or are tests sufficient?

7

Do we need to persist the generated requestID?



8Will cps-temporal require the requestID?


Proposed Diagram


draw.io Diagram
bordertrue
diagramNameCPS-821
simpleViewerfalse
width
linksauto
tbstyletop
lboxtrue
diagramWidth771
revision5

Rest Endpoint with Async Flag


CurrentProposed

<ncmp>/v1/ch/PNFDemo/data/ds/ncmp-datastore:passthrough-running?resourceIdentifier=stores:bookstore

<ncmp>/v1/ch/PNFDemo/data/async/ds/ncmp-datastore:passthrough-running?resourceIdentifier=stores:bookstore


Kafka config & Implementation


Example of Existing Consumer (Java)

The below code snippet taken from cps-temporal can be used in the same way in NCMP to listen to message from DMI substituting the topics and errorHandler

Code Block
languagejava
titleExample Listener (Java, cps-temporal)
collapsetrue
 /**
     * Consume the specified event.
     *
     * @param cpsDataUpdatedEvent the data updated event to be consumed and persisted.
     */
    @KafkaListener(topics = "${app.listener.data-updated.topic}", errorHandler = "dataUpdatedEventListenerErrorHandler")
    public void consume(final CpsDataUpdatedEvent cpsDataUpdatedEvent) {

        log.debug("Receiving {} ...", cpsDataUpdatedEvent);

        // Validate event envelop
        validateEventEnvelop(cpsDataUpdatedEvent);

        // Map event to entity
        final var networkData = this.cpsDataUpdatedEventMapper.eventToEntity(cpsDataUpdatedEvent);
        log.debug("Persisting {} ...", networkData);

        // Persist entity
        final var persistedNetworkData = this.networkDataService.addNetworkData(networkData);
        log.debug("Persisted {}", persistedNetworkData);

    }


Example of Existing Consumer (Config)

Code Block
languageyml
titleExample of Existing Consumer (Config)
collapsetrue
# ============LICENSE_START=======================================================
# Copyright (c) 2021 Bell Canada.
# ================================================================================
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
#       http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
# ============LICENSE_END=========================================================

# Spring profile configuration for sasl ssl Kafka

spring:
    kafka:
        bootstrap-servers: ${KAFKA_BOOTSTRAP_SERVER}
        security:
            protocol: SASL_SSL
        ssl:
            trust-store-type: JKS
            trust-store-location: ${KAFKA_SSL_TRUST_STORE_LOCATION}
            trust-store-password: ${KAFKA_SSL_TRUST_STORE_PASSWORD}
        properties:
            sasl.mechanism: SCRAM-SHA-512
            sasl.jaas.config: ${KAFKA_SASL_JAAS_CONFIG}
            ssl.endpoint.identification.algorithm:


Example of Existing Producer (Java)


Example of Existing Producer (Config)


Example of Kafka Docker-Compose


Code Block
languageyml
titleKafka Docker Example
collapsetrue
  kafka:
    image: confluentinc/cp-kafka:6.1.1
    container_name: kafka
    ports:
      - "19092:19092"
    depends_on:
      - zookeeper
    environment:
      KAFKA_BROKER_ID: 1
      KAFKA_ZOOKEEPER_CONNECT: zookeeper:2181
      KAFKA_ADVERTISED_LISTENERS: PLAINTEXT://kafka:9092,CONNECTIONS_FROM_HOST://localhost:19092
      KAFKA_LISTENER_SECURITY_PROTOCOL_MAP: PLAINTEXT:PLAINTEXT,CONNECTIONS_FROM_HOST:PLAINTEXT
      KAFKA_OFFSETS_TOPIC_REPLICATION_FACTOR: 1



Response types for passthrough


Will we be able to handle everything "as-is"?


Future (or alternative)


What are Futures?



CompletableFuture (Java8+)

Java 8 introduced the CompletableFuture class. Along with the Future interface, it also implemented the CompletionStage interface. This interface defines the contract for an asynchronous computation step that we can combine with other steps.

CompletableFuture is at the same time a building block and a framework, with about 50 different methods for composing, combining, and executing asynchronous computation steps and handling errors.


Code Block
languagejava
themeEclipse
titleSimple Future Example
collapsetrue
public Future<String> calculateAsync() throws InterruptedException {
    CompletableFuture<String> completableFuture = new CompletableFuture<>();

    Executors.newCachedThreadPool().submit(() -> {
        Thread.sleep(500);
        completableFuture.complete("Hello");
        return null;
    });

    return completableFuture;
}

source: https://www.baeldung.com/java-completablefuture


Alternatives


Code Block
languagejava
titleThread Example
collapsetrue
int number = 20;
Thread newThread = new Thread(() -> {
    System.out.println("Factorial of " + number + " is: " + factorial(number));
});
newThread.start();


#TypeProsConsRecommend
1Future


2Thread


RequestID Generation


TypeMethodEase of implementationRecommend
UUID
String uniqueID = UUID.randomUUID().toString();
EasyY
CustomWe generate our ownMedium - HardN





Async Request Option using Messaging



Demo/Test