Skip to content

Commit

Permalink
Merge branch 'develop'
Browse files Browse the repository at this point in the history
  • Loading branch information
stefanseifert committed Jan 26, 2024
2 parents 7219417 + 3ddbed5 commit 05ca639
Show file tree
Hide file tree
Showing 60 changed files with 366 additions and 259 deletions.
13 changes: 13 additions & 0 deletions changes.xml
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,19 @@
xsi:schemaLocation="http://maven.apache.org/changes/1.0.0 https://maven.apache.org/plugins/maven-changes-plugin/xsd/changes-1.0.0.xsd">
<body>

<release version="2.20.0" date="not released">
<action type="add" dev="sseifert" issue="86"><![CDATA[
ContentPackageOsgiConfigPostProcessor: Accept both <a href="https://devops.wcm.io/conga/plugins/sling//osgi-config-combined-json.html">Combined JSON files</a>
and Sling Provisioning File Format as input for generating OSGi configurations.
]]></action>
<action type="update" dev="sseifert" issue="85">
ContentPackageOsgiConfigPostProcessor: Write OSGi configurations as .cfg.json files instead of .config files.
</action>
<action type="update" dev="sseifert">
Update to AEM Content Package Builder 1.7.4 to ensure folder path ZIP file entries are created.
</action>
</release>

<release version="2.19.10" date="2023-12-18">
<action type="fix" dev="sseifert">
Update to latest io.wcm.tooling.commons.content-package-builder to fix potential problem with element ordering content packages generated from JSON files.
Expand Down
4 changes: 2 additions & 2 deletions conga-aem-plugin/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -25,13 +25,13 @@
<parent>
<groupId>io.wcm.devops.conga.plugins</groupId>
<artifactId>io.wcm.devops.conga.plugins.aem.parent</artifactId>
<version>2.19.10</version>
<version>2.20.0</version>
<relativePath>../parent/pom.xml</relativePath>
</parent>

<groupId>io.wcm.devops.conga.plugins</groupId>
<artifactId>io.wcm.devops.conga.plugins.aem</artifactId>
<version>2.19.10</version>
<version>2.20.0</version>
<packaging>jar</packaging>

<name>CONGA AEM Plugin</name>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,7 @@
/**
* AES crypto support implementation with the same algorithms as used by AEM 6.3 and up.
*/
@SuppressWarnings("java:S5542") // cannot use a more secure cipher mode, we have to be compatible with AEM
public class AesCryptoSupport extends CryptoSupport {

private static final String AES_KEY_ALGORITHM = "AES";
Expand All @@ -54,7 +55,7 @@ private static Random initRandom() {
return SecureRandom.getInstance(SECURE_RANDOM_ALGORITHM);
}
catch (NoSuchAlgorithmException ex) {
throw new RuntimeException(ex);
throw new IllegalStateException(ex);
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,11 +19,11 @@
*/
package io.wcm.devops.conga.plugins.aem.handlebars.escaping;

import java.util.Map;

import org.apache.commons.text.translate.CharSequenceTranslator;
import org.apache.commons.text.translate.LookupTranslator;

import com.google.common.collect.ImmutableMap;

import io.wcm.devops.conga.generator.spi.handlebars.EscapingStrategyPlugin;
import io.wcm.devops.conga.generator.spi.handlebars.context.EscapingStrategyContext;
import io.wcm.devops.conga.generator.util.FileUtil;
Expand All @@ -44,7 +44,7 @@ public class AnyEscapingStrategy implements EscapingStrategyPlugin {
* Defines translations for strings in ANY files.
*/
private static final CharSequenceTranslator ESCAPE_ANY =
new LookupTranslator(ImmutableMap.of(
new LookupTranslator(Map.of(
"\"", "\\\"",
"\\", "\\\\"));

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -29,8 +29,6 @@
import com.github.jknack.handlebars.Context;
import com.github.jknack.handlebars.Options;
import com.github.jknack.handlebars.Options.Buffer;
import com.google.common.collect.ImmutableList;
import com.google.common.collect.ImmutableMap;

import io.wcm.devops.conga.generator.spi.handlebars.HelperPlugin;
import io.wcm.devops.conga.generator.spi.handlebars.context.HelperContext;
Expand All @@ -45,7 +43,7 @@ abstract class AbstractCloudManagerConditionalHelper implements HelperPlugin<Obj

static final String HTTPD_KEY = "httpd";
static final String CLOUD_MANAGER_CONDITIONAL_KEY = "cloudManagerConditional";
static final List<String> ENVIRONMENTS = ImmutableList.of("dev", "stage", "prod");
static final List<String> ENVIRONMENTS = List.of("dev", "stage", "prod");

@Override
@SuppressWarnings("unchecked")
Expand All @@ -70,7 +68,7 @@ public final Object apply(Object context, Options options, HelperContext pluginC
for (CloudManagerConditional item : items) {

// config inside httpd.cloudManagerConditional is considered to be prefixed with "httpd.", so wrap it around here for merging
Map<String, Object> httpdWrapper = ImmutableMap.of(HTTPD_KEY, item.getConfig());
Map<String, Object> httpdWrapper = Map.of(HTTPD_KEY, item.getConfig());
Map<String, Object> mergedModel = MapMerger.merge(httpdWrapper, (Map<String, Object>)currentContext.model());

// remove cloudManagerConditional after merging the models
Expand All @@ -96,7 +94,7 @@ protected abstract void renderBodyContent(Buffer buffer, CharSequence bodyConten

private List<CloudManagerConditional> getCloudManagerConditional(Map<String, Object> cloudManagerConditional) {
return ENVIRONMENTS.stream()
.map(env -> new CloudManagerConditional(env, cloudManagerConditional.getOrDefault(env, ImmutableMap.of())))
.map(env -> new CloudManagerConditional(env, cloudManagerConditional.getOrDefault(env, Map.of())))
.collect(Collectors.toList());
}

Expand All @@ -115,7 +113,7 @@ private static class CloudManagerConditional {
this.config = (Map<String, Object>)value;
}
else {
this.config = ImmutableMap.of();
this.config = Map.of();
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,7 @@ public String getName() {
}

@Override
@SuppressWarnings({ "java:S3776", "java:S5411" }) // ignore complexity
public Object apply(Object context, Options options, HelperContext pluginContext) throws IOException {
if (context == null) {
return null;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -73,6 +73,7 @@ protected String generateFilter(Map<String, Object> filterMap, Options options)
allowFrom, allowFromHost);
}

@SuppressWarnings({ "java:S3776", "java:S1192" }) // ignore complexity
private String generateRule(String ruleType, String ruleExpression, HttpdFilterType filterType,
String allowFrom, String allowFromHost) {
StringBuilder sb = new StringBuilder();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@
* Java bean that describes a AEM dispatcher filter rule as defined in
* https://docs.adobe.com/docs/en/dispatcher/disp-config.html#par_134_32_0009
*/
class DispatcherFilter extends AbstractFilter {
final class DispatcherFilter extends AbstractFilter {

/*
* The /type indicates whether to allow or deny access for the requests that match the pattern.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@
/**
* Java bean that describes a simple HTTPd filter rule.
*/
class HttpdFilter extends AbstractFilter {
final class HttpdFilter extends AbstractFilter {

private final HttpdFilterType type;

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@
import java.io.InputStream;
import java.io.OutputStream;
import java.nio.charset.StandardCharsets;
import java.nio.file.Files;
import java.util.Dictionary;
import java.util.HashMap;
import java.util.List;
Expand All @@ -39,25 +40,24 @@
import org.apache.sling.provisioning.model.Model;
import org.slf4j.Logger;

import com.google.common.collect.ImmutableList;
import com.google.common.collect.ImmutableMap;

import edu.umd.cs.findbugs.annotations.SuppressFBWarnings;
import io.wcm.devops.conga.generator.GeneratorException;
import io.wcm.devops.conga.generator.plugins.postprocessor.AbstractPostProcessor;
import io.wcm.devops.conga.generator.spi.context.FileContext;
import io.wcm.devops.conga.generator.spi.context.FileHeaderContext;
import io.wcm.devops.conga.generator.spi.context.PostProcessorContext;
import io.wcm.devops.conga.plugins.aem.util.ContentPackageUtil;
import io.wcm.devops.conga.plugins.sling.postprocessor.JsonOsgiConfigPostProcessor;
import io.wcm.devops.conga.plugins.sling.util.ConfigConsumer;
import io.wcm.devops.conga.plugins.sling.util.JsonOsgiConfigUtil;
import io.wcm.devops.conga.plugins.sling.util.OsgiConfigUtil;
import io.wcm.devops.conga.plugins.sling.util.ProvisioningUtil;
import io.wcm.tooling.commons.contentpackagebuilder.ContentPackage;
import io.wcm.tooling.commons.contentpackagebuilder.ContentPackageBuilder;

/**
* Transforms a Sling Provisioning file into OSGi configurations (ignoring all other provisioning contents)
* and then packages them up in an AEM content package to be deployed via CRX package manager.
* Transforms a Sling Provisioning file or Combined JSON file as used by CONGA Sling Plugin
* into OSGi configurations and then packages them up in an AEM content package to be deployed via CRX package manager.
*/
public class ContentPackageOsgiConfigPostProcessor extends AbstractPostProcessor {

Expand All @@ -73,7 +73,8 @@ public String getName() {

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

@Override
Expand All @@ -88,14 +89,20 @@ public List<FileContext> apply(FileContext fileContext, PostProcessorContext con
FileHeaderContext fileHeader = extractFileHeader(fileContext, context);

// generate OSGi configurations
Model model = ProvisioningUtil.getModel(fileContext);
Model model;
if (ProvisioningUtil.isProvisioningFile(fileContext)) {
model = ProvisioningUtil.getModel(fileContext);
}
else {
model = JsonOsgiConfigUtil.readToProvisioningModel(file);
}

// check if any osgi configuration is present
boolean hasAnyConfig = !ProvisioningUtil.visitOsgiConfigurations(model,
(ConfigConsumer<Boolean>)(path, properties) -> true).isEmpty();

// create AEM content package with configurations
File zipFile = new File(file.getParentFile(), FilenameUtils.getBaseName(file.getName()) + ".zip");
File zipFile = new File(file.getParentFile(), getBaseFileName(file.getName()) + ".zip");
logger.info("Generate {}", zipFile.getCanonicalPath());

String rootPath = ContentPackageUtil.getMandatoryProp(options, PROPERTY_PACKAGE_ROOT_PATH);
Expand All @@ -113,19 +120,19 @@ public List<FileContext> apply(FileContext fileContext, PostProcessorContext con
else {
// create folder for root path if package is empty otherwise
// (to make sure probably already existing config is overridden/cleaned)
contentPackage.addContent(rootPath, ImmutableMap.of("jcr:primaryType", "nt:folder"));
contentPackage.addContent(rootPath, Map.of("jcr:primaryType", "nt:folder"));
}
}

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

// set force to true by default for CONGA-generated packages (but allow override from role definition)
Map<String, Object> modelOptions = new HashMap<>();
modelOptions.put("force", true);
modelOptions.putAll(fileContext.getModelOptions());

return ImmutableList.of(new FileContext().file(zipFile).modelOptions(modelOptions));
return List.of(new FileContext().file(zipFile).modelOptions(modelOptions));
}
catch (IOException ex) {
throw new GeneratorException("Unable to post-process sling provisioning OSGi configurations.", ex);
Expand All @@ -146,12 +153,13 @@ private boolean generateOsgiConfigurations(Model model, ContentPackage contentPa
List<Void> result = ProvisioningUtil.visitOsgiConfigurations(model, new ConfigConsumer<Void>() {
@Override
@SuppressFBWarnings("RV_RETURN_VALUE_IGNORED_BAD_PRACTICE")
@SuppressWarnings("java:S3457") // log placeholders
public Void accept(String path, Dictionary<String, Object> properties) throws IOException {
String contentPath = rootPath + (StringUtils.contains(path, "/") ? "." : "/") + path;
context.getLogger().info(" Include " + contentPath);

// write configuration to temporary file
File tempFile = File.createTempFile(NAME, ".config");
File tempFile = File.createTempFile(NAME, ".cfg.json");
try (OutputStream os = new FileOutputStream(tempFile)) {
OsgiConfigUtil.write(os, properties);
}
Expand All @@ -168,12 +176,21 @@ public Void accept(String path, Dictionary<String, Object> properties) throws IO
}
finally {
// remove temporary file
tempFile.delete();
Files.delete(tempFile.toPath());
}
return null;
}
});
return !result.isEmpty();
}

private String getBaseFileName(String fileName) {
if (StringUtils.endsWith(fileName, JsonOsgiConfigPostProcessor.FILE_EXTENSION)) {
return StringUtils.substringBeforeLast(fileName, JsonOsgiConfigPostProcessor.FILE_EXTENSION);
}
else {
return FilenameUtils.getBaseName(fileName);
}
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -24,15 +24,14 @@
import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.nio.file.Files;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.apache.commons.io.FilenameUtils;
import org.slf4j.Logger;

import com.google.common.collect.ImmutableList;

import edu.umd.cs.findbugs.annotations.SuppressFBWarnings;
import io.wcm.devops.conga.generator.GeneratorException;
import io.wcm.devops.conga.generator.plugins.postprocessor.AbstractPostProcessor;
Expand Down Expand Up @@ -108,14 +107,14 @@ public List<FileContext> apply(FileContext fileContext, PostProcessorContext con
}

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

// set force to true by default for CONGA-generated packages (but allow override from role definition)
Map<String, Object> modelOptions = new HashMap<>();
modelOptions.put("force", true);
modelOptions.putAll(fileContext.getModelOptions());

return ImmutableList.of(new FileContext().file(zipFile).modelOptions(modelOptions));
return List.of(new FileContext().file(zipFile).modelOptions(modelOptions));
}
catch (IOException ex) {
throw new GeneratorException("Unable to post-process JSON data file: " + FileUtil.getCanonicalPath(file), ex);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -29,8 +29,6 @@
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;

import com.google.common.collect.ImmutableList;

import io.wcm.devops.conga.generator.GeneratorException;
import io.wcm.devops.conga.generator.plugins.postprocessor.AbstractPostProcessor;
import io.wcm.devops.conga.generator.spi.ImplicitApplyOptions;
Expand Down Expand Up @@ -103,7 +101,7 @@ public List<FileContext> apply(FileContext fileContext, PostProcessorContext con
throw new GeneratorException("Unable to extract properties from AEM package " + fileContext.getCanonicalPath(), ex);
}

return ImmutableList.of();
return List.of();
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,8 @@
final class ContentElementHandler implements ContentHandler {

private ContentElement root;

@SuppressWarnings("java:S5998") // analyzed paths should be safe
private static final Pattern PATH_PATTERN = Pattern.compile("^((/[^/]+)*)(/([^/]+))$");

@Override
Expand All @@ -44,11 +46,11 @@ public void resource(String path, Map<String, Object> properties) {
}
else {
if (root == null) {
throw new RuntimeException("Root resource not set.");
throw new IllegalArgumentException("Root resource not set.");
}
Matcher matcher = PATH_PATTERN.matcher(path);
if (!matcher.matches()) {
throw new RuntimeException("Unexpected path:" + path);
throw new IllegalArgumentException("Unexpected path:" + path);
}
String relativeParentPath = StringUtils.stripStart(matcher.group(1), "/");
String name = matcher.group(4);
Expand All @@ -60,7 +62,7 @@ public void resource(String path, Map<String, Object> properties) {
parent = root.getChild(relativeParentPath);
}
if (parent == null) {
throw new RuntimeException("Parent '" + relativeParentPath + "' does not exist.");
throw new IllegalArgumentException("Parent '" + relativeParentPath + "' does not exist.");
}
parent.getChildren().put(name, new ContentElementImpl(name, properties));
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.nio.file.Files;

import org.apache.commons.lang3.StringUtils;

Expand Down Expand Up @@ -101,7 +102,7 @@ public void deleteIfRequired(UrlFileManager urlFileManager, File targetDir) thro
}
File file = getFile(targetDir);
if (file != null) {
file.delete();
Files.delete(file.toPath());
}
}
}
Expand Down
Loading

0 comments on commit 05ca639

Please sign in to comment.