Más contenido relacionado
La actualidad más candente (19)
Similar a Reactive Jersey Client (20)
Reactive Jersey Client
- 1. Reac%ve
Jersey
Client
Michal
Gajdos
michal.gajdos@oracle.com
January,
2015
Copyright
©
2014,
Oracle
and/or
its
affiliates.
All
rights
reserved.
- 2. Copyright
©
2015,
Oracle
and/or
its
affiliates.
All
rights
reserved.
Safe
Harbor
Statement
The
following
is
intended
to
outline
our
general
product
direc%on.
It
is
intended
for
informa%on
purposes
only,
and
may
not
be
incorporated
into
any
contract.
It
is
not
a
commitment
to
deliver
any
material,
code,
or
func%onality,
and
should
not
be
relied
upon
in
making
purchasing
decisions.
The
development,
release,
and
%ming
of
any
features
or
func%onality
described
for
Oracle’s
products
remains
at
the
sole
discre%on
of
Oracle.
- 3. Copyright
©
2015,
Oracle
and/or
its
affiliates.
All
rights
reserved.
The
Problem
A
Travel
Agency
- 4. Copyright
©
2015,
Oracle
and/or
its
affiliates.
All
rights
reserved.
A
Travel
Agency
Service
Orchestra%ng
Services
Weather
Customers
Des%na%ons
Quo%ng
Travel
Agency
- 6. Copyright
©
2015,
Oracle
and/or
its
affiliates.
All
rights
reserved.
The
Why
• Client
specific
API
– Different
needs
for
various
devices:
screen
size,
payment
methods,
...
• Single
Entry
Point
– No
need
to
communicate
with
mul%ple
services
• Thinner
client
– No
need
to
consume
different
formats
of
data
• Less
frequent
client
updates
– Doesn’t
ma]er
if
one
service
is
removed
in
favor
of
another
service
Building
an
Orchestra6on
Layer
- 7. Copyright
©
2015,
Oracle
and/or
its
affiliates.
All
rights
reserved.
The
How
JAX-‐RS
2.0
and
Jersey
2
- 8. Copyright
©
2015,
Oracle
and/or
its
affiliates.
All
rights
reserved.
Demo
Applica%on
• “Remote”
– applica%on/json,
applica%on/xml
– delays
• “Agent”
– applica%on/json
– dependent
calls
Exposed
resources
- 9. Copyright
©
2015,
Oracle
and/or
its
affiliates.
All
rights
reserved.
A
Naïve
Approach
Implemen%ng
the
Service
Get
Customer
Details
Get
a
list
of
10
Recommended
Des6na6ons
Get
Quote
for
the
Customer
Get
Weather
Forecast
for
each
Des6na6on
for
each
Des6na6on
- 10. Copyright
©
2015,
Oracle
and/or
its
affiliates.
All
rights
reserved.
Client
client
=
ClientBuilder.newClient();
WebTarget
rx
=
client.target("http://example.com/rx").register(JacksonFeature.class);
WebTarget
forecasts
=
rx.path("remote/forecast/{destination}");
Forecast
forecast
=
forecasts.resolveTemplate("destination",
dest.getDestination())
.request("application/xml")
.get(Forecast.class);
JAX-‐RS
2.0
Client
–
Synchronous
- 12. Copyright
©
2015,
Oracle
and/or
its
affiliates.
All
rights
reserved.
A
Naïve
Approach
Implemen%ng
the
Service
Get
Customer
Details
Get
a
list
of
10
Recommended
Des6na6ons
Get
Quote
for
the
Customer
Get
Weather
Forecast
for
each
Des6na6on
for
each
Des6na6on
150
ms
250
ms
1
700
ms
170
ms
3
300
ms
330
ms
5
400
ms
- 13. Copyright
©
2015,
Oracle
and/or
its
affiliates.
All
rights
reserved.
Client
–
Synchronous
Approach
• Easy
to
read,
understand
and
debug
– Simple
requests,
Composed
requests
• Slow
– Sequen%al
processing
even
for
independent
requests
• Was%ng
resources
– Wai%ng
threads
• Suitable
for
– Lower
number
of
requests
– Single
request
that
depends
on
the
result
of
previous
opera%on
- 14. Copyright
©
2015,
Oracle
and/or
its
affiliates.
All
rights
reserved.
Op6mized
Approach
Implemen%ng
the
Service
170
ms
Get
Customer
Details
Get
a
list
of
10
Recommended
Des6na6ons
Async
Get
Quote
for
the
Customer
Async
Get
Weather
Forecast
for
each
Des6na6on
for
each
Des6na6on
150
ms
250
ms
330
ms
330
ms
730
ms
- 15. Copyright
©
2015,
Oracle
and/or
its
affiliates.
All
rights
reserved.
Future<Forecast>
forecast
=
forecasts.resolveTemplate("destination",
d.getDestination())
.request()
.async()
.get(new
InvocationCallback<Forecast>()
{
@Override
public
void
completed(Forecast
forecast)
{
//
Do
Something.
}
@Override
public
void
failed(Throwable
throwable)
{
//
Do
Something
else.
}
});
while
(!forecast.isDone())
{
//
Do
Something.
}
System.out.println(forecast.get());
JAX-‐RS
2.0
Client
–
Asynchronous
- 17. Copyright
©
2015,
Oracle
and/or
its
affiliates.
All
rights
reserved.
Client
–
Asynchronous
Approach
• Returns
immediately
afer
submigng
a
request
– Future
• Harder
to
understand,
debug
– Especially
when
dealing
with
mul%ple
futures
• Fast
– Each
request
can
run
on
a
separate
thread
– Need
to
ac%vely
check
for
comple%on
event
(future.isDone())
or
block
(slow)
Futures
- 18. Copyright
©
2015,
Oracle
and/or
its
affiliates.
All
rights
reserved.
Client
–
Asynchronous
Approach
• “Don’t
call
us,
we’ll
call
you”
• Harder
to
read,
understand
and
debug
– Especially
for
composed
calls
(dependent)
• Need
to
find
out
when
all
Async
requests
finished
– Relevant
only
for
2
or
more
requests
(CountDownLatch)
• Fast
– Each
request
can
run
on
a
separate
thread
• Suitable
for
– Many
independent
calls
The
Callback
Hell
- 19. Copyright
©
2015,
Oracle
and/or
its
affiliates.
All
rights
reserved.
Beyond
The
Callback
Hell
Reac6ve
(Jersey)
Client
- 20. Copyright
©
2015,
Oracle
and/or
its
affiliates.
All
rights
reserved.
Client
–
Reac%ve
Approach
• Data-‐Flows
– Execu%on
model
propagates
changes
through
the
flow
• Asynchronous
– Preferably,
Speed
• Event-‐based
– No%fy
user
code
or
another
item
in
flow
about
con%nua%on,
error,
comple%on
• Composable
– Compose/Transform
mul%ple
flows
into
the
resul%ng
one
- 21. Copyright
©
2015,
Oracle
and/or
its
affiliates.
All
rights
reserved.
Reac%ve
Java
Libraries
• RxJava
–
Observable
– Analogy
to
Iterable
– Currently
most
advanced
reac%ve
API
in
Java
– Contributed
by
Nemlix
–
hardened
&
tested
in
produc%on
• Java
SE
8
–
CompletionStage
and
CompletableFuture
– Na%ve
part
of
JDK
– Fits
the
new
Java
Stream
API
programming
model
– JSR166e
–
Support
for
CompletableFuture
on
Java
SE
6
and
Java
SE
7
• Guava
–
ListenableFuture
and
Futures
– Similar
to
Java
SE
8
- 22. Copyright
©
2015,
Oracle
and/or
its
affiliates.
All
rights
reserved.
Observable
• Observable
(push)
– retrieve
data
–
onNext(T)
– discover
error
–
onError(Exception)
– complete
–
onCompleted()
• Iterable
(pull)
– retrieve
data
–
T
next()
– discover
error
–
throws
Exception
– complete
–
!hasNext()
- 23. Copyright
©
2015,
Oracle
and/or
its
affiliates.
All
rights
reserved.
Observable<Response>
response
=
…
;
List<String>
visited
=
new
ArrayList<>(10);
//
Read
a
list
of
destinations
from
JAX-‐RS
response
response.map(resp
-‐>
resp.readEntity(new
GenericType<List<Destination>>()
{}))
//
If
an
exception
is
thrown,
continue
with
an
empty
list
.onErrorReturn(throwable
-‐>
Collections.emptyList())
//
Emit
list
of
destinations
as
a
new
Observable
.flatMap(Observable::from)
//
Take
the
first
10
destinations
.take(10)
//
Obtain
a
string
representation
of
a
destination
.map(Destination::getDestination)
//
Observe
the
destination
events
on
a
separate
thread
.observeOn(Schedulers.io())
//
Subscribe
to
callbacks
–
OnNext,
OnError,
OnComplete
.subscribe(visited::add,
async::resume,
()
-‐>
async.resume(visited));
An
Observable<Response>
Example
- 24. Copyright
©
2015,
Oracle
and/or
its
affiliates.
All
rights
reserved.
Reac%ve
Jersey
Client
• Remember
#request()
and
#request().async()
?
– request()
returns
Invoca6on.Builder;
SyncInvoker
–
sync
HTTP
methods
– request().async()
returns
AsyncInvoker
–
async
HTTP
methods
• #rx()
and
#rx(ExecutorService)
– Return
an
extension
of
RxInvoker
Extension
of
JAX-‐RS
Client
- 25. Copyright
©
2015,
Oracle
and/or
its
affiliates.
All
rights
reserved.
public
interface
SyncInvoker
{
Response
get();
<T>
T
get(Class<T>
responseType);
<T>
T
get(GenericType<T>
responseType);
//
...
}
public
interface
AsyncInvoker
{
Future<Response>
get();
<T>
Future<T>
get(Class<T>
responseType);
<T>
Future<T>
get(GenericType<T>
responseType);
//
...
}
SyncInvoker
and
AsyncInvoker
- 26. Copyright
©
2015,
Oracle
and/or
its
affiliates.
All
rights
reserved.
public
interface
RxInvoker<T>
{
T
get();
<R>
T
get(Class<R>
responseType);
<R>
T
get(GenericType<R>
responseType);
//
...
}
public
interface
RxObservableInvoker
extends
RxInvoker<Observable>
{
Observable<Response>
get();
<T>
Observable<T>
get(Class<T>
responseType);
<T>
Observable<T>
get(GenericType<T>
responseType);
//
...
}
RxInvoker
and
an
extension
Example
- 27. Copyright
©
2015,
Oracle
and/or
its
affiliates.
All
rights
reserved.
Reac%ve
Jersey
Client
–
contd
• Affected
JAX-‐RS
interfaces
– RxInvoca%onBuilder<RX
extends
RxInvoker>
extends
Invoca%on.Builder
– RxWebTarget<RX
extends
RxInvoker>
extends
WebTarget
– RxClient<RX
extends
RxInvoker>
extends
Client
• Rx
class
– RxObservable
– RxComple%onStage
– RxListenableFuture
– RxCompletableFuture
(JSR
166e)
Extension
of
JAX-‐RS
Client
- 28. Copyright
©
2015,
Oracle
and/or
its
affiliates.
All
rights
reserved.
Client
client
=
ClientBuilder.newClient();
WebTarget
target
=
client.target("...");
//
Rx
RxClient<RxObservableInvoker>
rxClient
=
Rx.newClient(RxObservableInvoker.class);
RxClient<RxObservableInvoker>
rxClient
=
Rx.client(client,
RxObservableInvoker.class);
RxWebTarget<RxObservableInvoker>
rxTarget
=
Rx.target(target,
RxObservableInvoker.class);
//
RxObservable
RxClient<RxObservableInvoker>
rxClient
=
RxObservable.newClient();
RxClient<RxObservableInvoker>
rxClient
=
RxObservable.client(client);
RxWebTarget<RxObservableInvoker>
rxTarget
=
RxObservable.target(target);
Reac%ve
Client
–
Crea%on
- 31. Copyright
©
2015,
Oracle
and/or
its
affiliates.
All
rights
reserved.
Resources
• JAX-‐RS
Client
API
– h]ps://jax-‐rs-‐spec.java.net/nonav/2.0/apidocs/overview-‐summary.html
– h]ps://jersey.java.net/documenta%on/latest/client.html
• Jersey
Rx
Client
– h]ps://github.com/jersey/jersey/tree/master/incubator/rx/rx-‐client
– h]ps://github.com/jersey/jersey/tree/master/incubator/rx/rx-‐client-‐guava
– h]ps://github.com/jersey/jersey/tree/master/incubator/rx/rx-‐client-‐java8
– h]ps://github.com/jersey/jersey/tree/master/incubator/rx/rx-‐client-‐jsr166e
– h]ps://github.com/jersey/jersey/tree/master/incubator/rx/rx-‐client-‐rxjava
JAX-‐RS
and
Jersey
- 32. Copyright
©
2015,
Oracle
and/or
its
affiliates.
All
rights
reserved.
Resources
• 3rd
party
libraries
– h]ps://code.google.com/p/guava-‐libraries/
– h]ps://github.com/Reac%veX/RxJava
– h]p://docs.oracle.com/javase/8/docs/api/java/u%l/concurrent/package-‐
summary.html
– h]p://gee.cs.oswego.edu/dl/concurrency-‐interest/index.html
• Example
(JDK7)
– h]ps://github.com/jersey/jersey/tree/master/examples/rx-‐client-‐webapp
Example
and
Libraries