diff --git a/build.gradle b/build.gradle index 3c85d3a..3a8f1c9 100644 --- a/build.gradle +++ b/build.gradle @@ -35,7 +35,7 @@ dependencies { api platform('com.exactpro.th2:bom:4.0.2') - implementation 'com.exactpro.th2:cache-common:0.0.1-dev-version-1-4230346685-cb0e98c-SNAPSHOT' + implementation 'com.exactpro.th2:cache-common:0.0.1-dev-version-1-4252277065-cbd09b1-SNAPSHOT' implementation 'com.exactpro.th2:common:3.39.0' implementation "com.exactpro.th2:cradle-core:${cradleVersion}" @@ -47,13 +47,15 @@ dependencies { implementation("io.ktor:ktor-server-compression:$ktor_version") implementation "io.ktor:ktor-server-status-pages:$ktor_version" - implementation 'com.arangodb:arangodb-java-driver:6.17.0' - implementation 'com.arangodb:jackson-dataformat-velocypack:3.0.1' implementation 'com.fasterxml.jackson.datatype:jackson-datatype-jsr310:2.13.3' implementation 'org.apache.logging.log4j:log4j-core:2.17.2' implementation 'org.apache.logging.log4j:log4j-slf4j-impl:2.17.2' implementation 'io.github.microutils:kotlin-logging:2.1.23' + + testImplementation 'org.junit.jupiter:junit-jupiter:5.8.1' + testImplementation 'io.mockk:mockk:1.13.4' + } jar { diff --git a/src/main/kotlin/com/exactpro/th2/cradle/cache/Main.kt b/src/main/kotlin/com/exactpro/th2/cradle/cache/Main.kt index 85dcc0b..6d49db8 100644 --- a/src/main/kotlin/com/exactpro/th2/cradle/cache/Main.kt +++ b/src/main/kotlin/com/exactpro/th2/cradle/cache/Main.kt @@ -45,7 +45,7 @@ class Main(args: Array) { configurationFactory = CommonFactory.createFromArguments(*args) resources += configurationFactory val configuration = configurationFactory.getCustomConfiguration(Configuration::class.java) - val arango = Arango(configuration.arangoCredentials) + val arango = Arango(com.exactpro.th2.cache.common.Arango(configuration.arangoCredentials)) resources += arango context = Context( configuration, diff --git a/src/main/kotlin/com/exactpro/th2/cradle/cache/db/Arango.kt b/src/main/kotlin/com/exactpro/th2/cradle/cache/db/Arango.kt index 996720f..7e8e6b4 100644 --- a/src/main/kotlin/com/exactpro/th2/cradle/cache/db/Arango.kt +++ b/src/main/kotlin/com/exactpro/th2/cradle/cache/db/Arango.kt @@ -20,15 +20,13 @@ import com.exactpro.th2.cache.common.Arango import com.exactpro.th2.cache.common.Arango.Companion.EVENT_COLLECTION import com.exactpro.th2.cache.common.Arango.Companion.EVENT_GRAPH import com.exactpro.th2.cache.common.Arango.Companion.PARSED_MESSAGE_COLLECTION -import com.exactpro.th2.cache.common.ArangoCredentials import com.exactpro.th2.cache.common.event.Event import com.exactpro.th2.cradle.cache.entities.exceptions.DataNotFoundException import com.exactpro.th2.cradle.cache.entities.exceptions.InvalidRequestException import com.exactpro.th2.cradle.cache.entities.response.event.EventResponse import java.util.function.Consumer -class Arango(credentials: ArangoCredentials) : AutoCloseable { - val arango: Arango = Arango(credentials) +class Arango(val arango: Arango) : AutoCloseable { fun getMessage(messageId: String, probe: Boolean): String? { val query = """FOR message IN $PARSED_MESSAGE_COLLECTION @@ -44,7 +42,7 @@ class Arango(credentials: ArangoCredentials) : AutoCloseable { val query = """FOR message IN $PARSED_MESSAGE_COLLECTION |FILTER message._key == "$messageId" |LIMIT 1 - |RETURN message.message""".trimMargin() + |RETURN message.body""".trimMargin() return arango.executeAqlQuery(query, String::class.java) .ifEmpty { if (probe) null else throw DataNotFoundException("Message not found by id: $messageId") } ?.first() diff --git a/src/test/kotlin/com/exactpro/th2/cradle/cache/db/ArangoTest.kt b/src/test/kotlin/com/exactpro/th2/cradle/cache/db/ArangoTest.kt new file mode 100644 index 0000000..f85c319 --- /dev/null +++ b/src/test/kotlin/com/exactpro/th2/cradle/cache/db/ArangoTest.kt @@ -0,0 +1,141 @@ +/* + * Copyright 2023 Exactpro (Exactpro Systems Limited) + * + * 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. + */ + +package com.exactpro.th2.cradle.cache.db + +import com.exactpro.th2.cache.common.event.Event +import io.mockk.mockk +import io.mockk.slot +import io.mockk.verify +import org.junit.jupiter.api.Assertions.assertEquals +import org.junit.jupiter.api.Test + +internal class ArangoTest { + private val arangoMock = mockk (relaxed = true) + private val arango = Arango(arangoMock) + + @Test + fun `check 'message'{id} works properly`() { + val expected = """FOR message IN parsed_messages + |FILTER message._key == "abc-def" + |LIMIT 1 + |RETURN message""".trimMargin() + + arango.getMessage("abc-def", true) + + val query = slot() + verify { arango.arango.executeAqlQuery(capture(query), String::class.java) } + assertEquals(expected, query.captured) + } + + @Test + fun `check 'event'{book}'{scope}'{id} works properly`() { + val expected = """FOR doc IN events + |FILTER doc.book == "book" AND doc.scope == "scope" AND doc.id == "id" + |LIMIT 1 + |RETURN doc""".trimMargin() + + arango.getEvent("book", "scope", "id", true) + + val query = slot() + verify { arango.arango.executeAqlQuery(capture(query), Event::class.java) } + assertEquals(expected, query.captured) + } + + @Test + fun `check 'eventParents'{book}'{scope} works properly`() { + val expected = """ + |FOR event IN events + | FILTER event.book == "book" AND event.scope == "scope" + | LET results = [] + | FOR vertex + | IN 0..100 + | INBOUND event + | GRAPH event_graph + | COLLECT r = event._key INTO results = vertex + | RETURN DISTINCT(results[-1])""".trimMargin() + + arango.getEventParents("book", "scope", mapOf(), true) + + val query = slot() + verify { arango.arango.executeAqlQuery(capture(query), any(), Event::class.java) } + assertEquals(expected, query.captured) + } + + @Test + fun `check 'attachedEvents'{id} works properly`() { + val expected = """FOR message IN parsed_messages + |FILTER message._key == "id" + |RETURN message.attachedEventIds + """.trimMargin() + + arango.getAttachedEvents("id", true) + + val query = slot() + verify { arango.arango.executeAqlQuery(capture(query), String::class.java) } + assertEquals(expected, query.captured) + } + + @Test + fun `check 'events'{book}'{scope} works properly`() { + val expected = """FOR doc IN events + |FILTER doc.book == "book" AND doc.scope == "scope" AND doc.id == "id" + |LIMIT 1 + |RETURN doc""".trimMargin() + + arango.getEvent("book", "scope", "id", true) + + val query = slot() + verify { arango.arango.executeAqlQuery(capture(query), Event::class.java) } + assertEquals(expected, query.captured) + } + + @Test + fun `check 'search'sse'messages works properly`() { + val expected = """FOR message IN parsed_messages + |FILTER message.timestamp >= 1000 AND message.timestamp <= 2000 AND message.alias IN ["session-1"] + |LIMIT 20, 10 + |RETURN message + """.trimMargin() + + val parametersMap = mapOf( + "start-timestamp" to listOf("1000"), + "end-timestamp" to listOf("2000"), + "page-size" to listOf("10"), + "page-number" to listOf("3") + ) + val sessions = listOf("session-1") + arango.searchMessages(parametersMap, sessions, true) { } + + val query = slot() + verify { arango.arango.executeAqlQuery(capture(query), String::class.java, any()) } + assertEquals(expected, query.captured) + } + + @Test + fun `check 'messageBody'{id} works properly`() { + val expexted = """FOR message IN parsed_messages + |FILTER message._key == "id" + |LIMIT 1 + |RETURN message.body""".trimMargin() + + arango.getMessageBody("id", true) + + val query = slot() + verify { arango.arango.executeAqlQuery(capture(query), String::class.java) } + assertEquals(expexted, query.captured) + } +}