Fix common event header parsing
During JSON parsing we were using 3 times 'version' field. Replaced
parsing with protobuf parser to avoid mistakes like this in future
Change-Id: I6224dc6533ab553e7e2315a95567a1fa48c1c5ad
Issue-ID: DCAEGEN2-710
Signed-off-by: Filip Krzywka <filip.krzywka@nokia.com>
diff --git a/hv-collector-core/src/main/kotlin/org/onap/dcae/collectors/veshv/impl/MessageValidator.kt b/hv-collector-core/src/main/kotlin/org/onap/dcae/collectors/veshv/impl/MessageValidator.kt
index 543d7dc..8affa0b 100644
--- a/hv-collector-core/src/main/kotlin/org/onap/dcae/collectors/veshv/impl/MessageValidator.kt
+++ b/hv-collector-core/src/main/kotlin/org/onap/dcae/collectors/veshv/impl/MessageValidator.kt
@@ -19,29 +19,17 @@
*/
package org.onap.dcae.collectors.veshv.impl
+import org.onap.dcae.collectors.veshv.domain.headerRequiredFieldDescriptors
import org.onap.dcae.collectors.veshv.model.VesMessage
import org.onap.ves.VesEventV5.VesEvent.CommonEventHeader
internal object MessageValidator {
- private val requiredFieldDescriptors = listOf(
- "version",
- "eventName",
- "domain",
- "eventId",
- "sourceName",
- "reportingEntityName",
- "priority",
- "startEpochMicrosec",
- "lastEpochMicrosec",
- "sequence")
- .map { fieldName -> CommonEventHeader.getDescriptor().findFieldByName(fieldName) }
-
fun isValid(message: VesMessage): Boolean {
return allMandatoryFieldsArePresent(message.header)
}
private fun allMandatoryFieldsArePresent(header: CommonEventHeader) =
- requiredFieldDescriptors
+ headerRequiredFieldDescriptors
.all { fieldDescriptor -> header.hasField(fieldDescriptor) }
}
diff --git a/hv-collector-domain/src/main/kotlin/org/onap/dcae/collectors/veshv/domain/validation.kt b/hv-collector-domain/src/main/kotlin/org/onap/dcae/collectors/veshv/domain/validation.kt
new file mode 100644
index 0000000..91c7545
--- /dev/null
+++ b/hv-collector-domain/src/main/kotlin/org/onap/dcae/collectors/veshv/domain/validation.kt
@@ -0,0 +1,35 @@
+/*
+ * ============LICENSE_START=======================================================
+ * dcaegen2-collectors-veshv
+ * ================================================================================
+ * Copyright (C) 2018 NOKIA
+ * ================================================================================
+ * 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.dcae.collectors.veshv.domain
+
+import org.onap.ves.VesEventV5
+
+val headerRequiredFieldDescriptors = listOf(
+ "version",
+ "eventName",
+ "domain",
+ "eventId",
+ "sourceName",
+ "reportingEntityName",
+ "priority",
+ "startEpochMicrosec",
+ "lastEpochMicrosec",
+ "sequence")
+ .map { fieldName -> VesEventV5.VesEvent.CommonEventHeader.getDescriptor().findFieldByName(fieldName) }
\ No newline at end of file
diff --git a/hv-collector-ves-message-generator/pom.xml b/hv-collector-ves-message-generator/pom.xml
index f06a911..4afe796 100644
--- a/hv-collector-ves-message-generator/pom.xml
+++ b/hv-collector-ves-message-generator/pom.xml
@@ -69,6 +69,10 @@
<scope>test</scope>
</dependency>
<dependency>
+ <groupId>com.google.protobuf</groupId>
+ <artifactId>protobuf-java-util</artifactId>
+ </dependency>
+ <dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-api</artifactId>
</dependency>
diff --git a/hv-collector-ves-message-generator/src/main/kotlin/org/onap/dcae/collectors/veshv/ves/message/generator/impl/CommonEventHeaderParser.kt b/hv-collector-ves-message-generator/src/main/kotlin/org/onap/dcae/collectors/veshv/ves/message/generator/impl/CommonEventHeaderParser.kt
index e5977fb..768685c 100644
--- a/hv-collector-ves-message-generator/src/main/kotlin/org/onap/dcae/collectors/veshv/ves/message/generator/impl/CommonEventHeaderParser.kt
+++ b/hv-collector-ves-message-generator/src/main/kotlin/org/onap/dcae/collectors/veshv/ves/message/generator/impl/CommonEventHeaderParser.kt
@@ -19,11 +19,10 @@
*/
package org.onap.dcae.collectors.veshv.ves.message.generator.impl
-import com.google.protobuf.ByteString
-import org.onap.ves.VesEventV5.VesEvent.CommonEventHeader
-import org.onap.ves.VesEventV5.VesEvent.CommonEventHeader.Domain
-import org.onap.ves.VesEventV5.VesEvent.CommonEventHeader.Priority
-import org.onap.ves.VesEventV5.VesEvent.CommonEventHeader.newBuilder
+import arrow.core.Option
+import com.google.protobuf.util.JsonFormat
+import org.onap.dcae.collectors.veshv.domain.headerRequiredFieldDescriptors
+import org.onap.ves.VesEventV5.VesEvent.*
import javax.json.JsonObject
/**
@@ -31,22 +30,21 @@
* @since July 2018
*/
class CommonEventHeaderParser {
- fun parse(json: JsonObject): CommonEventHeader = newBuilder()
- .setVersion(json.getString("version"))
- .setDomain(Domain.valueOf(json.getString("domain")))
- .setSequence(json.getInt("sequence"))
- .setPriority(Priority.forNumber(json.getInt("priority")))
- .setEventId(json.getString("version"))
- .setEventName(json.getString("version"))
- .setEventType(json.getString("version"))
- .setStartEpochMicrosec(json.getJsonNumber("startEpochMicrosec").longValue())
- .setLastEpochMicrosec(json.getJsonNumber("lastEpochMicrosec").longValue())
- .setNfNamingCode(json.getString("nfNamingCode"))
- .setNfcNamingCode(json.getString("nfcNamingCode"))
- .setReportingEntityId(json.getString("reportingEntityId"))
- .setReportingEntityName(ByteString.copyFromUtf8(json.getString("reportingEntityName")))
- .setSourceId(ByteString.copyFromUtf8(json.getString("sourceId")))
- .setSourceName(json.getString("sourceName"))
- .build()
+ fun parse(json: JsonObject): Option<CommonEventHeader> =
+ Option.fromNullable(
+ CommonEventHeader.newBuilder()
+ .apply { JsonFormat.parser().merge(json.toString(), this) }
+ .build()
+ .takeUnless { !isValid(it) }
+ )
+
+
+ private fun isValid(header: CommonEventHeader): Boolean {
+ return allMandatoryFieldsArePresent(header)
+ }
+
+ private fun allMandatoryFieldsArePresent(header: CommonEventHeader) =
+ headerRequiredFieldDescriptors
+ .all { fieldDescriptor -> header.hasField(fieldDescriptor) }
}
diff --git a/hv-collector-ves-message-generator/src/main/kotlin/org/onap/dcae/collectors/veshv/ves/message/generator/impl/MessageParametersParserImpl.kt b/hv-collector-ves-message-generator/src/main/kotlin/org/onap/dcae/collectors/veshv/ves/message/generator/impl/MessageParametersParserImpl.kt
index f309561..ea0ee28 100644
--- a/hv-collector-ves-message-generator/src/main/kotlin/org/onap/dcae/collectors/veshv/ves/message/generator/impl/MessageParametersParserImpl.kt
+++ b/hv-collector-ves-message-generator/src/main/kotlin/org/onap/dcae/collectors/veshv/ves/message/generator/impl/MessageParametersParserImpl.kt
@@ -21,6 +21,7 @@
import arrow.core.Option
import arrow.core.Try
+import arrow.core.identity
import org.onap.dcae.collectors.veshv.ves.message.generator.api.MessageParameters
import org.onap.dcae.collectors.veshv.ves.message.generator.api.MessageParametersParser
import org.onap.dcae.collectors.veshv.ves.message.generator.api.MessageType
@@ -42,6 +43,7 @@
.map {
val commonEventHeader = commonEventHeaderParser
.parse(it.getJsonObject("commonEventHeader"))
+ .fold({ throw IllegalStateException("Invalid common header") }, ::identity)
val messageType = MessageType.valueOf(it.getString("messageType"))
val messagesAmount = it.getJsonNumber("messagesAmount")?.longValue()
?: throw NullPointerException("\"messagesAmount\" could not be parsed from message.")
diff --git a/hv-collector-ves-message-generator/src/test/kotlin/org/onap/dcae/collectors/veshv/ves/message/generator/impl/CommonEventHeaderParserTest.kt b/hv-collector-ves-message-generator/src/test/kotlin/org/onap/dcae/collectors/veshv/ves/message/generator/impl/CommonEventHeaderParserTest.kt
new file mode 100644
index 0000000..c16459c
--- /dev/null
+++ b/hv-collector-ves-message-generator/src/test/kotlin/org/onap/dcae/collectors/veshv/ves/message/generator/impl/CommonEventHeaderParserTest.kt
@@ -0,0 +1,81 @@
+/*
+ * ============LICENSE_START=======================================================
+ * dcaegen2-collectors-veshv
+ * ================================================================================
+ * Copyright (C) 2018 NOKIA
+ * ================================================================================
+ * 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.dcae.collectors.veshv.ves.message.generator.impl
+
+import arrow.core.Option
+import arrow.core.identity
+import com.google.protobuf.util.JsonFormat
+import org.assertj.core.api.Assertions.assertThat
+import org.jetbrains.spek.api.Spek
+import org.jetbrains.spek.api.dsl.describe
+import org.jetbrains.spek.api.dsl.given
+import org.jetbrains.spek.api.dsl.it
+import org.onap.dcae.collectors.veshv.tests.utils.commonHeader
+import org.onap.ves.VesEventV5
+import java.io.ByteArrayInputStream
+import javax.json.Json
+import kotlin.test.fail
+
+class CommonEventHeaderParserTest : Spek({
+
+ describe("Common event header parser") {
+ val parser = CommonEventHeaderParser()
+
+ given("valid header in JSON format") {
+ val commonEventHeader = commonHeader(
+ domain = VesEventV5.VesEvent.CommonEventHeader.Domain.STATE_CHANGE,
+ id = "sample-event-id")
+ val json = JsonFormat.printer().print(commonEventHeader).byteInputStream()
+
+ it("should parse common event header") {
+ val result =
+ parser.parse(jsonObject(json))
+ .fold({ fail() }, ::identity)
+
+ assertThat(result).describedAs("common event header").isEqualTo(commonEventHeader)
+ }
+ }
+
+ given("invalid header in JSON format") {
+ val json = "{}".byteInputStream()
+
+ it("should throw exception") {
+ val result = parser.parse(jsonObject(json))
+
+ assertFailed(result)
+ }
+ }
+
+ given("invalid JSON") {
+ val json = "{}}}}".byteInputStream()
+
+ it("should throw exception") {
+ val result = parser.parse(jsonObject(json))
+
+ assertFailed(result)
+ }
+ }
+ }
+})
+
+fun assertFailed(result: Option<VesEventV5.VesEvent.CommonEventHeader>) =
+ result.fold({}, { fail() })
+
+fun jsonObject(json: ByteArrayInputStream) = Json.createReader(json).readObject()
\ No newline at end of file