diff --git a/.github/workflows/scala.yml b/.github/workflows/scala.yml index b888b2e..9b6915a 100644 --- a/.github/workflows/scala.yml +++ b/.github/workflows/scala.yml @@ -27,9 +27,6 @@ jobs: - name: Checking Code style run: sbt check - - name: Run NebulaGraph - run: docker-compose -f examples/src/main/resources/docker-compose.yaml up -d - - name: Run tests run: sbt test diff --git a/README.md b/README.md index cc47439..a339e4a 100644 --- a/README.md +++ b/README.md @@ -33,6 +33,7 @@ There are the version correspondence between zio-nebula and nebula-java: |:-----:|:----------:|:-----------:| | 2.0.x | 0.0.x | 3.6.0 | | 2.0.x | 0.1.x | 3.6.0 | +| 2.0.x | 0.1.1 | 3.6.1 | ## Example @@ -57,7 +58,7 @@ object NebulaSessionClientExample { object NebulaSessionClientMain extends ZIOAppDefault { override def run = (for { - _ <- ZIO.serviceWithZIO[NebulaSessionClient](_.init()) + _ <- ZIO.serviceWithZIO[NebulaSessionClient](_.init()) // since 0.1.1, no need to call it manually. _ <- ZIO.serviceWithZIO[NebulaSessionClientExample]( _.execute(""" |INSERT VERTEX person(name, age) VALUES diff --git a/build.sbt b/build.sbt index a9359f8..e9f82f9 100644 --- a/build.sbt +++ b/build.sbt @@ -1,11 +1,12 @@ -val zioVersion = "2.0.13" -val scala3_Version = "3.3.1" -val scala2_13Version = "2.13.12" -val scala2_12Version = "2.12.18" -val zioConfigVersion = "4.0.0-RC16" -val nebulaClientVersion = "3.6.0" -val logbackVersion = "1.4.11" -val silencerVersion = "1.4.2" +val zioVersion = "2.0.13" +val scala3_Version = "3.3.1" +val scala2_13Version = "2.13.12" +val scala2_12Version = "2.12.18" +val zioConfigVersion = "4.0.0-RC16" +val nebulaClientVersion = "3.6.1" +val logbackVersion = "1.4.11" +val silencerVersion = "1.4.2" +val testcontainersNebulaVersion = "0.1.0" val supportCrossVersionList = Seq(scala3_Version, scala2_13Version, scala2_12Version) @@ -42,13 +43,14 @@ lazy val core = project name := "zio-nebula", crossScalaVersions := supportCrossVersionList, libraryDependencies ++= Seq( - "com.vesoft" % "client" % nebulaClientVersion, - "dev.zio" %% "zio-config-typesafe" % zioConfigVersion, - "dev.zio" %% "zio-config-magnolia" % zioConfigVersion, - "dev.zio" %% "zio" % zioVersion, + "com.vesoft" % "client" % nebulaClientVersion, + "dev.zio" %% "zio-config-typesafe" % zioConfigVersion, + "dev.zio" %% "zio-config-magnolia" % zioConfigVersion, + "dev.zio" %% "zio" % zioVersion, // see https://github.com/zio/zio-config/issues/1245 - "com.github.ghik" %% "silencer-lib" % silencerVersion % Provided cross CrossVersion.for3Use2_13, - "ch.qos.logback" % "logback-classic" % logbackVersion % Test + "com.github.ghik" %% "silencer-lib" % silencerVersion % Provided cross CrossVersion.for3Use2_13, + "ch.qos.logback" % "logback-classic" % logbackVersion % Test, + "io.github.jxnu-liguobin" %% "testcontainers-nebula" % testcontainersNebulaVersion % Test ) ++ _zioTests.map(_ % Test), Test / parallelExecution := false, testFrameworks += new TestFramework("zio.test.sbt.ZTestFramework") diff --git a/core/src/main/scala/zio/nebula/NebulaConfig.scala b/core/src/main/scala/zio/nebula/NebulaConfig.scala index adf072a..19b4d09 100644 --- a/core/src/main/scala/zio/nebula/NebulaConfig.scala +++ b/core/src/main/scala/zio/nebula/NebulaConfig.scala @@ -66,7 +66,8 @@ final case class NebulaSessionPoolConfig( intervalTimeMills: Int = 0, healthCheckTimeSeconds: Int = 600, cleanTimeSeconds: Int = 3600, - reconnect: Boolean = false + reconnect: Boolean = false, + useHttp2: Boolean = false ) object NebulaConfig { diff --git a/core/src/main/scala/zio/nebula/NebulaSessionClient.scala b/core/src/main/scala/zio/nebula/NebulaSessionClient.scala index 4cc593b..97f4dc0 100644 --- a/core/src/main/scala/zio/nebula/NebulaSessionClient.scala +++ b/core/src/main/scala/zio/nebula/NebulaSessionClient.scala @@ -55,36 +55,30 @@ trait NebulaSessionClient { object NebulaSessionClient { - private def sessionLayer: ZLayer[NebulaSessionPoolConfig & Scope, Throwable, SessionPool] = - ZLayer.fromZIO { - ZIO.serviceWithZIO[NebulaSessionPoolConfig](nebulaConfig => - ZIO.acquireRelease( - ZIO.attempt( - new SessionPool( - new SessionPoolConfig( - nebulaConfig.address.map(d => new HostAddress(d.host, d.port)).asJava, - nebulaConfig.spaceName, - nebulaConfig.auth.username, - nebulaConfig.auth.password - ).setMaxSessionSize(nebulaConfig.maxSessionSize) - .setMinSessionSize(nebulaConfig.minSessionSize) - .setRetryTimes(nebulaConfig.retryTimes) - .setWaitTime(nebulaConfig.waitTimeMills) - .setIntervalTime(nebulaConfig.intervalTimeMills) - .setTimeout(nebulaConfig.timeoutMills) - .setCleanTime(nebulaConfig.cleanTimeSeconds) - .setReconnect(nebulaConfig.reconnect) - .setHealthCheckTime(nebulaConfig.healthCheckTimeSeconds) - ) - ) - )(release => ZIO.attempt(release.close()).onError(e => ZIO.logErrorCause(e)).ignoreLogged) - ) - } - - lazy val layer: ZLayer[NebulaSessionPoolConfig & Scope, Nothing, NebulaSessionClient] = { - val pool = ZLayer.fromZIO( - ZIO.serviceWith[SessionPool](new NebulaSessionClientLive(_)) - ) - (sessionLayer >>> pool).orDie + lazy val layer: ZLayer[Scope with NebulaSessionPoolConfig, Throwable, NebulaSessionClient] = ZLayer.fromZIO { + for { + nebulaConfig <- ZIO.service[NebulaSessionPoolConfig] + sessionPool <- ZIO.acquireRelease( + ZIO.attempt( + new SessionPool( + new SessionPoolConfig( + nebulaConfig.address.map(d => new HostAddress(d.host, d.port)).asJava, + nebulaConfig.spaceName, + nebulaConfig.auth.username, + nebulaConfig.auth.password + ).setMaxSessionSize(nebulaConfig.maxSessionSize) + .setMinSessionSize(nebulaConfig.minSessionSize) + .setRetryTimes(nebulaConfig.retryTimes) + .setWaitTime(nebulaConfig.waitTimeMills) + .setIntervalTime(nebulaConfig.intervalTimeMills) + .setTimeout(nebulaConfig.timeoutMills) + .setCleanTime(nebulaConfig.cleanTimeSeconds) + .setReconnect(nebulaConfig.reconnect) + .setHealthCheckTime(nebulaConfig.healthCheckTimeSeconds) + .setUseHttp2(nebulaConfig.useHttp2) + ) + ) + )(release => ZIO.attempt(release.close()).ignoreLogged) + } yield new NebulaSessionClientLive(sessionPool) } } diff --git a/core/src/main/scala/zio/nebula/NebulaSessionClientLive.scala b/core/src/main/scala/zio/nebula/NebulaSessionClientLive.scala index 8e8d07c..803e643 100644 --- a/core/src/main/scala/zio/nebula/NebulaSessionClientLive.scala +++ b/core/src/main/scala/zio/nebula/NebulaSessionClientLive.scala @@ -25,6 +25,9 @@ private[nebula] final class NebulaSessionClientLive(underlying: SessionPool) ext override def close(): Task[Unit] = ZIO.attempt(underlying.close()) + @deprecated( + "init the SessionPool this function is moved into SessionPool's constructor, no need to call it manually." + ) override def init(): Task[Boolean] = ZIO.attempt(underlying.init()) } diff --git a/core/src/main/scala/zio/nebula/net/NebulaClient.scala b/core/src/main/scala/zio/nebula/net/NebulaClient.scala index 2030180..f5e0ce8 100644 --- a/core/src/main/scala/zio/nebula/net/NebulaClient.scala +++ b/core/src/main/scala/zio/nebula/net/NebulaClient.scala @@ -34,6 +34,6 @@ object NebulaClient { ZIO.attempt(d.close()).onError(e => ZIO.logErrorCause(e)).ignoreLogged ) - lazy val layer: ZLayer[Scope, Nothing, NebulaClient] = + lazy val layer: ZLayer[Scope, Throwable, NebulaClient] = ZLayer.fromZIO(makePool.map(pool => new NebulaClientLive(pool))) } diff --git a/core/src/main/scala/zio/nebula/package.scala b/core/src/main/scala/zio/nebula/package.scala index 061d207..479bbd2 100644 --- a/core/src/main/scala/zio/nebula/package.scala +++ b/core/src/main/scala/zio/nebula/package.scala @@ -16,24 +16,24 @@ package object nebula { type Storage = NebulaStorageClient type Meta = NebulaMetaClient - lazy val SessionClientEnv: ZLayer[Scope, Nothing, SessionClient] = ZLayer.makeSome[Scope, SessionClient]( + lazy val SessionClientEnv: ZLayer[Scope, Throwable, SessionClient] = ZLayer.makeSome[Scope, SessionClient]( NebulaSessionClient.layer, NebulaConfig.sessionConfigLayer ) - lazy val ClientEnv: ZLayer[Scope, Nothing, Client] = + lazy val ClientEnv: ZLayer[Scope, Throwable, Client] = ZLayer.makeSome[Scope, Client]( NebulaClient.layer, NebulaConfig.poolConfigLayer, NebulaConfig.sessionConfigLayer ) - lazy val StorageEnv: ZLayer[Scope, Nothing, Storage] = ZLayer.makeSome[Scope, Storage]( + lazy val StorageEnv: ZLayer[Scope, Throwable, Storage] = ZLayer.makeSome[Scope, Storage]( NebulaStorageClient.layer, NebulaConfig.storageConfigLayer ) - lazy val MetaEnv: ZLayer[Scope, Nothing, Meta] = ZLayer.makeSome[Scope, Meta]( + lazy val MetaEnv: ZLayer[Scope, Throwable, Meta] = ZLayer.makeSome[Scope, Meta]( NebulaMetaClient.layer, NebulaConfig.metaConfigLayer ) diff --git a/core/src/main/scala/zio/nebula/storage/NebulaStorageClient.scala b/core/src/main/scala/zio/nebula/storage/NebulaStorageClient.scala index 6ce6435..247bf5d 100644 --- a/core/src/main/scala/zio/nebula/storage/NebulaStorageClient.scala +++ b/core/src/main/scala/zio/nebula/storage/NebulaStorageClient.scala @@ -24,7 +24,7 @@ trait NebulaStorageClient { object NebulaStorageClient { - lazy val layer: ZLayer[NebulaStorageConfig & Scope, Nothing, NebulaStorageClient] = + lazy val layer: ZLayer[NebulaStorageConfig & Scope, Throwable, NebulaStorageClient] = ZLayer.fromZIO { for { config <- ZIO.serviceWith[NebulaStorageConfig](_.underlying) @@ -44,5 +44,5 @@ object NebulaStorageClient { )(_.close().onError(e => ZIO.logErrorCause(e)).ignoreLogged) } yield manger - }.orDie + } } diff --git a/core/src/test/scala/zio/nebula/NebulaClientSpec.scala b/core/src/test/scala/zio/nebula/NebulaClientSpec.scala index 6fb0ea6..a19b29d 100644 --- a/core/src/test/scala/zio/nebula/NebulaClientSpec.scala +++ b/core/src/test/scala/zio/nebula/NebulaClientSpec.scala @@ -1,8 +1,7 @@ package zio.nebula -import zio.ZIO +import zio.{ Scope, ZIO } import zio.nebula.meta.NebulaMetaClient -import zio.nebula.net.{ NebulaClient, Stmt } import zio.nebula.storage.{ NebulaStorageClient, ScanEdge } import zio.test._ @@ -35,22 +34,10 @@ object NebulaClientSpec extends NebulaSpec { |MATCH (p:person) RETURN p LIMIT 4; |""".stripMargin + lazy val session = ZioNebulaEnvironment.defaultSession(container.graphdHostList.head, container.graphdPortList.head) + def specLayered: Spec[Nebula, Throwable] = suite("nebula suite")( - suite("nebula session pool")( - test("create and query") { - for { - init <- ZIO.serviceWithZIO[NebulaSessionClient](_.init()) - _ <- ZIO.logInfo(s"init session: $init") - res1 <- ZIO.serviceWithZIO[NebulaSessionClient](_.execute(insertVertexes)) - _ <- ZIO.logInfo(s"exec insert vertex: ${res1.errorMessage}") - res2 <- ZIO.serviceWithZIO[NebulaSessionClient](_.execute(insertEdges)) - _ <- ZIO.logInfo(s"exec insert edge: ${res2.errorMessage}") - res3 <- ZIO.serviceWithZIO[NebulaSessionClient](_.execute(query)) - _ <- ZIO.logInfo(s"exec query ${res3.errorMessage}") - } yield assertTrue(res3.rows.size == 4) - } - ), suite("nebula meta manager")( test("query") { for { @@ -72,6 +59,36 @@ object NebulaClientSpec extends NebulaSpec { _ <- ZIO.logInfo(s"scan result: $scanResult") } yield assertTrue(scanResult.hasNext) } + ), + suite("nebula session pool")( + test("create and query") { + for { + res1 <- + ZIO + .serviceWithZIO[NebulaSessionClient](_.execute(insertVertexes)) + .provide( + Scope.default, + session + ) + _ <- ZIO.logInfo(s"exec insert vertex: ${res1.errorMessage}") + res2 <- + ZIO + .serviceWithZIO[NebulaSessionClient](_.execute(insertEdges)) + .provide( + Scope.default, + session + ) + _ <- ZIO.logInfo(s"exec insert edge: ${res2.errorMessage}") + res3 <- + ZIO + .serviceWithZIO[NebulaSessionClient](_.execute(query)) + .provide( + Scope.default, + session + ) + _ <- ZIO.logInfo(s"exec query ${res3.errorMessage}") + } yield assertTrue(res3.rows.size == 4) + } ) ) diff --git a/core/src/test/scala/zio/nebula/NebulaSpec.scala b/core/src/test/scala/zio/nebula/NebulaSpec.scala index 11fbc71..c9ea485 100644 --- a/core/src/test/scala/zio/nebula/NebulaSpec.scala +++ b/core/src/test/scala/zio/nebula/NebulaSpec.scala @@ -5,9 +5,15 @@ import zio.nebula.net.{ NebulaClient, Stmt } import zio.test._ import zio.test.TestAspect._ +import testcontainers.containers.NebulaSimpleClusterContainer + trait NebulaSpec extends ZIOSpecDefault { - type Nebula = Client with SessionClient with Storage with Meta with Scope + type Nebula = Client with Storage with Meta with Scope + + val container: NebulaSimpleClusterContainer = new NebulaSimpleClusterContainer(subnetIp = "172.30.0.0/16") + + container.start() override def aspects: Chunk[TestAspectAtLeastR[TestEnvironment]] = Chunk(TestAspect.fibers, TestAspect.timeout(180.seconds)) @@ -26,10 +32,9 @@ trait NebulaSpec extends ZIOSpecDefault { ) @@ sequential @@ eventually) .provideShared( Scope.default, - MetaEnv, - StorageEnv, - SessionClientEnv, - ClientEnv + ZioNebulaEnvironment.defaultMeta(container.metadHostList.head, container.metadPortList.head), + ZioNebulaEnvironment.defaultStorage(container.metadHostList.head, container.metadPortList.head), + ZioNebulaEnvironment.defaultClient(container.graphdHostList.head, container.graphdPortList.head) ) def specLayered: Spec[Nebula, Throwable] diff --git a/core/src/test/scala/zio/nebula/ZioNebulaEnvironment.scala b/core/src/test/scala/zio/nebula/ZioNebulaEnvironment.scala new file mode 100644 index 0000000..adb032c --- /dev/null +++ b/core/src/test/scala/zio/nebula/ZioNebulaEnvironment.scala @@ -0,0 +1,84 @@ +package zio.nebula + +import zio._ +import zio.nebula.meta.NebulaMetaClient +import zio.nebula.net.NebulaClient +import zio.nebula.storage.NebulaStorageClient + +/** + * This is the default configuration dedicated to testing. + * + * @author + * 梦境迷离 + * @version 1.0,2023/9/19 + */ +object ZioNebulaEnvironment { + + var defaultUser = "root" + var defaultPwd = "nebula" + var defaultSpace = "test" + + def defaultSession(host: String, port: Int): ZLayer[Scope, Throwable, SessionClient] = + ZLayer.makeSome[Scope, SessionClient]( + NebulaSessionClient.layer, + ZLayer.succeed( + NebulaSessionPoolConfig( + List(NebulaHostAddress(host, port)), + NebulaAuth(defaultUser, defaultPwd), + defaultSpace + ) + ) + ) + + def defaultClient(host: String, port: Int): ZLayer[Scope, Throwable, Client] = + NebulaClient.layer ++ ZLayer.succeed( + NebulaPoolConfig( + timeoutMills = 60000, + enableSsl = false, + minConnsSize = 10, + maxConnsSize = 10, + intervalIdleMills = 100, + waitTimeMills = 100, + sslParam = None + ) + ) ++ ZLayer.fromZIO( + ZIO.attempt( + NebulaSessionPoolConfig( + List(NebulaHostAddress(host, port)), + NebulaAuth(defaultUser, defaultPwd), + defaultSpace + ) + ) + ) + + def defaultStorage(host: String, port: Int): ZLayer[Scope, Throwable, Storage] = + ZLayer.makeSome[Scope, Storage]( + NebulaStorageClient.layer, + ZLayer.succeed( + NebulaStorageConfig( + NebulaConfig( + List(NebulaHostAddress(host, port)), + 30000, + 3, + 3 + ) + ) + ) + ) + + def defaultMeta(host: String, port: Int): ZLayer[Scope, Throwable, Meta] = + ZLayer.makeSome[Scope, Meta]( + NebulaMetaClient.layer, + ZLayer.succeed( + NebulaMetaConfig( + NebulaConfig( + List(NebulaHostAddress(host, port)), + 30000, + 3, + 3 + ) + ) + ) + ) + +} diff --git a/examples/src/main/scala/zio/nebula/example/NebulaSessionClientExample.scala b/examples/src/main/scala/zio/nebula/example/NebulaSessionClientExample.scala index 940376e..a08782f 100644 --- a/examples/src/main/scala/zio/nebula/example/NebulaSessionClientExample.scala +++ b/examples/src/main/scala/zio/nebula/example/NebulaSessionClientExample.scala @@ -16,8 +16,6 @@ object NebulaSessionClientExample { object NebulaSessionClientMain extends ZIOAppDefault { override def run = (for { - _ <- ZIO - .serviceWithZIO[NebulaSessionClient](_.init()) _ <- ZIO .serviceWithZIO[NebulaSessionClientExample]( _.execute("""