<dependencies>
<dependency>
<groupId>org.faktorips.productdesigner</groupId>
<artifactId>productdesigner-web</artifactId>
<version>24.7.0</version>
</dependency>
</dependencies>
English Documentation
Setup
Setting up the Faktor-IPS Product Designer with custom product projects
The following describes the process for manually setting up the Product Designer as a local Spring Boot application with custom product projects, as well as subsequent deployment via Docker.
Updating Faktor-IPS Dependencies:
The Product Designer requires the latest Faktor-IPS version (currently 24.7) and Java 21. In the first step, the Faktor-IPS dependencies must be updated, and the current Faktor-IPS version must be installed in a suitable Eclipse via the update site. Subsequently, the model projects need to be rebuilt once. For more information on compatibilities between Faktor-IPS and Eclipse, please refer to this overview.
Creating a Maven project:
Next, a new Maven project is created with dependencies for the Product Designer, model projects, and Spring Boot starter.
Please note: In addition to the manual setup described below, there is also the option to generate a Maven Product Designer project using an archetype. More information on this can be found in the chapter 'Product Designer Archetype'.
Dependencies:
Productdesigner-Web:
Add required model dependencies – for example:
<dependencies>
<dependency>
<groupId>de.faktorzehn.muster.shu-gewerbe</groupId>
<artifactId>vm-gewerbe-gruppenunfall-produktmodellerw</artifactId>
<version>24.7.0-SNAPSHOT</version>
</dependency>
<dependency>
<groupId>de.faktorzehn.muster.shu-gewerbe</groupId>
<artifactId>vm-gewerbe-basis-produkte</artifactId>
<version>24.7.0-SNAPSHOT</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-validation</artifactId>
</dependency>
</dependencies>
In the Spring Boot plugin configuration, the Product Designer application created in the following step is registered:
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<configuration>
<wait>500</wait>
<maxAttempts>240</maxAttempts>
<!-- Insert the Product Designer Application here (see below) -->
<mainClass>org.faktorips.productdesigner.demo.SampleProductDesignerApplication</mainClass>
<layout>JAR</layout>
</configuration>
<executions>
<execution>
<goals>
<goal>repackage</goal>
</goals>
</execution>
</executions>
</plugin>
Below is an example pom.xml
of a Product Designer Maven project:
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>de.faktorzehn.commons</groupId>
<artifactId>f10-suite-starter-spring</artifactId>
<version>24.7.0</version>
</parent>
<groupId>org.faktorips.productdesigner</groupId>
<artifactId>demo</artifactId>
<version>0.0.1-SNAPSHOT</version>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<java.version>21</java.version>
<maven.compiler.release>${java.version}</maven.compiler.release>
<maven.compiler.source>${java.version}</maven.compiler.source>
<maven.compiler.target>${java.version}</maven.compiler.target>
<faktorips.version>24.7.0</faktorips.version>
</properties>
<dependencies>
<dependency>
<groupId>org.faktorips.productdesigner</groupId>
<artifactId>productdesigner-web</artifactId>
<version>24.7.0</version>
</dependency>
<!-- INSERT the model dependencies here -->
<dependency>
<groupId>de.faktorzehn.muster.shu-gewerbe</groupId>
<artifactId>vm-gewerbe-gruppenunfall-produktmodellerw</artifactId>
<version>24.7.0-SNAPSHOT</version>
</dependency>
<dependency>
<groupId>de.faktorzehn.muster.shu-gewerbe</groupId>
<artifactId>vm-gewerbe-basis-produkte</artifactId>
<version>24.7.0-SNAPSHOT</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-validation</artifactId>
</dependency>
</dependencies>
<build>
<defaultGoal>spring-boot:run</defaultGoal>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<configuration>
<source>${java.version}</source>
<target>${java.version}</target>
<showWarnings>true</showWarnings>
<showDeprecation>true</showDeprecation>
</configuration>
</plugin>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<configuration>
<wait>500</wait>
<maxAttempts>240</maxAttempts>
<!-- Insert the Product Designer Application here -->
<mainClass>org.faktorips.productdesigner.demo.SampleProductDesignerApplication</mainClass>
<layout>JAR</layout>
</configuration>
<executions>
<execution>
<goals>
<goal>repackage</goal>
</goals>
</execution>
</executions>
</plugin>
<plugin>
<groupId>com.vaadin</groupId>
<artifactId>vaadin-maven-plugin</artifactId>
<executions>
<execution>
<goals>
<goal>prepare-frontend</goal>
</goals>
<phase>compile</phase>
</execution>
</executions>
</plugin>
</plugins>
</build>
</project>
Creating a Spring Boot Application Class
Next, create an application class, which will be registered in the pom.xml
under the configuration of the spring-boot-maven-plugin.
Example: SampleProductDesignerApplication.java
:
import com.vaadin.flow.component.page.AppShellConfigurator;
import com.vaadin.flow.server.AppShellSettings;
import com.vaadin.flow.spring.annotation.EnableVaadin
import com.vaadin.flow.theme.Theme;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.faktorips.productdesigner.core.ProductDesigner;
import org.faktorips.productdesigner.core.ProductDesignerConfigurationProperties;
@Theme(value = "productdesigner", variant = "card-section-pages")
@SpringBootApplication(scanBasePackages = ProductDesigner.BASE_PACKAGE)
@EnableConfigurationProperties(ProductDesignerConfigurationProperties.class)
@EnableVaadin(value = ProductDesigner.BASE_PACKAGE)
public class SampleProductDesignerApplication implements AppShellConfigurator {
private static final long serialVersionUID = 1L;
public static void main(String[] args) {
SpringApplication.run(SampleProductDesignerApplication.class, args);
}
@Override
public void configurePage(AppShellSettings settings) {
settings.addFavIcon("icon", "../favicon.ico", "48x48");
}
}
Creating the Configuration and Including Additional Repositories
Now, under src/main/resources/, create an application.yml:
logging:
level:
org.springframework: WARN
server:
port: 8080
vaadin:
urlMapping: '/ui/*'
launch-browser: true
ips-product-designer:
ips-project-path: ../../../git/mustercontent/vm/vm.shu.gewerbe/gruppenunfall/produkte/
additional-repos:
- de.faktorzehn.versicherungsmodell.gw.produkte.GwProduktClassloaderRuntimeRepository
- de.faktorzehn.versicherungsmodell.gw.produkte.GwAllgemeinClassloaderRuntimeRepository
read-only-mode: false
In the additional-repos section, repositories on which the product project depends are included by their class references.
Not only product repositories but also the model repositories they are built on must be referenced via addDirectlyReferencedRepository for the Product Designer to find all model types, especially those not already used in products.
|
To ensure they are correctly loaded at runtime, each repository should have a class with an INSTANCE field for an IRuntimeRepository
or IRuntimeRepositoryLookup
.
For example, the class GwProduktClassloaderRuntimeRepository
referenced in the .yml for providing and configuring the singleton repository looks like this:
import org.faktorips.runtime.ClassloaderRuntimeRepository;
import org.faktorips.runtime.formula.groovy.GroovyFormulaEvaluatorFactory;
public class GwProduktClassloaderRuntimeRepository {
public static final ClassloaderRuntimeRepository INSTANCE = ClassloaderRuntimeRepository
.create("de/faktorzehn/versicherungsmodell/gw/produkte/internal/faktorips-repository-toc.xml");
static {
INSTANCE.addDirectlyReferencedRepository(GwAllgemeinClassloaderRuntimeRepository.INSTANCE);
INSTANCE.setFormulaEvaluatorFactory(new GroovyFormulaEvaluatorFactory());
}
private GwProduktClassloaderRuntimeRepository() {
// Soll nicht instanziiert werden
}
}
First, a ClassloaderRuntimeRepository
INSTANCE is initialized based on the associated toc.xml
.
In the static initialization block, necessary referenced repositories are then incorporated via their respective instances (INSTANCE.addDirectlyReferencedRepository(GwAllgemeinClassloaderRuntimeRepository.INSTANCE)
), and additionally, configurations for the repository instance are defined (INSTANCE.setFormulaEvaluatorFactory(new GroovyFormulaEvaluatorFactory());
).
Adding a Favicon
Finally, to display application icons in the browser tab, a favicon can optionally be placed in src/main/resources/static
.
Docker Deployment
When providing and deploying the application in Docker containers, it should be noted that the application is deployed as a .jar file, but the product data is unpacked and copied into the container. For this, the vaadin.productionMode
must first be set to true
in the pom.xml
.
<profiles>
<profile>
<id>production</id>
<properties>
<vaadin.productionMode>true</vaadin.productionMode>
</properties>
<build>
<plugins>
<plugin>
<groupId>com.vaadin</groupId>
<artifactId>vaadin-maven-plugin</artifactId>
<version>${vaadin.version}</version>
<executions>
<execution>
<goals>
<goal>prepare-frontend</goal>
<goal>build-frontend</goal>
</goals>
<phase>compile</phase>
</execution>
</executions>
</plugin>
</plugins>
</build>
</profile>
</profiles>
Dockerfile
example:
FROM eclipse-temurin:21-jre-jammy
RUN apt-get update \
&& ln -sf /usr/share/zoneinfo/Europe/Berlin /etc/localtime \
&& dpkg-reconfigure -f noninteractive tzdata
ARG UID=999
ARG GID=999
ENV JAVA_TOOL_OPTIONS "-Xms480m -Xmx1024m"
RUN groupadd --gid $GID spring \
&& useradd -r -m -d /opt/spring -s /sbin/nologin --gid $GID --uid $UID -c "Spring user" spring \
&& chmod 755 /opt/spring \
&& mkdir -p /var/opt/spring \
&& chown spring: /var/opt/spring \
&& chmod 755 /var/opt/spring
WORKDIR /opt/spring
COPY ${PATH_TO_APPLICATION_JAR} application.jar
COPY ${PATH_TO_PRODUCT_FOLDER} /var/opt/spring/produkte
RUN chown -R spring: /var/opt/spring
USER $UID
EXPOSE 8080
CMD ["java", \
"-Dspring.profiles.active=production", \
"-jar", \
"application.jar", \
"--server.port=8080", \
"--server.forward-headers-strategy=FRAMEWORK"]
docker-compose.yml
example:
version: '2.4'
services:
productdesigner-sample:
container_name: ${CONTAINER_NAME}-sample
build:
context: ../
dockerfile: ./path/to/Dockerfile
args:
- PATH_TO_APPLICATION_JAR=${PATH_TO_APPLICATION_JAR}
- PATH_TO_PRODUCT_FOLDER=${PATH_TO_PRODUCT_FOLDER}
environment:
SPRING_PROFILES_ACTIVE: production
ips-product-designer.ips-project-path: /var/opt/spring/produkte
labels:
url: ${CONTAINER_NAME}-sample
entry-path: ui
networks:
default:
name: network-${CONTAINER_NAME}
labels:
retention: ${CONTAINER_RETENTION}