Skip to content

Commit

Permalink
shadow at service layer
Browse files Browse the repository at this point in the history
  • Loading branch information
dvoet committed Nov 26, 2019
1 parent 742776c commit ceb2fd1
Show file tree
Hide file tree
Showing 3 changed files with 70 additions and 16 deletions.
59 changes: 52 additions & 7 deletions src/main/scala/org/broadinstitute/dsde/workbench/sam/Boot.scala
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package org.broadinstitute.dsde.workbench.sam

import java.io.File
import java.lang.reflect.Proxy
import java.net.URI

import akka.actor.ActorSystem
Expand Down Expand Up @@ -31,7 +32,7 @@ import org.broadinstitute.dsde.workbench.sam.model._
import org.broadinstitute.dsde.workbench.sam.openam._
import org.broadinstitute.dsde.workbench.sam.schema.JndiSchemaDAO
import org.broadinstitute.dsde.workbench.sam.service._
import org.broadinstitute.dsde.workbench.sam.util.{DaoWithShadow, NewRelicShadowResultReporter, ShadowRunner}
import org.broadinstitute.dsde.workbench.sam.util.{DaoWithShadow, NewRelicShadowResultReporter, ShadowRunner, ShadowRunnerDynamicProxy}
import org.broadinstitute.dsde.workbench.util.{DelegatePool, ExecutionContexts}
import org.ehcache.Cache
import org.ehcache.config.builders.{CacheConfigurationBuilder, CacheManagerBuilder, ExpiryPolicyBuilder, ResourcePoolsBuilder}
Expand Down Expand Up @@ -339,12 +340,56 @@ object Boot extends IOApp with LazyLogging {
accessPolicyDAO: AccessPolicyDAO,
directoryDAO: DirectoryDAO)(implicit actorSystem: ActorSystem, actorMaterializer: ActorMaterializer): AppDependencies = {
val resourceTypeMap = config.resourceTypes.map(rt => rt.name -> rt).toMap
val policyEvaluatorService = PolicyEvaluatorService(config.emailDomain, resourceTypeMap, accessPolicyDAO, directoryDAO)
val resourceService = new ResourceService(resourceTypeMap, policyEvaluatorService, accessPolicyDAO, directoryDAO, cloudExtensionsInitializer.cloudExtensions, config.emailDomain)
val userService = new UserService(directoryDAO, cloudExtensionsInitializer.cloudExtensions)
val statusService = new StatusService(directoryDAO, cloudExtensionsInitializer.cloudExtensions, 10 seconds)
val managedGroupService =
new ManagedGroupService(resourceService, policyEvaluatorService, resourceTypeMap, accessPolicyDAO, directoryDAO, cloudExtensionsInitializer.cloudExtensions, config.emailDomain)

val (policyEvaluatorService, resourceService, userService, statusService, managedGroupService) =
if (Proxy.isProxyClass(accessPolicyDAO.getClass)) {
val accessPolicyHandler = Proxy.getInvocationHandler(accessPolicyDAO).asInstanceOf[ShadowRunnerDynamicProxy[AccessPolicyDAO]]
val directoryHandler = Proxy.getInvocationHandler(directoryDAO).asInstanceOf[ShadowRunnerDynamicProxy[DirectoryDAO]]

val realPolicyEvalSvc = PolicyEvaluatorService(config.emailDomain, resourceTypeMap, accessPolicyHandler.realDAO, directoryHandler.realDAO)
val shadowPolicyEvalSvc = PolicyEvaluatorService(config.emailDomain, resourceTypeMap, accessPolicyHandler.shadowDAO, directoryHandler.shadowDAO)
val realResourceService = new ResourceService(resourceTypeMap, realPolicyEvalSvc, accessPolicyHandler.realDAO, directoryHandler.realDAO, cloudExtensionsInitializer.cloudExtensions, config.emailDomain)
val shadowResourceService = new ResourceService(resourceTypeMap, shadowPolicyEvalSvc, accessPolicyHandler.shadowDAO, directoryHandler.shadowDAO, NoExtensions, config.emailDomain)

val policyEvaluatorService = DaoWithShadow(
realPolicyEvalSvc,
shadowPolicyEvalSvc,
accessPolicyHandler.resultReporter, accessPolicyHandler.clock
)

val resourceService = DaoWithShadow(
realResourceService,
shadowResourceService,
accessPolicyHandler.resultReporter, accessPolicyHandler.clock
)

val userService = DaoWithShadow(
new UserService(directoryHandler.realDAO, cloudExtensionsInitializer.cloudExtensions),
new UserService(directoryHandler.shadowDAO, NoExtensions),
accessPolicyHandler.resultReporter, accessPolicyHandler.clock
)

val statusService = new StatusService(directoryDAO, cloudExtensionsInitializer.cloudExtensions, 10 seconds)

val managedGroupService = DaoWithShadow(
new ManagedGroupService(realResourceService, realPolicyEvalSvc, resourceTypeMap, accessPolicyHandler.realDAO, directoryHandler.realDAO, cloudExtensionsInitializer.cloudExtensions, config.emailDomain),
new ManagedGroupService(shadowResourceService, shadowPolicyEvalSvc, resourceTypeMap, accessPolicyHandler.shadowDAO, directoryHandler.shadowDAO, NoExtensions, config.emailDomain),
accessPolicyHandler.resultReporter, accessPolicyHandler.clock
)

(policyEvaluatorService, resourceService, userService, statusService, managedGroupService)

} else {
val policyEvaluatorService = PolicyEvaluatorService(config.emailDomain, resourceTypeMap, accessPolicyDAO, directoryDAO)
val resourceService = new ResourceService(resourceTypeMap, policyEvaluatorService, accessPolicyDAO, directoryDAO, cloudExtensionsInitializer.cloudExtensions, config.emailDomain)
val userService = new UserService(directoryDAO, cloudExtensionsInitializer.cloudExtensions)
val statusService = new StatusService(directoryDAO, cloudExtensionsInitializer.cloudExtensions, 10 seconds)
val managedGroupService =
new ManagedGroupService(resourceService, policyEvaluatorService, resourceTypeMap, accessPolicyDAO, directoryDAO, cloudExtensionsInitializer.cloudExtensions, config.emailDomain)

(policyEvaluatorService, resourceService, userService, statusService, managedGroupService)
}

val samApplication = SamApplication(userService, resourceService, statusService)

cloudExtensionsInitializer match {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,14 +19,15 @@ import scala.concurrent.duration._
/**
* Created by mbemis on 5/22/17.
*/
class ResourceService(
private val resourceTypes: Map[ResourceTypeName, ResourceType],
private[service] val policyEvaluatorService: PolicyEvaluatorService,
private val accessPolicyDAO: AccessPolicyDAO,
private val directoryDAO: DirectoryDAO,
private val cloudExtensions: CloudExtensions,
val emailDomain: String)(implicit val executionContext: ExecutionContext)
extends LazyLogging {
trait ResourceServiceTrait extends LazyLogging {
protected val resourceTypes: Map[ResourceTypeName, ResourceType]
protected[service] val policyEvaluatorService: PolicyEvaluatorService
protected val accessPolicyDAO: AccessPolicyDAO
protected val directoryDAO: DirectoryDAO
protected val cloudExtensions: CloudExtensions
val emailDomain: String
implicit val executionContext: ExecutionContext

implicit val cs = IO.contextShift(executionContext) //for running IOs in paralell

private case class ValidatableAccessPolicy(
Expand Down Expand Up @@ -505,3 +506,11 @@ class ResourceService(
workbenchUsers.map(user => UserIdInfo(user.id, user.email, user.googleSubjectId))
}
}

class ResourceService(protected val resourceTypes: Map[ResourceTypeName, ResourceType],
protected[service] val policyEvaluatorService: PolicyEvaluatorService,
protected val accessPolicyDAO: AccessPolicyDAO,
protected val directoryDAO: DirectoryDAO,
protected val cloudExtensions: CloudExtensions,
val emailDomain: String)(implicit val executionContext: ExecutionContext)
extends LazyLogging with ResourceServiceTrait
Original file line number Diff line number Diff line change
Expand Up @@ -88,7 +88,7 @@ object DaoWithShadow {
}
}

private class ShadowRunnerDynamicProxy[DAO](realDAO: DAO, shadowDAO: DAO, val resultReporter: ShadowResultReporter, val clock: Clock[IO])(implicit val contextShift: ContextShift[IO], timer: Timer[IO]) extends InvocationHandler with ShadowRunner {
class ShadowRunnerDynamicProxy[DAO](val realDAO: DAO, val shadowDAO: DAO, val resultReporter: ShadowResultReporter, val clock: Clock[IO])(implicit val contextShift: ContextShift[IO], timer: Timer[IO]) extends InvocationHandler with ShadowRunner {
override def invoke(proxy: Any, method: Method, args: Array[AnyRef]): AnyRef = {
// there should not be any functions in our DAOs that return non-IO type but scala does funny stuff at the java class level wrt default parameters
// so check if the return type is IO, if it is just call it and run with shadow
Expand Down

0 comments on commit ceb2fd1

Please sign in to comment.