├── .gitignore ├── .travis.yml ├── core ├── src │ └── vertices │ │ ├── core │ │ └── VertxScheduler.scala │ │ └── package.scala └── tut │ └── README.md ├── jdbc └── generated │ └── vertices │ └── jdbc │ └── package.scala ├── mail └── generated │ └── vertices │ └── mail │ └── package.scala ├── config └── generated │ └── vertices │ └── config │ └── package.scala ├── healthchecks └── generated │ └── vertices │ └── healthchecks │ └── package.scala ├── auth_mongo └── generated │ └── vertices │ └── auth │ └── mongo │ └── package.scala ├── auth └── generated │ └── vertices │ └── auth │ └── package.scala ├── mill ├── eventbus_bridge_tcp └── generated │ └── vertices │ └── eventbus │ └── bridge │ └── tcp │ └── package.scala ├── amqpbridge └── generated │ └── vertices │ └── amqpbridge │ └── package.scala ├── web_api_contract └── generated │ └── vertices │ └── web │ └── api │ └── contract │ └── package.scala ├── circuitbreaker └── generated │ └── vertices │ └── circuitbreaker │ └── package.scala ├── web_client └── generated │ └── vertices │ └── web │ └── client │ └── package.scala ├── cassandra └── generated │ └── vertices │ └── cassandra │ └── package.scala ├── codegen └── src │ └── vertices │ └── codegen │ ├── CodegenProcessor.scala │ └── Codegen.scala ├── stomp └── generated │ └── vertices │ └── stomp │ └── package.scala ├── auth_oauth2 └── generated │ └── vertices │ └── auth │ └── oauth2 │ └── package.scala ├── mqtt └── generated │ └── vertices │ └── mqtt │ └── package.scala ├── web └── generated │ └── vertices │ └── web │ └── package.scala ├── LICENSE ├── README.md ├── rabbitmq └── generated │ └── vertices │ └── rabbitmq │ └── package.scala ├── sql └── generated │ └── vertices │ └── sql │ └── package.scala ├── mongo └── generated │ └── vertices │ └── mongo │ └── package.scala ├── kafka_client └── generated │ └── vertices │ └── kafka │ └── client │ └── package.scala └── servicediscovery └── generated └── vertices └── servicediscovery └── package.scala /.gitignore: -------------------------------------------------------------------------------- 1 | .metals/ 2 | target/ 3 | out/ -------------------------------------------------------------------------------- /.travis.yml: -------------------------------------------------------------------------------- 1 | language: scala 2 | sudo: required 3 | dist: trusty 4 | 5 | jdk: 6 | - openjdk8 7 | - openjdk11 8 | 9 | script: 10 | - ./mill __.compile 11 | - ./mill core[_].tut 12 | 13 | cache: 14 | directories: 15 | - $HOME/.cache/coursier 16 | -------------------------------------------------------------------------------- /core/src/vertices/core/VertxScheduler.scala: -------------------------------------------------------------------------------- 1 | package vertices 2 | package core 3 | 4 | import io.vertx.core.Vertx 5 | import java.util.concurrent.TimeUnit 6 | import monix.execution.{ Cancelable, ExecutionModel } 7 | import monix.execution.schedulers.ReferenceScheduler 8 | 9 | class VertxScheduler(vertx: Vertx) extends ReferenceScheduler { 10 | val executionModel = ExecutionModel.Default 11 | 12 | def execute(command: Runnable): Unit = 13 | vertx.runOnContext(_ => command.run()) 14 | 15 | def reportFailure(t: Throwable): Unit = { 16 | val handler = vertx.exceptionHandler 17 | if (handler != null) handler.handle(t) 18 | } 19 | 20 | def scheduleOnce(initialDelay: Long, unit: TimeUnit, r: Runnable): Cancelable = { 21 | val delayMs = unit.convert(initialDelay, TimeUnit.MILLISECONDS) 22 | val timerId = vertx.setTimer(delayMs, _ => execute(r)) 23 | Cancelable(() => vertx.cancelTimer(timerId)) 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /jdbc/generated/vertices/jdbc/package.scala: -------------------------------------------------------------------------------- 1 | package vertices 2 | 3 | 4 | import monix.eval.Task 5 | import io.vertx.core.AsyncResult 6 | import io.vertx.core.Handler 7 | import io.vertx.core.Vertx 8 | import io.vertx.core.json.JsonArray 9 | import io.vertx.core.json.JsonObject 10 | import io.vertx.ext.jdbc.JDBCClient 11 | import io.vertx.ext.sql.SQLClient 12 | import io.vertx.ext.sql.SQLOperations 13 | import java.lang.String 14 | 15 | package object jdbc { 16 | implicit class VertxJDBCClientOps(val target: JDBCClient) extends AnyVal { 17 | 18 | def querySingleL(sql: String): Task[JsonArray] = 19 | Task.handle[JsonArray] { handler => 20 | target.querySingle(sql, handler) 21 | } 22 | 23 | 24 | def querySingleWithParamsL(sql: String, arguments: JsonArray): Task[JsonArray] = 25 | Task.handle[JsonArray] { handler => 26 | target.querySingleWithParams(sql, arguments, handler) 27 | } 28 | } 29 | 30 | 31 | } -------------------------------------------------------------------------------- /mail/generated/vertices/mail/package.scala: -------------------------------------------------------------------------------- 1 | package vertices 2 | 3 | 4 | import monix.eval.Task 5 | import io.vertx.core.AsyncResult 6 | import io.vertx.core.Handler 7 | import io.vertx.core.Vertx 8 | import io.vertx.ext.mail.MailClient 9 | import io.vertx.ext.mail.MailConfig 10 | import io.vertx.ext.mail.MailMessage 11 | import io.vertx.ext.mail.MailResult 12 | import java.lang.String 13 | 14 | package object mail { 15 | implicit class VertxMailClientOps(val target: MailClient) extends AnyVal { 16 | /** 17 | * send a single mail via MailClient 18 | * @param email MailMessage object containing the mail text, from/to, attachments etc 19 | * @param resultHandler will be called when the operation is finished or it fails 20 | * (may be null to ignore the result) 21 | * @return this MailClient instance so the method can be used fluently 22 | */ 23 | def sendMailL(email: MailMessage): Task[MailResult] = 24 | Task.handle[MailResult] { resultHandler => 25 | target.sendMail(email, resultHandler) 26 | } 27 | } 28 | 29 | 30 | } -------------------------------------------------------------------------------- /config/generated/vertices/config/package.scala: -------------------------------------------------------------------------------- 1 | package vertices 2 | 3 | 4 | import monix.eval.Task 5 | import io.vertx.config.ConfigChange 6 | import io.vertx.config.ConfigRetriever 7 | import io.vertx.config.ConfigRetrieverOptions 8 | import io.vertx.core.AsyncResult 9 | import io.vertx.core.Future 10 | import io.vertx.core.Handler 11 | import io.vertx.core.Vertx 12 | import io.vertx.core.json.JsonObject 13 | import io.vertx.core.streams.ReadStream 14 | import java.lang.Void 15 | import java.util.function.Function 16 | 17 | package object config { 18 | implicit class VertxConfigRetrieverOps(val target: ConfigRetriever) extends AnyVal { 19 | /** 20 | * Reads the configuration from the different {@link ConfigStore} 21 | * and computes the final configuration. 22 | * @param completionHandler handler receiving the computed configuration, or a failure if the 23 | * configuration cannot be retrieved 24 | */ 25 | def getConfigL(): Task[JsonObject] = 26 | Task.handle[JsonObject] { completionHandler => 27 | target.getConfig(completionHandler) 28 | } 29 | } 30 | 31 | 32 | } -------------------------------------------------------------------------------- /healthchecks/generated/vertices/healthchecks/package.scala: -------------------------------------------------------------------------------- 1 | package vertices 2 | 3 | 4 | import monix.eval.Task 5 | import io.vertx.core.AsyncResult 6 | import io.vertx.core.Handler 7 | import io.vertx.core.Promise 8 | import io.vertx.core.Vertx 9 | import io.vertx.core.json.JsonObject 10 | import io.vertx.ext.healthchecks.HealthChecks 11 | import io.vertx.ext.healthchecks.Status 12 | import java.lang.String 13 | 14 | package object healthchecks { 15 | implicit class VertxHealthChecksOps(val target: HealthChecks) extends AnyVal { 16 | /** 17 | * Invokes the registered procedure with the given name and sub-procedures. It computes the overall 18 | * outcome. 19 | * @param resultHandler the result handler, must not be {@code null}. The handler received an 20 | * {@link AsyncResult} marked as failed if the procedure with the given name cannot 21 | * be found or invoked. 22 | * @return the current {@link HealthChecks} 23 | */ 24 | def invokeL(name: String): Task[JsonObject] = 25 | Task.handle[JsonObject] { resultHandler => 26 | target.invoke(name, resultHandler) 27 | } 28 | } 29 | 30 | 31 | } -------------------------------------------------------------------------------- /auth_mongo/generated/vertices/auth/mongo/package.scala: -------------------------------------------------------------------------------- 1 | package vertices 2 | package auth 3 | 4 | import monix.eval.Task 5 | import io.vertx.core.AsyncResult 6 | import io.vertx.core.Handler 7 | import io.vertx.core.json.JsonObject 8 | import io.vertx.ext.auth.AuthProvider 9 | import io.vertx.ext.auth.mongo.HashAlgorithm 10 | import io.vertx.ext.auth.mongo.HashStrategy 11 | import io.vertx.ext.auth.mongo.MongoAuth 12 | import io.vertx.ext.mongo.MongoClient 13 | import java.lang.String 14 | import java.util.List 15 | 16 | package object mongo { 17 | implicit class VertxMongoAuthOps(val target: MongoAuth) extends AnyVal { 18 | /** 19 | * Insert a new user into mongo in the convenient way 20 | * @param username 21 | * the username to be set 22 | * @param password 23 | * the passsword in clear text, will be adapted following the definitions of the defined {@link HashStrategy} 24 | * @param roles 25 | * a list of roles to be set 26 | * @param permissions 27 | * a list of permissions to be set 28 | * @param resultHandler 29 | * the ResultHandler will be provided with the id of the generated record 30 | */ 31 | def insertUserL(username: String, password: String, roles: List[String], permissions: List[String]): Task[String] = 32 | Task.handle[String] { resultHandler => 33 | target.insertUser(username, password, roles, permissions, resultHandler) 34 | } 35 | } 36 | 37 | 38 | } -------------------------------------------------------------------------------- /auth/generated/vertices/auth/package.scala: -------------------------------------------------------------------------------- 1 | package vertices 2 | 3 | 4 | import monix.eval.Task 5 | import io.vertx.core.AsyncResult 6 | import io.vertx.core.Handler 7 | import io.vertx.core.json.JsonObject 8 | import io.vertx.ext.auth.AuthProvider 9 | import io.vertx.ext.auth.User 10 | import java.lang.Boolean 11 | import java.lang.String 12 | 13 | package object auth { 14 | 15 | 16 | implicit class VertxAuthProviderOps(val target: AuthProvider) extends AnyVal { 17 | /** 18 | * Authenticate a user. 19 | *

20 | * The first argument is a JSON object containing information for authenticating the user. What this actually contains 21 | * depends on the specific implementation. In the case of a simple username/password based 22 | * authentication it is likely to contain a JSON object with the following structure: 23 | *

24 |      *    {
25 |      *      "username": "tim",
26 |      *      "password": "mypassword"
27 |      *    }
28 |      *  
29 | * For other types of authentication it contain different information - for example a JWT token or OAuth bearer token. 30 | *

31 | * If the user is successfully authenticated a {@link User} object is passed to the handler in an {@link io.vertx.core.AsyncResult}. 32 | * The user object can then be used for authorisation. 33 | * @param authInfo The auth information 34 | * @param resultHandler The result handler 35 | */ 36 | def authenticateL(authInfo: JsonObject): Task[User] = 37 | Task.handle[User] { resultHandler => 38 | target.authenticate(authInfo, resultHandler) 39 | } 40 | } 41 | 42 | 43 | } -------------------------------------------------------------------------------- /mill: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env sh 2 | 3 | # This is a wrapper script, that automatically download mill from GitHub release pages 4 | # You can give the required mill version with MILL_VERSION env variable 5 | # If no version is given, it falls back to the value of DEFAULT_MILL_VERSION 6 | DEFAULT_MILL_VERSION=0.6.1 7 | 8 | set -e 9 | 10 | if [ -z "$MILL_VERSION" ] ; then 11 | if [ -f ".mill-version" ] ; then 12 | MILL_VERSION="$(head -n 1 .mill-version 2> /dev/null)" 13 | elif [ -f "mill" ] && [ "$BASH_SOURCE" != "mill" ] ; then 14 | MILL_VERSION=$(grep -F "DEFAULT_MILL_VERSION=" "mill" | head -n 1 | cut -d= -f2) 15 | else 16 | MILL_VERSION=$DEFAULT_MILL_VERSION 17 | fi 18 | fi 19 | 20 | if [ "x${XDG_CACHE_HOME}" != "x" ] ; then 21 | MILL_DOWNLOAD_PATH="${XDG_CACHE_HOME}/mill/download" 22 | else 23 | MILL_DOWNLOAD_PATH="${HOME}/.cache/mill/download" 24 | fi 25 | MILL_EXEC_PATH="${MILL_DOWNLOAD_PATH}/${MILL_VERSION}" 26 | 27 | version_remainder="$MILL_VERSION" 28 | MILL_MAJOR_VERSION="${version_remainder%%.*}"; version_remainder="${version_remainder#*.}" 29 | MILL_MINOR_VERSION="${version_remainder%%.*}"; version_remainder="${version_remainder#*.}" 30 | 31 | if [ ! -x "$MILL_EXEC_PATH" ] ; then 32 | mkdir -p $MILL_DOWNLOAD_PATH 33 | if [ "$MILL_MAJOR_VERSION" -gt 0 ] || [ "$MILL_MINOR_VERSION" -ge 5 ] ; then 34 | ASSEMBLY="-assembly" 35 | fi 36 | DOWNLOAD_FILE=$MILL_EXEC_PATH-tmp-download 37 | MILL_DOWNLOAD_URL="https://github.com/lihaoyi/mill/releases/download/${MILL_VERSION%%-*}/$MILL_VERSION${ASSEMBLY}" 38 | curl --fail -L -o "$DOWNLOAD_FILE" "$MILL_DOWNLOAD_URL" 39 | chmod +x "$DOWNLOAD_FILE" 40 | mv "$DOWNLOAD_FILE" "$MILL_EXEC_PATH" 41 | unset DOWNLOAD_FILE 42 | unset MILL_DOWNLOAD_URL 43 | fi 44 | 45 | unset MILL_DOWNLOAD_PATH 46 | unset MILL_VERSION 47 | 48 | exec $MILL_EXEC_PATH "$@" 49 | -------------------------------------------------------------------------------- /eventbus_bridge_tcp/generated/vertices/eventbus/bridge/tcp/package.scala: -------------------------------------------------------------------------------- 1 | package vertices 2 | package eventbus.bridge 3 | 4 | import monix.eval.Task 5 | import io.vertx.core.AsyncResult 6 | import io.vertx.core.Handler 7 | import io.vertx.core.Vertx 8 | import io.vertx.core.net.NetServerOptions 9 | import io.vertx.ext.bridge.BridgeOptions 10 | import io.vertx.ext.eventbus.bridge.tcp.BridgeEvent 11 | import io.vertx.ext.eventbus.bridge.tcp.TcpEventBusBridge 12 | import java.lang.String 13 | import java.lang.Void 14 | 15 | package object tcp { 16 | implicit class VertxTcpEventBusBridgeOps(val target: TcpEventBusBridge) extends AnyVal { 17 | /** 18 | * Listen on default port 7000 with a handler to report the state of the socket listen operation. 19 | * @param handler the result handler 20 | * @return self 21 | */ 22 | def listenL(): Task[TcpEventBusBridge] = 23 | Task.handle[TcpEventBusBridge] { handler => 24 | target.listen(handler) 25 | } 26 | 27 | /** 28 | * Listen on specific port and bind to specific address 29 | * @param port tcp port 30 | * @param address tcp address to the bind 31 | * @param handler the result handler 32 | * @return self 33 | */ 34 | def listenL(port: Int, address: String): Task[TcpEventBusBridge] = 35 | Task.handle[TcpEventBusBridge] { handler => 36 | target.listen(port, address, handler) 37 | } 38 | 39 | /** 40 | * Listen on specific port 41 | * @param port tcp port 42 | * @param handler the result handler 43 | * @return self 44 | */ 45 | def listenL(port: Int): Task[TcpEventBusBridge] = 46 | Task.handle[TcpEventBusBridge] { handler => 47 | target.listen(port, handler) 48 | } 49 | 50 | /** 51 | * Close the current socket. 52 | * @param handler the result handler 53 | */ 54 | def closeL(): Task[Unit] = 55 | Task.handle[Void] { handler => 56 | target.close(handler) 57 | }.map(_ => ()) 58 | } 59 | 60 | 61 | } -------------------------------------------------------------------------------- /amqpbridge/generated/vertices/amqpbridge/package.scala: -------------------------------------------------------------------------------- 1 | package vertices 2 | 3 | 4 | import monix.eval.Task 5 | import io.vertx.amqpbridge.AmqpBridge 6 | import io.vertx.amqpbridge.AmqpBridgeOptions 7 | import io.vertx.core.AsyncResult 8 | import io.vertx.core.Handler 9 | import io.vertx.core.Vertx 10 | import io.vertx.core.eventbus.MessageConsumer 11 | import io.vertx.core.eventbus.MessageProducer 12 | import java.lang.String 13 | import java.lang.Void 14 | 15 | package object amqpbridge { 16 | implicit class VertxAmqpBridgeOps(val target: AmqpBridge) extends AnyVal { 17 | /** 18 | * Starts the bridge, establishing the underlying connection. 19 | * @param hostname 20 | * the host name to connect to 21 | * @param port 22 | * the port to connect to 23 | * @param username 24 | * the username 25 | * @param password 26 | * the password 27 | * @param resultHandler 28 | * the result handler 29 | */ 30 | def startL(hostname: String, port: Int, username: String, password: String): Task[AmqpBridge] = 31 | Task.handle[AmqpBridge] { resultHandler => 32 | target.start(hostname, port, username, password, resultHandler) 33 | } 34 | 35 | /** 36 | * Starts the bridge, establishing the underlying connection. 37 | * @param hostname 38 | * the host name to connect to 39 | * @param port 40 | * the port to connect to 41 | * @param resultHandler 42 | * the result handler 43 | */ 44 | def startL(hostname: String, port: Int): Task[AmqpBridge] = 45 | Task.handle[AmqpBridge] { resultHandler => 46 | target.start(hostname, port, resultHandler) 47 | } 48 | 49 | /** 50 | * Shuts the bridge down, closing the underlying connection. 51 | * @param resultHandler 52 | * the result handler 53 | */ 54 | def closeL(): Task[Unit] = 55 | Task.handle[Void] { resultHandler => 56 | target.close(resultHandler) 57 | }.map(_ => ()) 58 | } 59 | 60 | 61 | } -------------------------------------------------------------------------------- /web_api_contract/generated/vertices/web/api/contract/package.scala: -------------------------------------------------------------------------------- 1 | package vertices 2 | package web.api 3 | 4 | import monix.eval.Task 5 | import io.swagger.v3.oas.models.OpenAPI 6 | import io.vertx.core.AsyncResult 7 | import io.vertx.core.Handler 8 | import io.vertx.core.Vertx 9 | import io.vertx.core.json.JsonObject 10 | import io.vertx.ext.web.Router 11 | import io.vertx.ext.web.RoutingContext 12 | import io.vertx.ext.web.api.contract.RouterFactory 13 | import io.vertx.ext.web.api.contract.RouterFactoryOptions 14 | import io.vertx.ext.web.api.contract.openapi3.OpenAPI3RouterFactory 15 | import io.vertx.ext.web.handler.BodyHandler 16 | import java.lang.String 17 | import java.util.List 18 | import java.util.function.Function 19 | 20 | package object contract { 21 | 22 | object OpenAPI3RouterFactoryFunctions { 23 | /** 24 | * Create a new OpenAPI3RouterFactory 25 | * @param vertx 26 | * @param url location of your spec. It can be an absolute path, a local path or remote url (with HTTP protocol) 27 | * @param handler When specification is loaded, this handler will be called with AsyncResult 28 | */ 29 | def createL(vertx: Vertx, url: String): Task[OpenAPI3RouterFactory] = 30 | Task.handle[OpenAPI3RouterFactory] { handler => 31 | OpenAPI3RouterFactory.create(vertx, url, handler) 32 | } 33 | 34 | /** 35 | * Create a new OpenAPI3RouterFactory 36 | * @param vertx 37 | * @param url location of your spec. It can be an absolute path, a local path or remote url (with HTTP protocol) 38 | * @param auth list of authorization values needed to access the remote url. Each item should be json representation 39 | * of an {@link AuthorizationValue} 40 | * @param handler When specification is loaded, this handler will be called with AsyncResult 41 | */ 42 | def createL(vertx: Vertx, url: String, auth: List[JsonObject]): Task[OpenAPI3RouterFactory] = 43 | Task.handle[OpenAPI3RouterFactory] { handler => 44 | OpenAPI3RouterFactory.create(vertx, url, auth, handler) 45 | } 46 | } 47 | 48 | } -------------------------------------------------------------------------------- /circuitbreaker/generated/vertices/circuitbreaker/package.scala: -------------------------------------------------------------------------------- 1 | package vertices 2 | 3 | 4 | import monix.eval.Task 5 | import io.vertx.circuitbreaker.CircuitBreaker 6 | import io.vertx.circuitbreaker.CircuitBreakerOptions 7 | import io.vertx.circuitbreaker.CircuitBreakerState 8 | import io.vertx.core.AsyncResult 9 | import io.vertx.core.Handler 10 | import io.vertx.core.Promise 11 | import io.vertx.core.Vertx 12 | import java.lang.Integer 13 | import java.lang.Long 14 | import java.lang.String 15 | import java.lang.Throwable 16 | import java.lang.Void 17 | import java.util.function.Function 18 | 19 | package object circuitbreaker { 20 | implicit class VertxCircuitBreakerOps(val target: CircuitBreaker) extends AnyVal { 21 | /** 22 | * Same as {@link #executeWithFallback(Handler, Function)} but using a callback. 23 | * @param command the operation 24 | * @param fallback the fallback 25 | * @param handler the completion handler receiving either the operation result or the fallback result. The 26 | * parameter is an {@link AsyncResult} because if the fallback is not called, the error is passed 27 | * to the handler. 28 | * @param the type of result 29 | */ 30 | def executeWithFallbackL[T](command: Handler[Promise[T]], fallback: Function[Throwable,T]): Task[T] = 31 | Task.handle[T] { handler => 32 | target.executeWithFallback(command, fallback, handler) 33 | } 34 | 35 | /** 36 | * Same as {@link #executeWithFallback(Handler, Function)} but using the circuit breaker default fallback. 37 | * @param command the operation 38 | * @param handler the completion handler receiving either the operation result or the fallback result. The 39 | * parameter is an {@link AsyncResult} because if the fallback is not called, the error is passed 40 | * to the handler. 41 | * @param the type of result 42 | */ 43 | def executeL[T](command: Handler[Promise[T]]): Task[T] = 44 | Task.handle[T] { handler => 45 | target.execute(command, handler) 46 | } 47 | } 48 | 49 | 50 | } -------------------------------------------------------------------------------- /web_client/generated/vertices/web/client/package.scala: -------------------------------------------------------------------------------- 1 | package vertices 2 | package web 3 | 4 | import monix.eval.Task 5 | import io.vertx.core.AsyncResult 6 | import io.vertx.core.Handler 7 | import io.vertx.core.MultiMap 8 | import io.vertx.core.buffer.Buffer 9 | import io.vertx.core.http.HttpMethod 10 | import io.vertx.core.json.JsonObject 11 | import io.vertx.core.streams.ReadStream 12 | import io.vertx.ext.web.client.HttpRequest 13 | import io.vertx.ext.web.client.HttpResponse 14 | import io.vertx.ext.web.client.predicate.ResponsePredicate 15 | import io.vertx.ext.web.client.predicate.ResponsePredicateResult 16 | import io.vertx.ext.web.codec.BodyCodec 17 | import io.vertx.ext.web.multipart.MultipartForm 18 | import java.lang.Boolean 19 | import java.lang.Iterable 20 | import java.lang.Object 21 | import java.lang.String 22 | import java.lang.Void 23 | import java.util.function.Function 24 | 25 | package object client { 26 | implicit class VertxHttpRequestOps[T](val target: HttpRequest[T]) { 27 | /** 28 | * Like {@link #send(Handler)} but with an HTTP request {@code body} stream. 29 | * @param body the body 30 | */ 31 | def sendStreamL(body: ReadStream[Buffer]): Task[HttpResponse[T]] = 32 | Task.handle[HttpResponse[T]] { handler => 33 | target.sendStream(body, handler) 34 | } 35 | 36 | /** 37 | * Like {@link #send(Handler)} but with an HTTP request {@code body} buffer. 38 | * @param body the body 39 | */ 40 | def sendBufferL(body: Buffer): Task[HttpResponse[T]] = 41 | Task.handle[HttpResponse[T]] { handler => 42 | target.sendBuffer(body, handler) 43 | } 44 | 45 | /** 46 | * Like {@link #send(Handler)} but with an HTTP request {@code body} object encoded as json and the content type 47 | * set to {@code application/json}. 48 | * @param body the body 49 | */ 50 | def sendJsonObjectL(body: JsonObject): Task[HttpResponse[T]] = 51 | Task.handle[HttpResponse[T]] { handler => 52 | target.sendJsonObject(body, handler) 53 | } 54 | 55 | /** 56 | * Like {@link #send(Handler)} but with an HTTP request {@code body} object encoded as json and the content type 57 | * set to {@code application/json}. 58 | * @param body the body 59 | */ 60 | def sendJsonL(body: Object): Task[HttpResponse[T]] = 61 | Task.handle[HttpResponse[T]] { handler => 62 | target.sendJson(body, handler) 63 | } 64 | 65 | /** 66 | * Like {@link #send(Handler)} but with an HTTP request {@code body} multimap encoded as form and the content type 67 | * set to {@code application/x-www-form-urlencoded}. 68 | *

69 | * When the content type header is previously set to {@code multipart/form-data} it will be used instead. 70 | * @param body the body 71 | */ 72 | def sendFormL(body: MultiMap): Task[HttpResponse[T]] = 73 | Task.handle[HttpResponse[T]] { handler => 74 | target.sendForm(body, handler) 75 | } 76 | 77 | /** 78 | * Like {@link #send(Handler)} but with an HTTP request {@code body} multimap encoded as form and the content type 79 | * set to {@code multipart/form-data}. You may use this method to send attributes and upload files. 80 | * @param body the body 81 | */ 82 | def sendMultipartFormL(body: MultipartForm): Task[HttpResponse[T]] = 83 | Task.handle[HttpResponse[T]] { handler => 84 | target.sendMultipartForm(body, handler) 85 | } 86 | 87 | /** 88 | * Send a request, the {@code handler} will receive the response as an {@link HttpResponse}. 89 | */ 90 | def sendL(): Task[HttpResponse[T]] = 91 | Task.handle[HttpResponse[T]] { handler => 92 | target.send(handler) 93 | } 94 | } 95 | 96 | 97 | } -------------------------------------------------------------------------------- /cassandra/generated/vertices/cassandra/package.scala: -------------------------------------------------------------------------------- 1 | package vertices 2 | 3 | 4 | import monix.eval.Task 5 | import com.datastax.driver.core.ColumnDefinitions 6 | import com.datastax.driver.core.ExecutionInfo 7 | import com.datastax.driver.core.PreparedStatement 8 | import com.datastax.driver.core.Row 9 | import com.datastax.driver.core.Statement 10 | import io.vertx.cassandra.CassandraClient 11 | import io.vertx.cassandra.CassandraClientOptions 12 | import io.vertx.cassandra.CassandraRowStream 13 | import io.vertx.cassandra.Mapper 14 | import io.vertx.cassandra.ResultSet 15 | import io.vertx.core.AsyncResult 16 | import io.vertx.core.Handler 17 | import io.vertx.core.Vertx 18 | import io.vertx.core.streams.Pipe 19 | import io.vertx.core.streams.ReadStream 20 | import io.vertx.core.streams.WriteStream 21 | import java.lang.Object 22 | import java.lang.String 23 | import java.lang.Throwable 24 | import java.lang.Void 25 | import java.util.List 26 | 27 | package object cassandra { 28 | implicit class VertxResultSetOps(val target: ResultSet) extends AnyVal { 29 | /** 30 | * 31 | * @param handler handler called when result is fetched 32 | * @see com.datastax.driver.core.ResultSet#fetchMoreResults() 33 | */ 34 | def fetchMoreResultsL(): Task[Unit] = 35 | Task.handle[Void] { handler => 36 | target.fetchMoreResults(handler) 37 | }.map(_ => ()) 38 | } 39 | 40 | 41 | implicit class VertxCassandraRowStreamOps(val target: CassandraRowStream) extends AnyVal { 42 | 43 | def pipeToL(dst: WriteStream[Row]): Task[Unit] = 44 | Task.handle[Void] { handler => 45 | target.pipeTo(dst, handler) 46 | }.map(_ => ()) 47 | } 48 | 49 | 50 | implicit class VertxCassandraClientOps(val target: CassandraClient) extends AnyVal { 51 | /** 52 | * Execute the query and provide a handler for consuming results. 53 | * @param resultHandler handler called when result of execution is present, but can be not fully fetched 54 | * @param query the query to execute 55 | * @return current Cassandra client instance 56 | */ 57 | def executeL(query: String): Task[ResultSet] = 58 | Task.handle[ResultSet] { resultHandler => 59 | target.execute(query, resultHandler) 60 | } 61 | 62 | /** 63 | * Executes the given SQL SELECT statement which returns the results of the query as a read stream. 64 | * @param sql the SQL to execute. For example SELECT * FROM table .... 65 | * @param rowStreamHandler the handler which is called once the operation completes. It will return an instance of {@link CassandraRowStream}. 66 | * @return current Cassandra client instance 67 | */ 68 | def queryStreamL(sql: String): Task[CassandraRowStream] = 69 | Task.handle[CassandraRowStream] { rowStreamHandler => 70 | target.queryStream(sql, rowStreamHandler) 71 | } 72 | 73 | /** 74 | * Closes this client. 75 | * @param closeHandler handler called when client is closed 76 | * @return current Cassandra client instance 77 | */ 78 | def closeL(): Task[Unit] = 79 | Task.handle[Void] { closeHandler => 80 | target.close(closeHandler) 81 | }.map(_ => ()) 82 | } 83 | 84 | 85 | implicit class VertxMapperOps[T](val target: Mapper[T]) { 86 | /** 87 | * Asynchronous save method. 88 | * @param entity object to be stored in database 89 | * @param handler result handler 90 | */ 91 | def saveL(entity: T): Task[Unit] = 92 | Task.handle[Void] { handler => 93 | target.save(entity, handler) 94 | }.map(_ => ()) 95 | 96 | /** 97 | * Asynchronous delete method based on the column values of the primary key. 98 | * @param primaryKey primary key used to find row to delete 99 | * @param handler result handler 100 | */ 101 | def deleteL(primaryKey: List[Object]): Task[Unit] = 102 | Task.handle[Void] { handler => 103 | target.delete(primaryKey, handler) 104 | }.map(_ => ()) 105 | 106 | /** 107 | * Asynchronous get method based on the column values of the primary key. 108 | * @param primaryKey primary key used to retrieve row 109 | * @param handler result handler 110 | */ 111 | def getL(primaryKey: List[Object]): Task[T] = 112 | Task.handle[T] { handler => 113 | target.get(primaryKey, handler) 114 | } 115 | } 116 | 117 | 118 | } -------------------------------------------------------------------------------- /core/src/vertices/package.scala: -------------------------------------------------------------------------------- 1 | import scala.util.{ Success, Failure } 2 | 3 | import cats.{ Contravariant, Functor } 4 | import io.vertx.core.{ AsyncResult, Promise => VertxPromise, Handler, Vertx } 5 | import io.vertx.core.streams.{ Pump, ReadStream, WriteStream } 6 | import io.vertx.ext.reactivestreams.{ ReactiveReadStream, ReactiveWriteStream } 7 | import monix.execution.{ Callback, Cancelable } 8 | import monix.eval.Task 9 | import monix.reactive.{ Observable, Observer } 10 | import scala.util.control.NonFatal 11 | import shapeless.=:!= 12 | 13 | package object vertices { 14 | implicit class MonixTaskCompanionVertxOps(task: Task.type) { 15 | def handle[A](f: Handler[AsyncResult[A]] => Unit): Task[A] = { 16 | def handler(cb: Callback[Throwable, A]): Handler[AsyncResult[A]] = { result => 17 | if (result.succeeded) 18 | cb.onSuccess(result.result) 19 | else 20 | cb.onError(result.cause) 21 | } 22 | 23 | def runnable(cb: Callback[Throwable, A]): Runnable = 24 | () => try f(handler(cb)) catch { 25 | case NonFatal(e) => cb.onError(e) 26 | } 27 | 28 | Task.create { (s, cb) => 29 | val scb = Callback.safe(cb)(s) 30 | s.execute(runnable(scb)) 31 | Cancelable.empty 32 | } 33 | } 34 | } 35 | 36 | implicit class VertxVoidPromiseOps[A <: Void](promise: VertxPromise[A]) { 37 | def completeWith[B](task: Task[B]): Task[Unit] = { 38 | task.materialize.map { 39 | case Success(_) => promise.complete() 40 | case Failure(error) => promise.fail(error) 41 | } 42 | } 43 | } 44 | 45 | implicit class VertxPromiseOps[A](promise: VertxPromise[A])(implicit neq: A =:!= Void) { 46 | def completeWith(task: Task[A]): Task[Unit] = { 47 | task.materialize.map { 48 | case Success(result) => promise.complete(result) 49 | case Failure(error) => promise.fail(error) 50 | } 51 | } 52 | } 53 | 54 | implicit class VertxReadStreamOps[A](readStream: ReadStream[A]) { 55 | def toObservable(vertx: Vertx): Task[Observable[A]] = { 56 | Task.eval { 57 | val writeStream = ReactiveWriteStream.writeStream[A](vertx) 58 | readStream.pipeTo(writeStream) 59 | Observable.fromReactivePublisher(writeStream) 60 | } 61 | } 62 | } 63 | 64 | implicit class VertxWriteStreamOps[A](writeStream: WriteStream[A]) { 65 | def toObserver: Task[Observer[A]] = Task.deferAction { implicit s => 66 | Task.eval { 67 | val readStream = ReactiveReadStream.readStream[A]() 68 | val pump = Pump.pump(readStream, writeStream).start() 69 | Observer.fromReactiveSubscriber(readStream, Cancelable(() => pump.stop())) 70 | } 71 | } 72 | } 73 | 74 | implicit val verticesContravariantForHandler: Contravariant[Handler] = new Contravariant[Handler] { 75 | def contramap[A, B](handler: Handler[A])(f: B => A): Handler[B] = 76 | b => handler.handle(f(b)) 77 | } 78 | 79 | implicit val verticesContravariantForWriteStream: Contravariant[WriteStream] = new Contravariant[WriteStream] { 80 | def contramap[A, B](writeStream: WriteStream[A])(f: B => A): WriteStream[B] = new WriteStream[B] { 81 | def drainHandler(end: Handler[Void]): WriteStream[B] = { 82 | writeStream.drainHandler(end) 83 | this 84 | } 85 | def end(): Unit = 86 | writeStream.end() 87 | def end(handler: Handler[AsyncResult[Void]]): Unit = 88 | writeStream.end(handler) 89 | def exceptionHandler(exc: Handler[Throwable]): WriteStream[B] = { 90 | writeStream.exceptionHandler(exc) 91 | this 92 | } 93 | def setWriteQueueMaxSize(size: Int): WriteStream[B] = { 94 | writeStream.setWriteQueueMaxSize(size) 95 | this 96 | } 97 | def write(b: B): WriteStream[B] = { 98 | writeStream.write(f(b)) 99 | this 100 | } 101 | def write(b: B, handler: Handler[AsyncResult[Void]]) = { 102 | writeStream.write(f(b), handler) 103 | this 104 | } 105 | def writeQueueFull(): Boolean = 106 | writeStream.writeQueueFull() 107 | } 108 | } 109 | 110 | implicit val verticesFunctorForReadStream: Functor[ReadStream] = new Functor[ReadStream] { 111 | def map[A, B](readStream: ReadStream[A])(f: A => B): ReadStream[B] = new ReadStream[B] { 112 | def endHandler(end: Handler[java.lang.Void]) = { 113 | readStream.endHandler(end) 114 | this 115 | } 116 | def exceptionHandler(exc: Handler[Throwable]) = { 117 | readStream.exceptionHandler(exc) 118 | this 119 | } 120 | def handler(b: Handler[B]) = { 121 | readStream.handler(verticesContravariantForHandler.contramap(b)(f)) 122 | this 123 | } 124 | def pause() = { 125 | readStream.pause() 126 | this 127 | } 128 | def resume() = { 129 | readStream.resume() 130 | this 131 | } 132 | def fetch(amount: Long) = { 133 | readStream.fetch(amount) 134 | this 135 | } 136 | } 137 | } 138 | } 139 | -------------------------------------------------------------------------------- /codegen/src/vertices/codegen/CodegenProcessor.scala: -------------------------------------------------------------------------------- 1 | package vertices.codegen 2 | 3 | import io.vertx.codegen._ 4 | import io.vertx.codegen.`type`._ 5 | import io.vertx.codegen.annotations.VertxGen 6 | import java.lang.{ Exception, String, System } 7 | import java.nio.file.{ Files, Paths, Path } 8 | import java.nio.charset.StandardCharsets 9 | import java.util.{ ArrayList, List, HashSet, Set } 10 | import java.util.stream.{ Collectors, Stream } 11 | import javax.annotation.processing.{ AbstractProcessor, RoundEnvironment } 12 | import javax.lang.model.SourceVersion 13 | import javax.lang.model.element.TypeElement 14 | import scala.{ Boolean, StringContext } 15 | import scala.Predef.{ augmentString, classOf } 16 | 17 | class CodegenProcessor extends AbstractProcessor { 18 | val excludedModels = { 19 | val excluded = new HashSet[String]() 20 | // excluded.add("io.vertx.core.Future") 21 | // excluded.add("io.vertx.core.CompositeFuture") 22 | // excluded.add("io.vertx.ext.bridge.BaseBridgeEvent") 23 | // excluded.add("io.vertx.ext.web.handler.sockjs.BridgeEvent") 24 | excluded 25 | } 26 | 27 | val importedTypes = new ArrayList[TypeInfo]() 28 | val opsClasses = new ArrayList[String]() 29 | 30 | def sanitisePackageName(name: String) = 31 | name.replaceAll("\\.type\\.", ".`type`.") 32 | 33 | def formatImports(importedTypes: List[TypeInfo]): String = { 34 | importedTypes.stream().distinct().reduce[List[String]]( 35 | new ArrayList[String](), { (imps: List[String], next: TypeInfo) => 36 | imps.add(sanitisePackageName(next.getName)) 37 | imps 38 | }, { (l, r) => 39 | l.addAll(r) 40 | l 41 | }).stream().map("import " + _).sorted.collect(Collectors.joining(System.lineSeparator)) 42 | } 43 | 44 | override def process(annotations: Set[_ <: TypeElement], roundEnv: RoundEnvironment): Boolean = { 45 | val classLoader = getClass.getClassLoader 46 | 47 | val codegen = new CodeGen(processingEnv, roundEnv, classLoader) 48 | 49 | val models = codegen.getModels().filter { 50 | _.getValue.isInstanceOf[ClassModel] 51 | }.map { 52 | _.getValue.asInstanceOf[ClassModel] 53 | } 54 | 55 | val modelsWithHandlers = models.filter { mdl => 56 | !mdl.getMethods.stream().filter { m => 57 | m.getKind == MethodKind.FUTURE 58 | }.collect(Collectors.toList()).isEmpty 59 | } 60 | 61 | val nonExcludedModels = modelsWithHandlers.filter { m => 62 | !m.isDeprecated && m.isConcrete && !excludedModels.contains(m.getFqn) 63 | }.collect(Collectors.toList()) 64 | 65 | val outPath = Paths.get(processingEnv.getOptions.get("codegen.output.dir")) 66 | 67 | val newImports = nonExcludedModels.stream().flatMap { mdl => 68 | Stream.concat( 69 | Stream.of(mdl.getType), 70 | mdl.getImportedTypes.stream() 71 | ) 72 | }.distinct.collect(Collectors.toList[TypeInfo]()) 73 | 74 | importedTypes.addAll(newImports) 75 | 76 | val newOpsClasses = nonExcludedModels.stream().map { mdl => 77 | Codegen.generate(mdl) 78 | }.collect(Collectors.toList()) 79 | 80 | opsClasses.addAll(newOpsClasses) 81 | 82 | if (roundEnv.processingOver()) { 83 | if (Files.exists(outPath) && !Files.isDirectory(outPath)) 84 | throw new Exception(s"The output path ${outPath} is not a directory") 85 | 86 | val modNameSegments = processingEnv.getOptions.get("codegen.module.name").split("_") 87 | 88 | val modName = modNameSegments(modNameSegments.length - 1) 89 | 90 | val modPackage = Stream.of(modNameSegments: _*) 91 | .limit(modNameSegments.length - 1L) 92 | .collect(Collectors.joining(".")) 93 | 94 | val modPackageStatement = 95 | if (modPackage.isEmpty()) "" else s"package ${modPackage}" 96 | 97 | val dest = Stream.of(modNameSegments: _*).reduce[Path]( 98 | outPath.resolve("vertices"), 99 | (path, segment) => path.resolve(segment), 100 | (l, r) => l.resolve(r) 101 | ) 102 | 103 | val destFile = dest.resolve(s"package.scala") 104 | 105 | if (!Files.exists(dest)) 106 | Files.createDirectories(dest) 107 | 108 | Files.deleteIfExists(destFile) 109 | 110 | val template = s""" 111 | |package vertices 112 | |${modPackageStatement} 113 | | 114 | |import monix.eval.Task 115 | |${formatImports(importedTypes)} 116 | | 117 | |package object ${modName} { 118 | |${opsClasses.stream().collect(Collectors.joining(System.lineSeparator))} 119 | |} 120 | """.trim.stripMargin 121 | 122 | Files.write(destFile, template.getBytes(StandardCharsets.UTF_8)) 123 | } 124 | 125 | true 126 | } 127 | 128 | override def getSupportedAnnotationTypes: Set[String] = { 129 | val set = new HashSet[String]() 130 | set.add(classOf[VertxGen].getName) 131 | set 132 | } 133 | 134 | override def getSupportedOptions: Set[String] = { 135 | val set = new HashSet[String]() 136 | set.add("codegen.module.name") 137 | set.add("codegen.output.dir") 138 | set 139 | } 140 | 141 | override def getSupportedSourceVersion: SourceVersion = SourceVersion.RELEASE_8 142 | } 143 | -------------------------------------------------------------------------------- /stomp/generated/vertices/stomp/package.scala: -------------------------------------------------------------------------------- 1 | package vertices 2 | 3 | 4 | import monix.eval.Task 5 | import io.vertx.core.AsyncResult 6 | import io.vertx.core.Handler 7 | import io.vertx.core.Vertx 8 | import io.vertx.core.http.ServerWebSocket 9 | import io.vertx.core.net.NetClient 10 | import io.vertx.core.net.NetServer 11 | import io.vertx.ext.auth.AuthProvider 12 | import io.vertx.ext.auth.User 13 | import io.vertx.ext.stomp.Acknowledgement 14 | import io.vertx.ext.stomp.BridgeOptions 15 | import io.vertx.ext.stomp.Destination 16 | import io.vertx.ext.stomp.DestinationFactory 17 | import io.vertx.ext.stomp.Frame 18 | import io.vertx.ext.stomp.ServerFrame 19 | import io.vertx.ext.stomp.StompClient 20 | import io.vertx.ext.stomp.StompClientConnection 21 | import io.vertx.ext.stomp.StompClientOptions 22 | import io.vertx.ext.stomp.StompServer 23 | import io.vertx.ext.stomp.StompServerConnection 24 | import io.vertx.ext.stomp.StompServerHandler 25 | import io.vertx.ext.stomp.StompServerOptions 26 | import java.lang.Boolean 27 | import java.lang.String 28 | import java.lang.Throwable 29 | import java.lang.Void 30 | import java.util.List 31 | 32 | package object stomp { 33 | implicit class VertxStompClientOps(val target: StompClient) extends AnyVal { 34 | /** 35 | * Connects to the server. 36 | * @param port the server port 37 | * @param host the server host 38 | * @param resultHandler handler called with the connection result 39 | * @return the current {@link StompClient} 40 | */ 41 | def connectL(port: Int, host: String): Task[StompClientConnection] = 42 | Task.handle[StompClientConnection] { resultHandler => 43 | target.connect(port, host, resultHandler) 44 | } 45 | 46 | /** 47 | * Connects to the server. 48 | * @param net the NET client to use 49 | * @param resultHandler handler called with the connection result 50 | * @return the current {@link StompClient} 51 | */ 52 | def connectL(net: NetClient): Task[StompClientConnection] = 53 | Task.handle[StompClientConnection] { resultHandler => 54 | target.connect(net, resultHandler) 55 | } 56 | 57 | /** 58 | * Connects to the server. 59 | * @param port the server port 60 | * @param host the server host 61 | * @param net the NET client to use 62 | * @param resultHandler handler called with the connection result 63 | * @return the current {@link StompClient} 64 | */ 65 | def connectL(port: Int, host: String, net: NetClient): Task[StompClientConnection] = 66 | Task.handle[StompClientConnection] { resultHandler => 67 | target.connect(port, host, net, resultHandler) 68 | } 69 | 70 | /** 71 | * Connects to the server using the host and port configured in the client's options. 72 | * @param resultHandler handler called with the connection result. A failure will be sent to the handler if a TCP 73 | * level issue happen before the `CONNECTED` frame is received. Afterwards, the 74 | * {@link #exceptionHandler(Handler)} is called. 75 | * @return the current {@link StompClient} 76 | */ 77 | def connectL(): Task[StompClientConnection] = 78 | Task.handle[StompClientConnection] { resultHandler => 79 | target.connect(resultHandler) 80 | } 81 | } 82 | 83 | 84 | implicit class VertxStompServerHandlerOps(val target: StompServerHandler) extends AnyVal { 85 | /** 86 | * Called when the client connects to a server requiring authentication. It invokes the {@link AuthProvider} configured 87 | * using {@link #authProvider(AuthProvider)}. 88 | * @param connection server connection that contains session ID 89 | * @param login the login 90 | * @param passcode the password 91 | * @param handler handler receiving the authentication result 92 | * @return the current {@link StompServerHandler} 93 | */ 94 | def onAuthenticationRequestL(connection: StompServerConnection, login: String, passcode: String): Task[Boolean] = 95 | Task.handle[java.lang.Boolean] { handler => 96 | target.onAuthenticationRequest(connection, login, passcode, handler) 97 | }.map(out => out: Boolean) 98 | } 99 | 100 | 101 | implicit class VertxStompServerOps(val target: StompServer) extends AnyVal { 102 | /** 103 | * Connects the STOMP server default port (61613) and network interface ({@code 0.0.0.0}). Once the socket 104 | * it bounds calls the given handler with the result. The result may be a failure if the socket is already used. 105 | * @param handler the handler to call with the result 106 | * @return the current {@link StompServer} 107 | */ 108 | def listenL(): Task[StompServer] = 109 | Task.handle[StompServer] { handler => 110 | target.listen(handler) 111 | } 112 | 113 | /** 114 | * Connects the STOMP server to the given port. This method use the default host ({@code 0.0.0.0}). Once the socket 115 | * it bounds calls the given handler with the result. The result may be a failure if the socket is already used. 116 | * @param port the port 117 | * @param handler the handler to call with the result 118 | * @return the current {@link StompServer} 119 | */ 120 | def listenL(port: Int): Task[StompServer] = 121 | Task.handle[StompServer] { handler => 122 | target.listen(port, handler) 123 | } 124 | 125 | /** 126 | * Connects the STOMP server to the given port / interface. Once the socket it bounds calls the given handler with 127 | * the result. The result may be a failure if the socket is already used. 128 | * @param port the port 129 | * @param host the host / interface 130 | * @param handler the handler to call with the result 131 | * @return the current {@link StompServer} 132 | */ 133 | def listenL(port: Int, host: String): Task[StompServer] = 134 | Task.handle[StompServer] { handler => 135 | target.listen(port, host, handler) 136 | } 137 | 138 | /** 139 | * Closes the server. 140 | * @param completionHandler handler called once the server has been stopped 141 | */ 142 | def closeL(): Task[Unit] = 143 | Task.handle[Void] { completionHandler => 144 | target.close(completionHandler) 145 | }.map(_ => ()) 146 | } 147 | 148 | 149 | } -------------------------------------------------------------------------------- /auth_oauth2/generated/vertices/auth/oauth2/package.scala: -------------------------------------------------------------------------------- 1 | package vertices 2 | package auth 3 | 4 | import monix.eval.Task 5 | import io.vertx.core.AsyncResult 6 | import io.vertx.core.Handler 7 | import io.vertx.core.Vertx 8 | import io.vertx.core.http.HttpClientOptions 9 | import io.vertx.core.json.JsonObject 10 | import io.vertx.ext.auth.AuthProvider 11 | import io.vertx.ext.auth.oauth2.AccessToken 12 | import io.vertx.ext.auth.oauth2.OAuth2Auth 13 | import io.vertx.ext.auth.oauth2.OAuth2ClientOptions 14 | import io.vertx.ext.auth.oauth2.OAuth2FlowType 15 | import io.vertx.ext.auth.oauth2.OAuth2RBAC 16 | import io.vertx.ext.auth.oauth2.providers.AzureADAuth 17 | import io.vertx.ext.auth.oauth2.providers.GoogleAuth 18 | import io.vertx.ext.auth.oauth2.providers.KeycloakAuth 19 | import io.vertx.ext.auth.oauth2.providers.OpenIDConnectAuth 20 | import io.vertx.ext.auth.oauth2.providers.SalesforceAuth 21 | import java.lang.Boolean 22 | import java.lang.String 23 | import java.lang.Void 24 | 25 | package object oauth2 { 26 | 27 | object AzureADAuthFunctions { 28 | /** 29 | * Create a OAuth2Auth provider for OpenID Connect Discovery. The discovery will use the default site in the 30 | * configuration options and attempt to load the well known descriptor. If a site is provided (for example when 31 | * running on a custom instance) that site will be used to do the lookup. 32 | *

33 | * If the discovered config includes a json web key url, it will be also fetched and the JWKs will be loaded 34 | * into the OAuth provider so tokens can be decoded. 35 | * @param vertx the vertx instance 36 | * @param config the initial config 37 | * @param handler the instantiated Oauth2 provider instance handler 38 | */ 39 | def discoverL(vertx: Vertx, config: OAuth2ClientOptions): Task[OAuth2Auth] = 40 | Task.handle[OAuth2Auth] { handler => 41 | AzureADAuth.discover(vertx, config, handler) 42 | } 43 | } 44 | 45 | 46 | object KeycloakAuthFunctions { 47 | /** 48 | * Create a OAuth2Auth provider for OpenID Connect Discovery. The discovery will use the default site in the 49 | * configuration options and attempt to load the well known descriptor. If a site is provided (for example when 50 | * running on a custom instance) that site will be used to do the lookup. 51 | *

52 | * If the discovered config includes a json web key url, it will be also fetched and the JWKs will be loaded 53 | * into the OAuth provider so tokens can be decoded. 54 | * @param vertx the vertx instance 55 | * @param config the initial config 56 | * @param handler the instantiated Oauth2 provider instance handler 57 | */ 58 | def discoverL(vertx: Vertx, config: OAuth2ClientOptions): Task[OAuth2Auth] = 59 | Task.handle[OAuth2Auth] { handler => 60 | KeycloakAuth.discover(vertx, config, handler) 61 | } 62 | } 63 | 64 | 65 | object OpenIDConnectAuthFunctions { 66 | /** 67 | * Create a OAuth2Auth provider for OpenID Connect Discovery. The discovery will use the given site in the 68 | * configuration options and attempt to load the well known descriptor. 69 | * 70 | * If the discovered config includes a json web key url, it will be also fetched and the JWKs will be loaded 71 | * into the OAuth provider so tokens can be decoded. 72 | * @param vertx the vertx instance 73 | * @param config the initial config, it should contain a site url 74 | * @param handler the instantiated Oauth2 provider instance handler 75 | */ 76 | def discoverL(vertx: Vertx, config: OAuth2ClientOptions): Task[OAuth2Auth] = 77 | Task.handle[OAuth2Auth] { handler => 78 | OpenIDConnectAuth.discover(vertx, config, handler) 79 | } 80 | } 81 | 82 | implicit class VertxOAuth2RBACOps(val target: OAuth2RBAC) extends AnyVal { 83 | /** 84 | * This method should verify if the user has the given authority and return either a boolean value or an error. 85 | * 86 | * Note that false and errors are not the same. A user might not have a given authority but that doesn't mean that 87 | * there was an error during the call. 88 | * @param user the given user to assert on 89 | * @param authority the authority to lookup 90 | * @param handler the result handler. 91 | */ 92 | def isAuthorizedL(user: AccessToken, authority: String): Task[Boolean] = 93 | Task.handle[java.lang.Boolean] { handler => 94 | target.isAuthorized(user, authority, handler) 95 | }.map(out => out: Boolean) 96 | } 97 | 98 | 99 | 100 | object GoogleAuthFunctions { 101 | /** 102 | * Create a OAuth2Auth provider for OpenID Connect Discovery. The discovery will use the default site in the 103 | * configuration options and attempt to load the well known descriptor. If a site is provided (for example when 104 | * running on a custom instance) that site will be used to do the lookup. 105 | *

106 | * If the discovered config includes a json web key url, it will be also fetched and the JWKs will be loaded 107 | * into the OAuth provider so tokens can be decoded. 108 | * @param vertx the vertx instance 109 | * @param config the initial config 110 | * @param handler the instantiated Oauth2 provider instance handler 111 | */ 112 | def discoverL(vertx: Vertx, config: OAuth2ClientOptions): Task[OAuth2Auth] = 113 | Task.handle[OAuth2Auth] { handler => 114 | GoogleAuth.discover(vertx, config, handler) 115 | } 116 | } 117 | 118 | 119 | 120 | 121 | object SalesforceAuthFunctions { 122 | /** 123 | * Create a OAuth2Auth provider for OpenID Connect Discovery. The discovery will use the default site in the 124 | * configuration options and attempt to load the well known descriptor. If a site is provided (for example when 125 | * running on a custom instance) that site will be used to do the lookup. 126 | *

127 | * If the discovered config includes a json web key url, it will be also fetched and the JWKs will be loaded 128 | * into the OAuth provider so tokens can be decoded. 129 | * @param vertx the vertx instance 130 | * @param config the initial config 131 | * @param handler the instantiated Oauth2 provider instance handler 132 | */ 133 | def discoverL(vertx: Vertx, config: OAuth2ClientOptions): Task[OAuth2Auth] = 134 | Task.handle[OAuth2Auth] { handler => 135 | SalesforceAuth.discover(vertx, config, handler) 136 | } 137 | } 138 | 139 | } -------------------------------------------------------------------------------- /codegen/src/vertices/codegen/Codegen.scala: -------------------------------------------------------------------------------- 1 | package vertices.codegen 2 | 3 | import io.vertx.codegen._ 4 | import io.vertx.codegen.doc._ 5 | import io.vertx.codegen.`type`._ 6 | import java.lang.{ String, System } 7 | import java.util.{ HashSet, List } 8 | import java.util.stream.{ Collectors, Stream } 9 | import scala.{ Array, Boolean, Char, Int, Option, StringContext } 10 | import scala.Predef.augmentString 11 | 12 | object Codegen { 13 | val excludedMethods = { 14 | val excluded = new HashSet[String]() 15 | // excluded.add("addInterceptor") 16 | // excluded.add("removeInterceptor") 17 | // excluded.add("pipe") 18 | // excluded.add("pipeTo") 19 | // excluded.add("redirectHandler") 20 | excluded 21 | } 22 | 23 | def generate(model: ClassModel): String = { 24 | def sanitiseName(name: String) = name 25 | .replaceFirst("^type$", "`type`") 26 | .replaceFirst("^object$", "`object`") 27 | 28 | def scalaParamTypeName(typ: TypeInfo) = { 29 | if (typ.getKind == ClassKind.STRING) 30 | "String" 31 | else if (typ.getKind == ClassKind.BOXED_PRIMITIVE) 32 | typ.getName 33 | else { 34 | typ.getSimpleName.replace("<", "[").replace(">", "]") 35 | } 36 | } 37 | 38 | def scalaTypeName(typ: TypeInfo) = { 39 | if (typ.getName == "byte" || typ.getName == "java.lang.Byte") 40 | "Byte" 41 | else if (typ.getName == "short" || typ.getName == "java.lang.Short") 42 | "Short" 43 | else if (typ.getName == "int" || typ.getName == "java.lang.Integer") 44 | "Int" 45 | else if (typ.getName == "long" || typ.getName == "java.lang.Long") 46 | "Long" 47 | else if (typ.getName == "float" || typ.getName == "java.lang.Float") 48 | "Float" 49 | else if (typ.getName == "double" || typ.getName == "java.lang.Double") 50 | "Double" 51 | else if (typ.getName == "boolean" || typ.getName == "java.lang.Boolean") 52 | "Boolean" 53 | else if (typ.getName == "char" || typ.getName == "java.lang.Character") 54 | "Char" 55 | else if (typ.getName == "void" || typ.getName == "java.lang.Void") 56 | "Unit" 57 | else if (typ.getKind == ClassKind.STRING) 58 | "String" 59 | else 60 | typ.getSimpleName 61 | .replace("<", "[") 62 | .replace(">", "]") 63 | } 64 | 65 | def typeParameters(tparams: List[_ <: TypeParamInfo]) = { 66 | if (tparams.isEmpty) 67 | "" 68 | else { 69 | "[" + 70 | tparams.stream() 71 | .map(_.getName) 72 | .collect(Collectors.joining(", ")) + 73 | "]" 74 | } 75 | 76 | } 77 | 78 | def methodParameters(kind: MethodKind, params: List[ParamInfo]) = { 79 | val parms = params.stream().map { param => 80 | sanitiseName(param.getName) + ": " + scalaTypeName(param.getType) 81 | } 82 | 83 | if (kind == MethodKind.FUTURE) 84 | parms.limit(params.size - 1L).collect(Collectors.joining(", ")) 85 | else 86 | parms.collect(Collectors.joining(", ")) 87 | } 88 | 89 | def handlerParam(kind: MethodKind, params: List[ParamInfo], tparam: Boolean = false) = { 90 | if (kind != MethodKind.FUTURE) 91 | "" 92 | else { 93 | val handlerParm = params 94 | .stream() 95 | .reduce((_, p) => p) 96 | .get() 97 | .getType 98 | .asInstanceOf[ParameterizedTypeInfo].getArg(0) 99 | .asInstanceOf[ParameterizedTypeInfo].getArg(0) 100 | if (tparam) 101 | scalaParamTypeName(handlerParm) 102 | else 103 | scalaTypeName(handlerParm) 104 | } 105 | } 106 | 107 | def returnType(kind: MethodKind, params: List[ParamInfo], ret: TypeInfo) = { 108 | if (kind == MethodKind.FUTURE) { 109 | s"Task[${handlerParam(kind, params)}]" 110 | } else { 111 | scalaTypeName(ret) 112 | } 113 | } 114 | 115 | def taskConversions(params: List[ParamInfo]) = { 116 | val handlerParm = params 117 | .stream() 118 | .reduce((_, p) => p) 119 | .get() 120 | .getType 121 | .asInstanceOf[ParameterizedTypeInfo].getArg(0) 122 | .asInstanceOf[ParameterizedTypeInfo].getArg(0) 123 | 124 | if (handlerParm.getName == "java.lang.Void") 125 | ".map(_ => ())" 126 | else if (handlerParm.getKind == ClassKind.BOXED_PRIMITIVE) 127 | s".map(out => out: ${scalaTypeName(handlerParm)})" 128 | else "" 129 | } 130 | 131 | def javaDocToScalaDoc(indent: Int)(doc: Doc): String = { 132 | val sep = System.lineSeparator 133 | 134 | val spaces = new String(new Array[Char](indent)).replace("\u0000", " ") 135 | 136 | spaces + "/**" + sep + 137 | Stream.of(doc.toString.split("\\r?\\n"): _*) 138 | .map(spaces + " * " + _) 139 | .collect(Collectors.joining(sep)) + sep + spaces + " */" 140 | } 141 | 142 | def instanceMethods(methods: List[MethodInfo]) = methods.stream().map { method => 143 | val tparams = method.getTypeParams 144 | val tparamString = typeParameters(tparams) 145 | val params = method.getParams 146 | val kind = method.getKind 147 | val handledParam = handlerParam(kind, params, tparam = true) 148 | val retType = returnType(kind, params, method.getReturnType) 149 | 150 | val scalaDoc = Option(method.getDoc) 151 | .map(javaDocToScalaDoc(4)) 152 | .getOrElse("") 153 | 154 | val paramNames = params.stream() 155 | .map(p => sanitiseName(p.getName)) 156 | .collect(Collectors.joining(", ")) 157 | 158 | val lastParamName = params.stream() 159 | .reduce((_, p) => p) 160 | .get() 161 | .getName 162 | 163 | s""" 164 | |${scalaDoc} 165 | | def ${sanitiseName(method.getName + "L")}${tparamString}(${methodParameters(kind, params)}): ${retType} = 166 | | Task.handle[${handledParam}] { ${lastParamName} => 167 | | target.${sanitiseName(method.getName)}(${paramNames}) 168 | | }${taskConversions(params)} 169 | """.trim.stripMargin 170 | }.collect(Collectors.joining(System.lineSeparator + System.lineSeparator)) 171 | 172 | def staticMethods(tpNme: String, methods: List[MethodInfo]) = methods.stream().map { method => 173 | val tparams = method.getTypeParams 174 | val tparamString = typeParameters(tparams) 175 | val params = method.getParams 176 | val kind = method.getKind 177 | val handledParam = handlerParam(kind, params, tparam = true) 178 | val retType = returnType(kind, params, method.getReturnType) 179 | 180 | val scalaDoc = Option(method.getDoc) 181 | .map(javaDocToScalaDoc(4)) 182 | .getOrElse("") 183 | 184 | val paramNames = params.stream() 185 | .map(p => sanitiseName(p.getName)) 186 | .map(_.toString) 187 | .collect(Collectors.joining(", ")) 188 | 189 | val lastParamName = params.stream() 190 | .reduce((_, p) => p) 191 | .get() 192 | .getName 193 | 194 | s""" 195 | |${scalaDoc} 196 | | def ${sanitiseName(method.getName + "L")}${tparamString}(${methodParameters(kind, params)}): ${retType} = 197 | | Task.handle[${handledParam}] { ${lastParamName} => 198 | | ${tpNme}.${sanitiseName(method.getName)}(${paramNames}) 199 | | }${taskConversions(params)} 200 | """.trim.stripMargin 201 | }.collect(Collectors.joining(System.lineSeparator + System.lineSeparator)) 202 | 203 | val tp = model.getType 204 | 205 | val tpNme = tp.getSimpleName() 206 | val tparams = model.getTypeParams 207 | val anyVal = if (tparams.isEmpty) "extends AnyVal " else " " 208 | val tparamString = typeParameters(tparams) 209 | 210 | val instanceHandlers = model.getInstanceMethods.stream().filter { m => 211 | !m.isDeprecated && m.getKind == MethodKind.FUTURE 212 | }.collect(Collectors.toList()) 213 | 214 | val staticHandlers = model.getStaticMethods.stream().filter { m => 215 | !m.isDeprecated && m.getKind == MethodKind.FUTURE 216 | }.collect(Collectors.toList()) 217 | 218 | val classTemplate = Option( 219 | s""" 220 | | implicit class Vertx${tpNme}Ops${tparamString}(val target: ${tpNme}${tparamString}) ${anyVal}{ 221 | |${instanceMethods(instanceHandlers)} 222 | | } 223 | | 224 | """.trim.stripMargin 225 | ).filterNot(_ => instanceHandlers.isEmpty).getOrElse("") 226 | 227 | val objectTemplate = Option( 228 | s""" 229 | | object ${tpNme}Functions { 230 | |${staticMethods(tpNme, staticHandlers)} 231 | | } 232 | | 233 | """.trim.stripMargin 234 | ).filterNot(_ => staticHandlers.isEmpty).getOrElse("") 235 | 236 | classTemplate + System.lineSeparator + objectTemplate 237 | } 238 | } 239 | -------------------------------------------------------------------------------- /mqtt/generated/vertices/mqtt/package.scala: -------------------------------------------------------------------------------- 1 | package vertices 2 | 3 | 4 | import monix.eval.Task 5 | import io.netty.handler.codec.mqtt.MqttConnectReturnCode 6 | import io.netty.handler.codec.mqtt.MqttQoS 7 | import io.vertx.core.AsyncResult 8 | import io.vertx.core.Handler 9 | import io.vertx.core.Vertx 10 | import io.vertx.core.buffer.Buffer 11 | import io.vertx.core.net.SocketAddress 12 | import io.vertx.mqtt.MqttAuth 13 | import io.vertx.mqtt.MqttClient 14 | import io.vertx.mqtt.MqttClientOptions 15 | import io.vertx.mqtt.MqttEndpoint 16 | import io.vertx.mqtt.MqttServer 17 | import io.vertx.mqtt.MqttServerOptions 18 | import io.vertx.mqtt.MqttWill 19 | import io.vertx.mqtt.messages.MqttConnAckMessage 20 | import io.vertx.mqtt.messages.MqttPublishMessage 21 | import io.vertx.mqtt.messages.MqttSubAckMessage 22 | import io.vertx.mqtt.messages.MqttSubscribeMessage 23 | import io.vertx.mqtt.messages.MqttUnsubscribeMessage 24 | import java.lang.Integer 25 | import java.lang.String 26 | import java.lang.Throwable 27 | import java.lang.Void 28 | import java.util.List 29 | import java.util.Map 30 | 31 | package object mqtt { 32 | implicit class VertxMqttClientOps(val target: MqttClient) extends AnyVal { 33 | /** 34 | * Connects to an MQTT server calling connectHandler after connection 35 | * @param port port of the MQTT server 36 | * @param host hostname/ip address of the MQTT server 37 | * @param connectHandler handler called when the asynchronous connect call ends 38 | * @return current MQTT client instance 39 | */ 40 | def connectL(port: Int, host: String): Task[MqttConnAckMessage] = 41 | Task.handle[MqttConnAckMessage] { connectHandler => 42 | target.connect(port, host, connectHandler) 43 | } 44 | 45 | /** 46 | * Connects to an MQTT server calling connectHandler after connection 47 | * @param port port of the MQTT server 48 | * @param host hostname/ip address of the MQTT server 49 | * @param serverName the SNI server name 50 | * @param connectHandler handler called when the asynchronous connect call ends 51 | * @return current MQTT client instance 52 | */ 53 | def connectL(port: Int, host: String, serverName: String): Task[MqttConnAckMessage] = 54 | Task.handle[MqttConnAckMessage] { connectHandler => 55 | target.connect(port, host, serverName, connectHandler) 56 | } 57 | 58 | /** 59 | * Disconnects from the MQTT server calling disconnectHandler after disconnection 60 | * @param disconnectHandler handler called when asynchronous disconnect call ends 61 | * @return current MQTT client instance 62 | */ 63 | def disconnectL(): Task[Unit] = 64 | Task.handle[Void] { disconnectHandler => 65 | target.disconnect(disconnectHandler) 66 | }.map(_ => ()) 67 | 68 | /** 69 | * Sends the PUBLISH message to the remote MQTT server 70 | * @param topic topic on which the message is published 71 | * @param payload message payload 72 | * @param qosLevel QoS level 73 | * @param isDup if the message is a duplicate 74 | * @param isRetain if the message needs to be retained 75 | * @param publishSentHandler handler called after PUBLISH packet sent with packetid (not when QoS 0) 76 | * @return current MQTT client instance 77 | */ 78 | def publishL(topic: String, payload: Buffer, qosLevel: MqttQoS, isDup: Boolean, isRetain: Boolean): Task[Int] = 79 | Task.handle[java.lang.Integer] { publishSentHandler => 80 | target.publish(topic, payload, qosLevel, isDup, isRetain, publishSentHandler) 81 | }.map(out => out: Int) 82 | 83 | /** 84 | * Subscribes to the topic with a specified QoS level 85 | * @param topic topic you subscribe on 86 | * @param qos QoS level 87 | * @param subscribeSentHandler handler called after SUBSCRIBE packet sent with packetid 88 | * @return current MQTT client instance 89 | */ 90 | def subscribeL(topic: String, qos: Int): Task[Int] = 91 | Task.handle[java.lang.Integer] { subscribeSentHandler => 92 | target.subscribe(topic, qos, subscribeSentHandler) 93 | }.map(out => out: Int) 94 | 95 | /** 96 | * Subscribes to the topic and adds a handler which will be called after the request is sent 97 | * @param topics topics you subscribe on 98 | * @param subscribeSentHandler handler called after SUBSCRIBE packet sent with packetid 99 | * @return current MQTT client instance 100 | */ 101 | def subscribeL(topics: Map[String,Integer]): Task[Int] = 102 | Task.handle[java.lang.Integer] { subscribeSentHandler => 103 | target.subscribe(topics, subscribeSentHandler) 104 | }.map(out => out: Int) 105 | 106 | /** 107 | * Unsubscribe from receiving messages on given topic 108 | * @param topic Topic you want to unsubscribe from 109 | * @param unsubscribeSentHandler handler called after UNSUBSCRIBE packet sent 110 | * @return current MQTT client instance 111 | */ 112 | def unsubscribeL(topic: String): Task[Int] = 113 | Task.handle[java.lang.Integer] { unsubscribeSentHandler => 114 | target.unsubscribe(topic, unsubscribeSentHandler) 115 | }.map(out => out: Int) 116 | } 117 | 118 | 119 | implicit class VertxMqttEndpointOps(val target: MqttEndpoint) extends AnyVal { 120 | /** 121 | * Sends the PUBLISH message to the remote MQTT server 122 | * @param topic topic on which the message is published 123 | * @param payload message payload 124 | * @param qosLevel QoS level 125 | * @param isDup if the message is a duplicate 126 | * @param isRetain if the message needs to be retained 127 | * @param publishSentHandler handler called after PUBLISH packet sent with a packetId 128 | * @return current MQTT client instance 129 | */ 130 | def publishL(topic: String, payload: Buffer, qosLevel: MqttQoS, isDup: Boolean, isRetain: Boolean): Task[Int] = 131 | Task.handle[java.lang.Integer] { publishSentHandler => 132 | target.publish(topic, payload, qosLevel, isDup, isRetain, publishSentHandler) 133 | }.map(out => out: Int) 134 | 135 | /** 136 | * Sends the PUBLISH message to the remote MQTT server explicitly specifying the messageId 137 | * @param topic topic on which the message is published 138 | * @param payload message payload 139 | * @param qosLevel QoS level 140 | * @param isDup if the message is a duplicate 141 | * @param isRetain if the message needs to be retained 142 | * @param messageId message ID 143 | * @param publishSentHandler handler called after PUBLISH packet sent with a packetId 144 | * @return current MQTT client instance 145 | */ 146 | def publishL(topic: String, payload: Buffer, qosLevel: MqttQoS, isDup: Boolean, isRetain: Boolean, messageId: Int): Task[Int] = 147 | Task.handle[java.lang.Integer] { publishSentHandler => 148 | target.publish(topic, payload, qosLevel, isDup, isRetain, messageId, publishSentHandler) 149 | }.map(out => out: Int) 150 | } 151 | 152 | 153 | implicit class VertxMqttServerOps(val target: MqttServer) extends AnyVal { 154 | /** 155 | * Start the server listening for incoming connections on the port and host specified 156 | * It ignores any options specified through the constructor 157 | * @param port the port to listen on 158 | * @param host the host to listen on 159 | * @param listenHandler handler called when the asynchronous listen call ends 160 | * @return a reference to this, so the API can be used fluently 161 | */ 162 | def listenL(port: Int, host: String): Task[MqttServer] = 163 | Task.handle[MqttServer] { listenHandler => 164 | target.listen(port, host, listenHandler) 165 | } 166 | 167 | /** 168 | * Start the server listening for incoming connections on the port specified but on 169 | * "0.0.0.0" as host. It ignores any options specified through the constructor 170 | * @param port the port to listen on 171 | * @param listenHandler handler called when the asynchronous listen call ends 172 | * @return a reference to this, so the API can be used fluently 173 | */ 174 | def listenL(port: Int): Task[MqttServer] = 175 | Task.handle[MqttServer] { listenHandler => 176 | target.listen(port, listenHandler) 177 | } 178 | 179 | /** 180 | * Start the server listening for incoming connections using the specified options 181 | * through the constructor 182 | * @param listenHandler handler called when the asynchronous listen call ends 183 | * @return a reference to this, so the API can be used fluently 184 | */ 185 | def listenL(): Task[MqttServer] = 186 | Task.handle[MqttServer] { listenHandler => 187 | target.listen(listenHandler) 188 | } 189 | 190 | /** 191 | * Close the server supplying an handler that will be called when the server is actually closed (or has failed). 192 | * @param completionHandler the handler called on completion 193 | */ 194 | def closeL(): Task[Unit] = 195 | Task.handle[Void] { completionHandler => 196 | target.close(completionHandler) 197 | }.map(_ => ()) 198 | } 199 | 200 | 201 | } -------------------------------------------------------------------------------- /web/generated/vertices/web/package.scala: -------------------------------------------------------------------------------- 1 | package vertices 2 | 3 | 4 | import monix.eval.Task 5 | import io.vertx.core.AsyncResult 6 | import io.vertx.core.Handler 7 | import io.vertx.core.MultiMap 8 | import io.vertx.core.Vertx 9 | import io.vertx.core.buffer.Buffer 10 | import io.vertx.core.json.JsonObject 11 | import io.vertx.core.net.SocketAddress 12 | import io.vertx.core.streams.Pipe 13 | import io.vertx.core.streams.ReadStream 14 | import io.vertx.core.streams.WriteStream 15 | import io.vertx.ext.auth.AuthProvider 16 | import io.vertx.ext.auth.User 17 | import io.vertx.ext.auth.htdigest.HtdigestAuth 18 | import io.vertx.ext.auth.jwt.JWTAuth 19 | import io.vertx.ext.auth.oauth2.OAuth2Auth 20 | import io.vertx.ext.web.Route 21 | import io.vertx.ext.web.RoutingContext 22 | import io.vertx.ext.web.Session 23 | import io.vertx.ext.web.common.template.TemplateEngine 24 | import io.vertx.ext.web.handler.AuthHandler 25 | import io.vertx.ext.web.handler.BasicAuthHandler 26 | import io.vertx.ext.web.handler.ChainAuthHandler 27 | import io.vertx.ext.web.handler.DigestAuthHandler 28 | import io.vertx.ext.web.handler.JWTAuthHandler 29 | import io.vertx.ext.web.handler.OAuth2AuthHandler 30 | import io.vertx.ext.web.handler.RedirectAuthHandler 31 | import io.vertx.ext.web.handler.sockjs.SockJSSocket 32 | import io.vertx.ext.web.sstore.SessionStore 33 | import java.lang.Integer 34 | import java.lang.Object 35 | import java.lang.String 36 | import java.lang.Throwable 37 | import java.lang.Void 38 | import java.util.List 39 | import java.util.Map 40 | import java.util.Set 41 | 42 | package object web { 43 | implicit class VertxJWTAuthHandlerOps(val target: JWTAuthHandler) extends AnyVal { 44 | /** 45 | * Parses the credentials from the request into a JsonObject. The implementation should 46 | * be able to extract the required info for the auth provider in the format the provider 47 | * expects. 48 | * @param context the routing context 49 | * @param handler the handler to be called once the information is available. 50 | */ 51 | def parseCredentialsL(context: RoutingContext): Task[JsonObject] = 52 | Task.handle[JsonObject] { handler => 53 | target.parseCredentials(context, handler) 54 | } 55 | 56 | /** 57 | * Authorizes the given user against all added authorities. 58 | * @param user a user. 59 | * @param handler the handler for the result. 60 | */ 61 | def authorizeL(user: User): Task[Unit] = 62 | Task.handle[Void] { handler => 63 | target.authorize(user, handler) 64 | }.map(_ => ()) 65 | } 66 | 67 | 68 | implicit class VertxTemplateEngineOps(val target: TemplateEngine) extends AnyVal { 69 | /** 70 | * Render the template. Template engines that support partials/fragments should extract the template base path from 71 | * the template filename up to the last file separator. 72 | * 73 | * Some engines support localization, for these engines, there is a predefined key "lang" to specify the language to 74 | * be used in the localization, the format should follow the standard locale formats e.g.: "en-gb", "pt-br", "en". 75 | * @param context the routing context 76 | * @param templateFileName the template file name to use 77 | * @param handler the handler that will be called with a result containing the buffer or a failure. 78 | */ 79 | def renderL(context: JsonObject, templateFileName: String): Task[Buffer] = 80 | Task.handle[Buffer] { handler => 81 | target.render(context, templateFileName, handler) 82 | } 83 | } 84 | 85 | 86 | implicit class VertxDigestAuthHandlerOps(val target: DigestAuthHandler) extends AnyVal { 87 | /** 88 | * Parses the credentials from the request into a JsonObject. The implementation should 89 | * be able to extract the required info for the auth provider in the format the provider 90 | * expects. 91 | * @param context the routing context 92 | * @param handler the handler to be called once the information is available. 93 | */ 94 | def parseCredentialsL(context: RoutingContext): Task[JsonObject] = 95 | Task.handle[JsonObject] { handler => 96 | target.parseCredentials(context, handler) 97 | } 98 | 99 | /** 100 | * Authorizes the given user against all added authorities. 101 | * @param user a user. 102 | * @param handler the handler for the result. 103 | */ 104 | def authorizeL(user: User): Task[Unit] = 105 | Task.handle[Void] { handler => 106 | target.authorize(user, handler) 107 | }.map(_ => ()) 108 | } 109 | 110 | 111 | implicit class VertxSockJSSocketOps(val target: SockJSSocket) extends AnyVal { 112 | 113 | def endL(): Task[Unit] = 114 | Task.handle[Void] { arg0 => 115 | target.end(arg0) 116 | }.map(_ => ()) 117 | 118 | 119 | def endL(data: Buffer): Task[Unit] = 120 | Task.handle[Void] { handler => 121 | target.end(data, handler) 122 | }.map(_ => ()) 123 | 124 | 125 | def pipeToL(dst: WriteStream[Buffer]): Task[Unit] = 126 | Task.handle[Void] { handler => 127 | target.pipeTo(dst, handler) 128 | }.map(_ => ()) 129 | 130 | 131 | def writeL(data: Buffer): Task[Unit] = 132 | Task.handle[Void] { handler => 133 | target.write(data, handler) 134 | }.map(_ => ()) 135 | } 136 | 137 | 138 | implicit class VertxChainAuthHandlerOps(val target: ChainAuthHandler) extends AnyVal { 139 | /** 140 | * Parses the credentials from the request into a JsonObject. The implementation should 141 | * be able to extract the required info for the auth provider in the format the provider 142 | * expects. 143 | * @param context the routing context 144 | * @param handler the handler to be called once the information is available. 145 | */ 146 | def parseCredentialsL(context: RoutingContext): Task[JsonObject] = 147 | Task.handle[JsonObject] { handler => 148 | target.parseCredentials(context, handler) 149 | } 150 | 151 | /** 152 | * Authorizes the given user against all added authorities. 153 | * @param user a user. 154 | * @param handler the handler for the result. 155 | */ 156 | def authorizeL(user: User): Task[Unit] = 157 | Task.handle[Void] { handler => 158 | target.authorize(user, handler) 159 | }.map(_ => ()) 160 | } 161 | 162 | 163 | implicit class VertxOAuth2AuthHandlerOps(val target: OAuth2AuthHandler) extends AnyVal { 164 | /** 165 | * Parses the credentials from the request into a JsonObject. The implementation should 166 | * be able to extract the required info for the auth provider in the format the provider 167 | * expects. 168 | * @param context the routing context 169 | * @param handler the handler to be called once the information is available. 170 | */ 171 | def parseCredentialsL(context: RoutingContext): Task[JsonObject] = 172 | Task.handle[JsonObject] { handler => 173 | target.parseCredentials(context, handler) 174 | } 175 | 176 | /** 177 | * Authorizes the given user against all added authorities. 178 | * @param user a user. 179 | * @param handler the handler for the result. 180 | */ 181 | def authorizeL(user: User): Task[Unit] = 182 | Task.handle[Void] { handler => 183 | target.authorize(user, handler) 184 | }.map(_ => ()) 185 | } 186 | 187 | 188 | implicit class VertxBasicAuthHandlerOps(val target: BasicAuthHandler) extends AnyVal { 189 | /** 190 | * Parses the credentials from the request into a JsonObject. The implementation should 191 | * be able to extract the required info for the auth provider in the format the provider 192 | * expects. 193 | * @param context the routing context 194 | * @param handler the handler to be called once the information is available. 195 | */ 196 | def parseCredentialsL(context: RoutingContext): Task[JsonObject] = 197 | Task.handle[JsonObject] { handler => 198 | target.parseCredentials(context, handler) 199 | } 200 | 201 | /** 202 | * Authorizes the given user against all added authorities. 203 | * @param user a user. 204 | * @param handler the handler for the result. 205 | */ 206 | def authorizeL(user: User): Task[Unit] = 207 | Task.handle[Void] { handler => 208 | target.authorize(user, handler) 209 | }.map(_ => ()) 210 | } 211 | 212 | 213 | implicit class VertxSessionStoreOps(val target: SessionStore) extends AnyVal { 214 | /** 215 | * Get the session with the specified ID. 216 | * @param cookieValue the unique ID of the session 217 | * @param resultHandler will be called with a result holding the session, or a failure 218 | */ 219 | def getL(cookieValue: String): Task[Session] = 220 | Task.handle[Session] { resultHandler => 221 | target.get(cookieValue, resultHandler) 222 | } 223 | 224 | /** 225 | * Delete the session with the specified ID. 226 | * @param id the session id 227 | * @param resultHandler will be called with a success or a failure 228 | */ 229 | def deleteL(id: String): Task[Unit] = 230 | Task.handle[Void] { resultHandler => 231 | target.delete(id, resultHandler) 232 | }.map(_ => ()) 233 | 234 | /** 235 | * Add a session with the specified ID. 236 | * @param session the session 237 | * @param resultHandler will be called with a success or a failure 238 | */ 239 | def putL(session: Session): Task[Unit] = 240 | Task.handle[Void] { resultHandler => 241 | target.put(session, resultHandler) 242 | }.map(_ => ()) 243 | 244 | /** 245 | * Remove all sessions from the store. 246 | * @param resultHandler will be called with a success or a failure 247 | */ 248 | def clearL(): Task[Unit] = 249 | Task.handle[Void] { resultHandler => 250 | target.clear(resultHandler) 251 | }.map(_ => ()) 252 | 253 | /** 254 | * Get the number of sessions in the store. 255 | *

256 | * Beware of the result which is just an estimate, in particular with distributed session stores. 257 | * @param resultHandler will be called with the number, or a failure 258 | */ 259 | def sizeL(): Task[Int] = 260 | Task.handle[java.lang.Integer] { resultHandler => 261 | target.size(resultHandler) 262 | }.map(out => out: Int) 263 | } 264 | 265 | 266 | implicit class VertxRedirectAuthHandlerOps(val target: RedirectAuthHandler) extends AnyVal { 267 | /** 268 | * Parses the credentials from the request into a JsonObject. The implementation should 269 | * be able to extract the required info for the auth provider in the format the provider 270 | * expects. 271 | * @param context the routing context 272 | * @param handler the handler to be called once the information is available. 273 | */ 274 | def parseCredentialsL(context: RoutingContext): Task[JsonObject] = 275 | Task.handle[JsonObject] { handler => 276 | target.parseCredentials(context, handler) 277 | } 278 | 279 | /** 280 | * Authorizes the given user against all added authorities. 281 | * @param user a user. 282 | * @param handler the handler for the result. 283 | */ 284 | def authorizeL(user: User): Task[Unit] = 285 | Task.handle[Void] { handler => 286 | target.authorize(user, handler) 287 | }.map(_ => ()) 288 | } 289 | 290 | 291 | } -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | Apache License 2 | Version 2.0, January 2004 3 | http://www.apache.org/licenses/ 4 | 5 | TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION 6 | 7 | 1. Definitions. 8 | 9 | "License" shall mean the terms and conditions for use, reproduction, 10 | and distribution as defined by Sections 1 through 9 of this document. 11 | 12 | "Licensor" shall mean the copyright owner or entity authorized by 13 | the copyright owner that is granting the License. 14 | 15 | "Legal Entity" shall mean the union of the acting entity and all 16 | other entities that control, are controlled by, or are under common 17 | control with that entity. For the purposes of this definition, 18 | "control" means (i) the power, direct or indirect, to cause the 19 | direction or management of such entity, whether by contract or 20 | otherwise, or (ii) ownership of fifty percent (50%) or more of the 21 | outstanding shares, or (iii) beneficial ownership of such entity. 22 | 23 | "You" (or "Your") shall mean an individual or Legal Entity 24 | exercising permissions granted by this License. 25 | 26 | "Source" form shall mean the preferred form for making modifications, 27 | including but not limited to software source code, documentation 28 | source, and configuration files. 29 | 30 | "Object" form shall mean any form resulting from mechanical 31 | transformation or translation of a Source form, including but 32 | not limited to compiled object code, generated documentation, 33 | and conversions to other media types. 34 | 35 | "Work" shall mean the work of authorship, whether in Source or 36 | Object form, made available under the License, as indicated by a 37 | copyright notice that is included in or attached to the work 38 | (an example is provided in the Appendix below). 39 | 40 | "Derivative Works" shall mean any work, whether in Source or Object 41 | form, that is based on (or derived from) the Work and for which the 42 | editorial revisions, annotations, elaborations, or other modifications 43 | represent, as a whole, an original work of authorship. For the purposes 44 | of this License, Derivative Works shall not include works that remain 45 | separable from, or merely link (or bind by name) to the interfaces of, 46 | the Work and Derivative Works thereof. 47 | 48 | "Contribution" shall mean any work of authorship, including 49 | the original version of the Work and any modifications or additions 50 | to that Work or Derivative Works thereof, that is intentionally 51 | submitted to Licensor for inclusion in the Work by the copyright owner 52 | or by an individual or Legal Entity authorized to submit on behalf of 53 | the copyright owner. For the purposes of this definition, "submitted" 54 | means any form of electronic, verbal, or written communication sent 55 | to the Licensor or its representatives, including but not limited to 56 | communication on electronic mailing lists, source code control systems, 57 | and issue tracking systems that are managed by, or on behalf of, the 58 | Licensor for the purpose of discussing and improving the Work, but 59 | excluding communication that is conspicuously marked or otherwise 60 | designated in writing by the copyright owner as "Not a Contribution." 61 | 62 | "Contributor" shall mean Licensor and any individual or Legal Entity 63 | on behalf of whom a Contribution has been received by Licensor and 64 | subsequently incorporated within the Work. 65 | 66 | 2. Grant of Copyright License. Subject to the terms and conditions of 67 | this License, each Contributor hereby grants to You a perpetual, 68 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable 69 | copyright license to reproduce, prepare Derivative Works of, 70 | publicly display, publicly perform, sublicense, and distribute the 71 | Work and such Derivative Works in Source or Object form. 72 | 73 | 3. Grant of Patent License. Subject to the terms and conditions of 74 | this License, each Contributor hereby grants to You a perpetual, 75 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable 76 | (except as stated in this section) patent license to make, have made, 77 | use, offer to sell, sell, import, and otherwise transfer the Work, 78 | where such license applies only to those patent claims licensable 79 | by such Contributor that are necessarily infringed by their 80 | Contribution(s) alone or by combination of their Contribution(s) 81 | with the Work to which such Contribution(s) was submitted. If You 82 | institute patent litigation against any entity (including a 83 | cross-claim or counterclaim in a lawsuit) alleging that the Work 84 | or a Contribution incorporated within the Work constitutes direct 85 | or contributory patent infringement, then any patent licenses 86 | granted to You under this License for that Work shall terminate 87 | as of the date such litigation is filed. 88 | 89 | 4. Redistribution. You may reproduce and distribute copies of the 90 | Work or Derivative Works thereof in any medium, with or without 91 | modifications, and in Source or Object form, provided that You 92 | meet the following conditions: 93 | 94 | (a) You must give any other recipients of the Work or 95 | Derivative Works a copy of this License; and 96 | 97 | (b) You must cause any modified files to carry prominent notices 98 | stating that You changed the files; and 99 | 100 | (c) You must retain, in the Source form of any Derivative Works 101 | that You distribute, all copyright, patent, trademark, and 102 | attribution notices from the Source form of the Work, 103 | excluding those notices that do not pertain to any part of 104 | the Derivative Works; and 105 | 106 | (d) If the Work includes a "NOTICE" text file as part of its 107 | distribution, then any Derivative Works that You distribute must 108 | include a readable copy of the attribution notices contained 109 | within such NOTICE file, excluding those notices that do not 110 | pertain to any part of the Derivative Works, in at least one 111 | of the following places: within a NOTICE text file distributed 112 | as part of the Derivative Works; within the Source form or 113 | documentation, if provided along with the Derivative Works; or, 114 | within a display generated by the Derivative Works, if and 115 | wherever such third-party notices normally appear. The contents 116 | of the NOTICE file are for informational purposes only and 117 | do not modify the License. You may add Your own attribution 118 | notices within Derivative Works that You distribute, alongside 119 | or as an addendum to the NOTICE text from the Work, provided 120 | that such additional attribution notices cannot be construed 121 | as modifying the License. 122 | 123 | You may add Your own copyright statement to Your modifications and 124 | may provide additional or different license terms and conditions 125 | for use, reproduction, or distribution of Your modifications, or 126 | for any such Derivative Works as a whole, provided Your use, 127 | reproduction, and distribution of the Work otherwise complies with 128 | the conditions stated in this License. 129 | 130 | 5. Submission of Contributions. Unless You explicitly state otherwise, 131 | any Contribution intentionally submitted for inclusion in the Work 132 | by You to the Licensor shall be under the terms and conditions of 133 | this License, without any additional terms or conditions. 134 | Notwithstanding the above, nothing herein shall supersede or modify 135 | the terms of any separate license agreement you may have executed 136 | with Licensor regarding such Contributions. 137 | 138 | 6. Trademarks. This License does not grant permission to use the trade 139 | names, trademarks, service marks, or product names of the Licensor, 140 | except as required for reasonable and customary use in describing the 141 | origin of the Work and reproducing the content of the NOTICE file. 142 | 143 | 7. Disclaimer of Warranty. Unless required by applicable law or 144 | agreed to in writing, Licensor provides the Work (and each 145 | Contributor provides its Contributions) on an "AS IS" BASIS, 146 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or 147 | implied, including, without limitation, any warranties or conditions 148 | of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A 149 | PARTICULAR PURPOSE. You are solely responsible for determining the 150 | appropriateness of using or redistributing the Work and assume any 151 | risks associated with Your exercise of permissions under this License. 152 | 153 | 8. Limitation of Liability. In no event and under no legal theory, 154 | whether in tort (including negligence), contract, or otherwise, 155 | unless required by applicable law (such as deliberate and grossly 156 | negligent acts) or agreed to in writing, shall any Contributor be 157 | liable to You for damages, including any direct, indirect, special, 158 | incidental, or consequential damages of any character arising as a 159 | result of this License or out of the use or inability to use the 160 | Work (including but not limited to damages for loss of goodwill, 161 | work stoppage, computer failure or malfunction, or any and all 162 | other commercial damages or losses), even if such Contributor 163 | has been advised of the possibility of such damages. 164 | 165 | 9. Accepting Warranty or Additional Liability. While redistributing 166 | the Work or Derivative Works thereof, You may choose to offer, 167 | and charge a fee for, acceptance of support, warranty, indemnity, 168 | or other liability obligations and/or rights consistent with this 169 | License. However, in accepting such obligations, You may act only 170 | on Your own behalf and on Your sole responsibility, not on behalf 171 | of any other Contributor, and only if You agree to indemnify, 172 | defend, and hold each Contributor harmless for any liability 173 | incurred by, or claims asserted against, such Contributor by reason 174 | of your accepting any such warranty or additional liability. 175 | 176 | END OF TERMS AND CONDITIONS 177 | 178 | APPENDIX: How to apply the Apache License to your work. 179 | 180 | To apply the Apache License to your work, attach the following 181 | boilerplate notice, with the fields enclosed by brackets "{}" 182 | replaced with your own identifying information. (Don't include 183 | the brackets!) The text should be enclosed in the appropriate 184 | comment syntax for the file format. We also recommend that a 185 | file or class name and description of purpose be included on the 186 | same "printed page" as the copyright notice for easier 187 | identification within third-party archives. 188 | 189 | Copyright {yyyy} {name of copyright owner} 190 | 191 | Licensed under the Apache License, Version 2.0 (the "License"); 192 | you may not use this file except in compliance with the License. 193 | You may obtain a copy of the License at 194 | 195 | http://www.apache.org/licenses/LICENSE-2.0 196 | 197 | Unless required by applicable law or agreed to in writing, software 198 | distributed under the License is distributed on an "AS IS" BASIS, 199 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 200 | See the License for the specific language governing permissions and 201 | limitations under the License. 202 | -------------------------------------------------------------------------------- /core/tut/README.md: -------------------------------------------------------------------------------- 1 | ## Vertices 2 | 3 | [![Build Status](https://api.travis-ci.org/DavidGregory084/vertices.svg)](https://travis-ci.org/DavidGregory084/vertices) 4 | [![License](https://img.shields.io/github/license/DavidGregory084/vertices.svg)](https://opensource.org/licenses/Apache-2.0) 5 | [![javadoc](https://javadoc.io/badge2/io.github.davidgregory084/vertices-core_2.13/javadoc.svg)](https://javadoc.io/doc/io.github.davidgregory084/vertices-core_2.13) 6 | 7 | ### Overview 8 | 9 | Vertices is a Scala library that provides extension methods for the [Eclipse Vert.x](http://vertx.io/) APIs. 10 | 11 | The basic idea of this library is to provide replacements for Vert.x methods which accept callbacks. This makes it easier to use the diverse functionality provided by the Vert.x libraries while writing idiomatic Scala code. 12 | 13 | The new methods make use of the [Task](https://monix.io/api/3.1/monix/eval/Task.html) type from the excellent [Monix](https://monix.io) library. 14 | 15 | ### Example 16 | 17 | The Vert.x library provides a [SharedData](https://vertx.io/docs/apidocs/io/vertx/core/shareddata/SharedData.html) object which we can use to store and retrieve named [AsyncMap](https://vertx.io/docs/apidocs/io/vertx/core/shareddata/AsyncMap.html) objects. 18 | 19 | Using the original Vert.x APIs we would write code to access this data like so: 20 | 21 | ```tut:silent 22 | import io.vertx.core._ 23 | import scala.concurrent.{ Await, Promise } 24 | import scala.concurrent.duration._ 25 | ``` 26 | ```tut:book 27 | val vertx = Vertx.vertx 28 | val resultPromise = Promise[String]() 29 | val sharedData = vertx.sharedData 30 | 31 | sharedData.getAsyncMap[String, String]("example", getMapResult => { 32 | if (getMapResult.succeeded) { 33 | val asyncMap = getMapResult.result 34 | asyncMap.put("key", "value", putResult => { 35 | if (putResult.succeeded) { 36 | asyncMap.get("key", getResult => { 37 | if (getResult.succeeded) { 38 | resultPromise.success(getResult.result) 39 | } else { 40 | resultPromise.failure(getResult.cause) 41 | } 42 | }) 43 | } else { 44 | resultPromise.failure(putResult.cause) 45 | } 46 | }) 47 | } else { 48 | resultPromise.failure(getMapResult.cause) 49 | } 50 | }) 51 | 52 | Await.result(resultPromise.future, 20.seconds) 53 | ``` 54 | 55 | As you can see this is a perfect demonstration of "callback hell". 56 | 57 | Using this library we can write the code above as follows: 58 | 59 | ```tut:silent 60 | import monix.execution.Scheduler 61 | import vertices._ 62 | import vertices.core._ 63 | ``` 64 | ```tut:book 65 | implicit val scheduler: Scheduler = new VertxScheduler(vertx) 66 | 67 | val resultTask = for { 68 | asyncMap <- sharedData.getAsyncMapL[String, String]("example") 69 | _ <- asyncMap.putL("key", "value") 70 | value <- asyncMap.getL("key") 71 | } yield value 72 | 73 | Await.result(resultTask.runToFuture, 20.seconds) 74 | ``` 75 | 76 | We can also convert Vert.x [ReadStream](https://vertx.io/docs/apidocs/io/vertx/core/streams/ReadStream.html) objects to Monix [Observable](https://monix.io/api/3.1/monix/reactive/Observable.html)s. 77 | 78 | The example below uses the Vert.x Event Bus to define an event bus consumer that echoes messages back to the sender in all-caps: 79 | 80 | ```tut:book 81 | import cats.syntax.apply._ 82 | 83 | val messageStream = vertx.eventBus.consumer[String]("echo") 84 | 85 | val echoMessagesExuberantly = for { 86 | messageObservable <- messageStream.toObservable(vertx) 87 | _ <- messageObservable.foreachL(msg => msg.reply(msg.body.toUpperCase)) 88 | } yield () 89 | 90 | echoMessagesExuberantly.runToFuture 91 | 92 | val sendAMessage = vertx.eventBus. 93 | requestL[String]("echo", "hello"). 94 | foreachL(msg => println(msg.body)) 95 | 96 | val demoTask = 97 | sendAMessage *> vertx.closeL 98 | 99 | Await.result(demoTask.runToFuture(Scheduler.global), 20.seconds) 100 | ``` 101 | 102 | ### Usage 103 | 104 | The library is published for Scala 2.12 and 2.13. 105 | 106 | The artifact names resemble those of the original Vert.x artifacts. 107 | 108 | They are listed below using the categories defined in the [Vert.x Documentation](https://vertx.io/docs/). 109 | 110 | SBT dependency coordinates: 111 | 112 | ```scala 113 | val verticesVersion = "0.1.2" 114 | 115 | // Vert.x core 116 | "io.github.davidgregory084" %% "vertices-core" % verticesVersion 117 | // Vert.x web 118 | "io.github.davidgregory084" %% "vertices-web" % verticesVersion 119 | "io.github.davidgregory084" %% "vertices-web-client" % verticesVersion 120 | "io.github.davidgregory084" %% "vertices-web-api-contract" % verticesVersion 121 | // Data access 122 | "io.github.davidgregory084" %% "vertices-mongo-client" % verticesVersion 123 | "io.github.davidgregory084" %% "vertices-redis-client" % verticesVersion 124 | "io.github.davidgregory084" %% "vertices-cassandra-client" % verticesVersion 125 | "io.github.davidgregory084" %% "vertices-sql-common" % verticesVersion 126 | "io.github.davidgregory084" %% "vertices-jdbc-client" % verticesVersion 127 | // Microservices 128 | "io.github.davidgregory084" %% "vertices-service-discovery" % verticesVersion 129 | "io.github.davidgregory084" %% "vertices-circuit-breaker" % verticesVersion 130 | "io.github.davidgregory084" %% "vertices-config" % verticesVersion 131 | // MQTT 132 | "io.github.davidgregory084" %% "vertices-mqtt" % verticesVersion 133 | // Authentication and Authorisation 134 | "io.github.davidgregory084" %% "vertices-auth-common" % verticesVersion 135 | "io.github.davidgregory084" %% "vertices-auth-oauth2" % verticesVersion 136 | "io.github.davidgregory084" %% "vertices-auth-mongo" % verticesVersion 137 | // Messaging 138 | "io.github.davidgregory084" %% "vertices-stomp" % verticesVersion 139 | "io.github.davidgregory084" %% "vertices-rabbitmq-client" % verticesVersion 140 | "io.github.davidgregory084" %% "vertices-amqp-bridge" % verticesVersion 141 | // Integration 142 | "io.github.davidgregory084" %% "vertices-kafka-client" % verticesVersion 143 | "io.github.davidgregory084" %% "vertices-mail-client" % verticesVersion 144 | "io.github.davidgregory084" %% "vertices-consul-client" % verticesVersion 145 | // Event Bus Bridge 146 | "io.github.davidgregory084" %% "vertices-tcp-eventbus-bridge" % verticesVersion 147 | // Devops 148 | "io.github.davidgregory084" %% "vertices-health-check" % verticesVersion 149 | ``` 150 | 151 | Mill dependency coordinates: 152 | 153 | ```scala 154 | def verticesVersion = T { "0.1.2" } 155 | 156 | // Vert.x core 157 | ivy"io.github.davidgregory084::vertices-core:${verticesVersion()}" 158 | // Vert.x web 159 | ivy"io.github.davidgregory084::vertices-web:${verticesVersion()}" 160 | ivy"io.github.davidgregory084::vertices-web-client:${verticesVersion()}" 161 | ivy"io.github.davidgregory084::vertices-web-api-contract:${verticesVersion()}" 162 | // Data access 163 | ivy"io.github.davidgregory084::vertices-mongo-client:${verticesVersion()}" 164 | ivy"io.github.davidgregory084::vertices-redis-client:${verticesVersion()}" 165 | ivy"io.github.davidgregory084::vertices-cassandra-client:${verticesVersion()}" 166 | ivy"io.github.davidgregory084::vertices-sql-common:${verticesVersion()}" 167 | ivy"io.github.davidgregory084::vertices-jdbc-client:${verticesVersion()}" 168 | // Microservices 169 | ivy"io.github.davidgregory084::vertices-service-discovery:${verticesVersion()}" 170 | ivy"io.github.davidgregory084::vertices-circuit-breaker:${verticesVersion()}" 171 | ivy"io.github.davidgregory084::vertices-config:${verticesVersion()}" 172 | // MQTT 173 | ivy"io.github.davidgregory084::vertices-mqtt:${verticesVersion()}" 174 | // Authentication and Authorisation 175 | ivy"io.github.davidgregory084::vertices-auth-common:${verticesVersion()}" 176 | ivy"io.github.davidgregory084::vertices-auth-oauth2:${verticesVersion()}" 177 | ivy"io.github.davidgregory084::vertices-auth-mongo:${verticesVersion()}" 178 | // Messaging 179 | ivy"io.github.davidgregory084::vertices-stomp:${verticesVersion()}" 180 | ivy"io.github.davidgregory084::vertices-rabbitmq-client:${verticesVersion()}" 181 | ivy"io.github.davidgregory084::vertices-amqp-bridge:${verticesVersion()}" 182 | // Integration 183 | ivy"io.github.davidgregory084::vertices-kafka-client:${verticesVersion()}" 184 | ivy"io.github.davidgregory084::vertices-mail-client:${verticesVersion()}" 185 | ivy"io.github.davidgregory084::vertices-consul-client:${verticesVersion()}" 186 | // Event Bus Bridge 187 | ivy"io.github.davidgregory084::vertices-tcp-eventbus-bridge:${verticesVersion()}" 188 | // Devops 189 | ivy"io.github.davidgregory084::vertices-health-check:${verticesVersion()}" 190 | ``` 191 | ### Cheat Sheet 192 | 193 | The naming strategy for extension methods follows that of [Monix](https://monix.io): the new methods which return [Task](https://monix.io/api/3.1/monix/eval/Task.html) are suffixed with the letter `L` since the underlying task is not executed right away (in other words that it is "lazy"). 194 | 195 | ```scala 196 | // Instead of the io.vertx.core.file.AsyncFile method 197 | def write(data: Buffer, handler: Handler[AsyncResult[Void]]): AsyncFile 198 | // We can use this extension method from vertices.core 199 | def writeL(data: Buffer): Task[Unit] 200 | 201 | // Instead of the io.vertx.core.dns.DnsClient method 202 | def resolveMX(name: String, handler: Handler[AsyncResult[List[MxRecord]]]): DnsClient 203 | // We can use this extension method from vertices.core 204 | def resolveMXL(name: String): Task[List[MxRecord]] 205 | ``` 206 | 207 | Since it's not possible to decorate a Java class with new static methods, replacements for static methods reside within a companion object named after the original class with `Functions` appended to the end. For example, `io.vertx.core.Vertx.clusteredVertx` has a matching `vertices.core.VertxFunctions.clusteredVertxL` function. 208 | 209 | ```scala 210 | // Instead of the io.vertx.ext.auth.oauth2.providers.GoogleAuth static method 211 | def create(vertx: Vertx, url: String, handler: Handler[AsyncResult[OAuth2Auth]]): Unit 212 | // We can use this function from vertices.auth.GoogleAuthFunctions 213 | def createL(vertx: Vertx, url: String): Task[OAuth2Auth] 214 | ``` 215 | 216 | ### Import Guide 217 | 218 | Extension methods are made available by importing from the package corresponding to each module. The package names are selected to resemble those used by the original APIs. 219 | 220 | ```scala 221 | // Vert.x core 222 | import vertices.core._ 223 | // Vert.x web modules 224 | import vertices.web._ 225 | import vertices.web.client._ 226 | import vertices.web.api.contract._ 227 | // Vert.x data access 228 | import vertices.mongo._ 229 | import vertices.redis.client._ 230 | import vertices.cassandra._ 231 | import vertices.sql._ 232 | import vertices.jdbc._ 233 | // Vert.x microservices 234 | import vertices.servicediscovery._ 235 | import vertices.circuitbreaker._ 236 | import vertices.config._ 237 | // Vert.x MQTT 238 | import vertices.mqtt._ 239 | // Vert.x authentication and authorisation 240 | import vertices.auth._ 241 | import vertices.auth.oauth2._ 242 | import vertices.auth.mongo._ 243 | // Vert.x messaging 244 | import vertices.stomp._ 245 | import vertices.rabbitmq._ 246 | import vertices.amqpbridge._ 247 | // Vert.x integration 248 | import vertices.kafka.client._ 249 | import vertices.mail._ 250 | import vertices.consul._ 251 | // Vert.x event bus bridge 252 | import vertices.eventbus.bridge.tcp._ 253 | // Vert.x devops 254 | import vertices.healthchecks._ 255 | ``` 256 | 257 | The root package `vertices` also provides some useful extension methods and type class instances for Vert.x types. 258 | 259 | ### FAQ 260 | 261 | Q. Why is `` missing? 262 | 263 | A. The stable modules that have `Handler` operations have been added. If there are new modules that you need please raise a PR. 264 | 265 | Q. Why is `` missing from the generated code? 266 | 267 | A. The Vert.x code generation process relies on annotations in the original Java code. Sometimes these annotations are missing for `Handler` methods that could be wrapped by *vertices*. The solution is to raise a PR against the corresponding Vert.x project to add the annotations ([see example](https://github.com/eclipse-vertx/vert.x/pull/2573)). 268 | 269 | ### Conduct 270 | 271 | Contributors are expected to follow the [Scala Code of Conduct](https://www.scala-lang.org/conduct/) while participating on Github and any other venues associated with the project. 272 | 273 | ### Acknowledgements 274 | 275 | Thanks are due to Alexandru Nedelcu ([@alexandru](https://github.com/alexandru)) for the [Monix](https://github.com/monix/monix) library, which makes writing asynchronous code in Scala an absolute pleasure. 276 | 277 | ### License 278 | 279 | All code in this repository is licensed under the Apache License, Version 2.0. See [LICENSE](./LICENSE). 280 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | ## Vertices 2 | 3 | [![Build Status](https://api.travis-ci.org/DavidGregory084/vertices.svg)](https://travis-ci.org/DavidGregory084/vertices) 4 | [![License](https://img.shields.io/github/license/DavidGregory084/vertices.svg)](https://opensource.org/licenses/Apache-2.0) 5 | [![javadoc](https://javadoc.io/badge2/io.github.davidgregory084/vertices-core_2.13/javadoc.svg)](https://javadoc.io/doc/io.github.davidgregory084/vertices-core_2.13) 6 | 7 | ### Overview 8 | 9 | Vertices is a Scala library that provides extension methods for the [Eclipse Vert.x](http://vertx.io/) APIs. 10 | 11 | The basic idea of this library is to provide replacements for Vert.x methods which accept callbacks. This makes it easier to use the diverse functionality provided by the Vert.x libraries while writing idiomatic Scala code. 12 | 13 | The new methods make use of the [Task](https://monix.io/api/3.1/monix/eval/Task.html) type from the excellent [Monix](https://monix.io) library. 14 | 15 | ### Example 16 | 17 | The Vert.x library provides a [SharedData](https://vertx.io/docs/apidocs/io/vertx/core/shareddata/SharedData.html) object which we can use to store and retrieve named [AsyncMap](https://vertx.io/docs/apidocs/io/vertx/core/shareddata/AsyncMap.html) objects. 18 | 19 | Using the original Vert.x APIs we would write code to access this data like so: 20 | 21 | ```scala 22 | import io.vertx.core._ 23 | import scala.concurrent.{ Await, Promise } 24 | import scala.concurrent.duration._ 25 | ``` 26 | ```scala 27 | val vertx = Vertx.vertx 28 | // vertx: io.vertx.core.Vertx = io.vertx.core.impl.VertxImpl@69ffdaa8 29 | 30 | val resultPromise = Promise[String]() 31 | // resultPromise: scala.concurrent.Promise[String] = Future() 32 | 33 | val sharedData = vertx.sharedData 34 | // sharedData: io.vertx.core.shareddata.SharedData = io.vertx.core.shareddata.impl.SharedDataImpl@70439c3 35 | 36 | sharedData.getAsyncMap[String, String]("example", getMapResult => { 37 | if (getMapResult.succeeded) { 38 | val asyncMap = getMapResult.result 39 | asyncMap.put("key", "value", putResult => { 40 | if (putResult.succeeded) { 41 | asyncMap.get("key", getResult => { 42 | if (getResult.succeeded) { 43 | resultPromise.success(getResult.result) 44 | } else { 45 | resultPromise.failure(getResult.cause) 46 | } 47 | }) 48 | } else { 49 | resultPromise.failure(putResult.cause) 50 | } 51 | }) 52 | } else { 53 | resultPromise.failure(getMapResult.cause) 54 | } 55 | }) 56 | 57 | Await.result(resultPromise.future, 20.seconds) 58 | // res1: String = value 59 | ``` 60 | 61 | As you can see this is a perfect demonstration of "callback hell". 62 | 63 | Using this library we can write the code above as follows: 64 | 65 | ```scala 66 | import monix.execution.Scheduler 67 | import vertices._ 68 | import vertices.core._ 69 | ``` 70 | ```scala 71 | implicit val scheduler: Scheduler = new VertxScheduler(vertx) 72 | // scheduler: monix.execution.Scheduler = vertices.core.VertxScheduler@4131f6db 73 | 74 | val resultTask = for { 75 | asyncMap <- sharedData.getAsyncMapL[String, String]("example") 76 | _ <- asyncMap.putL("key", "value") 77 | value <- asyncMap.getL("key") 78 | } yield value 79 | // resultTask: monix.eval.Task[String] = Task.FlatMap$482031947 80 | 81 | Await.result(resultTask.runToFuture, 20.seconds) 82 | // res2: String = value 83 | ``` 84 | 85 | We can also convert Vert.x [ReadStream](https://vertx.io/docs/apidocs/io/vertx/core/streams/ReadStream.html) objects to Monix [Observable](https://monix.io/api/3.1/monix/reactive/Observable.html)s. 86 | 87 | The example below uses the Vert.x Event Bus to define an event bus consumer that echoes messages back to the sender in all-caps: 88 | 89 | ```scala 90 | import cats.syntax.apply._ 91 | // import cats.syntax.apply._ 92 | 93 | val messageStream = vertx.eventBus.consumer[String]("echo") 94 | // messageStream: io.vertx.core.eventbus.MessageConsumer[String] = io.vertx.core.eventbus.impl.HandlerRegistration@32107bba 95 | 96 | val echoMessagesExuberantly = for { 97 | messageObservable <- messageStream.toObservable(vertx) 98 | _ <- messageObservable.foreachL(msg => msg.reply(msg.body.toUpperCase)) 99 | } yield () 100 | // echoMessagesExuberantly: monix.eval.Task[Unit] = Task.FlatMap$936177086 101 | 102 | echoMessagesExuberantly.runToFuture 103 | // res3: monix.execution.CancelableFuture[Unit] = Async(Future(),monix.eval.internal.TaskConnection$Impl$$anon$1@2b009051) 104 | 105 | val sendAMessage = vertx.eventBus. 106 | requestL[String]("echo", "hello"). 107 | foreachL(msg => println(msg.body)) 108 | // sendAMessage: monix.eval.Task[Unit] = Task.Map$368375378 109 | 110 | val demoTask = 111 | sendAMessage *> vertx.closeL 112 | // demoTask: monix.eval.Task[Unit] = Task.FlatMap$543433178 113 | 114 | Await.result(demoTask.runToFuture(Scheduler.global), 20.seconds) 115 | // HELLO 116 | ``` 117 | 118 | ### Usage 119 | 120 | The library is published for Scala 2.12 and 2.13. 121 | 122 | The artifact names resemble those of the original Vert.x artifacts. 123 | 124 | They are listed below using the categories defined in the [Vert.x Documentation](https://vertx.io/docs/). 125 | 126 | SBT dependency coordinates: 127 | 128 | ```scala 129 | val verticesVersion = "0.1.2" 130 | 131 | // Vert.x core 132 | "io.github.davidgregory084" %% "vertices-core" % verticesVersion 133 | // Vert.x web 134 | "io.github.davidgregory084" %% "vertices-web" % verticesVersion 135 | "io.github.davidgregory084" %% "vertices-web-client" % verticesVersion 136 | "io.github.davidgregory084" %% "vertices-web-api-contract" % verticesVersion 137 | // Data access 138 | "io.github.davidgregory084" %% "vertices-mongo-client" % verticesVersion 139 | "io.github.davidgregory084" %% "vertices-redis-client" % verticesVersion 140 | "io.github.davidgregory084" %% "vertices-cassandra-client" % verticesVersion 141 | "io.github.davidgregory084" %% "vertices-sql-common" % verticesVersion 142 | "io.github.davidgregory084" %% "vertices-jdbc-client" % verticesVersion 143 | // Microservices 144 | "io.github.davidgregory084" %% "vertices-service-discovery" % verticesVersion 145 | "io.github.davidgregory084" %% "vertices-circuit-breaker" % verticesVersion 146 | "io.github.davidgregory084" %% "vertices-config" % verticesVersion 147 | // MQTT 148 | "io.github.davidgregory084" %% "vertices-mqtt" % verticesVersion 149 | // Authentication and Authorisation 150 | "io.github.davidgregory084" %% "vertices-auth-common" % verticesVersion 151 | "io.github.davidgregory084" %% "vertices-auth-oauth2" % verticesVersion 152 | "io.github.davidgregory084" %% "vertices-auth-mongo" % verticesVersion 153 | // Messaging 154 | "io.github.davidgregory084" %% "vertices-stomp" % verticesVersion 155 | "io.github.davidgregory084" %% "vertices-rabbitmq-client" % verticesVersion 156 | "io.github.davidgregory084" %% "vertices-amqp-bridge" % verticesVersion 157 | // Integration 158 | "io.github.davidgregory084" %% "vertices-kafka-client" % verticesVersion 159 | "io.github.davidgregory084" %% "vertices-mail-client" % verticesVersion 160 | "io.github.davidgregory084" %% "vertices-consul-client" % verticesVersion 161 | // Event Bus Bridge 162 | "io.github.davidgregory084" %% "vertices-tcp-eventbus-bridge" % verticesVersion 163 | // Devops 164 | "io.github.davidgregory084" %% "vertices-health-check" % verticesVersion 165 | ``` 166 | 167 | Mill dependency coordinates: 168 | 169 | ```scala 170 | def verticesVersion = T { "0.1.2" } 171 | 172 | // Vert.x core 173 | ivy"io.github.davidgregory084::vertices-core:${verticesVersion()}" 174 | // Vert.x web 175 | ivy"io.github.davidgregory084::vertices-web:${verticesVersion()}" 176 | ivy"io.github.davidgregory084::vertices-web-client:${verticesVersion()}" 177 | ivy"io.github.davidgregory084::vertices-web-api-contract:${verticesVersion()}" 178 | // Data access 179 | ivy"io.github.davidgregory084::vertices-mongo-client:${verticesVersion()}" 180 | ivy"io.github.davidgregory084::vertices-redis-client:${verticesVersion()}" 181 | ivy"io.github.davidgregory084::vertices-cassandra-client:${verticesVersion()}" 182 | ivy"io.github.davidgregory084::vertices-sql-common:${verticesVersion()}" 183 | ivy"io.github.davidgregory084::vertices-jdbc-client:${verticesVersion()}" 184 | // Microservices 185 | ivy"io.github.davidgregory084::vertices-service-discovery:${verticesVersion()}" 186 | ivy"io.github.davidgregory084::vertices-circuit-breaker:${verticesVersion()}" 187 | ivy"io.github.davidgregory084::vertices-config:${verticesVersion()}" 188 | // MQTT 189 | ivy"io.github.davidgregory084::vertices-mqtt:${verticesVersion()}" 190 | // Authentication and Authorisation 191 | ivy"io.github.davidgregory084::vertices-auth-common:${verticesVersion()}" 192 | ivy"io.github.davidgregory084::vertices-auth-oauth2:${verticesVersion()}" 193 | ivy"io.github.davidgregory084::vertices-auth-mongo:${verticesVersion()}" 194 | // Messaging 195 | ivy"io.github.davidgregory084::vertices-stomp:${verticesVersion()}" 196 | ivy"io.github.davidgregory084::vertices-rabbitmq-client:${verticesVersion()}" 197 | ivy"io.github.davidgregory084::vertices-amqp-bridge:${verticesVersion()}" 198 | // Integration 199 | ivy"io.github.davidgregory084::vertices-kafka-client:${verticesVersion()}" 200 | ivy"io.github.davidgregory084::vertices-mail-client:${verticesVersion()}" 201 | ivy"io.github.davidgregory084::vertices-consul-client:${verticesVersion()}" 202 | // Event Bus Bridge 203 | ivy"io.github.davidgregory084::vertices-tcp-eventbus-bridge:${verticesVersion()}" 204 | // Devops 205 | ivy"io.github.davidgregory084::vertices-health-check:${verticesVersion()}" 206 | ``` 207 | ### Cheat Sheet 208 | 209 | The naming strategy for extension methods follows that of [Monix](https://monix.io): the new methods which return [Task](https://monix.io/api/3.1/monix/eval/Task.html) are suffixed with the letter `L` since the underlying task is not executed right away (in other words that it is "lazy"). 210 | 211 | ```scala 212 | // Instead of the io.vertx.core.file.AsyncFile method 213 | def write(data: Buffer, handler: Handler[AsyncResult[Void]]): AsyncFile 214 | // We can use this extension method from vertices.core 215 | def writeL(data: Buffer): Task[Unit] 216 | 217 | // Instead of the io.vertx.core.dns.DnsClient method 218 | def resolveMX(name: String, handler: Handler[AsyncResult[List[MxRecord]]]): DnsClient 219 | // We can use this extension method from vertices.core 220 | def resolveMXL(name: String): Task[List[MxRecord]] 221 | ``` 222 | 223 | Since it's not possible to decorate a Java class with new static methods, replacements for static methods reside within a companion object named after the original class with `Functions` appended to the end. For example, `io.vertx.core.Vertx.clusteredVertx` has a matching `vertices.core.VertxFunctions.clusteredVertxL` function. 224 | 225 | ```scala 226 | // Instead of the io.vertx.ext.auth.oauth2.providers.GoogleAuth static method 227 | def create(vertx: Vertx, url: String, handler: Handler[AsyncResult[OAuth2Auth]]): Unit 228 | // We can use this function from vertices.auth.GoogleAuthFunctions 229 | def createL(vertx: Vertx, url: String): Task[OAuth2Auth] 230 | ``` 231 | 232 | ### Import Guide 233 | 234 | Extension methods are made available by importing from the package corresponding to each module. The package names are selected to resemble those used by the original APIs. 235 | 236 | ```scala 237 | // Vert.x core 238 | import vertices.core._ 239 | // Vert.x web modules 240 | import vertices.web._ 241 | import vertices.web.client._ 242 | import vertices.web.api.contract._ 243 | // Vert.x data access 244 | import vertices.mongo._ 245 | import vertices.redis.client._ 246 | import vertices.cassandra._ 247 | import vertices.sql._ 248 | import vertices.jdbc._ 249 | // Vert.x microservices 250 | import vertices.servicediscovery._ 251 | import vertices.circuitbreaker._ 252 | import vertices.config._ 253 | // Vert.x MQTT 254 | import vertices.mqtt._ 255 | // Vert.x authentication and authorisation 256 | import vertices.auth._ 257 | import vertices.auth.oauth2._ 258 | import vertices.auth.mongo._ 259 | // Vert.x messaging 260 | import vertices.stomp._ 261 | import vertices.rabbitmq._ 262 | import vertices.amqpbridge._ 263 | // Vert.x integration 264 | import vertices.kafka.client._ 265 | import vertices.mail._ 266 | import vertices.consul._ 267 | // Vert.x event bus bridge 268 | import vertices.eventbus.bridge.tcp._ 269 | // Vert.x devops 270 | import vertices.healthchecks._ 271 | ``` 272 | 273 | The root package `vertices` also provides some useful extension methods and type class instances for Vert.x types. 274 | 275 | ### FAQ 276 | 277 | Q. Why is `` missing? 278 | 279 | A. The stable modules that have `Handler` operations have been added. If there are new modules that you need please raise a PR. 280 | 281 | Q. Why is `` missing from the generated code? 282 | 283 | A. The Vert.x code generation process relies on annotations in the original Java code. Sometimes these annotations are missing for `Handler` methods that could be wrapped by *vertices*. The solution is to raise a PR against the corresponding Vert.x project to add the annotations ([see example](https://github.com/eclipse-vertx/vert.x/pull/2573)). 284 | 285 | ### Conduct 286 | 287 | Contributors are expected to follow the [Scala Code of Conduct](https://www.scala-lang.org/conduct/) while participating on Github and any other venues associated with the project. 288 | 289 | ### Acknowledgements 290 | 291 | Thanks are due to Alexandru Nedelcu ([@alexandru](https://github.com/alexandru)) for the [Monix](https://github.com/monix/monix) library, which makes writing asynchronous code in Scala an absolute pleasure. 292 | 293 | ### License 294 | 295 | All code in this repository is licensed under the Apache License, Version 2.0. See [LICENSE](./LICENSE). 296 | -------------------------------------------------------------------------------- /rabbitmq/generated/vertices/rabbitmq/package.scala: -------------------------------------------------------------------------------- 1 | package vertices 2 | 3 | 4 | import monix.eval.Task 5 | import io.vertx.core.AsyncResult 6 | import io.vertx.core.Handler 7 | import io.vertx.core.Vertx 8 | import io.vertx.core.json.JsonObject 9 | import io.vertx.core.streams.Pipe 10 | import io.vertx.core.streams.ReadStream 11 | import io.vertx.core.streams.WriteStream 12 | import io.vertx.rabbitmq.QueueOptions 13 | import io.vertx.rabbitmq.RabbitMQClient 14 | import io.vertx.rabbitmq.RabbitMQConsumer 15 | import io.vertx.rabbitmq.RabbitMQMessage 16 | import io.vertx.rabbitmq.RabbitMQOptions 17 | import java.lang.Long 18 | import java.lang.String 19 | import java.lang.Throwable 20 | import java.lang.Void 21 | 22 | package object rabbitmq { 23 | implicit class VertxRabbitMQClientOps(val target: RabbitMQClient) extends AnyVal { 24 | /** 25 | * Acknowledge one or several received messages. Supply the deliveryTag from the AMQP.Basic.GetOk or AMQP.Basic.Deliver 26 | * method containing the received message being acknowledged. 27 | * @see com.rabbitmq.client.Channel#basicAck(long, boolean) 28 | */ 29 | def basicAckL(deliveryTag: Long, multiple: Boolean): Task[JsonObject] = 30 | Task.handle[JsonObject] { resultHandler => 31 | target.basicAck(deliveryTag, multiple, resultHandler) 32 | } 33 | 34 | /** 35 | * Reject one or several received messages. 36 | * @see com.rabbitmq.client.Channel#basicNack(long, boolean, boolean) 37 | */ 38 | def basicNackL(deliveryTag: Long, multiple: Boolean, requeue: Boolean): Task[JsonObject] = 39 | Task.handle[JsonObject] { resultHandler => 40 | target.basicNack(deliveryTag, multiple, requeue, resultHandler) 41 | } 42 | 43 | /** 44 | * Retrieve a message from a queue using AMQP.Basic.Get 45 | * @see com.rabbitmq.client.Channel#basicGet(String, boolean) 46 | */ 47 | def basicGetL(queue: String, autoAck: Boolean): Task[JsonObject] = 48 | Task.handle[JsonObject] { resultHandler => 49 | target.basicGet(queue, autoAck, resultHandler) 50 | } 51 | 52 | /** 53 | * 54 | * @see com.rabbitmq.client.Channel#basicConsume(String, Consumer) 55 | * @see RabbitMQClient#basicConsumer(String, Handler) 56 | */ 57 | def basicConsumerL(queue: String): Task[RabbitMQConsumer] = 58 | Task.handle[RabbitMQConsumer] { resultHandler => 59 | target.basicConsumer(queue, resultHandler) 60 | } 61 | 62 | /** 63 | * Create a consumer with the given {@code options}. 64 | * @param queue the name of a queue 65 | * @param options options for queue 66 | * @param resultHandler a handler through which you can find out the operation status; 67 | * if the operation succeeds you can begin to receive messages 68 | * through an instance of {@link RabbitMQConsumer} 69 | * @see com.rabbitmq.client.Channel#basicConsume(String, boolean, String, Consumer) 70 | */ 71 | def basicConsumerL(queue: String, options: QueueOptions): Task[RabbitMQConsumer] = 72 | Task.handle[RabbitMQConsumer] { resultHandler => 73 | target.basicConsumer(queue, options, resultHandler) 74 | } 75 | 76 | /** 77 | * Publish a message. Publishing to a non-existent exchange will result in a channel-level protocol exception, 78 | * which closes the channel. Invocations of Channel#basicPublish will eventually block if a resource-driven alarm is in effect. 79 | * @see com.rabbitmq.client.Channel#basicPublish(String, String, AMQP.BasicProperties, byte[]) 80 | */ 81 | def basicPublishL(exchange: String, routingKey: String, message: JsonObject): Task[Unit] = 82 | Task.handle[Void] { resultHandler => 83 | target.basicPublish(exchange, routingKey, message, resultHandler) 84 | }.map(_ => ()) 85 | 86 | /** 87 | * Enables publisher acknowledgements on this channel. Can be called once during client initialisation. Calls to basicPublish() 88 | * will have to be confirmed. 89 | * @see Channel#confirmSelect() 90 | * @see http://www.rabbitmq.com/confirms.html 91 | */ 92 | def confirmSelectL(): Task[Unit] = 93 | Task.handle[Void] { resultHandler => 94 | target.confirmSelect(resultHandler) 95 | }.map(_ => ()) 96 | 97 | /** 98 | * Wait until all messages published since the last call have been either ack'd or nack'd by the broker. 99 | * This will incur slight performance loss at the expense of higher write consistency. 100 | * If desired, multiple calls to basicPublish() can be batched before confirming. 101 | * @see Channel#waitForConfirms() 102 | * @see http://www.rabbitmq.com/confirms.html 103 | * @throws java.io.IOException Throws an IOException if the message was not written to the queue. 104 | */ 105 | def waitForConfirmsL(): Task[Unit] = 106 | Task.handle[Void] { resultHandler => 107 | target.waitForConfirms(resultHandler) 108 | }.map(_ => ()) 109 | 110 | /** 111 | * Wait until all messages published since the last call have been either ack'd or nack'd by the broker; or until timeout elapses. If the timeout expires a TimeoutException is thrown. 112 | * @param timeout 113 | * @see io.vertx.rabbitmq.impl.RabbitMQClientImpl#waitForConfirms(Handler) 114 | * @see http://www.rabbitmq.com/confirms.html 115 | * @throws java.io.IOException Throws an IOException if the message was not written to the queue. 116 | */ 117 | def waitForConfirmsL(timeout: Long): Task[Unit] = 118 | Task.handle[Void] { resultHandler => 119 | target.waitForConfirms(timeout, resultHandler) 120 | }.map(_ => ()) 121 | 122 | /** 123 | * Request a specific prefetchCount "quality of service" settings 124 | * for this channel. 125 | * @see #basicQos(int, int, boolean, Handler) 126 | * @param prefetchCount maximum number of messages that the server 127 | * will deliver, 0 if unlimited 128 | * @param resultHandler handler called when operation is done with a result of the operation 129 | */ 130 | def basicQosL(prefetchCount: Int): Task[Unit] = 131 | Task.handle[Void] { resultHandler => 132 | target.basicQos(prefetchCount, resultHandler) 133 | }.map(_ => ()) 134 | 135 | /** 136 | * Request a specific prefetchCount "quality of service" settings 137 | * for this channel. 138 | * @see #basicQos(int, int, boolean, Handler) 139 | * @param prefetchCount maximum number of messages that the server 140 | * will deliver, 0 if unlimited 141 | * @param global true if the settings should be applied to the 142 | * entire channel rather than each consumer 143 | * @param resultHandler handler called when operation is done with a result of the operation 144 | */ 145 | def basicQosL(prefetchCount: Int, global: Boolean): Task[Unit] = 146 | Task.handle[Void] { resultHandler => 147 | target.basicQos(prefetchCount, global, resultHandler) 148 | }.map(_ => ()) 149 | 150 | /** 151 | * Request specific "quality of service" settings. 152 | * 153 | * These settings impose limits on the amount of data the server 154 | * will deliver to consumers before requiring acknowledgements. 155 | * Thus they provide a means of consumer-initiated flow control. 156 | * @see com.rabbitmq.client.AMQP.Basic.Qos 157 | * @param prefetchSize maximum amount of content (measured in 158 | * octets) that the server will deliver, 0 if unlimited 159 | * @param prefetchCount maximum number of messages that the server 160 | * will deliver, 0 if unlimited 161 | * @param global true if the settings should be applied to the 162 | * entire channel rather than each consumer 163 | * @param resultHandler handler called when operation is done with a result of the operation 164 | */ 165 | def basicQosL(prefetchSize: Int, prefetchCount: Int, global: Boolean): Task[Unit] = 166 | Task.handle[Void] { resultHandler => 167 | target.basicQos(prefetchSize, prefetchCount, global, resultHandler) 168 | }.map(_ => ()) 169 | 170 | /** 171 | * Declare an exchange. 172 | * @see com.rabbitmq.client.Channel#exchangeDeclare(String, String, boolean, boolean, Map) 173 | */ 174 | def exchangeDeclareL(exchange: String, `type`: String, durable: Boolean, autoDelete: Boolean): Task[Unit] = 175 | Task.handle[Void] { resultHandler => 176 | target.exchangeDeclare(exchange, `type`, durable, autoDelete, resultHandler) 177 | }.map(_ => ()) 178 | 179 | /** 180 | * Declare an exchange with additional parameters such as dead lettering, an alternate exchange or TTL. 181 | * @see com.rabbitmq.client.Channel#exchangeDeclare(String, String, boolean, boolean, Map) 182 | */ 183 | def exchangeDeclareL(exchange: String, `type`: String, durable: Boolean, autoDelete: Boolean, config: JsonObject): Task[Unit] = 184 | Task.handle[Void] { resultHandler => 185 | target.exchangeDeclare(exchange, `type`, durable, autoDelete, config, resultHandler) 186 | }.map(_ => ()) 187 | 188 | /** 189 | * Delete an exchange, without regard for whether it is in use or not. 190 | * @see com.rabbitmq.client.Channel#exchangeDelete(String) 191 | */ 192 | def exchangeDeleteL(exchange: String): Task[Unit] = 193 | Task.handle[Void] { resultHandler => 194 | target.exchangeDelete(exchange, resultHandler) 195 | }.map(_ => ()) 196 | 197 | /** 198 | * Bind an exchange to an exchange. 199 | * @see com.rabbitmq.client.Channel#exchangeBind(String, String, String) 200 | */ 201 | def exchangeBindL(destination: String, source: String, routingKey: String): Task[Unit] = 202 | Task.handle[Void] { resultHandler => 203 | target.exchangeBind(destination, source, routingKey, resultHandler) 204 | }.map(_ => ()) 205 | 206 | /** 207 | * Unbind an exchange from an exchange. 208 | * @see com.rabbitmq.client.Channel#exchangeUnbind(String, String, String) 209 | */ 210 | def exchangeUnbindL(destination: String, source: String, routingKey: String): Task[Unit] = 211 | Task.handle[Void] { resultHandler => 212 | target.exchangeUnbind(destination, source, routingKey, resultHandler) 213 | }.map(_ => ()) 214 | 215 | /** 216 | * Actively declare a server-named exclusive, autodelete, non-durable queue. 217 | * @see com.rabbitmq.client.Channel#queueDeclare() 218 | */ 219 | def queueDeclareAutoL(): Task[JsonObject] = 220 | Task.handle[JsonObject] { resultHandler => 221 | target.queueDeclareAuto(resultHandler) 222 | } 223 | 224 | /** 225 | * Declare a queue 226 | * @see com.rabbitmq.client.Channel#queueDeclare(String, boolean, boolean, boolean, java.util.Map) 227 | */ 228 | def queueDeclareL(queue: String, durable: Boolean, exclusive: Boolean, autoDelete: Boolean): Task[JsonObject] = 229 | Task.handle[JsonObject] { resultHandler => 230 | target.queueDeclare(queue, durable, exclusive, autoDelete, resultHandler) 231 | } 232 | 233 | /** 234 | * Declare a queue with config options 235 | * @see com.rabbitmq.client.Channel#queueDeclare(String, boolean, boolean, boolean, java.util.Map) 236 | */ 237 | def queueDeclareL(queue: String, durable: Boolean, exclusive: Boolean, autoDelete: Boolean, config: JsonObject): Task[JsonObject] = 238 | Task.handle[JsonObject] { resultHandler => 239 | target.queueDeclare(queue, durable, exclusive, autoDelete, config, resultHandler) 240 | } 241 | 242 | /** 243 | * Delete a queue, without regard for whether it is in use or has messages on it 244 | * @see com.rabbitmq.client.Channel#queueDelete(String) 245 | */ 246 | def queueDeleteL(queue: String): Task[JsonObject] = 247 | Task.handle[JsonObject] { resultHandler => 248 | target.queueDelete(queue, resultHandler) 249 | } 250 | 251 | /** 252 | * Delete a queue 253 | * @see com.rabbitmq.client.Channel#queueDelete(String, boolean, boolean) 254 | */ 255 | def queueDeleteIfL(queue: String, ifUnused: Boolean, ifEmpty: Boolean): Task[JsonObject] = 256 | Task.handle[JsonObject] { resultHandler => 257 | target.queueDeleteIf(queue, ifUnused, ifEmpty, resultHandler) 258 | } 259 | 260 | /** 261 | * Bind a queue to an exchange 262 | * @see com.rabbitmq.client.Channel#queueBind(String, String, String) 263 | */ 264 | def queueBindL(queue: String, exchange: String, routingKey: String): Task[Unit] = 265 | Task.handle[Void] { resultHandler => 266 | target.queueBind(queue, exchange, routingKey, resultHandler) 267 | }.map(_ => ()) 268 | 269 | /** 270 | * Returns the number of messages in a queue ready to be delivered. 271 | * @see com.rabbitmq.client.Channel#messageCount(String) 272 | */ 273 | def messageCountL(queue: String): Task[Long] = 274 | Task.handle[java.lang.Long] { resultHandler => 275 | target.messageCount(queue, resultHandler) 276 | }.map(out => out: Long) 277 | 278 | /** 279 | * Start the rabbitMQ client. Create the connection and the chanel. 280 | * @see com.rabbitmq.client.Connection#createChannel() 281 | */ 282 | def startL(): Task[Unit] = 283 | Task.handle[Void] { resultHandler => 284 | target.start(resultHandler) 285 | }.map(_ => ()) 286 | 287 | /** 288 | * Stop the rabbitMQ client. Close the connection and its chanel. 289 | * @see com.rabbitmq.client.Connection#close() 290 | */ 291 | def stopL(): Task[Unit] = 292 | Task.handle[Void] { resultHandler => 293 | target.stop(resultHandler) 294 | }.map(_ => ()) 295 | } 296 | 297 | 298 | implicit class VertxRabbitMQConsumerOps(val target: RabbitMQConsumer) extends AnyVal { 299 | 300 | def pipeToL(dst: WriteStream[RabbitMQMessage]): Task[Unit] = 301 | Task.handle[Void] { handler => 302 | target.pipeTo(dst, handler) 303 | }.map(_ => ()) 304 | 305 | /** 306 | * Stop message consumption from a queue. 307 | *

308 | * The operation is asynchronous. When consumption will be stopped, you can by notified via {@link RabbitMQConsumer#endHandler(Handler)} 309 | * @param cancelResult contains information about operation status: success/fail. 310 | */ 311 | def cancelL(): Task[Unit] = 312 | Task.handle[Void] { cancelResult => 313 | target.cancel(cancelResult) 314 | }.map(_ => ()) 315 | } 316 | 317 | 318 | } -------------------------------------------------------------------------------- /sql/generated/vertices/sql/package.scala: -------------------------------------------------------------------------------- 1 | package vertices 2 | 3 | 4 | import monix.eval.Task 5 | import io.vertx.core.AsyncResult 6 | import io.vertx.core.Handler 7 | import io.vertx.core.json.JsonArray 8 | import io.vertx.core.streams.Pipe 9 | import io.vertx.core.streams.ReadStream 10 | import io.vertx.core.streams.WriteStream 11 | import io.vertx.ext.sql.ResultSet 12 | import io.vertx.ext.sql.SQLClient 13 | import io.vertx.ext.sql.SQLConnection 14 | import io.vertx.ext.sql.SQLOperations 15 | import io.vertx.ext.sql.SQLOptions 16 | import io.vertx.ext.sql.SQLRowStream 17 | import io.vertx.ext.sql.TransactionIsolation 18 | import io.vertx.ext.sql.UpdateResult 19 | import java.io.Closeable 20 | import java.lang.Integer 21 | import java.lang.String 22 | import java.lang.Throwable 23 | import java.lang.Void 24 | import java.util.List 25 | 26 | package object sql { 27 | implicit class VertxSQLRowStreamOps(val target: SQLRowStream) extends AnyVal { 28 | 29 | def pipeToL(dst: WriteStream[JsonArray]): Task[Unit] = 30 | Task.handle[Void] { handler => 31 | target.pipeTo(dst, handler) 32 | }.map(_ => ()) 33 | 34 | /** 35 | * Closes the stream/underlying cursor(s). The actual close happens asynchronously. 36 | * @param handler called when the stream/underlying cursor(s) is(are) closed 37 | */ 38 | def closeL(): Task[Unit] = 39 | Task.handle[Void] { handler => 40 | target.close(handler) 41 | }.map(_ => ()) 42 | } 43 | 44 | 45 | implicit class VertxSQLConnectionOps(val target: SQLConnection) extends AnyVal { 46 | /** 47 | * Execute a one shot SQL statement that returns a single SQL row. This method will reduce the boilerplate code by 48 | * getting a connection from the pool (this object) and return it back after the execution. Only the first result 49 | * from the result set is returned. 50 | * @param sql the statement to execute 51 | * @param handler the result handler 52 | * @return self 53 | */ 54 | def querySingleL(sql: String): Task[JsonArray] = 55 | Task.handle[JsonArray] { handler => 56 | target.querySingle(sql, handler) 57 | } 58 | 59 | /** 60 | * Execute a one shot SQL statement with arguments that returns a single SQL row. This method will reduce the 61 | * boilerplate code by getting a connection from the pool (this object) and return it back after the execution. 62 | * Only the first result from the result set is returned. 63 | * @param sql the statement to execute 64 | * @param arguments the arguments 65 | * @param handler the result handler 66 | * @return self 67 | */ 68 | def querySingleWithParamsL(sql: String, arguments: JsonArray): Task[JsonArray] = 69 | Task.handle[JsonArray] { handler => 70 | target.querySingleWithParams(sql, arguments, handler) 71 | } 72 | 73 | /** 74 | * Sets the auto commit flag for this connection. True by default. 75 | * @param autoCommit the autoCommit flag, true by default. 76 | * @param resultHandler the handler which is called once this operation completes. 77 | * @see java.sql.Connection#setAutoCommit(boolean) 78 | */ 79 | def setAutoCommitL(autoCommit: Boolean): Task[Unit] = 80 | Task.handle[Void] { resultHandler => 81 | target.setAutoCommit(autoCommit, resultHandler) 82 | }.map(_ => ()) 83 | 84 | /** 85 | * Executes the given SQL statement 86 | * @param sql the SQL to execute. For example CREATE TABLE IF EXISTS table ... 87 | * @param resultHandler the handler which is called once this operation completes. 88 | * @see java.sql.Statement#execute(String) 89 | */ 90 | def executeL(sql: String): Task[Unit] = 91 | Task.handle[Void] { resultHandler => 92 | target.execute(sql, resultHandler) 93 | }.map(_ => ()) 94 | 95 | /** 96 | * Executes the given SQL SELECT statement which returns the results of the query. 97 | * @param sql the SQL to execute. For example SELECT * FROM table .... 98 | * @param resultHandler the handler which is called once the operation completes. It will return a {@code ResultSet}. 99 | * @see java.sql.Statement#executeQuery(String) 100 | * @see java.sql.PreparedStatement#executeQuery(String) 101 | */ 102 | def queryL(sql: String): Task[ResultSet] = 103 | Task.handle[ResultSet] { resultHandler => 104 | target.query(sql, resultHandler) 105 | } 106 | 107 | /** 108 | * Executes the given SQL SELECT statement which returns the results of the query as a read stream. 109 | * @param sql the SQL to execute. For example SELECT * FROM table .... 110 | * @param handler the handler which is called once the operation completes. It will return a {@code SQLRowStream}. 111 | * @see java.sql.Statement#executeQuery(String) 112 | * @see java.sql.PreparedStatement#executeQuery(String) 113 | */ 114 | def queryStreamL(sql: String): Task[SQLRowStream] = 115 | Task.handle[SQLRowStream] { handler => 116 | target.queryStream(sql, handler) 117 | } 118 | 119 | /** 120 | * Executes the given SQL SELECT prepared statement which returns the results of the query. 121 | * @param sql the SQL to execute. For example SELECT * FROM table .... 122 | * @param params these are the parameters to fill the statement. 123 | * @param resultHandler the handler which is called once the operation completes. It will return a {@code ResultSet}. 124 | * @see java.sql.Statement#executeQuery(String) 125 | * @see java.sql.PreparedStatement#executeQuery(String) 126 | */ 127 | def queryWithParamsL(sql: String, params: JsonArray): Task[ResultSet] = 128 | Task.handle[ResultSet] { resultHandler => 129 | target.queryWithParams(sql, params, resultHandler) 130 | } 131 | 132 | /** 133 | * Executes the given SQL SELECT statement which returns the results of the query as a read stream. 134 | * @param sql the SQL to execute. For example SELECT * FROM table .... 135 | * @param params these are the parameters to fill the statement. 136 | * @param handler the handler which is called once the operation completes. It will return a {@code SQLRowStream}. 137 | * @see java.sql.Statement#executeQuery(String) 138 | * @see java.sql.PreparedStatement#executeQuery(String) 139 | */ 140 | def queryStreamWithParamsL(sql: String, params: JsonArray): Task[SQLRowStream] = 141 | Task.handle[SQLRowStream] { handler => 142 | target.queryStreamWithParams(sql, params, handler) 143 | } 144 | 145 | /** 146 | * Executes the given SQL statement which may be an INSERT, UPDATE, or DELETE 147 | * statement. 148 | * @param sql the SQL to execute. For example INSERT INTO table ... 149 | * @param resultHandler the handler which is called once the operation completes. 150 | * @see java.sql.Statement#executeUpdate(String) 151 | * @see java.sql.PreparedStatement#executeUpdate(String) 152 | */ 153 | def updateL(sql: String): Task[UpdateResult] = 154 | Task.handle[UpdateResult] { resultHandler => 155 | target.update(sql, resultHandler) 156 | } 157 | 158 | /** 159 | * Executes the given prepared statement which may be an INSERT, UPDATE, or DELETE 160 | * statement with the given parameters 161 | * @param sql the SQL to execute. For example INSERT INTO table ... 162 | * @param params these are the parameters to fill the statement. 163 | * @param resultHandler the handler which is called once the operation completes. 164 | * @see java.sql.Statement#executeUpdate(String) 165 | * @see java.sql.PreparedStatement#executeUpdate(String) 166 | */ 167 | def updateWithParamsL(sql: String, params: JsonArray): Task[UpdateResult] = 168 | Task.handle[UpdateResult] { resultHandler => 169 | target.updateWithParams(sql, params, resultHandler) 170 | } 171 | 172 | /** 173 | * Calls the given SQL PROCEDURE which returns the result from the procedure. 174 | * @param sql the SQL to execute. For example {call getEmpName}. 175 | * @param resultHandler the handler which is called once the operation completes. It will return a {@code ResultSet}. 176 | * @see java.sql.CallableStatement#execute(String) 177 | */ 178 | def callL(sql: String): Task[ResultSet] = 179 | Task.handle[ResultSet] { resultHandler => 180 | target.call(sql, resultHandler) 181 | } 182 | 183 | /** 184 | * Calls the given SQL PROCEDURE which returns the result from the procedure. 185 | * 186 | * The index of params and outputs are important for both arrays, for example when dealing with a prodecure that 187 | * takes the first 2 arguments as input values and the 3 arg as an output then the arrays should be like: 188 | * 189 | *

190 |      *    params = [VALUE1, VALUE2, null]
191 |      *    outputs = [null, null, "VARCHAR"]
192 |      *  
193 | * @param sql the SQL to execute. For example {call getEmpName (?, ?)}. 194 | * @param params these are the parameters to fill the statement. 195 | * @param outputs these are the outputs to fill the statement. 196 | * @param resultHandler the handler which is called once the operation completes. It will return a {@code ResultSet}. 197 | * @see java.sql.CallableStatement#execute(String) 198 | */ 199 | def callWithParamsL(sql: String, params: JsonArray, outputs: JsonArray): Task[ResultSet] = 200 | Task.handle[ResultSet] { resultHandler => 201 | target.callWithParams(sql, params, outputs, resultHandler) 202 | } 203 | 204 | /** 205 | * Closes the connection. Important to always close the connection when you are done so it's returned to the pool. 206 | * @param handler the handler called when this operation completes. 207 | */ 208 | def closeL(): Task[Unit] = 209 | Task.handle[Void] { handler => 210 | target.close(handler) 211 | }.map(_ => ()) 212 | 213 | /** 214 | * Commits all changes made since the previous commit/rollback. 215 | * @param handler the handler called when this operation completes. 216 | */ 217 | def commitL(): Task[Unit] = 218 | Task.handle[Void] { handler => 219 | target.commit(handler) 220 | }.map(_ => ()) 221 | 222 | /** 223 | * Rolls back all changes made since the previous commit/rollback. 224 | * @param handler the handler called when this operation completes. 225 | */ 226 | def rollbackL(): Task[Unit] = 227 | Task.handle[Void] { handler => 228 | target.rollback(handler) 229 | }.map(_ => ()) 230 | 231 | /** 232 | * Batch simple SQL strings and execute the batch where the async result contains a array of Integers. 233 | * @param sqlStatements sql statement 234 | * @param handler the result handler 235 | */ 236 | def batchL(sqlStatements: List[String]): Task[List[Integer]] = 237 | Task.handle[List[Integer]] { handler => 238 | target.batch(sqlStatements, handler) 239 | } 240 | 241 | /** 242 | * Batch a prepared statement with all entries from the args list. Each entry is a batch. 243 | * The operation completes with the execution of the batch where the async result contains a array of Integers. 244 | * @param sqlStatement sql statement 245 | * @param args the prepared statement arguments 246 | * @param handler the result handler 247 | */ 248 | def batchWithParamsL(sqlStatement: String, args: List[JsonArray]): Task[List[Integer]] = 249 | Task.handle[List[Integer]] { handler => 250 | target.batchWithParams(sqlStatement, args, handler) 251 | } 252 | 253 | /** 254 | * Batch a callable statement with all entries from the args list. Each entry is a batch. 255 | * The size of the lists inArgs and outArgs MUST be the equal. 256 | * The operation completes with the execution of the batch where the async result contains a array of Integers. 257 | * @param sqlStatement sql statement 258 | * @param inArgs the callable statement input arguments 259 | * @param outArgs the callable statement output arguments 260 | * @param handler the result handler 261 | */ 262 | def batchCallableWithParamsL(sqlStatement: String, inArgs: List[JsonArray], outArgs: List[JsonArray]): Task[List[Integer]] = 263 | Task.handle[List[Integer]] { handler => 264 | target.batchCallableWithParams(sqlStatement, inArgs, outArgs, handler) 265 | } 266 | 267 | /** 268 | * Attempts to change the transaction isolation level for this Connection object to the one given. 269 | * 270 | * The constants defined in the interface Connection are the possible transaction isolation levels. 271 | * @param isolation the level of isolation 272 | * @param handler the handler called when this operation completes. 273 | */ 274 | def setTransactionIsolationL(isolation: TransactionIsolation): Task[Unit] = 275 | Task.handle[Void] { handler => 276 | target.setTransactionIsolation(isolation, handler) 277 | }.map(_ => ()) 278 | 279 | /** 280 | * Attempts to return the transaction isolation level for this Connection object to the one given. 281 | * @param handler the handler called when this operation completes. 282 | */ 283 | def getTransactionIsolationL(): Task[TransactionIsolation] = 284 | Task.handle[TransactionIsolation] { handler => 285 | target.getTransactionIsolation(handler) 286 | } 287 | } 288 | 289 | 290 | implicit class VertxSQLClientOps(val target: SQLClient) extends AnyVal { 291 | /** 292 | * Execute a one shot SQL statement that returns a single SQL row. This method will reduce the boilerplate code by 293 | * getting a connection from the pool (this object) and return it back after the execution. Only the first result 294 | * from the result set is returned. 295 | * @param sql the statement to execute 296 | * @param handler the result handler 297 | * @return self 298 | */ 299 | def querySingleL(sql: String): Task[JsonArray] = 300 | Task.handle[JsonArray] { handler => 301 | target.querySingle(sql, handler) 302 | } 303 | 304 | /** 305 | * Execute a one shot SQL statement with arguments that returns a single SQL row. This method will reduce the 306 | * boilerplate code by getting a connection from the pool (this object) and return it back after the execution. 307 | * Only the first result from the result set is returned. 308 | * @param sql the statement to execute 309 | * @param arguments the arguments 310 | * @param handler the result handler 311 | * @return self 312 | */ 313 | def querySingleWithParamsL(sql: String, arguments: JsonArray): Task[JsonArray] = 314 | Task.handle[JsonArray] { handler => 315 | target.querySingleWithParams(sql, arguments, handler) 316 | } 317 | 318 | /** 319 | * Returns a connection that can be used to perform SQL operations on. It's important to remember 320 | * to close the connection when you are done, so it is returned to the pool. 321 | * @param handler the handler which is called when the JdbcConnection object is ready for use. 322 | */ 323 | def getConnectionL(): Task[SQLConnection] = 324 | Task.handle[SQLConnection] { handler => 325 | target.getConnection(handler) 326 | } 327 | 328 | /** 329 | * Close the client and release all resources. 330 | * Call the handler when close is complete. 331 | * @param handler the handler that will be called when close is complete 332 | */ 333 | def closeL(): Task[Unit] = 334 | Task.handle[Void] { handler => 335 | target.close(handler) 336 | }.map(_ => ()) 337 | 338 | /** 339 | * Execute a single SQL statement, this method acquires a connection from the the pool and executes the SQL 340 | * statement and returns it back after the execution. 341 | * @param sql the statement to execute 342 | * @param handler the result handler 343 | * @return self 344 | */ 345 | def queryL(sql: String): Task[ResultSet] = 346 | Task.handle[ResultSet] { handler => 347 | target.query(sql, handler) 348 | } 349 | 350 | /** 351 | * Executes the given SQL SELECT statement which returns the results of the query as a read stream. 352 | * @param sql the SQL to execute. For example SELECT * FROM table .... 353 | * @param handler the handler which is called once the operation completes. It will return a {@code SQLRowStream}. 354 | * @see java.sql.Statement#executeQuery(String) 355 | * @see java.sql.PreparedStatement#executeQuery(String) 356 | */ 357 | def queryStreamL(sql: String): Task[SQLRowStream] = 358 | Task.handle[SQLRowStream] { handler => 359 | target.queryStream(sql, handler) 360 | } 361 | 362 | /** 363 | * Executes the given SQL SELECT statement which returns the results of the query as a read stream. 364 | * @param sql the SQL to execute. For example SELECT * FROM table .... 365 | * @param params these are the parameters to fill the statement. 366 | * @param handler the handler which is called once the operation completes. It will return a {@code SQLRowStream}. 367 | * @see java.sql.Statement#executeQuery(String) 368 | * @see java.sql.PreparedStatement#executeQuery(String) 369 | */ 370 | def queryStreamWithParamsL(sql: String, params: JsonArray): Task[SQLRowStream] = 371 | Task.handle[SQLRowStream] { handler => 372 | target.queryStreamWithParams(sql, params, handler) 373 | } 374 | 375 | /** 376 | * Execute a single SQL prepared statement, this method acquires a connection from the the pool and executes the SQL 377 | * prepared statement and returns it back after the execution. 378 | * @param sql the statement to execute 379 | * @param arguments the arguments to the statement 380 | * @param handler the result handler 381 | * @return self 382 | */ 383 | def queryWithParamsL(sql: String, arguments: JsonArray): Task[ResultSet] = 384 | Task.handle[ResultSet] { handler => 385 | target.queryWithParams(sql, arguments, handler) 386 | } 387 | 388 | /** 389 | * Executes the given SQL statement which may be an INSERT, UPDATE, or DELETE 390 | * statement. 391 | * @param sql the SQL to execute. For example INSERT INTO table ... 392 | * @param handler the handler which is called once the operation completes. 393 | * @see java.sql.Statement#executeUpdate(String) 394 | * @see java.sql.PreparedStatement#executeUpdate(String) 395 | */ 396 | def updateL(sql: String): Task[UpdateResult] = 397 | Task.handle[UpdateResult] { handler => 398 | target.update(sql, handler) 399 | } 400 | 401 | /** 402 | * Executes the given prepared statement which may be an INSERT, UPDATE, or DELETE 403 | * statement with the given parameters 404 | * @param sql the SQL to execute. For example INSERT INTO table ... 405 | * @param params these are the parameters to fill the statement. 406 | * @param handler the handler which is called once the operation completes. 407 | * @see java.sql.Statement#executeUpdate(String) 408 | * @see java.sql.PreparedStatement#executeUpdate(String) 409 | */ 410 | def updateWithParamsL(sql: String, params: JsonArray): Task[UpdateResult] = 411 | Task.handle[UpdateResult] { handler => 412 | target.updateWithParams(sql, params, handler) 413 | } 414 | 415 | /** 416 | * Calls the given SQL PROCEDURE which returns the result from the procedure. 417 | * @param sql the SQL to execute. For example {call getEmpName}. 418 | * @param handler the handler which is called once the operation completes. It will return a {@code ResultSet}. 419 | * @see java.sql.CallableStatement#execute(String) 420 | */ 421 | def callL(sql: String): Task[ResultSet] = 422 | Task.handle[ResultSet] { handler => 423 | target.call(sql, handler) 424 | } 425 | 426 | /** 427 | * Calls the given SQL PROCEDURE which returns the result from the procedure. 428 | * 429 | * The index of params and outputs are important for both arrays, for example when dealing with a prodecure that 430 | * takes the first 2 arguments as input values and the 3 arg as an output then the arrays should be like: 431 | * 432 | *
433 |      *    params = [VALUE1, VALUE2, null]
434 |      *    outputs = [null, null, "VARCHAR"]
435 |      *  
436 | * @param sql the SQL to execute. For example {call getEmpName (?, ?)}. 437 | * @param params these are the parameters to fill the statement. 438 | * @param outputs these are the outputs to fill the statement. 439 | * @param handler the handler which is called once the operation completes. It will return a {@code ResultSet}. 440 | * @see java.sql.CallableStatement#execute(String) 441 | */ 442 | def callWithParamsL(sql: String, params: JsonArray, outputs: JsonArray): Task[ResultSet] = 443 | Task.handle[ResultSet] { handler => 444 | target.callWithParams(sql, params, outputs, handler) 445 | } 446 | } 447 | 448 | 449 | } -------------------------------------------------------------------------------- /mongo/generated/vertices/mongo/package.scala: -------------------------------------------------------------------------------- 1 | package vertices 2 | 3 | 4 | import monix.eval.Task 5 | import io.vertx.core.AsyncResult 6 | import io.vertx.core.Handler 7 | import io.vertx.core.Vertx 8 | import io.vertx.core.json.JsonArray 9 | import io.vertx.core.json.JsonObject 10 | import io.vertx.core.streams.ReadStream 11 | import io.vertx.ext.mongo.AggregateOptions 12 | import io.vertx.ext.mongo.BulkOperation 13 | import io.vertx.ext.mongo.BulkWriteOptions 14 | import io.vertx.ext.mongo.FindOptions 15 | import io.vertx.ext.mongo.IndexOptions 16 | import io.vertx.ext.mongo.MongoClient 17 | import io.vertx.ext.mongo.MongoClientBulkWriteResult 18 | import io.vertx.ext.mongo.MongoClientDeleteResult 19 | import io.vertx.ext.mongo.MongoClientUpdateResult 20 | import io.vertx.ext.mongo.UpdateOptions 21 | import io.vertx.ext.mongo.WriteOption 22 | import java.lang.Long 23 | import java.lang.String 24 | import java.lang.Void 25 | import java.util.List 26 | 27 | package object mongo { 28 | implicit class VertxMongoClientOps(val target: MongoClient) extends AnyVal { 29 | /** 30 | * Save a document in the specified collection 31 | *

32 | * This operation might change _id field of document parameter 33 | * @param collection the collection 34 | * @param document the document 35 | * @param resultHandler result handler will be provided with the id if document didn't already have one 36 | */ 37 | def saveL(collection: String, document: JsonObject): Task[String] = 38 | Task.handle[String] { resultHandler => 39 | target.save(collection, document, resultHandler) 40 | } 41 | 42 | /** 43 | * Save a document in the specified collection with the specified write option 44 | *

45 | * This operation might change _id field of document parameter 46 | * @param collection the collection 47 | * @param document the document 48 | * @param writeOption the write option to use 49 | * @param resultHandler result handler will be provided with the id if document didn't already have one 50 | */ 51 | def saveWithOptionsL(collection: String, document: JsonObject, writeOption: WriteOption): Task[String] = 52 | Task.handle[String] { resultHandler => 53 | target.saveWithOptions(collection, document, writeOption, resultHandler) 54 | } 55 | 56 | /** 57 | * Insert a document in the specified collection 58 | *

59 | * This operation might change _id field of document parameter 60 | * @param collection the collection 61 | * @param document the document 62 | * @param resultHandler result handler will be provided with the id if document didn't already have one 63 | */ 64 | def insertL(collection: String, document: JsonObject): Task[String] = 65 | Task.handle[String] { resultHandler => 66 | target.insert(collection, document, resultHandler) 67 | } 68 | 69 | /** 70 | * Insert a document in the specified collection with the specified write option 71 | *

72 | * This operation might change _id field of document parameter 73 | * @param collection the collection 74 | * @param document the document 75 | * @param writeOption the write option to use 76 | * @param resultHandler result handler will be provided with the id if document didn't already have one 77 | */ 78 | def insertWithOptionsL(collection: String, document: JsonObject, writeOption: WriteOption): Task[String] = 79 | Task.handle[String] { resultHandler => 80 | target.insertWithOptions(collection, document, writeOption, resultHandler) 81 | } 82 | 83 | /** 84 | * Update matching documents in the specified collection and return the handler with MongoClientUpdateResult result 85 | * @param collection the collection 86 | * @param query query used to match the documents 87 | * @param update used to describe how the documents will be updated 88 | * @param resultHandler will be called when complete 89 | */ 90 | def updateCollectionL(collection: String, query: JsonObject, update: JsonObject): Task[MongoClientUpdateResult] = 91 | Task.handle[MongoClientUpdateResult] { resultHandler => 92 | target.updateCollection(collection, query, update, resultHandler) 93 | } 94 | 95 | /** 96 | * Update matching documents in the specified collection, specifying options and return the handler with MongoClientUpdateResult result 97 | * @param collection the collection 98 | * @param query query used to match the documents 99 | * @param update used to describe how the documents will be updated 100 | * @param options options to configure the update 101 | * @param resultHandler will be called when complete 102 | */ 103 | def updateCollectionWithOptionsL(collection: String, query: JsonObject, update: JsonObject, options: UpdateOptions): Task[MongoClientUpdateResult] = 104 | Task.handle[MongoClientUpdateResult] { resultHandler => 105 | target.updateCollectionWithOptions(collection, query, update, options, resultHandler) 106 | } 107 | 108 | /** 109 | * Replace matching documents in the specified collection and return the handler with MongoClientUpdateResult result 110 | * @param collection the collection 111 | * @param query query used to match the documents 112 | * @param replace all matching documents will be replaced with this 113 | * @param resultHandler will be called when complete 114 | */ 115 | def replaceDocumentsL(collection: String, query: JsonObject, replace: JsonObject): Task[MongoClientUpdateResult] = 116 | Task.handle[MongoClientUpdateResult] { resultHandler => 117 | target.replaceDocuments(collection, query, replace, resultHandler) 118 | } 119 | 120 | /** 121 | * Replace matching documents in the specified collection, specifying options and return the handler with MongoClientUpdateResult result 122 | * @param collection the collection 123 | * @param query query used to match the documents 124 | * @param replace all matching documents will be replaced with this 125 | * @param options options to configure the replace 126 | * @param resultHandler will be called when complete 127 | */ 128 | def replaceDocumentsWithOptionsL(collection: String, query: JsonObject, replace: JsonObject, options: UpdateOptions): Task[MongoClientUpdateResult] = 129 | Task.handle[MongoClientUpdateResult] { resultHandler => 130 | target.replaceDocumentsWithOptions(collection, query, replace, options, resultHandler) 131 | } 132 | 133 | /** 134 | * Execute a bulk operation. Can insert, update, replace, and/or delete multiple documents with one request. 135 | * @param collection 136 | * the collection 137 | * @param operations 138 | * the operations to execute 139 | * @param resultHandler 140 | * will be called with a {@link MongoClientBulkWriteResult} when complete 141 | */ 142 | def bulkWriteL(collection: String, operations: List[BulkOperation]): Task[MongoClientBulkWriteResult] = 143 | Task.handle[MongoClientBulkWriteResult] { resultHandler => 144 | target.bulkWrite(collection, operations, resultHandler) 145 | } 146 | 147 | /** 148 | * Execute a bulk operation with the specified write options. Can insert, update, replace, and/or delete multiple 149 | * documents with one request. 150 | * @param collection 151 | * the collection 152 | * @param operations 153 | * the operations to execute 154 | * @param bulkWriteOptions 155 | * the write options 156 | * @param resultHandler 157 | * will be called with a {@link MongoClientBulkWriteResult} when complete 158 | */ 159 | def bulkWriteWithOptionsL(collection: String, operations: List[BulkOperation], bulkWriteOptions: BulkWriteOptions): Task[MongoClientBulkWriteResult] = 160 | Task.handle[MongoClientBulkWriteResult] { resultHandler => 161 | target.bulkWriteWithOptions(collection, operations, bulkWriteOptions, resultHandler) 162 | } 163 | 164 | /** 165 | * Find matching documents in the specified collection 166 | * @param collection the collection 167 | * @param query query used to match documents 168 | * @param resultHandler will be provided with list of documents 169 | */ 170 | def findL(collection: String, query: JsonObject): Task[List[JsonObject]] = 171 | Task.handle[List[JsonObject]] { resultHandler => 172 | target.find(collection, query, resultHandler) 173 | } 174 | 175 | /** 176 | * Find matching documents in the specified collection, specifying options 177 | * @param collection the collection 178 | * @param query query used to match documents 179 | * @param options options to configure the find 180 | * @param resultHandler will be provided with list of documents 181 | */ 182 | def findWithOptionsL(collection: String, query: JsonObject, options: FindOptions): Task[List[JsonObject]] = 183 | Task.handle[List[JsonObject]] { resultHandler => 184 | target.findWithOptions(collection, query, options, resultHandler) 185 | } 186 | 187 | /** 188 | * Find a single matching document in the specified collection 189 | *

190 | * This operation might change _id field of query parameter 191 | * @param collection the collection 192 | * @param query the query used to match the document 193 | * @param fields the fields 194 | * @param resultHandler will be provided with the document, if any 195 | */ 196 | def findOneL(collection: String, query: JsonObject, fields: JsonObject): Task[JsonObject] = 197 | Task.handle[JsonObject] { resultHandler => 198 | target.findOne(collection, query, fields, resultHandler) 199 | } 200 | 201 | /** 202 | * Find a single matching document in the specified collection and update it. 203 | *

204 | * This operation might change _id field of query parameter 205 | * @param collection the collection 206 | * @param query the query used to match the document 207 | * @param update used to describe how the documents will be updated 208 | * @param resultHandler will be provided with the document, if any 209 | */ 210 | def findOneAndUpdateL(collection: String, query: JsonObject, update: JsonObject): Task[JsonObject] = 211 | Task.handle[JsonObject] { resultHandler => 212 | target.findOneAndUpdate(collection, query, update, resultHandler) 213 | } 214 | 215 | /** 216 | * Find a single matching document in the specified collection and update it. 217 | *

218 | * This operation might change _id field of query parameter 219 | * @param collection the collection 220 | * @param query the query used to match the document 221 | * @param update used to describe how the documents will be updated 222 | * @param findOptions options to configure the find 223 | * @param updateOptions options to configure the update 224 | * @param resultHandler will be provided with the document, if any 225 | */ 226 | def findOneAndUpdateWithOptionsL(collection: String, query: JsonObject, update: JsonObject, findOptions: FindOptions, updateOptions: UpdateOptions): Task[JsonObject] = 227 | Task.handle[JsonObject] { resultHandler => 228 | target.findOneAndUpdateWithOptions(collection, query, update, findOptions, updateOptions, resultHandler) 229 | } 230 | 231 | /** 232 | * Find a single matching document in the specified collection and replace it. 233 | *

234 | * This operation might change _id field of query parameter 235 | * @param collection the collection 236 | * @param query the query used to match the document 237 | * @param replace the replacement document 238 | * @param resultHandler will be provided with the document, if any 239 | */ 240 | def findOneAndReplaceL(collection: String, query: JsonObject, replace: JsonObject): Task[JsonObject] = 241 | Task.handle[JsonObject] { resultHandler => 242 | target.findOneAndReplace(collection, query, replace, resultHandler) 243 | } 244 | 245 | /** 246 | * Find a single matching document in the specified collection and replace it. 247 | *

248 | * This operation might change _id field of query parameter 249 | * @param collection the collection 250 | * @param query the query used to match the document 251 | * @param replace the replacement document 252 | * @param findOptions options to configure the find 253 | * @param updateOptions options to configure the update 254 | * @param resultHandler will be provided with the document, if any 255 | */ 256 | def findOneAndReplaceWithOptionsL(collection: String, query: JsonObject, replace: JsonObject, findOptions: FindOptions, updateOptions: UpdateOptions): Task[JsonObject] = 257 | Task.handle[JsonObject] { resultHandler => 258 | target.findOneAndReplaceWithOptions(collection, query, replace, findOptions, updateOptions, resultHandler) 259 | } 260 | 261 | /** 262 | * Find a single matching document in the specified collection and delete it. 263 | *

264 | * This operation might change _id field of query parameter 265 | * @param collection the collection 266 | * @param query the query used to match the document 267 | * @param resultHandler will be provided with the deleted document, if any 268 | */ 269 | def findOneAndDeleteL(collection: String, query: JsonObject): Task[JsonObject] = 270 | Task.handle[JsonObject] { resultHandler => 271 | target.findOneAndDelete(collection, query, resultHandler) 272 | } 273 | 274 | /** 275 | * Find a single matching document in the specified collection and delete it. 276 | *

277 | * This operation might change _id field of query parameter 278 | * @param collection the collection 279 | * @param query the query used to match the document 280 | * @param findOptions options to configure the find 281 | * @param resultHandler will be provided with the deleted document, if any 282 | */ 283 | def findOneAndDeleteWithOptionsL(collection: String, query: JsonObject, findOptions: FindOptions): Task[JsonObject] = 284 | Task.handle[JsonObject] { resultHandler => 285 | target.findOneAndDeleteWithOptions(collection, query, findOptions, resultHandler) 286 | } 287 | 288 | /** 289 | * Count matching documents in a collection. 290 | * @param collection the collection 291 | * @param query query used to match documents 292 | * @param resultHandler will be provided with the number of matching documents 293 | */ 294 | def countL(collection: String, query: JsonObject): Task[Long] = 295 | Task.handle[java.lang.Long] { resultHandler => 296 | target.count(collection, query, resultHandler) 297 | }.map(out => out: Long) 298 | 299 | /** 300 | * Remove matching documents from a collection and return the handler with MongoClientDeleteResult result 301 | * @param collection the collection 302 | * @param query query used to match documents 303 | * @param resultHandler will be called when complete 304 | */ 305 | def removeDocumentsL(collection: String, query: JsonObject): Task[MongoClientDeleteResult] = 306 | Task.handle[MongoClientDeleteResult] { resultHandler => 307 | target.removeDocuments(collection, query, resultHandler) 308 | } 309 | 310 | /** 311 | * Remove matching documents from a collection with the specified write option and return the handler with MongoClientDeleteResult result 312 | * @param collection the collection 313 | * @param query query used to match documents 314 | * @param writeOption the write option to use 315 | * @param resultHandler will be called when complete 316 | */ 317 | def removeDocumentsWithOptionsL(collection: String, query: JsonObject, writeOption: WriteOption): Task[MongoClientDeleteResult] = 318 | Task.handle[MongoClientDeleteResult] { resultHandler => 319 | target.removeDocumentsWithOptions(collection, query, writeOption, resultHandler) 320 | } 321 | 322 | /** 323 | * Remove a single matching document from a collection and return the handler with MongoClientDeleteResult result 324 | * @param collection the collection 325 | * @param query query used to match document 326 | * @param resultHandler will be called when complete 327 | */ 328 | def removeDocumentL(collection: String, query: JsonObject): Task[MongoClientDeleteResult] = 329 | Task.handle[MongoClientDeleteResult] { resultHandler => 330 | target.removeDocument(collection, query, resultHandler) 331 | } 332 | 333 | /** 334 | * Remove a single matching document from a collection with the specified write option and return the handler with MongoClientDeleteResult result 335 | * @param collection the collection 336 | * @param query query used to match document 337 | * @param writeOption the write option to use 338 | * @param resultHandler will be called when complete 339 | */ 340 | def removeDocumentWithOptionsL(collection: String, query: JsonObject, writeOption: WriteOption): Task[MongoClientDeleteResult] = 341 | Task.handle[MongoClientDeleteResult] { resultHandler => 342 | target.removeDocumentWithOptions(collection, query, writeOption, resultHandler) 343 | } 344 | 345 | /** 346 | * Create a new collection 347 | * @param collectionName the name of the collection 348 | * @param resultHandler will be called when complete 349 | */ 350 | def createCollectionL(collectionName: String): Task[Unit] = 351 | Task.handle[Void] { resultHandler => 352 | target.createCollection(collectionName, resultHandler) 353 | }.map(_ => ()) 354 | 355 | /** 356 | * Get a list of all collections in the database. 357 | * @param resultHandler will be called with a list of collections. 358 | */ 359 | def getCollectionsL(): Task[List[String]] = 360 | Task.handle[List[String]] { resultHandler => 361 | target.getCollections(resultHandler) 362 | } 363 | 364 | /** 365 | * Drop a collection 366 | * @param collection the collection 367 | * @param resultHandler will be called when complete 368 | */ 369 | def dropCollectionL(collection: String): Task[Unit] = 370 | Task.handle[Void] { resultHandler => 371 | target.dropCollection(collection, resultHandler) 372 | }.map(_ => ()) 373 | 374 | /** 375 | * Creates an index. 376 | * @param collection the collection 377 | * @param key A document that contains the field and value pairs where the field is the index key and the value 378 | * describes the type of index for that field. For an ascending index on a field, 379 | * specify a value of 1; for descending index, specify a value of -1. 380 | * @param resultHandler will be called when complete 381 | */ 382 | def createIndexL(collection: String, key: JsonObject): Task[Unit] = 383 | Task.handle[Void] { resultHandler => 384 | target.createIndex(collection, key, resultHandler) 385 | }.map(_ => ()) 386 | 387 | /** 388 | * Creates an index. 389 | * @param collection the collection 390 | * @param key A document that contains the field and value pairs where the field is the index key and the value 391 | * describes the type of index for that field. For an ascending index on a field, 392 | * specify a value of 1; for descending index, specify a value of -1. 393 | * @param options the options for the index 394 | * @param resultHandler will be called when complete 395 | */ 396 | def createIndexWithOptionsL(collection: String, key: JsonObject, options: IndexOptions): Task[Unit] = 397 | Task.handle[Void] { resultHandler => 398 | target.createIndexWithOptions(collection, key, options, resultHandler) 399 | }.map(_ => ()) 400 | 401 | /** 402 | * Get all the indexes in this collection. 403 | * @param collection the collection 404 | * @param resultHandler will be called when complete 405 | */ 406 | def listIndexesL(collection: String): Task[JsonArray] = 407 | Task.handle[JsonArray] { resultHandler => 408 | target.listIndexes(collection, resultHandler) 409 | } 410 | 411 | /** 412 | * Drops the index given its name. 413 | * @param collection the collection 414 | * @param indexName the name of the index to remove 415 | * @param resultHandler will be called when complete 416 | */ 417 | def dropIndexL(collection: String, indexName: String): Task[Unit] = 418 | Task.handle[Void] { resultHandler => 419 | target.dropIndex(collection, indexName, resultHandler) 420 | }.map(_ => ()) 421 | 422 | /** 423 | * Run an arbitrary MongoDB command. 424 | * @param commandName the name of the command 425 | * @param command the command 426 | * @param resultHandler will be called with the result. 427 | */ 428 | def runCommandL(commandName: String, command: JsonObject): Task[JsonObject] = 429 | Task.handle[JsonObject] { resultHandler => 430 | target.runCommand(commandName, command, resultHandler) 431 | } 432 | 433 | /** 434 | * Gets the distinct values of the specified field name. 435 | * Return a JsonArray containing distinct values (eg: [ 1 , 89 ]) 436 | * @param collection the collection 437 | * @param fieldName the field name 438 | * @param resultHandler will be provided with array of values. 439 | */ 440 | def distinctL(collection: String, fieldName: String, resultClassname: String): Task[JsonArray] = 441 | Task.handle[JsonArray] { resultHandler => 442 | target.distinct(collection, fieldName, resultClassname, resultHandler) 443 | } 444 | 445 | /** 446 | * Gets the distinct values of the specified field name filtered by specified query. 447 | * Return a JsonArray containing distinct values (eg: [ 1 , 89 ]) 448 | * @param collection the collection 449 | * @param fieldName the field name 450 | * @param query the query 451 | * @param resultHandler will be provided with array of values. 452 | */ 453 | def distinctWithQueryL(collection: String, fieldName: String, resultClassname: String, query: JsonObject): Task[JsonArray] = 454 | Task.handle[JsonArray] { resultHandler => 455 | target.distinctWithQuery(collection, fieldName, resultClassname, query, resultHandler) 456 | } 457 | } 458 | 459 | 460 | } -------------------------------------------------------------------------------- /kafka_client/generated/vertices/kafka/client/package.scala: -------------------------------------------------------------------------------- 1 | package vertices 2 | package kafka 3 | 4 | import monix.eval.Task 5 | import io.vertx.core.AsyncResult 6 | import io.vertx.core.Handler 7 | import io.vertx.core.Vertx 8 | import io.vertx.core.streams.Pipe 9 | import io.vertx.core.streams.ReadStream 10 | import io.vertx.core.streams.WriteStream 11 | import io.vertx.kafka.admin.ConsumerGroupListing 12 | import io.vertx.kafka.admin.KafkaAdminClient 13 | import io.vertx.kafka.admin.NewTopic 14 | import io.vertx.kafka.client.common.PartitionInfo 15 | import io.vertx.kafka.client.common.TopicPartition 16 | import io.vertx.kafka.client.consumer.KafkaConsumer 17 | import io.vertx.kafka.client.consumer.KafkaConsumerRecord 18 | import io.vertx.kafka.client.consumer.KafkaConsumerRecords 19 | import io.vertx.kafka.client.consumer.OffsetAndMetadata 20 | import io.vertx.kafka.client.consumer.OffsetAndTimestamp 21 | import io.vertx.kafka.client.producer.KafkaProducer 22 | import io.vertx.kafka.client.producer.KafkaProducerRecord 23 | import io.vertx.kafka.client.producer.RecordMetadata 24 | import java.lang.Class 25 | import java.lang.Long 26 | import java.lang.String 27 | import java.lang.Throwable 28 | import java.lang.Void 29 | import java.util.List 30 | import java.util.Map 31 | import java.util.Set 32 | 33 | package object client { 34 | implicit class VertxKafkaConsumerOps[K, V](val target: KafkaConsumer[K, V]) { 35 | 36 | def pipeToL(dst: WriteStream[KafkaConsumerRecord[K,V]]): Task[Unit] = 37 | Task.handle[Void] { handler => 38 | target.pipeTo(dst, handler) 39 | }.map(_ => ()) 40 | 41 | /** 42 | * Subscribe to the given topic to get dynamically assigned partitions. 43 | *

44 | * Due to internal buffering of messages, when changing the subscribed topic 45 | * the old topic may remain in effect 46 | * (as observed by the {@linkplain #handler(Handler)} record handler}) 47 | * until some time after the given {@code completionHandler} 48 | * is called. In contrast, the once the given {@code completionHandler} 49 | * is called the {@link #batchHandler(Handler)} will only see messages 50 | * consistent with the new topic. 51 | * @param topic topic to subscribe to 52 | * @param completionHandler handler called on operation completed 53 | * @return current KafkaConsumer instance 54 | */ 55 | def subscribeL(topic: String): Task[Unit] = 56 | Task.handle[Void] { completionHandler => 57 | target.subscribe(topic, completionHandler) 58 | }.map(_ => ()) 59 | 60 | /** 61 | * Subscribe to the given list of topics to get dynamically assigned partitions. 62 | *

63 | * Due to internal buffering of messages, when changing the subscribed topics 64 | * the old set of topics may remain in effect 65 | * (as observed by the {@linkplain #handler(Handler)} record handler}) 66 | * until some time after the given {@code completionHandler} 67 | * is called. In contrast, the once the given {@code completionHandler} 68 | * is called the {@link #batchHandler(Handler)} will only see messages 69 | * consistent with the new set of topics. 70 | * @param topics topics to subscribe to 71 | * @param completionHandler handler called on operation completed 72 | * @return current KafkaConsumer instance 73 | */ 74 | def subscribeL(topics: Set[String]): Task[Unit] = 75 | Task.handle[Void] { completionHandler => 76 | target.subscribe(topics, completionHandler) 77 | }.map(_ => ()) 78 | 79 | /** 80 | * Manually assign a partition to this consumer. 81 | *

82 | * Due to internal buffering of messages, when reassigning 83 | * the old partition may remain in effect 84 | * (as observed by the {@linkplain #handler(Handler)} record handler)} 85 | * until some time after the given {@code completionHandler} 86 | * is called. In contrast, the once the given {@code completionHandler} 87 | * is called the {@link #batchHandler(Handler)} will only see messages 88 | * consistent with the new partition. 89 | * @param topicPartition partition which want assigned 90 | * @param completionHandler handler called on operation completed 91 | * @return current KafkaConsumer instance 92 | */ 93 | def assignL(topicPartition: TopicPartition): Task[Unit] = 94 | Task.handle[Void] { completionHandler => 95 | target.assign(topicPartition, completionHandler) 96 | }.map(_ => ()) 97 | 98 | /** 99 | * Manually assign a list of partition to this consumer. 100 | *

101 | * Due to internal buffering of messages, when reassigning 102 | * the old set of partitions may remain in effect 103 | * (as observed by the {@linkplain #handler(Handler)} record handler)} 104 | * until some time after the given {@code completionHandler} 105 | * is called. In contrast, the once the given {@code completionHandler} 106 | * is called the {@link #batchHandler(Handler)} will only see messages 107 | * consistent with the new set of partitions. 108 | * @param topicPartitions partitions which want assigned 109 | * @param completionHandler handler called on operation completed 110 | * @return current KafkaConsumer instance 111 | */ 112 | def assignL(topicPartitions: Set[TopicPartition]): Task[Unit] = 113 | Task.handle[Void] { completionHandler => 114 | target.assign(topicPartitions, completionHandler) 115 | }.map(_ => ()) 116 | 117 | /** 118 | * Get the set of partitions currently assigned to this consumer. 119 | * @param handler handler called on operation completed 120 | * @return current KafkaConsumer instance 121 | */ 122 | def assignmentL(): Task[Set[TopicPartition]] = 123 | Task.handle[Set[TopicPartition]] { handler => 124 | target.assignment(handler) 125 | } 126 | 127 | /** 128 | * Unsubscribe from topics currently subscribed with subscribe. 129 | * @param completionHandler handler called on operation completed 130 | * @return current KafkaConsumer instance 131 | */ 132 | def unsubscribeL(): Task[Unit] = 133 | Task.handle[Void] { completionHandler => 134 | target.unsubscribe(completionHandler) 135 | }.map(_ => ()) 136 | 137 | /** 138 | * Get the current subscription. 139 | * @param handler handler called on operation completed 140 | * @return current KafkaConsumer instance 141 | */ 142 | def subscriptionL(): Task[Set[String]] = 143 | Task.handle[Set[String]] { handler => 144 | target.subscription(handler) 145 | } 146 | 147 | /** 148 | * Suspend fetching from the requested partition. 149 | *

150 | * Due to internal buffering of messages, 151 | * the {@linkplain #handler(Handler) record handler} will 152 | * continue to observe messages from the given {@code topicPartition} 153 | * until some time after the given {@code completionHandler} 154 | * is called. In contrast, the once the given {@code completionHandler} 155 | * is called the {@link #batchHandler(Handler)} will not see messages 156 | * from the given {@code topicPartition}. 157 | * @param topicPartition topic partition from which suspend fetching 158 | * @param completionHandler handler called on operation completed 159 | * @return current KafkaConsumer instance 160 | */ 161 | def pauseL(topicPartition: TopicPartition): Task[Unit] = 162 | Task.handle[Void] { completionHandler => 163 | target.pause(topicPartition, completionHandler) 164 | }.map(_ => ()) 165 | 166 | /** 167 | * Suspend fetching from the requested partitions. 168 | *

169 | * Due to internal buffering of messages, 170 | * the {@linkplain #handler(Handler) record handler} will 171 | * continue to observe messages from the given {@code topicPartitions} 172 | * until some time after the given {@code completionHandler} 173 | * is called. In contrast, the once the given {@code completionHandler} 174 | * is called the {@link #batchHandler(Handler)} will not see messages 175 | * from the given {@code topicPartitions}. 176 | * @param topicPartitions topic partition from which suspend fetching 177 | * @param completionHandler handler called on operation completed 178 | * @return current KafkaConsumer instance 179 | */ 180 | def pauseL(topicPartitions: Set[TopicPartition]): Task[Unit] = 181 | Task.handle[Void] { completionHandler => 182 | target.pause(topicPartitions, completionHandler) 183 | }.map(_ => ()) 184 | 185 | /** 186 | * Get the set of partitions that were previously paused by a call to pause(Set). 187 | * @param handler handler called on operation completed 188 | */ 189 | def pausedL(): Task[Set[TopicPartition]] = 190 | Task.handle[Set[TopicPartition]] { handler => 191 | target.paused(handler) 192 | } 193 | 194 | /** 195 | * Resume specified partition which have been paused with pause. 196 | * @param topicPartition topic partition from which resume fetching 197 | * @param completionHandler handler called on operation completed 198 | * @return current KafkaConsumer instance 199 | */ 200 | def resumeL(topicPartition: TopicPartition): Task[Unit] = 201 | Task.handle[Void] { completionHandler => 202 | target.resume(topicPartition, completionHandler) 203 | }.map(_ => ()) 204 | 205 | /** 206 | * Resume specified partitions which have been paused with pause. 207 | * @param topicPartitions topic partition from which resume fetching 208 | * @param completionHandler handler called on operation completed 209 | * @return current KafkaConsumer instance 210 | */ 211 | def resumeL(topicPartitions: Set[TopicPartition]): Task[Unit] = 212 | Task.handle[Void] { completionHandler => 213 | target.resume(topicPartitions, completionHandler) 214 | }.map(_ => ()) 215 | 216 | /** 217 | * Overrides the fetch offsets that the consumer will use on the next poll. 218 | *

219 | * Due to internal buffering of messages, 220 | * the {@linkplain #handler(Handler) record handler} will 221 | * continue to observe messages fetched with respect to the old offset 222 | * until some time after the given {@code completionHandler} 223 | * is called. In contrast, the once the given {@code completionHandler} 224 | * is called the {@link #batchHandler(Handler)} will only see messages 225 | * consistent with the new offset. 226 | * @param topicPartition topic partition for which seek 227 | * @param offset offset to seek inside the topic partition 228 | * @param completionHandler handler called on operation completed 229 | * @return current KafkaConsumer instance 230 | */ 231 | def seekL(topicPartition: TopicPartition, offset: Long): Task[Unit] = 232 | Task.handle[Void] { completionHandler => 233 | target.seek(topicPartition, offset, completionHandler) 234 | }.map(_ => ()) 235 | 236 | /** 237 | * Seek to the first offset for each of the given partition. 238 | *

239 | * Due to internal buffering of messages, 240 | * the {@linkplain #handler(Handler) record handler} will 241 | * continue to observe messages fetched with respect to the old offset 242 | * until some time after the given {@code completionHandler} 243 | * is called. In contrast, the once the given {@code completionHandler} 244 | * is called the {@link #batchHandler(Handler)} will only see messages 245 | * consistent with the new offset. 246 | * @param topicPartition topic partition for which seek 247 | * @param completionHandler handler called on operation completed 248 | * @return current KafkaConsumer instance 249 | */ 250 | def seekToBeginningL(topicPartition: TopicPartition): Task[Unit] = 251 | Task.handle[Void] { completionHandler => 252 | target.seekToBeginning(topicPartition, completionHandler) 253 | }.map(_ => ()) 254 | 255 | /** 256 | * Seek to the first offset for each of the given partitions. 257 | *

258 | * Due to internal buffering of messages, 259 | * the {@linkplain #handler(Handler) record handler} will 260 | * continue to observe messages fetched with respect to the old offset 261 | * until some time after the given {@code completionHandler} 262 | * is called. In contrast, the once the given {@code completionHandler} 263 | * is called the {@link #batchHandler(Handler)} will only see messages 264 | * consistent with the new offset. 265 | * @param topicPartitions topic partition for which seek 266 | * @param completionHandler handler called on operation completed 267 | * @return current KafkaConsumer instance 268 | */ 269 | def seekToBeginningL(topicPartitions: Set[TopicPartition]): Task[Unit] = 270 | Task.handle[Void] { completionHandler => 271 | target.seekToBeginning(topicPartitions, completionHandler) 272 | }.map(_ => ()) 273 | 274 | /** 275 | * Seek to the last offset for each of the given partition. 276 | *

277 | * Due to internal buffering of messages, 278 | * the {@linkplain #handler(Handler) record handler} will 279 | * continue to observe messages fetched with respect to the old offset 280 | * until some time after the given {@code completionHandler} 281 | * is called. In contrast, the once the given {@code completionHandler} 282 | * is called the {@link #batchHandler(Handler)} will only see messages 283 | * consistent with the new offset. 284 | * @param topicPartition topic partition for which seek 285 | * @param completionHandler handler called on operation completed 286 | * @return current KafkaConsumer instance 287 | */ 288 | def seekToEndL(topicPartition: TopicPartition): Task[Unit] = 289 | Task.handle[Void] { completionHandler => 290 | target.seekToEnd(topicPartition, completionHandler) 291 | }.map(_ => ()) 292 | 293 | /** 294 | * Seek to the last offset for each of the given partitions. 295 | *

296 | * Due to internal buffering of messages, 297 | * the {@linkplain #handler(Handler) record handler} will 298 | * continue to observe messages fetched with respect to the old offset 299 | * until some time after the given {@code completionHandler} 300 | * is called. In contrast, the once the given {@code completionHandler} 301 | * is called the {@link #batchHandler(Handler)} will only see messages 302 | * consistent with the new offset. 303 | * @param topicPartitions topic partition for which seek 304 | * @param completionHandler handler called on operation completed 305 | * @return current KafkaConsumer instance 306 | */ 307 | def seekToEndL(topicPartitions: Set[TopicPartition]): Task[Unit] = 308 | Task.handle[Void] { completionHandler => 309 | target.seekToEnd(topicPartitions, completionHandler) 310 | }.map(_ => ()) 311 | 312 | /** 313 | * Commit current offsets for all the subscribed list of topics and partition. 314 | * @param completionHandler handler called on operation completed 315 | */ 316 | def commitL(): Task[Unit] = 317 | Task.handle[Void] { completionHandler => 318 | target.commit(completionHandler) 319 | }.map(_ => ()) 320 | 321 | /** 322 | * Get the last committed offset for the given partition (whether the commit happened by this process or another). 323 | * @param topicPartition topic partition for getting last committed offset 324 | * @param handler handler called on operation completed 325 | */ 326 | def committedL(topicPartition: TopicPartition): Task[OffsetAndMetadata] = 327 | Task.handle[OffsetAndMetadata] { handler => 328 | target.committed(topicPartition, handler) 329 | } 330 | 331 | /** 332 | * Get metadata about the partitions for a given topic. 333 | * @param topic topic partition for which getting partitions info 334 | * @param handler handler called on operation completed 335 | * @return current KafkaConsumer instance 336 | */ 337 | def partitionsForL(topic: String): Task[List[PartitionInfo]] = 338 | Task.handle[List[PartitionInfo]] { handler => 339 | target.partitionsFor(topic, handler) 340 | } 341 | 342 | /** 343 | * Close the consumer 344 | * @param completionHandler handler called on operation completed 345 | */ 346 | def closeL(): Task[Unit] = 347 | Task.handle[Void] { completionHandler => 348 | target.close(completionHandler) 349 | }.map(_ => ()) 350 | 351 | /** 352 | * Get the offset of the next record that will be fetched (if a record with that offset exists). 353 | * @param partition The partition to get the position for 354 | * @param handler handler called on operation completed 355 | */ 356 | def positionL(partition: TopicPartition): Task[Long] = 357 | Task.handle[java.lang.Long] { handler => 358 | target.position(partition, handler) 359 | }.map(out => out: Long) 360 | 361 | /** 362 | * Look up the offset for the given partition by timestamp. Note: the result might be null in case 363 | * for the given timestamp no offset can be found -- e.g., when the timestamp refers to the future 364 | * @param topicPartition TopicPartition to query. 365 | * @param timestamp Timestamp to be used in the query. 366 | * @param handler handler called on operation completed 367 | */ 368 | def offsetsForTimesL(topicPartition: TopicPartition, timestamp: Long): Task[OffsetAndTimestamp] = 369 | Task.handle[OffsetAndTimestamp] { handler => 370 | target.offsetsForTimes(topicPartition, timestamp, handler) 371 | } 372 | 373 | /** 374 | * Get the first offset for the given partitions. 375 | * @param topicPartition the partition to get the earliest offset. 376 | * @param handler handler called on operation completed. Returns the earliest available offset for the given partition 377 | */ 378 | def beginningOffsetsL(topicPartition: TopicPartition): Task[Long] = 379 | Task.handle[java.lang.Long] { handler => 380 | target.beginningOffsets(topicPartition, handler) 381 | }.map(out => out: Long) 382 | 383 | /** 384 | * Get the last offset for the given partition. The last offset of a partition is the offset 385 | * of the upcoming message, i.e. the offset of the last available message + 1. 386 | * @param topicPartition the partition to get the end offset. 387 | * @param handler handler called on operation completed. The end offset for the given partition. 388 | */ 389 | def endOffsetsL(topicPartition: TopicPartition): Task[Long] = 390 | Task.handle[java.lang.Long] { handler => 391 | target.endOffsets(topicPartition, handler) 392 | }.map(out => out: Long) 393 | 394 | /** 395 | * Executes a poll for getting messages from Kafka 396 | * @param timeout The time, in milliseconds, spent waiting in poll if data is not available in the buffer. 397 | * If 0, returns immediately with any records that are available currently in the native Kafka consumer's buffer, 398 | * else returns empty. Must not be negative. 399 | * @param handler handler called after the poll with batch of records (can be empty). 400 | */ 401 | def pollL(timeout: Long): Task[KafkaConsumerRecords[K,V]] = 402 | Task.handle[KafkaConsumerRecords[K,V]] { handler => 403 | target.poll(timeout, handler) 404 | } 405 | } 406 | 407 | 408 | implicit class VertxKafkaProducerOps[K, V](val target: KafkaProducer[K, V]) { 409 | 410 | def endL(): Task[Unit] = 411 | Task.handle[Void] { arg0 => 412 | target.end(arg0) 413 | }.map(_ => ()) 414 | 415 | 416 | def endL(data: KafkaProducerRecord[K,V]): Task[Unit] = 417 | Task.handle[Void] { handler => 418 | target.end(data, handler) 419 | }.map(_ => ()) 420 | 421 | 422 | def writeL(data: KafkaProducerRecord[K,V]): Task[Unit] = 423 | Task.handle[Void] { handler => 424 | target.write(data, handler) 425 | }.map(_ => ()) 426 | 427 | /** 428 | * Asynchronously write a record to a topic 429 | * @param record record to write 430 | * @param handler handler called on operation completed 431 | * @return current KafkaWriteStream instance 432 | */ 433 | def sendL(record: KafkaProducerRecord[K,V]): Task[RecordMetadata] = 434 | Task.handle[RecordMetadata] { handler => 435 | target.send(record, handler) 436 | } 437 | 438 | /** 439 | * Get the partition metadata for the give topic. 440 | * @param topic topic partition for which getting partitions info 441 | * @param handler handler called on operation completed 442 | * @return current KafkaProducer instance 443 | */ 444 | def partitionsForL(topic: String): Task[List[PartitionInfo]] = 445 | Task.handle[List[PartitionInfo]] { handler => 446 | target.partitionsFor(topic, handler) 447 | } 448 | 449 | /** 450 | * Close the producer 451 | * @param completionHandler handler called on operation completed 452 | */ 453 | def closeL(): Task[Unit] = 454 | Task.handle[Void] { completionHandler => 455 | target.close(completionHandler) 456 | }.map(_ => ()) 457 | 458 | /** 459 | * Close the producer 460 | * @param timeout timeout to wait for closing 461 | * @param completionHandler handler called on operation completed 462 | */ 463 | def closeL(timeout: Long): Task[Unit] = 464 | Task.handle[Void] { completionHandler => 465 | target.close(timeout, completionHandler) 466 | }.map(_ => ()) 467 | } 468 | 469 | 470 | implicit class VertxKafkaAdminClientOps(val target: KafkaAdminClient) extends AnyVal { 471 | /** 472 | * List the topics available in the cluster with the default options. 473 | * @param completionHandler handler called on operation completed with the topics set 474 | */ 475 | def listTopicsL(): Task[Set[String]] = 476 | Task.handle[Set[String]] { completionHandler => 477 | target.listTopics(completionHandler) 478 | } 479 | 480 | /** 481 | * Creates a batch of new Kafka topics 482 | * @param topics topics to create 483 | * @param completionHandler handler called on operation completed 484 | */ 485 | def createTopicsL(topics: List[NewTopic]): Task[Unit] = 486 | Task.handle[Void] { completionHandler => 487 | target.createTopics(topics, completionHandler) 488 | }.map(_ => ()) 489 | 490 | /** 491 | * Deletes a batch of Kafka topics 492 | * @param topicNames the names of the topics to delete 493 | * @param completionHandler handler called on operation completed 494 | */ 495 | def deleteTopicsL(topicNames: List[String]): Task[Unit] = 496 | Task.handle[Void] { completionHandler => 497 | target.deleteTopics(topicNames, completionHandler) 498 | }.map(_ => ()) 499 | 500 | /** 501 | * Get the the consumer groups available in the cluster with the default options 502 | * @param completionHandler handler called on operation completed with the consumer groups ids 503 | */ 504 | def listConsumerGroupsL(): Task[List[ConsumerGroupListing]] = 505 | Task.handle[List[ConsumerGroupListing]] { completionHandler => 506 | target.listConsumerGroups(completionHandler) 507 | } 508 | } 509 | 510 | 511 | } -------------------------------------------------------------------------------- /servicediscovery/generated/vertices/servicediscovery/package.scala: -------------------------------------------------------------------------------- 1 | package vertices 2 | 3 | 4 | import monix.eval.Task 5 | import io.vertx.core.AsyncResult 6 | import io.vertx.core.Handler 7 | import io.vertx.core.Vertx 8 | import io.vertx.core.eventbus.MessageConsumer 9 | import io.vertx.core.http.HttpClient 10 | import io.vertx.core.json.JsonObject 11 | import io.vertx.ext.jdbc.JDBCClient 12 | import io.vertx.ext.mongo.MongoClient 13 | import io.vertx.ext.web.client.WebClient 14 | import io.vertx.redis.RedisClient 15 | import io.vertx.servicediscovery.Record 16 | import io.vertx.servicediscovery.ServiceDiscovery 17 | import io.vertx.servicediscovery.ServiceDiscoveryOptions 18 | import io.vertx.servicediscovery.ServiceReference 19 | import io.vertx.servicediscovery.spi.ServiceExporter 20 | import io.vertx.servicediscovery.spi.ServiceImporter 21 | import io.vertx.servicediscovery.spi.ServicePublisher 22 | import io.vertx.servicediscovery.spi.ServiceType 23 | import io.vertx.servicediscovery.types.HttpEndpoint 24 | import io.vertx.servicediscovery.types.JDBCDataSource 25 | import io.vertx.servicediscovery.types.MessageSource 26 | import io.vertx.servicediscovery.types.MongoDataSource 27 | import io.vertx.servicediscovery.types.RedisDataSource 28 | import java.lang.Boolean 29 | import java.lang.Object 30 | import java.lang.String 31 | import java.lang.Void 32 | import java.util.List 33 | import java.util.Set 34 | import java.util.function.Function 35 | 36 | package object servicediscovery { 37 | 38 | object JDBCDataSourceFunctions { 39 | /** 40 | * Convenient method that looks for a JDBC datasource source and provides the configured {@link io.vertx.ext.jdbc.JDBCClient}. The 41 | * async result is marked as failed is there are no matching services, or if the lookup fails. 42 | * @param discovery The service discovery instance 43 | * @param filter The filter, optional 44 | * @param resultHandler The result handler 45 | */ 46 | def getJDBCClientL(discovery: ServiceDiscovery, filter: JsonObject): Task[JDBCClient] = 47 | Task.handle[JDBCClient] { resultHandler => 48 | JDBCDataSource.getJDBCClient(discovery, filter, resultHandler) 49 | } 50 | 51 | /** 52 | * Convenient method that looks for a JDBC datasource source and provides the configured {@link io.vertx.ext.jdbc.JDBCClient}. The 53 | * async result is marked as failed is there are no matching services, or if the lookup fails. 54 | * @param discovery The service discovery instance 55 | * @param filter The filter (must not be {@code null}) 56 | * @param resultHandler The result handler 57 | */ 58 | def getJDBCClientL(discovery: ServiceDiscovery, filter: Function[Record,Boolean]): Task[JDBCClient] = 59 | Task.handle[JDBCClient] { resultHandler => 60 | JDBCDataSource.getJDBCClient(discovery, filter, resultHandler) 61 | } 62 | 63 | /** 64 | * Convenient method that looks for a JDBC datasource source and provides the configured {@link io.vertx.ext.jdbc.JDBCClient}. The 65 | * async result is marked as failed is there are no matching services, or if the lookup fails. 66 | * @param discovery The service discovery instance 67 | * @param filter The filter, optional 68 | * @param consumerConfiguration the consumer configuration 69 | * @param resultHandler the result handler 70 | */ 71 | def getJDBCClientL(discovery: ServiceDiscovery, filter: JsonObject, consumerConfiguration: JsonObject): Task[JDBCClient] = 72 | Task.handle[JDBCClient] { resultHandler => 73 | JDBCDataSource.getJDBCClient(discovery, filter, consumerConfiguration, resultHandler) 74 | } 75 | 76 | /** 77 | * Convenient method that looks for a JDBC datasource source and provides the configured {@link io.vertx.ext.jdbc.JDBCClient}. The 78 | * async result is marked as failed is there are no matching services, or if the lookup fails. 79 | * @param discovery The service discovery instance 80 | * @param filter The filter, must not be {@code null} 81 | * @param consumerConfiguration the consumer configuration 82 | * @param resultHandler the result handler 83 | */ 84 | def getJDBCClientL(discovery: ServiceDiscovery, filter: Function[Record,Boolean], consumerConfiguration: JsonObject): Task[JDBCClient] = 85 | Task.handle[JDBCClient] { resultHandler => 86 | JDBCDataSource.getJDBCClient(discovery, filter, consumerConfiguration, resultHandler) 87 | } 88 | } 89 | 90 | 91 | object HttpEndpointFunctions { 92 | /** 93 | * Convenient method that looks for a HTTP endpoint and provides the configured {@link HttpClient}. The async result 94 | * is marked as failed is there are no matching services, or if the lookup fails. 95 | * @param discovery The service discovery instance 96 | * @param filter The filter, optional 97 | * @param resultHandler The result handler 98 | */ 99 | def getClientL(discovery: ServiceDiscovery, filter: JsonObject): Task[HttpClient] = 100 | Task.handle[HttpClient] { resultHandler => 101 | HttpEndpoint.getClient(discovery, filter, resultHandler) 102 | } 103 | 104 | /** 105 | * Convenient method that looks for a HTTP endpoint and provides the configured {@linkWebClient}. The async result 106 | * is marked as failed is there are no matching services, or if the lookup fails. 107 | * @param discovery The service discovery instance 108 | * @param filter The filter, optional 109 | * @param resultHandler The result handler 110 | */ 111 | def getWebClientL(discovery: ServiceDiscovery, filter: JsonObject): Task[WebClient] = 112 | Task.handle[WebClient] { resultHandler => 113 | HttpEndpoint.getWebClient(discovery, filter, resultHandler) 114 | } 115 | 116 | /** 117 | * Convenient method that looks for a HTTP endpoint and provides the configured {@link HttpClient}. The async result 118 | * is marked as failed is there are no matching services, or if the lookup fails. This method accepts a 119 | * configuration for the HTTP client 120 | * @param discovery The service discovery instance 121 | * @param filter The filter, optional 122 | * @param conf the configuration of the client 123 | * @param resultHandler The result handler 124 | */ 125 | def getClientL(discovery: ServiceDiscovery, filter: JsonObject, conf: JsonObject): Task[HttpClient] = 126 | Task.handle[HttpClient] { resultHandler => 127 | HttpEndpoint.getClient(discovery, filter, conf, resultHandler) 128 | } 129 | 130 | /** 131 | * Convenient method that looks for a HTTP endpoint and provides the configured {@link WebClient}. The async result 132 | * is marked as failed is there are no matching services, or if the lookup fails. This method accepts a 133 | * configuration for the HTTP client 134 | * @param discovery The service discovery instance 135 | * @param filter The filter, optional 136 | * @param conf the configuration of the client 137 | * @param resultHandler The result handler 138 | */ 139 | def getWebClientL(discovery: ServiceDiscovery, filter: JsonObject, conf: JsonObject): Task[WebClient] = 140 | Task.handle[WebClient] { resultHandler => 141 | HttpEndpoint.getWebClient(discovery, filter, conf, resultHandler) 142 | } 143 | 144 | /** 145 | * Convenient method that looks for a HTTP endpoint and provides the configured {@link HttpClient}. The async result 146 | * is marked as failed is there are no matching services, or if the lookup fails. 147 | * @param discovery The service discovery instance 148 | * @param filter The filter 149 | * @param resultHandler The result handler 150 | */ 151 | def getClientL(discovery: ServiceDiscovery, filter: Function[Record,Boolean]): Task[HttpClient] = 152 | Task.handle[HttpClient] { resultHandler => 153 | HttpEndpoint.getClient(discovery, filter, resultHandler) 154 | } 155 | 156 | /** 157 | * Convenient method that looks for a HTTP endpoint and provides the configured {@link WebClient}. The async result 158 | * is marked as failed is there are no matching services, or if the lookup fails. 159 | * @param discovery The service discovery instance 160 | * @param filter The filter 161 | * @param resultHandler The result handler 162 | */ 163 | def getWebClientL(discovery: ServiceDiscovery, filter: Function[Record,Boolean]): Task[WebClient] = 164 | Task.handle[WebClient] { resultHandler => 165 | HttpEndpoint.getWebClient(discovery, filter, resultHandler) 166 | } 167 | 168 | /** 169 | * Convenient method that looks for a HTTP endpoint and provides the configured {@link HttpClient}. The async result 170 | * is marked as failed is there are no matching services, or if the lookup fails. This method accepts a 171 | * configuration for the HTTP client. 172 | * @param discovery The service discovery instance 173 | * @param filter The filter 174 | * @param conf the configuration of the client 175 | * @param resultHandler The result handler 176 | */ 177 | def getClientL(discovery: ServiceDiscovery, filter: Function[Record,Boolean], conf: JsonObject): Task[HttpClient] = 178 | Task.handle[HttpClient] { resultHandler => 179 | HttpEndpoint.getClient(discovery, filter, conf, resultHandler) 180 | } 181 | 182 | /** 183 | * Convenient method that looks for a HTTP endpoint and provides the configured {@link WebClient}. The async result 184 | * is marked as failed is there are no matching services, or if the lookup fails. This method accepts a 185 | * configuration for the HTTP client. 186 | * @param discovery The service discovery instance 187 | * @param filter The filter 188 | * @param conf the configuration of the client 189 | * @param resultHandler The result handler 190 | */ 191 | def getWebClientL(discovery: ServiceDiscovery, filter: Function[Record,Boolean], conf: JsonObject): Task[WebClient] = 192 | Task.handle[WebClient] { resultHandler => 193 | HttpEndpoint.getWebClient(discovery, filter, conf, resultHandler) 194 | } 195 | } 196 | 197 | 198 | object MessageSourceFunctions { 199 | /** 200 | * Convenient method that looks for a message source and provides the configured {@link MessageConsumer}. The 201 | * async result is marked as failed is there are no matching services, or if the lookup fails. 202 | * @param discovery The service discovery instance 203 | * @param filter The filter, optional 204 | * @param resultHandler The result handler 205 | * @param The class of the message 206 | */ 207 | def getConsumerL[T](discovery: ServiceDiscovery, filter: JsonObject): Task[MessageConsumer[T]] = 208 | Task.handle[MessageConsumer[T]] { resultHandler => 209 | MessageSource.getConsumer(discovery, filter, resultHandler) 210 | } 211 | 212 | /** 213 | * Convenient method that looks for a message source and provides the configured {@link MessageConsumer}. The 214 | * async result is marked as failed is there are no matching services, or if the lookup fails. 215 | * @param discovery The service discovery instance 216 | * @param filter The filter, must not be {@code null} 217 | * @param resultHandler The result handler 218 | * @param The class of the message 219 | */ 220 | def getConsumerL[T](discovery: ServiceDiscovery, filter: Function[Record,Boolean]): Task[MessageConsumer[T]] = 221 | Task.handle[MessageConsumer[T]] { resultHandler => 222 | MessageSource.getConsumer(discovery, filter, resultHandler) 223 | } 224 | } 225 | 226 | 227 | object RedisDataSourceFunctions { 228 | /** 229 | * Convenient method that looks for a Redis data source and provides the configured {@link io.vertx.redis.RedisClient}. 230 | * The async result is marked as failed is there are no matching services, or if the lookup fails. 231 | * @param discovery The service discovery instance 232 | * @param filter The filter, optional 233 | * @param resultHandler The result handler 234 | */ 235 | def getRedisClientL(discovery: ServiceDiscovery, filter: JsonObject): Task[RedisClient] = 236 | Task.handle[RedisClient] { resultHandler => 237 | RedisDataSource.getRedisClient(discovery, filter, resultHandler) 238 | } 239 | 240 | /** 241 | * Convenient method that looks for a Redis data source and provides the configured {@link io.vertx.redis.RedisClient}. 242 | * The async result is marked as failed is there are no matching services, or if the lookup fails. 243 | * @param discovery The service discovery instance 244 | * @param filter The filter, cannot be {@code null} 245 | * @param resultHandler The result handler 246 | */ 247 | def getRedisClientL(discovery: ServiceDiscovery, filter: Function[Record,Boolean]): Task[RedisClient] = 248 | Task.handle[RedisClient] { resultHandler => 249 | RedisDataSource.getRedisClient(discovery, filter, resultHandler) 250 | } 251 | 252 | /** 253 | * Convenient method that looks for a Redis data source and provides the configured {@link io.vertx.redis.RedisClient}. 254 | * The async result is marked as failed is there are no matching services, or if the lookup fails. 255 | * @param discovery The service discovery instance 256 | * @param filter The filter, optional 257 | * @param consumerConfiguration The additional consumer configuration 258 | * @param resultHandler The result handler 259 | */ 260 | def getRedisClientL(discovery: ServiceDiscovery, filter: JsonObject, consumerConfiguration: JsonObject): Task[RedisClient] = 261 | Task.handle[RedisClient] { resultHandler => 262 | RedisDataSource.getRedisClient(discovery, filter, consumerConfiguration, resultHandler) 263 | } 264 | 265 | /** 266 | * Convenient method that looks for a Redis data source and provides the configured {@link io.vertx.redis.RedisClient}. 267 | * The async result is marked as failed is there are no matching services, or if the lookup fails. 268 | * @param discovery The service discovery instance 269 | * @param filter The filter, cannot be {@code null} 270 | * @param consumerConfiguration The additional consumer configuration 271 | * @param resultHandler The result handler 272 | */ 273 | def getRedisClientL(discovery: ServiceDiscovery, filter: Function[Record,Boolean], consumerConfiguration: JsonObject): Task[RedisClient] = 274 | Task.handle[RedisClient] { resultHandler => 275 | RedisDataSource.getRedisClient(discovery, filter, consumerConfiguration, resultHandler) 276 | } 277 | } 278 | 279 | implicit class VertxServiceDiscoveryOps(val target: ServiceDiscovery) extends AnyVal { 280 | /** 281 | * Registers a discovery service importer. Importers let you integrate other discovery technologies in this service 282 | * discovery. 283 | * @param importer the service importer 284 | * @param configuration the optional configuration 285 | * @param completionHandler handler call when the importer has finished its initialization and 286 | * initial imports 287 | * @return the current {@link ServiceDiscovery} 288 | */ 289 | def registerServiceImporterL(importer: ServiceImporter, configuration: JsonObject): Task[Unit] = 290 | Task.handle[Void] { completionHandler => 291 | target.registerServiceImporter(importer, configuration, completionHandler) 292 | }.map(_ => ()) 293 | 294 | /** 295 | * Registers a discovery bridge. Exporters let you integrate other discovery technologies in this service 296 | * discovery. 297 | * @param exporter the service exporter 298 | * @param configuration the optional configuration 299 | * @param completionHandler handler notified when the exporter has been correctly initialized. 300 | * @return the current {@link ServiceDiscovery} 301 | */ 302 | def registerServiceExporterL(exporter: ServiceExporter, configuration: JsonObject): Task[Unit] = 303 | Task.handle[Void] { completionHandler => 304 | target.registerServiceExporter(exporter, configuration, completionHandler) 305 | }.map(_ => ()) 306 | 307 | /** 308 | * Publishes a record. 309 | * @param record the record 310 | * @param resultHandler handler called when the operation has completed (successfully or not). In case of success, 311 | * the passed record has a registration id required to modify and un-register the service. 312 | */ 313 | def publishL(record: Record): Task[Record] = 314 | Task.handle[Record] { resultHandler => 315 | target.publish(record, resultHandler) 316 | } 317 | 318 | /** 319 | * Un-publishes a record. 320 | * @param id the registration id 321 | * @param resultHandler handler called when the operation has completed (successfully or not). 322 | */ 323 | def unpublishL(id: String): Task[Unit] = 324 | Task.handle[Void] { resultHandler => 325 | target.unpublish(id, resultHandler) 326 | }.map(_ => ()) 327 | 328 | /** 329 | * Lookups for a single record. 330 | *

331 | * Filters are expressed using a Json object. Each entry of the given filter will be checked against the record. 332 | * All entry must match exactly the record. The entry can use the special "*" value to denotes a requirement on the 333 | * key, but not on the value. 334 | *

335 | * Let's take some example: 336 | *

337 |      *    { "name" = "a" } => matches records with name set fo "a"
338 |      *    { "color" = "*" } => matches records with "color" set
339 |      *    { "color" = "red" } => only matches records with "color" set to "red"
340 |      *    { "color" = "red", "name" = "a"} => only matches records with name set to "a", and color set to "red"
341 |      *  
342 | *

343 | * If the filter is not set ({@code null} or empty), it accepts all records. 344 | *

345 | * This method returns the first matching record. 346 | * @param filter the filter. 347 | * @param resultHandler handler called when the lookup has been completed. When there are no matching record, the 348 | * operation succeeds, but the async result has no result ({@code null}). 349 | */ 350 | def getRecordL(filter: JsonObject): Task[Record] = 351 | Task.handle[Record] { resultHandler => 352 | target.getRecord(filter, resultHandler) 353 | } 354 | 355 | /** 356 | * Lookups for a single record. 357 | *

358 | * The filter is a {@link Function} taking a {@link Record} as argument and returning a boolean. You should see it 359 | * as an {@code accept} method of a filter. This method return a record passing the filter. 360 | *

361 | * This method only looks for records with a {@code UP} status. 362 | * @param filter the filter, must not be {@code null}. To return all records, use a function accepting all records 363 | * @param resultHandler the result handler called when the lookup has been completed. When there are no matching 364 | * record, the operation succeed, but the async result has no result. 365 | */ 366 | def getRecordL(filter: Function[Record,Boolean]): Task[Record] = 367 | Task.handle[Record] { resultHandler => 368 | target.getRecord(filter, resultHandler) 369 | } 370 | 371 | /** 372 | * Lookups for a single record. 373 | *

374 | * The filter is a {@link Function} taking a {@link Record} as argument and returning a boolean. You should see it 375 | * as an {@code accept} method of a filter. This method return a record passing the filter. 376 | *

377 | * Unlike {@link #getRecord(Function, Handler)}, this method may accept records with a {@code OUT OF SERVICE} 378 | * status, if the {@code includeOutOfService} parameter is set to {@code true}. 379 | * @param filter the filter, must not be {@code null}. To return all records, use a function accepting all records 380 | * @param includeOutOfService whether or not the filter accepts {@code OUT OF SERVICE} records 381 | * @param resultHandler the result handler called when the lookup has been completed. When there are no matching 382 | * record, the operation succeed, but the async result has no result. 383 | */ 384 | def getRecordL(filter: Function[Record,Boolean], includeOutOfService: Boolean): Task[Record] = 385 | Task.handle[Record] { resultHandler => 386 | target.getRecord(filter, includeOutOfService, resultHandler) 387 | } 388 | 389 | /** 390 | * Lookups for a set of records. Unlike {@link #getRecord(JsonObject, Handler)}, this method returns all matching 391 | * records. 392 | * @param filter the filter - see {@link #getRecord(JsonObject, Handler)} 393 | * @param resultHandler handler called when the lookup has been completed. When there are no matching record, the 394 | * operation succeed, but the async result has an empty list as result. 395 | */ 396 | def getRecordsL(filter: JsonObject): Task[List[Record]] = 397 | Task.handle[List[Record]] { resultHandler => 398 | target.getRecords(filter, resultHandler) 399 | } 400 | 401 | /** 402 | * Lookups for a set of records. Unlike {@link #getRecord(Function, Handler)}, this method returns all matching 403 | * records. 404 | *

405 | * The filter is a {@link Function} taking a {@link Record} as argument and returning a boolean. You should see it 406 | * as an {@code accept} method of a filter. This method return a record passing the filter. 407 | *

408 | * This method only looks for records with a {@code UP} status. 409 | * @param filter the filter, must not be {@code null}. To return all records, use a function accepting all records 410 | * @param resultHandler handler called when the lookup has been completed. When there are no matching record, the 411 | * operation succeed, but the async result has an empty list as result. 412 | */ 413 | def getRecordsL(filter: Function[Record,Boolean]): Task[List[Record]] = 414 | Task.handle[List[Record]] { resultHandler => 415 | target.getRecords(filter, resultHandler) 416 | } 417 | 418 | /** 419 | * Lookups for a set of records. Unlike {@link #getRecord(Function, Handler)}, this method returns all matching 420 | * records. 421 | *

422 | * The filter is a {@link Function} taking a {@link Record} as argument and returning a boolean. You should see it 423 | * as an {@code accept} method of a filter. This method return a record passing the filter. 424 | *

425 | * Unlike {@link #getRecords(Function, Handler)}, this method may accept records with a {@code OUT OF SERVICE} 426 | * status, if the {@code includeOutOfService} parameter is set to {@code true}. 427 | * @param filter the filter, must not be {@code null}. To return all records, use a function accepting all records 428 | * @param includeOutOfService whether or not the filter accepts {@code OUT OF SERVICE} records 429 | * @param resultHandler handler called when the lookup has been completed. When there are no matching record, the 430 | * operation succeed, but the async result has an empty list as result. 431 | */ 432 | def getRecordsL(filter: Function[Record,Boolean], includeOutOfService: Boolean): Task[List[Record]] = 433 | Task.handle[List[Record]] { resultHandler => 434 | target.getRecords(filter, includeOutOfService, resultHandler) 435 | } 436 | 437 | /** 438 | * Updates the given record. The record must has been published, and has it's registration id set. 439 | * @param record the updated record 440 | * @param resultHandler handler called when the lookup has been completed. 441 | */ 442 | def updateL(record: Record): Task[Record] = 443 | Task.handle[Record] { resultHandler => 444 | target.update(record, resultHandler) 445 | } 446 | } 447 | 448 | 449 | 450 | object MongoDataSourceFunctions { 451 | /** 452 | * Convenient method that looks for a Mongo datasource source and provides the configured {@link io.vertx.ext.mongo.MongoClient}. The 453 | * async result is marked as failed is there are no matching services, or if the lookup fails. 454 | * @param discovery The service discovery instance 455 | * @param filter The filter, optional 456 | * @param resultHandler The result handler 457 | */ 458 | def getMongoClientL(discovery: ServiceDiscovery, filter: JsonObject): Task[MongoClient] = 459 | Task.handle[MongoClient] { resultHandler => 460 | MongoDataSource.getMongoClient(discovery, filter, resultHandler) 461 | } 462 | 463 | /** 464 | * Convenient method that looks for a Mongo datasource source and provides the configured 465 | * {@link io.vertx.ext.mongo.MongoClient}. The 466 | * async result is marked as failed is there are no matching services, or if the lookup fails. 467 | * @param discovery The service discovery instance 468 | * @param filter The filter 469 | * @param resultHandler The result handler 470 | */ 471 | def getMongoClientL(discovery: ServiceDiscovery, filter: Function[Record,Boolean]): Task[MongoClient] = 472 | Task.handle[MongoClient] { resultHandler => 473 | MongoDataSource.getMongoClient(discovery, filter, resultHandler) 474 | } 475 | 476 | /** 477 | * Convenient method that looks for a Mongo datasource source and provides the configured {@link io.vertx.ext.mongo.MongoClient}. The 478 | * async result is marked as failed is there are no matching services, or if the lookup fails. 479 | * @param discovery The service discovery instance 480 | * @param filter The filter, optional 481 | * @param consumerConfiguration the consumer configuration 482 | * @param resultHandler the result handler 483 | */ 484 | def getMongoClientL(discovery: ServiceDiscovery, filter: JsonObject, consumerConfiguration: JsonObject): Task[MongoClient] = 485 | Task.handle[MongoClient] { resultHandler => 486 | MongoDataSource.getMongoClient(discovery, filter, consumerConfiguration, resultHandler) 487 | } 488 | } 489 | 490 | implicit class VertxServicePublisherOps(val target: ServicePublisher) extends AnyVal { 491 | /** 492 | * Publishes a record. 493 | * @param record the record 494 | * @param resultHandler handler called when the operation has completed (successfully or not). In case of success, 495 | * the passed record has a registration id required to modify and un-register the service. 496 | */ 497 | def publishL(record: Record): Task[Record] = 498 | Task.handle[Record] { resultHandler => 499 | target.publish(record, resultHandler) 500 | } 501 | 502 | /** 503 | * Un-publishes a record. 504 | * @param id the registration id 505 | * @param resultHandler handler called when the operation has completed (successfully or not). 506 | */ 507 | def unpublishL(id: String): Task[Unit] = 508 | Task.handle[Void] { resultHandler => 509 | target.unpublish(id, resultHandler) 510 | }.map(_ => ()) 511 | 512 | /** 513 | * Updates an existing record. 514 | * @param record the record 515 | * @param resultHandler handler called when the operation has completed (successfully or not). In case of success, 516 | * the passed record has a registration id required to modify and un-register the service. 517 | */ 518 | def updateL(record: Record): Task[Record] = 519 | Task.handle[Record] { resultHandler => 520 | target.update(record, resultHandler) 521 | } 522 | } 523 | 524 | 525 | } --------------------------------------------------------------------------------