mirror of
https://github.com/digital-asset/daml.git
synced 2024-09-19 16:57:40 +03:00
API version service [KVL-541] (#7792)
This change exposes a new endpoint with information about the ledger API version. The current approach is to read contents of ledger-api/VERSION and provide it as it is to the user. CHANGELOG_BEGIN - ledger API version endpoint CHANGELOG_END
This commit is contained in:
parent
1478669e2d
commit
9a2317cbdb
@ -41,6 +41,7 @@ all cases, the Ledger API exposes the same services:
|
||||
- Use the :ref:`package service <package-service>` to query the DAML packages deployed to the ledger.
|
||||
- Use the :ref:`ledger identity service <ledger-identity-service>` to retrieve the Ledger ID of the ledger the application is connected to.
|
||||
- Use the :ref:`ledger configuration service <ledger-configuration-service>` to retrieve some dynamic properties of the ledger, like maximum deduplication time for commands.
|
||||
- Use the :ref:`version service <version-service>` to retrieve information about the Ledger API version.
|
||||
- Testing services (on Sandbox only, *not* for production ledgers)
|
||||
|
||||
- Use the :ref:`time service <time-service>` to obtain the time as known by the ledger.
|
||||
|
@ -197,6 +197,15 @@ This configuration includes the maximum command deduplication time (see `Command
|
||||
|
||||
For full details, see :ref:`the proto documentation for the service <com.daml.ledger.api.v1.LedgerConfigurationService>`.
|
||||
|
||||
.. _version-service:
|
||||
|
||||
Version service
|
||||
============================
|
||||
|
||||
Use the **version service** to retrieve information about the Ledger API version.
|
||||
|
||||
For full details, see :ref:`the proto documentation for the service <com.daml.ledger.api.v1.VersionService>`.
|
||||
|
||||
.. _ledger-api-testing-services:
|
||||
|
||||
Testing services
|
||||
|
@ -25,7 +25,7 @@ Application Portability and to some extent Network Upgradeability are achieved b
|
||||
|
||||
Specifically, if a DAML Application is built against Ledger API version X.Y.Z and a Participant Node exposes Ledger API version X.Y2.Z2, the application is guaranteed to work as long as Y2.Z2 >= Y.Z.
|
||||
|
||||
Currently, the Ledger API version is the same as the version of the Integration Components used in the Participant Node. This is mostly the case because there has been no need for the versions to diverge yet. This will likely change at the latest when one part of the ecosystem moves to version 2.X. integration components, DAML drivers, and Participant Nodes advertise the Ledger API version they expose.
|
||||
Before SDK 1.7, the Ledger API version exposed by the Participant Node matches the SDK version. Currently, these versions can diverge. Integration Components, DAML Drivers, and Participant Nodes advertise the Ledger API version they expose.
|
||||
|
||||
As a concrete example, DAML for Postgres 1.4.0 has the Participant Node integrated, and exposes Ledger API version 1.4.0 and the DAML for VMware Blockchain 1.0 Participant Nodes expose Ledger API version 1.6.0. So any application that runs on DAML for Postgres 1.4.0 will also run on DAML for VMware Blockchain 1.0.
|
||||
|
||||
|
@ -1,2 +1,12 @@
|
||||
# Copyright (c) 2020 Digital Asset (Switzerland) GmbH and/or its affiliates. All rights reserved.
|
||||
# SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
filegroup(
|
||||
name = "api-version-files",
|
||||
srcs = [
|
||||
"VERSION",
|
||||
],
|
||||
visibility = [
|
||||
"//visibility:public",
|
||||
],
|
||||
)
|
||||
|
@ -1 +1 @@
|
||||
1.0.0
|
||||
1.7.0
|
||||
|
@ -0,0 +1,31 @@
|
||||
// Copyright (c) 2020 Digital Asset (Switzerland) GmbH and/or its affiliates. All rights reserved.
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
syntax = "proto3";
|
||||
|
||||
package com.daml.ledger.api.v1;
|
||||
|
||||
option java_outer_classname = "VersionServiceOuterClass";
|
||||
option java_package = "com.daml.ledger.api.v1";
|
||||
option csharp_namespace = "Com.Daml.Ledger.Api.V1";
|
||||
|
||||
// Allows clients to retrieve information about the ledger API version
|
||||
service VersionService {
|
||||
|
||||
// Read the Ledger API version
|
||||
rpc GetLedgerApiVersion (GetLedgerApiVersionRequest) returns (GetLedgerApiVersionResponse);
|
||||
}
|
||||
|
||||
message GetLedgerApiVersionRequest {
|
||||
|
||||
// Must correspond to the ledger ID reported by the Ledger Identification Service.
|
||||
// Must be a valid LedgerString (as described in ``value.proto``).
|
||||
// Required
|
||||
string ledger_id = 1;
|
||||
}
|
||||
|
||||
message GetLedgerApiVersionResponse {
|
||||
|
||||
// The version of the ledger API
|
||||
string version = 1;
|
||||
}
|
@ -64,6 +64,18 @@ final class LedgerClientIT
|
||||
}
|
||||
}
|
||||
|
||||
"get api version" in {
|
||||
// semantic versioning regex as in: https://semver.org/#is-there-a-suggested-regular-expression-regex-to-check-a-semver-string
|
||||
val semVerRegex =
|
||||
"""^(0|[1-9]\d*)\.(0|[1-9]\d*)\.(0|[1-9]\d*)(?:-((?:0|[1-9]\d*|\d*[a-zA-Z-][0-9a-zA-Z-]*)(?:\.(?:0|[1-9]\d*|\d*[a-zA-Z-][0-9a-zA-Z-]*))*))?(?:\+([0-9a-zA-Z-]+(?:\.[0-9a-zA-Z-]+)*))?$"""
|
||||
for {
|
||||
client <- LedgerClient(channel, ClientConfiguration)
|
||||
version <- client.versionClient.getApiVersion()
|
||||
} yield {
|
||||
version should fullyMatch regex semVerRegex
|
||||
}
|
||||
}
|
||||
|
||||
"shut down the channel when closed" in {
|
||||
for {
|
||||
client <- LedgerClient(channel, ClientConfiguration)
|
||||
|
@ -18,6 +18,7 @@ import com.daml.ledger.api.v1.command_submission_service.CommandSubmissionServic
|
||||
import com.daml.ledger.api.v1.ledger_identity_service.LedgerIdentityServiceGrpc
|
||||
import com.daml.ledger.api.v1.package_service.PackageServiceGrpc
|
||||
import com.daml.ledger.api.v1.transaction_service.TransactionServiceGrpc
|
||||
import com.daml.ledger.api.v1.version_service.VersionServiceGrpc
|
||||
import com.daml.ledger.client.configuration.LedgerClientConfiguration
|
||||
import com.daml.ledger.client.services.acs.ActiveContractSetClient
|
||||
import com.daml.ledger.client.services.admin.{PackageManagementClient, PartyManagementClient}
|
||||
@ -25,6 +26,7 @@ import com.daml.ledger.client.services.commands.{CommandClient, SynchronousComma
|
||||
import com.daml.ledger.client.services.identity.LedgerIdentityClient
|
||||
import com.daml.ledger.client.services.pkg.PackageClient
|
||||
import com.daml.ledger.client.services.transactions.TransactionClient
|
||||
import com.daml.ledger.client.services.version.VersionClient
|
||||
import io.grpc.netty.NettyChannelBuilder
|
||||
import io.grpc.stub.AbstractStub
|
||||
import io.grpc.{Channel, ManagedChannel}
|
||||
@ -71,6 +73,9 @@ final class LedgerClient private (
|
||||
ledgerId,
|
||||
LedgerClient.stub(TransactionServiceGrpc.stub(channel), config.token))
|
||||
|
||||
val versionClient: VersionClient =
|
||||
new VersionClient(ledgerId, LedgerClient.stub(VersionServiceGrpc.stub(channel), config.token))
|
||||
|
||||
override def close(): Unit =
|
||||
channel match {
|
||||
case channel: ManagedChannel =>
|
||||
|
@ -0,0 +1,23 @@
|
||||
// Copyright (c) 2020 Digital Asset (Switzerland) GmbH and/or its affiliates. All rights reserved.
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
package com.daml.ledger.client.services.version
|
||||
|
||||
import com.daml.dec.DirectExecutionContext
|
||||
import com.daml.ledger.api.domain.LedgerId
|
||||
import com.daml.ledger.api.v1.version_service.GetLedgerApiVersionRequest
|
||||
import com.daml.ledger.api.v1.version_service.VersionServiceGrpc.VersionServiceStub
|
||||
import com.daml.ledger.client.LedgerClient
|
||||
import scalaz.syntax.tag._
|
||||
|
||||
import scala.concurrent.Future
|
||||
|
||||
class VersionClient(ledgerId: LedgerId, service: VersionServiceStub) {
|
||||
|
||||
def getApiVersion(token: Option[String] = None): Future[String] =
|
||||
LedgerClient
|
||||
.stub(service, token)
|
||||
.getLedgerApiVersion(new GetLedgerApiVersionRequest(ledgerId.unwrap))
|
||||
.map(_.version)(DirectExecutionContext)
|
||||
|
||||
}
|
@ -81,7 +81,9 @@ da_scala_library(
|
||||
# Do not include logback.xml into the library: let the user
|
||||
# of the sandbox-as-a-library decide how to log.
|
||||
exclude = ["src/main/resources/logback.xml"],
|
||||
),
|
||||
) + [
|
||||
"//ledger-api:api-version-files",
|
||||
],
|
||||
tags = ["maven_coordinates=com.daml:participant-integration-api:__VERSION__"],
|
||||
visibility = [
|
||||
"//visibility:public",
|
||||
|
@ -134,6 +134,9 @@ private[daml] object ApiServices {
|
||||
val apiLedgerIdentityService =
|
||||
ApiLedgerIdentityService.create(() => identityService.getLedgerId())
|
||||
|
||||
val apiVersionService =
|
||||
ApiVersionService.create()
|
||||
|
||||
val apiPackageService = ApiPackageService.create(ledgerId, packagesService)
|
||||
|
||||
val apiConfigurationService =
|
||||
@ -178,6 +181,7 @@ private[daml] object ApiServices {
|
||||
new ActiveContractsServiceAuthorization(apiActiveContractsService, authorizer),
|
||||
apiReflectionService,
|
||||
apiHealthService,
|
||||
apiVersionService,
|
||||
)
|
||||
}
|
||||
|
||||
@ -284,4 +288,5 @@ private[daml] object ApiServices {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -0,0 +1,69 @@
|
||||
// Copyright (c) 2020 Digital Asset (Switzerland) GmbH and/or its affiliates. All rights reserved.
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
package com.daml.platform.apiserver.services
|
||||
|
||||
import com.daml.ledger.api.v1.version_service.GetLedgerApiVersionRequest
|
||||
import com.daml.ledger.api.v1.version_service.GetLedgerApiVersionResponse
|
||||
import com.daml.ledger.api.v1.version_service.VersionServiceGrpc
|
||||
import com.daml.ledger.api.v1.version_service.VersionServiceGrpc.VersionService
|
||||
import com.daml.logging.ContextualizedLogger
|
||||
import com.daml.logging.LoggingContext
|
||||
import com.daml.platform.api.grpc.GrpcApiService
|
||||
import io.grpc.ServerServiceDefinition
|
||||
import io.grpc.Status
|
||||
|
||||
import scala.concurrent.ExecutionContext
|
||||
import scala.concurrent.Future
|
||||
import scala.io.Source
|
||||
import scala.util.Try
|
||||
import scala.util.control.NonFatal
|
||||
|
||||
private[apiserver] final class ApiVersionService private (
|
||||
implicit loggingContext: LoggingContext,
|
||||
ec: ExecutionContext)
|
||||
extends VersionService
|
||||
with GrpcApiService {
|
||||
|
||||
private val logger = ContextualizedLogger.get(this.getClass)
|
||||
|
||||
private val versionFile: String = "ledger-api/VERSION"
|
||||
private lazy val apiVersion: Try[String] = readVersion(versionFile)
|
||||
|
||||
override def getLedgerApiVersion(
|
||||
request: GetLedgerApiVersionRequest): Future[GetLedgerApiVersionResponse] =
|
||||
Future
|
||||
.fromTry(apiVersion)
|
||||
.map(GetLedgerApiVersionResponse(_))
|
||||
.andThen(logger.logErrorsOnCall[GetLedgerApiVersionResponse])
|
||||
.recoverWith {
|
||||
case NonFatal(_) => internalError
|
||||
}
|
||||
|
||||
private lazy val internalError: Future[Nothing] =
|
||||
Future.failed(
|
||||
Status.INTERNAL
|
||||
.withDescription("Cannot read Ledger API version")
|
||||
.asRuntimeException()
|
||||
)
|
||||
|
||||
private def readVersion(versionFileName: String): Try[String] =
|
||||
Try {
|
||||
Source
|
||||
.fromResource(versionFileName)
|
||||
.getLines()
|
||||
.toList
|
||||
.head
|
||||
}
|
||||
|
||||
override def bindService(): ServerServiceDefinition =
|
||||
VersionServiceGrpc.bindService(this, ec)
|
||||
|
||||
override def close(): Unit = ()
|
||||
|
||||
}
|
||||
|
||||
private[apiserver] object ApiVersionService {
|
||||
def create()(implicit loggingContext: LoggingContext, ec: ExecutionContext): ApiVersionService =
|
||||
new ApiVersionService
|
||||
}
|
@ -30,10 +30,13 @@ final class ReflectionIT
|
||||
"accessed" should {
|
||||
|
||||
"provide a list of exposed services" in {
|
||||
val expectedServiceCount: Int = 16
|
||||
for {
|
||||
response <- execRequest(listServices)
|
||||
} yield {
|
||||
response.getListServicesResponse.getServiceCount shouldEqual 15
|
||||
withClue("ServiceCount: ") {
|
||||
response.getListServicesResponse.getServiceCount shouldEqual expectedServiceCount
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user