/*
* Copyright (C) 2010-2012 Stichting Akvo (Akvo Foundation)
*
* This file is part of Akvo FLOW.
*
* Akvo FLOW is free software: you can redistribute it and modify it under the terms of
* the GNU Affero General Public License (AGPL) as published by the Free Software Foundation,
* either version 3 of the License or any later version.
*
* Akvo FLOW is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
* without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
* See the GNU Affero General Public License included below for more details.
*
* The full license text can also be seen at <http://www.gnu.org/licenses/agpl.html>.
*/
package org.waterforpeople.mapping.app.web;
import java.io.IOException;
import java.util.ArrayList;
import java.util.logging.Logger;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.waterforpeople.mapping.app.web.dto.DeleteTaskRequest;
import org.waterforpeople.mapping.dao.AccessPointDao;
import org.waterforpeople.mapping.domain.AccessPoint;
import org.waterforpeople.mapping.helper.AccessPointHelper;
import com.gallatinsystems.common.util.PropertyUtil;
import com.google.appengine.api.datastore.Cursor;
import com.google.appengine.api.datastore.DatastoreService;
import com.google.appengine.api.datastore.DatastoreServiceFactory;
import com.google.appengine.api.datastore.Entity;
import com.google.appengine.api.datastore.FetchOptions;
import com.google.appengine.api.datastore.Key;
import com.google.appengine.api.datastore.PreparedQuery;
import com.google.appengine.api.datastore.Query;
import com.google.appengine.api.datastore.QueryResultIterator;
import com.google.appengine.api.taskqueue.Queue;
import com.google.appengine.api.taskqueue.QueueFactory;
import com.google.appengine.api.taskqueue.TaskOptions;
public class ScoreProcessor extends HttpServlet {
public static final String ASYNC_TASK_TIMEOUT = "asyncTaskTimeout";
/**
*
*/
private static final long serialVersionUID = 5500271297082259592L;
public static final String OBJECT_TASK_URL = "/app_worker/scoreprocessor";
public static final String ACCESSPOINT_QUEUE_NAME = "accesspointscorequeue";
private static final Logger log = Logger.getLogger(ScoreProcessor.class
.getName());
public void doPost(HttpServletRequest req, HttpServletResponse resp) {
this.scorePoints(req);
}
public void doGet(HttpServletRequest req, HttpServletResponse resp)
throws IOException {
this.scorePoints(req);
}
static Integer executionCount = 0;
private void scorePoints(HttpServletRequest req) {
final Integer timeoutSeconds = Integer.parseInt(PropertyUtil
.getProperty(ASYNC_TASK_TIMEOUT));
executionCount++;
log.info("Execution Count: " + executionCount);
int scored_count = 0;
final Integer FETCH_NUM_RECORDS = 10;
boolean is_finished = false;
AccessPointHelper aph = new AccessPointHelper();
AccessPointDao apDao = new AccessPointDao();
final DatastoreService dss = DatastoreServiceFactory
.getDatastoreService();
final long start = System.currentTimeMillis();
PreparedQuery pquery;
Cursor endCursor = null;
while (System.currentTimeMillis() - start < timeoutSeconds) {
final Query query = new Query("AccessPoint");
query.setKeysOnly();
final ArrayList<Key> keys = new ArrayList<Key>();
String cursor = req.getParameter("cursor");
pquery = dss.prepare(query);
cursor = cursor.trim();
FetchOptions fetchOptions = null;
if (cursor != null && !cursor.equalsIgnoreCase("null") && !cursor.equals("")) {
Cursor c = Cursor.fromWebSafeString(cursor);
fetchOptions = FetchOptions.Builder.withLimit(FETCH_NUM_RECORDS).startCursor(c);
} else {
fetchOptions = FetchOptions.Builder.withLimit(FETCH_NUM_RECORDS);
}
QueryResultIterator<Entity> list = pquery.asQueryResultIterator(fetchOptions);
while (list.hasNext()) {
keys.add(list.next().getKey());
}
endCursor = list.getCursor();
keys.trimToSize();
if (keys.size() == 0) {
is_finished = true;
break;
}
while (System.currentTimeMillis() - start < timeoutSeconds) {
try {
final Key apKey = keys.get(scored_count);
final AccessPoint ap = apDao.getByKey(apKey);
aph.scoreAccessPointNew(ap);
log.info("Scored : " + ap.getKeyString());
scored_count++;
if (keys.size() - 1 == scored_count++) {
break;
}
} catch (Throwable ignore) {
continue;
}
}
}
if (is_finished) {
System.err.println("*** score job for AccessPoint is completed.");
} else {
final Integer taskcount;
String taskCount = req.getParameter("taskCount");
final String tcs = taskCount;
if (tcs == null) {
taskcount = 0;
} else {
taskcount = Integer.parseInt(tcs) + 1;
}
Queue deleteQueue = QueueFactory.getQueue(ACCESSPOINT_QUEUE_NAME);
deleteQueue.add(TaskOptions.Builder.withUrl(OBJECT_TASK_URL).param(
DeleteTaskRequest.TASK_COUNT_PARAM, taskcount.toString())
.param("cursor", endCursor.toWebSafeString()));
System.err.println("*** finished scoring " + scored_count + " APs");
System.err.println("*** score task # " + taskcount + " for "
+ "AccessPoint" + " is queued.");
}
}
}