This is an automated email from the ASF dual-hosted git repository.

bdelacretaz pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/sling-whiteboard.git


The following commit(s) were added to refs/heads/master by this push:
     new caa59ba  Redesign with ProbeBuilder
caa59ba is described below

commit caa59ba81943a9ab73ae9179ccd736ef7878828f
Author: Bertrand Delacretaz <[email protected]>
AuthorDate: Thu May 24 16:28:08 2018 +0200

    Redesign with ProbeBuilder
---
 capabilities/README.md                             | 46 +++++++++++++
 capabilities/README.txt                            | 12 ----
 capabilities/pom.xml                               |  2 +-
 .../sling/capabilities/{internal => }/Probe.java   | 22 +++++-
 .../ScriptProbe.java => ProbeBuilder.java}         | 46 ++++++-------
 .../capabilities/internal/CapabilitiesServlet.java | 64 +++++++++++++-----
 .../capabilities/internal/HealthCheckProbe.java    | 47 -------------
 .../internal/HealthCheckProbeBuilder.java          | 78 ++++++++++++++++++++++
 .../capabilities/internal/JvmProbeBuilder.java     | 76 +++++++++++++++++++++
 .../sling/capabilities/internal/ProbeFactory.java  | 33 ---------
 10 files changed, 286 insertions(+), 140 deletions(-)

diff --git a/capabilities/README.md b/capabilities/README.md
new file mode 100644
index 0000000..6b2274d
--- /dev/null
+++ b/capabilities/README.md
@@ -0,0 +1,46 @@
+Sling Capabilities Module
+=========================
+
+This is a work in progress for a service that allows for creating Capabilities 
endpoints
+on a Sling instance: Resources that provide information on which services are 
available,
+version levels etc.
+
+Capabilities are computed by `Probes`, simple classes that can use Health 
Checks, access
+external systems or do anything suitable to check what's available. Each 
`Probe` can return
+multiple values as String key/value pairs.
+
+To define a Capabilities endpoint, create a Sling Resource with 1..N 
properties having
+names that end with the `_probe_` suffix. The String value of each property is 
passed
+to all available `ProbeBuilder` services, and the first one that returns a 
`Probe` is used.
+
+As an example, with the default Probes found in this module, creating a 
Resource such as
+
+    "caps": {
+      "jcr:primaryType": "nt:unstructured",
+      "foo_probe": "hc:The FOO cap:testing",
+      "two_probe": "jvm:info",
+      "3_probe": "hc:another HC:sometags",
+      "sling:resourceType": "sling/capabilities"
+    }
+  
+At `/tmp/caps` for example, and requesting 
`http://localhost:8080/tmp/caps.json` produces
+the following output:
+
+    {
+      "org.apache.sling.capabilities": {
+        "The FOO cap": {
+          "TODO": "would run HCs with tags testing"
+        },
+        "JvmProbe": {
+          "java.specification.version": "1.8",
+          "java.vm.version": "25.171-b11",
+          "java.vm.vendor": "Oracle Corporation"
+        },
+        "another HC": {
+          "TODO": "would run HCs with tags sometags"
+        }
+      }
+    }
+    
+This is not useful as is as the HC probes do not execute Health Checks yet - 
it's just meant
+to demonstrate how Probes are created and used.    
diff --git a/capabilities/README.txt b/capabilities/README.txt
deleted file mode 100644
index 35d07ba..0000000
--- a/capabilities/README.txt
+++ /dev/null
@@ -1,12 +0,0 @@
-Sling Capabilities Module
-=========================
-
-This is a work in progress for a service that provides information on the 
capabilities
-of a Sling instance: what is installed, version levels etc.
-
-Capabilities are defined either by executing sets of Health Checks, selected by
-tags, or by executing small scripts.
-
-Each capability has a name and a value.
-
-TODO: complete this, examples etc.
diff --git a/capabilities/pom.xml b/capabilities/pom.xml
index 6e2cad3..ce4f4a7 100644
--- a/capabilities/pom.xml
+++ b/capabilities/pom.xml
@@ -21,7 +21,7 @@
   <parent>
     <artifactId>sling</artifactId>
     <groupId>org.apache.sling</groupId>
-    <version>29</version>
+    <version>30</version>
     <relativePath/>
   </parent>
   <modelVersion>4.0.0</modelVersion>
diff --git 
a/capabilities/src/main/java/org/apache/sling/capabilities/internal/Probe.java 
b/capabilities/src/main/java/org/apache/sling/capabilities/Probe.java
similarity index 57%
rename from 
capabilities/src/main/java/org/apache/sling/capabilities/internal/Probe.java
rename to capabilities/src/main/java/org/apache/sling/capabilities/Probe.java
index 8446667..508ac09 100644
--- 
a/capabilities/src/main/java/org/apache/sling/capabilities/internal/Probe.java
+++ b/capabilities/src/main/java/org/apache/sling/capabilities/Probe.java
@@ -16,9 +16,25 @@
  ~ specific language governing permissions and limitations
  ~ under the License.
  
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
-package org.apache.sling.capabilities.internal;
+package org.apache.sling.capabilities;
 
-interface Probe {
+import java.util.Map;
+import org.osgi.annotation.versioning.ProviderType;
+
+/** A Probe computes capabilities. Various types of Probes are meant
+ *  to be implemented, using Health Checks, OSGi environment status
+ *  or any suitable input to find out which capabilities are present.
+ */
+@ProviderType
+public interface Probe {
+    /** @return the name of this Probe, which is used as a "section name" for
+     *  the capabilities that this Probe computes.
+     */
     String getName();
-    String getValue() throws Exception;
+    
+    /** @return zero to N capabilities, each being represented by
+     *      a key/value pair of Strings.
+     * @throws Exception if the capabilities could not be computed
+     */
+    Map<String, String> getValues() throws Exception;
 }
diff --git 
a/capabilities/src/main/java/org/apache/sling/capabilities/internal/ScriptProbe.java
 b/capabilities/src/main/java/org/apache/sling/capabilities/ProbeBuilder.java
similarity index 55%
rename from 
capabilities/src/main/java/org/apache/sling/capabilities/internal/ScriptProbe.java
rename to 
capabilities/src/main/java/org/apache/sling/capabilities/ProbeBuilder.java
index 4621db7..eec18dd 100644
--- 
a/capabilities/src/main/java/org/apache/sling/capabilities/internal/ScriptProbe.java
+++ b/capabilities/src/main/java/org/apache/sling/capabilities/ProbeBuilder.java
@@ -16,35 +16,27 @@
  ~ specific language governing permissions and limitations
  ~ under the License.
  
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
-package org.apache.sling.capabilities.internal;
+package org.apache.sling.capabilities;
 
-/** A Probe that executes a script to find out if 
- *  specific capabilities are present.
- *  The capability value is the output of the script.
- */
-class ScriptProbe implements Probe {
-    
-    public static final String ID = "script";
+import org.osgi.annotation.versioning.ProviderType;
+
+/** Service that builds a Probe if it gets a suitable definition */
+@ProviderType
+public interface ProbeBuilder {
     
-    private final String name;
-    private final String script;
+    String DEF_SEPARATOR = ":";
     
-    ScriptProbe(String name, String script) {
-        this.name = name;
-        this.script = script;
-    }
-
-    @Override
-    public String getName() {
-        return name;
-    }
+    /**
+     * @param definition A Probe definition in a syntax that this services 
supports
+     * @return null if the definition doesn't start with our prefix followed 
by a colon
+     * @throws IllegalArgumentException if the definition starts with our 
prefix
+     *      but is otherwise invalid
+     */
+    Probe buildProbe(String definition) throws IllegalArgumentException;
     
-    @Override
-    public String getValue() {
-        // TODO implement this
-        if(script.contains("EX")) {
-            throw new IllegalArgumentException("foobar");
-        }
-        return script;
-    }
+    /** The prefix which definitions must start with (followed by
+     *  our DEF_SEPARATOR) to be considered by this builder.
+     * @return our prefix
+     */
+    String getPrefix();
 }
diff --git 
a/capabilities/src/main/java/org/apache/sling/capabilities/internal/CapabilitiesServlet.java
 
b/capabilities/src/main/java/org/apache/sling/capabilities/internal/CapabilitiesServlet.java
index 4c39abf..6f77500 100644
--- 
a/capabilities/src/main/java/org/apache/sling/capabilities/internal/CapabilitiesServlet.java
+++ 
b/capabilities/src/main/java/org/apache/sling/capabilities/internal/CapabilitiesServlet.java
@@ -21,27 +21,43 @@ package org.apache.sling.capabilities.internal;
 import java.io.IOException;
 import java.util.ArrayList;
 import java.util.Collection;
-import java.util.Date;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import javax.servlet.Servlet;
 import javax.servlet.ServletException;
-import org.apache.felix.scr.annotations.sling.SlingServlet;
 import org.apache.sling.api.SlingHttpServletRequest;
 import org.apache.sling.api.SlingHttpServletResponse;
 import org.apache.sling.api.resource.Resource;
 import org.apache.sling.api.resource.ValueMap;
 import org.apache.sling.api.servlets.SlingSafeMethodsServlet;
 import org.apache.felix.utils.json.JSONWriter;
+import org.apache.sling.capabilities.Probe;
+import org.apache.sling.capabilities.ProbeBuilder;
+import org.osgi.service.component.annotations.Component;
+import org.osgi.service.component.annotations.Reference;
+import org.osgi.service.component.annotations.ReferenceCardinality;
+import org.osgi.service.component.annotations.ReferencePolicy;
+import org.osgi.service.component.annotations.ReferencePolicyOption;
+
+@Component(service = Servlet.class,
+property = {
+    "sling.servlet.resourceTypes=sling/capabilities",
+    "sling.servlet.methods=GET",
+    "sling.servlet.selectors=capabilities",
+    "sling.servlet.extensions=json"
+})
 
-@SlingServlet(
-        resourceTypes = {"sling/capabilities"},
-        selectors = {"capabilities"},
-        methods = "GET",
-        extensions = "json"
-)
 public class CapabilitiesServlet extends SlingSafeMethodsServlet {
     
+    @Reference(
+        policy=ReferencePolicy.DYNAMIC,
+        cardinality=ReferenceCardinality.AT_LEAST_ONE, 
+        policyOption=ReferencePolicyOption.GREEDY)
+    volatile List<ProbeBuilder> builders;
+
     public final static String PROBE_PROP_SUFFIX = "_probe";
     public final static String CAPS_KEY = "org.apache.sling.capabilities";
-    private final ProbeFactory factory = new ProbeFactory();
     
     @Override
     protected void doGet(SlingHttpServletRequest request, 
SlingHttpServletResponse response) throws ServletException, IOException {
@@ -54,15 +70,29 @@ public class CapabilitiesServlet extends 
SlingSafeMethodsServlet {
         jw.object();
         
         for(String def : getProbeDefinitions(request.getResource())) {
-            final Probe p = factory.buildProbe(def);
-            String value = null;
-            try {
-                value = p.getValue();
-            } catch(Exception e) {
-                value = "EXCEPTION:" + e.getClass().getName() + ":" + 
e.getMessage();
+            Map<String, String> values = null;
+            Probe p = null;
+            for(ProbeBuilder b : builders) {
+                p = b.buildProbe(def);
+                if(p != null) {
+                    try {
+                        values = p.getValues();
+                    } catch(Exception e) {
+                        values = new HashMap<>();
+                        values.put("_EXCEPTION_", e.getClass().getName() + ":" 
+ e.getMessage());
+                    }
+                    break;
+                }
+            }
+            if(p != null && values != null) {
+                jw.key(p.getName());
+                jw.object();
+                for(Map.Entry<String, String> e : values.entrySet()) {
+                    jw.key(e.getKey());
+                    jw.value(e.getValue());
+                }
+                jw.endObject();
             }
-            jw.key(p.getName());
-            jw.value(value);
         }
         
         jw.endObject();
diff --git 
a/capabilities/src/main/java/org/apache/sling/capabilities/internal/HealthCheckProbe.java
 
b/capabilities/src/main/java/org/apache/sling/capabilities/internal/HealthCheckProbe.java
deleted file mode 100644
index 7b50d50..0000000
--- 
a/capabilities/src/main/java/org/apache/sling/capabilities/internal/HealthCheckProbe.java
+++ /dev/null
@@ -1,47 +0,0 @@
-/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
- ~ 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.sling.capabilities.internal;
-
-/** A Probe that executes Health Checks to find out if 
- *  specific capabilities are present.
- *  The capability value is "true" if all HCs are OK,
- *  "false" otherwise.
- */
-class HealthCheckProbe implements Probe {
-    public static final String ID = "hc";
-    
-    private final String name;
-    private final String tags;
-    
-    HealthCheckProbe(String name, String tags) {
-        this.name = name;
-        this.tags = tags;
-    }
-
-    @Override
-    public String getName() {
-        return name;
-    }
-    
-    @Override
-    public String getValue() {
-        // TODO implement this
-        return tags;
-    }
-}
diff --git 
a/capabilities/src/main/java/org/apache/sling/capabilities/internal/HealthCheckProbeBuilder.java
 
b/capabilities/src/main/java/org/apache/sling/capabilities/internal/HealthCheckProbeBuilder.java
new file mode 100644
index 0000000..3787ce8
--- /dev/null
+++ 
b/capabilities/src/main/java/org/apache/sling/capabilities/internal/HealthCheckProbeBuilder.java
@@ -0,0 +1,78 @@
+/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ ~ 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.sling.capabilities.internal;
+
+import java.util.HashMap;
+import java.util.Map;
+import org.apache.sling.capabilities.Probe;
+import org.apache.sling.capabilities.ProbeBuilder;
+import org.osgi.service.component.annotations.Component;
+
+/** A Probe that executes Health Checks to find out if 
+ *  specific capabilities are present.
+ *  The capability value is "true" if all HCs are OK,
+ *  "false" otherwise.
+ * 
+ *  TODO move to a separate module to minimize dependencies of the 
+ *  core capabilities module.
+ */
+@Component(service=ProbeBuilder.class)
+public class HealthCheckProbeBuilder implements ProbeBuilder {
+    public static final String PREFIX = "hc" + DEF_SEPARATOR;
+    
+    static class HcProbe implements Probe {
+        private final String name;
+        private final String tags;
+        
+        HcProbe(String name, String tags) {
+            this.name = name;
+            this.tags = tags;
+        }
+
+        @Override
+        public String getName() {
+            return name;
+        }
+
+        @Override
+        public Map<String, String> getValues() throws Exception {
+            final Map<String, String> result = new HashMap<> ();
+            result.put("TODO", "would run HCs with tags " + tags);
+            return result;
+        }
+    }
+    
+    @Override
+    public Probe buildProbe(String definition) throws IllegalArgumentException 
{
+        if(!definition.startsWith(PREFIX)) {
+            return null;
+        }
+        
+        final String [] parts = definition.split(DEF_SEPARATOR);
+        if(parts.length != 3) {
+            throw new IllegalArgumentException("Invalid definition:" + 
definition);
+        }
+        return new HcProbe(parts[1], parts[2]);
+    }
+    
+    @Override
+    public String getPrefix() {
+        return PREFIX;
+    }
+}
diff --git 
a/capabilities/src/main/java/org/apache/sling/capabilities/internal/JvmProbeBuilder.java
 
b/capabilities/src/main/java/org/apache/sling/capabilities/internal/JvmProbeBuilder.java
new file mode 100644
index 0000000..d2097bb
--- /dev/null
+++ 
b/capabilities/src/main/java/org/apache/sling/capabilities/internal/JvmProbeBuilder.java
@@ -0,0 +1,76 @@
+/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ ~ 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.sling.capabilities.internal;
+
+import java.util.HashMap;
+import java.util.Map;
+import org.apache.sling.capabilities.Probe;
+import org.apache.sling.capabilities.ProbeBuilder;
+import static org.apache.sling.capabilities.ProbeBuilder.DEF_SEPARATOR;
+import org.osgi.service.component.annotations.Component;
+
+/** A Probe that executes a script to find out if 
+ *  specific capabilities are present.
+ *  The capability value is the output of the script.
+ */
+
+@Component(service=ProbeBuilder.class)
+public class JvmProbeBuilder implements ProbeBuilder {
+    
+    public static final String PREFIX = "jvm" + DEF_SEPARATOR;
+    
+    static class JvmProbe implements Probe {
+        @Override
+        public String getName() {
+            return getClass().getSimpleName();
+        }
+
+        @Override
+        public Map<String, String> getValues() throws Exception {
+            // Return semi-useful JVM properties for our proof of concept
+            final Map<String, String> result = new HashMap<>();
+            
+            final String [] props = {
+                "java.specification.version",
+                "java.vm.vendor",
+                "java.vm.version"
+            };
+            
+            for(String prop : props) {
+                result.put(prop, System.getProperty(prop));
+            }
+            
+            return result;
+        }
+    }
+    
+    @Override
+    public Probe buildProbe(String definition) throws IllegalArgumentException 
{
+        if(!definition.startsWith(PREFIX)) {
+            return null;
+        }
+        
+        return new JvmProbe();
+    }
+    
+    @Override
+    public String getPrefix() {
+        return PREFIX;
+    }
+}
\ No newline at end of file
diff --git 
a/capabilities/src/main/java/org/apache/sling/capabilities/internal/ProbeFactory.java
 
b/capabilities/src/main/java/org/apache/sling/capabilities/internal/ProbeFactory.java
deleted file mode 100644
index 11d2240..0000000
--- 
a/capabilities/src/main/java/org/apache/sling/capabilities/internal/ProbeFactory.java
+++ /dev/null
@@ -1,33 +0,0 @@
-/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
- ~ 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.sling.capabilities.internal;
-
-class ProbeFactory {
-    Probe buildProbe(String definition) {
-        final String [] parts = definition.split(":");
-        
-        if(ScriptProbe.ID.equals(parts[0])) {
-            return new ScriptProbe(parts[1], parts[2]);
-        } else if(HealthCheckProbe.ID.equals(parts[0])) {
-            return new HealthCheckProbe(parts[1], parts[2]);
-        } else {
-            throw new IllegalArgumentException("Invalid probe type " + 
parts[0] + " in " + definition);
-        }
-    }
-}

-- 
To stop receiving notification emails like this one, please contact
[email protected].

Reply via email to