diff --git a/pluto-server/pom.xml b/pluto-server/pom.xml index fe05a0f4d6d9c16a9bced2b8e838ba77a27b24a9..88c09c5d71732dfa7e2bf84304a5ead3e60cc008 100644 --- a/pluto-server/pom.xml +++ b/pluto-server/pom.xml @@ -55,9 +55,9 @@ <artifactId>spring-boot-admin-starter-client</artifactId> <version>${spring-admin.version}</version> </dependency> - <dependency> - <groupId>org.springframework.boot</groupId> - <artifactId>spring-boot-starter-validation</artifactId> + <dependency> + <groupId>org.springframework.boot</groupId> + <artifactId>spring-boot-starter-validation</artifactId> </dependency> <!-- own projects --> @@ -72,18 +72,22 @@ <groupId>com.thedeanda</groupId> <artifactId>lorem</artifactId> <version>${lorem.version}</version> + <scope>test</scope> </dependency> <dependency> <groupId>com.github.javafaker</groupId> <artifactId>javafaker</artifactId> <version>${faker.version}</version> </dependency> - <!-- tools --> <dependency> <groupId>org.mapstruct</groupId> <artifactId>mapstruct</artifactId> <version>${mapstruct.version}</version> </dependency> + <dependency> + <groupId>org.freemarker</groupId> + <artifactId>freemarker</artifactId> + </dependency> <!-- Dev --> <dependency> @@ -147,27 +151,27 @@ </execution> </executions> </plugin> - + <plugin> - <groupId>org.jacoco</groupId> - <artifactId>jacoco-maven-plugin</artifactId> - <version>0.8.6</version> - <executions> - <execution> - <id>start-agent</id> - <goals> - <goal>prepare-agent</goal> - </goals> - </execution> - <execution> - <id>generate-report</id> - <phase>package</phase> - <goals> - <goal>report</goal> - </goals> - </execution> - </executions> - </plugin> + <groupId>org.jacoco</groupId> + <artifactId>jacoco-maven-plugin</artifactId> + <version>0.8.6</version> + <executions> + <execution> + <id>start-agent</id> + <goals> + <goal>prepare-agent</goal> + </goals> + </execution> + <execution> + <id>generate-report</id> + <phase>package</phase> + <goals> + <goal>report</goal> + </goals> + </execution> + </executions> + </plugin> <plugin> <groupId>org.apache.maven.plugins</groupId> @@ -224,13 +228,13 @@ </plugin> </plugins> </build> - + <repositories> - <repository> - <id>ozg-nexus</id> - <name>ozg nexus</name> - <url>https://nexus.ozg-sh.de/repository/ozg-group/</url> - </repository> + <repository> + <id>ozg-nexus</id> + <name>ozg nexus</name> + <url>https://nexus.ozg-sh.de/repository/ozg-group/</url> + </repository> </repositories> <distributionManagement> @@ -259,7 +263,7 @@ <username>admin</username> <password>admin</password> <repository>registry.ozg-sh.de/sh-land/pluto</repository> -<!-- <repository>default-route-openshift-image-registry.apps.lab.okd.local/sh-kiel-dev/pluto</repository> --> + <!-- <repository>default-route-openshift-image-registry.apps.lab.okd.local/sh-kiel-dev/pluto</repository> --> <tag>${git.branch}-${project.version}</tag> <useMavenSettingsForAuth>true</useMavenSettingsForAuth> <buildArgs> diff --git a/pluto-server/src/main/java/de/itvsh/ozg/pluto/command/CreateCommandRequest.java b/pluto-server/src/main/java/de/itvsh/ozg/pluto/command/CreateCommandRequest.java index bc19f145ad5594a87a27f33d980516a23552e9f7..face497fe2d20ec419d8e43a5fbd56a13efd818a 100644 --- a/pluto-server/src/main/java/de/itvsh/ozg/pluto/command/CreateCommandRequest.java +++ b/pluto-server/src/main/java/de/itvsh/ozg/pluto/command/CreateCommandRequest.java @@ -18,10 +18,8 @@ public class CreateCommandRequest { @NotNull private String relationId; - @NotNull private Order order; - @NotNull private Long relationVersion; diff --git a/pluto-server/src/main/java/de/itvsh/ozg/pluto/common/errorhandling/TechnicalException.java b/pluto-server/src/main/java/de/itvsh/ozg/pluto/common/errorhandling/TechnicalException.java new file mode 100644 index 0000000000000000000000000000000000000000..3c15cc1e712c3e77258c7ec5cd5369d67ae20768 --- /dev/null +++ b/pluto-server/src/main/java/de/itvsh/ozg/pluto/common/errorhandling/TechnicalException.java @@ -0,0 +1,10 @@ +package de.itvsh.ozg.pluto.common.errorhandling; + +public class TechnicalException extends RuntimeException { + + private static final long serialVersionUID = 1L; + + public TechnicalException(String message, Throwable cause) { + super(message, cause); + } +} diff --git a/pluto-server/src/main/java/de/itvsh/ozg/pluto/common/mail/FreemarkerConfiguration.java b/pluto-server/src/main/java/de/itvsh/ozg/pluto/common/mail/FreemarkerConfiguration.java new file mode 100644 index 0000000000000000000000000000000000000000..fbe4a864f33437bb83be173a5cf9c4b5c940643b --- /dev/null +++ b/pluto-server/src/main/java/de/itvsh/ozg/pluto/common/mail/FreemarkerConfiguration.java @@ -0,0 +1,24 @@ +package de.itvsh.ozg.pluto.common.mail; + +import javax.servlet.ServletContext; + +import org.springframework.context.annotation.Bean; + +import freemarker.template.Configuration; +import freemarker.template.TemplateExceptionHandler; + +@org.springframework.context.annotation.Configuration +public class FreemarkerConfiguration { + + @Bean + public Configuration mailFreemarkerConfiguration(ServletContext servletContext) { + Configuration cfg = new Configuration(Configuration.VERSION_2_3_31); + + cfg.setClassForTemplateLoading(getClass(), "/"); + cfg.setTemplateExceptionHandler(TemplateExceptionHandler.RETHROW_HANDLER); + cfg.setLogTemplateExceptions(false); + cfg.setWrapUncheckedExceptions(true); + + return cfg; + } +} diff --git a/pluto-server/src/main/java/de/itvsh/ozg/pluto/common/mail/MailSendRequest.java b/pluto-server/src/main/java/de/itvsh/ozg/pluto/common/mail/MailSendRequest.java new file mode 100644 index 0000000000000000000000000000000000000000..2587e0524b2c69a909c05aad45cefdc9c670f1fa --- /dev/null +++ b/pluto-server/src/main/java/de/itvsh/ozg/pluto/common/mail/MailSendRequest.java @@ -0,0 +1,20 @@ +package de.itvsh.ozg.pluto.common.mail; + +import java.util.Collection; + +import lombok.Builder; +import lombok.Getter; +import lombok.Singular; + +@Getter +@Builder +public class MailSendRequest { + + private String fromAddress; + @Singular + private Collection<String> toAddresses; + + private String body; + + private String requestReference; +} diff --git a/pluto-server/src/main/java/de/itvsh/ozg/pluto/vorgang/VorgangMapper.java b/pluto-server/src/main/java/de/itvsh/ozg/pluto/vorgang/VorgangMapper.java deleted file mode 100644 index c0609ea454e65759f6927a9a039ee334b4d99a78..0000000000000000000000000000000000000000 --- a/pluto-server/src/main/java/de/itvsh/ozg/pluto/vorgang/VorgangMapper.java +++ /dev/null @@ -1,8 +0,0 @@ -package de.itvsh.ozg.pluto.vorgang; - -import org.mapstruct.Mapper; - -@Mapper -interface VorgangMapper { - -} diff --git a/pluto-server/src/main/java/de/itvsh/ozg/pluto/vorgang/redirect/RedirectRequest.java b/pluto-server/src/main/java/de/itvsh/ozg/pluto/vorgang/redirect/RedirectRequest.java new file mode 100644 index 0000000000000000000000000000000000000000..e5fcaf0717df6897e562a41d7d98672cc10859c6 --- /dev/null +++ b/pluto-server/src/main/java/de/itvsh/ozg/pluto/vorgang/redirect/RedirectRequest.java @@ -0,0 +1,12 @@ +package de.itvsh.ozg.pluto.vorgang.redirect; + +import lombok.Builder; +import lombok.Getter; + +@Getter +@Builder +public class RedirectRequest { + + private String email; + private String password; +} diff --git a/pluto-server/src/main/java/de/itvsh/ozg/pluto/vorgang/redirect/RedirectService.java b/pluto-server/src/main/java/de/itvsh/ozg/pluto/vorgang/redirect/RedirectService.java new file mode 100644 index 0000000000000000000000000000000000000000..5d703688b07055c3197b9b46b3282e139fea05ca --- /dev/null +++ b/pluto-server/src/main/java/de/itvsh/ozg/pluto/vorgang/redirect/RedirectService.java @@ -0,0 +1,74 @@ +package de.itvsh.ozg.pluto.vorgang.redirect; + +import java.io.ByteArrayOutputStream; +import java.io.IOException; +import java.io.OutputStreamWriter; +import java.util.HashMap; +import java.util.Map; + +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.beans.factory.annotation.Value; +import org.springframework.stereotype.Service; + +import de.itvsh.ozg.pluto.common.errorhandling.TechnicalException; +import de.itvsh.ozg.pluto.common.mail.MailSendRequest; +import de.itvsh.ozg.pluto.vorgang.Vorgang; +import freemarker.template.Configuration; +import freemarker.template.Template; +import freemarker.template.TemplateException; + +@Service +public class RedirectService { + + static final String MAIL_TEMPLATE = "mail/text/redirect.ftlh"; + + static final String FIELD_ANTRAGS_NAME = "antragsName"; + static final String FIELD_EINGANGS_KENNZEICHEN = "eingangsKennzeichen"; + + @Autowired + private Configuration freemarkerCfg; + + @Value("${pluto.redirect.mail-from}") + private String mailFrom; + + MailSendRequest createRedirectMail(Vorgang vorgang, RedirectRequest request) { + // FIXME set command id + // TODO add attachments + return MailSendRequest.builder() + .fromAddress(mailFrom) + .toAddress(request.getEmail()) + .body(fillMailTemplate(vorgang)) + .build(); + } + + String fillMailTemplate(Vorgang vorgang) { + return fillTemplate(MAIL_TEMPLATE, buildValues(vorgang)); + } + + Map<String, Object> buildValues(Vorgang vorgang) { + var map = new HashMap<String, Object>(); + + map.put(FIELD_ANTRAGS_NAME, vorgang.getEingangs().get(0).getHeader().getFormName()); + map.put(FIELD_EINGANGS_KENNZEICHEN, vorgang.getEingangs().get(0).getHeader().getRequestId()); + + return map; + } + + private String fillTemplate(String templateName, Object dataModel) { + try (var outStream = new ByteArrayOutputStream(); var writer = new OutputStreamWriter(outStream)) { + getTemplate(templateName).process(dataModel, writer); + return new String(outStream.toByteArray()); + } catch (IOException | TemplateException e) { + throw new TechnicalException("Error filling mail template", e); + } + } + + Template getTemplate(String templateName) { + try { + return freemarkerCfg.getTemplate(templateName); + } catch (IOException e) { + throw new TechnicalException("Error loading mail template", e); + } + } + +} diff --git a/pluto-server/src/main/resources/mail/text/redirect.ftlh b/pluto-server/src/main/resources/mail/text/redirect.ftlh new file mode 100644 index 0000000000000000000000000000000000000000..0696ccd73f3f396d4a20e9a57c4b60c7b8b30186 --- /dev/null +++ b/pluto-server/src/main/resources/mail/text/redirect.ftlh @@ -0,0 +1,30 @@ + Sehr geehrte Damen und Herren, + + anliegend übersende ich Ihnen zuständigkeitshalber einen Antrag ${antragsName} mit der Bitte um weitere Veranlassung. + + Das Aktenzeichen lautet: ${eingangsKennzeichen} + + Sollten noch Unterlagen oder Dokumente benötigt werden, teilen Sie mir das bitte kurz mit. + + Für die Eingangsbestätigung bestätigen Sie bitte entweder die angeforderte Lesebestätigung oder antworten Sie kurz und formlos auf diese E-Mail. + + Den Abschluss des Verfahrens bitten wir gesondert mitzuteilen. Wieder ist eine erneute Antwort auf diese E-Mail mit dem Hinweis "Verfahren abgeschlossen" ausreichend. + + Mit freundlichen Grüßen + + Antragsmanagement + + [cid:${CONTENT_ID_1}] + einheitlicher ansprechpartner schleswig-holstein + + im + [cid:${CONTENT_ID_2}] + IT Verbund Schleswig-Holstein + Anstalt öffentlichen Rechts + + Reventlouallee 6 + 24105 Kiel + Telefon: +49 (0)431 988-8650 + + mailto: info@ea-sh.de + www.ea-sh.de \ No newline at end of file diff --git a/pluto-server/src/test/java/de/itvsh/ozg/pluto/vorgang/EingangHeaderTestFactory.java b/pluto-server/src/test/java/de/itvsh/ozg/pluto/vorgang/EingangHeaderTestFactory.java index b6397405ae19610720caff3bde28f16211d44d15..afe624c9ad25651e7b5766750cd6762589f765b2 100644 --- a/pluto-server/src/test/java/de/itvsh/ozg/pluto/vorgang/EingangHeaderTestFactory.java +++ b/pluto-server/src/test/java/de/itvsh/ozg/pluto/vorgang/EingangHeaderTestFactory.java @@ -10,7 +10,7 @@ public class EingangHeaderTestFactory { public static final String CREATED_AT_STR = "2021-01-10T10:30:00Z"; public static final ZonedDateTime CREATED_AT = ZonedDateTime.parse(CREATED_AT_STR); - private static final String REQUEST_ID = UUID.randomUUID().toString(); + public static final String REQUEST_ID = UUID.randomUUID().toString(); private static final String FORM_ID = UUID.randomUUID().toString(); public static final String FORM_NAME = LoremIpsum.getInstance().getWords(10); private static final String SENDER = LoremIpsum.getInstance().getWords(2); diff --git a/pluto-server/src/test/java/de/itvsh/ozg/pluto/vorgang/redirect/RedirectRequestTestFactory.java b/pluto-server/src/test/java/de/itvsh/ozg/pluto/vorgang/redirect/RedirectRequestTestFactory.java new file mode 100644 index 0000000000000000000000000000000000000000..8f0993c73ff8500c3b6c12403ba77bd356b40429 --- /dev/null +++ b/pluto-server/src/test/java/de/itvsh/ozg/pluto/vorgang/redirect/RedirectRequestTestFactory.java @@ -0,0 +1,18 @@ +package de.itvsh.ozg.pluto.vorgang.redirect; + +class RedirectRequestTestFactory { + + static final String E_MAIL = "ich@hier.de"; + static final String PASSWORD = "geheim"; + + public static RedirectRequest create() { + return createBuilder().build(); + } + + public static RedirectRequest.RedirectRequestBuilder createBuilder() { + return RedirectRequest.builder() + .email(E_MAIL) + .password(PASSWORD); + + } +} diff --git a/pluto-server/src/test/java/de/itvsh/ozg/pluto/vorgang/redirect/RedirectServiceITCase.java b/pluto-server/src/test/java/de/itvsh/ozg/pluto/vorgang/redirect/RedirectServiceITCase.java new file mode 100644 index 0000000000000000000000000000000000000000..683c92dab9a749d82d4d73a88a430b8776dae057 --- /dev/null +++ b/pluto-server/src/test/java/de/itvsh/ozg/pluto/vorgang/redirect/RedirectServiceITCase.java @@ -0,0 +1,22 @@ +package de.itvsh.ozg.pluto.vorgang.redirect; + +import static org.assertj.core.api.Assertions.*; + +import org.junit.jupiter.api.Test; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.test.context.SpringBootTest; + +@SpringBootTest +class RedirectServiceITCase { + + @Autowired + private RedirectService service; + + @Test + void getRedirectTemplate() { + var template = service.getTemplate(RedirectService.MAIL_TEMPLATE); + + assertThat(template).isNotNull(); + } + +} diff --git a/pluto-server/src/test/java/de/itvsh/ozg/pluto/vorgang/redirect/RedirectServiceTest.java b/pluto-server/src/test/java/de/itvsh/ozg/pluto/vorgang/redirect/RedirectServiceTest.java new file mode 100644 index 0000000000000000000000000000000000000000..95182d5a8f7df8d77baba93acc25479e8593ec94 --- /dev/null +++ b/pluto-server/src/test/java/de/itvsh/ozg/pluto/vorgang/redirect/RedirectServiceTest.java @@ -0,0 +1,96 @@ +package de.itvsh.ozg.pluto.vorgang.redirect; + +import static org.assertj.core.api.Assertions.*; +import static org.mockito.ArgumentMatchers.*; +import static org.mockito.Mockito.*; + +import java.util.Map; + +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Nested; +import org.junit.jupiter.api.Test; +import org.mockito.InjectMocks; +import org.mockito.Spy; +import org.springframework.test.util.ReflectionTestUtils; + +import de.itvsh.ozg.pluto.vorgang.EingangHeaderTestFactory; +import de.itvsh.ozg.pluto.vorgang.Vorgang; +import de.itvsh.ozg.pluto.vorgang.VorgangTestFactory; + +class RedirectServiceTest { + + @Spy + @InjectMocks + private RedirectService service; + + @Nested + class TestFillingTemplate { + + @Nested + class TestBuildValues { + + private Vorgang vorgang = VorgangTestFactory.create(); + + @Test + void shouldCreateMap() { + var map = service.buildValues(vorgang); + + assertThat(map).isNotNull().isInstanceOf(Map.class); + } + + @Test + void shouldFillAntragsName() { + var map = service.buildValues(vorgang); + + assertThat(map.get(RedirectService.FIELD_ANTRAGS_NAME)).isNotNull().isEqualTo(EingangHeaderTestFactory.FORM_NAME); + } + + @Test + void shouldFillEingangsKennzeichen() { + var map = service.buildValues(vorgang); + + assertThat(map.get(RedirectService.FIELD_EINGANGS_KENNZEICHEN)).isNotNull().isEqualTo(EingangHeaderTestFactory.REQUEST_ID); + } + } + } + + @Nested + class TestCreateRedirectMail { + + private static final String MAIL_FROM = "FROM ME WITH L"; + private static final String BODY = "FILLED BODY"; + + private Vorgang vorgang = VorgangTestFactory.create(); + private RedirectRequest request = RedirectRequestTestFactory.create(); + + @BeforeEach + void initTest() { + ReflectionTestUtils.setField(service, "mailFrom", MAIL_FROM); + + doReturn(BODY).when(service).fillMailTemplate(any()); + } + + @Test + void shouldSetFromAddress() { + var mailSendRequest = service.createRedirectMail(vorgang, request); + + assertThat(mailSendRequest.getFromAddress()).isEqualTo(MAIL_FROM); + } + + @Test + void shouldSetToAddress() { + var mailSendRequest = service.createRedirectMail(vorgang, request); + + assertThat(mailSendRequest.getToAddresses()).containsExactly(RedirectRequestTestFactory.E_MAIL); + } + + @Test + void shouldSetBody() { + var mailSendRequest = service.createRedirectMail(vorgang, request); + + verify(service).fillMailTemplate(vorgang); + assertThat(mailSendRequest.getBody()).isEqualTo(BODY); + } + } + +}