| #set($h1 = '#') |
| #set($h2 = '##') |
| #set($h3 = '###') |
| #set($h4 = '####') |
| #set($sp = '${') |
| #set($sp2 = '${{') |
| #set($sp3 = '${{{') |
| #set($ep = '}') |
| |
| |
| $h2 Usage |
| |
| $h3 Converting Sling, Project Content Packages and Launch it |
| |
| **Note**: In this sample we use Maven variables like **project.groupId** instead of a static value assuming |
| that the project is within the same project that creates the content packages. Adjust that as needed. |
| **Note**: Because we generate Feature Model files here the feature model files are in **target/fm**. We use **fm** |
| instead of **features** to avoid confusion with the default feature source of **src/main/features**. |
| |
| First we need to define the Content Packages that are converted |
| |
| ``` |
| <dependencies> |
| ... |
| <dependency> |
| <groupId>${sp}project.groupId${ep}</groupId> |
| <artifactId>my-content-package</artifactId> |
| <version>${sp}project.version${ep}</version> |
| <type>zip</type> |
| </dependency> |
| ``` |
| |
| Then we need to include the JCR Package Init to deploy the packages when |
| the project is launched: |
| |
| ``` |
| <dependency> |
| <groupId>org.apache.sling</groupId> |
| <artifactId>org.apache.sling.jcr.packageinit</artifactId> |
| <version>0.0.1-SNAPSHOT</version> |
| </dependency> |
| ... |
| </dependencies> |
| ``` |
| |
| Then we need to include the package init feature model file which must |
| here is placed in the **src/main/resouces/fm** folder named **sling_packageinit.json**: |
| |
| ``` |
| { |
| "id":"${sp}project.groupId${ep}:${sp}project.artifactId${ep}:slingfeature:sling_packageinit:${sp}project.version${ep}", |
| "variables":{ |
| }, |
| "bundles":[ |
| { |
| "id":"org.apache.sling:org.apache.sling.jcr.packageinit:0.0.1-SNAPSHOT", |
| "start-level":"10" |
| } |
| ] |
| } |
| ``` |
| |
| We need to cpy this file into our target folder because this is not a regular JAR build |
| and so the copy of the resources is not done automatically: |
| |
| ``` |
| <build> |
| ... |
| <plugins> |
| <plugin> |
| <groupId>org.apache.maven.plugins</groupId> |
| <artifactId>maven-resources-plugin</artifactId> |
| <version>3.1.0</version> |
| <configuration> |
| <outputDirectory>${sp}project.build.directory}</outputDirectory> |
| <resources> |
| <resource> |
| <directory>src/main/resources</directory> |
| </resource> |
| </resources> |
| </configuration> |
| <executions> |
| <execution> |
| <id>copy-frm-resource</id> |
| <phase>process-resources</phase> |
| <goals> |
| <goal>copy-resources</goal> |
| </goals> |
| </execution> |
| </executions> |
| </plugin> |
| ``` |
| Then we need to setup the Sling Feature Converter Maven Plugin to convert Sling into its Feature Model |
| equivalent so that we can launch it together with the converter CP packages later: |
| |
| ``` |
| <plugin> |
| <groupId>org.apache.sling</groupId> |
| <artifactId>sling-feature-converter-maven-plugin</artifactId> |
| <version>${project.version}</version> |
| <extensions>true</extensions> |
| <executions> |
| <execution> |
| <id>convert-pm</id> |
| <phase>process-classes</phase> |
| <goals> |
| <goal>convert-pm</goal> |
| </goals> |
| <configuration> |
| <inputFolder>src/main/resources/sling/provisioning</inputFolder> |
| <outputFolder>target/fm</outputFolder> |
| <groupId>${sp}{project.groupId}}</groupId> |
| <artifactId>${sp}{project.artifactId}}</artifactId> |
| <version>${sp}{project.version}}</version> |
| <frameworkProperties> |
| launchpad:felix.systempackages.substitution=true, |
| launchpad:felix.systempackages.calculate.uses=true |
| </frameworkProperties> |
| <excludeBundles> |
| org.apache.sling.launchpad.installer, |
| org.apache.sling.jcr.repoinit.impl.RepositoryInitializer |
| </excludeBundles> |
| <runModes> |
| oak_tar, |
| :standalone |
| </runModes> |
| </configuration> |
| </execution> |
| ``` |
| |
| In this scenario the Sling Provisioning Models are copied into the source folder. |
| The **Launchpad Installer** and the **Repository Initializer** do not work together with Sling FM so |
| they are excluded here. Then we select **oak_tar and :standalone** as the runmodes for this instance. |
| |
| Then we convert the Content Package: |
| |
| ``` |
| <execution> |
| <id>convert-cp</id> |
| <phase>process-classes</phase> |
| <goals> |
| <goal>convert-cp</goal> |
| </goals> |
| <configuration> |
| <!-- NOTE: ${sp2} / }} is a way to encode placeholders that should not be interpolated in Maven in this call |
| and ${sp3} / }}} is used to make it a CP Conversion Placeholder --> |
| <artifactIdOverride>${sp2}project.groupId}}:${sp2}project.artifactId}}:slingosgifeature:${sp3}filename}}}:${sp2}project.version}}</artifactIdOverride> |
| <installConvertedCP>true</installConvertedCP> |
| <!-- Attention: because of the hack to deal with the overrides in the local Repo the generated files must be placed locally and not in the local Maven repo --> |
| <convertedCPOutput>${sp}project.build.directory}/fm.out</convertedCPOutput> |
| <fmOutput>${sp}project.build.directory}/fm</fmOutput> |
| <fmPrefix>test-ui-apps-</fmPrefix> |
| <contentPackages> |
| <contentPackage> |
| <groupId>org.apache.sling.test</groupId> |
| <artifactId>ui.apps</artifactId> |
| </contentPackage> |
| </contentPackages> |
| </configuration> |
| </execution> |
| </executions> |
| </plugin> |
| ``` |
| |
| Here we override the Feature Id to a more generic version, mark that we want to intall the converted files into |
| our local Maven repo and that we prefix the converted FM file with **test-ui-apps-**. |
| |
| Now we setup this Plugin and set the features folder to **target/fm** (keep in mind this path has to |
| be relative to the basedir and cannot be absolute): |
| |
| ``` |
| <plugin> |
| <groupId>org.apache.sling</groupId> |
| <artifactId>slingfeature-maven-plugin</artifactId> |
| <version>1.0.7-SNAPSHOT</version> |
| <extensions>true</extensions> |
| <configuration> |
| <features>target/fm</features> |
| </configuration> |
| ``` |
| |
| Now we can aggregate, collect them into a single FM file (attach) and verify all the generated Feature Model files: |
| |
| ``` |
| <execution> |
| <id>aggregate-base-feature</id> |
| <phase>generate-test-sources</phase> |
| <goals> |
| <goal>aggregate-features</goal> |
| <generatedFeatures>${sp}basedir}/target/fm</generatedFeatures> |
| </goals> |
| <configuration> |
| <aggregates> |
| <aggregate> |
| <classifier>example-runtime</classifier> |
| <filesInclude>**/*.json</filesInclude> |
| </aggregate> |
| </aggregates> |
| </configuration> |
| </execution> |
| <execution> |
| <id>attach-base-feature</id> |
| <phase>process-test-sources</phase> |
| <goals> |
| <goal>attach-features</goal> |
| </goals> |
| </execution> |
| <execution> |
| <id>verify-analyze</id> |
| <phase>generate-test-resources</phase> |
| <goals> |
| <goal>analyse-features</goal> |
| </goals> |
| <configuration> |
| <framework> |
| <groupId>org.apache.felix</groupId> |
| <artifactId>org.apache.felix.framework</artifactId> |
| <version>6.0.1</version> |
| </framework> |
| <scans> |
| <scan> |
| <includeClassifier>example-runtime</includeClassifier> |
| <includeTasks> |
| <includeTask>bundle-packages</includeTask> |
| </includeTasks> |
| </scan> |
| </scans> |
| </configuration> |
| </execution> |
| </executions> |
| </plugin> |
| ... |
| </plugins> |
| </build> |
| ``` |
| |
| Finally we can define a profile to launch the Feature Model based project. With that the launch is only done |
| if the project is buil with goal **install** and profile **launch** (mvn install -P launch): |
| |
| ``` |
| <profiles> |
| <profile> |
| <id>launch</id> |
| <build> |
| <plugins> |
| <plugin> |
| <groupId>org.apache.sling</groupId> |
| <artifactId>slingfeature-maven-plugin</artifactId> |
| <version>1.0.7-SNAPSHOT</version> |
| <extensions>true</extensions> |
| <dependencies> |
| <!-- For now the Extension Content has to be placed ahead of the launcher to make CP |
| deployment work (see SLING-8483) --> |
| <dependency> |
| <groupId>org.apache.sling</groupId> |
| <artifactId>org.apache.sling.feature.extension.content</artifactId> |
| <version>1.0.5-SNAPSHOT</version> |
| </dependency> |
| <dependency> |
| <groupId>org.apache.sling</groupId> |
| <artifactId>org.apache.sling.feature.launcher</artifactId> |
| <version>1.0.7-SNAPSHOT</version> |
| </dependency> |
| </dependencies> |
| <executions> |
| <execution> |
| <id>launch-it</id> |
| <phase>install</phase> |
| <goals> |
| <goal>launch-features</goal> |
| </goals> |
| <configuration> |
| <selection> |
| <includeClassifier>example-runtime</includeClassifier> |
| </selection> |
| </configuration> |
| </execution> |
| </executions> |
| </plugin> |
| </plugins> |
| </build> |
| </profile> |
| </profiles> |
| ``` |
| |
| The execution of a conversion and launch would look like this: |
| |
| ``` |
| mvn \ |
| clean \ |
| install \ |
| -P launch |
| ``` |
| |
| $h3 Converting a Content Package and Install its Feature Model Descriptor |
| |
| Instead of building everything local in a dedicated Maven module now each Content Project Module |
| can install their generated Feature Module descriptor into the local Maven repository so that it |
| can be **included as artifact** when the FM project is assembled. |
| |
| First in each Content Package module add this plugin configuration to your POM in the **build** section: |
| |
| ``` |
| <plugin> |
| <groupId>org.apache.sling</groupId> |
| <artifactId>sling-feature-converter-maven-plugin</artifactId> |
| <version>${sp}sling-feature-converter-maven-plugin.version}</version> |
| <extensions>true</extensions> |
| <executions> |
| <execution> |
| <id>convert-cp</id> |
| <phase>verify</phase> |
| <goals> |
| <goal>convert-cp</goal> |
| </goals> |
| <configuration> |
| <artifactIdOverride>${sp}project.groupId}:${sp}project.artifactId}:slingosgifeature:${sp3}filename}}}:${sp}project.version}</artifactIdOverride> |
| <installConvertedCP>true</installConvertedCP> |
| <convertedCPOutput>${sp}project.build.directory}/fm.out</convertedCPOutput> |
| <fmOutput>${sp}project.build.directory}/fm</fmOutput> |
| <fmPrefix>peregrine-</fmPrefix> |
| <isContentPackage>true</isContentPackage> |
| <contentPackages> |
| <contentPackage> |
| <groupId>${sp}project.groupId}</groupId> |
| <artifactId>${sp}project.artifactId}</artifactId> |
| </contentPackage> |
| </contentPackages> |
| </configuration> |
| </execution> |
| </executions> |
| </plugin> |
| ``` |
| |
| * **sling-feature-converter-maven-plugin.version**: is a property with the version of this plugin to be used (1.0.0-SNAPSHOT for now) |
| * **artifactIdOverride**: This should match the Maven Id with this pattern: 'groupId':'artifactId':'type fixed to slingosgifeature':'classifier':'version' |
| * **installConvertedCP**: must be set to true otherwise I cannot be assembled later |
| * **convertedCPOutput/fmOutput/fmPrefix**: adjust to your preferences |
| * **isContentPackage**: must be set to true |
| * **contentPackage**: must match the module's properties (later we might remove this) |
| |
| After a successful build one can check the installation by going to your local Maven repository, got to the location of you artifact and |
| check if there is a file with the extension **slingosgifeature**. |
| |
| Now we can go to the Assembly part and add the FM installed locally as artifact: |
| |
| ``` |
| <plugin> |
| <groupId>org.apache.sling</groupId> |
| <artifactId>slingfeature-maven-plugin</artifactId> |
| <version>${slingfeature-maven-plugin.version}</version> |
| <extensions>true</extensions> |
| <configuration> |
| <features>target/fm</features> |
| <generatedFeatures>${basedir}/target/fm</generatedFeatures> |
| </configuration> |
| <executions> |
| <execution> |
| <id>aggregate-base-feature</id> |
| <phase>generate-test-sources</phase> |
| <goals> |
| <goal>aggregate-features</goal> |
| </goals> |
| <configuration> |
| <aggregates> |
| <aggregate> |
| <classifier>example-runtime</classifier> |
| <filesInclude>**/*.json</filesInclude> |
| <configurationOverrides>*=USE_LATEST</configurationOverrides> |
| <includeArtifact> |
| <groupId>${project.groupId}</groupId> |
| <artifactId>base.ui.apps</artifactId> |
| <version>${project.version}</version> |
| <classifier>base.ui.apps</classifier> |
| <type>slingosgifeature</type> |
| </includeArtifact> |
| ... |
| </aggregate> |
| </aggregates> |
| </configuration> |
| </execution> |
| </executions> |
| </plugin> |
| ``` |
| |
| * **slingfeature-maven-plugin.version**: version of the sling feature maven plugin to be used |
| * **features/generatedFeatures**: add/set depending on your project |
| * **classifier/filesInclude/configurationOverrides**: set depending on your project |
| * **includeArtifact**: one entry per Content Package FM. The **groupId**, **artifactId**, **version** and **classifier** |
| must match your FM descriptor |
| |