cloud foundy java client v 2.0 #cf_tokyo

Post on 22-Jan-2017

1.362 Views

Category:

Technology

1 Downloads

Preview:

Click to see full reader

TRANSCRIPT

‹#›© 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

‹#›© 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)

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

Agenda•How CF Java Client V1 was 😟

•How CF Java Client V2 looks 😎

‹#›© 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");

‹#›© 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) {} });

‹#›© 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

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

Too many overloading…😫

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

130+ methods…😫

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

I don’t need MVC…😫

‹#›© 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 😫

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

Cloud Foundry Java Client V2

https://lists.cloudfoundry.org/archives/list/cf-dev@lists.cloudfoundry.org/thread/W4455NML53LLSUSP25J2OXIYP2FNWUI4/

‹#›© 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

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

Class DiagramCloudFoundryOperations

DefaultCloudFoundryOperations

CloudFoundryClient

SpringCloudFoundryClient

Uses

LoggingClient

SpringLoggingClient

Uses

Uses

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

In Future?

CloudFoundryClient

SpringCloudFoundryClient

RetrofitCloudFoundryClient

AndroidCloudFoundryClient

for non-Spring user

for Android user

‹#›© 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

‹#›© 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());

‹#›© 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?

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

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

functional-style code

‹#›© 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

‹#›© 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

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

V2 supports Reactive Streams!!•Non-Blocking APIs

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

‹#›© 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/

‹#›© 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> {}

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

Subscription SubscriberPublisher Application

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

Subscription SubscriberPublisher Application

subscribe(Subscriber)

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

Subscription SubscriberPublisher Application

onSubscribe(Subscription)

subscribe(Subscriber)

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

Subscription SubscriberPublisher Application

onSubscribe(Subscription)

request(1)

subscribe(Subscriber)

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

Subscription SubscriberPublisher Application

onSubscribe(Subscription)

request(1)

onNext(●)

subscribe(Subscriber)

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

Subscription SubscriberPublisher Application

onSubscribe(Subscription)

request(1)

onNext(●)

request(2)

subscribe(Subscriber)

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

Subscription SubscriberPublisher Application

onSubscribe(Subscription)

request(1)

onNext(●)

request(2)

onNext(●)

subscribe(Subscriber)

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

Subscription SubscriberPublisher Application

onSubscribe(Subscription)

request(1)

onNext(●)

request(2)

onNext(●)

onNext(●)

subscribe(Subscriber)

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

Subscription SubscriberPublisher Application

onSubscribe(Subscription)

request(1)

onNext(●)

request(2)

onNext(●)

onNext(●)

request(4)

subscribe(Subscriber)

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

Subscription SubscriberPublisher Application

onSubscribe(Subscription)

request(1)

onNext(●)

request(2)

onNext(●)

onNext(●)

request(4)

onNext(●)

subscribe(Subscriber)

‹#›© 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)

‹#›© 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)

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

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

‹#›© 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() {} });

‹#›© 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

‹#›© 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/

‹#›© 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/

‹#›© 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

‹#›© 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));

‹#›© 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

‹#›© 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();

‹#›© 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>

‹#›© 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));

‹#›© 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());

‹#›© 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

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

Prefer former simple one?

😟

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

Going Non-Blocking is difficult

Blocking API Non-Blocking API

😎

😭difficult

easy

‹#›© 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();

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

Enjoy Reactive Programming with CF Java Client V2

😘

‹#›© 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

top related