diff --git a/node-it/src/test/scala/com/wavesplatform/it/Docker.scala b/node-it/src/test/scala/com/wavesplatform/it/Docker.scala index 0ece957584a..56637d181f8 100644 --- a/node-it/src/test/scala/com/wavesplatform/it/Docker.scala +++ b/node-it/src/test/scala/com/wavesplatform/it/Docker.scala @@ -1,29 +1,13 @@ package com.wavesplatform.it -import java.io.{FileOutputStream, IOException} -import java.net.{InetAddress, InetSocketAddress, URL} -import java.nio.file.{Files, Path, Paths} -import java.time.LocalDateTime -import java.time.format.DateTimeFormatter -import java.util.{Properties, List as JList, Map as JMap} -import java.util.Collections.* -import java.util.concurrent.ConcurrentHashMap -import java.util.concurrent.atomic.{AtomicBoolean, AtomicInteger} -import scala.annotation.tailrec -import scala.concurrent.{Await, Future, blocking} -import scala.concurrent.ExecutionContext.Implicits.global -import scala.concurrent.duration.* -import scala.jdk.CollectionConverters.* -import scala.util.{Random, Try} -import scala.util.control.NonFatal import com.fasterxml.jackson.databind.ObjectMapper import com.fasterxml.jackson.dataformat.javaprop.JavaPropsMapper import com.google.common.primitives.Ints.* -import com.spotify.docker.client.{DefaultDockerClient, DockerClient} import com.spotify.docker.client.messages.* import com.spotify.docker.client.messages.EndpointConfig.EndpointIpamConfig -import com.typesafe.config.{Config, ConfigFactory, ConfigRenderOptions} +import com.spotify.docker.client.{DefaultDockerClient, DockerClient} import com.typesafe.config.ConfigFactory.* +import com.typesafe.config.{Config, ConfigFactory, ConfigRenderOptions} import com.wavesplatform.account.AddressScheme import com.wavesplatform.block.Block import com.wavesplatform.common.utils.EitherExt2 @@ -40,6 +24,23 @@ import org.apache.commons.compress.archivers.tar.TarArchiveEntry import org.apache.commons.io.IOUtils import org.asynchttpclient.Dsl.* +import java.io.{FileOutputStream, IOException} +import java.net.{InetAddress, InetSocketAddress, URL} +import java.nio.file.{Files, Path, Paths} +import java.time.LocalDateTime +import java.time.format.DateTimeFormatter +import java.util.Collections.* +import java.util.concurrent.ConcurrentHashMap +import java.util.concurrent.atomic.{AtomicBoolean, AtomicInteger} +import java.util.{Properties, List as JList, Map as JMap} +import scala.annotation.tailrec +import scala.concurrent.ExecutionContext.Implicits.global +import scala.concurrent.duration.* +import scala.concurrent.{Await, Future, blocking} +import scala.jdk.CollectionConverters.* +import scala.util.control.NonFatal +import scala.util.{Random, Try} + class Docker( suiteConfig: Config = empty, tag: String = "", @@ -260,10 +261,16 @@ class Docker( profilerConfigEnv ).filter(_.nonEmpty) + val exposedPorts = new java.util.HashSet[String]() + exposedPorts.add(s"$internalDebuggerPort") + if (Try(nodeConfig.getStringList("waves.extensions").contains("com.wavesplatform.events.BlockchainUpdates")).getOrElse(false)) { + exposedPorts.add("6881") + } + val containerConfig = ContainerConfig .builder() .image(imageName) - .exposedPorts(s"$internalDebuggerPort") + .exposedPorts(exposedPorts) .networkingConfig(ContainerConfig.NetworkingConfig.create(Map(wavesNetwork.name() -> endpointConfigFor(nodeName)).asJava)) .hostConfig(hostConfig) .env(envs*) diff --git a/node-it/src/test/scala/com/wavesplatform/it/grpc/GrpcReflectionApiSuite.scala b/node-it/src/test/scala/com/wavesplatform/it/grpc/GrpcReflectionApiSuite.scala new file mode 100644 index 00000000000..d5abba28b79 --- /dev/null +++ b/node-it/src/test/scala/com/wavesplatform/it/grpc/GrpcReflectionApiSuite.scala @@ -0,0 +1,41 @@ +package com.wavesplatform.it.grpc + +import com.typesafe.config.Config +import com.wavesplatform.it.NodeConfigs +import com.wavesplatform.it.NodeConfigs.Default +import com.wavesplatform.it.sync.grpc.GrpcBaseTransactionSuite +import io.grpc.{CallOptions, ManagedChannelBuilder} +import io.grpc.reflection.v1alpha.ServerReflectionGrpc.getServerReflectionInfoMethod +import io.grpc.reflection.v1alpha.ServerReflectionRequest +import io.grpc.stub.ClientCalls + +import scala.util.Try + +class GrpcReflectionApiSuite extends GrpcBaseTransactionSuite { + override protected def nodeConfigs: Seq[Config] = + NodeConfigs + .Builder(Default, 1, Seq()) + .overrideBase(_.quorum(0)) + .overrideBase(_.raw("waves.extensions = [com.wavesplatform.api.grpc.GRPCServerExtension\ncom.wavesplatform.events.BlockchainUpdates]")) + .buildNonConflicting() + + test("successful getServerReflectionInfo call for BU") { + val buChannel = ManagedChannelBuilder + .forAddress(nodes.head.networkAddress.getHostString, nodes.head.nodeExternalPort(6881)) + .usePlaintext() + .build() + val call = buChannel.newCall(getServerReflectionInfoMethod, CallOptions.DEFAULT) + val request = ServerReflectionRequest.newBuilder().setFileContainingSymbol("waves.events.grpc.BlockchainUpdatesApi").build() + val result = Try(ClientCalls.blockingUnaryCall(call, request)) + result.isSuccess shouldBe true + result.get.hasFileDescriptorResponse shouldBe true + } + + test("successful getServerReflectionInfo call for GRPC methods") { + val call = nodes.head.grpcChannel.newCall(getServerReflectionInfoMethod, CallOptions.DEFAULT) + val request = ServerReflectionRequest.newBuilder().setFileContainingSymbol("waves.node.grpc.BlocksApi").build() + val result = Try(ClientCalls.blockingUnaryCall(call, request)) + result.isSuccess shouldBe true + result.get.hasFileDescriptorResponse shouldBe true + } +} diff --git a/project/Dependencies.scala b/project/Dependencies.scala index b55314263f9..73ed0a7d026 100644 --- a/project/Dependencies.scala +++ b/project/Dependencies.scala @@ -1,5 +1,6 @@ import org.portablescala.sbtplatformdeps.PlatformDepsPlugin.autoImport.* import sbt.{Def, *} +import scalapb.compiler.Version.scalapbVersion //noinspection TypeAnnotation object Dependencies { @@ -140,13 +141,16 @@ object Dependencies { ) ++ test ++ console ++ logDeps ++ levelDBJNA ++ protobuf.value ++ langCompilerPlugins.value ) - lazy val scalapbRuntime = Def.setting { - val version = scalapb.compiler.Version.scalapbVersion + val gProto = "com.google.protobuf" % "protobuf-java" % "3.24.4" + + lazy val scalapbRuntime = Def.setting( Seq( - "com.thesamet.scalapb" %%% "scalapb-runtime" % version, - "com.thesamet.scalapb" %%% "scalapb-runtime" % version % "protobuf" + ("com.thesamet.scalapb" %%% "scalapb-runtime" % scalapbVersion).exclude(gProto.organization, gProto.name), + ("com.thesamet.scalapb" %%% "scalapb-runtime" % scalapbVersion % "protobuf").exclude(gProto.organization, gProto.name), + gProto, + gProto % "protobuf" ) - } + ) lazy val protobuf = Def.setting { scalapbRuntime.value :+ protoSchemasLib % "protobuf" @@ -155,7 +159,7 @@ object Dependencies { lazy val grpc: Seq[ModuleID] = Seq( "io.grpc" % "grpc-netty" % scalapb.compiler.Version.grpcJavaVersion, "io.grpc" % "grpc-services" % scalapb.compiler.Version.grpcJavaVersion, - "com.thesamet.scalapb" %% "scalapb-runtime-grpc" % scalapb.compiler.Version.scalapbVersion, + "com.thesamet.scalapb" %% "scalapb-runtime-grpc" % scalapbVersion, protoSchemasLib % "protobuf" )