是使用tomcat异步和非阻塞的aws geo库for dynamodb吗?

时间:2014-03-28 21:31:07

标签: java tomcat servlets amazon-web-services amazon-dynamodb

我需要一台可以执行geohashing的服务器。我遇到了针对dynamodb的AWS geo库,看起来它可以做我需要做的事情http://mobile.awsblog.com/post/TxWTJOSLE7O3J2/Geo-Library-for-Amazon-DynamoDB-Part-1-Table-Structure。这个库只适用于Java,因为我不是JAVA程序员,我的问题是如果我使用tomcat在AWS上运行它,这会很好地处理并发性(代码是异步还是非阻塞)?我已经查看了一些Java api,并注意到代码是ASYN,通常会有一个Future类,所以我认为这不是,但因为我不是java程序员,我错过了什么?如果不是我怎么能让它异步?我基本上需要能够允许扩展tomcat服务器以及对数据库的调用不阻止或必须等待响应。我将使用它只有几天,但在那几天会有数百万的请求被发送以获取数据,所以我需要它来处理负载。

package com.amazonaws.geo.server;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.PrintWriter;
import java.io.StringWriter;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.UUID;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.codehaus.jackson.JsonFactory;
import org.codehaus.jackson.JsonNode;
import org.codehaus.jackson.JsonParseException;
import org.codehaus.jackson.JsonParser;
import org.codehaus.jackson.map.ObjectMapper;

import com.amazonaws.auth.AWSCredentials;
import com.amazonaws.auth.BasicAWSCredentials;
import com.amazonaws.geo.GeoDataManager;
import com.amazonaws.geo.GeoDataManagerConfiguration;
import com.amazonaws.geo.model.DeletePointRequest;
import com.amazonaws.geo.model.DeletePointResult;
import com.amazonaws.geo.model.GeoPoint;
import com.amazonaws.geo.model.GeoQueryResult;
import com.amazonaws.geo.model.GetPointRequest;
import com.amazonaws.geo.model.GetPointResult;
import com.amazonaws.geo.model.PutPointRequest;
import com.amazonaws.geo.model.PutPointResult;
import com.amazonaws.geo.model.QueryRadiusRequest;
import com.amazonaws.geo.model.QueryRadiusResult;
import com.amazonaws.geo.model.QueryRectangleRequest;
import com.amazonaws.geo.model.QueryRectangleResult;
import com.amazonaws.geo.model.UpdatePointRequest;
import com.amazonaws.geo.model.UpdatePointResult;
import com.amazonaws.regions.Region;
import com.amazonaws.regions.Regions;
import com.amazonaws.services.dynamodbv2.AmazonDynamoDBClient;
import com.amazonaws.services.dynamodbv2.model.AttributeAction;
import com.amazonaws.services.dynamodbv2.model.AttributeValue;
import com.amazonaws.services.dynamodbv2.model.AttributeValueUpdate;
import com.amazonaws.util.json.JSONException;
import com.amazonaws.util.json.JSONObject;

/**
 * Servlet implementation class GeoDynamoDBServlet
 */
public class GeoDynamoDBServlet extends HttpServlet {
    private static final long serialVersionUID = 1L;

    private GeoDataManagerConfiguration config;
    private GeoDataManager geoDataManager;

    private ObjectMapper mapper;
    private JsonFactory factory;

    public void init() throws ServletException {
        setupGeoDataManager();

        mapper = new ObjectMapper();
        factory = mapper.getJsonFactory();
    }

    private void setupGeoDataManager() {
        String accessKey = System.getProperty("AWS_ACCESS_KEY_ID");
        String secretKey = System.getProperty("AWS_SECRET_KEY");
        String tableName = System.getProperty("PARAM1");
        String regionName = System.getProperty("PARAM2");

        AWSCredentials credentials = new BasicAWSCredentials(accessKey, secretKey);
        AmazonDynamoDBClient ddb = new AmazonDynamoDBClient(credentials);
        Region region = Region.getRegion(Regions.fromName(regionName));
        ddb.setRegion(region);

        config = new GeoDataManagerConfiguration(ddb, tableName);
        geoDataManager = new GeoDataManager(config);
    }

    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException,
            IOException {
        try {
            StringBuffer buffer = new StringBuffer();
            String line = null;
            BufferedReader reader = request.getReader();

            while ((line = reader.readLine()) != null) {
                buffer.append(line);
            }

            JSONObject jsonObject = new JSONObject(buffer.toString());
            PrintWriter out = response.getWriter();

            String action = jsonObject.getString("action");
            log("action: " + action);
            JSONObject requestObject = jsonObject.getJSONObject("request");
            log("requestObject: " + requestObject);

            if (action.equalsIgnoreCase("put-point")) {
                putPoint(requestObject, out);
            } else if (action.equalsIgnoreCase("get-point")) {
                getPoint(requestObject, out);
            } else if (action.equalsIgnoreCase("update-point")) {
                updatePoint(requestObject, out);
            } else if (action.equalsIgnoreCase("query-rectangle")) {
                queryRectangle(requestObject, out);
            } else if (action.equalsIgnoreCase("query-radius")) {
                queryRadius(requestObject, out);
            } else if (action.equalsIgnoreCase("delete-point")) {
                deletePoint(requestObject, out);
            }
        } catch (Exception e) {
            StringWriter sw = new StringWriter();
            PrintWriter pw = new PrintWriter(sw);
            e.printStackTrace(pw);
            log(sw.toString());
        }
    }

    private void putPoint(JSONObject requestObject, PrintWriter out) throws IOException, JSONException {
        GeoPoint geoPoint = new GeoPoint(requestObject.getDouble("lat"), requestObject.getDouble("lng"));
        AttributeValue rangeKeyAttributeValue = new AttributeValue().withS(UUID.randomUUID().toString());
        AttributeValue schoolNameKeyAttributeValue = new AttributeValue().withS(requestObject.getString("schoolName"));

        PutPointRequest putPointRequest = new PutPointRequest(geoPoint, rangeKeyAttributeValue);
        putPointRequest.getPutItemRequest().addItemEntry("schoolName", schoolNameKeyAttributeValue);

        PutPointResult putPointResult = geoDataManager.putPoint(putPointRequest);

        printPutPointResult(putPointResult, out);
    }

    private void printPutPointResult(PutPointResult putPointResult, PrintWriter out) throws JsonParseException,
            IOException {

        Map<String, String> jsonMap = new HashMap<String, String>();
        jsonMap.put("action", "put-point");

        out.println(mapper.writeValueAsString(jsonMap));
        out.flush();
    }

    private void getPoint(JSONObject requestObject, PrintWriter out) throws IOException, JSONException {
        GeoPoint geoPoint = new GeoPoint(requestObject.getDouble("lat"), requestObject.getDouble("lng"));
        AttributeValue rangeKeyAttributeValue = new AttributeValue().withS(requestObject.getString("rangeKey"));

        GetPointRequest getPointRequest = new GetPointRequest(geoPoint, rangeKeyAttributeValue);
        GetPointResult getPointResult = geoDataManager.getPoint(getPointRequest);

        printGetPointRequest(getPointResult, out);
    }

    private void printGetPointRequest(GetPointResult getPointResult, PrintWriter out) throws JsonParseException,
            IOException {
        Map<String, AttributeValue> item = getPointResult.getGetItemResult().getItem();
        String geoJsonString = item.get(config.getGeoJsonAttributeName()).getS();
        JsonParser jsonParser = factory.createJsonParser(geoJsonString);
        JsonNode jsonNode = mapper.readTree(jsonParser);

        double latitude = jsonNode.get("coordinates").get(0).getDoubleValue();
        double longitude = jsonNode.get("coordinates").get(1).getDoubleValue();
        String hashKey = item.get(config.getHashKeyAttributeName()).getN();
        String rangeKey = item.get(config.getRangeKeyAttributeName()).getS();
        String geohash = item.get(config.getGeohashAttributeName()).getN();
        String schoolName = item.get("schoolName").getS();
        String memo = "";
        if (item.containsKey("memo")) {
            memo = item.get("memo").getS();
        }

        Map<String, String> resultMap = new HashMap<String, String>();
        resultMap.put("latitude", Double.toString(latitude));
        resultMap.put("longitude", Double.toString(longitude));
        resultMap.put("hashKey", hashKey);
        resultMap.put("rangeKey", rangeKey);
        resultMap.put("geohash", geohash);
        resultMap.put("schoolName", schoolName);
        resultMap.put("memo", memo);

        Map<String, Object> jsonMap = new HashMap<String, Object>();
        jsonMap.put("action", "get-point");
        jsonMap.put("result", resultMap);

        out.println(mapper.writeValueAsString(jsonMap));
        out.flush();
    }

    private void updatePoint(JSONObject requestObject, PrintWriter out) throws IOException, JSONException {
        GeoPoint geoPoint = new GeoPoint(requestObject.getDouble("lat"), requestObject.getDouble("lng"));
        AttributeValue rangeKeyAttributeValue = new AttributeValue().withS(requestObject.getString("rangeKey"));

        String schoolName = requestObject.getString("schoolName");
        AttributeValueUpdate schoolNameValueUpdate = null;

        String memo = requestObject.getString("memo");
        AttributeValueUpdate memoValueUpdate = null;

        if (schoolName == null || schoolName.equalsIgnoreCase("")) {
            schoolNameValueUpdate = new AttributeValueUpdate().withAction(AttributeAction.DELETE);
        } else {
            AttributeValue schoolNameAttributeValue = new AttributeValue().withS(schoolName);
            schoolNameValueUpdate = new AttributeValueUpdate().withAction(AttributeAction.PUT).withValue(
                    schoolNameAttributeValue);
        }

        if (memo == null || memo.equalsIgnoreCase("")) {
            memoValueUpdate = new AttributeValueUpdate().withAction(AttributeAction.DELETE);
        } else {
            AttributeValue memoAttributeValue = new AttributeValue().withS(memo);
            memoValueUpdate = new AttributeValueUpdate().withAction(AttributeAction.PUT).withValue(memoAttributeValue);
        }

        UpdatePointRequest updatePointRequest = new UpdatePointRequest(geoPoint, rangeKeyAttributeValue);
        updatePointRequest.getUpdateItemRequest().addAttributeUpdatesEntry("schoolName", schoolNameValueUpdate);
        updatePointRequest.getUpdateItemRequest().addAttributeUpdatesEntry("memo", memoValueUpdate);

        UpdatePointResult updatePointResult = geoDataManager.updatePoint(updatePointRequest);

        printUpdatePointResult(updatePointResult, out);
    }

    private void printUpdatePointResult(UpdatePointResult updatePointResult, PrintWriter out)
            throws JsonParseException, IOException {

        Map<String, String> jsonMap = new HashMap<String, String>();
        jsonMap.put("action", "update-point");

        out.println(mapper.writeValueAsString(jsonMap));
        out.flush();
    }

    private void queryRectangle(JSONObject requestObject, PrintWriter out) throws IOException, JSONException {
        GeoPoint minPoint = new GeoPoint(requestObject.getDouble("minLat"), requestObject.getDouble("minLng"));
        GeoPoint maxPoint = new GeoPoint(requestObject.getDouble("maxLat"), requestObject.getDouble("maxLng"));

        List<String> attributesToGet = new ArrayList<String>();
        attributesToGet.add(config.getRangeKeyAttributeName());
        attributesToGet.add(config.getGeoJsonAttributeName());
        attributesToGet.add("schoolName");

        QueryRectangleRequest queryRectangleRequest = new QueryRectangleRequest(minPoint, maxPoint);
        queryRectangleRequest.getQueryRequest().setAttributesToGet(attributesToGet);
        QueryRectangleResult queryRectangleResult = geoDataManager.queryRectangle(queryRectangleRequest);

        printGeoQueryResult(queryRectangleResult, out);
    }

    private void queryRadius(JSONObject requestObject, PrintWriter out) throws IOException, JSONException {
        GeoPoint centerPoint = new GeoPoint(requestObject.getDouble("lat"), requestObject.getDouble("lng"));
        double radiusInMeter = requestObject.getDouble("radiusInMeter");

        List<String> attributesToGet = new ArrayList<String>();
        attributesToGet.add(config.getRangeKeyAttributeName());
        attributesToGet.add(config.getGeoJsonAttributeName());
        attributesToGet.add("schoolName");

        QueryRadiusRequest queryRadiusRequest = new QueryRadiusRequest(centerPoint, radiusInMeter);
        queryRadiusRequest.getQueryRequest().setAttributesToGet(attributesToGet);
        QueryRadiusResult queryRadiusResult = geoDataManager.queryRadius(queryRadiusRequest);

        printGeoQueryResult(queryRadiusResult, out);
    }

    private void printGeoQueryResult(GeoQueryResult geoQueryResult, PrintWriter out) throws JsonParseException,
            IOException {
        Map<String, Object> jsonMap = new HashMap<String, Object>();
        List<Map<String, String>> resultArray = new ArrayList<Map<String, String>>();

        for (Map<String, AttributeValue> item : geoQueryResult.getItem()) {
            Map<String, String> itemMap = new HashMap<String, String>();

            String geoJsonString = item.get(config.getGeoJsonAttributeName()).getS();
            JsonParser jsonParser = factory.createJsonParser(geoJsonString);
            JsonNode jsonNode = mapper.readTree(jsonParser);

            double latitude = jsonNode.get("coordinates").get(0).getDoubleValue();
            double longitude = jsonNode.get("coordinates").get(1).getDoubleValue();
            String rangeKey = item.get(config.getRangeKeyAttributeName()).getS();
            String schoolName = "";
            if (item.containsKey("schoolName")) {
                schoolName = item.get("schoolName").getS();
            }

            itemMap.put("latitude", Double.toString(latitude));
            itemMap.put("longitude", Double.toString(longitude));
            itemMap.put("rangeKey", rangeKey);
            itemMap.put("schoolName", schoolName);

            resultArray.add(itemMap);
        }

        jsonMap.put("action", "query");
        jsonMap.put("result", resultArray);

        out.println(mapper.writeValueAsString(jsonMap));
        out.flush();
    }

    private void deletePoint(JSONObject requestObject, PrintWriter out) throws IOException, JSONException {
        GeoPoint geoPoint = new GeoPoint(requestObject.getDouble("lat"), requestObject.getDouble("lng"));
        AttributeValue rangeKeyAttributeValue = new AttributeValue().withS(requestObject.getString("rangeKey"));

        DeletePointRequest deletePointRequest = new DeletePointRequest(geoPoint, rangeKeyAttributeValue);
        DeletePointResult deletePointResult = geoDataManager.deletePoint(deletePointRequest);

        printDeletePointResult(deletePointResult, out);
    }

    private void printDeletePointResult(DeletePointResult deletePointResult, PrintWriter out)
            throws JsonParseException, IOException {

        Map<String, String> jsonMap = new HashMap<String, String>();
        jsonMap.put("action", "delete-point");

        out.println(mapper.writeValueAsString(jsonMap));
        out.flush();
    }

    public void destroy() {
        config.getExecutorService().shutdownNow();
    }
}

0 个答案:

没有答案