Introduced yaml parser as common lib 59/82659/7
authorTomasz Golabek <tomasz.golabek@nokia.com>
Tue, 19 Mar 2019 10:37:28 +0000 (11:37 +0100)
committerOfir Sonsino <ofir.sonsino@intl.att.com>
Mon, 1 Apr 2019 13:03:21 +0000 (13:03 +0000)
Introduced parser with capability of search for given json paths.
Introduced cucumber tests for gab service

Change-Id: I154d71085ee82c1ead7c4e002a488524f60c5d8d
Issue-ID: SDC-2094
Signed-off-by: Tomasz Golabek <tomasz.golabek@nokia.com>
19 files changed:
common/onap-generic-artifact-browser/onap-generic-artifact-browser-component-tests/pom.xml [new file with mode: 0644]
common/onap-generic-artifact-browser/onap-generic-artifact-browser-component-tests/src/test/java/org/onap/sdc/gab/cucumber/RunCucumberTest.java [new file with mode: 0644]
common/onap-generic-artifact-browser/onap-generic-artifact-browser-component-tests/src/test/java/org/onap/sdc/gab/cucumber/actions/gabcontroller/GABControllerStepDefinitions.java [new file with mode: 0644]
common/onap-generic-artifact-browser/onap-generic-artifact-browser-component-tests/src/test/resources/org/onap/sdc/gab/cucumber/gab_controller.feature [new file with mode: 0644]
common/onap-generic-artifact-browser/onap-generic-artifact-browser-component-tests/src/test/resources/yaml/faultRegistration.yml [new file with mode: 0644]
common/onap-generic-artifact-browser/onap-generic-artifact-browser-service/pom.xml [new file with mode: 0644]
common/onap-generic-artifact-browser/onap-generic-artifact-browser-service/src/main/java/org/onap/sdc/gab/GABService.java [new file with mode: 0644]
common/onap-generic-artifact-browser/onap-generic-artifact-browser-service/src/main/java/org/onap/sdc/gab/GABServiceImpl.java [new file with mode: 0644]
common/onap-generic-artifact-browser/onap-generic-artifact-browser-service/src/main/java/org/onap/sdc/gab/model/GABQuery.java [new file with mode: 0644]
common/onap-generic-artifact-browser/onap-generic-artifact-browser-service/src/main/java/org/onap/sdc/gab/model/GABResult.java [new file with mode: 0644]
common/onap-generic-artifact-browser/onap-generic-artifact-browser-service/src/main/java/org/onap/sdc/gab/model/GABResultEntry.java [new file with mode: 0644]
common/onap-generic-artifact-browser/onap-generic-artifact-browser-service/src/main/java/org/onap/sdc/gab/model/GABResults.java [new file with mode: 0644]
common/onap-generic-artifact-browser/onap-generic-artifact-browser-service/src/main/java/org/onap/sdc/gab/yaml/GABYamlParser.java [new file with mode: 0644]
common/onap-generic-artifact-browser/onap-generic-artifact-browser-service/src/main/java/org/onap/sdc/gab/yaml/YamlParser.java [new file with mode: 0644]
common/onap-generic-artifact-browser/onap-generic-artifact-browser-service/src/test/java/org/onap/sdc/gab/yaml/GABYamlParserTest.java [new file with mode: 0644]
common/onap-generic-artifact-browser/onap-generic-artifact-browser-service/src/test/resources/yaml/faultRegistration.yml [new file with mode: 0644]
common/onap-generic-artifact-browser/onap-generic-artifact-browser-service/src/test/resources/yaml/invalid.yml [new file with mode: 0644]
common/onap-generic-artifact-browser/pom.xml [new file with mode: 0644]
common/pom.xml

diff --git a/common/onap-generic-artifact-browser/onap-generic-artifact-browser-component-tests/pom.xml b/common/onap-generic-artifact-browser/onap-generic-artifact-browser-component-tests/pom.xml
new file mode 100644 (file)
index 0000000..a9b10c8
--- /dev/null
@@ -0,0 +1,59 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<project xmlns="http://maven.apache.org/POM/4.0.0"
+         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+    <modelVersion>4.0.0</modelVersion>
+
+    <parent>
+        <groupId>org.onap.sdc.common</groupId>
+        <artifactId>onap-generic-artifact-browser</artifactId>
+        <version>1.4.0-SNAPSHOT</version>
+    </parent>
+
+    <artifactId>onap-generic-artifact-browser-component-tests</artifactId>
+
+    <properties>
+        <maven-compiler-plugin.version>3.7.0</maven-compiler-plugin.version>
+        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
+    </properties>
+
+    <dependencies>
+        <!--tested packages-->
+        <dependency>
+            <groupId>org.onap.sdc.common</groupId>
+            <artifactId>onap-generic-artifact-browser-service</artifactId>
+            <version>${project.version}</version>
+        </dependency>
+
+        <!--cucumber-->
+        <dependency>
+            <groupId>io.cucumber</groupId>
+            <artifactId>cucumber-java</artifactId>
+            <version>${cucumber.version}</version>
+            <scope>test</scope>
+        </dependency>
+        <dependency>
+            <groupId>io.cucumber</groupId>
+            <artifactId>cucumber-junit</artifactId>
+            <version>${cucumber.version}</version>
+            <scope>test</scope>
+        </dependency>
+
+    </dependencies>
+
+    <build>
+        <plugins>
+            <plugin>
+                <groupId>org.apache.maven.plugins</groupId>
+                <artifactId>maven-compiler-plugin</artifactId>
+                <version>${maven-compiler-plugin.version}</version>
+                <configuration>
+                    <encoding>${project.build.sourceEncoding}</encoding>
+                    <source>8</source>
+                    <target>8</target>
+                    <compilerArgument>-Werror</compilerArgument>
+                </configuration>
+            </plugin>
+        </plugins>
+    </build>
+</project>
diff --git a/common/onap-generic-artifact-browser/onap-generic-artifact-browser-component-tests/src/test/java/org/onap/sdc/gab/cucumber/RunCucumberTest.java b/common/onap-generic-artifact-browser/onap-generic-artifact-browser-component-tests/src/test/java/org/onap/sdc/gab/cucumber/RunCucumberTest.java
new file mode 100644 (file)
index 0000000..3d5bf17
--- /dev/null
@@ -0,0 +1,30 @@
+/*
+ * ============LICENSE_START=======================================================
+ * GAB
+ * ================================================================================
+ * Copyright (C) 2019 Nokia Intellectual Property. All rights reserved.
+ * ================================================================================
+ * 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=========================================================
+ */
+
+package org.onap.sdc.gab.cucumber;
+
+import cucumber.api.CucumberOptions;
+import cucumber.api.junit.Cucumber;
+import org.junit.runner.RunWith;
+
+@RunWith(Cucumber.class)
+@CucumberOptions(plugin = {"pretty"})
+public class RunCucumberTest {
+}
\ No newline at end of file
diff --git a/common/onap-generic-artifact-browser/onap-generic-artifact-browser-component-tests/src/test/java/org/onap/sdc/gab/cucumber/actions/gabcontroller/GABControllerStepDefinitions.java b/common/onap-generic-artifact-browser/onap-generic-artifact-browser-component-tests/src/test/java/org/onap/sdc/gab/cucumber/actions/gabcontroller/GABControllerStepDefinitions.java
new file mode 100644 (file)
index 0000000..9f73a94
--- /dev/null
@@ -0,0 +1,77 @@
+/*
+ * ============LICENSE_START=======================================================
+ * GAB
+ * ================================================================================
+ * Copyright (C) 2019 Nokia Intellectual Property. All rights reserved.
+ * ================================================================================
+ * 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=========================================================
+ */
+
+package org.onap.sdc.gab.cucumber.actions.gabcontroller;
+
+import static org.junit.Assert.assertEquals;
+
+import cucumber.api.java.Before;
+import cucumber.api.java.en.Given;
+import cucumber.api.java.en.When;
+import cucumber.api.java.en.Then;
+import java.io.IOException;
+import java.util.HashSet;
+import java.util.Set;
+import org.onap.sdc.gab.GABService;
+import org.onap.sdc.gab.GABServiceImpl;
+import org.onap.sdc.gab.model.GABQuery;
+import org.onap.sdc.gab.model.GABQuery.GABQueryType;
+import org.onap.sdc.gab.model.GABResults;
+
+public class GABControllerStepDefinitions {
+
+    private GABService gabService;
+    private String yaml;
+    private GABQueryType gabQueryType;
+    private Set<String> headers;
+    private GABResults actualAnswer;
+
+    public GABControllerStepDefinitions() {
+        headers = new HashSet<>();
+    }
+
+    @Before
+    public void createNewGABService() {
+        gabService = new GABServiceImpl();
+    }
+
+    @Given("^yaml document \"([^\"]*)\" of type \"([^\"]*)\"$")
+    public void prepareYamlFile(String yaml, String type) {
+        this.yaml = yaml;
+        this.gabQueryType = GABQueryType.valueOf(type);
+    }
+
+    @Given("^header to search \"([^\"]*)\"$")
+    public void prepareHeader(String header) {
+        this.headers.add(header);
+    }
+
+    @When("^I ask service for results$")
+    public void executeSearchQuery() throws IOException {
+        GABQuery gabQuery = new GABQuery(headers, yaml, gabQueryType);
+        actualAnswer = gabService.searchFor(gabQuery);
+    }
+
+    @Then("^Service should find (\\d+) results$")
+    public void checkSizeOfTheAnswerEquals(int size) {
+        assertEquals(actualAnswer.getRows().size(), size);
+    }
+
+}
\ No newline at end of file
diff --git a/common/onap-generic-artifact-browser/onap-generic-artifact-browser-component-tests/src/test/resources/org/onap/sdc/gab/cucumber/gab_controller.feature b/common/onap-generic-artifact-browser/onap-generic-artifact-browser-component-tests/src/test/resources/org/onap/sdc/gab/cucumber/gab_controller.feature
new file mode 100644 (file)
index 0000000..d0d1d24
--- /dev/null
@@ -0,0 +1,14 @@
+Feature: GABService usage
+  GABService can find a keywords inside the yaml file
+
+  Scenario: Ask for two-results keyword providing path to yaml
+    Given yaml document "yaml/faultRegistration.yml" of type "PATH"
+    And header to search "event.action[1]"
+    When I ask service for results
+    Then Service should find 2 results
+
+  Scenario: Ask for single-results keyword providing yaml content
+    Given yaml document "event: {presence: required, action: [ any, any, alarm003, Clear ], structure: {}}" of type "CONTENT"
+    And header to search "event.action[1]"
+    When I ask service for results
+    Then Service should find 1 results
\ No newline at end of file
diff --git a/common/onap-generic-artifact-browser/onap-generic-artifact-browser-component-tests/src/test/resources/yaml/faultRegistration.yml b/common/onap-generic-artifact-browser/onap-generic-artifact-browser-component-tests/src/test/resources/yaml/faultRegistration.yml
new file mode 100644 (file)
index 0000000..447af5e
--- /dev/null
@@ -0,0 +1,412 @@
+---
+# registration for Fault\_vMrf\_alarm003
+# Constants: the values of domain, eventName, priority, vfstatus
+# , version, alarmCondition, eventSeverity, eventSourceType,
+# faultFieldsVersion, specificProblem,
+# Variables (to be supplied at runtime) include: eventId, lastEpochMicrosec,
+
+# reportingEntityId, reportingEntityName, sequence, sourceId, sourceName,
+# startEpochMicrosec
+
+event: {presence: required, action: [ any, any, alarm003,RECO-rebuildVnf ],
+        structure: {
+          commonEventHeader: {presence: required, structure: {
+            domain: {presence: required, value: fault},
+            eventName: {presence: required, value: Fault\_vMrf\_alarm003},
+            eventId: {presence: required},
+            nfNamingCode: {value: mrfx},
+            priority: {presence: required, value: Medium},
+            reportingEntityId: {presence: required},
+            reportingEntityName: {presence: required},
+            sequence: {presence: required},
+            sourceId: {presence: required},
+            sourceName: {presence: required},
+            startEpochMicrosec: {presence: required},
+            lastEpochMicrosec: {presence: required},
+            version: {presence: required, value: 3.0}
+          }},
+          faultFields: {presence: required, structure: {
+            alarmCondition: {presence: required, value: alarm003},
+            eventSeverity: {presence: required, value: MAJOR},
+            eventSourceType: {presence: required, value: virtualNetworkFunction},
+            faultFieldsVersion: {presence: required, value: 2.0},
+            specificProblem: {presence: required, value: "Configuration file was
+                        corrupt or not present"},
+            vfStatus: {presence: required, value: "Requesting Termination"}
+          }}
+        }}
+---
+# registration for clearing Fault\_vMrf\_alarm003Cleared
+# Constants: the values of domain, eventName, priority,
+# , version, alarmCondition, eventSeverity, eventSourceType,
+# faultFieldsVersion, specificProblem,
+# Variables (to be supplied at runtime) include: eventId,lastEpochMicrosec,
+# reportingEntityId, reportingEntityName, sequence, sourceId,
+# sourceName, startEpochMicrosec, vfStatus
+event: {presence: required, action: [ any, any, alarm003, Clear ], structure: {
+  commonEventHeader: {presence: required, structure: {
+    domain: {presence: required, value: fault},
+    eventName: {presence: required, value: Fault\_vMrf\_alarm003Cleared},
+    eventId: {presence: required},
+    nfNamingCode: {value: mrfx},
+    priority: {presence: required, value: Medium},
+    reportingEntityId: {presence: required},
+    reportingEntityName: {presence: required},
+    sequence: {presence: required},
+    sourceId: {presence: required},
+    sourceName: {presence: required},
+    startEpochMicrosec: {presence: required},
+    lastEpochMicrosec: {presence: required},
+    version: {presence: required, value: 3.0}
+  }},
+  faultFields: {presence: required, structure: {
+    alarmCondition: {presence: required, value: alarm003},
+    eventSeverity: {presence: required, value: NORMAL},
+    eventSourceType: {presence: required, value: virtualNetworkFunction},
+    faultFieldsVersion: {presence: required, value: 2.0},
+    specificProblem: {presence: required, value: "Valid configuration file found"},
+    vfStatus: {presence: required, value: "Requesting Termination"}
+  }}
+}}
+---
+# registration for Heartbeat_vMRF
+# Constants: the values of domain, eventName, priority, version
+# Variables (to be supplied at runtime) include: eventId, lastEpochMicrosec,
+# reportingEntityId, reportingEntityName, sequence, sourceId, sourceName,
+# startEpochMicrosec
+event: {presence: required, heartbeatAction: [3, vnfDown,RECO-rebuildVnf],
+        structure: {
+          commonEventHeader: {presence: required, structure: {
+            domain: {presence: required, value: heartbeat},
+            eventName: {presence: required, value: Heartbeat\_vMrf},
+            eventId: {presence: required},
+            nfNamingCode: {value: mrfx},
+            priority: {presence: required, value: Normal},
+            reportingEntityId: {presence: required},
+            reportingEntityName: {presence: required},
+            sequence: {presence: required},
+            sourceId: {presence: required},
+            sourceName: {presence: required},
+            startEpochMicrosec: {presence: required},
+            lastEpochMicrosec: {presence: required},
+            version: {presence: required, value: 3.0}
+          }},
+          heartbeatFields: {presence: optional, structure:{
+            heartbeatFieldsVersion: {presence: required, value: 1.0},
+            heartbeatInterval: {presence: required, range: [ 15, 300 ], default: 60 }
+          }}
+        }}
+---
+# registration for Mfvs\_vMRF
+# Constants: the values of domain, eventName, priority, version,
+# measurementFieldsVersion, additionalMeasurements.namedArrayOfFields.name,
+# Variables (to be supplied at runtime) include: eventId, reportingEntityName, sequence,
+# sourceName, start/lastEpochMicrosec, measurementInterval,
+# concurrentSessions, requestRate, numberOfMediaPortsInUse,
+# cpuUsageArray.cpuUsage,cpuUsage.cpuIdentifier, cpuUsage.percentUsage,
+# additionalMeasurements.namedArrayOfFields.arrayOfFields,
+# vNicPerformance.receivedOctetsAccumulated,
+# vNicPerformance.transmittedOctetsAccumulated,
+# vNicPerformance.receivedTotalPacketsAccumulated,
+# vNicPerformance.transmittedTotalPacketsAccumulated,
+# vNicPerformance.vNicIdentifier, vNicPerformance.receivedOctetsDelta,
+# vNicPerformance.receivedTotalPacketsDelta,
+# vNicPerformance.transmittedOctetsDelta,
+# vNicPerformance.transmittedTotalPacketsDelta,
+# vNicPerformance.valuesAreSuspect, memoryUsageArray.memoryUsage,
+# memoryUsage.memoryConfigured, memoryUsage.vmIdentifier,
+# memoryUsage.memoryUsed, memoryUsage.memoryFree
+event: {presence: required, structure: {
+  commonEventHeader: {presence: required, structure: {
+    domain: {presence: required, value: measurementsForVfScaling},
+    eventName: {presence: required, value: Mfvs\_vMrf},
+    eventId: {presence: required},
+    nfNamingCode: {value: mrfx},
+    priority: {presence: required, value: Normal},
+    reportingEntityId: {presence: required},
+    reportingEntityName: {presence: required},
+    sequence: {presence: required},
+    sourceId: {presence: required},
+    sourceName: {presence: required},
+    startEpochMicrosec: {presence: required},
+    lastEpochMicrosec: {presence: required},
+    version: {presence: required, value: 3.0}
+  }},
+  measurementsForVfScalingFields: {presence: required, structure: {
+    measurementFieldsVersion: {presence: required, value: 2.0},
+    measurementInterval: {presence: required, range: [ 60, 3600 ], default:300},
+    concurrentSessions: {presence: required, range: [ 0, 100000 ]},
+    requestRate: {presence: required, range: [ 0, 100000 ]},
+    numberOfMediaPortsInUse: {presence: required, range: [ 0, 100000 ]},
+    cpuUsageArray: {presence: required, array: [
+      cpuUsage: {presence: required, structure: {
+        cpuIdentifier: {presence: required},
+        percentUsage: {presence: required, range: [ 0, 100 ],
+                       action: [80, up, CpuUsageHigh, RECO-scaleOut],
+                       action: [10, down, CpuUsageLow, RECO-scaleIn]}
+      }}
+    ]},
+    memoryUsageArray: {presence: required, array: [
+      memoryUsage: {presence: required, structure: {
+        memoryConfigured: {presence: required, value: 33554432},
+        memoryFree: {presence: required, range: [ 0, 33554432 ],
+                     action: [100, down, FreeMemLow, RECO-scaleOut],
+                     action: [30198989, up, FreeMemHigh, RECO-scaleIn]},
+        memoryUsed: {presence: required, range: [ 0, 33554432 ]},
+        vmIdentifier: {presence: required}
+      }}
+    ]},
+    additionalMeasurements: {presence: required, array: [
+      namedArrayOfFields: {presence: required, structure: {
+        name: {presence: required, value: licenseUsage},
+        arrayOfFields: {presence: required, array: [
+          field: {presence: required, structure: {
+            name: {presence: required, value: G711AudioPort},
+            value: {presence: required, range: [ 0, 100000 ],
+                    units: numberOfPorts }
+          }},
+          field: {presence: required, structure: {
+            name: {presence: required, value: G729AudioPort},
+            value: {presence: required, range: [ 0, 100000 ],
+                    units: numberOfPorts }
+          }},
+          field: {presence: required, structure: {
+            name: {presence: required, value: G722AudioPort},
+            value: {presence: required, range: [ 0, 100000 ],
+                    units: numberOfPorts }
+          }},
+          field: {presence: required, structure: {
+            name: {presence: required, value: AMRAudioPort},
+            value: {presence: required, range: [ 0, 100000 ],
+                    units: numberOfPorts }
+          }},
+          field: {presence: required, structure: {
+            name: {presence: required, value: AMRWBAudioPort},
+            value: {presence: required, range: [ 0, 100000 ],
+                    units: numberOfPorts }
+          }},
+          field: {presence: required, structure: {
+            name: {presence: required, value: OpusAudioPort},
+            value: {presence: required, range: [ 0, 100000 ],
+                    units: numberOfPorts }
+          }},
+          field: {presence: required, structure: {
+            name: {presence: required, value: H263VideoPort},
+            value: {presence: required, range: [ 0, 100000 ],
+                    units: numberOfPorts }
+          }},
+          field: {presence: required, structure: {
+            name: {presence: required, value: H264NonHCVideoPort},
+            value: {presence: required, range: [ 0, 100000 ],
+                    units: numberOfPorts }
+          }},
+          field: {presence: required, structure: {
+            name: {presence: required, value: H264HCVideoPort},
+            value: {presence: required, range: [ 0, 100000 ],
+                    units: numberOfPorts }
+          }},
+          field: {presence: required, structure: {
+            name: {presence: required, value: MPEG4VideoPort},
+            value: {presence: required, range: [ 0, 100000 ],
+                    units: numberOfPorts }
+          }},
+          field: {presence: required, structure: {
+            name: {presence: required, value: VP8NonHCVideoPort},
+            value: {presence: required, range: [ 0, 100000 ],
+                    units: numberOfPorts }
+          }},
+          field: {presence: required, structure: {
+            name: {presence: required, value: VP8HCVideoPort},
+            value: {presence: required, range: [ 0, 100000 ],
+                    units: numberOfPorts }
+          }},
+          field: {presence: required, structure: {
+            name: {presence: required, value: PLC},
+            value: {presence: required, range: [ 0, 100000 ],
+                    units: numberOfPorts }
+          }},
+          field: {presence: required, structure: {
+            name: {presence: required, value: AEC},
+            value: {presence: required, range: [ 0, 100000 ],
+                    units: numberOfPorts }
+          }},
+          field: {presence: required, structure: {
+            name: {presence: required, value: NR},
+            value: {presence: required, range: [ 0, 100000 ],
+                    units: numberOfPorts }
+          }},
+          field: {presence: required, structure: {
+            name: {presence: required, value: NG},
+            value: {presence: required, range: [ 0, 100000 ],
+                    units: numberOfPorts }
+          }},
+          field: {presence: required, structure: {
+            name: {presence: required, value: NLD},
+            value: {presence: required, range: [ 0, 100000 ],
+                    units: numberOfPorts }
+          }},
+          field: {presence: required, structure: {
+            name: {presence: required, value: G711FaxPort},
+            value: {presence: required, range: [ 0, 100000 ],
+                    units: numberOfPorts }
+          }},
+          field: {presence: required, structure: {
+            name: {presence: required, value: T38FaxPort},
+            value: {presence: required, range: [ 0, 100000 ],
+                    units: numberOfPorts }
+          }},
+          field: {presence: required, structure: {
+            name: {presence: required, value: RFactor},
+            value: {presence: required, range: [ 0, 100000 ],
+                    units: numberOfPorts }
+          }},
+          field: {presence: required, structure: {
+            name: {presence: required, value: T140TextPort},
+            value: {presence: required, range: [ 0, 100000 ],
+                    units: numberOfPorts }
+          }},
+          field: {presence: required, structure: {
+            name: {presence: required, value: EVSAudioPort},
+            value: {presence: required, range: [ 0, 100000 ],
+                    units: numberOfPorts }
+          }}
+        ]}
+      }},
+      namedArrayOfFields: {presence: required, structure: {
+        name: {presence: required, value: mediaCoreUtilization},
+        arrayOfFields: {presence: required, array: [
+          field: {presence: required, structure: {
+            name: {presence: required, value: actualAvgAudio},
+            value: {presence: required, range: [ 0, 255 ],
+                    action: [80, up, AudioCoreUsageHigh, RECO-scaleOut],
+                    action: [10, down, AudioCoreUsageLow, RECO-scaleIn]}
+          }},
+          field: {presence: required, structure: {
+            name: {presence: required, value: modelAvgAudio},
+            value: {presence: required, range: [ 0, 100 ],
+                    action: [80, up, AudioCoreUsageHigh, RECO-scaleOut],
+                    action: [10, down, AudioCoreUsageLow, RECO-scaleIn]}
+          }},
+          field: {presence: required, structure: {
+            name: {presence: required, value: actualMaxAudio},
+            value: {presence: required, range: [ 0, 255 ]}
+          }},
+          field: {presence: required, structure: {
+            name: {presence: required, value: modelMaxAudio},
+            value: {presence: required, range: [ 0, 100 ]}
+          }},
+          field: {presence: required, structure: {
+            name: {presence: required, value: actualAvgVideo},
+            value: {presence: required, range: [ 0, 255 ],
+                    action: [80, up, VideoCoreUsageHigh, RECO-scaleOut],
+                    action: [10, down, VideoCoreUsageLow, RECO-scaleIn]}
+          }},
+          field: {presence: required, structure: {
+            name: {presence: required, value: modelAvgVideo},
+            value: {presence: required, range: [ 0, 100 ],
+                    action: [80, up, VideoCoreUsageHigh, RECO-scaleOut],
+                    action: [10, down, VideoCoreUsageLow, RECO-scaleIn]}
+          }},
+          field: {presence: required, structure: {
+            name: {presence: required, value: actualMaxVideo},
+            value: {presence: required, range: [ 0, 255 ]}
+          }},
+          field: {presence: required, structure: {
+            name: {presence: required, value: modelMaxVideo},
+            value: {presence: required, range: [ 0, 100 ]}
+          }},
+          field: {presence: required, structure: {
+            name: {presence: required, value: actualAvgHcVideo},
+            value: {presence: required, range: [ 0, 255 ],
+                    action: [80, up, HcVideoCoreUsageHigh, RECO-scaleOut],
+                    action: [10, down, HcVideoCoreUsageLow, RECO-scaleIn]}
+          }},
+          field: {presence: required, structure: {
+            name: {presence: required, value: modelAvgHcVideo},
+            value: {presence: required, range: [ 0, 100 ],
+                    action: [80, up, HcVideoCoreUsageHigh, RECO-scaleOut],
+                    action: [10, down, HcVideoCoreUsageLow, RECO-scaleIn]}
+          }},
+          field: {presence: required, structure: {
+            name: {presence: required, value: actualMaxHcVideo},
+            value: {presence: required, range: [ 0, 255 ]}
+          }},
+          field: {presence: required, structure: {
+            name: {presence: required, value: modelMaxHcVideo},
+            value: {presence: required, range: [ 0, 100 ]}
+          }}
+        ]}
+      }}
+    ]},
+    vNicPerformanceArray: {presence: required, array: [
+      vNicPerformance: {presence: required, structure: {
+        receivedOctetsAccumulated: {presence: required,
+                                    range: [ 0, 18446744073709551615 ]},
+        receivedTotalPacketsAccumulated: {presence: required,
+                                          range: [ 0, 18446744073709551615 ]},
+        receivedOctetsDelta: {presence: required},
+        range: [ 0, 18446744073709551615 ],
+        receivedTotalPacketsDelta: {presence: required,
+                                    range: [ 0, 18446744073709551615 ]},
+        transmittedOctetsDelta: {presence: required,
+                                 range: [ 0, 18446744073709551615 ]},
+        transmittedOctetsAccumulated: {presence: required,
+                                       range: [ 0, 18446744073709551615 ]},
+        transmittedTotalPacketsAccumulated: {presence: required,
+                                             range: [ 0, 18446744073709551615 ]},
+        transmittedTotalPacketsDelta: {presence: required,
+                                       range: [ 0, 18446744073709551615 ]},
+        valuesAreSuspect: {presence: required, value: [ true, false ]},
+        vNicIdentifier: {presence: required}
+      }}
+    ]}
+  }}
+}}
+---
+# registration for Syslog\_vMRF
+# Constants: the values of domain, eventName, priority, lastEpochMicrosec, version,
+# syslogFields.syslogFieldsVersion, syslogFields.syslogTag
+# Variables include: eventId, lastEpochMicrosec, reportingEntityId, reportingEntityName,
+# sequence, sourceId, sourceName, startEpochMicrosec,
+# syslogFields.eventSourceHost, syslogFields.eventSourceType,
+# syslogFields.syslogFacility, syslogFields.syslogMsg
+event: {presence: required, structure: {
+  commonEventHeader: {presence: required, structure: {
+    domain: {presence: required, value: syslog},
+    eventName: {presence: required, value: Syslog\_vMrf},
+    eventId: {presence: required},
+    nfNamingCode: {value: mrfx},
+    priority: {presence: required, value: Normal},
+    reportingEntityId: {presence: required},
+    reportingEntityName: {presence: required},
+    sequence: {presence: required},
+    sourceId: {presence: required},
+    sourceName: {presence: required},
+    startEpochMicrosec: {presence: required},
+    lastEpochMicrosec: {presence: required},
+    version: {presence: required, value: 3.0},
+  }},
+  syslogFields: {presence: required, structure: {
+    eventSourceHost: {presence: required},
+    eventSourceType: {presence: required, value: virtualNetworkFunction},
+    syslogFacility: {presence: required, range: [16, 23]},
+    syslogSev: {presence: required, value: [ 0, 1, 2, 3, 4 ]},
+    syslogFieldsVersion: {presence: required, value: 3.0},
+    syslogMsg: {presence: required},
+    syslogTag: {presence: required, value: vMRF},
+  }}
+}}
+---
+#Rules
+Rules: [
+  rule: {
+    trigger: CpuUsageHigh \|\| FreeMemLow \|\| AudioCoreUsageHigh \|\|
+      VideoCoreUsageHigh \|\| HcVideoCoreUsageHigh,
+    microservices: [scaleOut]
+  },
+  rule: {
+    trigger: CpuUsageLow && FreeMemHigh && AudioCoreUsageLow &&
+      VideoCoreUsageLow && HcVideoCoreUsageLow,
+    microservices: [scaleIn]
+  }
+]
\ No newline at end of file
diff --git a/common/onap-generic-artifact-browser/onap-generic-artifact-browser-service/pom.xml b/common/onap-generic-artifact-browser/onap-generic-artifact-browser-service/pom.xml
new file mode 100644 (file)
index 0000000..822dfa7
--- /dev/null
@@ -0,0 +1,103 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<project xmlns="http://maven.apache.org/POM/4.0.0"
+  xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+  xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+  <modelVersion>4.0.0</modelVersion>
+
+  <parent>
+    <groupId>org.onap.sdc.common</groupId>
+    <artifactId>onap-generic-artifact-browser</artifactId>
+    <version>1.4.0-SNAPSHOT</version>
+  </parent>
+
+  <artifactId>onap-generic-artifact-browser-service</artifactId>
+
+  <properties>
+    <junit.version>5.4.0</junit.version>
+    <maven-surefire-plugin.version>2.22.1</maven-surefire-plugin.version>
+    <lombok.version>1.18.2</lombok.version>
+    <snakeyaml.version>1.21</snakeyaml.version>
+    <jsurfer.version>1.4.3</jsurfer.version>
+  </properties>
+
+  <dependencies>
+    <dependency>
+      <groupId>org.projectlombok</groupId>
+      <artifactId>lombok</artifactId>
+      <version>${lombok.version}</version>
+      <scope>provided</scope>
+    </dependency>
+    <dependency>
+      <groupId>org.yaml</groupId>
+      <artifactId>snakeyaml</artifactId>
+      <version>${snakeyaml.version}</version>
+    </dependency>
+    <dependency>
+      <groupId>com.google.code.gson</groupId>
+      <artifactId>gson</artifactId>
+      <version>${gson.version}</version>
+    </dependency>
+    <dependency>
+      <groupId>com.github.jsurfer</groupId>
+      <artifactId>jsurfer-gson</artifactId>
+      <version>${jsurfer.version}</version>
+    </dependency>
+    <dependency>
+      <groupId>com.google.guava</groupId>
+      <artifactId>guava</artifactId>
+      <version>${guava.version}</version>
+    </dependency>
+    <dependency>
+      <groupId>commons-io</groupId>
+      <artifactId>commons-io</artifactId>
+      <version>${commons.io.version}</version>
+    </dependency>
+
+
+    <!--test-->
+    <dependency>
+      <groupId>org.junit.jupiter</groupId>
+      <artifactId>junit-jupiter-api</artifactId>
+      <version>${junit.version}</version>
+      <scope>test</scope>
+    </dependency>
+    <dependency>
+      <groupId>org.hamcrest</groupId>
+      <artifactId>hamcrest-all</artifactId>
+      <version>${hamcrest-all.version}</version>
+      <scope>test</scope>
+    </dependency>
+    <dependency>
+      <groupId>org.junit.jupiter</groupId>
+      <artifactId>junit-jupiter-engine</artifactId>
+      <version>${junit.version}</version>
+      <scope>test</scope>
+    </dependency>
+  </dependencies>
+
+  <build>
+    <pluginManagement>
+      <plugins>
+        <plugin>
+          <groupId>org.apache.maven.plugins</groupId>
+          <artifactId>maven-surefire-plugin</artifactId>
+          <version>${maven-surefire-plugin.version}</version>
+          <configuration>
+            <forkMode>once</forkMode>
+          </configuration>
+        </plugin>
+      </plugins>
+    </pluginManagement>
+    <plugins>
+      <plugin>
+        <groupId>org.apache.maven.plugins</groupId>
+        <artifactId>maven-compiler-plugin</artifactId>
+        <configuration>
+          <source>8</source>
+          <target>8</target>
+        </configuration>
+      </plugin>
+    </plugins>
+  </build>
+
+</project>
\ No newline at end of file
diff --git a/common/onap-generic-artifact-browser/onap-generic-artifact-browser-service/src/main/java/org/onap/sdc/gab/GABService.java b/common/onap-generic-artifact-browser/onap-generic-artifact-browser-service/src/main/java/org/onap/sdc/gab/GABService.java
new file mode 100644 (file)
index 0000000..0ac976a
--- /dev/null
@@ -0,0 +1,57 @@
+/*
+ * ============LICENSE_START=======================================================
+ * GAB
+ * ================================================================================
+ * Copyright (C) 2019 Nokia Intellectual Property. All rights reserved.
+ * ================================================================================
+ * 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=========================================================
+ */
+
+package org.onap.sdc.gab;
+
+import java.io.IOException;
+import org.onap.sdc.gab.model.GABQuery;
+import org.onap.sdc.gab.model.GABResults;
+
+/**
+ * <pre>
+ *     SDC/DCAE-DS FM/PM artifact browser service.
+ * </pre>
+ *
+ * Currently the artifact browser is able to parse VES_EVENT_REGISTRATION action (registering of all VES events -
+ * including alarms/faults) to serve required data from the given document.
+ *
+ * @version %I%, %G%
+ * @since 1.4.0-SNAPSHOT
+ */
+public interface GABService {
+
+    /**
+     * Extracting event data based on given YAML paths. As an output, a list of results is returned.
+     *
+     * @param gabQuery the parameter should contain three entries:
+     * <br>* JSON paths for querying specific data
+     * <br>* path/content of YAML document containing faults/measurements data
+     * <br>* type of the query - can be defined as a PATH or CONTENT depends of document-parameter type
+     *
+     * @exception IOException thrown in case of file/content problem.
+     * @return Result of search the query inside the given document.
+     *
+     * @see GABResults
+     * @see GABQuery
+     */
+    GABResults searchFor(GABQuery gabQuery) throws IOException;
+
+}
+
diff --git a/common/onap-generic-artifact-browser/onap-generic-artifact-browser-service/src/main/java/org/onap/sdc/gab/GABServiceImpl.java b/common/onap-generic-artifact-browser/onap-generic-artifact-browser-service/src/main/java/org/onap/sdc/gab/GABServiceImpl.java
new file mode 100644 (file)
index 0000000..7f6c353
--- /dev/null
@@ -0,0 +1,42 @@
+/*
+ * ============LICENSE_START=======================================================
+ * GAB
+ * ================================================================================
+ * Copyright (C) 2019 Nokia Intellectual Property. All rights reserved.
+ * ================================================================================
+ * 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=========================================================
+ */
+
+package org.onap.sdc.gab;
+
+import java.io.IOException;
+import org.onap.sdc.gab.model.GABQuery;
+import org.onap.sdc.gab.model.GABQuery.GABQueryType;
+import org.onap.sdc.gab.model.GABResults;
+import org.onap.sdc.gab.yaml.GABYamlParser;
+import org.onap.sdc.gab.yaml.YamlParser;
+
+public class GABServiceImpl implements GABService {
+
+    public GABResults searchFor(GABQuery gabQuery) throws IOException {
+        try (GABYamlParser gabYamlParser = new GABYamlParser(new YamlParser())) {
+            return parse(gabQuery, gabYamlParser).filter(gabQuery.getFields()).collect();
+        }
+    }
+
+    private GABYamlParser parse(GABQuery gabQuery, GABYamlParser gabYamlParser){
+        return gabQuery.getType() == GABQueryType.PATH ?
+            gabYamlParser.parseFile(gabQuery.getDocument()) : gabYamlParser.parseContent(gabQuery.getDocument());
+    }
+}
diff --git a/common/onap-generic-artifact-browser/onap-generic-artifact-browser-service/src/main/java/org/onap/sdc/gab/model/GABQuery.java b/common/onap-generic-artifact-browser/onap-generic-artifact-browser-service/src/main/java/org/onap/sdc/gab/model/GABQuery.java
new file mode 100644 (file)
index 0000000..f306e09
--- /dev/null
@@ -0,0 +1,60 @@
+/*
+ * ============LICENSE_START=======================================================
+ * GAB
+ * ================================================================================
+ * Copyright (C) 2019 Nokia Intellectual Property. All rights reserved.
+ * ================================================================================
+ * 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=========================================================
+ */
+
+package org.onap.sdc.gab.model;
+
+import java.util.Set;
+import lombok.AllArgsConstructor;
+import lombok.Getter;
+
+/**
+ * See GABQuery.{@link #fields}, GABQuery.{@link #document}
+ */
+@AllArgsConstructor
+@Getter
+public class GABQuery {
+
+    /**
+     * PATH - when provided path to the yaml file
+     * CONTENT - when provided yaml file content
+     */
+    public enum GABQueryType{
+        PATH, CONTENT
+    }
+
+    /**
+     * JSON paths for querying specific data (this will be the definition of a "column").
+     */
+    private Set<String> fields;
+
+    /**
+     * An YAML document path/content
+     */
+    private String document;
+
+    /**
+     * Used for query type checking.
+     *
+     * @see GABQueryType
+     *
+     */
+    private GABQueryType type;
+
+}
diff --git a/common/onap-generic-artifact-browser/onap-generic-artifact-browser-service/src/main/java/org/onap/sdc/gab/model/GABResult.java b/common/onap-generic-artifact-browser/onap-generic-artifact-browser-service/src/main/java/org/onap/sdc/gab/model/GABResult.java
new file mode 100644 (file)
index 0000000..3338024
--- /dev/null
@@ -0,0 +1,48 @@
+/*
+ * ============LICENSE_START=======================================================
+ * GAB
+ * ================================================================================
+ * Copyright (C) 2019 Nokia Intellectual Property. All rights reserved.
+ * ================================================================================
+ * 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=========================================================
+ */
+
+package org.onap.sdc.gab.model;
+
+import com.google.common.base.MoreObjects;
+import java.util.List;
+import lombok.AllArgsConstructor;
+import lombok.Getter;
+
+/**
+ * See GABResults.{@link #entries}
+ */
+@Getter
+@AllArgsConstructor
+public class GABResult {
+
+    /**
+     * Result entries list of the executed GABQuery.
+     *
+     * @see GABQuery
+     * @see GABResultEntry
+     */
+    private List<GABResultEntry> entries;
+
+    @Override
+    public String toString() {
+        return MoreObjects.toStringHelper(this).add("entries", entries).toString();
+    }
+
+}
diff --git a/common/onap-generic-artifact-browser/onap-generic-artifact-browser-service/src/main/java/org/onap/sdc/gab/model/GABResultEntry.java b/common/onap-generic-artifact-browser/onap-generic-artifact-browser-service/src/main/java/org/onap/sdc/gab/model/GABResultEntry.java
new file mode 100644 (file)
index 0000000..45b2412
--- /dev/null
@@ -0,0 +1,52 @@
+/*
+ * ============LICENSE_START=======================================================
+ * GAB
+ * ================================================================================
+ * Copyright (C) 2019 Nokia Intellectual Property. All rights reserved.
+ * ================================================================================
+ * 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=========================================================
+ */
+
+package org.onap.sdc.gab.model;
+
+import com.google.common.base.MoreObjects;
+import lombok.AllArgsConstructor;
+import lombok.Getter;
+import org.onap.sdc.gab.GABService;
+
+/**
+ * See GABResultEntry.{@link #path}, GABResultEntry.{@link #data}
+ */
+@Getter
+@AllArgsConstructor
+public class GABResultEntry {
+    /**
+     * Path of queried data.
+     */
+    private String path;
+
+    /**
+     * Specific events-template data served by the GABService
+     * @see GABService
+     */
+    private Object data;
+
+    @Override
+    public String toString() {
+        return MoreObjects.toStringHelper(this)
+            .add("path", path)
+            .add("data", data)
+            .toString();
+    }
+}
diff --git a/common/onap-generic-artifact-browser/onap-generic-artifact-browser-service/src/main/java/org/onap/sdc/gab/model/GABResults.java b/common/onap-generic-artifact-browser/onap-generic-artifact-browser-service/src/main/java/org/onap/sdc/gab/model/GABResults.java
new file mode 100644 (file)
index 0000000..23d026b
--- /dev/null
@@ -0,0 +1,47 @@
+/*
+ * ============LICENSE_START=======================================================
+ * GAB
+ * ================================================================================
+ * Copyright (C) 2019 Nokia Intellectual Property. All rights reserved.
+ * ================================================================================
+ * 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=========================================================
+ */
+
+package org.onap.sdc.gab.model;
+
+import com.google.common.base.MoreObjects;
+import java.util.List;
+import lombok.AllArgsConstructor;
+import lombok.Getter;
+
+/**
+ * See GABResults.{@link #rows}
+ */
+@Getter
+@AllArgsConstructor
+public class GABResults {
+
+    /**
+     * Results list of the executed GABQuery.
+     *
+     * @see GABQuery
+     * @see GABResult
+     */
+    private List<GABResult> rows;
+
+    @Override
+    public String toString() {
+        return MoreObjects.toStringHelper(this).add("rows", rows).toString();
+    }
+}
diff --git a/common/onap-generic-artifact-browser/onap-generic-artifact-browser-service/src/main/java/org/onap/sdc/gab/yaml/GABYamlParser.java b/common/onap-generic-artifact-browser/onap-generic-artifact-browser-service/src/main/java/org/onap/sdc/gab/yaml/GABYamlParser.java
new file mode 100644 (file)
index 0000000..fae9442
--- /dev/null
@@ -0,0 +1,118 @@
+/*
+ * ============LICENSE_START=======================================================
+ * GAB
+ * ================================================================================
+ * Copyright (C) 2019 Nokia Intellectual Property. All rights reserved.
+ * ================================================================================
+ * 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=========================================================
+ */
+
+package org.onap.sdc.gab.yaml;
+
+import java.io.IOException;
+import java.util.AbstractMap.SimpleEntry;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.List;
+import java.util.Objects;
+import java.util.Set;
+import java.util.stream.Collectors;
+import org.onap.sdc.gab.model.GABResult;
+import org.onap.sdc.gab.model.GABResultEntry;
+import org.onap.sdc.gab.model.GABResults;
+
+/**
+ * Yaml parser and searcher for GAB. Requires 3 steps:
+ *
+ * <br>1. Load content of Yaml file using {@link #parseContent(String)} or {@link #parseFile(String)}
+ * <br>2. Provide keywords to search using {@link #filter(String)} or {@link #filter(Set)}
+ * <br>3. Collect the results using {@link #collect()}
+ */
+public class GABYamlParser implements AutoCloseable {
+
+    private YamlParser yamlParser;
+
+    public GABYamlParser(YamlParser yamlParser) {
+        this.yamlParser = yamlParser;
+    }
+
+    /**
+     * Provides yaml path for processing.
+     *
+     * @param path Yaml file path.
+     * @return Same parser with loaded source.
+     */
+    public GABYamlParser parseFile(String path) {
+        yamlParser.parseFile(path);
+        return this;
+    }
+
+    /**
+     * Provides yaml content for processing.
+     *
+     * @param content Yaml file content.
+     * @return Same parser with loaded source.
+     */
+    public GABYamlParser parseContent(String content) {
+        yamlParser.parseContent(content);
+        return this;
+    }
+
+    /**
+     * Adds set of filters for processing.
+     *
+     * @param filters correct json paths for searching resources.
+     * @return Same parser with loaded filters.
+     */
+    public GABYamlParser filter(Set<String> filters) {
+        yamlParser.filter(filters);
+        return this;
+    }
+
+    /**
+     * Adds single filter for processing.
+     *
+     * @param filter correct json path for searching resource.
+     * @return Same parser with loaded filter.
+     */
+    public GABYamlParser filter(String filter) {
+        yamlParser.filter(filter);
+        return this;
+    }
+
+    /**
+     * Collects the results from parsed yaml file and applied filters.
+     *
+     * @exception IOException Means that yaml file has invalid content.
+     * @return {@link GABResults}
+     */
+    public GABResults collect() throws IOException {
+        return new GABResults(yamlParser.collect().stream()
+            .map(results -> new GABResult(createGabResultEntryList(results)))
+            .collect(Collectors.toList()));
+    }
+
+    private List<GABResultEntry> createGabResultEntryList(List<SimpleEntry<String, ? extends Collection<Object>>> parsedContent) {
+        return Objects.isNull(parsedContent) ? Collections.emptyList() : parsedContent.stream()
+                .map(result -> result.getValue().stream()
+                    .map(entry -> new GABResultEntry(result.getKey(), entry))
+                    .collect(Collectors.toList())).flatMap(Collection::stream)
+                .collect(Collectors.toList());
+    }
+
+    @Override
+    public void close() throws IOException {
+        yamlParser.close();
+    }
+}
diff --git a/common/onap-generic-artifact-browser/onap-generic-artifact-browser-service/src/main/java/org/onap/sdc/gab/yaml/YamlParser.java b/common/onap-generic-artifact-browser/onap-generic-artifact-browser-service/src/main/java/org/onap/sdc/gab/yaml/YamlParser.java
new file mode 100644 (file)
index 0000000..0d35759
--- /dev/null
@@ -0,0 +1,188 @@
+/*
+ * ============LICENSE_START=======================================================
+ * GAB
+ * ================================================================================
+ * Copyright (C) 2019 Nokia Intellectual Property. All rights reserved.
+ * ================================================================================
+ * 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=========================================================
+ */
+
+package org.onap.sdc.gab.yaml;
+
+import com.google.gson.Gson;
+import com.google.gson.JsonElement;
+import java.io.IOException;
+import java.io.InputStream;
+import java.util.AbstractMap.SimpleEntry;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Objects;
+import java.util.Set;
+import java.util.function.Function;
+import java.util.function.Predicate;
+import java.util.logging.Level;
+import java.util.logging.Logger;
+import java.util.stream.Collectors;
+import java.util.stream.Stream;
+import java.util.stream.StreamSupport;
+import org.antlr.v4.runtime.misc.ParseCancellationException;
+import org.apache.commons.io.IOUtils;
+import org.jsfr.json.JsonSurfer;
+import org.jsfr.json.JsonSurferGson;
+import org.yaml.snakeyaml.Yaml;
+
+/**
+ * Yaml parser and searcher which requires 3 steps:
+ *
+ * <br>1. Load content of Yaml file using {@link #parseContent(String)} or {@link #parseFile(String)}
+ * <br>2. Provide keywords to search using {@link #filter(String)} or {@link #filter(Set)}
+ * <br>3. Collect the results using {@link #collect()}
+ */
+public class YamlParser implements AutoCloseable {
+
+    private static Logger LOGGER = Logger.getLogger(YamlParser.class.getName());
+
+    private Stream<Object> parsedYamlContent;
+    private InputStream inputStream;
+    private Set<String> filters;
+
+    public YamlParser() {
+        this.parsedYamlContent = Stream.empty();
+        filters = new HashSet<>();
+    }
+
+    /**
+     * Provides yaml path for processing.
+     *
+     * @param path Yaml file path.
+     * @return Same parser with loaded source.
+     */
+    YamlParser parseFile(String path) {
+        filters = new HashSet<>();
+        InputStream newInputStream = this.getClass().getClassLoader().getResourceAsStream(path);
+        parse(path, newInputStream);
+        return this;
+    }
+
+    /**
+     * Provides yaml content for processing.
+     *
+     * @param content Yaml file content.
+     * @return Same parser with loaded source.
+     */
+    YamlParser parseContent(String content) {
+        filters = new HashSet<>();
+        InputStream newInputStream = IOUtils.toInputStream(content);
+        parse(content, newInputStream);
+        return this;
+    }
+
+    /**
+     * Adds set of filters for processing.
+     *
+     * @param filters correct json paths for searching resources.
+     * @return Same parser with loaded filters.
+     */
+    YamlParser filter(Set<String> filters) {
+        this.filters.addAll(filters);
+        return this;
+    }
+
+    /**
+     * Adds single filter for processing.
+     *
+     * @param filter correct json path for searching resource.
+     * @return Same parser with loaded filter.
+     */
+    YamlParser filter(String filter) {
+        filters.add(filter);
+        return this;
+    }
+
+    /**
+     * Collects the results from parsed yaml file and applied filters.
+     *
+     * @exception IOException Means that yaml file has invalid content.
+     * @return List of List of simple entry 'key: collection of data'
+     */
+    List<List<SimpleEntry<String, ? extends Collection<Object>>>> collect() throws IOException {
+        try {
+            return parsedYamlContent.map(containsKeys).filter(notEmptyListPredicate()).collect(Collectors.toList());
+        } catch(Exception e){
+            LOGGER.log(Level.WARNING, "Unexpected document content. Please check body of the yaml file.", e);
+            throw new IOException("Unexpected document content");
+        }
+    }
+
+    private void parse(String yaml, InputStream newInputStream) {
+        try {
+            closeStream(inputStream);
+            inputStream = newInputStream;
+            if (Objects.isNull(inputStream) || inputStream.available() <= 0) {
+                throw new IOException("Empty input stream of yaml content.");
+            }
+            parsedYamlContent = StreamSupport.stream(new Yaml().loadAll(inputStream).spliterator(), false);
+        } catch (IOException e) {
+            LOGGER.log(Level.WARNING, "Cannot parse yaml: " + yaml, e);
+            parsedYamlContent = Stream.empty();
+        }
+    }
+
+    private Function<Object, List<SimpleEntry<String, ? extends Collection<Object>>>> containsKeys = parsedYamlSingleDocument -> {
+        JsonElement jsonElement = new Gson().toJsonTree(parsedYamlSingleDocument);
+        return findInJson(filters, jsonElement);
+    };
+
+    private List<SimpleEntry<String, ? extends Collection<Object>>> findInJson(Set<String> keys,
+        JsonElement document) {
+        return keys.stream()
+            .map(getEntryForKeyFunction(document))
+            .filter(notEmptyEntryPredicate())
+            .collect(Collectors.toList());
+    }
+
+    private Predicate<? super List<SimpleEntry<String, ? extends Collection<Object>>>> notEmptyListPredicate() {
+        return list -> !list.isEmpty();
+    }
+
+    private Predicate<SimpleEntry<String, ? extends Collection<Object>>> notEmptyEntryPredicate() {
+        return entry -> !entry.getValue().isEmpty();
+    }
+
+    private Function<String, SimpleEntry<String, ? extends Collection<Object>>> getEntryForKeyFunction(
+        JsonElement document) {
+        return key -> {
+            JsonSurfer surfer = JsonSurferGson.INSTANCE;
+            try {
+                return new SimpleEntry<>(key, surfer.collectAll(document.toString(), "$." + key));
+            } catch (ParseCancellationException e) {
+                LOGGER.log(Level.WARNING, "Invalid filter key: " + key, e);
+                return new SimpleEntry<>(key, Collections.emptyList());
+            }
+        };
+    }
+
+    private void closeStream(InputStream stream) throws IOException {
+        if (!Objects.isNull(stream) && !(stream.available() > 0)) {
+            stream.close();
+        }
+    }
+
+    @Override
+    public void close() throws IOException {
+        closeStream(inputStream);
+    }
+}
diff --git a/common/onap-generic-artifact-browser/onap-generic-artifact-browser-service/src/test/java/org/onap/sdc/gab/yaml/GABYamlParserTest.java b/common/onap-generic-artifact-browser/onap-generic-artifact-browser-service/src/test/java/org/onap/sdc/gab/yaml/GABYamlParserTest.java
new file mode 100644 (file)
index 0000000..6589209
--- /dev/null
@@ -0,0 +1,195 @@
+/*
+ * ============LICENSE_START=======================================================
+ * GAB
+ * ================================================================================
+ * Copyright (C) 2019 Nokia Intellectual Property. All rights reserved.
+ * ================================================================================
+ * 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=========================================================
+ */
+
+package org.onap.sdc.gab.yaml;
+
+import static org.hamcrest.MatcherAssert.assertThat;
+import static org.hamcrest.Matchers.equalTo;
+import static org.hamcrest.Matchers.is;
+import static org.junit.jupiter.api.Assertions.assertThrows;
+
+import com.google.common.collect.Sets;
+import java.io.IOException;
+import java.util.Collections;
+import org.junit.jupiter.api.Test;
+import org.onap.sdc.gab.model.GABResult;
+import org.onap.sdc.gab.model.GABResultEntry;
+import org.onap.sdc.gab.model.GABResults;
+
+class GABYamlParserTest {
+
+    private static final String EVENT_PRESENCE = "event.presence";
+    private static final String REQUIRED = "required";
+    private static final String INVALID_EVENT_HEARTBEAT_ACTION = "event.heartbeatAction.[1]";
+    private static final String EVENT_HEARTBEAT_ACTION = "event.heartbeatAction[1]";
+    private static final String FAULT = "fault";
+    private static final String DOMAIN_VALUE = "event.structure.commonEventHeader.structure.domain.value";
+    private static final String VNF_DOWN = "vnfDown";
+    private static final String SYSLOG = "syslog";
+    private static final String EVENT_STRUCTURE_HEARTBEAT_FIELDS_PRESENCE = "event.structure.heartbeatFields.presence";
+    private static final String HEARTBEAT = "heartbeat";
+    private static final String MEASUREMENTS_FOR_VF_SCALING = "measurementsForVfScaling";
+    private static final String EVENT = "event";
+    private static final String TEST = "test";
+    private static final String NONEXISTENT_FILE = "nonexistent.file";
+    private static final String FAULT_REGISTRATION_YML = "yaml/faultRegistration.yml";
+    private static final String INVALID_YML = "yaml/invalid.yml";
+
+    @Test
+    void shouldNotParseAnyYamlAndGenerateEmptyMapOfKeys() throws Exception {
+        GABResults result;
+        try (GABYamlParser yamlParser = new GABYamlParser(new YamlParser())){
+            result = yamlParser.filter(TEST).collect();
+        }
+        assertResultIsEmpty(result);
+    }
+
+    @Test
+    void shouldParseNonexistentYamlAndGenerateEmptyMapOfKeys() throws Exception {
+        GABResults result;
+        try (GABYamlParser yamlParser = new GABYamlParser(new YamlParser())){
+            result = yamlParser.parseFile(NONEXISTENT_FILE).collect();
+        }
+        assertResultIsEmpty(result);
+    }
+
+    @Test
+    void shouldParseExistentFileYamlAndGenerateEmptyMapOfKeysIfNoKeywordsSearched() throws Exception {
+        GABResults result;
+        try (GABYamlParser yamlParser = new GABYamlParser(new YamlParser())){
+            result = yamlParser.parseFile(FAULT_REGISTRATION_YML).collect();
+        }
+        assertResultIsEmpty(result);
+    }
+
+    @Test
+    void shouldParseFaultRegistrationAndGenerateMapOfKeysOnSingleFilter() throws Exception {
+        GABResults result;
+        try (GABYamlParser yamlParser = new GABYamlParser(new YamlParser())){
+            result = yamlParser.parseFile(FAULT_REGISTRATION_YML)
+                .filter(EVENT_PRESENCE).filter(EVENT_PRESENCE).collect();
+
+        }
+        assertRowsSize(result, 5);
+        assertThatEntryIsEqualTo(result, 0, 0, EVENT_PRESENCE, REQUIRED);
+    }
+
+    @Test
+    void shouldParseFaultRegistrationAndGenerateMapOfKeysOnTwoIndependentFilters() throws Exception {
+        GABResults result;
+        try (GABYamlParser yamlParser = new GABYamlParser(new YamlParser())){
+            result = yamlParser.parseFile(FAULT_REGISTRATION_YML)
+                .filter(DOMAIN_VALUE)
+                .filter(EVENT_PRESENCE)
+                .collect();
+
+        }
+        assertRowsSize(result, 5);
+        assertThatEntryIsEqualTo(result, 0 , 0, DOMAIN_VALUE, FAULT);
+        assertThatEntryIsEqualTo(result, 4 , 0, DOMAIN_VALUE, SYSLOG);
+    }
+
+    @Test
+    void shouldParseFaultRegistrationAndGenerateMapOfKeysOnTwoDependentFilters() throws Exception {
+        GABResults result;
+        try (GABYamlParser yamlParser = new GABYamlParser(new YamlParser())){
+            result = yamlParser.parseFile(FAULT_REGISTRATION_YML)
+                .filter(Sets.newHashSet(DOMAIN_VALUE, EVENT_PRESENCE))
+                .collect();
+
+        }
+        assertRowsSize(result, 5);
+        assertThatEntryIsEqualTo(result, 0, 0, DOMAIN_VALUE, FAULT);
+        assertThatEntryIsEqualTo(result, 4, 0, DOMAIN_VALUE, SYSLOG);
+    }
+
+    @Test
+    void shouldParseFaultRegistrationAndGenerateMapOfKeysOnThreeCombinedFilters() throws Exception {
+        GABResults result;
+        try (GABYamlParser yamlParser = new GABYamlParser(new YamlParser())){
+            result = yamlParser.parseFile(FAULT_REGISTRATION_YML)
+                .filter(Sets.newHashSet(DOMAIN_VALUE, EVENT_PRESENCE))
+                .filter(EVENT_STRUCTURE_HEARTBEAT_FIELDS_PRESENCE)
+                .collect();
+
+        }
+        assertRowsSize(result, 5);
+        assertThatEntryIsEqualTo(result, 0,0, DOMAIN_VALUE, FAULT);
+        assertThatEntryIsEqualTo(result, 0,1, EVENT_PRESENCE, REQUIRED);
+        assertThatEntryIsEqualTo(result, 1,0, DOMAIN_VALUE, FAULT);
+        assertThatEntryIsEqualTo(result, 1,1, EVENT_PRESENCE, REQUIRED);
+        assertThatEntryIsEqualTo(result, 2,0, DOMAIN_VALUE, HEARTBEAT);
+        assertThatEntryIsEqualTo(result, 2,1, EVENT_PRESENCE, REQUIRED);
+        assertThatEntryIsEqualTo(result, 3,0, DOMAIN_VALUE, MEASUREMENTS_FOR_VF_SCALING);
+        assertThatEntryIsEqualTo(result, 3,1, EVENT_PRESENCE, REQUIRED);
+        assertThatEntryIsEqualTo(result, 4,0, DOMAIN_VALUE, SYSLOG);
+        assertThatEntryIsEqualTo(result, 4,1, EVENT_PRESENCE, REQUIRED);
+    }
+
+    @Test
+    void shouldParseFaultRegistrationAndGenerateMapOfKeysOnFilterFromArray() throws Exception {
+        GABResults result;
+        try (GABYamlParser yamlParser = new GABYamlParser(new YamlParser())){
+            result = yamlParser.parseFile(FAULT_REGISTRATION_YML)
+                .filter(Sets.newHashSet(EVENT_HEARTBEAT_ACTION, EVENT_PRESENCE))
+                .collect();
+        }
+        assertRowsSize(result, 5);
+        assertThatEntryIsEqualTo(result,0,0, EVENT_PRESENCE, REQUIRED);
+        assertThatEntryIsEqualTo(result,2,1, EVENT_HEARTBEAT_ACTION, VNF_DOWN);
+    }
+
+    @Test
+    void shouldParseFaultRegistrationAndGenerateMapOfKeysRemovingInvalidKey() throws Exception {
+        GABResults result;
+        try (GABYamlParser yamlParser = new GABYamlParser(new YamlParser())){
+            result = yamlParser.parseFile(FAULT_REGISTRATION_YML)
+                .filter(Sets.newHashSet(INVALID_EVENT_HEARTBEAT_ACTION, EVENT_PRESENCE))
+                .collect();
+        }
+        assertRowsSize(result, 5);
+        assertThatEntryIsEqualTo(result, 0, 0, EVENT_PRESENCE, REQUIRED);
+    }
+
+    @Test
+    void shouldParseInvalidYamlAndGenerateIOException() {
+        assertThrows(IOException.class, () -> {
+        try (GABYamlParser yamlParser = new GABYamlParser(new YamlParser())){
+            yamlParser.parseFile(INVALID_YML)
+                .filter(EVENT)
+                .collect();
+        }});
+    }
+
+    private void assertThatEntryIsEqualTo(GABResults result, int rowIndex, int entryIndex, String path, String data){
+        GABResultEntry entry = result.getRows().get(rowIndex).getEntries().get(entryIndex);
+        assertThat(entry.getData(), is(equalTo(data)));
+        assertThat(entry.getPath(), is(equalTo(path)));
+    }
+
+    private void assertResultIsEmpty(GABResults result) {
+        assertThat(result.getRows(), is(equalTo(Collections.<GABResult>emptyList())));
+    }
+
+    private void assertRowsSize(GABResults results, int size){
+        assertThat(results.getRows().size(), is(equalTo(size)));
+    }
+
+}
\ No newline at end of file
diff --git a/common/onap-generic-artifact-browser/onap-generic-artifact-browser-service/src/test/resources/yaml/faultRegistration.yml b/common/onap-generic-artifact-browser/onap-generic-artifact-browser-service/src/test/resources/yaml/faultRegistration.yml
new file mode 100644 (file)
index 0000000..447af5e
--- /dev/null
@@ -0,0 +1,412 @@
+---
+# registration for Fault\_vMrf\_alarm003
+# Constants: the values of domain, eventName, priority, vfstatus
+# , version, alarmCondition, eventSeverity, eventSourceType,
+# faultFieldsVersion, specificProblem,
+# Variables (to be supplied at runtime) include: eventId, lastEpochMicrosec,
+
+# reportingEntityId, reportingEntityName, sequence, sourceId, sourceName,
+# startEpochMicrosec
+
+event: {presence: required, action: [ any, any, alarm003,RECO-rebuildVnf ],
+        structure: {
+          commonEventHeader: {presence: required, structure: {
+            domain: {presence: required, value: fault},
+            eventName: {presence: required, value: Fault\_vMrf\_alarm003},
+            eventId: {presence: required},
+            nfNamingCode: {value: mrfx},
+            priority: {presence: required, value: Medium},
+            reportingEntityId: {presence: required},
+            reportingEntityName: {presence: required},
+            sequence: {presence: required},
+            sourceId: {presence: required},
+            sourceName: {presence: required},
+            startEpochMicrosec: {presence: required},
+            lastEpochMicrosec: {presence: required},
+            version: {presence: required, value: 3.0}
+          }},
+          faultFields: {presence: required, structure: {
+            alarmCondition: {presence: required, value: alarm003},
+            eventSeverity: {presence: required, value: MAJOR},
+            eventSourceType: {presence: required, value: virtualNetworkFunction},
+            faultFieldsVersion: {presence: required, value: 2.0},
+            specificProblem: {presence: required, value: "Configuration file was
+                        corrupt or not present"},
+            vfStatus: {presence: required, value: "Requesting Termination"}
+          }}
+        }}
+---
+# registration for clearing Fault\_vMrf\_alarm003Cleared
+# Constants: the values of domain, eventName, priority,
+# , version, alarmCondition, eventSeverity, eventSourceType,
+# faultFieldsVersion, specificProblem,
+# Variables (to be supplied at runtime) include: eventId,lastEpochMicrosec,
+# reportingEntityId, reportingEntityName, sequence, sourceId,
+# sourceName, startEpochMicrosec, vfStatus
+event: {presence: required, action: [ any, any, alarm003, Clear ], structure: {
+  commonEventHeader: {presence: required, structure: {
+    domain: {presence: required, value: fault},
+    eventName: {presence: required, value: Fault\_vMrf\_alarm003Cleared},
+    eventId: {presence: required},
+    nfNamingCode: {value: mrfx},
+    priority: {presence: required, value: Medium},
+    reportingEntityId: {presence: required},
+    reportingEntityName: {presence: required},
+    sequence: {presence: required},
+    sourceId: {presence: required},
+    sourceName: {presence: required},
+    startEpochMicrosec: {presence: required},
+    lastEpochMicrosec: {presence: required},
+    version: {presence: required, value: 3.0}
+  }},
+  faultFields: {presence: required, structure: {
+    alarmCondition: {presence: required, value: alarm003},
+    eventSeverity: {presence: required, value: NORMAL},
+    eventSourceType: {presence: required, value: virtualNetworkFunction},
+    faultFieldsVersion: {presence: required, value: 2.0},
+    specificProblem: {presence: required, value: "Valid configuration file found"},
+    vfStatus: {presence: required, value: "Requesting Termination"}
+  }}
+}}
+---
+# registration for Heartbeat_vMRF
+# Constants: the values of domain, eventName, priority, version
+# Variables (to be supplied at runtime) include: eventId, lastEpochMicrosec,
+# reportingEntityId, reportingEntityName, sequence, sourceId, sourceName,
+# startEpochMicrosec
+event: {presence: required, heartbeatAction: [3, vnfDown,RECO-rebuildVnf],
+        structure: {
+          commonEventHeader: {presence: required, structure: {
+            domain: {presence: required, value: heartbeat},
+            eventName: {presence: required, value: Heartbeat\_vMrf},
+            eventId: {presence: required},
+            nfNamingCode: {value: mrfx},
+            priority: {presence: required, value: Normal},
+            reportingEntityId: {presence: required},
+            reportingEntityName: {presence: required},
+            sequence: {presence: required},
+            sourceId: {presence: required},
+            sourceName: {presence: required},
+            startEpochMicrosec: {presence: required},
+            lastEpochMicrosec: {presence: required},
+            version: {presence: required, value: 3.0}
+          }},
+          heartbeatFields: {presence: optional, structure:{
+            heartbeatFieldsVersion: {presence: required, value: 1.0},
+            heartbeatInterval: {presence: required, range: [ 15, 300 ], default: 60 }
+          }}
+        }}
+---
+# registration for Mfvs\_vMRF
+# Constants: the values of domain, eventName, priority, version,
+# measurementFieldsVersion, additionalMeasurements.namedArrayOfFields.name,
+# Variables (to be supplied at runtime) include: eventId, reportingEntityName, sequence,
+# sourceName, start/lastEpochMicrosec, measurementInterval,
+# concurrentSessions, requestRate, numberOfMediaPortsInUse,
+# cpuUsageArray.cpuUsage,cpuUsage.cpuIdentifier, cpuUsage.percentUsage,
+# additionalMeasurements.namedArrayOfFields.arrayOfFields,
+# vNicPerformance.receivedOctetsAccumulated,
+# vNicPerformance.transmittedOctetsAccumulated,
+# vNicPerformance.receivedTotalPacketsAccumulated,
+# vNicPerformance.transmittedTotalPacketsAccumulated,
+# vNicPerformance.vNicIdentifier, vNicPerformance.receivedOctetsDelta,
+# vNicPerformance.receivedTotalPacketsDelta,
+# vNicPerformance.transmittedOctetsDelta,
+# vNicPerformance.transmittedTotalPacketsDelta,
+# vNicPerformance.valuesAreSuspect, memoryUsageArray.memoryUsage,
+# memoryUsage.memoryConfigured, memoryUsage.vmIdentifier,
+# memoryUsage.memoryUsed, memoryUsage.memoryFree
+event: {presence: required, structure: {
+  commonEventHeader: {presence: required, structure: {
+    domain: {presence: required, value: measurementsForVfScaling},
+    eventName: {presence: required, value: Mfvs\_vMrf},
+    eventId: {presence: required},
+    nfNamingCode: {value: mrfx},
+    priority: {presence: required, value: Normal},
+    reportingEntityId: {presence: required},
+    reportingEntityName: {presence: required},
+    sequence: {presence: required},
+    sourceId: {presence: required},
+    sourceName: {presence: required},
+    startEpochMicrosec: {presence: required},
+    lastEpochMicrosec: {presence: required},
+    version: {presence: required, value: 3.0}
+  }},
+  measurementsForVfScalingFields: {presence: required, structure: {
+    measurementFieldsVersion: {presence: required, value: 2.0},
+    measurementInterval: {presence: required, range: [ 60, 3600 ], default:300},
+    concurrentSessions: {presence: required, range: [ 0, 100000 ]},
+    requestRate: {presence: required, range: [ 0, 100000 ]},
+    numberOfMediaPortsInUse: {presence: required, range: [ 0, 100000 ]},
+    cpuUsageArray: {presence: required, array: [
+      cpuUsage: {presence: required, structure: {
+        cpuIdentifier: {presence: required},
+        percentUsage: {presence: required, range: [ 0, 100 ],
+                       action: [80, up, CpuUsageHigh, RECO-scaleOut],
+                       action: [10, down, CpuUsageLow, RECO-scaleIn]}
+      }}
+    ]},
+    memoryUsageArray: {presence: required, array: [
+      memoryUsage: {presence: required, structure: {
+        memoryConfigured: {presence: required, value: 33554432},
+        memoryFree: {presence: required, range: [ 0, 33554432 ],
+                     action: [100, down, FreeMemLow, RECO-scaleOut],
+                     action: [30198989, up, FreeMemHigh, RECO-scaleIn]},
+        memoryUsed: {presence: required, range: [ 0, 33554432 ]},
+        vmIdentifier: {presence: required}
+      }}
+    ]},
+    additionalMeasurements: {presence: required, array: [
+      namedArrayOfFields: {presence: required, structure: {
+        name: {presence: required, value: licenseUsage},
+        arrayOfFields: {presence: required, array: [
+          field: {presence: required, structure: {
+            name: {presence: required, value: G711AudioPort},
+            value: {presence: required, range: [ 0, 100000 ],
+                    units: numberOfPorts }
+          }},
+          field: {presence: required, structure: {
+            name: {presence: required, value: G729AudioPort},
+            value: {presence: required, range: [ 0, 100000 ],
+                    units: numberOfPorts }
+          }},
+          field: {presence: required, structure: {
+            name: {presence: required, value: G722AudioPort},
+            value: {presence: required, range: [ 0, 100000 ],
+                    units: numberOfPorts }
+          }},
+          field: {presence: required, structure: {
+            name: {presence: required, value: AMRAudioPort},
+            value: {presence: required, range: [ 0, 100000 ],
+                    units: numberOfPorts }
+          }},
+          field: {presence: required, structure: {
+            name: {presence: required, value: AMRWBAudioPort},
+            value: {presence: required, range: [ 0, 100000 ],
+                    units: numberOfPorts }
+          }},
+          field: {presence: required, structure: {
+            name: {presence: required, value: OpusAudioPort},
+            value: {presence: required, range: [ 0, 100000 ],
+                    units: numberOfPorts }
+          }},
+          field: {presence: required, structure: {
+            name: {presence: required, value: H263VideoPort},
+            value: {presence: required, range: [ 0, 100000 ],
+                    units: numberOfPorts }
+          }},
+          field: {presence: required, structure: {
+            name: {presence: required, value: H264NonHCVideoPort},
+            value: {presence: required, range: [ 0, 100000 ],
+                    units: numberOfPorts }
+          }},
+          field: {presence: required, structure: {
+            name: {presence: required, value: H264HCVideoPort},
+            value: {presence: required, range: [ 0, 100000 ],
+                    units: numberOfPorts }
+          }},
+          field: {presence: required, structure: {
+            name: {presence: required, value: MPEG4VideoPort},
+            value: {presence: required, range: [ 0, 100000 ],
+                    units: numberOfPorts }
+          }},
+          field: {presence: required, structure: {
+            name: {presence: required, value: VP8NonHCVideoPort},
+            value: {presence: required, range: [ 0, 100000 ],
+                    units: numberOfPorts }
+          }},
+          field: {presence: required, structure: {
+            name: {presence: required, value: VP8HCVideoPort},
+            value: {presence: required, range: [ 0, 100000 ],
+                    units: numberOfPorts }
+          }},
+          field: {presence: required, structure: {
+            name: {presence: required, value: PLC},
+            value: {presence: required, range: [ 0, 100000 ],
+                    units: numberOfPorts }
+          }},
+          field: {presence: required, structure: {
+            name: {presence: required, value: AEC},
+            value: {presence: required, range: [ 0, 100000 ],
+                    units: numberOfPorts }
+          }},
+          field: {presence: required, structure: {
+            name: {presence: required, value: NR},
+            value: {presence: required, range: [ 0, 100000 ],
+                    units: numberOfPorts }
+          }},
+          field: {presence: required, structure: {
+            name: {presence: required, value: NG},
+            value: {presence: required, range: [ 0, 100000 ],
+                    units: numberOfPorts }
+          }},
+          field: {presence: required, structure: {
+            name: {presence: required, value: NLD},
+            value: {presence: required, range: [ 0, 100000 ],
+                    units: numberOfPorts }
+          }},
+          field: {presence: required, structure: {
+            name: {presence: required, value: G711FaxPort},
+            value: {presence: required, range: [ 0, 100000 ],
+                    units: numberOfPorts }
+          }},
+          field: {presence: required, structure: {
+            name: {presence: required, value: T38FaxPort},
+            value: {presence: required, range: [ 0, 100000 ],
+                    units: numberOfPorts }
+          }},
+          field: {presence: required, structure: {
+            name: {presence: required, value: RFactor},
+            value: {presence: required, range: [ 0, 100000 ],
+                    units: numberOfPorts }
+          }},
+          field: {presence: required, structure: {
+            name: {presence: required, value: T140TextPort},
+            value: {presence: required, range: [ 0, 100000 ],
+                    units: numberOfPorts }
+          }},
+          field: {presence: required, structure: {
+            name: {presence: required, value: EVSAudioPort},
+            value: {presence: required, range: [ 0, 100000 ],
+                    units: numberOfPorts }
+          }}
+        ]}
+      }},
+      namedArrayOfFields: {presence: required, structure: {
+        name: {presence: required, value: mediaCoreUtilization},
+        arrayOfFields: {presence: required, array: [
+          field: {presence: required, structure: {
+            name: {presence: required, value: actualAvgAudio},
+            value: {presence: required, range: [ 0, 255 ],
+                    action: [80, up, AudioCoreUsageHigh, RECO-scaleOut],
+                    action: [10, down, AudioCoreUsageLow, RECO-scaleIn]}
+          }},
+          field: {presence: required, structure: {
+            name: {presence: required, value: modelAvgAudio},
+            value: {presence: required, range: [ 0, 100 ],
+                    action: [80, up, AudioCoreUsageHigh, RECO-scaleOut],
+                    action: [10, down, AudioCoreUsageLow, RECO-scaleIn]}
+          }},
+          field: {presence: required, structure: {
+            name: {presence: required, value: actualMaxAudio},
+            value: {presence: required, range: [ 0, 255 ]}
+          }},
+          field: {presence: required, structure: {
+            name: {presence: required, value: modelMaxAudio},
+            value: {presence: required, range: [ 0, 100 ]}
+          }},
+          field: {presence: required, structure: {
+            name: {presence: required, value: actualAvgVideo},
+            value: {presence: required, range: [ 0, 255 ],
+                    action: [80, up, VideoCoreUsageHigh, RECO-scaleOut],
+                    action: [10, down, VideoCoreUsageLow, RECO-scaleIn]}
+          }},
+          field: {presence: required, structure: {
+            name: {presence: required, value: modelAvgVideo},
+            value: {presence: required, range: [ 0, 100 ],
+                    action: [80, up, VideoCoreUsageHigh, RECO-scaleOut],
+                    action: [10, down, VideoCoreUsageLow, RECO-scaleIn]}
+          }},
+          field: {presence: required, structure: {
+            name: {presence: required, value: actualMaxVideo},
+            value: {presence: required, range: [ 0, 255 ]}
+          }},
+          field: {presence: required, structure: {
+            name: {presence: required, value: modelMaxVideo},
+            value: {presence: required, range: [ 0, 100 ]}
+          }},
+          field: {presence: required, structure: {
+            name: {presence: required, value: actualAvgHcVideo},
+            value: {presence: required, range: [ 0, 255 ],
+                    action: [80, up, HcVideoCoreUsageHigh, RECO-scaleOut],
+                    action: [10, down, HcVideoCoreUsageLow, RECO-scaleIn]}
+          }},
+          field: {presence: required, structure: {
+            name: {presence: required, value: modelAvgHcVideo},
+            value: {presence: required, range: [ 0, 100 ],
+                    action: [80, up, HcVideoCoreUsageHigh, RECO-scaleOut],
+                    action: [10, down, HcVideoCoreUsageLow, RECO-scaleIn]}
+          }},
+          field: {presence: required, structure: {
+            name: {presence: required, value: actualMaxHcVideo},
+            value: {presence: required, range: [ 0, 255 ]}
+          }},
+          field: {presence: required, structure: {
+            name: {presence: required, value: modelMaxHcVideo},
+            value: {presence: required, range: [ 0, 100 ]}
+          }}
+        ]}
+      }}
+    ]},
+    vNicPerformanceArray: {presence: required, array: [
+      vNicPerformance: {presence: required, structure: {
+        receivedOctetsAccumulated: {presence: required,
+                                    range: [ 0, 18446744073709551615 ]},
+        receivedTotalPacketsAccumulated: {presence: required,
+                                          range: [ 0, 18446744073709551615 ]},
+        receivedOctetsDelta: {presence: required},
+        range: [ 0, 18446744073709551615 ],
+        receivedTotalPacketsDelta: {presence: required,
+                                    range: [ 0, 18446744073709551615 ]},
+        transmittedOctetsDelta: {presence: required,
+                                 range: [ 0, 18446744073709551615 ]},
+        transmittedOctetsAccumulated: {presence: required,
+                                       range: [ 0, 18446744073709551615 ]},
+        transmittedTotalPacketsAccumulated: {presence: required,
+                                             range: [ 0, 18446744073709551615 ]},
+        transmittedTotalPacketsDelta: {presence: required,
+                                       range: [ 0, 18446744073709551615 ]},
+        valuesAreSuspect: {presence: required, value: [ true, false ]},
+        vNicIdentifier: {presence: required}
+      }}
+    ]}
+  }}
+}}
+---
+# registration for Syslog\_vMRF
+# Constants: the values of domain, eventName, priority, lastEpochMicrosec, version,
+# syslogFields.syslogFieldsVersion, syslogFields.syslogTag
+# Variables include: eventId, lastEpochMicrosec, reportingEntityId, reportingEntityName,
+# sequence, sourceId, sourceName, startEpochMicrosec,
+# syslogFields.eventSourceHost, syslogFields.eventSourceType,
+# syslogFields.syslogFacility, syslogFields.syslogMsg
+event: {presence: required, structure: {
+  commonEventHeader: {presence: required, structure: {
+    domain: {presence: required, value: syslog},
+    eventName: {presence: required, value: Syslog\_vMrf},
+    eventId: {presence: required},
+    nfNamingCode: {value: mrfx},
+    priority: {presence: required, value: Normal},
+    reportingEntityId: {presence: required},
+    reportingEntityName: {presence: required},
+    sequence: {presence: required},
+    sourceId: {presence: required},
+    sourceName: {presence: required},
+    startEpochMicrosec: {presence: required},
+    lastEpochMicrosec: {presence: required},
+    version: {presence: required, value: 3.0},
+  }},
+  syslogFields: {presence: required, structure: {
+    eventSourceHost: {presence: required},
+    eventSourceType: {presence: required, value: virtualNetworkFunction},
+    syslogFacility: {presence: required, range: [16, 23]},
+    syslogSev: {presence: required, value: [ 0, 1, 2, 3, 4 ]},
+    syslogFieldsVersion: {presence: required, value: 3.0},
+    syslogMsg: {presence: required},
+    syslogTag: {presence: required, value: vMRF},
+  }}
+}}
+---
+#Rules
+Rules: [
+  rule: {
+    trigger: CpuUsageHigh \|\| FreeMemLow \|\| AudioCoreUsageHigh \|\|
+      VideoCoreUsageHigh \|\| HcVideoCoreUsageHigh,
+    microservices: [scaleOut]
+  },
+  rule: {
+    trigger: CpuUsageLow && FreeMemHigh && AudioCoreUsageLow &&
+      VideoCoreUsageLow && HcVideoCoreUsageLow,
+    microservices: [scaleIn]
+  }
+]
\ No newline at end of file
diff --git a/common/onap-generic-artifact-browser/onap-generic-artifact-browser-service/src/test/resources/yaml/invalid.yml b/common/onap-generic-artifact-browser/onap-generic-artifact-browser-service/src/test/resources/yaml/invalid.yml
new file mode 100644 (file)
index 0000000..9334720
--- /dev/null
@@ -0,0 +1,2 @@
+---
+event: "an escaped \' single quote"
\ No newline at end of file
diff --git a/common/onap-generic-artifact-browser/pom.xml b/common/onap-generic-artifact-browser/pom.xml
new file mode 100644 (file)
index 0000000..ff06395
--- /dev/null
@@ -0,0 +1,21 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<project xmlns="http://maven.apache.org/POM/4.0.0"
+  xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+  xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+  <parent>
+    <artifactId>onap-common-lib</artifactId>
+    <groupId>org.onap.sdc.common</groupId>
+    <version>1.4.0-SNAPSHOT</version>
+  </parent>
+  <modelVersion>4.0.0</modelVersion>
+
+  <artifactId>onap-generic-artifact-browser</artifactId>
+  <packaging>pom</packaging>
+
+  <modules>
+    <module>onap-generic-artifact-browser-service</module>
+    <module>onap-generic-artifact-browser-component-tests</module>
+  </modules>
+
+
+</project>
\ No newline at end of file
index 2eccf43..183cf1d 100644 (file)
@@ -35,6 +35,7 @@
     <modules>
         <module>onap-common-configuration-management</module>
         <module>onap-tosca-datatype</module>
+        <module>onap-generic-artifact-browser</module>
     </modules>
 
     <build>