Author: bdelacretaz
Date: Mon Jul 29 13:00:49 2013
New Revision: 1508040

URL: http://svn.apache.org/r1508040
Log:
SLING-2983 - scripted health check rules, including examples

Added:
    
sling/trunk/contrib/extensions/healthcheck/hc-rules/src/main/java/org/apache/sling/hc/rules/scriptable/
    
sling/trunk/contrib/extensions/healthcheck/hc-rules/src/main/java/org/apache/sling/hc/rules/scriptable/ScriptableRuleBuilder.java
    
sling/trunk/contrib/extensions/healthcheck/hc-rules/src/test/java/org/apache/sling/hc/rules/impl/ScriptableRuleBuilderTest.java
    
sling/trunk/contrib/extensions/healthcheck/sling-demo/src/main/resources/SLING-CONTENT/apps/hc/demo/scripted-ecma.json
    
sling/trunk/contrib/extensions/healthcheck/sling-demo/src/main/resources/SLING-CONTENT/apps/hc/demo/scripted-groovy.json
Modified:
    sling/trunk/contrib/extensions/healthcheck/hc-rules/pom.xml
    
sling/trunk/contrib/extensions/healthcheck/hc-rules/src/main/java/org/apache/sling/hc/rules/osgi/Activator.java

Modified: sling/trunk/contrib/extensions/healthcheck/hc-rules/pom.xml
URL: 
http://svn.apache.org/viewvc/sling/trunk/contrib/extensions/healthcheck/hc-rules/pom.xml?rev=1508040&r1=1508039&r2=1508040&view=diff
==============================================================================
--- sling/trunk/contrib/extensions/healthcheck/hc-rules/pom.xml (original)
+++ sling/trunk/contrib/extensions/healthcheck/hc-rules/pom.xml Mon Jul 29 
13:00:49 2013
@@ -50,6 +50,17 @@
                     <target>1.6</target>
                 </configuration>
             </plugin>
+           <plugin>
+              <groupId>org.codehaus.mojo</groupId>
+              <artifactId>animal-sniffer-maven-plugin</artifactId>
+              <configuration>
+                <signature>
+                  <groupId>org.codehaus.mojo.signature</groupId>
+                  <artifactId>java16</artifactId>
+                  <version>1.0</version>
+                </signature>
+              </configuration>
+            </plugin>
         </plugins>
     </build>
 
@@ -88,5 +99,11 @@
             <version>4.8.1</version>
             <scope>test</scope>
         </dependency>
+        <dependency>
+            <groupId>org.mockito</groupId>
+            <artifactId>mockito-core</artifactId>
+            <version>1.9.5</version>
+            <scope>test</scope>
+        </dependency>
      </dependencies>
 </project>

Modified: 
sling/trunk/contrib/extensions/healthcheck/hc-rules/src/main/java/org/apache/sling/hc/rules/osgi/Activator.java
URL: 
http://svn.apache.org/viewvc/sling/trunk/contrib/extensions/healthcheck/hc-rules/src/main/java/org/apache/sling/hc/rules/osgi/Activator.java?rev=1508040&r1=1508039&r2=1508040&view=diff
==============================================================================
--- 
sling/trunk/contrib/extensions/healthcheck/hc-rules/src/main/java/org/apache/sling/hc/rules/osgi/Activator.java
 (original)
+++ 
sling/trunk/contrib/extensions/healthcheck/hc-rules/src/main/java/org/apache/sling/hc/rules/osgi/Activator.java
 Mon Jul 29 13:00:49 2013
@@ -22,6 +22,7 @@ import java.util.List;
 
 import org.apache.sling.hc.api.RuleBuilder;
 import org.apache.sling.hc.rules.jmx.JmxBeansRuleBuilder;
+import org.apache.sling.hc.rules.scriptable.ScriptableRuleBuilder;
 import org.osgi.framework.BundleActivator;
 import org.osgi.framework.BundleContext;
 import org.osgi.framework.ServiceRegistration;
@@ -34,6 +35,7 @@ public class Activator implements Bundle
         regs = new ArrayList<ServiceRegistration>();
         regs.add(ctx.registerService(RuleBuilder.class.getName(), new 
BundlesRuleBuilder(ctx), null));
         regs.add(ctx.registerService(RuleBuilder.class.getName(), new 
JmxBeansRuleBuilder(), null));
+        regs.add(ctx.registerService(RuleBuilder.class.getName(), new 
ScriptableRuleBuilder(ctx), null));
     }
 
     public void stop(BundleContext ctx) throws Exception {

Added: 
sling/trunk/contrib/extensions/healthcheck/hc-rules/src/main/java/org/apache/sling/hc/rules/scriptable/ScriptableRuleBuilder.java
URL: 
http://svn.apache.org/viewvc/sling/trunk/contrib/extensions/healthcheck/hc-rules/src/main/java/org/apache/sling/hc/rules/scriptable/ScriptableRuleBuilder.java?rev=1508040&view=auto
==============================================================================
--- 
sling/trunk/contrib/extensions/healthcheck/hc-rules/src/main/java/org/apache/sling/hc/rules/scriptable/ScriptableRuleBuilder.java
 (added)
+++ 
sling/trunk/contrib/extensions/healthcheck/hc-rules/src/main/java/org/apache/sling/hc/rules/scriptable/ScriptableRuleBuilder.java
 Mon Jul 29 13:00:49 2013
@@ -0,0 +1,125 @@
+/*
+ * 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 SF 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.sling.hc.rules.scriptable;
+
+import javax.script.ScriptEngine;
+import javax.script.ScriptEngineManager;
+import javax.script.ScriptException;
+
+import org.apache.sling.hc.api.Evaluator;
+import org.apache.sling.hc.api.Rule;
+import org.apache.sling.hc.api.RuleBuilder;
+import org.apache.sling.hc.api.SystemAttribute;
+import org.osgi.framework.BundleContext;
+import org.osgi.framework.ServiceReference;
+import org.slf4j.Logger;
+
+/** RuleBuilder that builds scriptable rules. The qualifier
+ *  indicates the scripting language extension (defaults to ecma) and
+ *  the expression must evaluate to true.
+ *  The rule name is only used for information, it is not used
+ *  in building the rule.
+ */
+public class ScriptableRuleBuilder implements RuleBuilder {
+
+    public static final String NAMESPACE = "script";
+    private final BundleContext ctx;
+    
+    static private class ScriptedAttribute implements SystemAttribute {
+
+        public static final String DEFAULT_LANGUAGE_EXTENSION = "ecma";
+        
+        private final String extension;
+        private final String expression;
+        private final String name;
+        private final ScriptEngine scriptEngine;
+        private final String scriptEngineMsg;
+        
+        ScriptedAttribute(BundleContext ctx, String name, String qualifier, 
String expression) {
+            this.extension = qualifier == null || qualifier.length() == 0 ? 
DEFAULT_LANGUAGE_EXTENSION : qualifier;
+            this.expression = expression;
+            this.name = name;
+            
+            // Get a ScriptEngine for our language extension
+            final ServiceReference r = 
ctx.getServiceReference(ScriptEngineManager.class.getName());
+            if(r != null) {
+                final ScriptEngineManager m = 
(ScriptEngineManager)ctx.getService(r);
+                scriptEngine = m.getEngineByExtension(extension);
+                if(scriptEngine == null) {
+                    scriptEngineMsg = "ScriptEngine not found for extension '" 
+ extension + "'";
+                } else {
+                    scriptEngineMsg = null;
+                }
+            } else {
+                scriptEngine = null;
+                scriptEngineMsg = "No ScriptEngineManager service available";
+            }
+            
+        }
+        
+        @Override
+        public String toString() {
+            return NAMESPACE + ":" + extension + ":" + name;
+        }
+        
+        @Override
+        public Object getValue(Logger logger) {
+            if(scriptEngineMsg != null) {
+                logger.error("Cannot evaluate: {}", scriptEngineMsg);
+            } else {
+                try {
+                    return scriptEngine.eval(expression);
+                } catch(ScriptException e) {
+                    logger.error("Script evaluation error (" + expression + 
")", e);
+                }
+            }
+            return null;
+        }
+    }
+    
+    static private class ExpectTrueEvaluator implements Evaluator {
+        @Override
+        public void evaluate(SystemAttribute a, String expression, Logger 
logger) {
+            final Object value = a.getValue(logger);
+            if(a instanceof ScriptedAttribute) {
+                final ScriptedAttribute sa = (ScriptedAttribute)a;
+                logger.debug("({}) [{}] is [{}]", new Object[] { sa.extension, 
sa.expression, value });
+            }
+            if(value == null) {
+                logger.error("Got null value from {}", a);
+            } else if(!Boolean.TRUE.equals(value) && 
!"true".equals(value.toString())) {
+                logger.warn("Expected 'true' value, got '{}' from '{}'", 
value, a);
+            } else {
+                logger.debug("Got value '{}' from '{}'", value, a);
+            }
+        }
+    }
+    
+    public ScriptableRuleBuilder(BundleContext ctx) {
+        this.ctx = ctx;
+    }
+    
+    @Override
+    public Rule buildRule(String namespace, String ruleName, final String 
qualifier, String expression) {
+        if(!NAMESPACE.equals(namespace)) {
+            return null;
+        }
+        
+        return new Rule(new ScriptedAttribute(ctx, ruleName,qualifier, 
expression), expression, new ExpectTrueEvaluator());
+    }
+}
\ No newline at end of file

Added: 
sling/trunk/contrib/extensions/healthcheck/hc-rules/src/test/java/org/apache/sling/hc/rules/impl/ScriptableRuleBuilderTest.java
URL: 
http://svn.apache.org/viewvc/sling/trunk/contrib/extensions/healthcheck/hc-rules/src/test/java/org/apache/sling/hc/rules/impl/ScriptableRuleBuilderTest.java?rev=1508040&view=auto
==============================================================================
--- 
sling/trunk/contrib/extensions/healthcheck/hc-rules/src/test/java/org/apache/sling/hc/rules/impl/ScriptableRuleBuilderTest.java
 (added)
+++ 
sling/trunk/contrib/extensions/healthcheck/hc-rules/src/test/java/org/apache/sling/hc/rules/impl/ScriptableRuleBuilderTest.java
 Mon Jul 29 13:00:49 2013
@@ -0,0 +1,99 @@
+/*
+ * 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 SF 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.sling.hc.rules.impl;
+
+import static org.junit.Assert.assertTrue;
+import static org.junit.Assert.assertFalse;
+
+import javax.script.ScriptEngine;
+import javax.script.ScriptEngineManager;
+import javax.script.ScriptException;
+
+import org.apache.sling.hc.api.Rule;
+import org.apache.sling.hc.api.RuleBuilder;
+import org.apache.sling.hc.rules.scriptable.ScriptableRuleBuilder;
+import org.junit.Before;
+import org.junit.Test;
+import org.mockito.Matchers;
+import org.mockito.Mockito;
+import org.osgi.framework.BundleContext;
+import org.osgi.framework.ServiceReference;
+
+public class ScriptableRuleBuilderTest {
+    private RuleBuilder builder;
+    private ServiceReference serviceReference;
+    private ScriptEngineManager scriptEngineManager; 
+    private ScriptEngine scriptEngine; 
+    
+    public static final String EXT = "test_ext";
+    public static final String CODE = "this is the test code";
+    public static final String NAME = "The rule name";
+    
+    @Before
+    public void setup() throws ScriptException {
+        setupScriptEngine(false);
+    }
+    
+    private void setupScriptEngine(boolean active) throws ScriptException {
+        final BundleContext ctx = Mockito.mock(BundleContext.class);
+        builder = new ScriptableRuleBuilder(ctx);
+        
+        if(!active) {
+            scriptEngineManager = null;
+            serviceReference = null;
+            scriptEngine = null;
+        } else {
+            serviceReference = Mockito.mock(ServiceReference.class);
+            
+            scriptEngine = Mockito.mock(ScriptEngine.class);
+            
Mockito.when(scriptEngine.eval(Matchers.same(CODE))).thenReturn("true");
+            
+            scriptEngineManager = Mockito.mock(ScriptEngineManager.class);
+            Mockito.when(
+                    
scriptEngineManager.getEngineByExtension(Matchers.same(EXT)))
+                    .thenReturn(scriptEngine);
+        }
+        
+        Mockito.when(
+                
ctx.getServiceReference(Matchers.same(ScriptEngineManager.class.getName())))
+                .thenReturn(serviceReference);
+        Mockito.when(
+                ctx.getService(Matchers.same(serviceReference)))
+                .thenReturn(scriptEngineManager);
+    }
+    
+    @Test
+    public void testNoServiceReference() {
+        final Rule r = builder.buildRule(ScriptableRuleBuilder.NAMESPACE, 
NAME, EXT, CODE);
+        assertTrue(r.evaluate().anythingToReport());
+    }
+    
+    @Test
+    public void testNoScriptEngine() throws ScriptException {
+        setupScriptEngine(true);
+        final Rule r = builder.buildRule(ScriptableRuleBuilder.NAMESPACE, 
NAME, "bad_extension", CODE);
+        assertTrue(r.evaluate().anythingToReport());
+    }
+    
+    @Test
+    public void testGoodScript() throws ScriptException {
+        setupScriptEngine(true);
+        final Rule r = builder.buildRule(ScriptableRuleBuilder.NAMESPACE, 
NAME, EXT, CODE);
+        assertFalse(r.evaluate().anythingToReport());
+    }    
+}
\ No newline at end of file

Added: 
sling/trunk/contrib/extensions/healthcheck/sling-demo/src/main/resources/SLING-CONTENT/apps/hc/demo/scripted-ecma.json
URL: 
http://svn.apache.org/viewvc/sling/trunk/contrib/extensions/healthcheck/sling-demo/src/main/resources/SLING-CONTENT/apps/hc/demo/scripted-ecma.json?rev=1508040&view=auto
==============================================================================
--- 
sling/trunk/contrib/extensions/healthcheck/sling-demo/src/main/resources/SLING-CONTENT/apps/hc/demo/scripted-ecma.json
 (added)
+++ 
sling/trunk/contrib/extensions/healthcheck/sling-demo/src/main/resources/SLING-CONTENT/apps/hc/demo/scripted-ecma.json
 Mon Jul 29 13:00:49 2013
@@ -0,0 +1,9 @@
+{
+  "sling:resourceType" : "sling/healthcheck/rules",
+  "namespace": "script",
+  "ruleName": "Test javascript (ecma) rule",
+  "qualifier": "ecma",
+  "expression": "Math.round(2.6) == 3",
+  "tags" : ["script","javascript"],
+  "jcr:primaryType": "nt:unstructured"
+}
\ No newline at end of file

Added: 
sling/trunk/contrib/extensions/healthcheck/sling-demo/src/main/resources/SLING-CONTENT/apps/hc/demo/scripted-groovy.json
URL: 
http://svn.apache.org/viewvc/sling/trunk/contrib/extensions/healthcheck/sling-demo/src/main/resources/SLING-CONTENT/apps/hc/demo/scripted-groovy.json?rev=1508040&view=auto
==============================================================================
--- 
sling/trunk/contrib/extensions/healthcheck/sling-demo/src/main/resources/SLING-CONTENT/apps/hc/demo/scripted-groovy.json
 (added)
+++ 
sling/trunk/contrib/extensions/healthcheck/sling-demo/src/main/resources/SLING-CONTENT/apps/hc/demo/scripted-groovy.json
 Mon Jul 29 13:00:49 2013
@@ -0,0 +1,9 @@
+{
+  "sling:resourceType" : "sling/healthcheck/rules",
+  "namespace": "script",
+  "ruleName": "Test Groovy rule",
+  "qualifier": "groovy",
+  "expression": "karre = { it * it } ; [ 1, 2, 3, 4 ].collect(karre)[2] == 9",
+  "tags" : ["script","groovy"],
+  "jcr:primaryType": "nt:unstructured"
+}
\ No newline at end of file


Reply via email to