Successfully reported this slideshow.
We use your LinkedIn profile and activity data to personalize ads and to show you more relevant ads. You can change your ad preferences anytime.

Reactive Jersey Client

6,641 views

Published on

CZJUG presentation (January 2015).

Published in: Software
  • Be the first to comment

Reactive Jersey Client

  1. 1. Reac%ve  Jersey  Client   Michal  Gajdos   michal.gajdos@oracle.com     January,  2015   Copyright  ©  2014,  Oracle  and/or  its  affiliates.  All  rights  reserved.      
  2. 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. 3. Copyright  ©  2015,  Oracle  and/or  its  affiliates.  All  rights  reserved.       The  Problem   A  Travel  Agency  
  4. 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  
  5. 5. Copyright  ©  2015,  Oracle  and/or  its  affiliates.  All  rights  reserved.       The  Why  
  6. 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. 7. Copyright  ©  2015,  Oracle  and/or  its  affiliates.  All  rights  reserved.       The  How   JAX-­‐RS  2.0  and  Jersey  2  
  8. 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. 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. 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  
  11. 11. Copyright  ©  2014,  Oracle  and/or  its  affiliates.  All  rights  reserved.       DEMO  
  12. 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. 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. 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. 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  
  16. 16. Copyright  ©  2014,  Oracle  and/or  its  affiliates.  All  rights  reserved.       DEMO  
  17. 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. 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. 19. Copyright  ©  2015,  Oracle  and/or  its  affiliates.  All  rights  reserved.       Beyond  The  Callback  Hell   Reac6ve  (Jersey)  Client  
  20. 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. 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. 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. 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. 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. 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. 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. 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. 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  
  29. 29. Copyright  ©  2014,  Oracle  and/or  its  affiliates.  All  rights  reserved.       DEMO  
  30. 30. Copyright  ©  2014,  Oracle  and/or  its  affiliates.  All  rights  reserved.       Q&A  
  31. 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. 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  

×