cloud foundy java client v 2.0 #cf_tokyo
Post on 22-Jan-2017
1.362 Views
Preview:
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