DICE-UNC/jargon

Execute rule defined in core.re

Closed this issue · 14 comments

The examples I have found in the code show how to execute a rule file or a rule string.
Is it possible to execute a rule defined in the core.re?

For a bit more clarity, we have a rule in core.re:

my_rule(){
   some actions
}

With icommands we can execute this rule like this:

irule -r irods_rule_engine_plugin-irods_rule_language-instance my_rule '*var1=/zone/home/user/dir/file.txt' ruleExecOut

For now we can't find the example to do the same in jargon.

Here's an example demonstrating how to call writeLine and extracting the values written by the server.

IRODSAccount acct = IRODSAccount.instance(/* removed for brevity */);

IRODSFileSystem fsys = IRODSFileSystem.instance();
IRODSAccessObjectFactory aof = fsys.getIRODSAccessObjectFactory();

StringBuilder sb = new StringBuilder();
sb.append("main { writeLine('stdout', 'x=[*x], y=[*y]'); *y = 'updated by server'; }\n");
sb.append("INPUT *x=,*y=\n");
sb.append("OUTPUT *y, ruleExecOut");
		
List<IRODSRuleParameter> params = new ArrayList<>();
params.add(new IRODSRuleParameter("*x", "kory"));
params.add(new IRODSRuleParameter("*y", "draughn"));

RuleProcessingAO rpao = aof.getRuleProcessingAO(acct);
RuleInvocationConfiguration ctx = new RuleInvocationConfiguration();
ctx.setIrodsRuleInvocationTypeEnum(IrodsRuleInvocationTypeEnum.OTHER);
ctx.setRuleEngineSpecifier("irods_rule_engine_plugin-irods_rule_language-instance");
		
try {
    IRODSRuleExecResult execRes = rpao.executeRule(sb.toString(), params, ctx);
    System.out.println(execRes.getRuleExecOut());
    System.out.println(execRes.getRuleExecErr());
    System.out.println(execRes.getOutputParameterResults());
    System.out.println("         *y = " + execRes.getOutputParameterResults().get("*y").getResultObject());
    System.out.println("ruleExecOut = " + execRes.getOutputParameterResults().get("ruleExecOut").getResultObject());
}
finally {
    aof.closeSessionAndEatExceptions();
    fsys.closeAndEatExceptions();
}

But this “injects” the content of the rule into a call right?

rpao.executeRule(sb.toString(), params, ctx);

if an admin developed a rule and made it available through core.re how would I execute that rule without knowing the content?

But this “injects” the content of the rule into a call right?

The example demonstrates how to call a rule defined in the server. The example just happens to use writeLine. You can update the contents of main { <contents> } to call any number of rules in core.re. For example:

main { admin_approved_rule(*arg0, ..., *argN); }

If a rodsadmin wants to expose rules in the server to users, then they must also describe the expected inputs and outputs. iRODS doesn't provide a mechanism for users to query the contents of core.re.

how would I execute that rule without knowing the content?

The admin must tell the user what's available. iRODS doesn't provide a mechanism for users to query the contents of core.re.

@jjkoehorst Does that answer your question?

I think so… will try it out asap tomorrow morning.

Sounds good.

We'll leave this open until we hear back from you.

I think I am getting the concept however no luck yet

if (credentials.isSuccess()) {
            // irule -r irods_rule_engine_plugin-irods_rule_language-instance rdm_archive_this '*file_or_collection=/RDMtest/home/user/somecollection' ruleExecOut
            IRODSFileSystem fsys = IRODSFileSystem.instance();
            IRODSAccessObjectFactory aof = fsys.getIRODSAccessObjectFactory();

            StringBuilder sb = new StringBuilder();
            sb.append("main { rdm_archive_this('file_or_collection=[*x]'); }\n");
            sb.append("INPUT *x=\n");
            sb.append("OUTPUT ruleExecOut");

            List<IRODSRuleParameter> params = new ArrayList<>();
            params.add(new IRODSRuleParameter("*x", "/unlock/home/wur.fdp/largefile"));

            RuleProcessingAO rpao = aof.getRuleProcessingAO(credentials.getIrodsAccount());
            RuleInvocationConfiguration ctx = new RuleInvocationConfiguration();
            ctx.setIrodsRuleInvocationTypeEnum(IrodsRuleInvocationTypeEnum.OTHER);
            ctx.setRuleEngineSpecifier("irods_rule_engine_plugin-irods_rule_language-instance");

            try {
                IRODSRuleExecResult execRes = rpao.executeRule(sb.toString(), params, ctx);
                System.out.println(execRes.getRuleExecOut());
                System.out.println(execRes.getRuleExecErr());
                System.out.println(execRes.getOutputParameterResults());
                System.out.println("ruleExecOut = " + execRes.getOutputParameterResults().get("ruleExecOut").getResultObject());
            }
            finally {
                aof.closeSessionAndEatExceptions();
                fsys.closeAndEatExceptions();
            }
        }
    }

ill try to find out what this means

2024-08-13 08:20:24,265 [ERROR] o.i.j.c.c.IRODSMidLevelProtocol [Test worker] IRODS error occured msg : -1102000

error code received from iRODS:-1102000 message:DEBUG: 

org.irods.jargon.core.exception.JargonException: error code received from iRODS:-1102000 message:DEBUG: 

	at org.irods.jargon.core.connection.IRODSErrorScanner.checkSpecificCodesAndThrowIfExceptionLocated(IRODSErrorScanner.java:281)
	at org.irods.jargon.core.connection.IRODSErrorScanner.inspectAndThrowIfNeeded(IRODSErrorScanner.java:112)
	at org.irods.jargon.core.connection.IRODSMidLevelProtocol.processMessageInfoLessThanZero(IRODSMidLevelProtocol.java:1606)
	at org.irods.jargon.core.connection.IRODSMidLevelProtocol.readMessage(IRODSMidLevelProtocol.java:1110)
	at org.irods.jargon.core.connection.IRODSMidLevelProtocol.readMessage(IRODSMidLevelProtocol.java:1078)
	at org.irods.jargon.core.connection.IRODSMidLevelProtocol.irodsFunction(IRODSMidLevelProtocol.java:445)
	at org.irods.jargon.core.connection.IRODSMidLevelProtocol.irodsFunction(IRODSMidLevelProtocol.java:571)
	at org.irods.jargon.core.connection.IRODSMidLevelProtocol.irodsFunction(IRODSMidLevelProtocol.java:927)
	at org.irods.jargon.core.pub.RuleProcessingAOImpl.executeRule(RuleProcessingAOImpl.java:452)
	at nl.fairbydesign.IRODSTest.testArchive(IRODSTest.java:362)
	at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
	at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:77)
	at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
	at java.base/java.lang.reflect.Method.invoke(Method.java:569)
	at org.junit.platform.commons.util.ReflectionUtils.invokeMethod(ReflectionUtils.java:727)
	at org.junit.jupiter.engine.execution.MethodInvocation.proceed(MethodInvocation.java:60)
	at org.junit.jupiter.engine.execution.InvocationInterceptorChain$ValidatingInvocation.proceed(InvocationInterceptorChain.java:131)
	at org.junit.jupiter.engine.extension.TimeoutExtension.intercept(TimeoutExtension.java:156)
	at org.junit.jupiter.engine.extension.TimeoutExtension.interceptTestableMethod(TimeoutExtension.java:147)
	at org.junit.jupiter.engine.extension.TimeoutExtension.interceptTestMethod(TimeoutExtension.java:86)
	at org.junit.jupiter.engine.execution.InterceptingExecutableInvoker$ReflectiveInterceptorCall.lambda$ofVoidMethod$0(InterceptingExecutableInvoker.java:103)
	at org.junit.jupiter.engine.execution.InterceptingExecutableInvoker.lambda$invoke$0(InterceptingExecutableInvoker.java:93)
	at org.junit.jupiter.engine.execution.InvocationInterceptorChain$InterceptedInvocation.proceed(InvocationInterceptorChain.java:106)
	at org.junit.jupiter.engine.execution.InvocationInterceptorChain.proceed(InvocationInterceptorChain.java:64)
	at org.junit.jupiter.engine.execution.InvocationInterceptorChain.chainAndInvoke(InvocationInterceptorChain.java:45)
	at org.junit.jupiter.engine.execution.InvocationInterceptorChain.invoke(InvocationInterceptorChain.java:37)
	at org.junit.jupiter.engine.execution.InterceptingExecutableInvoker.invoke(InterceptingExecutableInvoker.java:92)
	at org.junit.jupiter.engine.execution.InterceptingExecutableInvoker.invoke(InterceptingExecutableInvoker.java:86)
	at org.junit.jupiter.engine.descriptor.TestMethodTestDescriptor.lambda$invokeTestMethod$7(TestMethodTestDescriptor.java:217)
	at org.junit.platform.engine.support.hierarchical.ThrowableCollector.execute(ThrowableCollector.java:73)
	at org.junit.jupiter.engine.descriptor.TestMethodTestDescriptor.invokeTestMethod(TestMethodTestDescriptor.java:213)
	at org.junit.jupiter.engine.descriptor.TestMethodTestDescriptor.execute(TestMethodTestDescriptor.java:138)
	at org.junit.jupiter.engine.descriptor.TestMethodTestDescriptor.execute(TestMethodTestDescriptor.java:68)
	at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$6(NodeTestTask.java:151)
	at org.junit.platform.engine.support.hierarchical.ThrowableCollector.execute(ThrowableCollector.java:73)
	at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$8(NodeTestTask.java:141)
	at org.junit.platform.engine.support.hierarchical.Node.around(Node.java:137)
	at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$9(NodeTestTask.java:139)
	at org.junit.platform.engine.support.hierarchical.ThrowableCollector.execute(ThrowableCollector.java:73)
	at org.junit.platform.engine.support.hierarchical.NodeTestTask.executeRecursively(NodeTestTask.java:138)
	at org.junit.platform.engine.support.hierarchical.NodeTestTask.execute(NodeTestTask.java:95)
	at java.base/java.util.ArrayList.forEach(ArrayList.java:1511)
	at org.junit.platform.engine.support.hierarchical.SameThreadHierarchicalTestExecutorService.invokeAll(SameThreadHierarchicalTestExecutorService.java:41)
	at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$6(NodeTestTask.java:155)
	at org.junit.platform.engine.support.hierarchical.ThrowableCollector.execute(ThrowableCollector.java:73)
	at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$8(NodeTestTask.java:141)
	at org.junit.platform.engine.support.hierarchical.Node.around(Node.java:137)
	at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$9(NodeTestTask.java:139)
	at org.junit.platform.engine.support.hierarchical.ThrowableCollector.execute(ThrowableCollector.java:73)
	at org.junit.platform.engine.support.hierarchical.NodeTestTask.executeRecursively(NodeTestTask.java:138)
	at org.junit.platform.engine.support.hierarchical.NodeTestTask.execute(NodeTestTask.java:95)
	at java.base/java.util.ArrayList.forEach(ArrayList.java:1511)
	at org.junit.platform.engine.support.hierarchical.SameThreadHierarchicalTestExecutorService.invokeAll(SameThreadHierarchicalTestExecutorService.java:41)
	at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$6(NodeTestTask.java:155)
	at org.junit.platform.engine.support.hierarchical.ThrowableCollector.execute(ThrowableCollector.java:73)
	at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$8(NodeTestTask.java:141)
	at org.junit.platform.engine.support.hierarchical.Node.around(Node.java:137)
	at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$9(NodeTestTask.java:139)
	at org.junit.platform.engine.support.hierarchical.ThrowableCollector.execute(ThrowableCollector.java:73)
	at org.junit.platform.engine.support.hierarchical.NodeTestTask.executeRecursively(NodeTestTask.java:138)
	at org.junit.platform.engine.support.hierarchical.NodeTestTask.execute(NodeTestTask.java:95)
	at org.junit.platform.engine.support.hierarchical.SameThreadHierarchicalTestExecutorService.submit(SameThreadHierarchicalTestExecutorService.java:35)
	at org.junit.platform.engine.support.hierarchical.HierarchicalTestExecutor.execute(HierarchicalTestExecutor.java:57)
	at org.junit.platform.engine.support.hierarchical.HierarchicalTestEngine.execute(HierarchicalTestEngine.java:54)
	at org.junit.platform.launcher.core.EngineExecutionOrchestrator.execute(EngineExecutionOrchestrator.java:107)
	at org.junit.platform.launcher.core.EngineExecutionOrchestrator.execute(EngineExecutionOrchestrator.java:88)
	at org.junit.platform.launcher.core.EngineExecutionOrchestrator.lambda$execute$0(EngineExecutionOrchestrator.java:54)
	at org.junit.platform.launcher.core.EngineExecutionOrchestrator.withInterceptedStreams(EngineExecutionOrchestrator.java:67)
	at org.junit.platform.launcher.core.EngineExecutionOrchestrator.execute(EngineExecutionOrchestrator.java:52)
	at org.junit.platform.launcher.core.DefaultLauncher.execute(DefaultLauncher.java:114)
	at org.junit.platform.launcher.core.DefaultLauncher.execute(DefaultLauncher.java:86)
	at org.junit.platform.launcher.core.DefaultLauncherSession$DelegatingLauncher.execute(DefaultLauncherSession.java:86)
	at org.gradle.api.internal.tasks.testing.junitplatform.JUnitPlatformTestClassProcessor$CollectAllTestClassesExecutor.processAllTestClasses(JUnitPlatformTestClassProcessor.java:119)
	at org.gradle.api.internal.tasks.testing.junitplatform.JUnitPlatformTestClassProcessor$CollectAllTestClassesExecutor.access$000(JUnitPlatformTestClassProcessor.java:94)
	at org.gradle.api.internal.tasks.testing.junitplatform.JUnitPlatformTestClassProcessor.stop(JUnitPlatformTestClassProcessor.java:89)
	at org.gradle.api.internal.tasks.testing.SuiteTestClassProcessor.stop(SuiteTestClassProcessor.java:62)
	at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
	at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:77)
	at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
	at java.base/java.lang.reflect.Method.invoke(Method.java:569)
	at org.gradle.internal.dispatch.ReflectionDispatch.dispatch(ReflectionDispatch.java:36)
	at org.gradle.internal.dispatch.ReflectionDispatch.dispatch(ReflectionDispatch.java:24)
	at org.gradle.internal.dispatch.ContextClassLoaderDispatch.dispatch(ContextClassLoaderDispatch.java:33)
	at org.gradle.internal.dispatch.ProxyDispatchAdapter$DispatchingInvocationHandler.invoke(ProxyDispatchAdapter.java:94)
	at jdk.proxy1/jdk.proxy1.$Proxy2.stop(Unknown Source)
	at org.gradle.api.internal.tasks.testing.worker.TestWorker$3.run(TestWorker.java:193)
	at org.gradle.api.internal.tasks.testing.worker.TestWorker.executeAndMaintainThreadName(TestWorker.java:129)
	at org.gradle.api.internal.tasks.testing.worker.TestWorker.execute(TestWorker.java:100)
	at org.gradle.api.internal.tasks.testing.worker.TestWorker.execute(TestWorker.java:60)
	at org.gradle.process.internal.worker.child.ActionExecutionWorker.execute(ActionExecutionWorker.java:56)
	at org.gradle.process.internal.worker.child.SystemApplicationClassLoaderWorker.call(SystemApplicationClassLoaderWorker.java:113)
	at org.gradle.process.internal.worker.child.SystemApplicationClassLoaderWorker.call(SystemApplicationClassLoaderWorker.java:65)
	at worker.org.gradle.process.internal.worker.GradleWorkerMain.run(GradleWorkerMain.java:69)
	at worker.org.gradle.process.internal.worker.GradleWorkerMain.main(GradleWorkerMain.java:74)

trel commented
$ ierror 1102000
irods error: -1102000 NO_MICROSERVICE_FOUND_ERR

That error means there is no function/rule or microservice by that name and signature...

Can you execute the equivalent call to rdm_archive_this via irule?

Please show the signature of rdm_archive_this?

We need to see its parameter list.

works like a charm! was a typo 👍

Yep, and the signature as well:

Rule was:

rule_name{
    python_version_of_rule_in_core_py(*argument)
}

and not

rule_name(*argument){
    python_version_of_rule_in_core_py(*argument)
}

hence it needed to be:

sb.append("main { rdm_archive_this(); }\n");
...
params.add(new IRODSRuleParameter("*argument", "/unlock/home/wur.fdp/largefile"));

I see. Glad you got it to work.

Thanks for the help, sometimes the solution is obvious but you still don't see it.