diff --git a/examples/pom.xml b/examples/pom.xml
index 5f74199f6..b860c0abb 100644
--- a/examples/pom.xml
+++ b/examples/pom.xml
@@ -18,6 +18,7 @@
ws-bootable-jar-example
wstrust
+ wildfly-keycloak-saml-adapter
diff --git a/examples/wildfly-keycloak-saml-adapter/README.md b/examples/wildfly-keycloak-saml-adapter/README.md
new file mode 100644
index 000000000..627c38f8a
--- /dev/null
+++ b/examples/wildfly-keycloak-saml-adapter/README.md
@@ -0,0 +1,57 @@
+# Intersmash examples - Wildfly with Keycloak SAML Adapter Galleon Pack
+
+This example shows how to use Intersmash to provision and test a WildFly application on OpenShift via a s2i binary
+source build.
+
+## Overview
+The application is a simple "Hello World!" Java EE application, which is executed by a WildFly instance that is
+provisioned via the WildFly Maven Plugin. Such plugin allows for tailoring a WildFly server with just the
+required modules and configuration enabled.
+In this example case, the application project POM also demonstrates how to configure the plugin for adding the WildFly
+Keycloak SAML Adapter Galleon Pack and the related `keycloak-saml` layer to the server configuration.
+There is no interoperability involved in this example, as there isn't a Keycloak server that the WildFly application
+interacts with, and the test ony verifies that the server configuration contains the elements related to the
+Keycloak SAML Adapter resources.
+
+## Test code
+The test code consists of an Intersmash _application descriptor_ class, i.e.
+[KeycloakCapableImageBasedWildflyApplication](../wildfly-keycloak-saml-adapter/src/test/java/org/jboss/intersmash/examples/wildfly/keycloak/saml/KeycloakCapableImageBasedWildflyApplication.java)
+and an Intersmash test class, i.e.
+[KeycloakCapableImageBasedWildflyApplicationTest](../wildfly-keycloak-saml-adapter/src/test/java/org/jboss/intersmash/examples/wildfly/keycloak/saml/KeycloakCapableImageBasedWildflyApplicationTest.java).
+
+### The _application descriptor_
+[KeycloakCapableImageBasedWildflyApplication](../wildfly-keycloak-saml-adapter/src/test/java/org/jboss/intersmash/examples/wildfly/keycloak/saml/KeycloakCapableImageBasedWildflyApplication.java) provides the information that the provisioner will use to deploy the
+service on OpenShift. For instance, it can define environment variables, or secrets, and the build input. This is the input for the s2i build that the provisioner will orchestrate on
+OpenShift, in order to generate the final immutable image containing WildFly and the application deployment.
+In our case the build input is represented by a local WildFly deployment, as generated by the WildFly Maven plugin
+execution.
+
+#### Resolving the build input
+The `templating-maven-plugin` is used to have e.g. Maven project properties initialized with concrete values in Java
+classes at runtime.
+When built, this example uses such plugin in order to generate the
+`KeycloackCapableWildflyDeploymentConfiguration` Java class from the
+[KeycloackCapableWildflyDeploymentConfiguration.java](../wildfly-keycloak-saml-adapter/src/test/resources/java-templates/org/jboss/intersmash/examples/wildfly/keycloak/saml/config/KeycloackCapableWildflyDeploymentConfiguration.java) template.
+Such class contains the information needed to identify the built artifact properties or location, and is used by
+[KeycloakCapableImageBasedWildflyApplication](../wildfly-keycloak-saml-adapter/src/test/java/org/jboss/intersmash/examples/wildfly/keycloak/saml/KeycloakCapableImageBasedWildflyApplication.java) to initialize the build input with the `target/server`
+directory produced by the WildFly Maven Plugin.
+
+#### The _provisioner_
+The _provisioner_ is [selected by Intersmash](../../../intersmash/provisioners/README.md#mapping-of-implemented-provisioners-), based on the `Application` type that a given _application descriptor_ implements.
+[KeycloakCapableImageBasedWildflyApplication](../wildfly-keycloak-saml-adapter/src/test/java/org/jboss/intersmash/examples/wildfly/keycloak/saml/KeycloakCapableImageBasedWildflyApplication.java) extends
+[WildflyImageOpenShiftApplication](../../../intersmash/provisioners/src/main/java/org/jboss/intersmash/application/openshift/WildflyImageOpenShiftApplication.java) which is provisioned by
+[WildflyImageOpenShiftProvisioner](/../../../intersmash/provisioners/src/main/java/org/jboss/intersmash/provision/openshift/WildflyImageOpenShiftProvisioner.java).
+Such provisioner infers the build input runtime type in order to create the resources for either a source or binary s2i
+build to happen on OpenShift and to generate the final WildFly application image that will be fed to a `DeploymentConfig` resource, which is eventually used for orchestrating the pods that run the actual application service workload.
+
+### The test class
+
+[KeycloakCapableImageBasedWildflyApplicationTest](/../../../intersmash/examples/wildfly-keycloak-saml-adapter/src/test/java/org/jboss/intersmash/examples/wildfly/keycloak/saml/KeycloakCapableImageBasedWildflyApplicationTest.java)
+is a valid Intersmash test class - as per the `@Intersmash` annotation, and its lifecycle is fully managed by
+Intersmash, based on the information provided by the `@Service` annotations.
+The scenario consists of just one service, i.e. the one represented by the
+[KeycloakCapableImageBasedWildflyApplication](../wildfly-keycloak-saml-adapter/src/test/java/org/jboss/intersmash/examples/wildfly/keycloak/saml/KeycloakCapableImageBasedWildflyApplication.java)
+_application descriptor_.
+It uses the `@ServiceUrl` annotation in order to let Intersmash inject the URL that exposes the application service
+outside OpenShift, and which is used by one test method, which is a simple call to check that the server
+configuration actually contains the resources defined by the WildFly Keycloak SAML Adapter Galleon pack.
diff --git a/examples/wildfly-keycloak-saml-adapter/pom.xml b/examples/wildfly-keycloak-saml-adapter/pom.xml
new file mode 100644
index 000000000..74b2faec3
--- /dev/null
+++ b/examples/wildfly-keycloak-saml-adapter/pom.xml
@@ -0,0 +1,174 @@
+
+
+ 4.0.0
+
+ org.jboss.intersmash.examples
+ intersmash-examples
+ 0.0.2-SNAPSHOT
+ ../pom.xml
+
+
+ wildfly-keycloak-saml-adapter
+ war
+
+ Intersmash Demos : (Wildfly): Wildfly with Keycloak SAML Adapter
+
+
+ ${project.parent.parent.basedir}/ide-config
+ 3.3.2
+
+ 30.0.0.Final
+
+ 4.2.2.Final
+
+ ${version.wildfly-server}
+
+ org.wildfly:wildfly-galleon-pack:${version.wildfly-server}
+ org.wildfly:wildfly-ee-galleon-pack:${version.wildfly-server}
+ org.wildfly.cloud:wildfly-cloud-galleon-pack:5.0.1.Final
+
+
+ org.keycloak
+ keycloak-saml-adapter-galleon-pack
+ 22.0.3
+
+
+
+
+
+
+ org.wildfly.bom
+ wildfly-ee
+ ${bom.wildfly-ee.version}
+ pom
+ import
+
+
+
+
+
+
+ jakarta.ws.rs
+ jakarta.ws.rs-api
+ provided
+
+
+ jakarta.annotation
+ jakarta.annotation-api
+ provided
+
+
+ jakarta.enterprise
+ jakarta.enterprise.cdi-api
+
+
+ org.wildfly.core
+ wildfly-controller-client
+ 23.0.0.Beta4
+
+
+
+ org.jboss.intersmash
+ intersmash-core
+ test
+
+
+ org.jboss.intersmash
+ intersmash-provisioners
+ test
+
+
+ org.jboss.intersmash.test
+ deployments-provider
+ 0.0.2-SNAPSHOT
+ test
+
+
+
+
+
+
+ org.codehaus.mojo
+ templating-maven-plugin
+ 3.0.0
+
+
+ filter-src
+
+ filter-test-sources
+
+
+
+ ${basedir}/src/test/resources/java-templates/org/jboss/intersmash/examples/wildfly/keycloak/saml/config/
+ ${project.build.directory}/generated-sources
+
+
+
+
+
+
+ org.apache.maven.plugins
+ maven-war-plugin
+ ${version.maven-war-plugin}
+
+ false
+ ROOT
+
+
+
+ org.wildfly.plugins
+ wildfly-maven-plugin
+ ${wildfly-maven-plugin.version}
+
+ ROOT.war
+
+ true
+
+
+ ${wildfly.feature-pack.location}
+
+
+ ${wildfly.cloud-feature-pack.location}
+
+
+ ${keycloak-saml-adapter-galleon-pack.groupId}
+ ${keycloak-saml-adapter-galleon-pack.artifactId}
+ ${keycloak-saml-adapter-galleon-pack.version}
+
+
+
+ cloud-default-config
+ keycloak-saml
+
+
+ true
+
+
+
+
+
+ package
+
+
+
+
+
+
+
diff --git a/examples/wildfly-keycloak-saml-adapter/src/main/java/org/jboss/intersmash/examples/wildfly/keycloak/saml/HelloResource.java b/examples/wildfly-keycloak-saml-adapter/src/main/java/org/jboss/intersmash/examples/wildfly/keycloak/saml/HelloResource.java
new file mode 100644
index 000000000..34ef670e1
--- /dev/null
+++ b/examples/wildfly-keycloak-saml-adapter/src/main/java/org/jboss/intersmash/examples/wildfly/keycloak/saml/HelloResource.java
@@ -0,0 +1,17 @@
+package org.jboss.intersmash.examples.wildfly.keycloak.saml;
+
+import jakarta.enterprise.context.ApplicationScoped;
+import jakarta.ws.rs.GET;
+import jakarta.ws.rs.Path;
+import jakarta.ws.rs.Produces;
+import jakarta.ws.rs.core.MediaType;
+
+@Path("/hello")
+@ApplicationScoped
+public class HelloResource {
+ @GET
+ @Produces(MediaType.TEXT_PLAIN)
+ public String greet() {
+ return "Hello world!";
+ }
+}
diff --git a/examples/wildfly-keycloak-saml-adapter/src/main/java/org/jboss/intersmash/examples/wildfly/keycloak/saml/RestApplication.java b/examples/wildfly-keycloak-saml-adapter/src/main/java/org/jboss/intersmash/examples/wildfly/keycloak/saml/RestApplication.java
new file mode 100644
index 000000000..f6f99a9eb
--- /dev/null
+++ b/examples/wildfly-keycloak-saml-adapter/src/main/java/org/jboss/intersmash/examples/wildfly/keycloak/saml/RestApplication.java
@@ -0,0 +1,8 @@
+package org.jboss.intersmash.examples.wildfly.keycloak.saml;
+
+import jakarta.ws.rs.ApplicationPath;
+import jakarta.ws.rs.core.Application;
+
+@ApplicationPath("/")
+public class RestApplication extends Application {
+}
diff --git a/examples/wildfly-keycloak-saml-adapter/src/main/java/org/jboss/intersmash/examples/wildfly/keycloak/saml/ServerConfigurationResource.java b/examples/wildfly-keycloak-saml-adapter/src/main/java/org/jboss/intersmash/examples/wildfly/keycloak/saml/ServerConfigurationResource.java
new file mode 100644
index 000000000..6308fe46c
--- /dev/null
+++ b/examples/wildfly-keycloak-saml-adapter/src/main/java/org/jboss/intersmash/examples/wildfly/keycloak/saml/ServerConfigurationResource.java
@@ -0,0 +1,32 @@
+package org.jboss.intersmash.examples.wildfly.keycloak.saml;
+
+import jakarta.enterprise.context.ApplicationScoped;
+import jakarta.ws.rs.GET;
+import jakarta.ws.rs.Path;
+import jakarta.ws.rs.Produces;
+import jakarta.ws.rs.core.MediaType;
+
+import java.io.BufferedReader;
+import java.io.FileInputStream;
+import java.io.IOException;
+import java.io.InputStreamReader;
+import java.nio.charset.StandardCharsets;
+import java.util.stream.Collectors;
+
+@Path("/config")
+@ApplicationScoped
+public class ServerConfigurationResource {
+ @GET
+ @Path("/read")
+ @Produces(MediaType.TEXT_PLAIN)
+ public String read() throws IOException {
+ String fileName = System.getProperty("jboss.server.config.dir") + "/standalone.xml";
+ try (FileInputStream fis = new FileInputStream(fileName)) {
+ return new BufferedReader(
+ new InputStreamReader(fis, StandardCharsets.UTF_8))
+ .lines()
+ .collect(Collectors.joining("\n"));
+
+ }
+ }
+}
diff --git a/examples/wildfly-keycloak-saml-adapter/src/test/java/org/jboss/intersmash/examples/wildfly/keycloak/saml/KeycloakCapableImageBasedWildflyApplication.java b/examples/wildfly-keycloak-saml-adapter/src/test/java/org/jboss/intersmash/examples/wildfly/keycloak/saml/KeycloakCapableImageBasedWildflyApplication.java
new file mode 100644
index 000000000..d59ac88a6
--- /dev/null
+++ b/examples/wildfly-keycloak-saml-adapter/src/test/java/org/jboss/intersmash/examples/wildfly/keycloak/saml/KeycloakCapableImageBasedWildflyApplication.java
@@ -0,0 +1,28 @@
+package org.jboss.intersmash.examples.wildfly.keycloak.saml;
+
+import java.nio.file.Path;
+import java.nio.file.Paths;
+
+import org.jboss.intersmash.application.openshift.WildflyImageOpenShiftApplication;
+import org.jboss.intersmash.application.openshift.input.BinarySource;
+import org.jboss.intersmash.application.openshift.input.BuildInput;
+import org.jboss.intersmash.examples.wildfly.keycloak.saml.config.KeycloackCapableWildflyDeploymentConfiguration;
+
+public class KeycloakCapableImageBasedWildflyApplication implements WildflyImageOpenShiftApplication {
+
+ @Override
+ public String getName() {
+ return "wildfly-app";
+ }
+
+ @Override
+ public BuildInput getBuildInput() {
+ return (BinarySource) () -> {
+ Path path = Paths.get(KeycloackCapableWildflyDeploymentConfiguration.deploymentPath());
+ if (path.toFile().exists() && path.toFile().isDirectory()) {
+ return path;
+ }
+ throw new RuntimeException("Cannot find sources root directory: " + path.toFile().getAbsolutePath());
+ };
+ }
+}
diff --git a/examples/wildfly-keycloak-saml-adapter/src/test/java/org/jboss/intersmash/examples/wildfly/keycloak/saml/KeycloakCapableImageBasedWildflyApplicationTest.java b/examples/wildfly-keycloak-saml-adapter/src/test/java/org/jboss/intersmash/examples/wildfly/keycloak/saml/KeycloakCapableImageBasedWildflyApplicationTest.java
new file mode 100644
index 000000000..7245971e9
--- /dev/null
+++ b/examples/wildfly-keycloak-saml-adapter/src/test/java/org/jboss/intersmash/examples/wildfly/keycloak/saml/KeycloakCapableImageBasedWildflyApplicationTest.java
@@ -0,0 +1,54 @@
+package org.jboss.intersmash.examples.wildfly.keycloak.saml;
+
+import java.io.IOException;
+import java.net.URI;
+import java.net.URISyntaxException;
+import java.net.http.HttpClient;
+import java.net.http.HttpRequest;
+import java.net.http.HttpResponse;
+
+import org.apache.http.HttpStatus;
+import org.jboss.intersmash.annotations.Intersmash;
+import org.jboss.intersmash.annotations.Service;
+import org.jboss.intersmash.annotations.ServiceUrl;
+import org.junit.jupiter.api.Assertions;
+import org.junit.jupiter.api.Test;
+
+@Intersmash(@Service(KeycloakCapableImageBasedWildflyApplication.class))
+public class KeycloakCapableImageBasedWildflyApplicationTest {
+
+ @ServiceUrl(KeycloakCapableImageBasedWildflyApplication.class)
+ private String wildflyApplicationUrl;
+
+ @Test
+ public void testGreeting() throws URISyntaxException, IOException, InterruptedException {
+ HttpRequest request = HttpRequest.newBuilder()
+ .uri(new URI(wildflyApplicationUrl + "/hello"))
+ .GET()
+ .build();
+
+ HttpResponse response = HttpClient
+ .newBuilder()
+ .build()
+ .send(request, HttpResponse.BodyHandlers.ofString());
+
+ Assertions.assertEquals(HttpStatus.SC_OK, response.statusCode());
+ Assertions.assertEquals("Hello world!", response.body());
+ }
+
+ @Test
+ public void testSamlSubsystemIsDefined() throws URISyntaxException, IOException, InterruptedException {
+ HttpRequest request = HttpRequest.newBuilder()
+ .uri(new URI(wildflyApplicationUrl + "/config/read"))
+ .GET()
+ .build();
+
+ HttpResponse response = HttpClient
+ .newBuilder()
+ .build()
+ .send(request, HttpResponse.BodyHandlers.ofString());
+
+ Assertions.assertEquals(HttpStatus.SC_OK, response.statusCode());
+ Assertions.assertTrue(response.body().contains(""));
+ }
+}
diff --git a/examples/wildfly-keycloak-saml-adapter/src/test/resources/META-INF/services/org.junit.platform.launcher.TestExecutionListener b/examples/wildfly-keycloak-saml-adapter/src/test/resources/META-INF/services/org.junit.platform.launcher.TestExecutionListener
new file mode 100644
index 000000000..63b7383d3
--- /dev/null
+++ b/examples/wildfly-keycloak-saml-adapter/src/test/resources/META-INF/services/org.junit.platform.launcher.TestExecutionListener
@@ -0,0 +1,2 @@
+cz.xtf.junit5.listeners.TestExecutionLogger
+cz.xtf.junit5.listeners.ProjectCreator
diff --git a/examples/wildfly-keycloak-saml-adapter/src/test/resources/java-templates/org/jboss/intersmash/examples/wildfly/keycloak/saml/config/KeycloackCapableWildflyDeploymentConfiguration.java b/examples/wildfly-keycloak-saml-adapter/src/test/resources/java-templates/org/jboss/intersmash/examples/wildfly/keycloak/saml/config/KeycloackCapableWildflyDeploymentConfiguration.java
new file mode 100644
index 000000000..fe3384340
--- /dev/null
+++ b/examples/wildfly-keycloak-saml-adapter/src/test/resources/java-templates/org/jboss/intersmash/examples/wildfly/keycloak/saml/config/KeycloackCapableWildflyDeploymentConfiguration.java
@@ -0,0 +1,20 @@
+package org.jboss.intersmash.examples.wildfly.keycloak.saml.config;
+
+public class KeycloackCapableWildflyDeploymentConfiguration {
+
+ public static String getProjectGroupId() {
+ return "${project.groupId}";
+ }
+
+ public static String getProjectArtifactId() {
+ return "${project.artifactId}";
+ }
+
+ public static String getProjectVersion() {
+ return "${project.version}";
+ }
+
+ public static String deploymentPath() {
+ return "${project.basedir}/target/server";
+ }
+}
diff --git a/examples/wildfly-keycloak-saml-adapter/src/test/resources/logback.xml b/examples/wildfly-keycloak-saml-adapter/src/test/resources/logback.xml
new file mode 100644
index 000000000..4657bc2c3
--- /dev/null
+++ b/examples/wildfly-keycloak-saml-adapter/src/test/resources/logback.xml
@@ -0,0 +1,59 @@
+
+
+
+
+
+
+ ${console-log-level:-INFO}
+
+
+ [%d] %-5p- %m%n
+
+
+
+ 300
+
+
+
+
+ log/test.log
+ false
+
+ DEBUG
+
+
+ [%d] %-5level [%thread]: %message%n
+
+
+
+ 300
+
+
+
+
+ log/everything.log
+ false
+
+ [%d] %-5p- %m%n
+
+
+
+ 300
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/provisioners/src/test/java/org/jboss/intersmash/provision/ProvisionerManagerTestCase.java b/provisioners/src/test/java/org/jboss/intersmash/provision/ProvisionerManagerTestCase.java
index 2386eed14..5d384f95e 100644
--- a/provisioners/src/test/java/org/jboss/intersmash/provision/ProvisionerManagerTestCase.java
+++ b/provisioners/src/test/java/org/jboss/intersmash/provision/ProvisionerManagerTestCase.java
@@ -80,14 +80,19 @@ enum SupportedApplication {
PostgreSQLImageOpenShiftProvisioner.class),
PostgreSQLTemplateOpenShiftApplication(
getApplicationMock(org.jboss.intersmash.application.openshift.PostgreSQLTemplateOpenShiftApplication.class,
- (application) -> when(((org.jboss.intersmash.application.openshift.PostgreSQLTemplateOpenShiftApplication) application).getTemplate())
- .thenReturn(org.jboss.intersmash.application.openshift.template.PostgreSQLTemplate.POSTGRESQL_PERSISTENT)),
+ (application) -> when(
+ ((org.jboss.intersmash.application.openshift.PostgreSQLTemplateOpenShiftApplication) application)
+ .getTemplate())
+ .thenReturn(
+ org.jboss.intersmash.application.openshift.template.PostgreSQLTemplate.POSTGRESQL_PERSISTENT)),
PostgreSQLTemplateOpenShiftProvisioner.class),
RhSsoOperatorApplication(getApplicationMock(org.jboss.intersmash.application.openshift.RhSsoOperatorApplication.class),
RhSsoOperatorProvisioner.class),
RhSsoTemplateOpenShiftApplication(
getApplicationMock(org.jboss.intersmash.application.openshift.RhSsoTemplateOpenShiftApplication.class,
- (application) -> when(((org.jboss.intersmash.application.openshift.RhSsoTemplateOpenShiftApplication) application).getTemplate())
+ (application) -> when(
+ ((org.jboss.intersmash.application.openshift.RhSsoTemplateOpenShiftApplication) application)
+ .getTemplate())
.thenReturn(org.jboss.intersmash.application.openshift.template.RhSsoTemplate.X509_HTTPS)),
RhSsoTemplateOpenShiftProvisioner.class),
WildflyImageOpenShiftApplication(