Groovy Scripts as REST Services
1 Overview
This article describes how to use Groovy scripts as REST services. We are going to consider these operations:- Load script and save it in JCR.
- Instantiate script.
- Deploy newly created Class as RESTful service.
- Script Lifecycle Management.
- And finally we will discover simple example which can get JCR node UUID.
2 Loading script and save it in JCR
There are two ways to save a script in JCR. The first way is to save it at server startup time by using configuration.xml and the second way is to upload the script via HTTP.2.1 Load script at startup time
This way can be used for load prepared scripts, for use this way we must configure org.exoplatform.services.jcr.ext.script.groovy.GroovyScript2RestLoaderPlugin. This is simple configuration example.<external-component-plugins>
<target-component>org.exoplatform.services.jcr.ext.script.groovy.GroovyScript2RestLoader</target-component>
<component-plugin>
<name>test</name>
<set-method>addPlugin</set-method>
<type>org.exoplatform.services.jcr.ext.script.groovy.GroovyScript2RestLoaderPlugin</type>
<init-params>
<value-param>
<name>repository</name>
<value>repository</value>
</value-param>
<value-param>
<name>workspace</name>
<value>production</value>
</value-param>
<value-param>
<name>node</name>
<value>/script/groovy</value>
</value-param>
<properties-param>
<name>JcrGroovyTest.groovy</name>
<property name="autoload" value="true" />
<property name="path" value="file:/home/andrew/JcrGroovyTest.groovy" />
</properties-param>
</init-params>
</component-plugin>
</external-component-plugins>2.2 Load script via HTTP
This is samples of HTTP requests. In this examples we will upload script from file with name test.groovy.andrew@ossl:~> curl -u root:exo \
-X POST \
-H 'Content-type:script/groovy' \
--data-binary @test.groovy \
http://localhost:8080/rest/script/groovy/add/repository/production/script/groovy/test.groovyandrew@ossl:~> curl -u root:exo \ -X POST \ -F "file=@test.groovy;name=test" \ -F "autoload=true" \ http://localhost:8080/rest/script/groovy/add/repository/production/script/groovy/test1.groovy
3 Instantiation
org.exoplatform.services.script.groovy.GroovyScriptInstantiator is part of project exo.core.component.script.groovy. GroovyScriptInstantiator can load script from specified URL and parse stream that contains Groovy source code. It has possibility inject component from Container in Groovy Class constructor. Configuration example:<component> <type>org.exoplatform.services.script.groovy.GroovyScriptInstantiator</type> </component>
4 Deploy newly created Class as RESTful service
For deploy script automatically at server statup time its property exo:autoload must be set as true. org.exoplatform.services.jcr.ext.script.groovy.GroovyScript2RestLoader check JCR workspaces which were specified in configuration and deploy all auto-loadable scripts. Example of configuration.<component>
<type>org.exoplatform.services.jcr.ext.script.groovy.GroovyScript2RestLoader</type>
<init-params>
<object-param>
<name>observation.config</name>
<object type="org.exoplatform.services.jcr.ext.script.groovy.ObservationListenerConfiguration">
<field name="repository">
<string>repository</string>
</field>
<field name="workspaces">
<collection type="java.util.ArrayList">
<value>
<string>production</string>
</value>
</collection>
</field>
</object>
</object-param>
</init-params>
</component>5 Script Lifecycle Management
If GroovyScript2RestLoader configured as was decribed in previous section then all "autoload" scripts deployed. In first section we added script from file /home/andrew/JcrGroovyTest.groovy to JCR node /script/groovy/JcrGroovyTest.groovy, repository repository, workspace production. In section "Load script via HTTP" it was refered about load scripts via HTTP, there is an opportunity to manage the life cycle of script. Undeploy script, which is alredy deployed:andrew@ossl:~> curl -u root:exo \ -X GET \ http://localhost:8080/rest/script/groovy/load/repository/production/script/groovy/JcrGroovyTest.groovy?state=false
andrew@ossl:~> curl -u root:exo \ -X GET \ http://localhost:8080/rest/script/groovy/load/repository/production/script/groovy/JcrGroovyTest.groovy?state=true
andrew@ossl:~> curl -u root:exo \
-X GET \
http://localhost:8080/rest/script/groovy/load/repository/production/script/groovy/JcrGroovyTest.groovyandrew@ossl:~> curl -u root:exo \ -X GET \ http://localhost:8080/rest/script/groovy/repository/production/script/groovy/JcrGroovyTest.groovy/autoload?state=false
andrew@ossl:~> curl -u root:exo \ -X GET \ http://localhost:8080/rest/script/groovy/autoload/repository/production/script/groovy/JcrGroovyTest.groovy?state=true
andrew@ossl:~> curl -u root:exo \
-X GET \
http://localhost:8080/rest/script/groovy/autoload/repository/production/script/groovy/JcrGroovyTest.groovyandrew@ossl:~> curl -u root:exo \
-X POST \
-H 'Content-type:script/groovy' \
--data-binary @JcrGroovyTest.groovy \
http://localhost:8080/rest/script/groovy/update/repository/production/script/groovy/JcrGroovyTest.groovyandrew@ossl:~> curl -u root:exo \ -X POST \ -F "file=@JcrGroovyTest.groovy;name=test" \ http://localhost:8080/rest/script/groovy/update/repository/production/script/groovy/JcrGroovyTest.groovy
andrew@ossl:~> curl -u root:exo \
-X GET \
http://localhost:8080/rest/script/groovy/delete/repository/production/script/groovy/JcrGroovyTest.groovy6 Get node UUID example
Now we are going to try simple example of Groovy RESTfull service. There is one limitation, even if we use groovy we should use Java style code and decline to use dynamic types, but of course we can use it in private methods and feilds. Create file JcrGroovyTest.groovy, in this example I save it in my home directory /home/andrew/JcrGroovyTest.groovy. Then configure GroovyScript2RestLoaderPlugin as described in section Load script at startup time.import javax.jcr.Node import javax.jcr.Session import javax.ws.rs.GET import javax.ws.rs.Path import javax.ws.rs.PathParam import org.exoplatform.services.jcr.RepositoryService import org.exoplatform.services.jcr.ext.app.ThreadLocalSessionProviderService @Path("groovy/test/{repository}/{workspace}") public class JcrGroovyTest { private RepositoryService repositoryService private ThreadLocalSessionProviderService sessionProviderService public JcrGroovyTest(RepositoryService repositoryService, ThreadLocalSessionProviderService sessionProviderService) { this.repositoryService = repositoryService this.sessionProviderService = sessionProviderService } @GET @Path("{path:.*}") public String nodeUUID(@PathParam("repository") String repository, @PathParam("workspace") String workspace, @PathParam("path") String path) { Session ses = null try { ses = sessionProviderService.getSessionProvider(null).getSession(workspace, repositoryService.getRepository(repository)) Node node = (Node) ses.getItem("/" + path) return node.getUUID() + "\n" } finally { if (ses != null) ses.logout() } } }
In screenshot we can see service deployed.
First create folder via WebDAV in repository production, folder name 'test'.
Now we can try access this service. Open another console and type command:
andrew@ossl:~> curl -u root:exo \
http://localhost:8080/rest/groovy/test/repository/production/test@POST @Path("{path:.*}") public void addReferenceableMixin(@PathParam("repository") String repository, @PathParam("workspace") String workspace, @PathParam("path") String path) { Session ses = null try { ses = sessionProviderService.getSessionProvider(null).getSession(workspace, repositoryService.getRepository(repository)) Node node = (Node) ses.getItem("/" + path) node.addMixin("mix:referenceable") ses.save() } finally { if (ses != null) ses.logout() } }
andrew@ossl:~> curl -i -v -u root:exo \
-X POST \
--data-binary @JcrGroovyTest.groovy \
-H 'Content-type:script/groovy' \
http://localhost:8080/rest/script/groovy/update/repository/production/script/groovy/JcrGroovyTest.groovy
Script was redeployed, now try access newly created method.
andrew@ossl:~> curl -u root:exo \
-X POST \
http://localhost:8080/rest/groovy/test/repository/production/testandrew@ossl:~> curl -u root:exo \
http://localhost:8080/rest/groovy/test/repository/production/test
1b8c88d37f0000020084433d3af4941fandrew@ossl:~> curl -u root:exo \
http://localhost:8080/rest/script/groovy/delete/repository/production/script/groovy/JcrGroovyTest.groovy
That is all.
on 08/05/2009 at 12:49