Talk about carrera's GroovyScriptAction

order

This article focuses on carrera's GroovyScriptAction

Action

DDMQ/carrera-consumer/src/main/java/com/xiaojukeji/carrera/cproxy/actions/Action.java

public interface Action {
    enum Status {
        FAIL, CONTINUE, FINISH, ASYNCHRONIZED
    }

    class UnsupportedDataType extends RuntimeException {
    }

    default Status act(UpstreamJob job) {
        Object data = job.getData();
        if (data instanceof byte[]) {
            return act(job, (byte[]) data);
        } else if (data instanceof JSONObject) {
            return act(job, (JSONObject) data);
        } else {
            throw new UnsupportedDataType();
        }
    }

    default Status act(UpstreamJob job, byte[] bytes) {
        throw new UnsupportedDataType();
    }

    default Status act(UpstreamJob job, JSONObject jsonObject) {
        throw new UnsupportedDataType();
    }

    default void shutdown() {
        // DO NOTHING BY DEFAULT
    }

    default void logMetrics() {
        // DO NOTHING BY DEFAULT
    }
}
  • The Action interface defines Status enumeration and act, shutdown and logMetrics methods

GroovyScriptAction

DDMQ/carrera-consumer/src/main/java/com/xiaojukeji/carrera/cproxy/actions/GroovyScriptAction.java

public class GroovyScriptAction implements Action {
    private final static String CARRERA_GROOVY_CONTEXT = "carreraContext";

    @SuppressWarnings("rawtypes")
    private final static LoadingCache<String, Class> cache = CacheBuilder
        .newBuilder()
        .expireAfterAccess(1, TimeUnit.HOURS)
        .build(new CacheLoader<String, Class>() {
            private final AtomicLong al = new AtomicLong(0);

            @Override
            public Class load(String key) throws Exception {
                try (GroovyClassLoader groovyLoader = new GroovyClassLoader()) {
                    GroovyCodeSource gcs = AccessController.doPrivileged((PrivilegedAction<GroovyCodeSource>) () -> new GroovyCodeSource(key, "Script" + al.getAndIncrement() + ".groovy", "/groovy/shell"));
                    Class clazz = groovyLoader.parseClass(gcs, false);
                    return clazz;
                } catch (Throwable e) {
                    LogUtils.logErrorInfo("GroovyScript_error", "[GroovyErr]", e);
                    return null;
                }
            }

        });

    @Override
    public Status act(UpstreamJob job, JSONObject jsonObject) {
        String groovyText = job.getUpstreamTopic().getGroovyScript();
        if (StringUtils.isBlank(groovyText)) {
            return Status.FINISH;
        }

        try {
            @SuppressWarnings("rawtypes")
            Class groovyScript = cache.get(groovyText);
            if (groovyScript == null) {
                MetricUtils.qpsAndFilterMetric(job, MetricUtils.ConsumeResult.INVALID);
                return Status.FINISH;
            }

            jsonObject.put(CARRERA_GROOVY_CONTEXT, new GroovyContext(job));
            Script script = InvokerHelper.createScript(groovyScript, new Binding(jsonObject));
            Object scriptRet = script.run();
            if (scriptRet instanceof Boolean) {
                if ((Boolean) scriptRet) {
                    jsonObject.remove(CARRERA_GROOVY_CONTEXT);
                    return Status.CONTINUE;
                }
            }
        } catch (MissingPropertyException e) {
            LogUtils.logErrorInfo("GroovyScript_error", "missing property exception, jsonObject:{}, job:{}, e.msg:{}",
                    JsonUtils.toJsonString(jsonObject), job.info(), e.getMessageWithoutLocationText());
        } catch (Throwable e) {
            LogUtils.logErrorInfo("GroovyScript_error", "error when running groovy script, job={}, e={}", job, e.getMessage());
        }

        MetricUtils.qpsAndFilterMetric(job, MetricUtils.ConsumeResult.INVALID);
        return Status.FINISH;
    }
}
  • GroovyScriptAction implements the Action interface. It uses the LoadingCache of guava to define the cache of groovy class. Its load method of CacheLoader will create groovyclass loader, and then parse the class of specified GroovyCodeSource; its act method obtains groovyText from job.getUpstreamTopic().getGroovyScript(), and then obtains the specified class from the cache according to groovyText, and then through in Vokerhelper. Createscript (groovyscript, new binding (jsonobject)) creates a Script, and then executes script.run() to get the return value

Summary

GroovyScriptAction implements the Action interface. It uses the LoadingCache of guava to define the cache of groovy class. Its load method of CacheLoader will create groovyclass loader, and then parse the class of specified GroovyCodeSource; its act method obtains groovyText from job.getUpstreamTopic().getGroovyScript(), and then obtains the specified class from the cache according to groovyText, and then through in Vokerhelper. Createscript (groovyscript, new binding (jsonobject)) creates a Script, and then executes script.run() to get the return value

doc

Tags: Programming Java shell

Posted on Sat, 11 Jan 2020 11:46:06 -0500 by stanleycwb