Skip to content

Commit 83a011f

Browse files
author
Steve Salas
committed
Merge branch 'dev/dotnet' of https://github.com/codedx/codepulse into dev/dotnet
2 parents a3aa87c + 804c399 commit 83a011f

File tree

3 files changed

+70
-17
lines changed

3 files changed

+70
-17
lines changed

codepulse/src/main/scala/com/secdec/codepulse/input/project/ProjectInput.scala

Lines changed: 66 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -21,47 +21,100 @@ package com.secdec.codepulse.input.project
2121

2222
import scala.concurrent.ExecutionContext.Implicits.global
2323

24-
import akka.actor.{ Actor, Stash }
24+
import akka.actor.{ Actor, ActorRef, Stash }
25+
import scala.collection.mutable.{ Map => MutableMap }
2526
import com.secdec.codepulse.data.model.{ ProjectData, ProjectId }
2627
import com.secdec.codepulse.events.GeneralEventBus
28+
import com.secdec.codepulse.input.LanguageProcessor
2729
import com.secdec.codepulse.processing.ProcessEnvelope
2830
import com.secdec.codepulse.processing.ProcessStatus._
29-
import com.secdec.codepulse.tracer.{ generalEventBus, projectDataProvider, projectManager }
31+
import com.secdec.codepulse.tracer.{ BootVar, generalEventBus, projectDataProvider, projectManager }
3032

3133
trait ProjectLoader {
32-
def createAndLoadProjectData(doLoad: (ProjectData, GeneralEventBus) => Unit): ProjectData
34+
protected def createProject: ProjectData
3335
}
3436

35-
case class CreateProject(load: (ProjectData, GeneralEventBus) => Unit)
37+
case class CreateProject(processors: List[BootVar[ActorRef]], load: (ProjectData, GeneralEventBus) => Unit)
3638

3739
class ProjectInputActor extends Actor with Stash with ProjectLoader {
3840

41+
val projectCreationProcessors = MutableMap.empty[String, List[BootVar[ActorRef]]]
42+
43+
val projectProcessingSuccesses = MutableMap.empty[String, Integer]
44+
45+
val projectProcessingFailures = MutableMap.empty[String, Integer]
46+
3947
// TODO: handle data input by creating a project and broadcasting with 'DataInputAvailable' with project payload
4048
// TODO: capture failed state to cause a failed message and redirect (as necessary) for the user
4149

4250
def receive = {
43-
case CreateProject(load) => {
44-
val projectData = createAndLoadProjectData(load)
51+
case CreateProject(processors, load) => {
52+
val projectData = createProject
53+
addProjectCreators(projectData, processors)
54+
55+
load(projectData, generalEventBus)
56+
4557
sender ! projectData
4658
}
4759
case ProcessEnvelope(_, ProcessDataAvailable(identifier, file, treeNodeData)) => {
48-
for (target <- projectManager getProject ProjectId(identifier.toInt)) {
49-
target.notifyLoadingFinished()
60+
val numberOfProcessors = projectCreationProcessors.get(identifier).get.length
61+
val succeeded = projectProcessorSucceeded(identifier)
62+
val failed = projectProcessingFailures.get(identifier).get
63+
64+
val remaining = numberOfProcessors - (succeeded + failed)
65+
66+
if(remaining == 0 && succeeded >= 1) {
67+
projectManager getProject ProjectId(identifier.toInt) foreach(_.notifyLoadingFinished())
68+
clearProjectCreators(identifier)
5069
}
5170
}
5271
case ProcessEnvelope(_, Failed(identifier, action, Some(exception))) if action != "Dependency Check" => {
53-
for (target <- projectManager.removeUnloadedProject(ProjectId(identifier.toInt), exception.getMessage)) {
54-
//target.notifyLoadingFailed(exception.getMessage)
72+
val numberOfProcessors = projectCreationProcessors.get(identifier).get.length
73+
val succeeded = projectProcessingSuccesses.get(identifier).get
74+
val failed = projectProcessorFailed(identifier)
75+
76+
val remaining = numberOfProcessors - (succeeded + failed)
77+
78+
if(remaining == 0 && failed == numberOfProcessors) {
79+
projectManager.removeUnloadedProject(ProjectId(identifier.toInt), exception.getMessage)
80+
clearProjectCreators(identifier)
5581
}
5682
}
5783
}
5884

59-
def createAndLoadProjectData(doLoad: (ProjectData, GeneralEventBus) => Unit): ProjectData = {
85+
protected def createProject: ProjectData = {
6086
val projectId = projectManager.createProject
6187
val projectData = projectDataProvider getProject projectId
6288

63-
doLoad(projectData, generalEventBus)
64-
6589
projectData
6690
}
91+
92+
protected def addProjectCreators(projectData: ProjectData, processors: List[BootVar[ActorRef]]): Integer = {
93+
val id = projectData.id.num.toString
94+
projectCreationProcessors.put(id, processors)
95+
projectProcessingSuccesses.put(id, 0)
96+
projectProcessingFailures.put(id, 0)
97+
processors.length
98+
}
99+
100+
protected def clearProjectCreators(projectId: String) = {
101+
projectCreationProcessors.remove(projectId)
102+
projectProcessingSuccesses.remove(projectId)
103+
projectProcessingFailures.remove(projectId)
104+
}
105+
106+
protected def projectProcessorSucceeded(projectId: String): Integer = {
107+
incrementProcessor(projectId, projectProcessingSuccesses)
108+
}
109+
110+
protected def projectProcessorFailed(projectId: String) = {
111+
incrementProcessor(projectId, projectProcessingFailures)
112+
}
113+
114+
private def incrementProcessor(key: String, map: MutableMap[String, Integer]): Integer = {
115+
val count = map.get(key).get + 1
116+
map.update(key, count)
117+
118+
count
119+
}
67120
}

codepulse/src/main/scala/com/secdec/codepulse/tracer/ProjectFileUploadHandler.scala

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -73,7 +73,7 @@ class ProjectFileUploadHandler(projectManager: ProjectManager, eventBus: General
7373
}
7474
name <- req.param("name") ?~ "You must specify a name"
7575
} yield {
76-
val project = Await.result((projectInput() ? CreateProject((projectData, eventBus) => {
76+
val project = Await.result((projectInput() ? CreateProject(processors, (projectData, eventBus) => {
7777
projectData.metadata.name = name
7878
projectData.metadata.creationDate = System.currentTimeMillis
7979

codepulse/src/main/scala/com/secdec/codepulse/util/ZipEntryChecker.scala

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -68,7 +68,7 @@ trait ZipEntryChecker {
6868
entry <- entryStream
6969
if !ZipCleaner.shouldFilter(entry)
7070
} {
71-
if (isZip(entry.getName) && recursive)
71+
if (entry.isDirectory || (isZip(entry.getName) && recursive))
7272
forEachEntry(s"$filename/${entry.getName}", new CloseShieldInputStream(zipStream), true)(callback)
7373
else
7474
callback(filename, entry, zipStream)
@@ -104,9 +104,9 @@ trait ZipEntryChecker {
104104
.filterNot(ZipCleaner.shouldFilter)
105105

106106
entryStream.exists { entry =>
107-
lazy val recurse = recursive &&
107+
lazy val recurse = entry.isDirectory || (recursive &&
108108
isZip(entry.getName) &&
109-
findFirstEntry(s"$filename/${entry.getName}", new CloseShieldInputStream(zipStream), true)(predicate)
109+
findFirstEntry(s"$filename/${entry.getName}", new CloseShieldInputStream(zipStream), true)(predicate))
110110

111111
predicate(filename, entry, zipStream) || recurse
112112
}

0 commit comments

Comments
 (0)