diff --git a/.gitignore b/.gitignore index 6c172b698..5c94a8e1f 100644 --- a/.gitignore +++ b/.gitignore @@ -70,3 +70,4 @@ apps/splitwell/src/test/resources/splitwell-bundle*.tar.gz **/SingletonCookie __pycache__/ +docs/src/deployment/observability/metrics_reference.rst diff --git a/LATEST_RELEASE b/LATEST_RELEASE index 667843220..940ac09aa 100644 --- a/LATEST_RELEASE +++ b/LATEST_RELEASE @@ -1 +1 @@ -0.3.8 +0.3.9 diff --git a/VERSION b/VERSION index 940ac09aa..5503126d5 100644 --- a/VERSION +++ b/VERSION @@ -1 +1 @@ -0.3.9 +0.3.10 diff --git a/apps/app/src/test/scala/org/lfdecentralizedtrust/splice/integration/tests/DockerComposeValidatorFrontendIntegrationTest.scala b/apps/app/src/test/scala/org/lfdecentralizedtrust/splice/integration/tests/DockerComposeValidatorFrontendIntegrationTest.scala index 60bb02afa..c8b0a5fe9 100644 --- a/apps/app/src/test/scala/org/lfdecentralizedtrust/splice/integration/tests/DockerComposeValidatorFrontendIntegrationTest.scala +++ b/apps/app/src/test/scala/org/lfdecentralizedtrust/splice/integration/tests/DockerComposeValidatorFrontendIntegrationTest.scala @@ -1,5 +1,11 @@ package org.lfdecentralizedtrust.splice.integration.tests +import com.digitalasset.canton.integration.BaseEnvironmentDefinition +import org.apache.pekko.actor.ActorSystem +import org.apache.pekko.http.scaladsl.Http +import org.apache.pekko.http.scaladsl.client.RequestBuilding.Get +import org.apache.pekko.http.scaladsl.model.StatusCodes +import org.apache.pekko.http.scaladsl.model.headers.Host import org.lfdecentralizedtrust.splice.environment.EnvironmentImpl import org.lfdecentralizedtrust.splice.integration.EnvironmentDefinition import org.lfdecentralizedtrust.splice.integration.tests.SpliceTests.SpliceTestConsoleEnvironment @@ -8,13 +14,12 @@ import org.lfdecentralizedtrust.splice.util.{ FrontendLoginUtil, WalletFrontendTestUtil, } -import com.digitalasset.canton.integration.BaseEnvironmentDefinition +import java.lang.ProcessBuilder +import java.nio.file.{Path, Paths} import scala.concurrent.duration.* import scala.jdk.CollectionConverters.* import scala.sys.process.* -import java.lang.ProcessBuilder -import java.nio.file.{Path, Paths} class DockerComposeValidatorFrontendIntegrationTest extends FrontendIntegrationTest("frontend") @@ -32,7 +37,7 @@ class DockerComposeValidatorFrontendIntegrationTest extraClue: String = "", startFlags: Seq[String] = Seq.empty, extraEnv: Seq[(String, String)] = Seq.empty, - ) = { + ): Unit = { val command = (Seq( "build-tools/splice-compose.sh", "start", @@ -246,6 +251,32 @@ class DockerComposeValidatorFrontendIntegrationTest ) } } + + clue("validator and participant metrics work") { + implicit val sys: ActorSystem = env.actorSystem + registerHttpConnectionPoolsCleanup(env) + + def metricsAreAvailableFor(node: String) = { + val result = Http() + .singleRequest( + Get(s"http://localhost/metrics") + // java can't resolve the *.localhost domain, so we need to set the Host header manually + .withHeaders(Host(s"$node.localhost")) + ) + .futureValue + result.status should be(StatusCodes.OK) + result.entity.toStrict(10.seconds).futureValue.data.utf8String should include( + "target_info" // basic metric included by opentelemtry + ) + } + + metricsAreAvailableFor( + "validator" + ) + metricsAreAvailableFor( + "participant" + ) + } } } diff --git a/apps/common/frontend/src/contexts/LedgerApiContext.tsx b/apps/common/frontend/src/contexts/LedgerApiContext.tsx index 778439f85..11df48873 100644 --- a/apps/common/frontend/src/contexts/LedgerApiContext.tsx +++ b/apps/common/frontend/src/contexts/LedgerApiContext.tsx @@ -67,8 +67,15 @@ export class LedgerApiClient { const response = await fetch(`${this.jsonApiUrl}v2/users/${encodeURIComponent(userId)}`, { headers: this.headers, }); - const responseBody = await response.json(); - return responseBody.user; + if (response.ok) { + const responseBody = await response.json(); + return responseBody.user; + } else { + const responseBody = await response.text(); + throw new Error( + `getPrimaryParty: HTTP ${response.status} ${response.statusText}: ${responseBody}` + ); + } }, this.userId ); @@ -119,28 +126,27 @@ export class LedgerApiClient { package_id_selection_preference: [], }; + const describeChoice = `Exercised choice: actAs=${JSON.stringify( + actAs + )}, readAs=${JSON.stringify(readAs)}, choiceName=${choice.choiceName}, templateId=${ + choice.template().templateId + }, contractId=${contractId}`; + const responseBody = await fetch( `${this.jsonApiUrl}v2/commands/submit-and-wait-for-transaction-tree`, { headers: this.headers, method: 'POST', body: JSON.stringify(body) } ) - .then(r => { - console.debug( - `Exercised choice: actAs=${JSON.stringify(actAs)}, readAs=${JSON.stringify( - readAs - )}, choiceName=${choice.choiceName}, templateId=${ - choice.template().templateId - }, contractId=${contractId} succeeded.` - ); - return r.json(); + .then(async r => { + if (r.ok) { + console.debug(`${describeChoice} succeeded.`); + return r.json(); + } else { + const body = await r.text(); + throw new Error(`HTTP ${r.status} ${r.statusText}: ${body}`); + } }) .catch(e => { - console.debug( - `Exercised choice: actAs=${JSON.stringify(actAs)}, readAs=${JSON.stringify( - readAs - )}, choiceName=${choice.choiceName}, templateId=${ - choice.template().templateId - }, contractId=${contractId} failed: ${JSON.stringify(e)}` - ); + console.debug(`${describeChoice} failed: ${JSON.stringify(e)}`); throw e; }); diff --git a/apps/common/src/main/scala/org/lfdecentralizedtrust/splice/store/DomainParamsStore.scala b/apps/common/src/main/scala/org/lfdecentralizedtrust/splice/store/DomainParamsStore.scala index c7e63496d..a1a9c32b4 100644 --- a/apps/common/src/main/scala/org/lfdecentralizedtrust/splice/store/DomainParamsStore.scala +++ b/apps/common/src/main/scala/org/lfdecentralizedtrust/splice/store/DomainParamsStore.scala @@ -142,7 +142,7 @@ object DomainParamsStore { domainUnpausedPromise: Option[Promise[Unit]], ) - private class Metrics(metricsFactory: LabeledMetricsFactory) extends AutoCloseable { + class Metrics(metricsFactory: LabeledMetricsFactory) extends AutoCloseable { private val prefix: MetricName = SpliceMetrics.MetricsPrefix :+ "domain_params_store" diff --git a/apps/common/src/test/scala/org/lfdecentralizedtrust/splice/store/db/SpliceDbTest.scala b/apps/common/src/test/scala/org/lfdecentralizedtrust/splice/store/db/SpliceDbTest.scala index 65ed9e9fc..4f0bdebd6 100644 --- a/apps/common/src/test/scala/org/lfdecentralizedtrust/splice/store/db/SpliceDbTest.scala +++ b/apps/common/src/test/scala/org/lfdecentralizedtrust/splice/store/db/SpliceDbTest.scala @@ -106,14 +106,18 @@ trait SpliceDbTest extends DbTest with BeforeAndAfterAll { this: Suite => val dbLockPort: Int = 54321 implicit val tc: TraceContext = TraceContext.empty logger.info("Acquiring SpliceDbTest lock") - val lockTimeout = 10.minutes // expectation: Db tests won't take longer than 5m + // Needs to be long enough to allow all other concurrently started tests to finish, + // we therefore use a time roughly equal to the expected maximal duration of the entire CI job. + val lockTimeout = 20.minutes dbLockSocket = BaseTest.eventually(lockTimeout)( Try(new ServerSocket(dbLockPort)) .fold( e => { logger.debug(s"Acquiring SpliceDbTest lock: port $dbLockPort is in use") throw new TestFailedException( - s"Failed to acquire lock within timeout ($lockTimeout).", + s"Failed to acquire lock within timeout ($lockTimeout). " + + "We start many tests suites in parallel but wait for the lock before actually running test in this suite. " + + "Either increase the timeout, or reduce the number of test suites running in the same CI job.", e, 0, ) diff --git a/apps/metrics-docs/src/main/scala/org/lfdecentralizedtrust/splice/metrics/MetricsDocs.scala b/apps/metrics-docs/src/main/scala/org/lfdecentralizedtrust/splice/metrics/MetricsDocs.scala new file mode 100644 index 000000000..39f08b24c --- /dev/null +++ b/apps/metrics-docs/src/main/scala/org/lfdecentralizedtrust/splice/metrics/MetricsDocs.scala @@ -0,0 +1,111 @@ +// Copyright (c) 2024 Digital Asset (Switzerland) GmbH and/or its affiliates. All rights reserved. +// SPDX-License-Identifier: Apache-2.0 + +package org.lfdecentralizedtrust.splice.metrics + +import better.files.File +import com.daml.metrics.api.MetricsContext +import com.digitalasset.canton.discard.Implicits.DiscardOps +import com.digitalasset.canton.metrics.{MetricDoc, MetricsDocGenerator} +import com.digitalasset.canton.topology.PartyId +import org.lfdecentralizedtrust.splice.admin.api.client.DamlGrpcClientMetrics +import org.lfdecentralizedtrust.splice.automation.TriggerMetrics +import org.lfdecentralizedtrust.splice.scan.store.db.DbScanStoreMetrics +import org.lfdecentralizedtrust.splice.sv.automation.singlesv.{SequencerPruningMetrics} +import org.lfdecentralizedtrust.splice.sv.automation.ReportSvStatusMetricsExportTrigger +import org.lfdecentralizedtrust.splice.sv.store.db.DbSvDsoStoreMetrics +import org.lfdecentralizedtrust.splice.store.{DomainParamsStore, HistoryMetrics, StoreMetrics} +import org.lfdecentralizedtrust.splice.wallet.metrics.AmuletMetrics + +final case class GeneratedMetrics( + common: List[MetricDoc.Item], + validator: List[MetricDoc.Item], + sv: List[MetricDoc.Item], + scan: List[MetricDoc.Item], +) { + def render(): String = + Seq( + s"""|.. + | Copyright (c) 2024 Digital Asset (Switzerland) GmbH and/or its affiliates. All rights reserved. + |.. + | SPDX-License-Identifier: Apache-2.0 + | + |.. _metrics-reference: + | + |Metrics Reference + |================= + |""".stripMargin, + renderSection("Common", common), + renderSection("Validator", validator), + renderSection("SV", sv), + renderSection("Scan", scan), + ).mkString("\n") + + def renderSection(prefix: String, metrics: List[MetricDoc.Item]): String = { + val header = s"$prefix Metrics" + (Seq( + header, + "+" * header.length, + ) ++ + // We seem to automatically pull in the daml.cache metrics which make no sense for splice at this point + metrics.filter(m => !m.name.startsWith("daml.cache")).map(renderMetric(_))).mkString("\n") + } + + def renderMetric(metric: MetricDoc.Item): String = + Seq( + metric.name, + "^" * metric.name.length, + s"* **Summary**: ${metric.summary}", + s"* **Description**: ${metric.description}", + s"* **Type**: ${metric.metricType}", + s"* **Qualification**: ${metric.qualification}", + "\n", + ).mkString("\n") +} + +object MetricsDocs { + private def metricsDocs(): GeneratedMetrics = { + val walletUserParty = PartyId.tryFromProtoPrimitive("wallet_user::namespace") + val svParty = PartyId.tryFromProtoPrimitive("sv::namespace") + val generator = new MetricsDocGenerator() + // common + new DomainParamsStore.Metrics(generator) + new HistoryMetrics(generator)(MetricsContext.Empty) + new StoreMetrics(generator)(MetricsContext.Empty) + new DamlGrpcClientMetrics(generator, "") + new TriggerMetrics(generator) + val commonMetrics = generator.getAll() + generator.reset() + // validator + new AmuletMetrics(walletUserParty, generator) + val validatorMetrics = generator.getAll() + generator.reset() + // sv + new DbSvDsoStoreMetrics(generator) + new SequencerPruningMetrics(generator) + new ReportSvStatusMetricsExportTrigger.SvCometBftMetrics(generator) + new ReportSvStatusMetricsExportTrigger.SvStatusMetrics( + ReportSvStatusMetricsExportTrigger.SvId(svParty.toProtoPrimitive, "svName"), + generator, + ) + val svMetrics = generator.getAll() + generator.reset() + // scan + new DbScanStoreMetrics(generator) + val scanMetrics = generator.getAll() + generator.reset() + GeneratedMetrics( + commonMetrics, + validatorMetrics, + svMetrics, + scanMetrics, + ) + } + + def main(args: Array[String]): Unit = { + val file = File(args(0)) + file.parent.createDirectoryIfNotExists() + val docs = metricsDocs() + file.overwrite(docs.render()).discard[File] + } +} diff --git a/apps/sv/src/main/scala/org/lfdecentralizedtrust/splice/sv/automation/ReportSvStatusMetricsExportTrigger.scala b/apps/sv/src/main/scala/org/lfdecentralizedtrust/splice/sv/automation/ReportSvStatusMetricsExportTrigger.scala index 9c204d26b..caff46503 100644 --- a/apps/sv/src/main/scala/org/lfdecentralizedtrust/splice/sv/automation/ReportSvStatusMetricsExportTrigger.scala +++ b/apps/sv/src/main/scala/org/lfdecentralizedtrust/splice/sv/automation/ReportSvStatusMetricsExportTrigger.scala @@ -151,9 +151,9 @@ class ReportSvStatusMetricsExportTrigger( object ReportSvStatusMetricsExportTrigger { - private case class SvId(svParty: String, svName: String) + case class SvId(svParty: String, svName: String) - private case class SvCometBftMetrics( + case class SvCometBftMetrics( metricsFactory: LabeledMetricsFactory ) extends AutoCloseable { @@ -188,7 +188,7 @@ object ReportSvStatusMetricsExportTrigger { } } - private case class SvStatusMetrics( + case class SvStatusMetrics( svId: SvId, metricsFactory: LabeledMetricsFactory, ) extends AutoCloseable { diff --git a/build.sbt b/build.sbt index 26ec38c59..377dfdc15 100644 --- a/build.sbt +++ b/build.sbt @@ -84,6 +84,7 @@ lazy val root: Project = (project in file(".")) `apps-splitwell`, `apps-sv`, `apps-app`, + `apps-metrics-docs`, `apps-wallet`, `apps-frontends`, `splice-util-daml`, @@ -186,7 +187,7 @@ lazy val docs = project val srcDir = sourceDirectory.value val log = streams.value.log val cacheDir = streams.value.cacheDirectory - val cache = FileFunction.cached(cacheDir) { _ => + val cacheDamlDocs = FileFunction.cached(cacheDir) { _ => runCommand( Seq("./gen-daml-docs.sh"), log, @@ -203,9 +204,30 @@ lazy val docs = project (`splice-validator-lifecycle-daml` / Compile / damlBuild).value ++ (`splice-wallet-daml` / Compile / damlBuild).value ++ (`splice-wallet-payments-daml` / Compile / damlBuild).value - cache( + cacheDamlDocs( damlSources.toSet ).toSeq + import scala.sys.process._ + val classPath = (`apps-metrics-docs` / Runtime / dependencyClasspath).value.files + val cacheMetricsDocs = FileFunction.cached(cacheDir) { _ => + val metricsReferencePath = srcDir / "deployment" / "observability" / "metrics_reference.rst" + // This seems to be the easiest way to run a target from another SBT project and has the advantage + // that it is much faster than the approach taken by Canton of running the target from bundle with a console script. + runCommand( + Seq( + "java", + "-cp", + classPath.mkString(":"), + "org.lfdecentralizedtrust.splice.metrics.MetricsDocs", + metricsReferencePath.toString, + ), + log, + None, + Some(baseDir), + ) + Set.empty + } + cacheMetricsDocs(Set()).toSeq }.taskValue, bundle := { (Compile / resources).value @@ -1317,7 +1339,20 @@ checkErrors := { checkLogs("log/canton_network_test.clog", Seq("canton_network_test_log")) } -lazy val `apps-app` = +lazy val `apps-metrics-docs` = + project + .in(file("apps/metrics-docs")) + .dependsOn( + `apps-common`, + `apps-scan`, + `apps-sv`, + `apps-validator`, + ) + .settings( + Headers.ApacheDAHeaderSettings + ) + +lazy val `apps-app`: Project = project .in(file("apps/app")) .dependsOn( @@ -1376,6 +1411,10 @@ printTests := { def isNonDevNetTest(name: String): Boolean = name.contains("NonDevNet") def isPreflightIntegrationTest(name: String): Boolean = name.contains("PreflightIntegrationTest") + def isIntegrationTest(name: String): Boolean = + name.contains("org.lfdecentralizedtrust.splice.integration.tests") || name.contains( + "IntegrationTest" + ) def isCoreDeploymentPreflightIntegrationTest(name: String): Boolean = isPreflightIntegrationTest( name ) && !isValidator1DeploymentPreflightIntegrationTest( @@ -1434,6 +1473,11 @@ printTests := { // Order matters as each test is included in just one group, with the first match being used val testSplitRules = Seq( + ( + "Unit tests", + "test-full-class-names-non-integration.log", + (t: String) => !isIntegrationTest(t), + ), ( "Daml ciupgrade vote", "test-daml-ciupgrade-vote.log", diff --git a/canton/community/app-base/src/main/scala/com/digitalasset/canton/metrics/MetricsDocGenerator.scala b/canton/community/app-base/src/main/scala/com/digitalasset/canton/metrics/MetricsDocGenerator.scala new file mode 100644 index 000000000..3727962cc --- /dev/null +++ b/canton/community/app-base/src/main/scala/com/digitalasset/canton/metrics/MetricsDocGenerator.scala @@ -0,0 +1,67 @@ +// Copyright (c) 2025 Digital Asset (Switzerland) GmbH and/or its affiliates. All rights reserved. +// SPDX-License-Identifier: Apache-2.0 + +package com.digitalasset.canton.metrics + +import com.daml.metrics.api.MetricHandle.{Gauge, LabeledMetricsFactory} +import com.daml.metrics.api.noop.NoOpMetricsFactory +import com.daml.metrics.api.{MetricHandle, MetricInfo, MetricsContext} + +import scala.collection.mutable.ListBuffer + +/** Fake labelled factory used to collect metrics */ +class MetricsDocGenerator extends LabeledMetricsFactory { + + private val noop = NoOpMetricsFactory + + def getAll(): List[MetricDoc.Item] = assembled.toList.map { case (metricType, info) => + MetricDoc.Item( + name = info.name.toString(), + summary = info.summary, + description = info.description.stripMargin, + metricType = metricType, + qualification = info.qualification, + labelsWithDescription = info.labelsWithDescription, + ) + } + + def reset(): Unit = assembled.clear() + + private val assembled = new ListBuffer[(String, MetricInfo)]() + + override def timer(info: MetricInfo)(implicit context: MetricsContext): MetricHandle.Timer = { + assembled.addOne(("timer", info)) + noop.timer(info) + } + + override def gauge[T](info: MetricInfo, initial: T)(implicit + context: MetricsContext + ): MetricHandle.Gauge[T] = { + assembled.addOne(("gauge", info)) + noop.gauge(info, initial) + } + + override def gaugeWithSupplier[T](info: MetricInfo, gaugeSupplier: () => T)(implicit + context: MetricsContext + ): Gauge.CloseableGauge = { + assembled.addOne(("gauge", info)) + noop.gaugeWithSupplier(info, gaugeSupplier) + } + + override def meter(info: MetricInfo)(implicit context: MetricsContext): MetricHandle.Meter = { + assembled.addOne(("meter", info)) + noop.meter(info) + } + + override def counter(info: MetricInfo)(implicit context: MetricsContext): MetricHandle.Counter = { + assembled.addOne(("counter", info)) + noop.counter(info) + } + + override def histogram(info: MetricInfo)(implicit + context: MetricsContext + ): MetricHandle.Histogram = { + assembled.addOne(("histogram", info)) + noop.histogram(info) + } +} diff --git a/canton/community/common/src/main/scala/com/digitalasset/canton/metrics/MetricDoc.scala b/canton/community/common/src/main/scala/com/digitalasset/canton/metrics/MetricDoc.scala index fc10aada1..5bc6bd350 100644 --- a/canton/community/common/src/main/scala/com/digitalasset/canton/metrics/MetricDoc.scala +++ b/canton/community/common/src/main/scala/com/digitalasset/canton/metrics/MetricDoc.scala @@ -1,18 +1,19 @@ -// Copyright (c) 2024 Digital Asset (Switzerland) GmbH and/or its affiliates. All rights reserved. +// Copyright (c) 2025 Digital Asset (Switzerland) GmbH and/or its affiliates. All rights reserved. // SPDX-License-Identifier: Apache-2.0 package com.digitalasset.canton.metrics -import com.daml.metrics.api.MetricDoc.Tag import com.daml.metrics.api.MetricQualification object MetricDoc { final case class Item( - tag: Tag, name: String, + summary: String, + description: String, metricType: String, qualification: MetricQualification, + labelsWithDescription: Map[String, String], ) } diff --git a/cluster/compose/validator/nginx.conf b/cluster/compose/validator/nginx.conf index 7513e491b..dcc2bbb3a 100644 --- a/cluster/compose/validator/nginx.conf +++ b/cluster/compose/validator/nginx.conf @@ -26,4 +26,20 @@ http { proxy_pass http://ans-web-ui:80/; } } + + server { + listen 80; + server_name validator.localhost; + location /metrics { + proxy_pass http://validator:10013/metrics; + } + } + + server { + listen 80; + server_name participant.localhost; + location /metrics { + proxy_pass http://participant:10013/metrics; + } + } } diff --git a/cluster/images/splice-test-docker-runner/Dockerfile b/cluster/images/splice-test-docker-runner/Dockerfile index a5c6904fd..5687d7fc5 100644 --- a/cluster/images/splice-test-docker-runner/Dockerfile +++ b/cluster/images/splice-test-docker-runner/Dockerfile @@ -1,5 +1,5 @@ # Note that we don't currently support arm64 runners, so we build this only for amd64 -FROM --platform=$BUILDPLATFORM ghcr.io/actions/actions-runner:2.321.0 +FROM --platform=$BUILDPLATFORM ghcr.io/actions/actions-runner:2.322.0 # TODO(#15988): can we reduce duplication between this and splice-test-ci ? diff --git a/docs/src/app_dev/daml.rst b/docs/src/app_dev/daml.rst deleted file mode 100644 index 19b998915..000000000 --- a/docs/src/app_dev/daml.rst +++ /dev/null @@ -1,20 +0,0 @@ -.. - Copyright (c) 2024 Digital Asset (Switzerland) GmbH and/or its affiliates. All rights reserved. -.. - SPDX-License-Identifier: Apache-2.0 - -Daml API Reference -================== - -API docs for daml packages - - -.. toctree:: - - api/splice-amulet/index - api/splice-amulet-name-service/index - api/splice-dso-governance/index - api/splice-util/index - api/splice-validator-lifecycle/index - api/splice-wallet/index - api/splice-wallet-payments/index diff --git a/docs/src/app_dev/daml_api/index.rst b/docs/src/app_dev/daml_api/index.rst new file mode 100644 index 000000000..06a2ca23b --- /dev/null +++ b/docs/src/app_dev/daml_api/index.rst @@ -0,0 +1,22 @@ +.. + Copyright (c) 2024 Digital Asset (Switzerland) GmbH and/or its affiliates. All rights reserved. +.. + SPDX-License-Identifier: Apache-2.0 + +.. _app_dev_daml_api: + +Daml API +======== + +API docs for daml packages + + +.. toctree:: + + ../api/splice-amulet/index + ../api/splice-amulet-name-service/index + ../api/splice-dso-governance/index + ../api/splice-util/index + ../api/splice-validator-lifecycle/index + ../api/splice-wallet/index + ../api/splice-wallet-payments/index diff --git a/docs/src/app_dev/ledger_api/index.rst b/docs/src/app_dev/ledger_api/index.rst new file mode 100644 index 000000000..b95a43be3 --- /dev/null +++ b/docs/src/app_dev/ledger_api/index.rst @@ -0,0 +1,11 @@ +.. + Copyright (c) 2024 Digital Asset (Switzerland) GmbH and/or its affiliates. All rights reserved. +.. + SPDX-License-Identifier: Apache-2.0 + +.. _app_dev_ledger_api: + +Ledger API +========== + +.. todo:: Add content diff --git a/docs/src/app_dev/index.rst b/docs/src/app_dev/overview/index.rst similarity index 67% rename from docs/src/app_dev/index.rst rename to docs/src/app_dev/overview/index.rst index bd2982b30..363a7bc88 100644 --- a/docs/src/app_dev/index.rst +++ b/docs/src/app_dev/overview/index.rst @@ -3,7 +3,7 @@ .. SPDX-License-Identifier: Apache-2.0 - +.. _app_dev_overview: Overview ======== @@ -22,34 +22,6 @@ Overview .. todo:: add section on testing including spinning up localnet .. todo:: add section on deployment for app devs, e.g., DAR uploads -Version Information -=================== - -.. list-table:: - :header-rows: 0 - - * - Canton version used for validator and SV nodes - - |canton_version| - * - Daml SDK version used to compile ``.dars`` - - |daml_sdk_version| - * - Daml SDK version used for Java and TS codegens - - |daml_sdk_tooling_version| - -Testing -======= - -.. toctree:: - - localnet - - -API Reference -============= - -.. todo:: - - add overview over each API type, e.g., overview over scan - .. todo:: Add overview of how to integrate with CC at the Daml level @@ -63,5 +35,5 @@ API Reference .. toctree:: - splice_app_apis/index - daml + version_information + splice_app_apis diff --git a/docs/src/app_dev/splice_app_apis/index.rst b/docs/src/app_dev/overview/splice_app_apis.rst similarity index 100% rename from docs/src/app_dev/splice_app_apis/index.rst rename to docs/src/app_dev/overview/splice_app_apis.rst diff --git a/docs/src/app_dev/overview/version_information.rst b/docs/src/app_dev/overview/version_information.rst new file mode 100644 index 000000000..e50e3223f --- /dev/null +++ b/docs/src/app_dev/overview/version_information.rst @@ -0,0 +1,17 @@ +.. + Copyright (c) 2024 Digital Asset (Switzerland) GmbH and/or its affiliates. All rights reserved. +.. + SPDX-License-Identifier: Apache-2.0 + +Version Information +=================== + +.. list-table:: + :header-rows: 0 + + * - Canton version used for validator and SV nodes + - |canton_version| + * - Daml SDK version used to compile ``.dars`` + - |daml_sdk_version| + * - Daml SDK version used for Java and TS codegens + - |daml_sdk_tooling_version| diff --git a/docs/src/app_dev/scan_api/index.rst b/docs/src/app_dev/scan_api/index.rst new file mode 100644 index 000000000..8ceca96ef --- /dev/null +++ b/docs/src/app_dev/scan_api/index.rst @@ -0,0 +1,11 @@ +.. + Copyright (c) 2024 Digital Asset (Switzerland) GmbH and/or its affiliates. All rights reserved. +.. + SPDX-License-Identifier: Apache-2.0 + +.. _app_dev_scan_api: + +Scan API +======== + +.. todo:: Add content diff --git a/docs/src/app_dev/testing/index.rst b/docs/src/app_dev/testing/index.rst new file mode 100644 index 000000000..b9540da85 --- /dev/null +++ b/docs/src/app_dev/testing/index.rst @@ -0,0 +1,15 @@ +.. + Copyright (c) 2024 Digital Asset (Switzerland) GmbH and/or its affiliates. All rights reserved. +.. + SPDX-License-Identifier: Apache-2.0 + +.. _app_dev_testing: + +Testing +======= + +.. todo:: Add content + +.. toctree:: + + localnet diff --git a/docs/src/app_dev/localnet.rst b/docs/src/app_dev/testing/localnet.rst similarity index 100% rename from docs/src/app_dev/localnet.rst rename to docs/src/app_dev/testing/localnet.rst diff --git a/docs/src/app_dev/validator_api/index.rst b/docs/src/app_dev/validator_api/index.rst new file mode 100644 index 000000000..fa89a2c61 --- /dev/null +++ b/docs/src/app_dev/validator_api/index.rst @@ -0,0 +1,11 @@ +.. + Copyright (c) 2024 Digital Asset (Switzerland) GmbH and/or its affiliates. All rights reserved. +.. + SPDX-License-Identifier: Apache-2.0 + +.. _app_dev_validator_api: + +Validator API +============= + +.. todo:: Add content diff --git a/docs/src/conf.py b/docs/src/conf.py index c4470afc0..0487f7d89 100644 --- a/docs/src/conf.py +++ b/docs/src/conf.py @@ -132,8 +132,11 @@ .. |splice_cluster| replace:: :raw-html:`unknown_cluster` -.. |da_hostname| replace:: :raw-html:`unknown_clusterglobal.canton.network.digitalasset.com` -.. |gsf_sv_url| replace:: :raw-html:`https://sv.sv-1.unknown_clusterglobal.canton.network.sync.global` +.. |da_hostname| replace:: :raw-html:`unknown_cluster.global.canton.network.digitalasset.com` +.. |gsf_sv_url| replace:: :raw-html:`https://sv.sv-1.unknown_cluster.global.canton.network.sync.global` +.. |generic_sv_url| replace:: :raw-html:`https://sv.sv-1.unknown_cluster.global.canton.network.YOUR_SV_SPONSOR` +.. |gsf_scan_url| replace:: :raw-html:`https://scan.sv-1.unknown_cluster.global.canton.network.sync.global` +.. |generic_scan_url| replace:: :raw-html:`https://scan.sv-1.unknown_cluster.global.canton.network.YOUR_SV_SPONSOR` .. |version_literal| replace:: ``{version}`` .. |chart_version_literal| replace:: ``{chart_version}`` diff --git a/docs/src/index.rst b/docs/src/index.rst index 7bac44de0..dfe579dc3 100644 --- a/docs/src/index.rst +++ b/docs/src/index.rst @@ -20,4 +20,15 @@ Splice Documentation :maxdepth: 2 :caption: Application Developers - app_dev/index.rst + app_dev/overview/index + app_dev/scan_api/index + app_dev/validator_api/index + app_dev/ledger_api/index + app_dev/daml_api/index + app_dev/testing/index + +.. toctree:: + :maxdepth: 2 + :caption: Metrics Reference + + deployment/observability/metrics_reference.rst diff --git a/project/ignore-patterns/sbt-output.ignore.txt b/project/ignore-patterns/sbt-output.ignore.txt index 0ecf84be3..21a80317c 100644 --- a/project/ignore-patterns/sbt-output.ignore.txt +++ b/project/ignore-patterns/sbt-output.ignore.txt @@ -116,4 +116,6 @@ WARNING: Failed to fetch secret, retrying in 10 seconds # This is actually not a warning Warning: No want/action statements, nothing to do +.*The geckodriver version cannot be discovered.* + # Make sure to have a trailing newline