Chapter 4. Capability Trimming in JBoss EAP for OpenShift

When building an image that includes JBoss EAP, you can control the JBoss EAP features and subsystems to include in the image.

The default JBoss EAP server included in S2I images includes the complete server and all features. You might want to trim the capabilities included in the provisioned server. For example, you might want to reduce the security exposure of the provisioned server, or you might want to reduce the memory footprint so it is more appropriate for a microservice container.

4.1. Provision a custom JBoss EAP server

To provision a custom server with trimmed capabilities, pass the GALLEON_PROVISION_LAYERS environment variable during the S2I build phase.

The value of the environment variable is a comma-separated list of the layers to provision to build the server.

For example, if you specify the environment variable as GALLEON_PROVISION_LAYERS=jaxrs-server,sso, a JBoss EAP server is provisioned with the following capabilities:

  • A servlet container
  • The ability to configure a datasource
  • The jaxrs, weld, and jpa subsystems
  • Red Hat SSO integration

4.2. Available JBoss EAP Layers

Red Hat makes available six layers to customize provisioning of the JBoss EAP server in OpenShift.

Three layers are base layers that provide core functionality. Three are decorator layers that enhance the base layers.

The following Jakarta EE specifications are not supported in any provisioning layer:

  • Jakarta Server Faces 2.3
  • Jakarta Enterprise Beans 3.2
  • Jakarta XML Web Services 2.3

4.2.1. Base Layers

Each base layer includes core functionality for a typical server user case.

datasources-web-server

This layer includes a servlet container and the ability to configure a datasource.

This layer does not include MicroProfile capabilities.

The following Jakarta EE specifications are supported in this layer:

  • Jakarta JSON Processing 1.1
  • Jakarta JSON Binding 1.0
  • Jakarta Servlet 4.0
  • Jakarta Expression Language 3.0
  • Jakarta Server Pages 2.3
  • Jakarta Standard Tag Library 1.2
  • Jakarta Concurrency 1.1
  • Jakarta Annotations 1.3
  • Jakarta XML Binding 2.3
  • Jakarta Debugging Support for Other Languages 1.0
  • Jakarta Transactions 1.3
  • Jakarta Connectors 1.7

jaxrs-server

This layer enhances the datasources-web-server layer with the following JBoss EAP subsystems:

  • jaxrs
  • weld
  • jpa

This layer also adds Infinispan-based second-level entity caching locally in the container.

The following MicroProfile capability is included in this layer:

  • MicroProfile REST Client

The following Jakarta EE specifications are supported in this layer in addition to those supported in the datasources-web-server layer:

  • Jakarta Contexts and Dependency Injection 2.0
  • Jakarta Bean Validation 2.0
  • Jakarta Interceptors 1.2
  • Jakarta RESTful Web Services 2.1
  • Jakarta Persistence 2.2

cloud-server

This layer enhances the jaxrs-server layer with the following JBoss EAP subsystems:

  • resource-adapters
  • messaging-activemq (remote broker messaging, not embedded messaging)

This layer also adds the following observability features to the jaxrs-server layer:

  • MicroProfile Health
  • MicroProfile Metrics
  • MicroProfile Config
  • MicroProfile OpenTracing

The following Jakarta EE specification is supported in this layer in addition to those supported in the jaxrs-server layer:

  • Jakarta Security 1.0

4.2.2. Decorator Layers

Decorator layers are not used alone. You can configure one or more decorator layers with a base layer to deliver additional functionality.

sso

This decorator layer adds Red Hat Single Sign-On integration to the provisioned server.

observability

This decorator layer adds the following observability features to the provisioned server:

  • MicroProfile Health
  • MicroProfile Metrics
  • MicroProfile Config
  • MicroProfile OpenTracing
Note

This layer is built in to the cloud-server layer. You do not need to add this layer to the cloud-server layer.

web-clustering

This layer adds embedded Infinispan-based web session clustering to the provisioned server.

4.3. Provisioning User-developed Layers in JBoss EAP

In addition to provisioning layers available from Red Hat, you can provision custom layers you develop.

Procedure

  1. Build a custom layer using the Galleon Maven plugin.

    For more information, see Building Custom Layers for JBoss EAP.

  2. Deploy the custom layer to an accessible Maven repository.
  3. Create a custom provisioning file to reference the user-defined layer and supported JBoss EAP layers and store it in your application directory.

    For more information, see Custom Provisioning Files for JBoss EAP.

  4. Optional: You can use custom Galleon feature pack environment variables to customize Galleon feature packs and layers during the S2I image build process.

    For more information about custom Galleon feature pack environment variables, see custom Galleon feature pack environment variables.

  5. Run the S2I process to provision a JBoss EAP server in OpenShift.

    For more information, see Building an Application Provisioned with User-developed Layers.

4.3.1. Building Custom Layers for JBoss EAP

Create your custom layer feature pack as a Maven project.

  1. Custom layers depend on at least a base layer. Select the base layer that provides the capabilities you need for your custom layer.
  2. Within the Maven project, create your layer content in the directory src/main/resources.

    For example, to create layers to provision support for PostgreSQL and a PostgreSQL datasource, in the directory src/main/resources create the layers/standalone subdirectories. The standalone subdirectory includes the following content.

    • postgresql-driver

      This directory contains a layer-spec.xml file with the following content.

      <?xml version="1.0" ?>
      <layer-spec xmlns="urn:jboss:galleon:layer-spec:1.0" name="postgresql-driver">
          <feature spec="subsystem.datasources">
              <feature spec="subsystem.datasources.jdbc-driver">
                  <param name="driver-name" value="postgresql"/>
                  <param name="jdbc-driver" value="postgresql"/>
                  <param name="driver-xa-datasource-class-name" value="org.postgresql.xa.PGXADataSource"/>
                  <param name="driver-module-name" value="org.postgresql.jdbc"/>
              </feature>
          </feature>
          <packages>
              <package name="org.postgresql.jdbc"/>
          </packages>
      </layer-spec>
    • postgresql-datasource

      This directory contains a layer-spec.xml file with the following content.

      <?xml version="1.0" ?>
      <layer-spec xmlns="urn:jboss:galleon:layer-spec:1.0" name="postgresql-datasource">
          <dependencies>
              <layer name="postgresql-driver"/>
          </dependencies>
          <feature spec="subsystem.datasources.data-source">
              <param name="use-ccm" value="true"/>
              <param name="data-source" value="PostgreSQLDS"/>
              <param name="enabled" value="true"/>
              <param name="use-java-context" value="true"/>
              <param name="jndi-name" value="java:jboss/datasources/${env.POSTGRESQL_DATASOURCE,env.OPENSHIFT_POSTGRESQL_DATASOURCE:PostgreSQLDS}"/>
              <param name="connection-url" value="jdbc:postgresql://${env.POSTGRESQL_SERVICE_HOST,\
      env.OPENSHIFT_POSTGRESQL_DB_HOST}:${env.POSTGRESQL_SERVICE_PORT,\
      env.OPENSHIFT_POSTGRESQL_DB_PORT}/${env.POSTGRESQL_DATABASE, env.OPENSHIFT_POSTGRESQL_DB_NAME}"/>
              <param name="driver-name" value="postgresql"/>
              <param name="user-name" value="${env.POSTGRESQL_USER, env.OPENSHIFT_POSTGRESQL_DB_USERNAME}"/>
              <param name="password" value="${env.POSTGRESQL_PASSWORD, env.OPENSHIFT_POSTGRESQL_DB_PASSWORD}"/>
              <param name="check-valid-connection-sql" value="SELECT 1"/>
              <param name="background-validation" value="true"/>
              <param name="background-validation-millis" value="60000"/>
              <param name="flush-strategy" value="IdleConnections"/>
              <param name="statistics-enabled" value="${wildfly.datasources.statistics-enabled:${wildfly.statistics-enabled:false}}" />
          </feature>
  3. In the pom.xml file used to build your custom feature pack, refer to the JBoss EAP dependencies.

    <dependency>
        <groupId>org.jboss.eap</groupId>
        <artifactId>wildfly-ee-galleon-pack</artifactId>1
        <version>7.4.0.GA-redhat-XXXXX</version> 2
        <type>zip</type>
    </dependency>
    1
    When using the JBoss EAP expansion pack (JBoss EAP XP), the value of this element should be wildfly-galleon-pack.
    2
    Where XXXXX is the minor version of your JBoss EAP instance.

    These dependencies are available in the Red Hat Maven repository: https://maven.repository.redhat.com/ga/

  4. Use the build-user-feature-pack goal in the Galleon Maven plugin to build custom layers.

Additional Resources

Base Layers

WildFly Galleon Maven Plugin Documentation

Example illustrating packaging of drivers and datasources as Galleon layers

4.3.2. Custom Provisioning Files for JBoss EAP

Custom provisioning files are XML files with the file name provisioning.xml that are stored in the galleon subdirectory.

Important

Do not create a custom provisioning file when using the GALLEON_PROVISION_LAYERS environment variable, because this environment variable configures the S2I build process to ignore the file.

The following code illustrates a custom provisioning file.

<?xml version="1.0" ?>
<installation xmlns="urn:jboss:galleon:provisioning:3.0">
    <feature-pack location="eap-s2i@maven(org.jboss.universe:s2i-universe)">1
        <default-configs inherit="false"/>2
        <packages inherit="false"/>3
    </feature-pack>
    <feature-pack location="com.example.demo:my-galleon-feature-pack:1.0
">4
        <default-configs inherit="false"/>
        <packages inherit="false"/>
    </feature-pack>
    <config model="standalone" name="standalone.xml">5
        <layers>
            <include name="cloud-server"/>
            <include name="my-custom-driver"/>
            <include name="my-custom-datasource"/>
        </layers>
    </config>
    <options>6
        <option name="optional-packages" value="passive+"/>
    </options>
</installation>
1
This element instructs the provisioning process to provision the current eap-s2i feature-pack. Note that a builder image includes only one feature pack.
2
This element instructs the provisioning process to exclude default configurations.
3
This element instructs the provisioning process to exclude default packages.
4
This element instructs the provisioning process to provision the com.example.demo:my-galleon-feature-pack:1.0 feature pack. The child elements instruct the process to exclude default configurations and default packages.
5
This element instructs the provisioning process to create a custom standalone configuration. The configuration includes the cloud-server base layer and the my-custom-driver and my-custom-datasource custom layers from the com.example.demo:my-galleon-feature-pack:1.0 feature pack.
6
This element instructs the provisioning process to optimize provisioning of JBoss EAP modules.

Additional resources

4.3.3. Building an Application Provisioned with User-developed Layers

When you build an application from a directory that includes a custom provisioning file, the S2I build process detects the provisioning file and provisions the JBoss EAP server as instructed.

Prerequisites

  • The user-developed layers must exist in an accessible Maven repository.
  • The application directory must contain a valid provisioning file that refers to the user-developed layers and the feature pack that contains them.

Procedure

  • Enter a standard S2I build command to build the application.

    For example, assume you create the following custom provisioning file in your application directory.

    <?xml version="1.0" ?>
    <installation xmlns="urn:jboss:galleon:provisioning:3.0">
        <feature-pack location="eap-s2i@maven(org.jboss.universe:s2i-universe)">
            <default-configs inherit="false"/>
            <packages inherit="false"/>
        </feature-pack>
        <feature-pack location="com.example.demo:my-galleon-feature-pack:1.0">
            <default-configs inherit="false"/>
            <packages inherit="false"/>
        </feature-pack>
        <config model="standalone" name="standalone.xml">
            <layers>
                <include name="cloud-server"/>
                <include name="my-custom-driver"/>
                <include name="my-custom-datasource"/>
            </layers>
        </config>
        <options>
            <option name="optional-packages" value="passive+"/>
        </options>
    </installation>

    The following command builds an application using the com.example.demo:my-galleon-feature-pack:1.0 feature pack, which includes the my-custom-driver and my-custom-datasource layers. The resulting application is named eap-my-custom-db. The connection to the database is configured using environment variables.

    oc build my-app \
    -e DEMO_DB=demo \
    -e DEMO_PASSWORD=demo \
    -e DEMO_HOST=127.0.0.1  \
    -e DEMO_PORT=5432 \
    -e DEMO_USER=demo \
    eap-my-custom-db

You can log in to the database on port 5432 with the user demo and the password demo.

4.3.4. Providing custom Galleon feature pack support for your JBoss EAP S2I image.

You can use custom Galleon feature pack environment variables to customize Galleon feature packs and layers during the S2I image build process. These environment variables expand on the fixed set of Galleon layers provided by the GALLEON_PROVISION_LAYERS environment variable.

The example in this procedure shows the use of the GALLEON_PROVISION_FEATURE_PACKS environment variable for provisioning a JBoss EAP server with a custom Galleon feature pack on OpenShift.

Procedure

  • Enter the following command that uses the eap74-basic-2si template to deploy an example quickstart, such as helloworld-html5, with a provisioned postgresql driver for a server. You must prepend a build environment variable with the --build-env argument.

    oc new-app --template=eap74-basic-s2i \
    -p IMAGE_STREAM_NAMESPACE=eap-demo \
    -p EAP_IMAGE_NAME=jboss-eap74-openjdk11-openshift:7.4.0 \
    -p EAP_RUNTIME_IMAGE_NAME=jboss-eap74-openjdk11-runtime-openshift:7.4.0 \
    -p SOURCE_REPOSITORY_URL=https://github.com/jboss-developer/jboss-eap-quickstarts \
    -p SOURCE_REPOSITORY_REF=7.4.x \
    -p GALLEON_PROVISION_LAYERS=jaxrs-server,postgresql-driver \ 1
    -p CONTEXT_DIR=helloworld-html5 \
    --build-env POSTGRESQL_DRIVER_VERSION=42.2.19 \ 2
    --build-env GALLEON_PROVISION_FEATURE_PACKS="org.jboss.eap:eap-datasources-galleon-pack:7.4.0.GA-redhat-00003" 3
    1
    Use the GALLEON_PROVISON_LAYERS environment variable to specify the postgresql-driver Galleon layer to provision a postgresql driver for your server.
    2
    Use the POSTGRESQL_DRIVER_VERSION build environment variable to specify the postgresql driver version to retrieve the driver artifact from the remote Maven repository when you provision the postgresql driver for your server.
    3
    Use the GALLEON_PROVISION_FEATURE_PACKS build environment variable to specify a custom Galleon feature pack for your S2I image.
    Note

    The org.jboss.eap:eap-datasources-galleon-pack feature pack contains Galleon layers that you can use to provision drivers and datasources, such as Microsoft SQL Server, Oracle database, or PostgreSQL, for JDBC drivers and datasources. The feature pack provides support for using the POSTGRESQL_DRIVER_VERSION environment variable in your project.

Expected outcome

The S2I process provisions your JBoss EAP server on OpenShift and the server contains the postgresql driver.

Additional resources

4.3.5. Configure Galleon by using advanced environment variables

You can use advanced custom Galleon feature pack environment variables to customize the location where you store your custom Galleon feature packs and layers during the S2I image build process. These advanced custom Galleon feature pack environment variables are as follows:

  • GALLEON_DIR=<path>, which overrides the default <project_root_dir>/galleon directory path to <project_root_dir>/<GALLEON_DIR>.
  • GALLEON_CUSTOM_FEATURE_PACKS_MAVEN_REPO=<path>, which overrides the <project root dir>/galleon/repository directory path with an absolute path to a Maven local repository cache directory. This repository contains custom Galleon feature packs.

You must locate the Galleon feature pack archive files inside a sub-directory that is compliant with the Maven local-cache file system configuration. For example, locate the org.examples:my-feature-pack:1.0.0.Final feature pack inside the path-to-repository/org/examples/my-feature-pack/1.0.0.Final/my-feature-pack-1.0.0.Final.zip path.

You can configure your Maven project settings by creating a settings.xml file in the <project_root>/<GALLEON_DIR> directory. The default value for GALLEON_DIR is <project_root_dir>/galleon. Maven uses the file to provision your custom Galleon feature packs for your application. If you do not create a settings.xml file, Maven uses a default settings.xml file that was created by the S2I image.

Important

Do not specify a local Maven repository location in a settings.xml file, because the S2I builder image specifies a location to your local Maven repository. The S2I builder image uses this location during the S2I build process.

Additional resources

4.3.6. Custom Galleon feature pack environment variables

You can use any of the following custom Galleon feature pack environment variables to customize how you use your JBoss EAP S2I image.

Table 4.1. Descriptions of custom Galleon feature pack environment variables

Environment variableDescription

GALLEON_DIR=<path>

Where <path> is a directory relative to the root directory of your application project. Your <path> directory contains your optional Galleon custom content, such as the settings.xml file and local Maven repository cache. This cache contains the custom Galleon feature packs.

Directory defaults to galleon.

GALLEON_CUSTOM_FEATURE_PACKS_MAVEN_REPO=<path>

<path> is the absolute path to a Maven local repository directory that contains custom feature packs. Directory defaults to galleon/repository.

GALLEON_PROVISION_FEATURE_PACKS=<list_of_galleon_feature_packs>

Where <list_of_galleon_feature_packs> is a comma-separated list of your custom Galleon feature packs identified by Maven coordinates. The listed feature packs must be compatible with the version of the JBoss EAP 7.4 server present in the builder image.

You can use the GALLEON_PROVISION_LAYERS environment variable to set the Galleon layers, which were defined by your custom feature packs, for your server.