diff --git a/adapter/adapter-service/src/test/scala/net/shrine/adapter/AbstractQueryRetrievalTestCase.scala b/adapter/adapter-service/src/test/scala/net/shrine/adapter/AbstractQueryRetrievalTestCase.scala
index e644441a4..2ba6d8a17 100644
--- a/adapter/adapter-service/src/test/scala/net/shrine/adapter/AbstractQueryRetrievalTestCase.scala
+++ b/adapter/adapter-service/src/test/scala/net/shrine/adapter/AbstractQueryRetrievalTestCase.scala
@@ -1,375 +1,377 @@
package net.shrine.adapter
+import net.shrine.problem.{TestProblem, ProblemSources, AbstractProblem}
+
import scala.xml.NodeSeq
import net.shrine.util.ShouldMatchersForJUnit
import ObfuscatorTest.within3
import javax.xml.datatype.XMLGregorianCalendar
import net.shrine.adapter.dao.AdapterDao
import net.shrine.adapter.dao.squeryl.AbstractSquerylAdapterTest
import net.shrine.client.HttpClient
import net.shrine.client.HttpResponse
import net.shrine.protocol.{HiveCredentials, AuthenticationInfo, BroadcastMessage, CrcRequest, Credential, ErrorResponse, I2b2ResultEnvelope, QueryResult, ReadResultRequest, ReadResultResponse, ResultOutputType, ShrineRequest, ShrineResponse, BaseShrineResponse, BaseShrineRequest, RunQueryRequest, RunQueryResponse, DefaultBreakdownResultOutputTypes}
import net.shrine.protocol.DefaultBreakdownResultOutputTypes.PATIENT_AGE_COUNT_XML
import net.shrine.protocol.ResultOutputType.PATIENT_COUNT_XML
import net.shrine.protocol.DefaultBreakdownResultOutputTypes.PATIENT_GENDER_COUNT_XML
import net.shrine.protocol.query.{QueryDefinition, Term}
import net.shrine.util.XmlDateHelper
import net.shrine.util.XmlDateHelper.now
import net.shrine.util.XmlGcEnrichments
import net.shrine.client.Poster
import net.shrine.adapter.translators.QueryDefinitionTranslator
import net.shrine.adapter.translators.ExpressionTranslator
import scala.util.Success
/**
* @author clint
* @since Nov 8, 2012
*/
//noinspection UnitMethodIsParameterless
abstract class AbstractQueryRetrievalTestCase[R <: BaseShrineResponse](
makeAdapter: (AdapterDao, HttpClient) => WithHiveCredentialsAdapter,
makeRequest: (Long, AuthenticationInfo) => BaseShrineRequest,
extractor: R => Option[(Long, QueryResult)]) extends AbstractSquerylAdapterTest with ShouldMatchersForJUnit {
private val authn = AuthenticationInfo("some-domain", "some-user", Credential("alskdjlkasd", false))
def doTestProcessRequestMissingQuery {
val adapter = makeAdapter(dao, MockHttpClient)
val response = adapter.processRequest(BroadcastMessage(0L, authn, makeRequest(-1L, authn)))
response.isInstanceOf[ErrorResponse] should be(true)
}
def doTestProcessInvalidRequest {
val adapter = makeAdapter(dao, MockHttpClient)
intercept[ClassCastException] {
//request must be a type of request we can handle
adapter.processRequest(BroadcastMessage(0L, authn, new AbstractQueryRetrievalTestCase.BogusRequest))
}
}
private val localMasterId = "alksjdkalsdjlasdjlkjsad"
private val shrineNetworkQueryId = 123L
private def doGetResults(adapter: Adapter) = adapter.processRequest(BroadcastMessage(shrineNetworkQueryId, authn, makeRequest(shrineNetworkQueryId, authn)))
private def toMillis(xmlGc: XMLGregorianCalendar): Long = xmlGc.toGregorianCalendar.getTimeInMillis
private val instanceId = 999L
private val setSize = 12345L
private val obfSetSize = setSize + 1
private val queryExpr = Term("foo")
private val topicId = "laskdjlkasd"
private val fooQuery = QueryDefinition("some-query",queryExpr)
def doTestProcessRequestIncompleteQuery(countQueryShouldWork: Boolean = true): Unit = afterCreatingTables {
val dbQueryId = dao.insertQuery(localMasterId, shrineNetworkQueryId, authn, fooQuery, isFlagged = false, hasBeenRun = true, flagMessage = None)
import ResultOutputType._
import XmlDateHelper.now
val breakdowns = Map(PATIENT_AGE_COUNT_XML -> I2b2ResultEnvelope(PATIENT_AGE_COUNT_XML, Map("a" -> 1L, "b" -> 2L)))
val obfscBreakdowns = breakdowns.mapValues(_.mapValues(_ + 1))
val startDate = now
val elapsed = 100L
val endDate = {
import XmlGcEnrichments._
import scala.concurrent.duration._
startDate + elapsed.milliseconds
}
val countResultId = 456L
val breakdownResultId = 98237943265436L
val incompleteCountResult = QueryResult(
resultId = countResultId,
instanceId = instanceId,
resultType = Some(PATIENT_COUNT_XML),
setSize = setSize,
startDate = Option(startDate),
endDate = Option(endDate),
description = Some("results from node X"),
statusType = QueryResult.StatusType.Processing,
statusMessage = None,
breakdowns = breakdowns)
val breakdownResult = breakdowns.head match {
case (resultType, data) => incompleteCountResult.withId(breakdownResultId).withBreakdowns(Map(resultType -> data)).withResultType(resultType)
}
val queryStartDate = now
val idsByResultType = dao.insertQueryResults(dbQueryId, incompleteCountResult :: breakdownResult :: Nil)
final class MightWorkMockHttpClient(expectedHiveCredentials: HiveCredentials) extends HttpClient {
override def post(input: String, url: String): HttpResponse = {
def makeFinished(queryResult: QueryResult) = queryResult.copy(statusType = QueryResult.StatusType.Finished)
def validateAuthnAndProjectId(req: ShrineRequest) {
req.authn should equal(expectedHiveCredentials.toAuthenticationInfo)
req.projectId should equal(expectedHiveCredentials.projectId)
}
val response = CrcRequest.fromI2b2String(DefaultBreakdownResultOutputTypes.toSet)(input) match {
case Success(req: ReadResultRequest) if req.localResultId == countResultId.toString => {
validateAuthnAndProjectId(req)
if (countQueryShouldWork) {
ReadResultResponse(123L, makeFinished(incompleteCountResult), I2b2ResultEnvelope(PATIENT_COUNT_XML, Map(PATIENT_COUNT_XML.name -> incompleteCountResult.setSize)))
} else {
- ErrorResponse("Retrieving count result failed")
+ ErrorResponse(TestProblem(summary = "Retrieving count result failed"))
}
}
case Success(req: ReadResultRequest) if req.localResultId == breakdownResultId.toString => {
validateAuthnAndProjectId(req)
ReadResultResponse(123L, makeFinished(breakdownResult), breakdowns.head._2)
}
case _ => fail(s"Unknown input: $input")
}
HttpResponse.ok(response.toI2b2String)
}
}
val adapter: WithHiveCredentialsAdapter = makeAdapter(dao, new MightWorkMockHttpClient(AbstractQueryRetrievalTestCase.hiveCredentials))
def getResults = doGetResults(adapter)
getResults.isInstanceOf[ErrorResponse] should be(true)
dao.insertCountResult(idsByResultType(PATIENT_COUNT_XML).head, setSize, obfSetSize)
dao.insertBreakdownResults(idsByResultType, breakdowns, obfscBreakdowns)
//The query shouldn't be 'done', since its status is PROCESSING
dao.findResultsFor(shrineNetworkQueryId).get.count.statusType should be(QueryResult.StatusType.Processing)
//Now, calling processRequest (via getResults) should cause the query to be re-retrieved from the CRC
val result = getResults.asInstanceOf[R]
//Which should cause the query to be re-stored with a 'done' status (since that's what our mock CRC returns)
val expectedStatusType = if (countQueryShouldWork) QueryResult.StatusType.Finished else QueryResult.StatusType.Processing
dao.findResultsFor(shrineNetworkQueryId).get.count.statusType should be(expectedStatusType)
if (!countQueryShouldWork) {
result.isInstanceOf[ErrorResponse] should be(true)
} else {
val Some((actualNetworkQueryId, actualQueryResult)) = extractor(result)
actualNetworkQueryId should equal(shrineNetworkQueryId)
import ObfuscatorTest.within3
actualQueryResult.resultType should equal(Some(PATIENT_COUNT_XML))
within3(setSize, actualQueryResult.setSize) should be(true)
actualQueryResult.description should be(Some("results from node X"))
actualQueryResult.statusType should equal(QueryResult.StatusType.Finished)
actualQueryResult.statusMessage should be(Some(QueryResult.StatusType.Finished.name))
actualQueryResult.breakdowns.foreach {
case (rt, I2b2ResultEnvelope(_, data)) => {
data.forall { case (key, value) => within3(value, breakdowns.get(rt).get.data.get(key).get) }
}
}
for {
startDate <- actualQueryResult.startDate
endDate <- actualQueryResult.endDate
} {
val actualElapsed = toMillis(endDate) - toMillis(startDate)
actualElapsed should equal(elapsed)
}
}
}
def doTestProcessRequestQueuedQuery: Unit = afterCreatingTables {
import ResultOutputType._
import XmlDateHelper.now
val startDate = now
val elapsed = 100L
val endDate = {
import XmlGcEnrichments._
import scala.concurrent.duration._
startDate + elapsed.milliseconds
}
val countResultId = 456L
val incompleteCountResult = QueryResult(-1L, -1L, Some(PATIENT_COUNT_XML), -1L, Option(startDate), Option(endDate), Some("results from node X"), QueryResult.StatusType.Queued, None)
dao.inTransaction {
val insertedQueryId = dao.insertQuery(localMasterId, shrineNetworkQueryId, authn, fooQuery, isFlagged = false, hasBeenRun = false, flagMessage = None)
//NB: We need to insert dummy QueryResult and Count records so that calls to StoredQueries.retrieve() in
//AbstractReadQueryResultAdapter, called when retrieving results for previously-queued-or-incomplete
//queries, will work.
val insertedQueryResultIds = dao.insertQueryResults(insertedQueryId, Seq(incompleteCountResult))
val countQueryResultId = insertedQueryResultIds(ResultOutputType.PATIENT_COUNT_XML).head
dao.insertCountResult(countQueryResultId, -1L, -1L)
}
val queryStartDate = now
object MockHttpClient extends HttpClient {
override def post(input: String, url: String): HttpResponse = ???
}
val adapter: WithHiveCredentialsAdapter = makeAdapter(dao, MockHttpClient)
def getResults = doGetResults(adapter)
getResults.isInstanceOf[ErrorResponse] should be(true)
//The query shouldn't be 'done', since its status is QUEUED
dao.findResultsFor(shrineNetworkQueryId).get.count.statusType should be(QueryResult.StatusType.Queued)
//Now, calling processRequest (via getResults) should NOT cause the query to be re-retrieved from the CRC, because the query was previously queued
val result = getResults
result.isInstanceOf[ErrorResponse] should be(true)
dao.findResultsFor(shrineNetworkQueryId).get.count.statusType should be(QueryResult.StatusType.Queued)
}
def doTestProcessRequest = afterCreatingTables {
val adapter = makeAdapter(dao, MockHttpClient)
def getResults = doGetResults(adapter)
getResults match {
case errorResponse:ErrorResponse => errorResponse.problemDigest.codec should be (classOf[QueryNotFound].getName)
case x => fail(s"Got $x, not an ErrorResponse")
}
val dbQueryId = dao.insertQuery(localMasterId, shrineNetworkQueryId, authn, fooQuery, isFlagged = false, hasBeenRun = false, flagMessage = None)
getResults match {
case errorResponse:ErrorResponse => errorResponse.problemDigest.codec should be (classOf[QueryResultNotAvailable].getName)
case x => fail(s"Got $x, not an ErrorResponse")
}
import ResultOutputType._
import XmlDateHelper.now
val breakdowns = Map(
PATIENT_AGE_COUNT_XML -> I2b2ResultEnvelope(PATIENT_AGE_COUNT_XML, Map("a" -> 1L, "b" -> 2L)),
PATIENT_GENDER_COUNT_XML -> I2b2ResultEnvelope(PATIENT_GENDER_COUNT_XML, Map("x" -> 3L, "y" -> 4L)))
val obfscBreakdowns = breakdowns.mapValues(_.mapValues(_ + 1))
val startDate = now
val elapsed = 100L
val endDate = {
import XmlGcEnrichments._
import scala.concurrent.duration._
startDate + elapsed.milliseconds
}
val countResult = QueryResult(
resultId = 456L,
instanceId = instanceId,
resultType = Some(PATIENT_COUNT_XML),
setSize = setSize,
startDate = Option(startDate),
endDate = Option(endDate),
description = Some("results from node X"),
statusType = QueryResult.StatusType.Finished,
statusMessage = None,
breakdowns = breakdowns
)
val breakdownResults = breakdowns.map {
case (resultType, data) =>
countResult.withBreakdowns(Map(resultType -> data)).withResultType(resultType)
}.toSeq
val queryStartDate = now
val idsByResultType = dao.insertQueryResults(dbQueryId, countResult +: breakdownResults)
getResults.isInstanceOf[ErrorResponse] should be(true)
dao.insertCountResult(idsByResultType(PATIENT_COUNT_XML).head, setSize, obfSetSize)
dao.insertBreakdownResults(idsByResultType, breakdowns, obfscBreakdowns)
val result = getResults.asInstanceOf[R]
val Some((actualNetworkQueryId, actualQueryResult)) = extractor(result)
actualNetworkQueryId should equal(shrineNetworkQueryId)
actualQueryResult.resultType should equal(Some(PATIENT_COUNT_XML))
actualQueryResult.setSize should equal(obfSetSize)
actualQueryResult.description should be(None) //TODO: This is probably wrong
actualQueryResult.statusType should equal(QueryResult.StatusType.Finished)
actualQueryResult.statusMessage should be(None)
actualQueryResult.breakdowns should equal(obfscBreakdowns)
for {
startDate <- actualQueryResult.startDate
endDate <- actualQueryResult.endDate
} {
val actualElapsed = toMillis(endDate) - toMillis(startDate)
actualElapsed should equal(elapsed)
}
}
}
object AbstractQueryRetrievalTestCase {
val hiveCredentials = HiveCredentials("some-hive-domain", "hive-username", "hive-password", "hive-project")
val doObfuscation = true
def runQueryAdapter(dao: AdapterDao, poster: Poster): RunQueryAdapter = {
val translator = new QueryDefinitionTranslator(new ExpressionTranslator(Map("foo" -> Set("bar"))))
new RunQueryAdapter(
poster,
dao,
AbstractQueryRetrievalTestCase.hiveCredentials,
translator,
10000,
doObfuscation,
runQueriesImmediately = true,
DefaultBreakdownResultOutputTypes.toSet,
collectAdapterAudit = false
)
}
import scala.concurrent.duration._
final class BogusRequest extends ShrineRequest("fooProject", 1.second, null) {
override val requestType = null
protected override def i2b2MessageBody: NodeSeq =
override def toXml =
}
}
\ No newline at end of file
diff --git a/adapter/adapter-service/src/test/scala/net/shrine/adapter/RunQueryAdapterTest.scala b/adapter/adapter-service/src/test/scala/net/shrine/adapter/RunQueryAdapterTest.scala
index b87a6e70a..f094d5b47 100644
--- a/adapter/adapter-service/src/test/scala/net/shrine/adapter/RunQueryAdapterTest.scala
+++ b/adapter/adapter-service/src/test/scala/net/shrine/adapter/RunQueryAdapterTest.scala
@@ -1,965 +1,965 @@
package net.shrine.adapter
-import net.shrine.problem.TestProblem
+import net.shrine.problem.{ProblemSources, AbstractProblem, TestProblem}
import scala.concurrent.duration.DurationInt
import org.junit.Test
import net.shrine.util.ShouldMatchersForJUnit
import ObfuscatorTest.within3
import net.shrine.adapter.dao.AdapterDao
import net.shrine.adapter.dao.squeryl.AbstractSquerylAdapterTest
import net.shrine.adapter.translators.ExpressionTranslator
import net.shrine.adapter.translators.QueryDefinitionTranslator
import net.shrine.client.HttpClient
import net.shrine.client.HttpResponse
import net.shrine.client.Poster
import net.shrine.protocol.{HiveCredentials, AuthenticationInfo, BroadcastMessage, CrcRequest, Credential, I2b2ResultEnvelope, QueryResult, RawCrcRunQueryResponse, ReadResultRequest, ReadResultResponse, ResultOutputType, RunQueryRequest, RunQueryResponse, ErrorResponse, BaseShrineResponse, DefaultBreakdownResultOutputTypes}
import net.shrine.protocol.RawCrcRunQueryResponse.toQueryResultMap
import net.shrine.protocol.DefaultBreakdownResultOutputTypes.PATIENT_AGE_COUNT_XML
import net.shrine.protocol.ResultOutputType.PATIENT_COUNT_XML
import net.shrine.protocol.DefaultBreakdownResultOutputTypes.PATIENT_GENDER_COUNT_XML
import net.shrine.protocol.DefaultBreakdownResultOutputTypes.PATIENT_RACE_COUNT_XML
import net.shrine.protocol.query.OccuranceLimited
import net.shrine.protocol.query.Or
import net.shrine.protocol.query.QueryDefinition
import net.shrine.protocol.query.Term
import net.shrine.util.XmlDateHelper
import net.shrine.util.XmlUtil
import scala.util.Success
import net.shrine.dao.squeryl.SquerylEntryPoint
import scala.concurrent.duration.Duration
import net.shrine.adapter.dao.model.ShrineError
import net.shrine.adapter.dao.model.QueryResultRow
/**
* @author Bill Simons
* @author Clint Gilbert
* @since 4/19/11
* @see http://cbmi.med.harvard.edu
*/
final class RunQueryAdapterTest extends AbstractSquerylAdapterTest with ShouldMatchersForJUnit {
private val queryDef = QueryDefinition("foo", Term("foo"))
private val broadcastMessageId = 1234563789L
private val queryId = 123L
private val expectedNetworkQueryId = 999L
private val expectedLocalMasterId = queryId.toString
private val masterId = 99L
private val instanceId = 456L
private val resultId = 42L
private val projectId = "projectId"
private val setSize = 17L
private val xmlResultId = 98765L
private val userId = "userId"
private val groupId = "groupId"
private val topicId = "some-topic-id-123-foo"
private val topicName = "Topic Name"
private val justCounts = Set(PATIENT_COUNT_XML)
private val now = XmlDateHelper.now
private val countQueryResult = QueryResult(resultId, instanceId, Some(PATIENT_COUNT_XML), setSize, Some(now), Some(now), None, QueryResult.StatusType.Finished, None)
private val dummyBreakdownData = Map("x" -> 99L, "y" -> 42L, "z" -> 3000L)
private val hiveCredentials = HiveCredentials("some-hive-domain", "hive-username", "hive-password", "hive-project")
private val authn = AuthenticationInfo("some-domain", "username", Credential("jksafhkjaf", false))
private val adapterLockoutThreshold = 99
private val altI2b2ErrorXml = XmlUtil.stripWhitespace {
1.1
2.4
edu.harvard.i2b2.crc
1.5
i2b2 Hive
i2b2_QueryTool
0.2
i2b2 Hive
1
i2b2
Log information
DONE
Query result instance id 3126 not found
}.toString
private val otherNetworkId: Long = 12345L
@Test
def testProcessRawCrcRunQueryResponseCountQueryOnly: Unit = afterCreatingTables{
val outputTypes = Set(PATIENT_COUNT_XML)
val translator = new QueryDefinitionTranslator(new ExpressionTranslator(Map("network" -> Set("local1a", "local1b"))))
val adapter = new RunQueryAdapter(
Poster("crc-url", null),
dao,
hiveCredentials,
translator,
adapterLockoutThreshold,
doObfuscation = false,
runQueriesImmediately = true,
breakdownTypes = DefaultBreakdownResultOutputTypes.toSet,
collectAdapterAudit = false
)
val request = RunQueryRequest(projectId, 1.second, authn, expectedNetworkQueryId, Option(topicId), Option(topicName), outputTypes, queryDef)
val networkAuthn = AuthenticationInfo("some-domain", "username", Credential("sadasdasdasd", false))
val broadcastMessage = BroadcastMessage(queryId, networkAuthn, request)
val rawRunQueryResponse = RawCrcRunQueryResponse(
queryId = queryId,
createDate = XmlDateHelper.now,
userId = request.authn.username,
groupId = request.authn.domain,
requestXml = request.queryDefinition,
queryInstanceId = otherNetworkId,
singleNodeResults = toQueryResultMap(Seq(countQueryResult)))
val resp = adapter.processRawCrcRunQueryResponse(networkAuthn, request, rawRunQueryResponse).asInstanceOf[RunQueryResponse]
resp should not be (null)
//Validate the response
resp.createDate should not be(null)
resp.groupId should be(request.authn.domain)
resp.userId should be(request.authn.username)
resp.queryId should be(queryId)
resp.queryInstanceId should be(otherNetworkId)
resp.requestXml should equal(request.queryDefinition)
(countQueryResult eq resp.singleNodeResult) should be(false)
within3(resp.singleNodeResult.setSize, countQueryResult.setSize) should be(true)
resp.singleNodeResult.resultType.get should equal(PATIENT_COUNT_XML)
resp.singleNodeResult.breakdowns should equal(Map.empty)
//validate the DB
val expectedNetworkTerm = queryDef.expr.get.asInstanceOf[Term]
//We should have one row in the shrine_query table, for the query just performed
val Seq(queryRow) = list(queryRows)
{
queryRow.dateCreated should not be (null)
queryRow.domain should equal(request.authn.domain)
queryRow.name should equal(queryDef.name)
queryRow.localId should equal(expectedLocalMasterId)
queryRow.networkId should equal(expectedNetworkQueryId)
queryRow.username should equal(authn.username)
queryRow.queryDefinition.expr.get should equal(expectedNetworkTerm)
}
//We should have one row in the count_result table, with the right obfuscated value, which is within the expected amount from the original count
val Seq(countRow) = list(countResultRows)
{
countRow.creationDate should not be (null)
countRow.originalValue should equal(countQueryResult.setSize)
within3(countRow.obfuscatedValue, countRow.originalValue) should be(true)
}
}
@Test
def testProcessRawCrcRunQueryResponseCountAndBreakdownQuery: Unit = afterCreatingTables {
val allBreakdownTypes = DefaultBreakdownResultOutputTypes.toSet
val breakdownTypes = Seq(PATIENT_GENDER_COUNT_XML)
val outputTypes = Set(PATIENT_COUNT_XML) ++ breakdownTypes
val translator = new QueryDefinitionTranslator(new ExpressionTranslator(Map("network" -> Set("local1a", "local1b"))))
val request = RunQueryRequest(projectId, 1.second, authn, expectedNetworkQueryId, Option(topicId), Option(topicName), outputTypes, queryDef)
val networkAuthn = AuthenticationInfo("some-domain", "username", Credential("sadasdasdasd", false))
val broadcastMessage = BroadcastMessage(queryId, networkAuthn, request)
val breakdownQueryResults = breakdownTypes.zipWithIndex.map {
case (rt, i) =>
countQueryResult.withId(resultId + i + 1).withResultType(rt)
}
val singleNodeResults = toQueryResultMap(countQueryResult +: breakdownQueryResults)
val rawRunQueryResponse = RawCrcRunQueryResponse(
queryId = queryId,
createDate = XmlDateHelper.now,
userId = request.authn.username,
groupId = request.authn.domain,
requestXml = request.queryDefinition,
queryInstanceId = otherNetworkId,
singleNodeResults = singleNodeResults)
//Set up our mock CRC
val poster = Poster("crc-url", new HttpClient {
def post(input: String, url: String): HttpResponse = HttpResponse.ok {
(RunQueryRequest.fromI2b2String(allBreakdownTypes)(input) orElse ReadResultRequest.fromI2b2String(allBreakdownTypes)(input)).get match {
case runQueryReq: RunQueryRequest => rawRunQueryResponse.toI2b2String
case readResultReq: ReadResultRequest => ReadResultResponse(xmlResultId = 42L, metadata = breakdownQueryResults.head, data = I2b2ResultEnvelope(PATIENT_GENDER_COUNT_XML, dummyBreakdownData)).toI2b2String
case _ => sys.error(s"Unknown request: '$input'") //Fail loudly
}
}
})
val adapter = new RunQueryAdapter(
poster,
dao,
hiveCredentials,
translator,
adapterLockoutThreshold,
doObfuscation = false,
runQueriesImmediately = true,
breakdownTypes = DefaultBreakdownResultOutputTypes.toSet,
collectAdapterAudit = false
)
val resp = adapter.processRawCrcRunQueryResponse(networkAuthn, request, rawRunQueryResponse).asInstanceOf[RunQueryResponse]
resp should not be (null)
//Validate the response
resp.createDate should not be(null)
resp.groupId should be(request.authn.domain)
resp.userId should be(request.authn.username)
resp.queryId should be(queryId)
resp.queryInstanceId should be(otherNetworkId)
resp.requestXml should equal(request.queryDefinition)
(countQueryResult eq resp.singleNodeResult) should be(false)
within3(resp.singleNodeResult.setSize, countQueryResult.setSize) should be(true)
resp.singleNodeResult.resultType.get should equal(PATIENT_COUNT_XML)
resp.singleNodeResult.breakdowns.keySet should equal(Set(PATIENT_GENDER_COUNT_XML))
val breakdownEnvelope = resp.singleNodeResult.breakdowns.values.head
breakdownEnvelope.resultType should equal(PATIENT_GENDER_COUNT_XML)
breakdownEnvelope.data.keySet should equal(dummyBreakdownData.keySet)
//All breakdowns are obfuscated
for {
(key, value) <- breakdownEnvelope.data
} {
within3(value, dummyBreakdownData(key)) should be(true)
}
//validate the DB
val expectedNetworkTerm = queryDef.expr.get.asInstanceOf[Term]
//We should have one row in the shrine_query table, for the query just performed
val Seq(queryRow) = list(queryRows)
{
queryRow.dateCreated should not be (null)
queryRow.domain should equal(request.authn.domain)
queryRow.name should equal(queryDef.name)
queryRow.localId should equal(expectedLocalMasterId)
queryRow.networkId should equal(expectedNetworkQueryId)
queryRow.username should equal(authn.username)
queryRow.queryDefinition.expr.get should equal(expectedNetworkTerm)
}
//We should have one row in the count_result table, with the right obfuscated value, which is within the expected amount from the original count
val Seq(countRow) = list(countResultRows)
{
countRow.creationDate should not be (null)
countRow.originalValue should equal(countQueryResult.setSize)
within3(countRow.obfuscatedValue, countRow.originalValue) should be(true)
}
val breakdownRows @ Seq(xRow, yRow, zRow) = list(breakdownResultRows)
breakdownRows.map(_.dataKey).toSet should equal(dummyBreakdownData.keySet)
within3(xRow.obfuscatedValue, xRow.originalValue) should be(true)
xRow.originalValue should be(dummyBreakdownData(xRow.dataKey))
within3(yRow.obfuscatedValue, yRow.originalValue) should be(true)
yRow.originalValue should be(dummyBreakdownData(yRow.dataKey))
within3(zRow.obfuscatedValue, zRow.originalValue) should be(true)
zRow.originalValue should be(dummyBreakdownData(zRow.dataKey))
}
//NB: See https://open.med.harvard.edu/jira/browse/SHRINE-745
@Test
def testParseAltErrorXml {
val adapter = new RunQueryAdapter(
Poster("crc-url", null),
null,
hiveCredentials,
null,
adapterLockoutThreshold,
doObfuscation = false,
runQueriesImmediately = false,
DefaultBreakdownResultOutputTypes.toSet,
collectAdapterAudit = false
)
val resp: ErrorResponse = adapter.parseShrineErrorResponseWithFallback(altI2b2ErrorXml).asInstanceOf[ErrorResponse]
resp should not be (null)
resp.errorMessage should be("Query result instance id 3126 not found")
}
@Test
def testParseErrorXml {
val xml = {
1.1
2.4
edu.harvard.i2b2.crc
1.4
i2b2 Hive
i2b2web
1.4
i2b2 Hive
1
Demo
Log information
Message error connecting Project Management cell
admin
0
0
CRC_QRY_runQueryInstance_fromQueryDefinition
Age
0
1
0
0
1
-
2
Age
\\i2b2\i2b2\Demographics\Age\
concept_dimension
concept_path
\i2b2\Demographics\Age\
T
concept_cd
false
}.toString
val adapter = new RunQueryAdapter(
Poster("crc-url", null),
null,
hiveCredentials,
null,
adapterLockoutThreshold,
doObfuscation = false,
runQueriesImmediately = true,
DefaultBreakdownResultOutputTypes.toSet,
collectAdapterAudit = false
)
val resp = adapter.parseShrineErrorResponseWithFallback(xml).asInstanceOf[ErrorResponse]
resp should not be (null)
resp.errorMessage should not be ("")
}
@Test
def testObfuscateBreakdowns {
val breakdown1 = I2b2ResultEnvelope(PATIENT_AGE_COUNT_XML, Map.empty)
val breakdown2 = I2b2ResultEnvelope(PATIENT_GENDER_COUNT_XML, Map("foo" -> 123, "bar" -> 345))
val breakdown3 = I2b2ResultEnvelope(PATIENT_RACE_COUNT_XML, Map("x" -> 999, "y" -> 888))
val original = Map.empty ++ Seq(breakdown1, breakdown2, breakdown3).map(env => (env.resultType, env))
val obfuscated = RunQueryAdapter.obfuscateBreakdowns(original)
original.keySet should equal(obfuscated.keySet)
original.keySet.forall(resultType => original(resultType).data.keySet == obfuscated(resultType).data.keySet) should be(true)
val localTerms = Set("local1a", "local1b")
for {
(resultType, origBreakdown) <- original
mappings = Map("network" -> localTerms)
translator = new QueryDefinitionTranslator(new ExpressionTranslator(mappings))
obfscBreakdown <- obfuscated.get(resultType)
key <- origBreakdown.data.keySet
} {
(origBreakdown eq obfscBreakdown) should be(false)
ObfuscatorTest.within3(origBreakdown.data(key), obfscBreakdown.data(key)) should be(true)
}
}
@Test
def testTranslateNetworkToLocalDoesntLeakCredentialsViaException: Unit = {
val mappings = Map.empty[String, Set[String]]
val translator = new QueryDefinitionTranslator(new ExpressionTranslator(mappings))
val adapter = new RunQueryAdapter(
Poster("crc-url", MockHttpClient),
null,
null,
translator,
adapterLockoutThreshold,
doObfuscation = false,
runQueriesImmediately = true,
DefaultBreakdownResultOutputTypes.toSet,
collectAdapterAudit = false
)
val queryDefinition = QueryDefinition("foo", Term("blah"))
val authn = AuthenticationInfo("d", "u", Credential("p", false))
val req = RunQueryRequest("projectId", Duration.Inf, authn, otherNetworkId, None, None, Set.empty, queryDef)
try {
adapter.translateNetworkToLocal(req)
fail("Expected an AdapterMappingException")
} catch {
case e: AdapterMappingException => {
e.getMessage.contains(authn.rawToString) should be(false)
e.getMessage.contains(AuthenticationInfo.elided.toString) should be(true)
}
}
}
@Test
def testTranslateQueryDefinitionXml {
val localTerms = Set("local1a", "local1b")
val mappings = Map("network" -> localTerms)
val translator = new QueryDefinitionTranslator(new ExpressionTranslator(mappings))
val adapter = new RunQueryAdapter(
Poster("crc-url", MockHttpClient),
null,
null,
translator,
adapterLockoutThreshold,
doObfuscation = false,
runQueriesImmediately = true,
DefaultBreakdownResultOutputTypes.toSet,
collectAdapterAudit = false
)
val queryDefinition = QueryDefinition("10-17 years old@14:39:20", OccuranceLimited(1, Term("network")))
val newDef = adapter.conceptTranslator.translate(queryDefinition)
val expected = QueryDefinition("10-17 years old@14:39:20", Or(Term("local1a"), Term("local1b")))
newDef should equal(expected)
}
@Test
def testQueuedRegularCountQuery: Unit = afterCreatingTables {
val adapter = RunQueryAdapter(
Poster("crc-url", MockHttpClient),
dao,
null,
null,
adapterLockoutThreshold,
doObfuscation = false,
runQueriesImmediately = false,
DefaultBreakdownResultOutputTypes.toSet,
collectAdapterAudit = false
)
val networkAuthn = AuthenticationInfo("nd", "nu", Credential("np", false))
import scala.concurrent.duration._
val req = RunQueryRequest(projectId, 1.second, authn, expectedNetworkQueryId, Option(topicId), Option(topicName), Set(PATIENT_COUNT_XML), queryDef)
val broadcastMessage = BroadcastMessage(queryId, networkAuthn, req)
val resp = adapter.processRequest(broadcastMessage).asInstanceOf[RunQueryResponse]
resp.groupId should equal(networkAuthn.domain)
resp.createDate should not be (null) // :\
resp.queryId should equal(-1L)
resp.queryInstanceId should equal(-1L)
resp.requestXml should equal(queryDef)
resp.userId should equal(networkAuthn.username)
resp.singleNodeResult.breakdowns should equal(Map.empty)
resp.singleNodeResult.description.isDefined should be(true)
resp.singleNodeResult.elapsed should equal(Some(0L))
resp.singleNodeResult.endDate.isDefined should be(true)
resp.singleNodeResult.startDate.isDefined should be(true)
resp.singleNodeResult.instanceId should equal(-1L)
resp.singleNodeResult.isError should be(false)
resp.singleNodeResult.resultId should equal(-1L)
resp.singleNodeResult.resultType should be(Some(PATIENT_COUNT_XML))
resp.singleNodeResult.setSize should equal(-1L)
resp.singleNodeResult.statusMessage.isDefined should be(true)
resp.singleNodeResult.statusType should be(QueryResult.StatusType.Held)
resp.singleNodeResult.endDate.isDefined should be(true)
val Some(storedQuery) = dao.findQueryByNetworkId(expectedNetworkQueryId)
storedQuery.dateCreated should not be (null) // :\
storedQuery.domain should equal(networkAuthn.domain)
storedQuery.isFlagged should equal(false)
storedQuery.localId should equal(-1L.toString)
storedQuery.name should equal(queryDef.name)
storedQuery.networkId should equal(expectedNetworkQueryId)
storedQuery.queryDefinition should equal(queryDef)
storedQuery.username should equal(networkAuthn.username)
}
private def doTestRegularCountQuery(status: QueryResult.StatusType, count: Long) = afterCreatingTables {
require(!status.isError)
val countQueryResultToUse = countQueryResult.copy(statusType = status, setSize = count)
val outputTypes = justCounts
val resp = doQuery(outputTypes) {
import RawCrcRunQueryResponse.toQueryResultMap
RawCrcRunQueryResponse(queryId, now, userId, groupId, queryDef, instanceId, toQueryResultMap(Seq(countQueryResultToUse))).toI2b2String
}.asInstanceOf[RunQueryResponse]
doBasicRunQueryResponseTest(resp)
val firstResult = resp.results.head
resp.results should equal(Seq(firstResult))
val Some(savedQuery) = dao.findResultsFor(expectedNetworkQueryId)
savedQuery.wasRun should equal(true)
savedQuery.isFlagged should equal(false)
savedQuery.networkQueryId should equal(expectedNetworkQueryId)
savedQuery.breakdowns should equal(Nil)
savedQuery.count.creationDate should not be (null)
savedQuery.count.localId should equal(countQueryResultToUse.resultId)
//savedQuery.count.resultId should equal(resultId) TODO: REVISIT
savedQuery.count.statusType should equal(status)
if (status.isDone && !status.isError) {
savedQuery.count.data.get.startDate should not be (null)
savedQuery.count.data.get.endDate should not be (null)
savedQuery.count.data.get.originalValue should be(count)
ObfuscatorTest.within3(savedQuery.count.data.get.obfuscatedValue, count) should be(true)
} else {
savedQuery.count.data should be(None)
}
}
@Test
def testRegularCountQuery = doTestRegularCountQuery(QueryResult.StatusType.Finished, countQueryResult.setSize)
@Test
def testRegularCountQueryComesBackProcessing = doTestRegularCountQuery(QueryResult.StatusType.Processing, -1L)
@Test
def testRegularCountQueryComesBackQueued = doTestRegularCountQuery(QueryResult.StatusType.Queued, -1L)
@Test
def testRegularCountQueryComesBackError = afterCreatingTables {
- val errorQueryResult = QueryResult.errorResult(Some("some-description"), "some-status-message",TestProblem)
+ val errorQueryResult = QueryResult.errorResult(Some("some-description"), "some-status-message",TestProblem())
val outputTypes = justCounts
val resp = doQuery(outputTypes) {
import RawCrcRunQueryResponse.toQueryResultMap
RawCrcRunQueryResponse(queryId, now, userId, groupId, queryDef, instanceId, toQueryResultMap(Seq(errorQueryResult))).toI2b2String
}
doBasicRunQueryResponseTest(resp)
//TODO: Why are status and description messages from CRC dropped when unmarshalling QueryResults?
//resp.results should equal(Seq(errorQueryResult))
resp.asInstanceOf[RunQueryResponse].results.head.statusType should be(QueryResult.StatusType.Error)
dao.findResultsFor(expectedNetworkQueryId) should be(None)
val Some(savedQueryRow) = dao.findQueryByNetworkId(expectedNetworkQueryId)
val Seq(queryResultRow: QueryResultRow) = {
import SquerylEntryPoint._
implicit val breakdownTypes = DefaultBreakdownResultOutputTypes.toSet
inTransaction {
from(tables.queryResults) { row =>
where(row.queryId === savedQueryRow.id).
select(row.toQueryResultRow)
}.toSeq
}
}
val Seq(errorRow: ShrineError) = {
import SquerylEntryPoint._
inTransaction {
from(tables.errorResults) { row =>
where(row.resultId === queryResultRow.id).
select(row.toShrineError)
}.toSeq
}
}
errorRow should not be (null)
//TODO: ErrorMessage
//errorRow.message should equal(errorQueryResult.statusMessage)
}
private def doTestBreakdownsAreObfuscated(result: QueryResult): Unit = {
result.breakdowns.values.map(_.data).foreach { actualBreakdowns =>
actualBreakdowns.keySet should equal(dummyBreakdownData.keySet)
for {
breakdownName <- actualBreakdowns.keySet
} {
within3(actualBreakdowns(breakdownName), dummyBreakdownData(breakdownName)) should be(true)
}
}
}
@Test
def testGetBreakdownsWithRegularCountQuery {
val breakdowns = DefaultBreakdownResultOutputTypes.values.map(breakdownFor)
val resp = doTestGetBreakdowns(breakdowns)
val firstResult = resp.results.head
firstResult.resultType should equal(Some(PATIENT_COUNT_XML))
firstResult.setSize should equal(setSize)
firstResult.description should equal(None)
firstResult.breakdowns.keySet should equal(DefaultBreakdownResultOutputTypes.toSet)
//NB: Verify that breakdowns are obfuscated
doTestBreakdownsAreObfuscated(firstResult)
resp.results.size should equal(1)
}
@Test
def testGetBreakdownsSomeFailures {
val resultTypesExpectedToSucceed = Seq(PATIENT_AGE_COUNT_XML, PATIENT_GENDER_COUNT_XML)
val breakdowns = resultTypesExpectedToSucceed.map(breakdownFor)
val resp = doTestGetBreakdowns(breakdowns)
val firstResult = resp.results.head
firstResult.resultType should equal(Some(PATIENT_COUNT_XML))
firstResult.setSize should equal(setSize)
firstResult.description should equal(None)
firstResult.breakdowns.keySet should equal(resultTypesExpectedToSucceed.toSet)
//NB: Verify that breakdowns are obfuscated
doTestBreakdownsAreObfuscated(firstResult)
resp.results.size should equal(1)
}
@Test
def testErrorResponsesArePassedThrough: Unit = {
- val errorResponse = ErrorResponse("blarg!")
+ val errorResponse = ErrorResponse(TestProblem(summary = "blarg!"))
val resp = doQuery(Set(PATIENT_COUNT_XML)) {
errorResponse.toI2b2String
}
resp should equal(errorResponse)
}
private def breakdownFor(resultType: ResultOutputType) = I2b2ResultEnvelope(resultType, dummyBreakdownData)
private def doTestGetBreakdowns(successfulBreakdowns: Seq[I2b2ResultEnvelope]): RunQueryResponse = {
val outputTypes = justCounts ++ DefaultBreakdownResultOutputTypes.toSet
val resp = doQueryThatReturnsSpecifiedBreakdowns(outputTypes, successfulBreakdowns)
doBasicRunQueryResponseTest(resp)
resp
}
private def doBasicRunQueryResponseTest(r: BaseShrineResponse) {
val resp = r.asInstanceOf[RunQueryResponse]
resp.createDate should equal(now)
resp.groupId should equal(groupId)
resp.queryId should equal(queryId)
resp.queryInstanceId should equal(instanceId)
resp.queryName should equal(queryDef.name)
resp.requestXml should equal(queryDef)
}
private def doQueryThatReturnsSpecifiedBreakdowns(outputTypes: Set[ResultOutputType], successfulBreakdowns: Seq[I2b2ResultEnvelope]): RunQueryResponse = afterCreatingTablesReturn {
val breakdownQueryResults = DefaultBreakdownResultOutputTypes.values.zipWithIndex.map {
case (rt, i) =>
countQueryResult.withId(resultId + i + 1).withResultType(rt)
}
//Need this rigamarole to ensure that resultIds line up such that the type of breakdown the adapter asks for
//(PATIENT_AGE_COUNT_XML, etc) is what the mock HttpClient actually returns. Here, we build up maps of QueryResults
//and I2b2ResultEnvelopes, keyed on resultIds generated in the previous expression, to use to look up values to use
//to build ReadResultResponses
val successfulBreakdownsByType = successfulBreakdowns.map(e => e.resultType -> e).toMap
val successfulBreakdownTypes = successfulBreakdownsByType.keySet
val breakdownQueryResultsByResultId = breakdownQueryResults.collect { case qr if successfulBreakdownTypes(qr.resultType.get) => qr.resultId -> qr }.toMap
val breakdownsToBeReturnedByResultId = breakdownQueryResultsByResultId.map {
case (resultId, queryResult) => (resultId, successfulBreakdownsByType(queryResult.resultType.get))
}
val expectedLocalTerm = Term("bar")
val httpClient = new HttpClient {
override def post(input: String, url: String): HttpResponse = {
val resp = CrcRequest.fromI2b2String(DefaultBreakdownResultOutputTypes.toSet)(input) match {
case Success(req: RunQueryRequest) => {
//NB: Terms should be translated
req.queryDefinition.expr.get should equal(expectedLocalTerm)
//Credentials should be "translated"
req.authn.username should equal(hiveCredentials.username)
req.authn.domain should equal(hiveCredentials.domain)
//I2b2 Project ID should be translated
req.projectId should equal(hiveCredentials.projectId)
val queryResultMap = RawCrcRunQueryResponse.toQueryResultMap(countQueryResult +: breakdownQueryResults)
RawCrcRunQueryResponse(queryId, now, "userId", "groupId", queryDef, instanceId, queryResultMap)
}
//NB: return a ReadResultResponse with new breakdown data each time, but will throw if the asked-for breakdown
//is not one of the ones passed to the enclosing method, simulating an error calling the CRC
case Success(req: ReadResultRequest) => {
val resultId = req.localResultId.toLong
ReadResultResponse(xmlResultId, breakdownQueryResultsByResultId(resultId), breakdownsToBeReturnedByResultId(resultId))
}
case _ => ??? //fail loudly
}
HttpResponse.ok(resp.toI2b2String)
}
}
val result = doQuery(outputTypes, dao, httpClient)
validateDb(successfulBreakdowns, breakdownQueryResultsByResultId)
result.asInstanceOf[RunQueryResponse]
}
private def validateDb(breakdownsReturned: Seq[I2b2ResultEnvelope], breakdownQueryResultsByResultId: Map[Long, QueryResult]) {
val expectedNetworkTerm = Term("foo")
//We should have one row in the shrine_query table, for the query just performed
val queryRow = first(queryRows)
{
queryRow.dateCreated should not be (null)
queryRow.domain should equal(authn.domain)
queryRow.name should equal(queryDef.name)
queryRow.localId should equal(expectedLocalMasterId)
queryRow.networkId should equal(expectedNetworkQueryId)
queryRow.username should equal(authn.username)
queryRow.queryDefinition.expr.get should equal(expectedNetworkTerm)
}
list(queryRows).size should equal(1)
//We should have one row in the count_result table, with the right obfuscated value, which is within the expected amount from the original count
val countRow = first(countResultRows)
{
countRow.creationDate should not be (null)
countRow.originalValue should equal(countQueryResult.setSize)
within3(countRow.obfuscatedValue, countQueryResult.setSize) should be(true)
within3(countRow.obfuscatedValue, countRow.originalValue) should be(true)
}
list(countResultRows).size should equal(1)
//We should have 5 rows in the query_result table, one for the count result and one for each of the 4 requested breakdown types
val queryResults = list(queryResultRows)
{
val countQueryResultRow = queryResults.find(_.resultType == PATIENT_COUNT_XML).get
countQueryResultRow.localId should equal(countQueryResult.resultId)
countQueryResultRow.queryId should equal(queryRow.id)
val resultIdsByResultType = breakdownQueryResultsByResultId.map { case (resultId, queryResult) => queryResult.resultType.get -> resultId }.toMap
for (breakdownType <- DefaultBreakdownResultOutputTypes.values) {
val breakdownQueryResultRow = queryResults.find(_.resultType == breakdownType).get
breakdownQueryResultRow.queryId should equal(queryRow.id)
//We'll have a result id if this breakdown type didn't fail
if (resultIdsByResultType.contains(breakdownQueryResultRow.resultType)) {
breakdownQueryResultRow.localId should equal(resultIdsByResultType(breakdownQueryResultRow.resultType))
}
}
}
queryResults.size should equal(5)
val returnedBreakdownTypes = breakdownsReturned.map(_.resultType).toSet
val notReturnedBreakdownTypes = DefaultBreakdownResultOutputTypes.toSet -- returnedBreakdownTypes
val errorResults = list(errorResultRows)
//We should have a row in the error_result table for each breakdown that COULD NOT be retrieved
{
for {
queryResult <- queryResults
if notReturnedBreakdownTypes.contains(queryResult.resultType)
resultType = queryResult.resultType
resultId = queryResult.id
} {
errorResults.find(_.resultId == resultId).isDefined should be(true)
}
}
errorResults.size should equal(notReturnedBreakdownTypes.size)
//We should have properly-obfuscated rows in the breakdown_result table for each of the breakdown types that COULD be retrieved
val breakdownResults = list(breakdownResultRows)
val bdrs = breakdownResults.toIndexedSeq
{
for {
queryResult <- queryResults
if returnedBreakdownTypes.contains(queryResult.resultType)
resultType = queryResult.resultType
resultId = queryResult.id
} {
//Find all the rows for a particular breakdown type
val rowsWithType = breakdownResults.filter(_.resultId == resultId)
//Combining the rows should give the expected dummy data
rowsWithType.map(row => row.dataKey -> row.originalValue).toMap should equal(dummyBreakdownData)
for (breakdownRow <- rowsWithType) {
within3(breakdownRow.obfuscatedValue, dummyBreakdownData(breakdownRow.dataKey)) should be(true)
}
}
}
}
private def doQuery(outputTypes: Set[ResultOutputType])(i2b2XmlToReturn: => String): BaseShrineResponse = {
doQuery(outputTypes, dao, MockHttpClient(i2b2XmlToReturn))
}
private def doQuery(outputTypes: Set[ResultOutputType], adapterDao: AdapterDao, httpClient: HttpClient): BaseShrineResponse = {
val translator = new QueryDefinitionTranslator(new ExpressionTranslator(Map("foo" -> Set("bar"))))
//NB: Don't obfuscate, for simpler testing
val adapter = new RunQueryAdapter(
Poster("crc-url", httpClient),
adapterDao,
hiveCredentials,
translator,
adapterLockoutThreshold,
doObfuscation = false,
runQueriesImmediately = true,
DefaultBreakdownResultOutputTypes.toSet,
collectAdapterAudit = false
)
import scala.concurrent.duration._
val req = RunQueryRequest(projectId, 1.second, authn, expectedNetworkQueryId, Option(topicId), Option(topicName), outputTypes, queryDef)
val networkAuthn = AuthenticationInfo("some-domain", "username", Credential("sadasdasdasd", false))
val broadcastMessage = BroadcastMessage(queryId, networkAuthn, req)
adapter.processRequest(broadcastMessage)
}
}
\ No newline at end of file
diff --git a/adapter/adapter-service/src/test/scala/net/shrine/adapter/dao/model/ShrineErrorTest.scala b/adapter/adapter-service/src/test/scala/net/shrine/adapter/dao/model/ShrineErrorTest.scala
index ab7c7305b..49182a56e 100644
--- a/adapter/adapter-service/src/test/scala/net/shrine/adapter/dao/model/ShrineErrorTest.scala
+++ b/adapter/adapter-service/src/test/scala/net/shrine/adapter/dao/model/ShrineErrorTest.scala
@@ -1,20 +1,20 @@
package net.shrine.adapter.dao.model
import net.shrine.util.ShouldMatchersForJUnit
import net.shrine.problem.TestProblem
import net.shrine.protocol.QueryResult
/**
* @author clint
* @since Nov 1, 2012
*/
final class ShrineErrorTest extends ShouldMatchersForJUnit {
def testToQueryResult() {
val message = "something broke"
- val testProblem = TestProblem
+ val testProblem = TestProblem()
val tpd = testProblem.toDigest
val error = ShrineError(1, 123, message,tpd.codec,tpd.stampText,tpd.summary,tpd.description,tpd.detailsXml)
- error.toQueryResult should equal(QueryResult.errorResult(Some(message), QueryResult.StatusType.Error.name,TestProblem))
+ error.toQueryResult should equal(QueryResult.errorResult(Some(message), QueryResult.StatusType.Error.name,testProblem))
}
}
\ No newline at end of file
diff --git a/adapter/adapter-service/src/test/scala/net/shrine/adapter/dao/model/ShrineQueryResultTest.scala b/adapter/adapter-service/src/test/scala/net/shrine/adapter/dao/model/ShrineQueryResultTest.scala
index 57af254f7..de860b50f 100644
--- a/adapter/adapter-service/src/test/scala/net/shrine/adapter/dao/model/ShrineQueryResultTest.scala
+++ b/adapter/adapter-service/src/test/scala/net/shrine/adapter/dao/model/ShrineQueryResultTest.scala
@@ -1,96 +1,96 @@
package net.shrine.adapter.dao.model
import net.shrine.problem.TestProblem
import net.shrine.util.ShouldMatchersForJUnit
import org.junit.Test
import net.shrine.protocol.ResultOutputType
import net.shrine.protocol.QueryResult.StatusType
import net.shrine.util.XmlDateHelper
import net.shrine.protocol.QueryResult
import net.shrine.protocol.I2b2ResultEnvelope
import net.shrine.protocol.query.{QueryDefinition, Term}
import net.shrine.protocol.DefaultBreakdownResultOutputTypes
/**
* @author clint
* @since Nov 1, 2012
*/
final class ShrineQueryResultTest extends ShouldMatchersForJUnit {
import ResultOutputType._
import DefaultBreakdownResultOutputTypes._
private val queryId = 999
private def someId = scala.util.Random.nextInt
private def queryResultRow(resultType: ResultOutputType) = QueryResultRow(
someId,
someId.toLong,
queryId,
resultType,
(if (resultType.isError) StatusType.Error else StatusType.Finished),
(if (resultType.isError) None else Some(100)),
XmlDateHelper.now)
private val countQueryResultRow = queryResultRow(PATIENT_COUNT_XML)
private val breakdownQueryResultRow1 = queryResultRow(PATIENT_AGE_COUNT_XML)
private val breakdownQueryResultRow2 = queryResultRow(PATIENT_GENDER_COUNT_XML)
private val errorQueryResultRow1 = queryResultRow(ERROR)
private val errorQueryResultRow2 = queryResultRow(ERROR)
private val topicId = "some-topic-id"
private val flagMessage = Some("alksjdkalsjdalsjd")
private val queryName = "some-query"
private val queryExpr = Term("foo")
private val queryDefinition = QueryDefinition(queryName,queryExpr)
private val queryRow = ShrineQuery(123, "48573498739845", 392874L, queryName, "some-user", "some-domain", XmlDateHelper.now, isFlagged = true, flagMessage = flagMessage,queryDefinition = queryDefinition)
private val resultRows = Seq(countQueryResultRow, breakdownQueryResultRow1, breakdownQueryResultRow2, errorQueryResultRow1, errorQueryResultRow2)
private val countRow = CountRow(someId, countQueryResultRow.id, 99, 100, XmlDateHelper.now)
private val breakdownRows = Map(
PATIENT_AGE_COUNT_XML -> Seq(BreakdownResultRow(someId, breakdownQueryResultRow1.id, "x", 1, 2), BreakdownResultRow(someId, breakdownQueryResultRow1.id, "y", 2, 3)),
PATIENT_GENDER_COUNT_XML -> Seq(BreakdownResultRow(someId, breakdownQueryResultRow2.id, "a", 9, 10), BreakdownResultRow(someId, breakdownQueryResultRow2.id, "b", 10, 11)))
- private val pd = TestProblem.toDigest
+ private val pd = TestProblem().toDigest
private val errorRows = Seq(ShrineError(someId, errorQueryResultRow1.id, "foo", pd.codec,pd.stampText,pd.summary,pd.description,pd.detailsXml), ShrineError(someId, errorQueryResultRow2.id, "bar", pd.codec,pd.stampText,pd.summary,pd.description,pd.detailsXml))
@Test
def testToQueryResults {
val Some(shrineQueryResult) = ShrineQueryResult.fromRows(queryRow, resultRows, countRow, breakdownRows, errorRows)
for (doObfuscation <- Seq(true, false)) {
def obfuscate(i: Int) = if (doObfuscation) i + 1 else i
val expected = Count.fromRows(countQueryResultRow, countRow).toQueryResult.map(_.withBreakdowns(Map(
PATIENT_AGE_COUNT_XML -> I2b2ResultEnvelope(PATIENT_AGE_COUNT_XML, Map("x" -> obfuscate(1), "y" -> obfuscate(2))),
PATIENT_GENDER_COUNT_XML -> I2b2ResultEnvelope(PATIENT_GENDER_COUNT_XML, Map("a" -> obfuscate(9), "b" -> obfuscate(10))))))
shrineQueryResult.toQueryResults(doObfuscation) should equal(expected)
}
}
@Test
def testFromRows {
ShrineQueryResult.fromRows(null, Nil, countRow, breakdownRows, errorRows) should be(None)
val Some(shrineQueryResult) = ShrineQueryResult.fromRows(queryRow, resultRows, countRow, breakdownRows, errorRows)
shrineQueryResult.isFlagged should be(queryRow.isFlagged)
shrineQueryResult.flagMessage should be(flagMessage)
shrineQueryResult.count should equal(Count.fromRows(countQueryResultRow, countRow))
shrineQueryResult.errors should equal(errorRows)
shrineQueryResult.breakdowns.toSet should equal(Set(
Breakdown(breakdownQueryResultRow1.id, breakdownQueryResultRow1.localId, PATIENT_AGE_COUNT_XML, Map("x" -> ObfuscatedPair(1, 2), "y" -> ObfuscatedPair(2, 3))),
Breakdown(breakdownQueryResultRow2.id, breakdownQueryResultRow2.localId, PATIENT_GENDER_COUNT_XML, Map("a" -> ObfuscatedPair(9, 10), "b" -> ObfuscatedPair(10, 11)))))
}
}
\ No newline at end of file
diff --git a/adapter/adapter-service/src/test/scala/net/shrine/adapter/dao/squeryl/SquerylAdapterDaoTest.scala b/adapter/adapter-service/src/test/scala/net/shrine/adapter/dao/squeryl/SquerylAdapterDaoTest.scala
index 07d7c184e..b882d394b 100644
--- a/adapter/adapter-service/src/test/scala/net/shrine/adapter/dao/squeryl/SquerylAdapterDaoTest.scala
+++ b/adapter/adapter-service/src/test/scala/net/shrine/adapter/dao/squeryl/SquerylAdapterDaoTest.scala
@@ -1,669 +1,669 @@
package net.shrine.adapter.dao.squeryl
import net.shrine.problem.TestProblem
import net.shrine.util.ShouldMatchersForJUnit
import net.shrine.protocol.AuthenticationInfo
import net.shrine.protocol.query.QueryDefinition
import net.shrine.protocol.Credential
import net.shrine.util.XmlDateHelper
import net.shrine.protocol.query.Term
import net.shrine.protocol.ResultOutputType
import net.shrine.protocol.I2b2ResultEnvelope
import net.shrine.protocol.QueryResult
import net.shrine.protocol.RawCrcRunQueryResponse
import org.junit.Test
import net.shrine.adapter.dao.model.ShrineQuery
import net.shrine.adapter.dao.model.ShrineQueryResult
import net.shrine.adapter.dao.model.ObfuscatedPair
import net.shrine.adapter.dao.model.QueryResultRow
import net.shrine.protocol.DefaultBreakdownResultOutputTypes
import net.shrine.adapter.dao.model.squeryl.SquerylShrineQuery
import net.shrine.dao.DateHelpers
/**
* @author clint
* @since May 24, 2013
*/
final class SquerylAdapterDaoTest extends AbstractSquerylAdapterTest with ShouldMatchersForJUnit {
private val authn = AuthenticationInfo("some-domain", "some-user", Credential("laskhdakslhd", false))
private val queryDef1 = QueryDefinition("foo", Term("blarg"))
private def now = Option(XmlDateHelper.now)
import ResultOutputType._
import DefaultBreakdownResultOutputTypes._
private val topicId = "some-topic-id"
private val count = 999L
private val resultId = 1L
private val instanceId = 2L
private val desc = Some("xyz")
private val message1 = "something bad happened"
private val message2 = "blah blah blah"
private val onlyAgeBreakdown = Map(PATIENT_AGE_COUNT_XML -> I2b2ResultEnvelope(PATIENT_AGE_COUNT_XML, Map("x" -> 1, "y" -> 2)))
private val onlyGenderBreakdown = Map(PATIENT_GENDER_COUNT_XML -> I2b2ResultEnvelope(PATIENT_GENDER_COUNT_XML, Map("a" -> 123, "b" -> 456)))
private val breakdownsByType = onlyAgeBreakdown ++ onlyGenderBreakdown
private val networkQueryId1 = 123L
private val networkQueryId2 = 456L
private val networkQueryId3 = 999L
private val masterId1 = "abc"
private val masterId2 = "def"
private val masterId3 = "ghi"
private val countQueryResult = QueryResult(resultId, instanceId, Some(PATIENT_COUNT_XML), count, now, now, desc, QueryResult.StatusType.Finished, None)
- private val errorQueryResult1 = QueryResult.errorResult(desc, message1,TestProblem)
- private val errorQueryResult2 = QueryResult.errorResult(desc, message2,TestProblem)
+ private val errorQueryResult1 = QueryResult.errorResult(desc, message1,TestProblem())
+ private val errorQueryResult2 = QueryResult.errorResult(desc, message2,TestProblem())
private val breakdownQueryResult1 = QueryResult(resultId, instanceId, Some(PATIENT_AGE_COUNT_XML), countQueryResult.setSize, now, now, desc, QueryResult.StatusType.Finished, None, breakdowns = onlyAgeBreakdown)
private val breakdownQueryResult2 = QueryResult(resultId, instanceId, Some(PATIENT_GENDER_COUNT_XML), countQueryResult.setSize, now, now, desc, QueryResult.StatusType.Finished, None, breakdowns = onlyGenderBreakdown)
import RawCrcRunQueryResponse.toQueryResultMap
private val countRunQueryResponse = RawCrcRunQueryResponse(networkQueryId1, now.get, authn.username, authn.domain, queryDef1, instanceId, toQueryResultMap(Seq(countQueryResult)))
private val onlyErrorsRunQueryResponse = countRunQueryResponse.withResults(Seq(errorQueryResult1, errorQueryResult2))
private val countAndBreakdownsRunQueryResponse = countRunQueryResponse.withResults(Seq(countQueryResult, breakdownQueryResult1, breakdownQueryResult2))
private val onlyBreakdownsRunQueryResponse = countRunQueryResponse.withResults(Seq(breakdownQueryResult1, breakdownQueryResult2))
@Test
def testFindQueryByNetworkIdNullQueryDefNonNullQueryExpr: Unit = afterCreatingTables {
val id = 123
val localId = "localId"
val networkQueryId = 42L
val queryName = "some-query"
val user = "u"
val domain = "d"
val expr = Term("""\\FOO\BAR\BAZ""")
val dateCreated = XmlDateHelper.now
val isFlagged = true
val flagMessage = Some("fm")
val hasBeenRun = true
val squerylShrineQuery = SquerylShrineQuery(
id,
localId,
networkQueryId,
queryName,
user,
domain,
Some(expr.toXmlString),
DateHelpers.toTimestamp(dateCreated),
isFlagged,
flagMessage,
hasBeenRun,
queryXml = None)
tables.shrineQueries.insert(squerylShrineQuery)
val shrineQuery = squerylShrineQuery.toShrineQuery
shrineQuery.dateCreated should equal(dateCreated)
shrineQuery.domain should equal(domain)
shrineQuery.username should equal(user)
shrineQuery.flagMessage should equal(flagMessage)
shrineQuery.id should equal(1)
shrineQuery.isFlagged should equal(isFlagged)
shrineQuery.localId should equal(localId)
shrineQuery.name should equal(queryName)
shrineQuery.networkId should equal(networkQueryId)
shrineQuery.queryDefinition should equal(QueryDefinition(queryName, expr))
val fromDb = dao.findQueryByNetworkId(networkQueryId).get
fromDb should equal(shrineQuery)
}
@Test
def testFindPreviousQueries = afterCreatingTables {
dao.findRecentQueries(0) should equal(Nil)
dao.findRecentQueries(1) should equal(Nil)
dao.insertQuery(masterId1, networkQueryId1, authn, queryDef1, isFlagged = false, hasBeenRun = true, flagMessage = None)
//Make next query happen 10 milliseconds later, so we can distinguish it from the one we just inserted
//(java.sql.Timestamps have 1ms resolution, it appears?)
Thread.sleep(10)
dao.findRecentQueries(0) should equal(Nil)
{
val Seq(query) = dao.findRecentQueries(1)
query.networkId should equal(networkQueryId1)
}
dao.insertQuery(masterId2, networkQueryId2, authn, queryDef1, isFlagged = false, hasBeenRun = true, flagMessage = None)
//Make next query happen 10 milliseconds later, so we can distinguish it from the one we just inserted
//(java.sql.Timestamps, or perhaps XmlGregorianCalendars, have 1ms resolution?)
Thread.sleep(10)
dao.insertQuery(masterId3, networkQueryId3, authn, queryDef1, isFlagged = false, hasBeenRun = true, flagMessage = None)
//Should come back newest-queries-first
dao.findRecentQueries(2).map(_.networkId) should equal(Seq(networkQueryId3, networkQueryId2))
}
@Test
def testDeleteQuery = afterCreatingTables {
//A RunQueryResponse with all types of QueryResults: count, breakdown, and error
val response = countRunQueryResponse.withResults(Seq(countQueryResult, breakdownQueryResult1, breakdownQueryResult2, errorQueryResult1, errorQueryResult2))
doTestFindResultsFor(response) { resultIdsByType =>
insertCount(resultIdsByType)
insertErrors(resultIdsByType)
insertBreakdowns(resultIdsByType, breakdownsByType)
} {
(resultIdsByType, resultOption) =>
val Some(result) = resultOption
validateCount(resultIdsByType, result)
validateBreakdowns(result)
validateErrors(result)
}
dao.deleteQuery(networkQueryId1)
dao.findQueryByNetworkId(networkQueryId1) should be(None)
}
@Test
def testRenameQuery = afterCreatingTables {
dao.insertQuery(masterId1, networkQueryId1, authn, queryDef1, isFlagged = false, hasBeenRun = true, flagMessage = None)
{
val Some(query) = dao.findQueryByNetworkId(networkQueryId1)
query.name should equal(queryDef1.name)
}
val newName = "zuh"
dao.renameQuery(networkQueryId1, newName)
val Some(renamedQuery) = dao.findQueryByNetworkId(networkQueryId1)
renamedQuery.name should equal(newName)
renamedQuery.id should be(1)
renamedQuery.networkId should equal(networkQueryId1)
renamedQuery.username should equal(authn.username)
renamedQuery.domain should equal(authn.domain)
renamedQuery.dateCreated should not be (null)
renamedQuery.queryDefinition.name should not equal(queryDef1.name)
renamedQuery.queryDefinition.expr should equal(queryDef1.expr)
renamedQuery.queryDefinition.timing should equal(queryDef1.timing)
renamedQuery.queryDefinition.id should equal(queryDef1.id)
renamedQuery.queryDefinition.queryType should equal(queryDef1.queryType)
renamedQuery.queryDefinition.constraints should equal(queryDef1.constraints)
renamedQuery.queryDefinition.subQueries should equal(queryDef1.subQueries)
renamedQuery.isFlagged should be(false)
renamedQuery.queryDefinition should not equal(queryDef1)
}
@Test
def testFlagQuery = afterCreatingTables {
dao.insertQuery(masterId1, networkQueryId1, authn, queryDef1, isFlagged = false, hasBeenRun = true, flagMessage = None)
{
val Some(query) = dao.findQueryByNetworkId(networkQueryId1)
query.isFlagged should be(false)
}
dao.flagQuery(networkQueryId1, None)
{
val Some(flaggedQuery) = dao.findQueryByNetworkId(networkQueryId1)
flaggedQuery.isFlagged should be(true)
flaggedQuery.flagMessage should be(None)
}
val message = "askldjjkalshd"
dao.flagQuery(networkQueryId1, Some(message))
{
val Some(flaggedQuery) = dao.findQueryByNetworkId(networkQueryId1)
flaggedQuery.isFlagged should be(true)
flaggedQuery.flagMessage should be(Some(message))
}
}
@Test
def testUnFlagQuery = afterCreatingTables {
dao.insertQuery(masterId1, networkQueryId1, authn, queryDef1, isFlagged = false, hasBeenRun = true, flagMessage = None)
{
val Some(query) = dao.findQueryByNetworkId(networkQueryId1)
query.isFlagged should be(false)
}
val message = "askdljasd"
dao.flagQuery(networkQueryId1, Some(message))
val Some(flaggedQuery) = dao.findQueryByNetworkId(networkQueryId1)
flaggedQuery.isFlagged should be(true)
flaggedQuery.flagMessage should be(Some(message))
dao.unFlagQuery(networkQueryId1)
val Some(unFlaggedQuery) = dao.findQueryByNetworkId(networkQueryId1)
unFlaggedQuery.isFlagged should be(false)
unFlaggedQuery.flagMessage should be(None)
}
@Test
def testInsertQueryAndFindQueryByNetworkId = afterCreatingTables {
dao.findQueryByNetworkId(networkQueryId1) should be(None)
dao.insertQuery(masterId1, networkQueryId1, authn, queryDef1, isFlagged = false, hasBeenRun = true, flagMessage = None)
{
val Some(ShrineQuery(id, localMasterId, actualNetworkId, name, username, domain, dateCreated, isFlagged, flagMessage,queryDef)) = dao.findQueryByNetworkId(networkQueryId1)
id should be(1)
localMasterId should equal(masterId1)
actualNetworkId should equal(networkQueryId1)
name should equal(queryDef.name)
username should equal(authn.username)
domain should equal(authn.domain)
dateCreated should not be (null) //NB: Don't compare, to avoid off-by-a-few errors :/
isFlagged should be(false)
queryDef should be(queryDef1)
}
//Inserting a query with the same values should be allowed, it should just create a new row with a new id
dao.insertQuery(masterId1, networkQueryId1, authn, queryDef1, isFlagged = false, hasBeenRun = true, flagMessage = None)
{
//However, the first shrine_query row with the passed networkQueryId should be returned, not the one we just inserted
val Some(ShrineQuery(id, localMasterId, actualNetworkId, name, username, domain, dateCreated, isFlagged, flagMessage,queryDef)) = dao.findQueryByNetworkId(networkQueryId1)
id should be(1)
localMasterId should equal(masterId1)
actualNetworkId should equal(networkQueryId1)
username should equal(authn.username)
domain should equal(authn.domain)
dateCreated should not be (null) //NB: Don't compare, to avoid off-by-a-few errors :/
queryDef should equal(queryDef1)
isFlagged should be(false)
}
}
@Test
def testFindQueriesByUserAndDomain: Unit = afterCreatingTables {
dao.findQueriesByUserAndDomain("", "", 50) should equal(Nil)
dao.insertQuery(masterId1, networkQueryId1, authn, queryDef1, isFlagged = false, hasBeenRun = true, flagMessage = None)
//Make next query happen 10 milliseconds later, so we can distinguish it from the one we just inserted
//(java.sql.Timestamps have 1ms resolution, it appears?)
Thread.sleep(10)
dao.insertQuery(masterId2, networkQueryId2, authn, queryDef1, isFlagged = false, hasBeenRun = true, flagMessage = None)
dao.findQueriesByUserAndDomain("", "", 50) should equal(Nil)
val Seq(foundQuery1, foundQuery2) = dao.findQueriesByUserAndDomain(authn.domain, authn.username, 50)
foundQuery1.domain should equal(authn.domain)
foundQuery1.username should equal(authn.username)
foundQuery1.localId should equal(masterId2)
foundQuery1.networkId should equal(networkQueryId2)
foundQuery1.queryDefinition should equal(queryDef1)
foundQuery2.domain should equal(authn.domain)
foundQuery2.username should equal(authn.username)
foundQuery2.localId should equal(masterId1)
foundQuery2.networkId should equal(networkQueryId1)
foundQuery2.queryDefinition should equal(queryDef1)
val Seq(foundQuery) = dao.findQueriesByUserAndDomain(authn.domain, authn.username, 1)
foundQuery should equal(foundQuery1)
}
@Test
def testInsertQuery: Unit = {
def doTestInsertQuery(flagged: Boolean, run: Boolean): Unit = afterCreatingTables {
val ids = for (i <- 1 to 2) yield dao.insertQuery(masterId1, networkQueryId1, authn, queryDef1, isFlagged = flagged, hasBeenRun = run, flagMessage = None)
ids should equal(Seq(1, 2))
def testRow(r: ShrineQuery) {
r.localId should equal(masterId1)
r.networkId should equal(networkQueryId1)
r.dateCreated should not be (null) // :/
r.domain should equal(authn.domain)
r.username should equal(authn.username)
r.queryDefinition should equal(queryDef1)
r.isFlagged should equal(flagged)
}
val rows = list(queryRows)
val Seq(row1, row2) = rows
row1.id should be(1)
row2.id should be(2)
rows.foreach(testRow)
}
doTestInsertQuery(true, true)
doTestInsertQuery(true, false)
doTestInsertQuery(false, true)
doTestInsertQuery(false, false)
}
@Test
def testInsertQueryResultsOnlyCount = afterCreatingTables {
intercept[Exception] {
//Should fail due to foreign key constraint
dao.insertQueryResults(-1, countRunQueryResponse.results)
}
val (resultIdsByType, resultRows) = doInsertQueryResultsTest(countRunQueryResponse)
val Seq(resultRow) = resultRows
resultRow.resultType should equal(PATIENT_COUNT_XML)
resultRow.status should equal(QueryResult.StatusType.Finished)
resultIdsByType should equal(Map(PATIENT_COUNT_XML -> Seq(resultRow.id)))
}
@Test
def testInsertQueryResultsOnlyErrors = afterCreatingTables {
val (resultIdsByType, resultRows) = doInsertQueryResultsTest(onlyErrorsRunQueryResponse)
resultRows.foreach { resultRow =>
resultRow.elapsed should be(None)
resultRow.resultType should equal(ERROR)
resultRow.status should equal(QueryResult.StatusType.Error)
}
}
@Test
def testInsertQueryResultsNoErrorsOneCountSomeBreakdowns = afterCreatingTables {
val (resultIdsByType, resultRows) = doInsertQueryResultsTest(countAndBreakdownsRunQueryResponse)
resultIdsByType.keySet should equal(Set(PATIENT_COUNT_XML, PATIENT_AGE_COUNT_XML, PATIENT_GENDER_COUNT_XML))
resultIdsByType.values.forall(_.size == 1) should be(true)
val countResultRow = resultRows.filter(_.resultType == PATIENT_COUNT_XML).head
countResultRow.resultType should equal(PATIENT_COUNT_XML)
resultRows.filter(row => Set(PATIENT_AGE_COUNT_XML, PATIENT_GENDER_COUNT_XML).contains(row.resultType)).size should be(2)
resultRows.foreach { resultRow =>
resultRow.elapsed should not be (None)
resultRow.status should equal(QueryResult.StatusType.Finished)
}
}
private def doInsertQueryResultsTest(response: RawCrcRunQueryResponse): (Map[ResultOutputType, Seq[Int]], Seq[QueryResultRow]) = {
list(queryResultRows).isEmpty should be(true)
val queryId = dao.insertQuery(masterId1, networkQueryId1, authn, queryDef1, isFlagged = false, hasBeenRun = true, flagMessage = None)
val resultIdsByType = dao.insertQueryResults(queryId, response.results)
val resultRows = list(queryResultRows)
resultRows.foreach { resultRow =>
resultRow.elapsed should not be (null)
resultRow.lastUpdated should not be (null)
resultRow.queryId should equal(queryId)
}
list(errorResultRows).isEmpty should be(true)
list(countResultRows).isEmpty should be(true)
list(breakdownResultRows).isEmpty should be(true)
(resultIdsByType, resultRows)
}
@Test
def testInsertCountResult = afterCreatingTables {
val queryId = dao.insertQuery(masterId1, networkQueryId1, authn, queryDef1, isFlagged = false, hasBeenRun = true, flagMessage = None)
val response = RawCrcRunQueryResponse(networkQueryId1, now.get, authn.username, authn.domain, queryDef1, instanceId, toQueryResultMap(Seq(countQueryResult)))
val resultIdsByType = dao.insertQueryResults(queryId, response.results)
val Seq(resultRow) = list(queryResultRows)
list(countResultRows).isEmpty should be(true)
dao.insertCountResult(resultRow.id, countQueryResult.setSize, countQueryResult.setSize + 2)
val Seq(countResultRow) = list(countResultRows)
countResultRow.creationDate should not be (null)
countResultRow.obfuscatedValue should equal(countQueryResult.setSize + 2)
countResultRow.originalValue should equal(countQueryResult.setSize)
countResultRow.resultId should equal(resultRow.id)
intercept[Exception] {
//Should fail due to foreign key constraint
dao.insertCountResult(-12345, countQueryResult.setSize, countQueryResult.setSize + 2)
}
}
@Test
def testInsertBreakdownResults = afterCreatingTables {
val (resultIdsByType, resultRows) = doInsertQueryResultsTest(onlyBreakdownsRunQueryResponse)
resultIdsByType.keySet should equal(Set(PATIENT_AGE_COUNT_XML, PATIENT_GENDER_COUNT_XML))
resultIdsByType.values.forall(_.size == 1) should be(true)
val Seq(breakdownResultRow1, breakdownResultRow2) = resultRows
dao.insertBreakdownResults(resultIdsByType, breakdownsByType, breakdownsByType.mapValues(_.mapValues(_ + 1)))
val ageBreakdownRows = list(breakdownResultRows).filter(_.resultId == resultIdsByType(PATIENT_AGE_COUNT_XML).head)
val genderBreakdownRows = list(breakdownResultRows).filter(_.resultId == resultIdsByType(PATIENT_GENDER_COUNT_XML).head)
{
val ageRowsByName = ageBreakdownRows.map(row => (row.dataKey, row)).toMap
ageRowsByName("x").originalValue should equal(1)
ageRowsByName("y").originalValue should equal(2)
ageRowsByName("x").obfuscatedValue should equal(2)
ageRowsByName("y").obfuscatedValue should equal(3)
}
{
val genderRowsByName = genderBreakdownRows.map(row => (row.dataKey, row)).toMap
genderRowsByName("a").originalValue should equal(123)
genderRowsByName("b").originalValue should equal(456)
genderRowsByName("a").obfuscatedValue should equal(124)
genderRowsByName("b").obfuscatedValue should equal(457)
}
intercept[Exception] {
//Should fail due to foreign key constraint
dao.insertBreakdownResults(Map(PATIENT_AGE_COUNT_XML -> Seq(-1000)), breakdownsByType, breakdownsByType)
}
}
@Test
def testInsertErrorResult = afterCreatingTables {
val queryId = dao.insertQuery(masterId1, networkQueryId1, authn, queryDef1, isFlagged = false, hasBeenRun = true, flagMessage = None)
val response = countRunQueryResponse.withResults(Seq(errorQueryResult1))
val resultIdsByType = dao.insertQueryResults(queryId, response.results)
val Seq(resultRow) = list(queryResultRows)
list(errorResultRows).isEmpty should be(true)
- val pd = TestProblem.toDigest
+ val pd = TestProblem().toDigest
dao.insertErrorResult(resultRow.id, message1,pd.codec,pd.stampText,pd.summary,pd.description,pd.detailsXml)
val Seq(errorResultRow) = list(errorResultRows)
errorResultRow.message should equal(message1)
errorResultRow.resultId should equal(resultRow.id)
intercept[Exception] {
//Should fail due to foreign key constraint
dao.insertErrorResult(-12345, "",pd.codec,pd.stampText,pd.summary,pd.description,pd.detailsXml)
}
}
@Test
def testFindResultsFor = afterCreatingTables {
//A RunQueryResponse with all types of QueryResults: count, breakdown, and error
val response = countRunQueryResponse.withResults(Seq(countQueryResult, breakdownQueryResult1, breakdownQueryResult2, errorQueryResult1, errorQueryResult2))
doTestFindResultsFor(response) { resultIdsByType =>
insertCount(resultIdsByType)
insertErrors(resultIdsByType)
insertBreakdowns(resultIdsByType, breakdownsByType)
} {
case (resultIdsByType, resultOption) =>
val Some(result) = resultOption
validateCount(resultIdsByType, result)
validateBreakdowns(result)
validateErrors(result)
}
}
@Test
def testFindResultsForOnlyCount = afterCreatingTables {
//A RunQueryResponse with only a count QueryResult
val response = countRunQueryResponse
doTestFindResultsFor(response) { resultIdsByType =>
insertCount(resultIdsByType)
} {
(resultIdsByType, resultOption) =>
val Some(result) = resultOption
validateCount(resultIdsByType, result)
result.breakdowns.isEmpty should be(true)
result.errors.isEmpty should be(true)
}
}
@Test
def testFindResultsForOnlyErrors = afterCreatingTables {
//A RunQueryResponse with only errors
val response = onlyErrorsRunQueryResponse
doTestFindResultsFor(response) { resultIdsByType =>
insertErrors(resultIdsByType)
} {
(resultIdsByType, resultOption) => resultOption should be(None)
}
}
@Test
def testFindResultsForOnlyBreakdowns = afterCreatingTables {
//A RunQueryResponse with only breakdowns
val response = countRunQueryResponse.withResults(Seq(countQueryResult, breakdownQueryResult1, breakdownQueryResult2, errorQueryResult1, errorQueryResult2))
doTestFindResultsFor(response) { resultIdsByType =>
insertBreakdowns(resultIdsByType, breakdownsByType)
} {
(resultIdsByType, resultOption) => resultOption should be(None)
}
}
private def insertCount(resultIdsByType: Map[ResultOutputType, Seq[Int]]) {
dao.insertCountResult(resultIdsByType(PATIENT_COUNT_XML).head, count, count + 42)
}
private def insertErrors(resultIdsByType: Map[ResultOutputType, Seq[Int]]) {
(resultIdsByType(ERROR) zip Seq(message1, message2)).foreach {
case (resultId, message) =>
- val pd = TestProblem.toDigest
+ val pd = TestProblem().toDigest
dao.insertErrorResult(resultId, message,pd.codec,pd.stampText,pd.summary,pd.description,pd.detailsXml)
}
}
private def insertBreakdowns(resultIdsByType: Map[ResultOutputType, Seq[Int]], breakdownsByType: Map[ResultOutputType, I2b2ResultEnvelope]) {
dao.insertBreakdownResults(resultIdsByType, breakdownsByType, breakdownsByType.mapValues(_.mapValues(_ + 42)))
}
private def validateCount(resultIdsByType: Map[ResultOutputType, Seq[Int]], result: ShrineQueryResult) {
val foundCount = result.count
foundCount.resultId should equal(resultIdsByType(PATIENT_COUNT_XML).head)
foundCount.data.get.originalValue should equal(count)
foundCount.data.get.obfuscatedValue should equal(count + 42)
foundCount.creationDate should not be (null)
}
private def validateBreakdowns(result: ShrineQueryResult) {
val retrievedBreakdownsByType = result.breakdowns.groupBy(_.resultType).mapValues(_.head)
retrievedBreakdownsByType(PATIENT_AGE_COUNT_XML).resultType should equal(PATIENT_AGE_COUNT_XML)
retrievedBreakdownsByType(PATIENT_AGE_COUNT_XML).data should equal(Map("x" -> ObfuscatedPair(1, 43), "y" -> ObfuscatedPair(2, 44)))
retrievedBreakdownsByType(PATIENT_GENDER_COUNT_XML).resultType should equal(PATIENT_GENDER_COUNT_XML)
retrievedBreakdownsByType(PATIENT_GENDER_COUNT_XML).data should equal(Map("a" -> ObfuscatedPair(123, 165), "b" -> ObfuscatedPair(456, 498)))
}
private def validateErrors(result: ShrineQueryResult) {
val Seq(err1, err2) = result.errors
err1.message should equal(message1)
err2.message should equal(message2)
}
private def doTestFindResultsFor(response: RawCrcRunQueryResponse)(inserts: Map[ResultOutputType, Seq[Int]] => Any)(validate: (Map[ResultOutputType, Seq[Int]], Option[ShrineQueryResult]) => Any) = {
dao.findResultsFor(networkQueryId1) should be(None)
val queryId = dao.insertQuery(masterId1, networkQueryId1, authn, queryDef1, isFlagged = false, hasBeenRun = true, flagMessage = None)
val resultIdsByType = dao.insertQueryResults(queryId, response.results)
inserts(resultIdsByType)
val resultOption = dao.findResultsFor(networkQueryId1)
validate(resultIdsByType, resultOption)
}
}
\ No newline at end of file
diff --git a/adapter/adapter-service/src/test/scala/net/shrine/adapter/service/AbstractI2b2AdminResourceJaxrsTest.scala b/adapter/adapter-service/src/test/scala/net/shrine/adapter/service/AbstractI2b2AdminResourceJaxrsTest.scala
index 8d65f28d7..0e49be7ee 100644
--- a/adapter/adapter-service/src/test/scala/net/shrine/adapter/service/AbstractI2b2AdminResourceJaxrsTest.scala
+++ b/adapter/adapter-service/src/test/scala/net/shrine/adapter/service/AbstractI2b2AdminResourceJaxrsTest.scala
@@ -1,101 +1,102 @@
package net.shrine.adapter.service
import junit.framework.TestCase
import net.shrine.adapter.AdapterTestHelpers
import net.shrine.adapter.dao.squeryl.AbstractSquerylAdapterTest
import net.shrine.client.{HttpClient, HttpResponse, JerseyHttpClient}
import net.shrine.crypto.TrustParam.AcceptAllCerts
+import net.shrine.problem.{TestProblem, ProblemSources, AbstractProblem}
import net.shrine.protocol.{DefaultBreakdownResultOutputTypes, ErrorResponse, I2b2AdminReadQueryDefinitionRequest, I2b2AdminRequestHandler, QueryMaster, ReadI2b2AdminPreviousQueriesRequest, ReadPreviousQueriesResponse, ReadQueryDefinitionResponse}
import net.shrine.protocol.query.QueryDefinition
import net.shrine.util.{ShouldMatchersForJUnit, XmlUtil}
import org.junit.{After, Before}
import scala.xml.XML
/**
* @author clint
* @since Apr 24, 2013
*/
abstract class AbstractI2b2AdminResourceJaxrsTest extends TestCase with JerseyTestComponent[I2b2AdminRequestHandler] with AbstractSquerylAdapterTest with ShouldMatchersForJUnit with CanLoadTestData with AdapterTestHelpers {
import scala.concurrent.duration._
protected def adminClient = I2b2AdminClient(resourceUrl, JerseyHttpClient(AcceptAllCerts, 5.minutes))
override def resourceClass(handler: I2b2AdminRequestHandler) = I2b2AdminResource(handler, DefaultBreakdownResultOutputTypes.toSet)
override val basePath = "i2b2/admin/request"
@Before
override def setUp(): Unit = this.JerseyTest.setUp()
@After
override def tearDown(): Unit = this.JerseyTest.tearDown()
-
+
protected object NeverAuthenticatesMockPmHttpClient extends HttpClient {
- override def post(input: String, url: String): HttpResponse = HttpResponse.ok(ErrorResponse("blarg").toI2b2String)
+ override def post(input: String, url: String): HttpResponse = HttpResponse.ok(ErrorResponse(TestProblem(summary = "blarg")).toI2b2String)
}
protected object AlwaysAuthenticatesMockPmHttpClient extends HttpClient {
override def post(input: String, url: String): HttpResponse = {
HttpResponse.ok(XmlUtil.stripWhitespace {
Some user
{ userId }
{ domain }
{ password }
MANAGER
}.toString)
}
}
protected def doTestReadQueryDefinition(networkQueryId: Long, expectedQueryNameAndQueryDef: Option[(String, QueryDefinition)]) {
val request = I2b2AdminReadQueryDefinitionRequest(projectId, waitTime, authn, networkQueryId)
val resp = adminClient.readQueryDefinition(request)
def stripNamespaces(s: String) = XmlUtil.stripNamespaces(XML.loadString(s))
expectedQueryNameAndQueryDef match {
case Some((expectedQueryName, expectedQueryDef)) => {
val response @ ReadQueryDefinitionResponse(masterId, name, userId, createDate, queryDefinition) = resp
masterId should be(networkQueryId)
name should be(expectedQueryName)
userId should be(authn.username)
createDate should not be (null)
//NB: I'm not sure why whacky namespaces were coming back from the resource;
//this checks that the gist of the queryDef XML makes it back.
//TODO: revisit this
stripNamespaces(queryDefinition) should equal(stripNamespaces(expectedQueryDef.toI2b2String))
}
case None => resp.isInstanceOf[ErrorResponse] should be(true)
}
}
protected def doTestReadI2b2AdminPreviousQueries(request: ReadI2b2AdminPreviousQueriesRequest, expectedQueryMasters: Seq[QueryMaster]) {
val ReadPreviousQueriesResponse(queryMasters) = adminClient.readI2b2AdminPreviousQueries(request)
if(expectedQueryMasters.isEmpty) { queryMasters.isEmpty should be(true) }
else {
(queryMasters zip expectedQueryMasters).foreach { case (queryMaster, expected) =>
queryMaster.createDate should not be(null)
queryMaster.name should equal(expected.name)
queryMaster.queryMasterId should equal(expected.queryMasterId)
queryMaster.userId should equal(expected.userId)
queryMaster.groupId should equal(expected.groupId)
queryMaster.flagged should equal(expected.flagged)
}
}
}
}
\ No newline at end of file
diff --git a/adapter/adapter-service/src/test/scala/net/shrine/adapter/service/I2b2AdminResourceJaxrsTest.scala b/adapter/adapter-service/src/test/scala/net/shrine/adapter/service/I2b2AdminResourceJaxrsTest.scala
index c58f32baa..9715b3912 100644
--- a/adapter/adapter-service/src/test/scala/net/shrine/adapter/service/I2b2AdminResourceJaxrsTest.scala
+++ b/adapter/adapter-service/src/test/scala/net/shrine/adapter/service/I2b2AdminResourceJaxrsTest.scala
@@ -1,194 +1,194 @@
package net.shrine.adapter.service
import com.sun.jersey.test.framework.{AppDescriptor, JerseyTest}
import net.shrine.adapter.service.I2b2AdminResourceJaxrsTest._
import net.shrine.client.JerseyHttpClient
import net.shrine.crypto.TrustParam.AcceptAllCerts
import net.shrine.problem.TestProblem
import net.shrine.protocol.{AbstractReadQueryDefinitionRequest, AuthenticationInfo, Credential, DefaultBreakdownResultOutputTypes, I2b2AdminReadQueryDefinitionRequest, I2b2AdminRequestHandler, I2b2AdminUserWithRole, QueryMaster, QueryResult, ReadI2b2AdminPreviousQueriesRequest, ReadI2b2AdminQueryingUsersRequest, ReadI2b2AdminQueryingUsersResponse, ReadPreviousQueriesResponse, ReadQueryDefinitionResponse, RunHeldQueryRequest, RunQueryResponse, ShrineResponse}
import net.shrine.protocol.query.{QueryDefinition, Term}
import net.shrine.util.{JerseyAppDescriptor, ShouldMatchersForJUnit, XmlDateHelper, XmlUtil}
import org.junit.{After, Before, Test}
import scala.xml.XML
/**
* @author clint
* @since Apr 10, 2013
*/
//noinspection ScalaUnnecessaryParentheses
final class I2b2AdminResourceJaxrsTest extends JerseyTest with ShouldMatchersForJUnit {
var handler: MockShrineRequestHandler = _
def resourceUrl = resource.getURI.toString + "i2b2/admin/request"
override def configure: AppDescriptor = {
JerseyAppDescriptor.thatCreates((h: I2b2AdminRequestHandler) => I2b2AdminResource(h, DefaultBreakdownResultOutputTypes.toSet)).using {
handler = new MockShrineRequestHandler
handler
}
}
@Before
override def setUp(): Unit = super.setUp()
@After
override def tearDown(): Unit = super.tearDown()
import scala.concurrent.duration._
def adminClient = I2b2AdminClient(resourceUrl, new JerseyHttpClient(AcceptAllCerts, 5.minutes))
@Test
def testReadQueryDefinition() {
val queryId = 987654321L
val request = I2b2AdminReadQueryDefinitionRequest(projectId, waitTime, authn, queryId)
val currentHandler = handler
val response = adminClient.readQueryDefinition(request).asInstanceOf[ReadQueryDefinitionResponse]
response should not be(null)
response.masterId should equal(queryId)
response.name should equal("some-query-name")
response.createDate should not be(null)
response.userId should equal(authn.username)
def stripNamespaces(s: String) = XmlUtil.stripNamespaces(XML.loadString(s))
//NB: I'm not sure why whacky namespaces were coming back from the resource;
//this checks that the gist of the queryDef XML makes it back.
//TODO: revisit this
stripNamespaces(response.queryDefinition) should equal(stripNamespaces(queryDef.toI2b2String))
currentHandler.shouldBroadcastParam should be(false)
currentHandler.readI2b2AdminPreviousQueriesParam should be(null)
currentHandler.readQueryDefinitionParam should equal(request)
}
@Test
def testReadI2b2AdminPreviousQueries() {
val searchString = "asdk;laskd;lask;gdjsg"
val maxResults = 123
val sortOrder = ReadI2b2AdminPreviousQueriesRequest.SortOrder.Ascending
val categoryToSearchWithin = ReadI2b2AdminPreviousQueriesRequest.Category.All
val searchStrategy = ReadI2b2AdminPreviousQueriesRequest.Strategy.Exact
import ReadI2b2AdminPreviousQueriesRequest.Username._
val request = ReadI2b2AdminPreviousQueriesRequest(projectId, waitTime, authn, Exactly("@"), searchString, maxResults, None, sortOrder, searchStrategy, categoryToSearchWithin)
val currentHandler = handler
val response = adminClient.readI2b2AdminPreviousQueries(request).asInstanceOf[ReadPreviousQueriesResponse]
response should not be(null)
response.queryMasters should equal(Seq(queryMaster))
currentHandler.shouldBroadcastParam should be(false)
currentHandler.readI2b2AdminPreviousQueriesParam should be(request)
currentHandler.readQueryDefinitionParam should be(null)
}
@Test
def testReadI2b2QueryingUsers() {
val projectIdToSearchFor = "foo-project-id"
val request = ReadI2b2AdminQueryingUsersRequest(projectId, waitTime, authn, projectIdToSearchFor)
val currentHandler = handler
val response = adminClient.readI2b2AdminQueryingUsers(request).asInstanceOf[ReadI2b2AdminQueryingUsersResponse]
response should not be(null)
response.users should equal(users)
currentHandler.shouldBroadcastParam should be(false)
currentHandler.readI2b2AdminPreviousQueriesParam should be(null)
currentHandler.readI2b2AdminQueryingUsersParam should be(request)
currentHandler.readQueryDefinitionParam should be(null)
}
}
object I2b2AdminResourceJaxrsTest {
private val queryDef = QueryDefinition("foo", Term("x"))
private val userId = "some-user-id"
private val domain = "some-domain"
private lazy val authn = new AuthenticationInfo(domain, userId, new Credential("some-val", false))
private val projectId = "some-project-id"
import scala.concurrent.duration._
private val waitTime = 12345.milliseconds
private lazy val queryMaster = QueryMaster(
queryMasterId = "queryMasterId",
networkQueryId = 123456789L,
name = "name",
userId = userId,
groupId = domain,
createDate = XmlDateHelper.now,
flagged = Some(true))
private lazy val users = Seq(
I2b2AdminUserWithRole("projectId1", "joe user", "some important role"),
I2b2AdminUserWithRole("projectId2", "jane user", "some other important role"),
I2b2AdminUserWithRole("projectId3", "some user", "some super important role"))
/**
* Mock ShrineRequestHandler; stores passed parameters for later inspection.
* Private, since this is (basically) the enclosing test class's state
*/
final class MockShrineRequestHandler extends I2b2AdminRequestHandler {
private val lock = new AnyRef
def shouldBroadcastParam = lock.synchronized(_shouldBroadcastParam)
def readQueryDefinitionParam = lock.synchronized(_readQueryDefinitionParam)
def readI2b2AdminPreviousQueriesParam = lock.synchronized(_readI2b2AdminPreviousQueriesParam)
def readI2b2AdminQueryingUsersParam = lock.synchronized(_readI2b2AdminQueryingUsersParam)
def runHeldQueryParam = lock.synchronized(_runHeldQueryParam)
private var _shouldBroadcastParam = false
private var _readQueryDefinitionParam: AbstractReadQueryDefinitionRequest = _
private var _readI2b2AdminPreviousQueriesParam: ReadI2b2AdminPreviousQueriesRequest = _
private var _readI2b2AdminQueryingUsersParam: ReadI2b2AdminQueryingUsersRequest = _
private var _runHeldQueryParam: RunHeldQueryRequest = _
override def readI2b2AdminPreviousQueries(request: ReadI2b2AdminPreviousQueriesRequest, shouldBroadcast: Boolean): ShrineResponse = setShouldBroadcastAndThen(shouldBroadcast) {
lock.synchronized { _readI2b2AdminPreviousQueriesParam = request }
ReadPreviousQueriesResponse(Seq(queryMaster))
}
override def readI2b2AdminQueryingUsers(request: ReadI2b2AdminQueryingUsersRequest, shouldBroadcast: Boolean): ShrineResponse = setShouldBroadcastAndThen(shouldBroadcast) {
lock.synchronized { _readI2b2AdminQueryingUsersParam = request }
ReadI2b2AdminQueryingUsersResponse(users)
}
override def readQueryDefinition(request: I2b2AdminReadQueryDefinitionRequest, shouldBroadcast: Boolean): ShrineResponse = setShouldBroadcastAndThen(shouldBroadcast) {
lock.synchronized { _readQueryDefinitionParam = request }
ReadQueryDefinitionResponse(request.queryId, "some-query-name", request.authn.username, XmlDateHelper.now, queryDef.toI2b2String)
}
override def runHeldQuery(request: RunHeldQueryRequest, shouldBroadcast: Boolean): ShrineResponse = {
lock.synchronized { _runHeldQueryParam = request }
- RunQueryResponse(request.networkQueryId, XmlDateHelper.now, request.authn.username, request.projectId, QueryDefinition("bogus", Term("placeholder")), 12345L, QueryResult.errorResult(Some("foo"), "not actually an error",TestProblem))
+ RunQueryResponse(request.networkQueryId, XmlDateHelper.now, request.authn.username, request.projectId, QueryDefinition("bogus", Term("placeholder")), 12345L, QueryResult.errorResult(Some("foo"), "not actually an error",TestProblem()))
}
private def setShouldBroadcastAndThen(shouldBroadcast: Boolean)(f: => ShrineResponse): ShrineResponse = {
try { f } finally {
lock.synchronized { _shouldBroadcastParam = shouldBroadcast }
}
}
}
}
\ No newline at end of file
diff --git a/commons/protocol/src/main/scala/net/shrine/protocol/ErrorResponse.scala b/commons/protocol/src/main/scala/net/shrine/protocol/ErrorResponse.scala
index 57fe1c3e7..904ea7093 100644
--- a/commons/protocol/src/main/scala/net/shrine/protocol/ErrorResponse.scala
+++ b/commons/protocol/src/main/scala/net/shrine/protocol/ErrorResponse.scala
@@ -1,125 +1,116 @@
package net.shrine.protocol
import net.shrine.log.Loggable
-import net.shrine.problem.{ProblemNotYetEncoded, LoggingProblemHandler, Problem, ProblemDigest}
+import net.shrine.problem.{LoggingProblemHandler, Problem, ProblemDigest}
import scala.xml.{NodeBuffer, NodeSeq}
import net.shrine.util.XmlUtil
import net.shrine.serialization.XmlUnmarshaller
import net.shrine.serialization.I2b2Unmarshaller
import net.shrine.util.NodeSeqEnrichments
import scala.util.Try
import scala.util.control.NonFatal
/**
* @author Bill Simons
* @since 4/25/11
* @see http://cbmi.med.harvard.edu
* @see http://chip.org
*
* NOTICE: This software comes with NO guarantees whatsoever and is
* licensed as Lgpl Open Source
* @see http://www.gnu.org/licenses/lgpl.html
*
* NB: Now a case class for structural equality
*/
final case class ErrorResponse(errorMessage: String,problemDigest:ProblemDigest) extends ShrineResponse {
override protected def status: NodeSeq = {
val buffer = new NodeBuffer
buffer += { errorMessage }
buffer += problemDigest.toXml
}
override protected def i2b2MessageBody = null
import ErrorResponse.rootTagName
override def toXml = { XmlUtil.stripWhitespace {
val xml = XmlUtil.renameRootTag(rootTagName) {
{ errorMessage }
{problemDigest.toXml}
}
xml
}
}
}
object ErrorResponse extends XmlUnmarshaller[ErrorResponse] with I2b2Unmarshaller[ErrorResponse] with HasRootTagName with Loggable {
val rootTagName = "errorResponse"
- //todo deprecate this one
- def apply(errorMessage:String,problem:Option[Problem] = None) = {
- new ErrorResponse(errorMessage,problem.fold{
- val problem = ProblemNotYetEncoded(s"'$errorMessage'")
- LoggingProblemHandler.handleProblem(problem) //todo someday hook up to the proper problem handler hierarchy.
- problem.toDigest
- }(p => p.toDigest))
- }
-
def apply(problem:Problem) = {
+ LoggingProblemHandler.handleProblem(problem) //todo someday hook up to the proper problem handler hierarchy.
new ErrorResponse(problem.summary,problem.toDigest)
}
-
override def fromXml(xml: NodeSeq): ErrorResponse = {
val messageXml = xml \ "message"
//NB: Fail fast
require(messageXml.nonEmpty)
val problemDigest = ProblemDigest.fromXml(xml)
ErrorResponse(XmlUtil.trim(messageXml),problemDigest)
}
override def fromI2b2(xml: NodeSeq): ErrorResponse = {
import NodeSeqEnrichments.Strictness._
//todo what determines parseFormatA vs parseFormatB when written? It looks like our ErrorResponses use A.
def parseFormatA: Try[ErrorResponse] = {
for {
statusXml <- xml withChild "response_header" withChild "result_status" withChild "status"
resultStatusXml <- xml withChild "response_header" withChild "result_status"
typeText <- statusXml attribute "type" if typeText == "ERROR" //NB: Fail fast{
statusMessage = XmlUtil.trim(statusXml)
problemDigest = ProblemDigest.fromXml(resultStatusXml)
} yield {
ErrorResponse(statusMessage,problemDigest)
}
}
def parseFormatB: Try[ErrorResponse] = {
for {
conditionXml <- xml withChild "message_body" withChild "response" withChild "status" withChild "condition"
typeText <- conditionXml attribute "type" if typeText == "ERROR"
statusMessage = XmlUtil.trim(conditionXml)
problemDigest = ErrorStatusFromCrc(Option(statusMessage),xml.text).toDigest//here's another place where an ERROR can have no ProblemDigest
} yield {
ErrorResponse(statusMessage,problemDigest)
}
}
parseFormatA.recoverWith { case NonFatal(e) => {
warn(s"Encountered a problem while parsing an error from I2B2 with 'format A', trying 'format B' ${xml.text}",e)
parseFormatB
} }.get
}
/**
*
*
*
*
*
* Query result instance id 3126 not found
*
*
*
*
*/
}
\ No newline at end of file
diff --git a/commons/protocol/src/test/scala/net/shrine/protocol/AggregatedRunQueryResponseTest.scala b/commons/protocol/src/test/scala/net/shrine/protocol/AggregatedRunQueryResponseTest.scala
index 0abbe99ed..574d82c51 100644
--- a/commons/protocol/src/test/scala/net/shrine/protocol/AggregatedRunQueryResponseTest.scala
+++ b/commons/protocol/src/test/scala/net/shrine/protocol/AggregatedRunQueryResponseTest.scala
@@ -1,318 +1,318 @@
package net.shrine.protocol
import net.shrine.problem.TestProblem
import scala.xml.NodeSeq
import org.junit.Test
import net.shrine.protocol.query.QueryDefinition
import net.shrine.protocol.query.Term
import net.shrine.util.XmlDateHelper
import net.shrine.util.XmlUtil
/**
*
*
* @author Justin Quan
* @see http://chip.org
* @since 8/12/11
*/
//noinspection EmptyParenMethodOverridenAsParameterless,EmptyParenMethodAccessedAsParameterless,UnitMethodIsParameterless
final class AggregatedRunQueryResponseTest extends ShrineResponseI2b2SerializableValidator {
private val queryId = 1L
private val queryName = "queryName"
private val userId = "user"
private val groupId = "group"
private val createDate = XmlDateHelper.now
private val requestQueryDef = QueryDefinition(queryName, Term("""\\i2b2\i2b2\Demographics\Age\0-9 years old\"""))
private val queryInstanceId = 2L
private val resultId = 3L
private val setSize = 10L
private val startDate = createDate
private val endDate = createDate
private val resultId2 = 4L
private val resultType1 = ResultOutputType.PATIENT_COUNT_XML
private val resultType2 = ResultOutputType.PATIENT_COUNT_XML
private val statusType = QueryResult.StatusType.Finished
override def messageBody = {
DONE
{ queryId }
{ queryName }
{ userId }
{ groupId }
{ createDate }
{ requestQueryDef.toI2b2 }
{ queryInstanceId }
{ queryId }
{ userId }
{ groupId }
6
COMPLETED
COMPLETED
{ resultId }
{ queryInstanceId }
4
{ resultType1 }
CATNUM
LA
Number of patients
{ setSize }
{ startDate }
{ endDate }
{ statusType }
3
FINISHED
{ resultId2 }
{ queryInstanceId }
4
{ resultType2 }
CATNUM
LA
Number of patients
{ setSize }
{ startDate }
{ endDate }
{ statusType }
3
FINISHED
}
private val qr1 = QueryResult(
resultId = resultId,
instanceId = queryInstanceId,
resultType = Option(resultType1),
setSize = setSize,
startDate = Option(createDate),
endDate = Option(createDate),
description = None,
statusType = statusType,
statusMessage = Some(statusType.name),
problemDigest = None,
breakdowns = Map.empty)
private val qr2 = QueryResult(
resultId = resultId2,
instanceId = queryInstanceId,
resultType = Option(resultType2),
setSize = setSize,
startDate = Option(createDate),
endDate = Option(createDate),
description = None,
statusType = statusType,
statusMessage = Some(statusType.name),
problemDigest = None,
breakdowns = Map.empty)
private val runQueryResponse = XmlUtil.stripWhitespace {
{ queryId }
{ queryInstanceId }
{ userId }
{ groupId }
{ requestQueryDef.toXml }
{ createDate }
{
Seq(qr1, qr2).map(_.toXml)
}
}
import DefaultBreakdownResultOutputTypes.{ values => breakdownTypes }
@Test
def testFromXml {
val actual = AggregatedRunQueryResponse.fromXml(breakdownTypes.toSet)(runQueryResponse).get
actual.queryId should equal(queryId)
actual.createDate should equal(createDate)
actual.userId should equal(userId)
actual.groupId should equal(groupId)
actual.requestXml should equal(requestQueryDef)
actual.queryInstanceId should equal(queryInstanceId)
actual.results should equal(Seq(qr1, qr2))
actual.queryName should equal(queryName)
}
@Test
def testToXml {
AggregatedRunQueryResponse(queryId, createDate, userId, groupId, requestQueryDef, queryInstanceId, Seq(qr1, qr2)).toXmlString should equal(runQueryResponse.toString)
}
@Test
def testFromI2b2 {
val translatedResponse = AggregatedRunQueryResponse.fromI2b2(breakdownTypes.toSet)(response).get
translatedResponse.queryId should equal(queryId)
translatedResponse.createDate should equal(createDate)
translatedResponse.userId should equal(userId)
translatedResponse.groupId should equal(groupId)
translatedResponse.requestXml should equal(requestQueryDef)
translatedResponse.queryInstanceId should equal(queryInstanceId)
translatedResponse.results should equal(Seq(qr1, qr2))
translatedResponse.queryName should equal(queryName)
}
@Test
def testFromI2b2StringRequestXml {
val hackToProduceXml = new HasResponse {
//Produces a message body where the tag contains escaped XML as a String, as is produced by the CRC
override def messageBody: NodeSeq = {
DONE
{ queryId }
{ queryName }
{ userId }
{ groupId }
{ createDate }
{ requestQueryDef.toI2b2String }
{ queryInstanceId }
{ queryId }
{ userId }
{ groupId }
6
COMPLETED
COMPLETED
{ resultId }
{ queryInstanceId }
{ resultType1 }
1
LIST
LA
Patient list
{ setSize }
{ startDate }
{ endDate }
{ statusType }
3
FINISHED
{ resultId2 }
{ queryInstanceId }
{ resultType2 }
4
CATNUM
LA
Number of patients
{ setSize }
{ startDate }
{ endDate }
{ statusType }
3
FINISHED
}
}
doTestFromI2b2(hackToProduceXml.response, requestQueryDef)
}
private def doTestFromI2b2(i2b2Response: NodeSeq, expectedQueryDef: AnyRef) {
val translatedResponse = AggregatedRunQueryResponse.fromI2b2(breakdownTypes.toSet)(i2b2Response).get
translatedResponse.queryId should equal(queryId)
translatedResponse.createDate should equal(createDate)
translatedResponse.userId should equal(userId)
translatedResponse.groupId should equal(groupId)
translatedResponse.requestXml should equal(expectedQueryDef)
translatedResponse.queryInstanceId should equal(queryInstanceId)
translatedResponse.results should equal(Seq(qr1, qr2))
translatedResponse.queryName should equal(queryName)
}
@Test
def testResultsPartitioned {
val actual = AggregatedRunQueryResponse.fromXml(breakdownTypes.toSet)(runQueryResponse).get
{
val (nonErrors, errors) = actual.resultsPartitioned
nonErrors should equal(Seq(qr1, qr2))
errors.size should equal(0)
}
- def error = QueryResult.errorResult(None, "something broke", TestProblem)
+ def error = QueryResult.errorResult(None, "something broke", TestProblem())
{
val withOnlyErrors = actual.withResults(Seq(error, error))
val (nonErrors, errors) = withOnlyErrors.resultsPartitioned
nonErrors.size should equal(0)
errors should equal(Seq(error, error))
}
{
val withErrorsAndSuccesses = actual.withResults(actual.results ++ Seq(error, error))
val (nonErrors, errors) = withErrorsAndSuccesses.resultsPartitioned
nonErrors should equal(Seq(qr1, qr2))
errors should equal(Seq(error, error))
}
{
val withNoResults = actual.withResults(Nil)
val (nonErrors, errors) = withNoResults.resultsPartitioned
nonErrors.size should equal(0)
errors.size should equal(0)
}
}
@Test
def testToI2b2 {
AggregatedRunQueryResponse(queryId, createDate, userId, groupId, requestQueryDef, queryInstanceId, Seq(qr1, qr2)).toI2b2String should equal(response.toString)
}
}
\ No newline at end of file
diff --git a/commons/protocol/src/test/scala/net/shrine/protocol/ErrorResponseTest.scala b/commons/protocol/src/test/scala/net/shrine/protocol/ErrorResponseTest.scala
index bbfb0888c..f8065600d 100644
--- a/commons/protocol/src/test/scala/net/shrine/protocol/ErrorResponseTest.scala
+++ b/commons/protocol/src/test/scala/net/shrine/protocol/ErrorResponseTest.scala
@@ -1,157 +1,158 @@
package net.shrine.protocol
import junit.framework.TestCase
import net.shrine.problem.TestProblem
import net.shrine.util.ShouldMatchersForJUnit
import org.junit.Test
import scala.xml.NodeSeq
import net.shrine.util.XmlUtil
/**
* @author clint
* @since Apr 5, 2013
*/
final class ErrorResponseTest extends TestCase with ShouldMatchersForJUnit {
val message = "foo"
+ val problem = TestProblem(message)
- val resp = ErrorResponse(message,Some(TestProblem))
+ val resp = ErrorResponse(problem)
val expectedShrineXml = XmlUtil.stripWhitespace {
{ message }
- {TestProblem.toDigest.toXml}
+ {problem.toDigest.toXml}
}
val expectedI2b2Xml = XmlUtil.stripWhitespace {
1.1
2.4
SHRINE
1.3-compatible
SHRINE
2011-04-08T16:21:12.251-04:00
{ message }
- {TestProblem.toDigest.toXml}
+ {problem.toDigest.toXml}
}
@Test
def testToXml() = doTestToXml(expectedShrineXml, _.toXml)
@Test
def testToI2b2() = doTestToXml(expectedI2b2Xml, _.toI2b2)
@Test
def testToXmlRoundTrip() = doTestRoundTrip(_.toXml, ErrorResponse.fromXml)
@Test
def testToI2b2RoundTrip() = doTestRoundTrip(_.toI2b2, ErrorResponse.fromI2b2)
@Test
def testFromXml() = doTestFromXml(expectedShrineXml, ErrorResponse.fromXml)
@Test
def testFromI2b2() = doTestFromXml(expectedI2b2Xml, ErrorResponse.fromI2b2)
//NB: See https://open.med.harvard.edu/jira/browse/SHRINE-745
@Test
def testFromI2b2AlternateFormat() {
val altI2b2Xml = XmlUtil.stripWhitespace {
1.1
2.4
edu.harvard.i2b2.crc
1.5
i2b2 Hive
i2b2_QueryTool
0.2
i2b2 Hive
1
i2b2
Log information
DONE
Query result instance id 3126 not found
}
val resp = ErrorResponse.fromI2b2(altI2b2Xml)
resp should not be null
resp.errorMessage should equal("Query result instance id 3126 not found")
}
private def doTestFromXml(xml: NodeSeq, deserialize: NodeSeq => ErrorResponse) {
intercept[Exception] {
deserialize(null)
}
intercept[Exception] {
deserialize()
}
intercept[Exception] {
//Correct I2b2 XML structure, wrong status type
deserialize({ message })
}
val deserialized = deserialize(xml)
deserialized.problemDigest.detailsXml should equal(resp.problemDigest.detailsXml)
deserialized.problemDigest should equal(resp.problemDigest)
deserialized should equal(resp)
}
private def doTestToXml(expected: NodeSeq, serialize: ErrorResponse => NodeSeq) {
val xml = serialize(resp)
xml.toString should equal(expected.toString())
}
private def doTestRoundTrip(serialize: ErrorResponse => NodeSeq, deserialize: NodeSeq => ErrorResponse) {
val unmarshalled = deserialize(serialize(resp))
unmarshalled should equal(resp)
}
}
\ No newline at end of file
diff --git a/commons/protocol/src/test/scala/net/shrine/protocol/QueryResultTest.scala b/commons/protocol/src/test/scala/net/shrine/protocol/QueryResultTest.scala
index 1b91ae976..9d84499cd 100644
--- a/commons/protocol/src/test/scala/net/shrine/protocol/QueryResultTest.scala
+++ b/commons/protocol/src/test/scala/net/shrine/protocol/QueryResultTest.scala
@@ -1,498 +1,496 @@
package net.shrine.protocol
import net.shrine.problem.{TestProblem, ProblemSources, AbstractProblem}
import net.shrine.util.ShouldMatchersForJUnit
import org.junit.Test
import net.shrine.util.XmlUtil
import net.shrine.util.XmlDateHelper
import net.shrine.util.XmlGcEnrichments
-import scala.xml.{XML, NodeSeq}
+import scala.xml.NodeSeq
/**
* @author Bill Simons
* @author clint
* @since 8/19/11
* @see http://cbmi.med.harvard.edu
* @see http://chip.org
*
* NOTICE: This software comes with NO guarantees whatsoever and is
* licensed as Lgpl Open Source
* @see http://www.gnu.org/licenses/lgpl.html
*/
//noinspection EmptyParenMethodAccessedAsParameterless,NameBooleanParameters
final class QueryResultTest extends ShouldMatchersForJUnit with XmlRoundTripper[QueryResult] with I2b2SerializableValidator {
private val date = XmlDateHelper.now
private val resultId = 1L
private val instanceId = 2L
private val resultType = ResultOutputType.PATIENT_COUNT_XML
private val setSize = 12L
private val statusType = QueryResult.StatusType.Finished
private val description = "description"
private val statusMessage = "lakjdalsjd"
private val queryResult = QueryResult(resultId, instanceId, Some(resultType), setSize, Option(date), Option(date), Option(description), statusType, Option(statusType.name))
import DefaultBreakdownResultOutputTypes.{ values => breakdownTypes, _ }
private val resultWithBreakDowns = queryResult.copy(
statusMessage = Some(statusMessage),
breakdowns =
Map(PATIENT_AGE_COUNT_XML -> I2b2ResultEnvelope(PATIENT_AGE_COUNT_XML, Map("foo" -> 1L, "bar" -> 2L)),
PATIENT_RACE_COUNT_XML -> I2b2ResultEnvelope(PATIENT_RACE_COUNT_XML, Map("nuh" -> 3L, "zuh" -> 4L)),
PATIENT_VITALSTATUS_COUNT_XML -> I2b2ResultEnvelope(PATIENT_VITALSTATUS_COUNT_XML, Map("blarg" -> 5L, "glarg" -> 6L)),
PATIENT_GENDER_COUNT_XML -> I2b2ResultEnvelope(PATIENT_GENDER_COUNT_XML, Map("huh" -> 7L, "yeah" -> 8))))
private val expectedWhenBreakdownsArePresent = XmlUtil.stripWhitespace {
{ resultId }
{ instanceId }
{ resultType.toXml }
{ setSize }
{ date }
{ date }
{ description }
{ statusType }
{ statusMessage }
{ PATIENT_AGE_COUNT_XML }
bar
2
foo
1
{ PATIENT_GENDER_COUNT_XML }
huh
7
yeah
8
{ PATIENT_RACE_COUNT_XML }
nuh
3
zuh
4
{ PATIENT_VITALSTATUS_COUNT_XML }
blarg
5
glarg
6
}.toString
private val expectedI2b2Xml = XmlUtil.stripWhitespace {
{ resultId }
{ instanceId }
{ description }
4
{ resultType }
CATNUMLANumber of patients
{ setSize }
{ date }
{ date }
{ statusType }
3FINISHED
}.toString
private val expectedI2b2XmlWithBreakdowns = XmlUtil.stripWhitespace {
{ resultId }
{ instanceId }
{ description }
{ resultType.toI2b2 }
{ setSize }
{ date }
{ date }
{ statusType }
3FINISHED
{ PATIENT_AGE_COUNT_XML }
bar
2
foo
1
{ PATIENT_GENDER_COUNT_XML }
huh
7
yeah
8
{ PATIENT_RACE_COUNT_XML }
nuh
3
zuh
4
{ PATIENT_VITALSTATUS_COUNT_XML }
blarg
5
glarg
6
}.toString
private val expectedI2b2ErrorXml = XmlUtil.stripWhitespace {
0
0
{ description }
0
ERROR
{ statusMessage }
}.toString
//NB: See https://open.med.harvard.edu/jira/browse/SHRINE-745
private val expectedI2b2IncompleteXml = XmlUtil.stripWhitespace {
0
0
{ description }
0
INCOMPLETE
{ statusMessage }
}.toString
import scala.xml.XML.loadString
//NB: See https://open.med.harvard.edu/jira/browse/SHRINE-745
@Test
def testParseIncomplete() {
val qr = QueryResult.fromI2b2(breakdownTypes.toSet)(loadString(expectedI2b2IncompleteXml))
qr.statusType should be(QueryResult.StatusType.Incomplete)
}
@Test
def testElapsed() {
queryResult.copy(startDate = None).elapsed should be(None)
queryResult.copy(endDate = None).elapsed should be(None)
queryResult.copy(startDate = None, endDate = None).elapsed should be(None)
{
val now = XmlDateHelper.now
queryResult.copy(startDate = Some(now), endDate = Some(now)).elapsed should equal(Some(0L))
}
{
val start = XmlDateHelper.now
val delta = 123L
import XmlGcEnrichments._
import scala.concurrent.duration._
val end = start + delta.milliseconds
queryResult.copy(startDate = Some(start), endDate = Some(end)).elapsed should equal(Some(delta))
}
}
@Test
def testIsError() {
queryResult.isError should be(false)
queryResult.copy(statusType = QueryResult.StatusType.Processing).isError should be(false)
queryResult.copy(statusType = QueryResult.StatusType.Finished).isError should be(false)
queryResult.copy(statusType = QueryResult.StatusType.Queued).isError should be(false)
queryResult.copy(statusType = QueryResult.StatusType.Incomplete).isError should be(false)
queryResult.copy(statusType = QueryResult.StatusType.Error).isError should be(true)
}
@Test
def testToXml() {
val queryResultForShrine = queryResult.copy(statusMessage = Some(statusMessage))
val expectedWhenNoBreakdowns = XmlUtil.stripWhitespace {
{ resultId }
{ instanceId }
{ resultType.toXml }
{ setSize }
{ date }
{ date }
{ description }
{ statusType }
{ statusMessage }
}.toString
queryResultForShrine.copy(statusMessage = Some(statusMessage)).toXmlString should equal(expectedWhenNoBreakdowns)
val expectedWhenNoStartDate = XmlUtil.stripWhitespace {
{ resultId }
{ instanceId }
{ resultType.toXml }
{ setSize }
{ date }
{ description }
{ statusType }
{ statusMessage }
}.toString
queryResultForShrine.copy(startDate = None).toXmlString should equal(expectedWhenNoStartDate)
val expectedWhenNoEndDate = XmlUtil.stripWhitespace {
{ resultId }
{ instanceId }
{ resultType.toXml }
{ setSize }
{ date }
{ description }
{ statusType }
{ statusMessage }
}.toString
queryResultForShrine.copy(endDate = None).toXmlString should equal(expectedWhenNoEndDate)
val expectedWhenNoDescription = XmlUtil.stripWhitespace {
{ resultId }
{ instanceId }
{ resultType.toXml }
{ setSize }
{ date }
{ date }
{ statusType }
{ statusMessage }
}.toString
queryResultForShrine.copy(description = None).toXmlString should equal(expectedWhenNoDescription)
val expectedWhenNoStatusMessage = XmlUtil.stripWhitespace {
{ resultId }
{ instanceId }
{ resultType.toXml }
{ setSize }
{ date }
{ date }
{ description }
{ statusType }
}.toString
queryResult.copy(statusMessage = None).toXmlString should equal(expectedWhenNoStatusMessage)
resultWithBreakDowns.toXmlString should equal(expectedWhenBreakdownsArePresent)
}
@Test
def testFromXml() {
QueryResult.fromXml(breakdownTypes.toSet)(loadString(expectedWhenBreakdownsArePresent)) should equal(resultWithBreakDowns)
}
@Test
def testShrineRoundTrip() = {
QueryResult.fromXml(breakdownTypes.toSet)(resultWithBreakDowns.toXml) should equal(resultWithBreakDowns)
}
private def compareIgnoringBreakdowns(actual: QueryResult, expected: QueryResult) {
//Ignore breakdowns field, since this can't be serialized to i2b2 format as part of a
actual.breakdowns should equal(Map.empty)
actual.description should equal(expected.description)
actual.endDate should equal(expected.endDate)
actual.instanceId should equal(expected.instanceId)
actual.resultId should equal(expected.resultId)
actual.resultType should equal(expected.resultType)
actual.setSize should equal(expected.setSize)
actual.startDate should equal(expected.startDate)
actual.statusMessage should equal(expected.statusMessage)
actual.statusType should equal(expected.statusType)
}
@Test
def testI2b2RoundTrip() = {
//NB: Needed because i2b2 handles status messages differently. In the error case, statusMessage is
//descriptive; otherwise, it's the all-caps name of the status type. This is different from how
//Shrine creates and parses statusMessage XML, so we need a new QueryResult here. (Previously, we
//could use the same one, since we were ignoring statusMessage and description when unmarshalling
//from i2b2 format.)
val newStatusMessage = Some(resultWithBreakDowns.statusType.name)
val resultWithBreakDownsForI2b2 = resultWithBreakDowns.copy(statusMessage = newStatusMessage)
val unmarshalled = QueryResult.fromI2b2(breakdownTypes.toSet)(resultWithBreakDownsForI2b2.toI2b2)
compareIgnoringBreakdowns(unmarshalled, resultWithBreakDownsForI2b2)
}
@Test
def testFromI2b2() {
compareIgnoringBreakdowns(QueryResult.fromI2b2(breakdownTypes.toSet)(loadString(expectedI2b2Xml)), queryResult)
}
@Test
def testFromI2b2WithErrors() {
- val errorResult = QueryResult.errorResult(Some(description), statusMessage,TestProblem)
+ val errorResult = QueryResult.errorResult(Some(description), statusMessage,TestProblem())
val actual = QueryResult.fromI2b2(breakdownTypes.toSet)(loadString(expectedI2b2ErrorXml))
compareIgnoringBreakdowns(actual, errorResult)
}
@Test
def testToI2b2() {
queryResult.toI2b2String should equal(expectedI2b2Xml)
}
@Test
def testToI2b2WithBreakdowns() {
resultWithBreakDowns.toI2b2String should equal(expectedI2b2XmlWithBreakdowns)
}
@Test
def testToI2b2AllStatusTypes(): Unit = {
def doTest(statusType: QueryResult.StatusType) {
val expectedI2b2Xml = XmlUtil.stripWhitespace {
{ resultId }
{ instanceId }
{ description }
{ resultType.toI2b2 }
{ setSize }
{ date }
{ date }
{ statusType }
{ statusType.i2b2Id.get }{ statusType }
}.toString
val result = queryResult.copy(statusType = statusType)
result.toI2b2String should equal(expectedI2b2Xml)
}
import QueryResult.StatusType
//NB: Error is tested by testToI2b2WithErrors()
val nonErrorStatuses = StatusType.values.toSet - StatusType.Error
for (statusType <- nonErrorStatuses) {
doTest(statusType)
}
}
@Test
def testToI2b2WithErrors(): Unit = {
- QueryResult.errorResult(Some(description), statusMessage, TestProblem).toI2b2String
+ QueryResult.errorResult(Some(description), statusMessage, TestProblem()).toI2b2String
}
@Test
def testWithErrorsAndProblemDigest():Unit = {
- case class TestProblem(override val summary: String = "test summary",override val description:String = "test description") extends AbstractProblem(ProblemSources.Unknown)
-
val testProblem:TestProblem = new TestProblem()
val expected: NodeSeq =
0
0
description
0
ERROR
lakjdalsjd
{testProblem.problemName}
{testProblem.stamp.pretty}
{testProblem.summary}
{testProblem.description}
{testProblem.detailsXml}
val actual = QueryResult.errorResult(
Some(description),
statusMessage,
testProblem)
val i2b2Xml: NodeSeq = actual.toI2b2
val pretty = new scala.xml.PrettyPrinter(80, 2)
pretty.formatNodes(i2b2Xml) should equal(pretty.formatNodes(expected))
val fromI2b2 = QueryResult.fromI2b2(Set.empty)(i2b2Xml)
fromI2b2 should equal(actual)
val xml = actual.toXml
val fromXml = QueryResult.fromXml(Set.empty)(xml)
fromXml should equal(actual)
}
}
\ No newline at end of file
diff --git a/commons/protocol/src/test/scala/net/shrine/protocol/ReadPreviousQueriesResponseTest.scala b/commons/protocol/src/test/scala/net/shrine/protocol/ReadPreviousQueriesResponseTest.scala
index 0a4256507..44d14217e 100644
--- a/commons/protocol/src/test/scala/net/shrine/protocol/ReadPreviousQueriesResponseTest.scala
+++ b/commons/protocol/src/test/scala/net/shrine/protocol/ReadPreviousQueriesResponseTest.scala
@@ -1,177 +1,178 @@
package net.shrine.protocol
+import net.shrine.problem.TestProblem
import org.junit.Test
import net.shrine.util.XmlUtil
import net.shrine.util.XmlDateHelper
import javax.xml.datatype.XMLGregorianCalendar
/**
* @author Bill Simons
* @since 4/12/11
* @see http://cbmi.med.harvard.edu
* @see http://chip.org
*
* NOTICE: This software comes with NO guarantees whatsoever and is
* licensed as Lgpl Open Source
* @see http://www.gnu.org/licenses/lgpl.html
*/
final class ReadPreviousQueriesResponseTest extends ShrineResponseI2b2SerializableValidator {
val queryMasterId1 = 1111111L
val queryMasterId2 = 222222L
val networkQueryId1 = 123455667L
val networkQueryId2 = 98327592L
val queryName1 = "name1"
val queryName2 = "name2"
val userId1 = Some("user1")
val userId2 = Some("user2")
val groupId1 = Some("group1")
val groupId2 = Some("group2")
val createDate1 = XmlDateHelper.now
val createDate2 = XmlDateHelper.now
val flagged1 = Some(true)
val flagged2 = None
val flagMessage1 = Some("askldhlaksdjlkasdjklasdjl")
val flagMessage2 = None
val queryMaster1 = makeQueryMaster(queryMasterId1, networkQueryId1, queryName1, userId1, groupId1, createDate1, flagged1, flagMessage1)
val queryMaster2 = makeQueryMaster(queryMasterId2, networkQueryId2, queryName2, userId2, groupId2, createDate2, flagged2, flagMessage2)
def makeQueryMaster(queryMasterId: Long, networkQueryId: Long, queryName: String, userId: Option[String], groupId: Option[String], createDate: XMLGregorianCalendar, flagged: Option[Boolean], flagMessage: Option[String]) = {
QueryMaster(String.valueOf(queryMasterId), networkQueryId, queryName, userId.get, groupId.get, createDate, flagged, flagMessage)
}
def messageBody = XmlUtil.stripWhitespace {
DONE
{ queryMasterId1 }
{ networkQueryId1 }
{ queryName1 }
{ userId1.get }
{ groupId1.get }
{ createDate1 }
{ flagged1.get }
{ flagMessage1.get }
{ queryMasterId2 }
{ networkQueryId2 }
{ queryName2 }
{ userId2.get }
{ groupId2.get }
{ createDate2 }
}
//keep the held field around to be sure that old messages can be read.
def oldMessageBody = XmlUtil.stripWhitespace {
DONE
{ queryMasterId1 }
{ networkQueryId1 }
{ queryName1 }
{ userId1.get }
{ groupId1.get }
{ createDate1 }
{ flagged1.get }
{ flagMessage1.get }
{ queryMasterId2 }
{ networkQueryId2 }
{ queryName2 }
{ userId2.get }
{ groupId2.get }
{ createDate2 }
false
}
val readPreviousQueriesResponse = XmlUtil.stripWhitespace {
{ queryMasterId1 }
{ networkQueryId1 }
{ queryName1 }
{ createDate1 }
{ userId1.get }
{ groupId1.get }
{ flagged1.get }
{ flagMessage1.get }
{ queryMasterId2 }
{ networkQueryId2 }
{ queryName2 }
{ createDate2 }
{ userId2.get }
{ groupId2.get }
}
@Test
def testFromI2b2FailsFast() {
intercept[Exception] {
ReadPreviousQueriesResponse.fromI2b2()
}
intercept[Exception] {
- ReadPreviousQueriesResponse.fromI2b2(ErrorResponse("foo!").toI2b2)
+ ReadPreviousQueriesResponse.fromI2b2(ErrorResponse(TestProblem("foo!")).toI2b2)
}
}
@Test
def testFromXml() {
val actual = ReadPreviousQueriesResponse.fromXml(readPreviousQueriesResponse)
val expectedQueryMasters = Set(queryMaster1, queryMaster2)
actual.queryMasters.toSet should equal(expectedQueryMasters)
}
@Test
def testToXml() {
//we compare the string versions of the xml because Scala's xml equality does not always behave properly
ReadPreviousQueriesResponse(Seq(queryMaster1, queryMaster2)).toXmlString should equal(readPreviousQueriesResponse.toString)
}
@Test
def testFromI2b2() {
val translatedResponse = ReadPreviousQueriesResponse.fromI2b2(response)
translatedResponse.queryMasters.toSet should equal(Set(queryMaster1, queryMaster2))
}
@Test
def testToI2b2() {
//Per-queryMaster userids and groupids
//we compare the string versions of the xml because Scala's xml equality does not always behave properly
val actual = ReadPreviousQueriesResponse(Seq(queryMaster1, queryMaster2)).toI2b2String
val expected = response.toString
actual should equal(expected)
}
}
\ No newline at end of file
diff --git a/commons/protocol/src/test/scala/net/shrine/protocol/ShrineMessageTest.scala b/commons/protocol/src/test/scala/net/shrine/protocol/ShrineMessageTest.scala
index bd979d01c..343acf579 100644
--- a/commons/protocol/src/test/scala/net/shrine/protocol/ShrineMessageTest.scala
+++ b/commons/protocol/src/test/scala/net/shrine/protocol/ShrineMessageTest.scala
@@ -1,166 +1,166 @@
package net.shrine.protocol
import net.shrine.problem.TestProblem
import net.shrine.util.ShouldMatchersForJUnit
import org.junit.Test
import scala.xml.NodeSeq
import net.shrine.protocol.query.QueryDefinition
import net.shrine.protocol.query.Term
import net.shrine.util.XmlDateHelper
import java.math.BigInteger
/**
* @author clint
* @since Feb 24, 2014
*/
final class ShrineMessageTest extends ShouldMatchersForJUnit {
@Test
def testRoundTrips {
val projectId = "salkdjksaljdkla"
import scala.concurrent.duration._
val waitTime: Duration = 98374L.milliseconds
val userId = "foo-user"
val groupId = "foo-group"
val authn = AuthenticationInfo("blarg-domain", userId, Credential("sajkhdkjsadh", true))
val queryId = 485794359L
val patientSetCollId = "ksaldjksal"
val optionsXml: NodeSeq = x
val fetchSize = 12345
val queryName = "saljkd;salda"
val topicId = "saldjkasljdasdsadsadasdas"
val topicName = "Topic Name"
val outputTypes = ResultOutputType.nonBreakdownTypes.toSet
val queryDefinition = QueryDefinition(queryName, Term("oiweruoiewkldfhsofi"))
val queryDefinition2 = QueryDefinition(queryName, Term("a;slkjflfjlsdkjf"))
val localResultId = "aoiduaojsdpaojcmsal"
val nodeId = NodeId("foo")
val nodeId2 = NodeId("bar")
val queryTopicId1 = 123L
val queryTopicId2 = 456L
val queryTopicName1 = "nuh"
val queryTopicName2 = "zuh"
val shrineNetworkQueryId = 1287698235L
val start = Some(XmlDateHelper.now)
val end = Some(XmlDateHelper.now)
- val singleNodeResult1 = QueryResult.errorResult(Some("blarg"), "glarg",TestProblem)
+ val singleNodeResult1 = QueryResult.errorResult(Some("blarg"), "glarg",TestProblem())
val singleNodeResult2 = QueryResult(
42L,
99L,
Option(ResultOutputType.PATIENT_COUNT_XML),
123L,
start,
end,
Some("description"),
QueryResult.StatusType.Finished,
Some("status"))
val param1 = ParamResponse("foo", "bar", "baz")
val queryMaster1 = QueryMaster("kjasdh", 12345L, "name1", userId, groupId, start.get)
val queryMaster2 = QueryMaster("skdjlhlasf", 873563L, "name2", userId, groupId, end.get)
val queryInstance1 = QueryInstance("asd", "42", userId, groupId, start.get, end.get)
val queryInstance2 = QueryInstance("asdasd", "99", userId, groupId, start.get, end.get)
val envelope = I2b2ResultEnvelope(DefaultBreakdownResultOutputTypes.PATIENT_AGE_COUNT_XML, Map("x" -> 1, "y" -> 2))
//BroadcastMessage
//Non-CA-signed signing cert
doMarshallingRoundTrip(BroadcastMessage(123456L, authn, DeleteQueryRequest(projectId, waitTime, authn, queryId), Some(Signature(XmlDateHelper.now, CertId(new BigInteger("1234567890")), None, "asdf".getBytes))))
//CA-signed signing cert
doMarshallingRoundTrip(BroadcastMessage(123456L, authn, DeleteQueryRequest(projectId, waitTime, authn, queryId), Some(Signature(XmlDateHelper.now, CertId(new BigInteger("1234567890")), Some(CertData("cert signed by ca".getBytes)), "asdf".getBytes))))
//Non-i2b2able requests
doMarshallingRoundTrip(ReadTranslatedQueryDefinitionRequest(authn, waitTime, queryDefinition))
doMarshallingRoundTrip(ReadQueryResultRequest(projectId, waitTime, authn, queryId))
//I2b2able requests
doMarshallingRoundTrip(DeleteQueryRequest(projectId, waitTime, authn, queryId))
doMarshallingRoundTrip(ReadApprovedQueryTopicsRequest(projectId, waitTime, authn, userId))
doMarshallingRoundTrip(ReadInstanceResultsRequest(projectId, waitTime, authn, queryId))
doMarshallingRoundTrip(ReadPreviousQueriesRequest(projectId, waitTime, authn, userId, fetchSize))
doMarshallingRoundTrip(ReadQueryDefinitionRequest(projectId, waitTime, authn, queryId))
doMarshallingRoundTrip(ReadQueryInstancesRequest(projectId, waitTime, authn, queryId))
doMarshallingRoundTrip(RenameQueryRequest(projectId, waitTime, authn, queryId, queryName))
doMarshallingRoundTrip(RunQueryRequest(projectId, waitTime, authn, queryId, Option(topicId), Option(topicName), outputTypes, queryDefinition))
doMarshallingRoundTrip(RunQueryRequest(projectId, waitTime, authn, queryId, None, None, outputTypes, queryDefinition))
doMarshallingRoundTrip(ReadResultRequest(projectId, waitTime, authn, localResultId))
//Non-i2b2able responses
doMarshallingRoundTrip(SingleNodeReadTranslatedQueryDefinitionResponse(SingleNodeTranslationResult(nodeId, queryDefinition)))
doMarshallingRoundTrip(AggregatedReadTranslatedQueryDefinitionResponse(Seq(SingleNodeTranslationResult(nodeId, queryDefinition), SingleNodeTranslationResult(nodeId2, queryDefinition2))))
//I2b2able responses
doMarshallingRoundTrip(DeleteQueryResponse(queryId))
doMarshallingRoundTrip(ReadApprovedQueryTopicsResponse(Seq(ApprovedTopic(queryTopicId1, queryTopicName1), ApprovedTopic(queryTopicId2, queryTopicName2))))
doMarshallingRoundTrip(ReadInstanceResultsResponse(shrineNetworkQueryId, singleNodeResult2))
doMarshallingRoundTrip(AggregatedReadInstanceResultsResponse(shrineNetworkQueryId, Seq(singleNodeResult1, singleNodeResult2)))
doMarshallingRoundTrip(ReadPdoResponse(Seq(EventResponse("foo", "bar", start, end, Seq(param1))), Seq(PatientResponse("nuh", Seq(param1))), Nil))
doMarshallingRoundTrip(ReadPreviousQueriesResponse(Seq(queryMaster1, queryMaster2)))
doMarshallingRoundTrip(ReadQueryDefinitionResponse(42L, "name", userId, start.get, queryDefinition.toXmlString))
doMarshallingRoundTrip(ReadQueryInstancesResponse(42L, userId, groupId, Seq(queryInstance1, queryInstance2)))
doMarshallingRoundTrip(RenameQueryResponse(12345L, queryName))
doMarshallingRoundTrip(RunQueryResponse(queryId, start.get, userId, groupId, queryDefinition, 12345L, singleNodeResult1))
doMarshallingRoundTrip(AggregatedRunQueryResponse(queryId, start.get, userId, groupId, queryDefinition, 12345L, Seq(singleNodeResult1, singleNodeResult2)))
doMarshallingRoundTrip(ReadResultResponse(42L, singleNodeResult2, envelope))
}
private def doMarshallingRoundTrip[T <: ShrineMessage](message: T) {
val xml = message.toXml
val unmarshalled = ShrineMessage.fromXml(DefaultBreakdownResultOutputTypes.toSet)(xml).get
message match {
//NB: Special handling of ReadInstanceResultsResponse because its member QueryRequests are munged
//before serialization
case readInstanceResultsResponse: ReadInstanceResultsResponse => {
val unmarshalledResp = unmarshalled.asInstanceOf[ReadInstanceResultsResponse]
val expected = readInstanceResultsResponse.copy(singleNodeResult = readInstanceResultsResponse.singleNodeResult.copy(instanceId = readInstanceResultsResponse.shrineNetworkQueryId))
unmarshalledResp should equal(expected)
}
//NB: Special handling of AggregatedReadInstanceResultsResponse because its member QueryRequests are munged
//before serialization
case aggReadInstanceResultsResponse: AggregatedReadInstanceResultsResponse => {
val unmarshalledResp = unmarshalled.asInstanceOf[AggregatedReadInstanceResultsResponse]
val expected = aggReadInstanceResultsResponse.copy(results = aggReadInstanceResultsResponse.results.map(_.copy(instanceId = aggReadInstanceResultsResponse.shrineNetworkQueryId)))
unmarshalledResp.results(0).problemDigest should equal(expected.results(0).problemDigest)
unmarshalledResp.results(0) should equal(expected.results(0))
unmarshalledResp.results should equal(expected.results)
unmarshalledResp should equal(expected)
}
//NB: Special handling of ReadQueryInstancesResponse because its member QueryInstances are not exactly preserved
//on serialization round trips
case readQueryInstancesResponse: ReadQueryInstancesResponse => {
val unmarshalledResp = unmarshalled.asInstanceOf[ReadQueryInstancesResponse]
val expected = unmarshalledResp.withInstances(unmarshalledResp.queryInstances.map(_.copy(queryMasterId = unmarshalledResp.queryMasterId.toString)))
}
//NB: Special handling of RunQueryResponse because its member QueryRequest is munged
//during serialization
case runQueryResponse: RunQueryResponse => {
val unmarshalledResp = unmarshalled.asInstanceOf[RunQueryResponse]
val expected = runQueryResponse.withResult(runQueryResponse.singleNodeResult.copy(instanceId = runQueryResponse.queryInstanceId))
unmarshalledResp should equal(expected)
}
//NB: Special handling of AggregatedRunQueryResponse because its member QueryRequests are munged
//during serialization
case aggRunQueryResponse: AggregatedRunQueryResponse => {
val unmarshalledResp = unmarshalled.asInstanceOf[AggregatedRunQueryResponse]
val expected = aggRunQueryResponse.withResults(aggRunQueryResponse.results.map(_.copy(instanceId = aggRunQueryResponse.queryInstanceId)))
unmarshalledResp should equal(expected)
}
case _ => unmarshalled should equal(message)
}
}
}
\ No newline at end of file
diff --git a/commons/protocol/src/test/scala/net/shrine/protocol/ShrineResponseTest.scala b/commons/protocol/src/test/scala/net/shrine/protocol/ShrineResponseTest.scala
index d676157a4..ecd4515b3 100644
--- a/commons/protocol/src/test/scala/net/shrine/protocol/ShrineResponseTest.scala
+++ b/commons/protocol/src/test/scala/net/shrine/protocol/ShrineResponseTest.scala
@@ -1,106 +1,106 @@
package net.shrine.protocol
import net.shrine.problem.TestProblem
import scala.xml.NodeSeq
import org.junit.Test
import net.shrine.util.ShouldMatchersForJUnit
import net.shrine.protocol.query.QueryDefinition
import net.shrine.protocol.query.Term
import net.shrine.util.XmlDateHelper
import net.shrine.util.XmlUtil
import scala.util.Success
/**
* @author clint
* @since Nov 5, 2012
*/
//noinspection UnitMethodIsParameterless,NameBooleanParameters,ScalaUnnecessaryParentheses
final class ShrineResponseTest extends ShouldMatchersForJUnit {
@Test
def testFromXml {
//ShrineResponse.fromXml(null: String).isFailure should be(true)
ShrineResponse.fromXml(DefaultBreakdownResultOutputTypes.toSet)(null: NodeSeq).isFailure should be(true)
ShrineResponse.fromXml(DefaultBreakdownResultOutputTypes.toSet)(NodeSeq.Empty).isFailure should be(true)
def roundTrip(response: ShrineResponse): Unit = {
val unmarshalled = ShrineResponse.fromXml(DefaultBreakdownResultOutputTypes.toSet)(response.toXml)
unmarshalled.get.getClass should equal(response.getClass)
unmarshalled should not be (null)
unmarshalled should equal(Success(response))
}
val queryResult1 = QueryResult(
resultId = 1L,
instanceId = 2342L,
resultType = Some(ResultOutputType.PATIENT_COUNT_XML),
setSize = 123L,
startDate = None,
endDate = None,
description = None,
statusType = QueryResult.StatusType.Finished,
statusMessage = None)
roundTrip(ReadQueryResultResponse(123L, queryResult1))
roundTrip(AggregatedReadQueryResultResponse(123L, Seq(queryResult1)))
roundTrip(DeleteQueryResponse(123L))
roundTrip(ReadInstanceResultsResponse(2342L, queryResult1))
roundTrip(AggregatedReadInstanceResultsResponse(2342L, Seq(queryResult1)))
roundTrip(ReadPreviousQueriesResponse(Seq(QueryMaster("queryMasterId", 12345L, "name", "userId", "groupId", XmlDateHelper.now, Some(false)))))
roundTrip(ReadQueryDefinitionResponse(8457L, "name", "userId", XmlDateHelper.now, "queryDefXml"))
roundTrip(ReadQueryInstancesResponse(12345L, "userId", "groupId", Seq.empty))
roundTrip(RenameQueryResponse(12345L, "name"))
roundTrip(RunQueryResponse(38957L, XmlDateHelper.now, "userId", "groupId", QueryDefinition("foo", Term("bar")), 2342L, queryResult1))
roundTrip(AggregatedRunQueryResponse(38957L, XmlDateHelper.now, "userId", "groupId", QueryDefinition("foo", Term("bar")), 2342L, Seq(queryResult1)))
roundTrip(UnFlagQueryResponse)
roundTrip(FlagQueryResponse)
- roundTrip(ErrorResponse("errorMessage",Some(TestProblem)))
+ roundTrip(ErrorResponse(TestProblem("errorMessage")))
}
@Test
def testToXml {
val response = new FooResponse
response.toXmlString should equal("")
}
@Test
def testToI2b2 {
val expected = XmlUtil.stripWhitespace(
1.1
2.4
SHRINE
1.3-compatible
SHRINE
2011-04-08T16:21:12.251-04:00
DONE
)
val response = new FooResponse
response.toI2b2String should equal(expected.toString())
}
private final class FooResponse extends ShrineResponse {
protected override def i2b2MessageBody =
override def toXml = i2b2MessageBody
}
}
\ No newline at end of file
diff --git a/commons/util/src/test/scala/net/shrine/problem/ProblemDigestTest.scala b/commons/util/src/test/scala/net/shrine/problem/ProblemDigestTest.scala
index b60492c8b..e84ae7f3e 100644
--- a/commons/util/src/test/scala/net/shrine/problem/ProblemDigestTest.scala
+++ b/commons/util/src/test/scala/net/shrine/problem/ProblemDigestTest.scala
@@ -1,26 +1,20 @@
package net.shrine.problem
import net.shrine.util.ShouldMatchersForJUnit
/**
*
* @author dwalend
* @since 1.20
*/
final class ProblemDigestTest extends ShouldMatchersForJUnit {
def testRoundTrip() = {
val problemDigest = ProblemDigest(getClass.getName, "stampText", "Test problem", "A problem for testing", "We use this problem for testing. Don't worry about it" )
val xml = problemDigest.toXml
val fromXml = ProblemDigest.fromXml(xml)
fromXml should be(problemDigest)
}
-}
-
-object TestProblem extends AbstractProblem(ProblemSources.Unknown) {
- override def summary: String = "Test problem summary"
-
- override def description: String = "Test problem description"
-}
+}
\ No newline at end of file
diff --git a/commons/util/src/test/scala/net/shrine/problem/ProblemHandlerTest.scala b/commons/util/src/test/scala/net/shrine/problem/ProblemHandlerTest.scala
index 533bfbf19..6b6bde240 100644
--- a/commons/util/src/test/scala/net/shrine/problem/ProblemHandlerTest.scala
+++ b/commons/util/src/test/scala/net/shrine/problem/ProblemHandlerTest.scala
@@ -1,69 +1,60 @@
package net.shrine.problem
import net.shrine.log.Loggable
import net.shrine.util.ShouldMatchersForJUnit
import org.apache.log4j.Level
import scala.collection.mutable.{Map => MMap}
/**
*
* @author dwalend
* @since 1.20
*/
final class ProblemHandlerTest extends ShouldMatchersForJUnit {
def testProblemHandler() = {
val loggable = new MockLoggable
- case class TestProblem(nodeName:String,summary:String,exception:Exception) extends AbstractProblem(ProblemSources.Hub) {
-
- val message = s"TestProblem involving $nodeName"
-
- val description = summary + message
-
- override def throwable = Some(exception)
- }
-
val fakeException = new RuntimeException("test exception")
fakeException.fillInStackTrace()
- val problem = TestProblem("testProblem","Problem created for testing",fakeException)
+ val problem = TestProblem("testProblem","Problem created for testing",Some(fakeException))
val problemHandler = LoggingProblemHandler
problemHandler.handleProblem(problem)
loggable.loggedAt(Level.ERROR) should be (right = true)
}
private final class MockLoggable extends Loggable {
val loggedAt: MMap[Level, Boolean] = MMap.empty
override def debug(s: => Any) {
loggedAt(Level.DEBUG) = true
super.debug(s)
}
override def info(s: => Any) {
loggedAt(Level.INFO) = true
super.info(s)
}
override def warn(s: => Any) {
loggedAt(Level.WARN) = true
super.warn(s)
}
override def error(s: => Any) {
loggedAt(Level.ERROR) = true
super.error(s)
}
}
}
\ No newline at end of file
diff --git a/commons/util/src/test/scala/net/shrine/problem/TestProblem.scala b/commons/util/src/test/scala/net/shrine/problem/TestProblem.scala
new file mode 100644
index 000000000..eeffb2e1b
--- /dev/null
+++ b/commons/util/src/test/scala/net/shrine/problem/TestProblem.scala
@@ -0,0 +1,9 @@
+package net.shrine.problem
+
+/**
+ * @author david
+ * @since 1.22
+ */
+case class TestProblem(override val summary: String = "test summary",
+ override val description:String = "test description",
+ override val throwable: Option[Throwable] = None) extends AbstractProblem(ProblemSources.Unknown)
diff --git a/hub/broadcaster-aggregator/src/test/scala/net/shrine/aggregation/ReadInstanceResultsAggregatorTest.scala b/hub/broadcaster-aggregator/src/test/scala/net/shrine/aggregation/ReadInstanceResultsAggregatorTest.scala
index 5c1faf6f3..bdc8f3529 100644
--- a/hub/broadcaster-aggregator/src/test/scala/net/shrine/aggregation/ReadInstanceResultsAggregatorTest.scala
+++ b/hub/broadcaster-aggregator/src/test/scala/net/shrine/aggregation/ReadInstanceResultsAggregatorTest.scala
@@ -1,107 +1,103 @@
package net.shrine.aggregation
-import net.shrine.problem.ProblemNotYetEncoded
-import org.junit.Test
-import org.junit.Assert.assertNotNull
-import net.shrine.protocol.{ ErrorResponse, QueryResult, ReadInstanceResultsResponse }
+import net.shrine.problem.TestProblem
import net.shrine.protocol.ResultOutputType._
-import net.shrine.util.XmlDateHelper
-import net.shrine.protocol.AggregatedReadInstanceResultsResponse
-import net.shrine.protocol.Result
-import net.shrine.protocol.NodeId
-import net.shrine.util.ShouldMatchersForJUnit
+import net.shrine.protocol.{AggregatedReadInstanceResultsResponse, ErrorResponse, NodeId, QueryResult, ReadInstanceResultsResponse, Result}
+import net.shrine.util.{ShouldMatchersForJUnit, XmlDateHelper}
+import org.junit.Assert.assertNotNull
+import org.junit.Test
/**
* @author Bill Simons
* @since 6/13/11
* @see http://cbmi.med.harvard.edu
* @see http://chip.org
*
* NOTICE: This software comes with NO guarantees whatsoever and is
* licensed as Lgpl Open Source
* @see http://www.gnu.org/licenses/lgpl.html
*/
//noinspection UnitMethodIsParameterless,NameBooleanParameters
final class ReadInstanceResultsAggregatorTest extends ShouldMatchersForJUnit {
import scala.concurrent.duration._
@Test
def testAggregate {
val instanceId = 123L
val startDate = XmlDateHelper.now
val endDate = XmlDateHelper.now
val queryResult1 = new QueryResult(1L, instanceId, PATIENT_COUNT_XML, 12, startDate, endDate, QueryResult.StatusType.Finished)
val queryResult2 = new QueryResult(2L, instanceId, PATIENT_COUNT_XML, 14, startDate, endDate, QueryResult.StatusType.Finished)
val aggregator = new ReadInstanceResultsAggregator(instanceId, true)
val aggregatorNoAggregate = new ReadInstanceResultsAggregator(instanceId, false)
val response1 = ReadInstanceResultsResponse(instanceId, queryResult1)
val response2 = ReadInstanceResultsResponse(instanceId, queryResult2)
val description1 = "NODE1"
val description2 = "NODE2"
val result1 = Result(NodeId(description1), 1.second, response1)
val result2 = Result(NodeId(description2), 5.seconds, response2)
{
val actual = aggregator.aggregate(Seq(result1, result2), Nil).asInstanceOf[AggregatedReadInstanceResultsResponse]
assertNotNull(actual)
assertNotNull(actual.results)
actual.results.size should equal(3)
val expectedTotal = queryResult1.setSize + queryResult2.setSize
actual.results.contains(queryResult1.withDescription(description1)) should be(true)
actual.results.contains(queryResult2.withDescription(description2).withResultType(PATIENT_COUNT_XML)) should be(true)
actual.results.exists(qr => qr.setSize == expectedTotal && qr.resultTypeIs(PATIENT_COUNT_XML) && qr.description.contains("Aggregated Count")) should be(true)
}
{
val actual = aggregatorNoAggregate.aggregate(Seq(result1, result2), Nil).asInstanceOf[AggregatedReadInstanceResultsResponse]
assertNotNull(actual)
assertNotNull(actual.results)
actual.results.size should equal(2)
actual.results.contains(queryResult1.withDescription(description1)) should be(true)
actual.results.contains(queryResult2.withDescription(description2).withResultType(PATIENT_COUNT_XML)) should be(true)
}
}
@Test
def testAggregateWithError {
val instanceId = 123L
val startDate = XmlDateHelper.now
val endDate = XmlDateHelper.now
val queryResult = new QueryResult(1L, instanceId, PATIENT_COUNT_XML, 12, startDate, endDate, QueryResult.StatusType.Finished)
val aggregator = new ReadInstanceResultsAggregator(instanceId, true)
val errorMessage = "you are an error"
val patientCountResponse = ReadInstanceResultsResponse(instanceId, queryResult)
- val errorResponse = ErrorResponse(errorMessage)
+ val errorResponse = ErrorResponse(TestProblem(errorMessage))
val patientCountNodeDescription = "NODE1"
val errorNodeDescription = "NODE2"
val result1 = Result(NodeId(patientCountNodeDescription), 1.minute, patientCountResponse)
val result2 = Result(NodeId(errorNodeDescription), 1.hour, errorResponse)
val actual = aggregator.aggregate(Seq(result1, result2), Nil).asInstanceOf[AggregatedReadInstanceResultsResponse]
assertNotNull(actual)
assertNotNull(actual.results)
actual.results.size should equal(3)
actual.results.contains(queryResult.withDescription(patientCountNodeDescription)) should be(true)
- actual.results.exists(qr => qr.problemDigest.exists(pd => pd.codec == classOf[ProblemNotYetEncoded].getName)) should be (true)
+ actual.results.exists(qr => qr.problemDigest.exists(pd => pd.codec == classOf[TestProblem].getName)) should be (true)
}
}
\ No newline at end of file
diff --git a/hub/broadcaster-aggregator/src/test/scala/net/shrine/aggregation/ReadQueryResultAggregatorTest.scala b/hub/broadcaster-aggregator/src/test/scala/net/shrine/aggregation/ReadQueryResultAggregatorTest.scala
index 19a38977a..b65e2dfcb 100644
--- a/hub/broadcaster-aggregator/src/test/scala/net/shrine/aggregation/ReadQueryResultAggregatorTest.scala
+++ b/hub/broadcaster-aggregator/src/test/scala/net/shrine/aggregation/ReadQueryResultAggregatorTest.scala
@@ -1,134 +1,125 @@
package net.shrine.aggregation
-import net.shrine.problem.ProblemNotYetEncoded
-
-import scala.concurrent.duration.DurationInt
-import org.junit.Test
+import net.shrine.problem.TestProblem
+import net.shrine.protocol.{AggregatedReadQueryResultResponse, BaseShrineResponse, ErrorResponse, NodeId, QueryResult, ReadQueryResultResponse, Result, ResultOutputType}
import net.shrine.util.ShouldMatchersForJUnit
-import net.shrine.protocol.AggregatedReadQueryResultResponse
-import net.shrine.protocol.ErrorResponse
-import net.shrine.protocol.NodeId
-import net.shrine.protocol.QueryResult
-import net.shrine.protocol.ReadQueryResultResponse
-import net.shrine.protocol.Result
-import net.shrine.protocol.ResultOutputType
-import net.shrine.protocol.BaseShrineResponse
+import org.junit.Test
/**
* @author clint
* @since Nov 7, 2012
*/
final class ReadQueryResultAggregatorTest extends ShouldMatchersForJUnit {
private val queryId = 12345L
import ResultOutputType._
private def asAggregatedResponse(resp: BaseShrineResponse) = resp.asInstanceOf[AggregatedReadQueryResultResponse]
private val setSize1 = 123L
private val setSize2 = 456L
private val totalSetSize = setSize1 + setSize2
private val queryResult1 = QueryResult(1L, 2L, Some(PATIENT_COUNT_XML), setSize1, None, None, None, QueryResult.StatusType.Finished, None)
private val queryResult2 = QueryResult(1L, 2L, Some(PATIENT_COUNT_XML), setSize2, None, None, None, QueryResult.StatusType.Finished, None)
private val response1 = ReadQueryResultResponse(queryId, queryResult1)
private val response2 = ReadQueryResultResponse(queryId, queryResult2)
import scala.concurrent.duration._
private val result1 = Result(NodeId("X"), 1.second, response1)
private val result2 = Result(NodeId("Y"), 1.second, response2)
- private val errors = Seq(ErrorResponse("blarg"), ErrorResponse("glarg"))
+ private val errors = Seq(ErrorResponse(TestProblem(summary ="blarg")), ErrorResponse(TestProblem(summary = "glarg")))
@Test
def testAggregate {
val aggregator = new ReadQueryResultAggregator(queryId, true)
val response = asAggregatedResponse(aggregator.aggregate(Seq(result1, result2), Nil))
val Seq(actualQueryResult1, actualQueryResult2, aggregatedQueryResult) = response.results
actualQueryResult1 should equal(queryResult1)
actualQueryResult2 should equal(queryResult2)
val expectedAggregatedResult = queryResult1.withSetSize(totalSetSize).withInstanceId(queryId).withDescription("Aggregated Count")
aggregatedQueryResult should equal(expectedAggregatedResult)
}
@Test
def testAggregateNoAggregatedResult {
val aggregator = new ReadQueryResultAggregator(queryId, false)
val response = asAggregatedResponse(aggregator.aggregate(Seq(result1, result2), Nil))
val Seq(actualQueryResult1, actualQueryResult2) = response.results
actualQueryResult1 should equal(queryResult1)
actualQueryResult2 should equal(queryResult2)
}
@Test
def testAggregateNoResponses {
for (doAggregation <- Seq(true, false)) {
val aggregator = new ReadQueryResultAggregator(queryId, true)
val response = asAggregatedResponse(aggregator.aggregate(Nil, Nil))
response.queryId should equal(queryId)
response.results.isEmpty should be(true)
}
}
@Test
def testAggregateOnlyErrorResponses {
val aggregator = new ReadQueryResultAggregator(queryId, true)
val response = asAggregatedResponse(aggregator.aggregate(Nil, errors))
response.queryId should equal(queryId)
- response.results.exists(qr => qr.problemDigest.exists(pd => pd.codec == classOf[ProblemNotYetEncoded].getName)) should be (true)
+ response.results.exists(qr => qr.problemDigest.exists(pd => pd.codec == classOf[TestProblem].getName)) should be (true)
}
@Test
def testAggregateSomeErrors {
val aggregator = new ReadQueryResultAggregator(queryId, true)
val response = asAggregatedResponse(aggregator.aggregate(Seq(result1, result2), errors))
val Seq(actualQueryResult1, actualQueryResult2, aggregatedQueryResult, actualErrorQueryResults @ _*) = response.results
actualQueryResult1 should equal(queryResult1)
actualQueryResult2 should equal(queryResult2)
val expectedAggregatedResult = queryResult1.withSetSize(totalSetSize).withInstanceId(queryId).withDescription("Aggregated Count")
aggregatedQueryResult should equal(expectedAggregatedResult)
- actualErrorQueryResults.exists(qr => qr.problemDigest.exists(pd => pd.codec == classOf[ProblemNotYetEncoded].getName)) should be (true)
+ actualErrorQueryResults.exists(qr => qr.problemDigest.exists(pd => pd.codec == classOf[TestProblem].getName)) should be (true)
}
@Test
def testAggregateSomeDownstreamErrors {
val aggregator = new ReadQueryResultAggregator(queryId, true)
val result3 = Result(NodeId("A"), 1.second, errors.head)
val result4 = Result(NodeId("A"), 1.second, errors.last)
val response = asAggregatedResponse(aggregator.aggregate(Seq(result1, result2, result3, result4), Nil))
val Seq(actualQueryResult1, actualQueryResult2, aggregatedQueryResult, actualErrorQueryResults @ _*) = response.results
actualQueryResult1 should equal(queryResult1)
actualQueryResult2 should equal(queryResult2)
val expectedAggregatedResult = queryResult1.withSetSize(totalSetSize).withInstanceId(queryId).withDescription("Aggregated Count")
aggregatedQueryResult should equal(expectedAggregatedResult)
actualErrorQueryResults.forall(qr => qr.description.contains("A")) should be(true)
}
}
\ No newline at end of file
diff --git a/hub/broadcaster-aggregator/src/test/scala/net/shrine/aggregation/RunQueryAggregatorTest.scala b/hub/broadcaster-aggregator/src/test/scala/net/shrine/aggregation/RunQueryAggregatorTest.scala
index 859fc729a..8a2387f1e 100644
--- a/hub/broadcaster-aggregator/src/test/scala/net/shrine/aggregation/RunQueryAggregatorTest.scala
+++ b/hub/broadcaster-aggregator/src/test/scala/net/shrine/aggregation/RunQueryAggregatorTest.scala
@@ -1,148 +1,150 @@
package net.shrine.aggregation
+import net.shrine.problem.TestProblem
+
import scala.concurrent.duration.DurationInt
import org.junit.Test
import net.shrine.util.ShouldMatchersForJUnit
import net.shrine.protocol.AggregatedRunQueryResponse
import net.shrine.protocol.ErrorResponse
import net.shrine.protocol.I2b2ResultEnvelope
import net.shrine.protocol.NodeId
import net.shrine.protocol.QueryResult
import net.shrine.protocol.Result
import net.shrine.protocol.ResultOutputType.PATIENT_COUNT_XML
import net.shrine.protocol.RunQueryResponse
import net.shrine.protocol.query.QueryDefinition
import net.shrine.protocol.query.Term
import net.shrine.util.XmlDateHelper
import net.shrine.protocol.DefaultBreakdownResultOutputTypes
/**
*
*
* @author Justin Quan
* @see http://chip.org
* Date: 8/12/11
*/
final class RunQueryAggregatorTest extends ShouldMatchersForJUnit {
private val queryId = 1234L
private val queryName = "someQueryName"
private val now = XmlDateHelper.now
private val userId = "user"
private val groupId = "group"
private val requestQueryDef = QueryDefinition(queryName, Term("""\\i2b2\i2b2\Demographics\Age\0-9 years old\"""))
private val requestQueryDefString = requestQueryDef.toI2b2String
private val queryInstanceId = 9999L
import scala.concurrent.duration._
@Test
def testAggregate {
val qrCount = new QueryResult(1L, queryInstanceId, PATIENT_COUNT_XML, 10L, now, now, "Desc", QueryResult.StatusType.Finished)
val rqr1 = RunQueryResponse(queryId, now, userId, groupId, requestQueryDef, queryInstanceId, qrCount)
val result1 = Result(NodeId("description2"), 1.second, rqr1)
val aggregator = new RunQueryAggregator(queryId, userId, groupId, requestQueryDef, true)
val actual = aggregator.aggregate(Vector(result1), Nil).asInstanceOf[AggregatedRunQueryResponse]
actual.queryId should equal(queryId)
actual.queryInstanceId should equal(-1L)
actual.results.size should equal(2)
actual.results.filter(_.resultTypeIs(PATIENT_COUNT_XML)).size should equal(2) //1 for the actual count result, 1 for the aggregated total count
actual.results.filter(hasTotalCount).size should equal(1)
actual.results.filter(hasTotalCount).head.setSize should equal(10)
actual.queryName should equal(queryName)
}
@Test
def testAggCount {
val qrSet = new QueryResult(2L, queryInstanceId, PATIENT_COUNT_XML, 10L, now, now, "Desc", QueryResult.StatusType.Finished)
val rqr1 = RunQueryResponse(queryId, now, userId, groupId, requestQueryDef, queryInstanceId, qrSet)
val rqr2 = RunQueryResponse(queryId, now, userId, groupId, requestQueryDef, queryInstanceId, qrSet)
val result1 = Result(NodeId("description1"), 1.second, rqr1)
val result2 = Result(NodeId("description2"), 1.second, rqr2)
val aggregator = new RunQueryAggregator(queryId, userId, groupId, requestQueryDef, true)
//TODO: test handling error responses
val actual = aggregator.aggregate(Vector(result1, result2), Nil).asInstanceOf[AggregatedRunQueryResponse]
actual.results.filter(_.description.getOrElse("").equalsIgnoreCase("TOTAL COUNT")).head.setSize should equal(20)
}
@Test
def testHandleErrorResponse {
val qrCount = new QueryResult(1L, queryInstanceId, PATIENT_COUNT_XML, 10L, now, now, "Desc", QueryResult.StatusType.Finished)
val rqr1 = RunQueryResponse(queryId, now, userId, groupId, requestQueryDef, queryInstanceId, qrCount)
val errorMessage = "error message"
- val errorResponse = ErrorResponse(errorMessage)
+ val errorResponse = ErrorResponse(TestProblem(summary = errorMessage))
val result1 = Result(NodeId("description1"), 1.second, rqr1)
val result2 = Result(NodeId("description2"), 1.second, errorResponse)
val aggregator = new RunQueryAggregator(queryId, userId, groupId, requestQueryDef, true)
val actual = aggregator.aggregate(Vector(result1, result2), Nil).asInstanceOf[AggregatedRunQueryResponse]
actual.results.size should equal(3)
actual.results.filter(_.resultTypeIs(PATIENT_COUNT_XML)).head.setSize should equal(10)
actual.results.filter(_.statusType == QueryResult.StatusType.Error).head.statusMessage should equal(Some(errorMessage))
actual.results.filter(hasTotalCount).head.setSize should equal(10)
}
@Test
def testAggregateResponsesWithBreakdowns {
def toColumnTuple(i: Int) = ("x" + i, i.toLong)
val breakdowns1 = Map.empty ++ DefaultBreakdownResultOutputTypes.values.map { resultType =>
resultType -> I2b2ResultEnvelope(resultType, (1 to 10).map(toColumnTuple).toMap)
}
val breakdowns2 = Map.empty ++ DefaultBreakdownResultOutputTypes.values.map { resultType =>
resultType -> I2b2ResultEnvelope(resultType, (11 to 20).map(toColumnTuple).toMap)
}
val qr1 = new QueryResult(1L, queryInstanceId, Some(PATIENT_COUNT_XML), 10L, Some(now), Some(now), Some("Desc"), QueryResult.StatusType.Finished, None, breakdowns = breakdowns1)
val qr2 = new QueryResult(2L, queryInstanceId, Some(PATIENT_COUNT_XML), 20L, Some(now), Some(now), Some("Desc"), QueryResult.StatusType.Finished, None, breakdowns = breakdowns2)
val rqr1 = RunQueryResponse(queryId, now, userId, groupId, requestQueryDef, queryInstanceId, qr1)
val rqr2 = RunQueryResponse(queryId, now, userId, groupId, requestQueryDef, queryInstanceId, qr2)
val result1 = Result(NodeId("description2"), 1.second, rqr1)
val result2 = Result(NodeId("description1"), 1.second, rqr2)
val aggregator = new RunQueryAggregator(queryId, userId, groupId, requestQueryDef, true)
val actual = aggregator.aggregate(Seq(result1, result2), Nil).asInstanceOf[AggregatedRunQueryResponse]
actual.results.size should equal(3)
actual.results.filter(hasTotalCount).size should equal(1)
val Seq(actualQr1, actualQr2, actualQr3) = actual.results.filter(_.resultTypeIs(PATIENT_COUNT_XML))
actualQr1.setSize should equal(10)
actualQr2.setSize should equal(20)
actualQr3.setSize should equal(30)
actualQr1.breakdowns should equal(breakdowns1)
actualQr2.breakdowns should equal(breakdowns2)
actualQr3.breakdowns.isEmpty should be(true)
}
private def hasTotalCount(result: QueryResult) = result.description.getOrElse("").equalsIgnoreCase("TOTAL COUNT")
private def toQueryResultMap(results: QueryResult*) = Map.empty ++ (for {
result <- results
resultType <- result.resultType
} yield (resultType, result))
}
diff --git a/hub/broadcaster-aggregator/src/test/scala/net/shrine/broadcaster/HubBroadcastServiceTest.scala b/hub/broadcaster-aggregator/src/test/scala/net/shrine/broadcaster/HubBroadcastServiceTest.scala
index 700cc38e8..acdf16070 100644
--- a/hub/broadcaster-aggregator/src/test/scala/net/shrine/broadcaster/HubBroadcastServiceTest.scala
+++ b/hub/broadcaster-aggregator/src/test/scala/net/shrine/broadcaster/HubBroadcastServiceTest.scala
@@ -1,100 +1,88 @@
package net.shrine.broadcaster
+import net.shrine.aggregation.Aggregator
import net.shrine.problem.TestProblem
+import net.shrine.protocol.{AuthenticationInfo, BroadcastMessage, Credential, DeleteQueryRequest, ErrorResponse, Failure, NodeId, Result, ShrineResponse, SingleNodeResult, Timeout}
+import net.shrine.util.ShouldMatchersForJUnit
+import org.junit.Test
import scala.concurrent.Await
-import org.junit.Test
-import net.shrine.util.ShouldMatchersForJUnit
-import net.shrine.aggregation.Aggregator
-import net.shrine.crypto.DefaultSignerVerifier
-import net.shrine.crypto.TestKeystore
-import net.shrine.protocol.AuthenticationInfo
-import net.shrine.protocol.BroadcastMessage
-import net.shrine.protocol.Credential
-import net.shrine.protocol.DeleteQueryRequest
-import net.shrine.protocol.ErrorResponse
-import net.shrine.protocol.Failure
-import net.shrine.protocol.NodeId
-import net.shrine.protocol.Result
-import net.shrine.protocol.ShrineResponse
-import net.shrine.protocol.SingleNodeResult
-import net.shrine.protocol.Timeout
-import net.shrine.broadcaster.dao.MockHubDao
/**
* @author clint
* @since Nov 19, 2013
*/
final class HubBroadcastAndAggregationServiceTest extends AbstractSquerylHubDaoTest with ShouldMatchersForJUnit {
- import scala.concurrent.duration._
import MockBroadcasters._
- private def result(description: Char) = Result(NodeId(description.toString), 1.second, ErrorResponse("blah blah blah",Some(TestProblem)))
+ import scala.concurrent.duration._
+
+ private def result(description: Char) = Result(NodeId(description.toString), 1.second, ErrorResponse(TestProblem(summary = "blah blah blah")))
private val results = "abcde".map(result)
private lazy val nullResultsByOrigin: Map[NodeId, SingleNodeResult] = Map(NodeId("X") -> null, NodeId("Y") -> null)
private lazy val resultsWithNullsByOrigin: Map[NodeId, SingleNodeResult] = {
results.collect { case r @ Result(origin, _, _) => origin -> r }.toMap ++ nullResultsByOrigin
}
private val broadcastMessage = {
val authn = AuthenticationInfo("domain", "username", Credential("asdasd", false))
import scala.concurrent.duration._
BroadcastMessage(authn, DeleteQueryRequest("projectId", 12345.milliseconds, authn, 12345L))
}
@Test
def testAggregateHandlesNullResults {
val mockBroadcaster = MockAdapterClientBroadcaster(resultsWithNullsByOrigin)
val broadcastService = new HubBroadcastAndAggregationService(InJvmBroadcasterClient(mockBroadcaster))
val aggregator: Aggregator = new Aggregator {
override def aggregate(results: Iterable[SingleNodeResult], errors: Iterable[ErrorResponse]): ShrineResponse = {
- ErrorResponse(results.size.toString,Some(TestProblem))
+ ErrorResponse(TestProblem(summary = results.size.toString))
}
}
val aggregatedResult = Await.result(broadcastService.sendAndAggregate(broadcastMessage, aggregator, true), 5.minutes)
mockBroadcaster.messageParam.signature.isDefined should be(false)
- aggregatedResult should equal(ErrorResponse(s"${results.size}",Some(TestProblem)))
+ aggregatedResult should equal(ErrorResponse(TestProblem(summary = results.size.toString)))
}
@Test
def testAggregateHandlesFailures {
- def toResult(description: Char) = Result(NodeId(description.toString), 1.second, ErrorResponse("blah blah blah"))
+ def toResult(description: Char) = Result(NodeId(description.toString), 1.second, ErrorResponse(TestProblem(summary = "blah blah blah")))
def toFailure(description: Char) = Failure(NodeId(description.toString), new Exception with scala.util.control.NoStackTrace)
val failuresByOrigin: Map[NodeId, SingleNodeResult] = {
"UV".map(toFailure).map { case f @ Failure(origin, _) => origin -> f }.toMap
}
val timeoutsByOrigin: Map[NodeId, SingleNodeResult] = Map(NodeId("Z") -> Timeout(NodeId("Z")))
val resultsWithFailuresByOrigin: Map[NodeId, SingleNodeResult] = resultsWithNullsByOrigin ++ failuresByOrigin ++ timeoutsByOrigin
val mockBroadcaster = MockAdapterClientBroadcaster(resultsWithFailuresByOrigin)
val broadcastService = new HubBroadcastAndAggregationService(InJvmBroadcasterClient(mockBroadcaster))
val aggregator: Aggregator = new Aggregator {
override def aggregate(results: Iterable[SingleNodeResult], errors: Iterable[ErrorResponse]): ShrineResponse = {
- ErrorResponse(s"${results.size},${errors.size}",Some(TestProblem))
+ ErrorResponse(TestProblem(summary = s"${results.size},${errors.size}"))
}
}
val aggregatedResult = Await.result(broadcastService.sendAndAggregate(broadcastMessage, aggregator, true), 5.minutes)
mockBroadcaster.messageParam.signature.isDefined should be(false)
- aggregatedResult should equal(ErrorResponse(s"${results.size + failuresByOrigin.size + timeoutsByOrigin.size},0",Some(TestProblem)))
+ aggregatedResult should equal(ErrorResponse(TestProblem(summary = s"${results.size + failuresByOrigin.size + timeoutsByOrigin.size},0")))
}
}
diff --git a/hub/broadcaster-aggregator/src/test/scala/net/shrine/broadcaster/SigningBroadcastAndAggregationServiceTest.scala b/hub/broadcaster-aggregator/src/test/scala/net/shrine/broadcaster/SigningBroadcastAndAggregationServiceTest.scala
index 28f37e2e2..561476d7a 100644
--- a/hub/broadcaster-aggregator/src/test/scala/net/shrine/broadcaster/SigningBroadcastAndAggregationServiceTest.scala
+++ b/hub/broadcaster-aggregator/src/test/scala/net/shrine/broadcaster/SigningBroadcastAndAggregationServiceTest.scala
@@ -1,102 +1,102 @@
package net.shrine.broadcaster
import net.shrine.problem.TestProblem
import scala.concurrent.Await
import org.junit.Test
import net.shrine.util.ShouldMatchersForJUnit
import net.shrine.aggregation.Aggregator
import net.shrine.crypto.DefaultSignerVerifier
import net.shrine.crypto.TestKeystore
import net.shrine.protocol.AuthenticationInfo
import net.shrine.protocol.BroadcastMessage
import net.shrine.protocol.Credential
import net.shrine.protocol.DeleteQueryRequest
import net.shrine.protocol.ErrorResponse
import net.shrine.protocol.Failure
import net.shrine.protocol.NodeId
import net.shrine.protocol.Result
import net.shrine.protocol.ShrineResponse
import net.shrine.protocol.SingleNodeResult
import net.shrine.protocol.Timeout
import net.shrine.crypto.SigningCertStrategy
import net.shrine.broadcaster.dao.MockHubDao
/**
* @author clint
* @since Nov 19, 2013
*/
final class SigningBroadcastAndAggregationServiceTest extends ShouldMatchersForJUnit {
import scala.concurrent.duration._
import MockBroadcasters._
- private def result(description: Char) = Result(NodeId(description.toString), 1.second, ErrorResponse("blah blah blah",Some(TestProblem)))
+ private def result(description: Char) = Result(NodeId(description.toString), 1.second, ErrorResponse(TestProblem(summary = "blah blah blah")))
private val results = "abcde".map(result)
private lazy val nullResultsByOrigin: Map[NodeId, SingleNodeResult] = Map(NodeId("X") -> null, NodeId("Y") -> null)
private lazy val resultsWithNullsByOrigin: Map[NodeId, SingleNodeResult] = {
results.collect { case r @ Result(origin, _, _) => origin -> r }.toMap ++ nullResultsByOrigin
}
private lazy val signer = new DefaultSignerVerifier(TestKeystore.certCollection)
private val broadcastMessage = {
val authn = AuthenticationInfo("domain", "username", Credential("asdasd", false))
import scala.concurrent.duration._
BroadcastMessage(authn, DeleteQueryRequest("projectId", 12345.milliseconds, authn, 12345L))
}
@Test
def testAggregateHandlesNullResults {
val mockBroadcaster = MockAdapterClientBroadcaster(resultsWithNullsByOrigin)
val broadcastService = SigningBroadcastAndAggregationService(InJvmBroadcasterClient(mockBroadcaster), signer, SigningCertStrategy.Attach)
val aggregator: Aggregator = new Aggregator {
override def aggregate(results: Iterable[SingleNodeResult], errors: Iterable[ErrorResponse]): ShrineResponse = {
- ErrorResponse(results.size.toString,Some(TestProblem))
+ ErrorResponse(TestProblem(results.size.toString))
}
}
val aggregatedResult = Await.result(broadcastService.sendAndAggregate(broadcastMessage, aggregator, true), 5.minutes)
mockBroadcaster.messageParam.signature.isDefined should be(true)
- aggregatedResult should equal(ErrorResponse(s"${results.size}",Some(TestProblem)))
+ aggregatedResult should equal(ErrorResponse(TestProblem(s"${results.size}")))
}
@Test
def testAggregateHandlesFailures {
- def toResult(description: Char) = Result(NodeId(description.toString), 1.second, ErrorResponse("blah blah blah",Some(TestProblem)))
+ def toResult(description: Char) = Result(NodeId(description.toString), 1.second, ErrorResponse(TestProblem("blah blah blah")))
def toFailure(description: Char) = Failure(NodeId(description.toString), new Exception with scala.util.control.NoStackTrace)
val failuresByOrigin: Map[NodeId, SingleNodeResult] = {
"UV".map(toFailure).map { case f @ Failure(origin, _) => origin -> f }.toMap
}
val timeoutsByOrigin: Map[NodeId, SingleNodeResult] = Map(NodeId("Z") -> Timeout(NodeId("Z")))
val resultsWithFailuresByOrigin: Map[NodeId, SingleNodeResult] = resultsWithNullsByOrigin ++ failuresByOrigin ++ timeoutsByOrigin
val mockBroadcaster = MockAdapterClientBroadcaster(resultsWithFailuresByOrigin)
val broadcastService = SigningBroadcastAndAggregationService(InJvmBroadcasterClient(mockBroadcaster), signer, SigningCertStrategy.DontAttach)
val aggregator: Aggregator = new Aggregator {
override def aggregate(results: Iterable[SingleNodeResult], errors: Iterable[ErrorResponse]): ShrineResponse = {
- ErrorResponse(s"${results.size},${errors.size}",Some(TestProblem))
+ ErrorResponse(TestProblem(s"${results.size},${errors.size}"))
}
}
val aggregatedResult = Await.result(broadcastService.sendAndAggregate(broadcastMessage, aggregator, true), 5.minutes)
mockBroadcaster.messageParam.signature.isDefined should be(true)
- aggregatedResult should equal(ErrorResponse(s"${results.size + failuresByOrigin.size + timeoutsByOrigin.size},0",Some(TestProblem)))
+ aggregatedResult should equal(ErrorResponse(TestProblem(s"${results.size + failuresByOrigin.size + timeoutsByOrigin.size},0")))
}
}
diff --git a/qep/service/src/test/scala/net/shrine/qep/queries/QepQueryDbTest.scala b/qep/service/src/test/scala/net/shrine/qep/queries/QepQueryDbTest.scala
index b8c75829f..8369d13d4 100644
--- a/qep/service/src/test/scala/net/shrine/qep/queries/QepQueryDbTest.scala
+++ b/qep/service/src/test/scala/net/shrine/qep/queries/QepQueryDbTest.scala
@@ -1,237 +1,237 @@
package net.shrine.qep.queries
import net.shrine.protocol.QueryResult.StatusType
import net.shrine.protocol.{I2b2ResultEnvelope, DefaultBreakdownResultOutputTypes, QueryResult, ResultOutputType}
import net.shrine.util.{XmlDateHelper, ShouldMatchersForJUnit}
import org.junit.{After, Before, Test}
import net.shrine.problem.TestProblem
/**
* @author david
* @since 1/20/16
*/
class QepQueryDbTest extends ShouldMatchersForJUnit {
val qepQuery = QepQuery(
networkId = 1L,
userName = "ben",
userDomain = "testDomain",
queryName = "testQuery",
expression = Some("testExpression"),
dateCreated = System.currentTimeMillis(),
deleted = false,
queryXml = "testXML",
changeDate = System.currentTimeMillis()
)
val secondQepQuery = QepQuery(
networkId = 2L,
userName = "dave",
userDomain = "testDomain",
queryName = "testQuery",
expression = Some("testExpression"),
deleted = false,
dateCreated = System.currentTimeMillis(),
queryXml = "testXML",
changeDate = System.currentTimeMillis()
)
val flag = QepQueryFlag(
networkQueryId = 1L,
flagged = true,
flagMessage = "This query is flagged",
changeDate = System.currentTimeMillis()
)
@Test
def testInsertQepQuery() {
QepQueryDb.db.insertQepQuery(qepQuery)
QepQueryDb.db.insertQepQuery(secondQepQuery)
val results = QepQueryDb.db.selectAllQepQueries
results should equal(Seq(qepQuery,secondQepQuery))
}
@Test
def testSelectQepQueriesForUser() {
QepQueryDb.db.insertQepQuery(qepQuery)
QepQueryDb.db.insertQepQuery(secondQepQuery)
val results = QepQueryDb.db.selectPreviousQueriesByUserAndDomain("ben","testDomain",100)
results should equal(Seq(qepQuery))
}
@Test
def testSelectQueryFlags() {
val results1 = QepQueryDb.db.selectMostRecentQepQueryFlagsFor(Set(1L,2L))
results1 should equal(Map.empty)
QepQueryDb.db.insertQepQueryFlag(flag)
val results2 = QepQueryDb.db.selectMostRecentQepQueryFlagsFor(Set(1L,2L))
results2 should equal(Map(1L -> flag))
}
val qepResultRowFromExampleCom = QueryResultRow(
resultId = 10L,
networkQueryId = 1L,
instanceId = 100L,
adapterNode = "example.com",
resultType = Some(ResultOutputType.PATIENT_COUNT_XML),
size = 30L,
startDate = Some(System.currentTimeMillis() - 60),
endDate = Some(System.currentTimeMillis() - 30),
status = QueryResult.StatusType.Finished,
statusMessage = None,
changeDate = System.currentTimeMillis()
)
@Test
def testInsertQueryResultRow() {
QepQueryDb.db.insertQepResultRow(qepResultRowFromExampleCom)
val results = QepQueryDb.db.selectMostRecentQepResultRowsFor(1L)
results should equal(Seq(qepResultRowFromExampleCom))
}
val queryResult = QueryResult(
resultId = 20L,
instanceId = 200L,
resultType = Some(ResultOutputType.PATIENT_COUNT_XML),
setSize = 2000L,
startDate = Some(XmlDateHelper.now),
endDate = Some(XmlDateHelper.now),
description = Some("example.com"),
statusType = StatusType.Finished,
statusMessage = None
)
@Test
def testInsertQueryResult(): Unit = {
QepQueryDb.db.insertQueryResult(2L,queryResult)
val results = QepQueryDb.db.selectMostRecentQepResultsFor(2L)
results should equal(Seq(queryResult))
}
val qepResultRowFromExampleComInThePast = QueryResultRow(
resultId = 8L,
networkQueryId = 1L,
instanceId = 100L,
adapterNode = "example.com",
resultType = Some(ResultOutputType.PATIENT_COUNT_XML),
size = 0L,
startDate = qepResultRowFromExampleCom.startDate,
endDate = None,
status = QueryResult.StatusType.Processing,
statusMessage = None,
changeDate = qepResultRowFromExampleCom.changeDate - 40
)
val qepResultRowFromGeneralHospital = QueryResultRow(
resultId = 100L,
networkQueryId = 1L,
instanceId = 100L,
adapterNode = "generalhospital.org",
resultType = Some(ResultOutputType.PATIENT_COUNT_XML),
size = 100L,
startDate = Some(System.currentTimeMillis() - 60),
endDate = Some(System.currentTimeMillis() - 30),
status = QueryResult.StatusType.Finished,
statusMessage = None,
changeDate = System.currentTimeMillis()
)
@Test
def testGetMostRecentResultRows() {
QepQueryDb.db.insertQepResultRow(qepResultRowFromExampleComInThePast)
QepQueryDb.db.insertQepResultRow(qepResultRowFromGeneralHospital)
QepQueryDb.db.insertQepResultRow(qepResultRowFromExampleCom)
val results = QepQueryDb.db.selectMostRecentQepResultRowsFor(1L)
results.to[Set] should equal(Set(qepResultRowFromExampleCom,qepResultRowFromGeneralHospital))
}
val maleRow = QepQueryBreakdownResultsRow(
networkQueryId = 1L,
adapterNode = "example.com",
resultId = 100L,
resultType = DefaultBreakdownResultOutputTypes.PATIENT_GENDER_COUNT_XML,
dataKey = "male",
value = 388,
changeDate = System.currentTimeMillis()
)
val femaleRow = QepQueryBreakdownResultsRow(
networkQueryId = 1L,
adapterNode = "example.com",
resultId = 100L,
resultType = DefaultBreakdownResultOutputTypes.PATIENT_GENDER_COUNT_XML,
dataKey = "female",
value = 390,
changeDate = System.currentTimeMillis()
)
val unknownRow = QepQueryBreakdownResultsRow(
networkQueryId = 1L,
adapterNode = "example.com",
resultId = 100L,
resultType = DefaultBreakdownResultOutputTypes.PATIENT_GENDER_COUNT_XML,
dataKey = "unknown",
value = 4,
changeDate = System.currentTimeMillis()
)
@Test
def testInsertBreakdownRows(): Unit = {
QepQueryDb.db.insertQueryBreakdown(maleRow)
QepQueryDb.db.insertQueryBreakdown(femaleRow)
QepQueryDb.db.insertQueryBreakdown(unknownRow)
val results = QepQueryDb.db.selectAllBreakdownResultsRows
results.to[Set] should equal(Set(maleRow,femaleRow,unknownRow))
}
val breakdowns = Map(DefaultBreakdownResultOutputTypes.PATIENT_GENDER_COUNT_XML -> I2b2ResultEnvelope(DefaultBreakdownResultOutputTypes.PATIENT_GENDER_COUNT_XML,Map("male" -> 3000,"female" -> 4000,"unknown" -> 234)))
@Test
def testInsertQueryResultWithBreakdowns(): Unit = {
val queryResultWithBreakdowns = queryResult.copy(breakdowns = breakdowns)
QepQueryDb.db.insertQueryResult(2L,queryResultWithBreakdowns)
val results = QepQueryDb.db.selectMostRecentQepResultsFor(2L)
results should equal(Seq(queryResultWithBreakdowns))
}
@Test
def testInsertQueryResultWithProblem(): Unit = {
- val queryResultWithProblem = queryResult.copy(statusType = StatusType.Error,problemDigest = Some(TestProblem.toDigest))
+ val queryResultWithProblem = queryResult.copy(statusType = StatusType.Error,problemDigest = Some(TestProblem().toDigest))
QepQueryDb.db.insertQueryResult(2L,queryResultWithProblem)
val results = QepQueryDb.db.selectMostRecentQepResultsFor(2L)
results should equal(Seq(queryResultWithProblem))
}
@Before
def beforeEach() = {
QepQueryDb.db.createTables()
}
@After
def afterEach() = {
QepQueryDb.db.dropTables()
}
}