package myfeed.ui; import java.util.Collections; import java.util.Date; import java.util.List; import java.util.Map; import lombok.Data; import lombok.NoArgsConstructor; import myfeed.core.AsyncRest; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.cloud.netflix.feign.FeignClient; import org.springframework.http.HttpEntity; import org.springframework.http.ResponseEntity; import org.springframework.web.bind.annotation.PathVariable; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RequestMethod; import org.springframework.web.bind.annotation.RestController; import rx.Observable; import rx.Single; import javax.servlet.http.HttpSession; /** * @author Spencer Gibb */ @RestController public class UiController { @Autowired private AsyncRest rest; @Autowired private FeedClient feedClient; @Autowired private FeatureService featureService; @RequestMapping("/ui/features") public Map<String, String> features() { return Collections.singletonMap("featureAaaFlag", featureService.getFeatureAaaFlag()); } @RequestMapping("/ui/feed/{username}") public Single<Feed> feed(@PathVariable("username") String username, HttpSession session) { Single<Feed> feed = getUser("http://myfeed-user/@{username}", username) .map(HttpEntity::getBody) .flatMap(user -> { // given the user, go get each following user and return the list of usernames Observable<User> u = Observable.just(user); Observable<List<FeedItem>> feedItems = feedClient.feedItems(user.getUsername()); Observable<List<String>> following = Observable.from(user.getFollowing()) .flatMap(userid -> getUser("http://myfeed-user/users/{userid}", userid) .map(HttpEntity::getBody) .map(User::getUsername) ).toList(); return Observable.zip(u, following, feedItems, Observable.just(session.getId()), Feed::new); }).toSingle(); return feed; } @FeignClient("myfeed-feed") public interface FeedClient { @RequestMapping(value = "/list/{username}", method = RequestMethod.GET) Observable<List<FeedItem>> feedItems(@PathVariable("username") String username); } private Observable<ResponseEntity<User>> getUser(String url, String username) { return Observable.from(rest.getForEntity(url, User.class, username)); } @Data private static class Feed { private final User profile; private final List<String> following; private final List<FeedItem> feed; private final String sessionId; } @Data @NoArgsConstructor private static class FeedItem { private String id; private String userid; private String username; private String text; private Date created; } }