-
Notifications
You must be signed in to change notification settings - Fork 140
Local Service Proxies
Local service proxies are documented as follows.
To communicate with a service in the same JVM you need a service bundle or a service queue.
A service bundle is a collection of services that are addressable via a URL.
Let's say a service has the following methods in its interface:
public interface SomeInterface {
void method1();
void method2(String hi, int amount);
String method3(String hi, int amount);
}
To invoke method1, you could create a simple proxy as follows:
final SomeInterface myServiceProxy = serviceBundle.createLocalProxy(SomeInterface.class, "myService");
myServiceProxy.method1();
myServiceProxy.method2("hi", 5);
myServiceProxy.flushSends();
The createLocalProxy is the key here. That creates a delegate that will enqueue messages to the service.
The bundle was created beforehand as follows:
final Factory factory = QBit.factory();
final ServiceBundle bundle = factory.createBundle("/root");
bundle.addService(myService);
@RequestMapping ("myService")
public class MyServiceClass implements SomeInterface {
@Override
public void method1() {
//do something
}
@Override
public void method2(String hi, int amount) {
//do something
}
@Override
public String method3(String hi, int amount) {
return "Hi " + hi + " " + amount;
}
}
There is also bean factories and such for Spring and Guice integration. A real service would be defined in its own class.
As you can see method 1 and method 2 are inherently asycn as they return void. No return type is expected so they are fire and forget calls.
You have options for handling a call to method3 which has a return type. You can use a Handler or you can use the response queue.
Here is an example of using the response queue.
myServiceProxy.method3("hi", 5);
bundle.flushSends(); //send all outstanding calls
//Get the return from the responseReceiveQueue
final Response<Object> objectResponse = responseReceiveQueue.pollWait();
ok = "Hi hi 5".equals(objectResponse.body()) || die();
The responseObject can either be an exception/error or the actual response, i.e., the return value from the async call.
Alternatively you can use a handler as follows:
First we create the handler:
ok = false;
Handler<String> returnHandler = new Handler<String>() {
@Override
public void handle(String returnValue) {
puts("We got", returnValue);
ok = "Hihi 5".equals(returnValue);
}
};
We define a client interface for dealing with this service that is different than the actual service interface. Note the use of a service interface is completely optional. You can use Java classes without interfaces, but the client proxies must use an interface.
Client interface
public static interface MyServiceInterfaceForClient {
void method1();
void method2(String hi, int amount);
void method3(Handler<String> handler, String hi, int amount);
}
final MyServiceInterfaceForClient myServiceProxy = bundle.createLocalProxy(
MyServiceInterfaceForClient.class,
"myService");
bundle.addService(myService);
Since you will no longer be polling the response queue, but using handlers, then you need to tell the service bundle to poll the response queue for you and call you handler for you.
bundle.startReturnHandlerProcessor();
Then when you invoke the method, you pass the Handler.
myServiceProxy.method3(returnHandler, "hi", 5);
bundle.flushSends();
You can handle exceptions as well.
Given an interface like this for the client:
public interface ClientInterfaceThrowsException {
public void methodThrowsExceptionIf5(Handler<String> arg, String hi, int amount);
}
We want to call as service like this:
@RequestMapping ("myService")
public class MyServiceClass {
public String methodThrowsExceptionIf5(String hi, int amount) {
if (amount == 5) {
return die(String.class, "Hi " + hi + " " + amount);
} else {
return "Hi " + hi + " " + amount;
}
}
}
We create the service and register it with a service bundle.
MyServiceClass myService = new MyServiceClass();
final Factory factory = QBit.factory();
final ServiceBundle bundle = factory.createBundle("/root");
bundle.addService(myService);
bundle.startReturnHandlerProcessor();
Then we create a local service proxy.
final ClientInterfaceThrowsException myServiceProxy = bundle.createLocalProxy(
ClientInterfaceThrowsException.class,
"myService");
Next we create two handlers. One handler is for Exceptions, and on handler is for return types. This way you can reuse your exception handler many times.
First Handler to handle return types (this gets called async)
ok = false;
Handler<String> returnHandler = new Handler<String>() {
@Override
public void handle(String returnValue) {
puts("We got", returnValue);
ok = "Hi hi 6".equals(returnValue);
}
};
Then a handler to handle exceptions.
Handler<Throwable> exceptionHandler = new Handler<Throwable>() {
@Override
public void handle(Throwable exception) {
puts("We got", exception.getMessage());
ok = "Hi hi 5".equals(exception.getMessage());
}
};
Now we combine them:
final Handler<String> handler = Handlers.handler(returnHandler, exceptionHandler);
Now we call the proxy with non exception case.
myServiceProxy.methodThrowsExceptionIf5(handler, "hi", 6);
bundle.flushSends();
Sys.sleep(1000);
ok = ok || die();
ok = false;
Now we call it, forcing it to throw an exception.
myServiceProxy.methodThrowsExceptionIf5(handler, "hi", 5);
bundle.flushSends();
Sys.sleep(1000);
ok = ok || die();
QBit Website What is Microservices Architecture?
QBit Java Micorservices lib tutorials
The Java microservice lib. QBit is a reactive programming lib for building microservices - JSON, HTTP, WebSocket, and REST. QBit uses reactive programming to build elastic REST, and WebSockets based cloud friendly, web services. SOA evolved for mobile and cloud. ServiceDiscovery, Health, reactive StatService, events, Java idiomatic reactive programming for Microservices.
Reactive Programming, Java Microservices, Rick Hightower
Java Microservices Architecture
[Microservice Service Discovery with Consul] (http://www.mammatustech.com/Microservice-Service-Discovery-with-Consul)
Microservices Service Discovery Tutorial with Consul
[Reactive Microservices] (http://www.mammatustech.com/reactive-microservices)
[High Speed Microservices] (http://www.mammatustech.com/high-speed-microservices)
Reactive Microservices Tutorial, using the Reactor
QBit is mentioned in the Restlet blog
All code is written using JetBrains Idea - the best IDE ever!
Kafka training, Kafka consulting, Cassandra training, Cassandra consulting, Spark training, Spark consulting
Tutorials
- QBit tutorials
- Microservices Intro
- Microservice KPI Monitoring
- Microservice Batteries Included
- RESTful APIs
- QBit and Reakt Promises
- Resourceful REST
- Microservices Reactor
- Working with JSON maps and lists
__
Docs
Getting Started
- First REST Microservice
- REST Microservice Part 2
- ServiceQueue
- ServiceBundle
- ServiceEndpointServer
- REST with URI Params
- Simple Single Page App
Basics
- What is QBit?
- Detailed Overview of QBit
- High level overview
- Low-level HTTP and WebSocket
- Low level WebSocket
- HttpClient
- HTTP Request filter
- HTTP Proxy
- Queues and flushing
- Local Proxies
- ServiceQueue remote and local
- ManagedServiceBuilder, consul, StatsD, Swagger support
- Working with Service Pools
- Callback Builders
- Error Handling
- Health System
- Stats System
- Reactor callback coordination
- Early Service Examples
Concepts
REST
Callbacks and Reactor
Event Bus
Advanced
Integration
- Using QBit in Vert.x
- Reactor-Integrating with Cassandra
- Using QBit with Spring Boot
- SolrJ and service pools
- Swagger support
- MDC Support
- Reactive Streams
- Mesos, Docker, Heroku
- DNS SRV
QBit case studies
QBit 2 Roadmap
-- Related Projects
- QBit Reactive Microservices
- Reakt Reactive Java
- Reakt Guava Bridge
- QBit Extensions
- Reactive Microservices
Kafka training, Kafka consulting, Cassandra training, Cassandra consulting, Spark training, Spark consulting