Author: ghenzler
Date: Fri Jan 25 21:22:55 2019
New Revision: 1852182

URL: http://svn.apache.org/viewvc?rev=1852182&view=rev
Log:
FELIX-6025 ScriptedHealthCheck - refactoring to allow reuse in sling

Added:
    
felix/trunk/healthcheck/generalchecks/src/main/java/org/apache/felix/hc/generalchecks/util/ScriptHelper.java
   (with props)
    
felix/trunk/healthcheck/generalchecks/src/main/java/org/apache/felix/hc/generalchecks/util/package-info.java
   (with props)
Modified:
    felix/trunk/healthcheck/generalchecks/bnd.bnd
    felix/trunk/healthcheck/generalchecks/pom.xml
    
felix/trunk/healthcheck/generalchecks/src/main/java/org/apache/felix/hc/generalchecks/ScriptedHealthCheck.java

Modified: felix/trunk/healthcheck/generalchecks/bnd.bnd
URL: 
http://svn.apache.org/viewvc/felix/trunk/healthcheck/generalchecks/bnd.bnd?rev=1852182&r1=1852181&r2=1852182&view=diff
==============================================================================
--- felix/trunk/healthcheck/generalchecks/bnd.bnd (original)
+++ felix/trunk/healthcheck/generalchecks/bnd.bnd Fri Jan 25 21:22:55 2019
@@ -9,3 +9,5 @@ Bundle-License: Apache License, Version
 Bundle-Vendor: The Apache Software Foundation
 
 Conditional-Package: org.apache.commons.cli.*,org.apache.felix.utils.*
+
+Export-Package: org.apache.felix.hc.generalchecks.util

Modified: felix/trunk/healthcheck/generalchecks/pom.xml
URL: 
http://svn.apache.org/viewvc/felix/trunk/healthcheck/generalchecks/pom.xml?rev=1852182&r1=1852181&r2=1852182&view=diff
==============================================================================
--- felix/trunk/healthcheck/generalchecks/pom.xml (original)
+++ felix/trunk/healthcheck/generalchecks/pom.xml Fri Jan 25 21:22:55 2019
@@ -95,6 +95,12 @@
             <version>6.0.0</version>
             <scope>provided</scope>
         </dependency>
+        <dependency>
+            <groupId>org.osgi</groupId>
+            <artifactId>osgi.annotation</artifactId>
+            <version>6.0.1</version>
+            <scope>provided</scope>
+        </dependency>
 
         <dependency>
             <groupId>org.apache.felix</groupId>

Modified: 
felix/trunk/healthcheck/generalchecks/src/main/java/org/apache/felix/hc/generalchecks/ScriptedHealthCheck.java
URL: 
http://svn.apache.org/viewvc/felix/trunk/healthcheck/generalchecks/src/main/java/org/apache/felix/hc/generalchecks/ScriptedHealthCheck.java?rev=1852182&r1=1852181&r2=1852182&view=diff
==============================================================================
--- 
felix/trunk/healthcheck/generalchecks/src/main/java/org/apache/felix/hc/generalchecks/ScriptedHealthCheck.java
 (original)
+++ 
felix/trunk/healthcheck/generalchecks/src/main/java/org/apache/felix/hc/generalchecks/ScriptedHealthCheck.java
 Fri Jan 25 21:22:55 2019
@@ -17,36 +17,15 @@
  */
 package org.apache.felix.hc.generalchecks;
 
-import java.io.BufferedReader;
-import java.io.IOException;
-import java.io.InputStreamReader;
-import java.io.StringWriter;
-import java.lang.reflect.Array;
-import java.net.URL;
-import java.net.URLConnection;
-import java.nio.charset.StandardCharsets;
-import java.util.ArrayList;
-import java.util.HashMap;
-import java.util.Iterator;
-import java.util.List;
-import java.util.Map;
-import java.util.stream.Collectors;
-
-import javax.script.Bindings;
-import javax.script.ScriptContext;
 import javax.script.ScriptEngine;
-import javax.script.SimpleBindings;
-import javax.script.SimpleScriptContext;
 
 import org.apache.commons.lang3.StringUtils;
 import org.apache.felix.hc.api.FormattingResultLog;
 import org.apache.felix.hc.api.HealthCheck;
 import org.apache.felix.hc.api.Result;
-import org.apache.felix.hc.api.ResultLog;
 import org.apache.felix.hc.generalchecks.util.ScriptEnginesTracker;
+import org.apache.felix.hc.generalchecks.util.ScriptHelper;
 import org.osgi.framework.BundleContext;
-import org.osgi.framework.InvalidSyntaxException;
-import org.osgi.framework.ServiceReference;
 import org.osgi.service.component.annotations.Activate;
 import org.osgi.service.component.annotations.Component;
 import org.osgi.service.component.annotations.ConfigurationPolicy;
@@ -67,11 +46,11 @@ public class ScriptedHealthCheck impleme
     public static final String HC_LABEL = "Health Check: Script";
 
     @ObjectClassDefinition(name = HC_LABEL, description = "Runs an arbitrary 
script in given scriping language (via javax.script). "
-            + "The script has the following default bindings available: 'log', 
'osgi' and 'bundleContext'. "
+            + "The script has the following default bindings available: 'log', 
'scriptHelper' and 'bundleContext'. "
             + "'log' is an instance of 
org.apache.felix.hc.api.FormattingResultLog and is used to define the result of 
the HC. "
-            + "'osgi.getService(classObj)' can be used as shortcut to retrieve 
a service."
-            + "'osgi.getServices(classObj, filter)' used to retrieve multiple 
services for a class using given filter. "
-            + "For all services retrieved via osgi binding, unget() is called 
automatically at the end of the script execution."
+            + "'scriptHelper.getService(classObj)' can be used as shortcut to 
retrieve a service."
+            + "'scriptHelper.getServices(classObj, filter)' used to retrieve 
multiple services for a class using given filter. "
+            + "For all services retrieved via scriptHelper, unget() is called 
automatically at the end of the script execution."
             + "'bundleContext' is available for advanced use cases. The script 
does not need to return any value, but if it does and it is "
             + "a org.apache.felix.hc.api.Result, that result and entries in 
'log' are combined then).")
     @interface Config {
@@ -104,6 +83,8 @@ public class ScriptedHealthCheck impleme
     @Reference
     private ScriptEnginesTracker scriptEnginesTracker;
 
+    private ScriptHelper scriptHelper = new ScriptHelper();
+
     @Activate
     protected void activate(BundleContext context, Config config) {
         this.bundleContext = context;
@@ -124,153 +105,20 @@ public class ScriptedHealthCheck impleme
     public Result execute() {
         FormattingResultLog log = new FormattingResultLog();
         
-        ScriptEngine scriptEngine = 
scriptEnginesTracker.getEngineByLanguage(language);
-        if(scriptEngine == null) {
-            log.healthCheckError("No ScriptEngineFactory found for language "+ 
language + " (available languages: 
"+scriptEnginesTracker.getLanguagesByBundle()+")");
-            return new Result(log);
-        }
         
-        final Bindings bindings = new SimpleBindings();
-        final ScriptHelper osgi = new ScriptHelper(bundleContext);
-
-        StringWriter stdout = new StringWriter();
-        StringWriter stderr = new StringWriter();
-
-        bindings.put("osgi", osgi);
-        bindings.put("log", log);
-        bindings.put("bundleContext", bundleContext);
-
-        SimpleScriptContext scriptContext = new SimpleScriptContext();
-        scriptContext.setBindings(bindings, ScriptContext.ENGINE_SCOPE);
-        scriptContext.setWriter(stdout);
-        scriptContext.setErrorWriter(stderr);
+        boolean urlIsUsed = StringUtils.isBlank(script);
+        String scriptToExecute = urlIsUsed ? 
scriptHelper.getFileContents(scriptUrl): script;
+        log.info("Executing script {} ({} lines)...", (urlIsUsed?scriptUrl:" 
as configured"), scriptToExecute.split("\n").length);
 
         try {
-            boolean urlIsUsed = StringUtils.isBlank(script);
-            String scriptToExecute = urlIsUsed ? getFileContents(scriptUrl): 
script;
-            log.info("Executing script {} ({} lines)...", 
(urlIsUsed?scriptUrl:" as configured"), scriptToExecute.split("\n").length);
-            log.debug(scriptToExecute);
-            Object scriptResult = scriptEngine.eval(scriptToExecute, 
scriptContext);
-            appendStreamsToResult(log, stdout, stderr, scriptContext);
-            
-            if(scriptResult instanceof Result) {
-                Result result = (Result) scriptResult;
-                for(ResultLog.Entry entry: result) {
-                    log.add(entry);
-                }
-            } else if(scriptResult != null){
-                log.info("Script result: {}", scriptResult);
-            }
-            
-            
+            ScriptEngine scriptEngine = 
scriptHelper.getScriptEngine(scriptEnginesTracker, language);
+            scriptHelper.evalScript(bundleContext, scriptEngine, 
scriptToExecute, log, null, true);
         }  catch (Exception e) {
-            log.healthCheckError("Exception during script execution: "+e, e);
-        } finally  {
-            osgi.ungetServices();
+            log.healthCheckError("Exception while executing script: "+e, e);
         }
 
         return new Result(log);
     }
 
-    private void appendStreamsToResult(FormattingResultLog log, StringWriter 
stdout, StringWriter stderr, SimpleScriptContext scriptContext)
-            throws IOException {
-        scriptContext.getWriter().flush();
-        String stdoutStr = stdout.toString();
-        if(StringUtils.isNotBlank(stdoutStr)) {
-            log.info("stdout of script: {}", stdoutStr);
-        }
-        
-        scriptContext.getErrorWriter().flush();
-        String stderrStr = stderr.toString();
-        if(StringUtils.isNotBlank(stderrStr)) {
-            log.critical("stderr of script: {}", stderrStr);
-        }
-    }
-    
-    public String getFileContents(String url) {
-        String content;
-        try {
-            URLConnection conn = new URL(url).openConnection();
-            try (BufferedReader reader = new BufferedReader(new 
InputStreamReader(conn.getInputStream(), StandardCharsets.UTF_8))) {
-                content = reader.lines().collect(Collectors.joining("\n"));
-            }
-            return content;
-        }catch(IOException e) {
-            throw new IllegalArgumentException("Could not read URL "+url+": 
"+e, e);
-        }
-    }
-
-    // Script Helper for OSGi available as binding 'osgi'
-    class ScriptHelper {
-        
-        private final BundleContext bundleContext;
-        private List<ServiceReference<?>> references;
-        private Map<String, Object> services;
-
-        public ScriptHelper(BundleContext bundleContext) {
-            this.bundleContext = bundleContext;
-        }
-
-        @SuppressWarnings("unchecked")
-        public <ServiceType> ServiceType getService(Class<ServiceType> type) {
-            ServiceType service = (this.services == null ? null  : 
(ServiceType) this.services.get(type.getName()));
-            if (service == null) {
-                final ServiceReference<?> ref = 
this.bundleContext.getServiceReference(type.getName());
-                if (ref != null) {
-                    service = (ServiceType) this.bundleContext.getService(ref);
-                    if (service != null) {
-                        if (this.services == null) {
-                            this.services = new HashMap<String, Object>();
-                        }
-                        if (this.references == null) {
-                            this.references = new 
ArrayList<ServiceReference<?>>();
-                        }
-                        this.references.add(ref);
-                        this.services.put(type.getName(), service);
-                    }
-                }
-            }
-            return service;
-        }
-
-        public <T> T[] getServices(Class<T> serviceType,  String filter) 
throws InvalidSyntaxException {
-            final ServiceReference<?>[] refs = 
this.bundleContext.getServiceReferences(serviceType.getName(), filter);
-            T[] result = null;
-            if (refs != null) {
-                final List<T> objects = new ArrayList<T>();
-                for (int i = 0; i < refs.length; i++) {
-                    @SuppressWarnings("unchecked")
-                    final T service = (T) 
this.bundleContext.getService(refs[i]);
-                    if (service != null) {
-                        if (this.references == null) {
-                            this.references = new 
ArrayList<ServiceReference<?>>();
-                        }
-                        this.references.add(refs[i]);
-                        objects.add(service);
-                    }
-                }
-                if (objects.size() > 0) {
-                    @SuppressWarnings("unchecked")
-                    T[] srv = (T[]) Array.newInstance(serviceType,  
objects.size());
-                    result = objects.toArray(srv);
-                }
-            }
-            return result;
-        }
 
-        public void ungetServices() {
-            if (this.references != null) {
-                final Iterator<ServiceReference<?>> i = 
this.references.iterator();
-                while (i.hasNext()) {
-                    final ServiceReference<?> ref = i.next();
-                    this.bundleContext.ungetService(ref);
-                }
-                this.references.clear();
-            }
-            if (this.services != null) {
-                this.services.clear();
-            }
-        }
-    }
-    
 }

Added: 
felix/trunk/healthcheck/generalchecks/src/main/java/org/apache/felix/hc/generalchecks/util/ScriptHelper.java
URL: 
http://svn.apache.org/viewvc/felix/trunk/healthcheck/generalchecks/src/main/java/org/apache/felix/hc/generalchecks/util/ScriptHelper.java?rev=1852182&view=auto
==============================================================================
--- 
felix/trunk/healthcheck/generalchecks/src/main/java/org/apache/felix/hc/generalchecks/util/ScriptHelper.java
 (added)
+++ 
felix/trunk/healthcheck/generalchecks/src/main/java/org/apache/felix/hc/generalchecks/util/ScriptHelper.java
 Fri Jan 25 21:22:55 2019
@@ -0,0 +1,207 @@
+/*
+ * 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.felix.hc.generalchecks.util;
+
+import java.io.BufferedReader;
+import java.io.IOException;
+import java.io.InputStreamReader;
+import java.io.StringWriter;
+import java.lang.reflect.Array;
+import java.net.URL;
+import java.net.URLConnection;
+import java.nio.charset.StandardCharsets;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Map;
+import java.util.stream.Collectors;
+
+import javax.script.Bindings;
+import javax.script.ScriptContext;
+import javax.script.ScriptEngine;
+import javax.script.ScriptException;
+import javax.script.SimpleBindings;
+import javax.script.SimpleScriptContext;
+
+import org.apache.commons.lang3.StringUtils;
+import org.apache.felix.hc.api.FormattingResultLog;
+import org.apache.felix.hc.api.Result;
+import org.apache.felix.hc.api.ResultLog;
+import org.osgi.framework.BundleContext;
+import org.osgi.framework.InvalidSyntaxException;
+import org.osgi.framework.ServiceReference;
+
+/** Script Helper to interact with . */
+public class ScriptHelper {
+
+    public String getFileContents(String url) {
+        String content;
+        try {
+            URLConnection conn = new URL(url).openConnection();
+            try (BufferedReader reader = new BufferedReader(new 
InputStreamReader(conn.getInputStream(), StandardCharsets.UTF_8))) {
+                content = reader.lines().collect(Collectors.joining("\n"));
+            }
+            return content;
+        }catch(IOException e) {
+            throw new IllegalArgumentException("Could not read URL "+url+": 
"+e, e);
+        }
+    }
+    
+    public ScriptEngine getScriptEngine(ScriptEnginesTracker 
scriptEnginesTracker, String language) {
+        ScriptEngine scriptEngine = 
scriptEnginesTracker.getEngineByLanguage(language);
+        if(scriptEngine == null) {
+            throw new IllegalArgumentException("No ScriptEngineFactory found 
for language "+ language + " (available languages: 
"+scriptEnginesTracker.getLanguagesByBundle()+")");
+        }
+        return scriptEngine;
+    }
+    
+    public Object evalScript(BundleContext bundleContext, ScriptEngine 
scriptEngine, String scriptToExecute, FormattingResultLog log, 
Map<String,Object> additionalBindings, boolean logScriptResult) throws 
ScriptException, IOException {
+
+        final Bindings bindings = new SimpleBindings();
+        final ScriptHelperBinding scriptHelper = new 
ScriptHelperBinding(bundleContext);
+
+        StringWriter stdout = new StringWriter();
+        StringWriter stderr = new StringWriter();
+
+        bindings.put("scriptHelper", scriptHelper);
+        bindings.put("osgi", scriptHelper); // also register script helper 
like in web console script console
+        bindings.put("log", log);
+        bindings.put("bundleContext", bundleContext);
+        if (additionalBindings != null) {
+            for (Map.Entry<String, Object> additionalBinding : 
additionalBindings.entrySet()) {
+                bindings.put(additionalBinding.getKey(), 
additionalBinding.getValue());
+            }
+        }
+        
+        SimpleScriptContext scriptContext = new SimpleScriptContext();
+        scriptContext.setBindings(bindings, ScriptContext.ENGINE_SCOPE);
+        scriptContext.setWriter(stdout);
+        scriptContext.setErrorWriter(stderr);
+
+        try {
+            log.debug(scriptToExecute);
+            Object scriptResult = scriptEngine.eval(scriptToExecute, 
scriptContext);
+            appendStreamsToResult(log, stdout, stderr, scriptContext);
+
+            if(scriptResult instanceof Result) {
+                Result result = (Result) scriptResult;
+                for(ResultLog.Entry entry: result) {
+                    log.add(entry);
+                }
+            } else if(scriptResult != null && logScriptResult){
+                log.info("Script result: {}", scriptResult);
+            }
+            
+            return scriptResult;
+        } finally  {
+            scriptHelper.ungetServices();
+        }
+    }
+
+    
+    
+    private void appendStreamsToResult(FormattingResultLog log, StringWriter 
stdout, StringWriter stderr, SimpleScriptContext scriptContext)
+            throws IOException {
+        scriptContext.getWriter().flush();
+        String stdoutStr = stdout.toString();
+        if(StringUtils.isNotBlank(stdoutStr)) {
+            log.info("stdout of script: {}", stdoutStr);
+        }
+        
+        scriptContext.getErrorWriter().flush();
+        String stderrStr = stderr.toString();
+        if(StringUtils.isNotBlank(stderrStr)) {
+            log.critical("stderr of script: {}", stderrStr);
+        }
+    }
+
+    // Script Helper for OSGi available as binding 'scriptHelper'
+    class ScriptHelperBinding {
+        
+        private final BundleContext bundleContext;
+        private List<ServiceReference<?>> references;
+        private Map<String, Object> services;
+
+        public ScriptHelperBinding(BundleContext bundleContext) {
+            this.bundleContext = bundleContext;
+        }
+
+        @SuppressWarnings("unchecked")
+        public <ServiceType> ServiceType getService(Class<ServiceType> type) {
+            ServiceType service = (this.services == null ? null  : 
(ServiceType) this.services.get(type.getName()));
+            if (service == null) {
+                final ServiceReference<?> ref = 
this.bundleContext.getServiceReference(type.getName());
+                if (ref != null) {
+                    service = (ServiceType) this.bundleContext.getService(ref);
+                    if (service != null) {
+                        if (this.services == null) {
+                            this.services = new HashMap<String, Object>();
+                        }
+                        if (this.references == null) {
+                            this.references = new 
ArrayList<ServiceReference<?>>();
+                        }
+                        this.references.add(ref);
+                        this.services.put(type.getName(), service);
+                    }
+                }
+            }
+            return service;
+        }
+
+        public <T> T[] getServices(Class<T> serviceType,  String filter) 
throws InvalidSyntaxException {
+            final ServiceReference<?>[] refs = 
this.bundleContext.getServiceReferences(serviceType.getName(), filter);
+            T[] result = null;
+            if (refs != null) {
+                final List<T> objects = new ArrayList<T>();
+                for (int i = 0; i < refs.length; i++) {
+                    @SuppressWarnings("unchecked")
+                    final T service = (T) 
this.bundleContext.getService(refs[i]);
+                    if (service != null) {
+                        if (this.references == null) {
+                            this.references = new 
ArrayList<ServiceReference<?>>();
+                        }
+                        this.references.add(refs[i]);
+                        objects.add(service);
+                    }
+                }
+                if (objects.size() > 0) {
+                    @SuppressWarnings("unchecked")
+                    T[] srv = (T[]) Array.newInstance(serviceType,  
objects.size());
+                    result = objects.toArray(srv);
+                }
+            }
+            return result;
+        }
+
+        public void ungetServices() {
+            if (this.references != null) {
+                final Iterator<ServiceReference<?>> i = 
this.references.iterator();
+                while (i.hasNext()) {
+                    final ServiceReference<?> ref = i.next();
+                    this.bundleContext.ungetService(ref);
+                }
+                this.references.clear();
+            }
+            if (this.services != null) {
+                this.services.clear();
+            }
+        }
+    }
+    
+}

Propchange: 
felix/trunk/healthcheck/generalchecks/src/main/java/org/apache/felix/hc/generalchecks/util/ScriptHelper.java
------------------------------------------------------------------------------
    svn:mime-type = text/plain

Added: 
felix/trunk/healthcheck/generalchecks/src/main/java/org/apache/felix/hc/generalchecks/util/package-info.java
URL: 
http://svn.apache.org/viewvc/felix/trunk/healthcheck/generalchecks/src/main/java/org/apache/felix/hc/generalchecks/util/package-info.java?rev=1852182&view=auto
==============================================================================
--- 
felix/trunk/healthcheck/generalchecks/src/main/java/org/apache/felix/hc/generalchecks/util/package-info.java
 (added)
+++ 
felix/trunk/healthcheck/generalchecks/src/main/java/org/apache/felix/hc/generalchecks/util/package-info.java
 Fri Jan 25 21:22:55 2019
@@ -0,0 +1,23 @@
+/*
+ * 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.
+ */
+
+@Version("2.0.0")
+package org.apache.felix.hc.generalchecks.util;
+
+import org.osgi.annotation.versioning.Version;

Propchange: 
felix/trunk/healthcheck/generalchecks/src/main/java/org/apache/felix/hc/generalchecks/util/package-info.java
------------------------------------------------------------------------------
    svn:mime-type = text/plain


Reply via email to