suspension函数只能在vertx的协同程序体中调用

hkmswyz6  于 2021-07-08  发布在  Java
关注(0)|答案(1)|浏览(542)

我有以下未编译的代码:

private suspend fun createRoutes(router: Router, auth: OAuth2Auth): Unit {

    val oauth2 = OAuth2AuthHandler.create(vertx, auth)
    val authz = KeycloakAuthorization.create()

    router.route().handler(LoggerHandler.create())

    router.route("/api/*").handler(oauth2)

    router.route("/api/greet").handler {

      println(RoleBasedAuthorization.create("ad-admins").match(it.user()))
      authz.getAuthorizations(it.user()).await()
    }

  }

编译器抱怨:

Suspension functions can be called only within coroutine body

如果没有协同程序,我必须以回调方式编写:

private fun createRoutes(router: Router, auth: OAuth2Auth): Unit {

    val oauth2 = OAuth2AuthHandler.create(vertx, auth)
    val authz = KeycloakAuthorization.create()

    router.route().handler(LoggerHandler.create())

    router.route("/api/*").handler(oauth2)

     router.route("/api/greet").handler {

      println(RoleBasedAuthorization.create("ad-admins").match(it.user()))

      authz.getAuthorizations(it.user())
        .onSuccess { _ ->

          println(RoleBasedAuthorization.create("ad-admins").match(it.user()))

          val res = it.response()
          res.putHeader("content-type", "text/plain")

          // Write to the response and end it
          res.end("I am interests path")

        }
    }
  }

不过,我想使用协同程序,而不是回调风格。
更新
这就是全部代码:

class MainVerticle : CoroutineVerticle() {

  private suspend fun initConfig(): JsonObject {
    val yamlConfigOpts = ConfigStoreOptions()
      .setFormat("yaml")
      .setType("file")
      .setConfig(JsonObject().put("path", "config.yaml"))

    val configRetrieverOpts = ConfigRetrieverOptions()
      .addStore(yamlConfigOpts)

    val configRetriever = ConfigRetriever.create(vertx, configRetrieverOpts)

    return configRetriever.config.await()
  }

  private suspend fun createJwtAuth(): OAuth2Auth =

    KeycloakAuth.discover(
      vertx,
      OAuth2Options()
        .setFlow(OAuth2FlowType.AUTH_CODE)
        .setClientID("svc")
        .setClientSecret("9d782e45-67e7-44b1-9b74-864f45f9a18f")
        .setSite("https://oic.dev.databaker.io/auth/realms/databaker")
    ).await()

  private suspend fun createRoutes(router: Router, auth: OAuth2Auth): Unit {

    val oauth2 = OAuth2AuthHandler.create(vertx, auth)
    val authz = KeycloakAuthorization.create()

    router.route().handler(LoggerHandler.create())

    router.route("/api/*").handler(oauth2)

     router.route("/api/greet").handler {

      println(RoleBasedAuthorization.create("ad-admins").match(it.user()))

      authz.getAuthorizations(it.user()).await()
    }

  }

  private suspend fun server(router: Router): HttpServer {
    val server = vertx.createHttpServer()

    return server.requestHandler(router)
      .listen(8080)
      .onSuccess {
        println("HTTP server started on port ${it.actualPort()}")
      }
      .onFailure {
        println("Failed to start the server. Reason ${it.message}")
      }
      .await()
  }

  override suspend fun start() {

    val router = Router.router(vertx)

    createRoutes(router, createJwtAuth())
    server(router)

  }

}

我得到的错误是:

authz.getAuthorizations(it.user()).await()
rbl8hiat

rbl8hiat1#

如果您愿意在kotlin中编写某种 Package 器,那么使用协同程序非常容易。对于初学者,请查看文档。
协同程序可以简单到 GlobalScope.launch { createRoutes(router, auth) }

相关问题