Skip to content

GuicedEE/Guiced-Vert.x

Folders and files

NameName
Last commit message
Last commit date

Latest commit

Β 

History

89 Commits
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 

Repository files navigation

Guiced Vert.x

Build Maven Central Snapshot License

Java 25+ Guice 7 Vert.X 5 Maven 4

Guice-first integration layer for Vert.x 5. Bootstraps Vert.x from the GuicedEE lifecycle, wires verticles and event-bus endpoints through dependency injection, and supplies codecs and Mutiny-friendly helpers so you can stay inside one DI container while building reactive services.

✨ Features

  • Vert.x lifecycle managed by GuicedEE β€” Vertx is injected everywhere via VertXModule
  • Annotation-driven consumers β€” @VertxEventDefinition + @VertxEventOptions with worker threads, instance counts, local-only, and backpressure hints
  • Injectable publishers β€” @Named or @VertxEventDefinition, returning Vert.x Future or Mutiny Uni
  • Automatic JSON mapping β€” codec registration through CodecRegistry and Jackson
  • Per-address consumer verticles β€” each consumer runs in its own dedicated verticle
  • Publisher-side throttling β€” FIFO queuing with configurable rate, no message loss
  • Runtime configuration β€” annotations (@VertX, @EventBusOptions, @FileSystemOptions, @MetricsOptions) plus SPI hooks (VertxConfigurator, ClusterVertxConfigurator, VerticleStartup)
  • Authentication & Authorization β€” annotation-driven auth via @AuthOptions with ChainAuth, KeyStoreOptions, PubSecKeyOptions, PRNG, and SPI-based provider registration

πŸ“¦ Installation

<dependency>
  <groupId>com.guicedee</groupId>
  <artifactId>vertx</artifactId>
</dependency>
Gradle (Kotlin DSL)
implementation("com.guicedee:guiced-vertx:2.0.1-SNAPSHOT")

πŸš€ Quick Start

Bootstrapping is automatic β€” call IGuiceContext.instance().inject() and VertXModule is discovered via SPI:

IGuiceContext.registerModuleForScanning.add("my.app");
IGuiceContext.instance();

Tune Vert.x at the package or type level:

@VertX(workerPoolSize = 32, haEnabled = true)
@EventBusOptions(clusterPublicHost = "127.0.0.1", preferNativeTransport = true)
class VertxRuntimeConfig {}

πŸ“₯ Declaring Consumers

Method-based consumers are the preferred style β€” the registry scans your classpath and binds them automatically:

import io.smallrye.mutiny.Uni;

public class GreetingConsumers {

    @VertxEventDefinition(value = "greeting.received",
            options = @VertxEventOptions(worker = true))
    public String handleGreeting(Message<Anything> message) {
        return "Hello " + message.body();
    }

    @VertxEventDefinition("user.created")
    public Uni<Void> trackUser(Anything payload) {
        return Uni.createFrom().voidItem();
    }
}

Processing model

  • One verticle per address β€” VertxConsumersStartup deploys an EventConsumerVerticle for every discovered event address
  • Scaling β€” @VertxEventOptions.instances() > 1 deploys multiple consumer verticles with round-robin
  • Worker execution β€” options.worker() dispatches off the event loop to a named worker pool
  • Local-only β€” options.localOnly() registers a local consumer inside its per-address verticle
  • Type mapping β€” non-Vert.x parameter types are mapped automatically via Jackson

πŸ“€ Publishing Events

Inject a publisher using @Named:

import io.smallrye.mutiny.Uni;

public class GreetingPublisher {

    @Inject
    @Named("greeting.received")
    private VertxEventPublisher<String> publisher;

    public Uni<String> greet(String name) {
        return publisher.send(name);       // request/response
    }

    public void broadcast(UserCreated event) {
        publisher.publish(event);           // fire to all consumers
    }
}

Throttling

Publisher-side throttling prevents flooding without message loss:

  • publish() and fire-and-forget send() are enqueued (FIFO) and drained at a configurable rate (default 50 ms)
  • request() remains immediate β€” no timeouts introduced
  • Per-instance queues β€” each publisher throttles independently
Environment variable Default Purpose
VERTX_PUBLISH_THROTTLE_MS 50 Global throttle period (0 = disabled)
VERTX_PUBLISH_THROTTLE_MS_<ADDR> β€” Per-address override
VERTX_PUBLISH_QUEUE_WARN 1000 Backlog warning threshold
VERTX_PUBLISH_QUEUE_WARN_<ADDR> β€” Per-address warning threshold

Address normalization: upper-case, replace . and - with _ (e.g. orders.events β†’ ORDERS_EVENTS)

βš™οΈ Runtime Overrides

Override event bus addresses and consumer options at runtime via system properties or environment variables:

Variable Type Purpose
VERTX_EVENT_ADDRESS_<ADDR> string Override the resolved address
VERTX_EVENT_LOCAL_ONLY boolean Force local-only consumers
VERTX_EVENT_CONSUMER_COUNT int Default consumer count
VERTX_EVENT_WORKER boolean Default worker mode
VERTX_EVENT_WORKER_POOL string Worker pool name
VERTX_EVENT_WORKER_POOL_SIZE int Worker pool size
VERTX_EVENT_INSTANCES int Verticle instances per address
VERTX_EVENT_TIMEOUT_MS long Consumer timeout
VERTX_EVENT_BATCH_WINDOW_MS int Batch window
VERTX_EVENT_BATCH_MAX int Max batch size
VERTX_EVENT_MAX_BUFFERED_MESSAGES int Backpressure buffer limit
VERTX_EVENT_RESUME_AT_MESSAGES int Resume threshold

πŸ” Authentication & Authorization

Built-in support for Vert.x Common Auth β€” annotation-driven configuration with Guice injection for all auth types.

Quick Setup

Place @AuthOptions on a class or package-info.java:

@AuthOptions(
    chainMode = AuthOptions.ChainMode.ANY,
    keyStore = @AuthKeyStore(
        path = "/path/to/keystore.pkcs12",
        type = "pkcs12",
        password = "changeit"
    ),
    pubSecKeys = {
        @AuthPubSecKey(algorithm = "RS256", path = "/path/to/public.pem")
    },
    prngAlgorithm = "SHA1PRNG",
    leeway = 5
)
package com.example.auth;

Authentication Providers (SPI)

Register custom authentication providers via IGuicedAuthenticationProvider:

public class MyAuthProvider implements IGuicedAuthenticationProvider {
    @Override
    public AuthenticationProvider getAuthenticationProvider() {
        // Return your provider implementation
        // e.g. UsernamePasswordCredentials-based, JWT, OAuth2, etc.
        return myProvider;
    }
}

Register in module-info.java:

provides IGuicedAuthenticationProvider with MyAuthProvider;

Multiple providers are combined via ChainAuth (ANY = first match wins, ALL = all must pass).

Authorization Providers (SPI)

Register custom authorization providers via IGuicedAuthorizationProvider:

public class MyAuthzProvider implements IGuicedAuthorizationProvider {
    @Override
    public AuthorizationProvider getAuthorizationProvider() {
        return myAuthorizationProvider;
    }
}

Guice Bindings

Type Scope Description
AuthenticationProvider Singleton Primary provider (or ChainAuth if multiple)
ChainAuth Singleton The authentication chain
AuthorizationProvider Singleton Primary authorization provider
Set<AuthorizationProvider> Multibinder All registered authorization providers
VertxContextPRNG Singleton Shared PRNG (non-blocking, event-loop safe)
KeyStoreOptions Instance JVM keystore config (if configured)
Set<PubSecKeyOptions> Multibinder PEM key configs (if configured)

Using Authentication

public class LoginService {
    @Inject private AuthenticationProvider authProvider;

    public Future<User> login(String username, String password) {
        return authProvider.authenticate(
            new UsernamePasswordCredentials(username, password));
    }
}

Using Authorization

Vert.x provides multiple authorization types:

// Role-based
RoleBasedAuthorization.create("admin").match(user);

// Permission-based
PermissionBasedAuthorization.create("printer:print").match(user);

// Wildcard permission
WildcardPermissionBasedAuthorization.create("printer:*").match(user);

// Logical combinations
AndAuthorization.create()
    .addAuthorization(RoleBasedAuthorization.create("admin"))
    .addAuthorization(PermissionBasedAuthorization.create("users:write"));

OrAuthorization.create()
    .addAuthorization(RoleBasedAuthorization.create("admin"))
    .addAuthorization(RoleBasedAuthorization.create("manager"));

NotAuthorization.create(RoleBasedAuthorization.create("guest"));

Load authorizations onto a user:

@Inject private Set<AuthorizationProvider> authzProviders;

public Future<Void> loadAuthorizations(User user) {
    List<Future<Void>> futures = authzProviders.stream()
        .map(p -> p.getAuthorizations(user))
        .toList();
    return Future.all(futures).mapEmpty();
}

User Principal & Attributes

// Access principal data (source identity)
JsonObject principal = user.principal();

// Access computed attributes
JsonObject attributes = user.attributes();

// Unified lookup (attributes first, then principal)
if (user.containsKey("sub")) {
    String sub = user.get("sub");
}

// Token expiration (exp, iat, nbf with leeway)
boolean expired = user.expired();

PRNG (Pseudo Random Number Generator)

The shared VertxContextPRNG is event-loop safe and injectable:

@Inject private VertxContextPRNG prng;

String token = prng.nextString(32);
int randomInt = prng.nextInt();

Configure via annotation or environment variables:

Attribute Variable Default System Property
prngAlgorithm VERTX_AUTH_PRNG_ALGORITHM (system) io.vertx.ext.auth.prng.algorithm
prngSeedInterval VERTX_AUTH_PRNG_SEED_INTERVAL 300000 ms io.vertx.ext.auth.prng.seed.interval
prngSeedBits VERTX_AUTH_PRNG_SEED_BITS 64 io.vertx.ext.auth.prng.seed.bits

Working with Keys

JVM KeyStore (pkcs12, jks):

@AuthOptions(keyStore = @AuthKeyStore(
    path = "/path/to/keystore.pkcs12",
    type = "pkcs12",
    password = "changeit",
    alias = "mykey",
    aliasPassword = "keypass"
))

Import PEM to PKCS12: openssl pkcs12 -export -in cert.pem -out keystore.pkcs12 -name myAlias -noiter -nomaciter

PEM Keys (PKCS8 format):

@AuthOptions(pubSecKeys = {
    @AuthPubSecKey(algorithm = "RS256", path = "/path/to/public.pem"),
    @AuthPubSecKey(algorithm = "ES256", buffer = "-----BEGIN PUBLIC KEY-----\n...")
})

Convert to PKCS8: openssl pkcs8 -topk8 -inform PEM -in private.pem -out private_key.pem -nocrypt

Environment Variable Overrides

Property Variable
chainMode() VERTX_AUTH_CHAIN_MODE
keyStore.path() VERTX_AUTH_KEYSTORE_PATH
keyStore.type() VERTX_AUTH_KEYSTORE_TYPE
keyStore.password() VERTX_AUTH_KEYSTORE_PASSWORD
keyStore.alias() VERTX_AUTH_KEYSTORE_ALIAS
keyStore.aliasPassword() VERTX_AUTH_KEYSTORE_ALIAS_PASSWORD
pubSecKeys[n].algorithm() VERTX_AUTH_PUBSECKEY_n_ALGORITHM
pubSecKeys[n].buffer() VERTX_AUTH_PUBSECKEY_n_BUFFER
pubSecKeys[n].path() VERTX_AUTH_PUBSECKEY_n_PATH
prngAlgorithm() VERTX_AUTH_PRNG_ALGORITHM
prngSeedInterval() VERTX_AUTH_PRNG_SEED_INTERVAL
prngSeedBits() VERTX_AUTH_PRNG_SEED_BITS
leeway() VERTX_AUTH_LEEWAY

πŸ”„ Startup Flow

flowchart TD
    n1["IGuiceContext.instance()"]
    n2["VertXPreStartup        β†’ builds Vertx, scans events, registers codecs"]
    n1 --> n2
    n3["VertxAuthPreStartup    β†’ scans @AuthOptions, discovers auth/authz providers,"]
    n1 --> n3
    n4["builds ChainAuth, configures PRNG and key stores"]
    n3 --> n4
    n5["VerticleBuilder     β†’ deploys app verticles from @Verticle annotations"]
    n3 --> n5
    n6["VertxConsumersStartup β†’ deploys one EventConsumerVerticle per address"]
    n5 --> n6
Loading

πŸ”Œ SPI Hooks

SPI Purpose
VertxConfigurator Customize VertxOptions during startup
ClusterVertxConfigurator Configure clustering
VerticleStartup Register custom verticles from Guice
IGuicedAuthenticationProvider Contribute authentication providers to ChainAuth
IGuicedAuthorizationProvider Contribute authorization providers

πŸ—ΊοΈ Module Graph

flowchart LR
    com_guicedee_vertx["com.guicedee.vertx"]
    com_guicedee_vertx --> com_guicedee_client["com.guicedee.client<br/>SPI contracts"]
    com_guicedee_vertx --> com_guicedee_jsonrepresentation["com.guicedee.jsonrepresentation<br/>JSON codec support"]
    com_guicedee_vertx --> io_vertx_core["io.vertx.core<br/>Vert.x runtime"]
    com_guicedee_vertx --> io_vertx_auth_common["io.vertx.auth.common<br/>Authentication & Authorization"]
    com_guicedee_vertx --> io_vertx_mutiny["io.vertx.mutiny<br/>Mutiny bindings"]
    com_guicedee_vertx --> io_smallrye_mutiny["io.smallrye.mutiny<br/>reactive streams"]
    com_guicedee_vertx --> io_github_classgraph["io.github.classgraph<br/>annotation scanning"]
    com_guicedee_vertx --> com_fasterxml_jackson_databind["com.fasterxml.jackson.databind<br/>JSON mapping"]
Loading

🀝 Contributing

Issues and pull requests are welcome β€” please add tests for new event patterns, codecs, or configurators.

πŸ“„ License

Apache 2.0

About

A Guiced up implementation of services running on Vert.x

Resources

License

Stars

Watchers

Forks

Releases

No releases published

Packages

 
 
 

Contributors

Languages