Skip to content

Commit

Permalink
#53 Make parameter CortexId optional on job submit
Browse files Browse the repository at this point in the history
  • Loading branch information
To-om committed Dec 12, 2016
1 parent eccdf68 commit 78c0687
Show file tree
Hide file tree
Showing 3 changed files with 39 additions and 29 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -32,11 +32,11 @@ class CortexClient(val name: String, baseUrl: String, key: String) {
}

def getAnalyzer(analyzerId: String)(implicit ws: WSClient, ec: ExecutionContext): Future[Analyzer] = {
request(s"/api/analyzer/$analyzerId", _.get, _.json.as[Analyzer])
request(s"/api/analyzer/$analyzerId", _.get, _.json.as[Analyzer]).map(_.copy(cortexIds = List(name)))
}

def listAnalyzer(implicit ws: WSClient, ec: ExecutionContext): Future[Seq[Analyzer]] = {
request(s"/api/analyzer", _.get, _.json.as[Seq[Analyzer]])
request(s"/api/analyzer", _.get, _.json.as[Seq[Analyzer]]).map(_.map(_.copy(cortexIds = List(name))))
}

def analyze(analyzerId: String, artifact: CortexArtifact)(implicit ws: WSClient, ec: ExecutionContext) = {
Expand All @@ -52,7 +52,7 @@ class CortexClient(val name: String, baseUrl: String, key: String) {
}

def listAnalyzerForType(dataType: String)(implicit ws: WSClient, ec: ExecutionContext): Future[Seq[Analyzer]] = {
request(s"/api/analyzer/type/$dataType", _.get, _.json.as[Seq[Analyzer]])
request(s"/api/analyzer/type/$dataType", _.get, _.json.as[Seq[Analyzer]]).map(_.map(_.copy(cortexIds = List(name))))
}

def listJob(implicit ws: WSClient, ec: ExecutionContext) = {
Expand Down
60 changes: 35 additions & 25 deletions thehive-cortex/app/connectors/cortex/services/CortexSrv.scala
Original file line number Diff line number Diff line change
Expand Up @@ -42,17 +42,16 @@ object CortexConfig {
}
}

def getInstances(configuration: Configuration): Map[String, CortexClient] = {
val instances = for {
def getInstances(configuration: Configuration): Seq[CortexClient] = {
for {
cfg configuration.getConfig("cortex").toSeq
key cfg.subKeys
c cfg.getConfig(key)
cic getCortexClient(key, c)
} yield key cic
instances.toMap
} yield cic
}
}
case class CortexConfig(truststore: Option[Path], instances: Map[String, CortexClient]) {
case class CortexConfig(truststore: Option[Path], instances: Seq[CortexClient]) {

@Inject
def this(configuration: Configuration) = this(
Expand Down Expand Up @@ -108,15 +107,15 @@ class CortexSrv @Inject() (
def askAllCortex[A](f: CortexClient Future[Seq[CortexModel[A]]]): Future[Seq[A]] = {
Future
.traverse(cortexConfig.instances.toSeq) {
case (name, cortex) f(cortex).map(_.map(_.onCortex(name)))
case cortex f(cortex).map(_.map(_.onCortex(cortex.name)))
}
.map(_.flatten)
}

def getAnalyzer(analyzerId: String): Future[Analyzer] = {
Future
.traverse(cortexConfig.instances) {
case (name, cortex) cortex.getAnalyzer(analyzerId).map(Some(_)).fallbackTo(Future.successful(None))
case cortex cortex.getAnalyzer(analyzerId).map(Some(_)).fallbackTo(Future.successful(None))
}
.map { analyzers
analyzers.foldLeft[Option[Analyzer]](None) {
Expand Down Expand Up @@ -165,25 +164,36 @@ class CortexSrv @Inject() (
()
}

def submitJob(cortexId: String, analyzerId: String, artifactId: String)(implicit authContext: AuthContext): Future[Job] = {
cortexConfig.instances.get(cortexId).fold[Future[Job]](Future.failed(NotFoundError(s"Cortex $cortexId not found"))) { cortex
def submitJob(cortexId: Option[String], analyzerId: String, artifactId: String)(implicit authContext: AuthContext): Future[Job] = {
val cortexClient = cortexId match {
case Some(id) Future.successful(cortexConfig.instances.find(_.name == id))
case None if (cortexConfig.instances.size <= 1) Future.successful(cortexConfig.instances.headOption)
else {
Future // If there are several cortex, select the first which has the analyzer
.traverse(cortexConfig.instances)(c c.getAnalyzer(analyzerId).map(_ Some(c)).recover { case _ None })
.map(_.flatten.headOption)
}
}

for {
artifact artifactSrv.get(artifactId)
cortexArtifact = (artifact.data(), artifact.attachment()) match {
case (Some(data), None) DataArtifact(data, artifact.attributes)
case (None, Some(attachment)) FileArtifact(attachmentSrv.source(attachment.id), artifact.attributes)
case _ throw InternalError(s"Artifact has invalid data : ${artifact.attributes}")
}
cortexJobJson cortex.analyze(analyzerId, cortexArtifact)
cortexJob = cortexJobJson.as[CortexJob]
job create(artifact, Fields.empty
.set("analyzerId", cortexJob.analyzerId)
.set("artifactId", artifactId)
.set("cortexId", cortex.name)
.set("cortexJobId", cortexJob.id))
_ = updateJobWithCortex(job.id, cortexJob.id, cortex)
} yield job
cortexClient.flatMap {
case Some(cortex)
for {
artifact artifactSrv.get(artifactId)
cortexArtifact = (artifact.data(), artifact.attachment()) match {
case (Some(data), None) DataArtifact(data, artifact.attributes)
case (None, Some(attachment)) FileArtifact(attachmentSrv.source(attachment.id), artifact.attributes)
case _ throw InternalError(s"Artifact has invalid data : ${artifact.attributes}")
}
cortexJobJson cortex.analyze(analyzerId, cortexArtifact)
cortexJob = cortexJobJson.as[CortexJob]
job create(artifact, Fields.empty
.set("analyzerId", cortexJob.analyzerId)
.set("artifactId", artifactId)
.set("cortexId", cortex.name)
.set("cortexJobId", cortexJob.id))
_ = updateJobWithCortex(job.id, cortexJob.id, cortex)
} yield job
case None Future.failed(NotFoundError(s"Cortex $cortexId not found"))
}
}
}
2 changes: 1 addition & 1 deletion thehive-cortex/app/controllers/CortextCtrl.scala
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,7 @@ class CortextCtrl @Inject() (
def createJob = authenticated(Role.write).async(fieldsBodyParser) { implicit request
val analyzerId = request.body.getString("analyzerId").getOrElse(throw BadRequestError(s"analyzerId is missing"))
val artifactId = request.body.getString("artifactId").getOrElse(throw BadRequestError(s"artifactId is missing"))
val cortexId = request.body.getString("cortexId").getOrElse(throw BadRequestError(s"cortexId is missing"))
val cortexId = request.body.getString("cortexId")
cortexSrv.submitJob(cortexId, analyzerId, artifactId).map { job
renderer.toOutput(OK, job)
}
Expand Down

0 comments on commit 78c0687

Please sign in to comment.