Blueprint Developer Manual / Version 2404
Table Of ContentsOne of the main goals of CoreMedia Content Cloud is to offer a developer friendly system with a lot of prefabricated features, that can simply be extended modularly. To this end, CoreMedia provides the Maven based CoreMedia Blueprint workspace and the extensions mechanism.
An extension adds new features to one or more CoreMedia applications. Assume, for example, that a feature requires a new content type. In this case the extension affects at least three applications:
The Content Server needs the new content type
The CAE needs according content beans
Studio needs according content forms
Manually enabling or disabling a feature in all the affected applications would be cumbersome, tedious and error-prone. Therefore, CoreMedia provides the extensions mechanism, which allows you to enable or disable a feature for all affected applications by a single configuration switch. The extensions mechanism is based on Maven modules and runtime dependencies. Adhering to some structural conventions enables you to use the CoreMedia Extension Tool to manage those dependencies.
Extensions Mechanism Structure
The extension mechanism structure consists of two parts:
extensions which extend different applications to provide a new feature
extension points of CoreMedia applications to which the features are added.
Extensions and extension points are separated for each
application workspace (apps/*
). In each workspace, extension points
(usually one) can be found at the local path
./modules/extension-config/*-extension-dependencies
and extensions are
located below ./modules/extensions
.
Any Maven module with an artifact ID using the pattern
{prefix}-extension-dependencies
constitutes an extension point,
for example the artifact ID studio-server-extension-dependencies
defines an
extension point named studio-server. This name serves as an ID by which an
extension point can be referenced from an extension.
In the new version of CoreMedia Content Cloud, the extension point names have been aligned with the application (workspace) names. For backwards compatibility, the old extension point names may still be used, but are deprecated.
Extensions points collect runtime dependencies on app extensions. Applications have explicit dependencies on extension points, so they get transitive dependencies on the actual app extensions.
Since an extension extends several applications, it consists of so-called application
extensions or for short app extensions, where one app extension
uses exactly one extension point and thus extends exactly one CoreMedia application. The desired
extension point is marked in the pom.xml
by the property named
coremedia.project.extension.for
and has the name of the extension point as
value.
<properties> <coremedia.project.extension.for>studio-client</coremedia.project.extension.for> </properties>
Example 4.3. Specify the extension point
In previous versions of CoreMedia Content Cloud, one module was allowed to use several extension points.
Since now, a clear separation of applications is enforced and only one extension point may be
used. To migrate a multi-extension-point extension, you must move the extension module to a
shared code location (shared/middle/modules/extensions/...
) and create two
app extensions that both have a dependency on the shared-code module.
Short overview of the extensions structure of each application workspace
apps/{application}
:
./modules/extensions - contains application extensions as Maven submodules
one extension - aggregator of all application extensions (usually only one per workspace)
one application extension - Maven module with property
coremedia.project.extension.for
another application extension - Maven module with property
coremedia.project.extension.for
extension library - Maven module with application-specific code that is used by one or more of the application extensions
./modules/extension-config - Maven aggregator module
{extension-point-name}-extension-dependencies - extension point for application with the identifier {extension-point-name}
./spring-boot/{application}-app - has a runtime dependency on {extension-point-name}-extension-dependencies.
Usually, each workspace below apps/
contains exactly one application with
exactly one extension point. However, there are two exceptions to this one-to-one rule.
The CAE comes in two application "flavors", cae-preview-app and cae-live-app, and consequently offers two extension points. Because only preview allows dedicated extensions, the extension points are called cae-preview (preview only) and cae (both preview and live).
The second exception is CoreMedia Studio client: The studio-app (an Ext JS app, not a Spring Boot app) allows statically linked as well as dynamically linked extension modules. Depending on your choice, use the extension point studio-client or studio-client-dynamic.
Extension points do not contain any code or configuration directly and should never be edited manually, because they are modified by the CoreMedia Extension Tool to contain all collected dependencies on active application extensions.
Usage of the CoreMedia Extension Tool
Within the extension mechanism structure, the extensions and the dependencies from the applications onto the extension points are maintained manually. The extension point modules must already be present and are updated by the CoreMedia Extension Tool. The tool lets you synchronize the dependencies from the extension points to application extensions by their status (enabled/disabled). You can disable, enable, remove and add prefabricated and custom extensions.
For convenience, the CoreMedia Extension Tool is implemented as a
Maven plugin, which is preconfigured for usage in the CoreMedia Blueprint workspace in the Maven POM file
workspace-configuration/extensions/pom.xml
. The tool is used by invoking it
through this POM, by running Maven either from that directory or from the project root
directory, adding -f workspace-configuration/extensions
. All relevant use cases and
command line examples can be found in
workspace-configuration/extensions/README.md
. The most important advice is
to call mvn -f workspace-configuration/extensions extensions:help
to see full usage
instructions of all available goals (commands) and their options (parameters). Especially the
extensive help text of goal sync
is important to understand how the tool works.
When disabling or removing extensions, note that extensions may depend on each other. Therefore, when you enable an extension all the extensions it depends on must also be enabled. For example, lc-p13n makes only sense if lc and p13n are enabled too. Otherwise, you would encounter runtime errors like missing Spring beans.
To prevent such situations, the CoreMedia Extension Tool does not allow enabling or disabling extensions that would result in such an inconsistent state. The tool will stop with an error message that tells you exactly what went wrong and how to fix the problem. For example, if you try to disable the extension alx, the tool outputs the following error (the concrete list of dependent modules may vary in future releases):
[ERROR] Inconsistent set of extensions to disable/remove. These extensions would need to be disabled or removed, too: [alx-google]
Implementing a Custom Extension
The following steps summarize how to add a custom extension to the CoreMedia Blueprint workspace. Let's call the extension my-feature.
Plan your feature: Which applications (workspaces) do you need to extend? Do you have shared code? Let's assume you need to extend cae and studio-server and want to have one shared code module.
For shared code, add a new Maven module at
shared/middle/modules/extensions/my-feature/
. Its parent must be set tocom.coremedia.blueprint:middle.extensions:1-SNAPSHOT
. If you have multiple shared modules, add an aggregator module at that location and place the other shared modules below that aggregator.For each application you want to extend, here cae and studio-server, create a new Maven module in its application workspace at
apps/{application}/modules/extensions/my-feature
. Its parent must be set tocom.coremedia.blueprint:{application}.extensions:1-SNAPSHOT
. Again, if you have multiple application-specific modules, instead create an aggregator at that location and place all modules below that aggregator.Set the
coremedia.project.extension.for
property in thepom.xml
file of all application extension modules, that is all modules that are supposed to be added as{extension-point}-extension-dependencies
. Usually, there is exactly one such module per extension point/application.This would be a good time to do a VCS commit. This helps you to see what modifications the CoreMedia Extension Tool applies in the next step, and if anything goes wrong, allows you to revert to this state.
Run the CoreMedia Extension Tool with goal
sync
(mvn -f workspace-configuration/extensions extensions:sync
and enable your new extension by adding-Denable=my-feature
.Use
mvn -f workspace-configuration/extensions extensions:list
to check that your extension has been added (my-feature
appears in the list) and activated (it does not start with a hash ("#
")).Check the changes the tool has applied to each affected workspace:
Your extension's workspace-specific root module is added as a
<module>
to the corresponding workspace extensions aggregator,{workspace}.extensions/pom.xml
.All affected extension points
{extension-point}-extension-dependencies/pom.xml
files should now contain dependencies on your application extensions.All modules of your extension that now belong to this workspace are added to the workspace's extensions BOM,
{workspace}-extensions-bom/pom.xml
, so that their version is managed for others who import this BOM.
Rebuild your project, at least all affected workspaces.
If your extension becomes obsolete, you can disable it:
Run the CoreMedia Extension Tool with goal
sync
and option-Ddisable=my-feature
.Checkpoint: In all affected workspaces, all three types of POMs (extensions aggregator, extension point, extensions BOM) no longer refer to any of your extension modules.
Rebuild your project, at least all affected workspaces.
If you want to reactivate your extension, just call the sync
goal with
-Denable=my-feature
again and rebuild your project. Otherwise, if you are sure that
you will never need your extension again, rerun the CoreMedia Extension
Tool with goal sync
and option -Dremove=my-feature
,
which removes all files of your extension from all workspaces.
Note
Removing is not recommended for extensions that come with the Blueprint, because when updating to a new Blueprint release, deleted files lead to merge conflicts for all files updated by CoreMedia.
Best Practice
In a particular project the set of active extensions is usually not changed frequently.
Therefore, CoreMedia recommends applying the CoreMedia Extension Tool
only manually and to check in all changed files into the VCS. You should then call the tool's
sync
goal without any additional parameters on a regular basis to check that all
generated extension dependencies are in a consistent state.
Alternatively, you could integrate the tool into the CI and synchronize the extension points in every build. However, since the result is almost always the same, this would unnecessarily increase the roundtrip time.