com.threewks.thundr.gae.job.JobQueueImpl Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of thundr-gae Show documentation
Show all versions of thundr-gae Show documentation
A thundr module enabling thundr for use on GAE (Google App Engine)
The newest version!
/*
* This file is a component of thundr, a software library from 3wks.
* Read more: http://3wks.github.io/thundr/
* Copyright (C) 2015 3wks,
*
* 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 com.threewks.thundr.gae.job;
import static com.googlecode.objectify.ObjectifyService.ofy;
import java.util.UUID;
import org.apache.commons.lang3.StringUtils;
import com.google.appengine.api.datastore.Transaction;
import com.google.appengine.api.taskqueue.Queue;
import com.google.appengine.api.taskqueue.QueueFactory;
import com.google.appengine.api.taskqueue.TaskOptions;
import com.google.appengine.api.taskqueue.TaskOptions.Method;
import com.google.gson.Gson;
import com.google.gson.GsonBuilder;
import com.threewks.thundr.Experimental;
import com.threewks.thundr.exception.BaseException;
import com.threewks.thundr.http.ContentType;
import com.threewks.thundr.http.Header;
import com.threewks.thundr.route.HttpMethod;
import com.threewks.thundr.route.ReverseRouteException;
import com.threewks.thundr.route.Route;
import com.threewks.thundr.route.Router;
@Experimental
public class JobQueueImpl implements JobQueue {
protected Router router;
protected Gson gson;
public JobQueueImpl(Router router, GsonBuilder gsonBuilder) {
super();
this.router = router;
this.gson = gsonBuilder.create();
}
@Override
public UUID queue(Job job) {
try {
JobStatus jobStatus = new JobStatus();
UUID id = jobStatus.getId();
TaskOptions taskOptions = createTaskOptions(job, id);
Queue queue = getQueue(job);
Transaction transaction = ofy().getTransaction();
queue.add(transaction, taskOptions);
ofy().save().entity(jobStatus);
return id;
} catch (Exception e) {
throw new JobException(e, "Failed to queue job: %s", e.getMessage());
}
}
protected TaskOptions createTaskOptions(Job job, UUID id) {
String url = determineUrl(job);
Method method = determineMethod(job);
byte[] payload = createPayload(job);
// @formatter:off
TaskOptions taskOptions = TaskOptions.Builder
.withMethod(method)
.url(url)
.header(Header.ContentType, ContentType.ApplicationJson.value())
.header(Header.ContentEncoding, "UTF-8")
.header(JobIdHeader, id.toString());
if(payload != null){
taskOptions = taskOptions.payload(payload);
}
// @formatter:on
return taskOptions;
}
@Override
public JobStatus getJobStatus(UUID jobStatus) {
return ofy().load().type(JobStatus.class).id(jobStatus.toString()).now();
}
protected byte[] createPayload(Job task) {
if (!task.hasPayload()) {
return null;
}
try {
Object data = task.getPayload();
return gson.toJson(data).getBytes("UTF-8");
} catch (Exception e) {
throw new BaseException(e, "Unable to convert payload to bytes: %s", e.getMessage());
}
}
protected String determineUrl(Job task) {
String destination = task.getDestination();
if (destination.startsWith("/")) {
return destination;
} else {
Route namedRoute = router.getNamedRoute(destination);
if (namedRoute == null) {
throw new ReverseRouteException("No reverse route named '%s' exists - make sure this route is named or you provide a url for this job starting with a /", destination);
}
// TODO - unused pathvar should be converted to query parameters
return namedRoute.getReverseRoute(task.getParams()).getUri();
}
}
protected Method determineMethod(Job task) {
HttpMethod method = task.getMethod();
String destination = task.getDestination();
if (!destination.startsWith("/")) {
Route namedRoute = router.getNamedRoute(destination);
if (namedRoute != null) {
method = namedRoute.getReverseRoute(task.getParams()).getMethod();
}
}
if (HttpMethod.GET == method) {
return TaskOptions.Method.GET;
}
if (HttpMethod.DELETE == method) {
return TaskOptions.Method.DELETE;
}
if (HttpMethod.HEAD == method) {
return TaskOptions.Method.HEAD;
}
if (HttpMethod.POST == method) {
return TaskOptions.Method.POST;
}
if (HttpMethod.PUT == method) {
return TaskOptions.Method.PUT;
}
return TaskOptions.Method.POST;
}
protected Queue getQueue(Job task) {
String queueName = task.getQueue();
return StringUtils.isBlank(queueName) ? QueueFactory.getDefaultQueue() : QueueFactory.getQueue(queueName);
}
}