<dependencies>
<dependency>
<groupId>org.faktorips.productdesigner</groupId>
<artifactId>productdesigner-web</artifactId>
<version>24.7.0</version>
</dependency>
</dependencies>
Setup
Einrichtung des Faktor-IPS-Product Designers mit eigenen Produktprojekten
Im Folgenden wird der Prozess zur manuellen Einrichtung des Produktdesigners als lokale Spring-Boot-Anwendung mit eigenen Produktprojekten, sowie zur anschließenden Bereitstellung via Docker-Deployment beschrieben.
Aktualisieren der Faktor-IPS Dependencies:
Der Produkt Designer setzt die neueste Faktor-IPS-Version (24.7) sowie Java 21 voraus . Im ersten Schritt müssen daher zunächst die Faktor-IPS-Dependencies aktualisiert und zudem in einem passenden Eclipse via der Updatesite das aktuelle Faktor-IPS installiert und nachfolgend die Modellprojekte einmal neu gebaut werden.
Für weitere Informationen zu Kompatibilitäten zwischen Faktor-IPS und Eclipse bitte diese Übersicht beachten.
Anlage eines Maven-Projekts:
Im zweiten Schritt wird ein neues Maven-Projekt mit Dependencies für den Product Designer, Modellprojekte und Spring-Boot-Starter angelegt.
Bitte beachten: Neben der im Folgenden beschriebenen manuellen Anlage, besteht auch die Möglichkeit, ein Maven Product Designer-Projekt mithilfe eines Archetypes zu generieren. Weitere Informationen dazu sind im Kapitel 'Produkt Designer Archetype' beschrieben.
Dependencies:
Productdesigner-Web:
Gewünschte Modellabhängigkeiten hinzufügen – z. B.:
<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 der Spring-Boot-Plugin-Configuration wird die im nachfolgenden Schritt erstellte Product Designer-Applikation eingetragen:
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<configuration>
<wait>500</wait>
<maxAttempts>240</maxAttempts>
<!-- HIER die Product-Designer-Application eintragen (s.u.) -->
<mainClass>org.faktorips.productdesigner.demo.SampleProductDesignerApplication</mainClass>
<layout>JAR</layout>
</configuration>
<executions>
<execution>
<goals>
<goal>repackage</goal>
</goals>
</execution>
</executions>
</plugin>
Nachfolgend eine beispielhafte pom.xml
eines Produkt Designer-Maven-Projekts:
<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>
<!-- HIER MODELL-Dependencie(s) angeben -->
<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>
<!-- HIER die Product-Designer-Application angeben (s.u.) -->
<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>
Anlage einer SpringBoot-Application-Klasse
Nun wird eine Application-Klasse angelegt, welche im Anschluss in der pom.xml
in der Konfiguration des spring-boot-maven-plugin
eingetragen wird.
Beispiel: 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");
}
}
Anlegen der Config und einbinden zusätzlicher Repositories
Unter src/main/resources/
wird nun eine application.yml
angelegt:
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
Im Abschnitt additional-repos
werden Repositories, von denen das Produktprojekt abhängt, durch ihre Klassenreferenzen eingebunden.
Damit diese zur Laufzeit korrekt geladen werden, sollte je Repository eine Klasse mit einem INSTANCE-Field
für ein IRuntimeRepository
oder IRuntimeRepositoryLookup
enthalten sein.
Am Beispiel des in der .yml
referenzierten Repositories sieht die Klasse GwProduktClassloaderRuntimeRepository
zur Bereitstellung und Konfiguration des Singleton-Repositories wie folgt aus:
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
}
}
Zunächst wird eine ClassloaderRuntimeRepository INSTANCE
, auf Basis der zugehörigen toc.xml
initialisiert.
Im statischen Initialisierungsblock werden dann notwendige, referenzierte Repositories über ihre jeweiligen Instanzen eingebunden (INSTANCE.addDirectlyReferencedRepository(GwAllgemeinClassloaderRuntimeRepository.INSTANCE);
), sowie zusätzlich auch Konfigurationen für die Repository Instanz definiert (INSTANCE.setFormulaEvaluatorFactory(new GroovyFormulaEvaluatorFactory());
).
Favicon hinzufügen
Um schließlich im Browser-Tab Icons der Anwendung anzeigen zu lassen, wird optional ein Favicon in src/main/resources/static
abgelegt.
Docker-Deployment
Beim Bereitstellen und Deployen der Anwendung in Docker-Containern ist zu berücksichtigen, dass die Anwendung als .jar deployt wird, die Produktdaten jedoch in entpackter Form in den Container kopiert und konfiguriert werden. Hierfür muss zunächst in der pom.xml
der vaadin.productionMode
auf true
gesetzt werden.
<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>
Beispiel Dockerfile
:
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"]
Beispiel docker-compose.yml
:
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}