Slide 1

Slide 1 text

26-27/05/2016 RxJava in Microservices World Piotr Kafel (@PiotrKafel)

Slide 2

Slide 2 text

26-27/05/2016 Microservices

Slide 3

Slide 3 text

26-27/05/2016 Trade-offs

Slide 4

Slide 4 text

26-27/05/2016 Microservices time

Slide 5

Slide 5 text

26-27/05/2016 Microservices time

Slide 6

Slide 6 text

26-27/05/2016 CompletableFuture CompletableFuture result = getUuid().thenApply(this::getString); public CompletableFuture getUuid() { // incredibly smart code goes here } public String getString(UUID uuid) { // incredibly smart code goes here }

Slide 7

Slide 7 text

26-27/05/2016 CompletableFuture CompletableFuture>> ohMyGod = getUuids() .thenApply(uuids -> uuids.stream() .map(this::getString) .collect(Collectors.toList())); public CompletableFuture> getUuids() { // incredibly smart code goes here } public CompletableFuture getString(UUID uuid) { // incredibly smart code goes here }

Slide 8

Slide 8 text

26-27/05/2016 Observable Observable result = getUuids().flatMap(this::getString); public Observable getUuids() { // incredibly smart code goes here } public Observable getString(UUID uuid) { // incredibly smart code goes here }

Slide 9

Slide 9 text

26-27/05/2016 RxJava

Slide 10

Slide 10 text

26-27/05/2016 Observable Observable.create(subscriber -> { subscriber.onNext("Hello World !"); subscriber.onCompleted(); }).forEach(System.out::println);

Slide 11

Slide 11 text

26-27/05/2016 Observable Observable.create(subscriber -> { subscriber.onNext("Hello"); subscriber.onNext("World"); subscriber.onNext("!"); subscriber.onCompleted(); }) .subscribeOn(Schedulers.newThread()) .forEach(System.out::println);

Slide 12

Slide 12 text

26-27/05/2016 Observable Observable.create(subscriber -> { try { subscriber.onNext(doSomething()); subscriber.onCompleted(); } catch(Exception e) { subscriber.onError(e); } }).forEach( i -> System.out.print(i), e -> e.printStackTrace() );

Slide 13

Slide 13 text

26-27/05/2016 Documentation

Slide 14

Slide 14 text

26-27/05/2016 Example public Observable retrieveDivisions (List divisions) { Locale locale = locale(); return Observable.from(divisions) .flatMap(divisionId -> geoPlacesClient.getDivisionsById(divisionId)) .filter(resp -> resp.status == SUCCESS) .flatMapIterable(resp -> resp.data) .filter(div -> div.status == Status.ACTIVE) .map(div -> new DealDivision( div.uuid.toString(), div.getNameOrDefault(locale))); }

Slide 15

Slide 15 text

26-27/05/2016 Pattern doHttpCallForUUids() .buffer(50) .flatMap(listOfUuids -> doHttpCallForEntities(listOfUuids));

Slide 16

Slide 16 text

26-27/05/2016 Pattern doHttpCall().retry( (i, throwable) -> i < 5 && throwable instanceof Status503Exception );

Slide 17

Slide 17 text

26-27/05/2016 Pattern doHttpCall().retryWhen(errorObservable -> errorObservable .zipWith(Observable.range(1, numberOfRetries), Pair::of) .flatMap(pair -> { if(pair.getRight() == numberOfRetries) { return Observable.error(pair.getLeft()); } else { return Observable.timer(wait, TimeUnit.MILLISECONDS); } }));

Slide 18

Slide 18 text

26-27/05/2016 Pattern Observable.range(1, Integer.MAX_VALUE) .concatMap(page -> doHttpCall(id, page, DEFAULT_PER_PAGE_SIZE)) .map(response -> response.getComments()) .takeWhile(comments -> comments.size() > 0)

Slide 19

Slide 19 text

26-27/05/2016 Adaptation Observable.defer(() -> Observable.just(completelySynchronousHttpCall())) .subscribeOn(Schedulers.io());

Slide 20

Slide 20 text

26-27/05/2016 Testing TestSubscriber subscriber = new TestSubscriber<>(); Observable.interval(100, TimeUnit.MILLISECONDS, Schedulers.computation()) .take(5) .map(i -> i + " value") .subscribe(subscriber); subscriber.awaitTerminalEvent(); subscriber.assertNoErrors(); subscriber.assertValueCount(5);

Slide 21

Slide 21 text

26-27/05/2016 Retrofit

Slide 22

Slide 22 text

26-27/05/2016 Retrofit public interface InventoryUnitClient { @GET("/inventory/v2/{entity}/search/redemption") Observable getInventoryUnitRedemption( @Path("uuid") UUID uuid); @POST("/inventory/v2/{entity}/search/redemption") Observable redeemUnit( @Path("uuid") UUID uuid, @Body JsonHolder redemption); }

Slide 23

Slide 23 text

26-27/05/2016 Hystrix

Slide 24

Slide 24 text

26-27/05/2016 Hystrix public class CommandHelloWorld extends HystrixCommand { private final String name; public CommandHelloWorld(String name) { super(HystrixCommandGroupKey.Factory.asKey("ExampleGroup")); this.name = name; } @Override protected String run() { return "Hello " + name + "!"; } }

Slide 25

Slide 25 text

26-27/05/2016 Spring

Slide 26

Slide 26 text

26-27/05/2016 Spring @RequestMapping(value = PATH_ACCOUNT_MANAGERS, method = RequestMethod.GET) public DeferredResult getAccountManagers() { DeferredResult result = new DeferredResult<>(); getAccountManagersObservable().subscribe( item -> result.setResult(item), exception -> result.setErrorResult(exception) ); return result; }

Slide 27

Slide 27 text

26-27/05/2016 Wow, is it really that cool !?

Slide 28

Slide 28 text

26-27/05/2016 That’s all folks !