Java tutorial
/* * Copyright 2014 Netflix, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package com.netflix.ribbon.examples.rx; import com.netflix.hystrix.util.HystrixTimer; import com.netflix.ribbon.examples.rx.common.Movie; import io.netty.buffer.ByteBuf; import rx.Notification; import rx.Observable; import rx.functions.Func1; import rx.functions.Func2; import java.nio.charset.Charset; import java.util.ArrayList; import java.util.Collections; import java.util.List; import java.util.regex.Pattern; import static java.lang.String.*; /** * Base class for the transport/template and proxy examples. It orchestrates application flow, and * handles result(s) from the server. The request execution is implemented in the derived classes, in a way * specific for each API abstration. This separation of concerns makes it is easy to compare complexity of different APIs. * * @author Tomasz Bak */ public abstract class AbstractRxMovieClient { protected static final String TEST_USER = "user1"; protected static final Pattern NEW_LINE_SPLIT_RE = Pattern.compile("\n"); protected abstract Observable<ByteBuf>[] triggerMoviesRegistration(); protected abstract Observable<ByteBuf>[] triggerRecommendationsUpdate(); protected abstract Observable<ByteBuf>[] triggerRecommendationsSearch(); protected Observable<ByteBuf> registerMovies() { return Observable.concat(Observable.from(triggerMoviesRegistration())); } protected Observable<ByteBuf> updateRecommendations() { return Observable.concat(Observable.from(triggerRecommendationsUpdate())); } protected Observable<Void> searchCatalog() { List<String> searches = new ArrayList<String>(2); Collections.addAll(searches, "findById", "findRawMovieById", "findMovie(name, category)"); return Observable.concat(Observable.from(triggerRecommendationsSearch())) .flatMap(new Func1<ByteBuf, Observable<List<Movie>>>() { @Override public Observable<List<Movie>> call(ByteBuf byteBuf) { List<Movie> movies = new ArrayList<Movie>(); String lines = byteBuf.toString(Charset.defaultCharset()); for (String line : NEW_LINE_SPLIT_RE.split(lines)) { movies.add(Movie.from(line)); } return Observable.just(movies); } }).zipWith(searches, new Func2<List<Movie>, String, Void>() { @Override public Void call(List<Movie> movies, String query) { System.out.println(format(" %s=%s", query, movies)); return null; } }); } public boolean runExample() { boolean allGood = true; try { System.out.println("Registering movies..."); Notification<Void> result = executeServerCalls(); allGood = !result.isOnError(); if (allGood) { System.out.println("Application finished"); } else { System.err.println("ERROR: execution failure"); result.getThrowable().printStackTrace(); } } catch (Exception e) { e.printStackTrace(); allGood = false; } finally { shutdown(); } return allGood; } Notification<Void> executeServerCalls() { Observable<Void> resultObservable = registerMovies().materialize() .flatMap(new Func1<Notification<ByteBuf>, Observable<Void>>() { @Override public Observable<Void> call(Notification<ByteBuf> notif) { if (!verifyStatus(notif)) { return Observable.error(notif.getThrowable()); } System.out.print("Updating user recommendations..."); return updateRecommendations().materialize() .flatMap(new Func1<Notification<ByteBuf>, Observable<Void>>() { @Override public Observable<Void> call(Notification<ByteBuf> notif) { if (!verifyStatus(notif)) { return Observable.error(notif.getThrowable()); } System.out.println("Searching through the movie catalog..."); return searchCatalog(); } }); } }); return resultObservable.materialize().toBlocking().last(); } protected void shutdown() { HystrixTimer.reset(); } private static boolean verifyStatus(Notification<ByteBuf> notif) { if (notif.isOnError()) { System.out.println("ERROR"); return false; } System.out.println("DONE"); return true; } }