Package com.thinkaurelius.faunus.tinkerpop.rexster

Source Code of com.thinkaurelius.faunus.tinkerpop.rexster.FaunusRexsterExecutorExtension

package com.thinkaurelius.faunus.tinkerpop.rexster;

import com.tinkerpop.rexster.RexsterResourceContext;
import com.tinkerpop.rexster.extension.AbstractRexsterExtension;
import com.tinkerpop.rexster.extension.ExtensionDefinition;
import com.tinkerpop.rexster.extension.ExtensionDescriptor;
import com.tinkerpop.rexster.extension.ExtensionMethod;
import com.tinkerpop.rexster.extension.ExtensionNaming;
import com.tinkerpop.rexster.extension.ExtensionPoint;
import com.tinkerpop.rexster.extension.ExtensionResponse;
import com.tinkerpop.rexster.extension.HttpMethod;
import com.tinkerpop.rexster.extension.RexsterContext;
import org.apache.log4j.Logger;
import org.codehaus.jettison.json.JSONObject;

import javax.ws.rs.core.Response;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;
import java.util.UUID;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ConcurrentMap;

/**
* Allows for remote execution and monitoring of a Faunus job via Rexster.
*
* @author Stephen Mallette (http://stephen.genoprime.com)
*/
@ExtensionNaming(namespace = FaunusRexsterExecutorExtension.EXTENSION_NAMESPACE, name = FaunusRexsterExecutorExtension.EXTENSION_NAME)
public class FaunusRexsterExecutorExtension extends AbstractRexsterExtension {
    private static final Logger logger = Logger.getLogger(FaunusRexsterExecutorExtension.class);

    public static final String EXTENSION_NAMESPACE = "faunus";
    public static final String EXTENSION_NAME = "executor";

    public static final String STATUS_ERROR = "error";
    public static final String STATUS_PROCESSING = "processing";
    public static final String STATUS_COMPLETE = "complete";

    public static final String FIELD_JOB = "job";
    public static final String FIELD_STATUS = "status";
    public static final String FIELD_MESSAGE = "message";

    private static final ConcurrentMap<String,FaunusEvaluationJob> jobs = new ConcurrentHashMap<String, FaunusEvaluationJob>();

    @ExtensionDefinition(extensionPoint = ExtensionPoint.GRAPH, method = HttpMethod.POST)
    @ExtensionDescriptor(description = "Execute a Faunus job")
    public ExtensionResponse evaluatePost(@RexsterContext final RexsterResourceContext context) {
        final String script = context.getRequestObject().optString("script");
        if (script == null || script.isEmpty()) {
            ExtensionMethod extMethod = context.getExtensionMethod();
            return ExtensionResponse.error("the script parameter cannot be empty", null,
                    Response.Status.BAD_REQUEST.getStatusCode(), null, generateErrorJson(extMethod.getExtensionApiAsJson()));
        }

        final JSONObject config = context.getRequestObject().optJSONObject("config");
        final UUID jobId = UUID.randomUUID();
        final FaunusEvaluationJob job = new FaunusEvaluationJob(script, jobId, context.getRexsterApplicationGraph(),
                convertToMap(config));

        logger.info(String.format("Faunus script [%s] assigned job id: %s", script, jobId));

        jobs.put(jobId.toString(), job);

        new Thread(new Runnable() {
            @Override
            public void run() {
                job.performJob();
            }
        }).start();

        return ExtensionResponse.ok(new HashMap<String,Object>() {{ put(FIELD_JOB, jobId.toString()); }});
    }

    @ExtensionDefinition(extensionPoint = ExtensionPoint.GRAPH, method = HttpMethod.GET)
    @ExtensionDescriptor(description = "Get Faunus job status")
    public ExtensionResponse evaluateGet(@RexsterContext final RexsterResourceContext context) {
        final String job = context.getRequestObject().optString("job");
        if (job == null || job.isEmpty()) {
            ExtensionMethod extMethod = context.getExtensionMethod();
            return ExtensionResponse.error("the job parameter cannot be empty", null,
                    Response.Status.BAD_REQUEST.getStatusCode(), null, generateErrorJson(extMethod.getExtensionApiAsJson()));
        }

        if (!jobs.containsKey(job)) {
            return new ExtensionResponse(Response.status(Response.Status.NOT_FOUND).build());
        }

        synchronized (this) {
            final FaunusEvaluationJob fej = jobs.get(job);
            final String status = fej.isComplete() ? (fej.isError() ? STATUS_ERROR : STATUS_COMPLETE) : STATUS_PROCESSING;

            if (fej.isComplete()) {
                jobs.remove(job);
            }

            return ExtensionResponse.ok(new HashMap<String,Object>(){{
                put(FIELD_JOB, job);
                put(FIELD_STATUS, status);
                put(FIELD_MESSAGE, fej.getErrorMessage());
            }});
        }
    }

    private static Map<String,String> convertToMap(final JSONObject config) {
        final Map<String,String> m = new HashMap<String, String>();

        if (config != null) {
            final Iterator itty = config.keys();
            while (itty.hasNext()) {
                final String currentKey = itty.next().toString();
                m.put(currentKey, config.optString(currentKey));
            }
        }

        return m;
    }
}
TOP

Related Classes of com.thinkaurelius.faunus.tinkerpop.rexster.FaunusRexsterExecutorExtension

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.