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].