Address sonar feedback

SLING-10644
2 files changed
tree: 8449cf47cd075d26de7cf1b620c45156b50c262f
  1. src/
  2. .asf.yaml
  3. .gitignore
  4. bnd.bnd
  5. CODE_OF_CONDUCT.md
  6. CONTRIBUTING.md
  7. Jenkinsfile
  8. LICENSE
  9. pom.xml
  10. README.md
README.md

Apache Sling

Build Status Test Status Coverage Sonarcloud Status JavaDoc Maven Central servlets License

Apache Sling Servlet Resolver

This module is part of the Apache Sling project.

Bundle implementing the Sling API ServletResolver. See the servlets & scripts documentation for how this works.

Bundled scripts

Version 2.7.0 of this bundle has added support for executing bundled scripts (precompiled or not), through the org.apache.sling.servlets.resolver.bundle.tracker API.

Although traditionally scripts are deployed as content stored in the search paths of a Sling instance, this leaves very little room for script evolution in a backwards compatible way. Furthermore, versioning scripts is a difficult process if the only mechanism to do this is the sling:resourceType property, since consumers (content nodes or other resource types) have then to explicitly mention the version expected to be executed.

Scripts should not be considered content, since their only purpose is to actually generate the rendering for a certain content structure. They are not consumed by users, but rather by the Sling Engine itself and have very little meaning outside this context. As such, scripts should be handled like code:

  1. they provide an HTTP API;
  2. they can evolve in a semantical [1] way;
  3. they have a developer audience.

How

Being built around a BundleTrackerCustomizer [2], the org.apache.sling.servlets.resolver.internal.bundle.BundledScriptTracker monitors the instance's bundles wired to the org.apache.sling.servlets.resolver bundle and scans the ones providing a sling.servlet capability [3]. The wiring is created by placing a Require-Capability header in the bundles that provide the sling.servlet capability:

osgi.extender;filter:="(&(osgi.extender=sling.scripting)(version>=1.0.0)(!(version>=2.0.0)))"

A sling.servlet capability has almost the same attributes as the properties required to register a servlet on the Sling platform [4]:

  1. sling.servlet.resourceTypes:List - mandatory; defines the provided resource type; its value is a list of resource types
  2. sling.servlet.selectors:List - optional; defines the list of selectors that this resource type can handle;
  3. sling.servlet.extensions:List - optional; defines the list of extensions that this resource type can handle;
  4. sling.servlet.methods:List - optional; defines the list of HTTP methods that this resource type can handle;
  5. version:Version - optional; defines the version of the provided resourceType;
  6. extends:String - optional; defines which resource type it extends; the version range of the extended resource type is defined in a Require-Capability.

The BundledScriptTracker will register a Sling Servlet with the appropriate properties for each sling.servlet capability. The servlets will be registered using the bundle context of the bundle providing the sling.servlet capability, making sure to expose the different versions of a resource type as part of the registered servlet's properties. On top of this, a plain resource type bound servlet will also be registered, which will be automatically wired to the highest version of the resourceType. All the mentioned service registrations are managed automatically by the BundledScriptTracker.

So how do I deploy my scripts?

Short answer: exactly like you deploy your code, preferably right next to it. Pack your scripts using the following conventions:

  1. create a src/main/resources/javax.script folder in your bundle (if you want to embed the scripts as they are) or just put the scripts in src/main/scripts if you want to precompiled them (e.g. JSP and HTL);
  2. each folder under the above folders will identify a resourceType;
  3. inside each resourceType folder you can optionally create a Version folder; this has to follow the Semantic Versioning constraints described at [1];
  4. add your scripts, using the same naming conventions that you were used to from before [5];
  5. manually define your provide and require capabilities; just kidding; add the scriptingbundle-maven-plugin to your build section and add its required properties in the maven-bundle-plugin's instructions (check these examples);
  6. mvn clean sling:install.

Integration Tests

The integration tests for bundled scripts are provided by the org.apache.sling.scripting.bundle.tracker.it project.

Resources

[1] - https://semver.org/
[2] - https://osgi.org/javadoc/r6/core/org/osgi/util/tracker/BundleTrackerCustomizer.html
[3] - https://osgi.org/download/r6/osgi.core-6.0.0.pdf, Page 41, section 3.3.3 “Bundle Capabilities”
[4] - https://sling.apache.org/documentation/the-sling-engine/servlets.html#servlet-registration-1
[5] - https://sling.apache.org/documentation/the-sling-engine/url-to-script-resolution.html