/*
* Copyright (C) 2010-2015 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.List;
import java.util.logging.Logger;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.apache.commons.lang.StringUtils;
import org.waterforpeople.mapping.app.web.dto.TaskRequest;
import com.gallatinsystems.device.dao.DeviceDAO;
import com.gallatinsystems.device.dao.DeviceFileJobQueueDAO;
import com.gallatinsystems.device.domain.Device;
import com.gallatinsystems.device.domain.DeviceFileJobQueue;
import com.gallatinsystems.messaging.dao.MessageDao;
import com.gallatinsystems.messaging.domain.Message;
import com.gallatinsystems.survey.dao.CascadeResourceDao;
import com.gallatinsystems.survey.dao.SurveyDAO;
import com.gallatinsystems.survey.domain.CascadeResource;
import com.gallatinsystems.survey.domain.CascadeResource.Status;
import com.google.appengine.api.taskqueue.Queue;
import com.google.appengine.api.taskqueue.QueueFactory;
import com.google.appengine.api.taskqueue.TaskOptions;
/**
* Servlet used by app to trigger processing of new survey data TODO: move parameter name strings
* into constants
*/
public class ProcessorServlet extends HttpServlet {
private static final long serialVersionUID = -7062679258542909086L;
private static final Logger log = Logger.getLogger(ProcessorServlet.class
.getName());
@Override
public void doGet(HttpServletRequest req, HttpServletResponse resp)
throws IOException {
if (req.getParameter("action") == null) {
log.info("No action specified for processor");
return;
}
String action = StringUtils.trim(req.getParameter("action"));
String fileName = StringUtils.trim(req.getParameter("fileName"));
String phoneNumber = StringUtils.trim(req.getParameter("phoneNumber"));
String androidId = StringUtils.trim(req.getParameter("androidId"));
String imei = StringUtils.trim(req.getParameter("imei"));
String checksum = StringUtils.trim(req.getParameter("checksum"));
log.info(" ProcessorServlet->action->" + action);
if (action.equals("submit")) {
if (fileName == null) {
log.info("Request for processing without filename: phoneNumber=(" + phoneNumber
+ "); IMEI=(" + imei + ")");
resp.setStatus(HttpServletResponse.SC_BAD_REQUEST);
return;
}
// If we get a form ID, ensure the form is still present in the datastore
Long formID = parseFormID(req);
if (formID != null) {
SurveyDAO surveyDAO = new SurveyDAO();
if (surveyDAO.getById(formID) == null) {
log.warning("Form " + formID + " doesn't exist in the datastore");
resp.setStatus(HttpServletResponse.SC_NOT_FOUND);
return;
}
}
log.info(" ProcessorServlet->filename->" + fileName);
log.info("about to submit task for fileName: " + fileName);
// Submit the fileName for processing
Queue queue = QueueFactory.getDefaultQueue();
TaskOptions options = TaskOptions.Builder.withUrl("/app_worker/task")
.param(TaskRequest.ACTION_PARAM, TaskRequest.PROCESS_FILE_ACTION)
.param(TaskRequest.FILE_NAME_PARAM, fileName);
if (androidId != null) {
options.param(TaskRequest.ANDROID_ID, androidId);
}
if (phoneNumber != null) {
options.param(TaskRequest.PHONE_NUM_PARAM, phoneNumber);
}
if (imei != null) {
options.param(TaskRequest.IMEI_PARAM, imei);
}
if (checksum != null) {
options.param(TaskRequest.CHECKSUM_PARAM, checksum);
}
queue.add(options);
log.info("submiting task for fileName: " + fileName);
} else if (action.equals("image")) {
Device d = null;
DeviceDAO dao = new DeviceDAO();
d = dao.getDevice(androidId, imei, phoneNumber);
if (d == null) {
log.severe(String.format(
"No device found with imei %s or phoneNumber %s",
imei, phoneNumber));
return;
}
DeviceFileJobQueueDAO dfDao = new DeviceFileJobQueueDAO();
List<DeviceFileJobQueue> missing = dfDao.listByDeviceAndFile(d
.getKey().getId(), fileName);
log.info(String.format(
"Deleting %s entities matching the fileName %s",
missing.size(), fileName));
dfDao.delete(missing);
} else if (action.equals("cascade")) {
Long crId = null;
final String status = req.getParameter("status");
final CascadeResourceDao crDao = new CascadeResourceDao();
try {
crId = Long.valueOf(req.getParameter("cascadeResourceId"));
} catch (NumberFormatException e) {
}
if (crId == null || status == null) {
return;
}
CascadeResource cr = crDao.getByKey(crId);
if (cr == null) {
return;
}
final MessageDao mDao = new MessageDao();
final Message m = new Message();
m.setActionAbout("cascadePublish");
if ("published".equals(status)) {
cr.setStatus(Status.PUBLISHED);
cr.setVersion(cr.getVersion() + 1);
m.setShortMessage("Cascade resource " + cr.getName() + " successfully published");
} else {
cr.setStatus(Status.NOT_PUBLISHED);
m.setShortMessage("Failed to publish cascade resource " + cr.getName());
}
crDao.save(cr);
mDao.save(m);
}
}
private Long parseFormID(HttpServletRequest req) {
String formID = StringUtils.trim(req.getParameter("formID"));
if (StringUtils.isNotBlank(formID)) {
try {
return Long.valueOf(formID);
} catch (NumberFormatException e) {
log.warning("Form ID is not a valid number: " + formID);
}
}
return null;
}
}