A reactive dataflow engine, a data stream processing framework using Vert.x

Overview

🐝 NeonBee Core

Discord REUSE status Coverage

NeonBee is an open source reactive dataflow engine, a data stream processing framework using Vert.x.

Description

NeonBee abstracts most of Vert.x's low-level functionality by adding an application layer for modeling a dataflow, data stream processing and for doing data consolidation, exposing everything via standardized APIs in form of interfaces called endpoints.

Additionally NeonBee takes care of all the execution and comes bundled with a full-blown application server with all the core capabilities of Vert.x at hand but without you having to care about things like a boot sequence, command line parsing, configuration, monitoring, clustering, deployment, scaling, logging / log handling and much more. Additionally, we put a rich convenience layer for data handling on top, simplifying technical data exchange.

To achieve this simplification, NeonBee reduces the scope of Vert.x by choosing and picking the most appropriate core and extensions components of Vert.x and providing them in a pre-configured / application server like fashion. For example, NeonBee comes with a default configuration of the SLF4J logging facade and Logback logging backend, so you won't have to deal with choosing and configuring the logging environment in the first place. However, in case you decide to go with the logging setup NeonBee provides, you are still free to change.

Core Components

To facilitate the true nature of NeonBee, it features a certain set of core components, abstracting and thus simplifying the naturally broad spectrum of the underlying Vert.x framework components:

  • Server: boot sequence (read config, deploy verticles & data models, start instance), master / slave handling, etc.
  • Command Line: CLI argument parsing, using Vert.x CLI API
  • Configuration: YAML config, using Vert.x Config
  • Monitoring: Using Micrometer.io API and Prometheus
  • Clustering: Clustered operation using any Cluster Manager
  • Deployment: Automated deployment of verticles and data model elements
  • Supervisor & Scaling: Automated supervision and scaling of verticles
  • Logging: Using the Vert.x Logging and SLF4J facades and Logback as a back end
  • Authentication: Configurable authentication chain using Vert.x Auth

Dataflow Processing

While you may just use the NeonBee core components to consume functionalities of Vert.x more easily, the main focus of NeonBee lies on data processing via its stream design. Thus, NeonBee adds a sophisticated high-performance data processing interface you can easily extend plug-and-play. The upcoming sections describe how to use NeonBees data processing capabilities hands-on. In case you would like to understand the concept of NeonBees dataflow processing more in detail, for instance on how different resolution strategies can be utilized, for a highly optimized traversal of the data tree, please have a look at this document explaining the theory behind NeonBees data processing.

Data Verticles / Sources

The main component for data processing is more or less a specialization of the verticle concept of Vert.x. NeonBee introduces a new AbstractVerticle implementation called DataVerticle. These types of verticles implement a very simple data processing interface and communicate between each other using the Vert.x Event Bus. Processing data using the DataVerticle becomes a piece of cake. Data retrieval was split in two phases or tasks:

  1. Require: Each verticle first announces the data it requires from other even multiple DataVerticle for processing the request. NeonBee will, depending on the resolution strategy (see below), attempt to pre-fetch all required data, before invoking the next phase of data processing.
  2. Retrieve: In the retrieval phase, the verticle either processes all the data it requested in the previous require processing phase, or it perform arbitrary actions, such as doing a database calls, or plain data processing, mapping, etc.

Conveniently, the method signatures of DataVerticle are named exactly like that. So, it is very easy to request / consolidate / process data from many different sources in a highly efficient manner.

During either phase, data can be requested from other verticles or arbitrary data sources, however, it is to note that those kinds of requests start spanning a new three, thus they can only again be optimized according to the chosen resolution strategy in their sub-tree. It is best to stick with one require / retrieval phase for one request / data stream, however it could become necessary mixing different strategies to achieve the optimal result, depending on the use case.

Entity Verticles & Data Model

Entity verticles are an even more specific abstraction of the data verticle concept. While data verticles can really deal with any kind of data, for data processing it is mostly more convenient to know how the data is structured. To define the data structure, NeonBee utilizes the OASIS Open Data Protocol (OData) 4.0 standard, which is also internationally certified by ISO/IEC.

OData 4.0 defines the structure of data in so-called models. In NeonBee, models can be easily defined using the Core Data and Services (CDS) Definition Language. CDS provide a human-readable syntax for defining models. These models can then be interpreted by NeonBee to build valid OData 4.0 entities.

For processing entities, NeonBee uses the Apache Olingo™ library. Entity verticles are essentially data verticles dealing with Olingo entities. This provides NeonBee the possibility to expose these entity verticles in a standardized OData endpoint, as well as to perform many optimizations when data is processed.

Data Endpoints

Endpoints are standardized interfaces provided by NeonBee. Endpoints call entry verticles (see dataflow processing) to fetch / write back data. Depending on the type of endpoint, different APIs like REST, OData, etc. will be provided and a different set of verticles gets exposed. Given the default configuration, NeonBee will expose two simplified HTTP endpoints:

  • A /raw HTTP REST endpoint that returns the data of any data verticle, preferably in a JSON format and
  • a standardized /odata HTTP endpoint to get a valid OData response from entity verticles.

Getting Started

The NeonBee data processing framework can be started like any other ordinary application server by using the start-up scripts provided in the root folder of NeonBee. By default, the boot sequence will check for verticles in the /verticles directory as well as from any remote source configured and deploy all these verticles automatically. This can be customized via command line and via a central configuration file in the /config directory. Also, the data model definition can be updated / loaded during runtime. To do so, valid CDS files must be put into the /models directory.

Writing Your First Data Verticles

Writing a DataVerticle is a piece of cake. Imagine one of your verticles reads customer data from a database, while another verticle should do the processing of it. Let's start with the database verticle:

public class DatabaseVerticle extends DataVerticle<JsonArray> {
    @Override
    public String getName() {
        return "Database";
    }

    @Override
    public Future<JsonArray> retrieveData(DataQuery query, DataContext context) {
        // return a future to a JsonArray here, e.g. by connecting to the database
        return Future.succeededFuture(new JsonArray()
            .add(new JsonObject().put("Id", 1).put("Name", "Customer A"))
            .add(new JsonObject().put("Id", 2).put("Name", "Customer B")));
    }
}

Note how the first verticle returns the name Database. By default, the name is set to the full qualified name of the class. We just return a name here to make the implementation of our processing verticle easier. We create a second data verticle called ProcessingVerticle. In order for the processing verticle to get data from the database verticle, a DataRequest can be returned from the processing verticles requireData method. NeonBee will try resolve all the dependencies of a data verticle, before invoking the verticles retrieveData method. This way it becomes very easy to request some data from another data verticle.

public class ProcessingVerticle extends DataVerticle<JsonArray> {
    @Override
    public String getName() {
        return "CustomerData";
    }

    @Override
    public Future<Collection<DataRequest>> requireData(DataQuery query, DataContext context) {
        return Future.succeededFuture(List.of(new DataRequest("Database", query)));
    }

    @Override @SuppressWarnings("unchecked")
    public Future<JsonArray> retrieveData(DataQuery query, DataMap require, DataContext context) {
        AsyncResult<JsonArray> databaseResult = require.<JsonArray>findFirst("Database").orElse(null);
        if (databaseResult.failed()) {
            // retrieving data from the database failed
            return Future.failedFuture(databaseResult.cause());
        }

        // reverse the database result or do any other more reasonable processing ;-)
        List<Object> reversedDatabaseResult = new ArrayList<>();
        new ArrayDeque<Object>(databaseResult.result().getList())
            .descendingIterator()
            .forEachRemaining(reversedDatabaseResult::add);

        return Future.succeededFuture(new JsonArray(reversedDatabaseResult));
    }
}

And that's it. Deploy your verticles by simply putting a JAR file of them into NeonBees /verticles directory. We will soon release a sample repository on how to build a compliant JAR file. Compliant JAR files refer to so called "modules". A module JAR is a fat / ueber JAR, which comes with any dependencies of the verticle, excluding NeonBee / Vert.x dependencies which are provided by the framework.

Start-up the server, on its default port you can fetch the data of your verticle via the raw endpoint at http://localhost:8080/raw/CustomerData/. NeonBee can easily run this verticle in a highly scalable cluster setup out of the box.

Advancing to Entity Verticles

Dealing with plain data verticles is great if you control who consumes the data and own all interfaces. The downside of data verticles is that they do not provide a structured and obliging interface, but if e.g. announcing to expose JsonObject the given JSON object could have any structure. In case you want to provide a public interface or simply need more control over the data returned, dealing with raw JSON, strings or even binary, gets a bit more troublesome.

NeonBee covers that with the concept of EntityVerticle an extension to the DataVerticle concept. Let's define a very simple data model using the CDS Definition Language first:

namespace MyModel;

entity Customers {
    key Id : Integer;
    Name : String;
}

Compile the CDS definition to EDMX.

Put the .cds and the resulting .edmx file in the /models directory of NeonBee. The OData endpoint now already knows about the Customers entity. The last thing to do is to actually define an EntityVerticle which returns the entity data on request:

public class CustomerEntityVerticle extends EntityVerticle {
    @Override
    public Future<Set<FullQualifiedName>> entityTypeNames() {
        return Set.of(new FullQualifiedName("MyModel", "Customers"));
    }

    @Override
    public Future<Collection<DataRequest>> requireData(DataQuery query, DataContext context) {
        return Future.succeededFuture(List.of(new DataRequest("CustomerData", query)));
    }

    @Override
    public Future<EntityWrapper> retrieveData(DataQuery query, DataMap require, DataContext context) {
        List<Entity> entities = new ArrayList<>();

        for (Object object : require.<JsonArray>resultFor("CustomerData")) {
            JsonObject jsonObject = (JsonObject) object;

            Entity entity = new Entity();
            entity.addProperty(new Property(null, "Id", ValueType.PRIMITIVE, jsonObject.getValue("Id")));
            entity.addProperty(new Property(null, "Name", ValueType.PRIMITIVE, jsonObject.getValue("Name")));
            entities.add(entity);
        }

        return Future.succeededFuture(new EntityWrapper(new FullQualifiedName("MyModel", "Customers"), entities));
    }
}

And that's it. You have created your first valid OData 4.0 endpoint in NeonBee. With the default configuration access the entity at http://localhost:8080/odata/Customers/. Similarly to data verticles the OData endpoint and your entity is now available and is highly scalable by NeonBee.

For Your Convenience

NeonBee provides further simplifications when dealing with verticle development.

Especially in large-scale distributed systems, correlating log messages become crucial to reproduce what is actually going on. Conveniently, NeonBee offers a simple LoggingFacade which masks the logging interface with:

// alternatively you can use the masqueradeLogger method,
// to use the facade on an existing SF4J logger
LoggingFacade logger = LoggingFacade.create();

logger.correlateWith(context).info("Hello NeonBee");

The logger gets correlated with a correlated ID passed through the routing context. In the default implementation of NeonBees logging facade, the correlation ID will be logged alongside the actual message as a so-called marker and can easily be used to trace a certain log message, even in distributed clusters. Note that the correlateWith method does not actually correlate the whole logging facade, but only the next message logged. This means you have to invoke the correlateWith method once again when the next message is logged.

Similar to Vert.x's shared instance, NeonBee provides its own shared instance holding some additional properties, such as the NeonBee options and configuration objects, as well as general purpose local and cluster-wide shared map for you to use. Each NeonBee instance has a one to one relation to a given Vert.x instance. To retrieve the NeonBee instance from anywhere, just use the static NeonBee.neonbee method of the NeonBee main class:

NeonBee neonbee = NeonBee.neonbee(vertx);

// get access to the NeonBee CLI options
NeonBeeOptions options = neonbee.getOptions();

// general purpose shared local / async (cluster-wide) maps
LocalMap<String, Object> sharedLocalMap = neonbee.getLocalMap();
AsyncMap<String, Object> sharedAsyncMap = neonbee.getAsyncMap();

Our Road Ahead

We have ambitious plans for NeonBee and would like to extend it to be able to provide a whole platform for dataflow / data stream processing. Generalizing endpoints, so further interfaces like OpenAPI can be provided or extending the data verticle concept by more optimized / non-deterministic resolution strategies are only two of them. Please have a look at our roadmap for an idea on what we are planning to do next.

Contributing

If you have suggestions how NeonBee could be improved, or want to report a bug, read up on our guidelines for contributing to learn about our submission process, coding rules and more.

We'd love all and any contributions.

Comments
  • feat: extend DataException and return DataException via eventbus

    feat: extend DataException and return DataException via eventbus

    Currently DataException only allows propagation of one error message. The intention is to add an failureDetail message to be able to propagate source error messages to the invoker, but should not be exposed to the consumer. A message codec for DataException is provided to allow serialization/deserialization of DataException objects via the event bus.

    opened by dapeng-wang 14
  • feat: add custom micrometer registries via NeonBeeConfig

    feat: add custom micrometer registries via NeonBeeConfig

    With this change the config parameter micrometerRegistries is introduced which allows the user to specify a list of (full qualified) class names, which must implement the load() method of the functional interface MicrometerRegistryLoader. The load method must return a MeterRegistry, which will be added to the micrometer registries by NeonBee. The PrometheusMeterRegistry will be the default registry, which is only available when the MetricsEndpoint is loaded.

    opened by s4heid 6
  • feat: add a ImmutableBuffer

    feat: add a ImmutableBuffer

    ImmutableBuffer throws a UnsupportedOperationException for anything that writes to the buffer. This disadvantage is compensated by the advantage the ImmutableBuffer can be transfered over the local event bus very efficiently without beeing copied.

    opened by kristian 5
  • fix: enable tests to run in intellij idea with coverage

    fix: enable tests to run in intellij idea with coverage

    IntelliJ IDEA seems to inject a bunch of libraries to the classpath/classloader when running tests in coverage mode. This leads to issues when running tests where classpath scanning is involved, because for example classes like org.jetbrains.coverage.org.objectweb.asm.ClassReader and org.jetbrains.coverage.org.objectweb.asm.Opcodes (as well as many more) are found during the classpath scan even if they not match the lookup criteria.

    Therefore the list of found files is filtered to clean it up from IntelliJ IDEA injected classes.

    Steps to reproduce:

    • open neonbee-core project in IntelliJ IDEA
    • right click io.neonbee.internal.scanner.ClassPathScannerTest
    • select "More Run/Debug" -> "Run 'ClassPathScannerTest' with Coverage
    • see that the "scanForAnnotation" test is failing

    Console output:

    unexpected (2): org.jetbrains.coverage.org.objectweb.asm.Opcodes, org.jetbrains.coverage.org.objectweb.asm.ClassReader
    ---
    expected      : [field.Hodor]
    but was       : [org.jetbrains.coverage.org.objectweb.asm.Opcodes, field.Hodor, org.jetbrains.coverage.org.objectweb.asm.ClassReader]
    java.lang.AssertionError: unexpected (2): org.jetbrains.coverage.org.objectweb.asm.Opcodes, org.jetbrains.coverage.org.objectweb.asm.ClassReader
    ---
    expected      : [field.Hodor]
    but was       : [org.jetbrains.coverage.org.objectweb.asm.Opcodes, field.Hodor, org.jetbrains.coverage.org.objectweb.asm.ClassReader]
    	at io.vertx.junit5.VertxExtension.joinActiveTestContexts(VertxExtension.java:193)
    	at io.vertx.junit5.VertxExtension.afterTestExecution(VertxExtension.java:164)
    	at org.junit.jupiter.engine.descriptor.TestMethodTestDescriptor.lambda$invokeAfterTestExecutionCallbacks$9(TestMethodTestDescriptor.java:233)
    	at org.junit.jupiter.engine.descriptor.TestMethodTestDescriptor.lambda$invokeAllAfterMethodsOrCallbacks$13(TestMethodTestDescriptor.java:273)
    	at org.junit.platform.engine.support.hierarchical.ThrowableCollector.execute(ThrowableCollector.java:73)
    	at org.junit.jupiter.engine.descriptor.TestMethodTestDescriptor.lambda$invokeAllAfterMethodsOrCallbacks$14(TestMethodTestDescriptor.java:273)
    	at java.base/java.util.ArrayList.forEach(ArrayList.java:1541)
    	at org.junit.jupiter.engine.descriptor.TestMethodTestDescriptor.invokeAllAfterMethodsOrCallbacks(TestMethodTestDescriptor.java:272)
    	at org.junit.jupiter.engine.descriptor.TestMethodTestDescriptor.invokeAfterTestExecutionCallbacks(TestMethodTestDescriptor.java:232)
    	at org.junit.jupiter.engine.descriptor.TestMethodTestDescriptor.execute(TestMethodTestDescriptor.java:137)
    	at org.junit.jupiter.engine.descriptor.TestMethodTestDescriptor.execute(TestMethodTestDescriptor.java:66)
    	at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$6(NodeTestTask.java:151)
    	at org.junit.platform.engine.support.hierarchical.ThrowableCollector.execute(ThrowableCollector.java:73)
    	at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$8(NodeTestTask.java:141)
    	at org.junit.platform.engine.support.hierarchical.Node.around(Node.java:137)
    	at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$9(NodeTestTask.java:139)
    	at org.junit.platform.engine.support.hierarchical.ThrowableCollector.execute(ThrowableCollector.java:73)
    	at org.junit.platform.engine.support.hierarchical.NodeTestTask.executeRecursively(NodeTestTask.java:138)
    	at org.junit.platform.engine.support.hierarchical.NodeTestTask.execute(NodeTestTask.java:95)
    	at java.base/java.util.ArrayList.forEach(ArrayList.java:1541)
    	at org.junit.platform.engine.support.hierarchical.SameThreadHierarchicalTestExecutorService.invokeAll(SameThreadHierarchicalTestExecutorService.java:41)
    	at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$6(NodeTestTask.java:155)
    	at org.junit.platform.engine.support.hierarchical.ThrowableCollector.execute(ThrowableCollector.java:73)
    	at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$8(NodeTestTask.java:141)
    	at org.junit.platform.engine.support.hierarchical.Node.around(Node.java:137)
    	at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$9(NodeTestTask.java:139)
    	at org.junit.platform.engine.support.hierarchical.ThrowableCollector.execute(ThrowableCollector.java:73)
    	at org.junit.platform.engine.support.hierarchical.NodeTestTask.executeRecursively(NodeTestTask.java:138)
    	at org.junit.platform.engine.support.hierarchical.NodeTestTask.execute(NodeTestTask.java:95)
    	at java.base/java.util.ArrayList.forEach(ArrayList.java:1541)
    	at org.junit.platform.engine.support.hierarchical.SameThreadHierarchicalTestExecutorService.invokeAll(SameThreadHierarchicalTestExecutorService.java:41)
    	at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$6(NodeTestTask.java:155)
    	at org.junit.platform.engine.support.hierarchical.ThrowableCollector.execute(ThrowableCollector.java:73)
    	at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$8(NodeTestTask.java:141)
    	at org.junit.platform.engine.support.hierarchical.Node.around(Node.java:137)
    	at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$9(NodeTestTask.java:139)
    	at org.junit.platform.engine.support.hierarchical.ThrowableCollector.execute(ThrowableCollector.java:73)
    	at org.junit.platform.engine.support.hierarchical.NodeTestTask.executeRecursively(NodeTestTask.java:138)
    	at org.junit.platform.engine.support.hierarchical.NodeTestTask.execute(NodeTestTask.java:95)
    	at org.junit.platform.engine.support.hierarchical.SameThreadHierarchicalTestExecutorService.submit(SameThreadHierarchicalTestExecutorService.java:35)
    	at org.junit.platform.engine.support.hierarchical.HierarchicalTestExecutor.execute(HierarchicalTestExecutor.java:57)
    	at org.junit.platform.engine.support.hierarchical.HierarchicalTestEngine.execute(HierarchicalTestEngine.java:54)
    	at org.junit.platform.launcher.core.EngineExecutionOrchestrator.execute(EngineExecutionOrchestrator.java:107)
    	at org.junit.platform.launcher.core.EngineExecutionOrchestrator.execute(EngineExecutionOrchestrator.java:88)
    	at org.junit.platform.launcher.core.EngineExecutionOrchestrator.lambda$execute$0(EngineExecutionOrchestrator.java:54)
    	at org.junit.platform.launcher.core.EngineExecutionOrchestrator.withInterceptedStreams(EngineExecutionOrchestrator.java:67)
    	at org.junit.platform.launcher.core.EngineExecutionOrchestrator.execute(EngineExecutionOrchestrator.java:52)
    	at org.junit.platform.launcher.core.DefaultLauncher.execute(DefaultLauncher.java:114)
    	at org.junit.platform.launcher.core.DefaultLauncher.execute(DefaultLauncher.java:86)
    	at org.junit.platform.launcher.core.DefaultLauncherSession$DelegatingLauncher.execute(DefaultLauncherSession.java:86)
    	at org.junit.platform.launcher.core.SessionPerRequestLauncher.execute(SessionPerRequestLauncher.java:53)
    	at org.gradle.api.internal.tasks.testing.junitplatform.JUnitPlatformTestClassProcessor$CollectAllTestClassesExecutor.processAllTestClasses(JUnitPlatformTestClassProcessor.java:99)
    	at org.gradle.api.internal.tasks.testing.junitplatform.JUnitPlatformTestClassProcessor$CollectAllTestClassesExecutor.access$000(JUnitPlatformTestClassProcessor.java:79)
    	at org.gradle.api.internal.tasks.testing.junitplatform.JUnitPlatformTestClassProcessor.stop(JUnitPlatformTestClassProcessor.java:75)
    	at org.gradle.api.internal.tasks.testing.SuiteTestClassProcessor.stop(SuiteTestClassProcessor.java:61)
    	at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    	at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
    	at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    	at java.base/java.lang.reflect.Method.invoke(Method.java:566)
    	at org.gradle.internal.dispatch.ReflectionDispatch.dispatch(ReflectionDispatch.java:36)
    	at org.gradle.internal.dispatch.ReflectionDispatch.dispatch(ReflectionDispatch.java:24)
    	at org.gradle.internal.dispatch.ContextClassLoaderDispatch.dispatch(ContextClassLoaderDispatch.java:33)
    	at org.gradle.internal.dispatch.ProxyDispatchAdapter$DispatchingInvocationHandler.invoke(ProxyDispatchAdapter.java:94)
    	at com.sun.proxy.$Proxy5.stop(Unknown Source)
    	at org.gradle.api.internal.tasks.testing.worker.TestWorker$3.run(TestWorker.java:193)
    	at org.gradle.api.internal.tasks.testing.worker.TestWorker.executeAndMaintainThreadName(TestWorker.java:129)
    	at org.gradle.api.internal.tasks.testing.worker.TestWorker.execute(TestWorker.java:100)
    	at org.gradle.api.internal.tasks.testing.worker.TestWorker.execute(TestWorker.java:60)
    	at org.gradle.process.internal.worker.child.ActionExecutionWorker.execute(ActionExecutionWorker.java:56)
    	at org.gradle.process.internal.worker.child.SystemApplicationClassLoaderWorker.call(SystemApplicationClassLoaderWorker.java:133)
    	at org.gradle.process.internal.worker.child.SystemApplicationClassLoaderWorker.call(SystemApplicationClassLoaderWorker.java:71)
    	at worker.org.gradle.process.internal.worker.GradleWorkerMain.run(GradleWorkerMain.java:69)
    	at worker.org.gradle.process.internal.worker.GradleWorkerMain.main(GradleWorkerMain.java:74)
    Caused by: unexpected (2): org.jetbrains.coverage.org.objectweb.asm.Opcodes, org.jetbrains.coverage.org.objectweb.asm.ClassReader
    ---
    expected      : [field.Hodor]
    but was       : [org.jetbrains.coverage.org.objectweb.asm.Opcodes, field.Hodor, org.jetbrains.coverage.org.objectweb.asm.ClassReader]
    	at app//io.neonbee.internal.scanner.ClassPathScannerTest.lambda$futureContainsExactly$11(ClassPathScannerTest.java:151)
    	at app//io.vertx.junit5.VertxTestContext.verify(VertxTestContext.java:368)
    	at app//io.neonbee.internal.scanner.ClassPathScannerTest.lambda$futureContainsExactly$12(ClassPathScannerTest.java:150)
    	at app//io.vertx.junit5.VertxTestContext.lambda$succeeding$2(VertxTestContext.java:215)
    	at app//io.vertx.core.impl.future.FutureImpl$3.onSuccess(FutureImpl.java:141)
    	at app//io.vertx.core.impl.future.FutureBase.emitSuccess(FutureBase.java:60)
    	at app//io.vertx.core.impl.future.FutureImpl.tryComplete(FutureImpl.java:211)
    	at app//io.vertx.core.impl.future.Composition$1.onSuccess(Composition.java:62)
    	at app//io.vertx.core.impl.future.FutureBase.emitSuccess(FutureBase.java:60)
    	at app//io.vertx.core.impl.future.FutureImpl.tryComplete(FutureImpl.java:211)
    	at app//io.vertx.core.impl.future.PromiseImpl.tryComplete(PromiseImpl.java:23)
    	at app//io.vertx.core.impl.future.PromiseImpl.onSuccess(PromiseImpl.java:49)
    	at app//io.vertx.core.impl.future.FutureBase.lambda$emitSuccess$0(FutureBase.java:54)
    	at app//io.netty.util.concurrent.AbstractEventExecutor.safeExecute(AbstractEventExecutor.java:164)
    	at app//io.netty.util.concurrent.SingleThreadEventExecutor.runAllTasks(SingleThreadEventExecutor.java:469)
    	at app//io.netty.channel.nio.NioEventLoop.run(NioEventLoop.java:503)
    	at app//io.netty.util.concurrent.SingleThreadEventExecutor$4.run(SingleThreadEventExecutor.java:986)
    	at app//io.netty.util.internal.ThreadExecutorMap$2.run(ThreadExecutorMap.java:74)
    	at app//io.netty.util.concurrent.FastThreadLocalRunnable.run(FastThreadLocalRunnable.java:30)
    	at [email protected]/java.lang.Thread.run(Thread.java:829)
    
    opened by gedack 4
  • NPE in EntityModelLoader when entity model is invalid

    NPE in EntityModelLoader when entity model is invalid

    Is there an existing issue for this?

    • [X] I have searched the existing issues

    Current Behavior

    Given an invalid model, the EntityModelLoader does not properly validate the model. Instead of propagating the error and failing the deployment of the model, a NullPointerException is thrown, which is not catched.

    The problematic code is in EntityModelLoader.buildModelMap, because serviceMetaData.getEdm().getEntityContainer() might be null.

    Expected Behavior

    The deployment of the invalid model should fail with an error message, describing the issue.

    Example code, which futurizes buildModelMap and handles the error:

    20:00:16.888 [vert.x-eventloop-thread-10] ERROR io.neonbee.internal.deploy.PendingDeployment - Deployment of Models(models/data-model.csn$models/Esrc.Service.edmx) failed
    io.vertx.core.impl.NoStackTraceThrowable: Cannot build model map. Entity Container is empty.
    20:00:16.903 [vert.x-eventloop-thread-6] INFO io.neonbee.internal.verticle.ServerVerticle - HTTP server started on port 8080
    20:00:16.904 [vert.x-eventloop-thread-10] ERROR io.neonbee.internal.deploy.PendingDeployment - Deployment of Deployables(module:2.0.0-SNAPSHOT) failed
    io.vertx.core.impl.NoStackTraceThrowable: Cannot build model map. Entity Container is empty.
    20:00:16.904 [vert.x-eventloop-thread-10] ERROR io.neonbee.internal.verticle.DeployerVerticle - Unexpected error occurred during deployment of module from JAR file: /Users/d061008/workspace/neonbee/working_dir/modules/dummy-2.0.0-SNAPSHOT-models.jar
    io.vertx.core.impl.NoStackTraceThrowable: Cannot build model map. Entity Container is empty.
    

    Steps To Reproduce

    Clone neonbee from the main branch, create a folder working_dir/modules, and create an invalid cds / edmx file. Start neonbee with ./gradlew run and you should be able to reproduce the error.

    Environment

    - OS: Darwin / 21.6.0 / arm64
    - Java: OpenJDK Runtime Environment SapMachine (build 11.0.14.1+1-LTS-sapmachine)
    - NeonBee: 0.16.1
    

    Relevant log output

    java.lang.NullPointerException: Cannot invoke "org.apache.olingo.commons.api.edm.EdmEntityContainer.getNamespace()" because the return value of "org.apache.olingo.commons.api.edm.Edm.getEntityContainer()" is null
            at io.neonbee.entity.EntityModelLoader.lambda$buildModelMap$16(EntityModelLoader.java:205)
            at java.base/java.util.stream.Collectors.lambda$uniqKeysMapAccumulator$1(Collectors.java:177)
            at java.base/java.util.stream.ReduceOps$3ReducingSink.accept(ReduceOps.java:169)
            at java.base/java.util.ArrayList$ArrayListSpliterator.forEachRemaining(ArrayList.java:1655)
            at java.base/java.util.stream.AbstractPipeline.copyInto(AbstractPipeline.java:484)
            at java.base/java.util.stream.AbstractPipeline.wrapAndCopyInto(AbstractPipeline.java:474)
            at java.base/java.util.stream.ReduceOps$ReduceOp.evaluateSequential(ReduceOps.java:913)
            at java.base/java.util.stream.AbstractPipeline.evaluate(AbstractPipeline.java:234)
            at java.base/java.util.stream.ReferencePipeline.collect(ReferencePipeline.java:578)
            at io.neonbee.entity.EntityModelLoader.buildModelMap(EntityModelLoader.java:204)
            at io.neonbee.entity.EntityModelLoader.lambda$loadModel$11(EntityModelLoader.java:184)
            at io.vertx.core.impl.future.FutureImpl$1.onSuccess(FutureImpl.java:91)
            at io.vertx.core.impl.future.FutureImpl$ListenerArray.onSuccess(FutureImpl.java:262)
            at io.vertx.core.impl.future.FutureBase.emitSuccess(FutureBase.java:60)
            at io.vertx.core.impl.future.FutureImpl.tryComplete(FutureImpl.java:211)
            at io.vertx.core.impl.future.CompositeFutureImpl.trySucceed(CompositeFutureImpl.java:163)
            at io.vertx.core.impl.future.CompositeFutureImpl.lambda$all$0(CompositeFutureImpl.java:38)
            at io.vertx.core.impl.future.FutureImpl$3.onSuccess(FutureImpl.java:141)
            at io.vertx.core.impl.future.FutureBase.emitSuccess(FutureBase.java:60)
            at io.vertx.core.impl.future.FutureImpl.tryComplete(FutureImpl.java:211)
            at io.vertx.core.impl.future.Composition$1.onSuccess(Composition.java:62)
            at io.vertx.core.impl.future.FutureBase.emitSuccess(FutureBase.java:60)
            at io.vertx.core.impl.future.FutureImpl.tryComplete(FutureImpl.java:211)
            at io.vertx.core.impl.future.PromiseImpl.tryComplete(PromiseImpl.java:23)
            at io.vertx.core.impl.future.PromiseImpl.onSuccess(PromiseImpl.java:49)
            at io.vertx.core.impl.future.FutureBase.lambda$emitSuccess$0(FutureBase.java:54)
            at io.netty.util.concurrent.AbstractEventExecutor.runTask(AbstractEventExecutor.java:174)
            at io.netty.util.concurrent.AbstractEventExecutor.safeExecute(AbstractEventExecutor.java:167)
            at io.netty.util.concurrent.SingleThreadEventExecutor.runAllTasks(SingleThreadEventExecutor.java:470)
            at io.netty.channel.nio.NioEventLoop.run(NioEventLoop.java:569)
            at io.netty.util.concurrent.SingleThreadEventExecutor$4.run(SingleThreadEventExecutor.java:997)
            at io.netty.util.internal.ThreadExecutorMap$2.run(ThreadExecutorMap.java:74)
            at io.netty.util.concurrent.FastThreadLocalRunnable.run(FastThreadLocalRunnable.java:30)
            at java.base/java.lang.Thread.run(Thread.java:829)
    

    Anything else?

    No response

    bug 
    opened by s4heid 3
  • feat: unregister entities from shared map

    feat: unregister entities from shared map

    NeonBee uses the shared map to manage the registration fo entities to EntityVerticles e.g: ("Products" -> "ProductsVerticle") ("OrderTypes" -> "C4SOrderTypesVerticle") During the boot up of an EntityVerticle "announceEntityVerticle" is used to register: "Entity Products" is handled by "me" (EntityProductsVerticle) Currently no "stop()" method is implemented, and no fallback handling was implemented (so the map may contain entries of verticles that no longer exist)

    This commit adds two methods to delete the registered entities from the shared map. The UnregisterEntityModelHook#unregisterOnShutdown method is executed if a node shuts down gracefully. The UnregisterEntityModelHook#cleanup method is executed when the cluster detects that a node has left

    opened by halber 3
  • feat: Make ServerVerticle handler configurable.

    feat: Make ServerVerticle handler configurable.

    The ServerVerticle attaches request handlers to the route. The request handlers attached to the route cannot be changed at the moment. This change makes the request handlers that the ServerVerticle attaches to the route configurable.

    A RoutingHandlerFactory is used to create an instance of the Handler<RoutingContext> class. In the ServerConfig, a list of RoutingHandlerFactory class names is used to specify the RoutingHandlerFactory. The handler created by the RoutingHandlerFactory is then added to the root route. The request handlers are added in the order specified in the ServerConfig list.

    code review required additional documentation required 
    opened by halber 3
  • fix: allow no active profile, make ALL the default

    fix: allow no active profile, make ALL the default

    Allow to set null / an empty list as active profiles, which means that no profiles are to be deployed and NeonBee will start with the system verticles only.

    opened by kristian 3
  • fix: odata query encoding and DataQuery setQuery

    fix: odata query encoding and DataQuery setQuery

    In this pull request two problems are fixed

    1. DataQuery cannot correctly process query strings The DataQuery expects a decoded query string in the setQuery method and in the constructors that accept a query parameter. These methods are now deprecated since this cannot be fixed. A new method setRawQuery is introduced which accepts the encoded query string and creates the parameters from it.

    2. odata query encoding in EntityVerticle The parseUri method expects the query parameter to be in percent encoding, but it was decoded.

    opened by halber 2
  • HTTP Header fields should be case-insensitive

    HTTP Header fields should be case-insensitive

    Is there an existing issue for this?

    • [X] I have searched the existing issues

    Current Behavior

    The getters of HTTP headers in DataQuery do not handle the names case-insensitively. However, they should be; as stated by the HTTP RFC 2616 Section 4.2:

    Field names are case-insensitive.

    Expected Behavior

    Field names are handled case-insensitively.

    Steps To Reproduce

    No response

    Environment

    No response

    Relevant log output

    No response

    Anything else?

    No response

    bug good first issue 
    opened by s4heid 2
  • fix: same NeonBee nodeId for multiple instances

    fix: same NeonBee nodeId for multiple instances

    The random NeonBee NODE_ID is the same for all NeonBee instances loaded from the same classloader. This fix makes the NeonBee nodeId an instance variable so that each NeonBee instance has its own nodeId.

    opened by halber 2
  • Execute global health checks only on the local instance

    Execute global health checks only on the local instance

    Is there an existing issue for this?

    • [X] I have searched the existing issues

    The Problem

    When NeonBee runs clustered, health checks are divided in node-specific and global health checks. If health information is requested via the HealthCheckHandler, node-specific checks are executed on every single node and the results will be consolidated in the HealthCheckRegistry. The current implementation, however, also executes the global checks in the same way as there is no differentiation between the type of check. All check results of a global check will be compared in the consolidateResults(...) method of the HealthCheckRegistry, and only the first check will be added to the list of consolidated checks (which will be returned by the HealthCheckHandler).

    This is a problem, because when having a large cluster, global checks are executed on every single node in parallel. Depending, on the type of check (e.g. health request to an external service) this can cause high load on the external services.

    Another issue with this implementation is that the NeonBee nodes not necessarily share the same configuration and thus might not be able to perform the health check. In that case, the consolidateResults method has redundant data. Therefore, we need to make it clear to the user where this check is performed, such that the required configuration can be set-up.

    Desired Solution

    A better implementation would only execute the global check once. It would be sufficient if the check is executed on the local node which invokes the health check handler. I think - for now - we do not have make it configurable on which node the check is executed, but this might be something we could keep in mind for the future in case there is demand.

    Alternative Solutions

    No response

    Additional Context

    To give more detail about the current implementation, here is some log output which would be generated in the HealthCheckRegistry.sendDataRequests(...), when logging the data object returned by the invoked data request of each HealthCheckVerticle. Assuming there is 3 verticles in a cluster with a global check service.feature-flags.health,

    Retrieved check from neonbee/_healthCheckVerticle-5404d541-7fe0-44a8-bed4-c60af882453b with data: [ {
    "id" : "cluster.hazelcast",
    "status" : "UP",
    "data" : {
    "clusterState" : "ACTIVE",
    "clusterSize" : 3,
    "lifecycleServiceState" : "ACTIVE"
    }
    }, {
    "id" : "service.feature-flags.health",
    "status" : "UP",
    "data" : {
    "statusCode" : 200,
    "latencyMillis" : 23,
    "statusMessage" : "UP"
    }
    } ]
    
    Retrieved check from neonbee/_healthCheckVerticle-0ac2c75e-7e63-4e29-b919-1304b023521b with data: [ {
    "id" : "cluster.hazelcast",
    "status" : "UP",
    "data" : {
    "clusterState" : "ACTIVE",
    "clusterSize" : 3,
    "lifecycleServiceState" : "ACTIVE"
    }
    }, {
    "id" : "service.feature-flags.health",
    "status" : "UP",
    "data" : {
    "statusCode" : 200,
    "latencyMillis" : 26,
    "statusMessage" : "UP"
    }
    } ]
    
    Retrieved check from neonbee/_healthCheckVerticle-69fc018f-eaaf-499f-acce-82a0752dc919 with data: [ {
    "id" : "cluster.hazelcast",
    "status" : "UP",
    "data" : {
    "clusterState" : "ACTIVE",
    "clusterSize" : 3,
    "lifecycleServiceState" : "ACTIVE"
    }
    }, {
    "id" : "service.feature-flags.health",
    "status" : "DOWN",
    "data" : {
    "cause" : "Could not fetch credentials for basic authentication"
    }
    } ]
    

    Here, NeonBee would report always the status of the HealthCheckVerticle which registered first in the shared map. The other check results are discarded. Also, notice that the node which runs neonbee/_healthCheckVerticle-69fc018f-eaaf-499f-acce-82a0752dc919 is not setup to authenticate against the service. If this verticle registered first, this failing status would always be returned.

    enhancement 
    opened by s4heid 0
  • [Discussion]: Increase timeouts for tests

    [Discussion]: Increase timeouts for tests

    Is there an existing issue for this?

    • [X] I have searched the existing issues

    The Problem

    The annotation ``@Timeout` defines the maximum time a test has the chance to complete. In the most tests we defined 2 seconds. On a slow machine or CI infrastructure there is a good chance to hit this timeout. Unfortunately it is not possible to configure a global timeout [1], which can be increased on slow machines.

    [1] https://discord.com/channels/751380286071242794/751398169199378553/1045722403705212979

    Desired Solution

    We should agree on a new default timeout value and adopt the tests.

    Alternative Solutions

    We write our own Timeout annotation?

    Additional Context

    No response

    enhancement 
    opened by pk-work 1
  • Only start running job verticles if boot process fully finished

    Only start running job verticles if boot process fully finished

    Is there an existing issue for this?

    • [X] I have searched the existing issues

    The Problem

    Currently, if verticles are deployed during the boot process of NeonBee, it can happen that JobVerticles already start their work, even though NeonBee is still in a booting state. As verticles are deployed as a last step of the boot, this is often times not critical, but especially if verticles depend on each other through the event loop, it can result in non-deterministic behavior, especially if the job verticle calls the dependent verticle immediately.

    Desired Solution

    Wait for starting the "clock" of execution of all job-verticles until the boot process of NeonBee signals full completion.

    Alternative Solutions

    No response

    Additional Context

    No response

    enhancement 
    opened by kristian 0
  • Test Infinispan and Hazelcast Classloader access when new

    Test Infinispan and Hazelcast Classloader access when new "NeonBeeTestRunner" is available

    Is there an existing issue for this?

    • [X] I have searched the existing issues

    Current Behavior

    Classloader access can't be tested, see https://github.com/SAP/neonbee/pull/189 and see https://github.com/SAP/neonbee/pull/195

    Expected Behavior

    It should be tested ..

    Steps To Reproduce

    No response

    Environment

    - OS:
    - Java:
    - NeonBee:
    

    Relevant log output

    No response

    Anything else?

    No response

    bug needs triage 
    opened by pk-work 0
Releases(0.18.0)
  • 0.18.0(Nov 15, 2022)

    Artifacts

    Maven Central: neonbee-core-0.18.0

    Maven

    <!-- https://mvnrepository.com/artifact/io.neonbee/neonbee-core -->
    <dependency>
      <groupId>io.neonbee</groupId>
      <artifactId>neonbee-core</artifactId>
      <version>0.18.0</version>
    </dependency>
    

    Gradle

    // https://mvnrepository.com/artifact/io.neonbee/neonbee-core
    implementation group: 'io.neonbee', name: 'neonbee-core', version: '0.18.0'
    

    Docker Image

    Use as base image in Dockerfile:

    FROM ghcr.io/sap/neonbee:0.18.0
    

    Changelog

    Bug Fixes

    • generated files have changed (80ef04ec)
    • odata query encoding in EntityVerticle (ae52053a)
    • dataquery cannot correctly process query strings (4cccf60b)

    Features

    • include a version file inside jar files (ed244da5)
    • load Hazelcast configuration from file (f721875a)

    Build System

    • deps: upgrade com.fasterxml.jackson to 2.13.4.2 (4f0bfaea)
    • docker: pin gradle version to 7.2 (cb1be0ed)
    Source code(tar.gz)
    Source code(zip)
  • 0.17.0(Oct 24, 2022)

    Artifacts

    Maven Central: neonbee-core-0.17.0

    Maven

    <!-- https://mvnrepository.com/artifact/io.neonbee/neonbee-core -->
    <dependency>
      <groupId>io.neonbee</groupId>
      <artifactId>neonbee-core</artifactId>
      <version>0.17.0</version>
    </dependency>
    

    Gradle

    // https://mvnrepository.com/artifact/io.neonbee/neonbee-core
    implementation group: 'io.neonbee', name: 'neonbee-core', version: '0.17.0'
    

    Docker Image

    Use as base image in Dockerfile:

    FROM ghcr.io/sap/neonbee:0.17.0
    

    Changelog

    Bug Fixes

    • multi-release issue w/ Infinispan (cd6ccd99)
    • close Infinispan cache container after NeonBee shutdown (57616a86)
    • #199, add tracing to EntityModelLoader and improve logging (d6130468)
    • odata query encoding (869d6875)

    Features

    • introduce a NeonBeeExtension.TestBase (9608028c)

    Continuous Integration

    Source code(tar.gz)
    Source code(zip)
  • 0.16.1(Oct 12, 2022)

    Artifacts

    Maven Central: neonbee-core-0.16.1

    Maven

    <!-- https://mvnrepository.com/artifact/io.neonbee/neonbee-core -->
    <dependency>
      <groupId>io.neonbee</groupId>
      <artifactId>neonbee-core</artifactId>
      <version>0.16.1</version>
    </dependency>
    

    Gradle

    // https://mvnrepository.com/artifact/io.neonbee/neonbee-core
    implementation group: 'io.neonbee', name: 'neonbee-core', version: '0.16.1'
    

    Docker Image

    Use as base image in Dockerfile:

    FROM ghcr.io/sap/neonbee:0.16.1
    

    Changelog

    Bug Fixes

    • pass SystemClassLoader to cluster manager configuration (ab258a7b)
    Source code(tar.gz)
    Source code(zip)
  • 0.16.0(Oct 11, 2022)

    Artifacts

    Maven Central: neonbee-core-0.16.0

    Maven

    <!-- https://mvnrepository.com/artifact/io.neonbee/neonbee-core -->
    <dependency>
      <groupId>io.neonbee</groupId>
      <artifactId>neonbee-core</artifactId>
      <version>0.16.0</version>
    </dependency>
    

    Gradle

    // https://mvnrepository.com/artifact/io.neonbee/neonbee-core
    implementation group: 'io.neonbee', name: 'neonbee-core', version: '0.16.0'
    

    Docker Image

    Use as base image in Dockerfile:

    FROM ghcr.io/sap/neonbee:0.16.0
    

    Changelog

    Bug Fixes

    • health: make health check collection more resilient (5421607b)
    • removed docker image tag with sha (44cd0379)
    • register NeonBee mock (5d3999b2)
    • make SystemClassLoader available to Infinispan (d8b9b1f2)

    Features

    • add option to set metrics registry name (194cbb2b)

    Code Refactoring

    • registerNeonBeeMock should not influence mock (d392975f)
    Source code(tar.gz)
    Source code(zip)
  • 0.15.0(Oct 6, 2022)

    Artifacts

    Maven Central: neonbee-core-0.15.0

    Maven

    <!-- https://mvnrepository.com/artifact/io.neonbee/neonbee-core -->
    <dependency>
      <groupId>io.neonbee</groupId>
      <artifactId>neonbee-core</artifactId>
      <version>0.15.0</version>
    </dependency>
    

    Gradle

    // https://mvnrepository.com/artifact/io.neonbee/neonbee-core
    implementation group: 'io.neonbee', name: 'neonbee-core', version: '0.15.0'
    

    Docker Image

    Use as base image in Dockerfile:

    FROM ghcr.io/sap/neonbee:0.15.0
    

    Changelog

    Bug Fixes

    • failing metrics test on Github (56eedff2)

    Features

    • health: add event-loop health check (1a2fa4be)
    • use Vert.x FakeClusterManager in NeonBeeExtension (e522452f)
    • make test cluster manager configurable (32e5d120)
    • add Infinispan ClusterManager (26bb382e)

    Code Refactoring

    Documentation

    • add docker login step to docs (bf2707df)

    Build System

    • deps: upgrade vertx to 4.3.4 (fedab717)

    Continuous Integration

    • github: update issue templates (65f5db6e)
    • add workflow step to publish docker image to ghcr (7152dba0)
    Source code(tar.gz)
    Source code(zip)
  • 0.14.0(Aug 30, 2022)

    Artifacts

    Maven Central: neonbee-core-0.14.0

    Maven

    <!-- https://mvnrepository.com/artifact/io.neonbee/neonbee-core -->
    <dependency>
      <groupId>io.neonbee</groupId>
      <artifactId>neonbee-core</artifactId>
      <version>0.14.0</version>
    </dependency>
    

    Gradle

    // https://mvnrepository.com/artifact/io.neonbee/neonbee-core
    implementation group: 'io.neonbee', name: 'neonbee-core', version: '0.14.0'
    

    Changelog

    Bug Fixes

    • same NeonBee nodeId for multiple instances (3b48202c)
    • pass vertx instance to NeonBee for the metrics config (05559de7)

    Features

    • support response hint (88cb66f5)
    • add failureDetail to DataException (c7fa2bdb)
    Source code(tar.gz)
    Source code(zip)
  • 0.13.0(Aug 10, 2022)

    Artifacts

    Maven Central: neonbee-core-0.13.0

    Maven

    <!-- https://mvnrepository.com/artifact/io.neonbee/neonbee-core -->
    <dependency>
      <groupId>io.neonbee</groupId>
      <artifactId>neonbee-core</artifactId>
      <version>0.13.0</version>
    </dependency>
    

    Gradle

    // https://mvnrepository.com/artifact/io.neonbee/neonbee-core
    implementation group: 'io.neonbee', name: 'neonbee-core', version: '0.13.0'
    

    Changelog

    Bug Fixes

    • speed up the test execution (c59f6d86)
    • disable unstable test on github (1e29e130)

    Features

    • make ServerVerticle handler configurable (deff579c)

    Documentation

    • health: add documentation for the health feature (99be11b7)

    Build System

    • deps: upgrade vertx to 4.3.3 (e0f366ca)
    Source code(tar.gz)
    Source code(zip)
  • 0.12.1(Jul 22, 2022)

    Artifacts

    Maven Central: neonbee-core-0.12.1

    Maven

    <!-- https://mvnrepository.com/artifact/io.neonbee/neonbee-core -->
    <dependency>
      <groupId>io.neonbee</groupId>
      <artifactId>neonbee-core</artifactId>
      <version>0.12.1</version>
    </dependency>
    

    Gradle

    // https://mvnrepository.com/artifact/io.neonbee/neonbee-core
    implementation group: 'io.neonbee', name: 'neonbee-core', version: '0.12.1'
    

    Changelog

    Chores

    • log the NeonBee Id (40203a3c)
    • remove physical memory from health check data (367eef5b)

    Build System

    • deps: upgrade vertx to 4.3.2 (edae6e0b)
    • deps: upgrade org.ow2.asm to version 9.3 (88d89b1e)
    • deps: upgrade dependencies (479456f9)
    Source code(tar.gz)
    Source code(zip)
  • 0.12.0(Jul 22, 2022)

    Artifacts

    Maven Central: neonbee-core-0.12.0

    Maven

    <!-- https://mvnrepository.com/artifact/io.neonbee/neonbee-core -->
    <dependency>
      <groupId>io.neonbee</groupId>
      <artifactId>neonbee-core</artifactId>
      <version>0.12.0</version>
    </dependency>
    

    Gradle

    // https://mvnrepository.com/artifact/io.neonbee/neonbee-core
    implementation group: 'io.neonbee', name: 'neonbee-core', version: '0.12.0'
    

    Changelog

    Bug Fixes

    • health: succeed if health check config not found (ae371b28)
    • do not mock NeonBee logger in NeonBeeMockHelper (8238ec8d)
    • avoid printing warnings when using NeonBeeMockHelper (03d9e535)

    Features

    • health: add health check verticle (7fbd10e4)
    • health: provide a /health endpoint (151cf6e2)
    • add metrics to DataVerticle (1afca66c)
    • make health checks addable via SPI (71e754e1)
    Source code(tar.gz)
    Source code(zip)
  • 0.11.1(Jul 22, 2022)

    Artifacts

    Maven Central: neonbee-core-0.11.1

    Maven

    <!-- https://mvnrepository.com/artifact/io.neonbee/neonbee-core -->
    <dependency>
      <groupId>io.neonbee</groupId>
      <artifactId>neonbee-core</artifactId>
      <version>0.11.1</version>
    </dependency>
    

    Gradle

    // https://mvnrepository.com/artifact/io.neonbee/neonbee-core
    implementation group: 'io.neonbee', name: 'neonbee-core', version: '0.11.1'
    

    Changelog

    Bug Fixes

    Source code(tar.gz)
    Source code(zip)
  • 0.11.0(Jun 3, 2022)

    Artifacts

    Maven Central: neonbee-core-0.11.0

    Maven

    <!-- https://mvnrepository.com/artifact/io.neonbee/neonbee-core -->
    <dependency>
      <groupId>io.neonbee</groupId>
      <artifactId>neonbee-core</artifactId>
      <version>0.11.0</version>
    </dependency>
    

    Gradle

    // https://mvnrepository.com/artifact/io.neonbee/neonbee-core
    implementation group: 'io.neonbee', name: 'neonbee-core', version: '0.11.0'
    

    Changelog

    BREAKING CHANGES

    • remove LauncherPreProcessor (b4a014d8)

    Bug Fixes

    • assertDataFailure should return a succeeded future (0f73202b)
    • enable tests to run in intellij idea with coverage (f263eac5)
    • loading the NeonBee configuration (649b54c9)

    Features

    Code Refactoring

    • created methods to reuse code (de48d135)

    Build System

    • deps: upgrade vertx to 4.2.5 (0723ac2b)
    • deps: upgrade vertx to 4.2.6 (624de7de)
    • deps: upgrade vertx to 4.2.7 (368451f1)
    Source code(tar.gz)
    Source code(zip)
  • 0.10.0(Mar 7, 2022)

    Artifacts

    Maven Central: neonbee-core-0.10.0

    Maven

    <!-- https://mvnrepository.com/artifact/io.neonbee/neonbee-core -->
    <dependency>
      <groupId>io.neonbee</groupId>
      <artifactId>neonbee-core</artifactId>
      <version>0.10.0</version>
    </dependency>
    

    Gradle

    // https://mvnrepository.com/artifact/io.neonbee/neonbee-core
    implementation group: 'io.neonbee', name: 'neonbee-core', version: '0.10.0'
    

    Changelog

    Bug Fixes

    • allow no active profile, make ALL the default (e8461712)
    • prefer loading Vert.x/NeonBee from system class loader (9d01198b)

    Features

    • add NeonBee vs. Vert.x to README.md (bf00a23a)
    • make NeonBee boot logging a little more verbose (ca5d8be2)

    Code Refactoring

    • change to futurized interfaces (e2659537)
    • improve wildcard handling in SelfFirstClassLoader (e98615bb)

    Continuous Integration

    • automate dependency upgrade (of vertx) (1ab6d1a8)
    Source code(tar.gz)
    Source code(zip)
  • 0.9.1(Mar 7, 2022)

    Artifacts

    Maven Central: neonbee-core-0.9.1

    Maven

    <!-- https://mvnrepository.com/artifact/io.neonbee/neonbee-core -->
    <dependency>
      <groupId>io.neonbee</groupId>
      <artifactId>neonbee-core</artifactId>
      <version>0.9.1</version>
    </dependency>
    

    Gradle

    // https://mvnrepository.com/artifact/io.neonbee/neonbee-core
    implementation group: 'io.neonbee', name: 'neonbee-core', version: '0.9.1'
    

    Changelog

    Bug Fixes

    • NPE ImmutableJsonObject/Array for null values (0a791364)
    Source code(tar.gz)
    Source code(zip)
  • 0.9.0(Feb 15, 2022)

    Artifacts

    Maven Central: neonbee-core-0.9.0

    Maven

    <!-- https://mvnrepository.com/artifact/io.neonbee/neonbee-core -->
    <dependency>
      <groupId>io.neonbee</groupId>
      <artifactId>neonbee-core</artifactId>
      <version>0.9.0</version>
    </dependency>
    

    Gradle

    // https://mvnrepository.com/artifact/io.neonbee/neonbee-core
    implementation group: 'io.neonbee', name: 'neonbee-core', version: '0.9.0'
    

    Changelog

    Bug Fixes

    • null values queried with contains (0b06e92b)

    Features

    • made EntityModelManager a non-static class (d5e57d9b)
    • improve Launcher, Deployable, EntityModelManager and more (b578bace)
    Source code(tar.gz)
    Source code(zip)
  • 0.8.0(Jan 27, 2022)

    Artifacts

    Maven Central: neonbee-core-0.8.0

    Maven

    <!-- https://mvnrepository.com/artifact/io.neonbee/neonbee-core -->
    <dependency>
      <groupId>io.neonbee</groupId>
      <artifactId>neonbee-core</artifactId>
      <version>0.8.0</version>
    </dependency>
    

    Gradle

    // https://mvnrepository.com/artifact/io.neonbee/neonbee-core
    implementation group: 'io.neonbee', name: 'neonbee-core', version: '0.8.0'
    

    Changelog

    Features

    • add custom micrometer registries via NeonBeeConfig (6a11d795)

    Documentation

    • fix typo in github release guide (33065169)

    Build System

    • deps: upgrade vertx to 4.2.3 (ea793306)
    • deps: upgrade micrometer-registry-prometheus to 1.8.1 (c1b4168c)
    • deps: upgrade cds4j-core to 1.25.0 (c1408cbd)
    • deps: upgrade mockito to 4.2.0 (b78c3448)
    • deps: upgrade junit to 5.8.2 (ac8d9c36)
    • deps: upgrade guava to 31.0.1-jre (9911f356)
    • deps: upgrade gradle plugin dependencies (7e7bdcec)
    • deps: upgrade logback-classic to 1.2.9 (67fff831)
    • deps: upgrade junit-platform to 1.8.2 (18feb6d7)
    • deps: upgrade slf4j-api to 1.7.32 (0953e401)

    Continuous Integration

    • update commitlint github action to @v4, fixes #91 (#91) (7803220e)
    Source code(tar.gz)
    Source code(zip)
  • 0.7.0(Dec 15, 2021)

    Artifacts

    Maven Central: neonbee-core-0.7.0

    Maven

    <!-- https://mvnrepository.com/artifact/io.neonbee/neonbee-core -->
    <dependency>
      <groupId>io.neonbee</groupId>
      <artifactId>neonbee-core</artifactId>
      <version>0.7.0</version>
    </dependency>
    

    Gradle

    // https://mvnrepository.com/artifact/io.neonbee/neonbee-core
    implementation group: 'io.neonbee', name: 'neonbee-core', version: '0.7.0'
    

    Changelog

    Features

    • move MetricOptions to NeonBeeOptions (6286fd1a)
    • make usage of createQualifiedName more resilient (56a16013)

    Code Refactoring

    • remove dependency to CompilingClassLoader of Vert.x (48e17700)

    Build System

    • deps: bump Vert.x from 4.1.0 to 4.2.1 (c498f707)
    • deps: bump Vert.x from 4.2.1 to 4.2.2 (db177905)
    Source code(tar.gz)
    Source code(zip)
  • 0.6.2(Dec 15, 2021)

    Artifacts

    Maven Central: neonbee-core-0.6.2

    Maven

    <!-- https://mvnrepository.com/artifact/io.neonbee/neonbee-core -->
    <dependency>
      <groupId>io.neonbee</groupId>
      <artifactId>neonbee-core</artifactId>
      <version>0.6.2</version>
    </dependency>
    

    Gradle

    // https://mvnrepository.com/artifact/io.neonbee/neonbee-core
    implementation group: 'io.neonbee', name: 'neonbee-core', version: '0.6.2'
    

    Changelog

    Bug Fixes

    Features

    • offer a new ErrorHandler which can be initialized asynchronously (597f2575)
    Source code(tar.gz)
    Source code(zip)
  • 0.6.1(Oct 5, 2021)

    Artifacts

    Maven Central: neonbee-core-0.6.1

    Maven

    <!-- https://mvnrepository.com/artifact/io.neonbee/neonbee-core -->
    <dependency>
      <groupId>io.neonbee</groupId>
      <artifactId>neonbee-core</artifactId>
      <version>0.6.1</version>
    </dependency>
    

    Gradle

    // https://mvnrepository.com/artifact/io.neonbee/neonbee-core
    implementation group: 'io.neonbee', name: 'neonbee-core', version: '0.6.1'
    

    Changelog

    Bug Fixes

    • make ImmutableJsonArray/Object.equals behave better (6cd3cf4a)
    Source code(tar.gz)
    Source code(zip)
  • 0.6.0(Oct 4, 2021)

    Artifacts

    Maven Central: neonbee-core-0.6.0

    Maven

    <!-- https://mvnrepository.com/artifact/io.neonbee/neonbee-core -->
    <dependency>
      <groupId>io.neonbee</groupId>
      <artifactId>neonbee-core</artifactId>
      <version>0.6.0</version>
    </dependency>
    

    Gradle

    // https://mvnrepository.com/artifact/io.neonbee/neonbee-core
    implementation group: 'io.neonbee', name: 'neonbee-core', version: '0.6.0'
    

    Changelog

    Bug Fixes

    • rephrase error handler properties in config (e9495778)
    • switch to Vert.x-owned Hazelcast instance creation (67b6b977)

    Features

    • add JobSchedule validation (17199b20)
    • add session id to DataContext (8fce1828)
    • add a ImmutableBuffer class (d6145454)
    • add NO_WEB profile (a2c3a5d5)
    • add a CompositeBuffer class (946049be)
    • add/removeActiveProfile to/from NeonBeeOptions.Mutable (69771636)
    • add doNotWatchFiles option to not watch for file changes (2e4c7934)

    Code Refactoring

    • do not fail start of WatchVerticle if doNotWatchFiles (f551fb1a)

    Chores

    • don't start gradle as a daemon (9f8fa949)

    Documentation

    Build System

    • deps: bump com.sap.cds:cds4j-core from 1.19.0 to 1.22.1 (7f043171)
    • upgrade to Gradle 7.2 and bump all test tooling (c035ebf4)

    Continuous Integration

    • gh-actions: add maven central section in release body (ea938f7d)
    • add NO_WEB profile to all tests not using the server verticle (dab61cdf)
    • add a RunningTest- and a AliveThreadReporter (d97bdce0)
    • add NeonBeeTestExecutionListener to check for stale threads (cf17fa40)
    • fix NeonBeeTestBaseTest on GitHub (cbd53b5c)
    • add better getFreePort implementation (bb443d52)
    • add cluster termination for tests (88df6657)
    • add some additional logging (77ab4b1c)
    • add and adapt test timeouts (6c8fea84)
    • add do not watch files test for WatchVerticle (48f6d572)
    • switch to setup-java@v2 cache for Gradle (3b6bb5df)
    • isolate tests modifying global resources (336db173)
    • always close Vert.x if tests create own instances (28f03861)
    • add vertx-parameters for tests (20cb77c1)
    • refactor NeonBeeTestExecutionListener into a StaleVertx/ThreadChecker (1b386199)
    • use better default options for NeonBee in tests (14128512)
    • fix typos, provide explanation why @BeforeEach ignores testContext (007b8ce6)
    • fix publish (b5f27df2)
    • add changelog again (a6b256ad)
    Source code(tar.gz)
    Source code(zip)
  • 0.5.1(Aug 6, 2021)

    Artifacts

    Maven Central: neonbee-core-0.5.1

    Maven

    <!-- https://mvnrepository.com/artifact/io.neonbee/neonbee-core -->
    <dependency>
        <groupId>io.neonbee</groupId>
        <artifactId>neonbee-core</artifactId>
        <version>0.5.1</version>
    </dependency>
    

    Gradle

    // https://mvnrepository.com/artifact/io.neonbee/neonbee-core
    implementation group: 'io.neonbee', name: 'neonbee-core', version: '0.5.1'
    

    Changelog

    Bug Fixes

    • decode query parameters in odata requests (38e36e2f)
    • prepend uri paths of entity requests with a slash (ae31b863)

    Code Refactoring

    • processor: extract common methods into helper (608ec395)
    • made the ClassPathScanner non-blocking (dc190210)
    • move error handler configuration to ServerConfig class (71e328ff)

    Features

    • allow multiple MANIFST.MF files when parsing NeonBee-Module (dec4a91f)

    Documentation

    • readme: add example repository (2a861f7f)
    Source code(tar.gz)
    Source code(zip)
  • 0.5.0(Jun 8, 2021)

    Artifacts

    Maven Central: neonbee-core-0.5.0

    Maven

    <!-- https://mvnrepository.com/artifact/io.neonbee/neonbee-core -->
    <dependency>
        <groupId>io.neonbee</groupId>
        <artifactId>neonbee-core</artifactId>
        <version>0.5.0</version>
    </dependency>
    

    Gradle

    // https://mvnrepository.com/artifact/io.neonbee/neonbee-core
    implementation group: 'io.neonbee', name: 'neonbee-core', version: '0.5.0'
    

    Changelog

    Bug Fixes

    • use gradle task for setting new version (9295c74a)
    • correct typos (d340192e)
    • switch to async. log appender (880b338b)
    • add fake URI path to navigation properties requests (3d2af584)
    • enable parseUriInfo for OData URIs containing properties (fea16bde)
    • re-enable system query count (d90c40f8)
    • calculation of system query count (35bd1dce)
    • respect HTTP server port configuration in NeonBee options (4cdbd150)
    • example for ServerVerticle (ServerConfig) (2509bfcc)

    Code Refactoring

    • remove annotation provider leftovers (1b9e0059)
    • split up god-class "Helper" (aacf9ff8)
    • refactor NeonBee class (61800401)
    • move files to prepare upcoming NeonBeeConfig change (0f47cec2)
    • serverPort + timeZone in options / config and Launcher (9499d2f3)
    • move files to prepare endpoints change (ddb9c29d)

    Features

    • add limited support for OData navigation properties (d520f703)
    • make launcher options configurable via env (f51886d0)
    • add Vert.x code generation and made NeonBeeConfig a DataObject (e026ab19)
    • add missing tests for NeonBeeOptions (9608bcca)
    • add missing tests for NeonBeeConfig (40b66db0)
    • make the ServerVerticle and its endpoints fully configurable (7871036d)
    • add support for custom error handlers (0b34d82c)
    • add test for JWT AuthHandler creation (ac544cfa)
    • introduce exposedEntities/Verticles allow/block lists (2c4e8356)

    Documentation

    • update roadmap (e98466eb)
    • mark configurable endpoints milestone as done (e2003852)

    Chores

    • add PMD rules to avoid unnecessary modifiers in tests (2e1c95dd)
    • add java doc build for test sources to the voter (decc350d)
    • bump static code dependencies (59a1ba87)

    Build System

    • ci: set Github Actions OS to ubuntu-18.04 (a7c20b1b)
    • commitlint: allow pascal-case scopes (1a80e51d)
    • deps: replace cds-services-impl with cds4j-core (a72d2d0e)
    • deps: bump vertx from 4.0.3 to 4.1.0 (55753cbd)

    Continuous Integration

    • actions: disable sonarqube on forks (dc73c8ef)
    • actions: disable sonarqube on pull requests (0f1135a7)
    Source code(tar.gz)
    Source code(zip)
  • 0.4.0(Mar 18, 2021)

    Artifacts

    Maven Central: neonbee-core-0.4.0

    Maven

    <!-- https://mvnrepository.com/artifact/io.neonbee/neonbee-core -->
    <dependency>
        <groupId>io.neonbee</groupId>
        <artifactId>neonbee-core</artifactId>
        <version>0.4.0</version>
    </dependency>
    

    Gradle

    // https://mvnrepository.com/artifact/io.neonbee/neonbee-core
    implementation group: 'io.neonbee', name: 'neonbee-core', version: '0.4.0'
    

    Changelog

    Bug Fixes

    Code Refactoring

    Features

    • add $expand support for entities (6c5d0790)

    Documentation

    Build System

    • deps: bump vertx from 4.0.0 to 4.0.3 (111301dd)

    Continuous Integration

    • use custom GitHub token for protected branches (710f4274)
    • add sonarqube to github voter (52f43ab2)
    Source code(tar.gz)
    Source code(zip)
  • 0.3.0(Mar 11, 2021)

    Artifacts

    Maven Central: neonbee-core-0.3.0

    Maven

    <!-- https://mvnrepository.com/artifact/io.neonbee/neonbee-core -->
    <dependency>
        <groupId>io.neonbee</groupId>
        <artifactId>neonbee-core</artifactId>
        <version>0.3.0</version>
    </dependency>
    

    Gradle

    // https://mvnrepository.com/artifact/io.neonbee/neonbee-core
    implementation group: 'io.neonbee', name: 'neonbee-core', version: '0.3.0'
    

    Changelog

    Bug Fixes

    • PubKey extraction for JWT Authhandler and other fixes (ff018e04)
    • prevent UnsupportedOperationException when deploying NeonBeeModules (e60a6a3b)
    • wrong hazelcast configuration version (1ed24b9f)
    • Usage of wrong verticles folder in WorkingDirectoryBuilder (ba0c0e98)
    • Eclipse Formatter rules for VS Code (4808ea9a)
    • Broken HTTP status code propagation in ODataEndpointHandler (eabd7742)
    • match correct version pattern when releasing (b64bbe3c)
    • Broken HTTP status code propagation to the client (9627ea73)
    • All static code errors (8aaf1654)

    Code Refactoring

    • Improve NeonBee ASCII art logo (3a52e479)
    • Remove broadcasting from DataRequest/simplify (d183a2ab)
    • simplify the EntityCollectionProcessor (02b1309f)
    • expose SLF4J Logger interface in LoggingFacade (d299658b)

    Features

    • support forward basic HTTP exceptions (4f4fdf58)
    • add $expand support for entity collections (92dbcde7)

    Documentation

    • Add CONTRIBUTING.md (14ff9121)
    • Add high-level milestones to docs/roadmap.md (c14c4ecb)
    • add licensing and contributing information (3e3d9a32)
    • change NeonBee description in README.md (2bd264e8)
    • adapt more technical writing in README, add dataflow and roadmap items (209abcde)
    • adapt docs for GitHub release workflow (d06c9ba9)

    Chores

    • Rename repository to just "neonbee" (c2a6d9f0)
    • update issue templates (5b8aef2d)
    • Adding missing license information (e20fb48c)
    • add codeowners (e41957b6)
    • Setup voter with github actions (99b1b7c7)
    • lint commit messages on push (726dae05)
    • disable body-max-line-length for commitlint (de63afe1)

    Tests

    • Fix all failing unit tests on Windows (8ce4d746)

    Build System

    • deps: downgrade jackson from 2.12.0 to 2.11.3 (06fd9a4b)
    • gradle: disable errorprone checks for TypeParameterUnusedInFormals (87b16311)
    • Move most .gradle files to /gradle and restructure (2dec63a9)
    • remove unnecessary repositories from Gradle files and bump Gradle (8226af83)
    • add required configuration for publishing to maven central (9cc50e4b)

    Continuous Integration

    • actions: add reuse compliance workflow (7867a2f6)
    • Add commitlint GitHub workflow (8ee0bdb6)
    • add publishing workflow (12e5b4fc)

    Others

    Source code(tar.gz)
    Source code(zip)
Owner
SAP
SAP SE, a global software company, is one of the largest vendors of ERP and other enterprise applications.
SAP
Vert.x is a tool-kit for building reactive applications on the JVM

Vert.x Core This is the repository for Vert.x core. Vert.x core contains fairly low-level functionality, including support for HTTP, TCP, file system

Eclipse Vert.x 13.3k Jan 8, 2023
Distributed Stream and Batch Processing

What is Jet Jet is an open-source, in-memory, distributed batch and stream processing engine. You can use it to process large volumes of real-time eve

hazelcast 1k Dec 31, 2022
Simple and lightweight sip server to create voice robots, based on vert.x

Overview Lightweight SIP application built on vert.x. It's intended to be used as addon for full-featured PBX to implement programmable voice scenario

Ivoice Technology 7 May 15, 2022
A reactive Java framework for building fault-tolerant distributed systems

Atomix Website | Javadoc | Slack | Google Group A reactive Java framework for building fault-tolerant distributed systems Please see the website for f

Atomix 2.3k Dec 29, 2022
Reactive Microservices for the JVM

Lagom - The Reactive Microservices Framework Lagom is a Swedish word meaning just right, sufficient. Microservices are about creating services that ar

Lagom Framework 2.6k Dec 30, 2022
Open Source In-Memory Data Grid

Hazelcast Hazelcast is an open-source distributed in-memory data store and computation platform. It provides a wide variety of distributed data struct

hazelcast 5.2k Dec 31, 2022
Orbit - Virtual actor framework for building distributed systems

Full Documentation See the documentation website for full documentation, examples and other information. Orbit 1 Looking for Orbit 1? Visit the orbit1

Orbit 1.7k Dec 28, 2022
a reverse proxy load balancer using Java. Inspired by Nginx.

Project Outline: Project Main coding reverse proxy support configuration adding unit test works on Websocket Stress Test compared to Nginx load balanc

Feng 12 Aug 5, 2022
Stream Processing and Complex Event Processing Engine

Siddhi Core Libraries Siddhi is a cloud native Streaming and Complex Event Processing engine that understands Streaming SQL queries in order to captur

Siddhi - Cloud Native Stream Processor 1.4k Jan 6, 2023
Drools is a rule engine, DMN engine and complex event processing (CEP) engine for Java.

An open source rule engine, DMN engine and complex event processing (CEP) engine for Java™ and the JVM Platform. Drools is a business rule management

KIE (Drools, OptaPlanner and jBPM) 4.9k Dec 31, 2022
Dataflow template which read data from Kafka (Support SSL), transform, and outputs the resulting records to BigQuery

Kafka to BigQuery Dataflow Template The pipeline template read data from Kafka (Support SSL), transform the data and outputs the resulting records to

DoiT International 12 Jun 1, 2021
Table-Computing (Simplified as TC) is a distributed light weighted, high performance and low latency stream processing and data analysis framework. Milliseconds latency and 10+ times faster than Flink for complicated use cases.

Table-Computing Welcome to the Table-Computing GitHub. Table-Computing (Simplified as TC) is a distributed light weighted, high performance and low la

Alibaba 34 Oct 14, 2022
Apache Heron (Incubating) is a realtime, distributed, fault-tolerant stream processing engine from Twitter

Heron is a realtime analytics platform developed by Twitter. It has a wide array of architectural improvements over it's predecessor. Heron in Apache

The Apache Software Foundation 3.6k Dec 28, 2022
Vert.x is a tool-kit for building reactive applications on the JVM

Vert.x Core This is the repository for Vert.x core. Vert.x core contains fairly low-level functionality, including support for HTTP, TCP, file system

Eclipse Vert.x 13.3k Jan 8, 2023