53
‹#› © 2016 Pivotal Software, Inc. All rights reserved. Cloud Foundry Java Client 2.0 Toshiaki Maki (@making) Cloud Foundry Tokyo Meetup #1 2016-03-31

Cloud Foundy Java Client V 2.0 #cf_tokyo

Embed Size (px)

Citation preview

Page 1: Cloud Foundy Java Client V 2.0 #cf_tokyo

‹#›© 2016 Pivotal Software, Inc. All rights reserved. ‹#›© 2016 Pivotal Software, Inc. All rights reserved.

Cloud Foundry Java Client 2.0Toshiaki Maki (@making) Cloud Foundry Tokyo Meetup #1 2016-03-31

Page 2: Cloud Foundy Java Client V 2.0 #cf_tokyo

‹#›© 2016 Pivotal Software, Inc. All rights reserved.

Who am I ?• Toshiaki Maki (@making)

•Sr. Solutions Architect

•Spring Framework enthusiast

Spring Framework 徹底入門

(Coming Soon)

Perfect Java EE

(Coming Soon)

Page 3: Cloud Foundy Java Client V 2.0 #cf_tokyo

‹#›© 2016 Pivotal Software, Inc. All rights reserved.

Agenda•How CF Java Client V1 was 😟

•How CF Java Client V2 looks 😎

Page 4: Cloud Foundy Java Client V 2.0 #cf_tokyo

‹#›© 2016 Pivotal Software, Inc. All rights reserved.

Cloud Foundry Java Client V1CloudCredentials credentials = new CloudCredentials("username", "password"); CloudFoundryClient client = new CloudFoundryClient(credentials, URI.create("https://api.run.pivotal.io").toURL()); client.login();// cf appsList<CloudApplication> apps = client.getApplications();// cf app helloCloudApplication app = client.getApplication("hello");

Page 5: Cloud Foundy Java Client V 2.0 #cf_tokyo

‹#›© 2016 Pivotal Software, Inc. All rights reserved.

Cloud Foundry Java Client V1// cf push hello -p foo.jar -m 512m -i 2client.createApplication("hello", new Staging(), 512, singletonList("hello.cfapps.io"), emptyList()); client.uploadApplication("hello", new File("foo.jar")); client.updateApplicationInstances("hello", 2); client.startApplication("hello");// cf logsclient.streamLogs("hello", new ApplicationLogListener() { public void onMessage(ApplicationLog log) { System.out.println(log.getMessage()); } public void onComplete() {} public void onError(Throwable exception) {} });

Page 6: Cloud Foundy Java Client V 2.0 #cf_tokyo

‹#›© 2016 Pivotal Software, Inc. All rights reserved.

Problems in V1•Monolithic implementation •No separation between API and Command

•Dependency on Spring Framework (RestTemplate)

•Blocking, Inefficient use of CC API

CF Java Client 2.0 design

Page 7: Cloud Foundy Java Client V 2.0 #cf_tokyo

‹#›© 2016 Pivotal Software, Inc. All rights reserved.

Too many overloading…😫

Page 8: Cloud Foundy Java Client V 2.0 #cf_tokyo

‹#›© 2016 Pivotal Software, Inc. All rights reserved.

130+ methods…😫

Page 9: Cloud Foundy Java Client V 2.0 #cf_tokyo

‹#›© 2016 Pivotal Software, Inc. All rights reserved.

I don’t need MVC…😫

Page 10: Cloud Foundy Java Client V 2.0 #cf_tokyo

‹#›© 2016 Pivotal Software, Inc. All rights reserved.

Cloud Foundry Java Client V1

// cf appsclient.getApplications();// cf app helloclient.getApplication("hello");// cf pushclient.createApplication(...); client.uploadApplication(...); client.updateApplicationInstances(...); client.startApplication(...);

Blocking 😫

Blocking 😫

Blocking 😫

Page 11: Cloud Foundy Java Client V 2.0 #cf_tokyo

‹#›© 2016 Pivotal Software, Inc. All rights reserved.

Cloud Foundry Java Client V2

https://lists.cloudfoundry.org/archives/list/[email protected]/thread/W4455NML53LLSUSP25J2OXIYP2FNWUI4/

Page 12: Cloud Foundy Java Client V 2.0 #cf_tokyo

‹#›© 2016 Pivotal Software, Inc. All rights reserved.

Project Structure in V2

cloudfoundry-client

cloudfoundry-operations

cloudfoundry-client-spring

Implements

Uses

CLI (cf ...)

REST API (CC API)

low level

high level

Page 13: Cloud Foundy Java Client V 2.0 #cf_tokyo

‹#›© 2016 Pivotal Software, Inc. All rights reserved.

Class DiagramCloudFoundryOperations

DefaultCloudFoundryOperations

CloudFoundryClient

SpringCloudFoundryClient

Uses

LoggingClient

SpringLoggingClient

Uses

Uses

Page 14: Cloud Foundy Java Client V 2.0 #cf_tokyo

‹#›© 2016 Pivotal Software, Inc. All rights reserved.

In Future?

CloudFoundryClient

SpringCloudFoundryClient

RetrofitCloudFoundryClient

AndroidCloudFoundryClient

for non-Spring user

for Android user

Page 15: Cloud Foundy Java Client V 2.0 #cf_tokyo

‹#›© 2016 Pivotal Software, Inc. All rights reserved.

SpringCloudFoundryClient cloudfoundryClient = SpringCloudFoundryClient.builder() .host("api.run.pivotal.io") .username("user") .password("password") .build();

LoggingClient loggingClient = SpringLoggingClient.builder() .cloudFoundryClient(cloudFoundryClient) .build();

CloudFoundryOperations operations = new CloudFoundryOperationsBuilder() .cloudFoundryClient(cloudFoundryClient) .target("org", "space") .loggingClient(loggingClient) .build();

Builder Pattern

Page 16: Cloud Foundy Java Client V 2.0 #cf_tokyo

‹#›© 2016 Pivotal Software, Inc. All rights reserved.

// cf appsoperations.applications().list();// cf app hellooperations.applications() .get(GetApplicationRequest.builder() .name("hello").build());// cf push hello -p foo.jar -m 512m -i 2operations.applications() .push(PushApplicationRequest.builder() .name("hello").path("foo.jar") .memory(512).instances(2).build());// cf logs hellooperations.applications().logs(LogsRequest.builder() .name("hello").build());

Page 17: Cloud Foundy Java Client V 2.0 #cf_tokyo

‹#›© 2016 Pivotal Software, Inc. All rights reserved.

Problems in V1•Monolithic implementation •No separation between API and Command

•Dependency on Spring Framework (RestTemplate)

•Blocking, Inefficient use of CC API

CF Java Client 2.0 design

😄😄😄

What about this?

Page 18: Cloud Foundy Java Client V 2.0 #cf_tokyo

‹#›© 2016 Pivotal Software, Inc. All rights reserved.

Non-Blocking!! Non-Blocking!!•Go reactive! 😎 •Move imperative logic to async, event-driven,

functional-style code

Page 19: Cloud Foundy Java Client V 2.0 #cf_tokyo

‹#›© 2016 Pivotal Software, Inc. All rights reserved.

Why Reactive?

http://www.slideshare.net/SpringCentral/reactive-web-applications-53170985

http://www.slideshare.net/SpringCentral/introduction-to-reactive-programming

Page 20: Cloud Foundy Java Client V 2.0 #cf_tokyo

‹#›© 2016 Pivotal Software, Inc. All rights reserved.

Why Reactive?

https://spring.io/blog/2016/03/11/reactor-core-2-5-becomes-a-unified-reactive-foundation-on-java-8#comment-2564120598

Page 21: Cloud Foundy Java Client V 2.0 #cf_tokyo

‹#›© 2016 Pivotal Software, Inc. All rights reserved.

V2 supports Reactive Streams!!•Non-Blocking APIs

// cf appsPublisher<ApplicationSummary> apps = operations.applications().list();

Page 22: Cloud Foundy Java Client V 2.0 #cf_tokyo

‹#›© 2016 Pivotal Software, Inc. All rights reserved.

Reactive Streams•Standard interfaces for asynchronous stream

processing with non-blocking back pressure •De facto standard for interop between reactive

libraries •Implemented by •Akka Streams •Reactor •RxJava • etc…

http://www.reactive-streams.org/

Page 23: Cloud Foundy Java Client V 2.0 #cf_tokyo

‹#›© 2016 Pivotal Software, Inc. All rights reserved.

Reactive Streams has 4 interfacespublic interface Publisher<T> { public void subscribe(Subscriber<? super T> s);}public interface Subscription { public void request(long n); public void cancel();}public interface Subscriber<T> { public void onSubscribe(Subscription s); public void onNext(T t); public void onError(Throwable t); public void onComplete();}public interface Processor<T, R> extends Publisher<T>, Subscriber<R> {}

Page 24: Cloud Foundy Java Client V 2.0 #cf_tokyo

‹#›© 2016 Pivotal Software, Inc. All rights reserved.

Subscription SubscriberPublisher Application

Page 25: Cloud Foundy Java Client V 2.0 #cf_tokyo

‹#›© 2016 Pivotal Software, Inc. All rights reserved.

Subscription SubscriberPublisher Application

subscribe(Subscriber)

Page 26: Cloud Foundy Java Client V 2.0 #cf_tokyo

‹#›© 2016 Pivotal Software, Inc. All rights reserved.

Subscription SubscriberPublisher Application

onSubscribe(Subscription)

subscribe(Subscriber)

Page 27: Cloud Foundy Java Client V 2.0 #cf_tokyo

‹#›© 2016 Pivotal Software, Inc. All rights reserved.

Subscription SubscriberPublisher Application

onSubscribe(Subscription)

request(1)

subscribe(Subscriber)

Page 28: Cloud Foundy Java Client V 2.0 #cf_tokyo

‹#›© 2016 Pivotal Software, Inc. All rights reserved.

Subscription SubscriberPublisher Application

onSubscribe(Subscription)

request(1)

onNext(●)

subscribe(Subscriber)

Page 29: Cloud Foundy Java Client V 2.0 #cf_tokyo

‹#›© 2016 Pivotal Software, Inc. All rights reserved.

Subscription SubscriberPublisher Application

onSubscribe(Subscription)

request(1)

onNext(●)

request(2)

subscribe(Subscriber)

Page 30: Cloud Foundy Java Client V 2.0 #cf_tokyo

‹#›© 2016 Pivotal Software, Inc. All rights reserved.

Subscription SubscriberPublisher Application

onSubscribe(Subscription)

request(1)

onNext(●)

request(2)

onNext(●)

subscribe(Subscriber)

Page 31: Cloud Foundy Java Client V 2.0 #cf_tokyo

‹#›© 2016 Pivotal Software, Inc. All rights reserved.

Subscription SubscriberPublisher Application

onSubscribe(Subscription)

request(1)

onNext(●)

request(2)

onNext(●)

onNext(●)

subscribe(Subscriber)

Page 32: Cloud Foundy Java Client V 2.0 #cf_tokyo

‹#›© 2016 Pivotal Software, Inc. All rights reserved.

Subscription SubscriberPublisher Application

onSubscribe(Subscription)

request(1)

onNext(●)

request(2)

onNext(●)

onNext(●)

request(4)

subscribe(Subscriber)

Page 33: Cloud Foundy Java Client V 2.0 #cf_tokyo

‹#›© 2016 Pivotal Software, Inc. All rights reserved.

Subscription SubscriberPublisher Application

onSubscribe(Subscription)

request(1)

onNext(●)

request(2)

onNext(●)

onNext(●)

request(4)

onNext(●)

subscribe(Subscriber)

Page 34: Cloud Foundy Java Client V 2.0 #cf_tokyo

‹#›© 2016 Pivotal Software, Inc. All rights reserved.

Subscription SubscriberPublisher Application

onSubscribe(Subscription)

request(1)

onNext(●)

request(2)

onNext(●)

onNext(●)

request(4)

onNext(●)

onNext(●)

subscribe(Subscriber)

Page 35: Cloud Foundy Java Client V 2.0 #cf_tokyo

‹#›© 2016 Pivotal Software, Inc. All rights reserved.

Subscription SubscriberPublisher Application

onSubscribe(Subscription)

request(1)

onNext(●)

request(2)

onNext(●)

onNext(●)

request(4)

onNext(●)

onNext(●)

onComplete()

subscribe(Subscriber)

Page 36: Cloud Foundy Java Client V 2.0 #cf_tokyo

‹#›© 2016 Pivotal Software, Inc. All rights reserved.

Reactive Streams with CF Java Client// cf appsPublisher<ApplicationSummary> apps = operations.applications() .list();

Page 37: Cloud Foundy Java Client V 2.0 #cf_tokyo

‹#›© 2016 Pivotal Software, Inc. All rights reserved.

Reactive Streams with CF Java Client// cf appsPublisher<ApplicationSummary> apps = operations.applications() .list(); services.subscribe(new Subscriber<ServiceInstance>() { Subscription s; public void onSubscribe(Subscription subscription) { this.s = subscription; subscription.request(1); } public void onNext(ServiceInstance i) { System.out.println(i.getName() + " : " + i.getService()); this.s.request(1); // one by one } public void onError(Throwable throwable) {} public void onComplete() {} });

Page 38: Cloud Foundy Java Client V 2.0 #cf_tokyo

‹#›© 2016 Pivotal Software, Inc. All rights reserved.

Reactive Streams with CF Java Client// cf appsPublisher<ApplicationSummary> apps = operations.applications() .list(); services.subscribe(new Subscriber<ServiceInstance>() { Subscription s; public void onSubscribe(Subscription subscription) { this.s = subscription; subscription.request(1); } public void onNext(ServiceInstance i) { System.out.println(i.getName() + " : " + i.getService()); this.s.request(1); // one by one } public void onError(Throwable throwable) {} public void onComplete() {} });

😟

No higher level abstractions like composition

Page 39: Cloud Foundy Java Client V 2.0 #cf_tokyo

‹#›© 2016 Pivotal Software, Inc. All rights reserved.

Reactive eXtensions •A pattern for composing potentially asynchronous and

event-based programs by using sequences or elements.

•On the JVM

•RxJava is the most used implementation

•Reactor Core is the main alternative

•Also for other languages, for example RxJava

•Some composition libraries doesn't follow closely RxPattern (Akka) https://speakerdeck.com/sdeleuze/a-lite-rx-api-for-the-jvm?slide=9

http://reactivex.io/

Page 40: Cloud Foundy Java Client V 2.0 #cf_tokyo

‹#›© 2016 Pivotal Software, Inc. All rights reserved.

Reactor

•Yet Another Rx library on the JVM

•Natively built on top of Reactive Streams

•Developed by Pivotal

•Reactor Core provides lite Rx API

• Flux / Mono

•CF Java Client V2 embraces Reactor Core

https://projectreactor.io/

Page 41: Cloud Foundy Java Client V 2.0 #cf_tokyo

‹#›© 2016 Pivotal Software, Inc. All rights reserved.

Flux / Mono•Both implement Publisher with Rx API

• Flux for 0..N elements

• Mono for 0..1 element

Page 42: Cloud Foundy Java Client V 2.0 #cf_tokyo

‹#›© 2016 Pivotal Software, Inc. All rights reserved.

FluxFlux<Integer> stream1 = Flux.just(1, 2, 3) .map(x -> x * 2) .filter(x -> x > 2); // 4, 6Flux<String> stream2 = Flux.just("a", "b", "c");

Flux.zip(stream1, stream2) .consume(t -> System.out.println(t.t1 + ":" + t.t2));Flux.merge(stream1, stream2) .consume(x -> System.out.println(x));

Page 43: Cloud Foundy Java Client V 2.0 #cf_tokyo

‹#›© 2016 Pivotal Software, Inc. All rights reserved.

FluxFlux<Integer> stream1 = Flux.just(1, 2, 3) .map(x -> x * 2) .filter(x -> x > 2); // 4, 6Flux<String> stream2 = Flux.just("a", "b", "c");

Flux.zip(stream1, stream2) .consume(t -> System.out.println(t.t1 + ":" + t.t2));Flux.merge(stream1, stream2) .consume(x -> System.out.println(x));

4:a6:b

46abc

Page 44: Cloud Foundy Java Client V 2.0 #cf_tokyo

‹#›© 2016 Pivotal Software, Inc. All rights reserved.

MonoMono<Boolean> result = Mono.just(true); result.consume(x -> System.out.println("result=" + x)); Mono<String> delayed = Mono .delay(Duration.ofSeconds(1)) .after(() -> Mono.just("Hi")); delayed.consume(x -> System.out.println("result=" + x)); Mono<Void> noValue = Mono.empty(); noValue .doOnSuccess(x -> System.out.println("finished!")) .subscribe();

Page 45: Cloud Foundy Java Client V 2.0 #cf_tokyo

‹#›© 2016 Pivotal Software, Inc. All rights reserved.

Type comparisonNo value Single value Multiple values

Sync (JDK)

void TFuture<T>

Iterable<T>Collection<T>java.util.stream.Stream<T>

Async (JDK)

CompletableFuture<Void> CompletableFuture<T> CompletableFuture<List<T>>

Reactive Streams

Publisher<Void> Publisher<T> Publisher<T>

RxJava Observable<Void>Completable

Single<T> Observable<T>

Reactor Mono<Void> Mono<T> Flux<T>

Page 46: Cloud Foundy Java Client V 2.0 #cf_tokyo

‹#›© 2016 Pivotal Software, Inc. All rights reserved.

Reactor with CF Java Client// cf appsFlux<ApplicationSummary> apps = operations .applications().list();apps.map(app -> app.getName()) .consume(x -> System.out.println("name=" + x));

// cf appMono<ApplicationDetail> app = operations .applications().get(GetApplicationRequest.builder() .name("hello").build());app.map(app -> app.getName()) .consume(x -> System.out.println("name=" + x));

Page 47: Cloud Foundy Java Client V 2.0 #cf_tokyo

‹#›© 2016 Pivotal Software, Inc. All rights reserved.

Reactor with CF Java Client// cf push hello -p foo.jar -m 512m -i 2Mono<Void> pushed = operations.applications() .push(PushApplicationRequest.builder() .name("hello").path("foo.jar") .memory(512).instances(2).build());pushed.doOnSuccess(x -> System.out.println("pushed!!")) .subscribe();

// cf logs helloFlux<LogMessage> logs = operations.applications() .logs(LogsRequest.builder() .name("hello").build());

Page 48: Cloud Foundy Java Client V 2.0 #cf_tokyo

‹#›© 2016 Pivotal Software, Inc. All rights reserved.

logs.filter(log -> "RTR".equals(log.getSourceName())).map(LogMessage::getMessage).filter(msg -> msg.contains(" 500 ")) // 500 error.userTimer(Timer.create()).buffer(Duration.ofSeconds(10)).map(List::size).filer(x -> x.size() > 5) // 5 errors in 10 sec.consume(x -> { System.out.println(x +" errors in 10 seconds!"); // some alerts});

Simple log monitor

Page 49: Cloud Foundy Java Client V 2.0 #cf_tokyo

‹#›© 2016 Pivotal Software, Inc. All rights reserved.

Prefer former simple one?

😟

Page 50: Cloud Foundy Java Client V 2.0 #cf_tokyo

‹#›© 2016 Pivotal Software, Inc. All rights reserved.

Going Non-Blocking is difficult

Blocking API Non-Blocking API

😎

😭difficult

easy

Page 51: Cloud Foundy Java Client V 2.0 #cf_tokyo

‹#›© 2016 Pivotal Software, Inc. All rights reserved.

to Blocking is Easy

Mono<ApplicationDetail> app = ...;ApplicationDetail detail = app.get();

Flux<ApplicationSummary> apps = ...;Iterable<ApplicationSummary> summaries = apps.toIterable();

Page 52: Cloud Foundy Java Client V 2.0 #cf_tokyo

‹#›© 2016 Pivotal Software, Inc. All rights reserved.

Enjoy Reactive Programming with CF Java Client V2

😘

Page 53: Cloud Foundy Java Client V 2.0 #cf_tokyo

‹#›© 2016 Pivotal Software, Inc. All rights reserved.

Further Reading•CF Java Client

https://github.com/cloudfoundry/cf-java-client

•CF Java Client 2.0 designhttps://docs.google.com/document/d/1Ui-67dBPYoADltErL80xXYEr_INPqdNJG9Va4gPBM-I/edit?pref=2&pli=1#heading=h.7gypq7vjwrk2

•A lite Rx API for the JVMhttps://speakerdeck.com/sdeleuze/a-lite-rx-api-for-the-jvm

•Reactor Core 2.5 becomes a unified Reactive Foundation on Java 8 https://spring.io/blog/2016/03/11/reactor-core-2-5-becomes-a-unified-reactive-foundation-on-java-8