Skip to content

Commit

Permalink
Add JsonOsgiConfigPostProcessor to support reading a combined set of …
Browse files Browse the repository at this point in the history
…OSGi configuration for run modes from .osgiconfig.json files (#7)
  • Loading branch information
stefanseifert authored Jan 10, 2024
1 parent ae0ddf8 commit b9dc6e2
Show file tree
Hide file tree
Showing 17 changed files with 671 additions and 40 deletions.
3 changes: 3 additions & 0 deletions changes.xml
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,9 @@
<body>

<release version="1.4.0" date="not released">
<action type="add" dev="sseifert" issue="7">
Add JsonOsgiConfigPostProcessor to support reading a combined set of OSGi configuration for run modes from .osgiconfig.json files.
</action>
<action type="update" dev="sseifert" issue="6">
ProvisioningOsgiConfigPostProcessor: Write OSGi configurations as .cfg.json files instead of .config files.
</action>
Expand Down
7 changes: 7 additions & 0 deletions conga-sling-plugin/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -79,6 +79,13 @@
<scope>compile</scope>
</dependency>

<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-databind</artifactId>
<version>2.16.1</version>
<scope>compile</scope>
</dependency>

<dependency>
<groupId>org.apache.felix</groupId>
<artifactId>org.apache.felix.cm.json</artifactId>
Expand Down
5 changes: 5 additions & 0 deletions conga-sling-plugin/src/it/example/src/main/roles/sling.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,11 @@ files:
postProcessors:
- sling-provisioning-osgiconfig

- file: config-sample.osgiconfig.json
dir: osgi-config-from-json
template: config-sample.osgiconfig.json.hbs
postProcessors:
- sling-json-osgiconfig

# Defines configuration parameters and default values
config:
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
{
"configurations": {
"my.pid": {
"heapspaceMax": "{{jvm.heapspace.max}}",
"booleanProp": true,
"numberProp": 123,
"arrayProp": ["v1","v2","v3"],
"numberArrayProp": [1,2]
}
},
"configurations:mode1": {
"my.pid2": {
"stringProperty": "{{var1}}",
"stringProperty2": "{{var2}}"
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,10 @@

my.pid
heapspaceMax="{{jvm.heapspace.max}}"
booleanProp=B"true"
numberProp=I"123"
arrayProp=["v1","v2","v3"]
numberArrayProp=I["1","2"]

[configurations runModes=mode1]

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,85 @@
/*
* #%L
* wcm.io
* %%
* Copyright (C) 2024 wcm.io
* %%
* Licensed 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.
* #L%
*/
package io.wcm.devops.conga.plugins.sling.postprocessor;

import java.io.File;
import java.io.IOException;
import java.nio.file.Files;
import java.util.List;

import org.apache.commons.lang3.StringUtils;
import org.apache.sling.provisioning.model.Model;

import edu.umd.cs.findbugs.annotations.SuppressFBWarnings;
import io.wcm.devops.conga.generator.GeneratorException;
import io.wcm.devops.conga.generator.spi.PostProcessorPlugin;
import io.wcm.devops.conga.generator.spi.context.FileContext;
import io.wcm.devops.conga.generator.spi.context.PostProcessorContext;
import io.wcm.devops.conga.plugins.sling.util.JsonOsgiConfigUtil;
import io.wcm.devops.conga.plugins.sling.util.ProvisioningUtil;

/**
* Transforms a combined JSON file containing OSGi configurations into individual OSGi configuration files.
*/
public class JsonOsgiConfigPostProcessor implements PostProcessorPlugin {

/**
* Plugin name
*/
public static final String NAME = "sling-json-osgiconfig";

/**
* File extension
*/
public static final String FILE_EXTENSION = ".osgiconfig.json";

@Override
public String getName() {
return NAME;
}

@Override
public boolean accepts(FileContext file, PostProcessorContext context) {
return StringUtils.endsWith(file.getFile().getName(), FILE_EXTENSION);
}

@Override
@SuppressFBWarnings("RV_RETURN_VALUE_IGNORED_BAD_PRACTICE")
public List<FileContext> apply(FileContext fileContext, PostProcessorContext context) {
File file = fileContext.getFile();
try {
// read JSON file with combined configurations
Model model = JsonOsgiConfigUtil.readToProvisioningModel(file);

// generate OSGi configurations
List<FileContext> files = ProvisioningUtil.generateOsgiConfigurations(model, file.getParentFile(), context);

// delete provisioning file after transformation
Files.delete(file.toPath());

// return list of generated osgi configuration files
return files;
}
catch (IOException ex) {
throw new GeneratorException("Unable to parse JSON file with OSGi configurations.", ex);
}
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -20,10 +20,8 @@
package io.wcm.devops.conga.plugins.sling.postprocessor;

import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.nio.charset.StandardCharsets;
import java.util.Dictionary;
import java.nio.file.Files;
import java.util.List;

import org.apache.sling.provisioning.model.Model;
Expand All @@ -33,12 +31,11 @@
import io.wcm.devops.conga.generator.spi.PostProcessorPlugin;
import io.wcm.devops.conga.generator.spi.context.FileContext;
import io.wcm.devops.conga.generator.spi.context.PostProcessorContext;
import io.wcm.devops.conga.plugins.sling.util.ConfigConsumer;
import io.wcm.devops.conga.plugins.sling.util.OsgiConfigUtil;
import io.wcm.devops.conga.plugins.sling.util.ProvisioningUtil;

/**
* Transforms a Sling Provisioning file into OSGi configurations (ignoring all other provisioning contents).
* Transforms a Sling Provisioning file into OSGi configuration files (.cfg.json).
* Repoinit statements are supported as well, all other provisioning contents are ignored
*/
public class ProvisioningOsgiConfigPostProcessor implements PostProcessorPlugin {

Expand All @@ -64,41 +61,17 @@ public List<FileContext> apply(FileContext fileContext, PostProcessorContext con
try {
// generate OSGi configurations
Model model = ProvisioningUtil.getModel(fileContext);
List<FileContext> files = generateOsgiConfigurations(model, file.getParentFile(), context);
List<FileContext> files = ProvisioningUtil.generateOsgiConfigurations(model, file.getParentFile(), context);

// delete provisioning file after transformation
file.delete();
Files.delete(file.toPath());

// return list of generated osgi configuration files
return files;
}
catch (IOException ex) {
throw new GeneratorException("Unable to post-process sling provisioning OSGi configurations.", ex);
throw new GeneratorException("Unable to post-process Sling Provisioning OSGi configurations.", ex);
}
}

/**
* Generate OSGi configuration for all feature and run modes.
* @param model Provisioning Model
* @param dir Target directory
* @param context Post processor context
*/
private List<FileContext> generateOsgiConfigurations(Model model, File dir, PostProcessorContext context) throws IOException {
return ProvisioningUtil.visitOsgiConfigurations(model, new ConfigConsumer<FileContext>() {
@Override
@SuppressFBWarnings("RV_RETURN_VALUE_IGNORED_BAD_PRACTICE")
public FileContext accept(String path, Dictionary<String, Object> properties) throws IOException {
context.getLogger().info(" Generate {}", path);

File confFile = new File(dir, path);
confFile.getParentFile().mkdirs();
try (FileOutputStream os = new FileOutputStream(confFile)) {
OsgiConfigUtil.write(os, properties);
}

return new FileContext().file(confFile).charset(StandardCharsets.UTF_8);
}
});
}

}
Loading

0 comments on commit b9dc6e2

Please sign in to comment.