org.springframework.amqp.rabbit.stocks.web.QuoteController.java Source code

Java tutorial

Introduction

Here is the source code for org.springframework.amqp.rabbit.stocks.web.QuoteController.java

Source

/*
 * Copyright 2002-2010 the original author or authors.
 * 
 * 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 org.springframework.amqp.rabbit.stocks.web;

import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.Comparator;
import java.util.Iterator;
import java.util.List;
import java.util.Queue;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ConcurrentMap;
import java.util.concurrent.PriorityBlockingQueue;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.springframework.amqp.rabbit.stocks.domain.Quote;
import org.springframework.amqp.rabbit.stocks.domain.TradeRequest;
import org.springframework.amqp.rabbit.stocks.domain.TradeResponse;
import org.springframework.amqp.rabbit.stocks.gateway.StockServiceGateway;
import org.springframework.stereotype.Controller;
import org.springframework.util.StringUtils;
import org.springframework.web.bind.annotation.ModelAttribute;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;

/**
 * @author Dave Syer
 * 
 */
@Controller
public class QuoteController {

    private static Log logger = LogFactory.getLog(QuoteController.class);

    private StockServiceGateway stockServiceGateway;

    private ConcurrentMap<String, TradeResponse> responses = new ConcurrentHashMap<String, TradeResponse>();

    private Queue<Quote> quotes = new PriorityBlockingQueue<Quote>(100, new QuoteComparator());

    private long timeout = 30000; // 30 seconds of data

    public void setStockServiceGateway(StockServiceGateway stockServiceGateway) {
        this.stockServiceGateway = stockServiceGateway;
    }

    public void handleTrade(TradeResponse response) {
        logger.info("Client received: " + response);
        String key = response.getRequestId();
        responses.putIfAbsent(key, response);
        Collection<TradeResponse> queue = new ArrayList<TradeResponse>(responses.values());
        long timestamp = System.currentTimeMillis() - timeout;
        for (Iterator<TradeResponse> iterator = queue.iterator(); iterator.hasNext();) {
            TradeResponse tradeResponse = iterator.next();
            if (tradeResponse.getTimestamp() < timestamp) {
                responses.remove(tradeResponse.getRequestId());
            }
        }
    }

    public void handleQuote(Quote message) {
        logger.info("Client received: " + message);
        long timestamp = System.currentTimeMillis() - timeout;
        for (Iterator<Quote> iterator = quotes.iterator(); iterator.hasNext();) {
            Quote quote = iterator.next();
            if (quote.getTimestamp() < timestamp) {
                iterator.remove();
            }
        }
        quotes.add(message);
    }

    @RequestMapping("/quotes")
    @ResponseBody
    public List<Quote> quotes(@RequestParam(required = false) Long timestamp) {
        if (timestamp == null) {
            timestamp = 0L;
        }
        ArrayList<Quote> list = new ArrayList<Quote>();
        for (Quote quote : quotes) {
            if (quote.getTimestamp() > timestamp) {
                list.add(quote);
            }
        }
        Collections.reverse(list);
        return list;
    }

    @RequestMapping(value = "/trade", method = RequestMethod.POST)
    @ResponseBody
    public TradeRequest trade(@ModelAttribute TradeRequest tradeRequest) {
        String ticker = tradeRequest.getTicker();
        Long quantity = tradeRequest.getQuantity();
        if (quantity == null || quantity <= 0 || !StringUtils.hasText(ticker)) {
            // error
            return tradeRequest;
        } else {
            // Fake rest of request while UI is basic
            tradeRequest.setAccountName("ACCT-123");
            tradeRequest.setBuyRequest(true);
            tradeRequest.setOrderType("MARKET");
            tradeRequest.setRequestId("REQ-1");
            tradeRequest.setUserName("Joe Trader");
            tradeRequest.setUserName("Joe");
            stockServiceGateway.send(tradeRequest);
        }
        return tradeRequest;
    }

    @RequestMapping(value = "/trade", method = RequestMethod.GET)
    @ResponseBody
    public TradeResponse response(@RequestParam String requestId) {
        TradeResponse result = responses.get(requestId);
        return result;
    }

    private static class QuoteComparator implements Comparator<Quote> {

        public int compare(Quote o1, Quote o2) {
            return new Long(o1.getTimestamp() - o2.getTimestamp()).intValue();
        }

    }

}