Skip to content

Commit

Permalink
Merge branch 'develop' into master
Browse files Browse the repository at this point in the history
  • Loading branch information
stefanseifert committed Oct 28, 2021
2 parents 1506d7e + 58af0c9 commit 70e70a7
Show file tree
Hide file tree
Showing 9 changed files with 376 additions and 3 deletions.
8 changes: 8 additions & 0 deletions changes.xml
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,14 @@
xsi:schemaLocation="http://maven.apache.org/changes/1.0.0 http://maven.apache.org/plugins/maven-changes-plugin/xsd/changes-1.0.0.xsd">
<body>

<release version="1.9.0" date="2021-10-28">
<action type="add" dev="sseifert"><![CDATA[
Provide a new "InstanceTypeService" which allows to detect whether the code is currently running on an author or publish instance.
This is usually done via an OSGi configuration - but if this is not present the instance is "guessed" from other OSGi configurations, without relying on the deprecated SlingSettingsService.<br/>
<strong>New OSGi configuration "wcm.io Commons AEM Instance Type" required</strong>, see <a href="configuration.html">System configuration</a>.
]]></action>
</release>

<release version="1.8.2" date="2021-06-01">
<action type="update" dev="sseifert">
ComponentPropertyResolverFactory: Mark return values of get methods as @NotNull.
Expand Down
10 changes: 8 additions & 2 deletions pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@

<groupId>io.wcm</groupId>
<artifactId>io.wcm.wcm.commons</artifactId>
<version>1.8.2</version>
<version>1.9.0</version>
<packaging>jar</packaging>

<name>WCM Commons</name>
Expand All @@ -49,7 +49,7 @@
<site.url.module.prefix>wcm/commons</site.url.module.prefix>

<!-- Enable reproducible builds -->
<project.build.outputTimestamp>2021-06-01T16:37:33Z</project.build.outputTimestamp>
<project.build.outputTimestamp>2021-10-28T13:13:19Z</project.build.outputTimestamp>
</properties>

<dependencies>
Expand All @@ -68,6 +68,12 @@
<scope>compile</scope>
</dependency>

<dependency>
<groupId>org.osgi</groupId>
<artifactId>org.osgi.service.cm</artifactId>
<scope>compile</scope>
</dependency>

<dependency>
<groupId>org.junit.jupiter</groupId>
<artifactId>junit-jupiter-api</artifactId>
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
/*
* #%L
* wcm.io
* %%
* Copyright (C) 2021 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.wcm.commons.instancetype;

import java.util.Set;

import org.jetbrains.annotations.NotNull;
import org.osgi.annotation.versioning.ProviderType;

/**
* Allows to detect if the current AEM instance is an author or publish instance.
* <p>
* This service does not rely in <code>SlingSettingServices</code> which is deprecated and subject to removal in latest
* AEM versions.
* Instead, it is based on a OSGi configuration which should be configured properly for author and publish instances.
* If not configured, it "guesses" the instance type from other OSGi configs and writes a warning in the logs.
* </p>
*/
@ProviderType
public interface InstanceTypeService {

/**
* Returns true if code is running on AEM author instance.
* @return true if AEM author instance.
*/
boolean isAuthor();

/**
* Returns true if code is running on AEM publish instance.
* @return true if AEM publish instance.
*/
boolean isPublish();

/**
* Returns a set with a single "author" or "publish" run mode string.
* This method is provided for for compatibility with code relying on sets of run modes formerly provided by
* <code>SlingSettingsService</code>.
* @return Set with a single element: Either "author" or "publish".
*/
@NotNull
Set<String> getRunModes();

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,142 @@
/*
* #%L
* wcm.io
* %%
* Copyright (C) 2021 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.wcm.commons.instancetype.impl;

import static org.osgi.framework.Constants.SERVICE_PID;

import java.io.IOException;
import java.util.Collections;
import java.util.Set;

import org.apache.commons.lang3.StringUtils;
import org.jetbrains.annotations.NotNull;
import org.osgi.framework.InvalidSyntaxException;
import org.osgi.service.cm.Configuration;
import org.osgi.service.cm.ConfigurationAdmin;
import org.osgi.service.component.annotations.Activate;
import org.osgi.service.component.annotations.Component;
import org.osgi.service.component.annotations.Reference;
import org.osgi.service.metatype.annotations.AttributeDefinition;
import org.osgi.service.metatype.annotations.Designate;
import org.osgi.service.metatype.annotations.ObjectClassDefinition;
import org.osgi.service.metatype.annotations.Option;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.day.cq.wcm.api.WCMMode;

import io.wcm.wcm.commons.instancetype.InstanceTypeService;
import io.wcm.wcm.commons.util.RunMode;

/**
* Implements {@link InstanceTypeService}.
*/
@Component(service = InstanceTypeService.class)
@Designate(ocd = InstanceTypeServiceImpl.Config.class)
public class InstanceTypeServiceImpl implements InstanceTypeService {

@ObjectClassDefinition(name = "wcm.io Commons AEM Instance Type",
description = "Configures if the current instance is an author or publish instance, and makes this information accessible for other services.")
@interface Config {

@AttributeDefinition(name = "Instance Type",
description = "Should be explicitely configured to 'author' or 'publish'. If not set, instance type will be guessed by heuristics from other OSGi configurations.",
options = {
@Option(value = RunMode.AUTHOR, label = "Author"),
@Option(value = RunMode.PUBLISH, label = "Publish"),
@Option(value = InstanceTypeServiceImpl.TYPE_AUTO, label = "Detect automatically (not recommended)")
})
String instance_type() default InstanceTypeServiceImpl.TYPE_AUTO;

}

static final String TYPE_AUTO = "auto";

static final String WCM_REQUEST_FILTER_PID = "com.day.cq.wcm.core.WCMRequestFilter";
static final String WCM_MODE_PROPERTY = "wcmfilter.mode";

private boolean isAuthor;
private Set<String> runModes;

@Reference
private ConfigurationAdmin configAdmin;

private final Logger log = LoggerFactory.getLogger(InstanceTypeServiceImpl.class);

@Activate
private void activate(Config config) {
// detect instance type
String instanceType = config.instance_type();
if (StringUtils.equals(instanceType, RunMode.AUTHOR)) {
isAuthor = true;
}
else if (StringUtils.equals(instanceType, RunMode.PUBLISH)) {
isAuthor = false;
}
else {
// not configured or set to "auto" - rely on guessing author mode
isAuthor = detectAutorMode();

log.warn("Please provide a 'wcm.io Commons AEM Instance Type' configuration "
+ "- falling back to guessing instance type from other configuration => {}.",
isAuthor ? RunMode.AUTHOR : RunMode.PUBLISH);
}

// set matching run mode set
if (isAuthor) {
runModes = Collections.singleton(RunMode.AUTHOR);
}
else {
runModes = Collections.singleton(RunMode.PUBLISH);
}
}

private boolean detectAutorMode() {
try {
Configuration[] configs = configAdmin.listConfigurations("(" + SERVICE_PID + "=" + WCM_REQUEST_FILTER_PID + ")");
if (configs != null && configs.length > 0) {
Object defaultWcmMode = configs[0].getProperties().get(WCM_MODE_PROPERTY);
if (defaultWcmMode instanceof String) {
return !StringUtils.equalsIgnoreCase(WCMMode.DISABLED.name(), (String)defaultWcmMode);
}
}
}
catch (IOException | InvalidSyntaxException ex) {
log.warn("Unable to read OSGi configuration: {}", WCM_REQUEST_FILTER_PID, ex);
}
return false;
}

@Override
public boolean isAuthor() {
return isAuthor;
}

@Override
public boolean isPublish() {
return !isAuthor;
}

@Override
public @NotNull Set<String> getRunModes() {
return Collections.unmodifiableSet(runModes);
}

}
24 changes: 24 additions & 0 deletions src/main/java/io/wcm/wcm/commons/instancetype/package-info.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
/*
* #%L
* wcm.io
* %%
* Copyright (C) 2018 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%
*/
/**
* Detect instance type (author/publish) of AEM instance.
*/
@org.osgi.annotation.versioning.Version("1.0")
package io.wcm.wcm.commons.instancetype;
4 changes: 4 additions & 0 deletions src/main/java/io/wcm/wcm/commons/util/RunMode.java
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,10 @@

/**
* Sling run mode utility methods.
* <p>
* Most methods in this class are deprecated because <code>SlingSettingsService</code> is deprecated in recent AEM
* versions. The OSGi service {@link io.wcm.wcm.commons.instancetype.InstanceTypeService} can be used instead.
* </p>
*/
@ProviderType
public final class RunMode {
Expand Down
20 changes: 20 additions & 0 deletions src/site/markdown/configuration.md
Original file line number Diff line number Diff line change
Expand Up @@ -14,3 +14,23 @@ Create a principal-based service user mapping with an entry like this:
The built-in principal `sling-scripting` has read access to `/apps` and `/libs`.

This configuration is required **on both author and publish instances**.


### AEM Instance Type configuration

To detect whether code is currently running on an Author or Publish instance (without relying on the deprecated `SlingSettingsService`), it is required to provide an OSGi configuration "wcm.io Commons AEM Instance Type" for author and publish instances:

```
[configurations runModes=author]
io.wcm.wcm.commons.instancetype.impl.InstanceTypeServiceImpl
instance.type="author"
[configurations runModes=publish]
io.wcm.wcm.commons.instancetype.impl.InstanceTypeServiceImpl
instance.type="publish"
```

If this configuration is not present, the [InstanceTypeService][InstanceTypeService] implementation tries to guess the instance type from other OSGi configurations, but this is only a fallback.


[InstanceTypeService]: apidocs/io/wcm/wcm/commons/instancetype/InstanceTypeService.html
2 changes: 1 addition & 1 deletion src/site/markdown/index.md
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ The WCM Commons library contains:

|WCM Commons version |AEM version supported
|--------------------|----------------------
|1.8.x or higher |AEM 6.4+
|1.8.x or higher |AEM 6.4+, AEMaaCS
|1.6.x - 1.7.x |AEM 6.3+
|1.3.x - 1.5.x |AEM 6.2+
|1.0.x - 1.2.x |AEM 6.1+
Expand Down
Loading

0 comments on commit 70e70a7

Please sign in to comment.