All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.virtuslab.ideprobe.jsonrpc.JsonRpcEndpoint.scala Maven / Gradle / Ivy

There is a newer version: 0.53.0
Show newest version
package org.virtuslab.ideprobe.jsonrpc

import org.virtuslab.ideprobe.Close
import org.virtuslab.ideprobe.jsonrpc.JsonRpc._
import org.virtuslab.ideprobe.jsonrpc.logging.{ProbeCommunicationLogger, GroupingLogger}
import scala.concurrent.ExecutionContext
import scala.concurrent.Future
import scala.reflect.ClassTag

trait JsonRpcEndpoint extends AutoCloseable {
  protected def logger: ProbeCommunicationLogger = ProbeCommunicationLogger.empty
  protected def connection: JsonRpcConnection

  implicit protected def ec: ExecutionContext

  protected def handler: Handler

  protected def sendRequest[A: ClassTag, B: ClassTag](method: Method[A, B], parameters: A): Future[B] = {
    Future(method.encode(parameters)).flatMap { json =>
      method match {
        case Method.Notification(name) =>
          logger.logRequest(name, json)
          connection.sendNotification(name, json)
          Future.unit.asInstanceOf[Future[B]]
        case Method.Request(name) =>
          logger.logRequest(name, json)
          connection
            .sendRequest(name, json)
            .flatMap {
              case JsonRpc.Failure(error) =>
                val exception = {
                  val cause = new Exception(error.message)
                  val stackTrace = JsonRpc.gson.fromJson(error.data, classOf[Array[StackTraceElement]])
                  cause.setStackTrace(stackTrace)
                  new RemoteException(cause)
                }

                logger.logResponse(error.message)
                Future.failed(exception)
              case response =>
                logger.logResponse(response.result)
                Future.successful(method.decode(response.result))
            }
      }
    }
  }

  lazy val listen: Unit =
    connection.onRequest { request =>
      handler(request.method, request.params)
        .map(connection.sendResponse(request, _))
        .recover { case cause => connection.sendError(request, cause) }
    }

  def close(): Unit = {
    Close(connection)
  }
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy