Skip to content

Commit

Permalink
Disable endpoints when corresponding service is disabled
Browse files Browse the repository at this point in the history
Resolves: #534
  • Loading branch information
tdroxler committed May 3, 2024
1 parent e9ab6dc commit aa38600
Show file tree
Hide file tree
Showing 13 changed files with 1,209 additions and 1,153 deletions.
1,951 changes: 932 additions & 1,019 deletions app/src/main/resources/explorer-backend-openapi.json

Large diffs are not rendered by default.

13 changes: 8 additions & 5 deletions app/src/main/scala/org/alephium/explorer/AppServer.scala
Original file line number Diff line number Diff line change
Expand Up @@ -31,11 +31,13 @@ import org.alephium.explorer.web._
// scalastyle:off magic.number parameter.number
object AppServer {

// scalastyle:off method.length
def routes(
exportTxsNumberThreshold: Int,
streamParallelism: Int,
maxTimeIntervals: ExplorerConfig.MaxTimeIntervals,
marketConfig: ExplorerConfig.Market
marketConfig: ExplorerConfig.Market,
servicesConfig: ExplorerConfig.Services
)(implicit
ec: ExecutionContext,
dc: DatabaseConfig[PostgresProfile],
Expand All @@ -57,15 +59,16 @@ object AppServer {
maxTimeIntervals.exportTxs
)
val transactionServer = new TransactionServer()
val infosServer = new InfosServer(TokenSupplyService, BlockService, TransactionService)
val infosServer =
new InfosServer(TokenSupplyService, BlockService, TransactionService, servicesConfig)
val utilsServer: UtilsServer = new UtilsServer()
val chartsServer: ChartsServer = new ChartsServer(maxTimeIntervals.charts)
val chartsServer: ChartsServer = new ChartsServer(maxTimeIntervals.charts, servicesConfig)
val tokenServer: TokenServer = new TokenServer(TokenService)
val mempoolServer = new MempoolServer()
val mempoolServer = new MempoolServer(servicesConfig.mempoolSync)
val eventServer = new EventServer()
val contractServer = new ContractServer()
val marketServer = new MarketServer(marketService)
val documentationServer = new DocumentationServer(maxTimeIntervals.exportTxs)
val documentationServer = new DocumentationServer(maxTimeIntervals.exportTxs, servicesConfig)

blockServer.routes ++
addressServer.routes ++
Expand Down
3 changes: 2 additions & 1 deletion app/src/main/scala/org/alephium/explorer/ExplorerState.scala
Original file line number Diff line number Diff line change
Expand Up @@ -97,7 +97,8 @@ sealed trait ExplorerStateRead extends ExplorerState {
config.exportTxsNumberThreshold,
config.streamParallelism,
config.maxTimeInterval,
config.market
config.market,
config.services
)(
executionContext,
database.databaseConfig,
Expand Down
173 changes: 124 additions & 49 deletions app/src/main/scala/org/alephium/explorer/docs/Documentation.scala
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,15 @@ import sttp.apispec.openapi.OpenAPI
import sttp.tapir.docs.openapi.OpenAPIDocsInterpreter

import org.alephium.explorer.api._
import org.alephium.explorer.config.ExplorerConfig

@SuppressWarnings(
Array(
"org.wartremover.warts.JavaSerializable",
"org.wartremover.warts.Product",
"org.wartremover.warts.Serializable"
)
)
trait Documentation
extends BlockEndpoints
with TransactionEndpoints
Expand All @@ -36,59 +44,126 @@ trait Documentation
with UtilsEndpoints
with OpenAPIDocsInterpreter {

lazy val docs: OpenAPI = addComponents(
toOpenAPI(
def servicesConfig: ExplorerConfig.Services

private lazy val blocks = List(
listBlocks,
getBlockByHash,
getBlockTransactions
)

private lazy val transactions = List(
getTransactionById
)

private lazy val addresses = List(
getTransactionById,
getAddressInfo,
getTransactionsByAddress,
getTransactionsByAddresses,
getTransactionsByAddressTimeRanged,
getTotalTransactionsByAddress,
addressMempoolTransactions,
getAddressBalance,
listAddressTokens,
listAddressTokenTransactions,
getAddressTokenBalance,
listAddressTokensBalance,
areAddressesActive,
exportTransactionsCsvByAddress,
getAddressAmountHistoryDEPRECATED,
getAddressAmountHistory
)

private lazy val infos = List(
getInfos,
getHeights,
getAverageBlockTime
)

private lazy val tokens = List(
listTokens,
listTokenTransactions,
listTokenAddresses,
listTokenInfo,
listFungibleTokenMetadata,
listNFTMetadata,
listNFTCollectionMetadata
)

private lazy val events = List(
getEventsByTxId,
getEventsByContractAddress,
getEventsByContractAndInputAddress
)

private lazy val contracts = List(
getParentAddress,
getSubContracts
)

private lazy val mempool =
if (servicesConfig.mempoolSync.enable) {
List(
listMempoolTransactions
)
} else {
List.empty
}

private lazy val tokenSupply =
if (servicesConfig.tokenSupply.enable) {
List(
listBlocks,
getBlockByHash,
getBlockTransactions,
getTransactionById,
getAddressInfo,
getTransactionsByAddress,
getTransactionsByAddresses,
getTransactionsByAddressTimeRanged,
getTotalTransactionsByAddress,
addressMempoolTransactions,
getAddressBalance,
listAddressTokens,
listAddressTokenTransactions,
getAddressTokenBalance,
listAddressTokensBalance,
areAddressesActive,
exportTransactionsCsvByAddress,
getAddressAmountHistoryDEPRECATED,
getAddressAmountHistory,
getInfos,
getHeights,
listMempoolTransactions,
listTokens,
listTokenTransactions,
listTokenAddresses,
listTokenSupply,
listTokenInfo,
listFungibleTokenMetadata,
listNFTMetadata,
listNFTCollectionMetadata,
getTotalSupply,
getCirculatingSupply,
getTotalSupply,
getReservedSupply,
getLockedSupply,
getTotalTransactions,
getAverageBlockTime,
getHashrates,
getAllChainsTxCount,
getPerChainTxCount,
getEventsByTxId,
getEventsByContractAddress,
getEventsByContractAndInputAddress,
getParentAddress,
getSubContracts,
getPrices,
getPriceChart,
sanityCheck,
changeGlobalLogLevel,
changeLogConfig
),
getLockedSupply
)
} else {
List.empty
}

private lazy val hashrate =
if (servicesConfig.hashrate.enable) {
List(getHashrates)
} else {
List.empty
}

private lazy val txHistory =
if (servicesConfig.txHistory.enable) {
List(getAllChainsTxCount, getPerChainTxCount)
} else {
List.empty
}

private lazy val market = List(
getPrices,
getPriceChart
)

private lazy val utils = List(
sanityCheck,
changeGlobalLogLevel,
changeLogConfig
)

lazy val docs: OpenAPI = addComponents(
toOpenAPI(
blocks ++
transactions ++
mempool ++
addresses ++
infos ++
tokenSupply ++
tokens ++
events ++
contracts ++
hashrate ++
txHistory ++
market ++
utils,
"Alephium Explorer API",
"1.0"
)
Expand Down
60 changes: 36 additions & 24 deletions app/src/main/scala/org/alephium/explorer/web/ChartsServer.scala
Original file line number Diff line number Diff line change
Expand Up @@ -32,39 +32,51 @@ import org.alephium.explorer.config.ExplorerConfig
import org.alephium.explorer.service.{HashrateService, TransactionHistoryService}

class ChartsServer(
maxTimeInterval: ExplorerConfig.MaxTimeInterval
maxTimeInterval: ExplorerConfig.MaxTimeInterval,
services: ExplorerConfig.Services
)(implicit
val executionContext: ExecutionContext,
dc: DatabaseConfig[PostgresProfile]
) extends Server
with ChartsEndpoints {

val routes: ArraySeq[Router => Route] =
ArraySeq(
route(getHashrates.serverLogic[Future] { case (timeInterval, interval) =>
validateTimeInterval(timeInterval, interval) {
HashrateService.get(timeInterval.from, timeInterval.to, interval)
}
}),
route(getAllChainsTxCount.serverLogic[Future] { case (timeInterval, interval) =>
validateTimeInterval(timeInterval, interval) {
TransactionHistoryService
.getAllChains(timeInterval.from, timeInterval.to, interval)
.map { seq =>
seq.map { case (timestamp, count) =>
TimedCount(timestamp, count)
val hashrateRoutes: Option[ArraySeq[Router => Route]] =
Option.when(services.hashrate.enable)(
ArraySeq(
route(getHashrates.serverLogic[Future] { case (timeInterval, interval) =>
validateTimeInterval(timeInterval, interval) {
HashrateService.get(timeInterval.from, timeInterval.to, interval)
}
})
)
)

val txHistoryRoutes: Option[ArraySeq[Router => Route]] =
Option.when(services.txHistory.enable)(
ArraySeq(
route(getAllChainsTxCount.serverLogic[Future] { case (timeInterval, interval) =>
validateTimeInterval(timeInterval, interval) {
TransactionHistoryService
.getAllChains(timeInterval.from, timeInterval.to, interval)
.map { seq =>
seq.map { case (timestamp, count) =>
TimedCount(timestamp, count)
}
}
}
}
}),
route(getPerChainTxCount.serverLogic[Future] { case (timeInterval, interval) =>
validateTimeInterval(timeInterval, interval) {
TransactionHistoryService
.getPerChain(timeInterval.from, timeInterval.to, interval)
}
})
}
}),
route(getPerChainTxCount.serverLogic[Future] { case (timeInterval, interval) =>
validateTimeInterval(timeInterval, interval) {
TransactionHistoryService
.getPerChain(timeInterval.from, timeInterval.to, interval)
}
})
)
)

val routes: ArraySeq[Router => Route] =
hashrateRoutes.getOrElse(ArraySeq.empty) ++ txHistoryRoutes.getOrElse(ArraySeq.empty)

private def validateTimeInterval[A](timeInterval: TimeInterval, intervalType: IntervalType)(
contd: => Future[A]
): Future[Either[ApiError[_ <: StatusCode], A]] =
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,11 +22,15 @@ import io.vertx.ext.web._

import org.alephium.api.OpenAPIWriters.openApiJson
import org.alephium.explorer.GroupSetting
import org.alephium.explorer.config.ExplorerConfig
import org.alephium.explorer.docs.Documentation
import org.alephium.http.SwaggerUI
import org.alephium.util.Duration

class DocumentationServer(val maxTimeIntervalExportTxs: Duration)(implicit
class DocumentationServer(
val maxTimeIntervalExportTxs: Duration,
val servicesConfig: ExplorerConfig.Services
)(implicit
groupSetting: GroupSetting
) extends Server
with Documentation {
Expand Down
Loading

0 comments on commit aa38600

Please sign in to comment.