All Downloads are FREE. Search and download functionalities are using the official Maven repository.

com.threewks.thundr.gae.job.JobQueueImpl Maven / Gradle / Ivy

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);
	}
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy