diff --git a/app/controllers/AnnotationController.scala b/app/controllers/AnnotationController.scala index f58225ddbd7..748032e8f15 100755 --- a/app/controllers/AnnotationController.scala +++ b/app/controllers/AnnotationController.scala @@ -56,7 +56,7 @@ class AnnotationController @Inject()( def info(typ: String, id: String, timestamp: Long): Action[AnyContent] = sil.UserAwareAction.async { implicit request => - log { + log() { val notFoundMessage = if (request.identity.isEmpty) "annotation.notFound.considerLoggingIn" else "annotation.notFound" for { @@ -211,7 +211,7 @@ class AnnotationController @Inject()( def finish(typ: String, id: String, timestamp: Long): Action[AnyContent] = sil.SecuredAction.async { implicit request => - log { + log() { for { (updated, message) <- finishAnnotation(typ, id, request.identity, timestamp) ?~> "annotation.finish.failed" restrictions <- provider.restrictionsFor(typ, id) @@ -222,7 +222,7 @@ class AnnotationController @Inject()( def finishAll(typ: String, timestamp: Long): Action[JsValue] = sil.SecuredAction.async(parse.json) { implicit request => - log { + log() { withJsonAs[JsArray](request.body \ "annotations") { annotationIds => val results = Fox.serialSequence(annotationIds.value.toList) { jsValue => jsValue.asOpt[String].toFox.flatMap(id => finishAnnotation(typ, id, request.identity, timestamp)) diff --git a/app/controllers/AnnotationIOController.scala b/app/controllers/AnnotationIOController.scala index ec48ac2c247..9f65d853408 100755 --- a/app/controllers/AnnotationIOController.scala +++ b/app/controllers/AnnotationIOController.scala @@ -63,7 +63,7 @@ class AnnotationIOController @Inject()(nmlWriter: NmlWriter, def upload: Action[MultipartFormData[TemporaryFile]] = sil.SecuredAction.async(parse.multipartFormData) { implicit request => - log { + log() { val shouldCreateGroupForEachFile: Boolean = request.body.dataParts("createGroupForEachFile").headOption.contains("true") val overwritingDataSetName: Option[String] = diff --git a/app/controllers/Application.scala b/app/controllers/Application.scala index 568b2db616a..5ec4a4ce13b 100755 --- a/app/controllers/Application.scala +++ b/app/controllers/Application.scala @@ -93,7 +93,7 @@ class Application @Inject()(multiUserDAO: MultiUserDAO, val after = System.currentTimeMillis() logger.info(s"Answering ok for wK health check, took ${after - before} ms$localStoresLabelWrapped") } - log { + log() { for { before <- Fox.successful(System.currentTimeMillis()) dataStoreDuration <- checkDatastoreHealthIfEnabled ?~> "dataStore.unavailable" diff --git a/app/controllers/DataSetController.scala b/app/controllers/DataSetController.scala index d9bb77ff544..915ce0eb0e8 100755 --- a/app/controllers/DataSetController.scala +++ b/app/controllers/DataSetController.scala @@ -205,7 +205,7 @@ class DataSetController @Inject()(userService: UserService, def read(organizationName: String, dataSetName: String, sharingToken: Option[String]): Action[AnyContent] = sil.UserAwareAction.async { implicit request => - log { + log() { val ctx = URLSharing.fallbackTokenAccessContext(sharingToken) for { organization <- organizationDAO.findOneByName(organizationName)(GlobalAccessContext) ?~> Messages( diff --git a/app/controllers/JobsController.scala b/app/controllers/JobsController.scala index 185b9218228..980603c81f4 100644 --- a/app/controllers/JobsController.scala +++ b/app/controllers/JobsController.scala @@ -123,7 +123,7 @@ class JobService @Inject()(wkConf: WkConf, celeryInfoJson <- flowerRpc("/api/tasks?offset=0").getWithJsonResponse[JsObject] celeryInfoMap <- celeryInfoJson .validate[Map[String, JsObject]] ?~> "Could not validate celery response as json map" - _ = trackAllNewlyFailed(celeryInfoMap) + _ = trackAllNewlyDone(celeryInfoMap) _ <- Fox.serialCombined(celeryInfoMap.keys.toList)(jobId => jobDAO.updateCeleryInfoByCeleryId(jobId, celeryInfoMap(jobId))) } yield () @@ -134,37 +134,40 @@ class JobService @Inject()(wkConf: WkConf, } } - private def trackAllNewlyFailed(celeryInfoMap: Map[String, JsObject]): Fox[Unit] = + private def trackAllNewlyDone(celeryInfoMap: Map[String, JsObject]): Fox[Unit] = for { oldJobs <- jobDAO.getAllByCeleryIds(celeryInfoMap.keys.toList) - nowFailedJobInfos = filterFailed(celeryInfoMap: Map[String, JsObject]) - newlyFailedJobs = getNewlyFailedJobs(oldJobs, nowFailedJobInfos) + nowFailedJobInfos = filterByStatus(celeryInfoMap: Map[String, JsObject], "FAILURE") + newlyFailedJobs = getNewlyDoneJobs(oldJobs, nowFailedJobInfos) _ = newlyFailedJobs.map(trackNewlyFailed) + nowSuccessfulJobInfos = filterByStatus(celeryInfoMap: Map[String, JsObject], "SUCCESS") + newlySuccessfulJobs = getNewlyDoneJobs(oldJobs, nowSuccessfulJobInfos) + _ = newlySuccessfulJobs.map(trackNewlySuccessful) } yield () - private def filterFailed(celeryInfoMap: Map[String, JsObject]): Map[String, JsObject] = + private def filterByStatus(celeryInfoMap: Map[String, JsObject], statusToFilter: String): Map[String, JsObject] = celeryInfoMap.filter(tuple => { val statusOpt = (tuple._2 \ "state").validate[String] statusOpt match { case JsSuccess(status, _) => - if (status == "FAILURE") true + if (status == statusToFilter) true else false case _ => false } }) - private def getNewlyFailedJobs(oldJobs: List[Job], nowFailedJobInfos: Map[String, JsObject]): List[Job] = { - val failableStates = List("STARTED", "PENDING", "RETRY") - val previouslyFailableJobs = oldJobs.filter(job => { + private def getNewlyDoneJobs(oldJobs: List[Job], nowDoneJobInfos: Map[String, JsObject]): List[Job] = { + val incompleteStates = List("STARTED", "PENDING", "RETRY") + val previouslyIncompleteJobs = oldJobs.filter(job => { val oldSatusOpt = (job.celeryInfo \ "state").validate[String] oldSatusOpt match { - case JsSuccess(status, _) => failableStates.contains(status) + case JsSuccess(status, _) => incompleteStates.contains(status) case _ => true } }) - val newlyFailedJobs = previouslyFailableJobs.filter(job => nowFailedJobInfos.contains(job.celeryJobId)) - newlyFailedJobs.map { job => - job.copy(celeryInfo = nowFailedJobInfos(job.celeryJobId)) + val newlyDoneJobs = previouslyIncompleteJobs.filter(job => nowDoneJobInfos.contains(job.celeryJobId)) + newlyDoneJobs.map { job => + job.copy(celeryInfo = nowDoneJobInfos(job.celeryJobId)) } } @@ -179,6 +182,12 @@ class JobService @Inject()(wkConf: WkConf, () } + private def trackNewlySuccessful(job: Job): Unit = + slackNotificationService.info( + "Successful job", + s"Job ${job._id} succeeded. Command ${job.command}, celery job id: ${job.celeryJobId}." + ) + def publicWrites(job: Job): Fox[JsObject] = Fox.successful( Json.obj( @@ -220,6 +229,7 @@ class JobService @Inject()(wkConf: WkConf, class JobsController @Inject()(jobDAO: JobDAO, sil: Silhouette[WkEnv], jobService: JobService, + slackNotificationService: SlackNotificationService, organizationDAO: OrganizationDAO)(implicit ec: ExecutionContext) extends Controller { @@ -241,16 +251,20 @@ class JobsController @Inject()(jobDAO: JobDAO, def runConvertToWkwJob(organizationName: String, dataSetName: String, scale: String): Action[AnyContent] = sil.SecuredAction.async { implicit request => - for { - organization <- organizationDAO.findOneByName(organizationName) ?~> Messages("organization.notFound", - organizationName) - _ <- bool2Fox(request.identity._organization == organization._id) ~> FORBIDDEN - command = "convert_to_wkw" - commandArgs = Json.obj("organization_name" -> organizationName, "dataset_name" -> dataSetName, "scale" -> scale) - - job <- jobService.runJob(command, commandArgs, request.identity) ?~> "job.couldNotRunCubing" - js <- jobService.publicWrites(job) - } yield Ok(js) + log(Some(slackNotificationService.noticeFailedJobRequest)) { + for { + organization <- organizationDAO.findOneByName(organizationName) ?~> Messages("organization.notFound", + organizationName) + _ <- bool2Fox(request.identity._organization == organization._id) ~> FORBIDDEN + command = "convert_to_wkw" + commandArgs = Json.obj("organization_name" -> organizationName, + "dataset_name" -> dataSetName, + "scale" -> scale) + + job <- jobService.runJob(command, commandArgs, request.identity) ?~> "job.couldNotRunCubing" + js <- jobService.publicWrites(job) + } yield Ok(js) + } } def runExportTiffJob(organizationName: String, @@ -262,28 +276,30 @@ class JobsController @Inject()(jobDAO: JobDAO, annotationId: Option[String], annotationType: Option[String]): Action[AnyContent] = sil.SecuredAction.async { implicit request => - for { - organization <- organizationDAO.findOneByName(organizationName) ?~> Messages("organization.notFound", - organizationName) - _ <- bool2Fox(request.identity._organization == organization._id) ?~> "job.export.notAllowed.organization" ~> FORBIDDEN - _ <- jobService.assertTiffExportBoundingBoxLimits(bbox) - command = "export_tiff" - exportFileName = s"${formatDateForFilename(new Date())}__${dataSetName}__${tracingId.map(_ => "volume").getOrElse(layerName.getOrElse(""))}.zip" - commandArgs = Json.obj( - "organization_name" -> organizationName, - "dataset_name" -> dataSetName, - "bbox" -> bbox, - "webknossos_token" -> TracingStoreRpcClient.webKnossosToken, - "export_file_name" -> exportFileName, - "layer_name" -> layerName, - "volume_tracing_id" -> tracingId, - "volume_tracing_version" -> tracingVersion, - "annotation_id" -> annotationId, - "annotation_type" -> annotationType - ) - job <- jobService.runJob(command, commandArgs, request.identity) ?~> "job.couldNotRunTiffExport" - js <- jobService.publicWrites(job) - } yield Ok(js) + log(Some(slackNotificationService.noticeFailedJobRequest)) { + for { + organization <- organizationDAO.findOneByName(organizationName) ?~> Messages("organization.notFound", + organizationName) + _ <- bool2Fox(request.identity._organization == organization._id) ?~> "job.export.notAllowed.organization" ~> FORBIDDEN + _ <- jobService.assertTiffExportBoundingBoxLimits(bbox) + command = "export_tiff" + exportFileName = s"${formatDateForFilename(new Date())}__${dataSetName}__${tracingId.map(_ => "volume").getOrElse(layerName.getOrElse(""))}.zip" + commandArgs = Json.obj( + "organization_name" -> organizationName, + "dataset_name" -> dataSetName, + "bbox" -> bbox, + "webknossos_token" -> TracingStoreRpcClient.webKnossosToken, + "export_file_name" -> exportFileName, + "layer_name" -> layerName, + "volume_tracing_id" -> tracingId, + "volume_tracing_version" -> tracingVersion, + "annotation_id" -> annotationId, + "annotation_type" -> annotationType + ) + job <- jobService.runJob(command, commandArgs, request.identity) ?~> "job.couldNotRunTiffExport" + js <- jobService.publicWrites(job) + } yield Ok(js) + } } def downloadExport(jobId: String, exportFileName: String): Action[AnyContent] = diff --git a/app/controllers/TaskController.scala b/app/controllers/TaskController.scala index 3a5bbf48eef..5a3be507d2c 100755 --- a/app/controllers/TaskController.scala +++ b/app/controllers/TaskController.scala @@ -147,7 +147,7 @@ class TaskController @Inject()(taskCreationService: TaskCreationService, } def request: Action[AnyContent] = sil.SecuredAction.async { implicit request => - log { + log() { val user = request.identity for { teams <- taskService.getAllowedTeamsForNextTask(user) diff --git a/app/controllers/UserController.scala b/app/controllers/UserController.scala index e5b9f832354..738555921b5 100755 --- a/app/controllers/UserController.scala +++ b/app/controllers/UserController.scala @@ -36,7 +36,7 @@ class UserController @Inject()(userService: UserService, private val DefaultAnnotationListLimit = 1000 def current: Action[AnyContent] = sil.SecuredAction.async { implicit request => - log { + log() { for { userJs <- userService.publicWrites(request.identity, request.identity) } yield Ok(userJs) @@ -44,7 +44,7 @@ class UserController @Inject()(userService: UserService, } def user(userId: String): Action[AnyContent] = sil.SecuredAction.async { implicit request => - log { + log() { for { userIdValidated <- ObjectId.parse(userId) ?~> "user.id.invalid" user <- userDAO.findOne(userIdValidated) ?~> "user.notFound" ~> NOT_FOUND diff --git a/app/oxalis/security/UserAwareRequestLogging.scala b/app/oxalis/security/UserAwareRequestLogging.scala index 5304faee317..df429e68154 100644 --- a/app/oxalis/security/UserAwareRequestLogging.scala +++ b/app/oxalis/security/UserAwareRequestLogging.scala @@ -10,18 +10,12 @@ trait UserAwareRequestLogging extends AbstractRequestLogging { case class RequesterIdOpt(id: Option[String]) //forcing implicit conversion - def log(block: => Result)(implicit request: Request[_], requesterIdOpt: RequesterIdOpt): Result = { - val result: Result = block - logRequestFormatted(request, result, requesterIdOpt.id) - result - } - - def log(block: => Future[Result])(implicit request: Request[_], - userIdOpt: RequesterIdOpt, - ec: ExecutionContext): Future[Result] = + def log(notifier: Option[String => Unit] = None)(block: => Future[Result])(implicit request: Request[_], + requesterIdOpt: RequesterIdOpt, + ec: ExecutionContext): Future[Result] = for { result: Result <- block - _ = logRequestFormatted(request, result, userIdOpt.id) + _ = logRequestFormatted(request, result, notifier, requesterIdOpt.id) } yield result implicit def userAwareRequestToRequesterIdOpt(implicit request: UserAwareRequest[WkEnv, _]): RequesterIdOpt = diff --git a/app/oxalis/telemetry/SlackNotificationService.scala b/app/oxalis/telemetry/SlackNotificationService.scala index 2f21353091b..d4eeae74358 100644 --- a/app/oxalis/telemetry/SlackNotificationService.scala +++ b/app/oxalis/telemetry/SlackNotificationService.scala @@ -25,6 +25,18 @@ class SlackNotificationService @Inject()(rpc: RPC, config: WkConf) extends LazyL msg = msg ) + def info(title: String, msg: String): Unit = + slackClient.info( + title = title, + msg = msg + ) + + def noticeFailedJobRequest(msg: String): Unit = + slackClient.warn( + title = "Failed job request", + msg = msg + ) + def noticeBaseAnnotationTaskCreation(taskType: List[String], numberOfTasks: Int): Unit = slackClient.info( title = "Task creation with base", diff --git a/app/utils/WkConf.scala b/app/utils/WkConf.scala index 825df2c0bd3..f9209b33c3e 100644 --- a/app/utils/WkConf.scala +++ b/app/utils/WkConf.scala @@ -91,7 +91,6 @@ class WkConf @Inject()(configuration: Configuration) extends ConfigReader with L val user: String = get[String]("mail.smtp.user") val pass: String = get[String]("mail.smtp.pass") } - val demoSender: String = get[String]("mail.demoSender") val defaultSender: String = get[String]("mail.defaultSender") object Mailchimp { val host: String = get[String]("mail.mailchimp.host") diff --git a/conf/application.conf b/conf/application.conf index a1501f48857..48240b60e77 100644 --- a/conf/application.conf +++ b/conf/application.conf @@ -153,7 +153,6 @@ mail { pass = "" } defaultSender = "webKnossos " - demoSender = "" reply = "webKnossos " mailchimp { host = "" diff --git a/util/src/main/scala/com/scalableminds/util/requestlogging/RequestLogging.scala b/util/src/main/scala/com/scalableminds/util/requestlogging/RequestLogging.scala index dfc5c4896a6..b489efa2bcf 100644 --- a/util/src/main/scala/com/scalableminds/util/requestlogging/RequestLogging.scala +++ b/util/src/main/scala/com/scalableminds/util/requestlogging/RequestLogging.scala @@ -1,32 +1,43 @@ package com.scalableminds.util.requestlogging import com.typesafe.scalalogging.LazyLogging -import play.api.http.HttpEntity +import play.api.http.{HttpEntity, Status} import play.api.mvc.{Request, Result} import scala.concurrent.{ExecutionContext, Future} trait AbstractRequestLogging extends LazyLogging { - def logRequestFormatted(request: Request[_], result: Result, userId: Option[String] = None): Unit = { - val userIdMsg = userId.map(id => s" for user $id").getOrElse("") + def logRequestFormatted(request: Request[_], + result: Result, + notifier: Option[String => Unit], + requesterId: Option[String] = None): Unit = { + + if (Status.isSuccessful(result.header.status)) return + + val userIdMsg = requesterId.map(id => s" for user $id").getOrElse("") + val resultMsg = s": ${resultBody(result)}" + val msg = s"Answering ${result.header.status} at ${request.uri}$userIdMsg$resultMsg" + logger.warn(msg) + notifier.foreach(_(msg)) + } + + private def resultBody(result: Result): String = result.body match { - case HttpEntity.Strict(byteString, _) if result.header.status != 200 => - logger.warn( - s"Answering ${result.header.status} at ${request.uri}$userIdMsg – ${byteString.take(20000).decodeString("utf-8")}") - case _ => () + case HttpEntity.Strict(byteString, _) => byteString.take(20000).decodeString("utf-8") + case _ => "" } - } } trait RequestLogging extends AbstractRequestLogging { // Hint: within webKnossos itself, UserAwareRequestLogging is available, which additionally logs the requester user id - def log(block: => Future[Result])(implicit request: Request[_], ec: ExecutionContext): Future[Result] = + def log(notifier: Option[String => Unit] = None)(block: => Future[Result])(implicit request: Request[_], + ec: ExecutionContext): Future[Result] = for { result: Result <- block - _ = logRequestFormatted(request, result) + _ = logRequestFormatted(request, result, notifier) } yield result def logTime(notifier: String => Unit)(block: => Future[Result])(implicit request: Request[_], @@ -43,14 +54,8 @@ trait RequestLogging extends AbstractRequestLogging { for { result: Result <- block executionTime = System.nanoTime() - start - _ = if (request.uri.contains("volume") && executionTime > 3e9) logTimeFormatted(executionTime, request, result) + _ = if (executionTime > 5e9) logTimeFormatted(executionTime, request, result) } yield result } - def log(block: => Result)(implicit request: Request[_]): Result = { - val result: Result = block - logRequestFormatted(request, result) - result - } - } diff --git a/webknossos-tracingstore/app/com/scalableminds/webknossos/tracingstore/TracingStoreConfig.scala b/webknossos-tracingstore/app/com/scalableminds/webknossos/tracingstore/TracingStoreConfig.scala index 6457d94f065..57e0382ef1b 100644 --- a/webknossos-tracingstore/app/com/scalableminds/webknossos/tracingstore/TracingStoreConfig.scala +++ b/webknossos-tracingstore/app/com/scalableminds/webknossos/tracingstore/TracingStoreConfig.scala @@ -32,5 +32,5 @@ class TracingStoreConfig @Inject()(configuration: Configuration) extends ConfigR val uri: String = get[String]("slackNotifications.uri") val verboseLoggingEnabled: Boolean = get[Boolean]("slackNotifications.verboseLoggingEnabled") } - val children = List(Http, Tracingstore) + val children = List(Http, Tracingstore, SlackNotifications) } diff --git a/webknossos-tracingstore/app/com/scalableminds/webknossos/tracingstore/controllers/Application.scala b/webknossos-tracingstore/app/com/scalableminds/webknossos/tracingstore/controllers/Application.scala index 8e8e5c57f36..f3d98a50ce0 100644 --- a/webknossos-tracingstore/app/com/scalableminds/webknossos/tracingstore/controllers/Application.scala +++ b/webknossos-tracingstore/app/com/scalableminds/webknossos/tracingstore/controllers/Application.scala @@ -14,7 +14,7 @@ class Application @Inject()(tracingDataStore: TracingDataStore, redisClient: Red extends Controller { def health: Action[AnyContent] = Action.async { implicit request => - log { + log() { AllowRemoteOrigin { for { before <- Fox.successful(System.currentTimeMillis()) diff --git a/webknossos-tracingstore/app/com/scalableminds/webknossos/tracingstore/controllers/SkeletonTracingController.scala b/webknossos-tracingstore/app/com/scalableminds/webknossos/tracingstore/controllers/SkeletonTracingController.scala index b24ccc136e6..92a81eed0fb 100644 --- a/webknossos-tracingstore/app/com/scalableminds/webknossos/tracingstore/controllers/SkeletonTracingController.scala +++ b/webknossos-tracingstore/app/com/scalableminds/webknossos/tracingstore/controllers/SkeletonTracingController.scala @@ -33,7 +33,7 @@ class SkeletonTracingController @Inject()(val tracingService: SkeletonTracingSer def mergedFromContents(persist: Boolean): Action[SkeletonTracings] = Action.async(validateProto[SkeletonTracings]) { implicit request => - log { + log() { accessTokenService.validateAccess(UserAccessRequest.webknossos) { AllowRemoteOrigin { val tracings: List[Option[SkeletonTracing]] = request.body @@ -48,7 +48,7 @@ class SkeletonTracingController @Inject()(val tracingService: SkeletonTracingSer def duplicate(tracingId: String, version: Option[Long], fromTask: Option[Boolean]): Action[AnyContent] = Action.async { implicit request => - log { + log() { accessTokenService.validateAccess(UserAccessRequest.webknossos) { AllowRemoteOrigin { for { @@ -63,7 +63,7 @@ class SkeletonTracingController @Inject()(val tracingService: SkeletonTracingSer } def updateActionLog(tracingId: String): Action[AnyContent] = Action.async { implicit request => - log { + log() { accessTokenService.validateAccess(UserAccessRequest.readTracing(tracingId)) { AllowRemoteOrigin { for { @@ -77,7 +77,7 @@ class SkeletonTracingController @Inject()(val tracingService: SkeletonTracingSer } def updateActionStatistics(tracingId: String): Action[AnyContent] = Action.async { implicit request => - log { + log() { accessTokenService.validateAccess(UserAccessRequest.readTracing(tracingId)) { AllowRemoteOrigin { for { diff --git a/webknossos-tracingstore/app/com/scalableminds/webknossos/tracingstore/controllers/TracingController.scala b/webknossos-tracingstore/app/com/scalableminds/webknossos/tracingstore/controllers/TracingController.scala index 6892b35dd9a..547a32db217 100644 --- a/webknossos-tracingstore/app/com/scalableminds/webknossos/tracingstore/controllers/TracingController.scala +++ b/webknossos-tracingstore/app/com/scalableminds/webknossos/tracingstore/controllers/TracingController.scala @@ -52,7 +52,7 @@ trait TracingController[T <: GeneratedMessage with Message[T], Ts <: GeneratedMe implicit val bodyParsers: PlayBodyParsers def save: Action[T] = Action.async(validateProto[T]) { implicit request => - log { + log() { logTime(slackNotificationService.noticeSlowRequest) { accessTokenService.validateAccess(UserAccessRequest.webknossos) { AllowRemoteOrigin { @@ -67,7 +67,7 @@ trait TracingController[T <: GeneratedMessage with Message[T], Ts <: GeneratedMe } def saveMultiple: Action[Ts] = Action.async(validateProto[Ts]) { implicit request => - log { + log() { logTime(slackNotificationService.noticeSlowRequest) { accessTokenService.validateAccess(UserAccessRequest.webknossos) { AllowRemoteOrigin { @@ -85,7 +85,7 @@ trait TracingController[T <: GeneratedMessage with Message[T], Ts <: GeneratedMe } def get(tracingId: String, version: Option[Long]): Action[AnyContent] = Action.async { implicit request => - log { + log() { accessTokenService.validateAccess(UserAccessRequest.readTracing(tracingId)) { AllowRemoteOrigin { for { @@ -100,7 +100,7 @@ trait TracingController[T <: GeneratedMessage with Message[T], Ts <: GeneratedMe def getMultiple: Action[List[Option[TracingSelector]]] = Action.async(validateJson[List[Option[TracingSelector]]]) { implicit request => - log { + log() { accessTokenService.validateAccess(UserAccessRequest.webknossos) { AllowRemoteOrigin { for { @@ -115,7 +115,7 @@ trait TracingController[T <: GeneratedMessage with Message[T], Ts <: GeneratedMe def update(tracingId: String): Action[List[UpdateActionGroup[T]]] = Action.async(validateJson[List[UpdateActionGroup[T]]]) { implicit request => - log { + log() { logTime(slackNotificationService.noticeSlowRequest) { accessTokenService.validateAccess(UserAccessRequest.writeTracing(tracingId)) { AllowRemoteOrigin { @@ -226,7 +226,7 @@ trait TracingController[T <: GeneratedMessage with Message[T], Ts <: GeneratedMe def mergedFromIds(persist: Boolean): Action[List[Option[TracingSelector]]] = Action.async(validateJson[List[Option[TracingSelector]]]) { implicit request => - log { + log() { accessTokenService.validateAccess(UserAccessRequest.webknossos) { AllowRemoteOrigin { for { diff --git a/webknossos-tracingstore/app/com/scalableminds/webknossos/tracingstore/controllers/VolumeTracingController.scala b/webknossos-tracingstore/app/com/scalableminds/webknossos/tracingstore/controllers/VolumeTracingController.scala index 6c7f5691075..256942230ce 100644 --- a/webknossos-tracingstore/app/com/scalableminds/webknossos/tracingstore/controllers/VolumeTracingController.scala +++ b/webknossos-tracingstore/app/com/scalableminds/webknossos/tracingstore/controllers/VolumeTracingController.scala @@ -45,7 +45,7 @@ class VolumeTracingController @Inject()(val tracingService: VolumeTracingService def initialData(tracingId: String, minResolution: Option[Int], maxResolution: Option[Int]): Action[AnyContent] = Action.async { implicit request => - log { + log() { logTime(slackNotificationService.noticeSlowRequest) { accessTokenService.validateAccess(UserAccessRequest.webknossos) { AllowRemoteOrigin { @@ -66,7 +66,7 @@ class VolumeTracingController @Inject()(val tracingService: VolumeTracingService def mergedFromContents(persist: Boolean): Action[VolumeTracings] = Action.async(validateProto[VolumeTracings]) { implicit request => - log { + log() { accessTokenService.validateAccess(UserAccessRequest.webknossos) { AllowRemoteOrigin { val tracings: List[Option[VolumeTracing]] = request.body @@ -80,7 +80,7 @@ class VolumeTracingController @Inject()(val tracingService: VolumeTracingService } def initialDataMultiple(tracingId: String): Action[AnyContent] = Action.async { implicit request => - log { + log() { logTime(slackNotificationService.noticeSlowRequest) { accessTokenService.validateAccess(UserAccessRequest.webknossos) { AllowRemoteOrigin { @@ -97,7 +97,7 @@ class VolumeTracingController @Inject()(val tracingService: VolumeTracingService } def allData(tracingId: String, version: Option[Long]): Action[AnyContent] = Action.async { implicit request => - log { + log() { accessTokenService.validateAccess(UserAccessRequest.readTracing(tracingId)) { AllowRemoteOrigin { for { @@ -112,7 +112,7 @@ class VolumeTracingController @Inject()(val tracingService: VolumeTracingService } def allDataBlocking(tracingId: String, version: Option[Long]): Action[AnyContent] = Action.async { implicit request => - log { + log() { accessTokenService.validateAccess(UserAccessRequest.readTracing(tracingId)) { AllowRemoteOrigin { for { @@ -127,7 +127,7 @@ class VolumeTracingController @Inject()(val tracingService: VolumeTracingService def data(tracingId: String): Action[List[WebKnossosDataRequest]] = Action.async(validateJson[List[WebKnossosDataRequest]]) { implicit request => - log { + log() { accessTokenService.validateAccess(UserAccessRequest.readTracing(tracingId)) { AllowRemoteOrigin { for { @@ -150,7 +150,7 @@ class VolumeTracingController @Inject()(val tracingService: VolumeTracingService minResolution: Option[Int], maxResolution: Option[Int], downsample: Option[Boolean]): Action[AnyContent] = Action.async { implicit request => - log { + log() { logTime(slackNotificationService.noticeSlowRequest) { accessTokenService.validateAccess(UserAccessRequest.webknossos) { AllowRemoteOrigin { @@ -173,7 +173,7 @@ class VolumeTracingController @Inject()(val tracingService: VolumeTracingService def unlinkFallback(tracingId: String): Action[DataSourceLike] = Action.async(validateJson[DataSourceLike]) { implicit request => - log { + log() { logTime(slackNotificationService.noticeSlowRequest) { accessTokenService.validateAccess(UserAccessRequest.webknossos) { AllowRemoteOrigin { @@ -190,7 +190,7 @@ class VolumeTracingController @Inject()(val tracingService: VolumeTracingService def importVolumeData(tracingId: String): Action[MultipartFormData[TemporaryFile]] = Action.async(parse.multipartFormData) { implicit request => - log { + log() { accessTokenService.validateAccess(UserAccessRequest.writeTracing(tracingId)) { AllowRemoteOrigin { for { @@ -205,7 +205,7 @@ class VolumeTracingController @Inject()(val tracingService: VolumeTracingService } def updateActionLog(tracingId: String): Action[AnyContent] = Action.async { implicit request => - log { + log() { accessTokenService.validateAccess(UserAccessRequest.readTracing(tracingId)) { AllowRemoteOrigin { for {