You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@unomi.apache.org by GitBox <gi...@apache.org> on 2021/09/09 11:04:27 UTC

[GitHub] [unomi] jsinovassin opened a new pull request #337: Tech 484 provide unomi groovy actions endpoint

jsinovassin opened a new pull request #337:
URL: https://github.com/apache/unomi/pull/337


   PR Title format: 
   
       [UNOMI-XXX] Pull request title with JIRA reference
   
   **Please** add a meaningful description for your change here
   
   ----
   
   **Please** following this checklist to help us incorporate your contribution quickly and easily:
   
    - [ ] Make sure there is a [JIRA issue](https://issues.apache.org/jira/browse/UNOMI) filed 
          for the change (usually before you start working on it).  Trivial changes like typos do not 
          require a JIRA issue.  Your pull request should address just this issue, without pulling in other changes.
    - [ ] Format the pull request title like `[UNOMI-XXX] - Title of the pull request`
    - [ ] Provide integration tests for your changes, especially if you are changing the behavior of existing code or adding
          significant new parts of code.
    - [ ] Write a pull request description that is detailed enough to understand what the pull request does, how, and why. 
          Copy the description to the related JIRA issue
    - [ ] Run `mvn clean install -P integration-tests` to make sure basic checks pass. A more thorough check will be 
           performed on your pull request automatically.
    
   Trivial changes like typos do not require a JIRA issue (javadoc, project build changes, small doc changes, comments...). 
    
   If this is your first contribution, you have to read the [Contribution Guidelines](https://unomi.apache.org/contribute.html)
   
   If your pull request is about ~20 lines of code you don't need to sign an [Individual Contributor License Agreement](https://www.apache.org/licenses/icla.pdf) 
   if you are unsure please ask on the developers list.
   
   To make clear that you license your contribution under the [Apache License Version 2.0, January 2004](http://www.apache.org/licenses/LICENSE-2.0)
   you have to acknowledge this by using the following check-box.
   
    - [ ] I hereby declare this contribution to be licenced under the [Apache License Version 2.0, January 2004](http://www.apache.org/licenses/LICENSE-2.0)
   


-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: dev-unsubscribe@unomi.apache.org

For queries about this service, please contact Infrastructure at:
users@infra.apache.org



[GitHub] [unomi] sergehuber commented on a change in pull request #337: UNOMI-508 provide Unomi Groovy actions endpoint

Posted by GitBox <gi...@apache.org>.
sergehuber commented on a change in pull request #337:
URL: https://github.com/apache/unomi/pull/337#discussion_r709326638



##########
File path: extensions/groovy-actions/services/src/main/java/org/apache/unomi/groovy/actions/GroovyActionDispatcher.java
##########
@@ -0,0 +1,89 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You 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 org.apache.unomi.groovy.actions;
+
+import groovy.lang.GroovyCodeSource;
+import groovy.lang.GroovyObject;
+import groovy.util.GroovyScriptEngine;
+import org.apache.unomi.api.Event;
+import org.apache.unomi.api.actions.Action;
+import org.apache.unomi.api.actions.ActionDispatcher;
+import org.apache.unomi.groovy.actions.services.GroovyActionsService;
+import org.apache.unomi.metrics.MetricAdapter;
+import org.apache.unomi.metrics.MetricsService;
+import org.osgi.framework.BundleContext;
+import org.osgi.framework.wiring.BundleWiring;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+/**
+ * An implementation of an ActionDispatcher for the Groovy language. This dispatcher will load the groovy action script matching to an
+ * actionName. If a script if found, it will be executed.
+ */
+public class GroovyActionDispatcher implements ActionDispatcher {
+
+    private static final Logger logger = LoggerFactory.getLogger(GroovyActionDispatcher.class.getName());
+
+    private static final String GROOVY_PREFIX = "groovy";
+
+    private MetricsService metricsService;
+
+    private GroovyActionsService groovyActionsService;
+
+    private BundleContext bundleContext;
+
+    public void setMetricsService(MetricsService metricsService) {
+        this.metricsService = metricsService;
+    }
+
+    public void setGroovyActionsService(GroovyActionsService groovyActionsService) {
+        this.groovyActionsService = groovyActionsService;
+    }
+
+    public void setBundleContext(BundleContext bundleContext) {
+        this.bundleContext = bundleContext;
+    }
+
+    public String getPrefix() {
+        return GROOVY_PREFIX;
+    }
+
+    public Integer execute(Action action, Event event, String actionName) {
+        GroovyAction groovyAction = groovyActionsService.getGroovyAction(actionName);
+        if (groovyAction == null) {
+            logger.warn("Couldn't find a Groovy action with name {}, action will not execute !", actionName);
+        } else {
+            try {
+                return new MetricAdapter<Integer>(metricsService, this.getClass().getName() + ".action.groovy." + actionName) {
+                    @Override
+                    public Integer execute(Object... args) throws Exception {
+                        GroovyBundleResourceConnector bundleResourceConnector = new GroovyBundleResourceConnector(bundleContext);
+                        GroovyScriptEngine engine = new GroovyScriptEngine(bundleResourceConnector,

Review comment:
       We should probably look into caching this if it is acceptable in Groovy practices.




-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: dev-unsubscribe@unomi.apache.org

For queries about this service, please contact Infrastructure at:
users@infra.apache.org



[GitHub] [unomi] jsinovassin commented on a change in pull request #337: UNOMI-508 provide unomi groovy actions endpoint

Posted by GitBox <gi...@apache.org>.
jsinovassin commented on a change in pull request #337:
URL: https://github.com/apache/unomi/pull/337#discussion_r706140434



##########
File path: extensions/groovy-actions/karaf-kar/pom.xml
##########
@@ -61,7 +69,11 @@
             <artifactId>jsoup</artifactId>
             <version>1.13.1</version>
         </dependency>
-
+        <dependency>
+            <groupId>com.sun.activation</groupId>

Review comment:
       I added it because of this error message: org.apache.felix.resolver.reason.ReasonException: Unable to resolve root: missing requirement [root] osgi.identity; osgi.identity=unomi-groovy-actions; type=karaf.feature; version="[1.6.0.SNAPSHOT,1.6.0.SNAPSHOT]"; filter:="(&(osgi.identity=unomi-groovy-actions)(type=karaf.feature)(version>=1.6.0.SNAPSHOT)(version<=1.6.0.SNAPSHOT))" [caused by: Unable to resolve unomi-groovy-actions/1.6.0.SNAPSHOT: missing requirement [unomi-groovy-actions/1.6.0.SNAPSHOT] osgi.identity; osgi.identity=org.apache.unomi.groovy-actions-rest; type=osgi.bundle; version="[1.6.0.SNAPSHOT,1.6.0.SNAPSHOT]"; resolution:=mandatory [caused by: Unable to resolve org.apache.unomi.groovy-actions-rest/1.6.0.SNAPSHOT: missing requirement [org.apache.unomi.groovy-actions-rest/1.6.0.SNAPSHOT] osgi.wiring.package; filter:="(&(osgi.wiring.package=javax.activation)(version>=1.2.0)(!(version>=2.0.0)))"]]
   




-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: dev-unsubscribe@unomi.apache.org

For queries about this service, please contact Infrastructure at:
users@infra.apache.org



[GitHub] [unomi] sergehuber commented on a change in pull request #337: UNOMI-508 provide Unomi Groovy actions endpoint

Posted by GitBox <gi...@apache.org>.
sergehuber commented on a change in pull request #337:
URL: https://github.com/apache/unomi/pull/337#discussion_r708152040



##########
File path: itests/src/test/java/org/apache/unomi/itests/GroovyActionsServiceIT.java
##########
@@ -0,0 +1,108 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You 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 org.apache.unomi.itests;
+
+import org.apache.unomi.api.actions.ActionType;
+import org.apache.unomi.api.services.DefinitionsService;
+import org.apache.unomi.groovy.actions.GroovyAction;
+import org.apache.unomi.groovy.actions.services.GroovyActionsService;
+import org.apache.unomi.groovy.actions.utils.Utils;
+import org.junit.After;
+import org.junit.Assert;
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.ops4j.pax.exam.junit.PaxExam;
+import org.ops4j.pax.exam.spi.reactors.ExamReactorStrategy;
+import org.ops4j.pax.exam.spi.reactors.PerSuite;
+import org.ops4j.pax.exam.util.Filter;
+
+import javax.inject.Inject;
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.IOException;
+
+@RunWith(PaxExam.class)
+@ExamReactorStrategy(PerSuite.class)
+public class GroovyActionsServiceIT extends BaseIT {
+
+    @Inject
+    @Filter(timeout = 600000)
+    protected GroovyActionsService groovyActionsService;
+
+    @Inject
+    @Filter(timeout = 600000)
+    protected DefinitionsService definitionsService;
+
+    @Before
+    public void setUp() throws InterruptedException {
+        refreshPersistence();
+    }
+
+    @After
+    public void cleanUp() throws InterruptedException {
+        refreshPersistence();
+    }
+
+    private String loadGroovyAction(String pathname) throws IOException {
+        return Utils.convertInputStreamToString(new FileInputStream(new File(pathname)));

Review comment:
       Please replace with IOUtils.toString(InputStream)

##########
File path: extensions/groovy-actions/services/src/main/java/org/apache/unomi/groovy/actions/GroovyAction.java
##########
@@ -0,0 +1,58 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You 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 org.apache.unomi.groovy.actions;
+
+import org.apache.unomi.api.Metadata;
+import org.apache.unomi.api.MetadataItem;
+
+/**
+ * Object which represents a Groovy action

Review comment:
       ```suggestion
    * Object which represents a Groovy action (including its script)
   ```
   ```suggestion
    * Object which represents a Groovy action
   ```

##########
File path: extensions/groovy-actions/services/src/main/java/org/apache/unomi/groovy/actions/utils/Utils.java
##########
@@ -0,0 +1,40 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You 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 org.apache.unomi.groovy.actions.utils;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.InputStreamReader;
+import java.io.Reader;
+import java.nio.charset.StandardCharsets;
+
+/**
+ * Utility class
+ */
+public class Utils {
+
+    public static String convertInputStreamToString(InputStream inputStream) throws IOException {

Review comment:
       Please do not use your own implementation, there are a LOT of available ones, especially in the Commons IO library.

##########
File path: extensions/groovy-actions/karaf-kar/pom.xml
##########
@@ -61,7 +69,11 @@
             <artifactId>jsoup</artifactId>
             <version>1.13.1</version>
         </dependency>
-
+        <dependency>
+            <groupId>com.sun.activation</groupId>

Review comment:
       Ok thank you I wonder what pull that dependency.

##########
File path: itests/src/test/java/org/apache/unomi/itests/GroovyActionsServiceIT.java
##########
@@ -0,0 +1,108 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You 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 org.apache.unomi.itests;
+
+import org.apache.unomi.api.actions.ActionType;
+import org.apache.unomi.api.services.DefinitionsService;
+import org.apache.unomi.groovy.actions.GroovyAction;
+import org.apache.unomi.groovy.actions.services.GroovyActionsService;
+import org.apache.unomi.groovy.actions.utils.Utils;
+import org.junit.After;
+import org.junit.Assert;
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.ops4j.pax.exam.junit.PaxExam;
+import org.ops4j.pax.exam.spi.reactors.ExamReactorStrategy;
+import org.ops4j.pax.exam.spi.reactors.PerSuite;
+import org.ops4j.pax.exam.util.Filter;
+
+import javax.inject.Inject;
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.IOException;
+
+@RunWith(PaxExam.class)
+@ExamReactorStrategy(PerSuite.class)
+public class GroovyActionsServiceIT extends BaseIT {
+
+    @Inject
+    @Filter(timeout = 600000)
+    protected GroovyActionsService groovyActionsService;
+
+    @Inject
+    @Filter(timeout = 600000)
+    protected DefinitionsService definitionsService;
+
+    @Before
+    public void setUp() throws InterruptedException {
+        refreshPersistence();
+    }
+
+    @After
+    public void cleanUp() throws InterruptedException {
+        refreshPersistence();
+    }
+
+    private String loadGroovyAction(String pathname) throws IOException {
+        return Utils.convertInputStreamToString(new FileInputStream(new File(pathname)));
+    }
+
+    @Test
+    public void testGroovyActionsService_saveActionAndTestSavedValues() throws IOException, InterruptedException {
+        groovyActionsService.save(loadGroovyAction("data/tmp/groovy/script.groovy"));
+
+        Thread.sleep(2000);
+
+        GroovyAction groovyAction = groovyActionsService.getGroovyAction("MyAction");
+
+        ActionType actionType = definitionsService.getActionType("scriptGroovyAction");
+
+        Assert.assertEquals("MyAction", groovyAction.getItemId());
+        Assert.assertEquals("MyAction", groovyAction.getName());
+        Assert.assertTrue(groovyAction.getScript().contains("A test Groovy"));
+
+        Assert.assertTrue(actionType.getMetadata().getId().contains("scriptGroovyAction"));
+        Assert.assertEquals(2, actionType.getMetadata().getSystemTags().size());
+        Assert.assertTrue(actionType.getMetadata().getSystemTags().contains("tag1"));
+        Assert.assertEquals(2, actionType.getParameters().size());
+        Assert.assertEquals("param1", actionType.getParameters().get(0).getId());
+
+        Assert.assertEquals("groovy:MyAction", actionType.getActionExecutor());
+        Assert.assertFalse(actionType.getMetadata().isHidden());
+    }
+
+    @Test
+    public void testGroovyActionsService_removeGroovyAction() throws IOException, InterruptedException {
+        groovyActionsService.save(loadGroovyAction("data/tmp/groovy/script.groovy"));
+
+        Thread.sleep(2000);
+
+        GroovyAction groovyAction = groovyActionsService.getGroovyAction("MyAction");
+
+        Assert.assertNotNull(groovyAction);
+
+        groovyActionsService.remove("MyAction");
+
+        Thread.sleep(2000);
+
+        groovyAction = groovyActionsService.getGroovyAction("scriptGroovyAction");
+
+        Assert.assertNull(groovyAction);

Review comment:
       Shouldn't we also remove the action from the definition service ? 




-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: dev-unsubscribe@unomi.apache.org

For queries about this service, please contact Infrastructure at:
users@infra.apache.org



[GitHub] [unomi] sergehuber commented on a change in pull request #337: UNOMI-508 provide Unomi Groovy actions endpoint

Posted by GitBox <gi...@apache.org>.
sergehuber commented on a change in pull request #337:
URL: https://github.com/apache/unomi/pull/337#discussion_r709332866



##########
File path: extensions/groovy-actions/services/src/main/java/org/apache/unomi/groovy/actions/GroovyActionDispatcher.java
##########
@@ -0,0 +1,89 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You 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 org.apache.unomi.groovy.actions;
+
+import groovy.lang.GroovyCodeSource;
+import groovy.lang.GroovyObject;
+import groovy.util.GroovyScriptEngine;
+import org.apache.unomi.api.Event;
+import org.apache.unomi.api.actions.Action;
+import org.apache.unomi.api.actions.ActionDispatcher;
+import org.apache.unomi.groovy.actions.services.GroovyActionsService;
+import org.apache.unomi.metrics.MetricAdapter;
+import org.apache.unomi.metrics.MetricsService;
+import org.osgi.framework.BundleContext;
+import org.osgi.framework.wiring.BundleWiring;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+/**
+ * An implementation of an ActionDispatcher for the Groovy language. This dispatcher will load the groovy action script matching to an
+ * actionName. If a script if found, it will be executed.
+ */
+public class GroovyActionDispatcher implements ActionDispatcher {
+
+    private static final Logger logger = LoggerFactory.getLogger(GroovyActionDispatcher.class.getName());
+
+    private static final String GROOVY_PREFIX = "groovy";
+
+    private MetricsService metricsService;
+
+    private GroovyActionsService groovyActionsService;
+
+    private BundleContext bundleContext;
+
+    public void setMetricsService(MetricsService metricsService) {
+        this.metricsService = metricsService;
+    }
+
+    public void setGroovyActionsService(GroovyActionsService groovyActionsService) {
+        this.groovyActionsService = groovyActionsService;
+    }
+
+    public void setBundleContext(BundleContext bundleContext) {
+        this.bundleContext = bundleContext;
+    }
+
+    public String getPrefix() {
+        return GROOVY_PREFIX;
+    }
+
+    public Integer execute(Action action, Event event, String actionName) {
+        GroovyAction groovyAction = groovyActionsService.getGroovyAction(actionName);
+        if (groovyAction == null) {
+            logger.warn("Couldn't find a Groovy action with name {}, action will not execute !", actionName);
+        } else {
+            try {
+                return new MetricAdapter<Integer>(metricsService, this.getClass().getName() + ".action.groovy." + actionName) {
+                    @Override
+                    public Integer execute(Object... args) throws Exception {
+                        GroovyBundleResourceConnector bundleResourceConnector = new GroovyBundleResourceConnector(bundleContext);
+                        GroovyScriptEngine engine = new GroovyScriptEngine(bundleResourceConnector,
+                                bundleContext.getBundle().adapt(BundleWiring.class).getClassLoader());
+
+                        Class clazzScript = engine.getGroovyClassLoader().parseClass(new GroovyCodeSource(groovyAction.getScript(), actionName, "/groovy/script"));
+                        GroovyObject groovyObj = (GroovyObject) clazzScript.newInstance();

Review comment:
       Maybe we should cache the groovyObject to avoid the overhead of compiling the class and instantiating it.




-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: dev-unsubscribe@unomi.apache.org

For queries about this service, please contact Infrastructure at:
users@infra.apache.org



[GitHub] [unomi] sergehuber commented on a change in pull request #337: Tech 484 provide unomi groovy actions endpoint

Posted by GitBox <gi...@apache.org>.
sergehuber commented on a change in pull request #337:
URL: https://github.com/apache/unomi/pull/337#discussion_r705285158



##########
File path: extensions/groovy-actions/karaf-kar/pom.xml
##########
@@ -61,7 +69,11 @@
             <artifactId>jsoup</artifactId>
             <version>1.13.1</version>
         </dependency>
-
+        <dependency>
+            <groupId>com.sun.activation</groupId>

Review comment:
       Why is this needed ? 

##########
File path: extensions/groovy-actions/rest/pom.xml
##########
@@ -0,0 +1,89 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+  ~ Licensed to the Apache Software Foundation (ASF) under one or more
+  ~ contributor license agreements.  See the NOTICE file distributed with
+  ~ this work for additional information regarding copyright ownership.
+  ~ The ASF licenses this file to You 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.
+  -->
+
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+    <parent>
+        <groupId>org.apache.unomi</groupId>
+        <artifactId>unomi-groovy-actions-root</artifactId>
+        <version>1.6.0-SNAPSHOT</version>
+    </parent>
+    <modelVersion>4.0.0</modelVersion>
+
+    <artifactId>unomi-groovy-actions-rest</artifactId>
+    <name>Apache Unomi :: Extensions :: Groovy Actions :: REST API</name>
+    <description>REST API for the Apache Unomi Context Server extension that integrates with groovy actions</description>
+    <packaging>bundle</packaging>
+
+    <dependencies>
+        <dependency>
+            <groupId>org.apache.unomi</groupId>
+            <artifactId>unomi-api</artifactId>
+            <version>${project.version}</version>
+            <scope>provided</scope>
+        </dependency>
+
+        <dependency>
+            <groupId>org.apache.unomi</groupId>
+            <artifactId>unomi-groovy-actions-services</artifactId>
+            <version>${project.version}</version>
+            <scope>provided</scope>
+        </dependency>
+
+        <dependency>
+            <groupId>javax.servlet</groupId>
+            <artifactId>javax.servlet-api</artifactId>
+            <scope>provided</scope>
+        </dependency>
+
+        <dependency>
+            <groupId>org.apache.cxf</groupId>
+            <artifactId>cxf-rt-frontend-jaxws</artifactId>
+            <scope>provided</scope>
+        </dependency>
+        <dependency>
+            <groupId>org.apache.cxf</groupId>
+            <artifactId>cxf-rt-frontend-jaxrs</artifactId>
+            <scope>provided</scope>
+        </dependency>
+        <dependency>
+            <groupId>org.apache.cxf</groupId>
+            <artifactId>cxf-rt-transports-http</artifactId>
+            <scope>provided</scope>
+        </dependency>
+        <dependency>
+            <groupId>org.apache.cxf</groupId>
+            <artifactId>cxf-rt-rs-security-cors</artifactId>

Review comment:
       Might be missing a <scope>provided</scope>

##########
File path: extensions/groovy-actions/karaf-kar/pom.xml
##########
@@ -61,7 +69,11 @@
             <artifactId>jsoup</artifactId>
             <version>1.13.1</version>
         </dependency>
-
+        <dependency>
+            <groupId>com.sun.activation</groupId>

Review comment:
       Why is this needed ?

##########
File path: extensions/groovy-actions/rest/pom.xml
##########
@@ -0,0 +1,89 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+  ~ Licensed to the Apache Software Foundation (ASF) under one or more
+  ~ contributor license agreements.  See the NOTICE file distributed with
+  ~ this work for additional information regarding copyright ownership.
+  ~ The ASF licenses this file to You 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.
+  -->
+
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+    <parent>
+        <groupId>org.apache.unomi</groupId>
+        <artifactId>unomi-groovy-actions-root</artifactId>
+        <version>1.6.0-SNAPSHOT</version>
+    </parent>
+    <modelVersion>4.0.0</modelVersion>
+
+    <artifactId>unomi-groovy-actions-rest</artifactId>
+    <name>Apache Unomi :: Extensions :: Groovy Actions :: REST API</name>
+    <description>REST API for the Apache Unomi Context Server extension that integrates with groovy actions</description>
+    <packaging>bundle</packaging>
+
+    <dependencies>
+        <dependency>
+            <groupId>org.apache.unomi</groupId>
+            <artifactId>unomi-api</artifactId>
+            <version>${project.version}</version>
+            <scope>provided</scope>
+        </dependency>
+
+        <dependency>
+            <groupId>org.apache.unomi</groupId>
+            <artifactId>unomi-groovy-actions-services</artifactId>
+            <version>${project.version}</version>
+            <scope>provided</scope>
+        </dependency>
+
+        <dependency>
+            <groupId>javax.servlet</groupId>
+            <artifactId>javax.servlet-api</artifactId>
+            <scope>provided</scope>
+        </dependency>
+
+        <dependency>
+            <groupId>org.apache.cxf</groupId>
+            <artifactId>cxf-rt-frontend-jaxws</artifactId>
+            <scope>provided</scope>
+        </dependency>
+        <dependency>
+            <groupId>org.apache.cxf</groupId>
+            <artifactId>cxf-rt-frontend-jaxrs</artifactId>
+            <scope>provided</scope>
+        </dependency>
+        <dependency>
+            <groupId>org.apache.cxf</groupId>
+            <artifactId>cxf-rt-transports-http</artifactId>
+            <scope>provided</scope>
+        </dependency>
+        <dependency>
+            <groupId>org.apache.cxf</groupId>
+            <artifactId>cxf-rt-rs-security-cors</artifactId>

Review comment:
       Shouldn't this be with <scope>provided</scope> ? 

##########
File path: extensions/groovy-actions/services/src/main/java/org/apache/unomi/groovy/actions/services/GroovyActionsService.java
##########
@@ -0,0 +1,30 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You 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 org.apache.unomi.groovy.actions.services;
+
+import java.io.File;
+
+/**
+ * Short description of the interface

Review comment:
       It is the convention that all interfaces have minimal Javadoc documentation in Unomi. Please add some documentation for the class and methods. Thank you

##########
File path: extensions/groovy-actions/rest/pom.xml
##########
@@ -0,0 +1,89 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+  ~ Licensed to the Apache Software Foundation (ASF) under one or more
+  ~ contributor license agreements.  See the NOTICE file distributed with
+  ~ this work for additional information regarding copyright ownership.
+  ~ The ASF licenses this file to You 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.
+  -->
+
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+    <parent>
+        <groupId>org.apache.unomi</groupId>
+        <artifactId>unomi-groovy-actions-root</artifactId>
+        <version>1.6.0-SNAPSHOT</version>
+    </parent>
+    <modelVersion>4.0.0</modelVersion>
+
+    <artifactId>unomi-groovy-actions-rest</artifactId>
+    <name>Apache Unomi :: Extensions :: Groovy Actions :: REST API</name>
+    <description>REST API for the Apache Unomi Context Server extension that integrates with groovy actions</description>
+    <packaging>bundle</packaging>
+
+    <dependencies>
+        <dependency>
+            <groupId>org.apache.unomi</groupId>
+            <artifactId>unomi-api</artifactId>
+            <version>${project.version}</version>
+            <scope>provided</scope>
+        </dependency>
+
+        <dependency>
+            <groupId>org.apache.unomi</groupId>
+            <artifactId>unomi-groovy-actions-services</artifactId>
+            <version>${project.version}</version>
+            <scope>provided</scope>
+        </dependency>
+
+        <dependency>
+            <groupId>javax.servlet</groupId>
+            <artifactId>javax.servlet-api</artifactId>
+            <scope>provided</scope>
+        </dependency>
+
+        <dependency>
+            <groupId>org.apache.cxf</groupId>
+            <artifactId>cxf-rt-frontend-jaxws</artifactId>
+            <scope>provided</scope>
+        </dependency>
+        <dependency>
+            <groupId>org.apache.cxf</groupId>
+            <artifactId>cxf-rt-frontend-jaxrs</artifactId>
+            <scope>provided</scope>
+        </dependency>
+        <dependency>
+            <groupId>org.apache.cxf</groupId>
+            <artifactId>cxf-rt-transports-http</artifactId>
+            <scope>provided</scope>
+        </dependency>
+        <dependency>
+            <groupId>org.apache.cxf</groupId>
+            <artifactId>cxf-rt-rs-security-cors</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>com.fasterxml.jackson.jaxrs</groupId>
+            <artifactId>jackson-jaxrs-json-provider</artifactId>

Review comment:
       Same here : provided ? 

##########
File path: extensions/groovy-actions/services/src/main/java/org/apache/unomi/groovy/actions/annotations/Action.java
##########
@@ -0,0 +1,37 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You 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 org.apache.unomi.groovy.actions.annotations;
+
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+
+@Retention(RetentionPolicy.RUNTIME)
+public @interface Action {

Review comment:
       Could you please add some basic Javadoc comments for the class and the parameters of the annotation so that they might show up in IDEs ?

##########
File path: extensions/groovy-actions/rest/pom.xml
##########
@@ -0,0 +1,89 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+  ~ Licensed to the Apache Software Foundation (ASF) under one or more
+  ~ contributor license agreements.  See the NOTICE file distributed with
+  ~ this work for additional information regarding copyright ownership.
+  ~ The ASF licenses this file to You 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.
+  -->
+
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+    <parent>
+        <groupId>org.apache.unomi</groupId>
+        <artifactId>unomi-groovy-actions-root</artifactId>
+        <version>1.6.0-SNAPSHOT</version>
+    </parent>
+    <modelVersion>4.0.0</modelVersion>
+
+    <artifactId>unomi-groovy-actions-rest</artifactId>
+    <name>Apache Unomi :: Extensions :: Groovy Actions :: REST API</name>
+    <description>REST API for the Apache Unomi Context Server extension that integrates with groovy actions</description>
+    <packaging>bundle</packaging>
+
+    <dependencies>
+        <dependency>
+            <groupId>org.apache.unomi</groupId>
+            <artifactId>unomi-api</artifactId>
+            <version>${project.version}</version>
+            <scope>provided</scope>
+        </dependency>
+
+        <dependency>
+            <groupId>org.apache.unomi</groupId>
+            <artifactId>unomi-groovy-actions-services</artifactId>
+            <version>${project.version}</version>
+            <scope>provided</scope>
+        </dependency>
+
+        <dependency>
+            <groupId>javax.servlet</groupId>
+            <artifactId>javax.servlet-api</artifactId>
+            <scope>provided</scope>
+        </dependency>
+
+        <dependency>
+            <groupId>org.apache.cxf</groupId>
+            <artifactId>cxf-rt-frontend-jaxws</artifactId>
+            <scope>provided</scope>
+        </dependency>
+        <dependency>
+            <groupId>org.apache.cxf</groupId>
+            <artifactId>cxf-rt-frontend-jaxrs</artifactId>
+            <scope>provided</scope>
+        </dependency>
+        <dependency>
+            <groupId>org.apache.cxf</groupId>
+            <artifactId>cxf-rt-transports-http</artifactId>
+            <scope>provided</scope>
+        </dependency>
+        <dependency>
+            <groupId>org.apache.cxf</groupId>
+            <artifactId>cxf-rt-rs-security-cors</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>com.fasterxml.jackson.jaxrs</groupId>
+            <artifactId>jackson-jaxrs-json-provider</artifactId>

Review comment:
       Same here ? Provided ?

##########
File path: extensions/groovy-actions/services/src/main/java/org/apache/unomi/groovy/actions/GroovyAction.java
##########
@@ -0,0 +1,58 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You 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 org.apache.unomi.groovy.actions;
+
+import org.apache.unomi.api.Metadata;
+import org.apache.unomi.api.MetadataItem;
+
+/**
+ * Object which represents a grrovy action

Review comment:
       ```suggestion
    * Object which represents a Groovy action in persistence service
   ```

##########
File path: extensions/groovy-actions/services/src/main/java/org/apache/unomi/groovy/actions/GroovyActionDispatcher.java
##########
@@ -0,0 +1,86 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You 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 org.apache.unomi.groovy.actions;
+
+import groovy.lang.GroovyObject;
+import groovy.util.GroovyScriptEngine;
+import org.apache.unomi.api.Event;
+import org.apache.unomi.api.actions.Action;
+import org.apache.unomi.api.actions.ActionDispatcher;
+import org.apache.unomi.metrics.MetricAdapter;
+import org.apache.unomi.metrics.MetricsService;
+import org.apache.unomi.persistence.spi.PersistenceService;
+import org.osgi.framework.BundleContext;
+import org.osgi.framework.wiring.BundleWiring;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+/**
+ * An implementation of an ActionDispatcher for the Groovy language. This dispatcher will load the groovy action script matching to an 
+ * actionName. If a script if found, it will be executed.
+ */
+public class GroovyActionDispatcher implements ActionDispatcher {
+
+    private static final Logger logger = LoggerFactory.getLogger(GroovyActionDispatcher.class.getName());
+
+    private static final String GROOVY_PREFIX = "groovy";
+
+    private MetricsService metricsService;
+    private PersistenceService persistenceService;
+    private BundleContext bundleContext;
+
+    public void setMetricsService(MetricsService metricsService) {
+        this.metricsService = metricsService;
+    }
+
+    public void setPersistenceService(PersistenceService persistenceService) {
+        this.persistenceService = persistenceService;
+    }
+
+    public void setBundleContext(BundleContext bundleContext) {
+        this.bundleContext = bundleContext;
+    }
+
+    public String getPrefix() {
+        return GROOVY_PREFIX;
+    }
+
+    public Integer execute(Action action, Event event, String actionName) {
+        GroovyAction groovyScript = persistenceService.load(actionName, GroovyAction.class);

Review comment:
       Ideally we should have some kind of cache for the scripts, possibly in the GroovyActionService. 
   
   So we would instead do something like groovyActionService.getScript(actionName), and in the service manage the cache and reload from the service with a thread on a regular basis (since other cluster nodes could deploy groovy scripts), as is done in other service implementations.

##########
File path: extensions/groovy-actions/services/src/main/java/org/apache/unomi/groovy/actions/GroovyAction.java
##########
@@ -0,0 +1,58 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You 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 org.apache.unomi.groovy.actions;
+
+import org.apache.unomi.api.Metadata;
+import org.apache.unomi.api.MetadataItem;
+
+/**
+ * Object which represents a grrovy action

Review comment:
       ```suggestion
    * Object which represents a Groovy action
   ```

##########
File path: extensions/groovy-actions/services/src/main/java/org/apache/unomi/groovy/actions/annotations/Parameter.java
##########
@@ -0,0 +1,29 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You 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 org.apache.unomi.groovy.actions.annotations;
+
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+
+@Retention(RetentionPolicy.RUNTIME)
+public @interface Parameter {

Review comment:
       Same thing here, please add Javadoc to explain how to use this

##########
File path: extensions/groovy-actions/services/src/main/resources/META-INF/cxs/mappings/groovyAction.json
##########
@@ -0,0 +1,20 @@
+{
+  "dynamic_templates": [
+    {
+      "all": {
+        "match": "*",
+        "match_mapping_type": "string",
+        "mapping": {
+          "type": "text",
+          "analyzer": "folding",
+          "fields": {
+            "keyword": {
+              "type": "keyword",
+              "ignore_above": 256
+            }
+          }
+        }
+      }
+    }
+  ]

Review comment:
       Since this type will not change, I think it would be best to put the full mapping for it.

##########
File path: extensions/groovy-actions/rest/src/main/java/org/apache/unomi/groovy/actions/rest/GroovyActionsEndPoint.java
##########
@@ -0,0 +1,103 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You 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 org.apache.unomi.groovy.actions.rest;
+
+import org.apache.cxf.jaxrs.ext.multipart.Attachment;
+import org.apache.cxf.jaxrs.ext.multipart.Multipart;
+import org.apache.cxf.rs.security.cors.CrossOriginResourceSharing;
+import org.apache.unomi.groovy.actions.services.GroovyActionsService;
+import org.osgi.service.component.annotations.Component;
+import org.osgi.service.component.annotations.Reference;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import javax.jws.WebMethod;
+import javax.jws.WebService;
+import javax.ws.rs.Consumes;
+import javax.ws.rs.DELETE;
+import javax.ws.rs.POST;
+import javax.ws.rs.Path;
+import javax.ws.rs.PathParam;
+import javax.ws.rs.Produces;
+import javax.ws.rs.core.MediaType;
+import javax.ws.rs.core.Response;
+import java.io.File;
+import java.io.IOException;
+import java.io.InputStream;
+import java.nio.file.Files;
+import java.nio.file.Paths;
+
+@WebService
+@Produces(MediaType.APPLICATION_JSON + ";charset=UTF-8")
+@CrossOriginResourceSharing(allowAllOrigins = true, allowCredentials = true)
+@Path("/groovyActions")
+@Component(service = GroovyActionsEndPoint.class, property = "osgi.jaxrs.resource=true")
+public class GroovyActionsEndPoint {
+
+    private static final Logger logger = LoggerFactory.getLogger(GroovyActionsEndPoint.class.getName());
+
+    @Reference
+    private GroovyActionsService groovyActionsService;
+
+    public GroovyActionsEndPoint() {
+        logger.info("Initializing groovy actions service endpoint...");
+    }
+
+    @WebMethod(exclude = true)
+    public void setGroovyActionsService(GroovyActionsService groovyActionsService) {
+        this.groovyActionsService = groovyActionsService;
+    }
+
+    /**
+     * Save a groovy action file and create an actionType entry to allow to call this action
+     *
+     * @param file the file to save
+     * @return
+     */
+    @POST
+    @Path("/")
+    @Consumes(MediaType.MULTIPART_FORM_DATA)
+    @Produces(MediaType.APPLICATION_JSON)
+    public Response save(@Multipart(value = "file") Attachment file) {
+        try {
+            String filename = file.getContentDisposition().getParameter("filename");
+
+            java.nio.file.Path path = Paths.get("/tmp/" + filename);

Review comment:
       I don't think this way of retrieving the temporary directory is correct. Instead we should use something like this: https://attacomsian.com/blog/java-create-temporary-directory#:~:text=In%20Java%207%20and%20higher%2C%20you%20can%20use,and%20print%20its%20absolute%20path%20on%20the%20console. and create a "unomi-groovy-actions" directory to make sure we don't mess up the main temp directory.




-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: dev-unsubscribe@unomi.apache.org

For queries about this service, please contact Infrastructure at:
users@infra.apache.org



[GitHub] [unomi] sergehuber merged pull request #337: UNOMI-508 provide Unomi Groovy actions endpoint

Posted by GitBox <gi...@apache.org>.
sergehuber merged pull request #337:
URL: https://github.com/apache/unomi/pull/337


   


-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: dev-unsubscribe@unomi.apache.org

For queries about this service, please contact Infrastructure at:
users@infra.apache.org