package io.pivotal.web.service; import java.util.ArrayList; import java.util.Arrays; import java.util.Collection; import java.util.Iterator; import java.util.List; import com.netflix.hystrix.contrib.javanica.annotation.HystrixProperty; import io.pivotal.web.domain.CompanyInfo; import io.pivotal.web.domain.Order; import io.pivotal.web.domain.Portfolio; import io.pivotal.web.domain.Quote; import io.pivotal.web.exception.OrderNotSavedException; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Value; import org.springframework.cloud.client.loadbalancer.LoadBalanced; import org.springframework.cloud.context.config.annotation.RefreshScope; import org.springframework.core.ParameterizedTypeReference; import org.springframework.http.HttpStatus; import org.springframework.http.ResponseEntity; import org.springframework.stereotype.Service; import org.springframework.web.client.RestTemplate; import com.netflix.hystrix.contrib.javanica.annotation.HystrixCommand; @Service @RefreshScope public class MarketService { private static final Logger logger = LoggerFactory.getLogger(MarketService.class); @Autowired @LoadBalanced private RestTemplate restTemplate; @Value("${pivotal.quotesService.name}") private String quotesService; @Value("${pivotal.portfolioService.name}") private String portfolioService; @HystrixCommand(fallbackMethod = "getCompaniesFallback") public List<CompanyInfo> getCompanies(String name) { logger.debug("Fetching companies with name or symbol matching: " + name); CompanyInfo[] infos = restTemplate.getForObject("http://" + quotesService + "/company/{name}", CompanyInfo[].class, name); return Arrays.asList(infos); } @SuppressWarnings("unused") private List<CompanyInfo> getCompaniesFallback(String name) { return new ArrayList<>(); } /** * Retrieve multiple quotes. * * @param symbols comma separated list of symbols. * @return */ @HystrixCommand(fallbackMethod = "getQuotesFallback", commandProperties = {@HystrixProperty(name="execution.timeout.enabled", value="false")}) public List<Quote> getQuotes(String symbols) { logger.debug("retrieving multiple quotes: " + symbols); Quote[] quotesArr = restTemplate.getForObject("http://" + quotesService + "/quotes?q={symbols}", Quote[].class, symbols); List<Quote> quotes = Arrays.asList(quotesArr); logger.debug("Received quotes: {}",quotes); return quotes; } @SuppressWarnings("unused") private List<Quote> getQuotesFallback(String symbols) { List<Quote> result = new ArrayList<>(); String[] splitSymbols = symbols.split(","); for (String symbol : splitSymbols) { Quote quote = new Quote(); quote.setSymbol(symbol); quote.setStatus("FAILED"); result.add( quote ); } return result; } public List<Quote> getQuotes(String[] symbols) { logger.debug("Fetching multiple quotes array: {} ",Arrays.asList(symbols)); return getQuotes(Arrays.asList(symbols)); } public List<Quote> getQuotes(Collection<String> symbols) { logger.debug("Fetching multiple quotes array: {} ",symbols); StringBuilder builder = new StringBuilder(); for (Iterator<String> i = symbols.iterator(); i.hasNext();) { builder.append(i.next()); if (i.hasNext()) { builder.append(","); } } return getQuotes(builder.toString()); } public Order sendOrder(Order order ) throws OrderNotSavedException{ logger.debug("send order: " + order); //check result of http request to ensure its ok. ResponseEntity<Order> result = restTemplate.postForEntity("http://" + portfolioService + "/portfolio/{accountId}", order, Order.class, order.getAccountId()); if (result.getStatusCode() == HttpStatus.INTERNAL_SERVER_ERROR) { throw new OrderNotSavedException("Could not save the order"); } logger.debug("Order saved:: " + result.getBody()); return result.getBody(); } @HystrixCommand(fallbackMethod = "getPortfolioFallback") public Portfolio getPortfolio(String accountId) { Portfolio folio = restTemplate.getForObject("http://" + portfolioService + "/portfolio/{accountid}", Portfolio.class, accountId); logger.debug("Portfolio received: " + folio); return folio; } @SuppressWarnings("unused") private Portfolio getPortfolioFallback(String accountId) { logger.debug("Portfolio fallback"); Portfolio folio = new Portfolio(); folio.setAccountId(accountId); return folio; } }