Skip to content

Commit

Permalink
Conseil api routes fix (#1006)
Browse files Browse the repository at this point in the history
* first working

* add openApi endpoints

* conseil routes fixed
  • Loading branch information
redroy44 authored Jun 7, 2021
1 parent d63998f commit df042fc
Show file tree
Hide file tree
Showing 13 changed files with 72 additions and 34 deletions.
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
package tech.cryptonomic.conseil.api

import java.util.UUID

import akka.actor.ActorSystem
import akka.event.Logging
import akka.http.scaladsl.server.Directives._
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,10 @@ object OpenApiDoc

/** OpenAPI definition */
def openapi: OpenApi = openApi(Info("Conseil API", "0.0.1"))(
queryEndpoint,
tezosQueryEndpoint,
bitcoinQueryEndpoint,
ethereumQueryEndpoint,
quorumQueryEndpoint,
tezosBlocksEndpoint,
tezosBlocksHeadEndpoint,
tezosBlockByHashEndpoint,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,16 +10,17 @@ trait ApiDataEndpoints extends algebra.JsonEntitiesFromSchemas with Validation {
self: ApiDataJsonSchemas =>

/** Common path among endpoints */
private val commonPath = path / "v2" / "data" / segment[String](name = "platform") / segment[String](name = "network")
private def commonPath(platform: String) =
path / "v2" / "data" / platform / segment[String](name = "network") / segment[String](name = "entity")

/** V2 Query endpoint definition */
def queryEndpoint: Endpoint[
(String, String, String, ApiQuery, Option[String]),
def queryEndpoint(platform: String): Endpoint[
(String, String, ApiQuery, Option[String]),
Option[Validation.QueryValidating[QueryResponseWithOutput]]
] =
endpoint(
request = post(
url = commonPath / segment[String](name = "entity"),
url = commonPath(platform),
entity = jsonRequest[ApiQuery],
headers = optRequestHeader("apiKey")
),
Expand Down
Original file line number Diff line number Diff line change
@@ -1,8 +1,10 @@
package tech.cryptonomic.conseil.api.routes.platform.data.bitcoin

import tech.cryptonomic.conseil.api.routes.platform.data.{ApiDataEndpoints, ApiDataJsonSchemas}
import tech.cryptonomic.conseil.api.routes.platform.data.{ApiDataEndpoints, ApiDataJsonSchemas, ApiDataTypes}
import tech.cryptonomic.conseil.common.generic.chain.DataTypes.QueryResponse
import endpoints.algebra
import tech.cryptonomic.conseil.api.routes.validation.Validation.QueryValidating
import tech.cryptonomic.conseil.common.generic.chain.DataTypes

/** Trait containing endpoints definition */
trait BitcoinDataEndpoints
Expand All @@ -11,7 +13,13 @@ trait BitcoinDataEndpoints
with ApiDataJsonSchemas
with BitcoinFilterFromQueryString {

private val root = path / "v2" / "data" / "bitcoin" / segment[String](name = "network")
private val platform = "bitcoin"

private val root = path / "v2" / "data" / platform / segment[String](name = "network")

def bitcoinQueryEndpoint: Endpoint[(String, String, ApiDataTypes.ApiQuery, Option[String]), Option[
QueryValidating[DataTypes.QueryResponseWithOutput]
]] = queryEndpoint(platform)

/** V2 Blocks endpoint definition */
def bitcoinBlocksEndpoint: Endpoint[((String, BitcoinFilter), Option[String]), Option[List[QueryResponse]]] =
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -30,19 +30,20 @@ case class BitcoinDataRoutes(
private val platformPath = PlatformPath("bitcoin")

/** V2 Route implementation for query endpoint */
override val postRoute: Route = queryEndpoint.implementedByAsync {
case (platform, network, entity, apiQuery, _) =>
val path = EntityPath(entity, NetworkPath(network, PlatformPath(platform)))
override val postRoute: Route = bitcoinQueryEndpoint.implementedByAsync {
case (network, entity, apiQuery, _) =>
val path = EntityPath(entity, NetworkPath(network, platformPath))

pathValidation(path) {
apiQuery
.validate(path, metadataService, metadataConfiguration)
.flatMap { validationResult =>
validationResult.map { validQuery =>
operations.queryWithPredicates(platform, entity, validQuery.withLimitCap(maxQueryResultSize)).map {
queryResponses =>
operations
.queryWithPredicates(platformPath.platform, entity, validQuery.withLimitCap(maxQueryResultSize))
.map { queryResponses =>
QueryResponseWithOutput(queryResponses, validQuery.output)
}
}
}.left.map(Future.successful).bisequence
}
.map(Some(_))
Expand Down
Original file line number Diff line number Diff line change
@@ -1,12 +1,19 @@
package tech.cryptonomic.conseil.api.routes.platform.data.ethereum

import tech.cryptonomic.conseil.api.routes.platform.data.{ApiDataEndpoints, ApiDataTypes}
import tech.cryptonomic.conseil.api.routes.validation.Validation.QueryValidating
import tech.cryptonomic.conseil.common.generic.chain.DataTypes
import tech.cryptonomic.conseil.common.generic.chain.DataTypes.QueryResponse

/** Represents list of endpoints exposed for Ethereum Blockchain */
trait EthereumDataEndpoints extends EthereumDataEndpointsCreator {

private val platform: String = "ethereum"

def ethereumQueryEndpoint: Endpoint[(String, String, ApiDataTypes.ApiQuery, Option[String]), Option[
QueryValidating[DataTypes.QueryResponseWithOutput]
]] = queryEndpoint(platform)

def ethereumBlocksEndpoint: Endpoint[((String, EthereumFilter), Option[String]), Option[List[QueryResponse]]] =
blocksEndpoint(platform)

Expand Down Expand Up @@ -59,6 +66,10 @@ trait QuorumDataEndpoints extends EthereumDataEndpointsCreator {

private val platform: String = "quorum"

def quorumQueryEndpoint: Endpoint[(String, String, ApiDataTypes.ApiQuery, Option[String]), Option[
QueryValidating[DataTypes.QueryResponseWithOutput]
]] = queryEndpoint(platform)

def quorumBlocksEndpoint: Endpoint[((String, EthereumFilter), Option[String]), Option[List[QueryResponse]]] =
blocksEndpoint(platform)

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ case class EthereumDataRoutes(
maxQueryResultSize: Int
)(implicit val executionContext: ExecutionContext)
extends EthereumDataRoutesCreator {
override val platform: PlatformPath = PlatformPath("ethereum")
override val platformPath: PlatformPath = PlatformPath("ethereum")
}

/** Represents the data routes for Quorum Blockchain */
Expand All @@ -25,5 +25,5 @@ case class QuorumDataRoutes(
maxQueryResultSize: Int
)(implicit val executionContext: ExecutionContext)
extends EthereumDataRoutesCreator {
override val platform: PlatformPath = PlatformPath("quorum")
override val platformPath: PlatformPath = PlatformPath("quorum")
}
Original file line number Diff line number Diff line change
Expand Up @@ -38,21 +38,22 @@ trait EthereumDataRoutesCreator
def maxQueryResultSize: Int

/** Path for the specific platform */
def platform: PlatformPath
def platformPath: PlatformPath

/** V2 Route implementation for query endpoint */
override val postRoute: Route = queryEndpoint.implementedByAsync {
case (platform, network, entity, apiQuery, _) =>
val path = EntityPath(entity, NetworkPath(network, PlatformPath(platform)))
override val postRoute: Route = ethereumQueryEndpoint.implementedByAsync {
case (network, entity, apiQuery, _) =>
val path = EntityPath(entity, NetworkPath(network, platformPath))
pathValidation(path) {
apiQuery
.validate(path, metadataService, metadataConfiguration)
.flatMap { validationResult =>
validationResult.map { validQuery =>
operations.queryWithPredicates(platform, entity, validQuery.withLimitCap(maxQueryResultSize)).map {
queryResponses =>
operations
.queryWithPredicates(platformPath.platform, entity, validQuery.withLimitCap(maxQueryResultSize))
.map { queryResponses =>
QueryResponseWithOutput(queryResponses, validQuery.output)
}
}
}.left.map(Future.successful).bisequence
}
.map(Some(_))
Expand Down Expand Up @@ -168,7 +169,7 @@ trait EthereumDataRoutesCreator
private def platformNetworkValidation[A](network: String)(
operation: => Future[Option[A]]
): Future[Option[A]] =
pathValidation(NetworkPath(network, platform))(operation)
pathValidation(NetworkPath(network, platformPath))(operation)

private def pathValidation[A](path: metadata.Path)(
operation: => Future[Option[A]]
Expand Down
Original file line number Diff line number Diff line change
@@ -1,11 +1,12 @@
package tech.cryptonomic.conseil.api.routes.platform.data.tezos

import tech.cryptonomic.conseil.api.routes.platform.data.ApiDataEndpoints
import tech.cryptonomic.conseil.api.routes.platform.data.{ApiDataEndpoints, ApiDataTypes}
import tech.cryptonomic.conseil.api.routes.platform.data.tezos.TezosDataOperations._
import tech.cryptonomic.conseil.common.generic.chain.DataTypes._
import tech.cryptonomic.conseil.common.tezos.Tables
import tech.cryptonomic.conseil.common.tezos.Tables.BlocksRow
import endpoints.algebra
import tech.cryptonomic.conseil.api.routes.validation.Validation.QueryValidating

/** Trait containing endpoints definition */
trait TezosDataEndpoints
Expand All @@ -14,7 +15,13 @@ trait TezosDataEndpoints
with TezosDataJsonSchemas
with TezosFilterFromQueryString {

private val root = path / "v2" / "data" / "tezos" / segment[String](name = "network")
private val platform = "tezos"

private val root = path / "v2" / "data" / platform / segment[String](name = "network")

def tezosQueryEndpoint: Endpoint[(String, String, ApiDataTypes.ApiQuery, Option[String]), Option[
QueryValidating[QueryResponseWithOutput]
]] = queryEndpoint(platform)

/** V2 Blocks endpoint definition */
def tezosBlocksEndpoint: Endpoint[((String, TezosFilter), Option[String]), Option[List[QueryResponse]]] =
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -60,9 +60,9 @@ case class TezosDataRoutes(
)

/** V2 Route implementation for query endpoint */
override val postRoute: Route = queryEndpoint.implementedByAsync {
case (platform, network, entity, apiQuery, _) =>
val path = EntityPath(entity, NetworkPath(network, PlatformPath(platform)))
override val postRoute: Route = tezosQueryEndpoint.implementedByAsync {
case (network, entity, apiQuery, _) =>
val path = EntityPath(entity, NetworkPath(network, platformPath))

pathValidation(path) {
shouldHideForkEntries(entity)(
Expand All @@ -72,7 +72,12 @@ case class TezosDataRoutes(
.flatMap { validationResult =>
validationResult.map { validQuery =>
operations
.queryWithPredicates(platform, entity, validQuery.withLimitCap(maxQueryResultSize), hideForkData)
.queryWithPredicates(
platformPath.platform,
entity,
validQuery.withLimitCap(maxQueryResultSize),
hideForkData
)
.map { queryResponses =>
QueryResponseWithOutput(queryResponses, validQuery.output)
}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package tech.cryptonomic.conseil.api.routes.platform.data.bitcoin

import akka.http.scaladsl.model._
import akka.http.scaladsl.server.Route
import akka.http.scaladsl.testkit.ScalatestRouteTest
import com.stephenn.scalatest.jsonassert.JsonMatchers
import org.scalamock.scalatest.MockFactory
Expand Down Expand Up @@ -89,7 +90,7 @@ class BitcoinDataRoutesTest
uri = "/v2/data/notSupportedPlatform/mainnet/blocks",
entity = HttpEntity(MediaTypes.`application/json`, jsonStringRequest)
)
postRequest ~> addHeader("apiKey", "hooman") ~> routes.postRoute ~> check {
postRequest ~> addHeader("apiKey", "hooman") ~> Route.seal(routes.postRoute) ~> check {
status shouldBe StatusCodes.NotFound
}
}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package tech.cryptonomic.conseil.api.routes.platform.data.ethereum

import akka.http.scaladsl.model._
import akka.http.scaladsl.server.Route
import akka.http.scaladsl.testkit.ScalatestRouteTest
import org.scalamock.scalatest.MockFactory
import org.scalatest.BeforeAndAfterEach
Expand All @@ -23,7 +24,6 @@ import tech.cryptonomic.conseil.common.metadata.{EntityPath, NetworkPath, Platfo

import scala.concurrent.{ExecutionContext, Future}
import scala.concurrent.duration._

import java.net.URL
import tech.cryptonomic.conseil.common.config.Platforms.EthereumRetryConfiguration
import tech.cryptonomic.conseil.common.testkit.ConseilSpec
Expand Down Expand Up @@ -93,7 +93,7 @@ class EthereumDataRoutesTest
uri = "/v2/data/notSupportedPlatform/mainnet/blocks",
entity = HttpEntity(MediaTypes.`application/json`, jsonStringRequest)
)
postRequest ~> addHeader("apiKey", "hooman") ~> routes.postRoute ~> check {
postRequest ~> addHeader("apiKey", "hooman") ~> Route.seal(routes.postRoute) ~> check {
status shouldBe StatusCodes.NotFound
}
}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package tech.cryptonomic.conseil.api.routes.platform.data.tezos

import akka.http.scaladsl.model._
import akka.http.scaladsl.server.Route
import akka.http.scaladsl.testkit.ScalatestRouteTest
import com.stephenn.scalatest.jsonassert.JsonMatchers
import org.scalamock.scalatest.MockFactory
Expand Down Expand Up @@ -84,7 +85,7 @@ class TezosDataRoutesTest
uri = "/v2/data/notSupportedPlatform/alphanet/accounts",
entity = HttpEntity(MediaTypes.`application/json`, jsonStringRequest)
)
postRequest ~> addHeader("apiKey", "hooman") ~> routes.postRoute ~> check {
postRequest ~> addHeader("apiKey", "hooman") ~> Route.seal(routes.postRoute) ~> check {
status shouldBe StatusCodes.NotFound
}
}
Expand Down

0 comments on commit df042fc

Please sign in to comment.