Introduced yaml parser as common lib
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>
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
index 0000000..a9b10c8
--- /dev/null
+++ b/common/onap-generic-artifact-browser/onap-generic-artifact-browser-component-tests/pom.xml
@@ -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
index 0000000..3d5bf17
--- /dev/null
+++ b/common/onap-generic-artifact-browser/onap-generic-artifact-browser-component-tests/src/test/java/org/onap/sdc/gab/cucumber/RunCucumberTest.java
@@ -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
index 0000000..9f73a94
--- /dev/null
+++ b/common/onap-generic-artifact-browser/onap-generic-artifact-browser-component-tests/src/test/java/org/onap/sdc/gab/cucumber/actions/gabcontroller/GABControllerStepDefinitions.java
@@ -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
index 0000000..d0d1d24
--- /dev/null
+++ b/common/onap-generic-artifact-browser/onap-generic-artifact-browser-component-tests/src/test/resources/org/onap/sdc/gab/cucumber/gab_controller.feature
@@ -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
index 0000000..447af5e
--- /dev/null
+++ b/common/onap-generic-artifact-browser/onap-generic-artifact-browser-component-tests/src/test/resources/yaml/faultRegistration.yml
@@ -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
index 0000000..822dfa7
--- /dev/null
+++ b/common/onap-generic-artifact-browser/onap-generic-artifact-browser-service/pom.xml
@@ -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
index 0000000..0ac976a
--- /dev/null
+++ b/common/onap-generic-artifact-browser/onap-generic-artifact-browser-service/src/main/java/org/onap/sdc/gab/GABService.java
@@ -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
index 0000000..7f6c353
--- /dev/null
+++ b/common/onap-generic-artifact-browser/onap-generic-artifact-browser-service/src/main/java/org/onap/sdc/gab/GABServiceImpl.java
@@ -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
index 0000000..f306e09
--- /dev/null
+++ b/common/onap-generic-artifact-browser/onap-generic-artifact-browser-service/src/main/java/org/onap/sdc/gab/model/GABQuery.java
@@ -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
index 0000000..3338024
--- /dev/null
+++ b/common/onap-generic-artifact-browser/onap-generic-artifact-browser-service/src/main/java/org/onap/sdc/gab/model/GABResult.java
@@ -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
index 0000000..45b2412
--- /dev/null
+++ b/common/onap-generic-artifact-browser/onap-generic-artifact-browser-service/src/main/java/org/onap/sdc/gab/model/GABResultEntry.java
@@ -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
index 0000000..23d026b
--- /dev/null
+++ b/common/onap-generic-artifact-browser/onap-generic-artifact-browser-service/src/main/java/org/onap/sdc/gab/model/GABResults.java
@@ -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
index 0000000..fae9442
--- /dev/null
+++ b/common/onap-generic-artifact-browser/onap-generic-artifact-browser-service/src/main/java/org/onap/sdc/gab/yaml/GABYamlParser.java
@@ -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
index 0000000..0d35759
--- /dev/null
+++ b/common/onap-generic-artifact-browser/onap-generic-artifact-browser-service/src/main/java/org/onap/sdc/gab/yaml/YamlParser.java
@@ -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
index 0000000..6589209
--- /dev/null
+++ b/common/onap-generic-artifact-browser/onap-generic-artifact-browser-service/src/test/java/org/onap/sdc/gab/yaml/GABYamlParserTest.java
@@ -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
index 0000000..447af5e
--- /dev/null
+++ b/common/onap-generic-artifact-browser/onap-generic-artifact-browser-service/src/test/resources/yaml/faultRegistration.yml
@@ -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
index 0000000..9334720
--- /dev/null
+++ b/common/onap-generic-artifact-browser/onap-generic-artifact-browser-service/src/test/resources/yaml/invalid.yml
@@ -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
index 0000000..ff06395
--- /dev/null
+++ b/common/onap-generic-artifact-browser/pom.xml
@@ -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
diff --git a/common/pom.xml b/common/pom.xml
index 2eccf43..183cf1d 100644
--- a/common/pom.xml
+++ b/common/pom.xml
@@ -35,6 +35,7 @@
<modules>
<module>onap-common-configuration-management</module>
<module>onap-tosca-datatype</module>
+ <module>onap-generic-artifact-browser</module>
</modules>
<build>