Skip to content

Releases: advantageous/qbit

QBit Java Reactive Microservices Lib Release 0.9.7

11 Apr 00:18
Compare
Choose a tag to compare

QBit Java Reactive Microservices Lib.

Updated to match Reakt 1.0.0.RELEASE.
You can now use Reakt Reactor instead of QBit Reactor on new projects.

QBit Java Reactive Microservices Lib Release 0.9.5

09 Apr 18:37
Compare
Choose a tag to compare

This is mostly to fix an issue with the maven pom that was introduced in the QBit Release 0.9.4.
There is also some code formatting.

QBit Java Reactive Microservices Lib Release 0.9.4

09 Apr 02:47
Compare
Choose a tag to compare

QBit Java Reactive Microservices Lib Release 0.9.4.

Added support for Reakt and started using it.
Also changed QBit Callbacks to be more compatible with Reakt Callbacks to make the transition easier.

QBit Java Reactive Microservices Lib Release 0.9.3

06 Apr 05:41
Compare
Choose a tag to compare
        /* Add a task that repeats every ten seconds. */
        reactor.addOneShotAfterTask(10, TimeUnit.SECONDS, () -> {
            test.set(true);
            count.incrementAndGet();
        });
final ManagedServiceBuilder managedServiceBuilder = managedServiceBuilder().setRootURI("/");

managedServiceBuilder.enableLoggingMappedDiagnosticContext();

QBit 0.9.1 Release

29 Oct 22:20
Compare
Choose a tag to compare

There were a lot of features added that users asked for (some a long time ago).

As we touch things to add JSend, we found easy ways to add some features users have been asking for.

There is also some docs for JMS support, Kafka support, DNS Service Discovery, sending back HTTP response codes other than 200, and 202, sending error response codes other than 500, service discovery aware web socket proxies, kv store/ kv cache support for Redis (async), improvements in speed for services with just a few clients (QBit was built for high-volume so we had to add some things to make it faster for low volume), and more.

1) Support for non-JSON bodies from REST end-points

Added support for String and byte[] to be passed without JSON parsing.

Issue.
Docs Added to wiki main.

    @RequestMapping(value = "/body/bytes", method = RequestMethod.POST)
    public boolean bodyPostBytes( byte[] body) {
        String string = new String(body, StandardCharsets.UTF_8);
        return string.equals("foo");
    }

    @RequestMapping(value = "/body/string", method = RequestMethod.POST)
    public boolean bodyPostString(String body) {
        return body.equals("foo");
    }

If the Content-Type of the request is null or is application/json then we will parse the body as JSON.
If the Content-Type is set and is not application/json then we will pass the raw String or raw bytes. This allows you to handle non-JSON content from REST. It does not do any auto-conversion. You will get the raw bytes or raw UTF-8 string.

    @Test
    public void testNoJSONParseWithBytes() {

        final HttpTextResponse httpResponse = httpServerSimulator.sendRequest(
                httpRequestBuilder.setUri("/es/body/bytes")
                        .setMethodPost().setContentType("foo")
                        .setBody("foo")
                        .build()
        );
        assertEquals(200, httpResponse.code());
        assertEquals("true", httpResponse.body());
    }


    @Test
    public void testNoJSONParseWithString() {

        final HttpTextResponse httpResponse = httpServerSimulator.sendRequest(
                httpRequestBuilder.setUri("/es/body/string")
                        .setMethodPost().setContentType("foo")
                        .setBody("foo")
                        .build()
        );

        assertEquals(200, httpResponse.code());
        assertEquals("true", httpResponse.body());

    }

2) Added HttpProxy support

You can proxy backend services from a single endpoint.
This also allows you to do actions before sending the request, and to not forward the request based on a Predicate.

Issue
Docs
Code

3) Added ability to return different response codes for success

By default QBit sends a 200 (OK) for a non-void call (a call that has a return or a Callback).
If the REST operation has no return or no callback then QBit sends a 202 (Accepted).
There may be times when you want to send a 201 (Created) or some other code that is not an Exception.
You can do that by setting code on @RequestMapping. By default the code is -1 which means use the default behavior.

Issue
Docs Added to wiki main.

  @RequestMapping(value = "/helloj7", code = 221)
    public void helloJSend7(Callback<JSendResponse<List<String>>> callback) {
        callback.returnThis(JSendResponseBuilder.jSendResponseBuilder(Lists.list(
                "hello " + System.currentTimeMillis())).build());
    }

4) Working with non JSON responses

Issue
Docs Added to wiki main.

You do not have to return JSON form rest calls.
You can return any binary or any text.

4.1) Returning non JSON from REST call

      @RequestMapping(method = RequestMethod.GET)
        public void ping2(Callback<HttpTextResponse> callback) {

            callback.returnThis(HttpResponseBuilder.httpResponseBuilder()
                    .setBody("hello mom").setContentType("mom")
                    .setCode(777)
                    .buildTextResponse());
        }

4.2) Returning binary from REST call

      @RequestMapping(method = RequestMethod.GET)
        public void ping2(Callback<HttpBinaryResponse> callback) {

            callback.returnThis(HttpResponseBuilder.httpResponseBuilder()
                    .setBody("hello mom").setContentType("mom")
                    .setCode(777)
                    .buildBinaryResponse());
        }

5) Create websocket service client that is ServiceDiscovery aware

ServiceDiscovery-aware websocket service client

        final Client client = clientBuilder
                .setServiceDiscovery(serviceDiscovery, "echo")
                .setUri("/echo").setProtocolBatchSize(20).build()
                 .startClient();

        final EchoAsync echoClient = client.createProxy(EchoAsync.class, "echo");

Currently the clientBuilder will load all service endpoints that are registered under the service name,
and randomly pick one.

In the future we can RoundRobin calls or shard calls to websocket service and/or provide auto fail over if the connection is closed. We do this for the event bus that uses service discovery but it is not baked into WebSocket based client stubs yet.

Issue.

For comparison here is a non-ServiceDiscovery version.

        final ClientBuilder clientBuilder = ClientBuilder.clientBuilder();
        final Client client = clientBuilder.setHost("localhost")
                .setPort(8080).setUri("/echo")
                .build().startClient();

        final EchoAsync echoClient = client.createProxy(EchoAsync.class, "echo");

Recall ServiceDiscovery includes Consul based, watching JSON files on disk, and DNS SVR records. It is easy to write your own service discovery as well and plug it into QBit.

6) JSend support for serialization and swagger

We started to add JSend support.
The JSend is supported for marshaling JSend objects, and via our Swagger support.

@RequestMapping("/hw")
public class HelloWorldJSend {

    public static class Hello {
        final String hello;

        public Hello(String hello) {
            this.hello = hello;
        }
    }

    @RequestMapping("/hello")
    public String hello() {
        return "hello " + System.currentTimeMillis();
    }



    @RequestMapping("/helloj")
    public JSendResponse<String> helloJSend() {

        return JSendResponseBuilder.jSendResponseBuilder("hello " + System.currentTimeMillis()).build();
    }


    @RequestMapping("/helloj2")
    public JSendResponse<Hello> helloJSend2() {

        return JSendResponseBuilder.jSendResponseBuilder(new Hello("hello " + System.currentTimeMillis())).build();
    }


    @RequestMapping("/helloj3")
    public JSendResponse<List<String>> helloJSend3() {

        return JSendResponseBuilder.jSendResponseBuilder(Lists.list("hello " + System.currentTimeMillis())).build();
    }


    @RequestMapping("/helloj4")
    public JSendResponse<List<Hello>> helloJSend4() {

        return JSendResponseBuilder.jSendResponseBuilder(Lists.list(new Hello("hello " + System.currentTimeMillis()))).build();
    }


    @RequestMapping("/helloj5")
    public void helloJSend5(Callback<JSendResponse<List<Hello>>> callback) {

        callback.returnThis(JSendResponseBuilder.jSendResponseBuilder(Lists.list(new Hello("hello " + System.currentTimeMillis()))).build());
    }

    @RequestMapping("/helloj6")
    public void helloJSend6(Callback<JSendResponse<List<String>>> callback) {
        callback.returnThis(JSendResponseBuilder.jSendResponseBuilder(Lists.list(
                "hello " + System.currentTimeMillis())).build());
    }


    @RequestMapping(value = "/helloj7", code = 221)
    public void helloJSend7(Callback<JSendResponse<List<String>>> callback) {
        callback.returnThis(JSendResponseBuilder.jSendResponseBuilder(Lists.list(
                "hello " + System.currentTimeMillis())).build());
    }

Hitting the above

# String respnose
curl http://localhost:8080/hw/hello | jq .
"hello 1446088919561"

# JSend wrapping a a string
$ curl http://localhost:8080/hw/helloj | jq .
{
  "data": "hello 1446088988074",
  "status": "success"
}

#JSend wrapping a domain Object Hello
$ curl http://localhost:8080/hw/helloj2 | jq .
{
  "data": {
    "hello": "hello 1446089041902"
  },
  "status": "success"
}

#JSend wrapping a list of domain objects
$ curl http://localhost:8080/hw/helloj5 | jq .
{
  "data": [
    {
      "hello": "hello 1446089152089"
    }
  ],
  "status": "success"
}

Use jq to get pretty print JSON from QBit.

In this example we setup the admin interface as well so we can query swagger gen.

Starting up admin

    public static void main(final String... args) {
        final ManagedServiceBuilder managedServiceBuilder =
                ManagedServiceBuilder.managedServiceBuilder().setRootURI("/");

        /* Start the service. */
        managedServiceBuilder.addEndpointService(new HelloWorldJSend())
                .getEndpointServerBuilder()
                .build().startServer();

        /* Start the admin builder which exposes health end-points and meta data. */
        managedServiceBuilder.getAdminBuilder().build().startServer();

        System.out.println("Servers started");

     ...
Read more

QBit 0.9.0 RELEASE

16 Sep 20:41
Compare
Choose a tag to compare
  • Admin: Added support for suggest GC.
  • Queue: Added warning messages if queue has not been started and you are sending items to a stopped queue
  • Health: Added a info message if you start more than one health system, and debug support.
  • Spring: Fixed bug with not starting health service
  • REST: Added @HideMethod annotation. Any method annotated with @HideMethod will not show up as REST end point, and will not be processes by Swagger.
  • Added chained predicates support for HttpServer
  • Admin: Fixed issue with stats for Heroku
  • Added better URI param handling (issue fixed resource handling with URI params)
  • Issue fixed with callback from REST (not getting sent to client). BoonServiceMethodCallHandler was missing onTimeout and onError. (Bug fix)
  • Admin GC stats collection and GC stat count fixed
  • (EndpointServer, REST support, HttpServer) Finished with response decorator and handling response in a callback.
  • Added spring support for discovery and construction os QBit Services
  • Added javax.inject support
  • Added response decorator capability (HttpServer to support CORS)
  • Added the ability for REST methods to return a HttpResponse object via callback
  • Changed to using longs for stats service (StatService)
  • Admin: Changed stats gathering for jvm. (no more .mb)
  • Admin: Added Buffered StatsCollector for performance of stats collection
  • Admin: Wrapped construction of stats collector with statscollectorbuffer
  • Added better error handling: QBit does not support method overloading and should give a warning instead of failing silently
  • Admin: Added support for more endpoints about the OS and VM for debugging.
  • Admin: Added password screen from property map.
  • Admin: Added black list for env variables and system properties
  • Swagger: Clean up error handling for admin and meta-data reader
  • HttpServer / EndpointServer: Improve info message so it does not say null for host
  • Admin: Added admin port env var
  • REST support now works with Map<String, Object>, and can converts all Value types to non-value types and sub-maps (Map<String, Object>)

QBit 0.9.0 Milestone 4

09 Sep 22:30
Compare
Choose a tag to compare
0.9.0.M4

m4 release

QBit 0.8.18 RELEASE

17 Aug 17:17
Compare
Choose a tag to compare
  • Improved swagger
  • Added JVM stats collection
  • Created auto service discovery / consul checkin for endpoint servers and http servers

QBit 0.8.16 RELEASE

04 Aug 23:42
Compare
Choose a tag to compare

• Exposed swagger through admin
• Added admin endpoint to ManagedServiceBuilder
• Exposed admin endpoint as __admin to make it consistent with local stats collections and health
• Added support for Map<String, String> to swagger support
• Added ssl support to http server and client
• Fixed bug in BasicQueue when dealing with ArrayBlockingQueue
• Fixed ServiceBuilder so you can pass beforeMethodCall or beforeMethodCallAfterTransform
• Fixed health check NPE which was happening every hour or so
• Auto registry with endpoint builder to service discovery and health implemented
• EventBusCluster now uses Service Discovery instead of using Consul direct

QBit 0.8.15 RELEASE

11 Jul 00:58
Compare
Choose a tag to compare
  • Added support for annotations by default like @JsonIgnore, @SerializedName, etc.
  • Health Service was sending too many pings. The timer was not reset after send.
  • Added local stats collection to store stats were they can be retrieved by 3rd party and stored.
  • Added reading default web port from environment variable which is compatible with Mesos, Heroku, and Docker
  • Documented and tested removing /serivces to / or /whatever
  • Switched Consul client to use HTTP and not to use connection pools
  • got rid of extra call to flush which was failing for proxies
    from stats service. This was filling up logging for non-remote stats.
  • Added utility class to implement /__health and /__stats/instance endpoints
  • Improved statsd replicator. making it less chatty. fixed timing.
  • Improved ServiceContext support and added ability to mark a service as down for health system auto-checkins.