Skip to content

Commit

Permalink
feat: support named argumentes in sql v1 queries
Browse files Browse the repository at this point in the history
  • Loading branch information
tomwwinter committed Nov 21, 2024
1 parent 7d21b6c commit a501553
Show file tree
Hide file tree
Showing 5 changed files with 201 additions and 8 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -97,7 +97,8 @@ class DefaultReportCalculationUseCase(

@Throws(AamException::class)
private fun handleSqlReport(
report: Report, reportCalculation: ReportCalculation
report: Report,
reportCalculation: ReportCalculation,
): UseCaseOutcome<ReportCalculationData> {
for ((argKey: String, transformationKeys: List<String>) in report.transformations) {
handleTransformations(argKey, transformationKeys, reportCalculation.args)
Expand Down Expand Up @@ -180,10 +181,14 @@ class DefaultReportCalculationUseCase(
): QueryRequest {
return when (report.version) {
1 -> {
QueryRequest(
query = query.sql,
args = reportCalculation.args.values.toList()
)
if (query.sql.contains("$")) {
getQueryRequest(query, reportCalculation.args)
} else {
QueryRequest(
query = query.sql,
args = reportCalculation.args.values.toList()
)
}
}

2 -> {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,8 +16,6 @@ import com.aamdigital.aambackendservice.reporting.transformation.SqlFromDateTran
import com.aamdigital.aambackendservice.reporting.transformation.SqlFromDateTransformation.Companion.DEFAULT_FROM_DATE
import com.aamdigital.aambackendservice.reporting.transformation.SqlToDateTransformation
import com.aamdigital.aambackendservice.reporting.transformation.SqlToDateTransformation.Companion.DEFAULT_TO_DATE
import com.fasterxml.jackson.core.JsonFactory
import com.fasterxml.jackson.module.kotlin.jacksonObjectMapper
import org.assertj.core.api.Assertions.assertThat
import org.junit.jupiter.api.Assertions.assertEquals
import org.junit.jupiter.api.BeforeEach
Expand All @@ -35,7 +33,7 @@ import org.mockito.kotlin.whenever
class DefaultReportCalculationUseCaseTest {

private lateinit var service: DefaultReportCalculationUseCase

@Mock
lateinit var reportCalculationStorage: ReportCalculationStorage

Expand Down Expand Up @@ -208,6 +206,153 @@ class DefaultReportCalculationUseCaseTest {
)
}

@Test
fun `should apply named argument transformations before sending to query service (v1)`() {
// given
val report = Report(
id = "Report:1",
title = "Report",
version = 1,
items = listOf(
ReportItem.ReportQuery(
sql = "SELECT * FROM foo WHERE time BETWEEN \$from and \$to",
)
),
transformations = mapOf(
"to" to listOf("SQL_TO_DATE"),
"from" to listOf("SQL_FROM_DATE"),
),
)

val reportCalculation = ReportCalculation(
id = "ReportCalculation:1",
report = DomainReference("Report:1"),
status = ReportCalculationStatus.PENDING,
args = mutableMapOf(
Pair("from", "2010-01-15T00:00:00.000Z"),
Pair("to", "2010-01-16"),
)
)

whenever(
reportCalculationStorage.fetchReportCalculation(
eq(DomainReference("ReportCalculation:1"))
)
).thenReturn(reportCalculation)

whenever(
reportStorage.fetchReport(
eq(DomainReference("Report:1"))
)
).thenReturn(report)

whenever(queryStorage.executeQuery(any())).thenReturn("[{}]".byteInputStream())

whenever(reportCalculationStorage.addReportCalculationData(any(), any()))
.thenReturn(reportCalculation)

// when
val response = service.run(
ReportCalculationRequest(
reportCalculationId = reportCalculation.id
)
)

// then
assertThat(response).isInstanceOf(UseCaseOutcome.Success::class.java)

assertEquals(
reportCalculation,
(response as UseCaseOutcome.Success).data.reportCalculation
)

verify(queryStorage).executeQuery(
eq(
QueryRequest(
query = "SELECT * FROM foo WHERE time BETWEEN ? and ?",
args = listOf(
"2010-01-15", "2010-01-16T23:59:59.999Z"
)
)
)
)
}

@Test
fun `should apply multiple named argument transformations before sending to query service (v1)`() {
// given
val report = Report(
id = "Report:1",
title = "Report",
version = 1,
items = listOf(
ReportItem.ReportQuery(
sql = "SELECT * FROM foo WHERE time BETWEEN \$from and \$to AND date BETWEEN \$from AND \$to",
)
),
transformations = mapOf(
"to" to listOf("SQL_TO_DATE"),
"from" to listOf("SQL_FROM_DATE"),
),
)

val reportCalculation = ReportCalculation(
id = "ReportCalculation:1",
report = DomainReference("Report:1"),
status = ReportCalculationStatus.PENDING,
args = mutableMapOf(
Pair("from", "2010-01-15T00:00:00.000Z"),
Pair("to", "2010-01-16"),
)
)

whenever(
reportCalculationStorage.fetchReportCalculation(
eq(DomainReference("ReportCalculation:1"))
)
).thenReturn(reportCalculation)

whenever(
reportStorage.fetchReport(
eq(DomainReference("Report:1"))
)
).thenReturn(report)

whenever(queryStorage.executeQuery(any())).thenReturn("[{}]".byteInputStream())

whenever(reportCalculationStorage.addReportCalculationData(any(), any()))
.thenReturn(reportCalculation)

// when
val response = service.run(
ReportCalculationRequest(
reportCalculationId = reportCalculation.id
)
)

// then
assertThat(response).isInstanceOf(UseCaseOutcome.Success::class.java)

assertEquals(
reportCalculation,
(response as UseCaseOutcome.Success).data.reportCalculation
)

verify(queryStorage).executeQuery(
eq(
QueryRequest(
query = "SELECT * FROM foo WHERE time BETWEEN ? and ? AND date BETWEEN ? AND ?",
args = listOf(
"2010-01-15",
"2010-01-16T23:59:59.999Z",
"2010-01-15",
"2010-01-16T23:59:59.999Z",
)
)
)
)
}

@Test
fun `should apply argument transformations before sending to query service (v2)`() {
// given
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -97,3 +97,22 @@ Feature: the report calculation endpoint persist to database
When the client calls GET /v1/reporting/report-calculation/ReportCalculation:4/data
Then the client receives an json object
Then the client receives status code of 200

Scenario: ReportCalculation for v1 ReportConfig with named arguments is processed within 5 seconds
Given document ReportConfig:5 is stored in database app
Given document Config:CONFIG_ENTITY is stored in database app
Given document ReportCalculation:5 is stored in database report-calculation
Given signed in as client dummy-client with secret client-secret in realm dummy-realm
When the client calls GET /v1/reporting/report-calculation/ReportCalculation:5
Then the client receives an json object
Then the client receives status code of 200
Then the client receives value PENDING for property status
Given emit ReportCalculationEvent for ReportCalculation:5 in tenant local-spring
Then the client waits for 5000 milliseconds
When the client calls GET /v1/reporting/report-calculation/ReportCalculation:5
Then the client receives an json object
Then the client receives status code of 200
Then the client receives value FINISHED_SUCCESS for property status
When the client calls GET /v1/reporting/report-calculation/ReportCalculation:5/data
Then the client receives an json object
Then the client receives status code of 200
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
{
"_id": "ReportCalculation:5",
"report": {
"id": "ReportConfig:5"
},
"args": {
"from": "2024-01-01T00:00:00Z",
"to": "2024-04-30T00:00:00Z"
},
"status": "PENDING",
"startDate": null,
"endDate": null
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
{
"_id": "ReportConfig:5",
"title": "Version 1 with placeholder",
"mode": "sql",
"version": 1,
"neededArgs": [
"from",
"to"
],
"aggregationDefinition": "SELECT s.name as name, s.privateSchool as privateSchool FROM School as s WHERE s.date BETWEEN $from AND $to AND s.date BETWEEN $from AND $to"
}

0 comments on commit a501553

Please sign in to comment.