You are viewing an old version of this page. View the current version.

Compare with Current View Page History

Version 1 Current »

Understanding the major lines of the source code of a component surely helps one to understand how it works, but it takes tremendous effort. This page walk you through the source code of Holmes Engine Management, in the hope to

  1. Help you to understand how things work internally.
  2. Give people working with the code a booting. 

You can check out the source code from ONAP gerrit: https://gerrit.onap.org/r/#/admin/projects/holmes/engine-management  

There are two sub modules, engine-d-standalone and engine-d. engine-d-standalone is for packaging the application into a Docker image, while engine-d has all the business logic.




Setup Docker Image

Holmes Engine Management can run in a Docker container. In folder /engine-d-standalone/src/main/assembly/, Dockerfile is used to pack the Docker image. During the packing, ActiveMQ and PostgreSQL client are installed. Docker ENTRYPOINT is bin/run.sh, where conf/engine-d.yml is used to inject parameters to Dropwizard configuration,  org.onap.holmes.engine.EngineDAppConfig, which is then passed to org.onap.holmes.engine.EngineDActiveApp.  EngineDActiveApp, which is a Dropwizard application, is the entrance point to Holmes Engine Management application. Dropwizard is an open source Java framework for developing RESTful web services, like Spring Boot. Here is a Dropwizard introduction.


Four things happen in EngineDActiveApp


  1. Register Holmes Engine Management service to MSB.

  2. Setup a background task to periodically (every 30 seconds) poll DCAE policy updates.

  3. Set up a servlet filter, TransactionIdFilter, which generates unique transaction ids for REST requests.

  4. Register a REST resource, EngineResources, to Dropwizard environment.

The following sections will go into details on these 4 aspects.


Register to MSB (Microservices Bus)

It is required that env variable “HOSTNAME” is provided. Engine application host address and port are obtained from Consul by passing in HOSTNAME (in org.onap.holmes.common.config.MicroServiceConfig.getMicroServiceIpAndPort()):
http://{CONSUL_HOST}:8500/v1/catalog/service/{HOSTNAME} ,
where CONSUL_HOST is defined in env as well.

Host address and port are then submitted to MSB, along with:
       msinfo.setServiceName("holmes-engine-mgmt");
       msinfo.setVersion("v1");
       msinfo.setUrl("/api/holmes-engine-mgmt/v1");



DCAE Configuration Polling

A thread is forked using JDK Executors.newSingleThreadScheduledExecutor(), the forked task, DcaeConfigurationPolling, runs at an interval of 30 seconds.

First, Config Binding Service (CBS) endpoint is obtained from DCAE Consul:
http://{CONSUL_HOST}:8500/v1/catalog/service/{CONFIG_BINDING_SERVICE}

From CBS, configuration info on HOSTNAME is obtained from:
http://{CBS ServiceAddress}:{CBS ServicePort}/service_component/{HOSTNAME}
(In MicroServiceConfig.getServiceConfigInfoFromCBS())

The service configuration data from CBS is in JSON format, and is parsed by DcaeConfigurationParser. The result is a DcaeConfigurations object, which contains rules, DMaaP Publisher topics, and DMaaP Subscriber topics. (In DcaeConfigurationParser.parse())

If the DcaeConfigurations has updates (by checking its MD5 against the previous version), DcaeConfigurationsCache is updated with the new config, and a subscriber is created for each new DMaaP Subscriber topic. (In DcaeConfigurationPolling)

Subscriber 



Each subscriber runs in its own thread as DMaaPAlarmPolling. (SubscriberAction.addSubscriber())

In DMaaPAlarmPolling, the subscriber reads the VES event data from DMaaP in JSON format, and converts it into a VES object, VesAlarm.  

Part of the info in VES object is then saved to PostgreSQL database table ALARM_INFO using this SQL statement: (in AlarmInfoDao.saveAlarm())
INSERT INTO ALARM_INFO  (EVENTID,EVENTNAME,STARTEPOCHMICROSEC,SOURCEID,SOURCENAME,ALARMISCLEARED,ROOTFLAG,LASTEPOCHMICROSEC) VALUES (:eventId,:eventName,:startEpochMicroSec,:sourceId,:sourceName,:alarmIsCleared,:rootFlag,:lastEpochMicroSec)

The VES object is then passed to DroolsEngine.putRaisedIntoStream(), where Drools Kie API is used to fire all rules on the event, to triggers new event if need.


Transaction Id Filter

Servlet filter TransactionIdFilter intercepts all HTTP requests.

If header “X-TransactionID" does not present in a HTTP request, the filter generates a random UUID and insert it to request header “X-TransactionID".

When sending responses to HTTP clients, response header “X-TransactionID" is set with the above value, and a new UUID is generated for another header, "X-InvocationID". (In TransactionIdFilter).

The purpose of these IDs is unclear to me at this writing. Your input is welcome.



Engine Management REST API


Like Spring Boot Controllers, Dropwizard Jersey resources are the entrance points of web services. EngineResources is such a resource that provides all engine REST APIs, with the following services:

  1. Deploying a rule into the Drools engine

    The request should be in such format:

    PUT /api/holmes-engine-mgmt/v1/rule
    {
     "content": "string",
     "engineid": "string",(optional)
     "loopcontrolname": "string"
    }


    This request is handled by EngineResources.deployRule(), where the “content” in the HTTP body is used as a rule and inserted into Drools rule engine using Kie API. On successfully deploying the rule, the package name is returned to the client.

  2. Testing if a rule is valid.
    The request should be in such format:

    POST  /api/holmes-engine-mgmt/v1/rule
    {
    "content": "string"
    }

    The {content} in the POST body contains the rule to be validated.
    This request is handled by EngineResources.compileRule(), where the “content” in the HTTP body is used as a rule and uses Kie API to see if the rule is valid. Notice that when deploying a rule (described above), the same validation is also performed.

  3. Undeploying a rule from the Drools engine.
    The request should be in such format:
    DELETE /api/holmes-engine-mgmt/v1/rule/{packageName}

    where {packageName} is the name of the package to be remove from the Drools engine.
    It is handled by EngineResources.undeployRule().

    engine-d/src/main/resources/swagger.json is the OpenAPI Specification (OAS) file that describes all the above APIs.


  • No labels